From d318611dd6f23fcfedd50e9b9e24620b102ba96a Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 21:44:05 +0200 Subject: Adding upstream version 1.23.0. Signed-off-by: Daniel Baumann --- .tarball-version | 1 + .version | 1 + AUTHORS | 0 BUG-REPORT | 72 + COPYING | 674 + ChangeLog | 18665 +++++++++++ ChangeLog.115 | 6156 ++++ ChangeLog.116 | 1397 + ChangeLog.117 | 2199 ++ ChangeLog.118 | 3803 +++ ChangeLog.119 | 5240 +++ ChangeLog.120 | 3053 ++ ChangeLog.121 | 788 + ChangeLog.122 | 5331 ++++ FDL | 451 + FOR-RELEASE | 58 + HACKING | 178 + INSTALL | 368 + INSTALL.REPO | 136 + INSTALL.extra | 273 + LICENSES | 219 + MANIFEST | 191 + MORE.STUFF | 189 + Makefile.am | 915 + Makefile.in | 15815 +++++++++ NEWS | 3594 +++ PROBLEMS | 1321 + PROJECTS | 52 + README | 130 + README.MinGW | 326 + THANKS | 0 TODO | 41 + acinclude.m4 | 25 + aclocal.m4 | 1593 + arch/djgpp/README | 361 + arch/djgpp/config.bat | 100 + arch/djgpp/config.sed | 21 + arch/djgpp/config.site | 38 + arch/djgpp/t-groff.bat | 83 + arch/mingw/afmtodit.cmd | 2 + arch/mingw/chem.cmd | 2 + arch/mingw/gperl.cmd | 2 + arch/mingw/gpinyin.cmd | 2 + arch/mingw/grap2graph.cmd | 86 + arch/mingw/grog.cmd | 2 + arch/mingw/gropdf.cmd | 2 + arch/mingw/mingw.am | 49 + arch/mingw/mmroff.cmd | 2 + arch/mingw/neqn.cmd | 6 + arch/mingw/pdfmom.cmd | 2 + arch/mingw/roff2dvi.cmd | 2 + arch/mingw/roff2html.cmd | 2 + arch/mingw/roff2pdf.cmd | 2 + arch/mingw/roff2ps.cmd | 2 + arch/mingw/roff2text.cmd | 2 + arch/mingw/roff2x.cmd | 2 + arch/misc/misc.am | 35 + arch/misc/shdeps.sh | 117 + build-aux/compile | 348 + build-aux/config.guess | 1774 ++ build-aux/config.rpath | 684 + build-aux/config.sub | 1907 ++ build-aux/depcomp | 790 + build-aux/git-version-gen | 227 + build-aux/install-sh | 541 + build-aux/missing | 215 + build-aux/test-driver | 153 + build-aux/ylwrap | 247 + configure | 31918 +++++++++++++++++++ configure.ac | 263 + contrib/chem/ChangeLog | 373 + contrib/chem/README.txt | 50 + contrib/chem/chem.1.man | 925 + contrib/chem/chem.am | 120 + contrib/chem/chem.pic | 89 + contrib/chem/chem.pl | 1231 + contrib/chem/examples/122/README.txt | 57 + contrib/chem/examples/122/ch2a_ethyl.chem | 43 + contrib/chem/examples/122/ch2b_benzene.chem | 38 + contrib/chem/examples/122/ch2c_benzene_right.chem | 36 + contrib/chem/examples/122/ch4a_stick.chem | 45 + contrib/chem/examples/122/ch4b_methyl_acetate.chem | 47 + contrib/chem/examples/122/ch4c_colon.chem | 42 + contrib/chem/examples/122/ch4d_HCl.H2O.chem | 38 + contrib/chem/examples/122/ch4e_CaSO4.2H2O.chem | 38 + contrib/chem/examples/122/ch4f_C.chem | 48 + contrib/chem/examples/122/ch4g_BP.chem | 48 + contrib/chem/examples/122/ch4h_methacrylate.chem | 65 + contrib/chem/examples/122/ch4i_cyclo.chem | 45 + contrib/chem/examples/122/ch4j_ring4.chem | 40 + contrib/chem/examples/122/ch4k_ring3.chem | 40 + contrib/chem/examples/122/ch4l_vertex.chem | 45 + contrib/chem/examples/122/ch4m_double.chem | 38 + contrib/chem/examples/122/ch4n_triple.chem | 38 + contrib/chem/examples/122/ch4o_aromatic.chem | 37 + contrib/chem/examples/122/ch4p_cholestanol.chem | 60 + contrib/chem/examples/122/ch4q_rings.chem | 46 + contrib/chem/examples/122/ch4r_spiro.chem | 42 + contrib/chem/examples/122/ch4s_heteroatoms.chem | 38 + contrib/chem/examples/122/ch4t_polycyclic.chem | 49 + contrib/chem/examples/122/ch4u_nicotine.chem | 42 + contrib/chem/examples/122/ch4v_histidine.chem | 44 + contrib/chem/examples/122/ch4w_lsd.chem | 50 + contrib/chem/examples/122/ch4x_anisole.chem | 42 + contrib/chem/examples/122/ch4y_reserpine.chem | 62 + contrib/chem/examples/122/ch4z1_eqn_glutamic.chem | 78 + contrib/chem/examples/122/ch4z2_text.chem | 53 + contrib/chem/examples/122/ch5a_size.chem | 45 + contrib/chem/examples/122/ch6a_pic.chem | 43 + contrib/chem/examples/122/ch6b_dna.chem | 59 + contrib/chem/examples/122/chAa_polymer.chem | 72 + contrib/chem/examples/122/chAb_vinyl_chloro.chem | 62 + contrib/chem/examples/122/chAc_morphine.chem | 52 + contrib/chem/examples/122/chAd_chlorophyll.chem | 69 + contrib/chem/examples/122/chAe_chair.chem | 49 + contrib/chem/examples/122/chAf_arrow.chem | 68 + contrib/chem/examples/122/chAg_circle.chem | 54 + contrib/chem/examples/122/chAh_brackets.chem | 60 + .../examples/122/chAi_poly_vinyl_chloride.chem | 141 + contrib/chem/examples/122/chBa_jump.chem | 41 + contrib/chem/examples/122/chBb_bonds.chem | 42 + contrib/chem/examples/122/chBc_rings.chem | 43 + contrib/chem/examples/README.txt | 47 + contrib/chem/examples/atp.chem | 58 + contrib/chem/examples/cholesterin.chem | 47 + contrib/chem/examples/ethamivan.chem | 43 + contrib/chem/examples/lsd.chem | 46 + contrib/chem/examples/morphine.chem | 51 + contrib/chem/examples/penicillin.chem | 52 + contrib/chem/examples/reserpine.chem | 63 + contrib/eqn2graph/eqn2graph.1.man | 188 + contrib/eqn2graph/eqn2graph.am | 40 + contrib/eqn2graph/eqn2graph.sh | 108 + contrib/gdiffmk/ChangeLog | 212 + contrib/gdiffmk/README | 53 + contrib/gdiffmk/gdiffmk.1.man | 304 + contrib/gdiffmk/gdiffmk.am | 59 + contrib/gdiffmk/gdiffmk.sh | 367 + contrib/gdiffmk/tests/baseline | 17 + contrib/gdiffmk/tests/baseline.10 | 26 + contrib/gdiffmk/tests/baseline.6 | 17 + contrib/gdiffmk/tests/baseline.6a | 17 + contrib/gdiffmk/tests/baseline.7 | 2 + contrib/gdiffmk/tests/baseline.8 | 26 + contrib/gdiffmk/tests/baseline.9 | 26 + contrib/gdiffmk/tests/baseline.9a | 26 + contrib/gdiffmk/tests/file1 | 11 + contrib/gdiffmk/tests/file2 | 11 + contrib/gdiffmk/tests/runtests.sh | 187 + contrib/glilypond/ChangeLog | 290 + contrib/glilypond/ChangeLog.0x | 104 + contrib/glilypond/README.txt | 43 + contrib/glilypond/examples/example.groff | 46 + contrib/glilypond/glilypond.1.man | 881 + contrib/glilypond/glilypond.am | 64 + contrib/glilypond/glilypond.pl | 1907 ++ contrib/gperl/ChangeLog | 142 + contrib/gperl/gperl.1.man | 491 + contrib/gperl/gperl.am | 48 + contrib/gperl/gperl.pl | 257 + contrib/gpinyin/ChangeLog | 200 + contrib/gpinyin/gpinyin.1.man | 378 + contrib/gpinyin/gpinyin.am | 56 + contrib/gpinyin/gpinyin.pl | 725 + contrib/grap2graph/grap2graph.1.man | 205 + contrib/grap2graph/grap2graph.am | 40 + contrib/grap2graph/grap2graph.sh | 107 + contrib/hdtbl/ChangeLog | 548 + contrib/hdtbl/TODO | 21 + contrib/hdtbl/examples/chess_board.roff | 64 + contrib/hdtbl/examples/col_rowspan_colors.roff | 82 + contrib/hdtbl/examples/color_boxes.roff | 52 + contrib/hdtbl/examples/color_nested_tables.roff | 60 + contrib/hdtbl/examples/color_table_cells.roff | 54 + contrib/hdtbl/examples/color_transitions.roff | 58 + contrib/hdtbl/examples/common.roff | 295 + contrib/hdtbl/examples/fonts_n.in | 149 + contrib/hdtbl/examples/fonts_x.in | 160 + contrib/hdtbl/examples/mixed_pickles.roff | 104 + contrib/hdtbl/examples/rainbow.roff | 86 + contrib/hdtbl/examples/short_reference.roff | 86 + contrib/hdtbl/examples/test-hdtbl.sh.in | 47 + contrib/hdtbl/groff_hdtbl.7.man | 1346 + contrib/hdtbl/hdmisc.tmac | 327 + contrib/hdtbl/hdtbl.am | 136 + contrib/hdtbl/hdtbl.tmac | 1003 + contrib/mm/ChangeLog | 1672 + contrib/mm/Makefile.sim | 84 + contrib/mm/NOTES | 116 + contrib/mm/README | 27 + contrib/mm/examples/APP | 359 + contrib/mm/examples/B1B2 | 98 + contrib/mm/examples/COVER | 242 + contrib/mm/examples/IND | 4198 +++ contrib/mm/examples/LT | 1065 + contrib/mm/examples/LT.se | 1069 + contrib/mm/examples/ML | 176 + contrib/mm/examples/MOVE | 182 + contrib/mm/examples/MUL | 542 + contrib/mm/examples/NCOL | 203 + contrib/mm/examples/ND | 24 + contrib/mm/examples/README | 40 + contrib/mm/examples/References | 982 + contrib/mm/examples/SETR | 116 + contrib/mm/examples/letter.mm | 51 + contrib/mm/groff_mm.7.man | 5428 ++++ contrib/mm/groff_mmse.7.man | 183 + contrib/mm/m.tmac | 3734 +++ contrib/mm/mm.am | 128 + contrib/mm/mm.tmac | 4 + contrib/mm/mm/0.MT | 175 + contrib/mm/mm/4.MT | 110 + contrib/mm/mm/5.MT | 61 + contrib/mm/mm/ms.cov | 121 + contrib/mm/mm/se_ms.cov | 3 + contrib/mm/mmroff.1.man | 171 + contrib/mm/mmroff.pl | 179 + contrib/mm/mmse.tmac | 4 + contrib/mm/mse.tmac | 166 + contrib/mm/refer-mm.tmac | 109 + contrib/mm/tests/LT_SP_AU_without_AT_works.sh | 50 + contrib/mm/tests/LT_SP_multi-word_LO_SJ_works.sh | 49 + contrib/mm/tests/MT-1-reports-all-TM-numbers.sh | 53 + contrib/mm/tests/MT_5_includes_AT_in_SG.sh | 43 + contrib/mm/tests/P-indentation-works.sh | 135 + contrib/mm/tests/artifacts/60657.ref | 11 + .../tests/ms_cover_sheet_robust_to_missing_AF.sh | 39 + .../mm/tests/mse_has-sufficient-footnote-space.sh | 77 + .../place-equation-labels-correctly-in-displays.sh | 62 + contrib/mm/tests/remove-stale-bib-entry-data.sh | 72 + .../mm/tests/short-pages-do-not-overflow-stack.sh | 59 + contrib/mom/BUGS | 985 + contrib/mom/ChangeLog | 1788 ++ contrib/mom/NEWS | 710 + contrib/mom/TODO | 10 + contrib/mom/copyright | 24 + contrib/mom/examples/README-fr.txt | 126 + contrib/mom/examples/README.txt | 119 + contrib/mom/examples/copyright-chapter.mom | 160 + contrib/mom/examples/copyright-default.mom | 149 + contrib/mom/examples/elvis_syntax | 96 + contrib/mom/examples/elvis_syntax.new | 116 + contrib/mom/examples/letter.mom | 46 + contrib/mom/examples/mom-pdf.mom | 620 + contrib/mom/examples/mom.vim | 140 + contrib/mom/examples/mon_premier_doc.mom | 140 + contrib/mom/examples/penguin.pdf | 148 + contrib/mom/examples/penguin.ps | 461 + contrib/mom/examples/sample_docs.mom | 713 + contrib/mom/examples/slide-demo.mom | 438 + contrib/mom/examples/test-mom.sh.in | 92 + contrib/mom/examples/typesetting.mom | 707 + contrib/mom/groff_mom.7.man | 3427 ++ contrib/mom/mom.am | 182 + contrib/mom/mom.tmac | 3 + contrib/mom/momdoc/appendices.html | 901 + contrib/mom/momdoc/color.html | 505 + contrib/mom/momdoc/cover.html | 851 + contrib/mom/momdoc/definitions.html | 995 + contrib/mom/momdoc/docelement.html | 6639 ++++ contrib/mom/momdoc/docprocessing.html | 4420 +++ contrib/mom/momdoc/goodies.html | 1785 ++ contrib/mom/momdoc/graphical.html | 689 + contrib/mom/momdoc/headfootpage.html | 2341 ++ contrib/mom/momdoc/images.html | 3515 ++ contrib/mom/momdoc/inlines.html | 1112 + contrib/mom/momdoc/intro.html | 487 + contrib/mom/momdoc/letters.html | 577 + contrib/mom/momdoc/macrolist.html | 1529 + contrib/mom/momdoc/rectoverso.html | 350 + contrib/mom/momdoc/refer.html | 2129 ++ contrib/mom/momdoc/reserved.html | 2736 ++ contrib/mom/momdoc/stylesheet.css | 691 + contrib/mom/momdoc/tables-of-contents.html | 1224 + contrib/mom/momdoc/toc.html | 476 + contrib/mom/momdoc/typesetting.html | 4988 +++ contrib/mom/momdoc/using.html | 319 + contrib/mom/momdoc/version-2.html | 424 + contrib/mom/om.tmac | 24571 ++++++++++++++ contrib/pdfmark/ChangeLog | 683 + contrib/pdfmark/PROBLEMS | 32 + contrib/pdfmark/README | 57 + contrib/pdfmark/TODO | 60 + contrib/pdfmark/cover.ms | 70 + contrib/pdfmark/pdfmark.am | 99 + contrib/pdfmark/pdfmark.ms | 2831 ++ contrib/pdfmark/pdfmark.tmac | 1953 ++ contrib/pdfmark/pdfroff.1.man | 981 + contrib/pdfmark/pdfroff.sh | 682 + contrib/pdfmark/sanitize.tmac | 170 + contrib/pdfmark/spdf.tmac | 328 + contrib/pic2graph/pic2graph.1.man | 234 + contrib/pic2graph/pic2graph.am | 40 + contrib/pic2graph/pic2graph.sh | 122 + contrib/rfc1345/COPYRIGHT | 23 + contrib/rfc1345/groff_rfc1345.7.man | 265 + contrib/rfc1345/rfc1345.am | 41 + contrib/rfc1345/rfc1345.tmac | 1705 + contrib/rfc1345/tests/rfc1345-smoke-test.sh | 31 + contrib/sboxes/ChangeLog | 202 + contrib/sboxes/msboxes.ms.in | 272 + contrib/sboxes/notquine.sed | 18 + contrib/sboxes/sboxes.am | 74 + contrib/sboxes/sboxes.tmac | 147 + doc/automake.mom | 789 + doc/doc.am | 711 + doc/fdl.texi | 505 + doc/gnu.eps | 784 + doc/gnu.xpm | 198 + doc/grnexmpl.g | 3250 ++ doc/grnexmpl.me | 88 + doc/groff.css | 17 + doc/groff.dvi | Bin 0 -> 1369752 bytes doc/groff.html | 24945 +++++++++++++++ doc/groff.html.node/Adjustment.html | 57 + doc/groff.html.node/Argument-Units.html | 68 + doc/groff.html.node/Artificial-Fonts.html | 252 + .../Assigning-Register-Formats.html | 188 + doc/groff.html.node/Auto_002dincrement.html | 124 + doc/groff.html.node/Background.html | 96 + doc/groff.html.node/Basics.html | 232 + doc/groff.html.node/Blank-Line-Traps.html | 71 + doc/groff.html.node/Breaking.html | 119 + doc/groff.html.node/Built_002din-Registers.html | 253 + doc/groff.html.node/Calling-Macros.html | 164 + doc/groff.html.node/Changing-the-Type-Size.html | 159 + .../Changing-the-Vertical-Spacing.html | 146 + doc/groff.html.node/Character-Classes.html | 140 + doc/groff.html.node/Character-Translations.html | 200 + doc/groff.html.node/Colors.html | 208 + doc/groff.html.node/Columnation.html | 53 + doc/groff.html.node/Command-Reference.html | 60 + doc/groff.html.node/Comment-Command.html | 65 + doc/groff.html.node/Comments.html | 157 + doc/groff.html.node/Common-Features.html | 89 + doc/groff.html.node/Compatibility-Mode.html | 221 + doc/groff.html.node/Concept-Index.html | 2359 ++ doc/groff.html.node/Conditional-Blocks.html | 174 + doc/groff.html.node/Conditionals-and-Loops.html | 64 + .../Configuration-and-Customization.html | 56 + doc/groff.html.node/Control-Characters.html | 137 + .../Conventions-Used-in-This-Manual.html | 124 + doc/groff.html.node/Copy-Mode.html | 256 + doc/groff.html.node/Copying-This-Manual.html | 534 + doc/groff.html.node/Credits.html | 58 + doc/groff.html.node/DESC-File-Format.html | 258 + doc/groff.html.node/Debugging.html | 317 + doc/groff.html.node/Default-Units.html | 87 + doc/groff.html.node/Deferring-Output.html | 106 + doc/groff.html.node/Delimiters.html | 233 + doc/groff.html.node/Device-Control-Commands.html | 185 + .../Device-and-Font-Description-Files.html | 77 + .../Differences-from-AT_0026T-ms.html | 171 + doc/groff.html.node/Displays-and-Keeps.html | 74 + doc/groff.html.node/Diversion-Traps.html | 79 + doc/groff.html.node/Diversions.html | 394 + doc/groff.html.node/Document-Formats.html | 57 + doc/groff.html.node/Document-Parts.html | 84 + doc/groff.html.node/Drawing-Geometric-Objects.html | 361 + doc/groff.html.node/Dummy-Characters.html | 166 + .../End_002dof_002dinput-Traps.html | 187 + doc/groff.html.node/Environment.html | 151 + doc/groff.html.node/Environments.html | 250 + doc/groff.html.node/Escape-Sequence-Index.html | 162 + doc/groff.html.node/Fields.html | 98 + doc/groff.html.node/File-Formats.html | 62 + doc/groff.html.node/File-Keyword-Index.html | 215 + doc/groff.html.node/Filling.html | 79 + .../Font-Description-File-Format.html | 280 + doc/groff.html.node/Font-Directories.html | 113 + doc/groff.html.node/Font-Families.html | 182 + doc/groff.html.node/Font-Positions.html | 138 + doc/groff.html.node/Font-and-Size-Changes.html | 56 + doc/groff.html.node/Footnotes-and-Endnotes.html | 60 + doc/groff.html.node/Formatter-Instructions.html | 83 + doc/groff.html.node/GNU-troff-Reference.html | 99 + doc/groff.html.node/Graphics-Commands.html | 247 + doc/groff.html.node/Groff-Options.html | 536 + doc/groff.html.node/Gtroff-Internals.html | 187 + doc/groff.html.node/Headers-and-Footers.html | 61 + doc/groff.html.node/Headings-in-ms.html | 214 + doc/groff.html.node/Hyphenation.html | 66 + doc/groff.html.node/I_002fO.html | 457 + doc/groff.html.node/Identifiers.html | 210 + .../Implementation-Differences.html | 64 + doc/groff.html.node/Indented-regions-in-ms.html | 112 + doc/groff.html.node/Indexing.html | 58 + doc/groff.html.node/Input-Conventions.html | 171 + doc/groff.html.node/Input-Encodings.html | 154 + doc/groff.html.node/Input-Line-Traps.html | 185 + doc/groff.html.node/Installation.html | 57 + .../Intermediate-Output-Examples.html | 171 + doc/groff.html.node/Interpolating-Registers.html | 99 + doc/groff.html.node/Introduction.html | 68 + doc/groff.html.node/Invocation-Examples.html | 120 + doc/groff.html.node/Invoking-Requests.html | 143 + doc/groff.html.node/Invoking-groff.html | 82 + doc/groff.html.node/Italic-Corrections.html | 96 + doc/groff.html.node/Language-Concepts.html | 70 + doc/groff.html.node/Leaders.html | 126 + doc/groff.html.node/Leading-Space-Traps.html | 82 + doc/groff.html.node/Ligatures-and-Kerning.html | 157 + doc/groff.html.node/Line-Continuation.html | 166 + doc/groff.html.node/Line-Layout.html | 267 + doc/groff.html.node/Lists-in-ms.html | 216 + doc/groff.html.node/Macro-Directories.html | 125 + doc/groff.html.node/Macro-Index.html | 335 + doc/groff.html.node/Macro-Package-Intro.html | 63 + doc/groff.html.node/Macro-Packages.html | 64 + doc/groff.html.node/Major-Macro-Packages.html | 103 + .../Manipulating-Filling-and-Adjustment.html | 501 + doc/groff.html.node/Manipulating-Hyphenation.html | 580 + doc/groff.html.node/Manipulating-Spacing.html | 220 + ...anipulating-Type-Size-and-Vertical-Spacing.html | 74 + doc/groff.html.node/Measurements.html | 177 + doc/groff.html.node/Miscellaneous.html | 275 + .../Missing-Unix-Version-7-ms-Macros.html | 78 + doc/groff.html.node/Motion-Quanta.html | 93 + doc/groff.html.node/Numeric-Expressions.html | 395 + doc/groff.html.node/Obsolete-Command.html | 74 + doc/groff.html.node/Operator-Index.html | 188 + doc/groff.html.node/Operators-in-Conditionals.html | 222 + doc/groff.html.node/Optional-man-extensions.html | 264 + doc/groff.html.node/Other-Differences.html | 248 + doc/groff.html.node/Output-Device-Intro.html | 63 + .../Output-Language-Compatibility.html | 103 + doc/groff.html.node/Page-Control.html | 218 + doc/groff.html.node/Page-Geometry.html | 140 + doc/groff.html.node/Page-Layout-Adjustment.html | 57 + doc/groff.html.node/Page-Layout.html | 188 + doc/groff.html.node/Page-Location-Traps.html | 326 + doc/groff.html.node/Page-Motions.html | 454 + doc/groff.html.node/Paper-Format.html | 101 + doc/groff.html.node/Paragraphs-in-ms.html | 160 + doc/groff.html.node/Paragraphs.html | 109 + doc/groff.html.node/Parameters.html | 195 + doc/groff.html.node/Postprocessor-Access.html | 144 + doc/groff.html.node/Predefined-Text.html | 53 + doc/groff.html.node/Preprocessor-Intro.html | 78 + doc/groff.html.node/Preprocessor-Support.html | 56 + doc/groff.html.node/Program-and-File-Index.html | 239 + doc/groff.html.node/Punning-Names.html | 190 + doc/groff.html.node/Register-Index.html | 349 + doc/groff.html.node/Registers.html | 65 + doc/groff.html.node/Request-Index.html | 394 + doc/groff.html.node/Requests-and-Macros.html | 221 + doc/groff.html.node/Safer-Mode.html | 61 + doc/groff.html.node/Sections-and-Chapters.html | 56 + doc/groff.html.node/Selecting-Fonts.html | 227 + doc/groff.html.node/Sentences.html | 174 + doc/groff.html.node/Separation.html | 94 + doc/groff.html.node/Setting-Registers.html | 215 + doc/groff.html.node/Simple-Commands.html | 207 + doc/groff.html.node/Special-Fonts.html | 93 + doc/groff.html.node/String-Index.html | 344 + doc/groff.html.node/Strings.html | 429 + doc/groff.html.node/Suppressing-Output.html | 147 + doc/groff.html.node/Tab-Stops-in-ms.html | 67 + doc/groff.html.node/Table-of-Contents.html | 71 + doc/groff.html.node/Tabs-and-Fields.html | 276 + doc/groff.html.node/Tabs-and-Leaders.html | 87 + doc/groff.html.node/Text-settings-in-ms.html | 76 + doc/groff.html.node/Text.html | 81 + doc/groff.html.node/The-Implicit-Page-Trap.html | 74 + doc/groff.html.node/Traps.html | 73 + doc/groff.html.node/Tutorial-for-Macro-Users.html | 68 + doc/groff.html.node/Typeface-and-decoration.html | 212 + .../Typographical-symbols-in-ms.html | 80 + doc/groff.html.node/Using-Escape-Sequences.html | 206 + doc/groff.html.node/Using-Fonts.html | 148 + .../Using-Fractional-Type-Sizes.html | 172 + doc/groff.html.node/Using-Symbols.html | 632 + doc/groff.html.node/Vertical-Position-Traps.html | 94 + doc/groff.html.node/Warnings.html | 246 + doc/groff.html.node/What-Is-groff_003f.html | 68 + doc/groff.html.node/Writing-Macros.html | 267 + doc/groff.html.node/als.html | 33 + doc/groff.html.node/groff-Capabilities.html | 91 + doc/groff.html.node/groff.html_fot.html | 525 + doc/groff.html.node/gtroff-Output.html | 100 + doc/groff.html.node/if_002delse.html | 97 + doc/groff.html.node/if_002dthen.html | 111 + doc/groff.html.node/index.html | 453 + doc/groff.html.node/man.html | 71 + doc/groff.html.node/mdoc.html | 61 + doc/groff.html.node/me.html | 67 + doc/groff.html.node/mm.html | 64 + doc/groff.html.node/mom.html | 85 + doc/groff.html.node/ms-Body-Text.html | 70 + .../ms-Document-Control-Settings.html | 524 + .../ms-Document-Description-Macros.html | 189 + doc/groff.html.node/ms-Document-Structure.html | 106 + doc/groff.html.node/ms-Footnotes.html | 155 + doc/groff.html.node/ms-Headers-and-Footers.html | 122 + doc/groff.html.node/ms-Insertions.html | 181 + doc/groff.html.node/ms-Introduction.html | 60 + doc/groff.html.node/ms-Legacy-Features.html | 285 + doc/groff.html.node/ms-Margins.html | 56 + doc/groff.html.node/ms-Multiple-Columns.html | 88 + doc/groff.html.node/ms-Naming-Conventions.html | 89 + doc/groff.html.node/ms-Page-Layout.html | 64 + doc/groff.html.node/ms-TOC.html | 242 + doc/groff.html.node/ms-basic-information.html | 211 + doc/groff.html.node/ms-keeps-and-displays.html | 207 + .../ms-language-and-localization.html | 135 + doc/groff.html.node/ms.html | 75 + doc/groff.html.node/troff-and-nroff-Modes.html | 114 + doc/groff.html.node/while.html | 161 + doc/groff.info | 423 + doc/groff.info-1 | 7824 +++++ doc/groff.info-2 | 7529 +++++ doc/groff.info-3 | Bin 0 -> 238373 bytes doc/groff.pdf | Bin 0 -> 1148308 bytes doc/groff.texi | 18927 +++++++++++ doc/groff.txt | 18123 +++++++++++ doc/me-revisions | 261 + doc/meintro.me.in | 2266 ++ doc/meintro_fr.me.in | 2374 ++ doc/meref.me.in | 2439 ++ doc/ms.ms | 4486 +++ doc/pic.ms | 3287 ++ doc/txi-en.tex | 74 + doc/webpage.ms | 2580 ++ font/devX100-12/CB | 215 + font/devX100-12/CBI | 215 + font/devX100-12/CI | 215 + font/devX100-12/CR | 215 + font/devX100-12/DESC | 9 + font/devX100-12/HB | 215 + font/devX100-12/HBI | 215 + font/devX100-12/HI | 215 + font/devX100-12/HR | 215 + font/devX100-12/NB | 215 + font/devX100-12/NBI | 215 + font/devX100-12/NI | 215 + font/devX100-12/NR | 215 + font/devX100-12/S | 221 + font/devX100-12/TB | 215 + font/devX100-12/TBI | 215 + font/devX100-12/TI | 215 + font/devX100-12/TR | 215 + font/devX100-12/devX100-12.am | 65 + font/devX100/CB | 215 + font/devX100/CBI | 215 + font/devX100/CI | 215 + font/devX100/CR | 215 + font/devX100/DESC | 9 + font/devX100/HB | 215 + font/devX100/HBI | 215 + font/devX100/HI | 215 + font/devX100/HR | 215 + font/devX100/NB | 215 + font/devX100/NBI | 215 + font/devX100/NI | 215 + font/devX100/NR | 215 + font/devX100/S | 221 + font/devX100/TB | 215 + font/devX100/TBI | 215 + font/devX100/TI | 215 + font/devX100/TR | 215 + font/devX100/devX100.am | 65 + font/devX75-12/CB | 215 + font/devX75-12/CBI | 215 + font/devX75-12/CI | 215 + font/devX75-12/CR | 215 + font/devX75-12/DESC | 9 + font/devX75-12/HB | 215 + font/devX75-12/HBI | 215 + font/devX75-12/HI | 215 + font/devX75-12/HR | 215 + font/devX75-12/NB | 215 + font/devX75-12/NBI | 215 + font/devX75-12/NI | 215 + font/devX75-12/NR | 215 + font/devX75-12/S | 221 + font/devX75-12/TB | 215 + font/devX75-12/TBI | 215 + font/devX75-12/TI | 215 + font/devX75-12/TR | 215 + font/devX75-12/devX75-12.am | 65 + font/devX75/CB | 215 + font/devX75/CBI | 215 + font/devX75/CI | 215 + font/devX75/CR | 215 + font/devX75/DESC | 9 + font/devX75/HB | 215 + font/devX75/HBI | 215 + font/devX75/HI | 215 + font/devX75/HR | 215 + font/devX75/NB | 215 + font/devX75/NBI | 215 + font/devX75/NI | 215 + font/devX75/NR | 215 + font/devX75/S | 221 + font/devX75/TB | 215 + font/devX75/TBI | 215 + font/devX75/TI | 215 + font/devX75/TR | 215 + font/devX75/devX75.am | 65 + font/devascii/DESC.proto | 8 + font/devascii/R.proto | 190 + font/devascii/devascii.am | 51 + font/devcp1047/DESC.proto | 8 + font/devcp1047/R.proto | 322 + font/devcp1047/devcp1047.am | 49 + font/devdvi/CW | 152 + font/devdvi/CWEC | 280 + font/devdvi/CWI | 151 + font/devdvi/CWIEC | 281 + font/devdvi/CWITC | 138 + font/devdvi/CWTC | 137 + font/devdvi/DESC.in | 11 + font/devdvi/EX | 144 + font/devdvi/HB | 297 + font/devdvi/HBEC | 2078 ++ font/devdvi/HBI | 298 + font/devdvi/HBIEC | 2079 ++ font/devdvi/HBITC | 138 + font/devdvi/HBTC | 137 + font/devdvi/HI | 298 + font/devdvi/HIEC | 2079 ++ font/devdvi/HITC | 138 + font/devdvi/HR | 297 + font/devdvi/HREC | 2078 ++ font/devdvi/HRTC | 137 + font/devdvi/MI | 137 + font/devdvi/S | 150 + font/devdvi/SA | 142 + font/devdvi/SB | 132 + font/devdvi/SC | 137 + font/devdvi/TB | 348 + font/devdvi/TBEC | 2306 ++ font/devdvi/TBI | 354 + font/devdvi/TBIEC | 2765 ++ font/devdvi/TBITC | 138 + font/devdvi/TBTC | 137 + font/devdvi/TI | 355 + font/devdvi/TIEC | 2765 ++ font/devdvi/TITC | 138 + font/devdvi/TR | 431 + font/devdvi/TREC | 2306 ++ font/devdvi/TRTC | 137 + font/devdvi/devdvi.am | 96 + font/devdvi/generate/CompileFonts | 15 + font/devdvi/generate/Makefile | 211 + font/devdvi/generate/ec.map | 255 + font/devdvi/generate/msam.map | 127 + font/devdvi/generate/msbm.map | 121 + font/devdvi/generate/tc.map | 81 + font/devdvi/generate/texb.map | 128 + font/devdvi/generate/texex.map | 100 + font/devdvi/generate/texi.map | 128 + font/devdvi/generate/texmi.map | 46 + font/devdvi/generate/texr.map | 128 + font/devdvi/generate/texsy.map | 127 + font/devdvi/generate/textex.map | 34 + font/devdvi/generate/textt.map | 128 + font/devhtml/DESC.proto | 13 + font/devhtml/R.in | 8 + font/devhtml/R.proto | 1035 + font/devhtml/devhtml.am | 69 + font/devlatin1/DESC.proto | 8 + font/devlatin1/R.proto | 322 + font/devlatin1/devlatin1.am | 49 + font/devlbp/CB | 216 + font/devlbp/CI | 216 + font/devlbp/CR | 216 + font/devlbp/DESC.in | 9 + font/devlbp/EB | 216 + font/devlbp/EI | 216 + font/devlbp/ER | 216 + font/devlbp/HB | 400 + font/devlbp/HBI | 401 + font/devlbp/HI | 401 + font/devlbp/HNB | 400 + font/devlbp/HNBI | 400 + font/devlbp/HNI | 400 + font/devlbp/HNR | 400 + font/devlbp/HR | 400 + font/devlbp/TB | 422 + font/devlbp/TBI | 402 + font/devlbp/TI | 430 + font/devlbp/TR | 426 + font/devlbp/devlbp.am | 60 + font/devlj4/AB | 428 + font/devlj4/ABI | 428 + font/devlj4/AI | 426 + font/devlj4/ALBB | 756 + font/devlj4/ALBR | 771 + font/devlj4/AOB | 720 + font/devlj4/AOI | 782 + font/devlj4/AOR | 708 + font/devlj4/AR | 430 + font/devlj4/CB | 330 + font/devlj4/CBI | 331 + font/devlj4/CI | 331 + font/devlj4/CLARENDON | 331 + font/devlj4/CORONET | 332 + font/devlj4/CR | 330 + font/devlj4/DESC.in | 9 + font/devlj4/GB | 718 + font/devlj4/GBI | 718 + font/devlj4/GI | 653 + font/devlj4/GR | 836 + font/devlj4/LGB | 330 + font/devlj4/LGI | 331 + font/devlj4/LGR | 330 + font/devlj4/MARIGOLD | 331 + font/devlj4/OB | 784 + font/devlj4/OBI | 776 + font/devlj4/OI | 887 + font/devlj4/OR | 863 + font/devlj4/S | 319 + font/devlj4/SYMBOL | 220 + font/devlj4/TB | 953 + font/devlj4/TBI | 1006 + font/devlj4/TI | 1090 + font/devlj4/TNRB | 444 + font/devlj4/TNRBI | 433 + font/devlj4/TNRI | 450 + font/devlj4/TNRR | 436 + font/devlj4/TR | 843 + font/devlj4/UB | 797 + font/devlj4/UBI | 748 + font/devlj4/UCB | 758 + font/devlj4/UCBI | 666 + font/devlj4/UCI | 806 + font/devlj4/UCR | 727 + font/devlj4/UI | 950 + font/devlj4/UR | 848 + font/devlj4/WINGDINGS | 230 + font/devlj4/devlj4.am | 111 + font/devlj4/generate/Makefile | 274 + font/devlj4/generate/special.awk | 80 + font/devlj4/generate/special.map | 271 + font/devlj4/generate/symbol.map | 199 + font/devlj4/generate/text.map | 845 + font/devlj4/generate/wingdings.map | 233 + font/devpdf/DESC.in | 11 + font/devpdf/Foundry.in | 121 + font/devpdf/devpdf.am | 210 + font/devpdf/tests/check-default-foundry.sh.in | 99 + font/devpdf/tests/check-urw-foundry.sh.in | 86 + font/devpdf/util/BuildFoundries.pl | 578 + font/devps/AB | 700 + font/devps/ABI | 701 + font/devps/AI | 688 + font/devps/AR | 687 + font/devps/BMB | 696 + font/devps/BMBI | 697 + font/devps/BMI | 648 + font/devps/BMR | 670 + font/devps/CB | 266 + font/devps/CBI | 267 + font/devps/CI | 267 + font/devps/CR | 266 + font/devps/DESC.in | 11 + font/devps/EURO | 33 + font/devps/HB | 1513 + font/devps/HBI | 1514 + font/devps/HI | 1645 + font/devps/HNB | 1513 + font/devps/HNBI | 1514 + font/devps/HNI | 1645 + font/devps/HNR | 1644 + font/devps/HR | 1644 + font/devps/NB | 964 + font/devps/NBI | 1614 + font/devps/NI | 1222 + font/devps/NR | 1175 + font/devps/PB | 728 + font/devps/PBI | 754 + font/devps/PI | 753 + font/devps/PR | 767 + font/devps/S | 244 + font/devps/SS | 210 + font/devps/TB | 573 + font/devps/TBI | 548 + font/devps/TI | 561 + font/devps/TR | 554 + font/devps/ZCMI | 910 + font/devps/ZD | 222 + font/devps/ZDR | 222 + font/devps/devps.am | 193 + font/devps/download | 6 + font/devps/freeeuro.afm | 34 + font/devps/freeeuro.ps | 321 + font/devps/generate/Makefile | 314 + font/devps/generate/afmname | 44 + font/devps/generate/dingbats-reversed.map | 4 + font/devps/generate/dingbats.map | 5 + font/devps/generate/freeeuro.sfd | 623 + font/devps/generate/make-zapfdr | 89 + font/devps/generate/sfdtopfa.pe | 9 + font/devps/generate/slanted-symbol.map | 31 + font/devps/generate/symbol.map | 449 + font/devps/generate/symbol.sed | 32 + font/devps/generate/symbolchars | 13 + font/devps/generate/symbolsl.awk | 19 + font/devps/generate/text.map | 434 + font/devps/generate/zapfdr.sed | 2 + font/devps/old/CB | 281 + font/devps/old/CBI | 282 + font/devps/old/CI | 282 + font/devps/old/CR | 281 + font/devps/old/HB | 481 + font/devps/old/HBI | 482 + font/devps/old/HI | 521 + font/devps/old/HNB | 481 + font/devps/old/HNBI | 482 + font/devps/old/HNI | 521 + font/devps/old/HNR | 520 + font/devps/old/HR | 520 + font/devps/old/NB | 392 + font/devps/old/NBI | 510 + font/devps/old/NI | 453 + font/devps/old/NR | 440 + font/devps/old/PB | 370 + font/devps/old/PBI | 376 + font/devps/old/PI | 375 + font/devps/old/PR | 377 + font/devps/old/S | 229 + font/devps/old/SS | 194 + font/devps/old/TB | 460 + font/devps/old/TBI | 443 + font/devps/old/TI | 456 + font/devps/old/TR | 448 + font/devps/old/symbol.afm | 212 + font/devps/old/symbolsl.afm | 203 + font/devps/old/zapfdr.afm | 222 + font/devps/old/zapfdr.ps | 225 + font/devps/prologue.ps | 261 + font/devps/psstrip.sed | 6 + font/devps/symbol.afm | 215 + font/devps/symbolsl.afm | 225 + font/devps/symbolsl.ps | 42 + font/devps/text.enc | 236 + font/devps/zapfdr.afm | 224 + font/devps/zapfdr.ps | 225 + font/devutf8/DESC.proto | 9 + font/devutf8/NOTES | 47 + font/devutf8/R.in | 4 + font/devutf8/R.proto | 1029 + font/devutf8/devutf8.am | 59 + font/scripts/gendesc.sh | 18 + font/scripts/genfonts.sh | 23 + font/scripts/scripts.am | 27 + font/util/make-Rproto | 47 + gendef.sh | 52 + gnulib_m4/00gnulib.m4 | 85 + gnulib_m4/absolute-header.m4 | 100 + gnulib_m4/alloca.m4 | 106 + gnulib_m4/assert_h.m4 | 67 + gnulib_m4/errno_h.m4 | 131 + gnulib_m4/exponentd.m4 | 116 + gnulib_m4/exponentf.m4 | 92 + gnulib_m4/exponentl.m4 | 112 + gnulib_m4/extensions.m4 | 232 + gnulib_m4/extern-inline.m4 | 130 + gnulib_m4/float_h.m4 | 106 + gnulib_m4/fpieee.m4 | 54 + gnulib_m4/fprintf-posix.m4 | 110 + gnulib_m4/free.m4 | 52 + gnulib_m4/frexp.m4 | 181 + gnulib_m4/frexpl.m4 | 233 + gnulib_m4/fseterr.m4 | 13 + gnulib_m4/gnulib-cache.m4 | 74 + gnulib_m4/gnulib-common.m4 | 1243 + gnulib_m4/gnulib-comp.m4 | 616 + gnulib_m4/include_next.m4 | 224 + gnulib_m4/intmax_t.m4 | 59 + gnulib_m4/inttypes.m4 | 184 + gnulib_m4/inttypes_h.m4 | 29 + gnulib_m4/isnand.m4 | 96 + gnulib_m4/isnanf.m4 | 197 + gnulib_m4/isnanl.m4 | 248 + gnulib_m4/ldexpl.m4 | 135 + gnulib_m4/libunistring-base.m4 | 145 + gnulib_m4/limits-h.m4 | 41 + gnulib_m4/math_h.m4 | 391 + gnulib_m4/memchr.m4 | 106 + gnulib_m4/mmap-anon.m4 | 55 + gnulib_m4/multiarch.m4 | 65 + gnulib_m4/nocrash.m4 | 131 + gnulib_m4/off_t.m4 | 18 + gnulib_m4/printf-frexp.m4 | 38 + gnulib_m4/printf-frexpl.m4 | 48 + gnulib_m4/printf.m4 | 1728 + gnulib_m4/signbit.m4 | 393 + gnulib_m4/size_max.m4 | 75 + gnulib_m4/snprintf.m4 | 62 + gnulib_m4/ssize_t.m4 | 23 + gnulib_m4/stdbool.m4 | 118 + gnulib_m4/stddef_h.m4 | 104 + gnulib_m4/stdint.m4 | 531 + gnulib_m4/stdint_h.m4 | 27 + gnulib_m4/stdio_h.m4 | 237 + gnulib_m4/stdlib_h.m4 | 209 + gnulib_m4/string_h.m4 | 150 + gnulib_m4/sys_types_h.m4 | 70 + gnulib_m4/unistd_h.m4 | 275 + gnulib_m4/vasnprintf.m4 | 298 + gnulib_m4/vsnprintf.m4 | 62 + gnulib_m4/warn-on-use.m4 | 62 + gnulib_m4/wchar_h.m4 | 258 + gnulib_m4/wchar_t.m4 | 24 + gnulib_m4/wctype_h.m4 | 200 + gnulib_m4/wcwidth.m4 | 115 + gnulib_m4/wint_t.m4 | 57 + gnulib_m4/xsize.m4 | 12 + gnulib_m4/zzgnulib.m4 | 23 + lib/_Noreturn.h | 50 + lib/alloca.in.h | 72 + lib/arg-nonnull.h | 26 + lib/asnprintf.c | 34 + lib/assert.in.h | 27 + lib/attribute.h | 226 + lib/c++defs.h | 331 + lib/errno.in.h | 279 + lib/float+.h | 147 + lib/float.c | 33 + lib/float.in.h | 194 + lib/fprintf.c | 73 + lib/fpucw.h | 108 + lib/free.c | 53 + lib/frexp.c | 168 + lib/frexpl.c | 35 + lib/fseterr.c | 84 + lib/fseterr.h | 45 + lib/gnulib.mk | 1823 ++ lib/inttypes.in.h | 1028 + lib/isnan.c | 190 + lib/isnand-nolibm.h | 33 + lib/isnand.c | 19 + lib/isnanf-nolibm.h | 41 + lib/isnanf.c | 20 + lib/isnanl-nolibm.h | 34 + lib/isnanl.c | 20 + lib/itold.c | 28 + lib/limits.in.h | 131 + lib/localcharset.c | 1159 + lib/localcharset.h | 137 + lib/math.c | 22 + lib/math.in.h | 2735 ++ lib/memchr.c | 172 + lib/memchr.valgrind | 30 + lib/printf-args.c | 183 + lib/printf-args.h | 150 + lib/printf-frexp.c | 190 + lib/printf-frexp.h | 23 + lib/printf-frexpl.c | 37 + lib/printf-frexpl.h | 23 + lib/printf-parse.c | 623 + lib/printf-parse.h | 193 + lib/signbitd.c | 64 + lib/signbitf.c | 64 + lib/signbitl.c | 64 + lib/size_max.h | 30 + lib/snprintf.c | 71 + lib/stdbool.in.h | 126 + lib/stddef.in.h | 147 + lib/stdint.in.h | 740 + lib/stdio-impl.h | 218 + lib/stdio-read.c | 168 + lib/stdio-write.c | 206 + lib/stdio.in.h | 1723 + lib/stdlib.in.h | 1678 + lib/streq.h | 176 + lib/string.in.h | 1355 + lib/sys_types.in.h | 106 + lib/unictype/bitmap.h | 48 + lib/unistd.c | 22 + lib/unistd.in.h | 2393 ++ lib/unitypes.in.h | 61 + lib/uniwidth.in.h | 72 + lib/uniwidth/cjk.h | 37 + lib/uniwidth/width.c | 95 + lib/uniwidth/width0.h | 494 + lib/uniwidth/width2.h | 549 + lib/vasnprintf.c | 5741 ++++ lib/vasnprintf.h | 72 + lib/verify.h | 365 + lib/vsnprintf.c | 70 + lib/warn-on-use.h | 149 + lib/wchar.in.h | 1378 + lib/wctype-h.c | 23 + lib/wctype.in.h | 732 + lib/wcwidth.c | 73 + lib/xsize.c | 21 + lib/xsize.h | 108 + m4/ax_compare_version.m4 | 177 + m4/ax_prog_perl_version.m4 | 70 + m4/codeset.m4 | 23 + m4/fcntl-o.m4 | 134 + m4/glibc21.m4 | 33 + m4/groff.m4 | 1886 ++ m4/iconv.m4 | 271 + m4/lib-ld.m4 | 119 + m4/lib-link.m4 | 777 + m4/lib-prefix.m4 | 224 + m4/localcharset.m4 | 17 + makevarescape.sed | 9 + man/groff.7.man | 8055 +++++ man/groff_char.7.man | 2282 ++ man/groff_diff.7.man | 6188 ++++ man/groff_font.5.man | 1114 + man/groff_out.5.man | 1963 ++ man/groff_tmac.5.man | 1474 + man/man.am | 46 + man/roff.7.man | 2613 ++ mdate.pl | 32 + src/devices/grodvi/dvi.cpp | 988 + src/devices/grodvi/grodvi.1.man | 633 + src/devices/grodvi/grodvi.am | 32 + src/devices/grohtml/grohtml.1.man | 731 + src/devices/grohtml/grohtml.am | 40 + src/devices/grohtml/html-table.cpp | 848 + src/devices/grohtml/html-table.h | 133 + src/devices/grohtml/html-text.cpp | 1056 + src/devices/grohtml/html-text.h | 138 + src/devices/grohtml/html.h | 97 + src/devices/grohtml/output.cpp | 363 + src/devices/grohtml/post-html.cpp | 5684 ++++ src/devices/grolbp/charset.h | 89 + src/devices/grolbp/grolbp.1.man | 504 + src/devices/grolbp/grolbp.am | 36 + src/devices/grolbp/lbp.cpp | 738 + src/devices/grolbp/lbp.h | 544 + src/devices/grolj4/grolj4.1.man | 896 + src/devices/grolj4/grolj4.am | 32 + src/devices/grolj4/lj4.cpp | 715 + src/devices/gropdf/TODO | 31 + src/devices/gropdf/gropdf.1.man | 1845 ++ src/devices/gropdf/gropdf.am | 58 + src/devices/gropdf/gropdf.pl | 3928 +++ src/devices/gropdf/pdfmom.1.man | 229 + src/devices/gropdf/pdfmom.pl | 150 + src/devices/grops/TODO | 24 + src/devices/grops/grops.1.man | 1831 ++ src/devices/grops/grops.am | 38 + src/devices/grops/ps.cpp | 1894 ++ src/devices/grops/ps.h | 129 + src/devices/grops/psfig.diff | 106 + src/devices/grops/psrm.cpp | 1189 + src/devices/grotty/TODO | 3 + src/devices/grotty/grotty.1.man | 810 + src/devices/grotty/grotty.am | 39 + .../tests/basic_latin_glyphs_map_correctly.sh | 205 + src/devices/grotty/tests/osc8_works.sh | 119 + src/devices/grotty/tty.cpp | 1043 + src/devices/xditview/ChangeLog | 556 + src/devices/xditview/DESC.in | 9 + src/devices/xditview/Dvi.c | 603 + src/devices/xditview/Dvi.h | 46 + src/devices/xditview/DviP.h | 235 + src/devices/xditview/FontMap-X11 | 17 + src/devices/xditview/GXditview-color.ad | 15 + src/devices/xditview/GXditview.ad | 71 + src/devices/xditview/Menu.h | 46 + src/devices/xditview/README | 13 + src/devices/xditview/TODO | 21 + src/devices/xditview/ad2c | 64 + src/devices/xditview/device.c | 565 + src/devices/xditview/device.h | 21 + src/devices/xditview/draw.c | 709 + src/devices/xditview/draw.h | 18 + src/devices/xditview/font.c | 446 + src/devices/xditview/font.h | 6 + src/devices/xditview/gray1.bm | 4 + src/devices/xditview/gray2.bm | 4 + src/devices/xditview/gray3.bm | 4 + src/devices/xditview/gray4.bm | 4 + src/devices/xditview/gray5.bm | 4 + src/devices/xditview/gray6.bm | 4 + src/devices/xditview/gray7.bm | 4 + src/devices/xditview/gray8.bm | 4 + src/devices/xditview/gxditview.1.man | 815 + src/devices/xditview/lex.c | 100 + src/devices/xditview/lex.h | 1 + src/devices/xditview/page.c | 86 + src/devices/xditview/page.h | 5 + src/devices/xditview/parse.c | 343 + src/devices/xditview/parse.h | 1 + src/devices/xditview/xdit.bm | 14 + src/devices/xditview/xdit_mask.bm | 14 + src/devices/xditview/xditview.am | 130 + src/devices/xditview/xditview.c | 684 + src/include/DviChar.h | 55 + src/include/XFontName.h | 50 + src/include/cmap.h | 55 + src/include/color.h | 88 + src/include/config.hin | 1584 + src/include/cset.h | 74 + src/include/curtime.h | 27 + src/include/device.h | 25 + src/include/driver.h | 38 + src/include/errarg.h | 46 + src/include/error.h | 69 + src/include/font.h | 343 + src/include/geometry.h | 26 + src/include/getopt.h | 226 + src/include/getopt_int.h | 130 + src/include/gettext.h | 22 + src/include/html-strings.h | 26 + src/include/htmlhint.h | 36 + src/include/include.am | 47 + src/include/index.h | 41 + src/include/itable.h | 193 + src/include/lf.h | 21 + src/include/lib.h | 161 + src/include/localcharset.h | 40 + src/include/macropath.h | 22 + src/include/nonposix.h | 230 + src/include/paper.h | 36 + src/include/posix.h | 66 + src/include/printer.h | 97 + src/include/ptable.h | 233 + src/include/refid.h | 34 + src/include/relocate.h | 37 + src/include/search.h | 100 + src/include/searchpath.h | 30 + src/include/stringclass.h | 194 + src/include/symbol.h | 88 + src/include/unicode.h | 63 + src/libs/libbib/common.cpp | 37 + src/libs/libbib/index.cpp | 688 + src/libs/libbib/libbib.am | 35 + src/libs/libbib/linear.cpp | 506 + src/libs/libbib/map.c | 86 + src/libs/libbib/search.cpp | 136 + src/libs/libdriver/input.cpp | 1841 ++ src/libs/libdriver/libdriver.am | 31 + src/libs/libdriver/printer.cpp | 268 + src/libs/libgroff/assert.cpp | 38 + src/libs/libgroff/change_lf.cpp | 37 + src/libs/libgroff/cmap.cpp | 56 + src/libs/libgroff/color.cpp | 404 + src/libs/libgroff/config.charset | 684 + src/libs/libgroff/cset.cpp | 104 + src/libs/libgroff/curtime.cpp | 55 + src/libs/libgroff/device.cpp | 39 + src/libs/libgroff/errarg.cpp | 136 + src/libs/libgroff/error.cpp | 185 + src/libs/libgroff/fatal.cpp | 30 + src/libs/libgroff/filename.cpp | 31 + src/libs/libgroff/fmod.c | 27 + src/libs/libgroff/font.cpp | 1321 + src/libs/libgroff/fontfile.cpp | 80 + src/libs/libgroff/geometry.cpp | 180 + src/libs/libgroff/getcwd.c | 54 + src/libs/libgroff/getopt.c | 1241 + src/libs/libgroff/getopt1.c | 172 + src/libs/libgroff/glyphuni.cpp | 523 + src/libs/libgroff/htmlhint.cpp | 60 + src/libs/libgroff/hypot.cpp | 34 + src/libs/libgroff/iftoa.c | 76 + src/libs/libgroff/invalid.cpp | 59 + src/libs/libgroff/itoa.c | 67 + src/libs/libgroff/lf.cpp | 78 + src/libs/libgroff/libgroff.am | 182 + src/libs/libgroff/lineno.cpp | 20 + src/libs/libgroff/localcharset.c | 579 + src/libs/libgroff/macropath.cpp | 29 + src/libs/libgroff/make-uniuni | 162 + src/libs/libgroff/matherr.c | 48 + src/libs/libgroff/maxfilename.cpp | 75 + src/libs/libgroff/maxpathname.cpp | 70 + src/libs/libgroff/mksdir.cpp | 33 + src/libs/libgroff/mkstemp.cpp | 33 + src/libs/libgroff/nametoindex.cpp | 167 + src/libs/libgroff/new.cpp | 75 + src/libs/libgroff/paper.cpp | 82 + src/libs/libgroff/prime.cpp | 55 + src/libs/libgroff/progname.c | 18 + src/libs/libgroff/ptable.cpp | 57 + src/libs/libgroff/putenv.c | 97 + src/libs/libgroff/quotearg.c | 213 + src/libs/libgroff/ref-add.sin | 29 + src/libs/libgroff/ref-del.sin | 24 + src/libs/libgroff/relocatable.h | 19 + src/libs/libgroff/relocate.cpp | 244 + src/libs/libgroff/searchpath.cpp | 215 + src/libs/libgroff/spawnvp.c | 120 + src/libs/libgroff/strcasecmp.c | 65 + src/libs/libgroff/strerror.c | 46 + src/libs/libgroff/string.cpp | 354 + src/libs/libgroff/strncasecmp.c | 19 + src/libs/libgroff/strsave.cpp | 40 + src/libs/libgroff/strtol.c | 131 + src/libs/libgroff/symbol.cpp | 157 + src/libs/libgroff/tmpfile.cpp | 188 + src/libs/libgroff/tmpname.cpp | 117 + src/libs/libgroff/unicode.cpp | 65 + src/libs/libgroff/uniglyph.cpp | 497 + src/libs/libgroff/uniuni.cpp | 2128 ++ src/libs/libxutil/DviChar.c | 679 + src/libs/libxutil/XFontName.c | 260 + src/libs/libxutil/libxutil.am | 35 + src/libs/libxutil/xmalloc.c | 28 + src/preproc/eqn/TODO | 49 + src/preproc/eqn/box.cpp | 651 + src/preproc/eqn/box.h | 278 + src/preproc/eqn/delim.cpp | 418 + src/preproc/eqn/eqn.1.man | 2240 ++ src/preproc/eqn/eqn.am | 79 + src/preproc/eqn/eqn.cpp | 2112 ++ src/preproc/eqn/eqn.h | 57 + src/preproc/eqn/eqn.hpp | 210 + src/preproc/eqn/eqn.ypp | 333 + src/preproc/eqn/lex.cpp | 1236 + src/preproc/eqn/limit.cpp | 217 + src/preproc/eqn/list.cpp | 241 + src/preproc/eqn/main.cpp | 485 + src/preproc/eqn/mark.cpp | 120 + src/preproc/eqn/neqn.1.man | 92 + src/preproc/eqn/neqn.sh | 26 + src/preproc/eqn/other.cpp | 706 + src/preproc/eqn/over.cpp | 204 + src/preproc/eqn/pbox.h | 140 + src/preproc/eqn/pile.cpp | 354 + src/preproc/eqn/script.cpp | 250 + src/preproc/eqn/special.cpp | 117 + src/preproc/eqn/sqrt.cpp | 186 + .../diagnostics-report-correct-line-numbers.sh | 55 + src/preproc/eqn/text.cpp | 957 + src/preproc/grn/README | 68 + src/preproc/grn/gprint.h | 90 + src/preproc/grn/grn.1.man | 978 + src/preproc/grn/grn.am | 35 + src/preproc/grn/hdb.cpp | 441 + src/preproc/grn/hgraph.cpp | 1060 + src/preproc/grn/hpoint.cpp | 59 + src/preproc/grn/main.cpp | 977 + src/preproc/html/html.am | 32 + src/preproc/html/pre-html.cpp | 1819 ++ src/preproc/html/pre-html.h | 38 + src/preproc/html/pushback.cpp | 336 + src/preproc/html/pushback.h | 52 + src/preproc/pic/TODO | 35 + src/preproc/pic/common.cpp | 647 + src/preproc/pic/common.h | 79 + src/preproc/pic/lex.cpp | 2039 ++ src/preproc/pic/main.cpp | 664 + src/preproc/pic/object.cpp | 2079 ++ src/preproc/pic/object.h | 227 + src/preproc/pic/output.h | 82 + src/preproc/pic/pic.1.man | 1569 + src/preproc/pic/pic.am | 56 + src/preproc/pic/pic.cpp | 5080 +++ src/preproc/pic/pic.h | 122 + src/preproc/pic/pic.hpp | 348 + src/preproc/pic/pic.ypp | 1957 ++ src/preproc/pic/position.h | 46 + src/preproc/pic/tex.cpp | 458 + src/preproc/pic/text.h | 46 + src/preproc/pic/troff.cpp | 579 + src/preproc/preconv/preconv.1.man | 559 + src/preproc/preconv/preconv.am | 37 + src/preproc/preconv/preconv.cpp | 1318 + .../preconv/tests/do-not-seek-the-unseekable.sh | 59 + src/preproc/preconv/tests/smoke-test.sh | 88 + src/preproc/refer/TODO | 124 + src/preproc/refer/command.cpp | 814 + src/preproc/refer/command.h | 35 + src/preproc/refer/label.cpp | 2607 ++ src/preproc/refer/label.hpp | 98 + src/preproc/refer/label.ypp | 1195 + src/preproc/refer/ref.cpp | 1161 + src/preproc/refer/ref.h | 127 + src/preproc/refer/refer.1.man | 2020 ++ src/preproc/refer/refer.am | 61 + src/preproc/refer/refer.cpp | 1267 + src/preproc/refer/refer.h | 81 + src/preproc/refer/tests/artifacts/62124.bib | 4 + .../refer/tests/report-correct-line-numbers.sh | 136 + src/preproc/refer/token.cpp | 377 + src/preproc/refer/token.h | 87 + src/preproc/soelim/TODO | 1 + src/preproc/soelim/soelim.1.man | 456 + src/preproc/soelim/soelim.am | 31 + src/preproc/soelim/soelim.cpp | 315 + src/preproc/tbl/main.cpp | 1692 + src/preproc/tbl/table.cpp | 3161 ++ src/preproc/tbl/table.h | 179 + src/preproc/tbl/tbl.1.man | 2018 ++ src/preproc/tbl/tbl.am | 54 + src/preproc/tbl/tests/boxes-and-vertical-rules.sh | 174 + .../tbl/tests/check-horizontal-line-length.sh | 78 + src/preproc/tbl/tests/check-line-intersections.sh | 52 + .../tbl/tests/check-vertical-line-length.sh | 49 + src/preproc/tbl/tests/cooperate-with-nm-request.sh | 47 + .../tbl/tests/count-continued-input-lines.sh | 43 + .../do-not-overdraw-page-top-in-nroff-mode.sh | 225 + .../tests/do-not-overlap-bottom-border-in-nroff.sh | 62 + .../do-not-segv-on-invalid-vertical-span-entry.sh | 41 + .../do-not-segv-when-backslash-R-in-text-block.sh | 75 + .../tbl/tests/expand-region-option-works.sh | 173 + .../tbl/tests/format-time-diagnostics-work.sh | 268 + .../save-and-restore-hyphenation-parameters.sh | 58 + .../tests/save-and-restore-inter-sentence-space.sh | 79 + .../tbl/tests/save-and-restore-line-numbering.sh | 85 + .../tbl/tests/save-and-restore-tab-stops.sh | 84 + .../tbl/tests/warn-on-long-boxed-unkept-table.sh | 56 + src/preproc/tbl/tests/x-column-modifier-works.sh | 172 + src/roff/groff/groff.1.man | 2403 ++ src/roff/groff/groff.am | 87 + src/roff/groff/groff.cpp | 866 + src/roff/groff/pipeline.c | 589 + src/roff/groff/pipeline.h | 30 + src/roff/groff/tests/ab_works.sh | 46 + src/roff/groff/tests/adjustment_works.sh | 92 + src/roff/groff/tests/artifacts/HONEYPOT | 15 + src/roff/groff/tests/artifacts/devascii/README | 1 + .../tests/break_zero-length_output_line_sanely.sh | 43 + .../device_control_escapes_express_basic_latin.sh | 60 + .../do_not_loop_infinitely_when_breaking_cjk.sh | 29 + src/roff/groff/tests/dot-cp_register_works.sh | 48 + src/roff/groff/tests/dot-nm_register_works.sh | 40 + src/roff/groff/tests/dot-nn_register_works.sh | 77 + .../tests/evc_produces_no_output_if_invalid.sh | 25 + .../tests/fp_should_not_traverse_directories.sh | 63 + .../tests/handle_special_input_code_points.sh | 47 + .../groff/tests/html_works_with_grn_and_eqn.sh | 46 + src/roff/groff/tests/initialization_is_quiet.sh | 59 + src/roff/groff/tests/localization_works.sh | 61 + src/roff/groff/tests/msoquiet_works.sh | 35 + .../groff/tests/on_latin1_device_oq_is_0x27.sh | 30 + .../tests/output_driver_C_and_G_options_work.sh | 50 + src/roff/groff/tests/recognize_end_of_sentence.sh | 33 + src/roff/groff/tests/regression_savannah_56555.sh | 27 + src/roff/groff/tests/regression_savannah_58153.sh | 34 + src/roff/groff/tests/regression_savannah_58162.sh | 26 + src/roff/groff/tests/regression_savannah_58337.sh | 32 + src/roff/groff/tests/regression_savannah_59202.sh | 29 + src/roff/groff/tests/smoke-test_html_device.sh | 90 + .../some_escapes_accept_newline_delimiters.sh | 128 + src/roff/groff/tests/soquiet_works.sh | 34 + src/roff/groff/tests/string_case_xform_errors.sh | 30 + src/roff/groff/tests/string_case_xform_requests.sh | 32 + .../tests/string_case_xform_unicode_escape.sh | 42 + src/roff/groff/tests/substring_works.sh | 120 + .../use_point_size_escape_with_single_digit_arg.sh | 44 + src/roff/nroff/nroff.1.man | 358 + src/roff/nroff/nroff.am | 44 + src/roff/nroff/nroff.sh | 204 + src/roff/nroff/tests/verbose_option_works.sh | 68 + src/roff/troff/TODO | 125 + src/roff/troff/charinfo.h | 301 + src/roff/troff/column.cpp | 731 + src/roff/troff/dictionary.cpp | 209 + src/roff/troff/dictionary.h | 91 + src/roff/troff/div.cpp | 1212 + src/roff/troff/div.h | 175 + src/roff/troff/env.cpp | 4138 +++ src/roff/troff/env.h | 421 + src/roff/troff/hvunits.h | 339 + src/roff/troff/input.cpp | 9209 ++++++ src/roff/troff/input.h | 120 + src/roff/troff/mtsm.cpp | 651 + src/roff/troff/mtsm.h | 165 + src/roff/troff/node.cpp | 6656 ++++ src/roff/troff/node.h | 670 + src/roff/troff/number.cpp | 712 + src/roff/troff/reg.cpp | 479 + src/roff/troff/reg.h | 74 + src/roff/troff/request.h | 97 + src/roff/troff/token.h | 249 + src/roff/troff/troff.1.man | 1047 + src/roff/troff/troff.am | 66 + src/roff/troff/troff.h | 97 + src/utils/addftinfo/addftinfo.1.man | 236 + src/utils/addftinfo/addftinfo.am | 35 + src/utils/addftinfo/addftinfo.cpp | 237 + src/utils/addftinfo/guess.cpp | 489 + src/utils/addftinfo/guess.h | 43 + src/utils/afmtodit/afmtodit.1.man | 635 + src/utils/afmtodit/afmtodit.am | 56 + src/utils/afmtodit/afmtodit.pl | 645 + src/utils/afmtodit/afmtodit.tables | 6163 ++++ src/utils/afmtodit/make-afmtodit-tables | 139 + src/utils/grog/grog.1.man | 628 + src/utils/grog/grog.am | 50 + src/utils/grog/grog.pl | 721 + .../grog/tests/PF-does-not-start-pic-region.sh | 33 + src/utils/grog/tests/avoid-refer-fakeout.sh | 34 + src/utils/grog/tests/foo.man | 146 + src/utils/grog/tests/preserve-groff-options.sh | 30 + src/utils/grog/tests/recognize-perl-pod.sh | 31 + src/utils/grog/tests/smoke-test.sh | 153 + src/utils/hpftodit/hpftodit.1.man | 476 + src/utils/hpftodit/hpftodit.am | 34 + src/utils/hpftodit/hpftodit.cpp | 1465 + src/utils/hpftodit/hpuni.cpp | 697 + src/utils/indxbib/eign | 133 + src/utils/indxbib/indxbib.1.man | 347 + src/utils/indxbib/indxbib.am | 57 + src/utils/indxbib/indxbib.cpp | 803 + src/utils/indxbib/signal.c | 77 + src/utils/lkbib/lkbib.1.man | 212 + src/utils/lkbib/lkbib.am | 30 + src/utils/lkbib/lkbib.cpp | 144 + src/utils/lookbib/lookbib.1.man | 166 + src/utils/lookbib/lookbib.am | 29 + src/utils/lookbib/lookbib.cpp | 146 + src/utils/pfbtops/pfbtops.1.man | 129 + src/utils/pfbtops/pfbtops.am | 32 + src/utils/pfbtops/pfbtops.c | 243 + src/utils/tfmtodit/tfmtodit.1.man | 415 + src/utils/tfmtodit/tfmtodit.am | 29 + src/utils/tfmtodit/tfmtodit.cpp | 889 + src/utils/xtotroff/xtotroff.1.man | 237 + src/utils/xtotroff/xtotroff.am | 41 + src/utils/xtotroff/xtotroff.c | 368 + test-groff.in | 54 + tmac/62bit.tmac | 203 + tmac/LOCALIZATION | 60 + tmac/TESTING-HINTS | 19 + tmac/TODO | 36 + tmac/X.tmac | 136 + tmac/Xps.tmac | 65 + tmac/an-ext.tmac | 205 + tmac/an.tmac | 1574 + tmac/andoc.tmac | 115 + tmac/composite.tmac | 30 + tmac/cp1047.tmac | 108 + tmac/cs.tmac | 214 + tmac/de.tmac | 218 + tmac/den.tmac | 31 + tmac/devtag.tmac | 124 + tmac/doc-old.tmac | 1862 ++ tmac/doc.tmac | 6957 ++++ tmac/dvi.tmac | 802 + tmac/e.tmac | 2255 ++ tmac/ec.tmac | 71 + tmac/en.tmac | 77 + tmac/eqnrc | 67 + tmac/europs.tmac | 44 + tmac/fallbacks.tmac | 214 + tmac/fixmacros.sed | 7 + tmac/fr.tmac | 213 + tmac/groff_man.7.man.in | 4287 +++ tmac/groff_mdoc.7.man | 5375 ++++ tmac/groff_me.7.man | 601 + tmac/groff_ms.7.man | 2906 ++ tmac/groff_trace.7.man | 335 + tmac/groff_www.7.man | 760 + tmac/html-end.tmac | 31 + tmac/html.tmac | 550 + tmac/hyphen.cs | 3672 +++ tmac/hyphen.den | 23437 ++++++++++++++ tmac/hyphen.det | 23515 ++++++++++++++ tmac/hyphen.en | 5018 +++ tmac/hyphen.fr | 1325 + tmac/hyphen.it | 431 + tmac/hyphen.sv | 4765 +++ tmac/hyphenex.cs | 18 + tmac/hyphenex.en | 115 + tmac/hyphenex.pl | 91 + tmac/it.tmac | 194 + tmac/ja.tmac | 62 + tmac/latin1.tmac | 114 + tmac/latin2.tmac | 242 + tmac/latin5.tmac | 134 + tmac/latin9.tmac | 138 + tmac/lbp.tmac | 103 + tmac/lj4.tmac | 41 + tmac/man.local | 31 + tmac/man.tmac | 5 + tmac/man.ultrix | 105 + tmac/mandoc.tmac | 5 + tmac/mdoc.local | 15 + tmac/mdoc.tmac | 5 + tmac/mdoc/doc-common | 1729 + tmac/mdoc/doc-ditroff | 287 + tmac/mdoc/doc-nroff | 229 + tmac/mdoc/doc-syms | 908 + tmac/me.tmac | 5 + tmac/ms.tmac | 5 + tmac/papersize.tmac | 167 + tmac/pdf.tmac | 834 + tmac/pdfpic.tmac | 287 + tmac/pic.tmac | 24 + tmac/ps.tmac | 698 + tmac/psatk.tmac | 78 + tmac/psfig.tmac | 104 + tmac/psold.tmac | 70 + tmac/pspic.tmac | 178 + tmac/ptx.tmac | 50 + tmac/refer-me.tmac | 107 + tmac/refer-ms.tmac | 94 + tmac/refer.tmac | 362 + tmac/s.tmac | 2177 ++ tmac/sv.tmac | 184 + tmac/tests/an-ext_MR-works.sh | 61 + tmac/tests/an-ext_MT-works.sh | 55 + tmac/tests/an-ext_UR-works.sh | 56 + .../an_AT-and-UC-footer-saved-and-restored.sh | 106 + tmac/tests/an_CS-register-off.sh | 27 + tmac/tests/an_CS-register-on.sh | 27 + tmac/tests/an_CS-register-unspecified.sh | 27 + tmac/tests/an_CT-register-off.sh | 27 + tmac/tests/an_CT-register-on.sh | 27 + tmac/tests/an_CT-register-unspecified.sh | 27 + .../an_FT-bad-value-should-not-trash-titles.sh | 93 + tmac/tests/an_HY-register-works.sh | 78 + tmac/tests/an_LL-init-sanely.sh | 48 + tmac/tests/an_ME-punct-hyphenates.sh | 55 + tmac/tests/an_MR-works.sh | 75 + tmac/tests/an_MT-body-hyphenates.sh | 37 + tmac/tests/an_MT-works.sh | 86 + tmac/tests/an_P-register-works.sh | 51 + tmac/tests/an_TH-repairs-ad-damage.sh | 41 + tmac/tests/an_TH-repairs-hy-damage.sh | 41 + tmac/tests/an_TS-adds-no-vertical-space.sh | 47 + tmac/tests/an_TS-do-not-keep-tables-when-cR-set.sh | 51 + tmac/tests/an_UE-breaks-before-long-URIs.sh | 68 + tmac/tests/an_UE-punct-hyphenates.sh | 53 + tmac/tests/an_UR-body-hyphenates.sh | 37 + tmac/tests/an_UR-works.sh | 86 + tmac/tests/an_X-register-works.sh | 62 + tmac/tests/an_adjust-link-text-correctly.sh | 40 + tmac/tests/an_avoid-two-font-denial-of-service.sh | 36 + ..._do-not-abbreviate-escape-using-TH-arguments.sh | 51 + .../an_font-remapping-does-not-affect-titles.sh | 60 + tmac/tests/an_handle-degenerate-input-quietly.sh | 29 + tmac/tests/an_inner-footer-abbreviation-works.sh | 70 + .../tests/an_link-macros-work-in-paragraph-tags.sh | 88 + tmac/tests/an_link-trailing-text-hugs-previous.sh | 52 + .../an_no-break-after-short-paragraph-tags.sh | 43 + ...an_output-footer-when-continuously-rendering.sh | 41 + tmac/tests/an_page-footers-present.sh | 68 + tmac/tests/an_page-header-has-current-data.sh | 70 + tmac/tests/an_reset-hyphenation-correctly.sh | 63 + tmac/tests/an_title-abbreviation-works.sh | 61 + tmac/tests/an_use-input-traps-correctly.sh | 113 + tmac/tests/an_works-with-ec.sh | 40 + tmac/tests/andoc_P-register-works.sh | 117 + tmac/tests/andoc_check-an-to-doc-transition.sh | 68 + tmac/tests/andoc_clear-doc-traps.sh | 47 + tmac/tests/andoc_flush-between-packages.sh | 77 + tmac/tests/doc_CS-works.sh | 42 + tmac/tests/doc_CT-works.sh | 42 + tmac/tests/doc_D-places-page-numbers-correctly.sh | 45 + .../doc_Lk-respect-sentence-ending-punctuation.sh | 40 + tmac/tests/doc_Mt-works.sh | 48 + tmac/tests/doc_Nm-works.sh | 74 + tmac/tests/doc_P-register-works.sh | 54 + tmac/tests/doc_X-register-works.sh | 70 + .../doc_accept-mixed-case-section-headings.sh | 76 + ...-not-loop-infinitely-when-shortening-headers.sh | 37 + tmac/tests/doc_heading-font-remapping-works.sh | 58 + tmac/tests/doc_indents-correctly.sh | 89 + ...oc_output-footer-when-continuously-rendering.sh | 43 + tmac/tests/doc_smoke-test.sh | 66 + tmac/tests/e_chapter-titles-work.sh | 68 + tmac/tests/e_columns-work-on-long-pages.sh | 38 + tmac/tests/e_delayed-text-marks-work.sh | 55 + tmac/tests/e_footnote-marks-work.sh | 74 + tmac/tests/e_footnotes-work-with-columns.sh | 43 + tmac/tests/e_ld-works.sh | 131 + tmac/tests/e_line-numbering-works.sh | 141 + tmac/tests/e_rejects-too-short-page-lengths.sh | 61 + tmac/tests/ec_works.sh | 45 + tmac/tests/latin2_works.sh | 76 + tmac/tests/latin5_works.sh | 30 + tmac/tests/latin9_works.sh | 30 + tmac/tests/localization-works.sh | 189 + .../pdfpic_does-not-choke-on-bad-pdfinfo-output.sh | 83 + tmac/tests/pdfpic_falls-back-to-PSPIC.sh | 77 + .../s_IP-indents-using-paragraph-type-size.sh | 50 + .../s_IP-respects-inter-sentence-space-in-tags.sh | 40 + tmac/tests/s_PN-works.sh | 37 + tmac/tests/s_R-handles-its-arguments.sh | 41 + tmac/tests/s_SH-resets-IP-indentation-amount.sh | 40 + .../s_TC-works-with-percent-in-custom-titles.sh | 52 + .../s_XA-literal-no-argument-suppresses-leader.sh | 59 + tmac/tests/s_honor-MINGW-when-two-columns.sh | 37 + tmac/tests/s_mark-column-start-correctly.sh | 38 + tmac/tests/s_no-excess-space-around-displays.sh | 39 + tmac/tests/s_rejects-too-short-page-lengths.sh | 61 + tmac/tmac.am | 385 + tmac/trace.tmac | 346 + tmac/trans.tmac | 176 + tmac/troffrc | 71 + tmac/troffrc-end | 34 + tmac/tty-char.tmac | 251 + tmac/tty.tmac | 100 + tmac/www.tmac.in | 1638 + tmac/zh.tmac | 61 + 1589 files changed, 847909 insertions(+) create mode 100644 .tarball-version create mode 100644 .version create mode 100644 AUTHORS create mode 100644 BUG-REPORT create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 ChangeLog.115 create mode 100644 ChangeLog.116 create mode 100644 ChangeLog.117 create mode 100644 ChangeLog.118 create mode 100644 ChangeLog.119 create mode 100644 ChangeLog.120 create mode 100644 ChangeLog.121 create mode 100644 ChangeLog.122 create mode 100644 FDL create mode 100644 FOR-RELEASE create mode 100644 HACKING create mode 100644 INSTALL create mode 100644 INSTALL.REPO create mode 100644 INSTALL.extra create mode 100644 LICENSES create mode 100644 MANIFEST create mode 100644 MORE.STUFF create mode 100644 Makefile.am create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 PROBLEMS create mode 100644 PROJECTS create mode 100644 README create mode 100644 README.MinGW create mode 100644 THANKS create mode 100644 TODO create mode 100644 acinclude.m4 create mode 100644 aclocal.m4 create mode 100644 arch/djgpp/README create mode 100644 arch/djgpp/config.bat create mode 100644 arch/djgpp/config.sed create mode 100644 arch/djgpp/config.site create mode 100644 arch/djgpp/t-groff.bat create mode 100644 arch/mingw/afmtodit.cmd create mode 100644 arch/mingw/chem.cmd create mode 100644 arch/mingw/gperl.cmd create mode 100644 arch/mingw/gpinyin.cmd create mode 100644 arch/mingw/grap2graph.cmd create mode 100644 arch/mingw/grog.cmd create mode 100644 arch/mingw/gropdf.cmd create mode 100644 arch/mingw/mingw.am create mode 100644 arch/mingw/mmroff.cmd create mode 100644 arch/mingw/neqn.cmd create mode 100644 arch/mingw/pdfmom.cmd create mode 100644 arch/mingw/roff2dvi.cmd create mode 100644 arch/mingw/roff2html.cmd create mode 100644 arch/mingw/roff2pdf.cmd create mode 100644 arch/mingw/roff2ps.cmd create mode 100644 arch/mingw/roff2text.cmd create mode 100644 arch/mingw/roff2x.cmd create mode 100644 arch/misc/misc.am create mode 100644 arch/misc/shdeps.sh create mode 100755 build-aux/compile create mode 100755 build-aux/config.guess create mode 100755 build-aux/config.rpath create mode 100755 build-aux/config.sub create mode 100755 build-aux/depcomp create mode 100755 build-aux/git-version-gen create mode 100755 build-aux/install-sh create mode 100755 build-aux/missing create mode 100755 build-aux/test-driver create mode 100755 build-aux/ylwrap create mode 100755 configure create mode 100644 configure.ac create mode 100644 contrib/chem/ChangeLog create mode 100644 contrib/chem/README.txt create mode 100644 contrib/chem/chem.1.man create mode 100644 contrib/chem/chem.am create mode 100644 contrib/chem/chem.pic create mode 100755 contrib/chem/chem.pl create mode 100644 contrib/chem/examples/122/README.txt create mode 100644 contrib/chem/examples/122/ch2a_ethyl.chem create mode 100644 contrib/chem/examples/122/ch2b_benzene.chem create mode 100644 contrib/chem/examples/122/ch2c_benzene_right.chem create mode 100644 contrib/chem/examples/122/ch4a_stick.chem create mode 100644 contrib/chem/examples/122/ch4b_methyl_acetate.chem create mode 100644 contrib/chem/examples/122/ch4c_colon.chem create mode 100644 contrib/chem/examples/122/ch4d_HCl.H2O.chem create mode 100644 contrib/chem/examples/122/ch4e_CaSO4.2H2O.chem create mode 100644 contrib/chem/examples/122/ch4f_C.chem create mode 100644 contrib/chem/examples/122/ch4g_BP.chem create mode 100644 contrib/chem/examples/122/ch4h_methacrylate.chem create mode 100644 contrib/chem/examples/122/ch4i_cyclo.chem create mode 100644 contrib/chem/examples/122/ch4j_ring4.chem create mode 100644 contrib/chem/examples/122/ch4k_ring3.chem create mode 100644 contrib/chem/examples/122/ch4l_vertex.chem create mode 100644 contrib/chem/examples/122/ch4m_double.chem create mode 100644 contrib/chem/examples/122/ch4n_triple.chem create mode 100644 contrib/chem/examples/122/ch4o_aromatic.chem create mode 100644 contrib/chem/examples/122/ch4p_cholestanol.chem create mode 100644 contrib/chem/examples/122/ch4q_rings.chem create mode 100644 contrib/chem/examples/122/ch4r_spiro.chem create mode 100644 contrib/chem/examples/122/ch4s_heteroatoms.chem create mode 100644 contrib/chem/examples/122/ch4t_polycyclic.chem create mode 100644 contrib/chem/examples/122/ch4u_nicotine.chem create mode 100644 contrib/chem/examples/122/ch4v_histidine.chem create mode 100644 contrib/chem/examples/122/ch4w_lsd.chem create mode 100644 contrib/chem/examples/122/ch4x_anisole.chem create mode 100644 contrib/chem/examples/122/ch4y_reserpine.chem create mode 100644 contrib/chem/examples/122/ch4z1_eqn_glutamic.chem create mode 100644 contrib/chem/examples/122/ch4z2_text.chem create mode 100644 contrib/chem/examples/122/ch5a_size.chem create mode 100644 contrib/chem/examples/122/ch6a_pic.chem create mode 100644 contrib/chem/examples/122/ch6b_dna.chem create mode 100644 contrib/chem/examples/122/chAa_polymer.chem create mode 100644 contrib/chem/examples/122/chAb_vinyl_chloro.chem create mode 100644 contrib/chem/examples/122/chAc_morphine.chem create mode 100644 contrib/chem/examples/122/chAd_chlorophyll.chem create mode 100644 contrib/chem/examples/122/chAe_chair.chem create mode 100644 contrib/chem/examples/122/chAf_arrow.chem create mode 100644 contrib/chem/examples/122/chAg_circle.chem create mode 100644 contrib/chem/examples/122/chAh_brackets.chem create mode 100644 contrib/chem/examples/122/chAi_poly_vinyl_chloride.chem create mode 100644 contrib/chem/examples/122/chBa_jump.chem create mode 100644 contrib/chem/examples/122/chBb_bonds.chem create mode 100644 contrib/chem/examples/122/chBc_rings.chem create mode 100644 contrib/chem/examples/README.txt create mode 100644 contrib/chem/examples/atp.chem create mode 100644 contrib/chem/examples/cholesterin.chem create mode 100644 contrib/chem/examples/ethamivan.chem create mode 100644 contrib/chem/examples/lsd.chem create mode 100644 contrib/chem/examples/morphine.chem create mode 100644 contrib/chem/examples/penicillin.chem create mode 100644 contrib/chem/examples/reserpine.chem create mode 100644 contrib/eqn2graph/eqn2graph.1.man create mode 100644 contrib/eqn2graph/eqn2graph.am create mode 100644 contrib/eqn2graph/eqn2graph.sh create mode 100644 contrib/gdiffmk/ChangeLog create mode 100644 contrib/gdiffmk/README create mode 100644 contrib/gdiffmk/gdiffmk.1.man create mode 100644 contrib/gdiffmk/gdiffmk.am create mode 100644 contrib/gdiffmk/gdiffmk.sh create mode 100644 contrib/gdiffmk/tests/baseline create mode 100644 contrib/gdiffmk/tests/baseline.10 create mode 100644 contrib/gdiffmk/tests/baseline.6 create mode 100644 contrib/gdiffmk/tests/baseline.6a create mode 100644 contrib/gdiffmk/tests/baseline.7 create mode 100644 contrib/gdiffmk/tests/baseline.8 create mode 100644 contrib/gdiffmk/tests/baseline.9 create mode 100644 contrib/gdiffmk/tests/baseline.9a create mode 100644 contrib/gdiffmk/tests/file1 create mode 100644 contrib/gdiffmk/tests/file2 create mode 100755 contrib/gdiffmk/tests/runtests.sh create mode 100644 contrib/glilypond/ChangeLog create mode 100644 contrib/glilypond/ChangeLog.0x create mode 100644 contrib/glilypond/README.txt create mode 100644 contrib/glilypond/examples/example.groff create mode 100644 contrib/glilypond/glilypond.1.man create mode 100644 contrib/glilypond/glilypond.am create mode 100755 contrib/glilypond/glilypond.pl create mode 100644 contrib/gperl/ChangeLog create mode 100644 contrib/gperl/gperl.1.man create mode 100644 contrib/gperl/gperl.am create mode 100755 contrib/gperl/gperl.pl create mode 100644 contrib/gpinyin/ChangeLog create mode 100644 contrib/gpinyin/gpinyin.1.man create mode 100644 contrib/gpinyin/gpinyin.am create mode 100755 contrib/gpinyin/gpinyin.pl create mode 100644 contrib/grap2graph/grap2graph.1.man create mode 100644 contrib/grap2graph/grap2graph.am create mode 100644 contrib/grap2graph/grap2graph.sh create mode 100644 contrib/hdtbl/ChangeLog create mode 100644 contrib/hdtbl/TODO create mode 100644 contrib/hdtbl/examples/chess_board.roff create mode 100644 contrib/hdtbl/examples/col_rowspan_colors.roff create mode 100644 contrib/hdtbl/examples/color_boxes.roff create mode 100644 contrib/hdtbl/examples/color_nested_tables.roff create mode 100644 contrib/hdtbl/examples/color_table_cells.roff create mode 100644 contrib/hdtbl/examples/color_transitions.roff create mode 100644 contrib/hdtbl/examples/common.roff create mode 100644 contrib/hdtbl/examples/fonts_n.in create mode 100644 contrib/hdtbl/examples/fonts_x.in create mode 100644 contrib/hdtbl/examples/mixed_pickles.roff create mode 100644 contrib/hdtbl/examples/rainbow.roff create mode 100644 contrib/hdtbl/examples/short_reference.roff create mode 100644 contrib/hdtbl/examples/test-hdtbl.sh.in create mode 100644 contrib/hdtbl/groff_hdtbl.7.man create mode 100644 contrib/hdtbl/hdmisc.tmac create mode 100644 contrib/hdtbl/hdtbl.am create mode 100644 contrib/hdtbl/hdtbl.tmac create mode 100644 contrib/mm/ChangeLog create mode 100644 contrib/mm/Makefile.sim create mode 100644 contrib/mm/NOTES create mode 100644 contrib/mm/README create mode 100644 contrib/mm/examples/APP create mode 100644 contrib/mm/examples/B1B2 create mode 100644 contrib/mm/examples/COVER create mode 100644 contrib/mm/examples/IND create mode 100644 contrib/mm/examples/LT create mode 100644 contrib/mm/examples/LT.se create mode 100644 contrib/mm/examples/ML create mode 100644 contrib/mm/examples/MOVE create mode 100644 contrib/mm/examples/MUL create mode 100644 contrib/mm/examples/NCOL create mode 100644 contrib/mm/examples/ND create mode 100644 contrib/mm/examples/README create mode 100644 contrib/mm/examples/References create mode 100644 contrib/mm/examples/SETR create mode 100644 contrib/mm/examples/letter.mm create mode 100644 contrib/mm/groff_mm.7.man create mode 100644 contrib/mm/groff_mmse.7.man create mode 100644 contrib/mm/m.tmac create mode 100644 contrib/mm/mm.am create mode 100644 contrib/mm/mm.tmac create mode 100644 contrib/mm/mm/0.MT create mode 100644 contrib/mm/mm/4.MT create mode 100644 contrib/mm/mm/5.MT create mode 100644 contrib/mm/mm/ms.cov create mode 100644 contrib/mm/mm/se_ms.cov create mode 100644 contrib/mm/mmroff.1.man create mode 100644 contrib/mm/mmroff.pl create mode 100644 contrib/mm/mmse.tmac create mode 100644 contrib/mm/mse.tmac create mode 100644 contrib/mm/refer-mm.tmac create mode 100755 contrib/mm/tests/LT_SP_AU_without_AT_works.sh create mode 100755 contrib/mm/tests/LT_SP_multi-word_LO_SJ_works.sh create mode 100755 contrib/mm/tests/MT-1-reports-all-TM-numbers.sh create mode 100755 contrib/mm/tests/MT_5_includes_AT_in_SG.sh create mode 100755 contrib/mm/tests/P-indentation-works.sh create mode 100644 contrib/mm/tests/artifacts/60657.ref create mode 100755 contrib/mm/tests/ms_cover_sheet_robust_to_missing_AF.sh create mode 100755 contrib/mm/tests/mse_has-sufficient-footnote-space.sh create mode 100755 contrib/mm/tests/place-equation-labels-correctly-in-displays.sh create mode 100755 contrib/mm/tests/remove-stale-bib-entry-data.sh create mode 100755 contrib/mm/tests/short-pages-do-not-overflow-stack.sh create mode 100644 contrib/mom/BUGS create mode 100644 contrib/mom/ChangeLog create mode 100644 contrib/mom/NEWS create mode 100644 contrib/mom/TODO create mode 100644 contrib/mom/copyright create mode 100644 contrib/mom/examples/README-fr.txt create mode 100644 contrib/mom/examples/README.txt create mode 100644 contrib/mom/examples/copyright-chapter.mom create mode 100644 contrib/mom/examples/copyright-default.mom create mode 100644 contrib/mom/examples/elvis_syntax create mode 100644 contrib/mom/examples/elvis_syntax.new create mode 100644 contrib/mom/examples/letter.mom create mode 100644 contrib/mom/examples/mom-pdf.mom create mode 100644 contrib/mom/examples/mom.vim create mode 100644 contrib/mom/examples/mon_premier_doc.mom create mode 100644 contrib/mom/examples/penguin.pdf create mode 100644 contrib/mom/examples/penguin.ps create mode 100644 contrib/mom/examples/sample_docs.mom create mode 100644 contrib/mom/examples/slide-demo.mom create mode 100644 contrib/mom/examples/test-mom.sh.in create mode 100644 contrib/mom/examples/typesetting.mom create mode 100644 contrib/mom/groff_mom.7.man create mode 100644 contrib/mom/mom.am create mode 100644 contrib/mom/mom.tmac create mode 100644 contrib/mom/momdoc/appendices.html create mode 100644 contrib/mom/momdoc/color.html create mode 100644 contrib/mom/momdoc/cover.html create mode 100644 contrib/mom/momdoc/definitions.html create mode 100644 contrib/mom/momdoc/docelement.html create mode 100644 contrib/mom/momdoc/docprocessing.html create mode 100644 contrib/mom/momdoc/goodies.html create mode 100644 contrib/mom/momdoc/graphical.html create mode 100644 contrib/mom/momdoc/headfootpage.html create mode 100644 contrib/mom/momdoc/images.html create mode 100644 contrib/mom/momdoc/inlines.html create mode 100644 contrib/mom/momdoc/intro.html create mode 100644 contrib/mom/momdoc/letters.html create mode 100644 contrib/mom/momdoc/macrolist.html create mode 100644 contrib/mom/momdoc/rectoverso.html create mode 100644 contrib/mom/momdoc/refer.html create mode 100644 contrib/mom/momdoc/reserved.html create mode 100644 contrib/mom/momdoc/stylesheet.css create mode 100644 contrib/mom/momdoc/tables-of-contents.html create mode 100644 contrib/mom/momdoc/toc.html create mode 100644 contrib/mom/momdoc/typesetting.html create mode 100644 contrib/mom/momdoc/using.html create mode 100644 contrib/mom/momdoc/version-2.html create mode 100644 contrib/mom/om.tmac create mode 100644 contrib/pdfmark/ChangeLog create mode 100644 contrib/pdfmark/PROBLEMS create mode 100644 contrib/pdfmark/README create mode 100644 contrib/pdfmark/TODO create mode 100644 contrib/pdfmark/cover.ms create mode 100644 contrib/pdfmark/pdfmark.am create mode 100644 contrib/pdfmark/pdfmark.ms create mode 100644 contrib/pdfmark/pdfmark.tmac create mode 100644 contrib/pdfmark/pdfroff.1.man create mode 100644 contrib/pdfmark/pdfroff.sh create mode 100644 contrib/pdfmark/sanitize.tmac create mode 100644 contrib/pdfmark/spdf.tmac create mode 100644 contrib/pic2graph/pic2graph.1.man create mode 100644 contrib/pic2graph/pic2graph.am create mode 100644 contrib/pic2graph/pic2graph.sh create mode 100644 contrib/rfc1345/COPYRIGHT create mode 100644 contrib/rfc1345/groff_rfc1345.7.man create mode 100644 contrib/rfc1345/rfc1345.am create mode 100644 contrib/rfc1345/rfc1345.tmac create mode 100755 contrib/rfc1345/tests/rfc1345-smoke-test.sh create mode 100644 contrib/sboxes/ChangeLog create mode 100644 contrib/sboxes/msboxes.ms.in create mode 100644 contrib/sboxes/notquine.sed create mode 100644 contrib/sboxes/sboxes.am create mode 100644 contrib/sboxes/sboxes.tmac create mode 100644 doc/automake.mom create mode 100644 doc/doc.am create mode 100644 doc/fdl.texi create mode 100644 doc/gnu.eps create mode 100644 doc/gnu.xpm create mode 100644 doc/grnexmpl.g create mode 100644 doc/grnexmpl.me create mode 100644 doc/groff.css create mode 100644 doc/groff.dvi create mode 100644 doc/groff.html create mode 100644 doc/groff.html.node/Adjustment.html create mode 100644 doc/groff.html.node/Argument-Units.html create mode 100644 doc/groff.html.node/Artificial-Fonts.html create mode 100644 doc/groff.html.node/Assigning-Register-Formats.html create mode 100644 doc/groff.html.node/Auto_002dincrement.html create mode 100644 doc/groff.html.node/Background.html create mode 100644 doc/groff.html.node/Basics.html create mode 100644 doc/groff.html.node/Blank-Line-Traps.html create mode 100644 doc/groff.html.node/Breaking.html create mode 100644 doc/groff.html.node/Built_002din-Registers.html create mode 100644 doc/groff.html.node/Calling-Macros.html create mode 100644 doc/groff.html.node/Changing-the-Type-Size.html create mode 100644 doc/groff.html.node/Changing-the-Vertical-Spacing.html create mode 100644 doc/groff.html.node/Character-Classes.html create mode 100644 doc/groff.html.node/Character-Translations.html create mode 100644 doc/groff.html.node/Colors.html create mode 100644 doc/groff.html.node/Columnation.html create mode 100644 doc/groff.html.node/Command-Reference.html create mode 100644 doc/groff.html.node/Comment-Command.html create mode 100644 doc/groff.html.node/Comments.html create mode 100644 doc/groff.html.node/Common-Features.html create mode 100644 doc/groff.html.node/Compatibility-Mode.html create mode 100644 doc/groff.html.node/Concept-Index.html create mode 100644 doc/groff.html.node/Conditional-Blocks.html create mode 100644 doc/groff.html.node/Conditionals-and-Loops.html create mode 100644 doc/groff.html.node/Configuration-and-Customization.html create mode 100644 doc/groff.html.node/Control-Characters.html create mode 100644 doc/groff.html.node/Conventions-Used-in-This-Manual.html create mode 100644 doc/groff.html.node/Copy-Mode.html create mode 100644 doc/groff.html.node/Copying-This-Manual.html create mode 100644 doc/groff.html.node/Credits.html create mode 100644 doc/groff.html.node/DESC-File-Format.html create mode 100644 doc/groff.html.node/Debugging.html create mode 100644 doc/groff.html.node/Default-Units.html create mode 100644 doc/groff.html.node/Deferring-Output.html create mode 100644 doc/groff.html.node/Delimiters.html create mode 100644 doc/groff.html.node/Device-Control-Commands.html create mode 100644 doc/groff.html.node/Device-and-Font-Description-Files.html create mode 100644 doc/groff.html.node/Differences-from-AT_0026T-ms.html create mode 100644 doc/groff.html.node/Displays-and-Keeps.html create mode 100644 doc/groff.html.node/Diversion-Traps.html create mode 100644 doc/groff.html.node/Diversions.html create mode 100644 doc/groff.html.node/Document-Formats.html create mode 100644 doc/groff.html.node/Document-Parts.html create mode 100644 doc/groff.html.node/Drawing-Geometric-Objects.html create mode 100644 doc/groff.html.node/Dummy-Characters.html create mode 100644 doc/groff.html.node/End_002dof_002dinput-Traps.html create mode 100644 doc/groff.html.node/Environment.html create mode 100644 doc/groff.html.node/Environments.html create mode 100644 doc/groff.html.node/Escape-Sequence-Index.html create mode 100644 doc/groff.html.node/Fields.html create mode 100644 doc/groff.html.node/File-Formats.html create mode 100644 doc/groff.html.node/File-Keyword-Index.html create mode 100644 doc/groff.html.node/Filling.html create mode 100644 doc/groff.html.node/Font-Description-File-Format.html create mode 100644 doc/groff.html.node/Font-Directories.html create mode 100644 doc/groff.html.node/Font-Families.html create mode 100644 doc/groff.html.node/Font-Positions.html create mode 100644 doc/groff.html.node/Font-and-Size-Changes.html create mode 100644 doc/groff.html.node/Footnotes-and-Endnotes.html create mode 100644 doc/groff.html.node/Formatter-Instructions.html create mode 100644 doc/groff.html.node/GNU-troff-Reference.html create mode 100644 doc/groff.html.node/Graphics-Commands.html create mode 100644 doc/groff.html.node/Groff-Options.html create mode 100644 doc/groff.html.node/Gtroff-Internals.html create mode 100644 doc/groff.html.node/Headers-and-Footers.html create mode 100644 doc/groff.html.node/Headings-in-ms.html create mode 100644 doc/groff.html.node/Hyphenation.html create mode 100644 doc/groff.html.node/I_002fO.html create mode 100644 doc/groff.html.node/Identifiers.html create mode 100644 doc/groff.html.node/Implementation-Differences.html create mode 100644 doc/groff.html.node/Indented-regions-in-ms.html create mode 100644 doc/groff.html.node/Indexing.html create mode 100644 doc/groff.html.node/Input-Conventions.html create mode 100644 doc/groff.html.node/Input-Encodings.html create mode 100644 doc/groff.html.node/Input-Line-Traps.html create mode 100644 doc/groff.html.node/Installation.html create mode 100644 doc/groff.html.node/Intermediate-Output-Examples.html create mode 100644 doc/groff.html.node/Interpolating-Registers.html create mode 100644 doc/groff.html.node/Introduction.html create mode 100644 doc/groff.html.node/Invocation-Examples.html create mode 100644 doc/groff.html.node/Invoking-Requests.html create mode 100644 doc/groff.html.node/Invoking-groff.html create mode 100644 doc/groff.html.node/Italic-Corrections.html create mode 100644 doc/groff.html.node/Language-Concepts.html create mode 100644 doc/groff.html.node/Leaders.html create mode 100644 doc/groff.html.node/Leading-Space-Traps.html create mode 100644 doc/groff.html.node/Ligatures-and-Kerning.html create mode 100644 doc/groff.html.node/Line-Continuation.html create mode 100644 doc/groff.html.node/Line-Layout.html create mode 100644 doc/groff.html.node/Lists-in-ms.html create mode 100644 doc/groff.html.node/Macro-Directories.html create mode 100644 doc/groff.html.node/Macro-Index.html create mode 100644 doc/groff.html.node/Macro-Package-Intro.html create mode 100644 doc/groff.html.node/Macro-Packages.html create mode 100644 doc/groff.html.node/Major-Macro-Packages.html create mode 100644 doc/groff.html.node/Manipulating-Filling-and-Adjustment.html create mode 100644 doc/groff.html.node/Manipulating-Hyphenation.html create mode 100644 doc/groff.html.node/Manipulating-Spacing.html create mode 100644 doc/groff.html.node/Manipulating-Type-Size-and-Vertical-Spacing.html create mode 100644 doc/groff.html.node/Measurements.html create mode 100644 doc/groff.html.node/Miscellaneous.html create mode 100644 doc/groff.html.node/Missing-Unix-Version-7-ms-Macros.html create mode 100644 doc/groff.html.node/Motion-Quanta.html create mode 100644 doc/groff.html.node/Numeric-Expressions.html create mode 100644 doc/groff.html.node/Obsolete-Command.html create mode 100644 doc/groff.html.node/Operator-Index.html create mode 100644 doc/groff.html.node/Operators-in-Conditionals.html create mode 100644 doc/groff.html.node/Optional-man-extensions.html create mode 100644 doc/groff.html.node/Other-Differences.html create mode 100644 doc/groff.html.node/Output-Device-Intro.html create mode 100644 doc/groff.html.node/Output-Language-Compatibility.html create mode 100644 doc/groff.html.node/Page-Control.html create mode 100644 doc/groff.html.node/Page-Geometry.html create mode 100644 doc/groff.html.node/Page-Layout-Adjustment.html create mode 100644 doc/groff.html.node/Page-Layout.html create mode 100644 doc/groff.html.node/Page-Location-Traps.html create mode 100644 doc/groff.html.node/Page-Motions.html create mode 100644 doc/groff.html.node/Paper-Format.html create mode 100644 doc/groff.html.node/Paragraphs-in-ms.html create mode 100644 doc/groff.html.node/Paragraphs.html create mode 100644 doc/groff.html.node/Parameters.html create mode 100644 doc/groff.html.node/Postprocessor-Access.html create mode 100644 doc/groff.html.node/Predefined-Text.html create mode 100644 doc/groff.html.node/Preprocessor-Intro.html create mode 100644 doc/groff.html.node/Preprocessor-Support.html create mode 100644 doc/groff.html.node/Program-and-File-Index.html create mode 100644 doc/groff.html.node/Punning-Names.html create mode 100644 doc/groff.html.node/Register-Index.html create mode 100644 doc/groff.html.node/Registers.html create mode 100644 doc/groff.html.node/Request-Index.html create mode 100644 doc/groff.html.node/Requests-and-Macros.html create mode 100644 doc/groff.html.node/Safer-Mode.html create mode 100644 doc/groff.html.node/Sections-and-Chapters.html create mode 100644 doc/groff.html.node/Selecting-Fonts.html create mode 100644 doc/groff.html.node/Sentences.html create mode 100644 doc/groff.html.node/Separation.html create mode 100644 doc/groff.html.node/Setting-Registers.html create mode 100644 doc/groff.html.node/Simple-Commands.html create mode 100644 doc/groff.html.node/Special-Fonts.html create mode 100644 doc/groff.html.node/String-Index.html create mode 100644 doc/groff.html.node/Strings.html create mode 100644 doc/groff.html.node/Suppressing-Output.html create mode 100644 doc/groff.html.node/Tab-Stops-in-ms.html create mode 100644 doc/groff.html.node/Table-of-Contents.html create mode 100644 doc/groff.html.node/Tabs-and-Fields.html create mode 100644 doc/groff.html.node/Tabs-and-Leaders.html create mode 100644 doc/groff.html.node/Text-settings-in-ms.html create mode 100644 doc/groff.html.node/Text.html create mode 100644 doc/groff.html.node/The-Implicit-Page-Trap.html create mode 100644 doc/groff.html.node/Traps.html create mode 100644 doc/groff.html.node/Tutorial-for-Macro-Users.html create mode 100644 doc/groff.html.node/Typeface-and-decoration.html create mode 100644 doc/groff.html.node/Typographical-symbols-in-ms.html create mode 100644 doc/groff.html.node/Using-Escape-Sequences.html create mode 100644 doc/groff.html.node/Using-Fonts.html create mode 100644 doc/groff.html.node/Using-Fractional-Type-Sizes.html create mode 100644 doc/groff.html.node/Using-Symbols.html create mode 100644 doc/groff.html.node/Vertical-Position-Traps.html create mode 100644 doc/groff.html.node/Warnings.html create mode 100644 doc/groff.html.node/What-Is-groff_003f.html create mode 100644 doc/groff.html.node/Writing-Macros.html create mode 100644 doc/groff.html.node/als.html create mode 100644 doc/groff.html.node/groff-Capabilities.html create mode 100644 doc/groff.html.node/groff.html_fot.html create mode 100644 doc/groff.html.node/gtroff-Output.html create mode 100644 doc/groff.html.node/if_002delse.html create mode 100644 doc/groff.html.node/if_002dthen.html create mode 100644 doc/groff.html.node/index.html create mode 100644 doc/groff.html.node/man.html create mode 100644 doc/groff.html.node/mdoc.html create mode 100644 doc/groff.html.node/me.html create mode 100644 doc/groff.html.node/mm.html create mode 100644 doc/groff.html.node/mom.html create mode 100644 doc/groff.html.node/ms-Body-Text.html create mode 100644 doc/groff.html.node/ms-Document-Control-Settings.html create mode 100644 doc/groff.html.node/ms-Document-Description-Macros.html create mode 100644 doc/groff.html.node/ms-Document-Structure.html create mode 100644 doc/groff.html.node/ms-Footnotes.html create mode 100644 doc/groff.html.node/ms-Headers-and-Footers.html create mode 100644 doc/groff.html.node/ms-Insertions.html create mode 100644 doc/groff.html.node/ms-Introduction.html create mode 100644 doc/groff.html.node/ms-Legacy-Features.html create mode 100644 doc/groff.html.node/ms-Margins.html create mode 100644 doc/groff.html.node/ms-Multiple-Columns.html create mode 100644 doc/groff.html.node/ms-Naming-Conventions.html create mode 100644 doc/groff.html.node/ms-Page-Layout.html create mode 100644 doc/groff.html.node/ms-TOC.html create mode 100644 doc/groff.html.node/ms-basic-information.html create mode 100644 doc/groff.html.node/ms-keeps-and-displays.html create mode 100644 doc/groff.html.node/ms-language-and-localization.html create mode 100644 doc/groff.html.node/ms.html create mode 100644 doc/groff.html.node/troff-and-nroff-Modes.html create mode 100644 doc/groff.html.node/while.html create mode 100644 doc/groff.info create mode 100644 doc/groff.info-1 create mode 100644 doc/groff.info-2 create mode 100644 doc/groff.info-3 create mode 100644 doc/groff.pdf create mode 100644 doc/groff.texi create mode 100644 doc/groff.txt create mode 100644 doc/me-revisions create mode 100644 doc/meintro.me.in create mode 100644 doc/meintro_fr.me.in create mode 100644 doc/meref.me.in create mode 100644 doc/ms.ms create mode 100644 doc/pic.ms create mode 100644 doc/txi-en.tex create mode 100644 doc/webpage.ms create mode 100644 font/devX100-12/CB create mode 100644 font/devX100-12/CBI create mode 100644 font/devX100-12/CI create mode 100644 font/devX100-12/CR create mode 100644 font/devX100-12/DESC create mode 100644 font/devX100-12/HB create mode 100644 font/devX100-12/HBI create mode 100644 font/devX100-12/HI create mode 100644 font/devX100-12/HR create mode 100644 font/devX100-12/NB create mode 100644 font/devX100-12/NBI create mode 100644 font/devX100-12/NI create mode 100644 font/devX100-12/NR create mode 100644 font/devX100-12/S create mode 100644 font/devX100-12/TB create mode 100644 font/devX100-12/TBI create mode 100644 font/devX100-12/TI create mode 100644 font/devX100-12/TR create mode 100644 font/devX100-12/devX100-12.am create mode 100644 font/devX100/CB create mode 100644 font/devX100/CBI create mode 100644 font/devX100/CI create mode 100644 font/devX100/CR create mode 100644 font/devX100/DESC create mode 100644 font/devX100/HB create mode 100644 font/devX100/HBI create mode 100644 font/devX100/HI create mode 100644 font/devX100/HR create mode 100644 font/devX100/NB create mode 100644 font/devX100/NBI create mode 100644 font/devX100/NI create mode 100644 font/devX100/NR create mode 100644 font/devX100/S create mode 100644 font/devX100/TB create mode 100644 font/devX100/TBI create mode 100644 font/devX100/TI create mode 100644 font/devX100/TR create mode 100644 font/devX100/devX100.am create mode 100644 font/devX75-12/CB create mode 100644 font/devX75-12/CBI create mode 100644 font/devX75-12/CI create mode 100644 font/devX75-12/CR create mode 100644 font/devX75-12/DESC create mode 100644 font/devX75-12/HB create mode 100644 font/devX75-12/HBI create mode 100644 font/devX75-12/HI create mode 100644 font/devX75-12/HR create mode 100644 font/devX75-12/NB create mode 100644 font/devX75-12/NBI create mode 100644 font/devX75-12/NI create mode 100644 font/devX75-12/NR create mode 100644 font/devX75-12/S create mode 100644 font/devX75-12/TB create mode 100644 font/devX75-12/TBI create mode 100644 font/devX75-12/TI create mode 100644 font/devX75-12/TR create mode 100644 font/devX75-12/devX75-12.am create mode 100644 font/devX75/CB create mode 100644 font/devX75/CBI create mode 100644 font/devX75/CI create mode 100644 font/devX75/CR create mode 100644 font/devX75/DESC create mode 100644 font/devX75/HB create mode 100644 font/devX75/HBI create mode 100644 font/devX75/HI create mode 100644 font/devX75/HR create mode 100644 font/devX75/NB create mode 100644 font/devX75/NBI create mode 100644 font/devX75/NI create mode 100644 font/devX75/NR create mode 100644 font/devX75/S create mode 100644 font/devX75/TB create mode 100644 font/devX75/TBI create mode 100644 font/devX75/TI create mode 100644 font/devX75/TR create mode 100644 font/devX75/devX75.am create mode 100644 font/devascii/DESC.proto create mode 100644 font/devascii/R.proto create mode 100644 font/devascii/devascii.am create mode 100644 font/devcp1047/DESC.proto create mode 100644 font/devcp1047/R.proto create mode 100644 font/devcp1047/devcp1047.am create mode 100644 font/devdvi/CW create mode 100644 font/devdvi/CWEC create mode 100644 font/devdvi/CWI create mode 100644 font/devdvi/CWIEC create mode 100644 font/devdvi/CWITC create mode 100644 font/devdvi/CWTC create mode 100644 font/devdvi/DESC.in create mode 100644 font/devdvi/EX create mode 100644 font/devdvi/HB create mode 100644 font/devdvi/HBEC create mode 100644 font/devdvi/HBI create mode 100644 font/devdvi/HBIEC create mode 100644 font/devdvi/HBITC create mode 100644 font/devdvi/HBTC create mode 100644 font/devdvi/HI create mode 100644 font/devdvi/HIEC create mode 100644 font/devdvi/HITC create mode 100644 font/devdvi/HR create mode 100644 font/devdvi/HREC create mode 100644 font/devdvi/HRTC create mode 100644 font/devdvi/MI create mode 100644 font/devdvi/S create mode 100644 font/devdvi/SA create mode 100644 font/devdvi/SB create mode 100644 font/devdvi/SC create mode 100644 font/devdvi/TB create mode 100644 font/devdvi/TBEC create mode 100644 font/devdvi/TBI create mode 100644 font/devdvi/TBIEC create mode 100644 font/devdvi/TBITC create mode 100644 font/devdvi/TBTC create mode 100644 font/devdvi/TI create mode 100644 font/devdvi/TIEC create mode 100644 font/devdvi/TITC create mode 100644 font/devdvi/TR create mode 100644 font/devdvi/TREC create mode 100644 font/devdvi/TRTC create mode 100644 font/devdvi/devdvi.am create mode 100755 font/devdvi/generate/CompileFonts create mode 100644 font/devdvi/generate/Makefile create mode 100644 font/devdvi/generate/ec.map create mode 100644 font/devdvi/generate/msam.map create mode 100644 font/devdvi/generate/msbm.map create mode 100644 font/devdvi/generate/tc.map create mode 100644 font/devdvi/generate/texb.map create mode 100644 font/devdvi/generate/texex.map create mode 100644 font/devdvi/generate/texi.map create mode 100644 font/devdvi/generate/texmi.map create mode 100644 font/devdvi/generate/texr.map create mode 100644 font/devdvi/generate/texsy.map create mode 100644 font/devdvi/generate/textex.map create mode 100644 font/devdvi/generate/textt.map create mode 100644 font/devhtml/DESC.proto create mode 100644 font/devhtml/R.in create mode 100644 font/devhtml/R.proto create mode 100644 font/devhtml/devhtml.am create mode 100644 font/devlatin1/DESC.proto create mode 100644 font/devlatin1/R.proto create mode 100644 font/devlatin1/devlatin1.am create mode 100644 font/devlbp/CB create mode 100644 font/devlbp/CI create mode 100644 font/devlbp/CR create mode 100644 font/devlbp/DESC.in create mode 100644 font/devlbp/EB create mode 100644 font/devlbp/EI create mode 100644 font/devlbp/ER create mode 100644 font/devlbp/HB create mode 100644 font/devlbp/HBI create mode 100644 font/devlbp/HI create mode 100644 font/devlbp/HNB create mode 100644 font/devlbp/HNBI create mode 100644 font/devlbp/HNI create mode 100644 font/devlbp/HNR create mode 100644 font/devlbp/HR create mode 100644 font/devlbp/TB create mode 100644 font/devlbp/TBI create mode 100644 font/devlbp/TI create mode 100644 font/devlbp/TR create mode 100644 font/devlbp/devlbp.am create mode 100644 font/devlj4/AB create mode 100644 font/devlj4/ABI create mode 100644 font/devlj4/AI create mode 100644 font/devlj4/ALBB create mode 100644 font/devlj4/ALBR create mode 100644 font/devlj4/AOB create mode 100644 font/devlj4/AOI create mode 100644 font/devlj4/AOR create mode 100644 font/devlj4/AR create mode 100644 font/devlj4/CB create mode 100644 font/devlj4/CBI create mode 100644 font/devlj4/CI create mode 100644 font/devlj4/CLARENDON create mode 100644 font/devlj4/CORONET create mode 100644 font/devlj4/CR create mode 100644 font/devlj4/DESC.in create mode 100644 font/devlj4/GB create mode 100644 font/devlj4/GBI create mode 100644 font/devlj4/GI create mode 100644 font/devlj4/GR create mode 100644 font/devlj4/LGB create mode 100644 font/devlj4/LGI create mode 100644 font/devlj4/LGR create mode 100644 font/devlj4/MARIGOLD create mode 100644 font/devlj4/OB create mode 100644 font/devlj4/OBI create mode 100644 font/devlj4/OI create mode 100644 font/devlj4/OR create mode 100644 font/devlj4/S create mode 100644 font/devlj4/SYMBOL create mode 100644 font/devlj4/TB create mode 100644 font/devlj4/TBI create mode 100644 font/devlj4/TI create mode 100644 font/devlj4/TNRB create mode 100644 font/devlj4/TNRBI create mode 100644 font/devlj4/TNRI create mode 100644 font/devlj4/TNRR create mode 100644 font/devlj4/TR create mode 100644 font/devlj4/UB create mode 100644 font/devlj4/UBI create mode 100644 font/devlj4/UCB create mode 100644 font/devlj4/UCBI create mode 100644 font/devlj4/UCI create mode 100644 font/devlj4/UCR create mode 100644 font/devlj4/UI create mode 100644 font/devlj4/UR create mode 100644 font/devlj4/WINGDINGS create mode 100644 font/devlj4/devlj4.am create mode 100644 font/devlj4/generate/Makefile create mode 100644 font/devlj4/generate/special.awk create mode 100644 font/devlj4/generate/special.map create mode 100644 font/devlj4/generate/symbol.map create mode 100644 font/devlj4/generate/text.map create mode 100644 font/devlj4/generate/wingdings.map create mode 100644 font/devpdf/DESC.in create mode 100644 font/devpdf/Foundry.in create mode 100644 font/devpdf/devpdf.am create mode 100755 font/devpdf/tests/check-default-foundry.sh.in create mode 100755 font/devpdf/tests/check-urw-foundry.sh.in create mode 100644 font/devpdf/util/BuildFoundries.pl create mode 100644 font/devps/AB create mode 100644 font/devps/ABI create mode 100644 font/devps/AI create mode 100644 font/devps/AR create mode 100644 font/devps/BMB create mode 100644 font/devps/BMBI create mode 100644 font/devps/BMI create mode 100644 font/devps/BMR create mode 100644 font/devps/CB create mode 100644 font/devps/CBI create mode 100644 font/devps/CI create mode 100644 font/devps/CR create mode 100644 font/devps/DESC.in create mode 100644 font/devps/EURO create mode 100644 font/devps/HB create mode 100644 font/devps/HBI create mode 100644 font/devps/HI create mode 100644 font/devps/HNB create mode 100644 font/devps/HNBI create mode 100644 font/devps/HNI create mode 100644 font/devps/HNR create mode 100644 font/devps/HR create mode 100644 font/devps/NB create mode 100644 font/devps/NBI create mode 100644 font/devps/NI create mode 100644 font/devps/NR create mode 100644 font/devps/PB create mode 100644 font/devps/PBI create mode 100644 font/devps/PI create mode 100644 font/devps/PR create mode 100644 font/devps/S create mode 100644 font/devps/SS create mode 100644 font/devps/TB create mode 100644 font/devps/TBI create mode 100644 font/devps/TI create mode 100644 font/devps/TR create mode 100644 font/devps/ZCMI create mode 100644 font/devps/ZD create mode 100644 font/devps/ZDR create mode 100644 font/devps/devps.am create mode 100644 font/devps/download create mode 100644 font/devps/freeeuro.afm create mode 100644 font/devps/freeeuro.ps create mode 100644 font/devps/generate/Makefile create mode 100755 font/devps/generate/afmname create mode 100644 font/devps/generate/dingbats-reversed.map create mode 100644 font/devps/generate/dingbats.map create mode 100644 font/devps/generate/freeeuro.sfd create mode 100755 font/devps/generate/make-zapfdr create mode 100644 font/devps/generate/sfdtopfa.pe create mode 100644 font/devps/generate/slanted-symbol.map create mode 100644 font/devps/generate/symbol.map create mode 100644 font/devps/generate/symbol.sed create mode 100644 font/devps/generate/symbolchars create mode 100644 font/devps/generate/symbolsl.awk create mode 100644 font/devps/generate/text.map create mode 100644 font/devps/generate/zapfdr.sed create mode 100644 font/devps/old/CB create mode 100644 font/devps/old/CBI create mode 100644 font/devps/old/CI create mode 100644 font/devps/old/CR create mode 100644 font/devps/old/HB create mode 100644 font/devps/old/HBI create mode 100644 font/devps/old/HI create mode 100644 font/devps/old/HNB create mode 100644 font/devps/old/HNBI create mode 100644 font/devps/old/HNI create mode 100644 font/devps/old/HNR create mode 100644 font/devps/old/HR create mode 100644 font/devps/old/NB create mode 100644 font/devps/old/NBI create mode 100644 font/devps/old/NI create mode 100644 font/devps/old/NR create mode 100644 font/devps/old/PB create mode 100644 font/devps/old/PBI create mode 100644 font/devps/old/PI create mode 100644 font/devps/old/PR create mode 100644 font/devps/old/S create mode 100644 font/devps/old/SS create mode 100644 font/devps/old/TB create mode 100644 font/devps/old/TBI create mode 100644 font/devps/old/TI create mode 100644 font/devps/old/TR create mode 100644 font/devps/old/symbol.afm create mode 100644 font/devps/old/symbolsl.afm create mode 100644 font/devps/old/zapfdr.afm create mode 100644 font/devps/old/zapfdr.ps create mode 100644 font/devps/prologue.ps create mode 100644 font/devps/psstrip.sed create mode 100644 font/devps/symbol.afm create mode 100644 font/devps/symbolsl.afm create mode 100644 font/devps/symbolsl.ps create mode 100644 font/devps/text.enc create mode 100644 font/devps/zapfdr.afm create mode 100644 font/devps/zapfdr.ps create mode 100644 font/devutf8/DESC.proto create mode 100644 font/devutf8/NOTES create mode 100644 font/devutf8/R.in create mode 100644 font/devutf8/R.proto create mode 100644 font/devutf8/devutf8.am create mode 100755 font/scripts/gendesc.sh create mode 100755 font/scripts/genfonts.sh create mode 100644 font/scripts/scripts.am create mode 100755 font/util/make-Rproto create mode 100644 gendef.sh create mode 100644 gnulib_m4/00gnulib.m4 create mode 100644 gnulib_m4/absolute-header.m4 create mode 100644 gnulib_m4/alloca.m4 create mode 100644 gnulib_m4/assert_h.m4 create mode 100644 gnulib_m4/errno_h.m4 create mode 100644 gnulib_m4/exponentd.m4 create mode 100644 gnulib_m4/exponentf.m4 create mode 100644 gnulib_m4/exponentl.m4 create mode 100644 gnulib_m4/extensions.m4 create mode 100644 gnulib_m4/extern-inline.m4 create mode 100644 gnulib_m4/float_h.m4 create mode 100644 gnulib_m4/fpieee.m4 create mode 100644 gnulib_m4/fprintf-posix.m4 create mode 100644 gnulib_m4/free.m4 create mode 100644 gnulib_m4/frexp.m4 create mode 100644 gnulib_m4/frexpl.m4 create mode 100644 gnulib_m4/fseterr.m4 create mode 100644 gnulib_m4/gnulib-cache.m4 create mode 100644 gnulib_m4/gnulib-common.m4 create mode 100644 gnulib_m4/gnulib-comp.m4 create mode 100644 gnulib_m4/include_next.m4 create mode 100644 gnulib_m4/intmax_t.m4 create mode 100644 gnulib_m4/inttypes.m4 create mode 100644 gnulib_m4/inttypes_h.m4 create mode 100644 gnulib_m4/isnand.m4 create mode 100644 gnulib_m4/isnanf.m4 create mode 100644 gnulib_m4/isnanl.m4 create mode 100644 gnulib_m4/ldexpl.m4 create mode 100644 gnulib_m4/libunistring-base.m4 create mode 100644 gnulib_m4/limits-h.m4 create mode 100644 gnulib_m4/math_h.m4 create mode 100644 gnulib_m4/memchr.m4 create mode 100644 gnulib_m4/mmap-anon.m4 create mode 100644 gnulib_m4/multiarch.m4 create mode 100644 gnulib_m4/nocrash.m4 create mode 100644 gnulib_m4/off_t.m4 create mode 100644 gnulib_m4/printf-frexp.m4 create mode 100644 gnulib_m4/printf-frexpl.m4 create mode 100644 gnulib_m4/printf.m4 create mode 100644 gnulib_m4/signbit.m4 create mode 100644 gnulib_m4/size_max.m4 create mode 100644 gnulib_m4/snprintf.m4 create mode 100644 gnulib_m4/ssize_t.m4 create mode 100644 gnulib_m4/stdbool.m4 create mode 100644 gnulib_m4/stddef_h.m4 create mode 100644 gnulib_m4/stdint.m4 create mode 100644 gnulib_m4/stdint_h.m4 create mode 100644 gnulib_m4/stdio_h.m4 create mode 100644 gnulib_m4/stdlib_h.m4 create mode 100644 gnulib_m4/string_h.m4 create mode 100644 gnulib_m4/sys_types_h.m4 create mode 100644 gnulib_m4/unistd_h.m4 create mode 100644 gnulib_m4/vasnprintf.m4 create mode 100644 gnulib_m4/vsnprintf.m4 create mode 100644 gnulib_m4/warn-on-use.m4 create mode 100644 gnulib_m4/wchar_h.m4 create mode 100644 gnulib_m4/wchar_t.m4 create mode 100644 gnulib_m4/wctype_h.m4 create mode 100644 gnulib_m4/wcwidth.m4 create mode 100644 gnulib_m4/wint_t.m4 create mode 100644 gnulib_m4/xsize.m4 create mode 100644 gnulib_m4/zzgnulib.m4 create mode 100644 lib/_Noreturn.h create mode 100644 lib/alloca.in.h create mode 100644 lib/arg-nonnull.h create mode 100644 lib/asnprintf.c create mode 100644 lib/assert.in.h create mode 100644 lib/attribute.h create mode 100644 lib/c++defs.h create mode 100644 lib/errno.in.h create mode 100644 lib/float+.h create mode 100644 lib/float.c create mode 100644 lib/float.in.h create mode 100644 lib/fprintf.c create mode 100644 lib/fpucw.h create mode 100644 lib/free.c create mode 100644 lib/frexp.c create mode 100644 lib/frexpl.c create mode 100644 lib/fseterr.c create mode 100644 lib/fseterr.h create mode 100644 lib/gnulib.mk create mode 100644 lib/inttypes.in.h create mode 100644 lib/isnan.c create mode 100644 lib/isnand-nolibm.h create mode 100644 lib/isnand.c create mode 100644 lib/isnanf-nolibm.h create mode 100644 lib/isnanf.c create mode 100644 lib/isnanl-nolibm.h create mode 100644 lib/isnanl.c create mode 100644 lib/itold.c create mode 100644 lib/limits.in.h create mode 100644 lib/localcharset.c create mode 100644 lib/localcharset.h create mode 100644 lib/math.c create mode 100644 lib/math.in.h create mode 100644 lib/memchr.c create mode 100644 lib/memchr.valgrind create mode 100644 lib/printf-args.c create mode 100644 lib/printf-args.h create mode 100644 lib/printf-frexp.c create mode 100644 lib/printf-frexp.h create mode 100644 lib/printf-frexpl.c create mode 100644 lib/printf-frexpl.h create mode 100644 lib/printf-parse.c create mode 100644 lib/printf-parse.h create mode 100644 lib/signbitd.c create mode 100644 lib/signbitf.c create mode 100644 lib/signbitl.c create mode 100644 lib/size_max.h create mode 100644 lib/snprintf.c create mode 100644 lib/stdbool.in.h create mode 100644 lib/stddef.in.h create mode 100644 lib/stdint.in.h create mode 100644 lib/stdio-impl.h create mode 100644 lib/stdio-read.c create mode 100644 lib/stdio-write.c create mode 100644 lib/stdio.in.h create mode 100644 lib/stdlib.in.h create mode 100644 lib/streq.h create mode 100644 lib/string.in.h create mode 100644 lib/sys_types.in.h create mode 100644 lib/unictype/bitmap.h create mode 100644 lib/unistd.c create mode 100644 lib/unistd.in.h create mode 100644 lib/unitypes.in.h create mode 100644 lib/uniwidth.in.h create mode 100644 lib/uniwidth/cjk.h create mode 100644 lib/uniwidth/width.c create mode 100644 lib/uniwidth/width0.h create mode 100644 lib/uniwidth/width2.h create mode 100644 lib/vasnprintf.c create mode 100644 lib/vasnprintf.h create mode 100644 lib/verify.h create mode 100644 lib/vsnprintf.c create mode 100644 lib/warn-on-use.h create mode 100644 lib/wchar.in.h create mode 100644 lib/wctype-h.c create mode 100644 lib/wctype.in.h create mode 100644 lib/wcwidth.c create mode 100644 lib/xsize.c create mode 100644 lib/xsize.h create mode 100644 m4/ax_compare_version.m4 create mode 100644 m4/ax_prog_perl_version.m4 create mode 100644 m4/codeset.m4 create mode 100644 m4/fcntl-o.m4 create mode 100644 m4/glibc21.m4 create mode 100644 m4/groff.m4 create mode 100644 m4/iconv.m4 create mode 100644 m4/lib-ld.m4 create mode 100644 m4/lib-link.m4 create mode 100644 m4/lib-prefix.m4 create mode 100644 m4/localcharset.m4 create mode 100644 makevarescape.sed create mode 100644 man/groff.7.man create mode 100644 man/groff_char.7.man create mode 100644 man/groff_diff.7.man create mode 100644 man/groff_font.5.man create mode 100644 man/groff_out.5.man create mode 100644 man/groff_tmac.5.man create mode 100644 man/man.am create mode 100644 man/roff.7.man create mode 100755 mdate.pl create mode 100644 src/devices/grodvi/dvi.cpp create mode 100644 src/devices/grodvi/grodvi.1.man create mode 100644 src/devices/grodvi/grodvi.am create mode 100644 src/devices/grohtml/grohtml.1.man create mode 100644 src/devices/grohtml/grohtml.am create mode 100644 src/devices/grohtml/html-table.cpp create mode 100644 src/devices/grohtml/html-table.h create mode 100644 src/devices/grohtml/html-text.cpp create mode 100644 src/devices/grohtml/html-text.h create mode 100644 src/devices/grohtml/html.h create mode 100644 src/devices/grohtml/output.cpp create mode 100644 src/devices/grohtml/post-html.cpp create mode 100644 src/devices/grolbp/charset.h create mode 100644 src/devices/grolbp/grolbp.1.man create mode 100644 src/devices/grolbp/grolbp.am create mode 100644 src/devices/grolbp/lbp.cpp create mode 100644 src/devices/grolbp/lbp.h create mode 100644 src/devices/grolj4/grolj4.1.man create mode 100644 src/devices/grolj4/grolj4.am create mode 100644 src/devices/grolj4/lj4.cpp create mode 100644 src/devices/gropdf/TODO create mode 100644 src/devices/gropdf/gropdf.1.man create mode 100644 src/devices/gropdf/gropdf.am create mode 100644 src/devices/gropdf/gropdf.pl create mode 100644 src/devices/gropdf/pdfmom.1.man create mode 100644 src/devices/gropdf/pdfmom.pl create mode 100644 src/devices/grops/TODO create mode 100644 src/devices/grops/grops.1.man create mode 100644 src/devices/grops/grops.am create mode 100644 src/devices/grops/ps.cpp create mode 100644 src/devices/grops/ps.h create mode 100644 src/devices/grops/psfig.diff create mode 100644 src/devices/grops/psrm.cpp create mode 100644 src/devices/grotty/TODO create mode 100644 src/devices/grotty/grotty.1.man create mode 100644 src/devices/grotty/grotty.am create mode 100755 src/devices/grotty/tests/basic_latin_glyphs_map_correctly.sh create mode 100755 src/devices/grotty/tests/osc8_works.sh create mode 100644 src/devices/grotty/tty.cpp create mode 100644 src/devices/xditview/ChangeLog create mode 100644 src/devices/xditview/DESC.in create mode 100644 src/devices/xditview/Dvi.c create mode 100644 src/devices/xditview/Dvi.h create mode 100644 src/devices/xditview/DviP.h create mode 100644 src/devices/xditview/FontMap-X11 create mode 100644 src/devices/xditview/GXditview-color.ad create mode 100644 src/devices/xditview/GXditview.ad create mode 100644 src/devices/xditview/Menu.h create mode 100644 src/devices/xditview/README create mode 100644 src/devices/xditview/TODO create mode 100644 src/devices/xditview/ad2c create mode 100644 src/devices/xditview/device.c create mode 100644 src/devices/xditview/device.h create mode 100644 src/devices/xditview/draw.c create mode 100644 src/devices/xditview/draw.h create mode 100644 src/devices/xditview/font.c create mode 100644 src/devices/xditview/font.h create mode 100644 src/devices/xditview/gray1.bm create mode 100644 src/devices/xditview/gray2.bm create mode 100644 src/devices/xditview/gray3.bm create mode 100644 src/devices/xditview/gray4.bm create mode 100644 src/devices/xditview/gray5.bm create mode 100644 src/devices/xditview/gray6.bm create mode 100644 src/devices/xditview/gray7.bm create mode 100644 src/devices/xditview/gray8.bm create mode 100644 src/devices/xditview/gxditview.1.man create mode 100644 src/devices/xditview/lex.c create mode 100644 src/devices/xditview/lex.h create mode 100644 src/devices/xditview/page.c create mode 100644 src/devices/xditview/page.h create mode 100644 src/devices/xditview/parse.c create mode 100644 src/devices/xditview/parse.h create mode 100644 src/devices/xditview/xdit.bm create mode 100644 src/devices/xditview/xdit_mask.bm create mode 100644 src/devices/xditview/xditview.am create mode 100644 src/devices/xditview/xditview.c create mode 100644 src/include/DviChar.h create mode 100644 src/include/XFontName.h create mode 100644 src/include/cmap.h create mode 100644 src/include/color.h create mode 100644 src/include/config.hin create mode 100644 src/include/cset.h create mode 100644 src/include/curtime.h create mode 100644 src/include/device.h create mode 100644 src/include/driver.h create mode 100644 src/include/errarg.h create mode 100644 src/include/error.h create mode 100644 src/include/font.h create mode 100644 src/include/geometry.h create mode 100644 src/include/getopt.h create mode 100644 src/include/getopt_int.h create mode 100644 src/include/gettext.h create mode 100644 src/include/html-strings.h create mode 100644 src/include/htmlhint.h create mode 100644 src/include/include.am create mode 100644 src/include/index.h create mode 100644 src/include/itable.h create mode 100644 src/include/lf.h create mode 100644 src/include/lib.h create mode 100644 src/include/localcharset.h create mode 100644 src/include/macropath.h create mode 100644 src/include/nonposix.h create mode 100644 src/include/paper.h create mode 100644 src/include/posix.h create mode 100644 src/include/printer.h create mode 100644 src/include/ptable.h create mode 100644 src/include/refid.h create mode 100644 src/include/relocate.h create mode 100644 src/include/search.h create mode 100644 src/include/searchpath.h create mode 100644 src/include/stringclass.h create mode 100644 src/include/symbol.h create mode 100644 src/include/unicode.h create mode 100644 src/libs/libbib/common.cpp create mode 100644 src/libs/libbib/index.cpp create mode 100644 src/libs/libbib/libbib.am create mode 100644 src/libs/libbib/linear.cpp create mode 100644 src/libs/libbib/map.c create mode 100644 src/libs/libbib/search.cpp create mode 100644 src/libs/libdriver/input.cpp create mode 100644 src/libs/libdriver/libdriver.am create mode 100644 src/libs/libdriver/printer.cpp create mode 100644 src/libs/libgroff/assert.cpp create mode 100644 src/libs/libgroff/change_lf.cpp create mode 100644 src/libs/libgroff/cmap.cpp create mode 100644 src/libs/libgroff/color.cpp create mode 100755 src/libs/libgroff/config.charset create mode 100644 src/libs/libgroff/cset.cpp create mode 100644 src/libs/libgroff/curtime.cpp create mode 100644 src/libs/libgroff/device.cpp create mode 100644 src/libs/libgroff/errarg.cpp create mode 100644 src/libs/libgroff/error.cpp create mode 100644 src/libs/libgroff/fatal.cpp create mode 100644 src/libs/libgroff/filename.cpp create mode 100644 src/libs/libgroff/fmod.c create mode 100644 src/libs/libgroff/font.cpp create mode 100644 src/libs/libgroff/fontfile.cpp create mode 100644 src/libs/libgroff/geometry.cpp create mode 100644 src/libs/libgroff/getcwd.c create mode 100644 src/libs/libgroff/getopt.c create mode 100644 src/libs/libgroff/getopt1.c create mode 100644 src/libs/libgroff/glyphuni.cpp create mode 100644 src/libs/libgroff/htmlhint.cpp create mode 100644 src/libs/libgroff/hypot.cpp create mode 100644 src/libs/libgroff/iftoa.c create mode 100644 src/libs/libgroff/invalid.cpp create mode 100644 src/libs/libgroff/itoa.c create mode 100644 src/libs/libgroff/lf.cpp create mode 100644 src/libs/libgroff/libgroff.am create mode 100644 src/libs/libgroff/lineno.cpp create mode 100644 src/libs/libgroff/localcharset.c create mode 100644 src/libs/libgroff/macropath.cpp create mode 100755 src/libs/libgroff/make-uniuni create mode 100644 src/libs/libgroff/matherr.c create mode 100644 src/libs/libgroff/maxfilename.cpp create mode 100644 src/libs/libgroff/maxpathname.cpp create mode 100644 src/libs/libgroff/mksdir.cpp create mode 100644 src/libs/libgroff/mkstemp.cpp create mode 100644 src/libs/libgroff/nametoindex.cpp create mode 100644 src/libs/libgroff/new.cpp create mode 100644 src/libs/libgroff/paper.cpp create mode 100644 src/libs/libgroff/prime.cpp create mode 100644 src/libs/libgroff/progname.c create mode 100644 src/libs/libgroff/ptable.cpp create mode 100644 src/libs/libgroff/putenv.c create mode 100644 src/libs/libgroff/quotearg.c create mode 100644 src/libs/libgroff/ref-add.sin create mode 100644 src/libs/libgroff/ref-del.sin create mode 100644 src/libs/libgroff/relocatable.h create mode 100644 src/libs/libgroff/relocate.cpp create mode 100644 src/libs/libgroff/searchpath.cpp create mode 100644 src/libs/libgroff/spawnvp.c create mode 100644 src/libs/libgroff/strcasecmp.c create mode 100644 src/libs/libgroff/strerror.c create mode 100644 src/libs/libgroff/string.cpp create mode 100644 src/libs/libgroff/strncasecmp.c create mode 100644 src/libs/libgroff/strsave.cpp create mode 100644 src/libs/libgroff/strtol.c create mode 100644 src/libs/libgroff/symbol.cpp create mode 100644 src/libs/libgroff/tmpfile.cpp create mode 100644 src/libs/libgroff/tmpname.cpp create mode 100644 src/libs/libgroff/unicode.cpp create mode 100644 src/libs/libgroff/uniglyph.cpp create mode 100644 src/libs/libgroff/uniuni.cpp create mode 100644 src/libs/libxutil/DviChar.c create mode 100644 src/libs/libxutil/XFontName.c create mode 100644 src/libs/libxutil/libxutil.am create mode 100644 src/libs/libxutil/xmalloc.c create mode 100644 src/preproc/eqn/TODO create mode 100644 src/preproc/eqn/box.cpp create mode 100644 src/preproc/eqn/box.h create mode 100644 src/preproc/eqn/delim.cpp create mode 100644 src/preproc/eqn/eqn.1.man create mode 100644 src/preproc/eqn/eqn.am create mode 100644 src/preproc/eqn/eqn.cpp create mode 100644 src/preproc/eqn/eqn.h create mode 100644 src/preproc/eqn/eqn.hpp create mode 100644 src/preproc/eqn/eqn.ypp create mode 100644 src/preproc/eqn/lex.cpp create mode 100644 src/preproc/eqn/limit.cpp create mode 100644 src/preproc/eqn/list.cpp create mode 100644 src/preproc/eqn/main.cpp create mode 100644 src/preproc/eqn/mark.cpp create mode 100644 src/preproc/eqn/neqn.1.man create mode 100644 src/preproc/eqn/neqn.sh create mode 100644 src/preproc/eqn/other.cpp create mode 100644 src/preproc/eqn/over.cpp create mode 100644 src/preproc/eqn/pbox.h create mode 100644 src/preproc/eqn/pile.cpp create mode 100644 src/preproc/eqn/script.cpp create mode 100644 src/preproc/eqn/special.cpp create mode 100644 src/preproc/eqn/sqrt.cpp create mode 100755 src/preproc/eqn/tests/diagnostics-report-correct-line-numbers.sh create mode 100644 src/preproc/eqn/text.cpp create mode 100644 src/preproc/grn/README create mode 100644 src/preproc/grn/gprint.h create mode 100644 src/preproc/grn/grn.1.man create mode 100644 src/preproc/grn/grn.am create mode 100644 src/preproc/grn/hdb.cpp create mode 100644 src/preproc/grn/hgraph.cpp create mode 100644 src/preproc/grn/hpoint.cpp create mode 100644 src/preproc/grn/main.cpp create mode 100644 src/preproc/html/html.am create mode 100644 src/preproc/html/pre-html.cpp create mode 100644 src/preproc/html/pre-html.h create mode 100644 src/preproc/html/pushback.cpp create mode 100644 src/preproc/html/pushback.h create mode 100644 src/preproc/pic/TODO create mode 100644 src/preproc/pic/common.cpp create mode 100644 src/preproc/pic/common.h create mode 100644 src/preproc/pic/lex.cpp create mode 100644 src/preproc/pic/main.cpp create mode 100644 src/preproc/pic/object.cpp create mode 100644 src/preproc/pic/object.h create mode 100644 src/preproc/pic/output.h create mode 100644 src/preproc/pic/pic.1.man create mode 100644 src/preproc/pic/pic.am create mode 100644 src/preproc/pic/pic.cpp create mode 100644 src/preproc/pic/pic.h create mode 100644 src/preproc/pic/pic.hpp create mode 100644 src/preproc/pic/pic.ypp create mode 100644 src/preproc/pic/position.h create mode 100644 src/preproc/pic/tex.cpp create mode 100644 src/preproc/pic/text.h create mode 100644 src/preproc/pic/troff.cpp create mode 100644 src/preproc/preconv/preconv.1.man create mode 100644 src/preproc/preconv/preconv.am create mode 100644 src/preproc/preconv/preconv.cpp create mode 100755 src/preproc/preconv/tests/do-not-seek-the-unseekable.sh create mode 100755 src/preproc/preconv/tests/smoke-test.sh create mode 100644 src/preproc/refer/TODO create mode 100644 src/preproc/refer/command.cpp create mode 100644 src/preproc/refer/command.h create mode 100644 src/preproc/refer/label.cpp create mode 100644 src/preproc/refer/label.hpp create mode 100644 src/preproc/refer/label.ypp create mode 100644 src/preproc/refer/ref.cpp create mode 100644 src/preproc/refer/ref.h create mode 100644 src/preproc/refer/refer.1.man create mode 100644 src/preproc/refer/refer.am create mode 100644 src/preproc/refer/refer.cpp create mode 100644 src/preproc/refer/refer.h create mode 100644 src/preproc/refer/tests/artifacts/62124.bib create mode 100755 src/preproc/refer/tests/report-correct-line-numbers.sh create mode 100644 src/preproc/refer/token.cpp create mode 100644 src/preproc/refer/token.h create mode 100644 src/preproc/soelim/TODO create mode 100644 src/preproc/soelim/soelim.1.man create mode 100644 src/preproc/soelim/soelim.am create mode 100644 src/preproc/soelim/soelim.cpp create mode 100644 src/preproc/tbl/main.cpp create mode 100644 src/preproc/tbl/table.cpp create mode 100644 src/preproc/tbl/table.h create mode 100644 src/preproc/tbl/tbl.1.man create mode 100644 src/preproc/tbl/tbl.am create mode 100755 src/preproc/tbl/tests/boxes-and-vertical-rules.sh create mode 100755 src/preproc/tbl/tests/check-horizontal-line-length.sh create mode 100755 src/preproc/tbl/tests/check-line-intersections.sh create mode 100755 src/preproc/tbl/tests/check-vertical-line-length.sh create mode 100755 src/preproc/tbl/tests/cooperate-with-nm-request.sh create mode 100755 src/preproc/tbl/tests/count-continued-input-lines.sh create mode 100755 src/preproc/tbl/tests/do-not-overdraw-page-top-in-nroff-mode.sh create mode 100755 src/preproc/tbl/tests/do-not-overlap-bottom-border-in-nroff.sh create mode 100755 src/preproc/tbl/tests/do-not-segv-on-invalid-vertical-span-entry.sh create mode 100755 src/preproc/tbl/tests/do-not-segv-when-backslash-R-in-text-block.sh create mode 100755 src/preproc/tbl/tests/expand-region-option-works.sh create mode 100755 src/preproc/tbl/tests/format-time-diagnostics-work.sh create mode 100755 src/preproc/tbl/tests/save-and-restore-hyphenation-parameters.sh create mode 100755 src/preproc/tbl/tests/save-and-restore-inter-sentence-space.sh create mode 100755 src/preproc/tbl/tests/save-and-restore-line-numbering.sh create mode 100755 src/preproc/tbl/tests/save-and-restore-tab-stops.sh create mode 100755 src/preproc/tbl/tests/warn-on-long-boxed-unkept-table.sh create mode 100755 src/preproc/tbl/tests/x-column-modifier-works.sh create mode 100644 src/roff/groff/groff.1.man create mode 100644 src/roff/groff/groff.am create mode 100644 src/roff/groff/groff.cpp create mode 100644 src/roff/groff/pipeline.c create mode 100644 src/roff/groff/pipeline.h create mode 100755 src/roff/groff/tests/ab_works.sh create mode 100755 src/roff/groff/tests/adjustment_works.sh create mode 100644 src/roff/groff/tests/artifacts/HONEYPOT create mode 100644 src/roff/groff/tests/artifacts/devascii/README create mode 100755 src/roff/groff/tests/break_zero-length_output_line_sanely.sh create mode 100755 src/roff/groff/tests/device_control_escapes_express_basic_latin.sh create mode 100755 src/roff/groff/tests/do_not_loop_infinitely_when_breaking_cjk.sh create mode 100755 src/roff/groff/tests/dot-cp_register_works.sh create mode 100755 src/roff/groff/tests/dot-nm_register_works.sh create mode 100755 src/roff/groff/tests/dot-nn_register_works.sh create mode 100755 src/roff/groff/tests/evc_produces_no_output_if_invalid.sh create mode 100755 src/roff/groff/tests/fp_should_not_traverse_directories.sh create mode 100755 src/roff/groff/tests/handle_special_input_code_points.sh create mode 100755 src/roff/groff/tests/html_works_with_grn_and_eqn.sh create mode 100755 src/roff/groff/tests/initialization_is_quiet.sh create mode 100755 src/roff/groff/tests/localization_works.sh create mode 100755 src/roff/groff/tests/msoquiet_works.sh create mode 100755 src/roff/groff/tests/on_latin1_device_oq_is_0x27.sh create mode 100755 src/roff/groff/tests/output_driver_C_and_G_options_work.sh create mode 100755 src/roff/groff/tests/recognize_end_of_sentence.sh create mode 100755 src/roff/groff/tests/regression_savannah_56555.sh create mode 100755 src/roff/groff/tests/regression_savannah_58153.sh create mode 100755 src/roff/groff/tests/regression_savannah_58162.sh create mode 100755 src/roff/groff/tests/regression_savannah_58337.sh create mode 100755 src/roff/groff/tests/regression_savannah_59202.sh create mode 100755 src/roff/groff/tests/smoke-test_html_device.sh create mode 100755 src/roff/groff/tests/some_escapes_accept_newline_delimiters.sh create mode 100755 src/roff/groff/tests/soquiet_works.sh create mode 100755 src/roff/groff/tests/string_case_xform_errors.sh create mode 100755 src/roff/groff/tests/string_case_xform_requests.sh create mode 100755 src/roff/groff/tests/string_case_xform_unicode_escape.sh create mode 100755 src/roff/groff/tests/substring_works.sh create mode 100755 src/roff/groff/tests/use_point_size_escape_with_single_digit_arg.sh create mode 100644 src/roff/nroff/nroff.1.man create mode 100644 src/roff/nroff/nroff.am create mode 100644 src/roff/nroff/nroff.sh create mode 100755 src/roff/nroff/tests/verbose_option_works.sh create mode 100644 src/roff/troff/TODO create mode 100644 src/roff/troff/charinfo.h create mode 100644 src/roff/troff/column.cpp create mode 100644 src/roff/troff/dictionary.cpp create mode 100644 src/roff/troff/dictionary.h create mode 100644 src/roff/troff/div.cpp create mode 100644 src/roff/troff/div.h create mode 100644 src/roff/troff/env.cpp create mode 100644 src/roff/troff/env.h create mode 100644 src/roff/troff/hvunits.h create mode 100644 src/roff/troff/input.cpp create mode 100644 src/roff/troff/input.h create mode 100644 src/roff/troff/mtsm.cpp create mode 100644 src/roff/troff/mtsm.h create mode 100644 src/roff/troff/node.cpp create mode 100644 src/roff/troff/node.h create mode 100644 src/roff/troff/number.cpp create mode 100644 src/roff/troff/reg.cpp create mode 100644 src/roff/troff/reg.h create mode 100644 src/roff/troff/request.h create mode 100644 src/roff/troff/token.h create mode 100644 src/roff/troff/troff.1.man create mode 100644 src/roff/troff/troff.am create mode 100644 src/roff/troff/troff.h create mode 100644 src/utils/addftinfo/addftinfo.1.man create mode 100644 src/utils/addftinfo/addftinfo.am create mode 100644 src/utils/addftinfo/addftinfo.cpp create mode 100644 src/utils/addftinfo/guess.cpp create mode 100644 src/utils/addftinfo/guess.h create mode 100644 src/utils/afmtodit/afmtodit.1.man create mode 100644 src/utils/afmtodit/afmtodit.am create mode 100644 src/utils/afmtodit/afmtodit.pl create mode 100644 src/utils/afmtodit/afmtodit.tables create mode 100755 src/utils/afmtodit/make-afmtodit-tables create mode 100644 src/utils/grog/grog.1.man create mode 100644 src/utils/grog/grog.am create mode 100644 src/utils/grog/grog.pl create mode 100755 src/utils/grog/tests/PF-does-not-start-pic-region.sh create mode 100755 src/utils/grog/tests/avoid-refer-fakeout.sh create mode 100644 src/utils/grog/tests/foo.man create mode 100755 src/utils/grog/tests/preserve-groff-options.sh create mode 100755 src/utils/grog/tests/recognize-perl-pod.sh create mode 100755 src/utils/grog/tests/smoke-test.sh create mode 100644 src/utils/hpftodit/hpftodit.1.man create mode 100644 src/utils/hpftodit/hpftodit.am create mode 100644 src/utils/hpftodit/hpftodit.cpp create mode 100644 src/utils/hpftodit/hpuni.cpp create mode 100644 src/utils/indxbib/eign create mode 100644 src/utils/indxbib/indxbib.1.man create mode 100644 src/utils/indxbib/indxbib.am create mode 100644 src/utils/indxbib/indxbib.cpp create mode 100644 src/utils/indxbib/signal.c create mode 100644 src/utils/lkbib/lkbib.1.man create mode 100644 src/utils/lkbib/lkbib.am create mode 100644 src/utils/lkbib/lkbib.cpp create mode 100644 src/utils/lookbib/lookbib.1.man create mode 100644 src/utils/lookbib/lookbib.am create mode 100644 src/utils/lookbib/lookbib.cpp create mode 100644 src/utils/pfbtops/pfbtops.1.man create mode 100644 src/utils/pfbtops/pfbtops.am create mode 100644 src/utils/pfbtops/pfbtops.c create mode 100644 src/utils/tfmtodit/tfmtodit.1.man create mode 100644 src/utils/tfmtodit/tfmtodit.am create mode 100644 src/utils/tfmtodit/tfmtodit.cpp create mode 100644 src/utils/xtotroff/xtotroff.1.man create mode 100644 src/utils/xtotroff/xtotroff.am create mode 100644 src/utils/xtotroff/xtotroff.c create mode 100644 test-groff.in create mode 100644 tmac/62bit.tmac create mode 100644 tmac/LOCALIZATION create mode 100644 tmac/TESTING-HINTS create mode 100644 tmac/TODO create mode 100644 tmac/X.tmac create mode 100644 tmac/Xps.tmac create mode 100644 tmac/an-ext.tmac create mode 100644 tmac/an.tmac create mode 100644 tmac/andoc.tmac create mode 100644 tmac/composite.tmac create mode 100644 tmac/cp1047.tmac create mode 100644 tmac/cs.tmac create mode 100644 tmac/de.tmac create mode 100644 tmac/den.tmac create mode 100644 tmac/devtag.tmac create mode 100644 tmac/doc-old.tmac create mode 100644 tmac/doc.tmac create mode 100644 tmac/dvi.tmac create mode 100644 tmac/e.tmac create mode 100644 tmac/ec.tmac create mode 100644 tmac/en.tmac create mode 100644 tmac/eqnrc create mode 100644 tmac/europs.tmac create mode 100644 tmac/fallbacks.tmac create mode 100644 tmac/fixmacros.sed create mode 100644 tmac/fr.tmac create mode 100644 tmac/groff_man.7.man.in create mode 100644 tmac/groff_mdoc.7.man create mode 100644 tmac/groff_me.7.man create mode 100644 tmac/groff_ms.7.man create mode 100644 tmac/groff_trace.7.man create mode 100644 tmac/groff_www.7.man create mode 100644 tmac/html-end.tmac create mode 100644 tmac/html.tmac create mode 100644 tmac/hyphen.cs create mode 100644 tmac/hyphen.den create mode 100644 tmac/hyphen.det create mode 100644 tmac/hyphen.en create mode 100644 tmac/hyphen.fr create mode 100644 tmac/hyphen.it create mode 100644 tmac/hyphen.sv create mode 100644 tmac/hyphenex.cs create mode 100644 tmac/hyphenex.en create mode 100644 tmac/hyphenex.pl create mode 100644 tmac/it.tmac create mode 100644 tmac/ja.tmac create mode 100644 tmac/latin1.tmac create mode 100644 tmac/latin2.tmac create mode 100644 tmac/latin5.tmac create mode 100644 tmac/latin9.tmac create mode 100644 tmac/lbp.tmac create mode 100644 tmac/lj4.tmac create mode 100644 tmac/man.local create mode 100644 tmac/man.tmac create mode 100644 tmac/man.ultrix create mode 100644 tmac/mandoc.tmac create mode 100644 tmac/mdoc.local create mode 100644 tmac/mdoc.tmac create mode 100644 tmac/mdoc/doc-common create mode 100644 tmac/mdoc/doc-ditroff create mode 100644 tmac/mdoc/doc-nroff create mode 100644 tmac/mdoc/doc-syms create mode 100644 tmac/me.tmac create mode 100644 tmac/ms.tmac create mode 100644 tmac/papersize.tmac create mode 100644 tmac/pdf.tmac create mode 100644 tmac/pdfpic.tmac create mode 100644 tmac/pic.tmac create mode 100644 tmac/ps.tmac create mode 100644 tmac/psatk.tmac create mode 100644 tmac/psfig.tmac create mode 100644 tmac/psold.tmac create mode 100644 tmac/pspic.tmac create mode 100644 tmac/ptx.tmac create mode 100644 tmac/refer-me.tmac create mode 100644 tmac/refer-ms.tmac create mode 100644 tmac/refer.tmac create mode 100644 tmac/s.tmac create mode 100644 tmac/sv.tmac create mode 100755 tmac/tests/an-ext_MR-works.sh create mode 100755 tmac/tests/an-ext_MT-works.sh create mode 100755 tmac/tests/an-ext_UR-works.sh create mode 100755 tmac/tests/an_AT-and-UC-footer-saved-and-restored.sh create mode 100755 tmac/tests/an_CS-register-off.sh create mode 100755 tmac/tests/an_CS-register-on.sh create mode 100755 tmac/tests/an_CS-register-unspecified.sh create mode 100755 tmac/tests/an_CT-register-off.sh create mode 100755 tmac/tests/an_CT-register-on.sh create mode 100755 tmac/tests/an_CT-register-unspecified.sh create mode 100755 tmac/tests/an_FT-bad-value-should-not-trash-titles.sh create mode 100755 tmac/tests/an_HY-register-works.sh create mode 100755 tmac/tests/an_LL-init-sanely.sh create mode 100755 tmac/tests/an_ME-punct-hyphenates.sh create mode 100755 tmac/tests/an_MR-works.sh create mode 100755 tmac/tests/an_MT-body-hyphenates.sh create mode 100755 tmac/tests/an_MT-works.sh create mode 100755 tmac/tests/an_P-register-works.sh create mode 100755 tmac/tests/an_TH-repairs-ad-damage.sh create mode 100755 tmac/tests/an_TH-repairs-hy-damage.sh create mode 100755 tmac/tests/an_TS-adds-no-vertical-space.sh create mode 100755 tmac/tests/an_TS-do-not-keep-tables-when-cR-set.sh create mode 100755 tmac/tests/an_UE-breaks-before-long-URIs.sh create mode 100755 tmac/tests/an_UE-punct-hyphenates.sh create mode 100755 tmac/tests/an_UR-body-hyphenates.sh create mode 100755 tmac/tests/an_UR-works.sh create mode 100755 tmac/tests/an_X-register-works.sh create mode 100755 tmac/tests/an_adjust-link-text-correctly.sh create mode 100755 tmac/tests/an_avoid-two-font-denial-of-service.sh create mode 100755 tmac/tests/an_do-not-abbreviate-escape-using-TH-arguments.sh create mode 100755 tmac/tests/an_font-remapping-does-not-affect-titles.sh create mode 100755 tmac/tests/an_handle-degenerate-input-quietly.sh create mode 100755 tmac/tests/an_inner-footer-abbreviation-works.sh create mode 100755 tmac/tests/an_link-macros-work-in-paragraph-tags.sh create mode 100755 tmac/tests/an_link-trailing-text-hugs-previous.sh create mode 100755 tmac/tests/an_no-break-after-short-paragraph-tags.sh create mode 100755 tmac/tests/an_output-footer-when-continuously-rendering.sh create mode 100755 tmac/tests/an_page-footers-present.sh create mode 100755 tmac/tests/an_page-header-has-current-data.sh create mode 100755 tmac/tests/an_reset-hyphenation-correctly.sh create mode 100755 tmac/tests/an_title-abbreviation-works.sh create mode 100755 tmac/tests/an_use-input-traps-correctly.sh create mode 100755 tmac/tests/an_works-with-ec.sh create mode 100755 tmac/tests/andoc_P-register-works.sh create mode 100755 tmac/tests/andoc_check-an-to-doc-transition.sh create mode 100755 tmac/tests/andoc_clear-doc-traps.sh create mode 100755 tmac/tests/andoc_flush-between-packages.sh create mode 100755 tmac/tests/doc_CS-works.sh create mode 100755 tmac/tests/doc_CT-works.sh create mode 100755 tmac/tests/doc_D-places-page-numbers-correctly.sh create mode 100755 tmac/tests/doc_Lk-respect-sentence-ending-punctuation.sh create mode 100755 tmac/tests/doc_Mt-works.sh create mode 100755 tmac/tests/doc_Nm-works.sh create mode 100755 tmac/tests/doc_P-register-works.sh create mode 100755 tmac/tests/doc_X-register-works.sh create mode 100755 tmac/tests/doc_accept-mixed-case-section-headings.sh create mode 100755 tmac/tests/doc_do-not-loop-infinitely-when-shortening-headers.sh create mode 100755 tmac/tests/doc_heading-font-remapping-works.sh create mode 100755 tmac/tests/doc_indents-correctly.sh create mode 100755 tmac/tests/doc_output-footer-when-continuously-rendering.sh create mode 100755 tmac/tests/doc_smoke-test.sh create mode 100755 tmac/tests/e_chapter-titles-work.sh create mode 100755 tmac/tests/e_columns-work-on-long-pages.sh create mode 100755 tmac/tests/e_delayed-text-marks-work.sh create mode 100755 tmac/tests/e_footnote-marks-work.sh create mode 100755 tmac/tests/e_footnotes-work-with-columns.sh create mode 100755 tmac/tests/e_ld-works.sh create mode 100755 tmac/tests/e_line-numbering-works.sh create mode 100755 tmac/tests/e_rejects-too-short-page-lengths.sh create mode 100755 tmac/tests/ec_works.sh create mode 100755 tmac/tests/latin2_works.sh create mode 100755 tmac/tests/latin5_works.sh create mode 100755 tmac/tests/latin9_works.sh create mode 100755 tmac/tests/localization-works.sh create mode 100755 tmac/tests/pdfpic_does-not-choke-on-bad-pdfinfo-output.sh create mode 100755 tmac/tests/pdfpic_falls-back-to-PSPIC.sh create mode 100755 tmac/tests/s_IP-indents-using-paragraph-type-size.sh create mode 100755 tmac/tests/s_IP-respects-inter-sentence-space-in-tags.sh create mode 100755 tmac/tests/s_PN-works.sh create mode 100755 tmac/tests/s_R-handles-its-arguments.sh create mode 100755 tmac/tests/s_SH-resets-IP-indentation-amount.sh create mode 100755 tmac/tests/s_TC-works-with-percent-in-custom-titles.sh create mode 100755 tmac/tests/s_XA-literal-no-argument-suppresses-leader.sh create mode 100755 tmac/tests/s_honor-MINGW-when-two-columns.sh create mode 100755 tmac/tests/s_mark-column-start-correctly.sh create mode 100755 tmac/tests/s_no-excess-space-around-displays.sh create mode 100755 tmac/tests/s_rejects-too-short-page-lengths.sh create mode 100644 tmac/tmac.am create mode 100644 tmac/trace.tmac create mode 100644 tmac/trans.tmac create mode 100644 tmac/troffrc create mode 100644 tmac/troffrc-end create mode 100644 tmac/tty-char.tmac create mode 100644 tmac/tty.tmac create mode 100644 tmac/www.tmac.in create mode 100644 tmac/zh.tmac diff --git a/.tarball-version b/.tarball-version new file mode 100644 index 0000000..a6c2798 --- /dev/null +++ b/.tarball-version @@ -0,0 +1 @@ +1.23.0 diff --git a/.version b/.version new file mode 100644 index 0000000..a6c2798 --- /dev/null +++ b/.version @@ -0,0 +1 @@ +1.23.0 diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/BUG-REPORT b/BUG-REPORT new file mode 100644 index 0000000..0ca6f2d --- /dev/null +++ b/BUG-REPORT @@ -0,0 +1,72 @@ + Copyright (C) 1999-2020, 2022 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without + modification, are permitted in any medium without royalty provided + the copyright notice and this notice are preserved. + + groff Bug Report + +[Please read the 'PROBLEMS' file before submitting a bug report. + +Please fill in all fields, even if you think they are not relevant. + +Please delete the text in square brackets before submitting it. + +Please report distinguishable problems separately. + +Place this completed form in a new bug report at +. Click on the "Bugs" link, +then select "Submit new" from the menu.] + ++verbatim+ +GROFF VERSION: +[Put the output of the failing command when run with the '--version' +option here. For example, "groff --version" or "indxbib --version".] + +PLATFORM: +[Put the output of the "uname -a" command here. On non-POSIX systems, +some alternative should be available; on Windows systems, use "ver".] + +CONFIGURATION REPORT: +[If you compiled groff yourself, include the portion of the 'configure' +script's output between rows of dashes. If you didn't compile groff +yourself, supply the packaging information from your distributor: in +DEB- and RPM-based GNU/Linux distributions, gather it with the commands +"dpkg -s groff" or "rpm -qi groff", respectively.] + +INPUT FILES: +[Include all the files necessary to reproduce the problem that are not +part of the standard groff distribution. This includes device and font +description files and any macro files your document uses that groff does +not supply. Attach them to the bug report. + +It's easier for us if you can provide an example that doesn't depend on +any macro package, but obviously if you're reporting a problem with a +macro package that won't be possible. Further, a short example is more +convenient than a long one, but don't worry if you can't find a short +example. A claim like "any file that X" is not helpful: always include +a concrete example.] + +COMMAND LINE: +[The command line that we should run in order to observe the bug. For +example, "groff -Tps bug.tr".] + +DESCRIPTION OF INCORRECT BEHAVIOUR: +[What goes wrong when that command line is run? For example, "groff +gets a segmentation fault.", or "The output looks bad because the bar +over the x is too long and is too far over to the left." If you get an +error message, include it here without modification: don't edit it to +make it more readable.] + +SUGGESTED FIX [optional]: +[If you can suggest a fix for the problem, you might include a unified +diff here. But don't delay submitting a bug report in the hope of +finding a fix. A guess about a bug's cause is not usually helpful.] +-verbatim- + +##### Editor settings +Local Variables: +fill-column: 72 +mode: text +End: +vim: set filetype= textwidth=72: diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..bfcc345 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,18665 @@ +2023-06-21 G. Branden Robinson + + [ms]: Offer advice to users of PDF who want a table of contents + at the front of the document. + + * doc/groff.texi (ms Document Structure): Move mention of + pdfjam(1) from here... + (ms TOC): ...to here, and identify alternatives, including + gropdf(1)'s `pdfswitchtopage` macro. + + * doc/ms.ms (General structure of an ms document): + (Creating a table of contents): Similar. + + Fixes . Thanks to Michał + Kruszewski for the report. + +2023-06-01 G. Branden Robinson + + [docs]: Migrate terminology to "scaling unit". + + ...from "scaling indicator". + + Fixes . Thanks to Ingo + Schwarze for the discussion. + +2023-05-29 G. Branden Robinson + + [docs]: Revise discussion of fonts. + + * doc/groff.texi: + - Rename node/section "Fonts and Symbols" to "Using Fonts". Add + giant new introduction, properly establishing terminology. + - Rename node/section "Changing Fonts" to "Selecting Fonts". + Shift location of `.fn` and `.sty` register documentation. + Rewrite presentation of `ft` and `\f`. Discuss typeface + selection by mounting position and font (or style) name + together; since arguments to these formatter instructions are + always interpreted as mounting positions first, it doesn't + make much sense to me to present them separately, and the new + introduction provides the necessary background. Tighten + example. Document that current and previous font selections + are environment properties. + - Add several concept index entries. + - Do more migration from "symbol" and "glyph" names to "special + character" names. + + * man/groff.7 (Using fonts): Introduce new section, synced with + the renamed node from our Texinfo manual above. + + Fixes . + +2023-05-29 G. Branden Robinson + + [docs]: Revise "Page Layout" material. + + * doc/groff.texi: + - Recast generally. + - Describe behavior of `pl` in more detail. + - Migrate terminology from "scaling indicator" to "scaling + unit". + - Stop discussing page margins in the context of the `pl` + request. + - Move concept index entries regarding margins from here to + "Traps". + - Move discussion of `pn` request to precede `tl` request. + - Add concept index entries. + - Recast description of `tl` request. Migrate terminology from + "justification" to "alignment". + - Recast description of `lt` request. Describe behavior in more + detail. + - Recast description of `pc` request. + - Add example of `lt` and `tl` usage. Add forward reference to + "Traps", mentioning page header and footer traps. + + Fixes . Thanks to Dave + Kemper for the report. + +2023-05-22 Dave Kemper + + [docs]: Correct minor punctuation, grammar, and spelling issues. + + Also remove a couple instances of unnecessarily telling the + reader to note something. + + * doc/groff.texi: + * man/groff.7.man: + * man/groff_char.7.man: + * man/groff_diff.7.man: + * man/roff.7.man: + * src/roff/nroff/nroff.1.man: Do it. + + Fixes . [I threw in a few + more fixes. --GBR] + +2023-04-22 G. Branden Robinson + + [docs]: Attempt to further clarify end-of-sentence detection. + + * doc/groff.texi (Sentences): + * man/roff.7 (Concepts): Do it. + + Fixes . Thanks to Ingo + Schwarze and Dave Kemper for the report. + +2023-04-14 G. Branden Robinson + + [docs]: Minimally document `tag`, `taga` requests. + + * doc/groff.texi (Postprocessor Access): + * man/groff.7 (Request short reference): Do it. + + Fixes . + +2023-04-11 G. Branden Robinson + + [docs]: Fix typos. + + * doc/groff.texi (ms basic information): + * doc/ms.ms (Basic information): Do it. + + Fixes . Thanks to an + anonymous reporter. + +2023-03-07 G. Branden Robinson + + * doc/groff.texi (Operators in Conditionals): + * man/groff.7.in (Conditional expressions): Clarify how the + output comparison operator is recognized. + + Fixes . Thanks to John + Gardner for the report. + +2023-03-06 G. Branden Robinson + + Use a better type for symbol hashes. + + * bootstrap.conf: Add "stdint" module to ensure that the + `uintptr_t` type is available. + * src/include/symbol.h: Include for `uintptr_t`. + (class symbol): + (symbol::hash): Change return type from `unsigned long`, which + causes build failures on 64-bit MinGW, to `uintptr_t`. + (symbol::hash): Use a C++ type cast, not a C-style one. + + Thanks to Bruno Haible for reporting the build failure in the + 64-bit MinGW environment, and for suggesting a remedy. + +2023-03-06 G. Branden Robinson + + [groff]: Revise a test to be more revealing. + + * src/roff/groff/tests/initialization_is_quiet.sh: Stop using + "set -e". Instead use `fail` variable and `wail` function (and + lowercase names for our internal variables) like many of our + other tests. If the "unset" shell built-in fails, skip the + test (prompted by /usr/xpg4/bin/sh on Solaris). Attempt every + groff locale, with and without compatibility mode initially + enabled, instead of stopping at the first failure. Report + standard error and standard output content separately. Use + groff's `-a` flag to prepare the standard output, for + readability. + * PROBLEMS: Document that this test might be skipped rather than + failing on Solaris. (What actually happens depends on which + shell you run it with, and we advise a variety of approaches.) + + Thanks to Bruno Haible for feedback regarding mysterious + failures of this test on GNU/Hurd and NetBSD systems. + +2023-03-06 G. Branden Robinson + + * bootstrap.conf (gnulib_modules): Add "stdbool-c99" per + recommendation from Bruno Haible. + + Fixes build problem on Solaris using Sun compiler. + +2023-03-06 Bruno Haible + + * Makefile.am (AR): Remove hardcoded value. Let Automake use the + value from config.status. + + {Fixes build problem on 64-bit AIX. Problem appears to date + back to commit 5fec19d453, 2014-08-15. --GBR} + +2023-03-06 Bruno Haible + + * arch/misc/misc.am (shdeps.sed): Rename target from this... + ($(SH_DEPS_SED_SCRIPT)): ...to this, to work better with make(1) + on FreeBSD, NetBSD, and AIX. + +2023-03-01 G. Branden Robinson + + [build]: Discard now-unneeded Autoconf macro and variables. + + * configure.ac: Stop calling `GROFF_POPPLER`. Stop populating + the Automake conditional `HAVE_PDFTOOLS`. Eliminate chatter + about their availability in the configuration report. + * m4/groff.m4 (GROFF_POPPLER): Delete. + +2023-03-01 G. Branden Robinson + + * m4/groff.m4 (GROFF_URW_FONTS_NOTICE): Adapt wording of notice + to presence and identity of Ghostscript interpreter command. + Clarify that it is gropdf(1) specifically that traverses the + Ghostscript search path reported by its "-h" option. + + Continues . Thanks to + Deri James for the ongoing discussion. + +2023-02-25 G. Branden Robinson + + [devpdf]: Revise tests. + + * font/devpdf/tests/check-default-foundry.sh.in: Test only the + base 14 fonts of the PDF standard unconditionally. Test the + remainder from the set of 35 commonly distributed only if a + Ghostscript interpreter was detected at configuration time, + because the latter fonts _must_ be embedded in PDF documents. + If they're not present, skip the test rather than failing it. + * font/devpdf/tests/check-urw-foundry.sh.in: Skip test if no URW + fonts detected at configuration time, rather than failing it. + * m4/groff.m4 (GROFF_GROPDF_PROGRAM_NOTICE) + (GROFF_URW_FONTS_NOTICE): Drop warnings of expected test + failures. The tests no longer fail in the anticipated + circumstances. + +2023-02-24 G. Branden Robinson + + [devpdf]: Generate tests from template files, so we can populate + the test scripts with information determined at configuration. + The default foundry test depends on $GHOSTSCRIPT, and the URW + foundry test on $urwfontsdir. + + * font/devpdf/tests/check-default-foundry.sh: + * font/devpdf/tests/check-urw-foundry.sh: Rename these... + * font/devpdf/tests/check-default-foundry.sh.in: + * font/devpdf/tests/check-urw-foundry.sh.in: ...to these. + + * font/devpdf/devpdf.am (font_devpdf_default_test) + (font_devpdf_urw_test): New variables store names of generated + test scripts. + (font/devpdf/tests/check-default-foundry.sh): + (font/devpdf/tests/check-urw-foundry.sh): New targets produce + test scripts from corresponding .in files. + +2023-02-24 G. Branden Robinson + + [devpdf]: Trivially refactor. Rename sed-substitutum [Lat.] + from "@GROFF_GHOSTSCRIPT_INTERPRETERS@" to "@GHOSTSCRIPT@" for + clarity and brevity; this is a scalar value containing the + Autoconf-determined name of the Ghostscript interpreter. It is + not the same as the replacement that occurs in contrib/pdfmark. + + * font/devpdf/devpdf.am: + * font/devpdf/util/BuildFoundries.pl: Do it. + +2023-02-24 G. Branden Robinson + + [build]: Stop scraping output of Ghostscript executable with + "-h" option to attempt to find URW fonts. Fonts that ship with + Ghostscript are regarded as the "default" foundry, not the URW + foundry (though they often ultimately originate with URW fonts). + They are often missing Adobe Font Metric (AFM) files, so it is + impossible for groff to generate font description files for them + at build time. + + * m4/groff.m4 (GROFF_URW_FONTS_CHECK): Drop `AC_REQUIRE` on + `GROFF_AWK_PATH`. Drop awk-based scraping of Ghostscript "-h" + output. Annotate need for sync between this list of + characteristic font file names and the one in BuildFoundries. + + Thanks to Deri James for the ongoing discussions. + +2023-02-24 G. Branden Robinson + + * configure.ac: Drop now-redundant explicit + `GROFF_URW_FONTS_CHECK`. `GROFF_GROPDF_DEPENDENCIES_CHECK` + `AC_REQUIRE`s it as of commit ec001d2a23, 18 February. + +2023-02-24 G. Branden Robinson + + * m4/groff.m4 (GROFF_URW_FONTS_CHECK): When looking for a + characteristic URW font by its file name, also check for + "URWGothic-Book" with no file extension. Avoids false negatives + in URW Type 1 font detection when using Ghostscript 9.53.3. + Thanks to Deri James for suggesting the test procedure that + uncovered this flaw. + +2023-02-22 G. Branden Robinson + + * Makefile.am (uninstall_groffdirs): Remove "html.mono" and + "html.node" directories corresponding to HTML version of our + Texinfo manual. + * doc/doc.am (uninstall-html): Uninstall HTML version of our + Texinfo manual more reliably. + + Fixes a regression introduced by me in commit c2698aade, 6 April + {my claim "we're only deleting files with this command, not + directories" was not correct}. + +2023-02-22 G. Branden Robinson + + [doc]: Handle output formats of our Texinfo manual more + consistently. + + * doc/doc.am (install-doc): Add dependency on (Automake + standard) target 'install-dvi'. + (maintainer-clean-local): Remove our Texinfo manual in plain + text format. + (install-data-local): Add dependency on new target + 'install-txt'. + (install-txt): Install our Texinfo manual in plain text format. + (uninstall-local): Add dependency on new target 'uninstall-txt'. + (uninstall-txt): Uninstall our Texinfo manual in plain text + format. + + Thanks to T. Kurt Bond for noticing the discrepancy. + +2023-02-22 G. Branden Robinson + + * doc/doc.am (install-pdf-local, install-html-local): Enable + rules to work in out-of-tree builds. + +2023-02-22 G. Branden Robinson + + * doc/doc.am (uninstall-hook): Drop dependency on + "uninstall_mom"; this is not the appropriate place to declare + it, and "uninstall_groffdirs" already depends on it in mom's + Automake file. + +2023-02-22 G. Branden Robinson + + [tests]: Have more tests report output. + + * src/roff/groff/tests/ab_works.sh: + * src/roff/groff/tests/handle_special_input_code_points.sh: + * src/roff/groff/tests/initialization_is_quiet.sh: + * src/roff/groff/tests/msoquiet_works.sh: + * src/roff/groff/tests/soquiet_works.sh: + * tmac/tests/an-ext_MR-works.sh: + * tmac/tests/an_MR-works.sh: Do it. + +2023-02-22 G. Branden Robinson + + [tests]: Prevent failures when $GROFF_ENCODING is set. + + * src/roff/groff/tests/ab_works.sh: + * src/roff/groff/tests/handle_special_input_code_points.sh: + * src/roff/groff/tests/initialization_is_quiet.sh: + * src/roff/groff/tests/msoquiet_works.sh: + * src/roff/groff/tests/soquiet_works.sh: + * tmac/tests/an-ext_MR-works.sh: + * tmac/tests/an_MR-works.sh: + * tmac/tests/an_font-remapping-does-not-affect-titles.sh: Unset + $GROFF_ENCODING before running test because preconv(1) confounds + these tests. + + Thanks to Alexis for reporting this problem. + +2023-02-21 G. Branden Robinson + + [ms]: Rename test. + + * tmac/tests/s_no-excess-space-around-displays.tmac: Rename... + * tmac/tests/s_no-excess-space-around-displays.sh: ...to this. + * tmac/tmac.am (tmac_TESTS): Update. + +2023-02-21 G. Branden Robinson + + [gropdf]: Revise tests to run unconditionally, rather than + configuring them away at build time, which can cause a + distribution archive to be incorrectly structured. Update + configuration notices when optional dependencies are absent. + + * font/devpdf/devpdf.am (font_devpdf_TESTS): Remove `USE_GROPDF` + and `HAVE_URW_FONTS` conditionals. + * m4/groff.m4 (GROFF_GROPDF_PROGRAM_NOTICE): + (GROFF_URW_FONTS_NOTICE): Warn reader that a gropdf test failure + is to be expected. + + Fixes (2/2). + +2023-02-21 G. Branden Robinson + + [grohtml]: Revise tests to check for requisite programs at test + time and skip if not found, rather than configuring them away at + build time, which can cause a distribution archive to be + incorrectly structured. + + * m4/groff.m4: Annotate requisite program list since we're + violating the DRY principle. + * src/roff/groff/groff.am (groff_TESTS): Populate + unconditionally. + + * src/roff/groff/tests/html_works_with_grn_and_eqn.sh: + * src/roff/groff/tests/smoke-test_html_device.sh: Check for + requisite programs and skip test if any are not found. + + Fixes (1/2). + +2023-02-21 G. Branden Robinson + + [man pages]: Define page-local `MR` fallback. + + [man pages]: Provide page-local fallback definition of new `MR` + macro. I didn't think I was going to have to do this, but the + premier site on the web for viewing Linux man pages, Michael + Kerrisk's man7.org, has been pulling snapshots of the pages + themselves without upgrading the underlying macros, and so man + page cross references set with `MR` are getting lost in its + presentations. (I acknowledge: Ingo Schwarze warned me + something like this could happen.) This definition is intended + as a stopgap measure only. I want to revert this after groff + 1.23 is released and has spread to some reasonable degree. + + * contrib/chem/chem.1.man: + * contrib/eqn2graph/eqn2graph.1.man: + * contrib/gdiffmk/gdiffmk.1.man: + * contrib/glilypond/glilypond.1.man: + * contrib/gperl/gperl.1.man: + * contrib/gpinyin/gpinyin.1.man: + * contrib/grap2graph/grap2graph.1.man: + * contrib/hdtbl/groff_hdtbl.7.man: + * contrib/mm/groff_mm.7.man: + * contrib/mm/groff_mmse.7.man: + * contrib/mm/mmroff.1.man: + * contrib/mom/groff_mom.7.man: + * contrib/pdfmark/pdfroff.1.man: + * contrib/pic2graph/pic2graph.1.man: + * contrib/rfc1345/groff_rfc1345.7.man: + * man/groff.7.man: + * man/groff_char.7.man: + * man/groff_diff.7.man: + * man/groff_font.5.man: + * man/groff_out.5.man: + * man/groff_tmac.5.man: + * man/roff.7.man: + * src/devices/grodvi/grodvi.1.man: + * src/devices/grohtml/grohtml.1.man: + * src/devices/grolbp/grolbp.1.man: + * src/devices/grolj4/grolj4.1.man: + * src/devices/gropdf/gropdf.1.man: + * src/devices/gropdf/pdfmom.1.man: + * src/devices/grops/grops.1.man: + * src/devices/grotty/grotty.1.man: + * src/devices/xditview/gxditview.1.man: + * src/preproc/eqn/eqn.1.man: + * src/preproc/eqn/neqn.1.man: + * src/preproc/grn/grn.1.man: + * src/preproc/pic/pic.1.man: + * src/preproc/preconv/preconv.1.man: + * src/preproc/refer/refer.1.man: + * src/preproc/soelim/soelim.1.man: + * src/preproc/tbl/tbl.1.man: + * src/roff/groff/groff.1.man: + * src/roff/nroff/nroff.1.man: + * src/roff/troff/troff.1.man: + * src/utils/addftinfo/addftinfo.1.man: + * src/utils/afmtodit/afmtodit.1.man: + * src/utils/grog/grog.1.man: + * src/utils/hpftodit/hpftodit.1.man: + * src/utils/indxbib/indxbib.1.man: + * src/utils/lkbib/lkbib.1.man: + * src/utils/lookbib/lookbib.1.man: + * src/utils/pfbtops/pfbtops.1.man: + * src/utils/tfmtodit/tfmtodit.1.man: + * src/utils/xtotroff/xtotroff.1.man: + * tmac/groff_man.7.man.in: + * tmac/groff_me.7.man: + * tmac/groff_ms.7.man: + * tmac/groff_trace.7.man: + * tmac/groff_www.7.man: Do it. + + Fixes . Thanks greatly to + Alexis for identifying an issue with mandoc(1)'s handling of an + earlier iteration of this fallback, and to John Gardner for + identifying a method of detecting mandoc as the renderer at + formatting time. + +2023-02-20 G. Branden Robinson + + * tmac/tests/an_TS-do-not-keep-tables-when-cR-set.sh: Improve + portability of script by using shell constructs instead of the + nonstandard GNU coreutils 'seq' utility. Resolves test failure + on Solaris 10. + * HACKING: Document this problem. + +2023-02-20 G. Branden Robinson + + * m4/groff.m4 (GROFF_MAKE_DEFINES_RM): Test the make(1) in the + environment variable $MAKE if defined, not a literal "make". + Required on (some) Solaris 10 configurations where traditional + make(1) is not installed but GNU make is installed as "gmake". + +2023-02-19 G. Branden Robinson + + * tmac/tests/latin2_works.sh: Fix missing backslash in printf. + Solaris printf(1) was sensitive to this error; macOS and GNU + printf were not. Fixes a test failure on Solaris 11. + +2023-02-19 G. Branden Robinson + + * src/roff/groff/tests/regression_savannah_58153.sh: Improve + portability. Avoid the unpredictability of implementations when + putting backslashes inside a groff-piped printf shell command + inside a here document inside a command substitution by changing + the groff escape character to something meaningless to the shell + and to printf ('@'). Fixes a test failure on Solaris 11. + +2023-02-18 G. Branden Robinson + + * font/devpdf/Foundry.in: Recognize URW foundry replacements for + Helvetica Bold-Oblique and Helvetica Oblique under the file + names "NimbusSans-BoldItalic.t1" and "NimbusSans-Italic.t1", + respectively. + +2023-02-18 G. Branden Robinson + + * doc/doc.am (uninstall-pdf): Clean more fastidiously; try to + remove the configured `pdfdocdir` in the event it is empty, but + do not fail if it isn't. (It can be a directory shared with + other groff components; we don't know in what order the + uninstall targets will serialize, but the last one run should + succeed.) + +2023-02-18 G. Branden Robinson + + [build]: Detangle "pdfroff" and "gropdf" configuration (2/2). + + * m4/groff.m4: Give pdfroff its own Autoconf macros to handle + dependency checking, build objectives, and user notice. + (GROFF_PDFROFF_DEPENDENCIES_CHECK): New macro requires + `GROFF_AWK_PATH` and `GROFF_GHOSTSCRIPT_PATH`, determines + whether pdfroff can be used at build time, and (if not) + constructs part of message to be shown to user explaining why. + (GROFF_PDFROFF_PROGRAM_NOTICE): New macro requires + `GROFF_PDFROFF_DEPENDENCIES_CHECK` and emits message if needed. + (GROFF_GHOSTSCRIPT_AVAILABILITY_NOTICE): Drop mention of impact + on pdfroff since its dedicated notice covers this now. + * configure.ac: Call the new macros at appropriate times. + Produce a new Automake macro, `USE_PDFROFF`, to replace + inapposite use of `USE_GROPDF` in pdfmark.am. + * contrib/pdfmark/pdfmark.am: Use `USE_PDFROFF` instead of + `USE_GROPDF`. + +2023-02-18 G. Branden Robinson + + [build]: Detangle "pdfroff" and "gropdf" configuration (1/2). + + * m4/groff.m4 (GROFF_GROPDF_DEPENDENCIES_CHECK): Add + `AC_REQUIRE`ment on `GROFF_URW_FONTS_CHECK`. Per discussion + with Deri James, if _either_ Ghostscript or the URW fonts are + avilable, gropdf will be fully functional, consequent to commit + d5515, 22 June. Drop dependency on awk; it is used only at + configuration time (in an Autoconf macro) and since Savannah + #62775 was resolved (19 September), it has not been strictly + necessary. (It is useful for searching more locations for URW + fonts, but several others are searched even if it is absent.) + Stop populating notice text here, instead moving it... + (GROFF_GROPDF_PROGRAM_NOTICE): ...here, since it no longer needs + to be dynamically constructed. + + Continues . Thanks to + Deri James for the continued discussion. + +2023-02-18 G. Branden Robinson + + [build]: Rename `GROFF_CHECK_GROPDF_PROGRAMS` macro to + `GROFF_GROPDF_DEPENDENCIES_CHECK` to generalize for greater + accuracy in forthcoming change. + + * configure.ac: + * m4/groff.m4: Do it. + +2023-02-18 G. Branden Robinson + + [gropdf]: Don't run automated tests if 'gropdf' will be + operating with reduced function. If neither Ghostscript nor the + URW fonts are available at configuration time, there is no point + testing for successful build-time population of the font + descriptions for the default and URW foundries. + + * font/devpdf/devpdf.am (font_devpdf_TESTS) [USE_GROPDF]: Run + "check-default-foundry" only if gropdf is fully functional. + (font_devpdf_TESTS) [USE_GROPDF && HAVE_URW_FONTS]: Run + "check-urw-foundry" only if the URW fonts were found. + + Continues . Thanks to + Deri James for the continued discussion. + +2023-02-18 G. Branden Robinson + + [gropdf]: Rename tests to more accurately characterize their + purpose. + + * font/devpdf/tests/basic-fonts-present.sh: + * font/devpdf/tests/urw-fonts-present.sh: Rename these... + * font/devpdf/tests/check-default-foundry.sh: + * font/devpdf/tests/check-urw-foundry.sh: ...to these. + * font/devpdf/devpdf.am (font_devpdf_TESTS): Reflect rename. + +2023-02-18 G. Branden Robinson + + [gropdf]: Revise tests to be foundry-focussed. + + * font/devpdf/tests/basic-fonts-present.sh: Stop trying to match + font descriptions in the "devps" directory with ones in + "devpdf"; instead, test whether "BuildFoundries" did its job. + Test for font descriptions corresponding to the full 35 + PostScript Level 2 font repertoire, plus groff's "EURO". + * font/devpdf/tests/urw-fonts-present.sh: Drop stale comment and + rename variable for better parallelism with the other test + above. + + Continues . Thanks to + Deri James for the continued discussion. + +2023-02-18 G. Branden Robinson + + [man]: Tweak fix to Savannah #63768. + + * tmac/an.tmac (MR): Ensure `an*url` always has a value, + defaulting to "format 1" (man:page(section)). Resequence the + macOS URL formats to sort the contemporary one before the + others. + * tmac/man.local: Reflect resequencing of integer assignments to + formats. Clarify historicity of annotations. + + Continues . Thanks to + John Gardner for further discussion. + +2023-02-16 G. Branden Robinson + + [ms]: Port a test to Solaris 11 sed. + + * tmac/tests/s_TC-works-with-percent-in-custom-titles.sh: Put + newlines after opening braces in sed scripts. macOS and GNU sed + tolerate their absence, but this sed does not. + * HACKING: Document this problem. + +2023-02-16 G. Branden Robinson + + * src/roff/groff/groff.am (groff_TESTS) [!USE_GROHTML]: Don't + test the 'grohtml' driver if we know it won't work. + +2023-02-16 G. Branden Robinson + + * src/roff/groff/tests/\ + device_control_escapes_express_basic_latin.sh: Use printf(1), + which is often a shell built-in command, more consistently. + Double backslashes intended as literals in the format string, + and single-quote format strings using them. Fixes test failure + seen on Solaris 11 with GNU Bash 4.4 and ksh 93u+ (2012-08-01). + +2023-02-15 G. Branden Robinson + + * tmac/tests/an_use-input-traps-correctly.sh: Explicitly test + `SM` and `SB` with 'ps' output device. If one set + GROFF_TYPESETTER=utf8 in the test environment, these test cases + would fail. Thanks to John Gardner for the report. + +2023-02-15 G. Branden Robinson + + * configure.ac: Add Automake conditional, `HAVE_GHOSTSCRIPT`, so + that we can populate the list of PDF device font tests + dynamically. Call new macro + `GROFF_GHOSTSCRIPT_AVAILABILITY_NOTICE`. Call + `GROFF_GHOSTSCRIPT_VERSION_NOTICE` after it, but before + `GROFF_URW_FONTS_NOTICE`. + * m4/groff.m4 (GROFF_AWK_NOTICE): New macro produces warning if + no awk could be found. This reduces gropdf functionality, but + so do missing URW fonts, so we report this problem separately. + Report the names under which we sought it, since there's a + configure script option for that. + (GROFF_GHOSTSCRIPT_AVAILABILITY_NOTICE): New macro explains + consequences of missing optional dependency on Ghostscript + program: reduced grohtml functionality, nonfunctional pdfroff. + Report the names under which we sought it, since there's a + configure script option for that. + (GROFF_CHECK_GROPDF_PROGRAMS): Better characterize gropdf's + reduced function, pointing out the ways in which it would be + more useful if the dependencies were met. Also simplify the + computational grammar. + (GROFF_URW_FONTS_NOTICE): Identify 'U' as the foundry name + gropdf uses for the URW fonts. Confirm continuing availability + of most recent URW fonts release; bump date. + * font/devpdf/devpdf.am: Test availability of "basic" (PDF base + 14) fonts (plus groff's "EURO") if either Ghostscript or URW + fonts are available. Test availability of URW fonts (35) only + if Ghostscript _and_ the URW fonts were found at configuration + time. + + Fixes . Thanks to Deri + James for the report and extremely helpful pseudocode. + +2023-02-15 G. Branden Robinson + + * m4/groff.m4 (GROFF_GHOSTSCRIPT_VERSION_CHECK, + GROFF_URW_FONTS_NOTICE): Add macro dependency on + `GROFF_GHOSTSCRIPT_PATH`, which should have been there already. + (GROFF_GROHTML_PROGRAM_NOTICE): Add macro dependency on + `GROFF_CHECK_GROHTML_PROGRAMS`, which should have been there + already. + + (GROFF_CHECK_GROHTML_PROGRAMS, GROFF_PNMTOOLS_CAN_BE_QUIET): + Move `AC_REQUIRE` expansions to precede shell variable + assignments (after checking that the required macros don't + clobber the assignments we're making). + +2023-02-15 G. Branden Robinson + + * font/devpdf/tests/basic-fonts-present.sh: Revise test again, + per feedback from Deri James. Even without Ghostscript or URW + fonts available, gropdf can generate valid PDF documents; it + simply can't embed fonts in general (without further + arrangements made on the host system), which means it is + restricted to the PDF base 14 fonts. That's enough for many + purposes, including generating our compiled man pages document + {with minor degradations to the typeface lists in gropdf(1) and + grops(1)}. Drop the 'gs' command check, which also didn't check + for the name of the Ghostscript interpreter determined by the + "configure" script. Replace dynamically generated font list + with a static one (the base 14 fonts plus groff's EURO). + +2023-02-13 G. Branden Robinson + + * font/devpdf/tests/basic-fonts-present.sh: Revise test. + Improve explanation of why we're looking for the gs(1) command + in a font availability test. Prefix diagnostic output with name + of test script. Perform a search for the 'ps' device font + descriptions that will work in more build scenarios (i.e., don't + assume an out-of-tree build taking place in an immediate + subdirectory of the source). Distinguish failure to find the + font descriptions from a failure to locate the 'gs' command, + skipping the test in both scenarios. Reduce noise in output. + * m4/groff.m4 (GROFF_CHECK_GROPDF_PROGRAMS): Revise warning + issued when awk and Ghostscript are unavailable; gropdf will not + be completely inoperative. Characterize its reduced function. + + Thanks to Deri James in for prompting me to take a + another look at this. + +2023-02-13 G. Branden Robinson + + * tmac/tests/latin2_works.sh: + * tmac/tests/latin5_works.sh: + * tmac/tests/latin9_works.sh: Port to work around macOS's + apparently POSIX non-conforming 'od' command. Use single-byte + octal output format instead of "character", and update test + expectations accordingly. Apparently gratuitously, macOS also + puts more spaces after the octal address field when using this + output format. + * HACKING: Document, and elaborate upon, this problem. + +2023-02-13 G. Branden Robinson + + [mdoc]: Port a test to work with macOS sed. + + * tmac/tests/doc_heading-font-remapping-works.sh: Put semicolons + between commands and closing braces in sed script. Put each of + multiple closing braces on a separate input line, because macOS + doesn't accept them otherwise. Resolves test failure observed + on macOS. + * HACKING: Document the closing brace sequence problem. + +2023-02-13 G. Branden Robinson + + [man]: Port a test to work with macOS sed. + + * tmac/tests/an_TS-adds-no-vertical-space.sh: Put semicolons + between commands and closing braces in sed script. Separate + command stream into multiple '-e' expressions, breaking them + after branch and label commands. Resolves test failure observed + on macOS. + * HACKING: Document the above problems. + +2023-02-13 G. Branden Robinson + + * src/roff/groff/tests/\ + some_escapes_accept_newline_delimiters.sh: Weaken regexes in two + test cases to accommodate excessive output from macOS's 'od' + command. Resolves test failure seen on macOS. + * HACKING: Add section "Writing Tests" and document the above + since this is the second time I've cracked my shin on this. + +2023-02-13 G. Branden Robinson + + * font/devpdf/tests/basic-fonts-present.sh: Skip test if 'gs' + command not available. The test is to ensure that gropdf will + produce sound documents using the base fonts from PostScript, + but since gropdf requires Ghostscript to do this (as noted in + our "./configure" messages), it makes no sense to validate font + availability if the program is absent. Resolves test failure + seen on macOS with minimal dependencies installed. + +2023-02-12 G. Branden Robinson + + * doc/groff.texi (Manipulating Filling and Adjustment): Say more + about the consequences of a break. + + Fixes . Thanks to Dave + Kemper for the report. + +2023-02-12 G. Branden Robinson + + [docs]: Re-re-christen 'ESCAPE_AMPERSAND' ('\&'). Now call it a + {non-transparent} "dummy character". Also rechristen + 'ESCAPE_RIGHT_PARENTHESIS', ('\)') as the "transparent dummy + character"; it has no impact on sentence-ending detection. + + * doc/groff.texi: + * doc/meref.me.in: + * man/groff.7.man: + * man/groff_diff.7.man: + * man/roff.7.man: + * src/preproc/refer/refer.1.man: + * tmac/groff_man.7.man.in: Do it. + + Fixes . Thanks to Dave + Kemper for the report and to the groff mailing list for the + vigorous discussion. I don't expect my solution to please + everyone. + +2023-02-11 G. Branden Robinson + + * tmac/an.tmac: Add internal register `an*MR-URL-format` to + select from a few known formats of man page hyperlink. There + are three known on macOS, and one used everywhere else. + * tmac/man.local: Document this feature so macOS users can enjoy + the OSC 8 hyperlink feature if their terminal application + supports it. + + I hope that this feature will be a temporary measure while macOS + implements support for the man page URL format used everywhere + else in the world. + + Fixes . Thanks to John + Gardner for the report, research, consultation, and testing. + +2023-02-11 Deri James + + [BuildFoundries]: Fails if neither ghostcript nor URW fonts + are installed. + + * font/devpdf/util/BuildFoundries.pl: When the change to hold + paths in an array, rather than a delimited string (see commit + 4ae4aeb6555f4f16c28fcb03eb1f56577826054c), the FindGSpath + subroutine should return a pointer to an empty array when the + call to ghostscript fails, rather than return an empty string, + as was done previously. + + See ; thanks to Bruno Haible for the report. + +2023-02-09 G. Branden Robinson + + Switch to using system's assert.h header file. It is futile to + attempt to preserve compatibility with ISO C90 systems by + providing a bespoke predicate-reporting assert() (a C99 feature) + when gnulib, which we require, itself demands C99. This ensures + that `static_assert` remains defined so that gnulib can use it. + Thanks to Bruno Haible for the consultation. + + + * src/include/assert.h: Delete. + + * src/devices/grodvi/dvi.cpp: + * src/devices/grolbp/lbp.cpp: + * src/devices/grolj4/lj4.cpp: + * src/include/itable.h: + * src/include/stringclass.h: + * src/libs/libbib/linear.cpp: + * src/libs/libbib/search.cpp: + * src/libs/libdriver/printer.cpp: + * src/libs/libgroff/assert.cpp: + * src/libs/libgroff/color.cpp: + * src/libs/libgroff/errarg.cpp: + * src/libs/libgroff/font.cpp: + * src/libs/libgroff/nametoindex.cpp: + * src/libs/libgroff/prime.cpp: + * src/libs/libgroff/relocate.cpp: + * src/libs/libgroff/searchpath.cpp: + * src/preproc/eqn/box.cpp: + * src/preproc/eqn/delim.cpp: + * src/preproc/eqn/pile.cpp: + * src/preproc/eqn/script.cpp: + * src/preproc/html/pre-html.cpp: + * src/preproc/pic/pic.h: + * src/preproc/preconv/preconv.cpp: + * src/preproc/soelim/soelim.cpp: + * src/roff/groff/groff.cpp: + * src/roff/troff/troff.h: + * src/utils/hpftodit/hpftodit.cpp: + * src/utils/indxbib/indxbib.cpp: + * src/utils/lkbib/lkbib.cpp: + * src/utils/lookbib/lookbib.cpp: + * src/utils/tfmtodit/tfmtodit.cpp: Respell "assert.h" inclusion + with angle brackets instead of quotation marks. + + Fixes . + +2023-02-09 G. Branden Robinson + + * src/roff/troff/input.cpp (token::next): Use correct kind of + null object in comparison. Fixes latent bug that would be + exposed if we were to migrate from zero literals to `nullptr`. + +2023-02-09 Deri James + + [gropdf] Parse multiple entries in 'papersize' as specified in + the groff_font man page. Reported by Ben Wong and fix based on + his patch, thanks. + + * src/devices/gropdf/gropdf.pl: Parse papersize string for + possible multiple (space separated) entries. First valid entry + wins. + + Fixes https://savannah.gnu.org/bugs/?63757 + +2023-02-04 G. Branden Robinson + + Correct numerous typos and solecisms throughout the source tree. + + * ChangeLog: + * ChangeLog.115: + * ChangeLog.116: + * ChangeLog.117: + * ChangeLog.118: + * ChangeLog.119: + * ChangeLog.121: + * ChangeLog.122: + * Makefile.am: + * NEWS: + * PROBLEMS: + * README: + * contrib/chem/chem.am: + * contrib/chem/chem.pl: + * contrib/glilypond/README.txt: + * contrib/glilypond/glilypond.pl: + * contrib/hdtbl/groff_hdtbl.7.man: + * contrib/mm/ChangeLog: + * contrib/mm/m.tmac: + * contrib/pdfmark/pdfmark.ms: + * doc/automake.mom: + * doc/groff.texi: + * doc/me-revisions: + * doc/webpage.ms: + * m4/lib-link.m4: + * man/groff.7.man: + * man/groff_diff.7.man: + * man/roff.7.man: + * src/devices/grohtml/post-html.cpp: + * src/devices/grolbp/lbp.h: + * src/devices/gropdf/TODO: + * src/devices/gropdf/gropdf.1.man: + * src/devices/gropdf/gropdf.pl: + * src/devices/xditview/ChangeLog: + * src/devices/xditview/xditview.c: + * src/libs/libdriver/input.cpp: + * src/libs/libgroff/glyphuni.cpp: + * src/preproc/eqn/eqn.1.man: + * src/preproc/grn/gprint.h: + * src/preproc/grn/main.cpp: + * src/preproc/html/pre-html.cpp: + * src/preproc/preconv/preconv.cpp: + * src/preproc/tbl/table.cpp: + * src/roff/groff/pipeline.c: + * src/roff/groff/tests/substring_works.sh: + * src/roff/groff/tests/ + use_point_size_escape_with_single_digit_arg.sh: + * src/roff/troff/div.cpp: + * src/roff/troff/input.cpp: + * src/roff/troff/troff.1.man: + * src/utils/grog/grog.pl: + * src/utils/indxbib/indxbib.cpp: + * src/utils/tfmtodit/tfmtodit.1.man: + * tmac/doc-old.tmac: + * tmac/doc.tmac: + * tmac/groff_man.7.man.in: + * tmac/hyphen.fr: Do it. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2023-02-04 G. Branden Robinson + + [tbl]: Drop XFAIL test. It was written with an unclear + understanding of how DWB (AT&T) and Heirloom Doctools troff + behaved. The individual checks might come back, modified. + + * src/preproc/tbl/tests/table-lacks-spurious-top-border.sh: + Delete. + + * src/preproc/tbl/tbl.am (tbl_TESTS): Drop it. + (tbl_XFAIL_TESTS, XFAIL_TESTS): Drop now empty assignment and + unnecessary update, respectively. + +2023-02-04 Bertrand Garrigues + + Update gnulib submodule + + gnulib now points on sha1 4e9fcc7b84fcac07a3e5a3cd5f66d1ff320dc8e8 + +2023-02-03 G. Branden Robinson + + [tbl]: Fix bugs using boxes or vertical rules at table edges on + nroff devices, particularly when combined with region or column + expansion. + + * src/preproc/tbl/table.h (class table): Add `GAP_EXPAND` + enumeration constant. James Clark seems to have designed GNU + tbl carefully to avoid distinguishing region expansion from + column expansion in a categorical way, but I needed a way for + formatting-time logic to know which was in use. (Column + expansion, the "x" modifier, expands columns--i.e., text. + Region expansion expands [or compresses] the _gaps_ between + columns.) + * src/preproc/tbl/main.cpp (process_options): Set `GAP_EXPAND` + flag in table if "expand" region option seen. + * src/preproc/tbl/table.cpp: Add new macro `LEFTOVER_FACTOR_REG` + to name a new roff register for the remainder of gap-expansion + space when the amount of space available for expansion is + divided by the number of gaps. + (table::compute_overall_width): If _not_ expanding a table in + either respect and in nroff mode, reduce line length by 1n for + each of any left and right border (because the vertical lines + eat character cells). This prevents bordered or boxed tables + from being overset even when they use neither expansion feature. + (table::compute_separation_factor): If gap-expanding a table, + store any remainder from the division used to compute the + separation factor into the new `LEFTOVER_FACTOR_REG`. + (table::compute_column_positions): Insert that remainder into + the gap before the last (rightmost) column of the table. This + _could_ be done more elegantly by spreading each en in a + symmetric way across a subset of the gaps. (It is necessarily a + subset by the pigeonhole principle.) But it didn't seem worth + the effort for a feature (region expansion) that few users + employ. (Usually what you want is the "x" column modifier.) + Alternatively, "forget it, Jake--it's a terminal emulator". + + * src/preproc/tbl/tbl.am (tbl_XFAIL_TESTS): Remove now-passing + tests. + + Fixes and + . + +2023-02-03 G. Branden Robinson + + * src/preproc/tbl/table.cpp (table::compute_column_positions): + Stop multiplying the gaps at the left and right edges of a table + {which occur when it is boxed or has a leading and/or trailing + vertical line} by the column separation factor. Only interior + column gaps should be spread. This change prevents tables using + the "expand" region option from being overset (exceeding the + line length), but might not (yet) fully expand to that length on + low-resolution devices due to integer roundoff. + +2023-02-03 G. Branden Robinson + + * src/preproc/tbl/table.cpp (table::compute_total_separation) + (table::compute_separation_factor, table::compute_widths): Add + comments to generated roff output to assist the mystified user. + +2023-02-03 G. Branden Robinson + + [tbl]: Refactor. + + * src/preproc/tbl/table.cpp: + * src/preproc/tbl/table.h: Rename `compute_expand_width` to + `compute_overall_width`, since this member function is used on + _all_ tables, not just those undergoing column or gap expansion. + For instance, in a post-groff 1.22.4 development, it throws a + diagnostic if an unexpanded table overruns the line length. + * src/preproc/tbl/table.cpp (table::compute_widths): Update call + site of `compute_overall_width`. + * src/preproc/tbl/table.cpp: Split the roff register behind the + `EXPAND_REG` C++ preprocessor macro into two, adding + `AVAILABLE_WIDTH_REG`. Annotate the distinction. + (compute_overall_width): Annotate. Move and conditionalize + logic so as not to produce as much unnecessary roff output. + +2023-02-03 G. Branden Robinson + + * src/preproc/tbl/main.cpp (main): Avoid reading from invalid + memory upon failure to open an input file. + + Fixes . + +2023-02-03 G. Branden Robinson + + * src/preproc/eqn/lex.cpp (get_delimited_text): Avoid reading + from invalid memory when throwing diagnostic. Duplicate + `filename` string, then free it on all paths out of function. + + Fixes . + +2023-02-03 G. Branden Robinson + + [tbl]: Add more tests. + + * src/preproc/tbl/tests/boxes-and-vertical-rules.sh: + * src/preproc/tbl/tests/expand-region-option-works.sh: + * src/preproc/tbl/tests/x-column-modifier-works.sh: Do it. + + * src/preproc/tbl/tbl.am (tbl_TESTS): Run tests. + (tbl_XFAIL_TESTS): Add; future changes will resolve these. + +2023-02-02 G. Branden Robinson + + * src/preproc/tbl/table.cpp (table::compute_column_positions): + If a table has "left separation" (it is boxed, or has a vertical + rule on the left-hand side), increase the first column's start + register value by 1n, for symmetry with the right-hand size. + + * src/preproc/tbl/tests/check-horizontal-line-length.sh: + * src/preproc/tbl/tests/check-line-intersections.sh: + * src/preproc/tbl/tests/check-vertical-line-length.sh: Update + output expectations. + + * src/preproc/tbl/tbl.am (tbl_XFAIL_TESTS): Remove now-passing + test. + + See for background. + +2023-02-02 G. Branden Robinson + + * src/preproc/tbl/table.cpp (table::compute_total_separation): + Trivially refactor; rename loop indices so it's obvious which + dimension of a matrix they're referring to. + +2023-02-02 G. Branden Robinson + + * src/preproc/tbl/table.cpp (table::determine_row_type) + (table::compute_widths, table::do_row): Boolify some local ints. + +2023-02-02 G. Branden Robinson + + [tbl]: Refactor handling of vertical lines in format. Validate + input more strictly. Add diagnostics when vertical lines are + redundant with box borders. + + * src/preproc/tbl/main.cpp (process_format): Shift diagnostic + about excess vertical lines in a sequence at the beginning of a + row description to later, after the first proper column + descriptor has been interpreted. Normalize a sequence of more + than two consecutive vertical lines to 2 when they occur at the + beginning of a row description. Unconditionally update + `list->vline` and reset `vline_count` once we start looking for + modifiers, since we know we've finished any sequence of vertical + lines, and at the end of a row definition. Rename and retype + loop variable int `success` to Boolean + `is_valid_modifier_sequence`. Drop now-invalid assertion. + * src/preproc/tbl/table.cpp (table::add_vlines): Throw new + diagnostics when vertical lines are redundant with box borders. + Add assertion to ensure we got a valid vertical line value (0, + 1, or 2) from `process_format`. Throw these only once per table + format, not for every row. + +2023-01-30 G. Branden Robinson + + * src/preproc/tbl/main.cpp (process_table): Trivially refactor. + Rename `form` to `fmt` to imply "format", not "form". + +2023-01-30 G. Branden Robinson + + * src/preproc/tbl/main.cpp (process_format): Throw error + diagnostic if more than 2 vertical lines are specified at the + beginning of a row definition. + + Fixes . + +2023-01-30 G. Branden Robinson + + * src/preproc/tbl/main.cpp (process_format): Recast diagnostic + message to refer to character by its Unicode name and generalize + to accurately cover additional circumstance of excess '|' + symbols at end of row definition. + +2023-01-29 G. Branden Robinson + + * doc/ms.ms: Remove redundant initializations. + +2023-01-29 G. Branden Robinson + + * doc/ms.ms: Define appropriate hyphen-minus mapping on 'cp1047' + output device. + +2023-01-26 G. Branden Robinson + + * tmac/s.tmac (TE): Enable no-space mode after outputting the + display distance vertically, replacing any inter-paragraph + distance that might follow. + +2023-01-24 G. Branden Robinson + + [grohtml]: Fix misleading diagnostic message. + + * src/preproc/html/pre-html.cpp (main): The suggestion should be + to re-run the formatter (groff, troff), not "pre-grohtml", with + a different output driver since the document may be malformed. + +2023-01-11 G. Branden Robinson + + * src/preproc/tbl/main.cpp (process_format): Fix code hygiene + nit: nullify `list` pointer after freeing its target. + +2023-01-11 G. Branden Robinson + + [tbl]: Really fix Savannah #63449. + + * src/preproc/tbl/main.cpp (process_format): "Or" on the + `HAS_TOP_VLINE` flag if the format specification begins with a + "|"; the beginning is a separate state in the FSM used to parse + the description. I missed it in commit 0e93ab4102, 1 December. + + Fixes . + +2023-01-10 G. Branden Robinson + + * src/preproc/tbl/tests/\ + do-not-overdraw-page-top-in-nroff-mode.sh: Correct erroneous + check of test output, and add two more test cases. + +2023-01-08 G. Branden Robinson + + * tmac/an-ext.tmac: Move the saving of the hyphenation mode from + the "top level" to... + (mY): ...this new macro. + (SY, mQ, MR): Call `mY` before disabling hyphenation. + + Problem introduced by me in commit 096c2f0567, 16 February. + "an-ext.tmac" gets sourced by "an.tmac" before any + command-line setting of the `HY` register is handled, so (for + groff) the stored hyphenation mode was the default for the + language, not reflecting user disablement. The synopsis macros, + which do not have an alternate implementation in "an.tmac" for + leverage of groff features, were causing hyphenation to be + resurrected (after `YS`) even if the user had disabled it. + Saving the hyphenation mode anew upon entry to these macros is + arguably inefficient, but it is more correct since a man page + could conceivably manipulate the automatic hyphenation mode + {even if that's not recommended outside of tbl(1) text blocks}. + +2023-01-08 G. Branden Robinson + + [man]: Add regression test for hyphenation getting wrongly + restored by `YS`, `ME`, `UE`, and `MR` macros. + + * tmac/tests/an_HY-register-works.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2023-01-03 G. Branden Robinson + + * tmac/mdoc/doc-common (Sh, Ss): Narrow scope of font remappings + lexically and restrict remapping to the heading font family (if + any) to avoid undesired remapping of fonts in page headers if, + say, a (sub)section heading begins just prior to a page + break--which is ugly anyway and should be avoided, but the + package has no keep macros and solving that problem in an + automatic way promises to be complex. + +2023-01-03 G. Branden Robinson + + * tmac/an.tmac (MT, UR): Throw style warning if macro called + without (exactly one) argument. + +2022-12-27 G. Branden Robinson + + * doc/doc.am (doc/groff-man-pages.pdf): Set (sub)section + headings in Helvetica bold in compiled man pages, as a test and + demonstration of the `HF` feature's application to both man(7) + and mdoc(7) documents. + +2022-12-27 G. Branden Robinson + + [mdoc]: Support `HF` string. + + * tmac/doc.tmac (initialization): Add logic supporting `HF` + string just as our man(7) implementation does. If the font name + ends with `B` (as the default does), set + `doc-remap-I-style-in-headings` register and extract font + family, which can be empty (as is the default). + * tmac/mdoc/doc-common (Sh, Ss): If + `doc-remap-I-style-in-headings` register set, perform (and + unwind) font remapping of italic to bold-italic face. + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: Define `doc-Sh-font` in terms of `HF`. + + * tmac/tests/doc_heading-font-remapping-works.sh: Test it. + * tmac/tmac.am (tmac_TESTS): Run test. + + * tmac/groff_mdoc.7.man (Options): Document it. + * NEWS: Update item. + + Fixes last part of . + +2022-12-26 G. Branden Robinson + + [tmac]: Revise "fallback" character definitions in several + respects for Unicode characters from General Punctuation block. + + * tmac/fallbacks.tmac: Comment out fallbacks for U+200B, U+2010, + U+2011, and U+201[89CD], due to ineffectuality or apparent groff + bugs. Redefine U+2012 fallback to include hair space (\^) + around synthetic figure dash. Redefine U+2016 to use `\[ba]` + special characters instead of ordinary `|` characters to dodge + possible character translations by user. + + Fixes part of . Thanks to + Dave Kemper for the (multifarious) discussion. + +2022-12-25 G. Branden Robinson + + * doc/groff.texi (Invoking groff, Built-in Registers): + * man/groff.7.man (Writable predefined registers): + * src/roff/groff/groff.1.man (Environment): + * src/roff/troff/troff.1.man (Environment): Replace erroneous + reference to ctime(3) with localtime(3). + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2022-12-19 G. Branden Robinson + + [tests]: Fix potential problem(s) in trap handler. + + * src/roff/groff/tests/smoke-test_html_device.sh: Move call of + `cleanup` function from end of script to after the tests that + generate temporary files have been run, and before script + possibly exits with status 77 to skip some checks. Within trap + handler, mask trapped signals while running handler. + (cleanup): Reset trap dispositions to default after removing + files; once the temporary files are gone, we no longer need a + trap handler. One might already be running however, and this + ensures that its "suicide" ("kill -s INT $$") will succeed. + +2022-12-18 G. Branden Robinson + + [mdoc]: Support `FT` register. + + * tmac/doc.tmac (initialization): Add logic supporting `FT` + register just as our man(7) implementation does. + * tmac/mdoc/doc-common (doc-set-up-titles): Plant footer trap in + validated user-requested location. + * tmac/groff_mdoc.7.man (Options): Document it. + * NEWS: Update item. + + Fixes part of . + +2022-12-18 G. Branden Robinson + + * tmac/an.tmac: Fix code style nit: use `as` requests to + avoid overlong input lines. + +2022-12-17 G. Branden Robinson + + * tmac/doc.tmac: Inform user we're ignoring their "-rD1" setting + if also formatting HTML; parallels groff man(7) behavior. + +2022-12-17 G. Branden Robinson + + * tmac/doc.tmac: Trivially refactor. Relocate handling of `D` + command-line register to prepare for greater synchronization + with groff man(7). + +2022-12-17 G. Branden Robinson + + * src/preproc/tbl/table.cpp: Trivially refactor. Rename + {portion of} internal register to include an interword hyphen + for readability. + +2022-12-16 G. Branden Robinson + + [ms]: Change default line length to 6.5 inches. + + * tmac/s.tmac (par@load-init): Do it. + + * doc/groff.texi (ms Document Control Settings): + * doc/ms.ms (Document control settings): + * tmac/groff_ms.7.man (Document control settings): Document it. + + * tmac/tests/s_honor-MINGW-when-two-columns.sh: + * tmac/tests/s_mark-column-start-correctly.sh: Update test + expectations. + + * NEWS: Add item. + +2022-12-15 G. Branden Robinson + + * tmac/an.tmac (TH): Relocate `an-break-body-text` trap to be + one half-inch above footer (instead of twice the footer + distance). I reason that anyone who customizes `FT` is doing so + to overprint some kind of material at the bottoms of pages, or + simply to make the margin larger. (One then wonders why we + don't have an `HD` register for the top.) Also remove register + when done with it. + * tmac/groff_man.7.man.in (Options) : Document this. + +2022-12-15 G. Branden Robinson + + * tmac/an.tmac (TH): Trivially refactor. Rename + `an-footer-location` to `an*footer-location` and set page traps + in order descending the page. + +2022-12-11 G. Branden Robinson + + [mdoc]: Support `X` register. + + * tmac/doc.tmac (initialization): Add logic supporting `X` + register just as our man(7) implementation does. + * tmac/groff_mdoc.7.man (Options): Document it. + * NEWS: Update item. + + Fixes part of . + +2022-12-15 G. Branden Robinson + + [mdoc]: Add unit test for `X` register. + + * tmac/tests/doc_X-register-works.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-12-15 G. Branden Robinson + + * tmac/doc.tmac (Nm): Fix `if` -> `ie` typo/thinko. + + Fixes . Thanks to John + Gardner for the report. + +2022-12-15 G. Branden Robinson + + * tmac/tests/doc_Nm-works.sh: Add more checks. + +2022-12-13 G. Branden Robinson + + * src/roff/groff/tests/smoke-test_html_device.sh: Add checks for + inlining of images when tbl(1) or eqn(1) used. + +2022-12-12 G. Branden Robinson + + * tmac/andoc.tmac (reload-man): Unplant `doc-break-body-text` + trap, added in commit 892703b17e, 6 September. Its survival + into man(7) pages didn't seem to cause any problems but I have + no confidence that will remain true forever. + +2022-12-12 G. Branden Robinson + + * tmac/an.tmac (initialization): Fix problem with `FT` register + validation. Small but valid values were being rejected due to + inappropriate use of scaling operator. Also throw user a bone + by expressing what size '1v' is for the output device, in basic + units. + +2022-12-12 G. Branden Robinson + + [man, mdoc]: Fix Savannah #63500. Support use of `P` (initial + page number) register when batch rendering, regardless of + switching macro packages between man(7) and mdoc(7) or setting + of `C` (continuous numbering) register. (`P` without `C` means + "start numbering each rendered document at \n[P]".) + + * tmac/an.tmac (an-end): Call `an*break-page-with-new-number` + instead of invoking `bp`. + (an*break-page-with-new-number): If `P` is set and `C` is not, + use value of `P` as the next page number. + (TH): If `C` register is set, remove `P` register after ending a + previous document. + (initialization): If `P` is set, assign the page number using + the `pn` request if the transition to the first formatted page + has not yet occurred; otherwise update page number register `%` + directly. Also ignore it with diagnostic if `ps4html` register + {for grohtml's internal use} is set. Add explanatory comment. + + * tmac/mdoc/doc-common (Dd): If `C` register is set, remove `P` + register after ending a previous document. + (doc-end-macro): Call `doc-break-page-with-new-number` instead + of invoking `bp`. + (doc-break-page-with-new-number): If `P` is set and `C` is not, + use value of `P` as the next page number. + * tmac/doc.tmac (initialization): If `P` is set, assign the page + number using the `pn` request if the transition to the first + formatted page has not yet occurred; otherwise update page + number register `%` directly. Also ignore it with diagnostic if + `ps4html` register (for grohtml's internal use) is set. Add + explanatory comment. + + Fixes . + +2022-12-11 G. Branden Robinson + + [mdoc]: Support `P` register. + + * tmac/doc.tmac (initialization): Add logic supporting `P` + register just as our man(7) implementation does. + * tmac/groff_mdoc.7.man (Formatting with groff, troff, and + nroff): Document it. + * NEWS: Update item. + + Fixes part of . + +2022-12-11 G. Branden Robinson + + [tests]: Add unit tests for man/mdoc `P` register. + + * tmac/tests/an_P-register-works.sh: + * tmac/tests/andoc_P-register-works.sh: + * tmac/tests/doc_P-register-works.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run tests. + +2022-12-11 G. Branden Robinson + + [man, mdoc]: Refactor. Rename a Boolean register to more + clearly communicate its purpose. This also reverses its sense. + + * tmac/an.tmac (TH): Rename `an-is-first-page-of-document` to + `an*need-titles-reset`. Drop redundant store. Reverse sense of + test. + (initialization): Initialize it to zero. + + * tmac/mdoc/doc-common (Dd): Rename + `doc-is-first-page-of-document` to `doc-need-titles-reset`. + Drop redundant store. Reverse sense of test. + (initialization): Initialize it to zero. + +2022-12-11 G. Branden Robinson + + [tests]: Add future regression test for header/footer + mishandling that wasn't already covered (not a live bug; was + exposed by attempted refactoring). + + * tmac/tests/andoc_check-an-to-doc-transition.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-12-11 G. Branden Robinson + + [man, mdoc]: Trivially refactor. + + * tmac/an.tmac (an-start-new-document): Rename this... + (an*break-page-with-new-number): ...to reflect its reduced + responsibility. + + * tmac/mdoc/doc-common (doc-start-new-document): Rename this... + (doc-break-page-with-new-number): ...to reflect its reduced + responsibility. + +2022-12-11 G. Branden Robinson + + [man, mdoc]: Refactor to separate page number management from + header trap management. + + * tmac/an.tmac (an-start-new-document): Stop removing + `an-header` trap. + (TH): Clear the trap here even if not continuously rendering, + and call `an-start-new-document`. + + * tmac/mdoc/doc-common (doc-start-new-document): Stop removing + `doc-header` trap. + (Dd): Clear the trap here even if not continuously rendering, + and call `doc-start-new-document`. + +2022-12-11 G. Branden Robinson + + * tmac/mdoc/doc-common: Refactor for better parallelism with our + man(7) implementation and to prepare for a synchronized change + to both. + (Dd): Move open-coded (inlined) operations from here... + (doc-start-new-document): ...to this new macro. + (doc-end-macro): Drop unnecessary register assignment. `Dd` + takes care of it if there is a subsequent mdoc(7) document. + +2022-12-07 G. Branden Robinson + + [tbl]: Fix off-by-one error in generated diagnostic message. + + * src/preproc/tbl/table.cpp: Define new preprocessor macro, + `PREVIOUS_PAGE_REG`. + (table::init_output): Compute value for register named using + `PREVIOUS_PAGE_REG`, use it in diagnostic, and then remove it. + Also fix verb tense in message. + +2022-12-07 G. Branden Robinson + + [tbl]: Expose the fact of a table's boxedness via a troff + register so that macro packages can make more intelligent + decisions about space requirements (since box borders occupy + significant space on nroff devices). + + * src/preproc/tbl/table.cpp: Define new preprocessor macro, + `IS_BOXED_REG`. + (table::do_top): Initialize "boxedness" register. + +2022-12-07 G. Branden Robinson + + * tmac/s.tmac (TH): Clarify computation and diagnostic message. + +2022-12-07 G. Branden Robinson + + [tbl]: Fix Savannah #61878. + + * src/preproc/tbl/table.cpp: Define new preprocessor macro, + `STARTING_PAGE_REG`. + (table::define_bottom_macro): Have the formatter issue a warning + if an unkept, boxed table ends on a different page than it + began. + (table::do_top): Save current page number when table begins. + + Fixes . + +2022-12-07 G. Branden Robinson + + [tbl]: Regression-test Savannah #61878. + + * src/preproc/tbl/tests/\ + warn-on-long-boxed-unkept-table.sh: Do it. + * src/preproc/tbl/tbl.am (tbl_TESTS): Run test. + +2022-12-06 G. Branden Robinson + + * src/preproc/tbl/table.cpp: Write comments to generated output; + these correspond to functions in this file and to major + operations of table construction. + (init_output, compute_widths, define_bottom_macro, do_row) + (do_top, do_bottom): Do it. + +2022-12-05 G. Branden Robinson + + [troff]: Trivially refactor. Rename class `constant_int_reg` to + `readonly_register`. Say "readonly" instead of "const" to + try to avoid confusion with C++ constness. Drop "int" because + integer-valued registers are the norm, not the exception. + + * src/roff/troff/column.cpp (init_column_requests): + * src/roff/troff/div.cpp (init_div_requests): + * src/roff/troff/input.cpp (top level, init_input_requests): + * src/roff/troff/node.cpp (init_node_requests): + * src/roff/troff/reg.h: Do it. + +2022-12-05 G. Branden Robinson + + [troff]: Trivially refactor. Rename class `constant_reg` to + `readonly_text_register`. Say "readonly" instead of "const" to + try to avoid confusion with C++ constness. Say "text" because + this class is _mostly_ used for interpolation of string-valued + registers like the version registers `.x`, `.y` and `.Y`. + Nevertheless there are some abuses (apparently because the + constructors for register classes don't accept integer + parameters for initialization--why?). + + * src/roff/troff/input.cpp (top level) + (readonly_text_register::readonly_text_register) + (readonly_text_register::get_string) + (main, init_registers, init_requests): Do it. + +2022-12-05 G. Branden Robinson + + [troff]: Trivially refactor. Rename `number_reg_dictionary` to + `register_dictionary`. It's shorter _and_ non-abbreviated _and_ + matches our documentation. + + * src/roff/troff/column.cpp (init_column_requests): + * src/roff/troff/div.cpp (page_number, init_div_requests): + * src/roff/troff/env.cpp (print_env, init_env_requests) + (init_hyphen_requests): + * src/roff/troff/input.cpp (length_request) + (interpolate_number_format, do_register, do_if_request, main) + (init_registers, init_input_requests): + * src/roff/troff/node.cpp (get_register, init_node_requests): + * src/roff/troff/reg.cpp (top level, define_number_reg) + (inline_define_reg, alter_format, remove_reg, alias_reg) + (rename_reg, print_number_regs): + * src/roff/troff/reg.h: Do it. + +2022-12-04 G. Branden Robinson + + [man]: Add regression test. + + * tmac/tests/an_link-trailing-text-hugs-previous.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-12-03 G. Branden Robinson + + * tmac/fallbacks.tmac: Really use troff-mode fallbacks only on + typesetting devices; because this macro file is loaded so early, + we cannot rely on ".if t". Thanks to Dave Kemper for the + discussion in Savannah #63354. + +2022-12-03 G. Branden Robinson + + * tmac/an-ext.tmac: Use more mnemonic register names, thanks to + the recent freeing up of some name space. + - mJ -> mH: saved automatic hyphenation mode + - mX -> mE: formatting in EX/EE context (Boolean) + +2022-12-03 G. Branden Robinson + + * tmac/pdf.tmac: Drop deletion of unused string `PDFHREF.TEXT`. + +2022-12-03 G. Branden Robinson + + * tmac/an.tmac (an-end, AT, UC, DT, PD, SH, IP, BI, BR, IB, IR) + (RB, RI, OP, an*end-hyperlink, MR): Refactor; "nop"ify macros + that produce formatted output or call other macros using string + interpolations--except where we can't: see Savannah #63470. + +2022-12-03 G. Branden Robinson + + * tmac/an.tmac (R): Drop macro definition, which implements a + hack for people who try to use "R" as a font style macro. This + doesn't seem to happen much in actual practice (though perhaps + the diagnostic this hack produces is responsible for suppression + of the mistake). Retaining it interferes with the + "nop"-ification of this macro file. + * NEWS: Add item. + +2022-12-03 G. Branden Robinson + + * tmac/an-ext.tmac: Use truly traditional hyphenation mode on + non-groff-compatible formatters. + +2022-12-03 G. Branden Robinson + + [man]: Update test coverage and expectations. + + * tmac/tests/an_ME-punct-hyphenates.sh: Test both "an.tmac" and + "an-ext.tmac" implementations of `ME`. + * tmac/tests/an_UE-punct-hyphenates.sh: Test both "an.tmac" and + "an-ext.tmac" implementations of `UE`. + * tmac/tests/an_UE-breaks-before-long-URIs.sh: Update test + expectations. I appear to have inadvertently fixed some + inelegant rendering. + +2022-12-02 G. Branden Robinson + + [tests]: Rename to reflect code reorganization. + + * tmac/tests/an-ext_ME-punct-hyphenates.sh: + * tmac/tests/an-ext_MT-body-hyphenates.sh: + * tmac/tests/an-ext_UE-breaks-before-long-URIs.sh: + * tmac/tests/an-ext_UE-punct-hyphenates.sh: + * tmac/tests/an-ext_UR-body-hyphenates.sh: Rename these... + * tmac/tests/an_ME-punct-hyphenates.sh: + * tmac/tests/an_MT-body-hyphenates.sh: + * tmac/tests/an_UE-breaks-before-long-URIs.sh: + * tmac/tests/an_UE-punct-hyphenates.sh: + * tmac/tests/an_UR-body-hyphenates.sh: ...to these. + + * tmac/tmac.am (tmac_TESTS): Reflect renames. + +2022-12-02 G. Branden Robinson + + * tmac/an-ext.tmac: Remove groff-feature-dependent code for + hyperlink management, greatly reducing the size of the file, + which we permissively license and encourage people to copy + around. Drop register definitions corresponding to + groff-specific output device names. Drop definition and use of + `mL` and `mR` strings for angle brackets; no observable change + on non-groff formatters. Recognize `mG` register to enable + testing of these macros even if the formatter is groff. + (mV): Radically simplify. This internal "back-end" for `MT` and + `UR` now just stores its argument in a string, `m1`. + (mQ): Radically simplify. This internal "back-end" for `ME` and + `UE` now just disables automatic hyphenation, formats the saved + `m1` string between angle brackets, suffixes it with the + optional argument, and restores automatic hyphenation. + (UR, MT): Call `mV` with one argument, not nine. + (UE, ME): Call `mQ` with one argument, not nine. + + * tmac/tests/an-ext_MR-works.sh: Add test of this file's + simplified `MR` implementation. + * tmac/tests/an-ext_MT-works.sh: + * tmac/tests/an-ext_UR-works.sh: Move tests of groff-specific + hyperlink output from here... + * tmac/tests/an_MT-works.sh: + * tmac/tests/an_UR-works.sh: ...to these new files. + * tmac/tests/an_MR-works.sh: + * tmac/tests/an_MT-works.sh: + * tmac/tests/an_UR-works.sh: Add tests for valid HTML formatting + of hyperlinks, which experience shows is a bit fragile in the + face of diversion manipulation and output line continuation. + + * tmac/tmac.am (tmac_TESTS): Run new tests. + +2022-12-02 G. Branden Robinson + + * tmac/an-ext.tmac: Support `mG` register: clear it to force the + loading of this file's macros even if they have an + implementation in tmac/an.tmac and the formatter claims groff + compatibility. This is to ease these macros' testing under + groff and keep the implementations here simple. + * tmac/an.tmac: Initialize `mG` register to 1 if not set on + command line. + +2022-12-02 G. Branden Robinson + + * tmac/an-ext.tmac: Initialize `mX` register. + +2022-12-02 G. Branden Robinson + + * tmac/an-ext.tmac: Define `mC` string (constant-width typeface + used by `EX`/`EE` macros) as `R` in nroff mode. Thanks to + Russ Allbery for prompting me to think more about the + limitations of Solaris troff. Implementations do varying + things with the "previous" font restored by `\fP` or an + unargumented `.ft` if a requested font is not found. + +2022-11-30 G. Branden Robinson + + [tbl]: Fix Savannah #63449. + + * src/preproc/tbl/table.h (class table): Add new enumeration + constants for use with `flags` member variable: `HAS_TOP_VLINE` + and `HAS_TOP_HLINE`, which track properties of the table. + Unlike others, these have no correspondence to table region + options. + * src/preproc/tbl/main.cpp (process_format): Add new local + Boolean to track whether we're interpreting a format for the + first row. Use this to "or" on the `HAS_TOP_VLINE` or + `HAS_TOP_HLINE` flags if "|" or [_-] are encountered in the + first row's format, as appropriate. + (process_data): "Or" on `HAS_TOP_HLINE` if a single or double + horizontal line is used as the first row's data. + * src/preproc/tbl/table.cpp (do_top): On nroff mode devices, add + one vee of space above the table if we're going to be drawing an + unintersected vertical rule above the table's top. + + Fixes . + +2022-11-30 G. Branden Robinson + + [tbl]: Regression-test Savannah #63449. + + * src/preproc/tbl/tests/\ + do-not-overdraw-page-top-in-nroff-mode.sh: Do it. + * src/preproc/tbl/tbl.am (tbl_TESTS): Run test. + +2022-11-29 G. Branden Robinson + + * src/preproc/tbl/main.cpp (struct input_entry_format) + (input_entry_format::input_entry_format) + free_input_entry_format_list, process_format): Trivially + refactor. Rename `pre_vline` to `vline_count`. + +2022-11-29 G. Branden Robinson + + * src/preproc/tbl/table.cpp + (vertical_rule::contribute_to_bottom_macro, table::print) + (table::init_output, table::divide_span) + (table::compute_expand_width, table::define_bottom_macro) + (table::do_bottom): Produce roff output that is more readable, + for maintainability. Indent control lines inside macro + definitions. Standardize form of `if`, `ie`, and `el` requests. + Some output will not be indented because it is produced within + narrowly-scoped C++ functions (set_troff_location, + table::print_single_hline, table::print_double_hline, + table::do_row), I haven't verified that each one is called from + a consistent troff indentation level, and I'm not sure it's a + win to parameterize those functions in the indentation level. + +2022-11-29 G. Branden Robinson + + [tbl]: Fix Savannah #61909. + + * src/preproc/tbl/table.cpp (SAVED_INTER_WORD_SPACE_SIZE) + (SAVED_INTER_SENTENCE_SPACE_SIZE): Add new preprocessor macros. + (block_entry::do_divert): Restore saved inter-word and + inter-sentence space when formatting a text entry. + (table::init_output): When a table region begions, save the + values of inter-word and inter-sentence space. Add request to + the reset macro to restore saved inter-word and inter-sentence + space when leaving table region. + (table::do_top): Set inter-sentence space to be equal to + inter-word space. This way spaces are "literal" in ordinary + table extries (but not text blocks). + + Fixes . + +2022-11-29 G. Branden Robinson + + [tbl]: Regression-test Savannah #61909. + + * src/preproc/tbl/tests/\ + save-and-restore-inter-sentence-space.sh: Do it. + * src/preproc/tbl/tbl.am (tbl_TESTS): Run test. + +2022-11-29 G. Branden Robinson + + [tbl]: Suppress line numbering when formatting tables, and + restore it afterward. + + * src/preproc/tbl/table.cpp: Revert much of commit b69062693's + {2011-07-20} changes to this file. They were too complex for me + to understand, and permitted Savannah #60140 to persist (or + caused it). + (ROW_START_LINE_REG, ROW_SAVE_LINE_REG, ROW_MAX_LINE_REG) + (REPEATED_NM_SET_MACRO, REPEATED_NM_SUS_MACRO): Drop + preprocessor macros. + (SAVED_NUMBERING_LINENO, SAVED_NUMBERING_SUPPRESSION_COUNT): Add + new preprocessor macros. + (table::init_output, table::print_single_hline) + (table::print_double_hline, table::define_bottom_macro) + (table::do_row, table::do_top, table::do_bottom): Drop old + logic. + + (table::init_output): When the table begins, save the current + line number register `ln` and the count of remaining lines to be + suppressed (the new `.nn` register). Then suppress numbering + for the next 2 billion+ lines of output, with a groveling + apology to the elegance police. + (table::do_bottom): Restore saved value of `.nn`. If numbering + was active (even if suppressed), restore it with `nm` request. + If it wasn't, disable it, in case it was turned on inside the + table region. + + Fixes . Thanks to Hans + Bezemer for noting the practical significance of this bug. + +2022-11-29 G. Branden Robinson + + [tbl]: Regression-test Savannah #60140. + + * src/preproc/tbl/tests/save-and-restore-line-numbering.sh: Do + it. + * src/preproc/tbl/tbl.am (tbl_TESTS): Run test. + +2022-11-28 G. Branden Robinson + + [troff]: Implement new `.nn` register to report the remaining + count of lines to have their numbering suppressed. + + * src/roff/troff/env.h (class environment): Declare new member + function `get_no_number_count()`. + * src/roff/troff/env.cpp (get_no_number_count): Define new + member function, returning value of member variable + `no_number_count`. + (init_env_requests): Define new ".nn" register and attach it to + `get_no_number_count()`. + + * doc/groff.texi (Miscellaneous): Document it. Include example + of use to determine whether current output line will be + numbered. Also clarify meaning of register; `.nn` is not + decremented except when output line numbering is enabled. + * man/groff.7.man (Read-only registers): Document it. + + * src/roff/groff/tests/dot-nn_register_works.sh: Test it. + * src/roff/groff/groff.am (groff_TESTS): Run test. + + * NEWS: Add item. + + See . + +2022-11-27 G. Branden Robinson + + * tmac/fallbacks.tmac: Comment out four of the fallback + character definitions for (preconv'd) Unicode character input + added to address Savannah #58930 (corresponding to \[dg], \[dd], + \[%0], and \[rn]; they are failing for not yet understood + reasons involving "macros" attached to groff character info + structs, and the semantics of what it means for a character to + "exist" per the 'c' conditional operator. Fixes regression when + using "tty-char.tmac" (which nroff loads by default). Problem + introduced by me in commit 132182bd71, 23 October. The hope is + to resolve this issue post-groff 1.23.0. Thanks to Dave Kemper + for the report and discussion in Savannah #63332. + +2022-11-25 G. Branden Robinson + + * tmac/an-ext.tmac (SY, YS, mV): Remove `mA`, `mI`, and `mT` + registers when done with them. + +2022-11-25 G. Branden Robinson + + * src/roff/troff/node.h (character_exists): + * src/roff/troff/node.cpp (character_exists): Boolify. + +2022-11-25 G. Branden Robinson + + [doc]: Add make(1) dependency. + + * doc/doc.am (doc/groff-man-pages.pdf): Add dependency on our + FreeEuro font since we embed it. + +2022-11-25 G. Branden Robinson + + [build]: Refactor generation of "freeeuro.pfa" to make more + economical use of existing infrastructure, per a suggestion from + Deri James. This also puts the file where gropdf's "download" + file can find it when running it in a separate build directory. + We use it to generate "groff-man-pages.pdf". + + * font/devps/freeeuro.pfa: Rename this... + * font/devps/freeeuro.ps: ...to this. We can now use the suffix + rule that also applies to "symbolsl.ps" and "zapfdr.ps". + + * font/devps/devps.am (DEVPSFONTFILES): Move "freeeuro.pfa" from + here... + (DEVPSFONTFILES_GENERATED): ...to here. + (EXTRA_DIST): Ship the "new" "freeeuro.ps" file. + +2022-11-25 G. Branden Robinson + + * font/devps/psstrip.sed: Stop stripping comment lines in + general instead of preserving only ones that use the form in the + Document Structuring Conventions. This way we won't strip + copyright notices, like Werner Lemberg's in the FreeEuro font. + Thanks to Deri James for pointing this out. + +2022-11-22 G. Branden Robinson + + tmac/an-ext.tmac: Refactor to reduce code size. + + * tmac/an-ext.tmac: Refactor to reduce code size. `UE` and `ME` + have nearly identical implementations so... + + (mQ): Define new macro to perform the requisite actions, and... + + (UE, ME): Make these into wrappers calling mQ. + +2022-11-22 G. Branden Robinson + + [man]: Add unit tests for `MT/ME` and `UR/UE`. + + * tmac/tests/an-ext_MT-works.sh: + * tmac/tests/an-ext_UR-works.sh: Do it. + + * tmac/tmac.am (tmac_TESTS): Run tests. + +2022-11-18 G. Branden Robinson + + * src/devices/gropdf/gropdf.pl: Throw warning if paper format is + unrecognized. + +2022-11-18 G. Branden Robinson + + * src/devices/gropdf/gropdf.pl (Msg): Align more closely with + diagnostic message format prescribed by GNU Coding Standards: + emit space (only) prior to message severity. + +2022-11-17 G. Branden Robinson + + * doc/meref.me.in: Drop unnecessary initialization parameters + from document. The line and title length do not need to be set + in troff mode; the document lays out fine for a variety of paper + formats if these are not forced to 6.5 inches. Also drop + redundant initialization of `pp` register. + +2022-11-17 G. Branden Robinson + + [mdoc]: Fix Savannah #63377. + + * tmac/doc.tmac (Nm): Properly leverage new + `doc-in-name-section` variable. Set page topic `doc-topic-name` + to the first encountered argumentful `Nm` call in the "Name" + section while handling other "Name" section concerns, instead of + later after deciding we're not in the "Synopsis" section. + Problem caused by me when fixing antediluvian mdoc bug in commit + 0d85615c62, 5 November. + + Fixes . Thanks to John + Gardner for the report. + +2022-11-17 G. Branden Robinson + + [mdoc]: Add tests for `Nm` macro. + + * tmac/tests/doc_Nm-works.sh: Do it. Test regression reported + in Savannah #63377. Also ensure that we handle the case where + multiple `Nm` items are declared in the "Name" section (as might + happen in library man pages). + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-11-17 G. Branden Robinson + + * tmac/papersize.tmac: Improve integration with mm(7) macro + package. If a paper format has been selected, set `W` register + to new line length (if not already set on command line). + Similarly, set `O` register to 1 inch for the symmetric + horizontal margins otherwise assumed by this macro file. This + means that "groff -mm" and "groff -dpaper=letter -mm" are _not_ + synonymous (when groff is configured to use U.S. letter as the + default paper format), because groff mm(7) uses a page offset of + 0.963 inches on typesetters for compatibility with DWB mm. + * NEWS: Add item. + + See discussion in and (some) follow-ups. + +2022-11-16 Deri James + + * src/devices/gropdf/gropdf.pl: If the argument to the paper + format option '-p' matches a recognized format but includes a + trailing 'L' or 'l' ("legalL" or "a4l", for example), rotate the + document's MediaBox. + +2022-11-16 Deri James + + * src/devices/gropdf/gropdf.pl: Fix incorrect hotspot placement + if page is in landscape orientation. + (FixRect): Perform coordinate transform if page is rotated. + (Rotate): New function performs relevant trigonometry. + + Fixes . Thanks to Blake + McBride for the report. + +2022-11-16 G. Branden Robinson + + * tmac/e.tmac: Integrate better with papersize.tmac by no longer + forcing line (and title) length to 6 inches for typesetters on + initialization. Gather default line length from output device + description, possibly modified later (by other macro file or + input). No change to terminal ("nroff mode") output. + * NEWS: Add item. + +2022-11-16 Peter Schaffter + + * tmac/papersize.tmac: If a paper format has been selected, + smuggle right margin setting to mom(7) if not overridden by the + user. See discussion in and (some) follow-ups. + +2022-11-12 G. Branden Robinson + + * doc/doc.am (doc/groff-man-pages.pdf) + (doc/groff-man-pages.utf8.txt): Add dependencies on new + `TMAC_PACKAGE_MAN` and `TMAC_PACKAGE_MDOC` convenience macros. + +2022-11-12 G. Branden Robinson + + * tmac/tmac.am (TMAC_PACKAGE_MAN, TMAC_PACKAGE_MDOC): Define + convenience macros for in-tree documents to depend on. + +2022-11-12 G. Branden Robinson + + * tmac/an.tmac: Trivially refactor. Rename `an-section` to + `an*section`. + +2022-11-12 G. Branden Robinson + + * src/devices/grolbp/lbp.cpp (usage): Tweak usage message. The + output driver should be perfectly capable of handling output + from non-GNU (but device-independent) troffs. + +2022-11-12 G. Branden Robinson + + * src/devices/grops/ps.cpp (usage): Employ more informative + metasyntactic variable names in usage message. Also summarize + program's function and direct reader to man page if help + explicitly requested (inferred from identity of output stream). + +2022-11-11 G. Branden Robinson + + * tmac/an.tmac: Trivially refactor for congruence with + documentary terminology. Rename strings and macros. + - an-title -> an*topic + - an-abbreviate-page-title -> an*abbreviate-page-topic + - an-title-abbv -> an*topic-abbv + - an-title-string -> an*topic-string + - an-title-length -> an*topic-length + - an-title-length-prev -> an*topic-length-prev + - an-title-new-length -> an*topic-new-length + - an-page-title-style -> an*topic-style + (TH): Recast diagnostic message to refer to "section", not + "volume" title. + +2022-11-11 G. Branden Robinson + + * tmac/an-ext.tmac: Refactor to reduce code size. `UR` and `MT` + have identical implementations so... + (mV): Define new macro to perform the requisite actions, and... + (UR, MT): Make these into wrappers calling mV. + +2022-11-11 G. Branden Robinson + + * tmac/an-ext.tmac (UR, MT): Fix problem with incorrect line + lengths and occasional "can't adjust" warnings when using + hyperlinks. Reduce the line length within the diversion by the + amount of indentation used in the context. Without this, lines + were getting set too short. (You might think they'd be too + long, but when creating a new environment, the _formatter's_ + default line length is used; that's 65n on terminal devices.) + +2022-11-11 G. Branden Robinson + + [man]: Add test to ensure that link text (when the hyperlink + itself is not formatted because the device supports + hyperlinking) uses the correct line length and is adjusted. + + * tmac/tests/an_adjust-link-text-correctly.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run tests. + +2022-11-11 G. Branden Robinson + + * font/devpdf/devpdf.am: Refactor. + (MOSTLYCLEANFILES): Populate macro incrementally, adjacent to + the targets that build the files to be cleaned. This will + enable cleaner refactoring in the future. + (DEFAULT_BASE35_FONTS): Add new macro storing the targets of the + PostScript Level 2 standard base 35 font descriptions. + (devpdffont_DATA): Populate using `DEFAULT_BASE35_FONTS`. + (URW_BASE35_FONTS): Add new macro, empty if [!HAVE_URW_FONTS]; + and [HAVE_URW_FONTS] otherwise naming the `U` foundry font + description counterparts of the `DEFAULT_BASE35_FONTS`. + (devpdffont_DATA): Append `URW_BASE35_FONTS`. + ($(DEFAULT_BASE35_FONTS) $(URW_BASE35_FONTS)): Assert dependency + on "font/devpdf/download". This isn't literally true, but + BuildFoundries generates all of these together, so if the + "font/devpdf/download" target rule runs successfully, the font + description files named in these macro expansions will be + generated too. + +2022-11-09 G. Branden Robinson + + * src/utils/afmtodit/afmtodit.pl: Add new command-line option to + specify the generated font description's "spacewidth" parameter; + in commit bf7f6862c3, 2021-09-24, I made libgroff complain if + this directive is missing (since any font, even a "special" one, + can be selected as current and the formatter's behavior when + encountering an input space should be well-defined under that + circumstance). Adding this option enables a well-formed font + description to be produced. + * src/utils/afmtodit/afmtodit.pl (usage): + * src/utils/afmtodit/afmtodit.1.man (Synopsis, Options): + Document it. + * NEWS: Add item. + +2022-11-09 G. Branden Robinson + + * src/utils/afmtodit/afmtodit.pl: Use our own fatal exit + function instead of Perl's "die". + (croak): New subroutine emits argument as part of diagnostic + message and exits with status 1. + (usage): Exit with status 2, not 1, on usage errors. + + * NEWS: Document new exit behavior. + +2022-11-09 G. Branden Robinson + + * font/devpdf/devpdf.am (font/devpdf/download): Improve + comprehensibility of comments in generated "download" file. + Stop bracketing path element separator with spaces. + +2022-11-09 G. Branden Robinson + + * font/devpdf/util/BuildFoundries.pl (LoadFoundry): Stop + capitalizing beginning of diagnostic message (per GNU Coding + Standards). Drop ellipsis from end since no further diagnostics + relevant to that message are expected. Trim trailing slashes + from font path elements. + +2022-11-08 G. Branden Robinson + + * font/devps/devps.am: Refactor. Turn two identical target + rules into a (BSD-make-style, old-fashioned) pattern rule. + +2022-11-08 G. Branden Robinson + + * configure.ac: Rechristen self "GNU roff". + +2022-11-07 G. Branden Robinson + + * src/preproc/pic/pic.ypp: Slightly refactor. Rename parameter + `form` (format) to `fmt` to make its nature as an abbreviation + clear. + (format_number, do_sprintf): Reorder null pointer equality + comparisons to avoid inadvertent lvalue assignment. + (do_sprintf): Declare lists of valid format conversion + specifiers and modifiers explicitly instead of as happenstance + literals. Recast diagnostic messages to refer to "invalid", not + "bad" input; refer to input keyword correctly as "sprintf" (not + "snprintf"); and report the identity of the invalid conversion + specifier we reject. + +2022-11-07 G. Branden Robinson + + * tmac/doc.tmac (Fl, doc-flag-recursion, doc-print-recursive) + (doc-print-prefixes, Ar, Nm, Pa, Xr, doc-do-func, Fn) + (doc-do-func-args, Fo): Remove now-relic resets of type size to + previous value. Since commit 5125754cdf, 23 February, no mdoc + macro ever changes the type size. + +2022-11-08 Deri James + + [gropdf]: Cater for invalid entries in download file. + + * src/devices/gropdf/gropdf.pl: Test if path in the "download" + file points to a readable file. Also change order so that the + first valid entry is used as the font to embed. This replaces + previous order where last found entry is used. + + Fixes . + +2022-11-05 G. Branden Robinson + + [mdoc]: Set page topic in roman in "Name" section. + + * tmac/doc.tmac (Nm): If in the "Name" section of the page, set + argument(s) with the `No` (normal formatting) macro instead of + handling them...normally. Since `Nm`'s usual behavior is to set + the next argument in boldface, in this circumstance it is set in + roman. Aligns page rendering with man(7) and fixes a bug + documented in the 4.3BSD-Reno mdoc.samples(7) page (1990-06-22), + upon which the groff_mdoc(7) page is based. + * tmac/groff_mdoc.7.man (Bugs): De-document bug. + + Fixes part of . + +2022-11-05 G. Branden Robinson + + * tmac/mdoc/doc-common: Add internal register + `doc-in-name-section` to keep track of whether a macro is called + within the "Name" section of the document, to prepare a means of + fixing a long-standing bug with `Nm`. + (Sh): Canonicalize capitalization of section heading sooner. + Set or clear `doc-in-name-section` based on result. + (Rd): Add new register to dump. + * tmac/doc.tmac (doc-save-global-vars, doc-restore-global-vars): + Handle new register. + +2022-11-04 G. Branden Robinson + + [mdoc]: Use font CR, not CB, for `Cm` ("command modifier") and + `Fl` ("flag") macros on typesetters. + + * tmac/mdoc/doc-ditroff (doc-Cm-font, doc-Fl-Font): Switch to + Courier roman from Courier bold. This congrues better with + other `Li` literals, which were not in boldface. + +2022-11-04 G. Branden Robinson + + * tmac/mdoc/doc-nroff (doc-Li-Font): Switch from roman to bold. + On typesetters, the use of Courier (roman) plainly distinguishes + unquoted literals from their context. On terminals there was no + such visible distinction. Fortunately, in groff_mdoc(7) itself, + this does not result in a blinding blitz of boldface because the + `Ql` (quoted literal) macro is so often used, and it maintains + the roman style. This change further aligns groff mdoc(7) with + groff man(7) style conventions. (Also see how we handle + literals for typesetters and terminals in the "ms.ms" document.) + +2022-11-03 G. Branden Robinson + + [mdoc]: Make `Sx` macro perform quotation, not italicization. + It's thorougly inconsistent with English composition practices + to refer to (sub)section headings within a document as if they + were major works. + + * tmac/doc.tmac (Sx): Implement. + * tmac/mdoc/doc-ditroff (doc-Sx-font): + * tmac/mdoc/doc-nroff (doc-Sx-font): Delete. + * tmac/groff_mdoc.7.man (Section Cross References): Rename... + ((Sub)section cross references): ...to this. Recognize + existence of `Ss` macro, curiously overlooked before. + * NEWS: Add item. + +2022-11-03 G. Branden Robinson + + [mdoc]: Drop now-unused `doc-pageref` string. It was nowhere + interpolated outside of state management macros. + + * tmac/doc.tmac (doc-save-global-vars, doc-restore-global-vars): + * tmac/mdoc/doc-common: Do it. + +2022-11-03 G. Branden Robinson + + * tmac/mdoc/doc-common (doc-header, doc-footer): Revise for + clarity and to use correct typefaces for titles. + (doc-header): Add new strings to ease title construction. + `doc-xref` stores the fully formatted page topic and section + number, e.g., "troff(1)"; `doc-abbv` stores the its potentially + abbreviated form when it is too long to fit. + (doc-footer): Use `doc-xref` as above. Stop setting the `Os` + and `Dd` parameters in the ("semantic"?) font used for the + page's section number (probably unnoticed all these years + because the font used to render that was (Times) roman). + +2022-11-03 G. Branden Robinson + + * tmac/doc.tmac: + * tmac/mdoc/doc-common: Rename strings for clarity. + - doc-document-title -> doc-page-topic + - doc-document-title-saved -> doc-page-topic-saved + * tmac/mdoc/doc-common: Use new name. + +2022-11-03 G. Branden Robinson + + * tmac/mdoc/doc-ditroff (doc-page-topic-font): + * tmac/mdoc/doc-nroff (doc-page-topic-font): Set man page topic + names in italics. + +2022-11-03 G. Branden Robinson + + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: Rename strings for clarity. + - doc-caption-font -> doc-page-topic-font + - doc-caption-font2 -> doc-page-section-font + * tmac/mdoc/doc-common (doc-header, doc-footer): Use new names. + +2022-11-03 G. Branden Robinson + + * tmac/doc.tmac: Delete suppression of `Pa` font selection in a + "Files" section. This special handling was not documented. + +2022-11-03 G. Branden Robinson + + * tmac/mdoc/doc-ditroff (doc-Pa-font): Set file specifications + in italics on typesetters. (Terminals already use italics.) + +2022-11-03 G. Branden Robinson + + * tmac/mdoc/doc-ditroff (doc-Xr-font): + * tmac/mdoc/doc-nroff (doc-Xr-font): Set man page topic cross + references in italics. + +2022-11-03 G. Branden Robinson + + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: Rename `doc-Tn-font-shape` to + `doc-Tn-font` for better parallelism with other font selection + strings for mdoc macros, since the `Tn` macro no longer + manipulates the type size. + * tmac/doc.tmac (Tn): Use new name. + +2022-11-02 G. Branden Robinson + + * doc/groff.texi (Debugging): Fix misleading claim. The + arguments to the `tm`, `tmc`, and `tm1` requests are not read in + copy mode. For example, you don't need to double backslashes to + get them to interpolate registers or strings. + +2022-11-02 G. Branden Robinson + + * tmac/an.tmac (an-end): + * tmac/mdoc/doc-common (doc-end-macro): Ensure that document + footer appears in continuous rendering mode even when a final + pending output line in the document is 1v from the page bottom. + Replace `fl` call with `br`, which IMO has clearer semantics. + Extend page length by 1v before doing so if the current vertical + position is within 1v of the page bottom. + + Thanks to Alex Colomar for the report. + +2022-11-02 G. Branden Robinson + + [man, mdoc]: Regression-test special case of continuous + rendering when the last pending output line in the document is + 1v from the (notional) page bottom. + + * tmac/tests/an_output-footer-when-continuously-rendering.sh: + * tmac/tests/doc_output-footer-when-continuously-rendering.sh: + Do it. + * tmac/tmac.am (tmac_TESTS): Run tests. + +2022-11-02 G. Branden Robinson + + * tmac/an.tmac (TE): Update diagnostic to mention another + failure mode: a man page that is simply a `so` request requires + soelim(1) to be run if the sourced page uses tbl(1). + +2022-11-01 G. Branden Robinson + + * src/devices/xditview/xditview.am + ($(GXDITVIEW_GROFF_VERSION_H)): Run `$(MKDIR_P)` and `printf` as + separate rule commands in order to use them with `$(AM_V_at)` + and `$(AM_V_GEN)`, respectively. Prevents noise from build. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2022-10-31 G. Branden Robinson + + [eqn]: Fix Savannah #63299. + + * src/preproc/eqn/main.cpp: Revise input file line number + handling. + (read_line): Stop dealing with `current_lineno` here; it's now + up to its caller (`do_file()`) to manipulate the line number. + (do_file): When reading new file, initialize `current_lineno` to + 1 instead of 0. Reset it to zero when encountering EOF (so that + diagnostics will not include a line number at all). When + performing nested call to `read_line()` to gather '.EN' from + input, increment the line number. Write correct line number in + output groff `lf` requests; in groff, its first argument assigns + the number of the _next_ input line. Increment line number at + end of outer `read_line()` loop. + + Fixes . Thanks to Alex + Colomar for the report. + +2022-10-31 G. Branden Robinson + + [eqn]: Regression-test Savannah #63299. + + * src/preproc/eqn/tests/\ + diagnostics-report-correct-line-numbers.sh: Do it. + * src/preproc/eqn/eqn.am (eqn_TESTS, TESTS, EXTRA_DIST): Run + test. + +2022-10-30 G. Branden Robinson + + * src/utils/grog/grog.pl (fail, warn, construct_command) + (version): Restore trailing newlines to `print`ed output. They + went missing when I removed the assignment of the output record + separator in commit 6f2e367836, 24 October. Thanks to Dave + Kemper for catching this. + +2022-10-30 G. Branden Robinson + + * src/preproc/preconv/preconv.cpp: Trivially refactor. Rename + `default_encoding` to `fallback_encoding` for clarity. Update + comments and debugging diagnostic messages accordingly. + +2022-10-29 G. Branden Robinson + + [grolj4]: Absorb lj4_font(5) man page into grolj4(1). + + * src/devices/grolj4/lj4_font.5.man: Delete, moving content... + * src/devices/grolj4/grolj4.1.man (Fonts): ...hither. + + * doc/doc.am (GROFF_MAN_PAGES1): + * src/devices/grolj4/grolj4.am (man5_MANS, EXTRA_DIST): Stop + formatting and shipping removed page. + + * src/roff/groff/groff.1.man: + * src/utils/hpftodit/hpftodit.1.man: Drop references to page. + + Fixes . + +2022-10-29 G. Branden Robinson + + [mdoc]: Support `SN` register to configure subsection heading + indentation. + + * tmac/doc.tmac: Recognize `SN` register if set on command line + and use groff man(7)-compatible default if it is not. + * tmac/mdoc/doc-common (Ss): Use this register instead of a + literal. + * tmac/groff_mdoc.7.man (Formatting with groff, troff, and + nroff): Document it. + * NEWS: Update item. + + Fixes part of . + +2022-10-29 G. Branden Robinson + + [mdoc]: Support `IN` register to configure paragraph + indentation. + + * tmac/doc.tmac: Recognize `IN` register if set on command line + and use groff man(7)-compatible defaults if it is not. + * tmac/mdoc/doc-common (Sh): Use this register instead of + `doc-paragraph-indentation`. + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: Stop setting pargraph indentation + defaults here. + * tmac/groff_mdoc.7.man (Formatting with groff, troff, and + nroff): Document it. + * NEWS: Update item. + + * tmac/tests/doc_Mt-works.sh: + * tmac/tests/doc_indents-correctly.sh: Update test expectations. + + Fixes part of . + +2022-10-29 G. Branden Robinson + + * tmac/mdoc/doc-common (Sh): Fix code style nit. Set paragraph + indentation absolutely rather than incrementally. mdoc(7) + doesn't have relative inset macros like man(7)'s `RS`/`RE`, so + the relative measurement could mislead the reader. (The + section heading itself uses an indentation of 0.) + +2022-10-29 G. Branden Robinson + + [mdoc]: Fix Debian #1022179. + + * tmac/mdoc/doc-common (Ss): Indent entire subsection heading by + 3 ens, even if it breaks across output lines. (Change and + restore indentation explicitly instead of using a temporary + indent to achieve this. Also indent absolutely by 3n instead of + retreating by one quarter inch.) + + Fixes . Thanks to наб for the + report. + +2022-10-29 G. Branden Robinson + + * tmac/tests/doc_indents-correctly.sh: Add regression test for + Debian #1022179. + + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-10-29 G. Branden Robinson + + [mdoc]: Fix misleading register name. + + * tmac/mdoc/doc-common (Sh): + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: Rename `doc-subheader-indent` to + `doc-paragraph-indentation`, because the latter is what it's + used for. + +2022-10-29 G. Branden Robinson + + * m4/groff.m4 (GROFF_POPPLER): Improve shell code portability. + Per the GNU Autoconf manual, "The -a, -o, '(', and ')' operands + are not present in all implementations, and have been marked + obsolete by Posix 2008. ...portable uses of test should never + have more than four arguments, and scripts should use shell + constructs like '&&' and '||' instead." + +2022-10-26 G. Branden Robinson + + * src/preproc/preconv/preconv.cpp: Alter usage message handling. + (usage): Summarize purpose of program and steer reader to man + page (only) if help was explicitly requested, and exit + successfully from here... + (main): ...instead of calling scope. + +2022-10-26 G. Branden Robinson + + * src/preproc/preconv/preconv.cpp (usage): Use more + communicative metasyntactic variable names. + * src/preproc/preconv/preconv.1.man (Synopsis, Options): Align + with updated usage message. + +2022-10-24 G. Branden Robinson + + * src/preproc/html/pre-html.cpp: Alter usage message handling. + (usage): Summarize purpose of program and steer reader to man + page (only) if help was explicitly requested, and exit + successfully from here... + (main): ...instead of calling scope. + +2022-10-24 G. Branden Robinson + + * src/devices/grolbp/lbp.cpp: Alter usage message handling. + (usage): Summarize purpose of program and steer reader to man + page (only) if help was explicitly requested, and exit + successfully from here... + (main): ...instead of calling scope. + +2022-10-24 G. Branden Robinson + + * src/devices/grolbp/lbp.cpp (main): Handle `getopt_long()` + return value more idiomatically. + +2022-10-24 G. Branden Robinson + + * src/devices/grolbp/lbp.cpp: Fix code style nits. + (main): Use standard C library symbols `EXIT_SUCCESS` and + `EXIT_FAILURE` instead of integer literals as arguments to + `exit()`. Add assertion. + +2022-10-24 G. Branden Robinson + + * src/devices/grotty/tty.cpp: Alter usage message handling. + (usage): Summarize purpose of program and steer reader to man + page (only) if help was explicitly requested, and exit + successfully from here... + (main): ...instead of calling scope. + +2022-10-24 G. Branden Robinson + + * src/devices/grotty/tty.cpp: Fix code style nits. + (main): Use standard C library symbols `EXIT_SUCCESS` and + `EXIT_FAILURE` instead of integer literals as arguments to + `exit()`. Replace `assert(0)` call with communicative + predicate. + +2022-10-24 G. Branden Robinson + + * src/roff/groff/groff.cpp: Alter usage message handling. + (synopsis, help): Coalesce these two functions... + (usage): ...into this one. Summarize purpose of program and + steer reader to man page only if help was explicitly requested, + rather than blitzing user with text upon a usage error. Also + drop option summary from usage message, as it duplicates + groff(1). + +2022-10-24 G. Branden Robinson + + * src/utils/grog/grog.pl: Alter usage message handling. + (help): Rename this subroutine... + (usage): ...to this. Summarize purpose of program and steer + reader to man page only if help was explicitly requested, rather + than blitzing user with text upon a usage error. Also drop + option summary from usage message, as it duplicates grog(1). + +2022-10-24 G. Branden Robinson + + * src/utils/grog/grog.pl: Drop relic code and comments. + +2022-10-24 G. Branden Robinson + + [grog]: Migrate expansion of Perl interpreter in shebang. + Use the same technique as afmtodit, mmroff, gropdf, and pdfmom. + + * src/utils/grog/grog.am (grog): Replace "@PERL@" instead of + '^\(#! \).*perl'. + * src/utils/grog/grog.pl: Use "@PERL@" in shebang. + +2022-10-24 G. Branden Robinson + + [afmtodit]: Give program a usage message. + + * src/utils/afmtodit/afmtodit.pl: Add new scalar `want_help` of + Boolean sense. Recognize new long option `--help`, attached to + `$want_help`. Stop stripping off directory name components from + program name when emitting diagnostics. No other groff program + does this (well, gropdf did until recently), and it might save + users some confusion if they're working with multiple copies of + afmtodit. + (usage): New subroutine reports usage message. If help was + explicitly requested, summarize purpose of program and steer + reader to man page. + +2022-10-24 G. Branden Robinson + + [afmtodit]: Migrate expansion of Perl interpreter in shebang. + Use the same technique as mmroff, gropdf, and pdfmom. + + * src/utils/afmtodit/afmtodit.am (afmtodit): Replace "@PERL@" + instead of "/usr/bin/perl". + * src/utils/afmtodit/afmtodit.pl: Use "@PERL@" in shebang. + +2022-10-24 G. Branden Robinson + + [gropdf] Give program a usage message. + + * src/devices/gropdf/gropdf.pl: Add new scalar `want_help` of + Boolean sense. Recognize new long option `--help`, attached to + `$want_help`. + (usage): New subroutine reports usage message. If help was + explicitly requested, summarize purpose of program and steer + reader to man page. + +2022-10-24 G. Branden Robinson + + * src/devices/xditview/xditview.c (Syntax): "#if 0" out + reference to `-noPolyText` option, whose effect is likewise + bracketed in another file. + +2022-10-24 G. Branden Robinson + + * src/roff/troff/input.cpp (enable_warning, disable_warning): + Recast diagnostic messages for clarity. + +2022-10-24 G. Branden Robinson + + [pfbtops]: Fix code style and diagnostic nits. + + * src/utils/pfbtops/pfbtops.c (error): Exit with `EXIT_FAILURE` + status (from standard C library) instead of status 2. + (main): Exit with `EXIT_SUCCESS` status when writing version or + help information. Exit with status 2 when dying due to usage + error. Use `fprintf()` and `strerror()` to construct error + message when dying due to inability to open input file instead + of using `perror()`, which anonymizes its caller and thus should + never be used in serious work. Avoid it like `gets()`. + * NEWS: Add item for exit status changes. + + Continues the long process of fixing Savannah #52463. + +2022-10-24 G. Branden Robinson + + [man pages]: Don't document macro package compatibility wrapper + directory if it's not used. + + * Makefile.am (.man): Use sed to replace + '@COMPATIBILITY_WRAPPERS@' in man page text with value of + `compatibility_wrappers` shell variable. Document its purpose. + * src/preproc/eqn/eqn.1.man (Description): + * src/preproc/grn/grn.1.man (Options): + * src/roff/groff/groff.1.man (Installation directories): + * src/roff/troff/troff.1.man (Environment): Mention + `@SYSTEMMACRODIR@` only if `@COMPATIBILITY_WRAPPERS@` expands to + something other than "no" (it could be "yes" or "manual"). + + Thanks to Alexander Kanavin and Jeremy Puhlman for the report. + +2022-10-21 Robert Yang + + * font/devpdf/util/BuildFoundries.pl: + * src/devices/gropdf/gropdf.pl: + * src/devices/gropdf/pdfmom.pl: Replace use of '-w' in shebang + line with "use warnings;". + +2022-10-23 G. Branden Robinson + + * tmac/fallbacks.tmac: Define fallback characters for many code + points from the Unicode General Punctuation Block. This is to + ease migration from other documentation formats; in many cases + there are more idiomatic *roff ways of getting results that + typeset better and are amenable to fine tuning. For instance, + Unicode defines spaces and dashes of various discrete widths; + when typesetting with *roff, you can have a space or dash (among + other things) of any length achievable by the output device. + * tmac/ps.tmac: Migrate non-breaking hyphen fallback character + definition from here to the foregoing. + + Fixes . Thanks to Dave Kemper + for the report and discussion. + +2022-10-23 G. Branden Robinson + + * tmac/an.tmac: + * tmac/s.tmac: Escape newlines when opening conditional blocks. + + Fixes . Thanks to Bjarni Ingi + Gislason for the report and Dave Kemper for the quick fix. + +2022-10-21 G. Branden Robinson + + * src/devices/grodvi/dvi.cpp (usage): + * src/devices/grohtml/post-html.cpp (usage): + * src/devices/grolbp/lbp.cpp (usage): + * src/devices/grolj4/lj4.cpp (usage): + * src/devices/grops/ps.cpp (usage): + * src/devices/grotty/tty.cpp (usage): + * src/devices/xditview/xditview.cpp (usage): + * src/preproc/eqn/main.cpp (usage): + * src/preproc/grn/main.cpp (usage): + * src/preproc/html/pre-html.cpp (usage): + * src/preproc/pic/main.cpp (usage): + * src/preproc/preconv/preconv.cpp (usage): + * src/preproc/refer/refer.cpp (usage): + * src/preproc/soelim/soelim.cpp (usage): + * src/preproc/tbl/main.cpp (usage): + * src/roff/groff/groff.cpp (synopsis, help): + * src/roff/nroff/nroff.sh: + * src/roff/troff/input.cpp (usage): + * src/utils/addftinfo/addftinfo.cpp (usage): + * src/utils/hpftodit/hpftodit.cpp (usage): + * src/utils/indxbib/indxbib.cpp (usage): + * src/utils/lkbib/lkbib.cpp (usage): + * src/utils/lookbib/lookbib.cpp (usage): + * src/utils/pfbtops/pfbtops.c (usage): + * src/utils/tfmtodit/tfmtodit.cpp (usage): + * src/utils/xtotroff/xtotroff.c (usage): Update usage message. + Present different modes of operation on separate output lines. + Sort options in English lexicographic order. Document help + option(s) as last mode of operation. + +2022-10-21 G. Branden Robinson + + * src/devices/gropdf/gropdf.pl: Revise handling of argument 0. + Rename scalar `progname` to `prog` for brevity (and preparation + for writing a usage message). Also stop stripping off directory + name components from it. No other groff program does this, and + it might save users some confusion if they're working with + multiple copies of gropdf. + +2022-10-21 G. Branden Robinson + + Migrate terminology from "paper size" to "paper format" or + "paper dimensions" as appropriate in documentation and + diagnostic messages. "Format" implies an orientation (which can + be overridden in many cases) whereas size does not. When only + the magnitudes of measurements are at issue (mainly for internal + purposes), use the term "dimensions". + + * NEWS: + * PROBLEMS: + * doc/groff.texi: + * m4/groff.m4 (GROFF_PAGE): + * man/groff_font.5.man: + * man/groff_tmac.5.man: + * src/devices/grodvi/dvi.cpp (main): + * src/devices/grolbp/grolbp.1.man: + * src/devices/grolbp/lbp.cpp (main): + * src/devices/grolj4/grolj4.1.man: + * src/devices/grolj4/lj4.cpp (lj4_printer::lj4_printer, main): + * src/devices/grolj4/lj4_font.5.man: + * src/devices/gropdf/gropdf.1.man: + * src/devices/grops/grops.1.man: + * src/devices/grops/ps.cpp (main): + * src/roff/groff/groff.1.man: + * tmac/papersize.tmac: Do it. + +2022-10-19 G. Branden Robinson + + * tmac/mdoc/doc-ditroff (doc-left-parenthesis) + (doc-right-parenthesis, doc-left-bracket, doc-right-bracket): + Drop thin and hair space escape sequences from these string + definitions. (Also, doc-right-bracket was inconsistent with + doc-left-bracket, the former inserting horizontal motion only + before the bracket character.) Eliminates excess space when + using Pq, Po, Pc and Bq, Bo, Bc macros and formatting for + typesetters, and aligns output with behavior of `Pq` and `Bq` as + documented in groff_mdoc(7). + + Fixes . Thanks to наб for the + report. + +2022-10-19 G. Branden Robinson + + * tmac/mdoc/doc-ditroff: Use groff-canonical typeface names in + font selection escape sequences. Migrate 'C' to 'CR' and 'CO' + to 'CI'. (Admittedly, "Courier oblique" is more pedantically + correct than "Courier italic". But the iron ball of Unix troff + history and its style trio [later quartet] of "R", "I", "B" + {then "BI"} will not be ignored.) + +2022-10-19 G. Branden Robinson + + * tmac/mdoc/doc-ditroff: Drop nilpotent type size escape + sequences from string definitions. + +2022-10-18 G. Branden Robinson + + Document a CSTR #54 erratum regarding \n(st and \n(sb. + + * doc/groff.texi (Page Motions): + * man/groff.7.man (Writable registers): + * man/groff_diff.7.man (New registers): Do it. + + * PROBLEMS: Further clarify. Note DWB and Heirloom behavior. + +2022-10-18 G. Branden Robinson + + * src/preproc/eqn/main.cpp (read_line): Fix switched test + consequents when updating `current_lineno`. + +2022-10-18 G. Branden Robinson + + * src/utils/xtotroff/xtotroff.c (main): Annotate "xtotroff" as a + GNU program in version information. + +2022-10-18 G. Branden Robinson + + * src/devices/xditview/xditview.am + ($(GXDITVIEW_GROFF_VERSION_H): Perform correct substitution to + get groff version string into `Version_string` C symbol. + Continues commit c73decb58f, 9 October. + +2022-10-18 G. Branden Robinson + + * src/utils/afmtodit/afmtodit.1.man (Files): Fix ordering error. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2022-10-15 G. Branden Robinson + + * src/preproc/eqn/lex.cpp (get_delimited_text): Clear line + number when hitting EOF. + * src/preproc/eqn/main.cpp: Revise end-of-file handling. Clear + line number upon reaching EOF so that we don't report a nonsense + value one greater than the number of lines in the input file. + (read_line): Boolify. Make static (local linkage only), since + it has no external callers. Introduce new Boolean variable + `is_end_of_file`. Clear `current_lineno` if EOF, and increment + it otherwise. + (do_file, main): Clarify diagnostic messages. + +2022-10-15 G. Branden Robinson + + [eqn]: Improve diagnostics involving unprintable characters. + + * src/preproc/eqn/main.cpp (input_char_description): New + function constructs a human-readable string describing + characters. + (read_line, inline_equation, main): Call new function and adjust + diagnostic message wording to accommodate the phrase it returns. + + Fixes . + +2022-10-14 G. Branden Robinson + + [eqn]: Improve diagnostics. + + * src/preproc/eqn/lex.cpp (file_input::~file_input): + * src/preproc/eqn/main.cpp (main): Die if `fclose()` fails and + report underlying system error. + (inline_equation): Identify inline equation context. + +2022-10-15 G. Branden Robinson + + * tmac/e.tmac (2c, 1c): Throw diagnostic if changing columnation + with a footnote pending. This isn't necessarily an error per + se, but in many cases it will flag an undesirable page layout + due to the limited flexibility of me(7)'s footnote support at + present. See . + +2022-10-14 G. Branden Robinson + + * src/preproc/eqn/main.cpp: Fix code style nits. + (usage): Align output with man page. Document separate + invocation modes separately. + (main): Use standard C library symbols `EXIT_SUCCESS` and + `EXIT_FAILURE` with `exit()` calls instead of integer literals. + Replace `assert(0)` call with communicative predicate. Check + return value of `fclose()`, and exit with fatal error if it + fails. Distinguish `ferror()` status and `fflush(stdout)` + failures when cleaning up before exit. + +2022-10-12 G. Branden Robinson + + * src/roff/troff/input.cpp (read_color_draw_node): Clarify + diagnostic. + +2022-10-10 G. Branden Robinson + + * tmac/dvi.tmac: Always render \[aq] as a neutral apostrophe. + Thanks to the TC fonts, we can do this even when the default CM + text fonts are in use. + + Fixes . + +2022-10-10 G. Branden Robinson + + * tmac/ec.tmac: Remove apparently unnecessary remappings of + styles (and reassertion of style slots in the font mounting + position list, albeit in an unusual order (RBI instead of RIB)). + This code frustrated the rendering of man pages with post-1.22.4 + groff for the 'dvi' output device when using EC fonts. Instead + remap the T and H family typefaces in all four styles + explicitly. (The CW and CWI faces were already handled.) Also + add remappings of groff+PostScriptish font names "CB" and "CBI" + to CW EC faces of normal weight, corresponding to dvi.tmac; see + commits 529e2ca0c4, 2002-03-23 and c9741da6c0, 2021-05-06. + + Fixes . + +2022-10-10 G. Branden Robinson + + * tmac/tests/an_works-with-ec.sh: Add regression test for + Savannah #63194. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-10-10 G. Branden Robinson + + * tmac/tests/ec_works.sh: Add unit test to validate use of EC + fonts when "-mec" option given. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-10-10 G. Branden Robinson + + * tmac/latin2.tmac: + * tmac/latin5.tmac: + * tmac/latin9.tmac: Perform the character remapping shenanigans + of the fix for Savannah #63112 only if the output device is + "latin1" (a terminal using an 8-bit character encoding). Only + then can we be sure that Latin-1 glyphs will be unavailable when + other encodings are used and that `\N` escape sequences will + identify correct glyph indices in a font (because there is no + font per se accessible to groff--simply a terminal implementing + a character encoding). + +2022-10-10 G. Branden Robinson + + * src/devices/gropdf/gropdf.pl (GetType1): Clarify diagnostic. + When failing to open a font file for embedding in a PDF, mention + this context. + +2022-10-09 G. Branden Robinson + + * src/utils/afmtodit/afmtodit.tables: Update against Unicode 15. + No substantive changes. + + Fixes . + +2022-10-09 G. Branden Robinson + + * configure.ac: If URW fonts were located, add the directory + where they were found to the configuration report. + + Attempts to fix (2/2). + +2022-10-09 G. Branden Robinson + + * m4/groff.m4: Try to make gropdf's search for URW font files + more deterministic. To disambiguate cases where multiple--not + necessarily identical--copies may be found on the system, search + _only_ in the directory given to the `--with-urw-fonts-dir` + configure option, if present. This populates the "Foundry" file + generated by the build, causing gropdf to search there first. + (GROFF_URW_FONTS_PATH): Stop `AC_SUBST`ing `urwfontsdir` here. + (GROFF_URW_FONTS_CHECK): `AC_REQUIRE` `GROFF_URW_FONTS_PATH` to + be run first. If `urwfontsdir` is not null, search only there + for URW fonts. Assign `urwfontsdir` the value of the directory + in which the fonts are found. Assign it an empty value if none + are found. Either way, `AC_SUBST` the variable. + + Attempts to fix (1/2). + +2022-10-09 G. Branden Robinson + + * src/devices/gropdf/gropdf.pl (LoadFont): Clarify diagnostic. + gropdf opens "fonts" in two distinct ways. On the one hand, it + opens groff font description files for essentially all + nontrivial output. On the other, it may open actual Type 1 font + files for embedding in a PDF. Make failure of the former case + less confusable with the latter. + +2022-10-09 G. Branden Robinson + + [ms]: Document new XN/XH and related macros. + + * doc/groff.texi (Creating a table of contents): + * doc/ms.ms (Creating a table of contents): + * tmac/groff_ms.7.man (Creating a table of contents): Do it. + + Fixes . + +2022-10-09 G. Branden Robinson + + [gxditview]: Support `-version`, `--version` option. As a C + program, gxditview had no access to the (C++) libgroff + `Version_string` symbol, so construct a header file to store + this datum at build time. If groff gets other user-facing C + programs, we should consider generating this header in + src/include instead. + + * src/devices/xditview/xditview.am: Generate "groff_version.h" + file. + (GXDITVIEW_GROFF_VERSION_H): Define new macro. + ($(GXDITVIEW_GROFF_VERSION_H)): Define target to generate file. + (XDITVIEW_GENHDRS): Add $(GXDITVIEW_GROFF_VERSION_H). + + * src/devices/xditview/xditview.c: Include new header file. + (Syntax): Report newly supported options. + (main): Recognize and handle new options. + + * src/devices/xditview/gxditview.1.man (Synopsis): Document + them. + +2022-10-09 G. Branden Robinson + + [gxditview]: Update usage message production and contents. + + * src/devices/xditview/xditview.c: Use C99 Boolean type. + (Syntax): Accept additional Boolean argument indicating whether + the usage message is to be issued due to an error. Write + message to stderr if so, and stdout otherwise. Stop presuming + length of output line; guessing where to wrap is unreliable due + to variable terminal width and length of argv[0]. Write one + line per invocation mode of the program. Stop duplicatively + documenting standard X Toolkit options. Exit with standard C + library `EXIT_FAILURE` status if there was an error, and + `EXIT_SUCCESS` otherwise. + (main): Refactor to prepare for `--version` support. + + * src/devices/xditview/gxditview.1.man (Synopsis): Sync list of + options with usage message. + +2022-10-09 G. Branden Robinson + + * src/utils/afmtodit/afmtodit.pl: Recognize "--version" as + synonym for "-v". To achieve this, use Getopt::Long instead of + Getopt::Std. + * src/utils/afmtodit/afmtodit.1.man (Synopsis, Options): + Document it. + +2022-10-09 G. Branden Robinson + + * src/devices/gropdf/pdfmom.pl: Recognize "--version" as synonym + for "-v". + * src/devices/gropdf/pdfmom.1.man (Synopsis, Description): + Document it. + +2022-10-08 G. Branden Robinson + + * src/utils/grog/grog.pl (version): Identify as a GNU program. + +2022-10-06 G. Branden Robinson + + * src/devices/grolj4/grolj4.1.man (Typefaces): Add new + subsection. + + Fixes . Thanks to T. Kurt + Bond for the report. + +2022-10-05 G. Branden Robinson + + * doc/meref.me.in (Columnated Output): Document persistence of + `$s` register value across columnation mode changes. + + Fixes . Thanks to Dave + Kemper for the report. + +2022-10-05 G. Branden Robinson + + * doc/meref.me.in: Annotate empty default arguments more + consistently. + + Fixes . Thanks to Dave + Kemper for the report. + +2022-10-05 G. Branden Robinson + + * doc/meref.me.in: Fix documentation error. + (Summary) <\_>: Describe as "underrule", not "underscore". + These are distinct: the latter is a glyph; the former is drawn + by typesetters and rendered with SGR attributes on terminals. + +2022-10-04 G. Branden Robinson + + * NEWS: Advise users of changes to "name" directive handling in + font description files. + + Fixes . Thanks to Dave + Kemper for the report. + +2022-10-04 G. Branden Robinson + + * src/roff/troff/number.cpp: Refactor and fix code style nits. + Boolify and rename static (local) functions. + - parse_expr -> is_valid_expression + - start_number -> is_valid_expression_start + - parse_term -> is_valid_term + Rename preprocessor macro `SCALE_INDICATOR_CHARS` to + `SCALING_UNITS`. + (is_valid_expression, is_valid_term): Rename parameters and + demote them from `int` to `bool`. + - scaling_indicator -> scaling_unit (no demotion) + - parenthesised -> is_parenthesized + - rigid -> is_mandatory + (is_valid_expression_start, is_valid_expression, is_valid_term): + Return Boolean rather than integer literals. + (get_vunits, get_hunits, get_number_rigidly, get_number) + (get_integer): Update call sites of renamed functions. Replace + Boolean-valued integer literals used as Booleans with Boolean + literals and annotate their purposes. (See .) + (get_vunits, get_hunits, get_number, get_integer): Replace `0` + in assertions with a communicative predicate. In all of these + it's an unhandled `switch()` case. + +2022-10-04 G. Branden Robinson + + * src/roff/troff/input.cpp (do_expr_test, do_zero_width): Use + better terminology in diagnostic messages. + +2022-10-04 G. Branden Robinson + + [troff]: Fix Savannah #63151. + + * src/roff/troff/input.cpp (read_draw_node): Throw "delim" + warning diagnostic when a drawing escape sequence ends the line + without a closing delimiter. + + Fixes . + +2022-10-03 G. Branden Robinson + + * tmac/fallbacks.tmac: Define fallbacks for characters in ISO + Latin-{2,5,9} but not in Latin-1. + + Fixes . Thanks to Rafal Pietrak + for the report. + +2022-10-03 G. Branden Robinson + + [troff]: Fix Savannah #63149. + + * src/roff/troff/reg.cpp (alter_format): Throw comprehensible + diagnostic when input delete character encountered in register + format. + + Fixes . + +2022-10-03 G. Branden Robinson + + [troff]: Describe an input delete character comprehensibly. + + * src/roff/troff/input.cpp (token::description): The delete + character (ISO 127 decimal, EBCDIC 7) is a valid `TOKEN_CHAR` + but is not printable. Don't attempt to output it literally in + diagnostics; describe it in a phrase instead. + +2022-10-03 G. Branden Robinson + + [troff]: Apply consistent terminology. + + * src/roff/troff/input.cpp: Rename functions to better align + with our documentation, and decouple their names from an + assumption of diagnostic severity. Also give them imperative + names since they are called for their side effects, not their + return values. + - empty_name_warning -> diagnose_missing_identifier + - non_empty_name_warning -> diagnose_invalid_identifier + (diagnose_missing_identifier): Refer to absent operand as + "identifier", not "name", in diagnostic messages since the + latter (strictly) refers to the request/macro/string/diversion + name space, and this function is also used to gather register + identifiers. + +2022-10-02 G. Branden Robinson + + [tmac]: Fix Savannah #63112 (3/3). + + * tmac/latin2.tmac: Replace characters that ISO Latin-1 has but + Latin-2 doesn't. Map characters that ISO Latin-2 has and + Latin-1 doesn't to their numeric code points. + +2022-10-02 G. Branden Robinson + + [tmac]: Regression-test Savannah #63112 (3/3). + + * tmac/tests/latin2_works: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-10-01 G. Branden Robinson + + [tmac]: Fix Savannah #63112 (2/3). + + * tmac/latin5.tmac: Replace characters that ISO Latin-1 has but + Latin-5 doesn't. Map characters that ISO Latin-5 has and + Latin-1 doesn't to their numeric code points. + +2022-10-01 G. Branden Robinson + + [tmac]: Regression-test Savannah #63112 (2/3). + + * tmac/tests/latin5_works: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-10-01 G. Branden Robinson + + [tmac]: Fix Savannah #63112 (1/3). + + * tmac/latin9.tmac: Replace characters that ISO Latin-1 has but + Latin-9 doesn't. Map characters that ISO Latin-9 has and + Latin-1 doesn't to their numeric code points. + +2022-10-01 G. Branden Robinson + + [tmac]: Regression-test Savannah #63112 (1/3). + + * tmac/tests/latin9_works: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-10-01 G. Branden Robinson + + * src/roff/troff/input.cpp: Refactor to parallelize logic in + similar routines; namely, those handling escape sequences that + accept newlines as argument delimiters. + +2022-10-01 G. Branden Robinson + + * src/roff/troff/input.cpp: Fix inconsistencies in handling of + escape sequences that accept newlines as delimiters. Some threw + spurious warnings as in Savannah #63011; others failed to treat + a newline-terminated escape sequence also as the ending of an + input line. + (do_name_test, do_zero_width): Suppress spurious warning. + (do_zero_width, do_width, do_special): Synthesize newline to + terminate input line. + +2022-10-01 G. Branden Robinson + + * src/roff/groff/tests/\ + some_escapes_accept_newline_delimiters.sh: Add test cases for + `\A` and test formatted output of escape sequences, not just the + absence of diagnostics from permitted use of newlines as + argument delimiters. + +2022-09-29 G. Branden Robinson + + * src/libs/libdriver/input.cpp (do_file): Make use of + positioning commands before the first page is started fatal + errors; they suggest ill-formed input. The 'p' command + clobbers the vertical position anyway. (See + https://bugs.debian.org/421437 for discussion.) + +2022-09-29 G. Branden Robinson + + * tmac/pdf.tmac: Add inclusion guard; if a `pdfmark` macro is + already defined, skip inclusion of this file. Unfortunately + there are multiple name collisions with pdfmark.tmac. + +2022-09-28 G. Branden Robinson + + * src/roff/troff/input.cpp: + * src/roff/troff/request.h: Trivially refactor. Boolify + `interpolate_macro` and `request::invoke`. Also rename + parameter `no_next` to `do_not_want_next_token`, exposing + potentially confusing interface design. + +2022-09-28 G. Branden Robinson + + * src/roff/troff/input.cpp (spring_trap, interpolate_string) + (interpolate_string_with_args): Improve error diagnostics: when + a sprung trap or an interpolation fails because it's being + attempted on a request, say so explicitly and _name_ it. If the + argument to the trap-planting request or to a string + interpolation escape sequence is itself an interpolation, this + name might not be obvious. Consider: + .wh \n[pos] \*[mac] + .em \*[mac] + .itc 1 \*[mac] + \*[\*[mac]] + Supplying this information requires no additional overhead. + +2022-09-28 G. Branden Robinson + + * src/roff/troff/input.cpp (interpolate_string): Trivially + refactor. Rename function parameter from `s` to `nm` to more + obviously align with `interpolate_string_with_args()`. + +2022-09-28 G. Branden Robinson + + * src/roff/troff/input.cpp (do_zero_width, token::description) + (interpolate_string, interpolate_string_with_args) + (token::get_char): Revise diagnostic messages to stop presuming + the identity of the escape character. + +2022-09-28 G. Branden Robinson + + * src/roff/troff/input.cpp (set_escape_char): Recast error + message to describe attempted operation and tell the user what + we're doing about being instructed to use an invalid escape + character. + +2022-09-28 G. Branden Robinson + + * src/roff/troff/input.cpp (read_size): Be more helpful to + ambiguous type size escape sequence users; offer advice in + terms of the current escape character. + +2022-09-28 G. Branden Robinson + + * src/roff/groff/groff.cpp (main): Fix SEGV when exiting + gxditview. The `postdriver` pointer always referred to + allocated memory except when the `-X` option was given; it was + then assigned the address of a #defined string literal. It was + thus statically allocated and an error to attempt to `free()` + it. Duplicate the string on the heap instead so that we can + clean up uniformly regardless of postprocessor. Problem caused + by me when introducing `xexit()` in commit 6769e56aab, 20 June. + +2022-09-28 G. Branden Robinson + + * tmac/e.tmac (@o, n2, sk (f, ++): Consistently call `@err` + macro with `do`. + +2022-09-25 G. Branden Robinson + + * tmac/e.tmac: Initialize new register `_f`, the value of `$m` + {column count} of the previous pending footnote, to zero, + meaning there is no previous pending footnote. + (@o): Emit diagnostic when flushing footnotes into a different + column layout than the pending footnote last added. Set `_f` to + zero. + ((f): Emit diagnostic when enqueueing footnote using a different + column layout than the previous pending footnote used. Set `_f` + to `$m`. + + Fixes . Thanks to Dave + Kemper for the report and discussion. + +2022-09-25 G. Branden Robinson + + * tmac/e.tmac: Explicitly initialize and annotate internal + register `?f`. + +2022-09-08 Nikita Ivanov + + * tmac/ps.tmac: Fallback definitions for glyphs that usually + come from special fonts should use `schar` instead of `fchar`. + {Define fallback special characters using `schar` instead of + `fchar` for glyphs that we do not expect to find in text fonts; + that is, they don't have bold, italic, and bold-italic stylistic + variants. This means all special character definitions in the + file except for rules, ligatures, and digraphs. Problem dates + back to a series of commits from March 2002 to February 2003, + straddling the introduction of the `schar` request in November + 2002. --GBR} + + Fixes . + +2022-09-21 G. Branden Robinson + + [ms]: Slightly simplify new `XN` macro feature to align it more + closely with Berkeley TOC macro behavior; don't prepend the + table of contents entry with the section number (`\*[SN]`). If + desired, a document can define `XN-REPLACEMENT`. This does not + regress "pdfmark.ms" because it uses an alternative, older + implementation of these features from "spdf.tmac". + + * tmac/s.tmac (XH-UPDATE-TOC): Update comments. + (XN-REPLACEMENT): Do it. + +2022-09-20 G. Branden Robinson + + * tmac/pdf.tmac (pdf*href-I): Call `pdf:error` macro by its + correct name. Both this macro file and + contrib/pdfmark/pdfmark.tmac seem to want to use the 'pdf' + prefix for their macro names, with much confusing overlap. + Problem dates back to commit 87046b2948, 2011-07-26. + +2022-09-19 G. Branden Robinson + + * m4/groff.m4 (GROFF_URW_FONTS_CHECK): If Ghostscript or awk are + unavailable, skip only the prepopulation of the URW font search + path instead of the entire check. This way we still locate the + URW fonts if they are in one of several standard locations. + + Fixes . + +2022-09-19 G. Branden Robinson + + [troff]: Trivially refactor. + + * src/roff/troff/input.cpp (do_name_test): Boolify and rename + local variables to..."impredicate" their names. + - bad_char -> got_bad_char + - some_char -> got_some_char + +2022-09-19 G. Branden Robinson + + [grodvi, ...]: Trivially refactor. + + Tidy up #includes of the "assert.h" header, which we locally + provide to ensure a C99-conformant implementation. Drop + inclusion of header from files that don't directly need it, add + it where they do, and spell the inclusion consistently with + double quotes to cue the reader of its local status. + + * src/devices/grodvi/dvi.cpp: + * src/devices/grolj4/lj4.cpp: + * src/libs/libdriver/printer.cpp: + * src/preproc/eqn/box.cpp: + * src/preproc/eqn/delim.cpp: + * src/preproc/eqn/pile.cpp: + * src/preproc/eqn/script.cpp: Add inclusion. + + * src/include/driver.h: + * src/libs/libgroff/fontfile.cpp: + * src/preproc/eqn/eqn.h: + * src/preproc/html/pushback.cpp: + * src/preproc/refer/refer.h: + * src/preproc/tbl/table.h: + * src/utils/addftinfo/addftinfo.cpp: Drop inclusion. + + * src/include/itable.h: + * src/include/stringclass.h: + * src/libs/libbib/linear.cpp: + * src/libs/libbib/search.cpp: + * src/libs/libgroff/color.cpp: + * src/libs/libgroff/font.cpp: + * src/libs/libgroff/nametoindex.cpp: + * src/libs/libgroff/prime.cpp: + * src/libs/libgroff/searchpath.cpp: + * src/preproc/html/pre-html.cpp: + * src/preproc/preconv/preconv.cpp: + * src/preproc/soelim/soelim.cpp: + * src/utils/indxbib/indxbib.cpp: + * src/utils/lkbib/lkbib.cpp: + * src/utils/lookbib/lookbib.cpp: Respell inclusion. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2022-09-18 G. Branden Robinson + + [troff, ...]: Trivially refactor. + + Boolify and rename internal library function from + `invalid_input_char` to `is_invalid_input_char`. + + * src/include/lib.h: Do it. + + * src/libs/libgroff/font.cpp (text_file::next_line): + * src/preproc/eqn/lex.cpp (file_input::read_line): + * src/preproc/eqn/main.cpp (read_line, main): + * src/preproc/pic/lex.cpp (file_input::read_line, + simple_file_input::get, simple_file_input::peek): + * src/preproc/pic/main.cpp (top_input::get, top_input::peek) + (do_file): + * src/preproc/refer/command.cpp (input_stack::push_file): + * src/preproc/refer/refer.cpp (do_file, do_bib): + * src/roff/troff/env.cpp (environment::make_tag): + * src/roff/troff/input.cpp (file_iterator::fill) + (file_iterator::peek, get_char_for_escape_parameter) + (transparent_translate, read_request, asciify) + (input_char_description, read_string, transparent_file, + set_string): Update call sites. + +2022-09-18 G. Branden Robinson + + [troff]: Tweak diagnostic messages. + + * src/roff/troff/input.cpp (token::description) + (input_char_description): Consistently use articles in + descriptive noun phrases. + +2022-09-18 G. Branden Robinson + + [troff]: Tweak diagnostic messages. + + * src/roff/troff/input.cpp (non_empty_name_warning): Say + "identifier", not "name", in diagnostic message; it can be + thrown for attempted assignments to invalid register + identifiers, and some of our documentation refers to identifiers + in the name space shared by requests, macros, strings, and + diversions as "names". + + * src/roff/troff/env.cpp (hyphen_trie::read_patterns_file): + * src/roff/troff/input.cpp (get_char_for_escape_parameter) + (token::usable_as_delimiter, non_empty_name_warning) + (pipe_source, psbb_locator::psbb_locator, open_request) + (opena_request, define_class, pipe_output, system_request): + Consistently say "_is_ not allowed". The zero copula poses too + great a risk of incomprehension IMO. + +2022-09-15 G. Branden Robinson + + [mdoc]: Add internal string `doc-Lk-font` to manage the typeface + in which to render URIs. + + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: Add it. Use roman instead of (Courier) + bold. This is more consistent with man(7)'s `UR` and less with + mandoc(1). + + * tmac/doc.tmac (Lk): Use it instead of `doc-Sy-font`. + +2022-09-15 G. Branden Robinson + + [mdoc]: Fix Savannah #59738. + + * tmac/doc.tmac (Lk): Process further macro arguments more like + other macros do, calling `doc-print-recursive`. This permits + recognition of end-of-sentence punctuation in the argument list. + + Fixes . + +2022-09-15 G. Branden Robinson + + [mdoc]: Regression-test Savannah #59738. + + * tmac/tests/doc_Lk-respect-sentence-ending-punctuation.sh: Do + it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-09-15 G. Branden Robinson + + [mdoc]: Fix code style nit. Rename `doc-arg-limit` to + `doc-arg-count`. This register doesn't track any sort of limit + on the number of arguments you can give to an mdoc(7) macro, or + anything like that. It is simply a count of the number of + arguments visible to the currently operating macro. + + * tmac/doc.tmac: + * tmac/mdoc/doc-common: + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: + * tmac/mdoc/doc-syms: Do it. + +2022-09-13 G. Branden Robinson + + [docs]: Fix errors in documentation regarding which escape + sequences accept newlines as argument delimiters, and other + inaccuracies. + + * doc/groff.texi (Escape Sequences): Cover general cases before + exceptional ones. Leaders can be used as argument delimiters. + Call out letters and numerals as (usually) usable as well. + Correct an almost completely inaccurate list of escape sequences + that accept a newline as an argument delimiter: \A, \b, \o, \w, + \X, and \Z do; \B does not. Correct example of use of newline + as delimiter with \o escape sequence. Stop referring to the + decimal point as an "operator". Drop "newline" from a list of + prohibited delimiters by several escape sequences since it has + already been discussed. + + * man/groff.7.man (Escape sequences): Replace weaksauce cross + reference to our Texinfo manual with a proper discussion of + acceptable delimiters in escape sequences, synced with the + foregoing change. Stop using quotation marks around escape + sequences, except for "\ " which obviously needs it. + + Fixes . Thanks to Dave + Kemper for the report. + +2022-09-13 G. Branden Robinson + + [troff]: Don't throw a spurious warning when using newline as + delimiter with the few escape sequences that permit this. + + * src/roff/troff/input.cpp (do_overstrike, do_bracket, do_width) + (do_special): Do it. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report and Dave Kemper for the discussion. + +2022-09-13 G. Branden Robinson + + [troff]: Add regression test for Savannah #63011. + + * src/roff/groff/tests/\ + some_escapes_accept_newline_delimiters.sh: Do it. + * src/roff/groff/groff.am (groff_TESTS): Run it. + +2022-09-13 G. Branden Robinson + + * src/roff/troff/input.cpp (do_special): Fix code style nit; + align function definition with declaration (internal linkage). + +2022-09-13 G. Branden Robinson + + * src/devices/grops/ps.cpp (ps_printer::special) + (resource_manager::process_file): Fix code style nit. Mark + static structs initialized within functions and never modified + thereafter as `const`. This attempts to work around an apparent + false positive from AddressSanitizer. If it doesn't pacify + ASAN, please explain to me how constant structure members + initialized to string literals and pointers to functions within + the translation unit can ever be null. If that is infeasible, + please report a bug to your compiler vendor. + + Fixes (addresses, at any rate) https://savannah.gnu.org/bugs/\ + ?61643>. Thanks to Bjarni Ingi Gislason for the report. + +2022-09-09 G. Branden Robinson + + [mdoc]: Refactor: relocate most rendering option handling to + "doc.tmac" from "doc-ditroff" and "doc-nroff", cutting down on a + lot of duplication. The `S` register retains separate handling. + + * tmac/doc.tmac: + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: Do it. + +2022-09-09 G. Branden Robinson + + * tmac/mdoc/doc-ditroff (doc-setup-page-layout): In troff mode, + if the user does not define the `LL` register, use the device's + default line length, not 6.5 inches. If the user does not + define the `LT` register, make the default line length for + titles the same as the regular line length, not 6.5 inches + independently of it. This is consistent with man(7)'s handling + of `LL` and `LT`. + +2022-09-09 G. Branden Robinson + + [mdoc]: Support `AD` string to set default adjustment mode. + + * tmac/mdoc/doc-common (Sh): Set adjustment mode to + user-specified default, not troff's default (and not only in + troff mode). + + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: Process `AD` string setting from command + line as man(7) does. + + * tmac/groff_mdoc.7.man (Formatting with groff, troff, and + nroff): Document it. + + * NEWS: Add and update items. + + Fixes part of . + +2022-09-09 G. Branden Robinson + + * tmac/doc.tmac (doc-tag-list): Fix code style nit: don't give + `ad` request a numeric argument. Say `l` instead of `0`. + +2022-09-08 G. Branden Robinson + + [mdoc]: Align inter-paragraph spacing with man(7). + + * tmac/mdoc/doc-common: Use `doc-paragraph-space` when spacing + prior to section and subsection headings instead of spacing by + the 1v default. + * tmac/mdoc/doc-ditroff: Align inter-paragraph distance amount + in troff mode with man(7), reducing to 0.4v from 0.5v. + +2022-09-08 G. Branden Robinson + + * tmac/mdoc/doc-nroff: Map monospaced fonts (CR, CB, CI, CBI) to + standard styles as man(7) has done for 15 years. This silences + warnings from the formatter when a man page attempts to use + fonts from the Courier family in tbl(1) tables, which is about + the only place a reasonable man page attempts such a thing. + +2022-09-07 G. Branden Robinson + + [mdoc]: Stop prefixing center header with name of operating + system. This was hard-coded to "BSD" and stuck on all mdoc(7) + pages using a default manual section number, regardless of host + operating system. Bad idea. Further, the argument to the `Os` + call, if any, or a default, is always disclosed in the left + footer. + + * tmac/mdoc/doc-common: Do it. + (Dt): Initialize `doc-volume` as empty and annotate it; + calling the macro with a numeric second argument overrides the + fallback default of "LOCAL". A slash is no longer needed to + separate a recognized architecture string from the OS name, so + drop it. + + * tmac/tests/doc_smoke-test.sh: Update test expectations. + +2022-09-07 G. Branden Robinson + + [mdoc]: Drop dead code. The register + `doc-volume-operating-system-ateol`, introduced in groff 1.18 + {July 2002}, was being tested but never set to a nonzero value. + In fact, it seems never to have been. + + * tmac/mdoc/doc-common: Get rid of it... + (Dt): ...and the dependent block. + +2022-09-07 G. Branden Robinson + + [mdoc]: Make `Ux` render "Unix" in mixed case. + + * tmac/mdoc/doc-syms (Ux): Do it. Also remove local string + after we're done with it. + + Continues work begun prior to groff 1.22.4 release. + +2022-09-07 G. Branden Robinson + + [mdoc]: Align spacing around headers with man(7). + + * tmac/doc.tmac (doc-save-global-vars, doc-restore-global-vars): + * tmac/mdoc/doc-common (Rd): + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: Stop defining, saving, and restoring + `doc-header-space`. + + * tmac/mdoc/doc-common (doc-header): When starting new document + and not continuously rendering, space by one half-inch instead + of by the now-defunct `doc-header-space` amount (which, + strictly, should not have applied to this measurement). If + continuously rendering, extend page length by 1v to accommodate + header line. After formatting header, if not continuously + rendering, space to 1 inch below first text baseline. + +2022-09-07 G. Branden Robinson + + [mdoc]: Support `C` register for consecutive page numbering. + + * tmac/mdoc/doc-common (Dd): Reset page number to 1 upon new + document only if not consecutively numbering. + + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: Process `C` register setting from command + line as man(7) does. + + * tmac/groff_mdoc.7.man (Formatting with groff, troff, and + nroff): Document it. + + Fixes part of . + +2022-09-07 G. Branden Robinson + + [mdoc]: Align trap management more closely with man(7). + + * tmac/mdoc/doc-common: Call new macro (see below) + `doc-set-up-continuous-rendering` when initializing, if that + mode is configured. + (doc-ne): New macro replaces `ne` request + in continuous rendering mode. It extends the page length by the + amount in the argument or by 1v if none given. + (doc-bp): New macro replaces `bp` request in continuous + rendering mode, setting the page length to the vertical drawing + position. + (doc-set-up-continuous-rendering): New macro renames requests to + emplace the foregoing. + (Dd): Interpret this macro call strictly as starting a new + mdoc(7) document. (andoc.tmac already makes this assumption, + and has for over 20 years. groff_mdoc(7) and mandoc_mdoc(7) + also prescribe the sequence `Dd`, `Dt`, `Os`.) We require this + invariant even more rigidly now because it's the only way we can + be sure that we can process multiple documents while rendering + headers and footers with information corresponding to the + appropriate document. (man(7)'s `TH` has an advantage here in + that calling it is "atomic": from its arguments alone you can + obtain everything you need to know to format the header and + footer. In mdoc(7), permuting the initialization macro order + reliably produces chaos.) Break the page (if necessary) + _before_ processing any arguments (instead of after), to flush + the previous page's footer. Stop calling `doc-set-up-titles` + here; we don't have enough information to do that yet. Also + stop writing the PDF bookmark here, because `doc-document-title` + and `doc-section` will not reflect the new page content yet. + (Os): Once the `doc-operating-system` string content has been + determined, call `doc-set-up-titles`, write the PDF bookmark for + the page, and call `doc-header`, causing the page header to be + formatted. These changes further imply a stronger requirement + on initialization macro ordering being canonical. + + Fixes (7/7). + +2022-09-07 G. Branden Robinson + + [mdoc]: Trivially refactor. Relocate string and macro + definition within file. mdoc(7) mandates that the document + setup macros `Dd`, `Dt`, and `Os` be called in that order; + arrange their definitions accordingly, for maintainability. + +2022-09-06 G. Branden Robinson + + [mdoc]: Refactor. Rename strings and macro for clarity. These + things don't only affect headers. + - doc-header-string -> doc-pageref + - doc-header-string-saved -> doc-pageref-saved + - doc-setup-header -> doc-set-up-titles + + * tmac/doc.tmac: + * tmac/mdoc/doc-common: Do it. + +2022-09-06 G. Branden Robinson + + [mdoc]: Refactor. There is no difference in + `doc-header-string` and `doc-setup-header` between the files + "doc-ditroff" and "doc-nroff", so define them only once, in + "doc-common". + + * tmac/mdoc/doc-common: + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: Do it. + +2022-09-06 G. Branden Robinson + + [mdoc]: Align footer management more closely with man(7). + + * tmac/doc.tmac (doc-save-global-vars, doc-restore-global-vars): + * tmac/mdoc/doc-common (Rd): + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: Stop defining, saving, and restoring + `doc-footer-space`. + + * tmac/mdoc/doc-common (doc-break-body-text): New macro, called + only when not continuously rendering, schedules a page break. + (doc-footer): Stop vertically spacing by `doc-footer-space`, + instead relying upon a trap to move us here. + + * tmac/mdoc/doc-ditroff (doc-setup-header): + * tmac/mdoc/doc-nroff (doc-setup-header): Set traps at the end + of the page where man(7) does by default; break the body text at + 1 inch from the page bottom, and write the footer at ½ inch. + + * tmac/mdoc/doc-nroff (doc-setup-header): Add 1/6 em "thin + space" between man page name and parenthesized section, for + precise parity with doc-ditroff implementation. (`\|` does not + take up any character cells on nroff devices.) + + Fixes (6/7). + +2022-09-06 G. Branden Robinson + + * tmac/mdoc/doc-common (Dt, Dd): Emit diagnostic warnings if + macros called with no arguments. + + Fixes (5/7). + +2022-09-06 G. Branden Robinson + + [mdoc]: Fix code style nit: stop using Control+G as an escape + sequence argument delimiter. This is not necessary in groff and + hasn't been for at least thirty years. See the node/section + "Implementation Differences" of our Texinfo manual. Our mdoc + implementation does not operate in compatibility mode, so using + control characters like this obfuscates input to no advantage. + + * tmac/doc.tmac: + * tmac/mdoc/doc-common: + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: + * tmac/mdoc/doc-syms: Do it. + +2022-09-06 G. Branden Robinson + + * tmac/mdoc/doc-common (doc-footer): Pull more footer concerns + into this macro. Don't bail out if continuously rendering; + instead, format the appropriate footer text if we are. For now, + break the page only if we are not continuously rendering. + (doc-end-macro): Call `doc-footer` instead of formatting footer + here. + + Fixes (4/7). + +2022-09-06 G. Branden Robinson + + * tmac/mdoc/doc-common (doc-end-macro): When continuously + rendering, set the page reference (e.g., "ls(1)") in the right + footer instead of repeating the left footer. Thanks to Ingo + Schwarze for the discussion. + + * tmac/tests/doc_smoke-test.sh: Update expectations of footer + regression test. + + Fixes part of . + +2022-09-06 G. Branden Robinson + + * tmac/mdoc/doc-common (doc-end-macro): Reset strings to reduce + info leaks from one man page to the next. + + Fixes (3/7). + +2022-09-06 G. Branden Robinson + + * tmac/mdoc/doc-common (Dt): Stop reinitializing `doc-volume` + and `doc-section`. This is the job of package initialization + {and, soon, the end-of-input macro}. + + Fixes (2/7). + +2022-09-06 G. Branden Robinson + + * tmac/mdoc/doc-common: Populate default date string + `doc-date-string` with "UNDATED". + (Dd, Dt, Os): Make more orthogonal: stop touching + `doc-topic-name`. It is "doc.tmac"'s job to initialize it and + the `Nm` macro's job to update it. + (Dd): Do nothing if given no arguments. (You can still blank + out the document date with an explicitly empty argument: + .Dd "" + .) + + Fixes (1/7). + +2022-09-06 G. Branden Robinson + + * tmac/mdoc/doc-common: Change `doc-default-operating-system` + string from "BSD" to "GNU", per discussion with Ingo Schwarze. + See . + + * tmac/tests/doc_smoke-test.sh: Update expectations of footer + regression test. + +2022-09-06 G. Branden Robinson + + * tmac/mdoc/doc-common (Dt): Delete lingering and useless + definition of `doc-command-name` string. Thanks to Steffen + Nurpmeso for the report. See commit e9e92ee008, 27 August. + +2022-09-03 G. Branden Robinson + + * src/preproc/pic/pic.ypp (not_lower_than): Emit deprecation + warning for use of 'rand()' with a (non-empty) argument. The + man page has declared it thus for over 30 years, at least since + groff 1.02 (June 1991). + +2022-09-03 G. Branden Robinson + + * src/preproc/pic/pic.ypp (object_spec): Emit deprecation + diagnostic for "plot" command. The man page has declared it + thus for over 30 years, at least since groff 1.02 (June 1991). + +2022-09-03 G. Branden Robinson + + * src/preproc/pic/pic.ypp (placeless_element): Explicitly say + that an unsafe command is being ignored in diagnostic. + +2022-09-03 G. Branden Robinson + + * src/preproc/eqn/main.cpp (main): Drop man page reference from + deprecation diagnostics. The man page might be installed with a + prefix determined at configuration time, and that's too much + trouble to mess with for construction of a message. Trust the + user of these ancient options to try reading the man page with + the same name as the command. + +2022-09-03 G. Branden Robinson + + [docs]: Revise discussion of measurements. + + * doc/groff.texi: Drop Texinfo @codequote* command brackets + around revised sections; relevant nodes have been reviewed for + correct glyph usage. Move concept index entries for obsolescent + term "machine units" to same location as "basic units". + Bump document date. + (Measurements): Rewrite presentation. We have already + introduced page geometry concepts, including the concept of + basic units. + (Motion Quanta): New subsection node; introduce this concept + much sooner, right after measurement units. Relocate + documentation of `.H` and `.V` registers from a miscellaneous + read-only register list here. Introduce example of rounding to + horizontal motion quantum. + (Default Units): Revise discussion. Stop abusing @result + notation in example. + (Built-In Registers): Relocate `.H` and `.V` as above. + + * man/groff.7.man: Sync with Texinfo content updates. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2022-09-02 G. Branden Robinson + + Drop groff_filenames(5) document. It says nothing accurate that + is not covered elsewhere. + + * contrib/groff_filenames: Delete. + * doc/doc.am (GROFF_MAN_PAGES): Drop. + * src/roff/groff/groff.1.man: Drop cross reference to it. + * NEWS: Add item. + + Fixes . + +2022-09-01 G. Branden Robinson + + * src/preproc/tbl/tbl.1.man (Table data): Generalize discussion + of roff control line use in tables. + (Examples): Illustrate how to embed a comment in a table. + +2022-08-31 G. Branden Robinson + + * NEWS: man(7)'s `TS` no longer adds vertical space. See commit + 7ec36dc9b9, 30 July. + +2022-08-28 G. Branden Robinson + + * src/preproc/eqn/main.cpp (main): Issue deprecation warning + upon use of '-p' or '-s' options. The eqn(1) man page has + documented these as deprecated since at least groff 1.02 (June + 1991). Don't count on them sticking around another 30 years. + +2022-08-28 G. Branden Robinson + + * src/preproc/eqn/main.cpp (main): Clarify error diagnostics + regarding invalid option arguments. Identify the option being + handled at the time and characterize the argument as "invalid", + not "bad". + +2022-08-28 G. Branden Robinson + + [eqn]: Drop support for undocumented '-D' option. It has been + undocumented, and issued a warning of its obsolescence upon use, + for 30 years, since groff 1.06 (September 1992). That's plenty + long enough for a deprecation cycle. + + * src/preproc/eqn/main.cpp (main): Do it. + * NEWS: Add item. + +2022-08-27 G. Branden Robinson + + [man]: (EX, EE): Always break line, even if call invalid. + + * tmac/an.tmac (EX, EE): + * tmac/an-ext.tmac (EX, EE): Do it. Ingo Schwarze pointed out + that page authors will expect breaking semantics from these + macros even if using them in an ill-formed way. In a + well-formed document, the breaks are redundant but harmless (the + later `nf` and `fi` requests, respectively, also cause breaks). + +2022-08-27 G. Branden Robinson + + [mdoc]: Trivially refactor. + + * tmac/doc.tmac: + * tmac/mdoc/doc-common: Rename string `doc-command-name` to + `doc-topic-name`; the former is misleading for man pages not in + sections 1, 6, or 8. + +2022-08-25 Bjarni Ingi Gislason + + * man/groff_char.7.man: Fix bad example syntax. + + Fixes . + +2022-08-25 G. Branden Robinson + + [mdoc]: Trivially refactor. + + * tmac/mdoc/doc-common: + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: Stop using "Null" as an empty string + indicator when comparing a string interpolation to an empty + parameter will serve just as well; it is also more idiomatic. + The string in question, `doc-section`, is never formatted if it + is empty anyway; the very tests at issue, which populate + `doc-header-string`, ensure this. + +2022-08-23 G. Branden Robinson + + * src/roff/troff/env.cpp (environment::set_family): Throw error + if user requests a font family that (when combined with the + current style) can't be resolved to a real font name. Fixes a + regression introduced by me in commit d8cb8cf9d8, 2021-09-15, + arising from a revision of font selection logic in node.cpp to + enable a bunch of _other_ font error diagnostics. + + Fixes . Thanks to Dave + Kemper for the report and two useful end points for a bisection. + +2022-08-23 G. Branden Robinson + + * src/roff/troff/env.cpp (environment::set_family): Add some + paranoia. Add `assert()`s on the previous font mounting + position still being valid and the font family dictionary lookup + not returning a null pointer. Add an early return for the + latter case (which should be impossible). + +2022-08-23 G. Branden Robinson + + * src/roff/troff/node.cpp (font_family::make_definite): + Refactor. Rename parameter from inscrutable `i` to + `mounting_position`. Add `assert()` to enforce invariant: we're + passed a mounting position that is nonnegative. Use `pos` as + short alias of parameter once we're into the function body. + Relocate conditional branches to front-load early returns as + well as those requiring little code to handle. This reduces the + average indentation level of the function, a readability win. + +2022-08-23 G. Branden Robinson + + [man]: Restore robustness to `EE` misuse. + + * tmac/an.tmac: Add `an*is-in-example` register to track state + of within-exampleness. Not doing so can cause a spurious use of + `EE` to wrongly set the inter-paragraph distance to zero. + (TH): Initialize register. + (EX): Test register; if set, ignore macro call and, if + `CHECKSTYLE` warnings are on, throw diagnostic. Set register. + (EE): Test register; if clear, ignore macro call and, if + `CHECKSTYLE` warnings are on, throw diagnostic. Clear register. + + * tmac/an-ext.tmac (EX, EE): Similar, using `mX` register. + Because AT&T troff had no `return` request, invert the sense of + the tests and put the entire macro bodies inside conditionals. + + This regressed post-1.22.4. Thanks to Ingo Schwarze for the + report and a proposed patch. + +2022-08-23 G. Branden Robinson + + * tmac/an-ext.tmac: Refactor. Rename `mX` to `mZ` so we can use + `mX` for an "in-example" state register in a future commit. + Rename `mE` to `mF` to store the current font's mounting + position. Bizarrely, `mF` was not already used for this + purpose. + +2022-08-22 G. Branden Robinson + + * src/libs/libgroff/error.cpp (do_error_with_file_and_line): + Trivially refactor. Use separate string constant for invariant + material. (This will make it easier to, for example, store the + diagnostic level strings in an array that can be indexed by + their corresponding `enum` type.) + +2022-08-22 G. Branden Robinson + + * src/roff/troff/input.cpp (fatal_with_file_and_line) + (error_with_file_and_line, debug_with_file_and_line): Align more + closely with GNU Coding Standards regarding diagnostics: don't + suffix the colon after the program name with a space when + location information follows. + +2022-08-22 G. Branden Robinson + + * src/devices/grohtml/grohtml.1.man: Fix erroneous claim. + Images are not generated when "baseline rules" or "box rules" + are encountered in the input. These are troff special + characters; the former is converted to an underscore and the + latter to U+2502, "box drawings light vertical". This remains + true even if a series of them is drawn with the `\l` escape + sequence. (I also checked vertical line drawing with `\L`. + grohtml's handling of that provoked a rather wet eructation from + my lower esophageal sphincter--the output is assuredly not + correct. But it's still not an image.) + +2022-08-22 Deri James + + Bug #62934 - after glyph remapped mark it as used + + When many glyphs are remapped from code points above 255 + such as writing documents in cyrillic with the U-TR fonts, + gropdf starts reusing code points in the range 128-255. + If subsequently one of those code points is actually required, + such as \(em (code 138), and it has been replaced by a + cyrillic, then it needs to be mapped to another free code. + + To determine if a particular code point is free each glyph + has a USED flag. The bug was caused because after remapping + \(em to the next free glyph the USED flag was not set. So the + next new cyrillic character to be entered was given the same + code point as had been allocated to \(em. + + * src/devices/gropdf/gropdf.pl: Set the USED flag on remapped + glyphs. + + Fixes . + + Thanks to Nikita Ivanov for spotting the problem and testing + the fix. + +2022-08-20 Deri James + + Bug #62923 - problem using aliased glyphs + + With a large font if 2 characters above the 255 code + point limit are aliased, the aliased glyph has incorrect meta + data. + + * src/devices/gropdf/gropdf.pl: Instead of duplicating a pointer + to the font metadata, duplicate the data itself. Then, if the + glyph is remapped to a code point under 256, the metadata is + preserved. + + Fixes . Thanks to Nikita + Ivanov for the report. + +2022-08-18 Deri James + + [gropdf]: Improve parsing of troff font files. + + * src/devices/gropdf/gropdf.pl: Allow the glyph code number + to be octal or hex as well as a decimal number. If entity_name + is missing use name instead. + +2022-08-15 G. Branden Robinson + + [ms]: Support pic(1) "flyback" feature. + + * tmac/s.tmac (PF): Add macro; it does what `PE` formerly did, + minus vertical spacing. + (PE): Call `PF` and vertically space as before. + + * doc/groff.texi (ms Insertions): + * doc/ms.ms (Tables, figures, equations, and references): + * tmac/groff_ms.7.man (Tables, figures, equations, and + references): Document it. + + * NEWS: Add item. + + Fixes . + +2022-08-15 G. Branden Robinson + + * tmac/s.tmac (@PS): Validate better; check for 2 arguments + exactly. + +2022-08-14 G. Branden Robinson + + [pic]: Recognize `.PY` as synonym of `.PF`. + + * src/preproc/pic/main.cpp: + * src/preproc/pic/pic.h: Add new Boolean variable, + `want_alternate_flyback` to record `.PY` usage. + + * src/preproc/pic/main.cpp (top_input::get, top_input::peek): + Recognize it. Update diagnostic messages to mention it. + (main): Define `PY` troff macro as empty if not defined. + + * src/preproc/pic/troff.cpp (troff_output::finish_picture): + Don't advance the vertical position if `want_alternate_flyback`. + Write out the `PY` macro call if it was on the input. + + * src/preproc/pic/pic.1.man: Document it. + + * tmac/pic.tmac (PY): Define the same as `PF`. + + * NEWS: Add item. + + Fixes . + +2022-08-14 G. Branden Robinson + + [pic]: Refactor `flyback_flag`. + + * src/preproc/pic/main.cpp: + * src/preproc/pic/pic.h: + * src/preproc/pic/troff.cpp: Rename to `want_flyback`. + + * src/preproc/pic/main.cpp: + * src/preproc/pic/pic.h: Demote type from `int` to `bool`. + + * src/preproc/pic/main.cpp (top_input::get, top_input::peek): + Use parentheses to clarify operation precedence. + +2022-08-14 G. Branden Robinson + + * src/preproc/eqn/eqn.1.man: Expand to include lists of + recognized primitives and predefined macros. + +2022-08-04 G. Branden Robinson + + * NEWS: Add item for new groff mm `V` register support. + +2022-08-04 G. Branden Robinson + + * src/preproc/eqn/lex.cpp (do_delim): Recognize "delim on" even + in compatibility mode, enabling tbl to toggle eqn delimiter + recognition when it is run in compatibility mode as well. + * src/preproc/eqn/eqn.1.man (Controlling delimiters): Update. + * NEWS: Add item. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2022-08-03 G. Branden Robinson + + * tmac/an.tmac (TH): Fix spurious complaint from `CHECKSTYLE` + feature when a custom manual section title is declared for a + standard section number. Thanks to Quentin Monnet for the + report. + +2022-07-31 G. Branden Robinson + + * tmac/pdfpic.tmac: Finish incomplete string renames. Continues + 0fd6ab6b4c, 21 January. + pdfpic*file-name -> pdfpic*file-name-base + pspic-args -> pdfpic*pspic-args + +2022-07-30 G. Branden Robinson + + * tmac/an.tmac (TS): Stop inserting space before tables. Unlike + ms(7), man(7) has no concept of "displays" and thus none of + "display distance". It is up to the page author to use + paragraphing macros around tables if vertical space is desired. + And not up to us to impose it. + + Fixes . + +2022-07-30 G. Branden Robinson + + [man]: Regression-test Savannah #62841. + + * tmac/tests/an_TS-adds-no-vertical-space.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-07-30 G. Branden Robinson + + * src/preproc/tbl/table.cpp (table::do_bottom): Avoid + overprinting a double-boxed table's bottom border on nroff + devices. + +2022-07-30 G. Branden Robinson + + [tbl]: Expand regression test for Savannah #49390. Check for + overlap of double box borders, too. + + * src/preproc/tbl/tests/\ + do-not-overlap-bottom-border-in-nroff.sh: Do it. + +2022-07-30 G. Branden Robinson + + [tbl]: Fix Savannah #49390. + + * src/preproc/tbl/table.cpp (table::do_bottom): Avoid + overprinting a boxed table's bottom border on nroff devices. + + Fixes . Thanks to Osamu + Sayama for the report. + +2022-07-30 G. Branden Robinson + + [tbl]: Regression-test Savannah #49390. + + * src/preproc/tbl/tests/\ + do-not-overlap-bottom-border-in-nroff.sh: Do it. + * src/preproc/tbl/tbl.am (tbl_TESTS): Run test. + +2022-07-28 Deri James + + [gropdf]: Improve slant application to lowercase Greek letters. + + + * tmac/pdf.tmac: Slant only if the glyph is sourced from a + special font, not a regular (text) font containing Greek glyphs. + +2022-07-26 G. Branden Robinson + + * tmac/s.tmac: Add italic correction support to `I` and `BI` + macros. Call `par*define-font-macro` with newly recognized + third argument indicating that italic corrections should be + applied. + (par*define-font-macro): Apply the corrections if directed. + +2022-07-25 G. Branden Robinson + + * src/roff/troff/input.cpp (input_char_description): Clear + static buffer on every entry to the function so that calling it + twice in succession where the second call populates the buffer + with less data than the first doesn't leave garbage characters + in a diagnostic message. Problem appears to date back to 1991 + or earlier. + + Fixes . + +2022-07-25 G. Branden Robinson + + * src/roff/troff/input.cpp (token::usable_as_delimiter): + (do_non_interpreted, interpolate_arg): Recast diagnostic + messages for clarity. + +2022-07-25 G. Branden Robinson + + * tmac/e.tmac: Initialize section number registers. Fixes + warnings when starting section numbering at a depth greater than + 1. + + Fixes . + +2022-07-23 G. Branden Robinson + + * m4/groff.m4 (GROFF_PAGE): Use 'grep -q' instead of redirecting + standard output to null device. The '-q' option was + standardized in POSIX Issue 5 (1997) or earlier. Also drop the + redirection of the standard error stream; we have already + checked the file named in "$descfile" for existence and + readability. grep should thus not emit diagnostic messages. + +2022-07-22 G. Branden Robinson + + * m4/groff.m4 (GROFF_PAGE): Macro used awk(1) without + `AC_REQUIRE`-ing a relevant macro or checking for its existence. + Fortunately, sed is powerful enough for our needs. Remove + dependency on awk. Cope with "search" directive in resolv.conf + having multiple arguments. Match "domain" directive in same + file instead of "dom", which I cannot find attested (this logic + dates to 1991). Rename `dom` shell variable to `domains` for + clarity, since its multiplicity could be greater than 1. + +2022-07-22 G. Branden Robinson + + * m4/groff.m4 (GROFF_PAGE): Refactor: drop AC_DEFINE of + `PAGEA4`. This symbol appears to be a relic; it is nowhere + tested or dereferenced. + +2022-07-15 G. Branden Robinson + + * tmac/tty-char.tmac: Drop definition of \[sd] special + character. This was superseded by commit 78e666246c, 8 May, + which defined a fallback for the character in tty.tmac instead. + Thanks to Dave Kemper for the catch. + +2022-07-15 G. Branden Robinson + + * tmac/tests/pdfpic_does-not-choke-on-bad-pdfinfo-output.sh: + Skip test if "pdfinfo" command not available. + +2022-07-14 G. Branden Robinson + + [build]: Add sanity checks for font description file generation + for PDF output device, prompted by discussion with Ingo + Schwarze. See . + + * font/devpdf/tests/basic-fonts-present.sh: + * font/devpdf/tests/urw-fonts-present.sh: Add files. + + * font/devpdf/devpdf.am (font_devpdf_TESTS): Add the former test + unconditionally, and the latter only if `HAVE_URW_FONTS`. + +2022-07-14 G. Branden Robinson + + * font/devpdf/devpdf.am: Refactor to simplify. Now that + symbol.map lives in the "devpdf/generate" directory along with + the other map files, it doesn't need a dedicated Makefile target + to produce it. + (DEVPDFFONTMAP_1, DEVPDFFONTMAP_2): Coalesce and rename to... + (devpdffontmapdata): ...this. + (font/devpdf/map/symbol.map:): Drop target. + (devpdffontmap_DATA, font/devpdf/download): Update dependencies. + +2022-07-13 G. Branden Robinson + + * font/devpdf/util/BuildFoundries.pl (LoadFoundry): Recast + diagnostic message so that the user understands the consequence + of failure to locate a Type 1 font file (that isn't one of the + base 14 PostScript level 1 fonts): the font will be unavailable + for the "pdf" output device. + +2022-07-13 G. Branden Robinson + + * font/devpdf/util/BuildFoundries.pl (LoadFoundry): Separate + lists of Type 1 font names with spaces as well as commas, for + better diagnostic message readability. Also begin message in + lowercase (per GNU Coding Standards). + +2022-07-13 G. Branden Robinson + + * font/devpdf/util/BuildFoundries.pl (LoadFoundry): Verify that + `$foundrypath->[$j]` is defined before operating on it. + +2022-07-10 G. Branden Robinson + + [afmtodit]: Clarify diagnostic message. + + * src/utils/afmtodit/afmtodit.pl: When we have excess Adobe + Glyph List mappings for a groff special character identifier + {making the reverse mapping from groff special character to font + glyph name ambiguous}, report that we're ignoring the excess. + Use "print STDERR" instead of Perl "warn" built-in since we want + diagnostic messages to start with the name of the program + emitting them. + +2022-07-10 G. Branden Robinson + + [build]: Name and place PS->groff glyph name maps consistently. + + * font/devps/symbolmap: Rename from this... + * font/devps/generate/symbol.map: ...to this. + + * font/devpdf/devpdf.am (font/devpdf/map/symbolmap): Rename + target... + (font/devpdf/map/symbol.map): ...to this. + (font/devpdf/map/symbol.map): Copy "devps" version of file from + its new location in the "generate" subdirectory. + + * font/devpdf/Foundry.in: Reflect rename. + + * font/devps/generate/Makefile (symbolmap): Rename target... + ($(srcdir)/symbol.map): ...to this. + + * font/devps/devps.am (DEVPSGENFILES, EXTRA_DIST): + * font/devps/generate/Makefile (S, EURO $(SPECIALFONTS), clean): + * src/utils/afmtodit/afmtodit.1.man: Reflect rename and + relocation. + + * font/devps/generate/dingbats.rmap: Rename from this... + * font/devps/generate/dingbats-reversed.map: ...to this. + + * font/devps/devps.am (DEVPSGENFILES): + * font/devps/generate/Makefile (ZDR): + * src/utils/afmtodit/afmtodit.1.man: Reflect rename. + + * font/devps/generate/lgreekmap: Rename from this... + * font/devps/generate/slanted-symbol.map: ...to this. + + * font/devps/devps.am (DEVPSGENFILES): + * font/devps/generate/Makefile (SS): + * src/utils/afmtodit/afmtodit.1.man: Reflect rename. + + * font/devps/generate/textmap: Rename from this... + * font/devps/generate/text.map: ...to this. + + * font/devpdf/Foundry.in: + * font/devpdf/devpdf.am (DEVPDFFONTMAP_1): + * font/devps/devps.am (DEVPSGENFILES): + * font/devps/generate/Makefile (TEXTMAP): + * src/devices/gropdf/gropdf.1.man: + * src/devices/grops/grops.1.man: + * src/utils/afmtodit/afmtodit.1.man: Reflect rename. + +2022-07-10 G. Branden Robinson + + * doc/doc.am (doc/ms.ps): Add dependency on "eqn", and call + groff with "-e" option. + * src/utils/grog/tests/smoke-test.sh: Update expected "grog" + output for the ms.ms document. + +2022-07-09 G. Branden Robinson + + * doc/doc.am (doc/ms.ps): Add dependency on "tbl". + +2022-07-08 G. Branden Robinson + + * src/roff/troff/node.cpp (suppress_node::tprint): Add source + file line number after its name when emitting "grohtml-info", to + aid debugging. + +2022-07-08 G. Branden Robinson + + * src/roff/troff/node.cpp (get_register, get_string): Reorder + null pointer inequality comparisons; they don't need to be in a + funny order because it's pretty hard to mistype `!=` as an + assignment operator. Annotate them as null pointers to ease any + future migration to ISO C++11. Use primitive type constructor + instead of C-style cast operator; this seems more idiomatic. + +2022-07-08 G. Branden Robinson + + * src/preproc/html/pre-html.cpp (generateImages): Flush the + standard error stream after writing to it in a loop. + +2022-07-08 G. Branden Robinson + + * tmac/s.tmac (RP): Recognize new optional arguments + `no-renumber` and `no-repeat-info`, the latter as a synonym for + the existing `no`. The former suppresses the page number + manipulation that normally occurs. Drop now-unnecessary `pn 0` + request. + (top level, cov*first-page-init, RP, cov*print): Rename + `cov*rp-format` to `cov*use-rp-format` for clarity. + (cov*break-page): New macro breaks the cover page at the end, + resetting next page number to 1 only if desired by user. + (cov*print, cov*rp-print): Call `cov*break-page` instead of + invoking `bp`. + + * doc/groff.texi (Document Description Macros) : + * doc/ms.ms (Document description macros) : + * tmac/groff_ms.7.man (Document description macros) : + Document them. + + * NEWS: Add item. + +2022-07-08 G. Branden Robinson + + * tmac/s.tmac: Rename register `cov*rp-no` to + `cov*rp-no-repeat-info`. + +2022-07-08 Deri James + + * font/devpdf/util/BuildFoundries.pl (LocateFile): Some systems + store .afm files in a parallel directory to the Type 1 files, + restore original path after checking for parallel directory. + +2022-07-07 G. Branden Robinson + + * font/devpdf/devpdf.am (font/devpdf/download): Call + "BuildFoundries" with new `--strict` option so that the build + fails if the AFM files for the URW fonts can't be found. + +2022-07-07 G. Branden Robinson + + * font/devpdf/util/BuildFoundries.pl: Add Boolean-valued scalar + `beStrict` (defaults false) and new command-line option + `--strict` to make it true. + (LoadFoundry): Check return value of subroutine `LocateAF`. + Emit diagnostic if it is null, as a warning if not "strict", and + fatal if so. + +2022-07-07 G. Branden Robinson + + * font/devpdf/devpdf.am (font/devpdf/util/BuildFoundries): Add + dependency on "afmtodit" since "BuildFoundries" calls this + program when generating groff font description files from URW + fonts. + +2022-07-06 G. Branden Robinson + + [ms]: Fix Savannah #62690. + + * tmac/s.tmac (P1, SC, UC, P2): Drop undocumented support for + document-private macros used by Kernighan & Cherry's + "Typesetting Mathematics -- User's Guide (Second Edition)". + + Fixes . + +2022-07-06 G. Branden Robinson + + [ms]: Fix Savannah #62688. + + * tmac/s.tmac (DE): Set no-space mode when ending displays. + (@EN): Set no-space mode after outputting the display distance + so that it doesn't combine with inter-paragraph space. + + Fixes . + +2022-07-06 G. Branden Robinson + + [ms]: Regression-test Savannah #62688. + + * tmac/tests/s_no-excess-space-around-displays.tmac: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-07-06 G. Branden Robinson + + [ms]: Fix Savannah #62687. + + * tmac/s.tmac (@MC): Honor `MINGW` register even when setting + only two columns, as clearly implied by our documentation. + + Fixes . + +2022-07-06 G. Branden Robinson + + [ms]: Regression-test Savannah #62687. + + * tmac/tests/s_honor-MINGW-when-two-columns.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-07-06 G. Branden Robinson + + [ms]: Fix Savannah #62686. + + * tmac/s.tmac (@MC): Set no-space mode before doing a paragraph + reset, not after: we don't want vertical space at the top of the + first column when entering multi-column mode, because then it + doesn't align with the tops of subsequent columns. + + Fixes . + +2022-07-06 G. Branden Robinson + + [ms]: Regression-test Savannah #62686. + + * tmac/tests/s_mark-column-start-correctly.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-07-06 G. Branden Robinson + + * tmac/s.tmac (IX): Drop. + * NEWS: Add item. + +2022-07-06 G. Branden Robinson + + * tmac/s.tmac: Add "sorry" implementations for documented but + unsupported Unix Version 7 ms macros. This way it's easier to + tell when a historical document needs one and this case is + distinguishable from a document-private macro warned about with + "groff -w mac". + +2022-07-06 G. Branden Robinson + + * tmac/s.tmac (UX): Drop undocumented support for this macro. + This implementation isn't consistent with historical ones, which + identified the trademark holder. But doing that is a problem, + so just stop trying to cope. Also, spelling Unix in full caps + was an imposition by the AT&T legal department on the CSRC. + + "The name Unix is a trademark, originally owned by Bell Labs and + subsequently traded off like a baseball card among a number of + companies." -- Ben Klemens + +2022-07-06 G. Branden Robinson + + [ms]: Replace incomplete documentation of unimplemented macros. + + * doc/groff.texi (Missing ms Macros): + * doc/ms.ms (AT&T ms macros not appearing in groff ms): Drop, + replacing with... + + * doc/groff.texi (Unix Version 7 ms Macros Not Implemented by + groff ms): + * doc/ms.ms (Unix Version 7 ms macros not implemented by groff + ms): + * tmac/groff_ms.7.man (Unix Version 7 macros not implemented by + groff ms): ...these. + +2022-07-06 G. Branden Robinson + + * src/roff/troff/input.cpp (do_translate): Throw an error + diagnostic when the user attempts to translate space characters. + {By contrast, translating _to_ [unbreakable, unadjustable] + spaces is an old troff hack often seen as ".tr ~ ", and largely + superseded by groff's "\~" escape sequence, now widely supported + by other troffs.} + + Fixes . Thanks to T. Kurt + Bond and Oliver Corff for the report. + +2022-07-01 G. Branden Robinson + + * src/roff/groff/pipeline.c: Refactor. Drop function rename via + preprocessor macro usage. Declare and define `c_error` by its + correct name. + (run_pipeline): Update call sites. Stop flushing standard error + stream after calling libgroff's `error` function (which + `c_error` wraps); libgroff already guarantees this operation. + +2022-07-01 G. Branden Robinson + + * src/roff/troff/input.cpp (abort_request): Flush the standard + error stream before exiting, to improve chances of user seeing + any message as arguments to the `ab` request. + +2022-06-28 G. Branden Robinson + + * src/preproc/html/pre-html.cpp + (char_buffer::run_output_filter): Die if platform supports + neither `fork()` nor `spawn()` for child process creation. + +2022-06-27 G. Branden Robinson + + * src/preproc/html/pre-html.cpp (cleanup): Add function to tidy + memory before exiting. + (main): Register aforementioned function with `atexit()`. Die + if registration fails. + +2022-06-27 G. Branden Robinson + + * src/preproc/html/pre-html.cpp (do_file): Die if `fclose()` + fails; such a situation suggests a pretty hosed environment. + +2022-06-27 G. Branden Robinson + + * src/preproc/html/pre-html.cpp (checkImageDir): If `mkdir()` + fails, use `strerror()` to report the underlying problem. + +2022-06-27 G. Branden Robinson + + * src/preproc/html/pre-html.cpp: Refactor. Drop unnecessary + prototype for static function. Use idiomatic C++98 null pointer + constant. Annotate it as null pointer to ease any future + migration to ISO C++11. Boolify. Use C++98 bool data type + instead of preprocessor macros `TRUE` and `FALSE`. Demote some + global Boolean variables from `int` to `bool` and rename some to + be more clear: `show_progress` -> `want_progress_report`; + `debugging`; `eqn_flag` -> `need_eqn`. + (make_message): Rename this... + (make_string): ...to this. Align more closely with contemporary + version of example from Linux man-pages printf(3) page. Use + `vsnprintf()` to determine size of memory buffer needed prior to + allocation instead of iteratively growing it until it is large + enough. Always die if `vsnprintf()` fails: this function now + always returns a valid pointer if it returns at all. + (makeFileName, setupAntiAlias, imageList::createPage, + imageList::createImage): Update call sites to use + `make_string()`. + (char_buffer::can_see): Demote return type from `int` to `bool`. + (char_buffer::skip_spaces): Drop unused member function. + (char_buffer::read_file, makeTempFiles): Demote return type from + `int` to `void`. Stop returning after calling functions that + don't return. + (char_buffer::read_file): Call `sys_fatal()` if `fread()` + returns an error, similarly to other calls into the standard C + library that this file makes. Improve check for error from + `fread()` by not regarding a return value of zero when the + end-of-file indicator is set as an error condition. + (makeFileName, checkImageDir, char_buffer::run_output_filter, + scanArguments): Call `fatal()` instead of `error()` and then + `exit(1)`. + (makeFileName, scanArguments): Dismiss Shlemiel the Painter: + save return value of `strlen()` and call `strcpy()` multiple + times instead of mixing `strcpy()` and `strcat()`; the latter + approach rescans the string unnecessarily. + (char_buffer::run_output_filter): Stop passing unnecessary null + pointer argument to diagnostic message functions. Stop calling + `fflush()` after libgroff diagnostic function, which always + {ultimately} flushes the standard error stream itself. + (makeTempFiles, do_file, main): Boolify. + (makeTempFiles, do_file): Reorder null pointer equality + comparisons to avoid inadvertent lvalue assignment. + (scanArguments, main): Use `EXIT_SUCCESS` and `EXIT_FAILURE` + constants from C library instead of integer literals for exit + status. + (do_file): Demote return type from `int` to `bool`. Return + Boolean literals. Drop conditional with empty consequent. + (main): Declare local variables closer to the points of use. + Stop trying to be a register allocator: stop reusing loop index + variable `i` as integer storage for another (albeit related) + purpose; introduce `operand_index` instead. Clarify logic by + splitting combined initialization and comparison operations, and + by testing function return value directly instead of storing it + in a pointless temporary. Use `EXIT_SUCCESS` and `EXIT_FAILURE` + constants from C library instead of integer literals for exit + status. + +2022-06-27 G. Branden Robinson + + * src/roff/groff/groff.cpp (run_commands): Trivially refactor. + Rename variable for clarity; add comment. + +2022-06-27 G. Branden Robinson + + * src/preproc/html/pre-html.cpp + (char_buffer::run_output_filter): Return wait status of child + process. + (char_buffer::run_output_filter, main): Rename local variable + `status` to `wstatus` to recognize distinction between exit + status (a 7-bit quantity) and wait status (a wider type). + (main): Issue fatal diagnostic if child process exited with + nonzero status. Since the child's output to the standard error + stream is lost, advise re-running with different output driver + to see them. This unhappy shortcoming is filed as Savannah + #62673. Explicitly return zero otherwise. + + Fixes . + +2022-06-22 G. Branden Robinson + + * src/roff/groff/tests/ab_works.sh: Add regression test for + Savannah #60782. + +2022-06-22 G. Branden Robinson + + [troff]: Trivially refactor. + + * src/roff/troff/input.cpp (token::next): Rename statement label + to use documentary terminology. + * src/roff/troff/node.cpp (make_composite_node) + (make_glyph_node): Make functions static since nothing outside + this translation unit calls them. + * src/roff/troff/node.cpp (make_glyph_node): Refactor optional + argument and its usage. Put it down, flip it, and reverse it. + That is, demote its type from `int` to `bool`, invert its sense, + and rename it since it affects warning, not error, diagnostics. + (character_exists): Update only call site of `make_glyph_node()` + that uses non-default argument value. + +2022-06-22 G. Branden Robinson + + [troff]: Adjust diagnostic message text to clarify and better + match terminology used in documentation. + + * src/roff/troff/input.cpp (set_escape_char, do_overstrike) + (do_bracket, do_name_test, do_width, do_special): + * src/roff/troff/node.cpp (suppress_node::tprint): Migrate from + "escape" to "escape sequence". + + * src/roff/troff/node.cpp (make_composite_node) + (make_glyph_node): Clarify what went wrong. + + * src/roff/troff/input.cpp (token::get_char) + (check_missing_character): Migrate from "normal character" to + "ordinary character" (see groff_char(7)). + +2022-06-22 G. Branden Robinson + + [troff]: Rename a function for clarity. + + * src/roff/troff/input.cpp (add_to_node_list): Rename this... + (add_to_zero_width_node_list): ...to this. + (do_zero_width): Update call site. + * src/roff/troff/token.h: Update declaration. + +2022-06-22 G. Branden Robinson + + * src/roff/groff/groff.cpp (handle_unknown_desc_command): + Refactor to skip unnecessary string comparisons. We explicitly + return in the final case instead of falling off the end of this + void function for consistency if additional cases are added. + +2022-06-22 G. Branden Robinson + + * src/roff/groff/groff.cpp (handle_unknown_desc_command): + Partially revert commit 64dc40d23a, 19 June. I forgot to save + and restore the previous values of the globals + `current_filename` and `current_lineno`, and, noticing that this + function has 3 return paths, decided that it's cheaper just to + go back to `error_with_file_and_line()`. + +2022-06-21 Deri James + + [gropdf]: Add more search paths to the Foundry file. + + * font/devpdf/Foundry.in: Use the directory specified with the + config flag --with-urw-fonts-dir to populate the default foundry + as well as the U foundry. Important to populate the download + file with font files to embed the fonts not part of the base + pdf fonts or if user wants all fonts embedded. + +2022-06-21 G. Branden Robinson + + * tmac/an-ext.tmac (UR, MT): Fix problem with hyphenation + occurring before the end of the line when the line length was + not the device default (common for man pages at the terminal) + and hyperlinks were enabled. The issue is that the new + environment we created inherits the default environment's line + length (its state at troff initialization, prior to macro + package loading and configuration). This latent issue was + exposed by post-groff 1.22.4 changes to enable the hyphenation + of link text and add the hyperlink feature. Fix it by copying + the line length at the time the macro is called, which is + necessarily after man(7) sets up the line length, to the new + environment. + +2022-06-21 G. Branden Robinson + + * src/devices/grops/psrm.cpp (resource_manager::output_prolog): + (resource_manager::supply_resource): + (resource_manager::read_download_file): Update diagnostic + message language and report underlying problem encountered by + system when failing to open files. This will probably be the + text for ENOENT in most cases, but should help avoid frustration + in those where it isn't. + +2022-06-20 G. Branden Robinson + + * src/devices/grops/psrm.cpp + (resource_manager::read_download_file): Align diagnostic message + wording with gropdf in the same circumstance. + +2022-06-20 G. Branden Robinson + + [troff]: Throw warning in font category when a font selection + escape sequence is used after the output line continuation + escape sequence on an input line, because it is ignored. + + * src/roff/troff/env.cpp (environment::set_font): Do it. + + * doc/groff.texi (Warnings): + * src/roff/troff/troff.1.man (Warnings): Document it. + +2022-06-20 G. Branden Robinson + + * src/roff/troff/env.cpp (font_change): Boolify. + +2022-06-20 G. Branden Robinson + + * src/devices/gropdf/gropdf.pl (LoadFont): Revise error message + when a font can't be found for embedding. User failure to add + an entry for locating the font file seems a more likely scenario + than outright corruption of the file. + +2022-06-20 G. Branden Robinson + + * src/roff/troff/env.cpp (font_change): Warn upon selection of a + nonexistent font name. + + Fixes . + +2022-06-20 G. Branden Robinson + + [troff]: Revise `environment::set_font` to return Boolean value + indicating success of font selection operation. + + * src/roff/troff/env.cpp (environment::set_font): + * src/roff/troff/env.h (environment::set_font): Do it. + + This prepares the way for a fix for Savannah #62656. + +2022-06-20 G. Branden Robinson + + * src/roff/groff/groff.cpp: Use single exit path, freeing + memory allocated for strings. + (xexit): Add `exit()` wrapper; free allocated memory. + (main): Use it in all three exit paths. + +2022-06-20 G. Branden Robinson + + * src/roff/groff/groff.cpp: Refactor to be more meticulous with + memory. Add globals `saved_path`, `groff_bin_path`, and + `groff_font` to store pointers into the process environment + returned by `putenv()`; once used, they need to remain valid for + the lifetime of the program. + (xstrdup): Add `strdup()` wrapper: dies if `strdup()` fails. + (main): Split nested `strsave()` and `xputenv()` (until recently + `putenv()`) calls. Free duplicate strings prior to exit. + +2022-06-19 G. Branden Robinson + + * src/roff/groff/groff.cpp (main): Rename temporary variable to + avoid shadowing one in enclosing scope, which can lead to + cut-and-paste errors (ask me how I know). + +2022-06-19 G. Branden Robinson + + * src/roff/groff/groff.cpp: Slightly refactor to indirect + `putenv` calls through an error-checking wrapper. + (xputenv): Add new function to die if `putenv()` fails. + (main): Update call sites to use it. + +2022-06-19 G. Branden Robinson + + [groff]: Add information to diagnostic messages. + + * src/roff/groff/groff.cpp (main): Report underlying system + error if `putenv()` fails. + (handle_unknown_desc_command): Set globals `current_filename` + and `current_lineno` from `filename` and `lineno` arguments + passed to us to we can use the simpler interface of `error()` + rather than `error_with_file_and_line()`. + +2022-06-19 G. Branden Robinson + + [libgroff]: Update return type of `font::load_desc` function to + enable more informative diagnostics from callers. + + * src/include/font.h (font::load_desc): Change return type from + `bool` to `const char` pointer. + * src/libs/libgroff/font.cpp (font::load_desc): Return null + pointer literal on failed `open()` or validation failures. + Return filespec on success. + + * src/libs/libdriver/input.cpp (do_file): + * src/preproc/grn/main.cpp (getres): + * src/roff/groff/groff.cpp (main): + * src/roff/troff/input.cpp (main): Compare `font::load_desc()` + return value to null pointer literal instead of treating it as a + Boolean. + + * src/roff/groff/groff.cpp (main): Report full filespec of + troublesome "DESC" file when complaining of missing "postpro" + directive. + +2022-06-18 G. Branden Robinson + + * src/roff/groff/groff.cpp: Add new Boolean global, + `need_postdriver`, and initialize it true. + (main): Make `need_postdriver` false if the `-X` or `-Z` options + are given. Test it later. This prevents groff from exiting + with a fatal error if an output driver is not available, but + also not required. Also reorder null pointer equality + comparison to avoid inadvertent lvalue assignment. + + Fixes . + +2022-06-16 G. Branden Robinson + + * src/roff/groff/groff.cpp (help): Revise usage message for + expressiveness and clarity. + +2022-06-21 Deri James + + [gropdf]: Correct display of pathnames used. + + * font/devpdf/util/BuildFoundries.pl: Convert array to + string of pathnames. + +2022-06-21 Deri James + + [gropdf]: Fix to gropdf. + + * src/devices/gropdf/gropdf.pl: If pdfbookmark was called + within 5p of top of page (e.g. straight after a .bp when + \n[nl] was zero) the click destination would be off by a + page. + +2022-06-19 Ingo Schwarze + + * font/devpdf/devpdf.am: Always build PDF font description + files. + + Build font/devpdf/download and the various TR, TB, CR etc. + files in the same directory even when they are not required + by the build because USE_GROPDF is unset, usually because + ghostscript is either unavailable or deliberately disabled + by the person running the build. These files need to be + built and installed anyway, and can be used on the target + system when the required infrastructure is available at run + time. + +2022-06-15 G. Branden Robinson + + [docs]: Revise introduction of vertical spacing concept to avoid + render inference that the formatter will compute a vertical + spacing appropriate to the type size automagically--it will not. + + Fixes . Thanks to Dave + Kemper for the report. + +2022-06-15 G. Branden Robinson + + [docs]: Revise discussion of end-of-sentence detection. + + * doc/groff.texi (Filling): + * man/roff.7.man (Concepts): Do it. "Spaces" is a now a term + with a much more restricted usage. Emphasize the input context, + now explicitly identified as plain text files with Unix line + endings. + + Fixes (one hopes) . + Thanks to Ingo Schwarze for the report and Dave Kemper for the + discussion. + +2022-06-10 Deri James + + [gropdf]: Changes to BuildFoundries. + + * font/devpdf/util/BuildFoundries.pl: Collect search paths into + an array rather than a colon delimited string, this allows + the @PATH_SEPARATOR@ character (':' or ';') to be used to + delimit paths yielded by the command 'gs -h' but still use ':' + to delimit paths in the Foundry file. This means the same + Foundry file can be used on all systems. + + * font/devpdf/Foundry.in: Add more likely paths to find the URW + fonts. + +2022-06-09 G. Branden Robinson + + [build]: Weaken dependency on TeX, instead using it (to generate + the DVI and PDF forms of our Texinfo manual) only if it is + available. + + * m4/groff.m4 (GROFF_USE_TEX_CHECK): Check for presence of 'tex' + executable in path. Set shell variable `groff_use_tex` to "yes" + if present, and "no" otherwise. This check runs only if the + 'makeinfo' and 'texi2dvi' version checks have already passed. + + * configure.ac: Run the new check. Set Automake conditional + `USE_TEX` only if shell variable `groff_use_tex` is "yes". + Report whether "groff.dvi" and "groff.pdf" are (re-)buildable. + + * doc/doc.am: Parameterize names of groff.{dvi,pdf} targets as + Make macros `GROFF_DVI` and `GROFF_PDF`. Define them only if + `USE_TEX`. Do _not_ update `EXTRA_DIST` macro; leave the + literal file names there because we require that distribution + archives contain these files. + (.texi.dvi, .texi.pdf): Update suffix rules to check `USE_TEX` + and fail, complaining of missing 'tex' program, if these targets + are attempted without it being true. Only manually specifying + the file names as targets to 'make' or attempting to generate a + distribution archive without TeX present should cause these + errors. + + * INSTALL.REPO: Update dependency information. + + Fixes . Thanks to Deri + James for the report. + +2022-06-09 G. Branden Robinson + + * doc/doc.am (.texi.dvi, .texi.pdf, $(DOC_GNU_EPS)): Quote names + of programs when aborting because they're missing. + +2022-06-09 G. Branden Robinson + + * m4/groff.m4 (GROFF_PROG_MAKEINFO, GROFF_PROG_TEXI2DVI): + Largely revert commit d5013ededc, 21 May: run checks for + 'makeinfo' and 'texi2dvi' programs regardless of presence of + ".tarball-version" file. Their presence is a necessary (but not + sufficient) condition for refresh of formatted forms of our + Texinfo manual if the source is modified. + + Begins addressing . + +2022-06-08 G. Branden Robinson + + [build]: Rename some groff Autoconf macros to better match + Autoconf's own naming conventions. + + * m4/groff.m4 (GROFF_MAKEINFO): Rename to... + (GROFF_PROG_MAKEINFO): ...this. + (GROFF_TEXI2DVI): Rename to... + (GROFF_PROG_TEXI2DVI): ...this. + + * configure.ac: + * m4/groff.m4 (GROFF_TEXI2DVI): Update call sites. + +2022-06-07 G. Branden Robinson + + * tmac/an.tmac (SH, SS, B, I, SM, SB): Set input trap with `it` + instead of `itc` for better Unix Version 7 man(7) compatibility. + + Fixes . Also see + discussion at + https://lists.gnu.org/archive/html/groff/2022-06/msg00020.html + et sequentia (amid a vigorous bikeshedding of `\&`'s name). + +2022-06-07 G. Branden Robinson + + [man]: Regression-test use of input traps. + + * tmac/tests/an_use-input-traps-correctly.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-06-06 G. Branden Robinson + + * src/devices/gropdf/gropdf.pl (LoadDesc): Validate device + description file for essential directives and acceptable values + as grops(1) does. + +2022-06-04 G. Branden Robinson + + [troff, grohtml, grops, grotty]: Update wording of diagnostic + messages to refer to "motion quantum" rather than "resolution" + where appropriate. + + * src/devices/grohtml/post-html.cpp + (html_printer::html_printer): + * src/devices/grops/ps.cpp (ps_printer::ps_printer): + * src/devices/grotty/tty.cpp (tty_printer::set_char) + (tty_printer::add_char, tty_printer::end_page): + * src/roff/troff/env.cpp (line_length, title_length): Do it. + +2022-06-04 G. Branden Robinson + + * src/devices/gropdf/gropdf.pl: Do more "DESC" file validation. + (LoadDesc): Bomb out gracefully if any of "unitwidth", "res", or + "sizescale" missing from "DESC" file. This prevents Perl + warnings about use of uninitialized values, and undoubtedly + mangled output. + +2022-06-04 G. Branden Robinson + + * src/devices/gropdf/gropdf.pl: Revise diagnostic message + handling. + (top level): Add new scalar `progname` to house executable name. + (Msg): Output messages in format recommended by GNU Coding + Standards manual. Identify who's talking (Savannah #52463). + Rename `lev` scalar to `fatal` since it is used only as a + Boolean for immediately exiting with failure status. Report + diagnostic severity as part of message. + (Warn, Die): Add new subroutines through which all diagnostics + are now emitted. + (top level): Migrate a use of Perl `die` builtin to our `Die`. + (top level, ToPoints, LoadDownload, LoadDesc, do_x, GetPoints, + LoadSWF, LoadPDF, LoadStream, BuildStream, ParsePDFHash, + LoadFont, GetType1, GetChunk, RemapChr, do_N): Migrate `Msg(0, + ...)` calls to `Warn` and `Msg(1, ...)` to `Die`. Begin + messages in lowercase (GNU Coding Standards). Recast a few + messages for clarity. + + Continues the long process of fixing Savannah #52463. + +2022-06-04 G. Branden Robinson + + * src/devices/gropdf/gropdf.pl (Load_Config): Drop unused + subroutine and its commented-out call site, which came in that + way in July 2011. + +2022-06-04 G. Branden Robinson + + * src/devices/gropdf/gropdf.pl (LoadFont): Warn if a font to be + embedded in PDF output cannot be located in the "download" file. + + Fixes . Thanks to Deri + James. + +2022-06-04 G. Branden Robinson + + * tmac/a4.tmac: Drop file from distribution. It has been + superseded by papersize.tmac for nearly 20 years. + * tmac/tmac.am (TMACNORMALFILES): Delete reference. + * NEWS: Add item. + + Fixes . + +2022-06-03 G. Branden Robinson + + [build]: Parameterize X11-related man pages, so they don't get + spuriously generated (and not cleaned) when building with X11 + support disabled. + + * Makefile.am (.man): Fix logic nit: drop unnecessary removal of + target before clobbering it with sed. + * src/devices/xditview/xditview.am (GXDITVIEW_MAN1): Add new + macro, expanding to nothing if `WITHOUT_X11` and to the target + name otherwise. + (man1_MANS): Append `GXDITVIEW_MAN1` expansion, not a literal. + * src/devices/xditview/xditview.am (XTOTROFF_MAN1): Add new + macro, expanding to nothing if `WITHOUT_X11` and to the target + name otherwise. + (man1_MANS): Append `XTOTROFF_MAN1` expansion, not a literal. + * doc/doc.am (GROFF_MAN_PAGES1): Append foregoing expansions + instead of literals. + +2022-06-03 G. Branden Robinson + + * configure.ac: Add `AM_CONDITIONAL`: `HAVE_URW_FONTS`, so our + Automake files can more easily cope with their absence. + * font/devpdf/Foundry.in: Add easily matched phrases to + comments, to clearly delimit the URW foundry portion of the file + so it can be omitted if those fonts are absent. + * font/devpdf/devpdf.am (font/devpdf/Foundry): Generate file + differently depending on `HAVE_URW_FONTS`; keep the existing + procedure if true, and delete the URW section from the generated + file otherwise, avoiding diagnostic messages from afmtodit(1) + and our BuildFoundries script. + + Fixes . + +2022-06-03 G. Branden Robinson + + * font/devpdf/devpdf.am (font/devpdf/util/BuildFoundries): + Generate script using the `PATH_SEPARATOR` Automake macro. + * font/devpdf/util/BuildFoundries.pl: Add `pathsep` scalar to + house the build-time path separator. + (LocateFile): Use it. + (LoadFoundry, CheckFoundry): Stop using spaces as part of the + path separation delimiter. It is not idiomatic. + +2022-06-02 G. Branden Robinson + + * configure.ac: Explicitly identify poppler tools in report. + +2022-06-02 G. Branden Robinson + + * font/devpdf/util/BuildFoundries.pl: Trivially refactor. Drop + unused hash `foundry`. Drop scalar `warn` that was set and + updated but never tested. + +2022-06-02 G. Branden Robinson + + * font/devpdf/util/BuildFoundries.pl: Alter script to write to + the standard output stream instead of (re)writing a file named + "download" in the current working directory. This recovers from + a problem I introduced in commit 6e62be835d, 2 May, as an + unforeseen side effect of improving build parallelism so that + the "download" file wouldn't be read until it was fully + populated. As a side benefit, this approach is more Unixy, and + less dependent on $PWD. + (top level): Stop calling `WriteDownload` with an argument. + (LoadFoundry): Close only the file handle of interest when done, + not all of them (including `STDOUT`, which we now need). + (CheckFoundry): Same--just for cleanliness, since at present + running the script in 'check' mode doesn't write to any streams. + (WriteDownload): Stop taking an argument and manipulating file + handles. Write download file to standard output. + (LoadDownload, WriteDownload): Drop `top` scalar, used as a + mutex to serialize read and write access to "download" file; it + is no longer needed since the "download" file is now only read. + +2022-06-01 G. Branden Robinson + + [build]: Rename shell variables and Autoconf/Automake macros of + Boolean sense to have names more like logical predicates and + avoid doofy "DONT" nomenclature. + + * m4/groff.m4 (GROFF_MAKE_RM): Rename shell variable + `groff_is_rm_defined` to `groff_make_defines_rm` (purely for + clarity; it already had a good name). + (GROFF_MAKE_RM): Rename this... + (GROFF_MAKE_DEFINES_RM): to this, to make parallelism obvious, + and enabling... + * configure.ac: ...rename of `MAKE_DONT_HAVE_RM` to + `MAKE_DEFINES_RM` with sense of test reversed. Also interpolate + `GROFF_MAKE_DEFINES_RM` instead of `GROFF_MAKE_RM`. This in + turn enables... + * Makefile.am: ...revision of conditional from + `MAKE_DONT_HAVE_RM` to "!`MAKE_DEFINES_RM`". + +2022-06-01 G. Branden Robinson + + * m4/groff.m4 (GROFF_URW_FONTS_PATH) + (GROFF_WITH_COMPATIBILITY_WRAPPERS, GROFF_APPDEFDIR_OPTION) + (GROFF_UCHARDET): Recast help strings to more closely parallel + structure and style of Autoconf's own help strings. + (GROFF_WITH_COMPATIBILITY_WRAPPERS): Recast to tighten wording. + +2022-06-01 G. Branden Robinson + + * configure.ac: + * m4/groff.m4 (GROFF_APPDEFDIR_OPTION, GROFF_APPDEFDIR_DEFAULT) + (GROFF_APPDEFDIR_CHECK): Rename m4 macros and shell variable + from "*appres*" to "*appdef*. Update interpolation sites. + + * configure.ac: + * m4/groff.m4 (GROFF_APPDEFDIR_CHECK): Further rename this... + (GROFF_APPDEFDIR_NOTICE): ...to this, for consistency with other + post-report output macros. + + * Makefile.am: + * PROBLEMS: + * doc/automake.mom: + * src/devices/xditview/xditview.am: Update interpolation sites + of `appresdir`. + + * Makefile.am: + * src/devices/xditview/gxditview.1.man: + * src/roff/groff/groff.1.man: Update interpolation sites of + `APPRESDIR`. + + * NEWS: Add item. + +2022-06-01 G. Branden Robinson + + * m4/groff.m4 (GROFF_X11, GROFF_UCHARDET): Drop redundant + messages (which are easily overlooked amid the torrent of + "checking" output anyway). Discovery failures of X11 and the + uchardet library are already parts of the configuration report + at or near the end of output. + +2022-06-01 G. Branden Robinson + + * m4/groff.m4 (GROFF_PNMTOPS_NOSETPAGE): Partially revert change + from 21 May and document why in a comment. + +2022-06-01 G. Branden Robinson + + * tmac/troffrc: Skip loading of "papersize.tmac" if not in troff + mode. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2022-05-31 G. Branden Robinson + + * configure.ac: Report use of "g" prefix for commands and macro + package compatibility wrappers. + * m4/groff.m4 (GROFF_G): Fix code style nits. Update + indentation to match recent practice. + +2022-05-31 G. Branden Robinson + + * configure.ac: Fix code style nits and tweak report. Stop + superfluously using braces for shell parameter expansions that + don't require them. The shell is not make(1). Say + "installation _directory_ prefix" since another kind of prefix + can be used by groff (the "g" in front of command and macro + package names shared with AT&T troff). + +2022-05-31 Dave Kemper + + * doc/groff.texi: Fix content and style nits. + - Remove redundancy ("fixed-width... character that can't be + adjusted"). + - Fix incorrect word ("environment value" -> "environment + variable"). + - Add or change the placement of a couple tie{}s to comport + with style-guide recommendation. + - Grammarify. + - Clarify and tighten wording. + + Fixes . + +2022-05-30 G. Branden Robinson + + * src/roff/troff/node.cpp (font_position): If mounting a font + fails and a third argument was given (to the `fp` request), + report its value in the diagnostic message. This could reveal a + prohibited attempt at directory traversal. See commit + a891161bc9, 7 November. + +2022-05-30 G. Branden Robinson + + * src/libs/libgroff/fontfile.cpp (font::open_file): Refactor. + Move more logic, including memory allocation, inside conditional + that accepts only file names without '/' characters, skipping + unnecessary work in the alternative. Annotate use of zero + literals as null pointers to ease any future migration to ISO + C++11. Add 'const' qualifier to variable that doesn't require + modification (and which is used in the LHS of an equality + comparison, so that clumsy operator misuse will provoke a + compiler warning). + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2022-05-30 G. Branden Robinson + + * configure.ac: In configuration report, say that we're + reporting compiler options along with the compiler executable. + Fix leftover test(1) comparison with garbage, overlooked in + commit faa22d89d2, 20 May. + +2022-05-30 G. Branden Robinson + + * doc/doc.am (doc/meintro_fr.ps): Build with '-t' option. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2022-05-28 G. Branden Robinson + + * src/roff/groff/groff.1.man (Options) <-l>: Handle case where + no default print spooler is configured, and report formatter + behavior correctly if it isn't. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2022-05-28 G. Branden Robinson + + * Makefile.am (.man): Process '@PSPRINT@' substitutions with + "makevarescape.sed". + +2022-05-26 G. Branden Robinson + + * m4/groff.m4 (GROFF_PROG_YACC, GROFF_MAKEINFO, GROFF_TEXI2DVI): + Fix logic error in detection of build scenario: the presence of + a ".git" directory is not an indicator that we're not building + from a distribution archive, because we might be building from a + snapshot archive (which also lacks it). Instead, perform checks + required only by builds from Git checkouts and snapshot archives + if the ".tarball-version" file is not present. + +2022-05-26 G. Branden Robinson + + * Makefile.am (EXTRA_DIST): Ship "HACKING" file. + +2022-05-26 G. Branden Robinson + + * bootstrap.conf: Add "pkg-config" to `buildreq`. Not having it + causes pretty horrible macro expansion problems and diagnostics + when 'autoreconf' is run; they're still pretty bad even if you + use `AC_REQUIRE` and `m4_pattern_forbid`. So just demand it. + +2022-05-25 G. Branden Robinson + + * font/devps/S: + * font/devps/symbolmap: Drop excess mapping of `*U` special + character. groff maps it to the Adobe Glyph List name + 'Upsilon1'. (The AGL 'Upsilon' is a homoglyph of the Latin + capital 'Y'.) + * PROBLEMS: De-document build-time warning, now resolved. + +2022-05-25 G. Branden Robinson + + * src/utils/afmtodit/afmtodit.tables: Regenerate using Unicode + 14.0. No substantive changes. + +2022-05-25 G. Branden Robinson + + * src/utils/afmtodit/make-afmtodit-tables: Refactor. Drop + unused variable `prog`. Use value of `CPP` from environment (if + defined) and use parameter expansion to apply a default if null + or not set. Use for loop to eliminate duplicative if statement. + Test input files for readability, not just existence. Use more + portable test(1) and shell syntax. Swap usage error and fatal + error exit statuses; using "1" for failure and "2" for usage + errors is more common in shell scripts I've seen. Update usage + message to put non-literal parameter in full caps, and clarify + its name. Update comment blocks written to generated files to + further clarify data provenance. + +2022-05-25 G. Branden Robinson + + * m4/groff.m4 (GROFF_PRINT): Refactor. Stop performing checks + for spooler options if none is available. Stop redundantly + reporting command name used for spooling PostScript files. If + an option is required for spooling DVI files, report it alone + instead of repeating the command name as well. + +2022-05-25 G. Branden Robinson + + Fix insensitivity of groff(1) man page to configured spooler. + + * Makefile.am (.man): Replace `@PSPRINT@` in man page sources + with name of configured print spooler command. + * src/roff/groff/groff.1.man (Options) <-l>: Use configured + print spooler command instead of literal 'lpr'. + +2022-05-24 G. Branden Robinson + + * m4/groff.m4 (GROFF_UCHARDET_CHECK): Fix grammar nit in failure + message when user demands uchardet support but the library + cannot be located. + +2022-05-24 G. Branden Robinson + + * m4/groff.m4 (GROFF_CHECK_GROHTML_PROGRAMS): Fix logic error in + computation of verb to be used in notice message. + +2022-05-24 G. Branden Robinson + + * m4/groff.m4 (GROFF_PROG_YACC, GROFF_URW_FONTS_CHECK) + (GROFF_WITH_COMPATIBILITY_WRAPPERS, GROFF_UCHARDET_NOTICE): + Improve shell code portability. Per the GNU Autoconf manual, + "The -a, -o, '(', and ')' operands are not present in all + implementations, and have been marked obsolete by Posix 2008. + ...portable uses of test should never have more than four + arguments, and scripts should use shell constructs like '&&' and + '||' instead." + +2022-05-24 G. Branden Robinson + + * src/roff/groff/groff.1.man (Installation directories): Don't + output a tagged paragraph for the X11 application defaults + directory if the build symbol '@APPRESDIR@' is not defined (that + is, we didn't build with X11 support). + +2022-05-24 G. Branden Robinson + + * m4/groff.m4 (GROFF_GHOSTSCRIPT_VERSION_CHECK): Fix code style + nits. Use lowercase for shell variables we define. Don't quote + literal operands to test(1) that don't contain syntactically + shell-significant characters. Update indentation to match + recent practice. + +2022-05-24 G. Branden Robinson + + * m4/groff.m4 (GROFF_URW_FONTS_NOTICE): Don't emit the notice if + Ghostscript isn't available, since it was a prerequisite for + the `GROFF_URW_FONTS_CHECK` macro in the first place. + +2022-05-24 G. Branden Robinson + + [build]: Add print spooler determination to configuration + report. + + * m4/groff.m4 (GROFF_PRINT): Add shell variable + `groff_have_spooler` to house the name of the print spooler + {"lp" or "lpr"} or the word "no". + * configure.ac: Report determined spooler, or its absence. + +2022-05-24 G. Branden Robinson + + * src/preproc/preconv/tests/do-not-seek-the-unseekable.sh: Skip + seekability check of the standard input stream if there is no + controlling terminal. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2022-05-24 G. Branden Robinson + + * m4/groff.m4 (GROFF_CHECK_GROHTML_PROGRAMS): Migrate from + `AC_FOREACH` to `m4_foreach` to avoid obsolescence warning from + GNU Autoconf 2.70 or later. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2022-05-22 G. Branden Robinson + + * man/groff.7.man: Rename "pilot" list macros for man(7) from + `BL`/`EL` to `LS`/`LE`, per suggestion from Alejandro Colomar. + +2022-05-21 G. Branden Robinson + + * m4/groff.m4 (GROFF_MAKEINFO, GROFF_TEXI2DVI): Check for + makeinfo(1) and texi2dvi(1) programs only if building from Git, + not a distribution archive. + +2022-05-21 G. Branden Robinson + + * doc/doc.am (doc/meintro_fr.ps): Call groff with `-K utf8` + instead of `-k`, in case the "configure" script didn't find + uchardet (and preconv(1) thus can't auto-detect an encoding). + + Fixes . + +2022-05-21 G. Branden Robinson + + * src/preproc/preconv/tests/do-not-seek-the-unseekable.sh: Skip + a check if /dev/stdin is not a character special device. + +2022-05-21 G. Branden Robinson + + * m4/groff.m4 (GROFF_PDFTOOLS): Rename this... + (GROFF_POPPLER): ...to this. + * configure.ac: Update call site. + +2022-05-21 G. Branden Robinson + + * m4/groff.m4 (GROFF_UCHARDET_CHECK): Rename this... + (GROFF_UCHARDET_NOTICE): ...to this. + * configure.ac: Update call site. + + * m4/groff.m4 (GROFF_UCHARDET_NOTICE): Tighten wording of + message reported to user. + + Fixes . Thanks to Dave + Kemper for the report. + +2022-05-21 G. Branden Robinson + + * m4/groff.m4 (GROFF_PNMTOOLS_CAN_BE_QUIET) + (GROFF_PNMTOPS_NOSETPAGE): Skip check if prerequisite not met. + +2022-05-21 G. Branden Robinson + + * m4/groff.m4 (GROFF_URW_FONTS_CHECK): Rename this... + (GROFF_URW_FONTS_NOTICE): ...to this. + (GROFF_URW_FONTS): ...and this... + (GROFF_URW_FONTS_CHECK): ...to this. + (GROFF_URW_FONTS_NOTICE): Give lengthy notice message a one-line + summary. + * configure.ac: Update call sites. + +2022-05-21 G. Branden Robinson + + * m4/groff.m4 (GROFF_URW_FONTS): Refactor. If our prerequisites + are not met (availability of 'awk' and 'gs'), don't even run the + check logic or print a "checking" message. + +2022-05-20 G. Branden Robinson + + Handle missing programs required to construct files needed at + runtime by gropdf more gracefully. Rename and refactor + configuration-time logic to be more understandable. + + * configure.ac: + * m4/groff.m4: Rename `GROFF_PDFDOC_PROGRAMS` macro to + `GROFF_CHECK_GROPDF_PROGRAMS`. Rename shell variable + `make_pdfdoc` to `use_gropdf`. Set it explicitly to "no" or + "yes" instead of null or not null. + + * configure.ac: + * m4/groff.m4: + * doc/doc.am: Rename `BUILD_PDFDOC` to `USE_GROPDF`. + + * configure.ac: Call `GROFF_GROPDF_PROGRAM_NOTICE`. + + * doc/doc.am: Bracket definition of `PROCESSEDDOCFILES_PDF` + macro and `$(PROCESSEDDOCFILES_PDF)` dependency declaration in + Automake `if USE_GROPDF` conditional. This prevents attempts + to build PDF documents using groff that are doomed to fail. + + * m4/groff.m4: Refactor gropdf runtime-dependency program check. + Split into two macros: one (`GROFF_CHECK_GROPDF_PROGRAMS`) + performs the check, the other (`GROFF_GROPDF_PROGRAM_NOTICE`) + issues a notice at the end of the configuration process if at + least one program was not found. Rename `docnote` shell + variable to `gropdf_notice`. Tighten wording of notice. Drop + unused `make_install_pdfdoc` and `make_uninstall_pdfdoc` shell + variables. + +2022-05-20 G. Branden Robinson + + Handle missing programs required at runtime by grohtml more + gracefully. Rename and refactor configuration-time logic to be + more understandable. + + * configure.ac: + * m4/groff.m4: Rename `GROFF_HTML_PROGRAMS` macro to + `GROFF_CHECK_GROHTML_PROGRAMS`. Rename shell variable + `make_htmldoc` to `use_grohtml`. Set it explicitly to "no" or + "yes" instead of null or not null. + + * configure.ac: + * m4/groff.m4: + * doc/doc.am: Rename `BUILD_HTML` to `USE_GROHTML`. + + * configure.ac: Call `GROFF_GROHTML_PROGRAM_NOTICE`. + + * doc/doc.am: Bracket definition of `PROCESSEDDOCFILES_HTML` + macro and `$(PROCESSEDDOCFILES_HTML)` dependency declaration + in Automake `if USE_GROHTML` conditional. This prevents an + attempt to build an HTML version of the "pic.ms" document that + is doomed to fail (noisily). + + * m4/groff.m4: Refactor grohtml runtime-dependency program + check. Split into two macros: one + {`GROFF_CHECK_GROHTML_PROGRAMS`} performs the check, the other + {`GROFF_GROHTML_PROGRAM_NOTICE`} issues a notice at the end of + the configuration process if at least one program was not found. + Rename `html_docnote` shell variable to `grohtml_notice`. + Tighten wording of notice. Drop unused `make_install_htmldoc` + and `make_uninstall_htmldoc` shell variables. + +2022-05-20 G. Branden Robinson + + * m4/groff.m4 (GROFF_GHOSTSCRIPT_VERSION_NOTICE): Add newline at + end of buggy Ghostscript notification, so that the multiple + possible lengthy notices after the configuration report have + blank lines separating them. + +2022-05-20 G. Branden Robinson + + Check for m4 program at configuration time. + + * m4/groff.m4 (GROFF_PROG_M4): Define new macro to perform the + check and error out if the program is missing. + * configure.ac: Call the new macro. + * tmac/tmac.am (tmac/groff_man.7.man) + (tmac/groff_man_style.7.man): Use the new implicitly AC_SUBST-ed + variable `M4` to run the program. + +2022-05-20 G. Branden Robinson + + * m4/groff.m4 (GROFF_PROG_YACC): Update wording of error + message: we search for "yacc", so report it as missing if it is + not found (along with "byacc" and "bison"). + +2022-05-20 G. Branden Robinson + + * configure.ac: Fix shell style nits. Get rid of string + {non-}nullity tests and comparisons involving concatenation with + garbage (usually "x"). See 13 November entry regarding m4. Use + idiomatic shell "brace style" for control structures. + +2022-05-20 G. Branden Robinson + + Trivially refactor libgroff allocator configuration. + + * m4/groff.m4 (GROFF_USE_GROFF_ALLOCATOR): Update description of + configuration flag to clarify that it's implemented in a + library. Rename shell variable to prefix it with "groff_", + putting it in an ad hoc name space as with other variables. If + feature disabled, set variable to literal "no". + * configure.ac: Use renamed variable and interpolate it directly + into configuration report, simplifying shell logic. + +2022-05-20 G. Branden Robinson + + * configure.ac: Revise configuration report for intelligibility. + Add report of C++ compiler and flags used: we compile much more + C++ than C code so this seems appropriate. Report Perl + interpreter version so that we can collect build reports and + turn the ratchet past Perl 5.6.1 at some point. Fix X11 + "resources" misnomer (application defaults are what is meant). + Rephrase generally. + +2022-05-20 G. Branden Robinson + + * Makefile.am (EXTRA_DIST): Ship "ChangeLog.122" in distribution + archive. Overlooked in commit c11995df16, 19 February 2021. + +2022-05-20 G. Branden Robinson + + * src/devices/grotty/tests/basic_latin_glyphs_map_correctly.sh: + Fix portability problem: POSIX says that "od -c" (and "od -t c") + are supposed to emit printing characters as defined by the + underlying locale, but GNU coreutils od doesn't do this and + macOS od does. Set `LC_ALL` to "C" when running it to force + 3-digit octal reporting of characters with their eighth bit set. + + Fixes . Thanks to John + Gardner for the report. Also see . + +2022-05-19 G. Branden Robinson + + * INSTALL.extra (In Case of Trouble): Add advice on using the + test suite, particularly if it fails. + + Fixes (one hopes). + +2022-05-19 G. Branden Robinson + + * doc/groff.texi (Input Line Traps): Expand discussion. The + `it` and `itc` requests count neither input lines (strictly) nor + text lines. Instead, they count input lines that _directly + produce formatted output_ (and, in the case of `itc`, are not + "interrupted" or continued with the `\c` escape sequence). This + is useful--empty requests and requests that don't put nodes on + the output don't break things--but does demand some explanation. + Clarify and provide example. + * man/groff.7.man (Escape sequence short reference) : Sync. + +2022-05-18 G. Branden Robinson + + * src/roff/troff/env.cpp (environment::choose_breakpoint): Tweak + diagnostic message ("can't" -> "cannot"). + * doc/groff.texi (Breaking): Update example. + +2022-05-17 G. Branden Robinson + + * doc/groff.texi (Copy Mode): + * man/groff.7.man (Copy mode): Fix omission; `\?` is interpreted + in copy mode. + +2022-05-17 G. Branden Robinson + + * tmac/s.tmac (PT): Unclutter name space; remove + `pg*saved-page-number-format` string when we're done with it. + +2022-05-17 G. Branden Robinson + + [tbl]: Add unit tests, including one XFAIL for bad behavior. + + * src/preproc/tbl/tests/check-horizontal-line-length.sh: + * src/preproc/tbl/tests/check-line-intersections.sh: + * src/preproc/tbl/tests/check-vertical-line-length.sh: + * src/preproc/tbl/tests/table-lacks-spurious-top-border.sh: Do + it. + * src/preproc/tbl/tbl.am (tbl_TESTS): Run tests. + (tbl_XFAIL_TESTS, XFAIL_TESTS): Expect one test failure. + +2022-05-16 G. Branden Robinson + + * src/devices/grotty/tty.cpp (tty_printer::add_char): Modify + diagnostic message: what gets written "above [the] first line" + might not be a character (glyph) per se, but a line (rule) from + a drawing command, and in fact the occurrence of these from + boxed tables is the most common cause of this message I've seen. + +2022-05-16 G. Branden Robinson + + [grotty]: Do more input validation. + + * src/devices/grotty/tty.cpp (tty_printer::draw): Throw warning + if an unsupported geometric primitive is encountered. + (tty_printer::line): Throw warning if a line is diagonal. Die + if length of a horizontal or vertical line is not a multiple of + the appropriate motion quantum of the device (troff should never + emit such nonsense, and currently doesn't appear to). + +2022-05-16 G. Branden Robinson + + * src/preproc/tbl/tbl.1.man (Miscellaneous): Document GNU tbl's + use of `#T` and `T.` registers. + +2022-05-15 G. Branden Robinson + + * src/roff/troff/input.cpp (read_color_draw_node): Tweak + diagnostic message to better distinguish drawing commands and + device control commands. + +2022-05-14 G. Branden Robinson + + [grohtml]: Mitigate double-free problem exposed by malformed + input. + + * src/roff/troff/mtsm.h (struct statem): Place member variable + `issue_no` behind `DEBUGGING` preprocessor symbol, omitting it + from production and ordinary development builds. + * src/roff/troff/mtsm.cpp (no_of_statems): Place global variable + behind `DEBUGGING` preprocessor symbol, omitting it from + production and ordinary development builds. + (statem::statem): Make constructor trivial if `DEBUGGING` not + defined in preprocessor; it manipulates only `issue_no` and + `no_of_statems`, which are synchronized. + (statem::statem {copy}): Gate assignment of `issue_no` member + variable from copy constructor behind `DEBUGGING` preprocessor + symbol. + (statem::flush, mtsm::inherit): Gate debugging output, already + runtime-gated on `debug_state` symbol, of `issue_no` member + variable, so that we don't reference it when it is not declared. + + See . + +2022-05-05 G. Branden Robinson + + [refer]: Rename a test artifact; it's a bibliographic database + file, not a refer(1) command file. + + * src/preproc/refer/tests/artifacts/62124.ref: Rename this... + * src/preproc/refer/tests/artifacts/62124.bib: ...to this. + * src/preproc/refer/refer.am (EXTRA_DIST): + * src/preproc/refer/tests/report-correct-line-numbers.sh: Use + new name. + +2022-05-05 G. Branden Robinson + + * src/preproc/refer/command.cpp (process_commands): Begin + migration to use existing global variables for location reports + in diagnostic messages. Save current file name and line number + before calling `command_loop()` and restore them afterward. + Also decrement line counter before entering that loop because it + would be too far advanced by one due to the final newline on a + parsed input line. + +2022-05-05 G. Branden Robinson + + * src/preproc/refer/refer.cpp (main): Report system error on + `fflush()` failure. POSIX Issue 5 a.k.a. SUSv2 (1997) specifies + several possible `errno` values this C standard library function + can set; see + . + +2022-05-05 G. Branden Robinson + + [refer]: Refactor: drop unused version of function (taking only + a `const char *` parameter). + + * src/preproc/refer/command.cpp (process_commands): Drop + definition. + * src/preproc/refer/command.h (process_commands): Drop + declaration. + +2022-05-04 G. Branden Robinson + + * src/preproc/refer/refer.cpp (do_file): Fix another off-by-one + line number reporting bug exposed by fix for Savannah #62391. + +2022-05-04 G. Branden Robinson + + * src/preproc/refer/tests/report-correct-line-numbers.sh: Add + more regression tests. + +2022-05-04 G. Branden Robinson + + [refer]: Trivially refactor: boolify. + + * src/preproc/refer/command.cpp (input_stack::push_file): Demote + and rename local variable from `int` to `bool`. + (bol): Renamed from this... + (is_at_beginning_of_line): ...to this. + +2022-05-04 G. Branden Robinson + + [refer]: Trivially refactor. + + * src/preproc/refer/command.cpp (input_stack::push_file): + * src/preproc/refer/refer.cpp (do_file): Drop unnecessary + construction of integer from integer (return type of `getc()`) + in argument to error diagnostic functions; parallelizes with + other diagnostic function calls. + +2022-05-04 G. Branden Robinson + + * src/preproc/refer/command.cpp: Refactor to simplify. + (get_location): Demote return type from `int` to `void`. The + function only ever returned a `1` literal. + (input_stack::error): Update call site to stop uselessly testing + return value of `get_location()`. + +2022-05-03 G. Branden Robinson + + * doc/doc.am (dist-info-bits, install_infodoc, dist-gnueps): Fix + logic error. When checking both source and build trees for + files to copy, break after successfully copying the files, not + after the first iteration of the loop unconditionally. This + caused the Info documents not to be installed from out-of-tree + builds, and potentially would prevent them and doc/gnu.eps from + being included in the distribution archive if for some reason + they didn't build and that build failure were not treated as an + error. Problems introduced by me in commits e78bd20d54, 27 + March, and d79c3f3a4a, 11 November. + +2022-05-03 G. Branden Robinson + + * m4/groff.m4 (GROFF_APPRESDIR_OPTION): Update comments and + human-readable output to (1) stop claiming that existing + gxditview application defaults in the installation directory + will be backed up; this is no longer true as of commit + c66cb7725f, 3 April; and (2) refer to these files as + "application defaults", not "resources". (X11 application + defaults are client-side and mandatory [for Xt-based programs]; + X resources are stored server-side and need not be configured to + determine an X client's geometry and rendering.) + +2022-05-03 G. Branden Robinson + + * font/devX100-12/devX100-12.am (devX100_12_fontdir): + * font/devX100/devX100.am (devX100_fontdir): + * font/devX75-12/devX75-12.am (devX75_12_fontdir): + * font/devX75/devX75.am (devX75_fontdir): Define macros without + an extra "font/" layer in the directory hierarchy. + + Fixes problem introduced by me in commit 3c82cbbfe5, 27 + February. + +2022-05-03 G. Branden Robinson + + * font/devpdf/devpdf.am (font/devpdf/util/BuildFoundries): Spell + dependency on `$(SH_DEPS_SED_SCRIPT)` using that macro expansion + instead of a literal file name. See doc/automake.mom. + +2022-05-02 G. Branden Robinson + + * src/preproc/eqn/eqn.am (MAINTAINERCLEANFILES): + * src/preproc/pic/pic.am (MAINTAINERCLEANFILES): + * src/preproc/refer/refer.am (MAINTAINERCLEANFILES): Preserve + byacc/bison output artifacts unless "maintainer-clean"ing. Per + the GNU Automake manual, "The intermediate files generated by + yacc (or lex) will be included in any distribution that is made. + That way the user doesn’t need to have yacc or lex." + +2022-05-02 G. Branden Robinson + + * Makefile.am: Stop manually handling "test-groff". Per the + GNU Automake manual, "If configure built it, then distclean + should delete it." This is taken care of automatically if we + don't interfere. + (BUILT_SOURCES, MOSTLYCLEANFILES): Drop "test-groff". + +2022-05-02 G. Branden Robinson + + * src/preproc/eqn/eqn.am (neqn): Produce temporary file first + and set its permissions before moving it into place. If + anything in the future ever has a dependency on it, this avoids + a race where the file exists, satisfying a dependency, but + execution is attempted before its `x` permission bit is set. + +2022-05-02 G. Branden Robinson + + [build]: Ensure that we install *.me source files, but don't + include them in the distribution archive. + + * doc/doc.am (dist_otherdoc_DATA): Move `$(GENERATEDDOCFILES)` + from here... + (nodist_otherdoc_DATA): ...to here. + (.PRECIOUS): Add `$(GENERATEDDOCFILES)` so that make(1) doesn't + automatically remove "intermediate" objects in the .me.in -> .me + -> .ps chain. + +2022-05-02 G. Branden Robinson + + [build]: Handle "gnu.eps" file better. + + * doc/doc.am (GENERATEDDOCFILES): Remove `$(DOC_GNU_EPS)`. + (EXTRA_DIST): Ship `$(DOC_GNU_EPS)` in distribution archive. + ($(DOC_GNU_EPS)): Simplify rule commands; stop trying to copy + the file around since it will either be (1) in the distribution + archive from which a build is performed; or (2) missing because + a build is being done from Git, in which case we expect the PNM + tools to be available. + +2022-05-02 G. Branden Robinson + + * doc/doc.am (clean_otherdoc): Drop target: it doesn't seem to + accomplish anything. + (clean_infodoc): Drop target, moving its rules into... + (maintainer-clean-local): ...this. Drop deps, both gone now. + +2022-05-02 G. Branden Robinson + + * doc/doc.am (distclean-local): Drop target: stop cleaning + generated forms of our Texinfo manual with the "distclean" + target. They ship with the distribution archive and should + remain in the tree even if the user needs to re-./configure. + +2022-05-02 G. Branden Robinson + + [build]: Fix problems exposed by high build parallelism. + + * font/devpdf/devpdf.am (font/devpdf/util/BuildFoundries) + (font/devpdf/DESC, font/devpdf/Foundry): Drop + unnecessary removal of target prior to creating it. + (font/devpdf/Foundry): Add creation of destination build + directory as other targets do. + (font/devpdf/download): Create dedicated target instead of + lumping its generation under the stamp file. Add missing + dependencies on `$(DEVPDFFONTMAP_1)`, `$(DEVPDFFONTMAP_2)`, + `font/devpdf/Foundry` and `font/devpdf/enc/text.enc`. Remove + now-unnecessarily complicated "forgery" of "GEN" line in quiet + builds. Tweak format of comment written to "download" file to + make field identities clearer. Construct output (with multiple + shell commands) in temporary file so it is not read prematurely + by the "BuildFoundries" script. Move target into place as the + last step. + (font/devpdf/stamp): Relocate target to follow its dependencies. + Add dependency on "font/devpdf/download". + +2022-05-02 G. Branden Robinson + + [build]: Tweak diagnostic messages in BuildFoundries script. + + * font/devpdf/util/BuildFoundries.pl (LoadFoundry) + (WriteDownload, CheckFoundry): Recast for specificity and + consistent style. + (Die): Stop reporting line number with fatal errors; none of the + call sites are parsing input. + +2022-05-02 G. Branden Robinson + + [refer]: Fix off-by-one error in line number for some + diagnostics. + + * src/preproc/refer/command.cpp (input_item::get_location): + Decrement reported line number by one after looping over input + so that we report the line number as it was before the last + newline character seen. This off-by-one error was partially + masked by... + * src/preproc/refer/refer.cpp (do_file): ...initialization of + `current_lineno` to zero. However, for syntax problems (as + opposed to the semantic problems of refer(1) command + processing), this could result in complaints about the line + number before they occurred, even on "line zero". Initialize + the variable to 1. + + Fixes . + +2022-05-02 G. Branden Robinson + + * src/preproc/refer/tests/report-correct-line-numbers.sh: Add + regression test for Savannah #62391. + +2022-05-02 G. Branden Robinson + + * src/utils/tfmtodit/tfmtodit.cpp (usage): Tweak usage message. + Condense `-v` and `--version` into a single output line with + brace and pipe notation, which we do not use in our man pages, + but consistently do in our usage messages. Use lowercase for + option arguments since they are separated from option flag + letters by space. Call `fprintf()` once instead of 3 times. + +2022-05-01 G. Branden Robinson + + * src/preproc/refer/refer.cpp (main): Tweak wording of + diagnostic messages to refer to options consistently and to + characterize input as "invalid" rather than "bad". + (usage): Document --version option. Use more informative + metasyntactic variable names. Organize usage message + consistently with our others, and stop wrapping the output + lines: we know neither the width of the terminal nor the length + of the `program_name` string we're interpolating. See commit + b4de44f0, 19 July 2021. + +2022-05-01 G. Branden Robinson + + * src/roff/troff/input.cpp (string_iterator::backtrace): Fix + spurious output when `mac.filename` is empty. Provoked by: + $ printf '\\(' | troff -b + +2022-05-01 G. Branden Robinson + + * src/preproc/refer/refer.cpp: Trivially refactor. Demote + global variable `recognize_R1_R2` from integer to Boolean. + (main, do_bib): Give expressions to `assert()` meaningful + content. + (is_list): Demote return type from `int` to `bool`. + (do_file): Demote and rename integer local variables + `start_of_line` to Boolean `at_start_of_line`. + (is_list, do_file): Reorder equality comparisons to avoid + inadvertent lvalue assignment. + +2022-05-01 G. Branden Robinson + + [build]: Reduce and rationalize in-tree document dependencies. + This eliminates spurious rebuilds of numerous documents + {including the 380+-page groff-man-pages collections}. It also + fixes missing dependencies when using the build's groff to + generate PostScript documents. + + * .gitignore: Drop old name of devpdf stamp file. + * doc/.gitignore: Drop now-unused "example.stamp" file. + * doc/doc.am (PROCESSEDDOCFILES_HTML, PROCESSEDDOCFILES_PDF) + (PROCESSEDDOCFILES_TXT): Add new macros grouping targets by the + format/output driver used to produce them, to better organize + dependencies for their generation. + (PROCESSEDDOCFILES): Redefine as simply the expansions of the + foregeoing. + (PROCESSEDFILES_DEPS_HTML, PROCESSEDFILES_DEPS_HTML, + PROCESSEDFILES_DEPS_PDF, PROCESSEDFILES_DEPS_TXT): Add new + macros defining prerequisites for production of the + corresponding output document formats. + ($(PROCESSEDDOCFILES_HTML), $(PROCESSEDDOCFILES_PDF), + $(PROCESSEDDOCFILES_PS), $(PROCESSEDDOCFILES_TXT)): Declare the + dependencies using expansions of the foregoing macros. + (MOSTLYCLEANFILES): Drop "doc/automake.pdf", now part of + `PROCESSEDDOCFILES_PDF`. + (doc/automake.pdf): Drop dependencies already supplied by + `PROCESSEDFILES_DEPS_PDF`. + (HTMLDOCFILES): Drop macro. "doc/pic.html" is now in the + expansion of `PROCESSEDDOCFILES_HTML`. + (htmlpic_DATA): Redefine as expansion of + `PROCESSEDDOCFILES_HTML` instead of `HTMLDOCFILES`. + (PROCESSEDEXAMPLEFILES_HTML) [BUILD_HTML]: Define as + "doc/webpage.html", otherwise as empty. + (PROCESSEDEXAMPLEFILES_PS): Contain "doc/webpage.ps" and + "doc/grnexampl.ps". + (PROCESSEDEXAMPLEFILES): Redefine as expansions of + `PROCESSEDEXAMPLEFILES_HTML` and `PROCESSEDEXAMPLEFILES_PS`. + ($(PROCESSEDEXAMPLEFILES_HTML), $(PROCESSEDEXAMPLEFILES_PS)): + Declare dependencies using `PROCESSEDFILES_DEPS_HTML` and + `PROCESSEDFILES_DEPS_PS`, respectively. + (HTMLEXAMPLEFILES): Drop macro. "doc/webpage.html" is now in + the expansion of `PROCESSEDDOCFILES_HTML`. + (nodist_htmlexamples_DATA): Drop macro, no longer needed. + ($(PROCESSEDDOCFILES_PS)): Relocated and redefined above. + ($(PROCESSEDEXAMPLEFILES) $(PROCESSEDDOCFILES)): Drop overbroad + dependency declarations in favor of the above. + (MOSTLYCLEANFILES, doc/examples.stamp): Drop generation and + removal of unnecessary stamp file. + (doc/pic.html, doc/webpage.html): Add explicit dependency on + required preprocessors. Drop redundant and spurious + dependencies. + * font/devhtml/devhtml.am (MOSTLYCLEANFILES) + (font/devhtml/stamp): Generate and remove stamp file to enable + reliable target dependencies for build-time generation of HTML + documents by groff. + * font/devpdf/devpdf.am (MOSTLYCLEANFILES, font/devpdf/stamp): + Rename stamp file from "font/devpdf/build_font_files". + (font/devpdf/stamp): Drop unnecessary dependency on "afmtodit". + * font/devps/devps.am (MOSTLYCLEANFILES, font/devps/stamp): + Generate and remove stamp file to enable reliable target + dependencies for build-time generation of PostScript documents + by groff. + * font/devutf8/devutf8.am (MOSTLYCLEANFILES) + (font/devutf8/stamp): Generate and remove stamp file to enable + reliable target dependencies for build-time generation of + UTF-8-encoded text documents by groff. + + Fixes ; thanks to + Sergei Trofimovich for the report. Also fixes + ; thanks to Bjarni Ingi + Gislason for the report. + +2022-04-30 G. Branden Robinson + + [build]: Fix code style nits in Automake files. + + * doc/doc.am: Put spaces around (Auto)make variable assignments, + for consistency with the rest of this .am file, and our others. + * font/devpdf/devpdf.am (font/devpdf/build_font_files): Use + shell '>' operator instead of touch(1). + * font/devhtml/devhtml.am (font/devhtml/DESC): + * font/devps/devps.am (font/devps/DESC): Construct target in + temporary file, since doing so is a multi-step process, moving + it to the target name when it is complete and usable by + dependencies. + +2022-04-29 G. Branden Robinson + + * src/preproc/refer/refer.cpp (main): When complaining of + unrecognized option, report the entire option string (after + the leading dash), not just its first character. + +2022-04-29 G. Branden Robinson + + * src/libs/libgroff/error.cpp: Trivially refactor. Explicitly + compare pointer lvalues to null pointers instead of punningly + treating them as Booleans. Annotate use of zero literals as + null pointers to ease any future migration to ISO C++11. + +2022-04-27 G. Branden Robinson + + * tmac/an.tmac (an*abbreviate-inner-footer): Clean up better + before early returns. Remove temporary registers. + +2022-04-27 G. Branden Robinson + + * tmac/fallbacks.tmac: Add fallbacks for U+02C6 MODIFIER LETTER + CIRCUMFLEX ACCENT and U+02DC SMALL TILDE to Basic Latin + characters. + +2022-04-27 G. Branden Robinson + + [tests]: Fix portability problem. Don't pass echo(1) arguments + containing backslashes because implementations handle them + differently. Use printf(1) instead. Thanks to Bertrand + Garrigues for reporting the problem and confirming the fix on + his build host. + + * tmac/tests/e_chapter-titles-work.sh: + * tmac/tests/e_ld-works.sh: + * tmac/tests/localization-works.sh: Do it. + +2022-04-27 G. Branden Robinson + + * src/devices/gropdf/gropdf.pl (ppsz): Recognize "com10" (U.S. + commercial envelope) paper format. + + Addresses the original issue reported in + . We have however broadened + its scope; see . + +2022-04-27 Dave Kemper + + * src/devices/gropdf/gropdf.pl (ppsz): Recognize ISO B-series + paper formats using strings of the form "b0-b6", not "isob0-b6", + for consistency with libgroff and papersize.tmac. + + Fixes . + +2022-04-27 G. Branden Robinson + + * doc/doc.am: Refactor to simplify. Ingo's removal of the + "--with-doc" "configure" option, among other changes, clears the + way to remove many phony targets and simplify dependencies + involving generation of the 5 formats of our Texinfo manual. + (build_infodoc, doc, doc_all, doc_txt, dvi, doc_dvi, pdf, + doc_pdf, html, doc_html): Drop phony targets. + (all): Depend directly on doc/groff.{info,txt,html,dvi,pdf}. + * NEWS: Add item since "make doc" is no longer necessary and + will do nothing. + +2022-04-26 G. Branden Robinson + + [tbl]: Handle `\R` sequences in text blocks robustly. + + * src/preproc/tbl/table.cpp (table::add_entry): Fix SEGV when + repeating glyph table entry syntax (`\Rx`) used in a text block. + Lift extraction of entry string to be done unconditionally, + rather than in 5 different special cases. This frees us up to + rewrite the entry if necessary, changing '\R' to '\&' inside a + text block. Recast diagnostic to describe the problem + clearly--"bad repeated character" suggests that something is + wrong with the "argument" to `\R`, when really the problem is + the _context_. + + Fixes . + +2022-04-27 G. Branden Robinson + + [tbl]: Regression-test Savannah #62366. + + * src/preproc/tbl/tests/\ + do-not-segv-when-backslash-R-in-text-block.sh: Do it. + * src/preproc/tbl/tbl.am (tbl_TESTS): Run test. + +2022-04-26 G. Branden Robinson + + * src/libs/libgroff/string.cpp (string::extract): Check return + value of `malloc()` for nullity, and only poke into the buffer + returned if it is valid. Discovered while troubleshooting + Savannah #62366. + +2022-04-23 Bertrand Garrigues + + gnulib: replace non-recursive-gnulib-prefix-hack with + automake-subdir option + + 'non-recursive-gnulib-prefix-hack' is deprecated by gnulib's + commit f8eed11b15e9141d061900e4068ea1f3ba9b63f6 and replaced by + '--automake-subdir'. + + * bootstrap.conf: + (gnulib_modules): Remove option + 'non-recursive-gnulib-prefix-hack'. + (gnulib_tool_option_extras): Add option '--automake-subdir'. + (bootstrap_post_import_hook): Remove the invocation of + 'build-aux/prefix-gnulib-mk'. + + * doc/automake.mom: update documentation accordingly. + + Fixes and + , issues reported and fix + suggested by Bjarni Ingi Gislason . Fix + also suggested by Werner LEMBERG (see + ). + +2022-04-23 Bertrand Garrigues + + Update gnulib submodule + + * gnulib now points on c8b8f3bbcde37a53cd226f4c9cebd0dde6aca37f + + * bootstrap: merge the latest version from gnulib/build-aux + {groff's bootstrap has a patch for OS X}. + + * bootstrap.conf: update copyright date. + +2022-04-17 G. Branden Robinson + + * tmac/s.tmac (XH-UPDATE-TOC): Modify Keith Marshall's new XN/XH + feature to indent TOC entries by section heading depth. The + increment is 2 ens per depth level. + +2022-04-17 G. Branden Robinson + + * tmac/s.tmac (XA): Drop apparently useless `ll` request. It + doesn't do anything according to my tests. + +2022-04-15 G. Branden Robinson + + * src/preproc/refer/label.ypp: Drop redundant declaration of + `yyparse`. Both byacc 20140715 and GNU Bison 3.3.2 supply the + the function prototype themselves. Addresses + "-Wredundant-decls" warning from GCC. + + Fixes . + +2022-04-15 G. Branden Robinson + + * src/preproc/grn/hdb.cpp (DBGetType): Lower fatal diagnostics + to errors when encounting invalid element type characters. + Return a value interpreted by our caller as an error indication + instead. Helps compilers determine that we're not implicitly + falling through our cases. Addresses "-Wimplicit-fallthrough" + warnings from GCC. + + Fixes https://savannah.gnu.org/bugs/?54702>. + +2022-04-15 G. Branden Robinson + + * src/preproc/grn/hdb.cpp (DBRead): Add more validity checking. + Verify that the number of conversions returned by fscanf() is as + expected instead of throwing this information away--abort + processing ("giving up" like pic(1) does) if it does not. + Consistently report this abandonment in diagnostic messages. + Similarly validate pointer returned by fgets(). Soften handling + of invalid text condition from fatal error, introduced in + commit eb4f0675e, 16 August, to a normal one with abandonment of + Gremlin file. Addresses "-Wunused-result" warnings from GCC. + +2022-04-14 G. Branden Robinson + + * src/preproc/grn/main.cpp (conv): Throw an error diagnostic + when failing to open a Gremlin picture file. + +2022-04-14 G. Branden Robinson + + [man]: Fix extraneous space in output after `ME` or `UE` when + mandoc wrapper is used. + + * tmac/an-ext.tmac (UE, ME): Double backslashes in macro + definitions when interpolating `.$` register (just like we tell + everyone else to do). This one was interesting to track down. + When using just `-man`, the problem never manifested; only with + `-mandoc`. The difference is that with the former, the `.$` + register is initialized to zero; with the latter, because `TH` + is aliased to another macro (then unaliased), `.$` has the + argument count to the `TH` macro, not to the macros actually + being called. This caused the wrong branch of a conditional to + be taken and put an extra space node on the output. + + Fixes . + +2022-04-14 G. Branden Robinson + + * tmac/cp1047.tmac: + * tmac/latin1.tmac: + * tmac/latin2.tmac: + * tmac/latin5.tmac: + * tmac/latin9.tmac: Stop remapping input soft hyphen characters + with `tr` requests in character encoding macro files. The + formatter does this for us now. + +2022-04-14 G. Branden Robinson + + [troff]: Translate 8-bit NBSP and SHY on input. + + * src/roff/troff/input.h: Define constant integers for "input" + no-break spaces and soft hyphens for EBCDIC and non-EBCDIC + (presumably ASCII/ISO 8859/Unicode) systems. + + * src/roff/troff/input.cpp (token::next): Translate the input + character codes for NBSP to \~ and SHY to \%. + + Fixes . Thanks to Dave + Kemper for the report, code review, and his suggestion to push + more work to compile time. + +2022-04-14 G. Branden Robinson + + [groff]: Regression-test Savannah #58962. + + * src/roff/groff/handle_special_input_code_points.diff: Do it. + * src/roff/groff/groff.am (groff_TESTS): Run test. + +2022-04-14 G. Branden Robinson + + * src/roff/troff/input.cpp (do_if_request): Clarify diagnostic; + at the point it is thrown, we know not merely that we're in a + conditional expression, but processing an output comparison + operator. + +2022-04-13 G. Branden Robinson + + * doc/groff.texi: + * doc/ms.ms: + * man/groff.7.man: Characterize "roff language" in the singular, + not the plural, emphasizing the similarity of extant specimens. + + * doc/groff.texi (Conventions Used in This Manual): Add + paragraph discussing denotations of "groff" and "roff". + + Fixes . Thanks to John + Gardner and Dave Kemper for the discussion. + +2022-04-12 Ingo Schwarze + + Delete the harmful, ill-designed, buggy, and essentially + unmaintained and untested --with-doc option of the configure + script. + + * configure.ac: Delete five AM_CONDITIONAL variables, one + autoconf(1) macro call, and some related diagnostic output. + * doc/doc.am: Delete two BUILD_EXAMPLES and one BUILD_OTHERDOC + conditional and use BUILD_HTML instead of BUILD_HTMLEXAMPLES. + * m4/groff.m4: Delete the GROFF_DOC_CHECK macro and simplify the + macros GROFF_HTML_PROGRAMS, GROFF_INSTALL_INFO, GROFF_MAKEINFO, + and GROFF_PDFDOC_PROGRAMS. This also deletes more than thirty + configuration variables. + * Makefile.am: Delete comments about 16 variables that are no + longer set. + * NEWS: Add details regarding the rationale. + +2022-04-12 G. Branden Robinson + + * src/preproc/preconv/preconv.cpp (unicode_entity): Convert + input U+00A0 to \~ as troff would, not to \[u00A0]. + + Fixes . + +2022-04-11 Deri James + + [gropdf] fails to deal with 255th glyph in font. + + * src/devices/gropdf/gropdf.pl: a pdf font can only contain 255 + glyphs. The array which holds the glyph names also holds the + start position (zero) as first element, it is legal for it to + contain 256 elements, so truncate to 256 (not 255). + + Fixes . + +2022-04-09 G. Branden Robinson + + [localization]: Define hyphenation mode registers for Japanese + and Chinese. They are set to zero but must be defined so that + macro packages can rely on their existence without causing 'reg' + warnings. + + * tmac/ja.tmac: + * tmac/zh.tmac: Do it. + +2022-04-09 G. Branden Robinson + + [tests]: Add test for multi-lingual man(7) scenario. + + * tmac/tests/localization-works.sh: Test two more cases. Ensure + that the 'trap bit' (hyphenation value 2, which has nothing to + do with any language) is preserved when switching locales back + from a CJK language, since those languages' modes + unconditionally clear it. We test Japanese and Chinese; we have + no localization macro file for Korean at this time. + +2022-04-09 G. Branden Robinson + + [man]: Slightly refactor `an*abbreviate-inner-footer`. + + * tmac/an.tmac (an*abbreviate-inner-footer): Discard + unnecessary string. + +2022-04-09 Ingo Schwarze + + Fix the configuration of texi2dvi. + + * m4/groff.m4: Set groff_have_texi2dvi if texi2dvi(1) is + available and usable, even if the availability was specified by + the user by manually providing the configure variable + PROG_TEXI2DVI, and not only if it was autodetected. + Also, set the PROG_TEXI2DVI Makefile variable to the name of + the texi2dvi program specified by the user or autodetected, + and not to the string "found", such that this Makefile variable + can be used for invoking the program. + * doc/doc.am: Call the texi2dvi program specified by the user + or autodetected rather than hardcoding "texi2dvi". This lets + the groff build succeed on systems where the first texi2dvi + in the $PATH is an old version unfit for groff's purposes. + +2022-04-08 G. Branden Robinson + + [man]: Abbreviate long `TH` arguments more carefully. + + * tmac/an.tmac: Do it. + (an*scan-string-for-backslash): Add new helper macro. + (an*abbreviate-inner-footer): Rewrite. Use the foregoing and a + different technique to compute available space and shorten the + string. + + Fixes . + +2022-04-08 G. Branden Robinson + + [man]: Add regression test for Savannah #62257. + + * tmac/tests/an_do-not-abbreviate-escape-using-TH-arguments.sh: + Do it. + * tmac/tmac.am (tmac_TESTS): Run it. + +2022-04-08 G. Branden Robinson + + * tmac/an.tmac: Trivially refactor. Rename strings `an-ifoot` + to `an*ifoot` and `an-outer-footer-text` to `an*ofoot`. + +2022-04-08 G. Branden Robinson + + * tmac/an.tmac: Refactor. Abbreviate page title and inner + footer only once per document instead of once per page. + Exception: the legacy macros `AT` and `UC` change the inner + footer, so re-abbreviate it if they are called. + (TH, AT, UC): Call abbreviation macros from here... + (an-header, an-footer): ...instead of here. + +2022-04-08 G. Branden Robinson + + * tmac/an.tmac: Refactor: initialize header/footer environment + only once. Also rename it to `an*env-header-and-footer`. + (TH): Do it here... + (an-header, an-footer): ...instead of here. + +2022-04-08 G. Branden Robinson + + * tmac/an.tmac: Trivially refactor. + (an*prepare-page-title): Rename this... + (an*abbreviate-page-title): ...to this. + (an-prepare-inner-footer): And this... + (an*abbreviate-inner-footer): ...to this. + (an-header, an-footer): Update call sites. + +2022-04-08 G. Branden Robinson + + * src/preproc/eqn/other.cpp (hmotion_box::output): Fix typo in + generated MathML diagnostic message. + +2022-04-07 G. Branden Robinson + + * doc/doc.am (EXTRA_DIST): Add "groff.dvi" and "groff.pdf" to + ensure that the GNU-released groff distribution archive contains + our Texinfo manual in these formats. (This doesn't increase the + build-dependency requirements unless you want to "make dist", in + which case it _should_.) + +2022-04-06 G. Branden Robinson + + [ms]: Add nroff mode fallback for `UL` macro. + + * tmac/s.tmac (UL): On nroff devices, bracket the first argument + with \(ul (underline rule) special character escape sequences. + {In plain language, '.UL "like this"' renders "_like this_".} + See corresponding 12 February change to "tmac/e.tmac". + +2022-04-06 G. Branden Robinson + + * doc/doc.am: Drop unnecessary `-I` options to groff. + (DOC_GROFF): There is no need to look at the top of the build + directory for any file inclusions. + (doc/webpage.html): There is no need to look in `doc_builddir` + for file inclusions, since that is the current working directory + when "webpage.ms" is processed. + +2022-04-06 G. Branden Robinson + + * doc/doc.am: Trivially refactor. Use `RM` macro idiomatically. + Automake ensures that it is defined to call an `rm` command with + the `-f` option, and this in turn ignores failures to delete + nonexistent files, so... + (uninstall_doc_examples, uninstall-pdf): Stop adding superfluous + `-f` flag. + (clean_infodoc uninstall-pdf, uninstall-html): Stop prefixing + command with `-` to ignore error exit status. + (uninstall-html): Drop superfluous `-r` flag; we're only + deleting files with this command, not directories. + +2022-04-05 G. Branden Robinson + + * doc/doc.am: Trivially refactor shell style in rule commands. + The placement of `&&` was inconsistent. Always begin a + continued rule line with it, and don't give it its own + indentation level. In general, operators adjacent to line + continuations should _follow_ the continuations because they are + easier for humans to spot at the (possibly indented) beginning + of a physical line. + +2022-04-05 G. Branden Robinson + + * Makefile.am: Rename `TFLAG` macro, which means "tmac flag", to + `MFLAG`, because it expands to `-M` options to groff, not the + `-T` option, which can be bewildering. + * doc/doc.am (DOC_GROFF): Update expansion site. + +2022-03-29 G. Branden Robinson + + * doc/doc.am: Rename `DOC_GROFF_ONLY` to `DOC_GROFF`. + +2022-03-29 G. Branden Robinson + + * doc/doc.am: Refactor. Drop ghastly hack used to get file + names into troff diagnostics when reading from standard input. + We've refactored so that it no longer does, making the hack + unnecessary. For the same reason, no users of the `DOC_GROFF` + macro remain, so delete it. Add comments to explain what + `DOC_SED` and `DOC_GROFF_ONLY` are for. + +2022-03-29 G. Branden Robinson + + * doc/doc.am: Refactor. + (doc/pic.html, doc/webpage.html): Drop indirection of source + document through `DOC_SED` macro. It was not necessary since + neither of these documents are parameterized in configuration + options (that is, they don't contain @VERSION@ or @g@). + +2022-04-05 G. Branden Robinson + + * doc/doc.am: Trivially refactor. + (doc/webpage.html): Tidy up dependency list. Create directory + using the same macro interpolation we use to change into it. + +2022-04-05 G. Branden Robinson + + * doc/doc.am: Refactor and fix error in builds in remote + out-of-source-tree builds exposed by pending commit and `make + distcheck`. The images generated for the pic.html and + webpage.html files were being built in the wrong directory, and + subsequently not found by an install rule. + (imagedir): Add comment explaining purpose of macro. It should + _not_ be used with any file specifications relative to the + source or build trees--it is for installation directories only. + (htmldocimagedir, exampleimagedir): Drop macros. + + (doc/pic.html, doc/webpage.html): Replace interpolations of + `imagedir` with literal "img", since these files are being + generated within the build tree: the directory name is known. + + (mostlyclean_doc, install_doc_htmldoc, install_doc_examples): + Replace interpolations of `htmldocimagedir` relative to + `doc_builddir` with "img" literals. + + (install_doc_htmldoc, uninstall_doc_htmldoc): Interpolate + concatenation of `htmldocdir` and `imagedir` instead of + `htmldocimagedir` (relative to `DESTDIR`). + (install_doc_examples, uninstall_doc_examples): Interpolate + concatenation of `exampledir` and `imagedir` instead of + `exampleimagedir` (relative to `DESTDIR`). + +2022-04-01 G. Branden Robinson + + * doc/doc.am: Refactor. Relocate "doc/grnexampl.ps" target to + group it with other me(7) documents. Put addition of + "doc/examples.stamp" to `MOSTLYCLEANFILES` adjacent to its + target rule. Relocate same rule so that it precedes the target + depending on it (make(1) might not benefit from this, but human + readers can). + +2022-03-29 G. Branden Robinson + + * doc/doc.am: Refactor. + (DOC_GROFF_ONLY): Drop preprocessor options from groff command. + This macro is now, simply, a way to run the in-tree groff: no + assumptions about preprocessors, macro packages, or output + device are made. + (doc/pic.html, doc/webpage.html): Add only necessary + preprocessor options after expansion of `DOC_GROFF_ONLY`. + +2022-03-29 G. Branden Robinson + + * doc/doc.am: Refactor. Add explicit dependencies of compiled + man page documents on preprocessors needed to generate them. In + their target rules, explicitly use groff's preprocessor options, + freeing us up to simplify the `DOC_GROFF_ONLY` macro. + +2022-03-29 G. Branden Robinson + + * doc/doc.am: Rationalize dependencies. Drop dependency of + `PROCESSEDEXAMPLEFILES` and `PROCESSEDDOCFILES` on expansion of + `hdtbltmac_DATA`, because nothing in this directory uses the + hdtbl package. Move dep of same expansions on "gnu.eps" to + "doc/webpage.html", which actually uses it. Put the numerous + dependencies of "doc/pic.html" and "doc/webpage.html" in a + parallel ordering so that they are easier for humans to + evaluate. These targets' dependencies on `bin_PROGRAMS` and + `prefixexecbin_PROGRAMS` are overkill and should be reviewed at + a later date. + +2022-04-03 G. Branden Robinson + + * doc/doc.am: Refactor use of target and suffix rules. + (doc/meintro.me, doc/meintro_fr.me, doc/meref.me): Add target + rules, with lengthy, exasperated comment about lack of feature + parity in various make(1) implementations. + (doc/meintro_fr.ps): Add target rule, as this seems to be the + only way to keep GNU Make from ignoring a '_fr.me._fr.ps' suffix + rule in favor of '.me.ps', which doesn't call preconv (and + doesn't need to--and moreover we don't want to build English + me(7) documents with the `-mfr` option). Depend on `preconv`. + (doc/webpage.ps): Convert from suffix rule to target rule. + (doc/ms.ps, doc/pic.ps, doc/webpage.ps): Add target rules and + dependencies. + (.ms.ps): Add commented-out suffix rule (since nothing uses it, + but might in the future). + (doc/meintro_fr.ps, .me.ps, doc/pic.ps, doc/webpage.ps): Migrate + expansions of `DOC_GROFF` to `DOC_GROFF_ONLY` to prepare for a + forthcoming simplification. + +2022-04-03 G. Branden Robinson + + * doc/doc.am: Clean generated doc files better. doc/me*.me were + getting left behind in the build tree. + (MOSTLYCLEANFILES): Add `GENERATEDDOCFILES`. This includes + `DOC_GNU_EPS`, so... + (clean_maintdoc): Drop phony target that manually removes it. + (maintainer-clean-local): Drop dependency on foregoing. + +2022-04-03 G. Branden Robinson + + * src/devices/xditview/xditview.am (install_xditview) + [!WITHOUT_X11]: Stop backing up existing "GXditview" and + "GXditview-color" application defaults files. There is no + symmetric restoration of them in the uninstall target, and it + seems like unjustifiable complexity to add such. These are + groff-specific file names, installed (by default) to /usr, + not /etc, so they are not going to be "configuration files" in + Debian-based systems, for example (and likely not elsewhere). + There are other ways to supersede application defaults for + programs using the X Toolkit Intrinsics. + +2022-04-03 G. Branden Robinson + + * doc/doc.am: Stop treating "gnu.eps" as an "example" file; it + is also used by pdfmark's cover.ms, which is ordinary + documentation. We therefore must not omit it when building. + (install-data-hook): Add dependency on new phony target, + "install_doc_gnu_eps". + (install_doc_examples): Move installation of "gnu.eps" from + here... + (install_doc_gnu_eps): ...to here. Also refactor the loop we + use to locate the file to follow a more idiomatic pattern. + +2022-04-03 G. Branden Robinson + + * doc/doc.am (dist-info-bits, install_infodoc, dist-gnueps): Fix + code style nit: use consistent "brace style" in conditionals and + loops. + +2022-04-01 G. Branden Robinson + + * doc/doc.am (mostlyclean_doc): When cleaning, try harder to + remove the image directory created by the "pic.html" and + "webpage.html" targets. + +2022-04-02 Ingo Schwarze + + * doc/doc.am: Stop installing doc/meintro.me.in, + doc/meintro_fr.me.in, and doc/meref.me.in. + +2022-03-30 G. Branden Robinson + + * doc/webpage.ms: Die horribly if `PSPIC` call fails. + +2022-03-30 G. Branden Robinson + + * tmac/pspic.tmac (pspic*error-hook): Define (as empty). + * man/groff_tmac.5.man (Auxiliary packages) : Document. + * NEWS: Add item. + +2022-03-29 G. Branden Robinson + + * doc/doc.am (doc/webpage.ps): Relocate target rule. + +2022-03-29 G. Branden Robinson + + * tmac/tests/pdfpic_does-not-choke-on-bad-pdfinfo-output.sh: + * tmac/tests/pdfpic_falls-back-to-PSPIC.sh: Remove output file + even when skipping test. Quote `fail` variable when checking it + with `test -z`. + +2022-03-29 G. Branden Robinson + + * man/groff_tmac.7.man (Auxiliary packages): Tweak sboxes + documentation to imply ms dependency. + + Fixes . + +2022-03-29 G. Branden Robinson + + * tmac/an.tmac (an*bookmark): Trivially refactor. Now that + we're no longer doing arithmetic on our first argument, simplify + our definition. Made possible by commit 3baf0e2f3, 23 February. + +2022-03-29 G. Branden Robinson + + * src/preproc/preconv/preconv.cpp (detect_file_encoding): Demote + an error diagnostic to a debugging message. libuchardet has no + man page, and inspecting the source of the + `uchardet_handle_data` function we find that it effectively + returns a Boolean value (if the result of a + `reinterpret_cast`(!) is not `NS_OK`). This is useless + information for a user-facing tool. We're designed to muddle on + regardless (see preconv(1)). + +2022-03-29 G. Branden Robinson + + * src/devices/grodvi/dvi.cpp (dvi_printer::set_color) + (draw_dvi_printer::fill_next): + * src/devices/grops/ps.cpp (output::put_color): + * src/libs/libgroff/color.cpp (color::print_color): Construct + doubles instead of casting to them. + +2022-03-28 G. Branden Robinson + + [doc]: Refactor handling of "gnu.eps" file. + + * doc/doc.am: Put "gnu.eps" in a Make macro, `DOC_GNU_EPS`. + ($(PROCESSEDEXAMPLEFILES) $(PROCESSEDDOCFILES), + doc/webpage.html, install_doc_examples): Migrate dependency to + `DOC_GNU_EPS`. + (doc/webpage.ps): Add (missing) dependency on `DOC_GNU_EPS`. + (DOC_GROFF_ONLY): Drop `-I` flag; it's not necessary given the + following. + (.ms.ps): Drop `-mwww` argument from suffix rule. A truly + generic ms document won't need it. + (doc/webpage.ps): Add target rule. Include `-mwww` argument. + (doc/webpage.ps, doc/webpage.html): Pass `-I` option to + `DOC_GROFF` and `DOC_GROFF_ONLY` (respectively) to enable + location of "gnu.eps" file. Search the build and source trees' + "doc" directories because the file can be generated as part of + the build or can come with the distribution archive. + (EXTRA_DIST): Drop redundant inclusion of "doc/gnu.xpm". + (clean_maintdoc): Add phony target to dispose of `DOC_GNU_EPS`. + (maintainer-clean-local): Depend on "clean_maintdoc". + + * tmac/tests/pdfpic_does-not-choke-on-bad-pdfinfo-output.sh: + * tmac/tests/pdfpic_falls-back-to-PSPIC.sh: Update tests to look + for "gnu.eps" in "doc" directory of build tree. Give generated + files distinguishable names so their tests can run concurrently. + +2022-03-23 G. Branden Robinson + + * doc/doc.am: Add new macro `PROCESSEDDOCFILES_PS` to isolate + names of targets in PostScript format. Expand this macro in + definition of `PROCESSEDDOCFILES` and use it to move PostScript + font description file dependencies of the latter and + `PROCESSEDEXAMPLEFILES` to the former. (At present, the + dependency might seem superfluous, since those files are in the + source distribution, but it's conceivable that in the near + future, they will be produced at build time from Adobe font + metric files; see font/devps/generate/Makefile). The "pic.html" + and "webpage.html" targets already had such a dependency because + of the way grohtml (pre-grohtml) works. + +2022-03-26 G. Branden Robinson + + * INSTALL.extra: Add a section on uninstalling. + +2022-03-23 G. Branden Robinson + + * doc/doc.am: Create target rule for "doc/grnexampl.ps" instead + of relying on a suffix rule. Explicitly depend on grn and eqn + executables. Produce output using their groff flags, "-ge". + +2022-03-25 G. Branden Robinson + + * tmac/pdfpic.tmac (PDFPIC): Fix breakage when no temporary + directory environment variables are defined: actually use string + interpolation syntax in comparand to output comparison + operator. Problem introduced by me in commits adc1999af and + 24900cf6d, 15 February. + +2022-03-25 G. Branden Robinson + + * font/devX100-12/devX100-12.am: + * font/devX100/devX100.am: + * font/devX75-12/devX75-12.am: + * font/devX75/devX75.am: Fix in-tree build; expand `fontdir` + instead of `abs_top_builddir` Make macro when defining Automake + variable for generated artifacts. Problem introduced by me in + commit 3c82cbbfe, 27 February. Thanks to Robert Goulding for + the report. + +2022-03-22 Ingo Schwarze + + * doc/doc.am: delete redundant "SUFFIXES +=" line + +2022-03-22 Ingo Schwarze + + * doc/doc.am: fix non-portable syntax in the meintro_fr.ps + target: This rule requires DOC_GROFF and hence $<, so turn it + into a suffix rule. + +2022-03-22 Ingo Schwarze + + * doc/doc.am: fix non-portable syntax in the doc/me*.me targets: + POSIX does not define the meaning of $< in non-suffix rules, so + use the portable $? instead. This is adequate here because each + of these three rules has exactly one prerequisite. + +2022-03-22 Ingo Schwarze + + * doc/doc.am: fix non-portable syntax in the groff-man-pages.* + targets by using DOC_GROFF_ONLY rather than DOC_GROFF in order + to not use $< outside a suffix rule; DOC_GROFF functionality is + not needed here in the first place. + +2022-03-21 G. Branden Robinson + + * tmac/an.tmac: + * tmac/doc.tmac: Stop remapping input hyphens on `utf8` device. + +2022-03-21 G. Branden Robinson + + * tmac/doc.tmac: Stop remapping ` and ' on `utf8` output device. + Aligns mdoc(7) with commit 697e6db7f, 19 October 2020 (for + man(7)). + +2022-03-21 G. Branden Robinson + + * src/utils/afmtodit/afmtodit.pl: Fix bug introduced in commit + 0d451902c, 10 March. Don't store a newline in the version + string. Put `\n` in its interpolation context as necessary. + +2022-03-19 G. Branden Robinson + + Install ptx.tmac. + + * tmac/tmac.am (TMACNORMALFILES): Add it. + * NEWS: Report availability. + + Fixes . Thanks to Ralph + Corderoy for the report. + +2022-03-19 G. Branden Robinson + + Drop ditroff(7) document. It says nothing that is not covered + elsewhere. + + * man/ditroff.7.man: Delete. + * doc/doc.am (GROFF_MAN_PAGES): + * man/man.am (man7_MANS, EXTRA_DIST): Stop processing, shipping. + * src/roff/groff/groff.1.man: Drop cross reference to it. + * NEWS: Add item. + + Fixes . + +2022-03-18 G. Branden Robinson + + [preconv]: Trivially refactor. + + * src/preproc/preconv/preconv.cpp: Use diagnostic message + functions from libgroff where possible. Explain in a comment + why we don't use `debug()`. Boolify and rename some variables, + and use Boolean literals to assign to them. + debug_flag -> is_debugging + invalid_warning -> emit_invalid_utf8_warning + incomplete_warning -> emit_incomplete_utf8_warning + Rename `expected_bytes` to `expected_byte_count`. Except for + the debugging flag, these are all members of `struct + conversion`. + (get_tag_lines): Migrate to `warning()`. + (detect_file_encoding): Migrate to `error()` and `fatal()`, as + appropriate. + (utf8::invalid, utf8::incomplete, get_tag_lines): Don't break a + line in the middle of a diagnostic; doing so frustrates grepping + and necessarily makes an assumption about the terminal width. + +2022-03-17 G. Branden Robinson + + [troff]: Trivially refactor. + + * src/roff/troff/input.cpp: Rename global variable + `have_string_arg` to `have_multiple_params` and demote it from + an integer to a Boolean. Assign Boolean literals to it. + (read_long_escape_parameters, get_copy, token::next): Do it. + +2022-03-16 G. Branden Robinson + + [tbl]: Fix Savannah #62191. + + * src/preproc/tbl/main.cpp (table_input::get): Increment input + line counter when encountering an escaped newline; this fixes + inaccurate diagnostics from the formatter at any point in a + document after a line-continued row of table data. Also drop a + "perhaps" comment. I tested the surmise (setting the FSM state + to "START"), and it results in bad formatting. + + Fixes . Problem appears + to date back to groff 1.02 (June 1991) at the latest. + +2022-03-16 G. Branden Robinson + + [tbl]: Regression-test Savannah #62191. + + * src/preproc/tbl/tests/count-continued-input-lines.sh: Do it. + * src/preproc/tbl/tbl.am (tbl_TESTS): Run test. + +2022-03-16 G. Branden Robinson + + * doc/groff.texi (Environments): Clarify environment handling. + * man/groff.7.man (Environments): Add new section. + + Fixes . Thanks to Dave + Kemper for the report and a suggested patch. + +2022-03-15 G. Branden Robinson + + * tmac/e.tmac (initialization): Define `@b` as empty if + formatting for HTML, because no page breaks occur in that + format. + + Fixes . + +2022-03-15 G. Branden Robinson + + * src/devices/grodvi/dvi.cpp (usage): Align usage message with + man page; disclose `-l` option. + +2022-03-15 G. Branden Robinson + + * src/devices/grodvi/dvi.cpp (main): + * src/devices/grops/ps.cpp (main): Update diagnostic: + characterize bad `-w` argument as "invalid", not "bad", and + explicitly report it as ignored. + + * src/devices/grodvi/dvi.cpp (main): Report invalid parameter + in `-w` diagnostic. + +2022-03-15 G. Branden Robinson + + * src/devices/grodvi/dvi.cpp (dvi_printer::set_color) + (draw_dvi_printer::fill_next): + * src/devices/grops/ps.cpp (output::put_color): + * src/libs/libgroff/color.cpp (color::print_color): Explicitly + cast `enum` divisors to `double`; quietens + `-Wdeprecated-enum-float-conversion` warnings. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2022-03-15 G. Branden Robinson + + * tmac/an.tmac: Recover more quickly from missing `EE` calls. + (initialization): Define new strings, `an*body-family` and + `an*example-family` to house the font families used in these + rendering contexts. + (TH, SH, SS): Restore the font family to `an*body-family`. + (TH): Set font style to roman as well. + (EX): Change to `an*example-family` instead of literal "C". + + Fixes . + +2022-03-15 G. Branden Robinson + + * tmac/e.tmac: Test register for existence before using it to + set hyphenation mode. A site troffrc or other local + customization might remove the register (which is guaranteed to + be set under the stock configuration) and, perversely, Heirloom + Doctools troff interprets a `do` request, instead of ignoring it + as a historical troff implementation would, so if they borrow + our me(7) changes, the register would be unset, interpolate + zero, and hyphenation would wind up disabled. + + Fixes . Thanks to Dave + Kemper for the report. + +2022-03-14 G. Branden Robinson + + [tests]: Rename test to apply naming scheme. + + * tmac/tests/pdfpic_falls_back_to_PSPIC.sh: Rename this... + * tmac/tests/pdfpic_falls-back-to-PSPIC.sh: ...to this. + * tmac/tmac.am (tmac_TESTS): Use new name. + +2022-03-14 G. Branden Robinson + + * src/devices/grops/ps.cpp (usage): Align usage message with man + page synopsis. + +2022-03-13 G. Branden Robinson + + * doc/groff.texi (Input Line Traps): Fix error; input traps do + _not_ ignore control lines. Error appears to have crept in with + the first version of our Texinfo manual, shipped with groff 1.14 + {December 1999}. + +2022-03-13 G. Branden Robinson + + * font/devps/devps.am: Rename targets. + (fonts): + (devps_fonts): Rename these... + (maintainer-font-descriptions): + (devps_font-descriptions): ...to these. Add comments explaining + what they're for and why they aren't used in a build. + + * font/devps/generate/Makefile: Add `outdir` variable to store + destination directory of font description files, and update all + targets that write artifacts to use this directory. This makes + the targets "phony", which I don't regard as a problem since the + generated artifacts are kept under source control, and this + isn't really a user-facing script (even though it gets + installed). I think there is a good chance that this will + become a shell script, because to avoid regressions we need to + generate the font descriptions using both the 229-glyph and + 314-glyph versions of the Adobe fonts' AFM files (so that we get + wider glyph coverage _and_ more kerning pair data) and we need + to add kerning information for the ellipsis (Savannah #58897). + (symbolsl.afm): Revise generation process to be sensitive to + failure. + +2022-03-09 G. Branden Robinson + + * font/devps/symbolsl.afm: New file. + * font/devps/devps.am (EXTRA_DIST): We have long shipped + "symbol.afm" with the distribution archive--I don't see why we + don't ship "symbolsl.afm" and "zapfdr.afm" as well (metrics for + `SS`, the slanted symbol font, and ZDR, reversed Zapf Dingbats). + Like the Type 1 font descriptions themselves, this file is + updated only in "maintainer mode", not as part of the build. + Moreover, these fonts are not part of the PostScript level 2 + base 35 fonts so their AFM files are unlikely to be readily + available elsewhere. + +2022-03-09 G. Branden Robinson + + * src/utils/afmtodit/afmtodit.pl: Trivially refactor. Store the + program's version string in scalar `afmtodit_version` and use + that in the usage message and comment embedded in the output. + +2022-03-09 G. Branden Robinson + + * src/utils/afmtodit/afmtodit.pl: Fix code style nits. Migrate + to the shebang line style we use in more recently modified Perl + scripts. Replace `-w` with `use warnings;`. Shorten an output + comment since the groff version string can grow long (see commit + 1264531310, 14 January 2018). + +2022-03-09 G. Branden Robinson + + * src/utils/afmtodit/afmtodit.pl: Stop writing full file name to + the generated font description file as the "name" (i.e., don't + include directory components). + + Fixes . Thanks to Dave + Kemper for the discussion and code review. + +2022-03-08 G. Branden Robinson + + * src/utils/afmtodit/afmtodit.1.man: + * src/utils/afmtodit/afmtodit.pl: Update and align man page + synopsis, option descriptions, and command usage output. + +2022-03-07 G. Branden Robinson + + * tmac/X.tmac: Redirect `fchar` requests for \[lq] and \[rq] to + \[dq] since the X11 Type 1-based text fonts encode ISO 8859-1 + {Latin-1} and don't have typopgrapher's quotes. Drop `fchar` + request for \[aq], which _is_ represented, per recent changes. + +2022-03-07 G. Branden Robinson + + * /font/devX100-12/CB: + * /font/devX100-12/CBI: + * /font/devX100-12/CI: + * /font/devX100-12/CR: + * /font/devX100-12/HB: + * /font/devX100-12/HBI: + * /font/devX100-12/HI: + * /font/devX100-12/HR: + * /font/devX100-12/NB: + * /font/devX100-12/NBI: + * /font/devX100-12/NI: + * /font/devX100-12/NR: + * /font/devX100-12/TB: + * /font/devX100-12/TBI: + * /font/devX100-12/TI: + * /font/devX100-12/TR: + * /font/devX100/CB: + * /font/devX100/CBI: + * /font/devX100/CI: + * /font/devX100/CR: + * /font/devX100/HB: + * /font/devX100/HBI: + * /font/devX100/HI: + * /font/devX100/HR: + * /font/devX100/NB: + * /font/devX100/NBI: + * /font/devX100/NI: + * /font/devX100/NR: + * /font/devX100/TB: + * /font/devX100/TBI: + * /font/devX100/TI: + * /font/devX100/TR: + * /font/devX75-12/CB: + * /font/devX75-12/CBI: + * /font/devX75-12/CI: + * /font/devX75-12/CR: + * /font/devX75-12/HB: + * /font/devX75-12/HBI: + * /font/devX75-12/HI: + * /font/devX75-12/HR: + * /font/devX75-12/NB: + * /font/devX75-12/NBI: + * /font/devX75-12/NI: + * /font/devX75-12/NR: + * /font/devX75-12/TB: + * /font/devX75-12/TBI: + * /font/devX75-12/TI: + * /font/devX75-12/TR: + * /font/devX75/CB: + * /font/devX75/CBI: + * /font/devX75/CI: + * /font/devX75/CR: + * /font/devX75/HB: + * /font/devX75/HBI: + * /font/devX75/HI: + * /font/devX75/HR: + * /font/devX75/NB: + * /font/devX75/NBI: + * /font/devX75/NI: + * /font/devX75/NR: + * /font/devX75/TB: + * /font/devX75/TBI: + * /font/devX75/TI: + * /font/devX75/TR: Regenerate font descriptions with xtotroff, + using updated ISO-8859_1 map. \[aq] and \[oq] are now aliases + of "'" and \[ga] is an alias of "`". This change probably + should have been made when the X11 fonts were corrected in + XFree86 4.0 (March 2000). See + . + + Fixes . + +2022-03-07 G. Branden Robinson + + * src/libs/libxutil/DviChar.c (ISO_8859_1_map): Fix incorrect + assignment of Latin-1 grave accent to \[oq] special character; + reassign it to the neutral apostrophe. Map \[aq] to neutral + apostrophe. Map \[ga] to '`'. + +2022-03-07 G. Branden Robinson + + * src/utils/xtotroff/xtotroff.1.man (Options) <-d>: Document new + option. + * src/utils/xtotroff/xtotroff.c (usage): Align with man page. + +2022-03-07 G. Branden Robinson + + * doc/groff.texi (Manipulating Filling and Adjustment): + Explicitly identify the page offset as an output line property + that is not determined until a break occurs. + + (Line Layout) : Correct error; the page offset for terminal + devices is set by "tty.tmac", not "troffrc". (The manual has + been wrong for a long time; we've had it in tty.tmac since James + Clark put it there in 1992.) Recast and tighten wording. Drop + the word "horizontal"; there is no vertical page offset (as + such) in *roff. Replace hand-waving about unexpected results + with a description of the formatter's behavior. Document + request behavior without an argument before getting into the + weeds (and CSTR #54 errata). Migrate terminology from "scaling + indicator" to "scaling unit". + + Fixes . + +2022-03-07 G. Branden Robinson + + * doc/groff.texi (Expressions): Expand '|' operator explanation. + Split discussion of its application into horizontal and vertical + contexts. Add example of vertical usage. + + Fixes . + +2022-03-07 G. Branden Robinson + + * src/roff/troff/input.cpp: Trivially refactor. Drop `#define` + that was working around a GCC 2.95-era libstdc++ problem. + Shorten long line. + (get_char_for_escape_parameter): Demote parameter from `int` to + `bool` and use Boolean literal for default argument. Annotate a + null pointer constant. + +2022-03-07 G. Branden Robinson + + [troff]: Rename some internal functions. + + * src/roff/troff/input.cpp: Do it. + (read_escape_name): + (read_long_escape_name): + (read_two_char_escape_name): + (get_char_for_escape_name): + (read_increment_and_escape_name): Rename these... + (read_escape_parameter): + (read_long_escape_parameters): + (get_char_for_escape_parameter): + (read_two_char_escape_parameter): + (read_increment_and_escape_parameter): ...to these. + (read_two_char_escape_parameter, read_long_escape_parameters, + read_escape_parameter, read_increment_and_escape_parameter, + get_copy, token::next): Update call sites. + +2022-03-07 G. Branden Robinson + + * src/roff/troff/input.cpp (get_char_for_escape_name): Recast + diagnostic messages to more accurately refer to escape + "sequence" rather than "name". "Name" is a confusing term here, + given that it also applies to a group of objects sharing a name + space (natch): requests, macros, strings, and diversions. + Further, the "escape name" cited by these diagnostics is not the + escape function selector; that is, the character after the + escape character which determines how the escape sequence is to + be interpreted. These diagnostics are only thrown after that + function is known, however, when parsing of an escape sequence + parameter is attempted. + (input_char_description): Drop leading articles ("a") from + input character descriptions, to economize in diagnostic + messages this function helps produce. + (non_empty_name_warning): Use zero copula for economy. + + * src/roff/troff/input.cpp (empty_name_warning, read_size) + (token::get_char, check_missing_character): + * src/roff/troff/number.cpp (start_number, parse_term): Recast + messages to more consistently use the form "expected X, got Y" + where feasible. + + * src/roff/troff/number.cpp (start_number): Say "numeric + expression missing" instead of "missing number"; we don't + require a terminal symbol in the expression grammar here. Also + use `tok.description()` where we can, and remove assumption that + the escape character is the default. + +2022-03-06 G. Branden Robinson + + * tmac/an.tmac (AT, UC, HP): Add deprecation warnings. For the + last, only do so if we're not inside a synopsis (SY/YS), since + our definition of `SY` calls `HP` internally. (This does seem + hypocritical. Perhaps if we knew the correct CSS incantation + to speak in grohtml, we could un-deprecate `HP`.) + +2022-03-06 G. Branden Robinson + + * tmac/tmac.an (M4CHECK): Rename stamp file to make its purpose + clearer. + +2022-03-06 G. Branden Robinson + + [man]: Tweak customization management. + + * tmac/an.tmac: Load "man.local" with `msoquiet` request, so + people can get rid of the file if they don't need it. + (PT, BT): Define these macros only if not already defined. This + is slightly less paranoid but far more ergonomic, given + interactions with the andoc wrapper. Now user-defined page + header traps (PT) defined in man.local can take effect on the + first page rendered. + + * tmac/groff_man.7.man.in (Hooks): Document how to remove page + headers and/or footers entirely. + + Fixes . + +2022-03-06 G. Branden Robinson + + [refer,mm]: Add and use `ref*reset` macro to clean up between + bibilography entries. + + * tmac/refer.tmac (]-): Move string clean up logic from here... + (ref*reset): ...to this new macro. Now we can also use it... + + * contrib/mm/refer-mm.tmac (ref*][-first-pass): ...here. + + Problem appears to date back to refer-mm.tmac's introduction in + January 2011. Thanks to Bjarni Ingi Gislason for the root-cause + analysis and proposed fix, to which I applied the DRY principle + and added a reset of `ref*string` as well. + + Fixes . + +2022-03-06 G. Branden Robinson + + [mm]: Regression-test Savannah #60657. + + * contrib/mm/tests/remove-stale-bib-entry-data.sh: Do it. + * contrib/mm/tests/artifacts/60657.ref: Add new file. + * contrib/mm/mm.am (mm_TESTS): Run test. + (EXTRA_DIST): Ship test artifact in distribution archive. + + Thanks to Bjarni Ingi Gislason for the straightforward + bug reproducer. + +2022-03-06 G. Branden Robinson + + [refer]: Report correct line number in bibliography file + diagnostics. + + * src/preproc/refer/refer.cpp (do_bib): Set line number to 1 + upon successfully opening a bibliography file. + + Problem appears to date back to groff 1.02 (June 1991) at the + latest. + + Fixes . + +2022-03-06 G. Branden Robinson + + [refer]: Regression-test Savannah #62124. + + * src/preproc/refer/tests/report-correct-line-numbers.sh: Do it. + * src/preproc/refer/tests/artifacts/62124.ref: Add new file. + * src/preproc/refer/refer.am (refer_TESTS): Run test. + (EXTRA_DIST): Ship test artifact in distribution archive. + +2022-03-05 G. Branden Robinson + + * src/roff/troff/div.cpp + (top_level_diversion::transparent_output): + * src/roff/troff/input.cpp (transparent_translate): Suppress two + troublesome (i.e., more or less spurious) error diagnostics + about transparent output/throughput unless the environment + variable `GROFF_ENABLE_TRANSPARENCY_WARNINGS` is present. This + is a bit of a bodge until we get diversion sanitization worked + out. See Savannah #61407. + +2022-03-04 G. Branden Robinson + + [preconv]: Stop assuming that the default input stream, or an + explicit '-' operand, is the only unseekable stream. Check + instead. + + * src/preproc/preconv/preconv.cpp (do_file): Add new Boolean + `is_seekable`. Test the input stream with `fseek()` per a + suggestion from Ingo Schwarze. Report unseekability in debug + output and skip coding tag and uchardet tests altogether + {precisely paralleling our description in the preconv(1) man + page}. Also update debugging output to say "" + instead of "-". + + Fixes . + +2022-03-04 G. Branden Robinson + + [preconv]: Regression-test Savannah #62131. + + * src/preproc/preconv/tests/do-not-seek-the-unseekable.sh: Do + it. + * src/preproc/preconv/preconv.am (preconv_TESTS): Run test. + +2022-03-01 G. Branden Robinson + + * src/preproc/tbl/main.cpp (process_format): Update diagnostic + to recognize that a font mounting position is also an acceptable + argument to the 'f' column modifier. + +2022-02-27 G. Branden Robinson + + Refactor X11 font description generation. Integrate it with our + "new" (post-2014) Automake-based build system. + + * src/utils/xtotroff/Makefile.in: Delete relic of old build + system. Also, it had a bug: it generated X11 output device + 'DESC' files with a "unitwidth 10" directive even for the "-12" + devices, which is not correct (the in-tree DESC files we've been + shipping for years were nevertheless correct, apparently fixed + by hand by James Clark in groff 1.07 [March 1993]). + + * src/utils/xtotroff/xtotroff.am: Define `xtotroff` variable for + use by X11 font description generation targets below. + + * font/devX100-12/devX100-12.am: + * font/devX100/devX100.am: + * font/devX75-12/devX75-12.am: + * font/devX75/devX75.am: Add new (phony) targets, variously + named "devX{100,100_12,75,75_12}", to generate the corresponding + output device's DESC file and run xtotroff(1) to generate its + font description files. Be sure to set the correct "unitwidth" + for the "-12" devices. Add new dependency-only rule + "maintainer-font-descriptions" depending on these new targets + for convenience (and future expansion to devps and devlj4). + + * FOR-RELEASE: Document existence of + "maintainer-font-descriptions" Make target and when to run it. + + Running this target with the aforementioned bug fix, overwriting + the in-tree DESC and font description files using data gathered + from a running X server, results in no changes whatsoever. Say + what you will about X11 core font technology--it's stable. + +2022-02-27 G. Branden Robinson + + Rename and ship "FontMap-X11". xtotroff(1) is not very useful + without a font name mapping file to read. To date it has been + available only in the source distribution. Remedy that. The + file is placed directly in the groff font directory alongside + the device directories because it applies to four different + devices, and four copies of this data are not required. + + * src/devices/xditview/FontMap: Rename to... + * src/devices/xditview/FontMap-X11: ...this. + + * LICENSES: + * src/devices/xditview/xditview.am (EXTRA_DIST): Reflect rename. + + * src/devices/xditview/xditview.am (install_xditview + [!WITHOUT_X11], uninstall_xtdiview): (Un-)install it. + + * src/utils/xtotroff/xtotroff.1.man (Files): Add section + documenting the presence and purpose of this file. + +2022-02-26 G. Branden Robinson + + [xtotroff]: Add `-d` option to produce font description files in + specified directory. + + * src/utils/xtotroff/xtotroff.c: Do it. Add global `destdir` + pointer. + (xtotroff_exit): Add new function to clean up storage allocated + by `strdup()` (below) for destination directory. + (MapFont): Introduce new variable `file_name`, into which we + assemble a destination file name from `destdir` (if not null) + and the troff font name. Handle memory allocation failure (by + carefully dying). Free allocated storage on success and failure + paths out of the function. + (usage): Document new `-d` option. + (main): Instruct `getopt_long` to expect a `-d` flag with an + argument. Use `strdup()` to make a copy of any such option + argument. Call `xtotroff_exit()` instead of `exit()`. + + * src/utils/xtotroff/xtotroff.1.man: Document new `-d` option. + +2022-02-26 G. Branden Robinson + + [xtotroff]: Trivially refactor. + + * src/utils/xtotroff/xtotroff.c: Boolify. Include `stdbool.h` + and `errno.h` headers. + (charExists, CanonicalizeFontName, FontNamesAmbiguous, MapFont): + Boolify. Demote return type from `int` to `bool` and return + Boolean instead of integer literals. + (FontNamesAmbiguous, main): Reorder equality comparisons with + simple left-hand sides to avoid inadvertent lvalue assignments. + (FontNamesAmbiguous, MapFont): Refer to font name as "invalid", + not "bad", in diagnostic messages. + (MapFont, main): Use `strerror()` instead of `perror()` so that + diagnostics include the program name and an indication of + problem severity. + (MapFont): Compare `FILE` stream pointer to `NULL` instead of + treating it as a Boolean. + (main): Use `EXIT_SUCCESS` and `EXIT_FAILURE` constants from C + library instead of integer literals for exit status. + +2022-02-24 G. Branden Robinson + + [pic]: Fix "unused result" compiler warning. + + * src/preproc/pic/pic.ypp (placeless_element) : Check return + value of `system()` to quieten `-Wunused-result` warning; if it + is less than zero, report it to the standard error stream. + +2022-02-23 G. Branden Robinson + + * tmac/safer.tmac: Drop file from distribution. It contained + only comments. + * tmac/tmac.am (TMACNORMALFILES): Delete reference. + * NEWS: Add item. Suggest two workarounds for its absence. + + Fixes . + +2022-02-23 G. Branden Robinson + + * tmac/doc.tmac (initialization): Drop definition of + `doc-curr-size` register. It is no longer needed since nothing + internal to the package now changes the type size. + + * tmac/doc.tmac (Fl, doc-print-recursive, doc-print-prefixes) + (doc-generic-macro, Ar, Cd, doc-do-func-decl, Fd, In, Nm, Pa) + (Tn, doc-enclose-string, Ef, Bd, doc-save-global-vars) + (doc-restore-global-vars, doc-diag-list, Xr, Dl, Vt, Ft, Fa) + (doc-do-func, Fn, doc-do-func-args, Fo, Fc, %A, %B, %C, %D, %I) + (%J, %N, %O, %P, %Q, %R, %T, %U, %V, doc-do-reference, Hf, An) + Lk): + * tmac/mdoc/doc-common (Sh, Ss, Rd): + * tmac/mdoc/doc-syms (Ux, Bx, At, Dx, Fx, Nx, Ox, Bsx, St, Lb): + Drop interpolations of the string and comments documenting that + each macro has a side effect on the type size. + +2022-02-23 G. Branden Robinson + + * tmac/doc.tmac (Tn): + * tmac/mdoc/doc-syms (Ux, Bx): Stop interpolating string + `doc-Tn-font-size` to set macro arguments at a smaller type + size. This leaves the string without a purpose, so... + + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: Drop definitions of `doc-Tn-font-size`. + + * tmac/mdoc/doc-syms: Drop interpolations of that string from + numerous other string definitions. + + Fixes . + +2022-02-23 G. Branden Robinson + + Revert addition of man(7) `BD` register. This feature, which I + introduced in commit ea3b27102f (31 January) doesn't work + because pdf.tmac normalizes the bookmark depth. Embedding a man + page in a larger PDF document with appropriately nested + bookmarks is a project that will have to await another day (or + perhaps already has tools to implement it). + + * tmac/an.tmac: Do it. + * tmac/groff_man.7.man.in: De-document it. + +2022-02-23 G. Branden Robinson + + * tmac/pdf.tmac: Add string containing the name of the macro + package for use in diagnostic messages. + (pdf:warn, pdf:error): Use it. + + Continues the long process of fixing Savannah #52463. + +2022-02-23 G. Branden Robinson + + [man,mdoc,me]: Revise hyphenation localization. + + * tmac/an.tmac (an*reset-hyphenation-mode): New macro sets the + hyphenation mode appropriate to the locale depending on the + values of `cR` (continuous rendering mode) and `HY` (hyphenation + enablement); the latter is now interpreted as a Boolean. Define + new register `an*hyphenation-mode` reflecting these conditions. + (TH): Call the foregoing instead of invoking `hy` request. + (MR): Restore hyphenation mode to `an*hyphenation-mode`. + (initialization): Simplify; if not defined, set `HY` to 1. + + * tmac/e.tmac (ld): Set the hyphenation mode here instead of in + initialization (which already calls this macro). Set the mode + to 6 for the benefit of anyone borrowing our me(7) changes, but + then immediately change to the mode determined by the + localization file. + + * tmac/mdoc/doc-common (doc-hyphen-flags): Set a hyphenation + mode appropriate to the locale, depending on the values of `cR` + and `HY`. + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: Simplify initialization; if not defined, + set `HY` to 1. + + * tmac/cs.tmac: + * tmac/de.tmac: + * tmac/en.tmac: + * tmac/fr.tmac: + * tmac/it.tmac: + * tmac/sv.tmac: Before switching locales, set a flag if + troublesome value 2 of the hyphenation mode is set so that we + can preserve it. Shift man(7) and me(7) logic to follow setup + of the new hyphenation mode; for the former, call the new + `an*reset-hyphenation-mode`. + + * tmac/groff_man.7.man.in: + * tmac/groff_mdoc.7.man: Document updated meaning of `HY` + register. + + * NEWS: Add item noting change of man(7) `HY`'s meaning. Update + existing item regarding mdoc(7)'s support for it (groff 1.22.4 + mdoc(7) didn't recognize the register at all). + + Fixes (for real this + time?). + +2022-02-22 G. Branden Robinson + + [man]: Regression-test Savannah #61734. + + * tmac/tests/an_reset-hyphenation-correctly.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-02-21 G. Branden Robinson + + * man/groff_char.7.man (History): Add new section. + (See also): Add cross reference to 1976 edition of CSTR #54. + +2022-02-21 G. Branden Robinson + + * tmac/groff_man.7.man.in (Document structure macros) + [style]: Add material cautioning writers against asoociating + the disablement of filling with some sort of "literal mode". + Document still-operational status of inter-sentence space + supplementation. + (Notes) [style]: Describe an alternative (and macro + call-symmetrical) means of using `RS` and `RE` with `TP`. + +2022-02-20 G. Branden Robinson + + * doc/doc.am: Add phony targets "man-all" and "man-clean" to + {re-}generate and delete all man pages, respectively. + + Arguably fixes . + +2022-02-20 G. Branden Robinson + + * Makefile.am (.man): Prefix hyphenation control escape + sequences to more configuration-time interpolations to prevent + their hyphenation: @DEVICE@, @g@, @INDEX_SUFFIX@, @PAGE@, + @TMAC_{AN,M,S}_PREFIX@, @TMAC_MDIR@. + +2022-02-16 G. Branden Robinson + + [man]: Refactor `EX` and `EE` macros. + + * tmac/an-ext.tmac: Add new `mC` string to store the font name + to be used for example regions. In AT&T device-independent + troff, "CW" was a common name, so use that. It is however a + terrible fit for groff's font family and style-combination + functionality, and is inflexible in the face of font selection + requests and escape sequences within the example region. (One + either needs to know the names of the fonts available on the + output device, or suffer the indignity of mixed constant-width + and proportional typefaces.) Relatedly, drop groff-specific + font remapping requests. + (EX, EE): Ignore definition if GNU troff is the formatter. Drop + font family manipulation. Drop specialized logic for groff's + DVI output device. + + * tmac/an.tmac (initialization): Resurrect font remapping + requests here. + (EX, EE): Add new definitions, saving and restoring more state + and remapping DVI output device fonts to reflect the absence of + CWB and CWBI faces. + +2022-02-16 G. Branden Robinson + + * tmac/an-ext.tmac: Slightly refactor. Stop using groff's `HY` + register to restore the hyphenation mode, since I plan to change + its semantics to a Boolean value (see Savannah #61734). + Introduce new register `mJ` to store "1" (if not groff) and the + current hyphenation mode otherwise. Explain why in a comment. + (YS, UE, ME, MR): Restore hyphenation mode using `mJ` instead of + `HY`. + +2022-02-16 G. Branden Robinson + + * tmac/an-ext.tmac: Trivially refactor. Use a better idiom + {seen in James Clark's changes to BSD me(7)} for conditionally + defining a (simple) macro. + +2022-02-16 G. Branden Robinson + + * src/devices/grotty/tty.cpp (tty_printer::special): Warn upon + encountering unrecognized device control commands using the + 'tty:' tag. + +2022-02-16 G. Branden Robinson + + [grotty]: Remove 'sgr' device control command. + + * src/devices/grotty/tty.cpp (tty_printer::special): Do it. + * src/devices/grotty/grotty.1.man (Device control commands): + {De-}document it. + * NEWS: Add item. + + Fixes . + +2022-02-15 G. Branden Robinson + + * tmac/pdfpic.tmac: Add support for Cygwin/MinGW temporary + directory conventions. + +2022-02-15 G. Branden Robinson + + * tmac/pdfpic.tmac: Search for temporary directories as groff(1) + does, instead of going straight to /tmp. + (pdfpic@get-temporary-directory): New function checks each of + its arguments for validity as a temporary directory; if one is + found, its name is left in `pdfpic*temporary-directory`. + (pdfpic@cleanup): Remove strings `pdfpic*temporary-directory` + and `pdfpic*temporary-file`. + (PDFPIC): Call `pdfpic@get-temporary-directory`, using the + contents of the environment variables $GROFF_TMPDIR and $TMPDIR, + and then /tmp, in that order. Store the temporary file name in + string `pdfpic*temporary-file`. Use this string in subsequent + `sy` and `so` requests. + + Fixes for Unix systems. + +2022-02-15 G. Branden Robinson + + [tests]: Add test for PDFPIC fallback to PSPIC. + + * tmac/tests/pdfpic_falls_back_to_PSPIC.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-02-15 G. Branden Robinson + + [tests]: Tweak PDFPIC test input. + + * tmac/tests/pdfpic_does-not-choke-on-bad-pdfinfo-output.sh: + Eliminate unnecessary blank lines from input. Also call gs(1) + with '-q' in addition to '-o'. (Why does the latter not imply + the former?!) Thanks to Deri James for the advice. + +2022-02-15 G. Branden Robinson + + * tmac/pdfpic.tmac: Slightly refactor. + (pdfpic@cleanup, PDFPIC): Rename `pdfpic*file-name` to + `pdfpic*file-name-base` since it is not used as a complete file + name (but rather a basis for an ".eps" extension). + (PDFPIC): When testing PDF file extension, include the "."; a + file name like "mxyzptlkpdf" is too dubious to accept. Also + explicitly compare `systat` register as equal or not equal to + zero, since its truth value is inverted from the expectations of + *roff expressions. + +2022-02-15 G. Branden Robinson + + * tmac/pdfpic.tmac (PDFPIC): Refactor PDFPIC_NOSPACE handling. + Stop shelling out to create, and then sourcing, a temporary file + just to obtain the value of an environment variable. groff + already has the `\V` escape sequence for that purpose (it's even + safe!). Check that the value of $GROFF_PDFPIC_NOSPACE is a + valid numeric expression before assigning it to a register. + Trivially, use '=' instead of '==' as an equality operator. + *roff languages do not use '=' as an assignment operator, and I + believe the '==' synonym to be a sop to C programmers. + +2022-02-14 G. Branden Robinson + + [man]: Stop attempting to adjust pargraph tag lines. + + * tmac/an.tmac (TP): Disable adjustment inside the diversion. + (an-write-paragraph-tag): Restore adjustment outside of it. + + Fixes . + +2022-02-13 G. Branden Robinson + + * tmac/e.tmac (@z): Conceal bare tab after request name (exposed + by no longer stripping the macro file). See commit ad0575f20, 9 + December. + +2022-02-12 G. Branden Robinson + + [grops,troff]: Migrate to term "scaling unit" in diagnostics. + + * src/devices/grops/ps.cpp (ps_printer::do_import): + * src/roff/troff/input.cpp (warnscale_request): + * src/roff/troff/number.cpp (parse_term): Do it. + +2022-02-12 G. Branden Robinson + + [me]: Add nroff mode fallback for `u` macro. + + * tmac/e.tmac (u): On nroff devices, bracket the first argument + with \(ul (underline rule) special character escape sequences. + {In plain language, '.u "like this"' renders "_like this_".} + + I regard this as a cosmetic and semantic improvement; since the + quarter-em vertical motions used in troff mode were ignored in + nroff mode, the effect was not underlining but a sort of + strike-through, visible only at spaces in the argument. The use + of this macro was thus invisible in nroff output if no spaces + were present in the argument. This is probably the best we can + do without a fatter interface to terminal device capabilities. + +2022-02-12 G. Branden Robinson + + [me]: Simulate boxed text support on nroff devices with ISO 6429 + color escape sequences. + + * tmac/e.tmac (bx): Do it. Add further fallback for non-groff + formatters in nroff mode, bracketing the boxed argument with '|' + glyphs. + * doc/meref.me.in: Document it. + + Fixes . + +2022-02-12 G. Branden Robinson + + [me]: Rename registers `$v` -> `tv`, `$V` -> `dv`. + + * tmac/e.tmac: Do it. Also include much commentary (including + some from James Clark in 1992) attempting to illuminate the + confusing history (and naming) of `$[rRvV]`. + + * doc/meref.me.in: Document it. Introduce new terms + "text vertical spacing" and "display vertical spacing" earlier + and use them to condense and clarify discussions of their use. + + * NEWS: Add item. + + Fixes . + +2022-02-09 G. Branden Robinson + + * doc/groff.texi (Deferring Output): Add new node introducing + and motivating environments, diversions, and traps. + +2022-02-06 G. Branden Robinson + + [tmac]: Add more compatibility mode guards. + +2022-02-06 G. Branden Robinson + + * tmac/pdf.tmac: Add compatibility mode guards so that we can + run even if troff is given the -C option. Resurrect your + vintage 1975 Sixth Edition Unix manuals from '.deth' and format + them in PDF today! + + Fixes . + +2022-02-06 G. Branden Robinson + + * tmac/andoc.tmac: Prefix diagnostic with package file name + literally. + +2022-02-04 G. Branden Robinson + + [man]: Trivially refactor. + + * tmac/an.tmac (an*localize): Rename to... + (an*localize-strings): ...this. + (TH): Update call site. + +2022-02-03 G. Branden Robinson + + [docs]: Present several fundamental concepts. + + * doc/groff.texi (Page Geometry): + * man/roff.7.man (Concepts): Add new node/section. + - page geometry + - basic units + - device resolution + - drawing position + - text baseline + - page offset + - vertical spacing + - page break + + Fixes the remainder of . + +2022-02-02 G. Branden Robinson + + [me]: Add page length insufficiency check. + + * tmac/e.tmac (@h): Port Keith Marshall's page length checker + from ms(7). + + Fixes and + . + +2022-02-02 G. Branden Robinson + + [me]: Add test for insufficient page length error. + + * tmac/tests/e_rejects-too-short-page-lengths.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-02-02 G. Branden Robinson + + [me]: Slightly refactor. + + * tmac/e.tmac (@h): Use groff default scaling operator in + conditional expression. Add `do` requests so that the logic for + checking the line length works in compatibility mode. Also move + misplaced parenthesis in conditional expression. + +2022-02-02 G. Branden Robinson + + [ms]: Refactor insufficient page length check. + + * tmac/s.tmac (pg@top): Drop extraneous closing parenthesis from + numeric expression. Change operator from '>' to '>='; a page + length right at the boundary causes a spurious extra page break + when a paragraphing macro is used to initialize the document. + Condense diagnostic emission using the @error macro instead of + duplicating it. Change indentation to fit the style of the rest + of the file (use hard tabs). If aborting, truncate the page + length to the current vertical position so that we don't + uselessly output further vertical space. + +2022-02-01 G. Branden Robinson + + [ms]: Add test for insufficient page length error. + + * tmac/tests/s_rejects-too-short-page-lengths.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-02-01 G. Branden Robinson + + [me]: Vertically space delayed text like other annotations. + + * tmac/e.tmac ((d): Set vertical spacing using percentage in + `$V` register. + ()d): Restore vertical spacing using percentage in `$v` + register. + + Fixes . + +2022-01-31 G. Branden Robinson + + [build]: Expand '@PAGE@' when generating man pages. + + * Makefile.am (.man): Substitute the './configure'd paper format + for @PAGE@. + * src/roff/groff/groff.1.man: Use it. + +2022-01-31 G. Branden Robinson + + [man]: Trivially refactor an-ext.tmac. + + * tmac/an-ext.tmac (EX, EE): Do a better job of keeping the + name space promise made in comments at the top of the file. + Rename `sP` register to `mP`. Problem introduced by me in + commit 69895ec20, 15 January 2020. Also rename `la` and `ra` + strings to `mL` and `mR`, respectively. These (undocumented) + string names date back to commit 259929625, 15 January 2007. + + * tmac/groff_man.7.man.in (Files) : Document the + aforementioned promise. + +2022-01-31 G. Branden Robinson + + [man]: Refactor PDF bookmark support. + + * tmac/an.tmac (an*bookmark): New internal macro calls + `pdfbookmark` (only if the output device is 'pdf'). + (initialization): Migrate macro appendments to appropriate + definitions. Two cases... + (SH, SS): ...were straightforward. + (initialization): Another (for the man page title) was poorly + placed when appended to the `TH` macro, skipping over the page + header. Move it instead... + (PT): ...here. But to keep this bookmark from being generated + on every page of a document, we need a new variable + `an*was-TH-bookmark-emitted` which is tested here and assigned + once one bookmark corresponding to a `TH` call has been written. + (TH): Initialize `an*was-TH-bookmark-emitted` to zero. + (SS): Write the bookmark _before_ the subsection heading text. + (initialization): Drop short-lived `BM` register. It seems + harmless to unconditionally include bookmarks in PDF output. A + PDF tool can strip them out if they're not desired, and viewers + seem capable of minimizing or reducing the navigation pane (if + they even offer one in the first place). + + * tmac/an.tmac (initialization): Rename new `BN` register to + `BD`... + * tmac/groff_man.7.man.in (Options) : ...and document it. + Also document `PT`'s new bookmarking responsibility. + + Fixes and + . + +2022-01-31 G. Branden Robinson + + [grohtml,groff,nroff,troff]: Tweak usage message. + + * src/devices/grohtml/post-html.cpp (usage): + * src/roff/groff/groff.cpp (synopsis): + * src/roff/nroff/nroff.sh: + * src/roff/troff/input.cpp (usage): Partly revert commit + 06ae7b0b8, 16 January. Move an ellipsis back inside a bracketed + operand (that is, an optional one). On reflection, I think this + notation makes it clearer that the command can be meaningfully + run without operands. + +2022-01-31 G. Branden Robinson + + * tmac/papersize.tmac: Slightly refactor. Use new `stringdown` + request instead of a combination of `tr`, `di`, `asciify`, and + `chop`. + +2022-01-27 G. Branden Robinson + + [man]: Slightly refactor. + + * tmac/an.tmac (an-prepare-page-title): Rename to... + (an*prepare-page-title): ...this. Also simplify numeric + expression. Add comment regarding necessity of correct + environment. + + (an-header): Update call site of `an*prepare-page-title`. + + (TH): Move planting of `an-header` trap from out of the midst of + footer trap management. Add comments. + + (an-header): Move `pl` and `sp` requests from here... + (PT): ...to here. While it's conceptually nice to have these + macros consist solely of `tl` requests, it doesn't yield enough + power to those who want to redefine them. Add comment. + + (an-footer, BT): ...simile. + +2022-01-27 Dave Kemper + + [man pages]: Add more references to pic(1)'s .PF. + + * contrib/chem/chem.1.man: + * contrib/pic2graph/pic2graph.1.man: + * src/utils/grog/grog.1.man: Do it. + + Fixes . + +2022-01-27 G. Branden Robinson + + Implement PDF bookmark support for man pages. Limitation: A + {sub}section can only be bookmarked if it is specified in the + arguments to the `SH` or `SS` requests, not on the next line in + an input trap. Thanks to Deri James for providing the + fundamentals (blame me for any weird bits). + + * tmac/an.tmac (an-prepare-page-title): Define a new string, + `an*page-ref-string`, which is the man page's own reference + {such as "groff(1)"} without any abbreviation, ellipsis, or font + selection or italic correction escape sequences. + (SS): Define a new string, `an*subsection-heading`, storing the + macro arguments (if any). These could contain font selection + escape sequences, for instance, a fact that becomes important + later. + (initialization): + - Recognize `BM` register to enable PDF bookmarks (only on the + 'pdf' output device); defaults on. Recognize `BN` register to + set a base level/depth for the bookmarks; this is to ease + embedding of man pages in other PDF documents that already use + bookmarks. The default is 0. The registers are not yet + documented. + - If the output device is 'pdf' and bookmarks are enabled, set + `PDFOUTLINE.FOLDLEVEL` and `PDFHREF.VIEW.LEADING` registers + {recognized by 'pdf.tmac'}. Append to `TH`, `SH`, `SS` to get + the `an*page-ref-string`, `an-section-heading`, and + `an*subsection-heading` bookmarks in the document at the + applicable levels. + + * tmac/mdoc/doc-common: Add straw-man implementation--it doesn't + support the `BM` and `BN` configuration parameters yet. (This + is enough to get bookmarks for the groff_mdoc(7) page to + correctly appear in the new 'groff-man-pages.pdf' document.) + (Dt, Sh, Ss): If the output device is 'pdf', place bookmarks in + the document at levels 1, 2, and 3. + + Fixes . + +2022-01-26 Deri James + + [gropdf]: Allow multiline text in .pdfinfo + + * src/devices/gropdf/gropdf.pl: Use either '\\\\\\\\n' or + '\[u000a]' as line separators in the string. + +2022-01-25 G. Branden Robinson + + * tmac/trans.tmac: Further follow up commit c64fd60dff. If the + `andoc` wrapper is being used, perform man(7) localization (not + just when `an` is loaded). + +2022-01-25 G. Branden Robinson + + [man pages]: Fix options used to generate compilations. + + * doc/doc.am (doc/groff-man-pages.pdf): Drop `-rU0` option (it's + unnecessary since we don't yet have PDF hyperlink support in + this document). Add `-rC1` option to enable continuous page + numbering. + (doc/groff-man-pages.utf8.txt): Drop `-rC1 -rU1`. Continuous + page numbering is superfluous since page numbers are not shown + in continuous rendering mode. Stop turning on OSC 8 defaults; + we don't know if the document will be viewed with a supporting + pager+terminal combination, and further we don't yet have a + mechanism for making `MR` man page cross references internal to + the document when they indicate groff man pages. + +2022-01-24 G. Branden Robinson + + [man pages]: Ship compilations in UTF-8 text and PDF. + + Localization support and the resolution of Savannah #61266 have + made it practical to batch-render all of groff's man pages as a + single giant document. Provide PDF and UTF-8 text (with ECMA-48 + escape sequences, but not the italic attribute or OSC 8 + sequences). + + Reasons for this addition include: {1} it is now possible, + whereas I don't believe it was in any previous groff release; + {2} many people still don't realize how much more pleasant + reading typeset man pages can be (while a subjective assessment, + I'm not alone[1]); {3} providing these forms permits full-text + searching of groff's entire man page corpus via the PDF viewer + or a pager like "less -R", the latter without sacrificing the + style variations of the text that aid the reader to comprehend + the material; {4} sentimentally, it honors the 50th anniversary + of the first Unix manual (dated 3 November 1971) + . + + * doc/doc.am (PROCESSEDDOCFILES): Add + 'doc/groff-man-pages.{pdf,utf8.txt}'. + (GROFF_MAN_PAGES{1,2,3}): Add new macro storing names of all man + pages generated in the build tree. Motivate the reason for 3 + variables in a comment (it's due to groff locale switching). + (GROFF_MAN_PAGES_ALL): Add convenience macro for use in + dependency lists required by... + ('doc/groff-man-pages.{pdf,utf8.txt}'): ...these targets. + Generate pages with the lint dial turned all the way up. + + Fixes . + + [1] "The manual was intended to be typeset; some detail is + sacrificed on terminals." (man(1), _Unix Time-Sharing System + Programmer's Manual_, Eighth Edition, Volume 1, February 1985) + +2022-01-24 G. Branden Robinson + + [man]: Commit c64fd60dff was not quite cooked. The localized + strings (in English) for the manual section titles need to be + set at every document load (i.e., when `TH` is called), but only + if the groff locale is "english". When switching locales, these + strings were getting "stuck" in their non-English translations + even when returning to an English page. + + * tmac/an.tmac (an*localize): New macro initializes strings. + (TH): Call `an*localize` if the locale is "english". + (initialization): Drop initialization of section title strings. + + Continues fixing . + +2022-01-24 Deri James + + [gropdf]: Fix Savannah #61908 + + * src/devices/gropdf/gropdf.pl: Adjust text position when + given landscape media (i.e -P-l). + + Fixes . + + Thanks to KUBO Koichi for finding the problem and supplying a + patch. + +2022-01-24 Deri James + + * src/devices/gropdf/gropdf.pl: A fix to importing pdf + versions > 1.4. + +2022-01-23 G. Branden Robinson + + [grotty]: Skip part of test if locale doesn't support UTF-8. + + * src/devices/grotty/tests/basic_latin_glyphs_map_correctly.sh: + Skip test of 'utf8' output device if locale lacks UTF-8 support. + But if the 'ascii' or 'latin1' test cases have already failed, + report that instead. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2022-01-23 Bjarni Ingi Gislason + + [man pages]: Fix typos. + + Fixes . + +2022-01-22 G. Branden Robinson + + [tmac]: Fix style nits in test. + + * tmac/tests/pdfpic_does-not-choke-on-bad-pdfinfo-output.sh: + - Emit complaints about test environment to standard error. + - Replace lingering literal file name with variable expansion. + - Skip test if gs(1) fails, instead of reporting failure. + - Begin continued lines with operators, for visibility. + +2022-01-22 G. Branden Robinson + + [grohtml]: Fix misspelled member variable. + + * src/devices/grohtml/post-html.cpp (class html_printer): + Rename `supress_sub_sup` to `suppress_sub_sup`. + +2022-01-21 G. Branden Robinson + + [pdfpic]: Fix Savannah #58206. + + * tmac/pdfpic.tmac (PDFPIC): Scrub null bytes out of pdfinfo(1) + output. Thanks to an anonymous contributor for the patch (the + commentary about it is mine, if someone wants an argument). + + Fixes . + +2022-01-21 G. Branden Robinson + + [pdfpic]: Regression-test Savannah #58206. + + * tmac/tests/pdfpic_does-not-choke-on-bad-pdfinfo-output.sh: Do + it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-01-21 G. Branden Robinson + + [pdfpic]: Refactor. + + Now that the package does not abort upon the first whiff of any + trouble, avoid littering groff's name spaces. Take this + opportunity to rename registers and strings to have obvious + meaning to even the casual reader. + + * tmac/pdfpic.tmac: Do it. + (pdfpic@cleanup): New macro removes temporary strings and + registers. + (PDFPIC): Call the cleanup macro upon entry; this way, if we + errored out from a previous call, we avoid confusion. (We don't + clean up upon an error return because the leftover objects might + be useful for troubleshooting.) Rename registers and strings, + to get them under name space discipline and also to better + suggest their purpose. + - convert-pdf -> pdfpic*do-conversion + - pdf-offset-mode -> pdfpic*offset-mode + - pspic-args -> pdfpic*pspic-args + - pdf-offset -> pdfpic*indentation + - is-pdf -> pdfpic*file-extension + - img-file -> pdfpic*file-name + - pdf-wid -> pdfpic*width + - pdf-ht -> pdfpic*height + - pdf-deswid -> pdfpic*desired-width + - pdf-desht -> pdfpic*desired-height + Call cleanup macro before returning upon successful operation. + +2022-01-21 G. Branden Robinson + + [pdfpic]: Improve robustness. + + * tmac/pdfpic.tmac (@abort): Rename to `pdfpic@error`. This is + an auxiliary package, and something else could very well step on + the former name (or worse, we break it if we're loaded later). + (pdfpic@error): Stop aborting; simply report an error. It's up + to the user how serious `PDFPIC` macro problems are. As noted + in a comment, the user can easily `am pdfpic@error` to tack an + `ab` request onto the end of its definition. Always report + input file name and line number. Replace "[PDFPIC]" prefix with + the name of the macro file complaining, to make it easier for + groff non-experts to find. + (PDFPIC): Return upon errors. Recast diagnostic messages. Stop + implying that we perform any sort of probing test of file type + {there's no telling what pdfinfo(1) will say}. Apply new + 'stringdown' request so that we accept '.pdf' file name + extension in any lettercase. Test file argument for existence + before proceeding (acknowledge TOCTTOU exposure). Skip file if + pipeline returned a non-zero exit status or the registers into + which we extract the height and width are undefined (indicating + failure of a temporary file to be created or read). Reject + files with non-positive image width or height reported by + pdfinfo. Validate `width` and `height` arguments, if given, + rejecting non-positive values. + + Fixes . + +2022-01-21 G. Branden Robinson + + [mdoc]: Make `Pa` macro interpolate basic Latin tilde on all + output devices. + + * tmac/doc.tmac (Pa): Do it. + +2022-01-21 G. Branden Robinson + + [tbl]: Fix incorrect line numbers in diagnostics. Line numbers + for multiple format-time diagnostics emitted by tbl(1)-generated + groff input were off by +5 lines. + + * src/preproc/tbl/table.cpp: Fix it. + (NOP_NAME): Add new preprocessor symbol to construct name of + "nop" macro to be used as end macro for `ig` requests inside + macro definitions. + (table::init_output, table::compute_expand_list, + table::compute_separation_factor): + - Move `entry_list->set_location()` calls to more auspicious + locations. + - Replace "around line X" language in diagnostic messages with a + more idiomatic, and less embarrassing, simple report of an + integer. + (table::init_output): + - Add `entry_list->set_location()` call right before emitting + diagnostic about a table row not fitting on a page. + - Turn off eqn(1) delimiters when emitting diagnostic about a + boxed table not fitting on a page (necessitating `.TS H` + support), using new NOP_NAME-based end macro to achieve this + inside a macro definition. + (table::compute_expand_list): Suppress issue of too-wide table + diagnostic when the `EXPAND` table flag is set (corresponding to + the `expand` region option), because other code already emits + diagnostics in this case. + + Fixes . Problem appears + to date back to commit 3bc4a53a45, 2013-01-07. + +2022-01-21 G. Branden Robinson + + [tbl]: Add unit test for format-time diagnostics. + + Ensure that the various format-time diagnostics that a + tbl-preprocessed document can generate (1) occur when they are + supposed to and (2) are appropriately suppressed by the + "nowarn" and/or "nokeep" region options. One of them is an + error and cannot be suppressed by the former, but _can_ be by + "nokeep", which is arguably a bug (Savannah #61878). + + * src/preproc/tbl/tests/format-time-diagnostics-work.sh: Do it. + * src/preproc/tbl/tbl.am (tbl_TEST): Run test. + +2022-01-21 G. Branden Robinson + + [tbl]: Trivially refactor. + + * src/preproc/tbl/table.cpp (table::compute_expand_width): + Declare and initialize variables closer to use. Also, the width + computed is compared to the line length and indentation, so use + these well-established *roff terms in the diagnostic message. + +2022-01-20 G. Branden Robinson + + [tbl]: Fix Savannah #61854. + + * src/preproc/tbl/table.cpp (compute_expand_width): To properly + warn if a table is too wide to fit between the indentation and + the right margin, we need to compute its column widths including + those eligible for expansion via the 'x' column modifier; we + cannot use the same expression that we do to determine the + amount of space we have to distribute among the expanded + columns. Iterate through columns again (the function was + already doing so twice), once to potentially produce the + warning, and then as before to distribute any available width. + In other words, warnings were only being emitted for too-wide + tables where one or more columns used the 'x' modifier. + + Fixes . + +2022-01-19 G. Branden Robinson + + [ms]: Don't add leaders that don't lead anywhere. + + * tmac/s.tmac (toc*end-entry): If no page number string + `toc*num` is defined, don't interpolate its emptiness prefixed + with a leader (and tab). This makes "no" as the first argument + to `XS` and `XA` work as documented, suppressing not only the + page number but the leader after the entry. + + Fixes . + +2022-01-19 G. Branden Robinson + + [ms]: Add regression test for Savannah #61853. + + * tmac/tests/s_XA-literal-no-argument-suppresses-leader.sh: Do + it. + * tmac/tmac.am (tmac_TESTS): Run it. + +2022-01-19 G. Branden Robinson + + [me]: Fix bad unit test. + + * tmac/tests/e_chapter-titles-work.sh: Fix missing shell test at + end of script, which caused it to exit successfully regardless + of any test failures. Irritating. This is among the fruits of + the "never, ever use 'set -e'" tree. (This religion has a thick + bible: .) Fortunately, + all the tests pass legitimately. + +2022-01-16 G. Branden Robinson + + [font]: For 'ascii' and 'latin1' devices, consistently define + glyphs for ordinary characters before their special character + aliases. This parallels existing usage for the 'cp1047' device, + and, I think, makes the file contents slightly more accessible. + + * font/devascii/R.proto: + * font/devlatin1/R.proto: Do it. + +2022-01-16 G. Branden Robinson + + [grohtml]: Update diagnostic messages. + + * src/devices/grohtml/post-html.cpp (assert_state::add) + (assert_state::compare, replace_negate_str) + (assert_state::check_value_error, make_val): Make format of + internal assertion system messages shorter and more mutually + parallel. + (html_printer::set_char, html_printer::set_numbered_char) + (html_printer::set_char_and_width): Parallelize diagnostic + messages with libdriver; see yesterday's commit. + (main): Put information in argument to `assert()`; see commit + 11b43053, 24 November. + +2022-01-16 G. Branden Robinson + + [nroff]: Emit usage message on usage errors. + + * src/roff/nroff/nroff.sh: Store the usage message in a shell + variable instead of a here document, and sling it to the + standard output or standard error streams, as appropriate. + +2022-01-16 G. Branden Robinson + + [grohtml,groff,nroff,troff]: Tweak usage message. + + * src/devices/grohtml/post-html.cpp (usage): + * src/roff/groff/groff.cpp (synopsis): + * src/roff/nroff/nroff.sh: + * src/roff/troff/input.cpp (usage): Stop putting an ellipsis + inside a bracket expression (for file arguments); that suggests + misleading complexity. + + * src/devices/grohtml/post-html.cpp (usage): Also don't set + metasyntactic variable names in screaming capitals when they are + separated from option letters by space and thus can't be + confused with them. + +2022-01-15 G. Branden Robinson + + [libdriver]: Update diagnostic messages. + + * src/libs/libdriver/printer.cpp (printer::find_font): Describe + the problem encountered instead of saying lamely "sorry, I can't + continue". + (printer::set_char_and_width, printer::set_numbered_char): + Characterize input as "invalid", not "bad"; see commit bb7512b5, + 17 September. When referring to font mounting position, say so. + (printer::set_char_and_width): Describe required input character + as "ordinary", not "ascii". Apart from the incorrect casing, + doing so better aligns with our terminology in groff_char(7), + groff_out(5), our Texinfo manual, and other diagnostic messages; + moreover, the use of "ascii" is potentially confusing to those + whose environments use another encoding, like UTF-8 or IBM code + page 1047. + + Fixes . + +2022-01-15 G. Branden Robinson + + [grotty]: Check basic Latin ("ASCII") glyph mappings. + + * src/devices/grotty/tests/basic_latin_glyphs_map_correctly.sh: + Do it. + * src/devices/grotty/grotty.am (grotty_TESTS): Run test. + +2022-01-15 G. Branden Robinson + + [font,tmac]: Simplify Unicode character mapping process. + + * tmac/unicode.tmac: Drop. It was originally added in 2005 to + suppress horizontal spacing of glyphs in the range U+0483..9. + Its purpose has wandered over the years; most recently to map + the Basic Latin ("ASCII") hyphen-minus, apostrophe, and grave + accent to special characters (and thus ultimately to the General + Punctuation block). But this is unnecessary since the font + descriptions for devices with the `unicode` property can provide + this information, and anyone who wants to alter the mappings can + change either font description files, output device macro files, + or troffrc; or add `char` requests to their macro packages or + documents (in decreasing magnitude of ambition). + + * tmac/html.tmac: + * tmac/tty.tmac: Stop sourcing unicode.tmac. + + * tmac/tmac.am (TMACNORMALFILES): Stop shipping it. + + * font/devutf8/NOTES: Drop remarks about mapping of \[a~], + \[a^], and Basic Latin circumflex accent and tilde. Not only do + I disagree with the reasoning (whether these glyphs are "too + small" depends on the font used by the terminal emulator, over + which we have no control), but this mapping happens in a + completely different part of the source tree, + src/libs/libgroff/glyphuni.cpp. + + * font/devhtml/R.proto: + * font/devutf8/R.proto: Add mappings for the five Basic Latin + characters that map surprisingly (see groff_char(7)) and are not + syntactically significant to troff. Three of these are ported + from unicode.tmac. + (html): Don't migrate the hyphen-minus--yet. + +2022-01-15 G. Branden Robinson + + * tmac/tty-char.tmac: Drop redundant logic. We don't need to + source the `cp1047` or `latin1` files here; `troffrc` will + already have loaded `tty` for us, which loads whichever applies. + +2022-01-14 G. Branden Robinson + + * doc/doc.am: Separate concerns better; stop re-generating plain + text and HTML documents when the 'doc' target is updated; these + are already handled by the 'build_infodoc' target. + (build_infodoc): Use existing phony targets for plain text and + HTML output files instead of repeating filename literals. + (doc_all): Remove those same two phony targets from this one's + dependencies. + +2022-01-14 G. Branden Robinson + + * src/roff/troff/input.cpp: Rename `eoi_macro_name` to + `end_of_input_macro_name`. It's long, yes, but better parallels + `blank_line_macro_name` and `leading_spaces_macro_name`. It is + not used in lengthy expressions and furthermore clarifies the + meaning of the nearby function name `eoi_macro` in one use. + +2022-01-11 G. Branden Robinson + + * src/preproc/preconv/preconv.1.man (Limitations): Add + subsection. + + Fixes . + +2022-01-11 G. Branden Robinson + + [docs]: Be more careful with control characters when they are + word-initial in filled text lines. The idea is to prevent + baffling surprises if a sentence is recast in a text editor, and + a word beginning with a dot or neutral apostrophe is reflowed + onto the beginning of the next input line--suddenly it is parsed + as a control character. Based on a patch by Bjarni Ingi + Gislason. + + * contrib/hdtbl/groff_hdtbl.7.man: + * doc/automake.mom: + * doc/meintro.me.in: + * doc/meintro_fr.me.in: + * doc/pic.ms: + * doc/webpage.ms: + * src/devices/gropdf/gropdf.1.man: Do it. + + Fixes . + +2022-01-11 G. Branden Robinson + + * doc/groff.texi (Font Description File Format): + * man/groff_font.5.man (Font description file format): Document + restriction of kerning adjustment to glyph pairs from within a + single font (since that is the scope of the font description). + + Fixes . + +2022-01-11 G. Branden Robinson + + * contrib/groff_filenames/groff_filenames.5.man: Remove + superfluous paragraphing macro. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report and a suggested patch. + +2022-01-10 G. Branden Robinson + + * doc/groff.texi (Operators in Conditionals): Update explanation + of output-comparison conditional operator. + + Fixes . + +2022-01-08 G. Branden Robinson + + [build]: Use pnmtops(1)'s -quiet option if possible, to quieten + build. + + * m4/groff.m4 (GROFF_PNMTOOLS_CAN_BE_QUIET): Add new macro to + test pnmtops for support for (undocumented) '-quiet' option. + + * configure.ac: Perform the check. + + * doc/doc.am: Alter check of shell variable `pnmtops_nosetpage` + {processed by AC_SUBST} to correctly match even if pnmtops + accepts the '-quiet' option. + +2022-01-06 G. Branden Robinson + + [tmac]: Manage hyphenation mode more carefully in localization + packages. + + * tmac/{cs,de,it,sv}.tmac: Localize the man(7) package's HY + register. + + * tmac/{cs,de,fr,it,sv}.tmac: When localizing the ms(7) package, + use mode "2" instead of "3": the 'hy' request complains of + contradictory hyphenation modes if "3" is used (the semantics of + the hyphenation mode are complex and non-orthogonal; see + groff(7) or our Texinfo manual). + + * tmac/{cs,de,en,fr,it,sv}.tmac: If the one language-independent + hyphenation bit (don't hyphenate just prior to a page location + trap) is set, preserve it; this way a system's troffrc or a + macro package can set it and it will not get turned off by the + localization package, which for best results should be loaded + after any full-service package (and any auxiliary package + requiring localized strings, though none are yet distributed + with groff). + +2022-01-06 G. Branden Robinson + + [tmac]: Add unit test for localization macro files. Right now + this just covers the hyphenation mode. + + * tmac/tests/localization-works.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2022-01-05 G. Branden Robinson + + [indxbib]: Document --version in usage message. + + * src/utils/indxbib/indxbib.cpp (usage): Document --version + option. Use more informative metasyntactic variable names. + Organize usage message consistently with our others, and stop + wrapping the output lines: we know neither the width of the + terminal nor the length of the `program_name` string we're + interpolating. See commit b4de44f0, 19 July 2021. + +2022-01-05 G. Branden Robinson + + [libbib]: Refactor index header checking. + + * src/libs/libbib/index.cpp: Move more header validity checks... + (index_search_item::load): ...from here... + + (index_search_item::check_header): ...to here. Test all size + values in header for negative values (never valid) before + proceeding. (These data could be changed to unsigned integer + types in the file format, but that would require bumping the + file version. That in turn would make indexes generated with + groff 1.23 unusable on systems running older groffs and, perhaps + worse, would make groff 1.23 reject index files produced by + older groffs. On the other hand, the regeneration of index + files should be, for those who use them, a common activity, and + as long as the original database files are kept intact, it seems + likely that most people, given modern machines, won't even + notice a slowdown in document generation when refer(1) and + friends fail to open the indices and fall back to full-text + searches of the originals. So we could still consider revising + the file format before the groff 1.23 release.) + + * src/libs/libbib/index.cpp (index_search_item::load): + Explicitly perform widening conversion from signed `off_t` value + {from a stat(2) buffer} to an unsigned integer; quietens + compiler warning about comparison between integers differing in + signedness. + +2022-01-05 G. Branden Robinson + + * configure.ac (AC_CHECK_HEADERS): Expect stdbool.h, since we + now use it in src/include/lib.h. + +2022-01-05 G. Branden Robinson + + [libbib, libgroff, indxbib]: Slightly refactor. + + Also, it's silly to test even numbers > 2 for primality. Stop. + + * src/include/lib.h: Include `stdbool.h` since this header file + is used for both C and C++ code. + + * src/include/lib.h (is_prime): + * src/libs/libgroff/prime.cpp (is_prime): Boolify. Return + Boolean instead of integer literals and demote return type to + `bool`. Include `assert.h` and add assertion to reject + mathematically offensive input. + + * src/libs/libbib/index.cpp + (index_search_item::read_common_words_file): Test only odd + numbers for primality. + * src/utils/indxbib/indxbib.cpp (main): Same. Since the number + comes from user input, make it (a potential hash table size) odd + first. + +2022-01-04 G. Branden Robinson + + [man]: Internationalize and localize. + + * tmac/an.tmac (TH): Indirect predefined manual section titles + through new strings `an*section[1-9]` so that they can be + localized. + (initialization): Give these strings English defaults. + (TH): Move `ss` request from here... + + * tmac/en.tmac: ...to here. It's not the man(7) package's + business what the inter-word and inter-sentence spacing values + are. Also, having the correct[disputed] inter-sentence spacing + value for English in its localization file restores it for the + benefit of multi-lingual documents (mainly roff applications + other than man(7)). + + * tmac/{cs,de,fr,it,sv}.tmac: Supply translations for the manual + section titles; these were done by a monoglot American employing + Google Translate, so those scandalized or running into howlingly + wrong locutions are warmly invited to submit corrections. + + * tmac/trans.tmac: Load localized strings. + + Fixes . + +2022-01-04 G. Branden Robinson + + * src/utils/grog/grog.pl: Handle auxiliary macro package + arguments correctly. + (process_arguments): Don't append the argument to the '-m' + option to the command line; requested macro packages have + dedicated logic. + (construct_command): When iterating through requested package + list, assume each element is an auxiliary package unless it + matches an element in the list of main packages. If the + assumption holds, append the package name to a new list, + `auxiliary_package_argument` (prefixed with '-m'). Push this + list onto the command line after any main package. + + Also rename `$selected_main_package` to `$main_package` for + brevity, and drop unused global lists `m` and + `supplemental_package`. + + Fixes . + +2022-01-04 G. Branden Robinson + + * src/utils/grog/tests/smoke-test.sh: Add test cases for user + specification of auxiliary macro packages. + +2022-01-03 G. Branden Robinson + + [me]: Drop unnecessary code. Apart from being superfluous, it + prevented a user-defined value of the `sx` register from being + applied to the first footnote marker interpolated, a subtlety + that escaped my notice because the first footnotes in our + "meref" and "meintro" documents are not numeric, but symbolic, + and their markers occurred on lines with vertical space above + and below. (The bug was further masked by an otherwise + redundant redefinition of the `*` string inside the `)f` macro.) + + * tmac/e.tmac ()f, +c): Stop redefining footnote marker string + `*` after updating the automatic footnote number; its + interpolation is already backslash-protected. + ()d, pd): Stop redefining delayed text marker string `#` for an + analogous reason. + (initialization): Drop unneeded `_*` and `_#` strings. + + Thanks to Robert Goulding for his feedback and patience. See + . + +2022-01-03 G. Branden Robinson + + * tmac/tests/e_footnote-marks-work.sh: Enhance test. Confirm + that the automatic footnote number is reset to 1 by starting a + new chapter with the `+c` macro. + +2022-01-02 G. Branden Robinson + + [me]: Revise `n1` and `n2` interface and behavior. + + There were several bugs in the previous implementation. + + * tmac/e.tmac (po): Issue diagnostic if an attempt is made to + set the page offset to a negative value. + + (n1): Accept new optional "C" argument to behave more (but not + exactly) like roff(1), as the formerly-recognized "c" argument + to `n2` did. If present, the line length is reduced by the same + amount (in new interface register `no`) as the line number field + to preserve the overall line length. Save the previous line + length in internal register `_l` and set a flag, stored in `?N`, + indicating this reduction. Otherwise, the macro expects to be + able to reduce the page offset to accommodate the line number. + If it cannot (for example, with the zero page offset default + used by nroff output devices), see above re: the `po` macro. + + (n2): Cache the last line number that may have been output, + instead of the current one, so that we can operate on it + consistently with user expectations. Do this earlier, and + rename this macro-local variable from `_ln` to `_n` so that we + don't need groff's `do` request to operate on it. Drop + recognition of "c" as an optional second argument. If turning + off line numbering: if the line length was shortened (`?N`) + restore the saved value and delete `_l` register; otherwise, + reverse the change to the page offset. Delete `_n` register. + + (initialization): Assign `\w'0000'u` to `no` register; this was + previously hard-coded in `n1` and `n2`. Initialize `?N` with 0. + + * doc/meref.me.in (roff Support): Update to reflect interface + changes and describe behavior more accurately. + + * doc/meref.me.in (Summary): + * tmac/groff_me.7.in (Registers): Document new `no` register and + mark it as a groff extension. + + * NEWS: Add item documenting interface changes. + + Fixes . See the comments + in the report for a lengthy enumeration of rendering problems + exhibited by the previous implementation. + +2022-01-02 G. Branden Robinson + + [me]: Add unit test for line numbering feature. + + * tmac/tests/e_line-numbering-works.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2021-12-31 G. Branden Robinson + + * src/devices/grohtml/post-html.cpp (style::style): Add + initializer to argumentless constructor to avoid later read from + uninitialized memory in `html_printer::do_font`. + + Fixes . + +2021-12-31 G. Branden Robinson + + [groff]: Add regression test for Savannah #61748. + + * src/roff/groff/tests/html_works_with_grn_and_eqn.sh: Do it. + * src/roff/groff/groff.am (groff_TESTS): Run it. + +2021-12-31 G. Branden Robinson + + * src/devices/grohtml/post-html.cpp + (html_printer::do_file_components): Emit fatal diagnostic if + we're unable to `freopen()` standard output. Quietens + `-Wunused-result` warning from GCC 8.3. + +2021-12-31 G. Branden Robinson + + * src/devices/grohtml/html.h (INT_HEXDIGITS): Add new constant + to store the maximum possible quantity of digits in the + hexadecimal representation of an `int`. + + * src/devices/grohtml/html-text.cpp (html_text::issue_tag): + * src/devices/grohtml/post-html.cpp (html_printer::do_body): + Guard against format string overflow by large integers in RGB + color channel specifications; in a *printf format string, the + precision (like the field width) is a _minimum_. Quietens + `-Wformat-overflow` warnings from GCC 8.3. + +2021-12-30 G. Branden Robinson + + * src/preproc/html/pre-html.cpp (get_image_generator): Clarify + complex conditional expression. Quietens `-Wparentheses` + warning from GCC 8.3. + +2021-12-28 G. Branden Robinson + + [me]: Rename new `$x` register to `sx`. Since we expect the + user to set this register directly, it should not be named with + a leading '$' per the "me Reference Manual". + + * tmac/e.tmac (initialization, {, }): Do it. + + * tmac/groff_me.7.man: + * doc/meref.me.in: + * NEWS: Update documentation. + + * doc/meintro.me.in: + * doc/meintro_fr.me.in: + * doc/meref.me.in: Sync with new register name. + + See . Thanks to Dave + Kemper for the discussion in + . + +2021-12-28 G. Branden Robinson + + [troff]: Slightly refactor. + + * src/roff/troff/div.cpp: + * src/roff/troff/div.h: + * src/roff/troff/input.cpp: Rename variables to reduce confusion + between "end macros" and "end-of-input macros". Call the latter + "eoi" macros for brevity. + +2021-12-28 G. Branden Robinson + + * tmac/e.tmac: Fix code style nits. + - Use new terminology in diagnostic. See commit 66ac1a8db9, + 11 December. + - Drop unused '&&&' annotation for macro definitions. This + was a BSD me(7) implementation detail wherein parts of the + package were broken out into module files, loaded if/when + their macros were called. groff me(7) is monolithic, except + for devtag and refer(1) support. + - Remove '&&' end macro when we're done using it. + +2021-12-27 G. Branden Robinson + + [me]: (Re-)localize strings. + + * tmac/{cs,de,fr,it,sv}.tmac: Update package localizations to + use new resources. As a happy side effect (and with the new + appendix string), the `+c` macro is now localized for Czech, + German, and Swedish. + + * doc/meintro_fr.me.in (Les Parties du Document): Update example + to reflect mixed-case default string used in chapter headings. + + * tmac/tests/e_ld-works.sh: Add tests for localization. + +2021-12-27 G. Branden Robinson + + [me]: Internationalize strings. + + * tmac/e.tmac (initialization): Introduce internal + `_mo1`..`_mo12`, `_dw1`..`_dw7`, and `_td_format` strings (with + English defaults). Define them outside of the new `ld` macro so + that they can be overridden by localization packages. + (ld) : Populate via the above new strings. + * tmac/trans.tmac: Stop defining `mo` and `dw`. Instead, make + them aliases of the new strings above. Handle `wa` and `wc` + similarly. + +2021-12-26 G. Branden Robinson + + [me]: Add `ld` macro to re-init date/l10n stuff. + + * tmac/e.tmac (ld): New macro updates `y2` and `y4` registers + and `wa`, `wc`, `mo`, `dw`, and `td` strings. + + * doc/meref.me.in (Miscellaneous, Predefined Strings): + * tmac/groff_me.7.man (Macros): Document it. + + * tmac/tests/e_ld-works.sh: Add unit test. + * tmac/tmac.am (tmac_TESTS): Run test. + + Fixes . + +2021-12-26 G. Branden Robinson + + * tmac/tests/e_chapter-titles-work.sh: Add unit test for chapter + heading feature. + * tmac/tmac.am (tmac_TESTS): Run test. + +2021-12-26 G. Branden Robinson + + * tmac/e.tmac: Ease localization and customization by exposing + strings for "Chapter" and "Appendix" instead of hard-coding + these words into the `$c` macro. + (initialization): Define new `wa` and `wc` strings. Separate + these and existing localization strings from `y2` and `y4` + initialization since the latter don't involve natural languages. + ($c): Interpolate these strings in chapter and appendix headings + and in calls to `$C` hook macro. Set "Chapter" and "Appendix" + in mixed case instead of full capitals, and set one + adjustable nonbreaking word space `\~` between them and the + chapter number instead of two unadjustable nonbreaking spaces. + {These changes do slightly alter the default output of the + package when the `+c` macro is used.} + + * doc/meref.me.in (Predefined Strings): + * tmac/groff_me.7.man (Strings): Document new strings. + + * doc/meintro.me.in (Parts of the Basic Paper): Update example + to reflect mixed-case default string. + + Fixes . + +2021-12-25 G. Branden Robinson + + * tmac/e.tmac (@p): Deactivate right alignment (the effect of + groff's `rj` request) when starting a new paragraph. + * doc/meref.me.in (Paragraphing) : Document this. + +2021-12-25 G. Branden Robinson + + * tmac/e.tmac ()c): Add bounds check to avoid attempting to set + a negative indentation, provoking a troff warning. Problem + exposed by formatting "meintro_fr.me" document with default + nroff mode line length. + +2021-12-24 G. Branden Robinson + + [troff]: Slightly refactor (boolify). + + * src/roff/troff/div.cpp: + * src/roff/troff/div.h: + * src/roff/troff/env.cpp: + * src/roff/troff/input.cpp: Rename variables and demote from + `int` to `bool`. Initialize and assign them using Boolean + literals. The new names try harder to express a logical + predicate, and start with verbs to resist interpretation as + noun phrases. + - exit_started -> is_exit_underway + - done_end_macro -> is_end_macro_finished + - seen_last_page_ejector (demoted but not renamed) + - began_page_in_end_macro (demoted but not renamed) + +2021-12-20 G. Branden Robinson + + * tmac/e.tmac: Explain presence of undocumented `$r` and `$R` + registers. + + Fixes . + +2021-12-20 G. Branden Robinson + + * tmac/e.tmac (bc): To get to the next column, space by the page + length `.p`, not by the distance to the next trap (or 24 inches, + as hard-coded in me(7) traditionally). It is up to any sprung + traps to issue further space requests or otherwise ensure a + transition to the next column. + + See for discussion. + +2021-12-17 G. Branden Robinson + + * tmac/e.tmac ({): Fix missing scaling unit in arithmetic + expression: broke footnotes in troff mode. Problem introduced + by me in commit 6eafd208, 16 December. Thanks to Robert + Goulding for the (informal) report. + +2021-12-17 G. Branden Robinson + + * doc/doc.am (doc/{pic,webpage}.html): Quieten build. Stop + passing `-p` (progress) option to postprocessor, which produces + TeX-like bracketed page numbers when images occur. + +2021-12-17 G. Branden Robinson + + * doc/doc.am (.ms.html): Drop unused suffix rule. + +2021-12-16 G. Branden Robinson + + * tmac/tmac.am (tmac_XFAIL_TESTS): Mark test + "e_footnotes-work-with-columns.sh" as expected to fail (as it + does now, consequent to a reverted commit). + +2021-12-16 Dave Kemper + + * man/groff_tmac.5.man: Fix minor errors. + + Fixes . + +2021-12-16 G. Branden Robinson + + Parameterize line height adjustment when super/subscripting. + + * tmac/e.tmac (initialization): Assign 0.2m to register `$x`.2m. + ({, <}: Apply adjustment, multiplied by -1 for superscripts. + + * doc/meref.me.in: + * tmac/groff_me.7.man: Document it. + + * NEWS: Add item. + + * doc/meintro.me.in: + * doc/meintro_fr.me.in: + * doc/meref.me.in: Forego extra line height for more attractive + typesetting. + + Fixes . Thanks to Robert + Goulding for the suggestion. + +2021-12-15 G. Branden Robinson + + * tmac/e.tmac ($c): Draw the footnote separator no wider than + the column width. + + Fixes . + +2021-12-15 G. Branden Robinson + + * tmac/e.tmac (2c): Accept an empty first argument, permitting + the number of columns to be specified but preserving the default + column separation. + + Fixes . + +2021-12-12 G. Branden Robinson + + * tmac/e.tmac (initialization): Initialize `$C` hook, preventing + `mac` warnings from troff(1) if chapter title feature is used. + +2021-12-10 G. Branden Robinson + + * tmac/e.tmac (i, bi): Add italic corrections. + +2021-12-09 G. Branden Robinson + + * tmac/e.tmac: Fix groff warnings and correctness issue. + (n2): Prefix `ie` request with `do` because it uses the groff + `\B` escape sequence. Use braces to group multiple requests + after an `el` request: `ie` and `el` count as two requests, not + one. Add comment regarding the unfortunate choice of brace + style given *roff's syntactical constraints. + (n2, (c): Conceal bare tab in request argument list (exposed by + no longer stripping the macro file). + +2021-12-08 G. Branden Robinson + + [me]: Revise diagnostic messages to follow GNU Coding Standards, + identifying what is emitting them. + + * tmac/e.tmac (_e): New string holds "e.tmac". + (@err): New macro constructs and issues diagnostics. Add file + name to messages when available. Suppress line number when + unavailable. + (check_page_length, @z, @h, n2, sk, @p, @(, @), (c, )c, EQ, (f, + ++, @U): Call `@err` instead of invoking `tm` request. Revise + wording of messages in an attempt at clarity. + + Continues the long process of fixing Savannah #52463. + +2021-12-08 G. Branden Robinson + + * tmac/e.tmac: Slightly refactor footnote numbering. + ()f): Tighten code style and end string definition with comment. + (+c, initialization): Drop unused auto-incrementation of + footnote number register `$f`. Add new string `_*` to use when + {re-}initializing `*` outside of a footnote diversion, and + interpolate the footnote number register instead of a literal. + +2021-12-08 G. Branden Robinson + + * tmac/tests/e_footnote-marks-work.sh: Add unit test. + * tmac/tmac.am (tmac_TESTS): Run test. + +2021-12-08 G. Branden Robinson + + * tmac/e.tmac: Fix automatic numbering of delayed text. + (initialization): Add `_#` string for use in multiple + assignments of `#` string. + (initialization, pd): Remove unused auto-incrementation from + `$d` delayed text number register. + ()d): Increment `$d` register unconditionally, no longer + conditionally on whether the delayed text marker string `#` has + been interpolated. + ()d, pd): Update `#` string using new `_#` string. Stop + initializing the string with `\k` mark-setting escape sequence. + + * doc/meref.me (Annotations) <)d>: Document now-unconditional + incrementation of `$d` register. + + Fixes . + +2021-12-07 G. Branden Robinson + + * tmac/tests/e_delayed-text-marks-work.sh: Add test. + * tmac/tmac.am (tmac_TESTS): Run test. + +2021-12-07 G. Branden Robinson + + * tmac/e.tmac: Rename internal register out of user name space. + (@f): Rename `VL` to `__`; remove it immediately after using it. + +2021-12-07 G. Branden Robinson + + * doc/meref.me: Fix documentation error; the `$s` macro draws a + horizontal line of 2 inches' length, not 1.5 inches. + + Fixes . Thanks to Dave + Kemper for the report. + +2021-12-06 G. Branden Robinson + + Generate me(7) manual sources as part of the build. We had been + shipping 'me' sources with the string '@VERSION@' in them and + only sed-replacing that to produce generated PostScript, but + this replacement was not occurring for users who processed the + documents themselves. + + * doc/meintro.me: + * doc/meintro_fr.me: + * doc/meref.me: Rename these to... + * doc/meintro.me.in: + * doc/meintro_fr.me.in: + * doc/meref.me.in: ...these. + + * doc/doc.am (DOCFILES): Add the new *.in files. Move the *.me + files from here... + (GENERATEDDOCFILES): ...to this new variable. + (dist_otherdoc_DATA, EXTRA_DIST): Add `$(GENERATEDDOCFILES)`. + (doc/me{intro{,_fr},ref}.me): Add new target rules. + + * src/utils/grog/tests/smoke-test.sh: Update test to look for + the above source tree documents under their new names. + +2021-12-06 G. Branden Robinson + + * doc/doc.am (.me.txt, .ms.txt): Drop unused suffix rules. + +2021-12-06 G. Branden Robinson + + * doc/doc.am (DOC_SED): Add substitution of command prefix + {"@g@"} so we can make accurate reference to groff commands with + Unix counterparts in our documentation. + +2021-12-05 G. Branden Robinson + + * tmac/e.tmac: Add nroff mode string definitions for 4.4BSD + compatibility. + - Define '{' and '}' (superscripting) strings as '[' and ']'. + - Define '<' and '>' (subscripting) strings as '\(la and + '\(ra' if available on the device, otherwise '<' and '>'. + + * tmac/tests/e_footnote-marks-work.sh: Update expected output. + + * doc/meref.me: Document it. + + Fixes . + +2021-12-05 G. Branden Robinson + + * doc/doc.am (doc/meintro_fr.ps): Add target rule (overriding + suffix rule) to generate this file using `-mfr` (load the French + localization macro file). + +2021-11-27 G. Branden Robinson + + [troff]: Drop redundant `do_divert()` declaration. + + * src/roff/troff/env.h: Do it. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2021-11-27 G. Branden Robinson + + [troff]: Remove `DEBUGGING` preprocessor cruft. + + * src/roff/troff/input.cpp: + * src/roff/troff/mtsm.cpp: Stop defining `DEBUGGING` + preprocessor macro (as empty). + + * src/roff/troff/input.cpp: Give `DEBUG_OPTION` an empty string + value if the former is undefined, so the `getopt_long()` call + will compile. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2021-11-26 G. Branden Robinson + + [tbl]: Slightly refactor table format column modifier `p` and + `v` validation. + + * src/preproc/tbl/main.cpp (process_format): Make code terser by + introducing references to `list->point_size` and + `list->vertical_spacing`. Doing this requires a new scope + {because a switch case isn't one} so add it, without updating + indentation for this commit. When complaining of out-of-range + type size or vertical spacing, report the limit. + +2021-11-25 G. Branden Robinson + + [tbl]: Improve diagnostic messages. + + Revise diagnostic messages generally to use terminology + consistent with the recent rewrite of tbl(1), identify a + contextual token when possible, and communicate more helpfully. + + * src/preproc/tbl/main.cpp (process_options): Tell the user + which region option is missing a closing parenthesis or cannot + accept an empty argument. Refer to region options as such, not + simply "options" (so they can't be confused with command-line + options). Say that input is "invalid" instead of "bad". + (process_format): Say "table format specification" instead of + just "format". Say "column classifier" instead of "format". + When a column modifier is missing an argument or a closing + parenthesis, identify it and refer to it as a "column modifier" + instead of omitting context. Inform user that arguments to `p` + and `v` column modifiers must be "(optionally signed) integer"s, + not "numbers", lower these diagnostics' levels from error to + warning, and indicate that the modifier is ignored. Clarify + diagnostic when extra characters trail `.` at the end of a table + format line. + (process_data): Say "table entry" instead of "data entry" when + discarding an excess one. + (process_table): Say we're giving up on "this table region", not + this "table", particularly since any table continuations (.T&) + are ignored. + +2021-11-25 G. Branden Robinson + + [tbl]: Fix call to `getopt_long()`. + + * src/preproc/tbl/main.cpp (main): Stop telling `getopt_long()` + to look for a `T` option. Continues b4bbf32e, 16 October 2020. + +2021-11-25 G. Branden Robinson + + [tbl]: Tweak usage message. + + * src/preproc/tbl/main.cpp (usage): Document `--version`. Give + version retrieval mode separate synopsis. Use more normative + synopsis syntax. + +2021-11-25 G. Branden Robinson + + [tbl]: Fix code style nits. + + * src/preproc/tbl/main.cpp (process_input_file) + (entry_format::debug_print, process_data, main): Replace + `assert(0)` calls with communicative predicates. + (struct input_entry_format, input_entry_format::debug_print, + process_format): Boolify. Demote and rename `int`s + `last_column` and `equal` to `bool`s named `is_last_column` and + `is_equal_width`. Assign them Boolean literals. + (process_format): Boolify. Demote `have_expand`, `got_format`, + and `got_period` from `int` to `bool`. Use Boolean literals in + assignments thereto. + (process_options): Swap order of null pointer comparison when a + typo or thinko could lead to lvalue assignment. + (process_data): Boolify. Demote `give_up` from `int` to `bool`. + Demote and rename `int` `row_comment` to `bool` + `seen_row_comment`. Use Boolean literals in assignments + thereto. + (main): Use standard C library symbols `EXIT_SUCCESS` and + `EXIT_FAILURE` with `exit()` calls instead of `0` and `1`. + +2021-11-24 G. Branden Robinson + + [grog]: Fix Savannah #61520. + + * src/utils/grog/grog.pl: Move hash `preprocessor_for_macro` to + global scope since it is now mutable across `do_line` subroutine + calls. + (do_line): Adjust regex matching an end macro to work better. + Check names of macros being defined by the document; if they + start with '[' or ']', stop attempting to detect refer(1) usage, + by deleting its key from the `preprocessor_for_macro` hash. + + Fixes . + +2021-11-24 G. Branden Robinson + + [grog]: Add regression test for Savannah #61520. + + * src/utils/grog/tests/avoid-refer-fakeout.sh: Do it. + * src/utils/grog/grog.am (grog_TESTS): Run test. + +2021-11-23 G. Branden Robinson + + * doc/groff.texi (Page Motions): + * man/groff.7.man (Escape short reference): Fix error: the `\r`, + `\u`, and `\d` escape sequences move in ems, not vees, despite + being vertical motions. Add discussion and example. Thanks to + Bjarni Ingi Gislason for pointing out the problem in groff(7) + and Tadziu Hoffman for his lucid explanation. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report and a suggested patch. + +2021-11-20 G. Branden Robinson + + * src/include/error.h: Drop `extern` storage class from + diagnostic function prototypes. Drop parameter names from + prototypes, in keeping with the Stroustrup-style C++ used in + most of groff. + +2021-11-20 G. Branden Robinson + + * src/libs/libgroff/font.cpp (font::load): Update diagnostic + messages to say "kerning pair" instead of "kern pair". + +2021-11-20 G. Branden Robinson + + * src/roff/troff/input.cpp (read_size): Update diagnostic + messages to use more normative language: say "type size" instead + of "point-size", and "escape sequence" instead of "escape". + * src/roff/groff/tests/\ + use_point_size_escape_with_single_digit_arg.sh: Update expected + diagnostic wording in text. + +2021-11-20 G. Branden Robinson + + * src/roff/troff/input.cpp (read_size): Boolify. Update + prototype. Demote return type from `int` to `bool`. Use + Boolean literals for return values. Similarly demote local + variable, rename it from `bad_digit` to + `contains_invalid_digit`, and use Boolean literals with it. + +2021-11-16 Deri James + + * src/devices/gropdf/gropdf.pl: Fixes to importing pdf versions + > 1.4. + +2021-11-15 G. Branden Robinson + + [tbl]: If "nowarn", suppress table row warning. + + * src/preproc/tbl/table.cpp (table::init_output): Bracket the + generated groff code that emits a warning if a table row + overruns a page location trap (usually, is too long to + vertically fit on the page) in a test for whether the "nowarn" + region option was given, so that this warning is suppressed as + well when that option is used. + * src/preproc/tbl/tbl.1.man (Region options): Document new + "nowarn" behavior. + + {"nokeep" also suppresses this warning, for a different reason; + no diversion is created to hold the table row, so its vertical + size does not exist to be compared to the distance to the next + page trap.} + + Fixes . + +2021-11-13 G. Branden Robinson + + * src/preproc/tbl/table.cpp (table::do_vspan): Fix code style + nits. Swap order of null pointer and zero equality comparisons + when a typo or thinko could lead to lvalue assignment. Break a + series of 6 and-ed assertion predicates into separate `assert()` + calls--sure to be less maddening for anyone who has to debug + such a contingency. Clarify comment since C++98 didn't yet have + `nullptr`. + +2021-11-13 G. Branden Robinson + + [m4]: Clean up shell variable quoting and bracing. + + * m4/groff.m4 (GROFF_PROG_YACC, GROFF_MAKEINFO) + (GROFF_BROKEN_SPOOLER_FLAGS, GROFF_TARGET_PATH_SEPARATOR): Stop + bracing shell variable expansions that don't require it; the + shell is not make(1). + (GROFF_PROG_YACC, GROFF_MAKEINFO): Double-quote shell variable + expansions that might produce whitespace. + (GROFF_MAKEINFO): Drop unnecessary leading zeroes from version + number component construction. Drop unnecessary escaping of + plus sign in expr(1) input. + +2021-11-13 G. Branden Robinson + + [m4]: Clean up test(1) usage. + + Get rid of string (non-)nullity tests and comparisons involving + concatenation with garbage (usually "x"). Even the GNU Autoconf + manual's shell portability material doesn't recommend this. It + must be either a bodge cooked up by shell programmers who + couldn't remember to quote variable expansions, or a workaround + for shells of such poor quality that they defied the odds and + decayed out of usage or got fixed. + + Instead, use double quotes (only where necessary). Test for + non-empty strings with "test -n" and empty strings with "test + -z". Stop quoting literal comparands that obviously have no + shell metacharacters in them. + + * m4/groff.m4 (GROFF_PRINT, GROFF_PROG_YACC, GROFF_PERL) + (GROFF_DOC_CHECK, GROFF_MAKEINFO, GROFF_TEXI2DVI) + (GROFF_HTML_PROGRAMS, GROFF_PDFDOC_PROGRAMS, GROFF_PAGE) + (GROFF_TMAC, GROFF_WITH_COMPATIBILITY_WRAPPERS, GROFF_X11) + (GROFF_APPRESDIR_DEFAULT, GROFF_APPRESDIR_CHECK) + (GROFF_HAVE_TEST_EF_OPTION, GROFF_BASH, GROFF_UCHARDET) + (GROFF_UCHARDET_CHECK, GROFF_PDFTOOLS) + (GROFF_USE_GROFF_ALLOCATOR): Do it. + +2021-11-12 G. Branden Robinson + + * m4/groff.m4 (GROFF_TEXI2DVI): Add dependency on + `GROFF_MAKEINFO` macro. Rewrite to also test `MAKEINFO` + variable, which is empty if the `makeinfo` command is not + installed or too old. Consequently ignore `texi2dvi` if is too + old without having to do a version check (since it and + `makeinfo` are distributed together, both being part of GNU + Texinfo). + + * doc/doc.am (.texi.dvi, .texi.pdf): Update error message to + indicate that `texi2dvi` is _either_ missing or too old. + +2021-11-12 G. Branden Robinson + + * m4/groff.m4 (GROFF_MAKEINFO): Stop throwing a warning if the + installed `makeinfo` is old but the distributed Info manual is + up to date. This is not a configure-time problem; the user will + be notified when they run 'make' if they modify doc/groff.texi, + or if they run 'make doc' (which has required a TeX installation + for years). Empty the `MAKEINFO` variable immediately if a + too-old version is detected. Drop needless `AC_SUBST`itution of + the detected `makeinfo` version. + +2021-11-12 G. Branden Robinson + + * m4/groff.m4 (GROFF_HTML_PROGRAMS): Clarify message; it is only + groff-generated HTML that is disabled by the absence of the + programs checked for. (`makeinfo` can still generate our + Texinfo manual in HTML format.) + +2021-11-11 G. Branden Robinson + + [build]: Drop `BUILD_INFODOC` symbol. Ship manual in GNU Info, + text, and HTML forms in distribution archive. + + * Makefile.am (MAINTAINERCLEANFILES): Initialize. + (MOSTLYCLEANADD): Drop unused variable. + * configure.ac: Drop `AM_CONDITIONAL([BUILD_INFODOC]...`. + * doc/doc.am (EXTRA_DIST): Rearrange shipment of our Texinfo + manual source files to precede all of the generated forms, for + clarity. Drop all `BUILD_INFODOC` conditionals. Make + `build_infodoc` phony target depend on plain text, GNU Info, and + HTML forms of Texinfo manual unconditionally. Also drop unused + variables `groffinfodir`, `groffpdfdir`, and `texi2dvi_missing`. + (EXTRA_DIST, MAINTAINERCLEANFILES): Add Info form of manual. + Drop glob pattern attempting to match the segments that + `makeinfo` breaks it into. It isn't necessary for + MAINTAINERCLEANFILES. + (EXTRA_DIST, MAINTAINERCLEANFILES): Add text form of manual. + (EXTRA_DIST, MAINTAINERCLEANFILES): Add HTML form of manual. + (dist-hook): Depend on new (phony) target `dist-info-bits`. + (dist-info-bits): Look for the info document in the build + directory, then the source directory. (It could be in either + place depending on whether the build from a Git working tree is + being done in or out of a separate build directory.) When + found, copy the segments to the assembly area for the + distribution archive. + (install_infodoc): Refactor. Remove any groff info files from + the destination info directory using a shell glob directly + instead of a partly redundant ls(1) command substitution. + Similarly, use a shell glob to cp(1) the info files (including + any matched segments) to the destination info directory before + running `install-info`. (In this process I learned that + `install-info` doesn't "install" anything; instead, it + {de-}registers info files with their top-level catalog.) + +2021-11-11 G. Branden Robinson + + * doc/doc.am (.texi.txt, .texi.html): Reorder pattern rules to + make it clearer which formats require only `makeinfo` and which + require `texi2dvi`. The latter imposes more build dependencies, + including a full TeX installation. + +2021-11-11 G. Branden Robinson + + [mom]: Build more quietly. + + * contrib/mom/mom.am (penguin.{ps,.pdf}): Make targets quiet by + default; they are simple file copies. + +2021-11-11 G. Branden Robinson + + [tests]: Revise a test's setup. + + * src/roff/groff/tests/fp_should_not_traverse_directories.sh: + Revise search for device/font description directory to work in + within-source-tree builds and (for now) with the approach used + by Automake's "distcheck" target. + +2021-11-10 G. Branden Robinson + + [tbl]: Accept `\&` as an empty table entry. + + * src/preproc/tbl/table.cpp (table::add_entry): Suppress + diagnostic about non-empty table entries classified as `_` or + `=` if the entry consists of exactly `\&`. + + * src/preproc/tbl/tbl.1.man (Table data): Document this idiom. + +2021-11-10 G. Branden Robinson + + [tbl]: Update diagnostic messages. + + * src/preproc/tbl/main.cpp (process_options, process_format): + * src/preproc/tbl/table.cpp (table::add_entry): Align diagnostic + text with terminology now used in tbl(1) man page. + - "global option" -> "region option" + - "specifier" -> "column modifier" + - "format" -> "column classifier" + +2021-11-10 G. Branden Robinson + + [libgroff]: Fix missing colon in diagnostic messages. + + * src/libs/libgroff/error.cpp (do_error_with_file_and_line): + Restore missing colon to diagnostic text. Problem introduced by + me in commit 9a038161, 8 November. + +2021-11-09 G. Branden Robinson + + [libgroff,grops]: Slightly refactor. + + * src/devices/grops/ps.cpp: Explicitly preprocessor-include + "lib.h" since we use the `PI` symbol it defines. + + * src/include/lib.h: Add inclusion guard. Wrap only `extern "C" + and its braces in preprocessor conditionals, so that prototypes + are present in the header even for C language code that + #includes this header. Add `static` storage class to `PI` + symbol to avoid redefinition errors from the linker. + + * src/libs/libgroff/iftoa.c (if_to_a): + * src/libs/libgroff/itoa.c (i_to_a, ui_to_a): Add `const` type + qualifier to function definitions for agreement with prototypes + in "lib.h". Drop local copies of prototypes. + +2021-11-09 G. Branden Robinson + + [libgroff]: Centralize definitions of {U,}INT_DIGITS. + + * src/libs/libgroff/iftoa.c: + * src/libs/libgroff/itoa.c: Move definitions of `INT_DIGITS` and + `UINT_DIGITS` from here... + * src/include/lib.h: ...to here. + + * src/libs/libgroff/iftoa.c: + * src/libs/libgroff/itoa.c: Preprocessor-include "lib.h". This + revealed missing guards around `extern "C"` declarations, so... + + * src/include/lib.h: Add them where necessary. + +2021-11-09 G. Branden Robinson + + * tmac/an.tmac (OP): Fix code style nits. Don't quote macro + arguments unnecessarily. Use consistent backslashing. Use + groff font escape sequence syntax. Use adjustable non-breaking + space escape sequence instead of a non-adjustable one. + Parenthesize numeric expression for better readability. + +2021-11-09 G. Branden Robinson + + [libgroff]: Make allocator replacement optional. Switch it + off by default, relying on C++ runtime new/delete support. + + * configure.ac: Call new `GROFF_USE_GROFF_ALLOCATOR` m4 macro. + Use `AM_CONDITIONAL` to set Automake variable + `USE_GROFF_ALLOCATOR` if appropriate. Report whether the + allocator is used in configure script output summary. + * m4/groff.m4 (GROFF_USE_GROFF_ALLOCATOR): Define new macro to + collect user preference. The default is off. + * src/libs/libgroff/libgroff.am (libgroff_a_SOURCES): Build and + link new.cpp only if we are to `USE_GROFF_ALLOCATOR`. + + * NEWS: Add item. + +2021-11-09 G. Branden Robinson + + * m4/groff.m4 (GROFF_TMAC): Report a human-readable message if + no system tmac prefix is found, instead of leaving the ellipsis + hanging. + +2021-11-09 G. Branden Robinson + + * m4/groff.m4 (GROFF_TMAC): Use separate shell variable for + `AC_MSG_RESULT()` content since the human-readable string we + populate it with in the empty case is not appropriate for later + `AC_SUBST()`-itution. Problem introduced by me in commit + 19670348, 31 October. + +2021-11-09 G. Branden Robinson + + * tmac/tmac.am (MOSTLYCLEANFILES): Remove `$(TMACMDOCFILES)`. + This variable, formerly named `TMACMDOCSTRIPFILES`, should not + be used in a clean target because its contents are (no longer) + generated files. Problem introduced by me in commit 24602f42, 4 + July (only noticeable in within-source-tree builds). + +2021-11-08 G. Branden Robinson + + [libgroff,pic]: Check `strdup()` return value. + + * src/libs/libgroff/font.cpp (struct text_file): Add `fatal()` + member function. + (text_file::fatal): Implement it. + + * src/libs/libgroff/font.cpp (font::load_desc): + * src/preproc/pic/troff.cpp (troff_output::set_location): Die if + `strdup()` returned a null pointer. + +2021-11-08 G. Branden Robinson + + * src/libs/libgroff/error.cpp (do_error_with_file_and_line): + Revise to eliminate `fprintf()` calls, which might perform + dynamic memory allocation, rendering this function unsafe to + call after memory allocation failures. Since this function is + near the top of our diagnostic output call stack, that would be + unfortunate. `errprint()` does not use dynamic allocation, nor + do the `i_to_a()` and `ui_to_a()` functions it calls to format + integers. + +2021-11-08 G. Branden Robinson + + * configure.ac: Add `strdup` to AC_CHECK_FUNCS since we are + using it and the whole point of libgroff's `strsave()` was to + get along without it. But `strdup` has been standardized in + POSIX for 20 years (SUSv3, POSIX:2001) and is on its way into + ISO standard C (N2353) and C++ (P2391R0) as well. + +2021-11-08 G. Branden Robinson + + * src/libs/libgroff/strsave.cpp (strsave): Call `strcpy()` only + if `malloc()` did not return a null pointer. Problem noted by + Ingo Schwarze. + +2021-11-07 G. Branden Robinson + + * src/libs/libgroff/fontfile.cpp (font::open_file): Don't open + user-specified font file names with slashes in them; i.e., don't + traverse directories outside the configured font path. Also + refuse to open the file if the `sprintf()` used to construct its + file name doesn't write the expected quantity of bytes to the + destination buffer. + + Fixes . Thanks to Ingo + Schwarze for feedback. + +2021-11-07 G. Branden Robinson + + [libgroff]: Regression-test Savannah #61424. + + * src/roff/groff/tests/fp_should_not_traverse_directories.sh: Do + it. + * src/roff/groff/tests/artifacts/HONEYPOT: Add test artifact. + * src/roff/groff/tests/artifacts/devascii/README: ...and this; + we need a directory to make the test work but empty ones tend to + look unintentional. + * src/roff/groff/groff.am (groff_TESTS): Run test. + (EXTRA_DIST): Ship artifacts. + +2021-11-06 G. Branden Robinson + + [libgroff]: Fix diagnostic error wording. + + * src/libs/libgroff/font.cpp (font::load): Fix diagnostic + message; this is issued when an unrecognized directive is + encountered, so it necessarily occurs _before_ any `charset` or + `kernpairs` directive. Give the user a hint accordingly. + +2021-11-06 G. Branden Robinson + + [man]: Fix paragraph tag regressions. + + * tmac/an-ext.mac (UR, MR): Only create an environment and + diversion if we're not already in one of the latter. If we are + {in groff man, this occurs only when collecting a `TP` paragraph + tag}, then typeset the URI as part of the indented paragraph. + (UE, ME): Pop the diversion and environment stacks only if we + pushed them in the first place. Eliminate spurious space in + post-URI arguments by only typesetting excess macro parameters + if there were any. + +2021-11-05 G. Branden Robinson + + [man]: Regression-test Savannah #61425. + + * tmac/tests/an-ext_link-macros-work-in-paragraph-tags.sh: Do + it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2021-11-05 G. Branden Robinson + + * tmac/s.tmac (DS): Drop a redundant unconditional break; every + display macro we call in the event of a valid call already + breaks the line, and it's polite to not break if we're given an + invalid argument. Emit a diagnostic error if the argument we're + given is invalid, and immediately end the diversion we just + opened. + +2021-11-04 G. Branden Robinson + + * src/roff/troff/env.cpp (environment::set_font): Clarify + diagnostic warning. + +2021-11-04 G. Branden Robinson + + * src/preproc/tbl/table.cpp (table::add_entry): If we see a '\^' + entry on the first row of a table, it's invalid, but we need to + create an empty entry in its place. Otherwise, someone can put + another '\^' right below the one on the first row, creating a + reference to a nonexistent table entry and provoking a SEGV. + Issue an error diagnostic (distinct from the one in + `do_vspan()`), create the entry, and skip `do_vspan()` (given a + '^' in a first-row definition, it issues an error diagnostic and + returns early, which suffices). Problem appears to date back to + groff 1.02 (June 1991) at the latest. + + Fixes . + +2021-11-04 G. Branden Robinson + + [tbl]: Regression-test Savannah #61417. + + * src/preproc/tbl/tests/\ + do-not-segv-on-invalid-vertical-span-entry.sh: Do it. + * src/preproc/tbl/tbl.am (tbl_TESTS): Run test. + +2021-11-02 G. Branden Robinson + + [man]: Fix Savannah #61408. + + * tmac/an.tmac (an-prepare-inner-footer): Don't try to get a + substring of an empty string; the man page author might not have + specified a third argument to `TH` (or supplied an empty one). + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2021-11-02 G. Branden Robinson + + [man]: Add regression test for Savannah #61408. + + * tmac/tests/an_inner-footer-abbreviation-works.sh: Do it. + +2021-11-02 G. Branden Robinson + + [man]: Tweak computation in URI breaking. + + * tmac/an-ext.tmac (UE, ME): Stop adding the page offset `.o` + when performing the available horizontal space computation for + the typeset URI string. This made no difference on nroff + devices (grotty; even with `.po 15n`), but it caused the + breaking decision to be too conservative on troff devices + {grops}, forcing some URIs that would fit on the current line to + the next one. + + * tmac/tests/an-ext_UE-breaks-before-long-URIs.sh: Add test of + URI with no link text, which also has break points after every + character, so that we detect even slight alterations. + +2021-11-02 G. Branden Robinson + + [libgroff]: Do more device and font description file validation, + resolve an assertion failure arising from a negative declared + device resolution, and correct a documentation error. + + * src/libs/libgroff/font.cpp (font::load): Include more + information about invalid input in diagnostic messages. + - When a kern pair's amount is missing or invalid, report the + name of the kern pair. + - When someone tries to declare the first entry in the charset + section as an alias, report the glyph name. + - Identify the token for the unnamed character if an attempt + is made to alias it. + - When an out-of-range character type is applied to a glyph, + name the glyph. + (font::load_desc): Same. + - Drop redundant zero initialization of `res`. + - Check all directives that take basic units for positive + values, adding `res`, `unitwidth`, `paperwidth`, and + `paperlength`. Update this diagnostic to demand positive, + not nonnegative, values. + - When the font count is long in a `fonts` directive, report + how many font names were declared (and thus expected). (If + the count is short, the next line is read for a font name, + like 'tcommand' in our devutf8/DESC.) + - When interpreting a `papersize` directive, throw an error + and return false if `res` has not yet been encountered, + since it is used in subsequent computations. + - When a paper format cannot be determined, report the + original declared value from the DESC file. Use `strdup()` + to save it since it gets clobbered by the resolving process. + `free()` the saved string when we're done, regardless of + error condition. + + * doc/groff.texi (Device and Font Files): + * man/groff_font.5.man (DESC file format): Document additional + exception to order-indifference of directives: (at least one) + `res` must precede `papersize`. + + Fixes . + +2021-11-01 G. Branden Robinson + + * src/devices/grohtml/post-html.cpp + (html_printer::do_file_components): Add assertion. + +2021-11-01 G. Branden Robinson + + * src/devices/grops/ps.cpp (usage): Document -p and --version + options. + +2021-10-31 G. Branden Robinson + + * tmac/mdoc/doc-nroff (doc-setup-page-layout): Set the title + length to the device line length (register `.l`) if register + `LT` is not defined. This keeps the title length from being set + to 78n when the line length is not, preventing the output from + looking silly. + +2021-10-31 G. Branden Robinson + + * src/preproc/tbl/main.cpp (main): Emit groff code to define + macro `T&` as empty if it is not already defined. (All of our + full-service macro packages [except mdoc(7)] already do this, so + there's no change in semantics; mom(7) even defines it as an + empty _string_.) + +2021-10-31 G. Branden Robinson + + * src/roff/groff/tests/string_case_xform_requests.sh: Migrate + test to POSIX shell, dropping use of process substitution (a + Bashism). Also rewrite to stop using a here document within a + command substitution, mainly for paranoia. + + * src/roff/groff/tests/string_case_xform_requests.sh: + * src/roff/groff/tests/on_latin1_device_oq_is_0x27.sh: Update + shebang lines to use /bin/sh as the interpreter. + +2021-10-31 G. Branden Robinson + + * src/devices/grops/ps.cpp (encode_subfont): Update assertion to + check for `sub` parameter being a null pointer rather than + `sub->glyphs`; the latter is a member array of a `subencoding` + struct so it can't be a null pointer. (`glyphs` is an array of + pointers to `const char`; the _elements_ of the array can [and + are initialized to] be null pointers, but the address of the + array itself will never be in a C/C++ implementation.) Detected + by Clang 13's "-Wtautological-pointer-compare". + +2021-10-31 G. Branden Robinson + + * src/libs/libgroff/new.cpp (delete): Declare `throw()` (no + exceptions thrown); quiets "-Wimplicit-exception-spec-mismatch" + from Clang 13. + +2021-10-31 G. Branden Robinson + + * m4/groff.m4: Fix messaging nits. + (GROFF_MAKEINFO): Set `missing` to "missing 'makeinfo'" for + consistency with other assignments to `missing`. + (GROFF_TMAC): Utter an intelligible result in the configure + check when no system macro files requiring groff wrapping are + located. + +2021-10-30 G. Branden Robinson + + [troff]: Handle special character escape sequences that map to + basic Latin glyphs in device control escape sequences + consistently among output devices. + + * src/roff/troff/input.cpp (encode_char): Rearrange + conditionals. This is the logic that puts the "whatever" within + a \X'whatever' escape sequence into GNU troff's intermediate + output. Handle adjustable and nonadjustable space escape + sequences ("\~" and \ ") first. Then, if the token is a special + character escape sequence, retrieve its "contents" (glyph name). + Move the basic Latin mapping for the seven glyph names '-', + 'aq', 'dq', 'ga', 'ha', 'rs', and 'ti' here, before checking + whether the device description issued the + 'use_charnames_in_special' directive. This way, the 'html' and + 'xhtml' output devices can straightforwardly embed these basic + Latin characters in device control escapes (notably, "html:", + for which the present convention is to follow the this tag + immediately with a literal HTML URI, complete with `` + element syntax). If the special character is none of these and + we should 'use_charnames_in_special', proceed as groff 1.22.4 + and earlier did. This is a behavior change, as was my addition + of this translation mechanism in the first place, so... + + * doc/groff.texi (Postprocessor Access): Document it. + + * src/roff/groff/tests/\ + device_control_escapes_express_basic_latin.sh: Test it. + * src/roff/groff/groff.am (groff_TESTS): Run test. + + Fixes . + +2021-10-30 G. Branden Robinson + + [troff]: Map \[ti] correctly in device control escape sequences. + + * src/roff/troff/input.cpp (encode_char): Fix copy-and-paste + error. \[ti] should put '~', not '^', into a device control + command. + + Fixes ; problem introduced + by me in commit 9d61b3d1, 1 October. + +2021-10-30 G. Branden Robinson + + [man]: Handle degenerate input quietly. + + * tmac/an.tmac (TH): Define new register `an-TH-was-called`. + (an-end): Return immediately if that register is not defined; + to format the default page footer we must have the information + declared in a valid `TH` call. (`TH` also initializes the type + size and baseline spacing registers we use to prepare the page + footer environment.) If the register _is_ defined, remove it + just prior to the end of this macro definition, in preparation + for next page to be rendered. + + * tmac/tests/an_handle-degenerate-input-quietly.sh: Test it. + * tmac/tmac.am (tmac_TESTS): Run test. + + Fixes , a regression from + groff 1.22.4 (problem introduced by me in the course of many + changes to trap management and header/footer handling to work + nicely in batch rendering with -mandoc and mdoc(7) documents). + +2021-10-28 G. Branden Robinson + + [man]: Warn if `TE` table macro called but `TW` register (set by + tbl(1)) undefined. Arrange it so that we warn only once per + man(7) document, not per table region. + + * tmac/an.tmac (TH): Remove `TW` register when processing new + document and clear `an-was-tbl-failure-reported` register. + (TE): Check `TW` and `an-was-tbl-failure-reported` registers; if + the former is undefined and the latter false, emit the message + and set `an-was-tbl-failure-reported`. + + Addresses part of . + Thanks to Bjarni Ingi Gislason for the suggestion. + +2021-10-28 G. Branden Robinson + + [tests]: Improve portability. + + * src/devices/grotty/tests/osc8_works.sh: Fix typo in test. + Multiple regex quantifiers after an atom were not flagged with a + diagnostic by GNU grep 3.3, but were by BSD grep 2.5.1-FreeBSD. + + * src/roff/groff/tests/smoke-test_html_device.sh: Stop trying to + set $LC_CTYPE to "C.UTF-8"; some systems don't support this + expediency. Skip the test if the tester hasn't configured the + environment adequately. + + * tmac/tests/s_TC-works-with-percent-in-custom-titles.sh: Fix + portability problems exposed by FreeBSD sed (which version is + unclear). {1} Use POSIX BREs, dropping use of '+' quantifier. + {2} Add semicolons to terminate commands before braces on the + same line. Simplify surrounding test structure. + * tmac/tests/e_footnotes-work-with-columns.sh: Fix same two sed + problems. + * tmac/tests/andoc_flush-between-packages.sh: + * tmac/tests/doc_accept-mixed-case-section-headings.sh: + * tmac/tests/an_TS-do-not-keep-tables-when-cR-set.sh: Fix same + sed semicolon problem. + + * src/roff/groff/tests/on_latin1_device_oq_is_0x27.sh: Rewrite + test to stop using a here document (containing an unpaired + single quote) inside a command substitution, which is broken in + GNU Bash 3.2 and some other versions. Instead construct the + input with printf(1). Also gets rid of a Bashism (process + substitution) that Ingo pointed out years ago. + * src/utils/grog/tests/recognize-perl-pod.sh: Same problem, + different solution. The Perl POD output is far too large to + construct programmatically, so move it into an external file... + * src/utils/grog/tests/foo.man: ...here. + * src/utils/grog/grog.am (EXTRA_DIST): Ship new test artifact. + +2021-10-27 G. Branden Robinson + + * doc/doc.am: Make sed-based insertion of `lf` requests more + portable: a dance is required to embed a literal newline inside + a sed expression inside a shell command executed as part of a + Make target rule. We assume that neither the POSIX shell $'' + operator nor a working printf(1) is available. + (DOC_GROFF): Define a shell variable containing a literal + newline, evading make(1) and echo(1)'s valiant attempts to + consume it. + (doc/pic.html, doc/webpage.html): Repeat trick, slightly + modified since the dependency needs to be manually identified. + + Solution adapted from the GNU Autoconf manual, "Newlines in Make + Rules". + + Fixes . Thanks to John + Gardner for the report. + +2021-10-26 G. Branden Robinson + + * tmac/an.tmac (TH): Stop populating `an-extra3` (the default + center header) if the section argument is "3p". "3p" does not + always mean a Perl-related man page; Debian- and Arch + Linux-based systems[1][2] (at least) have long used a "3perl" + suffix, while OpenBSD appears to still use "3p" for Perl[3], + which is also used by the POSIX man page distribution[4]. + Fortunately, Perl and POSIX are reliable at providing a fifth + argument to `TH` anyway, so our fallback is as unnecessary as it + is non-impartial. + * tmac/groff_man.7.man.in (Document structure macros) : + De-document the above behavior. + + [1] https://manpages.debian.org/bullseye/perl-doc/\ + Pod::Man.3perl.en.html + [2] https://man.archlinux.org/man/Pod::Man.3perl + [3] https://man.openbsd.org/man3p/Pod::Man.3p + [4] https://man7.org/linux/man-pages/man3/system.3p.html + +2021-10-26 G. Branden Robinson + + [man]: Abbreviate the inside footer if necessary. + + * tmac/an.tmac (an-prepare-inner-footer): Prevent the inside + footer from overrunning the center footer. + (BT): Use new string `an-ifoot` instead of `an-extra2` in page + footers. + + Fixes . + +2021-10-26 G. Branden Robinson + + Add regression test for Savannah #61386. + + * tmac/tests/an_inner-footer-abbreviation-works.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2021-10-26 G. Branden Robinson + + * man/groff_char.7.man (Description, Special character escape + forms): Document the `\C` escape sequence. Fix error: \[a] is + _not_ "translated to \a, the uninterpreted leader escape + sequence," but requests a glyph _named_ '\a' internally--it + appears thus in diagnostic messages and, importantly, in the + font description files defining special character glyph names. + +2021-10-25 G. Branden Robinson + + * tmac/an.tmac: Refactor to reduce repetition. + (an-break-paragraph): New macro handles paragraph-breaking tasks + previously duplicated. + (SH, SS, P, TP, IP, HP): Call it rather than issuing its + constituent requests. + +2021-10-25 G. Branden Robinson + + * tmac/an.tmac (TP): Reset type size, vertical spacing, and font + to defaults before setting the new paragraph. + + Fixes . + +2021-10-24 G. Branden Robinson + + * doc/groff.texi (Auto-increment): Fix error; the `\R` escape + sequence does _not_ support an auto-incrementation amount. + * man/groff_out.5.man (Command reference/Simple commands): Fix + erroneous claim: 'N' is not a GNU roff extension; it appears on + page 27 of CSTR#54 (1992). + +2021-10-24 Keith Marshall + + [ms]: Provide global default XH and XN implementations. + + cf. + + * tmac/s.tmac (XH-INIT, XN-INIT, XH-UPDATE-TOC) + (XH, XN, XH-REPLACEMENT, XN-REPLACEMENT): Implement them, and... + * tmac/groff_ms.7.man: ...document them. + +2021-10-24 Keith Marshall + + [ms]: Fix misleading NH macro indentation. + + * tmac/s.tmac (@NH) [.T is html]: .if statement should exhibit + same indentation as preceding .DEVTAG-NH statement, but is + overindented; fix it. + +2021-10-23 Keith Marshall + + [ms]: Defend against uncontrolled page trap recursion. + + * tmac/s.tmac (pg@top) [HM+FM+.V>.p]: Diagnose insufficient page + length, and abort; cf. + +2021-10-21 G. Branden Robinson + + [groff]: Fix code style nits. + + * src/roff/groff/groff.cpp (main, help): Use standard C library + preprocessor symbols `EXIT_SUCCESS` and `EXIT_FAILURE` instead + of 0 and 1 literals, respectively. See commit fa4c27e9, 7 + September. + (main): Replace `assert(0)` with a communicative predicate. + +2021-10-21 G. Branden Robinson + + * src/devices/grotty/tty.cpp (tty_printer::special_link): + Eliminate casts by retyping `uri` and `pair` to pointers to + `const char`s. + +2021-10-21 G. Branden Robinson + + * tmac/tmac.am: Build more quietly. + (tmac/stamp-wrap): Prefix all rule commands with `$(AM_V_at)`; + since this target is a stamp file instead of a useful artifact + to be distributed, make its creation completely silent by + default. + +2021-10-21 G. Branden Robinson + + * src/roff/troff/troff.am: Build more robustly. + (src/roff/troff/majorminor.cpp): Drop progress-reporting `echo` + in favor of prefixing final rule command with `$(AM_V_GEN)`. + Prefix earlier rule commands with `$(AM_V_at)`. Use `printf` + instead of `echo` to build the file, and create a temporary file + at first so that we don't race with the compiler on parallelized + builds. + +2021-10-21 G. Branden Robinson + + * src/preproc/eqn/eqn.am (neqn): Simplify: drop removal of + target prior to overwriting it; any system we can build groff on + should have a shell that implements the clobbering semantics of + the POSIX shell '>' operator. (If this isn't true, we have + _many_ other target rules in our build to which we must add + prefatory `$(RM)`s, or I miss my guess.) + +2021-10-21 G. Branden Robinson + + * src/libs/libgroff/libgroff.am: Build more quietly and + robustly. + (src/libs/libgroff/version.cpp): Drop progress-reporting `echo` + in favor of prefixing final rule command with `$(AM_V_GEN)`. + Prefix earlier rule commands with `$(AM_V_at)`. Use `printf` + instead of `echo` to build the file, and create a temporary file + at first so that we don't race with the compiler on parallelized + builds. Drop nilpotent sed transformation; this looks like a + relic of past times when we'd drop a trailing ".0" from the + version number stored in the C symbol `Version_string`. + (charset.alias, ref-del.sed, ref-add.sed): Prefix rule command + with `$(AM_V_GEN)`. + +2021-10-21 G. Branden Robinson + + * src/devices/xditview/xditview.am: Build more quietly. + (src/devices/xditview/GXditview-ad.h): Drop progress-reporting + `echo` in favor of prefixing rule command with `$(AM_V_GEN)`. + +2021-10-21 G. Branden Robinson + + * font/devpdf/devpdf.am: Build more quietly. + (font/devpdf/enc/text.enc, font/devpdf/map/symbolmap, + $(DEVPDFFONTMAP_1)): Prefix all rule commands with + `$(AM_V_at)`; since these are all `mkdir`s and `cp`s, I reason + that little can go wrong with them that won't be disclosed by + these tools' own diagnostic messages, so they are insignificant + from a perspective of build progress. + +2021-10-21 G. Branden Robinson + + * doc/doc.am: Build more quietly. + (doc/examples.stamp): Prefix all rule commands with + `$(AM_V_at)`; since this target is a stamp file instead of + a useful artifact to be distributed, make its creation + completely silent by default. + (doc/groff.info, .texi.txt): Prefix directory creation with + `$(AM_V_at)` and `makeinfo` command with `$(AM_V_GEN)`. + (.texi.dvi, .texi.pdf): Prefix directory creation with + `$(AM_V_at)` and `makeinfo` command with `$(AM_V_GEN)`. Send + diagnostic message to standard error if `texi2dvi` is + unavailable. + (.texi.html): Prefix directory creation with + `$(AM_V_at)`. Two HTML versions are produced, in split and + unsplit versions; prefix one `makeinfo` command with + `$(AM_V_GEN)` and the other with `$(AM_V_at)` so that only one + message is produced. + (gnu.eps): Drop useless/noisy `echo` command. Prefix copy + operation with `$(AM_V_at)`. Send diagnostic messages to + standard error if there are problems with the Netpbm tools. + + (MOSTLYCLEANFILES): The `mostlyclean` target was leaving a file, + `groff.info-3`, behind in the build tree. At some point our + Texinfo manual grew beyond earlier expectations. Use a glob + `[0-9]` instead (giving a hostage to fortune that `makeinfo` + will never split our manual into more than nine chunks). + +2021-10-21 G. Branden Robinson + + * arch/misc/misc.am: + (arch_shdeps_sh): Pull file name into a new variable. + (EXTRA_DIST, shdeps.sed): Use it. + (shdeps.sed): Build more quietly; prefix with `$(AM_GEN_V)`. + +2021-10-20 G. Branden Robinson + + [nroff]: Support groff's -R flag to run refer(1). + + There's no reason not to support calling `refer` with nroff-mode + documents; typographically, it's less demanding than tbl(1). + GNU troff(1) supports an incompatible `-R` flag to suppress the + reading of troffrc{,-end} files, but this is likely not the `-R` + that users will want--it is most useful for troubleshooting + troff, and nroff already unconditionally loads a macro file + {tty-char.tmac}. + + * src/roff/nroff/nroff.sh: Do it. + + * src/roff/nroff/nroff.1.man: + * NEWS: Document it. + +2021-10-20 G. Branden Robinson + + * tmac/tmac.am (tmac/groff_man.7.man) + (tmac/groff_man_style.7.man): Be quieter by default; use + $(AM_V_GEN) more consistently with the rest of the build. + +2021-10-19 G. Branden Robinson + + * src/roff/troff/input.cpp (do_error): Format diagnostic + messages in closer alignment with GNU Coding Standards: don't + introduce a space between the program name and the input file + name. + + * src/roff/groff/tests/string_case_xform_errors.sh: Update + expected output. + +2021-10-19 G. Branden Robinson + + * src/roff/troff/env.cpp (distribute_space): Revert an + `assert()` I added in commit b93eacd8d7 (5 September); we can + indeed reach this code with a negative amount of desired space, + and in fact the "show hyphenation points" trick + + relies upon it. Add explanatory comment. + + Fixes . + +2021-10-17 G. Branden Robinson + + * test-groff.in: Add support for sboxes.tmac. + +2021-10-11 Paul Eggert + + Include before any standard headers. + + Gnulib requires that files that might use Gnulib features (which + pretty much means every C or C++ source file) must include + first. Arrange for that. This will be needed once + Groff updates to the latest Gnulib; see Bjarni Ingi Gislason's + problem report in: + + + The only exception I can see is src/utils/addftinfo/guess.cpp, + which does not include any standard include file either directly + or indirectly, and so need not include . + + * src/devices/xditview/Dvi.c: + * src/devices/xditview/font.c: + * src/devices/xditview/lex.c: + * src/devices/xditview/page.c: + * src/devices/xditview/parse.c: + * src/libs/libbib/map.c: + * src/libs/libgroff/change_lf.cpp: + * src/libs/libgroff/cmap.cpp: + * src/libs/libgroff/cset.cpp: + * src/libs/libgroff/fmod.c: + * src/libs/libgroff/getcwd.c: + * src/libs/libgroff/lf.cpp: + * src/libs/libgroff/ptable.cpp: + * src/libs/libgroff/quotearg.c: + * src/libs/libxutil/DviChar.c: + * src/libs/libxutil/XFontName.c: + * src/libs/libxutil/xmalloc.c: + * src/utils/indxbib/signal.c: Do it. + + [Fixes . --GBR] + +2021-10-10 Deri James + + Handle pdfs > v1.4 loaded by \X'pdf: pdfpic'. + + * src/devices/gropdf/gropdf.pl: Improve loading of pdfs above + version 1.4, i.e. handle compressed nodes in /ObjStm. Also + improve code in \X'pdf: import'. + +2021-10-10 Deri James + + Add new background boxes to gropdf. + + * src/devices/gropdf/gropdf.pl: New \X'pdf: background' command. + * tmac/pdf.tmac: Covenience command .pdfbackground added. + * contrib/sboxes/: Files which demonstrate use of background + boxes using -ms macros. + +2021-10-09 G. Branden Robinson + + [tests]: Fix portability problems in 2 tests. + + * src/roff/groff/tests/break_zero-length_output_line_sanely.sh: + * tmac/tests/s_PN-works.sh: Migrate from `echo` to `printf` for + test inputs containing backslashes to be interpreted literally. + + Fixes part of . Thanks to + Deri James for identifying the problem. + +2021-10-08 G. Branden Robinson + + [grotty]: Slightly refactor. + + * src/devices/grotty/tty.cpp: Boolify. Demote numerous + variables (and one return type) from `int` to `bool`, use + Boolean instead of integer literals with them, and give the + variables names resembling logical predicates. + - horizontal_tab_flag -> want_horizontal_tabs + - form_feed_flag -> want_form_feeds + - bold_flag_option -> want_emboldening_by_overstriking + - bold_flag -> do_bold + - underline_flag_option -> want_italics_by_underlining + - underline_flag -> do_underline + - overstrike_flag -> want_glyph_composition_by_overstriking + - draw_flag -> allow_drawing_commands + - italic_flag_option -> want_sgr_italics + - italic_flag -> do_sgr_italics + - reverse_flag_option -> want_reverse_video_for_italics + - reverse_flag -> do_reverse_video + - old_drawing_scheme -> use_overstriking_drawing_scheme + (class tty_printer:printer): Similarly. + - is_underline -> is_underlining + - is_bold -> is_boldfacing + - cu_flag -> is_continuously_underlining + (tty_printer::tty_color): Demote return type as above. Invert + its sense; rename `unknown_color` to `is_known_color`. + (tty_printer::color_to_idx): Invert sense of test at + `tty_color()` call site. + +2021-10-07 G. Branden Robinson + + [ms]: Finish documenting new `TC-MARGIN` register and + `TC-LEADER` special character. + + Fixes . + +2021-10-06 G. Branden Robinson + + [grotty]: Slightly refactor. + + * src/devices/grotty/tty.cpp (tty_printer::special_link): Use + consistent loop styles and drop unnecessary arithmetic. + +2021-10-06 G. Branden Robinson + + [man]: Fix oversight and improve `MR` test. + + * tmac/an-ext.tmac (initialization): Enable `mY` register to + indicate use of grotty(1) (and therefore OSC 8 support) if the + "ascii", "cp1047", or "latin1" output devices are used, not just + "utf8". + + * tmac/tests/an_MR-works.sh: Drop copy-and-paste cruft from a + different test. Update expected output and check for the + presence of "link" device control subcommands, not just correct + font selections. + +2021-10-05 G. Branden Robinson + + [man]: Add `MR` macro for man page cross references. + + * tmac/an.tmac (an-prepare-page-title): After a possibly + abbreviated man page title is determined, redefine `an-pageref` + to set the title portion in the font stored in the `MF` string + and bracket it with italic corrections if that font is thought + to be oblique. + (MR): Add macro to format the text of a man page cross + reference, and hyperlink it on HTML and terminal output devices + if permitted by the `U` register. + (initialization): Define `MF` string as `I` if not already set. + Define `an-lic` and `an-ic` strings as either empty or as + containing italic corrections. + + * tmac/an-ext.tmac (MR): If the formatter is not GNU troff, + define macro to format the text of a man page cross reference. + + * tmac/groff_man.7.man.in: Document it. + (Description): Add macro to summary table. + (Description/Hyperlink macros): Document new feature. Note + origin in Plan 9 troff. [style] Add examples of use. + (Description/Font style macros): Drop man page cross references + from list of items whose typeface conventions are disputed, + since we have a semantic macro now and a configurable means of + resolving the problem. + (History): Add `MR` item. + (Options) : Document new string. + (Files) : Revise discussion to accommodate `MR`. + (Authors): Add myself an author of extension macros. + + * tmac/tests/an_MR-works.sh: Test it. + * tmac/tmac.am (tmac_TESTS): Run test. + + * NEWS: Add item. + +2021-10-05 G. Branden Robinson + + * tmac/an.tmac (SH, SS): Invoke `ne` request _before_ performing + font remapping: any page-breaking decision will be taken before + the remapping happens, and so won't be in effect across a page + boundary, undesirably impacting header and footer text. + + Fixes . + +2021-10-05 G. Branden Robinson + + Regression-test Savannah #61279. + + * tmac/tests/an_font-remapping-does-not-affect-titles.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2021-10-04 G. Branden Robinson + + * tmac/an.tmac (an-abbreviate-title): Rename to... + (an-prepare-page-title): ...this. + +2021-10-03 G. Branden Robinson + + [docs]: Correct erroneous claim: the ".NH S" extension to ms(7) + comes from 4.2BSD, not GNU. + +2021-10-03 G. Branden Robinson + + * doc/ms.ms (Creating a table of contents): Sync with recent + additions to groff_ms(7), expand, and heavily revise. + +2021-10-03 G. Branden Robinson + + [andoc,man,mdoc]: Fix Savannah #61266. Resolve problems in + batch rendering of man pages to PDF arising from entanglement + of end-of-input traps, page location traps, continuous rendering + mode, and andoc's reloading of the (m)an and (m)doc packages. + + * tmac/andoc.tmac (reload-doc, reload-man): Remove end-of-input + traps alongside others. + + * tmac/an.tmac (an-end): Only perform flush and "manual" page + footer placement if in continuous rendering mode, since this + macro is not only called by a trap placed only in continuous + rendering mode, but also by andoc when changing macro packages. + Unconditionally remove the `an-header` trap since the next + document might be using a different macro package. + + * tmac/mdoc/doc-common: In initialization, set flag indicating + that manual header placement will be required. + (Dt): Call `doc-setup-header` (which sets up several types of + trap) unconditionally, and break the page if the vertical + drawing position is anywhere but at the top. + (Os): If the package has just been initialized, call + `doc-header` to force the page header to be written. + (doc-end-macro): Remove `doc-header` trap since the next + document might be using a different macro package. Break the + page. Set flag indicating that manual header placement will be + required for the next document. + + * tmac/mdoc/doc-ditroff (doc-setup-header): Only set page + location traps for the header and footer if not continuously + rendering. + * tmac/mdoc/doc-nroff (doc-setup-header): Stop calling + `doc-header` here if continuously rendering. Emit an + unconditional break. Except for the location of the footer + trap, the `doc-setup-header` implementations are now identical. + + Refactoring is needed: some macros and registers have misleading + names, there is some code duplication in mdoc, and some of the + trap management problems are solved in slightly different ways + in man(7) and mdoc(7), perhaps unnecessarily. We also need some + test scripts to protect us from regressions. But this fixes the + rendering problems. + + Fixes . + +2021-10-02 Keith Marshall + + Correct manpage typo/inconsistency. + + * tmac/groff_ms.7.man (TC_LEADER, TC_MARGIN): Correct; should + be... + (TC\-LEADER, TC\-MARGIN): ...respectively, for consistency + with... + * tmac/s.tmac (TC-LEADER, TC-MARGIN): ...these. + +2021-10-03 G. Branden Robinson + + * src/roff/troff/input.cpp (encode_char): Update diagnostic + messages to not presume the identity of the escape character; + continues 9be3f8e3 (4 June). + +2021-10-03 G. Branden Robinson + + * src/devices/grotty/tty.cpp (tty_printer:special_link): Tighten + code slightly by taking advantage of preprocessor string literal + concatenation. + +2021-10-01 G. Branden Robinson + + [man]: Fix `U` enablement override so it actually works the way + I had in mind. + - The package proper enables it by default, but + - the sample site configuration file switches it off, on the + assumption that distributors and users will know better than + we do when they get a capable pager in place, and + - a register setting at the command line (or otherwise prior to + the loading of the macro package) is dispositive. + + * tmac/an-ext.tmac: Rename URI output device capability register + from `U` to `mU`. + (UR, UE, MT, ME): Test both `U` and `mU` before handling + hyperlinks specially. + * tmac/an.tmac: If `man.local` did not initialize `U`, switch it + on. The hope is that we can drop the stuff in `man.local` + completely at some point. + * tman/man.local: Only initialize `U` if it is not already + defined. + +2021-10-01 G. Branden Robinson + + [man]: Use OSC 8 hyperlinks. + + * tmac/an-ext.tmac: Add registers `mY` (output driver is + "grotty") and `U` (generate hyperlinks). `U` is intended to + apply to hyperlinking support in general, not just grotty's OSC + 8 feature. If the output driver is either grohtml or grotty, + make `U` true (`man.local` is read subsequently and can override + it). + (UR, MT): Conditionalize diversion production on hyperlink + support, not grohtml use per se. + (UE, ME): Generate device control commands for `tty` device to + emit hyperlinks. + + * tmac/groff_man.7.man.in (Options): Document -rU. + (Files) [style]: Add example of `U` register enablement. + + * tmac/man.local: Disable `U` register by default, except on the + `html` device. + + * NEWS: Add item. + +2021-10-01 G. Branden Robinson + + [grotty]: Add OSC 8 hyperlink support. + + * src/devices/grotty/tty.cpp: Do it. Define `OSC` (Operating + System Command) and `ST` (String Terminator) preprocessor + symbols for these ECMA-48 (ISO 6429) character sequences. + (tty_printer::simple_add_char): Add stripped-down alternative to + `add_char()` member function for cases where we want to use many + defaults because we're writing a terminal escape sequence, not + rendering a glyph. (A function like `add_char()` that takes 8 + arguments of varying types is a code smell--phew!) + (tty_printer::special): Call `special_link()` member function if + the device control command is `link`. + (tty_printer::special_link): Add new member function to generate + OSC 8 hyperlinks. + + * src/devices/grotty/grotty.1.man: Document it. Observe in + multiple places that disablement of SGR escape sequences + disables OSC 8 too. + + * src/devices/grotty/tests/osc8_works.sh: Test it. + * src/devices/grotty/grotty.am (TESTS, grotty_TESTS): Run test. + (EXTRA_DIST): Ship test. + + * NEWS: Add item. + + Fixes . Thanks to Steffen + Nurpmeso for supplying a proof-of-concept. (I went with my own + implementation, though, so blame me if it breaks.) + +2021-10-01 G. Branden Robinson + + [troff]: Convert special character glyphs corresponding to + Unicode Basic Latin ("ASCII") code points to those code points + when they occur in device escapes. (They should be correct for + IBM code page 1047 as well, but this is untested.) This is + necessary for encoding URLs in device control commands. Special + character identifiers are presumed to be the defaults documented + in groff_char(7); this is a design gap that we should consider + addressing. (We don't have a way to ask "is this the special + character corresponding to Unicode basic Latin code point X?") + + * src/roff/troff/input.cpp (encode_char): Do it. + +2021-09-30 G. Branden Robinson + + [man, mdoc]: Draw line after each page more consistently in + continuous rendering mode. + + * tmac/an.tmac (an-bp): Move responsibility for line-drawing + after each document from here... + (an-end): ...to here. Refactor; drop + `an-do-draw-line-after-document` register in favor of testing + `\n[.F]` for nullity; if it is not null, then another document + is due to be processed (in fact, `.F` already contains its file + name), and we need to draw a separating line. If it is null, we + have reached the end of input and none is necessary. + + * tmac/mdoc/doc-ditroff.tmac (doc-setup-page-layout): + * tmac/mdoc/doc-nroff.tmac (doc-setup-page-layout): Save + configured line length in new register `doc-line-length`. + * tmac/mdoc/doc-common.tmac (doc-end-macro): Port the above + man(7) feature to mdoc(7); draw a line of this length after each + document if continuously rendering. + +2021-10-01 Keith Marshall + + [ms]: Update footnote handling documentation. + + * tmac/groff_ms.7.man: Make some linguistic style adjustments. + (FP): Document it; see . + (FS-MARK): Likewise, document this recently added feature. + +2021-10-01 Keith Marshall + + [ms]: Support user-defined TOC leader style. + + * tmac/s.tmac (toc*leader-char): Rename it as... + (TC-LEADER): ...this; within PX, leave it unchanged, if + predefined. + (TC-MARGIN): New numeric register; if predefined, leave it + unchanged, otherwise define as \w'000'; use it instead of + hard-wired definition, within PX; see + . + + * tmac/groff_ms.7.man (TC-LEADER, TC-MARGIN): Document them. + +2021-09-28 G. Branden Robinson + + [pic]: Update input file name correctly. + + * src/preproc/pic/troff.cpp (troff_output::set_location): Copy + the inbound file name argument with `strdup()` and store pointer + to this copy in `last_filename` instead of aliasing argument. + (troff_output::~troff_output): `free()` the memory allocated by + `strdup()` in destructor. + + Fixes . Pointer + assignment instead of a string copy was being performed, which + means that after its initial assignment, `last_filename` always + shared its value ultimately with the `current_filename` pointer + {a libgroff symbol}, so `strcmp()` was always being performed on + identical pointers. Problem appears to date back 30+ years, to + the dawn of our repo history. + +2021-09-24 G. Branden Robinson + + * font/devlj4/S: Make font name consistent with file name. + +2021-09-24 G. Branden Robinson + + * src/libs/libgroff/font.cpp (font::load): Throw error if a font + description file is missing a `spacewidth` directive, since it + is now re-documented as mandatory. Atypically, we don't return + false in this scenario; instead we proceed with the existing + logic to compute a space width for the font based on typical + practices for Western alphabetic fonts (see, e.g., + . + + * font/devdvi/EX: + * font/devdvi/MI: + * font/devdvi/S: + * font/devdvi/SA: + * font/devps/EURO: Add `spacewidth` directive to font + description files we ship that were missing it. We use the same + values that libgroff would have computed, so there should be no + visible difference. + +2021-09-24 G. Branden Robinson + + * Makefile.am: Mark `$(TEST_SUITE_LOG)` as `.PRECIOUS`. This + prevents the test suite log from being deleted if there are any + failures. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2021-09-23 G. Branden Robinson + + * src/utils/grog/grog.pl (do_line): Move first-macro-call test + for `TH` to a more appropriate location. + +2021-09-23 G. Branden Robinson + + [grog]: Refactor to make it easier to generalize a per-package + scoring mechanism. + + * src/utils/grog/grog.pl: Convert `inferred_main_package` from + scalar to list. Add scalar `selected_main_package` to store a + "winner" from the list of main packages inferred. + (push_main_package): Add subroutine to populate + `inferred_main_package`. + (do_line, infer_man_or_ms_package): Update to use + `push_main_package`. + (construct_command): Rewrite to select a main package from the + list `inferred_main_package`, taking user-supplied arguments + into account as an overriding factor. Drop now-unused `msupp` + list. + +2021-09-23 G. Branden Robinson + + * src/roff/groff/groff.cpp (main): If the `-I` option is given, + run the grn preprocessor and pass it an `-M` option with `-I`'s + argument. + + * NEWS: + * src/roff/groff/groff.1.man (Options): Document it. Also + document that `-I` options are passed to the output driver. + +2021-09-23 G. Branden Robinson + + * src/utils/grog/grog.pl (do_line): Don't strip groff-style + comments \# if AT&T compatibility mode is enabled. + +2021-09-23 G. Branden Robinson + + [libgroff]: Perform more font description file validation. Our + documentation said that the `name` directive was mandatory but + we didn't actually enforce this. Also be more specific in our + complaints of ill-formedness. + + * src/libs/libgroff/font.cpp (font::load): Add local Boolean + variable `saw_name_directive`. Rename `had_charset` to + `saw_charset_directive` for symmetry. Emit distinct diagnostics + for `spacewidth` and `slant` directives having a missing, + non-numeric, or out-of-range argument. Emit diagnostic if the + file lacks a `name` directive. + +2021-09-23 G. Branden Robinson + + [libgroff]: Slightly refactor. + + * src/libs/libgroff/font.cpp (struct text_file): Rename member + variable `size` to `linebufsize` for clarity (it's certainly not + the size of the text file). + (text_file::text_file): Initialize `linebufsize` in constructor. + (text_file::next_line): Allocate new `buf` using `linebufsize` + instead of magic number (which was also stored to `size`, making + it only semi-magic, I guess). Rename local variable `i` to + `length` since it is in fact the length (in `char`s) of the + string stored in `buf`. + +2021-09-23 G. Branden Robinson + + [libgroff]: Revisit fix for Savannah #61173. + + * src/libs/libgroff/font.cpp (text_file::text_file): Restore + setting of `lineno` member variable to `0` in constructor + initializer list, but... + (text_file::next_line): ...unconditionally increment it every + time through this member function's outer loop. + +2021-09-23 G. Branden Robinson + + [troff]: Align diagnostic message format with libgroff. + + * src/roff/troff/input.cpp (fatal_with_file_and_line): Report + the program name if one is defined. + (fatal_with_file_and_line, error_with_file_and_line, + debug_with_file_and_line): Report the line number of the input + file only if it is positive, so that other values can be used + for "whole file" complaints. See commit cd0457b6, 17 September. + +2021-09-23 G. Branden Robinson + + [libgroff]: Drop redundant diagnostic. + + * src/libs/libgroff/font.cpp (font::load): Drop redundant + diagnostic; a missing `charset` directive is already checked for + later, circa line 998. + +2021-09-22 G. Branden Robinson + + [libgroff]: Fix code style nits. + + * src/libs/libgroff/font.cpp (font::font): Use initializer list + as much as possible in constructor. + (font::unit_scale, font::get_width, font::get_height, + font::get_depth, font::get_italic_correction, + font::get_left_italic_correction, + font::get_subscript_correction, font::get_character_type, + font::get_code, font::get_special_device_encoding): These member + functions rely on the font being either indexed or associated + with an output device that uses the `unicode` directive in its + `DESC` file. The compiler doesn't know this, so annotate the + `abort()` calls that conclude them. Add an `assert()` before + each one to more usefully describe the violated invariant in the + event this unreachable code is somehow reached. + (font::get_width): Annotate special meaning of zero zoom factor. + +2021-09-21 G. Branden Robinson + + * src/include/font.h (UNDEFINED_GLYPH): Use idiomatic C++98 null + pointer constant. + +2021-09-19 G. Branden Robinson + + [grohtml]: Fix compiler warning and dead store. + + * src/devices/grohtml/post-html.cpp (html_printer::special): + Update call of `font::load_font()` to stop passing obsolete + parameter (deleted by me in 2dff87d3, 17 September). The value + stored to the parameter by that function was never read anyway, + so also get rid of the variable that contained it. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2021-09-19 G. Branden Robinson + + [libgroff]: Slightly refactor. + + * src/include/font.h (font::scan_papersize): Demote return type + from `int` to `bool`. + * src/libs/libgroff/font.cpp (font::scan_papersize): As above. + Use Boolean instead of integer literals. Also rename `FILE` + stream pointer from `f` to `fp` and perform an explicit + comparison against the idiomatic C++98 null pointer constant. + +2021-09-17 G. Branden Robinson + + [libgroff, troff]: Slightly refactor device and font description + file loading. Remove dead code. + + * src/include/font.h (font::load_font): Drop second parameter. + It was never used for its intended purpose. + (load): Drop first parameter; likewise. + * src/libs/libgroff/font.cpp (font::load, load): As above. + + * src/libs/libgroff/font.cpp (struct text_file): Rename + `skip_comments` to `recognize_comments`. Demote that and + `silent` from `int` to `bool`. + (text_file::text_file): Use Boolean rather than integer literals + in constructor. + (text_file::next_line, font::load): Apply above renaming. + + * src/libs/libgroff/font.cpp (font::load): Rename parameter from + `head_only` to `load_header_only` to be more communicative. + Drop test of font description file name being `DESC`; this code + was not being reached. Stop throwing errors from this function + on failure to open the file; the caller will handle this when it + sees our false return value. Rename local variable `command` to + `directive` for alignment with our documentation. Replace "I + dont think this should happen" test and comment with `assert()`. + (struct table): Rename member from `command` to + `numeric_directive` to indicate its specificity, tracking only a + subset of valid `DESC` file directives. + + * src/libs/libgroff/font.cpp (font::load, font::load_desc): + Remove redundant assignments to the member variable formerly + known as `skip_comments`. + + * src/libs/libgroff/font.cpp (font::load_desc): Rename local + variable `directive_found` to `numeric_directive_found` to + clarify logic. + + * src/roff/troff/node.cpp (mount_font_no_translate): Simplify + call of `font::load_font`. The `not_found` in-out parameter + which was so agonizingly passed up through layers of library + calls was never actually read. Drop code that has been `#if + 0`-ed out since 1993. + +2021-09-17 G. Branden Robinson + + * src/libs/libgroff/font.cpp (font::load_desc): Clear line + number before emitting whole-file validity diagnostics. + +2021-09-17 G. Branden Robinson + + * src/libs/libgroff/font.cpp (font::load_desc): Emit correct + line numbers when complaining of invalid `sizescale`, `hor`, or + `vert` values in device description files. + + Fixes . + +2021-09-17 G. Branden Robinson + + [libgroff]: Increase validation of device and font description + files. + + * src/libs/libgroff/font.cpp (font::load): Validate the syntax + and value of the `name` directive. + (font::load_desc): Issue distinct diagnostics for a `fonts` + directive that is missing arguments and for a first argument + that can't be interpreted as a valid number. + +2021-09-17 G. Branden Robinson + + [libgroff]: Make error reporting more flexible. + + * src/libs/libgroff/error.cpp (do_error_with_file_and_line): + Interpret a nonpositive line number specially: treat the + diagnostic as applying to the entire file, and omit the line + number. + +2021-09-17 G. Branden Robinson + + [libgroff]: Add information to diagnostics. + + * src/libs/libgroff/font.cpp (font::load): Drop unused argument + from `error()` call. + (font::load_desc): In another, add name of numeric directive + that is given an unparsable number. + +2021-09-17 G. Branden Robinson + + [libgroff]: Tweak code style. + + * src/libs/libgroff/font.cpp (trim_args, font::load) + (font::load_desc): Compare pointer explicitly to null pointer + literal `0` instead of using logical complementation. + (font::load, font::load_desc): Swap order of null pointer + equality comparisons when a typo or thinko could lead to lvalue + assignment. + +2021-09-17 G. Branden Robinson + + [libgroff]: Use idiomatic C++98 null pointer constant. + + * src/libs/libgroff/font.cpp (text_file::error) + (glyph_to_unicode, font::get_special_device_encoding) + (font::load): + * src/libs/libgroff/fontfile.cpp (font::image_generator): + * src/libs/libgroff/nametoindex.cpp (class charinfo) + (character_indexer::named_char_glyph) + (character_indexer::numbered_char_glyph): + * src/libs/libgroff/string.cpp (string::clear): + * src/libs/libgroff/tmpfile.cpp (temp_init::temp_init): + * src/libs/libgroff/tmpname.cpp (gen_tempname): Use `0` literal + instead of `NULL` to represent a null pointer; this was + idiomatic in C++98 and is mostly the practice elsewhere in + groff. Also swap order of null pointer equality comparisons + when a typo or thinko could lead to lvalue assignment. + + * src/roff/troff/input.cpp (input_stack::diversion_state) + (input_stack::get_diversion_state, charinfo::contains) + (glyph_to_name): Similar. + +2021-09-17 G. Branden Robinson + + [libgroff]: Slightly refactor. + + * src/libs/libgroff/font.cpp (font::load): Use same loop style + as `font::load_desc()`. + +2021-09-17 G. Branden Robinson + + [libgroff]: Fix off-by-one error in font and device description + file reader diagnostics. + + * src/libs/libgroff/font.cpp (text_file::text_file): All text + files begin with line 1, not line 0. + + Fixes . + +2021-09-17 G. Branden Robinson + + [libgroff]: Boolify more interfaces. + + * src/include/font.h (font::unit_scale): + * src/libs/libgroff/font.cpp (font::unit_scale): Demote return + type from `int` to `bool`. Use Boolean literals instead of + integers. + + * src/libs/libgroff/font.cpp (struct text_file): Rename `next` + member function to `next_line`. Demote its return type from + `int` to `bool`. Use Boolean literals instead of integers. + +2021-09-16 G. Branden Robinson + + [libgroff]: Boolify local variables. + + * src/libs/libgroff/font.cpp (font::load, font::load_desc): + Demote local variables used as Booleans from `int` to `bool` and + update literals used with them from integer to Boolean. + +2021-09-16 G. Branden Robinson + + [grn, groff, troff]: Communicate better when device DESC file + can't be loaded. + + * src/libs/libgroff/font.cpp (font::load_desc): Stop writing + diagnostic to standard error. + * src/preproc/grn/main.cpp (getres): + * src/roff/troff/troff.cpp (main): Replace "sorry, I can't + continue" fatal diagnostic with a more informative message. + Instead say which device's DESC file the program was trying to + open, which might reveal a user's logic error or typo. + * src/roff/groff/groff.cpp (main): Replace "invalid device" text + of fatal diagnostic similarly. I think it is more helpful to + indicate the operation that failed rather than saying the device + was invalid, particularly since there are other ways for a + device description to be invalid even if a DESC file is found + and loaded. + +2021-09-16 G. Branden Robinson + + [troff]: Throw warning diagnostic if device DESC file attempts + to load unavailable fonts. + + * src/roff/troff/input.cpp (main): Take advantage of new Boolean + return values of `mount_style()` and `mount_font()` to produce + warning diagnostics if mounting a style or font as directed by + the DESC file fails. Explain in a comment why, at present, this + style mount warning will never actually trip. + +2021-09-15 G. Branden Robinson + + [troff]: Lift font mounting diagnostic messages to be closer to + their user-controlled contexts to provide more information. In + many cases no diagnostic was being thrown at all when an + unavailable font was requested by name, which is the method most + users prefer, and which meant that failures resulting from typos + in font names for many requests (`uf`, `fschar`, `rfschar`, + `special`, `fspecial`, `fzoom`, `bd`, `tkf`, `cs`) were going + unreported. Further, promote these font warnings to errors + because the request will utterly fail to do what was requested + with no reasonable fallback. Possibly, they were formerly + warnings because at the low level they were being emitted, they + could also have originated from unavailable fonts encountered in + device description files, and while that's bad news, it results + in no formatting problems if it doesn't affect fonts that an + input document actually uses. + + * src/roff/troff/node.cpp (struct font_lookup_info): New struct + keeps the font name or position requested, and the position of + successful font lookup. + (font_lookup_info::font_lookup_info): Add constructor. + (font_lookup_error): New function builds error message using a + `font_lookup_info` struct and a message argument. + (get_fontno): Rename to... + (has_font): ...this. Add argument to take a pointer to a + `font_lookup_info` struct. Return a `bool` indicating whether + the lookup succeeded. Place former `int` return value into the + struct instead. Populate the other struct members with the + requested font name or position, as appropriate. + (mount_font_no_translate): Stop throwing warning diagnostic here + if a font cannot be loaded. Instead, throw them... + (font_position): ...here, and... + (underline_font, define_font_special_character, + remove_font_special_character, read_special_fonts, + font_special_request, font_zoom_request, bold_font, track_kern, + constant_space): ...here, using `font_lookup_info` structs and + `has_font()`. + (remove_font_special_character): Stop returning early if font + lookup fails; it's gratuitously inconsistent with other similar + functions (save one, which has a reason to be different). + (define_font_special_character): Return early if font lookup + fails and say why in a comment (we can't `skip_line()`). + + Fixes . + +2021-09-15 G. Branden Robinson + + * [libgroff, troff]: Further boolify. + + * src/include/font.h (load_font, font): Demote parameters from + {pointer to} `int` to `bool` and update default literal from + integer to Boolean (except for the pointer). Update comment. + * src/libs/libgroff/font.cpp (load_font, load): Similarly. + + * src/roff/troff/node.h (mount_font): + * src/roff/troff/node.cpp (mount_font): Demote return type from + `int` to `bool`. + + * src/roff/troff/node.h (mount_style): + * src/roff/troff/node.cpp (mount_style): Promote return type + from `void` to `bool`. + + * src/roff/troff/node.cpp (mount_font_no_translate): Demote + return type and `check_only` parameter from `int` to `bool` and + use Boolean rather than integer literals with them. + (check_font): Update call site of `mount_font_no_translate` to + use Boolean literal. + (font_position): Indicate that "error" is ignored by casting + return value of `mount_font` to void instead of using a comment. + (style): Cast return value of `mount_style` to `void`. + +2021-09-15 G. Branden Robinson + + * Makefile.am: Add `.DELETE_ON_ERROR` special target; both GNU + and FreeBSD make(1)s support it so maybe it will be portable + enough. This avoids, among other problems, a target appearing + falsely up-to-date (often as an empty file) when the troff + process generating it experiences an assertion failure. + +2021-09-12 G. Branden Robinson + + Since June 1991 if not earlier, groff (technically, the refer, + lookbib, and lkbib programs) has trusted the header contents of + binary bibliographic index files (canonically generated with + indxbib(1)) regarding the sizes of the data structures that + follow in the file, a notorious class of security problem. In + July 2013, the Mayhem Team at Carnegie Mellon University + reported to the Debian Bug Tracking System a problem with + groff's refer(1) implementation dumping core when reading an + index file prepared by a fuzzer. + + * src/libs/libbib/index.cpp (index_search_item::check_header): + Add new member function to validate the header of an indexed + bibliography file, returning a string describing in detail the + first validity problem encountered. + (index_search_item::load): Perform the foregoing check before + using any of the size values taken from the header; they are + relied upon for pointer arithmetic. If in verification mode + {using the undocumented `-V` flag to refer(1), lkbib(1), or + lookbib(1)}, report the details of the problem encountered. + Regardless of that mode, if there is a validity problem, report + corruption of the index file and abandon it, forcing fallback to + the text version of the corresponding bibliography file. + + Fixes . + +2021-09-12 G. Branden Robinson + + * src/libs/libbib/index.cpp + (index_search_item::get_invalidity_reason): Don't complain about + a last list element being nonnegative if the list size was zero + in the first place, as can happen with an empty index. More + seriously from a language standpoint, avoid reading through a + negative array index (this can escape a compiler's attention + because we're reading from the midst of a heap-allocated or + `mmap()`ed region, but it's still a code smell). + + Fixes . + +2021-09-12 G. Branden Robinson + + * src/libs/libbib/index.cpp (index_search_item::load) + (index_search_item::get_invalidity_reason) + (index_search_item::add_out_of_date_file): Clarify diagnostic + messages. Make it more obvious when we're complaining of a + problem in an indexed bibliographic database file (rather than a + plain text one). Dial down the amount of Unix jargon a little. + +2021-09-12 G. Branden Robinson + + [libbib]: Partially boolify. + + * src/include/search.h: + * src/libs/libbib/index.cpp: + * src/preproc/refer/refer.cpp: + * src/utils/lkbib/lkbib.cpp: + * src/utils/lookbib/lookbib.cpp: Demote `verify_flag` from an + `int` to a `bool`, rename it to `do_verify`, use Boolean + instead of integer literals with it, and update call sites. + + * src/libs/libbib/index.cpp: Rename `do_verify()` member + function to `get_invalidity_reason()` (it returns a string). + Demote `load()` from `int` to `bool`; do the same for `verify()` + and rename it to `is_valid()` as well. Use Boolean instead of + integer literals with them. + (index_search_item::is_valid, make_index_search_item): Update + call sites of renamed member functions. + +2021-09-12 G. Branden Robinson + + * src/libs/libbib/map.c (mapread): Compare return value of + `mmap()` to `MAP_FAILED` instead of `(char *)-1`. `MAP_FAILED` + is documented in POSIX Issue 5 a.k.a. SUSv2 + + {1997} and should be portable enough by now. + +2021-09-11 G. Branden Robinson + + [troff]: Clamp negative tab stop positions to zero instead of + throwing an assertion failure. + + * src/roff/troff/env.cpp (tab_stops::distance_to_next_tab): + Replace `assert` with clamping logic, ensuring that `lastpos` + can never be negative. While negative tab stop positions don't + make much sense (they result in zero horizontal motion), user + input like `.ta T -5` should never provoke an assertion failure. + + (set_tabs): Throw range warning in additional scenario, viz., if + a repeating tab offset is negative. + + Fixes . Thanks to наб for the + report. + +2021-09-11 G. Branden Robinson + + [troff]: Boolify `set_tabs` function. + + * src/roff/troff/env.cpp (set_tabs): Demote local variables from + `int` to `bool` and give them predicate-like names. + - `first` -> `is_first_stop` + - `repeated` -> `is_repeating_stop` + Use Boolean instead of integer literals in assignments to them. + +2021-09-11 G. Branden Robinson + + [man]: Deprecate `OP` macro. + + * tmac/an-ext.tmac (OP): Move implementation from here... + * tmac/an.tmac (OP): ...to here. Throw deprecation warning. + Throw style warning if wrong number of arguments given. + + * tmac/groff_man.7.man.in (Description): Drop from introductory + macro summary. + (Description/Command synopsis macros): Move discussion from + here... + (Description/Deprecated features): ...to here. Explain why it's + deprecated. + +2021-09-07 G. Branden Robinson + + [troff]: Make `ab` request quiet if given no arguments. The + `tm`, `tm1`, and `tmc` requests provide ample flexibility for + constructing diagnostic messages prior to an error exit, and + it's convenient to make `ab` itself quiet instead of saying + "User Abort." as Unix Version 7 troff did. Further, there is no + standardization across troffs regarding what `ab` should emit if + arguments are absent. + + * src/roff/troff/input.cpp (abort_request): Do it. + + * src/roff/groff/tests/ab_works.sh: + * src/roff/groff/groff.am (groff_TESTS): Test it. + + * doc/groff.texi (Debugging, Implementation Differences): + * man/groff.7.man (Requests/Request short reference): + * man/groff_diff.7.man (Implementation differences): Document + it. + + Fixes . Thanks to Dave + Kemper for the discussion. + +2021-09-07 G. Branden Robinson + + [troff]: Update exit status literals. + + * src/roff/troff/div.cpp (top_level_diversion::begin_page): + * src/roff/troff/input.cpp (exit_troff, abort_request, do_error) + (fatal_with_file_and_line): Use standard C library preprocessor + symbols `EXIT_SUCCESS` and `EXIT_FAILURE` instead of 0 and 1 + literals, respectively. + +2021-09-06 G. Branden Robinson + + [troff]: Drop unused member function. + + * src/roff/troff/token.h (class token): Drop unused `title` + member function. Its implementation was apparently removed in + the prehistory of our Git repository: see James Clark's + ChangeLog entry of 1990-09-06. + +2021-09-06 G. Branden Robinson + + [troff]: Remove workaround for Cfront 1.2 bug. + + * src/roff/troff/input.cpp (do_define_macro): Move `dot_symbol` + from to file to function local scope as originally intended. + +2021-09-06 G. Branden Robinson + + [troff]: Rename parameter. + + * src/roff/troff/input.cpp (token::usable_as_delimiter): Rename + parameter from `err` to `report_error` to be more communicative. + +2021-09-06 G. Branden Robinson + + [troff]: Boolify members of `token` class. + + * src/roff/troff/token.h (class token): Demote return type of + several member functions from `int` to `bool` and rename them. + - `backspace` -> `is_backspace` + - `delimiter` -> `usable_as_delimiter` + - `dummy` -> `is_dummy` + - `eof` -> `is_eof` + - `horizontal_space` -> `is_horizontal_space` + - `hyphen_indicator` -> `is_hyphen_indicator` + - `leader` -> `is_leader` + - `left_brace` -> `is_left_brace` + - `newline` -> `is_newline` + - `page_ejector` -> `is_page_ejector` + - `right_brace` -> `is_right_brace` + - `space` -> `is_space` + - `special` -> `is_special` + - `stretchable_space` -> `is_stretchable_space` + - `tab` -> `is_tab` + - `transparent_dummy` -> `is_transparent_dummy` + - `transparent` -> `is_transparent` + - `unstretchable_space` -> `is_unstretchable_space` + - `white_space` -> `is_white_space` + - `zero_width_break` -> `is_zero_width_break` + (class token): Drop 1991 comment anticipating that member + function `nspaces` could return "2" for a "double space"; this + was apparently never implemented. + (class token): Drop parameter names from declarations; the + prevailing style (familiar from Stroustrup) is not to use them. + (token::is_special): Simplify implementation. + + * src/roff/troff/input.cpp (has_arg) + (token::usable_as_delimiter): Update definitions of above member + functions not defined in token.h. + + * src/roff/troff/div.cpp (begin_page, space_request, need_space) + (output_saved_vertical_space, flush_output): + * src/roff/troff/env.cpp (fill, no_fill, center) + (right_justify, indent, temporary_indent, margin_character) + (number_lines, do_break_request, hyphen_word): + * src/roff/troff/input.cpp (next_file, do_overstrike) + (do_bracket, do_name_test, do_expr_test, do_zero_width) + (token::skip, has_arg, skip_line, empty_name_warning) + (non_empty_name_warning, do_get_long_name, process_input_stack) + (flush_pending_lines, decode_args, read_request) + (do_define_string, do_define_character, remove_character) + (do_define_macro, length_request, get_delim_number) + (get_line_arg, read_size, get_delim_name, do_register, do_width) + (read_title_parts, encode_char, do_special, device_request) + (output_request, skip_alternative, begin_alternative) + (nop_request, do_if_request, do_source, pipe_source) + (ps_bbox_request, tag, taga, do_terminal, do_translate) + (hyphenation_code, hyphenation_patterns_file_code, define_class) + (get_optional_char, check_missing_character, abort_request) + (copy_file, transparent_file, do_macro_source) + (charinfo_to_node_list, read_draw_node, read_color_draw_node): + * src/roff/troff/node.cpp (get_fontno) + (remove_font_special_character, bold_font): + * src/roff/troff/number.cpp (start_number, parse_term): + * src/roff/troff/reg.cpp (define_number_reg, alter_format): + Update call sites to use new names. + + * src/roff/troff/input.cpp (token::usable_as_delimiter) + (read_draw_node): Return Boolean, not integer, literals. + +2021-09-06 G. Branden Robinson + + [troff]: Clamp line and title lengths to device horizontal + resolution. + + * src/roff/troff/env.cpp (line_length, title_length): Do it. + + Fixes . + +2021-09-06 G. Branden Robinson + + * src/roff/troff/env.cpp (do_hyphenation_patterns_file): + Refactor slightly. Demote `append` from `int` to `bool`. + (hyphenation_patterns_file, hyphenation_patterns_file_append): + Update call sites to use Boolean, not integer, literals. + +2021-09-05 G. Branden Robinson + + * src/roff/troff/hvunits.h: + * src/roff/groff/number.cpp: Mark `H0`, `V0` objects as `const`. + +2021-09-05 G. Branden Robinson + + * src/roff/troff/env.cpp (do_underline_special): Refactor + slightly. + - Rename `underline_spaces` -> `do_underline_spaces`. + - Demote it from an `int` to a `bool`. + - Use ternary operator and explicit character literals when + writing device control command instead of doing arithmetic + on a character literal. + - Update call sites to use Boolean literals. + - Relocate function to avoid forward reference. + - Mark function as static to eliminate external linkage. + Remove now-unnecessary prototype. + +2021-09-04 Keith Marshall + + Add "ms" footnote marker placement hook. + + * tmac/s.tmac (FS-MARK): New macro; define as no-op, by default. + (@FS): Invoke FS-MARK as first action, allowing caller to "hook" it. + +2021-09-04 G. Branden Robinson + + * src/roff/troff/env.cpp (distribute_space): Refactor slightly. + - Rename `force_reverse` to `force_reverse_node_list`. + - Rename `reverse` to `do_reverse`. + - Demote both of the above from `int` to `bool`. + - Use Boolean literals with them. + - Add assertions to enforce positive values of `nspaces` and + `desired_space`. + - Remove now-redundant test for `nspaces` being positive. + - Add explanatory comments. + (environment::wrap_up_field): Update call sites of + `distribute_space` when non-default value of + `force_reverse_node_list` is supplied. + +2021-09-04 G. Branden Robinson + + [troff]: Don't adjust nonadjustable lines. This means that the + direction from which an output line in adjustment mode "b" (or + its "n" synonym) is filled with supplemental space is not + changed if that output line does not require adjustment. This + will result in whitespace changes to documents using that + adjustment mode, and these changes will be plainly visible on + low-resolution output devices like terminals. + + To illustrate, in the following "A" means an output line + requiring adjustment; "F" a line that is "full" and does not; + and "L" and "R" indicate distribution of adjustment spaces from + the left and right, respectively. + + groff 1.22.4 groff 1.23.0 + ------------ ------------ + A L A L + A R A R + F L F R + A R A L + + * src/roff/troff/env.cpp (distribute_space): Return early if + either the amount of desired space to be distributed or the + count of space nodes in the output line to distribute it among + is zero. + + * tmac/tests/an_TH-repairs-ad-damage.sh: Update test to expect + space to be distributed differently. + + Fixes and + . + +2021-09-04 G. Branden Robinson + + Skip core-dump-checking test if a core file already exists. + + * src/roff/groff/tests/regression_savannah_59202.sh: Skip test + if a core dump is already present. + +2021-09-04 G. Branden Robinson + + Add regression test for Savannah #60189. + + * src/roff/groff/tests/break_zero-length_output_line_sanely.sh: + Do it. + * src/roff/groff/groff.am (groff_TESTS): Run test. + +2021-08-29 G. Branden Robinson + + [troff]: Tweak diagnostic message. + + * src/roff/troff/env.cpp (environment::environment): Use + terminology more rigorously in diagnostic. + +2021-08-29 G. Branden Robinson + + [libgroff]: Fix code style nit. + + * src/libs/libgroff/errarg.cpp (errprint): Replace `assert(0)` + with a meaningful predicate. + +2021-08-28 G. Branden Robinson + + [libgroff]: Demote `need_space` to Boolean. + + * src/libs/libgroff/error.cpp (do_error_with_file_and_line): + Demote local integer `need_space` and its assignments to `bool`. + +2021-08-28 G. Branden Robinson + + [libgroff]: Boolify `font::load()` and `font::load_desc()` + return values. + + * src/include/font.h (font::load, font::load_desc): + * src/libs/libgroff/font.cpp (font::load, font::load_desc): Do + it. + +2021-08-28 G. Branden Robinson + + * m4/groff.m4 (TRADITIONAL_CPP): Update `AC_MSG_CHECKING` + argument to refer to "pre-ISO C90 syntax" instead of a + "traditional" preprocessor. Call `AC_MSG_ERROR` (aborting + configuration) if the check (for pre-C90 transformation) + succeeds. We thus withdraw support for such superannuated + {"Reiser"} C preprocessors. + +2021-08-28 G. Branden Robinson + + [libgroff]: Un-indirect token concatenation through macro. + + * src/include/itable.h: + * src/include/ptable.h: Do it. + +2021-08-28 G. Branden Robinson + + [libgroff]: Drop support for `TRADITIONAL_CPP`. This means a C + preprocessor that does not support the ANSI C89/ISO C90 + token concatenation operator "##". + + * src/include/itable.h: + * src/include/ptable.h: Do it. + + * Makefile.am: Undocument preprocessor symbol. + +2021-08-27 G. Branden Robinson + + [libgroff]: Drop `a_delete` preprocessor wrapper for the + `delete` operator. It has been rendered unnecessary by the + removal of support for ancient C++ compilers. + + * src/include/lib.h (a_delete): Drop symbol definition. + + * src/devices/grohtml/output.cpp (word::~word): + * src/devices/grohtml/post-html.cpp (char_block::char_block) + (assert_state::~assert_state, assert_state::add) + (assert_state::close, replace_negate_str): + * src/devices/grops/ps.cpp (ps_font::ps_font) + (subencoding::subencoding, ps_printer::define_encoding) + (ps_printer::encode_fonts): + * src/devices/grops/psrm.cpp (resource_manager::document_setup) + (resource_manager::supply_resource): + * src/devices/grotty/tty.cpp (tty_printer::tty_color) + (tty_printer::tty_printer, tty_printer::color_to_idx) + (tty_printer::add_char): + * src/include/itable.h (ITABLE(T)::~ITABLE(T)) + (ITABLE(T)::define): + * src/include/ptable.h (PTABLE(T)::~PTABLE(T)) + (PTABLE(T)::define): + * src/libs/libbib/index.cpp + (index_search_item::~index_search_item, make_index_search_item, + index_search_item_iterator::index_search_item_iterator, + index_search_item::get_tag, index_search_item::munge_filename, + index_search_item::search): + * src/libs/libbib/linear.cpp (bmpattern::~bmpattern) + (file_buffer::file_buffer, file_buffer::load) + (linear_searcher::linear_searcher) + (linear_searcher::~linear_searcher): + * src/libs/libbib/search.cpp + (search_list_iterator::search_list_iterator) + (search_item::search_item): + * src/libs/libdriver/input.cpp (IntArray::~IntArray) + (IntArray::append, StringBuf::~StringBuf, StringBuf::append) + (get_integer_arg, parse_x_command, do_file): + * src/libs/libdriver/printer.cpp (printer::printer) + (printer::load_font, text_file::~text_file, text_file::next) + (font::~font, font_widths_cache::~font_widths_cache) + (font:alloc_ch_index, font::extend_ch, font::compact) + (font::load_desc): + * src/libs/libgroff/fontfile.cpp (font::open_file): + * src/libs/libgroff/relocate.cpp (searchpath, searchpathext) + (set_current_prefix): + * src/libs/libgroff/searchpath.cpp (search_path::search_path) + (search_path::command_line_dir, search_path::open_file) + (search_path::open_file_cautious): + * src/libs/libgroff/string.cpp (sfree, srealloc) + (string::remove_spaces): + * src/libs/libgroff/symbol.cpp (symbol::symbol, concat): + * src/libs/libgroff/tmpfile.cpp (temp_init::temp_init) + (xtmpfile_list_init::~xtmpfile_list_init, xtmpfile): + * src/preproc/eqn/box.cpp (set_gfont, set_grfont, set_gbfont) + (box_list::append, box_list::~box_list): + * src/preproc/eqn/delim.cpp (make_delim_box) + (delim_box::~delim_box): + * src/preproc/eqn/eqn.ypp (number): + * src/preproc/eqn/lex.ypp (file_input::~file_input) + (argument_macro_input::~argument_macro_input): + * src/preproc/eqn/pile.ypp (matrix_box::~matrix_box) + (matrix_box::append): + * src/preproc/eqn/special.cpp (special_box::~special_box): + * src/preproc/eqn/text.ypp (set_char_type): + * src/preproc/html/pre-html.cpp (get_line, scanArguments): + * src/preproc/pic/object.cpp (output::~output) + (output::set_args, text_item::~text_item) + (object_spec::~object_spec, command_object::~command_object) + (line_object::~line_object): + * src/preproc/pic/pic.ypp (placeless_element, reset_variables) + (print_args, text_expr, object_spec, text, sprintf_args, path): + * src/preproc/refer/command.cpp (input_item::~input_item) + (input_item::peek_char): + * src/preproc/refer/label.ypp (lookup_label): + * src/preproc/refer/refer.cpp (store_citation, store_reference): + * src/preproc/tbl/main.cpp (format::add_rows, format::~format): + * src/preproc/tbl/table.cpp (block_entry::~block_entry) + (table::~table, table::allocate): + * src/roff/groff/groff.cpp (possible_command::~possible_command) + (possible_command::clear_name): + * src/roff/troff/column.cpp + ((justification_spec::~justification_spec) + (justification_spec::append): + * src/roff/troff/dictionary.cpp (dictionary::lookup): + * src/roff/troff/env.cpp (override_sizes, tab_stops::to_string) + (hyphen_word, hyphen_trie::insert_hyphenation): + * src/roff/troff/input.cpp (read_long_escape_name, token::next) + (do_get_long_name, temp_iterator::~temp_iterator) + (get_delim_name, pipe_source, read_string, pipe_output) + (system_request, open_mac_file, do_macro_source) + (do_register_assignment, do_string_assignment, read_draw_node) + (copy_mode_error): + * src/roff/troff/node.cpp (troff_output_file::set_font) + (troff_output_file::~troff_output_file, draw_node::is_tag) + (grow_font_table, font_family::~font_family) + (font_family::make_definite): + * src/utils/hpftodit/hpftodit.cpp (name_list::~name_list) + (read_map): + * src/utils/indxbib/indxbib.cpp (main, get_cwd): + * src/utils/tfmtodit/tfmtodit.cpp (tfm::~tfm, tfm::load): Port + uses of `a_delete` to `delete[]`. + +2021-08-27 G. Branden Robinson + + [libgroff]: Drop `ad_delete` preprocessor wrapper for the + `delete` operator. It has been rendered unnecessary by the + removal of support for ancient C++ compilers. + + * src/include/lib.h (ad_delete): Drop symbol definition. + + * src/preproc/pic/object.cpp (graphic_object::print_text): + * src/preproc/refer/ref.cpp (reference::reference) + (reference::merge, reference::insert_field) + (reference::delete_field): + * src/preproc/tbl/main.cpp (format::add_rows): Port uses of + `ad_delete` to `delete[]`. + +2021-08-28 G. Branden Robinson + + * m4/groff.m4 (GROFF_ARRAY_DELETE): Update `AC_MSG_CHECKING` + argument to refer to "ISO C++98" instead of "ANSI". Call + `AC_MSG_ERROR` (aborting configuration) if the check fails. + +2021-08-27 G. Branden Robinson + + [libgroff]: Drop support for `ARRAY_DELETE_NEEDS_SIZE`. + + * src/include/lib.h [ARRAY_DELETE_NEEDS_SIZE]: Drop preprocessor + conditional branch. This abandons support for certain pre-ISO + C++98 compilers. (According to a now-removed comment, unsized + array deletion was documented in "ARM", meaning _The C++ + Annotated Reference Manual_, published in 1989.) + + * Makefile.am: Undocument preprocessor symbol. + +2021-08-27 G. Branden Robinson + + [libgroff]: Drop redefinition of `INT_MIN`. + + * src/include/lib.h: Drop redefinition of `INT_MIN`. It was + motivated by a bug in the AT&T C++ compiler (cfront), version + 2.0, released in June 1989. Implementations have had 30 years + to get this right; assume that they have. + + * PROBLEMS: Drop corresponding item. + +2021-08-27 G. Branden Robinson + + [libgroff]: Drop long-dead `COOKIE_BUG` logic. + + * src/libs/libgroff/new.cpp (operator new, operator delete): + Drop preprocessor conditional branches on the `COOKIE_BUG` + symbol. This was de-documented, and an autoconf check for its + necessity removed, way back in groff 1.10 (November 1995). It + was relevant only to GCC from versions 2.0 to 2.2.2 (all 1992). + +2021-08-24 G. Branden Robinson + + [libgroff]: Refactor `font::scan_papersize()`. + + * src/libs/libgroff/font.cpp (font::scan_papersize): Ensure + successful return value of `fgets()` before attempting to parse + string for paper format. Convert `test_file` to Boolean and + rename to `attempt_file_open`. Quiets GCC `-Wunused-result` + warning. + +2021-08-23 G. Branden Robinson + + [tests]: Apply naming convention. + + * tmac/tests/e_footnotes_work_with_columns.sh: Rename from... + * tmac/tests/e_footnotes-work-with-columns.sh: ...to this. + * tmac/tmac.am (tmac_TESTS): Update. + +2021-08-23 G. Branden Robinson + + * tmac/an.tmac (IP): Make code more accessible by using a + Boolean operator rather than an arithmetic one (assembly + language programmers are comfortable with the interchangeability + of subtraction and comparison, but not everyone is). + +2021-08-23 G. Branden Robinson + + groff(7): Document more escapes. + + * man/groff.7.man (Escape short reference): Document + `\[charNNN]`, `\[uNNNN]`, `\[uNNNN_NNNN...]` escape sequences. + Revise descriptions of `\O0` and `\O1` escape sequences. + Document `\O2`, `\O3`, `\O4`, and `\O5` escape sequences. + +2021-08-23 G. Branden Robinson + + groff(7): Fix bug in `\?` escape rendering. + + * man/groff.7.man (ESC?): Fix bug in page-private macro: the + question mark that ends this uniquely-syntaxed escape sequence + was not shown with the mandatory escape character before it. + Problem dates back at least to commit 41b0e794, 19 February + 2007, but possiby to f790bc7a9, 6 January 2002. + +2021-08-21 G. Branden Robinson + + [docs]: Elaborate macro definition discussion. + + Fixes . Thanks to Dave + Kemper for the report. + +2021-08-21 G. Branden Robinson + + [tests]: Make robust against $GROFF_TYPESETTER settings. + + * src/roff/groff/tests/\ + use_point_size_escape_with_single_digit_arg.sh: + * src/roff/nroff/tests/verbose_option_works.sh: + * tmac/tests/s_IP-indents-using-paragraph-type-size.sh: Export + an empty $GROFF_TYPESETTER to the environment. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2021-08-21 G. Branden Robinson + + [libgroff]: Treat an empty $GROFF_TYPESETTER as unset. + + * src/libs/libgroff/device.cpp (device_init::device_init): Test + both returned pointer from `getenv()` and, if that's not null, + the first character of the string for nullity before assigning + it to `device`. + + Fixes . + +2021-08-21 G. Branden Robinson + + [libgroff]: Rename font class member variable. + + * src/include/font.h (font class): Rename `unscaled_charwidths` + member variable to `use_unscaled_charwidths`: since it is a + Boolean, make it read more like a logical predicate. + + * src/libs/libgroff/font.cpp (font::get_width, font::load_desc): + * src/libs/libgroff/fontfile.cpp (font class): Update + initialization and assignments. + +2021-08-20 G. Branden Robinson + + * src/roff/troff/input.cpp (get_copy): Demote integer arguments + to Booleans and use Boolean literals for default values. Rename + `defining` to `is_defining`. + (get_char_for_escape_name, do_define_macro): Update call sites + that use non-default arguments to use Boolean literals and + comments to document what's being requested. + +2021-08-17 G. Branden Robinson + + * doc/doc.am (DOC_GROFF_ONLY): Stop running groff in unsafe + mode; no documents (in _this_ directory) appear to require it. + +2021-08-16 G. Branden Robinson + + [grn]: Fix code style issues. + + * src/preproc/grn/hgraph.cpp: + * src/preproc/grn/hpoint.cpp: + * src/preproc/grn/main.cpp: + * src/preproc/grn/hdb.cpp: Drop use of `register` storage class. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report and a suggested patch. + + * src/preproc/grn/hgraph.cpp (len, HGPrintElt, picurve): + * src/preproc/grn/hdb.cpp (DBRead): Wrap long lines. + + * src/preproc/grn/hgraph.cpp: Rename function from + `Paramaterize` to `Parameterize`. + (HGCurve): Update call site. + + * src/preproc/grn/main.cpp (add_file): Drop redundant cast in + `realloc()` call. + (conv, interpret): Use standard English in diagnostic messages. + +2021-08-16 G. Branden Robinson + + * src/preproc/grn/hdb.cpp: Perform more input validation. + Improve diagnostics by taking advantage of libgroff + infrastructure and tracking the line number of the input file. + Add global `lineno`. + (DBRead): Increment `lineno` after reading newlines from input. + Call `error_with_file_and_line()` instead of `error()`. If + input reports a negative length for the text (string) to follow + in the file, exit with a fatal diagnostic. Check for EOF while + reading text string. + (DBGetType): Convert `fprintf()` call for warning diagnostic to + `warning_with_file_and_line()`. + (DBRead, DBGetType): Add contextual information to diagnostic + messages. + + Fixes . Thanks to + Savannah user eqkws for the report. + +2021-08-16 G. Branden Robinson + + * src/preproc/grn/main.cpp (usage): Update usage message. + +2021-08-16 G. Branden Robinson + + [grn]: Add and use `malloc()` wrapper. + + * /src/preproc/grn/main.cpp (grnmalloc): New function takes + argument of `size_t` type and constant string argument to + describe what is being allocated. Return non-null pointer from + `malloc()`, otherwise call `fatal()`, describing what was being + allocated and the problem reported by the system. + + * src/preproc/grn/hdb.cpp (DBCreateElt): + * src/preproc/grn/hpoint.cpp (PTMakePoint): + * /src/preproc/grn/main.cpp (main, interpret): Migrate + `malloc()` callers to `grnmalloc()`. + +2021-08-16 G. Branden Robinson + + * src/preproc/grn/hdb.cpp (DBRead): Check return value of + `sscanf()` and call `fatal()` if no conversions succeeded. The + blithe discard of a useful return value is bad enough, but this + one took place inside a do-while such that it could loop + forever trying fruitlessly to parse two doubles out of strings + that didn't contain them (the loop never checked the EOF status + of the file stream from which it was reading, and relied on + `fgets()` to keep advancing the stream pointer). Discovered + while root-causing Savannah #61043. + +2021-08-15 G. Branden Robinson + + Resolve compiler warnings relating to format string security and + ISO C++98 conformance. + + * src/preproc/eqn/delim.cpp (define_extensible_string): + * src/preproc/pic/pic.ypp (do_sprintf): Use #pragma to silence + GCC "format-nonliteral" warning and explain why our usage is + safe in a comment. + + * src/preproc/preconv/preconv.cpp (detect_file_encoding): Use + `l` modifier to `%u` `fprintf()` conversion instead of `z`, and + cast return values of `size_t` to unsigned long; "ISO C++98 + does not support the ‘z’ gnu_printf length modifier" (it doesn't + support `ll` either). N.B. this is debugging output only. + + * src/roff/groff/groff.cpp (synopsis): + * src/roff/troff/input.cpp (usage): Repeat variadic argument for + `%s` conversion in `fprintf()` call because "ISO C++98 does not + support %n$ operand number formats". + + * src/roff/troff/env.cpp: Initialize adjustment and hyphenation + mode enums without commas at the end of the enumeration lists. + +2021-08-15 G. Branden Robinson + + [man]: Clean up the interface between `an-footer` and `BT`, and + HTML header and footer suppression generally. Move + responsibility for checking the `ps4html` register from the + latter to the former. This is not something a `BT` redefiner + {see groff_man(7)} should have to worry about. + + * tmac/an.tmac (BT): Drop test of `ps4html` register and early + return. + (an-header, an-footer): Return immediately if + `an-suppress-header-and-footer` is true. Remove conditional on + `an-is-output-html`. + (initialization): Define `an-suppress-header-and-footer` + register; true if `an-is-output-html` is true, or if `ps4html` + is defined. + +2021-08-13 G. Branden Robinson + + * src/preproc/html/pre-html.cpp (get_resolution): Unbrace a + single-statement `while` loop per prevailing coding style. Add + comments noting how we aren't parsing DESC files _precisely_ as + our documentation specifies. + +2021-08-13 G. Branden Robinson + + Convert font class `int` members to `bool` where appropriate. + + * src/include/font.h (font class): Demote integers to Booleans + and use Boolean literals where possible. Rename some member + variables to look like logical predicates. + - contains() + - is_special() + - has_ligature() + - tcommand -> has_tcommand + - unscaled_charwidths + - pass_filenames + - use_charnames_in_special + - is_unicode + - special (private) + * src/libs/libgroff/font.cpp (font::font): Construct object + using Boolean literal. + (font::contains): + (font::is_special): + (font::has_ligature): Convert return type to `bool`. + (font::load): + (font::load_desc): Assign to member variables using Boolean + literals. + * src/libs/libgroff/fontfile.cpp: Initialize appropriate globals + using `bool` type and Boolean literals. + * src/roff/troff/troff.h: + * src/roff/troff/input.cpp (main): + * src/roff/troff/node.cpp (troff_output_file::put_char_width): + Rename `tcommand_flag` to `device_has_tcommand` to suggest a + logical predicate, and to emphasize the formatter's concern with + what the output device can accept in the intermediate output + language. + * src/roff/troff/input.cpp: Initialize `device_has_tcommand` + global using `bool` type and Boolean literal. + +2021-08-13 G. Branden Robinson + + [me]: Clarify breadth of application of `ll` macro. + + * doc/meref.me: Document application of .ll macro only to the 3 + environments that me(7) uses, not any the user might create. + * tmac/e.tmac (@C, xl, ll): Update comments. + + Fixes . + +2021-08-13 G. Branden Robinson + + Add regression test for Savannah #58736. + + * tmac/tests/e_footnotes_work_with_columns.sh: Test it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2021-08-13 G. Branden Robinson + + * tmac/e.tmac (bc): Fix problem with multiple columns on long + pages. Space to the next page location trap, not 24 inches. + Thanks to Dave Kemper and Bjarni Ingi Gislason for help tracking + this bug down. + + Fixes . + +2021-08-13 G. Branden Robinson + + Add regression test for Savannah #55081. + + * tmac/tests/e_columns-work-on-long-pages.sh: Test it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2021-08-09 G. Branden Robinson + + * man/groff.7.man (Localization): Add section. + +2021-08-09 G. Branden Robinson + + * tmac/cs.tmac: + * tmac/de.tmac: + * tmac/fr.tmac: + * tmac/it.tmac: + * tmac/sv.tmac: Update ms package localization to use an + appropriate hyphenation mode for the `HY` register (the + mode for the pattern files, plus 2 as is traditional in ms). + +2021-08-08 G. Branden Robinson + + * tmac/e.tmac (1c): Place comment escape sequence immediately + after macro argument. (When redefining a request, one needs to + remember that request arguments are not parsed exactly as macro + arguments are.) Quiets "-w tab" warning. + +2021-08-08 G. Branden Robinson + + [me]: Fix misleading documentation claim; gremlin(1) pictures + cannot be included directly; they must be preprocessed with + grn(1). + + * doc/meref.me: + * tmac/groff_me.7.man: Replace "gremlin" with "grn". + +2021-08-08 G. Branden Robinson + + * tmac/groff_me.7.man: Document `n1` and `n2` macros. + +2021-08-08 G. Branden Robinson + + [me]: Fix PS/n1 combination diagnostic spew and apparent logic + error. + + * tmac/e.tmac (@h): Place comment escape sequence immediately + after macro argument. (When redefining a request, one needs to + remember that request arguments are not parsed exactly as macro + arguments are.) + (n2): Prefix with `do` requests using long register names. + (n2): Add macro-local register `|l` to store length of first + argument. Don't attempt to extract a substring beyond the + bounds of its source, which produces a warning diagnostic. + (&&): Define no-op macro for use as end macro in nested macro + definition. + (PS): Fix unbalanced-else diagnostic by changing `if` to `ie`. + (PS): Initialize `PS_nm_cnt` register to 0 instead of relying on + implicit definition. + (PS): Prefix with `do` definition of long macro name. + (PS): Indent call of end macro. + (PS): Add comment after escaped space. + (PS, PF): Prefix with `do` call of long macro name. + + Fixes . + +2021-08-08 G. Branden Robinson + + * src/utils/grog/grog.pl (do_line): Recognize `n1` and `n2` as + characteristic me(7) macros. + +2021-08-08 G. Branden Robinson + + * tmac/groff_me.7.man: Document GF, IE, IF, IS, and PF macros. + +2021-08-08 Dave Kemper + + * tmac/e.tmac: Rename `PE` to `PF` but remove vertical spacing. + (PE): New `PE` calls `PF` and then spaces as old `PE` did. + + Fixes . + +2021-08-06 Dave Kemper + + * doc/meref.me: Improve documentation of image-inclusion macros. + + Fixes . + +2021-08-06 Dave Kemper + + GNU pic recognizes two possible endings of a pic block: .PE or + .PF. This fact was documented in doc/pic.ms but not in the pic + man page. The minimal pic implementation provided by pic.tmac + also did not include a .PF definition. + + * src/preproc/pic/main.cpp (main): Add dummy definition of `PF` + macro. + * tmac/pic.tmac (PF): Add macro that performs indentation only. + (PE): Call PF for indentation. + + * doc/pic.ms (Interface to [gt]roff/How Scaling is Handled): + * src/preproc/pic/pic.1.man (Description, Options): Mention `PF` + in addition to `PS` and `PE`. + + Fixes . + +2021-08-05 G. Branden Robinson + + * tmac/refer-ms.tmac: + * tmac/s.tmac (fn@init, @PP): Rename strings + `fn@sup-{start,end}` to `fn@mark-{start,end}`. This makes it + more clear that the strings are brackets for the footnote + marker, and not so much to do with the note text. Further, in + nroff mode, they aren't superscripts at all, but bracket glyphs. + +2021-08-02 G. Branden Robinson + + * src/preproc/refer/refer.1.man (Examples): Add section. + + Addresses part of . + +2021-08-02 G. Branden Robinson + + * tmac/refer-ms.tmac: Use `fn@sup-{start,end}` instead of + `par@sup-{start,end}` when setting refer(1) citation labels. + This improves the appearance of the default labels on nroff + devices. Continues commit caeede07, 1 May. + +2021-08-01 G. Branden Robinson + + * tman/an-ext.tmac (EX, EE): Stop manipulating hyphenation. + It's redundant since disabling fill mode already prevents + automatic breaking, and therefore automatic hyphenation. + * tmac/groff_man.7.man.in (Description/Document structure + macros) : Update documentation. + +2021-08-01 G. Branden Robinson + + * src/utils/grog/grog.pl: Update authorship credits. I appear + to have removed or refactored all of the "device" (recte: macro + package) inference logic adapted from Ralph Corderoy's grog.sh; + see commit 3617f42048f54cc3f0adc282ee3b9e481c75ebd5, 13 June + 2014. + +2021-07-31 G. Branden Robinson + + * src/utils/grog/grog.pl: Refactor through relocation and + renaming. Move several global objects into subroutines. + - `@request` -> `&do_line` + - `@macro_ms`, `@macro_man`, `@macro_man_or_ms` -> + `&infer_man_or_ms_package` + - `@main_package` -> `&construct_command` + Rename some objects for clarity. + - `%Groff` -> `%score` + - `@filespec` -> `$input_file` + Delete unused object. + - `@standard_macro` + Add comments. + +2021-07-31 G. Branden Robinson + + * src/utils/grog/grog.pl (do_line): When matching macro/request + names, accept any non-whitespace character (Perl: \S) instead of + just a word-constituent character (Perl: \w), since roff + identifiers can contain unusual characters (refer(1) and + groff_me(7) illustrate some real-world cases). + +2021-07-31 G. Branden Robinson + + * src/utils/grog/grog.pl: Refactor macro package inference. + - Stop manually populating `Groff` hash. (It's itching for a + rename.) + - Stop calling now-dead subroutine `infer_macro_packages`. + (do_line): Always store the names of all macros called to the + `Groff` hash, incrementing it. Now it's a proper scoreboard. + Populate `inferred_main_package` from here upon encountering + characteristic (i.e., uniquely named) macros of each package. + Bug fix: drop "SP" from list of characteristic mom(7) macros; + it's shared with mm(7). + (infer_man_or_ms_package): Update comment. Return 0 (false) if + document appears to be "raw", using no full-service macro + package. + (infer_macro_packages): Delete; do_line() does this work. + +2021-07-31 G. Branden Robinson + + * src/utils/grog/grog.pl: Refactor preprocessor inference. + - Add new list, `inferred_preprocessor`. + - Drop preprocessor-related keys from `Groff` hash. + - Drop scalar `inside_tbl_table`. + (do_line): Set up hash `preprocessor_for_macro`. Detect + preprocessor macros the way the preprocessors do, explained in a + comment. Respect AT&T compatibility mode when doing so. Build + list of inferred preprocessors. This replaces the extensive and + gaseous series of `if` statements that manipulated the `Groff` + hash. + (infer_preprocessors): Completely replace. Set up a hash + `option_for_preprocessor` mapping preprocessor names to groff + options (where applicable). Append to `command` and + `preprocessor` lists as appropriate. Sort the preprocessor + options so they don't move around in the argument list depending + on the order of their macros' appearance in the input. + + * src/utils/grog/tests/smoke-test.sh: Update test cases to + expect preprocessor options to show up in sorted order. + +2021-07-31 G. Branden Robinson + + * src/utils/grog/grog.pl: Drop dead code. Delete global + hash `preprocs_tmacs`, unused since commit b0de53c9, 30 June. + +2021-07-30 G. Branden Robinson + + [grohtml]: Fix code nit. + + * src/preproc/html/pre-html.cpp (get_image_generator): + Type-qualify `keyword_len` as `const` to encourage the compiler + to compute this value (the length of a string literal) at build + time. + +2021-07-30 G. Branden Robinson + + [troff]: Slightly refactor. + + * src/roff/troff/node.cpp: Add static `image_filename_len` to + store length of cached image file name, so we don't wastefully + recompute its length every time one is re-used. + (suppress_node::tprint): Compute image file name length only + when saving a new image file name. Use saved length in later + expressions. + (min): Drop unused inline function. + +2021-07-30 G. Branden Robinson + + [troff]: Fix regression (breaking important pdfmark/pdfroff + features) caused by my commit + e876d4bfd193abb9a7d1fb6e76519349bded482a, 27 July. An empty + image file name is in fact semantically valid when writing a + bounding box; pdfmark uses such boxes to frame hyperlinks. + Avoid null pointer dereference by initializing `image_filename` + to an empty string literal. Thanks to Tadziu Hoffman and Keith + Marshall for their patient explanations. + +2021-07-29 G. Branden Robinson + + [troff]: Refactor some internal functions. + + * src/roff/troff/node.cpp: Rename two functions that have only + one caller. + - get_reg_int -> get_register + - get_reg_str -> get_string + We now have: + (get_register, get_string): Use `assert()` aggressively because + these are deeply internal and validation is imperative. Get rid + of diagnostic messages (one of which perpetuated the dubious + "number register" nomenclature) accordingly. + (fetch_register): Also rename `prev_value`, misleadingly + specific and seemingly copy-and-pasted out of a context where an + auto-increment or -decrement might have been applied. It's just + the `value`. + (suppress_node::tprint): Update call site. + +2021-07-29 G. Branden Robinson + + [troff]: Refactor `get_value` member functions. Given their + names and popular "getter/setter" paradigms from many OO + languages, the return type is misleading. Change it from `int` + to `bool` since it returns only a success/failure status and + modifies an argument (passed by reference) to deliver the + requested data. + + * src/roff/troff/reg.h (reg, variable_reg): + * src/roff/troff/div.cpp (page_offset_reg, page_length_reg) + (vertical_position_reg, high_water_mark_reg) + (distance_to_next_trap_reg, page_number_reg, no_space_mode_reg): + * src/roff/troff/env.cpp (int_env_reg, vunits_env_reg) + (hunits_env_reg, horizontal_place_reg): + * src/roff/troff/input.cpp (writable_lineno_reg): + * src/roff/troff/reg.cpp (reg, number_reg, variable_reg): Update + class and member function definitions to reflect the new type. + Update member function definitions to return appropriate Boolean + literals instead of 0 and 1. + +2021-07-28 G. Branden Robinson + + [grohtml]: Fix Savannah #60981. Refactor device description + file handling and make it more robust. Make pre-grohtml's + -F option work as documented and honor device description file + semantics documented in groff_font(5). + + * src/preproc/html/pre-html.cpp: Store partial filespecs of HTML + and PostScript device files in constant strings. + (get_resolution): Initialize `res` to zero. Only `free()` the + pointer `pathp` if `open_file()` succeeded (populating it). + Stop checking for valid `sscanf()` conversions of an integer to + store in `res`, and don't return early. Instead process the + whole DESC file; per our Texinfo manual and groff_font(5), + "Later entries in the file ... override previous values." + (get_image_generator): Add new function, paralleling + `get_resolution()`, replacing open-coded logic in `main()`. + Only the body of the `while` loop significantly differs. + Instead of using `sscanf`, process the input character by + character matching the keyword and {1,} spaces or tabs + after it. Whatever follows in `linebuf` must be the program + name. + (imageList::createPage): Add `assert()` to cause failure if an + empty image generator program gets this far, because it creates + repeated messes if it does. (Something isn't checking exit + statuses.) + (main): Condense `image_gen` collection to a function call, a + null pointer check, and a fatal diagnostic. Add a sanity check + and a fatal diagnostic if the PostScript resolution is garbage. + {It's initialized to -1 and `get_resolution()` will return 0 if + it doesn't find one.} + + Fixes . + +2021-07-28 G. Branden Robinson + + [grohtml]: Delete or rename `debug` symbols to avoid clash with + new `debug` function in libgroff. + + * src/preproc/html/pre-html.cpp: Update a comment to refer to + "debugging" mode. Rename static global from `debug` to + `debugging`. + (html_system, imageList::createPage, imageList::createImage, + print_args, char_buffer::do_html, char_buffer::do_image, + scanArguments): Update uses of static global. + + * src/preproc/html/pushback.cpp: + * src/preproc/html/pushback.h: Delete unused `debug` member + variable. + +2021-07-27 G. Branden Robinson + + * src/roff/nroff/nroff.sh: Fix straggling use of `$1`, which + might not have a clear meaning in some shells after being + shifted (what if we just shifted the last argument?). Also + `continue` after processing a (groff) option argument, as we + should make no attempt to parse it. + +2021-07-27 G. Branden Robinson + + * src/roff/troff/input.cpp (do_suppress): Recast diagnostic + messages for clarity, to communicate in terms of what the + escape sequence _is_, and to quote literals expected as input. + * src/roff/troff/node.cpp (suppress_node::tprint): Recast + diagnostic to prevent misinterpretation of image "description" + as being HTML IMG tag alt text or something like that. + Unfortunately, the new language speaks in terms of internal + implementation details ("grohtml-info"), but at least that way + it's easier for a user to decide if they care about it. + +2021-07-27 G. Branden Robinson + + [troff]: Avoid using sprintf() with user-controlled format + string. + + * src/preproc/html/pre-html.cpp (makeFileName): Add comment + noting need for implementation synchrony between this function, + which generates \O5 escape sequences, and troff's + suppress_node::tprint member function, which interprets them. + * src/roff/troff/node.cpp: Rename 2 static globals for clarity. + - `last_image_filename` -> `image_filename` + - `last_image_id` -> `subimage_counter` + (suppress_node::tprint): Set up the buffer for image file name + to be written using a constant rather than an embedded literal. + Unconditionally initialize the buffer with a string terminator, + so there is no chance of a read from uninitialized storage. + Drop unused code involving `tem`. Drop stale comments. Clarify + comment: an `image_filename` doesn't _always_ contain a format + string, only sometimes. Replace use of `sprintf` with manual + construction of a new image filename string. There are two + cases, one where a format string {presently "%d"} is present, + and one where it is not. If it is present, locate it + {`percent`}. This means a limited/bounded image ("subimage") is + being processed; increment the subimage counter. Write a new + image file name preserving the parts before and after "%d" (the + "prefix" and "suffix", and replacing only the middle, using + `sprintf` with the subimage counter and the (string literal) + format. Be mindful of string bounds and memory allocation, + issuing diagnostics or aborting as necessary. If the image file + name does _not_ contain a format string, but needs only to be + copied, do that (`strcpy`), again instead of using `sprintf`. + + Fixes . + +2021-07-26 G. Branden Robinson + + [grohtml]: Fix Savannah #60971. + + * src/preproc/html/pre-html.cpp (makeFileName): Consistently put + a dash at the end of `macroset_template` whether the image file + name stem is user-supplied or the default. Stop adding the dash + before the image number in `image_template` instead. This makes + the image file name format reliable whether the image needs to + be subdivided (eqn) or not (tbl). + + Fixes . + +2021-07-26 G. Branden Robinson + + [grohtml]: Reduce noise to standard error stream. + + * src/preproc/html/pre-html.cpp (imageList::createImage): Fix + apparent oversight: `EXE_EXT` was not being applied to the + second of three commands being run in a pipeline (did Windows + users notice?). Also issue (undocumented!) `-quiet` option to + `pnmtopng` to shut up its commentary about counting colors. + +2021-07-26 G. Branden Robinson + + [grohtml]: Stop discarding standard error output. + + * src/preproc/html/pre-html.cpp (html_system): Stop sending the + standard error stream to /dev/null; this just makes debugging + harder, and doesn't produce much more output for well-formed + input documents. Rename `save_stdout` to `saved_stdout`. + +2021-07-26 G. Branden Robinson + + [grohtml]: Fix misspelled variable. + + * src/preproc/html/pre-html.cpp: Rename `IMAGE_BOARDER_PIXELS` + to `IMAGE_BORDER_PIXELS`. + +2021-07-26 G. Branden Robinson + + [libgroff, troff]: Add debug diagnostic level. + + * src/include/error.h: Declare functions + `debug_with_file_and_line` and `debug`. + * src/libs/libgroff/error.cpp: Add `DEBUG` to enum `error_type`. + (do_error_with_file_and_line): Add case for `DEBUG` in switch. + (debug, debug_with_file_and_line): Add new functions. + + Do the same for troff since it has a private implementation of + the diagnostic functions (thanks to `output_warning()`). + + * src/roff/troff/input.cpp: Add `DEBUG` to enum `error_type`. + (do_error_with_file_and_line): Add case for `DEBUG` in switch. + (debug, debug_with_file_and_line): Add new functions. + +2021-07-26 G. Branden Robinson + + * src/utils/hpftodit/hpftodit.cpp (hp_msl_to_ucode_name) + (unicode_to_ucode_name): Hush "format nonliteral" compiler + warnings by using a preprocessor-defined string literal as an + sprintf() format string instead of a C++ variable that just + compared identically to the same thing. + +2021-07-25 G. Branden Robinson + + * src/utils/hpftodit/hpftodit.cpp (show_symset): Prevent + sprintf() from overunning a static buffer. Thanks to Bjarni + Ingi Gislason for the report. Resize buffer to be large enough + to accommodate a 64-bit unsigned int type formatted as decimal. + Also add assert() before the sprintf() to abort if the int type + is even larger than that. Use "%u" conversion instead of "%d" + since the quantity is unsigned. + (hp_msl_to_ucode_name): Similar, but for a signed int. + (unicode_to_ucode_name): Similar, but for a signed int formatted + as (unsigned) hexadecimal. + + Fixes . + +2021-07-23 G. Branden Robinson + + * src/roff/nroff/nroff.sh: Refactor, mostly by relocation. Move + locale character set inference logic so that we only run it if + we have to (`-T` option was invalid or not given and + `GROFF_TYPESETTER` was not set in the environment or invalid). + Initialize `T` variable as empty. + +2021-07-23 G. Branden Robinson + + * src/roff/nroff/nroff.sh: Use Version 7 Unix sh-compatible form + of parameter expansion; per the GNU Autoconf manual[1], "[o]ld + BSD shells, including the Ultrix sh, don't accept the colon for + any shell substitution, and complain and die." This is also the + form of such substitutions used elsewhere in the script, so they + should be mutually consistent. + + [1] https://www.gnu.org/software/autoconf/manual/autoconf-2.60/\ + html_node/Shell-Substitutions.html + +2021-07-23 G. Branden Robinson + + * src/roff/nroff/nroff.sh: Slightly refactor. Rename formerly + unused loop index variable from `i` to `arg` to leverage it in a + later diagnostic message without a separate definition. Inside + the loop, expand `arg` instead of positional parameter 1, the + meaning of which is less obvious after the parameter list is + shifted by the new `is_option_argument_pending` logic (commit + 2b955c57, 20 July). + +2021-07-23 G. Branden Robinson + + * src/roff/groff/groff.1.man (Options) <-S>: Fix error: `-S` + sets safer mode (redundantly) but is not passed to pic and troff + as was claimed. + +2021-07-21 G. Branden Robinson + + * src/roff/troff/number.cpp (parse_term): Tweak diagnostic + messages. When a left operand to a binary operator is empty, + report the operator in question (helpful for string + interpolations in complex expressions). When handling input + scaling indicators, drop word "this" from "this context", since + the parser's context might not be clear from a file name and + line number. Say "scaling indicator" instead of "scale + indicator". + (parse_expr, parse_term): Rename function parameter from + `scale_indicator` to `scaling_indicator`. + +2021-07-21 G. Branden Robinson + + * src/roff/troff/input.cpp (define_color): Tweak warning + diagnostics for clarity. Only one value is expected when + defining a color in the `gray` color space. Quote recognized + color space names when complaining of an unknown one. + +2021-07-21 G. Branden Robinson + + [nroff]: Pass a supplied `-c` option to groff. While at present + this does little more than `-P-c` already achieves, that might + not be true forever. Further, there is a distinction between + ignoring color-related requests in groff input documents and + ignoring color-related commands in device-independent output. + This distinction would make it unwise to adapt `-c` to any other + purpose in nroff in the future. + + * NEWS: Update item from commit dd725dce, 10 February 2020. + * src/roff/nroff/nroff.sh: Pass `-c` option to groff in addition + to synthesizing a `-P-c` option (for grotty) when it is seen. + * src/roff/nroff/nroff.1.man (Options): Document `-c` as an + option recognized by troff(1). + +2021-07-20 G. Branden Robinson + + [nroff]: Support space between option flags and their arguments. + + * src/roff/nroff/nroff.sh: Add new `is_option_argument_pending` + flag to add an additional state to the option parser. Set it if + an argument-requiring option is encountered with no abutting + argument. If it is set when a new argument is encountered, + absorb the argument into the groff option list and clear the + flag. Modernize script in a couple of other ways. + - Exit with status 2 upon usage errors so that this condition + is easily distinguished from a groff abort (which exits with + status 1). + - Test shell variables for non-nullity with test(1) -n + operator instead of a string comparison. + * src/roff/nroff/tests/verbose_option_works.sh: Test correct + construction of groff command using this input form. + * src/roff/nroff/nroff.1.man (Options): Add spaces between + option flags and option arguments. Sync metasyntactic variable + names with groff(1) while we're at it. + (Description): Drop sentence warning of whitespace prohibition. + (Exit status): Add new section. + + Fixes . + +2021-07-19 G. Branden Robinson + + * src/roff/troff/input.cpp (main): Emit error diagnostic if `-d` + or `-r` option is given a malformed argument. This prevents a + string or register with an empty name from being created. + + Fixes . + +2021-07-19 G. Branden Robinson + + * src/roff/nroff/nroff.sh: + * src/roff/troff/input.cpp (usage): Use "dev" as metasyntactic + variable name for -T option argument to achieve consistency with + our other documentation. + +2021-07-19 G. Branden Robinson + + [groff]: Comment out vestiges of gideal support. It would be + lovely to have, but no free (and GPL-compatible) implementation + has showed up after decades of waiting. Production of the + original was a Ph.D. thesis. Excited by de Moivre's theorem? + Take a stab at it. + + * src/roff/groff/groff.cpp (main): Comment out effect of `-J` + option. It remains recognized, but silently ignored (instead of + attempting to execute a nonexistent preprocessor). + (synopsis): Add comment reminding us to document the option if + we ever get the support. + (help): Comment out documentation of option. + +2021-07-18 G. Branden Robinson + + [[gnt]roff]: Make usage messages more accurate. + + * src/roff/groff/groff.cpp (synopsis): Drop `-h` and `-v` from + normal operation synopsis. Sort options in en_US lexicographic + order. Tighten presentation of alternate usage forms. + (help): Document longer forms of `-d` and `-r`. + * src/roff/nroff/nroff.sh: Report `$prog` instead of "nroff" + literal. Refer to `-P` option argument as "arg" instead of + "opt", for consistency with groff usage message. Use opposite + case from option letter for option argument. + * src/roff/troff/input.cpp (usage): Put brackets around options. + Sort options in en_US lexicographic order. Drop `-v` from + normal operation synopsis. Use opposite case from option letter + for option argument. Put operand name in capitals. Set valid + usage forms on one physical line each (see 89648fb4, 5 June). + Add synopsis line for alternate usage forms. + +2021-07-13 G. Branden Robinson + + [troff]: Refactor environment initialization, switching, and + copying. + + * src/roff/troff/env.cpp: Rename struct `env_list` to + `env_list_node` since it describes a node of a singly-linked + list. Remove constant `NENVIRONMENTS` and array `env_table`. + Add static symbol `default_environment_name` to replace string + literal. + (init_environments): Stop initializing `curenv` through + `env_table`. Use `default_environment_name` for that + initialization and add the default environment to + `env_dictionary`. + (environment_switch): Simplify. Shorten "dummy environment" + diagnostic message. Stop creating an integer-named + environment inside the `env_table` array, only falling through + to use the `env_dictionary` if the named environment is not a + valid integer or if the array is full. Instead use + `env_dictionary` always. Drop no longer needed `pop` + quasi-Boolean integer with extra state to suppress environment + stack underflow errors. Instead report the error if underflow + occurs, regardless of any other circumstance. + (environment_copy): Simplify. Stop searching the `env_table` + array for an environment to copy from, only falling through to + use the `env_dictionary` if the named environment is not a valid + integer or if the array is full. Instead search + `env_dictionary` always. Emit "no environment specified to copy + from" diagnostic only if the `evc` request is given no argument. + If the source environment to copy from is given but not found, + emit a new diagnostic naming the nonexistent environment. Fix + bug: stop returning early if no copying could be done; instead + fall through to the end of the function, which calls + `skip_line()` and prevents anything on the remainder of the + {invalid} control line from being interpreted. Problem dates + back to commit da3b7137, 6 March 2000 (groff 1.16). + + Fixes . + +2021-07-13 G. Branden Robinson + + * src/roff/groff/tests/evc_produces_no_output_if_invalid.sh: + Regression-test Savannah #60913. + * src/roff/groff/groff.am (groff_TESTS): Run test. + +2021-07-11 G. Branden Robinson + + Update English hyphenation patterns. + + * NEWS: Add item. + * tmac/hyphen.en: Update file using `hyph-en-us.tex` patterns + file from the TeX hyph-utf8 project. + * tmac/hyphenex.en: Remove explicit hyphenations for words that + no longer require them when using the new patterns. Add one + item scraped from an erratum comment in hyphen.en + {"dem-o-crat"}. + + The new patterns likely _will_ change the automatic hyphenation + break points of your English documents. Here is a sample of + affected words found within groff's own documentary corpus. + + OLD NEW + === === + ar‐range‐ment arrange‐ment + col‐umns columns + con‐struc‐ted con‐structed + cus‐tom‐ized cus‐tomized + def‐i‐ni‐tions de‐f‐i‐n‐i‐tions + der‐i‐va‐tions de‐riva‐tions + hy‐phen‐a‐tion hy‐phen‐ation + ma‐te‐rial ma‐te‐r‐ial + Mi‐cro‐soft Mi‐crosoft + pipe‐lines pipelines + post‐pro‐ces‐sors post‐proces‐sors + pro‐cessed processed + pro‐cesses processes + spa‐ces spaces + Wer‐ner Werner + +2021-07-10 G. Branden Robinson + + [troff]: Add unit test for `substring` request. + + * src/roff/groff/tests/substring_works.sh: Do it. + * src/roff/groff/groff.am (groff_TESTS): Run test. + +2021-07-10 G. Branden Robinson + + [tmac]: Remove compatibility mode save registers after using + them. + + * tmac/an.tmac: + * tmac/andoc.tmac: + * tmac/cp1047.tmac: + * tmac/devtag.tmac: + * tmac/ec.tmac: + * tmac/fallbacks.tmac: + * tmac/latin1.tmac: + * tmac/latin2.tmac: + * tmac/latin5.tmac: + * tmac/latin9.tmac: + * tmac/papersize.tmac: + * tmac/pdfpic.tmac: + * tmac/psold.tmac: + * tmac/pspic.tmac: + * tmac/trace.tmac: + * tmac/unicode.tmac: Do it. + + * doc/groff.texi (Implementation Differences): + * man/groff_diff.7.man (Implementation Differences): Illustrate + doing so in relevant examples. + +2021-07-09 G. Branden Robinson + + * tmac/troffrc: Load the English localization file `en.tmac` by + default, instead of dealing with hyphenation language and + patterns directly in this file. (This also replaces a + localization-determination mechanism that was never part of a + groff release.) + + * src/roff/groff/tests/initialization_is_quiet.sh: + * src/roff/groff/tests/localization_works.sh: Rewrite to use + explicit macro file loading localization mechanism. + +2021-07-06 G. Branden Robinson + + Move core man(7) implementation to an.tmac. + + * tmac/an.tmac: Delete andoc-sourcing wrapper. + + * tmac/an-old.tmac: Rename... + * tmac/an.tmac: ...to this. + + * tmac/tests/an-old_AT-and-UC-footer-saved-and-restored.sh: + * tmac/tests/an-old_CS-register-off.sh: + * tmac/tests/an-old_CS-register-on.sh: + * tmac/tests/an-old_CS-register-unspecified.sh: + * tmac/tests/an-old_CT-register-off.sh: + * tmac/tests/an-old_CT-register-on.sh: + * tmac/tests/an-old_CT-register-unspecified.sh: + * tmac/tests/an-old_FT-bad-value-should-not-trash-titles.sh: + * tmac/tests/an-old_LL-init-sanely.sh: + * tmac/tests/an-old_TH-repairs-ad-damage.sh: + * tmac/tests/an-old_TH-repairs-hy-damage.sh: + * tmac/tests/an-old_TS-do-not-keep-tables-when-cR-set.sh: + * tmac/tests/an-old_X-register-works.sh: + * tmac/tests/an-old_avoid-two-font-denial-of-service.sh: + * tmac/tests/an-old_no-break-after-short-paragraph-tags.sh: + * tmac/tests/an-old_page-footers-present.sh: + * tmac/tests/an-old_page-header-has-current-data.sh: + * tmac/tests/an-old_title-abbreviation-works.sh: Rename... + + * tmac/tests/an_AT-and-UC-footer-saved-and-restored.sh: + * tmac/tests/an_CS-register-off.sh: + * tmac/tests/an_CS-register-on.sh: + * tmac/tests/an_CS-register-unspecified.sh: + * tmac/tests/an_CT-register-off.sh: + * tmac/tests/an_CT-register-on.sh: + * tmac/tests/an_CT-register-unspecified.sh: + * tmac/tests/an_FT-bad-value-should-not-trash-titles.sh: + * tmac/tests/an_LL-init-sanely.sh: + * tmac/tests/an_TH-repairs-ad-damage.sh: + * tmac/tests/an_TH-repairs-hy-damage.sh: + * tmac/tests/an_TS-do-not-keep-tables-when-cR-set.sh: + * tmac/tests/an_X-register-works.sh: + * tmac/tests/an_avoid-two-font-denial-of-service.sh: + * tmac/tests/an_no-break-after-short-paragraph-tags.sh: + * tmac/tests/an_page-footers-present.sh: + * tmac/tests/an_page-header-has-current-data.sh: + * tmac/tests/an_title-abbreviation-works.sh: ...to these. + + * tmac/tmac.am (TMACNORMALFILES): Remove an-old.tmac. + (tmac_TESTS): Reflect renames of test files above. + (tmac/stamp-wrap): Macro-source `an.tmac` in the man wrapper. + + * tmac/andoc.tmac: Refer to (and macro-source) an.tmac. + * tmac/man.tmac: Macro-source `an.tmac`, not `andoc.tmac`. + * tmac/tests/andoc_flush-between-packages.sh: Call groff with + `-mandoc` option instead of `-man`. Henceforth, if you want the + andoc wrapper, you have to ask for it. + + * tmac/an.tmac: Drop "-old" nomenclature. + + * PROBLEMS: + * doc/groff.texi (man): + * tmac/man.local: Update documentation appropriately. + + * NEWS: Add item. + + * man/groff_tmac.5.man (Macro packages/man pages): + * src/roff/groff/groff.1.man (Usage/Macro packages): Update + discussion of an, doc, and andoc. + * tmac/groff_man.7.man.in (Files): Update descriptions of + an.tmac, andoc.tmac, man.tmac, and mandoc.tmac. + + Fixes . + +2021-07-05 G. Branden Robinson + + [troff]: Slightly refactor. Make the source code slightly more + accessible by using a `bool` type for a function's default + parameter used as a Boolean, and comment it at call sites where + the default is overridden. + + * src/roff/troff/token.h (get_name, get_long_name): Change type + of parameter from `int` to `bool` and default from 0 to `false`. + * src/roff/troff/input.cpp (do_get_long_name) + (empty_name_warning, get_name, get_long_name): Change type of + parameter from `int` to `bool` in declarations and definitions. + * src/roff/troff/column.cpp (column_justify): + * src/roff/troff/div.cpp (diversion_trap): + * src/roff/troff/env.cpp (environment_switch, environment_copy) + (do_input_trap, set_hyphenation_language) + (do_hyphenation_patterns_file): + * src/roff/troff/input.cpp (define_color, composite_request) + (do_define_string, do_define_macro, rename_macro, alias_macro) + (chop_macro, do_string_case_transform, substring_request) + (length_request, asciify_macro, unformat_macro, do_register) + (device_macro_request, do_if_request, do_source) + (ps_bbox_request, do_open, close_request, do_write_request) + (write_macro_request, define_class, copy_file, vjustify) + (transparent_file, do_macro_source): + * src/roff/troff/node.cpp (font_translate, font_position, style) + (get_fontno): + * src/roff/troff/reg.cpp (define_number_reg, inline_define_reg) + (alter_format, alias_reg, rename_reg): Update call sites. Add + (comment indicating meaning of parameter. + + Do similarly for token::delimiter() member function. + + * src/roff/troff/token.h (token::delimiter): Change type of + parameter from `int` to `bool`, name from `warn` to `err` (to + match definition and behavior in input.cpp) and default from 0 + to `false`. + * src/roff/troff/input.cpp (token::delimiter): Change type of + parameter from `int` to `bool` in definition. + * src/roff/troff/input.cpp (do_expr_test, get_delim_number) + (get_line_arg, read_size, do_register, read_draw_node): + * src/roff/troff/reg.cpp (inline_define_reg): Update call sites. + Add comment indicating meaning of parameter. + +2021-07-05 G. Branden Robinson + + * tmac/an-old.tmac (an-footer): Remove string + `an-outer-footer-text` after we're done with it. + +2021-07-05 G. Branden Robinson + + Remove the stripper script and its vestiges. + + * contrib/hdtbl/hdmisc.tmac: + * contrib/hdtbl/hdtbl.tmac: + * contrib/mom/om.tmac: + * tmac/doc.tmac: + * tmac/e.tmac: + * tmac/mdoc/doc-common: + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: + * tmac/mdoc/doc-syms: Remove `%beginstrip` comment. + + * tmac/strip.sed: Delete. + + * tmac/tmac.am (EXTRA_DIST): Stop shipping `strip.sed`. + + Fixes . + +2021-07-04 G. Branden Robinson + + Skip the stripper, part 3/3 (mdoc). + + * tmac/doc-old.tmac-u: + * tmac/doc.tmac-u: + * tmac/mdoc/doc-common-u: + * tmac/mdoc/doc-ditroff-u: + * tmac/mdoc/doc-nroff-u: + * tmac/mdoc/doc-syms-u: Rename these... + + * tmac/doc-old.tmac: + * tmac/doc.tmac: + * tmac/mdoc/doc-common: + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: + * tmac/mdoc/doc-syms: ...to these. + + * tmac/tmac.am (TMACNORMALFILES): Add `doc-old.tmac` and + `doc.tmac`. + (TMACUNSTRIPFILES, TMACSTRIPFILES): Delete variables. + (dist_tmac_DATA): Drop `$(TMACUNSTRIPFILES)`. + (nodist_tmac_DATA): Drop `$(TMACSTRIPFILES)`. + (TMACMDOCSTRIPFILES): Rename... + (TMACMDOCFILES): ...to this. + (nodist_mdoc_DATA, MOSTLYCLEANFILES): Reflect above rename. + (nodist_mdoc_DATA): Rename... + (dist_mdoc_DATA): ...to this. + (TMACMDOCUNSTRIPFILES): Delete variable. + (EXTRA_DIST): Drop `$(TMACMDOCUNSTRIPFILES)`. + ($(TMACSTRIPFILES), $(TMACMDOCSTRIPFILES)): Drop targets. + + The portions above are based on a patch by Ingo Schwarze. + + * tmac/doc.tmac: + * tmac/mdoc/doc-common: + * tmac/mdoc/doc-ditroff: + * tmac/mdoc/doc-nroff: + * tmac/mdoc/doc-syms: Bracket macro definitions tightly with + `eo` and `ec` requests since they were written under this + assumption. The files in general were also drafted under the + assumption that they'd be stripped, so `eo` was in effect for + broad swaths of the file including portions outside of any macro + definition where comments were used. But comments are expressed + using the escape character! So we got warnings about an + undefined '\"' macro, and that was just the beginning of a + wrecking ball of trouble that smashed through the + implementation. Some--but not all--string definitions (and + appendments) needed to be bracketed with `eo` and `ec` as well, + to delay interpolation of embedded string names that are not + defined until macros interpolate them later. I did what + appeared necessary to pass our tests and keep -Tutf8 and -Tps + renderings of tmac/groff_mdoc.7 from changing from their + strip-influenced output. Subtle bugs might linger, but some + won't be the fault of the unstripping process. (For instance, + try provoking a usage message on the `Hf` macro.) + +2021-07-03 G. Branden Robinson + + [man pages]: Remove compatibility save register. + + * **/*.man*: Remove page-local compatibility save register after + using it. + +2021-07-03 G. Branden Robinson + + [tmac]: Simplify `mso` requests. + + * tmac/X.tmac: + * tmac/Xps.tmac: + * tmac/dvi.tmac: + * tmac/html.tmac: + * tmac/lbp.tmac: + * tmac/lj4.tmac: + * tmac/ps.tmac: + * tmac/tty-char.tmac: + * tmac/tty.tmac: + * tmac/www.tmac.in: Move `mso` requests to be inside regions + where compatibility mode is turned off. I believe they were + placed where they were because things didn't work when the + compatibility mode register being saved was .C, rather than the + .cp register introduced in commit 6a37bb5f, 17 April 2020. Now + the logic is less mysterious. Also, remove the register used to + save compatibility mode after we're done with it, to reduce name + space clutter. + +2021-07-03 G. Branden Robinson + + * tmac/it.tmac: Drop sourcing of `latin1.tmac` and set up of + hyphenation codes; since the `hyphen.it` file is pure ASCII, we + don't need to expect Latin-1-encoded code points in it. + +2021-07-03 G. Branden Robinson + + [tmac]: Make localization files work in compatibility mode. + + * tmac/cs.tmac: + * tmac/de.tmac: + * tmac/en.tmac: + * tmac/fr.tmac: + * tmac/it.tmac: + * tmac/ja.tmac: + * tmac/sv.tmac: + * tmac/zh.tmac: Save and restore compatibility mode. + + * tmac/den.tmac: Invoke requests with `do`. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2021-07-03 G. Branden Robinson + + Add regression test for Savannah #60874. + + * src/roff/groff/tests/initialization_is_quiet.sh: Test it. + * src/roff/groff/groff.am (groff_TESTS): Run test. + +2021-07-02 G. Branden Robinson + + Integrate Italian localization. + + * NEWS: Add item. Update an existing list of localization macro + files. + * doc/groff.texi (Manipulating Hyphenation): Update table of + hyphenation pattern left and right minimums and list of + available localization files to include Italian. + * man/groff_tmac.5.man: Update list of available localization + files to include Italian. + * src/roff/groff/tests/localization_works.sh: Test it. + * tmac/tmac.am (TMACNORMALFILES): Add `it.tmac` and `hyphen.it`. + + Fixes . + +2021-07-02 G. Branden Robinson + + [tmac]: Flesh out Italian localization. + + * tmac/hyphen.it: Add hyphenation patterns from TeX hyph-utf8 + project. + * tmac/it.tmac: + - Revise copyright date to just this year (it had been copied + from fr.tmac). + - Use grave accents instead of acute ones to indicate stress + on word-final vowels. Per the University of Wikipedia and a + sampling of apparently well-typeset Italian language + documents online, this appears to be correct. Yell at me if + I'm wrong. + - Source latin1.tmac instead of latin9.tmac; Italian doesn't + require any letter code points from Latin-9, unlike the + French file upon which this one was based, and Latin-1 is + less of a pain to work with. + - Set the hyphenation mode to 1 instead of 4 for congruence + with the requirements of the hyphenation patterns. + - Set up hyphenation codes. This (and sourcing latin1.tmac) + might not be necessary as the hyphenation pattern file, of a + more recent vintage than the others we're using, is pure + ASCII. However I don't understand these issues perfectly so + I am making the conservative choice. Again per the + University of Wikipedia, Italian requires only acute and + grave accents, in contrast to the rich French diacritical + bouillabaisse. + - Set the hyphenation language and load the pattern file. + - Add comments in parallel with other localization files and + to supply text editors with hints. + +2021-07-02 Edmond Orignac + + * tmac/it.tmac: Add Italian localization. + +2021-07-01 G. Branden Robinson + + Skip the stripper, part 1/3 ("me"). + + * tmac/e.tmac-u: Rename to... + * tmac/e.tmac: ...this. + + * tmac/tmac.am (TMACNORMALFILES): Add tmac/e.tmac. + (TMACUNSTRIPFILES): Remove tmac/e.tmac-u. + (TMACSTRIPFILES): Remove tmac/e.tmac. + + Fixes one third of . + +2021-07-01 G. Branden Robinson + + * src/utils/grog/grog.pl: Simplify parsing. Dave Kemper pointed + out that preprocessors like pic(1) use pretty unsophisticated + *roff parsing to determine where to perform their textual + replacements. My enhancements to support input line + continuation and cope with brace escapes were thus + overengineered. Remove them. + - Drop scalars `is_continued_line` and `logical_line`. + (do_line): Stop performing logical line concatenation and + detecting input line continuation. Perform operations on + `line` instead of `logical_line`. Stop removing brace + escapes. + * src/utils/grog/grog.1.man (Limitations): Update discussion. + + Fixes . Thanks, Dave! + +2021-06-30 G. Branden Robinson + + * src/roff/troff/reg.cpp (lookup_number_reg, alias_reg): In + diagnostic messages, say simply "register" instead of "number + register" (there is no other kind). + +2021-06-30 G. Branden Robinson + + [grog]: Refactor input parsing. + + * src/utils/grog/grog.pl: + - Add scalar `use_compatibility_mode` (see below). + - Add list `request` to store the names of all requests + recognized by groff so that they aren't confused with macro + names. + - Add scalars `have_seen_first_macro_call` (replaces + `before_first_command`, but at global scope), + `is_continued_line` and `logical_line`. The latter two + enable us to handle *roff input line continuation correctly. + (process_arguments): Set `use_compatibility_mode` if `-C` + option specified. + (process_input): Refactor to greatly simplify, to not attempt + to read the first line of an input file as a special case, and + to avoid sending `do_line` an undefined argument (when EOF is + reached). + (do_first_line): Delete. + (do_line): Rewrite the early stages of input parsing. + - Concatenate continued input lines, setting + `is_continued_line` and returning early as each one is seen, + storing the accumulating input in `logical_line`. + - Check the input line for the form of comment deposited by + Perl's Pod::Man, which uses a highly accented dialect of + man(7); if it's present, inflate `man_score` to compensate + for the page-private `IX` macro it defines but which + duplicates the name and function of a 4.2BSD-era ms(7) + extension that would otherwise deceive our scoring + mechanism, because Pod::Man produces `IX` calls to + metastatic excess. (An alternative to this kludge is + documented in comments: if a "standard" macro is redefined, + we could delete it from the relevant lists and hashes.) + - Strip *roff comments from input. + - Normalize control lines; convert the no-break control + character to the regular one and remove unnecessary + white space. + - Remove brace escapes. + - Recognize two-character macro calls when not followed by + white space in compatibility mode. + - Drop logic that erroneously attempted to infer soelim(1) use + from macro calls and request invocations. The grog(1) and + soelim(1) man pages now both explain why such an effort was + misguided. + - Recognize macro definitions created by .am and .am1 requests + {not just .de and .de1}. + - Ignore all other *roff requests. + - What remains must be a ("standard") macro call, so set + `have_seen_first_macro_call`. + + * src/utils/grog/grog.1.man (Limitations): Document a further + restriction: don't change the escape character, either. + + * src/utils/grog/tests/smoke-test.sh: Comment out pic-detection + test on soelim(1). The pic macro calls are guarded by roff + control structures and only worked previously by accident + because grog did not recognize *roff input line continuation, + now it does and the illusion is dispelled. (A reliable way to + fool grog before and after my refactoring is now documented in + its man page.) + + Fixes . + +2021-06-30 G. Branden Robinson + + Add regression test for Savannah #59622. + + * src/utils/grog/tests/recognize-perl-pod.sh: Test it. + * src/utils/grog/grog.am (grog_TESTS): Run test. + +2021-06-29 G. Branden Robinson + + * src/utils/grog/grog.1.man (Limitations): Document further + restrictions (no changing of control characters, control + structures not interpreted). + +2021-06-29 G. Branden Robinson + + [grog]: Refactor command-line argument handling. + + * src/utils/grog/grog.pl: + - Drop scalars `groff_opts`, `device`, and `with_warnings`. + - Move scalar `pdf_with_ligatures`... + (process_arguments): ...here. Recognize all groff options + that take an optionally whitespace-separated option argument + and apply the existing "delayed option" handling to them. + Push any groff option except `-m` as-is onto the constructed + groff command's argument list (`-m` handling is unchanged). + Match long option names exactly, not sloppily. Stop + recognizing `--warnings` option. Emit error diagnostic if + unrecognized long option encountered. + (infer_device): Delete subroutine and its top-level call site. + (help): Undocument `--warnings`. + + * src/utils/grog/grog.1.man: + (Synopsis): Use font style macros instead of .OP. Undocument + `--warnings`. + (Options): Note that the groff arguments produced by the grog + `--ligatures` option are supported only by the `pdf` device. + Undocument `--warnings`. Undocument groff-incompatible + restriction on whitespace before option arguments; grog is + compatible now. Simplify discussion in light of simplified + grog logic. + (Details): Undocument scenario where grog infers multiple + main/major/full-service macro packages; this no longer + happens. + (Examples): Update to no longer illustrate inclusion of `-T + ps` option; this no longer happens by default. + + * NEWS: Document removal of grog's `--warnings` option. + + Fixes ; groff options are + no longer "mangled". + +2021-06-29 G. Branden Robinson + + Add regression test for Savannah #57873. + + * src/utils/grog/tests/preserve-groff-options.sh: Test it. + * src/utils/grog/grog.am (grog_TESTS): Run test. + +2021-06-28 G. Branden Robinson + + [grog]: Refactor device (`-T` option) handling. + + * src/utils/grog/grog.pl: Redeclare `device` as a scalar instead + of a list. + (process_arguments): Generalize handling of `-T` and `-m` + options to permit optional whitespace. Rename scalar `was_T` to + `delayed_option`. + (infer_device): Stop unconditionally adding a `-T ps` argument + to the generated groff command. Remove logic that validates any + given `-T` option argument; instead, let groff fail if a bad one + is supplied (its own diagnostics in this scenario were improved + in commit 5a721a30, 27 May). This makes grog agnostic about any + differently configured default device in groff itself, and about + the GROFF_TYPESETTER environment variable. + + Fixes by getting out of + the way. + + * src/utils/grog/tests/PF-does-not-start-pic-region.sh: + * src/utils/grog/tests/smoke-test.sh: Update expected output. + +2021-06-28 G. Branden Robinson + + * src/utils/grog/grog.am (grog): Drop sed replacement of unused + configuration variables @g@, @BINDIR@, @libdir@, and @EGREP@. + * src/utils/grog/grog.pl (process_arguments, construct_command): + Tweak warning diagnostics to use a style where an empty argument + will be easy to spot. + (do_first_line): Stop emitting pseudo-diagnostic (to standard + output!) if we see a "groff options line" [it's not] of + incorrect form. The preprocessor encoding hint convention of + concern here is particular to man pages, disregarded by at least + one major implementation thereof (man-db man), and not used by + other types of roff documents; at this point, we don't yet know + if the document we're processing is a man page. + (construct_command): Correct comment and related logic error. + Clear the inferred main macro package if _any_ `-m` argument + matching any main macro package is given. Warn only if what is + specified doesn't match the inference. + +2021-06-28 G. Branden Robinson + + [grog]: Heavily refactor. + + * src/utils/grog/grog.pl: + - Drop import of unused module `Data::Dumper`. + - Drop unused scalars `Sp` and `correct_tmac`. + - Simplify determination of version number. Drop hash `at_at` + which only stored one key, `GROFF_VERSION`. Initialize + scalar `groff_version` to "DEVELOPMENT". Rename scalar + `before_make` to `in_source_tree` and initialize to zero. + Update `groff_version` with Automake-determined version + variable if it is defined (i.e., grog is not running outside + of, or in an unbuilt, groff source or binary distribution). + - Drop unused `Mparams` list. Replace it with new list + `requested_package`, which stores the arguments to any grog + `-m` options specified by the user. + - Rename many objects so that I, and others, can better + comprehend their purpose, and for consistent letter casing. + . @Command -> @command + . @devices -> @device + . $Prog -> $program_name + . %macros -> %user_macro + . $have_any_valid_args -> $have_any_valid_arguments + . &handle_args -> &process_arguments + . &handle_whole_files -> &process_input + . @preprograms -> @preprocessor + . &make_groff_device -> &infer_device + . &make_groff_preproc -> &infer_preprocessors + . &make_groff_tmac_others -> &infer_macro_packages + . &make_groff_tmac_man_ms -> &infer_man_or_ms_package + . &make_groff_line_rest -> &construct_command + - Drop many unused keys in `Groff` hash. + - Add new lists, `macro_ms`, `macro_man`, and + `macro_man_or_ms` to support new scoring technique to + disambiguate input documents between these two packages. + - Append the foregoing 3 lists to new list `standard_macro`, + and add these as keys to the `Groff` hash. + - Add new list `main_package` to keep track of full-service + package names. + - Add new scalars `man_score`, `ms_score`, and + `inside_tbl_table` to aid disambiguation of .TH macro calls + and the many macro names shared between man(7) and ms(7). + (process_arguments): Strip '-m' off of argument before storing + the remainder in `@requested_package`. + (do_line): Detect .TH macro call even if white space occurs + between the control character and the macro name. + (do_line): Inflate `$man_score` by 100 if .TH is the first + macro call seen in a document. + (do_line): Fix bug; clear `$before_first_command` in correct + scope--after any macro call, not just if we saw a .TH as the + first macro call. + (do_line): Set `$inside_tbl_table` when we see a .TS call. + (do_line): Clear `$inside_tbl_table` when we see a .TE call. + Also increment `$Groff{'tbl')' again, increasing the "score" + of tbl(1) usage evidence. + (do_line): Drop a lot of code that manually increments %Groff + keys corresponding to man and ms macros. This is now done + differently and elsewhere. + (do_line): Drop "P" from list of characteristic mm(7) macros. + (do_line): Simplify matching of mom(7) macros (match $command, + not $line). Extend list of characteristic mom(7) macros. + (do_line): Increment $Groff{$key} if $key is in + @standard_macro. + (infer_man_or_ms_package): Rewrite. Compute a score for each + package by counting occurrences of their characteristic + macros. If both have a score of zero, assume that the input + is a raw roff document. If the scores are equal + {doc/webpage.ms, startlingly, comes within 1 point of a tied + score}, infer ms(7) if 'TH' was never called, and if it was, + issue a diagnostic advising user to supply a disambiguating + `-m` option. Otherwise, the scores are unequal: infer the + package of the winner. Set scalar `inferred_main_package` + instead of pushing `-m` options onto `@m`. + (infer_macro_packages): Set scalar `inferred_main_package` + instead of pushing `-m` options onto `@m`. Explicitly return + 0 if we fall off the end of the function. + (construct_command): Rewrite handling of -m options. Add new + list `msupp` to store supplementary (non-main) macro package + arguments. If a full-service package was explicitly + requested, it had better not clash with what we inferred. If + it does, explicitly unset `inferred_main_package` so that the + -m arguments are placed in the same order that the user gave + them; caveat dictator. If `--run` option was given, just + print the command; don't preface it with __FILE__ and __LINE__ + noise. + - Remove comments documenting shared variables used by + subroutines. These are far from useless but too tedious to + keep up to date while the code is in flux. + - Note several places for further code review or refactoring + with "XXX" comments. + - Add Vim modeline. + + grog now passes all its tests and correctly infers arguments for + all in-tree groff documents (except for a known, and already + documented in grog(1), false positive detection of soelim in + soelim(1)). This refactor also obviates or resolves several + outstanding Savannah tickets. + + Fixes by obviating it; + grog no longer cares about file name extensions on man pages (or + any other input). + + Fixes ; same. The quality + of diagnostic messages has been improved as well. + + Fixes ; same. + + Fixes . The attached + patch was a less aggressive refactor of &do_line and %Groff. + Its author made the following claim for it: "With this patch, + all 'man', 'me', 'mom, and 'ms' files in the repository are + correctly identified. The only example of a 'mm'-file is + "letter.mm", which is not recognized correctly." As noted + above, the present refactor achieves correct recognition of all + of the files, including letter.mm. + +2021-06-28 G. Branden Robinson + + * src/utils/grog/tests/smoke-test.sh: Perform whole-line + matches. Apply DRY principle to expected output. In + anticipation of pending changes to grog.pl, uncomment and add + tests for several in-tree documents. + doc/meref.me + contrib/mom/examples/copyright-chapter.mom + contrib/mom/examples/copyright-default.mom + contrib/mom/examples/letter.mom + contrib/mom/examples/mom-pdf.mom + contrib/mom/examples/mon_premier_doc.mom + contrib/mom/examples/sample_docs.mom + contrib/mom/examples/slide-demo.mom + contrib/mom/examples/typesetting.mom + doc/webpage.ms + +2021-06-27 G. Branden Robinson + + [grog]: Refactor. Discard filename extension-based inference. + + * src/utils/grog/grog.pl (do_line): Stop saving the control + character in the matched scalar `command` (the request or macro + name). We don't need it, and it simplifies much later matching. + (handle_file_ext): Delete. + (top level): Drop call site. + + * src/utils/grog/grog.pl: Rename `tmac_ext` scalar to + `inferred_main_package`. + +2021-06-27 G. Branden Robinson + + * src/utils/grog/grog.pl (handle_args): Complain less noisily + and more comprehensibly when given unrecognized groff options. + +2021-06-27 G. Branden Robinson + + [grog]: Handle "--" argument as documented. + + * src/utils/grog/grog.pl (handle_args): Rename scalar + `double_minus` to `no_more_options` so it actually communicates + something. Drop openability check of operand encountered after + "--"; since it's on the operand list, it will be checked later + {in `handle_whole_files`}. Stop pushing "--" itself onto the + `filespec` list. + + Fixes . + +2021-06-27 G. Branden Robinson + + [grog]: Revise operand handling, diagnostics, and exit status. + + * src/utils/grog/grog.pl: Track more state so that we can + process the argument list more intelligently and exit with a + meaningful status. Add `had_inference_problem`, + `had_processing_problem`, and `have_any_valid_args` Boolean + scalars. + (fail): Add diagnostic subroutine for serious problems; sets + `had_processing_problem`. + (handle_args, handle_file_ext): Stop complaining here about + unopenable file operands. + (handle_whole_files): Complain only here, with `fail` if a file + operand cannot be opened. + (make_groff_line_rest): Don't exit immediately if there is a + macro package inference clash, because there might be more + operands to process. Instead, set `had_inference_problem`. + Stop exiting from this subroutine. + (top level): Only call the inference subroutines if we had a + valid operand to work with (including an implicit read from + stdin). Exit with a status corresponding to the Booleans + declared above. + + * src/utils/grog/grog.1.man (Exit status): Add section; describe + semantics of exit status values. + + Fixes . + +2021-06-27 G. Branden Robinson + + [grog]: Revise diagnostic messages. + + * src/utils/grog/grog.1.man (err): Rename from this... + (warn): ...to this. Prefix diagnostic with command name and + diagnostic severity level. The subroutine didn't change the + exit status and was not used to report serious trouble, so + "warning" seems appropriate. + (make_groff_tmac_man_ms): Update call sites. Modify diagnostic + wording to stop calling macros "requests". + +2021-06-27 G. Branden Robinson + + * src/utils/grog/grog.1.man (Limitations): Add subsection + covering the problem grog has with soelim inference. Undocument + groff's -s option as one that can be inferred, because at + present it cannot be. + + Prompted by Savannah #60421. + +2021-06-26 Dave Kemper + + [grog]: Fix erroneous detection of pic(1) usage. + + Fixes . + +2021-06-26 G. Branden Robinson + + * src/utils/grog/tests/PF-does-not-start-pic-region.sh: + Regression-test Savannah #60772. + * src/utils/grog/grog.am (grog_TESTS): Run test. + +2021-06-26 G. Branden Robinson + + [grog]: Add smoke test. + + * src/utils/grog/tests/smoke-test.sh: Add test. + * src/utils/grog/grog.am (grog_TESTS): Run it. + (TESTS): Add `grog_TESTS`. + (EXTRA_DIST): Ship test. + +2021-06-26 G. Branden Robinson + + [grog]: Relocate in source tree. + + * src/roff/grog: Move from here... + * src/utils/grog: ...to here. + + * MANIFEST: + * Makefile.am: + * src/utils/grog/grog.am: Reflect move. + + Fixes . + +2021-06-25 G. Branden Robinson + + * doc/groff.texi (Assigning Formats): Revise discussion. + Clarify that a format never causes truncation of an interpolated + magnitude. Note that non-Arabic number formats cannot be used + as operands to arithmetic expressions. Add example of how to + work around this. + +2021-06-25 G. Branden Robinson + + [troff]: Clarify diagnostics. + + * src/roff/troff/reg.cpp (reg::set_increment): Update diagnostic + to unabbreviate "auto". + (reg::alter_format): Update diagnostic to say "assign" instead + of "alter", since the documentation consistently uses the former + term. + +2021-06-25 G. Branden Robinson + + [troff]: Slightly refactor. Make the source code slightly more + accessible by using a `bool` type for a member function's + default parameter used as a Boolean, and comment it at call + sites where the default is overridden. + + * src/roff/troff/token.h (token::get_char): Change type of + parameter from `int` to `bool` and default from 0 to `false`. + * src/roff/troff/input.cpp (token::get_char): Update definition. + * src/roff/troff/env.cpp (hyphen_word): + * src/roff/troff/node.cpp (remove_font_special_character): + * src/roff/troff/input.cpp (do_overstrike, do_bracket, next) + (do_define_character, remove_character, get_line_arg) + (encode_char, do_if_request, do_translate, char_flags) + (hyphenation_code, define_class): Update call sites. Add + comment indicating meaning of parameter. + +2021-06-25 G. Branden Robinson + + * tmac/an-old.tmac (TH): When outputting HTML, write the + possibly case-transformed (but not yet abbreviated) page title + as the `title` element instead of the unaltered first argument + to `TH`. + +2021-06-25 G. Branden Robinson + + * tmac/an-old.tmac (an-abbreviate-title): Define with `de`, not + `de1`, since it is not intended for call by traps or users. + +2021-06-20 G. Branden Robinson + + * doc/groff.texi (Tab Stops): Fix erroneous claim; tab stops are + not set "every half inch across the page". This is only true in + "line tabs mode", which is not enabled by default. The default + behavior, to keep compatibility with AT&T troff, measures tab + stops relative to the current position on the input line. + +2021-06-19 G. Branden Robinson + + * tmac/mdoc/doc-nroff-u: Set the usekeeps register used by tbl + to the logical complement of the cR (continuous rendering) + register. This prevents blank lines from creeping into tables + in that mode. + +2021-06-19 G. Branden Robinson + + * tmac/an-old.tmac (an-blank-line-trap, an-leading-space-trap): + We say in a comment, "Macros ... that are called by traps of any + kind must be defined with `de1` because they might be called + from a context where compatibility mode is enabled." So do it. + +2021-06-19 G. Branden Robinson + + * tmac/an-old.tmac (an-header): Lightly refactor; tighten. + +2021-06-19 G. Branden Robinson + + * tmac/an-old.tmac (an-write-paragraph-tag): Lightly refactor + for clarity and to reduce code duplicated in both branches of an + `ie`/`el` structure. + +2021-06-19 G. Branden Robinson + + * tmac/an-old.tmac: Rename `an-HF-remap-I-style` register to + `an-remap-I-style-in-headings` for greater clarity. + +2021-06-19 G. Branden Robinson + + * tmac/mdoc/doc-common-u (doc-header, doc-end-macro): Partially + revert bf4b3dde (from 20 May); per Ingo Schwarze, continuous + rendering in mdoc(7) documents has always used only one vee + between headers, footers, and man page body text. + +2021-06-19 G. Branden Robinson + + * tmac/en.tmac: Stop using `do` request; it's unnecessary since + the file is already loaded with compatibility mode off. + +2021-06-18 G. Branden Robinson + + [ms]: Fix doc omission; .ID can take an argument. + + * doc/groff.texi (ms Document Control Settings) : + Characterize register setting as a _default_. + (ms Displays and Keeps): Add optional variable "indent" argument + to syntax summary of ".DS I" and ".ID". Note that the given + indentation is used if present, and \n[DI] otherwise. + * doc/ms.ms (Displays and keeps): Add optional variable "indent" + argument to syntax summary of ".ID". Switch fonts more + carefully and apply italic corrections. + * tmac/groff_ms.7.man (Displays and keeps): Sync with doc/ms.ms. + +2021-06-17 G. Branden Robinson + + * tmac/s.tmac: Properly situate devtag flag-related register + names in the package name space. Rename `need_eo_h` to + `s@devtag-needs-end-of-heading'. Rename `need_eo_tl` to + `s@devtag-needs-end-of-title`. + ((initialization), par@reset, @SH, par@finish, @NH): Do it. + (par@reset): Test their values more idiomatically. + + Fixes last third of . + +2021-06-17 G. Branden Robinson + + * tmac/e.tmac-u (@h): Migrate SCCS revision 2.37 to be idiomatic + for groff (and not throw warnings of type 'mac'). + +2021-06-17 G. Branden Robinson + + * doc/doc.am: Improve diagnostics during documentation + generation; none should occur normally, but when they do, seeing + troff complain about "" is disheartening. + (DOC_GROFF_ONLY): Add -b option so we get backtraces (also kill + off trailing whitespace). + (DOC_GROFF): + (doc/pic.html): + (doc/webpage.html): Add sed expression to inject `lf` request + into the stream to identify the file being processed. + +2021-06-17 G. Branden Robinson + + * doc/me-revisions: Supplement history with subsequent BSD work + from versions 2.29 (1988-04-22) to 8.1 (1993-06-05). + +2021-06-17 G. Branden Robinson + + * doc/me-revisions: Add 'me' macro package revision log, scraped + from . + * doc/doc.am (DOCFILES): Ship it. + +2021-06-17 G. Branden Robinson + + * tmac/e.tmac-u: Rename registers for clarity. Unlike other + macro packages supplied by groff, "me" mostly remains within the + AT&T 2-character name space, accessing extended names + selectively through `do` and `de1` requests. The package + therefore has no characteristic name prefix. + need_eo_h -> devtag-needs-end-of-heading + need_eo_tl -> devtag-needs-end-of-title + need_tl -> devtag-needs-title + (@html_check_need_title, sh, EQ): The foregoing registers are + effectively Booleans, so perform Boolean-style tests on their + interpolations. + + Fixes a second third of . + +2021-06-16 G. Branden Robinson + + * tmac/e.tmac-u: Work in compatibility mode. It seems this was + the intention (reasonable, since "me" originates in pre-groff + BSD Unix), but there were several problems. + (@R): Prefix register existence test with `do`. + (@html_check_need_title): Define with `do` since the macro name + is long, and also with `de1` so that we can freely use groff + extensions within. Drop many `do` requests from macro + definition. + (@check_need_title): Define with `do`, as above. Add comment + explaining why `de1` is not needed for this macro definition. + (@S): Prefix macro/string existence test with `do`. Remove + spurious space so that the argument string name is truly defined + as empty. + (nm, n1, n2): Prefix handling of long register names `_#p` and + `_#f` with `do` request. + (top level): Prefix `mso` request with `do`. + ((x-html): Define with `do` and `de1` instead of `de`. Drop + now-unnecessary `do` requests from macro body. + ()x-html): Define with `do` and `de1` instead of `de` for + symmetry. + (xp-html): Define with `do` and `de1` instead of `de`. Drop + now-unnecessary `do` requests from macro body. + + Fixes . + +2021-06-16 G. Branden Robinson + + * tmac/devtag.tmac: Work in compatibility mode; define macros + with the `de1` instead of the `de` request. + +2021-06-16 G. Branden Robinson + + * tmac/refer-me.tmac: + * tmac/refer.tmac: Add include guards. + +2021-06-16 G. Branden Robinson + + * tmac/refer-me.tmac: Handle being loaded in compatibility mode. + +2021-06-16 G. Branden Robinson + + * tmac/an-old.tmac: Properly situate devtag flag-related + register names in the package name space. Rename `need_eo_h` to + `an-devtag-needs-end-of-heading'. Rename `need_col2` to + `an-devtag-needs-second-column`. + (an-input-trap, SH, SS, HP, (initialization)): Do it. + (an-input-trap): Test their values more idiomatically. + + Fixes one third of . + +2021-06-16 G. Branden Robinson + + * src/roff/troff/input.cpp (do_if_request): Improve diagnostic + message; say "conditional operator", not just "conditional". + +2021-06-16 G. Branden Robinson + + * tmac/an-old.tmac (an-end, an-header): In continuous rendering + mode, use same spacing amount after header and before footer as + mdoc in its own continuous rendering mode. Thanks to Ingo + Schwarze for the suggestion. + + Fixes . + +2021-06-16 G. Branden Robinson + + * tmac/an-old.tmac (P): Define this as the "canonical" + paragraphing macro. + (LP, PP): Make these aliases of P. + +2021-06-16 G. Branden Robinson + + * src/roff/troff/input.cpp (spring_trap): Tighten lexical + discipline; describe macro as "trap-called" rather than + "trap-invoked". + +2021-06-15 G. Branden Robinson + + [man]: Don't spuriously break a page after a paragraph tag when + the tag is short enough to fit within the paragraph's + indentation. + + * tmac/an-old.tmac (an-write-paragraph-tag): Reserve ("need") 2 + vees plus 1 basic unit of vertical space regardless of the width + of the tag. In the short tag case, we reverse space by one vee + after outputting the diversion in which the tag is stored, but + it will always contain a break, and by the time we reverse, we + might have already hit a page location trap + {an-break-body-text}, and by then it's too late to back up. + + * tmac/tests/an-old_no-break-after-short-paragraph-tags.sh: Test + it. + * tmac/tmac.am (tmac_TESTS): Run test. + + Fixes . + +2021-06-15 G. Branden Robinson + + * tmac/an-old.tmac: Rename environments to be more descriptive. + an-env -> an-env-header-or-footer + an-2 -> an-env-paragraph-tag + (an-header, an-footer, an-write-paragraph-tag): Do it. + +2021-06-14 G. Branden Robinson + + * tmac/s.tmac: Add diagnostic error if .EQ used within .TS/.TE. + Introduce register `tbl@within-table` to track whether we're + inside a table. + (@EQ): Check register and issue error if it is true. + (@TS): Set register. + (@TE): Clear register. + + Prompted by Savannah #55754. + +2021-06-14 G. Branden Robinson + + * tmac/s.tmac: Permit document to start with .PS. + (cov*ab-init): Alias PS to @PS. + (PS): Call LP, then re-execute (aliased) self as TS does. + (TS): Update comment to parallel the one in PS. + +2021-06-11 Tadziu Hoffmann + + Indent an IP paragraph based on the type size of the paragraph + text, not a preceding heading. We have to delay evaluating IP's + argument until the font size has been reset, which I've + attempted to do by simply passing the argument unevaluated down + the call hierarchy, instead of saving it in a number register + right away, as appears customary in this ms implementation. + + However, par@reset is called from a great number of places, and + these usually set the indent registers beforehand. I've left + this as it is, so now two ways of setting the indents exist: via + register and optionally via argument. + + * tmac/s.tmac (par@reset): Move font-size setting stuff before + indent-setting stuff; set registers from optional arguments with + default "n" scaling indicator before setting indents. + (par*start, par@finish): Don't set registers, but instead pass + arguments to par@reset. + (@IP): Pass argument unevaluated to par*start. + + Fixes . + +2021-06-11 Tadziu Hoffmann + + * tmac/s.tmac (@QP, @XP): Be more scrupulous about using "u" + scaling indicator. + +2021-06-11 G. Branden Robinson + + Add regression test for Savannah #59604. + + * tmac/tests/s_IP-indents-using-paragraph-type-size.sh: Add it. + * tmac/tmac.am (tmac_TEST): Run it. + +2021-06-08 G. Branden Robinson + + Refactor grog even more aggressively. Make the tedious search + for subs.pl unnecessary by inlining it into grog.pl directly. + This makes the script stand alone and much more convenient to + work with, and doesn't contribute to bloat, in my + opinion--subs.pl was 10 times the size of grog.pl, and most of + the code in the latter was dedicated to trying to locate + subs.pl. + + * Makefile.am: Delete references to $(grog_dir). + * configure.ac: Delete call of `GROFF_GROGDIR_DEFAULT` macro. + * m4/groff.m4: Delete definition of same. + * src/roff/grog/grog.am (GROG, dist_grog_DATA, grogdir): Drop + variables. + (grog): Remove target's dependency on `$(GROG)`. Remove sed + expression replacing `@grog_dir@` with `$(grog_dir)` in grog.pl. + * src/roff/grog/grog.pl: Inline most of subs.pl (except for + author/license comment banner). Delete sub-hunting logic. + * src/roff/grog/subs.pl: Delete. + +2021-06-08 G. Branden Robinson + + * doc/pic.ms (Basic PIC Concepts, Decorating Objects/Filled + Objects, PIC Reference/Semi-Formal Grammar): Fix error: the + keyword "solid" sets a line style, not a fill for a closed + figure. Thanks to Dave Kemper and Wim Stockman for reporting + and researching this issue. + + Fixes . + +2021-06-06 G. Branden Robinson + + * NEWS: + * doc/webpage.ms: + * man/groff.7.man (Registers/Read-only registers) <.U>: + * man/groff_diff.7.man (Language/New number registers) <.U>: Fix + error; the sense of this Boolean variable was backwardly + documented {perhaps due to an implementation detail from 2004 + that was reversed in commit 7a0e2f15, 26 February 2008}. + +2021-06-05 G. Branden Robinson + + * src/roff/groff/groff.cpp: Revise usage message. + (synopsis): Set primary synopsis on a single output line, for + convenience of parsing and also because we have no control over + the width of the program name in character cells; it comes from + argv[0] and is under user control. There is thus no point in + trying to get pretty formatting. Also include separate synopsis + lines for short and long help options. Use opposite case from + option flags for option arguments. + (help): Collate option flags in English lexicographic order. + Include space after flag letters for options that take + arguments. Consistently use capitals for option arguments + because they are space-separated here. Illustrate longer forms + of -d and -r options. Update language (some, like "tmac.name", + was very old). Add reference to groff(1) man page at end. + (usage): Drop appendnment of notice regarding -h option; this is + now covered in `synopsis()` unconditionally. + +2021-06-05 G. Branden Robinson + + Eliminate "groff_opts_no_arg.txt" and "groff_opts_with_arg.txt" + files from distribution. They are not needed by any live code + in the tree; possibly only groffer ever used them. + + * src/roff/groff/groff.am (GROFF_OPTS_OUTPUT, groffoptsdir) + (groffopts_DATA): Delete variables. + (MOSTLYCLEANFILES): Stop adding to target. + (groff_opts.tmp, groff_opts_no_arg.txt, + groff_opts_with_arg.txt): Delete targets. + +2021-06-05 G. Branden Robinson + + * src/roff/grog/subs.pl (version): Report version information in + a format consistent with our other programs. + +2021-06-05 G. Branden Robinson + + * src/roff/grog/grog.pl: Refactor initialization so that the + program can be run from a build tree--and tested. Drop much + cruft from before Bertrand Garrigues's 2018 work to adopt + `git-version-gen`. + +2021-06-04 G. Branden Robinson + + * tmac/tests/an-old_title-abbreviation-works.sh: Log more + accurate messages in test failures. + +2021-06-03 G. Branden Robinson + + * tmac/an-old.tmac (an-abbreviate-title): Add new internal macro + to reduce the length of a man page title (i.e., the "ls" in + "ls(1)", if it is too wide to fit in the page header (and would + overwrite the center header material, usually the title of the + manual section). Since the beginning and end of the title might + be important for disambiguation, truncation at either end would + be unwise; replace the middle of the title with an ellipsis. + Define new an-pageref and an-title-abbv strings for use by other + macros and user-defined PT and BT traps. + (PT, an-footer): Use new an-pageref string for economy. + (an-header): Call an-abbreviate-title after setting the title + length. + + * tmac/tests/an-old_title-abbreviation-works.sh: Test it. + * tmac/tmac.am (tmac_TESTS): Run test. + + Fixes . + +2021-06-03 G. Branden Robinson + + * man/groff.7.man (Copy mode): Add new section. + +2021-06-03 G. Branden Robinson + + * src/roff/troff/input.cpp (else_request, while_request) + (pipe_source, open_request, opena_request, pipe_output) + (system_request): Update diagnostic messages to not presume the + identities of the control or escape characters. + +2021-06-01 G. Branden Robinson + + * doc/groff.texi (Conventions Used in This Manual): Add node. + +2021-05-31 G. Branden Robinson + + * src/roff/groff/groff.1.man: Expand to aid beginners. + (initialization): Define `TeX` string. + (Usage): Rewrite. + (Usage/Getting started): Add "Hello, world!" example using + multiple output devices (formats). + (Usage/Using groff as a REPL): Add example of likely interest to + programmers. Or so I hope. It illustrates the Turing + fundamentals; we read, store, test, and branch. + +2021-05-29 G. Branden Robinson + + * tmac/papersize.tmac: Improve diagnostic message; when + complaining about unrecognized input, report back the input we + actually received, not what it looks like after we transform it. + Also add name of macro package to diagnostic so the user knows + who is speaking, continuing the long process of fixing Savannah + #52463. + +2021-05-29 G. Branden Robinson + + * tmac/groff_ms.7.man (Usage/Paragraphs) : Fix error: .QP + paragraphs are indented by \n[QI], not \n[PI]. + +2021-05-27 G. Branden Robinson + + * src/libs/libdriver/input.cpp (do_file): Make fatal diagnostic + from output driver when the device description file "DESC" can't + be found more informative by including the name of the device + for which the input was prepared. Also makes malformed input of + intermediate format more obvious. + +2021-05-27 G. Branden Robinson + + * src/preproc/tbl/tbl.1.man (Miscellaneous): Add paragraph + cautioning users against making tbl(1) tables conditional + document content. + +2021-05-25 G. Branden Robinson + + [man]: Add style warnings for documents with input lines that + are blank or have leading spaces, since they can cause + surprising rendering; enabled if the CHECKSTYLE register is + greater than 2. + + * tmac/an-old.tmac (an-blank-line-trap, an-leading-space-trap): + Issue style warning if enabled (and only if fill mode enabled in + leading space trap); in any event, recreate the default *roff + behavior. + (TH): Install traps. + + * doc/andoc.tmac (reload-doc): Remove man(7) traps before + loading doc.tmac. + +2021-05-25 G. Branden Robinson + + * doc/andoc.tmac (reload-doc): Fix spurious blank line. + +2021-05-25 G. Branden Robinson + + * doc/groff.texi (Operators in Conditionals): + * man/groff.7.man (Control structures/Conditional expressions): + Fix omission; the conditional operators "F", "m", and "S" also + accept optional spaces and/or tabs between themselves and their + arguments. + +2021-05-25 G. Branden Robinson + + * man/groff.7.man (Requests/Request short reference) <.ta>: + Describe the request as tersely as possible without omitting its + essential syntax and semantics. (The AT&T troff "+" relative + prefix for normally absolute positions ".ta 1i +1i +1i" and + alignment-specifying suffixes "L", "R", and "C" had both been + omitted.) + +2021-05-25 G. Branden Robinson + + * man/groff.7.man (Registers/Writable registers): Fix error: + \n[nl] interpolates the current vertical position, not the + vertical position of the "last printed text baseline"; the + latter is \n[.h]. + +2021-05-25 G. Branden Robinson + + * doc/groff.texi (Manipulating Filling and Adjustment): Update + inter-sentence space example to be more illustrative. Thanks to + Dave Kemper and Doug McIlroy for the discussion. + + Fixes . + +2021-05-23 G. Branden Robinson + + * tmac/mdoc/doc-common-u: Add comment warning source divers that + \n[doc-header-space] is re-used for a purpose for which it is + not documented. + * tmac/mdoc/doc-nroff-u: Initialize doc-{header,footer}-space + registers, which define the vertical spacing between body text + and the relevant titles (not between the titles and the page + margins) to 1v instead of 0.5i. This is what mdoc(7) has always + done in practice, per Ingo Schwarze. + +2021-05-23 G. Branden Robinson + + * src/devices/grohtml/post-html.cpp (assert_state::add): Avoid + potential deallocation of statically-allocated strings. Use + strsave() to duplicate them so that they can be safely handed to + a_delete(). Also update diagnostic message to report name of + complaining program (continuing the long process of fixing + Savannah #52463). + + Fixes . Thanks to + Petru-Florin Mihancea for the report. + +2021-05-23 G. Branden Robinson + + * tmac/troffrc-end: Fix transposition error (in commit a248aa33 + on 15 January) that broke most table image generation in HTML + output. + + Fixes . + +2021-05-23 G. Branden Robinson + + * tmac/an-ext.tmac (UE, ME): Replace calls to HTML-NS macro for + emissions of HTML 'A' tags with direct usage of \X device + control escapes. Replace .nop requests with text lines since + this file is supposed to be maximally portable to other *roffs. + +2021-05-22 G. Branden Robinson + + * src/preproc/html/pre-html.cpp (main): Call `scanArguments()` + earlier, before trying to load a font description, so that -v, + --version, and --help work. + +2021-05-22 G. Branden Robinson + + [grohtml]: Add -C and -G options to postprocessor, to suppress + output of CreationDate and Creator HTML comments, respectively. + These can inject unwanted noise into build artifacts. + + * src/devices/grohtml/post-html.cpp: Add static globals + `do_write_creator_comment` and `do_write_date_comment`. + (html_printer::{do_file_components,~html_printer}): Write + comments per corresponding global variables. + (main): Add to `getopt_long()` call parameter and set as needed. + (usage): Document them. + + * src/preproc/html/pre-html.cpp (scanArguments): Add to + `getopt_long()` parameter, but ignore. + + * src/devices/grohtml/grohtml.1.man (Synopsis, Options): + Document them. + + * src/roff/groff/tests/output_driver_C_and_G_options_work.sh: + Test them. + * tmac/tmac.am (groff_TESTS): Run test. + + Fixes 1/3rd of . + +2021-05-22 G. Branden Robinson + + * src/preproc/html/pre-html.cpp (usage): + * src/devices/grohtml/post-html.cpp (usage): Fix inaccuracies in + supported option summary. + +2021-05-22 G. Branden Robinson + + * src/preproc/html/pre-html.cpp (scanArguments): + * src/devices/grohtml/post-html.cpp (main): Use libgroff's + warning() instead of printf() to emit diagnostic about + unrecognized parameter to `-x` option. This sends the + diagnostic to the standard error stream and continues the long + process of fixing Savannah #52463. + +2021-05-22 G. Branden Robinson + + * tmac/groff_www.7.man: Stop using the "www" macro package. The + macros it exposes are not part of the quasi-standardized man(7) + language, and thus should not be used in man(7) documents. See + groff_man_style(7) for portability advice. Besides, the + extension macros in the permissively-licensed an-ext.tmac are + sufficient to support URL and email hyperlinks, and our SH and + SS macro implementations already support anchor placement + without requiring explicit effort from page authors. + (initialization): Stop sourcing www.tmac. Stop calling .LK and + .HR; the page-internal navigation links were being placed after + the apropos line instead of at the beginning of the page, + contradicting the comment that was there (possibly a bug). + (Requests) : Stop calling .TAG. + : Drop paragraph advising reader to format page for groff's + HTML output device to observe the navigation links at that point + in the test. + +2021-05-22 G. Branden Robinson + + * doc/groff.texi (Comments): Fix error in description of parser + operation; '.\"' is an effective whole-line comment not because + it is a call of an undefined macro named '\"' (no 'mac' warning + is emitted when that warning type is enabled), but because the + comment escape is recognized normally and what remains is + handled as the empty request. Clarify that the optional + argument to the .ig request is the name of a macro (which will + be called normally _and_ end the ignored region; this is + analogous to ".de foo bar"). + +2021-05-22 G. Branden Robinson + + * tmac/an-ext.tmac (UR, UE, MT, ME): Rename environment and + diversion for clarity; they apply to the link text, not the URL + {or email address}. The latter might not visibly appear, + depending on the output driver. + +2021-05-20 G. Branden Robinson + + * tmac/an-old.tmac (TH): Remove extraneous right-brace escape. + + Fixes . Thanks to Bjarni + Ingi Gislason for catching it. + +2021-05-20 G. Branden Robinson + + * doc/groff.texi (Copy Mode): Fix omissions from list of escape + sequences interpreted even in copy mode. Add \g, \V, "\.", + '\"', \#, \a, \e and \E (with caveat), and \t. Parallels + groff(7) now. Add cross reference to "Character Translations" + node. + +2021-05-20 G. Branden Robinson + + * man/groff.7.man (Escape Sequences): Fix omission; the escape + character in an unrecognized escape sequence is not merely + ignored; the sequence produces a warning diagnostic, albeit of a + type that is disabled by default. + (Escape Sequences/Escape short reference): Fix omissions; \# and + \V are interpreted even in copy mode. + +2021-05-20 G. Branden Robinson + + * tmac/an-old.tmac (an-header): Fix missing brace escape. + +2021-05-20 G. Branden Robinson + + [man]: Slightly refactor footer spacing management when + continuously rendering. + + * tmac/an-old.tmac (an-end): Increase the page length _after_ + flushing a pending output line. Do so only by the amount of + spacing we actually perform next. Make the scaling indicator on + the .sp request explicit. The amount seemed magical because it + was accounting for the one line to be consumed by output of the + footer title line. Instead, move that further increase of the + page length from here... + (an-footer): ...to here (~250 lines away), before calling BT. + +2021-05-20 G. Branden Robinson + + * tmac/mdoc/doc-common-u (doc-end-macro): When continuously + rendering and after flushing the last line of the body text of a + page, vertically space by 3 vees instead of 1, for consistency + with our man(7) implementation. Also increase page length by + same amount _after_ flushing a pending output line, for symmetry + with other spacing requests (and to prevent nasty surprises + analogous to those in Savannah #60611). + (doc-header): Put 3 vees of space after the header in continuous + rendering mode, not 1 (and increase page length accordingly). + +2021-05-20 G. Branden Robinson + + [man]: Add warnings for macros deprecated in groff_man(7), + emitted if the CHECKSTYLE register is greater than 1. + + * tmac/an-old.tmac (an-deprecation-warn): New macro emits + diagnostic. + (DT, PD): Call the foregoing, re-using arguments. + +2021-05-20 G. Branden Robinson + + * tmac/an-old.tmac: Refactor to move bodies of DT and PD into + private macros. + (an-reset-tab-stops, an-reset-paragraph-spacing): New names for + the former DT and PT. + (TH): Call these new macro names. + (DT, PD): Wrap the corresponding private macros. + +2021-05-20 G. Branden Robinson + + * tmac/an-old.tmac (an-bp): In continuous rendering mode, draw + a horizontal line between a page footer of one man page document + and the header of the next, but only if multiple documents are + being rendered. + (initialization): Use variable to ensure we don't draw this line + after finishing the only document we render. + + Fixes other half of . + +2021-05-20 G. Branden Robinson + + [man]: Fix stochastic vertical space loss problems in continuous + rendering mode by being more scrupulous about extending the page + length. As noted in Savannah #60611, sometimes the vertical + space between a header line and the first section heading + {"Name"} would be reduced or removed altogether, in a way that + was highly sensitive to circumstances. As far as I can tell, + the problem is that this vertical space disappeared only when we + were in double-secret probation no-space mode; this is the + special non-spacing mode {not apparent with inspection of + \n[.ns]} that happens when the stealth internal page location + trap is sprung. This trap does not appear in .ptr output but + can be disabled with ".vpt 0", which is an alternative fix for + this problem {because continuous rendering mode does not use + vertical position traps at all}. Another fix might have been to + simply call the moral equivalent of ".pl MAXINT" as soon as + continuous rendering mode was decided upon. + + * tmac/an-old.tmac (an-header): In continuous rendering mode, + extend the page length by one line before calling PT to output + the page header, and afterwards, extend the page length by 3 + vees and space by that amount (instead of half an inch). + + Fixes half of . + +2021-05-20 G. Branden Robinson + + * tmac/an-old.tmac (an-header, an-footer): Drop no-op .tl + requests. + +2021-05-20 G. Branden Robinson + + * tmac/an-old.tmac (an-footer): Improve symmetry with an-header. + If rendering to HTML, don't bother setting the + an-outer-footer-text, an-extra1, and an-extra2 strings to empty + values; instead don't call BT, just as we don't call PT in + an-header. + +2021-05-19 G. Branden Robinson + + * tmac/an-old.tmac (an-end): Drop needless .nr % assignment. + Call our (wrapped) bp instead of the .pl request directly. + (an-bp): Drop needless .br and (aliased) real .bp request. + +2021-05-19 G. Branden Robinson + + * tmac/an-old.tmac (an-footer): Refactor complex conditional. + +2021-05-19 G. Branden Robinson + + * tmac/tests/an-old_X-register-works.sh: Add test for footer + creeping into page content. + +2021-05-19 G. Branden Robinson + + * tmac/an-old.tmac (initialization): Ignore P and X rendering + parameter registers if specified with continuous rendering + enabled (the default in the nroff mode used for terminals), and + emit diagnostic. + +2021-05-19 G. Branden Robinson + + * tmac/tests/an-old_X-register-works.sh: Rewrite. Increase test + coverage and stop assuming that -rcR=1 and -rX=anything is a + supported combination. (Continuous rendering is supposed to + suppress the printing of page numbers anyway.) + +2021-05-19 G. Branden Robinson + + * tmac/an-old.tmac (initialization): Refactor handling of P and + X rendering parameter register validation in preparation for + disabling them in continuous rendering mode, where they don't + make any sense. + +2021-05-19 G. Branden Robinson + + * tmac/tests/an-old_TH-repairs-ad-damage.sh: Tweak test + internals to make troubleshooting easier. + +2021-05-18 G. Branden Robinson + + * tmac/an-old.tmac (TH): Relocate some initialization logic to + be adjacent to (most of) the rest of it. + +2021-05-18 G. Branden Robinson + + * tmac/an-old.tmac (TH): Remove useless .if. Its condition is + always true now in the wake of the fix for Savannah #60609. + +2021-05-18 G. Branden Robinson + + * tmac/an-old.tmac: Rename many package macros, strings, and + registers (and the lone named environment) to be more expressive + of their function. "an-footer" is now the proper complement of + "an-header" (setting up an environment and calling a + user-redefinable trap macro). + an-first -> an-is-first-page-of-document + an-html -> an-is-output-html + an-footer -> an-break-body-text + an-p-footer -> an-footer + an-set-margin -> an-reset-margin-and-inset-level + an-level -> an-inset-level + an-tag-sep -> an-tag-separation + an-no-space-flag -> an-need-no-space-mode + an-break-flag -> an-need-break + an-div? -> an-is-in-diversion + an-page-string -> an-outer-footer-text + an-trap -> an-input-trap + an-do-tag -> an-write-paragraph-tag + an-1 -> an-env + + * tmac/andoc.tmac (reload-doc): ...as above for the exposed + parts of the interface. + an-footer -> an-break-body-text + an-p-footer -> an-footer + +2021-05-18 G. Branden Robinson + + * tmac/an-old.tmac: Rearrange alternating font macros to be in + alphabetical order (and the order documented in groff_man(7). + +2021-05-18 G. Branden Robinson + + * tmac/an-old.tmac: Refactor alternating font macros. These + macros are hard enough to understand without adding gratuitous + structural differences to the reader's burden. Make their + implementations rigidly parallel. Update comments. + (RI, IR, IB, BI, RB, BR): Always define the `an-result` string + as empty except for a dummy character '\&' for the sake of + compatibility mode. + (RI, IR, IB, BI): Defer interpolation of the first argument to + the while loop if there are at least two (like the existing RB, + BR). This way the style name arguments to the font selection + escape sequences in the appendment to `an-result` match the + order of the letters in the macro name (useful to make sense of + diffs). + (RI, IR, IB, BI, RB, BR): Always remove the `an-result` string + after interpolating it. + (RB, BR): Only do work if there are any arguments. + +2021-05-18 G. Branden Robinson + + [man]: Apply italic corrections more consistently. + + * tmac/an-old.tmac (BI, IB, IR, RI): Apply italic corrections + more consistently. Add lengthy comment rationalizing approach. + (RI, BI): An italic correction is now applied after the last + argument if it is of even parity (i.e., the 2nd, 4th, 6th, ...). + + * tmac/groff_man.7.man.in (Description/Font style macros): Note + that italic corrections are applied. + + Fixes . + + Thanks to Bjarni Ingi Gislason for the report and a suggested + patch. + +2021-05-17 G. Branden Robinson + + [man]: Ignore FT register when appropriate. + + * tmac/an-old.tmac (initialization): Validate user-specified + value of \n[FT]. Continuous rendering ignores FT (page location + traps are not used for footers in that mode). Measuring a + footer distance from the page top isn't done. A footer distance + of over half the page length is unlikely. A footer distance of + less than one line height is too. Issue diagnostics in all of + these cases. + + * tmac/tests/tmac/tests/\ + an-old_FT-bad-value-should-not-trash-titles.sh: Test it. + * tmac/tmac.am (tmac_TESTS): Run test. + + Fixes . + +2021-05-17 G. Branden Robinson + + * tmac/an-old.tmac (TH): Plant the an-footer trap (where we + schedule a break in the page text prior to spacing down to the + footer) at twice the value of \n[FT], not a hard-coded -1i. + This way, the user can't make the an-p-footer trap (planted at + \n[FT]) spring before the an-footer trap that should precede it. + + * tmac/groff_man.7.man.in (Options) <-rFT>: Document this. + +2021-05-16 G. Branden Robinson + + * m4/groff.m4 (GROFF_GHOSTSCRIPT_VERSION_CHECK): Add new + autoconf macro to check Ghostscript version. Versions 9.00 <= x + < 9.54 suffer from a rendering glitch that affects the AT&T + troff (and groff) special character \(lh; see + . Store + the result of the check. + (GROFF_GHOSTSCRIPT_VERSION_NOTICE): Add new macro to report the + problem detected by GROFF_GHOSTSCRIPT_VERSION_CHECK to the user. + + * configure.ac: Call the macros in appropriate places. + + Fixes . + +2021-05-16 G. Branden Robinson + + * tmac/andoc.tmac (reload-man): Remove removal of RI macro, made + unnecessary by commit 551f138 (15 May). + +2021-05-16 G. Branden Robinson + + * m4/groff.m4 (GROFF_HTML_PROGRAMS, GROFF_PDFDOC_PROGRAMS): + Tweak autoconf warning messages when Ghostscript (gs) command + missing to be more mutually congruent. + (GROFF_URW_FONTS_CHECK): Tweak to note that gs is only run to + locate the URW fonts if gs is available. + +2021-05-16 G. Branden Robinson + + * tmac/tests/an-old_AT-and-UC-footer-saved-and-restored.sh: + Tweak to be more helpful when troubleshooting exasperating + header/footer problems as in Savannah #60609. + +2021-05-16 G. Branden Robinson + + [man]: Fix missing page footers when continuously rendering + multiple documents. Resolving this uncovered entangled header + and footer management bugs with batch processing even when _not_ + continuously rendering. + + * tmac/an-old.tmac (an-start-new-document): New macro clears + header trap so it doesn't get called with stale information. + {The TH macro already replants a header trap with every man + page if not continuously rendering.} This macro also absorbs + the break-page and page number incrementation logic from TH. + (TH): Adapt semantics of "an-first" register to mean not "first + page rendered" (apparently) but "first page of new document". + If we are _not_ on the first page of a new document and the TH + macro is called, we must be batch processing: force the previous + man page to end (call an-end if continuously rendering, or + an-start-new-document if not). After all the header and footer + strings have been configured for the man page, call an-header if + we're on the first page of the document, not (just) if we're + continuously rendering. Zero an-first register at end of macro + here unconditionally instead of conditionally in .an-header. + (an-header): Drop conditional on continuous rendering. + + When I batch-render our 62 man pages to the terminal, I do note + one cosmetic regression: the lj4_font(5) page, when continuously + rendered in batch processing, has no space between its header + line and first section heading ("Name"). Another cosmetic issue + in this scenario is that the footers for every rendered page but + the last, which had (wrongly) been absent entirely, are set with + no space after them and the header of the next. + + * tmac/tests/an-old_page-footers-present.sh: + * tmac/tests/an-old_page-header-has-current-data.sh: Add man + page header/footer regression tests. + * tmac/tmac.am (tmac_TESTS): Run the tests. + + Fixes . + +2021-05-15 G. Branden Robinson + + * tmac/an-old.tmac (initialization): Key the reprocessing guard + {like a C language #include guard} on the existence of the TH + macro instead of RI. The latter seemed kind of random and TH + is even more guaranteed to exist; it is the macro name most + characteristic of the man(7) language and the andoc.tmac + superstructure relies on it. (TH may have been avoided because + of its use with tbl(1); however, neither man(7) nor mdoc(7) + support tbl's TH feature, and GNU tbl does not supply its own + empty fallback definition as it does for TS and TE. If we ever + want TH-like functionality in future man pages, I suggest we + pick a new, non-colliding name for it.) + (initialization): Relocate load of devtag package; we don't + need it before entering compatibility mode. Move assignment of + format of an-page-letter register from a "loose declaration" + amid macro definitions to within existence test of X register. + Stop initializing an-extra[123] strings outside of any macro; + they need to be reinitialized at every TH call when batch + rendering. + (TH): Call DT in a less surprising place. + (TH): Initialize all header/footer-related strings before + calling header macros, even those not needed for the default + header configuration. + (TH): Add style warnings for underspecified arguments. + (an-ne): Rename register from "an-need", which is pretty + confusing in context, to "an-amount", since (1) a (vertical) + amount is what it is, and (2) it's only used within this macro. + Also due to factor (2), remove the register after using it. + +2021-05-15 G. Branden Robinson + + * m4/groff.m4 (GROFF_URW_FONTS): Update configure script check + for URW fonts to recognize recent releases of the URW Base 35 + fonts from Artifex Software. Look for the AR (Arial roman + equivalent) font under all of the names recognized by + fonts/devpdf/Foundry.in. + * m4/groff.m4 (GROFF_URW_FONTS_CHECK): Update wording of notice + when URW fonts are not found. Replace dead URL with working + one. Try to hedge against the future, but the Web is an + ephemeral place, as are the file names Artifex gives to its + fonts. Thanks to T. Kurt Bond and Thomas Dupond for reporting + and investigating the problem. + + Fixes . + +2021-05-13 G. Branden Robinson + + * doc/groff.texi (ms Document Control Settings) : + * doc/ms.ms (Document control settings, Displays and keeps) + : + * tmac/groff_ms.7.man (Document control settings, Displays and + keeps) : Document this register; it had been mentioned only + in passing. + +2021-05-13 G. Branden Robinson + + * doc/groff.texi (ms Document Control Settings)
: + * doc/ms.ms (Document control settings)
: + * tmac/groff_ms.7.man (Document control settings)
: Fix + error; changes to \n[DD] take effect at the next display + boundary (including the end of the active one), not the next + "paragraph" (paragraph macros cannot be called inside a display + anyway). + +2021-05-12 G. Branden Robinson + + * tmac/andoc.tmac (reload-man): Delete no-op line that attempts + to restore compatibility mode. Individual pages have to do + this, and ".do cp \n(.C" is not effective for the reason + discussed in the 2020-04-16 ChangeLog entry. + +2021-05-08 G. Branden Robinson + + * tmac/s.tmac (@RT): Delete definition; make it an alias for + par@finish. Until commit 021ba0e7 (1 May), they had identical + definitions. I find it difficult to imagine what use it would + be to have an undocumented reset macro that resets everything + _except_ the deeply internal \n[.ev]:ai. + +2021-05-08 G. Branden Robinson + + [man]: Handle HF strings with an embedded font family when + applying italic-to-bold-italic remapping; the feature now works + on troff devices as well. + + * tmac/an-old.tmac (initialization): Do more validity checking. + Store heading family in new string \*[an-heading-family]. Clean + up after self. + (SH, SS): Include the heading family in the remapping target. + + * tmac/groff_man.7.man.in (Description/Document structure + macros) <.SH, .SS>: Document it. + +2021-05-07 G. Branden Robinson + + * man/groff_char.7.man (Glyph tables/Mathematical symbols): Fix + errors in special character descriptions; \[sqrt] is a "special" + glyph (that is, it uses mathematical metrics on typesetter + devices), and \[radicalex) is not (and is thus a "text" glyph). + See Werner Lemberg's ChangeLog entry of 2003-01-05. Problem + dates to 07a6233ad, 27 May 2014. + + The overloaded use of the word "special" really pinches here. + +2021-05-07 G. Branden Robinson + + * tmac/tty.tmac: Replace fallback glyphs for radical extension + and square root extension; use \[rn] instead, which works fine. + + Now the only glyph in the page that doesn't render on a UTF-8 + terminal (if one's font has adequate coverage) is the Bell + System logo. + +2021-05-07 G. Branden Robinson + + * tmac/tty.char: Add fallback characters for \[fm] and \[sd]. + +2021-05-06 G. Branden Robinson + + [man]: If \*[HF] is a bold style, substitute bold italics for + italics in section and subsection headings, keeping the font + weight consistent. + + * tmac/an-old.tmac (initialization): Set a flag for this based + on the interpolation of \*[HF] matching "B" as its last + character. + (SH, SS): Apply and reverse font remapping based on this flag. + +2021-05-06 G. Branden Robinson + + * tmac/an-ext.tmac (EX): Work around Savannah #59522 by changing + fonts differently on DVI output, avoiding a font warning. + +2021-05-06 G. Branden Robinson + + * tmac/an-ext.tmac: If in nroff mode, remap font CBI to BI. + * tmac/dvi.tmac: Remap font CBI to CWI. (Computer Modern + Constant Width has no bold styles.) + +2021-05-05 G. Branden Robinson + + * tmac/s.tmac (NL, SM, LG): Issue warning diagnostic if macro + called with arguments. + (par*define-font-macro): Construct font macro with diagnostic to + warn if called with excess arguments. + (UL, BX): Issue warning diagnostic if macro called with excess + arguments. + + Fixes . + +2021-05-05 G. Branden Robinson + + * doc/groff.texi: Delete redefinition of \putwordAppendix + Texinfo macro. This restores the word "Appendix" to the names + of all appendices and fixes two bad internal links to Appendix + E, the Register Index, in the DVI and PDF output formats. Per + consultation with Texinfo maintainer Gavin Smith, it's difficult + to get the behavior we want, so give up trying for now. + +2021-05-05 G. Branden Robinson + + * tmac/s.tmac (@MC): Actually diagnose and recover when user + tries to .MC inside a diversion. + +2021-05-05 G. Branden Robinson + + * doc/groff.texi (Differences from AT&T ms): + * doc/ms.ms (Differences from AT&T ms): + * tmac/groff_ms.7.man (Differences from AT&T ms): Document our + different default (empty) for the center footer in nroff mode; + this behavior appears to date back to June 1991 or earlier, + drawing few complaints. + + Fixes . + +2021-05-02 G. Branden Robinson + + * tmac/tests/*: Rename files to use consistent scheme; one + underscore to separate the package name from the test objective, + dashes to otherwise separate words. + * tmac/tmac.am (tmac_TESTS): Use new names. + +2021-05-02 G. Branden Robinson + + [ms]: Restore support for AT&T ms PN register. + + * tmac/s.tmac (pg): Make register PN an alias of %. + + * doc/groff.texi (Differences from AT&T ms): + * doc/ms.ms (Differences from AT&T ms): + * tmac/groff_ms.7.man (Differences from troff ms): We don't need + PN, and it was removed in commit 08291b40 (25 October 2020), but + since it is documented in Lesk 1978 we're stuck with it. Advise + users to stick with %. Also warn them of the hoop they must + jump through if they redefine the page trap macro PT, which Lesk + 1978 also encourages. + + * tmac/tests/s_PN-works.sh: Test it. + * tmac/tmac.am (tmac_TESTS): Run test. + + Fixes . + +2021-05-01 G. Branden Robinson + + [ms]: Restore default IP paragraph indentation after an SH call. + + * tmac/s.tmac (par@finish): Set "ai" register for the current + environment to the paragraph indent (PI) setting for the current + environment. + + * doc/groff.texi (Highlighting in ms) : + * doc/ms.ms (Highlighting) : + * tmac/groff_ms.7.man (Usage/Highlighting) : Update + documentation. + + * tmac/tests/s_SH_resets_IP_indentation_amount: Test it. + * tmac/tmac.am (tmac_TESTS): Run test. + + Fixes . + +2021-05-01 G. Branden Robinson + + * tmac/s.tmac (DS): Issue diagnostic and attempt recovery if + document attempts to start a display within another display. + + Fixes . + +2021-04-30 G. Branden Robinson + + * tmac/s.tmac: Implement alternative rendering for automatic + footnote numbers in nroff mode, inspired by Heirloom Doctools + ms; since superscripting is not universally available on + terminals, surround number with square brackets instead. + (fn@init): New macro finishes initializing footnote module, + setting up aliases to par@sup-{start,end} strings in troff mode + and otherwise defining fn@sup-{start,end} as brackets. Define * + string here, using new strings. + (par): Call fn@init after par@sup-{start,end} are defined, and + prior to other footnote integration material. + (par*fp!0): Migrate from par@sup-{start,end} to + fn@sup-{start,end}. + + * doc/groff.texi (ms Document Control Settings) : + * doc/ms.ms (Footnotes) : + * tmac/groff_ms.7.man (Usage/Footnotes) : Document it. + + Fixes . + +2021-04-30 G. Branden Robinson + + * test-groff.in: Stop passing the built groff executable -b and + -ww options by default. This reverses a change from 2017. Dave + Kemper has convincingly argued that there's no way to override + -b and turn backtraces on warnings/errors back off, and that the + built groff should behave as much like a "normal" one as + possible. The latter factor is of added importance now that we + are using test-groff for generation of documents. + + * src/roff/groff/tests/regression_savannah_58153.sh: Adapt. + +2021-04-30 G. Branden Robinson + + * tmac/s.tmac (BX): Add alternative implementation for terminal + {nroff} devices. Store width of boxed text, adding .4m only on + troff devices (to make room for the vertical box lines). Break + long input line in troff implementation. If not in troff mode, + use ISO 6429 color escapes to render boxed text in black on + white. Use the \Z escape to match breaking semantics of macro + in troff mode. + + * doc/groff.texi (Highlighting in ms) : + * doc/ms.ms (Highlighting) : + * tmac/groff_ms.7.man (Usage/Highlighting) : Document it. + + Fixes . + +2021-04-30 G. Branden Robinson + + * doc/doc.am: Make $(PROCESSEDDOCFILES) depend on all the same + targets as $(PROCESSEDEXAMPLEFILES); this way the me, ms, and + pic.ms manuals are all regenerated upon changes to their + underlying macro packages. + +2021-04-22 G. Branden Robinson + + * INSTALL.extra: Update. + (Evaluation): New section updates material on "test-groff" + script. Also tell people how to preview our Texinfo manual (in + info, text, DVI, PDF, and HTML formats). + (In Case of Trouble): New section updates bug reporting URL. + + Fixes . + +2021-04-21 G. Branden Robinson + + * tmac/s.tmac: Make the FAM string work more sensibly; it now + applies to headers, footers, and footnotes only if set + before the first call of a sectioning, paragraphing, or + {non-date} document description macro. + (PT, BT): Set the font family to that saved for titles. + (fn*do-FS): Set the font family to that saved for footnotes. + (par@init): Copy the document font family to independent strings + for titles and footnotes. + (par@reset): If in a footnote environment, set the font family + to that saved for footnotes; otherwise use \*[FAM]. + + * tmac/groff_ms.7.man (Differences from troff ms/Text settings): + Describe placement-dependent effect of FAM string setting. + + * doc/groff.texi (Highlighting in ms): + * doc/ms.ms (Highlighting): As above, and suggest different + occasions in which ".ds FAM C" and "CW" are convenient. + + Fixes . + +2021-04-19 G. Branden Robinson + + * src/roff/troff/input.cpp (source, source_quietly) + (macro_source, macro_source_quietly): Use idiomatic Boolean + literals. + +2021-04-17 G. Branden Robinson + + * doc/groff.texi: Drop workarounds for Texinfo pre-5.0 versions; + our local macros produced many warnings during generation of our + Texinfo manual. + (Langlemacro): + (Ranglemacro): + (Lparenmacro): + (Rparenmacro): + (Lbrackmacro): + (Rbrackmacro): Delete. Replace call sites with literals. + (Lbracemacro): + (Rbracemacro): Delete. Replace call sites with @lbracechar{} + and @rbracechar{}. + (angles): Reimplement in terms of @guilsinglleft{} and + @guilsinglright{}. Flesh out comment. + + Fixes remainder of . + +2021-04-17 Dave Kemper + + * doc/meintro.me: + * doc/meref.me: Correct and make consistent usage of the term + "point size". + + Fixes . + +2021-04-17 G. Branden Robinson + + * tmac/an-old.tmac (SS): Add devtags support. Set a subsection + title as a second-level heading and add it to a table of + contents, if any. Prompted by a query from Hans Unzner to the + groff mailing list. Thanks, Hans! + +2021-04-17 G. Branden Robinson + + * tmac/an-old.tmac (SH): Fix apparent thinko. Pass the devtags + macro a literal "1" argument. Passing it \n[an-level] wasn't + correct (it stores the relative inset level, not a sectioning + level), and was useless anyway: SH has already called + .an-set-margin by this point, which resets \n[an-level] to 1. + man(7) does not support nesting of SH macros. Also call + .DEVTAG-NH by its alias .DEVTAG-SH since section headings are + not numbered in man(7). + +2021-04-15 G. Branden Robinson + + [tmac]: Adjust editor file encoding hints. + + * tmac/cs.tmac: Tell Vim the file is "iso-8859-2" (ISO Latin-2). + * tmac/en.tmac: Stop telling Emacs the file is "latin-1"; it's + ASCII. + * tmac/fr.tmac: Tell Vim file is "iso-8859-15" (ISO Latin-9). + + Vim users may need to use ":e ++enc=iso-8859-2", for instance, + to see correct glyphs. + +2021-04-15 G. Branden Robinson + + The first-order determinant of hyphenation points is language, + not territory. Use ISO 639 2-letter language codes for + hyphenation and exception patterns instead of ISO 3166 2-letter + territory codes. + + * tmac/*.us: Rename *.us files to *.en. + * tmac/troffrc: Change hyphenation language "us" to "en". + * tmac/en.tmac: Add English localization file. Set hyphenation + mode to 4. + * tmac/troffrc: Derive groff locale from system. + + * doc/groff.texi (Manipulating Hyphenation): + * man/groff.7.man (Hyphenation): + * man/groff_diff.7.man (Implementation differences): Refer to + "U.S. English" hyphenation patterns as simply "English"; they + will be mostly correct for Commonwealth English as well, and no + alternative English hyphenation patterns for other territories + are available. + + * doc/groff.texi (Manipulating Hyphenation): + * man/groff_diff.7.man (New requests): Note that default + hyphenation mode depends on the language used on the system. + Add concept index entry for localization. Add file index + entries for the locale macro files (cs.tmac, etc.). Update to + reflect rename of English hyphenation patterns and .hla + identifier from "us" to "en". + + * src/roff/groff/tests/localization_works.sh: Add 10 test cases. + * src/roff/groff/groff.am (groff_TESTS): Run test. + + * tmac/LOCALIZATION: Rewrite. + + Fixes . + +2021-04-12 Dave Kemper + + * doc/meref.me: Correct various small issues. + + Fixes . + +2021-04-12 Dave Kemper + + * man/groff.7.man (Registers/Writable registers) : + Drop discussion of Y2K issues. + + Fixes . + +2021-04-11 G. Branden Robinson + + * doc/groff.texi (Setting Registers) : Fix error: the + request is not ignored if the second argument (the new name) + does not exist. Problem dates back to 52a6d12a (11 May 2000). + +2021-04-09 G. Branden Robinson + + Implement new .soquiet and .msoquiet requests. + + Needed for two planned developments: {1} the i18n patch in + Savannah #59814 can use this to quietly attempt to open a + localization file. groff only supports a few locales, so people + with LANG=es_ES, for instance, would ordinarily see warning + diagnostics on every groff startup; and {2} system- or + site-configurable support of per-user {.,}troffrc or man.local + files, gracefully failing if they don't exist. + + * src/roff/troff/input.cpp: + (do_source): Add new function, taking boolean "quietly" + parameter and absorbing function of source(), with added + conditional. + (source): Convert into a wrapper to call do_source() unquietly. + (source_quietly): Wrap do_source(), quietly. + (do_macro_source, macro_source, macro_source_quietly): Analogous + to the foregoing. + (init_requests): Hook "msoquiet" to macro_source_quietly() and + "soquiet" to "source_quietly(). + + * doc/groff.texi (I/O): + * man/groff.7.man (Requests/Request short reference): + * man/groff_diff.7.man (Language/New requests): Document them. + + * src/roff/groff/tests/msoquiet_works.sh: + * src/roff/groff/tests/soquiet_works.sh: Test them. + + * src/roff/groff/groff.am (groff_TESTS): Add tests. + + Fixes . + +2021-04-08 G. Branden Robinson + + * doc/groff.texi (ms Document Control Settings) : Update + description to cover application of footnote format to footnote + markers in general, not just numbers. Clarify different + behavior of format 1 with respect to automatic numbers and other + markers. + (ms Footnotes) <*>: Describe string operation in more detail. + : Describe more precisely how the optional argument is + handled. + + * doc/ms.ms (Footnotes): Synchronize with doc/groff.texi. Add + example using document's own text as a model. + + * tmac/groff_ms.7.man (Usage/Footnotes): Resync relevant + portions with doc/ms.ms. + + Fixes . + +2021-04-06 Dave Kemper + + * src/roff/nroff/nroff.sh: Recognize -k and -K options and pass + them through to troff. Document them in usage message. + * src/roff/nroff/nroff.1.man: Document new -k and -K options. + + Fixes . + +2021-04-06 G. Branden Robinson + + * doc/groff.texi (Manipulating Hyphenation): + Recast introductory paragraph to better distinguish the + automatic breaking of words and placement of hyphens at + user-specified hyphenation points (done with the \% escape) and + automatic determination of hyphenation points within words (what + the pattern files and most of the hyphenation mode parameters + are for). Clarify that what our manual calls "automatic + hyphenation" pertains only to the latter. + Correct over-general claim; hyphenation exceptions defined + with the .hw request _do_ honor .hy value 2 (don't break a word + at the bottom of a page), but none of the others. + <\%> Recast description of escape to emphasize independence of + its two uses (e.g., "\%pseudo\%unununium" is hyphenated only + after "pseudo-", if at all). + <\:> Clarify that escape is an input word boundary. + Clarify that the soft hyphen glyph is applied to manual as + well as automatically-determined hyphenation points. + Recharacterize as setting the _automatic_ hyphenation mode. + Note that restrictions apart from value 2 are not applied to + words with manually-assigned hyphenation points. + Note that request affects only automatic hyphenation. + + * man/groff.7.man (Requests/Request short reference) <.hy,.nh>: + Clarify that requests deal with _automatic_ hyphenation. + (Registers/Read-only registers) <.hy>: + Clarify that register applies to _automatic_ hyphenation. + (Hyphenation): Add new introductory paragraph summarizing manual + hyphenation support and features, including notice that breaking + at explicit hyphens is performed in fill mode, i.e., even if + _automatic_ hyphenation is disabled. + + Thanks to Peter Schaffter for the report. + + Fixes . + +2021-03-27 Deri James + + Changes to the ghostscript fontnames (9.53.3). + + * font/devpdf/Foundry.in: HI and HBI switch to using + Italic rather than Oblique. + +2021-03-24 G. Branden Robinson + + * doc/groff.texi (Manipulating Filling and Adjustment): + * man/groff_diff.7.man (Language/Extended requests): Fix + incorrect claim that additional inter-sentence space is applied + only in fill mode. Drop word "parameter" from description of + unit used in .ss request arguments; it is a needlessly specific + reference to the font file format. Tighten wording. + + * man/groff.7.man (Control Characters): Fix incorrect claim that + end-of-sentence detection is attempted only in fill mode. Note + that .ss request also affects inter-word spacing. + + * man/groff_diff.7.man (Language/Extended requests): + - Drop example. + - Move discussion of AT&T vs. GNU troff difference in .ss + handling from here... + (Implementation Differences): ...to here. + + Thanks to Dave Kemper for his continued scrutiny! + +2021-03-20 G. Branden Robinson + + * doc/groff.texi (ms Cover Page Macros): + * doc/ms.ms (Cover page macros): + * tmac/groff_ms.7.man (Usage/Cover page macros): Revise and + rename (sub)sections to "Document description macros". + +2021-03-15 Dave Kemper + + * Makefile.am: Fix typos. Thanks to Bjarni Ingi Gislason for + the report. + + Fixes . + +2021-03-14 Dave Kemper + + * man/groff_tmac.5.man: Correct erroneous reference to PSPIC + where PDFPIC was intended. Fix numerous smaller style and + content problems. + + Fixes . + +2021-03-03 G. Branden Robinson + + * doc/groff.texi (Optional man extensions) : + (Highlighting in ms) : + (Additional ms macros) : Use "monospaced" to refer to font + selected, retaining "constant-width" term only where it explains + the macro mnemonic. Thanks to Dave Kemper for pointing out the + issue. Also fix error: .CW in the ms package seems to have + originated with Research Unix, not Berkeley. + + * doc/ms.ms (Highlighting) : Sync with our Texinfo manual. + * tmac/groff_ms.7.man: Sync with ms.ms, omitting FAM advice. + + Fixes . + +2021-03-02 G. Branden Robinson + + * doc/groff.texi (Identifiers, Strings, Writing Macros) + (Diversions): Improve cross-linkage of documentation regarding + shared name space of macros, strings, diversions, and boxes. + + Fixes . + +2021-03-01 G. Branden Robinson + + * tmac/s.tmac: Improve diagnostic messages. + (@diag): New macro wraps .tm request, always prefixing it with + the name of the macro package, as well as file and line + indicators only if these are set to non-empty or non-zero + values, respectively. + (@error, @warning): Call @diag instead of .tm directly. + (@fatal): Retire; it had only one call site and it would have + greatly complicated @diag to support calling .ab instead of .tm. + An ugly alternative would have been to call .ab with a redundant + message after calling @diag. + (@divert): New macro wraps .di request, remembering the name of + the current file (\n[.F]) when a diversion is started. + (@error-recover): Call .ab instead of (deleted) @fatal. + (pg@super-eject): Tell user what the last file name seen was + when recovering from an unfinished diversion when processing + ends. + + Fixes . + +2021-02-25 G. Branden Robinson + + Fix bug where having line numbering off but the output line + number register \n[ln] set to a positive value would cause + tbl(1) table rows to spontaneously become numbered. Use new + \n[.nm] register to determine whether line numbering is enabled. + + * src/preproc/tbl/table.cpp (table::init_output, table::do_row) + (table::do_bottom): Predicate all conditions on \n[ln] + additionally on \n[.nm]. + + Thanks to Olle LĂśgdahl for the report. Problem appears to date + back to commit b69062693d3360efce9d4d63fac337be21e07db7, 20 July + 2011. + + Fixes . + +2021-02-25 G. Branden Robinson + + Add regression test for Savannah #59812. + + * src/preproc/tbl/tests/cooperate-with-nm-request.sh: Do it. + * src/preproc/tbl/tbl.am (tbl_TEST): Run test. + +2021-02-25 G. Branden Robinson + + Implement new read-only register ".nm". It reports the + enablement status of output line numbering (caused by the .nm + request) irrespective of the temporary suspension of numbering + with the .nn request. Needed because there was no way to + introspect its state, tbl(1) needs to do so, and the writable + line number register \n[ln] is not a reliable proxy for it. + + * src/roff/troff/env.h: Add get_numbering_nodes(), returning + `int`, to public interface of `environment` class. + * src/roff/troff/env.cpp: Implement get_numbering_nodes(). + + * src/roff/groff/tests/dot-nm_register_works.sh: Test it. + * src/roff/groff/groff.am (groff_TESTS): Run test. + + * doc/groff.texi (Miscellaneous): + * man/groff_diff.7.man (Language/New number registers): + * man/groff.7.man (Registers/Read-only registers): Document it. + + * NEWS: Add item. + +2021-02-23 G. Branden Robinson + + * tmac/s.tmac: Emit warning diagnostic when using a multi-page + table with a repeating header (".TS H"). + (KS): Rename diversion from "kp*div" to "kp@div" since the name + is now referenced outside the keep module. + (KF): ...similarly for kp@fdiv. + (generally): Update diversion dereference sites and derived + names. + (@TS): When handling "H" argument, check identity of current + diversion and emit appropriately worded warning. + +2021-02-14 G. Branden Robinson + + * FOR-RELEASE: Add more procedures and information related to + incrementing groff's version number. + +2021-02-14 G. Branden Robinson + + * src/libs/libgroff/searchpath.cpp (search_path::open_file) + (search_path::open_file_cautious): Save errno before calling + free() and restore it afterwards. A future version of POSIX + will require that free() not change errno if it succeeds[1]; + some C library implementations, including recent versions of + glibc[2], lack this property. free() is called in these + libgroff functions to clean up after an unsuccessful fopen() of + a heap-allocated file name string, and because the errno from + fopen() may be passed to strerror() in a diagnostic message, it + needs to be accurate. I checked the rest of groff's codebase + and found no other instances of free() being used to clean up + after fopen() failure. + + [1] https://www.austingroupbugs.net/view.php?id=385 + [2] https://sourceware.org/bugzilla/attachment.cgi?id=13073 + +2021-02-11 G. Branden Robinson + + Address build failure on macOS. + + Follow the advice of the gnulib manual ("Changing your source + for use with gnulib") more scrupulously; include config.h in + more files. + + * src/libs/libgroff/curtime.cpp [HAVE_CONFIG_H]: + * src/libs/libgroff/device.cpp [HAVE_CONFIG_H]: + * src/libs/libgroff/fatal.cpp [HAVE_CONFIG_H]: + * src/libs/libgroff/string.cpp [HAVE_CONFIG_H]: + * src/libs/libgroff/strsave.cpp [HAVE_CONFIG_H]: + * src/preproc/eqn/other.cpp [HAVE_CONFIG_H]: + * src/preproc/eqn/text.cpp [HAVE_CONFIG_H]: + * src/preproc/pic/object.cpp [HAVE_CONFIG_H]: Do it. + + * src/libs/libgroff/assert.cpp [HAVE_CONFIG_H]: + * src/libs/libgroff/errarg.cpp [HAVE_CONFIG_H]: + * src/libs/libgroff/error.cpp [HAVE_CONFIG_H]: #include + config.h using angle brackets instead of quotation marks. + + Fixes . + +2021-02-11 G. Branden Robinson + + Add regression test for Savannah #60025. + + * tmac/tests/doc_Mt-works.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2021-02-11 G. Branden Robinson + + [ms]: Demote definition of \[yogh] special character escape from + unconditional availability to be defined only if the output + device defines it or if .AM macro is called to enable support + for Berkeley-style accent marks. + + See + https://lists.gnu.org/archive/html/groff/2021-01/msg00000.html + and follow-ups for discussion. + + * tmac/s.tmac (initialization): Move definition of \[yogh] (only + if the output device doesn't already define it) from here... + (AM): ...to here. + +2021-02-08 G. Branden Robinson + + * doc/ms.ms: Use \[ps] special character instead of local + character definition using numeric code point escape, which is + less portable. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report and a suggested patch. + +2021-02-04 G. Branden Robinson + + * tmac/s.tmac (initialization): Call par*define-font-macro with + arguments "CW" and "R" in nroff mode to silence font warnings + from documents using .CW macro in nroff mode. + +2021-02-03 G. Branden Robinson + + * src/preproc/tbl/table.cpp (table::init_output): Save value of + hyphenation maximum consecutive line count register (\n[.hlm]) + more carefully to keep it from being incorrectly parsed as a + decrement, because negative values of \n[.hlm] are valid (in + fact, "-1" is the default). In documents with a large number of + tables, this can lead to a Persian chessboard problem and an + integer overflow (at the groff language level, caught and + handled by src/roff/troff/number.cpp:parse_term()). + + It is wise to wrap a non-literal second argument to the .nr + request in parentheses if assignment is desired and its value + can be negative. See section 5.6.1 ("Setting Registers") of the + groff Texinfo manual. + + Fixes . + +2021-02-03 G. Branden Robinson + + * test-groff.in: Add support for rfc1345.tmac. + +2021-02-02 G. Branden Robinson + + Integrate rfc1345.tmac into build system. + + * contrib/rfc1345/rfc1345.am: Do it. + * Makefile.am: Include contrib/rfc1345/rfc1345.am. + +2021-02-01 G. Branden Robinson + + * src/roff/troff/input.cpp (open_mac_file): Report problem when + attempting to open macro files (-m arguments) and the error is + something other than ENOENT. + (process_macro_file): Update diagnostic to be more precise; the + file couldn't be _opened_, not necessarily _found_, and clarify + that the string being reported back to the user is the argument + to the -m option, not a file name. + (macro_source): Update diagnostic to report that the file + couldn't be _opened_, not necessarily _found_, and include the + nature of the problem. + +2021-01-30 G. Branden Robinson + + [tbl]: Save and restore hyphenation parameters. + + * src/preproc/tbl/table.cpp (table::init_output): When starting + a table, save the hyphenation parameters (\n[.hy], \n[.hla], + \n[.hlm], \n[.hym], \n[.hys]). Restore them in the table reset + macro (confusingly called "3init"), which is called before + performing each diversion and before exiting a table. + + This enables people to, e.g., turn off hyphenation in a table + text block with .nh, just as they can turn off adjustment with + .na, without having to manually reset it. The next text block, + and the material after the table, will not be affected. + + Fixes . + +2021-01-30 G. Branden Robinson + + Add regression test for Savannah #59971. + + * src/preproc/tbl/tests/\ + save-and-restore-hyphenation-parameters.sh: Do it. + * src/preproc/tbl/tbl.am (tbl_TEST): Run test. + +2021-01-30 G. Branden Robinson + + * tmac/tmac.am ($(TMACSTRIPFILES)): + ($(TMACMDOCSTRIPFILES)): Remove unidiomatic for loop which + frustrated parallel make operation. + + Thanks to an anonymous contributor for the report and patch. + + Fixes . + +2021-01-29 G. Branden Robinson + + * doc/ms.ms (Document control settings): Document old FAM string + and new FR string. + +2021-01-29 T. Kurt Bond + + [ms]: Add new string FR to hold an expression for computing the + footnote length relative to the line length, consistently for + single- and multi-column modes, which \n[FL] has never done. + + * tmac/s.tmac: Initialize FR string to "11/12". + (@MC): Compute footnote column width using \*[FR] instead of a + hard-coded "11/12" expression. + (par@init): Compute default \n[FL] using \*[FR] instead of a + hard-coded "11/12" expression. + + * doc/groff.texi (Macro Packages/ms/Document control settings): + * tmac/groff_ms.7.man (Usage/Document control registers): + Document it. + + Fixes . + +2021-01-25 G. Branden Robinson + + * src/roff/troff/env.cpp: Add ADJUST_MAX enumeration constant to + record maximum valid numerical adjustment mode. + (adjust): Verify numeric argument against ADJUST_MAX instead of + a numeric literal. Ignore excessively large values instead of + setting adjustment mode to "right". Update warning diagnostic. + +2021-01-25 G. Branden Robinson + + Add regression test for .ad and .na requests. + + * src/roff/groff/tests/adjustment_works.sh: Do it. + * src/roff/groff/groff.am (groff_TESTS): Run test. + +2021-01-24 G. Branden Robinson + + * doc/groff.texi (Manipulating Filling and Adjustment): + * man/groff.7 (Requests/Request short reference): Clarify + behavior of ".na" and ".ad l". + + Thanks to Bjarni Ingi Gislason for pointing out the potential + for confusion and for his careful review of the new text. + + Fixes . + +2021-01-20 G. Branden Robinson + + * src/roff/grog/grog.pl: Report program name in fatal error + diagnostics. Also drop sentence-ending punctuation since Perl + supplies additional information. + + Continues the long process of fixing Savannah #52463. + +2021-01-19 G. Branden Robinson + + * tmac/an-old.tmac (RE): Style-warn if macro arguments are out + of range or redundant. + + Fixes . + +2021-01-15 G. Branden Robinson + + Improve style of troffrc{,-end} files. Follow established + idioms and make them consistent with each other. + + * tmac/troffrc: + * tmac/troffrc-end: + - Identify files in header comments as part of GNU troff. + + * tmac/troffrc: + - Clarify purpose of .do request. + - Identify .X (set by groff -X) as a register, not a string. + - Remove temporary registers one per line to make + synchronization with foregoing logic easier. Fixes name + space management nits: an undefined string troffrc!Xps was + being removed, and troffrc!{ascii,latin1,utf8,cp1047} were + not being removed despite being defined. + + * tmac/troffrc-end: + - Clarify that file is read after -m file arguments (not "all + macro sets", which can be loaded with .mso after this file + is processed). + - Advise usage of .do for groff extensions. + - Line-break one-off conditionals as troffrc does. + - Add empty string comment to empty string definitions. + +2021-01-14 Dave Kemper + + Commit 87edb525, from 2003, added character U+2026 (HORIZONTAL + ELLIPSIS) to most base groff fonts, but there has been no + kerning information for this character. To produce consistent + typography, it should be kerned the same way as the period, + which is in 818 kern pairs across all the devps fonts. + + Apply the following shell command to the groff description files + of the PostScript fonts. + + for file in font/devps/*[A-Z] + do sed -Ei\~ 's/(.*)(^| )\. (.*)/&\n\1\2u2026 \3/' $file + done + + * font/devps/AB: + * font/devps/ABI: + * font/devps/AI: + * font/devps/AR: + * font/devps/BMB: + * font/devps/BMBI: + * font/devps/BMI: + * font/devps/BMR: + * font/devps/HB: + * font/devps/HBI: + * font/devps/HI: + * font/devps/HNB: + * font/devps/HNBI: + * font/devps/HNI: + * font/devps/HNR: + * font/devps/HR: + * font/devps/NB: + * font/devps/NBI: + * font/devps/NI: + * font/devps/NR: + * font/devps/PB: + * font/devps/PBI: + * font/devps/PI: + * font/devps/PR: + * font/devps/TB: + * font/devps/TBI: + * font/devps/TI: + * font/devps/TR: + * font/devps/ZCMI: Apply above script. + + Fixes . However, this + will need to be done again if afmtodit is used to regenerate the + above files, or afmtodit will need to be modified to add this + kerning information itself. + +2021-01-12 G. Branden Robinson + + * src/libs/libgroff/relocate.cpp (set_current_prefix) [_WIN32]: + Move declaration of `pathextstr` to lie within preprocessor + conditional, since it is dereferenced only there. + +2021-01-10 G. Branden Robinson + + Add support for strsignal(). + + POSIX.1-2008 added strsignal() to the C library and recommended + its use over sys_siglist[], but groff's pipeline management + hadn't been updated in that respect since that time. + + * configure.ac: Check for strsignal(). + * src/roff/groff/pipeline.c (xstrsignal): Return strsignal() if + it is defined. + + Thanks to an anonymous contributor for the report and the patch. + + Fixes . + +2021-01-06 G. Branden Robinson + + * src/libs/libgroff/relocate.cpp (relocatep): Add assertion to + identify logic error if `curr_prefix` is unexpectedly a null + pointer. + (set_current_prefix) [_WIN32]: Allocate memory from heap for + `curr_prefix` only on Windows; on other systems, this file's + searchpath() is used to populate `curr_prefix`, and that + function (except on Windows) performs its own allocation. Fixes + memory leak noted by Ingo Schwarze. + (set_current_prefix) [!_WIN32]: Move logic attempting to set + `curr_prefix` by calling searchpathext() from here... + [WIN32]: ...to here. The PATHEXT environment variable has + semantics only under Windows, not POSIX systems, so the + placement of this code seemed erroneous. + + See . + +2021-01-06 Colin Watson + + * contrib/glilypond/glilypond.pl: + * contrib/gperl/gperl.pl: + * contrib/gpinyin/gpinyin.pl: + * tmac/hyphenex.pl: Avoid Perl's unsafe "<>" operator. + + The "<>" operator is implemented using the two-argument form of + "open", which interprets magic such as pipe characters, allowing + execution of arbitrary commands which is unlikely to be + expected. Perl >= 5.22 has a "<<>>" operator which avoids this, + but also forbids the use of "-" to mean the standard input, + which is a facility that the affected groff programs document. + + ARGV::readonly would probably also fix this, but I fundamentally + dislike the approach of escaping data in preparation for a + language facility to unescape it, especially when the required + escaping is as non-obvious as it is here. (For the same reason, + I prefer to use subprocess invocation facilities that allow + passing the argument list as a list rather than as a string to + be interpreted by the shell.) So I've abandoned this dubious + convenience and changed the affected programs to iterate over + command-line arguments manually using the three-argument form of + open. + + glilypond doesn't need the initial unshift since that's already + handled in contrib/glilypond/args.pl. + + Fixes . + +2021-01-06 G. Branden Robinson + + * tmac/s.tmac: Set footnote line length in multi-column + environments to 11/12ths of the text line length for consistency + with earlier change to FL register default. + + Thanks to T. Kurt Bond for bringing this issue to my attention. + +2021-01-04 John Gardner + + * tmac/strip.sed: Escape '.' wildcard when matching lines using + .as and .ds requests. + + Fixes . + +2021-01-04 G. Branden Robinson + + Document use of SOURCE_DATE_EPOCH and TZ. + + The semantics of SOURCE_DATE_EPOCH to groff were not established + with respect to time zone selection, prompting divergent + interpretations; Debian and distributions derived from it have + for several years patched groff to implicitly use UTC as the + time zone when interpreting the current time (or + SOURCE_DATE_EPOCH) as a local time. While a convenient and + defensible choice for reproducible build efforts[1], it runs + against the grain of user expectations. Systems programmers + like monotonically increasing clocks; the broader user base + usually prefers a clock that follows an applicable civil + calendar. To the latter audience, a difference between + $ date "+%Y-%M-%d %H:%m:%S" + and + $ groff <. + + [1] https://reproducible-builds.org/docs/source-date-epoch/ + +2020-12-25 G. Branden Robinson + + * doc/doc.am (.texi.dvi): Call texi2dvi with FORCE_SOURCE_DATE=1 + in the environment, avoiding an embedded timestamp in the + generated groff.dvi file, which frustrated reproducible builds. + Thanks to Werner Lemberg for the suggestion. + + * src/roff/groff/tests/string_case_xform_unicode_escape.sh: Fix + test to no longer use Bash process substitution, resulting in + nondeterministic file descriptor numbers appearing in test logs, + frustrating reproducible builds. + + * contrib/pdfmark/pdfmark.am (PDFROFF): Call pdfroff without + `--keep-temporary-files` option. Temporary directories are + created with mktemp(1) and files with an embedded process + identifier, which frustrates reproducible builds. + + See . + +2020-12-21 Dorai Sitaram + + * tmac/s.tmac (@IP): Handle inter-sentence space correctly in + paragraph tags by copying \n[.sss] from the enclosing + environment to that used to format the paragraph tag. + + Fixes . + +2020-12-21 G. Branden Robinson + + Add regression test for Savannah #59742. + + * tmac/tests/s_IP_respects_inter-sentence_space_in_tags.sh: Do + it. + * tmac/tmac.am (tmac_TESTS): Run it. + +2020-12-21 Bjarni Ingi Gislason + + * src/utils/addftinfo/addftinfo.cpp (usage): Use size_t for loop + index when iterating over a count of size_t items. Quiets + signedness mismatch compiler warning. + + Fixes . + +2020-12-20 Colin Watson + + * src/devices/gropdf/gropdf.pl: + * src/utils/afmtodit/afmtodit.pl: Sort Perl hash keys. Hash + iteration order may differ between runs, which makes builds + harder to reproduce. Sort hash keys in gropdf and afmtodit + output to avoid this. + +2020-12-20 G. Branden Robinson + + * doc/ms.ms (Basic Information): Tweak unit definitions. groff + defines a typesetter's point as precisely 1/72 inches. Also use + the correct symbol for inch units--strictly, it's the same as + that for "seconds" as in subdivisions of the degree, and not a + typographical quote of any sort. + + Fixes . + +2020-12-20 G. Branden Robinson + + [ms]: Set footnote line length to AT&T default. + + groff ms has since its initial implementation used a default + footnote line length of 5/6ths of the text line length; this may + correspond to an early AT&T ms default (perhaps documented in + the 1974 version of the M. E. Lesk paper, "Typing Documents on + the UNIX System"[1]). However, as early as V6 Unix (1975), AT&T + ms actually used a footnote line length of 11/12ths of the text + line length instead[2]. + + Heirloom Doctools and neatroff ms also use this default. + + * tmac/s.tmac: Set default footnote line length to 11/12ths of + the text line length. + + * doc/groff.texi (ms Document Control Settings): + * doc/ms.ms (Document control registers): Document new default. + + [1] https://www.troff.org/using-ms.pdf + [2] https://minnie.tuhs.org/cgi-bin/utree.pl?file=V6/usr/lib/tmac.s + +2020-12-09 G. Branden Robinson + + Lower new unplanted trap error to 'mac' warning. + + * src/roff/troff/div.cpp (top_level_diversion::change_trap): + Change error upon invalid attempt to move an unplanted trap into + a warning of type 'mac'. + + * doc/groff.texi (Warnings): + * src/roff/troff/troff.1.man (Warnings): Recast description of + 'mac' warning type to include the above scenario. + + Thanks to Bjarni Ingi Gislason for reporting the diagnostic + arising in real life, and to Peter Schaffter for the discussion + and recommendation. Some bike sheds get painted quickly! + + Fixes . + +2020-12-05 G. Branden Robinson + + * tmac/groff_mdoc.7.man: Tweak mandatory macro explanations. + + Update descriptions and template of .Dd, .Dt, .Os usage to + reflect recent changes and recommended conventions. + + Thanks to Ingo Schwarze, Colin Watson, and Alan D. Salewski for + the discussion, and Florent Rougon and Robert Bihlmeyer (many + years ago) for the original report. + + Fixes . + +2020-12-01 G. Branden Robinson + + * src/utils/xtotroff/xtotroff.c (MapFont): Avoid writing past + the end of a static buffer. Problem found and patch supplied by + Bjarni Ingi Gislason. I tweaked it to comment it differently + {in case the buffer ever needs to grow, but the prospects of + future X11 server-side font rendering development seem dim} and + use snprintf() instead of retaining the existing sprintf(). + + Fixes . + +2020-12-01 G. Branden Robinson + + * src/utils/xtotroff/xtotroff.c (CanonicalizeFontName) + (FontNamesAmbiguous, MapFont, main): Format diagnostic messages + more consistently with GNU Coding Standards. Prefix with name + of complaining command. Put argument literals in quotation + marks. Put each message on one line only. + +2020-11-28 G. Branden Robinson + + * doc/groff.texi (Parameters): Fix error in example. Arguments + to .als were in the wrong order (.als is not ln(1)). Also mark + output to the standard error stream using the @error Texinfo + command instead of @result. + + Thanks to Dorai Sitaram for finding this error. + + Fixes . + +2020-11-28 G. Branden Robinson + + * doc/groff.texi (Debugging): Update with a more helpful + introduction, summarizing available procedures. Mention + backtracing since it is much more useful now (post-groff + 1.22.4.) + + * man/groff.7 (Debugging): Add new section summarizing + material added to our Texinfo manual. + + * man/groff_diff.7.man (Debugging): Add new section describing + groff extensions. + +2020-11-22 G. Branden Robinson + + * doc/groff.texi (Traps): Update. Organize subsubsections "Page + Location Traps" and "Diversion Traps" under new subsection node + "Vertical Position Traps" to make the conceptual organization + more clear. Define and discuss trap visibility earlier. + Document unit used for page location trap reporting. Introduce + analogy of .wh and .ch requests as queue operations. Document + what happens when the same macro is planted as a trap in + multiple locations; supply example. Supply example of .itc + usage. Consistently refer to an end-of-input macro as such, to + contrast it with the "end macro" that can be used with, e.g., + .de and .ig requests. + + * man/groff.7 (Traps): Add new section summarizing + language feature. + +2020-11-18 G. Branden Robinson + + * tmac/mdoc/doc-common-u (doc-footer): When performing + double-sided page layout, set page number on outside of _recto_ + {odd-numbered} pages, as is conventional and for consistency + with man(7). + + * tmac/groff_mdoc.7.man + (Formatting with groff, troff, and nroff): Document what + double-sided layout (not "printing") means. Also correct + description of continuous rendering, which implied that page + headers and footers were not written at all, and used an + incorrect groff driver name. + + Fixes . Also see: + https://lists.gnu.org/archive/html/groff/2019-01/msg00021.html + Thanks to Ralph Corderoy for the discussion. + + * tmac/tests/doc-D_places_page_numbers_correctly.sh: Test it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2020-11-18 G. Branden Robinson + + * tmac/mdoc/doc-common-u (doc-header): Fix infinite loop when + attempting to trim header string (like "FTP(1)") to fit when the + available title length won't allow even extreme shortening. + Measure the string before and after calling .substring on it, + and break out of loop if it didn't get shorter. + + Problem dates back to at least + ed63b0ae76a611b581601a1afc192f6a7367be6f (7 July 2002), possibly + as far as the Great Mdoc Rewrite of + 058f72af832fc68488d33cd09ec819e5c560fa09 (23 March 2001). + + One can never check loop invariants too many times... + + Fixes . + + * tmac/tests/\ + doc-do_not_loop_infinitely_when_shortening_headers.sh: Test it. + * tmac/tmac.am (tmac_TESTS): Run test. + +2020-11-18 G. Branden Robinson + + * src/roff/nroff/nroff.sh: Recognize -b and -z options and pass + them through to troff. Document them in usage message. + * src/roff/nroff/nroff.1.man: Document new -b and -z options. + +2020-11-17 G. Branden Robinson + + * src/roff/troff/div.cpp (top_level_diversion::change_trap): + Emit error diagnostic if an attempt is made to move an unplanted + macro. This could have been a warning, as it's pretty harmless + {though possibly a big surprise to anyone who was wondering why + their .ch was a no-op}, but there's no good warning category for + this kind of problem and I am not about to start a bike shed + discussion about it right now. + +2020-11-15 G. Branden Robinson + + * doc/groff.texi: Update. Add introductory material. Rewrite + the first section of the "gtroff Reference" chapter of our + Texinfo manual. It is written as an introduction for readers + who want to go straight to "raw" troff without knowing much or + anything about existing macro packages. Thanks to Dave Kemper + and John Gardner for feedback and support. + + Clarify whitespace usage. "Whitespace" is defined in this + manual as "spaces, tabs, and newlines". Say only "spaces and + tabs" when newlines should not be included. + + Rename "Font Files" to "Device and Font Files". + + Rename "Manipulating Filling and Adjusting" to "Manipulating + Filling and Adjustment". + + Update discussion of "copy mode". Rename from "copy-in mode", + which I don't think eludicdated anything; is there a "copy-out + mode"? Rename nodes accordingly. Attempt to explain more + clearly. Recast to shift emphasis to what _isn't_ merely copied + in copy mode, since that is what seems to cause confusion among + the inexperienced. + + Update "Conditionals and Loops". Add introductory paragraph. + Add nodes/subsections "if-then" and "Conditional Blocks". Add + subsection "Conditional Blocks" to explain the behavior of the + \{ and \} escapes much more precisely. I don't think this + syntactical area is well understood. Supply examples. + +2020-11-14 G. Branden Robinson + + Add style checks to man(7) macro package. + + Not otherwise documented yet; experimental--subject to change. + + * tmac/an-old.tmac: Initialize CHECKSTYLE to false if not + already set. + (an-style-warn): New macro emits diagnostic of type "style" when + called if CHECKSTYLE register is true. + (TH): Call an-style-warn if fewer than two or more than five + arguments are seen. + (RI, IR, IB, BI, RB, BR): Call an-style-warn if fewer than two + arguments are seen. + +2020-11-11 Bertrand Garrigues + + Update copyright. + + * update-copyright.sh: use gnulib's 'update-copyright' script. + Pass this script in directories 'arch', 'contrib', 'font', + 'man', 'tmac', 'src' and on a list of extra files. + + * FOR-RELEASE: mention this point. + +2020-11-11 G. Branden Robinson + + * src/preproc/preconv/preconv.1.man (Description): Fix error: + groff's -K option, not -k, specifies a character econding (and + overrides GROFF_ENCODING in the environment). Also explain how + valid encoding strings are determined. + + Thanks to Bjarni Ingi Gislason for the report. + + Fixes . + +2020-11-11 G. Branden Robinson + + * src/preproc/tbl/table.cpp (table::compute_separation_factor): + Add word "table" to diagnostic message to better cue the user + that it is produced by roff that has been injected into the + document by the tbl(1) preprocessor. The other 3 such possible + diagnostic messages already do this. Thanks to Bjarni Ingi + Gislason for bringing the inconsistency to light. + + Fixes . + +2020-11-07 G. Branden Robinson + + * tmac/groff_mdoc.7.man (Predefined strings): Ensure the table + fits even on ASCII and Latin-1 terminals. Thanks to Bjarni Ingi + Gislason for the report. + + Fixes . + +2020-11-01 G. Branden Robinson + + * tmac/groff_mdoc.7.man (General text domain/Enclosure and + Quoting Macros): Fix errors in macro descriptions. + <.Dq>: Encloses its arguments in directional double quotes where + available. + <.Eq>: Misrendered example; say "XstringY" rather than + "XXstring". + <.Sq>: Encloses its arguments in directional single quotes where + available. + +2020-10-31 G. Branden Robinson + + Add support for CS and CT registers to mdoc(7), just like in + man(7), from a year ago. + + * tmac/doc.tmac-u (doc-print-recursive): Call .stringup on each + argument if register doc-do-capitalize is true. + * tmac/mdoc/doc-common-u (Dt): Call .stringup on + doc-document-title if \n[CT] is true. + (Sh): Set doc-do-capitalize to value of \n[CS]. Set + doc-do-capitalize false before returning. + * tmac/mdoc/doc-ditroff-u: + * tmac/mdoc/doc-nroff-u: Set CS and CT registers to 0 (false) + if the user has not defined them. + + * tmac/groff_mdoc.7.man \ + (Formatting with groff, troff, and nroff): Document it. + + * tmac/tests/doc-CS_works.sh: + * tmac/tests/doc-CT_works.sh: Test it. + * tmac/tmac.am (tmac_TESTS): Run tests. + +2020-10-31 G. Branden Robinson + + * src/roff/troff/input.cpp (do_overstrike, do_bracket) + (do_name_test, do_expr_test, do_zero_width, do_width) + (do_special, do_if_request, read_color_draw_node): Improve + diagnostic messages for missing closing delimiters by describing + the incomplete structure and the problem token. + (read_rgb, read_cmy, read_cmyk, read_gray): Improve English + syntax of diagnostic message when color definition missing. + +2020-10-31 G. Branden Robinson + + * tmac/mdoc/doc-ditroff-u: + * tmac/mdoc/doc-nroff-u: Recognize but ignore the groff_man(7) + string HF and registers FT, IN, P, SN, and X (by initializing + them empty or zero if they are not set). This reserves them so + that they don't become used for divergent purposes. man(1) + programs set these and other parameters already handled (like + LL) to configure page rendering, and it would break the + macro-package agnosticism afforded by andoc.tmac to expose + different externally-programmable registers and strings. + * tmac/groff_mdoc.7.man \ + (Formatting with groff, troff, and nroff): Document this. + +2020-10-31 G. Branden Robinson + + * tmac/s.tmac: Implement \*< and \*> strings for subscripting. + groff ms has had (extension) strings for superscripting since + 1991 at the latest, and the asymmetry possessed me of a madness. + Both pairs of string names follow similar usage in Eric Allman's + "me" macros. + + * NEWS: + * doc/groff.texi: + * tmac/groff_ms.7.man: Document it. + +2020-10-31 G. Branden Robinson + + * tmac/groff_mdoc.7.man (Predefined strings): Fix error: the + \*[Lq] and \*[Rq] strings degrade to neutral double quotes (") + on "nroff" devices (-Tascii and -Tlatin1), not "``" and "''". + +2020-10-31 G. Branden Robinson + + * tmac/s.tmac (ds*end!0): Improve diagnostic to mention .RD. + +2020-10-30 G. Branden Robinson + + * tmac/s.tmac: Revise diagnostic messages. Define a common + prefix string, starting all such messages with "s.tmac". + Continues the long process of fixing Savannah #52463. Drop the + word "macro" from diagnostic since this will now be clear from + the prefix. Prefix every macro name in a diagnostic message + with a leading dot; this was already done in four cases. + (cov*first-page-init): Use temporary string to avoid multi-line + diagnostic message. + (@NH): Use temporary string to prevent overlength line. + + A further benefit of this revision is that index information + produced by ms's .IX macro (which writes to the standard error + stream) will now be trivially easy to extract even for documents + that cause diagnostic messages. One can simply filter them with + grep -v '^s\.tmac:' + or similar. + +2020-10-28 Ingo Schwarze + + * man/roff.7.man, tmac/groff_man.7.man.in: Correct man(7) + history. + +2020-10-26 G. Branden Robinson + + Fix ms .R macro to work as documented, by handling its arguments + instead of ignoring them. + + * tmac/s.tmac (R): Delete. During set up, call + par*define-font-macro for R font just as we do for B, I, and BI. + + Problem dates back at least to groff 1.02, June 1991. + + * tmac/tests/s_R-handles-its-arguments.sh: Test it. + * tmac/tmac.am (tmac_TESTS): Run test. + + Fixes . + +2020-10-25 G. Branden Robinson + + Fix ms .TC macro by allowing it to actually use lowercase Roman + numerals for the page(s) of the table of contents when a custom + title (header or footer) is defined containing '%'. + + As a side effect, eliminate the PN register, which was + apparently misused because it was undocumented and had a name + just long enough to be both suggestive and ambiguous. Another + pin goes into my Ken Thompson voodoo doll. + + * tmac/s.tmac (IX): Write out page number of index term(s) using + the % register (instead of PN), obtaining whatever format is + assigned to the register at that time. + (CH): Similarly, output %, not PN, in the center of the default + heading. + (PT): Save the format of %, set it to decimal, copy its value to + a new register, pg*page-number-in-decimal, then restore %'s + previous format. Compare the new register, not %, to 1 to + determine whether special page one behavior should be used. + (pg*end-page): Assign pg*next-format to %, not PN. + (XA): Define toc*num with the interpolation of %, not PN. + + * tmac/tests/s_TC-works-with-percent-in-custom-titles.sh: Test. + * tmac/tmac.am (tmac_TESTS): Run test. + + Problem appears to be very old; as I read it, Larry Kollar was + complaining of it in his ms.ms document over 20 years ago. + + Fixes . + +2020-10-25 G. Branden Robinson + + * man/groff.7 (Requests/Request short reference) <.af>: Fix + error; "l" is not a valid register format. Explain what the + request does, and the default format, as tersely as possible. + +2020-10-22 G. Branden Robinson + + Use only `malloc()` and `free()` to manage memory of paths + opened by the parser instead of mixing in C++ new/delete + management under some runtime-dependent circumstances. + + * src/libs/libgroff/relocate.cpp (relocatep): Use `malloc()`, + not new. + * src/roff/troff/input.cpp (process_macro_file) + (process_startup_file, macro_source): Use `free()`, not + `{a_,}delete()`. + + Thanks to an anonymous contributor for the report and patch. + + Fixes . + +2020-10-22 G. Branden Robinson + + * man/groff_char.7.man (Description/Special character escape + forms): Clarify discussion of Unicode Normalization Form D and + its applicability to code points acceptable in Unicode numeric + special character escapes. Also document that these escapes + must use uppercase hexadecimal digits. + + Attempts once again to slay the unkillable beast that is + . + +2020-10-21 Ingo Schwarze + + On systems without NAME_MAX, use FILENAME_MAX as a last resort. + + Problem reported by Eli Zaretskii + on MS Windows in https://savannah.gnu.org/bugs/?55449 + +2020-10-20 G. Branden Robinson + + * src/roff/troff/env.cpp (environment::possibly_break_line): + Emit break warning and return if the output width is not + positive. The code assumes that it will be and loops infinitely + if it isn't. I _think_ this is because we're not able to get + width data for (some?) CJK glyphs. Based on a patch by Osamu + Sayama. + + * src/roff/groff/tests/\ + do_not_loop_infinitely_when_breaking_cjk.sh: Test it. + * src/roff/groff/groff.am: Run test. + + Fixes . + +2020-10-20 G. Branden Robinson + + * src/preproc/tbl/table.cpp (table::init_output): Save the value + of \n[.tabs] when starting a table. In the reset macro, restore + the saved value. + + Based on a patch by Bjarni Ingi Gislason (tweaked to use a more + normative preprocessor symbol; "REG"s aren't "NAME"s). + + * src/preproc/tbl/tests/save-and-restore-tab-stops.sh: Test it. + * src/preproc/tbl/tbl.am (tbl_TESTS): Run test. + + Fixes . + +2020-10-20 G. Branden Robinson + + * src/roff/nroff/nroff.sh: Recognize -E option and pass it + through to troff. Document it in usage message. + * src/roff/nroff/nroff.1.man: Document new -E option. + + Based on a patch by Ingo Schwarze. + + Fixes . + +2020-10-18 G. Branden Robinson + + * tmac/an-old.tmac: Stop remapping ` and '. Our own pages now + appear to be clear of wrong-quote problems, so let's make them + visible if they recur. Those who don't want to fix bad man + pages (distributors, site admins) can restore the mappings in + their man.local files. + +2020-10-18 G. Branden Robinson + + * tmac/an-old.tmac (an-warn): New; emits warning diagnostic. + (R): Use new macro instead of .tm* requests directly. + +2020-10-18 Ingo Schwarze + + #include "config.h" before + + Required with e.g. gcc 4.2.1 because gnulib/lib/stdio.in.h + uses the "restrict" keyword since this gnulib commit: + commit 182afcba2635cbff91240656c7fb3742dd23ab6f + Author: Bruno Haible + Date: Sat Feb 22 20:57:30 2020 +0100 + + Otherwise, the build may die from the declaration of + various printf-like functions with messages like: + ./lib/stdio.h:851: error: expected ',' or '...' before 'fp' + + * src/libs/libgroff/assert.cpp, src/libs/libgroff/errarg.cpp, + src/libs/libgroff/error.cpp, src/preproc/eqn/eqn.ypp: + #include "config.h". + +2020-10-18 Bertrand Garrigues + + hpftodit: incorrect 'delete' after new[] + + * src/utils/hpftodit/hpftodit.cpp (output_font_name): use + 'delete[]'. + + Fixes bug #55331. Found by David Binderman, fixed by Ingo + Schwarze. + +2020-10-18 Bertrand Garrigues + + preconv: don't use libuchardet if input is stdin + + * src/preproc/preconv/preconv.cpp (do_file): don't call + detect_file_encoding if input file is "-" + + This fixes the failure on MS-Windows described #55334, however + this does not fix the encoding detection with uchardet if the + input is stdin (the user would have to pass with -D the correct + encoding as explained in the man page). + +2020-10-17 G. Branden Robinson + + * src/preproc/eqn/lex.cpp (troff_defs): Set the "..." token on + the baseline, not vertically centered, aligning the actual + behavior with what our eqn(1) man page has claimed since 2007. + + Fixes . + +2020-10-17 G. Branden Robinson + + * src/devices/grops/grops.1.man + (Usage/TrueType and other font formats): Remove dead URL to + ttftot42 utility. Update URL to fontforge tool. Replace much + of the discussion with an example, motivated by Jordan Torbiak's + "groff-install-font" script on GitHub Gist, of how to add the + Roboto Slab Regular font to a user-local groff font directory + {and how to test it, too}. + + Fixes . + +2020-10-17 G. Branden Robinson + + * src/utils/afmtodit/afmtodit.pl: Report program name in warning + diagnostics. + + Continues the long process of fixing Savannah #52463. + +2020-10-17 G. Branden Robinson + + * tmac/an-old.tmac: Add fallback for lq, rq strings. + + Define \*(lq and \*(rq as '"' if the output device has no \(lq + or \(rq special character escapes defined (respectively). + + This is a bit belt-and-suspenders for groff since our output + devices all guarantee availability of these glyphs, but if this + macro file gets used with other implementations (and if they + support the 'c' conditional), it should prevent the strings from + producing empty output. + + Man page writers should simply use \(lq and \(rq unless they are + aiming for pathological levels of portability (e.g., composing + man pages today for consumption on simulators of 1980s Unix + systems). + +2020-10-16 G. Branden Robinson + + * tmac/an-old.tmac: Define an-end with .de1. We need to define + an-end with de1 (execute macro with compatibility mode off) + because, as of 37b4180a27a6eeaea429e40ec278abefcda7f3a7 (11 + October), it can now be called from a trap executing in a + context whence compatibility mode might be on (namely, + "reload-doc" in andoc.tmac). + +2020-10-16 G. Branden Robinson + + * src/preproc/eqn/main.cpp (main): + * src/preproc/pic/main.cpp (main): + * src/preproc/tbl/main.cpp (main): + * tmac/eqnrc: + * tmac/troffrc: Perform checks of register and macro definitions + with a .do request, since we might be in compatibility mode. + +2020-10-16 G. Branden Robinson + + * src/roff/troff/input.cpp (do_if_request): Emit warning of type + "syntax" if a groff conditional expression extension is used + when compatibility mode is active. + + * doc/groff.texi: + * src/roff/troff/troff.1.man: Update description of "syntax" + warning type to be more general. It was inaccurate, referring + only to "dubious syntax in numeric expressions", which was not + the case. Instead it was being used only for poor construction + of character classes with the .class request. + +2020-10-16 G. Branden Robinson + + * src/preproc/tbl/main.cpp (main): Stop ignoring -T. GNU tbl + was undocumentedly ignoring the -T option; apparently IRIX tbl + implemented it, something on the system called tbl with that + option (I'm guessing IRIX's man(1)) and its users spammed James + Clark with bug reports. We can probably weather the volume of + such spurious reports from IRIX users today. + +2020-10-16 G. Branden Robinson + + * src/preproc/tbl/main.cpp (main): Clarify fatal diagnostic in + generated document by informing the user that the program is + aborting, and also that it is groff extensions that are required + rather than GNU troff per se (since Heirloom Doctools troff + claims groff extension support via the .g register). + +2020-10-14 Ingo Schwarze + + In groff(1), fix the combination of -v with -k, -j, and -J. + + * src/roff/groff/groff.cpp: Pass the -v option through to the + preconv, chem, and ideal preprocessors, just like for all + other preprocessors, to print the version of the preprocessor + and to avoid garbage output. + + Bugfix patch from Eli Zaretskii + submitted in: https://savannah.gnu.org/bugs/?55297 + +2020-10-12 Bertrand Garrigues + + Update 'gnulib' submodule. + + * gnulib: now points on d60a35e94c4f5b8f09f15828242418f5073d46e7 + from 'gnulib' repository. + + * configure.ac: minimum autoconf version is now 2.64 due to + gnulib upgrade. + + * FOR-RELEASE: add the gnulib update to the checklist. + +2020-10-11 G. Branden Robinson + + * tmac/andoc.tmac: When switching between macro packages in + andoc and using continuous-rendering mode, flush any partially + collected output line and write page footer. + (reload-doc): Call an-end if it is defined. + (reload-man): Call doc-end-macro if it is defined. + * tmac/tests/andoc-flush-between-packages.sh: Add regression + test. + * tmac/tmac.am (tmac_TESTS): Run test. + + Fixes . + +2020-10-11 G. Branden Robinson + + * tmac/andoc.tmac: Remove traps set by mdoc package by the names + they actually use. + * tmac/tests/andoc-clear-doc-traps.sh: Add regression test. + * tmac/tmac.am (tmac_TESTS): Run test. + + Fixes . + +2020-10-10 G. Branden Robinson + + * src/preproc/tbl/table.cpp (table::init_output): In the release + macro written to the output, reword the warning diagnostic that + is emitted when a table row is to be output without enough room + before the next page location trap. The former wording said + that a "text block" would not fit on the page, and that is + normally how table rows grow longer than one line in the first + place. However, there are other ways the conditional can be + satisfied, as witnessed in Savannah #57665, so simply say what + is known; that the table _row_ overruns the space to the next + trap (we say the row won't "fit on [the] page"). + + Fixes . + +2020-10-10 G. Branden Robinson + + * src/preproc/tbl/table.cpp + (double_line_entry::double_line_entry): + (double_line_entry::simple_print): Remove garbage lines + inadvertently added in previous commit. + +2020-10-09 G. Branden Robinson + + Stop tbl from injecting spurious blank lines (and emitting + spurious warnings about tables and "text blocks" not "fitting on + a page") into long tables in man pages when continuous rendering + is used (the default for nroff output devices). + + * src/preproc/tbl/table.cpp (USE_KEEPS_REG): New preprocessor + symbol stores name of groff register for dynamic determination + of keep usage. + (table::init_output): If the NOKEEP flag is not set, then in + generated groff output, see if the usekeeps register is defined; + if not, define it and enable usage of keeps. + (table::do_row): In groff output, check usekeeps register before + calling keep and release macros. + (table::do_bottom): In groff output, check usekeeps register + before calling release macro. + + * tmac/an-old.tmac (TS): Set the usekeeps register used by tbl + to the logical complement of the man(7) cR (continuous + rendering) register. + + * tmac/tests/an-old_TS_do_not_keep_tables_when_cR_set.sh: Add + regression test. + * tmac/tmac.am (tmac_TESTS): Run test. + + Problem appears to date back to the introduction of continuous + rendering in groff 1.17 (3 May 2001). + + Fixes . + +2020-10-09 G. Branden Robinson + + * src/preproc/tbl/table.cpp (simple_entry::position_vertically): + (block_entry::position_vertically): + (table::determine_row_type): + (printfs): Update assertions to indicate what actually went + wrong. + +2020-10-02 G. Branden Robinson + + * src/roff/troff/node.cpp: Make diagnostics slightly more + informative in unusual error cases. + (real_output_file::~real_output_file): If ferror() reports error + status on a stream say that, instead of "error writing". If it + does not, but fflush() fails on the stream, describe the flush + as failing, and use strerror() since fflush() sets errno. If + pclose() fails, say that we were unable to close a pipe instead + of repeating the name of the C library function to the user, who + might not be a C programmer. Report strerror() in this case and + for a failing fclose(). + (real_output_file::flush): Repeat updated fflush() logic from + previous function. + +2020-09-30 G. Branden Robinson + + * tmac/an-old.tmac (register setup): Make interaction of \n[C] + register and HTML output more clear in code and comments. + +2020-09-30 G. Branden Robinson + + * src/roff/groff/tests/regression_savannah_59202.sh: Reduce test + case. + +2020-09-29 G. Branden Robinson + + Fix SEGV arising from recursing destructor. + + * src/roff/troff/node.h (output_file): Add class member + `is_dying` to track whether destructor has already been entered; + initialize false. + * src/roff/troff/node.cpp (real_output_file::~real_output_file): + Set `is_dying` true when destructor entered. + * src/roff/troff/div.cpp (cleanup_and_exit): Only delete + `the_output` object if it is not already being destroyed. + * src/roff/groff/tests/regression_savannah_59202.sh: Add test. + * src/roff/groff/groff.am (groff_TESTS): Run test. + + Thanks to "hackerb9" for reporting the problem. Problem appears + to date back to groff 1.02 (June 1991) or earlier. + + Fixes . + +2020-09-28 G. Branden Robinson + + * tmac/an-old.tmac (register setup): Condition decisions on + \n[an-html] rather than a string comparison using \*[.T]; that + is what the register is there for. + +2020-09-28 G. Branden Robinson + + * tmac/andoc.tmac: Save alias to .ne request. + (reload-doc): Restore .ne request, which an-old.tmac meddles + with if continuous rendering is used. (The meddling ultimately + dates back to 777e2d262862621966c18d685a000cc88f432bc6, 26 + January 2002, which simply redefined .ne as empty on nroff + devices.) + +2020-09-27 G. Branden Robinson + + Ship tests in distribution archive. + + * src/preproc/preconv/preconv.am (EXTRA_DIST): + * src/roff/groff/groff.am (EXTRA_DIST): + * src/roff/nroff/nroff.am (EXTRA_DIST): + * tmac/tmac.am (EXTRA_DIST): Add + $({preconv,groff,nroff,tmac}_TESTS), as appropriate. + + * src/roff/nroff/nroff.am (MOSTLYCLEANFILES): Stop adding + $(nroff_TESTS), which can only have unhappy consequences. + +2020-09-27 G. Branden Robinson + + * tmac/tmac.am: Fix problem with recently-relocated mdoc macro + files not ending up in the right place in the distribution + archive. + (dist_tmac_DATA): Also include $(TMACUNSTRIPFILES). + (TMACMDOCSTRIPFILES): Rename from $(TMACMDOCFILES). Update + interpolation sites. + (TMACMDOCUNSTRIPFILES): New variable holds mdoc macro files in + the tmac/mdoc subdirectory. Stop adding these files to + $(TMACUNSTRIPFILES) since those reside in tmac/ directly. + (EXTRA_DIST): Add $(TMACMDOCUNSTRIPFILES). + ($(TMACSTRIPFILES)): Depend only on $(TMACUNSTRIPFILES). + ($(TMACMDOCSTRIPFILES)): Add new rule, much like the foregoing. + Depend on $(TMACMDOCUNSTRIPFILES) and copy files into tmac/mdoc. + (dist-hook, tmac-dist-hook): Remove; they no longer do any + distinct work. + + Fixes . + +2020-09-26 G. Branden Robinson + + * src/preproc/tbl/table.cpp (table::init_output): + (table::compute_expand_width): + (table::compute_separation_factor): Use consistent format for + diagnostic messages. + - Do not spread a single diagnostic across multiple lines. + - Report messages in GNU Coding Standards format, that is: + - Report the name of the file the problem is in... + - ...then the line number... + - ...then the diagnostic severity level... + - ...then the specific problem. + +2020-09-26 G. Branden Robinson + + * tmac/an-old.tmac: Emit warnings when configuration registers + are ignored when producing output for HTML. + +2020-09-25 G. Branden Robinson + + * tmac/an-old.tmac (an-p-footer): Define \*[an-page-string] if + (1) the output device is not HTML; (2) \n[X] has been defined; + and (3) the page number has not yet reached the threshold + defined by \n[X]. + + Fixes . + +2020-09-25 G. Branden Robinson + + Add regression test for Savannah #59179. + + * tmac/tests/an-old_X_register_works.sh: Do it. + * tmac/tmac.am (tmac_TESTS): Run it. + +2020-09-25 G. Branden Robinson + + * tmac/an-old.tmac: + * tmac/doc.tmac-u: Emit more informative fatal diagnostic when + installed version of groff is too old. Report the version found + and explicitly note consequent abort. + +2020-09-25 G. Branden Robinson + + * tmac/tmac.am: Regenerate stripped macro files upon changes to + any of their unstripped counterparts. This is crude, but they + weren't being regenerated at _all_. Defeating a central + function of Make is bad. + (TMACUNSTRIPFILES): New variable. Populate with -u files. + ($(TMACMDOCFILES) $(TMACSTRIPFILES)): Depend on + $(TMACUNSTRIPFILES). + +2020-09-25 G. Branden Robinson + + * tmac/an-old.tmac: + * tmac/andoc.tmac: + * tmac/doc.tmac-u: + * tmac/s.tmac: Clarify fatal diagnostics by informing the user + that the program is aborting. + +2020-09-25 G. Branden Robinson + + * tmac/www.tmac.in: Revise diagnostic message handling. + (www:fatal): New macro handles fatal macro usage errors. + (www:lenstr): Use www:fatal instead of writing to standard error + with .tm (rather than www:error) and then calling .ab without + arguments, which produces an unsightly "User Abort." message. + (www:lenstr): + (www:splitstr): + (www:url_breaks): + (www:url_breaks_split): + (LINKSTYLE): Report expected number of arguments in diagnostics. + (www:fontstyle): Shorten diagnostic message. + +2020-09-25 G. Branden Robinson + + * src/roff/troff/div.cpp + (top_level_diversion::clear_diversion_trap): Fix copy and paste + error in diagnostic, which wrongly reported that a top-level + diversion trap couldn't be "set" when "clear"ed was meant. + +2020-09-19 G. Branden Robinson + + * src/preproc/grn/main.cpp (conv): + * src/roff/troff/node.cpp (suppress_node::tprint): Remove + embedded newlines from diagnostic messages. + +2020-09-18 G. Branden Robinson + + * tmac/an-old.tmac: Move setup of remaining rendering option + parameters (registers C, D, P, and X) to end of file. + +2020-09-17 G. Branden Robinson + + * tmac/an-old.tmac (TH): Move setup of rendering parameter + registers IN and SN from here to the end of the file. Update + comments. + +2020-09-17 G. Branden Robinson + + * tmac/an-old.tmac: Drop \*[an-empty] string. This string is + documented as preventing "looping" (presumably infinitely) if + someone calls a two-font macro with an inconvenient parameter; + the example shown is ".RB ( \\ )". This string was being + interpolated at the end of each argument pair to the two-font + macros BI, BR, IB, RB, and RI. This code dates back to groff + 1.10 (dc5351364982f78f8c630f1e856d692d4a82666f, 26 November + 1995). Did you notice a two-font macro missing? It was: IR. + Using it with the proscribed input fails to cause a problem; the + others similarly operate just fine when the empty string + interpolation is removed. Presumably at some point in the past + 25 years, this workaround became unnecessary. + (BI, BR, IB, RB, RI): Remove interpolations of string. + + * tmac/tests/an-old_avoid_two-font_denial_of_service.sh: Add + regression test. + * tmac/tmac.am (tmac_TESTS): Run test. + +2020-09-16 G. Branden Robinson + + * tmac/an-old.tmac: Refactor continuous rendering handling. + Relocate set up of \n[cR] to end of file in parallel with other + rendering parameter management. Instead of conditionally + defining the an-ne and an-bp macros, define them + unconditionally. Also define them with .de instead of .de1, + since they will only be called within the contexts of macros + that are already running with compatibility mode off (i.e., the + public interface macros). Relocate definition of an-end to sit + alongside these other continuous-rendering-mode specific macros + and avoid a forward reference and scattering of \n[cR] + conditionals around the file. + (an-set-up-continuous-rendering): Define new macro to move + macros (and end macro) into place. Call it at the end of the + file only if cR eventually winds up being true. + +2020-09-16 G. Branden Robinson + + * tmac/an-old.tmac: Improve name space management. Rename .ne + request to .an-ne instead of outright clobbering it (and in + parallel with .an-bp). Rename 'an-ne' register to 'an-need' to + prevent confusion with renamed request. + +2020-09-16 G. Branden Robinson + + * tmac/an-old.tmac: Drop .ll hack for LL register. + + Drop the .ll hack for setting the line length on nroff devices. + + Once upon a time, the only way to get man pages to render on a + terminal at any width other than the nroff default of 65n was to + put an .ll request into the page--a mortal sin against + portability--or your man(1) program could sneak such a request + into nroff's input stream. + + Also, long ago, John Eaton of UT Austin wrote a man(1) program. + In a few years this implementation branched into two lines of + development, which I'll call man-db man (Wilford/Polacco/Watson) + and another, Brouwer/Lucifredi man, which as of this writing saw + its last release in 2011 (1.6g). + + The man and mdoc macros of groff 1.18 (July 2002) introduced an + LL register to configure the line length, respecting an -rLL + command-line option. The source change was made by Werner + Lemberg on 3 May 2002 and Colin Watson updated man-db man(1)--on + the same day!--to synthesize the option when calling groff. + + Later, in August 2005, Keith Marshall, a user of version 1.5m of + Brouwer/Lucifredi man(1), which did not set the LL register, + suggested that the existing .ll setting (technically, the value + of \n[.l], the only way the result of an .ll request could be + introspected) be honored in the absence of the LL register. + However, it is impossible to distinguish a user-supplied ".ll + 65n" request from nroff's default setting, which was in that + case overridden to the modern default of 78n. + + And so, in what is now git commit + f9d5df4aebd3d834b4084ffefa52a115e00dce38 (1 September 2005), it + was done. + + This led to (1) surprising behavior for users accustomed to old + methods and desirous of the nroff default and (2) lengthy + apologia in groff source code comments and the groff_man(7) man + page. + + Ironically, Brouwer/Lucifredi man(1) had already added support + for the LL register by the time of its 1.6 release two months + earlier (20 June 2005). (Curiously, it did so similarly to the + old .ll hack, by injecting an '.nr LL' request into groff's + input stream, rather than using the -r command-line option.) + Moreover, Marshall and the groff list were already aware of + this, but the change was accepted anyway because version 1.6 + was "too new"! (Distributions are slow sometimes, true...) + + Let us survey the field in 2020. man-db man(1) has supported + the LL register for eighteen years, and Brouwer/Lucifredi man(1) + for fifteen. Heirloom Doctools's man macros set the line length + to 78n on nroff devices unconditionally. mandoc(1) similarly + also always formats for 78 columns on terminals. groff's + mdoc(7) macros grew support for LL in parallel with man(7) in + 2002 and never added the \n[.l] introspection at all. + + There no longer seems to be any reason to preserve this hack. + + * tmac/an-old.tmac (initialization): Drop complex setup of LL + register. + (TH): Relocate line length reset; no behavior change. + (after .mso man.local): Initialize LL only if the user hasn't; + use device default in troff mode, and 78n in nroff mode. + + * tmac/groff_man.7.man.in (Options) <-rLL>: Stop documenting .ll + hack. + + Fixes . + +2020-09-16 G. Branden Robinson + + * tmac/tests/an-old_LL_init_sanely.sh: Add test. + * tmac/tmac.am (tmac_TESTS): Run test. + +2020-09-15 G. Branden Robinson + + * src/devices/xditview/GXditview.ad: Widen the default geometry + to accommodate the width of a page rendered using the X100-12 + device. Display devices these days have much greater horizontal + resolution than they did 20 years ago. + +2020-09-14 G. Branden Robinson + + * tmac/an-old.tmac: Use correct point size default for + X{75,100}-12 devices. + +2020-09-14 G. Branden Robinson + + * tmac/mdoc/doc-common-u (doc-prepare-section-heading): New + macro defines new string doc-sec-head to enable recognition of + mixed-case section headings in mdoc man pages. For example, + "Name" and "Description" are now recognized in addition to + "NAME" and "DESCRIPTION". + (doc-section-{name,synopsis,library,description,see-also,files, + authors}): Redefine strings to be mixed-case. Add trailing + comment guard per recommended best practice. + (Sh): Call doc-prepare-section-heading instead of + doc-first-parameter, and compare predefined section strings to + doc-sec-head instead of doc-str-dfp. + + * tmac/tests/doc-accept-mixed-case-section-headings.sh: Test it. + * tmac/tmac.am (tmac_TESTS): Run test. + * tmac/tests/doc-smoke-test.sh: Use mixed-case section headings. + +2020-09-03 G. Branden Robinson + + * makevarescape.sed: Use \[] form of special character escapes. + + The only man page we have that doesn't turn compatibility mode + off (neqn) also doesn't use any sed-substituted patterns where + characters replaced by a \[] special character escape form are + likely to be used. + + The @g@ command prefix is the main avenue for intrusion of such + escapes, but I think it improbable that many people are going to + include apostrophes, double quotes, carets, grave accents, or + tildes in the command prefix; some or all of these will pick + fights with the shell and require quoting that we don't + represent in man page text anyway. + + On top of that, neqn is largely a stub page. + + If it's a problem, a better fix than reverting this is to make + neqn switch out of compatibility mode like our other man pages. + +2020-09-03 G. Branden Robinson + + * FOR-RELEASE: Start a release checklist. We probably should + have done the afmtodit.tables update for 1.22.4. There were no + AGL changes and the Unicode decomposition changes were limited + to additions for Balinese (11), CJK compatibility ideographs + (5), and 13 code points outside the Basic Multilingual Plane. + +2020-09-02 G. Branden Robinson + + * src/utils/afmtodit/afmtodit.tables: Regenerate using Unicode + 13.0.0. + +2020-09-02 G. Branden Robinson + + make-afmtodit-tables: Automate AGL reassignments. + + Automate the procedure done manually in + b72b91e85e80a69304e6569db535bcca0e0ecab5 (9 April 2007), so that + it doesn't regress when we regenerate afmtodit.tables. + + * src/utils/afmtodit/make-afmtodit-tables: Do it. + * src/utils/afmtodit/afmtodit.tables: Regenerate it. + +2020-09-02 G. Branden Robinson + + * src/roff/groff/groff.1.man (Options) <-E>: + * src/roff/troff/troff.1.man (Options) <-E>: Document that -E + implies -Ww. + + Fixes . + +2020-09-01 G. Branden Robinson + + * man/groff_char.7.man: Revise glyph descriptions. + + Fixes . + +2020-09-01 G. Branden Robinson + + * tmac/tty.tmac: Define fallback glyphs for Bell System logo + {non-breaking adjustable space} and radical extension and square + root extension (both dummy characters '\&') to suppress warnings + from groff_char(7). As none of these are encoded in Unicode it + seems unlikely they will become supported soon. + +2020-08-30 G. Branden Robinson + + * src/roff/troff/troff.1.man (Options) <-I>: The current working + directory is searched _last_, not first, unless the order is + altered with "-I .". + + * src/roff/groff/groff.1.man (Options) <-I>: Rearrange + description. + +2020-08-25 G. Branden Robinson + + Update mdoc package to honor HY register as man does now, per + suggestion from Colin Watson. Recognize but ignore AD string + for man package compatibility (essentially "reserving" it), + though mdoc intentionally does not permit configuration of + adjustment. + + * tmac/mdoc/doc-ditroff-u: + * tmac/mdoc/doc-nroff-u: Do it. + + * tmac/mdoc/doc-common-u: Initialize \n[doc-hyphen-flags] from + \n[HY]. + + * tmac/groff_mdoc.7.man \ + (FORMATTING WITH GROFF, TROFF, AND NROFF): Document it. + +2020-08-25 G. Branden Robinson + + * tmac/an-old.tmac (TH): Reset inter-word and inter-sentence + spacing to default with each new page rendered. + + {To observe the problem prior to this change, + $ groff -mandoc groff_mmse.7 $any_other_man_page + groff_mmse(7) loads sv.tmac, which changes the sentence + spacing.} + +2020-08-25 G. Branden Robinson + + * PROBLEMS: Undocument the problem with test-groff and mdoc. + It's resolved. + + Fixes . + +2020-08-25 G. Branden Robinson + + * tmac/tmac.am (NORMALFILES, MDOCFILES): Drop unused variables. + ($(TMACMDOCFILES) $(TMACSTRIPFILES)): Scrub trailing whitespace. + Wrap long line. + +2020-08-25 G. Branden Robinson + + mdoc: Relocate within build tree. + + The (modern) mdoc macro package has not been usable within the + build tree, unlike the others. This makes it more troublesome + to test changes, and frustrates deploying our test + infrastructure against it. Re-arrange the build tree to + resemble an installation tree closely enough for the macro + package to load. + + * tmac/doc-common-u: + * tmac/doc-ditroff-u: + * tmac/doc-nroff-u: + * tmac/doc-syms-u: Rename to... + * tmac/mdoc/doc-common-u: + * tmac/mdoc/doc-ditroff-u: + * tmac/mdoc/doc-nroff-u: + * tmac/mdoc/doc-syms-u: ...these. + + * tmac/tmac.am (TMACMDOCFILES): Look for files in tmac/mdoc. + ($(TMACMDOCFILES)): Create tmac/mdoc in build tree. + + Fixes . + +2020-08-25 G. Branden Robinson + + Add regression test for usable in-tree mdoc. + + * tmac/tests/doc-smoke-test.sh: Add test. + * tmac/tmac.am (tmac_TESTS): Run test. + +2020-08-22 G. Branden Robinson + + * tmac/tests/an-old_TH_repairs_ad_damage.sh: + * tmac/tests/an-old_TH_repairs_hy_damage.sh: Add tests. + * tmac/tmac.am (tmac_TESTS): Run tests. + +2020-08-22 G. Branden Robinson + + * tmac/an-old.tmac (TH): Set hyphenation mode to user preference + with each new page rendered, in case a hostile page meddled with + '.hy' or '.nh'. + (after .mso man.local): Relocate setting of default hyphenation + mode here (instead of just before .mso man.local). Eliminate + conditional on \n[an-html]; this doesn't matter because + grohtml(1) doesn't support hyphenation anyway. If it does learn + to hyphenate, we should treat it the same as other output + devices in any case. Add comment explaining why we fall back to + different defaults depending on \n[cR]. + +2020-08-22 G. Branden Robinson + + * tmac/an-old.tmac (TH): Set adjustment to user preference with + each new page rendered, in case a hostile page meddled with + '.ad' or '.na'. + (after .mso man.local): Set the default adjustment mode only if + a -d option or man.local did not. Also do the same for the HF + string; relocate its definition here and make it similarly + conditional. Also update comment on setting of CS and CT + registers and style their conditionals consistently with the + rest of the package. + + * tmac/groff_man.7.man.in (Strings) <\*(AD>: Document it. + (Strings) <\*(HF>: Parallelize language with new \*(AD. + (Options) Expand introductory sentence to discuss -d and -r + options. + (Options) <-dAD>: Document default and likely values. Nobody + right-justifies or centers man page text; send the curious to + groff(7) for '.ad' request documentation. + (Options) <-dHF>: Document default and steer people to groff(7) + for '.ft' request documentation. + +2020-08-21 G. Branden Robinson + + * tmac/an-old.tmac (set-an-margin): Rename... + (an-set-margin): ...to this. It was the only package-internal + register, macro, string, or diversion that wasn't named using + the "an-*" schema. + (TH, SH, SS): Update call sites. + +2020-08-16 G. Branden Robinson + + * tmac/an-ext.tmac (.ME, .UE): Restore hyphenation after + "punctuation" arguments have been output. The next token will + always be a space node, the end of the document, or similar. + + * tmac/tmac.am (tmac_XFAIL_TESTS): Mark the punctuation + hyphenation tests as expected to fail, because they now do. + +2020-08-16 G. Branden Robinson + + * tmac/ps.tmac: Define ordinary hyphen-minus as fallback + character for U+2011 (non-breaking hyphen). Prompted by + discussion with Dave Kemper in Savannah #58390. + +2020-08-15 G. Branden Robinson + + Fix hyphenation bug. The UR/UE and MT/ME macros were much too + aggressive about turning hyphenation off. Disable it only when + writing the actual URL or email address. + + * tmac/an-ext.tmac (.MT, .UR): Stop disabling hyphenation here. + (.ME, .UE): Disable hyphenation right before output of + URL/address; restore it right before output of supplementary + arguments ("punctuation"). + + * tmac/tests/an-ext_ME_punct_hyphenates.sh: + * tmac/tests/an-ext_MT_body_hyphenates.sh: + * tmac/tests/an-ext_UE_punct_hyphenates.sh: + * tmac/tests/an-ext_UR_body_hyphenates.sh: Test behavior. + + * tmac/tmac.am (tmac_TESTS): Run tests. + +2020-08-15 G. Branden Robinson + + Adapt to the fact that \: reĂŤnables hyphenation. Rename + "hyphenless [discretionary] break" to "non-printing break point" + in documentation. + + * doc/groff.texi (Manipulating Hyphenation): Rename "hyphenless + break" to "non-printing break point". Clarify that it is the + soft hyphen glyph, not necessarily a hyphen, that is ordinarily + written to the output on hyphenation breaks. Note that the + remainder of a word after \: is subject to hyphenation as + normal. Note (new) '\:\%' idiom for getting what people will + want at least some of the time. Update example to use it. + * makevarescape.sed: Insert \% after we insert \: to rewrite + slashes in filenames, to protect later portions of the filename + from hyphenation. + * man/groff.7.man (Escape Sequences/Escape short reference): + Rename "hyphenless break" to "non-printing break point". + * man/groff_diff.7.man (Language/Escape sequences): Resync with + our Texinfo manual. + * tmac/groff_man.7.man.in (Description/Hyperlink and email + macros): Rename "hyphenless break" to "non-printing break + point". + +2020-08-15 G. Branden Robinson + + documentation: Re-christen 'ESCAPE_AMPERSAND'. + + s/zero[- ]width space character/non-printing input break/ + + * doc/groff.texi (Requests): Rename. Update conceptual index + entries; retain old name (with an appended "[sic]") to aid + readers accustomed to it. + (Ligatures and kerning): Update conceptual index entries. + Supply context ("effect on kerning"). + (Drawing requests): Update conceptual index entries. Supply + context ("effect on '\l'"). + * man/groff.7.man (Description): Rename in macro-advice-writing + shorthand. + (Escape Sequences/Escape short reference): Rename. + * tmac/groff_man.7.man.in (Description/Command synopsis macros + [style]: Rename. + (Description/Portability) [style]: Rename. + * tmac/groff_mdoc.7.man (TROFF IDIOSYNCRASIES/Macro Usage): + Rename. + (TROFF IDIOSYNCRASIES/Other Possible Pitfalls): Rename. + +2020-08-14 G. Branden Robinson + + * tmac/groff_man.7.man.in (Description/{Document structure + macros <.TH>, Horizontal and vertical spacing}): Fix erroneous + use of "flush left". The current uses were introduced by me, + but the page has borne incorrect uses of it as far back as 1999 + {in the description of .TP}. Simply say "with no indentation" + instead. + +2020-08-13 G. Branden Robinson + + * tmac/groff_man.7.man.in (Description/Number registers): Inform + reader that registers can be set in man.local file and + cross-reference it. + (Files/*/man.local): [style] Supply example of man.local + customizations, prompted by recent discussions on groff, + linux-man, and man-db mailing lists. + +2020-08-12 G. Branden Robinson + + * tmac/tmac.am: Use a stamp file for m4 keyword check. + (M4CHECK): Add stamp file variable. + ($(M4CHECK)): Create stamp file if check succeeds. + +2020-08-12 G. Branden Robinson + + Split groff_man(7) into two pages; one a (relatively) terse + reference and the other a tutorial and style guide. Both are + generated from the same source, which is processed by m4 into + two man page sources. + + * tmac/groff_man.7.man: Rename... + * tmac/groff_man.7.man.in: ...to this. + + * tmac/groff_man.7.man.in: Add m4 directives and define macros. + Protect m4 keywords in English from unintended expansion (this + affected the word "include"). Add new .TH and apropos lines for + style guide. Convert marker comments into m4 macros for content + control. Uncomment material intended only for basic reference + page. + + * tmac/tmac.am (man7_MANS): Add groff_man_style.7. + (EXTRADIST) Add groff_man.7.man.in. + (MOSTLYCLEANFILES): Add m4-generated man page sources + tmac/groff_man{,_style}.7.man. + Add targets to generate those same two pages from the renamed + file. Add target to grep the page for unprotected English m4 + keywords and halt the build if they are found. Make generation + of those pages depend on this new target. + +2020-08-11 G. Branden Robinson + + * tmac/groff_man.7.man: Add material on hooks and encoding. + (Description, ./Deprecated features): Stop identifying .PT and + .BT as "deprecated"; they shouldn't ever be called in man pages, + but that has never been their intention. + (Description): Identify character encoding and line-ending + requirements (tutorial/style-guide material). + (Description/Hooks): Add new subsection to house descriptions of + .PT and .BT. Add mnemonic expansions for both. + +2020-07-31 G. Branden Robinson + + * man/groff.7.man (Control Characters): Incorrect claims were + made. Double quotes can indeed be used to enclose arguments to + string interpolations. The statement about a leading " in a + string definition (or appendment with .as) was stated too + generally. The leading quote is not necessary to include + leading tab characters, which can be input as-is, even in + compatibility mode. + +2020-07-28 G. Branden Robinson + + * man/groff.7.man (Requests/Request short reference/.ft): Fix + some outright damage in the description of the request; the + escape sequences that are synonymous with a nullary .ft had been + wrongly removed. + +2020-07-25 G. Branden Robinson + + * doc/meintro.me: + * doc/meref.me: + * tmac/e.tmac-u: Remove postal address for Eric Allman. It's + probably decades out of date. Adjust footnote symbols. Thanks + to Dave Kemper for the bug report and the patch. Fixes + . + +2020-07-23 G. Branden Robinson + + Migrate macro packages from font CW to CR. The font name "CW" + {"constant-width"} is a legacy item we can dispose of (except + for the DVI device, which also has CWI for "constant-width + italic"), and much of the groff codebase already did starting + with commit 0de1d6d79cdb959ffa7dac3af77c2a36ef31873f {October + 2017}. Courier is available in the usual four styles {roman, + bold, italic, bold+italic}. + + * tmac/an-ext.tmac (.EX): Set font to R, not CW. The existing + .ft request was somewhat redundant with the '.do fam C' + immediately before, which set the font family to Courier. + * tmac/s.tmac (.UC): Use font CR, not CW. + +2020-07-23 G. Branden Robinson + + * tmac/tty.tmac: Stop suppressing nonexistent font warning. + Prompted by a 2017 suggestion and patch from Bjarni Ingi + Gislason. Documents and macro packages that want to change the + font family should do so in awareness that this is meaningless + on terminal (nroff) devices (and -Thtml as well). + + Fixes . + +2020-07-18 G. Branden Robinson + + * tmac/groff_man.7.man (.PP, .LP, .P): Fix error: these macros + do not reset the left margin. + +2020-07-16 G. Branden Robinson + + * doc/groff.texi (Strings): Document behavior of .ds request + when only one argument is supplied. (The string is defined as + empty.) Thanks to Dave Kemper for the report and the patch. + + Fixes . + +2020-07-16 G. Branden Robinson + + * doc/groff.texi (Using Symbols): Fix error in .rfschar + description, which should refer to "font f" rather than "glyph + f". Thanks to Dave Kemper for the report and the patch. + + Fixes . + +2020-07-12 G. Branden Robinson + + * tmac/groff_man.7.man (.EE, .YS): Fix error: refer to "initial + hyphenation setting" instead of "previous hyphenation mode". + Incidentally, this fact points out why putting ".hy 0" or ".nh" + in your man page is futile. + +2020-06-28 G. Branden Robinson + + * man/groff.7.man (Requests/Request short reference): Fix error + in description of .hc; it changes the hyphenation character + rather than supplying an additional one. + +2020-06-12 G. Branden Robinson + + * doc/groff.texi (Groff Options): Remove editorial comment about + '-a' option being "useless". It isn't. Update example for + contemporary systems (like Debian) and to reflect the fact that + the GNU troff(1) man page needs to be preprocessed with tbl(1). + (Invoking grotty): Recast discussion of -c option, importing + much language from grotty(1) page rewrite from a year ago. Add + program index entries for col, more, and ul. Fix transposition + error in ISO document number. + + * src/devices/grotty/grotty.1.man (Description/Legacy output + format): Make slight wording changes prompted by content of + parallel section in our Texinfo manual. + + * src/roff/groff/groff.1.man (Options/-a): Parallelize with + first sentence of corresponding material in our Texinfo + manual. + + * src/roff/troff/troff.1.man (Options/-a): Parallelize with + our Texinfo manual. + + Fixes the rest of + . + +2020-06-12 G. Branden Robinson + + * man/groff_diff.7.man (Language/Long names): Fix error: groff + adds three new requests with short names, not two. List them in + an adjacent comment. + +2020-06-04 G. Branden Robinson + + * tmac/an-ext.tmac (.ME, .UE): Fix portability issue. While + widely supported, the \$* escape is not documented in CSTR #54. + If groff is not the typesetter, append macro arguments using + \$1, \$2, ..., \$9 instead. + +2020-05-19 G. Branden Robinson + + * man/groff.7.man (Numerical Expressions): Fix error: negative + expressions evaluate false, not true as was implied. + Parallelize descriptions with our Texinfo manual and + groff_diff(7) (in abbreviated form). + +2020-05-18 G. Branden Robinson + + * doc/groff.texi (Manipulating Filling and Adjusting): Fix error + in code sample: missing 'n' in number register interpolation. + +2020-05-14 G. Branden Robinson + + * src/preproc/preconv/tests/smoke-test.sh: Make BOM detection + override less hinky (i.e., use more normative input). Add tests + for all five detected BOMs. + +2020-05-09 G. Branden Robinson + + * src/roff/troff/env.cpp (space_size): Prevent assertion + failure. If an argument to the .ss request is negative, throw a + range warning and ignore it. + * src/roff/groff/tests/regression_savannah_58337.sh: Add test. + * src/roff/groff/groff.am (groff_TESTS): Run test. + + Fixes https://savannah.gnu.org/bugs/?58337. + +2020-05-08 G. Branden Robinson + + Update documentation of .ss request. + + * doc/groff.texi (Manipulating Filling and Adjusting): Rewrite + documentation of .ss request and \n[.ss] and \n[.sss] escapes. + Note that negative values are not permitted in either argument + to .ss. Use new terminology, "minimal inter-word spacing" and + "additional inter-sentence spacing" for clarity. Clarify that + additional inter-sentence spacing is only used when the output + line is not full when the end of a sentence occurs. Add index + nodes to help readers find discussion of details of spacing + between words and sentences. Move discussion of differences + from AT&T troff to section "Implementation Differences". Update + example to more closely resemble a real-world case, use second + argument to .ss request, and eliminate hackish use of .nop + request. + + * man/groff_diff.7.man (New number registers): Recast in + parallel with the foregoing. + + * man/groff.7.man (Read-only registers): Use new terminology and + describe \n[.ss] and \n[.sss] in meaningful terms, not by + reference to arguments to the .ss request (which wasn't even + accurate, because these registers have default values). + + Fixes https://savannah.gnu.org/bugs/?54101. + +2020-05-06 G. Branden Robinson + + Undocument plans to support end-of-file GNU Emacs coding tags. + + * src/preproc/preconv/preconv.cpp (check_coding_tag): Update + comments. + (detect_file_encoding): Alter debugging output so it's easier to + grep and verify Emacs coding tag detection. + + * src/preproc/preconv/preconv.1.man (Bugs): Delete; its sole + concern was the absence of this feature. + (Usage): Document detection algorithm in more detail. Note + which detection methods don't work on unseekable input (pipes). + Offer recommendations for those struggling with encoding + detection. + (Usage/Coding Tags): Stop manipulating line adjustment. Use + hyphen-minus (\- escape) characters in coding tag names, since + they are literals that one might copy and paste. Stop + referencing XEmacs, whose development appears moribund. + (See Also): Add cross-references to iconv(3) and locale(7) man + pages. + + * src/preproc/preconv/tests/smoke-test.sh: Test each of the + steps in the detection algorithm. + * src/preproc/preconv/preconv.am: Run test. + (preconv_TESTS): Add new variable. + (TESTS): Append $(preconv_TESTS). + +2020-05-05 G. Branden Robinson + + * src/utils/afmtodit/afmtodit.pl: Format usage message with + full capitals for parameters, and break out -v option in a + separate "synopsis". + +2020-05-05 G. Branden Robinson + + * font/devpdf/util/BuildFoundries.pl: Stop throwing away + diagnostics from afmtodit. This results in only one extra line + of build output: + + both Upsilon1 and Upsilon map to *U at .../afmtodit line + 6413. + +2020-05-05 G. Branden Robinson + + Correct documentation of .pm request. + + * man/groff.7.man (Requests/Request short reference): The .pm + request's classical behavior was described instead of groff's, + and omitted mention of strings and diversions; correct it. + + * man/groff_diff.7.man (Implementation Differences): Document + this difference between AT&T troff and groff. + + * doc/groff.texi (Debugging): Relocate description of .pm + behavioral difference... + (Implementation Differences): ...hither. + +2020-04-30 G. Branden Robinson + + * src/utils/addftinfo/addftinfo.cpp (usage): + * src/utils/tfmtodit/tfmtodit.cpp (usage): Add "usage:" prefix + to messages documenting auxiliary modes of invoking the program. + The output doesn't look right without one, and it feels + dishonest to not document the relevant options (-v, --version) + disjunctively. I'm trying to strike a balance between the + ultra-terse BSD approach and the ultra-garrulous GNU one (see, + e.g., ls(1)). Likely both camps will be unhappy. :-/ + +2020-04-30 G. Branden Robinson + + * src/utils/tfmtodit/tfmtodit.cpp (read_map): Report invalid + character code from map file in diagnostic. + (main): Report invalid skew character position in diagnostic. + Explicitly report insufficient arguments in addition to usage + message. Lift invariant computed expressions out of loops (more + to shorten long lines than because I think the compiler won't + figure it out). Give content to "impossible assertion". + (tfm::load): Capitalize TFM initialism in diagnostics. + (usage): Use full capitals for parameters as is conventional. + Document disjunction of -v/--version flag from other + invocations. + +2020-04-29 G. Branden Robinson + + * src/utils/addftinfo/addftinfo.cpp (usage): Add overloaded + version that accepts a constant string argument, which emits the + argument as a diagnostic and then calls usage(). + (main): Add diagnostics to usage message where the problem is + clear. Add comment explaining why it sometimes isn't. + (usage): Refactor main usage message (which prints the summary) + to report the actual names of the accepted option arguments + instead of just "-param", which is not literally accepted. + + Sort param_table alphabetically for use by the usage message. + +2020-04-22 G. Branden Robinson + + Delete groffer. + + Per discussion on the groff development mailing list, there is + no desire to retain the maintenance of this portion of the groff + distribution. + + See + + et seq. + + * contrib/groffer: Recursively delete. + + * Makefile.am: + * arch/mingw/mingw.am: Stop building groffer. + + * m4/groff.m4 (GROFF_GROFFERDIR_DEFAULT): + (GROFF_GROFFERDIR_OPTION): Delete; remove "--with-grofferdir" + configuration option. + * configure.ac: Stop calling these macros. + + * MANIFEST: + * NEWS: + * PROJECTS: + * TODO: + * contrib/chem/chem.1.man: + * contrib/chem/examples/122/README.txt: + * contrib/chem/examples/README.txt: + * contrib/glilypond/glilypond.1.man: + * contrib/gperl/gperl.1.man: + * contrib/gpinyin/gpinyin.1.man: + * contrib/groff_filenames/groff_filenames.5.man: + * man/groff_font.5.man: + * man/roff.7.man: + * src/roff/groff/groff.1.man: + * src/roff/grog/grog.1.man: + * src/utils/addftinfo/addftinfo.1.man: + * tmac/groff_trace.7.man: Delete references to groffer. + +2020-04-19 G. Branden Robinson + + * src/include/curtime.h: #include if we're returning + a time_t from current_time(). + + * src/libs/libgroff/curtime.cpp (current_time): Quote + $SOURCE_DATE_EPOCH variable content in diagnostics produced due + to bad input since it's under user control and could have all + kinds of bogosity in it (like whitespace). + +2020-04-19 G. Branden Robinson + + * **/*.{man,tmac}: Save compatibility mode robustly. + + Use new \n[.cp] register to save compatibility mode. + + Use register names based on the filename (at the source + maintenance level) to avoid clobbering other files' saved + compatibility modes. + + * tmac/html.tmac: Eliminate test of saved-compatibility + register by moving its body inside the block where compatibility + mode is off. This is the only part of this changeset that was + not automated. + + Fixes . + +2020-04-16 G. Branden Robinson + + Implement new read-only .cp register. + + Within a .do request, \n[.cp] holds the saved value of + compatibility mode. + + The register \n[.cp] is specialized and may require a statement + of rationale. When writing macro packages or documents that use + groff features and which may be mixed with other packages or + documents that do not—common scenarios include serial processing + of man pages or use of the .so or .mso requests—you may desire + correct operation regardless of compatibility mode in the + surrounding context. It may occur to you to save the existing + value of \n(.C into a register, say, _C, at the beginning of + your file, turn compatibility mode off with “.cp 0”, then + restore it from that register at the end with “.cp \n(_C”. At + the same time, a modular design of a document or macro package + may lead you to multiple layers of inclusion. You cannot use + the same register name everywhere or you risk “clobbering” the + value from a preceding or enclosing context. The two‐character + register namespace of AT&T troff is confining and mnemonically + challenging; you may wish to use groff's more capacious + namespace. However, attempting “.nr _my_saved_C \n(.C” will not + work in compatibility mode; the register name is too long. + “This is exactly what .do is for,” you think, “.do nr + _my_saved_C \n(.C”. The foregoing will always save zero to your + register, because .do turns compatibility mode off while it + interprets its argument list. What you need is: + .do nr _my_saved_C \n[.cp] + .cp 0 + at the beginning of your file, followed by + .cp \n[_my_saved_C] + at the end. As in the C language, we all have to share one big + namespace, so choose a register name that is unlikely to collide + with other uses. + + * src/roff/troff/input.cpp (do_request, init_input_requests): + Implement it. + + * doc/groff.texi: + * man/groff.7.man: + * man/groff_diff.7.man: Document it. + + * src/roff/groff/tests/dot-cp_register_works.sh: Test it. + * src/roff/groff/groff.am (groff_TESTS): Run test. + + Enables a fix for + . + + Thanks to John Gardner and Ingo Schwarze for the discussion. + +2020-04-15 G. Branden Robinson + + * doc/groff.texi (Implementation Differences): + * man/groff_diff.7.man (New requests): Rewrite description of + .do request, and replace example with a more illustrative one. + + * man/groff.7.man (Request short reference): Rewrite description + of .do request briefly. + +2020-04-14 G. Branden Robinson + + * doc/groff.texi (Implementation Differences): Remove incorrect + claim. The .C register cannot be manipulated manually. + +2020-04-14 G. Branden Robinson + + * src/roff/groff/tests/smoke-test_html_device.sh: Simplify + charmap test. + +2020-04-13 G. Branden Robinson + + It's too easy for the nroff version to get desynced from the + groff version when we're running test cases, leading to spurious + results. Make it easier to see a discrepancy. + + * src/roff/nroff/nroff.sh: Call groff with -v or --version when + we are called that way. Let test cases tell us to use + test-groff as groff with an environment variable. + + * src/roff/nroff/tests/verbose_option_works.sh.in: Rename to... + * src/roff/nroff/tests/verbose_option_works.sh: ...this. Check + the nroff version being tested against the groff version being + wrapped. This exposes a bug; the system groff rather than the + build tree groff was being invoked. Refactor. Stop messing + with @GROFF_BIN_PATH_SETUP@ (enabling the rename); instead, let + test-groff handle that for us. Locate it and export the + variable GROFF_TEST_GROFF so nroff can find it. Because we + manipulate $PATH to run the tests, the $PATH of an installed + groff system will _always_ differ from that used by a build + tree; ignore it in the test cases. Dispose of bashisms and set + shebang to /bin/sh. + + * src/roff/nroff/nroff.am: Stop generating the above test + script. It can now be run as it ships. + +2020-04-13 G. Branden Robinson + + Make our assert() C99-conformant. + + groff has its own implementation of the standard C library's + assert() macro. It hasn't been updated since C89. C99 requires + that the diagnostic emitted by assert() contain the failing + expression and name of the function in scope. + + * src/include/assert.h: Add additional pointer to const char + arguments to do_assert() and assertion_failed() for function + name and stringified expression. + (assertion_failed): Update prototype. + (do_assert): Accept 'func' and 'msg' parameters and pass them to + assertion_failed(). + (assert): Update macro to collect '__func__' and stringify the + expr parameter (as 'msg') and pass them do do_assert(). + * src/libs/libgroff/assert.cpp (assertion_failed): Rewrite + diagnostic to more closely match GNU Coding Style format and + also report function and failing expression. + + Example output: + troff: ../src/roff/troff/input.cpp:2644: do_request(): + assertion failed: '0 == "But first, here's a rotten old + BBC programme."' + + We have no excuse to assert(0) ever again. Express the + invariant that has been violated. + +2020-04-13 G. Branden Robinson + + * src/roff/groff/tests/smoke-test_html_device.sh: Set + LC_CTYPE=C.UTF-8 so that byte sequences in the pipelines are + handled correctly. Skip the test if the environment doesn't + support UTF-8. Thanks to Bjarni Ingi Gislason for the trouble + report. + + Fixes . + +2020-04-13 G. Branden Robinson + + * tmac/html.tmac: Use .do so we correctly load unicode.tmac in + compatibility mode. + + Fixes the following problem (wrapped, filenames abbreviated): + + $ echo | ./build/test-groff -C -Thtml >/dev/null + troff: backtrace: file '.../groff/build/../tmac/html.tmac':546 + troff: backtrace: file '.../groff/build/../tmac/troffrc':30 + troff: .../groff/build/../tmac/html.tmac:546: warning: macro + 'ms' not defined + +2020-04-13 G. Branden Robinson + + * src/roff/groff/tests/smoke-test_html_device.sh: Add test. + * src/roff/groff/groff.am (groff_TESTS): Run test. + +2020-04-12 G. Branden Robinson + + * src/roff/groff/tests/regression_savannah_58153.sh: + * src/roff/groff/tests/\ + use_point_size_escape_with_single_digit_arg.sh: Use "set -e" to + ensure that multi-test script files don't hide problems. There + are arguments against "set -e" (and you can ask Greg Wooledge + for all of them), but I'm so used to it from years of writing + Debian package maintainer scripts that I feel comfortable with + it. It is less verbose than several alternatives (especially + having one test script per case). + + * src/roff/groff/tests/string_case_xform_unicode_escape.sh: + Update with respect to new failure output (in a comment only, + since this is an XFAIL test). + + * tmac/tests/an-old_AT_and_UC_footer_saved_and_restored.sh: + Drop unnecessary "|| exit 1" from end of script. Incidentally, + this script illustrates an alternative to "set -e". + +2020-04-11 G. Branden Robinson + + Rework documentation of .spreadwarn. + + * doc/groff.texi (Debugging): + * man/groff.7.man (Request short reference): + * man/groff_diff.7.man (New requests): Recast description of + .spreadwarn request, some based on suggestions from Dave Kemper. + Make more prominent the fact that spreading only applies to + adjustment mode 'b'. Document warning type used. + + Fixes half of Savannah #58035. + +2020-04-11 G. Branden Robinson + + Require Texinfo 5.0 (February 2013) at a minimum. + + * m4/groff.m4 (GROFF_MAKEINFO): Check for version 5.0 (increased + from 4.8). Update diagnostics and comments. + + * INSTALL.extra: + * README: + * doc/groff.texi: + * doc/webpage.ms: Document updated requirement. + + * doc/fixinfo.sh: Delete; it is no longer necessary to work + around Texinfo 4.x bugs. + + * doc/doc.am (EXTRA_DIST): Stop shipping fixinfo.sh. + (.texi.html): Remove makeinfo < 5.0 version check and consequent + execution of fixinfo.sh. Update comment. + +2020-04-11 G. Branden Robinson + + Enable backtracing across process/file boundaries when errors or + non-ignored warnings are encountered. + + Experimentation reveals that .so, .mso, and .pso requests acted + as barriers to backtracing except when explicitly requested with + the .backtrace request. Judging by the git history, this + behavior dates back to June 1991 or earlier. The intention, + according to a source comment, was only to suppress the + backtrace output for the line corresponding to the outermost + level of the input stack (commonly, a file argument to groff). + Unfortunately, that wasn't its only effect. + + This change does result in one additional line of output for + each error or (non-ignored) warning when -b is given. However, + I regard this as unobjectionable because {1} a backtrace was in + fact explicitly requested; and {2} it seems a poor tradeoff to + suppress most of the backtrace in some complicated and + frustrating cases for the sake of one fewer line of backtrace + output in a trivial one. + + Now, backtracing behaves the same no matter what triggers it. + + Fixes Savannah #58153. + + * src/roff/troff/input.cpp (file_iterator::backtrace): Call + get_location() for its side effect of rewriting a filename of + "-" to "", for consistency with other diagnostic + messages. (In this class, this member function always returns + 1, so ignore the return value. This fact is an essential part + of what led to the bug; the conditional + p && !p->get_location(0, &f, &n) + which appeared in the for loop of input_stack::backtrace() prior + to this change would always evaluate to false when a node of the + file_iterator class was encountered.) + (input_stack::backtrace): Replace member function body with that + of input_stack::backtrace_all(). + (input_stack::backtrace_all): Delete. + (backtrace_request): Update the only call site of the above. + + * src/roff/groff/tests/regression_savannah_58153.sh: Add test. + * src/roff/groff/groff.am (groff_TESTS): Run test. + + * src/roff/groff/tests/string_case_xform_errors.sh: Update + regression test to not be confounded by additional line of + backtrace output. Remove bashism along the way. + + * doc/groff.texi: + * man/groff.7.man: + * man/groff_diff.7.man: Update documentation. + +2020-04-10 G. Branden Robinson + + Reorganize backtrace output. + + * src/roff/troff/input.cpp (string_iterator::backtrace): + Prefix the output with the program name if it is known. In a + deviation from the GNU Coding Standards, put the string + "backtrace:" immediately next instead of the file and line + number; this is because, particularly in cases where the + backtrace is most interesting or needed, it will produce + multiple lines of output and the common prefix aids visual + understanding. + (file_iterator::backtrace): As above; also, change prefix for + popened nodes in the iterator from "process" to "pipe". This + seemed preferable to omitting the information entirely or using + an inscrutable sigil like 'f' or 'p'. The advantage is that the + output is better aligned--better ergonomics for those who have + to cope with a lot of it. Furthermore, output the filename only + once. + + Example of old and new output: + + /tmp/inner:2: backtrace: file '/tmp/inner' + echo .so /tmp/inner:1: backtrace: process 'echo .so /tmp/inner' + /tmp/outer:1: backtrace: file '/tmp/outer' + + troff: backtrace: file '/tmp/inner':2 + troff: backtrace: pipe 'echo .so /tmp/inner':1 + troff: backtrace: file '/tmp/outer':1 + +2020-04-10 G. Branden Robinson + + * src/roff/troff/input.cpp (read_size): Add units to diagnostic. + This function works only with device-specific basic units + internally; users likely think in terms of point size, so add + the basic unit suffix "u" to offer a hint about what's going on. + + Example: + $ groff -ww >/dev/null + \s[10]A\s[-12]B + troff: :1: warning: point-size escape results in + non-positive size -2000u; set to 1u + + On a PostScript device with 1000 basic units to the point, the + difference is important and would be confusing without the unit + indication. + +2020-04-08 G. Branden Robinson + + Correct and clarify point size documentation. + + Our Texinfo manual has long documented the request '.ps 0' as + restoring the previous point size (just as '\s0' or '.ps' with + no argument does), but this is incorrect; since groff 1.02 or + earlier (June 1991), the request has not actually worked this + way. Instead, '.ps 0' sets the point size to 1 basic unit + {though output drivers may clamp this to a higher value}. This + behavior is consistent with AT&T troff, Hierloom Doctools troff + and, per Ingo Schwarze, Plan 9 troff. (It is, however, not + consistent with neatroff.) + + * doc/groff.texi (Changing Type Sizes): Stop claiming that '.ps + 0' works like '\s0'. Note that the resulting (computed) point + size, not the argument, is clamped. Note that it is + non-positive, not negative, point sizes that are clamped to 1u. + Add (forward) cross-reference to section where \n[.ps] is + defined since it is mentioned here. Move explanation of special + handling of zero argument to \s escape description. + + * man/groff.7.man (Request short reference): Explain .ps N + independently of \s. Note clamping behavior. + +2020-04-06 G. Branden Robinson + + * src/roff/troff/input.cpp (read_size): Correctly brace 'else' + block. + + * src/roff/groff/tests/\ + use_point_size_escape_with_single_digit_arg.sh: + Check that we get a diagnostic when relying on ambiguous form. + +2020-04-04 G. Branden Robinson + + * src/roff/troff/input.cpp (read_size): Move special-case + interpretation of the '\sN' form of point-size escapes when 'N' + is 1, 2, or 3 to compatibility mode (groff -C) only, and throw + error diagnostic with suggestion for remedy if encountered. + + Traditionally, '\s36A' is interpreted as "set point size to 36, + then emit 'A'". However, only values in the range 10-39 are + handled specially; '\s40A' is interpreted as a four-point "0A". + This is unlike anything else in *roff grammar; see \*, \$, \f, + \F, \g, \k, \m, \M, \n, \V, \Y, and \z. + + To anticipate objections: Why not throw only a warning? Because + there isn't a warning category for supported but ambiguous + syntax (this behavior of AT&T troff dates back to the mid-1970s + but was not documented in the Troff User's Manual until 1992). + Why not throw the error outside of compatibility mode too? + Because outside of compatibility mode we (now) have an + unambiguous parse. + + Background: The Graphic Systems C/A/T phototypesetter (the + original device target for AT&T troff) only supported a few + discrete point sizes in the range 6..36, so Ossanna + special-cased the parser to do what the user must have meant. + Kernighan warned of this in the 1992 revision of CSTR #54 + {§2.3}, and more recently, McIlroy referred to it as a "living + fossil". + + See: + https://lists.gnu.org/archive/html/groff/2020-03/msg00054.html + https://lists.gnu.org/archive/html/groff/2020-04/msg00002.html + https://lists.gnu.org/archive/html/groff/2020-04/msg00015.html + and follow-ups for discussion. + + * NEWS: Advise users of behavior change and offer guidance. + + * doc/groff.texi: + * man/groff.7.man: Document the restriction of special handling + of point-size arguments to '\s' to compatibility mode. + + * src/roff/groff/tests/\ + use_point_size_escape_with_single_digit_arg.sh: Add regression + test. + * src/roff/groff/groff.am (groff_TESTS): Run test. + +2020-04-04 G. Branden Robinson + + Improve point-size escape diagnostics. + + * src/roff/troff/input.cpp (read_size): Disclose context + {point-size escape interpretation} in diagnostic messages. When + a "bad digit" is encountered, describe it if possible. When a + relative adjustment results in a negative point size, report the + computed value. Also rename a variable for slightly more + clarity ("bad" does not refer to all bad parses, just some cases + of bad digits), and update an insufficiently generalized comment + {"\s(00" is also an acceptable expression for point-size zero}. + + Based on suggestions by Ingo Schwarze and Bjarni Ingi Gislason. + +2020-04-01 G. Branden Robinson + + Align diagnostic message format. + + * src/libs/libgroff/error.cpp (do_error_with_file_and_line): + * src/roff/troff/input.cpp (do_error): + Display the diagnostic level when it is "error", instead of + leaving it implicit. + + * src/roff/troff/input.cpp (error_with_file_and_line): Include + the program name in the diagnostic message if it is known. + + * src/roff/groff/tests/string_case_xform_errors.sh: Update + diagnostic message expectation. + +2020-02-10 G. Branden Robinson + + * doc/groff.texi (Page Motions): + * man/groff.7.man (Single-character escapes): Document + non-breaking spaces as such. + + Report and patch by Dave Kemper . + Fixes . + +2020-02-10 G. Branden Robinson + + nroff: Implement -P and -V options. + + * src/roff/nroff/nroff.sh: Recognize -P option (with argument) + and pass it through to groff. Recognize -V option; if given, + display constructed groff command instead of executing it. + Update usage message to document new options. Tidy up shell + style and indentation. Add comments. + * src/roff/nroff/nroff.1.man: Document new -P and -V options. + * src/roff/nroff/tests/verbose_option_works.sh.in: Test -V + option. + * src/roff/nroff/nroff.am: Generate test and run it. + +2020-02-06 G. Branden Robinson + + Stop ms macro package from manipulating warnings. + + * tmac/s.tmac: Remove code block that attempted to enable all + warnings "only if none are given on the command line". It did + this by simply comparing the value of the warn register + {\n[.warn]} against the default value; but of course, a user + could specify -w options that exactly matched the default and + the test would not be able to tell, causing puzzling and + undesired behavior. Furthermore, the hard-coded default was out + of date and did not correspond to recent releases of groff. If + you want all warnings on, use the ".warn" request with no + arguments in your ms document or pass "-w w" to groff (see + troff(1) or our Texinfo manual for more on warnings). + + Thanks to Bjarni Ingi Gislason for bringing this issue to our + attention. + + Resolves . + +2020-01-21 George HELFFRICH + + [me]: Fix regression of '.nm' (#57638). + + * tmac/e.tmac-u (nm): Use saved point size and font position + for line numbering only if those registers exist. + + Fixes . + +2020-01-18 Ingo Schwarze + + Accept any number of arguments for .Dd in the groff_mdoc(7) + macros. + + * tmac/doc-common-u: The .Dd macro behaved in a weird way: + Without arguments, it printed the string "Epoch". + With one, two, four, or more arguments, it ignored all arguments + and used the current date instead. + Only for exactly three arguments, it printed the arguments. + None of this made sense. Giving the date as "Epoch" is + absurd, and printing the current date is just misleading: + why should a document be considered up-to-date when the author + did not even bother to state the date of the last change? + Admittedly, the behaviour for 0 and 4 or more arguments + already appeared 4.3BSD-Reno, and the behaviour for 2 or 3 + arguments in 4.4BSD. But it was already wrong even in those + days: several manual pages in 4.4BSD gave .Dd a single, quoted + argument, e.g. .Dd "June 9, 1993": cap_mkdb(1), id(1), sed(1), + err(3), getcap(3), sysctl(3), amd(8), disklabel(8), and others. + Consequently, simply print all the arguments, no matter how + many there are. + + This bug was found by Jonathan Gray + while he looked at 4.xBSD manual pages. + +2020-01-18 G. Branden Robinson + + * doc/groff.texi: Document initial empty set membership of + characters with cflags values of 128, 256, or 512 in parallel + with preceding paragraphs regarding smaller powers of two. + + Report and patch by Dave Kemper . + Fixes . + +2020-01-18 G. Branden Robinson + + * src/roff/groff/tests/*.sh: Rename some tests so their + filenames are more self-descriptive. + * src/roff/groff/groff.am (groff_TESTS): Update. + +2020-01-18 G. Branden Robinson + + * src/roff/groff/tests/transparent_end-of-sentence_chars.sh: Add + test for end-of-sentence recognition. + * src/roff/groff/groff.am (groff_TESTS): Run test. + +2020-01-18 G. Branden Robinson + + * src/roff/troff/input.cpp: Mark \[dd] character (double dagger) + as transparent for purposes of end-of-sentence recognition. + + * doc/groff.texi (Sentences): + * man/groff_diff.7.man (New requests/.cflags): Document this. + + Report and patch by Dave Kemper . + Fixes . + +2020-01-17 G. Branden Robinson + + * src/preproc/refer/refer.1.man (See Also): + * src/utils/indxbib/indxbib.1.man (See Also): + * src/utils/lkbib/lkbib.1.man (See Also): + * src/utils/lookbib/lookbib.1.man (See Also): Add bibliographic + reference to the original Bell Labs "refer" paper by Mike Lesk. + +2020-01-17 G. Branden Robinson + + * tmac/tests/an-old_AT_and_UC_footer_saved_and_restored.sh: Add + regression test for Ingo's change below. + +2020-01-16 Ingo Schwarze + + Repair .AT and .UC in the groff_man(7) macros. + + * tmac/an-old.tmac: Setting user-defined strings in a macro that + will later be called indirectly from page location traps is + excessively complicated. Besides, the implementation doesn't + work: when the trap is finally sprung, the defaults from the + an-init macro clobber what the author specified with .AT or .UC. + Instead, all that is needed is setting the strings for the + header before triggering the page break, such that they appear + right away, while setting the strings for the footer after the + page break, such that they don't appear on the previous page. + + This bug was found by Jonathan Gray while he + looked at 4.xBSD manual pages. + +2020-01-16 G. Branden Robinson + + * tmac/groff_man.7.man (Document structure macros/.SH): Fix + errors in footer description. + +2020-01-12 G. Branden Robinson + + * tmac/tests/an-old_CS_register_on.sh: Tweak flags; all the + other tests in this group pass "-Tascii -P-cbou" instead of + "-Tutf8". (This is so that output is easy to grep from a shell + script.) Bring this test into line. Does not regress anything. + +2019-12-30 Deri James + + Certain pdfmark destination names caused gropdf to fail. + + * src/devices/gropdf/gropdf.pl: Look for pdfmark types, (i.e. + DEST, OUT, ANN), only preceding 'pdfmark' at end of line, not + anywhere else. + +2019-12-30 Ingo Schwarze + + Correct output of sprintf("%%") in pic(1). + + * src/preproc/pic/pic.ypp: Print "%" rather than "%%". + + Bug reported by Doug McIlroy . + Patch using feedback from Larry McVoy . + +2019-12-29 Deri James + + Update man page of gropdf to document \X calls. + + * src/devices/gropdf/gropdf.1.man: The calls 'pagename' and + 'switchtopage' (used by mom to relocate TOC) are documented, + together with their convenience commands '.pdfpagename' and + '.pdfswitchtopage'. + +2019-12-29 Ingo Schwarze + + Improve documentation of pic(1) regarding printf. + + * src/preproc/pic/pic.1.man: + Document which conversion specifications are supported. + * doc/pic.ms: + Correct the list of supported conversion specifications. + +2019-12-21 Ingo Schwarze + + Update NetBSD, OpenBSD, FreeBSD, Darwin, and DragonFly version + strings. + + * tmac/doc-common-u: Update. + * tmac/groff_mdoc.7.man: Synchronize. + + Based on a patch from Guillem Jover + via Colin Watson , tweaked by me. + Fixes: https://bugs.debian.org/867123 + +2019-09-22 G. Branden Robinson + + Use a vertical spacing of 1v between paragraphs in man page + examples. This looks better (on typesetter devices like + PostScript and PDF) with the Courier font family also used in + examples. Typewriter devices (like the terminal) already used + an inter-paragraph spacing of 1v. + + * tmac/an-ext.tmac (EX): Save the value of the PD number + register (inter-paragraph distance), and set it to 1v. + (EE): Restore previous value of the PD register. + +2019-09-21 Deri James + + Changes to allow configure to check for URW fonts + + * font/devpdf/util/BuildFoundries.pl: Call the program with + --dirURW with path provided to ./configure, and --check to do + a dry-run just checking if the fonts are available. (bug #56748) + +2019-09-21 Deri James + + Add new ghostscript font names (bug #56748) + + * font/devpdf/Foundry.in: Add changed font names + +2019-09-21 Deri James + + Prevent gropdf executing arbitrary commands + + * src/devices/gropdf/gropdf.pl: See bug #55557 + +2019-09-15 G. Branden Robinson + + * tmac/an-old.tmac: Move test for definitions of CS and CT + registers to after man.local is sourced; this way we can both + respect any setting of those registers in that file (which is + intended for customization by the site administrator) and ensure + that the registers are defined when dereferenced later. + +2019-09-15 G. Branden Robinson + + * **/*.man: Put section headings in title case. + +2019-09-13 G. Branden Robinson + + * src/roff/troff/input.cpp: Lift invariant out of loop. + +2019-09-11 G. Branden Robinson + + * src/preproc/refer/refer.1.man: Add mention of man and mm + packages as supporting the "refer" preprocessor (GNU mm grew + this support back in groff 1.22.1). + +2019-09-10 G. Branden Robinson + + Mark expected-to-fail test as XFAIL. + + Automake supports XFAIL and XPASS, so actually use the + infrastructure as intended. + + * Makefile.am: Declare XFAIL_TESTS variable. + * src/roff/groff/groff.am (groff_XFAIL_TESTS): Add + string_case_xform_unicode_escape.sh. + * src/roff/groff/tests/string_case_xform_unicode_escape.sh: Set + the expected output to what it would be if string case + transforms worked on groff Unicode escapes. + +2019-09-10 G. Branden Robinson + + Retire '@G@' build system macro. + + It existed only for forcibly-capitalized man page titles; it was + the uppercase-transformed counterpart of @g@. + + * Makefile.am: Delete sed transformation of @G@. + * src/preproc/tbl/tbl.1.man: Replace '@G@EQN' in section heading + with '@g@eqn'. + +2019-09-10 G. Branden Robinson + + * **/*.man: Downcase man page titles, except for glilypond and + roff2*, which did not require it. + + Here's a sed script for the aid of those who have a corpus of + man pages to migrate. + + # Downcase man page titles. + # + # Use the first line to skip any .TH lines that require + # special handling, perhaps because the name of the + # command gets externally macro-expanded. In groff, the + # "roff2.1.man" page is an example. + # + # This script operates _only_ on .TH lines. + # + # usage: sed -i -f this_script.sed your_man_page.1 ... + /@ROFF2MODE@/b + /^\.\s*TH/{ + h + s/^\.\s*TH \+\([^ ]\+\) .*/\1/ + y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + G + s/\([^ ]\+\)\n\(^\.\s*TH \+\)[^ ]\+\( .*\)/\2\1\3/ + } + +2019-09-09 G. Branden Robinson + + The an (man) macro package supports new CS and CT number + registers to control rendering of man page section headings and + titles, respectively, in full capitals. These default off (with + no visible effect on pages which already fully capitalize these + strings in man page sources). The rationale is to encourage man + page authors to preserve case distinction information in (or + restore it to) their titles and section headings, while giving + users (including system administrators, distributors, + integrators, and maintainers of man(1) implementations) a way to + view the rendered page elements in full capitals if desired. + + * tmac/an-old.tmac (TH/an-init): If number register CT is + defined and nonzero, call .stringup on \*[an-title]. + (SH): Store macro argument list to \*[an-section-heading]. If + number register CS is defined and nonzero, call .stringup on it. + * tmac/groff_man.7.man (OPTIONS): Document the CS and CT number + registers. + * tmac/tests/an-old_CS_register_off.sh: + * tmac/tests/an-old_CS_register_on.sh: + * tmac/tests/an-old_CS_register_unspecified.sh: + * tmac/tests/an-old_CT_register_off.sh: + * tmac/tests/an-old_CT_register_on.sh: + * tmac/tests/an-old_CT_register_unspecified.sh: Add tests. + * tmac/tmac.am (tmac_TESTS): Run tests. + +2019-09-09 G. Branden Robinson + + Add regression test to check behavior of case transformation + request on a string containing a Unicode character escape. + Right now, this is not supported, so it is an XFAIL test in the + parlance of DejaGNU/POSIX 1003.3. + + * src/roff/groff/tests/string_case_xform_unicode_escape.sh: New + test. + * src/roff/groff/groff.am (groff_TESTS): Run test. + +2019-09-09 G. Branden Robinson + + Implement .stringdown and .stringup requests. + + * src/roff/troff/input.cpp: Add .stringdown and .stringup + requests. + * doc/groff.texi: Document them, including example. + * man/groff_diff.7.man: Same. + * man/groff.7.man: Document them briefly. + +2019-09-09 G. Branden Robinson + + Regression-test string case transform feature. + + * src/roff/groff/tests/string_case_xform_errors.sh: New test. + * src/roff/groff/tests/string_case_xform_requests.sh: New test. + * src/roff/groff/groff.am (groff_TESTS): Run tests. + +2019-06-30 G. Branden Robinson + + * src/devices/grotty/grotty.1.man (Options/-i): Note support of + recent versions of xterm for italic (oblique) styles. + + Fixes part of . + +2019-06-28 G. Branden Robinson + + devlatin1: Map \(oq to ' on output. + + * font/devlatin1/R.proto: Render the output glyph \[oq] + {opening quote} as 0x27 (apostrophe) instead of 0x60 (grave + accent). A grave accent is just flat wrong for the Latin-1 + character set, a.k.a. ISO 8859-1. The defining document ECMA-94 + {June 1986} is freely available for perusal. The ECMA-94 Latin + character sets do not define any glyphs for directional + {"typographer's"} quotation marks, but the apostrophe is + depicted as a neutral (vertical) glyph, whereas the grave accent + 0x60 and acute accent 0xB4 are mirror-symmetric diacritical + marks. + + Note that this change has no effect on _input_ conventions for + roff source documents. You can still get directional single + quotes on UTF-8, PostScript, PDF, and other output devices + supporting them by typing sequences like `this' in the input + {character remapping with ".char" requests and similar + notwithstanding}. + + Patch and idea from Ingo Schwarze, who originally proposed it + for ASCII as well, and included Latin-1 for parallelism. + The groff developers could reach no consensus about the wisdom + of such a change for ASCII (which was designed to support + ambiguity for some code points, requiring the development of + supplementary interpretation conventions between parties). + ECMA-94/ISO-8859 is more strongly prescriptive. + + See https://savannah.gnu.org/bugs/?55616 and the groff mailing + list archives for 31 January to 23 February 2019 at + https://lists.gnu.org/archive/html/groff for lengthy discussion. + + * src/roff/groff/tests/on-latin1-device-oq-is-0x27.sh: Check for + correct output glyph. + + * src/roff/groff/groff.am: Add test. + +2019-06-28 G. Branden Robinson + + * tmac/unicode.tmac: Save and restore compatibility mode since + the script uses a GNU extension (.char). + +2019-06-27 G. Branden Robinson + + libdriver: Fix SEGV (Savannah #56555). + + * src/libs/libdriver/printer.cpp: Check result of + set_char_and_width() for error condition before relying on it. + + * src/roff/groff/tests/regression-56555.sh: Provoke segfault + with five bytes of input using transparent line indicator. + + * src/roff/groff/groff.am: Add test. + + Fixes . + +2019-01-12 Ingo Schwarze + + Correctly handle groff_mdoc(7) .Lk arguments starting with a + dot. + + * tmac/doc.tmac-u: Each argument to the .Lk macro is printed + on its own roff input line. If it happens to start with a dot + or apostroph, it was misinterpreted as a request or macro. + Force it to be treated as text by adding "\&" in front of it. + +2018-12-31 Ingo Schwarze + + * man/groff_diff.7.man: remove two stray .RE macros + + +________________________________________________________________________ + +##### License + +Copyright 2018-2021 Free Software Foundation, Inc. + +Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. + + +##### Editor settings +Local Variables: +fill-column: 72 +mode: change-log +version-control: never +End: +vim:set autoindent textwidth=72: diff --git a/ChangeLog.115 b/ChangeLog.115 new file mode 100644 index 0000000..6f8b17b --- /dev/null +++ b/ChangeLog.115 @@ -0,0 +1,6156 @@ + +Version 1.15 released +===================== + +1999-12-28 Werner LEMBERG + + * NEWS, VERSION: Changed to 1.15 + +1999-12-27 Paul Eggert + + * nroff/nroff.man: -S is safer, not safe. + + * groff/groff.cc (main): Use `safer', not `safe', in variable + names. This does not change the behavior. + + * troff/input.cc (main): Likewise. + + * nroff/nroff.sh: Likewise. + + * troff/input.cc (prepend_string): New function. + (main): Prepend -msafer, so that we check macro libraries for + safety. + + * PROBLEMS: Report problem with Sun C++ 5.0 and 5.1. + +Version 1.14 released +===================== + +1999-12-26 Werner LEMBERG + + * NEWS, VERSION: Changed to 1.14. + +1999-12-24 Werner LEMBERG + + * refer/refer.cc: Fixing the last fix. + +Version 1.13 released +===================== + +1999-12-23 Werner LEMBERG + + * tmac/tmac.an: A typo (`.if' instead of `.ie') made the page + number disappear. + + * NEWS: Updated. + + * tmac/tmac.safer: Forgot to remove `so' from the `rm' request. + + * VERSION: Changed to 1.13 -- to be compliant with the Adobe 3.0 + document conventions, the version number must be a real. + +Version 1.12.1 released +======================= + +1999-12-22 Werner LEMBERG + + * VERSION: Changed to 1.12.1. + +1999-12-22 Alan Rooks + + * refer/refer.cc (do_file): Slight modification to satisfy the + `Standard system CC - C++ Compilation System 3.1 03/03/99' on SCO + UnixWare 7.1. + +1999-12-20 Werner LEMBERG + + * changed prep.ai.mit.edu -> ftp.gnu.org; updated copyright + notices. + + * tmac/tmac.safer, tmac/groff_msafer.man: Remove `so' (again) from + list of unsafe requests. + + * pic/pic.man: Fixed a typo. + + * man/groff_out.man: Fixed a typo. + +1999-12-18 Werner LEMBERG + + * Makefile.in: Doc fixes. + +1999-12-17 Fabrizio Polacco + + * groff/groff.cc: Missing `U' option added to getopt(). + + * troff/troff.man: Missing `U' option added to synopsis. + +Version 1.12 released +===================== + +1999-12-14 Werner LEMBERG + + * troff/input.cc (usage), groff/groff.cc (synopsis): Added -U flag + to the synopsis. + + * nroff/nroff.sh, nroff/nroff.man: Replaced `secure', `unsecure' + with the more appropriate terms `safer' and `unsafe'. + + * libgroff/strerror.c, aclocal.m4, configure.in: Added checks for + sys_nerr and sys_errlist[]. + + * pic/pic.h, aclocal.m4, configure.in: Added check for hypot(). + + * pic/pic.y, pic/pic.cc: Added check for fmod(). + +1999-12-13 Werner LEMBERG + + * VERSION: Changed to 1.12. + + Here some patches from various sources; most of them taken from + the Debian distribution. + + * tmac/groff_mdoc.man, tmac/groff_mdoc.samples.man, + tmac/Makefile.sub: New files copied directly from the NetBSD + distribution. Probably, some additional adaptation later on is + necessary... + + * tmac/tmac.safer, tmac/groff_msafer.man: Added `so' to the list + of unsafe requests. + + * groff/groff.cc, groff/groff.man, nroff/nroff.sh, + nroff/nroff.man, pic/main.cc, pic/pic.man, troff/input.cc, + troff/troff.man: Added option `-U' for unsafe mode. Safe mode + (`-S') is now the default. + + * README, NEWS: Updated. + +1999-12-09 Werner LEMBERG + + * doc/groff.texinfo: Regenerated nodes and menus with emacs. + + * doc/Makefile (clean): Added cleaning commands for groff.texinfo. + +1999-12-06 Werner LEMBERG + + * configure.in: Removed AC_PREFIX_PROGRAM since it causes more + grief than relief today. Additionally, it is against the GNU + coding standards. + + * configure: Recreated. + +1999-12-05 Werner LEMBERG + + * configure.in: Added GROFF_LIBM. + + * configure: Recreated. + + * aclocal.m4 (GROFF_LIBM): New function which tests whether -lm is + necessary. + + * Makefile.in: Added definition of $(LIBM). + + * Makefile.comm (LIBM): Removed. + + * pfbtops/Makefile.sub: On AIX, -lm is needed also. + +1999-12-03 Gaius Mulley + + * doc/Makefile: Added rule for generation pic.html. + + (clean): Files produced by grohtml will be removed also. + + * doc/pic.ms: Small fix. + + * tmac/tmac.html: Fixed suppression of headers. + +1999-11-16 Gaius Mulley + + * tmac/tmac.html: Fixing horizontal arrows. + + Turning off hyphenation. + + * tmac/tmac.an: Improved support for grohtml; better indentation, + no footers/headers. + +1999-10-31 Gaius Mulley + + * tmac/tmac.arkup: Added CDFTP macro + + * tmac/tmac.html: All headers are turned off for ms, me, and mm + macros. + + * tmac/troffrc: Some additions for HTML stuff. + +1999-10-06 Gaius Mulley + + * tmac/tmac.html: Small changes. + +1999-09-26 Werner LEMBERG + + * doc/groff.texinfo: Minor fixes. + +1999-09-26 Gaius Mulley + + * devhtml/TR: Changed spacewidth to 3. + + * tmac/Makefile.sub (NORMALFILES): Added tmac.arkup. + + * tmac/tmac.html: Moved markup macros to tmap.arkup. + + * tmac/tmac.arkup: New file. + + * grohtml/ChangeLog: New file. + +1999-09-16 Werner LEMBERG + + * doc/groff.texinfo (Common Features): Added Copying chapter. + Changed format to @smallbook. + +1999-09-15 Werner LEMBERG + + * NEWS: Added info about groff.texinfo. + + * doc/groff.texinfo: Will now compile (using texi2dvi) without + warning messages. + +1999-09-14 Werner LEMBERG + + * groff/groff.man: More updates. + +1999-09-13 Werner LEMBERG + + * doc/groff.texinfo: New file. This manual is still very + rudimentary. It has been originally contributed by Trent + A. Fisher with first corrections and + additions by me. + + * INSTALL: Added information about the `doc' subdir + + * troff/troff.man: Minor fixes. + + * groff/groff.man: Added missing `-L arg' to SYNOPSIS section; + reordered options. + + * troff/input.cc (usage): Added missing `-ffam' to usage message. + + * Makefile.in (dist): groff-$(version).tar.gz must be removed + also, otherwise it is included itself in another call of `make + dist'. + + * groff/groff.cc (synopsis): Removed superfluous space. + + * PROJECTS, PROBLEMS, NEWS: Updated. + + * VERSION: Updated to 1.12beta. + + * BUG-REPORT: Some cosmetic fixes. Corrected email address. + + * README: Updated: Included documentation about CVS repository, + mailing lists, and daily snapshots. + + * tmac/Makefile.sub: Fixed $(tmap_wrap) finally. + +1999-09-12 Bjarni Ingi Gislason + + * tmac/tmac.an: If the tag didn't fit into the space that the + macro `TP' specifies, the rest of the tag went into the space for + the next line. + +1999-09-12 Jeffrey Copeland + + * grolj4/lj4.cc: Added duplex printing (option `-d'). + + * grolj4/grolj4.man: Document duplex printing. + +1999-09-12 Werner LEMBERG + + * doc/Makefile (pic.ps): Fixed rule which caused problems with + non-GNUish sed programs. + + * tmac/doc-syms: Removed extra space from -iso8802-3 macro + definition. + + * configure.in (LIBS): Added `-lc' + + * Makefile.comm (.man.n): Added substitution for @TMAC_AN_PREFIX@. + + * pic/tex.cc (solid_arc): Casting M_PI to double. + + * libgroff/putenv.c (putenv): Changed function header to ANSI C. + + * groff/groff.man, tmac/Makefile.sub (MAN7), tmac/groff_msafer.man + (new file), tmac/msafer.man (deleted), tmac/groff_me.man (new + file), tmac/me.man (deleted): {me,msafer} -> groff_{me,msafer}. + + * groff/groff_man.man: New file. This manual page was originally + written for the Debian GNU/Linux system by Susan G. Kleinmann + . + + * eqn/list.cc (list_box::compute_metrics, + list_box::compute_sublist_width): Removed variable declaration to + avoid shadowing warnings. + + * grops/psrm.cc (resource_manager::process_file): Ditto. + + * tfmtodit/tfmtodit.cc (main): Ditto. + + * libgroff/font.cc (font::load_desc): Renamed auxiliary variable + to avoid shadowing warnings. + + * tbl/table.cc (block_entry::do_divert, table::do_row): Renamed + shadowing loop variable. + + * groff/groff.man, troff/troff.man: Added doc about grohtml. + +1999-09-12 Gaius Mulley + + New grohtml frontend to convert groff input to html. + + * Makefile.in (CCPROGDIRS, DEVDIRS): Added html device. + + * tmac/Makefile.sub (NORMALFILES): Added tmac.html. + + * tmac/eqnrc: Added html device. + + * tmac/tmac.html: New file. + + * eqn/main.cc (do_file, inline_equation), pic/troff.cc + (troff_output::start_picture, troff_output::finish_picture), + tbl/main.cc (process_input_file): + Surrounded output with `graphics_start' and `graphics_end' so that + the html driver can identify non-text portions. + + * grodvi/dvi.cc (dvi_printer::set_char), grolj4/lj4.cc + (lj4_printer::set_char), grops/ps.cc (ps_printer::set_char), + grotty/tty.ps (tty_printer::set_char): Additional parameter + `name'. + + * include/printer.h: Class printer: New function + set_char_and_width; new variables (is_char_named, is_named_set, + named_command, named_char_s, named_char_n) to hold information + about named characters -- needed by the html driver. + + * libdriver/printer.cc (printer::set_ascii_char, + printer::set_special_char): Use set_char_and_width. + + * devhtml/*: New device files for html driver. + + * grohtml/*: New driver grohtml. + +1999-09-11 Wilfredo Sanchez + + * tmac/doc-common, tmac/tmac.an: Removed the word `UNIX' in + default strings. + +1999-09-11 Luke Mewburn + + * libgroff/string.cc (search): Small fix to test against NULL + pointer. + +1999-09-11 Jeff Conrad + + * troff/node.cc (copy): The characters in a bracket escape (e.g., + \b'abc') were stacked in reverse order when processed in a + diversion. + + * troff/node.h: Added `*last' to struct `node' to make the above + fix work. + + * troff/input.cc (read_draw_node), libdriver/input.cc (do_file): + The default scale for the 'f' and 't' graphics functions were 'm' + rather than 'u' (i.e., no scaling). + +1999-09-11 Peter Miller + + * groff/groff.cc (main), groff.man, soelim/soelim.cc (main, + do_file), soelim/soelim.man: Added `-I file' option to soelim, + defining include paths. + + * soelim/soelim.cc (include_path_append): New function. + +1999-09-11 Larry Jones + + * tbl/main.cc (process_options): Unix (at least Documenter's + Workbench) tbl allows arbitrary non-alpha characters between + options. + +1999-09-11 Paul Eggert + + Y2k fixes. Don't assume that the current year precedes 2000. + + * doc/meref.me: Add \n(y2, \n(y4. + + * tmac/doc-common (Yr): New number register. + (Dd): Don't assume current year precedes 2000. + + * tmac/tmac.e (td): Likewise. + (y2, y4): New number registers. + + * pic/pic.man: Update reference for pic paper to May, 1991 + version. + +1999-09-11 Werner LEMBERG + + * tmac/Makefile.sub (install_data, stamp-wrap, uninstall_sub): + Removed quotation marks which prevented correct expansion of + $(tmac_wrap). + + * devlj4/Makefile.sub (LJ4RES): Fixed value (600 instead of 300). + +1999-09-10 Werner LEMBERG + + * Makefile.sub (DISTCLEANFILES): Added `config.log' and + `config.cache'. + + * Removed configure.old. + +1999-08-31 Werner LEMBERG + + * VERSION: Updated to 1.11.1 + +1999-05-27 Werner LEMBERG + + * doc/Makefile: changed `.PS' postfix to `.ps' for consistency. + + * tmac/Makefile.sub (install_data, stamp-wrap, uninstall_sub): + added quotations around $(tmac_wrap) to avoid syntax error if + variable is empty. + + * configure: Newly generated using autoconf 2.13. + + * Makefile.in (LDFLAGS): Set variable to @LDFLAGS@. + +Fri Aug 15 08:51:47 1997 Eric S. Raymond + + * README, PROJECTS, NEWS, INSTALL, VERSION, + doc/Makefile. doc/pic.ms, groff/groff.man: + Prepare for 1.11 release. No code changes. + Documentation for pic added (doc/pic.ms). + +Sun Nov 26 11:45:13 1995 James Clark + + * Version 1.10 released. + +Fri Nov 24 09:56:16 1995 James Clark + + * afmtodit/afmtodit.pl: Avoid comment on first line. + +Mon Nov 20 11:13:49 1995 James Clark + + * aclocal.m4 (GROFF_INSTALL_SH): New macro. + * configure.in: Call it. + + * Makefile.sub (configure): Depends on aclocal.m4 not acgroff.m4. + (distfiles): Doesn't depend on config.log or config.cache. + +Sun Oct 1 08:45:36 1995 James Clark + + * grog/grog.sh: Use print "" rather than print in END rule. + +Wed Aug 23 13:30:52 1995 James Clark + + * tbl/main.cc (process_data): Don't give error for excess data + entries that are comments. + +Fri Jul 28 11:00:27 1995 James Clark + + * tbl/main.cc (process_data): Fix case where new for-scope rules + silently change meaning of code. + +Tue Jul 4 23:39:51 1995 James Clark + + * troff/env.cc (hyphenate): Loop over all consecutive sequences + of non-zero hyphenation codes. + +Sat Jul 1 00:42:15 1995 James Clark + + * aclocal.m4 (GROFF_POSIX): Use conflicting declaration technique. + +Thu Jun 29 13:58:36 1995 James Clark + + * tmac/tmac.e (ip): Divert the tag so as to freeze the spaces. + +Tue Jun 27 12:30:16 1995 James Clark + + * tmac/tmac.andoc: Make it work in compatibility mode. + + * refer/token.h (token_info::is_range_sep): New function. + * refer/token.cc (init_special_chars): Make \(en a RANGE_SEP. + * refer/ref.cc (reference::output): More sophisticated check for + multiple pages. + + * devps/prologue.ps (MANUAL): New procedure. + * grops/ps.cc (main): New -m option. + (usage): Include -m. + (ps_printer::~ps_printer): Implement -m. + + * aclocal.m4 (GROFF_G): New macro. + * configure.in: Call it. + * Makefile.in (g): Provided by configure. + + * hpftodit/hpftodit.cc (basename): Rename to xbasename. + + * tmac/tmac.tty: Disable warning about bad fonts. Remove font + translations. + + * Makefile.in (tmacpath): Don't include /usr/lib/tmac. + (tmac_m, tmac_s): Deleted. + (sys_tmac_prefix, tmac_wrap, tmac_prefix, tmac_an_prefix, + tmac_s_prefix): New variables. + (MDEFINES): Change accordingly. + * Makefile.comm (.man.n): Use new TMAC_* variables. + * configure.in (GROFF_TMAC): Call. + * aclocal.m4 (GROFF_TMAC): Define. + * tmac/Makefile.sub (stamp_wrap): New target. + (install_data, uninstall_sub): Handle macro wrapping. + +Mon Jun 26 14:54:39 1995 James Clark + + * tbl/main.cc (main): Ignore -T option. + +Thu Jun 22 09:08:06 1995 James Clark + + * devlj4/generate/special.map: Add definition of \(nb. + + * tmac/tmac.dvi: Add definition of \(nb. + + * troff/dictionary.c (dictionary::dictionary): association::v gets + initialized by association::association. + + * tmac/Makefile.sub: Avoid using temporary files when installing. + + * troff/env.cc (environment::set_font): Make bad font number a + warning. + + * Makefile.in (fontpath): Remove $(prefix)/lib/font from fontpath. + + * Makefile.in (datadir): Use share rather than lib. + + * groff/groff.cc (basename): Rename to xbasename. + +Wed Jun 21 16:59:46 1995 James Clark + + * Makefile (CCLIBS): Don't use. + * Makefile.ccpg: Likewise. + + * acgroff.m4: Rename to... + * aclocal.m4: Modify extensively for autoconf 2. + * configure.in: Likewise. + * Makefile.in: Likewise. + + * groff/pipeline.c (const): Declare as empty if __STDC__ not + defined. + (xstrsignal): Check for definition of NSIG. Conditionalize + on SYS_SIGLIST_DECLARED. Make return type const. + +Sat Jun 10 12:28:16 1995 James Clark + + * troff/input.cc (interpolate_macro): Rephrase missing space + warning. + +Thu May 11 01:07:16 1995 Jason Merrill + + * addftinfo/addftinfo.cc, eqn/delim.cc, eqn/lex.cc, eqn/list.cc, + grodvi/dvi.cc, groff/groff.cc, grops/ps.cc, grops/psrm.cc, + grotty/tty.cc, include/ptable.h indxbib/indxbib.cc, + libbib/index.cc, libbib/linear.cc, libbib/search.cc, + libdriver/input.cc, libdriver/printer.cc, libgroff/font.cc, + libgroff/lf.cc, libgroff/nametoindex.cc, libgroff/ptable.cc, + libgroff/string.cc, lkbib/lkbib.cc, lookbib/lookbib.cc, + pic/lex.cc, pic/object.cc, pic/pic.y refer/label.y refer/ref.cc, + refer/refer.cc, refer/token.cc, tbl/main.cc, tbl/table.cc, + tfmtodit/tfmtodit.cc, troff/dictionary.cc, troff/div.cc, + troff/env.cc, troff/input.cc, troff/node.cc, troff/symbol.cc: + Fix 'for' scoping. + +Wed Apr 19 21:15:11 1995 James Clark + + * troff/input.cc (spring_trap): Push a macro_iterator rather than a + string_iterator. + (spring_trap, postpone_traps, unpostpone_traps): Move to later in + file. + (macro_iterator::macro_iterator): Add additional argument. + +Mon Apr 10 12:06:02 1995 James Clark + + * troff/div.cc (vertical_size::vertical_size): In place of integer + specifying line spacing use cunits specifying post vertical + space. + (macro_diversion::output, top_level_diversion::output): Likewise. + * troff/div.h: Change declarations accordingly. + * troff/env.cc (pending_output_line): Replace ls field by post_vs + field. + (pending_output_line::pending_output_line, + pending_output_line::output, environment::output, + environment::output_line, environment::output_title, + environment::hyphenate_line): In place of + integer specifying line spacing use cunits specifying post vertical + space. + (environment::environment): Add post_vertical_spacing and + prev_post_vertical_spacing arguments. + (environment::get_post_vertical_spacing): New function. + (environment::total_post_vertical_spacing): New function. + (environment::post_vertical_spacing): New function. + (init_env_requests): Initialize pvs request and .pvs register. + * troff/env.h: Change declarations. + +Tue Mar 28 09:52:07 1995 James Clark + + * tmac/tmac.pspic: Immediately remove the temporary file. + +Sat Mar 25 10:43:11 1995 James Clark + + * tmac/tmac.pspic (PSPIC): Scale graphic uniformly even when + height is specified. + +Thu Jan 26 16:20:13 1995 James Clark + + * tbl/table.c (struct vertical rule, class table_entry): Use int + not short for start_row and end_row. + +Fri Jan 13 13:53:05 1995 James Clark + + * troff/input.cc (trapping_blank_line, blank_line_macro): New + functions. + (diverted_space_node::reread, process_input_stack): Call + trapping_blank_line() rather than blank_line(). + (init_input_requests): Bind "blm" to blank_line_macro(). + + * tmac/tmac.s (XA): Use .br and par@reset rather than XA. + +Tue Jan 10 11:40:35 1995 James Clark + + * troff/env.cc (environment::possibly_break_line): Require that + width total excluding width of final space node be greater than + the target text length. + +Tue Jan 3 09:13:37 1995 James Clark + + * troff/node.cc (kern_pair_node::vertical_extent): New function. + +Sun Dec 4 13:19:07 1994 James Clark + + * troff/node.cc (charinfo_node): New class. + (glyph_node, composite_node): Derive from charinfo_node. Change + member functions accordingly. + +Wed Nov 30 10:29:29 1994 James Clark + + * nroff/nroff.sh: Use -Tlatin1 not -TLatin1. + +Mon Aug 8 10:17:59 1994 James Clark (jjc@jclark.com) + + * tmac/tmac.tty-char: Add definitions for \(ab and \[arrowvertex]. + + * devps/generate/textmap (notsubset): Add. + + * tmac/tmac.a4: New file. + +Sun Jul 24 20:08:42 1994 James Clark (jjc@jclark.com) + + * pic/main.cc (had_parse_error): New variable. + (do_picture, do_whole_file): Set had_parse_error if yyparse() + returns non-zero. + (main): Return 1 if had_parse_error is true. + +Tue Jul 19 13:40:31 1994 James Clark (jjc@jclark.com) + + * grolj4/lj4.cc (main): Avoid use of strtoul. + +Mon Jul 18 15:03:02 1994 James Clark (jjc@jclark.com) + + * nroff/nroff.sh: Default device is -Tlatin1 if $LC_CTYPE is + iso_8859_1 or $LESSCHARSET is latin1. + +Sun Jul 10 13:38:35 1994 James Clark (jjc@jclark.com) + + * hpftodit: New directory. + * Makefile.in (CCPROGDIRS): Add hpftodit. + * devlj4/generate: New directory. + +Thu Jul 7 23:49:48 1994 James Clark (jjc@jclark.com) + + * configure.in: Don't use AC_VFORK. + * groff/pipeline.c (run_pipeline): Use fork() always. + +Wed Jul 6 11:13:17 1994 James Clark (jjc@jclark.com) + + * grops/ps.cc (main): Use %1 not %s in error message for -w. + + * Makefile.in (CCPROGDIRS): Add grolj4. + (DEVDIRS): Add devlj4. + * grolj4, devlj4: New directories. + * tmac/troffrc: Handle lj4. + * tmac/tmac.lj4: New file. + +Fri Jun 17 18:02:53 1994 James Clark (jjc@jclark.com) + + * tmac/tmac.e (@n): Set indent to 0 before calling |h. + +Wed Jun 1 07:33:47 1994 James Clark (jjc@jclark.com) + + * troff/input.cc (do_if_request): At end of second string, switch + environments before getting next token. + +Fri May 20 07:39:18 1994 James Clark (jjc@jclark.com) + + * devps/psstrip.sed: Split rule that strips whitespace on either + side of delimiters. + +Wed May 18 08:13:47 1994 James Clark (jjc@jclark.com) + + * troff/node.h (font_family::make_definition): Add return value to + declaration. * troff/symbol.h (symbol::operator==, + symbol::operator!=): Likewise. + +Tue May 17 20:46:06 1994 James Clark (jjc@jclark.com) + + * groff/groff.cc (main, help, synopsis): Handle -S. + (possible_command::insert_arg): New function. + + * tmac/tmac.safer: New file. + * tmac/msafer.man: New file. + * tmac/Makefile.sub (FILES): Add tmac.safer and msafer.man. + +Thu Mar 10 01:58:30 1994 Paul Eggert (eggert@twinsun.com) + + * pic/pic.h, pic/main.cc (safer_flag): New variable. + * pic/pic.y (placeless_element): Avoid unsafe operations if + `safer_flag' is set. + * pic/main.cc (main): Add -S option, which sets `safer_flag'. + +Tue May 10 13:02:31 1994 James Clark (jjc@jclark.com) + + * eqn/lex.cc (get_token): Put call to add_context() in block to + work around Sun C++ 4.0 bug. + + * include/stringclass.h (operator +): Use ?: instead of `if' to + work around Sun C++ 4.0 bug. + +Thu May 5 11:18:03 1994 James Clark (jjc@jclark.com) + + * tbl/main.cc (process_format): Accept - as a synonym for the _ + key letter. + + * libbib/index.cc (minus_one): Don't declare as const. + +Fri Apr 29 09:32:48 1994 James Clark (jjc@jclark.com) + + * troff/input.cc (get_char_for_escape_name): Push back a newline. + +Wed Apr 27 21:14:18 1994 James Clark (jjc@jclark.com) + + * troff/input.cc (write_macro_request): New function. + (init_input_requests): Bind write_macro_request to writem. + +Sun Apr 17 11:15:38 1994 James Clark (jjc@jclark.com) + + * tmac/tmac.s (@EN): Turn filling back on even if there was no + equation. + + * eqn/lex.cc (do_space): Supply missing argument to lex_error. + + * tmac/tmac.s (@TS): Renamed from TS. + (TS): Call LP then TS again. + (cov*ab-init): Alias @TS to TS. + + * tmac/tmac.s: Allow QP or RS to initialize. + + * tmac/tmac.s (par@load-init): New macro. Call at end of file. + Move initializations of PS and LL here. + (par@init): Don't initialize HY. Avoid changing environment 0. + (par*env-init): Don't all par@reset. + +Thu Apr 14 19:15:45 1994 James Clark (jjc@jclark.com) + + * include/posix.h: Include only if not using . + +Sun Apr 10 09:54:44 1994 James Clark (jjc@jclark.com) + + * Makefile.in (MDEFINES): Add LDFLAGS. + (LDFLAGS): Add definition line. + +Thu Apr 7 22:22:22 1994 James Clark (jjc@jclark.com) + + * troff/input.cc (get_optional_char): Split off error check into... + (check_missing_character): New function. + * troff/token.h: Declare it. + * troff/env.cc (margin_character): Don't call get_optional_char. + Only call tok.next() after making the node. + + * include/lib.h (getopt): Make 2nd argument char *const *. + +Fri Mar 11 07:28:03 1994 James Clark (jjc@jclark.com) + + * nroff/conftest.sh: Deleted. + +Fri Mar 4 10:51:36 1994 James Clark (jjc@jclark.com) + + * pic/make-dos-dist: Deleted. + +Wed Mar 2 20:59:16 1994 James Clark (jjc@jclark.com) + + * devps/psstrip.sed: Strip comments before stripping trailing + white space. + +Sat Feb 19 13:07:16 1994 James Clark (jjc@jclark.com) + + * Version 1.09 released. + +Wed Feb 16 16:53:49 1994 James Clark (jjc@jclark.com) + + * tmac/doc-ditroff (hK): Don't reset page number if \nC is > 0. + +Mon Feb 14 08:26:40 1994 James Clark (jjc@jclark.com) + + * libgroff/font.cc (font::load_desc): Fix typo in error message. + +Sun Feb 13 09:37:38 1994 James Clark (jjc@jclark.com) + + * libgroff/new.cc (operator new): Rewrite so as to avoid warning + about returning without a value. + + * troff/charinfo.h (charinfo::get_special_translation): Cast + TRANSLATE_NONE to int. + + * refer/token.cc (lookup_token, store_token): Remove bogus loop + test. Fix test so that it works with n unsigned. + + * pic/pic.y (defaults_table): Fully bracket initializer. + * pic/lex.cc (lookup_keyword): Likewise. + * eqn/lex.cc (token_table, def_table): Likewise. + * eqn/box.cc (param_table): Likewise. + * troff/input.cc (warning_table): Likewise. + * libgroff/font.cc (table): Likewise. + * grops/ps.cc (ps_printer::special): Likewise. + * grops/psrm.cc (resource_manager::process_file): Likewise. + * tfmtodit/tfmtodit.cc (lig_chars, lig_table): Likewise. + * refer/command.cc (command_table): Likewise. + * addftinfo/addftinfo.cc (param_table): Likewise. + + * troff/symbol.cc (symbol::symbol): Prevent compiler warnings + about temp's being unused. + (unused): New function. + + * groff/pipeline.cc: Declare c_fatal. + + * libbib/linear.cc (bmpattern::search): Cast patterrn[--j] to + uchar. + + * libbib/index.cc (index_search_item::load): Prevent compiler + warnings about fd_closer's being unused. + (unused): New function. + +Sat Feb 12 10:31:59 1994 James Clark (jjc@jclark.com) + + * troff/input.cc (copy_mode_error): Make `prefix' static. + Fix typo. + + * include/posix.h: Include is HAVE_CC_OSFCN_H is + defined. + * acgroff.m4, configure.in, Makefile: Rename HAVE_CC_UNISTD_H to + HAVE_CC_OSFCN_H and modify accordingly. + + * troff/input.cc (init_charset_table): radicalex overlaps + horizontally. + + * groff/acgroff.m4 (GROFF_ISC_SYSV3): New macro (from + udodo!hans@relay.NL.net). + * groff/configure.in: Call it. + + * groff/acgroff.m4 (GROFF_PCLOSE): New macro. + * groff/configure.in: Call it. + * include/lib.h: Conditionalize declaration of pclose. + + * troff/div.cc (last_page_number): New global variable. + (top_level_diversion::begin_page): Exit if we just printed the + last page. + * troff/div.h (last_page_number): Declare it. + * troff/input.cc (parse_output_page_list): Set last_page_number. + + * eqn/sqrt.cc: Rename \(rn to \[radicalex]. + * devps/S, devps/textmap, tmac/tmac.ps, tmac/tmac.dvi, + tmac/tmac.X: Likewise. + * tmac/tmac.ps, tmac/tmac.X, tmac.dvi: Add definitions of \(rn. + * tmac.dvi: Make \(ru and \(ul extend beyond their width by .04m. + +Fri Feb 11 11:45:40 1994 James Clark (jjc@jclark.com) + + * tmac/doc-ditroff (hK): Remove groff specific code which + prevented page-breaks between separate manual entries. If this is + the first page, don't set the page number to 1. + + * acgroff.m4 (GROFF_POSIX): New macro. + * configure.in: Use it. + + * troff/node.cc (class real_output_file, + real_output_file::real_output_file, + real_output_file::~real_output_file): Conditionalize use of + popen/pclose on POPEN_MISSING. + * troff/node.h: Conditionalize pipe_command on POPEN_MISSING. + * troff/input.cc (pipe_command): Give an error if POPEN_MISSING. + (pipe_source): Similarly. + + * acgroff.m4 (GROFF_PROG_CCC): Update message about libg++. + + * acgroff.m4 (GROFF_GETOPT, GROFF_PUTENV, GROFF_POPEN): Detect + presence of declarations by trying to compile example with + conflicting declarations. (gcc only gives a warning for missing + declarations.) + +Wed Feb 9 09:12:23 1994 James Clark (jjc@jclark.com) + + * tmac/tmac.pspic (PSPIC): Allow options to specify alignment + (from Ulrich Lauther). + +Tue Feb 8 03:56:40 1994 James Clark (jjc@jclark.com) + + * libbib/linear.cc (file_buffer::load): Use S_ISREG macro. + +Thu Feb 3 09:34:35 1994 James Clark (jjc@jclark.com) + + * indxbib/indxbib.cc (write_hash_table): Add code for case where + pointers and ints have different sizes. + +Sun Jan 9 16:17:51 1994 James Clark (jjc@jclark.com) + + * tmac/tmac.s (par*env-init): Call par@reset. + +Fri Jan 7 10:24:27 1994 James Clark (jjc@jclark.com) + + * tmac/tmac.s (@IP): Switch to a new environment when diverting + tag. + (par*push-tag-env, par*pop-tag-env): New macros. + +Wed Jan 5 21:18:34 1994 James Clark (jjc@jclark.com) + + * grops/ps.cc (ps_printer::ps_printer): Use MAX_LINE_LENGTH for + initializing `out'. Reduce MAX_LINE_LENGTH from 79 to 72. + + * grops/ps.cc (ps_printer::~ps_printer): Output %%CreationDate + comment. Include . + +Wed Dec 15 14:14:00 1993 James Clark (jjc@jclark.com) + + * grops/ps.cc (is_small_h, is_small_v): Deleted. + (ps_printer::flush_sbuf): Use absolute motion only at beginning of + lines. + +Tue Dec 14 10:06:34 1993 James Clark (jjc@jclark.com) + + * troff/input.cc (read_request): Only print a prompt if reading + from the terminal. Also clearerr on EOF if reading from the + terminal. Declare isatty. + +Mon Nov 29 08:38:15 1993 James Clark (jjc@jclark.com) + + * refer/label.y: Rename map_t to map_func and extractor_t to + extractor_func. + +Sat Oct 30 06:38:12 1993 James Clark (jjc@jclark.com) + + * include/assert.h: Don't use volatile. + * libgroff/assert.cc: Likewise. + +Fri Oct 29 15:00:23 1993 James Clark (jjc@jclark.com) + + * troff/input.cc (abort_request): Look at character in tok before + calling get_copy(). + +Thu Oct 28 14:09:48 1993 James Clark (jjc@jclark.com) + + * troff/troff.h (NO_RETURN): Deleted. + * troff/div.cc (cleanup_and_exit): Don't declare aas NO_RETURN. + * troff/input.cc (exit_troff): Likewise + + * Makefile.in: Remove `Making ...' messages since GNU make now + gives these. + + * configure.in: Use AC_HAVE_HEADERS(unistd.h) instead of AC_UNISTD_H. + +Wed Oct 27 11:12:51 1993 James Clark (jjc@jclark.com) + + * tmac/tmac.s (@init): Initialize PO to \n(.o here, rather than + to constant 1 inch. + +Sat Oct 23 10:03:52 1993 James Clark (jjc@jclark.com) + + * tmac/tmac.e (hl): Use \n[.in] rather than \n(.i. + +Thu Oct 14 12:09:45 1993 James Clark (jjc@jclark.com) + + * eqn/delim.cc (delim_box::compute_metrics): Don't increase + MARK_REG if there was no left delimiter. + +Sat Oct 2 19:54:47 1993 James Clark (jjc@jclark.com) + + * pic/troff.cc (troff_output::text): Set line thickness to + relative before outputting text. + + * tmac/tmac.e (@k): Don't zero ?T. + ((z): Likewise. + +Sat Sep 25 11:08:43 1993 James Clark (jjc@jclark.com) + + * tmac/tmac.e ($p): Handle possibility that $3 is empty. + +Wed Aug 18 08:51:41 1993 James Clark (jjc@jclark.com) + + * troff/input.cc (decode_args): Warn about unquoted tabs (from + Paul Eggert). + +Tue Aug 10 08:38:32 1993 James Clark (jjc@jclark.com) + + * troff/input.cc (ignoring): New variable. + (ignore): Set ignoring during call to do_define_macro. + (do_define_macro): Clear ignoring before interpolating terminating + macro. + (copy_mode_error): New function. + (get_char_for_escape_name, read_long_escape_name, + interpolate_arg): Use copy_mode_error. + (warning_table): Add WARN_IG. + * troff/troff.h (WARN_IG): Declare. + (WARN_TOTAL): Change accordingly. + + * groff/pipeline.c (strsignal): Rename to xstrsignal. + * groff/groff.cc (strsignal): Delete declaration. + +Fri Jul 16 01:43:12 1993 James Clark (jjc@jclark.com) + + * troff/div.cc (page_offset): Use 'm' as default scaling. + +Sat Jul 3 09:11:38 1993 James Clark (jjc@jclark.com) + + * nroff/nroff.sh: Ignore -u. + +Wed Jun 9 12:17:27 1993 James Clark (jjc@jclark.com) + + * Makefile.in (MDEFINES): Pass down MAKEOVERRIDES. + +Fri Jun 4 17:35:47 1993 James Clark (jjc@jclark.com) + + * tmac/tmac.s (par*box-draw): Set adjustment mode to l while + drawing box. + (B2): With -Tascii, leave additional vertical space before + and after. Ensure that the left and right indent is restored to + what it was even if the point size changes. Don't call + par@finish. Change the indent, line length and title length + directly. With -Tascii, make the width of the box 1n less. + (B1): Remember 1n at the current point size. Don't call + par@reset. Change the indent, line length and title length + directly. Ensure that the temporary indent is preserved. + (par*box-mark-top): Turn off no spacing mode. + +Thu Jun 3 17:47:14 1993 James Clark (jjc@jclark.com) + + * Makefile.in (dist): Use .gz suffix. + +Thu May 27 20:04:59 1993 James Clark (jjc@jclark.com) + + * troff/input.cc (main): Add return 0. + * pic/main.cc (main): Use return instead of exit. + * tbl/main.cc (main): Likewise. + * eqn/main.cc (main): Likewise. + * grops/ps.cc (main): Likewise. + * grotty/tty.cc (main): Likewise. + * groff/groff.cc (main): Likewise. + * grodvi/dvi.cc (main): Likewise. + * refer/refer.cc (main): Likewise. + * indxbib/indxbib.cc (main): Likewise. + * lkbib/lkbib.cc (main): Likewise. + * soelim/soelim.cc (main): Likewise. + * addftinfo/addftinfo.cc (main): Likewise. + * acgroff.m4 (GROFF_PROG_CCC, GROFF_CC_COMPILE_CHECK, + GROFF_COOKIE_BUG, GROFF_CC_ANSI_BUG): Likewise. + + * troff/token.h (process_input_stack): Don't declare as static. + * troff/input.cc: Likewise. + + * troff/node.c (invalidate_fontno): Make it a static member of + class font_family. Change callers. + * troff/node.c: Change declaration. + + * tbl/main.cc (struct input_entry_format): Add explicit public + specifier. + * tbl/table.cc (struct text_stuff, struct single_hline_stuff, + struct double_hline_stuff): Likewise. + * tbl/table.h (struct entry_format): Likewise. + * pic/object.h (struct saved_state): Likewise. + + * include/stringclass.h: Add forward declarations of friend + functions that are later declared as inline. Don't include inline + specifier in friend declaration. + + * libgroff/lib.h: Declare popen and pclose. + * acgroff.m4 (GROFF_POPEN): New macro. + * configure.in: Call it. + + * include/lib.h (PI): New constant. Undef first if necessary. + * tfmtodit/tfmtodit.cc (main): Use PI rather than M_PI. + * grops/ps.cc (degrees, radians): Likewise. + * libgroff/font.cc (font::get_skew): Likewise. + + * grops/ps.cc (is_ascii): New function. + (ps_output::put_string): Use is_ascii. Use csprint rather than + isprint. + (ps_printer::define_encoding): Use csspace. + * libgroff/strtol.c (ISASCII): New macro. + (strtol): Cast arguments to is*() and tolower() to unsigned char. + Use ISASCII rather than isascii. + * libgroff/cmap.cc: Use isascii() only if defines it. + * libgroff/cset.cc: Likewise. + * libdriver/input.cc: Include cset.h. + (do_file, get_integer, possibly_get_integer): Use csdigit() rather + than isdigit(). + + * refer/refer.cc (main): Use %ld rather than %d for longs. + + * libbib/index.cc (index_search_item_iterator::get_tag): Use + S_ISREG macro. + + * addftinfo/addftinfo.cc (param_t): Add explicit `int'. + +Mon May 24 08:51:37 1993 James Clark (jjc@jclark.com) + + * troff/input.cc (hyphenation_code): Skip white space between + char/code pairs. + +Sun May 16 08:15:52 1993 James Clark (jjc at jclark.com) + + * tbl/table.h (table::entry_list_tailp): New member. + (table::table): Initialize it. + (table::add_entry): Use entry_list_tailp to avoid O(n^2) + behaviour. + +Sat May 15 17:26:00 1993 James Clark (jjc at jclark.com) + + * grotty/tty.cc (tty_printer::add_char): Don't discard characters + with negative horizontal positions. Remove casts of glyph::hpos to + int. + (USHRT_MAX): Delete definition. + (SHRT_MAX, SHRT_MIN): New definitions. + (glyph::hpos): Change type to short. + (tty_printer::end_page): Output multiple backspaces if necessary. + Remove casts of glyph::hpos to int. + +Fri May 7 12:14:37 1993 James Clark (jjc at jclark.com) + + * tmac/tmac.s (@RT): New definition. + +Thu May 6 21:36:54 1993 James Clark (jjc at jclark.com) + + * refer/refer.cc (do_file): Make sure current_filename is set when + filename is "-". + + * pic/common.cc (common_output::dot_line): Handle zero length + lines. + +Sun May 2 19:54:16 1993 James Clark (jjc at jclark.com) + + * tmac/tmac.s (par@reset): Get value for .hy for \n[HY]. + (par@init): Initialize \n[HY]. + +Mon Apr 26 11:43:16 1993 James Clark (jjc at jclark.com) + + * troff/dictionary.cc (dictionary::remove): Continue when + r < j < i. + +Sun Apr 25 11:03:00 1993 James Clark (jjc at jclark.com) + + * Makefile.com (.y.cc): Avoid ending up with two versions of + $(YTABH). + +Thu Apr 22 21:03:45 1993 James Clark (jjc at jclark.com) + + * tmac/tmac.dvi (\(,c): Define only if it does not exist. + (\(,C): Likewise. Also fix typo. + +Wed Apr 21 08:47:32 1993 James Clark (jjc at jclark.com) + + * lib.h: Delete extraneous semi-colon. + + * Add pso request: `so' from a pipe. + * troff/input.c (file_iterator::file_iterator): Add 3rd argument. + (file_iterator::close): New function. + (file_iterator::~file_iterator, file_iterator::next_file): Use + file_iterator::close. + (file_iterator::backtrace): Say `process' rather than `file' when + the stream is popened. + (pipe_source): New function. + (init_input_requests): Bind ".pso" to pipe_source. + +Tue Apr 20 00:02:26 1993 James Clark (jjc at jclark.com) + + * afmtodit/afmtodit.pl: Avoid single quotes in comments. + + * pfbtops/pfbtops.c: Output 64 characters per line. Output hex + digits in lower case. + +Mon Apr 19 09:55:57 1993 James Clark (jjc at jclark) + + * Version 1.08 released. + + * Makefile.in (dist): Insert || true after ln -s commands that + might fail. + + * mm: Update to mm 1.16. + + * acgroff.m4 (GROFF_CSH_HACK): New macro. + * configure.in: Call GROFF_CSH_HACK. Substitute for + SH_SCRIPT_SED_CMD. + * Makefile.in (SH_SCRIPT_SED_CMD): New variable. Include in + MDEFINES. + * nroff/Makefile.sub (nroff): New target. + (install_data): Install nroff. + * eqn/Makefile.sub (neqn): Sed with SH_SCRIPT_SED_CMD. + * grog/Makefile.sub (grog): Sed grog.sh with SH_SCRIPT_SED_CMD. + +Sat Apr 17 08:24:28 1993 James Clark (jjc at jclark) + + * eqn/Makefile.sub (neqn): Add chmod +x. + + * grog/Makefile.sub (grog): Remove spurious semi-colon. + +Fri Apr 16 22:41:57 1993 James Clark (jjc at jclark) + + * troff/input.cc (string_iterator::string_iterator()): Initialize + lineno and count. + +Tue Apr 13 10:22:28 1993 James Clark (jjc at jclark) + + * troff/div.cc (macro_diversion::space, + top_level_diversion::space): Don't set high_water_mark. + (macro_diversion::output, top_level_diversion::output): Don't + include post line space in high water mark. + +Wed Apr 7 12:48:18 1993 James Clark (jjc at jclark) + + * eqn/eqn.y: Don't define YYDEBUG. + * pic/pic.y: Likewise. + +Mon Apr 5 10:15:15 1993 James Clark (jjc at jclark) + + * tmac/tmac.e ([3): Add space after comma following editors. + Change double spaces to single spaces. + ([4): Change double spaces to single spaces. + + * grops/ps.h (USE_PS_ADOBE_2_0): New flag for broken_flags. + * grops/ps.cc (ps_printer::~ps_printer): If the USE_PS_ADOBE_2_0 + bit is set in broken_flags, use 2.0 rather than 3.0 as the version + after %!PS-Adobe- (for Newsprint). + + * troff/div.cc (top_level_diversion::begin_page): When + before_first_page is 1, set page_number to 1. + +Sun Apr 4 14:28:53 1993 James Clark (jjc at jclark) + + * eqn/box.cc (box::top_level): Protect equation with \&. + +Sat Apr 3 23:27:25 1993 James Clark (jjc at jclark) + + * groff/groff.cc (possible_command::set_name): Delete old name. + + * groff/groff.cc (possible_command::~possible_command): Use + a_delete. + + * troff/node.cc (troff_output_file::begun_page): New member. + (troff_output_file::troff_output_file): Initialize it. + (troff_output_file::really_begin_page): Only output V command if a + page has been begun. + + * pic/pic.y (placeless_element): Delete argument to PRINT after + use. + +Fri Apr 2 11:31:02 1993 James Clark (jjc at jclark) + + * Make wrapman work. + * troff/div.h (class top_level_diversion): Replace + first_page_begun by before_first_page (with opposite sense). + * Change first_page_begun to before_first_page inverting sense. + * troff/div.cc (class nl_reg): New class. + (init_div_requests): Use class nl_reg for \n(nl. + (top_level_diversion::begin_page): Don't call + output_file::begin_page if before_first_page is 2; + reset before_first_page afterwards. If have_next_page_number is + false, then always increment page_number. + * tmac/tmac.an: Set traps within TH rather than at the top-level. + Restore compatibility mode after loading, and then disable + compatibility mode in TH. + +Thu Apr 1 11:09:34 1993 James Clark (jjc at jclark) + + * grotty/tty.cc (tty_printer::end_page): Don't discard characters + past last line. + * troff/node.h (output_file::trailer): Declare. + * troff/div.cc (cleanup_and_exit): Call output_file::trailer(). + * troff/node.cc (output_file::trailer): New function. + (troff_output_file::~troff_output_file): Move most code into... + (troff_output_file::trailer): New function. + (class troff_output_file): Delete page_length member. Declare + trailer(). + (troff_output_file::really_begin_page): Use current page length + for final V command. + + * tbl/main.cc (struct options): New decimal_point_char member. + (options::options): Initialize this. + (process_options): Implement decimalpoint option. + (process_data): Pass decimal_point_char option to table::table. + * tbl/table.h (class table): New decimal_point_char member. + (table::table): Add additional argument. + * tbl/table.cc (find_dot): Rename to find_decimal_point. Add + second argument specifying decimal point character. Use this + instead of '.'. + (table::table): Initialize decimal_point_char. + (table::add_entry): Change call to find_dot. + + * troff/input.cc (get_copy, token::next): Implement \V. + (interpolate_environment_variable): New function. + +Tue Mar 30 14:41:39 1993 James Clark (jjc at jclark) + + * pic/lex.cc (lookup_keyword): Rename MIN to K_MIN, MAX to K_MAX. + * pic/pic.y: Likewise. + + * grotty/tty.cc (tty_printer::add_char, tty_printer::end_page): + Add casts to int. + * refer/ref.cc (reference::insert_field, reference::delete_field): + Likewise. + * troff/number.cc (parse_term): Likewise. + + * acgroff.m4 (GROFF_PROG_YACC): New macro. + * configure.in: Use GROFF_PROG_YACC. + + * acgroff.m4 (GROFF_PROG_CCC): Don't add -O automatically for gcc + and g++. + * Makefile.in (OPTIMIZE): New define. + (DEBUG): Empty by default. + (CCFLAGS, CFLAGS): Include $(OPTIMIZE). + + * acgroff.m4 (GROFF_SYS_SIGLIST): Don't quote program. + (GROFF_ARRAY_DELETE): Likewise. + (GROFF_CC_COMPILE_CHECK): Quote use of $2 and $3. + + * troff/env.cc (trie::~trie): Make virtual to shut up g++. + + * devps/psstrip.sed: Use different delimiter on last line (so that + it works with BSD 4.4 sed.) + +Mon Mar 29 17:07:14 1993 James Clark (jjc at jclark) + + * devps/psstrip.sed: Delete comments. + + * acgroff.m4 (AC_GETOPT): Don't test whether declares + optind, opterr, optarg. + * lib.h: When UNISTD_H_DECLARES_GETOPT is defined, declare optind, + opterr, optarg. + +Sun Mar 28 17:44:25 1993 James Clark (jjc at jclark) + + * Makefile.in (check): Dummy target. + +Wed Mar 3 04:53:38 1993 James Clark (jjc at jclark) + + * Version 1.07 released. + + * Integrate mm 1.11. + + * tbl/table.cc (alphabetic_block_entry::print): start_row was used + where start_col was meant. + +Thu Feb 25 07:55:36 1993 James Clark (jjc at jclark) + + * grog/grog.sh, grog/grog.pl: Recognize PH and SA as -mm macros. + +Wed Feb 24 10:15:34 1993 James Clark (jjc at jclark) + + * troff/input.cc (token::next): Make \z\o'...' and similar things + work. + + * env.h (MARGIN_CHARACTER_ON, MARGIN_CHARACTER_NEXT): New + constants. + (environment): Add margin_character_flags member. + * env.cc (environment::environment(symbol), + environment::environment(const environment *): Initialize + margin_character_flags. + (margin_character): Rewrite. + (environment::output_line): Add a margin character if + margin_character_flags is non-zero. Turn off the + MARGIN_CHARACTER_NEXT bit. If that makes margin_character_flags + zero, use margin_character_node without copying and then set + margin_character_node to 0. + + * devps/DESC.in: Change minimum size to 1000. + +Tue Feb 23 14:57:49 1993 James Clark (jjc at jclark) + + * troff/symbol.h (symbol::hash): Change return type to unsigned + long. + * troff/dictionary.cc (dictionary::lookup, dictionary::remove): + Add casts to int. + + * test-groff: Use -r rather than -x. + + * grops/psfig.diff: Include in distribution again. + +Mon Feb 22 09:10:44 1993 James Clark (jjc at jclark) + + * Makefile.in (dist): Use gzip. + +Sun Feb 21 11:12:53 1993 James Clark (jjc at jclark) + + * acgroff.m4 (GROFF_GETOPT): Check for declaration of getopt() in + unistd.h as well as in stdlib.h. + * include/lib.h: Include is STDLIB_H_DECLARES_GETOPT is + defined; otherwise include and if + UNISTD_H_DECLARES_GETOPT is defined. + + * configure.in: use builtin(include, ... rather than include(... + * configure: Regenerate with autoconf 1.3. + + * libdriver/print.cc (printer::adjust_arc_center): Use new + algorithm suggested by Andy Fyfe. + + * libdriver/printer.cc (printer::adjust_arc_center): New function. + * include/printer.h: Declare this. + * grops/ps.cc (ps_printer::draw): Use it. + * grodvi/dvi.cc (dvi_printer::draw): Use it. + +Fri Feb 19 23:13:51 1993 James Clark (jjc at jclark) + + * Makefile.comm (.man.n): Replace macrodir by tmacdir. + +Thu Feb 11 16:46:59 1993 James Clark (jjc at jclark) + + * eqn/main.cc (main): Handle "eqn -". + +Mon Jan 4 20:29:56 1993 James Clark (jjc at jclark) + + * tmac/tmac.e (++): Install fix from comp.bugs.4sd. + + * mm: Integrate version 1.08. + + * pic/troff.cc (troff_output::finish_picture): Set + EQN_NO_EXTRA_SPACE reg to 0 rather than removing it. + * eqn/box.cc (box::extra_space): Set EQN_NO_EXTRA_SPACE_REG to 0 + if it's not defined. Check whether the register is non-zero rather + than whether it's not defined. + * tmac.e ({, <): Make argument to \x zero if \n(0x is non-zero. + + * indxbib/indxbib.cc: Move all signal handling into... + * indxbib/signal.c: New file. + * configure.in: Call AC_RETSIGTYPE. + + * acgroff.m4 (GROFF_STRUCT_EXCEPTION): New macro. + * configure.in: Call GROFF_STRUCT_EXCEPTION. + * libgroff/matherr.c: Protect with ifdef HAVE_STRUCT_EXCEPTION. + + * troff/input.cc (token::token, token::operator=): Work round SGI + C++ bug. + * pic/object.cc (position::position): Likewise. + +Mon Dec 28 21:50:21 1992 James Clark (jjc at jclark) + + * pic/pic.h: Move declaration of hypot(). + +Wed Dec 16 12:28:29 1992 James Clark (jjc at jclark) + + * pic/pic.h: Declare hypot(). + + * pic/pic.h: Define M_PI if necessary. + +Thu Dec 10 12:03:29 1992 James Clark (jjc at jclark) + + * tmac/tmac.e (re): Add alternative version that doesn't use groff + `.ta T' feature. + + * devps/prologue.ps (RE): Handle the possibility that the old font + doesn't have a FontName entry. + +Wed Dec 2 10:25:29 1992 James Clark (jjc at jclark) + + * tmac/tmac.e (fam): Redefine to set family in environment 2. + (@C): Use @fam not fam. + +Thu Nov 26 16:01:25 1992 James Clark (jjc at jclark) + + * lookbib/lookbib.cc (main): Change type of start to const char *. + * lkbib/lkbib.cc (main): Likewise. + + * eqn/lex.cc (definition::definition): Don't use member + initializer syntax for members of anonymous unions. + + * troff/input.cc (input_stack::backtrace): Change type of to const + char *. + +Wed Nov 25 13:43:09 1992 James Clark (jjc at jclark) + + * include/stringclass.h (class string): Declare inline friend + functions as inline in class declaration. + * troff/hvunits.h (class hunits, class vunits): Likewise. + * include/refid.h (class reference_id): Likewise + * troff/troff.h (points_to_units(units), scale(units, double)): + Delete declarations. + * libdriver/input.cc (get_char): Delete declaration. + * include/lib.h: Change 2nd argument of getopt from const char ** + to char **. + * troff/symbol.cc (symbol::symbol): Cast `new char *[n]' to `const + char **' before assigning to a `const char **'. + * tbl/table.cc: Delete extra declarations of prints(). + +Tue Nov 24 14:33:13 1992 James Clark (jjc at jclark) + + * libgroff/font.cc (font::load_desc): Cast `new char *[n]' to `const + char **' before assigning to a `const char **'. + + * libgroff/errarg.cc (errarg::errarg): Don't use member + initializer syntax for members of anonymous unions. + +Sat Nov 21 05:02:23 1992 James Clark (jjc at jclark) + + * mm: Integrate version 1.07. + +Tue Nov 17 16:44:27 1992 James Clark (jjc at jclark) + + * troff/input.c (translate2): Rename to + (translate_no_transparent). + (init_input_requests): Rename tr2 to trnt. + +Mon Nov 16 09:49:32 1992 James Clark (jjc at jclark) + + * troff/charinfo.h (class charinfo): Add transparent_translate field. + (charinfo::set_translation, charinfo::set_special_translation): + Add second argument that specifies value for + transparent_translate. + (charinfo::get_translation, charinfo::get_special_translation): + Add optional second argument that specifies whether translation is + being used for transparent throughput. + * troff/input.cc (charinfo::set_translation, + charinfo::set_special_translation): Handle second argument. + (charinfo::charinfo): Initialize transparent_translate. + (translate): Split main part off into + (do_translate): New function. Pass argument saying whether + translation applies to transparent throughput. + (translate2): New request. + (init_input_requests): Bind translate2 to `tr2'. + +Wed Nov 11 11:43:20 1992 James Clark (jjc at jclark) + + * tbl/table.h (class table): Add `nokeep' flag. + * tbl/main.cc (process_options): Handle `nokeep' option. + * tbl/table.cc (table::init_output, table::do_row, table::do_top, + table::do_bottom): Don't output keep/release macro definitions or + calls when `nokeep' option has been specified. + +Sat Nov 7 01:28:33 1992 James Clark (jjc at jclark) + + * tmac/tmac.Xps (Xps-char): Use " as delimiter for \Z. + +Wed Nov 4 16:29:04 1992 James Clark (jjc at jclark) + + * tbl/table.cc (table_entry::divert, block_entry::do_divert, + block_entry::divert, alphabetic_block_entry::divert): Add extra + argument giving column separation. + (table::compute_widths): Pass column separation to + table_entry::divert(). + (block_entry::do_divert): If an entry spans multiple columns and a + minimumum width has been specified for each column, then set the + line length to the sum of the widths (plus possibly the column + separations). + + * troff/input.cc (set_escape_char): Don't set the escape_char + until after calling has_arg(). + +Tue Nov 3 11:23:27 1992 James Clark (jjc at jclark) + + * tbl/table.cc (table::do_top): Add missing \s0 for double box + case. + + * tbl/table.cc (table::print_double_hline): Avoid extra new line + in case where r > nrows - 1. + + * tbl/table.cc (BODY_HEIGHT): Deleted. + (LINE_SEP): New definition. + (table::print_single_hline, table::print_double_hline, + table::compute_vrule_top_adjust, table::compute_vrule_bot_adjust, + table::do_row, table::do_top): Use LINE_SEP space before a line + instead of \n[.v]-BODY_HEIGHT-BODY_DEPTH. + + * tbl/table.cc (text_entry::print_contents): New function. + (text_string_name, right_text_string_name): Deleted. + (TEXT_STRING, RIGHT_TEXT_STRING): Deleted. + (simple_text_entry::do_width, numeric_text_entry::do_width, + alphabetic_text_entry::do_width): Don't store the contents of the + entry in a string. + (left_text_entry::simple_print, right_text_entry::simple_print, + center_text_entry::simple_print, + alphabetic_text_entry::simple_print, + numeric_text_entry::simple_print): Print the entry directly + instead of using the stored string. + +Fri Oct 30 10:39:32 1992 James Clark (jjc at jclark) + + * devps/Makefile: Strip PostScript files. + * devps/prologue: Rename to... + * devps/prologue.ps. + * devps/psstrip.sed: New file. + * devps/download: Use .pfa rather than .ps for installed versions + of fonts. + +Thu Oct 29 09:14:43 1992 James Clark (jjc at jclark) + + * troff/env.cc (input_trap): Give a warning if the argument is out + of range. + + * troff/env.cc (adjust): Treat negative argument as missing. Round + argument > 5 down to 5. + + * troff/env.cc (center, right_justify): Make negative argument zero. + + * troff/div.cc (page_offset, vertical_position_traps): Treat + invalid argument as missing. + * troff/env.cc (line_spacing, line_length, title_length, indent, + underline, hyphen_line_max_request, control_char, + no_break_control_char, widow_control_request, adjust, input_trap, + point_size): Likewise. + * troff/node.cc (ligature, kern_request, bold_font, track_kern, + constant_space): Likewise. + * troff/input.cc (compatible, shift, warn_request, + set_escape_char): Likewise. + + * tbl/main.cc (format::format): Avoid doing `new int[0]'. + * tbl/table.cc (table::table): Likewise. + + * Makefile.dev (install_dev): depends on $(DEVFILES). + +Wed Oct 28 08:30:57 1992 James Clark (jjc at jclark) + + * devX75, devX75-12, devX100, devX100-12: New directories. + * Makefile.in: Add these to DEVDIRS. + + * troff/Makefile.sub, eqn/Makefile.sub, indxbib/Makefile.sub, + afmtodit/Makefile.sub, tmac/Makefile.sub, nroff/Makefile.sub, + grog/Makefile.sub, mm/Makefile.sub (uninstall_sub): New target. + * Makefile.in (uninstall, uninstall_sub, uninstall_dirs): New + targets. + * Makefile.ccpg, Makefile.cpg, Makefile.dev, Makefile.man + (uninstall): New target. + * Makefile.comm (uninstall, uninstall_sub, uninstall_man, + uninstall_prog, uninstall_dev): New targets. + + * troff/div.cc (return_request): Treat an invalid argument as + missing. + +Mon Oct 26 11:33:47 1992 James Clark (jjc at jclark) + + * tmac/tmac.e ((f): Set up the environment even when there's a + current diversion. Transparently throughput a call to @N. + (@N): New macro. + +Thu Oct 22 05:05:59 1992 James Clark (jjc at jclark) + + * tbl/table.cc (table::compute_vrule_top_adjust): Round adjustment + up to vertical resolution. + + * tbl/table.cc (table::do_row): Change row number after printing + stuff list. + + * pic/lex.cc (get_token_after_dot): Make .left and .right work. + +Wed Oct 21 14:46:45 1992 James Clark (jjc at jclark) + + * Rename CHANGES to NEWS. + +Tue Oct 20 23:25:21 1992 James Clark (jjc at jclark) + + * libgroff/new.cc (operator new): Avoid calling malloc(0). + +Mon Oct 19 09:10:13 1992 James Clark (jjc at jclark) + + * man.ultrix: Removed. + +Sun Oct 18 06:35:15 1992 James Clark (jjc at jclark) + + * Makefile.comm (extraclean): Delete files whose names begin with + `='. + + * pic/troff.cc (troff_output::text): Fix typo in implementation of + aligned text. + +Sat Oct 10 09:32:29 1992 James Clark (jjc at jclark) + + * troff/env.cc (hyphenate_request, vertical_spacing, no_number): + * troff/div.cc (page_length, need_space, space_request): Treat + invalid optional argument as missing. + * troff/env.cc (number_lines): If the first argument is present + but not a number, turn on line numbering, don't change the next + line number and parse the remaining arguments. + + * tmac/tmac.e (@q): Do the `ne' before changing to environment 2. + +Thu Oct 8 10:24:40 1992 James Clark (jjc at jclark) + + * eqn/box.h: Change declaration accordingly. + * eqn/box.cc (set_gsize): Change return type to int. Return 0 if + the specified size was bad but don't give an error. Check for + overflow. + * eqn/main.cc (main): Change caller. Leave validation to set_gsize. + * eqn/lex (do_size): Likewise. + +Wed Oct 7 09:48:59 1992 James Clark (jjc at jclark) + + * acgroff.m4 (GROFF_PROG_CCC): Use fopen when checking for C++ + compatible headers. + +Sun Oct 4 18:24:02 1992 James Clark (jjc at jclark) + + * tbl/table.cc (table::init_output): Improve error message when + table won't fit on one page. + +Fri Oct 2 10:41:40 1992 James Clark (jjc at jclark) + + * pic/troff.cc (troff_output::start_picture): Generate line + containing a horizontal motion equal to the width of the picture. + + * groff/groff.cc (main): Allow PROG_PREFIX to be set at runtime + using GROFF_COMMAND_PREFIX environment variable. + +Fri Sep 25 11:40:40 1992 James Clark (jjc at jclark) + + * mdate.sh: Use $NF rather than $(NF). + +Tue Sep 22 09:47:24 1992 James Clark (jjc at jclark) + + * pic/main.cc (main): Use %1 not %c in argument to warning. + + * eqn/main.cc (main): Output code to check that geqn was given the + correct -T option. + +Mon Sep 21 10:59:16 1992 James Clark (jjc at jclark) + + * Makefile.in (dist): Instead of doing `make -f ../Makefile', do + `ln -s ../Makefile .; make; rm -f Makefile'. + + * troff/hyphen: Rename to... + * troff/hyphen.us: + * troff/input.cc (main): Delete -H option. Don't call + read_hyphen_file(). + * troff/env.cc: Include searchpath.h and macropath.h. + (exception_dictionary): Deleted. + (ht): Deleted. + (read_hyphen_file): Deleted. + (hyphenation_language): New struct. + (class trie, class hyphen_trie): Move declarations up. + (trie_node::~trie_node): Deleted. + (trie::delete_trie_node): New function. + (trie::do_delete): New pure virtual function. + (hyphen_trie::do_delete): New function. + (trie::~trie): New function. + (hyphen_trie::~hyphen_trie): New function. + (trie::clear): No need to check that tp is not 0. + (current_language, language_dictionary): New variables. + (hyphen_word): Give an error if no current language. Use + exceptions dictionary in current language. + (hyphen_trie::read_patterns_file): Find file using macro_path. + Allow comments (starting with %) in patterns file. Don't make it + a fatal error if the file can't be found. + (hyphenate): Return if no current language. Get the exceptions + dictionary and the hyphenation patterns from the current language. + (set_hyphenation_language): New variable. + (hyphenation_patterns_file): New function. + (hyphenation_language_reg): New class. + (hyphenation_language_reg::get_string): New function. + (init_hyphen_requests): Bind "hla" to set_hyphenation_language and + "hpf" to hyphenation_patterns_file. Initialize `.hla' number + register. + * groff/groff.cc (main, help, synopsis): Delete -H option. + * include/Makefile.sub: Don't define HYPHENFILE. + * Makefile.in: Delete hyphenfile variable and remove from MDEFINES. + * Makefile.comm (.man.n): Don't substitute for HYPHENFILE. + * tmac/troffrc: Set hyphenation language to `us'. Load `hyphen.us' + hyphenation patterns. + +Sun Sep 20 09:33:02 1992 James Clark (jjc at jclark) + + * eqn/neqn.sh: New file. + * eqn/Makefile.sub: Handle neqn.sh. + + * eqn/eqn.h: Declare `nroff' variable. + * eqn/box.cc (param_table): Add `nroff' param. + (nroff): Define it. + * eqn/lex.cc (yylex): Handle TDEFINE and NDEFINE using `nroff' + variable. + * tmac/eqnrc: Set `nroff' to 1 for -Tascii or -Tlatin1. + + * troff/troff.h (WARN_FONT): New warning. + (WARN_TOTAL): Change accordingly. + * troff/input.cc (DEFAULT_WARNING_MASK): Include WARN_FONT. + (warning_table): Add WARN_FONT. + * troff/node.cc (mount_font_no_translate): Pass argument to + font::load_font. If this is non-zero, give a warning. + Don't give an error message when accessing a font that has already + been found to be invalid. + * include/font.h (font::load, font::load_font): Add additional + optional argument which suppresses error message if the font is + not found. + * libgroff/font.cc (font::load_font): Handle additional argument. + (font::load): Add additional argument. If this is non-null, set it + to 1 and don't give error message. + + * include/printer.h (printer::end_page): Add argument giving + length of page. + * libdriver/input.cc (do_file): Pass this. + * grops/ps.cc (ps_printer::end_page): Add argument. + * grodvi/dvi.cc (dvi_printer::end_page, + draw_dvi_printer::end_page): Add argument. + * grotty/tty.cc (class tty_printer): Remove lines_per_page and + columns_per_page members. New member nlines. + (DEFAULT_LINES_PER_PAGE): Deleted. + (tty_printer::tty_printer): Don't compute lines_per_page from + font::paperlength. Don't compute columns_per_page from + font::paperwidth. + (tty_printer::add_char): Don't check horizontal position against + columns_per_page. Grow glyphs vector if necessary. + (tty_printer::end_page): Add argument giving page_length in units. + Discard lines past end of page. + +Wed Sep 16 06:29:52 1992 James Clark (jjc at jclark) + + * tmac/tmac.tty-char: Fix definition of \(/l. + + * tmac/tmac.X: Define \(en. + +Tue Sep 15 10:37:13 1992 James Clark (jjc at jclark) + + * acgroff.m4 (GROFF_PRINT): If a system has lpr and lp but not + lpq, then use lp rather than lpr. + + * tmac/tmac.s (par@reset): Don't call `ad'. + (par*env-init): Call `ad'. + +Sun Sep 13 18:48:20 1992 James Clark (jjc at jclark) + + * mdate.sh: Use $(NF) instead of $6 to extract year from output of + date. + + * troff/symbol.cc: #undef BLOCK_SIZE if it's defined. + * indxbib/indxbib.cc: Likewise. + +Sun Sep 6 09:44:46 1992 James Clark (jjc at jclark) + + * libgroff/putenv.c: New file. + * libgroff/Makefile.sub: Add putenv.c to CSRCS. + * Makefile.in: Say that putenv.o can be one of LIBOBJS. + * configure.in: Test for putenv with AC_REPLACE_FUNCS. Test for + stdlib.h with AC_HAVE_HEADERS. + +Sat Sep 5 18:11:52 1992 James Clark (jjc at jclark) + + * indxbib/dirnamemax.c: Include only if + does not exist. + +Fri Sep 4 09:43:26 1992 James Clark (jjc at jclark) + + * eqn/box.cc (gsize): Make it an int. + (set_gsize): Parse argument handling increment or decrement. + (box::top_level): Convert gsize to a string. + + * troff/input.cc (exit_troff): Make buf unsigned char []. + Call to make_temp_iterator casts buf to char*. + + * Makefile.in ($(TARGETS), dot): Pass $(MDEFINES) to recursive makes. + + * Makefile.ccpg (depend.temp): Depends on $(YTABC). + * Makefile.cpg (depend.temp): Likewise. + + * Makefile.dep: Remove Makefile.dep from $(REALCLEANFILES). + + * Makefile.comm: Add y.output to MOSTLYCLEANFILES. + +Thu Sep 3 08:01:55 1992 James Clark (jjc at jclark) + + * tmac/tmac.s (B, I, BI, CW): Rewrite avoiding aliases. + +Tue Sep 1 18:24:53 1992 James Clark (jjc at jclark) + + * Version 1.06 released. + + * Integrate mm 1.04. + +Fri Aug 28 11:28:19 1992 James Clark (jjc at jclark) + + * Makefile.comm, Makefile.ccpg, Makefile.cpg: Fix TAGS target. + +Thu Aug 27 11:03:33 1992 James Clark (jjc at jclark) + + * afmtodit/afmtodit.pl: Add -n option that disables generation of + ligatures command. + * devps/generate/Makefile (CR, CB, CI, CBI): Pass -n flag to + afmtodit. Regenerate. + + * tmac/tmac.e ()z): Adjust _b if necessary so as to avoid moving + @f back past the current position. + + * tmac/tmac.e: Change calls to @R so that comments are not part of + arguments. + +Tue Aug 25 10:42:07 1992 James Clark (jjc at jclark) + + * configure.in: Check for mkstemp with AC_HAVE_FUNCS. + + * acgroff.m4 (GROFF_PROG_CCC): Don't check for . Instead + check that we can link a call to a function declared in . + (GROFF_UNISTD_H): New macro. + * configure.in: Call it. + * Makefile.in: Document it. + * include/posix.h: New file. + * troff/troff.h: Don't include + * troff/input.cc: Include posix.h. + * libgroff/new.cc, libgroff/tmpfile.cc: Include posix.h rather than + osfcn.h. + * indxbib/indxbib.cc, libbib/{search.cc,linear.cc,index.cc}: + Include posix.h rather , , , + . + * indxbib/indxbib.cc (S_IRUSR, S_IRGRP, S_IROTH): Delete definitions. + * libbib/index.cc (S_ISREG, O_RDONLY): Delete definitions. + * libbib/search.cc (O_RDONLY): Delete definition. + * refer/refer.cc, include/driver.h, pic/pic.h, groff/groff.cc: + Don't include . + + * acgroff.m4 (GROFF_TIME_T): New macro. + * configure.in: Call it. + * Makefile.in: Document it. + + * acgroff.m4 (GROFF_TRADITIONAL_CPP): New macro. + * configure.in: Call it. + * Makefile.in: Document -DTRADITIONAL_CPP. + * include/ptable.h: Don't include generic.h. + (name2): Define it. + + * tmac/tmac.s (][): Make [T1 and [T2 aliases for [T. + Afterwards remove [T1 and [T2. + (ref*spec!0, ref*spec!2): Use T1 rather than T. + (ref*spec!1, ref*spec!4, ref*spec!4): Use T2 rather than T. + (ref*add-T2): Renamed from ref*add-T. + (ref*add-T1): New macro. + +Mon Aug 24 11:11:11 1992 James Clark (jjc at jclark) + + * acgroff.m4 (AC_PROG_CCC): Use GROFF_EXIT rather than exit 1. + + * libbib/index.cc: Include . + (O_RDONLY): Define if necessary. + (make_index_search_item, index_search_item_iterator::get_tag, + index_search_item::check_files): Use O_RDONLY. + * libbib/search.cc: Include , , . + (O_RDONLY): Define if necessary. + (search_list::add_file): Use O_RDONLY. + * indxbib/indxbib.cc: Include , , + . + (S_IRUSR, S_IRGRP, S_IROTH): Define if necessary. + (main): Use these. + + * libbib/index.cc (S_ISREG): Define it if necessary. + (index_search_item::load): Use S_ISREG. + + * include/driver.h: Include . + +Sun Aug 23 11:32:18 1992 James Clark (jjc at jclark) + + * eqn/box.cc (body_height): Increase default value to 85. + (body_depth): Increase default value to 35. + +Fri Aug 21 05:34:42 1992 James Clark (jjc at jclark) + + * eqn/pbox.h (SAVE_FONT_STRING): Define it. + * eqn/box.cc (box::top_level): Hide use of \R in a string that is + protected from expansion with \E. + + * acgroff.m4 (GROFF_PAGE): Use `case' to test domain. + + * Makefile (Makefile): New target. + + * Makefile.sub (configure, distfiles): New targets. + + * acgroff.m4 (GROFF_BROKEN_SPOOLER_FLAGS): Avoid using ${var:-val} + construct. + +Thu Aug 20 12:27:26 1992 James Clark (jjc at jclark) + + * eqn/box.cc (param_table): Add body_height and body_depth. + + * eqn/lex.cc (def_table): Make circumflex in hat_def roman. + +Tue Aug 18 16:24:25 1992 James Clark (jjc at jclark) + + * psbb/Makefile.sub: Don't link with libgroff.a. + + * acgroff.m4 (GROFF_PUTENV): New macro. + * configure.in: Call GROFF_PUTENV. + * Makefile.in: Document STDLIB_H_DECLARES_PUTENV. + * groff/groff.cc: Don't declare putenv if STDLIB_H_DECLARES_PUTENV + is defined. + + * troff/env.cc (distribute_space): Rename force_forward argument + to force_reverse. Reverse the list if force_reverse is true. + +Mon Aug 17 17:49:05 1992 James Clark (jjc at jclark) + + * tmac/tmac.an: Don't define a string `T'. Just define Tm. + + * eqn/pile.cc (matrix_box::compute_metrics): Don't allow computed + height or depth to be negative. Guard against SUP_RAISE quantity + being negative. + +Sat Aug 15 08:18:54 1992 James Clark (jjc at jclark) + + * devps/generate/textmap: Add `an' (arrowhorizex). + * tmac/tmac.ps: \(an overlaps horizontally. + * tmac/tmac.dvi, tmac/tmac.tty: Add `an'. + + * devps/symbolchars: Add arrowverttp, arrowvertbt. + * devps/textmap: Add arrowvertex. + * eqn/delim.cc (delim_table): Add uparrow, downarrow and + updownarrow delimiters. + * tmac/tmac.ps, tmac/tmac.X: Add definition of \(va. + + * tbl/table.cc (simple_entry::position_vertically, + block_entry::position_vertically): For a centered entry, perform + the motion in two stages. + + * refer/refer.cc (split_punct): Don't call lookup_token if there + is no token. + +Fri Aug 14 11:14:58 1992 James Clark (jjc at jclark) + + * troff/input.cc (token::next): Delete token_node after copying + token. + + * grodvi/grodvi.cc (dvi_printer::dvi_printer): Initialize + cur_point_size. + + * libdriver/printer.cc (printer::load_font): Delete old_font_table. + + * grops/ps.cc (ps_printer::define_encoding): Delete elements of vec. + +Tue Aug 11 13:50:38 1992 James Clark (jjc at jclark) + + * grops/ps.cc (usage): -b option takes an argument. + + * devps/prologue (PLG): New procedure. + * grops/ps.cc (main, usage): New -g option. + (ps_printer::~ps_printer): If guess_flag is set, guess the paper + length using PLG. + +Mon Aug 10 11:17:53 1992 James Clark (jjc at jclark) + + * include/cset.h: Include if we have it. + + * libgroff/illegal.cc: New file. + * include/lib.h (illegal_input_char): Use table. + * troff/input.cc (ESCAPE_RIGHT_PARENTHESIS): Renumber to 0206. + * pic/lex.cc (ARG1): Renumber to 14. + * eqn/lex.cc (ARG1): Likewise. + + * troff/Makefile.sub (majorminor.cc): Handle 3 part versions + (eg 1.05.90) correctly. + +Sun Aug 9 13:35:43 1992 James Clark (jjc at jclark) + + * tmac/tmac.e (sr): Deleted. Set $r and $R directly. + Rename $r and $R registers to $v and $V. + ($r, $R): Initialize to 0. + (@v, @V): New macros. + (sz): Call @v. + (@M): Call @V. + + * troff/input.cc (main, usage): Add -R option that says not to + load troffrc. + * eqn/main.cc (main, usage): Rename -n to -R. + +Sat Aug 8 00:16:00 1992 James Clark (jjc at jclark) + + * devps/DESC.in: Leave font positions 5-9 blank. + * devdvi/DESC.in: Likewise. + + * grog/grog.pl: Handle `.PS 0. + + * macros/tmac.e (@R, @S): New macros. + Declare @, po, $0, $i, $p, df, so, fu, bt, *, ?a, ?b, ?C, ?e, ?H, + ?I, ?n, ?o, ?R, ?s, ?T, ?W, ?w registers with @R. + Declare $H, $[0-9], .. macros with @S. + Declare |0, |1, |2, |3 strings with @S. + + * macros/tmac.e (@S): Rename to @U. + + * macros/tmac.e (@z): Define @b and bp as empty instead of + deleting them, + + * macros/tmac.e (@m): Deleted. + (@h): Don't call @m. + (@z): Don't set @m trap. + + * macros/tmac.e ($h, $f): Define |z as empty string. + + * macros/tmac.e (@D): Rework to avoid unbalanced .el requests. + (@q): Likewise. + + * macros/tmac.e (@h): Set ?H, ?C , ?s registers to 0 rather than + removing them. + ()f): Likewise for * register. + + * macros/tmac.e (sr): Don't ever scale the arguments. If the third + argument is missing, don't change $R. Call sr with three + arguments when initializing. + +Thu Jul 16 12:17:12 1992 James Clark (jjc at jclark) + + * macros/tmac.e (sr): New macro. + Initialize $r and $R using sr. + + * macros/tmac.e (,): Delete \*(#[. + + * troff/env.c (set_tabs): Read the tab type even if the position + is bad. Allow the position of the first tab stop to be negative. + +Wed Jul 15 13:14:37 1992 James Clark (jjc at jclark) + + * refer/dirnamemax.c: Use pathconf() if defines + _POSIX_VERSION. + * refer/Makefile: Compile dirnamemax.c using -DHAVE_UNISTD_H + rather than -DPATHCONF_MISSING. + * Makefile: Get rid of PATHCONF_MISSING. + + * refer/map.c: New file. + * refer/index.c: Interface to mmap through map.c. Rename map_size + to map_len. + * refer/Makefile: Handle map.c. + * Makefile: Include -DHAVE_MMAP in OLDCFLAGS rather than CFLAGS. + +Tue Jul 14 14:15:20 1992 James Clark (jjc at jclark) + + * Makefile: RANLIB should be `true' if there is no ranlib. + * lib/Makefile (libgroff.a): Simplify. + * driver/Makefile (libdriver.a): Simplify. + + * Makefile: Change -DWAIT_COREDUMP_0200 to -DWCOREFLAG=0200. + * groff.c (WCOREDUMP): Use WCOREFLAG. Define only if not already + defined. + +Sat Jul 11 09:19:17 1992 James Clark (jjc at jclark) + + * troff/env.c (compare_ranges): Declare as extern "C". + + * troff/input.c (init_registers): Use `struct tm' instead of `tm'. + + * macros/tmac.s, macros/tmac.e: Change .nx /dev/null to .nx. + +Wed Jul 8 11:52:27 1992 James Clark (jjc at jclark) + + * pic/troff.c (troff_output::text): Merge in grops_output::text, + but conditionalize use of \X based on \*(.T. + (grops_output::*): Deleted. + * pic/output.h: Delete declaration of make_grops_output. + * pic/main.c (main): Ignore -p and -x. driver_extension_flag is 1 + by default. -n sets it to 0. + (usage): Corresponding changes. + * groff.c (main): Don't pass -x or -p to pic. + * groff.sh: Likewise. + + * ps/ps.c (ps_printer::do_exec, ps_printer::do_file): Force ndefs + to be non-zero. + + * ps/devps/afmtodit: Change calculation of asc_boundary and + desc_boundary. Make these bounds inclusive. + * ps/devps: Regenerate font files. + +Tue Jul 7 13:14:15 1992 James Clark (jjc at jclark) + + * macros/tmac.latin1: New file. + * macros/tmac.tty-char: Use tmac.latin1. + (tmac.tty-tr): Deleted. + * macros/Makefile: Install tmac.latin1. + * macros/tmac.dvi: Use tmac.latin1. + * macros/troffrc: Translate \[char160] onto no-break space here. + * macros/{tmac.dvi,tmac.ps,tmac.tty,tmac.X75}: Don't do it here. + +Mon Jul 6 11:06:52 1992 James Clark (jjc at jclark) + + * macros/tmac.Xps: Use `do' request. + + * macros/tmac.ps: Use `do' request. + + * macros/tmac.e (@C): Use `do' request. + + * macros/tmac.X, macros/tmac.Xps: Moved from xditview. + * macros/Makefile: Install tmac.X*. + + * tty/tmac.tty, tty/tmac.tty-char: Move to macros. + * tty/Makefile: Don't install tmac.tty*. + * macros/Makefile: Install tmac.tty*. + + * dvi/tmac.dvi: Move to macros. + * dvi/Makefile: Don't install tmac.dvi. + * macros/Makefile: Install tmac.dvi. + + * ps/tmac.ps*: Move to macros. + * ps/Makefile: Don't install tmac.ps*. + * macros/Makefile: Install tmac.ps*. + + * eqn/box.c: Provide draw_lines parameter corresponding to -D + option. + * macros/eqnrc: Set draw_lines parameter based on device. + * groff.c: Don't pass -D flag to eqn. + * groff.sh: Likewise. + * eqn/main.c: Warn about use of -D. + + * troff/input.c (process_startup_file): New function. + (main): Call process_startup_file(). + * macros/troffrc: New file. + * macros/Makefile: Install troffrc. + * groff.c (main): Don't pass extra -m option to troff. For a + pseudo device pass the name of the pseudo device to troff using + -d. + * groff.sh: Likewise. + * groff.c (possible_command::prepend_arg): Deleted. + + * troff/input.c (do_request): New function. + (init_input_requests): Bind "do" to do_request. + + * eqn/main.c (main): Instead of loading eqnchar from device directory, + load eqnrc from macro directory. + * macros/eqnrc: New file. + * macros/Makefile: Install eqnrc. + * ps/devps/eqnchar: Deleted. + * ps/devps/Makefile: Don't install eqnchar. + * dvi/devdvi/eqnchar: Deleted. + * dvi/devdvi/Makefile: Don't install eqnchar. + * groff.c (main): Pass -M to eqn. Don't pass -F to eqn. New + variable optM. + + * lib/device.[ch]: New files. + * lib/font.h (font::set_device_name, font::get_device_name): + Deleted. + * lib/fontfile.c: Use device.h. + * lib/Makefile: Handle device.[ch]. Make paths.h define DEVICE. + * troff/input.c: Delete definition of `device'. + (main): Don't initialize device. + * troff/troff.h: Include device.h rather than declaring device. + * troff/Makefile: No need to handle DEVICE. + * driver/input.c: Include device.h. Don't use + font::{set,get}_device_name. + * groff.c, Makefile: Rename device.h to config.h. + * groff.c: Use library device variable. + * eqn/main.c: Use library device variable. + * eqn/Makefile: No need to handle DEVICE. + + * lib/searchpath.[ch]: New files. + * lib/Makefile: Handle searchpath.[ch]. + * troff/input.c (open_file, init_dirs): Deleted. + (macro_dirs): Deleted. + (open_mac_file, macro_source): Use class search_path. + (add_string, struct string_list): Move definition. + (main): Change -M option to use macro_path. Delete call to + init_dirs(). + * lib/fontfile.c (font::command_line_font_dir, font::open_file): + Rewrite to use class search_path. + * lib/font.h, lib/fontfile.c (font::cl_font_dirs): Deleted. + * lib/Makefile: fontfile.c depends on searchpath.h. + * lib/Makefile: Rename fontpath.h to paths.h. Make paths.h define + MACROPATH. + * lib/macropath.[ch]: New files. + * troff/Makefile: No need to handle MACROPATH. + + * troff/input.c: Delete DUMP code. + * lib/fontfile.c, lib/font.h: Delete + font::forget_command_line_font_dirs. + + * troff/input.c (push_token): New function. + (handle_first_page_transition): Use push_token(). + (process_input_stack): Change handling of a space at the beginning + of the line. + +Sun Jul 5 17:11:09 1992 James Clark (jjc at jclark) + + * troff/input.c (font_dirs): Delete unused variable. + + * eqn/lex.c (do_set): Correct error messages. + +Sat Jul 4 10:20:55 1992 James Clark (jjc at jclark) + + * troff/input.c (do_define_string): Allow the string name to be + followed immediately by a tab. + (define_character): Likewise. + +Thu Jul 2 10:59:15 1992 James Clark (jjc at jclark) + + * ps/ps.c (ps_printer::draw): When drawing an arc, don't allow k to + be negative. + + * troff/input.c (input_iterator::is_file): New virtual function. + (file_iterator::is_file): New function. + (input_stack::end_file): New function. + (input_stack::next_file): Handle the situation where there is no + file on the input stack correctly. Avoid making two passes over + the input stack. + (next_file): Make the filename optional; in this case call + input_stack::end_file(). + +Wed Jul 1 10:17:25 1992 James Clark (jjc at jclark) + + * dvi/tmac.dvi: Change the definitions of \(ul and _ so that they + produce a real _ character when the current font is CW and _ + otherwise. + + * lib/errarg.c (errarg::errarg(const char *)): Invert conditional + expression to work around gcc 2.2 bug. + +Wed Jun 24 08:12:24 1992 James Clark (jjc at jclark) + + * eqn/main.c (main): Don't give an error if we can't find eqnchar. + + * troff/env.c (environment::add_padding): New function. + (environment::add_char): Use add_padding(). + (environment::space): Likewise. + (environment::wrap_up_field): Add some padding if there is none + and there's no current tab. + * troff/env.h: Declare environment::add_padding. + +Mon Jun 22 08:37:45 1992 James Clark (jjc@jclark) + + * pic/pic.y: undef fmod and rand before declaring them. + +Sun Jun 14 11:40:18 1992 James Clark (jjc@jclark) + + * troff/input.c (main): If the DESC file specifies a font name of + 0, then leave the corresponding font position empty. + + * nroff.sh: New file. + * Makefile (install.nobin): Install nroff.sh. + + * tty/devlatin1/R.proto: Add ao as synonym for de. + * tty/tmac.tty-char: Define ao as o. + + * tty/dev{ascii,latin1}/R.proto: Add aq. + * tty/tmac.tty-char: Delete definition of aq. + +Mon Jun 8 11:43:20 1992 James Clark (jjc@jclark) + + * troff/input.c (init_charset_table): Don't translate 0240. + * ps/tmac.ps: Translate char160 to space. + * dvi/tmac.dvi: Likewise. + * tty/tmac.tty: Likewise. + +Sun Jun 7 10:52:35 1992 James Clark (jjc@jclark) + + * dvi/tmac.dvi: Add support for all Latin-1 characters. + + * macros/tmac.s: Delete definitions of \(rg, \(ah, \(ad, \(a-, + \(ao, \(ac, \(ho, \(-D, \(Sd, \(TP, \(Tp, \(ss, \(AE, \(ae, \(OE, + \(oe, \(r?, \(r!. + + * tty/tmac.tty-char: Add \(ah. + + * dvi/tmac.dvi: Add definitions of Tp, TP, Sd, -D, ho. + No need to define \(FM and \(!/. Conditionalize all character + definitions. + + * ps/devps/lgreekmap: Add +h, +f, +p. + + * ps/tmac.psnew: New file. + * ps/Makefile: Install tmac.psnew. + + * troff/input.c (charinfo_to_node_list): Don't ever interpret + character definitions in compatible mode. + + * troff/input.c (remove_character): New function. + (init_input_requests): Bind remove_character to "rchar". + + * ps/tmac.psold: New file. + * ps/Makefile: Install tmac.psold. + * ps/tmac.ps: Load tmac.psold. Move definitions of ISO Latin-1 + characters into tmac.psold. Make these definitions unconditional. + + * tty/tmac.tty-char: Define \n(_C only if it is not already defined. + + * ps/tmac.ps: Don't define \('c and \('C. + + * ps/devps/textmap: Move Greek characters to... + * ps/devps/symbolchars: + +Sat Jun 6 16:41:17 1992 James Clark (jjc@jclark) + + * ps/devps/text.enc: Add quotesingle. + * ps/devps/textmap: Add +h, +f, +p, Fn, Bq, bq, aq, lz. + * tty/tmac.tty-char: Likewise. + * dvi/devdvi/texmi.map: Add +h, +f, +p. + * dvi/devdvi/texi.map: Add Fn. + * dvi/devdvi/msam.map: Add lz. + * dvi/tmac.dvi: Handle Bq, bq, aq. + + * pic/lex.c (get_token): Recognize 'th. + * pic/map.y: Allow `expr'th in contexts where ORDINAL was allowed. + +Fri Jun 5 11:20:46 1992 James Clark (jjc@jclark) + + * ps/devps/textmap: Move di, mu, +- to... + * ps/devps/symbolchars: + + * macros/tmac.s (@XS): Don't call par@reset or fi. + (XA): Call LP. Turn off adjustment. Reduce line length. + + * macros/tmac.s: Initially alias XS to LP. + (XS): Rename to @XS. + (cov*ab-init): Alias XS to @XS. + +Thu Jun 4 09:12:05 1992 James Clark (jjc@jclark) + + * troff/token.h: Delete TOKEN_CHAR_HEIGHT, TOKEN_CHAR_SLANT, + TOKEN_FONT_NAME, TOKEN_FONT_POSITION, TOKEN_SIZE tokens. + (token::is_size, token::changes_env): Deleted. + * troff/number.c (parse_term): No need to process \s explicitly. + Call tok.next() only after scale indicator has been processed. + * troff/input.c (do_overstrike, do_bracket): No need to process \s, + \f etc explicitly. + (token::next): Handle \s, \f, \S, \H immediately rather than + returning them as tokens. + (token::operator==, token::description, token::add_to_node_list, + token::process): Remove handling of deleted tokens. + + * troff/env.c (environment::add_char): When adding padding + indicator character, call start_line() if necessary. + +Wed Jun 3 09:55:50 1992 James Clark (jjc@jclark) + + * ps/devps/afmtodit: Don't output 0 kerns. + + * ps/devps/afmtodit: Remove directory from name of encoding in + font description file. + + * ps/devps/afmtodit: Improve error messages. + + * ps/devps/afmtodit: Allow DESC file to be specified with -d. + + * ps/devps/Makefile: Incorporate FontMakefile. Rework. + * ps/devps/FontMakefile: Deleted. + * ps/devps/afmname: New file. + + * ps/devps/symbol.sed: New file. + * ps/devps/symbol.diff: Deleted. + * ps/devps/FontMakefile: Generate symbol.afm using symbol.sed. + Generate zapfdr.afm from zapfd.afm. + + * tty/tmac.tty (tty-char): Prefix definition with ". + + * macros/tmac.an (TP): Don't start a diversion if one has already + been started. + + * tty/tmac.tty-char: Add Latin-1 characters. + + * tty/tmac.tty-char: Incorporate suggestions from Paul Eggert. + +Tue Jun 2 00:54:34 1992 James Clark (jjc@jclark) + + * tbl/table.c (table::allocate): Delete old_vline, old_entry. + Move declaration of struct horizontal_span. + + * tbl/table.c (table::table): Initialize span_list. + (table::~table): Delete span_list. + + * lib/ptable.h (PTABLE(T)::~PTABLE(T)): Delete v. + + * ps/devps/Makefile: Avoid dependency on GNU make. + + * ps/tmac.ps: Check that character does not already exist before + defining it. + + * tty/tmac.tty: Add definitions of \(ff, \(!=, \(==, \(~=, \(sq, + \(OE, \(oe, \(AE, \(ae, \(lh, \(rh. Delete definitions of \(en, + \(ru, \(ul, \(br, \(bv, \(sl which are in the font description + files. + + * tty/tmac.tty-char: New file. + * tty/Makefile: Install tmac.tty-char. + * tty/tmac.tty: Move definitions of \(ua, \(da, \(uA, \(dA into + tmac.tty-char. + + * tty/tmac.tty: Fix definition of \(34. + + * tty/dev{ascii,latin1}/R.proto: Add ha and ti. Map + bracket-drawing characters onto |. Add *o. + + * troff/env.c (environment::wrap_up_tab): Increment field_spaces + only if current_field. + + * troff/dictionary.c (dictionary::lookup): Free old_table after + rehashing. + +Mon Jun 1 10:15:22 1992 James Clark (jjc@jclark) + + * tty/dev{ascii,latin1}/R.proto: Add uppercase Greek characters + whose glyphs are identical to glyphs of some Roman character. + + * tty/devlatin1/R.proto (bu): Deleted. + * tty/devascii/R.proto (bu): Deleted. + * tty/tmac.tty: Add definition of \(bu. + + * eqn/main.c (do_file): Pass FILE as argument. + (main): Automatically load eqnchar. New options -F and -n. + Pass do_file an opened FILE. + * groff.c: Don't pass eqnchar to eqn. Pass -F options onto eqn. + No need to include font.h. + * groff.sh: Likewise. Don't need to use - for standard input. + Prefix files with -- if first file starts with -. + + * macros/tmac.e: Conditionalize use of \$* on \n(.g. + + * troff/env.c (environment::possibly_break_line): Don't set line + to 0 across call to output_line(). Don't call output_line() until + after discarding nodes after break. + +Sun May 31 10:45:29 1992 James Clark (jjc@jclark) + + * request.h (macro::empty): Declare it. + * input.c (macro::empty): New method. + (interpolate_macro): Don't give a WARN_SPACE if the two-character + macro is empty. + +Sat May 30 10:27:15 1992 James Clark (jjc@jclark) + + * troff/env.c (environment::start_field): Decrement space_total + when a space is frozen. + +Fri May 22 14:34:38 1992 James Clark (jjc@jclark) + + * macros/tmac.an (R): Delete macro. + + * troff/input.c (get_copy, token::next): Support \# (like \" but + newline is ignored). + + * troff/input.c (token::next): Fix error message in 'Y' case. + +Thu May 21 09:26:24 1992 James Clark (jjc@jclark) + + * eqn/delim.c (define_extensible_string): Recognize any prefix of + a delimiter name. + +Fri May 15 10:20:41 1992 James Clark (jjc at jclark) + + * c++test.c: Include . + + * lib/strtol.c, lib/getcwd.c, ps/psbb.c: Declare errno in case + doesn't. + +Fri May 8 09:37:19 1992 James Clark (jjc at jclark) + + * tbl/table.c (table::divide_span): Don't count column separation + if expand was specified. + + * tbl/main.c (process_format): Don't ignore width specs in + continued format. Give warning for changing equal widths or + column separation in continued format. + (process_data): Set column separation, minimum width, equal + columns at end of table. + +Thu May 7 08:50:40 1992 James Clark (jjc at jclark) + + * troff/node.c (kern_pair_node::add_discretionary_hyphen, + node::add_discretionary_hyphen): Use soft_hyphen_char. + (set_soft_hyphen_char): New function. + (init_node_requests): Bind to shc. Initialize soft_hyphen_char. + + * Makefile (c++tested): Give more helpful message if test fails. + +Tue May 5 10:58:39 1992 James Clark (jjc at jclark) + + * troff/input.c (init_charset_table): Translate 0240 to + an unbreakable space. + + * troff/token.h (token::hyphen_indicator): New function. + * troff/charinfo.h (TRANSLATE_HYPHEN_INDICATOR): New special + translation. + * troff/input.c (translate): Allow translation to \%. + * troff/node.c (node::add_char): Handle + TRANSLATE_HYPHEN_INDICATOR. + (make_node): Don't allow TRANSLATE_HYPHEN_INDICATOR here. + + * troff/input.c (init_charset_table): Don't set BREAK_AFTER flag + for \(hy. + + * tty/devlatin1/R.proto: \(hy and - should print as 055. + +Tue Apr 21 09:24:42 1992 James Clark (jjc at jclark) + + * groff.c (run_commands): If the last command gets a SIGPIPE send + a SIGPIPE to all children than haven't yet terminated. When + command terminates, set pid field to -1. + +Fri Apr 17 11:20:48 1992 James Clark (jjc at jclark) + + * groff.c (main): Pass an appropriate -filename option to gxditview. + +Thu Apr 16 15:11:40 1992 James Clark (jjc at jclark) + + * Makefile.bd (install): Remove existing program before copying. + + * Makefile, */Makefile, Makefile.bd, groff.sh, groff.c: Allow + programs which have Unix counterparts to be installed with + user-specified prefix. + + * troff/input.c (exit_troff): Don't check if exit_started. + (exit_request): Don't call exit_troff if exit_started. + + * Makefile.bd (install.mm): Rename to install.dwbmm. + +Tue Apr 14 10:05:10 1992 James Clark (jjc at jclark) + + * driver/input.c (do_file): Add missing break for '#' case. + +Mon Apr 13 10:11:02 1992 James Clark (jjc at jclark) + + * troff/input.c (input_stack::clear): Clear past any boundaries and + then add the boundaries back. + + * troff/input.c (exit_troff): Return immediately if already + exiting. + + * macros/tmac.s (pg@end-text): New macro. Use pg@end-text for the + end macro. + (pg*end-page): If the text has ended and there are no more + footnotes or keeps, exit. + + * macros/doc-ditroff (Lq, Rq): Define as \(lq and \(rq. + + * troff/input.c (init_charset_table): Make \(rq transparent by + default. + + * macros/tmac.an: Define lq and rq strings. + + * macros/tmac.s (Q, U): Define as \(lq and \(rq. + +Sun Apr 12 12:54:37 1992 James Clark (jjc at jclark) + + * troff/env.c (environment::final_break): New function. + (environment::newline): Set prev_line_interrupted to 2 if + exit_started. + * troff/env.h: Declare environment::final_break. + * troff/input.c (exit_troff): Call environment::final_break() + instead of environment::do_break(). + + * macros/Makefile: Install man.local if $(MACRODIR)/man.local + doesn't already exist. + * macros/man.local: New file. + * macros/tmac.an: Load man.local. + * macros/man.ultrix: New file. + +Sat Apr 11 17:32:04 1992 James Clark (jjc at jclark) + + * troff/input.c (exit_groff): Rename to... + (exit_troff): New function. + + * troff/div.c (exit_started, done_end_macro, + seen_last_page_ejector): New global variables. + (began_page_in_end_macro): New static variable. + (exit_flag): Deleted. + (top_level_diversion::top_level_diversion): Initialize + last_page_count. + (top_level_diversion): More elaborate test for whether + cleanup_and_exit() should be called. + Set began_page_in_end_macro if the end macro isn't yet finished. + * troff/div.h (top_level_diversion::last_page_count): New data + member. + (top_level_diversion::set_last_page): New function. + (exit_started, done_end_macro, seen_last_page_ejector): Declare. + * troff/env.c (do_break): Zero prev_line_interrupted. + * troff/input.c (exit_flag): Delete declaration. + (LAST_PAGE_EJECTOR): New magic cookie. + (token::next): Handle LAST_PAGE_EJECTOR. + (exit_groff): Set exit_started and done_end_macro instead of + exit_flag. Call top_level_diversion::set_last_page. Push a + LAST_PAGE_EJECTOR instead of calling push_page_ejector(). Do + another ejection after setting seen_last_page_ejector. + +Thu Apr 9 04:37:11 1992 James Clark (jjc at jclark) + + * etc/grog.sh, etc/grog.sh: Recognize -me sh macro. + + * macros/tmac.e (TH): Make sure there's room for the initial + header. + + * macros/tmac.s (par@init): Make PD and DD at least \n(.V. + Set FVS in points rather than units. + +Mon Apr 6 11:21:32 1992 James Clark (jjc at jclark) + + * troff/div.c (top_level_diversion::add_trap): Don't consider the + position of empty slots. + +Fri Apr 3 10:46:45 1992 James Clark (jjc at jclark) + + * ps/devps/S: Fix height and depth of parenrightex. + * ps/devps/symbol.diff: Regenerate. + +Sat Mar 28 21:17:52 1992 James Clark (jjc at jclark) + + * tmac.e (u): Do underlining as in -mgs. + +Fri Mar 27 09:23:44 1992 James Clark (jjc at jclark) + + * tty/tty.c (tty_printer::end_page): If overstriking is + suppressed, still turn overstruck horizontal and vertical lines + into +. + + * lib/new.c: Back out Feb 24 change; no longer needed with gcc + 2.1. + + * refer/label.y (format_expr::evaluate): Avoid use of %0*d. + +Wed Mar 18 09:29:10 1992 James Clark (jjc at jclark) + + * Version 1.05 released. + +Tue Mar 17 16:50:45 1992 James Clark (jjc at jclark) + + * tty/tty.c: Instead of keeping an array of glyphs and then + sorting it, keep a ordered linked list of glyphs for each line. + + * driver/driver.h: Include stddef.h. + + * tty/tty.c (compare_glyph): + * refer/refer.c (rcompare): + * troff/env.c (compare_ranges): Arguments of qsort comparison + function should be const void *. + + * troff/number.c (parse_term): + * dvi/dvi.c (draw_dvi_printer::draw): Avoid initialization in + switch statement. + + * refer/label.y (consider_authors): Don't access variables + constructed under a condition outside that condition: put braces + round for statement containing declaration; redeclare use of same + variable later. + + * pic/pic.y (text_expr): Delete production that allows + parenthesised text_expr. + (expr): Allow a conditional_expr to appear in parentheses. + (conditional_expr): Rename to any_expr. + + * mm: Install new version 1.01 from jh. + + * lib/font.c (font::get_width): Cache scaled widths. + (font::font): Initialize widths_cache. + (font::~font): Destroy widths_cache. + * lib/font.h: Add font::widths_cache. Declare font_widths_cache. + +Mon Mar 16 10:16:10 1992 James Clark (jjc at jclark) + + * c++test.c, c++test.ref: New files. + * Makefile: Check that the C++ compiler works. + + * ps/tmac.pspic (PSPIC): Do a break. + + * ps/tmac.ps: Move definition of PSPIC into... + * ps/tmac.pspic: New file. + (PSPIC): Draw box around picture, but make it invisible to grops. + * ps/tmac.ps: Load tmac.pspic. + * ps/Makefile: Install tmac.pspic. + +Sun Mar 15 14:18:08 1992 James Clark (jjc at jclark) + + * lib/font.c (scale_round): If n is negative, + subtract .5 before truncating floating point result. + + * lib/fontfile.c: Include . + +Tue Mar 10 14:17:03 1992 James Clark (jjc at jclark) + + * driver/input.c (get_char): Inline. Don't update current_lineno. + Change callers to up date current_lineno if necessary. + Use get_char() instead of getc(current_file). + +Sun Mar 8 18:05:28 1992 James Clark (jjc at jclark) + + * ps/tmac.ps: Fix up spacing of \(mo and \(nm. + +Fri Mar 6 19:38:58 1992 James Clark (jjc at jclark) + + * tty/tty.c (tmac.tty): Define \(rg as (R). + +Tue Mar 3 10:11:25 1992 James Clark (jjc at jclark) + + * lib/lib.h: New define a_delete. + * Use a_delete instead of delete when deleting an array of objects + without destructors. + + * lib/lib.h: Rename adelete to ad_delete. + * Change uses of adelete. + +Mon Mar 2 12:41:05 1992 James Clark (jjc at jclark) + + * eqn/eqn.y: Include lib.h. + + * troff/node.c (grow_font_table): Delete old_font_table. + + * mm: Install new version from jh. + +Fri Feb 28 10:42:23 1992 James Clark (jjc at jclark) + + * tbl/table.h (format_type): Make global instead of local to class + entry_format. Prefix enumerators with FORMAT_. + * tbl/table.c, tbl/main.c: Corresponding changes. + * refer/token.h (token_type): Make global. Prefix enumerators + with TOKEN_. + * refer/token.[ch]: Corresponding changes. + * Makefile: Get rid of -DNO_NESTED_TYPES configuration option. + + * troff/div.c (node::set_vertical_size): Don't name argument. + +Thu Feb 27 10:29:19 1992 James Clark (jjc at jclark) + + * Makefile: New configuration option ARRAY_DELETE_NEEDS_SIZE. + * lib/lib.h: Define adelete accordingly. + * pic/object.c (graphic_object::graphic_object): + * tbl/main.c (format::~format): + * tbl/table.c (table::~table): + * refer/ref.c (reference::~reference, reference::merge, + reference::insert_field, reference::delete_field): Use adelete. + + * Makefile: Change NESTED_TYPES to NO_NESTED_TYPES. + * refer/token.h: + * tbl/table.h: Corresponding changes. + + * common.c (common_output::dashed_arc, common_output::dotted_arc): + Ensure total_angle is positive. + +Wed Feb 26 08:49:26 1992 James Clark (jjc at jclark) + + * refer/ref.c (reference::merge, reference::insert_field, + reference::delete_field): Avoid delete[0]. + + * refer/token.c (init_special_chars): Move calls to cmupper + outside calls to init_two_char_letter to work around bug in gcc + 2.0. + +Mon Feb 24 14:20:00 1992 James Clark (jjc at jclark) + + * lib/new.c (operator new): Use __builtin_new for g++. + + * pic/object.c (graphic_object::~graphic_object): Don't use + delete [] on 0. + + * pic/object.c (output::compute_scale): Initialize max_width and + max_height. + +Sat Feb 15 09:55:20 1992 James Clark (jjc at jclark) + + * troff/input.c (write_request): Call fflush. + + * troff/node.h (class composite_node): Move declaration to node.c + * troff/input.c (charinfo_to_node): Rename to ... + (charinfo_to_node_list): Return node list rather than composite + node. + * troff/node.c (make_composite_node): New function. + (make_node, add_char): Call make_composite_node instead of + charinfo_to_node. + (class composite_node): Add a tfont * member. Delete font_size + member. + (composite_node::composite_node, composite_node::copy, + composite_node::size): Corresponding changes. + (composite_node::tprint): Provide constant spacing, emboldening + and track kerning as specified in tfont. + (composite_node::width): Change width calculation accordingly. + * troff/env.h (environment::composite): New member. + (environment::is_composite, environment::set_composite): New + functions. + * troff/env.c (environment::environment): Initialize composite. + * troff/input.c (charinfo_to_node): Call + environment::set_composite. + * troff/node.c (make_composite_node, make_glyph_node): Use the + plain version of the tfont if the environment is composite. + + * troff/node.c (font_info::get_space_width): Additional argument + giving space_size. Handle constant space correctly. Scale by + space_size unless constant spaced. + (env_sentence_space_width): New function. + * troff/node.h: Declare it. + * troff/env.h (environment::get_space_size, + environment::get_sentence_space_size, + environment::get_narrow_space_width, + environment::get_half_narrow_space_width): Make inline. + (environment::get_space_width): Make inline. Just call + env_space_width. + * troff/env.c: Delete definitions for functions made inline. + (environment::space_newline, environment::space): Use + env_sentence_space_width(). Don't scale by space_size. + * troff/node.h: Move declarations of env*space_width() functions + into env.h. + +Sat Feb 8 09:30:22 1992 James Clark (jjc at jclark) + + * macros/tmac.s (PS): Don't try to set negative indent. + +Thu Feb 6 09:00:35 1992 James Clark (jjc at jclark) + + * pic/pic.y: Fix min function. + +Tue Jan 28 07:52:29 1992 James Clark (jjc at jclark) + + * man/mdate.sh: Clear LANGUAGE. + +Sun Jan 19 13:02:41 1992 James Clark (jjc at jclark) + + * pic/pic.y, pic/lex.c: Rename COMMAND token to COMMAND_LINE. + * pic/lex.c: New COMMAND keyword. + * pic/pic.y (print_args, print_arg): New rules. + (placeless_element): Use print_args for PRINT. + New COMMAND element. + +Tue Jan 7 13:14:31 1992 James Clark (jjc at jclark) + + * troff/input.c (terminal): Handle missing argument correctly. + + * pic/pic.y (text_expr): New rule. + + * pic/pic.y: Implement := operator. + +Sun Jan 5 10:23:02 1992 James Clark (jjc at jclark) + + * etc/grog.pl, etc/grog.sh: Distinguish old and new versions of + mdoc. + +Sat Jan 4 14:42:26 1992 James Clark (jjc at jclark) + + * ps/devps/dingbatsrmap: Include this in the distribution. + + * macros/tmac.doc: Replace with new version from 2nd Networking + Release. Fix loading of doc-* files. + * macros/{doc-common,doc-ditroff,doc-nroff,doc-syms}: New files. + * macros/tmac.doc.old: New file. Apply fixes that had been + applied to old tmac.doc. + * macros/tmac.andoc: Check that we're running under groff. + * macros/Makefile: Rework. + +Fri Jan 3 13:27:51 1992 James Clark (jjc at jclark) + + * tbl/table.h (format_type): + * refer/token.h (token_type): If NESTED_TYPES is defined, use + typedef to make these types visible at file scope. + * Makefile: Add NESTED_TYPES configuration option. + + * troff/div.c (mark): At the top level use the value of + nl_reg_contents rather than the current vertical position. + +Thu Jan 2 10:34:51 1992 James Clark (jjc at jclark) + + * tty/tty.c: Implement \D for horizontal or vertical lines. + (tty_printer::set_char): Use vec_used+2 as serial number. + Don't allow size of vector to exceed USHRT_MAX-2. + Split off part into... + (tty_printer::add_char): New function. + (tty_printer::draw): New function. + (compare_glyph): Handle equal serial numbers. + (tty_printer::end_page): Handle overstruck characters from \D. + (main, usage): Implement -d option. + +Mon Dec 23 10:37:51 1991 James Clark (jjc at jclark) + + * tbl/main.c (process_format): + * eqn/text.c (split_text): + * troff/input.c (token::next): Use inner block for declarations + with initializers in switch statement. + +Mon Dec 16 20:52:03 1991 James Clark (jjc at jclark) + + * pic/common.c (common_output::dash_line): Cope with zero-length + lines. + +Sun Nov 17 12:04:08 1991 James Clark (jjc at jclark) + + * Version 1.04 released. + +Wed Nov 13 05:27:21 1991 James Clark (jjc at jclark) + + * macros/tmac.an (TH): Define a macro an-init to define variables + based on command line arguments. + (an-header): Call it. + +Sun Nov 3 12:07:34 1991 James Clark (jjc at jclark) + + * Makefile (install.mm): Rename to install.dwbmm. + + * Makefile: Integrate mm. + * mm: New directory. + +Wed Oct 30 10:11:34 1991 James Clark (jjc at jclark) + + * refer/dirnamemax.c: If PATHCONF_MISSING is defined, include + . + + * pic/troff.c (troff_output::simple_spline, + troff_output::simple_polygon): Rename variable `v' to `d' to avoid + shadowing parameter. + + * lib/tmpfile.c (xtmpfile): Declare dir as const char *. + + * lib/ptable.h: Add explicit casts when converting from unsigned + long to unsigned. + + * dvi/devdvi/{SA,SB,msam.map,msbm.map}: New files. + * dvi/devdvi/Makefile: Install SA, SB. + + * refer/indxbib.c: Add declaration of mktemp. + + * refer/lookbib.c: Add declaration of isatty. + +Fri Oct 25 09:00:17 1991 James Clark (jjc at jclark) + + * pic/lex.c (interpolate_macro_with_args): While collecting + arguments, keep track of whether we're in a string. + +Wed Oct 23 08:42:48 1991 James Clark (jjc at jclark) + + * ps/tmac.ps (PSPIC): Do the .sp after the \X, and move the \X + down with \v, so as to avoid problems with top of page trap + setting no space mode. + +Tue Oct 22 17:38:49 1991 James Clark (jjc at jclark) + + * eqn/lex.c (get_delimited_text): Allow tab before macro body. + +Tue Oct 15 17:24:53 1991 James Clark (jjc at jclark) + + * ps/psrm.c (ps_get_line): Fix bug when lines longer than 255. + Improve error message. + +Fri Oct 11 11:09:38 1991 James Clark (jjc at jclark) + + * ps/psrm.c (print_ps_string): Don't pass negative numbers to + printf("%03o"); + +Wed Oct 9 17:50:14 1991 James Clark (jjc at jclark) + + * groff.c (possible_command::execp): Always use _exit() after a + failed exec. + + * Makefile: Add HAVE_UNION_WAIT, HAVE_PID_T, WAIT_COREDUMP_0200, + NO_SYS_WAIT_H configuration options. + * groff.c: Use these options. Use POSIX-style macros to extract + fields from the status returned by wait(). + +Fri Oct 4 12:12:27 1991 James Clark (jjc at jclark) + + * tbl/table.c (table::compute_separation_factor): Allow the + separation factor to drop to 0. + +Tue Oct 1 18:12:38 1991 James Clark (jjc at jclark) + + * refer/search.c: Include . + +Sun Sep 29 08:40:57 1991 James Clark (jjc at jclark) + + * pic/pic.y (YYDEBUG): Don't define for Borland C++. + + * lib/lib.h: #ifdef out declarations of itoa and iftoa for Borland + C++. + + * pic/lex.c (input_stack::bol): Move definition out of class body. + + * pic/main.c: On MS-DOS munge argv[0]. + + * lib/ptable.h: Define name2 as _Paste2 for Borland C++. + + * lib/ptable.c (hash_string): Use unsigned long rather than + unsigned. + (next_ptable_size): Use unsigned rather than int. Give an error + message if we've hit the largest table size. + * lib/ptable.c: Corresponding changes. Also use unsigneds for the + table size. + + * pic/object.h (object_spec): Make flags unsigned long. Declare + flags as const unisgned long rather than as enums. + + * pic/output.c: Deleted. + + * pic/troff.c (troff_output::simple_ellipse): Remove spurious %. + + * tbl/table.c (simple_entry::note_double_vrule_on_{left,right}): + Add additional argument. + (line_entry::note_double_vrule_on_{left,right}): Set value of + douvle_vrule_on_{right,left} flag according to argument. + (simple_line_entry::simple_print, + simple_line_entry::double_line_print): If adjacent to double vrule + on a corner extend rather than shorten the rule by half the double + vrule sep. + + * troff/number.c (parse_term): In checking for overflow, handle the + case where the current horizontal position is negative. + +Thu Sep 12 08:26:09 1991 James Clark (jjc at jclark) + + * pic/object.c (draw_arrow): Check for object having zero length. + +Wed Sep 11 10:32:38 1991 James Clark (jjc at jclark) + + * eqn/main.c (do_file): Split off inline equation handling into... + (inline_equation): New function. Search for starting delimiter + using... + (delim_search): New function. Don't recognize a delimiter that + occurs in the name of an escape sequence, number register, string + etc. + +Tue Sep 10 04:01:11 1991 James Clark (jjc at jclark) + + * eqn/delim.c (delim_box::compute_metrics): Don't call + define_extensible_string if left is 0. + (delim_box::output): Don't print the left delimiter if left is 0. + (delim_box::debug_print): Check for left == 0 before calling printf. + +Fri Aug 23 13:02:30 1991 James Clark (jjc at jclark) + + * troff/Makefile (majorminor.c): Include only digits in + minor_version. + +Thu Aug 22 09:35:37 1991 James Clark (jjc at jclark) + + * refer/dirnamemax.c: new file. + * refer/genlimits.c: Deleted. + * refer/indxbib.c (main): Use dir_name_max() instead of NAME_MAX. + Don't check path length. + * refer/Makefile: Add dir_name_max.o; delete genlimits. + * Makefile: Add PATHCONF_MISSING option. + + * refer/indxbib.c (get_cwd): New function. + (main): Use get_cwd(). + * lib/getcwd.c: New file. + * Makefile: Delete -DHAVE_GETWD. Include GETCWD variable. Pass + GETCWD in SUBFLAGS. + * lib/Makefile: Compile getcwd.o. + + * ps/tmac.psatk (psatk-defs): Define showpage after pushing + userdict. + + * refer/indxbib.c (main): Check success of mktemp. + + * lib/tmpfile.c: New file. + * lib/Makefile: Add tmpfile.c. + * lib/lib.h: Declare xtmpfile(); include . + * ps/ps.h: Delete declaration of mktemp(). + * ps/ps.c (ps_printer::ps_printer): Use xtmpfile(). + * refer/refer.c (divert_to_temporary_file): Use xtmpfile(). + * driver/driver.h: No need now to include errno.h. + + * everywhere: Set errno to 0 before calling fopen(). + + * eqn/eqn.h, etc/soelim.c, driver/driver.h, etc/addftinfo.c, + dvi/tfmtodit.c, groff.c, refer/index.c, refer/linear.c, + refer/lookbib.c, refer/refer.h, ps/psbb.c: Include . + +Mon Aug 19 10:52:18 1991 James Clark (jjc at jclark) + + * troff/env.h (translate_space_to_dummy): Declare it. + * troff/env.c (environment::space_newline, environment::space): + If translate_space_to_dummy is set then make the width of spaces 0. + * troff/input.c (translate): If the second character of a + translation is a space, translate to unbreakable space. If the + first character is a space, set or clear translate_space_to_dummy + according to whether the second character is \&. Weird! + +Tue Jul 30 10:03:56 1991 James Clark (jjc at jclark) + + * groff.c (run_commands): Don't use non-zero exit code because a + command gets SIGPIPE. + + * groff.c, groff.sh: Use -mXps with -TXps. + + * ps/ps.c (ps_printer::special): Move call to flush_sbuf() into... + (ps_printer::do_exec, ps_printer::do_file, ps_printer::do_def, + ps_printer::do_mdef, ps_printer::do_import): Call flush_sbuf(). + (ps_printer::special): New specials invis and endinvis. + (ps_printer::do_invis, ps_printer::do_endinvis): New functions. + (ps_printer::set_char, ps_printer::draw): Return if invis_count>0. + (ps_printer::end_page): Check that invis_count == 0. + (ps_printer::invis_count): New member. + (ps_printer::ps_printer): Initialize invis_count to 0. + + * troff/env.c (environment::hyphenate_line): Hyphenation + indicator at beginning of word inhibits splitting after -, \(em + etc. + + * pic/pic.y (element): Allow another element to follow } without + any intervening separator. + +Mon Jul 22 12:27:37 1991 James Clark (jjc at jclark) + + * pic/lex.c (get_delimited): Allow tabs before delimiter. + +Wed Jul 17 10:59:08 1991 James Clark (jjc at jclark) + + * groff.c: Get rid of HAVE_UNION_WAIT stuff. Instead suppress + declaration of wait() in header files. + * Makefile: Get rid of -DHAVE_UNION_WAIT. + + * tbl/table.c (alphabetic_text_entry::add_tab): New function. + + * lib/lib.h: Declare return type of strerror as char *. + + * man/Makefile: Add g flag to sed substitutions. + * Makefile (shgroff, bindist): Likewise. + +Sun Jul 14 11:57:02 1991 James Clark (jjc at jclark) + + * ps/ps.c (ps_printer::do_import): Move push of userdict into... + * ps/devps/prologue (PBEGIN): Define showpage after pushing + userdict. + +Sat Jul 13 20:53:04 1991 James Clark (jjc at jclark) + + * ps/devps/prologue (PBEGIN): Zap any definition of showpage in + userdict. + +Fri Jul 12 07:10:09 1991 James Clark (jjc at jclark) + + * man/mdate.sh: Handle the fact that BSD ls -l does not print the + group. + +Sun Jul 7 08:00:23 1991 James Clark (jjc at jclark) + + * troff/input.c (define_number_reg): If currently undefined, + don't define it if the argument is an invalid expression. + + * Makefile: Ignore return value of `if' commands without `else' + parts. + + * Makefile: Split up CPPDEFINES into a series of separate + configuration options. + + * troff/input.c (init_registers): Use time_t instead of long + unless LONG_FOR_TIME_T is defined. Use returned result rather + than passing pointer. + * Makefile: Document LONG_FOR_TIME_T as a CPPDEFINE. + + * lib/Makefile (fontpath.h): Use gendef. + +Thu Jul 4 09:48:05 1991 James Clark (jjc at jclark) + + * troff/input.c (input_iterator::shift): Delete argument name. + * troff/node.c (suppress_output_file::really_begin_page, + suppress_output_file::really_transparent_char, node::ascii_print, + node::tprint): Delete names of unused arguments. + +Wed Jul 3 17:34:57 1991 James Clark (jjc at jclark) + + * refer/label.y (string): Pass $4 to command_error. + +Tue Jul 2 15:06:01 1991 James Clark (jjc at jclark) + + * Version 1.03 released. + +Sat Jun 29 08:14:01 1991 James Clark (jjc at jclark) + + * Makefile: Pass definition of SHELL in SUBFLAGS. + + * gendef: New file. + * Makefile, eqn/Makefile, refer/Makefile, troff/Makefile, + ps/Makefile: Use gendef to construct header files that are + constructed from the Makefile. + + * macros/Makefile: make all should build stripped version of tmac.e. + + * refer/Makefile (clean): Remove y.output. + +Fri Jun 28 09:44:36 1991 James Clark (jjc at jclark) + + * ps/pfbtops.c (main): Add -v option which prints out a version + number. + * ps/Makefile (pfbtops): Link with libgroff.a. + +Fri Jun 21 07:43:23 1991 James Clark (jjc at jclark) + + * refer/search.h (linear_searcher::get_nkeys): Delete declaration. + * refer/linear.c (linear_searcher::get_nkeys): Delete definition. + + * refer/lkbib.c (main): Always terminate reference with blank + line. + * refer/lookbib.c (main): Likewise. + + * refer/linear.c (file_buffer::load): Check that the file is not a + binary file. + + * refer/Makefile (genlimits): Possibly add -DHAVE_SYS_DIR_H. + (genlimits.c): Include if HAVE_SYS_DIR_H is defined. + Delete second inclusion of . + +Tue Jun 18 01:32:26 1991 James Clark (jjc at jclark) + + * troff/token.h (token::special): Deleted. + + * tbl/main.c (process_format): Rework so that opt->tab_char is + recognized only when appropriate. + + * ps/Makefile (clean): Remove pfbtops. + +Sun Jun 16 09:37:19 1991 James Clark (jjc at jclark) + + * lib/font.c (text_file::next): Don't return if we have got a + blank line. + +Fri Jun 14 09:52:26 1991 James Clark (jjc at jclark) + + * refer/refer.c (store_reference): Get hash code from old_table[i] + when rehashing the table. + +Thu Jun 13 01:26:43 1991 James Clark (jjc at jclark) + + * eqn/box.c (box::top_level): Save size and prev size using \R and + restore it afterwards. Set the size to the size at the beginning + of the line. + * eqn/pbox.h: Declare SAVED_INLINE_PREV_SIZE_REG, + SAVED_INLINE_SIZE_REG, and SAVED_SIZE_REG. + + * refer/Makefile (limits.h): Use ./genlimits. + +Wed Jun 12 16:05:34 1991 James Clark (jjc at jclark) + + * refer/index.c: Delete declarations of stat() and fstat(). + +Tue Jun 11 14:52:49 1991 James Clark (jjc at jclark) + + * tty/tmac.tty: Add character definitions for \(>= and \(<=. + +Mon Jun 10 22:49:48 1991 James Clark (jjc at jclark) + + * etc/grog.sh, etc/grog.pl: Change regex for .PS. + +Fri Jun 7 09:13:06 1991 James Clark (jjc at jclark) + + * troff/input.c (token::get_char): Handle \e. + + * refer/linear.c: Delete declarations of fstat() and stat(). + +Wed Jun 5 09:11:59 1991 James Clark (jjc at jclark) + + * troff/node.c, troff/env.c, troff/input.c, Makefile: Remove + OP_DELETE_BROKEN stuff, since we now have a fix for g++. + +Mon Jun 3 13:41:32 1991 James Clark (jjc at jclark) + + * troff/input.c (do_define_macro): Improve error handling for end + of file while defining macro. + +Sun Jun 2 10:20:24 1991 James Clark (jjc at jclark) + + * eqn/box.h: Fix declaration of set_gsize. + * eqn/box.c (set_gsize): Make argument const char *. + (gsize): Declare as char *. + * eqn/main.c (main): Don't convert gsize to int. + * eqn/lex.c (do_gsize): Pass char * to set_gsize. + + * Version 1.02 released. + +Sat Jun 1 12:19:46 1991 James Clark (jjc at jclark) + + * macros/tmac.andoc: New file. + * macros/Makefile: Install tmac.andoc. + + * troff/node.c, troff/env.c, troff/input.c: Conditionalize use of + operator new and delete on OP_DELETE_BROKEN not being defined. + * Makefile: Mention OP_DELETE_BROKEN. + +Mon May 27 13:49:07 1991 James Clark (jjc at jclark) + + * Makefile (bindist): Pass SUBFLAGS. + +Sun May 26 14:13:22 1991 James Clark (jjc at jclark) + + * Makefile, groff.c: Pass definitions to groff.c via device.h. + + * tty/tty.c (tty_font::load_tty_font): Avoid shadowing + parameter. + + * ps/Makefile, ps.c: Pass BROKEN_SPOOLER_FLAGS via broken.h. + + * ps/ps.h, ps/psrm.c: Make comment_table and + header_comment_table local to resource_manager::process_file. + + * groff.sh: With -TXps pass -printCommand option to gxditview. + + * groff.c (possible_command::print): Implement using + append_arg_to_string. + + * xditview: Merge in new implementation with own ChangeLog. + +Sat May 25 18:33:20 1991 James Clark (jjc at jclark) + + * groff.c (main): Implement PRINT_OPTION. + (append_arg_to_string): New command. + (device_table): Set PRINT_OPTION flag for Xps. + +Fri May 24 09:48:58 1991 James Clark (jjc at jclark) + + * troff/groff.h: Rename to troff.h. + + * pic/lex.c (lookup_keyword, docmp): New functions. + (get_token): Use new lookup_keyword. + Don't include key.h. + * pic/key.[ch], pic/pic.gperf: Deleted. + * pic/Makefile: Remove gperf stuff. + + * pic/Makefile, pic/output.h: Move definition of TEX_SUPPORT + into output.h. + * pic/tex.c: Move include of pic.h before test of TEX_SUPPORT. + + * troff/Makefile, troff/node.c: Move definition of + STORE_WIDTH into node.c. + + * etc/grog.pl, etc/grog.sh: Support -mdoc. + +Thu May 23 12:30:49 1991 James Clark (jjc at jclark) + + * dvi/devdvi/texr.map, dvi.devdvi/texi.map, + dvi/devdvi/texb.map: Add lq and rq. + dvi/devdvi: Regenerate fonts. + * ps/devps/textmap: Add lq and rq. + * ps/devps: Regenerate fonts. + * tty/devascii/R.proto, tty/devlatin1/R.proto: Add lq and rq. + * macros/tmac.e: Define \*(lq and \*(rq to be \(lq and \(rq. + + * pic/object.c (position_rectangle): When checking radius + cope with possibility that width or height is negative. + (box_object::box_object): Have separate xrad and yrad with + signs matching signs of dim components. + (box_object::{north,south}_{east,west}): Use xrad and yrad. + (box_object::print): With rounded boxes use absolute values + for dim and rad arguments. + + * lib/Makefile, lib/fontfile.o: Pass definition of FONTPATH + in fontpath.h. + + * eqn/Makefile, eqn/main.c: Pass definition of DEVICE in device.h. + + * various files: Add explicit destructors to keep Saber CC +d + happy. + +Wed May 22 11:37:11 1991 James Clark (jjc at jclark) + + * eqn/box.c (box::top_level): Restore fonts correctly after + font changes in line containing inline equation. Also + restore previous font as well as current font. + * eqn/pbox.h: Define necessary string and register names. + + * troff/input.c (token::next): Case 'R' calls do_register. + (do_register): New function. + +Tue May 21 11:28:23 1991 James Clark (jjc at jclark) + + * groff.c, groff.sh: Support Xps device. Allow each device + to have a pseudo_name and a real_name. + + * groff.c (run_commands): Don't print `Broken pipe' messages. + + * ps/pfbtops.c: New file. + * ps/Makefile: Add pfbtops. + + * troff/number.c (parse_term): Improved error message. + +Mon May 20 11:22:14 1991 James Clark (jjc at jclark) + + * groff.c, groff.sh, etc/grog.sh, etc/grog.pl: Support grefer. + + * Makefile: Integrate refer. + * refer: New directory. + * man/grefer.man, man/glookbib.man, man/gindxbib.man, + man/lkbib.man: New files. + * man/Makefile: Support refer man pages. + + * lib/lib.h: Declare is_prime. + * lib/prime.c: New file. + + * troff/input.c (macro_source): New function. + (init_input_requests): Bind "mso" to macro_source. + + * troff/env.c (environment::possibly_break_line): Maintain + pointer to pointer to node to be split in ndp so as to avoid + using address of freed node. + + * troff/env.c (environment::hyphenate_line): Maintain pointer to + pointer to first node to be hyphenated in startp so as to + avoid using address of freed node. + + * troff/env.c (class trie, class hyphen_trie): Make the + elements of the trie be of type char not unsigned char. + Declare arguments to be const char* instead of unsigned char *. + + * troff/env.c (hyphenate): Initialize hbuf[0]. + + * troff/input.c (set_string): Declare p to be char * and cast + *p to unsigned char when necessary. + + * troff/input.c (do_define_macro): Declare s to be const + char*. Cast element to unisgned char when necessary, Declare + d to be an int. Handle EOF better. + + * troff/Makefile, troff/input.c: Different scheme for passing + definitions of MACROPATH, HYPHENFILE and DEVICE. + +Tue May 14 13:41:36 1991 James Clark (jjc at jclark) + + * tty/devascii/R.proto: Delete entry for em. + * tty/devlatin1/R.proto: Likewise. + +Sat May 11 11:13:28 1991 James Clark (jjc at jclark) + + * troff/input.c (translate): Stop when we get a space. Treat eof + like newline. + + * macros/tmac.an (IP): Only pass quoted argument to TP when \n(.$>1. + +Wed Apr 24 19:24:33 1991 James Clark (jjc at jclark) + + * tbl/main.c (process_format): A font name following a `f' + modifier that starts with a digit can be only one character long. + Also deal with EOF on the second character of the font name. + +Wed Apr 17 11:23:43 1991 James Clark (jjc at jclark) + + * troff/input.c (token::next): Turn \~ into an + unbreakable_space_node. + * troff/node.c (unbreakable_space_node): New class. + * troff/node.h: Declare it. + +Tue Apr 16 10:47:12 1991 James Clark (jjc at jclark) + + * dvi/dvi.c (dvi_printer::set_char): Make code an int. Check that + it's >= 0, before outputting it as a single byte. + +Mon Apr 15 11:20:23 1991 James Clark (jjc at jclark) + + * lib/font.c: Make font_char_metric::code an int. + (font::get_code): Change return type to int. + (font::load): Allow code to be arbitrary integer. + * lib/font.h (font::get_code): Change return type to int. + (font::number_to_index): Change argument type to int. + * troff/input.c (token::next): In case 'N', allow any value. + Store value in token::val. + (token::operator==): For TOKEN_NUMBERED_CHAR test equality of val. + (token::get_char, token::add_to_node_list, token::process): Get + number from val. + (charinfo::set_number): Change argument to int. + (charinfo::get_number): Require that NUMBERED flag be set. + (get_charinfo_by_number): Store numbered characters not between 0 + and 255 in a dictionary. + * troff/charinfo.h (get_charinfo_by_number): Change argument type + to int. + (charinfo::number): Change type to int. + (charinfo::set_number): Change type of set_number to int. + * troff/node.c (troff_output_file::put_char_width, + troff_output_file::put_char): Test whether character is numbered + using charinfo::numbered(). + * driver/printer.c (printer::set_numbered_char): Allow arbitrary + values of num. + * lib/nametoindex.c: New implementation to cope with arbitrary + number characters. + + * troff/input.c (token::operator==): Test val for + TOKEN_CHAR_HEIGHT, TOKEN_CHAR_SLANT, TOKEN_FONT_POSITION, and + TOKEN_SIZE. + + * man/Makefile: Add definition of BROKEN_SPOOLER_FLAGS. + (.man.n): sed out @BROKEN_SPOOLER_FLAGS@. + +Sun Apr 14 12:57:00 1991 James Clark (jjc at jclark) + + * ps/devps/zapfdr.ps: Don't copy UniqueID. Avoid use of newdict + variable. + + * all Makefiles: rm targets of cp and >. + + * xditview/xtotroff.c (MapFont): Unlink troff_name before opening + it. + + * eqn/lex.c (def_table): Add dollar. + +Sat Apr 13 13:02:44 1991 James Clark (jjc at jclark) + + * troff/input.c (do_width): Push back newline before closing delim + like do_bracket. + +Fri Apr 12 15:16:03 1991 James Clark (jjc at jclark) + + * groff.c (possible_command::prepend_arg): New function. + (main): Prepend device -m option. + * groff.sh: Put device -m options before command-line options. + +Tue Apr 9 10:24:43 1991 James Clark (jjc at jclark) + + * macros/tmac.an (IP): Quote argument to TP. + + * ps/ps.c (main): New option -b, which sets... + (broken_flags): New variable. + (ps_printer::~ps_printer): Incorporate the setup section in the + prolog if (broken_flags & NO_SETUP_SECTION). + (ps_printer::begin_page): Generate {Begin,End}PageSetup comments. + (ps_printer::merge_download_fonts, ps_printer::merge_import_fonts, + ps_printer::merge_ps_fonts, ps_printer::print_font_comment, + ps_printer::print_needed_font_comment, + ps_printer::print_supplied_font_comment, + ps_printer::print_include_font_comments, + ps_printer::lookup_doc_font, ps_printer::download_fonts, + ps_printer::read_download_file, read_document_fonts, add_font, + skip_line, parse_fonts_arg, document_font::document_font, + document_font::~document_font, document_font::download, + ps_output::include_file): Deleted. + (ps_printer::~ps_printer): Generate %%EOF. Generate %!PS-Adobe-3.0 + rather than %!PS-Adobe-2.0. Make calls to + resource_manager::need_font for each font that we used. Replace + calls to merge_ps_fonts, merge_download_fonts, print_font_comment, + print_supplied_font_comment, print_needed_font_comment by call to + resource_manager::print_header_comments. Output %%Orientation + comment. Output %%Requirements: numcopies comment if ncopies > 1. + Don't output the prolog directly. Instead call + resource_manager::output_prolog. Only define #copies when ncopies + > 1. Delete calls to print_include_font_comments and + download_fonts. Add call to resource_manager::document_setup. + (ps_printer::do_file): Call resource_manager::import_file instead + of including it ourselves. + (ps_printer::do_import): Likewise. Also don't call + merge_import_fonts. Push userdict on the dictionary stack before + and pop it afterwards. + Move declaration of ps_output into ps.h. + * ps/psrm.c: New file implementing resource_manager class. + * ps/ps.h: New file declaring ps_output and resource_manager + classes. + * ps/devps/zapfdr.ps: + * ps/devps/symbolsl.ps: + * ps/devps/prologue: Use 3.0 conventions. + * ps/Makefile: Pass definition of BROKEN_SPOOLER_FLAGS in DEFINES. + Add default definition of BROKEN_SPOOLER_FLAGS. + * Makefile: New variable BROKEN_SPOOLER_FLAGS. Add + BROKEN_SPOOLER_FLAGS to SUBFLAGS. + +Mon Apr 8 09:26:54 1991 James Clark (jjc at jclark) + + * etc/grog.pl: New file. + * Makefile (GROG): New variable. + Add GROG to SUBFLAGS. + * etc/Makefile (GROG): New variable. + (install.nobin): Install $(GROG) rather than grog.sh. + +Thu Apr 4 11:36:45 1991 James Clark (jjc at jclark) + + * eqn/special.c (special_box::compute_metrics): Make the input and + output strings the same. Get the new height and depth from the + predefined height and depth registers. Also make subscript kern + and skew available. + (special_box::compute_subscript_kern, special_box::compute_skew): + New functions. + + * eqn/box.c (pointer_box::compute_skew, + simple_box::compute_metrics, box::top_level) + * eqn/text.c (prime_box::compute_metrics, + prime_box::comput_subscript_kern) + * eqn/limit.c (limit_box::compute_metrics): + * eqn/delim.c (build_extensible, delim_box::compute_metrics): + * eqn/sqrt.c (sqrt_box::compute_metrics): Protect possibly + negative numbers in `nr' requests with a leading 0. + +Wed Apr 3 15:58:23 1991 James Clark (jjc at jclark) + + * eqn/special.c: New file. + * eqn/eqn.y: Declare token SPECIAL. Make it right associative. + Add new rule for simple. + * eqn/lex.c (token_table): Add SPECIAL. + * eqn/box.h: Declare make_special_box. + * eqn/Makefile: Add special.[co]. + +Sat Mar 30 10:57:53 1991 James Clark (jjc at jclark) + + * ps/devps/prologue: Possibly set packing to true while defining. + Create grops dictionary here. Initialize local variables before + defining procedures. + (PICTURE): Rename to PBEGIN. Also do save, noop showpage, count + the dictionary stack. Set strokeadjust and overprint to false if + the relevant operators are defined. + (PEND): New procedure. + * ps/ps.c (ps_printer::~ps_printer): In the prolog just include + prologue. Do everything else in the setup section. + (ps_printer::do_import): Just call PBEGIN and PEND around the + picture. Also push userdict before, and pop it afterwards. + +Wed Mar 27 07:59:50 1991 James Clark (jjc at jclark) + + * troff/node.c (bracket_node::tprint): Brackets were being printed + 1m too low. + + * macros/tmac.an (SH, SS): Set fill mode. + +Tue Mar 26 07:46:31 1991 James Clark (jjc at jclark) + + * troff/div.c (top_level_diversion::begin_page): Set + high_water_mark to 0. + +Fri Mar 22 09:19:46 1991 James Clark (jjc at jclark) + + * man/mdate.sh: New file. + * man/mdate.c: Deleted. + * man/Makefile: Use mdate.sh instead of mdate. + (mdate): Deleted. + + * eqn/lex.c (do_gsize): Supply missing argument to error message. + +Tue Mar 19 11:06:50 1991 James Clark (jjc at jclark) + + * man/mdate.c: New file. + * man/*.man: Replace modification date by @MDATE@. + * man/Makefile (.man.n): Replace @MDATE@ by `mdate $<`. + (mdate): New target. + + * lib/font.c (text_file::next): Deal with arbitrarily long lines. + Remove invalid input characters. + +Mon Mar 18 08:32:25 1991 James Clark (jjc at jclark) + + * macros/tmac.s (pg*start-col): Do .ns *after* running the hooks. + +Sat Mar 16 03:52:25 1991 James Clark (jjc at jclark) + + * troff/div.c (begin_page): Change behaviour when + !first_page_begun and !break_flag. + + * troff/input.c (do_name_test): Return 0 if argument is empty. + + * troff/input.c (read_long_escape_name): Require closing ] to be + at same input level as opening [. + + * troff/input.c (read_increment_and_escape_name): New function. + (get_copy, process_input_stack): Use this for \n. + +Fri Mar 15 00:31:48 1991 James Clark (jjc at jclark) + + * troff/div.c (top_level_diversion::begin_page): Ignore the + current value of page_number if !first_page_begun. + + * groff.c (main): Fix declaration of buf. + + * troff/input.c (do_name_test): New function. + (token::next): Implement \A. + (token::next): Implement \e by turning it into a TOKEN_ESCAPE. + (token::description, token::add_to_node_list, token::process): + Handle TOKEN_ESCAPE. + * troff/token.h: New token TOKEN_ESCAPE. + +Thu Mar 14 10:22:26 1991 James Clark (jjc at jclark) + + * pic/main.c (do_picture): Allow space before and after filename + following `<'. Check that the filename is not empty. + +Wed Mar 13 12:49:40 1991 James Clark (jjc at jclark) + + * Version 1.01 released. + + * dvi/devdvi/CompileFonts: Add cm*ss10 fonts. + + * dvi/tmac.dvi: ftr HR to H. + + * macros/tmac.e: Round up computation of $r. + + * xditview/tmac.X: Don't give up completely in compatibility mode. + Use \n(.s instead of \n[.s]. + + * dvi/tmac.dvi: Don't give up completely in compatibility mode. + Use \(ci instead of \[ci]. Use \n(.s instead of \n[.s]. + Add u to factors inside \s[...]. Rename frac to dvi-frac. + Translate \(FM onto \[prime] and \(!/ onto \[slashnot]; use these + short names in the char definitions. + + * ps/tmac.ps: Don't give up completely in compatibility mode. + Fix the fraction definitions to use \n(.s and \(f/. Add an extra + quote in front of \n(.s. Add u to factors inside \s[...]. + +Mon Mar 11 12:01:20 1991 James Clark (jjc at jclark) + + * tty/tmac.tty: Call the nroff request. + + * macros/tmac.e ((x, )x): Better definitions that work properly + in a diversion. + (@0, @1): Helper macros for (x. + + * macros/tmac.e ($s, hl): Use \l rather than \D. + + * tty/tmac.tty: Make it work better in compatibility mode. + (pchar): Rename to tty-char. + + * macros/tmac.e (@E): New macro. + (r, i, b, rb, bi): Use @E. + + * macros/tmac.e (@F): Don't use (;...) syntax. + + * macros/tmac.e: Remove mention of \*(||/revisions. Mention that + it was modified for groff. + + * macros/tmac.e: Make sure \n(ps and \n(es are >= \n(.V. + + * macros/tmac.e (<., .>): Removed. + ([., .]): If \n(.V>=1v, use [] instead of superscripting. + + * macros/tmac.e: Remove check that groff is being used. + + * macros/tmac.e (@C): Change families only if using groff; turn + compatibility mode off while changing families. Save + compatibility mode before changing families and restore it + afterwards. + + * macros/tmac.e (@h): Remove test for offset + line length. + + * macros/tmac.e (sorry): Rename to @S. Use \$1 instead of \$0 + (lo, th, ac): Define to call @S instead of using als. + + * macros/tmac.e: Make $r and $R now contain \n(.v*100/\n(.sp, ie + the ratio of the vertical spacing to the point size in units + expressed as a percentage. Use these instead of $10r and $10R, + Delete $10r and $10R. + + * lib/font.c (font::load): In default computation of space_width, + divide by sizescale. Use scale_round. + + * macros/tmac.an (TP): Don't call `nf'. + (an-do-tag): Don't call `fi'. + +Sun Mar 10 09:52:35 1991 James Clark (jjc at jclark) + + * troff/input.c (process_input_stack): Handle the case where + spaces at the beginning of an input line are followed by a + newline. + +Thu Mar 7 20:18:07 1991 James Clark (jjc at jclark) + + * groff.c (device_table): Add PIC_X_OPTION for dvi device. + * groff.sh: Use pic -x with the dvi device. + + * dvi/devdvi/FontMakefile (H): Don't use -s. + + * dvi/devdvi/HI, dvi/devdvi/HB: New files. + * dvi/devdvi/Makefile: Add HI and HB to FONTS. + * dvi/devdvi/FontMakefile: Add rules for HI and HB. Include these + in FONTS. + +Mon Mar 4 13:20:14 1991 James Clark (jjc at jclark) + + * ps/psfig.diff: New file. + * ps/tmac.psfig: New file. + +Sat Mar 2 00:15:09 1991 James Clark (jjc at jclark) + + * macros/tmac.s (]=, ref*do-tl, ref*bib-print): Deleted. + (]-): Don't call ref*do-tl. + + * macros/tmac.s (ref*end-print): Use XP if [F not defined. + + * macros/tmac.s (ref*normal-print): Call FS rather than fn@do-FS. + (fn@do-FS): Rename to fn*do-FS. + + * troff/input.c (transparent_translate): New function. + (process_input_stack): Apply transparent_translate before calling + diversion::transparent_output(unsigned char). + +Wed Feb 27 00:13:25 1991 James Clark (jjc at jclark) + + * troff/input.c (do_define_macro): Define the macro before calling + skip_line. + + * xditview/Makefile: Add DEVICES variable. Change install target + to use this. + +Tue Feb 26 10:46:22 1991 James Clark (jjc at jclark) + + * groff.c (run_commands): Handle the possibility that there are + child processes other than those forked by us. + +Sun Feb 24 21:32:30 1991 James Clark (jjc at jclark) + + * lib/string.c (string::append): New function. + * lib/stringclass.h: Declare it. + +Thu Feb 21 11:49:26 1991 James Clark (jjc at jclark) + + * eqn/main.c (main): New option -N which sets + no_newline_in_delim_flag. + (do_file): If no_newline_in_delim_flag is set don't allow newlines + in delimiters. + * groff.c (main): Pass -N on to eqn. + (help, synopsis): Mention -N. + * groff.sh: Implement -N. + +Wed Feb 20 15:16:10 1991 James Clark (jjc at jclark) + + * macros/tmac.s (]=, ref*bib-print, ref*do-tl): New macros. + (]-): Call ref*do-tl if ref*need-tl is non-zero. + (XP): Allow as initializer. + +Tue Feb 19 14:09:06 1991 James Clark (jjc at jclark) + + * troff/env.c (environment::wrap_up_field): If field_spaces are + non-zero and we have a current_tab, subtract padding from + tab_distance. If this makes tab_distance <= 0, use the next tab + stop instead. If there isn't any next tab or it's a left tab, + wrap up the current tab. + (environment::start_field): Initialize tab_precedes_field. + (environment::wrap_up_tab): If there's a current field, update + pre_field_width, field_distance and tab_precedes_field. + * troff/env.h (environment::tab_precedes_field): New member. + +Fri Feb 15 01:24:00 1991 James Clark (jjc at jclark) + + * ps/ps.c (ps_printer::do_file): New function. + (ps_printer::special): Bind to `file' special. + (ps_printer::do_exec): Set ndefined_styles to 0. + +Sat Feb 9 03:03:04 1991 James Clark (jjc at jclark) + + * eqn/text.c (split_text): Grok \* and similar escapes sequences. + Avoid stripping first character from the start of unrecognized + escapes. Use lex_error instead of error to report errors. + * eqn/lex.c (get_token): Rework handling of escapes. + (lex_error): Move declaration into... + * eqn/eqn.h. + + * xditview/xditview.c (main): Make -page option work. + + * Makefile: Correct comment about -DBROKEN_SPOOLER and pageview. + +Wed Feb 6 12:28:43 1991 James Clark (jjc at jclark) + + * macros/tmac.s (B2): Correct size of box. + +Tue Feb 5 00:37:35 1991 James Clark (jjc at jclark) + + * macros/tmac.s (B2): Postpone drawing the box until in the + top-level diversion. + + * tty/tmac.tty: Add font translations for C, CR, CW. + + * groff.c (synopsis, help): Document -i. + * groff.sh: Implement -i. + + * macros/tmac.s (@NH): Put a `.' after multi-part numbers. + Simplify the construction of SN. + + * troff/number.c (parse_term): Give `|' a higher precedence. + * tbl/table.c (numeric_text_entry::simple_print): Parenthesise + accordingly. + + * macros/tmac.s (B2): Use par@finish instead of par@reset. + +Mon Feb 4 12:36:09 1991 James Clark (jjc at jclark) + + * lib/string.c (string::move): New function. + * lib/stringclass.h: Declare it. + +Sat Feb 2 16:02:16 1991 James Clark (jjc at jclark) + + * troff/env.c (distribute_space): Add optional argument + `force_forward'. + (environment::wrap_up_field): Call distribute_space with + `force_forward' argument of 1. + +Fri Feb 1 19:36:33 1991 James Clark (jjc at jclark) + + * lib/string.c, lib/stringclass.h (string::operator+=(char)): + Inline it. Move reallocation into... + (string::grow1): New function. + * pic/Makefile, tbl/Makefile, eqn/Makefile, ps/Makefile: Redo + dependencies to include library header files. + * lib/Makefile: Make string.c and lf.c depend on stringclass.h. + +Thu Jan 31 15:02:27 1991 James Clark (jjc at jclark) + + * macros/tmac.s (@NH): Use the same number registers than -ms does + for the heading level counters. Use the same string that -ms does + for the number for this heading. + +Wed Jan 30 14:25:40 1991 James Clark (jjc at jclark) + + * lib/new.c (operator new): Cast result of malloc to char *. + + * troff/input.c (spring_trap, lookup_request): Add assert that nm + is not null. + +Tue Jan 29 18:08:05 1991 James Clark (jjc at jclark) + + * groff.c (main): Support -i. + +Sun Jan 27 13:23:17 1991 James Clark (jjc at jclark) + + * pic/pic.h: Include . + + * ps/ps.c: Add declaration of mktemp. + + * Makefile: Add -DHAVE_UNION_WAIT option for CPPDEFINES. + * groff.c: If HAVE_UNION_WAIT is defined, declare wait()'s + argument as union wait *. + (run_commands): If HAVE_UNION_WAIT is defined cast wait()'s + argument to union wait *. + +Sat Jan 26 12:04:52 1991 James Clark (jjc at jclark) + + * tty/tmac.tty: Add definition of \(co. + + * pic/object.c (make_arc): Only increase radius when radius + strictly less than d. + (arc_object::update_bounding_box): May need to add 4.0 to end_quad + more than once. + + * troff/env.c (environment::environment(symbol), + environment::environment(const environment *)): Initialize + input_trap_count. + +Sat Jan 19 08:18:35 1991 James Clark (jjc at jclark) + + * tbl/main.c (main): Add exit(0). + + * ps/ps.c (ps_printer::~ps_printer): Use fseek instead of rewind. + + * pic/main.c (main): + * eqn/main.c (main): + * tbl/main.c (main): + * etc/soelim.c (main): + * driver/printer.c (printer::~printer): + * troff/node.c (real_output_file::~real_output_file, + real_output_file::flush): Check for errors on stdout. + + * most files: Add 1991 to copyright notice. + + * macros/tmac.s: Don't test \n(.x and \n(.y. + + * troff/input.c (token::next): Rename `escape_char' label to + `handle_escape_char' and `normal_char' label to + `handle_normal_char'. + +Thu Jan 17 15:46:35 1991 James Clark (jjc at jclark) + + * groff.c (main, synopsis, help): Support -a option. + * groff.sh: Likewise. Also eliminate Zflag variable by adding -z + to trflags while parsing options. + +Tue Jan 15 13:07:27 1991 James Clark (jjc at jclark) + + * troff/number.c (parse_term): With `m', `M' and `n' scale + indicators, convert scale factor to hunits before scaling. + +Mon Jan 14 12:39:12 1991 James Clark (jjc at jclark) + + * lib/font.c (scale_round): Better test for overflow when n is + negative. + +Thu Jan 10 11:10:56 1991 James Clark (jjc at jclark) + + * tbl/main.c (process_format): Add second argument of type + options*. Change callers. Allow opt->tab_char as well as '\t' + between format items. + +Mon Jan 7 12:30:18 1991 James Clark (jjc at jclark) + + * macros/tmac.an (PD): With no arguments, make sure register PD is + at least \n[.V]. + (TH): Call PD with no argument, instead of setting register PD + directly. + +Sun Jan 6 11:18:39 1991 James Clark (jjc at jclark) + + * Version 1.00 released. + +Sat Jan 5 08:44:30 1991 James Clark (jjc at jclark) + + * ps/tmac.ps, xditview/tmac.X: Add font translation of C to CR. + + * dvi/devdvi/DESC: Mount CW instead of CR. + + * dvi/tmac.dvi: Add definition of \(tm. + + * dvi/devdvi/texsy.map: Add lh, and rh. + * dvi/devdvi/texex.map: Add lt, rt, lb, rb, lk, rk. + * dvi/devdvi/texmi.map: Add *o. Regenerate fonts. + + * dvi/devdvi/FontMakefile: Generate H from cmss10. + * dvi/devdvi/Makefile: Install H. + * dvi/devdvi/H: New file. + +Fri Jan 4 15:04:57 1991 James Clark (jjc at jclark) + + * troff/env.c (vertical_spacing): Don't allow vertical spacing to + be 0. + +Thu Jan 3 13:41:19 1991 James Clark (jjc at jclark) + + * macros/tmac.s (@EN): Add \n(.V to the argument to ds@need. + + * macros/tmac.pic (PS): Avoid attempting to set negative indent. + + * macros/tmac.s (@EN): Handle the case where the equation is empty + but the label is not. + +Wed Jan 2 10:31:44 1991 James Clark (jjc at jclark) + + * troff/groff.h: New warning category WARN_SPACE. + * troff/input.c: Add WARN_SPACE to DEFAULT_WARNING_MASK. Add + WARN_SPACE to warning_table. + (interpolate_macro): Give a warning of type WARN_SPACE if the name + is longer than two characters and is not defined, but the first + two characters do make a defined name. + + * PROBLEMS: New file. + + * CHANGES: New file. + * README-0.6, README-1.00: Deleted. + + * groff.c, groff.sh: Add X75-12 and X100-12 devices. + * xditview/devX75/Makefile: Make devX75-12. + * xditview/devX100/Makefile: Make devX100-12. + + * xditview/devX100/eqnchar, xditview/devX75/eqnchar, + dvi/devdvi/eqnchar, ps/devps/eqnchar: Remove use of \R. + +Tue Jan 1 19:24:01 1991 James Clark (jjc at jclark) + + * README-0.7: Rename to README-1.00. + + * macros/tmac.pic: New file. + * macros/Makefile (install.nobin): Install tmac.pic. + +Mon Dec 31 10:40:53 1990 James Clark (jjc at jclark) + + * troff/env.c (hyphen_word): Correct the test for whether the + token is a hyphen. Reset npos to 0. + + * macros/tmac.s (par@sup-start, par@sup-end): New implementations. + +Sun Dec 30 15:53:13 1990 James Clark (jjc at jclark) + + * macros/tmac.s (ds*common-end): Call par*reset. + (PE): Likewise. + (par@reset-indent): Deleted. + + * macros/tmac.s (@IP): Divert the label. + +Sat Dec 29 14:33:32 1990 James Clark (jjc at jclark) + + * xditview/draw.c (setGC): Use a line width of .1m rather than + .04m by default; round rather than truncate value. + + * tbl/table.c (class empty_entry): New class. + (empty_entry::empty_entry, empty_entry::line_type): New functions. + (table::add_entry): Represent empty entries by objects of type + empty_entry. + (table_entry::line_type): Return -1. + (table::determine_row_type): Ignore entries with line_type 0. + Treat type -1 as non-lines. + +Fri Dec 28 15:04:41 1990 James Clark (jjc at jclark) + + * ps/devps/textmap, xditview/libXdvi/DviChar.c, tty/devlatin1/R.proto, + macros/tmac.s: Rename \(-d to \(Sd. + +Thu Dec 27 12:35:47 1990 James Clark (jjc at jclark) + + * ps/devps/textmap: Add `sd', `/_' and `3d' characters. + * xditview/libXdvi/DviChar.c: Likewise. + * dvi/devdvi/texsy.map: Add `<<', `>>'. + +Wed Dec 26 13:33:23 1990 James Clark (jjc at jclark) + + * troff/div.c (top_level_diversion::begin_page): Call + init_output() if the_output is 0. + +Sat Dec 22 12:35:29 1990 James Clark (jjc at jclark) + + * troff/input.c: Replace ESCAPE_E by ESCAPE_e and ESCAPE_C by + ESCAPE_c. + (get_copy): Turn \E into ESCAPE_E. + (token::process, asciify): Handle ESCAPE_E. + + * macros/tmac.s (ds*common-end, par@reset): Add `.rj 0'. + (RD): New macro. + (DS): Implement `.DS R'. + +Fri Dec 21 11:41:53 1990 James Clark (jjc at jclark) + + * macros/tmac.s (FS): New macro. + + * macros/tmac.s (fn@do-FS): Use @LP instead of LP. + + * macros/tmac.s (cov*tl-init): Remove after first execution + instead of aliasing to @nop. Call top of page macro explicitly + instead of setting trap; call @init first. Set pg@top as top of + page macro. + (cov*auto-init): Deleted. Set cov*tl-init instead of + cov*auto-init as top of page trap. + (TL, LP): Do a break instead of calling cov*tl-init. + (cov*print): With RP format but no TL, alias FS and FE to @FS and + @FE; in this case also give a warning and always start another + page. No need to set pg@top here. + (cov*tl-init): Rename to cov*first-page-init. + + * macros/tmac.s (RP): Do `.pn 0'. + (cov*tl-init): With RP format don't do `.pn 0'. + + * macros/tmac.s (pg@cs-top): Set no space mode. + + * macros/tmac.s (par@TL, par@AU, par@AI): New macros. + (cov*ab-init): Alias TL, AU and AI to these. + +Thu Dec 20 10:10:50 1990 James Clark (jjc at jclark) + + * macros/tmac.s (@EQ): Move the space before the equation into @EN + (@EN): Do nothing unless \n[dl] is > 0. + +Tue Dec 18 12:20:47 1990 James Clark (jjc at jclark) + + * pic/object.c (ellipse_object::radius): New function. + + * VERSION: Change version to 0.7. + + * tbl/table.c (block_entry::do_divert): Declare return type as + void. + (block_entry::divert, alphabetic_block_entry::divert): Return 1. + +Mon Dec 17 12:30:34 1990 James Clark (jjc at jclark) + + * troff/column.c: New file. + * troff/Makefile: Corresponding changes. + + * troff/hvunits.c (scale(vunits, vunits, vunits)): New function. + Friend of vunits. + + * troff/div.c (top_level_diversion::space): If the space causes + the first-page transition and springs a trap, truncate the space + to 0. + +Fri Dec 14 12:30:02 1990 James Clark (jjc at jclark) + + * ps/ps.c (ps_printer::do_import): Add a `clear' after including + the document. + + * pic/troff.c (troff_output::line_thickness, + troff_output::set_fill): Do a horizontal motion to compensate for + the width of the \D escape sequence. + +Thu Dec 13 10:17:14 1990 James Clark (jjc at jclark) + + * xditview/tmac.X: Reinstate definition of \(rn, but only for X100 + (not X75). + + * eqn/sqrt.c (sqrt_box::compute_metrics): Supply missing argument + to printf. + + * tbl/table.c (simple_entry::simply_print): Don't declare as pure. + Supply empty definition. + (text_entry::simple_print, simple_text_entry::simple_print): + Delete declarations. + (table::add_entry): Represent empty entries by objects of type + `simple_entry'. + +Wed Dec 12 08:50:48 1990 James Clark (jjc at jclark) + + * troff/Makefile: Remove -DHYPHEN_CONTROL from DEFINES. + + * tbl/table.c (left_text_entry::add_tab): New function. + + * macros/tmac.s: Make @RT an alias for par@reset. Make RT + initialize like LP. + +Mon Dec 10 11:19:55 1990 James Clark (jjc at jclark) + + * troff/env.c (environment::start_field): Give an error message if + there is no next tab. + +Sun Dec 9 11:46:40 1990 James Clark (jjc at jclark) + + * troff/env.c (hyphenate): Skip initial elements with zero + hyphenation code. + + * macros/tmac.s (par@init): Keep VS in points rather than units. + +Sat Dec 8 23:00:27 1990 James Clark (jjc at jclark) + + * pic/main.c (main): Implement `-c' option. + * pic/output.h: Declare make_tpic_output(). + * pic/tex.c (tex_output::set_pen_size): Make it virtual and + protected. + (tpic_output): New class. + (tpic_output::tpic_output, tpic_output::set_pen_size, + tpic_output::command, make_tpic_output): New functions. + +Fri Dec 7 11:57:41 1990 James Clark (jjc at jclark) + + * tbl/main.c (main): Call `.ab' if \n(.g is false. Define TS/TE + if they're not already defined. + * tbl/table.c (init_output): Don't test \n(.g. + + * troff/input.c (do_if_request): Delete `g' condition. Recognize + `d', `r' and `c' conditions even in compatibility mode. + +Tue Dec 4 09:13:47 1990 James Clark (jjc at jclark) + + * ps/tmac.ps (ps-bb): Protect against negative numbers in bounding + box. + +Mon Dec 3 07:18:26 1990 James Clark (jjc at jclark) + + * troff/env.h (environment::prev_line_interrupted): New member. + (environment::get_prev_line_interrupted): New function. + * troff/env.c (environment::newline): Set prev_line_interrupted. + (environment::environment(const environment *), + environment::environment(symbol)): Initialize + prev_line_interrupted. + * troff/input.c (process_input_stack): Don't give special + treatment to space and newline at the beginning of the line if the + previous line was interrupted. + +Sat Dec 1 15:48:37 1990 James Clark (jjc at jclark) + + * eqn/eqn.y: Disallow PRIME by itself. + * eqn/lex.c (token_table): Bind `opprime' instead of `prime' to + PRIME. + (def_table): Remove definition of '. Define prime to be `. + + * eqn/eqn.y: Split off part of rule `script' into a new rule + `nonsup'. + +Fri Nov 30 10:23:44 1990 James Clark (jjc at jclark) + + * macros/tmac.s ({, }): New string aliases. + +Thu Nov 29 11:34:40 1990 James Clark (jjc at jclark) + + * README-0.7: New file. + +Wed Nov 28 10:09:57 1990 James Clark (jjc at jclark) + + * macros/tmac.s: New file. + * man/groff_ms.man: New file. + * Makefile: Add definition of TMAC_S. Pass TMAC_S in SUBFLAGS. + * Makefile.bd: Similarly. + * man/Makefile: Add groff_ms.n to MAN7PAGES. Replace @TMAC_S@. Add + definition of TMAC_S. + * macros/Makefile: Add definition of TMAC_S. Install tmac.s. + * macros/TODO: New file. + +Sat Nov 24 20:04:54 1990 James Clark (jjc at jclark) + + * troff/env.c (right_justify): New function. + (init_env_requests): Bind this to request "rj". + (center_lines): Set right_justify_lines to 0. If we get a bad + integer, center 1 line. + (environment::environment(symbol), environment::environment(const + environment *)): Initialize right_justify_lines. + (environment::get_right_justify_lines): New function. + (init_env_requests): Bind this to number_register ".rj". + + * troff/env.c (environment::choose_breakpoint): Implement + hyphenation_margin and hyphenation_space. + (environment::get_hyphenation_space, + environment::get_hyphenation_margin): New functions. + (init_env_requests): Bind these to .hys and .hym. + (hyphenation_space_request, hyphenation_margin_request): New + functions + (init_env_requests): Bind these to hys and hym. + (environment::environment(symbol), environment::environment(const + environment *)): Initialize hyphenation_margin and + hyphenation_space. + * troff/env.h: Corresponding changes to class environment. + +Fri Nov 23 09:08:16 1990 James Clark (jjc at jclark) + + * troff/div.c (blank_line): Always do a break. + + * eqn/box.c (do_text): Turn off escapes while appending text to + string. + +Thu Nov 22 10:58:59 1990 James Clark (jjc at jclark) + + * troff/input.c (while_break_request, while_continue_request): New + functions. + (init_input_requests): Bind these to "break" and "continue". + (while_depth, while_break_flag): New variables. + (while_request): Update while_depth. Break out of loop if + while_break_flag is set. + +Wed Nov 21 10:54:40 1990 James Clark (jjc at jclark) + + * tbl/table.c (init_span_reg): Initialize span_width_reg to \n(.H + rather than 0. + +Mon Nov 19 00:45:03 1990 James Clark (jjc at jclark) + + * Makefile: Include -DBROKEN_SPOOLER by default. Expand comment. + + * stringify: New file. + * Makefile (groff.o): Use stringify. + + * xditview/tmac.X: Remove definition of \(rn. + * xditview/libXdvi/DviChar.c: Remove radicalex from + Adobe_symbol_map. + +Sat Nov 17 10:44:58 1990 James Clark (jjc at jclark) + + * tbl/table.c (table::add_entry): Allow alphabetic text blocks. + (alphabetic_block_entry::alphabetic_block_entry, + alphabetic_block_entry::divert, alphabetic_block_entry::print): + New functions. + (block_entry::divert): Split off body into ... + (block_entry::do_divert): If the block is alphabetic, subtract 2n + from the line length; also update the span width to dl+2n, and the + alphabetic span width to dl. + + * driver/input.c (do_file): While reading argument to D command, + when expanding buffer, multiply szp by sizeof(int) rather than 2 + in the argument to memcpy. + + * tbl/table.c (compute_span_width): Add 2n rather than 1n to the + width of alphabetic columns. + +Fri Nov 16 06:34:27 1990 James Clark (jjc at jclark) + + * troff/node.c (lookup_family): Supply second argument to lookup. + + * troff/dictionary.c (dictionary::lookup): After an unsuccessful + search, return immediately if v is 0. + + * pic/troff.c: Define EQN_NO_EXTRA_SPACE_REG. + (troff_output::start_picture): Set this reg. + (troff_output::end_picture): Remove this reg + * eqn/box.c (box::extra_space): Don't produce `\x's if + EQN_NO_EXTRA_SPACE_REG is defined. + + * eqn/eqn.y: Allow just a PRIME to be a `simple'. + * eqn/text.c (split_text): Map ' to \(fm when it's the first + character. + +Thu Nov 15 10:35:06 1990 James Clark (jjc at jclark) + + * macros/tmac.e: Use font 3 instead of B in $c. Remove `bd' + requests. + + * troff/div.c (top_level_diversion::top_level_diversion): + Initialize page_number to 0. + +Wed Nov 14 21:41:58 1990 James Clark (jjc at jclark) + + * groff/troff (environment::environment(const environment *)): + Initialize name to e->name, rather than "anonymous". + +Sat Nov 10 01:59:37 1990 James Clark (jjc at jclark) + + * xditview/libXdvi/Dvi.c (ShowDvi): If eof is encountered, reset + requested_page. Split middle part into ... + (FindPage): New function. + (SetValues): If we don't yet know the last page, and the requested + page is greater than the current page, call FindPage. + Update the font_map_string before doing this. + + * xditview/tmac.X: Add definitions of \(sq, \(ga, \(dg and \(dd. + Translate \(lh and \(rh into left and right double arrows. + + * troff/node.c (class hyphen_inhibitor_node): New class. + (hyphen_inhibitor_node::hyphen_inhibitor_node, + hyphen_inhibitor_node::copy, hyphen_inhibitor_node::same, + hyphen_inhibitor_node::type, + hyphen_inhibitor_node::get_hyphenation_type): New functions. + (node::add_discretionary_hyphen): Use hyphen_inhibitor_node rather + than dbreak_node(0, 0) to represent a `\%' at the beginning of a + word. + +Fri Nov 9 16:05:38 1990 James Clark (jjc at jclark) + + * troff/node.h (dummy_node::get_hyphenation_type, + transparent_dummy_node::get_hyphenation_type): Declare them. + * troff/node.c: (dummy_node::get_hyphenation_type, + transparent_dummy_node::get_hyphenation_type): New functions. + +Wed Nov 7 10:09:06 1990 James Clark (jjc at jclark) + + * xditview/libXdvi/draw.c: If M_PI not defined after including + math.h, then define it. + + * xditview/Makefile: Add definition of AR. Pass it to the submake + in libXdvi. + * xditview/libXdvi/Makefile: Add definitions of AR and RANLIB. + +Tue Nov 6 10:14:27 1990 James Clark (jjc at jclark) + + * troff/dictionary.h (object_dictionary::alias): Declare return + value as int. + * troff/dictionary.c (object_dictionary::alias): Return non-zero + if the old name was defined. + * troff/input.c (alias_macro): Give a warning if the old name was + not defined. + * troff/reg.c (alias_reg): Likewise. + +Mon Nov 5 00:31:39 1990 James Clark (jjc at jclark) + + * troff/input.c (token::next): Delete implementation of \R. + + * macros/Makefile: Strip comments from tmac.e while installing it. + + * troff/input.c: New variable `nroff_mode'. + (troff_request, nroff_request): New functions. + (init_input_requests): Bind `troff' and `nroff' to troff_request + and nroff_request. + (do_if_request): Compute results of t and n conditions from + nroff_mode. + + * text/text.c (split_text): Fix typo in >=. + + * eqn/lex.c: Add definition of `==' to def_table. + +Fri Nov 2 02:49:09 1990 James Clark (jjc at jclark) + + * pic/tex.c (tex_output::start_picture): Change the definitions of + \graph and \graphtemp so that they work properly with Plain TeX. + + * pic/tex.c (tex_output::solid_arc): Ensure that the second angle + argument to `ar' is not less than the first. + + * pic/pic.y: Allow a comma between elements of the variable list + in the argument to `reset'. + + * pic/object.c (arc_object::arc_object): Fix computation of + radius. + + * eqn/main.c (main): Add exit(0). + +Thu Nov 1 02:03:50 1990 James Clark (jjc at jclark) + + * troff/div.c (begin_page): Test no_space_mode after doing the + break, but still push the page ejector cookie before doing the + break. Also set the next page number after doing the break. + + * xditview/xditview.c (NewFile): Don't set the title and icon name + if this is the first file and its name is `-'. + * groff/groff.c: Define a new device flag XT_OPTION. Set it for + the X75 and X100 devices. + (main): If a device has the XT_OPTION flag set and there's exactly + one file argument, pass the driver -xrm and -title options to set + the icon name and window title to the name of the file. + + * troff/env.c (environment_switch): If there was an argument but + it wasn't a valid number or name, then pop an environment but + don't give an error message on underflow. + + * troff/number.c (start_number): Correct spelling in error message. + + * troff/input.c (token::delimiter): Don't print an error message + if err is false. + + * xditview/libXdvi/parse.c (ParseInput): In case 'D', only call + ParseDrawFunction if dw->display_enable is true. + +Wed Oct 31 05:49:50 1990 James Clark (jjc at jclark) + + * pic/pic.y: Parse text positioning like normal attributes, so as + to allow `"text" at 0,0 ljust'. Don't allow `center' as a + positioning attribute. + +Mon Oct 29 22:50:38 1990 James Clark (jjc at jclark) + + * tbl/main.c (process_data): When in state START while reading a + text block, don't change to state MIDDLE if c is a newline. + +Sun Oct 28 21:59:56 1990 James Clark (jjc at jclark) + + * dvi/dvi.c (dvi_printer::begin_page): Rename `i' variable to `j' + so as to avoid shadowing parameter. + +Wed Oct 24 18:35:39 1990 James Clark (jjc at jclark) + + * tbl/table.c (trim_space): Deleted. + (table::add_entry): Don't call trim_space. + +Mon Oct 22 03:48:39 1990 James Clark (jjc at jclark) + + * VERSION: Change version to 0.6. + + * troff/number.c (parse_expr): Make == work. + +Sat Oct 20 11:28:17 1990 James Clark (jjc at jclark) + + * man/grog.man: New file. + * man/Makefile: Add grog.n to MAN1PAGES. + * etc/grog.sh: New file. + * etc/Makefile: Install grog.sh as grog. + +Fri Oct 19 11:17:15 1990 James Clark (jjc at jclark) + + * troff/input.c (token::next): Implement \E. + +Thu Oct 18 11:56:24 1990 James Clark (jjc at jclark) + + * xditview/tmac.X: Change font translations to match tmac.ps. + + * troff/input.c (non_empty_name_warning): Don't give a warning if + `\{' terminates the name. + +Tue Oct 16 10:04:23 1990 James Clark (jjc at jclark) + + * ps/devps/symbol.diff: New file. + * ps/devps/FontMakefile: Mention symbol.diff. + +Sun Oct 14 11:46:46 1990 James Clark (jjc at jclark) + + * troff/node.c (font_position): Use get_long_name to read the + external_name. + + * troff/env.c (environment_switch): If we get a number that's < 0 + or >= NENVIRONMENTS, treat it like a name. + Change NENVIRONMENTS to 10. + + * troff/groff.h: Remove definition of FONTS_MAX. + * troff/node.h (class font_family): Make map a pointer instead of + an array. Add a map_size member. Make it a class. Make nm const + and public. Make invalidate_fontno a friend. + * troff/node.c: Define font_table_size. Make font_info a pointer + rather than an array. + (class troff_output_file): Allocate font_position dynamically. Add + nfont_positions member. + (troff_output_file::set_font): Grow font_position if necessary. + (troff_output_file::~troff_output_file): Delete font_position. + (troff_output_file::troff_output_file): Allocate font_position. + (grow_font_table): New function. + (troff_output_file::really_begin_page, + troff_output_file:really_copy_page): Use nfont_positions rather + than FONTS_MAX. + (mount_font_no_translate, mount_style): Call grow_font_table if + necessary. + (font_family::font_family): Allocate map. + (font_family::make_definite): Grow map if necessary. Use + font_table_size instead of FONTS_MAX. + (font_family::~font_family): New function. + (invalidate_fontno): Use font_family::map_size. + (get_fontno, env_space_width, env_half_narrow_space_width, + env_narrow_space_width, symbol_fotno, is_good_fontno, + get_bold_fontno, make_glyph_node): Use font_table_size rather than + FONTS_MAX. + (next_available_font_position): Never return 0. + +Fri Oct 12 10:17:52 1990 James Clark (jjc at jclark) + + * ps/tmac.ps: Add font translations for compatibility with dpost. + +Thu Oct 11 12:09:03 1990 James Clark (jjc at jclark) + + * eqn/pile.c: Rename default_baseline_sep to baseline_sep. + Move BASELINE_SEP_FORMAT and COLUMN_WIDTH_FORMAT into pbox.h. + Move definitions baseline_sep, shift_down, column_sep, + matrix_side_sep into... + * eqn/box.c: Add them to param_table. + * eqn/pbox.h: Add declarations to pbox.h. + + * troff/input.c (set_string): Cast value to unsigned char *. + + * troff/token.h (process_input_stack): Declare it static before + declaring it a friend. + +Wed Oct 10 09:59:13 1990 James Clark (jjc at jclark) + + * dvi/devdvi/texex.map: Fix positions of extensible brace middle + and bottom. + * dvi/devdvi/EX: Regenerate. + + * troff/input.c (init_charset_table): Make ", ', ), ], *, \(dg + transparent. + +Tue Oct 9 08:34:02 1990 James Clark (jjc at jclark) + + * eqn/lex.c: In defaults_table, make definition of `dot' call + `dot_def'. Don't explicitly make it roman. Similarly for other + accents. + + * pic/lex.c (for_input::for_input): Add by_is_multiplicative + argument. + (for_input::get, for_input::peek): Use this. + (do_for): Add by_is_multiplicative argument. + * pic/pic.y: Change optional_by clause to allow '*' after `by'. + Change semantic value of optional_by to be a double plus a flag + saying whethet the by clause is multiplicative. + + * eqn/lex.c (get_delimited_text): Remember location of start of + definition. Improve error handling when EOF is encountered. + + * lib/font.h: Rename handle_x_command to + handle_unknown_font_command. + * lib/font.c (font::load): Call handle_unknown_font_command for + any unknown command in the font description file. Don't call + handle_x_command. Include the name of the command in the argv. + Improve message for unknown command after kernpairs or charset + command. + * ps/ps.c (ps_font::handle_x_command): Rename to + handle_unknown_font_command. Remove message about `x download' + command. Give error message for wrong number of arguments. + * ps/devps/afmtodit: Generate `encoding' instead of `x encoding'. + * dvi/dvi.c (dvi_font::handle_x_command): Rename to + handle_unknown_font_command. Give an error message for wrong + number of arguments. Rename design_size to designsize. + * dvi/tfmtodit.c (main): Generate `checksum' instead of `x + checksum', `designsize' instead of `design_size'. + +Mon Oct 8 00:38:55 1990 James Clark (jjc at jclark) + + * eqn/*.[chy]: Change underaccent to uaccent. + + * eqn/eqn.y: Add rule for underaccent. Declare UNDERACCENT token; + give it the same precedence as ACCENT. + * eqn/other.c (make_underaccent_box): New function. + * eqn/box.h: Declare it. + * eqn/lex.c: Add UNDERACCENT to token_table. Add utilde to + def_table. + +Sun Oct 7 11:25:16 1990 James Clark (jjc at jclark) + + * pic/pic.y (reset_all): New function. Called in rule for RESET. + (parse_init): Call reset_all. + (define_variable): When defining scale reset only those + pre-defined variables that are scaled. + (defaults_table): Add `scale' as non-scaled value. + + * pic/pic.y: Redo parsing of text adjustments: parse adjustments + together with the text; allow any number of positioning words; + allow center as a positioning word. + + * pic/object.c (output::compute_scale): Get picture maximum height + and width from variables called maxpswid and maxpsht. + * pic/pic.y: Add maxpswid and maxpsht to defaults_table. + +Sat Oct 6 10:16:56 1990 James Clark (jjc at jclark) + + * pic/object.c (object_spec::make_text): Multiply textht by number + of text items. + + * pic/pic.y: Allow `sprintf("string", expr,...)' wherever text can + occur. + (do_sprintf): New function. + (pic.gperf): Add sprintf token. + (text, sprintf): New rules. + + * pic/pic.y: `rand()' with no arguments returns a random number + in the range [0,1). + + * pic/pic.y: Allow a bare expression to be an attribute: change + precedences to support this. Change optional_ordinal rule to + optional_ordinal_last to avoid reduce/reduce conflict. + * pic/object.c (object_spec::object_spec): Initialize direction. + + * pic/pic.y: Implement ^ operator meaning exponentiation. + + * troff/node.h: Add default argument to mount_font. + * troff/node.c (font_position): Read an optional third argument + giving the external_name. + (mount_font): Add optional argument giving the external_name. + (mount_font_not_translate): Have additional argument giving + external name. Use this name to load the font. Pass both names + to font_info::font_info. + (font_info::font_info): Have additional argument giving + external_name. + (class tfont): New member external_name. + (font_info::get_tfont): Use external name to construct tfont_spec. + +Fri Oct 5 04:03:13 1990 James Clark (jjc at jclark) + + * eqn/lex.c (init_table): Add argument giving device. Define + name of device to be "1". + (do_ifdef): Counts as true if the argument has been defined with + `define'. + * eqn/main.c (main): Call init_table with device argument. Make + device local to main. + * eqn/eqn.h: Change declaration of init_table. Remove declaration + of device. + + * pic/lex.c (get_delimited): Allow text to be delimited by + matching {}s. Don't recognize ending delimiter within a string. + + * troff/input.c (get_delim_name): New function. + (token::next): Implement \C. + + * lib/font.c (font::load): Grok ---. Add an alias for each + character based on its code. + (font::get_code_width): Deleted. + * lib/font.h (class font): Declare font::number_to_index(). + Remove declaration of font::get_code_width. + * lib/nametoindex.c (font::name_to_index): Add 512 rather than 256 + to indices of named characters. + (font::number_to_index): New function. + * troff/input.c (font::number_to_index): New function. + (get_charinfo_by_number, charinfo::get_number, + charinfo::set_number): New functions. + (token::next): Turn \N into a TOKEN_NUMBERED_CHAR. + (token::process, token::description, token::get_char, + token::add_to_node_list, token::operator==): Handle + TOKEN_NUMBERED_CHAR. + * troff/charinfo.h: Declare get_charinfo_by_number, + charinfo::get_number, charinfo::set_number. Add NUMBERED flag to + charinfo class. + (charinfo::numbered): New function. + * troff/token.h: Add TOKEN_NUMBERED_CHAR. + * troff/env.h (class environment): Remove declaration of ... + * troff/env.c (environment::make_numbered_char_node): Deleted. + * troff/node.c (make_numbered_node): Deleted. + (class numbered_glyph_node): Remove. + (troff_output_file::put_char_width, troff_output_file::put_char): + Handle numbered chars. + (troff_output_file::numbered_char): Removed. + (tfont::get_code_width): Removed. + (make_glyph_node): Don't search special fonts for numbered + characters. + * troff/node.h: Remove declaration of make_numbered_node. + * driver/input.c (do_file): Handle N command. + * driver/printer.h: Add declaration of ... + * driver/printer.c (printer::set_numbered_char): New function. + * dvi/tfmtodit.c (main): Generate unnamed entries. + * ps/devps/afmtodit: Likewise. + * xditview/xtotroff.c (MapFont): Likewise. + * xditview/libXdvi/parse.c (ParseInput): Grok N command. + + * tbl/main.c (process_format): If multiple widths are specified + for a column but all the widths are the same, don't give an error + message. + + * tbl/table.c (table::do_row): If the current row is all lines and + the stuff doesn't contains a line, mark the top of the row after + printing stuff before the row. If the current row is not all + lines and the stuff doesn't contain a line, don't unnecessarily + mark the top of the row before printing the stuff. + +Mon Oct 1 11:42:00 1990 James Clark (jjc at jclark) + + * troff/groff.h: Remove MAX_PATH. + * troff/input.c (open_file): Dynamically allocate space for the + path. + (open_mac_file, process_macro_file): Corresponding changes. + +Sun Sep 23 18:56:26 1990 James Clark (jjc at jclark) + + * troff/node.h (class output_file): Make copy_file pure. Add + vspace method ifdef COLUMN. Add is_printing method. + * troff/node.c: Add class printing_reg. Add class + real_output_file. Derive other output_file classes from + real_output_file; in these classes rename begin_page to + really_begin_page, print_line to really_print_line, copy_file to + really_copy_file, transparent_char to really_transparent_char. + Move output_file::flush to real_output_file. Add printing member + to class output_file. + * troff/div.h: Remove printing member from top_level_diversion. + Add vspace member function to class diversion ifdef COLUMN. Add + some declarations ifdef COLUMN. + * troff/div.c (top_level_diversion::copy_file, + top_level_diversion::transparent_output, + top_level_diversion::output): Don't test printing member before + output. + * troff/input.c: Handle initial variable_space_request ifdef + COLUMN. + * troff/Makefile: Add column.c but comment it out. Add -DCOLUMN + but comment it out. + +Sat Sep 22 11:32:22 1990 James Clark (jjc at jclark) + + * troff/div.c (diversion::need): Make any space forced. If we + sprung a trap, set truncated_space to minus the distance to the + trap and set needed_space to the amount that was needed. + (top_level_diversion::space): A forced space turns no_space_mode + off. + (class constant_vunits_reg): New class. + (init_div_requests): Implement number registers .trunc and .ne + using constant_vunits_reg. + (class truncated_space_reg): Deleted. + + * troff/div.h: Don't have a no_space_mode member in diversion. + Instead have it in top_level_diversion. + * troff/div.c (diversion::diversion): Don't initialize + no_space_mode. + (top_level_diversion::top_level_diversion): Initialize + no_space_mode. + (no_space, restore_spacing): Do nothing if curdiv != topdiv. + (macro_diversion::output): Don't clear no_space_mode. + + * troff/input.c (diverted_space_node::reread): Don't call + environment::do_break. In fill mode, act like a blank line. + (diverted_copy_file_node::reread): Don't call + environment::do_break. + + * troff/div.c (blank_line): New function. + * troff/div.h: Declare it. + * troff/input.c (process_input_stack): Call it. + + * troff/div.c (truncated_space_reg::get_string): New function. + (init_div_requests): Bind to .trunc. + (space_request, top_level_diversion::space, + top_level_diversion::output, macro_diversion::space, + macro_diversion::output): Update truncated_space. + (macro_diversion::output): Redo calculations when trap sprung. + (macro_diversion::output, macro_diversion::space): No need for + trap_flag. + + * troff/div.c (top_level_diversion::output): Set nl_reg_contents + after truncating post line spacing. + +Fri Sep 21 11:27:25 1990 James Clark (jjc at jclark) + + * ps/devps/prologue (MF, SF): Make them work even if setfont is + defined as a procedure rather than as an operator. + +Thu Sep 20 12:55:05 1990 James Clark (jjc at jclark) + + * troff/div.c (macro_diversion::space): Ignore no_space_mode. + +Wed Sep 19 10:54:37 1990 James Clark (jjc at jclark) + + * troff/div.c (top_level_diversion::output): Merge + output_file::print_line and output_file::end_of_line member + functions. + * troff/div.h (class output_file): + * troff/node.c (troff_output_file::print_line, + troff_output_file::end_of_line, output_file::end_of_line, + ascii_output_file::print_line, suppress_output_file::print_line): + Corresponding changes. + +Tue Sep 18 11:31:47 1990 James Clark (jjc at jclark) + + * troff/input.c (token::next): Don't give a warning for `\.'. + + * troff/env.c (environment::get_center_lines): New function. + (init_env_requests): Bind number register .ce to it. + * troff/env.h: Declare it. + * tbl/table.c (table::init_output): Define reset macro to restore + .ce. If center option not given, store .ce in SAVED_CENTER_REG. + Then do .ce 0. + (table::print): If center option not given, then imply center + option if SAVED_CENTER_REG > 0. + +Mon Sep 17 09:19:19 1990 James Clark (jjc at jclark) + + * ps/devps/Makefile: Remove T from FONTS. Remove TSymbol.ps and + Troff.ps from DOWNLOAD. + + * troff/Makefile: Change comment in DEFINES to avoid confusing + System V make. + + * ps/ps.c (ps_printer::do_exec): Allow newlines within PostScript + code. Don't try to catch errors with stopped. + (check_line_lengths): New function. + * ps/devps/prologue (EXEC): Deleted. + (EBEGIN, EEND): New procedures. + +Sun Sep 16 14:51:15 1990 James Clark (jjc at jclark) + + * troff/input.c: Include request.h before node.h. + * troff/node.c: Likewise. + * troff/env.c: Likewise. + * troff/div.c: Likewise. + * troff/node.h (class special_node): Store argument as a macro + rather than a char *. + * troff/node.c (special_node::special_node, special_node::copy): + Grok this. + (special_node::~special_node): Deleted. + (special_node::tprint): Deleted. + (special_node::tprint_start, special_node::tprint_end, + special_node::tprint_char): New functions. + (troff_output_file::special): Deleted. + (troff_output_file::start_special, troff_output_file::end_special, + troff_output_file::special_char): New functions. + * troff/input.c (special_node::tprint): New function. + (do_special): Use macro not char *. + (do_transparent_macro): Deleted. + (token::next): Don't call do_transparent_macro. + + * troff/input.c (token::next): Add 'Y' case. + (do_transparent_macro): New function. + * troff/node.c (troff_output_file::special): Handle newlines with + argument using new continuation convention. + * driver/input.c (get_string): Cope with continuation convention. + (do_file): Don't call skip_line after calling get_string(1). + * ps/ps.c (ps_printer::special, ps_printer::do_import, + ps_printer::do_def, ps_printer::do_exec): Cope with newlines in + arg. + * xditview/libXdvi/parse.c (ParseInput): Ignore lines starting + with +. + +Sat Sep 15 19:00:10 1990 James Clark (jjc at jclark) + + * troff/input.c (asciify): By default, invalid input characters + should return empty string. + + * troff/input.c (copy_file): Handle first page transition like title. + (token::next, process_input_stack): Grok COPY_FILE_REQUEST. + + * troff/input.c (token::next): Improve error message for EOF after + escape character. + (input_char_description): New function. + (get_char_for_escape_name): Use input_char_description. + (token::next): Warn about unrecognized escape sequences. + (warning_table): Add WARN_ESCAPE. + * troff/groff.h: Declare WARN_ESCAPE. Change WARN_TOTAL + accordingly. + + * troff/token.h: Remove declaration of process_input_stack. + + * troff/input.c: Remove declaration of init_hyphen_requests. + * troff/request.h: Correct spelling in declaration of same. + + * troff/input.c (token::next): Check whether escape_char is 0. + +Fri Sep 14 12:09:25 1990 James Clark (jjc at jclark) + + * groff.c (main, usage, help): Implement -P and -L options. + * groff.sh: Likewise. + + * troff/input.c (token::next): Use some gotos to avoid code + duplication. + + * troff/input.c (get_long_name, get_name, read_long_ecsape_name): + Avoid calling symbol::symbol if name empty. + +Thu Sep 13 06:21:45 1990 James Clark (jjc at jclark) + + * troff/input.c (init_input_requests): Make \n(.x return the major + version number and \n(.y return the minor version number. + * troff/Makefile: Construct file majorminor.c defining + major_version and minor_version automatically from ../VERSION. + + * troff/node.c (class glyph_node): Make operator new and operator + delete public. + (class ligature_node): Similarly. + + * troff/input.c (operator==(const macro &, const macro &)): New + function. + (non_interpreted_node::same): Use this. + (string_iterator::string_iterator): Make macro& argument const. + + * troff/input.c (input_iterator::get): New function. Don't make + asciify_macro or class non_interpreted_node friends of class + input_iterator. + (non_interpreted_node::interpret): Use input_iterator::get. + (asciify_macro): Likewise. + + * troff/input.c (~token_node, ~string_iterator, ~arg_list, + ~non_interpreted_node): Deleted. + * troff/node.c: (~suppress_output_file, ~ascii_output_file): + Deleted. + + * troff/symbol.h: Make all symbol member functions const. + + * lib/strtol.c: New file. + * lib/Makefile: Add strtol.c. + * Makefile: Define STRTOL as strtol.o to include strtol in + libgroff.a. + +Wed Sep 12 10:00:49 1990 James Clark (jjc at jclark) + + * pic/troff.c (troff_output::simple_circle): Divide by scale. + +Tue Sep 11 14:17:16 1990 James Clark (jjc at jclark) + + * troff/input.c (do_special): Use input_level. + + * troff/token.h (TOKEN_BACKSPACE): New token. + (token::backspace): New function. + * troff/input.c (token::description, token::next, token::process): + Grok TOKEN_BACKSPACE. + (do_special): Turn TOKEN_BACKSPACE back into \b. + + * troff/token.h (token::leader): New function. + * troff/input.c (do_special): Turn TOKEN_LEADER back into \001. + + * troff/input.c (do_special): Turn TOKEN_TAB back into \t. + + * troff/input.c (do_special): Use token::description in error + message. + +Mon Sep 10 11:06:27 1990 James Clark (jjc at jclark) + + * troff/input.c (decode_args): Combine quoted and + quote_input_level variables. Make it a for (;;) loop. + + * troff/input.c (get_char_for_escape_name): Check for \001 and \b. + + * troff/input.c (read_long_escape_name): The test for whether to + expand buffer was off by 1. + (read_string): Similarly. + +Fri Sep 7 11:45:50 1990 James Clark (jjc at jclark) + + * troff/input.c: Use `const int' rather than `static const int'. + + * troff/div.h (diversion::copy_file): Declare as pure virtual. + (macro_diversion::copy_file): New function. + * troff/node.h: New class diverted_copy_file_node. + * troff/node.c: Implement it. + * troff/input.c (copy_file): Use diversion::copy_file. Handle + first page transition by pushing a diverted_copy_file_node. + * troff/input.c (token::next, process_input_stack): Don't handle + COPY_FILE_REQUEST. + +Thu Sep 6 13:29:10 1990 James Clark (jjc at jclark) + + * ps/ps.c (flush_sbuf): Remember to add sbuf_kern when checking + whether space widths need adjusting. + + * troff/charinfo.h: Generalize translated_to_space to + special_translation so as to allow translation to \&. + * troff/input.c (translate): Allow translation to \&. + (charinfo::*): Corresponding changes. + * troff/node.c (make_node, node::add_char): Corresponding changes. + * troff/node.h (dummy_node::dummy_node): Allow optional first + argument. + + * lib/lib.h: Make codes 0200 to 0237 invalid input characters. + * troff/token.h: Remove TOKEN_TITLE. Remove token::title. Add + TOKEN_REQUEST. + * troff/input.c (token::next): Turn a TITLE_REQUEST into a + TOKEN_REQUEST with an argument of TITLE_REQUEST. + (token::process): Grok that. + * troff/input.c (copy_file): Handle first page transition like + title by pushing a COPY_FILE_REQUEST cookie. + (token::next, process_input_stack): Grok that. + * troff/node.h (output_file::copy_file): Add x and y arguments. + Make it non-pure. + * troff/div.c (top_level_diversion::copy_file): Supply them. + * troff/node.c (troff_output_file::copy_file): Add x and y + arguments; moveto specified position. Invalidate font_position + array after copying file. + (output_file::copy_file): New function. + (suppressed_output_file::copy_file, ascii_output::copy_file): + Removed. + * troff/input.c (transparent_file): New function. + (init_input_requests): Bind to "trf". + (token::next): Handle TRANSPARENT_FILE_REQUEST cookie. + (process_input_stack): Likewise. + + * troff/Makefile: Add ../lib/lib.h to GROFF_H. + + * troff/node.c (init_node_requests): New number registers .kern + pointing to global_kern_mode, and .lg pointing to + global_ligature_mode. + + * troff/node.c (ligature): Don't change it if we get a bad + integer. + + * troff/input.c (do_define_string): Don't strip tabs. + + * troff/input.c (asciify_macro): Make the string_iterator auto. + + * troff/node.c (init_font_requests): Rename to... + (init_node_requests): + * troff/node.h: Change declaration. + * troff/input.c (main): Change call. + + * troff/input.c (node::reread, diverted_space_node::reread): New + methods. + (process_input_stack): Call reread rather than + get_diverted_space_node. + * troff/node.c (node::get_diverted_space_node, + diverted_space_node::get_diverted_space_node): Removed. + * troff/node.h: Declare reread methods instead of + get_diverted_space_node methods. Make `n' member private. + * troff/input.c: (token::diverted_space): Removed. + * troff/token.h: Removed declaration. + + +Tue Sep 4 00:48:04 1990 James Clark (jjc at jclark) + + * eqn/script.c (script_box::compute_metrics): Don't let + SUP_RAISE_FORMAT become negative. + + * tbl/table.c (table::do_row): Entries that don't end in the + this row shouldn't make the row non-blank. + + * tbl/table.c (table::make_columns_equal): Only set the width of + columns which are marked as equal. + + * tbl/main.c (process_data): Before issuing excess data error, + if last character was a newline unget it; then get it again after + the error. Also include the contents of the entry in the message. + + * groff.c: New file. + * Makefile: Build groff from groff.c. Make it possible to use + either groff.sh or groff.c as groff. + * Makefile.bd: Similarly. + +Mon Sep 3 09:39:49 1990 James Clark (jjc at jclark) + + * groff.sh: Don't delay expansion of $@ in assignment to files. + Remove occurrences of \". + +Sun Sep 2 09:56:59 1990 James Clark (jjc at jclark) + + * all Makefiles: Simplify and rearrange. + + * Makefile: Handle fmod like malloc. + * lib/Makefile: Similarly. + * lib/fmod.c: Remove #ifdef NEED_FMOD. + + * Makefile: Rename OPTIMISE to OPTIMIZE. + + * groff.sh: Remove assignment to PATH. + * Makefile: Remove SHPATH variable. + * Makefile.bd: Similarly. + + * groff.sh: Add -V option to print the pipeline instead of + executing it. + +Fri Aug 31 00:56:46 1990 James Clark (jjc at jclark) + + * lib/font.c: Split off file searching into ... + * lib/fontfile.c: New file. + + * lib/strerror.c (strerror): Use `Error %d' for unknown errors. + +Thu Aug 30 13:13:55 1990 James Clark (jjc at jclark) + + * tbl/table.c (table::do_hspan): Delete assertion that e != 0. + Also change misleading comment. + (table::do_vspan): Change similarly misleading comment. + * tbl/main.c (process_data): A format row with an explicit `s' + uses up a data line, even if all the other columns are `_' or `='. + + * troff/input.c (token::description): Fix description of + TOKEN_DUMMY and TOKEN_EMPTY. + +Wed Aug 29 04:12:08 1990 James Clark (jjc at jclark) + + * groff.sh: Fix description of -Z in help message. + +Tue Aug 28 07:28:33 1990 James Clark (jjc at jclark) + + * pic/object.c (object_spec::make_object): Allow negative and zero + line thicknesses. + * pic/pic.y: Give linethick default value of -1.0. + * pic/troff.c (troff_output::troff_output): Initialize + last_line_thickness to BAD_THICKNESS. + (troff_output::finish_picture): Set thickness to BAD_THICKNESS. + (troff_output::line_thickness): Canonicalize negative thicknesses + to RELATIVE_THICKNESS. + * pic/tex.c (tex_output::set_pen_size): Silently map negative line + thicknesses to DEFAULT_PEN_SIZE. Canonicalize negative pen sizes + to -1.0. + (tex_output::start_picture): Set pen_size to -2.0. + + * ps/ps.c (ps_printer::set_line_thickness): If line_thickness is + 0, then use 0 linewidth. + (ps_printer::ps_printer): Initialize line_thickness to -1. + + * pic/troff.c (troff_output::simple_ellipse): Divide by scale. + + * ps/devps/symbolchars: Remove `or'. + * ps/tmac.ps: Implement \(or with .char. + + * ps/devps/symbolchars: Move most characters into textmap. + * ps/devps/textmap: Add names for troff bracket characters. Remove + ul, ru, br, bv. + + * ps/devps/TSymbol.ps: Removed. + * ps/devps/FontMakefile: Make S from Symbol not TSymbol. + * ps/tmac.ps: Do with .char what TSymbol did. + * ps/devps/download: Remove TSymbol. + + * ps/devps/T: Removed. + * ps/devps/Troff.ps: Removed. + * ps/devps/Troff.afm: Removed. + * ps/tmac.ps: Implement \(ru, \(ul, and \(br with .char. + * ps/devps/download: Remove Troff. + * ps/devps/FontMakefile: Remove T target. + * ps/devps/DESC-A4: Remove T from font list. + * ps/devps/DESC-letter: Likewise. + + * troff/input.c (macro_to_node): Rename to ... + (charinfo_to_node): Don't pass mac argument. Temporarily remove the + character's definition while processing it. + * troff/node.c (node::add_char, make_node): Change calls to + macro_to_node accordingly. + + * troff/input.c (token::next): Translate \_ to \(ul. + + * tty/devascii/R.proto: Add `|'. + * tty/devlatin1/R.proto: Likewise. + +Mon Aug 27 11:25:41 1990 James Clark (jjc at jclark) + + * man: Put the version number in all the man pages. + +Sun Aug 26 11:40:05 1990 James Clark (jjc at jclark) + + * Makefile.bd: New file. + * README.bd: New file. + + * VERSION: New file. + * lib/version.c: Removed. + * lib/Makefile: Create version.c from ../VERSION. Remove version.c + in clean target. + + * troff/input.c (main): Get hyphen_file from GROFF_HYPHEN + environment variable. + + * all Makefiles: Split install target into install.bin for + binaries, and install.nobin for everything else. + * Makefile: Add bindist target. + + * man/afmtodit.man: New file. + * man/Makefile: Add afmtodit.n to MAN1PAGES. + * ps/devps/Makefile: Add textmap to DEVICEFILES. Install afmtodit + in BINDIR. + * ps/Makefile: Pass BINDIR to make install in devps. + + * ps/ps.c (ps_printer::set_char): Do nothing if the character is + the space character. + + * ps/devps/FontMakefile: Rename symbol.afm to tsymbol.afm. + +Sat Aug 25 15:39:03 1990 James Clark (jjc at jclark) + + * ps/ps.c: Redo font downloading. + * ps/devps/download: New file. + * ps/devps/Makefile: Add download to DEVICEFILES. + * ps/devps/afmtodit: Remove -d option. + * ps/devps/FontMakefile: Don't use -d option with afmtodit. + * ps/devps/symbosl.ps: Add %%DocumentFonts comment. + * ps/devps/zapfdr.ps: Likewise. + * ps/devps/TSymbol.ps: Likewise. + +Fri Aug 24 20:10:30 1990 James Clark (jjc at jclark) + + * groff.sh: Initialize dev to ${GROFF_TYPESETTER:-@DEVICE@}. + +Thu Aug 23 10:03:47 1990 James Clark (jjc at yquem) + + * ps/ps.c (ps_output::include_file): If BROKEN_SPOOLER is defined, + then strip the first line if it starts with %. + * Makefile: Add a comment about this. + + * man/tfmtodit.man: New file. + * man/Makefile: Add tfmtodit.n to MAN1PAGES. + * dvi/Makefile: Install tfmtodit in BINDIR. + + * dvi/tfmtodit.c (usage): Mention -v option. + +Wed Aug 22 09:56:36 1990 James Clark (jjc at yquem) + + * troff/node.c (troff_output_file::end_of_line): Call do_motion. + * troff/node.c (troff_output_file::transparent_char): Don't call + flush_tbuf. + + * eqn: Add check_tabs method to most box classes. + * eqn/box.c (box::top_level): Call check_tabs. + + * eqn/script.c (script_box::output): Use \Z. + * eqn/limit.c (limit_box::output): Use \Z. + + * eqn/box.c (box::top_level): Use itoa. + +Tue Aug 21 09:29:28 1990 James Clark (jjc at yquem) + + * dvi/tmac.dvi: Add font translations for CR, C, TT. + * dvi/devdvi/Makefile: Don't make links to CW. + + * ps/tmac.ps: Add font translations for C, CW, CO, CX, CD, H, HO, + HX, HD. + * xditview/tmac.X: Likewise. + + * troff/node.c: Add font translation feature. + (get_font_translation): New function. + (symbol_fontno): Translate the font name. + (mount_font_no_translate): Rename to mount_font to this. + (mount_font): New function. + (font_family::make_definite): Call mount_font_no_translate instead + of mount_font. + (mount_style): Translate the font name. + (font_translate): New function. + (init_font_requests): Bind "ftr" to font_translate. + + * ps/devps/prologue (SN): New procedure that rounds a position to + the nearest (pixel + (.25,.25)). + (DL): Use SN to round endpoints. + + * lib/version.c: Changed version to 0.5. + +Sat Aug 18 04:43:21 1990 James Clark (jjc at yquem) + + * Makefile: Move definition of PAGE to the very beginning, so that + people are less likely to miss it. + +Fri Aug 17 02:15:11 1990 James Clark (jjc at yquem) + + * man/Makefile: Don't need to sed out @UPCASE_PROG_PREFIX@. + + * troff/env.c (environment::choose_breakpoint): Make `can't find + breakpoint' error a warning of type WARN_BREAK. Change message to + `can't break line'. + * troff/groff.h: Declare WARN_BREAK with code 4; change WARN_INPUT to + code 040000. + * troff/input.c: Add WARN_BREAK to warning_table. Include + WARN_BREAK in DEFAULT_WARNING_MASK. + + * tty/tmac.tty: Add definition of \(+-. + + * groff.sh: Remove `--' option to set command. + + * dvi/devdvi/texsy.map: Remove duplicate md entry. + + * ps/devps/eqnchar: Better definition of cdot using md. + * dvi/devdvi/eqnchar: Likewise. + * xditview/devX100/eqnchar: Likewise. + * xditview/devX75/eqnchar: Likewise. + * eqn/lex.c: Add definition of cdot. + +Thu Aug 16 09:33:57 1990 James Clark (jjc at yquem) + + * troff/input.c (get_optional_char): New function. + * troff/input.c (set_page_character): Use get_optional_char(), + rather than has_arg() and tok.get_char(1). + * troff/env.c (tab_character, leader_character, hyphen_char, + field_characters): Likewise. + (margin_character): Likewise. Also always delete the + margin_character_node. + + * troff/input.c (token::get_char): Use token::description. + + * troff/input.c (has_arg): Don't skip over tab and \}. + * troff/number.c (start_number): Give a warning if the number + starts with \} (WARN_RIGHT_BRACE) or tab (WARN_TAB). + +Wed Aug 15 10:04:37 1990 James Clark (jjc at yquem) + + * troff/input.c (empty_name_warning, non_empty_name_warning): New + functions. + (get_name, get_long_name): Use these. Rename `warn' argument to + `required'. + + * troff/node.c (get_fontno): Test that the symbol is not null. + + * troff/input.c (token::description): New function. + * troff/number.c (parse_term): Use token::description in `numeric + expression expected' message. + * troff/groff.h: Add WARN_MISSING. + * troff/number.c (start_number): New function. + * troff/number.c (get_vunits, get_hunits, get_number, get_integer, + get_incr_number): Use start_number(). + * troff/input.c (DEFAULT_WARNING_MASK): Enable WARN_NUMBER by + default. + * troff/input.c (get_name, get_long_name): Use WARN_MISSING. + * troff/reg.c (alter_format): Use WARN_MISSING. Also use + token::descripion. + * troff/input.c (token::get_char): Use WARN_MISSING. + * troff/input.c (token::delimiter): Use token::description. + * troff/env.c (environment_switch): Back out Aug 3 change. + * troff/input.c (has_arg): Skip over \}s and tabs but give a + warning. + * troff/token.h (token::tab): New function. + * troff/node.c (get_fontno): Use tok.skip() rather than has_arg(). + * troff/reg.c (alter_format): Likewise. + * troff/node.c (bold_font): Use has_arg() rather than tok.skip(). + +Tue Aug 14 10:11:21 1990 James Clark (jjc at yquem) + + * troff (most files): Redo warnings. Divide warnings into various + categories; warning() has an additional first argument indicating + the category it falls into. + * troff/input.c (main): -w now takes an argument. New option -W. + (enable_warning, disable_warning): New functions. + + * ps/devps/afmtodit: Add -a option to lie about the italic angle. + * ps/devps/FontMakefile: Pretend TI has an angle of 7. + +Mon Aug 13 10:11:16 1990 James Clark (jjc at yquem) + + * ps/devps/eqnchar: Better definitions of dotdot, vec, dyad, inf. + * xditview/devX100/eqnchar: Likewise. Remove definition of dot. + * xditview/devX75/eqnchar: Likewise. + * dvi/devdvi/eqnchar: Better definitions of vec, dyad, dotdot. + + * eqn/other.c: When bar or over applies to a single character + don't produce an overline_box or an underline_box. Instead produce + an accent_box or an underaccent_box, with the accent a line + whose width is accent_width. New classes underaccent_box, + overline_char_box and underline_char_box. + * eqn/box.h: Move overline_box, underline_box, accent_box class + declarations into eqn/other.c. Add declarations of + make_underline_box, make_overline_box, make_accent_box. + * eqn/eqn.y: Call make_overline_box, make_underline_box + make_accent_box instead of constructors. + * eqn/pbox.h, eqn/box.c: Add accent_width parameter. + + * eqn/other.c: Add accent_box::~accent_box. + * eqn/box.h: Declare it. + + * groff.sh: With -Tps, use eqn -D. + + * eqn/other.c (overline_box::output): Use \Z. If draw_flag use \D + rather than \l. + (underline_box::output): Similarly. + (accent_box::output): Use \Z. + + * xditview/tmac.X: Add definitions of ~ and ^ (so that they are a + bit smaller.) + +Sun Aug 12 09:41:15 1990 James Clark (jjc at yquem) + + * troff/div.c (top_level_diversion::transparent_output(unsigned + char)): Use asciify. + * troff/input.c (asciify): Don't make it static. + * troff/token.h (asciify): Declare it. + + * troff/input.c (get_name, get_long_name, token::get_char, + token::delimiter): Add an extra default argument which says + whether a warning should be printed. + * troff: Pass a non-zero argument to one of these rather than + printing a warning directly. + +Sat Aug 11 09:02:21 1990 James Clark (jjc at yquem) + + * troff: Consistently use symbol::is_null. + + * troff/dictionary.h: Move some inline functions into + dictionary.c. + + * troff/request.h: Move inline functions into input.c. + (request_or_macro::invoke): Make it pure. + + * troff/input.c, troff/reg.h: New class `constant_int_reg'. + * troff/input.c (init_input_requests): Use class constant_int_reg. + (class compatible_reg): Deleted. + * troff/div.c (init_div_requests): Use class constant_int_reg. + (class last_post_line_extra_space_reg): Deleted. + + * troff/env.c (tab_character): Don't change the tab character if + we get an invalid argument. + (hyphen_char): Similarly. + + * troff/reg.c (alter_format): Check that nm is not null. + + * Makefile, groff.sh: Make it possible to customize the commands + used for printing PostScript and dvi files. Also make it possible + to customize the path used by groff.sh. + + * eqn/eqn.y: Make `left' right associative. + +Fri Aug 10 18:20:39 1990 James Clark (jjc at yquem) + + * pic/pic.h: Added definition of M_SQRT2 for those systems that + don't have it. + + * pic/pic.h: Removed definition of INT_MAX. + + * troff/node.c (italic_corrected_node::vertical_extent): Omit + `return'. + + * troff/input.c (token::next): Handle \R like \n. + +Tue Aug 7 09:46:33 1990 James Clark (jjc at yquem) + + * ps/tmac.pc (PSPIC): Simplify. + + * troff/env.c (tab_stops::to_string): + * pic/pic.y (object_type_name): + * pic/troff.c (simple_output::line): + * pic/tex.c (tex_output::spline): + * pic/object.c (object_spec::make_object): + * tbl/main.c (process_data): Add cases to switch statements to + avoid cfront warnings. (Some of these are spurious, since the + switch already has a default case.) + + * ps/tmac.ps (PSPIC): Reformatted. Prefix all local names with + `ps-'. Don't test systat; instead check number of arguments to + ps-bb. + +Mon Aug 6 00:13:07 1990 James Clark (jjc at yquem) + + * macros/tmac.e: Do not decrease the page offset by 0.5i. + + * ps/ps.c (ps_printer::ps_printer): Use mktemp instead of tempnam. + Unlink the file as soon as we have opened it, so that we don't + have to bother with signal handlers. + (handler): Deleted. + (fatal_error_exit): Deleted. + (main): Don't call signal. + + * dvi/tfmtodit.c: Add -k option so that kerns with the skewchar + can be ignored. + * dvi/devdvi/Makefile: Use the -k option with S and MI. + + * pic/pic.y: If there is a label, or an nth construction before + the first `.' in the argument to `with', ignore it and generate a + warning. + * pic/lex.c (lex_warning): New function. + + * tbl/table.c (table::init_output): In section keep and release + macro, use 0 indent when diverting and the correct indent when + rereading. + + * troff/input.c (interpolate_number_format): Do not interpolate + anything if the number register is not defined. + + * tbl/main.c (process_data): Don't add entry when col >= ncolumns. + +Sat Aug 4 08:12:05 1990 James Clark (jjc at yquem) + + * ps/devps/prologue (PICTURE): Set components of graphics state to + their default values. + + * ps/devps/text.enc: Add trademark + * ps/devps/textmap: Add names for club, spade, heart, diamond, + carriagereturn, suchthat. Use Upsilon1 rather than Upsilon. + * ps/devps/symbolchars: Add names for summation and product. + + * dvi/devdvi/texsy.map: Add names for club, spade, heart, diamond, + suchthat. Add pp. Add upper-case letters. + + * xditview/libXdvi/DviChar.c: Add names for club, spade, heart, + diamond, carriagereturn, suchthat. Use Upsilon1 rather than + Upsilon. + + * dvi/devdvi/texsy.map: Rename lA (left angle bracket) to la, and + rA (right angle bracket) to ra. Introduce names for double-headed + arrows and double-barred arrows: <>, va, lA, rA, hA, uA, dA, vA. + * ps/devps/textmap: Likewise for ps device. + * xditview/libXdvi/DviChar.c: Likewise for X100 and X75 devices. + * tty/devascii/R.proto: Rename lA to la and rA to ra. + * tty/devascii/R.proto: Likewise. + * tty/tmac.tty: Provide definitions for \(<>, \(lA, \(rA, \(hA, + \(uA, \(dA. + * eqn/delim.c: In delim_table, rename \(lA to \(la and \(rA to \(ra. + + * xditview/tmac.X: Add definitions for \(fi \(fl \(ff \(Fi \(Fl. + + * eqn/lex.c: Added definitions of `approx', `grad' and `del' to + def_table. + +Fri Aug 3 09:59:27 1990 James Clark (jjc at yquem) + + * troff/div.c (when_request): Use symbol::is_null rather than + has_arg to determine whether we have an argument. + (change_trap): Remove the trap if we get an invalid number. Give + an error if we don't get at least the macro name. + (diversion_trap): Remove trap if we get an invalid name or number. + + * troff/env.c (environment_switch): Pop if we get an invalid + symbol or numeric expression. + + * troff/input.c (do_define_macro): If EOF is encountered while + defining the macro, do tok.next() before returning. + + * troff/token.h (has_arg): Move definition from here, to ... + * troff/input.c (has_arg): ... here + + * troff/env.c (space_size): Do nothing if we get an invalid argument. + * troff/input.c (shift): Likewise. + + * pic/lex.c (get_token_after_dot): Accept `.center' as a synonym + for `.c'. + + * pic/troff.c (troff_output::start_picture): Comment out calls to + `..'. + + * eqn/main.c (do_file): Subtract 1 from current_lineno if + interpret_lf_args succeeds. + + * eqn/main.c (do_file): Don't recognize delimiter if preceded by + \\. This avoids problems with \$N. + + * groff.sh: Pass -C to preprocessors. + + * lib/lf.c (interpret_lf_args): Be more flexible. + + * tbl/main.c (main): Add -C option. + (table_input::get): Do not recognize TE if followed by character + other than a space or newline unless -C option given. + (process_input_file): Likewise for lf, TS. + (process_data): Likewise for lf in text blocks. + + * eqn/main.c (main): Add -C option. + (do_file): Don't recognize EQ, EN or lf if followed by character + other than space or newline unless -C option given. + * eqn/lex.c (file_input::read_line): Similarly. + * eqn/eqn.h: Declare compatible_flag. + + * etc/soelim.c (main): Add -C option. + (interpret_lf_args): Use version in libgroff. + (do_file): + + * pic/main.c (main): Add -C option, which sets compatible_flag. + (top_input::get), (top_input::peek): If -C option not given, + do not recognize .PS/.PE/.PF/.lf if followed by a character + other than space or newline. + * pic/lex.c (file_input::read_line): Similarly. + * pic/pic.h: Add declaration of compatible_flag. + +Thu Aug 2 11:11:27 1990 James Clark (jjc at yquem) + + * ps/tmac.ps (PSPIC): Avoid use of `echo -n'. + + * troff/node.c, troff/node.h: Add `asciify' methods to classes + derived from node. New class space_char_hmotion_node. + * troff/input.c (asciify_macro): New function. + * troff/input.c (init_input_requests): New request `asciify' bound + to asciify_macro. + * macros/mm.diff: New file. + * Makefile: In install.mm target use `patch' to apply + macros/mm.diff. + + * troff/input.c (macro::print_size): Just print the size in bytes. + + * troff/div.c (return_request): Correct the argument + interpretation. + +Wed Aug 1 12:38:36 1990 James Clark (jjc at yquem) + + * troff/node.h (class composite_node): Add sz member. + * troff/node.c (composite_node::size): Return sz. + * troff/input.c (macro_to_node): Use the initial size in the + environment as the size of the composite_node. + + * troff/node.c (node::zero_width_tprint): Provide a reasonable + default. + +Tue Jul 31 10:07:10 1990 James Clark (jjc at yquem) + + * troff/div.c (change_trap): If we get a bad number expression, + do nothing. + +Mon Jul 30 10:30:49 1990 James Clark (jjc at yquem) + + * lib/matherr.c (matherr): Define this only if math.h defines + TLOSS. + +Sun Jul 29 10:34:27 1990 James Clark (jjc at yquem) + + * troff/div.c (macro_diversion::distance_to_next_trap): If there + no diversion trap return vunits(INT_MAX - vresolution). + +Sat Jul 28 14:28:14 1990 James Clark (jjc at yquem) + + * troff/input.c (do_zero_width): New implementation that doesn't + use a temporary environment. Use instead: + (token::add_to_node_list): New function. + * troff/env.c (environment::get_prev_char_height), + (environment::get_prev_char_height), + (environment::get_prev_char_skew): New functions. + (environment::get_prev_char): New function. + (environment::get_prev_char_width): Change to use get_prev_char. + (init_env_request): Implement new registers .cht, .cdp, .csk. + * eqn/sqrt.c (sqrt_box::output): Don't rely upon the argument to + \Z being processed in a separate environment. + +Fri Jul 27 10:21:25 1990 James Clark (jjc at yquem) + + * tbl/table.c: Removed TABLE_BOTTOM_REG. + + * tbl/table.c (table::init_output): In the section release macro, + give a warning message if the section won't fit on one page. + + * tbl/table.c (table::do_top): Emit table keep only if table is + boxed. + (table::do_bottom): Likewise for table release. + (table::table), (table::add_vertical_rule): Remove reference to + keep member. + * tbl/table.h: Remove keep member. + + * tbl/table.c: New register SUPPRESS_BOTTOM_REG. In + SECTION_RELEASE_MACRO, if there's not enough space before the next + trap to output the diversion, call T# ourselves, set + SUPPRESS_BOTTOM_REG to 1, spring the trap, then set + SUPPRESS_BOTTOM_REG back to 0. In T#, do nothing if + SUPPRESS_BOTTOM_REG is non-zero. In T#, always mark the current + vertical position and return to it before turning traps on again. + +Thu Jul 26 02:54:32 1990 James Clark (jjc at yquem) + + * troff/node.c, troff/node.h: In classes derived from node, + replace prev_char_width method by last_char_node method. + * troff/env.c (environment::get_prev_char_width): Use + node::last_char_node rather than node::get_prev_char_width. + + * Makefile: Added comment about -fno-inline on 68030-based + Apollos. + + * troff/reg.c (number_format_to_ascii), eqn/delim.c (DELIM_TABLE_SIZE), + tty/tty.c (tty_font::load_tty_font), dvi/tfmtodit.c (main): Cast + expressions using sizeof to int. + * dvi/dvi.c (dvi_font::handle_x_command): Avoid long->int warnings. + + * macros/tmac.e (TS): Don't move @f back past the current + position. + +Wed Jul 25 09:11:08 1990 James Clark (jjc at yquem) + + * ps/ps.c (main): Buffer stderr. + * dvi/dvi.c (main): Likewise. + * tty/tty.c (main): Likewise. + + * ps/ps.c (ps_printer::do_import): Improve error handling. + + * troff/input.c (abort_request): Use asciify. + + * driver/printer.h (printer::draw), driver/printer.c (printer::draw), + ps/ps.c (ps_printer::draw), dvi/dvi.c (dvi_printer::draw): Make + type of first argument int rather than char. This works around a + bug on the 68030 based Apollo using g++ 1.37.1. + + * tbl/table.h (class table): Add `keep' member. + * tbl/table.c (table::table): Initialize `keep'. + (table::add_vertical_rule): Set `keep' to 1. + (table::do_top): Only emit table keep macro is `keep' is non-zero. + (table::do_bottom): Likewise for table release macro. + (table::do_row): Emit section keep macro even if the row is 0. + +Tue Jul 24 08:35:07 1990 James Clark (jjc at yquem) + + * macros/tmac.e (@C): Preserve the font family across the change + in environments. + +Mon Jul 23 10:15:23 1990 James Clark (jjc at yquem) + + * lib/font.c: Initialize font::hor and font::vert to 1. + (font::load_desc): Check the values of font::hor and font::vert. + + * lib/lib.h: Added definition of INT_DIGITS. Fix it so that it can + be included in a C compilation. + (iftoa): Use INT_DIGITS. Include lib.h. + (itoa): Likewise. + (as_string): Likewise. + * tbl/table.c: Removed definition of INT_DIGITS. + * eqn/box.c (box::top_level): Use INT_DIGITS + 1 instead of 12. + * troff/input.c (input_input_requests): Likewise. + * ps/ps.c (make_encoding_name): Likewise. + (ps_printer::set_style): Likewise. + (ps_output::put_number): Use 1 + INT_DIGITS + 1 instead of 12. + + * tty/devascii/R.proto: Map fm onto '. + * tty/devlatin1/R.proto: Likewise. + +Sat Jul 21 12:45:07 1990 James Clark (jjc at yquem) + + * tbl/table.c: Use ' instead of DELIMITER_CHAR in places where the + argument to \w is at a different input level. + + * tbl/table.c (table::init_output): Define a new macro + REPEATED_VPT_MACRO, like vpt but if in a diversion also + transparently outputs itself. + (table::define_bottom_macro): Use REPEATED_VPT_MACRO instead of + vpt. + (table::do_row): Likewise. + + * tbl/table.c (vertical_rule::print): Prefix the .sp -1 line with + TRANSPARENT_STRING_NAME. + + * tbl/table.c (table::init_output): In the table release macro + print an error message and don't produce any output if after + issuing the need request the table still will not fit. Also + remove the diversion after bringing it back. + + * tbl/table.c (table::init_output): Define a new macro + REPEATED_MARK_MACRO, like mk but if in a diversion also + transparently outputs itself. + (table::do_row): Mark row_top_reg using REPEATED_MARK_MACRO. This + is necessary because .TH might not call .T#. + (table::do_top): Likewise TOP_REG. + (table::define_bottom_macro): If TOP_REG is no longer valid, use + #T - DOUBLE_LINE_SEP rather than #T. This is necessary because the + table header might contain just the two top rules. + +Fri Jul 20 10:51:42 1990 James Clark (jjc at yquem) + + * troff/div.c: Implement new request `ptr' to print all traps. + + * troff/env.c (init_env_requests): Implement `.tabs' reg with + init_string_env_reg. + * troff/env.c (class tab_reg): Deleted. + +Thu Jul 19 12:07:16 1990 James Clark (jjc at yquem) + + * troff/div.c: New number register .pn returns the number of the + next page as set by the pn request. + + * macros/tmac.an: Redid headers and footers. Number each manual + entry starting from 1 unless \nC is > 0, like Sun. Added an + optional 5th argument to .TH which specifies the manual name and + appears in the center of the header. Understand the X, P and D + registers like Sun. + +Wed Jul 18 10:23:31 1990 James Clark (jjc at yquem) + + * troff/env.c (init_env_requests): New number register `.lt' to + return the title length. + + * troff/node.h (class transparent_dummy_node): New class. + * troff/node.c (class transparent_dummy_node): Provide member + functions. + * troff/env.c (interrupt): Add a transparent_dummy_node, rather + than a dummy_node. + + * troff/input.c (token::next): New escape sequence \). + * troff/input.c (get_copy): Recognize \) in copy mode. + + * troff/input.c (input_stack::clear): New function. + * troff/input.c (exit_request): Use input_stack::clear. + + * troff/token.h: Removed TOKEN_NO_PRINT_CHAR. + * troff/input.c (token::process): Removed case TOKEN_NO_PRINT_CHAR. + + * troff/env.c: Move set_page_character to input.c. Move + page_character to input.c also. + * troff/env.c (title): Split off the reading of the parts of the + title into read_title_parts. + * troff/input.c (read_title_parts): New function. Check the + input_level when testing whether a token matches the delimiter. + + * troff/input.c (exit_request): New function. + * troff/input.c (init_input_requests): Bind ex request to + exit_request rather than exit_groff. + + * troff/input.c (exit_groff): Call tok.next() before + process_input_stack(). + +Mon Jul 16 09:47:23 1990 James Clark (jjc at yquem) + + * troff/env.c: ifdef widow control support on WIDOW_CONTROL. + * troff/env.h: ditto. + * troff/input.c: ditto. + + * troff/env.c (environment::is_empty): Test pending_lines. + + * troff/env.c (environment::have_pending_lines): Removed. + + * troff/input.c: Add request to flush pending lines from the + environment. + + * troff/env.c, troff/env.h: Add automatic widow control feature. + + * troff/input.c (exit_groff): Do process_input_stack() after + do_break() but before setting exit_flag to 2. + + * troff/input.c: Remove FLUSH_PENDING_LINES and + TOKEN_FLUSH_PENDING_LINES. Instead, flush pending lines from + environment after END_TRAP token seen, but only if there aren't + any more traps still unfinished. + * troff/token.h: Remove TOKEN_FLUSH_PENDING_LINES. + +Sun Jul 15 10:50:08 1990 James Clark (jjc at yquem) + + * troff/env.c: Rename the `retain_size' member of class + pending_output_line to `no_fill'. + + * troff/env.c (title): When the line is output, make the + retain_size argument !fill. + + * troff/node.h: Add `hyphenated' member to struct breakpoint. + * troff/node.c (space_node::get_breakpoints), + (dbreak_node::get_breakpoints): Fill this in. + * troff/env.c: Allow specification of maximum number of + consecutive hyphenated lines. + + * troff/env.c (environment::is_empty): Add test for !current_tab. + +Sat Jul 14 11:23:01 1990 James Clark (jjc at yquem) + + * troff/env.c (environment::hyphenate_line): Don't completely give + up if the word is not to be hyphenated; continue so that breaks + can be made at break_char_node's. + + * lib/lib.h: Only define INT_MAX if it's not already defined; + undef INT_MIN if it's already defined. + + * Makefile: Make it easy to define CFRONT_ANSI_BUG. + + * lib/lib.h: If CFRONT_ANSI_BUG is defined, cast INT_MIN to long. + This works around a bug in AT&T C++ 2.0 used with an ANSI C + compiler. + + * macros/tmac.an (an-header): Set no-space mode. + + * macros/tmac.an (TH): Start a new page if necessary. + + * Started using ChangeLog at version 0.4. + +Copyright 1990-1999 Free Software Foundation, Inc. + +Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. + +Local Variables: +fill-column: 72 +mode: change-log +version-control: never +End: +vim:set autoindent textwidth=72: diff --git a/ChangeLog.116 b/ChangeLog.116 new file mode 100644 index 0000000..85f26b7 --- /dev/null +++ b/ChangeLog.116 @@ -0,0 +1,1397 @@ + +Version 1.16.1 released +======================= + +2000-07-31 Werner LEMBERG + + Preparing release 1.16.1. + + * REVISION: Revision number set to 1. + * MORE.STUFF: Added info about port to DOS. + * NEWS, win32-diffs: Updated. + + * src/include/nonposix.h: Remove first line -- this file is used + in C also. + + * Makefile.in (dist): Delete Imakefile earlier to avoid a soft + link to it. + +2000-07-30 Werner LEMBERG + + * doc/texinfo.tex: Update to latest version. + +2000-06-28 Paul Eggert + + * Makefile.in (ENVSETUP): Don't assume POSIX make semantics for + commands that fail. Don't assume that "export a=b" is valid shell + syntax. This is needed for Solaris 2.5.1. + + * src/libs/libgroff/tmpfile.cc, src/utils/indxbib/indxbib.cc: Fix + comment about missing Solaris headers. + + * PROBLEMS: Add section about problems with Sun Make and VPATH. + +2000-06-25 Werner LEMBERG + + * src/devics/grodvi/dvi.cc: Replace _setmode() (for MSC) with + SET_BINARY(). + + * src/include/posix.h: Use HAVE_UNISTD instead of _MSC_VER. + + * win32-diffs: Updated. + * README.WIN32: Added CRs to make all Windows editors happy. + + * src/roff/troff/node.cc: Added WIFSIGNALED() macro (copied from + src/roff/groff/pipeline.c). + +2000-06-23 Eli Zaretskii + + * src/roff/grog/Makefile.sub (grog): Prepend `-e' to + $(SH_SCRIPT_SED_CMD), for the case where its value is empty. + +2000-06-17 Eli Zaretskii + + * src/utils/tfmtodit/tfmtodit.cc: #include nonposix.h. + (tfm::load, gf::load): Open tfm and gf files in binary mode: these + are binary files. + (main): Support non-Posix systems with several different styles of + slash characters in file names. + + * src/utils/pfbtops/pfbtops.c: #include nonposix.h. + (main) [SET_BINARY]: Switch stdin into binary mode. + + * src/utils/indxbib/indxbib.cc: #include nonposix.h. + (main): Support file names with several possible slash-type + characters, as given by DIR_SEPS[] in nonposix.h. + (main) [__MSDOS__]: If renaming the temporary index file fails + because it has more than one dot in its trunk, replace the dot + with an underscore and try again. + (do_file): Use FOPEN_RB instead of "r". Skip every CR before a + Newline. + [__MSDOS__ || _MSC_VER]: Stop at the first ^Z character. + + * src/utils/hpftodit/hpftodit.cc: #include nonposix.h. + (File::File): Open the input file in binary mode. Strip CR + characters from each CR-LF pair. + (xbasename): Support file names with several possible slash-type + characters, as given by DIR_SEPS[] in nonposix.h. + + * src/include/Makefile.sub (HDRS): Add nonposix.h. + + * src/roff/troff/node.cc [HAVE_UNISTD_H]: Include . + (WIFEXITED, WEXITSTATUS, WTERMSIG, WIFSTOPPED, WSTOPSIG) + [!_POSIX_VERSION]: Define for traditional Unix systems. + (real_output_file::real_output_file): Remove the MSVC-specific + call to popen, use instead POPEN_WT, appropriately defined on + nonposix.h. #include nonposix.h. + (real_output_file::~real_output_file): Remove the MSVC-specific + call to pclose, a suitable macro is now defined on nonposix.h. + Use the portable macros WIFEXITED, WIFSIGNALED, WTERMSIG, WSTOPSIG + and WEXITSTATUS instead of assuming traditional Unix + interpretation of the status returned by pclose. + + * src/roff/troff/input.cc (pipe_source): Remove the MSVC-specific + call to popen, use POPEN_RT instead (appropriately defined on + nonposix.h). #include nonposix.h. + (ps_bbox_request): Open the PostScript file in binary mode. + Close the file after processing it. + (getpid) [_MSC_VER]: Remove; a suitable macro is now defined on + nonposix.h. + + * src/roff/groff/pipeline.c (run_pipeline) [__MSDOS__ || _WIN32]: + A version of run_pipeline that doesn't use `fork'. + (signal_catcher) [__MSDOS__ || _WIN32]: New function. + (system_shell_name, system_shell_dash_c) + (is_system_shell) [__MSDOS__ || _WIN32]: New functions, to hide + the ugliness of testing DOS/Windows file names for equality, and + support both stock shells and ports of Unix shells. + + * src/roff/groff/groff.cc: #include nonposix.h. + (BSHELL): Definition moved to nonposix.h. + (main): Use PATH_SEP[0] instead of literal ':'. Use BSHELL_DASH_C + instead of a literal "-c". + (xbasename): Support file names with several possible slash-type + characters, as given by DIR_SEPS[] in nonposix.h. + (possible_command::print): Use BSHELL_DASH_C and IS_BSHELL instead + of literal strings. + + * src/preproc/soelim/soelim.cc: #include nonposix.h. + (do_file): Use IS_ABSOLUTE instead of testing for a literal '/'. + + * src/preproc/pic/Makefile.sub (YTABH): Change pic.tab.h to + pic_tab.h. + + * src/preproc/pic/lex.cc: Change pic.tab.h to pic_tab.h. + + * src/preproc/eqn/Makefile.sub (YTABH): Rename eqn.tab.h to + eqn_tab.h. + + * src/preproc/eqn/lex.cc: #include eqn_tab.h, not eqn.tab.h. + + * src/libs/libgroff/tmpfile.cc (DEFAULT_TMPDIR) [P_tmpdir]: If + P_tmpdir is defined, use it instead of the literal "/tmp". + (remove_tmp_files, add_tmp_file): New functions. + (xtmpfile): Record temporary files and register an atexit function + to delete them explicitly, instead of relying on the OS to do + that, which doesn't work on non-Unix systems. + + * src/libs/libgroff/searchpath.cc: #include nonposix.h. + (search_path::search_path): Use PATH_SEP instead of a literal + colon. + (search_path::command_line_dir): Ditto. + (search_path::open_file): Use IS_ABSOLUTE, PATH_SEP and DIR_SEPS, + to support non-Posix systems. + + * src/libs/libbib/search.cc: #include nonposix.h. + (search_list::add_file): Open the file in binary mode. + + * src/libs/libbib/linear.cc: #include nonposix.h. + (file_buffer::load): Remove \r characters preceding \n from the + loaded buffer. + + * src/libs/libbib/index.cc: #include nonposix.h. + (make_index_search_item): Open index_filename in O_BINARY mode. + (index_search_item_iterator::get_tag): Ditto. Remove \r + characters before \n characters. + (index_search_item::check_files): Open files in binary mode. + (index_search_item::munge_filename): Support DOS-style file names + with backslashes and drive letters, use IS_ABSOLUTE. + + * src/devices/grops/ps.cc: #include nonposix.h. + (main) [SET_BINARY]: Switch stdout to binary mode. + + * src/devices/grolj4/lj4.cc: #include nonposix.h. + (main) [SET_BINARY]: Switch stdout to binary mode. + + * src/devices/grolbp/lbp.cc: #include nonposix.h + (fill_pattern) [SET_BINARY]: Switch stdout to binary mode. + + * src/devices/grodvi/dvi.cc: #include nonposix.h. + [_MSC_VER]: Remove inclusion of Windows-specific headers (done by + nonposix.h). + (main) [SET_BINARY]: Switch stdout to binary mode. + [_MSC_VER]: Remove an explicit call to _setmode. + + * src/include/nonposix.h: New file. + + * Makefile.in (ENVSETUP): New variable, to set up case-sensitive + operation when building with DJGPP. + ($(TARGETS), dot, $(LIBDIRS), $(CPROGDIRS), $(CCPROGDIRS)) + ($(DEVDIRS), $(TTYDEVDIRS), $(INCDIRS), $(OTHERDIRS)): Use + ENVSETUP. + + * Makefile.comm: mv y.tab.[ch] to y_tab.[ch], to make it work on + MS-DOS. + (.man.n): Replace `;' with `|', since FONTPATH, MACROPATH, + etc. can include a semi-colon on DOS/Windows. + (depend.temp): Use depend1.temp instead of depend.temp1, to + prevent files from overerwiting each other on 8+3 filesystems. + + * gendef.sh (t): Change definition to work with DOS/Windows. + + doc/groff.texinfo: Apart of some typo corrections, I also changed + some index entris, to make them more non-ambiguous, and also put + @ignore around some parts that are not yet written, to allow the + Info output be readable. + +2000-06-10 Gael Queri + + Replaced specific checks for function declarations with a generic + routine taken from GNU bfd. + + * aclocal.m4 (GROFF_NEED_DECLARATION): New function. + GROFF_PUTENV, GROFF_POPEN, GROFF_PCLOSE, GROFF_HYPOT: Removed. + * configure.in: Use it. + * src/devices/grolbp/lbp.cc, src/include/lib.h, + src/preproc/grn/hgraph.cc, src/preproc/pic/pic.h, + src/roff/groff/groff.cc: Use it. + * Makefile.in, configure: Updated. + +2000-06-07 Paco Andrés Verdú + + * src/devices/grolbp/lbp.h: Removed unused variables. + +2000-05-31 Keith Thompson + + * src/devices/grolbp/lbp.cc (set_papersizes): Add declaration of + strncasecmp(). + +2000-05-31 Werner LEMBERG + + * aclocal.m4 (GROFF_SRAND): New function to test the return value + of srand() -- at least SunOS 4.1.3 uses `int' instead of `void'. + * configure.in: Use it. + * src/preproc/pic/pic.y, src/preproc/pic/pic.cc: Use it. + * configure, Makefile.in: Updated. + + * configure.in: Add test for strncasecmp(). + * src/include/lib.h: Use it. + +2000-05-29 Andrej Borsenkow + + * src/preproc/grn/Makefile.sub: Add MLIB. + +2000-05-29 Nix + + * Makefile.in: Use @datadir@ and @mandir@ appropriately. + +2000-05-29 Werner LEMBERG + + * src/roff/grog/Makefile.sub, src/roff/grog/grog.sh: Add `@g@'. + + * PROBLEMS: Small update. + + * src/devices/grolbp/lbp.cc: Various small fixes. + +2000-05-28 Keith Thompson + + * src/roff/nroff/nroff.sh: Fix main loop syntax. + + * src/utils/indxbib/indxbib.cc: Add declaration of mkstemp(). + +2000-05-25 Werner LEMBERG + + * man/roff.man: Removed unused macro. + +2000-05-24 Werner LEMBERG + + * Makefile.in (dist): Remove src/xditview/Imakefile explicitly. + This is needed e.g. if you do + `make distclean; ./configure; make dist'. + +Version 1.16 released +===================== + +2000-05-23 Werner LEMBERG + + Adding font CWI (constant width italic) to devdvi. + + * font/devdvi/CWI: New file. + * font/devdvi/generate/Makefile: Add generating rule. + * font/devdvi/DESC.in, font/devdvi/Makefile.sub, win32-diffs, + tmac/tmac.dvi: Use it. + * NEWS: Announce it. + + * font/devlj4/*: Regenerated (only adding kernings for `cq' glyph). + * font/devlj4/generate/Makefile: Cosmetic changes only. + + * man/groff.man: Removed most of the redundant description of + special characters (which is in groff_char.man). Added font + translation CB->CR for devdvi. Other minor fixes. + + * tmac/tmac.dvi: Improved appearance of \(co (copyright) and \(rg + (registered) symbols. + +2000-05-22 Werner LEMBERG + + * doc/Makefile: Added rule for creating info files. + + * font/devdvi/*: Added kernings for `cq' glyph. Updated to latest + AMS font metrics. + * font/devdvi/generate/Makefile: Fixed dependencies. + + * font/devps/*: Regenerated. Heavy changes for Bookman and + NewCentury Schoolbook! + * font/devps/generate/afmname: Will now run with GNU awk. + * font/devps/generate/textmap: Added forgotten `cq' glyph name. + * font/devps/generate/Makefile: Cosmetic changes only. + +2000-05-21 Werner LEMBERG + + * tmac/tmac.an: Added a new command line option `-rSxx' (`xx' can be + 10, 11, or 12) to support output with 11pt and 12pt base font sizes. + `.SS' now produces a heading with a smaller size than `.SH'. + Completely formatted. + * doc/groff.texinfo, tmac/groff_man.man, NEWS: Document it. + + * man/groff.man: Improved table appearance. Use of `eo' request + to reduce number of doubled backslashes in macro definitions. + Replacing `\e' with `\(rs'. Other minor fixes. + + * src/preproc/tbl/main.cc: Insert HTML table end tag before `lf' + to have correct line number. + + * INSTALL: Small improvement. + +2000-05-20 Bernd Warken + + * man/roff.man, tmac/groff_tmac.man: Updates (with corrections by + WL). + +2000-05-19 Bernd Warken + + * man/groff.man: Complete update (with a lot of corrections by WL). + +2000-05-18 Werner LEMBERG + + Adding `cq' (PS name `quoteright') glyph name as an alias for "'". + + * font/*/*: Implement it. + * man/groff_char.man, NEWS: Document it. + + * src/include/unix.h: Removed. It isn't used. + + * doc/groff.texinfo: Slight improvements. + +2000-05-17 Werner LEMBERG + + * README, win32-diffs: Small fixes and improvements. + +2000-05-16 Werner LEMBERG + + * FDL: New file (the Free Documentation License version 1.1). + + * doc/groff.texinfo: Added many start-up values for gtroff. + Some structural improvements of the source code. + +2000-05-15 Werner LEMBERG + + * src/roff/troff/input.cc: Added small comment about troffrc-end. + * src/roff/troff/troff.man: Added info about troffrc-end. + +2000-05-14 Werner LEMBERG + + * Makefile.in (EXTRADIRS): Fix typos. + (dist): Handle deletion of old .tar.gz file correctly. + (DISTDIRS): Include all tty output devices. + + * doc/groff.texinfo: Adding more cross references; countless other + fixes. + +2000-05-13 Werner LEMBERG + + * MORE.STUFF: Added Robert Marks's utilities. + +2000-05-12 Werner LEMBERG + + Added win32 port contributed by Blake McBride + . + + * README.WIN32, win32-diffs: New files. + * NEWS: Updated. + + * src/preproc/grn/hgraph.cc (HGSetBrush): Replace `%lf' with `%f'. + (tmove, tmove2): Added parentheses to avoid compiler warnings. + (change): Removed unused variables. + + * src/preproc/grn/main.cc (main, conv): Removed unused variables. + (savebounds): Changed return value from `int' to `void'. + * src/preproc/grn/hdb.cc: Ditto. + + * src/devices/grolbp/lbp.cc (lbp_printer::draw): Removed superfluous + final backslash in comment to avoid compiler warning. + + * src/utils/pfbtops/pfbtops.c: Added `getopt.h'. + + * doc/groff.texinfo: More fixes. + +2000-05-11 OKAZAKI Tetsurou + + * tmac/tmac.doc: Documentation fix. + +2000-05-11 Werner LEMBERG + + * doc/groff.texinfo: Reading the source code shows up a lot of + omissions and incorrect data... More conversion to @Deffn macros. + +2000-05-10 Werner LEMBERG + + * src/roff/troff/reg.cc (number_value_to_ascii): Remove ASCII + dependency. + + * src/roff/troff/request.h: Removing unused `no_break_flag'. + +2000-05-09 Werner LEMBERG + + * man/groff.man, man/roff.man, tmac/groff_tmac.man: Minor + improvements. + + * doc/groff.texinfo: Extended history section. More conversion to + @Deffn macros. More .tr documentation. + +2000-05-07 Werner LEMBERG + + * doc/groff.texinfo: Completed tab section. Added info about + fields. + +2000-05-06 Mike MacIsaac + + * PROBLEMS: Describe configure script fix for OS/390 Unix. + +2000-05-05 Werner LEMBERG + + * font/devdvi/DESC.in: Change size 11pt to 10.95pt (as used in + LaTeX 2e). + * NEWS: Document it. + + * man/troff.man: Minor optical improvements. + +2000-05-03 Werner LEMBERG + + Adding `dq' (PS name `quotedbl') glyph name as an alias for `"'. + + * font/*/*: Implement it. + * man/groff_char.man, NEWS: Document it. + +2000-05-02 Werner LEMBERG + + * tmac/groff_tmac.man, man/groff.man, man/roff.man: Fixing @MANxEXT@ + expansion. + * NEWS: Document the three new man pages. + + * aclocal.m4 (GROFF_CXX_CHECK): Removing obsolete AC_C_CROSS call. + * configure: Updated. + + * font/devcp1047/R.proto: Fixing fatal bug (a missing `"' character). + +2000-05-01 Werner LEMBERG + + Added grap support to grog. + + * src/roff/grog/grog.sh, src/roff/grog/grog.pl: Implement it. + * src/roff/grog/grog.man: Document it. + + * doc/groff.texinfo, NEWS: Add info about grap support. + + Add new man pages comptributed by Bernd Warken + (with slight fixes by me). + + * tmac/groff_tmac.man: New file documenting tmac mechanism. + * tmac/Makefile.sub: Add groff_tmac.man. + * man/roff.man: New file giving overview of roff system. + * man/troff.man: A short reference of troff. + * man/Makefile.sub: Add roff.man and troff.man. + +2000-04-30 Werner LEMBERG + + Added grap support to groff. + + * src/roff/groff/groff.cc: Implement it. + * src/roff/groff/groff.man: Document it. + + * src/devices/grotty/grotty.man: Add cp1047 device. + * src/preproc/eqn/eqn.man, src/preproc/eqn/neqn.sh, tmac/eqnrc: + Ditto. + * src/roff/groff/groff.man: Ditto. + * src/roff/nroff/nroff.sh, src/roff/nroff/nroff.man: Ditto. + * doc/groff.texinfo: Ditto. + + * tmac/troffrc: Fix mapping of latin-1 char 160 (non-breakable space) + for cp1047. + +2000-04-29 Werner LEMBERG + + * man/groff_char.man: Add `pc' glyph. + * tmac/tmac.latin1: Replacing `md' glyph with `pc'. + * tmac/tmac.tty: Add `pc' glyph. + * tmac/tmac.tty-char: Use/add `pc' glyph. Don't call tmac.latin1 if + we use cp1047 output device. + + * Makefile.in, aclocal.m4: Don't build utf8 on EBCDIC hosts since + there are still hardcoded latin1->unicode values in utf8's font + definition files. + * configure: Updated. + * NEWS: Minor clarification. Updated. + + * PROBLEMS: Formatted. Added info about C++ fix pack for OS/390 + Unix. + +2000-04-28 Werner LEMBERG + + Adding EBCDIC code page 1047. + + * font/devcp1047/R.proto, font/devcp1047/Makefile.sub, + font/devcp1047/DESC.proto: New files. + + * aclocal.m4 (GROFF_EBCDIC): Introduce TTYDEVDIRS which can be + either ascii/latin1 or cp1047. + * Makefile.in: Use it. + * configure: Updated. + + Replacing and/or adding `md' (mathdot) glyph with `pc' + (periodcentered) in all text fonts. + + * font/*/*: Change it. + +2000-04-27 Werner LEMBERG + + * aclocal.m4 (GROFF_OS390): Fixing compiler flags. + + * configure.in: Add check for strings.h. + * src/include/driver.h: Use HAVE_STRINGS_H. + * src/devices/grolbp/lpb.cc: Remove string.h. + + * src/include/groff-getopt.h: New file. It will be used instead of + getopt.h (to be included in lib.h) to avoid endless problems with + picky C++ compilers. + * src/include/lib.h: Use groff-getopt.h. + * src/include/Makefile.sub: Updated. + + * configure: Updated. + * Makefile.in: Updated. + + * NEWS: Mention EBCDIC support. + +2000-04-26 Werner LEMBERG + + * TODO: Some additions. + +2000-04-25 Werner LEMBERG + + * src/roff/troff/troff.man, doc/groff.texinfo: Fixing documentation + of mso request. + +2000-04-23 Werner LEMBERG + + * src/roff/troff/troff.man: Minor fixes. + +2000-04-22 Werner LEMBERG + + * src/roff/troff/troff.man, doc/groff.texinfo, NEWS: Document the + `.T' string register and the incompatible definition of the `.T' + number register (compared to Unix troff). + + * man/groff_char.man: Add some missing characters. + * font/devutf8/NOTES: Update. + +2000-04-21 Werner LEMBERG + + * src/include/htmlindicate.h, src/include/lib.h, + src/include/posix.h: Fix copyright. + + * src/include/Makefile.sub: Update. + +2000-04-20 Werner LEMBERG + + * src/roff/troff/input.cc (input_char_description): Removing + superfluous space char. + + * tmac/tmac.X: Fix typo \(bq -> \(Bq. + + * doc/groff.texinfo: Document EBCDIC. + +2000-04-19 Werner LEMBERG + + Introducing `shc' as the glyph name for the soft hyphen character. + + * tmac/tmac.tty, tmac/tmac.latin1, tmac/tmac.html, + font/devlatin1/R.proto: Use it. + + * NEWS: Updated. + +2000-04-18 Werner LEMBERG + + * src/devices/grops/ps.cc (ps_printer::flush_sbuf): Removing + dependency on ASCII order. + +2000-04-16 Sandor BARANY + + * src/libs/libgroff/illegal.c: Added EBCDIC table. + * src/roff/troff/input.cc: Added adaptation to EBCDIC. + + * src/preproc/refer/refer.cc, src/roff/troff/env.cc: Minor changes + to increase portability. + +2000-04-15 Werner LEMBERG + + * aclocal.m4: Added GROFF_EBCDIC and GROFF_OS390 tests. + Redefined AC_OUTPUT_MAKE_DEFS to replace ASCII character `012' with + the generic `\n' if under OS/390 Unix. + + * configure.in: Call GROFF_EBCDIC and GROFF_OS390. + + * configure: Regenerated. + +2000-04-14 Werner LEMBERG + + * doc/groff.texinfo: More conversions to @Deffn. + +2000-04-12 Werner LEMBERG + + * tmac/tmac.psfig: Fix incorrect use of `&' operator by replacing it + with `:'. + + * src/roff/nroff/nroff.man: Add note about tmac.tty-char. + +2000-04-10 Werner LEMBERG + + * doc/groff.texinfo: More conversions to @Deffn. + +2000-04-08 Werner LEMBERG + + * src/libs/libgroff/{getopt.c,getopt1.c}, src/include/getopt.h: + Updated to latest version (glibc 2.1.3). + +2000-04-07 Werner LEMBERG + + * doc/Makefile (clean): Include more index files. + Add rule texinfo->dvi. + +2000-04-05 Werner LEMBERG + + * doc/groff.texinfo: Added new index `op' for operators. More + info on end of sentence characters. More use of @Deffn. + +2000-03-30 Werner LEMBERG + + * */*.man: Adding a note that a whitespace can be inserted between + a command line option and its parameter -- we are using GNU getopt. + + * src/roff/groff/groff.man: Add example of `-m mandoc'. + +2000-03-28 Werner LEMBERG + + Correct anachronism of calling the man macro file with `-man' + instead of `-m man' etc. + + * tmac/tmac.man, tmac/tmac.mandoc, tmac/tmac.markup, tmac/tmac.mdoc, + tmac/tmac.me, tmac/tmac.ms: New files tmac.m which simply + load tmac.. + + * tmac/Makefile.sub: Updated. Take care of $(tmac_an_prefix) etc. + + * NEWS: Updated. + + * doc/groff.texinfo: Updated. + + * tmac/groff_man.man: Copyright added. + +2000-03-27 Werner LEMBERG + + * doc/groff.texinfo: Introducing macros `Deffn' and `Defmac' to + typeset the request resp. escape name with a tt font -- due to a + bug in texinfo.tex it is necessary to use the `-e' switch with + texi2dvi. + + Improving info about usage of groff units. + + Other minor fixes. + +2000-03-20 Werner LEMBERG + + * doc/groff.texinfo: Added section about man macro package + (I've basically taken groff_man.man). Introducing new indices `ma' + for macros/strings and `gl' for glyph names. Other minor fixes. + + * tmac/groff_man.man: Fixed some typos. + +2000-03-19 Werner LEMBERG + + * doc/groff.texinfo: Removed all occurrences of `you', `we', etc. + Other minor fixes. + + * doc/texinfo.tex: New file. + +2000-03-18 Werner LEMBERG + + * doc/groff.texinfo: Improved section on number registers. Other + minor updates. + +2000-03-16 Werner LEMBERG + + * src/roff/groff/groff.man: Added info about grolbp. Make nicer + synopsis. + + * src/devices/grolbp/grolbp.man, src/roff/nroff/nroff.man, + src/devices/grolj4/grlj4.man, src/devices/grops/grops.man, + src/preproc/eqn/eqn.man, src/utils/afmtodit/afmtodit.man, + src/utils/tfmtodit/tfmtodit.man: Make nicer synopsis. + + * src/preproc/grn/grn.man: Better synopsis; added copyright. + + * src/roff/grog/grog.man: Updated copyright date. + +2000-03-14 Francisco Andrés Verdú + + * configure.in: Added test for strdup. + + * src/devices/grolbp/lbp.cc: Added a strdup() version in case none + is available. + + Replaced dynamic allocation of arrays `[...]' with `new' operator. + + Other minor fixes. + +2000-03-12 OKAZAKI Tetsurou + + * Makefile.comm: Add $(INCLUDES) to $(ALL_CFLAGS). + +2000-03-11 Werner LEMBERG + + * src/preproc/grn/hdb.cc (DBGetType): Added return value to make + compilers silent. + * src/preproc/grn/hgraph.cc: Add #ifdef for hypot(). + * src/include/lib.h: Remove some spaces. + +2000-03-10 Werner LEMBERG + + * src/libs/libgroff/tmpfile.cc (xtmptemplate, xtmpfile): Removing + initializers from arguments (some compilers don't like this). + +2000-03-09 Gaius Mulley + + * src/libs/libgroff/htmlindicate.cc: Added library file which is now + used by pic and eqn to tell grohtml where the graphic regions start + and end. + * src/libs/libgroff/Makefile.sub: Use it. + * src/preproc/eqn/main.cc, src/preproc/pic/troff.cc: Altered to use + graphic_start() and graphic_end() from htmlindicate.cc. + +2000-03-09 Werner LEMBERG + + * tmac/tmac.safer: Will now work correctly in compatibility mode. + * tmac/groff_man.man: More fixes. + +2000-03-08 Werner LEMBERG + + * doc/Makefile: Added texput.log to the `clean' target. + * doc/groff.texinfo: Added info about delimiters for escapes. + +2000-03-08 Bernd Warken + + * src/preproc/pic/pic.man: Add info on conversion of pic images to + other graphic formats. + +2000-03-07 OKAZAKI Tetsurou + + * Makefile.in, Makefile.sub, src/preproc/eqn/Makefile.sub, + src/roff/groff/Makefile.sub, src/roff/nroff/Makefile.sub, + src/utils/afmtodit/Makefile.sub: Use $(INSTALL_SCRIPT) for script + files. + +2000-03-07 Werner LEMBERG + + * doc/groff.texinfo: Spelling fixes. + +2000-03-06 Werner LEMBERG + + * tmac/groff_man.man: Completely revised to cover everything in + tmac.an. + + * doc/groff.texinfo, src/roff/troff/troff.man: Document evc request. + Other minor fixings. + * src/roff/troff/env.cc (environment_copy): Improve error message and + fix itoa->i_to_a. + * src/roff/troff/TODO: Updated. + + * doc/Makefile: Bug fixes -- this is still provisional, though... + + * tmac/eqnrc: Small fixes. + +2000-03-05 Abramo Bagnara + + Adding a request `evc' to copy environments. + + * src/roff/troff/env.cc (environment::copy, environment_copy): + Implement it. + * src/roff/troff/env.h: Add prototype. + +2000-03-05 Francisco Andrés Verdú + + Adding strsep() -- Solaris 8 doesn't have it. + + * configure.in: Test it. + * src/devices/grolbp/lbp.cc: Add code. + +2000-03-05 Werner LEMBERG + + * src/roff/troff/div.cc (macro_diversion::output, + top_level_diversion::output): Fixing an incompatibility with + original troff: \x'0' updates the .a register also. Thanks to + for pointing this out. + * doc/groff.texinfo: Document it. + + * Makefile.in: Create Makefile.dep if necessary before calling the + submake process to avoid warning about nonexistent file. + + * NEWS, PROJECTS: Updated. + +2000-03-04 Werner LEMBERG + + * tmac/troffrc: Add tmac.lbp. + +2000-03-03 Francisco Andrés Verdú + + * tmac/tmac.lbp: New file. + * src/devices/grolbp/grolbp.man: Add documentation of `lbpname' + command. + +2000-03-03 Werner LEMBERG + + * Makefile.in: Fixing $(subdir). + + * README, NEWS: Small fixes. + + * test-groff: Adding path to grolbp. + + * configure.in: The (new) file src/xditview/Imakefile.in will be + also configured -- it is now possible to build gxditview in a + directory different from $srcdir. + +2000-03-02 Blake McBride + + * src/libs/libgroff/searchpath.cc (open_file): Adapting to WinNT. + + * MORE.STUFF: Added website of bell labs and info about plot2dev. + +2000-03-01 Colin Phipps + + * src/utils/indxbib/indxbib.cc (main): Use mkstemp() for temporary + files. + +2000-02-29 Werner LEMBERG + + Adding GNU getopt to the groff distribution. + + * src/include/getopt.h, src/libs/libgroff/{getopt.c,getopt1.c}: + New files. + * src/include/Makefile.sub, src/libs/libgroff/Makefile.sub: Update. + * aclocal.a4: Remove GROFF_GETOPT function. + * configure.in, Makefile.in, PROBLEMS: Update. + * src/include/lib.h: Replace getopt tests with getopt.h. + * src/devices/grolbp/lpb.cc: Remove inclusion of getopt.h. + + * doc/groff.texinfo: Further checking/updating. Adding more index + entries. + + * man/groff_out.man: Fix nroff mode activation (for emacs). + * man/groff_font.man: Add missing ligature. + +2000-02-28 Werner LEMBERG + + * doc/groff.texinfo: Further checking/updating. Adding more index + entries. + + * src/devices/grolbp/grolbp.man: Added a comment line at the + beginning of the file (similar to shell scripts) which indicates + that `tbl' should be used as a preprocessor. + +2000-02-27 Blake McBride + + Adapting groff to MS Visual C++ 6.0 compiler (tested with + Windows NT 4.0). Uses _MSC_VER define where necessary. + + * src/devices/grodvi/dvi.cc: Making stdout a binary stream. + * src/devices/grolj4/lj4.cc: Making getopt variables `extern "C"'. + * src/devices/grohtml/html.cc, src/devices/grops/ps.cc, + src/include/lib.h, src/libs/libgroff/errarg.cc, + src/libs/libgroff/itoa.c, src/libs/libgroff/nametoindex.cc, + src/preproc/refer/label.y, src/preproc/refer/label.cc, + src/roff/groff/pipeline.c, src/roff/troff/column.cc, + src/roff/troff/div.cc, src/roff/troff/env.cc, + src/roff/troff/input.cc, src/roff/troff/node.cc, + src/roff/troff/reg.cc: Renaming itoa() to i_to_a() and iftoa() to + if_to_a() to avoid name clashes. + * src/include/posix.h: Don't use unistd.h. + * src/libs/libgroff/tmpfile.cc: Use `#ifndef...#else...#endif' + clause for integrating non-Unix xtmpfile() code. + * src/roff/troff/input.cc: Adding `public' keyword to macro_header + structure; use "rt" for popen() in pipe_source(); add getpid() + dummy function. + * src/roff/troff/node.cc: Use special versions of popen() in + real_output_file() and pclose() in ~real_output_file(). + +2000-02-27 Werner LEMBERG + + Adding a new driver, grolbp, for Canon CAPSL printers (LBP-4 and + LBP-8 series laser printers). This code has been contributed by + Francisco Andrés Verdú . + + * src/devices/grolbp/*: The grolbp output device. + * font/devlpb/*: The font description files. + * Makefile.in: Add grolpb and devlbp subdirectories. + + * src/devices/grodvi/grodvi.man, src/devices/grolj4/grolj4.man, + src/devices/grotty/grotty.man,src/roff/troff/troff.man: Minor + typographic fixes. + + * doc/groff.texinfo: Further checking/updating. Adding more index + entries. + + * NEWS: Updated. + + * src/devices/grolbp/Makefile.sub: Adding $(srcdir). + + * man/groff_font.man: Adding info about obsolete DESC keywords. + * src/devices/grolj4/grolj4.man: Documenting additional DESC + keywords. + +2000-02-26 Werner LEMBERG + + * src/preproc/grn/grn.man: Added info about the gremlin file format + (contributed by Daniel Senderowicz ). + +2000-02-25 Werner LEMBERG + + * src/preproc/grn/main.cc: Allow values of `narrow' parameter and + friends to be non-integer. + + * src/preproc/grn/grn.man: Document it. + + * doc/groff.texinfo: Further checking/updating. Adding more index + entries. + +2000-02-24 Werner LEMBERG + + * src/preproc/grn/main.cc: Introduce BASE_THICKNESS, defining + line thicknesses to be integer multiples of this value. + + * src/preproc/grn/grn.man: Commenting out the -s option -- the + corresponding code doesn't work (yet). + + * doc/groff.texinfo: Further checking/updating. Adding more index + entries. + +2000-02-23 Werner LEMBERG + + * src/preproc/grn/{main.cc, hgraph.cc}: Using point units to + specify line thickness instead of base units. The new default + values are now 0.15,pt 0.45pt, and 0.75pt for thin, middle, and + thick lines respectively. + + Removed unused variable `prevval'. + + * src/preproc/grn/grn.man: Updated. + +2000-02-22 Werner LEMBERG + + * src/preproc/grn/main.cc: Slight formatting. + + * src/roff/groff/groff.man: Formatting fix. + * src/preproc/grn/grn.man: Ditto. + + * src/roff/grog/grog.pl: Fixing two embarrassing bugs. + + * doc/groff.texinfo: Further checking/updating. + +2000-02-21 Werner LEMBERG + + * README, INSTALL, PROJECT, PROBLEMS, BUGREPORT: Updated. + + * test-groff: Added grn subdir to path. + + * doc/groff.texinfo: Some restructing and other small improvements. + + * src/roff/groff/groff.cc (help): Fixed info string. + +2000-02-20 Werner LEMBERG + + * doc/meref.me: Fix description of .GS request. + + * src/roff/troff/troff.man: Fixing typo. + + Adding the `grn' preprocessor for gremlin graphic files. + + * src/preproc/grn/*: This is the Berkeley distribution written by + David Slattengren and Barry Roitblat, adapted to groff by Daniel + Senderowicz and Werner Lemberg. + + * doc/grnexampl.{me,g}: A sample for grn. + + * Makefile.in: Added subdirectory entry for grn. + + * src/roff/groff/groff.cc: Added support for grn. It can be now + called with the switch `-g'. + + * src/roff/groff/groff.man: Updated. + + * src/roff/grog/grog.{man,pl,sh}: Updated. + + * NEWS: Updated. + +2000-02-11 Gaius Mulley + + * src/include/lib.h: Added xtmptemplate and made xtmpfile + parametrically polymorphic. + + * src/libs/libgroff/tmpfile.cc: Implemented xtmptemplate + and the alterations to xtmpfile. + xtmpfile can be requested to return the filename created + and asked not to unlink the temp file. The default behaviour + if parameters are absent is exactly the same as before. + +2000-02-11 Abramo Bagnara + + A new request `length' is available which returns the length of a + string in a number register: + + * src/roff/troff/input.cc (length_macro): Implement it. + * src/roff/troff/input.cc (init_input_requests): Register it. + +2000-02-11 Werner LEMBERG + + * doc/groff.texinfo, src/roff/troff/troff.man: Add documentation + of the `substring' request. + + * src/roff/troff/troff.man, doc/groff.texinfo: Document `length' + request. + + * src/roff/troff/TODO, NEWS: Updated. + +2000-02-09 Werner LEMBERG + + * src/roff/groff/groff.man: Added an example. + +2000-02-06 Werner LEMBERG + + I've considerably modified the directory structure of the + distribution to get a more vertical layout. For example, the number + of top level directories has been reduced from 42 to 6. + + As a consequence, many changes, especially to the makefiles, were + necessary: + + * The makefile variables `top_builddir' and `top_srcdir' have been + introduced. Virtually all relative paths have been replaced with + absolute ones using these two variables. + + * Dependencies (in the files `Makefile.dep') are no longer part of + the distribution. Instead, they are created during a `make install' + in the build directory. + + * aclocal.m4 (GROFF_SRCDIR, GROFF_BUILDDIR): Two new functions to + make `top_srcdir' and `top_builddir' absolute. + + Some other changes: + + * Man pages now depend on the files `VERSION' and `REVISION'. + + * The added shell script `mkinstalldirs' will replace `mkdir' in + almost all cases. + + * VERSION: Version number increased to 1.16. + +2000-02-04 Werner LEMBERG + + * grops/psrm.cc (read_one_of): Fixed pointer incrementation. + + * Makefile.in: Removed $(tmac_m) since it is no longer needed + (after an update of the mm stuff). + + * troff/Makefile.sub (majorminor.cc): Fix dependencies. + +2000-02-03 Werner LEMBERG + + The .psbb request will now also accept Mac PS images (i.e. using LF + as the EOL character). + + * troff/input.cc (ps_get_line): New function, taken from psrm.cc + (with slight modifications). + * troff/input.cc (do_ps_file): Use it. + + * test-groff: Add grohtml and grolj4 output devices to PATH. + +2000-01-30 Werner LEMBERG + + * NEWS, MORE.STUFF: Updated. + +2000-01-30 Cary D. Renzema + + Add the `srand' command to pic. + + * pic/lex.cc, pic/pic.y: Implement it. + * pic/pic.man: Document it. + * pic/pic.cc, pic/pic.tab.h: Regenerated (with yacc). + +2000-01-30 Werner LEMBERG + + Add a new request `.psbb'. This does exactly what the external + program psbb did. It scans a PostScript image file for a + %%BoundingBox comment and extracts the bounding box values (in + PostScript units) which are then stored in the four new (read-only) + number registers `llx', `lly', `urx', and `ury'. + + This will allow the usage of the .PSPIC macro without worrying + about unsafe behaviour of groff, i.e., it will work without the + `-U' switch of groff. + + * troff/input.cc: Implement it. + * tmac/tmac.pspic: Use it. + * troff/troff.man, grops/grops.man, NEWS: Document it. + * psbb/*, Makefile.in: Remove it since it is no longer needed. + + This is bloody C code simply adapted from psbb.c! Any improvements + welcome. + +2000-01-29 Werner LEMBERG + + * man/groff_font.man: Minor clarifications. + + * NEWS: Updated. + +2000-01-28 Werner LEMBERG + + * afmtodit/afmtodit.pl: Use new `--' comment delimiter. + +2000-01-28 Gaius Mulley + + * man/groff_font.man: Brought up to date regarding tcommand + extensions. + * libgroff/font.cc: Handle everything after `--' as a comment + in the font files. + * devps/*: Added comment delimiter inside devps font files. + +2000-01-28 Werner LEMBERG + + * tmac/tmac.arkup, tmac/groff_markup.man: Replace \fC...\fR with + \fC...\fP (which now works as expected). + + * troff/troff.man: Fix typo. + +2000-01-27 Gaius Mulley + + Completed the pass_filenames implementation in troff. + + * libdriver/input.cc: Will read the new `F' tcommand. + * troff/node.cc, troff/node.h: Will issue the new `F' tcommand. + * troff/input.cc: Use it. + +2000-01-26 Werner LEMBERG + + * troff/env.cc (set_font): Fix the behaviour of \fP. The previous + font will now be updated even if an invalid font is selected. + +2000-01-24 Werner LEMBERG + + * doc/homepage.ms: Updated for new tmac.arkup. + + * tmac/tmac.html: Disable line breaks after hyphen-like characters. + + * tmac/tmac.arkup: Cleanup. + + Added `\&' to .HTML macro to `leave vertical mode', so to say. + + Removed obsolete .LINK macro completely. + + The macros .URL, .FTP, and .MAILTO now accept a third argument which + will be immediately appended to the second argument (to be used with + punctuation, for example). + + Disabled .CDFTP macro temporarily for security reasons. + + * tmac/groff_markup.man: Complete revision for latest changes in + tmac.arkup -- note that it does not yet format correctly with + grohtml :-( + +2000-01-23 Bruno Haible + + * nroff/nroff.sh: Accept -Tutf8 option and pass it through. + * devutf8/R.proto: Add mappings for wp, lh, rh. + * devutf8/NOTES: Updated. + +2000-01-23 Werner LEMBERG + + * doc/groff.texinfo: Updated version/copyright info. + +2000-01-21 Gaius Mulley + + Added support for two new directives in device descriptions: + `pass_filenames' (to pass the input file name to the output device) + and `use_charnames_in_special' (to support e.g. accented characters + in the `X' request). + + * include/font.h, troff/charinfo.h: Declare it. + + * libgroff/font.cc, libgroff/fontfile.cc: Set it. + + * devhtml/DESC: Use it. + + * troff/input.cc: New function encoded_char. + + * troff/token.h: Add test for `specialness'. + +2000-01-21 Werner LEMBERG + + * tmac/Makefile.sub: tmac.a4 and tmac.trace have been removed by + mistake from the list of files to be installed. + +2000-01-18 Werner LEMBERG + + * README: Added info how to apply patches. + +2000-01-15 Jan Echternach + + * troff/node.cc (ligature_note::operator delete): Fix g++ warning. + +2000-01-15 Gaius Mulley + + * troff/input.cc: Add support for troffrc-end. + + * tbl/main.cc: Altered to issue table-start and table-end special + characters if using the html device. + + * devhtml/*: Modified font files to incorporate html encoding of + characters. + + * tmac/groff_markup.man: New file documenting tmac.arkup. + + * tmac/troffrc-end: New file. This is invoked after all user + specified macros. Currently used by the html device to include + tmac.html. Thus no need for users to specify -mhtml anymore. + + * tmac/Makefile.sub (NORMALFILES): Add troffrc-end. + (MAN7): Add groff_markup.man. + + * tmac/tmac.an, tmac/tmac.html: Small html updates. + + * tmac/troffrc: tmac.arkup will now be called for the html device. + + * libgroff/font.cc, libgroff/font.h: Altered to include reading of + extra device specific information about fonts. + + * doc/homepage.ms: New file. It is an example how an HTML home page + could look like with grohtml. + + * doc/Makefile: Add homepage.ms. Remove rule for pic.html. + +2000-01-12 Bruno Haible + + * devutf8/R.proto: Add mappings for ti, Fn, st, an. Change mappings + of Im, Re. + + * devutf8/NOTES: Updated. + +2000-01-08 Bruno Haible + + * eqn/box.cc, eqn/lex.cc, eqn/other.cc, eqn/over.cc, eqn/special.cc, + eqn/text.cc, grodvi/dvi.cc, grops/ps.cc, grops/psrm.cc, + libbib/index.cc, libbib/linear.cc, libbib/search.cc, + libdriver/printer.cc, libgroff/font.cc, libgroff/string.cc, + pic/lex.cc, pic/object.cc, refer/label.y, refer/ref.cc, tbl/main.cc, + tbl/table.cc, tfmtodit/tfmtodit.cc, troff/dictionary.cc, + troff/div.cc, troff/env.cc, troff/input.cc, troff/node.cc, + troff/node.h, troff/reg.cc: Avoid most "g++ -Wall -Wno-sign-compare" + warnings. + + * troff/node.cc (bracket_node::copy): Initialize last to NULL. + +2000-01-12 Fabrizio Polacco + + grolj4: Paper size will be searched case-insensitively. + + * include/lib.h: Add check for strcasecmp(). + * grolj4/li4.cc (lookup_paper_size): Use strcasecmp(). + * configure.in: Check for strcasecmp(). + +2000-01-11 Werner LEMBERG + + * troff/Makefile.sub (majorminor.cc): Fix incorrect path to + `REVISION'. + +2000-01-10 Werner LEMBERG + + * Makefile.comm, Makefile.in, doc/Makefile: More fixes for the + revision scheme. + + Add a new read-only register, `.Y', which contains the groff + revision. + + * troff/input.cc (init_input_requests): Define it. + * troff/Makefile.sub (majorminor.cc): Define `revision' string. + * doc/groff.texinfo, troff/troff.man: Document it. + + * libgroff/Makefile.sub (version.cc): Add definition of + `Version_string[]', consisting of `..' + * eqn/main.cc, grodvi/dvi.cc, grolj4/lj4.cc, grops/ps.cc, + grotty/tty.cc, hpftodit/hpftodit.cc, indxbib/indxbib.cc, pic/main.cc, + refer/refer.cc, soelim/soelim.cc, tbl/main.cc, tfmtodit/tfmtodit.cc, + troff/input.cc, pfbtops/pfbtops.c: Use it. + +2000-01-10 Fabrizio Polacco + + Add a revision scheme to the groff package. + + * REVISION: New file. + * libgroff/Makefile.sub (version.cc): Use it to define + `revision_string[]'. + * grops/psrm.cc: Use revision_string (converted to an unsigned + integer) in constructor of resource_manager. + +2000-01-10 Bruno Haible + + * devutf8/Makefile.sub, devutf8/DESC.proto, devutf8/R.proto: New + files. + * Makefile.in (DEVDIRS): Add devutf8. + * grotty/tty.cc: Include device.h. + (glyph): Change type of `code' to `unsigned int'. + (tty_printer): New field is_utf8. Constructor takes device argument. + (tty_printer::tty_printer): If device if `utf8', set is_utf8. + (tty_printer::add_char): Change type of first arg to `unsigned int'. + (tty_printer::put_char): New function. + (tty_printer::end_page): Use put_char() instead of ::putchar(). + (make_printer): Pass device to tty_printer constructor. + * nroff.sh: Determine default device by calling 'locale'. As a + fallback, look at all of $LC_ALL, $LC_CTYPE, $LANG, $LESSCHARSET. + Recognize UTF-8 locales. + * tmac/eqnrc: Recognize utf8 like latin1. + * tmac/troffrc: Device utf8 needs tmac.tty. + +2000-01-07 Werner LEMBERG + + * tmac/Makefile.sub: tmac.a4 and tmac.trace will now be installed. + +2000-01-07 Paul Eggert + + Add a new predefined writeable number register, `year', + which contains the current year. + + * doc/groff.texinfo, PROBLEMS, troff/troff.man: Document it. + * tmac/tmac.s: Use it. + * troff/input.cc (init_registers): Initialize it. + +2000-01-06 Werner LEMBERG + + * PROBLEMS: Fixed typo. + +2000-01-04 Paul Eggert + + * PROBLEMS: Add Y2k advice for the yr number register. + +2000-01-03 Paul Eggert + + * doc/groff.texinfo: Fix Y2k bug in documentation of \n(yr. + +2000-01-02 Werner LEMBERG + + * tmac/tmac.arkup: Slight modification of macros to provide better + appearance for non-HTML formats. + +2000-01-01 Charles Levert + + * soelim/soelim.cc (include_path_append): realloc(NULL, n) + does not automatically translate to malloc(n) on all OSes + (e.g., SunOS) so do it explicitly. Also, check the returned + value. + +2000-01-01 Werner LEMBERG + + * tmac/tmac.arkup: Added .LINE macro. Some formatting. + + * Makefile.in: Added $(tmac_m) again since the Makefile in `mm' + expects this variable + +2000-01-01 Gaius Mulley + + * doc/Makefile: Added instructions to create HTML and text + versions of some files. + +1999-12-31 Werner LEMBERG + + * Updated INSTALL.gen. + + * tmac/tmac.arkup: Added fixes so that .FTP and .MAILTO works + better resp. correctly with non-HTML devices. + +Copyright 1999-2000 Free Software Foundation, Inc. + +Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. + +Local Variables: +coding: latin-1 +fill-column: 72 +mode: change-log +version-control: never +End: +vim:set autoindent textwidth=72: diff --git a/ChangeLog.117 b/ChangeLog.117 new file mode 100644 index 0000000..5724952 --- /dev/null +++ b/ChangeLog.117 @@ -0,0 +1,2199 @@ + +Version 1.17.2 released +======================= + +2001-07-07 Werner LEMBERG + + * src/utils/indxbib/indxbib.cc (main): Change type of `name_max' + to size_t. + +2001-07-06 Ruslan Ermilov + + * tmac/doc.tmac (Rv): Make `Rv' really not parseable. + Fix synopsis. + * tmac/groff_mdoc.man: Fix synopsis. + +2001-07-05 Ruslan Ermilov + + * tmac/doc.tmac (doc-inset-list, doc-hang-list, doc-ohang-list): + Restore `doc-Pa-font'. + +2001-07-04 Werner LEMBERG + + * src/utils/indxbib/dirnamemax.c: Moved to ... + * src/libs/libgroff/maxfilename.cc: Here. + s/dir_name_max/file_name_max/. + Add copyright. + * src/include/lib.h: Add file_name_max. + * src/utils/indxbib/indxbib.cc: Updated. + * src/utils/indxbib/Makefile.sub, src/libs/libgroff/Makefile.sub: + Updated. + + * src/libs/libgroff/tmpfile.cc (TMPFILE_PREFIX) [__MSDOS__]: Define + as empty. + (xtmpfile) [_MSC_VER]: Removed -- MSVC has mktemp(). + + * src/preproc/html/pre-html.cc (PAGE_TEMPLATE, PS_TEMPLATE, + REGION_TEMPLATE): New macros. + (createAllPages, makeTempFiles): Use them. + Include `nonposix.h'. + (html_system): New function. + (createAllPages, createImage): Use it. + Use EXE_EXT. + + * tmac/www.tmac: Fix typos. + +2001-07-03 Werner LEMBERG + + * tmac/www.tmac: Disable hyphenation in normal text only if output + device is html. + (URL, FTP, MAILTO): Disable hyphenation of actual URL with `\%'. + * tmac/groff_mwww.man, NEWS: Updated. + +2001-07-03 Gaius Mulley + + * tmac/www.tmac (.IMAGE): Add fourth parameter to specify vertical + image location. + +2001-07-02 Ruslan Ermilov + + * tmac/doc-common, tmac/doc.tmac (doc-display-ft-stack, + doc-display-ps-stack): Implement font and font size stack for + displays. + +2001-07-02 Werner LEMBERG + + * REVISION: Increased to 2. + * src/roff/troff/input.cc (read_size): Fix special case `\s[0]'. + + * src/groff/grog/grog.pl (process): Handle `Oo' and `Oc' not at the + beginning of a line. + * src/groff/grog/grog.sh: Ditto. + +2001-06-29 Peter Marquardt + + * src/preproc/eqn/neqn.sh: Put `export' keyword in a new line to + make it portable. + +2001-06-27 Werner LEMBERG + + Fix problems with preprocessor string for `man' program. + + * *.man: Don't use `s' in preprocessor string -- it doesn't exist. + Updated/added copyright. + Moved Emacs's local variable to identify nroff mode to the end of + the file; add local variable if missing. + +2001-06-26 Andras Salamon + + * aclocal.m4: Replace AC_LANG_SAVE + AC_LANG_CPLUSPLUS with + AC_LANG_PUSH(C++) and AC_LANG_RESTORE with AC_LANG_POP(C++). + * configure: Regenerated. + +2001-06-25 Andras Salamon + + * aclocal.m4 (GROFF_PAGE): Fix page detection code. + * configure: Regenerated. + +2001-06-24 Werner LEMBERG + + * doc/homepage.ms: Don't include arkup.tmac (which no longer exists) + but www.tmac. + * doc/pic.ms: Fix typos. + +Version 1.17.1 released +======================= + +2001-06-21 Golubev I. N. + + * aclocal.m4 (GROFF_NEED_DECLARATION): Fix inclusion of strings.h. + * configure: Updated. + +2001-06-20 Gaius Mulley + + * src/roff/preproc/html/pre-html.cc (make_message): Fix incorrect + image names. + * src/roff/troff/dic.cc (blank_line): Add html tag. + +2001-06-19 Gaius Mulley + + * src/roff/troff/input.cc (do_suppress): Fix typo. + +2001-06-18 Gaius Mulley + + Added two new options (-D and -I) to specify image names and a + subdirectory to place the images in. + + Change syntax from \\Ox to \\O[x]. + + * src/devices/grohtml/post-html.cc (main): Add options. + (usage): Updated. + * src/preproc/html/pre-html.cc: Include `stdarg.h'. + Use `NULL' instead of `0' for null string pointers. + (MAX_RETRIES): New macro. + (lengthOfintToStr, intToStr, make_message): New functions. + (makeFileName): Make function static. + Implement -D and -I options. + (checkImageDir): New function. + (write_end_image, write_start_image): Use new syntax of \O. + (createAllPages, removeAllPages): Implement -D and -I options. Use + make_message(). + (createImage): Use make_message(). + (addps4html): Add guard for malloc(). + (usage, scanArguments): Updated. + (makeTempFiles): Use mkstemp(). + (removeTempFiles): Use unlink(). + (findPrefix): Add guard for malloc(). + (main): Updated. + * src/roff/troff/input.cc (get_delim_file_name): New function to + parse \O. + (do_suppress): Updated to parse new syntax. + * src/devices/grohtml/grohtml.man: Updated. + * tmac/www.tmac: Updated to new syntax. + + * NEWS: Updated. + +2001-06-15 Werner LEMBERG + + * src/roff/grog/Makefile.sub: Remove NAMEPREFIX. + + * src/devices/grohtml/grohtml.man: Minor improvements. + +2001-06-14 Werner LEMBERG + + * src/preproc/html/Makefile.sub: Remove NAMEPREFIX. + +2001-06-11 Werner LEMBERG + + * man/roff.man, mann/groff.man: Use '\" instead of .\" in the first + line to specify preprocessor options -- mandb 2.3.1 only recognizes + the former. + * src/preproc/grn/grn.man: Add proper '\" string. + +2001-06-11 OKAZAKI Tetsurou + + * test-groff: Don't use PATH but GROFF_BIN_PATH. + +2001-06-08 Werner LEMBERG + + Updated to autoconf 2.50. + + * configure.in: Renamed to... + * configure.ac: This. + * aclocal.m4 (AC_OUTPUT_MAKE_DEFS): Removed. + (GROFF_OS390): Updated. + * configure: Regenerated. + +2001-05-18 Werner LEMBERG + + * src/roff/troff/env.c, src/roff/troff/env.h, + src/roff/troff/input.cc, src/roff/troff/troff.man: Undo `ss' change + from 2000-12-21. + +2001-05-17 Jeffrey Friedl + + * src/roff/troff/input.cc (read_size): Fix special case `\s0'. + +2001-05-16 Werner LEMBERG + + * src/roff/troff/input.cc (read_size): Emit warning if value becomes + less than or equal zero; set it to 1 then. + * src/roff/troff/node.h (node::node): Initialize `last'. + +2001-05-08 Werner LEMBERG + + * tmac/an-old.tmac: Make predefined strings work in compatibility + mode. + Add troff version guard. + * tmac/doc.tmac: Simplify version guard. + +2001-05-07 Werner LEMBERG + + The .ns and .rs requests are now honoured not only in the top-level + but in all diversions (similar to UNIX troff). + + This change is based on a patch from Tadziu Hoffmann + . + + * src/roff/troff/div.h (diversion): Add `no_space_mode' member. + (top_level_diversion): Remove `no_space_mode' member. + * src/roff/troff/div.cc (diversion::diversion, + top_level_diversion::top_level_diversion): Updated. + (macro_diversion::output): Reset `no_space_mode'. + (no_space, restore_spacing): Use `curdiv' unconditionally. + (space_request, blank_line): Check `curdiv->no_space_mode'. + (no_space_mode_reg::get_value, no_space_mode_reg::get_string): Use + `curdiv' unconditionally. + * NEWS, src/roff/troff/troff.man, man/groff.man, doc/groff.texinfo: + Updated. + +2001-05-06 Werner LEMBERG + + Added two new requests `de1' and `am1' which are similar to `de' and + `am' with the difference that compatibility mode is saved on entry, + switched off during macro execution, and restored on exit. + + * src/roff/troff/input.h: Added two new special characters + (COMPATIBLE_SAVE, COMPATIBLE_RESTORE). + * src/roff/troff/input.cc (input_iterator): Added two member + functions `save_compatible_flag' and `get_compatible_flag'. + (input_stack): Ditto. + (string_iterator): Ditto. Also add private member + `saved_compatible_flag'. + (token::next): Use COMPATIBLE_SAVE and COMPATIBLE_RESTORE. + (calling_mode): New enumeration. + (do_define_macro): Use it. Insert COMPATIBLE_SAVE and + COMPATIBLE_RESTORE at the beginning and end of macro, respectively. + (define_macro, define_indirect_macro, append_macro, ignore): Use + `calling_mode'. + (define_nocomp_macro, append_nocomp_macro): New functions. + (init_input_requests): Updated. + (do_request): Rename local variable `saved_compatible_flag' to + `old_compatible_flag'. + * NEWS, src/roff/troff/troff.man, man/groff.man: Document it. + + * tmac/an-old.tmac: Use `de1' instead of `de' request for all + public and trap-invoked macros. As a consequence, the man macros + work in compatibility mode also. + +2001-05-06 Solar Designer + + * Makefile.in: Use $(mandir). + +2001-05-06 Alexios Zavras + + * src/utils/afmtodit/afmtodit.pl: Fix serious typo. + +2001-05-05 Werner LEMBERG + + Added `.ns' number register: Returns 1 in no-space mode (if in + top-level diversion), 0 otherwise. + + * src/roff/troff/div.cc (no_space_mode_reg): New class. + (init_div_requests): Updated. + * NEWS, src/roff/troff/troff.man, man/groff.man, doc/groff.texinfo: + Document it. + +2001-05-04 Werner LEMBERG + + * src/roff/nroff/nroff.man: Improved documentation (especially + locales). + +2001-05-02 Werner LEMBERG + + Added `brp' request: This is \p as a request. + + * src/roff/troff/env.cc (environment::do_break): Add parameter + `spread'. + (do_break_request): New function (was `break_request'). + (break_request): Calls `do_break_request'. + (break_spread_request): New; calls `do_break_request'. + (init_env_requests): Updated. + * src/roff/troff/env.h: Updated. + * NEWS, src/roff/troff/troff.man, man/groff.man: Document it. + + * REVISION: Increased to 1. + * win32-diffs: Updated. + +2001-05-01 Werner LEMBERG + + * tmac/an-old.tmac: Fix minor compatibility mode issue. + * tmac/troffrc-end: Make it really work in compatibility mode. + +2001-04-27 Werner LEMBERG + + * src/utils/lkbib/lkbib.cc: Switch inclusion order of stdio.h and + stdlib.h. + +2001-04-22 Werner LEMBERG + + * src/libs/libgroff/getopt.c, src/include/getopt.h: Updating to + latest versions from glibc CVS archive. + + * MORE.STUFF: Updated, using a patch from Kees Zeelenberg + . + +2001-04-21 Werner LEMBERG + + * configure.in: Move check for mkstemp() to... + * aclocal.m4 (GROFF_MKSTEMP): This new function. + * configure: Regenerated. + + * src/include/groff-getopt.h: Don't use variable names in + declarations. + + * src/devices/grohtml/html-chars.h: Removed. It isn't used. + * src/devices/grohtml/Makefile.sub, + src/devices/grohtml/post-html.cc: Updated. + +2001-04-21 Albert Chin-A-Young + + * configure.in: Add special check for mkstemp(). + * src/libs/libgroff/tmpfile.cc: Use it. + * src/utils/indxbib/indxbib.cc: Ditto. + * src/utils/pfbtops/pfbtops.c (main): Don't use C++ comment style. + * src/devices/grolbp/lbp.h (lbpprintf, lbpputs, vdmprintf): Use + `const'. + +2001-04-20 Bruce Lilly + + `Version_string' as C++ object was not visible to linker from C + object files. + Add `const' to `Version_string'. + + * src/utils/pfbtops/pfbtops.c (main), src/roff/groff/groff.cc + (main), src/roff/troff/input.cc (main), src/preproc/tbl/main.cc + (main), src/preproc/pic/main.cc (main), src/preproc/eqn/main.cc + (main), src/preproc/grn/main.cc (main), src/preproc/html/pre-html.cc + (scanArguments), src/preproc/refer/refer.cc (main), + src/preproc/soelim/soelim.cc (main), src/devices/grotty/tty.cc + (main), src/devices/grodvi/dvi.cc (main), src/devices/grolj4/lj4.cc + (main), src/devices/grohtml/post-html.cc (main), + src/devices/grolbp/lbp.cc (main), src/utils/tfmtodit/tfmtodit.cc + (main), src/utils/hpftodit/hpftodit.cc (main), + src/utils/lookbib/lookbib.cc (main), src/utils/indxbib/indxbib.cc + (main), src/utils/lkbib/lkbib.cc (main), + src/utils/addftinfo/addftinfo.cc (main): Implement it. + + * src/roff/groff/pipeline.c: Add _UWIN. + * src/include/nonposix.h: Ditto. + +2001-04-20 Werner LEMBERG + + * src/include/lib.h: Use HAVE_STRERROR. + * src/roff/groff/pipeline.c: Ditto. + * src/preproc/html/pre-html.cc: Remove declaration of `strerror'. + * src/libs/libgroff/Makefile.sub (version.cc): Add `extern "C"'. + * src/utils/pfbtops/pfbtops.c: Add copyright notice. + * win32-diffs: Updated. + * src/utils/hpftodit/hpftodit.cc (read_map): Fix compiler warning. + +2001-04-19 Werner LEMBERG + + * src/preproc/html/pre-html.cc (scanArguments): Use `troff_command' + instead of hardwired `"troff"'. + (char_buffer::read_file): Remove unused variables. + (char_buffer::write_file_troff): Ditto. + (char_buffer::write_file_html): Ditto. + (generateImages): Ditto. + (abs): Removed. + * src/utils/addftinfo/addftinfo.cc (main): Fix compilation problem. + + * src/include/lib.h: Don't include `groff-getopt.h' for UWIN. + + * src/libs/libgroff/font.cc (font::load_desc): Fix compiler warning. + * src/libs/libbib/index.cc (index_search_item_iterator::get_tag, + index_search_item::search1): Ditto. + * src/roff/troff/node.h (width_list): Reorder members. + * src/roff/troff/input.cc (do_define_macro): Fix compiler warning. + (lookup_warning): Ditto. + (prepend_string): Commented out. + * src/roff/troff/dictionary.cc (is_good_size): Fix compiler warning. + * src/roff/troff/reg.cc (number_value_to_ascii): Ditto. + * src/preproc/tbl/main.cc (process_format): Ditto. + * src/preproc/pic/pic.y (define_variable, reset, reset_all): Fix + compiler warnings. + * src/preproc/pic/pic.cc: Updated. + * src/preproc/eqn/lex.cc (init_table): Fix compiler warnings. + * src/preproc/eqn/over.cc (over_box::compute_metrics): Ditto. + * src/preproc/refer/command.cc (execute_command): Ditto. + * src/preproc/refer/ref.cc (sortify_title, find_month): Ditto. + * src/preproc/refer/token.cc (lookup_token): Ditto. + * src/preproc/soelim/soelim.cc: Ditto. + * src/preproc/html/pushbackbuffer.cc (ERROR): Ditto. + (isHexDigit): Commented out. + (pushBackBuffer::isString): Remove unused variable. + * src/devices/grops/ps.cc (ps_printer::special): Fix compiler + warning. + * src/devices/grops/psrm.cc (resource_manager::lookup_font, + resource_manager::read_resource_arg, read_one_of, parse_extensions): + Ditto. + * src/devices/grodvi/dvi.cc (dvi_printer::draw): Ditto. + * src/devices/grolj4/lj4.cc (lj4_font::handle_unknown_font_command, + lookup_paper_size): Ditto. + * src/devices/grohtml/post-html.cc (is_subsection): Commented out. + (text_glob, element_list): Reorder members. + * src/devices/grohtml/html-text.cc (html_text::do_pre): Remove + compiler warning. + * src/devices/grohtml/html-text.h (html_text::emit_space): Change + return value to `void'. + * src/devices/grohtml/output.cc (word_list::word_list): Fix order + of initializers. + * src/devices/grohtml/html.h (simple_output::check_newline, + simple_output::space_or_newline, simple_output::enable_newlines): + Add return value. + * src/devices/grolbp/lbp.cc (wp54charset, set_papersize): Remove + compiler warnings. + * src/utils/tfmtodit/tfmtodit.cc (tfm::load, gf::load, main): Ditto. + * src/utils/hpftodit/hpftodit.cc (File::seek, read_symbol_sets, + output_ligatures, output_charset, read_map): Ditto. + * src/utils/lookbib/lookbib.cc (main): Ditto. + * src/utils/indxbib/indxbib.cc (main, fwrite_or_die): Ditto. + (do_file): Fix typo (`=' -> `=='). + * src/utils/lkbib/lkbib.cc (main): Remove compiler warning. + * src/utils/addftinfo/addftinfo.cc (main): Ditto. + +2001-04-18 Ruslan Ermilov + + * src/roff/nroff/nroff.sh: Adding -p (pic) and -t (tbl) options. + Fix usage of GROFF_BIN_PATH. + * src/roff/nroff/nroff.man: Updated. + +2001-04-18 Werner LEMBERG + + * NEWS: Fixing typos. + Updated. + +Version 1.17 released +===================== + +2001-04-17 Werner LEMBERG + + * tmac/Makefile.sub (install-data): mdoc.local-s is in current + directory, not in $(srcdir). + +2001-04-16 Werner LEMBERG + + * doc/groff.texinfo: More info on conditionals. + +2001-04-15 Werner LEMBERG + + * doc/groff.texinfo: Added some info about groff internals. + + * src/roff/troff/node.cc (make_glyph_node): Emit warning message + about missing special character only if the name is non-null. + +2001-04-14 Werner LEMBERG + + Removing the grohtml-old device driver which is now obsolete. + + * src/devices/grohtml-old/*: Removed. + * font/devhtml-old/*: Removed. + * src/libs/libgroff/htmlindicate.cc (graphic_start, graphic_end): + Remove comments. + * Makefile.in (CCPROGDIRS, DEVDIRS): Updated. + * test-groff (PATH): Updated. + * tmac/Makefile.sub (NORMALFILES): Updated. + * tmac/an-old.tmac: Remove special code for html-old device. + Replace `html-or-html-old' register with `an-html'. + * tmac/eqnrc: Updated. + * tmac/html-old.tmac: Removed. + * tmac/troffrc, tmac/troffrc-end: Updated. + * tmac/www.tmac: Remove special code for html-old device. + Replace `html-or-html-old' register with `www-html'. + + * src/libs/libgroff/tmpfile.cc (remove_tmp_files), + src/libs/libgroff/htmlindicate.cc (graphic_end), + include/htmlindicate.h, src/preproc/grn/*.cc, + src/roff/groff/env.{cc,h}: Remove `void' parameter if used as a + single argument for consistency with rest of source code. + + * aclocal.m4, tmac/an-old.tmac: Fix copyright. + +2001-04-13 Ruslan Ermilov + + * src/roff/troff/troff.man: Fixing typos. + +2001-04-13 Werner LEMBERG + + * doc/pic.ms: Fixing many font switches. + * doc/groff.texinfo: Fixes, additions. + * MORE.STUFF: Updated. + +2001-04-12 Gaius Mulley + + * src/devices/grohtml/grohtml.man: Updated manual page regarding + simple anchor. + * src/preproc/html/pre-html.cc (createImage): Fixed right hand + cropping of images. + (removeTempFiles): New function to tidy up temporary files. + * src/preproc/html/pre-html.cc (main): Calls `removeTempFiles()'. + Many fixes to do with the new inline suppress node and image regions + are much tighter. + * src/devices/grohtml/post-html.cc: New method `is_auto_img'. + (generate_img_src): New function. + (html_printer::do_auto_image): Utilizes it. + (do_heading, do_title): Include inline images within their contents. + (html_printer::begin_page): Tidied up comments that are issued to + the html output file. + (html_printer::do_fill): Fixed so that `.nf' works with fonts other + than courier. + (text_glob::is_br): New method used by do_heading. + * tmac/s.tmac: If -Thtml then emit $1 in .IP rather than its + equivalent diversion. + * src/include/html-strings.h: Altered image tags to reflect the + inline image node. + * src/include/htmlindicate.h (html_end_suppress): Added `is_inline' + parameter. + * src/preproc/eqn/main.cc: Will suppress generation of image tags if + it is already inside a pic image. Only emit tags if the argument + `-Tps:html' is present. + * src/preproc/tbl/main.cc: Changes to reflect additional + `html_end_suppress' parameter. + * src/roff/troff/env.cc: Only emit eol tag if a node has been + emitted since the last eol tag was written. + * src/roff/troff/env.h: New boolean `emitted_node'. + * src/roff/troff/input.cc (do_suppress): Handles extra suppress + nodes \O3, \O4, \O5. No longer use `output_low_mark_miny'. + * src/roff/troff/node.cc (check_charinfo): New method. + (troff_output_file::determine_line_limits): Alterations to limit + checking. + * tmac/www.tmac: Changes to reflect new suppress nodes. + +2001-04-12 Bruno Haible + + * src/devices/grohtml/post-html.cc (html_printer::add_to_sbuf): + Escape the html_glyph in the buffer. + (str_translate_to_html): Output the unescaped escaped_char. + * src/devices/grohtml/html-text.cc (issue_table_begin): Set + `frame=void', not `frame=none'. Add `border=0'. + +2001-04-12 Werner LEMBERG + + * PROBLEMS: Add some words on how to avoid wrapper macros. + +2001-04-11 Blake McBride + + * src/include/nonposix.h (fileno) [_MSC_VER]: Removed. + +2001-04-11 Werner LEMBERG + + * font/devlbp/Makefile.sub (CLEANADD): Set it. + * tmac/Makefile.sub (CLEANADD): Add tmac.local-s. + * Makefile.in (dist): Don't remove src/xditview/Imakefile, but ... + * Makefile.sub (DISTCLEANFILES): Here. + + * libs/libgroff/new.cc: Include `nonposix.h'. + * win32-diffs: Updated. + +2001-04-10 Ruslan Ermilov + + Added skeleton macro for defunct macros. + + Updated documentation. + + When inside displays, an empty input line warning should be + suppressed. If another macro call is put inside a display, + all subsequent empty lines found in that display caused a + warning to be emitted. + + * tmac/doc.tmac (doc-defunct-macro): New macro. + (Db, Ds, Ex, Or, Sf): Reimplemented using this macro. + (doc-restore-global-vars): Fixed typo. + (doc-empty-line): Check the `doc-display-depth' register to + determine whether we are inside display or not. + + * tmac/doc-common: Removed `Or' and `Sf' registers. + Moved obsolete `Ds' macro to doc.tmac. + + * tmac/groff_mdoc.man: Bump document date. + Document `.Vt' under ``Variable Types''. + Removed documentation for obsolete `.Or' macro. + +2001-04-10 Werner LEMBERG + + * NEWS: Updated. + * doc/groff.texinfo: Many fixes, additions, clarifications, etc. + +2001-04-10 Bruno Haible + + * src/devices/grodvi/dvi.cc (main): Accept --help and --version. + (usage): Add stream argument. Don't exit. + * src/devices/grohtml/post-html.cc (main): Accept --help and --version. + Write --version output to stdout, not stderr. + (usage): Add stream argument. Don't exit. + * src/devices/grohtml-old/html.cc (main): Accept --help and --version. + (usage): Add stream argument. Don't exit. + * src/devices/grolbp/lbp.cc (long_options): Use symbolic getopt.h + constants. + (usage): Add stream argument. Don't exit. + (main): Write --help output to stdout, not stderr. + * src/devices/grolj4/lj4.cc (main): Accept --help and --version. + (usage): Add stream argument. Don't exit. + * src/devices/grops/ps.cc (main): Accept --help and --version. + (usage): Add stream argument. Don't exit. + * src/devices/grotty/tty.cc (main): Accept --help and --version. + (usage): Add stream argument. Don't exit. + * src/preproc/eqn/main.cc (usage): Add stream argument. Don't exit. + (main): Accept --help and --version. + * src/preproc/grn/main.cc (usage): Add stream argument. Don't exit. + (main): Accept --help and --version. + * src/preproc/html/pre-html.cc (usage): Add stream argument. + (scanArguments): Accept --help and --version. + * src/preproc/pic/main.cc (usage): Add stream argument. Don't exit. + (main): Accept --help and --version. + * src/preproc/refer/refer.cc (main): Accept --help and --version. + (usage): Add stream argument. Don't exit. + * src/preproc/soelim/soelim.cc (usage): Add stream argument. Don't + exit. + (main): Accept --help and --version. + * src/preproc/tbl/main.cc (usage): Add stream argument. Don't exit. + (main): Accept --help and --version. + * src/roff/groff/groff.cc (main): Accept --help and --version. + (synopsis): Add stream argument. + (help): Write --help output to stdout, not stderr. + (usage): Add stream argument. Don't exit. + * src/roff/grog/grog.pl: Accept --help and --version. + (help): New sub. + * src/roff/grog/grog.sh: Accept --help and --version. + * src/roff/nroff/nroff.sh: Accept --help and --version. + * src/roff/troff/input.cc (USAGE_EXIT_CODE): Remove macro. + (usage): Add stream argument. Don't exit. + (main): Accept --help and --version. + * src/utils/addftinfo/addftinfo.cc (main): Accept --help and --version. + (usage): New function with stream argument, doesn't exit. + * src/utils/hpftodit/hpftodit.cc (main): Accept --help and --version. + (usage): New function with stream argument, doesn't exit. + * src/utils/indxbib/indxbib.cc (main): Accept --help and --version. + (usage): Add stream argument. Don't exit. + * src/utils/lkbib/lkbib.cc (usage): Add stream argument. Don't exit. + (main): Accept --help and --version. + * src/utils/lookbib/lookbib.cc (usage): Add stream argument. Don't + exit. + (main): Accept --help and --version. + * src/utils/pfbtops/pfbtops.c (usage): Add stream argument. Don't exit. + (main): Accept --help and --version. + * src/utils/tfmtodit/tfmtodit.cc (main): Accept --help and --version. + (usage): Add stream argument. Don't exit. + +2001-04-10 Ruslan Ermilov + + Fix indentation in SYNOPSIS. + + Updated to include changes of latest BSD mdoc version (basically, + the only change is that `.Fn' and `.Fc' put a final semicolon after + a function declaration in the SYNOPSIS section). + + * tmac/doc.tmac (doc-in-synopsis-count): Replaced with ... + (doc-in-synopsis-section): New variable. Updated all related + functions. + (doc-indent-synopsis-active): New register. + (Nd, Fn, Fo): Use it. + (Cd): It requires manipulation of \n[doc-indent-synopsis] so that + `.Cd' with long argument line produces indented wrapped lines. + Also, the misplaced `.nop \*[doc-Nm-font]\c'' caused extra + undesirable line break to be output. + (doc-do-func-decl, Nm, Vt, Fn, Fo): Remove extraneous calls to + `.rs'. + (Fn, Fc): Add final `;' to output. + (doc-save-global-vars, doc-restore-global-vars): Updated. + * tmac/doc-common: Remove `Ex' register. + Updated. + * tmac/doc-ditroff, tmac/doc-nroff, tmac/doc-syms: Updated + copyright. + +2001-04-06 Ruslan Ermilov + + * tmac/doc.tmac (Cd): Simplify code. + * tmac/groff_mdoc.man: Document some behaviour of `Cd' request. + +2001-04-06 Werner LEMBERG + + Implement continuous underlining for nroff mode. To do that, a new + request in the ditroff language has been added: `x u N' (N is 0 + or 1). + + \X and \Y are now transparent to end-of-sentence recognition. + + * src/include/printer.h (printer): Add `type' parameter to `special' + method. + * src/libs/libdriver/printer.cc (printer::special): Updated. + * src/libs/libdriver/input.cc (do_file): Handle `x u N'. + + * src/devices/dvi/dvi.cc (dvi_printer::special): Handle only + specials of type `p'. + * src/devices/grohtml/post-html.cc (html_printer::special): Ditto. + * src/devices/grohtml-old/html.cc (html_printer::special): Ditto. + * src/devices/grops/ps.cc (ps_printer::special): Ditto. + * src/devices/grotty/tty.cc: Add new enum CU_MODE. + (glyph::order): New method. + (tty_printer::add_char): Use it. + (tty_printer::special): New method. + (tty_printer::end_page): Implement it. + + * src/roff/troff/node.h (special_node): Add `no_init_string' member. + * src/roff/troff/node.cc (special_node::special_node): Add parameter + to set `no_init_string'. + (special_node::tprint_start): Use it. + (special_node::same, special_node::copy): Updated. + (special_node::ends_sentence): New method. + (troff_output_file::start_special): Add parameter to include + initialization of special conditionally. + + * src/roff/troff/env.h (environment): New member `underline_spaces'. + * src/roff/troff/env.cc (do_underline_special): New function. + (environment::set_font): Use it. + (do_underline): Use it. This was `underline()'. + (underline): Call `do_underline()'. + (continuous_underline): New function which calls `do_underline()'. + (environment::newline): Use `do_underline_special()'. + (init_env_requests): Updated. + + * NEWS, man/troff_out.man: Updated. + +2001-04-06 Bruno Haible + + * font/devutf8/R.proto: Fix code of 'shc'. + +2001-04-06 Ruslan Ermilov + + Many fixes. Diag lists can now be nested also; additionally, + `-compact' and `-offset' are supported. + + * tmac/doc.tmac (doc-have-indent): Replaced with ... + (doc-list-have-indent-stackXXX): A new register stack. + (doc-have-diag-list): Removed. + (Bl): Use `doc-list-have-indent-stackXXX'. + (El): Updated. + (doc-diag-list): Use `doc-compact-list-stackXXX'. + (doc-tag-list): Use `doc-list-have-indent-stackXXX'. + (doc-set-vertical-and-indent): Ditto. + (doc-next-list-depth): Removed. + (doc-increment-list-stack): Updated. + (doc-decrement-list-stack): Use `doc-list-depth' instead of + `doc-next-list-depth'. + (doc-end-list, doc-end-column-list): Don't use + `doc-increment-list-stack'. + (doc-set-column-tab): Don't use `doc-list-offset-stackXXX'. + (doc-save-global-vars, doc-restore-global-vars): Updated. + * tmac/doc-common: Updated. + * tmac/groff_mdoc.man: Updated. + * NEWS: Fix typo. + +2001-04-02 Werner LEMBERG + + * src/devices/grotty/grotty.man: Fix grammatical error. + +2001-03-30 Ruslan Ermilov + + Remove .Ld from mdoc package; replace it with special handling of + `...'. + + * tmac/doc-common: Remove `Ld' register. + Uncomment `doc-volume-ds-*' strings. + Remove `doc-operating-system-default'. + (Os): Updated. + * tmac/doc-syms (Ld): Removed. + * tmac/doc.tmac (doc-parse-args, doc-parse-arg-vector): Handle + `...' specially. + * NEWS: Updated. + + * tmac/groff_mdoc.man: Many fixes and updates. + +2001-03-29 Werner LEMBERG + + * tmac/troffrc-end: Protect data with `.do'. Reported by T. Kurt + Bond . + * tmac/www.tmac: Save compatibility mode. + +2001-03-28 Ruslan Ermilov + + * tmac/groff_mdoc.man: Many fixes. + +2001-03-28 Werner LEMBERG + + * src/preproc/soelim/soelim.man: Document that `.so' + isn't recognized. + +2001-03-27 Werner LEMBERG + + * tmac/an-old.tmac (TP, an-do-tag): Reduce line length while in + diversion. This fixes overlong tags. + +2001-03-26 Werner LEMBERG + + * doc/groff.texinfo: Fixed and improved documentation of fonts. + * tmac/doc-syms: Fix error messages. + * tmac/an-old.tmac: Remove incorrect double backslashes. + +2001-03-24 Ruslan Ermilov + + * tmac/Makefile.sub: Strip mdoc.local also + * tmac/strip.sed: Fixed. + +2001-03-24 Werner LEMBERG + + * tmac/doc-nroff, tmac/doc-ditroff: Implement -rSxx switch for + selecting the font size. + * tmac/groff_mdoc.man, NEWS: Document it. + +2001-03-23 Werner LEMBERG + + * src/roff/troff/div.cc (save_vertical_space): Add default argument + to `sv' request. + * src/roff/troff/env.cc (family_change): Make `.fam' accept no + argument to restore previous font family. + * src/roff/troff/troff.man, man/groff.man, NEWS: Updated. + + * doc/groff.texinfo: More fixes and additions (mainly for font + manipulating commands). + + * tmac/groff_mdoc.reference.man: Small updates and renamed to ... + * tmac/groff_mdoc.man: This. The quick reference has been removed. + * tmac/Makefile.sub, NEWS: Updated. + +2001-03-23 Werner LEMBERG + + Replaced mdoc implementation. The new version is `state of the + art', using almost all new features of groff 1.17 -- it won't run + with older versions. + + * tmac/doc.tmac: Completely rewritten. + * tmac/doc-common: Ditto. + * tmac/doc-nroff: Ditto. + * tmac/doc-ditroff: Ditto. + * tmac/doc-syms: Ditto. + * tmac/mdoc.local: New file. + * tmac/groff_mdoc.samples.man: Replaced with ... + * tmac/groff_mdoc.reference.man: New file, covering mdoc completely. + * tmac/strip.sed: Updated. + * tmac/Makefile.sub: Updated. + * INSTALL: Updated. + + * tmac/groff_man.man: Add `man.local' to the FILES section. + +2001-03-22 Werner LEMBERG + + * doc/groff.texinfo: Added many @noindent. + Replaced @end_Example -> @endExample. + Added info whether registers are r/o. + Many other additions and fixes. + +2001-03-21 Werner LEMBERG + + * doc/groff.texinfo: Added macro @Var (and some hacks due to bugs + in makeinfo of texinfo 4.0) to be used in @Def* macros. + Improved @Def* macros: Now the exact syntax of request, register, + and escapes is shown. + Added macros for parentheses and brackets to be used in @Def*. + Many fixes and improvements of the documentation. + +2001-03-20 Werner LEMBERG + + * doc/groff.texinfo: Added new index: `st' (for strings). + Added macros @Defstr(x). + Added macro @Example (adding @group). + Other minor improvements. + +2001-03-19 Werner LEMBERG + + * doc/groff.texinfo: Added two new indices: `es' (for escapes) and + `rq' for requests. `fn' is no longer used. + Added macros @Defreq(x), @Defreg(x), and @Defesc(x). + Removed @Deffn(x). + + * tmac/an-old.tmac (an-p-footer): If `cR' is set, replace page + number with name of man page. + +2001-03-19 Larry Kollar + + * doc/groff.texinfo: Complete revision. Added many @Deffn to gain + consistency. + +2001-03-19 Werner LEMBERG + + * man/groff_font.man: Document `prepro', `postpro', and `print'. + * src/roff/groff/groff.man: Improve documentation of `-l' and `-L'. + * src/devices/grohtml/grohtml.man: Fixing typos. + +2001-03-19 Gaius Mulley + + * tmac/s.tmac (@IP): Pass `.ip' html tag. + * tmac/groff_mwww.man: Remove .LINE macro + * tmac/www.tmac (LINE): Add `.ti'. + + * src/devices/grohtml/post-html.cc (html_printer): New member + `indent'. + (html_printer::emit_raw): Use it. + (html_printer::do_linelength): Ditto. + (html_printer::do_pageoffset): Ditto. + (html_printer::do_indentation): Ditto. + (html_printer::do_tempindent): Ditto. + (html_printer::do_break): Ditto. + (html_printer::begin_page): Ditto. + (html_printer::do_indentedparagraph): New function. + (html_printer::troff_tag): Handle `.ip'. + * src/devices/grohtml/html-text.cc (html_text::issue_table_begin): + Add `' handling. + (html_text::do_table): Add parameter. + (html_text::do_indent): Updated. + * src/devices/grohtml/html-text.h: Updated. + +2001-03-16 Gaius Mulley + + Introduced simple html tables to implement indentation. + + * src/devices/grohtml/html.h (word, word_list): New structures. + (simple_output): Use it. + * src/devices/grohtml/post-html.cc: Add `INDENTATION'. + (html_printer): Improve indentation handling. + (html_printer::emit_raw): Set `in_table' element. Handle + indentation if set. + (html_printer::write_header): Move conditional downwards. + Don't allow whitespace in tags. + (html_printer::do_linelength): Handle line length and indentation + conditionally. + (html_printer::do_pageoffset): Handle indentation conditionally. + (html_printer::do_indentation): Ditto. + (html_printer::do_tempindent): New function member. + (html_printer::do_fill): Take care of indentation. + (html_printer::do_flush): Finish table. + (html_printer::do_links): Ditto. + (html_printer::do_break): New function for handling `.br' and `.ti'. + (html_printer::troff_tag): Use it. + Handle `.ti'. + (html_printer::flush_globs): Fix. + (html_printer::flush_page): Finish table. + (html_printer::html_printer): Fix error message. Set up + `linelength'. + (html_printer::add_to_sbuf): Remove special handling of character + code 255. + (to_unicode): Remove `stop()'. + (html_printer::write_title): Cleanup. + (html_printer::begin_page): Use `put_string()'. Handle indentation. + (html_printer::~html_printer): Flush text and end the line. + Use `put_string()'. + * src/devices/grohtml/html_text.h: Add more *_TAG enum values. + * src/devices/grohtml/html_text.cc (html_text::end_tag): Fix + emission of tags. + (html_text::start_tag): Disable newlines. + (html_text::table_is_void): New function. + (html_text::issue_table_begin): Ditto. + (html_text::issue_table_end): Ditto. + (html_text::push_para): Better table handling. + (html_text::do_indent): New function. + (html_text::do_table): Ditto. + (html_text::done_table): Ditto. + (html_text::do_tt): Handle PRE_TAG. + (html_text::is_in_table): New function. + (html_text::check_emit_text): Handle tables. + (html_text::do_emittext): Use `nl()'. + (html_text::do_para): Handle table. + (html_text::remove_def): New function. + * src/devices/grohtml/output.cc (word, word_list): Implement + methods. + (simple_output::end_line): Flush last word. + (simple_output::simple_comment): Ditto. + (simple_output::begin_comment): Recoded. + (simple_output::end_comment): Ditto. + (simple_output::comment_arg): Removed. + (simple_output::check_newline): Improve test and flush last word. + (simple_output::space_or_newline): Improved. + (simple_output::write_newline): Replaced with... + (simple_output::nl): This. + (simple_output::put_raw_char): Flush last word. + (simple_output::check_space): Removed. + (simple_output::put_translated_string): Ditto. + (simple_output::put_string): Simplified. + (simple_output::put_number): Updated. + (simple_output::put_float): Ditto. + (simple_output::put_symbol): Removed. + (simple_output::enable_newlines): Add `check_newline()'. + (simple_output::flush_last_word): New function. + + * src/roff/troff/enc.cc (no_fill): Remove call to add_html_tag(). + * src/roff/troff/div.cc (page_offset): Add call to add_html_tag(). + + * tmac/s.tmac (@PP, @IP): Add html conditional code. + * tmac/an-old.tmac (TP): Ditto. + +2001-03-09 Ruslan Ermilov + + * mdate.sh: Make it POSIX compliant. + +2001-03-09 Werner LEMBERG + + Added the `return' request to end a macro immediately. It simply + pops iterators from the input stack until a macro iterator is found. + + * src/roff/troff/input.cc (input_iterator::is_macro, + macro_iterator::is_macro): New member. + (input_return_boundary): New class to signal an immediate return + to while_request(). + (input_stack::add_return_boundary, input_stack::is_return_boundary): + New functions. + (input_stack::clear): Use it. + (input_stack::pop_macro): New function. + (while_request): Use `is_return_boundary()'. + (return_macro_request): New function. + (init_input_requests): Use it. + + * src/roff/troff/TODO: Updated. + * NEWS, src/roff/troff/troff.man, man/groff.man: Document it. + +2001-03-08 Werner LEMBERG + + * src/roff/troff/input.cc (input_iterator::is_boundary): Minor + cleanup. + +2001-03-07 Werner LEMBERG + + Make `\B' more rigid. + + * src/roff/troff/number.cc (parse_expr, parse_term): Add `rigid' + parameter. + (get_number_rigidly): New function. + * src/roff/troff/input.cc (do_expr_test): Use it. + * src/roff/troff/token.h: Updated. + + * src/roff/troff/request.h: Fix typo (init_html_request -> + init_markup_request). + +2001-03-04 Gaius Mulley + + Fixed grohtml handling of any named glyph for glyph indexes < 0x80. + Cosmetic changes to `.html-begin', `.html-end', `.html-image' which + are now `.begin', `.end', `.image'. + + * src/devices/grohtml/post-html.cc: Adding UNICODE_DESC_START. + (html_printer::add_to_sbuf): Changing type of `code' parameter. + Use add_char_to_sbuf(). + (to_unicode): New function. + (char_translate_to_html): Changing type of `ch' parameter. + Use `to_unicode()'. + (html_printer::~html_printer): Comment out doctype string. + * src/preproc/html/pre-html.cc (write_end_image): Use `.end' + instead of `.html-end'. + (write_start_image): Use `.begin' and `.image' instead of + `.html-begin' and `.html-image'. + * src/roff/troff/input.cc: Rename `html_level' to `begin_level'. + (html_begin): Renamed to ... + (begin): This. + (html_end): Renamed to ... + (end): This. + (html_image): Renamed to ... + (image): This. + (init_html_requests): Renamed to ... + (init_markup_requests): This. + * tmac/www.tmac: Updated. + +2001-02-28 Bram + + * src/libs/libgroff/font.cc (font_widths_cache): Fixing syntax of + constructor. + +2001-02-26 David Leonard + + * doc/meref.me: Fixing some typos. + +2001-02-16 Werner LEMBERG + + * src/roff/troff/node.cc (space_node::get_hyphenation_type): New + method. Return `HYPHEN_MIDDLE' if it was `\:'. + * src/roff/troff/node.h: Updated. + +2001-02-17 Ruslan Ermilov + + * tmac/groff_tmac.man: Fix typo. + +2001-02-16 Werner LEMBERG + + Fixing a bug which prevented proper end-of-sentence recognition + between an `unformatted' box and the following text. As a + consequence, vertical line distances are no longer preserved in + boxes after a call to `.unformat' -- because boxes aren't + line-oriented (contrary to diversions), this doesn't make sense + anyway. + + * src/roff/troff/node.cc (*node::set_unformat_flag): Add return + value. + (vertical_size_node::set_unformat_flag): New method. + * src/roff/troff/node.hh: Updated. + * src/roff/troff/input.cc (word_space_node::reread, + hmotion_node::reread): Reset `unformat' flag after usage. + (unformat_macro): Append only if `set_unformat_flag()' returns + non-zero. + * src/roff/troff/troff.man: Updated. + +2001-02-15 Werner LEMBERG + + * src/roff/troff/troff.man, NEWS, man/groff.man: Improved + documentation of `asciify' and `unformat' requests. + +2001-02-13 Werner LEMBERG + + Redesigned the `unformat' request. It is no longer connected with + `asciify' but rather uses new `reread()' methods if the `unformat' + flag is set. Additionally, the handling of space characters after + unformatting has been fixed so that they retain their width. + + * src/roff/troff/node.h (width_list): New structure to store + original widths of spaces. + (node): Added `unformat' member. + Replaced `num_spaces' variable with `orig_width' list. + * src/roff/troff/node.cc (*node::asciify, + asciify_reverse_node_list): Removed `unformat_only' flag and related + code. + (word_space_node::asciify, word_space_node::word_space_node): Use + `orig_width'. + (word_space_node::~word_space_node): New destructor. + (word_space_node::copy): Updated to handle `orig_width'. + (hmotion_node::copy, unbreakable_space_node::copy): Updated. + (*node::merge_space): Update `orig_width' list if necessary. + (*node::set_unformat_flag): New methods to set the `unformat' flag. + * src/roff/troff/enc.cc (environment::space_newline): Use + `width_list'. + (environment::space): Added method to handle space width and + sentence space width as parameters. Use `width_list'. + (environment::make_tab_node): Updated. + * src/roff/troff/env.h: Updated. + * src/roff/troff/input.cc (word_space_node::reread, + unbreakable_space_node::reread, hmotion_node::reread): New methods + to handle nodes specially if `unformat' flag is set. + (do_asciify_macro): Renamed back to ... + (asciify_macro): This. + (unformat_macro): New implementation to simply set the `unformat' + flag. + + * MORE.STUFF: Added more info about deroff. + +2001-02-08 Werner LEMBERG + + * src/roff/troff/node.h (unbreakable_space_node, hmotion_node, + space_char_hmotion_node, overstrike_node): Add `get_hyphen_list()' + and `add_self()' methods to avoid hyphenation. For example, the + hyphen list for `foo\0\0bar' was `foobar', causing insertion of a + soft hyphen after `foo'. Now the hyphen list is correctly + `foobar'. + +2001-02-05 Yoshiteru Kageyama + + * tmac/groff_tmac.man: Fix `BIR' macro. + +2001-02-04 Werner LEMBERG + + A new escape sequence `\:', inserting a zero-width break point. + + * src/roff/troff/input.h: Adding `ESCAPE_COLON'. + * src/roff/troff/input.cc (get_copy, token::next, asciify): + Implement it. + * src/roff/troff/node.h (node): Add `is_escape_colon()' virtual + method. + (space_node): Add `was_escape_colon' member. Add `is_escape_colon()' + and `asciify()' methods. + * src/roff/troff/node.cc (space_node::space_node): Updated. + (space_node::asciify): Handle `was_escape_colon'. + * NEWS, src/roff/troff/troff.man, man/groff.man: Document it. + + Handle `\~' similar to other comparable requests. + + * src/roff/troff/input.cc (process_input_stack): Remove now obsolete + label. + (token::next): Move creation of an unbreakable_space_node to... + (token::add_to_node_list): Here. + + Fix a bug which sometimes prevented hyphenation of words connected + with `\~' or `\ ' (and other escape sequences handled as + TOKEN_NODE). This also fixes a hyphenation problem with boxes + (after a call to the `unformat' request). + + * src/roff/troff/env.h (environment::possibly_break_line, + environment::hyphenate_line): Introducing `start_here' parameter. + * src/roff/troff/env.cc (environment::space_newline, + environment::space): Use it. + (environment::possibly_break_line, environment::hyphenate_line): + Implement it. + * src/roff/troff/input.cc (process_input_stack): Use it. + * src/roff/troff/node.h (unbreakable_space_node, hmotion_node, + space_char_hmotion_node, overstrike_node): Add + `get_hyphenation_type()' method. + * src/roff/troff/node.cc (break_char_node::asciify): Don't asciify + if `unformat_only' is active. + +2001-01-30 Werner LEMBERG + + Implemented new read-only number register `.linetabs' which + returns 1 if in line-tabs mode, 0 otherwise. + + * src/roff/troff/env.h (environment): Add get_line_tabs() member. + * src/roff/troff/env.cc (get_line_tabs): New function. + (init_env_requests): Use it. + * NEWS, src/roff/troff/troff.man, man/groff.man: Document it. + + * VERSION, REVISION: Changing to 1.17.0. + +2001-01-28 Werner LEMBERG + + Fixed a bug which prevented hyphenation of words which are finished + with `\)'. + + * src/roff/troff/token.h (token): Add enum type + `TOKEN_TRANSPARENT_DUMMY' and method `transparent_dummy()'. + * src/roff/troff/input.cc (token::next, token::description, + get_line_arg, token::add_to_node_list, token::process): Use it. + +2001-01-27 Werner LEMBERG + + * src/roff/troff/div.h (diversion): Add `saved_prev_line_interrupted'. + * src/roff/troff/div.cc (do_divert): Use it. + + * src/roff/troff/input.cc (asciify): Add ESCAPE_RIGHT_PARENTHESIS. + +2001-01-25 Werner LEMBERG + + Adding the `linetabs' request. If set, tab distances are not + computed relative to the input line but relative to the output line. + + * src/roff/troff/env.h (environment): New member `line_tabs'. + * src/roff/troff/env.cc (line_tabs_request): Implement request. + (environment::environment, environment::copy): Updated. + (environment::distance_to_next_tab): Use `line_tabs'. + (init_env_requests): Register request. + * src/roff/troff/troff.man, man/groff.man, NEWS: Document it. Other + fixes. + +2001-01-24 Werner LEMBERG + + Introducing a new read-only register `.int' which is set to a + positive value if the last output line is interrupted (i.e., if it + contains `\c'). + + * src/roff/troff/env.cc (init_env_requests): Add it. + * NEWS, src/roff/troff/troff.man, man/groff.man: Document it. + +2001-01-23 Gaius Mulley + + * tmac/mwww.tmac: Call `www.tmac', not `arkup.tmac'. + * src/preproc/html/pre-html.cc (findPrefix): New function which + generates the troff executable name via the system prefix. + * src/preproc/eqn/main.cc: Modified warning message. + +2001-01-23 Werner LEMBERG + + troff's `box' and `boxa' requests didn't preserve temporary + indentation. + + * src/roff/troff/div.h (diversion): Add `saved_saved_indent' and + `saved_target_text_length' members. + * src/roff/troff/div.cc (do_divert): Use them. + + Tabs (but not yet leaders and fields) are now handled correctly by + `asciify' request. + + * node.h (hmotion_node): Add field `was_tab'. + * env.cc (environment::make_tab_node): Set it. + * node.cc (hmotion_node::copy, hmotion_node::asciify): Use it. + + Added new request `unformat' which will, contrary to `asciify', + preserve font information after unformatting (i.e., only nodes + dealing with horizontal space are converted back to input + characters). + + * input.cc (asciify_macro): Renamed to ... + (do_asciify_macro): this, having a new parameter `unformat_only'. + (asciify_macro, unformat_macro): New; using do_asciify_macro. + (init_input_requests): Added `unformat'. + * node.cc (*_node::asciify), asciify_reverse_node_list: Added + parameter to control asciification process. + * node.h (*_node::asciify): Ditto. + * NEWS, src/roff/troff/troff.man, man/groff.man: Document it. + +2001-01-20 Werner LEMBERG + + * doc/groff.texinfo: Minor improvement of `.in' documentation. + +2001-01-18 Werner LEMBERG + + * tmac/ps.tmac: Remove call of psold.tmac. + * tmac/psold.tmac: Comment updated. + * tmac/psnew.tmac: Removed since no longer needed. + * tmac/Makefile.sub, NEWS, src/devices/grops/grops.man: Updated. + + * font/devutf8/R.proto: Adding `shc' glyph. + * font/devutf8/NOTES: Updated. + + * test-groff: Updated. + +2001-01-15 Gaius Mulley + + First cut of the new html device driver. Changes to pre-html and + the new grohtml are too numerous to be documented here. + + Stuff related to `html' has been renamed to `html-old' and `html2' + stuff has been renamed to `html' (including directories). The new + html device driver is therefore invoked as `-Thtml'. + + Added new `\O' escape to suppress output (needed by html driver). + + Added functions and code to pass info about input-level commands + (`.in', `.fl', etc.) to html driver. + + Three new functions (.html-begin, .html-end, and .html-image) for + better html handling: `html-begin' will execute the remaining line + if at the outermost nesting level, increasing an internal counter. + `html-end' does the same but decreases the internal counter. + `html_image' puts its arguments into a special node (suppress_node) + to define an image region. + + The `output' request has been removed. + + * tmac/html-tags.tmac: Removed. + * tmac/arkup.tmac: Updated and renamed to ... + * tmac/www.tmac: New file. + * tmac/markup.tmac Updated and renamed to ... + * tmac/mwww.tmac: New file. + * tmac/Makefile.sub: Updated. + * tmac/an-old.tmac: Updated. + * tmac/eqnrc: Updated. + * tmac/groff_man.man + * tmac/groff_markup.man: Updated and renamed to ... + * tmac/groff_mwww.man: New file. + * tmac/groff_tmac.man: Updated. + * tmac/html-old.tmac: Updated and Renamed from html.tmac. + * tmac/html.tmac: Updated and renamed from html2.tmac. + * tmac/pspic.tmac: Updated html support. + * tmac/s.tmac: Added html output support. + * tmac/troffrc, tmac/troffrc-end: Updated. + + * Makefile.in, doc/Makefile: Updated. + * doc/groff.texinfo: Added info about new `\O' escape. + * doc/homepage.ms: Use `MAILTO' macro. + + * font/devhtml/DESC.proto: Add `C' font. + * font/devhtml/Makefile.sub: Updated. + * font/devhtml/R.proto: Minor fixes. + * font/devhtml-old/Makefile.sub: Updated. + + * src/devices/grohtml-old/Makefile.sub: Updated. + + * src/libs/libdriver/printer.cc (printer::get_font_from_index): New + method. + * src/libs/libgroff/htmlindicate.cc (html_begin_suppress, + graphic_start): Add `inline' parameter. Update. + (html_end_suppress, graphic_end): Update. + + * src/include/html-strings.h: New file. + * src/include/htmlindicate.h: Comments updated. + * src/include/printer.h: Updated. + + * src/preproc/eqn/main.cc (do_file, main): Updated. + * src/preproc/pic/troff.cc (troff_output::start_picture, + troff_output::finish_picture): Updated. + * src/preproc/tbl/main.cc (process_input_file): Updated. + + * src/roff/groff/groff.cc (main): Updated. + Pass device arguments to predrivers also. + Use `ps' device for `eqn' preprocessor if `-Thtml' is given. + * src/roff/troff/env.h (environment): Updated. + New elements `need_eol' and `ignore_next_eol' (for html output). + * src/roff/troff/env.cc (environment::environment): Add initializers + for `need_eol' and `ignore_next_eol'. + (environment::add_html_tag_eol, environment::add_html_tag_tabs): New + functions. + (point_size, fill, no_fill, center, right_justify, line_length, + indent, temporary_indent, break_request, handle_tab): Use + `add_html_tag()'. + (set_tabs): Use `add_html_tag_tabs()'. + (environment::add_html_tag): Updated. + (environment::do_break): Updated. + * src/roff/troff/div.cc (space_request, flush_output): Use + `environment::add_html_tag()'. + * src/roff/troff/input.cc: Updated. + New variable `html_level' to indicate nested `html-begin' requests. + (file_iterator::fill): Use `environment::add_html_tag_eol()'. + (non_interpreted_char_node, token_node, non_interpreted_node): Add + `force_tprint()' method. + (token::next): Handle `\O'. + (do_suppress): Implement it. + (html_begin, html_end, html_image): New functions. + (init_output_requests): Renamed to ... + (init_html_requests): this. + (main): Use it. + (macro::append_str, macro::append_unsigned, macro::append_int): New + methods. + New variable `output_low_mark_miny' to limit minimal value of y. + (reset_output_registers): Use it. + (output_request): Removed. + (get_output_registers): New function. + * src/roff/troff/node.h (node): Make `force_tprint()' virtual. + (*_node): Added `force_tprint()' if necessary. + (special_node): New elements `tf' and `get_tfont()'. + (suppress_node): New class. + * src/roff/troff/node.cc: + New global variables `image_no' and `suppress_start_page'. + (real_output_file): New method `is_on()'. + (troff_output_file): New method `start_special(tfont)'. + (troff_output_file::really_print_line): Use `tprint' conditionally. + (real_output_file::print_line): Updated. + (real_output_file::on): Updated. + (*_node): Added `force_tprint()'. + (special_node::special_node): Initializer updated. + (special_node::same, special_node::copy, special_node::tprint_start): + Updated. + (get_reg_int, get_reg_str): New functions. + (suppress_node::*): New methods. + New global variables last_position, last_image_filename; + (min): New inline function. + * src/roff/troff/reg.h, src/roff/troff/request.h, + src/roff/troff/troff.h: Updated. + +2001-01-13 Werner LEMBERG + + * NEWS, src/roff/troff/troff.man, doc/groff.texinfo: Fix + documentation of `asciify' request. + +2001-01-12 Werner LEMBERG + + * src/roff/troff/input.cc: Move definition of special characters + like `ESCAPE_TILDE' to ... + * src/roff/troff/input.h: New file. + * src/roff/troff/Makefile.sub (HDRS): Add it. + + Extending the .asciify request to `unformat' space characters also. + + * src/roff/troff/node.h (word_space_node): Add `num_spaces' element + to count input space characters. + Update constructors to take care of it. + * src/roff/troff/node.cc (space_char_hmotion_node::asciify): Use + `ESCAPE_SPACE' instead of normal space. + (word_space_node::asciify): New method. + (unbreakable_space_node::asciify): New method. + (word_space_node::merge_space): New method. + * src/roff/troff/env.cc (environment::space_newline, + environment::space): Add code to initialize `num_spaces' (using the + constructor of `word_space_node'). + * NEWS, src/roff/troff/troff.man, man/groff.man, doc/groff.texinfo: + Document it. + +2001-01-09 Werner LEMBERG + + * man/groff_char.man: Use table header traps only conditionally. + +2001-01-09 Bjarni Ingi Gíslason + + * man/groff_char.man: Add `ý' and `Ý' to the `acute' group. + +2001-01-08 Werner LEMBERG + + Introducing the `box' and `boxa' requests which are similar to + `di' resp. `da' but omitting a partially filled line (which is + restored after ending the diversion). + + * src/roff/troff/div.h (diversion): Add elements to save partially + filled line. + * src/roff/troff/div.cc (do_divert): Add parameter `boxing' to save + partially filled line. + (divert, divert_append): Updated. + (box, box_append): New functions. + (init_div_requests): Use them. + * src/roff/troff/env.h (environment): do_divert() is now a friend. + * NEWS, src/roff/troff/troff.man, man/groff.man: Document it. + + * doc/groff.texinfo: Fix documentation of `lf' request. + +2000-12-25 Werner LEMBERG + + * src/roff/troff/troff.man, NEWS: Document `writem' request. + +2000-12-21 Werner LEMBERG + + Ignore `ss' request if in compatibility mode. + + * src/roff/troff/input.cc: Make `compatible_flag' non-static. + * src/roff/troff/env.h: Added extern `compatible_flag' declaration. + * src/roff/troff/env.cc (space_size): Use it. + + * doc/groff.texinfo, src/roff/troff/troff.man: Fix documentation of + `ss' request in nroff mode. + + * tmac/an-old.tmac: Fixed some serious bugs introduced with latest + changes. + +2000-12-15 Ruslan Ermilov + + * tmac/troffrc, tmac/troffrc-end: Convert tmac.* to *.tmac. + +2000-12-13 Werner LEMBERG + + * src/preproc/eqn/Makefile.sub (MAN1): Added neqn.man. + * src/preproc/eqn/neqn.man: Small fixes and additions. + +2000-12-13 Ruslan Ermilov + + * src/utils/addftinfo/addftinfo.man, src/devices/grops/grops.man: + Fixing typo. + + * src/preproc/eqn/neqn.man: New file. + + * src/preproc/tbl/table.cc (table::print): Fix `indent cannot be + negative' warning. + + * tmac/e.tmac: Add `T&' macro. + Fix `indent cannot be negative' warning. + * tmac/s.tmac: Fix `indent cannot be negative' warning. + +2000-12-07 Werner LEMBERG + + * src/include/lib.h: Replaced __ALPHA with __alpha symbol. + +2000-12-06 Werner LEMBERG + + * PROBLEMS: Added info about adding -lPW on HP-UX to satisfy the + `alloca' symbol . + + * MORE.STUFF: Added info about deroff for djgpp. + + * tmac/an-old.tmac, tmac/groff_man.man, doc/groff.texinfo, NEWS: Fix + documentation of -rcR switch. + +2000-12-03 Werner LEMBERG + + * tmac/an-old.tmac: Implementing the -rcR switch (similar to mdoc); + if -rcR=1 (which is now the default in nroff mode), a single, very + long page is created instead of multiple pages: All `ne' and `wh' + requests are put into conditionals; a new macro `an-end' is added to + be called with `em'. + + Some other minor cleanups. + + * NEWS, tmac/groff_man.man, doc/groff.texinfo: Updated. + +2000-12-02 Werner LEMBERG + + Fixing a bug which prevented hyphenation in words followed + immediately by a TOKEN_NODE (e.g. `\ ', `\~', etc.). + + * src/roff/troff/input.cc (process_input_stack ): + Adding possibly_break_line(). + * src/roff/troff/env.h (environment): Make possibly_break_line() + public. + + Make `\~' usable in .tr request. + + * src/roff/troff/token.h (token_type): Add TOKEN_STRETCHABLE_SPACE. + (token): Add stretchable_space(). + * src/roff/troff/input.cc (token::next, token::delimiter, + token::description, process_input_stack, do_translate, + add_to_node_list, token::process): Use it. + * src/roff/troff/node.h (node): Add fourth parameter to add_char() + for adjusting the space. + * src/roff/troff/node.cc (node::add_char): Implement it. Add code + for stretchable space. + * src/roff/troff/input.cc (token::add_to_node_list): Use it. + (make_node): Add code for stretchable space. + * src/roff/troff/env.cc (environment::add_char): Use it. + * src/roff/troff/input.cc: Add ESCAPE_TILDE special character. + (get_copy, token::next, transparent_translate, asciify): Use it. + + * NEWS, src/roff/troff/troff.man, src/roff/troff/TODO, + doc/groff.texinfo: Updated. + * man/groff.man: Small reorderings. + +2000-11-23 Werner LEMBERG + + * NEWS: Fixes. + * src/preproc/eqn/main.cc (main): Use `config_macro_path' for -M + option. + * src/roff/troff/input.cc (main): Add `config_macro_path' and + `safer_macro_path' to -M option. + * src/roff/troff/troff.man: Fixes. + +2000-11-22 Werner LEMBERG + + Use safer path (except for config files) if -U isn't specified. Add + a special macro path (without home and current directory) for config + files. Add home directory to unsafe path for consistency. Don't + include the home directory in the font path. + + * src/libs/libgroff/macropath.cc: Add `config_macro_path', change + `macro_path'. + * src/include/macropath.h: Add `config_macrp_path'. + * src/libs/libgroff/fontfile.cc: Fix font path. + * src/roff/troff/input.cc (process_startup_file): Use + `config_macro_path'. + (main): Select unsafe path if -U is given. + + * src/preproc/eqn/main.cc (main): Fixing search path for + configuration file. + * src/preproc/eqn/eqn.man: Updated. + + * src/roff/troff/troff.man, man/roff.man, tmac/groff_tmac.man: + Updated. + + * src/preproc/grn/grn.man, src/devices/grodvi/grodvi.man, + src/devices/grohtml/grohtml.man, src/devices/grolbp/grplbp.man, + src/devices/grolj4/grolj4.man, src/devices/grops/grops.man, + src/devices/grotty/grotty.man: Updated. + + * Makefile.in: Fix comments. + +2000-11-17 Werner LEMBERG + + * tmac/safer.tmac: Empty file added (again) for compatibility + reasons. + * tmac/Makefile.sub: Updated. + +2000-11-16 Werner LEMBERG + + * src/devices/grodvi/dvi.cc (main), + src/devices/grohtml2/post-html.cc (main), + src/devices/grolbp/lbp.cc (main), src/devices/grolj4/lj4.cc + (main), src/devices/grops/ps.cc (main), src/devices/grotty/tty.cc + (main), src/preproc/eqn/main.cc (main), src/preproc/grn/main.cc + (main), src/preproc/html2/pre-html.cc (main), + src/preproc/pic/main.cc (main), src/preproc/refer/refer.cc (main), + src/preproc/soelim/soelim.cc (main), src/preproc/tbl/main.cc + (main), src/roff/groff/groff.cc (main), src/roff/troff/input.cc + (main), src/utils/hpftodit/hpftodit.cc (main), + src/utils/indxbib/indxbib.cc (main), src/utils/lkbib/lkbib.cc + (main), src/utils/lookbib/lookbib.cc (main), + src/utils/pfbtops/pfbtops.c (main), src/utils/tfmtodit/tfmtodit.cc + (main): Use stdout for -v. + * src/roff/groff/groff.cc (run_commands), + src/roff/groff/pipeline.c (run_pipeline): New parameter `no_pipe' + to make direct printing to stdout possible. + * src/roff/groff/pipeline.h: Updated. + + * src/utils/afmtodit/afmtodit.pl: Add -v switch. + * src/utils/afmtodit/Makefile.sub (afmtodit): Use @VERSION@. + * src/utils/afmtodit/afmtodit.man: Updated. + + * src/utils/addftinfo/addftinfo.cc (main): Add -v switch. + (version): New function. + (usage): Updated. + * src/utils/addftinfo/addftinfo.man: Updated. + + * src/devices/*/*, src/preproc/*/*, src/roff/*/*, src/utils/*/*: + Fixing copyright dates. + + * src/preproc/eqn/neqn.sh: Adding GROFF_BIN_PATH to path instead of + replacing it. + + * src/devices/grolbp/lbp.cc (main): Use Version_string instead of + version_string. + + * src/roff/nroff/Makefile.sub (nroff): Fix use of @VERSION@. + +2000-11-15 Werner LEMBERG + + In all programs, make -v return immediately with exit status 0 to + be compliant with the GNU standard. + + * src/devices/grodvi/dvi.cc (main), + src/devices/grohtml2/post-html.cc (main), + src/devices/grolbp/lbp.cc (main), src/devices/grolj4/lj4.cc + (main), src/devices/grops/ps.cc (main), src/devices/grotty/tty.cc + (main) src/preproc/eqn/main.cc (main), src/preproc/grn/main.cc + (main), src/preproc/html2/pre-html.cc (main), + src/preproc/pic/main.cc (main), src/preproc/refer/refer.cc (main), + src/preproc/soelim/soelim.cc (main), src/preproc/tbl/main.cc + (main), src/roff/groff/groff.cc (main), src/roff/troff/input.cc + (main): Implement it. + * NEWS: Updated. + + * src/roff/groff/groff.cc (main): Add copyright notice. Add refer + and postprocessors to the -v option. + + * src/roff/grog/grog.pl: Implement -v. + * src/roff/grog/Makefile.sub (grog): Use @VERSION@. + * src/roff/grog/grog.man, doc/groff.texinfo: Updated. + + * src/roff/nroff/nroff.sh: Implement -v. + * src/roff/nroff/Makefile.sub (nroff): Use @VERSION@. + * src/roff/nroff/nroff.man: Updated. + + * src/preproc/eqn/main.cc (main): Fix comment typo. + + * MORE.STUFF: Added info about djgpp port of grap. + +2000-11-14 Werner LEMBERG + + * src/roff/grog/grog.{pl,sh}: Implemented -C switch for compatibility + mode (or rather, implemented non-compatibility mode). + * NEWS, src/roff/grog/grog.man, doc/groff.texinfo: Updated. + + * src/roff/groff/groff.cc (main): Add BIN_PATH to PATH instead of + replacing it -- we don't find gxditview otherwise. + * NEWS, src/roff/groff/groff.man, doc/groff.texinfo: Updated. + + * src/preproc/pic/depend: Removed. Unnecessary. + + Implemented dummy keyword `solid' in pic for compatibility with + AT&T pic. + + * lex.cc (lookup_keyword): Added `solid'. + * pic.y: Added SOLID with dummy rule. + * pic.cc, pic_tab.h: Regenerated. + * doc/pic.ms: Updated. + +2000-11-13 Werner LEMBERG + + For security reasons, don't use the current directory but the home + directory while searching and scanning troffrc and troffrc-end. + Similarly, replace the current directory with the home directory + in the font path. + + * Makefile.in (fontpath, tmacpath): Remove current directory. + + * src/libs/libgroff/searchpath.cc (search_path::search_path): Add + two parameters `add_home' and `add_current'. + (search_path::~search_path, search_path::command_line_dir, + search_path::open_file): Remove tests for `dirs' being zero. + * src/include/searchpath.h: Adjust. + * src/libs/libgroff/macropath.cc, src/include/macropath.h: Add + `safer_macro_path'. + * src/libs/libgroff/fontfile.cc: Adjust `font_path'. + + * src/roff/troff/troff.h: Add `searchpath.h' and `mac_path'. + * src/roff/troff/input.cc: Use `mac_path', initialized with + `macro_path'. + (process_startup_file): Set `mac_path' to `safer_macro_path'. + * src/roff/troff/env.cc: Use `mac_path'. + + * src/preproc/eqn/main.cc (main): Use `safer_macro_path'. + + * NEWS, man/roff.man, src/roff/troff/troff.man, + src/roff/groff/groff.man, tmac/groff_tmac.man, arch/djgpp/README: + Updated. + +2000-11-12 Werner LEMBERG + + * src/include/lib.h: Don't include groff-getopt.h for OSF/1. + + * aclocal.m4 (GROFF_SYS_ERRLIST): Do test in C, not in C++. + * configure.in: Fix typo in comment. + * configure: Regenerated. + + * src/libs/libgroff/*, src/include/*, src/roff/troff/*: Fixing + copyright dates. + +2000-11-08 Werner LEMBERG + + Add system tmac directory (/usr/local/lib/groff/site-tmac). + + * Makefile.in: Add $(libdir), $(libprogramdir), and $(systemtmacdir). + (uninstall_dirs): Add $(libdir), $(libprogramdir), and + $(systemtmacdir). + Use @libdir@. + * Makefile.comm (.man.n): Add @SYSTEMMACRODIR@. + * tmac/Makefile.sub (install_data): Create + $(systemtmacdir) and $(localtmacdir). + (uninstall_sub): Use $(systemtmacdir) for wrapper macros. + * man/roff.man, src/roff/troff/troff.man, src/roff/groff/groff.man, + NEWS, doc/groff.texinfo: Updated and minor fixes. + + * Makefile.comm, Makefile.in: Added tmac_{s,an}_prefix stuff again. + * tmac/Makefile.sub: Added `wrap' stuff again, but installing into + $(systemtmacdir) since the wrapper files are platform-dependent. + +2000-11-01 Werner LEMBERG + + * doc/groff.texinfo: Fix typo. + +2000-10-26 Werner LEMBERG + + Convert macros `tmac.XXX' to `XXX.tmac'. Special cases: + tmac.doc.old -> doc-old.tmac + tmac.an.old -> an-old.tmac + + * tmac/tmac.*: Moved to ... + * tmac/*.tmac: this. + * tmac/man.local: Fix comment. + * tmac/groff_man.man, tmac/groff_markup.man, tmac/groff_mdoc.man, + tmac/groff_me.man, tmac/groff_ms.man, tmac/groff_tmac.man: Updated. + Added some `FILES' sections. More use of @...@ directives. Other + minor updates. + * arch/djgpp/README, font/devutf8/NOTES: Updated. + * doc/homepage.ms, doc/groff.texinfo: Updated. + * man/groff.man, man/roff.man: Updated. + * src/devices/grodvi/grodvi.man, src/devices/grolbp/grolbp.man, + src/devices/grolj4/grolj4.man, src/devices/grops/grops.man, + src/devices/grotty/grotty.man: Updated. + * src/preproc/pic/pic.man: Updated. + * src/roff/grog/grog.pl, src/roff/grog/grog.sh: Use -mdoc-old + instead of -mdoc.old. + * src/roff/grog/grog.man: Document -mdoc and -mdoc-old. + * src/roff/nroff/nroff.man: Updated. + * NEWS: Updated. + + * tmac/fixmacros.sed, tmac/strip.sed: Add explanatory comment. + + * tmac/mm.diff: Removed -- it has no use now since the mm package + is part of groff. + + * tmac/*: Removed trailing spaces. + + * arch/djgpp/t-groff.bat: Fix GROFF_TMAC_PATH (hyphen.us is now in + the tmac subdirectory also). + + * Makefile.comm, Makefile.in: Remove tmac_{s,an}_prefix stuff. + * tmac/Makefile.sub: Adapted to new macro names; removed `wrap' + stuff since it is no longer needed. + + * README, PROBLEMS: Updated. + +2000-10-25 Werner LEMBERG + + Invert current behaviour: Search first FOOBAR.tmac, then + tmac.FOOBAR. + + * src/roff/troff/input.cc: Introduce MACRO_POSTFIX. + (open_mac_file, macro_source): Implement it. + * src/roff/troff/troff.man, tmac/groff_tmac.man, man/roff.man, + doc/groff.texinfo, NEWS: Document it. + + * src/roff/nroff/nroff.man, src/roff/groff/groff.man, man/groff.man: + Small documentation improvements. + + * test-groff: Fix GROFF_TMAC_PATH (hyphen.us is now in the tmac + subdirectory also). + + * font/devps/Makefile.sub: Fix rules for dingbats.*map. + +2000-10-24 Werner LEMBERG + + Add local tmac directory (groff/site-tmac). + + * Makefile.in: Add $(localtmacdir). + (uninstall_dirs): Add $(localtmacdir). + * Makefile.comm (.man.n): Add @LOCALMACRODIR@. + * tmac/Makefile.sub (install_data, uninstall_sub): Handle man.local + in $(localtmacdir). Create $(localtmacdir). + * man/roff.man, src/roff/troff/troff.man, NEWS, doc/groff.texinfo: + Updated and minor fixes. + + Rename font/devps/generate/dingbats[r]map to dingbats.[r]map. + + * font/devps/generate/Makefile.sub, arch/djgpp/README: Adjust. + +2000-10-23 Werner LEMBERG + + Move hyphen.us to tmac directory. + + * src/roff/troff/hyphen.us: Removed. + * src/tmac/hyphen.us: Added. + * src/roff/troff/Makefile.sub, tmac/Makefile.sub: Updated. + + Change installation structure for data files from .../groff/... to + .../groff//... to be conform with other GNU + programs. + + * Makefile.in, Makefile.comm, src/utils/indxbib/Makefile.sub, + doc/Makefile: Implement it. + * aclocal.m4 (GROFF_PAGE): Add test for new directory structure. + * configure: Updated. + * arch/djgpp/README, font/devutf8/NOTES: Use it. + * NEWS: Document it. + * man/roff.man, tmac/groff_tmac.man: Use @FONTPATH@, @FONTDIR@, and + @MACRODIR@ instead of hard-coded directories. + +2000-10-22 Werner LEMBERG + + Implement $GROFF_BIN_PATH environment variable (which defaults to + $bindir) used for child programs of groff and similar wrappers. + + * gendefs.sh: Improve documentation. + * Makefile.comm (,man.n), src/include/Makefile.sub (defs.h), + src/preproc/eqn/Makefile.sub (neqn), + src/roff/nroff/Makefile.sub (nroff): Add $(bindir). + * src/preproc/eqn/neqn.sh, src/roff/nroff/nroff.sh: Implement + $GROFF_BIN_PATH. + * src/roff/groff/groff.cc (main): Implement $GROFF_BIN_PATH and + $GROFF_PATH__ (the latter for communication with troff). + * src/roff/troff/input.cc (main): Use $GROFF_PATH__ for $PATH if + set. + * NEWS, src/roff/nroff/nroff.man, src/roff/groff/groff.man, + doc/groff.texinfo: Document it. + + * doc/groff.texinfo: Improve documentation of troff's -a option. + +2000-10-17 Gaius Mulley + + * src/roff/troff/node.cc: Fixed calculation of opminx and fixed + non-intrusive eol marker. + (troff_output_file::determine_line_limits): New function. + (troff_output_file::draw): Use it. + * src/roff/troff/env.cc (environment::add_html_tag): Use output() + + output_pending_lines() instead of output_line(). + * src/preproc/eqn/main.cc (do_file): Fix graphic_end(). + * src/preproc/html2/pre-html.cc (char_buffer::write_file_troff, + createImage): Small fixes. + +2000-10-14 Werner LEMBERG + + Replace tmac.safer with a real secure solution. + + * src/roff/troff/input.cc (open_request, opena_request, pipe_source, + system_request, pipe_output): Disable requests if in safer mode. + * src/roff/groff/groff.cc (main): Remove reference to tmac.safer. + * tmac/tmac.safer, tmac/groff_msafer.man: Removed. + * tmac/Makefile.sub, NEWS, man/roff.man, tmac/groff_tmac.man, + doc/groff.texinfo, src/roff/groff/groff.man, + src/roff/troff/troff.man, arch/djgpp/README: Updated. + + * src/devices/grops/ps.cc (main), src/devices/grops/psrm.cc + (resource_manager::output_prolog): Replace setenv() with putenv(). + +2000-10-09 Werner LEMBERG + + * src/libs/libbib/map.c, src/libs/libgroff/getcwd.c, + src/libs/libgroff/strtol.c, src/preproc/html2/image.cc, + src/preproc/html2/pre-html.cc, src/preproc/html2/pushbackbuffer.cc, + src/roff/groff/pipeline.c: Removing `#ifndef errno' to avoid + compilation errors with some compilers. It seems that this code + is no longer necessary -- if yes, it is easy to add some #ifdef's + for that particular old-fashioned compiler. + + * MORE.STUFF: Added info about Meta-tbl. + + * doc/groff.texinfo: Added more info about `.if "..."..."'. + +2000-10-07 Werner LEMBERG + + Adding a new escape sequence \B'...': If the string between + the delimiters is a valid numeric expression, return the character + `1', and `0' otherwise. This is an analogon to \A. + + * src/roff/troff/input.cc (do_expr_test): Implement it. + (token::next): Use it. + * src/roff/troff/troff.man, NEWS, man/groff.man: Document it. + + * tmac/tmac.trace: Made independent from escape character. + +2000-10-06 Werner LEMBERG + + Adding a new request .dei: define indirect. The first and second + parameter of .dei are taken from string registers instead directly; + this very special request is needed to make tmac.trace independent + from the escape character (which might even be disabled). + + * src/roff/troff/input.cc (do_define_macro): Implement it. + (define_macro_indirect): New function. + (init_input_requests): Use it. + + Adding two requests .ecs and .ecr: Save and restore the escape + character. These two requests are needed to make tmac.trace + independent from the escape character (which might even be + disabled). + + * src/roff/troff/input.cc (save_escape_char, restore_escape_char): + Implement it. + (init_input_requests): Use it. + + * src/roff/troff/troff.man, NEWS, man/groff.man: Updated. + +2000-09-22 Ricardo Soares Guimarăes + + Adding a new option -P and new environment variable GROPS_PROLOGUE + to grops, selecting a different prologue file (minor modifications + by WL). + + * src/devices/grops/psrm.cc (resource_manager::output_prolog), + src/devices/grops/ps.cc (main): Implement it. + * src/devices/grops/grops.man, NEWS: Document it. + +2000-09-22 Werner LEMBERG + + * INSTALL: Add info about selecting paper format. + +2000-09-21 Werner LEMBERG + + * src/roff/troff/input.cc (main): Fixing compiler warning. + * src/include/{driver.h, lib.h}: Move inclusion of string.h and + strings.h from the former to the latter. + * src/devices/grolbp/lpb.cc, src/include/lib.h: Move strncasecmp() + stuff from the former to the latter. + +2000-09-11 Werner LEMBERG + + Implementing two new requests .tm1 and .tmc: The former is similar + to .tm but can output leading spaces; its syntax is similar to + defining a string, i.e., a `"' can be used to mark the beginning of + the string to be written to stderr: `.tm1 " test'. The latter is + similar to .tm1 but doesn't write out a final newline character. + + * src/roff/troff/input.cc (terminal1, terminal_continue, + do_terminal): New functions. + (init_input_requests): Use them. + * src/roff/troff/troff.man, NEWS, man/groff.man: Updated. + +2000-09-09 Werner LEMBERG + + * tmac/groff_mdoc.samples.man: Small fixes. + +2000-09-08 Werner LEMBERG + + * tmac/groff_mdoc.man: Fixing typo. + +2000-09-02 Werner LEMBERG + + Implementing a .nop request which does nothing. + + * src/roff/troff/input.cc (nop_request): New function. + (init_input_requests): Use it. + * src/roff/troff/troff.man, NEWS, man/groff.man: Updated. + +2000-09-01 Werner LEMBERG + + * doc/groff.texinfo: Added some comments. + +2000-08-30 Werner LEMBERG + + * src/roff/troff/TODO: Updated. + +2000-08-25 Werner LEMBERG + + * doc/groff.texinfo: Fix comment how to compile the DVI file. + +2000-08-25 Eli Zaretskii + + * font/devps/generate/Makefile (SHELL): Define explicitly to + "/bin/sh", for non-Unix platforms. + (extraclean): Use a more portable "" quoting instead of a + backslash (which doesn't work on DOS/Windows). + + * font/devlj4/generate/Makefile (extraclean): Ditto. + + * font/devdvi/generate/Makefile (extraclean): Ditto. + +2000-08-25 Werner LEMBERG + + * NEWS, doc/groff.texinfo, tmac/groff_tmac.man, man/roff.man, + src/roff/troff/troff.man: Document Eli's latest changes. + +2000-08-25 Eli Zaretskii + + * src/roff/troff/input.cc (open_mac_file, macro_source): Support + macro file names of the form NAME.tmac as well as tmac.NAME. + +2000-08-25 Werner LEMBERG + + * src/include/posix.h: Remove definition of FILENAME_MAX. + + * src/preproc/html2/pre-html.h, pre-html.cc: Add return type to + `sys_fatal' and `stop' function(). + + * test-groff: Updated. + +2000-08-24 Gaius Mulley + + Added the new troff command .output to suppress output (while + still obeying motion) and also the opminx, opminy, opmaxx, opmaxy + registers (for passing the output dimensions to the output device). + + * src/roff/troff/div.cc (top_level_diversion::output): Use `width' + parameter. + * src/roff/troff/node.h, src/roff/troff/node.cc + (troff_output_file::really_print_line, + ascii_output_file::really_print_line, + supress_output_file::really_print_line): Use `width' parameter. + (troff_output_file::really_on, troff_output_file::really_off, + output_file::on, output_file::off, real_output_file::on, + real_output_file::off, real_output_file::really_on, + real_output_file::really_off): New functions. + (real_output_file:public output_file): New variable `output_on'. + (real_output_file::begin_page, real_output_file::copy_file, + real_output_file::transparent_char, real_output_file::print_line): + Use it. + (real_output_file::print_line): Use check_output_limits. + * src/roff/troff/reg.h, src/roff/troff/request.h, + src/roff/troff/input.cc (assign_registers): New function to remove + two `goto's. + (do_ps_file): Use it. + (check_output_limits, reset_output_registers, output_request, + init_output_requests): New functions. + (init_input_requests): Updated. + + Added new grohtml2 device and html2 preprocessor (coding + not yet finished) which will eventually replace grohtml. + + * Makefile.in, tmac/Makefile.sub, tmac/eqnrc, tmac/troffrc-end: + Updated. + * src/include/htmlindicate.h, src/include/htmlindicate + (html_begin_suppress, html_end_suppress): New functions. + * src/preproc/tbl/main.cc: Use it. + * src/roff/groff/groff.cc: Add support for html2 device (which will + automatically invoke the html2 preprocessor). + * src/roff/troff/input.cc (is_html2): New variable. + * src/roff/troff/troff.h, src/roff/troff/env.h, + src/roff/troff/env.cc (environment::add_html_tag): New function + (uses `is_html2'). + (environment::do_break): Use it. + * font/devhtml2/*: New files. + * src/devices/grohtml2: New device. + * src/preproc/html2: New preprocessor. + * tmac/tmac.html-tags, tmac/tmac.html2: New files. + +2000-08-23 Werner LEMBERG + + * src/devices/grolbp/lbp.cc: Same workaround for sinix as for AIX. + +2000-08-22 Werner LEMBERG + + * src/include/lib.h: Provide a fix for IRIX to not include + groff-getopt.h. + +2000-08-18 Werner LEMBERG + + * configure.in: Don't provide an empty value for SH_SCRIPT_SED_CMD + since some non-GNU sed programs can't handle null regexps. + * configure, src/preproc/eqn/Makefile.sub, + src/roff/grog/Makefile.sub, src/roff/nroff/Makefile.sub: Updated. + + * src/devices/grolbp/lbp.cc: Add an AIX workaround for an autoconf + bug (string.h and strings.h are both needed according to latest + POSIX standard). + + * MORE.STUFF: Added info about unroff and troffcvt. + +2000-08-08 Werner LEMBERG + + * tmac/tmac.a4: Will now work with ms macros also; -ma4 should be + used before -ms. + + * tmac/tmac.man.old: Remove unused number register. + + * tmac.doc: Minor documentation fix. + +2000-08-07 Paul Eggert + + * src/roff/groff/pipeline.c (is_system_shell): + Fix typo: "monocased_shell" no longer exists. + +2000-08-07 Paul Eggert + + Remove FILENAME_MAX limits. + + * src/roff/groff/pipeline.c (is_system_shell): Do not assume + that the argument length is less than FILENAME_MAX. + * src/libs/libgroff/tmpfile.cc (add_tmp_file): Likewise. + Use struct hack to allocate and free file name. + (struct xtmpfile_list): fname is now part of the structure, + not a pointer to another string. + +2000-08-07 Tom Schmidt + + * src/include/posix.h: Add a default value for FILENAME_MAX. + +2000-08-06 Paul Eggert + + Add support for new BSD-style man pages (with ".Dd" instead of + ".TH"), so that "groff -man" understands both styles, even + when running "groff -man" on a host whose system man page + macros don't support ".Dd". + + * tmac/Makefile.sub (NORMALFILES): Add tmac.an.old. + (stamp-wrap): Source tmac.andoc first when wrapping man macros, + in case the system man macros don't define Dd or TH. + + * tmac/tmac.an.old: Renamed from tmac/tmac.an. + * tmac/tmac.an: New one-line file. + * tmac/tmac.andoc (TH): Adjust to the tmac.an.old file renaming. + +2000-08-06 Werner LEMBERG + + * src/roff/troff/troff.man: Fixing typos. + +Copyright 2000-2001 Free Software Foundation, Inc. + +Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. + +Local Variables: +coding: latin-1 +fill-column: 72 +mode: change-log +version-control: never +End: +vim:set autoindent textwidth=72: diff --git a/ChangeLog.118 b/ChangeLog.118 new file mode 100644 index 0000000..a87d02c --- /dev/null +++ b/ChangeLog.118 @@ -0,0 +1,3803 @@ + +Version 1.18.1 released +======================= + +2002-10-08 Werner LEMBERG + + * doc/webpage.ms, NEWS: Updated. + +2002-10-07 Werner LEMBERG + + * tmac/doc-common (Ss): Add final `.ns' (similar to `.Sh') to + suppress additional whitespace after the header. + + * tmac/doc-ditroff, tmac/doc-nroff (Am): New string to be in sync + with NetBSD. + + * src/preproc/grn/grn.man, tmac/groff_mdoc.man, NEWS: Updated. + +2002-10-07 Ruslan Ermilov + + * tmac/doc-common(doc-volume-operating-system-ateol): New flag. + (Dt): Use it to improve language localization (especially Russian + and French). + +2002-10-07 Daniel Senderowicz + + * src/preproc/grn/gprint.h (BSPLINE, BEZIER): New macros. + * src/preproc/grn/hdb.cc (DBGetType): Parse spline and bezier + drawing commands. + * src/preproc/grn/hgraph.cc (drawwig): Add parameter to control + curve type. + Call `picurve' for BSPLINE. + (HGPrintElt): Handle BSPLINE. + * src/preproc/grn/README: Document it. + +2002-10-03 Werner LEMBERG + + * src/roff/troff/node.cc (break_char_node::col): New variable. + Updated constructor. + (space_node::tprint, word_space_node::tprint): Call `fill_color' + unconditionally. + (space_node::space_node): Remove assertion. + (break_char_node::add_self): Pass color argument to space node. + * src/roff/troff/input.cc (token::add_to_node_list, token::process): + Ditto. + * src/roff/troff/env.cc (environment::do_break, + environment::add_padding): Ditto. + +2002-10-02 Werner LEMBERG + + Redesigning color support in troff. Colors are no longer + represented as separate nodes but are now part of glyph nodes and + friends. This fixes the current formatting misbehaviour due to the + changes introduced on 2002-09-20. Some extra code is necessary for + proper grotty support: Without adding color variables to + space-related nodes, the background color would be changed too late. + + * src/roff/troff/node.h, src/roff/troff/node.cc: + s/current_pagecolor/current_fill_color/. + s/current_glyphcolor/current_glyph_color/. + (glyph_color_node, fill_color_node): Removed. + (node::get_glyph_color, node::get_fill_color): New virtual member + functions. + (space_node::col): New variable. + Updated constructors of space_node and derived classes accordingly. + (hmotion_node::col): New variable. + Updated constructors of hmotion_node and space_char_hmotion_node + accordingly. + (vmotion_node::col): New variable. + Updated constructor accordingly. + (draw_node::gcol, draw_node::fcol): New variables. + Updated constructor accordingly. + (special_node::gcol, special_node::fcol): New variables. + Updated constructors accordingly. + (troff_output_file::put_char, troff_output_file::put_charwidth, + troff_output_file::draw): Set glyph and fill color. + (troff_output_file::start_special): Set glyph and fill color. + Always set current font. + (troff_output_file::fill_color, troff_output_file::glyph_color): + Don't call `do_motion'. + (glyph_node::gcol, glyph_node::fcol): New variables. + Updated constructors of glyph_node and ligature_node accordingly. + (glyph_node::get_glyph_color, glyph_node::get_fill_color): New + member functions. + (glyph_node::merge_glyph_node, + kern_pair_node::add_discretionary_hyphen, + node::add_discretionary_hyphen): Updated. + (break_char_node::merge_self): Updated. + (word_space_node::tprint, space_node::tprint, hmotion_node::tprint, + vmotion_node::tprint): Handle color. + (make_glyph_node, make_node, node::add_char): Updated. + + * src/roff/troff/env.cc (environment::space_newline, + environment::space, environment::output_line, environment::do_break, + environment::make_tab_node, environment::add_padding, title): + Updated. + (environment_switch, environment_copy): Don't add color nodes. + + * src/roff/troff/input.cc (do_glyph_color, do_fill_color): Return + nothing. + (token::next): Updated. + \m and \M now are as transparent as \s. + (process_input_stack, token::add_to_node_list, token::process, + read_draw_node): Updated. + (charinfo_to_node_list): Don't add color nodes. + + * doc/groff.texinfo: Updated. + +2002-09-27 Ruslan Ermilov + + * tmac/doc-common (ds-operating-system-FreeBSD-4.*): New version + strings. + +2002-09-27 Colin Watson + + * src/roff/troff/node.cc (bracket_node::copy): Check `list' != 0. + +2002-09-23 Werner LEMBERG + + * src/devices/grolbp/lbp.cc: Replace `300' with `font::res' where + appropriate. + (DEFAULT_LINEWIDTH_FACTOR): New macro. + (linewidth_factor): New global variable. + (lbp_printer::set_line_thickness): Fix case for size < 0, using + linewidth_factor. + (long_options): Add -w/--linewidth option. + (usage): Updated. + (main): Handle -w option to set linewidth_factor. + (lbp_printer::lbp_printer): Initialize req_linethickness, not + line_thickness. + + * src/devices/grolbp/grolbp.man, NEWS, doc/webpage.ms: Updated. + +2002-09-22 Paco Andrés Verdú + + Fixed a bug in the line thickness setting code. + + * src/devices/grolbp/lbp.cc (lbp_printer::req_linethickness): New + variable. + (lbp_printer::set_line_thickness): Pass environment as second + parameter. + Implement it actually. + (lpb_printer::set_char, lbp_printer::draw): Use `req_linethickness' + and `set_line_thickness, depending on the current font size. + +2002-09-21 Werner LEMBERG + + Some Debian patches. + + * src/roff/groff/pipeline.h (MAX_COMMANDS): Increase to 12. + * src/roff/troff/node.cc (bracket_node::copy): Initialize + `list->last'. + +2002-09-20 Werner LEMBERG + + * configure: Regenerated with autoconf 2.54. + +2002-09-20 Werner LEMBERG + + * src/roff/troff/env.h (environment): Rename cur_glyph_color to + glyph_color. + Rename cur_fill_color to fill_color. + * src/roff/troff/env.cc: Updated. + +2002-09-20 Werner LEMBERG + + * src/roff/troff/env.cc (title): Copy color status after processing + title. + * src/roff/troff/input.cc (charinfo_to_node_list): Emit glyph and + fill color nodes to reset colors properly. + + * tmac/www.tmac (DC): Fix color handling. + + * src/preproc/pic/pic.man, doc/pic.ms: Document some color issues. + * doc/groff.texinfo: Fixing documentation of `tl' request. + * doc/webpage.ms: Updated. + +2002-09-19 Werner LEMBERG + + * src/roff/troff/env.cc (environent_switch, environment_copy): + Emit glyph and fill color nodes to initialize colors properly. + +2002-09-17 Colin Watson + + * src/roff/troff/env.cc (environment::set_glyph_color, + environment::set_fill_color): Fix typo which prevented \m[] work + correctly. + +2002-09-17 Werner LEMBERG + + Add left and right italic correction to non-slanted PS fonts. This + is an experimental feature to improve image rendering of grohtml. + + * font/devps/generate/Makefile (RFLAG): New variable, set to `-i 0'. + ({T,H,C,P,N,BM,A,HN}{R,B}, ZD, S, ZDR): Use it. + * font/devps/*: All non-slanted fonts regenerated. + * NEWS: Updated. + +2002-09-16 Werner LEMBERG + + Add a site-specific font directory. + + * Makefile.in (localfontdir, legacyfontdir): New variables. + (fontpath): Use them. + (MDEFINES, uninstall_dirs): Updated. + * Makefile.comm (.man.n): Add `LOCALFONTDIR' and `LEGACYFONTDIR'. + Remove `FONTPATH' and `MACROPATH'. + + * src/roff/troff/troff.man, NEWS: Updated. + * doc/groff.texinfo (Font Directories): New section. + Other minor fixes. + + * src/devices/grodvi/grodvi.man, src/devices/grohtml/grohtml.man, + src/devices/grolbp/grolbp.man, src/devices/grolj4/grolj4.man, + src/preproc/grn/grn.man: Minor fixes. + + * src/devices/grohtml/post-html.cc (html_printer::do_tab_ts): + Remove unused variable. + +2002-09-11 Werner LEMBERG + + * doc/groff.texinfo, man/groff_font.man: Clarify argument of \N. + * man/groff_out.man: Fix documentation of 'N'. + +2002-09-09 Gaius Mulley + + * doc/Makefile.in (webpage.html): Depend on gnu.eps also. + * src/roff/troff/env.cc (indent): Emit html tag only if break_flag is + set. + * src/devices/grohtml/post-html.cc (text_glob::is_br_ni): Removed. + (text_glob::is_br, html_printer::lookahead_for_tables): Updated. + (html_printer::do_tab_ts): Call `emit_table_header' with `FALSE'. + * src/devices/grohtml/html-text.cc (html_text::start_tag) : Call `begin' with `FALSE'. + +2002-09-09 Ralph Corderoy + + * src/libs/libgroff/string.cc (string::extract): Fix position of + terminating null byte. + +2002-09-08 Werner LEMBERG + + Add global option `nospaces' to tbl so that leading and trailing + spaces in data items are ignored. + + * src/libs/libgroff/string.cc (string::remove_spaces): New member + function to remove leading and trailing spaces. + * src/include/stringclass.h: Updated. + + * src/preproc/tbl/table.h (table): Add flag `NOSPACES'. + + * src/preproc/tbl/main.cc (process_options): Handle `nospaces' + option. + Fix typo in error messages. + (process_data): Implement `nospaces' option. + * src/preproc/tbl/tbl.man, NEWS, doc/webpage.ms: Updated. + +2002-09-07 Werner LEMBERG + + * src/include/config.hin: Add `HAVE_ISATTY'. + * src/libs/libgroff/tmpfile.cc (xtmpfile_list): Drop `const' for + `fname' member. + * src/libs/libgroff/tmpname.cc: Include `time.h'. + * src/libs/libdriver/input.cc (Char): Add `operator==' and + `operator!=' for `char'. + * doc/groff.texinfo: Replace @ifnottex block for top node with + @ifhtml block. + +2002-09-06 Werner LEMBERG + + * doc/Makefile.in (.texinfo.html): Add -I switch. + * doc/groff.texinfo: Add @ifnottex block for top node to make + translation to HTML work. + +2002-09-05 Gaius Mulley + + * src/preproc/html/pre-html.cc (LETTER_LENGTH): Removed. + (get_papersize, determine_vertical_offset): Removed. + (char_buffer::do_image): Always specify letter size. + (main): Updated. + (imageList::createPage): Use -dDEVICEHEIGHTPOINTS instead of + -sPAPERSIZE. + +2002-09-05 Werner LEMBERG + + * doc/groff.texinfo, tmac/groff_man.man: Improve documentation of + default indentation. + +2002-09-04 Gaius Mulley + + * src/preproc/html/pre-html.cc (imageList::createPage): Use + -sPAPERSIZE for gs. + (generateImages): Clean up push-back buffer. + +2002-09-04 Ralph Corderoy + + * doc/groff.texinfo: Minor fixes. + +2002-08-21 Gaius Mulley + + * src/preproc/html/pre-html.cc (DEFAULT_LINE_LENGTH): New macro. + (MAX_WIDTH, A4_LENGTH, A4_OFFSET, LETTER_OFFSET): Removed. + (gsPaper): Removed. + (determine_vertical_offset): Use LETTER_LENGTH. + (createPage): Moved to ... + (imageList::createPage): This. + Call gs with -dDEVICEWIDTHPOINTS to avoid cropping. + (imageList::getMaxX): New function. + (createImage): Moved to ... + (imageList::createImage): This. + (imageList::createImages): New function. + (generateImages): Read `maxx' directly. + Updated. + (scanArguments): Don't specify `gsPaper' for `-o'. + (makeTempFiles): Call `xtmpfile' with the last argument set to + `TRUE'. + +2002-08-24 Werner LEMBERG + + * src/include/nonposix.h (mkdir, WAIT, creat) [_MSC_VER]: Define. + (WAIT, _WAIT_CHILD) [!_MSC_VER]: Define. + * src/preproc/html/pre-html.cc (waitForChild): Use WAIT. + * src/preproc/html/pushback.cc: Include nonposix.h. + * src/roff/groff/pipeline.c: Define strcasecmp and strncasecmp + conditionally. + +2002-08-23 Werner LEMBERG + + Use $(OBJEXT) for the object file extension. + + * Makefile.comm (.SUFFIXES): Add .obj. + (.cc.obj, .c.obj): New implicit rules. + * Makefile.in (OBJEXT): New variable, initialized from autoconf. + (MDEFINES): Add EXEEXT and OBJEXT. + * */Makefile.sub: s/.o/.$(OBJEXT)/. + +2002-08-22 Werner LEMBERG + + * INSTALL: Mention texinfo 4.2 as a prerequisite. + +2002-08-21 Gaius Mulley + + * src/devices/grohtml/post-html.cc (colType): Make enum global to + the file. + (html_printer::update_min_max, html_printer::add_table_end): New + methods. + (html_printer::lookahead_for_tables): Use them. + Reset page offset correctly. + (html_printer::~html_printer): Add creation of creator comment up. + +2002-08-20 Werner LEMBERG + + * tmac/an-old.tmac (T&): New dummy macro to avoid warning. + * man/groff_tmac.man: Fix typos. + * man/groff_font.man: Minor reordering. + * contrib/eqn2graph/eqn2graph.man (Tp): New macro. + +2002-08-18 Gaius Mulley + + Avoid endless loops while scanning for tables. + + * src/devices/grohtml/post-html.cc (list::insert): Set + ptr->right->left. + (html_printer::next_horiz_pos): Add `text_glob' argument; update + all callers. + Return immediately if that argument is NULL. + (html_printer::calc_nf): Don't test if `g' is NULL. + (html_printer::lookahead_for_tables): Use + `glyphs.move_right_get_data'. + Don't test if `g' is NULL. + +2002-08-18 Gaius Mulley + + A better fix, replacing fix 2002-08-15, for increasing SIZE. + + * src/devices/grohtml/post-html.cc (char_block): Make `buffer' + a pointer. + (char_block::char_block): Allocate `buffer'. + (char_buffer::add_string): Use it. + +2002-08-15 Werner LEMBERG + + * src/devices/grops/grops.man, src/devices/grolj4/grolj4.man, + src/devices/grodvi/grodvi.man: Document default line thickness. + +2002-08-15 Gaius Mulley + + * src/devices/grohtml/post-html.cc (char_block): Increase SIZE to + 8192. + +2002-08-14 Werner LEMBERG + + * doc/webpage.ms: Updated. + +2002-08-09 Werner LEMBERG + + * src/roff/troff/node.cc (node::add_char): Call `freeze_space' for + unbreakable space. + +2002-08-08 Aaron Campbell + + * src/preproc/pic/object.cc (object_spec::make_move): Fix typo + (&& -> &). + +2002-08-08 Werner LEMBERG + + * src/roff/troff/input.cc (read_rgb, read_cmy, read_cmyk): Call + tok.next(). + (read_gray): Ditto. + Don't push back a space but a newline onto the stack. + +2002-08-07 Gaius Mulley + + Add fonts `CI', `CB', and `CBI' to grohtml which have been omitted + inadvertently. + + * src/devices/grohtml/post-html.cc (html_printer::end_font, + html_printer::start_font): Handle them. + * src/devices/grohtml/html-text.cc (html_text::do_italic): Don't + reset bold and tt. + (html_text::do_bold): Don't reset italic and tt. + (html_text::do_tt, html_text::do_pre): Don't reset bold and italic. + * font/devhtml/DESC.proto: Add those fonts. + * font/devhtml/Makefile.sub (PROTOFONTS): Updated. + +2002-08-07 Werner LEMBERG + + * MORE.STUFF: Added gpresent. + + * tmac/trace.tmac: Show nesting level by a corresponding amount of + whitespace before printing the logging message. + +2002-07-31 Colin Watson + + * src/devices/grohtml/html-table.cc (html_table::finish_row): + Initialize `n' to zero. This fixes a segfault on ARM. + +2002-07-30 Werner LEMBERG + + * doc/grnexmpl.me: Remove calls to .st and .sc which are undefined. + +2002-07-29 Werner LEMBERG + + * src/preproc/pic/pic.y (print_arg, relative_path): Add missing + final semicolon. + +2002-07-28 Colin Watson + + * src/devices/grohtml/post-html (html_printer::troff_tag): Handle + `.ps'. + (html_printer::html_printer): Initialize `pointsize'. + +2002-07-26 Werner LEMBERG + + * doc/Makefile.sub (PROCESSEDEXAMPLEFILES): Remove gnu.eps and + gnu.png. + (CLEANNOTSRCDIRADD): Add gnu.eps and gnu.png. + (gnu.eps): Add -rle switch to pnmtops. + (distfiles): Add gnu.eps and gnu.png. + +2002-07-25 Petter Reinholdtsen + + * src/libs/libdriver/input.cc (Char): Add const to `operator=='. + Add `operator!='. + +2002-07-24 Werner LEMBERG + + * doc/Makefile.in, doc/Makefile.sub (groff_bin_path): Don't use + ' \+' but ' *' for sed. + (GROFF): Set GROFF_COMMAND_PREFIX to empty value. + +2002-07-23 Werner LEMBERG + + * doc/groff.texinfo: Document `papersize' keyword. + * NEWS, man/groff_font.man: Updated. + +2002-07-23 Colin Watson + + Extend papersize keyword to accept more than a single entry. The + first valid will be used. + + * src/libs/libgroff/font.cc (font::load_desc): Implement it. + (font::scan_papersize): Really skip final newline. + * src/preproc/html/pre-html.cc (get_papersize): Ditto. + +2002-07-23 Werner LEMBERG + + * configure.ac: Test for isatty. + * configure: Regenerated. + * src/include/posix.h: Check HAVE_ISATTY. + * src/roff/troff/input.cc [ISATTY_MISSING]: Removed. + * src/utils/lookbib/lookbib.cc: Include posix.h. + Don't declare isatty. + +2002-07-21 Werner LEMBERG + + * NEWS: Add `output' request. + + * REVISION: Increased to 1. + +Version 1.18.0 released +======================= + +2002-07-19 Gaius Mulley + + Allow internal glyph indices > 0xFF in grohtml for input characters. + + * src/devices/grohtml/post-html.cc (to_unicode): Use `unsigned int' + as parameter. + (html_printer::add_to_sbuf): Use `unsigned int' as first parameter. + Updated all callers. + (html_printer::sbuf_continuation, html_printer::overstrike): Ditto. + (html_printer): Updated. + +2002-07-19 Werner LEMBERG + + * font/devhtml/R.proto: Updated to HTML 4, adding many glyphs. + * font/devutf8/R.proto: Adding some missing glyphs. + * font/devutf8/NOTES: Updated. + + * tmac/dvi.tmac: Add more composite glyphs. + * tmac/html.tmac: Updated. + + * man/groff_char.man: Add `sum' and `product' entities. + + * NEWS: Updated. + +2002-07-18 Gaius Mulley + + Improved table, tab, and indenting support. + + * src/roff/troff/input.cc (file_iterator::suppress_newline_flag, + string_iterator::suppress_newline_flag): Removed. Updated all + function which have used it. + + * src/roff/troff/env.cc: Include `input.h'. + (environment::add_node): Accept 0 as parameter. + (environment::add_html_tag): Add `force' parameter. + Updated all callers. + (environment::add_html_tag_tabs): Ditto. + For the moment, support left-aligned tabs only. + (environment::make_html_tag): New function. + (fill, no_fill): Set .br html tag additionally. + (environment::newline): Emit `eol.ce' or `eol' tag for html. + (environment::add_html_tag_eol): Removed. + (tab_stops::distance_to_next_tab): Add variant for handling + nextpos'. + (environment::distance_to_next_tab): Ditto. + Updated all callers. + (environment::handle_tab): Handle tabs for html. + + * src/roff/troff/env.h: Updated. + + * src/roff/troff/div.cc: Updated all callers of + `environment::add_html_tag'. + + * src/devices/grohtml/html-table.cc, + src/devices/grohtml/html-table.h: New files. + + * src/devices/grohtml/html-text.cc (html_text): New members + `blank_para' and `start_space'. + (html_text::issue_tag): Don't emit TABLE_TAG. + Handle indentation for PRE_TAG and P_TAG. + (html_text::end_tag): Updated. + (html_text::table_is_void, html_text::issue_table_begin, + html_text::issue_table_end): Removed. + (html_text::do_push): Simplified. + [DEBUGGING]: Small fix. + (html_text::push_para): Add new parameter for indentation; updated + all callers. + Handle PRE_TAG. + (html_text::do_indent, html_text::do_table, html_text::done_table, + html_text::is_in_table): Removed. + (html_text::do_pre): Handle P_TAG also. + (html_text::shutdown): Handle p->indent. + (html_text::check_emit_text): Simplified. + (html_text::do_emittext): Reset `blank_para'. + (html_text::do_para): Add new parameter for indentation; updated + all callers. + (html_text::remove_indent): New function. + (html_text::do_space): Handle verbatim text properly. + (html_text::ever_emitted_text, html_text::starts_with_space, + html_text::remove_para_align): New functions. + (html_text::dump_stack_element, html_text::dump_stack): Updated. + + * src/devices/grohtml/html_text.h (HTML_TAG): Remove TABLE_TAG. + Updated. + + * src/devices/grohtml/post-html.cc: Include html-table.h. + (INDENTATION): Removed. + (text_glob): Added many `is_' functions. + Added table description `tab'. + Added `get_arg',`get_tab_args', `remember_table', and `get_table' + member functions. + (list): Add `insert' and `move_to' member functions. + (page): Add `insert_tag' member function. + (page::dump_page) [DEBUG_TABLES]: Improved. + (html_printer): Add `table' and `max_linelength' elements. + Add many `do_', `insert_', `next_horiz_pos', + `lookahead_for_tables', `shutdown_table', `calc_nf', `calc_po_in', + `remove_tabs', `remove_courier_tabs'. + (html_printer::emit_raw): Handle indentation. + (html_printer::do_center, html_printer::write_header): Updated. + (html_printer::is_courier_until_eol): Check for tag. + (html_printer::do_linelength): Handle max_linelength. + (html_printer::do_page_offset, html_printer::do_indentation): Handle + fill_on. + (html_printer::do_tempindent): Updated. + (html_printer::do_indentedparagraph): Removed. + (html_printer::do_indent): Simplified. + (html_printer::do_eol): Use `ever_emitted_text'. + (html_printer::do_flush, html_printer::do_links): Don't call + done_table. + (html_printer::do_break): Handle end_tempindent. + (html_printer::troff_tag): Get argument. + Don't handle `.ip'. + Handle `.tab-ts', `.tab-te', `.col', `tab', and `tab0' tags. + (html_printer::flush_page): Call `lookahead_for_tables'. + Don't call `done_table'. + (html_printer::add_to_sbuf): Always call do_indent. + + * src/devices/grohtml/Makefile.sub: Updated. + + * tmac/an-old.tmac (TP): Don't handle html device specially. + (an-do-tag-html): New function which will be used instead of + `an-do-tag' if html device is used. + + * tmac/html.tmac: Call .po to pass default page offset to grohtml. + + * tmac/s.tmac (@IP): Don't handle html device specially. + (@IP-html): New function which will be used instead of `@IP' if + html device is used. + + * tmac/www.tmac (HTML-NS, HTML-TAG-NS): New auxiliary macros -- this + is a hack which will eventually vanish again. + (PIMG): Handle `-C' option correctly if not html. + (HR): Use HTML-NS. + +2002-07-17 Werner LEMBERG + + * src/utils/afmtodit/afmtodit.pl: Don't use `-P-' for invoking perl. + +2002-07-14 Eric S. Raymond + + * contrib/pic2graph/pic2graph.*: Use convert(1). + * contrib/eqn2graph/eqn2graph.*: Minor fixes. + +2002-07-14 Bernd Warken + + * tmac/groff_trace.man: New file. + * tmac/Makefile.sub: Updated. + * NEWS: Updated. + +2002-07-13 Werner LEMBERG + + * src/roff/groff/groff.man: Add some cross references. + +2002-07-12 Werner LEMBERG + + * src/roff/troff/input.cc (substring_request): Add warnings for + string indices out of range. + +2002-07-11 Werner LEMBERG + + * font/devdvi/generate/ec.map: Fix typo (`(l' -> `/l'). + * font/devdvi/*EC: Regenerated. + +2002-07-10 Bernd Warken + + * man/groff_char.man: Updated and extended. + +2002-07-10 Werner LEMBERG + + * src/roff/troff/input.cc (length_macro): Renamed to... + (length_request): This. + Move call of `tok.next()' to the very end, otherwise the register + value hasn't been updated yet. + (init_input_requests): Updated. + +2002-07-09 Werner LEMBERG + + * src/roff/troff/input.cc (substring_macro): Renamed to... + (substring_request): This. + (init_input_requests): Updated. + * src/roff/troff/request.h: Updated. + +2002-07-08 Robert D. Goulding + + * src/roff/grog/grog.sh: Fix typo. + +2002-07-08 Werner LEMBERG + + * win32-diffs: Updated. + + Handle `papersize' keyword properly in DESC. + + * src/libs/libgroff/font.cc (font::scan_papersize): Fix argument + type. + Updated all callers. + * src/libs/libgroff/paper.cc: Add four more paper formats used by + grolj4. + * src/include/paper.h: Updated. + + * src/devices/grolbp/lbp.cc: Remove unnecessary semicolons. + Other minor C syntax fixes. + (papersize, paperlength, paperwidth): Renamed to `user_*'. + (lbp_printer): Add `papersize', `paperlength', and `paperwidth' + members. + (lbp_printer::lbp_printer): Pass three arguments. + Set paper dimensions properly. + (make_printer, main): Updated. + (handle_unknown_desc_command): Fix error messages. + (main): Handle papersize keyword in DESC properly. + + * src/devices/grolj4/lj4.cc (paper_size): Renamed to + `user_paper_size'. + (lbp_printer::lbp_printer): Pass an argument. + Set paper_size properly. + (handle_unknown_desc_command): Removed. + (make_printer, main): Updated. + * src/devices/grolj4/grolj4.man: Minor documentation fix. + + * man/groff_font.man, NEWS: Updated. + +2002-07-07 Werner LEMBERG + + Integrated eqn2graph, contributed by Eric S. Raymond. + + * contrib/eqn2graph/{Makefile.sub, eqn2graph.sh, eqn2graph.man}: New + files. + * Makefile.in, NEWS: Updated. + +2002-06-04 Werner LEMBERG + + Changing the substring request to make it fit better with other + string manipulation functions in other programming languages: + Index 0 is now the first character in the string, and index -1 + indicates the last character. Since this request didn't work + properly anyway in the last release, it doesn't harm too much to + change the syntax. + + * src/roff/troff/input.cc (substring_macro): Use loops to get + the real string length (ignoring COMPATIBLE_SAVE and + COMPATIBLE_RESTORE) and offsets. + Implement change described above. + + * man/groff_char.man, tmac/doc-common (doc-header), tmac/doc.tmac + (doc-do-Bd-args, doc-do-Bl-args): Changed accordingly. + + * NEWS, doc/groff.texinfo, man/groff_diff.man: Updated. + +2002-06-03 Werner LEMBERG + + Make .chop work with .de1 and friends. COMPATIBLE_SAVE and + COMPATIBLE_RESTORE are completely ignored. + + * src/roff/troff/input.cc (char_list::set, char_list::get): New + functions. + (macro): `length' field renamed to `len'. + Added new field `empty_macro' (1 if macro is empty), to be used + instead of checking `len'. + Updated all callers. + (macro::empty): Updated. + (macro::length, macro::set, macro::get): New functions. + (macro::append): Ignore COMPATIBLE_SAVE and COMPATIBLE_RESTORE. + Set `empty_macro'. + (chop_macro): Check and remove trailing COMPATIBLE_SAVE/ + COMPATIBLE_RESTORE pairs. + (asciify): Ignore COMPATIBLE_SAVE and COMPATIBLE_RESTORE. + * src/roff/troff/request.h: Updated. + + * doc/groff.texinfo: Document .chop's behaviour better. + +2002-06-02 Werner LEMBERG + + * doc/pic.ms: Fix documentation for the addition of positions. + + * tmac/doc.tmac, tmac/an-old.tmac: Need groff version 1.18. + +2002-06-29 Werner LEMBERG + + Implementation of string arguments of the form \*[foo arg1 arg2 ...] + + * src/roff/troff/input.cc (have_string_arg): New global variable. + (read_mode): New enumeration. + (read_escape_name): Use it. Update all calls. + (read_long_escape_name): Use it. Update all calls. + Set have_string_arg if appropriate. + (get_char_for_escape_name): Add parameter for handling space + character. + (interpolate_string_with_args, decode_string_args): New functions. + (get_copy, token::next): Call it if necessary. + (interpolate_string): Fix error message. + + * NEWS, doc/groff.texinfo, man/groff.man, man/groff_diff.man: + Document it. + +2002-06-24 Bernd Warken + + * man/groff_tmac.man: Updated and extended. + +2002-06-24 Werner LEMBERG + + * doc/pic.ms, src/preproc/pic/pic.man: Fix description of `:='. + +2002-06-23 Werner LEMBERG + + * doc/pic.ms: Improve documentation of composite block objects. + +2002-06-22 Werner LEMBERG + + * src/roff/troff/input.cc (init_registers): Add three registers + `seconds', `minutes', and `hours' to hold the current time. + + * NEWS, doc/groff.texinfo, man/groff.man, man/groff_diff.man: + Updated. + +2002-06-20 Werner LEMBERG + + Make \X accept both `\ ' and `\~', converting them to single space + characters. + + * src/roff/troff/token.h (token): Add TOKEN_UNSTRETCHABLE_SPACE. + (token::unstretchable_space): New inline function. + * src/roff/troff/input.cc (token::next, token::delimiter, + token::description, token::add_to_node_list, token::process): Handle + TOKEN_UNSTRETCHABLE_NODE. + (encode_char): Handle tok.stretchable_space and + tok.unstretchable_space. + + * NEWS, doc/groff.texinfo: Document it.. + +2002-06-19 Werner LEMBERG + + * src/devices/grops/ps.cc (ps_printer::special): Fix error message. + + * src/devices/grotty/tty.cc (tty_printer::special): Add `sgr' + keyword to enable/disable SGR output. + (tty_printer::change_fill_color): New function. + * NEWS, src/devices/grotty/grotty.man: Document `sgr' special. + + * src/roff/troff/input.cc (output_request): Add missing `tok.next()' + call. + +2002-06-18 Werner LEMBERG + + Add a `color' request and a `.color' register to control usage of + colours. + + * src/roff/troff/input.cc (disable_color_flag): Replaced with... + (color_flag): This (which is the inverse). + (activate_color): New function. + (main, init_input_requests): Updated. + * src/roff/troff/troff.h, src/roff/troff/node.cc + (troff_output_file::fill_color, troff_output_file::glyph_color): + Updated. + + * NEWS, doc/groff.texinfo, man/groff_diff.man, man/groff.man: + Document the changes. + +2002-06-17 Colin Watson + + Circumvent bug in autoconf 2.53 regarding top_builddir. + + * aclocal.m4 (GROFF_BUILDDIR): s/top_builddir/groff_top_builddir/. + * Makefile.in, doc/Makefile.in: + s/@top_builddir@/@groff_top_builddir@/. + * configure: Regenerated (with autoconf 2.53). + +2002-06-17 Werner LEMBERG + + * src/libs/libgroff/font.cc (font::load_desc): Fix computation of + `paperwidth' and `paperlength' for the `papersize' keyword. + +2002-06-16 P. Alejandro Lopez-Valencia + + * src/devices/grops/grops.man: Add info about Type 42 fonts. + +2002-06-15 Gaius Mulley + + * src/devices/grohtml/post-html.cc (html_printer::emit_raw, + html_printer::do_linelength, html_printer::do_pageoffset, + html_printer::do_indentation, html_printer::do_tempindent, + html_printer::do_break, html_printer::begin_page): Clear indented + text. + * tmac/html.tmac: Disable hyphenation. + +2002-06-15 Werner LEMBERG + + Don't produce HTML files if utility programs are missing. + + * Makefile.in (make_html, make_install_html): New variables. + (MDEFINES): Updated. + + * aclocal.m4 (GROFF_HTML_PROGRAMS): New function to test for HTML + utility programs. + * configure.ac: Use it. + * configure: Regenerated. + + * doc/Makefile.sub (PROCESSEDEXAMPLEFILES): Move webpage.html to... + (HTMLEXAMPLESFILES): This new variable. + (EXAMPLESIMAGEFILES): Renamed to... + (HTMLEXAMPLEIMAGEFILES): This. + (CLEANADD): Add HTMLEXAMPLEFILES. + (all): Use `make_html'. + (html): New target. + (install_data): Use `make_install_html'. + Move html stuff to... + (install_html): This new target. + (uninstall_sub): Updated. + +2002-06-14 Bernd Warken + + * src/roff/grog/Makefile.sub (grog): Renamed to... + (grog.old): This. + (grog): New rule to always install grog.sh as grog. + +2002-06-08 Bernd Warken + + * src/roff/grog/grog.pl: Fix typo. + +2002-06-07 Werner LEMBERG + + * doc/groff.texinfo: Add more info on .tr arguments. + +2002-06-05 Werner LEMBERG + + * NEWS, src/roff/grog/grog.man, doc/groff.texinfo: Updated. + + * aclocal.m4 (GROFF_MKSTEMP): Include unistd.h. + * configure: Regenerated. + +2002-06-05 Ralph Corderoy + + * src/roff/troff/symbol.cc (table_sizes): Add more values. + + * src/roff/grog/grog.pl, src/roff/grog/grog.sh: Recognize mom. + +2002-06-04 Werner LEMBERG + + * aclocal.m4 (GROFF_PAGE): Don't use `prefix' directly since it + is not initialized at the time we need it in case `--prefix' hasn't + been set. Check for `ac_default_prefix' also. + Test for `papersize' keyword also and generalize allowed whitespace. + * configure: Regenerated. + + * font/devps/Makefile.sub (DESC): Use `papersize' instead of + `paperlength'. + + * src/libs/libgroff/Makefile.sub (version, revision): Replaced + with... + (src_version, src_revision): New variables to avoid overwriting + from parent make process. + (version.cc): Updated. + + * src/preproc/html/pre-html.cc: Include paper.h and font.h. + (linebuf, linebufsize): New global variables. + (sys_fatal): Use `fatal' to abort properly. + (get_line): New function. + (get_resolution): Use it. + Improve error messages. + (get_papersize): Check `papersize' also. + Use `get_line'. + Improve error messages. + +2002-06-03 Werner LEMBERG + + * Makefile.comm (CLEANNOTSRCDIRADD): New target for files which + should be removed only if builddir is not srcdir. + (mostlyclean): Handle `CLEANNOTSRCDIRADD'. + (clean): Depend on `mostlyclean'. + (distclean): Depend on `clean'. + (realclean, extraclean): Depend on `distclean'. + (.y.cc, .y.o): Simplified. The output files are no longer written + to srcdir but to builddir. + * Makefile.in (MDEFINES): Add `version' and `revision'. + (uninstall_dirs): Fix order of directories. + * doc/Makefile.sub (version, revision): Removed. + (CLEANADD): Removed grnexmpl.g, groff, groff-*. + Added `HTMLDOCFILES'. + (CLEANNOTSRCDIRADD): New target for grnexmpl.h, groff, groff-*. + * src/preproc/eqn/Makefile.sub, src/preproc/pic/Makefile.sub, + src/preproc/refer/Makefile.sub (YTABC, YTABH): Don't use `srcdir' + as prefix. + + * doc/texinfo.tex (\authortt): New macro. + (\shortcontt): Define. + (\titlepage): Set \tt to \authortt while defining \authorfont. + (\appendixbox): New macro. + (\chapmacro, \appendixentry): Use \appendixbox to get even + indentation for letters. + (\summarycontents): Set \tt. + (\internalpagesize): Add two arguments for real paper width and + height as needed by pdfTeX. + (\letterpaper, \smallbook, \afourpaper, \afivepaper, \afourlatex): + Updated. + (\tempdima, \tempdimb): New temporary dimensions. + (\pagesizesyyy): Updated. + +2002-06-02 Werner LEMBERG + + Adding a new keyword `papersize' to the DESC file format (similar + but not completely identical to grolbp's extension). grops now has + a -p command line option to override `papersize'. Finally, grolbp + has been adapted to the new syntax. + + * src/libs/libgroff/paper.cc, src/include/paper.h: New files. It + defines and initializes the `papersizes[]' array with NUM_PAPERSIZES + elements. + * src/libs/libgroff/Makefile.sub (OBJS): Add `paper.o'. + (CCSRCS): Add `paper.cc'. + + * src/include/font.h (font): Add `papersize' element. + * src/libs/libgroff/font.cc (font::unit_scale): New helper function. + (font::scan_papersize): New function. + (font::load_desc): Use it for handling `papersize' keyword. + * src/libs/libgroff/fontfile.cc: Initialize `font::papersize'. + + * src/devices/grops/ps.cc: Include paper.h. + (user_paper_length): New global variable. + (ps_printer): Use paper length as initializer. + (make_printer): Updated. + (main): Handle new `-p' option. + * src/devices/grops/grops.man: Updated. + + * src/devices/grolbp/lbp.cc: Include paper.h. + s/papersizes/lbp_papersizes/. + (set_papersize): Use new `papersizes' array. + (handle_unknown_desc_command): Don't handle `papersize'. + (main): Use `font::scan_papersize' for handling `-p' option. + * src/devices/grolbp/grolbp.man: Updated. + + * man/groff_font.man: Document `papersize'. + * NEWS: Updated. + +2002-05-30 Werner LEMBERG + + * src/devices/grops/TODO: Updated. + * src/devices/grops/grops.man: More info on paper formats. + * man/groff_font.man: Document `paperheight' and `paperwidth'. + +2002-05-29 Werner LEMBERG + + * doc/Makefile.sub (CLEANADD): Add grnexmpl.g, groff, and groff-* + to list only if srcdir != currdir. + (distfiles): New target. + + * Makefile.in (EXTRADIRS): Add font/devlj4/generate. + (NOMAKEDIRS): New variable. + (DISTDIRS): Use it. + +2002-05-26 Werner LEMBERG + + Add .output request, similar to \! at top-level. + + * src/roff/troff/input.cc (transparent): Remove unused declaration. + (output_request): New function. + (init_input_requests): Add it. + Sorted. + * NEWS, doc/groff.texinfo, man/groff_diff.man, man/groff.man: + Document it. + + * Makefile.in (MDEFINES): Add INSTALL_INFO. + (prepare_examples): Fix typo. + * doc/groff.texinfo (@direntry): Fix it. + +2002-05-25 Werner LEMBERG + + Including the doc subdir into groff's Makefile system. + + * aclocal.m4 (GROFF_INSTALL_INFO): New function. + * configure.ac: Use it. + Generate `doc/Makefile'. + * configure: Regenerated. + + * Makefile.in (infodir, INSTALL_INFO): New variables. + (MDEFINES, uninstall_dirs): Updated. + (OTHERDIRS): Add `doc'. + * Makefile.comm (CLEANDIRADD): New variable. + (mostlyclean): Use it. + + * doc/Makefile.sub, doc/Makefile.in: New files. + * doc/Makefile: Removed. + + * NEWS, INSTALL: Updated. + +2002-05-24 Werner LEMBERG + + * doc/homepage.ms: Renamed to ... + * doc/webpage.ms: This. + Use `.NHR'. + +2002-05-23 Werner LEMBERG + + Integrating the `mom' macro package, contributed by Peter Schaffter + . + + * contrib/mom/*: New subdirectory tree. + * Makefile.in (docdir, exampledir, htmldocdir): New variables to + be used for documentation files. + (MDEFINES, uninstall_dirs): Use them. + (OTHERDIRS): Add contrib/mom. + * Makefile.comm (.man.n): Add @DOCDIR@, @EXAMPLEDIR@, and + @HTMLDOCDIR@. + * MANIFEST, NEWS: Updated. + +2002-05-22 Gaius Mulley + + Change syntax of \O: \O[0] suppresses output, \O[1] enables output + if at outer level; at start-up we are at outer level. + + * src/roff/troff/input.cc (do_suppress): Implement it. + Simplify \O[3]. + + Add option -p to show progress information. + pre-grohtml will now render only one page at a time, reducing the + size of needed disk resources enormously. + + * src/preproc/html/pre-html.cc (imagePageStem): Replaced with... + (imagePageName): New global variable. + (psPageName, show_progress, currentPageNo): New global variables. + (html_system): Close saved stderr and stdout handles. + (write_end_image): Accept a parameter to control \O escape. + (write_start_image): Adapted to new \O meaning. + (char_buffer::write_upto_newline): Updated. + (createAllPages): Replaced with... + (createPage): This new function to create a single page for images. + It uses `psselect' from the psutils package. + (removeAllPages): Removed. + (createImage): Updated. + Handle progress display. + (char_buffer::do_html, char_buffer::do_image) [DEBUGGING]: Removed. + (scanArguments): Add option -p. + (makeTempFiles): Updated to create temp files for psPageName and + imagePageName. + (removeTempFiles): Removed. + (main): Updated. + + * src/devices/grohtml/post-html.cc (header_desc::write_headings, + html_printer::write_header): Append `\0' to `buffer'. + (html_printer::do_eol): Depend on `current_paragraph->emitted_text'. + (main): Handle -p. + * src/devices/grohtml/html-text.cc (html_text::dump_stack_element): + Handle `text_emitted'. + (html_text::table_is_void): Slightly rewritten. + (stop): New external symbol. + (html_text::do_push) [DEBUGGING]: Use it and simplify. + (html_text::shutdown): Call `dump_stack'. + (html_text::do_space): Rewritten. + * src/devices/grohtml/grohtml.man: Document -p and the need of + `psselect'. + + * tmac/www.tmac (DC, HTML-DO-IMAGE, HTML-IMAGE-END): Updated to + new \O syntax. + Call \O[0] if `ps4html' is active. + * tmac/s.tmac (@EQ, @EN): Handle html better. + (@TS, TE): Ditto. + * tmac/html.tmac: Don't use black for background colour. + + * src/roff/troff/node.cc: Include `div.h'. + (troff_output_file::really_print_line): Don't use `is_on'. + (troff_output_file::word_marker, troff_output_file::flush_tbuf + troff_output_file::check_charinfo, + troff_output_file::put_char_width, troff_output_file::put_char, + troff_output_file::determine_line_limits, troff_output_file::draw, + real_output_file::begin_page, glyph_color_node::tprintf, + fill_color_node::tprint, hline_node::tprint, vline_node::tprint): + Use `is_on'. + (troff_output_file::really_on): Call `do_motion'. + (suppress_node::tprint): Use `get_page_number' instead of `%' + register. + Call `reset_output_registers' conditionally on `is_on'. + + * doc/groff.texinfo: Document new syntax of \O. + * NEWS, man/groff_diff.man: Updated. + +2002-05-22 Werner LEMBERG + + * MORE.STUFF: Add info about David Frey's deroff implementation. + Mention troff.org. + +2002-05-16 Werner LEMBERG + + Pic's `with' attribute now accepts positions. + + * src/preproc/pic/pic.y: Make `.', BOX, CIRCLE, ELLIPSE, ARC, LINE, + ARROW, SPLINE, and `[' left-associative tokens to fix shift/reduce + conflicts. + (object_spec): Add rule for `WITH' and `position'. + (relative_path): Give `corner' the precedence of `CHOP'. + * src/preproc/pic/object.h (path): New members `pos' and + `is_position'. + * src/preproc/pic/object.cc: Updated initializers of `path'. + (path::follow): Handle `is_position'. + + * doc/pic.ms: Completely updated grammar description. + Many typographical improvements. + +2002-05-15 Werner LEMBERG + + * src/roff/troff/env.cc(hyphen_trie::hpf_getc): Accept ^^x (char + code of x in range 0-127) also. + * doc/groff.texinfo, man/groff_diff.man: Updated. + + Added keywords `north', `south', `east', and `west' for corners + in pic. + + * src/preproc/pic/lex.cc (lookup_keyword): Add NORTH, SOUTH, EAST, + and WEST. + (yylex): Handle them. + * src/preproc/pic/pic.y: Add tokens NORTH, SOUTH, EAST, and WEST. + (corner): Handle them. + +2002-05-14 Werner LEMBERG + + * src/devices/grops/grops.man: Clarify handling of `download' file. + +2002-05-11 Werner LEMBERG + + Adding `warnscale' and `spreadwarn' requests, based on a patch from + Jeffrey Friedl . + + * src/roff/troff/input.cc (spread_limit, warn_scale, + warn_scaling_indicator): New global variables. + (warnscale_request, spreadwarn_requests): New functions. + (main): Initialize `warn_scale' and `warn_scaling_indicator'. + (init_input_requests): Updated. + (error_type): Add `OUTPUT_WARNING'. + (do_error): Handle it. + (output_warning): New warning function which shows output location. + * src/roff/troff/env.h (spread_limit): New external variable. + * src/roff/troff/env.cc (environment::choose_breakpoint): Use + `output_warning'. + (distribute_space): Emit warning if added space is larger than + `spread_limit'. + (environment::possibly_break_line): Emit warning if a line can't + be adjusted on both sides. + + * doc/groff.texinfo, man/groff_diff.man, man/groff.man: Document it. + +2002-05-08 Werner LEMBERG + + * src/roff/troff/node.cc (special_node::special_node): Use + env_definite_font(curenv) instead of curenv->get_font(). Otherwise + \X''\% crashes, for example. + + * doc/groff.texinfo: Document \! and \? used at top-level. + +2002-05-06 Werner LEMBERG + + * src/preproc/pic/pic.man: Fix some keyword syntax. + Other minor typographical fixes. + + * src/roff/groff/groff.man: Fix typos. + +2002-05-04 Werner LEMBERG + + * src/roff/groff/groff.man ([ShortOpt]): Renamed to... + (ShortOpt[]): This to avoid problems with refer. + + * doc/pic.ms: Fix typo. + Fix pic grammar description. + + * tmac/an-old.tmac (ne): Use de1, not de. + +2002-05-03 Werner LEMBERG + + * doc/groff.texinfo: Finished separation of glyphs and characters. + Don't use the string `Appendix' for appendix headers (both in + the text and the table of contents). + * man/groff_tmac.man, src/roff/troff/troff.man: Fix order of tmac + directories. + + Use registers LL and LT (similar to -ms) for controlling the + length of title and line, respectively, in the -man and -mdoc + macro packages. + + * tmac/doc-ditroff (doc-setup-page-layout), tmac/doc-nroff + (doc-setup-page-layout): Use \n[LL] and \n[LT]. + * tmac/an-old.tmac: Set \n[LL] and \n[LT] if not defined. + (TH): Use \n[LL]. + (an-header, an-p-footer): Use \n[LT]. + * NEWS, tmac/groff_man.man, tmac/groff_mdoc.man, + doc/groff.texinfo: Document it. + +2002-05-02 Werner LEMBERG + + * doc/fdl.texi: New file. + * doc/groff.texinfo: Include it. + Define and use @copying. + Starting with separating glyph, symbol, and character. + +2002-04-27 Werner LEMBERG + + * Makefile.in (EXEEXT): Set it. + * src/*/Makefile.sub (PROG): Add $(EXEEXT) for all non-script + programs. + + * src/include/nonposix.h: Define GS_NAME. + * src/preproc/html/pre-html.cc (createAllPages): Use GS_NAME. + + Some preliminary changes for EMX support under OS/2. + + * src/preproc/pic/main.cc (main), src/roff/groff/pipeline.c: Add + __EMX__ similar to __MSDOS__. + * src/utils/indxbib/indxbib.cc (main) [__EMX__]: Use `unlink'. + +2002-04-25 Werner LEMBERG + + * doc/groff.texinfo: Integrated groff_out.man. + Some macro fixes. + +2002-04-23 Werner LEMBERG + + * man/groff_out.man: Minor fixes. + +2002-04-23 Werner LEMBERG + + * doc/groff.texinfo: Moving @cindex entries after @Def* to get + correct page references. + Fixed many index entries. + +2002-04-23 Bernd Warken + + * man/roff.man: Enlarged. + +2002-04-22 Werner LEMBERG + + * doc/groff.texinfo: More examples, other fixes. + +2002-04-20 Werner LEMBERG + + * src/roff/troff/input.cc (pipe_output): Multiple calls to `pi' + will now form a chain, e.g. + + .pi foo + .pi bar + + is now the same as + + .pi foo | bar + + This is for compatibility with plan 9's troff. + + * tmac/tty.tmac: Set default tab values to 0.8i to be compatible + with UNIX troff. + * NEWS: Updated. + + * doc/groff.texinfo: Add documentation of remaining requests and + registers. + +2002-04-19 Werner LEMBERG + + * doc/groff.texinfo: Add documentation of remaining escapes. + + * font/devdvi/generate/tc.map: Remove entry for `sr'. + * font/devdvi/*TC: Regenerated. + +2002-04-18 Werner LEMBERG + + * src/roff/troff/input.cc (token::next): Make \H behave consistently + if not in compatibility mode, i.e., increment relative to the + previous height. + * doc/groff.texinfo: Updated accordingly. + +2002-04-17 Werner LEMBERG + + * doc/groff.texinfo: Document \\, \e, \E, \., and \c. + +2002-04-16 Bernd Warken + + * src/roff/groff/groff.man: Improve documentation of -P option. + Other minor fixes. + +2002-04-15 Werner LEMBERG + + Add new escape \F to switch font family. + + * src/roff/troff/input.cc (token::next): Handle \F. + * src/roff/troff/env.cc (environment::set_family): Handle + `interrupted' flag. + * NEWS, doc/groff.texinfo, man/groff_diff.man, man/groff.man: + Document it. + +2002-04-14 Werner LEMBERG + + * tmac/doc.tmac (doc-tag-list): Use \Z to avoid stretching of + spaces in tags. + +2002-04-13 Werner LEMBERG + + Implement \f[] as an alternative to \fP. Change \mP and \MP to + \m[] and \M[], respectively. + + * src/roff/troff/symbol.cc (EMPTY_SYMBOL): New global variable. + (symbol::symbol): Handle NULL string and empty string differently. + * src/roff/troff/symbol.h (symbol::is_empty): New inline function. + * src/roff/troff/input.cc (read_escape_name, read_long_escape_name): + Add optional parameter. + Updated calling functions. + (get_copy, do_glyph_color, do_fill_color, token::next): Use + `symbol::is_empty'. + * src/roff/troff/env.cc (environment::set_font): Ditto. + + * src/preproc/pic/troff.cc (troff_output::set_fill, + troff_output::reset_color: Updated. + + * tmac/www.tmac: Updated. + + * NEWS, man/groff_diff.man, man/groff.man, doc/groff.texinfo, + doc/homepage.ms, src/devices/grotty/grotty.man, tmac/groff_www.man: + Updated. + + * tmac/Xps.tmac: Remove some redundant code. + + * tmac/doc-common, tmac/doc-ditroff, tmac/doc-nroff, tmac/doc.tmac, + tmac/dvi.tmac, man/roff.man, man/groff_out.man, man/groff.man, + man/groff_diff.man, src/roff/groff/groff.man: Replace \f[P] with + \f[]. + +2002-04-13 Bernd Warken + + * src/include/printer.h, src/libs/libdriver/printer.cc + (printer::change_fill_color): New member function. + * src/libs/libdriver/input.cc (parse_D_command): Use it. + +2002-04-12 Werner LEMBERG + + * doc/groff.texinfo: Completed pass on gtroff reference. + +2002-04-11 Werner LEMBERG + + * doc/groff.texinfo: More fixes. + +2002-04-11 Bernd Warken + + * src/include/color.h: Decorate with `const'. + Use `size_t'. + Include `stddef.h'. + * src/libs/libgroff.color.cc: Decorate with `const'. + Use `size_t'. + (color::color): Initialize members. + * src/libs/libdriver/input.cc (parse_D_command): Handle `f' + command according to the documentation. + + * man/groff_out.man: Updated. + Minor fixes. + +2002-04-11 Gaius Mulley + + * src/preproc/html/pre-html.cc (write_start_image): Remove + redundant output. + * tmac/www.tmac (DC, HTML-DO-IMAGE): Ditto. + + * src/devices/grohtml/post-html.cc (page::add_and_encode): Using + \C'hy' caused an assertion failure. + + * src/roff/troff/env.cc (environment::environment): Initialize + `emitted_node'. + (environment::copy): Handle `ignore_next_eol' and `emitted_node'. + +2002-04-10 Werner LEMBERG + + * man/groff_diff.man, man/groff.man, NEWS, doc/groff.texinfo: + Document pvs request and .pvs register. + +2002-04-09 Werner LEMBERG + + * doc/groff.texinfo: Improve and fix documentation of diversions + and environments. + +2002-04-08 Werner LEMBERG + + * doc/groff.texinfo: Fix documentation of drawing functions. + Other minor fixes. + +2002-04-07 Werner LEMBERG + + * doc/groff.texinfo: Better documentation of double quotes as + arguments. + Other minor fixes. + +2002-04-06 Werner LEMBERG + + * man/groff_font.man: Document names of special characters better. + * doc/groff.texinfo: Minor improvements. + + * tmac/lbp.tmac: Load latin1.tmac. + * tmac/X.tmac, tmac/Xps.tmac: Load latin1.tmac or cp1047.tmac. + + * font/devX*/*: Regenerated (all chars > 0x80 removed). + +2002-04-05 Werner LEMBERG + + * tmac/tty.tmac: Don't use shc request. + * tmac/latin1.tmac, tmac/cp1047.tmac: Translate soft hyphen to `\%'. + * NEWS: Updated. + + * man/groff_diff.man: Minor fixes. + + * font/devlbp/*: Remove all `charXXX' entities. + + * src/libs/libgroff/font.cc (font::~font): Deallocate + `special_device_coding'. + (font::load): Use `new' for allocating `special_device_coding'. + * src/libs/libgroff/nametoindex.cc (character_indexer::lookup_char): + Removed unused member. + +2002-04-05 Werner LEMBERG + + * src/drivers/grops/psrm.cc (skip_possible_newline): New function. + (resource_manager::do_begin_binary, + resource_manager::do_begin_data): Use it. + + * doc/texinfo.tex: Updated to version 4.2. + + * src/roff/troff/token.h: Add TOKEN_ZERO_WIDTH_BREAK for `\:'. + (token::zero_width_break): New inline function. + * src/roff/troff/input.cc (token::next): Use it. + (token::description): Updated. + (encode_char): Ignore `\%', `\&', `\)', and `\:'. + (token::add_to_node_list, token::process): Use it. + * NEWS, doc/groff.texinfo: Updated. + + * src/preproc/eqn/over.cc (over_box::output): Fix typo. + * tmac/tty.tmac: Add missing backslash. + +2002-04-04 Tadziu Hoffmann + + * src/preproc/eqn/box.cc (set_script_size, box::top_level): Use + `.ps' register instead of `.s' to handle fractional point sizes. + * src/preproc/eqn/limit.cc (limit_box::compute_metrics, + limit_box::output): Ditto. + * src/preproc/eqn/other.cc (size_box::compute_metrics, + size_box::output): Ditto. + * src/preproc/eqn/over.cc (over_box::compute_metrics, + over_box::output): Ditto. + * src/preproc/eqn/script.cc (script_box::compute_metrics, + script_box::output): Ditto. + * src/preproc/eqn/sqrt.cc (sqrt_box::compute_metrics, + sqrt_box::output): Ditto. + +2002-04-03 Michael Selway + + * src/drivers/grops/psrm.cc (resource_manager::do_begin_binary): + Fix typo. + +2002-04-03 Werner LEMBERG + + * doc/homepage.ms: Reduce title size. + * doc/groff.texinfo: Fix documentation of .t register. + Fix handling of colon. + Fix `\' vs. `\\'. + + * src/roff/troff/input.cc (exit_troff): Emit LAST_PAGE_EJECTOR + only if page length is positive to avoid a loop. + + * tmac/an-old.tmac (ne): Increase page length to avoid problems with + tbl. + +2002-04-02 P. Alejandro Lopez-Valencia + + * src/include/nonposix.h, src/roff/groff/pipeline.c: + s/__CYGWIN32__/__CYGWIN__/. + +2002-03-28 Gaius Mulley + + * doc/gnu.xpm: New image contributed by Emily Mulley. + * doc/Makefile (gnu.eps, gnu.png): Use pnmdepth. + (homepage.html): Be dependent on gnu.eps. + * doc/homepage.ms: Updated to new image. + + * src/devices/grohtml/post-html.cc (html_printer): New member + `sbuf_prev_hpos'. + (html_printer::flush_sbuf, html_printer::set_char): Set it. + (html_printer::sbuf_continuation): Use it. + +2002-03-28 Werner LEMBERG + + * src/libs/libgroff/getopt.c: Updated to latest version. + + * tmac/README: More on hyphen.tex license. + +2002-03-26 Larry Kollar + + * doc/groff.texinfo: Add documentation of most missing requests. + +2002-03-25 Werner LEMBERG + + Add three glyphs `t+-', `tmu', and `tdi' which are textual variants + of `+-', `mu', and `di', respectively. + + * font/devascii/R.proto, font/devutf8/R.proto, + font/devlatin1/R.proto, font/devhtml/R.proto, + font/devcp1047/R.proto, font/devlpb/*: Add them. + * font/devps/generate/textmap: Ditto. + * font/devps/*: Regenerated. + * font/devlj4/generate/text.map: Add them. + * font/devlj4/*: Regenerated. + * font/devdvi/generate/tc.map: Use them. + * font/devdvi/generate/texsy.map: Add them. + * font/devdvi/*: Regenerated. + * font/devX*/*: Regenerated. + + * tmac/latin1.tmac, tmac/cp1047.tmac, tmac/tty.tmac, + tmac/tty-char.tmac: Updated. + + * NEWS, man/groff_char.man: Updated. + +2002-03-24 Werner LEMBERG + + * tmac/dvi.tmac, tmac/X.tmac, tmac/ps.tmac, tmac/html.tmac, + tmac/lj4.tmac, tmac/tty.tmac: Replace most `.char' with `.fchar'. + * tmac/ec.tmac: Remove `.rchar' calls (no longer necessary since + we use `.fchar' in dvi.tmac. + * tmac/dvi.tmac: Improve definition of \[Fo] and \[Fc]. + * tmac/Xps.tmac: Simplify some char definitions. + Add definition for \[f/]. + * man/groff_char.man: Updated for new X.tmac. + + * tmac/README: New file. + +2002-03-23 Phil Lobbes + + * Makefile.comm (.y.o): New rule for make on Solaris 2.5.1 -- the + internal .y.o rule took precedence over the .y.cc rule, compiling + the yacc files with gcc instead of g++. + +2002-03-23 Werner LEMBERG + + * tmac/dvi.tmac: Add replacement font for `CB'. + + * tmac/doc.tmac: s/request/macro/ in messages. + (doc-generic-macro): Improve error message. + * tmac/groff_mdoc.man: Minor improvements. + +2002-03-22 Werner LEMBERG + + * doc/groff.texinfo: Document possible conflict between `tr' and + `char' requests. + +2002-03-21 Werner LEMBERG + + Improve handling of hyphenation patterns. It is now possible to + use most of TeX's pattern files unmodified. To make the process + more flexible, a new request `hpfcode' has been added which + provides a character code mapping for the `hpf' request. See + comment before hpf_getc() for more details. + + * src/roff/troff/env.cc (insert_hyphenation, hpf_getc): New + functions. + (read_patterns_file): Additional parameter for exception dictionary. + Extended to recognize \pattern, \hyphenation, and \endinput. + (do_hyphenation_patterns_file): Updated. + * src/roff/troff/env.h (hpf_code_table): New extern. + + * src/roff/troff/input.cc (hpf_code_table): New array. + (init_hpf_code_table, hyphenation_patterns_file_code): New + functions. + (hyphenation_code): Handle translation from `trin' correctly. + (main, init_input_requests): Updated. + (charinfo::set_translation): Handle hyphenation code also. + + * src/roff/troff/charinfo.h (charinfo::get_translation_input): New + inline function. + + * src/roff/troff/env.cc (WORD_MAX): Reduced to 256 since `unsigned + char' is used for offsets in hyphenation exceptions. + + * tmac/hyphen.us: Replace with contents of unmodified `hyphen.tex'. + + * NEWS, man/groff_diff.man, man/groff.man: Document it. + +2002-03-20 Larry Kollar + + * doc/groff.texinfo: Add documentation for `hpfa' and `trin' + requests. + +2002-03-18 Werner LEMBERG + + * tmac/html.tmac: Fix serious typo. + +2002-03-17 Larry Kollar + + * doc/groff.texinfo: Add documentation for `writec' request. + +2002-03-17 Werner LEMBERG + + Added request `hpfa' to append hyphenation patterns. + + * src/roff/troff/env.cc (hyphen_trie::read_patterns_file): Add + parameter `append'. + (hyphenation_patterns_file): Renamed to... + (do_hyphenation_patterns_file): This. + (hyphenation_patterns_file, hyphenation_patterns_file_append): New + functions. + (init_hyphen_requests): Updated. + * NEWS, man/groff.man, man/groff_diff.man: Document it. + +2002-03-16 Werner LEMBERG + + Added request `writec' in analogy to `tmc'. + + * src/roff/troff/input.cc (write_request): Renamed to... + (do_write_request): This. + Added one parameter. + (write_request, write_request_continue): New functions. + (init_input_requests): Updated. + * NEWS, man/groff.man, man/groff_diff.man: Document it. + + * font/devdvi/DESC.in (sizes): Allow all sizes in the range + 5-10000pt. + * NEWS: Document it. + +2002-03-15 Werner LEMBERG + + * man/groff.man: Add writem request. + + Add request `trin' (translate input) to make `.asciify' work + correctly. This is necessary since `charXXX' entity names are no + longer hardcoded in font definition files. + + * src/roff/troff/charinfo.h (charinfo): Add `asciify_code' and + `translate_input' members. + (charinfo::set_asciify_code, charinfo::get_asciify_code, + charinfo::set_translation_input): New methods. + (charinfo::set_translation): Add third argument. + * src/roff/troff/input.cc (charinfo:set_translation): Set + `asciify_code'. + (do_translate): Add second argument. + (translate_input): New function. + (init_input_requests): Updated. + * src/roff/troff/node.cc (glyph_node::asciify, + composite_node::asciify): Use `get_asciify_code'. + + * tmac/cp1047.tmac, tmac/latin1.tmac: Use `trin'. + + * NEWS, man/groff.man, man/groff_diff.man: Updated. + +2002-03-14 Larry Kollar + + * doc/groff.texinfo: Improve documentation of .RS and .RE. + +2002-03-14 Werner LEMBERG + + Add a new request `sizes' similar to the `sizes' command in DESC + files. + + * src/roff/troff/env.cc (override_sizes): New function. + (init_env_requests): Use it. + * src/roff/troff/token.h: Export `read_string'. + * NEWS, man/groff_diff.man, man/groff.man: Document it. + +2002-03-12 Werner LEMBERG + + * doc/groff.texinfo: More fixes for texinfo 4.1 and higher. + +2002-03-10 Werner LEMBERG + + * tmac/pspic.tmac: Add support for -Tdvi. + * tmac/dvi.tmac: Include pspic.tmac. + * src/devices/grodvi/grodvi.man: Document it. + * NEWS: Updated. + + * font/devlj4/generate/Makefile: Fix URL of metric files. + +2002-03-09 Werner LEMBERG + + * PROBLEMS: The static constructor bug has been fixed in z/OS V1R3. + +2002-03-09 Larry Kollar + + * tmac/groff_ms.man: Add documentation for RS and RE macros. + +2002-03-08 Werner LEMBERG + + * doc/groff.texinfo: Fixes for texinfo 4.1. + +2002-03-07 Werner LEMBERG + + * src/include/lib.h: Include getopt.h if groff-getopt.h can't be + included. + Handle CYGWIN properly. + +2002-03-07 Paco Andrés Verdú + + * font/devlbp/Makefile.sub (DEVFILES): Add some missing fonts. + * tmac/lbp.tmac: Add some font translations. + +2002-03-02 Werner LEMBERG + + * font/devcp1047/R.proto, font/devlatin1/R.proto, + font/devhtml/R.proto: Remove `charXXX' entries. + * tmac/tty.tmac, tmac/html.tmac: Load latin1.tmac or cp1047.tmac + where appropriate. + + * font/devlj4/generate/text.map: Remove `charXXX' entries. + * font/devlj4/*: Regenerated all font definition files. + * tmac/lj4.tmac: Load latin1.tmac. + + * src/utils/hpftodit/hpftodit.cc (do_file): Partially undo change + from 2000-06-17: LJ4 metric files are *not* text files. + + * tmac/troffrc, tmac/dvi.tmac, tmac/ps.tmac: Don't use .T string + register to test for EBCDIC. + +2002-03-01 Werner LEMBERG + + * src/utils/afmtodit/afmtodit.pl: Skip comment lines in encoding + files (as grops already does). + * src/utils/afmtodit/afmtodit.man: Document comment lines in map + files. + * src/devices/grops/grops.man: Document comment lines in encoding + files. + + * tmac/cp1047.tmac: New file. + * tmac/dvi.tmac, tmac/tty-char.tmac: Use it. + * tmac/ps.tmac: Load latin1.tmac or cp1047.tmac. + * tmac/Makefile.sub (NORMALFILES): Updated. + + * tmac/ec.tmac: Don't load latin1.tmac again. + + * font/devps/generate/lgreekmap, font/devps/generate/symbolchars, + font/devps/generate/dingbats.map, + font/devps/generate/dingbats.rmap, font/devps/text.enc, + font/devps/generate/Makefile (symbolmap): Add header comment. + * font/devps/generate/textmap: Ditto. + Remove `charXXX' entries. + * font/devps/symbolmap: Regenerated. + * font/devps/*: Regenerated all font definition files. + +2002-02-28 Werner LEMBERG + + Add color support to grodvi (for drawing colors are currently + translated to gray values). + + * src/devices/grodvi/dvi.cc (FILL_MAX): Removed. + (dvi_printer): Add `cur_color' member. + (dvi_printer::set_color): New function. + (draw_dvi_printer): Remove `fill'. + (draw_dvi_printer::fill_next): Pass environment as parameter. + Update code for new color support translated to gray. + (dvi_printer::set_char): Updated. + (dvi_printer::begin_page, dvi_printer::end_page): Handle color + changes crossing the page border. + (dvi_printer::draw): Updated. + Remove cases `f' and `F'. + * tmac/dvi.tmac: Add color definitions. + * NEWS, src/devices/grodvi/grodvi.man: Updated. + + * tmac/an-old.tmac (R): Make this a macro to emit a warning if + used incorrectly. + + * aclocal.m4 (GROFF_NEED_DECLARATION): Use test similar to recent + versions of autoconf. + * configure: Updated. + + * doc/homepage.ms: Use `.blm'. + * tmac/www.tmac (www-depth): New auxiliary variable. + (www-pop-level): Don't issue HTML tag. + (ULS, ULE, LI): Use absolute indentation. + + * src/devices/grops/ps.cc (ps_printer::begin_page, + ps_printer::end_page): Switch forth and back to default color while + starting a new page. + +2002-02-27 Werner LEMBERG + + Add EC and TC fonts to devdvi. + + * src/utils/tfmtodit/tfmtodit.man: Document patching of exbase.mf. + * font/devdvi/generate/cork.map: Renamed to... + * font/devdvi/generate/ec.map: This. + Remove entry for `aq'. + * font/devdvi/generate/tc.map: New file. + * font/devdvi/generate/Makefile (*EC, *TC): New creation rules for + EC and TC fonts. + (FONTS): Updated. + * font/devdvi/*EC, font/devdvi/*TC: New font definition files. + * font/devdvi/Makefile.sub (DEVFILES): Updated. + * tmac/ec.tmac: New file. + * tmac/Makefile.sub (NORMALFILES): Updated. + * NEWS, src/devices/grodvi/grodvi.man: Updated. + * man/groff_char.man: Check `ECFONTS' register. + + * font/devdvi/{TR,TI,TB,TBI,HR}: Fix `name' field. + +2002-02-26 Werner LEMBERG + + * font/devdvi/generate/*.map: Remove all `charXXX' entries. + * font/devdvi/generate/cork.map: Add 'y and 'Y. + * font/devdvi/*: Updated. + * tmac/dvi.tmac: Formatting. + + Add font `HBI' for the dvi output. + Add support for font families `T' and `H'. + + * font/devdvi/HBI: New file. + * font/devdvi/B: Renamed to ... + * font/devdvi/TB: This. + * font/devdvi/BI: Renamed to ... + * font/devdvi/TBI: This. + * font/devdvi/I: Renamed to ... + * font/devdvi/TI: This. + * font/devdvi/R: Renamed to ... + * font/devdvi/TR: This. + * font/devdvi/H: Renamed to ... + * font/devdvi/HR: This. + * font/devdvi/Makefile.sub (DEVFILES): Updated. + * font/devdvi/generate/Makefile (HBI): New rule. + (FONTS): Updated. + (R, I, B, BI, H): Renamed to ... + (TR, TI, TB, TBI, HR): This, respectively. + (srcdir): Fixed. + * NEWS, src/devices/grodvi/grodvi.man: Updated. + * font/devdvi/DESC.in: Don't mount R, I, B, BI, and CWI. + Add `styles' and `family' keywords. + * tmac/dvi.tmac: Alias `H' to `HR'. + Add some fspecial requests for italic fonts. + Add TR and TI as special. + Add support for `_' with font CWI. + + * src/roff/troff/number.cc (parse_expr): Add missing `break' for + operator `:'. Until now, the expression `0:1' would return 2 + instead of 1. + +2002-02-25 Werner LEMBERG + + * man/groff_char.man: Added some missing PS glyph names (from the + Adobe Glyph List). + * font/devps/generate/textmap, font/devps/symbolmap: Add + `arrowupdn'. + + * doc/groff.texinfo: Minor additions and fixes. + * man/groff_diff.man: Remove documentation of fp request. This + is already covered in the original troff manual. + Updated to be consistent with other doc files. + * NEWS: Updated. + +2002-02-24 Werner LEMBERG + + * aclocal.m4 (GROFF_EBCDIC): Don't include `font/devutf8' in + TTYDEVDIRS. + Define new variable OTHERDEVDIRS (containing `font/devlj4 + font/devlbp' if not EBCDIC). + * Makefile.in (TTYDEVDIRS): Always include `font/devutf8'. + (OTHERDEVDIRS): New variable. + (MDEFINES, DEVDIRS, ALLDIRS, DISTDIRS): Updated. + * configure: Regenerated. + + * NEWS, src/devices/grotty/grotty.man: Updated. + +2002-02-23 Werner LEMBERG + + * src/roff/troff/input.cc (do_overstrike, do_bracket, + get_line_arg): Honour input level. + + Add new symbol `mc' corresponding to U+00B5 MICRO SIGN. + + * font/*/*: Implement it in all font files. + * font/devps/generate/textmap, font/devps/generate/symbolchars, + * font/devps/symbolmap: Updated. + * font/devlj4/generate/text.map: Updated. + * font/devdvi/generate/CompileFonts (sizes): Add LaTeX sizes. + * font/devdvi/generate/texmi.map: Updated. + + * font/devutf8/R.proto: Remove all `charXXX' entries. + * font/devutf8/NOTES: Updated. + + * font/devX*/*: Regenerated with xtotroff, using fonts from XFree86 + version 4.1.0. + + * tmac/latin1.tmac, tmac/psold.tmac, tmac/tty-char.tmac: Updated. + + * NEWS, man/groff_char.man: Updated. + +2002-02-21 Phil Lobbes + + * src/include/lib.h [HAVE_SNPRINTF]: Include stdarg.h. + +2002-02-20 Ralph Corderoy + + * src/roff/grog/grog.pl: Fix computation of $refer. + +2002-02-19 Werner LEMBERG + + * src/include/lib.h [!HAVE_SNPRINTF]: Add declarations for + `snprintf' and `vsnprintf'. + + * src/include/htmlindicate.h: Renamed to... + * src/include/htmlhint.h: This. + * src/include/Makefile.sub: Updated. + * src/preproc/eqn/main.cc: Updated. + +2002-02-18 Werner LEMBERG + + * man/roff.man, man/groff_out.man, man/groff.man, + man/groff_diff.man, man/ditroff.man, src/roff/groff/groff.man, + src/roff/troff/troff.man: Updated to latest changes in www.tmac. + + * win32-diffs: Updated. + +2002-02-17 Werner LEMBERG + + * doc/Makefile (clean): Add *.eps. + (MEMACROS): Removed. + (TFLAG): New variable. + (TROFF): Use it. + Add -ww. + (GROFF): Use TFLAG, FFLAG, -U, -p, -e, -t, and -ww. + (.me.dit): Fixed. + (.ms.html, .ms.ascii, .ms.ps, homepage.html): Simplify. + + * tmac/www.tmac: Use dummy diversion while resetting and disabling + `.tl'. + * tmac/e.tmac: Inserted some more `\"' to remove warnings if used + unstripped. + * src/roff/troff/troff.man: Fix order of parameter description. + + * NEWS: Updated. + +2002-02-16 Gaius Mulley + + Simplify image handling for grohtml. + Fix

bug. + + * src/devices/grohtml/html-text.cc (DEBUGGING): Don't undefine but + comment out. + (html_text::dump_stack): Don't emit newline while debugging. + (html_text::do_push) [DEBUGGING]: Print more info. + (html_text::check_emit_text): Fix handling of

. + * src/devices/grohtml/html.h: Updated. + * src/devices/grohtml/output.cc (FPUTC, FPUTS, PUTC): New macros, + replacing `fputc', `fputs', `putc'. If DEBUGGING is defined, they + send its data to stderr also. + Update all callers. + (simple_output::space_or_newline) [DEBUGGING]: Removed. + * src/devices/grohtml/post-html.cc (html_printer::do_links, + html_printer::html_printer): Remove `DEBUGGING' conditionals. + + * src/include/html-strings.h (HTML_IMAGE_{CENTERED,LEFT,RIGHT,END}): + Removed. + * src/libs/libgroff/htmlhint.cc (is_in_graphic_start, + is_inline_image): Removed. + (html_begin_suppress, html_end_suppress): Don't take a parameter. + (graphic_start, graphic_end): Removed. + * src/include/htmlindicate.h: Updated. + * src/preproc/html/pre-html.cc (DEBUG_HTML): Removed. + (macroset_template): New global variable. + (makeFileName): Use `macroset_template'. + (write_end_image): Don't take a parameter. + Don't emit newline. + (write_start_image: Don't emit newline. + (char_buffer::write_upto_newline): Updated. + (char_buffer::skip_to_newline): Renamed to ... + (char_buffer::skip_until_newline): This. + Fix code. + (char_buffer::write_file_troff, char_buffer::write_file_html): + Simplified. + (createAllPages, createImage) [DEBUGGING]: Handle `debug' flag. + (removeAllPages): Remove `DEBUGGING' conditionals. + (addRegDef, dump_args): New functions. + (char_buffer::do_html, char_buffer::do_image): Handle + `www-image-template' command line variable. + Add more debugging code. + (addps4html): Removed. + (removeTempFiles) [DEBUGGING]: Handle `debug' flag. + + * src/preproc/eqn/main.cc: Include `ctype.h'. + (suppress_html): Removed. + (do_file): Updated. + (inline_equation): Use `html_begin_suppress' and + `html_end_suppress'. + * src/preproc/pic/troff.cc: Don't include `htmlindicate.h'. + (troff_output::start_picture, troff_output::finish_picture): + Updated. + * src/preproc/tbl/main.cc: Don't include `htmlindicate.h'. + (process_input_file): Updated. + + * src/roff/troff/div.cc (page_number): Set page number only if the + `ps4html' register isn't defined. + * src/roff/troff/input.cc (image_no): New external variable. + (do_suppress): Use it. + * src/roff/troff/node.h (suppress_node::image_id): New member. + * src/roff/troff/node.cc (image_no): Remove `static' keyword. + (suppress_node::suppress_node): Initialize `image_id' member. + (suppress_node::same): Handle `image_id' also. + (suppress_node::copy): Updated. + (last_image_id): New global variable. + (suppress_node::tprint): Use it. + + * tmac/an-old.tmac (TS, TE, EQ, EN): Use HTML-IMAGE and + HTML-IMAGE-END. + * tmac/pspic.mac (PSPIC): Fix html support. + * tmac/s.tmac (@EQ, @EN, @TS, TE, PS, PE): Ditto. + * tmac/www.tmac (www-image-template): Set up. + (HTMLINDEX): Renamed to... + (HX): This. + (BODYCOLOR): Renamed to... + (BCL): This. + (BACKGROUND): Renamed to... + (BGIMG): This. + (URL): Change order of parameters for consistency. + (MAILTO): Renamed to... + (MTO): This. + (IMAGE, PNG-IMAGE, MARGIN-PNG-IMAGE): Renamed to... + (IMG, PIMG, MPIMG): This. + (HTML-H-BEGIN, HTML-H-END): Renamed to... + (HnS, HnE): This. + (LINKS): Renamed to... + (LK): This. + (LINE): Renamed to... + (HR): This. + (NO-AUTO-RULE): Renamed to... + (NHR): This. + (HTML-TL): Renamed to... + (HTL): This. + (UL-BEGIN, UL-END): Renamed to... + (ULS, ULE): This. + (DROPCAP): Renamed to... + (DC): This. + (TS, TE, EQ, EN): Provide default definitions. + (www-make-unique-name): Updated. + (HTML-IMAGE-INLINE): Fix typo. + * tmac/groff_www.man: Updated. + + * doc/Makefile (homepage.html): Add option -r to grohtml. + Use shortened image name. + * doc/groff.texinfo: Updated info on grohtml strings and macros. + * doc/homepage.ms: Updated and extended. + +2002-02-14 Werner LEMBERG + + Don't use `CSI 39 m' and `CSI 49 m' but `CSI 0 m'. + + * src/devices/grotty/tty.cc (SGR_DEFAULT_COLOR, + SGR_BACK_DEFAULT_COLOR): Replaced with ... + (tty_printer::put_color): Use it. + (ttr_printer::end_page): Simplify. + +2002-02-13 Werner LEMBERG + + * tmac/groff_tmac.man: Moved to... + * man/groff_tmac.man: This place. + * tmac/Makefile.sub, man/Makefile.sub: Updated. + +2002-02-12 Werner LEMBERG + + * src/libs/libgroff/Makefile.sub (snprintf.o): Don't use + $(COMPILE.c) to not include groff's assert.h. + + * src/drivers/grotty/tty.cc (main): Add GROFF_NO_SGR environment + variable. + * NEWS, src/drivers/grotty/grotty.man: Document it. + +2002-02-11 Werner LEMBERG + + * src/libs/snprintf/snprintf.c: Updated to latest version + (2002-02-11). + + * src/roff/grog/grog.pl (process): Fix handling of `.['. We now + test whether there is `.]' also. + Don't check for spaces after `.['. + * src/roff/grog/grog.sh: Do the same. + +2002-02-10 Werner LEMBERG + + Illegal -> Invalid. + + * src/libs/libgroff/illegal.cc: Renamed to ... + * src/libs/libgroff/invalid.cc: This. + (illegal_char_table): Renamed to ... + (invalid_char_table): This. + * src/libs/libgroff/Makefile.sub: Updated. + * win32-diffs: Updated. + + * doc/groff.texinfo, src/devices/grops/psrm.cc (ps_get_line), + src/libs/libdriver/input.cc (fatal_command, parse_color_command, + parse_x_command), src/libs/libgroff/font.cc (text_file::next, + font::load), src/preproc/eqn/main.cc (read_line, main), + src/preproc/eqn/lex.cc (file_input::read_line), + src/preproc/pic/lex.cc (file_input::read_line, + simple_file_input::get, simple_file_input::peek), + src/preproc/pic/main.cc (top_input::get, top_input::peek), + src/preproc/pic/pic.man, src/preproc/refer/main.cc + (input_stack::push_file), src/preproc/refer/refer.cc (do_file, + do_bib), src/preproc/tbl/main.cc (table_input::get), + src/preproc/grn/grn.man, src/preproc/grn/main.cc (interpret), + src/roff/troff/input.cc (file_iterator::fill, file_iterator::peek, + do_zero_width, read_request, encode_char, ps_get_line, + transparent_file, get_char_for_escape_name, transparent_translate, + asciify, input_char_description, read_string, set_string), + src/roff/troff/env.cc (environment::add_html_tag), + src/roff/troff/troff.man, tmac/e.tmac (`@(', `(f'): Do it. + + * src/include/lib.h: Updated. + + * src/preproc/eqn/eqn.cc: Removed. + + * NEWS: Updated. + + * src/preproc/grn/hdb.cc (DBRead): Fix fscanf() fields. + +2002-02-09 Werner LEMBERG + + * doc/gnu.xpm: New image. + * doc/Makefile (DOCS): Add homepage.ps. + Add rules for converting xpm->png and xpm->eps. + Use `gnu.{xpm,eps}' as image names. + * doc/homepage.ms: Updated. + +2002-02-09 Gaius Mulley + + * tmac/www.tmac (www-error): New macro, replacing calls to `@error'. + (IMAGE): Change image position parameters to `-L', `-R', and `-C'. + Remove calls to `B1' and `B2' + (PNG-IMAGE): New macro for inclusion of images in PNG format. + (www-left-ll-trap, www-left-po-trap, www-right-ll-trap): New + auxiliary variables for MARGIN-PNG-IMAGE. + (www-finish-left-po, www-finish-right-ll, www-finish-left-ll): New + auxiliary macros for MARGIN-PNG-IMAGE. + (MARGIN-PNG-IMAGE): New macro to put an image in PNG format into + the margin. + (www-heading-no): New auxiliary variable for HTML-H-{BEGIN,END}. + (HTML-H-BEGIN, HTML-H-END): New macros to begin and end a heading. + (DROPCAP): New macro to produce dropcap characters. + (www-do-image): Renamed back to... + (HTML-DO-IMAGE): This. + Updated all callers. + + * doc/Makefile (gnubw.eps): Updated. + * doc/homepage.ms: Updated. + +2002-02-08 Werner LEMBERG + + * doc/pic.ms: Fixed typos (\(*tx -> \*(tx). + Added `linethick' to table in section `Style Variables'. + +2002-02-08 Gaius Mulley + + * src/libs/libdriver/input.cc (get_extended_arg): Fix conditional. + +2002-02-07 Werner LEMBERG + + Adding options -C (compatibility mode) and -c (grotty's old output + scheme) to nroff. + + * src/roff/nroff/nroff.sh: Implement it. + Remove `-Wall'. + * NEWS, src/roff/nroff/nroff.man: Updated. + + * PROBLEMS: Document bison 1.32 bug. + + Some fixes to make groff compile on z/OS 1.2 UNIX (was OS/390). + + * src/roff/troff/node.cc (make_tfont): Define it earlier. + * src/roff/troff/div.h: Add prototype for `end_diversions'. + * src/roff/troff/input.cc: Add prototype for `process_input_stack'. + * src/roff/troff/env.h: Add prototype for `title'. + + Adding EBCDIC support to grotty. + + * src/devices/grotty/tty.cc (CSI): New macro. + (SGR_*, tty_printer::put_color): Use it. + +2002-02-06 Werner LEMBERG + + Implementing color support in grotty. The new switch -c activates + the old drawing scheme, disabling color at the same time. The new + switch `-i' selects italic instead of underlining (SGR only). + + * src/devices/grotty/tty.cc (putstring): New define instead of + `fputs'. Updated all callers. + (old_drawing_scheme): New global variable. + (COLOR_CHANGE): New enum value. + (SGR_*): New defines containing color handling escape sequences. + (TTY_MAX_COLORS, DEFAULT_COLOR_IDX): New defines. + (glyph): New members `back_color_idx' and `fore_color_idx'. + (glyph::order): Add COLOR_CHANGE. + (tty_printer): New members `cur_fore_idx', `curr_back_idx', + `is_underline', `is_bold', `cu_flag', `tty_colors'. + New methods `make_underline', `make_bold', `color_to_idx', + `change_color', `put_color'. + (cu_flag): Moved into `tty_printer' class. + (tty_printer::tty_printer): Initialize colors. + (tty_printer::add_char, tty_printer::set_char, tty_printer::special, + tty_printer::draw, tty_printer::end_page): Handle colors also. + (main): Add options `-c' and `-i'. + (usage): Updated. + * NEWS, src/devices/grotty/grotty.man: Updated. + + * src/include/errarg.h (errarg): Add support for `unsigned int'. + * src/libs/libgroff/errarg.c: Implement it. + + * src/include/printer.h (printer): Add `change_color' method + (currently used by grotty only). + * src/libs/libdriver/printer.cc: Implement it. + * src/libs/libdriver/input.cc (parse_D_command, do_file): Add + call to `pr->change_color'. + + * src/roff/troff/node.cc (troff_output_file::fill_color, + troff_output_file::glyph_color): Call `do_motion'. + + * tmac/tty.tmac: Add color definitions. + + * src/roff/groff/groff.man: Minor fixes. + +2002-02-05 Bernd Warken + + * src/libs/libdriver/input.cc: Introduce `EnvInt' typedef and use + it. This is a preparation for future changes. + +2002-02-05 Werner LEMBERG + + * src/roff/troff/input.cc (process_input_stack): Fix the case + where leading spaces are followed by \f or \s; previously, an + incorrect space width has been used. + + * doc/roff.man (quoted_char): Fix argument. + (comment): Define string. + +2002-02-04 Larry Kollar + + * doc/groff.texinfo: More fixes. + +2002-02-04 Werner LEMBERG + + * src/preproc/eqn/box.cc (output_string): Don't use \\*[...]. + * src/preproc/eqn/main.cc (do_file, inline_equation): Call + `restore_compatibility' before `output_string' -- the LINE_STRING + register now already contains proper switches from and to + compatibility mode. + + * man/groff_char.man: Add Euro symbol. + * man/groff_diff.man: Improve documentation of `.am1' and `.as1'. + * tmac/tty.tmac: Add `EUR' as replacement for `eu' and `Eu'. + * doc/groff.texinfo (Defstr*): Print strings with full syntax. + Other minor fixes. + + * doc/Makefile (.SUFFIXES, .texinfo.pdf, clean): Add support for + texinfo->pdf. + (.texinfo.html): Add support for texinfo->html. + +2002-02-03 Werner LEMBERG + + Added three new requests `ds1', `as1', and `ami'. The former two + are equivalent to `ds' and `as' with the difference that + compatibility mode is saved on entry, switched off during string + expansion, and restored on exit. The latter is the pendant to `dei' + for `am'. + + (do_define_string): Use `define_mode' and `calling mode'. + Insert COMPATIBLE_SAVE and COMPATIBLE_RESTORE at the beginning and + end of string, respectively. + (define_string, append_string): Use `calling_mode'. + (define_nocomp_string, append_nocomp_string, + define_string_indirect): New functions. + (init_input_requests): Updated. + * NEWS, man/groff_diff.man, man/groff.man: Document it. + + * src/preproc/eqn/box.cc (box::top_level, box::extra_space): Use + `as1' for assigning LINE_STRING (this is `10' usually). Sun's + mm macro package accesses this string register directly. + * src/preproc/eqn/main.cc (inline_equation): Use `as1'. + + * tmac/trace.tmac: Trace calls to `am' also. Make it work in + compatibility mode. + +2002-02-02 Larry Kollar + + * doc/groff.texinfo, tmac/groff_ms.man: More fixes. + +2002-01-31 Werner LEMBERG + + * tmac/an-old.tmac (I): Use \, and \/ to improve spacing. + +2002-01-31 Bernd Warken + + * src/devices/grolbp/lbp.cc (main): Delete `pr'. + * man/groff_out.man: Revised and updated. + +2002-01-30 Bernd Warken + + * src/libs/libdriver/input.cc [USE_ENV_STACK]: New macro to comment + out the unused `{' and `}' commands. Undefined by default. + (IntArray): Make `data' private. + (IntArray::operator[], IntArray::get_data, IntArray::len): Use these + new methods instead. + (skip_line_D, skip_to_end_of_line): New functions. + (get_D_fixed_args): Use `skip_line_D'. + Changed to handle dummy odd arguments by ... + (get_D_fixed_args_odd_dummy): This new function. + (get_D_variable_args): Split some code into ... + (get_possibly_integer_args): This new function. + (send_draw): Use more `const'. + (delete_current_env): New function. + (position_to_end_of_args): Use `size_t'. + Updated. + (send_draw): Updated. + (parse_D_command): Handle `c', `C', and `t' better. + Updated. + (do_file): Updated. + +2002-01-29 Werner LEMBERG + + * NEWS: Revised. + * doc/groff.texinfo: Introduce @Def...List, @Def...Item, and + @Def...ListEnd which replaces @Def...x. This is necessary to get + proper HTML output -- see the comment in the file for more + information. + Updated all calls. + +2002-01-29 Gaius Mulley + + Fixes to make color changes of 2002-01-21 work with grohtml. + + * src/devices/grohtml/post-html.cc (style): Updated. + (html_printer): Remove unused methods. + (html_printer::do_font, html_printer::draw, html_printer::set_char, + html_printer::special): Updated. + * src/devices/grohtml/html-text.cc (debugStack, turnDebug, + html_text::dump_stack_element, html_text::dump_stack) [DEBUGGING]: + Added some debugging code. + (html_text::start_tag): Updated. + (html_text::do_push): New method. + (html_text::push_para): Call it. + Add method for handling color. + (html_text::do_color): Updated. + (html_text::shutdown): Handle color. + * src/devices/grohtml/html-text.h (tag_definition): New member + `col'. + Updated. + +2002-01-28 Werner LEMBERG + + * tmac/ps.tmac, tmac/html.tmac: Fix compatibility mode issues. + +2002-01-27 Gaius Mulley + + Add two switches -a and -g to control the antialiasing bits for + text and graphics, respectively. + + * src/devices/grohtml/post-html.cc (main): Dummy code for `-a' and + `-g'. + * src/devices/grohtml/grohtml.man: Document them. + * src/preproc/html/pre-html.cc (MIN_ALPHA_BITS, MAX_ALPHA_BITS): + New macros. + (textAlphaBits, graphicAlphaBits, antiAlias): New global variables. + (setupAntiAlias): New function. + (createAllPages): Updated. + (scanArguments): Handle `-a' and `-g'. + (main): Call `setupAntiAlias'. + * NEWS: Updated. + +2002-01-27 Werner LEMBERG + + * doc/groff.texinfo (Def*): Call index function after deffn. + + * tmac/html.tmac: Call `nroff' request. + +2002-01-26 Larry Kollar + + * tmac/groff_ms.man: Add some omissions. + +2002-01-25 Larry Kollar + + * tmac/groff_ms.man: Typographical improvements. + +2002-01-25 Werner LEMBERG + + * doc/groff.texinfo: Updated version and copyright. + * src/devices/grops/grops.man: Updated. + + * tmac/groff_tmac.man: Fix `ig' macro. + + * tmac/an-old.tmac (ne): Redefine `ne' request to be a no-op in + nroff mode. + Use `.ne' unconditionally everywhere. + (TS): Only insert some vertical space. Doing a page break is no + longer necessary due to the redefinition of the `ne' request. + + * src/libs/libdriver/input.cc (parse_D_command): Don't emit a + warning for unknown subcommands but parse and pass them to the + device driver. + +2002-01-24 Werner LEMBERG + + * tmac/groff_www.man, NEWS: Fix typos. + +2002-01-21 Werner LEMBERG + + Complete revision of color support: + + Adapt programs to the new libdriver/input.cc. + + Color spaces are no longer converted to RGB but transferred as-is + in the troff intermediate output format. + + Handle default color gracefully. troff now supports a `default' + color (which can't be changed). + + grops will now use the proper color space functions if available. + + Update pic. + + Note that currently grohtml doesn't handle colors properly. This + has to be fixed. + + * src/libs/libgroff/itoa.c (UINT_DIGITS): New macro. + (ui_to_a): New function. + * src/include/lib.h: Updated. + + * src/include/color.h (color_scheme): Replace `NONE' with `DEFAULT'. + (color): Simplified; removed all `double' members and methods. + A new array `components' now holds the color parameters. + (color::is_default, color::get_components): New methods. + (color::operator==, color:operator!=): New. + (Red, Green, Blue, Cyan, Magenta, Yellow, Black, Gray): New macros + to make access to the `components' array more comprehensible. + * src/libs/libgroff/color.cc: Implement new color support. + (atoh): Small fixes. + (color::read_encoding): Simplified for new troff intermediate color + output format. + (default_color): New global variable. + + * src/roff/troff/input.cc (default_symbol): New global variable. + (lookup_color): Use it. + (default_black): Removed. + (do_glyph_color, do_fill_color): Simplified. + (define_color): Handle default color. + Improve warnings. + (do_if_request): Handle default color. + * src/roff/troff/env.cc (environment::environment): Initialize + colors with `default_color'. + * src/roff/troff/node.cc (troff_output_file::put): Add method + for `unsigned int'. + (troff_output_file::hex): Removed. + (troff_output_file::fill_color, troff_output_file::glyph_color): + Updated to include/color.h and libdriver/input.cc. + + * src/preproc/pic/object.cc (draw_arrow): New parameter to set + fill color properly (identically to the outline color). \D'f...' + doesn't work any more. + All function calls to it updated. + + * src/devices/grohtml/post-html.cc (html_printer::do_body, main): + Updated. + * src/devices/grohtml/html-text.cc (html_text::issue_color_begin): + Updated. + + * src/devices/grops/ps.cc (ps_output::put_color): New method. + (ps_printer::sbuf_color): Make a real member instead of pointer. + (ps_printer::fill_color, ps_printer::output_color): Removed. + (ps_printer::ps_printer): Updated. + (ps_printer::set_char): Ditto. + (ps_printer::set_color): Use various color schemes. + Use `put_color' method. + (ps_printer::flush_sbuf): Don't set color. + (ps_printer::fill_path): Take `environment' as parameter. + Simplify color handling. + (ps_printer::set_line_thickness): Renamed to ... + (ps_printer::set_line_thickness_and_color): This (and updated). + (ps_printer::set_color): Change second parameter from `complete' + to `fill' which better describes what it does. + (ps_printer::draw): Call `flush_sbuf' to output graphic commands + and text in the right order. + Updated. + Remove branches for `f' and `F'; this is handled by + libdriver/input.cc. + * src/devices/grops/ps.h: Updated. + * font/devps/prologue (FL): Redefined. + ({F,C}r,k,g: New color functions (with and without filling). + + * doc/pic.ms, src/preproc/pic/pic.man: Small fixes. + * man/groff_diff.man, man/groff.man, man/groff_out.man, + doc/groff.texinfo, NEWS: Updated. + +2002-01-20 Bernd Warken + + * src/libs/libdriver/input.cc: Completely rewritten. See comments + in this file for what has been changed. + +2002-01-19 Werner LEMBERG + + * test-groff: Fix GROFF_FONT_PATH. + * tmac/andoc.tmac: Add dummy macros for equation support -- eqnrc + is read before .TH or .Dd is parsed. + +2002-01-18 Gaius Mulley + + * src/libs/libgroff/geometry.cc (check_output_arc_limits): Fix + quadrant boundaries. + +2002-01-18 Werner LEMBERG + + * devices/grops/ps.cc: Aargh! Fix the fix of the incorrectly + applied last patch. + +2002-01-17 Ruslan Ermilov + + * tmac/doc.common: Initialize %I register for the %I macro to + avoid (harmless) warning. + * tmac/doc.tmac (Bd): There is no reason to enforce -compact + when in the SYNOPSIS section. + +2002-01-17 Bruno Haible + + * src/preproc/pic/lex.cc (get_token): Fix typo. + +2002-01-17 Werner LEMBERG + + * devices/grops/ps.cc: Fix incorrectly applied last patch. + +2002-01-17 Larry Kollar + + * tmac/groff_ms.man: Completely rewritten. + +2002-01-16 Werner LEMBERG + + * tmac/an-old.tmac (TS): Force break, inserting some vertical space. + +2002-01-15 Gaius Mulley + + * devices/grops/ps.cc (ps_printer::fill_path): Fix handling of + fill colors. + (ps_printer::draw): Ditto. + +2002-01-14 Ruslan Ermilov + + * tmac/groff_mdoc.man: Minor fixes. + +2002-01-13 Werner LEMBERG + + * man/groff_out.man: Some fixes. + +2002-01-13 Gaius Mulley + + * doc/pic.ms: Fix typos. + +2002-01-12 Werner LEMBERG + + * doc/groff.texinfo, doc/groff.man: More on a printable backslash. + +2002-01-10 Werner LEMBERG + + * font/devutf8/R.proto, font/devhtml/R.prot: Add `Eu' and `eu' + symbols. + * NEWS: Updated. + +2002-01-09 Bernd Warken + + * man/groff_out.man: Revised. + * man/roff.man: Minor fixes. + * src/roff/troff/troff.man: Some reordering. + +2002-01-09 Werner LEMBERG + + * tmac/an-old.tmac: Add dummy macros for equation support. + +2002-01-07 Werner LEMBERG + + doc/groff.texinfo: Fix documentation of glyph searching algorithm. + + * tmac/an-old.tmac: Revert change 2001-12-23. This breaks too many + man pages. + * tmac/groff_man.man: Small improvements. + +2002-01-07 Bernd Warken + + * man/groff_diff.man: Revised. + +2002-01-06 Werner LEMBERG + + * tmac/www.tmac: Remove extraneous backslash. + +2002-01-06 Bernd Warken + + * man/ditroff.man, src/roff/groff/groff.man, man/groff.man: Revised. + +2002-01-05 Werner LEMBERG + + Integrated groffer, contributed by Bernd Warken. + + * contrib/groffer/*: New. + * Makefile.in, NEWS: Updated. + +2002-01-04 Werner LEMBERG + + * doc/groff.texinfo: Added macros `@Defmpreg' and `@Defmpregx' for + registers defined in macro packages. + Revising the ms part. + +2002-01-04 Larry Kollar + + * doc/groff.texinfo: Add documentation for ms macros. + +2002-01-02 Werner LEMBERG + + First step in adding PS support for the Euro symbol. `eu' is the + official Euro logo, `Eu' is a font-specific glyph variant. + + * font/devps/text.enc: Add `Euro' at position 9. + * font/devps/generate/textmap: Add `Euro' as symbol `Eu'. + * font/devps/symbolmap: Regenerated. + + * NEWS: Updated. + +2002-01-02 Bernd Warken + + * man/roff.man: Revised. + +2002-01-01 Bernd Warken + + * src/roff/groff/groff.man: Completely rewritten. + +2001-12-31 Werner LEMBERG + + * doc/Makefile: Updated. + +2001-12-30 Werner LEMBERG + + * tmac/www.tmac: Make all names of internal macros/registers/strings + lowercase, and prepend `www-'. + Other minor changes. + * src/roff/troff/troff.man: Add preprocessor string at BOF. + +2001-12-30 Gaius Mulley + + Implement option `-b' in grohtml to set the HTML background colour. + + * src/devices/grohtml/post-html.cc (default_background): New global + variable. + (html_printer::html_printer): Initialize `background' to + `default_background'. + (main): Implement option `-b'. + (usage): Updated. + * src/preproc/html/pre-html.cc (scanArguments): Add dummy handling + of `-b' option. + * src/devices/grohtml/grohtml.man: Updated. + * doc/Makefile (.ms.html): Use `-b'. + * tmac/html.tmac: Don't set background color. + + Add new grohtml tag `.html-tl'. + + * src/devices/grohtml/post-html.cc (title_desc): Add `with_h1' + member variable. + (title_desc::title_desc): Updated. + (html_printer::troff_tag): Handle `.html-tl'. + (html_printer::write_title): Use `with_h1'. + * tmac/www.tmac (www-end-nowhere): New auxiliary macro. + (HTML-TL): New macro. + + Add support for unordered lists in HTML. + + * tmac/www.tmac (www-level): New auxiliary register. + (www-level1, www-level2, www-level3): New auxiliary strings. + (www-push-level, www-pop-level): New auxiliary macros + (UL-BEGIN, UL-END, LI): User macros for unordered lists. + + Miscellaneous. + + * src/preproc/html/pre-html.cc (DEFAULT_IMAGE_RES): Increase to 100. + (DEFAULT_VERTICAL_OFFSET): Removed. + (IMAGE_BOARDER_PIXELS): Set to 0. + (A4_LENGTH, A4_OFFSET, LETTER_LENGTH, LETTER_OFFSET): New macros. + (vertical_offset): Initialize with 0. + (gsPaper): New global variable. + (get_resolution): Scan for and return unsigned int. + (get_papersize): New function to get paper length from devps/DESC. + (determine_vertical_offset): New function. + (createAllPages): Produce gray-level images and use proper page + length. + (createImage): Use `-quiet' option of pnmcrop. + (addZ): Fix passing of `-Z'. + (scanArguments): Fix handling of `-o'. + (main): Call `determine_vertical_offset'. + * src/devices/grohtml/post-html.cc (html_printer::draw): Comment out + code for `l'. + + * src/libs/libgroff/tmpfile.cc (add_tmp_file): Fix buffer length. + * src/roff/troff/node.cc (troff_output_file::check_charinfo): Handle + glyph descenders properly. + + * doc/homepage.ms: Include `gnubw.eps'. + * doc/Makefile (gnubw.eps): New rule. + (homepage.html): Depend on `gnubw.eps'. + +2001-12-25 Werner LEMBERG + + * src/roff/troff/input.cc (default_black): Fix return value. + +2001-12-24 Ruslan Ermilov + + * tmac/doc-common (Dt): Change output of architecture strings. + Do some syntax cleanup. + * tmac/groff_mdoc.man: Updated. + +2001-12-23 Werner LEMBERG + + Adding an `itc' request (input line trap accepting \c). + + * src/roff/troff/env.h (environment): New member + `continued_input_trap'. + Make `do_input_trap' a friend function instead of `input_trap'. + * src/roff/troff/env.cc (environment::environment, + environment::copy): Updated. + (environment::newline): Implement it. + (do_input_trap): New function. + (input_trap): Call `do_input_trap'. + (input_trap_continued): New function. + (init_env_requests): Updated. + * src/roff/troff/TODO: Updated. + + * tmac/an-old.tmac (SH, SS, B, I, SM, SB, TP): Use `.itc' instead of + `.it'. + + * src/preproc/grn/hdb.cc (DBRead): Really chop after 127 characters. + +2001-12-22 Ruslan Ermilov + + * tmac/doc-common, tmac/doc-syms: Small updates. + +2001-12-22 Colin Watson + + * tmac/an-old.tmac (an-p-footer): Set title length in environment 1. + +2001-12-22 Bernd Warken + + * MANIFEST: New file. + +2001-12-22 Werner LEMBERG + + * src/preproc/grn/grn.man: Updated. + +2001-12-22 Solar Designer + + * src/preproc/grn/hdb.cc (MAXSTRING_S): New macro. + (DBRead): Use it. + +2001-12-19 Werner LEMBERG + + Implement a fallback character request `.fchar'. + + * src/roff/troff/charinfo.h (charinfo): New flag `fallback'. + (is_fallback): New inline function. + * src/roff/troff/input.cc (do_define_character): New function. + (define_character): Call `do_define_character'. + (define_fallback_character): New function. + (init_input_requests): Add `fchar'. + (charinfo::charinfo): Updated. + (charinfo::set_macro): New argument to set `fallback' flag. + * src/roff/troff/node.cc (make_glyph_node, make_node, + node::add_char): Check `fallback' flag. + * NEWS, man/groff_diff.man, man/groff_man: Updated. + +2001-12-16 Werner LEMBERG + + * groff.texinfo: Document exact search algorithm for glyphs. + +2001-12-15 Werner LEMBERG + + * Makefile.cpg, Makefile.ccpg, Makefile.man: Add dummy file to + the left side of $(MANPAGES) rule to make it always non-empty. + +2001-12-14 Werner LEMBERG + + * src/roff/troff/input.cc (default_black): Define default color + `black' if not yet defined. + +2001-12-13 Werner LEMBERG + + Implement new string-valued register `.fn' to return the current + real (internal) font name. + + * env.cc (environment::get_font_name_string): New function. + (init_env_requests): Add `.fn' register. + * env.h (environment): Updated. + * node.cc (font_info): Make `get_font_name' a friend. + (get_font_name): New function. + * node.h: Updated. + + * man/groff_diff.man, man/groff.man, NEWS: Updated. + +2001-12-12 Ralph Corderoy + + * src/preproc/eqn/main.cc (inline_equation): Fix typos. + +2001-12-12 Werner LEMBERG + + * tmac/groff_man.man, doc/groff.texinfo: There is no .R macro. + +2001-12-10 Gaius Mulley + + * man/groff_diff.man: Adding documentation for \O. + +2001-12-10 Werner LEMBERG + + * src/preproc/html/pre-html.cc (TROFF_COMMAND): Removed. + (scanArguments): Use PROG_PREFIX for the name of the troff binary. + +2001-12-09 Werner LEMBERG + + * man/roff.man: Revised. + * src/roff/groff/groff.man: Replace man page references with a + pointer to roff.man. + +2001-12-09 Bernd Warken + + * man/roff.man: Completely rewritten. + +2001-12-06 Ralph Corderoy + + * src/preproc/eqn/main.cc (inline_equation): Improve error message. + +2001-12-05 Werner LEMBERG + + * src/roff/troff/input.cc (get_delim_file_name): Removed since no + longer used. + * src/devices/grohtml/post-html.cc (html_printer::html_printer): Fix + order of initializers. + * NEWS: Updated. + +2001-12-05 Gaius Mulley + + * doc/groff.texinfo: Fix documentation of \O. + + * src/devices/grohtml/html-text.cc (html_text::do_indent, + html_text::do_table, html_text::do_emittext, html_text::do_para): + Use `const' for first argument. + (html_text::do_table): Use cast. + * src/devices/grohtml/html-text.h: Updated. + * src/devices/grohtml/output.cc (simple_output::put_string): Add + method for `const string &s'. + * src/devices/grohtml/html.h: Updated. + * src/devices/grohtml/post-html.cc (MAX_STRING_LENGTH): Removed. + (ANCHOR_TEMPLATE): Modified. + (manufacture_headings): New global variable to handle `-h' option. + (is_subsection): Removed. + (char_buffer::add_string): Add `const' to first argument. + Protect against invalid string argument. + Add method for `const string &s'. + (text_glob): Completely redesigned. + (page): Use `const' for strings and remove string length variable. + (page::add_html): Removed. + (page::add_end_encode): New member function. + (to_unicode): Moved upwards. + (title_desc, header_desc): Updated. + (header_desc::write_headings): Updated to new ANCHOR_TEMPLATE + definition. + (html_printer::is_bold, html_printer::make_bold): New member + functions. + (html_printer::end_of_line): Updated. + (generate_img_src, html_printer::do_auto_image, + html_printer::do_title, html_printer::write_header, + html_printer::determine_header_level, html_printer::do_heading, + html_printer::do_linelength, html_printer::do_pageoffset, + html_printer::do_indentation, html_printer::do_tempindent, + html_printer::do_indentedparagraph, html_printer::do_break, + html_printer::flush_sbuf, get_html_translation, + html_printer::begin_page, html_printer::special): Rewritten to get + rid of static string length limit. + (html_printer::troff_tag): Added `.no-auto-rule'. + (html_printer::flush_globs): Small fix. + (html_printer::determine_space): Don't compute `space_width'. + (html_printer::translate_to_html): Renamed to ... + (html_printer::emit_html): This (with updates). + (html_printer::write_header): Implement `-h' option. + (html_printer::draw): Remove commented-out code. Handle `F' + command. + (html_printer::add_char_to_sbuf): Removed. + (html_printer::add_to_sbuf): Rewritten. + (html_printer::sbuf_continuation): Fixed. + (html_printer::seen_backwards_escape, reverse, + html_printer::remove_last_char_from_sbuf): Removed. + (char_translate_to_html, str_translate_to_html): Removed. + (html_printer::overstrike): New function member. + (html_printer::set_char): Use it. + (html_printer::do_body): New function member. + (html_printer::~html_printer): Use it. + (main): Handle `-h' option. + (usage): Updated. + * src/devices/grohtml/grohtml.man: Document -h switch. + + * src/preproc/html/pre-html.cc: Include searchpath.h + Replace `POSTSCRIPTRES' macro with `postscriptRes' variable. + (get_resolution): New function. + (checkImageDir): Use `0777' permissions in mkdir() + (write_start_image): Rewritten to use `\O[5...]'. + (createImage, generateImages): Updated. + (main): Handle `F' and `h' options. + Use `get_resolution'. + + * src/roff/troff/input.cc (begin, end, image): Removed. + (do_suppress): Take parameter. + Handle modified syntax of `\O'. + (token::next): Updated. + (init_markup_requests): Removed. + (main): Updated. + + * src/roff/troff/div.h: Add declaration for begin_page(). + + * tmac/color-html.tmac: Removed. Contents moved to... + * tmac/html.tmac: Here. Set background color. + * tmac/color.tmac: Removed. Contents moved to... + * tmac/ps.tmac: Here. + * tmac/www.tmac: Remove the title command when generating images + for html. + (NO_AUTO_RULE): New macro. + (HTML_DO_IMAGE): Use revised `\O' escapes. + * tmac/Makefile.sub, tmac/groff_www.man, tmac/troffrc: Updated. + +2001-12-02 Werner LEMBERG + + * tmac/groff_mdoc.man: Fix typo. + +2001-12-01 Colin Watson + + * man/roff.man: Fix typo. + +2001-11-29 Werner LEMBERG + + * src/libs/libbib/map.c, src/utils/pfbtops/pfbtops.c: Include + stdlib.h. + + * src/roff/troff/input.cc (read_draw_node): Emit error message if + more than one argument to \D'f ...'. + + * tmac/Makefile.sub (NORMALFILES): Add lbp.tmac. + +2001-11-28 Werner LEMBERG + + * tmac/an-old.tmac, tmac/doc.tmac: Assure that the macro package is + loaded only once. + + * tmac/groff_man.man: Minor cosmetic fix. + +2001-11-27 Werner LEMBERG + + * src/roff/groff/groff.man, tmac/groff_tmac.man, + tmac/groff_www.man: s/mwww/www/. + +2001-11-26 Werner LEMBERG + + * aclocal.m4 (GROFF_MKSTEMP): Implement test using C++ linkage. + * configure: Regenerated. + * win32-diffs: Updated. + + * tmac/groff_mwww.tmac: Renamed to ... + * tmac/groff_www.tmac: This. + * tmac/mwww.tmac: Removed. + * NEWS, tmac/Makefile.sub: Updated. + +2001-11-21 Werner LEMBERG + + * doc/groff.texinfo: Improve documentation of the `\v' escape. + Fix explanation of `\D' and `rt'. + +2001-11-20 Werner LEMBERG + + * tmac/an-old.tmac (an-header): Set header length equal to page + width. + * doc/groff.texinfo: Improve documentation of `ne' request. Other + minor fixes. + * NEWS: Small fix. + +2001-11-19 Werner LEMBERG + + * NEWS, man/Makefile.sub: Updated. + +2001-11-19 Bernd Warken + + * man/ditroff.man: New file. + +2001-11-17 Werner LEMBERG + + * man/groff_differences.man: Renamed to ... + * man/groff_diff.man: This. Updated. + * man/Makefile.sub, src/roff/troff/troff.man, NEWS: Updated. + + * src/preproc/html/pushbackbuffer.cc: Renamed to ... + * src/preproc/html/pushback.cc: This. Updated. + * src/preproc/html/pushbackbuffer.h: Renamed to ... + * src/preproc/html/pushback.h: This. + * src/preproc/html/Makefile.sub, src/preproc/html/pre-html.cc: + Updated. + + * src/libs/libgroff/htmlindicate.cc: Renamed to ... + * src/libs/libgroff/htmlhint.cc: This. + * src/libs/libgroff/Makefile.sub: Updated. + + * tmac/an-old.tmac (an-end): Fix page length. + +2001-11-16 Werner LEMBERG + + * NEWS, man/groff_differences.man, doc/groff.texinfo: Updated. + * man/Makefile.sub: Include groff_differences.man. + * VERSION: Set to 1.18. + * REVISION: Set to 0. + +2001-11-16 Bernd Warken + + * src/roff/troff/input.cc (do_define_macro): Allow whitespace before + the second dot (or ending macro name) to end a macro. + * doc/groff.texinfo: Doc fix. + +2001-11-16 Ruslan Ermilov + + * tmac/doc-common (doc-header): Handle very long document titles + better. + +2001-11-16 Werner LEMBERG + + * tmac/doc.tmac (doc-do-Bl-args): Fix .substring requests. + +2001-11-15 Werner LEMBERG + + * src/roff/troff/troff.man: Revised and split into troff.man and... + * man/groff_differences.man: New file. + * NEWS: Updated. + +2001-11-13 Werner LEMBERG + + * tmac/an-old.tmac (TS, TE): New macros for table support. + +2001-11-12 Werner LEMBERG + + * src/include/lib.h: Provide a fix for emx to not include + groff-getopt.h. + +2001-10-27 Werner LEMBERG + + * src/roff/troff/input.cc (substring_macro): Fix computation of + boundary values. + +2001-10-20 Werner LEMBERG + + Undo change from 2001-08-28. + + * src/roff/troff/input.cc (have_input): New global variable. + (token::next): Set `have_input' for \f, \H, \R, \s, and \S if not + in compatibility mode. + (process_input_stack): Use it. + +2001-10-19 Ruslan Ermilov + + * tmac/doc.tmac (doc-flag-recursion): Protect arguments against + being handled as end-of-sentence characters, + +2001-10-10 Gaius Mulley + + * src/roff/troff/input.cc (file_iterator): New members + `suppress_newline_flag' and `seen_escape'. + (file_iterator::next_file): Updated. + (file_iterator::fill): Use it. + (string_iterator): New member `suppress_newline_flag'. + (string_iterator::fill): Set it. + (get_color_element): Use MAX_COLOR_VAL. + * src/roff/troff/env.cc (environment): Remove `need_eol'. + (no_fill): Don't set `env->ignore_next_eol'. + (environment::newline): Handle `eol' tag properly. + Emit `eol.ce'. + (environment::add_html_tag): Set `env->ignore_next_eol'. + Don't handle `.ce'. + * src/roff/troff/env.h (environment): Updated. + + * src/devices/grohtml/post-html.cc (text_glob::is_eol_ce): New + member function. + (html_printer::outstanding_eol): New member function. + (html_printer::do_title): Use new functions. + (html_printer::troff_tag): Test `id_eol_ce'. + +2001-10-10 Werner LEMBERG + + * tmac/color.tmac, tmac/color-html.tmac: Use `.do' to make those + files work with -C also. + +2001-10-05 Werner LEMBERG + + * doc/pic.ms: Minor fix. + * src/preproc/html/pre-html.cc (scanArguments): Don't handle `-?' + as a valid command line switch. + * src/devices/grohtml/post-html.cc (main): Ditto. + (usage): Updated. + * src/devices/grohtml/grohtml.man: Updated. + * src/roff/groff/groff.cc (main): Pass `-v' to predriver also. + +2001-10-04 Werner LEMBERG + + Implementing color support in troff, pic, grops, and grohtml. These + changes are based on a major patch provided by Gaius Mulley + . + + New request: `defcolor', supporting rgb, cmy, cmyk, and gray + definitions with both hex values and fractions. + + New escapes: \m and \M for drawing and background color, + respectively. This corresponds to the troff output commands `m' + and `DF'. + + groff and troff accept command line switch `-c' to disable color + output (which is automatically disabled in compatibility mode). + + New scaling indicator `f' for fractions (1f = 65536u). + + New conditional operator `m' to test for defined colors with `if' + and `ie'. + + New keywords `color' (or `colour', `colored', `coloured'), `outline' + (or `outlined'), and `shaded' added to pic. + + * src/include/color.h: New file. + * src/include/driver.h: Include it. + * src/include/printer.h: Include color.h. + (environment): New members `col' and `fill'. + (printer): Remove `adjust_arc_center' member function. + * src/include/Makefile.sub: Updated. + + * src/libs/libdriver/input.cc (do_file): Initialize `env.col' and + `env.fill'. + Handle `m' and `DF' troff commands. + * src/libs/libgroff/color.cc: New file. + * src/libs/libgroff/Makefile.sub: Updated. + + * src/preproc/html/pre-html.cc (IMAGE_BORDER_PIXELS): Set to 2. + (stop): Removed. + (createImage): Fix computation of `y2'. + Use `pnmcrop' also. + (buffer::write_file_html): Remove calls to `stop'. + + * src/preproc/pic/common.h (common_output): New abstract function + members `set_color', `reset_color', `get_last_filled', and + `get_outline_color'. + * src/preproc/pic/object.h: Add `IS_SHADED' and `IS_OUTLINED'. + (object_spec): Add members `shaded' and `outlined'. + * src/preproc/pic/output.h (output): `command' is now abstract. + New function members `set_color', `reset_color', `get_last_filled', + and `get_outline_color'. + * src/preproc/pic/lex.cc (lookup_keyword): Recognize `colo[u]r[ed]', + `outline[d]', and `shaded'. + * src/preproc/pic/object.cc (output::command): Removed. + (output::set_location): Moved to output.h. + (graphic_object): Add protected members `outline_color' and + `color_fill'. + Add member functions `set_outline_color', `get_outline_color', and + `set_fill_color'. + (closed_object): Add member function `set_fill_color'. + Add member `color_fill'. + (graphic_object::print_text): Use `out->set_color' and + `out->reset_color'. + (box_object::print, ellipse_object::print, circle_object::print, + line_object::print, spline_object::print, arc_object::print): Ditto. + (object_spec::make_object): Implement `IS_OUTLINED' and `IS_SHADED'. + * src/preproc/pic/pic.y: Add tokens `COLORED', `OUTLINED', and + `SHADED', making them `%left'. + Add rules `object_spec [SHADED|COLORED|OUTLINED] text'. + * src/preproc/pic/tex.cc (tex_output): New dummy function members + `set_color', `reset_color', `get_last_filled', and + `get_outline_color'. + * src/preproc/pic/troff.cc (simple_output): New abstract function + members `set_color', `reset_color', and `get_last_filled'. + (simple_output::polygon, simple_output::circle, + simple_output::ellipse): Use `get_last_filled'. + (troff_output): New members `last_filled' and `last_outlined'. + New function members `set_color', `reset_color', `get_last_filled', + and `get_outline_color'. + (troff_output::finish_picture): Use `reset_color'. + (troff_output::set_fill): Test `last_filled'. + * src/preproc/pic/pic.man: Updated. + + * src/roff/groff/groff.cc (main): Implement `-c' option. + (synopsis, help): Updated. + src/roff/groff/groff.man: Updated. + + * src/roff/troff/troff.h: Include color.h. + (warning_type): Add WARN_COLOR. + * src/roff/troff/env.h (environment): New members + `{cur,prev}_{glyph,fill}_color'. + New member functions `get_{prev_,}{glyph,fill}_color'. + * src/roff/troff/env.cc: Initialize and implement them. + * src/roff/troff/input.cc: New global variable `disable_color_flag'. + Replace `NULL' with `0' everywhere for consistency. + (lookup_color, default_black, do_glyph_color, do_fill_color, + get_color_element, read_rgb, read_cmy, read_cmyk, read_gray, + define_color): New functions. + (token::next): Implement \M and \m escapes. + (do_if_request): Implement `m' operator. + (usage): Updated. + (main): Implement `-c' option. + (init_markup_requests): Add `defcolor' request. + (warning_table): Add `color' warning. + * src/roff/troff/node.h (glyph_color_node, fill_color_node): New + classes. + * src/roff/troff/node.cc (troff_output_file): New members + `current_{page,glyph}color'. New member functions `put_hex', + `glyph_color', and `fill_color'. + (glyph_color_node::*, fill_color_node::*): Implement it. + * src/roff/troff/number.cc (SCALE_INDICATOR_CHARS): Add `f'. + (parse_term): Add support for `f'. + * src/roff/troff/troff.man: Updated. + + * src/devices/grodvi/dvi.cc (draw_dvi_printer::draw): Add dummy + entry for `F'. + * src/devices/grolbp/lbp.cc (lbp_printer::draw): Ditto. + * src/devices/grolj4/lj4.cc (lj4_printer::draw): Ditto. + + * src/devices/grohtml/html-text.h (HTML_TAG): Add COLOR_TAG. + (tag_definition): Use `void *' for arg1. + (html_text): New member functions `do_color' and `done_color'. + Use `void *' for second parameter of `push_para' member function. + New `push_para' member function with a single parameter. + Use `char *' for parameter of `issue_table_begin' member function. + New `issue_color_begin' member function. + * src/devices/grohtml/html-text.cc (html_text::end_tag): Handle + COLOR_TAG. + (html_text::issue_color_begin): New function. + (html_text::issue_table_begin): Use `char *' for parameter. + (html_text::start_tag, html_text::shutdown, + html_text::check_emit_text): Updated. + (html_text::push_para): Use `void *' for second parameter. + Add same function with only one parameter. + (html_text::do_*): Updated. + (html_text::do_color, html_text::done_color): New functions. + * src/devices/grohtml/post-html.cc (style): New member `col'. + Mew member `style' with 6 parameters. + (style::style, style::operator==): Updated. + (html_printer::do_font): Use it. + (html_printer::draw): Add dummy entry for `F'. + (html_printer::set_char): Updated. + * src/devices/grohtml/grohtml.man: Updated. + + * src/devices/grops/ps.cc (ps_output::put_float): Use `%g' to have + trailing zeroes removed. + (ps_printer): New members `sbuf_color', `fill_color', and + `output_color'. + Removed member `fill'. + New member function `set_color'. + (ps_printer::ps_printer, ps_printer::set_char): Updated. + (ps_printer::flush_sbuf, ps_printer::set_line_thickness, + ps_printer::fill_path, ps_printer::draw): Use `set_color'. + + * tmac/color-html.tmac, tmac/color.tmac: New files. + * tmac/troffrc: Include them. + * tmac/www.tmac (URL, FTP, MAILTO): Use blue color. + * tmac/Makefile.sub: Updated. + + * NEWS, doc/groff.texinfo, doc/pic.ms, man/groff_out.man, + man/groff.man: Updated. + * font/devps/prologue.ps: Define FC and CO functions. + +2001-10-04 Gaius Mulley + + Fix incorrect cropping of images and incorrect handling of special + characters. Fix handling of file names in \O. + + * src/include/geometry.h: New file. + * src/libs/libgroff/geometry.cc: New file. + * src/libs/libdriver/printer.cc (printer::adjust_arc_center): Moved + to `geometry.cc'. + * src/roff/troff/input.cc (get_delim_file_name): Fixed problem with + initial spaces. + (do_suppress): Updated. + * src/roff/troff/node.cc: Include geometry.h. + (troff_output_file::flush_tbuf): Fixed parameters to + `check_output_limits'. + (troff_output_file::check_charinfo): Ditto. + (troff_output_file::determine_line_limits): Add support for `Da' + and `Dl' commands. + + * src/devices/grohtml/post-html.cc (str_translate_to_html): + Add new parameter `is_special' to decode special characters from + escape sequences. + (html_printer::do_title, html_printer::do_heading, + html_printer::do_indentedparagraph, + html_printer::translate_to_html, html_printer::special): Updated. + +2001-10-03 Werner LEMBERG + + * Makefile.sub (DISTCLEANFILES): Add stamp-h. + Fix entry for config.h. + * test-groff (GROFF_BIN_PATH): Add $builddir/roff/groff. + * tmac/troffrc: Translate nonbreakable space character to `\~'. + * src/preproc/eqn/eqn.man: Document -d command line option. + +2001-09-27 Werner LEMBERG + + * man/groff.man: Use + + .ev xxx + .na + .nh + + .ev + + instead of the old code (`.ad .hy' after the table) to suppress + incorrect hyphenation for grohtml output. + +2001-09-22 Werner LEMBERG + + * man/groff_font.man, man/groff_out.man: Minor fixes. + +2001-09-20 Werner LEMBERG + + * PROBLEMS: Updated, reordered. Improved EPS section (thanks to + Arnold Robbins ). + +2001-09-09 Werner LEMBERG + + * configure: Regenerated with autoconf 2.52. + + * doc/groff.texinfo: Complete revision of indices. + +2001-09-07 Werner LEMBERG + + * doc/Makefile (clean): Updated to delete all indices. + +2001-09-05 Werner LEMBERG + + * src/roff/troff/troff.man: Remove superfluous line. + + * tmac/s.tmac: Enable all warnings only if no -W or -w option is + given on the command line (or rather, if only the default warnings + are set). + +2001-09-03 Werner LEMBERG + + * man/groff.man, src/preproc/eqn/eqn.man, tmac/groff_mdoc.man: Don't + use .ne for TTY devices. + +2001-08-31 Werner LEMBERG + + * src/roff/troff/token.h, src/roff/troff/input.cc: + s/TOKEN_TRANSPARENT_ESCAPE/TOKEN_OPAQUE_ESCAPE/. + +2001-08-28 Werner LEMBERG + + * src/roff/troff/token.h (token_type): Add TOKEN_TRANSPARENT_ESCAPE. + * src/roff/troff/input.cc (token::next): Return + TOKEN_TRANSPARENT_ESCAPE for \f, \H, \R, \s, and \S if not in + compatibility mode. + (token::description): Updated. + (process_input_stack): Reset `bol' for TOKEN_TRANSPARENT_ESCAPE. + (token::add_to_node_list, token::process): Ignore + TOKEN_TRANSPARENT_ESCAPE. + +2001-08-27 Werner LEMBERG + + * tmac/an-old.tmac: Fix `S' string. + +2001-08-26 Werner LEMBERG + + * src/roff/troff/troff.man: Don't use .ne for TTY devices. + +2001-08-25 Werner LEMBERG + + * doc/pic.ms: Replace `\\' with `\e' (and fixing some single + backslashes). + Many other minor fixes. + + * configure.ac: Add message at end to inform how to compile + xditview. + * configure: Regenerated. + +2001-08-24 Werner LEMBERG + + * src/include/getopt.h, src/libs/libgroff/{getopt.c, getopt1.c}: + Updated to latest version of libc. + +2001-08-23 Werner LEMBERG + + * configure.ac: Don't create subdirectories before AC_CONFIG_FILES. + Autoconf 2.50 and newer can handle this. + * configure: Regenerated. + +2001-08-21 Werner LEMBERG + + * doc/pic.ms: Fix typo. + * src/preproc/tbl/tbl.man: Document case of global options. + +2001-08-21 Gaius Mulley + + * src/devices/grohtml/post-html.cc (html_printer::end_font): Fix + handling of `CR' font. + +2001-08-20 Werner LEMBERG + + Use a config.h file. + + * src/include/lib.h: Include config.h. + * All C files: Ditto (if necessary). + * All C++ source and header files: Include lib.h first (if + necessary). + + * src/include/config.hin: New file (autogenerated by autoheader). + * stamp-h.in: New file. + * configure.ac: Updated. + * aclocal.m4: Add third parameters to AC_DEFINE macros. + (GROFF_ARRAY_DELETE): Simplified. + * Makefile.sub (DISTCLEANFILES): Updated. + Added targets for remaking config.status, config.hin, config.h, + stamp-h.in, and stamp-h. + * configure: Regenerated. + +2001-08-19 Werner LEMBERG + + * NEWS: Updated. + +2001-08-18 Sebastian Krahmer + + * src/preproc/pic/pic.y (format_number): Use do_sprintf(). + (do_sprintf): Use snprintf(). + +2001-08-18 Werner LEMBERG + + * src/libs/snprintf/*: Added an snprintf module written by Mark + Martinec. + * src/libs/libgroff/Makefile.sub: Updated. + * configure.ac: Add test for snprintf(). + * Makefile.in: Updated. + * configure: Regenerated. + + * src/preproc/html/pre-html.cc (make_message): Reactivate code which + uses snprintf(). + +2001-08-14 Ruslan Ermilov + + * tmac/doc.tmac (Ex): New implementation. + * tmac/doc-common, tmac/groff_tmac.man: Updated. + +2001-08-13 Ruslan Ermilov + + * tmac/doc.tmac (Rv): Implement support for 0 or more than 1 + argument. + * tmac/groff_tmac.man: Updated. + +2001-08-13 Werner LEMBERG + + * src/preproc/tbl/tbl.man: Minor documentation update. + +2001-08-13 John David Anglin + + * src/libs/libgroff/tmpname.cc: Add prototype for gettimeofday(). + * configure.ac: Add declaration test for gettimeofday(). + * Makefile.in: Document NEED_DECLARATION_GETTIMEOFDAY defines. + * aclocal.m4: Include sys/time.h for gettimeofday declaration test. + * configure: Regenerated. + +2001-08-11 Werner LEMBERG + + * aclocal.m4 (GROFF_MKSTEMP): Define HAVE_MKSTEMP. + * configure.ac: Add declaration test for strcasecmp(). + * Makefile.in: Updated. + * configure: Regenerated. + * src/include/lib.h [!HAVE_MKSTEMP]: Add prototype for mkstemp() -- + this is necessary because groff's mkstemp.cc is C++. + Add declaration conditionally for strcasecmp(). + +2001-08-10 Werner LEMBERG + + Integrated pic2graph, contributed by Eric S. Raymond. + + * contrib/pic2graph/{Makefile.sub, pic2graph.sh, pic2graph.man}: New + files. + * Makefile.in, NEWS: Updated. + + * src/preproc/tbl/tbl.man: Revised. + +2001-08-09 Eric S. Raymond + + * src/preproc/tbl/tbl.man: Extended to cover all tbl features. + +2001-08-09 Werner LEMBERG + + * src/preproc/tbl/main.cc (process_data): Fix recognition of .lf + requests. + +2001-08-08 Paul Eggert + + * Makefile.sub (configure): Depend on configure.ac, not + configure.in. + * INSTALL.gen: Upgrade to autoconf 2.52's INSTALL. + +2001-08-07 Werner LEMBERG + + * src/utils/afmtodit/afmtodit.man, src/roff/groff/groff.man: Minor + fixes. + +2001-08-06 Werner LEMBERG + + * src/roff/troff/troff.man: Improve documentation of -E option. + +2001-07-28 Ralph Corderoy + + * src/preproc/html/pushbackbuffer.cc (pushBackBuffer::readNumber): + Simplified. + +2001-07-27 Werner LEMBERG + + * src/preproc/refer/refer.cc: Undo last change. + * src/devices/grohtml/post-html.cc: Ditto. + +2001-07-26 Werner LEMBERG + + * src/preproc/refer/refer.cc: Include `lib.h'. + * src/devices/grohtml/post-html.cc: Ditto. + +2001-07-25 Gaius Mulley + + * aclocal.m4 (GROFF_PAGE): Add `AC_DEFINE(PAGEA4)'. + * src/preproc/html/pre-html.cc: Use it for DEFAULT_VERTICAL_OFFSET. + * Makefile.in: Comment updated. + * configure: Regenerated. + +2001-07-25 Werner LEMBERG + + * src/preproc/pic/pic.cc: Removed. + * src/preproc/pic/pic_tab.h: Removed. + * src/preproc/refer/label.cc: Removed. + + * doc/Makefile (.ms.html): Don't use a file name extension in + argument to grohtml's -I option. + * Makefile.in (dist): Remove CVS directories. + Call `distfiles' target. + + * src/devices/grohtml/grohtml.man: Add information about valid + versions of pnmtopng. + * src/preproc/html/pre-html.cc (TRANSPARENT): Use `white' as colour + name instead of number. + +2001-07-24 Werner LEMBERG + + * doc/groff.texinfo: Minor fixes. + +2001-07-21 Gaius Mulley + + * doc/Makefile (.ms.html): Put image files into a subdirectory. + (clean): Updated. + +2001-07-20 Werner LEMBERG + + * src/libs/libgroff/tmpname.cc: New file, defining get_tempname(). + * src/libs/libgroff/mkstemp.cc: New file. + * src/libs/libgroff/mksdir.cc: New file. + * src/libs/libgroff/tmpfile.cc [HAVE_MKSTEMP_PROTO]: Removed. + (xtmpfile) [!HAVE_MKSTEMP]: Removed. + * src/libs/libgroff/Makefile.sub: Updated. + * src/include/lib.h: Add mksdir() prototype. + * src/include/posix.h: Define S_IXUSR if not yet defined. + + * src/preproc/html/pre-html.cc (MAX_RETRIES): Removed. + (createAllPages): Use mksdir() instead of current code. + * src/utils/indxbib/indxbib.cc [HAVE_MKSTEMP_PROTO]: Removed. + (main): [!HAVE_MKSTEMP]: Removed. + + * aclocal.m4 (GROFF_MKSTEMP): Updated to use new mkstemp.cc file. + (GROFF_INTTYPES_H, GROFF_UNSIGNED_LONG_LONG, GROFF_UINTMAX_T): New + macros. + * configure.ac: Add tests for stdint.h, sys/time.h, and + gettimeofday(). + Call new GROFF_xxx macros. + * configure: Regenerated. + * Makefile.in: Comments updated. + +2001-07-20 Gaius Mulley + + * src/preproc/html/pre-html.cc (scanArguments): Use getopt_long() + instead of current code. + * src/devices/grohtml/post-html.cc (main): Handle `-d' option. + * src/roff/groff/groff.cc (possible_command::insert_args): New + function. + (main): Use it for predriver handling instead of insert_arg(). + +2001-07-19 Werner LEMBERG + + * doc/Makefile: Added GROFF_BIN_PATH to make it work with uninstalled + groff also. + + * src/include/posix.h: Define S_IWUSR if not yet defined. + +2001-07-18 Werner LEMBERG + + * NEWS: Updated. + +2001-07-18 Ruslan Ermilov + + * tmac/groff_mdoc.man: Document new -width and -column syntax. + Some other minor fixes. + * tmac/an-old.tmac: Add `AT' and `UC' macros. + +2001-07-17 Gaius Mulley + + Replace call to `troff' with `groff -Z' to make it aware of + GROFF_BIN_PATH. + + * src/preproc/html/pre-html.cc (TROFF_COMMAND): New macro. + (troff_command, command_prefix): Removed. + (alterDeviceTo): Use groff. + (addZ): New function. + (char_buffer::do_html): Use it. + (scanArguments): Use TROFF_COMMAND. + (findPrefix): Removed. + (main): Updated. + * src/roff/groff/groff.cc (main): Handle zflag for preprocessors. + +2001-07-17 Eric S. Raymond + + * doc/pic.ms: Documentation fixes. + +2001-07-17 Werner LEMBERG + + Replace atexit() with global destructor. + + * src/libs/libgroff/tmpfile.cc (xtmpfile_list): Add constructor. + (xtmpfile_list_init): New global structure to deallocate + xtmpfile_list on exit. Its destructor inherits most code from + remove_tmp_files(). + (remove_tmp_files): Deleted. + (add_tmp_file): Simplified. + +2001-07-16 Werner LEMBERG + + Replace strdup() with strsave(). + + * src/devices/grolbp/lbp.cc [!HAVE_STRDUP]: Removed. + (set_papersize): Use strsave() and a_delete. + (main): Use strsave(). + * src/preproc/html/pre-html.cc (make_message, createAllPages, + removeAllPages): Use strsave() and a_delete. + + * configure.ac: Remove test for strdup. + * Makefile.in: Comment updated. + * configure: Regenerated. + +2001-07-15 Werner LEMBERG + + * win32-diffs: Updated. + +2001-07-14 Werner LEMBERG + + * src/preproc/html/pre-html.cc (makeTempFiles): Activate new code, + removing the old one. + * src/utils/indxbib/indxbib.cc (main): Remove compiler warning. + +2001-07-14 Ralph Corderoy + + * src/libs/libgroff/tmpfile.cc (xtmpfile): Fix guard for `namep'. + +2001-07-12 Ruslan Ermilov + + Merge -xwidth into -width. Add -xwidth functionality to -column + also. + + * tmac/doc.tmac (Bl): Add dummy doc-typeXXX and doc-spaceXXX to + avoid warning. + (doc-do-Bl-args): Merge -xwidth code with -width. Test whether + string immediately following a leading dot starts with a valid mdoc + argument. + Add similar code to the -column branch. + (doc-Bl-usage): Updated. + * groff_mdoc.man: s/-xwidth/-width/. + +2001-07-12 Gaius Mulley + + * src/devices/grohtml/post-html.cc (text_glob::is_br): Stop titles + running into centered or non-formatted text. + +2001-07-11 Werner LEMBERG + + Introduce short and long prefixes to have the selection at run-time + whether there is a 8+3 limit for names of temporary files. + + * src/libs/libgroff/tmpfile.cc (TMPFILE_PREFIX): Replaced with... + (TMPFILE_PREFIX_SHORT, TMPFILE_PREFIX_LONG): This. + (tmpfile_prefix, tmpfile_prefix_len, use_short_prefix): New + variables. + (temp_init): New global structure to initialize above three + variables. + (xtmptemplate): Use two parameters for long and short prefix. + Simplify code use above three variables. + (xtmpfile): Use long and short prefixes as parameters. + * src/include/lib.h: Updated. + + * src/preproc/html/pre-html.cc ({PAGE,PS,REGION}_TEMPLATE): Replace + with ... + ({PAGE,PS,REGION}_TEMPLATE_{SHORT,LONG}): This. + (createAllPages, makeTempFiles): Updated. + +2001-07-09 Werner LEMBERG + + * REVISION: Increased to 3. + +Copyright 2001-2002 Free Software Foundation, Inc. + +Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. + +Local Variables: +coding: latin-1 +fill-column: 72 +mode: change-log +version-control: never +End: +vim:set autoindent textwidth=72: diff --git a/ChangeLog.119 b/ChangeLog.119 new file mode 100644 index 0000000..2840368 --- /dev/null +++ b/ChangeLog.119 @@ -0,0 +1,5240 @@ + +Version 1.19.2 released +======================= + + * tmac/groff_ms.man, doc/groff.texinfo: Synchronize. + + * doc/webpage.ms: Updated. + + * install-sh, mkinstalldirs: New versions; taken from texinfo CVS. + +2005-09-04 Jörgen Grahn + + * tmac/groff_ms.man: Document `PO' better. + +2005-09-03 Werner LEMBERG + + * NEWS: Document grotty changes. + +2005-09-01 Keith Marshall + + Backward compatibility support for `man' program. + + * tmac/an-old.tmac (LL): Initialize it to respect prior LL register + assignment, prior `.ll' request and then package defaults, in this + specified order of decreasing priority. + + * tmac/groff_man.man, doc/groff.texinfo (Man options): Document + altered `LL' register initialization priorities. + +2005-08-29 Gary W. Swearingen + + * tmac/groff_mdoc.man: Go into more details how the `AUTHORS' + section should look like. + +2005-08-29 Werner LEMBERG + + * tmac/groff_mdoc.man: The month's name in a call to .Dd shouldn't + be abbreviated. + +2005-08-27 Bernd Warken + + * tmac/groff_man.man: Add man(7) too SEE ALSO and more minor + fixes. + +2005-08-11 Bernd Warken + + * tmac/www.tmac (URL, MTO): Handle empty \\$1 better. + +2005-08-09 Bernd Warken + + * tmac/www.tmac (URL, MTO): Use bold series if color support is + deactivated. + +2005-08-02 Bernd Warken + + * doc/Makefile.sub (uninstall_sub): Use --remove, not --delete + as argument to $(INSTALL_INFO). The latter isn't portable. + Remove $(HTMLEXAMPLEFILES) too. + + * Makefile.in (uninstall_dirs): Remove $(datadir)/doc/groff and + $(datadir)/doc too. + Suppress warning messages and return always true. + + * tmac/Makefile.sub (uninstall_sub): Remove www.tmac too. + +2005-07-02 Bernd Warken + + * src/devices/xditview/gxditview.man: Change many `.I' to `.B'. + * man/groff_out.man: More markup and minor improvements. + * src/roff/groff/groff.man: Minor improvements. + +2005-06-28 Werner LEMBERG + + * ChangeLog: Split off older entries into... + * ChangeLog.115 ChangeLog.116, ChangeLog.117, ChangeLog.118: New + files. + +2005-06-26 Bernd Warken + + * src/devices/xditview/gxditview.man: More minor fixes. + +2005-06-24 Werner LEMBERG + + * src/preproc/pic/troff.cpp (troff_output::set_fill, + troff_output::set_color, troff_output::reset_color): Use .bcolor and + .fcolor instead of \m and \M, respectively. + +2005-06-23 Bernd Warken + + * src/devices/xditview/gxditview.man: More minor fixes. + * README: Formatting issues. + Mention some problems with Debian. + +2005-06-23 Bernd Warken + + * src/devices/xditview/gxditview.man: Revised and improved. + +2005-06-22 Werner LEMBERG + + Another round in fixing getopt problems. Hopefully the last one! + This time we use the getopt stuff from gnulib and define a prefix + unconditionally so that there are no collisions with any other + getopt implementations. This is a slight waste of space in case + we already use a GNU getopt implementation, but on + the other hand it really simplifies life. + + * src/include/getopt.h: Use gnulib version. + + * src/include/getopt_int.h: Use gnulib version. + + * src/include/groff-getopt.h: Removed. Obsolete now. + + * src/include/lib.h: Regarding getopt, don't handle any platform + specially; just include getopt.h. + (__GETOPT_PREFIX): Define (before getopt.h). + + * src/include/Makefile.sub (HDRS): Updated. + + * src/libs/libgroff/getopt1.c, src/libs/libgroff/getopt.c: Use + gnulib version. + + * src/libs/libgroff/Makefile.sub (EXTRA_CFLAGS): Set + __GETOPT_PREFIX. + + * src/utils/pfbtops/pfbtops.c, src/utils/xtotroff/xtotroff.c + (__GETOPT_PREFIX): Define (before getopt.h). + +2005-06-21 Werner LEMBERG + + * src/include/lib.h: Provide a fix for Mac OS X to not include + groff-getopt.h. + +2005-06-20 Denis M. Wilson + + * font/devps/prologue.ps (EP): Don't use `bind'. Reason: Using + `bind' to define a procedure which contains `showpage' means that an + invocation of `showpage' may execute wrongly (the exact effect + depending on the interpreter). Not usually a problem except under + transformations, such as combining pages. + (PEND): Don't call `clear'. Reason: Using `clear' in the definition + of /PEND means that stack underflow will occur if the stack is + deliberately non-empty before document inclusion. If included + files are found to be generally badly behaved, we could replace the + `clear' with `mark' in /PBEGIN and `cleartomark' in /PEND (I've + never found this necessary). + +2005-06-20 Jörgen Grahn + + * src/preproc/soelim/soelim.cpp (do_file): Append trailing zero + earlier to get correct error message. + +2005-06-16 Bernd Warken + * src/roff/nroff/nroff.sh: Add support for iso-8859-15. + +2005-06-15 Werner LEMBERG + + Another try to update getopt files. This time we add a dummy + gettext.h file to satisfy the dependency. + + * src/include/getopt.h, src/libs/libgroff/getopt.c, + src/libs/libgroff/getopt1.c: Updated from GNU libc CVS. + + * src/include/getopt_int.h: New file (from GNU libc CVS). + + * src/include/gettext.h: Dummy file which just defines a gettext() + macro. + + * src/include/groff-getopt.h: Updated. + + * src/include/Makefile.sub (HDRS): Add getopt_int.h and gettext.h. + + + * src/libs/libdriver/input.cpp (IntArray): Remove superfluous + `const' keywords in return value. + + * src/preproc/html/pushback.cpp (pushBackBuffer::~pushBackBuffer): + Remove redundant variable `old'. + (pushBackBuffer::skipToNewline): Remove redundant variable `ch'. + + * src/preproc/tbl/main.cpp (process_table): Remove redundant + variable `c'. + + + Fix more friend name injection problems since modern C++ compilers + fail otherwise. We simply provide (global) declarations for all + functions declared as friends. This is not really necessary but + doesn't harm. + + * src/preproc/eqn/lex.cpp: Provide declarations for get_char, + peek_char, and get_location. + + * src/preproc/refer/ref.h: Provide declarations for + compare_reference, same_reference, same_year, same_date, + same_author_last_name, and same_author_name. + + * src/roff/troff/div.h: Provide declarations for do_divert and + page_offset. + + * src/roff/troff/env.h: Provide declarations for title_length, + space_size, fill, no_fill, adjust, no_adjust, center, right_justify, + vertical_spacing, post_vertical_spacing, line_spacing, line_length, + indent, temporary_indent, do_underline, do_input_trap, set_tabs, + margin_character, no_number, number_lines, leader_character, + tab_character, hyphenate_request, no_hyphenate, + hyphen_line_max_request, hyphenation_space_request, + hyphenation_margin_request, line_width, tabs_save, tabs_restore, + line_tabs_request, widow_control_request, and do_divert. + + * src/roff/troff/input.cpp: Provide declaration for chop_macro. + + * src/roff/troff/node.cpp: Provide declarations for class + tfont_spec. + Provide declaration for make_tfont. + +2005-05-29 Werner LEMBERG + + * doc/fdl.texi: Updated to version 1.2. Reported by + Bernd Warken . + +2005-05-28 Werner LEMBERG + + * src/devices/grolbp/lbp.cpp, src/devices/grolbp/lbp.h: Remove + redundant semicolons. + + * src/preproc/eqn/Makefile.sub, src/preproc/html/Makefile.sub, + src/preproc/soelim/Makefile.sub, src/preproc/tbl/Makefile.sub: + Define `MLIB'. Some compilers need this for linking with libgroff. + +2005-05-27 Werner LEMBERG + + * MANIFEST, README, doc/webpage.ms: Updated. + +2005-05-26 Werner LEMBERG + + * All affected files: Update postal address of FSF. + +2005-05-25 Keith Marshall + Bernd Warken + + * README: More fixes. + + * README.CVS: Removed. Its contents is now part of the README file. + +2005-05-21 Werner LEMBERG + + * README: Updated. Based on a patch from + Bernd Warken . + +2005-05-16 Keith Marshall + + Miscellaneous script portability enhancements. + + * aclocal.m4: (GROFF_CSH_HACK): Add space in shebang prototype for + generated conftest.sh script, conforming to portability + recommendation in autoconf docs. + * configure: Likewise, for code generated by GROFF_CSH_HACK. + * contrib/eqn2graph/eqn2graph.sh: Add space in shebang, conforming + to portability recommendation in autoconf docs. + * contrib/grap2graph/grap2graph.sh: Likewise. + * contrib/pic2graph/pic2graph.sh: Likewise. + * font/devps/generate/afmname: Likewise. + * src/devices/xditview/ad2c: Likewise. + * src/preproc/eqn/neqn.sh: Likewise. + * src/roff/grog/grog.pl: Likewise. + * src/roff/grog/grog.sh: Likewise. + * src/roff/nroff/nroff.sh: Likewise. + * PROBLEMS: Likewise, in embedded script examples. + +2005-05-16 Keith Marshall + + Improve portability of `pdfroff' shell script. + + * arch/misc/shdeps.sh: Add space in shebang, conforming to + portability guidelines in `autoconf' docs. + (PATH_SEARCH_SETUP): New substitution; emits PATH_SEPARATOR + initialization code. Used by contrib/pdfmark/pdfroff.sh's + `searchpath' function. + +2005-05-14 Werner LEMBERG + + * contrib/pic2graph/pic2graph.sh, contrib/graph2graph.sh, + contrib/eqn2graph.sh: Add option `-trim' to `convert' which is + needed for newer ImageMagick versions. + +2005-05-07 Werner LEMBERG + + * src/preproc/refer/refer.man: Many small typographic fixes. + +2005-05-06 Jeff Conrad + + * src/devices/grohtml/post-html.cpp (assert_state::~assert_state): + Use `char *' cast for a_delete. + +2005-05-03 Werner LEMBERG + + * src/libs/libgroff/maxpathname.cpp: Include stdlib.h. + src/libs/libgroff/relocate.cpp: Use path_name_max everywhere. + +2005-05-03 Jeff Conrad + + * src/devices/grohtml/post-html.cpp: Use casts to `char *' if using + `a_delete' for `const char *'. + +2005-05-03 Werner LEMBERG + + * src/devices/grohtml/post-html.cpp, + src/devices/grohtml/html-table.cpp, + src/devices/grohtml/html-text.cpp, src/devices/grohtml/output.cpp: + Replace malloc/free with new/delete/a_delete. + + * src/devices/grolbp/lbp.h: Remove superfluous semicolons which + are prohibited with ANSI C++. + (lbpprintf, vdmprintf): Remove useless `inline' keyword (since the + function has a variable number of arguments). + + * src/preproc/grn/main.cpp (doinput): Change return type to `int'. + Simplify function and update all callers. + +2005-05-02 Werner LEMBERG + + Undo getopt changes from 2005-04-30. We don't want a dependency + on gettext. + + * src/include/getopt_int.h: Removed. + + * src/include/getopt.h, src/include/groff-getopt.h, + src/include/Makefile.sub, src/libs/libgroff/getopt.c, + src/libs/libgroff/getopt1.c: Revert to previous version. + + + * src/include/nonposix.h (access) [_MSC_VER]: New macro. + + * src/include/posix.h (F_OK): Define conditionally. + + * src/devices/grotty/tty.cpp (tty_printer::make_underline): Use + different variable name in second `for' loop to avoid MSVC compiler + problem. + +2005-04-30 Werner LEMBERG + + AC_TYPE_SIGNAL from current autoconf can fail if CC=g++. + + * aclocal.m4 (GROFF_TYPE_SIGNAL): New function. + * configure.ac: Use GROFF_TYPE_SIGNAL, not AC_TYPE_SIGNAL. + * configure, src/include/config.hin: Regenerated. + + * PROBLEMS: Updated. + + + Update getopt files. + + * src/include/getopt.h, src/libs/libgroff/getopt.c, + src/libs/libgroff/getopt1.c: Updated from GNU libc CVS. + + * src/include/getopt_int.h: New file (from GNU libc CVS). + + * src/include/groff-getopt.h: Updated. + + * src/include/Makefile.sub (HDRS): Add getopt_int.h. + + + * font/devutf8/NOTES: Updated. + +2005-04-28 Werner LEMBERG + + Bug fix for Win32 relocatable code. Based on a patch from Keith + Marshall. + + * src/libs/libgroff/maxpathname.cpp (PATH_MAX): Test for `_MAX_PATH' + also. + + * src/libs/libgroff/relocate.c (DEBUG): Define it conditionally. + (searchpath) [_WIN32]: Use `_fullpath', not `realpath'. + +2005-04-28 Keith Marshall + + Correct `gnu.eps' handling for build from distribution tarball, with + separate source and build directories. + + * doc/Makefile.sub: (examples.stamp): New target; forces copy of + grnexmpl.g, groff.css and gnu.eps from source to build directory; + generate gnu.eps from gnu.xpm if required; touch examples.stamp. + (prepare_examples): Make it depend on examples.stamp. + (CLEANADD): Add examples.stamp. + +2005-04-27 Werner LEMBERG + + Implement the rule + + position: `(' position `)' + + in pic. + + * src/preproc/pic/pic.y (position, position_not_place): Handle + additional parentheses. + + * doc/pic.ms: Updated. + +2005-04-23 Larry Jones + + * src/utils/xtotroff/xtotroff.c (MapFont): Fix variable declaration. + +2005-04-18 Werner LEMBERG + + * src/roff/groff/pipeline.c: Don't include ctype.h. + +2005-04-13 Werner LEMBERG + + * src/roff/nroff/nroff.man: Document option `-M'. + +2005-04-13 Bruce Lilly + + * src/roff/nroff/nroff.sh: Make the script accept option `-M'. + +2005-04-01 Kees Zeelenberg + Werner LEMBERG + + Add binary relocation support for Windows platforms. + + * src/include/Makefile.sub (defs.h): Add `INSTALLPATH'. + + * src/include/relocate.h, src/libs/libgroff/relocate.cpp: New files. + + * src/libs/libgroff/searchpath.cpp: Handle `relocate'. + (search_path::search_path, search_path::open_file_cautious): Use + `relocate'. + + * src/libs/libgroff/Makefile.sub (OBJS, CCSRCS), + src/include/Makefile.sub (HDRS): Updated. + +2005-04-01 Werner LEMBERG + + * src/devices/grohtml/post-html.cpp: Don't use strdup/free but + strsave/a_delete. + + * src/libs/libgroff/font.cpp: Replace strdup with strsave. + + * src/libs/libgroff/maxfilename.cpp: Don't include limits.h since + lib.h already does it. + + * src/libs/libgroff/maxpathname.cpp: New file, defining + path_name_max. + + * src/include/lib.h: Add prototype for path_name_max. + + * src/libs/libgroff/Makefile.sub (OBJS, CCSRCS): Updated. + + * src/include/nonposix.h (PATH_EXT): New macro. + +2005-03-28 Werner LEMBERG + + Add support for double- and zero-width characters in grotty. + + * src/devices/grotty/tty.cpp (glyph): Add width. + (tty_printer::make_underline, tty_printer::make_bold, + tty_printer::add_character): Add parameter to pass character width. + Update all callers. + (tty_printer::end_page): Increase hpos by actual character width. + + * font/devutf8/R.proto: Specify zero width for non-spacing + characters. + + * tmac/unicode.tmac: Remove definitions for non-spacing entities. + + * Makefile.comm (extraclean): Remove more junk files. + +2005-03-25 Werner LEMBERG + + * configure.ac: Undo change from 2005-03-24. + * configure: Regenerated. + +2005-03-24 Werner LEMBERG + + * Makefile.in (NOMAKEDIRS): Add contrib/gdiffmk/tests. + (dist): Search Makefile while descending into $(EXTRADIRS). + + * doc/Makefile.in (.PHONY): Add. + (clean): Don't remove *.png and *.eps. + Don't handle *.gif. + (realclean): Remove *.png and *.eps. + (extraclean): Depend on distclean. + + * configure.ac: Add copyright. + Handle contrib/pdfmark/Makefile. + + * configure: Regenerated. + +2005-03-18 Larry Kollar + + Add numbered and definition lists to www.tmac. + + * tmac/www.tmac (www-ul-level1, www-ul-level2, www-ul-level3, + www-ol-level1, www-ol-level2, www-ol-level3, www-ol-tmp): New + auxiliary string registers. + (www-ul-level, www-ol-level, www-dl-level, www-ol-ctr1, www-ol-ctr2, + www-ol-ctr3, www-dl-shift): New auxiliary number registers. + (www-level): Removed. + (www-level1, www-level2, www-level3): Initialize to empty. + (www-level0, www-level4, www-level5, www-level6, www-level7, + www-level8, www-level9): New string registers. + (www-push-li, www-pop-li): New macros. + (www-push-level, www-pop-level): Renamed to... + (www-push-ul-level, www-pop-ul-level): This. + Updated. + (www-push-ol-level, www-pop-ol-level): New macros. + (ULS, ULE): Updated. + (OLS, OLE, DLS, DLE): New user macros. + (LI): Removed. It is aliased to one of... + (www-li-ul, www-li-ol, www-li-dl): New macros. + + * tmac/groff_www.man: Document new macros. + + * NEWS: Updated. + +2005-03-18 Werner LEMBERG + + * tmac/doc-common (doc-operating-system-NetBSD-2.0.1, + doc-operating-system-NetBSD-2.0.2): New strings. + + * tmac/groff_mdoc.man: Updated. + +2005-03-17 Werner LEMBERG + + * doc/Makefile.sub (CLEANADD): Add `groff.html'. + +2005-03-17 Werner LEMBERG + + * src/libs/libgroff/hypot.c: Renamed to... + * src/libs/libgroff/hypot.cpp: This. Updated to C++. + + * src/libs/libgroff/Makefile.sub (CCSRCS, CSRCS): Updated. + + * src/include/lib.h: Updated. + +2005-03-16 Werner LEMBERG + + Add workaround for broken hypot() on Interix. + + * src/libs/libgroff/hypot.c: New wrapper file for `hypot'. + + * src/libs/libgroff/Makefile.sub (OBJS): Add `hypot.o'. + (CSRCS): Add `hypot.c'. + + * src/include/lib.h: Declare `groff_hypot'. + + * src/preproc/grn/hgraph.cpp: Don't declare `hypot'. + Use `groff_hypot'. + + * src/preproc/pic/pic.h: Don't declare `hypot'. + + * src/preproc/pic/object.cpp (hypot): Use `groff_hypot'. + +2005-03-15 Gaius Mulley + + * src/devices/grohtml/post-html.cpp + (html_printer::lookahead_for_tables): End .ce properly to avoid a + segfault. + +2005-03-15 Werner LEMBERG + + makeinfo 4.8 doesn't produce good HTML output from groff.texinfo. + + * doc/fixinfo.sh: New script to postprocess makeinfo's HTML output. + + * doc/Makefile.in (.texinfo.html): Call fixinfo.sh. + +2005-03-14 Werner LEMBERG + + Add Cyrillic support to devutf8 and devhtml. + + * font/devutf8/R.proto, font/devhtml/R.proto: Add Cyrillic blocks. + + * tmac/unicode.tmac: New file. + + * tmac/tty.tmac: Include unicode.tmac if device is utf8. + + * tmac/Makefile.sub (NORMALFILES): Add unicode.tmac. + + * NEWS: Updated. + +2005-03-02 Keith Marshall + + * src/libs/libdriver/printer.cpp (check_for_output_error): New + function. It has been introduced to catch peculiar error contexts + on MS-Windows platforms. + +2005-02-28 Werner LEMBERG + + * src/roff/troff/input.cpp (string_iterator::fill): Protect against + null pointer. + + * tmac/papersize.tmac: Convert `paper' string contents to lowercase. + + * configure: Regenerated. + + * NEWS: Updated. + +2005-02-28 Keith Marshall + + Integrate `pdfmark' into normal groff build system; + install macro `pdfmark' packages, build and install `pdfroff', + and PDF format documentation. + + * Makefile.comm: Add PDFDOCDIR. + + * Makefile.in: (MDEFINES) ALT_AWK_PROGS, ALT_GHOSTSCRIPT_PROGS, + pdfdocdir, make_pdfdoc, make_install_pdfdoc: New variables. + (unstall_dirs): Add pdfdocdir. + + * aclocal.m4: (GROFF_GHOSTSCRIPT_PREFS): New function; support + `--with-alt-gs' option, set ALT_GHOSTSCRIPT_PROGS. + (GROFF_GHOSTSCRIPT_PATH): Support `--with-gs' option, force use of + GROFF_GHOSTSCRIPT_PREFS, set GHOSTSCRIPT. + (GROFF_HTML_PROGRAMS): Force use of GROFF_GHOSTSCRIPT_PATH; tidy up. + (GROFF_AWK_PREFS): New function; support `--with-alt-awk' option, + set ALT_AWK_PROGS. + (GROFF_AWK_PATH): New function; support `--with-awk' option, force + use of GROFF_AWK_PREFS. + (GROFF_PDFDOC_PROGRAMS): New function; force use of GROFF_AWK_PATH + and GROFF_GHOSTSCRIPT_PATH, set make_pdfdoc and make_install_pdfdoc. + + * configure.ac: Add AC_PREREQ(2.59), GROFF_PDFDOC_PROGRAMS. + Remove GROFF_GHOSTSCRIPT_PATH, (forced by GROFF_PDFDOC_PROGRAMS, and + also by modified GROFF_HTML_PROGRAMS). + +2005-02-27 Gaius Mulley + + * src/devices/grohtml/html-text.cpp (html_text::do_pre): Preserve + paragraph spacing. + (html_text::done_para): Unset `start_space'. + (html_text::remove_para_align): Call `retrieve_para_space' for the + spacing. + + * src/devices/grohtml/post-html.cpp (html_printer::emit_raw): Unset + `seen_space'. + (html_printer::do_check_center): Emit vertical space if necessary. + + * src/roff/troff/env.cpp (environment_switch): Preserve + `seen_space', `seen_eol', and `suppress_next_eol' while switching + environments. + + * src/roff/troff/node.cpp (suppress_node::suppress_node): Set + `is_special'. + +2005-02-20 Werner LEMBERG + + * src/preproc/eqn/eqn.man, NEWS: Document various extensions of + eqn. + +2005-02-17 Werner LEMBERG + + * doc/pic.ms, man/groff.man: Fix typos. + + * doc/groff.texinfo: Fix typos. + (\LEmacro): Get proper mathematical spacing. + +2005-02-16 Werner LEMBERG + + * aclocal.m4 (GROFF_APPRESDIR_CHECK): Improve warning message. + * configure: Regenerated with autoconf 2.59b. + +2005-02-16 Gaius Mulley + + * src/devices/grohtml/post-html.cpp (html_printer::is_line_start, + html_printer::start_font): Fix handling of preformatted text. + +2005-02-15 Gaius Mulley + + These patches modify the indentation implementation to use `

'. Many thanks to Peter and Larry for + suggesting this solution. Grohtml only uses tables for `.IP' and + related tags when the first operand has a short width. + + Similarly, they modify all vertical space code. By default, grohtml + sets up a style sheet which uses no vertical space between `table', + `pre', and `p' tags. It forces spaces when it needs them using + `style="margin-top: 1em"'. + + * src/devices/grohtml/html-table.cpp: Include `html-text.h'. + (html_table::emit_table_header, html_table::emit_new_row): + Rewritten. + (html_table::set_space): New function. + (html_indent::html_indent): Don't set `is_used'. + (html_indent::begin): Rewritten. + (html_indent::end): Remove code in function. + + * src/devices/grohtml/html-table.h: Updated. + (html_table): Make `out' public. + + * src/devices/grohtml/html-text.cpp (html_text::html_text): + Initialize `start_space' with FALSE. + (html_text::end_tag) : Updated. + (html_text::issue_tag): Add argument to handle space style. + (html_text::start_tag) : Updated. + (html_text::flush_text): Don't set `start_space'. + (html_text::push_para): Don't set `p->really_issued'. + (html_text::do_emittext): Updated. + (html_text::do_para): Add parameter to handle space. + Update all callers. + (html_text::retrieve_para_space): New function. + + * src/devices/grohtml/html-text.h (STYLE_VERTICAL_SPACE): New macro. + (tag_definition): Remove `really_issued'. + (html_text): Updated. + + * src/devices/grohtml/post-html.cpp (html_printer): Add variables + `current_column' and `row_space'. + Update constructor. + (html_printer::emit_raw, html_printer::write_header, + html_printer::do_indent, html_printer::do_check_center, + html_printer::do_tab_ts): Handle vertical space. + (html_printer:do_tab_te, html_printer::do_end_para): Call + `remove_para_space'. + (html_printer::do_col): Rewritten. + (html_printer::flush_globs): Remove debugging code. + (html_printer::is_line_start): New function. + (html_printer::start_font): Use `is_line_start'. + (html_printer::writeHeadMetaStyle): New function. + (html_printer::do_file_components, html_printer::~html_printer): + Call `writeHeadMetaStyle'. + + * tmac/www.tmac (www-handle-percent): New macro. + (MPIMG): Handle percent values for width and height parameters. + (DC): Updated. + + * tmac/groff_www.man: Updated. + +2005-02-14 Werner LEMBERG + + * src/utils/afmtodit/afmtodit.pl: Remove an incorrect `my' from + $psname and $italic_angle. + Immediately restart file input loops if `split' returns an empty + array. + +2005-02-13 Michail Vidiassov + Werner LEMBERG + + Update afmtodit to better support Unicode (Michail). + Update afmtodit to use Perl 5 syntax (Werner). + + * src/utils/afmtodit/afmtodit.pl: Don't use `getopts.pl' but + `Getopts::Std'. + Decorate variables with `my' where necessary. + Use `defined' where necessary to avoid warnings. + Don't use `do' for subroutine calls. + Other minor syntax updates. + Check for both `uXXXX[X[X]]' and `uniXXXX'. + Handle glyph variants properly. + (%unicode_decomposed, %AGL_to_unicode): Don't use `u' prefix in + strings. + + * src/utils/afmtodit/afmtodit.man: Updated. + +2005-02-13 Werner LEMBERG + + Make groff.texinfo work with texinfo 4.8. + + * doc/groff.texinfo (@Var): Use @r and @slanted. + (@defdummy, @Def*): Use @c to avoid empty lines. + (\angles): Replaced with... + (\Langlemacro, \Ranglemacro): New TeX macros. + (@Langlemacro, @Ranglemacro): New variables defined with @set. + (@angles): Use @Langlemacro and @Ranglemacro. + (\LE): Replaced with... + (\LEmacro): New TeX macro. + (@LEmacro): New variable defined with @set. + (@LE): Use @LEmacro. + (@Lparenmacro, @Rparenmacro, @Lbrackmacro, @Rbrackmacro): New + variables defined with @set. + (@lparen, @rparen, @lbrack, @rbrack): Replaced with... + (@Lparen, @Rparen, @Lbrack, @Rbrack): New macros. + Update all callers. + + Other minor updates. + + * doc/texinfo.tex: Update to texinfo version 4.8. + + * README.CVS: Updated. + +2005-02-09 Alejandro López-Valencia (tiny change) + + * doc/groff.texinfo (ms Document Control Registers): Document `HY' + and `FAM' registers. + +2005-02-05 Werner LEMBERG + + * tmac/groff_mdoc.man, tmac/doc-common, tmac/doc-ditroff, + tmac/doc-nroff, tmac/doc-old.tmac, tmac/doc-syms, tmac/doc.tmac: + Update BSD license. + +2005-02-01 Werner LEMBERG + + * src/roff/groff/groff.man: Add information about paper size. + +2005-01-25 Werner LEMBERG + + * src/roff/nroff/nroff.sh: Handle `*.ISO8859-1' in locale. From + NetBSD bin/29114. + +2005-01-22 Ruslan Ermilov + + * tmac/doc.tmac (Sm): Improved. It didn't work properly in many + cases. + (Re): Emit a warning if called without `.Rs'. + (doc-finish-reference): Use parameter for decreasing + `doc-reference-count'. + (doc-print-reference): Pass specific count parameters to + `doc-finish-reference'. + +2005-01-21 Werner LEMBERG + + * src/libs/libdriver/input.cpp (delete_current_env, do_file): + Reset pointers to zero after deallocation. This fixes a crash + if a driver is called with multiple input files. Reported by + Ken Chilton . + + * src/devices/grops/grops.man: Add more info on DSC. + +2005-01-17 Ruslan Ermilov + + * tmac/doc-common (Dd), tmac/doc-ditroff (gX, doc-setup-header): + Remove dead code. + +2005-01-17 Werner LEMBERG + + * src/roff/troff/div.cpp (top_level_diversion::space): Protect + against division by zero. + +2005-01-13 Ruslan Ermilov + + * tmac/doc.tmac (Ef): Restore doc-curr-font and doc-curr-size. + +2004-12-19 Werner LEMBERG + + * install-sh: New version; taken from texinfo CVS. + +2004-12-17 Werner LEMBERG + + * tmac/devtag.tmac: Protect against loading twice. + Protect against compatibility mode. + * tmac/www.tmac: Protect against loading twice. + Load `devtag.tmac' before switching off compatibility mode. + * tmac/an-old.tmac, tmac/s.tmac: Load `devtag.tmac'. + +2004-12-16 Mike Bianchi + + * configure.ac: Produce `contrib/gdiffmk/tests/runtests'. + * configure: Updated. + +2004-12-15 Thomas Klausner + + * tmac/doc-syms, tmac/groff_mdoc.man: Add `libpam' library. + +2004-12-15 Werner LEMBERG + + Make `test-groff' work again -- previously, wrong paths have been + used. Additionally, it can now be called from anywhere. + + * test-groff.in: Don't test for groff binary. This is no longer + necessary since the proper paths are determined by `configure'. + (EXEEXT): Removed. No longer used. + (srcdir, builddir): Use values provided by the configure script. + (XENVIRONMENT): Updated. + + * INSTALL: Updated. + +2004-12-14 Gaius Mulley + + Make .tag and .taga work for all devices (but only grohtml actually + handles them). + + * src/devices/grohtml/post-html.cpp: s/html-tag/devtag/. + (text_glob::is_br, page::add_tag, html_printer::troff_tag, + html_printer::handle_assertion): Don't use hard-coded string + lengths. + (html_printer::lookahead_for_table): Reset `tbl' properly if + necessary. + (html_printer::devtag): New function, handling `devtag'. + (html_printer::special): Don't handle `html-tag'. + + * src/include/printer.h, src/libs/libdriver/printer.cpp + (printer::devtag): New virtual function. + + * src/libs/libdriver/input.cpp (parse_x_command) <'X'>: Handle + `devtag'. + + * src/roff/troff/env.cpp, src/roff/troff/mtsm.cpp, + src/roff/troff/node.cpp: s/html-tag/devtag/. + + * src/roff/troff/input.cpp (tag, taga): Always call + curenv->add_node. + + * tmac/an-old.tmac, tmac/s.tmac, tmac/troffrc-end: Use DEVTAG* + macros instead of HTML-TAG*. + + * tmac/devtag.tmac: New file, defining the DEVTAG-* macros. + + * tmac/www.tmac: Load devtag.tmac. + Replace HTML-TAG* macros with DEVTAG* macros. + (HTML, HTML-NS): Changed definitions. + (URL): Use HTML-NS. + (HTML-TAG, HTML-TAG-NS, HTML-TAG-NEXT): Removed. + + * tmac/Makefile.sub (NORMALFILES): Add devtag.tmac. + +2004-12-10 Werner LEMBERG + + Import Mike's `gdiffmk' package. + + * contrib/gdiffmk/*: New files. + * Makefile.in (OTHERDIRS): Add contrib/gdiffmk. + * NEWS: Updated. + +2004-12-08 Werner LEMBERG + + Import Keith's `pdfmark' package. Integration is very preliminary. + + * contrib/pdfmark/*: New files. + * Makefile.in (OTHERDIRS): Add contrib/pdfmark. + * NEWS: Updated. + +2004-12-07 Gaius Mulley + + Fix a bug with title handling in HTML. + + * src/devices/grohtml/post-html.cpp (text_glob::is_nf, + text_glob::is_fi, text_glob::is_ce): Use strlen to compute string + length. + (html_printer::handle_tag_within_title): New function. + (html_printer::do_title): Use it. + + * tmac/s.tmac (TL): Don't set `need_eo_tl'. + (cov*tl-au-print): Emit `.eo.tl' tag. + +2004-12-05 Alejandro López-Valencia + + * man/groff_char.man: Minor imrovements. + +2004-12-04 Werner LEMBERG + + * src/preproc/eqn/eqn.man: Revised. + +2004-11-25 Werner LEMBERG + + * src/utils/xtotroff/xtotroff.c: Reformat to be similar to other + groff source files. + Include config.h. + Include limits.h. + Remove X_NOT_STDC_ENV conditional. + (Version_string, program_name): New global variables. + (groff_flag): Removed. + (MapFont): Updated. + (usage): Take a stream as argument. + Use `program_name'. + Update all callers. + (main): Add `long_options' array for `--help' and `--version'. + Make `-g' a dummy option. + Handle `-v' and unknown options. + Remove unused `position' variable. + + * src/utils/xtotroff/Makefile.sub (MAN1): Define. + (XLIBS): Add LIBGROFF. + + * src/utils/xtotroff/xtotroff.man, src/utils/xtotroff/Makefile.in: + New files. + + * src/devices/xditview/Dvi.c (default_font_map): Split into three + parts to avoid compiler warning. + (resources): Don't initialize with `default_font_map'. + (ClassInitialize): Initialize first element of `resources'. + + * src/devices/xditview/Makefile.sub (devdir, xtotroff, DPIS, fonts): + Removed. + + * src/utils/lkbib/lkbib.man, src/utils/lookbib/lookbib.man, + src/utils/pfbtops/pfbtops.man: Revised, updated. + + * configure.ac: Generate src/utils/xtotroff/Makefile. + * configure: Regenerated. + +2004-11-24 Werner LEMBERG + + First fixes to get produce HTML. + + * src/devices/grohtml/post-html.cpp (generate_img_src): Add `alt' + attribute. + + * tmac/www.tmac (IMG, PIMG, MPIMG): Add `alt' attribute. + (HR, LI): Use `HTML

', not `HTML'. + + * doc/webpage.ms: Minor updates. + +2004-11-23 Larry Kollar + + Add option -S grohtml to determine the file split level. + + * src/devices/grohtml/post-html.cpp (split_level): New global + variable. + (html_header::determine_header_level): Use split_level. + (main): Handle `-S' command line option. + Sort options. + + * src/preproc/html/pre-html.cpp (scanArguments): Updated. + + * src/devices/grohtml/grohtml.man: Document it. + Sort options. + + * NEWS: Document it. + +2004-11-23 Y T + + * tmac/s.tmac (ref*add-V, ref*add-N): New macros for handling + the volume and number refer entries. + +2004-11-22 Werner LEMBERG + + * src/devices/grohtml/html-table.cpp + (html_table::emit_table_header): Don't emit `cols' attribute which + doesn't exist in HTML 4.0 and is thus invalid. + + * NEWS: More minor fixes and updates. + +2004-11-18 Werner LEMBERG + + * tmac/www.tmac (HTML-NS, HTML-TAG-NS, HTML-TAG-NEXT): Simplified. + (HTML

): Minor clean-up. + + * tmac/groff_www.man: Updated. + + * src/devices/grohtml/grohtml.man: Revised and updated. + + * NEWS: Updated. + +2004-11-18 Gaius Mulley + + * src/devices/grohtml/post-html.cpp (html_printer::do_heading): + Fix space insertion. + (html_printer::do_links): Fix rules generation around automatic + heading links. + + * tmac/www.tmac (LK): Use HTML-TAG-NS. + (HR): Simplify. + No longer emit empty line for non-HTML devices. + +2004-11-17 Werner LEMBERG + + * doc/Makefile.in (prepare_examples, webpage.html): Handle + `groff.css'. + + * doc/Makefile.sub (EXAMPLEFILES, CLEANNOTSRCDIRADD, + prepare_examples, webpage.html): Handle `groff.css'. + +2004-11-15 Werner LEMBERG + + * NEWS, README, doc/webpage.ms: Updated. + + * tmac/www.tmac (HTML, HTML-TAG): Minor clean-ups. + +2004-10-30 Gaius Mulley + + * src/include/printer.h (printer): Remove virtual function + `round_width'. + Update all source files. + + * src/devices/grohtml/post-html.cpp (html_printer): New member + function `round_width'. + +2004-10-20 Tadziu Hoffmann + + * src/preproc/tbl/table.cpp (table::do_row): Fix handling of the `d' + column key letter suffix. + +2004-10-14 Werner LEMBERG + + * Makefile.in (check): Depend on `site.exp' and `docheck'. + (docheck): Run dejagnu's `runtest' if it exists. + (site.exp): Create dejagnu configuration file. + + * Makefile.sub (DISTCLEANFILES): Add files related to dejagnu. + +2004-10-13 Werner LEMBERG + + * src/devices/grohtml/html-text.cpp (html_text_get_alignment), + src/devices/grohtml/post-html.cpp (make_val, + html_printer::handle_state_assertion): Fix compiler warnings. + + * src/roff/troff/div.cpp: Include `stringclass.h' and `mtsm.h'. + (diversion::diversion): Fix order of initializers. + + * src/roff/troff/div.h: Don't include `mtsm.h'. + + * src/roff/troff/env.cpp: Include `stringclass.h' and `mtsm.h'. + (environment::environment): Fix order of initializers. + (environment::make_tag, environment::construct_format_state): Fix + compiler warnings. + + * src/roff/troff/input.cpp: Include `stringclass.h' and `mtsm.h'. + (input_iterator::input_iterator, macro::macro): Fix order of + initializers. + + * src/roff/troff/mtsm.cpp: Include only necessary header files. + (state_set::add, state_set::val): Fix compiler warnings. + + * src/roff/troff/mtsm.h: Don't include `stringclass.h'. + (bool_value_state, int_value_state, units_value_state, + string_value_state): Remove comma after last element which causes + an error with g++ 3.3.3. + + * src/roff/troff/node.cpp: Include `stringclass.h'. + (hline_node::hline_node, vline_node::vline_node, + space_char_hmotion_node, left_italic_corrected_node): Fix compiler + warnings. + (zero_width_node::zero_width_node): Fix order of initializers. + + * src/roff/troff/node.h: Don't include `mtsm.h'. + (hmotion_node): Fix compiler warnings. + + * src/roff/troff/number.cpp: Include `stringclass.h' and `mtsm.h'. + +2004-10-12 Gaius Mulley + + * doc/groff.css: New file. + + * doc/webpage.ms: Use `groff.css'. + Other small fixes. + + * tmac/an-old.tmac (need_eo_h): New number register. + (TH): Emit `.eo.tl' tag after title. + (SH): Set `need_eo_h'. + (an-trap): Handle `need_eo_h'. + (an-do-tag): s/HTML-TAG-NS/HTML-TAG-NEXT/. + + * tmac/s.tmac (need_eo_h, need_eo_tl): New number registers. + (TL): Always start diversion. + Updated. + (@AI): Always call `par@reset'. + (@AB): Update code for -Thtml. + (cov*tl-au-print): Handle -Thtml. + (par@reset): Handle `need_eo_tl', `need_eo_h'. + (@IP): Simplified. + (@IT-html): Removed. + (@SH): Set `need_eo_h' for -Thtml. + (par@TL): s/HTML-TAG/HTMl-TAG-NS/. + Set `need_eo_tl'. + (@NH): s/HTML-TAG/HTMl-TAG-NS/. + Set `need_eo_h' for -Thtml. + (@EQ, @EN): Don't handle -Thtml specially. + (par@load-init): Don't handle -Thtml specially. + + * tmac/www.tmac (www:paraspace): New macro. + (HTML-NS, HTML-TAG-NS): Use new `tag' request. + (HTML

, HTML-TAG-NEXT): New macros. + (HnE): Emit tag `.eo.h' instead of break. + (HR): s/HTML-NS/HTML/. + (www-end-nowhere): End diversion only if `www-html' not set. + Emit `.eo.tl' tag. + (ULS, ULE): s|HTML|HTML

|. + (LI): Call `www:paraspace'. + (HEAD): New macro. + +2004-10-11 Gaius Mulley + + * src/roff/troff/request.h (macro): Make `p' public. + New variable `is_a_diversion'. + New member function `is_diversion'. + + + * src/devices/grohtml/html.h (simple_output): New member function + `force_nl'. + + * src/devices/grohtml/html-table.cpp (tabs::compatible): Fix + computation of `total'. + (tabs::check_init): New function. + (html_table::emit_table_header): Emit style data. + (html_table::insert_column): Improved. + + * src/devices/grohtml/html-table.h: Updated. + + * src/devices/grohtml/html-text.cpp (html_text::html_text): + Initialize `start_space' with TRUE. + (html_text::end_tag, html_start_tag): Fix `P_TAG' and `PRE_TAG' + cases. + (html_text::flush_text): Set `start_space' flag. + (html_text::uses_indent, html_text::remove_para_space, + html_text::get_alignment): New functions. + (html_text::push_para): Updated. + (html_text::do_para): Check for empty argument. + Don't set `space_emitted'. + (html_text::do_space, html_text::emit_space): Updated. + + * src/devices/grohtml/html-text.h (tag_definition): New variable + `really_issued'. + (html_text): New member function `uses_indent', `remove_para_space', + `get_alignment'. + + * src/devices/grohtml/output.cpp (simple_output::force_nl): New + function. + (simple_output:nl): Always emit `\n'. + + * src/devices/grohtml/post-html.cpp: Include `string.h'. + (BASE_POINT_SIZE): Removed. + (base_point_size, head_info): New global variables. + (text_glob): New member functions `is_ll', `is_tl', `is_eo_tl', + `is_eo_h'. + (text_glob::is_nf, text_glob::is_fi): Handle `.fi 0' and `.fi 1' + tags, respectively. + (page::add_and_encode): Pass additional parameter for tag flag. + (assert_pos): New structure. + (assert_state): New class. + (html_printer): Remove `indentation', `prev_indent'. + Add variables `troff_indent', `device_indent', `temp_indent'. + Add variables `seen_indent', `next_indent', `seen_pageoffset', + `next_pageoffset', `seen_linelenght', `next_linelength', + `seen_center', `next_center', `seen_space', `seen_break', `as'. + Add member functions `do_check_center', `do_space', `do_head', + `get_troff_indent', `restore_troff_indent', `handle_assertion', + `handle_state_assertion', `do_end_para', `set_char_and_width'. + Change argument to `do_fill' to `char *'. + Update constructor. + (html_printer::emit_raw): Call `shutdown_table'. + Use new functions. + (html_printer::do_center): Simplified. + (html_printer::do_title): Improved. + (html_printer::write_header): Emit one more newline. + Use new functions. + (html_printer::do_heading, html_printer::do_indent, + html_printer::do_eol, html_printer::do_tab_ts, + html_printer::do_tab, html_printer::do_tab0, + html_printer::calc_po_in, html_printer::next_horiz_pos, + html_printer::remove_courier_tabs, + html_printer::insert_tab0_foreach_tab, html_printer::begin_page): + Updated. + (html_printer::do_linelength, html_printer::do_pageoffset, + html_printer::do_indentation, html_printer::do_tempindent, + html_printer::do_tab_te): Simplified. + (html_printer::do_pointsize): Check whether point size is really + associated a `.tl' tag. + (html_printer::do_break): Rewritten. + (html_printer::troff_tag): Improved. + (html_printer::flush_globs): Updated. + (html_printer::lookahead_for_tables): Handle `is_br'. + Use new functions. + (html_printer::set_char): Check `sbuf_style.f'. + (html_printer::write_navigation): Use string comparison. + (html_printer::~html_printer): Emit `head_info'. + (html_printer::special): Rewritten. + (get_str, make_val): New functions. + (main): New option `s' to set the base point size. + + * src/preproc/html/pre-html.cpp (scanArguments): Handle option `s'. + +2004-10-10 Gaius Mulley + + * src/roff/troff/node.cpp: New extern `debug_state'. + Include `stringclass.h' and `mtsm.h'. + Implement new classes and class members from `node.h'. + (real_output_file): Make `fp' public. + (troff_output_file): New variables `cur_div_level' and `tag_list'. + Update constructors. + (troff_output_file::really_print_line): Check whether we should push + the current troff state and use the state at the start of the + invocation of this diversion. + (troff_output_file::add_to_tag_list): New member function. + (node::add_char): Handle `glyph_comp_np'. + + * src/roff/troff/node.h: Include `mtsm.h'. + (node): New variables `state', `push_state', `div_nest_level', + `is_special'. Update constructors, all descendants. + Pass additional argument to `add_char' member function. + New virtual member functions `is_tag', `debug_node', + `debug_node_list'. Update all descendants. + (tag_node): New class for handling tags. + (output_file): Add variable `state'. + +2004-10-09 Gaius Mulley + + * src/roff/troff/mtsm.cpp, src/roff/troff/mtsm.h: New files, + providing a minimal troff state machine to emit meta tags for the + post-grohtml device driver. + + * src/roff/troff/Makefile.sub (OBJS, CCSRCS, HDRS): Handle new + files. + +2004-10-09 Werner LEMBERG + + * tmac/trace.tmac: Fix handling of `am' and `am1' calls. + +2004-10-06 Gaius Mulley + + * src/roff/troff/column.cpp (vjustify_node::copy): Updated. + + * src/roff/troff/div.h: Include `mtsm.h'. + (diversion): New variables `any_chars_added', `needs_push', + `saved_seen_break', `saved_seen_space', `saved_seen_eol', + `saved_suppress_next_eol', `modified_tag'. + New virtual member function `is_diversion'. Update all descendants. + + * src/roff/troff/div.cpp (diversion::diversion, + macro_diversion::macro_diversion): Updated. + (do_divert): Handle `seen_break', `seen_space', `seen_eol', + `suppress_next_eol'. + (top_level_diversion::space): Handle `curenv->seen_space'. + (page_offset): Update tag handling. + (space_request, blank_line, flush_output): Don't call `add_html_tag'. + + * src/roff/troff/env.h (environment): Make `tabs' public. + Remove `ignore_next_eol', `emitted_node'. + Update `output_line', `output'. + New variables `seen_space', `seen_eol', `suppress_next_eol', + `seen_break'. + New member functions `construct_state', `make_tag', + `construct_format_state, `construct_new_line_state, + `dump_troff_state'. + Remove `add_html_tag', `make_html_tag'. + + * src/roff/troff/env.cpp: New externs `suppress_push', + `get_diversion_state', `global_diverted_space'. + (pending_output_line): New variable `was_centered'. + Update constructor and all callers. + (pending_output_line::output): Call `curenv->construct_format_state'. + (environment::environment, environment::copy): Updated. + (environment::output): Handle `was_centered'. + (environment::add_char): Handle construct and diversion state. + (environment::add_node): Handle construct state. + (environment::newline): Handle `was_centered'. + (environment::output_line): Updated. + (environment::possibly_break_line): Updated. + Update tag handling. + (environment::add_html_tag): Replaced with... + (environment::make_tag): New function. + (environment::add_html_tag_tabs, environment::make_html_tag): Removed. + (environment::dump_troff_state): New debugging function. + (environment::construct_state, environment::construct_format_state, + environment::construct_new_line_state): New functions. + (environment::do_break): Updated. + Handle `global_diverted_space'. + (environment::handle_tag): Update tag handling. + (point_size, fill, do_break_request): Don't call `add_html_tag'. + (no_fill): Don't call `add_html_tag'. + Set `suppress_next_eol'. + (center, right_justify, line_length, indent, temporary_indent, + set_tabs): + Update tag handling. + + * src/roff/troff/input.cpp: Don't include `stringclass.h'. + (input_iterator): New variables `is_diversion', `diversion_state'. + Update constructors. + (input_stack): New member functions `get_div_level', + `get_diversion_state', `check_end_diversion'. + New variables `div_level', `diversion_state'. Initialize them. + (suppress_push, global_diverted_space): New global variables. + (input_stack::finish_get, input_stack::finish_peek, + input_stack::remove_boundary, input_stack::end_file, + input_stack::clear, input_stack::pop_macro): Call + `check_end_diversion'. + (input_stack::push): Handle `div_level' and `diversion_state'. + (get_diversion_state): New function. + (diverted_space_node::reread): Handle `global_diverted_space'. + (macro::macro): Update constructors. + (macro::is_diversion): New function. + (macro::operator=): Set `is_a_diversion'. + (string_iterator): New member function `is_diversion'. + (string_iterator::string_iterator): Update constructors. + (string_iterator::fill): Set `div_nest_level'. + (macro_iterator): New member function `is_diversion'. + (do_if_request): Handle `suppress_push'. + (tag, taga): New functions. + (init_input_requests): Add `tag' and `taga' requests. + +2004-10-05 Gaius Mulley + + * src/include/font.h (font): New member function + `get_image_generator'. + New variables `unscaled_charwidths' and `image_generator'. + + * src/libs/libgroff/font.cpp (font::get_width): Always return the + character's unscaled width if `font::unscaled_charwidths' is set. + (font::get_image_generator): New function. + (font::load_desc): Check the `unscaled_charwidths' and + `image_generator' keywords. + + * src/libs/libgroff/fontfile.cpp: Initialize + `font::unscaled_charwidths' and `font::image_generator'. + + * font/devhtml/DESC.proto: s/html/unscaled_charwidths/. + + * font/devhtml/Makefile.sub (DESC): Set `image_generator' keyword. + + * man/groff_font.man: Document `unscaled_charwidths' and + `image_generator'. + + * src/preproc/html/pre-html.cpp: Include `device.h'. + (image_gen): New global variable. + (imageList::createPage): Use `image_gen'. + (main): Use `image_generator' keyword. + +2004-10-04 Gaius Mulley + + * tmac/html.tmac: Handle \[sqrtex]. + +2004-10-04 Gaius Mulley + + * src/include/printer.h (printer): New virtual method `round_width'. + + * src/devices/grodvi/dvi.cpp, src/devices/grolbp/lbp.cpp, + src/devices/grolj4/lj4.cpp, src/devices/grops/ps.cpp, + src/devices/grotty/tty.cpp (printer::round_width): New function + member. + + * src/devices/grohtml/post-html.cpp (printer::round_width): New + function member. + (html_printer::set_numbered_char): Use it. + +2004-10-03 Gaius Mulley + + * aclocal.m4 (GROFF_GHOSTSCRIPT_PATH): New macro. + + * configure.ac: Call GROFF_GHOSTSCRIPT_PATH. + + * configure: Regenerated. + + * Makefile.in (GHOSTSCRIPT): New variable. + (MDEFINES): Add GHOSTSCRIPT. + +2004-10-03 Werner LEMBERG + + * INSTALL.gen: Updated (taken from texinfo CVS). + +2004-09-28 Werner LEMBERG + + * NEWS: Updated. + +2004-09-28 Heinz-Jürgen Oertel + + * tmac/groff_www.man: Revised and updated. + +2004-09-26 Werner LEMBERG + + Fix \$@ and \$* to handle any number of arguments. + + * src/roff/troff/input.h (BEGIN_QUOTE, END_QUOTE): New special + characters. + + * src/roff/troff/input.cpp (input_iterator::internal_level): + Removed. + (input_stack): New member functions `increase_level' and + `decrease_level'. + (input_stack::get_level): Don't use `internal_level'. + (get_copy, token::next): Handle BEGIN_QUOTE and END_QUOTE. + (end_quote_iterator): Completely removed. + (interpolate_arg): Build string for \$@ and \$* which is then + pushed onto the input stack. + +2004-09-23 Keith Marshall + + * tmac/groff_ms.man, doc/groff.texinfo (ms Document Control + Registers): Document changes from 2004-09-19. + +2004-09-23 Werner LEMBERG + + * tmac/an-old.tmac (ne): Using default scaling operator. + +2004-09-19 Keith Marshall + + This change implements the following features: + + PORPHANS + New numeric register: Defines number of lines following LP, PP, + QP, IP or XP, which must be kept together, before any automatic + page break. If insufficient space remains on the current page, a + page break is forced before the new paragraph begins. + + HORPHANS + New numeric register: Sets number of lines of following paragraph + which must be kept with a heading, defined by NH or SH, before any + automatic page break. If insufficient space remains on the + current page, a page break is forced before the heading. + + GROWPS + (Thanks to Joerg van den Hoff, for this idea). + + New numeric register: Sets the first level of heading (set with + NH), which will keep the same point size as body text; e.g. if + GROWPS is set to 3, .NH 3, .NH 4, ... will produce headings at the + point size specified by \n[PS], but .NH 2 and .NH 1 will have + progressively larger point sizes, determined by \n[PSINCR] (see + below). + + PSINCR + New numeric register: Sets the point size increment for each level + of heading, (set with NH), below the threshold level set by + GROWPS; e.g. if \n[PS] = 10, \n[GROWPS] = 3 and \n[PSINCR] = 2.0p, + then .NH 1 will produce 14pt headings, .NH 2 will produce 12pt, + and all other levels will remain at 10pt, (because \n[PS] = 10). + + SH + Existing macro now accepts a numeric argument, to make heading + size match that of NH with same argument value, when the + GROWPS/PSINCR feature is enabled. + + SN-DOT + New string, set by NH macro, replaces the existing (undocumented) + use of SN, to represent the assigned section number. + + SN-NO-DOT + New string, set by NH macro, represents the assigned section + number, but omits the terminal period (periods at intermediate + levels are retained). + + SN + String set by NH macro, originally undocumented, now implemented + as an alias for SN-DOT (which reproduces original behaviour). + + * tmac/s.tmac (PORPHANS): New register. + (par*start): Use it. + (HORPHANS, GROWPS, PSINCR): New registers. + (SH-NO-TAG, @SH): Use them. + (@NH): Improved. + +2004-09-19 Keith Marshall + + * NEWS, doc/groff.texinfo (ms Display and Keeps), tmac/groff_ms.man: + Document the deletion of `Ds' and `De' macros. + +2004-09-10 Werner LEMBERG + + In tbl, handle \a as an interpreted leader character if in + compatibility mode. + + * src/preproc/tbl/table.h (PREFIX, PREFIX_CHAR, LEADER, + LEADER_CHAR): New macros. + (compatible_flag): New declaration. + + * src/preproc/tbl/main.cpp (table_input): Add LEADER_1, LEADER_2, + LEADER_3, and LEADER_4 to `state'. + (table_input::get): Handle `\a'. + + * src/preproc/tbl/table.cpp (PREFIX): Removed. + (LEADER_REG): New macro. + (table::init_output): Define LEADER_REG string register if in + compatibility mode. + + * src/preproc/tbl/tbl.man: Document it. + +2004-08-18 Werner LEMBERG + + * tmac/doc.tmac (An): Fix error message. + +2004-08-06 Werner LEMBERG + + * src/preproc/tbl/main.cpp (main): Call `fatal' not `error' if a + file can't be opened. UNIX tbl has the same behaviour. + +2004-08-05 Y T + + * src/preproc/grn/hdb.cpp (compatibility_flag): Add declaration. + (DBRead): If in compatibility mode, take into account the text + when computing figure boundaries. + +2004-08-05 Werner LEMBERG + + * src/preproc/soelim/soelim.man: Improved. Based on suggestions + from Tadziu Hoffmann. + +2004-08-03 Werner LEMBERG + + * doc/meref.me: Document `_M' register. + +2004-08-03 Martin Husemann + + Make hpftodit work correctly on big-endian systems. + + * src/utils/hpftodit/hpftodit.cpp (File): New method + `get_uint32(char *)'. + (entry): New member `orig_value'. + (read_tags): Use new method. + (output_font_name, read_and_output_pcltypeface, dump_ascii): + Updated. + +2004-08-01 Werner LEMBERG + + * tmac/s.tmac: Undo change 2003-06-29. The proper macro definitions + are already in X11's `macros.t' file. + +2004-08-01 Jeff Conrad + + * src/utils/hpftodit/hfptodit.cpp (output_font_name, dump_ascii): + Fix casting bug. + (read_and_output_pcltypeface): Handle strings with length <= 4. + +2004-07-27 Egil Kvaleberg + + * tmac/s.tmac (pg@top): Don't save `PO' register. + (pg*end-col, pg*end-page): Directly use `PO' register. + +2004-07-27 Werner LEMBERG + + * man/groff_tmac.man: Mention `trace' and `pic' macro packages. + + * src/preproc/refer/refer.cpp (output_references): Check for + empty hash table. + * src/preproc/refer/refer.man: Improve documentation of + `bibliography' command. + +2004-07-26 Werner LEMBERG + + Add requests `fcolor' and `gcolor'. + + * src/roff/troff/env.cpp (fill_color_change, glyph_color_change): + New functions. + (init_env_requests): Add `fcolor' and `gcolor'. + + * src/roff/troff/input.h: Export do_glyph_color and do_fill_color. + + * NEWS, man/groff_diff.man, man/groff.man, doc/groff.texinfo + (Colors): Document new requests. + +2004-07-24 Werner LEMBERG + + Add support for fractional point sizes in ms macros. A value for + PS, VS, FPS, and FVS greater than or equal to 1000 is always divided + by 1000. For example, `.nr PS 10250' sets the font size to 10.25p. + + * tmac/s.tmac (@AU, @AI, par@load-init, par@init, par@reset, NL, + PX): Handle fractional point sizes for PS, VS, FPS, and FVS. + + * tmac/groff_ms.man, docs/groff.texinfo (ms Document Control + Registers), NEWS: Document it. + +2004-07-19 Werner LEMBERG + + * src/preproc/pic/lex.cpp (for_input): Add member `from'. + Update constructor. + (do_for, for_input::get, for_input::peek): Handle negative `by'. + * src/preproc/pic/pic.man, doc/pic.ms, NEWS: Document it. + +2004-07-08 Thomas Klausner + + * tmac/doc-syms (doc-str-St--p1003.1-2004): New string. + * tmac/groff_mdoc.man: Updated. + +2004-07-05 Werner LEMBERG + + * doc/groff.texinfo (Manipulating Hyphenation): Further improve + documentation of `hcode'. + +2004-07-04 Sang Dae Yu + + Improve appearance of arrows in pic. + + * src/preproc/pic/object.cpp (draw_arrow): Make outline of filled + arrow head thin. + Use two line segments for drawing non-filled arrow head. + (line_object::print, spline_object::print): Shorten line length to + avoid arrow sticking. + (arc_object::print): Take arrow direction into account. + +2004-07-03 Heinz-Jürgen Oertel + + * tmac/groff_www.man: Update documentation of .MPIMG. + +2004-07-03 Werner LEMBERG + + * tmac/an-old.tmac (RI): Always start with font `R'. + (RI, IR): Properly end with font `R'. + +2004-07-02 Paul Eggert + + * man/ditroff.man, man/groff_font.man, man/groff_out.man, + src/devices/grohtml/grohtml.man, src/preproc/grn/grn.man, + src/preproc/pic/pic.man, tmac/groff_man.man, tmac/groff_ms.man: + Don't pass more than six arguments to .R, .I, .B, etc., for + compatibility with traditional troff macros. + +2004-07-02 Werner LEMBERG + + * src/roff/troff/input.h: s/COMPATIBLE_SAVE/PUSH_GROFF_MODE/. + s/COMPATIBLE_RESTORE/POP_GROFFCOMP_MODE/. + Update all users. + (PUSH_COMP_MODE): New internal character constant. + Update all users. + + * src/roff/troff/input.cpp (get_copy): Handle PUSH_GROFF_MODE, + PUSH_COMP_MODE, and POP_GROFFCOMP_MODE. + (token::next, macro::append): Handle PUSH_COMP_MODE. + (decode_args): Add PUSH_GROFF_MODE or PUSH_COMP_MODE before and + POP_GROFFCOMP after each of the decoded arguments to make them + independent from the compatibility mode status. + (comp_mode): Add `COMP_ENABLE'. + (do_define_string, do_define_macro): Handle COMP_ENABLE. + (define_string, append_string, define_macro, define_indirect_macro, + append_macro, append_indirect_macro): Handle `compatible_flag'. + (chop_macro, substring_request, asciify): Handle PUSH_COMP_MODE. + + * man/groff_diff.man, doc/groff.texinfo: Updated. + +2004-07-01 Werner LEMBERG + + * doc/groff.texinfo: Improve documentation of `hcode'. + Use @documentencoding and convert document to latin-1; to do that + make latin characters active and assign proper macros (within a + @tex...@end tex environment). + * doc/Makefile.in (.texinfo.html, groff): Use --enable-encoding. + * doc/Makefile.sub (groff): Ditto. + +2004-06-29 Werner LEMBERG + + Implement two new conditional operators `F ' and `S ' + which check whether is a valid font or style, respectively. + + * src/libs/libgroff/font.cpp (text_file): Add `silent' member. + (text_file::text_file): Updated. + (text_file::error): Don't emit message if `silent' is set. + (font::load_font): Add optional third argument (which is directly + passed to `load'. + (font::load): Add optional second argument to check the header of + a font only, without emitting warning or error messages. + * src/include/font.h (font): Updated. + + * src/roff/troff/input.cpp (do_if_request): Implement `S' and `F' + conditionals. + * src/roff/troff/node.cpp (mount_font_no_translate): Add optional + fourth argument to check a font without mounting. + (check_font, check_style): New functions. + * src/roff/troff/node.h: Updated. + + * man/groff_diff.man, man/groff.man, NEWS, doc/groff.texinfo: + Updated. + +2004-06-27 Werner LEMBERG + + Implement new string-valued register `.sty' to return the current + style name. + + * env.cpp (environment::get_style_name_string): New function. + (init_env_requests): Add `.sty' register. + * env.h (environment): Updated. + * node.cpp (font_info): Make `get_style_name' a friend. + (get_style_name): New function. + * node.h: Updated. + + * man/groff_diff.man, man/groff.man, NEWS, doc/groff.texinfo: + Updated. + +2004-06-15 Werner LEMBERG + + * src/preproc/tbl/main.cpp (process_data) : Handle + `nospaces' option. + +2004-06-10 Colin Percival + + * doc/meintro.me, doc/meref.me: Don't use \*[td], \n[dy], \*[mo], + and \n[mo] to avoid dependency on current date. + +2004-06-08 Werner LEMBERG + + * Makefile.sub (install_data): New target. + +2004-06-04 Werner LEMBERG + + * src/libs/libxutil/Makefile.sub (EXTRA_CFLAGS): Define. + +2004-06-03 Werner LEMBERG + + * src/devices/xditview/Makefile.sub (EXTRA_LDFLAGS): Fix typo and + order of libraries. + (install_data): Add $(srcdir). + + * src/utils/xtotroff/Makefile.sub (EXTRA_LDFLAGS): Fix order of + libraries. + +2004-06-02 Werner LEMBERG + + * aclocal.m4 (GROFF_X11): s/have_no_x/groff_no_x/. + Add X11 stuff to CFLAGS, LDFLAGS, and LIBS temporarily. + Add test for Xmu library. + (GROFF_APPRESDIR_OPTION, GROFF_APPRESDIR_CHECK, + GROFF_APPRESDIR_DEFAULT): New macros. + + * configure.ac: Call GROFF_APPRESDIR_OPTION, GROFF_APPRESDIR_CHECK, + and GROFF_APPRESDIR_DEFAULT. + + * configure: Regenerated. + + * Makefile.in (appresdir): New variable. + (MDEFINES): Add appresdir. + + * src/devices/xditview/Makefile.sub (EXTRA_LDFLAGS): Add -Xmu and + -Xt. + (install_data, uninstall_sub): New targets to handle GXditview.ad. + + * src/utils/indxbib/Makefiles.ub (install_data): Depend on + `$(srcdir)/eign', not `eign'. + + * MANIFEST, INSTALL, NEWS, PROBLEMS: Updated. + + * man/groff_out.man, man/roff.man, src/devices/grops/grops.man, + src/devices/xditview/gxditview.man, src/roff/groff/groff.man: + Protect (g)xditview with `\%' to avoid hyphenation. + Other minor formatting. + +2004-06-01 Werner LEMBERG + + Integrate gxditview into groff's standard directory hierarchy. + + * src/xditview/*: Moved to ... + * src/devices/xditview/*: Here. + Moved DviChar.h and XFontName.h to src/include. + Moved DviChar.c and XFontName.c to new directory src/libs/libxutil. + Split off `xmalloc' into new file src/libs/libxutil/xmalloc.c. + Moved xtotroff.c to new directory src/utils/xtotroff. + Provide proper Makefile.sub files (reusing the stuff from + Imakefile.in). + DESC renamed to DESC.in. + Removed GXDitview-ad.h, INSTALL, Imakefile.in. + Converted everything from K&R to ANSI C. + Decorated with const where appropriate. + Cast string constants with `String' and `char *' where appropriate. + Made it compile with C++ (used as a C compiler). + Removed other minor compiler warnings. + + * src/devices/xditview/device.c: Include config.h, string.h, and + defs.h. + Don't declare `exit', `strtok', `strchr', and `getenv'. + (FONTPATH): Remove. + + * src/devices/xditview/font.c: Don't declare `XParseFontName' and + `XFormatFontName'. + + * src/devices/xditview/xditview.c: Include config.h. + Include stdio.h earlier. + Protect declaration of `popen' and `pclose' with + NEED_DECLARATION_POPEN and NEED_DECLARATION_PCLOSE. + Replace `caddr_t' with `XtPointer'. + (MakePromptFunc): New typedef. + (DoPrint): Use RETSIGTYPE. + (promptfunction): Change type to MakePromptFunc. + (MakePrompt): Use MakePromptFunc for third argument. + (xmalloc): Removed. + + * src/devices/xditview/ad2c: Add casts to `String'. + + * src/include/XFontName.h (XFontNameString): Don't use array + notation. + Add prototypes for `XParseFontName', `XFormatFontName', + `XCompareFontName', and `XCopyFontName'. + + * src/include/Makefile.sub (HDRS): Add `DviChar.h' and + `XFontName.h'. + + * src/utils/xtotroff/xtotroff.c: Include getopt.h. + Don't declare `XParseFontName' and `XFormatFontName'. + (xmalloc): Removed. + (main): Remove `optind' and `optarg'. + + * Makefile.in (XDEVDIRS, XPROGDIRS, XLIBDIRS): New variables + (to select programs which need X). + Make XDEVIDIRS depend on `FORCE'. + (X_CFLAGS, X_LIBS, X_EXTRA_LIBS, X_PRE_LIBS): New variables (for + X support). + (MDEFINES): Updated. + (LIBDIRS): Use XLIBDIRS. + (CPROGDIRS): Use XPROGDIRS. + (DEVDIRS): Remove font directories for gxditview. + (ALLDIRS, DISTDIRS): Add XDEVDIRS. + (EXTRADIRS): Remove src/xditview. + + * Makefile.sub (DISCLEANFILES): Updated. + + * Makefile.comm (LIBXUTIL): New variable. + (.cpp.o, .cpp.obj): Handle EXTRA_CCFLAGS. + (.c.o, .c.obj, .y.o): Handle EXTRA_CFLAGS. + + * Makefile.cpg, Makefile.ccpg ($PROG): Handle EXTRA_LDFLAGS. + + * aclocal.m4 (GROFF_X11): New function. + + * configure.ac: Call GROFF_X11. + Don't create src/xditview/Imakefile. + Don't emit notice how to build gxditview. + + * configure: Regenerated. + + * test-groff.in (GROFF_BIN_PATH, XENVIRONMENT): Updated. + +2004-05-28 Akihiro Sagawa + + * Makefile.in (CPPFLAGS): Define. + (MDEFINES): Add CPPFLAGS. + +2004-05-27 Werner LEMBERG + + * arch/misc/Makefile.sub (shdeps.sed): Use $(srcdir). + +2004-05-26 Niklas Edmundsson + + Fix problems with `friend name injections'. + + * src/preproc/eqn/box.h (make_mark_box, make_lineup_box, + make_script_box), src/roff/troff/div.h (end_diversions), + src/roff/troff/env.h (title), input.cpp (process_input_stack): Undo + change 2004-04-08. + +2004-05-25 Bernd Warken + + * src/preproc/pic/pic.man, doc/pic.ms: Add example for `command'. + +2004-05-25 Werner LEMBERG + + * src/libs/libgroff/cset.cpp, src/libs/libgroff/lf.cpp, + src/libs/libgroff/color.cpp: Include lib.h. + +2004-05-25 Paul Eggert + + * PROBLEMS: Update documentation for problems with Sun C++ 5.0 + through Forte 6u1, and for how to get GNU make on Solaris. + +2004-05-24 Werner LEMBERG + + * PROBLEMS: Document problems with gcc 3.4.0 on Sun. Reported + by Paul Eggert. + +2004-05-15 Keith Marshall + + * arch/misc/Makefile.sub (shdeps.sed): Don't use `$<' in explicit + rule. + +2004-05-14 Werner LEMBERG + + * REVISION: Set to 2. + + * aclocal.m4 (GROFF_STDINT_H): Removed. + (GROFF_INTTYPES_H): Define HAVE_CC_INTTYPES_H. + + * configure.ac: Updated. + * configure, src/include/config.hin: Regenerated. + + * src/libs/libgroff/tmpname.cpp: Don't include stdint.h but + inttypes.h conditionally. + +2004-05-13 Werner LEMBERG + +Version 1.19.1 released +======================= + +2004-05-10 Stephen Gildea + + * src/preproc/refer/label.y (same_author_last_name, + same_author_name): Handle empty sort keys. + +2004-05-10 Werner LEMBERG + + * NEWS, README, TODO, PROJECTS, PROBLEMS, MANIFEST, doc/webpage.ms, + tmac/TODO: Updated. + + * tmac/doc-syms (doc-str-Lb-libposix, doc-str-Lb-libpthread, + doc-str-Lb-librt): Reset font. + (Lb): Rename `doc-str-Lb' to `doc-str-Lb1'. + Provide `doc-str-Lb' to reset font. + * tmac/groff_mdoc.man: Updated. + +2004-05-08 Jan Schaumann + + * src/preproc/html/pre-html.cpp (make_message): Make it work for + snprintf versions which don't conform to ANSI C 99 (this is, + counting the string's trailing null byte in the return value). + +2004-05-07 Keith Marshall + + * src/roff/troff/node.cpp (suppress_node::tprint): Don't expect + that all implementations of sprintf handle null pointers correctly. + +2004-05-04 Werner LEMBERG + + * NEWS, man/groff_diff.man, man/groff.man, doc/groff.texinfo: + Document `.U' register. + + * src/roff/troff/env.cpp (environment::mark_last_line) + [WIDOW_CONTROL]: Fix scope of `p' for new C++ compilers. + +2004-05-04 Larry Kollar + + New read-only register `.U'; it returns 1 in safer mode and 0 + otherwise. + + * src/roff/troff/input.cpp (init_input_requests): Implement `.U' + register. + +2004-05-03 Werner LEMBERG + + * install-sh, mkinstalldirs: New versions; taken from texinfo CVS. + +2004-04-17 Werner LEMBERG + + * src/include/font.h (font): Use `int' for ch_index. + * src/libs/libgroff/font.cpp (font::alloc_ch_index, + font::compact): Updated. + + * src/roff/groff/pipeline.c (run_pipeline) [_WIN32]: Fix compiler + warnings. + + * src/roff/troff/div.cpp (begin_page), src/roff/troff/env.cpp + (hyphen_word): Fix compiler warnings. + * src/roff/troff/input.cpp (get_char_for_escape_name): Return + `char'. + Update all callers. + (get_delim_number, get_line_arg): Change second argument type to + `unsigned char'. + (macro_header::copy, token::next, do_define_string, + do_define_character, substring_request, asciify_macro, + unformat_macro, read_size, non_interpreted_node::interpret, + while_request, main: Fix compiler warnings. + (read_color_draw_node): Initialize `col'. + + * src/preproc/tbl/table.cpp (horizontal_span, table_entry): Make + `start_col' and `end_col' of type `int'. + (vertical_rule): Make `col' of type `int'. + + * src/preproc/grn/hdb.cpp (DBRead): Protect call to getc with check + for EOF. + + * src/preproc/refer/label.y (uppercase_array, lowercase_array): + New arrays. + (format_serial): Use them to remove dependency on ASCII. + + * src/devices/grops/ps.cpp (ps_printer::define_encoding): Fix + compiler warning. + * src/devices/grops/psrm.cpp (resource_manager::supply_resource): + Ditto. + + * src/devices/grotty/tty.cpp (tty_font::load_tty_font): Fix + compiler warnings. + (glyph): Change type of `hpos' to `int'. + + * src/devices/lbp/lbp.cpp (strsep): Removed. Unused. + * src/devices/lbp/lbp.h (splinerel): Fix compiler warnings. + + * src/utils/tfmtodit.cpp (gf::load): Fix compiler warnings. + + * src/utils/pfbtops/pfbtops.c (get_text): Fix compiler warning. + +2004-04-16 Werner LEMBERG + + * src/devices/grolbp/lbp.h, src/preproc/grn/gprint.h, + src/preproc/grn/hgraph.cpp, src/preproc/grn/hpoint.cpp, + src/preproc/html/pushback.cpp, src/preproc/html/pushback.h: Use + `double' instead of `float' everywhere. + * src/preproc/grn/main.cpp: Use `double' instead of `float' + everywhere. + (main): Add return value. + * src/preproc/grn/hdb.cpp: Use `double' instead of `float' + everywhere. + Update all user functions. + + * src/include/search.h, src/include/ptable.h, src/include/printer.h, + src/preproc/eqn/box.h, src/preproc/pic/object.h, + src/preproc/refer/refer.h, src/preproc/tbl/table.h, + src/preproc/tbl/table.cpp, src/roff/troff/env.h, + src/roff/troff/div.h, src/roff/troff/token.h, src/roff/troff/node.h, + src/roff/troff/input.cpp, src/roff/troff/request.h, + src/roff/troff/node.cpp: Don't mix `struct' and `class' in forward + declarations. + + * src/utils/indxbib/signal.c: Include stdlib.h. + +2004-04-14 Keith Marshall + + * tmac/s.tmac (@init, RP): Allow initialization of the PO register + before the first page. + +2004-04-14 Thomas Klausner + + * tmac/doc-common (doc-volume-as-*): Use lowercase names. + (doc-operating-system-*): Updated. + * tmac/doc-syms (doc-str-St-*): Various small fixes. + (doc-str-Lb-*): Add more library names. + +2004-04-10 Art Haas + + * src/utils/hpftodit/hpuni.cpp (hp_msl_to_unicode_list): Don't + use anonymous type. + +2004-04-09 Art Haas + + * src/utils/tfmtodit.cpp (lig_chars): Don't use anonymous type. + +2004-04-09 Keith Marshall + + * arch/misc/shdeps.sh: Generate better comment for sed script. + +2004-04-08 Art Haas + + * src/libs/libgroff/glyphuni.cpp (glyph_to_unicode_list), + src/libs/libgroff/uniglyph.cpp (unicode_to_glyph_list), + src/libs/libgroff/uniuni.cpp (unicode_decompose_list), + src/preproc/eqn/box.cpp (param_table), src/preproc/grn/hgraph.cpp + (polyfill), src/preproc/grn/main.cpp (polyfill), + src/preproc/refer/command.cpp (command_table), + src/utils/tfmtodit.cpp (lig_table): Don't use anonymous types (which + gcc 3.5 doesn't like). + +2004-04-08 Werner LEMBERG + + Removing many compiler warnings. groff should now compile with + a C++ compiler used for C files also. [Simple variable renamings + to avoid shadowing aren't logged in detail.] + + * src/devices/grodvi/dvi.cpp: Some local variable renamings. + (draw_dvi_printer::draw) ['c']: Enclose in block. + + * src/devices/grohtml/post-html.cpp: Some local variable renamings. + (page::add_line): Fix typos. + * src/devices/grohtml/html-text.cpp: Some local variable renamings. + + * src/devices/grolbp/lbp.cpp: Don't define _GNU_SOURCE. + Some local variable renamings. + * src/devices/grolbp/lbp.h: Some local variable renamings. + + * src/devices/grolj4/lj4.cpp, src/devices/grotty/tty.cpp: Some local + variable renamings. + + * src/libs/libbib/index.cpp (index_search_item_iterator::get_tag): + Remove redundant local variable declaration. + * src/libs/libbib/map.c (mapread, unmap): Don't use K&R style. + Don't use `caddr_t' but `void *'. + Enclose functions with `extern "C"' for C++. + + * src/libs/libdriver/input.cpp (remember_filename, + remember_source_filename): Use cast for string constant. + + * src/libs/libgroff/font.cpp, src/libs/libgroff/fontfile.cpp, + src/libs/libgroff/nametoindex.cpp, src/libs/libgroff/paper.cpp, + src/libs/libgroff/geometry.cpp: Some local variable renamings. + * src/libs/libgroff/iftoa.c, src/libs/libgroff/itoa.c: Don't use K&R + style. + Enclose functions with `extern "C"' for C++. + * src/libs/libgroff/quotearg.c (TRUE,FALSE): Define as macros. + (needs_quoting): Return `int'. + (quote_arg): Add proper casts to malloc and realloc. + * src/libs/libgroff/spawnvp.c: Compile code only for MS-DOS and + various MS Windows environments. + (spawnvp_wrapper): Add proper cast to malloc. + + * src/preproc/eqn/box.h: Remove redundant declarations of + `make_script_box', `make_mark_box' and `make_lineup_box'. + * src/preproc/eqn/eqn.y: Remove redundant declaration of `strsave'. + * src/preproc/eqn/script.cpp, src/preproc/eqn/pile.cpp: Some local + variable renamings. + + * src/preproc/grn/hpoint.cpp: Some local variable renamings. + * src/preproc/grn/hgraph.cpp: Some local variable renamings. + (dx, dy): Renamed functions to... + (deltax, deltay): This. + * src/preproc/grn/main.cpp: Some local variable renamings. + (deffont): Add `const'. + (initpic, conv): Use cast for string constant. + + * src/preproc/html/pre-html.cpp: Some local variable renamings. + (makeFileName, alterDeviceTo, addZ): Use cast for string constant. + (char_buffer::run_output_filter): Second argument is unused. + * src/preproc/html/pushback.cpp: Some local variable renamings. + + * src/preproc/pic/pic.y: Remove redundant declaration of `do_copy'. + * src/preproc/pic/object.cpp: Some local variable renamings. + + * src/preproc/refer/label.y (lookup_label): Remove redundant + declaration of local variable. + + * src/preproc/soelim.cpp: Remove redundant declaration of + `interpret_lf_args'. + + * src/preproc/tbl/main.cpp: Some local variable renamings. + + * src/roff/groff/groff.cpp (main): Use cast for string constant. + * src/roff/groff/pipeline.c: Enclose declarations of `error', + `c_fatal', and `i_to_a' with `extern "C"' for C++. + Don't use C++-style comments. + + * src/roff/troff/env.h: Remove redundant declaration of `title'. + * src/roff/troff/node.h, src/roff/troff/env.cpp, + src/roff/troff/div.cpp, src/roff/troff/node.cpp: Some local variable + renamings. + * src/roff/troff/div.h: Remove redundant declaration of + `end_diversions'. + * src/roff/troff/troff.h: Remove redundant declaration of + `cleanup_and_exit' + * src/roff/troff/input.cpp: Remove redundant declaration of + `handle_first_page_transition' and `process_input_stack'. + + * src/utils/hpftodit.cpp: Some local variable renamings. + + * src/utils/indxbib/signal.c: Enclose functions with `extern "C"' + for C++. + Don't define RETSIGTYPE. + * src/utils/indxbib/indxbib.cpp: Some local variable renamings. + + * src/utils/pfbtops/pfbtops.cpp: Don't use K&R style. + (error): Use `const' in argument. + (main): Remove redundant declaration of `optind'. + Move declaration of `Version_string' to top-level. + + * PROBLEMS: Document difficulties compiling signal.c if a C++ + compiler is used for C. + +2004-04-07 Werner LEMBERG + + * Makefile.sub (DISTCLEANFILES): Add `test-groff'. + +2004-04-06 Keith Marshall + + Make scripts like nroff.sh and neqn.sh portable across various + (Unix-like) shell implementations from Cygwin, MSYS, etc., which use + non-POSIX path separators. The idea is to extend those scripts to + decide at run-time (of the script) which path separator to use. + + * arch/misc/Makefile.sub: New file. + * arch/misc/shdeps.sh: New file, generating OS dependency fixups. + This script handles @GROFF_BIN_PATH_SETUP@, replacing it with + a proper definition of the variable `GROFF_RUNTIME'. + + * Makefile.in (SH_DEPS_SED_SCRIPT): New variable. + (MDEFINES): Add SH_DEPS_SED_SCRIPT. + (PROGDEPDIRS): New variable. + `FORCE' it. + (PROGDIRS): Add PROGDEPDIRS. + + * src/preproc/eqn/Makefile.sub (neqn): Call SH_DEPS_SED_SCRIPT. + Don't substitute @SEP@ and @BINDIR@. + * src/preproc/eqn/neqn.sh: Use @GROFF_BIN_PATH_SETUP@. + (PATH): Use GROFF_RUNTIME. + + * src/roff/nroff/Makefile.sub (nroff): Call SH_DEPS_SED_SCRIPT. + Don't substitute @SEP@ and @BINDIR@. + * src/roff/nroff/nroff.sh: Use @GROFF_BIN_PATH_SETUP@. + (PATH): Use GROFF_RUNTIME. + +2004-04-05 Keith Marshall + + * src/roff/nroff/nroff.sh: Implement work-around for sh.exe from + Cygwin which doesn't handle stderr correctly. + +2004-03-08 Werner LEMBERG + + * Makefile.comm (install_dev, uninstall_dev): Protect `for' loops + against empty argument. Problem reported by . + +2004-03-05 Keith Marshall + + * Makefile.in (SEP): Replaced with... + (RT_SEP, SH_SEP): Separators for the target platform's native path + separator and the build environment, respectively. + (fontpath, tmacpath): Use RT_SEP. + (MDEFINES): Updated. + + * doc/Makefile.sub (GROFF_BIN_PATH): Use SH_SEP. + * src/preproc/eqn/Makefile.sub (neqn): Use SH_SEP. + * src/roff/nroff/Makefile.sub (nroff): Use SH_SEP. + +2004-03-05 Werner LEMBERG + + * font/devlj4/Makefile.sub (LJ4RES): Set to 1200. This helps to + reduce alignment problems with newer printers which use built-in + TrueType fonts (instead of the older Intellifonts). The ideal + solution is to provide a second set of groff metric files, but this + is extremely time-consuming to produce, given that HP's metric + files are very rudimentary. + +2004-03-01 Werner LEMBERG + + * src/devices/grolj4/lj4.cpp (main): Fix argument of getopt_long. + s/operand/argument/ in error message. + +2004-03-01 Keith Marshall + + * src/roff/groff/groff.cpp (main): Don't allow option -o if -Thtml + is in use. + +2004-03-01 Antti Kantee + + * tmac/s.tmac (XE): Fix error message. + +2004-02-27 Jeff Conrad + + * src/include/nonposix.h (write, dup, dup2, close) [_MSC_VER]: + New macros. + + * src/roff/groff/pipeline.c: Declare strcasecmp. + (run_pipeline) [_WIN32]: Use function name variants which don't + start with `_'. + Fix stream handling. + +2004-02-27 Keith Marshall + + * src/include/nonposix.h: Fix declaration of `system_shell_name'. + Declare `spawnvp_wrapper' and macro definitions of spawnvp only + for platforms which use the native Win32 runtime libraries. + (FLUSH_INPUT_PIPE) [_UWIN]: Provide non-empty version. + + * src/libs/libgroff/quotearg.c (QUOTE_ARG_MALLOC_ERROR, + QUOTE_ARG_REALLOC_ERROR): Fix string. + + * src/preproc/html/pre-html.cpp: Remove declaration of + `spawnvp_wrapper'. + Don't use __MINGW32__. + s/DEBUG_FILE/DEBUG_FILE_DIR/. + (DEBUG_TEXT, DEBUG_NAME, DEBUG_FILE) [DEBUGGING]: New macros. + (OUTPUT_STREAM, PS_OUTPUT_STREAM, REGION_OUTPUT_STREAM): New macros. + (char_buffer::run_output_filter) [MAY_FORK_CHILD_PROCESS]: Fix + calls to `set_redirection' and `WAIT'. + [MAY_SPAWN_ASYNCHRONOUS_CHILD]: Remove unused variable `i' and `j'. + Fix calls to `set_redirection' and `save_and_redirect'. + (char_buffer::do_html, char_buffer::do_image) [DEBUGGING]: Fix calls + to `set_redirection' and `save_and_redirect'. + (usage): Fix message. + (makeTempFiles, main): Use `DEBUG_FILE'. + +2004-02-21 Werner LEMBERG + + * src/roff/troff/troff.h (WARN_TOTAL): Fix value. + +2004-02-21 Keith Marshall + + * src/libs/libgroff/quotearg.c: New file, providing proper argument + quoting for MSVC's spawn* and exec* functions. + * src/libs/libgroff/spawnvp.c: New file, providing a wrapper around + spawnvp with proper quoting for MSVC. + + * src/libs/libgroff/assert.cpp (program_name), + src/libs/libgroff/new.cpp (program_name): Declare as `extern "C"'. + * src/libs/libgroff/Makefile.sub (OBJS, CSRCS): Updated. + + * src/roff/troff/input.cpp (program_name): Declare as `extern "C"'. + + * src/include/error.h (program_name): Declare as `extern "C"'. + * src/include/nonposix.h [__MSDOS__ ...]: Handle spawnvp. + +2004-02-21 Jeff Conrad + + * src/preproc/html/pre-html.cpp [__CYGWIN__ ...]: Declare + spawnvp_wrapper. + [MAY_SPAWN_ASYNCHRONOUS_CHILD]: Declare i and j. + +2004-02-20 Jeff Conrad + + * src/roff/groff/pipeline.c (cmd) [__MSDOS__ || ...]: New global + variable. + (sbasename) [__MSDOS__ || ...]: New function. + (system_shell_name) [__MSDOS__ || ...]: Use a different, more + generic algorithm. + (system_shell_dash_c, is_system_shell) [__MSDOS__ || ...]: Updated. + (run_pipeline) [_WIN32]: Use _XXX variants for some macros instead + of XXX. + Use STDOUT_FILENO instead of hardcoded file handle. + (signal_catcher) [__MSDOS__]: Moved to non-_WIN32 section. + +2004-02-19 Werner LEMBERG + + * src/roff/troff/div.cpp: Include nonposix.h after troff.h to + avoid warnings w.r.t. redefinition of P_tmpdir for some compilers. + +2004-02-18 Werner LEMBERG + + * font/devlj4/Makefile.sub (DEVFILES): Updated to contain all + new font and mapping files. + +2004-02-18 Jeff Conrad + Keith Marshall + + * src/include/nonposix.h (FLUSH_INPUT_PIPE): New macro to empty + an input pipe. This is needed for the MSVC compiler to make troff's + `-o' option work. + + * src/roff/troff/div.cpp: Include nonposix.h. + (cleanup_and_exit): Call FLUSH_INPUT_PIPE. + +2004-02-17 Werner LEMBERG + + * font/devlj4/generate/special.awk: New script. + * font/devlj4/generate/Makefile (S): Use special.awk. + * font/devlj4/*: Regenerated, including the following new files: + Arial (AR, AB, AI, ABI), Times New Roman (TNRR, TNRB, TNRI, TNRBI), + MS Symbol (SYMBOL), Wingdings (WINGDINGS). + * NEWS: Document new lj4 fonts and revised hpftodit. + +2004-02-17 Paco Andrés Verdú + + * src/devices/grolbp/lbp.h (vmdvarc): Fix formatting string. + +2004-01-25 Werner LEMBERG + + * src/libs/libgroff/progname.cpp: Replaced with... + * src/libs/libgroff/progname.c: New file. + * src/libs/libgroff/Makefile.sub: Updated accordingly. + +2004-01-17 Werner LEMBERG + + * font/devlj4/generate/Makefile (SYMBOL): Use 9nb28703.tfm. + +2004-01-16 Jeff Conrad + + * font/devlj4/generate/wingdings.map, + font/devlj4/generate/symbol.map: Include unnamed glyphs. + Use groff glyph names where possible. + * src/devices/grolj4/lj4_font.man: Minor updates. + +2004-01-13 Werner LEMBERG + + * tmac/www.tmac (DC): Handle TTY devices. + + * doc/webpage.ms: Document viewCVS from ffii.org. + * NEWS, README: Updated. + + * src/roff/groff/groff.man: Mention lj4_font man page. + + * font/devlj4/generate/Makefile (SYMBOLMAP, WINGDINGSMAP): New + variables. + (FONTS): Add SYMBOL and WINGDINGS. + (SYMBOL, WINGDINGS): New targets. + +2004-01-13 Jeff Conrad + + * src/devices/grolj4/lj4_font.man: New man page. + * src/devices/grolj4/Makefile.sub (MAN5): New variable. + * src/devices/grolj4.man: Mention lj4_font man page. + + * src/utils/hpftodit/hpftodit.cpp (read_map): Handle line comments. + * src/utils/hpftodit/hpftodit.man: Document it. + (CW): New macro. + Remove details about fonts (which are now in lj4_font.man). + + * font/devlj4/generate/symbol.map, + font/devlj4/generate/wingdings.map: New files. + +2004-01-12 Werner LEMBERG + + * README: Mention ffii's viewcvs access. + +2004-01-09 Werner LEMBERG + + * font/devlj4/generate/special.map: Map MSL 228 to U+221F. + +2004-01-09 Jeff Conrad + + Revert most of the change from 2004-01-03 to better control used + symbol sets. + + * src/utils/hpftodit/hpftodit.cpp (symbol_set): New structure. + (text_symbol_sets, special_symbol_sets): New arrays. + (symbol_set_table): New global variable. + (read_symbol_sets): Use search order given in the text_symbol_sets + and special_symbol_sets arrays. If command line flag -a is not + given, search both arrays. + (output_charset): Require x_height_tag only for command line flag -i. + +2004-01-06 Werner LEMBERG + + Implement string-valued registers \n[.m] and \n[.M] to return the + name of the current drawing and background color, respectively. + + * src/roff/troff/symbol.h: Moved to... + * src/include/symbol.h: Here. + Small fixes to make it work outside of the `troff' directory. + * src/roff/troff/symbol.cpp: Moved to... + * src/libs/libgroff/symbol.cpp: Here. + Small fixes to make it work outside of the `troff' directory. + + * src/include/Makefile.sub (HDRS), src/libs/libgroff/Makefile.sub + (OBJS, CCSRCS), src/roff/troff/Makefile.sub (OBJS, CCSRCS, HDRS): + Updated. + + * src/include/color.h: Include symbol.h. + (color): Add new field `nm'. + * src/libs/libgroff/color.cpp (color::color): Updated. + + * src/roff/troff/dictionary.cpp, src/roff/troff/div.cpp, + src/roff/troff/node.cpp, src/roff/troff/number.cpp, + src/roff/troff/reg.cpp: Don't include symbol.h. + + * src/roff/troff/env.cpp: Don't include symbol.h. + (environment::get_glyph_color_string, + environment_get_fill_color_string): New member functions. + (init_env_requests): Handle `.m' and `.M' registers. + * src/roff/troff/input.cpp: Don't include symbol.h. + (default_symbol): Moved to symbol.cpp/symbol.h. + (do_glyph_color, do_fill_color, define_color): Pass symbol name + to color constructor. + * src/roff/troff/env.h: Updated. + + * NEWS, man/groff_diff.man, man/groff.man, doc/groff.texinfo: + Document new registers. + +2004-01-05 Werner LEMBERG + + * src/roff/troff/node.cpp (space_node::get_breakpoints, + space_node::nbreaks): Protect against zero `next' field. + +2004-01-03 Jeff Conrad + + In hpftodit, use the symbol sets offered in the TFM. + + * src/utils/hpftodit/hpftodit.cpp (NO_GLYPH): New constant. + (symbol_set, text_symbol_sets, special_symbol_sets, + symbol_set_table): Removed. + (get_printcode): Removed. + (read_symbol_sets): Initialize `symbol_set' field with + `NO_SYMBOL_SET'. + Simplify code to just use the `kind' value. + (output_charset): Improve output formatting. + (dump_symbols): Simplified. + +2004-01-02 Werner LEMBERG + + * font/devlj4/generate/text.map: Add more MSL numbers. + +2004-01-02 Jeff Conrad + + * src/utils/hpftodit/hpftodit.cpp (is_decomposed): New macro. + (text_symbol_sets): Add more symbol sets. + (debug_flag): New static variable (moved from `main'). + (get_printcode, show_symset): New functions. + (main): Remove `debug_flag'. + (output_charset): Use `show_symset'. + (dump_symbols): Use `show_symset'. + Print symsets for all glyphs. + (read_map): Actually call `unicode_to_ucode_make' but this time + correctly. + +2004-01-01 Werner LEMBERG + + * font/devlj4/generate/text.map, font/devlj4/generate/special.map: + Fix placement of comments. + +2004-01-01 Jeff Conrad + + * src/utils/hpftodit/hpftodit.cpp (main): Read map file also if + option `-d' is given. + (output_charset): Improve warning messages to give more information. + (dump_symbols): Make information more precise. + (usage): Updated. + (read_map): Don't call unicode_to_ucode_name; the glyph names must + appear as-is and shouldn't be decomposed. + +2003-12-31 Werner LEMBERG + + * src/utils/hpftodit/hpftodit.cpp (dump_tags): Handle posture_tag. + * font/devlj4/generate/Makefile (IFLAG): Updated to new units. + (FONTS): Add TrueType font families Arial and Times New Roman. + (TNRR, TNRB, TNRI, TNRBI, AR, AB, AI, ABI): New targets. + * font/devlj4/generate/text.map: Fix Unicode values of `fi' and + `fl'. + +2003-12-31 Jeff Conrad + + * test-groff.in (SEP): Quote value. + * src/roff/troff/node.cpp (suppress_node::tprint): Change type of + `tem' to `char*' to avoid deallocation of a pointer to a constant + object which some compilers don't like. + +2003-12-31 Werner LEMBERG + + * font/devlj4/generate (text.map, special.map): Rewritten to work + with the new hpftodit version. + +2003-12-30 Jeff Conrad + + * src/utils/hpftodit/hpftodit.cpp (output_charset): Emit HP symbol + set and 8bit character code for all glyphs also. + +2003-12-30 Werner LEMBERG + + * src/libs/libgroff/strcasecmp.c: Updated from gnulib. + +2003-12-29 Werner LEMBERG + + More fixes for MSVC compiler. + + * doc/Makefile.sub (GROFF_BIN_PATH): Use $(SEP). + + * src/include/nonposix.h (STDIN_FILENO, STDOUT_FILENO, + STDERR_FILENO) [_MSC_VER]: Define conditionally. + (getpid) [_MSC_VER]: Remove. + Include direct.h and process.h conditionally. + + * src/roff/troff/node.cpp (suppress_node::tprint): Don't use + parentheses for a_delete. + + * src/utils/lookbib/lookbib.cpp: Include nonposix.h. + + * test-groff: Replaced with... + * test-groff.in: This new template to handle path separator + properly. + + * configure.ac: Check for direct.h and process.h. + Generate test-groff script. + * configure, src/include/config.hin: Regenerated. + +2003-12-28 Werner LEMBERG + + Add integral extension glyph. + Add new option `-x' to afmtodit to suppress use of built-in AGL. + + * font/devhtml/R.proto, font/devutf8/R.proto: Add `u23AE'. + + * font/devps/generate/textmap: Provide entry for `integralex' to + override (old) PUA value of the AGL. + * font/devps/generate/Makefile (SS): Add afmtodit option `-x'. + * font/devps/*: Regenerated. + + * src/utils/afmtodit/afmtodit.pl: Add option `-x'. + * src/utils/afmtodit/afmtodit.man, NEWS: Updated. + +2003-12-27 Werner LEMBERG + + Add forgotten `coproduct' symbol (already available for DVI). + + * font/devhtml/R.proto, font/devps/generate/textmap, + font/devps/symbolmap, font/devutf8/R.proto, man/groff_char.man, + src/libs/libgroff/uniglyph.cc, src/libs/libgroff/glyphuni.cpp: Add + U+2210 (\[coproduct]). + +2003-12-26 Jeff Conrad + + hpftodit has been extended to handle TrueType metric files and + more glyphs. See hpftodit.man for more details. + + * src/utils/hpftodit/hpftodit.cpp: Include stdio.h, string.h, + ctype.h, and unicode.h. + s/msl/charcode/ everywhere since we now handle Unicode values also. + (equal, NO, YES, MSL, SYMSET, UNICODE, UNICODE): New macros. + Use it where appropriate. + (MULTIPLIER): Replaced with... + (multiplier): New global static variable. + (scale): Updated. + (tag_type): Add more TFM tags. + (tag_name): New array. + (ENUM_TYPE, FLOAT_TYPE): Removed. + (BYTE_TYPE): New value assigned. + (ASCII_TYPE, RATIONAL_TYPE): New enumeration values. + (text_symbol_sets, special_symbol_sets): Extended to cover more + sets. + (check_type): Add return value. + (check_units): Add parameters to get ppi and upem values. + Handle TrueType TFM data. + (output_font_name): New function. + (output_charset): Add parameter to handle TFM type. + Handle TrueType TFMs also. + (em_fract): New macro. + (dump_tags): Be much more verbose and handle more tags. + (dump_ascii, dump_symbol_sets, dump_symbols): New functions. + (hp_msl_to_ucode_name, unicode_to_ucode_name, is_uname): New + functions. + (read_map): Add parameter to handle TFM type. + Handle both MSL and Unicode mappings. + (main): Add two new command line options `-a' and `-q'. + Updated to make use of new functions. + (usage): Updated. + + * src/utils/hpftodit/hpuni.cpp: New file. + + * src/utils/hpftodit/Makefile.sub, src/utils/hpftodit/hpftodit.man: + Updated. + +2003-12-25 Werner LEMBERG + + * src/include/nonposix.h (read) [_MSC_VER]: Define. + +2003-12-24 Werner LEMBERG + + * src/utils/afmtodit/afmtodit.man: Some reformulations as suggested + by Michail Vidiassov . + +2003-12-20 Werner LEMBERG + + * font/devhtml/R.proto: Add u00{47,67}_0306, u00{53,73}_0327, + and u0049_0307. + Add missing latin-2 glyphs. + * font/devutf8/R.proto: Add missing latin-2 glyphs. + + * tmac/troffrc: Load `composite.tmac' earlier. + + * tmac/dvi.tmac, tmac/ps.tmac, tmac/lbp.tmac: Add u00{47,67}_0306, + u00{53,73}_0327, and u0049_0307. + * tmac/X.tmac: Add u00{47,67}_0306. + * tmac/tty-char.tmac: Use composite glyph names for readability. + + * NEWS: Updated. + + * src/include/unicode.h: Remove `extern' keywords. + +2003-12-20 Nilgün Belma Bugüner + + * tmac/latin5.tmac: New file. + +2003-12-19 Werner LEMBERG + + Add some glyphs needed for Turkish. + + * font/devutf8/R.proto: Add u00{47,67}_0306, u00{53,73}_0327, + and u0049_0307. + + * tmac/composite.tmac: Add `,' as a synonym for `ac' accent. + * tmac/tty-char.tmac: Add representations for u00{47,67}_0306, + u00{53,73}_0327, and u0049_0307. + +2003-12-18 Werner LEMBERG + + * src/devices/grops/ps.cc (ps_output::put_float): Revert change + from 2001-10-04. + Remove trailing zeros. + +2003-12-17 Werner LEMBERG + + Make \? transparent to end-of-sentence recognition. + + * src/roff/troff/input.cc (non_interpreted_node): Add + `ends_sentence' member function. + +2003-12-16 Werner LEMBERG + + * doc/groff.texinfo: Document `dt' request correctly. + Other minor typographical improvements. + +2003-12-10 Michail Vidiassov + + * src/utils/afmtodit/Makefile.sub (afmtodit): Fix typo. + +2003-12-10 Richard Stallman + + * LICENSE: Better wording. + +2003-12-09 Werner LEMBERG + + * aclocal.m4 (GROFF_BROKEN_SPOOLER_FLAGS): Set default value to 0. + * configure, NEWS: Updated. + +2003-12-08 Werner LEMBERG + + * FDL: Updated to version 1.2 (from www.gnu.org/copyleft). + +2003-12-07 Bernd Warken + + * LICENSE: Updated. + +2003-12-07 Werner LEMBERG + + * INSTALL: Improved. + +2003-12-05 Keith Marshall + + Use path separator character of target platform for compiled-in + default paths. + + * aclocal.m4 (GROFF_TARGET_PATH_SEPARATOR): New macro. + * configure.ac: Use GROFF_TARGET_PATH_SEPARATOR. + * configure: Regenerated. + * Makefile.in (SEP): Use GROFF_PATH_SEPARATOR. + +2003-12-05 Werner LEMBERG + + * src/include/nonposix.h (PATH_SEP_CHAR): New definition. + Replace `PATH_SEP[0]' with `PATH_SEP_CHAR' everywhere. + +2003-12-04 Bernd Warken + + * LICENSE: New file. + +2003-12-03 Werner LEMBERG + + * src/utils/afmtodit/afmtodit.pl: Comment out code which handles + ligatures present in AFM files since groff currently only + understands some standard ligatures and nothing else. + +2003-12-03 Jeff Conrad + + * src/roff/groff/groff.cpp (main): Don't run the spooler if + option -v is given. + + * src/roff/groff/pipeline.c (run_pipeline) [_WIN32]: Fix error + messages. + Close stdout copy. + Don't use Unix wait flags. + +2003-12-02 Werner LEMBERG + + * src/roff/troff/glyphuni.cpp, src/roff/troff/unicode.cpp, + src/roff/troff/unicode.h, src/roff/troff/uniglyph.cpp, + src/roff/troff/uniuni.cpp: Moved to... + * src/libs/libgroff/glyphuni.cpp, src/libs/libgroff/unicode.cpp, + src/libs/libgroff/unicode.h, src/libs/libgroff/uniglyph.cpp, + src/libs/libgroff/uniuni.cpp: Here. + + * src/include/Makefile.sub.old (HDRS), + src/libs/libgroff/Makefile.sub (OBJS, CCSRCS), + src/roff/troff/Makefile.sub (HDRS, PBJS, CCSRCS): Updated. + +2003-12-01 Keith Marshall + + * src/preproc/htlp/pre-html.cpp (__tmpfile): Renamed to + `DEBUG_FILE'. + Updated all users. + +2003-12-01 Werner LEMBERG + + * groff.texinfo: Document special behaviour of `.vs 0'. + Improve documentation of `cflags' request. + * NEWS: Updated. + +2003-11-29 Werner LEMBERG + + * font/devlj4/generate/Makefile (CORONET): Use correct TFM. + * font/devlj4/CORONET: Regenerated. + +2003-11-24 Werner LEMBERG + + * src/roff/troff/env.cpp (hyphen_trie::read_patterns_file): Fix loop + if processing hyphenation patterns in traditional mode. + Improve error messages. + +2003-11-20 Werner LEMBERG + + * src/roff/troff/node.cpp (troff_output_file::put_char_width, + troff_output_file::put_char): Fix type of local variable `c'. + +2003-11-19 Werner LEMBERG + + * src/roff/groff/pipeline.c (P): Removed. Updated all function + declarations. + (i_to_a): Removed. libgroff already provides this function. + (run_pipeline) [_WIN32]: Don't use itoa but i_to_a. + +2003-11-18 Keith Marshall + + * src/roff/groff/pipeline.c (xstrsignal): Fix usage of + HAVE_DECL_SYS_LIST. + +2003-11-17 Werner LEMBERG + + * COPYING: Use correct version. + +2003-11-11 Werner LEMBERG + + LynxOS 4.0.0 doesn't declare vfprintf. + + * configure.ac: Check for vfprintf. + * configure: Regenerated. + * src/include/lib.h: Handle `NEED_DECLARATION_VFPRINTF'. + * src/include/config.hin: Regenerated. + +2003-11-10 Werner LEMBERG + + LynxOS 4.0.0 has snprintf (without declaration) but no vsnprintf. + + * configure.ac: Check for vsnprintf. + * configure: Regenerated. + * src/include/lib.h: Handle `NEED_DECLARATION_VSNPRINTF' and + `HAVE_VSNPRINTF'. + * src/include/config.hin: Regenerated. + +2003-11-09 Werner LEMBERG + + * aclocal.m4: Updated syntax to autoconf 2.59. + (GROFF_HTML_PROGRAMS): Use AC_FOREACH. + Don't check for gsos2. + (GROFF_SRCDIR, GROFF_BUILDDIR): Removed. autoconf 2.59 provides + working abs_top_srcdir and abs_top_builddir. + + * configure.ac: Updated syntax to autoconf 2.59. + Don't call GROFF_SRCDIR and GROFF_BUILDDIR. + Replace call to AC_DECL_SYS_SIGLIST with call to AC_CHECK_DECLS. + * configure: Regenerated. + + * Makefile.in, doc/Makefile.in: s/@top_srcdir@/@abs_top_srcdir@/, + s/@groff_top_builddir@/@abs_top_builddir@/. + + * src/roff/groff/pipeline.c (xstrsignal): + s/SYS_SIGLIST_DECLARED/HAVE_DECL_SYS_SIGLIST/. + +2003-11-07 Werner LEMBERG + + * src/devices/grodvi/dvi.cpp (draw_dvi_printer::draw) ['a']: Always + make start angle smaller than end angle to circumvent a bug in tpic + handling of some versions of dvipdfm (and dvipdfmx). + +2003-10-30 Werner LEMBERG + + * src/devices/grops/grops.man: Improve section on creating EPS. + +2003-10-29 Werner LEMBERG + + * contrib/pic2graph/pic2graph.sh: Fix typo (-P-letter -> + -P-pletter). + +2003-10-28 Werner LEMBERG + + * doc/groff.texinfo: Fix documentation of `.if'. + +2003-10-27 Michail Vidiassov + + * src/utils/afmtodit/afmtodit.pl: Handle unmapped characters of + the form `uniXXXX' also. + +2003-10-27 Werner LEMBERG + + * contrib/eqn2graph/eqn2graph.sh, contrib/grap2graph/grap2graph.sh, + contrib/pic2graph/pic2graph.sh: Implement secure management of + temporary files. + Pass `-P-pletter' to groff to avoid data outside of the converted + area -- some versions of `convert' (for example 5.3.8) don't check + the bounding box of the image but always use a fixed image size + (letter paper format). + * contrib/eqn2graph/eqn2graph.man, contrib/grap2graph/grap2graph.man, + contrib/pic2graph/pic2graph.man: Updated. + + * src/roff/groff/groff.man: Document $TMP and $TEMP. + +2003-10-26 Werner LEMBERG + + * src/preproc/pic/troff.cpp (troff_output::simple_circle, + troff_output::simple_ellipse, troff_output::simple_arc, + troff_output::simple_line, troff_output::simple_spline, + troff_output::simple_polygon): Insert a space before arguments. + (troff_output::set_fill): Emit `\&' before `\D'Fg...' since the + latter doesn't produce a node, so the following `.sp -1' would do + the wrong thing. + Don't emit `.sp -1' after \M. This also doesn't produce a token + (and we don't have to care about compatibility mode). + (troff_output::set_color, troff_output::reset_color): Don't emit + `.sp -1' after \M and \m. + + * src/roff/troff/input.cpp (old_have_input): New global variable. + (input_stack::get): Handle `old_have_input'. + (process_input_stack) : Call + `trapping_blank_line' depending on `old_have_input', not + `have_input'. + +2003-10-20 Keith Marshall + + * src/libs/libgroff/tmpfile.cpp [__MSDOS__, _Win32] + (WIN32_TMPDIR_ENVVAR, MSDOS_TMPDIR_ENVVAR): New macros, providing + default directory names for temporary files. + [__MSDOS__, _Win32] (temp_init::temp_init): Use them. + + * src/roff/groff/pipeline.c [__MSDOS__]: Include stdlib.h. + [__MSDOS__] (run_pipeline): Honour environment variables. + Don't use `tmpnam' but `tempnam' to work around messy + implementation. + + * README.MinGW: New file. + +2003-10-16 Werner LEMBERG + + * src/preproc/html/pre-html.cpp (write_upto_newline): Don't use + `(*t)->next' without testing validity of `*t'. + (usage): Make it more readable. + +2003-10-16 Keith Marshall + + Make html device run under both MS-DOS and Win32. + + * src/preproc/html/pre-html.cpp (MAY_FORK_CHILD_PROCESS, + MAY_SPAWN_ASYNCHRONOUS_CHILD): New macros to control whether + spawn or fork+exec has to be used, and whether parent must sleep + until the child process terminates. Used in + `char_buffer::run_output_filter'. + (copyofstdoutfd): Removed. + (char_buffer): Replace `write_file_html' and `write_file_troff' + member functions with `emit_troff_output' and `run_output_filter'. + (DEVICE_FORMAT, HTML_OUTPUT_FILTER, IMAGE_OUTPUT_FILTER): New + macros. + (replaceFd): Replaced with... + (set_redirection): New auxiliary function. + (waitForChild): Replaced with... + (save_and_redirect): New auxiliary function for. + + (char_buffer::do_html, char_buffer::do_image): Simplified, using new + functions. + +2003-10-14 Keith Marshall + + * aclocal.m4 (GROFF_SYS_NERR): Check stdlib.h also. + (GROFF_LIBC): New function. + * configure.ac: Call GROFF_LIBC. + Check for `kill'. + * configure: Regenerated. + + * src/include/lib.h: Handle __MINGW32__. + * src/include/nonposix.h [_MSC_VER]: Handle __MINGW32__. + Add macro for `pipe'. + Define P_tmpdir. + + * src/roff/groff/pipeline.c (run_pipeline): Handle `no_pipe' + correctly. + + * src/utils/indxbib/signal.c (handle_fatal_signal) [!HAVE_KILL]: + Implement. + +2003-10-12 Werner LEMBERG + + * src/roff/groff/groff.cpp (help), src/devices/grops/ps.cpp (usage), + src/roff/troff/input.cc (usage): Updated. + + * NEWS, doc/groff.texinfo: Updated. + +2003-10-12 Peter Miller + + * src/libs/libgroff/searchpath.cpp + (search_path::open_file_cautious): New function which also handles + `-' as stdin and stdout depending on the access mode. + * src/include/searchpath.h (search_path): Updated. + + * src/devices/grops/ps.cpp (main): Handle new `-I' switch. + * src/devices/grops/ps.h: Include `searchpath.h'. + * src/devices/grops/psrm.cpp (resource_manager::supply_resource): + Open resource file with `include_search_path.open_file_cautious'. + * src/devices/grops/grops.man: Document new `-I' switch. + + * src/devices/grodvi/dvi.cpp (main), src/devices/grolbp/lbp.cpp + (main), src/devices/grolj4/lj4.cpp (main), + src/devices/grotty/tty.cpp (main): Ignore new `-I' switch. + + * src/preproc/soelim/soelim.cpp (include_list_length, include_list): + Replaced with... + (include_search_path): New global variable. + (include_path_append): Removed. + (main): Use `include_search_path.command_line_dir' to handle `-I'. + (do_file): Simplify, using new + `include_search_path.open_file_cautious'. + + * src/roff/groff/groff.cpp (print_commands): Accept file handle as + parameter. + (main): Pass arguments to `-I' to both troff and devices. + Improve handling of `-V'. + * src/roff/groff/groff.man: Document changes to -I and -V. + + * src/roff/troff/input.cpp (include_search_path): New global + variable. + (next_file, source, ps_bbox_request, transparent_file, + process_input_file): Use new + `include_search_path.open_file_cautious'. + (main) Handle `-I' switch. + * src/roff/troff/node.cpp (troff_output_file::really_copy_file): + Use new `include_search_path.open_file_cautious'. + * src/roff/troff/node.h: New extern symbol `include_search_path'. + * src/roff/troff/troff.man: Document new `-I' switch. + +2003-09-15 Ruslan Ermilov + + Support multiple calls of .Lb in LIBRARY section. + + * tmac/doc-common (doc-in-library-section): New register. + (doc-section-library): New string. + (Sh): Set `doc-in-library-section'. + (Rd): Updated. + * tmac/doc-syms (Lb): Insert breaks before and after arguments + if in LIBRARY section. + * tmac/doc.tmac (doc-save-global-vars): Updated. + * NEWS, tmac/groff_mdoc.man: Updated. + +2003-09-14 Ruslan Ermilov + + * tmac/doc-common (doc-default-operating-system): New variable. + (Os): Use it. + +2003-09-08 Werner LEMBERG + + * tmac/doc.tmac (doc-reset-reference): Handle data for `%I' also. + +2003-08-31 Werner LEMBERG + + * Makefile.comm: Use `test ... ||' in favor of `if test ...; then'. + (install_dev, uninstall_dev): Check whether $(DEVSCRIPTS) and + $(DEVFILES) are not empty. + * Makefile.in: Use `test ... ||' in favor of `if test ...; then'. + +2003-08-23 Stephen Gildea + + * src/preproc/refer/ref.cpp (reference::compute_sort_key): Always + insert SORT_SEP. With certain combinations of sort specifications, + refer sorted entries in the wrong order. In particular, entries + with a missing field should be sorted before all entries that + have that field, before refer looks to the next field. + +2003-08-23 Werner LEMBERG + + * src/utils/pfbtops/Makefile.sub (LINK.c): Define it so that the + g++ linker is used. Reported by Mark J. Reed + . + +2003-08-16 Heinz-Jürgen Oertel + + Add key character `x' to tbl which makes tbl call a user-defined + macro on a table cell. + + * src/preproc/tbl/table.h (entry_modifier): Add `macro'. + * src/preproc/tbl/table.cpp (block_entry::do_divert): Call + `set_modifier' after printing the compatibility request. + (set_modifier): Print call to `m->macro' if not empty. + * src/preproc/tbl/main.cpp (entry_format::debug_print): Handle + `macro'. + (process_format): Implement cases `x' and `X'. + * src/preproc/tbl/tbl.man, NEWS: Updated. + +2003-08-15 Werner LEMBERG + + * doc/groff.texinfo: Minor fixes. + +2003-08-09 Werner LEMBERG + + * tmac/an-old.tmac [cR]: Fix redefinition of `bp'. + +2003-08-07 Werner LEMBERG + + * doc/Makefile.sub: Not all shells expand wildcards in the `for' + argument list to nothing if there is no file to match. Use `ls' as + a protection, similar to autoconf. + + * Makefile.comm (install_dev, uninstall_dev): Protect `for' against + empty argument lists. + + * doc/groff.texinfo: Improve documentation how vertical spacing + and line breaks interact. + Other minor fixes. + + * tmac/www.tmac: Initialize `www-htmlimage-gap'. + +2003-08-03 Werner LEMBERG + + * NEWS, src/devices/grops/grops.man: -b16 is necessary to produce + EPS (using eps2eps or similar programs to compute the bounding box). + +2003-07-24 Werner LEMBERG + + * doc/groff.texinfo: Use the new @/ command to avoid overlong lines. + * doc/texinfo.tex: Updated from texinfo 4.6. + * README.CVS: From now on we need texinfo 4.6. + +2003-07-23 Werner LEMBERG + + Add requests `dei1' and `ami1' for completeness. + + * src/roff/troff/input.cc (calling_mode): Remove + CALLING_DISABLE_COMP. + (comp_mode): New enumeration. + (do_define_string, define_string, define_nocomp_string, + append_string, append_nocomp_string): Updated. + (do_define_macro): Add third parameter. + (define_macro, define_nocomp_macro, define_indirect_macro, + append_macro, append_nocomp_macro, append_indirect_macro): Updated. + (define_indirect_nocomp_macro, append_indirect_nocomp_macro): New + functions. + (ignore): Updated. + (init_input_requests): Add `dei1' and `ami1'. + + * tmac/trace.tmac: Handle de1 and am1. + (de): Improve tracing message. + (am): Add missing `do'. + (return): Use de1. + + * NEWS, man/groff_diff.man, man/groff.man, doc/groff.texinfo: + Document new requests. + +2003-07-22 Heinz-Jürgen Oertel + + Add option -G to .MPIMG to insert a gap between text and the image. + + * tmac/www.tmac (www-finish-left-po, www-finish-right-ll, + www-finish-left-ll): Updated. + (www-image-just, www-image-gap, www-htmlimage-gap): New variables. + (MPIMG): Make option -L and -R optional. + Implement option -G. + +2003-07-22 Gaius Mulley + + * src/devices/grohtml/post-html.cpp + (html_printer::do_file_components): Don't use `stdout' as lvalue + since it can be a macro. + +2003-07-22 Werner LEMBERG + + * src/libs/libgroff/strerror.c: Include errno.h to be in sync with + the corresponding test in aclocal.m4. + +2003-07-21 Werner LEMBERG + + * src/preproc/html/pre-html.cpp (TRANSPARENT): Don't use colour + names but RGB values directly. Otherwise pnmtopng depends on + an external file `rgb.txt' which maps colour names to values. + +2003-07-20 Werner LEMBERG + + * aclocal.m4 (GROFF_SYS_ERRLIST): Include stdlib.h for MinGW. + * configure, src/include/config.hin: Regenerated. + + * src/libs/libgroff/strerror.c: Include stdlib.h for MinGW. + +2003-07-19 Werner LEMBERG + + * PROBLEMS: Add solution for UTF-8 problem with hyphens. + +2003-07-18 Werner LEMBERG + + * *.man: Switch to non-compatibility mode temporarily if GNU + syntax extensions are used in the particular man page. + + * PROBLEMS: Add solutions for SGR problems. + +2003-07-17 Werner LEMBERG + + Don't ignore grotty's command line options if \X'tty: sgr ...' is + used to change the drawing scheme. + + * src/devives/grotty/tty.cpp (bold_flag_option, + underline_flag_option, italic_flag_option, reverse_flag_option, + bold_underline_mode_option): New global variables. + (update_options): New function. + (tty_printer::special): Call update_options. + (main): Don't set xxx_flag but xxx_flag_option, then call + update_options. + +2003-07-14 Werner LEMBERG + + Make grotty emit proper Unicode box drawing characters for -Tutf8. + + * src/devices/grotty/tty.cpp (START_LINE, END_LINE): New enum + values. + (hline_char, vline_char): New global variables. + (tty_printer::tty_printer): Initialize them. + (tty_printer::draw): Emit START_LINE and END_LINE flags for both + horizontal and vertical lines. + (crossings): New global array. + (tty_printer::end_page): Use it to determine the proper crossing + character for -Tutf8. + +2003-07-12 Werner LEMBERG + + * doc/Makefilesub (HTMLDOCFILESALL): New macro. + (HTMLDOCFILES): Revert to `pic.html'. + (CLEANADD, install_html, uninstall_sub): Use HTMLDOCFILESALL. + +2003-07-11 Werner LEMBERG + + * doc/pic.ms: Improve documentation of absolute coordinates. + Document absolute positioning of pictures. + + * NEWS: Add new pic capability. + +2003-07-09 Hartmut Henkel + + * src/libs/libgroff/geometry.cpp (check_output_arc_limits): + Rewritten. + +2003-07-07 Werner LEMBERG + + Implement support for dashed and dotted ellipses in pic. Based on + a patch from Hartmut Henkel . + + * src/preproc/pic/common.cpp (common_output::ellipse_arc, + common_output::dashed_ellipse, common_output::dotted_ellipse): New + functions. Ellipse arcs are approximated with circle arcs. + * src/preproc/pic/common.h (common_output): Updated. + * src/preproc/pic/tex.cpp (tex_output::ellipse): Use new ellipse + functions. + * src/preproc/pic/troff.cpp (simple_output::ellipse): Ditto. + + * src/preproc/pic/TODO, src/preproc/pic/pic.man: Updated. + +2003-07-06 Werner LEMBERG + + Make grotty work on platforms which have unsigned char as the + default for char. Based on a patch by Thomas Klausner + . + + * src/devices/grotty/tty.cpp (schar): New typedef. + Updated calls to declare_ptable and implement_ptable. + (glyph): Use schar for back_color_idx and fore_color_idx. + (tty_printer): Use schar for curr_fore_idx and curr_back_idx. + (tty_printer::tty_color, tty_printer::tty_printer, + tty_printer::color_to_idx, tty_printer::put_color): Updated. + +2003-07-06 Ruslan Ermilov + + * src/roff/nroff/nroff.sh: Add option -d for completeness. + * src/roff/nroff/nroff.man: Updated. + +2003-07-05 Werner LEMBERG + + * NEWS, tmac/groff_www.man: Updated. + * doc/Makefile.sub: Updated. + +2003-07-05 Gaius Mulley + + Implement support for multiple HTML output files. + + * src/preproc/html/pre-html.cpp (scanArguments): Dummy handling for + -j command line option. + + * src/devices/grohtml/post-html.cpp (job_name, multiple_files): New + global variables. + (file): New fields `new_output_file', `require_links', + `output_file_name'. + (file::file): Updated. + (files::set_file_name, files::set_links_required, + files::are_links_required, files::is_new_output_file, + files::file_name, files::next_file_name): New functions. + (header_desc): New fields `no_of_level_one_headings', + `header_filename'. + (header_desc::header_desc): Updated. + (header_desc::write_headings): Handle multiple files. + (html_printer::write_header): Save file name in which header occurs. + (html_printer::determine_header_level): Possibly split files on + level one headings. + (html_printer::do_links, html_printer::troff_tag): Updated. + (html_printer::insert_split_file, html_printer::do_job_name, + html_printer::emit_link, html_printer::write_navigation, + html_printer::do_file_components): New functions. + (html_printer::~html_printer): Handle multiple files. + (main): Handle command line option `-j'. + + * src/devices/grohtml/grohtml.man: Updated. + + * doc/Makefile.sub (pic.html), doc/Makefile.in (pic.html): New rule + which splits file. + + * tmac/www.tmac (JOBNAME): New macro. + * tmac/s.tmac (SH-NO-TAG): New macro. + (@SH): Call SH-NO-TAG. + (@NH): Updated. + +2003-07-05 Ruslan Ermilov + + * tmac/groff_mdoc.man: Improve documentation of punctuation + characters. + +2003-07-04 Ruslan Ermilov + + * tmac/doc.tmac (Bd): Change to doc-Li-font later. + +2003-07-03 Werner LEMBERG + + * tmac/an-old.tmac [cR]: Redefine `bp' to avoid empty lines. + +2003-07-01 Ruslan Ermilov + + * tmac/doc.tmac (doc-do-func, doc-do-func-args): Don't print a comma + after `/*' and `*/'. + Fix spacing. + (Fn, Fo): Reduce indentation in synopsis. + + * tmac/doc-common (doc-check-depth): New macro. + (doc-end-macro, Sh, Ss): Use it. + (Cd): Fix behaviour in synopsis. + (In): Make it parsed and callable. + If not in the synopsis, represent the C header file enclosed in + angle brackets. + (doc-str-Rv-std-suffix, doc-str-Rv-stds-suffix, doc-str-Rv-std0): + Use minus, not hyphen. + + * tmac/groff_mdoc.man: Updated. + +2003-07-01 Werner LEMBERG + + Integrated grap2graph, contributed by Eric S. Raymond. + + * contrib/grap2graph/{Makefile.sub, grap2graph.sh, grap2graph.man}: + New files. + * Makefile.in, NEWS, MANIFEST, contrib/eqn2graph.man, + contrib/pic2graph.man, src/roff/groff/groff.man: Updated. + +2003-07-01 Colin Watson + + * src/xditview/*.c: Add prototypes, fix return types, add includes. + Based on work by Fumitoshi UKAI . + +2003-06-31 Ruslan Ermilov + + * tmac/tty-char.tmac: Provide `lb', `rb', `lk', `rk', `lt', `rt'. + +2003-06-31 Werner LEMBERG + + * doc/Makefile.sub (CLEANADD): Remove all files created by + running `make groff.{pdf,dvi}'. + + * Makefile.sub (DISTCLEANFILES): Remove all non-source files from + src/xditview also. + +2003-06-30 Werner LEMBERG + + * Makefile.in (SHELL): Define as @SHELL@. + (mkinstalldirs): Use $(SHELL). + (MDEFINES): Add $(SHELL). + * Makefile.comm (SHELL): Removed. + +2003-06-29 Werner LEMBERG + + * tmac/s.tmac (De, Ds): New aliases for .DE and .DS, respectively. + The X11 documentation files use them. + * tmac/groff_ms.man, doc/groff.texinfo: Document them. + +2003-06-15 Robert Goulding + + * tmac/e.tmac (@C): Handle .ad also. + +2003-06-12 Werner LEMBERG + + * src/preproc/tbl/tbl.man: Document formatting of text blocks. + + * src/roff/troff/input.cc (token::next) : + Assign `n' even here. It is possible to construct a node + immediately following an escape character: + + .di xx + \?\\\?a + .br + .di + .xx + +2003-06-10 Werner LEMBERG + + * README.WIN32: Removed. + * MANIFEST: Updated. + +2003-06-07 Werner LEMBERG + + * src/roff/nroff/nroff.sh: Don't emit SGR for option -u. + +2003-06-05 Werner LEMBERG + + * src/preproc/pic/pic.y : Implement workaround for bug + in Compaq C++ V6.5-033 for Compaq Tru64 UNIX V5.1A (Rev. 1885). + +2003-06-03 Werner LEMBERG + + * src/preproc/grn/hdb.cpp (DBRead): Don't close file handle; this + is done by the calling function. + +2003-05-22 Ruslan Ermilov + + * tmac/X.tmac: Fix definition of `em'. + +2003-05-22 Werner LEMBERG + + * src/roff/troff/input.cc (return_macro_request): Fix detection of + argument. + +2003-05-18 Werner LEMBERG + + * tmac/doc.tmac (doc-tag-list): Force horizontal mode after tag + to make items work which consist only of a tag. + +2003-05-17 Werner LEMBERG + + * tmac/doc.tmac (doc-tag-list): Don't use \Z to assure that spaces + aren't stretched in a tag (this can fail with unformatted boxes). + Instead, insert a break and go back one line. + +2003-05-16 Werner LEMBERG + + * src/roff/troff/input.cc (return_macro_request): If called with + argument pop macro twice. We need this to trace `return'. + + * tmac/trace.tmac: Handle `return'. + Fix typos. + + * NEWS, man/groff_diff.man, man/groff.man, doc/groff.texinfo: + Document. + +2003-05-15 Larry Kollar + + * tmac/groff_ms.man, doc/groff.texinfo: Improve documentation of + registers `FPS', `FVS', and `FPD'. + +2003-05-15 Werner LEMBERG + + * src/utils/pfbtops/pfbtops.c (get_text): Handle loop counter + correctly. + +2003-05-03 Ruslan Ermilov + + * tmac/groff_mdoc.man: Slight improvements. + +2003-05-03 Werner LEMBERG + + * tmac/doc-common (doc-header): Emit vertical space of 1v instead of + `doc-header-space' after header line if register `cR' is set. + +2003-05-02 Werner LEMBERG + + * TODO: Updated. + +2003-05-01 Ruslan Ermilov + + * tmac/doc-common (Nd): Use \[em]. + +2003-05-01 Werner LEMBERG + + * tmac/doc-ditroff, tmac/doc-nroff (doc-header-space, + doc-footer-space): Initialize to 0.5i. + (doc-setup-page-layout): Don't set doc-header-space and + doc-footer-space. + +2003-04-30 Werner LEMBERG + + * REVISION: Set to 1. + + * doc/pic.ms: Document possible problems with `figname'. + +2003-04-29 Werner LEMBERG + +Version 1.19 released +===================== + + * VERSION: Set to 1.19. + * REVISION: Set to 0. + * doc/groff.texinfo, doc/webpage.ms, NEWS: Updated. + + * src/devices/grohtml/post-html.cpp (html_printer::~html_printer): + Define charset as `US-ASCII' in html output. + + * tmac/www.tmac (ULE): Add missing scaling indicator. + + * win32-diffs: Removed. + +2003-04-28 Werner LEMBERG + + * doc/groff.texinfo: Document `dn' and `dl' registers if used with + `.da' and `.boxa'. + Document how to insert discardable whitespace with `.ss'. + +2003-04-27 Werner LEMBERG + + * src/preproc/pic/tex.cpp (tex_output::start_picture): Make code + work with plain TeX also. + + * src/preproc/pic/pic.man, doc/pic.ms: Fix TeX code example. + +2003-04-25 Gaius Mulley + + * src/devices/grohtml/post-html.cpp (html_printer::~html_printer): + Use a loose DTD. + +2003-04-24 Werner LEMBERG + + * src/preproc/pic/pic.man, doc/pic.ms: Explain how to get a + vbox with positive height and zero depth if in TeX mode. + + * NEWS: Document glyph name changes for grodvi and grolj4. + +2003-04-23 Werner LEMBERG + + * src/preproc/pic/tex.cpp (tex_output::start_picture): Fix TeX code. + * doc/pic.ms: Fixed. + +2003-04-21 Werner LEMBERG + + HP-UX 10.20 has `snprintf' but it isn't declared. + + * configure.ac: Add declaration test for snprintf. + * configure: Regenerated. + * src/include/lib.h: Handle `NEED_DECLARATION_SNPRINTF'. + * src/include/config.hin: Regenerated. + +2003-04-19 Werner LEMBERG + + Add keyword `figname' to pic, specifying the name of the picture + box in TeX mode. Based on a patch from William J Poser + . + + * src/preproc/pic/pic.y: New token `FIGNAME'. + (macro_name): New rule of type . + (placeless_element): Handle `FIGNAME'. + * src/preproc/pic/lex.cpp (lookup_keyword): Add `figname'. + * src/preproc/pic/main.cpp (graphname): New global variable. + (do_picture): Initialize `graphname'. + * src/preproc/pic/pic.h: Updated. + * src/preproc/pic/tex.cpp (tex_output::start_picture): Use + `graphname'. + Simplify TeX code. + (tex_output::text): Beautify output. + * src/preproc/pic/object.cpp (object_spec::~object_spec): Deallocate + `shaded' and `outlined' unconditionally. + * NEWS, src/preproc/pic/pic.man, doc/pic.ms: Updated. + Minor improvements. + + * PROBLEMS, README.CVS: Mention that bison version 1.875b or + greater is necessary. + +2003-04-17 Hartmut Henkel + + Add option -r to soelim to avoid emission of `.lf' lines. + Add option -t to produces TeX comment lines instead of `.lf' lines. + + * src/preproc/soelim/soelim.cpp: New global variables `raw_flag' + and `tex_flag'. + (usage): Updated. + (main): Handle `-r' and `-t'. + (set_location): Handle `raw_flag' and `tex_flag'. + * src/preproc/soelim/soelim.man, NEWS: Updated. + +2003-04-17 Werner LEMBERG + + * tmac/hyphenex.sh: Replaced with... + * tmac/hyphenex.pl: This perl script to avoid sed compatibility + nightmares. + + * aclocal.m4 (GROFF_HTML_PROGRAMS): Emit useful warning message + if --quiet is used for the configure script. + * configure: Regenerated. + +2003-04-16 Werner LEMBERG + + * src/devices/grohtml/post-html.cpp (text_glob::text_glob): + Add `const' to second argument. + (html_printer::add_table_end): Add `const' to argument. + * src/devices/grohtml/html-text.cpp (html_text::issue_tag): Add + `const' to arguments. + * src/devices/grohtml/html-text.h: Updated. + + * src/devices/grolbp/charset.h (symset): Use `unsigned char'. + * src/devices/grolbp/lbp.h (lbpputc): Use `unsigned char' for + argument. + + * src/devices/grotty/tty.cpp (tty_printer::make_rgb_string): Use + cast for integer constant. + + * src/preproc/html/pre-html.cpp (image_device): Use `const'. + (writeNbytes): Add `const' to first argument. + (writeString): Add `const' to argument. + (char_buffer::can_see): Add `const' to third argument. + * src/preproc/html/pushback.cpp (pushBackBuffer::isString): Add + `const' to argument. + * src/preproc/html/pushback.h: Updated. + + * src/preproc/soelim/soelim.cpp (include_list): Add `const'. + (include_path_append): Add `const' to argument. + (do_file): Updated. + + * src/roff/troff/uniglyph.cpp (unicode_to_glyph_list): Use `const' + for `value'. + (unicode_to_glyph_init::unicode_to_glyph_init): Updated. + * src/roff/troff/uniuni.cpp (unicode_decompose_list): Use `const' + for `value'. + (unicode_decompose_init::unicode_decompose_init): Updated. + * src/roff/troff/glyphuni.cpp (glyph_to_unicode_list): Use `const' + for `value'. + (glyph_to_unicode_init::glyph_to_unicode_init): Updated. + * src/roff/troff/input.cc (process_startup_file): Add `const' to + argument. + + * tmac/hyphenex.sh: Make script more portable by using a here + document. + +2003-04-15 Werner LEMBERG + + Renamed all `*.cc' files to `*.cpp'. + Updated all configuration files, makefiles, and documentation. + +2003-04-14 Werner LEMBERG + + * tmac/hyphenex.sh: Slight improvements. + +2003-04-13 Werner LEMBERG + + * font/devascii/R.proto, font/devcp1037/R.proto, + font/devlatin1/R.proto, font/devutf8/R.proto: Fill up remaining + character slots with unnamed glyphs. + + * tmac/an-old.tmac: Fix hyphenation value if `cR' is active. + (an-first): New global variable. + (an-header): Emit vertical space between multiple man pages. + +2003-04-11 Werner LEMBERG + + * doc/groff.texinfo, man/groff_out.man: \S only accepts integer + values. + +2003-04-10 Werner LEMBERG + + * PROBLEMS: Revised. + +2003-04-10 Bernd Warken + + * doc/webpage.ms: Improved. + +2003-04-09 Werner LEMBERG + + Add register \n[.height] which returns the value of \H. + Add register \n[.slant] which returns the value of \S. + + * src/roff/troff/env.cc (init_env_requests): Implement. + * NEWS, man/groff_diff.man, man/groff.man, doc/groff.texinfo: + Document. + +2003-04-08 Werner LEMBERG + + * tmac/html.tmac: Move some of the data into html-end.tmac. + Remove most of the character translations for eqn since html fonts + now cover those characters. + Load www.tmac. + * tmac/html-end.tmac: New file. + * tmac/troffrc: Load html.tmac not www.tmac for -Thtml. + * tmac/troffrc-end: Load html-end.tmac not html.tmac for -Thtml. + * tmac/Makefile.sub (NORMALFILES): Add html-end.tmac. + +2003-04-07 Werner LEMBERG + + * man/groff_out.man: Document negative values of `N' if -Thtml is + used. + +2003-04-06 Werner LEMBERG + + * Makefile.comm (depend.temp): Check location of YTABC. + +2003-04-05 Maciej W. Rozycki + + * doc/Makefile.in (TROFFBIN): New variable for troff + binary path. + (GROFFBIN): New variable for groff binary path. + (groff_bin_path): Rename to GROFF_BIN_PATH. + (TROFF): Use TROFFBIN. + (GROFF): Use GROFFBIN and GROFF_BIN_PATH. + * doc/Makefile.sub (GROFFBIN): New variable for groff + binary path. + (groff_bin_path): Rename to GROFF_BIN_PATH. + (GROFF): Use GROFFBIN and GROFF_BIN_PATH. + + * Makefile.comm (install_dev): Install scripts from DEVSCRIPTS + with INSTALL_SCRIPT. + (uninstall_dev): Uninstall scripts from DEVSCRIPTS. + * Makefile.dev (all): Depend on DEVSCRIPTS. + (install_dev): Likewise. + * font/devdvi/Makefile.sub (DEVSCRIPTS): New variable to hold + scripts. + * font/devps/Makefile.sub (DEVSCRIPTS): Likewise. + (DEVGENSCRIPTS): New variable to hold generated scripts. + +2003-04-05 Werner LEMBERG + + * src/libs/libdriver/input.cc (IntArray::operator[], + IntArray::get_data): Remove meaningless `const' in return value. + + * README.CVS: New file. + +2003-04-04 Werner LEMBERG + + Check for stdint.h in C++, not in C. + + * aclocal.m4 (GROFF_STDINT_H): New function, + * configure.ac: Check for stdint.h with GROFF_STDINT_H instead of + AC_CHECK_HEADERS. + * configure, src/include/config.hin: Regenerated. + * src/libs/libgroff/tmpname.cc: Use HAVE_CC_STDINT_H. + + + Fix handling of   in grohtml. To do this, troff emits `N' + with a negative value, representing the width of the unbreakable + space (only for -Thtml). grohtml then converts this back to +   and uses the value of N as its width. + + * src/roff/troff/node.cc (space_char_hmotion_node::tprint, + unbreakable_space_node::tprint): Emit `N-'. + * src/include/printer.h (printer::set_numbered_char): Make it + virtual. + Make members `font_table' and `nfonts' protected instead of private. + * src/devices/grohtml/post-html.cc + (html_printer::set_numbered_char): New member function. + + + * src/libs/libgroff/maxfilename.cc: + s/HAVE_LIMITS_H/HAVE_CC_LIMITS_H/. + + * src/roff/troff/node.cc (unbreakable_space_node::tprint): Don't + emit word marker. + +2003-04-03 Sergey A. Osokin + + * man/roff.man: Small fixes. + +2003-04-03 Werner LEMBERG + + Make groff independent from locale's numeric settings. + + * configure.ac: Check for `setlocale'. + * configure, src/include/config.hin: Regenerated. + + * src/include/lib.h: Handle HAVE_SETLOCALE. + + * src/devices/grodvi/dvi.cc (main), src/devices/grolj4/lj4.cc + (main), src/devices/grops/ps.cc (main), src/preproc/grn/main.cc + (main), src/preproc/pic/main.cc (main): Call `setlocale'. + + + * doc/groff.texinfo: Change dir category to `Typesetting'. + (Man font macros): Mention that there is no space between arguments + of .BI and friends. + + * src/libs/libdriver/printer.cc, src/devices/grotty/tty.cc + (*printer::change_color, *printer::change_fill_color): Add missing + `const'. + +2003-04-02 Werner LEMBERG + + * src/devices/grohtml/html-table.cc (html_table::emit_col, + html_table::is_gap): Compute table widths after converting border + positions to avoid rounding errors. + +2003-04-01 Werner LEMBERG + + * src/devices/grohtml/html-text.cc (html_text::do_space): Handle + `space_emitted' properly. + +2003-03-31 Werner LEMBERG + + * src/devices/grohtml/html-table.cc: Fix column width calculation. + (html_table::set_linelength): Don't add 1. + (html_table::add_indent): Don't subtract 1. + + * tmac/html.tmac: Set default page offset to zero. + +2003-03-30 Werner LEMBERG + + Make groff emit ` ' for `\ ' and `\~' if `-Thtml' is used. + + * src/roff/troff/node.cc (space_char_hmotion_node::tprint, + unbreakable_space_node::tprint): New functions. + (troff_output_file): Make space_char_hmotion_mode::tprint and + unbreakable_space_node::tprint to friends. + * src/roff/troff/node.h: Updated. + + * font/devhtml/R.proto: Add ` ' at position 0xA0 (as defined + in the HTML standard). + +2003-03-29 Werner LEMBERG + + * src/roff/troff/env.cc (point_size): Fix emission of html tag. + Otherwise, the following code + + .di xxx + .ps 10 + a + .br + .di + x\*[xxx] + + produces `x a' instead of `xa'. This is a temporary fix, disabling + font changes in diversions for -Thtml. + + * tmac/an-old.tmac (TH, SH): Use `HTML-TAG-NS' instead of + `HTML-TAG'. + (an-do-tag-html): Merge with ... + (an-do-tag): This macro. + Change code slightly to circumvent grohtml bug. + * tmac/troffrc-end: Define dummy for HTML-TAG-NS. + + * src/devices/grohtml/html-table.cc (html_table::emit_col, + html_table::is_gap): Round `width' properly. + + * tmac/html.tmac: Provide some default layout parameters for + grohtml. + + * font/devhtml/DESC.proto: Don't use discrete values for `sizes' + command. + +2003-03-28 Werner LEMBERG + + src/devices/grops/ps.cc (ps_printer::do_import): Fix error message. + +2003-03-27 Werner LEMBERG + + * tmac/an-old.tmac (BT): Don't call .tl if register `ps4html' is + defined. + +2003-03-20 Werner LEMBERG + + * src/roff/troff/env.cc (vertical_spacing): Allow zero value for + `.vs'. + * doc/groff.texinfo: Updated. + +2003-03-19 Werner LEMBERG + + * src/roff/troff/input.cc (process_input_stack) : Reset `have_input'. + +2003-03-18 Werner LEMBERG + + * src/roff/groff/groff.man: Mention groff_trace man page. + +2003-03-16 Werner LEMBERG + + * Makefile.in (LIBEXT): New variable to indicate the file extension + of library files. Computed heuristically from $(OBJEXT). + (MDEFINES): Add $(LIBEXT). + * Makefile.lib, Makefile.comm: Use it. + + * src/utils/pfbtops/pfbtops.c (get_text): New function. Split + overlong lines into smaller chunks. + (get_binary): New function. + (main): Use them. + * src/utils/pfbtops/pfbtops.man: Updated. + +2003-03-15 Colin Watson + + * src/roff/groff/groff.man: Minor syntax fix. + +2003-03-14 Egil Kvaleberg + + * src/devices/grops/ps.cc (ps_printer::media_set, + ps_printer::~ps_printer): Handle zero paper width and length. + +2003-03-13 Werner LEMBERG + + Add options -p and -l to grodvi. + + * src/devices/grodvi/dvi.cc: Include paper.h. + (landscape_flag, user_paper_length, user_paper_width): New global + variables. + (dvi_printer::begin_page): Emit `papersize' special. + Set color after initialization of `cur_h' and `cur_v'. + (main): Add options `-l' and `-p'. + * font/devdvi/Makefile.sub (DESC): Set `papersize'. + * src/devices/grodvi/grodvi.man, NEWS: Updated. + + * src/devices/grops/psrm.cc (valid_input_table): Fixed. + +2003-03-12 Werner LEMBERG + + * src/devices/grops/grops.man: Move documentation of .PSPIC to... + * man/groff_tmac.man: This man page. + * man/groff_font.man: Declare `paperwidth' and `paperlength' as + deprecated. + + * tmac/X.tmac: Don't load pspic.tmac. + +2003-03-11 Werner LEMBERG + + Make variable `pr' local to libdriver/input.cc. Based on a patch + by Bernd Warken . + + * src/include/driver.h (pr): Removed. + + * src/libs/libdriver/input.cc (pr): New global variable. + (do_file): Deallocate `pr'. + * src/libs/libdriver/printer.cc (pr): Removed. + + * src/devices/grodvi/dvi.cc (main), src/devices/grohtml/post-html.cc + (main), src/devices/grolbp/lbp.cc (main), src/devices/grolj4/lj4.cc + (main), src/devices/grops/ps.cc (main), src/devices/grotty/tty.cc + (main): Don't delete `pr'. + +2003-03-10 Werner LEMBERG + + * tmac/a4.tmac, tmac/composite.tmac: Use `.do'. + * tmac/papersize.tmac: New file. + * tmac/troffrc: Include `papersize.tmac'. + * tmac/Makefile.sub (NORMALFILES): Add `papersize.tmac'. + * tmac/an-old.tmac: Set LT to LL by default. + + * NEWS, MANIFEST, tmac/groff_man.man, man/groff_tmac.man, + doc/groff.texinfo: Updated. + + * src/libs/libgroff/paper.cc (add_iso_paper): Fix very embarrassing + bug which caused all odd iso papers to have wrong dimensions. + + * src/devices/grops/ps.cc (user_paper_width): New global variable. + (main) <'p'>: Set `user_paper_width' also. + (ps_printer::media_width, ps_printer::media_height): Use values + given with option `-p'. + +2003-03-09 Werner LEMBERG + + * src/include/nonposix.h: Provide default for SET_BINARY. + + * src/devices/grodvi/dvi.cc, src/devices/grolbp/lbp.cc, + src/devices/grolj4/lj4.cc, src/devices/grops/ps.cc: Call SET_BINARY + unconditionally. + + * src/utils/pfbtops/pfbtops.c: Call SET_BINARY unconditionally. + (main): Treat \r\n as \n. + +2003-03-08 Werner LEMBERG + + * tmac/an-old.tmac: Use register `HY' to control hyphenation. + * NEWS, tmac/groff_man.man, doc/groff.texinfo: Document it. + +2003-03-07 Werner LEMBERG + + Added support to access more than 256 glyphs in Type 1 fonts. + + * src/devices/grops/ps.cc (subencoding): New structure. + (style): Add `sub' field. + Updated all users. + (ps_printer): Add `subencodings' and `next_subencoding_index' fields. + Add `set_subencoding', `get_subfont' and `encode_subfont' member + functions. + Updated all users. + (ps_printer::set_char): Use `set_subencoding'. + (make_subencoding_name): New function. + (ps_printer::set_style): Handle case where `sty.sub' is not zero. + (ps_printer::~ps_printer): Emit subencoding definitions. + + * src/devices/grops/psrm.cc (valid_input_table): New array to + properly support EBCDIC. + (white_space): Add `\f'. + (ps_get_line): Change first argument to be of type `string &'. + Updated all callers. + This allows to get lines of arbitrary length. + Use `valid_input_table'. + Remove warning about non-conforming PS line length. This seems + not to be of great importance -- for example, dvips don't emit + a warning either. + (PS_LINE_MAX): Removed. + (matches_comment): Change first argument to be of type `string &'. + + * src/devices/grops/grops.man, src/devices/grops/TODO: Updated. + + * src/utils/afmtodit/afmtodit.pl (%unicode_decomposed, + %AGL_to_unicode, %default_ligatures): New hash tables. + Read all map entries. + Add unencoded characters. + Check for default ligatures if there are no `L' entries. + Print all kern entries. + Print all characters in charset. + * src/utils/afmtodit/afmtodit.man: Updated. + + * font/devps/*: Regerated all fonts. + + * tmac/latin[129].tmac, tmac/cp1047.tmac: Don't test for existence + of characters, just use `.trin'. Otherwise the mapping depends + on the font encoding. + * tmac/ps.tmac: Add `fi' and `fl'. + Improve `Fi' and `Fl'. + * tmac/X.tmac, tmac/lbp.tmac, tmac/tty.tmac: Improve `Fi' and `Fl'. + * tmac/Xps.tmac: Fix `em'. + + * NEWS: Updated. + +2003-03-04 Werner LEMBERG + + * src/roff/troff/input.cc (charinfo_to_node_list): Reset + `have_input'. + +2003-03-03 Werner LEMBERG + + * Makefile.sub (DISTCLEANFILES): Add gxditview._man. + + * font/devps/generate/textmap: Remove entry `similarequal'. + * font/devps/symbolmap: Updated. + +2003-03-02 Werner LEMBERG + + * src/libs/libgroff/font.cc (font::load): Fix error message for + bad character type. + + * src/devices/grops/grops.man: Improve documentation of the -b + flag. + + * tmac/tty.tmac: Load latin1.tmac for all TTY devices except + `ascii' and `cp1047'. + +2003-03-01 Werner LEMBERG + + Document composite glyphs and the `composite' request. + + * man/groff.man, man/groff_diff.man, doc/groff.texinfo: Do it. + +2003-02-28 Werner LEMBERG + + * font/devdvi/generate/ec.map: Add some more Unicode entities. + * font/devdvi/*EC: Updated. + + * tmac/composite.tmac, tmac/latin2.tmac, tmac/latin9.tmac: New files. + * tmac/latin1 (latin1-tr): Undo any previous mapping. + * tmac/troffrc: Load `composite.tmac'. + * tmac/Makefile.sub (NORMALFILES): Updated. + + * doc/groff.texinfo (Input Encodings): New section. + * NEWS: Updated. + +2003-02-27 Werner LEMBERG + + * doc/texinfo.tex: New version 2003-02-11.06. + + * tmac/doc-common (Dt): Don't emit warning for unknown section. + * tmac/groff_mdoc.man: Fix description of `Dt'. + +2003-02-26 Egil Kvaleberg + + * font/devps/prologue.ps: Fix for included Postscript that does + a setpagedevice -- which is now safely ignored. + + * NEWS: Updated. + + * src/devices/grops/ps.cc: Now sets the page size in the generated + document. This is done in two ways: Via a %%-comment for gv and + the like, and via a PageSize and setpagedevice for programs that + understands Postscript proper, like ps2pdf. + + * src/devices/grops/ps.h: New broken-flag to avoid page size + definition, if required. + + * src/devices/grops/grops.man: New broken-flag 16 mentioned. + + * doc/Makefile.in: Added -nosetpage flag (via @pnmtops_nosetpage@). + Not really necessary due to the fix in prologue.ps, but cleaner: + Such information does not belong in an .eps file. + + * doc/Makefile.sub: See doc/Makefile.in. + +2003-02-26 Ralph Corderoy + + * aclocal.m4 (GROFF_PNMTOPS_NOSETPAGE): Use P2 format for testing + instead of P1 since the latter is broken in some versions of netpbm. + * configure: Updated. + +2003-02-26 Larry Kollar + + Make man pages more customizable. + + * tmac/an-old.tmac (FT): New register holding footer distance from + bottom. + (HF): New string holding the default heading font. + (TH): Handle registers `IN' and `SN' set on the command line. + Use `FT'. + (PT, BT): New strings to customize header and footer lines. + (an-header, an-footer): Use them. + (SH, SS): Use `HF'. + * tmac/groff_man.man: Document changes. + + * doc/groff.texinfo: Document man changes. + Document Ultrix extensions of man. + +2003-02-26 Werner LEMBERG + + * src/roff/troff/input.cc (do_width, do_if_request): Reset + `have_input' after changing back to old environment. + + * src/devices/grolbp/lbp.cc (lbp_printer::set_line_thickness): Move + function up to be defined before first call. This is necessary to + avoid a compilation problem with Sun's WorkShop 6 C++ compiler. + + * src/utils/afmtodit/afmtodit.pl: Make script search for files in + the default font directory also. Based on a patch from James + J. Ramsey . + * src/utils/afmtodit/Makefile.sub (afmtodit): Handle @FONTDIR@. + * src/utils/afmtodit/afmtodit.man: Document it. + + * NEWS: Updated. + + * tmac/groff_man.man, doc/groff.texinfo: Many minor fixes. + +2003-02-25 Gaius Mulley + + * aclocal.m4 (GROFF_HTML_PROGRAMS): Add test for pnmtops. + (GROFF_PNMTOPS_NOSETPAGE): New macro. + * configure.ac: Use it. + * configure: Regenerated. + * Makefile.in: Updated. + + * tmac/Makefile.sub (NORMALFILES): Remove www.tmac. + (CLEANADD): Add www.tmac-sed. + (pnmtops_nosetpage): Define default. + (install_data): Handle www.tmac-sed and substitute + @PNMTOPS_NOSETPAGE@. + (stamp-sed): Add www.tmac. + * tmac/www.tmac: Rewritten, based on a patch by Bernd Warken. + It now breaks URLs at suitable places. + (www:substring_ok): New register set by... + (www:@test_substring): New macro. + (www:error): New alias to www-error. + (www:lenstr, www:splitstr, www:url_breaks, www:url_breaks_splitted): + New macros. + (URL): Use www:url_breaks. + (PIMG, MPIMG): Use @PNMTOPS_NOSETPAGE@. + (CDS, CDE): New macros. + +2003-02-25 Werner LEMBERG + + * src/devices/grops/ps.cc (ps_printer::define_encoding): Avoid + buffer overflow. + +2003-02-24 Werner LEMBERG + + Contrary to the PCL5 Developer's Guide, the ascenders in TFM files + can be negative also. + + * src/utils/hpftodit/hpftodit.cc (char_info): `ascent' must be + `int16'. + (read_char_table): Avoid negative ascenders. + (output_charset): Add cast. + * font/devlj4/*: Regenerated. + + Replace unnamed glyphs for DVI fonts with `uXXXX' glyph names where + possible. + + * font/devdvi/generate/{tc,texttt,ec,texmi,texsy,textex}.map: Do it. + * font/devdvi/generate/textex.map: Map glyph 23 to `u21C6' instead + of `<>'. + * font/devdvi/*: Regenerated. + + Map `la' and `ra' to U+27E8 and U+27E9. These two characters have + normal width, while the previously used characters (U+2329 and + U+232A) are classified as wide due to canonical equivalence with the + CJK punctuation characters U+3008 and U+3009. + + * font/devutf8/R.proto: Updated. + * src/roff/troff/uniglyph.cc, src/roff/troff/glyphuni.cc: Ditto. + + * man/groff_char.man: Simplify handling of table traps by + introducing `start block' and `end block' macros. + (Ns, Ne, 2s, 2e, Ds, De): New macros. + (DL): Make it work with Unix troff also. + Fix code values of `la' and `ra'. + + * tmac/dvi.tmac: Define `<>' for CW and CWI. + +2003-02-23 Gaius Mulley + + * src/devices/grohtml/post-html.cc (element_list::~element_list): + New destructor, fixing a major memory leak. + +2003-02-22 Werner LEMBERG + + * font/devhtml/R.proto, font/devutf8/R.proto: Flip `*f' and `+f' + to be in conformance with Unicode 3.0 and newer. + + * font/devlj4/generate/text.map: Add `Eu'. + * font/devlj4/generate/special.map: Flip `*e' and `+e'. + * font/devlj4/S: Regenerated. + + * man/groff_char.man: Completely rewritten. + + * doc/groff.texinfo: Fix description of request and macro arguments. + +2003-02-20 Gaius Mulley + + Valgrind fixes. + + * src/devices/grohtml/html-table.cc (html_table::~html_table): + Deallocate `columns' list. + * src/devices/grohtml/post-html.cc (char_block::~char_block): + New destructor. + (text_glob::text_glob_html, text_glob::text_glob_special, + text_glob::text_glob_line, text_glob::text_glob_auto_image, + text_glob::text_glob_tag): Avoid memory leaks. + (text_glob::remember_table): Free memory before reassigning. + +2003-02-19 Werner LEMBERG + + Add glyph `+e', greek lunate epsilon symbol, and `-h' (with the + alias `hbar'), the Planck constant over two pi. + + * font/devdvi/generate/texmi.map: Use `*e' for position 15 and + `+e' for position 34. + * font/devdvi/generate/texsy.map: Replace `DI' and `HE' with + `u2662' and `u2661'. + * font/devdvi/{MI,S}: Regenerated. + * font/devhtml/R.proto, font/devutf8/R.proto: Add `+e', `-h', `hbar'. + * font/devlbp/*: Add `hbar' alias. + * font/devlj4/generate/special.map: Ditto. + * font/devlj4/S: Regenerated. + * font/devps/generate/symbolchars: Add `+e'. + * font/devps/generate/textmap: Fix PS name for `-h'. + Add `hbar' alias. + * font/devps/symbolmap: Regenerated. + + * src/devices/grops/ps.cc (transform_fill): Removed since unused. + + * src/roff/troff/glyphuni.cc (glyph_to_unicode_list): Add `+e', + `-h', `hbar'. + * src/roff/troff/uniglyph.cc (unicode_to_glyph_list): Add `+e', + `-h'. + + * tmac/X.tmac, tmac/ps.tmac: Provide definitions for `-h' and + `hbar'. + * tmac/tty-char.tmac: Add `+e'. + +2003-02-17 Werner LEMBERG + + Another round trying to really fix problems with `have_input'. + + * src/roff/troff/input.cc (input_stack::get): Handle `have_input'. + (token::next) <'\n'>, <\'\n'>: Don't handle `have_input'. + + * src/devices/grotty/tty.cc (tty_printer::put_color): Fix color + handling if both foreground and background colors are default. + + * doc/groff.texinfo (Debugging): Document .lf differences to + AT&T troff. + +2003-02-16 Werner LEMBERG + + * src/devices/grotty/tty.cc (tty_printer::make_rgb_string): Avoid + null-bytes in created string. + + * src/roff/troff/input.cc (lookup_color, interpolate_macro, + alias_macro, lookup_request): Improve warning messages. + + * src/roff/troff/node.cc (suppress_node::tprint): Use `strsave', + not `strdup'. + Free `last_image_filename'. + + * src/preproc/html/pre-html.cc (char_block::char_block): Initialize + `buffer'. + (imageList::createPage, imageList::createImage): Use `free', not + `a_delete'. + (imageItem::~imageItem): Free `imageName'. + (addRegDef): Use `strsave', not `strdup'. + (get_resolution): Free `pathp'. + +2003-02-15 Werner LEMBERG + + * src/devices/grotty/tty.cc (tty_printer::tty_printer): Fix pointer + to `dummy'. + +2003-02-14 Werner LEMBERG + + Add memory management for colors to deallocate unnamed colors + properly. + + * src/include/color.h (color): New members `free_list' and `next'. + New member functions `new' and `delete'. + Add destructor. + * src/libs/libgroff/color.cc: Implement it. + + * src/libs/libgroff/font.cc (font::add_kern): Use integer cast + for array size of new operator. + + * src/libs/libdriver/input.cc (IntArray::operator[]): Remove + redundant comparison. + + * src/roff/troff/input.cc (word_space_node::reread, + hmotion_node::reread): Avoid warning about unused parameter. + (reset_output_registers): Remove redundant parameter. + (define_color): Undo change 2003-02-12. + + * src/roff/troff/reg.h: Updated. + + * src/roff/troff/node.cc (troff_output_file::really_print_line, + output_file::put_filename, real_output_file::really_put_filename, + ascii_output_file::really_print_line, + break_char_node::get_hyphen_list): Avoid warning about unused + parameter. + (suppress_node::tprint): Updated. + + * configure.ac: Check declaration for rand() and srand(). + * configure: Regenerated. + + * src/preproc/pic/pic.h: Declare fmod(), rand(), and srand() + conditionally. + * src/preproc/pic/pic.y: Remove declaration of fmod(), rand(), + and srand(). + + * src/preproc/eqn/delim.cc (delim_table): Add missing initializers + to avoid compiler warnings. + + * src/preproc/grn/hgraph.cc (HGPrintElt): Second parameter is + unused. + + * src/devices/grops/ps.cc (ps_printer::set_char): Last parameter + is unused. + * src/devices/grops/psrm.cc (skip_possible_newline): Remove first + (unused) parameter. + Updated all callers. + + * src/devices/grotty/tty.cc (tty_printer::set_char): Last parameter + is unused. + * src/devices/grodvi/dvi.cc (dvi_printer::set_char): Ditto. + * src/devices/grolj4/lj4.cc (lj4_printer::set_char): Ditto. + + * src/devices/grohtml/post-html.cc (html_printer::emit_line): + Parameter is unused. + (html_printer::add_table_end): Define parameter conditionally. + * src/devices/grohtml/output.cc (simple_output::special): Parameter + is unused. + + * src/devices/grolbp/lbp.cc: Define _GNU_SOURCE conditionally. + (lbp_printer::set_char): Last parameter is unused. + + * src/utils/indxbib/indxbib.cc (main): Remove redundant comparison. + +2003-02-13 Werner LEMBERG + + New commands \D'Fr ...', \D'Fc ...', etc. for orthogonality. + Make \D'f ...' move horizontally again for backwards compatibility. + Replace it with \D'Fg ...' where appropriate to avoid dependency + on horizontal resolution. + + * src/roff/troff/input.cc (do_get_long_name): New function. + (get_long_name): Call it. + + (read_draw_node): Handle `\D'Fx ...' by calling ... + (read_color_draw_node): New function. + + (read_rgb, read_cmy, read_cmyk, read_gray): New optional argument + `end'. + Pass it to `do_get_long_name' which is used instead of + `get_long_name'. + + * src/libs/libdriver/input.cc (color_from_Df_command): Remove + unnecessary value guard. + (parse_D_command) <'f'>: Add horizontal shift. + + * src/preproc/grn/hgraph.cc (HGPrintElt) : Use \D'Fg ...'. + * src/preproc/pic/troff.cc (troff_output::set_fill): Ditto. + (FILL_MAX): Removed. + + * NEWS, man/groff_diff.man, man/groff.man, doc/groff.texinfo: + Updated. + +2003-02-12 Werner LEMBERG + + * src/roff/troff/input.cc (do_name_test, do_expr_test, + do_zero_width): Push `\n' if closing delimiter is missing. + + (token::next) , <'\n'>, <\'\n'>: Reset `have_input'. + <'F'>: Make \F non-transparent at the beginning of line. + (process_input_stack) : Don't handle + `have_input'. + + (define_color): Free color in case of reassignment. + + * doc/groff.texinfo (@Defesc, @DefescList, @DefescItem, + @DefescListEnd): Use @Var, not @var. + Fix all calls. + + * src/preproc/grn/hgraph.cc (HGPrintElt): Fix typo. + + * src/preproc/pic/object.cc (object_spec::~object_spec): Free + `shaded' and `outlined' arrays. + (object_spec::object_spec): Initialize `shaded' and `outlined'. + (graphic_object::set_fill_color, graphic_object::set_outline_color): + Use strsave. + (closed_object::set_fill_color): Ditto. + * src/preproc/pic/troff.cc (troff_output::set_color): Use strsave + instead of strdup. + (troff_output::reset_color): Use a_delete instead of free. + * src/preproc/pic/main.cc (do_file): Free `out' in case of error. + +2003-02-11 Werner LEMBERG + + * doc/groff.texinfo: Improve documentation of `ad'. + Document that \D'f...' is dependent on the horizontal resolution. + * man/groff_diff.man: Improve documentation of \D'f...'. + + * src/preproc/grn/hgraph.cc (HGPrintElt) : Don't emit + compensating \h'...' for \D'f ...' since the latter no longer moves + current position. + * src/preproc/pic/troff.cc (troff_output::set_fill): Ditto. + +2003-02-10 Werner LEMBERG + + Improve error messages for `x F' (and `F') commands. + + * src/include/error.h: Add declaration for + `current_source_filename'. + * src/libs/libgroff/filename.cc: Add `current_source_filename'. + * src/libs/libgroff/error.cc (do_error_with_file_and_line): Add + parameter for source file string. + Updated all callers. + + * src/libs/libdriver/input.cc: Add `current_source_filename'. + (remember_source_filename): New function. + (parse_x_command <'F'>, do_file <'F'>): Use it. + +2003-02-09 Werner LEMBERG + + Make grotty not emit warnings about unknown colors more than + necessary. + + * src/devices/grotty/tty.cc: Include `ptable.h'. + (TTY_MAX_COLORS): Removed. + (DEFAULT_COLOR_IDX): Defined to -1. + (glyph): Change `back_color_idx' and `fore_color_idx' to `char'. + (tty_printer): Change `curr_back_idx' and `curr_fore_idx' to `char'. + Change `tty_colors' to be a ptable. + First arg of `put_color' is now `char'. + New functions `make_rgb_string' and `tty_color'. + (tty_printer::tty_printer): Use `tty_color'. + (tty_printer::color_to_idx): Return value is now `char'. + Use `tty_color'. + + * src/include/color.h (color): Add `print_color' member function. + * src/libs/libgroff/color.cc (color::print_color): Implement it. + +2003-02-08 Werner LEMBERG + + Valgrind fixes. + + * src/devices/grops/ps.cc (ps_printer::define_encoding): Close + encoding file. + + * src/include/ptable.h (PTABLE::~PTABLE, PTABLE::define): Always + assume that value has been allocated with `new[]', thus use + `a_delete' for deallocation. + + * src/libs/libdriver/input.cc (get_integer_arg, + get_possibly_int_args, parse_x_command, do_file): Use `a_delete' + where appropriate. + + * src/libs/libgroff/new.cc (delete) [!COOKIE_BUG]: Define. + * src/libs/libgroff/nametoindex.cc + (character_indexer::named_char_index): Use `new [1]'. + + * src/preproc/eqn/lex.cc (init_table, do_definition): Use `new + [1]'. + * src/preproc/eqn/text.cc (set_special_char_type): Ditto. + (split_text): Use `a_delete'. + + * src/preproc/pic/pic.y (define_label, define_variable): Use `new + [1]'. + + * src/roff/troff/env.cc (environment::choose_breakpoint): Avoid + harmless memory leak. + (hyphen_trie::read_patterns_file): Initialize `buf'. + * src/roff/troff/node.cc (troff_output_file::troff_output_file): + Initialize `current_fill_color'and `current_glyph_color'. + * src/roff/troff/glyphuni.cc + (glyph_to_unicode_init::glyph_to_unicode_init): Use `new [1]'. + * src/roff/troff/uniuni.cc + (unicode_decompose_init::unicode_decompose_init): Ditto. + * src/roff/troff/uniglyph.cc + (unicode_to_glyph_init::unicode_to_glyph_init): Ditto. + +2003-01-26 Werner LEMBERG + + * src/utils/indxbib/indxbib.cc (main) [__EMX__]: Check with + `access' before calling `unlink'. + (do_file): Handle __EMX__. + + * src/include/nonposix.h: Handle __EMX__. + + * Makefile.in (SEP): New variable; set to @PATH_SEPARATOR@. + (fontpath,tmacpath): Use it. + (MDEFINES): Add it. + Sorted alphabetically. + + * src/preproc/eqn/neqn.sh, src/roff/nroff/nroff.sh: Use + @SEP@. + * src/preproc/eqn/Makefile.sub, src/roff/nroff/Makefile.sub: Handle + @SEP@. + +2003-01-27 Werner LEMBERG + + * src/libs/libgroff/strcasecmp.c, src/libs/libgroff/strncasecmp.c: + New files, copied from gnulib. + * src/libs/libgroff/Makefile.sub (CSRCS): Add them. + * configure.ac: Updated. + * configure: Regenerated. + + * src/include/config.hin: Regenerated. + * src/include/lib.h [!HAVE_STRCASECMP]: Declare `strcasecmp'. + Don't define `strcasecmp' as `strcmp'. + [!HAVE_STRNCASECMP]: Declare `strncasecmp'. + Dont define `strncasecmp' as `strncmp'. + + * src/roff/groff/pipeline.c [!HAVE_STRCASECMP, !HAVE_STRNCASECMP]: + Removed. + +2003-01-26 Werner LEMBERG + + * src/utils/indxbib/indxbib.cc (main) [__EMX__]: Fix typo: + s/unline/unlink/. + +2003-01-25 Werner LEMBERG + + * doc/groff.texinfo (Ligatures and Kerning): Mention limitations. + +2003-01-24 Werner LEMBERG + + Add US-english hyphenation exceptions (converted from Barbara + Beeton's hyphenation exception log reports which appear irregularly + in TUGBoat). + + * tmac/hyphen.us: Updated to latest version. + * tmac/README: Updated. + * tmac/hyphenex.us, tmac/hyphenex.sh: New files. + * tmac/troffrc: Load `hyphenex.us'. + * tmac/Makefile.sub (NORMALFILES): Add `hyphenex.us'. + * doc/groff.texinfo: Updated. + +2003-01-23 Werner LEMBERG + + Improve hyphenation slightly. This is a first step in redesigning + the hyphenation algorithm to make it more flexible (e.g. allowing + kerns and ligatures between the hyphenation character and the + following character -- while not used normally in English, other + languages like German would benefit). + + * src/roff/troff/env.cc (environment::hyphenate_line): Use + assertion instead of if-clause. + Let `get_hyphen_list' return the number of involved characters in + the hyphenation pattern instead of computing it directly (which + often yields too small values). + * src/roff/troff/node.h (*::get_hyphen_list): Add second parameter. + * src/roff/troff/node.cc (*::get_hyphen_list): Handle new second + parameter. + +2003-01-22 Werner LEMBERG + + Fixing a bug which caused groff to hang if the hyphenation exception + dictionary tried to grow. + + * src/roff/troff/env.cc (hyphen_trie::insert_hyphenation, + hyphen_trie::read_patterns_file, do_hyphenation_patterns_file): Use + pointer to dictionary. + +2003-01-20 Werner LEMBERG + + * src/utils/afmtodit/afmtodit.pl: Add switch `-m' to suppress + negative left italic correction. + * src/utils/afmtodit/afmtodit.man: Document it. + + * font/devps/generate/Makefile (RFLAG): Add `-m'. + * font/devps/{AB,AR,BMB,BMR,CB,CR,EURO,HB,HR,HNB,HNR,NB,NR,PB,PR, + S,TB,TR,ZD,ZDR}: Regenerated with afmtodit options `-i 0 -m'. + + * NEWS: Updated. + +2003-01-16 Werner LEMBERG + + * NEWS: Updated. + +2003-01-16 Jörgen Grahn + + * src/preproc/refer/refer.man: Mention REFER environment variable. + +2003-01-05 Werner LEMBERG + + Similar to \[is], the square root glyph (\[sr]) and the square root + extension glyph (\[radicalex]) are now text symbols. The new + mathematical versions are called \[sqrt] and \[sqrtex], + respectively. + + * font/devX*/S: Regenerated. + * font/devdvi/generate/texex.map: Rename `sr[0123]' to `sqrt[0123]'. + * font/devdvi/generate/texsy.map: Rename `sr' to `sqrt'. + * font/devdvi/EX, font/devdvi/S: Regenerated. + * font/devhtml/R.proto, font/devutf8/R.proto: Add `sqrt'. + * font/devlj4/generate/special.map: Add `sqrt'. + * font/devlj4/S: Regenerated. + * font/devps/generate/textmap: Add `sqrt'. + * font/devps/S, font/devps/symbolmap: Regenerated. + + * src/preproc/eqn/sqrt.cc (SQRT_CHAR, RADICAL_EXTENSION_CHAR, + SQRT_CHAIN, BAR_CHAIN): Use `sqrt*' and `sqrtex*'. + * src/roff/troff/input.cc (init_charset_table): Make `sqrtex' + overlap horizontally. + + * tmac/X.tmac, tmac/ps.tmac, tmac/lj4.tmac: Add `sqrtex'. + * tmac/dvi.tmac: Add `sr', and `sqrtex'. + Fix `radicalex'. + + * doc/groff.texinfo, man/groff_diff.man: Document that `radicalex' + and `sqrtex' are overlapping glyphs. + +2003-01-04 Werner LEMBERG + + * font/devdvi/generate/texsy.map: Add `is'. + * font/devps/symbolmap: Regenerated. + * font/devdvi/*TC, MI, S: Regenerated. + + * tmac/dvi.tmac: Remove `is'. + +2003-01-03 Werner LEMBERG + + `is' is now a text symbol (only relevant for dvi). The math variant + can be accessed with `integral'. + + * font/devX*/S: Regenerated. + * font/devdvi/generate/texex.map: Remove `is'. + * font/devdvi/EX: Updated. + * font/devhtml/R.proto, font/devutf8/R.proto: Add `integral'. + * font/devlj4/generate/special.map: Ditto. + * font/devlj4/S: Regenerated. + * font/devps/generate/textmap: Add `integral'. + * font/devps/S: Regenerated. + + * tmac/dvi.tmac: Define `is'. + + * src/roff/troff/glyphuni.cc (glyph_to_unicode_list): Add `integral'. + + * src/preproc/tbl/main.cc (process_format): Fix error message. + +2003-01-02 Werner LEMBERG + + * font/devhtml/R.proto, font/devutf8/R.proto: Add `ne' and `nc'. + * font/devps/textmap: Fix entries for `ne' and `nc'. + * font/devps/symbolmap: Regenerated. + + * src/roff/troff/glyphuni.cc (glyph_to_unicode_list), + src/roff/troff/uniglyph.cc (unicode_to_glyph_list): Add `18', + `38', `58', `78', `-+', `|=', `nc', `ne'. + + * tmac/dvi.tmac: Add `nm', `ne', `nc'. + Use `schar' for `aq'. + * tmac/ps.tmac, tmac/X.tmac: Add `nc' and `ne'. + * tmac/ec.tmac: Add `SC' to special fonts for `CW' and `CWI'. + * tmac/tty.tmac: Add `ne'. + + * src/roff/troff/node.cc (make_glyph_node): Test with `get_macro' + for fallback glyphs. + +2002-12-29 Werner LEMBERG + + Add glyph `|='. + + * font/devX*/*: Regenerated. + * font/devdvi/generate/ec.map: Remove `eq'. + * font/devdvi/generate/texsy.map: Make `~=' the same as `~~'. + Assign `|=' to position 39. + * font/devdvi/*EC, S: Regenerated. + * font/devhtml/R.proto, font/devutf8/R.proto: Add `|='. + * font/devlj4/generate/special.map: Make `~=' the same as `~~'. + Assign `|=' to position 549. + * font/devps/generate/textmap, font/devps/enerate/symbolmap: Remove + `equalmath'. + Add `uni2243' for `|='. + + * tmac/ec.tmac: Add `eq'. + * tmac/dvi.tmac: Add `=~'. + * tmac/tty-char.tmac, tmac/ps.tmac, tmac/X.tmac, tmac/lbp.tmac: Add + `|='. + +2002-12-21 Werner LEMBERG + + * font/devdvi/generate/tc.map: Remove `**'. + * font/devdvi/*TC: Regenerated. + * font/devhtml/R.proto, font/devutf8/R.proto: Add `18', `38', `58', + `78', `<<', `>>'. + * font/devutf8/NOTES: Updated. + + * src/roff/troff/charinfo.h (charinfo): Add `setx_macro' function. + Don't give default parameter to `set_macro'. + * src/roff/troff/input.cc (do_define_character): Use `setx_macro' + instead of `set_macro'. + (charinfo::setx_macro): Implement it. + (charinfo::set_macro): Don't change `mode'. + + * tmac/tty.tmac: Add `18', `38', `58', `78', `<<', `>>'. + * tmac/ps.tmac, tmac/X.tmac: Add `<<', `>>'. + * tmac/dvi.tmac: Define `!=' with `.schar'. + +2002-12-20 Werner LEMBERG + + * font/devX*/S: Regenerated. + * font/devdvi/generate/ec.map: Remove `pl'. + * font/devdvi/generate/tc.map: Remove `mi', `14', `12', `34'. + * font/devdvi/*{TC,EC}: Regenerated. + * font/devhtml/R.proto: Add `-+'. + Remove double entries for `rk', `lk', `lt', `rt', `rb', `lb'. + * font/devlbp/*: Remove `or'. + * font/devlj4/generate/special.map: Remove `or'. + * font/devlj4/S: Regenerated. + * font/devps/generate/textmap: Add `fiveeighths', `oneeighth', + `seveneighths', `threeeighths'. + Remove `plusmath'. + Replace `minusplus' with `uni2213'. + * font/devps/symbolmap: Regenerated. + * font/devutf8/R.proto: Replace `shc' with unnamed glyph. + Add `-+'. + + * src/roff/troff/charinfo.h (charinfo): Add `is_normal' inline + function. + * src/roff/troff/node.cc (troff_output_file::put_char_width): + Call glyph_color and fill_color even if tcommand_flag isn't set. + (make_node, node::add_char): Check not ci->is_fallback but + ci->is_normal. + + * tmac/lj4.tmac, tmac/lbp.tmac: Define `or'. + * tmac/ec.tmac: Add .rchar entry for `f/'. + Don't remove `12', `14', `34'. + Define `pl' to be always roman. + * tmac/ps.tmac (ps-frac, ps-frac-mono): New macros. + Define `18', `38', `58', `78'. + * tmac/tty.tmac: Add `-+'. + * tmac/dvi.tmac: Define `f/'. + (dvi-frac): Use `f/'. + * tmac/X.tmac (X-frac, X-frac-mono): New macros. + Define `18', `38', `58', `78'. + +2002-12-15 Colin Watson + + * contrib/pic2graph/pic2graph.sh: Add missing `;;'. + +2002-12-10 Werner LEMBERG + + Add glyph `tno', a textual variant of `no'. + + * font/devX*/*: Regenerated. + * font/{devcp1047,devlatin1,devutf8,devhtml}/R.proto: Add `tno'. + * font/devdvi/generate/{tc.map: Replace `no' with `tno'. + * font/devdvi/generated/{texsy,textex}.map: Add `tno'. + * font/devdvi/*: Regenerated. + * font/devlbp/*: Add `tno'. + * font/devlj4/generate/tex.map: Replace `no' with `tno'. + * font/devlj4/*: Regenerated. + * font/devps/generate/textmap: Replace `no' with `tno'. + * font/devps/generate/symbolchars: Add `no'. + * font/devps/*: Regenerated. + + * src/roff/troff/glyphuni.cc (glyph_to_unicode_list): Add `tno'. + + * tmac/cp1047.tmac, tmac/latin1.tmac: Replace `no' with `tno'. + * tmac/tty-char.tmac: Add entry for `tno' and `3d'. + + * NEWS: Updated. + + * tmac/dvi.tmac: Replace most `\\' with `\E'. + Add definition for `sd'. + * tmac/X.tmac, tmac/ps.tmac: Replace most `\\' with `\E'. + + * tmac/eqnrc : Use `integral' instead of `is' glyph. + +2002-12-08 Werner LEMBERG + + * tmac/an-old.tmac (TH): Use integer value for `IN' if in nroff + mode to avoid rounding errors. + (an-do-tag, an-do-tag-html, RS, RE): Remove redundant `.br'. + + * src/roff/groff/groff.man, src/roff/nroff/nroff.man, + src/roff/troff/troff.man: Improve documentation of -T. + +2002-12-07 Jeff Conrad + + * src/roff/groff/pipeline.c: Don't define `const' for _WIN32. + (run_pipeline) [_WIN32]: Provide working function without `fork'. + +2002-12-06 Werner LEMBERG + + * font/devps/generate/freeeuro.sfd: Make dimensions of Euro.symbol + glyphs compatible to Adobe's Euro fonts (scaling them down a bit). + Scaling Euro.sansserif glyphs down to have the same height as + digits. + Removed unnecessary points; added some extrema. + + * font/devps/EURO, font/devps/freeeuro.afm, font/devps/freeeuro.pfa: + Regenerated. + +2002-12-04 Werner LEMBERG + + * font/devps/generate/freeeuro.sfd: Add glyphs `Euro.symbol.slanted' + and `Euro.symbol.bold.slanted'. + Improve some glyph offsets and widths. + * font/devps/EURO, font/devps/freeeuro.afm, font/devps/freeeuro.pfa: + Regenerated. + * font/devps/generate/Makefile (freeeuro.afm freeeuro.pfa): Fix + typo. + * font/devps/generate/sfdtopfa.pe: Generate PFA in current + directory. + + * tmac/europs.tmac: Updated to new glyph indices. + Use Euro.symbol for font family `A'. + + * doc/groff.texinfo: Minor improvements. + +2002-12-02 Werner LEMBERG + + * font/devdvi/generate.tc.map: s/%O/%0/. + * font/devdvi/*TC: Regenerated. + + * src/roff/troff/div.cc (init_div_requests): Sorted. + + * tmac/dvi.tmac: Remove `Ye'. + * tmac/ec.tmac: Remove `Ye'. + Add .rchar entry for `de'. + + * man/groff.man, man/groff_diff.man: Document register `.pe'. + * doc/groff.texinfo: Document registers `.pe', `.n', and `.w'. + * NEWS: Updated. + +2002-11-30 Werner LEMBERG + + Add PS font for various Euro glyphs. + + * font/devps/generate/freeeuro.sfd: New master font file for + pfaedit. + * font/devps/generate/sfdtopfa.pe: New conversion script for + pfaedit. + * font/devps/generate/Makefile (FONTS): Add `EURO'. + (EURO, freeeuro.afm, freeeuro.pfa): New rules. + * font/devps/freeeuro.pfa, font/devps/freeeuro.afm: Generated from + `freeeuro.sfd'. + * font/devps/EURO: Generated from `freeeuro.afm'. + * font/devps/download: Add `freeuro.pfa'. + * font/devps/Makefile.sub (NORMALFILES): Adde `EURO' and + `freeeuro.pfa'. + + * tmac/europs.tmac: New file. + * tmac/ps.tmac: Include `europs.tmac'. + * tmac/Makefile.sub (DISTFILES): Add `europs.tmac'. + +2002-11-29 Werner LEMBERG + + * font/devdvi/generate/texsy.map: Remove `lh' and `rh'. + * font/devdvi/S: Regenerated. + * font/devhtml/R.proto: Fix `CR' and `ci'. + Add `OK'. + * font/devps/generate/textmap: Fix `lh', `rh', and `sq'. + Remove `bs'. + * font/devps/symbolmap: Regenerated. + * font/devutf8/R.proto: Fix `CR' and `ci'. + Add `OK'. + * font/devutf8/NOTES: Updated. + + * src/roff/troff/uniglyph.cc (unicode_to_glyph_list): Fix `CR' and + `ci'. + Add `OK'. + * src/roff/troff/glyphuni.cc (glyph_to_unicode_list): Ditto. + + * tmac/dvi.tmac: Add `lh' and `rh'. + * tmac/Xps.tmac: Fix `lh' and `rh'. + * tmac/X.tmac: Add `OK'. + * tmac/lj4.tmac: Ditto. + +2002-11-24 Werner LEMBERG + + * font/devX*/S: Regenerated. + * font/devascii/R.proto, font/devcp1047/R.proto: Remove glyphs `lb', + `lc', `lf', `lk', `lt', `rb', `rc', `rf', `rk', and `rt'. + * font/devdvi/generate/texsy.map: Remove `or' glyph. + * font/devdvi/S: Regenerated. + * font/devhtml/R.proto, font/devutf8/R.proto: Add/fix glyphs + `parenlefttp', `parenleftex', `parenleftbt', `parenrighttp', + `parenrightex', `parenrightbt', `bracketlefttp', `bracketleftex', + `bracketleftbt', `bracketrighttp', `bracketrightex', + `bracketrightbt', `bracelefttp', `braceleftmid', `braceleftbt', + `braceex', `braceleftex', `bracerightex', `bracerighttp', + `bracerightmid', `bracerightbt', `lt', `lk', `lb', `rt', `rk', + `rb', and `bv'. + * src/roff/troff/glyphuni.cc, src/roff/troff/uniglyph.cc: Ditto. + * font/devutf8/NOTES: Updated. + * font/devlj4/generate/special.map: Add glyph `braceex'. + * font/devlj4/S: Regenerated. + + * tmac/tty-char.tmac: Add glyphs `lf', `rf', `lc', and `rc'. + +2002-11-14 Werner LEMBERG + + * src/roff/troff/uniglyph.cc (unicode_to_glyph_list): Add `va' + and `vA'. + Fix code for `an'. + * src/roff/troff/glyphuni.cc (glyph_to_unicode_list): Ditto. + + * doc/texinfo.tex: New version from texinfo 4.3. + * doc/groff.texinfo: Updated for texinfo 4.3. + Use @tie{} where appropriate. + * font/devdvi/generate/ec.map: Don't include `or' and `bv'. + * font/devdvi/generate/tc.map: Remove `rn'. + * font/devdvi/*TC, font/devdvi/*EC: Regenerated. + * font/devhtml/R.proto, font/devutf8/R.proto: Add `vA'. + Fix code for `an'. + * font/devX100/*, font/devX100-12/*, font/devX75/*, + font/devX75-12/*: Regenerated. + + * tmac/dvi.tmac: Add special fonts `SA' and `SB'. + Use .char (again) for `br', `ul', `rn', `or', and `ru'. + Improve definition of `an'. + * tmac/ps.tmac: Use .char (again) for `br', `ul', `rn', `or', and + `ru'. + * tmac/lj4.tmac: Use .char (again) for `br', `ul', `rn', and `ru'. + * tmac/X.tmac: Add definition for `or'. + * tmac/Xps.tmac: Undo change 2002-11-05. + * tmac/lbp.tmac: Add definitions for `br', `rn', `ul', and `ru'. + +2002-11-11 Werner LEMBERG + + * src/roff/troff/node.cc (troff_output_file::put_char): Always + call flush_tbuf. + +2002-11-10 Werner LEMBERG + + Added three new requests `schar', `fschar', and `rfschar'. `schar' + defines a glyph which is searched after the check for fonts declared + with `.special' (and before the check for all mounted special + fonts). `fschar' defines a glyph for a particular font which is + searched after the check for fonts declared with `.fspecial' (and + before the check for fonts declared with `.special'). `rfschar' + removes glyphs defined with `fschar'. + + * src/roff/troff/token.h (char_mode): New enum. + Declare do_define_character. + * src/roff/troff/charinfo.h (charinfo): Replace `fallback' with + `mode'. + (charinfo::is_fallback): Updated. + (charinfo::is_special): New method. + * src/roff/troff/input.cc (do_define_character): Add and use + optional second parameter used as a prefix for font-specific glyph + names. + (define_character, define_fallback_character): Updated. + (define_special_character): New function. + (init_input_requests): Add `schar'. + (charinfo::charinfo, charinfo::set_macro): Updated. + * src/roff/troff/node.cc: Include `stringclass.h'. + (make_glyph_node): Handle special glyphs defined with `.schar' and + `.fschar'. + (define_font_special_character, remove_font_special_character): New + functions. + (init_node_requests): Sorted. + Add `fschar' and `rfschar'. + * NEWS, man/groff_diff.man, man/groff.man, doc/groff.texinfo: + Document new requests. + + * font/devhtml/R.proto, font/devutf8/R.proto: Add `va'. + * tmac/dvi.tmac: Add `va' for CW and CWI (using `.fschar'). + +2002-11-08 Werner LEMBERG + + Added new font `SC' (cmtex10) to devdvi. + + * devdvi/generate/Makefile (FONTS): Add `SC'. + (SC): New rule. + * devdvi/generate/textex.map: New map file for cmtex. + * devdvi/SC: New. + * devdvi/Makefile.sub (DEVFILES): Updated. + * tmac/dvi.tmac: Add fspecial entries for SC. + Add `MI', `S' and `CW' to the `special' call. Otherwise, `SC' is + found before `S' since the font position of `SC' is lower due to the + gaps in DESC's `font' line. + * tmac/ec.tmac: Add a `special' call. + * NEWS: Updated. + + * font/devhtml/R.proto: Remove double entry for `ti'. + * tmac/tty.tmac: Add entries for `IJ', `ij', and `bq'. + * tmac/tty-char.tmac: Remove entry for `bq'. + * tmac/lbp.tmac: Add entries for `lq', `rq', `fo', `fc', and `em'. + * tmac/ec.tmac: Don't remove `aq' glyph. + * tmac/X.tmac: Fix entry for `em'. + Add entries for `fo' and `fc'. + * tmac/dvi.tmac: Add entries for `em', `en', `hy', `fo', and `fc'. + + * doc/groff.texinfo, man/groff.man, man/groff_diff.man: Fix + documentation of `special' and `fspecial' requests. + +2002-11-05 Werner LEMBERG + + * font/devascii/R.proto, font/devcp1047/R.proto, + font/devlatin1/R.proto: Remove entry for `.i'. + * font/devdvi/generate/textt.map: Add entry for `ad'. + * font/devdvi/generate/texr.map, font/devdvi/generate/texb.map, + font/devdvi/generate/texi.map: Add dummy glyph name `slash@for@l'. + We need this for getting kerning values to compose `/l' and `/L'. + * font/devdvi: Regenerated font definition files for CM fonts. + * font/devhtml/R.proto: Add entries for "'C", "'c", `IJ', and `ij'. + * font/devutf8/R.proto: Ditto. + Remove double entry for `ti'. + + * src/roff/troff/glyphuni.cc (glyph_to_unicode_list): Fix entries + for (groff) ligatures, `la', and `ra'. + Add "'C", "'c", `IJ', and `ij'. + Remove double entry for `ti'. + * src/roff/troff/uniglyph.cc (unicode_to_glyph_list): Remove all + double entries. + Add "'C", "'c", `IJ', and `ij'. + Fix entries for (groff) ligatures, `la', and `ra'. + + * tmac/ps.tmac (ps-achar): New macro. + Define "'c" and "'C". + * tmac/tty.tmac: Add entry for `.i'. + * tmac/X.tmac (X-achar): New macro. + Define "'c", "'C", and `:Y'. + Add entries for `IJ' and `ij'. + * tmac/Xps.tmac (Xps-achar): New macro. + Define "'c" and "'C". + Add entries for `IJ' and `ij'. + * tmac/lbp.tmac (lbp-achar): New macro. + Add fallback characters for all groff ligatures and many other + glyphs. + * tmac/dvi.tmac: Fix definitions of `_' and `ul'. + Add entries for `/l' and `/L'. + Define "'c" and "'C". + Add entries for `IJ' and `ij'. + +2002-11-02 Larry Kollar + + * PROBLEMS: Document how to solve Mac OS X compilation problems. + +2002-11-02 Werner LEMBERG + + Adding support for composite glyphs: \[xxx yyy ...] and the + `composite' request. + + * src/roff/troff/glyphuni.cc: New file for mapping groff glyph names + to Unicode-based glyph names. + * src/roff/troff/uniglyph.cc: New file for mapping Unicode-based + glyph names to groff glyph names. + * src/roff/troff/uniuni.cc: New file for canonically decomposing + Unicode-based glyph names. + * src/roff/troff/unicode.cc, src/roff/troff/unicode.h: New files + for handling Unicode glyph names. + * src/roff/troff/input.cc: Include unicode.h. + (composite_glyph_name): New function. + (token::next) <'['>: Handle Unicode glyph names and composite + glyphs. + (composite_dictionary): New dictionary for the `composite' request. + (composite_request): Implement `composite' request. + (init_input_requests): Add `composite'. + Alphabetically sorted. + * src/roff/troff/env.cc (tabs_save, tabs_restore): Removed (already + commented out). + (init_env_requests): Alphabetically sorted. + Removed `tas' and `tar' (already commented out). + * src/roff/troff/Makefile.sub: Updated. + +2002-10-31 Ruslan Ermilov + + * src/roff/nroff/nroff.man, src/roff/nroff/nroff.sh: Fix description + of options. + +2002-10-29 Werner LEMBERG + + Fix computation of .trunc register. Additionally, its value (and + the value of the .ne register) is now always set before entering the + trap. + + * src/roff/troff/div.cc (diversion::need): Set `truncated_space' and + `needed_space' before calling `space'. + (top_level_diversion::space): Remove special code for 'sp before the + first page. + Call `begin_page' with the discarded space as a parameter. + (top_level_diversion::begin_page): Add optional parameter to set + `truncated_space'. + * src/roff/troff/div.h: Updated. + + * doc/groff.texinfo: Improve documentation of .sp, \n[.trunc], and + \n[.ne]. + + * tmac/an-old.tmac (SH, SS, TP, IP, HP, TS): Undo change 2002-10-26. + (LP): Remove superfluous call to `br'. + * tmac/doc-common (doc-paragraph): Undo change 2002-10-26. + * tmac/doc.tmac (Bd, Bl, doc-set-vertical-and-indent): Ditto. + +2002-10-26 Werner LEMBERG + + * tmac/doc-ditroff: Remove useless switch/variable -rC. + (doc-setup-header): Don't set page register `%'. + * tmac/doc-nroff: Remove variable `C'. + (doc-setup-page-layout): Set doc-header-space to .5i unconditionally. + (doc-setup-header): Don't set page register `%'. + Don't call `bp'. + * tmac/doc-common (doc-header): Call `ns'. + (doc-paragraph): Protect .sp with .br so that it survives traps + possibly set by the user. + * tmac/doc.tmac (Bd, Bl, doc-set-vertical-and-indent): Ditto. + + * tmac/doc*: Replace ' with . for consistency if no effect. + +2002-10-26 Werner LEMBERG + + * tmac/an-old.tmac (SH, SS, TP, IP, HP, TS): Protect .sp with .br + so that it survives traps possibly set by the user. + + * src/roff/troff/node.cc: Fix the changes from 2002-10-23. + (troff_output_file::set_font): Call flush_tbuf if necessary. + (troff_output_file::fill_color, troff_output_file::glyph_color): Call + flush_tbuf and do_motion only if necessary. + (troff_output_file::start_special, + troff_output_file::put_char_width, troff_output_file::put_char, + troff_output_file::draw): Updated. + (word_space_node::tprint, space_node::tprint, hmotion_node::tprint, + vmotion_node::tprint): Undo change 2002-10-23. + +2002-10-25 Werner LEMBERG + + * tmac/www.tmac (DC): Fix case of overlapping images. + +2002-10-23 Werner LEMBERG + + * src/roff/troff/node.cc (troff_output_file::fill_color, + troff_output_file::glyph_color): Set current color before testing + color_flag. + (troff_output_file::put_char_width, troff_output_file::put_char, + troff_output_file::draw): Don't call flush_tbuf and/or do_motion + before glyph_color. + (troff_output_file::file_color, troff_output_file::glyph_color): + Call do_motion. + (word_space_node::tprint, space_node::tprint, hmotion_node::tprint, + vmotion_node::tprint): Move first, then call fill_color. + +2002-10-20 Werner LEMBERG + + * doc/groff.texinfo, man/groff_tmac.man: Document that it is not + possible to use multiple main macro packages. + +2002-10-19 Werner LEMBERG + + * src/devices/grops/ps.cc (cmyk_flag): New global variable. + (ps_printer::set_color): Set `cmyk_flag' for CMY and CMYK colors. + (ps_printer::~ps_printer): Emit `%%Extensions: CMYK' if `cmyk_flag' + is set. + * font/devps/prologue.ps (Fk, Ck): Enclose definitions with a + `where' construction since `cmyksetcolor' is a PS Level 2 operator. + +2002-10-16 Werner LEMBERG + + * NEWS, doc/webpage.ms: Updated. + +2002-10-14 Werner LEMBERG + + * src/roff/troff/node.cc (troff_output_file::put_char_width, + troff_output_file::put_char, troff_output_file::fill_color, + troff_output_file::glyph_color): Handle case where color pointer + is null. + +2002-10-13 Ruslan Ermilov + + Add the new -r option to grotty. It is similar to the -i option + except it tells grotty(1) to use the `reverse video' attribute to + render italic fonts. + + * src/devices/grotty/tty.cc (reverse_flag): New global variable. + (SGR_REVERSE, SGR_NO_REVERSE): New macros. + (tty_printer::make_underline, tty_printer::put_color, + tty_printer::end_page): Use it. + (main): Add -r switch. + (usage): Updated. + * src/devices/grotty/grotty.man: Document it. + +2002-10-11 Ruslan Ermilov + + * src/roff/troff/env.cc (hyphen_trie::read_patterns_file): Add + cast to `unsigned char' to properly read patterns with 8bit + characters. + +2002-10-08 Werner LEMBERG + + * REVISION: Increased to 2. + +Copyright 2002-2005 Free Software Foundation, Inc. + +Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. + +Local Variables: +coding: latin-1 +fill-column: 72 +mode: change-log +version-control: never +End: +vim:set autoindent textwidth=72: diff --git a/ChangeLog.120 b/ChangeLog.120 new file mode 100644 index 0000000..0451689 --- /dev/null +++ b/ChangeLog.120 @@ -0,0 +1,3053 @@ + +Version 1.20.1 released +======================= + + `gnu.png' isn't needed any more. + + * doc/Makefile.in: Don't handle or create `gnu.png'. + Update all affected targets. + + * doc/Makefile.sub: Don't handle or create `gnu.png'. + Update alll affected targets. + + + `gnu.eps' was missing in the tarball. + Problem reported by Patrik Gräser. + + (PROCESSEDEXAMPLEFILES): Remove `gnu.eps'. + (MOSTLYCLEANNOTSRCDIRADD): Fix names of info files. + (install_data): Handle `gnu.eps' specially. + + * MORE.STUFF: Mention texi2html's troff backend. + Mention http://groff.ffii.org/groff/contrib. + + * README: Mention `MORE.STUFF'. + + * NEWS, doc/webpage.ms, doc/groff.texinfo: Updated. + +2009-01-08 Werner LEMBERG + + * */Makefile.* (CLEANADD, CLEANNOTSRCDIRADD, CLEANDIRADD): Renamed + to... + (MOSTLYCLEANADD, MOSTLYCLEANNOTSRCDIRADD, MOSTLYCLEANDIRADD): This. + +2009-01-06 Werner LEMBERG + + Remove heuristics for LIBEXT. + + * configure.ac: Provide LIBEXT. + * Makefile.in: Use it. + + * configure: Regenerated. + +2009-01-05 Werner LEMBERG + +Version 1.20 released +===================== + +2009-01-05 Werner LEMBERG + + * */*: Update FDL 1.1 to FDL 1.3. + +2009-01-05 Werner LEMBERG + + * */*: Update copyright year. + +2009-01-05 Werner LEMBERG + + * MANIFEST: Updated. + +2009-01-05 Werner LEMBERG + + * doc/texinfo.tex (\key): Fix excessive whitespace. + (\texinfoversion): Tag file as patched. + +2009-01-05 Werner LEMBERG + + * tmac/s.tmac (@TS, TE, @EQ, @EN), tmac/an-old.tmac (TS, TE, EQ, + EN), tmac/e.tmac (TS, TE, EQ, EN): Set line length to a large value + if processed with -Thtml. + +2009-01-04 Werner LEMBERG + + * tmac/www.tmac (TS, TE, EQ, EN): Set line length to a large value + if processed with -Thtml to avoid warning messages (from code + inserted by tbl, for example). + +2009-01-04 Gunnar Florus + + * */*: Update GPL2 to GPL3. + +2009-01-04 Werner LEMBERG + + * Makefile.in (dist): Don't use soft links but copy files to + preserve the file's time stamps. + * Makefile.sub (configure): Remove `autom4te.cache'. + +2009-01-04 Werner LEMBERG + + * tmac/de.tmac: Fix German date strings. Reported by Axel Kielhorn. + +2009-01-04 Werner LEMBERG + + * doc/texinfo.tex: Updated from `texinfo' CVS repository. + * doc/txi-en.tex: New file from `texinfo' CVS repository. + +2009-01-04 Werner LEMBERG + + * font/make-Rproto: Moved to... + * font/util/make-Rproto: Here. + + * Makefile.in (NOMAKEDIRS): Add `m4', `font/devps/old', and + `font/util'. + +2009-01-04 Werner LEMBERG + + * src/roff/troff/TODO: Mention local variables. + +2009-01-03 Werner LEMBERG + + * contrib/hdtbl/examples/col_rowspan_colors.roff, + contrib/hdtbl/examples/color_boxes.roff, + contrib/hdtbl/examples/color_nested_tables.roff, + contrib/hdtbl/examples/color_table_cells.roff, + contrib/hdtbl/examples/color_transitions.roff, + contrib/hdtbl/examples/short_reference.roff: Minor improvements. + +2009-01-03 Werner LEMBERG + + * doc/webpage.ms: Updated. + +2009-01-03 Werner LEMBERG + + * NEWS, doc/groff.texinfo, font/devps/*, VERSION, REVISION: Prepare + for version 1.20. + +2009-01-03 Werner LEMBERG + + * src/preproc/tbl/table.cpp (table::compute_expand_width, + table::compute_separation_factor): In warning messages, don't refer + to pages but to input line numbers. + +2009-01-03 Werner LEMBERG + + * tmac/groff_ms.man: Improve formatting of tables. + +2009-01-03 Werner LEMBERG + + * tmac/www.tmac (www->): Handle XHTML. + (HTML

): Handle non-HTML devices. + (www:url_check_tag): Avoid warnings. + +2009-01-03 Werner LEMBERG + + * tmac/an-old.tmac, tmac/doc.tmac: For -Tutf8, map \-, -, ', and ` + conservatively to ASCII for the sake of easy cut and paste. + +2009-01-03 Werner LEMBERG + + * NEWS: Mention hdtbl. + +2009-01-02 Werner LEMBERG + + * tmac/groff_mdoc.man: Update OS version string listing. + +2009-01-02 Werner LEMBERG + + * config.rpath, m4/codeset.m4, m4/glibc21.m4, m4/iconv.m4, + m4/lib-link.m4, m4/lib-prefix.m4, src/include/localcharset.h, + src/libs/libgroff/config.charset, src/libs/libgroff/localcharset.c, + src/libs/libgroff/ref-add.sin, src/libs/libgroff/ref-del.sin: + Updated from `gnulib' git repository. + + * configure: Regenerated. + +2009-01-02 Werner LEMBERG + + * tmac/ptx.tmac: New file. + + * NEWS, man/groff_tmac: man: Document it. + +2008-12-30 Werner LEMBERG + + Fix more quoting issues. + + * tmac/www.tmac (BCL, BGIMG, PIMG, MPIMG, LNS): For the sake of + XHTML, quote more arguments. + (IMG): Fix quoting. + +2008-12-30 Werner LEMBERG + + Fix quoting issues in www.tmac. + + * tmac/www.tmac (www:url_breaks_splitted): Renamed to... + (www:url_breaks_split): This. + (www->): New string to close tag singletons like or
. In + XHTML mode (not implemented yet), this has to be changed from `>' to + `/>'. + (IMG): Don't use + Use www->. + (PIMG, MPIMG): Don't use + Use www->. + Fix doublequote issues. + (HR): Don't use . + Use www->. + (LNS): Fix doublequote issues. + +2008-12-24 Michail Vidiassov + + * tmac/doc-common: Add entries for Mac OS X and FreeBSD. + +2008-12-22 Alexey Gladkov + + * contrib/groffer/perl/roff2.pl: Fix syntax error. + +2008-12-15 Werner LEMBERG + + * NEWS: Mention `preconv'. + +2008-11-12 Werner LEMBERG + + Implement `x' specifier for expanded columns. Contrary to old DWB + tbl, more than a single `x' specifier can be used. At the same + time, remove most of the code from change 2007-02-09 which collides + with the new implementation. + + * src/preproc/tbl/main.cpp (format): Add `expand' array. + (format::format, format::~format): Updated. + (input_entry_format): Add `expand' field. + (input_entry_format::input_entry_format): Updated. + (input_entry_format::debug_print): Handle `expand'. + (process_format): Handle `x' specifier. + (process_data): Updated. + + * src/preproc/tbl/table.cpp (AVAILABLE_REG, COLCOUNT_REG): Remove. + (EXPAND_REG): New macro. + (table_entry::divert, block_entry::divert, + alphabetic_block_entry::divert): Add parameter to control whether + expanded columns shall be handled. + (block_entry::do_width): Remove. + (block_entry::do_divert): Add parameter to control whether expanded + columns shall be handled. + Treat expanded columns like columns with a minimum width. + Remove `experimental' code. + (table::table, table::~table, table::allocate): Updated. + (table::set_expand_column): New function. + (table::count_block_columns): Replace with... + (table::count_expand_columns): This function. + (table::divide_span): Handle expanded columns the same as equal + columns. + (table::sum_columns): Add parameter to control whether expanded + columns shall be handled. + (table::compute_available_block_width): Replace with... + (table::compute_expand_width): This function. + (table::compute_total_separation): New function, taking code from + `compute_separation_factor'. + (table::compute_separation_factor): Simpler code. The check for the + `EXPAND' flag has been moved to the caller. + (table::compute_widths): Add `top-level' changes to handle expanded + blocks. + + * src/preproc/tbl/table.h (table): New field `total_separation'. + Remove `blockflag' array. + Add `expand' array. + Update member function declarations. + + * src/preproc/tbl/tbl.man: Document `x' specifier. + Expand documentation to cover all aspects of Lesk's tbl reference. + + * NEWS: Document `x' specifier. + +2008-11-08 Werner LEMBERG + + * src/preproc/tbl/tbl.man: Restructuring. + Improve text block documentation. + +2008-11-07 Werner LEMBERG + + * src/preproc/tbl/table.cpp (table::compute_widths): Use default + scaling operator for minimum width. Without this fix, `lw3' (or + `lw(3)' would be handled as a column with a minimum width of 3u + instead of 3n. + +2008-11-05 Werner LEMBERG + + * tmac/doc-common (Dt): Start a new page if necessary and set up + headers. + + * tmac/andoc.tmac (reload-doc): Simplify due to change in + doc-common. + + * NEWS: Document it. + +2008-10-18 Werner LEMBERG + + * src/preproc/tbl/main.cpp (process_format): Rename `x' and `X' to + `m' and `M', respectively. + Sort entries in `switch' block. + * src/preproc/tbl/tbl.man: Updated. + Sort key entries; other minor improvements. + +2008-10-17 Werner LEMBERG + + * src/preproc/tbl/table.cpp (table::compute_available_block_width): + New function. + (table::compute_widths): Replace some code with new function + (shifted to a more appropriate place). + * src/preproc/tbl/table.h: Updated. + +2008-10-16 Werner LEMBERG + + * tmac/doc-common (doc-operating-system-*), tmac/groff_mdoc.man: Add + NetBSD 4.0.1. + +2008-10-13 Werner LEMBERG + + * tmac/groff_mdoc.man: Update documentation on BSD-like OS string + versions. + +2008-10-10 Werner LEMBERG + + * man/roff.man, doc/groff.texinfo: Improve the history part. This + is based on input from Tom Van Vleck . + + + * src/preproc/eqn/sqrt.cpp (sqrt_box::compute_metrics): Assure that + value of `rst' register is not zero, as can happen for the HTML + output device. Otherwise, there are too many loops, and we get a + stack overflow because of recursion. + +2008-10-05 Stephen Gildea + + * src/preproc/ref/ref.cpp (reference::compute_sort_key): Do + not insert SORT_SEP before the first field, so that sort_key + has the same format as before the patch of 2003-08-23. + +2008-10-04 Werner LEMBERG + + * tmac/doc-common (doc-operating-system-*): Update releases. + + * tmac/an-old.tmac (an-extra1, an-extra2, an-extra3): Initialize. + + * tmac/andoc.tmac: Rewritten, based on a preliminary version from + Tadziu Hoffmann. It can now process multiple man pages with both + man and mdoc formats intermixed. + + * NEWS, tmac/groff_man.man, tmac/groff_mdoc.man, + man/groff_tmac.man: Document it. + +2008-10-04 Werner LEMBERG + + * src/roff/troff/input.cpp (do_suppress): Make \O[3], \O[4], and + \O[5] non-transparent w.r.t. beginning-of-line recognition (similar + to the other \O variants). + + * tmac/www.tmac (TS, TE, EQ, EN): Don't use .als for setting up + default macros. This causes endless loops (at least for TE). + + * doc/groff.texinfo: Improve documentation of `.als'. + +2008-10-03 Werner LEMBERG + + * src/devices/grops/grops.man, src/roff/troff/troff.man, + src/preproc/soelim/soelim.man: Correct documentation of -I switch. + Reported by Larry Kollar. + Other minor formatting issues. + +2008-10-02 Werner LEMBERG + + * tmac/trace.tmac: Much improved. + (trace-full): New register to be set on the command line; it + controls whether number and string register assignments get traced + also. + (!!c): New macro for comments. + (rm): New traced macro. + (de, de1, am, am1): Use \\[xxx]\\ calling method to pass \$0 to + `!!xxx'; this makes doc.tmac completely traceable. + Trace call of .de and friends also. + + * tmac/groff_tmac.man, NEWS: Update. + +2008-09-30 Werner LEMBERG + + Restore behaviour of \$0 if a macro is called with string syntax + (problem caused by change on 2008-09-29). + + * src/roff/troff/input.cpp (input_iterator, input_stack, + macro_iterator): Add `get_macro_name' member function. + (interpolate_string): Use it. + +2008-09-29 Werner LEMBERG + + Make \\*[xxx]\\ within a macro (with `xxx' a macro too) work as + expected. Without the patch, + + .de aaa + \\*[bbb]\\ + . tm \\$* + .. + .de bbb + . shift + .. + .aaa 1 2 3 + + prints `2 3' instead of `1 2 3'. + + * src/roff/troff/input.cpp (input_iterator, input_stack, + macro_iterator): Add `get_arg_list' member function. + (macro): Add `is_a_string', `is_string', and `clear_string_flag' + members. + Update constructors and operators. + (arg_list): Add copy constructor. + (macro_iterator): Add optional argument to constructor to indicate + whether arguments shall be inherited from calling macro. + (interpolate_string): If string argument is a macro, push a macro + iterator on the stack. + (do_define_macro): Call clear_string_flag if macro data contains a + newline. + + * src/roff/troff/request.h: Updated. + +2008-09-29 Eric S. Raymond + + * doc/pic.ms: Fold in documentation of pic2plot(1) capabilities. + Improve the documentation of text objects. + +2008-09-28 Eric S. Raymond + + * contrib/pic2graph, contrib/pic2graph.man, contrib/eqn2graph, + contrib/eqn2graph.man: Tweak scripts to cope with incompatible + changes in ImageMagick crop options. Document the bugs. + +2008-09-28 Werner LEMBERG + + If a macro is called as a string, inherit value of \n[.br] from the + caller. This is useful for `trace.tmac'. + + * src/roff/troff/input.cpp (string_iterator): New members + `with_break' and `get_break_flag'. + (string_iterator::string_iterator): Updated. + + * doc/groff.texinfo: Improve documentation of \$0 and string syntax + calling of macros. + Document behaviour of \n[.br] within strings. + +2008-09-26 Werner LEMBERG + + * tmac/trace.tmac: Add copyright message. + Use `.de1' where possible to make source code more readable. + (so, mso, als, rn): Restore escape character before executing the + request. + (de, de1, am, am1): Trace `.foo' also if called as `\\[foo]'. + +2008-09-24 Werner LEMBERG + + Fix incompatibility between `.de1' and `.do'. Without this change, + the following snippet + + .de1 xx + . tm \\n(.C + .. + .cp 1 + .do xx + + prints 1 instead of 0. + + * src/roff/troff/input.cc (do_request): If a macro gets processed, + call tok.next(). + (interpolate_macro): Add optional argument. Update callers. + (request::invoke): Add optional argument. + (macro::invoke): Add optional argument to delay call of tok.next(). + + * src/roff/troff/request.h (request_or_macro): Add argument to + `invoke' member. Update all derived classes. + + * doc/groff.texinfo: Improve documentation of .do request. + +2008-09-09 Werner LEMBERG + + * tmac/an-old.tmac (FT): Initialize properly. Reported by Tadziu + Hoffmann. + +2008-09-06 Werner LEMBERG + + * tmac/doc-common (Dd, Os, Dt): Reset `doc-command-name' to make + `.Nm' work properly if next manual page is printed. + +2008-08-20 Werner LEMBERG + + * src/preproc/tbl/tbl.man: Document computation of element widths. + +2008-08-20 Alexey Gladkov + Werner LEMBERG + + Add default encoding option -D to preconv and groff. + + * src/preproc/preconv/preconv.cpp (default_encoding): Make it an + array. + Update all users. + (main): Handle new option -D. + (usage): Updated. + * src/preproc/preconv/preconv.man: Updated. + + * src/roff/groff/groff.cpp (main): Handle new option -D. + (synopsis, help): Updated. + * src/roff/groff/groff.man: Updated. + +2008-07-26 Werner LEMBERG + + * tmac/eqnrc (.EQ, .EN): Provide default definitions. Reported + by Denis M. Wilson. + + * tmac/www.tmac (.EQ, .EN, .TS, .TE): Fix definitions. + +2008-07-24 Denis M. Wilson + + New options -f and -k for afmtodit. + + * src/afmtodit/afmtodit.pl: New options `-f NAME' sets the internal + name of the groff font. + New option `-k' disables output of kerning data. + * src/afmtodit/afmtodit.man, NEWS: Document new options. + +2008-07-18 Werner LEMBERG + + * src/preproc/tbl/table.cpp (table::compute_separation_factor): Emit + warning messages if table gets squeezed. + (table::compute_widths): Fix computation of AVAILABLE_REG. + Emit warning if table is wider than line length. + + * src/preproc/tbl/tbl.man: Minor improvements. + +2008-05-02 Larry Jones + + * contrib/chem/Makefile.sub (README, examples/README): In makefiles, + the `$<' macro is only guaranteed to be defined in inference rules, + not in explicit target rules. Since there is only one input file in + the places where it is used, the `$?' macro (which is guaranteed to be + defined for both kinds of rules) is a suitable replacement. + + * hdtbl/examples/fonts_n.in, hdtbl/examples/fonts_n.in: Most + versions of ls don't have a `--color' option. + +2008-04-30 Larry Jones + + * Makefile.comm (depend.temp): Add `EXTRA_CCFLAGS'. + +2008-04-29 Larry Jones + + * src/eqn/script.cpp (script_box::output): Portability fix. + +2008-04-05 Dorai Sitaram + + Add better support for `.TAG #
column column_arg column_element_list + +%% +top: + /* empty */ + | equation + { $1->top_level(); non_empty_flag = 1; } + ; + +equation: + mark + { $$ = $1; } + | equation mark + { + list_box *lb = $1->to_list_box(); + if (!lb) + lb = new list_box($1); + lb->append($2); + $$ = lb; + } + ; + +mark: + from_to + { $$ = $1; } + | MARK mark + { $$ = make_mark_box($2); } + | LINEUP mark + { $$ = make_lineup_box($2); } + ; + +from_to: + sqrt_over %prec FROM + { $$ = $1; } + | sqrt_over TO from_to + { $$ = make_limit_box($1, 0, $3); } + | sqrt_over FROM sqrt_over + { $$ = make_limit_box($1, $3, 0); } + | sqrt_over FROM sqrt_over TO from_to + { $$ = make_limit_box($1, $3, $5); } + | sqrt_over FROM sqrt_over FROM from_to + { $$ = make_limit_box($1, make_limit_box($3, $5, 0), 0); } + ; + +sqrt_over: + script + { $$ = $1; } + | SQRT sqrt_over + { $$ = make_sqrt_box($2); } + | sqrt_over OVER sqrt_over + { $$ = make_over_box($1, $3); } + | sqrt_over SMALLOVER sqrt_over + { $$ = make_small_over_box($1, $3); } + ; + +script: + nonsup + { $$ = $1; } + | simple SUP script + { $$ = make_script_box($1, 0, $3); } + ; + +nonsup: + simple %prec SUP + { $$ = $1; } + | simple SUB nonsup + { $$ = make_script_box($1, $3, 0); } + | simple SUB simple SUP script + { $$ = make_script_box($1, $3, $5); } + ; + +simple: + TEXT + { $$ = split_text($1); } + | QUOTED_TEXT + { $$ = new quoted_text_box($1); } + | SPLIT QUOTED_TEXT + { $$ = split_text($2); } + | NOSPLIT TEXT + { $$ = new quoted_text_box($2); } + | '^' + { $$ = new half_space_box; } + | '~' + { $$ = new space_box; } + | '\t' + { $$ = new tab_box; } + | '{' equation '}' + { $$ = $2; } + | PILE pile_arg + { $2->set_alignment(CENTER_ALIGN); $$ = $2; } + | LPILE pile_arg + { $2->set_alignment(LEFT_ALIGN); $$ = $2; } + | RPILE pile_arg + { $2->set_alignment(RIGHT_ALIGN); $$ = $2; } + | CPILE pile_arg + { $2->set_alignment(CENTER_ALIGN); $$ = $2; } + | MATRIX '{' column_list '}' + { $$ = $3; } + | LEFT delim equation RIGHT delim + { $$ = make_delim_box($2, $3, $5); } + | LEFT delim equation + { $$ = make_delim_box($2, $3, 0); } + | simple BAR + { $$ = make_overline_box($1); } + | simple UNDER + { $$ = make_underline_box($1); } + | simple PRIME + { $$ = make_prime_box($1); } + | simple ACCENT simple + { $$ = make_accent_box($1, $3); } + | simple UACCENT simple + { $$ = make_uaccent_box($1, $3); } + | ROMAN simple + { $$ = new font_box(strsave(get_grfont()), $2); } + | BOLD simple + { $$ = new font_box(strsave(get_gbfont()), $2); } + | ITALIC simple + { $$ = new font_box(strsave(get_gfont()), $2); } + | FAT simple + { $$ = new fat_box($2); } + | FONT text simple + { $$ = new font_box($2, $3); } + | SIZE text simple + { $$ = new size_box($2, $3); } + | FWD number simple + { $$ = new hmotion_box($2, $3); } + | BACK number simple + { $$ = new hmotion_box(-$2, $3); } + | UP number simple + { $$ = new vmotion_box($2, $3); } + | DOWN number simple + { $$ = new vmotion_box(-$2, $3); } + | TYPE text simple + { $3->set_spacing_type($2); $$ = $3; } + | VCENTER simple + { $$ = new vcenter_box($2); } + | SPECIAL text simple + { $$ = make_special_box($2, $3); } + ; + +number: + text + { + int n; + if (sscanf($1, "%d", &n) == 1) + $$ = n; + delete[] $1; + } + ; + +pile_element_list: + equation + { $$ = new pile_box($1); } + | pile_element_list ABOVE equation + { $1->append($3); $$ = $1; } + ; + +pile_arg: + '{' pile_element_list '}' + { $$ = $2; } + | number '{' pile_element_list '}' + { $3->set_space($1); $$ = $3; } + ; + +column_list: + column + { $$ = new matrix_box($1); } + | column_list column + { $1->append($2); $$ = $1; } + ; + +column_element_list: + equation + { $$ = new column($1); } + | column_element_list ABOVE equation + { $1->append($3); $$ = $1; } + ; + +column_arg: + '{' column_element_list '}' + { $$ = $2; } + | number '{' column_element_list '}' + { $3->set_space($1); $$ = $3; } + ; + +column: + COL column_arg + { $2->set_alignment(CENTER_ALIGN); $$ = $2; } + | LCOL column_arg + { $2->set_alignment(LEFT_ALIGN); $$ = $2; } + | RCOL column_arg + { $2->set_alignment(RIGHT_ALIGN); $$ = $2; } + | CCOL column_arg + { $2->set_alignment(CENTER_ALIGN); $$ = $2; } + ; + +text: TEXT + { $$ = $1; } + | QUOTED_TEXT + { $$ = $1; } + ; + +delim: + text + { $$ = $1; } + | '{' + { $$ = strsave("{"); } + | '}' + { $$ = strsave("}"); } + ; + +%% diff --git a/src/preproc/eqn/lex.cpp b/src/preproc/eqn/lex.cpp new file mode 100644 index 0000000..e38a486 --- /dev/null +++ b/src/preproc/eqn/lex.cpp @@ -0,0 +1,1236 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "eqn.h" +#include "eqn.hpp" +#include "stringclass.h" +#include "ptable.h" + + +// declarations to avoid friend name injection problems +int get_char(); +int peek_char(); +int get_location(char **, int *); + +struct definition { + char is_macro; + char is_simple; + union { + int tok; + char *contents; + }; + definition(); + ~definition(); +}; + +definition::definition() : is_macro(1), is_simple(0) +{ + contents = 0; +} + +definition::~definition() +{ + if (is_macro) + free(contents); +} + +declare_ptable(definition) +implement_ptable(definition) + +PTABLE(definition) macro_table; + +static struct { + const char *name; + int token; +} token_table[] = { + { "over", OVER }, + { "smallover", SMALLOVER }, + { "sqrt", SQRT }, + { "sub", SUB }, + { "sup", SUP }, + { "lpile", LPILE }, + { "rpile", RPILE }, + { "cpile", CPILE }, + { "pile", PILE }, + { "left", LEFT }, + { "right", RIGHT }, + { "to", TO }, + { "from", FROM }, + { "size", SIZE }, + { "font", FONT }, + { "roman", ROMAN }, + { "bold", BOLD }, + { "italic", ITALIC }, + { "fat", FAT }, + { "bar", BAR }, + { "under", UNDER }, + { "accent", ACCENT }, + { "uaccent", UACCENT }, + { "above", ABOVE }, + { "fwd", FWD }, + { "back", BACK }, + { "down", DOWN }, + { "up", UP }, + { "matrix", MATRIX }, + { "col", COL }, + { "lcol", LCOL }, + { "rcol", RCOL }, + { "ccol", CCOL }, + { "mark", MARK }, + { "lineup", LINEUP }, + { "space", SPACE }, + { "gfont", GFONT }, + { "gsize", GSIZE }, + { "define", DEFINE }, + { "sdefine", SDEFINE }, + { "ndefine", NDEFINE }, + { "tdefine", TDEFINE }, + { "undef", UNDEF }, + { "ifdef", IFDEF }, + { "include", INCLUDE }, + { "copy", INCLUDE }, + { "delim", DELIM }, + { "chartype", CHARTYPE }, + { "type", TYPE }, + { "vcenter", VCENTER }, + { "set", SET }, + { "opprime", PRIME }, + { "grfont", GRFONT }, + { "gbfont", GBFONT }, + { "split", SPLIT }, + { "nosplit", NOSPLIT }, + { "special", SPECIAL }, +}; + +struct builtin_def { + const char *name; + const char *def; +}; + +static struct builtin_def common_defs[] = { + { "ALPHA", "\\(*A" }, + { "BETA", "\\(*B" }, + { "CHI", "\\(*X" }, + { "DELTA", "\\(*D" }, + { "EPSILON", "\\(*E" }, + { "ETA", "\\(*Y" }, + { "GAMMA", "\\(*G" }, + { "IOTA", "\\(*I" }, + { "KAPPA", "\\(*K" }, + { "LAMBDA", "\\(*L" }, + { "MU", "\\(*M" }, + { "NU", "\\(*N" }, + { "OMEGA", "\\(*W" }, + { "OMICRON", "\\(*O" }, + { "PHI", "\\(*F" }, + { "PI", "\\(*P" }, + { "PSI", "\\(*Q" }, + { "RHO", "\\(*R" }, + { "SIGMA", "\\(*S" }, + { "TAU", "\\(*T" }, + { "THETA", "\\(*H" }, + { "UPSILON", "\\(*U" }, + { "XI", "\\(*C" }, + { "ZETA", "\\(*Z" }, + { "Alpha", "\\(*A" }, + { "Beta", "\\(*B" }, + { "Chi", "\\(*X" }, + { "Delta", "\\(*D" }, + { "Epsilon", "\\(*E" }, + { "Eta", "\\(*Y" }, + { "Gamma", "\\(*G" }, + { "Iota", "\\(*I" }, + { "Kappa", "\\(*K" }, + { "Lambda", "\\(*L" }, + { "Mu", "\\(*M" }, + { "Nu", "\\(*N" }, + { "Omega", "\\(*W" }, + { "Omicron", "\\(*O" }, + { "Phi", "\\(*F" }, + { "Pi", "\\(*P" }, + { "Psi", "\\(*Q" }, + { "Rho", "\\(*R" }, + { "Sigma", "\\(*S" }, + { "Tau", "\\(*T" }, + { "Theta", "\\(*H" }, + { "Upsilon", "\\(*U" }, + { "Xi", "\\(*C" }, + { "Zeta", "\\(*Z" }, + { "alpha", "\\(*a" }, + { "beta", "\\(*b" }, + { "chi", "\\(*x" }, + { "delta", "\\(*d" }, + { "epsilon", "\\(*e" }, + { "eta", "\\(*y" }, + { "gamma", "\\(*g" }, + { "iota", "\\(*i" }, + { "kappa", "\\(*k" }, + { "lambda", "\\(*l" }, + { "mu", "\\(*m" }, + { "nu", "\\(*n" }, + { "omega", "\\(*w" }, + { "omicron", "\\(*o" }, + { "phi", "\\(*f" }, + { "pi", "\\(*p" }, + { "psi", "\\(*q" }, + { "rho", "\\(*r" }, + { "sigma", "\\(*s" }, + { "tau", "\\(*t" }, + { "theta", "\\(*h" }, + { "upsilon", "\\(*u" }, + { "xi", "\\(*c" }, + { "zeta", "\\(*z" }, + { "max", "{type \"operator\" roman \"max\"}" }, + { "min", "{type \"operator\" roman \"min\"}" }, + { "lim", "{type \"operator\" roman \"lim\"}" }, + { "sin", "{type \"operator\" roman \"sin\"}" }, + { "cos", "{type \"operator\" roman \"cos\"}" }, + { "tan", "{type \"operator\" roman \"tan\"}" }, + { "sinh", "{type \"operator\" roman \"sinh\"}" }, + { "cosh", "{type \"operator\" roman \"cosh\"}" }, + { "tanh", "{type \"operator\" roman \"tanh\"}" }, + { "arc", "{type \"operator\" roman \"arc\"}" }, + { "log", "{type \"operator\" roman \"log\"}" }, + { "ln", "{type \"operator\" roman \"ln\"}" }, + { "exp", "{type \"operator\" roman \"exp\"}" }, + { "Re", "{type \"operator\" roman \"Re\"}" }, + { "Im", "{type \"operator\" roman \"Im\"}" }, + { "det", "{type \"operator\" roman \"det\"}" }, + { "and", "{roman \"and\"}" }, + { "if", "{roman \"if\"}" }, + { "for", "{roman \"for\"}" }, + { "times", "type \"binary\" \\(mu" }, + { "ldots", "type \"inner\" { . . . }" }, + { "inf", "\\(if" }, + { "partial", "\\(pd" }, + { "nothing", "\"\"" }, + { "half", "{1 smallover 2}" }, + { "hat_def", "roman \"^\"" }, + { "hat", "accent { hat_def }" }, + { "tilde_def", "\"~\"" }, + { "tilde", "accent { tilde_def }" }, + { "==", "type \"relation\" \\(==" }, + { "!=", "type \"relation\" \\(!=" }, + { "+-", "type \"binary\" \\(+-" }, + { "->", "type \"relation\" \\(->" }, + { "<-", "type \"relation\" \\(<-" }, + { "<<", "type \"relation\" \\(<<" }, + { ">>", "type \"relation\" \\(>>" }, + { "prime", "'" }, + { "approx", "type \"relation\" \"\\(~=\"" }, + { "grad", "\\(gr" }, + { "del", "\\(gr" }, + { "cdot", "type \"binary\" \\(md" }, + { "cdots", "type \"inner\" { \\(md \\(md \\(md }" }, + { "dollar", "$" }, +}; + +/* composite definitions that require troff size and motion operators */ +static struct builtin_def troff_defs[] = { + { "sum", "{type \"operator\" vcenter size +5 \\(*S}" }, + { "prod", "{type \"operator\" vcenter size +5 \\(*P}" }, + { "int", "{type \"operator\" vcenter size +8 \\(is}" }, + { "union", "{type \"operator\" vcenter size +5 \\(cu}" }, + { "inter", "{type \"operator\" vcenter size +5 \\(ca}" }, + { "dot_def", "up 52 back 15 \".\"" }, + { "dot", "accent { dot_def }" }, + { "dotdot_def", "up 52 back 25 \"..\"" }, + { "dotdot", "accent { dotdot_def }" }, + { "utilde_def", "down 75 \"~\"" }, + { "utilde", "uaccent { utilde_def }" }, + { "vec_def", "up 52 size -5 \\(->" }, + { "vec", "accent { vec_def }" }, + { "dyad_def", "up 52 size -5 { \\(<> }" }, + { "dyad", "accent { dyad_def }" }, + { "...", "type \"inner\" { . . . }" }, +}; + +/* equivalent definitions for MathML mode */ +static struct builtin_def mathml_defs[] = { + { "sum", "{type \"operator\" size big \\(*S}" }, + { "prod", "{type \"operator\" size big \\(*P}" }, + { "int", "{type \"operator\" size big \\(is}" }, + { "union", "{type \"operator\" size big \\(cu}" }, + { "inter", "{type \"operator\" size big \\(ca}" }, + { "dot", "accent { \".\" }" }, + { "dotdot", "accent { \"..\" }" }, + { "utilde", "uaccent { \"~\" }" }, + { "vec", "accent { \\(-> }" }, + { "dyad", "accent { \\(<> }" }, + { "...", "type \"inner\" { . . . }" }, +}; + +void init_table(const char *device) +{ + unsigned int i; + for (i = 0; i < sizeof(token_table)/sizeof(token_table[0]); i++) { + definition *def = new definition[1]; + def->is_macro = 0; + def->tok = token_table[i].token; + macro_table.define(token_table[i].name, def); + } + for (i = 0; i < sizeof(common_defs)/sizeof(common_defs[0]); i++) { + definition *def = new definition[1]; + def->is_macro = 1; + def->contents = strsave(common_defs[i].def); + def->is_simple = 1; + macro_table.define(common_defs[i].name, def); + } + if (output_format == troff) { + for (i = 0; i < sizeof(troff_defs)/sizeof(troff_defs[0]); i++) { + definition *def = new definition[1]; + def->is_macro = 1; + def->contents = strsave(troff_defs[i].def); + def->is_simple = 1; + macro_table.define(troff_defs[i].name, def); + } + } + else if (output_format == mathml) { + for (i = 0; i < sizeof(mathml_defs)/sizeof(mathml_defs[0]); i++) { + definition *def = new definition[1]; + def->is_macro = 1; + def->contents = strsave(mathml_defs[i].def); + def->is_simple = 1; + macro_table.define(mathml_defs[i].name, def); + } + } + definition *def = new definition[1]; + def->is_macro = 1; + def->contents = strsave("1"); + macro_table.define(device, def); +} + +class input { + input *next; +public: + input(input *p); + virtual ~input(); + virtual int get() = 0; + virtual int peek() = 0; + virtual int get_location(char **, int *); + + friend int get_char(); + friend int peek_char(); + friend int get_location(char **, int *); + friend void init_lex(const char *str, const char *filename, int lineno); +}; + +class file_input : public input { + FILE *fp; + char *filename; + int lineno; + string line; + const char *ptr; + int read_line(); +public: + file_input(FILE *, const char *, input *); + ~file_input(); + int get(); + int peek(); + int get_location(char **, int *); +}; + + +class macro_input : public input { + char *s; + char *p; +public: + macro_input(const char *, input *); + ~macro_input(); + int get(); + int peek(); +}; + +class top_input : public macro_input { + char *filename; + int lineno; + public: + top_input(const char *, const char *, int, input *); + ~top_input(); + int get(); + int get_location(char **, int *); +}; + +class argument_macro_input: public input { + char *s; + char *p; + char *ap; + int argc; + char *argv[9]; +public: + argument_macro_input(const char *, int, char **, input *); + ~argument_macro_input(); + int get(); + int peek(); +}; + +input::input(input *x) : next(x) +{ +} + +input::~input() +{ +} + +int input::get_location(char **, int *) +{ + return 0; +} + +file_input::file_input(FILE *f, const char *fn, input *p) +: input(p), lineno(0), ptr("") +{ + fp = f; + filename = strsave(fn); +} + +file_input::~file_input() +{ + if (fclose(fp) < 0) + fatal("unable to close '%1': %2", filename, strerror(errno)); + delete[] filename; +} + +int file_input::read_line() +{ + for (;;) { + line.clear(); + lineno++; + for (;;) { + int c = getc(fp); + if (c == '\r') { + c = getc(fp); + if (c != '\n') + lex_error("invalid input character code %1", '\r'); + } + if (c == EOF) + break; + else if (is_invalid_input_char(c)) + lex_error("invalid input character code %1", c); + else { + line += char(c); + if (c == '\n') + break; + } + } + if (line.length() == 0) + return 0; + if (!(line.length() >= 3 && line[0] == '.' && line[1] == 'E' + && (line[2] == 'Q' || line[2] == 'N') + && (line.length() == 3 || line[3] == ' ' || line[3] == '\n' + || compatible_flag))) { + line += '\0'; + ptr = line.contents(); + return 1; + } + } +} + +int file_input::get() +{ + if (*ptr != '\0' || read_line()) + return *ptr++ & 0377; + else + return EOF; +} + +int file_input::peek() +{ + if (*ptr != '\0' || read_line()) + return *ptr; + else + return EOF; +} + +int file_input::get_location(char **fnp, int *lnp) +{ + *fnp = filename; + *lnp = lineno; + return 1; +} + +macro_input::macro_input(const char *str, input *x) : input(x) +{ + p = s = strsave(str); +} + +macro_input::~macro_input() +{ + free(s); +} + +int macro_input::get() +{ + if (p == 0 || *p == '\0') + return EOF; + else + return *p++ & 0377; +} + +int macro_input::peek() +{ + if (p == 0 || *p == '\0') + return EOF; + else + return *p & 0377; +} + +top_input::top_input(const char *str, const char *fn, int ln, input *x) +: macro_input(str, x), lineno(ln) +{ + filename = strsave(fn); +} + +top_input::~top_input() +{ + free(filename); +} + +int top_input::get() +{ + int c = macro_input::get(); + if (c == '\n') + lineno++; + return c; +} + +int top_input::get_location(char **fnp, int *lnp) +{ + *fnp = filename; + *lnp = lineno; + return 1; +} + +// Character representing $1. Must be invalid input character. +#define ARG1 14 + +argument_macro_input::argument_macro_input(const char *body, int ac, + char **av, input *x) +: input(x), ap(0), argc(ac) +{ + int i; + for (i = 0; i < argc; i++) + argv[i] = av[i]; + p = s = strsave(body); + int j = 0; + for (i = 0; s[i] != '\0'; i++) + if (s[i] == '$' && s[i+1] >= '0' && s[i+1] <= '9') { + if (s[i+1] != '0') + s[j++] = ARG1 + s[++i] - '1'; + } + else + s[j++] = s[i]; + s[j] = '\0'; +} + + +argument_macro_input::~argument_macro_input() +{ + for (int i = 0; i < argc; i++) + delete[] argv[i]; + delete[] s; +} + +int argument_macro_input::get() +{ + if (ap) { + if (*ap != '\0') + return *ap++ & 0377; + ap = 0; + } + if (p == 0) + return EOF; + while (*p >= ARG1 && *p <= ARG1 + 8) { + int i = *p++ - ARG1; + if (i < argc && argv[i] != 0 && argv[i][0] != '\0') { + ap = argv[i]; + return *ap++ & 0377; + } + } + if (*p == '\0') + return EOF; + return *p++ & 0377; +} + +int argument_macro_input::peek() +{ + if (ap) { + if (*ap != '\0') + return *ap & 0377; + ap = 0; + } + if (p == 0) + return EOF; + while (*p >= ARG1 && *p <= ARG1 + 8) { + int i = *p++ - ARG1; + if (i < argc && argv[i] != 0 && argv[i][0] != '\0') { + ap = argv[i]; + return *ap & 0377; + } + } + if (*p == '\0') + return EOF; + return *p & 0377; +} + +static input *current_input = 0; + +/* we insert a newline between input from different levels */ + +int get_char() +{ + if (current_input == 0) + return EOF; + else { + int c = current_input->get(); + if (c != EOF) + return c; + else { + input *tem = current_input; + current_input = current_input->next; + delete tem; + return '\n'; + } + } +} + +int peek_char() +{ + if (current_input == 0) + return EOF; + else { + int c = current_input->peek(); + if (c != EOF) + return c; + else + return '\n'; + } +} + +int get_location(char **fnp, int *lnp) +{ + for (input *p = current_input; p; p = p->next) + if (p->get_location(fnp, lnp)) + return 1; + return 0; +} + +string token_buffer; +const int NCONTEXT = 4; +string context_ring[NCONTEXT]; +int context_index = 0; + +void flush_context() +{ + for (int i = 0; i < NCONTEXT; i++) + context_ring[i] = ""; + context_index = 0; +} + +void show_context() +{ + int i = context_index; + fputs(" context is\n\t", stderr); + for (;;) { + int j = (i + 1) % NCONTEXT; + if (j == context_index) { + fputs(">>> ", stderr); + put_string(context_ring[i], stderr); + fputs(" <<<", stderr); + break; + } + else if (context_ring[i].length() > 0) { + put_string(context_ring[i], stderr); + putc(' ', stderr); + } + i = j; + } + putc('\n', stderr); +} + +void add_context(const string &s) +{ + context_ring[context_index] = s; + context_index = (context_index + 1) % NCONTEXT; +} + +void add_context(char c) +{ + context_ring[context_index] = c; + context_index = (context_index + 1) % NCONTEXT; +} + +void add_quoted_context(const string &s) +{ + string &r = context_ring[context_index]; + r = '"'; + for (int i = 0; i < s.length(); i++) + if (s[i] == '"') + r += "\\\""; + else + r += s[i]; + r += '"'; + context_index = (context_index + 1) % NCONTEXT; +} + +void init_lex(const char *str, const char *filename, int lineno) +{ + while (current_input != 0) { + input *tem = current_input; + current_input = current_input->next; + delete tem; + } + current_input = new top_input(str, filename, lineno, 0); + flush_context(); +} + + +void get_delimited_text() +{ + char *filename, *last_seen_filename; + int lineno; + int got_location = get_location(&filename, &lineno); + // `filename` gets invalidated if we iterate off the end of the file. + last_seen_filename = strdup(filename); + int start = get_char(); + while (start == ' ' || start == '\t' || start == '\n') + start = get_char(); + token_buffer.clear(); + if (start == EOF) { + current_lineno = 0; + if (got_location) + error_with_file_and_line(last_seen_filename, lineno, + "end of input while defining macro"); + else + error("end of input while defining macro"); + free(last_seen_filename); + return; + } + for (;;) { + int c = get_char(); + if (c == EOF) { + current_lineno = 0; + if (got_location) + error_with_file_and_line(last_seen_filename, lineno, + "end of input while defining macro"); + else + error("end of input while defining macro"); + add_context(start + token_buffer); + free(last_seen_filename); + return; + } + if (c == start) + break; + token_buffer += char(c); + } + add_context(start + token_buffer + start); + free(last_seen_filename); +} + +void interpolate_macro_with_args(const char *body) +{ + char *argv[9]; + int argc = 0; + int i; + for (i = 0; i < 9; i++) + argv[i] = 0; + int level = 0; + int c; + do { + token_buffer.clear(); + for (;;) { + c = get_char(); + if (c == EOF) { + lex_error("end of input while scanning macro arguments"); + break; + } + if (level == 0 && (c == ',' || c == ')')) { + if (token_buffer.length() > 0) { + token_buffer += '\0'; + argv[argc] = strsave(token_buffer.contents()); + } + // for 'foo()', argc = 0 + if (argc > 0 || c != ')' || i > 0) + argc++; + break; + } + token_buffer += char(c); + if (c == '(') + level++; + else if (c == ')') + level--; + } + } while (c != ')' && c != EOF); + current_input = new argument_macro_input(body, argc, argv, current_input); +} + +/* If lookup flag is non-zero the token will be looked up to see +if it is macro. If it's 1, it will looked up to see if it's a token. +*/ + +int get_token(int lookup_flag = 0) +{ + for (;;) { + int c = get_char(); + while (c == ' ' || c == '\n') + c = get_char(); + switch (c) { + case EOF: + { + add_context("end of input"); + } + return 0; + case '"': + { + int quoted = 0; + token_buffer.clear(); + for (;;) { + c = get_char(); + if (c == EOF) { + lex_error("missing \""); + break; + } + else if (c == '\n') { + lex_error("newline before end of quoted text"); + break; + } + else if (c == '"') { + if (!quoted) + break; + token_buffer[token_buffer.length() - 1] = '"'; + quoted = 0; + } + else { + token_buffer += c; + quoted = quoted ? 0 : c == '\\'; + } + } + } + add_quoted_context(token_buffer); + return QUOTED_TEXT; + case '{': + case '}': + case '^': + case '~': + case '\t': + add_context(c); + return c; + default: + { + int break_flag = 0; + int quoted = 0; + token_buffer.clear(); + if (c == '\\') + quoted = 1; + else + token_buffer += c; + int done = 0; + while (!done) { + c = peek_char(); + if (!quoted && lookup_flag != 0 && c == '(') { + token_buffer += '\0'; + definition *def = macro_table.lookup(token_buffer.contents()); + if (def && def->is_macro && !def->is_simple) { + (void)get_char(); // skip initial '(' + interpolate_macro_with_args(def->contents); + break_flag = 1; + break; + } + token_buffer.set_length(token_buffer.length() - 1); + } + if (quoted) { + quoted = 0; + switch (c) { + case EOF: + lex_error("'\\' ignored at end of equation"); + done = 1; + break; + case '\n': + lex_error("'\\' ignored because followed by newline"); + done = 1; + break; + case '\t': + lex_error("'\\' ignored because followed by tab"); + done = 1; + break; + case '"': + (void)get_char(); + token_buffer += '"'; + break; + default: + (void)get_char(); + token_buffer += '\\'; + token_buffer += c; + break; + } + } + else { + switch (c) { + case EOF: + case '{': + case '}': + case '^': + case '~': + case '"': + case ' ': + case '\t': + case '\n': + done = 1; + break; + case '\\': + (void)get_char(); + quoted = 1; + break; + default: + (void)get_char(); + token_buffer += char(c); + break; + } + } + } + if (break_flag || token_buffer.length() == 0) + break; + if (lookup_flag != 0) { + token_buffer += '\0'; + definition *def = macro_table.lookup(token_buffer.contents()); + token_buffer.set_length(token_buffer.length() - 1); + if (def) { + if (def->is_macro) { + current_input = new macro_input(def->contents, current_input); + break; + } + else if (lookup_flag == 1) { + add_context(token_buffer); + return def->tok; + } + } + } + add_context(token_buffer); + return TEXT; + } + } + } +} + +void do_include() +{ + int t = get_token(2); + if (t != TEXT && t != QUOTED_TEXT) { + lex_error("bad filename for include"); + return; + } + token_buffer += '\0'; + const char *filename = token_buffer.contents(); + errno = 0; + FILE *fp = fopen(filename, "r"); + if (fp == 0) { + lex_error("can't open included file '%1'", filename); + return; + } + current_input = new file_input(fp, filename, current_input); +} + +void ignore_definition() +{ + int t = get_token(); + if (t != TEXT) { + lex_error("bad definition"); + return; + } + get_delimited_text(); +} + +void do_definition(int is_simple) +{ + int t = get_token(); + if (t != TEXT) { + lex_error("bad definition"); + return; + } + token_buffer += '\0'; + const char *name = token_buffer.contents(); + definition *def = macro_table.lookup(name); + if (def == 0) { + def = new definition[1]; + macro_table.define(name, def); + } + else if (def->is_macro) { + free(def->contents); + } + get_delimited_text(); + token_buffer += '\0'; + def->is_macro = 1; + def->contents = strsave(token_buffer.contents()); + def->is_simple = is_simple; +} + +void do_undef() +{ + int t = get_token(); + if (t != TEXT) { + lex_error("bad undef command"); + return; + } + token_buffer += '\0'; + macro_table.define(token_buffer.contents(), 0); +} + +void do_gsize() +{ + int t = get_token(2); + if (t != TEXT && t != QUOTED_TEXT) { + lex_error("bad argument to gsize command"); + return; + } + token_buffer += '\0'; + if (!set_gsize(token_buffer.contents())) + lex_error("invalid size '%1'", token_buffer.contents()); +} + +void do_gfont() +{ + int t = get_token(2); + if (t != TEXT && t != QUOTED_TEXT) { + lex_error("bad argument to gfont command"); + return; + } + token_buffer += '\0'; + set_gfont(token_buffer.contents()); +} + +void do_grfont() +{ + int t = get_token(2); + if (t != TEXT && t != QUOTED_TEXT) { + lex_error("bad argument to grfont command"); + return; + } + token_buffer += '\0'; + set_grfont(token_buffer.contents()); +} + +void do_gbfont() +{ + int t = get_token(2); + if (t != TEXT && t != QUOTED_TEXT) { + lex_error("bad argument to gbfont command"); + return; + } + token_buffer += '\0'; + set_gbfont(token_buffer.contents()); +} + +void do_space() +{ + int t = get_token(2); + if (t != TEXT && t != QUOTED_TEXT) { + lex_error("bad argument to space command"); + return; + } + token_buffer += '\0'; + char *ptr; + long n = strtol(token_buffer.contents(), &ptr, 10); + if (n == 0 && ptr == token_buffer.contents()) + lex_error("bad argument '%1' to space command", token_buffer.contents()); + else + set_space(int(n)); +} + +void do_ifdef() +{ + int t = get_token(); + if (t != TEXT) { + lex_error("bad ifdef"); + return; + } + token_buffer += '\0'; + definition *def = macro_table.lookup(token_buffer.contents()); + int result = def && def->is_macro && !def->is_simple; + get_delimited_text(); + if (result) { + token_buffer += '\0'; + current_input = new macro_input(token_buffer.contents(), current_input); + } +} + +char start_delim_saved = '\0'; +char end_delim_saved = '\0'; + +void do_delim() +{ + int c = get_char(); + while (c == ' ' || c == '\n') + c = get_char(); + int d; + if (c == EOF || (d = get_char()) == EOF) + lex_error("end of file while reading argument to 'delim'"); + else { + if (c == 'o' && d == 'f' && peek_char() == 'f') { + (void)get_char(); + start_delim_saved = start_delim; + end_delim_saved = end_delim; + start_delim = end_delim = '\0'; + } + else if (c == 'o' && d == 'n') { + start_delim = start_delim_saved; + end_delim = end_delim_saved; + } + else { + start_delim = c; + end_delim = d; + } + } +} + +void do_chartype() +{ + int t = get_token(2); + if (t != TEXT && t != QUOTED_TEXT) { + lex_error("bad chartype"); + return; + } + token_buffer += '\0'; + string type = token_buffer; + t = get_token(); + if (t != TEXT && t != QUOTED_TEXT) { + lex_error("bad chartype"); + return; + } + token_buffer += '\0'; + set_char_type(type.contents(), strsave(token_buffer.contents())); +} + +void do_set() +{ + int t = get_token(2); + if (t != TEXT && t != QUOTED_TEXT) { + lex_error("bad set"); + return; + } + token_buffer += '\0'; + string param = token_buffer; + t = get_token(); + if (t != TEXT && t != QUOTED_TEXT) { + lex_error("bad set"); + return; + } + token_buffer += '\0'; + int n; + if (sscanf(&token_buffer[0], "%d", &n) != 1) { + lex_error("bad number '%1'", token_buffer.contents()); + return; + } + set_param(param.contents(), n); +} + +int yylex() +{ + for (;;) { + int tk = get_token(1); + switch(tk) { + case UNDEF: + do_undef(); + break; + case SDEFINE: + do_definition(1); + break; + case DEFINE: + do_definition(0); + break; + case TDEFINE: + if (!nroff) + do_definition(0); + else + ignore_definition(); + break; + case NDEFINE: + if (nroff) + do_definition(0); + else + ignore_definition(); + break; + case GSIZE: + do_gsize(); + break; + case GFONT: + do_gfont(); + break; + case GRFONT: + do_grfont(); + break; + case GBFONT: + do_gbfont(); + break; + case SPACE: + do_space(); + break; + case INCLUDE: + do_include(); + break; + case IFDEF: + do_ifdef(); + break; + case DELIM: + do_delim(); + break; + case CHARTYPE: + do_chartype(); + break; + case SET: + do_set(); + break; + case QUOTED_TEXT: + case TEXT: + token_buffer += '\0'; + yylval.str = strsave(token_buffer.contents()); + // fall through + default: + return tk; + } + } +} + +void lex_error(const char *message, + const errarg &arg1, + const errarg &arg2, + const errarg &arg3) +{ + char *filename; + int lineno; + if (!get_location(&filename, &lineno)) + error(message, arg1, arg2, arg3); + else + error_with_file_and_line(filename, lineno, message, arg1, arg2, arg3); +} + +void yyerror(const char *s) +{ + char *filename; + int lineno; + if (!get_location(&filename, &lineno)) + error(s); + else + error_with_file_and_line(filename, lineno, s); + show_context(); +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/eqn/limit.cpp b/src/preproc/eqn/limit.cpp new file mode 100644 index 0000000..bf64a04 --- /dev/null +++ b/src/preproc/eqn/limit.cpp @@ -0,0 +1,217 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "eqn.h" +#include "pbox.h" + +class limit_box : public box { +private: + box *p; + box *from; + box *to; +public: + limit_box(box *, box *, box *); + ~limit_box(); + int compute_metrics(int); + void output(); + void debug_print(); + void check_tabs(int); +}; + +box *make_limit_box(box *pp, box *qq, box *rr) +{ + return new limit_box(pp, qq, rr); +} + +limit_box::limit_box(box *pp, box *qq, box *rr) +: p(pp), from(qq), to(rr) +{ + spacing_type = p->spacing_type; +} + +limit_box::~limit_box() +{ + delete p; + delete from; + delete to; +} + +int limit_box::compute_metrics(int style) +{ + printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid); + if (!(style <= SCRIPT_STYLE && one_size_reduction_flag)) + set_script_size(); + printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid); + int res = 0; + int mark_uid = -1; + if (from != 0) { + res = from->compute_metrics(cramped_style(script_style(style))); + if (res) + mark_uid = from->uid; + } + if (to != 0) { + int r = to->compute_metrics(script_style(style)); + if (res && r) + error("multiple marks and lineups"); + else { + mark_uid = to->uid; + res = r; + } + } + printf(".ps \\n[" SIZE_FORMAT "]u\n", uid); + int r = p->compute_metrics(style); + p->compute_subscript_kern(); + if (res && r) + error("multiple marks and lineups"); + else { + mark_uid = p->uid; + res = r; + } + printf(".nr " LEFT_WIDTH_FORMAT " " + "0\\n[" WIDTH_FORMAT "]", + uid, p->uid); + if (from != 0) + printf(">?(\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])", + p->uid, from->uid); + if (to != 0) + printf(">?(-\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])", + p->uid, to->uid); + printf("/2\n"); + printf(".nr " WIDTH_FORMAT " " + "0\\n[" WIDTH_FORMAT "]", + uid, p->uid); + if (from != 0) + printf(">?(-\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])", + p->uid, from->uid); + if (to != 0) + printf(">?(\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])", + p->uid, to->uid); + printf("/2+\\n[" LEFT_WIDTH_FORMAT "]\n", uid); + printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]", uid, p->uid); + if (to != 0) + printf(">?\\n[" WIDTH_FORMAT "]", to->uid); + if (from != 0) + printf(">?\\n[" WIDTH_FORMAT "]", from->uid); + printf("\n"); + if (res) + printf(".nr " MARK_REG " +(\\n[" LEFT_WIDTH_FORMAT "]" + "-(\\n[" WIDTH_FORMAT "]/2))\n", + uid, mark_uid); + if (to != 0) { + printf(".nr " SUP_RAISE_FORMAT " %dM+\\n[" DEPTH_FORMAT + "]>?%dM+\\n[" HEIGHT_FORMAT "]\n", + uid, big_op_spacing1, to->uid, big_op_spacing3, p->uid); + printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n[" + HEIGHT_FORMAT "]+%dM\n", + uid, uid, to->uid, big_op_spacing5); + } + else + printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid); + if (from != 0) { + printf(".nr " SUB_LOWER_FORMAT " %dM+\\n[" HEIGHT_FORMAT + "]>?%dM+\\n[" DEPTH_FORMAT "]\n", + uid, big_op_spacing2, from->uid, big_op_spacing4, p->uid); + printf(".nr " DEPTH_FORMAT " \\n[" SUB_LOWER_FORMAT "]+\\n[" + DEPTH_FORMAT "]+%dM\n", + uid, uid, from->uid, big_op_spacing5); + } + else + printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid); + return res; +} + +void limit_box::output() +{ + if (output_format == troff) { + printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid); + if (to != 0) { + printf("\\Z" DELIMITER_CHAR); + printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid); + printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u" + "+(-\\n[" WIDTH_FORMAT "]u+\\n[" SUB_KERN_FORMAT "]u/2u)'", + uid, to->uid, p->uid); + to->output(); + printf(DELIMITER_CHAR); + } + if (from != 0) { + printf("\\Z" DELIMITER_CHAR); + printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid); + printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u" + "+(-\\n[" SUB_KERN_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'", + uid, p->uid, from->uid); + from->output(); + printf(DELIMITER_CHAR); + } + printf("\\s[\\n[" SIZE_FORMAT "]u]", uid); + printf("\\Z" DELIMITER_CHAR); + printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u" + "-(\\n[" WIDTH_FORMAT "]u/2u)'", + uid, p->uid); + p->output(); + printf(DELIMITER_CHAR); + printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid); + } + else if (output_format == mathml) { + if (from != 0 && to != 0) { + printf(""); + p->output(); + from->output(); + to->output(); + printf(""); + } + else if (from != 0) { + printf(""); + p->output(); + from->output(); + printf(""); + } + else if (to != 0) { + printf(""); + p->output(); + to->output(); + printf(""); + } + } +} + +void limit_box::debug_print() +{ + fprintf(stderr, "{ "); + p->debug_print(); + fprintf(stderr, " }"); + if (from) { + fprintf(stderr, " from { "); + from->debug_print(); + fprintf(stderr, " }"); + } + if (to) { + fprintf(stderr, " to { "); + to->debug_print(); + fprintf(stderr, " }"); + } +} + +void limit_box::check_tabs(int level) +{ + if (to) + to->check_tabs(level + 1); + if (from) + from->check_tabs(level + 1); + p->check_tabs(level + 1); +} diff --git a/src/preproc/eqn/list.cpp b/src/preproc/eqn/list.cpp new file mode 100644 index 0000000..52644c5 --- /dev/null +++ b/src/preproc/eqn/list.cpp @@ -0,0 +1,241 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "eqn.h" +#include "pbox.h" + +list_box *box::to_list_box() +{ + return 0; +} + +list_box *list_box::to_list_box() +{ + return this; +} + +void list_box::append(box *pp) +{ + list_box *q = pp->to_list_box(); + if (q == 0) + list.append(pp); + else { + for (int i = 0; i < q->list.len; i++) { + list.append(q->list.p[i]); + q->list.p[i] = 0; + } + q->list.len = 0; + delete q; + } +} + +list_box::list_box(box *pp) : list(pp), sty(-1) +{ + list_box *q = pp->to_list_box(); + if (q != 0) { + // flatten it + list.p[0] = q->list.p[0]; + for (int i = 1; i < q->list.len; i++) { + list.append(q->list.p[i]); + q->list.p[i] = 0; + } + q->list.len = 0; + delete q; + } +} + +static int compute_spacing(int is_script, int left, int right) +{ + if (left == SUPPRESS_TYPE || right == SUPPRESS_TYPE) + return 0; + if (left == PUNCTUATION_TYPE) + return is_script ? 0 : thin_space; + if (left == OPENING_TYPE || right == CLOSING_TYPE) + return 0; + if (right == BINARY_TYPE || left == BINARY_TYPE) + return is_script ? 0 : medium_space; + if (right == RELATION_TYPE) { + if (left == RELATION_TYPE) + return 0; + else + return is_script ? 0 : thick_space; + } + if (left == RELATION_TYPE) + return is_script ? 0 : thick_space; + if (right == OPERATOR_TYPE) + return thin_space; + if (left == INNER_TYPE || right == INNER_TYPE) + return is_script ? 0 : thin_space; + if (left == OPERATOR_TYPE && right == ORDINARY_TYPE) + return thin_space; + return 0; +} + +int list_box::compute_metrics(int style) +{ + sty = style; + int i; + for (i = 0; i < list.len; i++) { + int t = list.p[i]->spacing_type; + // 5 + if (t == BINARY_TYPE) { + int prevt; + if (i == 0 + || (prevt = list.p[i-1]->spacing_type) == BINARY_TYPE + || prevt == OPERATOR_TYPE + || prevt == RELATION_TYPE + || prevt == OPENING_TYPE + || prevt == SUPPRESS_TYPE + || prevt == PUNCTUATION_TYPE) + list.p[i]->spacing_type = ORDINARY_TYPE; + } + // 7 + else if ((t == RELATION_TYPE || t == CLOSING_TYPE + || t == PUNCTUATION_TYPE) + && i > 0 && list.p[i-1]->spacing_type == BINARY_TYPE) + list.p[i-1]->spacing_type = ORDINARY_TYPE; + } + for (i = 0; i < list.len; i++) { + unsigned flags = 0; + if (i - 1 >= 0 && list.p[i - 1]->right_is_italic()) + flags |= HINT_PREV_IS_ITALIC; + if (i + 1 < list.len && list.p[i + 1]->left_is_italic()) + flags |= HINT_NEXT_IS_ITALIC; + if (flags) + list.p[i]->hint(flags); + } + is_script = (style <= SCRIPT_STYLE); + int total_spacing = 0; + for (i = 1; i < list.len; i++) + total_spacing += compute_spacing(is_script, list.p[i-1]->spacing_type, + list.p[i]->spacing_type); + int res = 0; + for (i = 0; i < list.len; i++) + if (!list.p[i]->is_simple()) { + int r = list.p[i]->compute_metrics(style); + if (r) { + if (res) + error("multiple marks and lineups"); + else { + compute_sublist_width(i); + printf(".nr " MARK_REG " +\\n[" TEMP_REG"]\n"); + res = r; + } + } + } + printf(".nr " WIDTH_FORMAT " %dM", uid, total_spacing); + for (i = 0; i < list.len; i++) + if (!list.p[i]->is_simple()) + printf("+\\n[" WIDTH_FORMAT "]", list.p[i]->uid); + printf("\n"); + printf(".nr " HEIGHT_FORMAT " 0", uid); + for (i = 0; i < list.len; i++) + if (!list.p[i]->is_simple()) + printf(">?\\n[" HEIGHT_FORMAT "]", list.p[i]->uid); + printf("\n"); + printf(".nr " DEPTH_FORMAT " 0", uid); + for (i = 0; i < list.len; i++) + if (!list.p[i]->is_simple()) + printf(">?\\n[" DEPTH_FORMAT "]", list.p[i]->uid); + printf("\n"); + int have_simple = 0; + for (i = 0; i < list.len && !have_simple; i++) + have_simple = list.p[i]->is_simple(); + if (have_simple) { + printf(".nr " WIDTH_FORMAT " +\\w" DELIMITER_CHAR, uid); + for (i = 0; i < list.len; i++) + if (list.p[i]->is_simple()) + list.p[i]->output(); + printf(DELIMITER_CHAR "\n"); + printf(".nr " HEIGHT_FORMAT " \\n[rst]>?\\n[" HEIGHT_FORMAT "]\n", + uid, uid); + printf(".nr " DEPTH_FORMAT " 0-\\n[rsb]>?\\n[" DEPTH_FORMAT "]\n", + uid, uid); + } + return res; +} + +void list_box::compute_sublist_width(int n) +{ + int total_spacing = 0; + int i; + for (i = 1; i < n + 1 && i < list.len; i++) + total_spacing += compute_spacing(is_script, list.p[i-1]->spacing_type, + list.p[i]->spacing_type); + printf(".nr " TEMP_REG " %dM", total_spacing); + for (i = 0; i < n; i++) + if (!list.p[i]->is_simple()) + printf("+\\n[" WIDTH_FORMAT "]", list.p[i]->uid); + int have_simple = 0; + for (i = 0; i < n && !have_simple; i++) + have_simple = list.p[i]->is_simple(); + if (have_simple) { + printf("+\\w" DELIMITER_CHAR); + for (i = 0; i < n; i++) + if (list.p[i]->is_simple()) + list.p[i]->output(); + printf(DELIMITER_CHAR); + } + printf("\n"); +} + +void list_box::compute_subscript_kern() +{ + // We can only call compute_subscript_kern if we have called + // compute_metrics first. + if (list.p[list.len-1]->is_simple()) + list.p[list.len-1]->compute_metrics(sty); + list.p[list.len-1]->compute_subscript_kern(); + printf(".nr " SUB_KERN_FORMAT " \\n[" SUB_KERN_FORMAT "]\n", + uid, list.p[list.len-1]->uid); +} + +void list_box::output() +{ + if (output_format == mathml) + printf(""); + for (int i = 0; i < list.len; i++) { + if (output_format == troff && i > 0) { + int n = compute_spacing(is_script, + list.p[i-1]->spacing_type, + list.p[i]->spacing_type); + if (n > 0) + printf("\\h'%dM'", n); + } + list.p[i]->output(); + } + if (output_format == mathml) + printf(""); +} + +void list_box::handle_char_type(int st, int ft) +{ + for (int i = 0; i < list.len; i++) + list.p[i]->handle_char_type(st, ft); +} + +void list_box::debug_print() +{ + list.list_debug_print(" "); +} + +void list_box::check_tabs(int level) +{ + list.list_check_tabs(level); +} diff --git a/src/preproc/eqn/main.cpp b/src/preproc/eqn/main.cpp new file mode 100644 index 0000000..81d5184 --- /dev/null +++ b/src/preproc/eqn/main.cpp @@ -0,0 +1,485 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "eqn.h" +#include "stringclass.h" +#include "device.h" +#include "searchpath.h" +#include "macropath.h" +#include "htmlhint.h" +#include "pbox.h" +#include "ctype.h" +#include "lf.h" + +#define STARTUP_FILE "eqnrc" + +extern int yyparse(); +extern "C" const char *Version_string; + +static char *delim_search (char *, int); +static int inline_equation (FILE *, string &, string &); + +char start_delim = '\0'; +char end_delim = '\0'; +int non_empty_flag; +int inline_flag; +int draw_flag = 0; +int one_size_reduction_flag = 0; +int compatible_flag = 0; +int no_newline_in_delim_flag = 0; +int html = 0; +int xhtml = 0; +eqnmode_t output_format; + +static const char *input_char_description(int c) +{ + switch (c) { + case '\001': + return "a leader character"; + case '\n': + return "a newline character"; + case '\b': + return "a backspace character"; + case '\t': + return "a tab character"; + case ' ': + return "a space character"; + case '\177': + return "a delete character"; + } + size_t bufsz = sizeof "character code " + INT_DIGITS + 1; + // repeat expression; no VLAs in ISO C++ + static char buf[sizeof "character code " + INT_DIGITS + 1]; + (void) memset(buf, 0, bufsz); + if (csprint(c)) { + buf[0] = '\''; + buf[1] = c; + buf[2] = '\''; + return buf; + } + (void) sprintf(buf, "character code %d", c); + return buf; +} + +static bool read_line(FILE *fp, string *p) +{ + p->clear(); + int c = -1; + while ((c = getc(fp)) != EOF) { + if (!is_invalid_input_char(c)) + *p += char(c); + else + error("invalid input (%1)", input_char_description(c)); + if (c == '\n') + break; + } + return (p->length() > 0); +} + +void do_file(FILE *fp, const char *filename) +{ + string linebuf; + string str; + string fn(filename); + fn += '\0'; + normalize_for_lf(fn); + current_filename = fn.contents(); + if (output_format == troff) + printf(".lf 1 %s\n", current_filename); + current_lineno = 1; + while (read_line(fp, &linebuf)) { + if (linebuf.length() >= 4 + && linebuf[0] == '.' && linebuf[1] == 'l' && linebuf[2] == 'f' + && (linebuf[3] == ' ' || linebuf[3] == '\n' || compatible_flag)) + { + put_string(linebuf, stdout); + linebuf += '\0'; + // In GNU roff, `lf` assigns the number of the _next_ line. + if (interpret_lf_args(linebuf.contents() + 3)) + current_lineno--; + } + else if (linebuf.length() >= 4 + && linebuf[0] == '.' + && linebuf[1] == 'E' + && linebuf[2] == 'Q' + && (linebuf[3] == ' ' || linebuf[3] == '\n' + || compatible_flag)) { + put_string(linebuf, stdout); + int start_lineno = current_lineno + 1; + str.clear(); + for (;;) { + if (!read_line(fp, &linebuf)) { + current_lineno = 0; // suppress report of line number + fatal("end of file before .EN"); + } + if (linebuf.length() >= 3 + && linebuf[0] == '.' + && linebuf[1] == 'E') { + if (linebuf[2] == 'N' + && (linebuf.length() == 3 || linebuf[3] == ' ' + || linebuf[3] == '\n' || compatible_flag)) + break; + else if (linebuf[2] == 'Q' && linebuf.length() > 3 + && (linebuf[3] == ' ' || linebuf[3] == '\n' + || compatible_flag)) { + current_lineno++; // We just read another line. + fatal("equations cannot be nested (.EQ within .EQ)"); + } + } + str += linebuf; + } + str += '\0'; + start_string(); + init_lex(str.contents(), current_filename, start_lineno); + non_empty_flag = 0; + inline_flag = 0; + yyparse(); + restore_compatibility(); + if (non_empty_flag) { + if (output_format == mathml) + putchar('\n'); + else { + current_lineno++; + printf(".lf %d\n", current_lineno); + output_string(); + } + } + if (output_format == troff) { + current_lineno++; + printf(".lf %d\n", current_lineno); + } + put_string(linebuf, stdout); + } + else if (start_delim != '\0' && linebuf.search(start_delim) >= 0 + && inline_equation(fp, linebuf, str)) + ; + else + put_string(linebuf, stdout); + current_lineno++; + } + current_filename = 0; + current_lineno = 0; +} + +// Handle an inline equation. Return 1 if it was an inline equation, +// otherwise. +static int inline_equation(FILE *fp, string &linebuf, string &str) +{ + linebuf += '\0'; + char *ptr = &linebuf[0]; + char *start = delim_search(ptr, start_delim); + if (!start) { + // It wasn't a delimiter after all. + linebuf.set_length(linebuf.length() - 1); // strip the '\0' + return 0; + } + start_string(); + inline_flag = 1; + for (;;) { + if (no_newline_in_delim_flag && strchr(start + 1, end_delim) == 0) { + error("unterminated inline equation; started with %1," + " expecting %2", input_char_description(start_delim), + input_char_description(end_delim)); + char *nl = strchr(start + 1, '\n'); + if (nl != 0) + *nl = '\0'; + do_text(ptr); + break; + } + int start_lineno = current_lineno; + *start = '\0'; + do_text(ptr); + ptr = start + 1; + str.clear(); + for (;;) { + char *end = strchr(ptr, end_delim); + if (end != 0) { + *end = '\0'; + str += ptr; + ptr = end + 1; + break; + } + str += ptr; + if (!read_line(fp, &linebuf)) + fatal("unterminated inline equation; started with %1," + " expecting %2", input_char_description(start_delim), + input_char_description(end_delim)); + linebuf += '\0'; + ptr = &linebuf[0]; + } + str += '\0'; + if (output_format == troff && html) { + printf(".as1 %s ", LINE_STRING); + html_begin_suppress(); + printf("\n"); + } + init_lex(str.contents(), current_filename, start_lineno); + yyparse(); + if (output_format == troff && html) { + printf(".as1 %s ", LINE_STRING); + html_end_suppress(); + printf("\n"); + } + if (output_format == mathml) + printf("\n"); + if (xhtml) { + /* skip leading spaces */ + while ((*ptr != '\0') && (*ptr == ' ')) + ptr++; + } + start = delim_search(ptr, start_delim); + if (start == 0) { + char *nl = strchr(ptr, '\n'); + if (nl != 0) + *nl = '\0'; + do_text(ptr); + break; + } + } + restore_compatibility(); + if (output_format == troff) + printf(".lf %d\n", current_lineno); + output_string(); + if (output_format == troff) + printf(".lf %d\n", current_lineno + 1); + return 1; +} + +/* Search for delim. Skip over number register and string names etc. */ + +static char *delim_search(char *ptr, int delim) +{ + while (*ptr) { + if (*ptr == delim) + return ptr; + if (*ptr++ == '\\') { + switch (*ptr) { + case 'n': + case '*': + case 'f': + case 'g': + case 'k': + switch (*++ptr) { + case '\0': + case '\\': + break; + case '(': + if (*++ptr != '\\' && *ptr != '\0' + && *++ptr != '\\' && *ptr != '\0') + ptr++; + break; + case '[': + while (*++ptr != '\0') + if (*ptr == ']') { + ptr++; + break; + } + break; + default: + ptr++; + break; + } + break; + case '\\': + case '\0': + break; + default: + ptr++; + break; + } + } + } + return 0; +} + +void usage(FILE *stream) +{ + fprintf(stream, + "usage: %s [-CNrR] [-d xy] [-f font] [-m n] [-M dir] [-p n] [-s n]" + " [-T name] [file ...]\n" + "usage: %s {-v | --version}\n" + "usage: %s --help\n", + program_name, program_name, program_name); +} + +int main(int argc, char **argv) +{ + program_name = argv[0]; + static char stderr_buf[BUFSIZ]; + setbuf(stderr, stderr_buf); + int opt; + int load_startup_file = 1; + static const struct option long_options[] = { + { "help", no_argument, 0, CHAR_MAX + 1 }, + { "version", no_argument, 0, 'v' }, + { NULL, 0, 0, 0 } + }; + while ((opt = getopt_long(argc, argv, "CNrRd:f:m:M:p:s:T:v", + long_options, NULL)) + != EOF) + switch (opt) { + case 'C': + compatible_flag = 1; + break; + case 'R': // don't load eqnrc + load_startup_file = 0; + break; + case 'M': + config_macro_path.command_line_dir(optarg); + break; + case 'v': + printf("GNU eqn (groff) version %s\n", Version_string); + exit(EXIT_SUCCESS); + break; + case 'd': + if (optarg[0] == '\0' || optarg[1] == '\0') + error("'-d' option requires a two-character argument"); + else if (is_invalid_input_char(optarg[0])) + error("invalid delimiter (%1) in '-d' option argument", + input_char_description(optarg[0])); + else if (is_invalid_input_char(optarg[1])) + error("invalid delimiter (%1) in '-d' option argument", + input_char_description(optarg[1])); + else { + start_delim = optarg[0]; + end_delim = optarg[1]; + } + break; + case 'f': + set_gfont(optarg); + break; + case 'T': + device = optarg; + if (strcmp(device, "ps:html") == 0) { + device = "ps"; + html = 1; + } + else if (strcmp(device, "MathML") == 0) { + output_format = mathml; + load_startup_file = 0; + } + else if (strcmp(device, "mathml:xhtml") == 0) { + device = "MathML"; + output_format = mathml; + load_startup_file = 0; + xhtml = 1; + } + break; + case 's': + if (set_gsize(optarg)) + warning("option '-s' is deprecated"); + else + error("invalid size '%1' in '-s' option argument ", optarg); + break; + case 'p': + { + int n; + if (sscanf(optarg, "%d", &n) == 1) { + warning("option '-p' is deprecated"); + set_script_reduction(n); + } + else + error("invalid size '%1' in '-p' option argument ", optarg); + } + break; + case 'm': + { + int n; + if (sscanf(optarg, "%d", &n) == 1) + set_minimum_size(n); + else + error("invalid size '%1' in '-n' option argument", optarg); + } + break; + case 'r': + one_size_reduction_flag = 1; + break; + case 'N': + no_newline_in_delim_flag = 1; + break; + case CHAR_MAX + 1: // --help + usage(stdout); + exit(EXIT_SUCCESS); + break; + case '?': + usage(stderr); + exit(EXIT_FAILURE); + break; + default: + assert(0 == "unhandled getopt_long return value"); + } + init_table(device); + init_char_table(); + printf(".do if !dEQ .ds EQ\n" + ".do if !dEN .ds EN\n"); + if (output_format == troff) { + printf(".if !'\\*(.T'%s' " + ".if !'\\*(.T'html' " // the html device uses '-Tps' to render + // equations as images + ".tm warning: %s should have been given a '-T\\*(.T' option\n", + device, program_name); + printf(".if '\\*(.T'html' " + ".if !'%s'ps' " + ".tm warning: %s should have been given a '-Tps' option\n", + device, program_name); + printf(".if '\\*(.T'html' " + ".if !'%s'ps' " + ".tm warning: (it is advisable to invoke groff via: groff -Thtml -e)\n", + device); + } + if (load_startup_file) { + char *path; + FILE *fp = config_macro_path.open_file(STARTUP_FILE, &path); + if (fp) { + do_file(fp, path); + if (fclose(fp) < 0) + fatal("unable to close '%1': %2", STARTUP_FILE, + strerror(errno)); + free(path); + } + } + if (optind >= argc) + do_file(stdin, "-"); + else + for (int i = optind; i < argc; i++) + if (strcmp(argv[i], "-") == 0) + do_file(stdin, "-"); + else { + errno = 0; + FILE *fp = fopen(argv[i], "r"); + if (!fp) + fatal("unable to open '%1': %2", argv[i], strerror(errno)); + else { + do_file(fp, argv[i]); + if (fclose(fp) < 0) + fatal("unable to close '%1': %2", argv[i], strerror(errno)); + } + } + if (ferror(stdout)) + fatal("standard output stream is in an error state"); + if (fflush(stdout) < 0) + fatal("unable to flush standard output stream: %1", + strerror(errno)); + exit(EXIT_SUCCESS); +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/eqn/mark.cpp b/src/preproc/eqn/mark.cpp new file mode 100644 index 0000000..9427b10 --- /dev/null +++ b/src/preproc/eqn/mark.cpp @@ -0,0 +1,120 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "eqn.h" +#include "pbox.h" + +class mark_box : public pointer_box { +public: + mark_box(box *); + int compute_metrics(int); + void output(); + void debug_print(); +}; + +// we push down marks so that they don't interfere with spacing + +box *make_mark_box(box *p) +{ + list_box *b = p->to_list_box(); + if (b != 0) { + b->list.p[0] = make_mark_box(b->list.p[0]); + return b; + } + else + return new mark_box(p); +} + +mark_box::mark_box(box *pp) : pointer_box(pp) +{ +} + +void mark_box::output() +{ + p->output(); +} + +int mark_box::compute_metrics(int style) +{ + int res = p->compute_metrics(style); + if (res) + error("multiple marks and lineups"); + printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid); + printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid); + printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid); + printf(".nr " MARK_REG " 0\n"); + return FOUND_MARK; +} + +void mark_box::debug_print() +{ + fprintf(stderr, "mark { "); + p->debug_print(); + fprintf(stderr, " }"); +} + + +class lineup_box : public pointer_box { +public: + lineup_box(box *); + void output(); + int compute_metrics(int style); + void debug_print(); +}; + +// we push down lineups so that they don't interfere with spacing + +box *make_lineup_box(box *p) +{ + list_box *b = p->to_list_box(); + if (b != 0) { + b->list.p[0] = make_lineup_box(b->list.p[0]); + return b; + } + else + return new lineup_box(p); +} + +lineup_box::lineup_box(box *pp) : pointer_box(pp) +{ +} + +void lineup_box::output() +{ + p->output(); +} + +int lineup_box::compute_metrics(int style) +{ + int res = p->compute_metrics(style); + if (res) + error("multiple marks and lineups"); + printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid); + printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid); + printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid); + printf(".nr " MARK_REG " 0\n"); + return FOUND_LINEUP; +} + +void lineup_box::debug_print() +{ + fprintf(stderr, "lineup { "); + p->debug_print(); + fprintf(stderr, " }"); +} diff --git a/src/preproc/eqn/neqn.1.man b/src/preproc/eqn/neqn.1.man new file mode 100644 index 0000000..758a150 --- /dev/null +++ b/src/preproc/eqn/neqn.1.man @@ -0,0 +1,92 @@ +.TH @g@neqn @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +@g@neqn \- format equations for character-cell terminal output +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 2001-2020 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_neqn_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY @g@neqn +.RI [ @g@eqn-argument \~.\|.\|.] +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I @g@neqn +invokes the +.MR @g@eqn @MAN1EXT@ +command with the +.B ascii +output device. +. +. +.LP +.I @g@eqn +does not support low-resolution, +typewriter-like devices, +although it may work adequately for very simple input. +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.MR @g@eqn @MAN1EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_neqn_1_man_C] +.do rr *groff_neqn_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=nroff textwidth=72: diff --git a/src/preproc/eqn/neqn.sh b/src/preproc/eqn/neqn.sh new file mode 100644 index 0000000..fb8d616 --- /dev/null +++ b/src/preproc/eqn/neqn.sh @@ -0,0 +1,26 @@ +#! /bin/sh +# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# +# This file 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 2 of the License (GPL2). +# +# 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. +# +# The GPL2 license text is available in the internet at +# . + +# Provision of this shell script should not be taken to imply that use of +# GNU eqn with groff -Tascii|-Tlatin1|-Tutf8|-Tcp1047 is supported. + +@GROFF_BIN_PATH_SETUP@ +PATH="$GROFF_RUNTIME$PATH" +export PATH +exec @g@eqn -Tascii ${1+"$@"} + +# eof diff --git a/src/preproc/eqn/other.cpp b/src/preproc/eqn/other.cpp new file mode 100644 index 0000000..1ddc8fb --- /dev/null +++ b/src/preproc/eqn/other.cpp @@ -0,0 +1,706 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "eqn.h" +#include "pbox.h" + +class accent_box : public pointer_box { +private: + box *ab; +public: + accent_box(box *, box *); + ~accent_box(); + int compute_metrics(int); + void output(); + void debug_print(); + void check_tabs(int); +}; + +box *make_accent_box(box *p, box *q) +{ + return new accent_box(p, q); +} + +accent_box::accent_box(box *pp, box *qq) : pointer_box(pp), ab(qq) +{ +} + +accent_box::~accent_box() +{ + delete ab; +} + +#if 0 +int accent_box::compute_metrics(int style) +{ + int r = p->compute_metrics(style); + p->compute_skew(); + ab->compute_metrics(style); + printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid); + printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid); + printf(".nr " SUP_RAISE_FORMAT " \\n[" HEIGHT_FORMAT "]-%dM>?0\n", + uid, p->uid, x_height); + printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]+\\n[" + SUP_RAISE_FORMAT "]\n", + uid, ab->uid, uid); + return r; +} + +void accent_box::output() +{ + if (output_format == troff) { + printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u+\\n[" + SKEW_FORMAT "]u'", + p->uid, ab->uid, p->uid); + printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid); + ab->output(); + printf("\\h'-\\n[" WIDTH_FORMAT "]u'", ab->uid); + printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid); + printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u+\\n[" + SKEW_FORMAT "]u)'", + p->uid, ab->uid, p->uid); + p->output(); + } + else if (output_format == mathml) { + printf(""); + p->output(); + ab->output(); + printf("") + } +} +#endif + +/* This version copes with the possibility of an accent's being wider +than its accentee. LEFT_WIDTH_FORMAT gives the distance from the +left edge of the resulting box to the middle of the accentee's box.*/ + +int accent_box::compute_metrics(int style) +{ + int r = p->compute_metrics(style); + p->compute_skew(); + ab->compute_metrics(style); + printf(".nr " LEFT_WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]/2" + ">?(\\n[" WIDTH_FORMAT "]/2-\\n[" SKEW_FORMAT "])\n", + uid, p->uid, ab->uid, p->uid); + printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]/2" + ">?(\\n[" WIDTH_FORMAT "]/2+\\n[" SKEW_FORMAT "])" + "+\\n[" LEFT_WIDTH_FORMAT "]\n", + uid, p->uid, ab->uid, p->uid, uid); + printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid); + printf(".nr " SUP_RAISE_FORMAT " \\n[" HEIGHT_FORMAT "]-%dM>?0\n", + uid, p->uid, x_height); + printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]+\\n[" + SUP_RAISE_FORMAT "]\n", + uid, ab->uid, uid); + if (r) + printf(".nr " MARK_REG " +\\n[" LEFT_WIDTH_FORMAT "]" + "-(\\n[" WIDTH_FORMAT "]/2)'\n", + uid, p->uid); + return r; +} + +void accent_box::output() +{ + if (output_format == troff) { + printf("\\Z" DELIMITER_CHAR); + printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u+\\n[" SKEW_FORMAT "]u" + "-(\\n[" WIDTH_FORMAT "]u/2u)'", + uid, p->uid, ab->uid); + printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid); + ab->output(); + printf(DELIMITER_CHAR); + printf("\\Z" DELIMITER_CHAR); + printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u-(\\n[" WIDTH_FORMAT "]u/2u)'", + uid, p->uid); + p->output(); + printf(DELIMITER_CHAR); + printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid); + } + else if (output_format == mathml) { + printf(""); + p->output(); + ab->output(); + printf(""); + } +} + +void accent_box::check_tabs(int level) +{ + ab->check_tabs(level + 1); + p->check_tabs(level + 1); +} + +void accent_box::debug_print() +{ + fprintf(stderr, "{ "); + p->debug_print(); + fprintf(stderr, " } accent { "); + ab->debug_print(); + fprintf(stderr, " }"); +} + +class overline_char_box : public simple_box { +public: + overline_char_box(); + void output(); + void debug_print(); +}; + +overline_char_box::overline_char_box() +{ +} + +void overline_char_box::output() +{ + if (output_format == troff) { + printf("\\v'-%dM/2u-%dM'", 7*default_rule_thickness, x_height); + printf((draw_flag ? "\\D'l%dM 0'" : "\\l'%dM\\&\\(ru'"), + accent_width); + printf("\\v'%dM/2u+%dM'", 7*default_rule_thickness, x_height); + } + else if (output_format == mathml) + printf("¯"); +} + +void overline_char_box::debug_print() +{ + fprintf(stderr, ""); +} + +class overline_box : public pointer_box { +public: + overline_box(box *); + int compute_metrics(int); + void output(); + void debug_print(); +}; + +box *make_overline_box(box *p) +{ + if (p->is_char()) + return new accent_box(p, new overline_char_box); + else + return new overline_box(p); +} + +overline_box::overline_box(box *pp) : pointer_box(pp) +{ +} + +int overline_box::compute_metrics(int style) +{ + int r = p->compute_metrics(cramped_style(style)); + // 9 + printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]+%dM\n", + uid, p->uid, default_rule_thickness*5); + printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid); + printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid); + return r; +} + +void overline_box::output() +{ + if (output_format == troff) { + // 9 + printf("\\Z" DELIMITER_CHAR); + printf("\\v'-\\n[" HEIGHT_FORMAT "]u-(%dM/2u)'", + p->uid, 7*default_rule_thickness); + if (draw_flag) + printf("\\D'l\\n[" WIDTH_FORMAT "]u 0'", p->uid); + else + printf("\\l'\\n[" WIDTH_FORMAT "]u\\&\\(ru'", p->uid); + printf(DELIMITER_CHAR); + p->output(); + } + else if (output_format == mathml) { + printf(""); + p->output(); + printf("¯"); + } +} + +void overline_box::debug_print() +{ + fprintf(stderr, "{ "); + p->debug_print(); + fprintf(stderr, " } bar"); +} + +class uaccent_box : public pointer_box { + box *ab; +public: + uaccent_box(box *, box *); + ~uaccent_box(); + int compute_metrics(int); + void output(); + void compute_subscript_kern(); + void check_tabs(int); + void debug_print(); +}; + +box *make_uaccent_box(box *p, box *q) +{ + return new uaccent_box(p, q); +} + +uaccent_box::uaccent_box(box *pp, box *qq) +: pointer_box(pp), ab(qq) +{ +} + +uaccent_box::~uaccent_box() +{ + delete ab; +} + +int uaccent_box::compute_metrics(int style) +{ + int r = p->compute_metrics(style); + ab->compute_metrics(style); + printf(".nr " LEFT_WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]/2" + ">?(\\n[" WIDTH_FORMAT "]/2)\n", + uid, p->uid, ab->uid); + printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]/2" + ">?(\\n[" WIDTH_FORMAT "]/2)" + "+\\n[" LEFT_WIDTH_FORMAT "]\n", + uid, p->uid, ab->uid, uid); + printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid); + printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]" + "+\\n[" DEPTH_FORMAT "]\n", + uid, p->uid, ab->uid); + if (r) + printf(".nr " MARK_REG " +\\n[" LEFT_WIDTH_FORMAT "]" + "-(\\n[" WIDTH_FORMAT "]/2)'\n", + uid, p->uid); + return r; +} + +void uaccent_box::output() +{ + if (output_format == troff) { + printf("\\Z" DELIMITER_CHAR); + printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u-(\\n[" WIDTH_FORMAT "]u/2u)'", + uid, ab->uid); + printf("\\v'\\n[" DEPTH_FORMAT "]u'", p->uid); + ab->output(); + printf(DELIMITER_CHAR); + printf("\\Z" DELIMITER_CHAR); + printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u-(\\n[" WIDTH_FORMAT "]u/2u)'", + uid, p->uid); + p->output(); + printf(DELIMITER_CHAR); + printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid); + } + else if (output_format == mathml) { + printf(""); + p->output(); + ab->output(); + printf(""); + } +} + +void uaccent_box::check_tabs(int level) +{ + ab->check_tabs(level + 1); + p->check_tabs(level + 1); +} + +void uaccent_box::compute_subscript_kern() +{ + box::compute_subscript_kern(); // want 0 subscript kern +} + +void uaccent_box::debug_print() +{ + fprintf(stderr, "{ "); + p->debug_print(); + fprintf(stderr, " } uaccent { "); + ab->debug_print(); + fprintf(stderr, " }"); +} + +class underline_char_box : public simple_box { +public: + underline_char_box(); + void output(); + void debug_print(); +}; + +underline_char_box::underline_char_box() +{ +} + +void underline_char_box::output() +{ + if (output_format == troff) { + printf("\\v'%dM/2u'", 7*default_rule_thickness); + printf((draw_flag ? "\\D'l%dM 0'" : "\\l'%dM\\&\\(ru'"), + accent_width); + printf("\\v'-%dM/2u'", 7*default_rule_thickness); + } + else if (output_format == mathml) + printf("_"); +} + +void underline_char_box::debug_print() +{ + fprintf(stderr, ""); +} + + +class underline_box : public pointer_box { +public: + underline_box(box *); + int compute_metrics(int); + void output(); + void compute_subscript_kern(); + void debug_print(); +}; + +box *make_underline_box(box *p) +{ + if (p->is_char()) + return new uaccent_box(p, new underline_char_box); + else + return new underline_box(p); +} + +underline_box::underline_box(box *pp) : pointer_box(pp) +{ +} + +int underline_box::compute_metrics(int style) +{ + int r = p->compute_metrics(style); + // 10 + printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]+%dM\n", + uid, p->uid, default_rule_thickness*5); + printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid); + printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid); + return r; +} + +void underline_box::output() +{ + if (output_format == troff) { + // 10 + printf("\\Z" DELIMITER_CHAR); + printf("\\v'\\n[" DEPTH_FORMAT "]u+(%dM/2u)'", + p->uid, 7*default_rule_thickness); + if (draw_flag) + printf("\\D'l\\n[" WIDTH_FORMAT "]u 0'", p->uid); + else + printf("\\l'\\n[" WIDTH_FORMAT "]u\\&\\(ru'", p->uid); + printf(DELIMITER_CHAR); + p->output(); + } + else if (output_format == mathml) { + printf(""); + p->output(); + printf("¯"); + } +} + +// we want an underline box to have 0 subscript kern + +void underline_box::compute_subscript_kern() +{ + box::compute_subscript_kern(); +} + +void underline_box::debug_print() +{ + fprintf(stderr, "{ "); + p->debug_print(); + fprintf(stderr, " } under"); +} + +size_box::size_box(char *s, box *pp) : pointer_box(pp), size(s) +{ +} + +int size_box::compute_metrics(int style) +{ + printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid); + printf(".ps %s\n", size); + printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid); + int r = p->compute_metrics(style); + printf(".ps \\n[" SIZE_FORMAT "]u\n", uid); + printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid); + printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid); + printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid); + return r; +} + +void size_box::output() +{ + if (output_format == troff) { + printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid); + p->output(); + printf("\\s[\\n[" SIZE_FORMAT "]u]", uid); + } + else if (output_format == mathml) { + printf("", size); + p->output(); + printf(""); + } +} + +size_box::~size_box() +{ + free(size); +} + +void size_box::debug_print() +{ + fprintf(stderr, "size %s { ", size); + p->debug_print(); + fprintf(stderr, " }"); +} + + +font_box::font_box(char *s, box *pp) : pointer_box(pp), f(s) +{ +} + +font_box::~font_box() +{ + free(f); +} + +int font_box::compute_metrics(int style) +{ + const char *old_roman_font = current_roman_font; + current_roman_font = f; + printf(".nr " FONT_FORMAT " \\n[.f]\n", uid); + printf(".ft %s\n", f); + int r = p->compute_metrics(style); + current_roman_font = old_roman_font; + printf(".ft \\n[" FONT_FORMAT "]\n", uid); + printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid); + printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid); + printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid); + return r; +} + +void font_box::output() +{ + if (output_format == troff) { + printf("\\f[%s]", f); + const char *old_roman_font = current_roman_font; + current_roman_font = f; + p->output(); + current_roman_font = old_roman_font; + printf("\\f[\\n[" FONT_FORMAT "]]", uid); + } + else if (output_format == mathml) { + const char *mlfont = f; + // bold and italic are already in MathML; translate eqn roman here + switch (f[0]) { + case 'I': + case 'i': + mlfont = "italic"; + break; + case 'B': + case 'b': + mlfont = "bold"; + break; + case 'R': + case 'r': + default: + mlfont = "normal"; + break; + } + printf("", mlfont); + p->output(); + printf(""); + } +} + +void font_box::debug_print() +{ + fprintf(stderr, "font %s { ", f); + p->debug_print(); + fprintf(stderr, " }"); +} + +fat_box::fat_box(box *pp) : pointer_box(pp) +{ +} + +int fat_box::compute_metrics(int style) +{ + int r = p->compute_metrics(style); + printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]+%dM\n", + uid, p->uid, fat_offset); + printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid); + printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid); + return r; +} + +void fat_box::output() +{ + if (output_format == troff) { + p->output(); + printf("\\h'-\\n[" WIDTH_FORMAT "]u'", p->uid); + printf("\\h'%dM'", fat_offset); + p->output(); + } + else if (output_format == mathml) { + printf(""); + p->output(); + printf(""); + } +} + + +void fat_box::debug_print() +{ + fprintf(stderr, "fat { "); + p->debug_print(); + fprintf(stderr, " }"); +} + + +vmotion_box::vmotion_box(int i, box *pp) : pointer_box(pp), n(i) +{ +} + +int vmotion_box::compute_metrics(int style) +{ + int r = p->compute_metrics(style); + printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid); + if (n > 0) { + printf(".nr " HEIGHT_FORMAT " %dM+\\n[" HEIGHT_FORMAT "]\n", + uid, n, p->uid); + printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid); + } + else { + printf(".nr " DEPTH_FORMAT " %dM+\\n[" DEPTH_FORMAT "]>?0\n", + uid, -n, p->uid); + printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", + uid, p->uid); + } + return r; +} + +void vmotion_box::output() +{ + if (output_format == troff) { + printf("\\v'%dM'", -n); + p->output(); + printf("\\v'%dM'", n); + } + else if (output_format == mathml) { + printf("eqn vertical motion cannot be expressed " + "in MathML"); + p->output(); + } +} + +void vmotion_box::debug_print() +{ + if (n >= 0) + fprintf(stderr, "up %d { ", n); + else + fprintf(stderr, "down %d { ", -n); + p->debug_print(); + fprintf(stderr, " }"); +} + +hmotion_box::hmotion_box(int i, box *pp) : pointer_box(pp), n(i) +{ +} + +int hmotion_box::compute_metrics(int style) +{ + int r = p->compute_metrics(style); + printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]+%dM\n", + uid, p->uid, n); + printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid); + printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid); + if (r) + printf(".nr " MARK_REG " +%dM\n", n); + return r; +} + +void hmotion_box::output() +{ + if (output_format == troff) { + printf("\\h'%dM'", n); + p->output(); + } + else if (output_format == mathml) { + printf("eqn horizontal motion cannot be expressed " + "in MathML"); + p->output(); + } +} + +void hmotion_box::debug_print() +{ + if (n >= 0) + fprintf(stderr, "fwd %d { ", n); + else + fprintf(stderr, "back %d { ", -n); + p->debug_print(); + fprintf(stderr, " }"); +} + +vcenter_box::vcenter_box(box *pp) : pointer_box(pp) +{ +} + +int vcenter_box::compute_metrics(int style) +{ + int r = p->compute_metrics(style); + printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid); + printf(".nr " SUP_RAISE_FORMAT " \\n[" DEPTH_FORMAT "]-\\n[" + HEIGHT_FORMAT "]/2+%dM\n", + uid, p->uid, p->uid, axis_height); + printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]+\\n[" + SUP_RAISE_FORMAT "]>?0\n", uid, p->uid, uid); + printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]-\\n[" + SUP_RAISE_FORMAT "]>?0\n", uid, p->uid, uid); + + return r; +} + +void vcenter_box::output() +{ + if (output_format == troff) + printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid); + p->output(); + if (output_format == troff) + printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid); +} + +void vcenter_box::debug_print() +{ + fprintf(stderr, "vcenter { "); + p->debug_print(); + fprintf(stderr, " }"); +} + diff --git a/src/preproc/eqn/over.cpp b/src/preproc/eqn/over.cpp new file mode 100644 index 0000000..6a9cd9b --- /dev/null +++ b/src/preproc/eqn/over.cpp @@ -0,0 +1,204 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "eqn.h" +#include "pbox.h" + +class over_box : public box { +private: + int reduce_size; + box *num; + box *den; +public: + over_box(int small, box *, box *); + ~over_box(); + void debug_print(); + int compute_metrics(int); + void output(); + void check_tabs(int); +}; + +box *make_over_box(box *pp, box *qq) +{ + return new over_box(0, pp, qq); +} + +box *make_small_over_box(box *pp, box *qq) +{ + return new over_box(1, pp, qq); +} + +over_box::over_box(int is_small, box *pp, box *qq) +: reduce_size(is_small), num(pp), den(qq) +{ + spacing_type = INNER_TYPE; +} + +over_box::~over_box() +{ + delete num; + delete den; +} + +int over_box::compute_metrics(int style) +{ + if (reduce_size) { + style = script_style(style); + printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid); + set_script_size(); + printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid); + } + int mark_uid = 0; + int res = num->compute_metrics(style); + if (res) + mark_uid = num->uid; + int r = den->compute_metrics(cramped_style(style)); + if (r && res) + error("multiple marks and lineups"); + else { + mark_uid = den->uid; + res = r; + } + if (reduce_size) + printf(".ps \\n[" SIZE_FORMAT "]u\n", uid); + printf(".nr " WIDTH_FORMAT " (\\n[" WIDTH_FORMAT "]>?\\n[" WIDTH_FORMAT "]", + uid, num->uid, den->uid); + // allow for \(ru being wider than both the numerator and denominator + if (!draw_flag) + fputs(">?\\w" DELIMITER_CHAR "\\(ru" DELIMITER_CHAR, stdout); + printf(")+%dM\n", null_delimiter_space*2 + over_hang*2); + // 15b + printf(".nr " SUP_RAISE_FORMAT " %dM\n", + uid, (reduce_size ? num2 : num1)); + printf(".nr " SUB_LOWER_FORMAT " %dM\n", + uid, (reduce_size ? denom2 : denom1)); + + // 15d + printf(".nr " SUP_RAISE_FORMAT " +(\\n[" DEPTH_FORMAT + "]-\\n[" SUP_RAISE_FORMAT "]+%dM+(%dM/2)+%dM)>?0\n", + uid, num->uid, uid, axis_height, default_rule_thickness, + default_rule_thickness*(reduce_size ? 1 : 3)); + printf(".nr " SUB_LOWER_FORMAT " +(\\n[" HEIGHT_FORMAT + "]-\\n[" SUB_LOWER_FORMAT "]-%dM+(%dM/2)+%dM)>?0\n", + uid, den->uid, uid, axis_height, default_rule_thickness, + default_rule_thickness*(reduce_size ? 1 : 3)); + + + printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n[" + HEIGHT_FORMAT "]\n", + uid, uid, num->uid); + printf(".nr " DEPTH_FORMAT " \\n[" SUB_LOWER_FORMAT "]+\\n[" + DEPTH_FORMAT "]\n", + uid, uid, den->uid); + if (res) + printf(".nr " MARK_REG " +(\\n[" WIDTH_FORMAT "]-\\n[" + WIDTH_FORMAT "]/2)\n", uid, mark_uid); + return res; +} + +#define USE_Z + +void over_box::output() +{ + if (output_format == troff) { + if (reduce_size) + printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid); + #ifdef USE_Z + printf("\\Z" DELIMITER_CHAR); + #endif + // move up to the numerator baseline + printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid); + // move across so that it's centered + printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'", + uid, num->uid); + + // print the numerator + num->output(); + + #ifdef USE_Z + printf(DELIMITER_CHAR); + #else + // back again + printf("\\h'-\\n[" WIDTH_FORMAT "]u'", num->uid); + printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'", + uid, num->uid); + // down again + printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid); + #endif + #ifdef USE_Z + printf("\\Z" DELIMITER_CHAR); + #endif + // move down to the denominator baseline + printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid); + + // move across so that it's centered + printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'", + uid, den->uid); + + // print the denominator + den->output(); + + #ifdef USE_Z + printf(DELIMITER_CHAR); + #else + // back again + printf("\\h'-\\n[" WIDTH_FORMAT "]u'", den->uid); + printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'", + uid, den->uid); + // up again + printf("\\v'-\\n[" SUB_LOWER_FORMAT "]u'", uid); + #endif + if (reduce_size) + printf("\\s[\\n[" SIZE_FORMAT "]u]", uid); + // draw the line + printf("\\h'%dM'", null_delimiter_space); + printf("\\v'-%dM'", axis_height); + fputs(draw_flag ? "\\D'l" : "\\l'", stdout); + printf("\\n[" WIDTH_FORMAT "]u-%dM", + uid, 2*null_delimiter_space); + fputs(draw_flag ? " 0'" : "\\&\\(ru'", stdout); + printf("\\v'%dM'", axis_height); + printf("\\h'%dM'", null_delimiter_space); + } + else if (output_format == mathml) { + // FIXME: passing a displaystyle attribute doesn't validate. + printf(""); + num->output(); + den->output(); + printf(""); + } +} + +void over_box::debug_print() +{ + fprintf(stderr, "{ "); + num->debug_print(); + if (reduce_size) + fprintf(stderr, " } smallover { "); + else + fprintf(stderr, " } over { "); + den->debug_print(); + fprintf(stderr, " }"); +} + +void over_box::check_tabs(int level) +{ + num->check_tabs(level + 1); + den->check_tabs(level + 1); +} diff --git a/src/preproc/eqn/pbox.h b/src/preproc/eqn/pbox.h new file mode 100644 index 0000000..b185419 --- /dev/null +++ b/src/preproc/eqn/pbox.h @@ -0,0 +1,140 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +extern int fat_offset; + +extern int over_hang; +extern int accent_width; + +extern int delimiter_factor; +extern int delimiter_shortfall; + +extern int null_delimiter_space; +extern int script_space; +extern int thin_space; +extern int medium_space; +extern int thick_space; + +extern int num1; +extern int num2; +// we don't use num3, because we don't have \atop +extern int denom1; +extern int denom2; +extern int axis_height; +extern int sup1; +extern int sup2; +extern int sup3; +extern int default_rule_thickness; +extern int sub1; +extern int sub2; +extern int sup_drop; +extern int sub_drop; +extern int x_height; +extern int big_op_spacing1; +extern int big_op_spacing2; +extern int big_op_spacing3; +extern int big_op_spacing4; +extern int big_op_spacing5; + +extern int baseline_sep; +extern int shift_down; +extern int column_sep; +extern int matrix_side_sep; + +// ms.eqn relies on this! + +#define LINE_STRING "10" +#define MARK_OR_LINEUP_FLAG_REG "MK" + +#define WIDTH_FORMAT PREFIX "w%d" +#define HEIGHT_FORMAT PREFIX "h%d" +#define DEPTH_FORMAT PREFIX "d%d" +#define TOTAL_FORMAT PREFIX "t%d" +#define SIZE_FORMAT PREFIX "z%d" +#define SMALL_SIZE_FORMAT PREFIX "Z%d" +#define SUP_RAISE_FORMAT PREFIX "p%d" +#define SUB_LOWER_FORMAT PREFIX "b%d" +#define SUB_KERN_FORMAT PREFIX "k%d" +#define FONT_FORMAT PREFIX "f%d" +#define SKEW_FORMAT PREFIX "s%d" +#define LEFT_WIDTH_FORMAT PREFIX "lw%d" +#define LEFT_DELIM_STRING_FORMAT PREFIX "l%d" +#define RIGHT_DELIM_STRING_FORMAT PREFIX "r%d" +#define SQRT_STRING_FORMAT PREFIX "sqr%d" +#define SQRT_WIDTH_FORMAT PREFIX "sq%d" +#define BASELINE_SEP_FORMAT PREFIX "bs%d" +// this needs two parameters, the uid and the column index +#define COLUMN_WIDTH_FORMAT PREFIX "cw%d,%d" + +#define BAR_STRING PREFIX "sqb" +#define TEMP_REG PREFIX "temp" +#define MARK_REG PREFIX "mark" +#define MARK_WIDTH_REG PREFIX "mwidth" +#define SAVED_MARK_REG PREFIX "smark" +#define MAX_SIZE_REG PREFIX "mxsz" +#define REPEAT_APPEND_STRING_MACRO PREFIX "ras" +#define TOP_HEIGHT_REG PREFIX "th" +#define TOP_DEPTH_REG PREFIX "td" +#define MID_HEIGHT_REG PREFIX "mh" +#define MID_DEPTH_REG PREFIX "md" +#define BOT_HEIGHT_REG PREFIX "bh" +#define BOT_DEPTH_REG PREFIX "bd" +#define EXT_HEIGHT_REG PREFIX "eh" +#define EXT_DEPTH_REG PREFIX "ed" +#define TOTAL_HEIGHT_REG PREFIX "tot" +#define DELTA_REG PREFIX "delta" +#define DELIM_STRING PREFIX "delim" +#define DELIM_WIDTH_REG PREFIX "dwidth" +#define SAVED_FONT_REG PREFIX "sfont" +#define SAVED_PREV_FONT_REG PREFIX "spfont" +#define SAVED_INLINE_FONT_REG PREFIX "sifont" +#define SAVED_INLINE_PREV_FONT_REG PREFIX "sipfont" +#define SAVED_SIZE_REG PREFIX "ssize" +#define SAVED_INLINE_SIZE_REG PREFIX "sisize" +#define SAVED_INLINE_PREV_SIZE_REG PREFIX "sipsize" +#define SAVE_FONT_STRING PREFIX "sfont" +#define RESTORE_FONT_STRING PREFIX "rfont" +#define INDEX_REG PREFIX "i" +#define TEMP_MACRO PREFIX "tempmac" + +#define DELIMITER_CHAR "\\(EQ" + +const int CRAMPED_SCRIPT_STYLE = 0; +const int SCRIPT_STYLE = 1; +const int CRAMPED_DISPLAY_STYLE = 2; +const int DISPLAY_STYLE = 3; + +extern int script_style(int); +extern int cramped_style(int); + +const int ORDINARY_TYPE = 0; +const int OPERATOR_TYPE = 1; +const int BINARY_TYPE = 2; +const int RELATION_TYPE = 3; +const int OPENING_TYPE = 4; +const int CLOSING_TYPE = 5; +const int PUNCTUATION_TYPE = 6; +const int INNER_TYPE = 7; +const int SUPPRESS_TYPE = 8; + +void set_script_size(); + +enum { HINT_PREV_IS_ITALIC = 01, HINT_NEXT_IS_ITALIC = 02 }; + +extern const char *current_roman_font; diff --git a/src/preproc/eqn/pile.cpp b/src/preproc/eqn/pile.cpp new file mode 100644 index 0000000..fcc2e92 --- /dev/null +++ b/src/preproc/eqn/pile.cpp @@ -0,0 +1,354 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +// piles and matrices + +#include + +#include "eqn.h" +#include "pbox.h" + +// SUP_RAISE_FORMAT gives the first baseline +// BASELINE_SEP_FORMAT gives the separation between baselines + +int pile_box::compute_metrics(int style) +{ + int i; + for (i = 0; i < col.len; i++) + col.p[i]->compute_metrics(style); + printf(".nr " WIDTH_FORMAT " 0", uid); + for (i = 0; i < col.len; i++) + printf(">?\\n[" WIDTH_FORMAT "]", col.p[i]->uid); + printf("\n"); + printf(".nr " BASELINE_SEP_FORMAT " %dM", + uid, baseline_sep+col.space); + for (i = 1; i < col.len; i++) + printf(">?(\\n[" DEPTH_FORMAT "]+\\n[" HEIGHT_FORMAT "]+%dM)", + col.p[i-1]->uid, col.p[i]->uid, default_rule_thickness*5); + // round it so that it's a multiple of the vertical motion quantum + printf("+(\\n(.V/2)/\\n(.V*\\n(.V\n"); + + printf(".nr " SUP_RAISE_FORMAT " \\n[" BASELINE_SEP_FORMAT "]*%d/2" + "+%dM\n", + uid, uid, col.len-1, axis_height - shift_down); + printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n[" + HEIGHT_FORMAT "]\n", + uid, uid, col.p[0]->uid); + printf(".nr " DEPTH_FORMAT " \\n[" BASELINE_SEP_FORMAT "]*%d+\\n[" + DEPTH_FORMAT "]-\\n[" SUP_RAISE_FORMAT "]\n", + uid, uid, col.len-1, col.p[col.len-1]->uid, uid); + return FOUND_NOTHING; +} + +void pile_box::output() +{ + if (output_format == troff) { + int i; + printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid); + for (i = 0; i < col.len; i++) { + switch (col.align) { + case LEFT_ALIGN: + break; + case CENTER_ALIGN: + printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'", + uid, col.p[i]->uid); + break; + case RIGHT_ALIGN: + printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'", + uid, col.p[i]->uid); + break; + default: + assert(0); + } + col.p[i]->output(); + printf("\\h'-\\n[" WIDTH_FORMAT "]u'", col.p[i]->uid); + switch (col.align) { + case LEFT_ALIGN: + break; + case CENTER_ALIGN: + printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'", + col.p[i]->uid, uid); + break; + case RIGHT_ALIGN: + printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'", + col.p[i]->uid, uid); + break; + default: + assert(0); + } + if (i != col.len - 1) + printf("\\v'\\n[" BASELINE_SEP_FORMAT "]u'", uid); + } + printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid); + printf("\\v'-(%du*\\n[" BASELINE_SEP_FORMAT "]u)'", col.len - 1, uid); + printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid); + } + else if (output_format == mathml) { + const char *av; + switch (col.align) { + case LEFT_ALIGN: + av = "left"; + break; + case RIGHT_ALIGN: + av = "right"; + break; + case CENTER_ALIGN: + av = "center"; + break; + default: + assert(0); + } + printf("", av); + for (int i = 0; i < col.len; i++) { + printf(""); + col.p[i]->output(); + printf(""); + } + printf(""); + } +} + +pile_box::pile_box(box *pp) : col(pp) +{ +} + +void pile_box::check_tabs(int level) +{ + col.list_check_tabs(level); +} + +void pile_box::debug_print() +{ + col.debug_print("pile"); +} + +int matrix_box::compute_metrics(int style) +{ + int i, j; + int max_len = 0; + int space = 0; + for (i = 0; i < len; i++) { + for (j = 0; j < p[i]->len; j++) + p[i]->p[j]->compute_metrics(style); + if (p[i]->len > max_len) + max_len = p[i]->len; + if (p[i]->space > space) + space = p[i]->space; + } + for (i = 0; i < len; i++) { + printf(".nr " COLUMN_WIDTH_FORMAT " 0", uid, i); + for (j = 0; j < p[i]->len; j++) + printf(">?\\n[" WIDTH_FORMAT "]", p[i]->p[j]->uid); + printf("\n"); + } + printf(".nr " WIDTH_FORMAT " %dM", + uid, column_sep*(len-1)+2*matrix_side_sep); + for (i = 0; i < len; i++) + printf("+\\n[" COLUMN_WIDTH_FORMAT "]", uid, i); + printf("\n"); + printf(".nr " BASELINE_SEP_FORMAT " %dM", + uid, baseline_sep+space); + for (i = 0; i < len; i++) + for (j = 1; j < p[i]->len; j++) + printf(">?(\\n[" DEPTH_FORMAT "]+\\n[" HEIGHT_FORMAT "]+%dM)", + p[i]->p[j-1]->uid, p[i]->p[j]->uid, default_rule_thickness*5); + // round it so that it's a multiple of the vertical motion quantum + printf("+(\\n(.V/2)/\\n(.V*\\n(.V\n"); + printf(".nr " SUP_RAISE_FORMAT " \\n[" BASELINE_SEP_FORMAT "]*%d/2" + "+%dM\n", + uid, uid, max_len-1, axis_height - shift_down); + printf(".nr " HEIGHT_FORMAT " 0\\n[" SUP_RAISE_FORMAT "]+(0", + uid, uid); + for (i = 0; i < len; i++) + printf(">?\\n[" HEIGHT_FORMAT "]", p[i]->p[0]->uid); + printf(")>?0\n"); + printf(".nr " DEPTH_FORMAT " \\n[" BASELINE_SEP_FORMAT "]*%d-\\n[" + SUP_RAISE_FORMAT "]+(0", + uid, uid, max_len-1, uid); + for (i = 0; i < len; i++) + if (p[i]->len == max_len) + printf(">?\\n[" DEPTH_FORMAT "]", p[i]->p[max_len-1]->uid); + printf(")>?0\n"); + return FOUND_NOTHING; +} + +void matrix_box::output() +{ + if (output_format == troff) { + printf("\\h'%dM'", matrix_side_sep); + for (int i = 0; i < len; i++) { + int j; + printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid); + for (j = 0; j < p[i]->len; j++) { + switch (p[i]->align) { + case LEFT_ALIGN: + break; + case CENTER_ALIGN: + printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'", + uid, i, p[i]->p[j]->uid); + break; + case RIGHT_ALIGN: + printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'", + uid, i, p[i]->p[j]->uid); + break; + default: + assert(0); + } + p[i]->p[j]->output(); + printf("\\h'-\\n[" WIDTH_FORMAT "]u'", p[i]->p[j]->uid); + switch (p[i]->align) { + case LEFT_ALIGN: + break; + case CENTER_ALIGN: + printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" COLUMN_WIDTH_FORMAT "]u/2u'", + p[i]->p[j]->uid, uid, i); + break; + case RIGHT_ALIGN: + printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" COLUMN_WIDTH_FORMAT "]u'", + p[i]->p[j]->uid, uid, i); + break; + default: + assert(0); + } + if (j != p[i]->len - 1) + printf("\\v'\\n[" BASELINE_SEP_FORMAT "]u'", uid); + } + printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid); + printf("\\v'-(%du*\\n[" BASELINE_SEP_FORMAT "]u)'", p[i]->len - 1, uid); + printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u'", uid, i); + if (i != len - 1) + printf("\\h'%dM'", column_sep); + } + printf("\\h'%dM'", matrix_side_sep); + } + else if (output_format == mathml) { + int n = p[0]->len; // Each column must have the same number of rows in it + printf(""); + for (int i = 0; i < n; i++) { + printf(""); + for (int j = 0; j < len; j++) { + const char *av; + switch (p[j]->align) { + case LEFT_ALIGN: + av = "left"; + break; + case RIGHT_ALIGN: + av = "right"; + break; + case CENTER_ALIGN: + av = "center"; + break; + default: + assert(0); + } + printf("", av); + p[j]->p[i]->output(); + printf(""); + } + printf(""); + } + printf(""); + } +} + +matrix_box::matrix_box(column *pp) +{ + p = new column*[10]; + for (int i = 0; i < 10; i++) + p[i] = 0; + maxlen = 10; + len = 1; + p[0] = pp; +} + +matrix_box::~matrix_box() +{ + for (int i = 0; i < len; i++) + delete p[i]; + delete[] p; +} + +void matrix_box::append(column *pp) +{ + if (len + 1 > maxlen) { + column **oldp = p; + maxlen *= 2; + p = new column*[maxlen]; + memcpy(p, oldp, sizeof(column*)*len); + delete[] oldp; + } + p[len++] = pp; +} + +void matrix_box::check_tabs(int level) +{ + for (int i = 0; i < len; i++) + p[i]->list_check_tabs(level); +} + +void matrix_box::debug_print() +{ + fprintf(stderr, "matrix { "); + p[0]->debug_print("col"); + for (int i = 1; i < len; i++) { + fprintf(stderr, " "); + p[i]->debug_print("col"); + } + fprintf(stderr, " }"); +} + +column::column(box *pp) : box_list(pp), align(CENTER_ALIGN), space(0) +{ +} + +void column::set_alignment(alignment a) +{ + align = a; +} + +void column::set_space(int n) +{ + space = n; +} + +void column::debug_print(const char *s) +{ + char c = '\0'; // shut up -Wall + switch (align) { + case LEFT_ALIGN: + c = 'l'; + break; + case RIGHT_ALIGN: + c = 'r'; + break; + case CENTER_ALIGN: + c = 'c'; + break; + default: + assert(0); + } + fprintf(stderr, "%c%s %d { ", c, s, space); + list_debug_print(" above "); + fprintf(stderr, " }"); +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/eqn/script.cpp b/src/preproc/eqn/script.cpp new file mode 100644 index 0000000..f485eb9 --- /dev/null +++ b/src/preproc/eqn/script.cpp @@ -0,0 +1,250 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include + +#include "eqn.h" +#include "pbox.h" + +class script_box : public pointer_box { +private: + box *sub; + box *sup; +public: + script_box(box *, box *, box *); + ~script_box(); + int compute_metrics(int); + void output(); + void debug_print(); + int left_is_italic(); + void hint(unsigned); + void check_tabs(int); +}; + +/* The idea is that the script should attach to the rightmost box +of a list. For example, given '2x sup 3', the superscript should +attach to 'x' rather than '2x'. */ + +box *make_script_box(box *nuc, box *sub, box *sup) +{ + list_box *b = nuc->to_list_box(); + if (b != 0) { + b->list.p[b->list.len-1] = make_script_box(b->list.p[b->list.len - 1], + sub, + sup); + return b; + } + else + return new script_box(nuc, sub, sup); +} + +script_box::script_box(box *pp, box *qq, box *rr) +: pointer_box(pp), sub(qq), sup(rr) +{ +} + +script_box::~script_box() +{ + delete sub; + delete sup; +} + +int script_box::left_is_italic() +{ + return p->left_is_italic(); +} + +int script_box::compute_metrics(int style) +{ + int res = p->compute_metrics(style); + p->compute_subscript_kern(); + printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid); + if (!(style <= SCRIPT_STYLE && one_size_reduction_flag)) + set_script_size(); + printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid); + if (sub != 0) + sub->compute_metrics(cramped_style(script_style(style))); + if (sup != 0) + sup->compute_metrics(script_style(style)); + // 18a + if (p->is_char()) { + printf(".nr " SUP_RAISE_FORMAT " 0\n", uid); + printf(".nr " SUB_LOWER_FORMAT " 0\n", uid); + } + else { + printf(".nr " SUP_RAISE_FORMAT " \\n[" HEIGHT_FORMAT "]-%dM>?0\n", + uid, p->uid, sup_drop); + printf(".nr " SUB_LOWER_FORMAT " \\n[" DEPTH_FORMAT "]+%dM\n", + uid, p->uid, sub_drop); + } + printf(".ps \\n[" SIZE_FORMAT "]u\n", uid); + if (sup == 0) { + assert(sub != 0); + // 18b + printf(".nr " SUB_LOWER_FORMAT " \\n[" SUB_LOWER_FORMAT "]>?%dM>?(\\n[" + HEIGHT_FORMAT "]-(%dM*4/5))\n", + uid, uid, sub1, sub->uid, x_height); + } + else { + // sup != 0 + // 18c + int pos; + if (style == DISPLAY_STYLE) + pos = sup1; + else if (style & 1) // not cramped + pos = sup2; + else + pos = sup3; + printf(".nr " SUP_RAISE_FORMAT " \\n[" SUP_RAISE_FORMAT + "]>?%dM>?(\\n[" DEPTH_FORMAT "]+(%dM/4))\n", + uid, uid, pos, sup->uid, x_height); + // 18d + if (sub != 0) { + printf(".nr " SUB_LOWER_FORMAT " \\n[" SUB_LOWER_FORMAT "]>?%dM\n", + uid, uid, sub2); + // 18e + printf(".nr " TEMP_REG " \\n[" DEPTH_FORMAT "]-\\n[" + SUP_RAISE_FORMAT "]+\\n[" HEIGHT_FORMAT "]-\\n[" + SUB_LOWER_FORMAT "]+(4*%dM)\n", + sup->uid, uid, sub->uid, uid, default_rule_thickness); + printf(".if \\n[" TEMP_REG "] \\{"); + printf(".nr " SUB_LOWER_FORMAT " +\\n[" TEMP_REG "]\n", uid); + printf(".nr " TEMP_REG " (%dM*4/5)-\\n[" SUP_RAISE_FORMAT + "]+\\n[" DEPTH_FORMAT "]>?0\n", + x_height, uid, sup->uid); + printf(".nr " SUP_RAISE_FORMAT " +\\n[" TEMP_REG "]\n", uid); + printf(".nr " SUB_LOWER_FORMAT " -\\n[" TEMP_REG "]\n", uid); + printf(".\\}\n"); + } + } + printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]", uid, p->uid); + if (sub != 0 && sup != 0) + printf("+((\\n[" WIDTH_FORMAT "]-\\n[" SUB_KERN_FORMAT "]>?\\n[" + WIDTH_FORMAT "])+%dM)>?0\n", + sub->uid, p->uid, sup->uid, script_space); + else if (sub != 0) + printf("+(\\n[" WIDTH_FORMAT "]-\\n[" SUB_KERN_FORMAT "]+%dM)>?0\n", + sub->uid, p->uid, script_space); + else if (sup != 0) + printf("+(\\n[" WIDTH_FORMAT "]+%dM)>?0\n", sup->uid, script_space); + else + printf("\n"); + printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]", + uid, p->uid); + if (sup != 0) + printf(">?(\\n[" SUP_RAISE_FORMAT "]+\\n[" HEIGHT_FORMAT "])", + uid, sup->uid); + if (sub != 0) + printf(">?(-\\n[" SUB_LOWER_FORMAT "]+\\n[" HEIGHT_FORMAT "])", + uid, sub->uid); + printf("\n"); + printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]", + uid, p->uid); + if (sub != 0) + printf(">?(\\n[" SUB_LOWER_FORMAT "]+\\n[" DEPTH_FORMAT "])", + uid, sub->uid); + if (sup != 0) + printf(">?(-\\n[" SUP_RAISE_FORMAT "]+\\n[" DEPTH_FORMAT "])", + uid, sup->uid); + printf("\n"); + return res; +} + +void script_box::output() +{ + if (output_format == troff) { + p->output(); + if (sup != 0) { + printf("\\Z" DELIMITER_CHAR); + printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid); + printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid); + sup->output(); + printf("\\s[\\n[" SIZE_FORMAT "]u]", uid); + printf(DELIMITER_CHAR); + } + if (sub != 0) { + printf("\\Z" DELIMITER_CHAR); + printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid); + printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid); + printf("\\h'-\\n[" SUB_KERN_FORMAT "]u'", p->uid); + sub->output(); + printf("\\s[\\n[" SIZE_FORMAT "]u]", uid); + printf(DELIMITER_CHAR); + } + printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'", + uid, p->uid); + } + else if (output_format == mathml) { + if (sup != 0 && sub != 0) { + printf(""); + p->output(); + sub->output(); + sup->output(); + printf(""); + } + else if (sup != 0) { + printf(""); + p->output(); + sup->output(); + printf(""); + } + else if (sub != 0) { + printf(""); + p->output(); + sub->output(); + printf(""); + } + } +} + +void script_box::hint(unsigned flags) +{ + p->hint(flags & ~HINT_NEXT_IS_ITALIC); +} + +void script_box::debug_print() +{ + fprintf(stderr, "{ "); + p->debug_print(); + fprintf(stderr, " }"); + if (sub) { + fprintf(stderr, " sub { "); + sub->debug_print(); + fprintf(stderr, " }"); + } + if (sup) { + fprintf(stderr, " sup { "); + sup->debug_print(); + fprintf(stderr, " }"); + } +} + +void script_box::check_tabs(int level) +{ + if (sup) + sup->check_tabs(level + 1); + if (sub) + sub->check_tabs(level + 1); + p->check_tabs(level); +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/eqn/special.cpp b/src/preproc/eqn/special.cpp new file mode 100644 index 0000000..8ad8238 --- /dev/null +++ b/src/preproc/eqn/special.cpp @@ -0,0 +1,117 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "eqn.h" +#include "pbox.h" + +#define STRING_FORMAT PREFIX "str%d" + +#define SPECIAL_STRING "0s" +#define SPECIAL_WIDTH_REG "0w" +#define SPECIAL_HEIGHT_REG "0h" +#define SPECIAL_DEPTH_REG "0d" +#define SPECIAL_SUB_KERN_REG "0skern" +#define SPECIAL_SKEW_REG "0skew" + +/* +For example: + +.de Cl +.ds 0s \Z'\\*[0s]'\v'\\n(0du'\D'l \\n(0wu -\\n(0hu-\\n(0du'\v'\\n(0hu' +.. +.EQ +define cancel 'special Cl' +.EN +*/ + + +class special_box : public pointer_box { + char *macro_name; +public: + special_box(char *, box *); + ~special_box(); + int compute_metrics(int); + void compute_subscript_kern(); + void compute_skew(); + void output(); + void debug_print(); +}; + +box *make_special_box(char *s, box *p) +{ + return new special_box(s, p); +} + +special_box::special_box(char *s, box *pp) : pointer_box(pp), macro_name(s) +{ +} + +special_box::~special_box() +{ + delete[] macro_name; +} + +int special_box::compute_metrics(int style) +{ + int r = p->compute_metrics(style); + p->compute_subscript_kern(); + p->compute_skew(); + printf(".ds " SPECIAL_STRING " \""); + p->output(); + printf("\n"); + printf(".nr " SPECIAL_WIDTH_REG " 0\\n[" WIDTH_FORMAT "]\n", p->uid); + printf(".nr " SPECIAL_HEIGHT_REG " \\n[" HEIGHT_FORMAT "]\n", p->uid); + printf(".nr " SPECIAL_DEPTH_REG " \\n[" DEPTH_FORMAT "]\n", p->uid); + printf(".nr " SPECIAL_SUB_KERN_REG " \\n[" SUB_KERN_FORMAT "]\n", p->uid); + printf(".nr " SPECIAL_SKEW_REG " 0\\n[" SKEW_FORMAT "]\n", p->uid); + printf(".%s\n", macro_name); + printf(".rn " SPECIAL_STRING " " STRING_FORMAT "\n", uid); + printf(".nr " WIDTH_FORMAT " 0\\n[" SPECIAL_WIDTH_REG "]\n", uid); + printf(".nr " HEIGHT_FORMAT " 0>?\\n[" SPECIAL_HEIGHT_REG "]\n", uid); + printf(".nr " DEPTH_FORMAT " 0>?\\n[" SPECIAL_DEPTH_REG "]\n", uid); + printf(".nr " SUB_KERN_FORMAT " 0>?\\n[" SPECIAL_SUB_KERN_REG "]\n", uid); + printf(".nr " SKEW_FORMAT " 0\\n[" SPECIAL_SKEW_REG "]\n", uid); + // User will have to change MARK_REG if appropriate. + return r; +} + +void special_box::compute_subscript_kern() +{ + // Already computed in compute_metrics(), so do nothing. +} + +void special_box::compute_skew() +{ + // Already computed in compute_metrics(), so do nothing. +} + +void special_box::output() +{ + if (output_format == troff) + printf("\\*[" STRING_FORMAT "]", uid); + else if (output_format == mathml) + printf("eqn specials cannot be expressed in MathML"); +} + +void special_box::debug_print() +{ + fprintf(stderr, "special %s { ", macro_name); + p->debug_print(); + fprintf(stderr, " }"); +} diff --git a/src/preproc/eqn/sqrt.cpp b/src/preproc/eqn/sqrt.cpp new file mode 100644 index 0000000..e8d7c77 --- /dev/null +++ b/src/preproc/eqn/sqrt.cpp @@ -0,0 +1,186 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "eqn.h" +#include "pbox.h" + + +class sqrt_box : public pointer_box { +public: + sqrt_box(box *); + int compute_metrics(int style); + void output(); + void debug_print(); + void check_tabs(int); +}; + +box *make_sqrt_box(box *pp) +{ + return new sqrt_box(pp); +} + +sqrt_box::sqrt_box(box *pp) : pointer_box(pp) +{ +} + +#define SQRT_CHAR "\\[sqrt]" +#define RADICAL_EXTENSION_CHAR "\\[sqrtex]" + +#define SQRT_CHAIN "\\[sqrt\\\\n[" INDEX_REG "]]" +#define BAR_CHAIN "\\[sqrtex\\\\n[" INDEX_REG "]]" + +int sqrt_box::compute_metrics(int style) +{ + // 11 + int r = p->compute_metrics(cramped_style(style)); + printf(".nr " TEMP_REG " \\n[" HEIGHT_FORMAT "]+\\n[" DEPTH_FORMAT + "]+%dM+(%dM/4)\n", + p->uid, p->uid, default_rule_thickness, + (style > SCRIPT_STYLE ? x_height : default_rule_thickness)); + printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid); + printf(".ds " SQRT_STRING_FORMAT " " SQRT_CHAR "\n", uid); + printf(".ds " BAR_STRING " " RADICAL_EXTENSION_CHAR "\n"); + printf(".nr " SQRT_WIDTH_FORMAT + " 0\\w" DELIMITER_CHAR SQRT_CHAR DELIMITER_CHAR "\n", + uid); + printf(".if \\n[rst]-\\n[rsb]-%dM<\\n[" TEMP_REG "] \\{", + default_rule_thickness); + + printf(".nr " INDEX_REG " 0\n" + ".de " TEMP_MACRO "\n" + ".ie c" SQRT_CHAIN " \\{" + ".ds " SQRT_STRING_FORMAT " " SQRT_CHAIN "\n" + ".ie c" BAR_CHAIN " .ds " BAR_STRING " " BAR_CHAIN "\n" + ".el .ds " BAR_STRING " " RADICAL_EXTENSION_CHAR "\n" + ".nr " SQRT_WIDTH_FORMAT + " 0\\w" DELIMITER_CHAR SQRT_CHAIN DELIMITER_CHAR "\n" + ".if \\\\n[rst]-\\\\n[rsb]-%dM<\\n[" TEMP_REG "] \\{" + ".nr " INDEX_REG " +1\n" + "." TEMP_MACRO "\n" + ".\\}\\}\n" + ".el .nr " INDEX_REG " 0-1\n" + "..\n" + "." TEMP_MACRO "\n", + uid, uid, default_rule_thickness); + + printf(".if \\n[" INDEX_REG "]<0 \\{"); + + // Determine the maximum point size + printf(".ps 1000\n"); + printf(".nr " MAX_SIZE_REG " \\n[.ps]\n"); + printf(".ps \\n[" SIZE_FORMAT "]u\n", uid); + // We define a macro that will increase the current point size + // until we get a radical sign that's tall enough or we reach + // the maximum point size. + printf(".de " TEMP_MACRO "\n" + ".nr " SQRT_WIDTH_FORMAT + " 0\\w" DELIMITER_CHAR "\\*[" SQRT_STRING_FORMAT "]" DELIMITER_CHAR "\n" + ".if \\\\n[rst]" + "&(\\\\n[rst]-\\\\n[rsb]-%dM<\\n[" TEMP_REG "])" + "&(\\\\n[.ps]<\\n[" MAX_SIZE_REG "]) \\{" + ".ps +1\n" + "." TEMP_MACRO "\n" + ".\\}\n" + "..\n" + "." TEMP_MACRO "\n", + uid, uid, default_rule_thickness); + + printf(".\\}\\}\n"); + + printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid); + // set TEMP_REG to the amount by which the radical sign is too big + printf(".nr " TEMP_REG " \\n[rst]-\\n[rsb]-%dM-\\n[" TEMP_REG "]\n", + default_rule_thickness); + // If TEMP_REG is negative, the bottom of the radical sign should + // be -TEMP_REG above the bottom of p. If it's positive, the bottom + // of the radical sign should be TEMP_REG/2 below the bottom of p. + // This calculates the amount by which the baseline of the radical + // should be raised. + printf(".nr " SUP_RAISE_FORMAT " (-\\n[" TEMP_REG "]>?(-\\n[" TEMP_REG "]/2))" + "-\\n[rsb]-\\n[" DEPTH_FORMAT "]\n", uid, p->uid); + printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]" + ">?(\\n[" SUP_RAISE_FORMAT "]+\\n[rst])\n", + uid, p->uid, uid); + printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]" + ">?(-\\n[" SUP_RAISE_FORMAT "]-\\n[rsb])\n", + uid, p->uid, uid); + // Do this last, so we don't lose height and depth information on + // the radical sign. + // Remember that the width of the bar might be greater than the width of p. + + printf(".nr " TEMP_REG " " + "\\n[" WIDTH_FORMAT "]" + ">?\\w" DELIMITER_CHAR "\\*[" BAR_STRING "]" DELIMITER_CHAR "\n", + p->uid); + printf(".as " SQRT_STRING_FORMAT " " + "\\l'\\n[" TEMP_REG "]u\\&\\*[" BAR_STRING "]'\n", + uid); + printf(".nr " WIDTH_FORMAT " \\n[" TEMP_REG "]" + "+\\n[" SQRT_WIDTH_FORMAT "]\n", + uid, uid); + + if (r) + printf(".nr " MARK_REG " +\\n[" SQRT_WIDTH_FORMAT "]\n", uid); + // the top of the bar might be higher than the top of the radical sign + printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]" + ">?(\\n[" SUP_RAISE_FORMAT "]+\\n[rst])\n", + uid, p->uid, uid); + // put a bit of extra space above the bar + printf(".nr " HEIGHT_FORMAT " +%dM\n", uid, default_rule_thickness); + printf(".ps \\n[" SIZE_FORMAT "]u\n", uid); + return r; +} + +void sqrt_box::output() +{ + if (output_format == troff) { + printf("\\Z" DELIMITER_CHAR); + printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid); + printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid); + printf("\\*[" SQRT_STRING_FORMAT "]", uid); + printf("\\s[\\n[" SIZE_FORMAT "]u]", uid); + printf(DELIMITER_CHAR); + + printf("\\Z" DELIMITER_CHAR); + printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u" + "+\\n[" SQRT_WIDTH_FORMAT "]u/2u'", + uid, p->uid, uid); + p->output(); + printf(DELIMITER_CHAR); + + printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid); + } + else if (output_format == mathml) { + printf(""); + p->output(); + printf(""); + } +} + +void sqrt_box::debug_print() +{ + fprintf(stderr, "sqrt { "); + p->debug_print(); + fprintf(stderr, " }"); +} + +void sqrt_box::check_tabs(int level) +{ + p->check_tabs(level + 1); +} diff --git a/src/preproc/eqn/tests/diagnostics-report-correct-line-numbers.sh b/src/preproc/eqn/tests/diagnostics-report-correct-line-numbers.sh new file mode 100755 index 0000000..feb78c1 --- /dev/null +++ b/src/preproc/eqn/tests/diagnostics-report-correct-line-numbers.sh @@ -0,0 +1,55 @@ +#!/bin/sh +# +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +eqn="${abs_top_builddir:-.}/eqn" +fail= + +wail () { + echo "...FAILED" >&2 + echo "$error" + fail=yes +} + +# Verify that correct input file line numbers are reported. + +echo "checking for absent line number in early EOF diagnostic" >&2 +input='.EQ' +error=$(printf "%s\n" "$input" | "$eqn" 2>&1 > /dev/null) +echo "$error" | grep -Eq '^[^:]+:[^:]+: fatal' || wail + +echo "checking for correct line number in nested 'EQ' diagnostic" >&2 +input='.EQ +.EQ' +error=$(printf "%s\n" "$input" | "$eqn" 2>&1 > /dev/null) +echo "$error" | grep -Eq '^[^:]+:[^:]+:2: fatal' || wail + +echo "checking for correct line number in invalid input character" \ + "diagnostic" >&2 +error=$(printf ".EQ\nx\n.EN\n\200\n" | "$eqn" 2>&1 > /dev/null) +echo "$error" | grep -Eq '^[^:]+:[^:]+:4: error' || wail + +echo "checking for correct line number in invalid input character" \ + "diagnostic when 'lf' request used beforehand" >&2 +error=$(printf ".EQ\nx\n.EN\n.lf 99\n\200\n" | "$eqn" 2>&1 > /dev/null) +echo "$error" | grep -Eq '^[^:]+:[^:]+:99: error' || wail + +test -z "$fail" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/preproc/eqn/text.cpp b/src/preproc/eqn/text.cpp new file mode 100644 index 0000000..272f3fe --- /dev/null +++ b/src/preproc/eqn/text.cpp @@ -0,0 +1,957 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include "eqn.h" +#include "pbox.h" +#include "ptable.h" + +struct map { + const char *from; + const char *to; +}; + +struct map entity_table[] = { + // Classic troff special characters + {"%", "­"}, // ISOnum + {"'", "´"}, // ISOdia + {"!=", "≠"}, // ISOtech + {"**", "∗"}, // ISOtech + {"*a", "α"}, // ISOgrk3 + {"*A", "A"}, + {"*b", "β"}, // ISOgrk3 + {"*B", "B"}, + {"*d", "δ"}, // ISOgrk3 + {"*D", "Δ"}, // ISOgrk3 + {"*e", "ε"}, // ISOgrk3 + {"*E", "E"}, + {"*f", "φ"}, // ISOgrk3 + {"*F", "Φ"}, // ISOgrk3 + {"*g", "γ"}, // ISOgrk3 + {"*G", "Γ"}, // ISOgrk3 + {"*h", "θ"}, // ISOgrk3 + {"*H", "Θ"}, // ISOgrk3 + {"*i", "ι"}, // ISOgrk3 + {"*I", "I"}, + {"*k", "κ"}, // ISOgrk3 + {"*K", "K;"}, + {"*l", "λ"}, // ISOgrk3 + {"*L", "Λ"}, // ISOgrk3 + {"*m", "μ"}, // ISOgrk3 + {"*M", "M"}, + {"*n", "ν"}, // ISOgrk3 + {"*N", "N"}, + {"*o", "o"}, + {"*O", "O"}, + {"*p", "π"}, // ISOgrk3 + {"*P", "Π"}, // ISOgrk3 + {"*q", "ψ"}, // ISOgrk3 + {"*Q", "&PSI;"}, // ISOgrk3 + {"*r", "ρ"}, // ISOgrk3 + {"*R", "R"}, + {"*s", "σ"}, // ISOgrk3 + {"*S", "Σ"}, // ISOgrk3 + {"*t", "τ"}, // ISOgrk3 + {"*T", "Τ"}, // ISOgrk3 + {"*u", "υ"}, // ISOgrk3 + {"*U", "Υ"}, // ISOgrk3 + {"*w", "ω"}, // ISOgrk3 + {"*W", "Ω"}, // ISOgrk3 + {"*x", "χ"}, // ISOgrk3 + {"*X", "Χ"}, // ISOgrk3 + {"*y", "η"}, // ISOgrk3 + {"*Y", "Η"}, // ISOgrk3 + {"*z", "ζ"}, // ISOgrk3 + {"*Z", "Ζ"}, // ISOgrk3 + {"+-", "±"}, // ISOnum + {"->", "→"}, // ISOnum + {"12", "½"}, // ISOnum + {"14", "¼"}, // ISOnum + {"34", "¾"}, // ISOnum + {"<-", "←"}, // ISOnum + {"==", "≡"}, // ISOtech + {"Fi", "ffi"}, // ISOpub + {"Fl", "ffl"}, // ISOpub + {"aa", "´"}, // ISOdia + {"ap", "∼"}, // ISOtech + {"bl", "&phonexb;"}, // ISOpub + {"br", "│"}, // ISObox + {"bs", "☎"}, // ISOpub (for the Bell logo) + {"bu", "•"}, // ISOpub + {"bv", "|"}, // ISOnum + {"ca", "∩"}, // ISOtech + {"ci", "○"}, // ISOpub + {"co", "©"}, // ISOnum + {"ct", "¢"}, // ISOnum + {"cu", "∪"}, // ISOtech + {"da", "↓"}, // ISOnum + {"de", "°"}, // ISOnum + {"dg", "†"}, // ISOpub + {"dd", "‡"}, // ISOpub + {"di", "÷"}, // ISOnum + {"em", "—"}, // ISOpub + {"eq", "="}, // ISOnum + {"es", "∅"}, // ISOamso + {"ff", "ff"}, // ISOpub + {"fi", "fi"}, // ISOpub + {"fl", "fl"}, // ISOpub + {"fm", "′"}, // ISOtech + {"ge", "≥"}, // ISOtech + {"gr", "∇"}, // ISOtech + {"hy", "‐"}, // ISOnum + {"ib", "⊆"}, // ISOtech + {"if", "∞"}, // ISOtech + {"ip", "⊇"}, // ISOtech + {"is", "∫"}, // ISOtech + {"le", "≤"}, // ISOtech + // Some pile characters go here + {"mi", "−"}, // ISOtech + {"mo", "∈"}, // ISOtech + {"mu", "×"}, // ISOnum + {"no", "¬"}, // ISOnum + {"or", "|"}, // ISOnum + {"pl", "+"}, // ISOnum + {"pt", "∝"}, // ISOtech + {"rg", "™"}, // ISOnum + // More pile characters go here + {"rn", "¯"}, // ISOdia + {"ru", "_"}, // ISOnum + {"sb", "⊂"}, // ISOtech + {"sc", "§"}, // ISOnum + {"sl", "/"}, + {"sp", "⊃"}, // ISOtech + {"sq", "▪"}, // ISOpub + {"sr", "√"}, // ISOtech + {"ts", "ς"}, // ISOgrk3 + {"ua", "↑"}, // ISOnum + {"ul", "_"}, + {"~=", "≅"}, // ISOtech + // Extended specials supported by groff; see groff_char(7). + // These are listed in the order they occur on that man page. + {"-D", "Ð"}, // ISOlat: Icelandic uppercase eth + {"Sd", "ð"}, // ISOlat1: Icelandic lowercase eth + {"TP", "Þ"}, // ISOlat1: Icelandic uppercase thorn + {"Tp", "þ"}, // ISOlat1: Icelandic lowercase thorn + {"ss", "ß"}, // ISOlat1 + // Ligatures + // ff, fi, fl, ffi, ffl from old troff go here + {"AE", "Æ"}, // ISOlat1 + {"ae", "æ"}, // ISOlat1 + {"OE", "Œ"}, // ISOlat2 + {"oe", "œ"}, // ISOlat2 + {"IJ", "ij"}, // ISOlat2: Dutch IJ ligature + {"ij", "IJ"}, // ISOlat2: Dutch ij ligature + {".i", "ı"}, // ISOlat2,ISOamso + {".j", "&jnodot;"}, // ISOamso (undocumented but in 1.19) + // Accented characters + {"'A", "Á"}, // ISOlat1 + {"'C", "Ć"}, // ISOlat2 + {"'E", "É"}, // ISOlat1 + {"'I", "Í"}, // ISOlat1 + {"'O", "Ó"}, // ISOlat1 + {"'U", "Ú"}, // ISOlat1 + {"'Y", "Ý"}, // ISOlat1 + {"'a", "á"}, // ISOlat1 + {"'c", "ć"}, // ISOlat2 + {"'e", "é"}, // ISOlat1 + {"'i", "í"}, // ISOlat1 + {"'o", "ó"}, // ISOlat1 + {"'u", "ú"}, // ISOlat1 + {"'y", "ý"}, // ISOlat1 + {":A", "Ä"}, // ISOlat1 + {":E", "Ë"}, // ISOlat1 + {":I", "Ï"}, // ISOlat1 + {":O", "Ö"}, // ISOlat1 + {":U", "Ü"}, // ISOlat1 + {":Y", "Ÿ"}, // ISOlat2 + {":a", "ä"}, // ISOlat1 + {":e", "ë"}, // ISOlat1 + {":i", "ï"}, // ISOlat1 + {":o", "ö"}, // ISOlat1 + {":u", "ü"}, // ISOlat1 + {":y", "ÿ"}, // ISOlat1 + {"^A", "Â"}, // ISOlat1 + {"^E", "Ê"}, // ISOlat1 + {"^I", "Î"}, // ISOlat1 + {"^O", "Ô"}, // ISOlat1 + {"^U", "Û"}, // ISOlat1 + {"^a", "â"}, // ISOlat1 + {"^e", "ê"}, // ISOlat1 + {"^i", "î"}, // ISOlat1 + {"^o", "ô"}, // ISOlat1 + {"^u", "û"}, // ISOlat1 + {"`A", "À"}, // ISOlat1 + {"`E", "È"}, // ISOlat1 + {"`I", "Ì"}, // ISOlat1 + {"`O", "Ò"}, // ISOlat1 + {"`U", "Ù"}, // ISOlat1 + {"`a", "à"}, // ISOlat1 + {"`e", "è"}, // ISOlat1 + {"`i", "ì"}, // ISOlat1 + {"`o", "ò"}, // ISOlat1 + {"`u", "ù"}, // ISOlat1 + {"~A", "Ã"}, // ISOlat1 + {"~N", "Ñ"}, // ISOlat1 + {"~O", "Õ"}, // ISOlat1 + {"~a", "ã"}, // ISOlat1 + {"~n", "ñ"}, // ISOlat1 + {"~o", "õ"}, // ISOlat1 + {"vS", "Š"}, // ISOlat2 + {"vs", "š"}, // ISOlat2 + {"vZ", "Ž"}, // ISOlat2 + {"vz", "ž"}, // ISOlat2 + {",C", "Ç"}, // ISOlat1 + {",c", "ç"}, // ISOlat1 + {"/L", "Ł"}, // ISOlat2: Polish L with a slash + {"/l", "ł"}, // ISOlat2: Polish l with a slash + {"/O", "Ø"}, // ISOlat1 + {"/o", "ø"}, // ISOlat1 + {"oA", "Å"}, // ISOlat1 + {"oa", "å"}, // ISOlat1 + // Accents + {"a\"","˝"}, // ISOdia: double acute accent (Hungarian umlaut) + {"a-", "¯"}, // ISOdia: macron or bar accent + {"a.", "˙"}, // ISOdia: dot above + {"a^", "ˆ"}, // ISOdia: circumflex accent + {"aa", "´"}, // ISOdia: acute accent + {"ga", "`"}, // ISOdia: grave accent + {"ab", "˘"}, // ISOdia: breve accent + {"ac", "¸"}, // ISOdia: cedilla accent + {"ad", "¨"}, // ISOdia: umlaut or dieresis + {"ah", "ˇ"}, // ISOdia: caron (aka hacek accent) + {"ao", "˚"}, // ISOdia: ring or circle accent + {"a~", "˜"}, // ISOdia: tilde accent + {"ho", "˛"}, // ISOdia: hook or ogonek accent + {"ha", "^"}, // ASCII circumflex, hat, caret + {"ti", "~"}, // ASCII tilde, large tilde + // Quotes + {"Bq", "‚"}, // ISOpub: low double comma quote + {"bq", "„"}, // ISOpub: low single comma quote + {"lq", "“"}, // ISOnum + {"rq", "”"}, // ISOpub + {"oq", "‘"}, // ISOnum: single open quote + {"cq", "’"}, // ISOnum: single closing quote (ASCII 39) + {"aq", "&zerosp;'"}, // apostrophe quote + {"dq", "\""}, // double quote (ASCII 34) + {"Fo", "«"}, // ISOnum + {"Fc", "»"}, // ISOnum + //{"fo", "&fo;"}, + //{"fc", "&fc;"}, + // Punctuation + {"r!", "¡"}, // ISOnum + {"r?", "¿"}, // ISOnum + // Old troff \(em goes here + {"en", "–"}, // ISOpub: en dash + // Old troff \(hy goes here + // Brackets + {"lB", "["}, // ISOnum: left (square) bracket + {"rB", "]"}, // ISOnum: right (square) bracket + {"lC", "{"}, // ISOnum: left (curly) brace + {"rC", "}"}, // ISOnum: right (curly) brace + {"la", "⟨"}, // ISOtech: left angle bracket + {"ra", "⟩"}, // ISOtech: right angle bracket + // Old troff \(bv goes here + // Bracket-pile characters could go here. + // Arrows + // Old troff \(<- and \(-> go here + {"<>", "↔"}, // ISOamsa + {"da", "↓"}, // ISOnum + {"ua", "↑"}, // ISOnum + {"lA", "⇐"}, // ISOtech + {"rA", "⇒"}, // ISOtech + {"hA", "⇔"}, // ISOtech: horizontal double-headed arrow + {"dA", "⇓"}, // ISOamsa + {"uA", "⇑"}, // ISOamsa + {"vA", "⇕"}, // ISOamsa: vertical double-headed double arrow + //{"an", "&an;"}, + // Lines + {"-h", "ℏ"}, // ISOamso: h-bar (Planck's constant) + // Old troff \(or goes here + {"ba", "|"}, // ISOnum + // Old troff \(br, \{u, \(ul, \(bv go here + {"bb", "¦"}, // ISOnum + {"sl", "/"}, + {"rs", "\"}, // ISOnum + // Text markers + // Old troff \(ci, \(bu, \(dd, \(dg go here + {"lz", "◊"}, // ISOpub + // Old troff sq goes here + {"ps", "¶"}, // ISOnum: paragraph or pilcrow sign + {"sc", "§"}, // ISOnum (in old troff) + // Old troff \(lh, \{h go here + {"at", "@"}, // ISOnum + {"sh", "#"}, // ISOnum + //{"CR", "&CR;"}, + {"OK", "✓"}, // ISOpub + // Legalize + // Old troff \(co, \{g go here + {"tm", "™"}, // ISOnum + // Currency symbols + {"Do", "$"}, // ISOnum + {"ct", "¢"}, // ISOnum + {"eu", "€"}, + {"Eu", "€"}, + {"Ye", "¥"}, // ISOnum + {"Po", "£"}, // ISOnum + {"Cs", "¤"}, // ISOnum: currency sign + {"Fn", "&fnof"}, // ISOtech + // Units + // Old troff de goes here + {"%0", "‰"}, // ISOtech: per thousand, per mille sign + // Old troff \(fm goes here + {"sd", "″"}, // ISOtech + {"mc", "µ"}, // ISOnum + {"Of", "ª"}, // ISOnum + {"Om", "º"}, // ISOnum + // Logical symbols + {"AN", "∧"}, // ISOtech + {"OR", "∨"}, // ISOtech + // Old troff \(no goes here + {"te", "∃"}, // ISOtech: there exists, existential quantifier + {"fa", "∀"}, // ISOtech: for all, universal quantifier + {"st", "&bepsi"}, // ISOamsr: such that + {"3d", "∴"}, // ISOtech + {"tf", "∴"}, // ISOtech + // Mathematical symbols + // Old troff "12", "14", "34" goes here + {"S1", "¹"}, // ISOnum + {"S2", "²"}, // ISOnum + {"S3", "³"}, // ISOnum + // Old troff \(pl", \-, \(+- go here + {"t+-", "±"}, // ISOnum + {"-+", "∓"}, // ISOtech + {"pc", "·"}, // ISOnum + {"md", "·"}, // ISOnum + // Old troff \(mu goes here + {"tmu", "×"}, // ISOnum + {"c*", "⊗"}, // ISOamsb: multiply sign in a circle + {"c+", "⊕"}, // ISOamsb: plus sign in a circle + // Old troff \(di goes here + {"tdi", "÷"}, // ISOnum + {"f/", "―"}, // ISOnum: horizintal bar for fractions + // Old troff \(** goes here + {"<=", "≤"}, // ISOtech + {">=", "≥"}, // ISOtech + {"<<", "≪"}, // ISOamsr + {">>", "≫"}, // ISOamsr + {"!=", "≠"}, // ISOtech + // Old troff \(eq and \(== go here + {"=~", "≅"}, // ISOamsr + // Old troff \(ap goes here + {"~~", "≈"}, // ISOtech + // This appears to be an error in the groff table. + // It clashes with the Bell Labs use of ~= for a congruence sign + // {"~=", "≈"}, // ISOamsr + // Old troff \(pt, \(es, \(mo go here + {"nm", "∉"}, // ISOtech + {"nb", "⊄"}, // ISOamsr + {"nc", "⊅"}, // ISOamsn + {"ne", "≢"}, // ISOamsn + // Old troff \(sb, \(sp, \(ib, \(ip, \(ca, \(cu go here + {"/_", "∠"}, // ISOamso + {"pp", "⊥"}, // ISOtech + // Old troff \(is goes here + {"sum", "∑"}, // ISOamsb + {"product", "∏"}, // ISOamsb + {"gr", "∇"}, // ISOtech + // Old troff \(sr. \{n, \(if go here + {"Ah", "ℵ"}, // ISOtech + {"Im", "ℑ"}, // ISOamso: Fraktur I, imaginary + {"Re", "ℜ"}, // ISOamso: Fraktur R, real + {"wp", "℘"}, // ISOamso + {"pd", "∂"}, // ISOtech: partial differentiation sign + // Their table duplicates the Greek letters here. + // We list only the variant forms here, mapping them into + // the ISO Greek 4 variants (which may or may not be correct :-() + {"+f", "&b.phiv;"}, // ISOgrk4: variant phi + {"+h", "&b.thetas;"}, // ISOgrk4: variant theta + {"+p", "&b.omega;"}, // ISOgrk4: variant pi, looking like omega + // Card symbols + {"CL", "♣"}, // ISOpub: club suit + {"SP", "♠"}, // ISOpub: spade suit + {"HE", "♥"}, // ISOpub: heart suit + {"DI", "♦"}, // ISOpub: diamond suit +}; + +const char *special_to_entity(const char *sp) +{ + struct map *mp; + for (mp = entity_table; + mp < entity_table + sizeof(entity_table)/sizeof(entity_table[0]); + mp++) { + if (strcmp(mp->from, sp) == 0) + return mp->to; + } + return NULL; +} + +class char_box : public simple_box { + unsigned char c; + char next_is_italic; + char prev_is_italic; +public: + char_box(unsigned char); + void debug_print(); + void output(); + int is_char(); + int left_is_italic(); + int right_is_italic(); + void hint(unsigned); + void handle_char_type(int, int); +}; + +class special_char_box : public simple_box { + char *s; +public: + special_char_box(const char *); + ~special_char_box(); + void output(); + void debug_print(); + int is_char(); + void handle_char_type(int, int); +}; + +enum spacing_type { + s_ordinary, + s_operator, + s_binary, + s_relation, + s_opening, + s_closing, + s_punctuation, + s_inner, + s_suppress +}; + +const char *spacing_type_table[] = { + "ordinary", + "operator", + "binary", + "relation", + "opening", + "closing", + "punctuation", + "inner", + "suppress", + 0, +}; + +const int DIGIT_TYPE = 0; +const int LETTER_TYPE = 1; + +const char *font_type_table[] = { + "digit", + "letter", + 0, +}; + +struct char_info { + int spacing_type; + int font_type; + char_info(); +}; + +char_info::char_info() +: spacing_type(ORDINARY_TYPE), font_type(DIGIT_TYPE) +{ +} + +static char_info char_table[256]; + +declare_ptable(char_info) +implement_ptable(char_info) + +PTABLE(char_info) special_char_table; + +static int get_special_char_spacing_type(const char *ch) +{ + char_info *p = special_char_table.lookup(ch); + return p ? p->spacing_type : ORDINARY_TYPE; +} + +static int get_special_char_font_type(const char *ch) +{ + char_info *p = special_char_table.lookup(ch); + return p ? p->font_type : DIGIT_TYPE; +} + +static void set_special_char_type(const char *ch, int st, int ft) +{ + char_info *p = special_char_table.lookup(ch); + if (!p) { + p = new char_info[1]; + special_char_table.define(ch, p); + } + if (st >= 0) + p->spacing_type = st; + if (ft >= 0) + p->font_type = ft; +} + +void init_char_table() +{ + set_special_char_type("pl", s_binary, -1); + set_special_char_type("mi", s_binary, -1); + set_special_char_type("eq", s_relation, -1); + set_special_char_type("<=", s_relation, -1); + set_special_char_type(">=", s_relation, -1); + char_table['}'].spacing_type = s_closing; + char_table[')'].spacing_type = s_closing; + char_table[']'].spacing_type = s_closing; + char_table['{'].spacing_type = s_opening; + char_table['('].spacing_type = s_opening; + char_table['['].spacing_type = s_opening; + char_table[','].spacing_type = s_punctuation; + char_table[';'].spacing_type = s_punctuation; + char_table[':'].spacing_type = s_punctuation; + char_table['.'].spacing_type = s_punctuation; + char_table['>'].spacing_type = s_relation; + char_table['<'].spacing_type = s_relation; + char_table['*'].spacing_type = s_binary; + for (int i = 0; i < 256; i++) + if (csalpha(i)) + char_table[i].font_type = LETTER_TYPE; +} + +static int lookup_spacing_type(const char *type) +{ + for (int i = 0; spacing_type_table[i] != 0; i++) + if (strcmp(spacing_type_table[i], type) == 0) + return i; + return -1; +} + +static int lookup_font_type(const char *type) +{ + for (int i = 0; font_type_table[i] != 0; i++) + if (strcmp(font_type_table[i], type) == 0) + return i; + return -1; +} + +void box::set_spacing_type(char *type) +{ + int t = lookup_spacing_type(type); + if (t < 0) + error("unrecognised type '%1'", type); + else + spacing_type = t; + free(type); +} + +char_box::char_box(unsigned char cc) +: c(cc), next_is_italic(0), prev_is_italic(0) +{ + spacing_type = char_table[c].spacing_type; +} + +void char_box::hint(unsigned flags) +{ + if (flags & HINT_PREV_IS_ITALIC) + prev_is_italic = 1; + if (flags & HINT_NEXT_IS_ITALIC) + next_is_italic = 1; +} + +void char_box::output() +{ + if (output_format == troff) { + int font_type = char_table[c].font_type; + if (font_type != LETTER_TYPE) + printf("\\f[%s]", current_roman_font); + if (!prev_is_italic) + fputs("\\,", stdout); + if (c == '\\') + fputs("\\e", stdout); + else + putchar(c); + if (!next_is_italic) + fputs("\\/", stdout); + else + fputs("\\&", stdout); // suppress ligaturing and kerning + if (font_type != LETTER_TYPE) + fputs("\\fP", stdout); + } + else if (output_format == mathml) { + if (isdigit(c)) + printf(""); + else if (char_table[c].spacing_type) + printf(""); + else + printf(""); + if (c == '<') + printf("<"); + else if (c == '>') + printf(">"); + else if (c == '&') + printf("&"); + else + putchar(c); + if (isdigit(c)) + printf(""); + else if (char_table[c].spacing_type) + printf(""); + else + printf(""); + } +} + +int char_box::left_is_italic() +{ + int font_type = char_table[c].font_type; + return font_type == LETTER_TYPE; +} + +int char_box::right_is_italic() +{ + int font_type = char_table[c].font_type; + return font_type == LETTER_TYPE; +} + +int char_box::is_char() +{ + return 1; +} + +void char_box::debug_print() +{ + if (c == '\\') { + putc('\\', stderr); + putc('\\', stderr); + } + else + putc(c, stderr); +} + +special_char_box::special_char_box(const char *t) +{ + s = strsave(t); + spacing_type = get_special_char_spacing_type(s); +} + +special_char_box::~special_char_box() +{ + free(s); +} + +void special_char_box::output() +{ + if (output_format == troff) { + int font_type = get_special_char_font_type(s); + if (font_type != LETTER_TYPE) + printf("\\f[%s]", current_roman_font); + printf("\\,\\[%s]\\/", s); + if (font_type != LETTER_TYPE) + printf("\\fP"); + } + else if (output_format == mathml) { + const char *entity = special_to_entity(s); + if (entity != NULL) + printf("%s", entity); + else + printf("unknown eqn/troff special char %s", s); + } +} + +int special_char_box::is_char() +{ + return 1; +} + +void special_char_box::debug_print() +{ + fprintf(stderr, "\\[%s]", s); +} + + +void char_box::handle_char_type(int st, int ft) +{ + if (st >= 0) + char_table[c].spacing_type = st; + if (ft >= 0) + char_table[c].font_type = ft; +} + +void special_char_box::handle_char_type(int st, int ft) +{ + set_special_char_type(s, st, ft); +} + +void set_char_type(const char *type, char *ch) +{ + assert(ch != 0); + int st = lookup_spacing_type(type); + int ft = lookup_font_type(type); + if (st < 0 && ft < 0) { + error("bad character type '%1'", type); + delete[] ch; + return; + } + box *b = split_text(ch); + b->handle_char_type(st, ft); + delete b; +} + +/* We give primes special treatment so that in "x' sub 2", the "2" +will be tucked under the prime */ + +class prime_box : public pointer_box { + box *pb; +public: + prime_box(box *); + ~prime_box(); + int compute_metrics(int style); + void output(); + void compute_subscript_kern(); + void debug_print(); + void handle_char_type(int, int); +}; + +box *make_prime_box(box *pp) +{ + return new prime_box(pp); +} + +prime_box::prime_box(box *pp) : pointer_box(pp) +{ + pb = new special_char_box("fm"); +} + +prime_box::~prime_box() +{ + delete pb; +} + +int prime_box::compute_metrics(int style) +{ + int res = p->compute_metrics(style); + pb->compute_metrics(style); + printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]" + "+\\n[" WIDTH_FORMAT "]\n", + uid, p->uid, pb->uid); + printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]" + ">?\\n[" HEIGHT_FORMAT "]\n", + uid, p->uid, pb->uid); + printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]" + ">?\\n[" DEPTH_FORMAT "]\n", + uid, p->uid, pb->uid); + return res; +} + +void prime_box::compute_subscript_kern() +{ + p->compute_subscript_kern(); + printf(".nr " SUB_KERN_FORMAT " 0\\n[" WIDTH_FORMAT "]" + "+\\n[" SUB_KERN_FORMAT "]>?0\n", + uid, pb->uid, p->uid); +} + +void prime_box::output() +{ + p->output(); + pb->output(); +} + +void prime_box::handle_char_type(int st, int ft) +{ + p->handle_char_type(st, ft); + pb->handle_char_type(st, ft); +} + +void prime_box::debug_print() +{ + p->debug_print(); + putc('\'', stderr); +} + +box *split_text(char *text) +{ + list_box *lb = 0; + box *fb = 0; + char *s = text; + while (*s != '\0') { + char c = *s++; + box *b = 0; + switch (c) { + case '+': + b = new special_char_box("pl"); + break; + case '-': + b = new special_char_box("mi"); + break; + case '=': + b = new special_char_box("eq"); + break; + case '\'': + b = new special_char_box("fm"); + break; + case '<': + if (*s == '=') { + b = new special_char_box("<="); + s++; + break; + } + goto normal_char; + case '>': + if (*s == '=') { + b = new special_char_box(">="); + s++; + break; + } + goto normal_char; + case '\\': + if (*s == '\0') { + lex_error("bad escape"); + break; + } + c = *s++; + switch (c) { + case '(': + { + char buf[3]; + if (*s != '\0') { + buf[0] = *s++; + if (*s != '\0') { + buf[1] = *s++; + buf[2] = '\0'; + b = new special_char_box(buf); + } + else { + lex_error("bad escape"); + } + } + else { + lex_error("bad escape"); + } + } + break; + case '[': + { + char *ch = s; + while (*s != ']' && *s != '\0') + s++; + if (*s == '\0') + lex_error("bad escape"); + else { + *s++ = '\0'; + b = new special_char_box(ch); + } + } + break; + case 'f': + case 'g': + case 'k': + case 'n': + case '*': + { + char *escape_start = s - 2; + switch (*s) { + case '(': + if (*++s != '\0') + ++s; + break; + case '[': + for (++s; *s != '\0' && *s != ']'; s++) + ; + break; + } + if (*s == '\0') + lex_error("bad escape"); + else { + ++s; + char *buf = new char[s - escape_start + 1]; + memcpy(buf, escape_start, s - escape_start); + buf[s - escape_start] = '\0'; + b = new quoted_text_box(buf); + } + } + break; + case '-': + case '_': + { + char buf[2]; + buf[0] = c; + buf[1] = '\0'; + b = new special_char_box(buf); + } + break; + case '`': + b = new special_char_box("ga"); + break; + case '\'': + b = new special_char_box("aa"); + break; + case 'e': + case '\\': + b = new char_box('\\'); + break; + case '^': + case '|': + case '0': + { + char buf[3]; + buf[0] = '\\'; + buf[1] = c; + buf[2] = '\0'; + b = new quoted_text_box(strsave(buf)); + break; + } + default: + lex_error("unquoted escape"); + b = new quoted_text_box(strsave(s - 2)); + s = strchr(s, '\0'); + break; + } + break; + default: + normal_char: + b = new char_box(c); + break; + } + while (*s == '\'') { + if (b == 0) + b = new quoted_text_box(0); + b = new prime_box(b); + s++; + } + if (b != 0) { + if (lb != 0) + lb->append(b); + else if (fb != 0) { + lb = new list_box(fb); + lb->append(b); + } + else + fb = b; + } + } + free(text); + if (lb != 0) + return lb; + else if (fb != 0) + return fb; + else + return new quoted_text_box(0); +} + diff --git a/src/preproc/grn/README b/src/preproc/grn/README new file mode 100644 index 0000000..73273f7 --- /dev/null +++ b/src/preproc/grn/README @@ -0,0 +1,68 @@ +This is grn from the Berkeley ditroff distribution. It has no +AT&T code and is therefore freely distributable. + +Tim Theisen + +===================================================================== + +This is the modified code for the groff. It uses the different +devxxx format that is ascii rather than binary as in the +Berkeley distribution. Since groff does not have the \Ds option +for line drawing (dotted, dashed, etc.), this version includes +the routines for drawing curves and arcs, so it does not use the +\D~, \Da nor \Dc. Although also included in here is a routine +for drawing the optional gremlin style curves, it is not used +because the gremlin editor uses the conventional spline +algorithm. The Berkeley grn has the choice of different +stipples. Here, only different shades of gray will be painted +depending on the gremlin file. It is possible to upgrade this at +a later time. (Daniel Senderowicz 12/28/99) + +===================================================================== + +Gremlin produces three types of curves: B-Splines, interpolated +curves and Bezier. As the original Berkeley grn, now groff grn +will honor B-Splines and interpolated curves. Bezier curves will +be printed as B-Splines. (Daniel Senderowicz +10/04/02) + +===================================================================== + +It has been further modified by Werner Lemberg to fit +better into the groff package. + + . Replaced Makefile with Makefile.sub. + + . Removed dev.h since it is unused. + + . Renamed grn.1 to grn.man; this man page has been extensively + revised. + + . Used error() and fatal() from libgroff for all source files. + + . Renamed *.c to *.cpp; updates as needed for C++ (prototypes, proper + casts, standard header files etc). Heavy formatting. + + . main.cpp: + + Using groff's default values instead of DEVDIR, DEFAULTDEV, + PRINTER, TYPESETTER, and GREMLIB. + + 'res' is now an integer. + + Added '-C' command flag (for compatibility mode) as with other + preprocessors. + + Added '-F' and '-v' option (similar to troff). + + Renamed '-L' option to '-M' for consistence. + + Removed '-P' option. + + Using font::load_desc() for scanning DESC files. + + Removed SYSV-specific code. + + Using macro_path.open_file() for getting gremlin graphic files. + + Added usage(). diff --git a/src/preproc/grn/gprint.h b/src/preproc/grn/gprint.h new file mode 100644 index 0000000..772d79a --- /dev/null +++ b/src/preproc/grn/gprint.h @@ -0,0 +1,90 @@ +/* Last non-groff version: gprint.h 1.1 84/10/08 + * + * This file contains standard definitions used by the gprint program. + */ + +#include +#include + + +#define xorn(x,y) (x) + /* was 512 */ +#define yorn(x,y) (511 - (y)) /* switch direction for */ + /* y-coordinates */ + +#define STYLES 6 +#define SIZES 4 +#define FONTS 4 +#define SOLID -1 +#define DOTTED 004 /* 014 */ +#define DASHED 020 /* 034 */ +#define DOTDASHED 024 /* 054 */ +#define LONGDASHED 074 + +#define DEFTHICK -1 /* default thickness */ +#define DEFSTYLE SOLID /* default line style */ + +#define TRUE 1 +#define FALSE 0 + +#define nullelt -1 +#define nullpt -1 +#define nullun NULL + +#define BOTLEFT 0 +#define BOTRIGHT 1 +#define CENTCENT 2 +#define VECTOR 3 +#define ARC 4 +#define CURVE 5 +#define POLYGON 6 +#define BSPLINE 7 +#define BEZIER 8 +#define TOPLEFT 10 +#define TOPCENT 11 +#define TOPRIGHT 12 +#define CENTLEFT 13 +#define CENTRIGHT 14 +#define BOTCENT 15 +#define TEXT(t) ( (t <= CENTCENT) || (t >= TOPLEFT) ) + +/* WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING + * The above (TEXT) test is dependent on the relative values of the + * constants and will have to change if these values change or if new + * commands are added with value greater than BOTCENT + */ + +#define NUSER 4 +#define NFONTS 4 +#define NBRUSHES 6 +#define NSIZES 4 +#define NJUSTS 9 +#define NSTIPPLES 16 + +#define ADD 1 +#define DELETE 2 +#define MOD 3 + +typedef struct point { + double x, y; + struct point *nextpt; +} POINT; + +typedef struct elmt { + int type, brushf, size, textlength; + char *textpt; + POINT *ptlist; + struct elmt *nextelt, *setnext; +} ELT; + +#define DBNextElt(elt) (elt->nextelt) +#define DBNextofSet(elt) (elt->setnext) +#define DBNullelt(elt) (elt == NULL) +#define Nullpoint(pt) ((pt) == (POINT *) NULL) +#define PTNextPoint(pt) (pt->nextpt) + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/grn/grn.1.man b/src/preproc/grn/grn.1.man new file mode 100644 index 0000000..cbc15ae --- /dev/null +++ b/src/preproc/grn/grn.1.man @@ -0,0 +1,978 @@ +'\" t +.TH @g@grn @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +@g@grn \- embed Gremlin images in +.I groff +documents +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 2000-2020 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_grn_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY @g@grn +.RB [ \-C ] +.RB [ \-T\~\c +.IR dev ] +.RB [ \-M\~\c +.IR dir ] +.RB [ \-F\~\c +.IR dir ] +.RI [ file\~ .\|.\|.] +.YS +. +. +.SY @g@grn +.B \-? +. +.SY @g@grn +.B \-\-help +.YS +. +. +.SY @g@grn +.B \-v +. +.SY @g@grn +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I @g@grn +is a preprocessor for including +.I gremlin +pictures in +.MR @g@troff @MAN1EXT@ +input. +. +.I @g@grn +writes to standard output, +processing only input lines between two that start with +.B .GS +and +.BR .GE . +. +Those lines must contain +.I @g@grn +commands +(see below). +. +These macros request a +.I gremlin +file; +the picture in that file is converted and placed in the +.I @g@troff +input stream. +. +.B .GS +may be called with a +.BR C , +.BR L , +or +.B R +argument to center, +left-, +or right-justify the whole +.I gremlin +picture +(the default is to center). +. +If no +.I file +is mentioned, +the standard input is read. +. +At the end of the picture, +the position on the page is the bottom of the +.I gremlin +picture. +. +If the +.I @g@grn +entry is ended with +.B .GF +instead of +.BR .GE , +the position is left at the top of the picture. +. +. +.PP +Currently only the +.I me +macro package has support for +.BR .GS , +.BR .GE , +and +.BR .GF . +. +. +.PP +.I @g@grn +produces drawing escape sequences that use +.IR groff 's +color scheme extension +.RB ( \[rs]D\[aq]F \~.\|.\|.\& \[aq] ), +and thus may not work with other +.IR troff s. +. +. +.\" ==================================================================== +.SS "\f[I]grn\f[] commands" +.\" ==================================================================== +. +Each input line between +.B .GS +and +.B .GE +may have one +.I @g@grn +command. +. +Commands consist of one or two strings separated by white space, +the first string being the command and the second its operand. +. +Commands may be upper- or lowercase and abbreviated down to one +character. +. +. +.PP +Commands that affect a picture's environment +(those listed before +.RB \%\[lq] default \[rq], +see below) +are only in effect for the current picture: +the environment is reinitialized to the defaults at the start of the +next picture. +. +The commands are as follows. +. +. +.TP +.BI 1\~ N +.TQ +.BI 2\~ N +.TQ +.BI 3\~ N +.TQ +.BI 4\~ N +. +Set +.IR gremlin 's +text size number 1 +(2, +3, +or 4) +to +.I N +points. +. +The default is 12 +(16, +24, +and 36, +respectively). +. +. +.TP +.BI roman\~ f +.TQ +.BI italics\~ f +.TQ +.BI bold\~ f +.TQ +.BI special\~ f +Set the roman +(italics, +bold, +or special) +font to +.IR @g@troff 's +font +.I f +(either a name or number). +. +The default is R +(I, +B, +and S, +respectively). +. +. +.TP +.BI l\~ f +.TQ +.BI stipple\~ f +Set the stipple font to +.IR @g@troff 's +stipple font +.I f +(name or number). +. +The command +.B \%stipple +may be abbreviated down as far as +.RB \[lq] st \[rq] +(to avoid confusion with +.RB \%\[lq] special \[rq]). +. +There is +.I no +default for stipples +(unless one is set by the +.RB \%\[lq] default \[rq] +command), +and it is invalid to include a +.I gremlin +picture with polygons without specifying a stipple font. +. +. +.TP +.BI x\~ N +.TQ +.BI scale\~ N +Magnify the picture +(in addition to any default magnification) +by +.IR N , +a floating-point number larger than zero. +. +The command +.B scale +may be abbreviated down to +.RB \[lq] sc \[rq]. +. +. +.TP +.BI narrow\~ N +.TQ +.BI medium\~ N +.TQ +.BI thick\~ N +. +Set the thickness of +.IR gremlin 's +narrow +(medium and thick, +respectively) +lines to +.I N +times 0.15pt +(this value can be changed at compile time). +. +The default is 1.0 +(3.0 and 5.0, +respectively), +which corresponds to 0.15pt +(0.45pt and 0.75pt, +respectively). +. +A thickness value of zero selects the smallest available line thickness. +. +Negative values cause the line thickness to be proportional to the +current point size. +. +. +.TP +.BR pointscale\~ [ off | on ] +Scale text to match the picture. +. +Gremlin text is usually printed in the point size specified with the +commands +.BR 1 , +.BR 2 , +.BR 3 , +.RB or\~ 4 , +regardless of any scaling factors in the picture. +. +Setting +.B pointscale +will cause the point sizes to scale with the picture +(within +.IR @g@troff 's +limitations, +of course). +. +An operand of anything but +.B off +will turn text scaling on. +. +. +.TP +.B default +Reset the picture environment defaults to the settings in the current +picture. +. +This is meant to be used as a global parameter setting mechanism at +the beginning of the +.I @g@troff +input file, +but can be used at any time to reset the default settings. +. +. +.TP +.BI width\~ N +Force the picture to be +.I N +inches wide. +. +This overrides any scaling factors present in the same picture. +. +.RB \[lq] "width 0" \[rq] +is ignored. +. +. +.TP +.BI height\~ N +Force the picture to be +.I N +inches high, +overriding other scaling factors. +. +If both +.B width +and +.B height +are specified, +the tighter constraint will determine the scale of the picture. +. +.B height +and +.B width +commands are not saved with a +.RB \%\[lq] default \[rq] +command. +. +They will, +however, +affect point size scaling if that option is set. +. +. +.TP +.BI file\~ name +Get picture from +.I gremlin +file +.I name +located the current directory +(or in the library directory; +see the +.B \-M +option above). +. +If multiple +.B file +commands are given, +the last one controls. +. +If +.I name +doesn't exist, +an error message is reported and processing continues from the +.B .GE +line. +. +. +.\" ==================================================================== +.SS "Usage with \f[I]groff\f[]" +.\" ==================================================================== +. +Since +.I @g@grn +is a preprocessor, +it has no access to elements of formatter state, +such as +indentation, +line length, +type size, +or +register values. +. +Consequently, +no +.I @g@troff +input can be placed between the +.B .GS +and +.B .GE +macros. +. +However, +.I gremlin +text elements are subsequently processed by +.IR @g@troff , +so anything valid in a single line of +.I @g@troff +input is valid in a line of +.I gremlin +text +(barring the dot control character \[lq].\[rq] at the beginning of a +line). +. +Thus, +it is possible to have equations within a +.I gremlin +figure by including in the +.I gremlin +file +.I eqn \" language +expressions enclosed by previously defined delimiters +(e.g., +\[lq]$$\[rq]). +. +. +.PP +When using +.I @g@grn +along with other preprocessors, +it is best to run +.MR @g@tbl @MAN1EXT@ +before +.IR @g@grn , +.MR @g@pic @MAN1EXT@ , +and/or +.I ideal \" no GNU version yet +to avoid overworking +.IR @g@tbl . +. +.MR @g@eqn @MAN1EXT@ +should always be run last. +. +.MR groff @MAN1EXT@ +will automatically run preprocessors in the correct order. +. +. +.PP +A picture is considered an entity, +but that doesn't stop +.I @g@troff +from trying to break it up if it falls off the end of a page. +. +Placing the picture between \[lq]keeps\[rq] in the +.I me +macros will ensure proper placement. +. +. +.PP +.I @g@grn +uses +.IR @g@troff 's +registers +.B g1 +through +.B g9 +and sets registers +.B g1 +and +.B g2 +to the width and height of the +.I gremlin +figure +(in device units) +before entering the +.B .GS +macro +(this is for those who want to rewrite these macros). +. +. +.\" ==================================================================== +.SS "Gremlin file format" +.\" ==================================================================== +. +There exist two distinct +.I gremlin +file formats: +the original format for AED graphic terminals, +and the Sun or X11 version. +. +An extension used by the Sun/X11 version allowing reference points with +negative coordinates is +.I not +compatible with the AED version. +. +As long as a +.I gremlin +file does not contain negative coordinates, +either format will be read correctly by either version of +.I gremlin +or +.IR @g@grn . +. +The other difference in +Sun/X11 format is the use of names for picture objects +(e.g., +.BR POLYGON , +.BR CURVE ) +instead of numbers. +. +Files representing the same picture are shown below. +. +. +.PP +.ie t .ne 18v +.el .ne 19v +.TS +center, tab(@); +l lw(0.1i) l. +sungremlinfile@@gremlinfile +0 240.00 128.00@@0 240.00 128.00 +CENTCENT@@2 +240.00 128.00@@240.00 128.00 +185.00 120.00@@185.00 120.00 +240.00 120.00@@240.00 120.00 +296.00 120.00@@296.00 120.00 +*@@\-1.00 \-1.00 +2 3@@2 3 +10 A Triangle@@10 A Triangle +POLYGON@@6 +224.00 416.00@@224.00 416.00 +96.00 160.00@@96.00 160.00 +384.00 160.00@@384.00 160.00 +*@@\-1.00 \-1.00 +5 1@@5 1 +0@@0 +\-1@@\-1 +.TE +. +. +.IP \[bu] 2n +The first line of each +.I gremlin +file contains either the string +.RB \[lq] gremlinfile \[rq] +(AED) +or +.RB \[lq] sungremlinfile \[rq] +(Sun/X11). +. +. +.IP \[bu] +The second line of the file contains an orientation and +.I x +and +.I y +values for a positioning point, +separated by spaces. +. +The orientation, +either +.B 0 +or +.BR 1 , +is ignored by the Sun/X11 version. +. +.B 0 +means that +.I gremlin +will display things in horizontal format +(a drawing area wider than it is tall, +with a menu across the top). +. +.B 1 +means that +.I gremlin +will display things in vertical format +(a drawing area taller than it is wide, +with a menu on the left side). +. +.I x +and +.I y +are floating-point values giving a positioning point to be used when +this file is read into another file. +. +The stuff on this line really isn't all that important; +a value of +.RB \[lq] "1 0.00 0.00" \[rq] +is suggested. +. +. +.IP \[bu] +The rest of the file consists of zero or more element specifications. +. +After the last element specification is a line containing the string +.RB \[lq] \-1 \[rq]. +. +. +.IP \[bu] +Lines longer than 127 characters are truncated to that length. +. +. +.\" ==================================================================== +.SS "Element specifications" +.\" ==================================================================== +. +.IP \[bu] 2n +The first line of each element contains a single decimal number giving +the type of the element (AED) or its name (Sun/X11). +. +. +.IP +.ie t .ne 18v +.el .ne 19v +.TS +center, tab(@); +css +ccc +nBlBl. +\f[I]gremlin\f[] File Format: Object Type Specification +_ +AED Number@Sun/X11 Name@Description +0@BOTLEFT@bottom-left-justified text +1@BOTRIGHT@bottom-right-justified text +2@CENTCENT@center-justified text +3@VECTOR@vector +4@ARC@arc +5@CURVE@curve +6@POLYGON@polygon +7@BSPLINE@b-spline +8@BEZIER@B\['e]zier +10@TOPLEFT@top-left-justified text +11@TOPCENT@top-center-justified text +12@TOPRIGHT@top-right-justified text +13@CENTLEFT@left-center-justified text +14@CENTRIGHT@right-center-justified text +15@BOTCENT@bottom-center-justified text +.TE +. +. +.IP \[bu] +After the object type comes a variable number of lines, +each specifying a point used to display the element. +. +Each line contains an x-coordinate and a y-coordinate in floating-point +format, +separated by spaces. +. +The list of points is terminated by a line containing the string +.RB \[lq] "\-1.0 \-1.0" \[rq] +(AED) or a single asterisk, +.RB \[lq] * \[rq] +(Sun/X11). +. +. +.IP \[bu] +After the points comes a line containing two decimal values, +giving the brush and size for the element. +. +The brush determines the style in which things are drawn. +. +For vectors, +arcs, +and curves there are six valid brush values. +. +. +.IP +.TS +center, tab(@); +nB l. +1@thin dotted lines +2@thin dot-dashed lines +3@thick solid lines +4@thin dashed lines +5@thin solid lines +6@medium solid lines +.TE +. +. +.IP +For polygons, +one more value, +0, +is valid. +. +It specifies a polygon with an invisible border. +. +For text, +the brush selects a font as follows. +. +. +.IP +.TS +center, tab(@); +nB l. +1@roman (R font in \f[I]@g@troff\f[]) +2@italics (I font in \f[I]@g@troff\f[]) +3@bold (B font in \f[I]@g@troff\f[]) +4@special (S font in \f[I]@g@troff\f[]) +.TE +. +. +.IP +If you're using +.I @g@grn +to run your pictures through +.IR groff , +the font is really just a starting font. +. +The text string can contain formatting sequences like +\[lq]\[rs]fI\[rq] +or +\[lq]\[rs]d\[rq] +which may change the font +(as well as do many other things). +. +For text, +the size field is a decimal value between 1 and 4. +. +It selects the size of the font in which the text will be drawn. +. +For polygons, +this size field is interpreted as a stipple number to fill the polygon +with. +. +The number is used to index into a stipple font at print time. +. +. +.IP \[bu] +The last line of each element contains a decimal number and a string of +characters, +separated by a single space. +. +The number is a count of the number of characters in the string. +. +This information is used only for text elements, +and contains the text string. +. +There can be spaces inside the text. +. +For arcs, +curves, +and vectors, +the character count is zero +.RB ( 0 ), +followed by exactly one space before the newline. +. +. +.\" ==================================================================== +.SS Coordinates +.\" ==================================================================== +. +.I gremlin +was designed for AED terminals, +and its coordinates reflect the AED coordinate space. +. +For vertical pictures, +.IR x \~values +range 116 to 511, +and +.IR y \~values +from 0 to 483. +. +For horizontal pictures, +.IR x \~values +range from 0 to 511, +and +.IR y \~values +from 0 to 367. +. +Although you needn't absolutely stick to this range, +you'll get better results if you at least stay in this vicinity. +. +Also, +point lists are terminated by a point of +(\-1, +\-1), +so you shouldn't ever use negative coordinates. +. +.I gremlin +writes out coordinates using the +.MR printf 3 +format \[lq]%f1.2\[rq]; +it's probably a good idea to use the same format if you want to modify +the +.I @g@grn +code. +. +. +.\" ==================================================================== +.SS "Sun/X11 coordinates" +.\" ==================================================================== +. +There is no restriction on the range of coordinates used to create +objects in the Sun/X11 version of +.IR gremlin . +. +However, +files with negative coordinates +.I will +cause problems if displayed on the AED. +. +. +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-?\& +and +.B \-\-help +display a usage message, +while +.B \-v +and +.B \-\-version +show version information; +all exit afterward. +. +. +.TP +.B \-C +Recognize +.B .GS +and +.B .GE +(and +.BR .GF ) +even when followed by a character other than space or newline. +. +. +.TP +.BI \-F\~ dir +Search +.I dir +for subdirectories +.IR dev name +.RI ( name +is the name of the output driver) +for the +.I DESC +file before the default font directories +.IR @LOCALFONTDIR@ , +.IR @FONTDIR@ , +and +.IR @LEGACYFONTDIR@ . +. +. +.TP +.BI \-M\~ dir +Prepend +.I dir +to the search path for +.I gremlin +files. +. +The default search path is the current directory, +the home directory, +.if !'@COMPATIBILITY_WRAPPERS@'no' .IR @SYSTEMMACRODIR@ , +.IR @LOCALMACRODIR@ , +and +.IR @MACRODIR@ , +in that order. +.\". +.\". +.\".TP +.\".B \-s +.\"This switch causes the picture to be traversed twice: +.\"The first time, +.\"only the interiors of filled polygons +.\"(as borderless polygons) +.\"are printed. +.\". +.\"The second time, +.\"the outline is printed as a series of line segments. +.\". +.\"This way, +.\"postprocessors that overwrite rather than merge picture elements +.\"(such as PostScript) +.\"can still have text and graphics on a shaded background. +. +. +.TP +.BI \-T\~ dev +Prepare device output using output driver +.IR dev . +. +The default is +.BR @DEVICE@ . +. +See +.MR groff @MAN1EXT@ +for a list of valid devices. +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.IR @FONTDIR@/\:\%dev name /\:DESC +describes the output device +.IR name . +. +. +.\" ==================================================================== +.SH Authors +.\" ==================================================================== +. +David Slattengren and Barry Roitblat wrote the original Berkeley +.IR grn . +. +Daniel Senderowicz and Werner Lemberg modified it for +.IR groff . +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.MR gremlin 1 , +.MR groff @MAN1EXT@ , +.MR @g@pic @MAN1EXT@ , +.MR ideal 1 +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_grn_1_man_C] +.do rr *groff_grn_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/preproc/grn/grn.am b/src/preproc/grn/grn.am new file mode 100644 index 0000000..f45fa24 --- /dev/null +++ b/src/preproc/grn/grn.am @@ -0,0 +1,35 @@ +# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# +# This file 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 . + +prefixexecbin_PROGRAMS += grn +grn_SOURCES = \ + src/preproc/grn/hdb.cpp \ + src/preproc/grn/hpoint.cpp \ + src/preproc/grn/hgraph.cpp \ + src/preproc/grn/main.cpp \ + src/preproc/grn/gprint.h +src/preproc/grn/main.$(OBJEXT): defs.h +grn_LDADD = libgroff.a lib/libgnu.a $(LIBM) +PREFIXMAN1 += src/preproc/grn/grn.1 +EXTRA_DIST += src/preproc/grn/README src/preproc/grn/grn.1.man + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/preproc/grn/hdb.cpp b/src/preproc/grn/hdb.cpp new file mode 100644 index 0000000..9ba3eaa --- /dev/null +++ b/src/preproc/grn/hdb.cpp @@ -0,0 +1,441 @@ + /* Last non-groff version: hdb.c 1.8 (Berkeley) 84/10/20 + * + * Copyright -C- 1982 Barry S. Roitblat + * + * This file contains database routines for the hard copy programs of + * the gremlin picture editor. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "gprint.h" +#include +#include + +#include "errarg.h" +#include "error.h" + +#define MAXSTRING 128 +#define MAXSTRING_S "127" + +/* imports from main.cpp */ + +extern char gremlinfile[]; /* name of file currently reading */ +extern int SUNFILE; /* TRUE if SUN gremlin file */ +extern int compatibility_flag; /* TRUE if in compatibility mode */ +extern void *grnmalloc(size_t size, const char *what); +extern void savebounds(double x, double y); + +/* imports from hpoint.cpp */ + +extern POINT *PTInit(); +extern POINT *PTMakePoint(double x, double y, POINT ** pplist); + + +int DBGetType(char *s); + +static long lineno = 0; /* line number of gremlin file */ + +/* + * This routine returns a pointer to an initialized database element + * which would be the only element in an empty list. + */ +ELT * +DBInit() +{ + return ((ELT *) NULL); +} /* end DBInit */ + + +/* + * This routine creates a new element with the specified attributes and + * links it into database. + */ +ELT * +DBCreateElt(int type, + POINT * pointlist, + int brush, + int size, + char *text, + ELT **db) +{ + ELT *temp = 0; + + temp = (ELT *) grnmalloc(sizeof(ELT), "picture element"); + temp->nextelt = *db; + temp->type = type; + temp->ptlist = pointlist; + temp->brushf = brush; + temp->size = size; + temp->textpt = text; + *db = temp; + return (temp); +} /* end CreateElt */ + + +/* + * This routine reads the specified file into a database and returns a + * pointer to that database. + */ +ELT * +DBRead(FILE *file) +{ + int i; + int done; /* flag for input exhausted */ + double nx; /* x holder so x is not set before orienting */ + int type; /* element type */ + ELT *elist; /* pointer to the file's elements */ + POINT *plist; /* pointer for reading in points */ + char string[MAXSTRING], *txt; + double x, y; /* x and y are read in point coords */ + int len, brush, size; + int lastpoint; + + SUNFILE = FALSE; + elist = DBInit(); + int nitems = fscanf(file, "%" MAXSTRING_S "s%*[^\n]\n", string); + if (nitems != 1) { + error_with_file_and_line(gremlinfile, lineno, + "malformed input; giving up on this" + " picture"); + return (elist); + } + lineno++; + if (strcmp(string, "gremlinfile")) { + if (strcmp(string, "sungremlinfile")) { + error_with_file_and_line(gremlinfile, lineno, + "not a gremlin file; giving up on this" + " picture"); + return (elist); + } + SUNFILE = TRUE; + } + + nitems = fscanf(file, "%d%lf%lf\n", &size, &x, &y); + if (nitems != 3) { + error_with_file_and_line(gremlinfile, lineno, + "malformed input; giving up on this" + " picture"); + return (elist); + } + lineno++; + /* ignore orientation and file positioning point */ + + done = FALSE; + while (!done) { + /* if (fscanf(file,"%" MAXSTRING_S "s\n", string) == EOF) */ + /* I changed the scanf format because the element */ + /* can have two words (e.g. CURVE SPLINE) */ + if (fscanf(file, "\n%" + MAXSTRING_S + "[^\n]%*[^\n]\n", string) == EOF) { + lineno++; + error_with_file_and_line(gremlinfile, lineno, "error in format;" + " giving up on this picture"); + return (elist); + } + lineno++; + + type = DBGetType(string); /* interpret element type */ + if (type < 0) { /* no more data */ + done = TRUE; + } else { + /* always one point */ +#ifdef UW_FASTSCAN + (void) xscanf(file, &x, &y); +#else + nitems = fscanf(file, "%lf%lf\n", &x, &y); + if (nitems != 2) { + error_with_file_and_line(gremlinfile, lineno, + "malformed input; giving up on this" + " picture"); + return (elist); + } + lineno++; +#endif /* UW_FASTSCAN */ + plist = PTInit(); /* NULL point list */ + + /* + * Files created on the SUN have point lists terminated by a line + * containing only an asterisk ('*'). Files created on the AED + * have point lists terminated by the coordinate pair (-1.00 + * -1.00). + */ + if (TEXT(type)) { /* read only first point for TEXT elements */ + nx = xorn(x, y); + y = yorn(x, y); + (void) PTMakePoint(nx, y, &plist); + savebounds(nx, y); + +#ifdef UW_FASTSCAN + while (xscanf(file, &x, &y)); +#else + lastpoint = FALSE; + do { + char *cp = fgets(string, MAXSTRING, file); + if (0 /* nullptr */ == cp) { + error_with_file_and_line(gremlinfile, lineno, + "premature end-of-file or error" + " reading input; giving up on this" + " picture"); + return(elist); + } + lineno++; + if (string[0] == '*') { /* SUN gremlin file */ + lastpoint = TRUE; + } else { + if (!sscanf(string, "%lf%lf", &x, &y)) { + error_with_file_and_line(gremlinfile, lineno, + "expected coordinate pair, got" + " '%1'; giving up on this" + " picture", string); + return(elist); + } + if ((x == -1.00 && y == -1.00) && (!SUNFILE)) + lastpoint = TRUE; + else { + if (compatibility_flag) + savebounds(xorn(x, y), yorn(x, y)); + } + } + } while (!lastpoint); +#endif /* UW_FASTSCAN */ + } else { /* not TEXT element */ +#ifdef UW_FASTSCAN + do { + nx = xorn(x, y); + y = yorn(x, y); + (void) PTMakePoint(nx, y, &plist); + savebounds(nx, y); + } while (xscanf(file, &x, &y)); +#else + lastpoint = FALSE; + while (!lastpoint) { + nx = xorn(x, y); + y = yorn(x, y); + (void) PTMakePoint(nx, y, &plist); + savebounds(nx, y); + + char *cp = fgets(string, MAXSTRING, file); + if (0 /* nullptr */ == cp) { + error_with_file_and_line(gremlinfile, lineno, + "premature end-of-file or error" + " reading input; giving up on this" + " picture"); + return(elist); + } + lineno++; + if (string[0] == '*') { /* SUN gremlin file */ + lastpoint = TRUE; + } else { + (void) sscanf(string, "%lf%lf", &x, &y); + if ((x == -1.00 && y == -1.00) && (!SUNFILE)) + lastpoint = TRUE; + } + } +#endif /* UW_FASTSCAN */ + } + nitems = fscanf(file, "%d%d\n", &brush, &size); + if (nitems != 2) { + error_with_file_and_line(gremlinfile, lineno, + "malformed input; giving up on this" + " picture"); + return (elist); + } + lineno++; + nitems = fscanf(file, "%d", &len); /* text length */ + if (nitems != 1) { + error_with_file_and_line(gremlinfile, lineno, + "malformed input; giving up on this" + " picture"); + return (elist); + } + (void) getc(file); /* eat blank */ + lineno++; /* advance line counter early */ + if (len < 0) { + error_with_file_and_line(gremlinfile, lineno, + "length claimed for text is nonsense:" + " '%1'; giving up on this picture", + len); + return (elist); + } + txt = (char *) grnmalloc((unsigned) len + 1, "element text"); + for (i = 0; i < len; ++i) { /* read text */ + int c = getc(file); + if (c == EOF) + break; + txt[i] = c; + } + if (feof(file)) { + error_with_file_and_line(gremlinfile, lineno, + "end of file while reading text of" + " length %1; giving up on this" + " picture", len); + return (elist); + } + txt[len] = '\0'; + (void) DBCreateElt(type, plist, brush, size, txt, &elist); + } /* end else */ + } /* end while not done */ ; + return (elist); +} /* end DBRead */ + + +/* + * Interpret element type in string s. + * Old file format consisted of integer element types. + * New file format has literal names for element types. + */ +int +DBGetType(char *s) +{ + if (isdigit(s[0]) || (s[0] == '-')) /* old element format or EOF */ + return (atoi(s)); + + switch (s[0]) { + case 'P': + return (POLYGON); + case 'V': + return (VECTOR); + case 'A': + return (ARC); + case 'C': + if (s[1] == 'U') { + if (s[5] == '\n') + return (CURVE); + switch (s[7]) { + case 'S': + return(BSPLINE); + case 'E': + warning_with_file_and_line(gremlinfile, lineno, + "using B-spline for Bezier curve"); + return(BSPLINE); + default: + return(CURVE); + } + } + switch (s[4]) { + case 'L': + return (CENTLEFT); + case 'C': + return (CENTCENT); + case 'R': + return (CENTRIGHT); + default: + error_with_file_and_line(gremlinfile, lineno, + "unknown element type '%1'", s); + return -1; + } + case 'B': + switch (s[3]) { + case 'L': + return (BOTLEFT); + case 'C': + return (BOTCENT); + case 'R': + return (BOTRIGHT); + default: + error_with_file_and_line(gremlinfile, lineno, + "unknown element type '%1'", s); + return -1; + } + case 'T': + switch (s[3]) { + case 'L': + return (TOPLEFT); + case 'C': + return (TOPCENT); + case 'R': + return (TOPRIGHT); + default: + error_with_file_and_line(gremlinfile, lineno, + "unknown element type '%1'", s); + return -1; + } + default: + error_with_file_and_line(gremlinfile, lineno, + "unknown element type '%1'", s); + return -1; + } +} + +#ifdef UW_FASTSCAN +/* + * Optimization hack added by solomon@crys.wisc.edu, 12/2/86. + * A huge fraction of the time was spent reading floating point numbers + * from the input file, but the numbers always have the format 'ddd.dd'. + * Thus the following special-purpose version of fscanf. + * + * xscanf(f,xp,yp) does roughly what fscanf(f,"%f%f",xp,yp) does except: + * -the next piece of input must be of the form + * * *'.'* * *'.'* + * -xscanf eats the character following the second number + * -xscanf returns 0 for "end-of-data" indication, 1 otherwise, where + * end-of-data is signalled by a '*' [in which case the rest of the + * line is gobbled], or by '-1.00 -1.00' [but only if !SUNFILE]. + */ +int +xscanf(FILE *f, + double *xp, + double *yp) +{ + int c, i, j, m, frac; + int iscale = 1, jscale = 1; /* x = i/scale, y=j/jscale */ + + while ((c = getc(f)) == ' '); + if (c == '*') { + while ((c = getc(f)) != '\n'); + return 0; + } + i = m = frac = 0; + while (isdigit(c) || c == '.' || c == '-') { + if (c == '-') { + m++; + c = getc(f); + continue; + } + if (c == '.') + frac = 1; + else { + if (frac) + iscale *= 10; + i = 10 * i + c - '0'; + } + c = getc(f); + } + if (m) + i = -i; + *xp = (double) i / (double) iscale; + + while ((c = getc(f)) == ' '); + j = m = frac = 0; + while (isdigit(c) || c == '.' || c == '-') { + if (c == '-') { + m++; + c = getc(f); + continue; + } + if (c == '.') + frac = 1; + else { + if (frac) + jscale *= 10; + j = 10 * j + c - '0'; + } + c = getc(f); + } + if (m) + j = -j; + *yp = (double) j / (double) jscale; + return (SUNFILE || i != -iscale || j != -jscale); +} +#endif /* UW_FASTSCAN */ + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/grn/hgraph.cpp b/src/preproc/grn/hgraph.cpp new file mode 100644 index 0000000..9ed81a4 --- /dev/null +++ b/src/preproc/grn/hgraph.cpp @@ -0,0 +1,1060 @@ +/* Last non-groff version: hgraph.c 1.14 (Berkeley) 84/11/27 + * + * This file contains the graphics routines for converting gremlin + * pictures to troff input. + */ + +#include "lib.h" + +#include "gprint.h" + +#define MAXVECT 40 +#define MAXPOINTS 200 +#define LINELENGTH 1 +#define PointsPerInterval 64 +#define pi 3.14159265358979324 +#define twopi (2.0 * pi) +#define len(a, b) groff_hypot((double)(b.x-a.x), \ + (double)(b.y-a.y)) + + +extern int dotshifter; /* for the length of dotted curves */ + +extern int style[]; /* line and character styles */ +extern double thick[]; +extern char *tfont[]; +extern int tsize[]; +extern int stipple_index[]; /* stipple font idx for stipples 0-16 */ +extern char *stipple; /* stipple type (cf or ug) */ + + +extern double troffscale; /* imports from main.c */ +extern double linethickness; +extern int linmod; +extern int lastx; +extern int lasty; +extern int lastyline; +extern int ytop; +extern int ybottom; +extern int xleft; +extern int xright; +extern enum E { + OUTLINE, FILL, BOTH +} polyfill; + +extern double adj1; +extern double adj2; +extern double adj3; +extern double adj4; +extern int res; + +void HGSetFont(int font, int size); +void HGPutText(int justify, POINT pnt, char *string); +void HGSetBrush(int mode); +void tmove2(int px, int py); +void doarc(POINT cp, POINT sp, int angle); +void tmove(POINT * ptr); +void cr(); +void drawwig(POINT * ptr, int type); +void HGtline(int x1, int y1); +void deltax(double x); +void deltay(double y); +void HGArc(int cx, int cy, int px, int py, int angle); +void picurve(int *x, int *y, int npts); +void HGCurve(int *x, int *y, int numpoints); +void Parameterize(int x[], int y[], double h[], int n); +void PeriodicSpline(double h[], int z[], + double dz[], double d2z[], double d3z[], + int npoints); +void NaturalEndSpline(double h[], int z[], + double dz[], double d2z[], double d3z[], + int npoints); + + + +/*--------------------------------------------------------------------* + | Routine: HGPrintElt (element_pointer, baseline) + | + | Results: Examines a picture element and calls the appropriate + | routine(s) to print them according to their type. After + | the picture is drawn, current position is (lastx,lasty). + *--------------------------------------------------------------------*/ + +void +HGPrintElt(ELT *element, + int /* baseline */) +{ + POINT *p1; + POINT *p2; + int length; + int graylevel; + + if (!DBNullelt(element) && !Nullpoint((p1 = element->ptlist))) { + /* p1 always has first point */ + if (TEXT(element->type)) { + HGSetFont(element->brushf, element->size); + switch (element->size) { + case 1: + p1->y += adj1; + break; + case 2: + p1->y += adj2; + break; + case 3: + p1->y += adj3; + break; + case 4: + p1->y += adj4; + break; + default: + break; + } + HGPutText(element->type, *p1, element->textpt); + } else { + if (element->brushf) /* if there is a brush, the */ + HGSetBrush(element->brushf); /* graphics need it set */ + + switch (element->type) { + + case ARC: + p2 = PTNextPoint(p1); + tmove(p2); + doarc(*p1, *p2, element->size); + cr(); + break; + + case CURVE: + length = 0; /* keep track of line length */ + drawwig(p1, CURVE); + cr(); + break; + + case BSPLINE: + length = 0; /* keep track of line length */ + drawwig(p1, BSPLINE); + cr(); + break; + + case VECTOR: + length = 0; /* keep track of line length so */ + tmove(p1); /* single lines don't get long */ + while (!Nullpoint((p1 = PTNextPoint(p1)))) { + HGtline((int) (p1->x * troffscale), + (int) (p1->y * troffscale)); + if (length++ > LINELENGTH) { + length = 0; + printf("\\\n"); + } + } /* end while */ + cr(); + break; + + case POLYGON: + { + /* brushf = style of outline; size = color of fill: + * on first pass (polyfill=FILL), do the interior using 'P' + * unless size=0 + * on second pass (polyfill=OUTLINE), do the outline using a + * series of vectors. It might make more sense to use \D'p + * ...', but there is no uniform way to specify a 'fill + * character' that prints as 'no fill' on all output + * devices (and stipple fonts). + * If polyfill=BOTH, just use the \D'p ...' command. + */ + double firstx = p1->x; + double firsty = p1->y; + + length = 0; /* keep track of line length so */ + /* single lines don't get long */ + + if (polyfill == FILL || polyfill == BOTH) { + /* do the interior */ + char command = (polyfill == BOTH && element->brushf) + ? 'p' : 'P'; + + /* include outline, if there is one and */ + /* the -p flag was set */ + + /* switch based on what gremlin gives */ + switch (element->size) { + case 1: + graylevel = 1; + break; + case 3: + graylevel = 2; + break; + case 12: + graylevel = 3; + break; + case 14: + graylevel = 4; + break; + case 16: + graylevel = 5; + break; + case 19: + graylevel = 6; + break; + case 21: + graylevel = 7; + break; + case 23: + graylevel = 8; + break; + default: /* who's giving something else? */ + graylevel = NSTIPPLES; + break; + } + /* int graylevel = element->size; */ + + if (graylevel < 0) + break; + if (graylevel > NSTIPPLES) + graylevel = NSTIPPLES; + printf("\\D'Fg %.3f'", + double(1000 - stipple_index[graylevel]) / 1000.0); + cr(); + tmove(p1); + printf("\\D'%c", command); + + while (!Nullpoint((PTNextPoint(p1)))) { + p1 = PTNextPoint(p1); + deltax((double) p1->x); + deltay((double) p1->y); + if (length++ > LINELENGTH) { + length = 0; + printf("\\\n"); + } + } /* end while */ + + /* close polygon if not done so by user */ + if ((firstx != p1->x) || (firsty != p1->y)) { + deltax((double) firstx); + deltay((double) firsty); + } + putchar('\''); + cr(); + break; + } + /* else polyfill == OUTLINE; only draw the outline */ + if (!(element->brushf)) + break; + length = 0; /* keep track of line length */ + tmove(p1); + + while (!Nullpoint((PTNextPoint(p1)))) { + p1 = PTNextPoint(p1); + HGtline((int) (p1->x * troffscale), + (int) (p1->y * troffscale)); + if (length++ > LINELENGTH) { + length = 0; + printf("\\\n"); + } + } /* end while */ + + /* close polygon if not done so by user */ + if ((firstx != p1->x) || (firsty != p1->y)) { + HGtline((int) (firstx * troffscale), + (int) (firsty * troffscale)); + } + cr(); + break; + } /* end case POLYGON */ + } /* end switch */ + } /* end else Text */ + } /* end if */ +} /* end PrintElt */ + + +/*---------------------------------------------------------------------* + | Routine: HGPutText (justification, position_point, string) + | + | Results: Given the justification, a point to position with, and a + | string to put, HGPutText first sends the string into a + | diversion, moves to the positioning point, then outputs + | local vertical and horizontal motions as needed to + | justify the text. After all motions are done, the + | diversion is printed out. + *--------------------------------------------------------------------*/ + +void +HGPutText(int justify, + POINT pnt, + char *string) +{ + int savelasty = lasty; /* vertical motion for text is to be */ + /* ignored. Save current y here */ + + printf(".nr g8 \\n(.d\n"); /* save current vertical position. */ + printf(".ds g9 \""); /* define string containing the text. */ + while (*string) { /* put out the string */ + if (*string == '\\' && + *(string + 1) == '\\') { /* one character at a */ + printf("\\\\\\"); /* time replacing // */ + string++; /* by //// to prevent */ + } /* interpretation at */ + printf("%c", *(string++)); /* printout time */ + } + printf("\n"); + + tmove(&pnt); /* move to positioning point */ + + switch (justify) { + /* local vertical motions--the numbers here are used to be + somewhat compatible with gprint */ + case CENTLEFT: + case CENTCENT: + case CENTRIGHT: + printf("\\v'0.85n'"); /* down half */ + break; + + case TOPLEFT: + case TOPCENT: + case TOPRIGHT: + printf("\\v'1.7n'"); /* down whole */ + } + + switch (justify) { + /* local horizontal motions */ + case BOTCENT: + case CENTCENT: + case TOPCENT: + printf("\\h'-\\w'\\*(g9'u/2u'"); /* back half */ + break; + + case BOTRIGHT: + case CENTRIGHT: + case TOPRIGHT: + printf("\\h'-\\w'\\*(g9'u'"); /* back whole */ + } + + printf("\\&\\*(g9\n"); /* now print the text. */ + printf(".sp |\\n(g8u\n"); /* restore vertical position */ + lasty = savelasty; /* vertical position restored to */ + lastx = xleft; /* where it was before text, also */ + /* horizontal is at left */ +} /* end HGPutText */ + + +/*--------------------------------------------------------------------* + | Routine: doarc (center_point, start_point, angle) + | + | Results: Produces either drawarc command or a drawcircle command + | depending on the angle needed to draw through. + *--------------------------------------------------------------------*/ + +void +doarc(POINT cp, + POINT sp, + int angle) +{ + if (angle) /* arc with angle */ + HGArc((int) (cp.x * troffscale), (int) (cp.y * troffscale), + (int) (sp.x * troffscale), (int) (sp.y * troffscale), angle); + else /* a full circle (angle == 0) */ + HGArc((int) (cp.x * troffscale), (int) (cp.y * troffscale), + (int) (sp.x * troffscale), (int) (sp.y * troffscale), 0); +} + + +/*--------------------------------------------------------------------* + | Routine: HGSetFont (font_number, Point_size) + | + | Results: ALWAYS outputs a .ft and .ps directive to troff. This + | is done because someone may change stuff inside a text + | string. Changes thickness back to default thickness. + | Default thickness depends on font and point size. + *--------------------------------------------------------------------*/ + +void +HGSetFont(int font, + int size) +{ + printf(".ft %s\n" + ".ps %d\n", tfont[font - 1], tsize[size - 1]); + linethickness = DEFTHICK; +} + + +/*--------------------------------------------------------------------* + | Routine: HGSetBrush (line_mode) + | + | Results: Generates the troff commands to set up the line width + | and style of subsequent lines. Does nothing if no + | change is needed. + | + | Side Efct: Sets 'linmode' and 'linethickness'. + *--------------------------------------------------------------------*/ + +void +HGSetBrush(int mode) +{ + int printed = 0; + + if (linmod != style[--mode]) { + /* Groff doesn't understand \Ds, so we take it out */ + /* printf ("\\D's %du'", linmod = style[mode]); */ + linmod = style[mode]; + printed = 1; + } + if (linethickness != thick[mode]) { + linethickness = thick[mode]; + printf("\\h'-%.2fp'\\D't %.2fp'", linethickness, linethickness); + printed = 1; + } + if (printed) + cr(); +} + + +/*--------------------------------------------------------------------* + | Routine: deltax (x_destination) + | + | Results: Scales and outputs a number for delta x (with a leading + | space) given 'lastx' and x_destination. + | + | Side Efct: Resets 'lastx' to x_destination. + *--------------------------------------------------------------------*/ + +void +deltax(double x) +{ + int ix = (int) (x * troffscale); + + printf(" %du", ix - lastx); + lastx = ix; +} + + +/*--------------------------------------------------------------------* + | Routine: deltay (y_destination) + | + | Results: Scales and outputs a number for delta y (with a leading + | space) given 'lastyline' and y_destination. + | + | Side Efct: Resets 'lastyline' to y_destination. Since 'line' + | vertical motions don't affect 'page' ones, 'lasty' isn't + | updated. + *--------------------------------------------------------------------*/ + +void +deltay(double y) +{ + int iy = (int) (y * troffscale); + + printf(" %du", iy - lastyline); + lastyline = iy; +} + + +/*--------------------------------------------------------------------* + | Routine: tmove2 (px, py) + | + | Results: Produces horizontal and vertical moves for troff given + | the pair of points to move to and knowing the current + | position. Also puts out a horizontal move to start the + | line. This is a variation without the .sp command. + *--------------------------------------------------------------------*/ + +void +tmove2(int px, + int py) +{ + int dx; + int dy; + + if ((dy = py - lasty)) { + printf("\\v'%du'", dy); + } + lastyline = lasty = py; /* lasty is always set to current */ + if ((dx = px - lastx)) { + printf("\\h'%du'", dx); + lastx = px; + } +} + + +/*--------------------------------------------------------------------* + | Routine: tmove (point_pointer) + | + | Results: Produces horizontal and vertical moves for troff given + | the pointer of a point to move to and knowing the + | current position. Also puts out a horizontal move to + | start the line. + *--------------------------------------------------------------------*/ + +void +tmove(POINT * ptr) +{ + int ix = (int) (ptr->x * troffscale); + int iy = (int) (ptr->y * troffscale); + int dx; + int dy; + + if ((dy = iy - lasty)) { + printf(".sp %du\n", dy); + } + lastyline = lasty = iy; /* lasty is always set to current */ + if ((dx = ix - lastx)) { + printf("\\h'%du'", dx); + lastx = ix; + } +} + + +/*--------------------------------------------------------------------* + | Routine: cr ( ) + | + | Results: Ends off an input line. '.sp -1' is also added to + | counteract the vertical move done at the end of text + | lines. + | + | Side Efct: Sets 'lastx' to 'xleft' for troff's return to left + | margin. + *--------------------------------------------------------------------*/ + +void +cr() +{ + printf("\n.sp -1\n"); + lastx = xleft; +} + + +/*--------------------------------------------------------------------* + | Routine: line ( ) + | + | Results: Draws a single solid line to (x,y). + *--------------------------------------------------------------------*/ + +void +line(int px, + int py) +{ + printf("\\D'l"); + printf(" %du", px - lastx); + printf(" %du'", py - lastyline); + lastx = px; + lastyline = lasty = py; +} + + +/*--------------------------------------------------------------------* + | Routine: drawwig (ptr, type) + | + | Results: The point sequence found in the structure pointed by ptr + | is placed in integer arrays for further manipulation by + | the existing routing. With the corresponding type + | parameter, either picurve or HGCurve are called. + *--------------------------------------------------------------------*/ + +void +drawwig(POINT * ptr, + int type) +{ + int npts; /* point list index */ + int x[MAXPOINTS], y[MAXPOINTS]; /* point list */ + + for (npts = 1; !Nullpoint(ptr); ptr = PTNextPoint(ptr), npts++) { + x[npts] = (int) (ptr->x * troffscale); + y[npts] = (int) (ptr->y * troffscale); + } + if (--npts) { + if (type == CURVE) /* Use the 2 different types of curves */ + HGCurve(&x[0], &y[0], npts); + else + picurve(&x[0], &y[0], npts); + } +} + + +/*--------------------------------------------------------------------* + | Routine: HGArc (xcenter, ycenter, xstart, ystart, angle) + | + | Results: This routine plots an arc centered about (cx, cy) + | counter-clockwise starting from the point (px, py) + | through 'angle' degrees. If angle is 0, a full circle + | is drawn. It does so by creating a draw-path around the + | arc whose density of points depends on the size of the + | arc. + *--------------------------------------------------------------------*/ + +void +HGArc(int cx, + int cy, + int px, + int py, + int angle) +{ + double xs, ys, resolution, fullcircle; + int m; + int mask; + int extent; + int nx; + int ny; + int length; + double epsilon; + + xs = px - cx; + ys = py - cy; + + length = 0; + + resolution = (1.0 + groff_hypot(xs, ys) / res) * PointsPerInterval; + /* mask = (1 << (int) log10(resolution + 1.0)) - 1; */ + (void) frexp(resolution, &m); /* more elegant than log10 */ + for (mask = 1; mask < m; mask = mask << 1); + mask -= 1; + + epsilon = 1.0 / resolution; + fullcircle = (2.0 * pi) * resolution; + if (angle == 0) + extent = (int) fullcircle; + else + extent = (int) (angle * fullcircle / 360.0); + + HGtline(px, py); + while (--extent >= 0) { + xs += epsilon * ys; + nx = cx + (int) (xs + 0.5); + ys -= epsilon * xs; + ny = cy + (int) (ys + 0.5); + if (!(extent & mask)) { + HGtline(nx, ny); /* put out a point on circle */ + if (length++ > LINELENGTH) { + length = 0; + printf("\\\n"); + } + } + } /* end for */ +} /* end HGArc */ + + +/*--------------------------------------------------------------------* + | Routine: picurve (xpoints, ypoints, num_of_points) + | + | Results: Draws a curve delimited by (not through) the line + | segments traced by (xpoints, ypoints) point list. This + | is the 'Pic'-style curve. + *--------------------------------------------------------------------*/ + +void +picurve(int *x, + int *y, + int npts) +{ + int nseg; /* effective resolution for each curve */ + int xp; /* current point (and temporary) */ + int yp; + int pxp, pyp; /* previous point (to make lines from) */ + int i; /* inner curve segment traverser */ + int length = 0; + double w; /* position factor */ + double t1, t2, t3; /* calculation temps */ + + if (x[1] == x[npts] && y[1] == y[npts]) { + x[0] = x[npts - 1]; /* if the lines' ends meet, make */ + y[0] = y[npts - 1]; /* sure the curve meets */ + x[npts + 1] = x[2]; + y[npts + 1] = y[2]; + } else { /* otherwise, make the ends of the */ + x[0] = x[1]; /* curve touch the ending points of */ + y[0] = y[1]; /* the line segments */ + x[npts + 1] = x[npts]; + y[npts + 1] = y[npts]; + } + + pxp = (x[0] + x[1]) / 2; /* make the last point pointers */ + pyp = (y[0] + y[1]) / 2; /* point to the start of the 1st line */ + tmove2(pxp, pyp); + + for (; npts--; x++, y++) { /* traverse the line segments */ + xp = x[0] - x[1]; + yp = y[0] - y[1]; + nseg = (int) groff_hypot((double) xp, (double) yp); + xp = x[1] - x[2]; + yp = y[1] - y[2]; + /* 'nseg' is the number of line */ + /* segments that will be drawn for */ + /* each curve segment. */ + nseg = (int) ((double) (nseg + (int) groff_hypot((double) xp, + (double) yp)) / + res * PointsPerInterval); + + for (i = 1; i < nseg; i++) { + w = (double) i / (double) nseg; + t1 = w * w; + t3 = t1 + 1.0 - (w + w); + t2 = 2.0 - (t3 + t1); + xp = (((int) (t1 * x[2] + t2 * x[1] + t3 * x[0])) + 1) / 2; + yp = (((int) (t1 * y[2] + t2 * y[1] + t3 * y[0])) + 1) / 2; + + HGtline(xp, yp); + if (length++ > LINELENGTH) { + length = 0; + printf("\\\n"); + } + } + } +} + + +/*--------------------------------------------------------------------* + | Routine: HGCurve(xpoints, ypoints, num_points) + | + | Results: This routine generates a smooth curve through a set of + | points. The method used is the parametric spline curve + | on unit knot mesh described in 'Spline Curve Techniques' + | by Patrick Baudelaire, Robert Flegal, and Robert Sproull + | -- Xerox Parc. + *--------------------------------------------------------------------*/ + +void +HGCurve(int *x, + int *y, + int numpoints) +{ + double h[MAXPOINTS], dx[MAXPOINTS], dy[MAXPOINTS]; + double d2x[MAXPOINTS], d2y[MAXPOINTS], d3x[MAXPOINTS], d3y[MAXPOINTS]; + double t, t2, t3; + int j; + int k; + int nx; + int ny; + int lx, ly; + int length = 0; + + lx = x[1]; + ly = y[1]; + tmove2(lx, ly); + + /* + * Solve for derivatives of the curve at each point separately for x + * and y (parametric). + */ + Parameterize(x, y, h, numpoints); + + /* closed curve */ + if ((x[1] == x[numpoints]) && (y[1] == y[numpoints])) { + PeriodicSpline(h, x, dx, d2x, d3x, numpoints); + PeriodicSpline(h, y, dy, d2y, d3y, numpoints); + } else { + NaturalEndSpline(h, x, dx, d2x, d3x, numpoints); + NaturalEndSpline(h, y, dy, d2y, d3y, numpoints); + } + + /* + * Generate the curve using the above information and + * PointsPerInterval vectors between each specified knot. + */ + + for (j = 1; j < numpoints; ++j) { + if ((x[j] == x[j + 1]) && (y[j] == y[j + 1])) + continue; + for (k = 0; k <= PointsPerInterval; ++k) { + t = (double) k *h[j] / (double) PointsPerInterval; + t2 = t * t; + t3 = t * t * t; + nx = x[j] + (int) (t * dx[j] + t2 * d2x[j] / 2 + t3 * d3x[j] / 6); + ny = y[j] + (int) (t * dy[j] + t2 * d2y[j] / 2 + t3 * d3y[j] / 6); + HGtline(nx, ny); + if (length++ > LINELENGTH) { + length = 0; + printf("\\\n"); + } + } /* end for k */ + } /* end for j */ +} /* end HGCurve */ + + +/*--------------------------------------------------------------------* + | Routine: Parameterize (xpoints, ypoints, hparams, num_points) + | + | Results: This routine calculates parametric values for use in + | calculating curves. The parametric values are returned + | in the array h. The values are an approximation of + | cumulative arc lengths of the curve (uses cord length). + | For additional information, see paper cited below. + *--------------------------------------------------------------------*/ + +void +Parameterize(int x[], + int y[], + double h[], + int n) +{ + int dx; + int dy; + int i; + int j; + double u[MAXPOINTS]; + + for (i = 1; i <= n; ++i) { + u[i] = 0; + for (j = 1; j < i; j++) { + dx = x[j + 1] - x[j]; + dy = y[j + 1] - y[j]; + /* Here was overflowing, so I changed it. */ + /* u[i] += sqrt ((double) (dx * dx + dy * dy)); */ + u[i] += groff_hypot((double) dx, (double) dy); + } + } + for (i = 1; i < n; ++i) + h[i] = u[i + 1] - u[i]; +} /* end Parameterize */ + + +/*--------------------------------------------------------------------* + | Routine: PeriodicSpline (h, z, dz, d2z, d3z, npoints) + | + | Results: This routine solves for the cubic polynomial to fit a + | spline curve to the points specified by the list of + | values. The curve generated is periodic. The + | algorithms for this curve are from the 'Spline Curve + | Techniques' paper cited above. + *--------------------------------------------------------------------*/ + +void +PeriodicSpline(double h[], /* parameterization */ + int z[], /* point list */ + double dz[], /* to return the 1st derivative */ + double d2z[], /* 2nd derivative */ + double d3z[], /* 3rd derivative */ + int npoints) /* number of valid points */ +{ + double d[MAXPOINTS]; + double deltaz[MAXPOINTS], a[MAXPOINTS], b[MAXPOINTS]; + double c[MAXPOINTS], r[MAXPOINTS], s[MAXPOINTS]; + int i; + + /* step 1 */ + for (i = 1; i < npoints; ++i) { + deltaz[i] = h[i] ? ((double) (z[i + 1] - z[i])) / h[i] : 0; + } + h[0] = h[npoints - 1]; + deltaz[0] = deltaz[npoints - 1]; + + /* step 2 */ + for (i = 1; i < npoints - 1; ++i) { + d[i] = deltaz[i + 1] - deltaz[i]; + } + d[0] = deltaz[1] - deltaz[0]; + + /* step 3a */ + a[1] = 2 * (h[0] + h[1]); + b[1] = d[0]; + c[1] = h[0]; + for (i = 2; i < npoints - 1; ++i) { + a[i] = 2 * (h[i - 1] + h[i]) - + pow((double) h[i - 1], (double) 2.0) / a[i - 1]; + b[i] = d[i - 1] - h[i - 1] * b[i - 1] / a[i - 1]; + c[i] = -h[i - 1] * c[i - 1] / a[i - 1]; + } + + /* step 3b */ + r[npoints - 1] = 1; + s[npoints - 1] = 0; + for (i = npoints - 2; i > 0; --i) { + r[i] = -(h[i] * r[i + 1] + c[i]) / a[i]; + s[i] = (6 * b[i] - h[i] * s[i + 1]) / a[i]; + } + + /* step 4 */ + d2z[npoints - 1] = (6 * d[npoints - 2] - h[0] * s[1] + - h[npoints - 1] * s[npoints - 2]) + / (h[0] * r[1] + h[npoints - 1] * r[npoints - 2] + + 2 * (h[npoints - 2] + h[0])); + for (i = 1; i < npoints - 1; ++i) { + d2z[i] = r[i] * d2z[npoints - 1] + s[i]; + } + d2z[npoints] = d2z[1]; + + /* step 5 */ + for (i = 1; i < npoints; ++i) { + dz[i] = deltaz[i] - h[i] * (2 * d2z[i] + d2z[i + 1]) / 6; + d3z[i] = h[i] ? (d2z[i + 1] - d2z[i]) / h[i] : 0; + } +} /* end PeriodicSpline */ + + +/*-------------------------------------------------------------------- + | Routine: NaturalEndSpline (h, z, dz, d2z, d3z, npoints) + | + | Results: This routine solves for the cubic polynomial to fit a + | spline curve the points specified by the list of values. + | The algorithms for this curve are from the 'Spline Curve + | Techniques' paper cited above. + *--------------------------------------------------------------------*/ + +void +NaturalEndSpline(double h[], /* parameterization */ + int z[], /* Point list */ + double dz[], /* to return the 1st derivative */ + double d2z[], /* 2nd derivative */ + double d3z[], /* 3rd derivative */ + int npoints) /* number of valid points */ +{ + double d[MAXPOINTS]; + double deltaz[MAXPOINTS], a[MAXPOINTS], b[MAXPOINTS]; + int i; + + /* step 1 */ + for (i = 1; i < npoints; ++i) { + deltaz[i] = h[i] ? ((double) (z[i + 1] - z[i])) / h[i] : 0; + } + deltaz[0] = deltaz[npoints - 1]; + + /* step 2 */ + for (i = 1; i < npoints - 1; ++i) { + d[i] = deltaz[i + 1] - deltaz[i]; + } + d[0] = deltaz[1] - deltaz[0]; + + /* step 3 */ + a[0] = 2 * (h[2] + h[1]); + b[0] = d[1]; + for (i = 1; i < npoints - 2; ++i) { + a[i] = 2 * (h[i + 1] + h[i + 2]) - + pow((double) h[i + 1], (double) 2.0) / a[i - 1]; + b[i] = d[i + 1] - h[i + 1] * b[i - 1] / a[i - 1]; + } + + /* step 4 */ + d2z[npoints] = d2z[1] = 0; + for (i = npoints - 1; i > 1; --i) { + d2z[i] = (6 * b[i - 2] - h[i] * d2z[i + 1]) / a[i - 2]; + } + + /* step 5 */ + for (i = 1; i < npoints; ++i) { + dz[i] = deltaz[i] - h[i] * (2 * d2z[i] + d2z[i + 1]) / 6; + d3z[i] = h[i] ? (d2z[i + 1] - d2z[i]) / h[i] : 0; + } +} /* end NaturalEndSpline */ + + +/*--------------------------------------------------------------------* + | Routine: change (x_position, y_position, visible_flag) + | + | Results: As HGtline passes from the invisible to visible (or vice + | versa) portion of a line, change is called to either + | draw the line, or initialize the beginning of the next + | one. Change calls line to draw segments if visible_flag + | is set (which means we're leaving a visible area). + *--------------------------------------------------------------------*/ + +void +change(int x, + int y, + int vis) +{ + static int length = 0; + + if (vis) { /* leaving a visible area, draw it. */ + line(x, y); + if (length++ > LINELENGTH) { + length = 0; + printf("\\\n"); + } + } else { /* otherwise entering one; remember */ + /* beginning */ + tmove2(x, y); + } +} + + +/*--------------------------------------------------------------------* + | Routine: HGtline (xstart, ystart, xend, yend) + | + | Results: Draws a line from current position to (x1,y1) using + | line(x1, y1) to place individual segments of dotted or + | dashed lines. + *--------------------------------------------------------------------*/ + +void +HGtline(int x_1, + int y_1) +{ + int x_0 = lastx; + int y_0 = lasty; + int dx; + int dy; + int oldcoord; + int res1; + int visible; + int res2; + int xinc; + int yinc; + int dotcounter; + + if (linmod == SOLID) { + line(x_1, y_1); + return; + } + + /* for handling different resolutions */ + dotcounter = linmod << dotshifter; + + xinc = 1; + yinc = 1; + if ((dx = x_1 - x_0) < 0) { + xinc = -xinc; + dx = -dx; + } + if ((dy = y_1 - y_0) < 0) { + yinc = -yinc; + dy = -dy; + } + res1 = 0; + res2 = 0; + visible = 0; + if (dx >= dy) { + oldcoord = y_0; + while (x_0 != x_1) { + if ((x_0 & dotcounter) && !visible) { + change(x_0, y_0, 0); + visible = 1; + } else if (visible && !(x_0 & dotcounter)) { + change(x_0 - xinc, oldcoord, 1); + visible = 0; + } + if (res1 > res2) { + oldcoord = y_0; + res2 += dx - res1; + res1 = 0; + y_0 += yinc; + } + res1 += dy; + x_0 += xinc; + } + } else { + oldcoord = x_0; + while (y_0 != y_1) { + if ((y_0 & dotcounter) && !visible) { + change(x_0, y_0, 0); + visible = 1; + } else if (visible && !(y_0 & dotcounter)) { + change(oldcoord, y_0 - yinc, 1); + visible = 0; + } + if (res1 > res2) { + oldcoord = x_0; + res2 += dy - res1; + res1 = 0; + x_0 += xinc; + } + res1 += dx; + y_0 += yinc; + } + } + if (visible) + change(x_1, y_1, 1); + else + change(x_1, y_1, 0); +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/grn/hpoint.cpp b/src/preproc/grn/hpoint.cpp new file mode 100644 index 0000000..5ef0c0a --- /dev/null +++ b/src/preproc/grn/hpoint.cpp @@ -0,0 +1,59 @@ +/* Last non-groff version: hpoint.c 1.1 84/10/08 */ + +/* + * This file contains routines for manipulating the point data + * structures for the gremlin picture editor. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "gprint.h" + +/* imports from main.cpp */ +extern void *grnmalloc(size_t size, const char *what); + +/* + * Return pointer to empty point list. + */ +POINT * +PTInit() +{ + return ((POINT *) NULL); +} + + +/* + * This routine creates a new point with coordinates x and y and links + * it into the point list. + */ +POINT * +PTMakePoint(double x, + double y, + POINT **pplist) +{ + POINT *pt; + + if (Nullpoint(pt = *pplist)) { /* empty list */ + *pplist = (POINT *) grnmalloc(sizeof(POINT), "initial point"); + pt = *pplist; + } else { + while (!Nullpoint(pt->nextpt)) + pt = pt->nextpt; + pt->nextpt = (POINT *) grnmalloc(sizeof(POINT), "subsequent point"); + pt = pt->nextpt; + } + + pt->x = x; + pt->y = y; + pt->nextpt = PTInit(); + return (pt); +} /* end PTMakePoint */ + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/grn/main.cpp b/src/preproc/grn/main.cpp new file mode 100644 index 0000000..6d6d586 --- /dev/null +++ b/src/preproc/grn/main.cpp @@ -0,0 +1,977 @@ +/* Last non-groff version: main.c 1.23 (Berkeley) 85/08/05 + * + * Adapted to GNU troff by Daniel Senderowicz 99/12/29. + * + * Further refinements by Werner Lemberg 00/02/20. + * + * + * This file contains the main and file system dependent routines for + * processing gremlin files into troff input. The program watches input + * go by to standard output, only interpreting things between .GS and + * .GE lines. Default values (font, size, scale, thickness) may be + * overridden with a 'default' command and are further overridden by + * commands in the input. + * + * Inside the GS and GE, commands are accepted to reconfigure the + * picture. At most one command may reside on each line, and each + * command is followed by a parameter separated by white space. The + * commands are as follows, and may be abbreviated down to one character + * (with exception of 'scale' and 'stipple' down to "sc" and "st") and + * may be upper or lower case. + * + * default - Make all settings in the current + * .GS/.GE the global defaults. + * Height, width and file are NOT + * saved. + * 1, 2, 3, 4 - Set size 1, 2, 3, or 4 (followed + * by an integer point size). + * roman, italics, bold, special - Set gremlin's fonts to any other + * troff font (1 or 2 characters). + * stipple, l - Use a stipple font for polygons. + * Arg is troff font name. No + * default. Can use only one stipple + * font per picture. (See below for + * stipple font index.) + * scale, x - Scale is IN ADDITION to the global + * scale factor from the default. + * pointscale - Turn on scaling point sizes to + * match 'scale' commands. (Optional + * operand 'off' to turn it off.) + * narrow, medium, thick - Set widths of lines. + * file - Set the file name to read the + * gremlin picture from. If the file + * isn't in the current directory, + * the gremlin library is tried. + * width, height - These two commands override any + * scaling factor that is in effect, + * and forces the picture to fit into + * either the height or width + * specified, whichever makes the + * picture smaller. The operand for + * these two commands is a + * floating-point number in units of + * inches. + * l (integer ) - Set association between stipple + * and a stipple 'character'. + * must be in the range 0 to + * NSTIPPLES (16) inclusive. The + * integer operand is an index in the + * stipple font selected. Valid cf + * (cifplot) indices are 1-32 + * (although 24 is not defined), + * valid ug (unigrafix) indices are + * 1-14, and valid gs (gray scale) + * indices are 0-16. Nonetheless, + * any number between 0 and 255 is + * accepted since new stipple fonts + * may be added. An integer operand + * is required. + * + * Troff number registers used: g1 through g9. g1 is the width of the + * picture, and g2 is the height. g3, and g4, save information, g8 and + * g9 are used for text processing and g5-g7 are reserved. + */ + + +#include "lib.h" + +#include +#include +#include // errno +#include "gprint.h" + +#include "device.h" +#include "font.h" +#include "searchpath.h" +#include "macropath.h" + +#include "errarg.h" +#include "error.h" +#include "defs.h" + +extern "C" const char *Version_string; + +/* database imports */ + +extern void HGPrintElt(ELT *element, int baseline); +extern ELT *DBInit(); +extern ELT *DBRead(FILE *file); +extern POINT *PTInit(); +extern POINT *PTMakePoint(double x, double y, POINT **pplist); + +#define INIT_FILE_SIZE 50 /* Initial sz of file array from cmd line. */ +#define FILE_SIZE_INCR 50 /* Amount to increase array of files by. */ + +#define SUN_SCALEFACTOR 0.70 + +/* #define DEFSTIPPLE "gs" */ +#define DEFSTIPPLE "cf" +/* + * This grn implementation emits '.st' requests to control stipple + * effects, but groff does not (currently) support any such request. + * + * This hack disables the emission of such requests, without destroying + * the infrastructure necessary to support the feature in the future; to + * enable the emission of '.st' requests, at a future date when groff + * can support them, simply rewrite the following #define as: + * + * #define USE_ST_REQUEST stipple + * + * with accompanying comment: "emit '.st' requests as required". + */ +#define USE_ST_REQUEST 0 /* never emit '.st' requests */ + +#define MAXINLINE 100 /* input line length */ + +#define SCREENtoINCH 0.02 /* scaling factor, screen to inches */ + +#define BIG 999999999999.0 /* unwieldy large floating number */ + + +/* static char sccsid[] = "@(#) (Berkeley) 8/5/85, 12/28/99"; */ + +int res; /* the printer's resolution goes here */ + +int dotshifter; /* for the length of dotted curves */ + +double linethickness; /* brush styles */ +int linmod; +int lastx; /* point registers for printing */ +int lasty; /* elements */ +int lastyline; /* A line's vertical position is NOT */ + /* the same after that line is over, */ + /* so for a line of drawing commands, */ + /* vertical spacing is kept in */ + /* lastyline. */ + +/* These are the default fonts, sizes, line styles, */ +/* and thicknesses. They can be modified from a */ +/* 'default' command and are reset each time the */ +/* start of a picture (.GS) is found. */ + +const char *deffont[] = +{"R", "I", "B", "S"}; +int defsize[] = +{10, 16, 24, 36}; +/* #define BASE_THICKNESS 1.0 */ +#define BASE_THICKNESS 0.15 +double defthick[STYLES] = +{1 * BASE_THICKNESS, + 1 * BASE_THICKNESS, + 5 * BASE_THICKNESS, + 1 * BASE_THICKNESS, + 1 * BASE_THICKNESS, + 3 * BASE_THICKNESS}; + +/* int cf_stipple_index[NSTIPPLES + 1] = */ +/* {0, 1, 3, 12, 14, 16, 19, 21, 23}; */ +/* a logarithmic scale looks better than a linear one for gray shades */ +/* */ +/* int other_stipple_index[NSTIPPLES + 1] = */ +/* {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; */ + +int cf_stipple_index[NSTIPPLES + 1] = +{0, 18, 32, 56, 100, 178, 316, 562, 1000}; /* only 1-8 used */ +int other_stipple_index[NSTIPPLES + 1] = +{0, 62, 125, 187, 250, 312, 375, 437, 500, + 562, 625, 687, 750, 812, 875, 937, 1000}; + +/* int *defstipple_index = other_stipple_index; */ +int *defstipple_index = cf_stipple_index; + +int style[STYLES] = +{DOTTED, DOTDASHED, SOLID, DASHED, SOLID, SOLID}; +double scale = 1.0; /* no scaling, default */ +int defpoint = 0; /* flag for point size scaling */ +char *defstipple = (char *) 0; +enum E { + OUTLINE, FILL, BOTH +} polyfill; + +/* flag to control filling of polygons */ + +double adj1 = 0.0; +double adj2 = 0.0; +double adj3 = 0.0; +double adj4 = 0.0; + +double thick[STYLES]; /* thicknesses set by defaults, then */ + /* by commands */ +char *tfont[FONTS]; /* fonts originally set to deffont */ + /* values, then optionally changed by */ +int tsize[SIZES]; /* commands inside grn */ +int stipple_index[NSTIPPLES + 1]; /* stipple font file indices */ +char *stipple; + +double xscale; /* scaling factor from individual pictures */ +double troffscale; /* scaling factor at output time */ + +double width; /* user-request maximum width for picture */ + /* (in inches) */ +double height; /* user-request height */ +int pointscale; /* flag for point size scaling */ +int setdefault; /* flag for a .GS/.GE to remember all */ + /* settings */ +int sflag; /* -s flag: sort order (do polyfill first) */ + +double toppoint; /* remember the picture */ +double bottompoint; /* bounds in these variables */ +double leftpoint; +double rightpoint; + +int ytop; /* these are integer versions of the above */ +int ybottom; /* so not to convert each time they're used */ +int xleft; +int xright; + +static int linenum = 0; /* line number of troff input file */ +char inputline[MAXINLINE]; /* spot to filter through the file */ +char *c1 = inputline; /* c1, c2, and c3 will be used to */ +char *c2 = inputline + 1; /* hunt for lines that begin with */ +char *c3 = inputline + 2; /* '.GS' by looking individually */ +char *c4 = inputline + 3; /* needed for compatibility mode */ +char GScommand[MAXINLINE]; /* put user's '.GS' command line here */ +char gremlinfile[MAXINLINE]; /* filename to use for a picture */ +int SUNFILE = FALSE; /* TRUE if SUN gremlin file */ +int compatibility_flag = FALSE; /* TRUE if in compatibility mode */ + + +void getres(); +int doinput(FILE *fp); +void conv(FILE *fp, int baseline); +void savestate(); +int has_polygon(ELT *elist); +void interpret(char *line); + +void * +grnmalloc(size_t size, + const char *what) +{ + void *ptr = 0; + ptr = malloc(size); + if (!ptr) { + fatal("memory allocation failed for %1: %2", what, strerror(errno)); + } + return ptr; +} + +void +usage(FILE *stream) +{ + fprintf(stream, + "usage: %s [-Cs] [-M dir] [-F dir] [-T dev] [file ...]\n" + "usage: %s {-v | --version}\n" + "usage: %s --help\n", + program_name, program_name, program_name); +} + + +/* Add a new file entry in the array, expanding array if needs be. */ + +char ** +add_file(char **file, + char *new_file, + int *count, + int *cur_size) +{ + if (*count >= *cur_size) { + *cur_size += FILE_SIZE_INCR; + file = (char **) realloc(file, *cur_size * sizeof(char *)); + if (file == NULL) { + fatal("unable to extend file array"); + } + } + file[*count] = new_file; + *count += 1; + + return file; +} + + +/*--------------------------------------------------------------------* + | Routine: main (argument_count, argument_pointer) + | + | Results: Parses the command line, accumulating input file names, + | then reads the inputs, passing it directly to output + | until a '.GS' line is read. Main then passes control to + | 'conv' to do the gremlin file conversions. + *--------------------------------------------------------------------*/ + +int +main(int argc, + char **argv) +{ + setlocale(LC_NUMERIC, "C"); + program_name = argv[0]; + FILE *fp; + int k; + char c; + int gfil = 0; + char **file = NULL; + int file_cur_size = INIT_FILE_SIZE; + char *operand(int *argcp, char ***argvp); + + file = (char **) grnmalloc(file_cur_size * sizeof(char *), + "file array"); + while (--argc) { + if (**++argv != '-') + file = add_file(file, *argv, &gfil, &file_cur_size); + else + switch (c = (*argv)[1]) { + + case 0: + file = add_file(file, NULL, &gfil, &file_cur_size); + break; + + case 'C': /* compatibility mode */ + compatibility_flag = TRUE; + break; + + case 'F': /* font path to find DESC */ + font::command_line_font_dir(operand(&argc, &argv)); + break; + + case 'T': /* final output typesetter name */ + device = operand(&argc, &argv); + break; + + case 'M': /* set library directory */ + macro_path.command_line_dir(operand(&argc, &argv)); + break; + + case 's': /* preserve order of elements */ + sflag = 1; + break; + + case '-': + if (strcmp(*argv,"--version")==0) { + case 'v': + printf("GNU grn (groff) version %s\n", Version_string); + exit(0); + break; + } + if (strcmp(*argv,"--help")==0) { + case '?': + usage(stdout); + exit(0); + break; + } + // fallthrough + default: + error("unknown switch: %1", c); + usage(stderr); + exit(1); + } + } + + getres(); /* set the resolution for an output device */ + + if (gfil == 0) { /* no filename, use standard input */ + file[0] = NULL; + gfil++; + } + + for (k = 0; k < gfil; k++) { + if (file[k] != NULL) { + if ((fp = fopen(file[k], "r")) == NULL) + fatal("can't open %1", file[k]); + } else + fp = stdin; + + while (doinput(fp)) { + if (*c1 == '.' && *c2 == 'G' && *c3 == 'S') { + if (compatibility_flag || + *c4 == '\n' || *c4 == ' ' || *c4 == '\0') + conv(fp, linenum); + else + fputs(inputline, stdout); + } else + fputs(inputline, stdout); + } + } + + return 0; +} + + +/*--------------------------------------------------------------------* + | Routine: char * operand (& argc, & argv) + | + | Results: Returns address of the operand given with a command-line + | option. It uses either '-Xoperand' or '-X operand', + | whichever is present. The program is terminated if no + | option is present. + | + | Side Efct: argc and argv are updated as necessary. + *--------------------------------------------------------------------*/ + +char * +operand(int *argcp, + char ***argvp) +{ + if ((**argvp)[2]) + return (**argvp + 2); /* operand immediately follows */ + if ((--*argcp) <= 0) { /* no operand */ + error("command-line option operand missing."); + exit(8); + } + return (*(++(*argvp))); /* operand is next word */ +} + + +/*--------------------------------------------------------------------* + | Routine: getres () + | + | Results: Sets 'res' to the resolution of the output device. + *--------------------------------------------------------------------*/ + +void +getres() +{ + int linepiece; + + if (0 /* nullptr */ == font::load_desc()) + fatal("cannot load 'DESC' description file for device '%1'", + device); + + res = font::res; + + /* Correct the brush thicknesses based on res */ + /* if (res >= 256) { + defthick[0] = res >> 8; + defthick[1] = res >> 8; + defthick[2] = res >> 4; + defthick[3] = res >> 8; + defthick[4] = res >> 8; + defthick[5] = res >> 6; + } */ + + linepiece = res >> 9; + for (dotshifter = 0; linepiece; dotshifter++) + linepiece = linepiece >> 1; +} + + +/*--------------------------------------------------------------------* + | Routine: int doinput (file_pointer) + | + | Results: A line of input is read into 'inputline'. + | + | Side Efct: "linenum" is incremented. + | + | Bugs: Lines longer than MAXINLINE are NOT checked, except for + | updating 'linenum'. + *--------------------------------------------------------------------*/ + +int +doinput(FILE *fp) +{ + if (fgets(inputline, MAXINLINE, fp) == NULL) + return 0; + if (strchr(inputline, '\n')) /* ++ only if it's a complete line */ + linenum++; + return 1; +} + + +/*--------------------------------------------------------------------* + | Routine: initpic ( ) + | + | Results: Sets all parameters to the normal defaults, possibly + | overridden by a setdefault command. Initialize the + | picture variables, and output the startup commands to + | troff to begin the picture. + *--------------------------------------------------------------------*/ + +void +initpic() +{ + int i; + + for (i = 0; i < STYLES; i++) { /* line thickness defaults */ + thick[i] = defthick[i]; + } + for (i = 0; i < FONTS; i++) { /* font name defaults */ + tfont[i] = (char *)deffont[i]; + } + for (i = 0; i < SIZES; i++) { /* font size defaults */ + tsize[i] = defsize[i]; + } + for (i = 0; i <= NSTIPPLES; i++) { /* stipple font file default */ + /* indices */ + stipple_index[i] = defstipple_index[i]; + } + stipple = defstipple; + + gremlinfile[0] = 0; /* filename is 'null' */ + setdefault = 0; /* not the default settings (yet) */ + + toppoint = BIG; /* set the picture bounds out */ + bottompoint = -BIG; /* of range so they'll be set */ + leftpoint = BIG; /* by 'savebounds' on input */ + rightpoint = -BIG; + + pointscale = defpoint;/* flag for scaling point sizes default */ + xscale = scale; /* default scale of individual pictures */ + width = 0.0; /* size specifications input by user */ + height = 0.0; + + linethickness = DEFTHICK; /* brush styles */ + linmod = DEFSTYLE; +} + + +/*--------------------------------------------------------------------* + | Routine: conv (file_pointer, starting_line) + | + | Results: At this point, we just passed a '.GS' line in the input + | file. conv reads the input and calls 'interpret' to + | process commands, gathering up information until a '.GE' + | line is found. It then calls 'HGPrint' to do the + | translation of the gremlin file to troff commands. + *--------------------------------------------------------------------*/ + +void +conv(FILE *fp, + int baseline) +{ + FILE *gfp = NULL; /* input file pointer */ + int done = 0; /* flag to remember if finished */ + ELT *e; /* current element pointer */ + ELT *PICTURE; /* whole picture data base pointer */ + double temp; /* temporary calculating area */ + /* POINT ptr; */ /* coordinates of a point to pass to 'mov' */ + /* routine */ + int flyback; /* flag 'want to end up at the top of the */ + /* picture?' */ + int compat; /* test character after .GE or .GF */ + + + initpic(); /* set defaults, ranges, etc. */ + strcpy(GScommand, inputline); /* save '.GS' line for later */ + + do { + done = !doinput(fp); /* test for EOF */ + flyback = (*c3 == 'F'); /* and .GE or .GF */ + compat = (compatibility_flag || + *c4 == '\n' || *c4 == ' ' || *c4 == '\0'); + done |= (*c1 == '.' && *c2 == 'G' && (*c3 == 'E' || flyback) && + compat); + + if (done) { + if (setdefault) + savestate(); + + if (!gremlinfile[0]) { + if (!setdefault) + error("no picture file name at line %1", baseline); + return; + } + char *path; + gfp = macro_path.open_file(gremlinfile, &path); + if (0 /* nullptr */ == gfp) { + error("cannot open picture file '%1'", gremlinfile); + return; + } + PICTURE = DBRead(gfp); /* read picture file */ + fclose(gfp); + free(path); + if (DBNullelt(PICTURE)) + return; /* If a request is made to make the */ + /* picture fit into a specific area, */ + /* set the scale to do that. */ + + if (stipple == (char *) NULL) /* if user forgot stipple */ + if (has_polygon(PICTURE)) /* and picture has a polygon */ + stipple = (char *)DEFSTIPPLE; /* then set the default */ + + if ((temp = bottompoint - toppoint) < 0.1) + temp = 0.1; + temp = (height != 0.0) ? height / (temp * SCREENtoINCH) : BIG; + if ((troffscale = rightpoint - leftpoint) < 0.1) + troffscale = 0.1; + troffscale = (width != 0.0) ? + width / (troffscale * SCREENtoINCH) : BIG; + if (temp == BIG && troffscale == BIG) + troffscale = xscale; + else { + if (temp < troffscale) + troffscale = temp; + } /* here, troffscale is the */ + /* picture's scaling factor */ + if (pointscale) { + int i; /* do point scaling here, when */ + /* scale is known, before output */ + for (i = 0; i < SIZES; i++) + tsize[i] = (int) (troffscale * (double) tsize[i] + 0.5); + } + + /* change to device units */ + troffscale *= SCREENtoINCH * res; /* from screen units */ + + /* Calculate integer versions of the picture limits. */ + ytop = (int) (toppoint * troffscale); + ybottom = (int) (bottompoint * troffscale); + xleft = (int) (leftpoint * troffscale); + xright = (int) (rightpoint * troffscale); + + /* save stuff in number registers, */ + /* register g1 = picture width and */ + /* register g2 = picture height, */ + /* set vertical spacing, no fill, */ + /* and break (to make sure picture */ + /* starts on left), and put out the */ + /* user's '.GS' line. */ + printf(".br\n" + ".nr g1 %du\n" + ".nr g2 %du\n" + "%s" + ".nr g3 \\n(.f\n" + ".nr g4 \\n(.s\n" + "\\0\n" + ".sp -1\n", + xright - xleft, ybottom - ytop, GScommand); + + if (USE_ST_REQUEST) /* stipple requested for this picture */ + printf(".st %s\n", stipple); + lastx = xleft; /* note where we are (upper left */ + lastyline = lasty = ytop; /* corner of the picture) */ + + /* Just dump everything in the order it appears. + * + * If -s command-line option, traverse picture twice: First time, + * print only the interiors of filled polygons (as borderless + * polygons). Second time, print the outline as series of line + * segments. This way, postprocessors that overwrite rather than + * merge picture elements (such as Postscript) can still have text + * and graphics on a shaded background. + */ + /* if (sflag) */ + if (!sflag) { /* changing the default for filled polygons */ + e = PICTURE; + polyfill = FILL; + while (!DBNullelt(e)) { + printf(".mk\n"); + if (e->type == POLYGON) + HGPrintElt(e, baseline); + printf(".rt\n"); + lastx = xleft; + lastyline = lasty = ytop; + e = DBNextElt(e); + } + } + e = PICTURE; + + /* polyfill = !sflag ? BOTH : OUTLINE; */ + polyfill = sflag ? BOTH : OUTLINE; /* changing default */ + while (!DBNullelt(e)) { + printf(".mk\n"); + HGPrintElt(e, baseline); + printf(".rt\n"); + lastx = xleft; + lastyline = lasty = ytop; + e = DBNextElt(e); + } + + /* decide where to end picture */ + + /* I [Senderowicz?] changed everything here. I always use the */ + /* combination .mk and .rt, so once finished I just space down */ + /* height of the picture that is \n(g2u. */ + if (flyback) { /* end picture at upper left */ + /* ptr.x = leftpoint; + ptr.y = toppoint; */ + } else { /* end picture at lower left */ + /* ptr.x = leftpoint; + ptr.y = bottompoint; */ + printf(".sp \\n(g2u\n"); + } + + /* tmove(&ptr); */ /* restore default line parameters */ + + /* Restore everything to the way it was before the .GS, then */ + /* put out the '.GE' line from user */ + + /* printf("\\D't %du'\\D's %du'\n", DEFTHICK, DEFSTYLE); */ + /* groff doesn't understand the \Ds command */ + + printf("\\D't %du'\n", DEFTHICK); + if (flyback) /* make sure we end up at top of */ + printf(".sp -1\n"); /* picture if 'flying back' */ + if (USE_ST_REQUEST) /* restore stipple to previous */ + printf(".st\n"); + printf(".br\n" + ".ft \\n(g3\n" + ".ps \\n(g4\n" + "%s", inputline); + } else + interpret(inputline); /* take commands from the input file */ + } while (!done); +} + + +/*--------------------------------------------------------------------* + | Routine: savestate ( ) + | + | Results: All the current scaling/font size/font name/thickness/ + | pointscale settings are made the defaults. Scaled + | point sizes are NOT saved. The scaling is done each + | time a new picture is started. + | + | Side Efct: scale, and def* are modified. + *--------------------------------------------------------------------*/ + +void +savestate() +{ + int i; + + for (i = 0; i < STYLES; i++) /* line thickness defaults */ + defthick[i] = thick[i]; + for (i = 0; i < FONTS; i++) /* font name defaults */ + deffont[i] = tfont[i]; + for (i = 0; i < SIZES; i++) /* font size defaults */ + defsize[i] = tsize[i]; + /* stipple font file default indices */ + for (i = 0; i <= NSTIPPLES; i++) + defstipple_index[i] = stipple_index[i]; + + defstipple = stipple; /* if stipple has been set, it's remembered */ + scale *= xscale; /* default scale of individual pictures */ + defpoint = pointscale;/* flag to scale point sizes from x factors */ +} + + +/*--------------------------------------------------------------------* + | Routine: savebounds (x_coordinate, y_coordinate) + | + | Results: Keeps track of the maximum and minimum extent of a + | picture in the global variables: left-, right-, top- and + | bottompoint. 'savebounds' assumes that the points have + | been oriented to the correct direction. No scaling has + | taken place, though. + *--------------------------------------------------------------------*/ + +void +savebounds(double x, + double y) +{ + if (x < leftpoint) + leftpoint = x; + if (x > rightpoint) + rightpoint = x; + if (y < toppoint) + toppoint = y; + if (y > bottompoint) + bottompoint = y; +} + + +/*--------------------------------------------------------------------* + | Routine: interpret (character_string) + | + | Results: Commands are taken from the input string and performed. + | Commands are separated by newlines, and are of the + | format: + | string1 string2 + | where string1 is the command, string2 the argument. + | + | Side Efct: Font and size strings, plus the gremlin file name and + | the width and height variables are set by this routine. + *--------------------------------------------------------------------*/ + +void +interpret(char *line) +{ + char str1[MAXINLINE]; + char str2[MAXINLINE]; + char *chr; + int i; + double par; + + str2[0] = '\0'; + sscanf(line, "%80s%80s", &str1[0], &str2[0]); + for (chr = &str1[0]; *chr; chr++) /* convert command to */ + if (isupper(*chr)) + *chr = tolower(*chr); /* lower case */ + + switch (str1[0]) { + + case '1': + case '2': /* font sizes */ + case '3': + case '4': + i = atoi(str2); + if (i > 0 && i < 1000) + tsize[str1[0] - '1'] = i; + else + error("bad font size value at line %1", linenum); + break; + + case 'r': /* roman */ + if (str2[0] < '0') + goto nofont; + tfont[0] = (char *) grnmalloc(strlen(str2) + 1, "roman command"); + strcpy(tfont[0], str2); + break; + + case 'i': /* italics */ + if (str2[0] < '0') + goto nofont; + tfont[1] = (char *) grnmalloc(strlen(str2) + 1, "italics command"); + strcpy(tfont[1], str2); + break; + + case 'b': /* bold */ + if (str2[0] < '0') + goto nofont; + tfont[2] = (char *) grnmalloc(strlen(str2) + 1, "bold command"); + strcpy(tfont[2], str2); + break; + + case 's': /* special */ + if (str1[1] == 'c') + goto scalecommand; /* or scale */ + + if (str2[0] < '0') { + nofont: + error("no font name specified in line %1", linenum); + break; + } + if (str1[1] == 't') + goto stipplecommand; /* or stipple */ + + tfont[3] = (char *) grnmalloc(strlen(str2) + 1, "special command"); + strcpy(tfont[3], str2); + break; + + case 'l': /* l */ + if (isdigit(str1[1])) { /* set stipple index */ + int idx = atoi(str1 + 1), val; + + if (idx < 0 || idx > NSTIPPLES) { + error("bad stipple number %1 at line %2", idx, linenum); + break; + } + if (!defstipple_index) + defstipple_index = other_stipple_index; + val = atoi(str2); + if (val >= 0 && val < 256) + stipple_index[idx] = val; + else + error("bad stipple index value at line %1", linenum); + break; + } + + stipplecommand: /* set stipple name */ + stipple = (char *) grnmalloc(strlen(str2) + 1, "stipple command"); + strcpy(stipple, str2); + /* if it's a 'known' font (currently only 'cf'), set indices */ + if (strcmp(stipple, "cf") == 0) + defstipple_index = cf_stipple_index; + else + defstipple_index = other_stipple_index; + for (i = 0; i <= NSTIPPLES; i++) + stipple_index[i] = defstipple_index[i]; + break; + + case 'a': /* text adjust */ + par = atof(str2); + switch (str1[1]) { + case '1': + adj1 = par; + break; + case '2': + adj2 = par; + break; + case '3': + adj3 = par; + break; + case '4': + adj4 = par; + break; + default: + error("bad adjust command at line %1", linenum); + break; + } + break; + + case 't': /* thick */ + thick[2] = defthick[0] * atof(str2); + break; + + case 'm': /* medium */ + thick[5] = defthick[0] * atof(str2); + break; + + case 'n': /* narrow */ + thick[0] = thick[1] = thick[3] = thick[4] = + defthick[0] * atof(str2); + break; + + case 'x': /* x */ + scalecommand: /* scale */ + par = atof(str2); + if (par > 0.0) + xscale *= par; + else + error("invalid scale value on line %1", linenum); + break; + + case 'f': /* file */ + strcpy(gremlinfile, str2); + break; + + case 'w': /* width */ + width = atof(str2); + if (width < 0.0) + width = -width; + break; + + case 'h': /* height */ + height = atof(str2); + if (height < 0.0) + height = -height; + break; + + case 'd': /* defaults */ + setdefault = 1; + break; + + case 'p': /* pointscale */ + if (strcmp("off", str2)) + pointscale = 1; + else + pointscale = 0; + break; + + default: + error("unknown command '%1' on line %2", str1, linenum); + exit(8); + break; + }; +} + + +/* + * return TRUE if picture contains a polygon + * otherwise FALSE + */ + +int +has_polygon(ELT *elist) +{ + while (!DBNullelt(elist)) { + if (elist->type == POLYGON) + return (1); + elist = DBNextElt(elist); + } + + return (0); +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/html/html.am b/src/preproc/html/html.am new file mode 100644 index 0000000..ac5ca9d --- /dev/null +++ b/src/preproc/html/html.am @@ -0,0 +1,32 @@ +# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# +# This file 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 . + +bin_PROGRAMS += pre-grohtml +pre_grohtml_LDADD = libgroff.a lib/libgnu.a $(LIBM) +pre_grohtml_SOURCES = \ + src/preproc/html/pre-html.cpp \ + src/preproc/html/pushback.cpp \ + src/preproc/html/pre-html.h \ + src/preproc/html/pushback.h +src/preproc/html/pre-html.$(OBJEXT): defs.h + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/preproc/html/pre-html.cpp b/src/preproc/html/pre-html.cpp new file mode 100644 index 0000000..fecfb05 --- /dev/null +++ b/src/preproc/html/pre-html.cpp @@ -0,0 +1,1819 @@ +/* Copyright (C) 2000-2021 Free Software Foundation, Inc. + * Written by Gaius Mulley (gaius@glam.ac.uk). + * + * This file 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 groff; see the file COPYING. If not, write to the Free + * Software Foundation, 51 Franklin St - Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#define PREHTMLC + +#include "lib.h" + +#include +#include +#include +#include +#include + +#include "errarg.h" +#include "error.h" +#include "stringclass.h" +#include "posix.h" +#include "defs.h" +#include "searchpath.h" +#include "paper.h" +#include "device.h" +#include "font.h" + +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifdef _POSIX_VERSION +# include +# define PID_T pid_t +#else /* not _POSIX_VERSION */ +# define PID_T int +#endif /* not _POSIX_VERSION */ + +#include + +#include "nonposix.h" + +#if 0 +# define DEBUGGING +#endif + +/* Establish some definitions to facilitate discrimination between + differing runtime environments. */ + +#undef MAY_FORK_CHILD_PROCESS +#undef MAY_SPAWN_ASYNCHRONOUS_CHILD + +#if defined(__MSDOS__) || defined(_WIN32) + +// Most MS-DOS and Win32 environments will be missing the 'fork' +// capability (some, like Cygwin, have it, but it is better avoided). + +# define MAY_FORK_CHILD_PROCESS 0 + +// On these systems, we use 'spawn...', instead of 'fork' ... 'exec...'. +# include // for 'spawn...' +# include // for attributes of pipes + +# if defined(__CYGWIN__) || defined(_UWIN) || defined(_WIN32) + +// These Win32 implementations allow parent and 'spawn...'ed child to +// multitask asynchronously. + +# define MAY_SPAWN_ASYNCHRONOUS_CHILD 1 + +# else + +// Others may adopt MS-DOS behaviour where parent must sleep, +// from 'spawn...' until child terminates. + +# define MAY_SPAWN_ASYNCHRONOUS_CHILD 0 + +# endif /* not defined __CYGWIN__, _UWIN, or _WIN32 */ + +# if defined(DEBUGGING) && !defined(DEBUG_FILE_DIR) +/* When we are building a DEBUGGING version we need to tell pre-grohtml + where to put intermediate files (the DEBUGGING version will preserve + these on exit). + + On a Unix host, we might simply use '/tmp', but MS-DOS and Win32 will + probably not have this on all disk drives, so default to using + 'c:/temp' instead. (Note that user may choose to override this by + supplying a definition such as + + -DDEBUG_FILE_DIR=d:/path/to/debug/files + + in the CPPFLAGS to 'make'.) */ + +# define DEBUG_FILE_DIR c:/temp +# endif + +#else /* not __MSDOS__ or _WIN32 */ + +// For non-Microsoft environments assume Unix conventions, +// so 'fork' is required and child processes are asynchronous. +# define MAY_FORK_CHILD_PROCESS 1 +# define MAY_SPAWN_ASYNCHRONOUS_CHILD 1 + +# if defined(DEBUGGING) && !defined(DEBUG_FILE_DIR) +/* For a DEBUGGING version, on the Unix host, we can also usually rely + on being able to use '/tmp' for temporary file storage. (Note that, + as in the __MSDOS__ or _WIN32 case above, the user may override this + by defining + + -DDEBUG_FILE_DIR=/path/to/debug/files + + in the CPPFLAGS.) */ + +# define DEBUG_FILE_DIR /tmp +# endif + +#endif /* not __MSDOS__ or _WIN32 */ + +#ifdef DEBUGGING +// For a DEBUGGING version, we need some additional macros, +// to direct the captured debugging mode output to appropriately named +// files in the specified DEBUG_FILE_DIR. + +# define DEBUG_TEXT(text) #text +# define DEBUG_NAME(text) DEBUG_TEXT(text) +# define DEBUG_FILE(name) DEBUG_NAME(DEBUG_FILE_DIR) "/" name +#endif + +extern "C" const char *Version_string; + +#include "pre-html.h" +#include "pushback.h" +#include "html-strings.h" + +#define DEFAULT_LINE_LENGTH 7 // inches wide +#define DEFAULT_IMAGE_RES 100 // number of pixels per inch resolution +#define IMAGE_BORDER_PIXELS 0 +#define INLINE_LEADER_CHAR '\\' + +// Don't use colour names here! Otherwise there is a dependency on +// a file called 'rgb.txt' which maps names to colours. +#define TRANSPARENT "-background rgb:f/f/f -transparent rgb:f/f/f" +#define MIN_ALPHA_BITS 0 +#define MAX_ALPHA_BITS 4 + +#define PAGE_TEMPLATE_SHORT "pg" +#define PAGE_TEMPLATE_LONG "-page-" +#define PS_TEMPLATE_SHORT "ps" +#define PS_TEMPLATE_LONG "-ps-" +#define REGION_TEMPLATE_SHORT "rg" +#define REGION_TEMPLATE_LONG "-regions-" + +typedef enum { + CENTERED, LEFT, RIGHT, INLINE +} IMAGE_ALIGNMENT; + +typedef enum {xhtml, html4} html_dialect; + +static int postscriptRes = -1; // PostScript resolution, + // dots per inch +static int stdoutfd = 1; // output file descriptor - + // normally 1 but might move + // -1 means closed +static char *psFileName = 0 /* nullptr */; // PostScript file name +static char *psPageName = 0 /* nullptr */; // name of file + // containing current + // PostScript page +static char *regionFileName = 0 /* nullptr */; // name of file + // containing all image + // regions +static char *imagePageName = 0 /* nullptr */; // name of bitmap image + // file containing + // current page +static const char *image_device = "pnmraw"; +static int image_res = DEFAULT_IMAGE_RES; +static int vertical_offset = 0; +static char *image_template = 0 /* nullptr */; // image file name + // template +static char *macroset_template= 0 /* nullptr */; // image file + // name template + // passed to + // troff by -D +static int troff_arg = 0; // troff arg index +static char *image_dir = 0 /* nullptr */; // user-specified image + // directory +static int textAlphaBits = MAX_ALPHA_BITS; +static int graphicAlphaBits = MAX_ALPHA_BITS; +static char *antiAlias = 0 /* nullptr */; // anti-alias arguments + // to be passed to gs +static bool want_progress_report = false; // display page numbers + // as they are processed +static int currentPageNo = -1; // current image page number +#if defined(DEBUGGING) +static bool debugging = false; +static char *troffFileName = 0 /* nullptr */; // pre-html output sent + // to troff -Tps +static char *htmlFileName = 0 /* nullptr */; // pre-html output sent + // to troff -Thtml +#endif +static bool need_eqn = false; // must we preprocess via eqn? + +static char *linebuf = 0 /* nullptr */; // for scanning devps/DESC +static int linebufsize = 0; +static const char *image_gen = 0 /* nullptr */; // the 'gs' program + +static const char devhtml_desc[] = "devhtml/DESC"; +static const char devps_desc[] = "devps/DESC"; + +const char *const FONT_ENV_VAR = "GROFF_FONT_PATH"; +static search_path font_path(FONT_ENV_VAR, FONTPATH, 0, 0); +static html_dialect dialect = html4; + + +/* + * Images are generated via PostScript, gs, and the pnm utilities. + */ +#define IMAGE_DEVICE "-Tps" + + +/* + * sys_fatal - Write a fatal error message. + * Taken from src/roff/groff/pipeline.c. + */ + +void sys_fatal(const char *s) +{ + fatal("%1: %2", s, strerror(errno)); +} + +/* + * get_line - Copy a line (w/o newline) from a file to the + * global line buffer. + */ + +int get_line(FILE *f) +{ + if (f == 0) + return 0; + if (linebuf == 0) { + linebuf = new char[128]; + linebufsize = 128; + } + int i = 0; + // skip leading whitespace + for (;;) { + int c = getc(f); + if (c == EOF) + return 0; + if (c != ' ' && c != '\t') { + ungetc(c, f); + break; + } + } + for (;;) { + int c = getc(f); + if (c == EOF) + break; + if (i + 1 >= linebufsize) { + char *old_linebuf = linebuf; + linebuf = new char[linebufsize * 2]; + memcpy(linebuf, old_linebuf, linebufsize); + delete[] old_linebuf; + linebufsize *= 2; + } + linebuf[i++] = c; + if (c == '\n') { + i--; + break; + } + } + linebuf[i] = '\0'; + return 1; +} + +/* + * get_resolution - Return the PostScript device resolution. + */ + +static unsigned int get_resolution(void) +{ + char *pathp; + FILE *f; + unsigned int res = 0; + f = font_path.open_file(devps_desc, &pathp); + if (0 == f) + fatal("cannot open file '%1'", devps_desc); + free(pathp); + // XXX: We should break out of this loop if we hit a "charset" line. + // "This line and everything following it in the file are ignored." + // (groff_font(5)) + while (get_line(f)) + (void) sscanf(linebuf, "res %u", &res); + fclose(f); + return res; +} + + +/* + * get_image_generator - Return the declared program from the HTML + * device description. + */ + +static char *get_image_generator(void) +{ + char *pathp; + FILE *f; + char *generator = 0; + const char keyword[] = "image_generator"; + const size_t keyword_len = strlen(keyword); + f = font_path.open_file(devhtml_desc, &pathp); + if (0 == f) + fatal("cannot open file '%1'", devhtml_desc); + free(pathp); + // XXX: We should break out of this loop if we hit a "charset" line. + // "This line and everything following it in the file are ignored." + // (groff_font(5)) + while (get_line(f)) { + char *cursor = linebuf; + size_t limit = strlen(linebuf); + char *end = linebuf + limit; + if (0 == (strncmp(linebuf, keyword, keyword_len))) { + cursor += keyword_len; + // At least one space or tab is required. + if(!(' ' == *cursor) || ('\t' == *cursor)) + continue; + cursor++; + while((cursor < end) && ((' ' == *cursor) || ('\t' == *cursor))) + cursor++; + if (cursor == end) + continue; + generator = cursor; + } + } + fclose(f); + return generator; +} + +/* + * html_system - A wrapper for system(). + */ + +void html_system(const char *s, int redirect_stdout) +{ +#if defined(DEBUGGING) + if (debugging) { + fprintf(stderr, "executing: "); + fwrite(s, sizeof(char), strlen(s), stderr); + fflush(stderr); + } +#endif + { + int saved_stdout = dup(1); + int fdnull = open(NULL_DEV, O_WRONLY|O_BINARY, 0666); + if (redirect_stdout && saved_stdout > 1 && fdnull > 1) + dup2(fdnull, 1); + if (fdnull >= 0) + close(fdnull); + int status = system(s); + if (redirect_stdout) + dup2(saved_stdout, 1); + if (status == -1) + fprintf(stderr, "Calling '%s' failed\n", s); + else if (status) + fprintf(stderr, "Calling '%s' returned status %d\n", s, status); + close(saved_stdout); + } +} + +/* + * make_string - Create a string via `malloc()`, place the variadic + * arguments as formatted by `fmt` into it, and return + * it. Adapted from Linux man-pages' printf(3) example. + * We never return a null pointer, instead treating + * failure as invariably fatal. + */ + +char *make_string(const char *fmt, ...) +{ + size_t size = 0; + char *p = 0 /* nullptr */; + va_list ap; + va_start(ap, fmt); + int n = vsnprintf(p, size, fmt, ap); + va_end(ap); + if (n < 0) + sys_fatal("vsnprintf"); + size = static_cast(n) + 1 /* '\0' */; + p = static_cast(malloc(size)); + if (0 /* nullptr */ == p) + sys_fatal("vsnprintf"); + va_start(ap, fmt); + n = vsnprintf(p, size, fmt, ap); + va_end(ap); + if (n < 0) + sys_fatal("vsnprintf"); + assert(p != 0 /* nullptr */); + return p; +} + +/* + * classes and methods for retaining ascii text + */ + +struct char_block { + enum { SIZE = 256 }; + char buffer[SIZE]; + int used; + char_block *next; + + char_block(); +}; + +char_block::char_block() +: used(0), next(0) +{ + for (int i = 0; i < SIZE; i++) + buffer[i] = 0; +} + +class char_buffer { +public: + char_buffer(); + ~char_buffer(); + void read_file(FILE *fp); + int do_html(int argc, char *argv[]); + int do_image(int argc, char *argv[]); + void emit_troff_output(int device_format_selector); + void write_upto_newline(char_block **t, int *i, int is_html); + bool can_see(char_block **t, int *i, const char *string); + void skip_until_newline(char_block **t, int *i); +private: + char_block *head; + char_block *tail; + int run_output_filter(int device_format_selector, int argc, + char *argv[]); +}; + +char_buffer::char_buffer() +: head(0), tail(0) +{ +} + +char_buffer::~char_buffer() +{ + while (head != 0 /* nullptr */) { + char_block *temp = head; + head = head->next; + delete temp; + } +} + +/* + * read_file - Read file `fp` into char_blocks. + */ + +void char_buffer::read_file(FILE *fp) +{ + int n; + while (!feof(fp)) { + if (0 /* nullptr */ == tail) { + tail = new char_block; + head = tail; + } + else { + if (tail->used == char_block::SIZE) { + tail->next = new char_block; + tail = tail->next; + } + } + // We now have a tail ready for the next `SIZE` bytes of the file. + n = fread(tail->buffer, sizeof(char), char_block::SIZE-tail->used, + fp); + if ((n < 0) || ((0 == n) && !feof(fp))) + sys_fatal("fread"); + tail->used += n * sizeof(char); + } +} + +/* + * writeNbytes - Write n bytes to stdout. + */ + +static void writeNbytes(const char *s, int l) +{ + int n = 0; + int r; + + while (n < l) { + r = write(stdoutfd, s, l - n); + if (r < 0) + sys_fatal("write"); + n += r; + s += r; + } +} + +/* + * writeString - Write a string to stdout. + */ + +static void writeString(const char *s) +{ + writeNbytes(s, strlen(s)); +} + +/* + * makeFileName - Create the image filename template + * and the macroset image template. + */ + +static void makeFileName(void) +{ + if ((image_dir != 0 /* nullptr */) + && (strchr(image_dir, '%') != 0 /* nullptr */)) + fatal("'%%' is prohibited within the image directory name"); + if ((image_template != 0 /* nullptr */) + && (strchr(image_template, '%') != 0 /* nullptr */)) + fatal("'%%' is prohibited within the image template"); + if (0 /* nullptr */ == image_dir) + image_dir = (char *)""; + else if (strlen(image_dir) > 0 + && image_dir[strlen(image_dir) - 1] != '/') + image_dir = make_string("%s/", image_dir); + if (0 /* nullptr */ == image_template) + macroset_template = make_string("%sgrohtml-%d-", image_dir, + int(getpid())); + else + macroset_template = make_string("%s%s-", image_dir, + image_template); + size_t mtlen = strlen(macroset_template); + image_template = (char *)malloc(strlen("%d") + mtlen + 1); + if (0 /* nullptr */ == image_template) + sys_fatal("malloc"); + char *s = strcpy(image_template, macroset_template); + s += mtlen; + // Keep this format string synced with troff:suppress_node::tprint(). + strcpy(s, "%d"); +} + +/* + * setupAntiAlias - Set up the antialias string, used when we call gs. + */ + +static void setupAntiAlias(void) +{ + if (textAlphaBits == 0 && graphicAlphaBits == 0) + antiAlias = make_string(" "); + else if (textAlphaBits == 0) + antiAlias = make_string("-dGraphicsAlphaBits=%d ", + graphicAlphaBits); + else if (graphicAlphaBits == 0) + antiAlias = make_string("-dTextAlphaBits=%d ", textAlphaBits); + else + antiAlias = make_string("-dTextAlphaBits=%d" + " -dGraphicsAlphaBits=%d ", textAlphaBits, + graphicAlphaBits); +} + +/* + * checkImageDir - Check whether the image directory is available. + */ + +static void checkImageDir(void) +{ + if (image_dir != 0 /* nullptr */ && strcmp(image_dir, "") != 0) + if (!(mkdir(image_dir, 0777) == 0 || errno == EEXIST)) + fatal("cannot create directory '%1': %2", image_dir, + strerror(errno)); +} + +/* + * write_end_image - End the image. Write out the image extents if we + * are using -Tps. + */ + +static void write_end_image(int is_html) +{ + /* + * if we are producing html then these + * emit image name and enable output + * else + * we are producing images + * in which case these generate image + * boundaries + */ + writeString("\\O[4]\\O[2]"); + if (is_html) + writeString("\\O[1]"); + else + writeString("\\O[0]"); +} + +/* + * write_start_image - Write troff code which will: + * + * (i) disable html output for the following image + * (ii) reset the max/min x/y registers during + * Postscript Rendering. + */ + +static void write_start_image(IMAGE_ALIGNMENT pos, int is_html) +{ + writeString("\\O[5"); + switch (pos) { + case INLINE: + writeString("i"); + break; + case LEFT: + writeString("l"); + break; + case RIGHT: + writeString("r"); + break; + case CENTERED: + default: + writeString("c"); + break; + } + writeString(image_template); + writeString(".png]"); + if (is_html) + writeString("\\O[0]\\O[3]"); + else + // reset min/max registers + writeString("\\O[1]\\O[3]"); +} + +/* + * write_upto_newline - Write the contents of the buffer until a + * newline is seen. Check for + * HTML_IMAGE_INLINE_BEGIN and + * HTML_IMAGE_INLINE_END; process them if they are + * present. + */ + +void char_buffer::write_upto_newline(char_block **t, int *i, + int is_html) +{ + int j = *i; + + if (*t) { + while (j < (*t)->used + && (*t)->buffer[j] != '\n' + && (*t)->buffer[j] != INLINE_LEADER_CHAR) + j++; + if (j < (*t)->used + && (*t)->buffer[j] == '\n') + j++; + writeNbytes((*t)->buffer + (*i), j - (*i)); + if (j < char_block::SIZE && (*t)->buffer[j] == INLINE_LEADER_CHAR) { + if (can_see(t, &j, HTML_IMAGE_INLINE_BEGIN)) + write_start_image(INLINE, is_html); + else if (can_see(t, &j, HTML_IMAGE_INLINE_END)) + write_end_image(is_html); + else { + if (j < (*t)->used) { + *i = j; + j++; + writeNbytes((*t)->buffer + (*i), j - (*i)); + } + } + } + if (j == (*t)->used) { + *i = 0; + *t = (*t)->next; + if (*t && (*t)->buffer[j - 1] != '\n') + write_upto_newline(t, i, is_html); + } + else + // newline was seen + *i = j; + } +} + +/* + * can_see - Return true if we can see string in t->buffer[i] onwards. + */ + +bool char_buffer::can_see(char_block **t, int *i, const char *str) +{ + int j = 0; + int l = strlen(str); + int k = *i; + char_block *s = *t; + + while (s) { + while (k < s->used && j < l && s->buffer[k] == str[j]) { + j++; + k++; + } + if (j == l) { + *i = k; + *t = s; + return true; + } + else if (k < s->used && s->buffer[k] != str[j]) + return false; + s = s->next; + k = 0; + } + return false; +} + +/* + * skip_until_newline - Skip all characters until a newline is seen. + * The newline is not consumed. + */ + +void char_buffer::skip_until_newline(char_block **t, int *i) +{ + int j = *i; + + if (*t) { + while (j < (*t)->used && (*t)->buffer[j] != '\n') + j++; + if (j == (*t)->used) { + *i = 0; + *t = (*t)->next; + skip_until_newline(t, i); + } + else + // newline was seen + *i = j; + } +} + +#define DEVICE_FORMAT(filter) (filter == HTML_OUTPUT_FILTER) +#define HTML_OUTPUT_FILTER 0 +#define IMAGE_OUTPUT_FILTER 1 +#define OUTPUT_STREAM(name) creat((name), S_IWUSR | S_IRUSR) +#define PS_OUTPUT_STREAM OUTPUT_STREAM(psFileName) +#define REGION_OUTPUT_STREAM OUTPUT_STREAM(regionFileName) + +/* + * emit_troff_output - Write formatted buffer content to the troff + * post-processor data pipeline. + */ + +void char_buffer::emit_troff_output(int device_format_selector) +{ + // Handle output for BOTH html and image device formats + // if 'device_format_selector' is passed as + // + // HTML_FORMAT(HTML_OUTPUT_FILTER) + // Buffer data is written to the output stream + // with template image names translated to actual image names. + // + // HTML_FORMAT(IMAGE_OUTPUT_FILTER) + // Buffer data is written to the output stream + // with no translation, for image file creation in the + // post-processor. + + int idx = 0; + char_block *element = head; + + while (element != 0 /* nullptr */) + write_upto_newline(&element, &idx, device_format_selector); + +#if 0 + if (close(stdoutfd) < 0) + sys_fatal ("close"); + + // now we grab fd=1 so that the next pipe cannot use fd=1 + if (stdoutfd == 1) { + if (dup(2) != stdoutfd) + sys_fatal ("dup failed to use fd=1"); + } +#endif /* 0 */ +} + +/* + * The image class remembers the position of all images in the + * PostScript file and assigns names for each image. + */ + +struct imageItem { + imageItem *next; + int X1; + int Y1; + int X2; + int Y2; + char *imageName; + int resolution; + int maxx; + int pageNo; + + imageItem(int x1, int y1, int x2, int y2, + int page, int res, int max_width, char *name); + ~imageItem(); +}; + +/* + * imageItem - Constructor. + */ + +imageItem::imageItem(int x1, int y1, int x2, int y2, + int page, int res, int max_width, char *name) +{ + X1 = x1; + Y1 = y1; + X2 = x2; + Y2 = y2; + pageNo = page; + resolution = res; + maxx = max_width; + imageName = name; + next = 0 /* nullptr */; +} + +/* + * imageItem - Destructor. + */ + +imageItem::~imageItem() +{ + if (imageName) + free(imageName); +} + +/* + * imageList - A class containing a list of imageItems. + */ + +class imageList { +private: + imageItem *head; + imageItem *tail; + int count; +public: + imageList(); + ~imageList(); + void add(int x1, int y1, int x2, int y2, + int page, int res, int maxx, char *name); + void createImages(void); + int createPage(int pageno); + void createImage(imageItem *i); + int getMaxX(int pageno); +}; + +/* + * imageList - Constructor. + */ + +imageList::imageList() +: head(0), tail(0), count(0) +{ +} + +/* + * imageList - Destructor. + */ + +imageList::~imageList() +{ + while (head != 0 /* nullptr */) { + imageItem *i = head; + head = head->next; + delete i; + } +} + +/* + * createPage - Create image of page `pageno` from PostScript file. + */ + +int imageList::createPage(int pageno) +{ + char *s; + + if (currentPageNo == pageno) + return 0; + + if (currentPageNo >= 1) { + /* + * We need to unlink the files which change each time a new page is + * processed. The final unlink is done by xtmpfile when + * pre-grohtml exits. + */ + unlink(imagePageName); + unlink(psPageName); + } + + if (want_progress_report) { + fprintf(stderr, "[%d] ", pageno); + fflush(stderr); + } + +#if defined(DEBUGGING) + if (debugging) + fprintf(stderr, "creating page %d\n", pageno); +#endif + + s = make_string("psselect -q -p%d %s %s\n", + pageno, psFileName, psPageName); + html_system(s, 1); + assert(strlen(image_gen) > 0); + s = make_string("echo showpage | " + "%s%s -q -dBATCH -dSAFER " + "-dDEVICEHEIGHTPOINTS=792 " + "-dDEVICEWIDTHPOINTS=%d -dFIXEDMEDIA=true " + "-sDEVICE=%s -r%d %s " + "-sOutputFile=%s %s -\n", + image_gen, + EXE_EXT, + (getMaxX(pageno) * image_res) / postscriptRes, + image_device, + image_res, + antiAlias, + imagePageName, + psPageName); + html_system(s, 1); + free(s); + currentPageNo = pageno; + return 0; +} + +/* + * min - Return the minimum of two numbers. + */ + +int min(int x, int y) +{ + if (x < y) + return x; + else + return y; +} + +/* + * max - Return the maximum of two numbers. + */ + +int max(int x, int y) +{ + if (x > y) + return x; + else + return y; +} + +/* + * getMaxX - Return the largest right-hand position for any image + * on `pageno`. + */ + +int imageList::getMaxX(int pageno) +{ + imageItem *h = head; + int x = postscriptRes * DEFAULT_LINE_LENGTH; + + while (h != 0 /* nullptr */) { + if (h->pageNo == pageno) + x = max(h->X2, x); + h = h->next; + } + return x; +} + +/* + * createImage - Generate a minimal PNG file from the set of page + * images. + */ + +void imageList::createImage(imageItem *i) +{ + if (i->X1 != -1) { + char *s; + int x1 = max(min(i->X1, i->X2) * image_res / postscriptRes + - IMAGE_BORDER_PIXELS, + 0); + int y1 = max(image_res * vertical_offset / 72 + + min(i->Y1, i->Y2) * image_res / postscriptRes + - IMAGE_BORDER_PIXELS, + 0); + int x2 = max(i->X1, i->X2) * image_res / postscriptRes + + IMAGE_BORDER_PIXELS; + int y2 = image_res * vertical_offset / 72 + + max(i->Y1, i->Y2) * image_res / postscriptRes + + 1 + IMAGE_BORDER_PIXELS; + if (createPage(i->pageNo) == 0) { + s = make_string("pnmcut%s %d %d %d %d < %s " + "| pnmcrop%s -quiet | pnmtopng%s -quiet %s" + "> %s\n", + EXE_EXT, + x1, y1, x2 - x1 + 1, y2 - y1 + 1, + imagePageName, + EXE_EXT, + EXE_EXT, + TRANSPARENT, + i->imageName); + html_system(s, 0); + free(s); + } + else { + fprintf(stderr, "failed to generate image of page %d\n", + i->pageNo); + fflush(stderr); + } +#if defined(DEBUGGING) + } + else { + if (debugging) { + fprintf(stderr, "ignoring image as x1 coord is -1\n"); + fflush(stderr); + } +#endif + } +} + +/* + * add - Add an image description to the imageList. + */ + +void imageList::add(int x1, int y1, int x2, int y2, + int page, int res, int maxx, char *name) +{ + imageItem *i = new imageItem(x1, y1, x2, y2, page, res, maxx, name); + + if (0 /* nullptr */ == head) { + head = i; + tail = i; + } + else { + tail->next = i; + tail = i; + } +} + +/* + * createImages - For each image descriptor on the imageList, + * create the actual image. + */ + +void imageList::createImages(void) +{ + imageItem *h = head; + + while (h != 0 /* nullptr */) { + createImage(h); + h = h->next; + } +} + +static imageList listOfImages; // list of images defined by region file + +/* + * generateImages - Parse the region file and generate images from the + * PostScript file. The region file contains the + * x1,y1--x2,y2 extents of each image. + */ + +static void generateImages(char *region_file_name) +{ + pushBackBuffer *f=new pushBackBuffer(region_file_name); + + while (f->putPB(f->getPB()) != eof) { + if (f->isString("grohtml-info:page")) { + int page = f->readInt(); + int x1 = f->readInt(); + int y1 = f->readInt(); + int x2 = f->readInt(); + int y2 = f->readInt(); + int maxx = f->readInt(); + char *name = f->readString(); + int res = postscriptRes; + listOfImages.add(x1, y1, x2, y2, page, res, maxx, name); + while (f->putPB(f->getPB()) != '\n' + && f->putPB(f->getPB()) != eof) + (void)f->getPB(); + if (f->putPB(f->getPB()) == '\n') + (void)f->getPB(); + } + else { + /* Write any error messages out to the user. */ + fputc(f->getPB(), stderr); + } + } + fflush(stderr); + + listOfImages.createImages(); + if (want_progress_report) { + fprintf(stderr, "done\n"); + fflush(stderr); + } + delete f; +} + +/* + * set_redirection - Redirect file descriptor `was` to file descriptor + * `willbe`. + */ + +static void set_redirection(int was, int willbe) +{ + // Nothing to do if 'was' and 'willbe' already have same handle. + if (was != willbe) { + // Otherwise attempt the specified redirection. + if (dup2(willbe, was) < 0) { + // Redirection failed, so issue diagnostic and bail out. + fprintf(stderr, "failed to replace fd=%d with %d\n", was, willbe); + if (willbe == STDOUT_FILENO) + fprintf(stderr, + "likely that stdout should be opened before %d\n", was); + sys_fatal("dup2"); + } + + // When redirection has been successfully completed assume redundant + // handle 'willbe' is no longer required, so close it. + if (close(willbe) < 0) + // Issue diagnostic if 'close' fails. + sys_fatal("close"); + } +} + +/* + * save_and_redirect - Duplicate file descriptor for `was` on file + * descriptor `willbe`. + */ + +static int save_and_redirect(int was, int willbe) +{ + if (was == willbe) + // No redirection specified; silently bail out. + return (was); + + // Proceeding with redirection so first save and verify our duplicate + // handle for 'was'. + int saved = dup(was); + if (saved < 0) { + fprintf(stderr, "unable to get duplicate handle for %d\n", was); + sys_fatal("dup"); + } + + // Duplicate handle safely established so complete redirection. + set_redirection(was, willbe); + + // Finally return the saved duplicate descriptor for the original + // 'was' descriptor. + return saved; +} + +/* + * alterDeviceTo - If toImage is set + * the argument list is altered to include + * IMAGE_DEVICE; we invoke groff rather than troff. + * Else + * set -Thtml and groff. + */ + +static void alterDeviceTo(int argc, char *argv[], int toImage) +{ + int i = 0; + + if (toImage) { + while (i < argc) { + if ((strcmp(argv[i], "-Thtml") == 0) || + (strcmp(argv[i], "-Txhtml") == 0)) + argv[i] = (char *)IMAGE_DEVICE; + i++; + } + argv[troff_arg] = (char *)"groff"; /* rather than troff */ + } + else { + while (i < argc) { + if (strcmp(argv[i], IMAGE_DEVICE) == 0) { + if (dialect == xhtml) + argv[i] = (char *)"-Txhtml"; + else + argv[i] = (char *)"-Thtml"; + } + i++; + } + argv[troff_arg] = (char *)"groff"; /* use groff -Z */ + } +} + +/* + * addArg - Append newarg onto the command list for groff. + */ + +char **addArg(int argc, char *argv[], char *newarg) +{ + char **new_argv = (char **)malloc((argc + 2) * sizeof(char *)); + int i = 0; + + if (0 /* nullptr */ == new_argv) + sys_fatal("malloc"); + + if (argc > 0) { + new_argv[i] = argv[i]; + i++; + } + new_argv[i] = newarg; + while (i < argc) { + new_argv[i + 1] = argv[i]; + i++; + } + argc++; + new_argv[argc] = 0 /* nullptr */; + return new_argv; +} + +/* + * addRegDef - Append a defined register or string onto the command + * list for troff. + */ + +char **addRegDef(int argc, char *argv[], const char *numReg) +{ + char **new_argv = (char **)malloc((argc + 2) * sizeof(char *)); + int i = 0; + + if (0 /* nullptr */ == new_argv) + sys_fatal("malloc"); + + while (i < argc) { + new_argv[i] = argv[i]; + i++; + } + new_argv[argc] = strsave(numReg); + argc++; + new_argv[argc] = 0 /* nullptr */; + return new_argv; +} + +/* + * dump_args - Display the argument list. + */ + +void dump_args(int argc, char *argv[]) +{ + fprintf(stderr, " %d arguments:", argc); + for (int i = 0; i < argc; i++) + fprintf(stderr, " %s", argv[i]); + fprintf(stderr, "\n"); +} + +/* + * print_args - Print arguments as if issued on the command line. + */ + +#if defined(DEBUGGING) + +void print_args(int argc, char *argv[]) +{ + if (debugging) { + fprintf(stderr, "executing: "); + for (int i = 0; i < argc; i++) + fprintf(stderr, "%s ", argv[i]); + fprintf(stderr, "\n"); + } +} + +#else + +void print_args(int, char **) +{ +} + +#endif + +int char_buffer::run_output_filter(int filter, int argc, char **argv) +{ + int pipedes[2]; + PID_T child_pid; + int wstatus; + + print_args(argc, argv); + if (pipe(pipedes) < 0) + sys_fatal("pipe"); + +#if MAY_FORK_CHILD_PROCESS + // This is the Unix process model. To invoke our post-processor, + // we must 'fork' the current process. + + if ((child_pid = fork()) < 0) + sys_fatal("fork"); + + else if (child_pid == 0) { + // This is the child process. We redirect its input file descriptor + // to read data emerging from our pipe. There is no point in + // saving, since we won't be able to restore later! + + set_redirection(STDIN_FILENO, pipedes[0]); + + // The parent process will be writing this data; release the child's + // writeable handle on the pipe since we have no use for it. + + if (close(pipedes[1]) < 0) + sys_fatal("close"); + + // The IMAGE_OUTPUT_FILTER needs special output redirection... + + if (filter == IMAGE_OUTPUT_FILTER) { + // ...with BOTH 'stdout' AND 'stderr' diverted to files, the + // latter so that `generateImages()` can scrape "grohtml-info" + // from it. + + set_redirection(STDOUT_FILENO, PS_OUTPUT_STREAM); + set_redirection(STDERR_FILENO, REGION_OUTPUT_STREAM); + } + + // Now we are ready to launch the output filter. + + execvp(argv[0], argv); // does not return unless it fails + fatal("cannot execute '%1': %2", argv[0], strerror(errno)); + } + + else { + // This is the parent process. We write data to the filter pipeline + // where the child will read it. We have no need to read from the + // input side ourselves, so close it. + + if (close(pipedes[0]) < 0) + sys_fatal("close"); + + // Now redirect the standard output file descriptor to the inlet end + // of the pipe, and push the formatted data to the filter. + + pipedes[1] = save_and_redirect(STDOUT_FILENO, pipedes[1]); + emit_troff_output(DEVICE_FORMAT(filter)); + + // After emitting all the data we close our connection to the inlet + // end of the pipe so the child process will detect end of data. + + set_redirection(STDOUT_FILENO, pipedes[1]); + + // Finally, we must wait for the child process to complete. + + if (WAIT(&wstatus, child_pid, _WAIT_CHILD) != child_pid) + sys_fatal("wait"); + } + +#elif MAY_SPAWN_ASYNCHRONOUS_CHILD + + // We do not have `fork` (or we prefer not to use it), but + // asynchronous processes are allowed, passing data through pipes. + // This should be okay for most Win32 systems and is preferred to + // `fork` for starting child processes under Cygwin. + + // Before we start the post-processor we bind its inherited standard + // input file descriptor to the readable end of our pipe, saving our + // own standard input file descriptor in `pipedes[0]`. + + pipedes[0] = save_and_redirect(STDIN_FILENO, pipedes[0]); + + // For the Win32 model, + // we need special provision for saving BOTH 'stdout' and 'stderr'. + + int saved_stdout = dup(STDOUT_FILENO); + int saved_stderr = STDERR_FILENO; + + // The IMAGE_OUTPUT_FILTER needs special output redirection... + + if (filter == IMAGE_OUTPUT_FILTER) { + // with BOTH 'stdout' AND 'stderr' diverted to files while saving a + // duplicate handle for 'stderr'. + + set_redirection(STDOUT_FILENO, PS_OUTPUT_STREAM); + saved_stderr = save_and_redirect(STDERR_FILENO, + REGION_OUTPUT_STREAM); + } + + // Use an asynchronous spawn request to start the post-processor. + + if ((child_pid = spawnvp(_P_NOWAIT, argv[0], argv)) < 0) { + fatal("cannot spawn %1: %2", argv[0], strerror(errno)); + } + + // Once the post-processor has been started we revert our 'stdin' + // to its original saved source, which also closes the readable handle + // for the pipe. + + set_redirection(STDIN_FILENO, pipedes[0]); + + // if we redirected 'stderr', for use by the image post-processor, + // then we also need to reinstate its original assignment. + + if (filter == IMAGE_OUTPUT_FILTER) + set_redirection(STDERR_FILENO, saved_stderr); + + // Now we redirect the standard output to the inlet end of the pipe, + // and push out the appropriately formatted data to the filter. + + set_redirection(STDOUT_FILENO, pipedes[1]); + emit_troff_output(DEVICE_FORMAT(filter)); + + // After emitting all the data we close our connection to the inlet + // end of the pipe so the child process will detect end of data. + + set_redirection(STDOUT_FILENO, saved_stdout); + + // And finally, we must wait for the child process to complete. + + if (WAIT(&wstatus, child_pid, _WAIT_CHILD) != child_pid) + sys_fatal("wait"); + +#else /* can't do asynchronous pipes! */ + + // TODO: code to support an MS-DOS style process model should go here + fatal("output filtering not supported on this platform"); + +#endif /* MAY_FORK_CHILD_PROCESS or MAY_SPAWN_ASYNCHRONOUS_CHILD */ + + return wstatus; +} + +/* + * do_html - Set the troff number htmlflip and + * write out the buffer to troff -Thtml. + */ + +int char_buffer::do_html(int argc, char *argv[]) +{ + string s; + + alterDeviceTo(argc, argv, 0); + argv += troff_arg; // skip all arguments up to groff + argc -= troff_arg; + argv = addArg(argc, argv, (char *)"-Z"); + argc++; + + s = (char *)"-dwww-image-template="; + s += macroset_template; // Do not combine these statements, + // otherwise they will not work. + s += '\0'; // The trailing '\0' is ignored. + argv = addRegDef(argc, argv, s.contents()); + argc++; + + if (dialect == xhtml) { + argv = addRegDef(argc, argv, "-rxhtml=1"); + argc++; + if (need_eqn) { + argv = addRegDef(argc, argv, "-e"); + argc++; + } + } + +#if defined(DEBUGGING) +# define HTML_DEBUG_STREAM OUTPUT_STREAM(htmlFileName) + // slight security risk: only enabled if defined(DEBUGGING) + if (debugging) { + int saved_stdout = save_and_redirect(STDOUT_FILENO, + HTML_DEBUG_STREAM); + emit_troff_output(DEVICE_FORMAT(HTML_OUTPUT_FILTER)); + set_redirection(STDOUT_FILENO, saved_stdout); + } +#endif + + return run_output_filter(HTML_OUTPUT_FILTER, argc, argv); +} + +/* + * do_image - Write out the buffer to troff -Tps. + */ + +int char_buffer::do_image(int argc, char *argv[]) +{ + string s; + + alterDeviceTo(argc, argv, 1); + argv += troff_arg; // skip all arguments up to troff/groff + argc -= troff_arg; + argv = addRegDef(argc, argv, "-rps4html=1"); + argc++; + + s = "-dwww-image-template="; + s += macroset_template; + s += '\0'; + argv = addRegDef(argc, argv, s.contents()); + argc++; + + // Override local settings and produce a letter-size PostScript page + // file. + argv = addRegDef(argc, argv, "-P-pletter"); + argc++; + + if (dialect == xhtml) { + if (need_eqn) { + argv = addRegDef(argc, argv, "-rxhtml=1"); + argc++; + } + argv = addRegDef(argc, argv, "-e"); + argc++; + } + +#if defined(DEBUGGING) +# define IMAGE_DEBUG_STREAM OUTPUT_STREAM(troffFileName) + // slight security risk: only enabled if defined(DEBUGGING) + if (debugging) { + int saved_stdout = save_and_redirect(STDOUT_FILENO, + IMAGE_DEBUG_STREAM); + emit_troff_output(DEVICE_FORMAT(IMAGE_OUTPUT_FILTER)); + set_redirection(STDOUT_FILENO, saved_stdout); + } +#endif + + return run_output_filter(IMAGE_OUTPUT_FILTER, argc, argv); +} + +static char_buffer inputFile; + +/* + * usage - Emit usage message. + */ + +static void usage(FILE *stream) +{ + fprintf(stream, +"usage: %s [-epV] [-a anti-aliasing-text-bits] [-D image-directory]" +" [-F font-directory] [-g anti-aliasing-graphics-bits] [-i resolution]" +" [-I image-stem] [-o image-vertical-offset] [-x html-dialect]" +" troff-command troff-argument ...\n" +"usage: %s {-v | --version}\n" +"usage: %s --help\n", + program_name, program_name, program_name); + if (stdout == stream) { + fputs( +"\n" +"Prepare a troff(1) document for HTML formatting.\n" +"\n" +"This program is not intended to be executed standalone; it is\n" +"normally part of a groff pipeline. If your need to run it manually\n" +"(e.g., for debugging purposes), give the 'groff' program the\n" +"command-line option '-V' to inspect the arguments with which\n", + stream); + fprintf(stream, +"'%s' is called. See the grohtml(1) manual page.\n", + program_name); + exit(EXIT_SUCCESS); + } +} + +/* + * scanArguments - Scan for all arguments including -P-i, -P-o, -P-D, + * and -P-I. Return the argument index of the first + * non-option. + */ + +static int scanArguments(int argc, char **argv) +{ + const char *cmdprefix = getenv("GROFF_COMMAND_PREFIX"); + if (!cmdprefix) + cmdprefix = PROG_PREFIX; + size_t pfxlen = strlen(cmdprefix); + char *troff_name = new char[pfxlen + strlen("troff") + 1]; + char *s = strcpy(troff_name, cmdprefix); + s += pfxlen; + strcpy(s, "troff"); + int c, i; + static const struct option long_options[] = { + { "help", no_argument, 0, CHAR_MAX + 1 }, + { "version", no_argument, 0, 'v' }, + { 0 /* nullptr */, 0, 0, 0 } + }; + while ((c = getopt_long(argc, argv, + "+a:bCdD:eF:g:Ghi:I:j:lno:prs:S:vVx:y", long_options, + 0 /* nullptr */)) + != EOF) + switch(c) { + case 'a': + textAlphaBits = min(max(MIN_ALPHA_BITS, atoi(optarg)), + MAX_ALPHA_BITS); + if (textAlphaBits == 3) + fatal("cannot use 3 bits of antialiasing information"); + break; + case 'b': + // handled by post-grohtml (set background color to white) + break; + case 'C': + // handled by post-grohtml (don't write Creator HTML comment) + break; + case 'd': +#if defined(DEBUGGING) + debugging = true; +#endif + break; + case 'D': + image_dir = optarg; + break; + case 'e': + need_eqn = true; + break; + case 'F': + font_path.command_line_dir(optarg); + break; + case 'g': + graphicAlphaBits = min(max(MIN_ALPHA_BITS, atoi(optarg)), + MAX_ALPHA_BITS); + if (graphicAlphaBits == 3) + fatal("cannot use 3 bits of antialiasing information"); + break; + case 'G': + // handled by post-grohtml (don't write CreationDate HTML comment) + break; + case 'h': + // handled by post-grohtml (write headings with font size changes) + break; + case 'i': + image_res = atoi(optarg); + break; + case 'I': + image_template = optarg; + break; + case 'j': + // handled by post-grohtml (set job name for multiple file output) + break; + case 'l': + // handled by post-grohtml (no automatic section links) + break; + case 'n': + // handled by post-grohtml (generate simple heading anchors) + break; + case 'o': + vertical_offset = atoi(optarg); + break; + case 'p': + want_progress_report = true; + break; + case 'r': + // handled by post-grohtml (no header and footer lines) + break; + case 's': + // handled by post-grohtml (use font size n as the HTML base size) + break; + case 'S': + // handled by post-grohtml (set file split level) + break; + case 'v': + printf("GNU pre-grohtml (groff) version %s\n", Version_string); + exit(EXIT_SUCCESS); + case 'V': + // handled by post-grohtml (create validator button) + break; + case 'x': + // html dialect + if (strcmp(optarg, "x") == 0) + dialect = xhtml; + else if (strcmp(optarg, "4") == 0) + dialect = html4; + else + warning("unsupported HTML dialect: '%1'", optarg); + break; + case 'y': + // handled by post-grohtml (create groff signature) + break; + case CHAR_MAX + 1: // --help + usage(stdout); + break; + case '?': + usage(stderr); + exit(EXIT_FAILURE); + break; + default: + break; + } + + i = optind; + while (i < argc) { + if (strcmp(argv[i], troff_name) == 0) + troff_arg = i; + else if (argv[i][0] != '-') + return i; + i++; + } + delete[] troff_name; + + return argc; +} + +/* + * makeTempFiles - Name the temporary files. + */ + +static void makeTempFiles(void) +{ +#if defined(DEBUGGING) + psFileName = DEBUG_FILE("prehtml-ps"); + regionFileName = DEBUG_FILE("prehtml-region"); + imagePageName = DEBUG_FILE("prehtml-page"); + psPageName = DEBUG_FILE("prehtml-psn"); + troffFileName = DEBUG_FILE("prehtml-troff"); + htmlFileName = DEBUG_FILE("prehtml-html"); +#else /* not DEBUGGING */ + FILE *f; + + // psPageName contains a single page of PostScript. + f = xtmpfile(&psPageName, PS_TEMPLATE_LONG, PS_TEMPLATE_SHORT, true); + if (0 /* nullptr */ == f) + sys_fatal("xtmpfile"); + fclose(f); + + // imagePageName contains a bitmap image of a single PostScript page. + f = xtmpfile(&imagePageName, PAGE_TEMPLATE_LONG, PAGE_TEMPLATE_SHORT, + true); + if (0 /* nullptr */ == f) + sys_fatal("xtmpfile"); + fclose(f); + + // psFileName contains a PostScript file of the complete document. + f = xtmpfile(&psFileName, PS_TEMPLATE_LONG, PS_TEMPLATE_SHORT, true); + if (0 /* nullptr */ == f) + sys_fatal("xtmpfile"); + fclose(f); + + // regionFileName contains a list of the images and their boxed + // coordinates. + f = xtmpfile(®ionFileName, + REGION_TEMPLATE_LONG, REGION_TEMPLATE_SHORT, true); + if (0 /* nullptr */ == f) + sys_fatal("xtmpfile"); + fclose(f); +#endif /* not DEBUGGING */ +} + +static bool do_file(const char *filename) +{ + FILE *fp; + + current_filename = filename; + if (strcmp(filename, "-") == 0) + fp = stdin; + else { + fp = fopen(filename, "r"); + if (0 /* nullptr*/ == fp) { + error("unable to open '%1': %2", filename, strerror(errno)); + return false; + } + } + inputFile.read_file(fp); + if (fp != stdin) + if (fclose(fp) != 0) + sys_fatal("fclose"); + current_filename = 0 /* nullptr */; + return true; +} + +static void cleanup(void) +{ + free(const_cast(image_gen)); +} + +int main(int argc, char **argv) +{ +#ifdef CAPTURE_MODE + fprintf(stderr, "%s: invoked with %d arguments ...\n", argv[0], argc); + for (int i = 0; i < argc; i++) + fprintf(stderr, "%2d: %s\n", i, argv[i]); + FILE *dump = fopen(DEBUG_FILE("pre-html-data"), "wb"); + if (dump != 0 /* nullptr */) { + while((int ch = fgetc(stdin)) >= 0) + fputc(ch, dump); + fclose(dump); + } + exit(EXIT_FAILURE); +#endif /* CAPTURE_MODE */ + program_name = argv[0]; + if (atexit(&cleanup) != 0) + sys_fatal("atexit"); + int operand_index = scanArguments(argc, argv); + image_gen = strsave(get_image_generator()); + if (0 == image_gen) + fatal("'image_generator' directive not found in file '%1'", + devhtml_desc); + postscriptRes = get_resolution(); + if (postscriptRes < 1) // TODO: what's a more sane minimum value? + fatal("'res' directive missing or invalid in file '%1'", + devps_desc); + setupAntiAlias(); + checkImageDir(); + makeFileName(); + bool have_file_operand = false; + while (operand_index < argc) { + if (argv[operand_index][0] != '-') { + if(!do_file(argv[operand_index])) + exit(EXIT_FAILURE); + have_file_operand = true; + } + operand_index++; + } + + if (!have_file_operand) + do_file("-"); + makeTempFiles(); + int wstatus = inputFile.do_image(argc, argv); + if (wstatus == 0) { + generateImages(regionFileName); + wstatus = inputFile.do_html(argc, argv); + } + else + if (WEXITSTATUS(wstatus) != 0) + // XXX: This is a crappy suggestion. See Savannah #62673. + fatal("'%1' exited with status %2; re-run with a different output" + " driver to see diagnostic messages", argv[0], + WEXITSTATUS(wstatus)); + exit(EXIT_SUCCESS); +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/html/pre-html.h b/src/preproc/html/pre-html.h new file mode 100644 index 0000000..f257854 --- /dev/null +++ b/src/preproc/html/pre-html.h @@ -0,0 +1,38 @@ +// -*- C++ -*- +/* Copyright (C) 2000-2020 Free Software Foundation, Inc. + * Written by Gaius Mulley (gaius@glam.ac.uk). + * + * This file 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 groff; see the file COPYING. If not, write to the Free Software + * Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * defines functions implemented within pre-html.cpp + */ + +#if !defined(PREHTMLH) +# define PREHTMLH +# if defined(PREHTMLC) +# define EXTERN +# else +# define EXTERN extern +# endif + + +extern void sys_fatal (const char *s); + +#undef EXTERN +#endif diff --git a/src/preproc/html/pushback.cpp b/src/preproc/html/pushback.cpp new file mode 100644 index 0000000..100ac0b --- /dev/null +++ b/src/preproc/html/pushback.cpp @@ -0,0 +1,336 @@ +/* Copyright (C) 2000-2020 Free Software Foundation, Inc. + Written by Gaius Mulley (gaius@glam.ac.uk). + +This file 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 . */ + +#include "lib.h" + +#include +#include +#include +#include +#include "errarg.h" +#include "error.h" +#include "stringclass.h" +#include "posix.h" +#include "nonposix.h" + +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "pushback.h" +#include "pre-html.h" + +#if !defined(TRUE) +# define TRUE (1==1) +#endif + +#if !defined(FALSE) +# define FALSE (1==0) +#endif + +# define ERROR(X) (void)(fprintf(stderr, "%s:%d error %s\n", __FILE__, __LINE__, X) && \ + (fflush(stderr)) && localexit(1)) + + +#define MAXPUSHBACKSTACK 4096 /* maximum number of character that can be pushed back */ + + +/* + * constructor for pushBackBuffer + */ + +pushBackBuffer::pushBackBuffer (char *filename) +{ + charStack = (char *)malloc(MAXPUSHBACKSTACK); + if (charStack == 0) { + sys_fatal("malloc"); + } + stackPtr = 0; /* index to push back stack */ + verbose = 0; + eofFound = FALSE; + lineNo = 1; + if (strcmp(filename, "") != 0) { + stdIn = dup(0); + if (stdIn < 0) { + sys_fatal("dup stdin"); + } + close(0); + if (open(filename, O_RDONLY) != 0) { + sys_fatal("when trying to open file"); + } else { + fileName = filename; + } + } +} + +pushBackBuffer::~pushBackBuffer () +{ + if (charStack != 0) { + free(charStack); + } + close(0); + /* restore stdin in file descriptor 0 */ + if (dup(stdIn) < 0) { + sys_fatal("restore stdin"); + } + close(stdIn); +} + +/* + * localexit - wraps exit with a return code to aid the ERROR macro. + */ + +int localexit (int i) +{ + exit(i); + return( 1 ); +} + +/* + * getPB - returns a character, possibly a pushed back character. + */ + +char pushBackBuffer::getPB (void) +{ + if (stackPtr>0) { + stackPtr--; + return( charStack[stackPtr] ); + } else { + char ch; + + if (read(0, &ch, 1) == 1) { + if (verbose) { + printf("%c", ch); + } + if (ch == '\n') { + lineNo++; + } + return( ch ); + } else { + eofFound = TRUE; + return( eof ); + } + } +} + +/* + * putPB - pushes a character onto the push back stack. + * The same character is returned. + */ + +char pushBackBuffer::putPB (char ch) +{ + if (stackPtr=0) { + if (putPB(s[i]) != s[i]) { + ERROR("assert failed"); + } + i--; + } + } + return( FALSE ); +} + +/* + * isDigit - returns TRUE if the character, ch, is a digit. + */ + +static int isDigit (char ch) +{ + return( ((ch>='0') && (ch<='9')) ); +} + +/* + * isHexDigit - returns TRUE if the character, ch, is a hex digit. + */ + +#if 0 +static int isHexDigit (char ch) +{ + return( (isDigit(ch)) || ((ch>='a') && (ch<='f')) ); +} +#endif + +/* + * readInt - returns an integer from the input stream. + */ + +int pushBackBuffer::readInt (void) +{ + int c =0; + int i =0; + int s =1; + char ch=getPB(); + + while (isWhite(ch)) { + ch=getPB(); + } + // now read integer + + if (ch == '-') { + s = -1; + ch = getPB(); + } + while (isDigit(ch)) { + i *= 10; + if ((ch>='0') && (ch<='9')) { + i += (int)(ch-'0'); + } + ch = getPB(); + c++; + } + if (ch != putPB(ch)) { + ERROR("assert failed"); + } + return( i*s ); +} + +/* + * convertToFloat - converts integers, a and b into a.b + */ + +static double convertToFloat (int a, int b) +{ + int c=10; + double f; + + while (b>c) { + c *= 10; + } + f = ((double)a) + (((double)b)/((double)c)); + return( f ); +} + +/* + * readNumber - returns a float representing the word just read. + */ + +double pushBackBuffer::readNumber (void) +{ + int i; + char ch; + + i = readInt(); + if ((ch = getPB()) == '.') { + return convertToFloat(i, readInt()); + } + putPB(ch); + return (double)i; +} + +/* + * readString - reads a string terminated by white space + * and returns a malloced area of memory containing + * a copy of the characters. + */ + +char *pushBackBuffer::readString (void) +{ + char buffer[MAXPUSHBACKSTACK]; + char *str = 0; + int i=0; + char ch=getPB(); + + while (isWhite(ch)) { + ch=getPB(); + } + while ((i < MAXPUSHBACKSTACK) && (! isWhite(ch)) && (! eofFound)) { + buffer[i] = ch; + i++; + ch = getPB(); + } + if (i < MAXPUSHBACKSTACK) { + buffer[i] = (char)0; + str = (char *)malloc(strlen(buffer)+1); + strcpy(str, buffer); + } + return( str ); +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/html/pushback.h b/src/preproc/html/pushback.h new file mode 100644 index 0000000..263a6c5 --- /dev/null +++ b/src/preproc/html/pushback.h @@ -0,0 +1,52 @@ +// -*- C -*- +/* Copyright (C) 2000-2020 Free Software Foundation, Inc. + Written by Gaius Mulley (gaius@glam.ac.uk). + +This file 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 . */ + + +#define eof (char)-1 + + +/* + * defines the class and methods implemented within pushback.cpp + */ + +class pushBackBuffer +{ + private: + char *charStack; + int stackPtr; /* index to push back stack */ + int verbose; + int eofFound; + char *fileName; + int lineNo; + int stdIn; + + public: + pushBackBuffer (char *); + ~ pushBackBuffer (); + char getPB (void); + char putPB (char ch); + void skipUntilToken (void); + void skipToNewline (void); + double readNumber (void); + int readInt (void); + char *readString (void); + int isString (const char *string); +}; + + diff --git a/src/preproc/pic/TODO b/src/preproc/pic/TODO new file mode 100644 index 0000000..53ca282 --- /dev/null +++ b/src/preproc/pic/TODO @@ -0,0 +1,35 @@ +In troff mode, dotted and dashed splines. + +Make DELIMITED have type lstr; this would allow us to give better +error messages for problems within the body of for and if constructs. + +In troff mode without -x, fake \D't' with .ps commands. + +Perhaps an option to set command char. + +Add an output class for dumb line printers. It wouldn't be pretty but +it would be better than nothing. Integrate it with texinfo. Useful +for groff -Tascii as well. + +Option to allow better positioning of arrowheads on arcs. + +Perhaps add PostScript output mode. + +Change the interface to the output class so that output devices have +the opportunity to handle arrowheads themselves. + +Consider whether the line thickness should scale. + +Consider whether the test in a for loop should be fuzzy (as it +apparently is in grap). + +Possibly change fillval so that zero is black. + +Provide a way of getting text blocks (positioned with '.in' rather +than \h), into pic. Should be possible to use block of diverted text +in pic. Possibly something similar to T{ and T} in tbl. + +Option to provide macro backtraces. + +Have a path that is searched by 'copy' statement. Set by environment +variable or command-line option. diff --git a/src/preproc/pic/common.cpp b/src/preproc/pic/common.cpp new file mode 100644 index 0000000..6a4a93e --- /dev/null +++ b/src/preproc/pic/common.cpp @@ -0,0 +1,647 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "pic.h" +#include "common.h" + +// output a dashed circle as a series of arcs + +void common_output::dashed_circle(const position ¢, double rad, + const line_type <) +{ + assert(lt.type == line_type::dashed); + line_type slt = lt; + slt.type = line_type::solid; + double dash_angle = lt.dash_width/rad; + int ndashes; + double gap_angle; + if (dash_angle >= M_PI/4.0) { + if (dash_angle < M_PI/2.0) { + gap_angle = M_PI/2.0 - dash_angle; + ndashes = 4; + } + else if (dash_angle < M_PI) { + gap_angle = M_PI - dash_angle; + ndashes = 2; + } + else { + circle(cent, rad, slt, -1.0); + return; + } + } + else { + ndashes = 4*int(ceil(M_PI/(4.0*dash_angle))); + gap_angle = (M_PI*2.0)/ndashes - dash_angle; + } + for (int i = 0; i < ndashes; i++) { + double start_angle = i*(dash_angle+gap_angle) - dash_angle/2.0; + solid_arc(cent, rad, start_angle, start_angle + dash_angle, lt); + } +} + +// output a dotted circle as a series of dots + +void common_output::dotted_circle(const position ¢, double rad, + const line_type <) +{ + assert(lt.type == line_type::dotted); + double gap_angle = lt.dash_width/rad; + int ndots; + if (gap_angle >= M_PI/2.0) { + // always have at least 2 dots + gap_angle = M_PI; + ndots = 2; + } + else { + ndots = 4*int(M_PI/(2.0*gap_angle)); + gap_angle = (M_PI*2.0)/ndots; + } + double ang = 0.0; + for (int i = 0; i < ndots; i++, ang += gap_angle) + dot(cent + position(cos(ang), sin(ang))*rad, lt); +} + +// recursive function for dash drawing, used by dashed_ellipse + +void common_output::ellipse_arc(const position ¢, + const position &z0, const position &z1, + const distance &dim, const line_type <) +{ + assert(lt.type == line_type::solid); + assert(dim.x != 0 && dim.y != 0); + double eps = 0.0001; + position zml = (z0 + z1) / 2; + // apply affine transformation (from ellipse to circle) to compute angle + // of new position, then invert transformation to get exact position + double psi = atan2(zml.y / dim.y, zml.x / dim.x); + position zm = position(dim.x * cos(psi), dim.y * sin(psi)); + // to approximate the ellipse arc with one or more circle arcs, we + // first compute the radius of curvature in zm + double a_2 = dim.x * dim.x; + double a_4 = a_2 * a_2; + double b_2 = dim.y * dim.y; + double b_4 = b_2 * b_2; + double e_2 = a_2 - b_2; + double temp = a_4 * zm.y * zm.y + b_4 * zm.x * zm.x; + double rho = sqrt(temp / a_4 / b_4 * temp / a_4 / b_4 * temp); + // compute center of curvature circle + position M = position(e_2 * zm.x / a_2 * zm.x / a_2 * zm.x, + -e_2 * zm.y / b_2 * zm.y / b_2 * zm.y); + // compute distance between circle and ellipse arc at start and end + double phi0 = atan2(z0.y - M.y, z0.x - M.x); + double phi1 = atan2(z1.y - M.y, z1.x - M.x); + position M0 = position(rho * cos(phi0), rho * sin(phi0)) + M; + position M1 = position(rho * cos(phi1), rho * sin(phi1)) + M; + double dist0 = hypot(z0 - M0) / sqrt(z0 * z0); + double dist1 = hypot(z1 - M1) / sqrt(z1 * z1); + if (dist0 < eps && dist1 < eps) + solid_arc(M + cent, rho, phi0, phi1, lt); + else { + ellipse_arc(cent, z0, zm, dim, lt); + ellipse_arc(cent, zm, z1, dim, lt); + } +} + +// output a dashed ellipse as a series of arcs + +void common_output::dashed_ellipse(const position ¢, const distance &dim, + const line_type <) +{ + assert(lt.type == line_type::dashed); + double dim_x = dim.x / 2; + double dim_y = dim.y / 2; + line_type slt = lt; + slt.type = line_type::solid; + double dw = lt.dash_width; + // we use an approximation to compute the ellipse length (found in: + // Bronstein, Semendjajew, Taschenbuch der Mathematik) + double lambda = (dim.x - dim.y) / (dim.x + dim.y); + double le = M_PI / 2 * (dim.x + dim.y) + * ((64 - 3 * lambda * lambda * lambda * lambda ) + / (64 - 16 * lambda * lambda)); + // for symmetry we make nmax a multiple of 8 + int nmax = 8 * int(le / dw / 8 + 0.5); + if (nmax < 8) { + nmax = 8; + dw = le / 8; + } + int ndash = nmax / 2; + double gapwidth = (le - dw * ndash) / ndash; + double l = 0; + position z = position(dim_x, 0); + position zdot = z; + int j = 0; + int jmax = int(10 / lt.dash_width); + for (int i = 0; i <= nmax; i++) { + position zold = z; + position zpre = zdot; + double ld = (int(i / 2) + 0.5) * dw + int((i + 1) / 2) * gapwidth; + double lold = 0; + double dl = 1; + // find next position for fixed arc length + while (l < ld) { + j++; + lold = l; + zold = z; + double phi = j * 2 * M_PI / jmax; + z = position(dim_x * cos(phi), dim_y * sin(phi)); + dl = hypot(z - zold); + l += dl; + } + // interpolate linearly between the last two points, + // using the length difference as the scaling factor + double delta = (ld - lold) / dl; + zdot = zold + (z - zold) * delta; + // compute angle of new position on the affine circle + // and use it to get the exact value on the ellipse + double psi = atan2(zdot.y / dim_y, zdot.x / dim_x); + zdot = position(dim_x * cos(psi), dim_y * sin(psi)); + if ((i % 2 == 0) && (i > 1)) + ellipse_arc(cent, zpre, zdot, dim / 2, slt); + } +} + +// output a dotted ellipse as a series of dots + +void common_output::dotted_ellipse(const position ¢, const distance &dim, + const line_type <) +{ + assert(lt.type == line_type::dotted); + double dim_x = dim.x / 2; + double dim_y = dim.y / 2; + line_type slt = lt; + slt.type = line_type::solid; + // we use an approximation to compute the ellipse length (found in: + // Bronstein, Semendjajew, Taschenbuch der Mathematik) + double lambda = (dim.x - dim.y) / (dim.x + dim.y); + double le = M_PI / 2 * (dim.x + dim.y) + * ((64 - 3 * lambda * lambda * lambda * lambda ) + / (64 - 16 * lambda * lambda)); + // for symmetry we make nmax a multiple of 4 + int ndots = 4 * int(le / lt.dash_width / 4 + 0.5); + if (ndots < 4) + ndots = 4; + double l = 0; + position z = position(dim_x, 0); + int j = 0; + int jmax = int(10 / lt.dash_width); + for (int i = 1; i <= ndots; i++) { + position zold = z; + double lold = l; + double ld = i * le / ndots; + double dl = 1; + // find next position for fixed arc length + while (l < ld) { + j++; + lold = l; + zold = z; + double phi = j * 2 * M_PI / jmax; + z = position(dim_x * cos(phi), dim_y * sin(phi)); + dl = hypot(z - zold); + l += dl; + } + // interpolate linearly between the last two points, + // using the length difference as the scaling factor + double delta = (ld - lold) / dl; + position zdot = zold + (z - zold) * delta; + // compute angle of new position on the affine circle + // and use it to get the exact value on the ellipse + double psi = atan2(zdot.y / dim_y, zdot.x / dim_x); + zdot = position(dim_x * cos(psi), dim_y * sin(psi)); + dot(cent + zdot, slt); + } +} + +// return non-zero iff we can compute a center + +int compute_arc_center(const position &start, const position ¢, + const position &end, position *result) +{ + // This finds the point along the vector from start to cent that + // is equidistant between start and end. + distance c = cent - start; + distance e = end - start; + double n = c*e; + if (n == 0.0) + return 0; + *result = start + c*((e*e)/(2.0*n)); + return 1; +} + +// output a dashed arc as a series of arcs + +void common_output::dashed_arc(const position &start, const position ¢, + const position &end, const line_type <) +{ + assert(lt.type == line_type::dashed); + position c; + if (!compute_arc_center(start, cent, end, &c)) { + line(start, &end, 1, lt); + return; + } + distance start_offset = start - c; + distance end_offset = end - c; + double start_angle = atan2(start_offset.y, start_offset.x); + double end_angle = atan2(end_offset.y, end_offset.x); + double rad = hypot(c - start); + double dash_angle = lt.dash_width/rad; + double total_angle = end_angle - start_angle; + while (total_angle < 0) + total_angle += M_PI + M_PI; + if (total_angle <= dash_angle*2.0) { + solid_arc(cent, rad, start_angle, end_angle, lt); + return; + } + int ndashes = int((total_angle - dash_angle)/(dash_angle*2.0) + .5); + double dash_and_gap_angle = (total_angle - dash_angle)/ndashes; + for (int i = 0; i <= ndashes; i++) + solid_arc(cent, rad, start_angle + i*dash_and_gap_angle, + start_angle + i*dash_and_gap_angle + dash_angle, lt); +} + +// output a dotted arc as a series of dots + +void common_output::dotted_arc(const position &start, const position ¢, + const position &end, const line_type <) +{ + assert(lt.type == line_type::dotted); + position c; + if (!compute_arc_center(start, cent, end, &c)) { + line(start, &end, 1, lt); + return; + } + distance start_offset = start - c; + distance end_offset = end - c; + double start_angle = atan2(start_offset.y, start_offset.x); + double total_angle = atan2(end_offset.y, end_offset.x) - start_angle; + while (total_angle < 0) + total_angle += M_PI + M_PI; + double rad = hypot(c - start); + int ndots = int(total_angle/(lt.dash_width/rad) + .5); + if (ndots == 0) + dot(start, lt); + else { + for (int i = 0; i <= ndots; i++) { + double a = start_angle + (total_angle*i)/ndots; + dot(cent + position(cos(a), sin(a))*rad, lt); + } + } +} + +void common_output::solid_arc(const position ¢, double rad, + double start_angle, double end_angle, + const line_type <) +{ + line_type slt = lt; + slt.type = line_type::solid; + arc(cent + position(cos(start_angle), sin(start_angle))*rad, + cent, + cent + position(cos(end_angle), sin(end_angle))*rad, + slt); +} + + +void common_output::rounded_box(const position ¢, const distance &dim, + double rad, const line_type <, + double fill, char *color_fill) +{ + if (fill >= 0.0 || color_fill) + filled_rounded_box(cent, dim, rad, fill); + switch (lt.type) { + case line_type::invisible: + break; + case line_type::dashed: + dashed_rounded_box(cent, dim, rad, lt); + break; + case line_type::dotted: + dotted_rounded_box(cent, dim, rad, lt); + break; + case line_type::solid: + solid_rounded_box(cent, dim, rad, lt); + break; + default: + assert(0); + } +} + + +void common_output::dashed_rounded_box(const position ¢, + const distance &dim, double rad, + const line_type <) +{ + line_type slt = lt; + slt.type = line_type::solid; + + double hor_length = dim.x + (M_PI/2.0 - 2.0)*rad; + int n_hor_dashes = int(hor_length/(lt.dash_width*2.0) + .5); + double hor_gap_width = (n_hor_dashes != 0 + ? hor_length/n_hor_dashes - lt.dash_width + : 0.0); + + double vert_length = dim.y + (M_PI/2.0 - 2.0)*rad; + int n_vert_dashes = int(vert_length/(lt.dash_width*2.0) + .5); + double vert_gap_width = (n_vert_dashes != 0 + ? vert_length/n_vert_dashes - lt.dash_width + : 0.0); + // Note that each corner arc has to be split into two for dashing, + // because one part is dashed using vert_gap_width, and the other + // using hor_gap_width. + double offset = lt.dash_width/2.0; + dash_arc(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad, + -M_PI/4.0, 0, slt, lt.dash_width, vert_gap_width, &offset); + dash_line(cent + position(dim.x/2.0, -dim.y/2.0 + rad), + cent + position(dim.x/2.0, dim.y/2.0 - rad), + slt, lt.dash_width, vert_gap_width, &offset); + dash_arc(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad, + 0, M_PI/4.0, slt, lt.dash_width, vert_gap_width, &offset); + + offset = lt.dash_width/2.0; + dash_arc(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad, + M_PI/4.0, M_PI/2, slt, lt.dash_width, hor_gap_width, &offset); + dash_line(cent + position(dim.x/2.0 - rad, dim.y/2.0), + cent + position(-dim.x/2.0 + rad, dim.y/2.0), + slt, lt.dash_width, hor_gap_width, &offset); + dash_arc(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad, + M_PI/2, 3*M_PI/4.0, slt, lt.dash_width, hor_gap_width, &offset); + + offset = lt.dash_width/2.0; + dash_arc(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad, + 3.0*M_PI/4.0, M_PI, slt, lt.dash_width, vert_gap_width, &offset); + dash_line(cent + position(-dim.x/2.0, dim.y/2.0 - rad), + cent + position(-dim.x/2.0, -dim.y/2.0 + rad), + slt, lt.dash_width, vert_gap_width, &offset); + dash_arc(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad, + M_PI, 5.0*M_PI/4.0, slt, lt.dash_width, vert_gap_width, &offset); + + offset = lt.dash_width/2.0; + dash_arc(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad, + 5*M_PI/4.0, 3*M_PI/2.0, slt, lt.dash_width, hor_gap_width, &offset); + dash_line(cent + position(-dim.x/2.0 + rad, -dim.y/2.0), + cent + position(dim.x/2.0 - rad, -dim.y/2.0), + slt, lt.dash_width, hor_gap_width, &offset); + dash_arc(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad, + 3*M_PI/2, 7*M_PI/4, slt, lt.dash_width, hor_gap_width, &offset); +} + +// Used by dashed_rounded_box. + +void common_output::dash_arc(const position ¢, double rad, + double start_angle, double end_angle, + const line_type <, + double dash_width, double gap_width, + double *offsetp) +{ + double length = (end_angle - start_angle)*rad; + double pos = 0.0; + for (;;) { + if (*offsetp >= dash_width) { + double rem = dash_width + gap_width - *offsetp; + if (pos + rem > length) { + *offsetp += length - pos; + break; + } + else { + pos += rem; + *offsetp = 0.0; + } + } + else { + double rem = dash_width - *offsetp; + if (pos + rem > length) { + solid_arc(cent, rad, start_angle + pos/rad, end_angle, lt); + *offsetp += length - pos; + break; + } + else { + solid_arc(cent, rad, start_angle + pos/rad, + start_angle + (pos + rem)/rad, lt); + pos += rem; + *offsetp = dash_width; + } + } + } +} + +// Used by dashed_rounded_box. + +void common_output::dash_line(const position &start, const position &end, + const line_type <, + double dash_width, double gap_width, + double *offsetp) +{ + distance dist = end - start; + double length = hypot(dist); + if (length == 0.0) + return; + double pos = 0.0; + for (;;) { + if (*offsetp >= dash_width) { + double rem = dash_width + gap_width - *offsetp; + if (pos + rem > length) { + *offsetp += length - pos; + break; + } + else { + pos += rem; + *offsetp = 0.0; + } + } + else { + double rem = dash_width - *offsetp; + if (pos + rem > length) { + line(start + dist*(pos/length), &end, 1, lt); + *offsetp += length - pos; + break; + } + else { + position p(start + dist*((pos + rem)/length)); + line(start + dist*(pos/length), &p, 1, lt); + pos += rem; + *offsetp = dash_width; + } + } + } +} + +void common_output::dotted_rounded_box(const position ¢, + const distance &dim, double rad, + const line_type <) +{ + line_type slt = lt; + slt.type = line_type::solid; + + double hor_length = dim.x + (M_PI/2.0 - 2.0)*rad; + int n_hor_dots = int(hor_length/lt.dash_width + .5); + double hor_gap_width = (n_hor_dots != 0 + ? hor_length/n_hor_dots + : lt.dash_width); + + double vert_length = dim.y + (M_PI/2.0 - 2.0)*rad; + int n_vert_dots = int(vert_length/lt.dash_width + .5); + double vert_gap_width = (n_vert_dots != 0 + ? vert_length/n_vert_dots + : lt.dash_width); + double epsilon = lt.dash_width/(rad*100.0); + + double offset = 0.0; + dot_arc(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad, + -M_PI/4.0, 0, slt, vert_gap_width, &offset); + dot_line(cent + position(dim.x/2.0, -dim.y/2.0 + rad), + cent + position(dim.x/2.0, dim.y/2.0 - rad), + slt, vert_gap_width, &offset); + dot_arc(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad, + 0, M_PI/4.0 - epsilon, slt, vert_gap_width, &offset); + + offset = 0.0; + dot_arc(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad, + M_PI/4.0, M_PI/2, slt, hor_gap_width, &offset); + dot_line(cent + position(dim.x/2.0 - rad, dim.y/2.0), + cent + position(-dim.x/2.0 + rad, dim.y/2.0), + slt, hor_gap_width, &offset); + dot_arc(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad, + M_PI/2, 3*M_PI/4.0 - epsilon, slt, hor_gap_width, &offset); + + offset = 0.0; + dot_arc(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad, + 3.0*M_PI/4.0, M_PI, slt, vert_gap_width, &offset); + dot_line(cent + position(-dim.x/2.0, dim.y/2.0 - rad), + cent + position(-dim.x/2.0, -dim.y/2.0 + rad), + slt, vert_gap_width, &offset); + dot_arc(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad, + M_PI, 5.0*M_PI/4.0 - epsilon, slt, vert_gap_width, &offset); + + offset = 0.0; + dot_arc(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad, + 5*M_PI/4.0, 3*M_PI/2.0, slt, hor_gap_width, &offset); + dot_line(cent + position(-dim.x/2.0 + rad, -dim.y/2.0), + cent + position(dim.x/2.0 - rad, -dim.y/2.0), + slt, hor_gap_width, &offset); + dot_arc(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad, + 3*M_PI/2, 7*M_PI/4 - epsilon, slt, hor_gap_width, &offset); +} + +// Used by dotted_rounded_box. + +void common_output::dot_arc(const position ¢, double rad, + double start_angle, double end_angle, + const line_type <, double gap_width, + double *offsetp) +{ + double length = (end_angle - start_angle)*rad; + double pos = 0.0; + for (;;) { + if (*offsetp == 0.0) { + double ang = start_angle + pos/rad; + dot(cent + position(cos(ang), sin(ang))*rad, lt); + } + double rem = gap_width - *offsetp; + if (pos + rem > length) { + *offsetp += length - pos; + break; + } + else { + pos += rem; + *offsetp = 0.0; + } + } +} + +// Used by dotted_rounded_box. + +void common_output::dot_line(const position &start, const position &end, + const line_type <, double gap_width, + double *offsetp) +{ + distance dist = end - start; + double length = hypot(dist); + if (length == 0.0) + return; + double pos = 0.0; + for (;;) { + if (*offsetp == 0.0) + dot(start + dist*(pos/length), lt); + double rem = gap_width - *offsetp; + if (pos + rem > length) { + *offsetp += length - pos; + break; + } + else { + pos += rem; + *offsetp = 0.0; + } + } +} + +void common_output::solid_rounded_box(const position ¢, + const distance &dim, double rad, + const line_type <) +{ + position tem = cent - dim/2.0; + arc(tem + position(0.0, rad), + tem + position(rad, rad), + tem + position(rad, 0.0), + lt); + tem = cent + position(-dim.x/2.0, dim.y/2.0); + arc(tem + position(rad, 0.0), + tem + position(rad, -rad), + tem + position(0.0, -rad), + lt); + tem = cent + dim/2.0; + arc(tem + position(0.0, -rad), + tem + position(-rad, -rad), + tem + position(-rad, 0.0), + lt); + tem = cent + position(dim.x/2.0, -dim.y/2.0); + arc(tem + position(-rad, 0.0), + tem + position(-rad, rad), + tem + position(0.0, rad), + lt); + position end; + end = cent + position(-dim.x/2.0, dim.y/2.0 - rad); + line(cent - dim/2.0 + position(0.0, rad), &end, 1, lt); + end = cent + position(dim.x/2.0 - rad, dim.y/2.0); + line(cent + position(-dim.x/2.0 + rad, dim.y/2.0), &end, 1, lt); + end = cent + position(dim.x/2.0, -dim.y/2.0 + rad); + line(cent + position(dim.x/2.0, dim.y/2.0 - rad), &end, 1, lt); + end = cent + position(-dim.x/2.0 + rad, -dim.y/2.0); + line(cent + position(dim.x/2.0 - rad, -dim.y/2.0), &end, 1, lt); +} + +void common_output::filled_rounded_box(const position ¢, + const distance &dim, double rad, + double fill) +{ + line_type ilt; + ilt.type = line_type::invisible; + circle(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad, ilt, fill); + circle(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad, ilt, fill); + circle(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad, ilt, fill); + circle(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad, ilt, fill); + position vec[4]; + vec[0] = cent + position(dim.x/2.0, dim.y/2.0 - rad); + vec[1] = cent + position(-dim.x/2.0, dim.y/2.0 - rad); + vec[2] = cent + position(-dim.x/2.0, -dim.y/2.0 + rad); + vec[3] = cent + position(dim.x/2.0, -dim.y/2.0 + rad); + polygon(vec, 4, ilt, fill); + vec[0] = cent + position(dim.x/2.0 - rad, dim.y/2.0); + vec[1] = cent + position(-dim.x/2.0 + rad, dim.y/2.0); + vec[2] = cent + position(-dim.x/2.0 + rad, -dim.y/2.0); + vec[3] = cent + position(dim.x/2.0 - rad, -dim.y/2.0); + polygon(vec, 4, ilt, fill); +} diff --git a/src/preproc/pic/common.h b/src/preproc/pic/common.h new file mode 100644 index 0000000..a2d5f70 --- /dev/null +++ b/src/preproc/pic/common.h @@ -0,0 +1,79 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +class common_output : public output { +private: + void dash_line(const position &start, const position &end, + const line_type <, double dash_width, double gap_width, + double *offsetp); + void dash_arc(const position ¢, double rad, + double start_angle, double end_angle, const line_type <, + double dash_width, double gap_width, double *offsetp); + void dot_line(const position &start, const position &end, + const line_type <, double gap_width, double *offsetp); + void dot_arc(const position ¢, double rad, + double start_angle, double end_angle, const line_type <, + double gap_width, double *offsetp); +protected: + virtual void dot(const position &, const line_type &) = 0; + void ellipse_arc(const position &, const position &, + const position &, const distance &, + const line_type &); + void dashed_circle(const position &, double rad, const line_type &); + void dotted_circle(const position &, double rad, const line_type &); + void dashed_ellipse(const position &, const distance &, const line_type &); + void dotted_ellipse(const position &, const distance &, const line_type &); + void dashed_arc(const position &, const position &, const position &, + const line_type &); + void dotted_arc(const position &, const position &, const position &, + const line_type &); + virtual void solid_arc(const position ¢, double rad, double start_angle, + double end_angle, const line_type <); + void dashed_rounded_box(const position &, const distance &, double, + const line_type &); + void dotted_rounded_box(const position &, const distance &, double, + const line_type &); + void solid_rounded_box(const position &, const distance &, double, + const line_type &); + void filled_rounded_box(const position &, const distance &, double, + double); +public: + void start_picture(double sc, const position &ll, const position &ur) = 0; + void finish_picture() = 0; + void circle(const position &, double rad, const line_type &, double) = 0; + void text(const position &, text_piece *, int, double) = 0; + void line(const position &, const position *, int n, const line_type &) = 0; + void polygon(const position *, int n, const line_type &, double) = 0; + void spline(const position &, const position *, int n, + const line_type &) = 0; + void arc(const position &, const position &, const position &, + const line_type &) = 0; + void ellipse(const position &, const distance &, + const line_type &, double) = 0; + void rounded_box(const position &, const distance &, double, + const line_type &, double, char *); + void set_color(char *, char *) = 0; + void reset_color() = 0; + char *get_last_filled() = 0; + char *get_outline_color() = 0; +}; + +int compute_arc_center(const position &start, const position ¢, + const position &end, position *result); + diff --git a/src/preproc/pic/lex.cpp b/src/preproc/pic/lex.cpp new file mode 100644 index 0000000..e59801b --- /dev/null +++ b/src/preproc/pic/lex.cpp @@ -0,0 +1,2039 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "pic.h" +#include "ptable.h" +#include "object.h" +#include "pic.hpp" + +declare_ptable(char) +implement_ptable(char) + +PTABLE(char) macro_table; + +// First character of the range representing $1-$. +// All of them must be invalid input characters. +#ifndef IS_EBCDIC_HOST +#define ARG1 0x80 +#define MAX_ARG 32 +#else +#define ARG1 0x30 +#define MAX_ARG 16 +#endif + +class macro_input : public input { + char *s; + char *p; +public: + macro_input(const char *); + ~macro_input(); + int get(); + int peek(); +}; + +class argument_macro_input : public input { + char *s; + char *p; + char *ap; + int argc; + char *argv[MAX_ARG]; +public: + argument_macro_input(const char *, int, char **); + ~argument_macro_input(); + int get(); + int peek(); +}; + +input::input() : next(0) +{ +} + +input::~input() +{ +} + +int input::get_location(const char **, int *) +{ + return 0; +} + +file_input::file_input(FILE *f, const char *fn) +: fp(f), filename(fn), lineno(0), ptr("") +{ +} + +file_input::~file_input() +{ + fclose(fp); +} + +int file_input::read_line() +{ + for (;;) { + line.clear(); + lineno++; + for (;;) { + int c = getc(fp); + if (c == '\r') { + c = getc(fp); + if (c != '\n') + lex_error("invalid input character code %1", '\r'); + } + if (c == EOF) + break; + else if (is_invalid_input_char(c)) + lex_error("invalid input character code %1", c); + else { + line += char(c); + if (c == '\n') + break; + } + } + if (line.length() == 0) + return 0; + if (!(line.length() >= 3 && line[0] == '.' && line[1] == 'P' + && (line[2] == 'S' || line[2] == 'E' || line[2] == 'F') + && (line.length() == 3 || line[3] == ' ' || line[3] == '\n' + || compatible_flag))) { + line += '\0'; + ptr = line.contents(); + return 1; + } + } +} + +int file_input::get() +{ + if (*ptr != '\0' || read_line()) + return (unsigned char)*ptr++; + else + return EOF; +} + +int file_input::peek() +{ + if (*ptr != '\0' || read_line()) + return (unsigned char)*ptr; + else + return EOF; +} + +int file_input::get_location(const char **fnp, int *lnp) +{ + *fnp = filename; + *lnp = lineno; + return 1; +} + +macro_input::macro_input(const char *str) +{ + p = s = strsave(str); +} + +macro_input::~macro_input() +{ + free(s); +} + +int macro_input::get() +{ + if (p == 0 || *p == '\0') + return EOF; + else + return (unsigned char)*p++; +} + +int macro_input::peek() +{ + if (p == 0 || *p == '\0') + return EOF; + else + return (unsigned char)*p; +} + +char *process_body(const char *body) +{ + char *s = strsave(body); + int j = 0; + for (int i = 0; s[i] != '\0'; i++) + if (s[i] == '$' && csdigit(s[i + 1])) { + int n = 0; + int start = i; + i++; + while (csdigit(s[i])) + if (n > MAX_ARG) + i++; + else + n = 10 * n + s[i++] - '0'; + if (n > MAX_ARG) { + string arg; + for (int k = start; k < i; k++) + arg += s[k]; + lex_error("invalid macro argument number %1", arg.contents()); + } + else if (n > 0) + s[j++] = ARG1 + n - 1; + i--; + } + else + s[j++] = s[i]; + s[j] = '\0'; + return s; +} + +argument_macro_input::argument_macro_input(const char *body, int ac, char **av) +: ap(0), argc(ac) +{ + for (int i = 0; i < argc; i++) + argv[i] = av[i]; + p = s = process_body(body); +} + +argument_macro_input::~argument_macro_input() +{ + for (int i = 0; i < argc; i++) + free(argv[i]); + free(s); +} + +int argument_macro_input::get() +{ + if (ap) { + if (*ap != '\0') + return (unsigned char)*ap++; + ap = 0; + } + if (p == 0) + return EOF; + while ((unsigned char)*p >= ARG1 + && (unsigned char)*p <= ARG1 + MAX_ARG - 1) { + int i = (unsigned char)*p++ - ARG1; + if (i < argc && argv[i] != 0 && argv[i][0] != '\0') { + ap = argv[i]; + return (unsigned char)*ap++; + } + } + if (*p == '\0') + return EOF; + return (unsigned char)*p++; +} + +int argument_macro_input::peek() +{ + if (ap) { + if (*ap != '\0') + return (unsigned char)*ap; + ap = 0; + } + if (p == 0) + return EOF; + while ((unsigned char)*p >= ARG1 + && (unsigned char)*p <= ARG1 + MAX_ARG - 1) { + int i = (unsigned char)*p++ - ARG1; + if (i < argc && argv[i] != 0 && argv[i][0] != '\0') { + ap = argv[i]; + return (unsigned char)*ap; + } + } + if (*p == '\0') + return EOF; + return (unsigned char)*p; +} + +class input_stack { + static input *current_input; + static int bol_flag; +public: + static void push(input *); + static void clear(); + static int get_char(); + static int peek_char(); + static int get_location(const char **fnp, int *lnp); + static void push_back(unsigned char c, int was_bol = 0); + static int bol(); +}; + +input *input_stack::current_input = 0; +int input_stack::bol_flag = 0; + +inline int input_stack::bol() +{ + return bol_flag; +} + +void input_stack::clear() +{ + while (current_input != 0) { + input *tem = current_input; + current_input = current_input->next; + delete tem; + } + bol_flag = 1; +} + +void input_stack::push(input *in) +{ + in->next = current_input; + current_input = in; +} + +void lex_init(input *top) +{ + input_stack::clear(); + input_stack::push(top); +} + +void lex_cleanup() +{ + while (input_stack::get_char() != EOF) + ; +} + +int input_stack::get_char() +{ + while (current_input != 0) { + int c = current_input->get(); + if (c != EOF) { + bol_flag = c == '\n'; + return c; + } + // don't pop the top-level input off the stack + if (current_input->next == 0) + return EOF; + input *tem = current_input; + current_input = current_input->next; + delete tem; + } + return EOF; +} + +int input_stack::peek_char() +{ + while (current_input != 0) { + int c = current_input->peek(); + if (c != EOF) + return c; + if (current_input->next == 0) + return EOF; + input *tem = current_input; + current_input = current_input->next; + delete tem; + } + return EOF; +} + +class char_input : public input { + int c; +public: + char_input(int); + int get(); + int peek(); +}; + +char_input::char_input(int n) : c((unsigned char)n) +{ +} + +int char_input::get() +{ + int n = c; + c = EOF; + return n; +} + +int char_input::peek() +{ + return c; +} + +void input_stack::push_back(unsigned char c, int was_bol) +{ + push(new char_input(c)); + bol_flag = was_bol; +} + +int input_stack::get_location(const char **fnp, int *lnp) +{ + for (input *p = current_input; p; p = p->next) + if (p->get_location(fnp, lnp)) + return 1; + return 0; +} + +string context_buffer; + +string token_buffer; +double token_double; +int token_int; + +void interpolate_macro_with_args(const char *body) +{ + char *argv[MAX_ARG]; + int argc = 0; + int ignore = 0; + int i; + for (i = 0; i < MAX_ARG; i++) + argv[i] = 0; + int level = 0; + int c; + enum { NORMAL, IN_STRING, IN_STRING_QUOTED } state = NORMAL; + do { + token_buffer.clear(); + for (;;) { + c = input_stack::get_char(); + if (c == EOF) { + lex_error("end of input while scanning macro arguments"); + break; + } + if (state == NORMAL && level == 0 && (c == ',' || c == ')')) { + if (token_buffer.length() > 0) { + token_buffer += '\0'; + if (!ignore) { + if (argc == MAX_ARG) { + lex_warning("only %1 macro arguments supported", MAX_ARG); + ignore = 1; + } + else + argv[argc] = strsave(token_buffer.contents()); + } + } + // for 'foo()', argc = 0 + if (argc > 0 || c != ')' || i > 0) + if (!ignore) + argc++; + break; + } + token_buffer += char(c); + switch (state) { + case NORMAL: + if (c == '"') + state = IN_STRING; + else if (c == '(') + level++; + else if (c == ')') + level--; + break; + case IN_STRING: + if (c == '"') + state = NORMAL; + else if (c == '\\') + state = IN_STRING_QUOTED; + break; + case IN_STRING_QUOTED: + state = IN_STRING; + break; + } + } + } while (c != ')' && c != EOF); + input_stack::push(new argument_macro_input(body, argc, argv)); +} + +static int docmp(const char *s1, int n1, const char *s2, int n2) +{ + if (n1 < n2) { + int r = memcmp(s1, s2, n1); + return r ? r : -1; + } + else if (n1 > n2) { + int r = memcmp(s1, s2, n2); + return r ? r : 1; + } + else + return memcmp(s1, s2, n1); +} + +int lookup_keyword(const char *str, int len) +{ + static struct keyword { + const char *name; + int token; + } table[] = { + { "Here", HERE }, + { "above", ABOVE }, + { "aligned", ALIGNED }, + { "and", AND }, + { "arc", ARC }, + { "arrow", ARROW }, + { "at", AT }, + { "atan2", ATAN2 }, + { "below", BELOW }, + { "between", BETWEEN }, + { "bottom", BOTTOM }, + { "box", BOX }, + { "by", BY }, + { "ccw", CCW }, + { "center", CENTER }, + { "chop", CHOP }, + { "circle", CIRCLE }, + { "color", COLORED }, + { "colored", COLORED }, + { "colour", COLORED }, + { "coloured", COLORED }, + { "command", COMMAND }, + { "copy", COPY }, + { "cos", COS }, + { "cw", CW }, + { "dashed", DASHED }, + { "define", DEFINE }, + { "diam", DIAMETER }, + { "diameter", DIAMETER }, + { "do", DO }, + { "dotted", DOTTED }, + { "down", DOWN }, + { "east", EAST }, + { "ellipse", ELLIPSE }, + { "else", ELSE }, + { "end", END }, + { "exp", EXP }, + { "figname", FIGNAME }, + { "fill", FILL }, + { "filled", FILL }, + { "for", FOR }, + { "from", FROM }, + { "height", HEIGHT }, + { "ht", HEIGHT }, + { "if", IF }, + { "int", INT }, + { "invis", INVISIBLE }, + { "invisible", INVISIBLE }, + { "last", LAST }, + { "left", LEFT }, + { "line", LINE }, + { "ljust", LJUST }, + { "log", LOG }, + { "lower", LOWER }, + { "max", K_MAX }, + { "min", K_MIN }, + { "move", MOVE }, + { "north", NORTH }, + { "of", OF }, + { "outline", OUTLINED }, + { "outlined", OUTLINED }, + { "plot", PLOT }, + { "print", PRINT }, + { "rad", RADIUS }, + { "radius", RADIUS }, + { "rand", RAND }, + { "reset", RESET }, + { "right", RIGHT }, + { "rjust", RJUST }, + { "same", SAME }, + { "sh", SH }, + { "shaded", SHADED }, + { "sin", SIN }, + { "solid", SOLID }, + { "south", SOUTH }, + { "spline", SPLINE }, + { "sprintf", SPRINTF }, + { "sqrt", SQRT }, + { "srand", SRAND }, + { "start", START }, + { "the", THE }, + { "then", THEN }, + { "thick", THICKNESS }, + { "thickness", THICKNESS }, + { "thru", THRU }, + { "to", TO }, + { "top", TOP }, + { "undef", UNDEF }, + { "until", UNTIL }, + { "up", UP }, + { "upper", UPPER }, + { "way", WAY }, + { "west", WEST }, + { "wid", WIDTH }, + { "width", WIDTH }, + { "with", WITH }, + { "xslanted", XSLANTED }, + { "yslanted", YSLANTED }, + }; + + const keyword *start = table; + const keyword *end = table + sizeof(table)/sizeof(table[0]); + while (start < end) { + // start <= target < end + const keyword *mid = start + (end - start)/2; + + int cmp = docmp(str, len, mid->name, strlen(mid->name)); + if (cmp == 0) + return mid->token; + if (cmp < 0) + end = mid; + else + start = mid + 1; + } + return 0; +} + +int get_token_after_dot(int c) +{ + // get_token deals with the case where c is a digit + switch (c) { + case 'h': + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 't') { + input_stack::get_char(); + context_buffer = ".ht"; + return DOT_HT; + } + else if (c == 'e') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'i') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'g') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'h') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 't') { + input_stack::get_char(); + context_buffer = ".height"; + return DOT_HT; + } + input_stack::push_back('h'); + } + input_stack::push_back('g'); + } + input_stack::push_back('i'); + } + input_stack::push_back('e'); + } + input_stack::push_back('h'); + return '.'; + case 'x': + input_stack::get_char(); + context_buffer = ".x"; + return DOT_X; + case 'y': + input_stack::get_char(); + context_buffer = ".y"; + return DOT_Y; + case 'c': + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'e') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'n') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 't') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'e') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'r') { + input_stack::get_char(); + context_buffer = ".center"; + return DOT_C; + } + input_stack::push_back('e'); + } + input_stack::push_back('t'); + } + input_stack::push_back('n'); + } + input_stack::push_back('e'); + } + context_buffer = ".c"; + return DOT_C; + case 'n': + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'e') { + input_stack::get_char(); + context_buffer = ".ne"; + return DOT_NE; + } + else if (c == 'w') { + input_stack::get_char(); + context_buffer = ".nw"; + return DOT_NW; + } + else { + context_buffer = ".n"; + return DOT_N; + } + break; + case 'e': + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'n') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'd') { + input_stack::get_char(); + context_buffer = ".end"; + return DOT_END; + } + input_stack::push_back('n'); + context_buffer = ".e"; + return DOT_E; + } + context_buffer = ".e"; + return DOT_E; + case 'w': + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'i') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'd') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 't') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'h') { + input_stack::get_char(); + context_buffer = ".width"; + return DOT_WID; + } + input_stack::push_back('t'); + } + context_buffer = ".wid"; + return DOT_WID; + } + input_stack::push_back('i'); + } + context_buffer = ".w"; + return DOT_W; + case 's': + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'e') { + input_stack::get_char(); + context_buffer = ".se"; + return DOT_SE; + } + else if (c == 'w') { + input_stack::get_char(); + context_buffer = ".sw"; + return DOT_SW; + } + else { + if (c == 't') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'a') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'r') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 't') { + input_stack::get_char(); + context_buffer = ".start"; + return DOT_START; + } + input_stack::push_back('r'); + } + input_stack::push_back('a'); + } + input_stack::push_back('t'); + } + context_buffer = ".s"; + return DOT_S; + } + break; + case 't': + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'o') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'p') { + input_stack::get_char(); + context_buffer = ".top"; + return DOT_N; + } + input_stack::push_back('o'); + } + context_buffer = ".t"; + return DOT_N; + case 'l': + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'e') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'f') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 't') { + input_stack::get_char(); + context_buffer = ".left"; + return DOT_W; + } + input_stack::push_back('f'); + } + input_stack::push_back('e'); + } + context_buffer = ".l"; + return DOT_W; + case 'r': + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'a') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'd') { + input_stack::get_char(); + context_buffer = ".rad"; + return DOT_RAD; + } + input_stack::push_back('a'); + } + else if (c == 'i') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'g') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'h') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 't') { + input_stack::get_char(); + context_buffer = ".right"; + return DOT_E; + } + input_stack::push_back('h'); + } + input_stack::push_back('g'); + } + input_stack::push_back('i'); + } + context_buffer = ".r"; + return DOT_E; + case 'b': + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'o') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 't') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 't') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'o') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'm') { + input_stack::get_char(); + context_buffer = ".bottom"; + return DOT_S; + } + input_stack::push_back('o'); + } + input_stack::push_back('t'); + } + context_buffer = ".bot"; + return DOT_S; + } + input_stack::push_back('o'); + } + context_buffer = ".b"; + return DOT_S; + default: + context_buffer = '.'; + return '.'; + } +} + +int get_token(int lookup_flag) +{ + context_buffer.clear(); + for (;;) { + int n = 0; + int bol = input_stack::bol(); + int c = input_stack::get_char(); + if (bol && c == command_char) { + token_buffer.clear(); + token_buffer += c; + // the newline is not part of the token + for (;;) { + c = input_stack::peek_char(); + if (c == EOF || c == '\n') + break; + input_stack::get_char(); + token_buffer += char(c); + } + context_buffer = token_buffer; + return COMMAND_LINE; + } + switch (c) { + case EOF: + return EOF; + case ' ': + case '\t': + break; + case '\\': + { + int d = input_stack::peek_char(); + if (d != '\n') { + context_buffer = '\\'; + return '\\'; + } + input_stack::get_char(); + break; + } + case '#': + do { + c = input_stack::get_char(); + } while (c != '\n' && c != EOF); + if (c == '\n') + context_buffer = '\n'; + return c; + case '"': + context_buffer = '"'; + token_buffer.clear(); + for (;;) { + c = input_stack::get_char(); + if (c == '\\') { + context_buffer += '\\'; + c = input_stack::peek_char(); + if (c == '"') { + input_stack::get_char(); + token_buffer += '"'; + context_buffer += '"'; + } + else + token_buffer += '\\'; + } + else if (c == '\n') { + error("newline in string"); + break; + } + else if (c == EOF) { + error("missing '\"'"); + break; + } + else if (c == '"') { + context_buffer += '"'; + break; + } + else { + context_buffer += char(c); + token_buffer += char(c); + } + } + return TEXT; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + int overflow = 0; + n = 0; + for (;;) { + if (n > (INT_MAX - 9)/10) { + overflow = 1; + break; + } + n *= 10; + n += c - '0'; + context_buffer += char(c); + c = input_stack::peek_char(); + if (c == EOF || !csdigit(c)) + break; + c = input_stack::get_char(); + } + token_double = n; + if (overflow) { + for (;;) { + token_double *= 10.0; + token_double += c - '0'; + context_buffer += char(c); + c = input_stack::peek_char(); + if (c == EOF || !csdigit(c)) + break; + c = input_stack::get_char(); + } + // if somebody asks for 1000000000000th, we will silently + // give them INT_MAXth + double temp = token_double; // work around gas 1.34/sparc bug + if (token_double > INT_MAX) + n = INT_MAX; + else + n = int(temp); + } + } + switch (c) { + case 'i': + case 'I': + context_buffer += char(c); + input_stack::get_char(); + return NUMBER; + case '.': + { + context_buffer += '.'; + input_stack::get_char(); + got_dot: + double factor = 1.0; + for (;;) { + c = input_stack::peek_char(); + if (c == EOF || !csdigit(c)) + break; + input_stack::get_char(); + context_buffer += char(c); + factor /= 10.0; + if (c != '0') + token_double += factor*(c - '0'); + } + if (c != 'e' && c != 'E') { + if (c == 'i' || c == 'I') { + context_buffer += char(c); + input_stack::get_char(); + } + return NUMBER; + } + } + // fall through + case 'e': + case 'E': + { + int echar = c; + input_stack::get_char(); + c = input_stack::peek_char(); + int sign = '+'; + if (c == '+' || c == '-') { + sign = c; + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == EOF || !csdigit(c)) { + input_stack::push_back(sign); + input_stack::push_back(echar); + return NUMBER; + } + context_buffer += char(echar); + context_buffer += char(sign); + } + else { + if (c == EOF || !csdigit(c)) { + input_stack::push_back(echar); + return NUMBER; + } + context_buffer += char(echar); + } + input_stack::get_char(); + context_buffer += char(c); + n = c - '0'; + for (;;) { + c = input_stack::peek_char(); + if (c == EOF || !csdigit(c)) + break; + input_stack::get_char(); + context_buffer += char(c); + n = n*10 + (c - '0'); + } + if (sign == '-') + n = -n; + if (c == 'i' || c == 'I') { + context_buffer += char(c); + input_stack::get_char(); + } + token_double *= pow(10.0, n); + return NUMBER; + } + case 'n': + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'd') { + input_stack::get_char(); + token_int = n; + context_buffer += "nd"; + return ORDINAL; + } + input_stack::push_back('n'); + return NUMBER; + case 'r': + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'd') { + input_stack::get_char(); + token_int = n; + context_buffer += "rd"; + return ORDINAL; + } + input_stack::push_back('r'); + return NUMBER; + case 't': + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'h') { + input_stack::get_char(); + token_int = n; + context_buffer += "th"; + return ORDINAL; + } + input_stack::push_back('t'); + return NUMBER; + case 's': + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 't') { + input_stack::get_char(); + token_int = n; + context_buffer += "st"; + return ORDINAL; + } + input_stack::push_back('s'); + return NUMBER; + default: + return NUMBER; + } + break; + case '\'': + { + c = input_stack::peek_char(); + if (c == 't') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == 'h') { + input_stack::get_char(); + context_buffer = "'th"; + return TH; + } + else + input_stack::push_back('t'); + } + context_buffer = "'"; + return '\''; + } + case '.': + { + c = input_stack::peek_char(); + if (c != EOF && csdigit(c)) { + n = 0; + token_double = 0.0; + context_buffer = '.'; + goto got_dot; + } + return get_token_after_dot(c); + } + case '<': + c = input_stack::peek_char(); + if (c == '-') { + input_stack::get_char(); + c = input_stack::peek_char(); + if (c == '>') { + input_stack::get_char(); + context_buffer = "<->"; + return DOUBLE_ARROW_HEAD; + } + context_buffer = "<-"; + return LEFT_ARROW_HEAD; + } + else if (c == '=') { + input_stack::get_char(); + context_buffer = "<="; + return LESSEQUAL; + } + context_buffer = "<"; + return '<'; + case '-': + c = input_stack::peek_char(); + if (c == '>') { + input_stack::get_char(); + context_buffer = "->"; + return RIGHT_ARROW_HEAD; + } + context_buffer = "-"; + return '-'; + case '!': + c = input_stack::peek_char(); + if (c == '=') { + input_stack::get_char(); + context_buffer = "!="; + return NOTEQUAL; + } + context_buffer = "!"; + return '!'; + case '>': + c = input_stack::peek_char(); + if (c == '=') { + input_stack::get_char(); + context_buffer = ">="; + return GREATEREQUAL; + } + context_buffer = ">"; + return '>'; + case '=': + c = input_stack::peek_char(); + if (c == '=') { + input_stack::get_char(); + context_buffer = "=="; + return EQUALEQUAL; + } + context_buffer = "="; + return '='; + case '&': + c = input_stack::peek_char(); + if (c == '&') { + input_stack::get_char(); + context_buffer = "&&"; + return ANDAND; + } + context_buffer = "&"; + return '&'; + case '|': + c = input_stack::peek_char(); + if (c == '|') { + input_stack::get_char(); + context_buffer = "||"; + return OROR; + } + context_buffer = "|"; + return '|'; + default: + if (c != EOF && csalpha(c)) { + token_buffer.clear(); + token_buffer = c; + for (;;) { + c = input_stack::peek_char(); + if (c == EOF || (!csalnum(c) && c != '_')) + break; + input_stack::get_char(); + token_buffer += char(c); + } + int tok = lookup_keyword(token_buffer.contents(), + token_buffer.length()); + if (tok != 0) { + context_buffer = token_buffer; + return tok; + } + char *def = 0; + if (lookup_flag) { + token_buffer += '\0'; + def = macro_table.lookup(token_buffer.contents()); + token_buffer.set_length(token_buffer.length() - 1); + if (def) { + if (c == '(') { + input_stack::get_char(); + interpolate_macro_with_args(def); + } + else + input_stack::push(new macro_input(def)); + } + } + if (!def) { + context_buffer = token_buffer; + if (csupper(token_buffer[0])) + return LABEL; + else + return VARIABLE; + } + } + else { + context_buffer = char(c); + return (unsigned char)c; + } + break; + } + } +} + +int get_delimited() +{ + token_buffer.clear(); + int c = input_stack::get_char(); + while (c == ' ' || c == '\t' || c == '\n') + c = input_stack::get_char(); + if (c == EOF) { + lex_error("missing delimiter"); + return 0; + } + context_buffer = char(c); + int had_newline = 0; + int start = c; + int level = 0; + enum { NORMAL, IN_STRING, IN_STRING_QUOTED, DELIM_END } state = NORMAL; + for (;;) { + c = input_stack::get_char(); + if (c == EOF) { + lex_error("missing closing delimiter"); + return 0; + } + if (c == '\n') + had_newline = 1; + else if (!had_newline) + context_buffer += char(c); + switch (state) { + case NORMAL: + if (start == '{') { + if (c == '{') { + level++; + break; + } + if (c == '}') { + if (--level < 0) + state = DELIM_END; + break; + } + } + else { + if (c == start) { + state = DELIM_END; + break; + } + } + if (c == '"') + state = IN_STRING; + break; + case IN_STRING_QUOTED: + if (c == '\n') + state = NORMAL; + else + state = IN_STRING; + break; + case IN_STRING: + if (c == '"' || c == '\n') + state = NORMAL; + else if (c == '\\') + state = IN_STRING_QUOTED; + break; + case DELIM_END: + // This case it just to shut cfront 2.0 up. + default: + assert(0); + } + if (state == DELIM_END) + break; + token_buffer += c; + } + return 1; +} + +void do_define() +{ + int t = get_token(0); // do not expand what we are defining + if (t != VARIABLE && t != LABEL) { + lex_error("can only define variable or placename"); + return; + } + token_buffer += '\0'; + string nm = token_buffer; + const char *name = nm.contents(); + if (!get_delimited()) + return; + token_buffer += '\0'; + macro_table.define(name, strsave(token_buffer.contents())); +} + +void do_undef() +{ + int t = get_token(0); // do not expand what we are undefining + if (t != VARIABLE && t != LABEL) { + lex_error("can only define variable or placename"); + return; + } + token_buffer += '\0'; + macro_table.define(token_buffer.contents(), 0); +} + + +class for_input : public input { + char *var; + char *body; + double from; + double to; + int by_is_multiplicative; + double by; + const char *p; + int done_newline; +public: + for_input(char *, double, double, int, double, char *); + ~for_input(); + int get(); + int peek(); +}; + +for_input::for_input(char *vr, double f, double t, + int bim, double b, char *bd) +: var(vr), body(bd), from(f), to(t), by_is_multiplicative(bim), by(b), + p(body), done_newline(0) +{ +} + +for_input::~for_input() +{ + free(var); + free(body); +} + +int for_input::get() +{ + if (p == 0) + return EOF; + for (;;) { + if (*p != '\0') + return (unsigned char)*p++; + if (!done_newline) { + done_newline = 1; + return '\n'; + } + double val; + if (!lookup_variable(var, &val)) { + lex_error("body of 'for' terminated enclosing block"); + return EOF; + } + if (by_is_multiplicative) + val *= by; + else + val += by; + define_variable(var, val); + if ((from <= to && val > to) + || (from >= to && val < to)) { + p = 0; + return EOF; + } + p = body; + done_newline = 0; + } +} + +int for_input::peek() +{ + if (p == 0) + return EOF; + if (*p != '\0') + return (unsigned char)*p; + if (!done_newline) + return '\n'; + double val; + if (!lookup_variable(var, &val)) + return EOF; + if (by_is_multiplicative) { + if (val * by > to) + return EOF; + } + else { + if ((from <= to && val + by > to) + || (from >= to && val + by < to)) + return EOF; + } + if (*body == '\0') + return EOF; + return (unsigned char)*body; +} + +void do_for(char *var, double from, double to, int by_is_multiplicative, + double by, char *body) +{ + define_variable(var, from); + if ((by_is_multiplicative && by <= 0) + || (by > 0 && from > to) + || (by < 0 && from < to)) + return; + input_stack::push(new for_input(var, from, to, + by_is_multiplicative, by, body)); +} + + +void do_copy(const char *filename) +{ + errno = 0; + FILE *fp = fopen(filename, "r"); + if (fp == 0) { + lex_error("can't open '%1': %2", filename, strerror(errno)); + return; + } + input_stack::push(new file_input(fp, filename)); +} + +class copy_thru_input : public input { + int done; + char *body; + char *until; + const char *p; + const char *ap; + int argv[MAX_ARG]; + int argc; + string line; + int get_line(); + virtual int inget() = 0; +public: + copy_thru_input(const char *b, const char *u); + ~copy_thru_input(); + int get(); + int peek(); +}; + +class copy_file_thru_input : public copy_thru_input { + input *in; +public: + copy_file_thru_input(input *, const char *b, const char *u); + ~copy_file_thru_input(); + int inget(); +}; + +copy_file_thru_input::copy_file_thru_input(input *i, const char *b, + const char *u) +: copy_thru_input(b, u), in(i) +{ +} + +copy_file_thru_input::~copy_file_thru_input() +{ + delete in; +} + +int copy_file_thru_input::inget() +{ + if (!in) + return EOF; + else + return in->get(); +} + +class copy_rest_thru_input : public copy_thru_input { +public: + copy_rest_thru_input(const char *, const char *u); + int inget(); +}; + +copy_rest_thru_input::copy_rest_thru_input(const char *b, const char *u) +: copy_thru_input(b, u) +{ +} + +int copy_rest_thru_input::inget() +{ + while (next != 0) { + int c = next->get(); + if (c != EOF) + return c; + if (next->next == 0) + return EOF; + input *tem = next; + next = next->next; + delete tem; + } + return EOF; + +} + +copy_thru_input::copy_thru_input(const char *b, const char *u) +: done(0) +{ + ap = 0; + body = process_body(b); + p = 0; + until = strsave(u); +} + + +copy_thru_input::~copy_thru_input() +{ + delete[] body; + delete[] until; +} + +int copy_thru_input::get() +{ + if (ap) { + if (*ap != '\0') + return (unsigned char)*ap++; + ap = 0; + } + for (;;) { + if (p == 0) { + if (!get_line()) + break; + p = body; + } + if (*p == '\0') { + p = 0; + return '\n'; + } + while ((unsigned char)*p >= ARG1 + && (unsigned char)*p <= ARG1 + MAX_ARG - 1) { + int i = (unsigned char)*p++ - ARG1; + if (i < argc && line[argv[i]] != '\0') { + ap = line.contents() + argv[i]; + return (unsigned char)*ap++; + } + } + if (*p != '\0') + return (unsigned char)*p++; + } + return EOF; +} + +int copy_thru_input::peek() +{ + if (ap) { + if (*ap != '\0') + return (unsigned char)*ap; + ap = 0; + } + for (;;) { + if (p == 0) { + if (!get_line()) + break; + p = body; + } + if (*p == '\0') + return '\n'; + while ((unsigned char)*p >= ARG1 + && (unsigned char)*p <= ARG1 + MAX_ARG - 1) { + int i = (unsigned char)*p++ - ARG1; + if (i < argc && line[argv[i]] != '\0') { + ap = line.contents() + argv[i]; + return (unsigned char)*ap; + } + } + if (*p != '\0') + return (unsigned char)*p; + } + return EOF; +} + +int copy_thru_input::get_line() +{ + if (done) + return 0; + line.clear(); + argc = 0; + int c = inget(); + for (;;) { + while (c == ' ') + c = inget(); + if (c == EOF || c == '\n') + break; + if (argc == MAX_ARG) { + do { + c = inget(); + } while (c != '\n' && c != EOF); + break; + } + argv[argc++] = line.length(); + do { + line += char(c); + c = inget(); + } while (c != ' ' && c != '\n'); + line += '\0'; + } + if (until != 0 && argc > 0 && strcmp(&line[argv[0]], until) == 0) { + done = 1; + return 0; + } + return argc > 0 || c == '\n'; +} + +class simple_file_input : public input { + const char *filename; + int lineno; + FILE *fp; +public: + simple_file_input(FILE *, const char *); + ~simple_file_input(); + int get(); + int peek(); + int get_location(const char **, int *); +}; + +simple_file_input::simple_file_input(FILE *p, const char *s) +: filename(s), lineno(1), fp(p) +{ +} + +simple_file_input::~simple_file_input() +{ + // don't delete the filename + fclose(fp); +} + +int simple_file_input::get() +{ + int c = getc(fp); + while (is_invalid_input_char(c)) { + error("invalid input character code %1", c); + c = getc(fp); + } + if (c == '\n') + lineno++; + return c; +} + +int simple_file_input::peek() +{ + int c = getc(fp); + while (is_invalid_input_char(c)) { + error("invalid input character code %1", c); + c = getc(fp); + } + if (c != EOF) + ungetc(c, fp); + return c; +} + +int simple_file_input::get_location(const char **fnp, int *lnp) +{ + *fnp = filename; + *lnp = lineno; + return 1; +} + + +void copy_file_thru(const char *filename, const char *body, const char *until) +{ + errno = 0; + FILE *fp = fopen(filename, "r"); + if (fp == 0) { + lex_error("can't open '%1': %2", filename, strerror(errno)); + return; + } + input *in = new copy_file_thru_input(new simple_file_input(fp, filename), + body, until); + input_stack::push(in); +} + +void copy_rest_thru(const char *body, const char *until) +{ + input_stack::push(new copy_rest_thru_input(body, until)); +} + +void push_body(const char *s) +{ + input_stack::push(new char_input('\n')); + input_stack::push(new macro_input(s)); +} + +int delim_flag = 0; + +char *get_thru_arg() +{ + int c = input_stack::peek_char(); + while (c == ' ') { + input_stack::get_char(); + c = input_stack::peek_char(); + } + if (c != EOF && csalpha(c)) { + // looks like a macro + input_stack::get_char(); + token_buffer = c; + for (;;) { + c = input_stack::peek_char(); + if (c == EOF || (!csalnum(c) && c != '_')) + break; + input_stack::get_char(); + token_buffer += char(c); + } + context_buffer = token_buffer; + token_buffer += '\0'; + char *def = macro_table.lookup(token_buffer.contents()); + if (def) + return strsave(def); + // I guess it wasn't a macro after all; so push the macro name back. + // -2 because we added a '\0' + for (int i = token_buffer.length() - 2; i >= 0; i--) + input_stack::push_back(token_buffer[i]); + } + if (get_delimited()) { + token_buffer += '\0'; + return strsave(token_buffer.contents()); + } + else + return 0; +} + +int lookahead_token = -1; +string old_context_buffer; + +void do_lookahead() +{ + if (lookahead_token == -1) { + old_context_buffer = context_buffer; + lookahead_token = get_token(1); + } +} + +int yylex() +{ + if (delim_flag) { + assert(lookahead_token == -1); + if (delim_flag == 2) { + if ((yylval.str = get_thru_arg()) != 0) + return DELIMITED; + else + return 0; + } + else { + if (get_delimited()) { + token_buffer += '\0'; + yylval.str = strsave(token_buffer.contents()); + return DELIMITED; + } + else + return 0; + } + } + for (;;) { + int t; + if (lookahead_token >= 0) { + t = lookahead_token; + lookahead_token = -1; + } + else + t = get_token(1); + switch (t) { + case '\n': + return ';'; + case EOF: + return 0; + case DEFINE: + do_define(); + break; + case UNDEF: + do_undef(); + break; + case ORDINAL: + yylval.n = token_int; + return t; + case NUMBER: + yylval.x = token_double; + return t; + case COMMAND_LINE: + case TEXT: + token_buffer += '\0'; + if (!input_stack::get_location(&yylval.lstr.filename, + &yylval.lstr.lineno)) { + yylval.lstr.filename = 0; + yylval.lstr.lineno = -1; + } + yylval.lstr.str = strsave(token_buffer.contents()); + return t; + case LABEL: + case VARIABLE: + token_buffer += '\0'; + yylval.str = strsave(token_buffer.contents()); + return t; + case LEFT: + // change LEFT to LEFT_CORNER when followed by OF + old_context_buffer = context_buffer; + lookahead_token = get_token(1); + if (lookahead_token == OF) + return LEFT_CORNER; + else + return t; + case RIGHT: + // change RIGHT to RIGHT_CORNER when followed by OF + old_context_buffer = context_buffer; + lookahead_token = get_token(1); + if (lookahead_token == OF) + return RIGHT_CORNER; + else + return t; + case UPPER: + // recognise UPPER only before LEFT or RIGHT + old_context_buffer = context_buffer; + lookahead_token = get_token(1); + if (lookahead_token != LEFT && lookahead_token != RIGHT) { + yylval.str = strsave("upper"); + return VARIABLE; + } + else + return t; + case LOWER: + // recognise LOWER only before LEFT or RIGHT + old_context_buffer = context_buffer; + lookahead_token = get_token(1); + if (lookahead_token != LEFT && lookahead_token != RIGHT) { + yylval.str = strsave("lower"); + return VARIABLE; + } + else + return t; + case NORTH: + // recognise NORTH only before OF + old_context_buffer = context_buffer; + lookahead_token = get_token(1); + if (lookahead_token != OF) { + yylval.str = strsave("north"); + return VARIABLE; + } + else + return t; + case SOUTH: + // recognise SOUTH only before OF + old_context_buffer = context_buffer; + lookahead_token = get_token(1); + if (lookahead_token != OF) { + yylval.str = strsave("south"); + return VARIABLE; + } + else + return t; + case EAST: + // recognise EAST only before OF + old_context_buffer = context_buffer; + lookahead_token = get_token(1); + if (lookahead_token != OF) { + yylval.str = strsave("east"); + return VARIABLE; + } + else + return t; + case WEST: + // recognise WEST only before OF + old_context_buffer = context_buffer; + lookahead_token = get_token(1); + if (lookahead_token != OF) { + yylval.str = strsave("west"); + return VARIABLE; + } + else + return t; + case TOP: + // recognise TOP only before OF + old_context_buffer = context_buffer; + lookahead_token = get_token(1); + if (lookahead_token != OF) { + yylval.str = strsave("top"); + return VARIABLE; + } + else + return t; + case BOTTOM: + // recognise BOTTOM only before OF + old_context_buffer = context_buffer; + lookahead_token = get_token(1); + if (lookahead_token != OF) { + yylval.str = strsave("bottom"); + return VARIABLE; + } + else + return t; + case CENTER: + // recognise CENTER only before OF + old_context_buffer = context_buffer; + lookahead_token = get_token(1); + if (lookahead_token != OF) { + yylval.str = strsave("center"); + return VARIABLE; + } + else + return t; + case START: + // recognise START only before OF + old_context_buffer = context_buffer; + lookahead_token = get_token(1); + if (lookahead_token != OF) { + yylval.str = strsave("start"); + return VARIABLE; + } + else + return t; + case END: + // recognise END only before OF + old_context_buffer = context_buffer; + lookahead_token = get_token(1); + if (lookahead_token != OF) { + yylval.str = strsave("end"); + return VARIABLE; + } + else + return t; + default: + return t; + } + } +} + +void lex_error(const char *message, + const errarg &arg1, + const errarg &arg2, + const errarg &arg3) +{ + const char *filename; + int lineno; + if (!input_stack::get_location(&filename, &lineno)) + error(message, arg1, arg2, arg3); + else + error_with_file_and_line(filename, lineno, message, arg1, arg2, arg3); +} + +void lex_warning(const char *message, + const errarg &arg1, + const errarg &arg2, + const errarg &arg3) +{ + const char *filename; + int lineno; + if (!input_stack::get_location(&filename, &lineno)) + warning(message, arg1, arg2, arg3); + else + warning_with_file_and_line(filename, lineno, message, arg1, arg2, arg3); +} + +void yyerror(const char *s) +{ + const char *filename; + int lineno; + const char *context = 0; + if (lookahead_token == -1) { + if (context_buffer.length() > 0) { + context_buffer += '\0'; + context = context_buffer.contents(); + } + } + else { + if (old_context_buffer.length() > 0) { + old_context_buffer += '\0'; + context = old_context_buffer.contents(); + } + } + if (!input_stack::get_location(&filename, &lineno)) { + if (context) { + if (context[0] == '\n' && context[1] == '\0') + error("%1 before newline", s); + else + error("%1 before '%2'", s, context); + } + else + error("%1 at end of picture", s); + } + else { + if (context) { + if (context[0] == '\n' && context[1] == '\0') + error_with_file_and_line(filename, lineno, "%1 before newline", s); + else + error_with_file_and_line(filename, lineno, "%1 before '%2'", + s, context); + } + else + error_with_file_and_line(filename, lineno, "%1 at end of picture", s); + } +} + diff --git a/src/preproc/pic/main.cpp b/src/preproc/pic/main.cpp new file mode 100644 index 0000000..f7e194f --- /dev/null +++ b/src/preproc/pic/main.cpp @@ -0,0 +1,664 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "pic.h" + +extern int yyparse(); +extern "C" const char *Version_string; + +output *out; +char *graphname; // the picture box name in TeX mode + +bool want_flyback = false; +// groff pic supports '.PY' to work around mm package stepping on 'PF'. +bool want_alternate_flyback = false; +int zero_length_line_flag = 0; +// Non-zero means we're using a groff driver. +int driver_extension_flag = 1; +int compatible_flag = 0; +int safer_flag = 1; +int command_char = '.'; // the character that introduces lines + // that should be passed through transparently +static int lf_flag = 1; // non-zero if we should attempt to understand + // lines beginning with '.lf' + +// Non-zero means a parse error was encountered. +static int had_parse_error = 0; + +void do_file(const char *filename); + +class top_input : public input { + FILE *fp; + int bol; + int eof; + int push_back[3]; + int start_lineno; +public: + top_input(FILE *); + int get(); + int peek(); + int get_location(const char **, int *); +}; + +top_input::top_input(FILE *p) : fp(p), bol(1), eof(0) +{ + push_back[0] = push_back[1] = push_back[2] = EOF; + start_lineno = current_lineno; +} + +int top_input::get() +{ + if (eof) + return EOF; + if (push_back[2] != EOF) { + int c = push_back[2]; + push_back[2] = EOF; + return c; + } + else if (push_back[1] != EOF) { + int c = push_back[1]; + push_back[1] = EOF; + return c; + } + else if (push_back[0] != EOF) { + int c = push_back[0]; + push_back[0] = EOF; + return c; + } + int c = getc(fp); + while (is_invalid_input_char(c)) { + error("invalid input character code %1", int(c)); + c = getc(fp); + bol = 0; + } + if (bol && c == '.') { + c = getc(fp); + if (c == 'P') { + c = getc(fp); + if (c == 'E' || c == 'F' || c == 'Y') { + int d = getc(fp); + if (d != EOF) + ungetc(d, fp); + if (d == EOF || d == ' ' || d == '\n' || compatible_flag) { + eof = 1; + want_flyback = (c == 'F'); + want_alternate_flyback = (c == 'Y'); + return EOF; + } + push_back[0] = c; + push_back[1] = 'P'; + return '.'; + } + if (c == 'S') { + c = getc(fp); + if (c != EOF) + ungetc(c, fp); + if (c == EOF || c == ' ' || c == '\n' || compatible_flag) { + error("nested .PS"); + eof = 1; + return EOF; + } + push_back[0] = 'S'; + push_back[1] = 'P'; + return '.'; + } + if (c != EOF) + ungetc(c, fp); + push_back[0] = 'P'; + return '.'; + } + else { + if (c != EOF) + ungetc(c, fp); + return '.'; + } + } + if (c == '\n') { + bol = 1; + current_lineno++; + return '\n'; + } + bol = 0; + if (c == EOF) { + eof = 1; + error("end of file before .PE, .PF, or .PY"); + error_with_file_and_line(current_filename, start_lineno - 1, + ".PS was here"); + } + return c; +} + +int top_input::peek() +{ + if (eof) + return EOF; + if (push_back[2] != EOF) + return push_back[2]; + if (push_back[1] != EOF) + return push_back[1]; + if (push_back[0] != EOF) + return push_back[0]; + int c = getc(fp); + while (is_invalid_input_char(c)) { + error("invalid input character code %1", int(c)); + c = getc(fp); + bol = 0; + } + if (bol && c == '.') { + c = getc(fp); + if (c == 'P') { + c = getc(fp); + if (c == 'E' || c == 'F' || c == 'Y') { + int d = getc(fp); + if (d != EOF) + ungetc(d, fp); + if (d == EOF || d == ' ' || d == '\n' || compatible_flag) { + eof = 1; + want_flyback = (c == 'F'); + want_alternate_flyback = (c == 'Y'); + return EOF; + } + push_back[0] = c; + push_back[1] = 'P'; + push_back[2] = '.'; + return '.'; + } + if (c == 'S') { + c = getc(fp); + if (c != EOF) + ungetc(c, fp); + if (c == EOF || c == ' ' || c == '\n' || compatible_flag) { + error("nested .PS"); + eof = 1; + return EOF; + } + push_back[0] = 'S'; + push_back[1] = 'P'; + push_back[2] = '.'; + return '.'; + } + if (c != EOF) + ungetc(c, fp); + push_back[0] = 'P'; + push_back[1] = '.'; + return '.'; + } + else { + if (c != EOF) + ungetc(c, fp); + push_back[0] = '.'; + return '.'; + } + } + if (c != EOF) + ungetc(c, fp); + if (c == '\n') + return '\n'; + return c; +} + +int top_input::get_location(const char **filenamep, int *linenop) +{ + *filenamep = current_filename; + *linenop = current_lineno; + return 1; +} + +void do_picture(FILE *fp) +{ + want_flyback = false; + int c; + if (!graphname) + free(graphname); + graphname = strsave("graph"); // default picture name in TeX mode + while ((c = getc(fp)) == ' ') + ; + if (c == '<') { + string filename; + while ((c = getc(fp)) == ' ') + ; + while (c != EOF && c != ' ' && c != '\n') { + filename += char(c); + c = getc(fp); + } + if (c == ' ') { + do { + c = getc(fp); + } while (c != EOF && c != '\n'); + } + if (c == '\n') + current_lineno++; + if (filename.length() == 0) + error("missing filename after '<'"); + else { + filename += '\0'; + const char *old_filename = current_filename; + int old_lineno = current_lineno; + // filenames must be permanent + do_file(strsave(filename.contents())); + current_filename = old_filename; + current_lineno = old_lineno; + } + out->set_location(current_filename, current_lineno); + } + else { + out->set_location(current_filename, current_lineno); + string start_line; + while (c != EOF) { + if (c == '\n') { + current_lineno++; + break; + } + start_line += c; + c = getc(fp); + } + if (c == EOF) + return; + start_line += '\0'; + double wid, ht; + switch (sscanf(&start_line[0], "%lf %lf", &wid, &ht)) { + case 1: + ht = 0.0; + break; + case 2: + break; + default: + ht = wid = 0.0; + break; + } + out->set_desired_width_height(wid, ht); + out->set_args(start_line.contents()); + lex_init(new top_input(fp)); + if (yyparse()) { + had_parse_error = 1; + lex_error("giving up on this picture"); + } + parse_cleanup(); + lex_cleanup(); + + // skip the rest of the .PE/.PF/.PY line + while ((c = getc(fp)) != EOF && c != '\n') + ; + if (c == '\n') + current_lineno++; + out->set_location(current_filename, current_lineno); + } +} + +void do_file(const char *filename) +{ + FILE *fp; + if (strcmp(filename, "-") == 0) + fp = stdin; + else { + errno = 0; + fp = fopen(filename, "r"); + if (fp == 0) { + delete out; + fatal("can't open '%1': %2", filename, strerror(errno)); + } + } + string fn(filename); + fn += '\0'; + normalize_for_lf(fn); + current_filename = fn.contents(); + out->set_location(current_filename, 1); + current_lineno = 1; + enum { START, MIDDLE, HAD_DOT, HAD_P, HAD_PS, HAD_l, HAD_lf } state = START; + for (;;) { + int c = getc(fp); + while (is_invalid_input_char(c)) { + error("invalid input character code %1", int(c)); + c = getc(fp); + } + if (c == EOF) + break; + switch (state) { + case START: + if (c == '.') + state = HAD_DOT; + else { + putchar(c); + if (c == '\n') { + current_lineno++; + state = START; + } + else + state = MIDDLE; + } + break; + case MIDDLE: + putchar(c); + if (c == '\n') { + current_lineno++; + state = START; + } + break; + case HAD_DOT: + if (c == 'P') + state = HAD_P; + else if (lf_flag && c == 'l') + state = HAD_l; + else { + putchar('.'); + putchar(c); + if (c == '\n') { + current_lineno++; + state = START; + } + else + state = MIDDLE; + } + break; + case HAD_P: + if (c == 'S') + state = HAD_PS; + else { + putchar('.'); + putchar('P'); + putchar(c); + if (c == '\n') { + current_lineno++; + state = START; + } + else + state = MIDDLE; + } + break; + case HAD_PS: + if (c == ' ' || c == '\n' || compatible_flag) { + ungetc(c, fp); + do_picture(fp); + state = START; + } + else { + fputs(".PS", stdout); + putchar(c); + state = MIDDLE; + } + break; + case HAD_l: + if (c == 'f') + state = HAD_lf; + else { + putchar('.'); + putchar('l'); + putchar(c); + if (c == '\n') { + current_lineno++; + state = START; + } + else + state = MIDDLE; + } + break; + case HAD_lf: + if (c == ' ' || c == '\n' || compatible_flag) { + string line; + while (c != EOF) { + line += c; + if (c == '\n') { + current_lineno++; + break; + } + c = getc(fp); + } + line += '\0'; + interpret_lf_args(line.contents()); + printf(".lf%s", line.contents()); + state = START; + } + else { + fputs(".lf", stdout); + putchar(c); + state = MIDDLE; + } + break; + default: + assert(0); + } + } + switch (state) { + case START: + break; + case MIDDLE: + putchar('\n'); + break; + case HAD_DOT: + fputs(".\n", stdout); + break; + case HAD_P: + fputs(".P\n", stdout); + break; + case HAD_PS: + fputs(".PS\n", stdout); + break; + case HAD_l: + fputs(".l\n", stdout); + break; + case HAD_lf: + fputs(".lf\n", stdout); + break; + } + if (fp != stdin) + fclose(fp); +} + +#ifdef FIG_SUPPORT +void do_whole_file(const char *filename) +{ + // Do not set current_filename. + FILE *fp; + if (strcmp(filename, "-") == 0) + fp = stdin; + else { + errno = 0; + fp = fopen(filename, "r"); + if (fp == 0) + fatal("can't open '%1': %2", filename, strerror(errno)); + } + lex_init(new file_input(fp, filename)); + if (yyparse()) + had_parse_error = 1; + parse_cleanup(); + lex_cleanup(); +} +#endif + +void usage(FILE *stream) +{ + fprintf(stream, "usage: %s [-CnSU] [file ...]\n", program_name); +#ifdef TEX_SUPPORT + fprintf(stream, "usage: %s -t [-cCSUz] [file ...]\n", program_name); +#endif +#ifdef FIG_SUPPORT + fprintf(stream, "usage: %s -f [-v] [file]\n", program_name); +#endif + fprintf(stream, "usage: %s {-v | --version}\n", program_name); + fprintf(stream, "usage: %s --help\n", program_name); +} + +#if defined(__MSDOS__) || defined(__EMX__) +static char *fix_program_name(char *arg, char *dflt) +{ + if (!arg) + return dflt; + char *prog = strchr(arg, '\0'); + for (;;) { + if (prog == arg) + break; + --prog; + if (strchr("\\/:", *prog)) { + prog++; + break; + } + } + char *ext = strchr(prog, '.'); + if (ext) + *ext = '\0'; + for (char *p = prog; *p; p++) + if ('A' <= *p && *p <= 'Z') + *p = 'a' + (*p - 'A'); + return prog; +} +#endif /* __MSDOS__ || __EMX__ */ + +int main(int argc, char **argv) +{ + setlocale(LC_NUMERIC, "C"); +#if defined(__MSDOS__) || defined(__EMX__) + argv[0] = fix_program_name(argv[0], "pic"); +#endif /* __MSDOS__ || __EMX__ */ + program_name = argv[0]; + static char stderr_buf[BUFSIZ]; + setbuf(stderr, stderr_buf); + int opt; +#ifdef TEX_SUPPORT + int tex_flag = 0; + int tpic_flag = 0; +#endif +#ifdef FIG_SUPPORT + int whole_file_flag = 0; + int fig_flag = 0; +#endif + static const struct option long_options[] = { + { "help", no_argument, 0, CHAR_MAX + 1 }, + { "version", no_argument, 0, 'v' }, + { NULL, 0, 0, 0 } + }; + while ((opt = getopt_long(argc, argv, "T:CDSUtcvnxzpf", long_options, NULL)) + != EOF) + switch (opt) { + case 'C': + compatible_flag = 1; + break; + case 'D': + case 'T': + break; + case 'S': + safer_flag = 1; + break; + case 'U': + safer_flag = 0; + break; + case 'f': +#ifdef FIG_SUPPORT + whole_file_flag++; + fig_flag++; +#else + fatal("fig support not included"); +#endif + break; + case 'n': + driver_extension_flag = 0; + break; + case 'p': + case 'x': + warning("-%1 option is obsolete", char(opt)); + break; + case 't': +#ifdef TEX_SUPPORT + tex_flag++; +#else + fatal("TeX support not included"); +#endif + break; + case 'c': +#ifdef TEX_SUPPORT + tpic_flag++; +#else + fatal("TeX support not included"); +#endif + break; + case 'v': + { + printf("GNU pic (groff) version %s\n", Version_string); + exit(0); + break; + } + case 'z': + // zero length lines will be printed as dots + zero_length_line_flag++; + break; + case CHAR_MAX + 1: // --help + usage(stdout); + exit(0); + break; + case '?': + usage(stderr); + exit(1); + break; + default: + assert(0); + } + parse_init(); +#ifdef TEX_SUPPORT + if (tpic_flag) { + out = make_tpic_output(); + lf_flag = 0; + } + else if (tex_flag) { + out = make_tex_output(); + command_char = '\\'; + lf_flag = 0; + } + else +#endif +#ifdef FIG_SUPPORT + if (fig_flag) + out = make_fig_output(); + else +#endif + { + out = make_troff_output(); + printf(".do if !dPS .ds PS\n" + ".do if !dPE .ds PE\n" + ".do if !dPF .ds PF\n" + ".do if !dPY .ds PY\n"); + } +#ifdef FIG_SUPPORT + if (whole_file_flag) { + if (optind >= argc) + do_whole_file("-"); + else if (argc - optind > 1) { + usage(stderr); + exit(1); + } else + do_whole_file(argv[optind]); + } + else { +#endif + if (optind >= argc) + do_file("-"); + else + for (int i = optind; i < argc; i++) + do_file(argv[i]); +#ifdef FIG_SUPPORT + } +#endif + delete out; + if (ferror(stdout) || fflush(stdout) < 0) + fatal("output error"); + return had_parse_error; +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/pic/object.cpp b/src/preproc/pic/object.cpp new file mode 100644 index 0000000..e207fb1 --- /dev/null +++ b/src/preproc/pic/object.cpp @@ -0,0 +1,2079 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "pic.h" +#include "ptable.h" +#include "object.h" + +void print_object_list(object *); + +line_type::line_type() +: type(solid), thickness(1.0) +{ +} + +output::output() : args(0), desired_height(0.0), desired_width(0.0) +{ +} + +output::~output() +{ + delete[] args; +} + +void output::set_desired_width_height(double wid, double ht) +{ + desired_width = wid; + desired_height = ht; +} + +void output::set_args(const char *s) +{ + delete[] args; + if (s == 0 || *s == '\0') + args = 0; + else + args = strsave(s); +} + +int output::supports_filled_polygons() +{ + return 0; +} + +void output::begin_block(const position &, const position &) +{ +} + +void output::end_block() +{ +} + +double output::compute_scale(double sc, const position &ll, const position &ur) +{ + distance dim = ur - ll; + if (desired_width != 0.0 || desired_height != 0.0) { + sc = 0.0; + if (desired_width != 0.0) { + if (dim.x == 0.0) + error("width specified for picture with zero width"); + else + sc = dim.x/desired_width; + } + if (desired_height != 0.0) { + if (dim.y == 0.0) + error("height specified for picture with zero height"); + else { + double tem = dim.y/desired_height; + if (tem > sc) + sc = tem; + } + } + return sc == 0.0 ? 1.0 : sc; + } + else { + if (sc <= 0.0) + sc = 1.0; + distance sdim = dim/sc; + double max_width = 0.0; + lookup_variable("maxpswid", &max_width); + double max_height = 0.0; + lookup_variable("maxpsht", &max_height); + if ((max_width > 0.0 && sdim.x > max_width) + || (max_height > 0.0 && sdim.y > max_height)) { + double xscale = dim.x/max_width; + double yscale = dim.y/max_height; + return xscale > yscale ? xscale : yscale; + } + else + return sc; + } +} + +position::position(const place &pl) +{ + if (pl.obj != 0) { + // Use two statements to work around bug in SGI C++. + object *tem = pl.obj; + *this = tem->origin(); + } + else { + x = pl.x; + y = pl.y; + } +} + +position::position() : x(0.0), y(0.0) +{ +} + +position::position(double a, double b) : x(a), y(b) +{ +} + + +int operator==(const position &a, const position &b) +{ + return a.x == b.x && a.y == b.y; +} + +int operator!=(const position &a, const position &b) +{ + return a.x != b.x || a.y != b.y; +} + +position &position::operator+=(const position &a) +{ + x += a.x; + y += a.y; + return *this; +} + +position &position::operator-=(const position &a) +{ + x -= a.x; + y -= a.y; + return *this; +} + +position &position::operator*=(double a) +{ + x *= a; + y *= a; + return *this; +} + +position &position::operator/=(double a) +{ + x /= a; + y /= a; + return *this; +} + +position operator-(const position &a) +{ + return position(-a.x, -a.y); +} + +position operator+(const position &a, const position &b) +{ + return position(a.x + b.x, a.y + b.y); +} + +position operator-(const position &a, const position &b) +{ + return position(a.x - b.x, a.y - b.y); +} + +position operator/(const position &a, double n) +{ + return position(a.x/n, a.y/n); +} + +position operator*(const position &a, double n) +{ + return position(a.x*n, a.y*n); +} + +// dot product + +double operator*(const position &a, const position &b) +{ + return a.x*b.x + a.y*b.y; +} + +double hypot(const position &a) +{ + return groff_hypot(a.x, a.y); +} + +struct arrow_head_type { + double height; + double width; + int solid; +}; + +void draw_arrow(const position &pos, const distance &dir, + const arrow_head_type &aht, const line_type <, + char *outline_color_for_fill) +{ + double hyp = hypot(dir); + if (hyp == 0.0) { + error("cannot draw arrow on object with zero length"); + return; + } + position base = -dir; + base *= aht.height/hyp; + position n(dir.y, -dir.x); + n *= aht.width/(hyp*2.0); + line_type slt = lt; + slt.type = line_type::solid; + if (aht.solid && out->supports_filled_polygons()) { + position v[3]; + v[0] = pos; + v[1] = pos + base + n; + v[2] = pos + base - n; + // fill with outline color + out->set_color(outline_color_for_fill, outline_color_for_fill); + // make stroke thin to avoid arrow sticking + slt.thickness = 0.1; + out->polygon(v, 3, slt, 1); + } + else { + // use two line segments to avoid arrow sticking + out->line(pos + base - n, &pos, 1, slt); + out->line(pos + base + n, &pos, 1, slt); + } +} + +object::object() : prev(0), next(0) +{ +} + +object::~object() +{ +} + +void object::move_by(const position &) +{ +} + +void object::print() +{ +} + +void object::print_text() +{ +} + +int object::blank() +{ + return 0; +} + +struct bounding_box { + int blank; + position ll; + position ur; + + bounding_box(); + void encompass(const position &); +}; + +bounding_box::bounding_box() +: blank(1) +{ +} + +void bounding_box::encompass(const position &pos) +{ + if (blank) { + ll = pos; + ur = pos; + blank = 0; + } + else { + if (pos.x < ll.x) + ll.x = pos.x; + if (pos.y < ll.y) + ll.y = pos.y; + if (pos.x > ur.x) + ur.x = pos.x; + if (pos.y > ur.y) + ur.y = pos.y; + } +} + +void object::update_bounding_box(bounding_box *) +{ +} + +position object::origin() +{ + return position(0.0,0.0); +} + +position object::north() +{ + return origin(); +} + +position object::south() +{ + return origin(); +} + +position object::east() +{ + return origin(); +} + +position object::west() +{ + return origin(); +} + +position object::north_east() +{ + return origin(); +} + +position object::north_west() +{ + return origin(); +} + +position object::south_east() +{ + return origin(); +} + +position object::south_west() +{ + return origin(); +} + +position object::start() +{ + return origin(); +} + +position object::end() +{ + return origin(); +} + +position object::center() +{ + return origin(); +} + +double object::width() +{ + return 0.0; +} + +double object::radius() +{ + return 0.0; +} + +double object::height() +{ + return 0.0; +} + +place *object::find_label(const char *) +{ + return 0; +} + +segment::segment(const position &a, int n, segment *p) +: is_absolute(n), pos(a), next(p) +{ +} + +text_item::text_item(char *t, const char *fn, int ln) +: next(0), text(t), filename(fn), lineno(ln) +{ + adj.h = CENTER_ADJUST; + adj.v = NONE_ADJUST; +} + +text_item::~text_item() +{ + delete[] text; +} + +object_spec::object_spec(object_type t) : type(t) +{ + flags = 0; + tbl = 0; + segment_list = 0; + segment_width = segment_height = 0.0; + segment_is_absolute = 0; + text = 0; + shaded = 0; + xslanted = 0; + yslanted = 0; + outlined = 0; + with = 0; + dir = RIGHT_DIRECTION; +} + +object_spec::~object_spec() +{ + delete tbl; + while (segment_list != 0) { + segment *tem = segment_list; + segment_list = segment_list->next; + delete tem; + } + object *p = oblist.head; + while (p != 0) { + object *tem = p; + p = p->next; + delete tem; + } + while (text != 0) { + text_item *tem = text; + text = text->next; + delete tem; + } + delete with; + delete[] shaded; + delete[] outlined; +} + +class command_object : public object { + char *s; + const char *filename; + int lineno; +public: + command_object(char *, const char *, int); + ~command_object(); + object_type type() { return OTHER_OBJECT; } + void print(); +}; + +command_object::command_object(char *p, const char *fn, int ln) +: s(p), filename(fn), lineno(ln) +{ +} + +command_object::~command_object() +{ + delete[] s; +} + +void command_object::print() +{ + out->command(s, filename, lineno); +} + +object *make_command_object(char *s, const char *fn, int ln) +{ + return new command_object(s, fn, ln); +} + +class mark_object : public object { +public: + mark_object(); + object_type type(); +}; + +object *make_mark_object() +{ + return new mark_object(); +} + +mark_object::mark_object() +{ +} + +object_type mark_object::type() +{ + return MARK_OBJECT; +} + +object_list::object_list() : head(0), tail(0) +{ +} + +void object_list::append(object *obj) +{ + if (tail == 0) { + obj->next = obj->prev = 0; + head = tail = obj; + } + else { + obj->prev = tail; + obj->next = 0; + tail->next = obj; + tail = obj; + } +} + +void object_list::wrap_up_block(object_list *ol) +{ + object *p; + for (p = tail; p && p->type() != MARK_OBJECT; p = p->prev) + ; + assert(p != 0); + ol->head = p->next; + if (ol->head) { + ol->tail = tail; + ol->head->prev = 0; + } + else + ol->tail = 0; + tail = p->prev; + if (tail) + tail->next = 0; + else + head = 0; + delete p; +} + +text_piece::text_piece() +: text(0), filename(0), lineno(-1) +{ + adj.h = CENTER_ADJUST; + adj.v = NONE_ADJUST; +} + +text_piece::~text_piece() +{ + free(text); +} + +class graphic_object : public object { + int ntext; + text_piece *text; + int aligned; +protected: + line_type lt; + char *outline_color; + char *color_fill; +public: + graphic_object(); + ~graphic_object(); + object_type type() = 0; + void print_text(); + void add_text(text_item *, int); + void set_dotted(double); + void set_dashed(double); + void set_thickness(double); + void set_invisible(); + void set_outline_color(char *); + char *get_outline_color(); + virtual void set_fill(double); + virtual void set_xslanted(double); + virtual void set_yslanted(double); + virtual void set_fill_color(char *); +}; + +graphic_object::graphic_object() +: ntext(0), text(0), aligned(0), outline_color(0), color_fill(0) +{ +} + +void graphic_object::set_dotted(double wid) +{ + lt.type = line_type::dotted; + lt.dash_width = wid; +} + +void graphic_object::set_dashed(double wid) +{ + lt.type = line_type::dashed; + lt.dash_width = wid; +} + +void graphic_object::set_thickness(double th) +{ + lt.thickness = th; +} + +void graphic_object::set_fill(double) +{ +} + +void graphic_object::set_xslanted(double) +{ +} + +void graphic_object::set_yslanted(double) +{ +} + +void graphic_object::set_fill_color(char *c) +{ + color_fill = strsave(c); +} + +void graphic_object::set_outline_color(char *c) +{ + outline_color = strsave(c); +} + +char *graphic_object::get_outline_color() +{ + return outline_color; +} + +void graphic_object::set_invisible() +{ + lt.type = line_type::invisible; +} + +void graphic_object::add_text(text_item *t, int a) +{ + aligned = a; + int len = 0; + text_item *p; + for (p = t; p; p = p->next) + len++; + if (len == 0) + text = 0; + else { + text = new text_piece[len]; + for (p = t, len = 0; p; p = p->next, len++) { + text[len].text = p->text; + p->text = 0; + text[len].adj = p->adj; + text[len].filename = p->filename; + text[len].lineno = p->lineno; + } + } + ntext = len; +} + +void graphic_object::print_text() +{ + double angle = 0.0; + if (aligned) { + position d(end() - start()); + if (d.x != 0.0 || d.y != 0.0) + angle = atan2(d.y, d.x); + } + if (text != 0) { + out->set_color(color_fill, get_outline_color()); + out->text(center(), text, ntext, angle); + out->reset_color(); + } +} + +graphic_object::~graphic_object() +{ + if (text) + delete[] text; +} + +class rectangle_object : public graphic_object { +protected: + position cent; + position dim; +public: + rectangle_object(const position &); + double width() { return dim.x; } + double height() { return dim.y; } + position origin() { return cent; } + position center() { return cent; } + position north() { return position(cent.x, cent.y + dim.y/2.0); } + position south() { return position(cent.x, cent.y - dim.y/2.0); } + position east() { return position(cent.x + dim.x/2.0, cent.y); } + position west() { return position(cent.x - dim.x/2.0, cent.y); } + position north_east() { return position(cent.x + dim.x/2.0, cent.y + dim.y/2.0); } + position north_west() { return position(cent.x - dim.x/2.0, cent.y + dim.y/2.0); } + position south_east() { return position(cent.x + dim.x/2.0, cent.y - dim.y/2.0); } + position south_west() { return position(cent.x - dim.x/2.0, cent.y - dim.y/2.0); } + object_type type() = 0; + void update_bounding_box(bounding_box *); + void move_by(const position &); +}; + +rectangle_object::rectangle_object(const position &d) +: dim(d) +{ +} + +void rectangle_object::update_bounding_box(bounding_box *p) +{ + p->encompass(cent - dim/2.0); + p->encompass(cent + dim/2.0); +} + +void rectangle_object::move_by(const position &a) +{ + cent += a; +} + +class closed_object : public rectangle_object { +public: + closed_object(const position &); + object_type type() = 0; + void set_fill(double); + void set_xslanted(double); + void set_yslanted(double); + void set_fill_color(char *fill); +protected: + double fill; // < 0 if not filled + double xslanted; // !=0 if x is slanted + double yslanted; // !=0 if y is slanted + char *color_fill; // = 0 if not colored +}; + +closed_object::closed_object(const position &pos) +: rectangle_object(pos), fill(-1.0), xslanted(0), yslanted(0), color_fill(0) +{ +} + +void closed_object::set_fill(double f) +{ + assert(f >= 0.0); + fill = f; +} + +/* accept positive and negative values */ +void closed_object::set_xslanted(double s) +{ + //assert(s >= 0.0); + xslanted = s; +} +/* accept positive and negative values */ +void closed_object::set_yslanted(double s) +{ + //assert(s >= 0.0); + yslanted = s; +} + +void closed_object::set_fill_color(char *f) +{ + color_fill = strsave(f); +} + +class box_object : public closed_object { + double xrad; + double yrad; +public: + box_object(const position &, double); + object_type type() { return BOX_OBJECT; } + void print(); + position north_east(); + position north_west(); + position south_east(); + position south_west(); +}; + +box_object::box_object(const position &pos, double r) +: closed_object(pos), xrad(dim.x > 0 ? r : -r), yrad(dim.y > 0 ? r : -r) +{ +} + +const double CHOP_FACTOR = 1.0 - 1.0/M_SQRT2; + +position box_object::north_east() +{ + return position(cent.x + dim.x/2.0 - CHOP_FACTOR*xrad, + cent.y + dim.y/2.0 - CHOP_FACTOR*yrad); +} + +position box_object::north_west() +{ + return position(cent.x - dim.x/2.0 + CHOP_FACTOR*xrad, + cent.y + dim.y/2.0 - CHOP_FACTOR*yrad); +} + +position box_object::south_east() +{ + return position(cent.x + dim.x/2.0 - CHOP_FACTOR*xrad, + cent.y - dim.y/2.0 + CHOP_FACTOR*yrad); +} + +position box_object::south_west() +{ + return position(cent.x - dim.x/2.0 + CHOP_FACTOR*xrad, + cent.y - dim.y/2.0 + CHOP_FACTOR*yrad); +} + +void box_object::print() +{ + if (lt.type == line_type::invisible && fill < 0.0 && color_fill == 0) + return; + out->set_color(color_fill, graphic_object::get_outline_color()); + if (xrad == 0.0) { + distance dim2 = dim/2.0; + position vec[4]; + /* error("x slanted %1", xslanted); */ + /* error("y slanted %1", yslanted); */ + vec[0] = cent + position(dim2.x, -(dim2.y - yslanted)); /* lr */ + vec[1] = cent + position(dim2.x + xslanted, dim2.y + yslanted); /* ur */ + vec[2] = cent + position(-(dim2.x - xslanted), dim2.y); /* ul */ + vec[3] = cent + position(-(dim2.x), -dim2.y); /* ll */ + out->polygon(vec, 4, lt, fill); + } + else { + distance abs_dim(fabs(dim.x), fabs(dim.y)); + out->rounded_box(cent, abs_dim, fabs(xrad), lt, fill, color_fill); + } + out->reset_color(); +} + +graphic_object *object_spec::make_box(position *curpos, direction *dirp) +{ + static double last_box_height; + static double last_box_width; + static double last_box_radius; + static int have_last_box = 0; + if (!(flags & HAS_HEIGHT)) { + if ((flags & IS_SAME) && have_last_box) + height = last_box_height; + else + lookup_variable("boxht", &height); + } + if (!(flags & HAS_WIDTH)) { + if ((flags & IS_SAME) && have_last_box) + width = last_box_width; + else + lookup_variable("boxwid", &width); + } + if (!(flags & HAS_RADIUS)) { + if ((flags & IS_SAME) && have_last_box) + radius = last_box_radius; + else + lookup_variable("boxrad", &radius); + } + last_box_width = width; + last_box_height = height; + last_box_radius = radius; + have_last_box = 1; + radius = fabs(radius); + if (radius*2.0 > fabs(width)) + radius = fabs(width/2.0); + if (radius*2.0 > fabs(height)) + radius = fabs(height/2.0); + box_object *p = new box_object(position(width, height), radius); + if (!position_rectangle(p, curpos, dirp)) { + delete p; + p = 0; + } + return p; +} + +// return non-zero for success + +int object_spec::position_rectangle(rectangle_object *p, + position *curpos, direction *dirp) +{ + position pos; + dir = *dirp; // ignore any direction in attribute list + position motion; + switch (dir) { + case UP_DIRECTION: + motion.y = p->height()/2.0; + break; + case DOWN_DIRECTION: + motion.y = -p->height()/2.0; + break; + case LEFT_DIRECTION: + motion.x = -p->width()/2.0; + break; + case RIGHT_DIRECTION: + motion.x = p->width()/2.0; + break; + default: + assert(0); + } + if (flags & HAS_AT) { + pos = at; + if (flags & HAS_WITH) { + place offset; + place here; + here.obj = p; + if (!with->follow(here, &offset)) + return 0; + pos -= offset; + } + } + else { + pos = *curpos; + pos += motion; + } + p->move_by(pos); + pos += motion; + *curpos = pos; + return 1; +} + +class block_object : public rectangle_object { + object_list oblist; + PTABLE(place) *tbl; +public: + block_object(const position &, const object_list &ol, PTABLE(place) *t); + ~block_object(); + place *find_label(const char *); + object_type type(); + void move_by(const position &); + void print(); +}; + +block_object::block_object(const position &d, const object_list &ol, + PTABLE(place) *t) +: rectangle_object(d), oblist(ol), tbl(t) +{ +} + +block_object::~block_object() +{ + delete tbl; + object *p = oblist.head; + while (p != 0) { + object *tem = p; + p = p->next; + delete tem; + } +} + +void block_object::print() +{ + out->begin_block(south_west(), north_east()); + print_object_list(oblist.head); + out->end_block(); +} + +static void adjust_objectless_places(PTABLE(place) *tbl, const position &a) +{ + // Adjust all the labels that aren't attached to objects. + PTABLE_ITERATOR(place) iter(tbl); + const char *key; + place *pl; + while (iter.next(&key, &pl)) + if (key && csupper(key[0]) && pl->obj == 0) { + pl->x += a.x; + pl->y += a.y; + } +} + +void block_object::move_by(const position &a) +{ + cent += a; + for (object *p = oblist.head; p; p = p->next) + p->move_by(a); + adjust_objectless_places(tbl, a); +} + + +place *block_object::find_label(const char *name) +{ + return tbl->lookup(name); +} + +object_type block_object::type() +{ + return BLOCK_OBJECT; +} + +graphic_object *object_spec::make_block(position *curpos, direction *dirp) +{ + bounding_box bb; + for (object *p = oblist.head; p; p = p->next) + p->update_bounding_box(&bb); + position dim; + if (!bb.blank) { + position m = -(bb.ll + bb.ur)/2.0; + for (object *p = oblist.head; p; p = p->next) + p->move_by(m); + adjust_objectless_places(tbl, m); + dim = bb.ur - bb.ll; + } + if (flags & HAS_WIDTH) + dim.x = width; + if (flags & HAS_HEIGHT) + dim.y = height; + block_object *block = new block_object(dim, oblist, tbl); + if (!position_rectangle(block, curpos, dirp)) { + delete block; + block = 0; + } + tbl = 0; + oblist.head = oblist.tail = 0; + return block; +} + +class text_object : public rectangle_object { +public: + text_object(const position &); + object_type type() { return TEXT_OBJECT; } +}; + +text_object::text_object(const position &d) +: rectangle_object(d) +{ +} + +graphic_object *object_spec::make_text(position *curpos, direction *dirp) +{ + if (!(flags & HAS_HEIGHT)) { + lookup_variable("textht", &height); + int nitems = 0; + for (text_item *t = text; t; t = t->next) + nitems++; + height *= nitems; + } + if (!(flags & HAS_WIDTH)) + lookup_variable("textwid", &width); + text_object *p = new text_object(position(width, height)); + if (!position_rectangle(p, curpos, dirp)) { + delete p; + p = 0; + } + return p; +} + + +class ellipse_object : public closed_object { +public: + ellipse_object(const position &); + position north_east() { return position(cent.x + dim.x/(M_SQRT2*2.0), + cent.y + dim.y/(M_SQRT2*2.0)); } + position north_west() { return position(cent.x - dim.x/(M_SQRT2*2.0), + cent.y + dim.y/(M_SQRT2*2.0)); } + position south_east() { return position(cent.x + dim.x/(M_SQRT2*2.0), + cent.y - dim.y/(M_SQRT2*2.0)); } + position south_west() { return position(cent.x - dim.x/(M_SQRT2*2.0), + cent.y - dim.y/(M_SQRT2*2.0)); } + double radius() { return dim.x/2.0; } + object_type type() { return ELLIPSE_OBJECT; } + void print(); +}; + +ellipse_object::ellipse_object(const position &d) +: closed_object(d) +{ +} + +void ellipse_object::print() +{ + if (lt.type == line_type::invisible && fill < 0.0 && color_fill == 0) + return; + out->set_color(color_fill, graphic_object::get_outline_color()); + out->ellipse(cent, dim, lt, fill); + out->reset_color(); +} + +graphic_object *object_spec::make_ellipse(position *curpos, direction *dirp) +{ + static double last_ellipse_height; + static double last_ellipse_width; + static int have_last_ellipse = 0; + if (!(flags & HAS_HEIGHT)) { + if ((flags & IS_SAME) && have_last_ellipse) + height = last_ellipse_height; + else + lookup_variable("ellipseht", &height); + } + if (!(flags & HAS_WIDTH)) { + if ((flags & IS_SAME) && have_last_ellipse) + width = last_ellipse_width; + else + lookup_variable("ellipsewid", &width); + } + last_ellipse_width = width; + last_ellipse_height = height; + have_last_ellipse = 1; + ellipse_object *p = new ellipse_object(position(width, height)); + if (!position_rectangle(p, curpos, dirp)) { + delete p; + return 0; + } + return p; +} + +class circle_object : public ellipse_object { +public: + circle_object(double); + object_type type() { return CIRCLE_OBJECT; } + void print(); +}; + +circle_object::circle_object(double diam) +: ellipse_object(position(diam, diam)) +{ +} + +void circle_object::print() +{ + if (lt.type == line_type::invisible && fill < 0.0 && color_fill == 0) + return; + out->set_color(color_fill, graphic_object::get_outline_color()); + out->circle(cent, dim.x/2.0, lt, fill); + out->reset_color(); +} + +graphic_object *object_spec::make_circle(position *curpos, direction *dirp) +{ + static double last_circle_radius; + static int have_last_circle = 0; + if (!(flags & HAS_RADIUS)) { + if ((flags & IS_SAME) && have_last_circle) + radius = last_circle_radius; + else + lookup_variable("circlerad", &radius); + } + last_circle_radius = radius; + have_last_circle = 1; + circle_object *p = new circle_object(radius*2.0); + if (!position_rectangle(p, curpos, dirp)) { + delete p; + return 0; + } + return p; +} + +class move_object : public graphic_object { + position strt; + position en; +public: + move_object(const position &s, const position &e); + position origin() { return en; } + object_type type() { return MOVE_OBJECT; } + void update_bounding_box(bounding_box *); + void move_by(const position &); +}; + +move_object::move_object(const position &s, const position &e) +: strt(s), en(e) +{ +} + +void move_object::update_bounding_box(bounding_box *p) +{ + p->encompass(strt); + p->encompass(en); +} + +void move_object::move_by(const position &a) +{ + strt += a; + en += a; +} + +graphic_object *object_spec::make_move(position *curpos, direction *dirp) +{ + static position last_move; + static int have_last_move = 0; + *dirp = dir; + // No need to look at at since 'at' attribute sets 'from' attribute. + position startpos = (flags & HAS_FROM) ? from : *curpos; + if (!(flags & HAS_SEGMENT)) { + if ((flags & IS_SAME) && have_last_move) + segment_pos = last_move; + else { + switch (dir) { + case UP_DIRECTION: + segment_pos.y = segment_height; + break; + case DOWN_DIRECTION: + segment_pos.y = -segment_height; + break; + case LEFT_DIRECTION: + segment_pos.x = -segment_width; + break; + case RIGHT_DIRECTION: + segment_pos.x = segment_width; + break; + default: + assert(0); + } + } + } + segment_list = new segment(segment_pos, segment_is_absolute, segment_list); + // Reverse the segment_list so that it's in forward order. + segment *old = segment_list; + segment_list = 0; + while (old != 0) { + segment *tem = old->next; + old->next = segment_list; + segment_list = old; + old = tem; + } + // Compute the end position. + position endpos = startpos; + for (segment *s = segment_list; s; s = s->next) + if (s->is_absolute) + endpos = s->pos; + else + endpos += s->pos; + have_last_move = 1; + last_move = endpos - startpos; + move_object *p = new move_object(startpos, endpos); + *curpos = endpos; + return p; +} + +class linear_object : public graphic_object { +protected: + char arrow_at_start; + char arrow_at_end; + arrow_head_type aht; + position strt; + position en; +public: + linear_object(const position &s, const position &e); + position start() { return strt; } + position end() { return en; } + void move_by(const position &); + void update_bounding_box(bounding_box *) = 0; + object_type type() = 0; + void add_arrows(int at_start, int at_end, const arrow_head_type &); +}; + +class line_object : public linear_object { +protected: + position *v; + int n; +public: + line_object(const position &s, const position &e, position *, int); + ~line_object(); + position origin() { return strt; } + position center() { return (strt + en)/2.0; } + position north() { return (en.y - strt.y) > 0 ? en : strt; } + position south() { return (en.y - strt.y) < 0 ? en : strt; } + position east() { return (en.x - strt.x) > 0 ? en : strt; } + position west() { return (en.x - strt.x) < 0 ? en : strt; } + object_type type() { return LINE_OBJECT; } + void update_bounding_box(bounding_box *); + void print(); + void move_by(const position &); +}; + +class arrow_object : public line_object { +public: + arrow_object(const position &, const position &, position *, int); + object_type type() { return ARROW_OBJECT; } +}; + +class spline_object : public line_object { +public: + spline_object(const position &, const position &, position *, int); + object_type type() { return SPLINE_OBJECT; } + void print(); + void update_bounding_box(bounding_box *); +}; + +linear_object::linear_object(const position &s, const position &e) +: arrow_at_start(0), arrow_at_end(0), strt(s), en(e) +{ +} + +void linear_object::move_by(const position &a) +{ + strt += a; + en += a; +} + +void linear_object::add_arrows(int at_start, int at_end, + const arrow_head_type &a) +{ + arrow_at_start = at_start; + arrow_at_end = at_end; + aht = a; +} + +line_object::line_object(const position &s, const position &e, + position *p, int i) +: linear_object(s, e), v(p), n(i) +{ +} + +void line_object::print() +{ + if (lt.type == line_type::invisible) + return; + out->set_color(0, graphic_object::get_outline_color()); + // shorten line length to avoid arrow sticking. + position sp = strt; + if (arrow_at_start) { + position base = v[0] - strt; + double hyp = hypot(base); + if (hyp == 0.0) { + error("cannot draw arrow on object with zero length"); + return; + } + if (aht.solid && out->supports_filled_polygons()) { + base *= aht.height / hyp; + draw_arrow(strt, strt - v[0], aht, lt, + graphic_object::get_outline_color()); + sp = strt + base; + } else { + base *= fabs(lt.thickness) / hyp / 72 / 4; + sp = strt + base; + draw_arrow(sp, sp - v[0], aht, lt, + graphic_object::get_outline_color()); + } + } + if (arrow_at_end) { + position base = v[n-1] - (n > 1 ? v[n-2] : strt); + double hyp = hypot(base); + if (hyp == 0.0) { + error("cannot draw arrow on object with zero length"); + return; + } + if (aht.solid && out->supports_filled_polygons()) { + base *= aht.height / hyp; + draw_arrow(en, v[n-1] - (n > 1 ? v[n-2] : strt), aht, lt, + graphic_object::get_outline_color()); + v[n-1] = en - base; + } else { + base *= fabs(lt.thickness) / hyp / 72 / 4; + v[n-1] = en - base; + draw_arrow(v[n-1], v[n-1] - (n > 1 ? v[n-2] : strt), aht, lt, + graphic_object::get_outline_color()); + } + } + out->line(sp, v, n, lt); + out->reset_color(); +} + +void line_object::update_bounding_box(bounding_box *p) +{ + p->encompass(strt); + for (int i = 0; i < n; i++) + p->encompass(v[i]); +} + +void line_object::move_by(const position &pos) +{ + linear_object::move_by(pos); + for (int i = 0; i < n; i++) + v[i] += pos; +} + +void spline_object::update_bounding_box(bounding_box *p) +{ + p->encompass(strt); + p->encompass(en); + /* + + If + + p1 = q1/2 + q2/2 + p2 = q1/6 + q2*5/6 + p3 = q2*5/6 + q3/6 + p4 = q2/2 + q3/2 + [ the points for the Bezier cubic ] + + and + + t = .5 + + then + + (1-t)^3*p1 + 3*t*(t - 1)^2*p2 + 3*t^2*(1-t)*p3 + t^3*p4 + [ the equation for the Bezier cubic ] + + = .125*q1 + .75*q2 + .125*q3 + + */ + for (int i = 1; i < n; i++) + p->encompass((i == 1 ? strt : v[i-2])*.125 + v[i-1]*.75 + v[i]*.125); +} + +arrow_object::arrow_object(const position &s, const position &e, + position *p, int i) +: line_object(s, e, p, i) +{ +} + +spline_object::spline_object(const position &s, const position &e, + position *p, int i) +: line_object(s, e, p, i) +{ +} + +void spline_object::print() +{ + if (lt.type == line_type::invisible) + return; + out->set_color(0, graphic_object::get_outline_color()); + // shorten line length for spline to avoid arrow sticking + position sp = strt; + if (arrow_at_start) { + position base = v[0] - strt; + double hyp = hypot(base); + if (hyp == 0.0) { + error("cannot draw arrow on object with zero length"); + return; + } + if (aht.solid && out->supports_filled_polygons()) { + base *= aht.height / hyp; + draw_arrow(strt, strt - v[0], aht, lt, + graphic_object::get_outline_color()); + sp = strt + base*0.1; // to reserve spline shape + } else { + base *= fabs(lt.thickness) / hyp / 72 / 4; + sp = strt + base; + draw_arrow(sp, sp - v[0], aht, lt, + graphic_object::get_outline_color()); + } + } + if (arrow_at_end) { + position base = v[n-1] - (n > 1 ? v[n-2] : strt); + double hyp = hypot(base); + if (hyp == 0.0) { + error("cannot draw arrow on object with zero length"); + return; + } + if (aht.solid && out->supports_filled_polygons()) { + base *= aht.height / hyp; + draw_arrow(en, v[n-1] - (n > 1 ? v[n-2] : strt), aht, lt, + graphic_object::get_outline_color()); + v[n-1] = en - base*0.1; // to reserve spline shape + } else { + base *= fabs(lt.thickness) / hyp / 72 / 4; + v[n-1] = en - base; + draw_arrow(v[n-1], v[n-1] - (n > 1 ? v[n-2] : strt), aht, lt, + graphic_object::get_outline_color()); + } + } + out->spline(sp, v, n, lt); + out->reset_color(); +} + +line_object::~line_object() +{ + delete[] v; +} + +linear_object *object_spec::make_line(position *curpos, direction *dirp) +{ + static position last_line; + static int have_last_line = 0; + *dirp = dir; + // We handle 'at' only in conjunction with 'with', otherwise it is + // the same as the 'from' attribute. + position startpos; + if ((flags & HAS_AT) && (flags & HAS_WITH)) + // handled later -- we need the end position + startpos = *curpos; + else if (flags & HAS_FROM) + startpos = from; + else + startpos = *curpos; + if (!(flags & HAS_SEGMENT)) { + if ((flags & IS_SAME) && (type == LINE_OBJECT || type == ARROW_OBJECT) + && have_last_line) + segment_pos = last_line; + else + switch (dir) { + case UP_DIRECTION: + segment_pos.y = segment_height; + break; + case DOWN_DIRECTION: + segment_pos.y = -segment_height; + break; + case LEFT_DIRECTION: + segment_pos.x = -segment_width; + break; + case RIGHT_DIRECTION: + segment_pos.x = segment_width; + break; + default: + assert(0); + } + } + segment_list = new segment(segment_pos, segment_is_absolute, segment_list); + // reverse the segment_list so that it's in forward order + segment *old = segment_list; + segment_list = 0; + while (old != 0) { + segment *tem = old->next; + old->next = segment_list; + segment_list = old; + old = tem; + } + // Absolutise all movements + position endpos = startpos; + int nsegments = 0; + segment *s; + for (s = segment_list; s; s = s->next, nsegments++) + if (s->is_absolute) + endpos = s->pos; + else { + endpos += s->pos; + s->pos = endpos; + s->is_absolute = 1; // to avoid confusion + } + if ((flags & HAS_AT) && (flags & HAS_WITH)) { + // 'tmpobj' works for arrows and splines too -- we only need positions + line_object tmpobj(startpos, endpos, 0, 0); + position pos = at; + place offset; + place here; + here.obj = &tmpobj; + if (!with->follow(here, &offset)) + return 0; + pos -= offset; + for (s = segment_list; s; s = s->next) + s->pos += pos; + startpos += pos; + endpos += pos; + } + // handle chop + line_object *p = 0; + position *v = new position[nsegments]; + int i = 0; + for (s = segment_list; s; s = s->next, i++) + v[i] = s->pos; + if (flags & IS_DEFAULT_CHOPPED) { + lookup_variable("circlerad", &start_chop); + end_chop = start_chop; + flags |= IS_CHOPPED; + } + if (flags & IS_CHOPPED) { + position start_chop_vec, end_chop_vec; + if (start_chop != 0.0) { + start_chop_vec = v[0] - startpos; + start_chop_vec *= start_chop / hypot(start_chop_vec); + } + if (end_chop != 0.0) { + end_chop_vec = (v[nsegments - 1] + - (nsegments > 1 ? v[nsegments - 2] : startpos)); + end_chop_vec *= end_chop / hypot(end_chop_vec); + } + startpos += start_chop_vec; + v[nsegments - 1] -= end_chop_vec; + endpos -= end_chop_vec; + } + switch (type) { + case SPLINE_OBJECT: + p = new spline_object(startpos, endpos, v, nsegments); + break; + case ARROW_OBJECT: + p = new arrow_object(startpos, endpos, v, nsegments); + break; + case LINE_OBJECT: + p = new line_object(startpos, endpos, v, nsegments); + break; + default: + assert(0); + } + have_last_line = 1; + last_line = endpos - startpos; + *curpos = endpos; + return p; +} + +class arc_object : public linear_object { + int clockwise; + position cent; + double rad; +public: + arc_object(int, const position &, const position &, const position &); + position origin() { return cent; } + position center() { return cent; } + double radius() { return rad; } + position north(); + position south(); + position east(); + position west(); + position north_east(); + position north_west(); + position south_east(); + position south_west(); + void update_bounding_box(bounding_box *); + object_type type() { return ARC_OBJECT; } + void print(); + void move_by(const position &pos); +}; + +arc_object::arc_object(int cw, const position &s, const position &e, + const position &c) +: linear_object(s, e), clockwise(cw), cent(c) +{ + rad = hypot(c - s); +} + +void arc_object::move_by(const position &pos) +{ + linear_object::move_by(pos); + cent += pos; +} + +// we get arc corners from the corresponding circle + +position arc_object::north() +{ + position result(cent); + result.y += rad; + return result; +} + +position arc_object::south() +{ + position result(cent); + result.y -= rad; + return result; +} + +position arc_object::east() +{ + position result(cent); + result.x += rad; + return result; +} + +position arc_object::west() +{ + position result(cent); + result.x -= rad; + return result; +} + +position arc_object::north_east() +{ + position result(cent); + result.x += rad/M_SQRT2; + result.y += rad/M_SQRT2; + return result; +} + +position arc_object::north_west() +{ + position result(cent); + result.x -= rad/M_SQRT2; + result.y += rad/M_SQRT2; + return result; +} + +position arc_object::south_east() +{ + position result(cent); + result.x += rad/M_SQRT2; + result.y -= rad/M_SQRT2; + return result; +} + +position arc_object::south_west() +{ + position result(cent); + result.x -= rad/M_SQRT2; + result.y -= rad/M_SQRT2; + return result; +} + + +void arc_object::print() +{ + if (lt.type == line_type::invisible) + return; + out->set_color(0, graphic_object::get_outline_color()); + // handle arrow direction; make shorter line for arc + position sp, ep, b; + if (clockwise) { + sp = en; + ep = strt; + } else { + sp = strt; + ep = en; + } + if (arrow_at_start) { + double theta = aht.height / rad; + if (clockwise) + theta = - theta; + b = strt - cent; + b = position(b.x*cos(theta) - b.y*sin(theta), + b.x*sin(theta) + b.y*cos(theta)) + cent; + if (clockwise) + ep = b; + else + sp = b; + if (aht.solid && out->supports_filled_polygons()) { + draw_arrow(strt, strt - b, aht, lt, + graphic_object::get_outline_color()); + } else { + position v = b; + theta = fabs(lt.thickness) / 72 / 4 / rad; + if (clockwise) + theta = - theta; + b = strt - cent; + b = position(b.x*cos(theta) - b.y*sin(theta), + b.x*sin(theta) + b.y*cos(theta)) + cent; + draw_arrow(b, b - v, aht, lt, + graphic_object::get_outline_color()); + out->line(b, &v, 1, lt); + } + } + if (arrow_at_end) { + double theta = aht.height / rad; + if (!clockwise) + theta = - theta; + b = en - cent; + b = position(b.x*cos(theta) - b.y*sin(theta), + b.x*sin(theta) + b.y*cos(theta)) + cent; + if (clockwise) + sp = b; + else + ep = b; + if (aht.solid && out->supports_filled_polygons()) { + draw_arrow(en, en - b, aht, lt, + graphic_object::get_outline_color()); + } else { + position v = b; + theta = fabs(lt.thickness) / 72 / 4 / rad; + if (!clockwise) + theta = - theta; + b = en - cent; + b = position(b.x*cos(theta) - b.y*sin(theta), + b.x*sin(theta) + b.y*cos(theta)) + cent; + draw_arrow(b, b - v, aht, lt, + graphic_object::get_outline_color()); + out->line(b, &v, 1, lt); + } + } + out->arc(sp, cent, ep, lt); + out->reset_color(); +} + +inline double max(double a, double b) +{ + return a > b ? a : b; +} + +void arc_object::update_bounding_box(bounding_box *p) +{ + p->encompass(strt); + p->encompass(en); + position start_offset = strt - cent; + if (start_offset.x == 0.0 && start_offset.y == 0.0) + return; + position end_offset = en - cent; + if (end_offset.x == 0.0 && end_offset.y == 0.0) + return; + double start_quad = atan2(start_offset.y, start_offset.x)/(M_PI/2.0); + double end_quad = atan2(end_offset.y, end_offset.x)/(M_PI/2.0); + if (clockwise) { + double temp = start_quad; + start_quad = end_quad; + end_quad = temp; + } + if (start_quad < 0.0) + start_quad += 4.0; + while (end_quad <= start_quad) + end_quad += 4.0; + double r = max(hypot(start_offset), hypot(end_offset)); + for (int q = int(start_quad) + 1; q < end_quad; q++) { + position offset; + switch (q % 4) { + case 0: + offset.x = r; + break; + case 1: + offset.y = r; + break; + case 2: + offset.x = -r; + break; + case 3: + offset.y = -r; + break; + } + p->encompass(cent + offset); + } +} + +// We ignore the with attribute. The at attribute always refers to the center. + +linear_object *object_spec::make_arc(position *curpos, direction *dirp) +{ + *dirp = dir; + int cw = (flags & IS_CLOCKWISE) != 0; + // compute the start + position startpos; + if (flags & HAS_FROM) + startpos = from; + else + startpos = *curpos; + if (!(flags & HAS_RADIUS)) + lookup_variable("arcrad", &radius); + // compute the end + position endpos; + if (flags & HAS_TO) + endpos = to; + else { + position m(radius, radius); + // Adjust the signs. + if (cw) { + if (dir == DOWN_DIRECTION || dir == LEFT_DIRECTION) + m.x = -m.x; + if (dir == DOWN_DIRECTION || dir == RIGHT_DIRECTION) + m.y = -m.y; + *dirp = direction((dir + 3) % 4); + } + else { + if (dir == UP_DIRECTION || dir == LEFT_DIRECTION) + m.x = -m.x; + if (dir == DOWN_DIRECTION || dir == LEFT_DIRECTION) + m.y = -m.y; + *dirp = direction((dir + 1) % 4); + } + endpos = startpos + m; + } + // compute the center + position centerpos; + if (flags & HAS_AT) + centerpos = at; + else if (startpos == endpos) + centerpos = startpos; + else { + position h = (endpos - startpos)/2.0; + double d = hypot(h); + if (radius <= 0) + radius = .25; + // make the radius big enough + if (radius < d) + radius = d; + double alpha = acos(d/radius); + double theta = atan2(h.y, h.x); + if (cw) + theta -= alpha; + else + theta += alpha; + centerpos = position(cos(theta), sin(theta))*radius + startpos; + } + arc_object *p = new arc_object(cw, startpos, endpos, centerpos); + *curpos = endpos; + return p; +} + +graphic_object *object_spec::make_linear(position *curpos, direction *dirp) +{ + linear_object *obj; + if (type == ARC_OBJECT) + obj = make_arc(curpos, dirp); + else + obj = make_line(curpos, dirp); + if (type == ARROW_OBJECT + && (flags & (HAS_LEFT_ARROW_HEAD|HAS_RIGHT_ARROW_HEAD)) == 0) + flags |= HAS_RIGHT_ARROW_HEAD; + if (obj && (flags & (HAS_LEFT_ARROW_HEAD|HAS_RIGHT_ARROW_HEAD))) { + arrow_head_type a; + int at_start = (flags & HAS_LEFT_ARROW_HEAD) != 0; + int at_end = (flags & HAS_RIGHT_ARROW_HEAD) != 0; + if (flags & HAS_HEIGHT) + a.height = height; + else + lookup_variable("arrowht", &a.height); + if (flags & HAS_WIDTH) + a.width = width; + else + lookup_variable("arrowwid", &a.width); + double solid; + lookup_variable("arrowhead", &solid); + a.solid = solid != 0.0; + obj->add_arrows(at_start, at_end, a); + } + return obj; +} + +object *object_spec::make_object(position *curpos, direction *dirp) +{ + graphic_object *obj = 0; + switch (type) { + case BLOCK_OBJECT: + obj = make_block(curpos, dirp); + break; + case BOX_OBJECT: + obj = make_box(curpos, dirp); + break; + case TEXT_OBJECT: + obj = make_text(curpos, dirp); + break; + case ELLIPSE_OBJECT: + obj = make_ellipse(curpos, dirp); + break; + case CIRCLE_OBJECT: + obj = make_circle(curpos, dirp); + break; + case MOVE_OBJECT: + obj = make_move(curpos, dirp); + break; + case ARC_OBJECT: + case LINE_OBJECT: + case SPLINE_OBJECT: + case ARROW_OBJECT: + obj = make_linear(curpos, dirp); + break; + case MARK_OBJECT: + case OTHER_OBJECT: + default: + assert(0); + break; + } + if (obj) { + if (flags & IS_INVISIBLE) + obj->set_invisible(); + if (text != 0) + obj->add_text(text, (flags & IS_ALIGNED) != 0); + if (flags & IS_DOTTED) + obj->set_dotted(dash_width); + else if (flags & IS_DASHED) + obj->set_dashed(dash_width); + double th; + if (flags & HAS_THICKNESS) + th = thickness; + else + lookup_variable("linethick", &th); + obj->set_thickness(th); + if (flags & IS_OUTLINED) + obj->set_outline_color(outlined); + if (flags & IS_XSLANTED) + obj->set_xslanted(xslanted); + if (flags & IS_YSLANTED) + obj->set_yslanted(yslanted); + if (flags & (IS_DEFAULT_FILLED | IS_FILLED)) { + if (flags & IS_SHADED) + obj->set_fill_color(shaded); + else { + if (flags & IS_DEFAULT_FILLED) + lookup_variable("fillval", &fill); + if (fill < 0.0) + error("bad fill value %1", fill); + else + obj->set_fill(fill); + } + } + } + return obj; +} + +struct string_list { + string_list *next; + char *str; + string_list(char *); + ~string_list(); +}; + +string_list::string_list(char *s) +: next(0), str(s) +{ +} + +string_list::~string_list() +{ + free(str); +} + +/* A path is used to hold the argument to the 'with' attribute. For + example, '.nw' or '.A.s' or '.A'. The major operation on a path is to + take a place and follow the path through the place to place within the + place. Note that '.A.B.C.sw' will work. + + For compatibility with DWB pic, 'with' accepts positions also (this + is incorrectly documented in CSTR 116). */ + +path::path(corner c) +: crn(c), label_list(0), ypath(0), is_position(0) +{ +} + +path::path(position p) +: crn(0), label_list(0), ypath(0), is_position(1) +{ + pos.x = p.x; + pos.y = p.y; +} + +path::path(char *l, corner c) +: crn(c), ypath(0), is_position(0) +{ + label_list = new string_list(l); +} + +path::~path() +{ + while (label_list) { + string_list *tem = label_list; + label_list = label_list->next; + delete tem; + } + delete ypath; +} + +void path::append(corner c) +{ + assert(crn == 0); + crn = c; +} + +void path::append(char *s) +{ + string_list **p; + for (p = &label_list; *p; p = &(*p)->next) + ; + *p = new string_list(s); +} + +void path::set_ypath(path *p) +{ + ypath = p; +} + +// return non-zero for success + +int path::follow(const place &pl, place *result) const +{ + if (is_position) { + result->x = pos.x; + result->y = pos.y; + result->obj = 0; + return 1; + } + const place *p = &pl; + for (string_list *lb = label_list; lb; lb = lb->next) + if (p->obj == 0 || (p = p->obj->find_label(lb->str)) == 0) { + lex_error("object does not contain a place '%1'", lb->str); + return 0; + } + if (crn == 0 || p->obj == 0) + *result = *p; + else { + position ps = ((p->obj)->*(crn))(); + result->x = ps.x; + result->y = ps.y; + result->obj = 0; + } + if (ypath) { + place tem; + if (!ypath->follow(pl, &tem)) + return 0; + result->y = tem.y; + if (result->obj != tem.obj) + result->obj = 0; + } + return 1; +} + +void print_object_list(object *p) +{ + for (; p; p = p->next) { + p->print(); + p->print_text(); + } +} + +void print_picture(object *obj) +{ + bounding_box bb; + for (object *p = obj; p; p = p->next) + p->update_bounding_box(&bb); + double scale; + lookup_variable("scale", &scale); + out->start_picture(scale, bb.ll, bb.ur); + print_object_list(obj); + out->finish_picture(); +} + diff --git a/src/preproc/pic/object.h b/src/preproc/pic/object.h new file mode 100644 index 0000000..e39b6a6 --- /dev/null +++ b/src/preproc/pic/object.h @@ -0,0 +1,227 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +struct place; + +enum object_type { + OTHER_OBJECT, + BOX_OBJECT, + CIRCLE_OBJECT, + ELLIPSE_OBJECT, + ARC_OBJECT, + SPLINE_OBJECT, + LINE_OBJECT, + ARROW_OBJECT, + MOVE_OBJECT, + TEXT_OBJECT, + BLOCK_OBJECT, + MARK_OBJECT + }; + +struct bounding_box; + +struct object { + object *prev; + object *next; + object(); + virtual ~object(); + virtual position origin(); + virtual double width(); + virtual double radius(); + virtual double height(); + virtual position north(); + virtual position south(); + virtual position east(); + virtual position west(); + virtual position north_east(); + virtual position north_west(); + virtual position south_east(); + virtual position south_west(); + virtual position start(); + virtual position end(); + virtual position center(); + virtual place *find_label(const char *); + virtual void move_by(const position &); + virtual int blank(); + virtual void update_bounding_box(bounding_box *); + virtual object_type type() = 0; + virtual void print(); + virtual void print_text(); +}; + +typedef position (object::*corner)(); + +struct place { + object *obj; + double x, y; +}; + +struct string_list; + +class path { + position pos; + corner crn; + string_list *label_list; + path *ypath; + int is_position; +public: + path(corner = 0); + path(position); + path(char *, corner = 0); + ~path(); + void append(corner); + void append(char *); + void set_ypath(path *); + int follow(const place &, place *) const; +}; + +struct object_list { + object *head; + object *tail; + object_list(); + void append(object *); + void wrap_up_block(object_list *); +}; + +declare_ptable(place) + +// these go counterclockwise +enum direction { + RIGHT_DIRECTION, + UP_DIRECTION, + LEFT_DIRECTION, + DOWN_DIRECTION + }; + +struct graphics_state { + double x, y; + direction dir; +}; + +struct saved_state : public graphics_state { + saved_state *prev; + PTABLE(place) *tbl; +}; + + +struct text_item { + text_item *next; + char *text; + adjustment adj; + const char *filename; + int lineno; + + text_item(char *, const char *, int); + ~text_item(); +}; + +const unsigned long IS_DOTTED = 01; +const unsigned long IS_DASHED = 02; +const unsigned long IS_CLOCKWISE = 04; +const unsigned long IS_INVISIBLE = 020; +const unsigned long HAS_LEFT_ARROW_HEAD = 040; +const unsigned long HAS_RIGHT_ARROW_HEAD = 0100; +const unsigned long HAS_SEGMENT = 0200; +const unsigned long IS_SAME = 0400; +const unsigned long HAS_FROM = 01000; +const unsigned long HAS_AT = 02000; +const unsigned long HAS_WITH = 04000; +const unsigned long HAS_HEIGHT = 010000; +const unsigned long HAS_WIDTH = 020000; +const unsigned long HAS_RADIUS = 040000; +const unsigned long HAS_TO = 0100000; +const unsigned long IS_CHOPPED = 0200000; +const unsigned long IS_DEFAULT_CHOPPED = 0400000; +const unsigned long HAS_THICKNESS = 01000000; +const unsigned long IS_FILLED = 02000000; +const unsigned long IS_DEFAULT_FILLED = 04000000; +const unsigned long IS_ALIGNED = 010000000; +const unsigned long IS_SHADED = 020000000; +const unsigned long IS_OUTLINED = 040000000; +const unsigned long IS_XSLANTED = 0100000000; +const unsigned long IS_YSLANTED = 0200000000; + +struct segment { + int is_absolute; + position pos; + segment *next; + segment(const position &, int, segment *); +}; + +class rectangle_object; +class graphic_object; +class linear_object; + +struct object_spec { + unsigned long flags; + object_type type; + object_list oblist; + PTABLE(place) *tbl; + double dash_width; + position from; + position to; + position at; + position by; + path *with; + text_item *text; + double height; + double radius; + double width; + double segment_width; + double segment_height; + double start_chop; + double end_chop; + double thickness; + double fill; + double xslanted; + double yslanted; + char *shaded; + char *outlined; + direction dir; + segment *segment_list; + position segment_pos; + int segment_is_absolute; + + object_spec(object_type); + ~object_spec(); + object *make_object(position *, direction *); + graphic_object *make_box(position *, direction *); + graphic_object *make_block(position *, direction *); + graphic_object *make_text(position *, direction *); + graphic_object *make_ellipse(position *, direction *); + graphic_object *make_circle(position *, direction *); + linear_object *make_line(position *, direction *); + linear_object *make_arc(position *, direction *); + graphic_object *make_linear(position *, direction *); + graphic_object *make_move(position *, direction *); + int position_rectangle(rectangle_object *p, position *curpos, + direction *dirp); +}; + + +object *make_object(object_spec *, position *, direction *); + +object *make_mark_object(); +object *make_command_object(char *, const char *, int); + +int lookup_variable(const char *name, double *val); +void define_variable(const char *name, double val); + +void print_picture(object *); + diff --git a/src/preproc/pic/output.h b/src/preproc/pic/output.h new file mode 100644 index 0000000..f01e0a1 --- /dev/null +++ b/src/preproc/pic/output.h @@ -0,0 +1,82 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +struct line_type { + enum { invisible, solid, dotted, dashed } type; + double dash_width; + double thickness; // the thickness is in points + + line_type(); +}; + + +class output { +protected: + char *args; + double desired_height; // zero if no height specified + double desired_width; // zero if no depth specified + double compute_scale(double, const position &, const position &); +public: + output(); + virtual ~output(); + void set_desired_width_height(double wid, double ht); + void set_args(const char *); + virtual void start_picture(double sc, const position &ll, const position &ur) = 0; + virtual void finish_picture() = 0; + virtual void circle(const position &, double rad, + const line_type &, double) = 0; + virtual void text(const position &, text_piece *, int, double) = 0; + virtual void line(const position &, const position *, int n, + const line_type &) = 0; + virtual void polygon(const position *, int n, + const line_type &, double) = 0; + virtual void spline(const position &, const position *, int n, + const line_type &) = 0; + virtual void arc(const position &, const position &, const position &, + const line_type &) = 0; + virtual void ellipse(const position &, const distance &, + const line_type &, double) = 0; + virtual void rounded_box(const position &, const distance &, double, + const line_type &, double, char *) = 0; + virtual void command(const char *, const char *, int) = 0; + virtual void set_location(const char *, int) {} + virtual void set_color(char *, char *) = 0; + virtual void reset_color() = 0; + virtual char *get_last_filled() = 0; + virtual char *get_outline_color() = 0; + virtual int supports_filled_polygons(); + virtual void begin_block(const position &ll, const position &ur); + virtual void end_block(); +}; + +extern output *out; + +/* #define FIG_SUPPORT 1 */ +#define TEX_SUPPORT 1 + +output *make_troff_output(); + +#ifdef TEX_SUPPORT +output *make_tex_output(); +output *make_tpic_output(); +#endif /* TEX_SUPPORT */ + +#ifdef FIG_SUPPORT +output *make_fig_output(); +#endif /* FIG_SUPPORT */ diff --git a/src/preproc/pic/pic.1.man b/src/preproc/pic/pic.1.man new file mode 100644 index 0000000..727cbc3 --- /dev/null +++ b/src/preproc/pic/pic.1.man @@ -0,0 +1,1569 @@ +.TH @g@pic @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +@g@pic \- compile pictures for +.I troff +or TeX +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1989-2020 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_pic_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.\" Definitions +.\" ==================================================================== +. +.ie t \{\ +. ds tx T\h'-.1667m'\v'.224m'E\v'-.224m'\h'-.125m'X +. ds lx L\h'-0.36m'\v'-0.22v'\s-2A\s0\h'-0.15m'\v'0.22v'\*[tx] +.\} +.el \{\ +. ds tx TeX +. ds lx LaTeX +.\} +. +.ie \n(.g .ds ic \/ +.el .ds ic \^ +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY @g@pic +.RB [ \-CnSU ] +.RI [ file\~ .\|.\|.] +.YS +. +. +.SY @g@pic +.B \-t +.RB [ \-cCSUz ] +.RI [ file\~ .\|.\|.] +.YS +. +. +.SY @g@pic +.B \-\-help +.YS +. +. +.SY @g@pic +.B \-v +. +.SY @g@pic +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +The GNU implementation of +.I pic \" generic +is part of the +.MR groff @MAN1EXT@ +document formatting system. +. +.I @g@pic +is a +.MR @g@troff @MAN1EXT@ +preprocessor that translates descriptions of diagrammatic pictures +embedded in +.MR roff @MAN7EXT@ +or \*[tx] input files into the language understood by \*[tx] or +.IR @g@troff . +. +It copies the contents of each +.I file +to the standard output stream, +except that lines between +.B .PS +and any of +.BR .PE , +.BR .PF , +or +.B .PY +are interpreted as picture descriptions in the +.I pic +language. +. +End a +.I @g@pic +picture with +.B .PE +to leave the drawing position at the bottom of the picture, +and with +.B .PF +or +.B .PY +to leave it at the top. +. +Normally, +.I @g@pic +is not executed directly by the user, +but invoked by specifying the +.B \-p +option to +.MR groff @MAN1EXT@ . +. +If no +.I file +operands are given on the command line, +or if +.I file +is +.RB \[lq] \- \[rq], +the standard input stream is read. +. +. +.P +It is the user's responsibility to provide appropriate definitions +of the +.BR PS , +.BR PE , +and one or both of the +.B PF +and +.B PY +macros. +. +When a macro package does not supply these, +obtain simple definitions with the +.I groff +option +.BR \-mpic ; +these will center each picture. +. +. +.P +GNU +.I pic \" GNU +supports +.B PY +as a synonym of +.B PF +to work around a name space collision with the +.I mm +macro package, +which defines +.B PF +as a page footer management macro. +. +Use +.B PF +preferentially unless a similar problem faces your document. +. +. +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-\-help +displays a usage message, +while +.B \-v +and +.B \-\-version +show version information; +all exit afterward. +. +. +.TP +.B \-c +Be more compatible with +.IR tpic ; +implies +.BR \-t . +. +Lines beginning with +.B \[rs] +are not passed through transparently. +. +Lines beginning with +.B .\& +are passed through with the initial +.B .\& +changed to +.BR \[rs] . +. +A line beginning with +.B .ps +is given special treatment: +it takes an optional integer argument specifying the line thickness +(pen size) +in milliinches; +a missing argument restores the previous line thickness; +the default line thickness is 8\~milliinches. +. +The line thickness thus specified takes effect only when a +non-negative line thickness has not been specified by use of the +.B \%thickness +attribute or by setting the +.B \%linethick +variable. +. +. +.TP +.B \-C +Recognize +.BR .PS , +.BR .PE , +.BR .PF , +and +.B .PY +even when followed by a character other than space or newline. +. +. +.TP +.B \-n +Don't use +.I groff +extensions to the +.I troff \" generic +drawing commands. +. +Specify this option if a postprocessor you're using doesn't support +these extensions, +described in +.MR groff_out @MAN5EXT@ . +. +This option also causes +.I @g@pic +not to use zero-length lines to draw dots in +.I troff \" generic +mode. +. +. +.TP +.B \-S +Operate in +.I safer mode; +.B sh +commands are ignored. +. +This mode, +enabled by default, +can be useful when operating on untrustworthy input. +. +. +.TP +.B \-t +Produce \*[tx] output. +. +. +.TP +.B \-U +Operate in +.I unsafe mode; +.B sh +commands are interpreted. +. +. +.TP +.B \-z +In \*[tx] mode, +draw dots using zero-length lines. +. +. +.P +The following options supported by other versions of +.I pic \" generic +are ignored. +. +. +.TP +.B \-D +Draw all lines using the \[rs]D escape sequence. +GNU +.I pic \" GNU +always does this. +. +.TP +.BI \-T\~ dev +Generate output for the +.I troff \" generic +device +.IR dev . +. +This is unnecessary because the +.I troff \" generic +output generated by +GNU +.I pic \" GNU +is device-independent. +. +. +.\" ==================================================================== +.SH Usage +.\" ==================================================================== +. +This section primarily discusses the differences between GNU +.I pic \" GNU +and the Eighth Edition Research Unix version of AT&T +.I pic \" AT&T +(1985). +. +Many of these differences also apply to later versions of AT&T +.IR pic . +. +. +.\" ==================================================================== +.SS "\*[tx] mode" +.\" ==================================================================== +. +\*[tx]-compatible output is produced when the +.B \-t +option is specified. +. +You must use a \*[tx] driver that supports +.I tpic +version 2 specials. +. +.RI ( tpic +was a fork of AT&T +.I pic \" AT&T +by Tim Morgan of the University of California at Irvine that diverged +from its source around 1984. +. +It is best known today for lending its name to a group of +.B \[rs]special +commands it produced for \*[tx].) +.\" http://ftp.cs.stanford.edu/tex/texhax/texhax90.019 +. +. +.P +Lines beginning with +.B \[rs] +are passed through transparently; +a +.B % +is added to the end of the line to avoid unwanted spaces. +. +You can safely use this feature to change fonts or the value of +.BR \[rs]baselineskip . +. +Anything else may well produce undesirable results; +use at your own risk. +. +By default, +lines beginning with a dot are not treated specially\[em]but see the +.B \-c +option. +. +. +.P +In \*[tx] mode, +.I @g@pic +will define a vbox called +.B \[rs]graph +for each picture. +. +Use GNU +.IR pic 's \" GNU +.B figname +command to change the name of the vbox. +. +You must print that vbox yourself using the command +. +.RS +.EX +\[rs]centerline{\[rs]box\[rs]graph} +.EE +.RE +. +for instance. +. +Since the vbox has a height of zero +(it is defined with +.BR \[rs]vtop ) +this will produce slightly more vertical space above the picture than +below it; +. +.RS +.EX +\[rs]centerline{\[rs]raise 1em\[rs]box\[rs]graph} +.EE +.RE +. +would avoid this. +. +To give the vbox a positive height and a depth of zero +(as used by \*[lx]'s +.IR \%graphics.sty , +for example) +define the following macro in your document. +. +.RS +.EX +\[rs]def\[rs]gpicbox#1{% + \[rs]vbox{\[rs]unvbox\[rs]csname #1\[rs]endcsname\[rs]kern 0pt}} +.EE +.RE +. +You can then simply say +.B \[rs]gpicbox{graph} +instead of +.BR \[rs]box\[rs]graph . +. +. +.\" ==================================================================== +.SS Commands +.\" ==================================================================== +. +Several commands new to GNU +.I pic \" GNU +accept delimiters, +shown in their synopses as braces +.BR "{ }" . +. +Nesting of braces is supported. +. +Any other characters +(except a space, +tab, +or newline) +.\" XXX even crazy control characters, ugh--src/preproc/pic/lex.cpp:1266 +may be used as alternative delimiters, +in which case the members of a given pair must be identical. +. +Strings are recognized within delimiters of either kind; +they may contain the delimiter character or unbalanced braces. +. +. +.TP +\fBfor\fR \fIvariable\fR \fB=\fR \fIexpr1\fR \fBto\fR \fIexpr2\fR \ +[\fBby\fR [\fB*\fR]\,\fIexpr3\/\fR] \fBdo\fR \fIX\fR \fIbody\fR \fIX\fR +Set +.I variable +to +.IR expr1 . +. +While the value of +.I variable +is less than or equal to +.IR expr2 , +do +.I body +and increment +.I variable +by +.IR expr3 ; +if +.B by +is not given, +increment +.I variable +by 1. +. +If +.I expr3 +is prefixed by +.B * +then +.I variable +will instead be multiplied by +.IR expr3 . +. +The value of +.I expr3 +can be negative for the additive case; +.I variable +is then tested whether it is greater than or equal to +.IR expr2 . +. +For the multiplicative case, +.I expr3 +must be greater than zero. +. +If the constraints aren't met, +the loop isn't executed. +. +.I X +can be any character not occurring in +.IR body . +. +.TP +\fBif\fR \fIexpr\fR \fBthen\fR \fIX\fR \fIif-true\fR \fIX\fR \ +[\fBelse\fR \fIY\fR \fIif-false\fR \fIY\fR] +Evaluate +.IR expr ; +if it is non-zero then do +.IR if-true , +otherwise do +.IR if-false . +. +.I X +can be any character not occurring in +.IR if-true . +. +.I Y +can be any character not occurring in +.IR if-false . +. +.TP +.BI print\~ arg\c +\~.\|.\|. +Concatenate and write arguments to the standard error stream followed by +a newline. +. +Each +.I arg +must be an expression, +a position, +or text. +. +This is useful for debugging. +. +.TP +.BI command\~ arg\c +\~.\|.\|. +.\" Move right margin to indentation since we must indent more later. +.RS +Concatenate arguments +and pass them as a line to +.I troff \" generic +or \*[tx]. +. +Each +.I arg +must be an expression, +a position, +or text. +. +.B command +allows the values of +.I pic +variables to be passed to the formatter. +. +For example, +. +.RS +.EX +\&.PS +x = 14 +command ".ds string x is " x "." +\&.PE +\[rs]*[string] +.EE +.RE +. +produces +. +.RS +.EX +x is 14. +.EE +.RE +when formatted with +.IR troff . \" generic +.RE +. +. +.TP +\fBsh\fR \fIX\fR \fIcommand\fR \fIX\fR +Pass +.I command +to a shell. +. +. +.TP +\fBcopy\fR \fB"\,\fIfilename\/\fB"\fR +Include +.I filename +at this point in the file. +. +. +.TP +.BR copy\~ [ \[dq]\c +.IB filename \[dq]\c +.RB ]\~ thru\~\c +.IR "X body X" \~\c \" space in roman: we must use 2-font macro with \c +.RB [ until\~ \[dq]\c +.IB word \[dq]\c +] +.TQ +.BR copy\~ [ \[dq]\c +.IB filename \[dq]\c +.RB ]\~ thru\~\c +.IR macro \~\c \" space roman because we must use 2-font macro with \c +.RB [ until\~ \[dq]\c +.IB word \[dq]\c +] +.\" Move right margin to indentation since we must indent more later. +.RS +This construct does +.I body +once for each line of +.IR filename ; +the line is split into blank-delimited words, +and occurrences of +.BI $ i +in +.IR body , +for +.I i +between 1 and 9, +are replaced by the +.IR i -th +word of the line. +. +If +.I filename +is not given, +lines are taken from the current input up to +.BR .PE . +. +If an +.B until +clause is specified, +lines will be read only until a line the first word of which is +.IR word ; +that line will then be discarded. +. +.I X +can be any character not occurring in +.IR body . +. +For example, +. +.RS \" now move further +.EX +\&.PS +copy thru % circle at ($1,$2) % until "END" +1 2 +3 4 +5 6 +END +box +\&.PE +.EE +.RE +. +and +. +.RS +.EX +\&.PS +circle at (1,2) +circle at (3,4) +circle at (5,6) +box +\&.PE +.EE +.RE +. +are equivalent. +. +The commands to be performed for each line can also be taken from a +macro defined earlier by giving the name of the macro as the argument to +.BR thru . +. +The argument after +.B thru +is looked up as a macro name first; +if not defined, +its first character is interpreted as a delimiter. +.RE +. +. +.TP +.B reset +.TQ +.BI reset\~ pvar1\c +.RB [ , ]\~\c +.IR pvar2 \~.\|.\|. +Reset predefined variables +.IR pvar1 , +.I pvar2 +\&.\|.\|.\& to their default values; +if no arguments are given, +reset all predefined variables to their default values. +. +Variable names may be separated by commas, +spaces, +or both. +. +Assigning a value to +.B scale +also causes all predefined variables that control dimensions to be reset +to their default values times the new value of +.BR scale . +. +. +.TP +\fBplot\fR \fIexpr\fR [\fB"\,\fItext\*(ic\fB"\fR] +This is a text object which is constructed by using +.I text +as a format string for sprintf +with an argument of +.IR expr . +. +If +.I text +is omitted a format string of +.B \[dq]%g\[dq] +is used. +. +Attributes can be specified in the same way as for a normal text +object. +Be very careful that you specify an appropriate format string; +.I @g@pic +does only very limited checking of the string. +. +This is deprecated in favour of +.BR sprintf . +. +.TP +.IB var \~:=\~ expr +.RS +This syntax resembles variable assignment with +.B = +except that +.I var +must already be defined, +and +.I expr +will be assigned to +.I var +without creating a variable local to the current block. +. +(By contrast, +.B = +defines +.I var +in the current block if it is not already defined there, +and then changes the value in the current block only.) +. +For example, +. +.RS +.EX +.B .PS +.B x = 3 +.B y = 3 +.B [ +.B x := 5 +.B y = 5 +.B ] +.B print x " " y +.B .PE +.EE +.RE +. +writes +. +.RS +.EX +5 3 +.EE +.RE +. +to the standard error stream. +.RE +. +. +.\" ==================================================================== +.SS Expressions +.\" ==================================================================== +. +The syntax for expressions has been significantly extended. +. +. +.P +.IB x\ \[ha]\ y +(exponentiation) +.br +.BI sin( x ) +.br +.BI cos( x ) +.br +.BI atan2( y , \ x ) +.br +.BI log( x ) +(base 10) +.br +.BI exp( x ) +(base 10, i.e.\& +.ie t 10\v'-.4m'\fIx\*(ic\fR\v'.4m') +.el 10\[ha]\fIx\fR) +.br +.BI sqrt( x ) +.br +.BI int( x ) +.br +.B rand() +(return a random number between 0 and 1) +.br +.BI rand( x ) +(return a random number between 1 and +.IR x ; +deprecated) +.br +.BI srand( x ) +(set the random number seed) +.br +.BI max( e1 , \ e2 ) +.br +.BI min( e1 , \ e2 ) +.br +.BI ! e +.br +\fIe1\fB && \fIe2\fR +.br +\fIe1\fB || \fIe2\fR +.br +\fIe1\fB == \fIe2\fR +.br +\fIe1\fB != \fIe2\fR +.br +\fIe1\fB >= \fIe2\fR +.br +\fIe1\fB > \fIe2\fR +.br +\fIe1\fB <= \fIe2\fR +.br +\fIe1\fB < \fIe2\fR +.br +\fB"\,\fIstr1\*(ic\fB" == "\,\fIstr2\*(ic\fB"\fR +.br +\fB"\,\fIstr1\*(ic\fB" != "\,\fIstr2\*(ic\fB"\fR +.br +. +. +.LP +String comparison expressions must be parenthesised in some contexts +to avoid ambiguity. +. +. +.\" ==================================================================== +.SS "Other changes" +.\" ==================================================================== +. +A bare expression, +.IR expr , +is acceptable as an attribute; +it is equivalent to +.IR dir\ expr , +where +.I dir +is the current direction. +. +For example +.LP +.RS +.B line 2i +.RE +.LP +means draw a line 2\ inches long in the current direction. +. +The \[oq]i\[cq] +(or \[oq]I\[cq]) +character is ignored; +to use another measurement unit, +set the +.I scale +variable to an appropriate value. +. +. +.LP +The maximum width and height of the picture are taken from the variables +.B maxpswid +and +.BR maxpsht . +. +Initially, +these have values 8.5 and 11. +. +. +.LP +Scientific notation is allowed for numbers. +For example +. +. +.RS +.LP +.B +x = 5e\-2 +.RE +. +. +.LP +Text attributes can be compounded. +. +For example, +. +.RS +.LP +.B +"foo" above ljust +.RE +. +. +.LP +is valid. +. +. +.LP +There is no limit to the depth to which blocks can be examined. +. +For example, +.RS +.LP +.EX +[A: [B: [C: box ]]] with .A.B.C.sw at 1,2 +circle at last [\^].A.B.C +.EE +.RE +. +. +.LP +is acceptable. +. +. +.LP +Arcs now have compass points determined by the circle of which the arc +is a part. +. +. +.LP +Circles, +ellipses, +and arcs can be dotted or dashed. +. +In \*[tx] mode splines can be dotted or dashed also. +. +. +.LP +Boxes can have rounded corners. +. +The +.B rad +attribute specifies the radius of the quarter-circles at each corner. +If no +.B rad +or +.B diam +attribute is given, +a radius of +.B boxrad +is used. +. +Initially, +.B boxrad +has a value of\ 0. +. +A box with rounded corners can be dotted or dashed. +. +. +.LP +Boxes can have slanted sides. +. +This effectively changes the shape of a box from a rectangle to an +arbitrary parallelogram. +. +The +.B xslanted +and +.B yslanted +attributes specify the x and y\~offset of the box's upper right +corner from its default position. +. +. +.LP +The +.B .PS +line can have a second argument specifying a maximum height for +the picture. +. +If the width of zero is specified the width will be ignored in computing +the scaling factor for the picture. +. +GNU +.I pic \" GNU +will always scale a picture by the same amount vertically as well as +horizontally. +. +This is different from DWB 2.0 +.I pic \" foreign +which may scale a picture by a different amount vertically than +horizontally if a height is specified. +. +. +.LP +Each text object has an invisible box associated with it. +. +The compass points of a text object are determined by this box. +. +The implicit motion associated with the object is also determined +by this box. +. +The dimensions of this box are taken from the width and height +attributes; +if the width attribute is not supplied then the width will be taken to +be +.BR textwid ; +if the height attribute is not supplied then the height will be taken to +be the number of text strings associated with the object times +.BR textht . +. +Initially, +.B textwid +and +.B textht +have a value of 0. +. +. +.LP +In +(almost all) +places where a quoted text string can be used, +an expression of the form +. +. +.IP +.BI sprintf(\[dq] format \[dq],\~ arg ,\fR\~.\|.\|.\fB) +. +. +.LP +can also be used; +this will produce the arguments formatted according to +.IR format , +which should be a string as described in +.MR printf 3 +appropriate for the number of arguments supplied. +. +Only the modifiers +.RB \[lq] # \[rq], +.RB \[lq] \- \[rq], +.RB \[lq] + \[rq], +and \[lq]\~\[rq] [space]), +a minimum field width, +an optional precision, +and the conversion specifiers +.BR %e , +.BR %E , +.BR %f , +.BR %g , +.BR %G , +and +.B %% +are supported. +. +. +.LP +The thickness of the lines used to draw objects is controlled by the +.B linethick +variable. +. +This gives the thickness of lines in points. +. +A negative value means use the default thickness: +in \*[tx] output mode, +this means use a thickness of 8 milliinches; +in \*[tx] output mode with the +.B \-c +option, +this means use the line thickness specified by +.B .ps +lines; +in +.I troff +output mode, +this means use a thickness proportional to the pointsize. +. +A zero value means draw the thinnest possible line supported by +the output device. +. +Initially, +it has a value of \-1. +. +There is also a +.BR thick [ ness ] +attribute. +. +For example, +. +. +.RS +.LP +.B circle thickness 1.5 +.RE +. +. +.LP +would draw a circle using a line with a thickness of 1.5 points. +. +The thickness of lines is not affected by the +value of the +.B scale +variable, +nor by the width or height given in the +.B .PS +line. +. +. +.LP +Boxes +(including boxes with rounded corners or slanted sides), +circles and ellipses can be filled by giving them an attribute of +.BR fill [ ed ]. +. +This takes an optional argument of an expression with a value between +0 and 1; +0 will fill it with white, +1 with black, +values in between with a proportionally gray shade. +. +A value greater than 1 can also be used: +this means fill with the +shade of gray that is currently being used for text and lines. +. +Normally this will be black, +but output devices may provide a mechanism for changing this. +. +Without an argument, +then the value of the variable +.B \%fillval +will be used. +. +Initially, +this has a value of 0.5. +. +The invisible attribute does not affect the filling of objects. +. +Any text associated with a filled object will be added after the object +has been filled, +so that the text will not be obscured by the filling. +. +. +.P +Additional modifiers are available to draw colored objects: +.BR \%outline [ d ] +sets the color of the outline, +.B shaded +the fill color, +and +.BR colo [ u ] r [ ed ] +sets both. +. +All expect a subsequent string argument specifying the color. +. +.RS +.EX +circle shaded \[dq]green\[dq] outline \[dq]black\[dq] +.EE +.RE +. +Color is not yet supported in \*[tx] mode. +. +Device macro files like +.I ps.tmac +declare color names; +you can define additional ones with the +.B \%defcolor +request +(see +.MR groff @MAN7EXT@ ). +. +. +.LP +To change the name of the vbox in \*[tx] mode, +set the pseudo-variable +.B \%figname +(which is actually a specially parsed command) +within a picture. +. +Example: +.RS +.LP +.B .PS +.br +.B figname = foobar; +.br +.B ... +.br +.B .PE +.RE +. +. +.LP +The picture is then available in the box +.BR \[rs]foobar . +. +. +.LP +.I @g@pic +assumes that at the beginning of a picture both glyph and fill color are +set to the default value. +. +. +.LP +Arrow heads will be drawn as solid triangles if the variable +.B arrowhead +is non-zero and either \*[tx] mode is enabled or the +.B \-n +option has not been given. +. +Initially, +.B arrowhead +has a value of\ 1. +. +Solid arrow heads are always filled with the current outline color. +. +. +.LP +The +.I troff +output of +.I @g@pic +is device-independent. +. +The +.B \-T +option is therefore redundant. +. +All numbers are taken to be in inches; +numbers are never interpreted to be in +.I troff +machine units. +. +. +.LP +Objects can have an +.B aligned +attribute. +. +This will only work if the postprocessor is +.MR grops @MAN1EXT@ +or +.MR gropdf @MAN1EXT@ . +. +Any text associated with an object having the +.B aligned +attribute will be rotated about the center of the object +so that it is aligned in the direction from the start point +to the end point of the object. +. +This attribute will have no effect on objects whose start and end points +are coincident. +. +. +.LP +In places where +.IB n th +is allowed, +.BI \[aq] expr \[aq]th +is also allowed. +. +.RB \[lq] \[aq]th \[lq] +is a single token: +no space is allowed between the apostrophe and the +.RB \[lq] th \[rq]. +. +. +For example, +.IP +.EX +for i = 1 to 4 do { + line from \[aq]i\[aq]th box.nw to \[aq]i+1\[aq]th box.se +} +.EE +. +. +.\" ==================================================================== +.SH Conversion +.\" ==================================================================== +. +To obtain a stand-alone picture from a +.I @g@pic +file, +enclose your +.I pic \" language +code with +.B .PS +and +.B .PE +requests; +.I roff +configuration commands may be added at the beginning of the file, +but no +.I roff +text. +. +. +.LP +It is necessary to feed this file into +.I groff +without adding any page information, +so you must check which +.B .PS +and +.B .PE +requests are actually called. +. +For example, +the +.I mm +macro package adds a page number, +which is very annoying. +. +At the moment, +calling standard +.I groff +without any macro package works. +. +Alternatively, +you can define your own requests, +e.g., +to do nothing: +. +. +.LP +.RS +.EX +\&.de PS +\&.. +\&.de PE +\&.. +.EE +.RE +. +. +.LP +.I groff +itself does not provide direct conversion into other graphics file +formats. +. +But there are lots of possibilities if you first transform your +picture into PostScript\*R format using the +.I groff +option +.BR \-Tps . +. +Since this +.IR ps -file +lacks BoundingBox information it is not very useful by itself, but it +may be fed into other conversion programs, usually named +.BI ps2 other +or +.BI psto other +or the like. +. +Moreover, +the PostScript interpreter Ghostscript +.RI ( gs (1)) +has built-in graphics conversion devices that are called with the option +. +. +.LP +.RS +.BI "gs \-sDEVICE=" +.RE +. +. +.LP +Call +. +. +.LP +.RS +.B gs \-\-help +.RE +. +. +.LP +for a list of the available devices. +. +. +.LP +An alternative may be to use the +.B \-Tpdf +option to convert your picture directly into +.B PDF +format. +. +The MediaBox of the file produced can be controlled by passing a +.B \-P\-p +papersize to +.IR groff . +. +. +.br +.ne 3v +.P +As the Encapsulated PostScript File Format +.B EPS +is getting more and more important, +and the conversion wasn't regarded trivial in the past you might be +interested to know that there is a conversion tool named +.I ps2eps +which does the right job. +. +It is much better than the tool +.I ps2epsi +packaged with +.IR gs . +. +. +.LP +For bitmapped graphic formats, +you should use +.IR pstopnm ; +the resulting (intermediate) +.MR pnm 5 +file can be then converted to virtually any graphics format using the +tools of the +.B netpbm +package. +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.I @MACRODIR@/pic.tmac +offers simple definitions of the +.BR PS , +.BR PE , +.BR PF , +and +.B PY +macros. +. +. +.\" ==================================================================== +.SH Bugs +.\" ==================================================================== +. +Characters that are invalid as input to GNU +.I troff \" GNU +(see the +.I groff +Texinfo manual or +.MR groff_char @MAN7EXT@ +for a list) +are rejected even in \*[tx] mode. +. +. +.LP +The interpretation of +.B \%fillval +is incompatible with the +.I pic \" AT&T +in Tenth Edition Research Unix, +which interprets 0 as black and 1 as white. +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.TP +.I @DOCDIR@/\:pic\:.ps +\[lq]Making Pictures with GNU pic\[rq], +by Eric S.\& Raymond. +. +This file, +together with its source, +.IR pic.ms , +is part of the +.I groff +distribution. +. +. +.P +\[lq]PIC\[em]A Graphics Language for Typesetting: User Manual\[rq], +by Brian W.\& Kernighan, +1984 +(revised 1991), +AT&T Bell Laboratories Computing Science Technical Report No.\& 116 +. +. +.P +.I ps2eps +is available from CTAN mirrors, e.g., +.UR ftp://\:ftp\:.dante\:.de/\:tex\-archive/\:support/\:ps2eps/ +.UE +. +. +.LP +W.\& Richard Stevens, +.UR http://\:www\:.kohala\:.com/\:start/\:troff/\:pic2html\:.html +.I Turning PIC into HTML +.UE +. +. +.LP +W.\& Richard Stevens, +.UR http://\:www\:.kohala\:.com/\:start/\:troff/\:pic\:.examples\:.ps +.IR "Examples of " pic " Macros" +.UE +. +. +.LP +.MR @g@troff @MAN1EXT@ , +.MR groff_out @MAN5EXT@ , +.MR tex 1 , +.MR gs 1 , +.MR ps2eps 1 , +.MR pstopnm 1 , +.MR ps2epsi 1 , +.MR pnm 5 +. +. +.\" Clean up. +.rm tx +.rm lx +.rm ic +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_pic_1_man_C] +.do rr *groff_pic_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/preproc/pic/pic.am b/src/preproc/pic/pic.am new file mode 100644 index 0000000..fae1372 --- /dev/null +++ b/src/preproc/pic/pic.am @@ -0,0 +1,56 @@ +# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# +# This file 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 . + +prefixexecbin_PROGRAMS += pic +pic_CPPFLAGS = $(AM_CPPFLAGS) \ + -I $(top_srcdir)/src/preproc/pic \ + -I $(top_builddir)/src/preproc/pic +pic_LDADD = libgroff.a $(LIBM) lib/libgnu.a +pic_SOURCES = \ + src/preproc/pic/pic.ypp \ + src/preproc/pic/lex.cpp \ + src/preproc/pic/main.cpp \ + src/preproc/pic/object.cpp \ + src/preproc/pic/common.cpp \ + src/preproc/pic/troff.cpp \ + src/preproc/pic/tex.cpp \ + src/preproc/pic/pic.h \ + src/preproc/pic/position.h \ + src/preproc/pic/text.h \ + src/preproc/pic/common.h \ + src/preproc/pic/output.h \ + src/preproc/pic/object.h + +PREFIXMAN1 += src/preproc/pic/pic.1 +EXTRA_DIST += \ + src/preproc/pic/TODO \ + src/preproc/pic/pic.1.man + +# Since pic_CPPFLAGS was set, all .o files have a 'pic-' prefix. +src/preproc/pic/pic-lex.$(OBJEXT): src/preproc/pic/pic.hpp + +MAINTAINERCLEANFILES += \ + src/preproc/pic/pic.cpp \ + src/preproc/pic/pic.hpp \ + src/preproc/pic/pic.output + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/preproc/pic/pic.cpp b/src/preproc/pic/pic.cpp new file mode 100644 index 0000000..14b15e4 --- /dev/null +++ b/src/preproc/pic/pic.cpp @@ -0,0 +1,5080 @@ +/* A Bison parser, made by GNU Bison 3.8.2. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output, and Bison version. */ +#define YYBISON 30802 + +/* Bison version string. */ +#define YYBISON_VERSION "3.8.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + + + +/* First part of user prologue. */ +#line 19 "../src/preproc/pic/pic.ypp" + +#include "pic.h" +#include "ptable.h" +#include "object.h" + +extern int delim_flag; +extern void copy_rest_thru(const char *, const char *); +extern void copy_file_thru(const char *, const char *, const char *); +extern void push_body(const char *); +extern void do_for(char *var, double from, double to, + int by_is_multiplicative, double by, char *body); +extern void do_lookahead(); + +/* Maximum number of characters produced by printf("%g") */ +#define GDIGITS 14 + +int yylex(); +void yyerror(const char *); + +void reset(const char *nm); +void reset_all(); + +place *lookup_label(const char *); +void define_label(const char *label, const place *pl); + +direction current_direction; +position current_position; + +implement_ptable(place) + +PTABLE(place) top_table; + +PTABLE(place) *current_table = &top_table; +saved_state *current_saved_state = 0; + +object_list olist; + +const char *ordinal_postfix(int n); +const char *object_type_name(object_type type); +char *format_number(const char *fmt, double n); +char *do_sprintf(const char *fmt, const double *v, int nv); + + +#line 115 "src/preproc/pic/pic.cpp" + +# ifndef YY_CAST +# ifdef __cplusplus +# define YY_CAST(Type, Val) static_cast (Val) +# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) +# else +# define YY_CAST(Type, Val) ((Type) (Val)) +# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) +# endif +# endif +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) +# endif +# endif + +/* Use api.header.include to #include this header + instead of duplicating it here. */ +#ifndef YY_YY_SRC_PREPROC_PIC_PIC_HPP_INCLUDED +# define YY_YY_SRC_PREPROC_PIC_PIC_HPP_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Token kinds. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + YYEMPTY = -2, + YYEOF = 0, /* "end of file" */ + YYerror = 256, /* error */ + YYUNDEF = 257, /* "invalid token" */ + LABEL = 258, /* LABEL */ + VARIABLE = 259, /* VARIABLE */ + NUMBER = 260, /* NUMBER */ + TEXT = 261, /* TEXT */ + COMMAND_LINE = 262, /* COMMAND_LINE */ + DELIMITED = 263, /* DELIMITED */ + ORDINAL = 264, /* ORDINAL */ + TH = 265, /* TH */ + LEFT_ARROW_HEAD = 266, /* LEFT_ARROW_HEAD */ + RIGHT_ARROW_HEAD = 267, /* RIGHT_ARROW_HEAD */ + DOUBLE_ARROW_HEAD = 268, /* DOUBLE_ARROW_HEAD */ + LAST = 269, /* LAST */ + BOX = 270, /* BOX */ + CIRCLE = 271, /* CIRCLE */ + ELLIPSE = 272, /* ELLIPSE */ + ARC = 273, /* ARC */ + LINE = 274, /* LINE */ + ARROW = 275, /* ARROW */ + MOVE = 276, /* MOVE */ + SPLINE = 277, /* SPLINE */ + HEIGHT = 278, /* HEIGHT */ + RADIUS = 279, /* RADIUS */ + FIGNAME = 280, /* FIGNAME */ + WIDTH = 281, /* WIDTH */ + DIAMETER = 282, /* DIAMETER */ + UP = 283, /* UP */ + DOWN = 284, /* DOWN */ + RIGHT = 285, /* RIGHT */ + LEFT = 286, /* LEFT */ + FROM = 287, /* FROM */ + TO = 288, /* TO */ + AT = 289, /* AT */ + WITH = 290, /* WITH */ + BY = 291, /* BY */ + THEN = 292, /* THEN */ + SOLID = 293, /* SOLID */ + DOTTED = 294, /* DOTTED */ + DASHED = 295, /* DASHED */ + CHOP = 296, /* CHOP */ + SAME = 297, /* SAME */ + INVISIBLE = 298, /* INVISIBLE */ + LJUST = 299, /* LJUST */ + RJUST = 300, /* RJUST */ + ABOVE = 301, /* ABOVE */ + BELOW = 302, /* BELOW */ + OF = 303, /* OF */ + THE = 304, /* THE */ + WAY = 305, /* WAY */ + BETWEEN = 306, /* BETWEEN */ + AND = 307, /* AND */ + HERE = 308, /* HERE */ + DOT_N = 309, /* DOT_N */ + DOT_E = 310, /* DOT_E */ + DOT_W = 311, /* DOT_W */ + DOT_S = 312, /* DOT_S */ + DOT_NE = 313, /* DOT_NE */ + DOT_SE = 314, /* DOT_SE */ + DOT_NW = 315, /* DOT_NW */ + DOT_SW = 316, /* DOT_SW */ + DOT_C = 317, /* DOT_C */ + DOT_START = 318, /* DOT_START */ + DOT_END = 319, /* DOT_END */ + DOT_X = 320, /* DOT_X */ + DOT_Y = 321, /* DOT_Y */ + DOT_HT = 322, /* DOT_HT */ + DOT_WID = 323, /* DOT_WID */ + DOT_RAD = 324, /* DOT_RAD */ + SIN = 325, /* SIN */ + COS = 326, /* COS */ + ATAN2 = 327, /* ATAN2 */ + LOG = 328, /* LOG */ + EXP = 329, /* EXP */ + SQRT = 330, /* SQRT */ + K_MAX = 331, /* K_MAX */ + K_MIN = 332, /* K_MIN */ + INT = 333, /* INT */ + RAND = 334, /* RAND */ + SRAND = 335, /* SRAND */ + COPY = 336, /* COPY */ + THRU = 337, /* THRU */ + TOP = 338, /* TOP */ + BOTTOM = 339, /* BOTTOM */ + UPPER = 340, /* UPPER */ + LOWER = 341, /* LOWER */ + SH = 342, /* SH */ + PRINT = 343, /* PRINT */ + CW = 344, /* CW */ + CCW = 345, /* CCW */ + FOR = 346, /* FOR */ + DO = 347, /* DO */ + IF = 348, /* IF */ + ELSE = 349, /* ELSE */ + ANDAND = 350, /* ANDAND */ + OROR = 351, /* OROR */ + NOTEQUAL = 352, /* NOTEQUAL */ + EQUALEQUAL = 353, /* EQUALEQUAL */ + LESSEQUAL = 354, /* LESSEQUAL */ + GREATEREQUAL = 355, /* GREATEREQUAL */ + LEFT_CORNER = 356, /* LEFT_CORNER */ + RIGHT_CORNER = 357, /* RIGHT_CORNER */ + NORTH = 358, /* NORTH */ + SOUTH = 359, /* SOUTH */ + EAST = 360, /* EAST */ + WEST = 361, /* WEST */ + CENTER = 362, /* CENTER */ + END = 363, /* END */ + START = 364, /* START */ + RESET = 365, /* RESET */ + UNTIL = 366, /* UNTIL */ + PLOT = 367, /* PLOT */ + THICKNESS = 368, /* THICKNESS */ + FILL = 369, /* FILL */ + COLORED = 370, /* COLORED */ + OUTLINED = 371, /* OUTLINED */ + SHADED = 372, /* SHADED */ + XSLANTED = 373, /* XSLANTED */ + YSLANTED = 374, /* YSLANTED */ + ALIGNED = 375, /* ALIGNED */ + SPRINTF = 376, /* SPRINTF */ + COMMAND = 377, /* COMMAND */ + DEFINE = 378, /* DEFINE */ + UNDEF = 379 /* UNDEF */ + }; + typedef enum yytokentype yytoken_kind_t; +#endif +/* Token kinds. */ +#define YYEMPTY -2 +#define YYEOF 0 +#define YYerror 256 +#define YYUNDEF 257 +#define LABEL 258 +#define VARIABLE 259 +#define NUMBER 260 +#define TEXT 261 +#define COMMAND_LINE 262 +#define DELIMITED 263 +#define ORDINAL 264 +#define TH 265 +#define LEFT_ARROW_HEAD 266 +#define RIGHT_ARROW_HEAD 267 +#define DOUBLE_ARROW_HEAD 268 +#define LAST 269 +#define BOX 270 +#define CIRCLE 271 +#define ELLIPSE 272 +#define ARC 273 +#define LINE 274 +#define ARROW 275 +#define MOVE 276 +#define SPLINE 277 +#define HEIGHT 278 +#define RADIUS 279 +#define FIGNAME 280 +#define WIDTH 281 +#define DIAMETER 282 +#define UP 283 +#define DOWN 284 +#define RIGHT 285 +#define LEFT 286 +#define FROM 287 +#define TO 288 +#define AT 289 +#define WITH 290 +#define BY 291 +#define THEN 292 +#define SOLID 293 +#define DOTTED 294 +#define DASHED 295 +#define CHOP 296 +#define SAME 297 +#define INVISIBLE 298 +#define LJUST 299 +#define RJUST 300 +#define ABOVE 301 +#define BELOW 302 +#define OF 303 +#define THE 304 +#define WAY 305 +#define BETWEEN 306 +#define AND 307 +#define HERE 308 +#define DOT_N 309 +#define DOT_E 310 +#define DOT_W 311 +#define DOT_S 312 +#define DOT_NE 313 +#define DOT_SE 314 +#define DOT_NW 315 +#define DOT_SW 316 +#define DOT_C 317 +#define DOT_START 318 +#define DOT_END 319 +#define DOT_X 320 +#define DOT_Y 321 +#define DOT_HT 322 +#define DOT_WID 323 +#define DOT_RAD 324 +#define SIN 325 +#define COS 326 +#define ATAN2 327 +#define LOG 328 +#define EXP 329 +#define SQRT 330 +#define K_MAX 331 +#define K_MIN 332 +#define INT 333 +#define RAND 334 +#define SRAND 335 +#define COPY 336 +#define THRU 337 +#define TOP 338 +#define BOTTOM 339 +#define UPPER 340 +#define LOWER 341 +#define SH 342 +#define PRINT 343 +#define CW 344 +#define CCW 345 +#define FOR 346 +#define DO 347 +#define IF 348 +#define ELSE 349 +#define ANDAND 350 +#define OROR 351 +#define NOTEQUAL 352 +#define EQUALEQUAL 353 +#define LESSEQUAL 354 +#define GREATEREQUAL 355 +#define LEFT_CORNER 356 +#define RIGHT_CORNER 357 +#define NORTH 358 +#define SOUTH 359 +#define EAST 360 +#define WEST 361 +#define CENTER 362 +#define END 363 +#define START 364 +#define RESET 365 +#define UNTIL 366 +#define PLOT 367 +#define THICKNESS 368 +#define FILL 369 +#define COLORED 370 +#define OUTLINED 371 +#define SHADED 372 +#define XSLANTED 373 +#define YSLANTED 374 +#define ALIGNED 375 +#define SPRINTF 376 +#define COMMAND 377 +#define DEFINE 378 +#define UNDEF 379 + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +union YYSTYPE +{ +#line 65 "../src/preproc/pic/pic.ypp" + + char *str; + int n; + double x; + struct { double x, y; } pair; + struct { double x; char *body; } if_data; + struct { char *str; const char *filename; int lineno; } lstr; + struct { double *v; int nv; int maxv; } dv; + struct { double val; int is_multiplicative; } by; + place pl; + object *obj; + corner crn; + path *pth; + object_spec *spec; + saved_state *pstate; + graphics_state state; + object_type obtype; + +#line 435 "src/preproc/pic/pic.cpp" + +}; +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE yylval; + + +int yyparse (void); + + +#endif /* !YY_YY_SRC_PREPROC_PIC_PIC_HPP_INCLUDED */ +/* Symbol kind. */ +enum yysymbol_kind_t +{ + YYSYMBOL_YYEMPTY = -2, + YYSYMBOL_YYEOF = 0, /* "end of file" */ + YYSYMBOL_YYerror = 1, /* error */ + YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ + YYSYMBOL_LABEL = 3, /* LABEL */ + YYSYMBOL_VARIABLE = 4, /* VARIABLE */ + YYSYMBOL_NUMBER = 5, /* NUMBER */ + YYSYMBOL_TEXT = 6, /* TEXT */ + YYSYMBOL_COMMAND_LINE = 7, /* COMMAND_LINE */ + YYSYMBOL_DELIMITED = 8, /* DELIMITED */ + YYSYMBOL_ORDINAL = 9, /* ORDINAL */ + YYSYMBOL_TH = 10, /* TH */ + YYSYMBOL_LEFT_ARROW_HEAD = 11, /* LEFT_ARROW_HEAD */ + YYSYMBOL_RIGHT_ARROW_HEAD = 12, /* RIGHT_ARROW_HEAD */ + YYSYMBOL_DOUBLE_ARROW_HEAD = 13, /* DOUBLE_ARROW_HEAD */ + YYSYMBOL_LAST = 14, /* LAST */ + YYSYMBOL_BOX = 15, /* BOX */ + YYSYMBOL_CIRCLE = 16, /* CIRCLE */ + YYSYMBOL_ELLIPSE = 17, /* ELLIPSE */ + YYSYMBOL_ARC = 18, /* ARC */ + YYSYMBOL_LINE = 19, /* LINE */ + YYSYMBOL_ARROW = 20, /* ARROW */ + YYSYMBOL_MOVE = 21, /* MOVE */ + YYSYMBOL_SPLINE = 22, /* SPLINE */ + YYSYMBOL_HEIGHT = 23, /* HEIGHT */ + YYSYMBOL_RADIUS = 24, /* RADIUS */ + YYSYMBOL_FIGNAME = 25, /* FIGNAME */ + YYSYMBOL_WIDTH = 26, /* WIDTH */ + YYSYMBOL_DIAMETER = 27, /* DIAMETER */ + YYSYMBOL_UP = 28, /* UP */ + YYSYMBOL_DOWN = 29, /* DOWN */ + YYSYMBOL_RIGHT = 30, /* RIGHT */ + YYSYMBOL_LEFT = 31, /* LEFT */ + YYSYMBOL_FROM = 32, /* FROM */ + YYSYMBOL_TO = 33, /* TO */ + YYSYMBOL_AT = 34, /* AT */ + YYSYMBOL_WITH = 35, /* WITH */ + YYSYMBOL_BY = 36, /* BY */ + YYSYMBOL_THEN = 37, /* THEN */ + YYSYMBOL_SOLID = 38, /* SOLID */ + YYSYMBOL_DOTTED = 39, /* DOTTED */ + YYSYMBOL_DASHED = 40, /* DASHED */ + YYSYMBOL_CHOP = 41, /* CHOP */ + YYSYMBOL_SAME = 42, /* SAME */ + YYSYMBOL_INVISIBLE = 43, /* INVISIBLE */ + YYSYMBOL_LJUST = 44, /* LJUST */ + YYSYMBOL_RJUST = 45, /* RJUST */ + YYSYMBOL_ABOVE = 46, /* ABOVE */ + YYSYMBOL_BELOW = 47, /* BELOW */ + YYSYMBOL_OF = 48, /* OF */ + YYSYMBOL_THE = 49, /* THE */ + YYSYMBOL_WAY = 50, /* WAY */ + YYSYMBOL_BETWEEN = 51, /* BETWEEN */ + YYSYMBOL_AND = 52, /* AND */ + YYSYMBOL_HERE = 53, /* HERE */ + YYSYMBOL_DOT_N = 54, /* DOT_N */ + YYSYMBOL_DOT_E = 55, /* DOT_E */ + YYSYMBOL_DOT_W = 56, /* DOT_W */ + YYSYMBOL_DOT_S = 57, /* DOT_S */ + YYSYMBOL_DOT_NE = 58, /* DOT_NE */ + YYSYMBOL_DOT_SE = 59, /* DOT_SE */ + YYSYMBOL_DOT_NW = 60, /* DOT_NW */ + YYSYMBOL_DOT_SW = 61, /* DOT_SW */ + YYSYMBOL_DOT_C = 62, /* DOT_C */ + YYSYMBOL_DOT_START = 63, /* DOT_START */ + YYSYMBOL_DOT_END = 64, /* DOT_END */ + YYSYMBOL_DOT_X = 65, /* DOT_X */ + YYSYMBOL_DOT_Y = 66, /* DOT_Y */ + YYSYMBOL_DOT_HT = 67, /* DOT_HT */ + YYSYMBOL_DOT_WID = 68, /* DOT_WID */ + YYSYMBOL_DOT_RAD = 69, /* DOT_RAD */ + YYSYMBOL_SIN = 70, /* SIN */ + YYSYMBOL_COS = 71, /* COS */ + YYSYMBOL_ATAN2 = 72, /* ATAN2 */ + YYSYMBOL_LOG = 73, /* LOG */ + YYSYMBOL_EXP = 74, /* EXP */ + YYSYMBOL_SQRT = 75, /* SQRT */ + YYSYMBOL_K_MAX = 76, /* K_MAX */ + YYSYMBOL_K_MIN = 77, /* K_MIN */ + YYSYMBOL_INT = 78, /* INT */ + YYSYMBOL_RAND = 79, /* RAND */ + YYSYMBOL_SRAND = 80, /* SRAND */ + YYSYMBOL_COPY = 81, /* COPY */ + YYSYMBOL_THRU = 82, /* THRU */ + YYSYMBOL_TOP = 83, /* TOP */ + YYSYMBOL_BOTTOM = 84, /* BOTTOM */ + YYSYMBOL_UPPER = 85, /* UPPER */ + YYSYMBOL_LOWER = 86, /* LOWER */ + YYSYMBOL_SH = 87, /* SH */ + YYSYMBOL_PRINT = 88, /* PRINT */ + YYSYMBOL_CW = 89, /* CW */ + YYSYMBOL_CCW = 90, /* CCW */ + YYSYMBOL_FOR = 91, /* FOR */ + YYSYMBOL_DO = 92, /* DO */ + YYSYMBOL_IF = 93, /* IF */ + YYSYMBOL_ELSE = 94, /* ELSE */ + YYSYMBOL_ANDAND = 95, /* ANDAND */ + YYSYMBOL_OROR = 96, /* OROR */ + YYSYMBOL_NOTEQUAL = 97, /* NOTEQUAL */ + YYSYMBOL_EQUALEQUAL = 98, /* EQUALEQUAL */ + YYSYMBOL_LESSEQUAL = 99, /* LESSEQUAL */ + YYSYMBOL_GREATEREQUAL = 100, /* GREATEREQUAL */ + YYSYMBOL_LEFT_CORNER = 101, /* LEFT_CORNER */ + YYSYMBOL_RIGHT_CORNER = 102, /* RIGHT_CORNER */ + YYSYMBOL_NORTH = 103, /* NORTH */ + YYSYMBOL_SOUTH = 104, /* SOUTH */ + YYSYMBOL_EAST = 105, /* EAST */ + YYSYMBOL_WEST = 106, /* WEST */ + YYSYMBOL_CENTER = 107, /* CENTER */ + YYSYMBOL_END = 108, /* END */ + YYSYMBOL_START = 109, /* START */ + YYSYMBOL_RESET = 110, /* RESET */ + YYSYMBOL_UNTIL = 111, /* UNTIL */ + YYSYMBOL_PLOT = 112, /* PLOT */ + YYSYMBOL_THICKNESS = 113, /* THICKNESS */ + YYSYMBOL_FILL = 114, /* FILL */ + YYSYMBOL_COLORED = 115, /* COLORED */ + YYSYMBOL_OUTLINED = 116, /* OUTLINED */ + YYSYMBOL_SHADED = 117, /* SHADED */ + YYSYMBOL_XSLANTED = 118, /* XSLANTED */ + YYSYMBOL_YSLANTED = 119, /* YSLANTED */ + YYSYMBOL_ALIGNED = 120, /* ALIGNED */ + YYSYMBOL_SPRINTF = 121, /* SPRINTF */ + YYSYMBOL_COMMAND = 122, /* COMMAND */ + YYSYMBOL_DEFINE = 123, /* DEFINE */ + YYSYMBOL_UNDEF = 124, /* UNDEF */ + YYSYMBOL_125_ = 125, /* '.' */ + YYSYMBOL_126_ = 126, /* '(' */ + YYSYMBOL_127_ = 127, /* '`' */ + YYSYMBOL_128_ = 128, /* '[' */ + YYSYMBOL_129_ = 129, /* ',' */ + YYSYMBOL_130_ = 130, /* '<' */ + YYSYMBOL_131_ = 131, /* '>' */ + YYSYMBOL_132_ = 132, /* '+' */ + YYSYMBOL_133_ = 133, /* '-' */ + YYSYMBOL_134_ = 134, /* '*' */ + YYSYMBOL_135_ = 135, /* '/' */ + YYSYMBOL_136_ = 136, /* '%' */ + YYSYMBOL_137_ = 137, /* '!' */ + YYSYMBOL_138_ = 138, /* '^' */ + YYSYMBOL_139_ = 139, /* ';' */ + YYSYMBOL_140_ = 140, /* '=' */ + YYSYMBOL_141_ = 141, /* ':' */ + YYSYMBOL_142_ = 142, /* '{' */ + YYSYMBOL_143_ = 143, /* '}' */ + YYSYMBOL_144_ = 144, /* ']' */ + YYSYMBOL_145_ = 145, /* ')' */ + YYSYMBOL_YYACCEPT = 146, /* $accept */ + YYSYMBOL_top = 147, /* top */ + YYSYMBOL_element_list = 148, /* element_list */ + YYSYMBOL_middle_element_list = 149, /* middle_element_list */ + YYSYMBOL_optional_separator = 150, /* optional_separator */ + YYSYMBOL_separator = 151, /* separator */ + YYSYMBOL_placeless_element = 152, /* placeless_element */ + YYSYMBOL_153_1 = 153, /* $@1 */ + YYSYMBOL_154_2 = 154, /* $@2 */ + YYSYMBOL_155_3 = 155, /* $@3 */ + YYSYMBOL_156_4 = 156, /* $@4 */ + YYSYMBOL_157_5 = 157, /* $@5 */ + YYSYMBOL_158_6 = 158, /* $@6 */ + YYSYMBOL_159_7 = 159, /* $@7 */ + YYSYMBOL_macro_name = 160, /* macro_name */ + YYSYMBOL_reset_variables = 161, /* reset_variables */ + YYSYMBOL_print_args = 162, /* print_args */ + YYSYMBOL_print_arg = 163, /* print_arg */ + YYSYMBOL_simple_if = 164, /* simple_if */ + YYSYMBOL_165_8 = 165, /* $@8 */ + YYSYMBOL_until = 166, /* until */ + YYSYMBOL_any_expr = 167, /* any_expr */ + YYSYMBOL_text_expr = 168, /* text_expr */ + YYSYMBOL_optional_by = 169, /* optional_by */ + YYSYMBOL_element = 170, /* element */ + YYSYMBOL_171_9 = 171, /* @9 */ + YYSYMBOL_172_10 = 172, /* $@10 */ + YYSYMBOL_optional_element = 173, /* optional_element */ + YYSYMBOL_object_spec = 174, /* object_spec */ + YYSYMBOL_175_11 = 175, /* @11 */ + YYSYMBOL_text = 176, /* text */ + YYSYMBOL_sprintf_args = 177, /* sprintf_args */ + YYSYMBOL_position = 178, /* position */ + YYSYMBOL_position_not_place = 179, /* position_not_place */ + YYSYMBOL_between = 180, /* between */ + YYSYMBOL_expr_pair = 181, /* expr_pair */ + YYSYMBOL_place = 182, /* place */ + YYSYMBOL_label = 183, /* label */ + YYSYMBOL_ordinal = 184, /* ordinal */ + YYSYMBOL_optional_ordinal_last = 185, /* optional_ordinal_last */ + YYSYMBOL_nth_primitive = 186, /* nth_primitive */ + YYSYMBOL_object_type = 187, /* object_type */ + YYSYMBOL_label_path = 188, /* label_path */ + YYSYMBOL_relative_path = 189, /* relative_path */ + YYSYMBOL_path = 190, /* path */ + YYSYMBOL_corner = 191, /* corner */ + YYSYMBOL_expr = 192, /* expr */ + YYSYMBOL_expr_lower_than = 193, /* expr_lower_than */ + YYSYMBOL_expr_not_lower_than = 194 /* expr_not_lower_than */ +}; +typedef enum yysymbol_kind_t yysymbol_kind_t; + + + + +#ifdef short +# undef short +#endif + +/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure + and (if available) are included + so that the code can choose integer types of a good width. */ + +#ifndef __PTRDIFF_MAX__ +# include /* INFRINGES ON USER NAME SPACE */ +# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_STDINT_H +# endif +#endif + +/* Narrow types that promote to a signed type and that can represent a + signed or unsigned integer of at least N bits. In tables they can + save space and decrease cache pressure. Promoting to a signed type + helps avoid bugs in integer arithmetic. */ + +#ifdef __INT_LEAST8_MAX__ +typedef __INT_LEAST8_TYPE__ yytype_int8; +#elif defined YY_STDINT_H +typedef int_least8_t yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef __INT_LEAST16_MAX__ +typedef __INT_LEAST16_TYPE__ yytype_int16; +#elif defined YY_STDINT_H +typedef int_least16_t yytype_int16; +#else +typedef short yytype_int16; +#endif + +/* Work around bug in HP-UX 11.23, which defines these macros + incorrectly for preprocessor constants. This workaround can likely + be removed in 2023, as HPE has promised support for HP-UX 11.23 + (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of + . */ +#ifdef __hpux +# undef UINT_LEAST8_MAX +# undef UINT_LEAST16_MAX +# define UINT_LEAST8_MAX 255 +# define UINT_LEAST16_MAX 65535 +#endif + +#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST8_TYPE__ yytype_uint8; +#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST8_MAX <= INT_MAX) +typedef uint_least8_t yytype_uint8; +#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX +typedef unsigned char yytype_uint8; +#else +typedef short yytype_uint8; +#endif + +#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST16_TYPE__ yytype_uint16; +#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST16_MAX <= INT_MAX) +typedef uint_least16_t yytype_uint16; +#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX +typedef unsigned short yytype_uint16; +#else +typedef int yytype_uint16; +#endif + +#ifndef YYPTRDIFF_T +# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ +# define YYPTRDIFF_T __PTRDIFF_TYPE__ +# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ +# elif defined PTRDIFF_MAX +# ifndef ptrdiff_t +# include /* INFRINGES ON USER NAME SPACE */ +# endif +# define YYPTRDIFF_T ptrdiff_t +# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX +# else +# define YYPTRDIFF_T long +# define YYPTRDIFF_MAXIMUM LONG_MAX +# endif +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned +# endif +#endif + +#define YYSIZE_MAXIMUM \ + YY_CAST (YYPTRDIFF_T, \ + (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ + ? YYPTRDIFF_MAXIMUM \ + : YY_CAST (YYSIZE_T, -1))) + +#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) + + +/* Stored state numbers (used for stacks). */ +typedef yytype_int16 yy_state_t; + +/* State numbers in computations. */ +typedef int yy_state_fast_t; + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + + +#ifndef YY_ATTRIBUTE_PURE +# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) +# else +# define YY_ATTRIBUTE_PURE +# endif +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +# else +# define YY_ATTRIBUTE_UNUSED +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YY_USE(E) ((void) (E)) +#else +# define YY_USE(E) /* empty */ +#endif + +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ +# if __GNUC__ * 100 + __GNUC_MINOR__ < 407 +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") +# else +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# endif +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + +#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ +# define YY_IGNORE_USELESS_CAST_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") +# define YY_IGNORE_USELESS_CAST_END \ + _Pragma ("GCC diagnostic pop") +#endif +#ifndef YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_END +#endif + + +#define YY_ASSERT(E) ((void) (0 && (E))) + +#if !defined yyoverflow + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* !defined yyoverflow */ + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yy_state_t yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYPTRDIFF_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / YYSIZEOF (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYPTRDIFF_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 6 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 2438 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 146 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 49 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 260 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 454 + +/* YYMAXUTOK -- Last valid token kind. */ +#define YYMAXUTOK 379 + + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +#define YYTRANSLATE(YYX) \ + (0 <= (YYX) && (YYX) <= YYMAXUTOK \ + ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ + : YYSYMBOL_YYUNDEF) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 137, 2, 2, 2, 136, 2, 2, + 126, 145, 134, 132, 129, 133, 125, 135, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 141, 139, + 130, 140, 131, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 128, 2, 144, 138, 2, 127, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 142, 2, 143, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124 +}; + +#if YYDEBUG +/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_int16 yyrline[] = +{ + 0, 275, 275, 276, 285, 290, 292, 296, 298, 302, + 303, 307, 315, 320, 332, 334, 336, 338, 340, 345, + 350, 357, 356, 372, 380, 382, 379, 393, 395, 392, + 405, 404, 413, 422, 421, 435, 436, 441, 442, 446, + 451, 456, 464, 466, 485, 492, 494, 505, 504, 516, + 517, 522, 524, 529, 535, 541, 543, 545, 547, 549, + 551, 553, 560, 564, 569, 577, 591, 597, 605, 612, + 618, 611, 627, 637, 638, 643, 645, 647, 649, 654, + 661, 668, 675, 682, 687, 694, 702, 701, 728, 734, + 740, 746, 752, 771, 778, 785, 792, 799, 806, 813, + 820, 827, 834, 849, 861, 867, 876, 883, 908, 912, + 918, 924, 930, 936, 941, 947, 953, 959, 966, 975, + 982, 998, 1015, 1020, 1025, 1030, 1035, 1040, 1045, 1050, + 1058, 1068, 1078, 1088, 1098, 1104, 1112, 1114, 1126, 1131, + 1161, 1163, 1169, 1178, 1180, 1185, 1190, 1195, 1200, 1205, + 1210, 1216, 1221, 1229, 1230, 1234, 1239, 1245, 1247, 1253, + 1259, 1265, 1274, 1284, 1286, 1295, 1297, 1305, 1307, 1312, + 1327, 1345, 1347, 1349, 1351, 1353, 1355, 1357, 1359, 1361, + 1366, 1368, 1376, 1380, 1382, 1390, 1392, 1398, 1404, 1410, + 1416, 1425, 1427, 1429, 1431, 1433, 1435, 1437, 1439, 1441, + 1443, 1445, 1447, 1449, 1451, 1453, 1455, 1457, 1459, 1461, + 1463, 1465, 1467, 1469, 1471, 1473, 1475, 1477, 1479, 1481, + 1483, 1485, 1487, 1492, 1494, 1499, 1504, 1512, 1514, 1521, + 1528, 1535, 1542, 1549, 1551, 1553, 1555, 1563, 1571, 1584, + 1586, 1588, 1597, 1606, 1619, 1628, 1637, 1646, 1648, 1650, + 1652, 1659, 1665, 1670, 1672, 1674, 1676, 1678, 1680, 1682, + 1684 +}; +#endif + +/** Accessing symbol of state STATE. */ +#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) + +#if YYDEBUG || 0 +/* The user-facing name of the symbol whose (internal) number is + YYSYMBOL. No bounds checking. */ +static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; + +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "\"end of file\"", "error", "\"invalid token\"", "LABEL", "VARIABLE", + "NUMBER", "TEXT", "COMMAND_LINE", "DELIMITED", "ORDINAL", "TH", + "LEFT_ARROW_HEAD", "RIGHT_ARROW_HEAD", "DOUBLE_ARROW_HEAD", "LAST", + "BOX", "CIRCLE", "ELLIPSE", "ARC", "LINE", "ARROW", "MOVE", "SPLINE", + "HEIGHT", "RADIUS", "FIGNAME", "WIDTH", "DIAMETER", "UP", "DOWN", + "RIGHT", "LEFT", "FROM", "TO", "AT", "WITH", "BY", "THEN", "SOLID", + "DOTTED", "DASHED", "CHOP", "SAME", "INVISIBLE", "LJUST", "RJUST", + "ABOVE", "BELOW", "OF", "THE", "WAY", "BETWEEN", "AND", "HERE", "DOT_N", + "DOT_E", "DOT_W", "DOT_S", "DOT_NE", "DOT_SE", "DOT_NW", "DOT_SW", + "DOT_C", "DOT_START", "DOT_END", "DOT_X", "DOT_Y", "DOT_HT", "DOT_WID", + "DOT_RAD", "SIN", "COS", "ATAN2", "LOG", "EXP", "SQRT", "K_MAX", "K_MIN", + "INT", "RAND", "SRAND", "COPY", "THRU", "TOP", "BOTTOM", "UPPER", + "LOWER", "SH", "PRINT", "CW", "CCW", "FOR", "DO", "IF", "ELSE", "ANDAND", + "OROR", "NOTEQUAL", "EQUALEQUAL", "LESSEQUAL", "GREATEREQUAL", + "LEFT_CORNER", "RIGHT_CORNER", "NORTH", "SOUTH", "EAST", "WEST", + "CENTER", "END", "START", "RESET", "UNTIL", "PLOT", "THICKNESS", "FILL", + "COLORED", "OUTLINED", "SHADED", "XSLANTED", "YSLANTED", "ALIGNED", + "SPRINTF", "COMMAND", "DEFINE", "UNDEF", "'.'", "'('", "'`'", "'['", + "','", "'<'", "'>'", "'+'", "'-'", "'*'", "'/'", "'%'", "'!'", "'^'", + "';'", "'='", "':'", "'{'", "'}'", "']'", "')'", "$accept", "top", + "element_list", "middle_element_list", "optional_separator", "separator", + "placeless_element", "$@1", "$@2", "$@3", "$@4", "$@5", "$@6", "$@7", + "macro_name", "reset_variables", "print_args", "print_arg", "simple_if", + "$@8", "until", "any_expr", "text_expr", "optional_by", "element", "@9", + "$@10", "optional_element", "object_spec", "@11", "text", "sprintf_args", + "position", "position_not_place", "between", "expr_pair", "place", + "label", "ordinal", "optional_ordinal_last", "nth_primitive", + "object_type", "label_path", "relative_path", "path", "corner", "expr", + "expr_lower_than", "expr_not_lower_than", YY_NULLPTR +}; + +static const char * +yysymbol_name (yysymbol_kind_t yysymbol) +{ + return yytname[yysymbol]; +} +#endif + +#define YYPACT_NINF (-240) + +#define yypact_value_is_default(Yyn) \ + ((Yyn) == YYPACT_NINF) + +#define YYTABLE_NINF (-206) + +#define yytable_value_is_error(Yyn) \ + 0 + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int16 yypact[] = +{ + -114, -240, 20, -240, 757, -107, -240, -98, -123, -240, + -240, -240, -240, -240, -240, -240, -240, -240, -240, -106, + -240, -240, -240, -240, 9, -240, 1087, 46, 1172, 49, + 1597, -70, 1087, -240, -240, -114, -240, 3, -33, -240, + 877, -240, -240, -114, 1172, -60, 36, -14, -240, 74, + -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, + -240, -240, -240, -240, -240, -240, -240, -240, -240, -34, + -18, 8, 38, 47, 51, 65, 101, 102, 112, 122, + -240, -240, 21, 150, -240, -240, -240, -240, -240, -240, + -240, -240, -240, 1257, 1172, 1597, 1597, 1087, -240, -240, + -43, -240, -240, 357, 2242, 59, 258, -240, 10, 2147, + -240, 1, 6, 1172, 1172, 145, -1, 2, 357, 2273, + -240, -240, 220, 249, 1087, -114, -114, -240, 721, -240, + 252, -240, -240, -240, -240, 1597, 1597, 1597, 1597, 2024, + 2024, 1853, 1939, 1682, 1682, 1682, 1427, 1767, -240, -240, + 2024, 2024, 2024, -240, -240, -240, -240, -240, -240, -240, + -240, 1597, 2024, 23, 23, 23, 1597, 1597, -240, -240, + 2282, 593, -240, 1172, -240, -240, -240, -240, 250, -240, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 458, + 1172, -240, -240, -240, -240, -240, -240, -240, -240, 121, + 107, 123, 256, 2157, 137, 261, 134, 134, -240, 1767, + 1767, -240, -240, -240, -240, -240, 276, -240, -240, -240, + -240, -240, -240, -240, -240, -240, -240, 138, -240, -240, + 24, 156, 235, -240, 1597, 1597, 1597, 1597, 1597, 1597, + 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1682, + 1682, 1597, -240, 134, -240, 1172, 1172, 23, 23, 1172, + 1172, -240, -240, 143, 757, 153, -240, -240, 280, 2282, + 2282, 2282, 2282, 2282, 2282, 2282, 2282, -43, 2147, -43, + -43, 2253, 275, 275, 295, 1002, -43, 2081, -240, -240, + 10, 1342, -240, 694, 2282, 2282, 2282, 2282, 2282, -240, + -240, -240, 2282, 2282, -98, -123, 16, 28, -240, -43, + 56, 302, -240, 291, -240, 155, 160, 172, 161, 164, + 167, 184, 185, 181, -240, 186, 188, -240, 1682, 1767, + 1767, -240, -240, 1682, 1682, -240, -240, -240, -240, -240, + 156, 279, 314, 2291, 440, 440, 413, 413, 2282, 413, + 413, -72, -72, 134, 134, 134, 134, -49, 117, 343, + 322, -240, 314, 239, 2300, -240, -240, -240, 314, 239, + 2300, -119, -240, -240, -240, -240, -240, 2116, 2116, -240, + 206, 333, -240, 123, 2131, -240, 228, -240, -240, 1172, + -240, -240, -240, 1172, 1172, -240, -240, -240, -110, 195, + 197, -47, 128, 292, 1682, 1682, 1597, -240, 1597, -240, + 757, -240, -240, 2116, -240, 228, 338, -240, 200, 202, + 212, -240, -240, -240, 1682, 1682, -240, -43, -27, 360, + 2282, -240, -240, 214, -240, -240, -240, -240, -240, -73, + 30, -240, 1512, 268, -240, -240, 216, 1597, 2282, -240, + -240, 2282, 354, -240 +}; + +/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_int16 yydefact[] = +{ + 7, 9, 0, 3, 2, 8, 1, 0, 0, 136, + 18, 75, 76, 77, 78, 79, 80, 81, 82, 0, + 14, 15, 17, 16, 0, 21, 0, 0, 0, 36, + 0, 0, 0, 86, 69, 7, 72, 35, 32, 5, + 65, 83, 10, 7, 0, 0, 0, 23, 27, 0, + 162, 226, 227, 165, 167, 205, 204, 161, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 202, 203, 0, 0, 210, 211, 216, 217, 218, 219, + 220, 222, 221, 0, 0, 0, 0, 20, 42, 45, + 46, 140, 143, 141, 157, 0, 0, 163, 0, 44, + 223, 224, 0, 0, 0, 0, 52, 0, 0, 51, + 224, 39, 84, 0, 19, 7, 7, 4, 8, 40, + 0, 33, 124, 125, 126, 0, 0, 0, 0, 93, + 95, 97, 99, 0, 0, 0, 0, 0, 107, 108, + 109, 111, 120, 122, 123, 130, 131, 132, 133, 127, + 128, 0, 113, 0, 0, 0, 0, 0, 135, 129, + 92, 0, 12, 0, 38, 37, 11, 24, 0, 22, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 208, 206, 212, 214, 209, 207, 213, 215, 0, + 0, 143, 141, 51, 224, 0, 239, 260, 43, 0, + 0, 228, 229, 230, 231, 232, 0, 158, 179, 168, + 171, 172, 173, 174, 175, 176, 177, 0, 169, 170, + 0, 159, 0, 153, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 61, 260, 47, 0, 0, 0, 0, 0, + 0, 85, 138, 0, 0, 0, 6, 41, 0, 88, + 89, 90, 91, 94, 96, 98, 100, 101, 0, 102, + 103, 162, 165, 167, 0, 0, 105, 183, 185, 104, + 182, 0, 106, 0, 110, 112, 121, 134, 114, 118, + 119, 117, 115, 116, 162, 226, 205, 204, 66, 0, + 67, 68, 13, 0, 28, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 251, 0, 0, 240, 0, 0, + 0, 156, 142, 0, 0, 166, 144, 146, 164, 178, + 160, 0, 258, 259, 257, 256, 253, 255, 155, 225, + 254, 233, 234, 235, 236, 237, 238, 0, 0, 0, + 0, 55, 56, 58, 59, 54, 53, 57, 258, 60, + 259, 0, 87, 70, 34, 190, 182, 0, 0, 180, + 0, 0, 184, 0, 51, 25, 49, 241, 242, 0, + 244, 245, 246, 0, 0, 249, 250, 252, 0, 144, + 146, 0, 0, 0, 0, 0, 0, 48, 0, 137, + 73, 189, 188, 0, 181, 49, 0, 29, 0, 0, + 0, 148, 145, 147, 0, 0, 154, 149, 0, 62, + 139, 74, 71, 0, 26, 50, 243, 247, 248, 149, + 0, 151, 0, 0, 186, 150, 151, 0, 63, 30, + 152, 64, 0, 31 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -240, -240, 17, -240, 12, 329, -240, -240, -240, -240, + -240, -240, -240, -240, -240, -240, 334, -76, -240, -240, + -42, 13, -103, -240, -127, -240, -240, -240, -240, -240, + 5, -240, 99, 194, 169, -44, 4, -100, -240, -240, + -240, -104, -240, -239, -240, -50, -26, -240, 61 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + 0, 2, 3, 35, 264, 5, 36, 49, 313, 415, + 178, 386, 452, 268, 176, 37, 97, 98, 38, 360, + 417, 199, 116, 443, 39, 126, 410, 432, 40, 125, + 117, 371, 100, 101, 249, 102, 118, 104, 105, 106, + 107, 228, 287, 288, 289, 108, 119, 110, 120 +}; + +/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_int16 yytable[] = +{ + 109, 266, 229, 404, 122, 424, 109, 129, 231, 41, + 408, 252, 4, 50, 170, 47, -17, 44, 45, 53, + 6, 208, 209, 210, 54, 1, 409, 50, -16, 9, + 103, 99, 42, 53, 46, 421, 103, 99, 54, 174, + 175, 115, 375, 43, 308, 169, 380, 127, 208, 201, + 112, 191, 192, 121, 217, 171, 123, 172, 230, 209, + 210, 131, 245, 246, 247, 218, 248, 203, 177, 206, + 207, 109, 445, 219, 220, 221, 222, 223, 224, 225, + 173, 226, 179, 209, 210, 209, 210, 111, 253, 209, + 210, 48, 180, 111, 255, 256, 290, 202, 109, 257, + 258, 103, 99, 292, 441, 209, 210, 205, 181, 269, + 270, 271, 272, 273, 274, 275, 276, 278, 278, 278, + 278, 293, 193, 194, 294, 295, 296, 261, 103, 99, + 340, 250, 130, 41, 182, 297, 298, 94, 411, 412, + 302, 303, 263, 265, 31, 278, 251, 103, 103, 103, + 103, 94, 361, 363, 204, -17, 367, 369, 111, -17, + -17, 446, 209, 210, 183, 336, 337, -16, 299, 300, + 301, -16, -16, 184, 433, 311, 41, 185, 377, 378, + 195, 196, 254, 293, 293, 111, 312, 227, -140, -140, + 231, 186, 200, 315, 316, 317, 318, 319, 320, 321, + 322, 323, 325, 326, 111, 111, 111, 111, 342, 343, + 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, + 354, 355, 356, 278, 278, 359, 9, 187, 188, 362, + 364, 376, 111, 368, 370, 290, 328, 382, 189, 329, + 330, 201, 277, 279, 280, 286, 405, 383, 190, 209, + 210, 197, 198, 103, 103, 262, 267, 425, 314, 203, + 209, 210, 365, 366, 218, 384, 327, 334, 331, 41, + 309, 335, 248, 220, 221, 222, 223, 224, 225, 338, + 226, 216, 339, 431, 341, 399, 400, 372, 374, 202, + 220, 221, 222, 223, 224, 225, 373, 226, 379, 385, + 387, 389, 278, 293, 293, 388, 390, 278, 278, 391, + 111, 111, 392, 393, 394, 234, 235, 236, 237, 238, + 239, 211, 212, 213, 214, 215, 395, 376, 376, 403, + 407, 396, 103, 397, 255, 413, 414, 103, 103, 416, + 422, 31, 423, 426, 435, 436, 204, 437, 357, 358, + 241, 242, 243, 244, 245, 246, 247, 438, 248, 444, + 449, 450, 453, 376, 128, 310, 124, 211, 212, 213, + 214, 215, 333, 434, 0, 0, 406, 0, 278, 278, + 429, 0, 430, 0, 200, 0, 227, 0, 0, 111, + 0, 0, 0, 0, 111, 111, 442, 0, 278, 278, + 0, 332, 418, 227, 0, 0, 419, 420, 103, 103, + 0, 236, 237, 238, 239, 41, 448, 0, 0, 0, + 0, 451, 211, 212, 213, 214, 215, 398, 103, 103, + 0, 0, 401, 402, -141, -141, 0, 0, 234, 235, + 236, 237, 238, 239, 241, 242, 243, 244, 245, 246, + 247, 0, 248, 0, 0, 234, 235, 236, 237, 238, + 239, 50, 51, 52, 9, 111, 111, 53, 0, 0, + 0, 0, 54, 241, 242, 243, 244, 245, 246, 247, + 0, 248, 0, 0, 0, 111, 111, 0, 55, 56, + 241, 242, 243, 244, 245, 246, 247, 0, 248, 0, + 0, 0, 0, 427, 428, 0, 0, 0, 0, 0, + 0, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 439, 440, 0, 0, 0, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 238, + 239, 80, 81, 82, 83, 243, 244, 245, 246, 247, + 0, 248, 0, 0, 0, 0, 0, 0, 0, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 0, 0, + 241, 242, 243, 244, 245, 246, 247, 0, 248, 31, + 0, 0, 0, 0, 113, 94, 0, 0, 0, 0, + 0, 95, 0, 0, 0, 114, 304, 305, 52, 9, + 10, 0, 53, 324, 0, 0, 0, 54, 11, 12, + 13, 14, 15, 16, 17, 18, 0, 0, 19, 0, + 0, 20, 21, 306, 307, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 0, 0, + 0, 0, 0, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 24, 0, 80, 81, 82, 83, + 25, 26, 0, 0, 27, 0, 28, 0, 0, 0, + 0, 0, 0, 0, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 29, 0, 30, 0, 0, 0, 0, + 0, 0, 0, 0, 31, 32, 0, 0, 0, 93, + 94, 33, 0, 0, 7, 8, 95, 9, 10, 0, + 96, 0, 0, 0, 0, 34, 11, 12, 13, 14, + 15, 16, 17, 18, 0, 0, 19, 0, 0, 20, + 21, 22, 23, 0, 0, 0, 0, 0, 0, 0, + 7, 8, 0, 9, 10, 0, 0, 0, 0, 0, + 0, 0, 11, 12, 13, 14, 15, 16, 17, 18, + 0, 0, 19, 0, 0, 20, 21, 22, 23, 234, + 235, 236, 237, 238, 239, 0, 0, 0, 0, 0, + 0, 0, 24, 0, 0, 0, 0, 0, 25, 26, + 0, 0, 27, 0, 28, 0, 0, 0, 0, 0, + 0, 0, 0, 240, 241, 242, 243, 244, 245, 246, + 247, 29, 248, 30, 0, 0, 0, 0, 24, 0, + 0, 0, 31, 32, 25, 26, 0, 0, 27, 33, + 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 42, 0, 0, 34, 0, 0, 0, 29, 0, 30, + 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, + 50, 51, 52, 9, 0, 33, 53, 0, 132, 133, + 134, 54, 0, 0, 0, 0, 0, 0, 0, 34, + 135, 136, 0, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 0, 0, 0, 0, 0, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 0, 0, 0, 0, 0, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, + 80, 81, 82, 83, 0, 0, 159, 160, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 0, 0, 0, + 161, 162, 163, 164, 165, 166, 167, 168, 31, 0, + 0, 0, 0, 113, 94, 50, 51, 52, 9, 0, + 95, 53, 0, 0, 96, 0, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 55, 56, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 0, 0, 0, + 0, 0, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 0, 0, 80, 81, 82, 83, 0, + 50, 51, 52, 9, 0, 0, 53, 0, 0, 0, + 0, 54, 0, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 0, 0, 0, 0, 0, 55, 56, 0, + 0, 0, 0, 31, 0, 0, 0, 284, 93, 94, + 0, 0, 0, 0, 0, 95, 0, 0, 0, 114, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 0, 0, 0, 0, 0, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, + 80, 81, 82, 83, 0, 50, 51, 52, 9, 0, + 0, 53, 0, 0, 0, 0, 54, 0, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 0, 0, 0, + 0, 0, 55, 56, 0, 0, 0, 0, 31, 0, + 0, 0, 0, 93, 94, 0, 0, 0, 0, 0, + 95, 0, 0, 0, 96, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 0, 0, 0, + 0, 0, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 0, 0, 80, 81, 82, 83, 0, + 50, 51, 52, 9, 0, 0, 53, 0, 0, 0, + 0, 54, 0, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 0, 0, 0, 0, 0, 55, 56, 0, + 0, 0, 0, 31, 0, 0, 0, 0, 113, 94, + 0, 0, 0, 0, 0, 95, 0, 0, 0, 114, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 0, 0, 0, 0, 0, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, + 80, 81, 82, 83, 0, 50, 51, 52, 9, 0, + 0, 53, 0, 0, 0, 0, 54, 0, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 0, 0, 0, + 0, 0, 55, 56, 0, 0, 0, 0, 31, 0, + 0, 0, 0, 93, 94, 0, 0, 0, 0, 0, + 95, 0, 0, 0, 114, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 0, 0, 0, + 0, 0, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 0, 0, 80, 81, 82, 83, 0, + 281, 51, 52, 0, 0, 0, 282, 0, 0, 0, + 0, 283, 0, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 0, 0, 0, 0, 0, 55, 56, 0, + 0, 0, 0, 31, 0, 0, 0, 0, 291, 94, + 0, 0, 0, 0, 0, 95, 0, 0, 0, 114, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 0, 0, 0, 0, 0, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, + 80, 81, 82, 83, 0, 50, 51, 52, 0, 0, + 0, 53, 0, 0, 0, 0, 54, 0, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 0, 0, 0, + 0, 0, 55, 56, 0, 0, 0, 0, 0, 0, + 0, 0, 284, 285, 94, 0, 0, 0, 0, 0, + 95, 0, 0, 0, 96, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 0, 0, 0, + 0, 0, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 0, 0, 80, 81, 82, 83, 0, + 50, 51, 52, 0, 0, 0, 53, 0, 0, 0, + 0, 54, 0, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 0, 0, 0, 0, 0, 55, 56, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 113, 94, + 0, 0, 0, 0, 0, 95, 447, 0, 0, 96, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 0, 0, 0, 0, 0, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, + 80, 81, 82, 83, 0, 50, 51, 52, 0, 0, + 0, 53, 0, 0, 0, 0, 54, 0, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 0, 0, 0, + 0, 0, 55, 56, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 113, 94, 0, 0, 0, 0, 0, + 95, 0, 0, 0, 96, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 0, 0, 0, + 0, 0, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 0, 0, 80, 81, 82, 83, 0, + 50, 51, 52, 0, 0, 0, 53, 0, 0, 0, + 0, 54, 0, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 0, 0, 0, 0, 0, 55, 56, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 93, 94, + 0, 0, 0, 0, 0, 95, 0, 0, 0, 96, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 0, 0, 0, 0, 0, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, + 80, 81, 82, 83, 0, 0, 50, 51, 52, 0, + 0, 0, 53, 0, 0, 0, 0, 54, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 291, 94, 0, 0, 0, 0, 0, + 95, -205, 0, 0, 96, 0, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 0, 0, + 0, 0, 0, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 0, 0, 80, 81, 82, 83, + 0, 0, 50, 51, 52, 0, 0, 0, 53, 0, + 0, 0, 0, 54, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, + 94, 0, 0, 0, 0, 0, 95, -204, 0, 0, + 96, 0, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 0, 0, 0, 0, 0, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 0, 0, 80, 81, 82, 83, 0, 50, 51, 52, + 0, 0, 0, 53, 0, 0, 0, 0, 54, 0, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 113, 94, 0, 0, 0, + 0, 0, 95, 0, 0, 0, 96, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 0, + 0, 0, 0, 0, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 0, 0, 80, 81, 82, + 83, 55, 56, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 0, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 55, 56, 0, 0, + 113, 94, 0, 0, 0, 0, 0, 95, 0, 0, + 0, 96, 0, 0, 80, 81, 82, 83, 0, 0, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 0, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 0, 0, 0, 0, 232, 0, 0, 233, 80, + 81, 82, 83, 0, 0, 232, 381, 0, 233, 0, + 0, 0, 0, 0, 0, 0, 0, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 259, 260, 236, 237, + 238, 239, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 284, 234, 235, 236, 237, 238, 239, 0, 0, + 0, 0, 259, 260, 236, 237, 238, 239, 0, 0, + 240, 241, 242, 243, 244, 245, 246, 247, 0, 248, + 0, 0, 0, 0, 0, 0, 240, 241, 242, 243, + 244, 245, 246, 247, 0, 248, 240, 241, 242, 243, + 244, 245, 246, 247, 0, 248, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 0, 0, + 0, 0, 0, 0, 0, 80, 81, 82, 83, 0, + 0, 0, 0, 0, 0, 0, 80, 81, 82, 83, + 0, 0, 0, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 0, 0, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 0, 0, 0, 0, 216, 259, 260, + 236, 237, 238, 239, 0, 0, 0, 234, 235, 236, + 237, 238, 239, 0, 0, 0, 234, 0, 236, 237, + 238, 239, 0, 0, 0, 259, 0, 236, 237, 238, + 239, 0, 0, 241, 242, 243, 244, 245, 246, 247, + 0, 248, 241, 242, 243, 244, 245, 246, 247, 0, + 248, 241, 242, 243, 244, 245, 246, 247, 0, 248, + 241, 242, 243, 244, 245, 246, 247, 0, 248 +}; + +static const yytype_int16 yycheck[] = +{ + 26, 128, 106, 52, 30, 52, 32, 4, 108, 4, + 129, 114, 0, 3, 40, 6, 0, 140, 141, 9, + 0, 97, 132, 133, 14, 139, 145, 3, 0, 6, + 26, 26, 139, 9, 140, 145, 32, 32, 14, 3, + 4, 28, 281, 141, 171, 40, 285, 35, 124, 93, + 4, 30, 31, 4, 104, 43, 126, 44, 48, 132, + 133, 94, 134, 135, 136, 6, 138, 93, 82, 95, + 96, 97, 145, 14, 15, 16, 17, 18, 19, 20, + 140, 22, 8, 132, 133, 132, 133, 26, 114, 132, + 133, 82, 126, 32, 95, 96, 146, 93, 124, 97, + 98, 97, 97, 147, 131, 132, 133, 94, 126, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 101, 102, 150, 151, 152, 122, 124, 124, + 230, 130, 129, 128, 126, 161, 162, 127, 377, 378, + 166, 167, 125, 126, 121, 171, 140, 143, 144, 145, + 146, 127, 255, 256, 93, 139, 259, 260, 97, 143, + 144, 131, 132, 133, 126, 209, 210, 139, 163, 164, + 165, 143, 144, 126, 413, 171, 171, 126, 282, 283, + 30, 31, 37, 209, 210, 124, 173, 128, 132, 133, + 290, 126, 93, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 143, 144, 145, 146, 234, 235, + 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 246, 247, 248, 249, 250, 251, 6, 126, 126, 255, + 256, 281, 171, 259, 260, 285, 129, 287, 126, 132, + 133, 285, 143, 144, 145, 146, 129, 291, 126, 132, + 133, 101, 102, 249, 250, 6, 4, 129, 8, 285, + 132, 133, 257, 258, 6, 291, 145, 130, 145, 264, + 171, 10, 138, 15, 16, 17, 18, 19, 20, 3, + 22, 125, 144, 410, 49, 329, 330, 144, 8, 285, + 15, 16, 17, 18, 19, 20, 143, 22, 3, 8, + 145, 129, 328, 329, 330, 145, 145, 333, 334, 145, + 249, 250, 145, 129, 129, 95, 96, 97, 98, 99, + 100, 65, 66, 67, 68, 69, 145, 377, 378, 50, + 8, 145, 328, 145, 95, 129, 3, 333, 334, 111, + 145, 121, 145, 51, 6, 145, 285, 145, 249, 250, + 130, 131, 132, 133, 134, 135, 136, 145, 138, 145, + 92, 145, 8, 413, 35, 171, 32, 65, 66, 67, + 68, 69, 203, 415, -1, -1, 33, -1, 404, 405, + 406, -1, 408, -1, 285, -1, 128, -1, -1, 328, + -1, -1, -1, -1, 333, 334, 36, -1, 424, 425, + -1, 145, 389, 128, -1, -1, 393, 394, 404, 405, + -1, 97, 98, 99, 100, 410, 442, -1, -1, -1, + -1, 447, 65, 66, 67, 68, 69, 328, 424, 425, + -1, -1, 333, 334, 132, 133, -1, -1, 95, 96, + 97, 98, 99, 100, 130, 131, 132, 133, 134, 135, + 136, -1, 138, -1, -1, 95, 96, 97, 98, 99, + 100, 3, 4, 5, 6, 404, 405, 9, -1, -1, + -1, -1, 14, 130, 131, 132, 133, 134, 135, 136, + -1, 138, -1, -1, -1, 424, 425, -1, 30, 31, + 130, 131, 132, 133, 134, 135, 136, -1, 138, -1, + -1, -1, -1, 404, 405, -1, -1, -1, -1, -1, + -1, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 424, 425, -1, -1, -1, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 99, + 100, 83, 84, 85, 86, 132, 133, 134, 135, 136, + -1, 138, -1, -1, -1, -1, -1, -1, -1, 101, + 102, 103, 104, 105, 106, 107, 108, 109, -1, -1, + 130, 131, 132, 133, 134, 135, 136, -1, 138, 121, + -1, -1, -1, -1, 126, 127, -1, -1, -1, -1, + -1, 133, -1, -1, -1, 137, 3, 4, 5, 6, + 7, -1, 9, 145, -1, -1, -1, 14, 15, 16, + 17, 18, 19, 20, 21, 22, -1, -1, 25, -1, + -1, 28, 29, 30, 31, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, -1, -1, + -1, -1, -1, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, -1, 83, 84, 85, 86, + 87, 88, -1, -1, 91, -1, 93, -1, -1, -1, + -1, -1, -1, -1, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, -1, 112, -1, -1, -1, -1, + -1, -1, -1, -1, 121, 122, -1, -1, -1, 126, + 127, 128, -1, -1, 3, 4, 133, 6, 7, -1, + 137, -1, -1, -1, -1, 142, 15, 16, 17, 18, + 19, 20, 21, 22, -1, -1, 25, -1, -1, 28, + 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, + 3, 4, -1, 6, 7, -1, -1, -1, -1, -1, + -1, -1, 15, 16, 17, 18, 19, 20, 21, 22, + -1, -1, 25, -1, -1, 28, 29, 30, 31, 95, + 96, 97, 98, 99, 100, -1, -1, -1, -1, -1, + -1, -1, 81, -1, -1, -1, -1, -1, 87, 88, + -1, -1, 91, -1, 93, -1, -1, -1, -1, -1, + -1, -1, -1, 129, 130, 131, 132, 133, 134, 135, + 136, 110, 138, 112, -1, -1, -1, -1, 81, -1, + -1, -1, 121, 122, 87, 88, -1, -1, 91, 128, + 93, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 139, -1, -1, 142, -1, -1, -1, 110, -1, 112, + -1, -1, -1, -1, -1, -1, -1, -1, 121, 122, + 3, 4, 5, 6, -1, 128, 9, -1, 11, 12, + 13, 14, -1, -1, -1, -1, -1, -1, -1, 142, + 23, 24, -1, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, -1, -1, -1, -1, -1, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, -1, -1, -1, -1, -1, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, -1, -1, + 83, 84, 85, 86, -1, -1, 89, 90, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 101, 102, + 103, 104, 105, 106, 107, 108, 109, -1, -1, -1, + 113, 114, 115, 116, 117, 118, 119, 120, 121, -1, + -1, -1, -1, 126, 127, 3, 4, 5, 6, -1, + 133, 9, -1, -1, 137, -1, 14, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 30, 31, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, -1, -1, -1, + -1, -1, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, -1, -1, 83, 84, 85, 86, -1, + 3, 4, 5, 6, -1, -1, 9, -1, -1, -1, + -1, 14, -1, 101, 102, 103, 104, 105, 106, 107, + 108, 109, -1, -1, -1, -1, -1, 30, 31, -1, + -1, -1, -1, 121, -1, -1, -1, 125, 126, 127, + -1, -1, -1, -1, -1, 133, -1, -1, -1, 137, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, -1, -1, -1, -1, -1, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, -1, -1, + 83, 84, 85, 86, -1, 3, 4, 5, 6, -1, + -1, 9, -1, -1, -1, -1, 14, -1, 101, 102, + 103, 104, 105, 106, 107, 108, 109, -1, -1, -1, + -1, -1, 30, 31, -1, -1, -1, -1, 121, -1, + -1, -1, -1, 126, 127, -1, -1, -1, -1, -1, + 133, -1, -1, -1, 137, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, -1, -1, -1, + -1, -1, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, -1, -1, 83, 84, 85, 86, -1, + 3, 4, 5, 6, -1, -1, 9, -1, -1, -1, + -1, 14, -1, 101, 102, 103, 104, 105, 106, 107, + 108, 109, -1, -1, -1, -1, -1, 30, 31, -1, + -1, -1, -1, 121, -1, -1, -1, -1, 126, 127, + -1, -1, -1, -1, -1, 133, -1, -1, -1, 137, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, -1, -1, -1, -1, -1, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, -1, -1, + 83, 84, 85, 86, -1, 3, 4, 5, 6, -1, + -1, 9, -1, -1, -1, -1, 14, -1, 101, 102, + 103, 104, 105, 106, 107, 108, 109, -1, -1, -1, + -1, -1, 30, 31, -1, -1, -1, -1, 121, -1, + -1, -1, -1, 126, 127, -1, -1, -1, -1, -1, + 133, -1, -1, -1, 137, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, -1, -1, -1, + -1, -1, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, -1, -1, 83, 84, 85, 86, -1, + 3, 4, 5, -1, -1, -1, 9, -1, -1, -1, + -1, 14, -1, 101, 102, 103, 104, 105, 106, 107, + 108, 109, -1, -1, -1, -1, -1, 30, 31, -1, + -1, -1, -1, 121, -1, -1, -1, -1, 126, 127, + -1, -1, -1, -1, -1, 133, -1, -1, -1, 137, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, -1, -1, -1, -1, -1, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, -1, -1, + 83, 84, 85, 86, -1, 3, 4, 5, -1, -1, + -1, 9, -1, -1, -1, -1, 14, -1, 101, 102, + 103, 104, 105, 106, 107, 108, 109, -1, -1, -1, + -1, -1, 30, 31, -1, -1, -1, -1, -1, -1, + -1, -1, 125, 126, 127, -1, -1, -1, -1, -1, + 133, -1, -1, -1, 137, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, -1, -1, -1, + -1, -1, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, -1, -1, 83, 84, 85, 86, -1, + 3, 4, 5, -1, -1, -1, 9, -1, -1, -1, + -1, 14, -1, 101, 102, 103, 104, 105, 106, 107, + 108, 109, -1, -1, -1, -1, -1, 30, 31, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 126, 127, + -1, -1, -1, -1, -1, 133, 134, -1, -1, 137, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, -1, -1, -1, -1, -1, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, -1, -1, + 83, 84, 85, 86, -1, 3, 4, 5, -1, -1, + -1, 9, -1, -1, -1, -1, 14, -1, 101, 102, + 103, 104, 105, 106, 107, 108, 109, -1, -1, -1, + -1, -1, 30, 31, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 126, 127, -1, -1, -1, -1, -1, + 133, -1, -1, -1, 137, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, -1, -1, -1, + -1, -1, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, -1, -1, 83, 84, 85, 86, -1, + 3, 4, 5, -1, -1, -1, 9, -1, -1, -1, + -1, 14, -1, 101, 102, 103, 104, 105, 106, 107, + 108, 109, -1, -1, -1, -1, -1, 30, 31, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 126, 127, + -1, -1, -1, -1, -1, 133, -1, -1, -1, 137, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, -1, -1, -1, -1, -1, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, -1, -1, + 83, 84, 85, 86, -1, -1, 3, 4, 5, -1, + -1, -1, 9, -1, -1, -1, -1, 14, 101, 102, + 103, 104, 105, 106, 107, 108, 109, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 126, 127, -1, -1, -1, -1, -1, + 133, 48, -1, -1, 137, -1, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, -1, -1, + -1, -1, -1, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, -1, -1, 83, 84, 85, 86, + -1, -1, 3, 4, 5, -1, -1, -1, 9, -1, + -1, -1, -1, 14, 101, 102, 103, 104, 105, 106, + 107, 108, 109, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 126, + 127, -1, -1, -1, -1, -1, 133, 48, -1, -1, + 137, -1, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, -1, -1, -1, -1, -1, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + -1, -1, 83, 84, 85, 86, -1, 3, 4, 5, + -1, -1, -1, 9, -1, -1, -1, -1, 14, -1, + 101, 102, 103, 104, 105, 106, 107, 108, 109, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 126, 127, -1, -1, -1, + -1, -1, 133, -1, -1, -1, 137, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, -1, + -1, -1, -1, -1, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, -1, -1, 83, 84, 85, + 86, 30, 31, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 101, 102, 103, 104, 105, + 106, 107, 108, 109, -1, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 30, 31, -1, -1, + 126, 127, -1, -1, -1, -1, -1, 133, -1, -1, + -1, 137, -1, -1, 83, 84, 85, 86, -1, -1, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, -1, 101, 102, 103, 104, 105, 106, 107, 108, + 109, -1, -1, -1, -1, 48, -1, -1, 51, 83, + 84, 85, 86, -1, -1, 48, 125, -1, 51, -1, + -1, -1, -1, -1, -1, -1, -1, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 95, 96, 97, 98, + 99, 100, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 125, 95, 96, 97, 98, 99, 100, -1, -1, + -1, -1, 95, 96, 97, 98, 99, 100, -1, -1, + 129, 130, 131, 132, 133, 134, 135, 136, -1, 138, + -1, -1, -1, -1, -1, -1, 129, 130, 131, 132, + 133, 134, 135, 136, -1, 138, 129, 130, 131, 132, + 133, 134, 135, 136, -1, 138, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, -1, -1, + -1, -1, -1, -1, -1, 83, 84, 85, 86, -1, + -1, -1, -1, -1, -1, -1, 83, 84, 85, 86, + -1, -1, -1, 101, 102, 103, 104, 105, 106, 107, + 108, 109, -1, -1, 101, 102, 103, 104, 105, 106, + 107, 108, 109, -1, -1, -1, -1, 125, 95, 96, + 97, 98, 99, 100, -1, -1, -1, 95, 96, 97, + 98, 99, 100, -1, -1, -1, 95, -1, 97, 98, + 99, 100, -1, -1, -1, 95, -1, 97, 98, 99, + 100, -1, -1, 130, 131, 132, 133, 134, 135, 136, + -1, 138, 130, 131, 132, 133, 134, 135, 136, -1, + 138, 130, 131, 132, 133, 134, 135, 136, -1, 138, + 130, 131, 132, 133, 134, 135, 136, -1, 138 +}; + +/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of + state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 139, 147, 148, 150, 151, 0, 3, 4, 6, + 7, 15, 16, 17, 18, 19, 20, 21, 22, 25, + 28, 29, 30, 31, 81, 87, 88, 91, 93, 110, + 112, 121, 122, 128, 142, 149, 152, 161, 164, 170, + 174, 176, 139, 141, 140, 141, 140, 6, 82, 153, + 3, 4, 5, 9, 14, 30, 31, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 83, 84, 85, 86, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 126, 127, 133, 137, 162, 163, 176, + 178, 179, 181, 182, 183, 184, 185, 186, 191, 192, + 193, 194, 4, 126, 137, 167, 168, 176, 182, 192, + 194, 4, 192, 126, 162, 175, 171, 150, 151, 4, + 129, 94, 11, 12, 13, 23, 24, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 89, + 90, 113, 114, 115, 116, 117, 118, 119, 120, 176, + 192, 150, 167, 140, 3, 4, 160, 82, 156, 8, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 30, 31, 101, 102, 30, 31, 101, 102, 167, + 178, 181, 182, 192, 194, 167, 192, 192, 163, 132, + 133, 65, 66, 67, 68, 69, 125, 191, 6, 14, + 15, 16, 17, 18, 19, 20, 22, 128, 187, 187, + 48, 183, 48, 51, 95, 96, 97, 98, 99, 100, + 129, 130, 131, 132, 133, 134, 135, 136, 138, 180, + 130, 140, 168, 192, 37, 95, 96, 97, 98, 95, + 96, 176, 6, 148, 150, 148, 170, 4, 159, 192, + 192, 192, 192, 192, 192, 192, 192, 178, 192, 178, + 178, 3, 9, 14, 125, 126, 178, 188, 189, 190, + 191, 126, 181, 192, 192, 192, 192, 192, 192, 176, + 176, 176, 192, 192, 3, 4, 30, 31, 170, 178, + 179, 182, 167, 154, 8, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 145, 167, 167, 145, 129, 132, + 133, 145, 145, 180, 130, 10, 181, 181, 3, 144, + 183, 49, 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 178, 178, 192, + 165, 168, 192, 168, 192, 176, 176, 168, 192, 168, + 192, 177, 144, 143, 8, 189, 191, 187, 187, 3, + 189, 125, 191, 181, 192, 8, 157, 145, 145, 129, + 145, 145, 145, 129, 129, 145, 145, 145, 178, 181, + 181, 178, 178, 50, 52, 129, 33, 8, 129, 145, + 172, 189, 189, 129, 3, 155, 111, 166, 167, 167, + 167, 145, 145, 145, 52, 129, 51, 178, 178, 192, + 192, 170, 173, 189, 166, 6, 145, 145, 145, 178, + 178, 131, 36, 169, 145, 145, 131, 134, 192, 92, + 145, 192, 158, 8 +}; + +/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ +static const yytype_uint8 yyr1[] = +{ + 0, 146, 147, 147, 148, 149, 149, 150, 150, 151, + 151, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 153, 152, 152, 154, 155, 152, 156, 157, 152, + 158, 152, 152, 159, 152, 152, 152, 160, 160, 161, + 161, 161, 162, 162, 163, 163, 163, 165, 164, 166, + 166, 167, 167, 168, 168, 168, 168, 168, 168, 168, + 168, 168, 169, 169, 169, 170, 170, 170, 170, 171, + 172, 170, 170, 173, 173, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 175, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 176, 176, 177, 177, + 178, 178, 178, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 180, 180, 181, 181, 182, 182, 182, + 182, 182, 183, 183, 183, 184, 184, 185, 185, 186, + 186, 187, 187, 187, 187, 187, 187, 187, 187, 187, + 188, 188, 189, 189, 189, 190, 190, 190, 190, 190, + 190, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 192, 192, 193, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, + 194 +}; + +/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ +static const yytype_int8 yyr2[] = +{ + 0, 2, 1, 1, 3, 1, 3, 0, 1, 1, + 2, 3, 3, 4, 1, 1, 1, 1, 1, 2, + 2, 0, 3, 2, 0, 0, 7, 0, 0, 6, + 0, 10, 1, 0, 4, 1, 1, 1, 1, 2, + 2, 3, 1, 2, 1, 1, 1, 0, 5, 0, + 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, + 3, 2, 0, 2, 3, 1, 4, 4, 4, 0, + 0, 6, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 3, 0, 4, 3, 3, + 3, 3, 2, 2, 3, 2, 3, 2, 3, 2, + 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, + 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, + 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 3, 2, 1, 5, 0, 3, + 1, 1, 3, 1, 3, 5, 3, 5, 5, 5, + 7, 6, 8, 1, 4, 3, 3, 1, 2, 2, + 3, 1, 1, 1, 3, 1, 3, 1, 2, 2, + 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, + 2, 3, 1, 1, 2, 1, 5, 4, 3, 3, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, + 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 1, 1, 2, 2, + 2, 2, 2, 3, 3, 3, 3, 3, 3, 2, + 3, 4, 4, 6, 4, 4, 4, 6, 6, 4, + 4, 3, 4, 3, 3, 3, 3, 3, 3, 3, + 2 +}; + + +enum { YYENOMEM = -2 }; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab +#define YYNOMEM goto yyexhaustedlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) + +/* Backward compatibility with an undocumented macro. + Use YYerror or YYUNDEF. */ +#define YYERRCODE YYUNDEF + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + + + + +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Kind, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) +{ + FILE *yyoutput = yyo; + YY_USE (yyoutput); + if (!yyvaluep) + return; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YY_USE (yykind); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ + +static void +yy_symbol_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) +{ + YYFPRINTF (yyo, "%s %s (", + yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); + + yy_symbol_value_print (yyo, yykind, yyvaluep); + YYFPRINTF (yyo, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, + int yyrule) +{ + int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), + &yyvsp[(yyi + 1) - (yynrhs)]); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) ((void) 0) +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + + + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, + yysymbol_kind_t yykind, YYSTYPE *yyvaluep) +{ + YY_USE (yyvaluep); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YY_USE (yykind); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + +/* Lookahead token kind. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; +/* Number of syntax errors so far. */ +int yynerrs; + + + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (void) +{ + yy_state_fast_t yystate = 0; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus = 0; + + /* Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* Their size. */ + YYPTRDIFF_T yystacksize = YYINITDEPTH; + + /* The state stack: array, bottom, top. */ + yy_state_t yyssa[YYINITDEPTH]; + yy_state_t *yyss = yyssa; + yy_state_t *yyssp = yyss; + + /* The semantic value stack: array, bottom, top. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp = yyvs; + + int yyn; + /* The return value of yyparse. */ + int yyresult; + /* Lookahead symbol kind. */ + yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yychar = YYEMPTY; /* Cause a token to be read. */ + + goto yysetstate; + + +/*------------------------------------------------------------. +| yynewstate -- push a new state, which is found in yystate. | +`------------------------------------------------------------*/ +yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + +/*--------------------------------------------------------------------. +| yysetstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + YY_ASSERT (0 <= yystate && yystate < YYNSTATES); + YY_IGNORE_USELESS_CAST_BEGIN + *yyssp = YY_CAST (yy_state_t, yystate); + YY_IGNORE_USELESS_CAST_END + YY_STACK_PRINT (yyss, yyssp); + + if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + YYNOMEM; +#else + { + /* Get the current used size of the three stacks, in elements. */ + YYPTRDIFF_T yysize = yyssp - yyss + 1; + +# if defined yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + yy_state_t *yyss1 = yyss; + YYSTYPE *yyvs1 = yyvs; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * YYSIZEOF (*yyssp), + &yyvs1, yysize * YYSIZEOF (*yyvsp), + &yystacksize); + yyss = yyss1; + yyvs = yyvs1; + } +# else /* defined YYSTACK_RELOCATE */ + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + YYNOMEM; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yy_state_t *yyss1 = yyss; + union yyalloc *yyptr = + YY_CAST (union yyalloc *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); + if (! yyptr) + YYNOMEM; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YY_IGNORE_USELESS_CAST_BEGIN + YYDPRINTF ((stderr, "Stack size increased to %ld\n", + YY_CAST (long, yystacksize))); + YY_IGNORE_USELESS_CAST_END + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ + + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token\n")); + yychar = yylex (); + } + + if (yychar <= YYEOF) + { + yychar = YYEOF; + yytoken = YYSYMBOL_YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else if (yychar == YYerror) + { + /* The scanner already issued an error message, process directly + to error recovery. But do not keep the error token as + lookahead, it is too special and may lead us to an endless + loop in error recovery. */ + yychar = YYUNDEF; + yytoken = YYSYMBOL_YYerror; + goto yyerrlab1; + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + /* Discard the shifted token. */ + yychar = YYEMPTY; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 3: /* top: element_list */ +#line 277 "../src/preproc/pic/pic.ypp" + { + if (olist.head) + print_picture(olist.head); + } +#line 2343 "src/preproc/pic/pic.cpp" + break; + + case 4: /* element_list: optional_separator middle_element_list optional_separator */ +#line 286 "../src/preproc/pic/pic.ypp" + { (yyval.pl) = (yyvsp[-1].pl); } +#line 2349 "src/preproc/pic/pic.cpp" + break; + + case 5: /* middle_element_list: element */ +#line 291 "../src/preproc/pic/pic.ypp" + { (yyval.pl) = (yyvsp[0].pl); } +#line 2355 "src/preproc/pic/pic.cpp" + break; + + case 6: /* middle_element_list: middle_element_list separator element */ +#line 293 "../src/preproc/pic/pic.ypp" + { (yyval.pl) = (yyvsp[-2].pl); } +#line 2361 "src/preproc/pic/pic.cpp" + break; + + case 11: /* placeless_element: FIGNAME '=' macro_name */ +#line 308 "../src/preproc/pic/pic.ypp" + { + delete[] graphname; + graphname = new char[strlen((yyvsp[0].str)) + 1]; + strcpy(graphname, (yyvsp[0].str)); + delete[] (yyvsp[0].str); + } +#line 2372 "src/preproc/pic/pic.cpp" + break; + + case 12: /* placeless_element: VARIABLE '=' any_expr */ +#line 316 "../src/preproc/pic/pic.ypp" + { + define_variable((yyvsp[-2].str), (yyvsp[0].x)); + free((yyvsp[-2].str)); + } +#line 2381 "src/preproc/pic/pic.cpp" + break; + + case 13: /* placeless_element: VARIABLE ':' '=' any_expr */ +#line 321 "../src/preproc/pic/pic.ypp" + { + place *p = lookup_label((yyvsp[-3].str)); + if (!p) { + lex_error("variable '%1' not defined", (yyvsp[-3].str)); + YYABORT; + } + p->obj = 0; + p->x = (yyvsp[0].x); + p->y = 0.0; + free((yyvsp[-3].str)); + } +#line 2397 "src/preproc/pic/pic.cpp" + break; + + case 14: /* placeless_element: UP */ +#line 333 "../src/preproc/pic/pic.ypp" + { current_direction = UP_DIRECTION; } +#line 2403 "src/preproc/pic/pic.cpp" + break; + + case 15: /* placeless_element: DOWN */ +#line 335 "../src/preproc/pic/pic.ypp" + { current_direction = DOWN_DIRECTION; } +#line 2409 "src/preproc/pic/pic.cpp" + break; + + case 16: /* placeless_element: LEFT */ +#line 337 "../src/preproc/pic/pic.ypp" + { current_direction = LEFT_DIRECTION; } +#line 2415 "src/preproc/pic/pic.cpp" + break; + + case 17: /* placeless_element: RIGHT */ +#line 339 "../src/preproc/pic/pic.ypp" + { current_direction = RIGHT_DIRECTION; } +#line 2421 "src/preproc/pic/pic.cpp" + break; + + case 18: /* placeless_element: COMMAND_LINE */ +#line 341 "../src/preproc/pic/pic.ypp" + { + olist.append(make_command_object((yyvsp[0].lstr).str, (yyvsp[0].lstr).filename, + (yyvsp[0].lstr).lineno)); + } +#line 2430 "src/preproc/pic/pic.cpp" + break; + + case 19: /* placeless_element: COMMAND print_args */ +#line 346 "../src/preproc/pic/pic.ypp" + { + olist.append(make_command_object((yyvsp[0].lstr).str, (yyvsp[0].lstr).filename, + (yyvsp[0].lstr).lineno)); + } +#line 2439 "src/preproc/pic/pic.cpp" + break; + + case 20: /* placeless_element: PRINT print_args */ +#line 351 "../src/preproc/pic/pic.ypp" + { + fprintf(stderr, "%s\n", (yyvsp[0].lstr).str); + delete[] (yyvsp[0].lstr).str; + fflush(stderr); + } +#line 2449 "src/preproc/pic/pic.cpp" + break; + + case 21: /* $@1: %empty */ +#line 357 "../src/preproc/pic/pic.ypp" + { delim_flag = 1; } +#line 2455 "src/preproc/pic/pic.cpp" + break; + + case 22: /* placeless_element: SH $@1 DELIMITED */ +#line 359 "../src/preproc/pic/pic.ypp" + { + delim_flag = 0; + if (safer_flag) + lex_error("unsafe to run command '%1'; ignoring", + (yyvsp[0].str)); + else { + int retval = system((yyvsp[0].str)); + if (retval < 0) + lex_error("error running command '%1': system()" + " returned %2", (yyvsp[0].str), retval); + } + delete[] (yyvsp[0].str); + } +#line 2473 "src/preproc/pic/pic.cpp" + break; + + case 23: /* placeless_element: COPY TEXT */ +#line 373 "../src/preproc/pic/pic.ypp" + { + if (yychar < 0) + do_lookahead(); + do_copy((yyvsp[0].lstr).str); + // do not delete the filename + } +#line 2484 "src/preproc/pic/pic.cpp" + break; + + case 24: /* $@2: %empty */ +#line 380 "../src/preproc/pic/pic.ypp" + { delim_flag = 2; } +#line 2490 "src/preproc/pic/pic.cpp" + break; + + case 25: /* $@3: %empty */ +#line 382 "../src/preproc/pic/pic.ypp" + { delim_flag = 0; } +#line 2496 "src/preproc/pic/pic.cpp" + break; + + case 26: /* placeless_element: COPY TEXT THRU $@2 DELIMITED $@3 until */ +#line 384 "../src/preproc/pic/pic.ypp" + { + if (yychar < 0) + do_lookahead(); + copy_file_thru((yyvsp[-5].lstr).str, (yyvsp[-2].str), (yyvsp[0].str)); + // do not delete the filename + delete[] (yyvsp[-2].str); + delete[] (yyvsp[0].str); + } +#line 2509 "src/preproc/pic/pic.cpp" + break; + + case 27: /* $@4: %empty */ +#line 393 "../src/preproc/pic/pic.ypp" + { delim_flag = 2; } +#line 2515 "src/preproc/pic/pic.cpp" + break; + + case 28: /* $@5: %empty */ +#line 395 "../src/preproc/pic/pic.ypp" + { delim_flag = 0; } +#line 2521 "src/preproc/pic/pic.cpp" + break; + + case 29: /* placeless_element: COPY THRU $@4 DELIMITED $@5 until */ +#line 397 "../src/preproc/pic/pic.ypp" + { + if (yychar < 0) + do_lookahead(); + copy_rest_thru((yyvsp[-2].str), (yyvsp[0].str)); + delete[] (yyvsp[-2].str); + delete[] (yyvsp[0].str); + } +#line 2533 "src/preproc/pic/pic.cpp" + break; + + case 30: /* $@6: %empty */ +#line 405 "../src/preproc/pic/pic.ypp" + { delim_flag = 1; } +#line 2539 "src/preproc/pic/pic.cpp" + break; + + case 31: /* placeless_element: FOR VARIABLE '=' expr TO expr optional_by DO $@6 DELIMITED */ +#line 407 "../src/preproc/pic/pic.ypp" + { + delim_flag = 0; + if (yychar < 0) + do_lookahead(); + do_for((yyvsp[-8].str), (yyvsp[-6].x), (yyvsp[-4].x), (yyvsp[-3].by).is_multiplicative, (yyvsp[-3].by).val, (yyvsp[0].str)); + } +#line 2550 "src/preproc/pic/pic.cpp" + break; + + case 32: /* placeless_element: simple_if */ +#line 414 "../src/preproc/pic/pic.ypp" + { + if (yychar < 0) + do_lookahead(); + if ((yyvsp[0].if_data).x != 0.0) + push_body((yyvsp[0].if_data).body); + delete[] (yyvsp[0].if_data).body; + } +#line 2562 "src/preproc/pic/pic.cpp" + break; + + case 33: /* $@7: %empty */ +#line 422 "../src/preproc/pic/pic.ypp" + { delim_flag = 1; } +#line 2568 "src/preproc/pic/pic.cpp" + break; + + case 34: /* placeless_element: simple_if ELSE $@7 DELIMITED */ +#line 424 "../src/preproc/pic/pic.ypp" + { + delim_flag = 0; + if (yychar < 0) + do_lookahead(); + if ((yyvsp[-3].if_data).x != 0.0) + push_body((yyvsp[-3].if_data).body); + else + push_body((yyvsp[0].str)); + free((yyvsp[-3].if_data).body); + free((yyvsp[0].str)); + } +#line 2584 "src/preproc/pic/pic.cpp" + break; + + case 36: /* placeless_element: RESET */ +#line 437 "../src/preproc/pic/pic.ypp" + { define_variable("scale", 1.0); } +#line 2590 "src/preproc/pic/pic.cpp" + break; + + case 39: /* reset_variables: RESET VARIABLE */ +#line 447 "../src/preproc/pic/pic.ypp" + { + reset((yyvsp[0].str)); + delete[] (yyvsp[0].str); + } +#line 2599 "src/preproc/pic/pic.cpp" + break; + + case 40: /* reset_variables: reset_variables VARIABLE */ +#line 452 "../src/preproc/pic/pic.ypp" + { + reset((yyvsp[0].str)); + delete[] (yyvsp[0].str); + } +#line 2608 "src/preproc/pic/pic.cpp" + break; + + case 41: /* reset_variables: reset_variables ',' VARIABLE */ +#line 457 "../src/preproc/pic/pic.ypp" + { + reset((yyvsp[0].str)); + delete[] (yyvsp[0].str); + } +#line 2617 "src/preproc/pic/pic.cpp" + break; + + case 42: /* print_args: print_arg */ +#line 465 "../src/preproc/pic/pic.ypp" + { (yyval.lstr) = (yyvsp[0].lstr); } +#line 2623 "src/preproc/pic/pic.cpp" + break; + + case 43: /* print_args: print_args print_arg */ +#line 467 "../src/preproc/pic/pic.ypp" + { + (yyval.lstr).str = new char[strlen((yyvsp[-1].lstr).str) + strlen((yyvsp[0].lstr).str) + 1]; + strcpy((yyval.lstr).str, (yyvsp[-1].lstr).str); + strcat((yyval.lstr).str, (yyvsp[0].lstr).str); + delete[] (yyvsp[-1].lstr).str; + delete[] (yyvsp[0].lstr).str; + if ((yyvsp[-1].lstr).filename) { + (yyval.lstr).filename = (yyvsp[-1].lstr).filename; + (yyval.lstr).lineno = (yyvsp[-1].lstr).lineno; + } + else if ((yyvsp[0].lstr).filename) { + (yyval.lstr).filename = (yyvsp[0].lstr).filename; + (yyval.lstr).lineno = (yyvsp[0].lstr).lineno; + } + } +#line 2643 "src/preproc/pic/pic.cpp" + break; + + case 44: /* print_arg: expr */ +#line 486 "../src/preproc/pic/pic.ypp" + { + (yyval.lstr).str = new char[GDIGITS + 1]; + sprintf((yyval.lstr).str, "%g", (yyvsp[0].x)); + (yyval.lstr).filename = 0; + (yyval.lstr).lineno = 0; + } +#line 2654 "src/preproc/pic/pic.cpp" + break; + + case 45: /* print_arg: text */ +#line 493 "../src/preproc/pic/pic.ypp" + { (yyval.lstr) = (yyvsp[0].lstr); } +#line 2660 "src/preproc/pic/pic.cpp" + break; + + case 46: /* print_arg: position */ +#line 495 "../src/preproc/pic/pic.ypp" + { + (yyval.lstr).str = new char[GDIGITS + 2 + GDIGITS + 1]; + sprintf((yyval.lstr).str, "%g, %g", (yyvsp[0].pair).x, (yyvsp[0].pair).y); + (yyval.lstr).filename = 0; + (yyval.lstr).lineno = 0; + } +#line 2671 "src/preproc/pic/pic.cpp" + break; + + case 47: /* $@8: %empty */ +#line 505 "../src/preproc/pic/pic.ypp" + { delim_flag = 1; } +#line 2677 "src/preproc/pic/pic.cpp" + break; + + case 48: /* simple_if: IF any_expr THEN $@8 DELIMITED */ +#line 507 "../src/preproc/pic/pic.ypp" + { + delim_flag = 0; + (yyval.if_data).x = (yyvsp[-3].x); + (yyval.if_data).body = (yyvsp[0].str); + } +#line 2687 "src/preproc/pic/pic.cpp" + break; + + case 49: /* until: %empty */ +#line 516 "../src/preproc/pic/pic.ypp" + { (yyval.str) = 0; } +#line 2693 "src/preproc/pic/pic.cpp" + break; + + case 50: /* until: UNTIL TEXT */ +#line 518 "../src/preproc/pic/pic.ypp" + { (yyval.str) = (yyvsp[0].lstr).str; } +#line 2699 "src/preproc/pic/pic.cpp" + break; + + case 51: /* any_expr: expr */ +#line 523 "../src/preproc/pic/pic.ypp" + { (yyval.x) = (yyvsp[0].x); } +#line 2705 "src/preproc/pic/pic.cpp" + break; + + case 52: /* any_expr: text_expr */ +#line 525 "../src/preproc/pic/pic.ypp" + { (yyval.x) = (yyvsp[0].x); } +#line 2711 "src/preproc/pic/pic.cpp" + break; + + case 53: /* text_expr: text EQUALEQUAL text */ +#line 530 "../src/preproc/pic/pic.ypp" + { + (yyval.x) = strcmp((yyvsp[-2].lstr).str, (yyvsp[0].lstr).str) == 0; + delete[] (yyvsp[-2].lstr).str; + delete[] (yyvsp[0].lstr).str; + } +#line 2721 "src/preproc/pic/pic.cpp" + break; + + case 54: /* text_expr: text NOTEQUAL text */ +#line 536 "../src/preproc/pic/pic.ypp" + { + (yyval.x) = strcmp((yyvsp[-2].lstr).str, (yyvsp[0].lstr).str) != 0; + delete[] (yyvsp[-2].lstr).str; + delete[] (yyvsp[0].lstr).str; + } +#line 2731 "src/preproc/pic/pic.cpp" + break; + + case 55: /* text_expr: text_expr ANDAND text_expr */ +#line 542 "../src/preproc/pic/pic.ypp" + { (yyval.x) = ((yyvsp[-2].x) != 0.0 && (yyvsp[0].x) != 0.0); } +#line 2737 "src/preproc/pic/pic.cpp" + break; + + case 56: /* text_expr: text_expr ANDAND expr */ +#line 544 "../src/preproc/pic/pic.ypp" + { (yyval.x) = ((yyvsp[-2].x) != 0.0 && (yyvsp[0].x) != 0.0); } +#line 2743 "src/preproc/pic/pic.cpp" + break; + + case 57: /* text_expr: expr ANDAND text_expr */ +#line 546 "../src/preproc/pic/pic.ypp" + { (yyval.x) = ((yyvsp[-2].x) != 0.0 && (yyvsp[0].x) != 0.0); } +#line 2749 "src/preproc/pic/pic.cpp" + break; + + case 58: /* text_expr: text_expr OROR text_expr */ +#line 548 "../src/preproc/pic/pic.ypp" + { (yyval.x) = ((yyvsp[-2].x) != 0.0 || (yyvsp[0].x) != 0.0); } +#line 2755 "src/preproc/pic/pic.cpp" + break; + + case 59: /* text_expr: text_expr OROR expr */ +#line 550 "../src/preproc/pic/pic.ypp" + { (yyval.x) = ((yyvsp[-2].x) != 0.0 || (yyvsp[0].x) != 0.0); } +#line 2761 "src/preproc/pic/pic.cpp" + break; + + case 60: /* text_expr: expr OROR text_expr */ +#line 552 "../src/preproc/pic/pic.ypp" + { (yyval.x) = ((yyvsp[-2].x) != 0.0 || (yyvsp[0].x) != 0.0); } +#line 2767 "src/preproc/pic/pic.cpp" + break; + + case 61: /* text_expr: '!' text_expr */ +#line 554 "../src/preproc/pic/pic.ypp" + { (yyval.x) = ((yyvsp[0].x) == 0.0); } +#line 2773 "src/preproc/pic/pic.cpp" + break; + + case 62: /* optional_by: %empty */ +#line 560 "../src/preproc/pic/pic.ypp" + { + (yyval.by).val = 1.0; + (yyval.by).is_multiplicative = 0; + } +#line 2782 "src/preproc/pic/pic.cpp" + break; + + case 63: /* optional_by: BY expr */ +#line 565 "../src/preproc/pic/pic.ypp" + { + (yyval.by).val = (yyvsp[0].x); + (yyval.by).is_multiplicative = 0; + } +#line 2791 "src/preproc/pic/pic.cpp" + break; + + case 64: /* optional_by: BY '*' expr */ +#line 570 "../src/preproc/pic/pic.ypp" + { + (yyval.by).val = (yyvsp[0].x); + (yyval.by).is_multiplicative = 1; + } +#line 2800 "src/preproc/pic/pic.cpp" + break; + + case 65: /* element: object_spec */ +#line 578 "../src/preproc/pic/pic.ypp" + { + (yyval.pl).obj = (yyvsp[0].spec)->make_object(¤t_position, + ¤t_direction); + if ((yyval.pl).obj == 0) + YYABORT; + delete (yyvsp[0].spec); + if ((yyval.pl).obj) + olist.append((yyval.pl).obj); + else { + (yyval.pl).x = current_position.x; + (yyval.pl).y = current_position.y; + } + } +#line 2818 "src/preproc/pic/pic.cpp" + break; + + case 66: /* element: LABEL ':' optional_separator element */ +#line 592 "../src/preproc/pic/pic.ypp" + { + (yyval.pl) = (yyvsp[0].pl); + define_label((yyvsp[-3].str), & (yyval.pl)); + free((yyvsp[-3].str)); + } +#line 2828 "src/preproc/pic/pic.cpp" + break; + + case 67: /* element: LABEL ':' optional_separator position_not_place */ +#line 598 "../src/preproc/pic/pic.ypp" + { + (yyval.pl).obj = 0; + (yyval.pl).x = (yyvsp[0].pair).x; + (yyval.pl).y = (yyvsp[0].pair).y; + define_label((yyvsp[-3].str), & (yyval.pl)); + free((yyvsp[-3].str)); + } +#line 2840 "src/preproc/pic/pic.cpp" + break; + + case 68: /* element: LABEL ':' optional_separator place */ +#line 606 "../src/preproc/pic/pic.ypp" + { + (yyval.pl) = (yyvsp[0].pl); + define_label((yyvsp[-3].str), & (yyval.pl)); + free((yyvsp[-3].str)); + } +#line 2850 "src/preproc/pic/pic.cpp" + break; + + case 69: /* @9: %empty */ +#line 612 "../src/preproc/pic/pic.ypp" + { + (yyval.state).x = current_position.x; + (yyval.state).y = current_position.y; + (yyval.state).dir = current_direction; + } +#line 2860 "src/preproc/pic/pic.cpp" + break; + + case 70: /* $@10: %empty */ +#line 618 "../src/preproc/pic/pic.ypp" + { + current_position.x = (yyvsp[-2].state).x; + current_position.y = (yyvsp[-2].state).y; + current_direction = (yyvsp[-2].state).dir; + } +#line 2870 "src/preproc/pic/pic.cpp" + break; + + case 71: /* element: '{' @9 element_list '}' $@10 optional_element */ +#line 624 "../src/preproc/pic/pic.ypp" + { + (yyval.pl) = (yyvsp[-3].pl); + } +#line 2878 "src/preproc/pic/pic.cpp" + break; + + case 72: /* element: placeless_element */ +#line 628 "../src/preproc/pic/pic.ypp" + { + (yyval.pl).obj = 0; + (yyval.pl).x = current_position.x; + (yyval.pl).y = current_position.y; + } +#line 2888 "src/preproc/pic/pic.cpp" + break; + + case 73: /* optional_element: %empty */ +#line 637 "../src/preproc/pic/pic.ypp" + {} +#line 2894 "src/preproc/pic/pic.cpp" + break; + + case 74: /* optional_element: element */ +#line 639 "../src/preproc/pic/pic.ypp" + {} +#line 2900 "src/preproc/pic/pic.cpp" + break; + + case 75: /* object_spec: BOX */ +#line 644 "../src/preproc/pic/pic.ypp" + { (yyval.spec) = new object_spec(BOX_OBJECT); } +#line 2906 "src/preproc/pic/pic.cpp" + break; + + case 76: /* object_spec: CIRCLE */ +#line 646 "../src/preproc/pic/pic.ypp" + { (yyval.spec) = new object_spec(CIRCLE_OBJECT); } +#line 2912 "src/preproc/pic/pic.cpp" + break; + + case 77: /* object_spec: ELLIPSE */ +#line 648 "../src/preproc/pic/pic.ypp" + { (yyval.spec) = new object_spec(ELLIPSE_OBJECT); } +#line 2918 "src/preproc/pic/pic.cpp" + break; + + case 78: /* object_spec: ARC */ +#line 650 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = new object_spec(ARC_OBJECT); + (yyval.spec)->dir = current_direction; + } +#line 2927 "src/preproc/pic/pic.cpp" + break; + + case 79: /* object_spec: LINE */ +#line 655 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = new object_spec(LINE_OBJECT); + lookup_variable("lineht", & (yyval.spec)->segment_height); + lookup_variable("linewid", & (yyval.spec)->segment_width); + (yyval.spec)->dir = current_direction; + } +#line 2938 "src/preproc/pic/pic.cpp" + break; + + case 80: /* object_spec: ARROW */ +#line 662 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = new object_spec(ARROW_OBJECT); + lookup_variable("lineht", & (yyval.spec)->segment_height); + lookup_variable("linewid", & (yyval.spec)->segment_width); + (yyval.spec)->dir = current_direction; + } +#line 2949 "src/preproc/pic/pic.cpp" + break; + + case 81: /* object_spec: MOVE */ +#line 669 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = new object_spec(MOVE_OBJECT); + lookup_variable("moveht", & (yyval.spec)->segment_height); + lookup_variable("movewid", & (yyval.spec)->segment_width); + (yyval.spec)->dir = current_direction; + } +#line 2960 "src/preproc/pic/pic.cpp" + break; + + case 82: /* object_spec: SPLINE */ +#line 676 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = new object_spec(SPLINE_OBJECT); + lookup_variable("lineht", & (yyval.spec)->segment_height); + lookup_variable("linewid", & (yyval.spec)->segment_width); + (yyval.spec)->dir = current_direction; + } +#line 2971 "src/preproc/pic/pic.cpp" + break; + + case 83: /* object_spec: text */ +#line 683 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = new object_spec(TEXT_OBJECT); + (yyval.spec)->text = new text_item((yyvsp[0].lstr).str, (yyvsp[0].lstr).filename, (yyvsp[0].lstr).lineno); + } +#line 2980 "src/preproc/pic/pic.cpp" + break; + + case 84: /* object_spec: PLOT expr */ +#line 688 "../src/preproc/pic/pic.ypp" + { + lex_warning("'plot' is deprecated; use 'sprintf'" + " instead"); + (yyval.spec) = new object_spec(TEXT_OBJECT); + (yyval.spec)->text = new text_item(format_number(0, (yyvsp[0].x)), 0, -1); + } +#line 2991 "src/preproc/pic/pic.cpp" + break; + + case 85: /* object_spec: PLOT expr text */ +#line 695 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = new object_spec(TEXT_OBJECT); + (yyval.spec)->text = new text_item(format_number((yyvsp[0].lstr).str, (yyvsp[-1].x)), + (yyvsp[0].lstr).filename, (yyvsp[0].lstr).lineno); + delete[] (yyvsp[0].lstr).str; + } +#line 3002 "src/preproc/pic/pic.cpp" + break; + + case 86: /* @11: %empty */ +#line 702 "../src/preproc/pic/pic.ypp" + { + saved_state *p = new saved_state; + (yyval.pstate) = p; + p->x = current_position.x; + p->y = current_position.y; + p->dir = current_direction; + p->tbl = current_table; + p->prev = current_saved_state; + current_position.x = 0.0; + current_position.y = 0.0; + current_table = new PTABLE(place); + current_saved_state = p; + olist.append(make_mark_object()); + } +#line 3021 "src/preproc/pic/pic.cpp" + break; + + case 87: /* object_spec: '[' @11 element_list ']' */ +#line 717 "../src/preproc/pic/pic.ypp" + { + current_position.x = (yyvsp[-2].pstate)->x; + current_position.y = (yyvsp[-2].pstate)->y; + current_direction = (yyvsp[-2].pstate)->dir; + (yyval.spec) = new object_spec(BLOCK_OBJECT); + olist.wrap_up_block(& (yyval.spec)->oblist); + (yyval.spec)->tbl = current_table; + current_table = (yyvsp[-2].pstate)->tbl; + current_saved_state = (yyvsp[-2].pstate)->prev; + delete (yyvsp[-2].pstate); + } +#line 3037 "src/preproc/pic/pic.cpp" + break; + + case 88: /* object_spec: object_spec HEIGHT expr */ +#line 729 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->height = (yyvsp[0].x); + (yyval.spec)->flags |= HAS_HEIGHT; + } +#line 3047 "src/preproc/pic/pic.cpp" + break; + + case 89: /* object_spec: object_spec RADIUS expr */ +#line 735 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->radius = (yyvsp[0].x); + (yyval.spec)->flags |= HAS_RADIUS; + } +#line 3057 "src/preproc/pic/pic.cpp" + break; + + case 90: /* object_spec: object_spec WIDTH expr */ +#line 741 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->width = (yyvsp[0].x); + (yyval.spec)->flags |= HAS_WIDTH; + } +#line 3067 "src/preproc/pic/pic.cpp" + break; + + case 91: /* object_spec: object_spec DIAMETER expr */ +#line 747 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->radius = (yyvsp[0].x)/2.0; + (yyval.spec)->flags |= HAS_RADIUS; + } +#line 3077 "src/preproc/pic/pic.cpp" + break; + + case 92: /* object_spec: object_spec expr */ +#line 753 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + (yyval.spec)->flags |= HAS_SEGMENT; + switch ((yyval.spec)->dir) { + case UP_DIRECTION: + (yyval.spec)->segment_pos.y += (yyvsp[0].x); + break; + case DOWN_DIRECTION: + (yyval.spec)->segment_pos.y -= (yyvsp[0].x); + break; + case RIGHT_DIRECTION: + (yyval.spec)->segment_pos.x += (yyvsp[0].x); + break; + case LEFT_DIRECTION: + (yyval.spec)->segment_pos.x -= (yyvsp[0].x); + break; + } + } +#line 3100 "src/preproc/pic/pic.cpp" + break; + + case 93: /* object_spec: object_spec UP */ +#line 772 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + (yyval.spec)->dir = UP_DIRECTION; + (yyval.spec)->flags |= HAS_SEGMENT; + (yyval.spec)->segment_pos.y += (yyval.spec)->segment_height; + } +#line 3111 "src/preproc/pic/pic.cpp" + break; + + case 94: /* object_spec: object_spec UP expr */ +#line 779 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->dir = UP_DIRECTION; + (yyval.spec)->flags |= HAS_SEGMENT; + (yyval.spec)->segment_pos.y += (yyvsp[0].x); + } +#line 3122 "src/preproc/pic/pic.cpp" + break; + + case 95: /* object_spec: object_spec DOWN */ +#line 786 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + (yyval.spec)->dir = DOWN_DIRECTION; + (yyval.spec)->flags |= HAS_SEGMENT; + (yyval.spec)->segment_pos.y -= (yyval.spec)->segment_height; + } +#line 3133 "src/preproc/pic/pic.cpp" + break; + + case 96: /* object_spec: object_spec DOWN expr */ +#line 793 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->dir = DOWN_DIRECTION; + (yyval.spec)->flags |= HAS_SEGMENT; + (yyval.spec)->segment_pos.y -= (yyvsp[0].x); + } +#line 3144 "src/preproc/pic/pic.cpp" + break; + + case 97: /* object_spec: object_spec RIGHT */ +#line 800 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + (yyval.spec)->dir = RIGHT_DIRECTION; + (yyval.spec)->flags |= HAS_SEGMENT; + (yyval.spec)->segment_pos.x += (yyval.spec)->segment_width; + } +#line 3155 "src/preproc/pic/pic.cpp" + break; + + case 98: /* object_spec: object_spec RIGHT expr */ +#line 807 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->dir = RIGHT_DIRECTION; + (yyval.spec)->flags |= HAS_SEGMENT; + (yyval.spec)->segment_pos.x += (yyvsp[0].x); + } +#line 3166 "src/preproc/pic/pic.cpp" + break; + + case 99: /* object_spec: object_spec LEFT */ +#line 814 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + (yyval.spec)->dir = LEFT_DIRECTION; + (yyval.spec)->flags |= HAS_SEGMENT; + (yyval.spec)->segment_pos.x -= (yyval.spec)->segment_width; + } +#line 3177 "src/preproc/pic/pic.cpp" + break; + + case 100: /* object_spec: object_spec LEFT expr */ +#line 821 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->dir = LEFT_DIRECTION; + (yyval.spec)->flags |= HAS_SEGMENT; + (yyval.spec)->segment_pos.x -= (yyvsp[0].x); + } +#line 3188 "src/preproc/pic/pic.cpp" + break; + + case 101: /* object_spec: object_spec FROM position */ +#line 828 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->flags |= HAS_FROM; + (yyval.spec)->from.x = (yyvsp[0].pair).x; + (yyval.spec)->from.y = (yyvsp[0].pair).y; + } +#line 3199 "src/preproc/pic/pic.cpp" + break; + + case 102: /* object_spec: object_spec TO position */ +#line 835 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + if ((yyval.spec)->flags & HAS_SEGMENT) + (yyval.spec)->segment_list = new segment((yyval.spec)->segment_pos, + (yyval.spec)->segment_is_absolute, + (yyval.spec)->segment_list); + (yyval.spec)->flags |= HAS_SEGMENT; + (yyval.spec)->segment_pos.x = (yyvsp[0].pair).x; + (yyval.spec)->segment_pos.y = (yyvsp[0].pair).y; + (yyval.spec)->segment_is_absolute = 1; + (yyval.spec)->flags |= HAS_TO; + (yyval.spec)->to.x = (yyvsp[0].pair).x; + (yyval.spec)->to.y = (yyvsp[0].pair).y; + } +#line 3218 "src/preproc/pic/pic.cpp" + break; + + case 103: /* object_spec: object_spec AT position */ +#line 850 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->flags |= HAS_AT; + (yyval.spec)->at.x = (yyvsp[0].pair).x; + (yyval.spec)->at.y = (yyvsp[0].pair).y; + if ((yyval.spec)->type != ARC_OBJECT) { + (yyval.spec)->flags |= HAS_FROM; + (yyval.spec)->from.x = (yyvsp[0].pair).x; + (yyval.spec)->from.y = (yyvsp[0].pair).y; + } + } +#line 3234 "src/preproc/pic/pic.cpp" + break; + + case 104: /* object_spec: object_spec WITH path */ +#line 862 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->flags |= HAS_WITH; + (yyval.spec)->with = (yyvsp[0].pth); + } +#line 3244 "src/preproc/pic/pic.cpp" + break; + + case 105: /* object_spec: object_spec WITH position */ +#line 868 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->flags |= HAS_WITH; + position pos; + pos.x = (yyvsp[0].pair).x; + pos.y = (yyvsp[0].pair).y; + (yyval.spec)->with = new path(pos); + } +#line 3257 "src/preproc/pic/pic.cpp" + break; + + case 106: /* object_spec: object_spec BY expr_pair */ +#line 877 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->flags |= HAS_SEGMENT; + (yyval.spec)->segment_pos.x += (yyvsp[0].pair).x; + (yyval.spec)->segment_pos.y += (yyvsp[0].pair).y; + } +#line 3268 "src/preproc/pic/pic.cpp" + break; + + case 107: /* object_spec: object_spec THEN */ +#line 884 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + if (!((yyval.spec)->flags & HAS_SEGMENT)) + switch ((yyval.spec)->dir) { + case UP_DIRECTION: + (yyval.spec)->segment_pos.y += (yyval.spec)->segment_width; + break; + case DOWN_DIRECTION: + (yyval.spec)->segment_pos.y -= (yyval.spec)->segment_width; + break; + case RIGHT_DIRECTION: + (yyval.spec)->segment_pos.x += (yyval.spec)->segment_width; + break; + case LEFT_DIRECTION: + (yyval.spec)->segment_pos.x -= (yyval.spec)->segment_width; + break; + } + (yyval.spec)->segment_list = new segment((yyval.spec)->segment_pos, + (yyval.spec)->segment_is_absolute, + (yyval.spec)->segment_list); + (yyval.spec)->flags &= ~HAS_SEGMENT; + (yyval.spec)->segment_pos.x = (yyval.spec)->segment_pos.y = 0.0; + (yyval.spec)->segment_is_absolute = 0; + } +#line 3297 "src/preproc/pic/pic.cpp" + break; + + case 108: /* object_spec: object_spec SOLID */ +#line 909 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); // nothing + } +#line 3305 "src/preproc/pic/pic.cpp" + break; + + case 109: /* object_spec: object_spec DOTTED */ +#line 913 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + (yyval.spec)->flags |= IS_DOTTED; + lookup_variable("dashwid", & (yyval.spec)->dash_width); + } +#line 3315 "src/preproc/pic/pic.cpp" + break; + + case 110: /* object_spec: object_spec DOTTED expr */ +#line 919 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->flags |= IS_DOTTED; + (yyval.spec)->dash_width = (yyvsp[0].x); + } +#line 3325 "src/preproc/pic/pic.cpp" + break; + + case 111: /* object_spec: object_spec DASHED */ +#line 925 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + (yyval.spec)->flags |= IS_DASHED; + lookup_variable("dashwid", & (yyval.spec)->dash_width); + } +#line 3335 "src/preproc/pic/pic.cpp" + break; + + case 112: /* object_spec: object_spec DASHED expr */ +#line 931 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->flags |= IS_DASHED; + (yyval.spec)->dash_width = (yyvsp[0].x); + } +#line 3345 "src/preproc/pic/pic.cpp" + break; + + case 113: /* object_spec: object_spec FILL */ +#line 937 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + (yyval.spec)->flags |= IS_DEFAULT_FILLED; + } +#line 3354 "src/preproc/pic/pic.cpp" + break; + + case 114: /* object_spec: object_spec FILL expr */ +#line 942 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->flags |= IS_FILLED; + (yyval.spec)->fill = (yyvsp[0].x); + } +#line 3364 "src/preproc/pic/pic.cpp" + break; + + case 115: /* object_spec: object_spec XSLANTED expr */ +#line 948 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->flags |= IS_XSLANTED; + (yyval.spec)->xslanted = (yyvsp[0].x); + } +#line 3374 "src/preproc/pic/pic.cpp" + break; + + case 116: /* object_spec: object_spec YSLANTED expr */ +#line 954 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->flags |= IS_YSLANTED; + (yyval.spec)->yslanted = (yyvsp[0].x); + } +#line 3384 "src/preproc/pic/pic.cpp" + break; + + case 117: /* object_spec: object_spec SHADED text */ +#line 960 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->flags |= (IS_SHADED | IS_FILLED); + (yyval.spec)->shaded = new char[strlen((yyvsp[0].lstr).str)+1]; + strcpy((yyval.spec)->shaded, (yyvsp[0].lstr).str); + } +#line 3395 "src/preproc/pic/pic.cpp" + break; + + case 118: /* object_spec: object_spec COLORED text */ +#line 967 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->flags |= (IS_SHADED | IS_OUTLINED | IS_FILLED); + (yyval.spec)->shaded = new char[strlen((yyvsp[0].lstr).str)+1]; + strcpy((yyval.spec)->shaded, (yyvsp[0].lstr).str); + (yyval.spec)->outlined = new char[strlen((yyvsp[0].lstr).str)+1]; + strcpy((yyval.spec)->outlined, (yyvsp[0].lstr).str); + } +#line 3408 "src/preproc/pic/pic.cpp" + break; + + case 119: /* object_spec: object_spec OUTLINED text */ +#line 976 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->flags |= IS_OUTLINED; + (yyval.spec)->outlined = new char[strlen((yyvsp[0].lstr).str)+1]; + strcpy((yyval.spec)->outlined, (yyvsp[0].lstr).str); + } +#line 3419 "src/preproc/pic/pic.cpp" + break; + + case 120: /* object_spec: object_spec CHOP */ +#line 983 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + // line chop chop means line chop 0 chop 0 + if ((yyval.spec)->flags & IS_DEFAULT_CHOPPED) { + (yyval.spec)->flags |= IS_CHOPPED; + (yyval.spec)->flags &= ~IS_DEFAULT_CHOPPED; + (yyval.spec)->start_chop = (yyval.spec)->end_chop = 0.0; + } + else if ((yyval.spec)->flags & IS_CHOPPED) { + (yyval.spec)->end_chop = 0.0; + } + else { + (yyval.spec)->flags |= IS_DEFAULT_CHOPPED; + } + } +#line 3439 "src/preproc/pic/pic.cpp" + break; + + case 121: /* object_spec: object_spec CHOP expr */ +#line 999 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + if ((yyval.spec)->flags & IS_DEFAULT_CHOPPED) { + (yyval.spec)->flags |= IS_CHOPPED; + (yyval.spec)->flags &= ~IS_DEFAULT_CHOPPED; + (yyval.spec)->start_chop = 0.0; + (yyval.spec)->end_chop = (yyvsp[0].x); + } + else if ((yyval.spec)->flags & IS_CHOPPED) { + (yyval.spec)->end_chop = (yyvsp[0].x); + } + else { + (yyval.spec)->start_chop = (yyval.spec)->end_chop = (yyvsp[0].x); + (yyval.spec)->flags |= IS_CHOPPED; + } + } +#line 3460 "src/preproc/pic/pic.cpp" + break; + + case 122: /* object_spec: object_spec SAME */ +#line 1016 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + (yyval.spec)->flags |= IS_SAME; + } +#line 3469 "src/preproc/pic/pic.cpp" + break; + + case 123: /* object_spec: object_spec INVISIBLE */ +#line 1021 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + (yyval.spec)->flags |= IS_INVISIBLE; + } +#line 3478 "src/preproc/pic/pic.cpp" + break; + + case 124: /* object_spec: object_spec LEFT_ARROW_HEAD */ +#line 1026 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + (yyval.spec)->flags |= HAS_LEFT_ARROW_HEAD; + } +#line 3487 "src/preproc/pic/pic.cpp" + break; + + case 125: /* object_spec: object_spec RIGHT_ARROW_HEAD */ +#line 1031 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + (yyval.spec)->flags |= HAS_RIGHT_ARROW_HEAD; + } +#line 3496 "src/preproc/pic/pic.cpp" + break; + + case 126: /* object_spec: object_spec DOUBLE_ARROW_HEAD */ +#line 1036 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + (yyval.spec)->flags |= (HAS_LEFT_ARROW_HEAD|HAS_RIGHT_ARROW_HEAD); + } +#line 3505 "src/preproc/pic/pic.cpp" + break; + + case 127: /* object_spec: object_spec CW */ +#line 1041 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + (yyval.spec)->flags |= IS_CLOCKWISE; + } +#line 3514 "src/preproc/pic/pic.cpp" + break; + + case 128: /* object_spec: object_spec CCW */ +#line 1046 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + (yyval.spec)->flags &= ~IS_CLOCKWISE; + } +#line 3523 "src/preproc/pic/pic.cpp" + break; + + case 129: /* object_spec: object_spec text */ +#line 1051 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + text_item **p; + for (p = & (yyval.spec)->text; *p; p = &(*p)->next) + ; + *p = new text_item((yyvsp[0].lstr).str, (yyvsp[0].lstr).filename, (yyvsp[0].lstr).lineno); + } +#line 3535 "src/preproc/pic/pic.cpp" + break; + + case 130: /* object_spec: object_spec LJUST */ +#line 1059 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + if ((yyval.spec)->text) { + text_item *p; + for (p = (yyval.spec)->text; p->next; p = p->next) + ; + p->adj.h = LEFT_ADJUST; + } + } +#line 3549 "src/preproc/pic/pic.cpp" + break; + + case 131: /* object_spec: object_spec RJUST */ +#line 1069 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + if ((yyval.spec)->text) { + text_item *p; + for (p = (yyval.spec)->text; p->next; p = p->next) + ; + p->adj.h = RIGHT_ADJUST; + } + } +#line 3563 "src/preproc/pic/pic.cpp" + break; + + case 132: /* object_spec: object_spec ABOVE */ +#line 1079 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + if ((yyval.spec)->text) { + text_item *p; + for (p = (yyval.spec)->text; p->next; p = p->next) + ; + p->adj.v = ABOVE_ADJUST; + } + } +#line 3577 "src/preproc/pic/pic.cpp" + break; + + case 133: /* object_spec: object_spec BELOW */ +#line 1089 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + if ((yyval.spec)->text) { + text_item *p; + for (p = (yyval.spec)->text; p->next; p = p->next) + ; + p->adj.v = BELOW_ADJUST; + } + } +#line 3591 "src/preproc/pic/pic.cpp" + break; + + case 134: /* object_spec: object_spec THICKNESS expr */ +#line 1099 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-2].spec); + (yyval.spec)->flags |= HAS_THICKNESS; + (yyval.spec)->thickness = (yyvsp[0].x); + } +#line 3601 "src/preproc/pic/pic.cpp" + break; + + case 135: /* object_spec: object_spec ALIGNED */ +#line 1105 "../src/preproc/pic/pic.ypp" + { + (yyval.spec) = (yyvsp[-1].spec); + (yyval.spec)->flags |= IS_ALIGNED; + } +#line 3610 "src/preproc/pic/pic.cpp" + break; + + case 136: /* text: TEXT */ +#line 1113 "../src/preproc/pic/pic.ypp" + { (yyval.lstr) = (yyvsp[0].lstr); } +#line 3616 "src/preproc/pic/pic.cpp" + break; + + case 137: /* text: SPRINTF '(' TEXT sprintf_args ')' */ +#line 1115 "../src/preproc/pic/pic.ypp" + { + (yyval.lstr).filename = (yyvsp[-2].lstr).filename; + (yyval.lstr).lineno = (yyvsp[-2].lstr).lineno; + (yyval.lstr).str = do_sprintf((yyvsp[-2].lstr).str, (yyvsp[-1].dv).v, (yyvsp[-1].dv).nv); + delete[] (yyvsp[-1].dv).v; + free((yyvsp[-2].lstr).str); + } +#line 3628 "src/preproc/pic/pic.cpp" + break; + + case 138: /* sprintf_args: %empty */ +#line 1126 "../src/preproc/pic/pic.ypp" + { + (yyval.dv).v = 0; + (yyval.dv).nv = 0; + (yyval.dv).maxv = 0; + } +#line 3638 "src/preproc/pic/pic.cpp" + break; + + case 139: /* sprintf_args: sprintf_args ',' expr */ +#line 1132 "../src/preproc/pic/pic.ypp" + { + (yyval.dv) = (yyvsp[-2].dv); + if ((yyval.dv).nv >= (yyval.dv).maxv) { + if ((yyval.dv).nv == 0) { + (yyval.dv).v = new double[4]; + (yyval.dv).maxv = 4; + } + else { + double *oldv = (yyval.dv).v; + (yyval.dv).maxv *= 2; +#if 0 + (yyval.dv).v = new double[(yyval.dv).maxv]; + memcpy((yyval.dv).v, oldv, (yyval.dv).nv*sizeof(double)); +#else + // workaround for bug in Compaq C++ V6.5-033 + // for Compaq Tru64 UNIX V5.1A (Rev. 1885) + double *foo = new double[(yyval.dv).maxv]; + memcpy(foo, oldv, (yyval.dv).nv*sizeof(double)); + (yyval.dv).v = foo; +#endif + delete[] oldv; + } + } + (yyval.dv).v[(yyval.dv).nv] = (yyvsp[0].x); + (yyval.dv).nv += 1; + } +#line 3669 "src/preproc/pic/pic.cpp" + break; + + case 140: /* position: position_not_place */ +#line 1162 "../src/preproc/pic/pic.ypp" + { (yyval.pair) = (yyvsp[0].pair); } +#line 3675 "src/preproc/pic/pic.cpp" + break; + + case 141: /* position: place */ +#line 1164 "../src/preproc/pic/pic.ypp" + { + position pos = (yyvsp[0].pl); + (yyval.pair).x = pos.x; + (yyval.pair).y = pos.y; + } +#line 3685 "src/preproc/pic/pic.cpp" + break; + + case 142: /* position: '(' place ')' */ +#line 1170 "../src/preproc/pic/pic.ypp" + { + position pos = (yyvsp[-1].pl); + (yyval.pair).x = pos.x; + (yyval.pair).y = pos.y; + } +#line 3695 "src/preproc/pic/pic.cpp" + break; + + case 143: /* position_not_place: expr_pair */ +#line 1179 "../src/preproc/pic/pic.ypp" + { (yyval.pair) = (yyvsp[0].pair); } +#line 3701 "src/preproc/pic/pic.cpp" + break; + + case 144: /* position_not_place: position '+' expr_pair */ +#line 1181 "../src/preproc/pic/pic.ypp" + { + (yyval.pair).x = (yyvsp[-2].pair).x + (yyvsp[0].pair).x; + (yyval.pair).y = (yyvsp[-2].pair).y + (yyvsp[0].pair).y; + } +#line 3710 "src/preproc/pic/pic.cpp" + break; + + case 145: /* position_not_place: '(' position '+' expr_pair ')' */ +#line 1186 "../src/preproc/pic/pic.ypp" + { + (yyval.pair).x = (yyvsp[-3].pair).x + (yyvsp[-1].pair).x; + (yyval.pair).y = (yyvsp[-3].pair).y + (yyvsp[-1].pair).y; + } +#line 3719 "src/preproc/pic/pic.cpp" + break; + + case 146: /* position_not_place: position '-' expr_pair */ +#line 1191 "../src/preproc/pic/pic.ypp" + { + (yyval.pair).x = (yyvsp[-2].pair).x - (yyvsp[0].pair).x; + (yyval.pair).y = (yyvsp[-2].pair).y - (yyvsp[0].pair).y; + } +#line 3728 "src/preproc/pic/pic.cpp" + break; + + case 147: /* position_not_place: '(' position '-' expr_pair ')' */ +#line 1196 "../src/preproc/pic/pic.ypp" + { + (yyval.pair).x = (yyvsp[-3].pair).x - (yyvsp[-1].pair).x; + (yyval.pair).y = (yyvsp[-3].pair).y - (yyvsp[-1].pair).y; + } +#line 3737 "src/preproc/pic/pic.cpp" + break; + + case 148: /* position_not_place: '(' position ',' position ')' */ +#line 1201 "../src/preproc/pic/pic.ypp" + { + (yyval.pair).x = (yyvsp[-3].pair).x; + (yyval.pair).y = (yyvsp[-1].pair).y; + } +#line 3746 "src/preproc/pic/pic.cpp" + break; + + case 149: /* position_not_place: expr between position AND position */ +#line 1206 "../src/preproc/pic/pic.ypp" + { + (yyval.pair).x = (1.0 - (yyvsp[-4].x))*(yyvsp[-2].pair).x + (yyvsp[-4].x)*(yyvsp[0].pair).x; + (yyval.pair).y = (1.0 - (yyvsp[-4].x))*(yyvsp[-2].pair).y + (yyvsp[-4].x)*(yyvsp[0].pair).y; + } +#line 3755 "src/preproc/pic/pic.cpp" + break; + + case 150: /* position_not_place: '(' expr between position AND position ')' */ +#line 1211 "../src/preproc/pic/pic.ypp" + { + (yyval.pair).x = (1.0 - (yyvsp[-5].x))*(yyvsp[-3].pair).x + (yyvsp[-5].x)*(yyvsp[-1].pair).x; + (yyval.pair).y = (1.0 - (yyvsp[-5].x))*(yyvsp[-3].pair).y + (yyvsp[-5].x)*(yyvsp[-1].pair).y; + } +#line 3764 "src/preproc/pic/pic.cpp" + break; + + case 151: /* position_not_place: expr_not_lower_than '<' position ',' position '>' */ +#line 1217 "../src/preproc/pic/pic.ypp" + { + (yyval.pair).x = (1.0 - (yyvsp[-5].x))*(yyvsp[-3].pair).x + (yyvsp[-5].x)*(yyvsp[-1].pair).x; + (yyval.pair).y = (1.0 - (yyvsp[-5].x))*(yyvsp[-3].pair).y + (yyvsp[-5].x)*(yyvsp[-1].pair).y; + } +#line 3773 "src/preproc/pic/pic.cpp" + break; + + case 152: /* position_not_place: '(' expr_not_lower_than '<' position ',' position '>' ')' */ +#line 1222 "../src/preproc/pic/pic.ypp" + { + (yyval.pair).x = (1.0 - (yyvsp[-6].x))*(yyvsp[-4].pair).x + (yyvsp[-6].x)*(yyvsp[-2].pair).x; + (yyval.pair).y = (1.0 - (yyvsp[-6].x))*(yyvsp[-4].pair).y + (yyvsp[-6].x)*(yyvsp[-2].pair).y; + } +#line 3782 "src/preproc/pic/pic.cpp" + break; + + case 155: /* expr_pair: expr ',' expr */ +#line 1235 "../src/preproc/pic/pic.ypp" + { + (yyval.pair).x = (yyvsp[-2].x); + (yyval.pair).y = (yyvsp[0].x); + } +#line 3791 "src/preproc/pic/pic.cpp" + break; + + case 156: /* expr_pair: '(' expr_pair ')' */ +#line 1240 "../src/preproc/pic/pic.ypp" + { (yyval.pair) = (yyvsp[-1].pair); } +#line 3797 "src/preproc/pic/pic.cpp" + break; + + case 157: /* place: label */ +#line 1246 "../src/preproc/pic/pic.ypp" + { (yyval.pl) = (yyvsp[0].pl); } +#line 3803 "src/preproc/pic/pic.cpp" + break; + + case 158: /* place: label corner */ +#line 1248 "../src/preproc/pic/pic.ypp" + { + path pth((yyvsp[0].crn)); + if (!pth.follow((yyvsp[-1].pl), & (yyval.pl))) + YYABORT; + } +#line 3813 "src/preproc/pic/pic.cpp" + break; + + case 159: /* place: corner label */ +#line 1254 "../src/preproc/pic/pic.ypp" + { + path pth((yyvsp[-1].crn)); + if (!pth.follow((yyvsp[0].pl), & (yyval.pl))) + YYABORT; + } +#line 3823 "src/preproc/pic/pic.cpp" + break; + + case 160: /* place: corner OF label */ +#line 1260 "../src/preproc/pic/pic.ypp" + { + path pth((yyvsp[-2].crn)); + if (!pth.follow((yyvsp[0].pl), & (yyval.pl))) + YYABORT; + } +#line 3833 "src/preproc/pic/pic.cpp" + break; + + case 161: /* place: HERE */ +#line 1266 "../src/preproc/pic/pic.ypp" + { + (yyval.pl).x = current_position.x; + (yyval.pl).y = current_position.y; + (yyval.pl).obj = 0; + } +#line 3843 "src/preproc/pic/pic.cpp" + break; + + case 162: /* label: LABEL */ +#line 1275 "../src/preproc/pic/pic.ypp" + { + place *p = lookup_label((yyvsp[0].str)); + if (!p) { + lex_error("there is no place '%1'", (yyvsp[0].str)); + YYABORT; + } + (yyval.pl) = *p; + free((yyvsp[0].str)); + } +#line 3857 "src/preproc/pic/pic.cpp" + break; + + case 163: /* label: nth_primitive */ +#line 1285 "../src/preproc/pic/pic.ypp" + { (yyval.pl).obj = (yyvsp[0].obj); } +#line 3863 "src/preproc/pic/pic.cpp" + break; + + case 164: /* label: label '.' LABEL */ +#line 1287 "../src/preproc/pic/pic.ypp" + { + path pth((yyvsp[0].str)); + if (!pth.follow((yyvsp[-2].pl), & (yyval.pl))) + YYABORT; + } +#line 3873 "src/preproc/pic/pic.cpp" + break; + + case 165: /* ordinal: ORDINAL */ +#line 1296 "../src/preproc/pic/pic.ypp" + { (yyval.n) = (yyvsp[0].n); } +#line 3879 "src/preproc/pic/pic.cpp" + break; + + case 166: /* ordinal: '`' any_expr TH */ +#line 1298 "../src/preproc/pic/pic.ypp" + { + // XXX Check for overflow (and non-integers?). + (yyval.n) = (int)(yyvsp[-1].x); + } +#line 3888 "src/preproc/pic/pic.cpp" + break; + + case 167: /* optional_ordinal_last: LAST */ +#line 1306 "../src/preproc/pic/pic.ypp" + { (yyval.n) = 1; } +#line 3894 "src/preproc/pic/pic.cpp" + break; + + case 168: /* optional_ordinal_last: ordinal LAST */ +#line 1308 "../src/preproc/pic/pic.ypp" + { (yyval.n) = (yyvsp[-1].n); } +#line 3900 "src/preproc/pic/pic.cpp" + break; + + case 169: /* nth_primitive: ordinal object_type */ +#line 1313 "../src/preproc/pic/pic.ypp" + { + int count = 0; + object *p; + for (p = olist.head; p != 0; p = p->next) + if (p->type() == (yyvsp[0].obtype) && ++count == (yyvsp[-1].n)) { + (yyval.obj) = p; + break; + } + if (p == 0) { + lex_error("there is no %1%2 %3", (yyvsp[-1].n), ordinal_postfix((yyvsp[-1].n)), + object_type_name((yyvsp[0].obtype))); + YYABORT; + } + } +#line 3919 "src/preproc/pic/pic.cpp" + break; + + case 170: /* nth_primitive: optional_ordinal_last object_type */ +#line 1328 "../src/preproc/pic/pic.ypp" + { + int count = 0; + object *p; + for (p = olist.tail; p != 0; p = p->prev) + if (p->type() == (yyvsp[0].obtype) && ++count == (yyvsp[-1].n)) { + (yyval.obj) = p; + break; + } + if (p == 0) { + lex_error("there is no %1%2 last %3", (yyvsp[-1].n), + ordinal_postfix((yyvsp[-1].n)), object_type_name((yyvsp[0].obtype))); + YYABORT; + } + } +#line 3938 "src/preproc/pic/pic.cpp" + break; + + case 171: /* object_type: BOX */ +#line 1346 "../src/preproc/pic/pic.ypp" + { (yyval.obtype) = BOX_OBJECT; } +#line 3944 "src/preproc/pic/pic.cpp" + break; + + case 172: /* object_type: CIRCLE */ +#line 1348 "../src/preproc/pic/pic.ypp" + { (yyval.obtype) = CIRCLE_OBJECT; } +#line 3950 "src/preproc/pic/pic.cpp" + break; + + case 173: /* object_type: ELLIPSE */ +#line 1350 "../src/preproc/pic/pic.ypp" + { (yyval.obtype) = ELLIPSE_OBJECT; } +#line 3956 "src/preproc/pic/pic.cpp" + break; + + case 174: /* object_type: ARC */ +#line 1352 "../src/preproc/pic/pic.ypp" + { (yyval.obtype) = ARC_OBJECT; } +#line 3962 "src/preproc/pic/pic.cpp" + break; + + case 175: /* object_type: LINE */ +#line 1354 "../src/preproc/pic/pic.ypp" + { (yyval.obtype) = LINE_OBJECT; } +#line 3968 "src/preproc/pic/pic.cpp" + break; + + case 176: /* object_type: ARROW */ +#line 1356 "../src/preproc/pic/pic.ypp" + { (yyval.obtype) = ARROW_OBJECT; } +#line 3974 "src/preproc/pic/pic.cpp" + break; + + case 177: /* object_type: SPLINE */ +#line 1358 "../src/preproc/pic/pic.ypp" + { (yyval.obtype) = SPLINE_OBJECT; } +#line 3980 "src/preproc/pic/pic.cpp" + break; + + case 178: /* object_type: '[' ']' */ +#line 1360 "../src/preproc/pic/pic.ypp" + { (yyval.obtype) = BLOCK_OBJECT; } +#line 3986 "src/preproc/pic/pic.cpp" + break; + + case 179: /* object_type: TEXT */ +#line 1362 "../src/preproc/pic/pic.ypp" + { (yyval.obtype) = TEXT_OBJECT; } +#line 3992 "src/preproc/pic/pic.cpp" + break; + + case 180: /* label_path: '.' LABEL */ +#line 1367 "../src/preproc/pic/pic.ypp" + { (yyval.pth) = new path((yyvsp[0].str)); } +#line 3998 "src/preproc/pic/pic.cpp" + break; + + case 181: /* label_path: label_path '.' LABEL */ +#line 1369 "../src/preproc/pic/pic.ypp" + { + (yyval.pth) = (yyvsp[-2].pth); + (yyval.pth)->append((yyvsp[0].str)); + } +#line 4007 "src/preproc/pic/pic.cpp" + break; + + case 182: /* relative_path: corner */ +#line 1377 "../src/preproc/pic/pic.ypp" + { (yyval.pth) = new path((yyvsp[0].crn)); } +#line 4013 "src/preproc/pic/pic.cpp" + break; + + case 183: /* relative_path: label_path */ +#line 1381 "../src/preproc/pic/pic.ypp" + { (yyval.pth) = (yyvsp[0].pth); } +#line 4019 "src/preproc/pic/pic.cpp" + break; + + case 184: /* relative_path: label_path corner */ +#line 1383 "../src/preproc/pic/pic.ypp" + { + (yyval.pth) = (yyvsp[-1].pth); + (yyval.pth)->append((yyvsp[0].crn)); + } +#line 4028 "src/preproc/pic/pic.cpp" + break; + + case 185: /* path: relative_path */ +#line 1391 "../src/preproc/pic/pic.ypp" + { (yyval.pth) = (yyvsp[0].pth); } +#line 4034 "src/preproc/pic/pic.cpp" + break; + + case 186: /* path: '(' relative_path ',' relative_path ')' */ +#line 1393 "../src/preproc/pic/pic.ypp" + { + (yyval.pth) = (yyvsp[-3].pth); + (yyval.pth)->set_ypath((yyvsp[-1].pth)); + } +#line 4043 "src/preproc/pic/pic.cpp" + break; + + case 187: /* path: ORDINAL LAST object_type relative_path */ +#line 1399 "../src/preproc/pic/pic.ypp" + { + lex_warning("'%1%2 last %3' in 'with' argument ignored", + (yyvsp[-3].n), ordinal_postfix((yyvsp[-3].n)), object_type_name((yyvsp[-1].obtype))); + (yyval.pth) = (yyvsp[0].pth); + } +#line 4053 "src/preproc/pic/pic.cpp" + break; + + case 188: /* path: LAST object_type relative_path */ +#line 1405 "../src/preproc/pic/pic.ypp" + { + lex_warning("'last %1' in 'with' argument ignored", + object_type_name((yyvsp[-1].obtype))); + (yyval.pth) = (yyvsp[0].pth); + } +#line 4063 "src/preproc/pic/pic.cpp" + break; + + case 189: /* path: ORDINAL object_type relative_path */ +#line 1411 "../src/preproc/pic/pic.ypp" + { + lex_warning("'%1%2 %3' in 'with' argument ignored", + (yyvsp[-2].n), ordinal_postfix((yyvsp[-2].n)), object_type_name((yyvsp[-1].obtype))); + (yyval.pth) = (yyvsp[0].pth); + } +#line 4073 "src/preproc/pic/pic.cpp" + break; + + case 190: /* path: LABEL relative_path */ +#line 1417 "../src/preproc/pic/pic.ypp" + { + lex_warning("initial '%1' in 'with' argument ignored", (yyvsp[-1].str)); + delete[] (yyvsp[-1].str); + (yyval.pth) = (yyvsp[0].pth); + } +#line 4083 "src/preproc/pic/pic.cpp" + break; + + case 191: /* corner: DOT_N */ +#line 1426 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::north; } +#line 4089 "src/preproc/pic/pic.cpp" + break; + + case 192: /* corner: DOT_E */ +#line 1428 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::east; } +#line 4095 "src/preproc/pic/pic.cpp" + break; + + case 193: /* corner: DOT_W */ +#line 1430 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::west; } +#line 4101 "src/preproc/pic/pic.cpp" + break; + + case 194: /* corner: DOT_S */ +#line 1432 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::south; } +#line 4107 "src/preproc/pic/pic.cpp" + break; + + case 195: /* corner: DOT_NE */ +#line 1434 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::north_east; } +#line 4113 "src/preproc/pic/pic.cpp" + break; + + case 196: /* corner: DOT_SE */ +#line 1436 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object:: south_east; } +#line 4119 "src/preproc/pic/pic.cpp" + break; + + case 197: /* corner: DOT_NW */ +#line 1438 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::north_west; } +#line 4125 "src/preproc/pic/pic.cpp" + break; + + case 198: /* corner: DOT_SW */ +#line 1440 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::south_west; } +#line 4131 "src/preproc/pic/pic.cpp" + break; + + case 199: /* corner: DOT_C */ +#line 1442 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::center; } +#line 4137 "src/preproc/pic/pic.cpp" + break; + + case 200: /* corner: DOT_START */ +#line 1444 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::start; } +#line 4143 "src/preproc/pic/pic.cpp" + break; + + case 201: /* corner: DOT_END */ +#line 1446 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::end; } +#line 4149 "src/preproc/pic/pic.cpp" + break; + + case 202: /* corner: TOP */ +#line 1448 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::north; } +#line 4155 "src/preproc/pic/pic.cpp" + break; + + case 203: /* corner: BOTTOM */ +#line 1450 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::south; } +#line 4161 "src/preproc/pic/pic.cpp" + break; + + case 204: /* corner: LEFT */ +#line 1452 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::west; } +#line 4167 "src/preproc/pic/pic.cpp" + break; + + case 205: /* corner: RIGHT */ +#line 1454 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::east; } +#line 4173 "src/preproc/pic/pic.cpp" + break; + + case 206: /* corner: UPPER LEFT */ +#line 1456 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::north_west; } +#line 4179 "src/preproc/pic/pic.cpp" + break; + + case 207: /* corner: LOWER LEFT */ +#line 1458 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::south_west; } +#line 4185 "src/preproc/pic/pic.cpp" + break; + + case 208: /* corner: UPPER RIGHT */ +#line 1460 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::north_east; } +#line 4191 "src/preproc/pic/pic.cpp" + break; + + case 209: /* corner: LOWER RIGHT */ +#line 1462 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::south_east; } +#line 4197 "src/preproc/pic/pic.cpp" + break; + + case 210: /* corner: LEFT_CORNER */ +#line 1464 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::west; } +#line 4203 "src/preproc/pic/pic.cpp" + break; + + case 211: /* corner: RIGHT_CORNER */ +#line 1466 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::east; } +#line 4209 "src/preproc/pic/pic.cpp" + break; + + case 212: /* corner: UPPER LEFT_CORNER */ +#line 1468 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::north_west; } +#line 4215 "src/preproc/pic/pic.cpp" + break; + + case 213: /* corner: LOWER LEFT_CORNER */ +#line 1470 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::south_west; } +#line 4221 "src/preproc/pic/pic.cpp" + break; + + case 214: /* corner: UPPER RIGHT_CORNER */ +#line 1472 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::north_east; } +#line 4227 "src/preproc/pic/pic.cpp" + break; + + case 215: /* corner: LOWER RIGHT_CORNER */ +#line 1474 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::south_east; } +#line 4233 "src/preproc/pic/pic.cpp" + break; + + case 216: /* corner: NORTH */ +#line 1476 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::north; } +#line 4239 "src/preproc/pic/pic.cpp" + break; + + case 217: /* corner: SOUTH */ +#line 1478 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::south; } +#line 4245 "src/preproc/pic/pic.cpp" + break; + + case 218: /* corner: EAST */ +#line 1480 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::east; } +#line 4251 "src/preproc/pic/pic.cpp" + break; + + case 219: /* corner: WEST */ +#line 1482 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::west; } +#line 4257 "src/preproc/pic/pic.cpp" + break; + + case 220: /* corner: CENTER */ +#line 1484 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::center; } +#line 4263 "src/preproc/pic/pic.cpp" + break; + + case 221: /* corner: START */ +#line 1486 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::start; } +#line 4269 "src/preproc/pic/pic.cpp" + break; + + case 222: /* corner: END */ +#line 1488 "../src/preproc/pic/pic.ypp" + { (yyval.crn) = &object::end; } +#line 4275 "src/preproc/pic/pic.cpp" + break; + + case 223: /* expr: expr_lower_than */ +#line 1493 "../src/preproc/pic/pic.ypp" + { (yyval.x) = (yyvsp[0].x); } +#line 4281 "src/preproc/pic/pic.cpp" + break; + + case 224: /* expr: expr_not_lower_than */ +#line 1495 "../src/preproc/pic/pic.ypp" + { (yyval.x) = (yyvsp[0].x); } +#line 4287 "src/preproc/pic/pic.cpp" + break; + + case 225: /* expr_lower_than: expr '<' expr */ +#line 1500 "../src/preproc/pic/pic.ypp" + { (yyval.x) = ((yyvsp[-2].x) < (yyvsp[0].x)); } +#line 4293 "src/preproc/pic/pic.cpp" + break; + + case 226: /* expr_not_lower_than: VARIABLE */ +#line 1505 "../src/preproc/pic/pic.ypp" + { + if (!lookup_variable((yyvsp[0].str), & (yyval.x))) { + lex_error("there is no variable '%1'", (yyvsp[0].str)); + YYABORT; + } + free((yyvsp[0].str)); + } +#line 4305 "src/preproc/pic/pic.cpp" + break; + + case 227: /* expr_not_lower_than: NUMBER */ +#line 1513 "../src/preproc/pic/pic.ypp" + { (yyval.x) = (yyvsp[0].x); } +#line 4311 "src/preproc/pic/pic.cpp" + break; + + case 228: /* expr_not_lower_than: place DOT_X */ +#line 1515 "../src/preproc/pic/pic.ypp" + { + if ((yyvsp[-1].pl).obj != 0) + (yyval.x) = (yyvsp[-1].pl).obj->origin().x; + else + (yyval.x) = (yyvsp[-1].pl).x; + } +#line 4322 "src/preproc/pic/pic.cpp" + break; + + case 229: /* expr_not_lower_than: place DOT_Y */ +#line 1522 "../src/preproc/pic/pic.ypp" + { + if ((yyvsp[-1].pl).obj != 0) + (yyval.x) = (yyvsp[-1].pl).obj->origin().y; + else + (yyval.x) = (yyvsp[-1].pl).y; + } +#line 4333 "src/preproc/pic/pic.cpp" + break; + + case 230: /* expr_not_lower_than: place DOT_HT */ +#line 1529 "../src/preproc/pic/pic.ypp" + { + if ((yyvsp[-1].pl).obj != 0) + (yyval.x) = (yyvsp[-1].pl).obj->height(); + else + (yyval.x) = 0.0; + } +#line 4344 "src/preproc/pic/pic.cpp" + break; + + case 231: /* expr_not_lower_than: place DOT_WID */ +#line 1536 "../src/preproc/pic/pic.ypp" + { + if ((yyvsp[-1].pl).obj != 0) + (yyval.x) = (yyvsp[-1].pl).obj->width(); + else + (yyval.x) = 0.0; + } +#line 4355 "src/preproc/pic/pic.cpp" + break; + + case 232: /* expr_not_lower_than: place DOT_RAD */ +#line 1543 "../src/preproc/pic/pic.ypp" + { + if ((yyvsp[-1].pl).obj != 0) + (yyval.x) = (yyvsp[-1].pl).obj->radius(); + else + (yyval.x) = 0.0; + } +#line 4366 "src/preproc/pic/pic.cpp" + break; + + case 233: /* expr_not_lower_than: expr '+' expr */ +#line 1550 "../src/preproc/pic/pic.ypp" + { (yyval.x) = (yyvsp[-2].x) + (yyvsp[0].x); } +#line 4372 "src/preproc/pic/pic.cpp" + break; + + case 234: /* expr_not_lower_than: expr '-' expr */ +#line 1552 "../src/preproc/pic/pic.ypp" + { (yyval.x) = (yyvsp[-2].x) - (yyvsp[0].x); } +#line 4378 "src/preproc/pic/pic.cpp" + break; + + case 235: /* expr_not_lower_than: expr '*' expr */ +#line 1554 "../src/preproc/pic/pic.ypp" + { (yyval.x) = (yyvsp[-2].x) * (yyvsp[0].x); } +#line 4384 "src/preproc/pic/pic.cpp" + break; + + case 236: /* expr_not_lower_than: expr '/' expr */ +#line 1556 "../src/preproc/pic/pic.ypp" + { + if ((yyvsp[0].x) == 0.0) { + lex_error("division by zero"); + YYABORT; + } + (yyval.x) = (yyvsp[-2].x)/(yyvsp[0].x); + } +#line 4396 "src/preproc/pic/pic.cpp" + break; + + case 237: /* expr_not_lower_than: expr '%' expr */ +#line 1564 "../src/preproc/pic/pic.ypp" + { + if ((yyvsp[0].x) == 0.0) { + lex_error("modulus by zero"); + YYABORT; + } + (yyval.x) = fmod((yyvsp[-2].x), (yyvsp[0].x)); + } +#line 4408 "src/preproc/pic/pic.cpp" + break; + + case 238: /* expr_not_lower_than: expr '^' expr */ +#line 1572 "../src/preproc/pic/pic.ypp" + { + errno = 0; + (yyval.x) = pow((yyvsp[-2].x), (yyvsp[0].x)); + if (errno == EDOM) { + lex_error("arguments to '^' operator out of domain"); + YYABORT; + } + if (errno == ERANGE) { + lex_error("result of '^' operator out of range"); + YYABORT; + } + } +#line 4425 "src/preproc/pic/pic.cpp" + break; + + case 239: /* expr_not_lower_than: '-' expr */ +#line 1585 "../src/preproc/pic/pic.ypp" + { (yyval.x) = -(yyvsp[0].x); } +#line 4431 "src/preproc/pic/pic.cpp" + break; + + case 240: /* expr_not_lower_than: '(' any_expr ')' */ +#line 1587 "../src/preproc/pic/pic.ypp" + { (yyval.x) = (yyvsp[-1].x); } +#line 4437 "src/preproc/pic/pic.cpp" + break; + + case 241: /* expr_not_lower_than: SIN '(' any_expr ')' */ +#line 1589 "../src/preproc/pic/pic.ypp" + { + errno = 0; + (yyval.x) = sin((yyvsp[-1].x)); + if (errno == ERANGE) { + lex_error("sin result out of range"); + YYABORT; + } + } +#line 4450 "src/preproc/pic/pic.cpp" + break; + + case 242: /* expr_not_lower_than: COS '(' any_expr ')' */ +#line 1598 "../src/preproc/pic/pic.ypp" + { + errno = 0; + (yyval.x) = cos((yyvsp[-1].x)); + if (errno == ERANGE) { + lex_error("cos result out of range"); + YYABORT; + } + } +#line 4463 "src/preproc/pic/pic.cpp" + break; + + case 243: /* expr_not_lower_than: ATAN2 '(' any_expr ',' any_expr ')' */ +#line 1607 "../src/preproc/pic/pic.ypp" + { + errno = 0; + (yyval.x) = atan2((yyvsp[-3].x), (yyvsp[-1].x)); + if (errno == EDOM) { + lex_error("atan2 argument out of domain"); + YYABORT; + } + if (errno == ERANGE) { + lex_error("atan2 result out of range"); + YYABORT; + } + } +#line 4480 "src/preproc/pic/pic.cpp" + break; + + case 244: /* expr_not_lower_than: LOG '(' any_expr ')' */ +#line 1620 "../src/preproc/pic/pic.ypp" + { + errno = 0; + (yyval.x) = log10((yyvsp[-1].x)); + if (errno == ERANGE) { + lex_error("log result out of range"); + YYABORT; + } + } +#line 4493 "src/preproc/pic/pic.cpp" + break; + + case 245: /* expr_not_lower_than: EXP '(' any_expr ')' */ +#line 1629 "../src/preproc/pic/pic.ypp" + { + errno = 0; + (yyval.x) = pow(10.0, (yyvsp[-1].x)); + if (errno == ERANGE) { + lex_error("exp result out of range"); + YYABORT; + } + } +#line 4506 "src/preproc/pic/pic.cpp" + break; + + case 246: /* expr_not_lower_than: SQRT '(' any_expr ')' */ +#line 1638 "../src/preproc/pic/pic.ypp" + { + errno = 0; + (yyval.x) = sqrt((yyvsp[-1].x)); + if (errno == EDOM) { + lex_error("sqrt argument out of domain"); + YYABORT; + } + } +#line 4519 "src/preproc/pic/pic.cpp" + break; + + case 247: /* expr_not_lower_than: K_MAX '(' any_expr ',' any_expr ')' */ +#line 1647 "../src/preproc/pic/pic.ypp" + { (yyval.x) = (yyvsp[-3].x) > (yyvsp[-1].x) ? (yyvsp[-3].x) : (yyvsp[-1].x); } +#line 4525 "src/preproc/pic/pic.cpp" + break; + + case 248: /* expr_not_lower_than: K_MIN '(' any_expr ',' any_expr ')' */ +#line 1649 "../src/preproc/pic/pic.ypp" + { (yyval.x) = (yyvsp[-3].x) < (yyvsp[-1].x) ? (yyvsp[-3].x) : (yyvsp[-1].x); } +#line 4531 "src/preproc/pic/pic.cpp" + break; + + case 249: /* expr_not_lower_than: INT '(' any_expr ')' */ +#line 1651 "../src/preproc/pic/pic.ypp" + { (yyval.x) = (yyvsp[-1].x) < 0 ? -floor(-(yyvsp[-1].x)) : floor((yyvsp[-1].x)); } +#line 4537 "src/preproc/pic/pic.cpp" + break; + + case 250: /* expr_not_lower_than: RAND '(' any_expr ')' */ +#line 1653 "../src/preproc/pic/pic.ypp" + { + lex_error("use of 'rand' with an argument is" + " deprecated; shift and scale 'rand()' with" + " arithmetic instead"); + (yyval.x) = 1.0 + floor(((rand()&0x7fff)/double(0x7fff))*(yyvsp[-1].x)); + } +#line 4548 "src/preproc/pic/pic.cpp" + break; + + case 251: /* expr_not_lower_than: RAND '(' ')' */ +#line 1660 "../src/preproc/pic/pic.ypp" + { + /* return a random number in the range [0,1) */ + /* portable, but not very random */ + (yyval.x) = (rand() & 0x7fff) / double(0x8000); + } +#line 4558 "src/preproc/pic/pic.cpp" + break; + + case 252: /* expr_not_lower_than: SRAND '(' any_expr ')' */ +#line 1666 "../src/preproc/pic/pic.ypp" + { + (yyval.x) = 0; + srand((unsigned int)(yyvsp[-1].x)); + } +#line 4567 "src/preproc/pic/pic.cpp" + break; + + case 253: /* expr_not_lower_than: expr LESSEQUAL expr */ +#line 1671 "../src/preproc/pic/pic.ypp" + { (yyval.x) = ((yyvsp[-2].x) <= (yyvsp[0].x)); } +#line 4573 "src/preproc/pic/pic.cpp" + break; + + case 254: /* expr_not_lower_than: expr '>' expr */ +#line 1673 "../src/preproc/pic/pic.ypp" + { (yyval.x) = ((yyvsp[-2].x) > (yyvsp[0].x)); } +#line 4579 "src/preproc/pic/pic.cpp" + break; + + case 255: /* expr_not_lower_than: expr GREATEREQUAL expr */ +#line 1675 "../src/preproc/pic/pic.ypp" + { (yyval.x) = ((yyvsp[-2].x) >= (yyvsp[0].x)); } +#line 4585 "src/preproc/pic/pic.cpp" + break; + + case 256: /* expr_not_lower_than: expr EQUALEQUAL expr */ +#line 1677 "../src/preproc/pic/pic.ypp" + { (yyval.x) = ((yyvsp[-2].x) == (yyvsp[0].x)); } +#line 4591 "src/preproc/pic/pic.cpp" + break; + + case 257: /* expr_not_lower_than: expr NOTEQUAL expr */ +#line 1679 "../src/preproc/pic/pic.ypp" + { (yyval.x) = ((yyvsp[-2].x) != (yyvsp[0].x)); } +#line 4597 "src/preproc/pic/pic.cpp" + break; + + case 258: /* expr_not_lower_than: expr ANDAND expr */ +#line 1681 "../src/preproc/pic/pic.ypp" + { (yyval.x) = ((yyvsp[-2].x) != 0.0 && (yyvsp[0].x) != 0.0); } +#line 4603 "src/preproc/pic/pic.cpp" + break; + + case 259: /* expr_not_lower_than: expr OROR expr */ +#line 1683 "../src/preproc/pic/pic.ypp" + { (yyval.x) = ((yyvsp[-2].x) != 0.0 || (yyvsp[0].x) != 0.0); } +#line 4609 "src/preproc/pic/pic.cpp" + break; + + case 260: /* expr_not_lower_than: '!' expr */ +#line 1685 "../src/preproc/pic/pic.ypp" + { (yyval.x) = ((yyvsp[0].x) == 0.0); } +#line 4615 "src/preproc/pic/pic.cpp" + break; + + +#line 4619 "src/preproc/pic/pic.cpp" + + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + + *++yyvsp = yyval; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; + yyerror (YY_("syntax error")); + } + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; + ++yynerrs; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + /* Pop stack until we find a state that shifts the error token. */ + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYSYMBOL_YYerror; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + YY_ACCESSING_SYMBOL (yystate), yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturnlab; + + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturnlab; + + +/*-----------------------------------------------------------. +| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | +`-----------------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + goto yyreturnlab; + + +/*----------------------------------------------------------. +| yyreturnlab -- parsing is finished, clean up and return. | +`----------------------------------------------------------*/ +yyreturnlab: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + YY_ACCESSING_SYMBOL (+*yyssp), yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + + return yyresult; +} + +#line 1689 "../src/preproc/pic/pic.ypp" + + +/* bison defines const to be empty unless __STDC__ is defined, which it +isn't under cfront */ + +#ifdef const +#undef const +#endif + +static struct { + const char *name; + double val; + int scaled; // non-zero if val should be multiplied by scale +} defaults_table[] = { + { "arcrad", .25, 1 }, + { "arrowht", .1, 1 }, + { "arrowwid", .05, 1 }, + { "circlerad", .25, 1 }, + { "boxht", .5, 1 }, + { "boxwid", .75, 1 }, + { "boxrad", 0.0, 1 }, + { "dashwid", .05, 1 }, + { "ellipseht", .5, 1 }, + { "ellipsewid", .75, 1 }, + { "moveht", .5, 1 }, + { "movewid", .5, 1 }, + { "lineht", .5, 1 }, + { "linewid", .5, 1 }, + { "textht", 0.0, 1 }, + { "textwid", 0.0, 1 }, + { "scale", 1.0, 0 }, + { "linethick", -1.0, 0 }, // in points + { "fillval", .5, 0 }, + { "arrowhead", 1.0, 0 }, + { "maxpswid", 8.5, 0 }, + { "maxpsht", 11.0, 0 }, +}; + +place *lookup_label(const char *label) +{ + saved_state *state = current_saved_state; + PTABLE(place) *tbl = current_table; + for (;;) { + place *pl = tbl->lookup(label); + if (pl) + return pl; + if (!state) + return 0; + tbl = state->tbl; + state = state->prev; + } +} + +void define_label(const char *label, const place *pl) +{ + place *p = new place[1]; + *p = *pl; + current_table->define(label, p); +} + +int lookup_variable(const char *name, double *val) +{ + place *pl = lookup_label(name); + if (pl) { + *val = pl->x; + return 1; + } + return 0; +} + +void define_variable(const char *name, double val) +{ + place *p = new place[1]; + p->obj = 0; + p->x = val; + p->y = 0.0; + current_table->define(name, p); + if (strcmp(name, "scale") == 0) { + // When the scale changes, reset all scaled predefined variables to + // their default values. + for (unsigned int i = 0; + i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++) + if (defaults_table[i].scaled) + define_variable(defaults_table[i].name, val*defaults_table[i].val); + } +} + +// called once only (not once per parse) + +void parse_init() +{ + current_direction = RIGHT_DIRECTION; + current_position.x = 0.0; + current_position.y = 0.0; + // This resets everything to its default value. + reset_all(); +} + +void reset(const char *nm) +{ + for (unsigned int i = 0; + i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++) + if (strcmp(nm, defaults_table[i].name) == 0) { + double val = defaults_table[i].val; + if (defaults_table[i].scaled) { + double scale; + lookup_variable("scale", &scale); + val *= scale; + } + define_variable(defaults_table[i].name, val); + return; + } + lex_error("'%1' is not a predefined variable", nm); +} + +void reset_all() +{ + // We only have to explicitly reset the predefined variables that + // aren't scaled because 'scale' is not scaled, and changing the + // value of 'scale' will reset all the predefined variables that + // are scaled. + for (unsigned int i = 0; + i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++) + if (!defaults_table[i].scaled) + define_variable(defaults_table[i].name, defaults_table[i].val); +} + +// called after each parse + +void parse_cleanup() +{ + while (current_saved_state != 0) { + delete current_table; + current_table = current_saved_state->tbl; + saved_state *tem = current_saved_state; + current_saved_state = current_saved_state->prev; + delete tem; + } + assert(current_table == &top_table); + PTABLE_ITERATOR(place) iter(current_table); + const char *key; + place *pl; + while (iter.next(&key, &pl)) + if (pl->obj != 0) { + position pos = pl->obj->origin(); + pl->obj = 0; + pl->x = pos.x; + pl->y = pos.y; + } + while (olist.head != 0) { + object *tem = olist.head; + olist.head = olist.head->next; + delete tem; + } + olist.tail = 0; + current_direction = RIGHT_DIRECTION; + current_position.x = 0.0; + current_position.y = 0.0; +} + +const char *ordinal_postfix(int n) +{ + if (n < 10 || n > 20) + switch (n % 10) { + case 1: + return "st"; + case 2: + return "nd"; + case 3: + return "rd"; + } + return "th"; +} + +const char *object_type_name(object_type type) +{ + switch (type) { + case BOX_OBJECT: + return "box"; + case CIRCLE_OBJECT: + return "circle"; + case ELLIPSE_OBJECT: + return "ellipse"; + case ARC_OBJECT: + return "arc"; + case SPLINE_OBJECT: + return "spline"; + case LINE_OBJECT: + return "line"; + case ARROW_OBJECT: + return "arrow"; + case MOVE_OBJECT: + return "move"; + case TEXT_OBJECT: + return "\"\""; + case BLOCK_OBJECT: + return "[]"; + case OTHER_OBJECT: + case MARK_OBJECT: + default: + break; + } + return "object"; +} + +static char sprintf_buf[1024]; + +char *format_number(const char *fmt, double n) +{ + if (0 /* nullptr */ == fmt) + fmt = "%g"; + return do_sprintf(fmt, &n, 1); +} + +char *do_sprintf(const char *fmt, const double *v, int nv) +{ + // Define valid conversion specifiers and modifiers. + static const char spcs[] = "eEfgG%"; + static const char mods[] = "#-+ 0123456789."; + string result; + int i = 0; + string one_format; + while (*fmt) { + if ('%' == *fmt) { + one_format += *fmt++; + for (; *fmt != '\0' && strchr(mods, *fmt) != 0; fmt++) + one_format += *fmt; + if ('\0' == *fmt || strchr(spcs, *fmt) == 0) { + lex_error("invalid sprintf conversion specifier '%1'", *fmt); + result += one_format; + result += fmt; + break; + } + if ('%' == *fmt) { + fmt++; + snprintf(sprintf_buf, sizeof(sprintf_buf), "%%"); + } + else { + if (i >= nv) { + lex_error("too few arguments to sprintf"); + result += one_format; + result += fmt; + break; + } + one_format += *fmt++; + one_format += '\0'; +// We validated the format string above. Most conversion specifiers are +// rejected, including `n`. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" + snprintf(sprintf_buf, sizeof(sprintf_buf), + one_format.contents(), v[i++]); +#pragma GCC diagnostic pop + } + one_format.clear(); + result += sprintf_buf; + } + else + result += *fmt++; + } + result += '\0'; + return strsave(result.contents()); +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/pic/pic.h b/src/preproc/pic/pic.h new file mode 100644 index 0000000..1a99498 --- /dev/null +++ b/src/preproc/pic/pic.h @@ -0,0 +1,122 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "lib.h" + +#include +#include +#include +#include + +#ifdef NEED_DECLARATION_RAND +#undef rand +extern "C" { + int rand(); +} +#endif /* NEED_DECLARATION_RAND */ + +#ifdef NEED_DECLARATION_SRAND +#undef srand +extern "C" { +#ifdef RET_TYPE_SRAND_IS_VOID + void srand(unsigned int); +#else + int srand(unsigned int); +#endif +} +#endif /* NEED_DECLARATION_SRAND */ + +#ifndef HAVE_FMOD +extern "C" { + double fmod(double, double); +} +#endif + +#include "cset.h" +#include "stringclass.h" +#include "lf.h" +#include "errarg.h" +#include "error.h" +#include "position.h" +#include "text.h" +#include "output.h" + +#ifndef M_SQRT2 +#define M_SQRT2 1.41421356237309504880 +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +class input { + input *next; +public: + input(); + virtual ~input(); + virtual int get() = 0; + virtual int peek() = 0; + virtual int get_location(const char **, int *); + friend class input_stack; + friend class copy_rest_thru_input; +}; + +class file_input : public input { + FILE *fp; + const char *filename; + int lineno; + string line; + const char *ptr; + int read_line(); +public: + file_input(FILE *, const char *); + ~file_input(); + int get(); + int peek(); + int get_location(const char **, int *); +}; + +void lex_init(input *); +int get_location(char **, int *); + +void do_copy(const char *file); +void parse_init(); +void parse_cleanup(); + +void lex_error(const char *message, + const errarg &arg1 = empty_errarg, + const errarg &arg2 = empty_errarg, + const errarg &arg3 = empty_errarg); + +void lex_warning(const char *message, + const errarg &arg1 = empty_errarg, + const errarg &arg2 = empty_errarg, + const errarg &arg3 = empty_errarg); + +void lex_cleanup(); + +extern bool want_flyback; +extern bool want_alternate_flyback; +extern int command_char; +// zero_length_line_flag is non-zero if zero-length lines are drawn +// as dots by the output device +extern int zero_length_line_flag; +extern int driver_extension_flag; +extern int compatible_flag; +extern int safer_flag; +extern char *graphname; diff --git a/src/preproc/pic/pic.hpp b/src/preproc/pic/pic.hpp new file mode 100644 index 0000000..c162496 --- /dev/null +++ b/src/preproc/pic/pic.hpp @@ -0,0 +1,348 @@ +/* A Bison parser, made by GNU Bison 3.8.2. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + +#ifndef YY_YY_SRC_PREPROC_PIC_PIC_HPP_INCLUDED +# define YY_YY_SRC_PREPROC_PIC_PIC_HPP_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Token kinds. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + YYEMPTY = -2, + YYEOF = 0, /* "end of file" */ + YYerror = 256, /* error */ + YYUNDEF = 257, /* "invalid token" */ + LABEL = 258, /* LABEL */ + VARIABLE = 259, /* VARIABLE */ + NUMBER = 260, /* NUMBER */ + TEXT = 261, /* TEXT */ + COMMAND_LINE = 262, /* COMMAND_LINE */ + DELIMITED = 263, /* DELIMITED */ + ORDINAL = 264, /* ORDINAL */ + TH = 265, /* TH */ + LEFT_ARROW_HEAD = 266, /* LEFT_ARROW_HEAD */ + RIGHT_ARROW_HEAD = 267, /* RIGHT_ARROW_HEAD */ + DOUBLE_ARROW_HEAD = 268, /* DOUBLE_ARROW_HEAD */ + LAST = 269, /* LAST */ + BOX = 270, /* BOX */ + CIRCLE = 271, /* CIRCLE */ + ELLIPSE = 272, /* ELLIPSE */ + ARC = 273, /* ARC */ + LINE = 274, /* LINE */ + ARROW = 275, /* ARROW */ + MOVE = 276, /* MOVE */ + SPLINE = 277, /* SPLINE */ + HEIGHT = 278, /* HEIGHT */ + RADIUS = 279, /* RADIUS */ + FIGNAME = 280, /* FIGNAME */ + WIDTH = 281, /* WIDTH */ + DIAMETER = 282, /* DIAMETER */ + UP = 283, /* UP */ + DOWN = 284, /* DOWN */ + RIGHT = 285, /* RIGHT */ + LEFT = 286, /* LEFT */ + FROM = 287, /* FROM */ + TO = 288, /* TO */ + AT = 289, /* AT */ + WITH = 290, /* WITH */ + BY = 291, /* BY */ + THEN = 292, /* THEN */ + SOLID = 293, /* SOLID */ + DOTTED = 294, /* DOTTED */ + DASHED = 295, /* DASHED */ + CHOP = 296, /* CHOP */ + SAME = 297, /* SAME */ + INVISIBLE = 298, /* INVISIBLE */ + LJUST = 299, /* LJUST */ + RJUST = 300, /* RJUST */ + ABOVE = 301, /* ABOVE */ + BELOW = 302, /* BELOW */ + OF = 303, /* OF */ + THE = 304, /* THE */ + WAY = 305, /* WAY */ + BETWEEN = 306, /* BETWEEN */ + AND = 307, /* AND */ + HERE = 308, /* HERE */ + DOT_N = 309, /* DOT_N */ + DOT_E = 310, /* DOT_E */ + DOT_W = 311, /* DOT_W */ + DOT_S = 312, /* DOT_S */ + DOT_NE = 313, /* DOT_NE */ + DOT_SE = 314, /* DOT_SE */ + DOT_NW = 315, /* DOT_NW */ + DOT_SW = 316, /* DOT_SW */ + DOT_C = 317, /* DOT_C */ + DOT_START = 318, /* DOT_START */ + DOT_END = 319, /* DOT_END */ + DOT_X = 320, /* DOT_X */ + DOT_Y = 321, /* DOT_Y */ + DOT_HT = 322, /* DOT_HT */ + DOT_WID = 323, /* DOT_WID */ + DOT_RAD = 324, /* DOT_RAD */ + SIN = 325, /* SIN */ + COS = 326, /* COS */ + ATAN2 = 327, /* ATAN2 */ + LOG = 328, /* LOG */ + EXP = 329, /* EXP */ + SQRT = 330, /* SQRT */ + K_MAX = 331, /* K_MAX */ + K_MIN = 332, /* K_MIN */ + INT = 333, /* INT */ + RAND = 334, /* RAND */ + SRAND = 335, /* SRAND */ + COPY = 336, /* COPY */ + THRU = 337, /* THRU */ + TOP = 338, /* TOP */ + BOTTOM = 339, /* BOTTOM */ + UPPER = 340, /* UPPER */ + LOWER = 341, /* LOWER */ + SH = 342, /* SH */ + PRINT = 343, /* PRINT */ + CW = 344, /* CW */ + CCW = 345, /* CCW */ + FOR = 346, /* FOR */ + DO = 347, /* DO */ + IF = 348, /* IF */ + ELSE = 349, /* ELSE */ + ANDAND = 350, /* ANDAND */ + OROR = 351, /* OROR */ + NOTEQUAL = 352, /* NOTEQUAL */ + EQUALEQUAL = 353, /* EQUALEQUAL */ + LESSEQUAL = 354, /* LESSEQUAL */ + GREATEREQUAL = 355, /* GREATEREQUAL */ + LEFT_CORNER = 356, /* LEFT_CORNER */ + RIGHT_CORNER = 357, /* RIGHT_CORNER */ + NORTH = 358, /* NORTH */ + SOUTH = 359, /* SOUTH */ + EAST = 360, /* EAST */ + WEST = 361, /* WEST */ + CENTER = 362, /* CENTER */ + END = 363, /* END */ + START = 364, /* START */ + RESET = 365, /* RESET */ + UNTIL = 366, /* UNTIL */ + PLOT = 367, /* PLOT */ + THICKNESS = 368, /* THICKNESS */ + FILL = 369, /* FILL */ + COLORED = 370, /* COLORED */ + OUTLINED = 371, /* OUTLINED */ + SHADED = 372, /* SHADED */ + XSLANTED = 373, /* XSLANTED */ + YSLANTED = 374, /* YSLANTED */ + ALIGNED = 375, /* ALIGNED */ + SPRINTF = 376, /* SPRINTF */ + COMMAND = 377, /* COMMAND */ + DEFINE = 378, /* DEFINE */ + UNDEF = 379 /* UNDEF */ + }; + typedef enum yytokentype yytoken_kind_t; +#endif +/* Token kinds. */ +#define YYEMPTY -2 +#define YYEOF 0 +#define YYerror 256 +#define YYUNDEF 257 +#define LABEL 258 +#define VARIABLE 259 +#define NUMBER 260 +#define TEXT 261 +#define COMMAND_LINE 262 +#define DELIMITED 263 +#define ORDINAL 264 +#define TH 265 +#define LEFT_ARROW_HEAD 266 +#define RIGHT_ARROW_HEAD 267 +#define DOUBLE_ARROW_HEAD 268 +#define LAST 269 +#define BOX 270 +#define CIRCLE 271 +#define ELLIPSE 272 +#define ARC 273 +#define LINE 274 +#define ARROW 275 +#define MOVE 276 +#define SPLINE 277 +#define HEIGHT 278 +#define RADIUS 279 +#define FIGNAME 280 +#define WIDTH 281 +#define DIAMETER 282 +#define UP 283 +#define DOWN 284 +#define RIGHT 285 +#define LEFT 286 +#define FROM 287 +#define TO 288 +#define AT 289 +#define WITH 290 +#define BY 291 +#define THEN 292 +#define SOLID 293 +#define DOTTED 294 +#define DASHED 295 +#define CHOP 296 +#define SAME 297 +#define INVISIBLE 298 +#define LJUST 299 +#define RJUST 300 +#define ABOVE 301 +#define BELOW 302 +#define OF 303 +#define THE 304 +#define WAY 305 +#define BETWEEN 306 +#define AND 307 +#define HERE 308 +#define DOT_N 309 +#define DOT_E 310 +#define DOT_W 311 +#define DOT_S 312 +#define DOT_NE 313 +#define DOT_SE 314 +#define DOT_NW 315 +#define DOT_SW 316 +#define DOT_C 317 +#define DOT_START 318 +#define DOT_END 319 +#define DOT_X 320 +#define DOT_Y 321 +#define DOT_HT 322 +#define DOT_WID 323 +#define DOT_RAD 324 +#define SIN 325 +#define COS 326 +#define ATAN2 327 +#define LOG 328 +#define EXP 329 +#define SQRT 330 +#define K_MAX 331 +#define K_MIN 332 +#define INT 333 +#define RAND 334 +#define SRAND 335 +#define COPY 336 +#define THRU 337 +#define TOP 338 +#define BOTTOM 339 +#define UPPER 340 +#define LOWER 341 +#define SH 342 +#define PRINT 343 +#define CW 344 +#define CCW 345 +#define FOR 346 +#define DO 347 +#define IF 348 +#define ELSE 349 +#define ANDAND 350 +#define OROR 351 +#define NOTEQUAL 352 +#define EQUALEQUAL 353 +#define LESSEQUAL 354 +#define GREATEREQUAL 355 +#define LEFT_CORNER 356 +#define RIGHT_CORNER 357 +#define NORTH 358 +#define SOUTH 359 +#define EAST 360 +#define WEST 361 +#define CENTER 362 +#define END 363 +#define START 364 +#define RESET 365 +#define UNTIL 366 +#define PLOT 367 +#define THICKNESS 368 +#define FILL 369 +#define COLORED 370 +#define OUTLINED 371 +#define SHADED 372 +#define XSLANTED 373 +#define YSLANTED 374 +#define ALIGNED 375 +#define SPRINTF 376 +#define COMMAND 377 +#define DEFINE 378 +#define UNDEF 379 + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +union YYSTYPE +{ +#line 65 "../src/preproc/pic/pic.ypp" + + char *str; + int n; + double x; + struct { double x, y; } pair; + struct { double x; char *body; } if_data; + struct { char *str; const char *filename; int lineno; } lstr; + struct { double *v; int nv; int maxv; } dv; + struct { double val; int is_multiplicative; } by; + place pl; + object *obj; + corner crn; + path *pth; + object_spec *spec; + saved_state *pstate; + graphics_state state; + object_type obtype; + +#line 334 "src/preproc/pic/pic.hpp" + +}; +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE yylval; + + +int yyparse (void); + + +#endif /* !YY_YY_SRC_PREPROC_PIC_PIC_HPP_INCLUDED */ diff --git a/src/preproc/pic/pic.ypp b/src/preproc/pic/pic.ypp new file mode 100644 index 0000000..b2fa6dc --- /dev/null +++ b/src/preproc/pic/pic.ypp @@ -0,0 +1,1957 @@ +/* Copyright (C) 1989-2022 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +%{ +#include "pic.h" +#include "ptable.h" +#include "object.h" + +extern int delim_flag; +extern void copy_rest_thru(const char *, const char *); +extern void copy_file_thru(const char *, const char *, const char *); +extern void push_body(const char *); +extern void do_for(char *var, double from, double to, + int by_is_multiplicative, double by, char *body); +extern void do_lookahead(); + +/* Maximum number of characters produced by printf("%g") */ +#define GDIGITS 14 + +int yylex(); +void yyerror(const char *); + +void reset(const char *nm); +void reset_all(); + +place *lookup_label(const char *); +void define_label(const char *label, const place *pl); + +direction current_direction; +position current_position; + +implement_ptable(place) + +PTABLE(place) top_table; + +PTABLE(place) *current_table = &top_table; +saved_state *current_saved_state = 0; + +object_list olist; + +const char *ordinal_postfix(int n); +const char *object_type_name(object_type type); +char *format_number(const char *fmt, double n); +char *do_sprintf(const char *fmt, const double *v, int nv); + +%} + +%expect 2 + +%union { + char *str; + int n; + double x; + struct { double x, y; } pair; + struct { double x; char *body; } if_data; + struct { char *str; const char *filename; int lineno; } lstr; + struct { double *v; int nv; int maxv; } dv; + struct { double val; int is_multiplicative; } by; + place pl; + object *obj; + corner crn; + path *pth; + object_spec *spec; + saved_state *pstate; + graphics_state state; + object_type obtype; +} + +%token LABEL +%token VARIABLE +%token NUMBER +%token TEXT +%token COMMAND_LINE +%token DELIMITED +%token ORDINAL +%token TH +%token LEFT_ARROW_HEAD +%token RIGHT_ARROW_HEAD +%token DOUBLE_ARROW_HEAD +%token LAST +%token BOX +%token CIRCLE +%token ELLIPSE +%token ARC +%token LINE +%token ARROW +%token MOVE +%token SPLINE +%token HEIGHT +%token RADIUS +%token FIGNAME +%token WIDTH +%token DIAMETER +%token UP +%token DOWN +%token RIGHT +%token LEFT +%token FROM +%token TO +%token AT +%token WITH +%token BY +%token THEN +%token SOLID +%token DOTTED +%token DASHED +%token CHOP +%token SAME +%token INVISIBLE +%token LJUST +%token RJUST +%token ABOVE +%token BELOW +%token OF +%token THE +%token WAY +%token BETWEEN +%token AND +%token HERE +%token DOT_N +%token DOT_E +%token DOT_W +%token DOT_S +%token DOT_NE +%token DOT_SE +%token DOT_NW +%token DOT_SW +%token DOT_C +%token DOT_START +%token DOT_END +%token DOT_X +%token DOT_Y +%token DOT_HT +%token DOT_WID +%token DOT_RAD +%token SIN +%token COS +%token ATAN2 +%token LOG +%token EXP +%token SQRT +%token K_MAX +%token K_MIN +%token INT +%token RAND +%token SRAND +%token COPY +%token THRU +%token TOP +%token BOTTOM +%token UPPER +%token LOWER +%token SH +%token PRINT +%token CW +%token CCW +%token FOR +%token DO +%token IF +%token ELSE +%token ANDAND +%token OROR +%token NOTEQUAL +%token EQUALEQUAL +%token LESSEQUAL +%token GREATEREQUAL +%token LEFT_CORNER +%token RIGHT_CORNER +%token NORTH +%token SOUTH +%token EAST +%token WEST +%token CENTER +%token END +%token START +%token RESET +%token UNTIL +%token PLOT +%token THICKNESS +%token FILL +%token COLORED +%token OUTLINED +%token SHADED +%token XSLANTED +%token YSLANTED +%token ALIGNED +%token SPRINTF +%token COMMAND + +%token DEFINE +%token UNDEF + +%left '.' + +/* this ensures that plot 17 "%g" parses as (plot 17 "%g") */ +%left PLOT +%left TEXT SPRINTF + +/* give text adjustments higher precedence than TEXT, so that +box "foo" above ljust == box ("foo" above ljust) +*/ + +%left LJUST RJUST ABOVE BELOW + +%left LEFT RIGHT +/* Give attributes that take an optional expression a higher +precedence than left and right, so that, e.g., 'line chop left' +parses properly. */ +%left CHOP SOLID DASHED DOTTED UP DOWN FILL COLORED OUTLINED +%left XSLANTED YSLANTED +%left LABEL + +%left VARIABLE NUMBER '(' SIN COS ATAN2 LOG EXP SQRT K_MAX K_MIN INT RAND SRAND LAST +%left ORDINAL HERE '`' + +%left BOX CIRCLE ELLIPSE ARC LINE ARROW SPLINE '[' + +/* these need to be lower than '-' */ +%left HEIGHT RADIUS WIDTH DIAMETER FROM TO AT THICKNESS + +/* these must have higher precedence than CHOP so that 'label %prec CHOP' +works */ +%left DOT_N DOT_E DOT_W DOT_S DOT_NE DOT_SE DOT_NW DOT_SW DOT_C +%left DOT_START DOT_END TOP BOTTOM LEFT_CORNER RIGHT_CORNER +%left UPPER LOWER NORTH SOUTH EAST WEST CENTER START END + +%left ',' +%left OROR +%left ANDAND +%left EQUALEQUAL NOTEQUAL +%left '<' '>' LESSEQUAL GREATEREQUAL + +%left BETWEEN OF +%left AND + +%left '+' '-' +%left '*' '/' '%' +%right '!' +%right '^' + +%type expr expr_lower_than expr_not_lower_than any_expr text_expr +%type optional_by +%type expr_pair position_not_place +%type simple_if +%type nth_primitive +%type corner +%type path label_path relative_path +%type place label element element_list middle_element_list +%type object_spec +%type position +%type object_type +%type optional_ordinal_last ordinal +%type macro_name until +%type sprintf_args +%type text print_args print_arg + +%% + +top: + optional_separator + | element_list + { + if (olist.head) + print_picture(olist.head); + } + ; + + +element_list: + optional_separator middle_element_list optional_separator + { $$ = $2; } + ; + +middle_element_list: + element + { $$ = $1; } + | middle_element_list separator element + { $$ = $1; } + ; + +optional_separator: + /* empty */ + | separator + ; + +separator: + ';' + | separator ';' + ; + +placeless_element: + FIGNAME '=' macro_name + { + delete[] graphname; + graphname = new char[strlen($3) + 1]; + strcpy(graphname, $3); + delete[] $3; + } + | + VARIABLE '=' any_expr + { + define_variable($1, $3); + free($1); + } + | VARIABLE ':' '=' any_expr + { + place *p = lookup_label($1); + if (!p) { + lex_error("variable '%1' not defined", $1); + YYABORT; + } + p->obj = 0; + p->x = $4; + p->y = 0.0; + free($1); + } + | UP + { current_direction = UP_DIRECTION; } + | DOWN + { current_direction = DOWN_DIRECTION; } + | LEFT + { current_direction = LEFT_DIRECTION; } + | RIGHT + { current_direction = RIGHT_DIRECTION; } + | COMMAND_LINE + { + olist.append(make_command_object($1.str, $1.filename, + $1.lineno)); + } + | COMMAND print_args + { + olist.append(make_command_object($2.str, $2.filename, + $2.lineno)); + } + | PRINT print_args + { + fprintf(stderr, "%s\n", $2.str); + delete[] $2.str; + fflush(stderr); + } + | SH + { delim_flag = 1; } + DELIMITED + { + delim_flag = 0; + if (safer_flag) + lex_error("unsafe to run command '%1'; ignoring", + $3); + else { + int retval = system($3); + if (retval < 0) + lex_error("error running command '%1': system()" + " returned %2", $3, retval); + } + delete[] $3; + } + | COPY TEXT + { + if (yychar < 0) + do_lookahead(); + do_copy($2.str); + // do not delete the filename + } + | COPY TEXT THRU + { delim_flag = 2; } + DELIMITED + { delim_flag = 0; } + until + { + if (yychar < 0) + do_lookahead(); + copy_file_thru($2.str, $5, $7); + // do not delete the filename + delete[] $5; + delete[] $7; + } + | COPY THRU + { delim_flag = 2; } + DELIMITED + { delim_flag = 0; } + until + { + if (yychar < 0) + do_lookahead(); + copy_rest_thru($4, $6); + delete[] $4; + delete[] $6; + } + | FOR VARIABLE '=' expr TO expr optional_by DO + { delim_flag = 1; } + DELIMITED + { + delim_flag = 0; + if (yychar < 0) + do_lookahead(); + do_for($2, $4, $6, $7.is_multiplicative, $7.val, $10); + } + | simple_if + { + if (yychar < 0) + do_lookahead(); + if ($1.x != 0.0) + push_body($1.body); + delete[] $1.body; + } + | simple_if ELSE + { delim_flag = 1; } + DELIMITED + { + delim_flag = 0; + if (yychar < 0) + do_lookahead(); + if ($1.x != 0.0) + push_body($1.body); + else + push_body($4); + free($1.body); + free($4); + } + | reset_variables + | RESET + { define_variable("scale", 1.0); } + ; + +macro_name: + VARIABLE + | LABEL + ; + +reset_variables: + RESET VARIABLE + { + reset($2); + delete[] $2; + } + | reset_variables VARIABLE + { + reset($2); + delete[] $2; + } + | reset_variables ',' VARIABLE + { + reset($3); + delete[] $3; + } + ; + +print_args: + print_arg + { $$ = $1; } + | print_args print_arg + { + $$.str = new char[strlen($1.str) + strlen($2.str) + 1]; + strcpy($$.str, $1.str); + strcat($$.str, $2.str); + delete[] $1.str; + delete[] $2.str; + if ($1.filename) { + $$.filename = $1.filename; + $$.lineno = $1.lineno; + } + else if ($2.filename) { + $$.filename = $2.filename; + $$.lineno = $2.lineno; + } + } + ; + +print_arg: + expr %prec ',' + { + $$.str = new char[GDIGITS + 1]; + sprintf($$.str, "%g", $1); + $$.filename = 0; + $$.lineno = 0; + } + | text + { $$ = $1; } + | position %prec ',' + { + $$.str = new char[GDIGITS + 2 + GDIGITS + 1]; + sprintf($$.str, "%g, %g", $1.x, $1.y); + $$.filename = 0; + $$.lineno = 0; + } + ; + +simple_if: + IF any_expr THEN + { delim_flag = 1; } + DELIMITED + { + delim_flag = 0; + $$.x = $2; + $$.body = $5; + } + ; + +until: + /* empty */ + { $$ = 0; } + | UNTIL TEXT + { $$ = $2.str; } + ; + +any_expr: + expr + { $$ = $1; } + | text_expr + { $$ = $1; } + ; + +text_expr: + text EQUALEQUAL text + { + $$ = strcmp($1.str, $3.str) == 0; + delete[] $1.str; + delete[] $3.str; + } + | text NOTEQUAL text + { + $$ = strcmp($1.str, $3.str) != 0; + delete[] $1.str; + delete[] $3.str; + } + | text_expr ANDAND text_expr + { $$ = ($1 != 0.0 && $3 != 0.0); } + | text_expr ANDAND expr + { $$ = ($1 != 0.0 && $3 != 0.0); } + | expr ANDAND text_expr + { $$ = ($1 != 0.0 && $3 != 0.0); } + | text_expr OROR text_expr + { $$ = ($1 != 0.0 || $3 != 0.0); } + | text_expr OROR expr + { $$ = ($1 != 0.0 || $3 != 0.0); } + | expr OROR text_expr + { $$ = ($1 != 0.0 || $3 != 0.0); } + | '!' text_expr + { $$ = ($2 == 0.0); } + ; + + +optional_by: + /* empty */ + { + $$.val = 1.0; + $$.is_multiplicative = 0; + } + | BY expr + { + $$.val = $2; + $$.is_multiplicative = 0; + } + | BY '*' expr + { + $$.val = $3; + $$.is_multiplicative = 1; + } + ; + +element: + object_spec + { + $$.obj = $1->make_object(¤t_position, + ¤t_direction); + if ($$.obj == 0) + YYABORT; + delete $1; + if ($$.obj) + olist.append($$.obj); + else { + $$.x = current_position.x; + $$.y = current_position.y; + } + } + | LABEL ':' optional_separator element + { + $$ = $4; + define_label($1, & $$); + free($1); + } + | LABEL ':' optional_separator position_not_place + { + $$.obj = 0; + $$.x = $4.x; + $$.y = $4.y; + define_label($1, & $$); + free($1); + } + | LABEL ':' optional_separator place + { + $$ = $4; + define_label($1, & $$); + free($1); + } + | '{' + { + $$.x = current_position.x; + $$.y = current_position.y; + $$.dir = current_direction; + } + element_list '}' + { + current_position.x = $2.x; + current_position.y = $2.y; + current_direction = $2.dir; + } + optional_element + { + $$ = $3; + } + | placeless_element + { + $$.obj = 0; + $$.x = current_position.x; + $$.y = current_position.y; + } + ; + +optional_element: + /* empty */ + {} + | element + {} + ; + +object_spec: + BOX + { $$ = new object_spec(BOX_OBJECT); } + | CIRCLE + { $$ = new object_spec(CIRCLE_OBJECT); } + | ELLIPSE + { $$ = new object_spec(ELLIPSE_OBJECT); } + | ARC + { + $$ = new object_spec(ARC_OBJECT); + $$->dir = current_direction; + } + | LINE + { + $$ = new object_spec(LINE_OBJECT); + lookup_variable("lineht", & $$->segment_height); + lookup_variable("linewid", & $$->segment_width); + $$->dir = current_direction; + } + | ARROW + { + $$ = new object_spec(ARROW_OBJECT); + lookup_variable("lineht", & $$->segment_height); + lookup_variable("linewid", & $$->segment_width); + $$->dir = current_direction; + } + | MOVE + { + $$ = new object_spec(MOVE_OBJECT); + lookup_variable("moveht", & $$->segment_height); + lookup_variable("movewid", & $$->segment_width); + $$->dir = current_direction; + } + | SPLINE + { + $$ = new object_spec(SPLINE_OBJECT); + lookup_variable("lineht", & $$->segment_height); + lookup_variable("linewid", & $$->segment_width); + $$->dir = current_direction; + } + | text %prec TEXT + { + $$ = new object_spec(TEXT_OBJECT); + $$->text = new text_item($1.str, $1.filename, $1.lineno); + } + | PLOT expr + { + lex_warning("'plot' is deprecated; use 'sprintf'" + " instead"); + $$ = new object_spec(TEXT_OBJECT); + $$->text = new text_item(format_number(0, $2), 0, -1); + } + | PLOT expr text + { + $$ = new object_spec(TEXT_OBJECT); + $$->text = new text_item(format_number($3.str, $2), + $3.filename, $3.lineno); + delete[] $3.str; + } + | '[' + { + saved_state *p = new saved_state; + $$ = p; + p->x = current_position.x; + p->y = current_position.y; + p->dir = current_direction; + p->tbl = current_table; + p->prev = current_saved_state; + current_position.x = 0.0; + current_position.y = 0.0; + current_table = new PTABLE(place); + current_saved_state = p; + olist.append(make_mark_object()); + } + element_list ']' + { + current_position.x = $2->x; + current_position.y = $2->y; + current_direction = $2->dir; + $$ = new object_spec(BLOCK_OBJECT); + olist.wrap_up_block(& $$->oblist); + $$->tbl = current_table; + current_table = $2->tbl; + current_saved_state = $2->prev; + delete $2; + } + | object_spec HEIGHT expr + { + $$ = $1; + $$->height = $3; + $$->flags |= HAS_HEIGHT; + } + | object_spec RADIUS expr + { + $$ = $1; + $$->radius = $3; + $$->flags |= HAS_RADIUS; + } + | object_spec WIDTH expr + { + $$ = $1; + $$->width = $3; + $$->flags |= HAS_WIDTH; + } + | object_spec DIAMETER expr + { + $$ = $1; + $$->radius = $3/2.0; + $$->flags |= HAS_RADIUS; + } + | object_spec expr %prec HEIGHT + { + $$ = $1; + $$->flags |= HAS_SEGMENT; + switch ($$->dir) { + case UP_DIRECTION: + $$->segment_pos.y += $2; + break; + case DOWN_DIRECTION: + $$->segment_pos.y -= $2; + break; + case RIGHT_DIRECTION: + $$->segment_pos.x += $2; + break; + case LEFT_DIRECTION: + $$->segment_pos.x -= $2; + break; + } + } + | object_spec UP + { + $$ = $1; + $$->dir = UP_DIRECTION; + $$->flags |= HAS_SEGMENT; + $$->segment_pos.y += $$->segment_height; + } + | object_spec UP expr + { + $$ = $1; + $$->dir = UP_DIRECTION; + $$->flags |= HAS_SEGMENT; + $$->segment_pos.y += $3; + } + | object_spec DOWN + { + $$ = $1; + $$->dir = DOWN_DIRECTION; + $$->flags |= HAS_SEGMENT; + $$->segment_pos.y -= $$->segment_height; + } + | object_spec DOWN expr + { + $$ = $1; + $$->dir = DOWN_DIRECTION; + $$->flags |= HAS_SEGMENT; + $$->segment_pos.y -= $3; + } + | object_spec RIGHT + { + $$ = $1; + $$->dir = RIGHT_DIRECTION; + $$->flags |= HAS_SEGMENT; + $$->segment_pos.x += $$->segment_width; + } + | object_spec RIGHT expr + { + $$ = $1; + $$->dir = RIGHT_DIRECTION; + $$->flags |= HAS_SEGMENT; + $$->segment_pos.x += $3; + } + | object_spec LEFT + { + $$ = $1; + $$->dir = LEFT_DIRECTION; + $$->flags |= HAS_SEGMENT; + $$->segment_pos.x -= $$->segment_width; + } + | object_spec LEFT expr + { + $$ = $1; + $$->dir = LEFT_DIRECTION; + $$->flags |= HAS_SEGMENT; + $$->segment_pos.x -= $3; + } + | object_spec FROM position + { + $$ = $1; + $$->flags |= HAS_FROM; + $$->from.x = $3.x; + $$->from.y = $3.y; + } + | object_spec TO position + { + $$ = $1; + if ($$->flags & HAS_SEGMENT) + $$->segment_list = new segment($$->segment_pos, + $$->segment_is_absolute, + $$->segment_list); + $$->flags |= HAS_SEGMENT; + $$->segment_pos.x = $3.x; + $$->segment_pos.y = $3.y; + $$->segment_is_absolute = 1; + $$->flags |= HAS_TO; + $$->to.x = $3.x; + $$->to.y = $3.y; + } + | object_spec AT position + { + $$ = $1; + $$->flags |= HAS_AT; + $$->at.x = $3.x; + $$->at.y = $3.y; + if ($$->type != ARC_OBJECT) { + $$->flags |= HAS_FROM; + $$->from.x = $3.x; + $$->from.y = $3.y; + } + } + | object_spec WITH path + { + $$ = $1; + $$->flags |= HAS_WITH; + $$->with = $3; + } + | object_spec WITH position %prec ',' + { + $$ = $1; + $$->flags |= HAS_WITH; + position pos; + pos.x = $3.x; + pos.y = $3.y; + $$->with = new path(pos); + } + | object_spec BY expr_pair + { + $$ = $1; + $$->flags |= HAS_SEGMENT; + $$->segment_pos.x += $3.x; + $$->segment_pos.y += $3.y; + } + | object_spec THEN + { + $$ = $1; + if (!($$->flags & HAS_SEGMENT)) + switch ($$->dir) { + case UP_DIRECTION: + $$->segment_pos.y += $$->segment_width; + break; + case DOWN_DIRECTION: + $$->segment_pos.y -= $$->segment_width; + break; + case RIGHT_DIRECTION: + $$->segment_pos.x += $$->segment_width; + break; + case LEFT_DIRECTION: + $$->segment_pos.x -= $$->segment_width; + break; + } + $$->segment_list = new segment($$->segment_pos, + $$->segment_is_absolute, + $$->segment_list); + $$->flags &= ~HAS_SEGMENT; + $$->segment_pos.x = $$->segment_pos.y = 0.0; + $$->segment_is_absolute = 0; + } + | object_spec SOLID + { + $$ = $1; // nothing + } + | object_spec DOTTED + { + $$ = $1; + $$->flags |= IS_DOTTED; + lookup_variable("dashwid", & $$->dash_width); + } + | object_spec DOTTED expr + { + $$ = $1; + $$->flags |= IS_DOTTED; + $$->dash_width = $3; + } + | object_spec DASHED + { + $$ = $1; + $$->flags |= IS_DASHED; + lookup_variable("dashwid", & $$->dash_width); + } + | object_spec DASHED expr + { + $$ = $1; + $$->flags |= IS_DASHED; + $$->dash_width = $3; + } + | object_spec FILL + { + $$ = $1; + $$->flags |= IS_DEFAULT_FILLED; + } + | object_spec FILL expr + { + $$ = $1; + $$->flags |= IS_FILLED; + $$->fill = $3; + } + | object_spec XSLANTED expr + { + $$ = $1; + $$->flags |= IS_XSLANTED; + $$->xslanted = $3; + } + | object_spec YSLANTED expr + { + $$ = $1; + $$->flags |= IS_YSLANTED; + $$->yslanted = $3; + } + | object_spec SHADED text + { + $$ = $1; + $$->flags |= (IS_SHADED | IS_FILLED); + $$->shaded = new char[strlen($3.str)+1]; + strcpy($$->shaded, $3.str); + } + | object_spec COLORED text + { + $$ = $1; + $$->flags |= (IS_SHADED | IS_OUTLINED | IS_FILLED); + $$->shaded = new char[strlen($3.str)+1]; + strcpy($$->shaded, $3.str); + $$->outlined = new char[strlen($3.str)+1]; + strcpy($$->outlined, $3.str); + } + | object_spec OUTLINED text + { + $$ = $1; + $$->flags |= IS_OUTLINED; + $$->outlined = new char[strlen($3.str)+1]; + strcpy($$->outlined, $3.str); + } + | object_spec CHOP + { + $$ = $1; + // line chop chop means line chop 0 chop 0 + if ($$->flags & IS_DEFAULT_CHOPPED) { + $$->flags |= IS_CHOPPED; + $$->flags &= ~IS_DEFAULT_CHOPPED; + $$->start_chop = $$->end_chop = 0.0; + } + else if ($$->flags & IS_CHOPPED) { + $$->end_chop = 0.0; + } + else { + $$->flags |= IS_DEFAULT_CHOPPED; + } + } + | object_spec CHOP expr + { + $$ = $1; + if ($$->flags & IS_DEFAULT_CHOPPED) { + $$->flags |= IS_CHOPPED; + $$->flags &= ~IS_DEFAULT_CHOPPED; + $$->start_chop = 0.0; + $$->end_chop = $3; + } + else if ($$->flags & IS_CHOPPED) { + $$->end_chop = $3; + } + else { + $$->start_chop = $$->end_chop = $3; + $$->flags |= IS_CHOPPED; + } + } + | object_spec SAME + { + $$ = $1; + $$->flags |= IS_SAME; + } + | object_spec INVISIBLE + { + $$ = $1; + $$->flags |= IS_INVISIBLE; + } + | object_spec LEFT_ARROW_HEAD + { + $$ = $1; + $$->flags |= HAS_LEFT_ARROW_HEAD; + } + | object_spec RIGHT_ARROW_HEAD + { + $$ = $1; + $$->flags |= HAS_RIGHT_ARROW_HEAD; + } + | object_spec DOUBLE_ARROW_HEAD + { + $$ = $1; + $$->flags |= (HAS_LEFT_ARROW_HEAD|HAS_RIGHT_ARROW_HEAD); + } + | object_spec CW + { + $$ = $1; + $$->flags |= IS_CLOCKWISE; + } + | object_spec CCW + { + $$ = $1; + $$->flags &= ~IS_CLOCKWISE; + } + | object_spec text %prec TEXT + { + $$ = $1; + text_item **p; + for (p = & $$->text; *p; p = &(*p)->next) + ; + *p = new text_item($2.str, $2.filename, $2.lineno); + } + | object_spec LJUST + { + $$ = $1; + if ($$->text) { + text_item *p; + for (p = $$->text; p->next; p = p->next) + ; + p->adj.h = LEFT_ADJUST; + } + } + | object_spec RJUST + { + $$ = $1; + if ($$->text) { + text_item *p; + for (p = $$->text; p->next; p = p->next) + ; + p->adj.h = RIGHT_ADJUST; + } + } + | object_spec ABOVE + { + $$ = $1; + if ($$->text) { + text_item *p; + for (p = $$->text; p->next; p = p->next) + ; + p->adj.v = ABOVE_ADJUST; + } + } + | object_spec BELOW + { + $$ = $1; + if ($$->text) { + text_item *p; + for (p = $$->text; p->next; p = p->next) + ; + p->adj.v = BELOW_ADJUST; + } + } + | object_spec THICKNESS expr + { + $$ = $1; + $$->flags |= HAS_THICKNESS; + $$->thickness = $3; + } + | object_spec ALIGNED + { + $$ = $1; + $$->flags |= IS_ALIGNED; + } + ; + +text: + TEXT + { $$ = $1; } + | SPRINTF '(' TEXT sprintf_args ')' + { + $$.filename = $3.filename; + $$.lineno = $3.lineno; + $$.str = do_sprintf($3.str, $4.v, $4.nv); + delete[] $4.v; + free($3.str); + } + ; + +sprintf_args: + /* empty */ + { + $$.v = 0; + $$.nv = 0; + $$.maxv = 0; + } + | sprintf_args ',' expr + { + $$ = $1; + if ($$.nv >= $$.maxv) { + if ($$.nv == 0) { + $$.v = new double[4]; + $$.maxv = 4; + } + else { + double *oldv = $$.v; + $$.maxv *= 2; +#if 0 + $$.v = new double[$$.maxv]; + memcpy($$.v, oldv, $$.nv*sizeof(double)); +#else + // workaround for bug in Compaq C++ V6.5-033 + // for Compaq Tru64 UNIX V5.1A (Rev. 1885) + double *foo = new double[$$.maxv]; + memcpy(foo, oldv, $$.nv*sizeof(double)); + $$.v = foo; +#endif + delete[] oldv; + } + } + $$.v[$$.nv] = $3; + $$.nv += 1; + } + ; + +position: + position_not_place + { $$ = $1; } + | place + { + position pos = $1; + $$.x = pos.x; + $$.y = pos.y; + } + | '(' place ')' + { + position pos = $2; + $$.x = pos.x; + $$.y = pos.y; + } + ; + +position_not_place: + expr_pair + { $$ = $1; } + | position '+' expr_pair + { + $$.x = $1.x + $3.x; + $$.y = $1.y + $3.y; + } + | '(' position '+' expr_pair ')' + { + $$.x = $2.x + $4.x; + $$.y = $2.y + $4.y; + } + | position '-' expr_pair + { + $$.x = $1.x - $3.x; + $$.y = $1.y - $3.y; + } + | '(' position '-' expr_pair ')' + { + $$.x = $2.x - $4.x; + $$.y = $2.y - $4.y; + } + | '(' position ',' position ')' + { + $$.x = $2.x; + $$.y = $4.y; + } + | expr between position AND position + { + $$.x = (1.0 - $1)*$3.x + $1*$5.x; + $$.y = (1.0 - $1)*$3.y + $1*$5.y; + } + | '(' expr between position AND position ')' + { + $$.x = (1.0 - $2)*$4.x + $2*$6.x; + $$.y = (1.0 - $2)*$4.y + $2*$6.y; + } + /* the next two rules cause harmless shift/reduce warnings */ + | expr_not_lower_than '<' position ',' position '>' + { + $$.x = (1.0 - $1)*$3.x + $1*$5.x; + $$.y = (1.0 - $1)*$3.y + $1*$5.y; + } + | '(' expr_not_lower_than '<' position ',' position '>' ')' + { + $$.x = (1.0 - $2)*$4.x + $2*$6.x; + $$.y = (1.0 - $2)*$4.y + $2*$6.y; + } + ; + +between: + BETWEEN + | OF THE WAY BETWEEN + ; + +expr_pair: + expr ',' expr + { + $$.x = $1; + $$.y = $3; + } + | '(' expr_pair ')' + { $$ = $2; } + ; + +place: + /* line at A left == line (at A) left */ + label %prec CHOP + { $$ = $1; } + | label corner + { + path pth($2); + if (!pth.follow($1, & $$)) + YYABORT; + } + | corner label + { + path pth($1); + if (!pth.follow($2, & $$)) + YYABORT; + } + | corner OF label + { + path pth($1); + if (!pth.follow($3, & $$)) + YYABORT; + } + | HERE + { + $$.x = current_position.x; + $$.y = current_position.y; + $$.obj = 0; + } + ; + +label: + LABEL + { + place *p = lookup_label($1); + if (!p) { + lex_error("there is no place '%1'", $1); + YYABORT; + } + $$ = *p; + free($1); + } + | nth_primitive + { $$.obj = $1; } + | label '.' LABEL + { + path pth($3); + if (!pth.follow($1, & $$)) + YYABORT; + } + ; + +ordinal: + ORDINAL + { $$ = $1; } + | '`' any_expr TH + { + // XXX Check for overflow (and non-integers?). + $$ = (int)$2; + } + ; + +optional_ordinal_last: + LAST + { $$ = 1; } + | ordinal LAST + { $$ = $1; } + ; + +nth_primitive: + ordinal object_type + { + int count = 0; + object *p; + for (p = olist.head; p != 0; p = p->next) + if (p->type() == $2 && ++count == $1) { + $$ = p; + break; + } + if (p == 0) { + lex_error("there is no %1%2 %3", $1, ordinal_postfix($1), + object_type_name($2)); + YYABORT; + } + } + | optional_ordinal_last object_type + { + int count = 0; + object *p; + for (p = olist.tail; p != 0; p = p->prev) + if (p->type() == $2 && ++count == $1) { + $$ = p; + break; + } + if (p == 0) { + lex_error("there is no %1%2 last %3", $1, + ordinal_postfix($1), object_type_name($2)); + YYABORT; + } + } + ; + +object_type: + BOX + { $$ = BOX_OBJECT; } + | CIRCLE + { $$ = CIRCLE_OBJECT; } + | ELLIPSE + { $$ = ELLIPSE_OBJECT; } + | ARC + { $$ = ARC_OBJECT; } + | LINE + { $$ = LINE_OBJECT; } + | ARROW + { $$ = ARROW_OBJECT; } + | SPLINE + { $$ = SPLINE_OBJECT; } + | '[' ']' + { $$ = BLOCK_OBJECT; } + | TEXT + { $$ = TEXT_OBJECT; } + ; + +label_path: + '.' LABEL + { $$ = new path($2); } + | label_path '.' LABEL + { + $$ = $1; + $$->append($3); + } + ; + +relative_path: + corner %prec CHOP + { $$ = new path($1); } + /* give this a lower precedence than LEFT and RIGHT so that + [A: box] with .A left == [A: box] with (.A left) */ + | label_path %prec TEXT + { $$ = $1; } + | label_path corner + { + $$ = $1; + $$->append($2); + } + ; + +path: + relative_path + { $$ = $1; } + | '(' relative_path ',' relative_path ')' + { + $$ = $2; + $$->set_ypath($4); + } + /* The rest of these rules are a compatibility sop. */ + | ORDINAL LAST object_type relative_path + { + lex_warning("'%1%2 last %3' in 'with' argument ignored", + $1, ordinal_postfix($1), object_type_name($3)); + $$ = $4; + } + | LAST object_type relative_path + { + lex_warning("'last %1' in 'with' argument ignored", + object_type_name($2)); + $$ = $3; + } + | ORDINAL object_type relative_path + { + lex_warning("'%1%2 %3' in 'with' argument ignored", + $1, ordinal_postfix($1), object_type_name($2)); + $$ = $3; + } + | LABEL relative_path + { + lex_warning("initial '%1' in 'with' argument ignored", $1); + delete[] $1; + $$ = $2; + } + ; + +corner: + DOT_N + { $$ = &object::north; } + | DOT_E + { $$ = &object::east; } + | DOT_W + { $$ = &object::west; } + | DOT_S + { $$ = &object::south; } + | DOT_NE + { $$ = &object::north_east; } + | DOT_SE + { $$ = &object:: south_east; } + | DOT_NW + { $$ = &object::north_west; } + | DOT_SW + { $$ = &object::south_west; } + | DOT_C + { $$ = &object::center; } + | DOT_START + { $$ = &object::start; } + | DOT_END + { $$ = &object::end; } + | TOP + { $$ = &object::north; } + | BOTTOM + { $$ = &object::south; } + | LEFT + { $$ = &object::west; } + | RIGHT + { $$ = &object::east; } + | UPPER LEFT + { $$ = &object::north_west; } + | LOWER LEFT + { $$ = &object::south_west; } + | UPPER RIGHT + { $$ = &object::north_east; } + | LOWER RIGHT + { $$ = &object::south_east; } + | LEFT_CORNER + { $$ = &object::west; } + | RIGHT_CORNER + { $$ = &object::east; } + | UPPER LEFT_CORNER + { $$ = &object::north_west; } + | LOWER LEFT_CORNER + { $$ = &object::south_west; } + | UPPER RIGHT_CORNER + { $$ = &object::north_east; } + | LOWER RIGHT_CORNER + { $$ = &object::south_east; } + | NORTH + { $$ = &object::north; } + | SOUTH + { $$ = &object::south; } + | EAST + { $$ = &object::east; } + | WEST + { $$ = &object::west; } + | CENTER + { $$ = &object::center; } + | START + { $$ = &object::start; } + | END + { $$ = &object::end; } + ; + +expr: + expr_lower_than + { $$ = $1; } + | expr_not_lower_than + { $$ = $1; } + ; + +expr_lower_than: + expr '<' expr + { $$ = ($1 < $3); } + ; + +expr_not_lower_than: + VARIABLE + { + if (!lookup_variable($1, & $$)) { + lex_error("there is no variable '%1'", $1); + YYABORT; + } + free($1); + } + | NUMBER + { $$ = $1; } + | place DOT_X + { + if ($1.obj != 0) + $$ = $1.obj->origin().x; + else + $$ = $1.x; + } + | place DOT_Y + { + if ($1.obj != 0) + $$ = $1.obj->origin().y; + else + $$ = $1.y; + } + | place DOT_HT + { + if ($1.obj != 0) + $$ = $1.obj->height(); + else + $$ = 0.0; + } + | place DOT_WID + { + if ($1.obj != 0) + $$ = $1.obj->width(); + else + $$ = 0.0; + } + | place DOT_RAD + { + if ($1.obj != 0) + $$ = $1.obj->radius(); + else + $$ = 0.0; + } + | expr '+' expr + { $$ = $1 + $3; } + | expr '-' expr + { $$ = $1 - $3; } + | expr '*' expr + { $$ = $1 * $3; } + | expr '/' expr + { + if ($3 == 0.0) { + lex_error("division by zero"); + YYABORT; + } + $$ = $1/$3; + } + | expr '%' expr + { + if ($3 == 0.0) { + lex_error("modulus by zero"); + YYABORT; + } + $$ = fmod($1, $3); + } + | expr '^' expr + { + errno = 0; + $$ = pow($1, $3); + if (errno == EDOM) { + lex_error("arguments to '^' operator out of domain"); + YYABORT; + } + if (errno == ERANGE) { + lex_error("result of '^' operator out of range"); + YYABORT; + } + } + | '-' expr %prec '!' + { $$ = -$2; } + | '(' any_expr ')' + { $$ = $2; } + | SIN '(' any_expr ')' + { + errno = 0; + $$ = sin($3); + if (errno == ERANGE) { + lex_error("sin result out of range"); + YYABORT; + } + } + | COS '(' any_expr ')' + { + errno = 0; + $$ = cos($3); + if (errno == ERANGE) { + lex_error("cos result out of range"); + YYABORT; + } + } + | ATAN2 '(' any_expr ',' any_expr ')' + { + errno = 0; + $$ = atan2($3, $5); + if (errno == EDOM) { + lex_error("atan2 argument out of domain"); + YYABORT; + } + if (errno == ERANGE) { + lex_error("atan2 result out of range"); + YYABORT; + } + } + | LOG '(' any_expr ')' + { + errno = 0; + $$ = log10($3); + if (errno == ERANGE) { + lex_error("log result out of range"); + YYABORT; + } + } + | EXP '(' any_expr ')' + { + errno = 0; + $$ = pow(10.0, $3); + if (errno == ERANGE) { + lex_error("exp result out of range"); + YYABORT; + } + } + | SQRT '(' any_expr ')' + { + errno = 0; + $$ = sqrt($3); + if (errno == EDOM) { + lex_error("sqrt argument out of domain"); + YYABORT; + } + } + | K_MAX '(' any_expr ',' any_expr ')' + { $$ = $3 > $5 ? $3 : $5; } + | K_MIN '(' any_expr ',' any_expr ')' + { $$ = $3 < $5 ? $3 : $5; } + | INT '(' any_expr ')' + { $$ = $3 < 0 ? -floor(-$3) : floor($3); } + | RAND '(' any_expr ')' + { + lex_error("use of 'rand' with an argument is" + " deprecated; shift and scale 'rand()' with" + " arithmetic instead"); + $$ = 1.0 + floor(((rand()&0x7fff)/double(0x7fff))*$3); + } + | RAND '(' ')' + { + /* return a random number in the range [0,1) */ + /* portable, but not very random */ + $$ = (rand() & 0x7fff) / double(0x8000); + } + | SRAND '(' any_expr ')' + { + $$ = 0; + srand((unsigned int)$3); + } + | expr LESSEQUAL expr + { $$ = ($1 <= $3); } + | expr '>' expr + { $$ = ($1 > $3); } + | expr GREATEREQUAL expr + { $$ = ($1 >= $3); } + | expr EQUALEQUAL expr + { $$ = ($1 == $3); } + | expr NOTEQUAL expr + { $$ = ($1 != $3); } + | expr ANDAND expr + { $$ = ($1 != 0.0 && $3 != 0.0); } + | expr OROR expr + { $$ = ($1 != 0.0 || $3 != 0.0); } + | '!' expr + { $$ = ($2 == 0.0); } + + ; + +%% + +/* bison defines const to be empty unless __STDC__ is defined, which it +isn't under cfront */ + +#ifdef const +#undef const +#endif + +static struct { + const char *name; + double val; + int scaled; // non-zero if val should be multiplied by scale +} defaults_table[] = { + { "arcrad", .25, 1 }, + { "arrowht", .1, 1 }, + { "arrowwid", .05, 1 }, + { "circlerad", .25, 1 }, + { "boxht", .5, 1 }, + { "boxwid", .75, 1 }, + { "boxrad", 0.0, 1 }, + { "dashwid", .05, 1 }, + { "ellipseht", .5, 1 }, + { "ellipsewid", .75, 1 }, + { "moveht", .5, 1 }, + { "movewid", .5, 1 }, + { "lineht", .5, 1 }, + { "linewid", .5, 1 }, + { "textht", 0.0, 1 }, + { "textwid", 0.0, 1 }, + { "scale", 1.0, 0 }, + { "linethick", -1.0, 0 }, // in points + { "fillval", .5, 0 }, + { "arrowhead", 1.0, 0 }, + { "maxpswid", 8.5, 0 }, + { "maxpsht", 11.0, 0 }, +}; + +place *lookup_label(const char *label) +{ + saved_state *state = current_saved_state; + PTABLE(place) *tbl = current_table; + for (;;) { + place *pl = tbl->lookup(label); + if (pl) + return pl; + if (!state) + return 0; + tbl = state->tbl; + state = state->prev; + } +} + +void define_label(const char *label, const place *pl) +{ + place *p = new place[1]; + *p = *pl; + current_table->define(label, p); +} + +int lookup_variable(const char *name, double *val) +{ + place *pl = lookup_label(name); + if (pl) { + *val = pl->x; + return 1; + } + return 0; +} + +void define_variable(const char *name, double val) +{ + place *p = new place[1]; + p->obj = 0; + p->x = val; + p->y = 0.0; + current_table->define(name, p); + if (strcmp(name, "scale") == 0) { + // When the scale changes, reset all scaled predefined variables to + // their default values. + for (unsigned int i = 0; + i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++) + if (defaults_table[i].scaled) + define_variable(defaults_table[i].name, val*defaults_table[i].val); + } +} + +// called once only (not once per parse) + +void parse_init() +{ + current_direction = RIGHT_DIRECTION; + current_position.x = 0.0; + current_position.y = 0.0; + // This resets everything to its default value. + reset_all(); +} + +void reset(const char *nm) +{ + for (unsigned int i = 0; + i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++) + if (strcmp(nm, defaults_table[i].name) == 0) { + double val = defaults_table[i].val; + if (defaults_table[i].scaled) { + double scale; + lookup_variable("scale", &scale); + val *= scale; + } + define_variable(defaults_table[i].name, val); + return; + } + lex_error("'%1' is not a predefined variable", nm); +} + +void reset_all() +{ + // We only have to explicitly reset the predefined variables that + // aren't scaled because 'scale' is not scaled, and changing the + // value of 'scale' will reset all the predefined variables that + // are scaled. + for (unsigned int i = 0; + i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++) + if (!defaults_table[i].scaled) + define_variable(defaults_table[i].name, defaults_table[i].val); +} + +// called after each parse + +void parse_cleanup() +{ + while (current_saved_state != 0) { + delete current_table; + current_table = current_saved_state->tbl; + saved_state *tem = current_saved_state; + current_saved_state = current_saved_state->prev; + delete tem; + } + assert(current_table == &top_table); + PTABLE_ITERATOR(place) iter(current_table); + const char *key; + place *pl; + while (iter.next(&key, &pl)) + if (pl->obj != 0) { + position pos = pl->obj->origin(); + pl->obj = 0; + pl->x = pos.x; + pl->y = pos.y; + } + while (olist.head != 0) { + object *tem = olist.head; + olist.head = olist.head->next; + delete tem; + } + olist.tail = 0; + current_direction = RIGHT_DIRECTION; + current_position.x = 0.0; + current_position.y = 0.0; +} + +const char *ordinal_postfix(int n) +{ + if (n < 10 || n > 20) + switch (n % 10) { + case 1: + return "st"; + case 2: + return "nd"; + case 3: + return "rd"; + } + return "th"; +} + +const char *object_type_name(object_type type) +{ + switch (type) { + case BOX_OBJECT: + return "box"; + case CIRCLE_OBJECT: + return "circle"; + case ELLIPSE_OBJECT: + return "ellipse"; + case ARC_OBJECT: + return "arc"; + case SPLINE_OBJECT: + return "spline"; + case LINE_OBJECT: + return "line"; + case ARROW_OBJECT: + return "arrow"; + case MOVE_OBJECT: + return "move"; + case TEXT_OBJECT: + return "\"\""; + case BLOCK_OBJECT: + return "[]"; + case OTHER_OBJECT: + case MARK_OBJECT: + default: + break; + } + return "object"; +} + +static char sprintf_buf[1024]; + +char *format_number(const char *fmt, double n) +{ + if (0 /* nullptr */ == fmt) + fmt = "%g"; + return do_sprintf(fmt, &n, 1); +} + +char *do_sprintf(const char *fmt, const double *v, int nv) +{ + // Define valid conversion specifiers and modifiers. + static const char spcs[] = "eEfgG%"; + static const char mods[] = "#-+ 0123456789."; + string result; + int i = 0; + string one_format; + while (*fmt) { + if ('%' == *fmt) { + one_format += *fmt++; + for (; *fmt != '\0' && strchr(mods, *fmt) != 0; fmt++) + one_format += *fmt; + if ('\0' == *fmt || strchr(spcs, *fmt) == 0) { + lex_error("invalid sprintf conversion specifier '%1'", *fmt); + result += one_format; + result += fmt; + break; + } + if ('%' == *fmt) { + fmt++; + snprintf(sprintf_buf, sizeof(sprintf_buf), "%%"); + } + else { + if (i >= nv) { + lex_error("too few arguments to sprintf"); + result += one_format; + result += fmt; + break; + } + one_format += *fmt++; + one_format += '\0'; +// We validated the format string above. Most conversion specifiers are +// rejected, including `n`. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" + snprintf(sprintf_buf, sizeof(sprintf_buf), + one_format.contents(), v[i++]); +#pragma GCC diagnostic pop + } + one_format.clear(); + result += sprintf_buf; + } + else + result += *fmt++; + } + result += '\0'; + return strsave(result.contents()); +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/pic/position.h b/src/preproc/pic/position.h new file mode 100644 index 0000000..fb32737 --- /dev/null +++ b/src/preproc/pic/position.h @@ -0,0 +1,46 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +struct place; +struct position { + double x; + double y; + position(double, double ); + position(); + position(const place &); + position &operator+=(const position &); + position &operator-=(const position &); + position &operator*=(double); + position &operator/=(double); +}; + +position operator-(const position &); +position operator+(const position &, const position &); +position operator-(const position &, const position &); +position operator/(const position &, double); +position operator*(const position &, double); +// dot product +double operator*(const position &, const position &); +int operator==(const position &, const position &); +int operator!=(const position &, const position &); + +double hypot(const position &a); + +typedef position distance; + diff --git a/src/preproc/pic/tex.cpp b/src/preproc/pic/tex.cpp new file mode 100644 index 0000000..c6071af --- /dev/null +++ b/src/preproc/pic/tex.cpp @@ -0,0 +1,458 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "pic.h" + +#ifdef TEX_SUPPORT + +#include "common.h" + +class tex_output : public common_output { +public: + tex_output(); + ~tex_output(); + void start_picture(double, const position &ll, const position &ur); + void finish_picture(); + void text(const position &, text_piece *, int, double); + void line(const position &, const position *, int n, + const line_type &); + void polygon(const position *, int n, + const line_type &, double); + void spline(const position &, const position *, int n, + const line_type &); + void arc(const position &, const position &, const position &, + const line_type &); + void circle(const position &, double rad, const line_type &, double); + void ellipse(const position &, const distance &, const line_type &, double); + void command(const char *, const char *, int); + void set_color(char *, char *); + void reset_color(); + char *get_last_filled(); + char *get_outline_color(); + int supports_filled_polygons(); +private: + position upper_left; + double height; + double width; + double scale; + double pen_size; + + void point(const position &); + void dot(const position &, const line_type &); + void solid_arc(const position ¢, double rad, double start_angle, + double end_angle, const line_type <); + position transform(const position &); +protected: + virtual void set_pen_size(double ps); +}; + +// convert inches to milliinches + +inline int milliinches(double x) +{ + return int(x*1000.0 + .5); +} + +inline position tex_output::transform(const position &pos) +{ + return position((pos.x - upper_left.x)/scale, + (upper_left.y - pos.y)/scale); +} + +output *make_tex_output() +{ + return new tex_output; +} + +tex_output::tex_output() +{ +} + +tex_output::~tex_output() +{ +} + +const int DEFAULT_PEN_SIZE = 8; + +void tex_output::set_pen_size(double ps) +{ + if (ps < 0.0) + ps = -1.0; + if (ps != pen_size) { + pen_size = ps; + printf(" \\special{pn %d}%%\n", + ps < 0.0 ? DEFAULT_PEN_SIZE : int(ps*(1000.0/72.0) + .5)); + } +} + +void tex_output::start_picture(double sc, const position &ll, + const position &ur) +{ + upper_left.x = ll.x; + upper_left.y = ur.y; + scale = compute_scale(sc, ll, ur); + height = (ur.y - ll.y)/scale; + width = (ur.x - ll.x)/scale; + /* The point of \vskip 0pt is to ensure that the vtop gets + a height of 0 rather than the height of the hbox; this + might be non-zero if text from text attributes lies outside pic's + idea of the bounding box of the picture. */ + /* \newbox and \newdimen are defined with \outer in plain.tex and can't + be used directly in an \if clause. */ + printf("\\expandafter\\ifx\\csname %s\\endcsname\\relax\n" + " \\csname newbox\\expandafter\\endcsname\\csname %s\\endcsname\n" + "\\fi\n" + "\\ifx\\graphtemp\\undefined\n" + " \\csname newdimen\\endcsname\\graphtemp\n" + "\\fi\n" + "\\expandafter\\setbox\\csname %s\\endcsname\n" + " =\\vtop{\\vskip 0pt\\hbox{%%\n", + graphname, graphname, graphname); + pen_size = -2.0; +} + +void tex_output::finish_picture() +{ + printf(" \\hbox{\\vrule depth%.3fin width0pt height 0pt}%%\n" + " \\kern %.3fin\n" + " }%%\n" + "}%%\n", + height, width); +} + +void tex_output::text(const position ¢er, text_piece *v, int n, double) +{ + position c = transform(center); + for (int i = 0; i < n; i++) + if (v[i].text != 0 && *v[i].text != '\0') { + int j = 2*i - n + 1; + if (v[i].adj.v == ABOVE_ADJUST) + j--; + else if (v[i].adj.v == BELOW_ADJUST) + j++; + if (j == 0) { + printf(" \\graphtemp=.5ex\n" + " \\advance\\graphtemp by %.3fin\n", c.y); + } + else { + printf(" \\graphtemp=\\baselineskip\n" + " \\multiply\\graphtemp by %d\n" + " \\divide\\graphtemp by 2\n" + " \\advance\\graphtemp by .5ex\n" + " \\advance\\graphtemp by %.3fin\n", + j, c.y); + } + printf(" \\rlap{\\kern %.3fin\\lower\\graphtemp", c.x); + fputs("\\hbox to 0pt{", stdout); + if (v[i].adj.h != LEFT_ADJUST) + fputs("\\hss ", stdout); + fputs(v[i].text, stdout); + if (v[i].adj.h != RIGHT_ADJUST) + fputs("\\hss", stdout); + fputs("}}%\n", stdout); + } +} + +void tex_output::point(const position &pos) +{ + position p = transform(pos); + printf(" \\special{pa %d %d}%%\n", milliinches(p.x), milliinches(p.y)); +} + +void tex_output::line(const position &start, const position *v, int n, + const line_type <) +{ + set_pen_size(lt.thickness); + point(start); + for (int i = 0; i < n; i++) + point(v[i]); + fputs(" \\special{", stdout); + switch(lt.type) { + case line_type::invisible: + fputs("ip", stdout); + break; + case line_type::solid: + fputs("fp", stdout); + break; + case line_type::dotted: + printf("dt %.3f", lt.dash_width/scale); + break; + case line_type::dashed: + printf("da %.3f", lt.dash_width/scale); + break; + } + fputs("}%\n", stdout); +} + +void tex_output::polygon(const position *v, int n, + const line_type <, double fill) +{ + if (fill >= 0.0) { + if (fill > 1.0) + fill = 1.0; + printf(" \\special{sh %.3f}%%\n", fill); + } + line(v[n-1], v, n, lt); +} + +void tex_output::spline(const position &start, const position *v, int n, + const line_type <) +{ + if (lt.type == line_type::invisible) + return; + set_pen_size(lt.thickness); + point(start); + for (int i = 0; i < n; i++) + point(v[i]); + fputs(" \\special{sp", stdout); + switch(lt.type) { + case line_type::solid: + break; + case line_type::dotted: + printf(" %.3f", -lt.dash_width/scale); + break; + case line_type::dashed: + printf(" %.3f", lt.dash_width/scale); + break; + case line_type::invisible: + assert(0); + } + fputs("}%\n", stdout); +} + +void tex_output::solid_arc(const position ¢, double rad, + double start_angle, double end_angle, + const line_type <) +{ + set_pen_size(lt.thickness); + position c = transform(cent); + printf(" \\special{ar %d %d %d %d %f %f}%%\n", + milliinches(c.x), + milliinches(c.y), + milliinches(rad/scale), + milliinches(rad/scale), + -end_angle, + (-end_angle > -start_angle) ? (double)M_PI * 2 - start_angle + : -start_angle); +} + +void tex_output::arc(const position &start, const position ¢, + const position &end, const line_type <) +{ + switch (lt.type) { + case line_type::invisible: + break; + case line_type::dashed: + dashed_arc(start, cent, end, lt); + break; + case line_type::dotted: + dotted_arc(start, cent, end, lt); + break; + case line_type::solid: + { + position c; + if (!compute_arc_center(start, cent, end, &c)) { + line(start, &end, 1, lt); + break; + } + solid_arc(c, + hypot(cent - start), + atan2(start.y - c.y, start.x - c.x), + atan2(end.y - c.y, end.x - c.x), + lt); + break; + } + } +} + +void tex_output::circle(const position ¢, double rad, + const line_type <, double fill) +{ + if (fill >= 0.0 && lt.type != line_type::solid) { + if (fill > 1.0) + fill = 1.0; + line_type ilt; + ilt.type = line_type::invisible; + ellipse(cent, position(rad*2.0, rad*2.0), ilt, fill); + } + switch (lt.type) { + case line_type::dashed: + dashed_circle(cent, rad, lt); + break; + case line_type::invisible: + break; + case line_type::solid: + ellipse(cent, position(rad*2.0,rad*2.0), lt, fill); + break; + case line_type::dotted: + dotted_circle(cent, rad, lt); + break; + default: + assert(0); + } +} + +void tex_output::ellipse(const position ¢, const distance &dim, + const line_type <, double fill) +{ + if (lt.type == line_type::invisible) { + if (fill < 0.0) + return; + } + else + set_pen_size(lt.thickness); + if (fill >= 0.0) { + if (fill > 1.0) + fill = 1.0; + printf(" \\special{sh %.3f}%%\n", fill); + } + position c = transform(cent); + switch (lt.type) { + case line_type::solid: + case line_type::invisible: + printf(" \\special{%s %d %d %d %d 0 6.28319}%%\n", + (lt.type == line_type::invisible ? "ia" : "ar"), + milliinches(c.x), + milliinches(c.y), + milliinches(dim.x/(2.0*scale)), + milliinches(dim.y/(2.0*scale))); + break; + case line_type::dashed: + dashed_ellipse(cent, dim / scale, lt); + break; + case line_type::dotted: + dotted_ellipse(cent, dim / scale, lt); + break; + default: + assert(0); + } +} + +void tex_output::command(const char *s, const char *, int) +{ + fputs(s, stdout); + putchar('%'); // avoid unwanted spaces + putchar('\n'); +} + +int tex_output::supports_filled_polygons() +{ + return 1; +} + +void tex_output::dot(const position &pos, const line_type <) +{ + if (zero_length_line_flag) { + line_type slt = lt; + slt.type = line_type::solid; + line(pos, &pos, 1, slt); + } + else { + int dot_rad = int(lt.thickness*(1000.0/(72.0*2)) + .5); + if (dot_rad == 0) + dot_rad = 1; + position p = transform(pos); + printf(" \\special{sh 1}%%\n" + " \\special{ia %d %d %d %d 0 6.28319}%%\n", + milliinches(p.x), milliinches(p.y), dot_rad, dot_rad); + } +} + +void tex_output::set_color(char *, char *) +{ + /* not implemented yet */ +} + +void tex_output::reset_color() +{ + /* not implemented yet */ +} + +char *tex_output::get_last_filled() +{ + /* not implemented yet */ + return NULL; +} + +char *tex_output::get_outline_color() +{ + /* not implemented yet */ + return NULL; +} + +class tpic_output : public tex_output { +public: + tpic_output(); + void command(const char *, const char *, int); +private: + void set_pen_size(double ps); + int default_pen_size; + int prev_default_pen_size; +}; + +tpic_output::tpic_output() +: default_pen_size(DEFAULT_PEN_SIZE), prev_default_pen_size(DEFAULT_PEN_SIZE) +{ +} + +void tpic_output::command(const char *s, const char *filename, int lineno) +{ + assert(s[0] == '.'); + if (s[1] == 'p' && s[2] == 's' && (s[3] == '\0' || !csalpha(s[3]))) { + const char *p = s + 3; + while (csspace(*p)) + p++; + if (*p == '\0') { + int temp = default_pen_size; + default_pen_size = prev_default_pen_size; + prev_default_pen_size = temp; + } + else { + char *ptr; + int temp = (int)strtol(p, &ptr, 10); + if (temp == 0 && ptr == p) + error_with_file_and_line(filename, lineno, + "argument to '.ps' not an integer"); + else if (temp < 0) + error_with_file_and_line(filename, lineno, + "negative pen size"); + else { + prev_default_pen_size = default_pen_size; + default_pen_size = temp; + } + } + } + else + printf("\\%s%%\n", s + 1); +} + +void tpic_output::set_pen_size(double ps) +{ + if (ps < 0.0) + printf(" \\special{pn %d}%%\n", default_pen_size); + else + tex_output::set_pen_size(ps); +} + +output *make_tpic_output() +{ + return new tpic_output; +} + +#endif diff --git a/src/preproc/pic/text.h b/src/preproc/pic/text.h new file mode 100644 index 0000000..9b9353f --- /dev/null +++ b/src/preproc/pic/text.h @@ -0,0 +1,46 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + + +enum hadjustment { + CENTER_ADJUST, + LEFT_ADJUST, + RIGHT_ADJUST + }; + +enum vadjustment { + NONE_ADJUST, + ABOVE_ADJUST, + BELOW_ADJUST + }; + +struct adjustment { + hadjustment h; + vadjustment v; +}; + +struct text_piece { + char *text; + adjustment adj; + const char *filename; + int lineno; + + text_piece(); + ~text_piece(); +}; diff --git a/src/preproc/pic/troff.cpp b/src/preproc/pic/troff.cpp new file mode 100644 index 0000000..3dc87a7 --- /dev/null +++ b/src/preproc/pic/troff.cpp @@ -0,0 +1,579 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "pic.h" +#include "common.h" + + +const double RELATIVE_THICKNESS = -1.0; +const double BAD_THICKNESS = -2.0; + +class simple_output : public common_output { + virtual void simple_line(const position &, const position &) = 0; + virtual void simple_spline(const position &, const position *, int n) = 0; + virtual void simple_arc(const position &, const position &, + const position &) = 0; + virtual void simple_circle(int, const position &, double rad) = 0; + virtual void simple_ellipse(int, const position &, const distance &) = 0; + virtual void simple_polygon(int, const position *, int) = 0; + virtual void line_thickness(double) = 0; + virtual void set_fill(double) = 0; + virtual void set_color(char *, char *) = 0; + virtual void reset_color() = 0; + virtual char *get_last_filled() = 0; + void dot(const position &, const line_type &) = 0; +public: + void start_picture(double sc, const position &ll, const position &ur) = 0; + void finish_picture() = 0; + void text(const position &, text_piece *, int, double) = 0; + void line(const position &, const position *, int n, + const line_type &); + void polygon(const position *, int n, + const line_type &, double); + void spline(const position &, const position *, int n, + const line_type &); + void arc(const position &, const position &, const position &, + const line_type &); + void circle(const position &, double rad, const line_type &, double); + void ellipse(const position &, const distance &, const line_type &, double); + int supports_filled_polygons(); +}; + +int simple_output::supports_filled_polygons() +{ + return driver_extension_flag != 0; +} + +void simple_output::arc(const position &start, const position ¢, + const position &end, const line_type <) +{ + switch (lt.type) { + case line_type::solid: + line_thickness(lt.thickness); + simple_arc(start, cent, end); + break; + case line_type::invisible: + break; + case line_type::dashed: + dashed_arc(start, cent, end, lt); + break; + case line_type::dotted: + dotted_arc(start, cent, end, lt); + break; + } +} + +void simple_output::line(const position &start, const position *v, int n, + const line_type <) +{ + position pos = start; + line_thickness(lt.thickness); + for (int i = 0; i < n; i++) { + switch (lt.type) { + case line_type::solid: + simple_line(pos, v[i]); + break; + case line_type::dotted: + { + distance vec(v[i] - pos); + double dist = hypot(vec); + int ndots = int(dist/lt.dash_width + .5); + if (ndots == 0) + dot(pos, lt); + else { + vec /= double(ndots); + for (int j = 0; j <= ndots; j++) + dot(pos + vec*j, lt); + } + } + break; + case line_type::dashed: + { + distance vec(v[i] - pos); + double dist = hypot(vec); + if (dist <= lt.dash_width*2.0) + simple_line(pos, v[i]); + else { + int ndashes = int((dist - lt.dash_width)/(lt.dash_width*2.0) + .5); + distance dash_vec = vec*(lt.dash_width/dist); + double dash_gap = (dist - lt.dash_width)/ndashes; + distance dash_gap_vec = vec*(dash_gap/dist); + for (int j = 0; j <= ndashes; j++) { + position s(pos + dash_gap_vec*j); + simple_line(s, s + dash_vec); + } + } + } + break; + case line_type::invisible: + break; + default: + assert(0); + } + pos = v[i]; + } +} + +void simple_output::spline(const position &start, const position *v, int n, + const line_type <) +{ + line_thickness(lt.thickness); + simple_spline(start, v, n); +} + +void simple_output::polygon(const position *v, int n, + const line_type <, double fill) +{ + if (driver_extension_flag && ((fill >= 0.0) || (get_last_filled() != 0))) { + if (get_last_filled() == 0) + set_fill(fill); + simple_polygon(1, v, n); + } + if (lt.type == line_type::solid && driver_extension_flag) { + line_thickness(lt.thickness); + simple_polygon(0, v, n); + } + else if (lt.type != line_type::invisible) { + line_thickness(lt.thickness); + line(v[n - 1], v, n, lt); + } +} + +void simple_output::circle(const position ¢, double rad, + const line_type <, double fill) +{ + if (driver_extension_flag && ((fill >= 0.0) || (get_last_filled() != 0))) { + if (get_last_filled() == 0) + set_fill(fill); + simple_circle(1, cent, rad); + } + line_thickness(lt.thickness); + switch (lt.type) { + case line_type::invisible: + break; + case line_type::dashed: + dashed_circle(cent, rad, lt); + break; + case line_type::dotted: + dotted_circle(cent, rad, lt); + break; + case line_type::solid: + simple_circle(0, cent, rad); + break; + default: + assert(0); + } +} + +void simple_output::ellipse(const position ¢, const distance &dim, + const line_type <, double fill) +{ + if (driver_extension_flag && ((fill >= 0.0) || (get_last_filled() != 0))) { + if (get_last_filled() == 0) + set_fill(fill); + simple_ellipse(1, cent, dim); + } + if (lt.type != line_type::invisible) + line_thickness(lt.thickness); + switch (lt.type) { + case line_type::invisible: + break; + case line_type::dotted: + dotted_ellipse(cent, dim, lt); + break; + case line_type::dashed: + dashed_ellipse(cent, dim, lt); + break; + case line_type::solid: + simple_ellipse(0, cent, dim); + break; + default: + assert(0); + } +} + +class troff_output : public simple_output { + const char *last_filename; + position upper_left; + double height; + double scale; + double last_line_thickness; + double last_fill; + char *last_filled; // color + char *last_outlined; // color +public: + troff_output(); + ~troff_output(); + void start_picture(double, const position &ll, const position &ur); + void finish_picture(); + void text(const position &, text_piece *, int, double); + void dot(const position &, const line_type &); + void command(const char *, const char *, int); + void set_location(const char *, int); + void simple_line(const position &, const position &); + void simple_spline(const position &, const position *, int n); + void simple_arc(const position &, const position &, const position &); + void simple_circle(int, const position &, double rad); + void simple_ellipse(int, const position &, const distance &); + void simple_polygon(int, const position *, int); + void line_thickness(double p); + void set_fill(double); + void set_color(char *, char *); + void reset_color(); + char *get_last_filled(); + char *get_outline_color(); + position transform(const position &); +}; + +output *make_troff_output() +{ + return new troff_output; +} + +troff_output::troff_output() +: last_filename(0), last_line_thickness(BAD_THICKNESS), + last_fill(-1.0), last_filled(0), last_outlined(0) +{ +} + +troff_output::~troff_output() +{ + free((char *)last_filename); +} + +inline position troff_output::transform(const position &pos) +{ + return position((pos.x - upper_left.x)/scale, + (upper_left.y - pos.y)/scale); +} + +#define FILL_REG "00" + +// If this register > 0, then pic will generate \X'ps: ...' commands +// if the aligned attribute is used. +#define GROPS_REG "0p" + +// If this register is defined, geqn won't produce '\x's. +#define EQN_NO_EXTRA_SPACE_REG "0x" + +void troff_output::start_picture(double sc, + const position &ll, const position &ur) +{ + upper_left.x = ll.x; + upper_left.y = ur.y; + scale = compute_scale(sc, ll, ur); + height = (ur.y - ll.y)/scale; + double width = (ur.x - ll.x)/scale; + printf(".PS %.3fi %.3fi", height, width); + if (args) + printf(" %s\n", args); + else + putchar('\n'); + printf(".\\\" %g %g %g %g\n", ll.x, ll.y, ur.x, ur.y); + printf(".\\\" %.3fi %.3fi %.3fi %.3fi\n", 0.0, height, width, 0.0); + printf(".nr " FILL_REG " \\n(.u\n.nf\n"); + printf(".nr " EQN_NO_EXTRA_SPACE_REG " 1\n"); + // This guarantees that if the picture is used in a diversion it will + // have the right width. + printf("\\h'%.3fi'\n.sp -1\n", width); +} + +void troff_output::finish_picture() +{ + line_thickness(BAD_THICKNESS); + last_fill = -1.0; // force it to be reset for each picture + reset_color(); + if (!(want_flyback || want_alternate_flyback)) + printf(".sp %.3fi+1\n", height); + printf(".if \\n(" FILL_REG " .fi\n"); + printf(".br\n"); + printf(".nr " EQN_NO_EXTRA_SPACE_REG " 0\n"); + // this is a little gross + set_location(current_filename, current_lineno); + if (want_flyback) + fputs(".PF\n", stdout); + else if (want_alternate_flyback) + fputs(".PY\n", stdout); + else + fputs(".PE\n", stdout); +} + +void troff_output::command(const char *s, + const char *filename, int lineno) +{ + if (filename != 0) + set_location(filename, lineno); + fputs(s, stdout); + putchar('\n'); +} + +void troff_output::simple_circle(int filled, const position ¢, double rad) +{ + position c = transform(cent); + printf("\\h'%.3fi'" + "\\v'%.3fi'" + "\\D'%c %.3fi'" + "\n.sp -1\n", + c.x - rad/scale, + c.y, + (filled ? 'C' : 'c'), + rad*2.0/scale); +} + +void troff_output::simple_ellipse(int filled, const position ¢, + const distance &dim) +{ + position c = transform(cent); + printf("\\h'%.3fi'" + "\\v'%.3fi'" + "\\D'%c %.3fi %.3fi'" + "\n.sp -1\n", + c.x - dim.x/(2.0*scale), + c.y, + (filled ? 'E' : 'e'), + dim.x/scale, dim.y/scale); +} + +void troff_output::simple_arc(const position &start, const distance ¢, + const distance &end) +{ + position s = transform(start); + position c = transform(cent); + distance cv = c - s; + distance ev = transform(end) - c; + printf("\\h'%.3fi'" + "\\v'%.3fi'" + "\\D'a %.3fi %.3fi %.3fi %.3fi'" + "\n.sp -1\n", + s.x, s.y, cv.x, cv.y, ev.x, ev.y); +} + +void troff_output::simple_line(const position &start, const position &end) +{ + position s = transform(start); + distance ev = transform(end) - s; + printf("\\h'%.3fi'" + "\\v'%.3fi'" + "\\D'l %.3fi %.3fi'" + "\n.sp -1\n", + s.x, s.y, ev.x, ev.y); +} + +void troff_output::simple_spline(const position &start, + const position *v, int n) +{ + position pos = transform(start); + printf("\\h'%.3fi'" + "\\v'%.3fi'", + pos.x, pos.y); + fputs("\\D'~ ", stdout); + for (int i = 0; i < n; i++) { + position temp = transform(v[i]); + distance d = temp - pos; + pos = temp; + if (i != 0) + putchar(' '); + printf("%.3fi %.3fi", d.x, d.y); + } + printf("'\n.sp -1\n"); +} + +// a solid polygon + +void troff_output::simple_polygon(int filled, const position *v, int n) +{ + position pos = transform(v[0]); + printf("\\h'%.3fi'" + "\\v'%.3fi'", + pos.x, pos.y); + printf("\\D'%c ", (filled ? 'P' : 'p')); + for (int i = 1; i < n; i++) { + position temp = transform(v[i]); + distance d = temp - pos; + pos = temp; + if (i != 1) + putchar(' '); + printf("%.3fi %.3fi", d.x, d.y); + } + printf("'\n.sp -1\n"); +} + +const double TEXT_AXIS = 0.22; // in ems + +static const char *choose_delimiter(const char *text) +{ + if (strchr(text, '\'') == 0) + return "'"; + else + return "\\(ts"; +} + +void troff_output::text(const position ¢er, text_piece *v, int n, + double ang) +{ + line_thickness(BAD_THICKNESS); // text might use lines (e.g., in equations) + int rotate_flag = 0; + if (driver_extension_flag && ang != 0.0) { + rotate_flag = 1; + position c = transform(center); + printf(".if \\n(" GROPS_REG " \\{\\\n" + "\\h'%.3fi'" + "\\v'%.3fi'" + "\\X'ps: exec gsave currentpoint 2 copy translate %.4f rotate neg exch neg exch translate'" + "\n.sp -1\n" + ".\\}\n", + c.x, c.y, -ang*180.0/M_PI); + } + for (int i = 0; i < n; i++) + if (v[i].text != 0 && *v[i].text != '\0') { + position c = transform(center); + if (v[i].filename != 0) + set_location(v[i].filename, v[i].lineno); + printf("\\h'%.3fi", c.x); + const char *delim = choose_delimiter(v[i].text); + if (v[i].adj.h == RIGHT_ADJUST) + printf("-\\w%s%s%su", delim, v[i].text, delim); + else if (v[i].adj.h != LEFT_ADJUST) + printf("-(\\w%s%s%su/2u)", delim, v[i].text, delim); + putchar('\''); + printf("\\v'%.3fi-(%dv/2u)+%dv+%.2fm", + c.y, + n - 1, + i, + TEXT_AXIS); + if (v[i].adj.v == ABOVE_ADJUST) + printf("-.5v"); + else if (v[i].adj.v == BELOW_ADJUST) + printf("+.5v"); + putchar('\''); + fputs(v[i].text, stdout); + fputs("\n.sp -1\n", stdout); + } + if (rotate_flag) + printf(".if \\n(" GROPS_REG " \\{\\\n" + "\\X'ps: exec grestore'\n.sp -1\n" + ".\\}\n"); +} + +void troff_output::line_thickness(double p) +{ + if (p < 0.0) + p = RELATIVE_THICKNESS; + if (driver_extension_flag && p != last_line_thickness) { + printf("\\D't %.3fp'\\h'%.3fp'\n.sp -1\n", p, -p); + last_line_thickness = p; + } +} + +void troff_output::set_fill(double f) +{ + if (driver_extension_flag && f != last_fill) { + // \D'Fg ...' emits a node only in compatibility mode, + // thus we add a dummy node + printf("\\&\\D'Fg %.3f'\n.sp -1\n", 1.0 - f); + last_fill = f; + } + if (last_filled) { + free(last_filled); + last_filled = 0; + printf(".fcolor\n"); + } +} + +void troff_output::set_color(char *color_fill, char *color_outlined) +{ + if (driver_extension_flag) { + if (last_filled || last_outlined) { + reset_color(); + } + // .gcolor and .fcolor emit a node in compatibility mode only, + // but that won't work anyway + if (color_fill) { + printf(".fcolor %s\n", color_fill); + last_filled = strsave(color_fill); + } + if (color_outlined) { + printf(".gcolor %s\n", color_outlined); + last_outlined = strsave(color_outlined); + } + } +} + +void troff_output::reset_color() +{ + if (driver_extension_flag) { + if (last_filled) { + printf(".fcolor\n"); + free(last_filled); + last_filled = 0; + } + if (last_outlined) { + printf(".gcolor\n"); + free(last_outlined); + last_outlined = 0; + } + } +} + +char *troff_output::get_last_filled() +{ + return last_filled; +} + +char *troff_output::get_outline_color() +{ + return last_outlined; +} + +const double DOT_AXIS = .044; + +void troff_output::dot(const position ¢, const line_type <) +{ + if (driver_extension_flag) { + line_thickness(lt.thickness); + simple_line(cent, cent); + } + else { + position c = transform(cent); + printf("\\h'%.3fi-(\\w'.'u/2u)'" + "\\v'%.3fi+%.2fm'" + ".\n.sp -1\n", + c.x, + c.y, + DOT_AXIS); + } +} + +void troff_output::set_location(const char *s, int n) +{ + if (last_filename != 0 && strcmp(s, last_filename) == 0) + printf(".lf %d\n", n); + else { + printf(".lf %d %s\n", n, s); + char *lfn = strdup(s); + if (0 == lfn) + fatal("memory allocation failure while copying file name"); + last_filename = lfn; + } +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/preconv/preconv.1.man b/src/preproc/preconv/preconv.1.man new file mode 100644 index 0000000..1535bae --- /dev/null +++ b/src/preproc/preconv/preconv.1.man @@ -0,0 +1,559 @@ +.TH preconv @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +preconv \- prepare files for typesetting with +.I groff +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 2006-2020 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_preconv_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY preconv +.RB [ \-dr ] +.RB [ \-D\~\c +.IR fallback-encoding ] +.RB [ \-e\~\c +.IR encoding ] +.RI [ file\~ .\|.\|.] +.YS +. +. +.SY preconv +.B \-h +. +.SY preconv +.B \-\-help +.YS +. +. +.SY preconv +.B \-v +. +.SY preconv +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I preconv +reads each +.IR file , +converts its encoded characters to a form +.MR @g@troff @MAN1EXT@ +can interpret, +and sends the result to the standard output stream. +. +Currently, +this means that code points in the range 0\[en]127 +(in US-ASCII, +ISO\~8859, +or Unicode) +remain as-is and the remainder are converted to the +.I groff +special character form +.RB \[lq] \[rs][\c +.BI u XXXX ]\c +\[rq], +where +.I XXXX +is a hexadecimal number of four to six digits corresponding to a Unicode +code point. +. +By default, +.I preconv +also inserts a +.I roff +.B .lf +request at the beginning of each +.IR file , +identifying it for the benefit of later processing +(including diagnostic messages); +the +.B \-r +option suppresses this behavior. +. +. +.PP +In typical usage scenarios, +.I preconv +need not be run directly; +instead it should be invoked with the +.B \-k +or +.B \-K +options of +.IR groff . +. +If no +.I file +operands are given on the command line, +or if +.I file +is +.RB \[lq] \- \[rq], +the standard input stream is read. +. +. +.PP +.I preconv +tries to find the input encoding with the following algorithm, +stopping at the first success. +. +. +.IP 1. 4n +If the input encoding has been explicitly specified with option +.BR \-e , +use it. +. +. +.IP 2. +If the input starts with a Unicode Byte Order Mark, +determine the encoding as UTF-8, +UTF-16, +or UTF-32 accordingly. +. +. +.IP 3. +If the input stream is seekable, +check the first and second input lines for a recognized GNU\~Emacs +file-local variable identifying the character encoding, +here referred to as the \[lq]coding tag\[rq] for brevity. +. +If found, +use it. +. +. +.IP 4. +If the input stream is seekable, +and if the +.I uchardet +library is available on the system, +use it to try to infer the encoding of the file. +. +. +.IP 5. +If the +.B \-D +option specifies an encoding, +use it. +. +. +.IP 6. +Use the encoding specified by the current locale +.RI ( LC_CTYPE ), +unless the locale is +\[lq]C\[rq], +\[lq]POSIX\[rq], +or empty, +in which case assume Latin-1 +(ISO\~8859-1). +. +. +.PP +The coding tag and +.I uchardet +methods in the above procedure rely upon a seekable input stream; +when +.I preconv +reads from a pipe, +the stream is not seekable, +and these detection methods are skipped. +. +If character encoding detection of your input files is unreliable, +arrange for one of the other methods to succeed by using +.IR preconv 's +.B \-D +or +.B \-e +options, +or by configuring your locale appropriately. +. +.I groff +also supports a +.I \%GROFF_ENCODING +environment variable, +which can be overridden by its +.B \-K +option. +. +Valid values for +(or parameters to) +all of these are enumerated in the lists of recognized coding tags in +the next subsection, +and are further influenced by +.I iconv +library support. +. +. +.\" ==================================================================== +.SS "Coding tags" +.\" ==================================================================== +. +Text editors that support more than a single character encoding need +tags within the input files to mark the file's encoding. +. +While it is possible to guess the right input encoding with the help of +heuristics that are reliable for a preponderance of natural language +texts, +they are not absolutely reliable. +. +Heuristics can fail on inputs that are too short or don't represent a +natural language. +. +. +.PP +Consequently, +.I preconv +supports the coding tag convention used by GNU\~Emacs +(with some restrictions). +. +This notation appears in specially marked regions of an input file +designated for \[lq]file-local variables\[rq]. +. +. +.PP +.I preconv +interprets the following syntax if it occurs in a +.I roff +comment +in the first or second line of the input file. +. +Both \[lq]\[rs]"\[rq] and \[lq]\[rs]#\[rq] comment forms are recognized, +but the control +(or no-break control) +character must be the default and must begin the line. +. +Similarly, +the escape character must be the default. +. +. +.RS +.EX +.B \-*\- \c +.RB [.\|.\|. ; ]\~\c +.B coding: \c +.I encoding\c +.RB [ ;\~ .\|.\|.\&]\~\c +.B \-*\- +.EE +.RE +. +. +.PP +The only variable +.I preconv +interprets is \[lq]coding\[rq], +which can take the values listed below. +. +. +.PP +The following list comprises all MIME \[lq]charset\[rq] parameter values +recognized, +case-insensitively, +by +.IR preconv . +. +.RS +\%big5, +\%cp1047, +\%euc\-jp, +\%euc\-kr, +\%gb2312, +\%iso\-8859\-1, +\%iso\-8859\-2, +\%iso\-8859\-5, +\%iso\-8859\-7, +\%iso\-8859\-9, +\%iso\-8859\-13, +\%iso\-8859\-15, +\%koi8\-r, +\%us\-ascii, +\%utf\-8, +\%utf\-16, +\%utf\-16be, +\%utf\-16le +.RE +. +. +.PP +In addition, +the following list of other coding tags is recognized, +each of which is mapped to an appropriate value from the list above. +. +.RS +\%ascii, +\%chinese\-big5, +\%chinese\-euc, +\%chinese\-iso\-8bit, +\%cn\-big5, +\%cn\-gb, +\%cn\-gb\-2312, +\%cp878, +\%csascii, +\%csisolatin1, +\%cyrillic\-iso\-8bit, +\%cyrillic\-koi8, +\%euc\-china, +\%euc\-cn, +\%euc\-japan, +\%euc\-japan\-1990, +\%euc\-korea, +\%greek\-iso\-8bit, +\%iso\-10646/utf8, +\%iso\-10646/utf\-8, +\%iso\-latin\-1, +\%iso\-latin\-2, +\%iso\-latin\-5, +\%iso\-latin\-7, +\%iso\-latin\-9, +\%japanese\-euc, +\%japanese\-iso\-8bit, +\%jis8, +\%koi8, +\%korean\-euc, +\%korean\-iso\-8bit, +\%latin\-0, +\%latin1, +\%latin\-1, +\%latin\-2, +\%latin\-5, +\%latin\-7, +\%latin\-9, +\%mule\-utf\-8, +\%mule\-utf\-16, +\%mule\-utf\-16be, +\%mule\-utf\-16\-be, +\%mule\-utf\-16be\-with\-signature, +\%mule\-utf\-16le, +\%mule\-utf\-16\-le, +\%mule\-utf\-16le\-with\-signature, +\%utf8, +\%utf\-16\-be, +\%utf\-16\-be\-with\-signature, +\%utf\-16be\-with\-signature, +\%utf\-16\-le, +\%utf\-16\-le\-with\-signature, +\%utf\-16le\-with\-signature +.RE +. +. +.PP +Trailing +\[lq]\-dos\[rq], +\[lq]\-unix\[rq], +and +\[lq]\-mac\[rq] +suffixes on coding tags +(which indicate the end-of-line convention used in the file) +are disregarded for the purpose of comparison with the above tags. +. +. +.\" ==================================================================== +.SS "\f[I]iconv\f[] support" +.\" ==================================================================== +. +While +.I preconv +recognizes all of the coding tags listed above, +it is capable on its own of interpreting only three encodings: +Latin-1, +code page 1047, +and UTF-8. +. +If +.I iconv +support is configured at compile time and available at run time, +all others are passed to +.I iconv +library functions, +which may recognize many additional encoding strings. +. +The command +.RB \[lq] preconv\~\-v \[rq] +discloses whether +.I iconv +support is configured. +. +. +.PP +The use of +.I iconv +means that characters in the input that encode invalid code points for +that encoding may be dropped from the output stream or mapped to the +Unicode replacement character +(U+FFFD). +. +Compare the following examples using the input \[lq]caf\['e]\[rq] +(note the \[lq]e\[rq] with an acute accent), +which due to its short length challenges inference of the encoding used. +. +.RS +.EX +printf \[aq]caf\[rs]351\[rs]n\[aq] | LC_ALL=en_US.UTF\-8 preconv +printf \[aq]caf\[rs]351\[rs]n\[aq] | preconv \-e us\-ascii +printf \[aq]caf\[rs]351\[rs]n\[aq] | preconv \-e latin\-1 +.EE +.RE +. +The fate of the accented \[lq]e\[rq] differs in each case. +. +In the first, +.I uchardet +fails to detect an encoding +(though the library on your system may behave differently) +and +.I preconv +falls back to the locale settings, +where octal 351 starts an incomplete UTF-8 sequence and results in the +Unicode replacement character. +. +In the second, +it is not a representable character in the declared input encoding of +US-ASCII and is discarded by +.IR iconv . +. +In the last, +it is correctly detected and mapped. +. +. +.\" ==================================================================== +.SS Limitations +.\" ==================================================================== +. +.I preconv +cannot perform any transformation on input that it cannot see. +. +Examples include files that are interpolated by preprocessors that run +subsequently, +including +.MR @g@soelim @MAN1EXT@ ; +files included by +.I @g@troff +itself through +.RB \[lq] so \[rq] +and similar requests; +and string definitions passed to +.I @g@troff +through its +.B \-d +command-line option. +. +. +.P +.I preconv +assumes that its input uses the default escape character, +a backslash +.BR \[rs] , +and writes special character escape sequences accordingly. +. +. +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-h +and +.B \-\-help +display a usage message, +while +.B \-v +and +.B \-\-version +show version information; +all exit afterward. +. +. +.TP +.B \-d +Emit debugging messages to the standard error stream. +. +. +.TP +.BI \-D\~ fallback-encoding +Report +.I fallback-encoding +if all detection methods fail. +. +. +.TP +.BI \-e\~ encoding +Skip detection and assume +.IR encoding ; +see +.IR groff 's +.B \-K +option. +. +. +.TP +.B \-r +Write files \[lq]raw\[rq]; +do not add +.B .lf +requests. +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.MR groff @MAN1EXT@ , +.MR iconv 3 , +.MR locale 7 +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_preconv_1_man_C] +.do rr *groff_preconv_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/preproc/preconv/preconv.am b/src/preproc/preconv/preconv.am new file mode 100644 index 0000000..199ff66 --- /dev/null +++ b/src/preproc/preconv/preconv.am @@ -0,0 +1,37 @@ +# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# +# This file 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 . + +bin_PROGRAMS += preconv +preconv_LDADD = libgroff.a $(LIBM) $(LIBICONV) $(UCHARDET_LIBS) \ + lib/libgnu.a +preconv_SOURCES = src/preproc/preconv/preconv.cpp +preconv_CPPFLAGS = $(AM_CPPFLAGS) $(UCHARDET_CFLAGS) +man1_MANS += src/preproc/preconv/preconv.1 +EXTRA_DIST += src/preproc/preconv/preconv.1.man + +preconv_TESTS = \ + src/preproc/preconv/tests/do-not-seek-the-unseekable.sh \ + src/preproc/preconv/tests/smoke-test.sh +TESTS += $(preconv_TESTS) +EXTRA_DIST += $(preconv_TESTS) + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/preproc/preconv/preconv.cpp b/src/preproc/preconv/preconv.cpp new file mode 100644 index 0000000..d403425 --- /dev/null +++ b/src/preproc/preconv/preconv.cpp @@ -0,0 +1,1318 @@ +/* Copyright (C) 2005-2020 Free Software Foundation, Inc. + Written by Werner Lemberg (wl@gnu.org) + +This file 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 . */ + +#include "lib.h" + +#include +#include +#include +#include +#ifdef HAVE_UCHARDET +#include +#endif + +#include "errarg.h" +#include "error.h" +#include "localcharset.h" +#include "nonposix.h" +#include "stringclass.h" +#include "lf.h" + +#include + +#if HAVE_ICONV +# include +# ifdef WORDS_BIGENDIAN +# define UNICODE "UTF-32BE" +# else +# define UNICODE "UTF-32LE" +# endif +#endif + +#define MAX_VAR_LEN 100 + +extern "C" const char *Version_string; + +char fallback_encoding[MAX_VAR_LEN]; +char user_encoding[MAX_VAR_LEN]; +char encoding_string[MAX_VAR_LEN]; +bool is_debugging = false; +int raw_flag = 0; + +struct conversion { + const char *from; + const char *to; +}; + +// The official list of MIME tags can be found at +// +// http://www.iana.org/assignments/character-sets +// +// For encodings which don't have a MIME tag we use GNU iconv's encoding +// names (which also work with the portable GNU libiconv package). They +// are marked with '*'. +// +// Encodings specific to XEmacs and Emacs are marked as such; no mark means +// that they are used by both Emacs and XEmacs. +// +// Encodings marked with '--' are special to Emacs, XEmacs, or other +// applications and shouldn't be used for data exchange. +// +// 'Not covered' means that the encoding can be handled neither by GNU iconv +// nor by libiconv, or just one of them has support for it. +// +// A special case is VIQR encoding: Despite of having a MIME tag it is +// missing in both libiconv 1.10 and iconv (coming with GNU libc 2.3.6). +// +// Finally, we add all aliases of GNU iconv for 'ascii', 'latin1', and +// 'utf8' to catch those encoding names before iconv is called. +// +// Note that most entries are commented out -- only a small, (rather) +// reliable and stable subset of encodings is recognized (for coding tags) +// which are still in greater use today (January 2006). Most notably, all +// Windows-specific encodings are not selected because they lack stability: +// Microsoft has changed the mappings instead of creating new versions. +// +// Please contact the groff list if you find the selection inadequate. + +static const conversion +emacs_to_mime[] = { + {"ascii", "US-ASCII"}, // Emacs + {"big5", "Big5"}, + {"chinese-big5", "Big5"}, // Emacs + {"chinese-euc", "GB2312"}, // XEmacs + {"chinese-iso-8bit", "GB2312"}, // Emacs + {"cn-big5", "Big5"}, + {"cn-gb", "GB2312"}, // Emacs + {"cn-gb-2312", "GB2312"}, + {"cp878", "KOI8-R"}, // Emacs + {"cp1047", "CP1047"}, // EBCDIC + {"csascii", "US-ASCII"}, // alias + {"csisolatin1", "ISO-8859-1"}, // alias + {"cyrillic-iso-8bit", "ISO-8859-5"}, // Emacs + {"cyrillic-koi8", "KOI8-R"}, // not KOI8!, Emacs + {"euc-china", "GB2312"}, // Emacs + {"euc-cn", "GB2312"}, // Emacs + {"euc-japan", "EUC-JP"}, + {"euc-japan-1990", "EUC-JP"}, // Emacs + {"euc-jp", "EUC-JP"}, + {"euc-korea", "EUC-KR"}, + {"euc-kr", "EUC-KR"}, + {"gb2312", "GB2312"}, + {"greek-iso-8bit", "ISO-8859-7"}, + {"iso-10646/utf8", "UTF-8"}, // alias + {"iso-10646/utf-8", "UTF-8"}, // alias + {"iso-8859-1", "ISO-8859-1"}, + {"iso-8859-13", "ISO-8859-13"}, // Emacs + {"iso-8859-15", "ISO-8859-15"}, + {"iso-8859-2", "ISO-8859-2"}, + {"iso-8859-5", "ISO-8859-5"}, + {"iso-8859-7", "ISO-8859-7"}, + {"iso-8859-9", "ISO-8859-9"}, + {"iso-latin-1", "ISO-8859-1"}, + {"iso-latin-2", "ISO-8859-2"}, // Emacs + {"iso-latin-5", "ISO-8859-9"}, // Emacs + {"iso-latin-7", "ISO-8859-13"}, // Emacs + {"iso-latin-9", "ISO-8859-15"}, // Emacs + {"japanese-iso-8bit", "EUC-JP"}, // Emacs + {"japanese-euc", "EUC-JP"}, // XEmacs + {"jis8", "EUC-JP"}, // XEmacs + {"koi8", "KOI8-R"}, // not KOI8!, Emacs + {"koi8-r", "KOI8-R"}, + {"korean-euc", "EUC-KR"}, // XEmacs + {"korean-iso-8bit", "EUC-KR"}, // Emacs + {"latin1", "ISO-8859-1"}, // alias + {"latin-0", "ISO-8859-15"}, // Emacs + {"latin-1", "ISO-8859-1"}, // Emacs + {"latin-2", "ISO-8859-2"}, // Emacs + {"latin-5", "ISO-8859-9"}, // Emacs + {"latin-7", "ISO-8859-13"}, // Emacs + {"latin-9", "ISO-8859-15"}, // Emacs + {"mule-utf-16", "UTF-16"}, // Emacs + {"mule-utf-16be", "UTF-16BE"}, // Emacs + {"mule-utf-16-be", "UTF-16BE"}, // Emacs + {"mule-utf-16be-with-signature", "UTF-16"}, // Emacs, not UTF-16BE + {"mule-utf-16le", "UTF-16LE"}, // Emacs + {"mule-utf-16-le", "UTF-16LE"}, // Emacs + {"mule-utf-16le-with-signature", "UTF-16"}, // Emacs, not UTF-16LE + {"mule-utf-8", "UTF-8"}, // Emacs + {"us-ascii", "US-ASCII"}, // Emacs + {"utf8", "UTF-8"}, // alias + {"utf-16", "UTF-16"}, // Emacs + {"utf-16be", "UTF-16BE"}, // Emacs + {"utf-16-be", "UTF-16BE"}, // Emacs + {"utf-16be-with-signature", "UTF-16"}, // Emacs, not UTF-16BE + {"utf-16-be-with-signature", "UTF-16"}, // Emacs, not UTF-16BE + {"utf-16le", "UTF-16LE"}, // Emacs + {"utf-16-le", "UTF-16LE"}, // Emacs + {"utf-16le-with-signature", "UTF-16"}, // Emacs, not UTF-16LE + {"utf-16-le-with-signature", "UTF-16"}, // Emacs, not UTF-16LE + {"utf-8", "UTF-8"}, // Emacs + +// {"alternativnyj", ""}, // ? +// {"arabic-iso-8bit", "ISO-8859-6"}, // Emacs +// {"binary", ""}, // -- +// {"chinese-hz", "HZ-GB-2312"}, // Emacs +// {"chinese-iso-7bit", "ISO-2022-CN"}, // Emacs +// {"chinese-iso-8bit-with-esc", ""}, // -- +// {"compound-text", ""}, // -- +// {"compound-text-with-extension", ""}, // -- +// {"cp1125", "cp1125"}, // * +// {"cp1250", "windows-1250"},// Emacs +// {"cp1251", "windows-1251"},// Emacs +// {"cp1252", "windows-1252"},// Emacs +// {"cp1253", "windows-1253"},// Emacs +// {"cp1254", "windows-1254"},// Emacs +// {"cp1255", "windows-1255"},// Emacs +// {"cp1256", "windows-1256"},// Emacs +// {"cp1257", "windows-1257"},// Emacs +// {"cp1258", "windows-1258"},// Emacs +// {"cp437", "cp437"}, // Emacs +// {"cp720", ""}, // not covered +// {"cp737", "cp737"}, // *, Emacs +// {"cp775", "cp775"}, // Emacs +// {"cp850", "cp850"}, // Emacs +// {"cp851", "cp851"}, // Emacs +// {"cp852", "cp852"}, // Emacs +// {"cp855", "cp855"}, // Emacs +// {"cp857", "cp857"}, // Emacs +// {"cp860", "cp860"}, // Emacs +// {"cp861", "cp861"}, // Emacs +// {"cp862", "cp862"}, // Emacs +// {"cp863", "cp863"}, // Emacs +// {"cp864", "cp864"}, // Emacs +// {"cp865", "cp865"}, // Emacs +// {"cp866", "cp866"}, // Emacs +// {"cp866u", "cp1125"}, // *, Emacs +// {"cp869", "cp869"}, // Emacs +// {"cp874", "cp874"}, // *, Emacs +// {"cp932", "cp932"}, // *, Emacs +// {"cp936", "cp936"}, // Emacs +// {"cp949", "cp949"}, // *, Emacs +// {"cp950", "cp950"}, // *, Emacs +// {"ctext", ""}, // -- +// {"ctext-no-compositions", ""}, // -- +// {"ctext-with-extensions", ""}, // -- +// {"cyrillic-alternativnyj", ""}, // ?, Emacs +// {"cyrillic-iso-8bit-with-esc", ""}, // -- +// {"cyrillic-koi8-t", "KOI8-T"}, // *, Emacs +// {"devanagari", ""}, // not covered +// {"dos", ""}, // -- +// {"emacs-mule", ""}, // -- +// {"euc-jisx0213", "EUC-JISX0213"},// *, XEmacs? +// {"euc-jisx0213-with-esc", ""}, // XEmacs? +// {"euc-taiwan", "EUC-TW"}, // *, Emacs +// {"euc-tw", "EUC-TW"}, // *, Emacs +// {"georgian-ps", "GEORGIAN-PS"}, // *, Emacs +// {"greek-iso-8bit-with-esc", ""}, // -- +// {"hebrew-iso-8bit", "ISO-8859-8"}, // Emacs +// {"hebrew-iso-8bit-with-esc", ""}, // -- +// {"hz", "HZ-GB-2312"}, +// {"hz-gb-2312", "HZ-GB-2312"}, +// {"in-is13194", ""}, // not covered +// {"in-is13194-devanagari", ""}, // not covered +// {"in-is13194-with-esc", ""}, // -- +// {"iso-2022-7", ""}, // XEmacs? +// {"iso-2022-7bit", ""}, // -- +// {"iso-2022-7bit-lock", ""}, // -- +// {"iso-2022-7bit-lock-ss2", ""}, // -- +// {"iso-2022-7bit-ss2", ""}, // -- +// {"iso-2022-8", ""}, // XEmacs? +// {"iso-2022-8bit", ""}, // XEmacs? +// {"iso-2022-8bit-lock", ""}, // XEmacs? +// {"iso-2022-8bit-lock-ss2", ""}, // XEmacs? +// {"iso-2022-8bit-ss2", ""}, // -- +// {"iso-2022-cjk", ""}, // -- +// {"iso-2022-cn", "ISO-2022-CN"}, // Emacs +// {"iso-2022-cn-ext", "ISO-2022-CN-EXT"},// Emacs +// {"iso-2022-int-1", ""}, // -- +// {"iso-2022-jp", "ISO-2022-JP"}, +// {"iso-2022-jp-1978-irv", "ISO-2022-JP"}, +// {"iso-2022-jp-2", "ISO-2022-JP-2"}, +// {"iso-2022-jp-3", "ISO-2022-JP-3"},// *, XEmacs? +// {"iso-2022-jp-3-compatible", ""}, // XEmacs? +// {"iso-2022-jp-3-strict", "ISO-2022-JP-3"},// *, XEmacs? +// {"iso-2022-kr", "ISO-2022-KR"}, +// {"iso-2022-lock", ""}, // XEmacs? +// {"iso-8859-10", "ISO-8859-10"}, // Emacs +// {"iso-8859-11", "ISO-8859-11"}, // *, Emacs +// {"iso-8859-14", "ISO-8859-14"}, // Emacs +// {"iso-8859-16", "ISO-8859-16"}, +// {"iso-8859-3", "ISO-8859-3"}, +// {"iso-8859-4", "ISO-8859-4"}, +// {"iso-8859-6", "ISO-8859-6"}, +// {"iso-8859-8", "ISO-8859-8"}, +// {"iso-8859-8-e", "ISO-8859-8"}, +// {"iso-8859-8-i", "ISO-8859-8"}, // Emacs +// {"iso-latin-10", "ISO-8859-16"}, // Emacs +// {"iso-latin-1-with-esc", ""}, // -- +// {"iso-latin-2-with-esc", ""}, // -- +// {"iso-latin-3", "ISO-8859-3"}, // Emacs +// {"iso-latin-3-with-esc", ""}, // -- +// {"iso-latin-4", "ISO-8859-4"}, // Emacs +// {"iso-latin-4-with-esc", ""}, // -- +// {"iso-latin-5-with-esc", ""}, // -- +// {"iso-latin-6", "ISO-8859-10"}, // Emacs +// {"iso-latin-8", "ISO-8859-14"}, // Emacs +// {"iso-safe", ""}, // -- +// {"japanese-iso-7bit-1978-irv", "ISO-2022-JP"}, // Emacs +// {"japanese-iso-8bit-with-esc", ""}, // -- +// {"japanese-shift-jis", "Shift_JIS"}, // Emacs +// {"japanese-shift-jisx0213", ""}, // XEmacs? +// {"jis7", "ISO-2022-JP"}, // Xemacs +// {"junet", "ISO-2022-JP"}, +// {"koi8-t", "KOI8-T"}, // *, Emacs +// {"koi8-u", "KOI8-U"}, // Emacs +// {"korean-iso-7bit-lock", "ISO-2022-KR"}, +// {"korean-iso-8bit-with-esc", ""}, // -- +// {"lao", ""}, // not covered +// {"lao-with-esc", ""}, // -- +// {"latin-10", "ISO-8859-16"}, // Emacs +// {"latin-3", "ISO-8859-3"}, // Emacs +// {"latin-4", "ISO-8859-4"}, // Emacs +// {"latin-6", "ISO-8859-10"}, // Emacs +// {"latin-8", "ISO-8859-14"}, // Emacs +// {"mac", ""}, // -- +// {"mac-roman", "MACINTOSH"}, // Emacs +// {"mik", ""}, // not covered +// {"next", "NEXTSTEP"}, // *, Emacs +// {"no-conversion", ""}, // -- +// {"old-jis", "ISO-2022-JP"}, +// {"pt154", "PT154"}, // Emacs +// {"raw-text", ""}, // -- +// {"ruscii", "cp1125"}, // *, Emacs +// {"shift-jis", "Shift_JIS"}, // XEmacs +// {"shift_jis", "Shift_JIS"}, +// {"shift_jisx0213", "Shift_JISX0213"},// *, XEmacs? +// {"sjis", "Shift_JIS"}, // Emacs +// {"tcvn", "TCVN"}, // *, Emacs +// {"tcvn-5712", "TCVN"}, // *, Emacs +// {"thai-tis620", "TIS-620"}, +// {"thai-tis620-with-esc", ""}, // -- +// {"th-tis620", "TIS-620"}, +// {"tibetan", ""}, // not covered +// {"tibetan-iso-8bit", ""}, // not covered +// {"tibetan-iso-8bit-with-esc", ""}, // -- +// {"tis-620", "TIS-620"}, +// {"tis620", "TIS-620"}, +// {"undecided", ""}, // -- +// {"unix", ""}, // -- +// {"utf-7", "UTF-7"}, // Emacs +// {"utf-7-safe", ""}, // XEmacs? +// {"utf-8-ws", "UTF-8"}, // XEmacs? +// {"vietnamese-tcvn", "TCVN"}, // *, Emacs +// {"vietnamese-viqr", "VIQR"}, // not covered +// {"vietnamese-viscii", "VISCII"}, +// {"vietnamese-vscii", ""}, // not covered +// {"viqr", "VIQR"}, // not covered +// {"viscii", "VISCII"}, +// {"vscii", ""}, // not covered +// {"windows-037", ""}, // not covered +// {"windows-10000", ""}, // not covered +// {"windows-10001", ""}, // not covered +// {"windows-10006", ""}, // not covered +// {"windows-10007", ""}, // not covered +// {"windows-10029", ""}, // not covered +// {"windows-10079", ""}, // not covered +// {"windows-10081", ""}, // not covered +// {"windows-1026", ""}, // not covered +// {"windows-1200", ""}, // not covered +// {"windows-1250", "windows-1250"}, +// {"windows-1251", "windows-1251"}, +// {"windows-1252", "windows-1252"}, +// {"windows-1253", "windows-1253"}, +// {"windows-1254", "windows-1254"}, +// {"windows-1255", "windows-1255"}, +// {"windows-1256", "windows-1256"}, +// {"windows-1257", "windows-1257"}, +// {"windows-1258", "windows-1258"}, +// {"windows-1361", "cp1361"}, // *, XEmacs +// {"windows-437", "cp437"}, // XEmacs +// {"windows-500", ""}, // not covered +// {"windows-708", ""}, // not covered +// {"windows-709", ""}, // not covered +// {"windows-710", ""}, // not covered +// {"windows-720", ""}, // not covered +// {"windows-737", "cp737"}, // *, XEmacs +// {"windows-775", "cp775"}, // XEmacs +// {"windows-850", "cp850"}, // XEmacs +// {"windows-852", "cp852"}, // XEmacs +// {"windows-855", "cp855"}, // XEmacs +// {"windows-857", "cp857"}, // XEmacs +// {"windows-860", "cp860"}, // XEmacs +// {"windows-861", "cp861"}, // XEmacs +// {"windows-862", "cp862"}, // XEmacs +// {"windows-863", "cp863"}, // XEmacs +// {"windows-864", "cp864"}, // XEmacs +// {"windows-865", "cp865"}, // XEmacs +// {"windows-866", "cp866"}, // XEmacs +// {"windows-869", "cp869"}, // XEmacs +// {"windows-874", "cp874"}, // XEmacs +// {"windows-875", ""}, // not covered +// {"windows-932", "cp932"}, // *, XEmacs +// {"windows-936", "cp936"}, // XEmacs +// {"windows-949", "cp949"}, // *, XEmacs +// {"windows-950", "cp950"}, // *, XEmacs +// {"x-ctext", ""}, // -- +// {"x-ctext-with-extensions", ""}, // -- + + {NULL, NULL}, +}; + +// --------------------------------------------------------- +// Convert encoding name from emacs to mime. +// --------------------------------------------------------- +char * +emacs2mime(char *emacs_enc) +{ + int emacs_enc_len = strlen(emacs_enc); + if (emacs_enc_len > 4 + && !strcasecmp(emacs_enc + emacs_enc_len - 4, "-dos")) + emacs_enc[emacs_enc_len - 4] = 0; + if (emacs_enc_len > 4 + && !strcasecmp(emacs_enc + emacs_enc_len - 4, "-mac")) + emacs_enc[emacs_enc_len - 4] = 0; + if (emacs_enc_len > 5 + && !strcasecmp(emacs_enc + emacs_enc_len - 5, "-unix")) + emacs_enc[emacs_enc_len - 5] = 0; + for (const conversion *table = emacs_to_mime; table->from; table++) + if (!strcasecmp(emacs_enc, table->from)) + return (char *)table->to; + return emacs_enc; +} + +// --------------------------------------------------------- +// Print out Unicode entity if value is greater than 0x7F. +// --------------------------------------------------------- +inline void +unicode_entity(int u) +{ + if (u < 0x80) + putchar(u); + else { + // Handle no-break space and soft hyphen specially--they are input + // characters only, not glyphs. See groff_char(7). + if (u == 0xA0) { + putchar('\\'); + putchar('~'); + } + else if (u == 0xAD) { + putchar('\\'); + putchar('%'); + } + else + printf("\\[u%04X]", u); + } +} + +// --------------------------------------------------------- +// Conversion functions. All functions take 'data', which +// normally holds the first two lines, and a file pointer. +// --------------------------------------------------------- + +// Conversion from ISO-8859-1 (aka Latin-1) to Unicode. +void +conversion_latin1(FILE *fp, const string &data) +{ + int len = data.length(); + const unsigned char *ptr = (const unsigned char *)data.contents(); + for (int i = 0; i < len; i++) + unicode_entity(ptr[i]); + int c = -1; + while ((c = getc(fp)) != EOF) + unicode_entity(c); +} + +// A future version of groff shall support UTF-8 natively. +// In this case, the UTF-8 stuff here in this file will be +// moved to the troff program. + +struct utf8 { + FILE *fp; + unsigned char s[6]; + enum { + FIRST = 0, + SECOND, + THIRD, + FOURTH, + FIFTH, + SIXTH + } byte; + int expected_byte_count; + bool emit_invalid_utf8_warning; + bool emit_incomplete_utf8_warning; + utf8(FILE *); + ~utf8(); + void add(unsigned char); + void invalid(); + void incomplete(); +}; + +utf8::utf8(FILE *f) : fp(f), byte(FIRST), expected_byte_count(1), + emit_invalid_utf8_warning(true), + emit_incomplete_utf8_warning(true) +{ + // empty +} + +utf8::~utf8() +{ + if (byte != FIRST) + incomplete(); +} + +inline void +utf8::add(unsigned char c) +{ + s[byte] = c; + if (byte == FIRST) { + if (c < 0x80) + unicode_entity(c); + else if (c < 0xC0) + invalid(); + else if (c < 0xE0) { + expected_byte_count = 2; + byte = SECOND; + } + else if (c < 0xF0) { + expected_byte_count = 3; + byte = SECOND; + } + else if (c < 0xF8) { + expected_byte_count = 4; + byte = SECOND; + } + else if (c < 0xFC) { + expected_byte_count = 5; + byte = SECOND; + } + else if (c < 0xFE) { + expected_byte_count = 6; + byte = SECOND; + } + else + invalid(); + return; + } + if (c < 0x80 || c > 0xBF) { + incomplete(); + add(c); + return; + } + switch (byte) { + case FIRST: + // can't happen + break; + case SECOND: + if (expected_byte_count == 2) { + if (s[0] < 0xC2) + invalid(); + else + unicode_entity(((s[0] & 0x1F) << 6) + | (s[1] ^ 0x80)); + byte = FIRST; + } + else + byte = THIRD; + break; + case THIRD: + if (expected_byte_count == 3) { + if (!(s[0] >= 0xE1 || s[1] >= 0xA0)) + invalid(); + else + unicode_entity(((s[0] & 0x1F) << 12) + | ((s[1] ^ 0x80) << 6) + | (s[2] ^ 0x80)); + byte = FIRST; + } + else + byte = FOURTH; + break; + case FOURTH: + // We reject everything greater than 0x10FFFF. + if (expected_byte_count == 4) { + if (!((s[0] >= 0xF1 || s[1] >= 0x90) + && (s[0] < 0xF4 || (s[0] == 0xF4 && s[1] < 0x90)))) + invalid(); + else + unicode_entity(((s[0] & 0x07) << 18) + | ((s[1] ^ 0x80) << 12) + | ((s[2] ^ 0x80) << 6) + | (s[3] ^ 0x80)); + byte = FIRST; + } + else + byte = FIFTH; + break; + case FIFTH: + if (expected_byte_count == 5) { + invalid(); + byte = FIRST; + } + else + byte = SIXTH; + break; + case SIXTH: + invalid(); + byte = FIRST; + break; + } +} + +// We use fprintf(stderr) instead of libgroff's debug() because we need +// to output longs, and libgroff's errprint() doesn't support that. + +void +utf8::invalid() +{ + if (is_debugging && emit_invalid_utf8_warning) { + fprintf(stderr, " invalid UTF-8 sequence(s) in input stream:" + " replacing each such sequence with 0xFFFD\n"); + emit_invalid_utf8_warning = false; + } + unicode_entity(0xFFFD); + byte = FIRST; +} + +void +utf8::incomplete() +{ + if (is_debugging && emit_incomplete_utf8_warning) { + fprintf(stderr, " incomplete UTF-8 sequence(s) in input stream:" + " replacing each such sequence with 0xFFFD\n"); + emit_incomplete_utf8_warning = false; + } + unicode_entity(0xFFFD); + byte = FIRST; +} + +// Conversion from UTF-8 to Unicode. +void +conversion_utf8(FILE *fp, const string &data) +{ + utf8 u(fp); + int len = data.length(); + const unsigned char *ptr = (const unsigned char *)data.contents(); + for (int i = 0; i < len; i++) + u.add(ptr[i]); + int c = -1; + while ((c = getc(fp)) != EOF) + u.add(c); + return; +} + +// Conversion from cp1047 (EBCDIC) to UTF-8. +void +conversion_cp1047(FILE *fp, const string &data) +{ + static unsigned char cp1047[] = { + 0x00, 0x01, 0x02, 0x03, 0x9C, 0x09, 0x86, 0x7F, // 0x00 + 0x97, 0x8D, 0x8E, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x9D, 0x85, 0x08, 0x87, // 0x10 + 0x18, 0x19, 0x92, 0x8F, 0x1C, 0x1D, 0x1E, 0x1F, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x0A, 0x17, 0x1B, // 0x20 + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x05, 0x06, 0x07, + 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, // 0x30 + 0x98, 0x99, 0x9A, 0x9B, 0x14, 0x15, 0x9E, 0x1A, + 0x20, 0xA0, 0xE2, 0xE4, 0xE0, 0xE1, 0xE3, 0xE5, // 0x40 + 0xE7, 0xF1, 0xA2, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, + 0x26, 0xE9, 0xEA, 0xEB, 0xE8, 0xED, 0xEE, 0xEF, // 0x50 + 0xEC, 0xDF, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E, + 0x2D, 0x2F, 0xC2, 0xC4, 0xC0, 0xC1, 0xC3, 0xC5, // 0x60 + 0xC7, 0xD1, 0xA6, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, + 0xF8, 0xC9, 0xCA, 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, // 0x70 + 0xCC, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, + 0xD8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, // 0x80 + 0x68, 0x69, 0xAB, 0xBB, 0xF0, 0xFD, 0xFE, 0xB1, + 0xB0, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, // 0x90 + 0x71, 0x72, 0xAA, 0xBA, 0xE6, 0xB8, 0xC6, 0xA4, + 0xB5, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, // 0xA0 + 0x79, 0x7A, 0xA1, 0xBF, 0xD0, 0x5B, 0xDE, 0xAE, + 0xAC, 0xA3, 0xA5, 0xB7, 0xA9, 0xA7, 0xB6, 0xBC, // 0xB0 + 0xBD, 0xBE, 0xDD, 0xA8, 0xAF, 0x5D, 0xB4, 0xD7, + 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, // 0xC0 + 0x48, 0x49, 0xAD, 0xF4, 0xF6, 0xF2, 0xF3, 0xF5, + 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, // 0xD0 + 0x51, 0x52, 0xB9, 0xFB, 0xFC, 0xF9, 0xFA, 0xFF, + 0x5C, 0xF7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, // 0xE0 + 0x59, 0x5A, 0xB2, 0xD4, 0xD6, 0xD2, 0xD3, 0xD5, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // 0xF0 + 0x38, 0x39, 0xB3, 0xDB, 0xDC, 0xD9, 0xDA, 0x9F, + }; + int len = data.length(); + const unsigned char *ptr = (const unsigned char *)data.contents(); + for (int i = 0; i < len; i++) + unicode_entity(cp1047[ptr[i]]); + int c = -1; + while ((c = getc(fp)) != EOF) + unicode_entity(cp1047[c]); +} + +// Locale-sensible conversion. +#if HAVE_ICONV +void +conversion_iconv(FILE *fp, const string &data, char *enc) +{ + iconv_t handle = iconv_open(UNICODE, enc); + if (handle == (iconv_t)-1) { + if (errno == EINVAL) { + error("encoding system '%1' not supported by iconv()", enc); + return; + } + fatal("iconv_open failed"); + } + char inbuf[BUFSIZ]; + int outbuf[BUFSIZ]; + char *outptr = (char *)outbuf; + size_t outbytes_left = BUFSIZ * sizeof (int); + // Handle 'data'. + char *inptr = (char *)data.contents(); + size_t inbytes_left = data.length(); + char *limit; + while (inbytes_left > 0) { + size_t status = iconv(handle, + (ICONV_CONST char **)&inptr, &inbytes_left, + &outptr, &outbytes_left); + if (status == (size_t)-1) { + if (errno == EILSEQ) { + // Invalid byte sequence. XXX + inptr++; + inbytes_left--; + } + else if (errno == E2BIG) { + // Output buffer is full. + limit = (char *)outbuf + BUFSIZ * sizeof (int) - outbytes_left; + for (int *ptr = outbuf; (char *)ptr < limit; ptr++) + unicode_entity(*ptr); + memmove(outbuf, outptr, outbytes_left); + outptr = (char *)outbuf + outbytes_left; + outbytes_left = BUFSIZ * sizeof (int) - outbytes_left; + } + else if (errno == EINVAL) { + // 'data' ends with partial input sequence. + memcpy(inbuf, inptr, inbytes_left); + break; + } + } + } + // Handle 'fp' and switch to 'inbuf'. + size_t read_bytes; + char *read_start = inbuf + inbytes_left; + while ((read_bytes = fread(read_start, 1, BUFSIZ - inbytes_left, fp)) > 0) { + inptr = inbuf; + inbytes_left += read_bytes; + while (inbytes_left > 0) { + size_t status = iconv(handle, + (ICONV_CONST char **)&inptr, &inbytes_left, + &outptr, &outbytes_left); + if (status == (size_t)-1) { + if (errno == EILSEQ) { + // Invalid byte sequence. XXX + inptr++; + inbytes_left--; + } + else if (errno == E2BIG) { + // Output buffer is full. + limit = (char *)outbuf + BUFSIZ * sizeof (int) - outbytes_left; + for (int *ptr = outbuf; (char *)ptr < limit; ptr++) + unicode_entity(*ptr); + memmove(outbuf, outptr, outbytes_left); + outptr = (char *)outbuf + outbytes_left; + outbytes_left = BUFSIZ * sizeof (int) - outbytes_left; + } + else if (errno == EINVAL) { + // 'inbuf' ends with partial input sequence. + memmove(inbuf, inptr, inbytes_left); + break; + } + } + } + read_start = inbuf + inbytes_left; + } + iconv_close(handle); + // XXX use ferror? + limit = (char *)outbuf + BUFSIZ * sizeof (int) - outbytes_left; + for (int *ptr = outbuf; (char *)ptr < limit; ptr++) + unicode_entity(*ptr); +} +#endif /* HAVE_ICONV */ + +// --------------------------------------------------------- +// Handle Byte Order Mark. +// +// Since we have a chicken-and-egg problem it's necessary +// to handle the BOM manually if it is in the data stream. +// As documented in the Unicode book it is very unlikely +// that any normal text file (regardless of the encoding) +// starts with the bytes which represent a BOM. +// +// Return the BOM in string 'BOM'; 'data' then starts with +// the byte after the BOM. This function reads (at most) +// four bytes from the data stream. +// +// Return encoding if a BOM is found, NULL otherwise. +// --------------------------------------------------------- +const char * +get_BOM(FILE *fp, string &BOM, string &data) +{ + // The BOM is U+FEFF. We have thus the following possible + // representations. + // + // UTF-8: 0xEFBBBF + // UTF-16: 0xFEFF or 0xFFFE + // UTF-32: 0x0000FEFF or 0xFFFE0000 + static struct { + int len; + const char *str; + const char *name; + } BOM_table[] = { + {4, "\x00\x00\xFE\xFF", "UTF-32"}, + {4, "\xFF\xFE\x00\x00", "UTF-32"}, + {3, "\xEF\xBB\xBF", "UTF-8"}, + {2, "\xFE\xFF", "UTF-16"}, + {2, "\xFF\xFE", "UTF-16"}, + }; + const int BOM_table_len = sizeof (BOM_table) / sizeof (BOM_table[0]); + char BOM_string[4]; + const char *retval = NULL; + int len; + for (len = 0; len < 4; len++) { + int c = getc(fp); + if (c == EOF) + break; + BOM_string[len] = char(c); + } + int i; + for (i = 0; i < BOM_table_len; i++) { + if (BOM_table[i].len <= len + && memcmp(BOM_string, BOM_table[i].str, BOM_table[i].len) == 0) + break; + } + int j = 0; + if (i < BOM_table_len) { + for (; j < BOM_table[i].len; j++) + BOM += BOM_string[j]; + retval = BOM_table[i].name; + } + for (; j < len; j++) + data += BOM_string[j]; + return retval; +} + +// --------------------------------------------------------- +// Get first two lines from input stream. +// +// Return string (allocated with 'new') without zero bytes +// or NULL in case no coding tag can occur in the data +// (which is stored unmodified in 'data'). +// --------------------------------------------------------- +char * +get_tag_lines(FILE *fp, string &data) +{ + int newline_count = 0; + int c, prev = -1; + // Handle CR, LF, and CRLF as line separators. + for (int i = 0; i < data.length(); i++) { + c = data[i]; + if (c == '\n' || c == '\r') + newline_count++; + if (c == '\n' && prev == '\r') + newline_count--; + prev = c; + } + if (newline_count > 1) + return NULL; + bool emit_warning = true; + for (int lines = newline_count; lines < 2; lines++) { + while ((c = getc(fp)) != EOF) { + if (c == '\0' && is_debugging && emit_warning) { + warning("null byte(s) found in input stream:" + " search for coding tag might return false result"); + emit_warning = false; + } + data += char(c); + if (c == '\n' || c == '\r') + break; + } + // Handle CR, LF, and CRLF as line separators. + if (c == '\r') { + c = getc(fp); + if (c != EOF && c != '\n') + ungetc(c, fp); + else + data += char(c); + } + } + return data.extract(); +} + +// --------------------------------------------------------- +// Check whether C string starts with a comment. +// +// Return 1 if true, 0 otherwise. +// --------------------------------------------------------- +int +is_comment_line(char *s) +{ + if (!s || !*s) + return 0; + if (*s == '.' || *s == '\'') + { + s++; + while (*s == ' ' || *s == '\t') + s++; + if (*s && *s == '\\') + { + s++; + if (*s == '"' || *s == '#') + return 1; + } + } + else if (*s == '\\') + { + s++; + if (*s == '#') + return 1; + } + return 0; +} + +// --------------------------------------------------------- +// Get a value/variable pair from a local variables list +// in a C string which look like this: +// +// : ; : ; ... +// +// Leading and trailing blanks are ignored. There might be +// more than one blank after ':' and ';'. +// +// Return position of next value/variable pair or NULL if +// at end of data. +// --------------------------------------------------------- +char * +get_variable_value_pair(char *d1, char **variable, char **value) +{ + static char var[MAX_VAR_LEN], val[MAX_VAR_LEN]; + *variable = var; + *value = val; + while (*d1 == ' ' || *d1 == '\t') + d1++; + // Get variable. + int l = 0; + while (l < MAX_VAR_LEN - 1 && *d1 && !strchr(";: \t", *d1)) + var[l++] = *(d1++); + var[l] = 0; + // Skip everything until ':', ';', or end of data. + while (*d1 && *d1 != ':' && *d1 != ';') + d1++; + val[0] = 0; + if (!*d1) + return NULL; + if (*d1 == ';') + return d1 + 1; + d1++; + while (*d1 == ' ' || *d1 == '\t') + d1++; + // Get value. + l = 0; + while (l < MAX_VAR_LEN - 1 && *d1 && !strchr("; \t", *d1)) + val[l++] = *(d1++); + val[l] = 0; + // Skip everything until ';' or end of data. + while (*d1 && *d1 != ';') + d1++; + if (*d1 == ';') + return d1 + 1; + return NULL; +} + +// --------------------------------------------------------- +// Check coding tag in the read buffer. +// +// We search for the following line: +// +// ... -*--*- +// +// ('...' might be anything). +// +// can be one of the following syntax forms at the +// beginning of the line: +// +// .\" .\# '\" '\# \# +// +// There can be whitespace after the leading '.' or "'". +// +// The local variables list must occur within the first +// comment block at the very beginning of the data stream. +// +// Within the , we search for +// +// coding: +// +// which specifies the coding system used for the data +// stream. +// +// Return if found, NULL otherwise. +// +// Note that null bytes in the data are skipped before applying +// the algorithm. This should work even with files encoded as +// UTF-16 or UTF-32 (or its siblings) in most cases. +// --------------------------------------------------------- +char * +check_coding_tag(FILE *fp, string &data) +{ + char *inbuf = get_tag_lines(fp, data); + char *lineend; + for (char *p = inbuf; is_comment_line(p); p = lineend + 1) { + if ((lineend = strchr(p, '\n')) == NULL) + break; + *lineend = 0; // switch temporarily to '\0' + char *d1 = strstr(p, "-*-"); + char *d2 = 0; + if (d1) + d2 = strstr(d1 + 3, "-*-"); + *lineend = '\n'; // restore newline + if (!d1 || !d2) + continue; + *d2 = 0; // switch temporarily to '\0' + d1 += 3; + while (d1) { + char *variable, *value; + d1 = get_variable_value_pair(d1, &variable, &value); + if (!strcasecmp(variable, "coding")) { + *d2 = '-'; // restore '-' + free(inbuf); + return value; + } + } + *d2 = '-'; // restore '-' + } + free(inbuf); + return NULL; +} + +char * +detect_file_encoding(FILE *fp) +{ +#ifdef HAVE_UCHARDET + uchardet_t ud = NULL; + struct stat stat_buf; + size_t len, read_bytes; + char *data = NULL; + int res, current_position; + const char *charset; + char *ret = NULL; + + current_position = ftell(fp); + /* Due to BOM and tag detection, we are not at the beginning of the + file. */ + rewind(fp); + if (fstat(fileno(fp), &stat_buf) != 0) { + error("fstat: %1", strerror(errno)); + goto end; + } + len = stat_buf.st_size; + if (is_debugging) + fprintf(stderr, " len: %lu\n", (unsigned long)len); + if (len == 0) + goto end; + data = (char *)calloc(len, 1); + read_bytes = fread(data, 1, len, fp); + if (read_bytes == 0) { + error("fread: %1", strerror(errno)); + goto end; + } + /* We rewind back to the original position */ + if (fseek(fp, current_position, SEEK_SET) != 0) { + fatal("fseek: %1", strerror(errno)); + goto end; + } + ud = uchardet_new(); + res = uchardet_handle_data(ud, data, len); + if (res != 0) { + debug(" uchardet_handle_data: error %1\n", res); + goto end; + } + if (is_debugging) + fprintf(stderr, " uchardet read: %lu bytes\n", + (unsigned long)read_bytes); + uchardet_data_end(ud); + charset = uchardet_get_charset(ud); + if (is_debugging) { + if (charset) + fprintf(stderr, " charset: %s\n", charset); + else + fprintf(stderr, " charset is NULL\n"); + } + /* uchardet 0.0.1 could return an empty string instead of NULL */ + if (charset && *charset) { + ret = (char *)malloc(strlen(charset) + 1); + strcpy(ret, charset); + } + +end: + if (ud) + uchardet_delete(ud); + if (data) + free(data); + + return ret; +#else /* not HAVE_UCHARDET */ + return NULL; +#endif /* not HAVE_UCHARDET */ +} + +// --------------------------------------------------------- +// Handle an input file. If `filename` is "-", read the +// standard input stream. +// +// Return 1 on success, 0 otherwise. +// --------------------------------------------------------- +int +do_file(const char *filename) +{ + FILE *fp; + string BOM, data; + bool is_seekable = false; + string reported_filename; + + // TODO: Consider moving some of this into a `quoted_file_name` + // function in libgroff. + if (strcmp(filename, "-") == 0) { + fp = stdin; + reported_filename = string(""); + } + else { + fp = fopen(filename, FOPEN_RB); + reported_filename = "'" + string(filename) + "'"; + } + if (!fp) { + error("can't open %1: %2", reported_filename.contents(), + strerror(errno)); + return 0; + } + if (is_debugging) + fprintf(stderr, "processing %s\n", reported_filename.contents()); + if (fseek(fp, 0L, SEEK_SET) == 0) + is_seekable = true; + else { + SET_BINARY(fileno(fp)); + if (is_debugging) + fprintf(stderr, " stream is not seekable: %s\n", + strerror(errno)); + } + const char *BOM_encoding = get_BOM(fp, BOM, data); + // Determine the encoding. + char *encoding; + int must_free_encoding = 0; + if (user_encoding[0]) { + if (is_debugging) { + fprintf(stderr, " user-specified encoding '%s', " + "no search for coding tag\n", + user_encoding); + if (BOM_encoding && strcmp(BOM_encoding, user_encoding)) + fprintf(stderr, " but BOM in data stream implies encoding '%s'!\n", + BOM_encoding); + } + encoding = (char *)user_encoding; + } + else if (BOM_encoding) { + if (is_debugging) + fprintf(stderr, " found BOM, no search for coding tag\n"); + encoding = (char *)BOM_encoding; + } + else { + // 'check_coding_tag' returns a pointer to a static array (or NULL). + char *file_encoding = check_coding_tag(fp, data); + if (!file_encoding) { + if (is_debugging) + fprintf(stderr, " no coding tag\n"); + if (is_seekable) + file_encoding = detect_file_encoding(fp); + if (!file_encoding) { + if (is_debugging) + fprintf(stderr, " could not detect encoding with uchardet\n"); + file_encoding = fallback_encoding; + } + else + must_free_encoding = 1; + } + else + if (is_debugging) + fprintf(stderr, " coding tag: '%s'\n", file_encoding); + encoding = file_encoding; + } + strncpy(encoding_string, encoding, MAX_VAR_LEN - 1); + encoding_string[MAX_VAR_LEN - 1] = 0; + if (must_free_encoding) + free(encoding); + encoding = encoding_string; + // Translate from MIME & Emacs encoding names to locale encoding names. + encoding = emacs2mime(encoding_string); + if (encoding[0] == '\0') { + error("encoding '%1' not supported, not a portable encoding", + encoding_string); + return 0; + } + if (is_debugging) + fprintf(stderr, " encoding used: '%s'\n", encoding); + if (!raw_flag) { + string fn(filename); + fn += '\0'; + normalize_for_lf(fn); + printf(".lf 1 %s\n", fn.contents()); + } + int success = 1; + // Call converter (converters write to stdout). + if (!strcasecmp(encoding, "ISO-8859-1")) + conversion_latin1(fp, BOM + data); + else if (!strcasecmp(encoding, "UTF-8")) + conversion_utf8(fp, data); + else if (!strcasecmp(encoding, "cp1047")) + conversion_cp1047(fp, BOM + data); + else { +#if HAVE_ICONV + conversion_iconv(fp, BOM + data, encoding); +#else + error("encoding system '%1' not supported", encoding); + success = 0; +#endif /* HAVE_ICONV */ + } + if (fp != stdin) + fclose(fp); + return success; +} + +// --------------------------------------------------------- +// Print usage. +// --------------------------------------------------------- +void +usage(FILE *stream) +{ + fprintf(stream, +"usage: %s [-dr] [-D fallback-encoding] [-e encoding] [file ...]\n" +"usage: %s {-v | --version}\n" +"usage: %s {-h | --help}\n", + program_name, program_name, program_name); + if (stdout == stream) { + fprintf(stream, +"\n" +"Read each file, convert its encoded characters to a form GNU" +" troff(1)\n" +"can interpret, and send the result to the standard output stream.\n" +"The default fallback encoding is '%s'. See the preconv(1) manual" +" page.\n", + fallback_encoding); + exit(EXIT_SUCCESS); + } +} + +// --------------------------------------------------------- +// Main routine. +// --------------------------------------------------------- +int +main(int argc, char **argv) +{ + program_name = argv[0]; + // Determine the fallback encoding. This must be done before + // getopt() is called since the usage message shows the fallback + // encoding. + setlocale(LC_ALL, ""); + char *locale = getlocale(LC_CTYPE); + if (!locale || !strcmp(locale, "C") || !strcmp(locale, "POSIX")) + strcpy(fallback_encoding, "latin1"); + else { + strncpy(fallback_encoding, locale_charset(), MAX_VAR_LEN - 1); + fallback_encoding[MAX_VAR_LEN - 1] = 0; + } + + program_name = argv[0]; + int opt; + static const struct option long_options[] = { + { "help", no_argument, 0, 'h' }, + { "version", no_argument, 0, 'v' }, + { NULL, 0, 0, 0 } + }; + // Parse the command-line options. + while ((opt = getopt_long(argc, argv, + "dD:e:hrv", long_options, NULL)) != EOF) + switch (opt) { + case 'v': + printf("GNU preconv (groff) version %s %s iconv support and %s uchardet support\n", + Version_string, +#ifdef HAVE_ICONV + "with", +#else + "without", +#endif /* HAVE_ICONV */ +#ifdef HAVE_UCHARDET + "with" +#else + "without" +#endif /* HAVE_UCHARDET */ + ); + exit(0); + break; + case 'd': + is_debugging = true; + break; + case 'e': + if (optarg) { + strncpy(user_encoding, optarg, MAX_VAR_LEN - 1); + user_encoding[MAX_VAR_LEN - 1] = 0; + } + else + user_encoding[0] = 0; + break; + case 'D': + if (optarg) { + strncpy(fallback_encoding, optarg, MAX_VAR_LEN - 1); + fallback_encoding[MAX_VAR_LEN - 1] = 0; + } + break; + case 'r': + raw_flag = 1; + break; + case 'h': + usage(stdout); + break; + case '?': + usage(stderr); + exit(1); + break; + default: + assert(0); + } + int nbad = 0; + if (is_debugging) + fprintf(stderr, "fallback encoding: '%s'\n", fallback_encoding); + if (optind >= argc) + nbad += !do_file("-"); + else + for (int i = optind; i < argc; i++) + nbad += !do_file(argv[i]); + if (ferror(stdout) || fflush(stdout) < 0) + fatal("output error"); + return nbad != 0; +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/preconv/tests/do-not-seek-the-unseekable.sh b/src/preproc/preconv/tests/do-not-seek-the-unseekable.sh new file mode 100755 index 0000000..2b1142d --- /dev/null +++ b/src/preproc/preconv/tests/do-not-seek-the-unseekable.sh @@ -0,0 +1,59 @@ +#!/bin/sh +# +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +set -e + +preconv="${abs_top_builddir:-.}/preconv" + +fail= + +wail () { + echo FAILED >&2 + fail=YES +} + +# Scrape debugging output to see if we're skipping unseekable streams. +# This is fragile, but we don't want to lock the language of diagnostic +# messages (especially debugging ones). If this test fails, check the +# text of the command's debugging output for a mismatch before +# investigating deeper problems. + +echo "testing seekability of file operand '-'" >&2 +output=$(printf '' | "$preconv" -d - 2>&1) +echo "$output" | grep -q "stream is not seekable" || wail + +# /dev/stdin might not exist in a chroot. Or, if it's not (a symbolic +# link to) a character special device, the next test will not be valid, +# as when using GNU Make's `-j` option. +# +# Similarly, we must have a controlling terminal. +test -z "$fail" +echo "skipping if /dev/stdin is not a character device" >&2 +test -c /dev/stdin || exit 77 # skip +echo "skipping if there is no controlling terminal" >&2 +test "$(tty)" != "not a tty" || exit 77 # skip + +echo "testing seekability of standard input stream" >&2 +output=$(printf '' | "$preconv" -d /dev/stdin 2>&1) +echo "$output" | grep -q "stream is not seekable" || wail + +test -z "$fail" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/preproc/preconv/tests/smoke-test.sh b/src/preproc/preconv/tests/smoke-test.sh new file mode 100755 index 0000000..4131416 --- /dev/null +++ b/src/preproc/preconv/tests/smoke-test.sh @@ -0,0 +1,88 @@ +#!/bin/sh +# +# Copyright (C) 2020 Free Software Foundation, Inc. +# +# This file 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 . +# + +# Ensure a predictable character encoding. +export LC_ALL=C + +set -e + +preconv="${abs_top_builddir:-.}/preconv" + +echo "testing -e flag override of BOM detection" >&2 +printf '\376\377\0\100\0\n' \ + | "$preconv" -d -e euc-kr 2>&1 > /dev/null \ + | grep -q "no search for coding tag" + +echo "testing detection of UTF-32BE BOM" >&2 +printf '\0\0\376\377\0\0\0\100\0\0\0\n' \ + | "$preconv" -d 2>&1 > /dev/null \ + | grep -q "found BOM" + +echo "testing detection of UTF-32LE BOM" >&2 +printf '\377\376\0\0\100\0\0\0\n\0\0\0' \ + | "$preconv" -d 2>&1 > /dev/null \ + | grep -q "found BOM" + +echo "testing detection of UTF-16BE BOM" >&2 +printf '\376\377\0\100\0\n' \ + | "$preconv" -d 2>&1 > /dev/null \ + | grep -q "found BOM" + +echo "testing detection of UTF-16LE BOM" >&2 +printf '\377\376\100\0\n\0' \ + | "$preconv" -d 2>&1 > /dev/null \ + | grep -q "found BOM" + +echo "testing detection of UTF-8 BOM" >&2 +printf '\357\273\277@\n' \ + | "$preconv" -d 2>&1 > /dev/null \ + | grep -q "found BOM" + +# We do not find a coding tag on piped input because it isn't seekable. +echo "testing detection of Emacs coding tag in piped input" >&2 +printf '.\\" -*- coding: euc-kr; -*-\\n' \ + | "$preconv" -d 2>&1 >/dev/null \ + | grep -q "no coding tag" + +# We need uchardet to work to get past this point. +echo "testing uchardet detection of encoding" >&2 +"$preconv" -v | grep -q 'with uchardet support' || exit 77 + +# Instead of using temporary files, which in all fastidiousness means +# cleaning them up even if we're interrupted, which in turn means +# setting up signal handlers, we use files in the build tree. + +doc=contrib/mm/groff_mmse.7 +echo "testing uchardet detection on Latin-1 document $doc" >&2 +"$preconv" -d -D us-ascii 2>&1 >/dev/null $doc \ + | grep -q 'charset: ISO-8859-1' + +# uchardet can't seek on a pipe either. +echo "testing uchardet detection on pipe (expect fallback to -D)" >&2 +printf 'Eat at the caf\351.\n' \ + | "$preconv" -d -D euc-kr 2>&1 > /dev/null \ + | grep -q "encoding used: 'EUC-KR'" + +# Fall back to the locale. preconv assumes Latin-1 for C instead of +# US-ASCII. +echo "testing fallback to locale setting in environment" >&2 +printf 'Eat at the caf\351.\n' \ + | "$preconv" -d 2>&1 > /dev/null \ + | grep -q "encoding used: 'ISO-8859-1'" diff --git a/src/preproc/refer/TODO b/src/preproc/refer/TODO new file mode 100644 index 0000000..36f4508 --- /dev/null +++ b/src/preproc/refer/TODO @@ -0,0 +1,124 @@ +inline references + +Some sort of macro/subroutine that can cover several references. + +move-punctuation should ignore multiple punctuation characters. + +Make the index files machine independent. + +Allow search keys to be negated (with !) to indicate that the +reference should not contain the key. Ignore negated keys during +indexed searching. + +Provide an option with lkbib and lookbib that prints the location +(filename, position) of each reference. Need to map filename_id's +back to filenames. + +Rename join-authors to join-fields. Have a separate label-join-fields +command used by @ and #. + +Have some sort of quantifier: e.g., $.n#A means execute '$.n' for each +instance of an A field, setting $ to that field, and then join the +results using the join-authors command. + +no-text-in-bracket command which says not to allow post_text and +pre_text when the [] flags has been given. Useful for superscripted +footnotes. + +Make it possible to translate - to \(en in page ranges. + +Trim eign a bit. + +In indexed searching discard all numeric keys except dates. + +Allow '\ ' to separate article from first word. + +%also + +Option automatically to supply [] flags in every reference. + +See if we can avoid requiring a comma before jr. and so on +in find_last_name(). + +Cache sortified authors in authors string during tentative evaluation of +label specification. + +Possibly don't allow * and % expressions in the first part of ?:, | or +& expressions. + +Handle better the case where <> occurs inside functions and in the +first operand of ~. Or perhaps implement <> using some magic character +in the string. + +Should special treatment be given to lines beginning with . in +references? (Unix refer seems to treat them like '%'). + +Add global flag to control whether all files should be stat-ed after +loading, and whether they should be stat-ed before each search. +Perhaps make this dependent on the number of files there are. + +Option to truncate keys to truncate_len in linear searching. + +Allow multiple -f options in indxbib. + +In indxbib, possibly store common words rather than common words +filename. In this case store only words that are actually present in +the file. + +Perhaps we should put out an obnoxious copyright message when lookbib +starts up. + +Provide an option that writes a file containing just the references +actually used. Useful if you want to distribute a document. + +Have a magic token such that +%A +will print as though it were +%A +but sort as though it were +%A +Do we need this if we can specify author alternatives for sorting? +No, provided we have separate alternatives for @. + +In consider_authors when last names are ambiguous we might be able to +use just the first name and not Jr. bit. Or we might be able to +abbreviate the author. + +It ought to be possible to specify an alternative field to sort on +instead of date. (ie if there's a field giving the type of document -- +these references should sort after any years) + +Provide a way to execute a command using a command-line option. + +Option to set the label-spec as a command-line option (-L). + +Command to specify which fields can occur multiple times: +multiple AE + +Command to specify how various fields sort: +aort-as-name A +sort-as-date D +sort-as-title T +sort-as-other O + +Command to specify which fields are author fields: +# if we don't have A use field Q +author-fields AQ + +Commands to set properties of tokens. +sortify-token \(ae ae +uppercase-token \[ae] \[AE] + +Command to set the names of months: +months january february march april may ... + +Perhaps provide some sort of macro capability: +# perhaps a macro capability +defmacro foo +annotation-field $1 +endef + +Command to control strings used in capitalization +capitalize-start \s+2 +capitalize-end \s-2 +(perhaps make these arguments to the capitalize command.) diff --git a/src/preproc/refer/command.cpp b/src/preproc/refer/command.cpp new file mode 100644 index 0000000..b49e2be --- /dev/null +++ b/src/preproc/refer/command.cpp @@ -0,0 +1,814 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "refer.h" +#include "refid.h" +#include "search.h" +#include "command.h" + +cset cs_field_name = csalpha; + +class input_item { + input_item *next; + char *filename; + int first_lineno; + string buffer; + const char *ptr; + const char *end; +public: + input_item(string &, const char *, int = 1); + ~input_item(); + int get_char(); + int peek_char(); + void skip_char(); + void get_location(const char **, int *); + + friend class input_stack; +}; + +input_item::input_item(string &s, const char *fn, int ln) +: filename(strsave(fn)), first_lineno(ln) +{ + buffer.move(s); + ptr = buffer.contents(); + end = ptr + buffer.length(); +} + +input_item::~input_item() +{ + delete[] filename; +} + +inline int input_item::peek_char() +{ + if (ptr >= end) + return EOF; + else + return (unsigned char)*ptr; +} + +inline int input_item::get_char() +{ + if (ptr >= end) + return EOF; + else + return (unsigned char)*ptr++; +} + +inline void input_item::skip_char() +{ + ptr++; +} + +void input_item::get_location(const char **filenamep, int *linenop) +{ + *filenamep = filename; + if (ptr == buffer.contents()) + *linenop = first_lineno; + else { + int ln = first_lineno; + const char *e = ptr - 1; + for (const char *p = buffer.contents(); p < e; p++) + if (*p == '\n') + ln++; + ln--; // Back up to identify line number _before_ last seen newline. + *linenop = ln; + } + return; +} + +class input_stack { + static input_item *top; +public: + static void init(); + static int get_char(); + static int peek_char(); + static void skip_char() { top->skip_char(); } + static void push_file(const char *); + static void push_string(string &, const char *, int); + static void error(const char *format, + const errarg &arg1 = empty_errarg, + const errarg &arg2 = empty_errarg, + const errarg &arg3 = empty_errarg); +}; + +input_item *input_stack::top = 0; + +void input_stack::init() +{ + while (top) { + input_item *tem = top; + top = top->next; + delete tem; + } +} + +int input_stack::get_char() +{ + while (top) { + int c = top->get_char(); + if (c >= 0) + return c; + input_item *tem = top; + top = top->next; + delete tem; + } + return -1; +} + +int input_stack::peek_char() +{ + while (top) { + int c = top->peek_char(); + if (c >= 0) + return c; + input_item *tem = top; + top = top->next; + delete tem; + } + return -1; +} + +void input_stack::push_file(const char *fn) +{ + FILE *fp; + if (strcmp(fn, "-") == 0) { + fp = stdin; + fn = ""; + } + else { + errno = 0; + fp = fopen(fn, "r"); + if (fp == 0) { + error("can't open '%1': %2", fn, strerror(errno)); + return; + } + } + string buf; + bool is_at_beginning_of_line = true; + int lineno = 1; + for (;;) { + int c = getc(fp); + if (is_at_beginning_of_line && c == '.') { + // replace lines beginning with .R1 or .R2 with a blank line + c = getc(fp); + if (c == 'R') { + c = getc(fp); + if (c == '1' || c == '2') { + int cc = c; + c = getc(fp); + if (compatible_flag || c == ' ' || c == '\n' || c == EOF) { + while (c != '\n' && c != EOF) + c = getc(fp); + } + else { + buf += '.'; + buf += 'R'; + buf += cc; + } + } + else { + buf += '.'; + buf += 'R'; + } + } + else + buf += '.'; + } + if (c == EOF) + break; + if (is_invalid_input_char(c)) + error_with_file_and_line(fn, lineno, + "invalid input character code %1", c); + else { + buf += c; + if (c == '\n') { + is_at_beginning_of_line = true; + lineno++; + } + else + is_at_beginning_of_line = false; + } + } + if (fp != stdin) + fclose(fp); + if (buf.length() > 0 && buf[buf.length() - 1] != '\n') + buf += '\n'; + input_item *it = new input_item(buf, fn); + it->next = top; + top = it; +} + +void input_stack::push_string(string &s, const char *filename, int lineno) +{ + input_item *it = new input_item(s, filename, lineno); + it->next = top; + top = it; +} + +void input_stack::error(const char *format, const errarg &arg1, + const errarg &arg2, const errarg &arg3) +{ + const char *filename; + int lineno; + for (input_item *it = top; it; it = it->next) { + it->get_location(&filename, &lineno); + error_with_file_and_line(filename, lineno, format, arg1, arg2, arg3); + return; + } + ::error(format, arg1, arg2, arg3); +} + +void command_error(const char *format, const errarg &arg1, + const errarg &arg2, const errarg &arg3) +{ + input_stack::error(format, arg1, arg2, arg3); +} + +// # not recognized in "" +// \ is recognized in "" +// # does not conceal newline +// if missing closing quote, word extends to end of line +// no special treatment of \ other than before newline +// \ not recognized after # +// ; allowed as alternative to newline +// ; not recognized in "" +// don't clear word_buffer; just append on +// return -1 for EOF, 0 for newline, 1 for word + +int get_word(string &word_buffer) +{ + int c = input_stack::get_char(); + for (;;) { + if (c == '#') { + do { + c = input_stack::get_char(); + } while (c != '\n' && c != EOF); + break; + } + if (c == '\\' && input_stack::peek_char() == '\n') + input_stack::skip_char(); + else if (c != ' ' && c != '\t') + break; + c = input_stack::get_char(); + } + if (c == EOF) + return -1; + if (c == '\n' || c == ';') + return 0; + if (c == '"') { + for (;;) { + c = input_stack::peek_char(); + if (c == EOF || c == '\n') + break; + input_stack::skip_char(); + if (c == '"') { + int d = input_stack::peek_char(); + if (d == '"') + input_stack::skip_char(); + else + break; + } + else if (c == '\\') { + int d = input_stack::peek_char(); + if (d == '\n') + input_stack::skip_char(); + else + word_buffer += '\\'; + } + else + word_buffer += c; + } + return 1; + } + word_buffer += c; + for (;;) { + c = input_stack::peek_char(); + if (c == ' ' || c == '\t' || c == '\n' || c == '#' || c == ';') + break; + input_stack::skip_char(); + if (c == '\\') { + int d = input_stack::peek_char(); + if (d == '\n') + input_stack::skip_char(); + else + word_buffer += '\\'; + } + else + word_buffer += c; + } + return 1; +} + +union argument { + const char *s; + int n; +}; + +// This is for debugging. + +static void echo_command(int argc, argument *argv) +{ + for (int i = 0; i < argc; i++) + fprintf(stderr, "%s\n", argv[i].s); +} + +static void include_command(int argc, argument *argv) +{ + assert(argc == 1); + input_stack::push_file(argv[0].s); +} + +static void capitalize_command(int argc, argument *argv) +{ + if (argc > 0) + capitalize_fields = argv[0].s; + else + capitalize_fields.clear(); +} + +static void accumulate_command(int, argument *) +{ + accumulate = 1; +} + +static void no_accumulate_command(int, argument *) +{ + accumulate = 0; +} + +static void move_punctuation_command(int, argument *) +{ + move_punctuation = 1; +} + +static void no_move_punctuation_command(int, argument *) +{ + move_punctuation = 0; +} + +static void sort_command(int argc, argument *argv) +{ + if (argc == 0) + sort_fields = "AD"; + else + sort_fields = argv[0].s; + accumulate = 1; +} + +static void no_sort_command(int, argument *) +{ + sort_fields.clear(); +} + +static void articles_command(int argc, argument *argv) +{ + articles.clear(); + int i; + for (i = 0; i < argc; i++) { + articles += argv[i].s; + articles += '\0'; + } + int len = articles.length(); + for (i = 0; i < len; i++) + articles[i] = cmlower(articles[i]); +} + +static void database_command(int argc, argument *argv) +{ + for (int i = 0; i < argc; i++) + database_list.add_file(argv[i].s); +} + +static void default_database_command(int, argument *) +{ + search_default = 1; +} + +static void no_default_database_command(int, argument *) +{ + search_default = 0; +} + +static void bibliography_command(int argc, argument *argv) +{ + have_bibliography = 1; + const char *saved_filename = current_filename; + int saved_lineno = current_lineno; + int saved_label_in_text = label_in_text; + label_in_text = 0; + if (!accumulate) + fputs(".]<\n", stdout); + for (int i = 0; i < argc; i++) + do_bib(argv[i].s); + if (accumulate) + output_references(); + else + fputs(".]>\n", stdout); + current_filename = saved_filename; + current_lineno = saved_lineno; + label_in_text = saved_label_in_text; +} + +static void annotate_command(int argc, argument *argv) +{ + if (argc > 0) + annotation_field = argv[0].s[0]; + else + annotation_field = 'X'; + if (argc == 2) + annotation_macro = argv[1].s; + else + annotation_macro = "AP"; +} + +static void no_annotate_command(int, argument *) +{ + annotation_macro.clear(); + annotation_field = -1; +} + +static void reverse_command(int, argument *argv) +{ + reverse_fields = argv[0].s; +} + +static void no_reverse_command(int, argument *) +{ + reverse_fields.clear(); +} + +static void abbreviate_command(int argc, argument *argv) +{ + abbreviate_fields = argv[0].s; + period_before_initial = argc > 1 ? argv[1].s : ". "; + period_before_last_name = argc > 2 ? argv[2].s : ". "; + period_before_other = argc > 3 ? argv[3].s : ". "; + period_before_hyphen = argc > 4 ? argv[4].s : "."; +} + +static void no_abbreviate_command(int, argument *) +{ + abbreviate_fields.clear(); +} + +string search_ignore_fields; + +static void search_ignore_command(int argc, argument *argv) +{ + if (argc > 0) + search_ignore_fields = argv[0].s; + else + search_ignore_fields = "XYZ"; + search_ignore_fields += '\0'; + linear_ignore_fields = search_ignore_fields.contents(); +} + +static void no_search_ignore_command(int, argument *) +{ + linear_ignore_fields = ""; +} + +static void search_truncate_command(int argc, argument *argv) +{ + if (argc > 0) + linear_truncate_len = argv[0].n; + else + linear_truncate_len = 6; +} + +static void no_search_truncate_command(int, argument *) +{ + linear_truncate_len = -1; +} + +static void discard_command(int argc, argument *argv) +{ + if (argc == 0) + discard_fields = "XYZ"; + else + discard_fields = argv[0].s; + accumulate = 1; +} + +static void no_discard_command(int, argument *) +{ + discard_fields.clear(); +} + +static void label_command(int, argument *argv) +{ + set_label_spec(argv[0].s); +} + +static void abbreviate_label_ranges_command(int argc, argument *argv) +{ + abbreviate_label_ranges = 1; + label_range_indicator = argc > 0 ? argv[0].s : "-"; +} + +static void no_abbreviate_label_ranges_command(int, argument *) +{ + abbreviate_label_ranges = 0; +} + +static void label_in_reference_command(int, argument *) +{ + label_in_reference = 1; +} + +static void no_label_in_reference_command(int, argument *) +{ + label_in_reference = 0; +} + +static void label_in_text_command(int, argument *) +{ + label_in_text = 1; +} + +static void no_label_in_text_command(int, argument *) +{ + label_in_text = 0; +} + +static void sort_adjacent_labels_command(int, argument *) +{ + sort_adjacent_labels = 1; +} + +static void no_sort_adjacent_labels_command(int, argument *) +{ + sort_adjacent_labels = 0; +} + +static void date_as_label_command(int argc, argument *argv) +{ + if (set_date_label_spec(argc > 0 ? argv[0].s : "D%a*")) + date_as_label = 1; +} + +static void no_date_as_label_command(int, argument *) +{ + date_as_label = 0; +} + +static void short_label_command(int, argument *argv) +{ + if (set_short_label_spec(argv[0].s)) + short_label_flag = 1; +} + +static void no_short_label_command(int, argument *) +{ + short_label_flag = 0; +} + +static void compatible_command(int, argument *) +{ + compatible_flag = 1; +} + +static void no_compatible_command(int, argument *) +{ + compatible_flag = 0; +} + +static void join_authors_command(int argc, argument *argv) +{ + join_authors_exactly_two = argv[0].s; + join_authors_default = argc > 1 ? argv[1].s : argv[0].s; + join_authors_last_two = argc == 3 ? argv[2].s : argv[0].s; +} + +static void bracket_label_command(int, argument *argv) +{ + pre_label = argv[0].s; + post_label = argv[1].s; + sep_label = argv[2].s; +} + +static void separate_label_second_parts_command(int, argument *argv) +{ + separate_label_second_parts = argv[0].s; +} + +static void et_al_command(int argc, argument *argv) +{ + et_al = argv[0].s; + et_al_min_elide = argv[1].n; + if (et_al_min_elide < 1) + et_al_min_elide = 1; + et_al_min_total = argc >= 3 ? argv[2].n : 0; +} + +static void no_et_al_command(int, argument *) +{ + et_al.clear(); + et_al_min_elide = 0; +} + +typedef void (*command_t)(int, argument *); + +/* arg_types is a string describing the numbers and types of arguments. +s means a string, i means an integer, f is a list of fields, F is +a single field, +? means that the previous argument is optional, * means that the +previous argument can occur any number of times. */ + +struct S { + const char *name; + command_t func; + const char *arg_types; +} command_table[] = { + { "include", include_command, "s" }, + { "echo", echo_command, "s*" }, + { "capitalize", capitalize_command, "f?" }, + { "accumulate", accumulate_command, "" }, + { "no-accumulate", no_accumulate_command, "" }, + { "move-punctuation", move_punctuation_command, "" }, + { "no-move-punctuation", no_move_punctuation_command, "" }, + { "sort", sort_command, "s?" }, + { "no-sort", no_sort_command, "" }, + { "articles", articles_command, "s*" }, + { "database", database_command, "ss*" }, + { "default-database", default_database_command, "" }, + { "no-default-database", no_default_database_command, "" }, + { "bibliography", bibliography_command, "ss*" }, + { "annotate", annotate_command, "F?s?" }, + { "no-annotate", no_annotate_command, "" }, + { "reverse", reverse_command, "s" }, + { "no-reverse", no_reverse_command, "" }, + { "abbreviate", abbreviate_command, "ss?s?s?s?" }, + { "no-abbreviate", no_abbreviate_command, "" }, + { "search-ignore", search_ignore_command, "f?" }, + { "no-search-ignore", no_search_ignore_command, "" }, + { "search-truncate", search_truncate_command, "i?" }, + { "no-search-truncate", no_search_truncate_command, "" }, + { "discard", discard_command, "f?" }, + { "no-discard", no_discard_command, "" }, + { "label", label_command, "s" }, + { "abbreviate-label-ranges", abbreviate_label_ranges_command, "s?" }, + { "no-abbreviate-label-ranges", no_abbreviate_label_ranges_command, "" }, + { "label-in-reference", label_in_reference_command, "" }, + { "no-label-in-reference", no_label_in_reference_command, "" }, + { "label-in-text", label_in_text_command, "" }, + { "no-label-in-text", no_label_in_text_command, "" }, + { "sort-adjacent-labels", sort_adjacent_labels_command, "" }, + { "no-sort-adjacent-labels", no_sort_adjacent_labels_command, "" }, + { "date-as-label", date_as_label_command, "s?" }, + { "no-date-as-label", no_date_as_label_command, "" }, + { "short-label", short_label_command, "s" }, + { "no-short-label", no_short_label_command, "" }, + { "compatible", compatible_command, "" }, + { "no-compatible", no_compatible_command, "" }, + { "join-authors", join_authors_command, "sss?" }, + { "bracket-label", bracket_label_command, "sss" }, + { "separate-label-second-parts", separate_label_second_parts_command, "s" }, + { "et-al", et_al_command, "sii?" }, + { "no-et-al", no_et_al_command, "" }, +}; + +static int check_args(const char *types, const char *name, + int argc, argument *argv) +{ + int argno = 0; + while (*types) { + if (argc == 0) { + if (types[1] == '?') + break; + else if (types[1] == '*') { + assert(types[2] == '\0'); + break; + } + else { + input_stack::error("missing argument for command '%1'", name); + return 0; + } + } + switch (*types) { + case 's': + break; + case 'i': + { + char *ptr; + long n = strtol(argv->s, &ptr, 10); + if ((n == 0 && ptr == argv->s) + || *ptr != '\0') { + input_stack::error("argument %1 for command '%2' must be an integer", + argno + 1, name); + return 0; + } + argv->n = (int)n; + break; + } + case 'f': + { + for (const char *ptr = argv->s; *ptr != '\0'; ptr++) + if (!cs_field_name(*ptr)) { + input_stack::error("argument %1 for command '%2' must be a list of fields", + argno + 1, name); + return 0; + } + break; + } + case 'F': + if (argv->s[0] == '\0' || argv->s[1] != '\0' + || !cs_field_name(argv->s[0])) { + input_stack::error("argument %1 for command '%2' must be a field name", + argno + 1, name); + return 0; + } + break; + default: + assert(0); + } + if (types[1] == '?') + types += 2; + else if (types[1] != '*') + types += 1; + --argc; + ++argv; + ++argno; + } + if (argc > 0) { + input_stack::error("too many arguments for command '%1'", name); + return 0; + } + return 1; +} + +static void execute_command(const char *name, int argc, argument *argv) +{ + for (unsigned int i = 0; + i < sizeof(command_table)/sizeof(command_table[0]); i++) + if (strcmp(name, command_table[i].name) == 0) { + if (check_args(command_table[i].arg_types, name, argc, argv)) + (*command_table[i].func)(argc, argv); + return; + } + input_stack::error("unknown command '%1'", name); +} + +static void command_loop() +{ + string command; + for (;;) { + command.clear(); + int res = get_word(command); + if (res != 1) { + if (res == 0) + continue; + break; + } + int argc = 0; + command += '\0'; + while ((res = get_word(command)) == 1) { + argc++; + command += '\0'; + } + argument *argv = new argument[argc]; + const char *ptr = command.contents(); + for (int i = 0; i < argc; i++) + argv[i].s = ptr = strchr(ptr, '\0') + 1; + execute_command(command.contents(), argc, argv); + delete[] argv; + if (res == -1) + break; + } +} + +void process_commands(string &s, const char *file, int lineno) +{ + const char *saved_filename = current_filename; + int saved_lineno = current_lineno; + input_stack::init(); + current_filename = file; + // Report diagnostics with respect to line _before_ last newline seen. + current_lineno = lineno - 1; + input_stack::push_string(s, file, lineno); + command_loop(); + current_filename = saved_filename; + current_lineno = saved_lineno; +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/refer/command.h b/src/preproc/refer/command.h new file mode 100644 index 0000000..db850f4 --- /dev/null +++ b/src/preproc/refer/command.h @@ -0,0 +1,35 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +void process_commands(string &s, const char *file, int lineno); + +extern int have_bibliography; +extern int accumulate; +extern int move_punctuation; +extern int search_default; +extern search_list database_list; +extern int label_in_text; +extern int label_in_reference; +extern int sort_adjacent_labels; +extern string pre_label; +extern string post_label; +extern string sep_label; + +extern void do_bib(const char *); +extern void output_references(); diff --git a/src/preproc/refer/label.cpp b/src/preproc/refer/label.cpp new file mode 100644 index 0000000..f8c1645 --- /dev/null +++ b/src/preproc/refer/label.cpp @@ -0,0 +1,2607 @@ +/* A Bison parser, made by GNU Bison 3.8.2. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output, and Bison version. */ +#define YYBISON 30802 + +/* Bison version string. */ +#define YYBISON_VERSION "3.8.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + + + +/* First part of user prologue. */ +#line 19 "../src/preproc/refer/label.ypp" + + +#include "refer.h" +#include "refid.h" +#include "ref.h" +#include "token.h" + +int yylex(); +void yyerror(const char *); + +static const char *format_serial(char c, int n); + +struct label_info { + int start; + int length; + int count; + int total; + label_info(const string &); +}; + +label_info *lookup_label(const string &label); + +struct expression { + enum { + // Does the tentative label depend on the reference? + CONTAINS_VARIABLE = 01, + CONTAINS_STAR = 02, + CONTAINS_FORMAT = 04, + CONTAINS_AT = 010 + }; + virtual ~expression() { } + virtual void evaluate(int, const reference &, string &, + substring_position &) = 0; + virtual unsigned analyze() { return 0; } +}; + +class at_expr : public expression { +public: + at_expr() { } + void evaluate(int, const reference &, string &, substring_position &); + unsigned analyze() { return CONTAINS_VARIABLE|CONTAINS_AT; } +}; + +class format_expr : public expression { + char type; + int width; + int first_number; +public: + format_expr(char c, int w = 0, int f = 1) + : type(c), width(w), first_number(f) { } + void evaluate(int, const reference &, string &, substring_position &); + unsigned analyze() { return CONTAINS_FORMAT; } +}; + +class field_expr : public expression { + int number; + char name; +public: + field_expr(char nm, int num) : number(num), name(nm) { } + void evaluate(int, const reference &, string &, substring_position &); + unsigned analyze() { return CONTAINS_VARIABLE; } +}; + +class literal_expr : public expression { + string s; +public: + literal_expr(const char *ptr, int len) : s(ptr, len) { } + void evaluate(int, const reference &, string &, substring_position &); +}; + +class unary_expr : public expression { +protected: + expression *expr; +public: + unary_expr(expression *e) : expr(e) { } + ~unary_expr() { delete expr; } + void evaluate(int, const reference &, string &, substring_position &) = 0; + unsigned analyze() { return expr ? expr->analyze() : 0; } +}; + +// This caches the analysis of an expression. + +class analyzed_expr : public unary_expr { + unsigned flags; +public: + analyzed_expr(expression *); + void evaluate(int, const reference &, string &, substring_position &); + unsigned analyze() { return flags; } +}; + +class star_expr : public unary_expr { +public: + star_expr(expression *e) : unary_expr(e) { } + void evaluate(int, const reference &, string &, substring_position &); + unsigned analyze() { + return ((expr ? (expr->analyze() & ~CONTAINS_VARIABLE) : 0) + | CONTAINS_STAR); + } +}; + +typedef void map_func(const char *, const char *, string &); + +class map_expr : public unary_expr { + map_func *func; +public: + map_expr(expression *e, map_func *f) : unary_expr(e), func(f) { } + void evaluate(int, const reference &, string &, substring_position &); +}; + +typedef const char *extractor_func(const char *, const char *, const char **); + +class extractor_expr : public unary_expr { + int part; + extractor_func *func; +public: + enum { BEFORE = +1, MATCH = 0, AFTER = -1 }; + extractor_expr(expression *e, extractor_func *f, int pt) + : unary_expr(e), part(pt), func(f) { } + void evaluate(int, const reference &, string &, substring_position &); +}; + +class truncate_expr : public unary_expr { + int n; +public: + truncate_expr(expression *e, int i) : unary_expr(e), n(i) { } + void evaluate(int, const reference &, string &, substring_position &); +}; + +class separator_expr : public unary_expr { +public: + separator_expr(expression *e) : unary_expr(e) { } + void evaluate(int, const reference &, string &, substring_position &); +}; + +class binary_expr : public expression { +protected: + expression *expr1; + expression *expr2; +public: + binary_expr(expression *e1, expression *e2) : expr1(e1), expr2(e2) { } + ~binary_expr() { delete expr1; delete expr2; } + void evaluate(int, const reference &, string &, substring_position &) = 0; + unsigned analyze() { + return (expr1 ? expr1->analyze() : 0) | (expr2 ? expr2->analyze() : 0); + } +}; + +class alternative_expr : public binary_expr { +public: + alternative_expr(expression *e1, expression *e2) : binary_expr(e1, e2) { } + void evaluate(int, const reference &, string &, substring_position &); +}; + +class list_expr : public binary_expr { +public: + list_expr(expression *e1, expression *e2) : binary_expr(e1, e2) { } + void evaluate(int, const reference &, string &, substring_position &); +}; + +class substitute_expr : public binary_expr { +public: + substitute_expr(expression *e1, expression *e2) : binary_expr(e1, e2) { } + void evaluate(int, const reference &, string &, substring_position &); +}; + +class ternary_expr : public expression { +protected: + expression *expr1; + expression *expr2; + expression *expr3; +public: + ternary_expr(expression *e1, expression *e2, expression *e3) + : expr1(e1), expr2(e2), expr3(e3) { } + ~ternary_expr() { delete expr1; delete expr2; delete expr3; } + void evaluate(int, const reference &, string &, substring_position &) = 0; + unsigned analyze() { + return ((expr1 ? expr1->analyze() : 0) + | (expr2 ? expr2->analyze() : 0) + | (expr3 ? expr3->analyze() : 0)); + } +}; + +class conditional_expr : public ternary_expr { +public: + conditional_expr(expression *e1, expression *e2, expression *e3) + : ternary_expr(e1, e2, e3) { } + void evaluate(int, const reference &, string &, substring_position &); +}; + +static expression *parsed_label = 0; +static expression *parsed_date_label = 0; +static expression *parsed_short_label = 0; + +static expression *parse_result; + +string literals; + + +#line 270 "src/preproc/refer/label.cpp" + +# ifndef YY_CAST +# ifdef __cplusplus +# define YY_CAST(Type, Val) static_cast (Val) +# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) +# else +# define YY_CAST(Type, Val) ((Type) (Val)) +# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) +# endif +# endif +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) +# endif +# endif + +/* Use api.header.include to #include this header + instead of duplicating it here. */ +#ifndef YY_YY_SRC_PREPROC_REFER_LABEL_HPP_INCLUDED +# define YY_YY_SRC_PREPROC_REFER_LABEL_HPP_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Token kinds. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + YYEMPTY = -2, + YYEOF = 0, /* "end of file" */ + YYerror = 256, /* error */ + YYUNDEF = 257, /* "invalid token" */ + TOKEN_LETTER = 258, /* TOKEN_LETTER */ + TOKEN_LITERAL = 259, /* TOKEN_LITERAL */ + TOKEN_DIGIT = 260 /* TOKEN_DIGIT */ + }; + typedef enum yytokentype yytoken_kind_t; +#endif +/* Token kinds. */ +#define YYEMPTY -2 +#define YYEOF 0 +#define YYerror 256 +#define YYUNDEF 257 +#define TOKEN_LETTER 258 +#define TOKEN_LITERAL 259 +#define TOKEN_DIGIT 260 + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +union YYSTYPE +{ +#line 218 "../src/preproc/refer/label.ypp" + + int num; + expression *expr; + struct { int ndigits; int val; } dig; + struct { int start; int len; } str; + +#line 340 "src/preproc/refer/label.cpp" + +}; +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE yylval; + + +int yyparse (void); + + +#endif /* !YY_YY_SRC_PREPROC_REFER_LABEL_HPP_INCLUDED */ +/* Symbol kind. */ +enum yysymbol_kind_t +{ + YYSYMBOL_YYEMPTY = -2, + YYSYMBOL_YYEOF = 0, /* "end of file" */ + YYSYMBOL_YYerror = 1, /* error */ + YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ + YYSYMBOL_TOKEN_LETTER = 3, /* TOKEN_LETTER */ + YYSYMBOL_TOKEN_LITERAL = 4, /* TOKEN_LITERAL */ + YYSYMBOL_TOKEN_DIGIT = 5, /* TOKEN_DIGIT */ + YYSYMBOL_6_ = 6, /* '?' */ + YYSYMBOL_7_ = 7, /* ':' */ + YYSYMBOL_8_ = 8, /* '|' */ + YYSYMBOL_9_ = 9, /* '&' */ + YYSYMBOL_10_ = 10, /* '~' */ + YYSYMBOL_11_ = 11, /* '@' */ + YYSYMBOL_12_ = 12, /* '%' */ + YYSYMBOL_13_ = 13, /* '.' */ + YYSYMBOL_14_ = 14, /* '+' */ + YYSYMBOL_15_ = 15, /* '-' */ + YYSYMBOL_16_ = 16, /* '*' */ + YYSYMBOL_17_ = 17, /* '(' */ + YYSYMBOL_18_ = 18, /* ')' */ + YYSYMBOL_19_ = 19, /* '<' */ + YYSYMBOL_20_ = 20, /* '>' */ + YYSYMBOL_YYACCEPT = 21, /* $accept */ + YYSYMBOL_expr = 22, /* expr */ + YYSYMBOL_conditional = 23, /* conditional */ + YYSYMBOL_optional_conditional = 24, /* optional_conditional */ + YYSYMBOL_alternative = 25, /* alternative */ + YYSYMBOL_list = 26, /* list */ + YYSYMBOL_substitute = 27, /* substitute */ + YYSYMBOL_string = 28, /* string */ + YYSYMBOL_optional_number = 29, /* optional_number */ + YYSYMBOL_number = 30, /* number */ + YYSYMBOL_digits = 31, /* digits */ + YYSYMBOL_flag = 32 /* flag */ +}; +typedef enum yysymbol_kind_t yysymbol_kind_t; + + + + +#ifdef short +# undef short +#endif + +/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure + and (if available) are included + so that the code can choose integer types of a good width. */ + +#ifndef __PTRDIFF_MAX__ +# include /* INFRINGES ON USER NAME SPACE */ +# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_STDINT_H +# endif +#endif + +/* Narrow types that promote to a signed type and that can represent a + signed or unsigned integer of at least N bits. In tables they can + save space and decrease cache pressure. Promoting to a signed type + helps avoid bugs in integer arithmetic. */ + +#ifdef __INT_LEAST8_MAX__ +typedef __INT_LEAST8_TYPE__ yytype_int8; +#elif defined YY_STDINT_H +typedef int_least8_t yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef __INT_LEAST16_MAX__ +typedef __INT_LEAST16_TYPE__ yytype_int16; +#elif defined YY_STDINT_H +typedef int_least16_t yytype_int16; +#else +typedef short yytype_int16; +#endif + +/* Work around bug in HP-UX 11.23, which defines these macros + incorrectly for preprocessor constants. This workaround can likely + be removed in 2023, as HPE has promised support for HP-UX 11.23 + (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of + . */ +#ifdef __hpux +# undef UINT_LEAST8_MAX +# undef UINT_LEAST16_MAX +# define UINT_LEAST8_MAX 255 +# define UINT_LEAST16_MAX 65535 +#endif + +#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST8_TYPE__ yytype_uint8; +#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST8_MAX <= INT_MAX) +typedef uint_least8_t yytype_uint8; +#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX +typedef unsigned char yytype_uint8; +#else +typedef short yytype_uint8; +#endif + +#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST16_TYPE__ yytype_uint16; +#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST16_MAX <= INT_MAX) +typedef uint_least16_t yytype_uint16; +#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX +typedef unsigned short yytype_uint16; +#else +typedef int yytype_uint16; +#endif + +#ifndef YYPTRDIFF_T +# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ +# define YYPTRDIFF_T __PTRDIFF_TYPE__ +# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ +# elif defined PTRDIFF_MAX +# ifndef ptrdiff_t +# include /* INFRINGES ON USER NAME SPACE */ +# endif +# define YYPTRDIFF_T ptrdiff_t +# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX +# else +# define YYPTRDIFF_T long +# define YYPTRDIFF_MAXIMUM LONG_MAX +# endif +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned +# endif +#endif + +#define YYSIZE_MAXIMUM \ + YY_CAST (YYPTRDIFF_T, \ + (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ + ? YYPTRDIFF_MAXIMUM \ + : YY_CAST (YYSIZE_T, -1))) + +#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) + + +/* Stored state numbers (used for stacks). */ +typedef yytype_int8 yy_state_t; + +/* State numbers in computations. */ +typedef int yy_state_fast_t; + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + + +#ifndef YY_ATTRIBUTE_PURE +# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) +# else +# define YY_ATTRIBUTE_PURE +# endif +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +# else +# define YY_ATTRIBUTE_UNUSED +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YY_USE(E) ((void) (E)) +#else +# define YY_USE(E) /* empty */ +#endif + +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ +# if __GNUC__ * 100 + __GNUC_MINOR__ < 407 +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") +# else +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# endif +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + +#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ +# define YY_IGNORE_USELESS_CAST_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") +# define YY_IGNORE_USELESS_CAST_END \ + _Pragma ("GCC diagnostic pop") +#endif +#ifndef YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_END +#endif + + +#define YY_ASSERT(E) ((void) (0 && (E))) + +#if !defined yyoverflow + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* !defined yyoverflow */ + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yy_state_t yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYPTRDIFF_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / YYSIZEOF (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYPTRDIFF_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 21 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 39 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 21 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 12 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 34 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 49 + +/* YYMAXUTOK -- Last valid token kind. */ +#define YYMAXUTOK 260 + + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +#define YYTRANSLATE(YYX) \ + (0 <= (YYX) && (YYX) <= YYMAXUTOK \ + ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ + : YYSYMBOL_YYUNDEF) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex. */ +static const yytype_int8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 12, 9, 2, + 17, 18, 16, 14, 2, 15, 13, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 7, 2, + 19, 2, 20, 6, 11, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 8, 2, 10, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5 +}; + +#if YYDEBUG +/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_int16 yyrline[] = +{ + 0, 246, 246, 251, 253, 259, 260, 265, 267, 269, + 274, 276, 281, 283, 288, 290, 295, 297, 299, 315, + 319, 350, 352, 354, 356, 358, 364, 365, 370, 372, + 377, 379, 386, 387, 389 +}; +#endif + +/** Accessing symbol of state STATE. */ +#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) + +#if YYDEBUG || 0 +/* The user-facing name of the symbol whose (internal) number is + YYSYMBOL. No bounds checking. */ +static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; + +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "\"end of file\"", "error", "\"invalid token\"", "TOKEN_LETTER", + "TOKEN_LITERAL", "TOKEN_DIGIT", "'?'", "':'", "'|'", "'&'", "'~'", "'@'", + "'%'", "'.'", "'+'", "'-'", "'*'", "'('", "')'", "'<'", "'>'", "$accept", + "expr", "conditional", "optional_conditional", "alternative", "list", + "substitute", "string", "optional_number", "number", "digits", "flag", YY_NULLPTR +}; + +static const char * +yysymbol_name (yysymbol_kind_t yysymbol) +{ + return yytname[yysymbol]; +} +#endif + +#define YYPACT_NINF (-26) + +#define yypact_value_is_default(Yyn) \ + ((Yyn) == YYPACT_NINF) + +#define YYTABLE_NINF (-1) + +#define yytable_value_is_error(Yyn) \ + 0 + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int8 yypact[] = +{ + 2, 11, -26, -26, 12, 2, 2, 24, -26, -26, + 21, 2, 18, -6, -26, 26, -26, -26, 27, 15, + 14, -26, 2, 2, 2, 18, 2, -3, 11, 11, + -26, -26, -26, -26, -26, 28, 2, 2, -6, -26, + -26, 33, 26, 26, 2, 11, -26, -26, 26 +}; + +/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_int8 yydefact[] = +{ + 5, 16, 15, 14, 0, 5, 5, 0, 6, 2, + 3, 7, 10, 12, 28, 17, 18, 30, 19, 0, + 0, 1, 5, 0, 0, 11, 0, 32, 0, 0, + 23, 29, 31, 24, 25, 0, 8, 9, 13, 33, + 34, 0, 21, 22, 0, 26, 4, 20, 27 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -26, -26, -7, -4, -26, -1, -11, 13, -26, -25, + -26, -26 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + 0, 7, 8, 9, 10, 11, 12, 13, 47, 15, + 18, 41 +}; + +/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_int8 yytable[] = +{ + 25, 19, 20, 42, 43, 1, 2, 27, 28, 29, + 30, 39, 40, 3, 4, 16, 14, 17, 35, 5, + 48, 6, 36, 37, 21, 25, 25, 22, 26, 23, + 24, 31, 32, 33, 34, 44, 45, 46, 0, 38 +}; + +static const yytype_int8 yycheck[] = +{ + 11, 5, 6, 28, 29, 3, 4, 13, 14, 15, + 16, 14, 15, 11, 12, 3, 5, 5, 22, 17, + 45, 19, 23, 24, 0, 36, 37, 6, 10, 8, + 9, 5, 5, 18, 20, 7, 3, 44, -1, 26 +}; + +/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of + state STATE-NUM. */ +static const yytype_int8 yystos[] = +{ + 0, 3, 4, 11, 12, 17, 19, 22, 23, 24, + 25, 26, 27, 28, 5, 30, 3, 5, 31, 24, + 24, 0, 6, 8, 9, 27, 10, 13, 14, 15, + 16, 5, 5, 18, 20, 24, 26, 26, 28, 14, + 15, 32, 30, 30, 7, 3, 23, 29, 30 +}; + +/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ +static const yytype_int8 yyr1[] = +{ + 0, 21, 22, 23, 23, 24, 24, 25, 25, 25, + 26, 26, 27, 27, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 29, 29, 30, 30, + 31, 31, 32, 32, 32 +}; + +/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ +static const yytype_int8 yyr2[] = +{ + 0, 2, 1, 1, 5, 0, 1, 1, 3, 3, + 1, 2, 1, 3, 1, 1, 1, 2, 2, 2, + 5, 3, 3, 2, 3, 3, 0, 1, 1, 2, + 1, 2, 0, 1, 1 +}; + + +enum { YYENOMEM = -2 }; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab +#define YYNOMEM goto yyexhaustedlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) + +/* Backward compatibility with an undocumented macro. + Use YYerror or YYUNDEF. */ +#define YYERRCODE YYUNDEF + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + + + + +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Kind, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) +{ + FILE *yyoutput = yyo; + YY_USE (yyoutput); + if (!yyvaluep) + return; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YY_USE (yykind); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ + +static void +yy_symbol_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) +{ + YYFPRINTF (yyo, "%s %s (", + yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); + + yy_symbol_value_print (yyo, yykind, yyvaluep); + YYFPRINTF (yyo, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, + int yyrule) +{ + int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), + &yyvsp[(yyi + 1) - (yynrhs)]); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) ((void) 0) +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + + + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, + yysymbol_kind_t yykind, YYSTYPE *yyvaluep) +{ + YY_USE (yyvaluep); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YY_USE (yykind); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + +/* Lookahead token kind. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; +/* Number of syntax errors so far. */ +int yynerrs; + + + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (void) +{ + yy_state_fast_t yystate = 0; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus = 0; + + /* Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* Their size. */ + YYPTRDIFF_T yystacksize = YYINITDEPTH; + + /* The state stack: array, bottom, top. */ + yy_state_t yyssa[YYINITDEPTH]; + yy_state_t *yyss = yyssa; + yy_state_t *yyssp = yyss; + + /* The semantic value stack: array, bottom, top. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp = yyvs; + + int yyn; + /* The return value of yyparse. */ + int yyresult; + /* Lookahead symbol kind. */ + yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yychar = YYEMPTY; /* Cause a token to be read. */ + + goto yysetstate; + + +/*------------------------------------------------------------. +| yynewstate -- push a new state, which is found in yystate. | +`------------------------------------------------------------*/ +yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + +/*--------------------------------------------------------------------. +| yysetstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + YY_ASSERT (0 <= yystate && yystate < YYNSTATES); + YY_IGNORE_USELESS_CAST_BEGIN + *yyssp = YY_CAST (yy_state_t, yystate); + YY_IGNORE_USELESS_CAST_END + YY_STACK_PRINT (yyss, yyssp); + + if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + YYNOMEM; +#else + { + /* Get the current used size of the three stacks, in elements. */ + YYPTRDIFF_T yysize = yyssp - yyss + 1; + +# if defined yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + yy_state_t *yyss1 = yyss; + YYSTYPE *yyvs1 = yyvs; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * YYSIZEOF (*yyssp), + &yyvs1, yysize * YYSIZEOF (*yyvsp), + &yystacksize); + yyss = yyss1; + yyvs = yyvs1; + } +# else /* defined YYSTACK_RELOCATE */ + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + YYNOMEM; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yy_state_t *yyss1 = yyss; + union yyalloc *yyptr = + YY_CAST (union yyalloc *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); + if (! yyptr) + YYNOMEM; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YY_IGNORE_USELESS_CAST_BEGIN + YYDPRINTF ((stderr, "Stack size increased to %ld\n", + YY_CAST (long, yystacksize))); + YY_IGNORE_USELESS_CAST_END + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ + + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token\n")); + yychar = yylex (); + } + + if (yychar <= YYEOF) + { + yychar = YYEOF; + yytoken = YYSYMBOL_YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else if (yychar == YYerror) + { + /* The scanner already issued an error message, process directly + to error recovery. But do not keep the error token as + lookahead, it is too special and may lead us to an endless + loop in error recovery. */ + yychar = YYUNDEF; + yytoken = YYSYMBOL_YYerror; + goto yyerrlab1; + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + /* Discard the shifted token. */ + yychar = YYEMPTY; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: /* expr: optional_conditional */ +#line 247 "../src/preproc/refer/label.ypp" + { parse_result = ((yyvsp[0].expr) ? new analyzed_expr((yyvsp[0].expr)) : 0); } +#line 1370 "src/preproc/refer/label.cpp" + break; + + case 3: /* conditional: alternative */ +#line 252 "../src/preproc/refer/label.ypp" + { (yyval.expr) = (yyvsp[0].expr); } +#line 1376 "src/preproc/refer/label.cpp" + break; + + case 4: /* conditional: alternative '?' optional_conditional ':' conditional */ +#line 254 "../src/preproc/refer/label.ypp" + { (yyval.expr) = new conditional_expr((yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].expr)); } +#line 1382 "src/preproc/refer/label.cpp" + break; + + case 5: /* optional_conditional: %empty */ +#line 259 "../src/preproc/refer/label.ypp" + { (yyval.expr) = 0; } +#line 1388 "src/preproc/refer/label.cpp" + break; + + case 6: /* optional_conditional: conditional */ +#line 261 "../src/preproc/refer/label.ypp" + { (yyval.expr) = (yyvsp[0].expr); } +#line 1394 "src/preproc/refer/label.cpp" + break; + + case 7: /* alternative: list */ +#line 266 "../src/preproc/refer/label.ypp" + { (yyval.expr) = (yyvsp[0].expr); } +#line 1400 "src/preproc/refer/label.cpp" + break; + + case 8: /* alternative: alternative '|' list */ +#line 268 "../src/preproc/refer/label.ypp" + { (yyval.expr) = new alternative_expr((yyvsp[-2].expr), (yyvsp[0].expr)); } +#line 1406 "src/preproc/refer/label.cpp" + break; + + case 9: /* alternative: alternative '&' list */ +#line 270 "../src/preproc/refer/label.ypp" + { (yyval.expr) = new conditional_expr((yyvsp[-2].expr), (yyvsp[0].expr), 0); } +#line 1412 "src/preproc/refer/label.cpp" + break; + + case 10: /* list: substitute */ +#line 275 "../src/preproc/refer/label.ypp" + { (yyval.expr) = (yyvsp[0].expr); } +#line 1418 "src/preproc/refer/label.cpp" + break; + + case 11: /* list: list substitute */ +#line 277 "../src/preproc/refer/label.ypp" + { (yyval.expr) = new list_expr((yyvsp[-1].expr), (yyvsp[0].expr)); } +#line 1424 "src/preproc/refer/label.cpp" + break; + + case 12: /* substitute: string */ +#line 282 "../src/preproc/refer/label.ypp" + { (yyval.expr) = (yyvsp[0].expr); } +#line 1430 "src/preproc/refer/label.cpp" + break; + + case 13: /* substitute: substitute '~' string */ +#line 284 "../src/preproc/refer/label.ypp" + { (yyval.expr) = new substitute_expr((yyvsp[-2].expr), (yyvsp[0].expr)); } +#line 1436 "src/preproc/refer/label.cpp" + break; + + case 14: /* string: '@' */ +#line 289 "../src/preproc/refer/label.ypp" + { (yyval.expr) = new at_expr; } +#line 1442 "src/preproc/refer/label.cpp" + break; + + case 15: /* string: TOKEN_LITERAL */ +#line 291 "../src/preproc/refer/label.ypp" + { + (yyval.expr) = new literal_expr(literals.contents() + (yyvsp[0].str).start, + (yyvsp[0].str).len); + } +#line 1451 "src/preproc/refer/label.cpp" + break; + + case 16: /* string: TOKEN_LETTER */ +#line 296 "../src/preproc/refer/label.ypp" + { (yyval.expr) = new field_expr((yyvsp[0].num), 0); } +#line 1457 "src/preproc/refer/label.cpp" + break; + + case 17: /* string: TOKEN_LETTER number */ +#line 298 "../src/preproc/refer/label.ypp" + { (yyval.expr) = new field_expr((yyvsp[-1].num), (yyvsp[0].num) - 1); } +#line 1463 "src/preproc/refer/label.cpp" + break; + + case 18: /* string: '%' TOKEN_LETTER */ +#line 300 "../src/preproc/refer/label.ypp" + { + switch ((yyvsp[0].num)) { + case 'I': + case 'i': + case 'A': + case 'a': + (yyval.expr) = new format_expr((yyvsp[0].num)); + break; + default: + command_error("unrecognized format '%1'", char((yyvsp[0].num))); + (yyval.expr) = new format_expr('a'); + break; + } + } +#line 1482 "src/preproc/refer/label.cpp" + break; + + case 19: /* string: '%' digits */ +#line 316 "../src/preproc/refer/label.ypp" + { + (yyval.expr) = new format_expr('0', (yyvsp[0].dig).ndigits, (yyvsp[0].dig).val); + } +#line 1490 "src/preproc/refer/label.cpp" + break; + + case 20: /* string: string '.' flag TOKEN_LETTER optional_number */ +#line 320 "../src/preproc/refer/label.ypp" + { + switch ((yyvsp[-1].num)) { + case 'l': + (yyval.expr) = new map_expr((yyvsp[-4].expr), lowercase); + break; + case 'u': + (yyval.expr) = new map_expr((yyvsp[-4].expr), uppercase); + break; + case 'c': + (yyval.expr) = new map_expr((yyvsp[-4].expr), capitalize); + break; + case 'r': + (yyval.expr) = new map_expr((yyvsp[-4].expr), reverse_name); + break; + case 'a': + (yyval.expr) = new map_expr((yyvsp[-4].expr), abbreviate_name); + break; + case 'y': + (yyval.expr) = new extractor_expr((yyvsp[-4].expr), find_year, (yyvsp[-2].num)); + break; + case 'n': + (yyval.expr) = new extractor_expr((yyvsp[-4].expr), find_last_name, (yyvsp[-2].num)); + break; + default: + (yyval.expr) = (yyvsp[-4].expr); + command_error("unknown function '%1'", char((yyvsp[-1].num))); + break; + } + } +#line 1524 "src/preproc/refer/label.cpp" + break; + + case 21: /* string: string '+' number */ +#line 351 "../src/preproc/refer/label.ypp" + { (yyval.expr) = new truncate_expr((yyvsp[-2].expr), (yyvsp[0].num)); } +#line 1530 "src/preproc/refer/label.cpp" + break; + + case 22: /* string: string '-' number */ +#line 353 "../src/preproc/refer/label.ypp" + { (yyval.expr) = new truncate_expr((yyvsp[-2].expr), -(yyvsp[0].num)); } +#line 1536 "src/preproc/refer/label.cpp" + break; + + case 23: /* string: string '*' */ +#line 355 "../src/preproc/refer/label.ypp" + { (yyval.expr) = new star_expr((yyvsp[-1].expr)); } +#line 1542 "src/preproc/refer/label.cpp" + break; + + case 24: /* string: '(' optional_conditional ')' */ +#line 357 "../src/preproc/refer/label.ypp" + { (yyval.expr) = (yyvsp[-1].expr); } +#line 1548 "src/preproc/refer/label.cpp" + break; + + case 25: /* string: '<' optional_conditional '>' */ +#line 359 "../src/preproc/refer/label.ypp" + { (yyval.expr) = new separator_expr((yyvsp[-1].expr)); } +#line 1554 "src/preproc/refer/label.cpp" + break; + + case 26: /* optional_number: %empty */ +#line 364 "../src/preproc/refer/label.ypp" + { (yyval.num) = -1; } +#line 1560 "src/preproc/refer/label.cpp" + break; + + case 27: /* optional_number: number */ +#line 366 "../src/preproc/refer/label.ypp" + { (yyval.num) = (yyvsp[0].num); } +#line 1566 "src/preproc/refer/label.cpp" + break; + + case 28: /* number: TOKEN_DIGIT */ +#line 371 "../src/preproc/refer/label.ypp" + { (yyval.num) = (yyvsp[0].num); } +#line 1572 "src/preproc/refer/label.cpp" + break; + + case 29: /* number: number TOKEN_DIGIT */ +#line 373 "../src/preproc/refer/label.ypp" + { (yyval.num) = (yyvsp[-1].num)*10 + (yyvsp[0].num); } +#line 1578 "src/preproc/refer/label.cpp" + break; + + case 30: /* digits: TOKEN_DIGIT */ +#line 378 "../src/preproc/refer/label.ypp" + { (yyval.dig).ndigits = 1; (yyval.dig).val = (yyvsp[0].num); } +#line 1584 "src/preproc/refer/label.cpp" + break; + + case 31: /* digits: digits TOKEN_DIGIT */ +#line 380 "../src/preproc/refer/label.ypp" + { (yyval.dig).ndigits = (yyvsp[-1].dig).ndigits + 1; (yyval.dig).val = (yyvsp[-1].dig).val*10 + (yyvsp[0].num); } +#line 1590 "src/preproc/refer/label.cpp" + break; + + case 32: /* flag: %empty */ +#line 386 "../src/preproc/refer/label.ypp" + { (yyval.num) = 0; } +#line 1596 "src/preproc/refer/label.cpp" + break; + + case 33: /* flag: '+' */ +#line 388 "../src/preproc/refer/label.ypp" + { (yyval.num) = 1; } +#line 1602 "src/preproc/refer/label.cpp" + break; + + case 34: /* flag: '-' */ +#line 390 "../src/preproc/refer/label.ypp" + { (yyval.num) = -1; } +#line 1608 "src/preproc/refer/label.cpp" + break; + + +#line 1612 "src/preproc/refer/label.cpp" + + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + + *++yyvsp = yyval; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; + yyerror (YY_("syntax error")); + } + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; + ++yynerrs; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + /* Pop stack until we find a state that shifts the error token. */ + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYSYMBOL_YYerror; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + YY_ACCESSING_SYMBOL (yystate), yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturnlab; + + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturnlab; + + +/*-----------------------------------------------------------. +| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | +`-----------------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + goto yyreturnlab; + + +/*----------------------------------------------------------. +| yyreturnlab -- parsing is finished, clean up and return. | +`----------------------------------------------------------*/ +yyreturnlab: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + YY_ACCESSING_SYMBOL (+*yyssp), yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + + return yyresult; +} + +#line 393 "../src/preproc/refer/label.ypp" + + +/* bison defines const to be empty unless __STDC__ is defined, which it +isn't under cfront */ + +#ifdef const +#undef const +#endif + +const char *spec_ptr; +const char *spec_end; +const char *spec_cur; + +static char uppercase_array[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', +}; + +static char lowercase_array[] = { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', +}; + +int yylex() +{ + while (spec_ptr < spec_end && csspace(*spec_ptr)) + spec_ptr++; + spec_cur = spec_ptr; + if (spec_ptr >= spec_end) + return 0; + unsigned char c = *spec_ptr++; + if (csalpha(c)) { + yylval.num = c; + return TOKEN_LETTER; + } + if (csdigit(c)) { + yylval.num = c - '0'; + return TOKEN_DIGIT; + } + if (c == '\'') { + yylval.str.start = literals.length(); + for (; spec_ptr < spec_end; spec_ptr++) { + if (*spec_ptr == '\'') { + if (++spec_ptr < spec_end && *spec_ptr == '\'') + literals += '\''; + else { + yylval.str.len = literals.length() - yylval.str.start; + return TOKEN_LITERAL; + } + } + else + literals += *spec_ptr; + } + yylval.str.len = literals.length() - yylval.str.start; + return TOKEN_LITERAL; + } + return c; +} + +int set_label_spec(const char *label_spec) +{ + spec_cur = spec_ptr = label_spec; + spec_end = strchr(label_spec, '\0'); + literals.clear(); + if (yyparse()) + return 0; + delete parsed_label; + parsed_label = parse_result; + return 1; +} + +int set_date_label_spec(const char *label_spec) +{ + spec_cur = spec_ptr = label_spec; + spec_end = strchr(label_spec, '\0'); + literals.clear(); + if (yyparse()) + return 0; + delete parsed_date_label; + parsed_date_label = parse_result; + return 1; +} + +int set_short_label_spec(const char *label_spec) +{ + spec_cur = spec_ptr = label_spec; + spec_end = strchr(label_spec, '\0'); + literals.clear(); + if (yyparse()) + return 0; + delete parsed_short_label; + parsed_short_label = parse_result; + return 1; +} + +void yyerror(const char *message) +{ + if (spec_cur < spec_end) + command_error("label specification %1 before '%2'", message, spec_cur); + else + command_error("label specification %1 at end of string", + message, spec_cur); +} + +void at_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &) +{ + if (tentative) + ref.canonicalize_authors(result); + else { + const char *end, *start = ref.get_authors(&end); + if (start) + result.append(start, end - start); + } +} + +void format_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &) +{ + if (tentative) + return; + const label_info *lp = ref.get_label_ptr(); + int num = lp == 0 ? ref.get_number() : lp->count; + if (type != '0') + result += format_serial(type, num + 1); + else { + const char *ptr = i_to_a(num + first_number); + int pad = width - strlen(ptr); + while (--pad >= 0) + result += '0'; + result += ptr; + } +} + +static const char *format_serial(char c, int n) +{ + assert(n > 0); + static char buf[128]; // more than enough. + switch (c) { + case 'i': + case 'I': + { + char *p = buf; + // troff uses z and w to represent 10000 and 5000 in Roman + // numerals; I can find no historical basis for this usage + const char *s = c == 'i' ? "zwmdclxvi" : "ZWMDCLXVI"; + if (n >= 40000) + return i_to_a(n); + while (n >= 10000) { + *p++ = s[0]; + n -= 10000; + } + for (int i = 1000; i > 0; i /= 10, s += 2) { + int m = n/i; + n -= m*i; + switch (m) { + case 3: + *p++ = s[2]; + /* falls through */ + case 2: + *p++ = s[2]; + /* falls through */ + case 1: + *p++ = s[2]; + break; + case 4: + *p++ = s[2]; + *p++ = s[1]; + break; + case 8: + *p++ = s[1]; + *p++ = s[2]; + *p++ = s[2]; + *p++ = s[2]; + break; + case 7: + *p++ = s[1]; + *p++ = s[2]; + *p++ = s[2]; + break; + case 6: + *p++ = s[1]; + *p++ = s[2]; + break; + case 5: + *p++ = s[1]; + break; + case 9: + *p++ = s[2]; + *p++ = s[0]; + } + } + *p = 0; + break; + } + case 'a': + case 'A': + { + char *p = buf; + // this is derived from troff/reg.c + while (n > 0) { + int d = n % 26; + if (d == 0) + d = 26; + n -= d; + n /= 26; + *p++ = c == 'a' ? lowercase_array[d - 1] : + uppercase_array[d - 1]; + } + *p-- = 0; + // Reverse it. + char *q = buf; + while (q < p) { + char temp = *q; + *q = *p; + *p = temp; + --p; + ++q; + } + break; + } + default: + assert(0); + } + return buf; +} + +void field_expr::evaluate(int, const reference &ref, + string &result, substring_position &) +{ + const char *end; + const char *start = ref.get_field(name, &end); + if (start) { + start = nth_field(number, start, &end); + if (start) + result.append(start, end - start); + } +} + +void literal_expr::evaluate(int, const reference &, + string &result, substring_position &) +{ + result += s; +} + +analyzed_expr::analyzed_expr(expression *e) +: unary_expr(e), flags(e ? e->analyze() : 0) +{ +} + +void analyzed_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &pos) +{ + if (expr) + expr->evaluate(tentative, ref, result, pos); +} + +void star_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &pos) +{ + const label_info *lp = ref.get_label_ptr(); + if (!tentative + && (lp == 0 || lp->total > 1) + && expr) + expr->evaluate(tentative, ref, result, pos); +} + +void separator_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &pos) +{ + int start_length = result.length(); + int is_first = pos.start < 0; + if (expr) + expr->evaluate(tentative, ref, result, pos); + if (is_first) { + pos.start = start_length; + pos.length = result.length() - start_length; + } +} + +void map_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &) +{ + if (expr) { + string temp; + substring_position temp_pos; + expr->evaluate(tentative, ref, temp, temp_pos); + (*func)(temp.contents(), temp.contents() + temp.length(), result); + } +} + +void extractor_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &) +{ + if (expr) { + string temp; + substring_position temp_pos; + expr->evaluate(tentative, ref, temp, temp_pos); + const char *end, *start = (*func)(temp.contents(), + temp.contents() + temp.length(), + &end); + switch (part) { + case BEFORE: + if (start) + result.append(temp.contents(), start - temp.contents()); + else + result += temp; + break; + case MATCH: + if (start) + result.append(start, end - start); + break; + case AFTER: + if (start) + result.append(end, temp.contents() + temp.length() - end); + break; + default: + assert(0); + } + } +} + +static void first_part(int len, const char *ptr, const char *end, + string &result) +{ + for (;;) { + const char *token_start = ptr; + if (!get_token(&ptr, end)) + break; + const token_info *ti = lookup_token(token_start, ptr); + int counts = ti->sortify_non_empty(token_start, ptr); + if (counts && --len < 0) + break; + if (counts || ti->is_accent()) + result.append(token_start, ptr - token_start); + } +} + +static void last_part(int len, const char *ptr, const char *end, + string &result) +{ + const char *start = ptr; + int count = 0; + for (;;) { + const char *token_start = ptr; + if (!get_token(&ptr, end)) + break; + const token_info *ti = lookup_token(token_start, ptr); + if (ti->sortify_non_empty(token_start, ptr)) + count++; + } + ptr = start; + int skip = count - len; + if (skip > 0) { + for (;;) { + const char *token_start = ptr; + if (!get_token(&ptr, end)) + assert(0); + const token_info *ti = lookup_token(token_start, ptr); + if (ti->sortify_non_empty(token_start, ptr) && --skip < 0) { + ptr = token_start; + break; + } + } + } + first_part(len, ptr, end, result); +} + +void truncate_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &) +{ + if (expr) { + string temp; + substring_position temp_pos; + expr->evaluate(tentative, ref, temp, temp_pos); + const char *start = temp.contents(); + const char *end = start + temp.length(); + if (n > 0) + first_part(n, start, end, result); + else if (n < 0) + last_part(-n, start, end, result); + } +} + +void alternative_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &pos) +{ + int start_length = result.length(); + if (expr1) + expr1->evaluate(tentative, ref, result, pos); + if (result.length() == start_length && expr2) + expr2->evaluate(tentative, ref, result, pos); +} + +void list_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &pos) +{ + if (expr1) + expr1->evaluate(tentative, ref, result, pos); + if (expr2) + expr2->evaluate(tentative, ref, result, pos); +} + +void substitute_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &pos) +{ + int start_length = result.length(); + if (expr1) + expr1->evaluate(tentative, ref, result, pos); + if (result.length() > start_length && result[result.length() - 1] == '-') { + // ought to see if pos covers the - + result.set_length(result.length() - 1); + if (expr2) + expr2->evaluate(tentative, ref, result, pos); + } +} + +void conditional_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &pos) +{ + string temp; + substring_position temp_pos; + if (expr1) + expr1->evaluate(tentative, ref, temp, temp_pos); + if (temp.length() > 0) { + if (expr2) + expr2->evaluate(tentative, ref, result, pos); + } + else { + if (expr3) + expr3->evaluate(tentative, ref, result, pos); + } +} + +void reference::pre_compute_label() +{ + if (parsed_label != 0 + && (parsed_label->analyze() & expression::CONTAINS_VARIABLE)) { + label.clear(); + substring_position temp_pos; + parsed_label->evaluate(1, *this, label, temp_pos); + label_ptr = lookup_label(label); + } +} + +void reference::compute_label() +{ + label.clear(); + if (parsed_label) + parsed_label->evaluate(0, *this, label, separator_pos); + if (short_label_flag && parsed_short_label) + parsed_short_label->evaluate(0, *this, short_label, short_separator_pos); + if (date_as_label) { + string new_date; + if (parsed_date_label) { + substring_position temp_pos; + parsed_date_label->evaluate(0, *this, new_date, temp_pos); + } + set_date(new_date); + } + if (label_ptr) + label_ptr->count += 1; +} + +void reference::immediate_compute_label() +{ + if (label_ptr) + label_ptr->total = 2; // force use of disambiguator + compute_label(); +} + +int reference::merge_labels(reference **v, int n, label_type type, + string &result) +{ + if (abbreviate_label_ranges) + return merge_labels_by_number(v, n, type, result); + else + return merge_labels_by_parts(v, n, type, result); +} + +int reference::merge_labels_by_number(reference **v, int n, label_type type, + string &result) +{ + if (n <= 1) + return 0; + int num = get_number(); + // Only merge three or more labels. + if (v[0]->get_number() != num + 1 + || v[1]->get_number() != num + 2) + return 0; + int i; + for (i = 2; i < n; i++) + if (v[i]->get_number() != num + i + 1) + break; + result = get_label(type); + result += label_range_indicator; + result += v[i - 1]->get_label(type); + return i; +} + +const substring_position &reference::get_separator_pos(label_type type) const +{ + if (type == SHORT_LABEL && short_label_flag) + return short_separator_pos; + else + return separator_pos; +} + +const string &reference::get_label(label_type type) const +{ + if (type == SHORT_LABEL && short_label_flag) + return short_label; + else + return label; +} + +int reference::merge_labels_by_parts(reference **v, int n, label_type type, + string &result) +{ + if (n <= 0) + return 0; + const string &lb = get_label(type); + const substring_position &sp = get_separator_pos(type); + if (sp.start < 0 + || sp.start != v[0]->get_separator_pos(type).start + || memcmp(lb.contents(), v[0]->get_label(type).contents(), + sp.start) != 0) + return 0; + result = lb; + int i = 0; + do { + result += separate_label_second_parts; + const substring_position &s = v[i]->get_separator_pos(type); + int sep_end_pos = s.start + s.length; + result.append(v[i]->get_label(type).contents() + sep_end_pos, + v[i]->get_label(type).length() - sep_end_pos); + } while (++i < n + && sp.start == v[i]->get_separator_pos(type).start + && memcmp(lb.contents(), v[i]->get_label(type).contents(), + sp.start) == 0); + return i; +} + +string label_pool; + +label_info::label_info(const string &s) +: start(label_pool.length()), length(s.length()), count(0), total(1) +{ + label_pool += s; +} + +static label_info **label_table = 0; +static int label_table_size = 0; +static int label_table_used = 0; + +label_info *lookup_label(const string &label) +{ + if (label_table == 0) { + label_table = new label_info *[17]; + label_table_size = 17; + for (int i = 0; i < 17; i++) + label_table[i] = 0; + } + unsigned h = hash_string(label.contents(), label.length()) % label_table_size; + label_info **ptr; + for (ptr = label_table + h; + *ptr != 0; + (ptr == label_table) + ? (ptr = label_table + label_table_size - 1) + : ptr--) + if ((*ptr)->length == label.length() + && memcmp(label_pool.contents() + (*ptr)->start, label.contents(), + label.length()) == 0) { + (*ptr)->total += 1; + return *ptr; + } + label_info *result = *ptr = new label_info(label); + if (++label_table_used * 2 > label_table_size) { + // Rehash the table. + label_info **old_table = label_table; + int old_size = label_table_size; + label_table_size = next_size(label_table_size); + label_table = new label_info *[label_table_size]; + int i; + for (i = 0; i < label_table_size; i++) + label_table[i] = 0; + for (i = 0; i < old_size; i++) + if (old_table[i]) { + h = hash_string(label_pool.contents() + old_table[i]->start, + old_table[i]->length); + label_info **p; + for (p = label_table + (h % label_table_size); + *p != 0; + (p == label_table) + ? (p = label_table + label_table_size - 1) + : --p) + ; + *p = old_table[i]; + } + delete[] old_table; + } + return result; +} + +void clear_labels() +{ + for (int i = 0; i < label_table_size; i++) { + delete label_table[i]; + label_table[i] = 0; + } + label_table_used = 0; + label_pool.clear(); +} + +static void consider_authors(reference **start, reference **end, int i); + +void compute_labels(reference **v, int n) +{ + if (parsed_label + && (parsed_label->analyze() & expression::CONTAINS_AT) + && sort_fields.length() >= 2 + && sort_fields[0] == 'A' + && sort_fields[1] == '+') + consider_authors(v, v + n, 0); + for (int i = 0; i < n; i++) + v[i]->compute_label(); +} + + +/* A reference with a list of authors _needs_ author i +where 0 <= i <= N if there exists a reference with a list of authors + such that != and M >= i +and Aj = Bj for 0 <= j < i. In this case if we can't say "A0, +A1,...,A(i-1) et al" because this would match both and +. If a reference needs author i we only have to call +need_author(j) for some j >= i such that the reference also needs +author j. */ + +/* This function handles 2 tasks: +determine which authors are needed (cannot be elided with et al.); +determine which authors can have only last names in the labels. + +References >= start and < end have the same first i author names. +Also they're sorted by A+. */ + +static void consider_authors(reference **start, reference **end, int i) +{ + if (start >= end) + return; + reference **p = start; + if (i >= (*p)->get_nauthors()) { + for (++p; p < end && i >= (*p)->get_nauthors(); p++) + ; + if (p < end && i > 0) { + // If we have an author list and an author list , + // then both lists need C. + for (reference **q = start; q < end; q++) + (*q)->need_author(i - 1); + } + start = p; + } + while (p < end) { + reference **last_name_start = p; + reference **name_start = p; + for (++p; + p < end && i < (*p)->get_nauthors() + && same_author_last_name(**last_name_start, **p, i); + p++) { + if (!same_author_name(**name_start, **p, i)) { + consider_authors(name_start, p, i + 1); + name_start = p; + } + } + consider_authors(name_start, p, i + 1); + if (last_name_start == name_start) { + for (reference **q = last_name_start; q < p; q++) + (*q)->set_last_name_unambiguous(i); + } + // If we have an author list and , then the lists + // need author D and E respectively. + if (name_start > start || p < end) { + for (reference **q = last_name_start; q < p; q++) + (*q)->need_author(i); + } + } +} + +int same_author_last_name(const reference &r1, const reference &r2, int n) +{ + const char *ae1; + const char *as1 = r1.get_sort_field(0, n, 0, &ae1); + const char *ae2; + const char *as2 = r2.get_sort_field(0, n, 0, &ae2); + if (!as1 && !as2) return 1; // they are the same + if (!as1 || !as2) return 0; + return ae1 - as1 == ae2 - as2 && memcmp(as1, as2, ae1 - as1) == 0; +} + +int same_author_name(const reference &r1, const reference &r2, int n) +{ + const char *ae1; + const char *as1 = r1.get_sort_field(0, n, -1, &ae1); + const char *ae2; + const char *as2 = r2.get_sort_field(0, n, -1, &ae2); + if (!as1 && !as2) return 1; // they are the same + if (!as1 || !as2) return 0; + return ae1 - as1 == ae2 - as2 && memcmp(as1, as2, ae1 - as1) == 0; +} + + +void int_set::set(int i) +{ + assert(i >= 0); + int bytei = i >> 3; + if (bytei >= v.length()) { + int old_length = v.length(); + v.set_length(bytei + 1); + for (int j = old_length; j <= bytei; j++) + v[j] = 0; + } + v[bytei] |= 1 << (i & 7); +} + +int int_set::get(int i) const +{ + assert(i >= 0); + int bytei = i >> 3; + return bytei >= v.length() ? 0 : (v[bytei] & (1 << (i & 7))) != 0; +} + +void reference::set_last_name_unambiguous(int i) +{ + last_name_unambiguous.set(i); +} + +void reference::need_author(int n) +{ + if (n > last_needed_author) + last_needed_author = n; +} + +const char *reference::get_authors(const char **end) const +{ + if (!computed_authors) { + ((reference *)this)->computed_authors = 1; + string &result = ((reference *)this)->authors; + int na = get_nauthors(); + result.clear(); + for (int i = 0; i < na; i++) { + if (last_name_unambiguous.get(i)) { + const char *e, *start = get_author_last_name(i, &e); + assert(start != 0); + result.append(start, e - start); + } + else { + const char *e, *start = get_author(i, &e); + assert(start != 0); + result.append(start, e - start); + } + if (i == last_needed_author + && et_al.length() > 0 + && et_al_min_elide > 0 + && last_needed_author + et_al_min_elide < na + && na >= et_al_min_total) { + result += et_al; + break; + } + if (i < na - 1) { + if (na == 2) + result += join_authors_exactly_two; + else if (i < na - 2) + result += join_authors_default; + else + result += join_authors_last_two; + } + } + } + const char *start = authors.contents(); + *end = start + authors.length(); + return start; +} + +int reference::get_nauthors() const +{ + if (nauthors < 0) { + const char *dummy; + int na; + for (na = 0; get_author(na, &dummy) != 0; na++) + ; + ((reference *)this)->nauthors = na; + } + return nauthors; +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/refer/label.hpp b/src/preproc/refer/label.hpp new file mode 100644 index 0000000..9f79fd2 --- /dev/null +++ b/src/preproc/refer/label.hpp @@ -0,0 +1,98 @@ +/* A Bison parser, made by GNU Bison 3.8.2. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + +#ifndef YY_YY_SRC_PREPROC_REFER_LABEL_HPP_INCLUDED +# define YY_YY_SRC_PREPROC_REFER_LABEL_HPP_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Token kinds. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + YYEMPTY = -2, + YYEOF = 0, /* "end of file" */ + YYerror = 256, /* error */ + YYUNDEF = 257, /* "invalid token" */ + TOKEN_LETTER = 258, /* TOKEN_LETTER */ + TOKEN_LITERAL = 259, /* TOKEN_LITERAL */ + TOKEN_DIGIT = 260 /* TOKEN_DIGIT */ + }; + typedef enum yytokentype yytoken_kind_t; +#endif +/* Token kinds. */ +#define YYEMPTY -2 +#define YYEOF 0 +#define YYerror 256 +#define YYUNDEF 257 +#define TOKEN_LETTER 258 +#define TOKEN_LITERAL 259 +#define TOKEN_DIGIT 260 + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +union YYSTYPE +{ +#line 218 "../src/preproc/refer/label.ypp" + + int num; + expression *expr; + struct { int ndigits; int val; } dig; + struct { int start; int len; } str; + +#line 84 "src/preproc/refer/label.hpp" + +}; +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE yylval; + + +int yyparse (void); + + +#endif /* !YY_YY_SRC_PREPROC_REFER_LABEL_HPP_INCLUDED */ diff --git a/src/preproc/refer/label.ypp b/src/preproc/refer/label.ypp new file mode 100644 index 0000000..f5210d5 --- /dev/null +++ b/src/preproc/refer/label.ypp @@ -0,0 +1,1195 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +%{ + +#include "refer.h" +#include "refid.h" +#include "ref.h" +#include "token.h" + +int yylex(); +void yyerror(const char *); + +static const char *format_serial(char c, int n); + +struct label_info { + int start; + int length; + int count; + int total; + label_info(const string &); +}; + +label_info *lookup_label(const string &label); + +struct expression { + enum { + // Does the tentative label depend on the reference? + CONTAINS_VARIABLE = 01, + CONTAINS_STAR = 02, + CONTAINS_FORMAT = 04, + CONTAINS_AT = 010 + }; + virtual ~expression() { } + virtual void evaluate(int, const reference &, string &, + substring_position &) = 0; + virtual unsigned analyze() { return 0; } +}; + +class at_expr : public expression { +public: + at_expr() { } + void evaluate(int, const reference &, string &, substring_position &); + unsigned analyze() { return CONTAINS_VARIABLE|CONTAINS_AT; } +}; + +class format_expr : public expression { + char type; + int width; + int first_number; +public: + format_expr(char c, int w = 0, int f = 1) + : type(c), width(w), first_number(f) { } + void evaluate(int, const reference &, string &, substring_position &); + unsigned analyze() { return CONTAINS_FORMAT; } +}; + +class field_expr : public expression { + int number; + char name; +public: + field_expr(char nm, int num) : number(num), name(nm) { } + void evaluate(int, const reference &, string &, substring_position &); + unsigned analyze() { return CONTAINS_VARIABLE; } +}; + +class literal_expr : public expression { + string s; +public: + literal_expr(const char *ptr, int len) : s(ptr, len) { } + void evaluate(int, const reference &, string &, substring_position &); +}; + +class unary_expr : public expression { +protected: + expression *expr; +public: + unary_expr(expression *e) : expr(e) { } + ~unary_expr() { delete expr; } + void evaluate(int, const reference &, string &, substring_position &) = 0; + unsigned analyze() { return expr ? expr->analyze() : 0; } +}; + +// This caches the analysis of an expression. + +class analyzed_expr : public unary_expr { + unsigned flags; +public: + analyzed_expr(expression *); + void evaluate(int, const reference &, string &, substring_position &); + unsigned analyze() { return flags; } +}; + +class star_expr : public unary_expr { +public: + star_expr(expression *e) : unary_expr(e) { } + void evaluate(int, const reference &, string &, substring_position &); + unsigned analyze() { + return ((expr ? (expr->analyze() & ~CONTAINS_VARIABLE) : 0) + | CONTAINS_STAR); + } +}; + +typedef void map_func(const char *, const char *, string &); + +class map_expr : public unary_expr { + map_func *func; +public: + map_expr(expression *e, map_func *f) : unary_expr(e), func(f) { } + void evaluate(int, const reference &, string &, substring_position &); +}; + +typedef const char *extractor_func(const char *, const char *, const char **); + +class extractor_expr : public unary_expr { + int part; + extractor_func *func; +public: + enum { BEFORE = +1, MATCH = 0, AFTER = -1 }; + extractor_expr(expression *e, extractor_func *f, int pt) + : unary_expr(e), part(pt), func(f) { } + void evaluate(int, const reference &, string &, substring_position &); +}; + +class truncate_expr : public unary_expr { + int n; +public: + truncate_expr(expression *e, int i) : unary_expr(e), n(i) { } + void evaluate(int, const reference &, string &, substring_position &); +}; + +class separator_expr : public unary_expr { +public: + separator_expr(expression *e) : unary_expr(e) { } + void evaluate(int, const reference &, string &, substring_position &); +}; + +class binary_expr : public expression { +protected: + expression *expr1; + expression *expr2; +public: + binary_expr(expression *e1, expression *e2) : expr1(e1), expr2(e2) { } + ~binary_expr() { delete expr1; delete expr2; } + void evaluate(int, const reference &, string &, substring_position &) = 0; + unsigned analyze() { + return (expr1 ? expr1->analyze() : 0) | (expr2 ? expr2->analyze() : 0); + } +}; + +class alternative_expr : public binary_expr { +public: + alternative_expr(expression *e1, expression *e2) : binary_expr(e1, e2) { } + void evaluate(int, const reference &, string &, substring_position &); +}; + +class list_expr : public binary_expr { +public: + list_expr(expression *e1, expression *e2) : binary_expr(e1, e2) { } + void evaluate(int, const reference &, string &, substring_position &); +}; + +class substitute_expr : public binary_expr { +public: + substitute_expr(expression *e1, expression *e2) : binary_expr(e1, e2) { } + void evaluate(int, const reference &, string &, substring_position &); +}; + +class ternary_expr : public expression { +protected: + expression *expr1; + expression *expr2; + expression *expr3; +public: + ternary_expr(expression *e1, expression *e2, expression *e3) + : expr1(e1), expr2(e2), expr3(e3) { } + ~ternary_expr() { delete expr1; delete expr2; delete expr3; } + void evaluate(int, const reference &, string &, substring_position &) = 0; + unsigned analyze() { + return ((expr1 ? expr1->analyze() : 0) + | (expr2 ? expr2->analyze() : 0) + | (expr3 ? expr3->analyze() : 0)); + } +}; + +class conditional_expr : public ternary_expr { +public: + conditional_expr(expression *e1, expression *e2, expression *e3) + : ternary_expr(e1, e2, e3) { } + void evaluate(int, const reference &, string &, substring_position &); +}; + +static expression *parsed_label = 0; +static expression *parsed_date_label = 0; +static expression *parsed_short_label = 0; + +static expression *parse_result; + +string literals; + +%} + +%union { + int num; + expression *expr; + struct { int ndigits; int val; } dig; + struct { int start; int len; } str; +} + +/* uppercase or lowercase letter */ +%token TOKEN_LETTER +/* literal characters */ +%token TOKEN_LITERAL +/* digit */ +%token TOKEN_DIGIT + +%type conditional +%type alternative +%type list +%type string +%type substitute +%type optional_conditional +%type number +%type digits +%type optional_number +%type flag + +%% + +expr: + optional_conditional + { parse_result = ($1 ? new analyzed_expr($1) : 0); } + ; + +conditional: + alternative + { $$ = $1; } + | alternative '?' optional_conditional ':' conditional + { $$ = new conditional_expr($1, $3, $5); } + ; + +optional_conditional: + /* empty */ + { $$ = 0; } + | conditional + { $$ = $1; } + ; + +alternative: + list + { $$ = $1; } + | alternative '|' list + { $$ = new alternative_expr($1, $3); } + | alternative '&' list + { $$ = new conditional_expr($1, $3, 0); } + ; + +list: + substitute + { $$ = $1; } + | list substitute + { $$ = new list_expr($1, $2); } + ; + +substitute: + string + { $$ = $1; } + | substitute '~' string + { $$ = new substitute_expr($1, $3); } + ; + +string: + '@' + { $$ = new at_expr; } + | TOKEN_LITERAL + { + $$ = new literal_expr(literals.contents() + $1.start, + $1.len); + } + | TOKEN_LETTER + { $$ = new field_expr($1, 0); } + | TOKEN_LETTER number + { $$ = new field_expr($1, $2 - 1); } + | '%' TOKEN_LETTER + { + switch ($2) { + case 'I': + case 'i': + case 'A': + case 'a': + $$ = new format_expr($2); + break; + default: + command_error("unrecognized format '%1'", char($2)); + $$ = new format_expr('a'); + break; + } + } + + | '%' digits + { + $$ = new format_expr('0', $2.ndigits, $2.val); + } + | string '.' flag TOKEN_LETTER optional_number + { + switch ($4) { + case 'l': + $$ = new map_expr($1, lowercase); + break; + case 'u': + $$ = new map_expr($1, uppercase); + break; + case 'c': + $$ = new map_expr($1, capitalize); + break; + case 'r': + $$ = new map_expr($1, reverse_name); + break; + case 'a': + $$ = new map_expr($1, abbreviate_name); + break; + case 'y': + $$ = new extractor_expr($1, find_year, $3); + break; + case 'n': + $$ = new extractor_expr($1, find_last_name, $3); + break; + default: + $$ = $1; + command_error("unknown function '%1'", char($4)); + break; + } + } + + | string '+' number + { $$ = new truncate_expr($1, $3); } + | string '-' number + { $$ = new truncate_expr($1, -$3); } + | string '*' + { $$ = new star_expr($1); } + | '(' optional_conditional ')' + { $$ = $2; } + | '<' optional_conditional '>' + { $$ = new separator_expr($2); } + ; + +optional_number: + /* empty */ + { $$ = -1; } + | number + { $$ = $1; } + ; + +number: + TOKEN_DIGIT + { $$ = $1; } + | number TOKEN_DIGIT + { $$ = $1*10 + $2; } + ; + +digits: + TOKEN_DIGIT + { $$.ndigits = 1; $$.val = $1; } + | digits TOKEN_DIGIT + { $$.ndigits = $1.ndigits + 1; $$.val = $1.val*10 + $2; } + ; + + +flag: + /* empty */ + { $$ = 0; } + | '+' + { $$ = 1; } + | '-' + { $$ = -1; } + ; + +%% + +/* bison defines const to be empty unless __STDC__ is defined, which it +isn't under cfront */ + +#ifdef const +#undef const +#endif + +const char *spec_ptr; +const char *spec_end; +const char *spec_cur; + +static char uppercase_array[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', +}; + +static char lowercase_array[] = { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', +}; + +int yylex() +{ + while (spec_ptr < spec_end && csspace(*spec_ptr)) + spec_ptr++; + spec_cur = spec_ptr; + if (spec_ptr >= spec_end) + return 0; + unsigned char c = *spec_ptr++; + if (csalpha(c)) { + yylval.num = c; + return TOKEN_LETTER; + } + if (csdigit(c)) { + yylval.num = c - '0'; + return TOKEN_DIGIT; + } + if (c == '\'') { + yylval.str.start = literals.length(); + for (; spec_ptr < spec_end; spec_ptr++) { + if (*spec_ptr == '\'') { + if (++spec_ptr < spec_end && *spec_ptr == '\'') + literals += '\''; + else { + yylval.str.len = literals.length() - yylval.str.start; + return TOKEN_LITERAL; + } + } + else + literals += *spec_ptr; + } + yylval.str.len = literals.length() - yylval.str.start; + return TOKEN_LITERAL; + } + return c; +} + +int set_label_spec(const char *label_spec) +{ + spec_cur = spec_ptr = label_spec; + spec_end = strchr(label_spec, '\0'); + literals.clear(); + if (yyparse()) + return 0; + delete parsed_label; + parsed_label = parse_result; + return 1; +} + +int set_date_label_spec(const char *label_spec) +{ + spec_cur = spec_ptr = label_spec; + spec_end = strchr(label_spec, '\0'); + literals.clear(); + if (yyparse()) + return 0; + delete parsed_date_label; + parsed_date_label = parse_result; + return 1; +} + +int set_short_label_spec(const char *label_spec) +{ + spec_cur = spec_ptr = label_spec; + spec_end = strchr(label_spec, '\0'); + literals.clear(); + if (yyparse()) + return 0; + delete parsed_short_label; + parsed_short_label = parse_result; + return 1; +} + +void yyerror(const char *message) +{ + if (spec_cur < spec_end) + command_error("label specification %1 before '%2'", message, spec_cur); + else + command_error("label specification %1 at end of string", + message, spec_cur); +} + +void at_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &) +{ + if (tentative) + ref.canonicalize_authors(result); + else { + const char *end, *start = ref.get_authors(&end); + if (start) + result.append(start, end - start); + } +} + +void format_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &) +{ + if (tentative) + return; + const label_info *lp = ref.get_label_ptr(); + int num = lp == 0 ? ref.get_number() : lp->count; + if (type != '0') + result += format_serial(type, num + 1); + else { + const char *ptr = i_to_a(num + first_number); + int pad = width - strlen(ptr); + while (--pad >= 0) + result += '0'; + result += ptr; + } +} + +static const char *format_serial(char c, int n) +{ + assert(n > 0); + static char buf[128]; // more than enough. + switch (c) { + case 'i': + case 'I': + { + char *p = buf; + // troff uses z and w to represent 10000 and 5000 in Roman + // numerals; I can find no historical basis for this usage + const char *s = c == 'i' ? "zwmdclxvi" : "ZWMDCLXVI"; + if (n >= 40000) + return i_to_a(n); + while (n >= 10000) { + *p++ = s[0]; + n -= 10000; + } + for (int i = 1000; i > 0; i /= 10, s += 2) { + int m = n/i; + n -= m*i; + switch (m) { + case 3: + *p++ = s[2]; + /* falls through */ + case 2: + *p++ = s[2]; + /* falls through */ + case 1: + *p++ = s[2]; + break; + case 4: + *p++ = s[2]; + *p++ = s[1]; + break; + case 8: + *p++ = s[1]; + *p++ = s[2]; + *p++ = s[2]; + *p++ = s[2]; + break; + case 7: + *p++ = s[1]; + *p++ = s[2]; + *p++ = s[2]; + break; + case 6: + *p++ = s[1]; + *p++ = s[2]; + break; + case 5: + *p++ = s[1]; + break; + case 9: + *p++ = s[2]; + *p++ = s[0]; + } + } + *p = 0; + break; + } + case 'a': + case 'A': + { + char *p = buf; + // this is derived from troff/reg.c + while (n > 0) { + int d = n % 26; + if (d == 0) + d = 26; + n -= d; + n /= 26; + *p++ = c == 'a' ? lowercase_array[d - 1] : + uppercase_array[d - 1]; + } + *p-- = 0; + // Reverse it. + char *q = buf; + while (q < p) { + char temp = *q; + *q = *p; + *p = temp; + --p; + ++q; + } + break; + } + default: + assert(0); + } + return buf; +} + +void field_expr::evaluate(int, const reference &ref, + string &result, substring_position &) +{ + const char *end; + const char *start = ref.get_field(name, &end); + if (start) { + start = nth_field(number, start, &end); + if (start) + result.append(start, end - start); + } +} + +void literal_expr::evaluate(int, const reference &, + string &result, substring_position &) +{ + result += s; +} + +analyzed_expr::analyzed_expr(expression *e) +: unary_expr(e), flags(e ? e->analyze() : 0) +{ +} + +void analyzed_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &pos) +{ + if (expr) + expr->evaluate(tentative, ref, result, pos); +} + +void star_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &pos) +{ + const label_info *lp = ref.get_label_ptr(); + if (!tentative + && (lp == 0 || lp->total > 1) + && expr) + expr->evaluate(tentative, ref, result, pos); +} + +void separator_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &pos) +{ + int start_length = result.length(); + int is_first = pos.start < 0; + if (expr) + expr->evaluate(tentative, ref, result, pos); + if (is_first) { + pos.start = start_length; + pos.length = result.length() - start_length; + } +} + +void map_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &) +{ + if (expr) { + string temp; + substring_position temp_pos; + expr->evaluate(tentative, ref, temp, temp_pos); + (*func)(temp.contents(), temp.contents() + temp.length(), result); + } +} + +void extractor_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &) +{ + if (expr) { + string temp; + substring_position temp_pos; + expr->evaluate(tentative, ref, temp, temp_pos); + const char *end, *start = (*func)(temp.contents(), + temp.contents() + temp.length(), + &end); + switch (part) { + case BEFORE: + if (start) + result.append(temp.contents(), start - temp.contents()); + else + result += temp; + break; + case MATCH: + if (start) + result.append(start, end - start); + break; + case AFTER: + if (start) + result.append(end, temp.contents() + temp.length() - end); + break; + default: + assert(0); + } + } +} + +static void first_part(int len, const char *ptr, const char *end, + string &result) +{ + for (;;) { + const char *token_start = ptr; + if (!get_token(&ptr, end)) + break; + const token_info *ti = lookup_token(token_start, ptr); + int counts = ti->sortify_non_empty(token_start, ptr); + if (counts && --len < 0) + break; + if (counts || ti->is_accent()) + result.append(token_start, ptr - token_start); + } +} + +static void last_part(int len, const char *ptr, const char *end, + string &result) +{ + const char *start = ptr; + int count = 0; + for (;;) { + const char *token_start = ptr; + if (!get_token(&ptr, end)) + break; + const token_info *ti = lookup_token(token_start, ptr); + if (ti->sortify_non_empty(token_start, ptr)) + count++; + } + ptr = start; + int skip = count - len; + if (skip > 0) { + for (;;) { + const char *token_start = ptr; + if (!get_token(&ptr, end)) + assert(0); + const token_info *ti = lookup_token(token_start, ptr); + if (ti->sortify_non_empty(token_start, ptr) && --skip < 0) { + ptr = token_start; + break; + } + } + } + first_part(len, ptr, end, result); +} + +void truncate_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &) +{ + if (expr) { + string temp; + substring_position temp_pos; + expr->evaluate(tentative, ref, temp, temp_pos); + const char *start = temp.contents(); + const char *end = start + temp.length(); + if (n > 0) + first_part(n, start, end, result); + else if (n < 0) + last_part(-n, start, end, result); + } +} + +void alternative_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &pos) +{ + int start_length = result.length(); + if (expr1) + expr1->evaluate(tentative, ref, result, pos); + if (result.length() == start_length && expr2) + expr2->evaluate(tentative, ref, result, pos); +} + +void list_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &pos) +{ + if (expr1) + expr1->evaluate(tentative, ref, result, pos); + if (expr2) + expr2->evaluate(tentative, ref, result, pos); +} + +void substitute_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &pos) +{ + int start_length = result.length(); + if (expr1) + expr1->evaluate(tentative, ref, result, pos); + if (result.length() > start_length && result[result.length() - 1] == '-') { + // ought to see if pos covers the - + result.set_length(result.length() - 1); + if (expr2) + expr2->evaluate(tentative, ref, result, pos); + } +} + +void conditional_expr::evaluate(int tentative, const reference &ref, + string &result, substring_position &pos) +{ + string temp; + substring_position temp_pos; + if (expr1) + expr1->evaluate(tentative, ref, temp, temp_pos); + if (temp.length() > 0) { + if (expr2) + expr2->evaluate(tentative, ref, result, pos); + } + else { + if (expr3) + expr3->evaluate(tentative, ref, result, pos); + } +} + +void reference::pre_compute_label() +{ + if (parsed_label != 0 + && (parsed_label->analyze() & expression::CONTAINS_VARIABLE)) { + label.clear(); + substring_position temp_pos; + parsed_label->evaluate(1, *this, label, temp_pos); + label_ptr = lookup_label(label); + } +} + +void reference::compute_label() +{ + label.clear(); + if (parsed_label) + parsed_label->evaluate(0, *this, label, separator_pos); + if (short_label_flag && parsed_short_label) + parsed_short_label->evaluate(0, *this, short_label, short_separator_pos); + if (date_as_label) { + string new_date; + if (parsed_date_label) { + substring_position temp_pos; + parsed_date_label->evaluate(0, *this, new_date, temp_pos); + } + set_date(new_date); + } + if (label_ptr) + label_ptr->count += 1; +} + +void reference::immediate_compute_label() +{ + if (label_ptr) + label_ptr->total = 2; // force use of disambiguator + compute_label(); +} + +int reference::merge_labels(reference **v, int n, label_type type, + string &result) +{ + if (abbreviate_label_ranges) + return merge_labels_by_number(v, n, type, result); + else + return merge_labels_by_parts(v, n, type, result); +} + +int reference::merge_labels_by_number(reference **v, int n, label_type type, + string &result) +{ + if (n <= 1) + return 0; + int num = get_number(); + // Only merge three or more labels. + if (v[0]->get_number() != num + 1 + || v[1]->get_number() != num + 2) + return 0; + int i; + for (i = 2; i < n; i++) + if (v[i]->get_number() != num + i + 1) + break; + result = get_label(type); + result += label_range_indicator; + result += v[i - 1]->get_label(type); + return i; +} + +const substring_position &reference::get_separator_pos(label_type type) const +{ + if (type == SHORT_LABEL && short_label_flag) + return short_separator_pos; + else + return separator_pos; +} + +const string &reference::get_label(label_type type) const +{ + if (type == SHORT_LABEL && short_label_flag) + return short_label; + else + return label; +} + +int reference::merge_labels_by_parts(reference **v, int n, label_type type, + string &result) +{ + if (n <= 0) + return 0; + const string &lb = get_label(type); + const substring_position &sp = get_separator_pos(type); + if (sp.start < 0 + || sp.start != v[0]->get_separator_pos(type).start + || memcmp(lb.contents(), v[0]->get_label(type).contents(), + sp.start) != 0) + return 0; + result = lb; + int i = 0; + do { + result += separate_label_second_parts; + const substring_position &s = v[i]->get_separator_pos(type); + int sep_end_pos = s.start + s.length; + result.append(v[i]->get_label(type).contents() + sep_end_pos, + v[i]->get_label(type).length() - sep_end_pos); + } while (++i < n + && sp.start == v[i]->get_separator_pos(type).start + && memcmp(lb.contents(), v[i]->get_label(type).contents(), + sp.start) == 0); + return i; +} + +string label_pool; + +label_info::label_info(const string &s) +: start(label_pool.length()), length(s.length()), count(0), total(1) +{ + label_pool += s; +} + +static label_info **label_table = 0; +static int label_table_size = 0; +static int label_table_used = 0; + +label_info *lookup_label(const string &label) +{ + if (label_table == 0) { + label_table = new label_info *[17]; + label_table_size = 17; + for (int i = 0; i < 17; i++) + label_table[i] = 0; + } + unsigned h = hash_string(label.contents(), label.length()) % label_table_size; + label_info **ptr; + for (ptr = label_table + h; + *ptr != 0; + (ptr == label_table) + ? (ptr = label_table + label_table_size - 1) + : ptr--) + if ((*ptr)->length == label.length() + && memcmp(label_pool.contents() + (*ptr)->start, label.contents(), + label.length()) == 0) { + (*ptr)->total += 1; + return *ptr; + } + label_info *result = *ptr = new label_info(label); + if (++label_table_used * 2 > label_table_size) { + // Rehash the table. + label_info **old_table = label_table; + int old_size = label_table_size; + label_table_size = next_size(label_table_size); + label_table = new label_info *[label_table_size]; + int i; + for (i = 0; i < label_table_size; i++) + label_table[i] = 0; + for (i = 0; i < old_size; i++) + if (old_table[i]) { + h = hash_string(label_pool.contents() + old_table[i]->start, + old_table[i]->length); + label_info **p; + for (p = label_table + (h % label_table_size); + *p != 0; + (p == label_table) + ? (p = label_table + label_table_size - 1) + : --p) + ; + *p = old_table[i]; + } + delete[] old_table; + } + return result; +} + +void clear_labels() +{ + for (int i = 0; i < label_table_size; i++) { + delete label_table[i]; + label_table[i] = 0; + } + label_table_used = 0; + label_pool.clear(); +} + +static void consider_authors(reference **start, reference **end, int i); + +void compute_labels(reference **v, int n) +{ + if (parsed_label + && (parsed_label->analyze() & expression::CONTAINS_AT) + && sort_fields.length() >= 2 + && sort_fields[0] == 'A' + && sort_fields[1] == '+') + consider_authors(v, v + n, 0); + for (int i = 0; i < n; i++) + v[i]->compute_label(); +} + + +/* A reference with a list of authors _needs_ author i +where 0 <= i <= N if there exists a reference with a list of authors + such that != and M >= i +and Aj = Bj for 0 <= j < i. In this case if we can't say "A0, +A1,...,A(i-1) et al" because this would match both and +. If a reference needs author i we only have to call +need_author(j) for some j >= i such that the reference also needs +author j. */ + +/* This function handles 2 tasks: +determine which authors are needed (cannot be elided with et al.); +determine which authors can have only last names in the labels. + +References >= start and < end have the same first i author names. +Also they're sorted by A+. */ + +static void consider_authors(reference **start, reference **end, int i) +{ + if (start >= end) + return; + reference **p = start; + if (i >= (*p)->get_nauthors()) { + for (++p; p < end && i >= (*p)->get_nauthors(); p++) + ; + if (p < end && i > 0) { + // If we have an author list and an author list , + // then both lists need C. + for (reference **q = start; q < end; q++) + (*q)->need_author(i - 1); + } + start = p; + } + while (p < end) { + reference **last_name_start = p; + reference **name_start = p; + for (++p; + p < end && i < (*p)->get_nauthors() + && same_author_last_name(**last_name_start, **p, i); + p++) { + if (!same_author_name(**name_start, **p, i)) { + consider_authors(name_start, p, i + 1); + name_start = p; + } + } + consider_authors(name_start, p, i + 1); + if (last_name_start == name_start) { + for (reference **q = last_name_start; q < p; q++) + (*q)->set_last_name_unambiguous(i); + } + // If we have an author list and , then the lists + // need author D and E respectively. + if (name_start > start || p < end) { + for (reference **q = last_name_start; q < p; q++) + (*q)->need_author(i); + } + } +} + +int same_author_last_name(const reference &r1, const reference &r2, int n) +{ + const char *ae1; + const char *as1 = r1.get_sort_field(0, n, 0, &ae1); + const char *ae2; + const char *as2 = r2.get_sort_field(0, n, 0, &ae2); + if (!as1 && !as2) return 1; // they are the same + if (!as1 || !as2) return 0; + return ae1 - as1 == ae2 - as2 && memcmp(as1, as2, ae1 - as1) == 0; +} + +int same_author_name(const reference &r1, const reference &r2, int n) +{ + const char *ae1; + const char *as1 = r1.get_sort_field(0, n, -1, &ae1); + const char *ae2; + const char *as2 = r2.get_sort_field(0, n, -1, &ae2); + if (!as1 && !as2) return 1; // they are the same + if (!as1 || !as2) return 0; + return ae1 - as1 == ae2 - as2 && memcmp(as1, as2, ae1 - as1) == 0; +} + + +void int_set::set(int i) +{ + assert(i >= 0); + int bytei = i >> 3; + if (bytei >= v.length()) { + int old_length = v.length(); + v.set_length(bytei + 1); + for (int j = old_length; j <= bytei; j++) + v[j] = 0; + } + v[bytei] |= 1 << (i & 7); +} + +int int_set::get(int i) const +{ + assert(i >= 0); + int bytei = i >> 3; + return bytei >= v.length() ? 0 : (v[bytei] & (1 << (i & 7))) != 0; +} + +void reference::set_last_name_unambiguous(int i) +{ + last_name_unambiguous.set(i); +} + +void reference::need_author(int n) +{ + if (n > last_needed_author) + last_needed_author = n; +} + +const char *reference::get_authors(const char **end) const +{ + if (!computed_authors) { + ((reference *)this)->computed_authors = 1; + string &result = ((reference *)this)->authors; + int na = get_nauthors(); + result.clear(); + for (int i = 0; i < na; i++) { + if (last_name_unambiguous.get(i)) { + const char *e, *start = get_author_last_name(i, &e); + assert(start != 0); + result.append(start, e - start); + } + else { + const char *e, *start = get_author(i, &e); + assert(start != 0); + result.append(start, e - start); + } + if (i == last_needed_author + && et_al.length() > 0 + && et_al_min_elide > 0 + && last_needed_author + et_al_min_elide < na + && na >= et_al_min_total) { + result += et_al; + break; + } + if (i < na - 1) { + if (na == 2) + result += join_authors_exactly_two; + else if (i < na - 2) + result += join_authors_default; + else + result += join_authors_last_two; + } + } + } + const char *start = authors.contents(); + *end = start + authors.length(); + return start; +} + +int reference::get_nauthors() const +{ + if (nauthors < 0) { + const char *dummy; + int na; + for (na = 0; get_author(na, &dummy) != 0; na++) + ; + ((reference *)this)->nauthors = na; + } + return nauthors; +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/refer/ref.cpp b/src/preproc/refer/ref.cpp new file mode 100644 index 0000000..9e1b5e7 --- /dev/null +++ b/src/preproc/refer/ref.cpp @@ -0,0 +1,1161 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. +Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "refer.h" +#include "refid.h" +#include "ref.h" +#include "token.h" + +static const char *find_day(const char *, const char *, const char **); +static int find_month(const char *start, const char *end); +static void abbreviate_names(string &); + +#define DEFAULT_ARTICLES "the\000a\000an" + +string articles(DEFAULT_ARTICLES, sizeof(DEFAULT_ARTICLES)); + +// Multiple occurrences of fields are separated by FIELD_SEPARATOR. +const char FIELD_SEPARATOR = '\0'; + +const char MULTI_FIELD_NAMES[] = "AE"; +const char *AUTHOR_FIELDS = "AQ"; + +enum { OTHER, JOURNAL_ARTICLE, BOOK, ARTICLE_IN_BOOK, TECH_REPORT, BELL_TM }; + +const char *reference_types[] = { + "other", + "journal-article", + "book", + "article-in-book", + "tech-report", + "bell-tm", +}; + +static string temp_fields[256]; + +reference::reference(const char *start, int len, reference_id *ridp) +: h(0), merged(0), no(-1), field(0), nfields(0), label_ptr(0), + computed_authors(0), last_needed_author(-1), nauthors(-1) +{ + int i; + for (i = 0; i < 256; i++) + field_index[i] = NULL_FIELD_INDEX; + if (ridp) + rid = *ridp; + if (start == 0) + return; + if (len <= 0) + return; + const char *end = start + len; + const char *ptr = start; + assert(*ptr == '%'); + while (ptr < end) { + if (ptr + 1 < end && ptr[1] != '\0' + && ((ptr[1] != '%' && ptr[1] == annotation_field) + || (ptr + 2 < end && ptr[1] == '%' && ptr[2] != '\0' + && discard_fields.search(ptr[2]) < 0))) { + if (ptr[1] == '%') + ptr++; + string &f = temp_fields[(unsigned char)ptr[1]]; + ptr += 2; + while (ptr < end && csspace(*ptr)) + ptr++; + for (;;) { + for (;;) { + if (ptr >= end) { + f += '\n'; + break; + } + f += *ptr; + if (*ptr++ == '\n') + break; + } + if (ptr >= end || *ptr == '%') + break; + } + } + else if (ptr + 1 < end && ptr[1] != '\0' && ptr[1] != '%' + && discard_fields.search(ptr[1]) < 0) { + string &f = temp_fields[(unsigned char)ptr[1]]; + if (f.length() > 0) { + if (strchr(MULTI_FIELD_NAMES, ptr[1]) != 0) + f += FIELD_SEPARATOR; + else + f.clear(); + } + ptr += 2; + if (ptr < end) { + if (*ptr == ' ') + ptr++; + for (;;) { + const char *p = ptr; + while (ptr < end && *ptr != '\n') + ptr++; + // strip trailing white space + const char *q = ptr; + while (q > p && q[-1] != '\n' && csspace(q[-1])) + q--; + while (p < q) + f += *p++; + if (ptr >= end) + break; + ptr++; + if (ptr >= end) + break; + if (*ptr == '%') + break; + f += ' '; + } + } + } + else { + // skip this field + for (;;) { + while (ptr < end && *ptr++ != '\n') + ; + if (ptr >= end || *ptr == '%') + break; + } + } + } + for (i = 0; i < 256; i++) + if (temp_fields[i].length() > 0) + nfields++; + field = new string[nfields]; + int j = 0; + for (i = 0; i < 256; i++) + if (temp_fields[i].length() > 0) { + field[j].move(temp_fields[i]); + if (abbreviate_fields.search(i) >= 0) + abbreviate_names(field[j]); + field_index[i] = j; + j++; + } +} + +reference::~reference() +{ + if (nfields > 0) + delete[] field; +} + +// ref is the inline, this is the database ref + +void reference::merge(reference &ref) +{ + int i; + for (i = 0; i < 256; i++) + if (field_index[i] != NULL_FIELD_INDEX) + temp_fields[i].move(field[field_index[i]]); + for (i = 0; i < 256; i++) + if (ref.field_index[i] != NULL_FIELD_INDEX) + temp_fields[i].move(ref.field[ref.field_index[i]]); + for (i = 0; i < 256; i++) + field_index[i] = NULL_FIELD_INDEX; + int old_nfields = nfields; + nfields = 0; + for (i = 0; i < 256; i++) + if (temp_fields[i].length() > 0) + nfields++; + if (nfields != old_nfields) { + if (old_nfields > 0) + delete[] field; + field = new string[nfields]; + } + int j = 0; + for (i = 0; i < 256; i++) + if (temp_fields[i].length() > 0) { + field[j].move(temp_fields[i]); + field_index[i] = j; + j++; + } + merged = 1; +} + +void reference::insert_field(unsigned char c, string &s) +{ + assert(s.length() > 0); + if (field_index[c] != NULL_FIELD_INDEX) { + field[field_index[c]].move(s); + return; + } + assert(field_index[c] == NULL_FIELD_INDEX); + string *old_field = field; + field = new string[nfields + 1]; + int pos = 0; + int i; + for (i = 0; i < int(c); i++) + if (field_index[i] != NULL_FIELD_INDEX) + pos++; + for (i = 0; i < pos; i++) + field[i].move(old_field[i]); + field[pos].move(s); + for (i = pos; i < nfields; i++) + field[i + 1].move(old_field[i]); + if (nfields > 0) + delete[] old_field; + nfields++; + field_index[c] = pos; + for (i = c + 1; i < 256; i++) + if (field_index[i] != NULL_FIELD_INDEX) + field_index[i] += 1; +} + +void reference::delete_field(unsigned char c) +{ + if (field_index[c] == NULL_FIELD_INDEX) + return; + string *old_field = field; + field = new string[nfields - 1]; + int i; + for (i = 0; i < int(field_index[c]); i++) + field[i].move(old_field[i]); + for (i = field_index[c]; i < nfields - 1; i++) + field[i].move(old_field[i + 1]); + if (nfields > 0) + delete[] old_field; + nfields--; + field_index[c] = NULL_FIELD_INDEX; + for (i = c + 1; i < 256; i++) + if (field_index[i] != NULL_FIELD_INDEX) + field_index[i] -= 1; +} + +void reference::compute_hash_code() +{ + if (!rid.is_null()) + h = rid.hash(); + else { + h = 0; + for (int i = 0; i < nfields; i++) + if (field[i].length() > 0) { + h <<= 4; + h ^= hash_string(field[i].contents(), field[i].length()); + } + } +} + +void reference::set_number(int n) +{ + no = n; +} + +const char SORT_SEP = '\001'; +const char SORT_SUB_SEP = '\002'; +const char SORT_SUB_SUB_SEP = '\003'; + +// sep specifies additional word separators + +void sortify_words(const char *s, const char *end, const char *sep, + string &result) +{ + int non_empty = 0; + int need_separator = 0; + for (;;) { + const char *token_start = s; + if (!get_token(&s, end)) + break; + if ((s - token_start == 1 + && (*token_start == ' ' + || *token_start == '\n' + || (sep && *token_start != '\0' + && strchr(sep, *token_start) != 0))) + || (s - token_start == 2 + && token_start[0] == '\\' && token_start[1] == ' ')) { + if (non_empty) + need_separator = 1; + } + else { + const token_info *ti = lookup_token(token_start, s); + if (ti->sortify_non_empty(token_start, s)) { + if (need_separator) { + result += ' '; + need_separator = 0; + } + ti->sortify(token_start, s, result); + non_empty = 1; + } + } + } +} + +void sortify_word(const char *s, const char *end, string &result) +{ + for (;;) { + const char *token_start = s; + if (!get_token(&s, end)) + break; + const token_info *ti = lookup_token(token_start, s); + ti->sortify(token_start, s, result); + } +} + +void sortify_other(const char *s, int len, string &key) +{ + sortify_words(s, s + len, 0, key); +} + +void sortify_title(const char *s, int len, string &key) +{ + const char *end = s + len; + for (; s < end && (*s == ' ' || *s == '\n'); s++) + ; + const char *ptr = s; + for (;;) { + const char *token_start = ptr; + if (!get_token(&ptr, end)) + break; + if (ptr - token_start == 1 + && (*token_start == ' ' || *token_start == '\n')) + break; + } + if (ptr < end) { + unsigned int first_word_len = ptr - s - 1; + const char *ae = articles.contents() + articles.length(); + for (const char *a = articles.contents(); + a < ae; + a = strchr(a, '\0') + 1) + if (first_word_len == strlen(a)) { + unsigned int j; + for (j = 0; j < first_word_len; j++) + if (a[j] != cmlower(s[j])) + break; + if (j >= first_word_len) { + s = ptr; + for (; s < end && (*s == ' ' || *s == '\n'); s++) + ; + break; + } + } + } + sortify_words(s, end, 0, key); +} + +void sortify_name(const char *s, int len, string &key) +{ + const char *last_name_end; + const char *last_name = find_last_name(s, s + len, &last_name_end); + sortify_word(last_name, last_name_end, key); + key += SORT_SUB_SUB_SEP; + if (last_name > s) + sortify_words(s, last_name, ".", key); + key += SORT_SUB_SUB_SEP; + if (last_name_end < s + len) + sortify_words(last_name_end, s + len, ".,", key); +} + +void sortify_date(const char *s, int len, string &key) +{ + const char *year_end; + const char *year_start = find_year(s, s + len, &year_end); + if (!year_start) { + // Things without years are often 'forthcoming', so it makes sense + // that they sort after things with explicit years. + key += 'A'; + sortify_words(s, s + len, 0, key); + return; + } + int n = year_end - year_start; + while (n < 4) { + key += '0'; + n++; + } + while (year_start < year_end) + key += *year_start++; + int m = find_month(s, s + len); + if (m < 0) + return; + key += 'A' + m; + const char *day_end; + const char *day_start = find_day(s, s + len, &day_end); + if (!day_start) + return; + if (day_end - day_start == 1) + key += '0'; + while (day_start < day_end) + key += *day_start++; +} + +// SORT_{SUB,SUB_SUB}_SEP can creep in from use of @ in label specification. + +void sortify_label(const char *s, int len, string &key) +{ + const char *end = s + len; + for (;;) { + const char *ptr; + for (ptr = s; + ptr < end && *ptr != SORT_SUB_SEP && *ptr != SORT_SUB_SUB_SEP; + ptr++) + ; + if (ptr > s) + sortify_words(s, ptr, 0, key); + s = ptr; + if (s >= end) + break; + key += *s++; + } +} + +void reference::compute_sort_key() +{ + if (sort_fields.length() == 0) + return; + sort_fields += '\0'; + const char *sf = sort_fields.contents(); + int first_time = 1; + while (*sf != '\0') { + if (!first_time) + sort_key += SORT_SEP; + first_time = 0; + char f = *sf++; + int n = 1; + if (*sf == '+') { + n = INT_MAX; + sf++; + } + else if (csdigit(*sf)) { + char *ptr; + long l = strtol(sf, &ptr, 10); + if (l == 0 && ptr == sf) + ; + else { + sf = ptr; + if (l < 0) { + n = 1; + } + else { + n = int(l); + } + } + } + if (f == '.') + sortify_label(label.contents(), label.length(), sort_key); + else if (f == AUTHOR_FIELDS[0]) + sortify_authors(n, sort_key); + else + sortify_field(f, n, sort_key); + } + sort_fields.set_length(sort_fields.length() - 1); +} + +void reference::sortify_authors(int n, string &result) const +{ + for (const char *p = AUTHOR_FIELDS; *p != '\0'; p++) + if (contains_field(*p)) { + sortify_field(*p, n, result); + return; + } + sortify_field(AUTHOR_FIELDS[0], n, result); +} + +void reference::canonicalize_authors(string &result) const +{ + int len = result.length(); + sortify_authors(INT_MAX, result); + if (result.length() > len) + result += SORT_SUB_SEP; +} + +void reference::sortify_field(unsigned char f, int n, string &result) const +{ + typedef void (*sortify_t)(const char *, int, string &); + sortify_t sortifier = sortify_other; + switch (f) { + case 'A': + case 'E': + sortifier = sortify_name; + break; + case 'D': + sortifier = sortify_date; + break; + case 'B': + case 'J': + case 'T': + sortifier = sortify_title; + break; + } + int fi = field_index[(unsigned char)f]; + if (fi != NULL_FIELD_INDEX) { + string &str = field[fi]; + const char *start = str.contents(); + const char *end = start + str.length(); + for (int i = 0; i < n && start < end; i++) { + const char *p = start; + while (start < end && *start != FIELD_SEPARATOR) + start++; + if (i > 0) + result += SORT_SUB_SEP; + (*sortifier)(p, start - p, result); + if (start < end) + start++; + } + } +} + +int compare_reference(const reference &r1, const reference &r2) +{ + assert(r1.no >= 0); + assert(r2.no >= 0); + const char *s1 = r1.sort_key.contents(); + int n1 = r1.sort_key.length(); + const char *s2 = r2.sort_key.contents(); + int n2 = r2.sort_key.length(); + for (; n1 > 0 && n2 > 0; --n1, --n2, ++s1, ++s2) + if (*s1 != *s2) + return (int)(unsigned char)*s1 - (int)(unsigned char)*s2; + if (n2 > 0) + return -1; + if (n1 > 0) + return 1; + return r1.no - r2.no; +} + +int same_reference(const reference &r1, const reference &r2) +{ + if (!r1.rid.is_null() && r1.rid == r2.rid) + return 1; + if (r1.h != r2.h) + return 0; + if (r1.nfields != r2.nfields) + return 0; + int i = 0; + for (i = 0; i < 256; i++) + if (r1.field_index != r2.field_index) + return 0; + for (i = 0; i < r1.nfields; i++) + if (r1.field[i] != r2.field[i]) + return 0; + return 1; +} + +const char *find_last_name(const char *start, const char *end, + const char **endp) +{ + const char *ptr = start; + const char *last_word = start; + for (;;) { + const char *token_start = ptr; + if (!get_token(&ptr, end)) + break; + if (ptr - token_start == 1) { + if (*token_start == ',') { + *endp = token_start; + return last_word; + } + else if (*token_start == ' ' || *token_start == '\n') { + if (ptr < end && *ptr != ' ' && *ptr != '\n') + last_word = ptr; + } + } + } + *endp = end; + return last_word; +} + +void abbreviate_name(const char *ptr, const char *end, string &result) +{ + const char *last_name_end; + const char *last_name_start = find_last_name(ptr, end, &last_name_end); + int need_period = 0; + for (;;) { + const char *token_start = ptr; + if (!get_token(&ptr, last_name_start)) + break; + const token_info *ti = lookup_token(token_start, ptr); + if (need_period) { + if ((ptr - token_start == 1 && *token_start == ' ') + || (ptr - token_start == 2 && token_start[0] == '\\' + && token_start[1] == ' ')) + continue; + if (ti->is_upper()) + result += period_before_initial; + else + result += period_before_other; + need_period = 0; + } + result.append(token_start, ptr - token_start); + if (ti->is_upper()) { + const char *lower_ptr = ptr; + int first_token = 1; + for (;;) { + token_start = ptr; + if (!get_token(&ptr, last_name_start)) + break; + if ((ptr - token_start == 1 && *token_start == ' ') + || (ptr - token_start == 2 && token_start[0] == '\\' + && token_start[1] == ' ')) + break; + ti = lookup_token(token_start, ptr); + if (ti->is_hyphen()) { + const char *ptr1 = ptr; + if (get_token(&ptr1, last_name_start)) { + ti = lookup_token(ptr, ptr1); + if (ti->is_upper()) { + result += period_before_hyphen; + result.append(token_start, ptr1 - token_start); + ptr = ptr1; + } + } + } + else if (ti->is_upper()) { + // MacDougal -> MacD. + result.append(lower_ptr, ptr - lower_ptr); + lower_ptr = ptr; + first_token = 1; + } + else if (first_token && ti->is_accent()) { + result.append(token_start, ptr - token_start); + lower_ptr = ptr; + } + first_token = 0; + } + need_period = 1; + } + } + if (need_period) + result += period_before_last_name; + result.append(last_name_start, end - last_name_start); +} + +static void abbreviate_names(string &result) +{ + string str; + str.move(result); + const char *ptr = str.contents(); + const char *end = ptr + str.length(); + while (ptr < end) { + const char *name_end = (char *)memchr(ptr, FIELD_SEPARATOR, end - ptr); + if (name_end == 0) + name_end = end; + abbreviate_name(ptr, name_end, result); + if (name_end >= end) + break; + ptr = name_end + 1; + result += FIELD_SEPARATOR; + } +} + +void reverse_name(const char *ptr, const char *name_end, string &result) +{ + const char *last_name_end; + const char *last_name_start = find_last_name(ptr, name_end, &last_name_end); + result.append(last_name_start, last_name_end - last_name_start); + while (last_name_start > ptr + && (last_name_start[-1] == ' ' || last_name_start[-1] == '\n')) + last_name_start--; + if (last_name_start > ptr) { + result += ", "; + result.append(ptr, last_name_start - ptr); + } + if (last_name_end < name_end) + result.append(last_name_end, name_end - last_name_end); +} + +void reverse_names(string &result, int n) +{ + if (n <= 0) + return; + string str; + str.move(result); + const char *ptr = str.contents(); + const char *end = ptr + str.length(); + while (ptr < end) { + if (--n < 0) { + result.append(ptr, end - ptr); + break; + } + const char *name_end = (char *)memchr(ptr, FIELD_SEPARATOR, end - ptr); + if (name_end == 0) + name_end = end; + reverse_name(ptr, name_end, result); + if (name_end >= end) + break; + ptr = name_end + 1; + result += FIELD_SEPARATOR; + } +} + +// Return number of field separators. + +int join_fields(string &f) +{ + const char *ptr = f.contents(); + int len = f.length(); + int nfield_seps = 0; + int j; + for (j = 0; j < len; j++) + if (ptr[j] == FIELD_SEPARATOR) + nfield_seps++; + if (nfield_seps == 0) + return 0; + string temp; + int field_seps_left = nfield_seps; + for (j = 0; j < len; j++) { + if (ptr[j] == FIELD_SEPARATOR) { + if (nfield_seps == 1) + temp += join_authors_exactly_two; + else if (--field_seps_left == 0) + temp += join_authors_last_two; + else + temp += join_authors_default; + } + else + temp += ptr[j]; + } + f = temp; + return nfield_seps; +} + +void uppercase(const char *start, const char *end, string &result) +{ + for (;;) { + const char *token_start = start; + if (!get_token(&start, end)) + break; + const token_info *ti = lookup_token(token_start, start); + ti->upper_case(token_start, start, result); + } +} + +void lowercase(const char *start, const char *end, string &result) +{ + for (;;) { + const char *token_start = start; + if (!get_token(&start, end)) + break; + const token_info *ti = lookup_token(token_start, start); + ti->lower_case(token_start, start, result); + } +} + +void capitalize(const char *ptr, const char *end, string &result) +{ + int in_small_point_size = 0; + for (;;) { + const char *start = ptr; + if (!get_token(&ptr, end)) + break; + const token_info *ti = lookup_token(start, ptr); + const char *char_end = ptr; + int is_lower = ti->is_lower(); + if ((is_lower || ti->is_upper()) && get_token(&ptr, end)) { + const token_info *ti2 = lookup_token(char_end, ptr); + if (!ti2->is_accent()) + ptr = char_end; + } + if (is_lower) { + if (!in_small_point_size) { + result += "\\s-2"; + in_small_point_size = 1; + } + ti->upper_case(start, char_end, result); + result.append(char_end, ptr - char_end); + } + else { + if (in_small_point_size) { + result += "\\s+2"; + in_small_point_size = 0; + } + result.append(start, ptr - start); + } + } + if (in_small_point_size) + result += "\\s+2"; +} + +void capitalize_field(string &str) +{ + string temp; + capitalize(str.contents(), str.contents() + str.length(), temp); + str.move(temp); +} + +int is_terminated(const char *ptr, const char *end) +{ + const char *last_token = end; + for (;;) { + const char *p = ptr; + if (!get_token(&ptr, end)) + break; + last_token = p; + } + return end - last_token == 1 + && (*last_token == '.' || *last_token == '!' || *last_token == '?'); +} + +void reference::output(FILE *fp) +{ + fputs(".]-\n", fp); + for (int i = 0; i < 256; i++) + if (field_index[i] != NULL_FIELD_INDEX && i != annotation_field) { + string &f = field[field_index[i]]; + if (!csdigit(i)) { + int j = reverse_fields.search(i); + if (j >= 0) { + int n; + int len = reverse_fields.length(); + if (++j < len && csdigit(reverse_fields[j])) { + n = reverse_fields[j] - '0'; + for (++j; j < len && csdigit(reverse_fields[j]); j++) + // should check for overflow + n = n*10 + reverse_fields[j] - '0'; + } + else + n = INT_MAX; + reverse_names(f, n); + } + } + int is_multiple = join_fields(f) > 0; + if (capitalize_fields.search(i) >= 0) + capitalize_field(f); + if (memchr(f.contents(), '\n', f.length()) == 0) { + fprintf(fp, ".ds [%c ", i); + if (f[0] == ' ' || f[0] == '\\' || f[0] == '"') + putc('"', fp); + put_string(f, fp); + putc('\n', fp); + } + else { + fprintf(fp, ".de [%c\n", i); + put_string(f, fp); + fputs("..\n", fp); + } + if (i == 'P') { + int multiple_pages = 0; + const char *s = f.contents(); + const char *end = f.contents() + f.length(); + for (;;) { + const char *token_start = s; + if (!get_token(&s, end)) + break; + const token_info *ti = lookup_token(token_start, s); + if (ti->is_hyphen() || ti->is_range_sep()) { + multiple_pages = 1; + break; + } + } + fprintf(fp, ".nr [P %d\n", multiple_pages); + } + else if (i == 'E') + fprintf(fp, ".nr [E %d\n", is_multiple); + } + for (const char *p = "TAO"; *p; p++) { + int fi = field_index[(unsigned char)*p]; + if (fi != NULL_FIELD_INDEX) { + string &f = field[fi]; + fprintf(fp, ".nr [%c %d\n", *p, + is_terminated(f.contents(), f.contents() + f.length())); + } + } + int t = classify(); + fprintf(fp, ".][ %d %s\n", t, reference_types[t]); + if (annotation_macro.length() > 0 && annotation_field >= 0 + && field_index[annotation_field] != NULL_FIELD_INDEX) { + putc('.', fp); + put_string(annotation_macro, fp); + putc('\n', fp); + put_string(field[field_index[annotation_field]], fp); + } +} + +void reference::print_sort_key_comment(FILE *fp) +{ + fputs(".\\\"", fp); + put_string(sort_key, fp); + putc('\n', fp); +} + +const char *find_year(const char *start, const char *end, const char **endp) +{ + for (;;) { + while (start < end && !csdigit(*start)) + start++; + const char *ptr = start; + if (start == end) + break; + while (ptr < end && csdigit(*ptr)) + ptr++; + if (ptr - start == 4 || ptr - start == 3 + || (ptr - start == 2 + && (start[0] >= '4' || (start[0] == '3' && start[1] >= '2')))) { + *endp = ptr; + return start; + } + start = ptr; + } + return 0; +} + +static const char *find_day(const char *start, const char *end, + const char **endp) +{ + for (;;) { + while (start < end && !csdigit(*start)) + start++; + const char *ptr = start; + if (start == end) + break; + while (ptr < end && csdigit(*ptr)) + ptr++; + if ((ptr - start == 1 && start[0] != '0') + || (ptr - start == 2 && + (start[0] == '1' + || start[0] == '2' + || (start[0] == '3' && start[1] <= '1') + || (start[0] == '0' && start[1] != '0')))) { + *endp = ptr; + return start; + } + start = ptr; + } + return 0; +} + +static int find_month(const char *start, const char *end) +{ + static const char *months[] = { + "january", + "february", + "march", + "april", + "may", + "june", + "july", + "august", + "september", + "october", + "november", + "december", + }; + for (;;) { + while (start < end && !csalpha(*start)) + start++; + const char *ptr = start; + if (start == end) + break; + while (ptr < end && csalpha(*ptr)) + ptr++; + if (ptr - start >= 3) { + for (unsigned int i = 0; i < sizeof(months)/sizeof(months[0]); i++) { + const char *q = months[i]; + const char *p = start; + for (; p < ptr; p++, q++) + if (cmlower(*p) != *q) + break; + if (p >= ptr) + return i; + } + } + start = ptr; + } + return -1; +} + +int reference::contains_field(char c) const +{ + return field_index[(unsigned char)c] != NULL_FIELD_INDEX; +} + +int reference::classify() +{ + if (contains_field('J')) + return JOURNAL_ARTICLE; + if (contains_field('B')) + return ARTICLE_IN_BOOK; + if (contains_field('G')) + return TECH_REPORT; + if (contains_field('R')) + return TECH_REPORT; + if (contains_field('I')) + return BOOK; + if (contains_field('M')) + return BELL_TM; + return OTHER; +} + +const char *reference::get_year(const char **endp) const +{ + if (field_index['D'] != NULL_FIELD_INDEX) { + string &date = field[field_index['D']]; + const char *start = date.contents(); + const char *end = start + date.length(); + return find_year(start, end, endp); + } + else + return 0; +} + +const char *reference::get_field(unsigned char c, const char **endp) const +{ + if (field_index[c] != NULL_FIELD_INDEX) { + string &f = field[field_index[c]]; + const char *start = f.contents(); + *endp = start + f.length(); + return start; + } + else + return 0; +} + +const char *reference::get_date(const char **endp) const +{ + return get_field('D', endp); +} + +const char *nth_field(int i, const char *start, const char **endp) +{ + while (--i >= 0) { + start = (char *)memchr(start, FIELD_SEPARATOR, *endp - start); + if (!start) + return 0; + start++; + } + const char *e = (char *)memchr(start, FIELD_SEPARATOR, *endp - start); + if (e) + *endp = e; + return start; +} + +const char *reference::get_author(int i, const char **endp) const +{ + for (const char *f = AUTHOR_FIELDS; *f != '\0'; f++) { + const char *start = get_field(*f, endp); + if (start) { + if (strchr(MULTI_FIELD_NAMES, *f) != 0) + return nth_field(i, start, endp); + else if (i == 0) + return start; + else + return 0; + } + } + return 0; +} + +const char *reference::get_author_last_name(int i, const char **endp) const +{ + for (const char *f = AUTHOR_FIELDS; *f != '\0'; f++) { + const char *start = get_field(*f, endp); + if (start) { + if (strchr(MULTI_FIELD_NAMES, *f) != 0) { + start = nth_field(i, start, endp); + if (!start) + return 0; + } + if (*f == 'A') + return find_last_name(start, *endp, endp); + else + return start; + } + } + return 0; +} + +void reference::set_date(string &d) +{ + if (d.length() == 0) + delete_field('D'); + else + insert_field('D', d); +} + +int same_year(const reference &r1, const reference &r2) +{ + const char *ye1; + const char *ys1 = r1.get_year(&ye1); + const char *ye2; + const char *ys2 = r2.get_year(&ye2); + if (ys1 == 0) { + if (ys2 == 0) + return same_date(r1, r2); + else + return 0; + } + else if (ys2 == 0) + return 0; + else if (ye1 - ys1 != ye2 - ys2) + return 0; + else + return memcmp(ys1, ys2, ye1 - ys1) == 0; +} + +int same_date(const reference &r1, const reference &r2) +{ + const char *e1; + const char *s1 = r1.get_date(&e1); + const char *e2; + const char *s2 = r2.get_date(&e2); + if (s1 == 0) + return s2 == 0; + else if (s2 == 0) + return 0; + else if (e1 - s1 != e2 - s2) + return 0; + else + return memcmp(s1, s2, e1 - s1) == 0; +} + +const char *reference::get_sort_field(int i, int si, int ssi, + const char **endp) const +{ + const char *start = sort_key.contents(); + const char *end = start + sort_key.length(); + if (i < 0) { + *endp = end; + return start; + } + while (--i >= 0) { + start = (char *)memchr(start, SORT_SEP, end - start); + if (!start) + return 0; + start++; + } + const char *e = (char *)memchr(start, SORT_SEP, end - start); + if (e) + end = e; + if (si < 0) { + *endp = end; + return start; + } + while (--si >= 0) { + start = (char *)memchr(start, SORT_SUB_SEP, end - start); + if (!start) + return 0; + start++; + } + e = (char *)memchr(start, SORT_SUB_SEP, end - start); + if (e) + end = e; + if (ssi < 0) { + *endp = end; + return start; + } + while (--ssi >= 0) { + start = (char *)memchr(start, SORT_SUB_SUB_SEP, end - start); + if (!start) + return 0; + start++; + } + e = (char *)memchr(start, SORT_SUB_SUB_SEP, end - start); + if (e) + end = e; + *endp = end; + return start; +} + diff --git a/src/preproc/refer/ref.h b/src/preproc/refer/ref.h new file mode 100644 index 0000000..1205a28 --- /dev/null +++ b/src/preproc/refer/ref.h @@ -0,0 +1,127 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +// declarations to avoid friend name injection problems +int compare_reference(const reference &, const reference &); +int same_reference(const reference &, const reference &); +int same_year(const reference &, const reference &); +int same_date(const reference &, const reference &); +int same_author_last_name(const reference &, const reference &, int); +int same_author_name(const reference &, const reference &, int); + +struct label_info; + +enum label_type { NORMAL_LABEL, SHORT_LABEL }; +const int N_LABEL_TYPES = 2; + +struct substring_position { + int start; + int length; + substring_position() : start(-1) { } +}; + +class int_set { + string v; +public: + int_set() { } + void set(int i); + int get(int i) const; +}; + +class reference { +private: + unsigned h; + reference_id rid; + int merged; + string sort_key; + int no; + string *field; + int nfields; + unsigned char field_index[256]; + enum { NULL_FIELD_INDEX = 255 }; + string label; + substring_position separator_pos; + string short_label; + substring_position short_separator_pos; + label_info *label_ptr; + string authors; + int computed_authors; + int last_needed_author; + int nauthors; + int_set last_name_unambiguous; + + int contains_field(char) const; + void insert_field(unsigned char, string &s); + void delete_field(unsigned char); + void set_date(string &); + const char *get_sort_field(int i, int si, int ssi, const char **endp) const; + int merge_labels_by_parts(reference **, int, label_type, string &); + int merge_labels_by_number(reference **, int, label_type, string &); +public: + reference(const char * = 0, int = -1, reference_id * = 0); + ~reference(); + void output(FILE *); + void print_sort_key_comment(FILE *); + void set_number(int); + int get_number() const { return no; } + unsigned hash() const { return h; } + const string &get_label(label_type type) const; + const substring_position &get_separator_pos(label_type) const; + int is_merged() const { return merged; } + void compute_sort_key(); + void compute_hash_code(); + void pre_compute_label(); + void compute_label(); + void immediate_compute_label(); + int classify(); + void merge(reference &); + int merge_labels(reference **, int, label_type, string &); + int get_nauthors() const; + void need_author(int); + void set_last_name_unambiguous(int); + void sortify_authors(int, string &) const; + void canonicalize_authors(string &) const; + void sortify_field(unsigned char, int, string &) const; + const char *get_author(int, const char **) const; + const char *get_author_last_name(int, const char **) const; + const char *get_date(const char **) const; + const char *get_year(const char **) const; + const char *get_field(unsigned char, const char **) const; + const label_info *get_label_ptr() const { return label_ptr; } + const char *get_authors(const char **) const; + // for sorting + friend int compare_reference(const reference &r1, const reference &r2); + // for merging + friend int same_reference(const reference &, const reference &); + friend int same_year(const reference &, const reference &); + friend int same_date(const reference &, const reference &); + friend int same_author_last_name(const reference &, const reference &, int); + friend int same_author_name(const reference &, const reference &, int); +}; + +const char *find_year(const char *, const char *, const char **); +const char *find_last_name(const char *, const char *, const char **); + +const char *nth_field(int i, const char *start, const char **endp); + +void capitalize(const char *ptr, const char *end, string &result); +void reverse_name(const char *ptr, const char *end, string &result); +void uppercase(const char *ptr, const char *end, string &result); +void lowercase(const char *ptr, const char *end, string &result); +void abbreviate_name(const char *ptr, const char *end, string &result); diff --git a/src/preproc/refer/refer.1.man b/src/preproc/refer/refer.1.man new file mode 100644 index 0000000..210afe7 --- /dev/null +++ b/src/preproc/refer/refer.1.man @@ -0,0 +1,2020 @@ +.TH @g@refer @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +@g@refer \- process bibliographic references for +.I groff +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1989-2021 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_refer_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY @g@refer +.RB [ \-bCenPRS ] +.RB [ \-a\~\c +.IR n ] +.RB [ \-B +.IB field . macro\c +] +.RB [ \-c\~\c +.IR fields ] +.RB [ \-f\~\c +.IR n ] +.RB [ \-i\~\c +.IR fields ] +.RB [ \-k\~\c +.IR field ] +.RB [ \-l\~\c +.IR range-expression ] +.RB [ \-p\~\c +.IR database-file ] +.RB [ \-s\~\c +.IR fields ] +.RB [ \-t\~\c +.IR n ] +.RI [ file\~ .\|.\|.] +.YS +. +. +.SY @g@refer +.B \-\-help +.YS +. +. +.SY @g@refer +.B \-v +. +.SY @g@refer +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +The GNU implementation of +.I \%refer \" generic +is part of the +.MR groff @MAN1EXT@ +document formatting system. +. +.I @g@refer +is a +.MR @g@troff @MAN1EXT@ +preprocessor that prepares bibilographic citations by looking up +keywords specified in a +.MR roff @MAN7EXT@ +input document, +obviating the need to type such annotations, +and permitting the citation style in formatted output to be altered +independently and systematically. +. +It copies the contents of each +.I file +to the standard output stream, +except that it interprets lines between +.B .[ +and +.B .]\& +as citations to be translated into +.I groff +input, +and lines between +.B .R1 +and +.B .R2 +as instructions regarding how citations are to be processed. +. +Normally, +.I @g@refer +is not executed directly by the user, +but invoked by specifying the +.B \-R +option to +.MR groff @MAN1EXT@ . +. +If no +.I file +operands are given on the command line, +or if +.I file +is +.RB \[lq] \- \[rq], +the standard input stream is read. +. +. +.LP +Each citation specifies a reference. +. +The citation can specify a reference that is contained in a +bibliographic database by giving a set of keywords that only that +reference contains. +. +Alternatively it can specify a reference by supplying a database record +in the citation. +. +A combination of these alternatives is also possible. +. +. +.LP +For each citation, +.I @g@refer +can produce a mark in the text. +. +This mark consists of some label which can be separated from the text +and from other labels in various ways. +. +For each reference it also outputs +.MR groff @MAN7EXT@ +language commands that can be used by a macro package to produce a +formatted reference for each citation. +. +The output of +.I @g@refer +must therefore be processed using a suitable macro package, +such as +.\" .IR man , +.IR me , +.IR mm , +.IR mom , +or +.IR ms . +. +The commands to format a citation's reference can be output immediately +after the citation, +or the references may be accumulated, +and the commands output at some later point. +. +If the references are accumulated, +then multiple citations of the same reference will produce a single +formatted reference. +. +. +.LP +The interpretation of lines between +.B .R1 +and +.B .R2 +as prepreocessor commands is a feature of GNU +.IR \%refer . \" GNU +. +Documents making use of this feature can still be processed by AT&T +.I \%refer \" AT&T +just by adding the lines +. +.RS +.EX +\&.de R1 +\&.ig R2 +\&.. +.EE +.RE +. +to the beginning of the document. +. +This will cause +.MR @g@troff @MAN1EXT@ +to ignore everything between +.B .R1 +and +.BR .R2 . +. +The effect of some commands can also be achieved by options. +. +These options are supported mainly for compatibility with AT&T +.IR \%refer . \" AT&T +. +It is usually more convenient to use commands. +. +. +.LP +.I @g@refer +generates +.B .lf +requests so that file names and line numbers in messages produced by +commands that read +.I @g@refer +output will be correct; +it also interprets lines beginning with +.B .lf +so that file names and line numbers in the messages and +.B .lf +lines that it produces will be accurate even if the input has been +preprocessed by a command such as +.MR @g@soelim @MAN1EXT@ . +. +. +.\" ==================================================================== +.SS "Bibliographic databases" +.\" ==================================================================== +. +The bibliographic database is a text file consisting of records +separated by one or more blank lines. +. +Within each record fields start with a +.B % +at the beginning of a line. +. +Each field has a one character name that immediately follows the +.BR % . +It is best to use only upper and lower case letters for the names +of fields. +. +The name of the field should be followed by exactly one space, +and then by the contents of the field. +. +Empty fields are ignored. +. +The conventional meaning of each field is as follows: +. +. +.TP +.B %A +The name of an author. +. +If the name contains a suffix such as \[lq]Jr.\&\[rq], +it should be separated from the last name by a comma. +. +There can be multiple occurrences of the +.B %A +field. +. +The order is significant. +. +It is a good idea always to supply an +.B %A +field or a +.B %Q +field. +. +. +.TP +.B %B +For an article that is part of a book, +the title of the book. +. +. +.TP +.B %C +The place (city) of publication. +. +. +.TP +.B %D +The date of publication. +. +The year should be specified in full. +. +If the month is specified, +the name rather than the number of the month should be used, +but only the first three letters are required. +. +It is a good idea always to supply a +.B %D +field; +if the date is unknown, +a value such as +.B in press +or +.B unknown +can be used. +. +. +.TP +.B %E +For an article that is part of a book, +the name of an editor of the book. +. +Where the work has editors and no authors, +the names of the editors should be given as +.B %A +fields and +.RB \[lq] ,\~(ed.)\& \[rq] +or +.RB \[lq] ,\~(eds.)\& \[rq] +should be appended to the last author. +. +. +.TP +.B %G +U.S. government ordering number. +. +. +.TP +.B %I +The publisher (issuer). +. +. +.TP +.B %J +For an article in a journal, +the name of the journal. +. +. +.TP +.B %K +Keywords to be used for searching. +. +. +.TP +.B %L +Label. +. +. +.TP +.B %N +Journal issue number. +. +. +.TP +.B %O +Other information. +. +This is usually printed at the end of the reference. +. +. +.TP +.B %P +Page number. +. +A range of pages can be specified as +.IB m \- \c +.IR n . +. +. +.TP +.B %Q +The name of the author, +if the author is not a person. +. +This will only be used if there are no +.B %A +fields. +. +There can only be one +.B %Q +field. +. +. +.TP +.B %R +Technical report number. +. +. +.TP +.B %S +Series name. +. +. +.TP +.B %T +Title. +. +For an article in a book or journal, +this should be the title of the article. +. +. +.TP +.B %V +Volume number of the journal or book. +. +. +.TP +.B %X +Annotation. +. +. +.LP +For all fields except +.B %A +and +.BR %E , +if there is more than one occurrence of a particular field in a record, +only the last such field will be used. +. +. +.P +If accent strings are used, +they should follow the character to be accented. +. +This means that an +.I ms +document must call the +.B .AM +macro when it initializes. +. +Accent strings should not be quoted: +use one +.B \e +rather than two. +. +Accent strings are an obsolescent feature of the +.I me +and +.I ms +macro packages; +modern documents should use +.I groff +special character escape sequences instead; +see +.MR groff_char @MAN7EXT@ . +. +. +.\" ==================================================================== +.SS Citations +.\" ==================================================================== +. +Citations have a characteristic format. +. +.RS +.EX +.BI .[ opening-text +.I flags keywords +.I fields +.BI .] closing-text +.EE +.RE +. +. +.LP +The +.IR opening-text , +.IR closing-text , +and +.I flags +components are optional. +. +Only one of the +.I keywords +and +.I fields +components need be specified. +. +. +.LP +The +.I keywords +component says to search the bibliographic databases for a reference +that contains all the words in +.IR keywords . +. +It is an error if more than one reference is found. +. +. +.LP +The +.I fields +components specifies additional fields to replace or supplement those +specified in the reference. +. +When references are being accumulated and the +.I keywords +component is non-empty, +then additional fields should be specified only on the first occasion +that a particular reference is cited, +and will apply to all citations of that reference. +. +. +.br +.ne 2v +.LP +The +.I opening-text +and +.I closing-text +components specify strings to be used to bracket the label instead of +those in the +.B \%bracket\-label +command. +. +If either of these components is non-empty, +the strings specified in the +.B \%bracket\-label +command will not be used; +this behavior can be altered using the +.B [ +and +.B ] +flags. +. +Leading and trailing spaces are significant for these components. +. +. +.LP +The +.I flags +component is a list of non-alphanumeric characters each of which +modifies the treatment of this particular citation. +. +AT&T +.I \%refer \" AT&T +will treat these flags as part of the keywords and so will ignore them +since they are non-alphanumeric. +. +The following flags are currently recognized. +. +. +.TP +.B # +Use the label specified by the +.B \%short\-label +command, +instead of that specified by the +.B \%label +command. +. +If no short label has been specified, +the normal label will be used. +. +Typically the short label is used with author-date labels and consists +of only the date and possibly a disambiguating letter; +the +.RB \[lq] # \[rq] +is supposed to be suggestive of a numeric type of label. +. +. +.TP +.B [ +Precede +.I opening-text +with the first string specified in the +.B \%bracket\-label +command. +. +. +.TP +.B ] +Follow +.I closing-text +with the second string specified in the +.B \%bracket\-label +command. +. +. +.LP +An advantage of using the +.B [ +and +.B ] +flags rather than including the brackets in +.I opening-text +and +.I closing-text +is that +. +you can change the style of bracket used in the document just by +changing the +.B \%bracket\-label +command. +. +Another is that sorting and merging of citations will not necessarily be +inhibited if the flags are used. +. +. +.LP +If a label is to be inserted into the text, +it will be attached to the line preceding the +.B .[ +line. +. +If there is no such line, +then an extra line will be inserted before the +.B .[ +line and a warning will be given. +. +. +.LP +There is no special notation for making a citation to multiple +references. +. +Just use a sequence of citations, +one for each reference. +. +Don't put anything between the citations. +. +The labels for all the citations will be attached to the line preceding +the first citation. +. +The labels may also be sorted or merged. +. +See the description of the +.B <> +label expression, +and of the +.B \%sort\-adjacent\-labels +and +.B \%abbreviate\-label\-ranges +commands. +. +A label will not be merged if its citation has a non-empty +.I opening-text +or +.IR closing-text . +. +However, +the labels for a citation using the +.B ] +flag and without any +.I closing-text +immediately followed by a citation using the +.B [ +flag and without any +.I opening-text +may be sorted and merged +even though the first citation's +.I opening-text +or the second citation's +.I closing-text +is non-empty. +. +(If you wish to prevent this, +use the dummy character escape sequence +.B \[rs]& +as the first citation's +.IR closing-text .) +. +. +.\" ==================================================================== +.SS Commands +.\" ==================================================================== +. +Commands are contained between lines starting with +.B .R1 +and +.BR .R2 . +. +Recognition of these lines can be prevented by the +.B \-R +option. +. +When a +.B .R1 +line is recognized any accumulated references are flushed out. +. +Neither +.B .R1 +nor +.B .R2 +lines, +nor anything between them, +is output. +. +. +.P +Commands are separated by newlines or semicolons. +. +A number sign +.RB ( # ) +introduces a comment that extends to the end of the line, +but does not conceal the newline. +. +Each command is broken up into words. +. +Words are separated by spaces or tabs. +. +A word that begins with a (neutral) double quote +.RB ( \[dq] ) +extends to the next double quote that is not followed by another double +quote. +. +If there is no such double quote, +the word extends to the end of the line. +. +Pairs of double quotes in a word beginning with a double quote collapse +to one double quote. +. +Neither a number sign nor a semicolon is recognized inside double +quotes. +. +A line can be continued by ending it with a backslash +.RB \[lq] \[rs] \[rq]; +this works everywhere except after a number sign. +. +. +.LP +.ds n \fR*\fP\" +Each command +.I name +that is marked with \*n has an associated negative command +.BI no\- name +that undoes the effect of +.IR name . +. +For example, +the +.B no\-sort +command specifies that references should not be sorted. +. +The negative commands take no arguments. +. +. +.LP +In the following description each argument must be a single word; +.I field +is used for a single upper or lower case letter naming a field; +.I fields +is used for a sequence of such letters; +.I m +and +.I n +are used for a non-negative numbers; +.I string +is used for an arbitrary string; +.I file +is used for the name of a file. +. +. +.TP +.BI abbreviate\*n\~ fields\~string1\~string2\~string3\~string4 +Abbreviate the first names of +.IR fields . +. +An initial letter will be separated from another initial letter by +.IR string1 , +from the last name by +.IR string2 , +and from anything else +(such as \[lq]von\[rq] or \[lq]de\[rq]) +by +.IR string3 . +. +These default to a period followed by a space. +. +In a hyphenated first name, +the initial of the first part of the name will be separated from the +hyphen by +.IR string4 ; +this defaults to a period. +. +No attempt is made to handle any ambiguities that might +result from abbreviation. +. +Names are abbreviated before sorting and before label construction. +. +. +.TP +.BI abbreviate\-label\-ranges\*n\~ string +. +Three or more adjacent labels that refer to consecutive references +will be abbreviated to a label consisting of the first label, +followed by +.IR string , +followed by the last label. +. +This is mainly useful with numeric labels. +. +If +.I string +is omitted, +it defaults to +.RB \[lq] \- \[rq]. +. +. +.TP +.B accumulate\*n +Accumulate references instead of writing out each reference +as it is encountered. +. +Accumulated references will be written out whenever a reference +of the form +. +.RS +.RS +.EX +.B .[ +.B $LIST$ +.B .] +.EE +.RE +. +is encountered, +after all input files have been processed, +and whenever a +.B .R1 +line is recognized. +.RE +. +. +.TP +.BI annotate\*n\~ "field string" +.I field +is an annotation; +print it at the end of the reference as a paragraph preceded by the line +. +.RS +.IP +.BI . string +. +. +.LP +If +.I string +is omitted, +it will default to +.BR AP ; +if +.I field +is also omitted it will default to +.BR X . +. +Only one field can be an annotation. +.RE +. +. +.TP +.BI articles\~ string\~\c +\&.\|.\|. +Each +.I string +is a definite or indefinite article, +and should be ignored at the beginning of +.B T +fields when sorting. +. +Initially, +\[lq]a\[rq], +\[lq]an\[rq], +and +\[lq]the\[rq] are recognized as articles. +. +. +.TP +.BI bibliography\~ file\~\c +\&.\|.\|. +. +Write out all the references contained in each bibliographic database +.IR file . +. +This command should come last in an +.BR .R1 / .R2 +block. +. +. +.TP +.BI bracket\-label\~ "string1 string2 string3" +In the text, +bracket each label with +.I string1 +and +.IR string2 . +. +An occurrence of +.I string2 +immediately followed by +.I string1 +will be turned into +.IR string3 . +. +The default behavior is as follows. +. +.RS \" RS twice to get inboard of the tagged paragraph indentation. +.RS +.EX +.B bracket\-label \e*([. \e*(.] \[dq], \[dq] +.EE +.RE +.RE +. +. +.TP +.BI capitalize\~ fields +Convert +.I fields +to caps and small caps. +. +. +.TP +.B compatible\*n +Recognize +.B .R1 +and +.B .R2 +even when followed by a character other than space or newline. +. +. +.TP +.BI database\~ file\~\c +\&.\|.\|. +Search each bibliographic database +.IR file . +. +For each +.IR file , +if an index +.RI file @INDEX_SUFFIX@ +created by +.MR @g@indxbib @MAN1EXT@ +exists, +then it will be searched instead; +each index can cover multiple databases. +. +. +.TP +.BI date\-as\-label\*n\~ string +.I string +is a label expression that specifies a string with which to replace the +.B D +field after constructing the label. +. +See subsection \[lq]Label expressions\[rq] below for a description of +label expressions. +. +This command is useful if you do not want explicit labels in the +reference list, +but instead want to handle any necessary disambiguation by qualifying +the date in some way. +. +The label used in the text would typically be some combination of the +author and date. +. +In most cases you should also use the +.B \%no\-label\-in\-reference +command. +. +For example, +. +.RS \" RS twice to get inboard of the tagged paragraph indentation. +.RS +.EX +.B date\-as\-label D.+yD.y%a*D.\-y +.EE +.RE +. +would attach a disambiguating letter to the year part of the +.B D +field in the reference. +.RE +. +. +.TP +.B default\-database\*n +The default database should be searched. +. +This is the default behavior, +so the negative version of this command is more useful. +. +.I @g@refer +determines whether the default database should be searched +on the first occasion that it needs to do a search. +. +Thus a +.B \%no\-default\-database +command must be given before then, +in order to be effective. +. +. +.TP +.BI discard\*n\~ fields +When the reference is read, +.I fields +should be discarded; +no string definitions for +.I fields +will be output. +. +Initially, +.I fields +are +.BR XYZ . +. +. +.TP +.BI et\-al\*n\~ "string m n" +Control use of +.B et al.\& +in the evaluation of +.B @ +expressions in label expressions. +. +If the number of authors needed to make the author sequence unambiguous +is +.I u +and the total number of authors is +.I t +then the last +.IR t \|\-\| u +authors will be replaced by +.I string +provided that +.IR t \|\-\| u +is not less than +.I m +and +.I t +is not less than +.IR n . +. +The default behavior is as follows. +. +.RS \" RS twice to get inboard of the tagged paragraph indentation. +.RS +.EX +.B et\-al \[dq] et al\[dq] 2 3 +.EE +.RE +. +Note the absence of a dot from the end of the abbreviation, +which is arguably not correct. +. +.RI ( "Et al" [.] +is short for +.IR "et alli" , +as +.I etc.\& +is short for +.IR "et cetera".) +.RE +. +. +.TP +.BI include\~ file +Include +.I file +and interpret the contents as commands. +. +. +.TP +.BI join\-authors\~ "string1 string2 string3" +Join multiple authors together with +.IR string s. +. +When there are exactly two authors, +they will be joined with +.IR string1 . +. +When there are more than two authors, +all but the last two will be joined with +.IR string2 , +and the last two authors will be joined with +.IR string3 . +. +If +.I string3 +is omitted, +it will default to +.IR string1 ; +if +.I string2 +is also omitted it will also default to +.IR string1 . +. +For example, +. +.RS +.RS +.EX +join\-authors \[dq] and \[dq] \[dq], \[dq] \[dq], and \[dq] +.EE +.RE +. +will restore the default method for joining authors. +.RE +. +. +.TP +.B label\-in\-reference\*n +When outputting the reference, +define the string +.B [F +to be the reference's label. +. +This is the default behavior, +so the negative version of this command is more useful. +. +. +.TP +.B label\-in\-text\*n +For each reference output a label in the text. +. +The label will be separated from the surrounding text as described in +the +.B \%bracket\-label +command. +. +This is the default behavior, +so the negative version of this command is more useful. +. +. +.TP +.BI label\~ string +.I string +is a label expression describing how to label each reference. +. +. +.TP +.BI separate\-label\-second\-parts\~ string +When merging two-part labels, +separate the second part of the second label from the first label with +.IR string . +. +See the description of the +.B <> +label expression. +. +. +.TP +.B move\-punctuation\*n +In the text, +move any punctuation at the end of line past the label. +. +It is usually a good idea to give this command unless you are using +superscripted numbers as labels. +. +. +.TP +.BI reverse\*n\~ string +Reverse the fields whose names +are in +.IR string . +. +Each field name can be followed by a number which says how many such +fields should be reversed. +. +If no number is given for a field, +all such fields will be reversed. +. +. +.TP +.BI search\-ignore\*n\~ fields +While searching for keys in databases for which no index exists, +ignore the contents of +.IR fields . +. +Initially, +fields +.B XYZ +are ignored. +. +. +.TP +.BI search\-truncate\*n\~ n +Only require the first +.I n +characters of keys to be given. +. +In effect when searching for a given key words in the database are +truncated to the maximum of +.I n +and the length of the key. +. +Initially, +.I n +is\~6. +. +. +.TP +.BI short\-label\*n\~ string +.I string +is a label expression that specifies an alternative +(usually shorter) +style of label. +. +This is used when the +.B # +flag is given in the citation. +. +When using author-date style labels, +the identity of the author or authors is sometimes clear from the +context, +and so it may be desirable to omit the author or authors from the label. +. +The +.B \%short\-label +command will typically be used to specify a label containing just +a date and possibly a disambiguating letter. +. +. +.TP +.BI sort\*n\~ string +Sort references according to +.IR string . +. +References will automatically be accumulated. +. +.I string +should be a list of field names, +each followed by a number, +indicating how many fields with the name should be used for sorting. +. +.RB \[lq] + \[rq] +can be used to indicate that all the fields with the name should be +used. +. +Also +.B .\& +can be used to indicate the references should be sorted using the +(tentative) label. +. +(Subsection \[lq]Label expressions\[rq] below describes the concept of a +tentative label.) +. +. +.TP +.B sort\-adjacent\-labels\*n +Sort labels that are adjacent in the text according to their position +in the reference list. +. +This command should usually be given if the +.B \%abbreviate\-label\-ranges +command has been given, +or if the label expression contains a +.B <> +expression. +. +This will have no effect unless references are being accumulated. +. +. +.\" ==================================================================== +.SS "Label expressions" +.\" ==================================================================== +. +Label expressions can be evaluated both normally and tentatively. +. +The result of normal evaluation is used for output. +. +The result of tentative evaluation, +called the +.IR "tentative label" , +is used to gather the information that normal evaluation needs to +disambiguate the label. +. +Label expressions specified by the +.B \%date\-as\-label +and +.B \%short\-label +commands are not evaluated tentatively. +. +Normal and tentative evaluation are the same for all types of expression +other than +.BR @ , +.BR * , +and +.B % +expressions. +. +The description below applies to normal evaluation, +except where otherwise specified. +. +. +.TP +.I field +.TQ +.I field\~n +The +.IR n -th +part of +.IR field . +. +If +.I n +is omitted, +it defaults to\~1. +. +. +.TP +.BI \[aq] string \[aq] +The characters in +.I string +literally. +. +. +.TP +.B @ +All the authors joined as specified by the +.B \%join\-authors +command. +. +The whole of each author's name will be used. +. +However, +if the references are sorted by author +(that is, +the sort specification starts with +.RB \[lq] A+ \[rq]), +then authors' last names will be used instead, +provided that this does not introduce ambiguity, +and also an initial subsequence of the authors may be used instead of +all the authors, +again provided that this does not introduce ambiguity. +. +The use of only the last name for the +.IR i -th +author of some reference +is considered to be ambiguous if +there is some other reference, +such that the first +.IR i \|\-\|1 +authors of the references are the same, +the +.IR i -th +authors are not the same, +but the +.IR i -th +authors last names are the same. +. +A proper initial subsequence of the sequence of authors for some +reference is considered to be ambiguous if there is a reference with +some other sequence of authors which also has that subsequence as a +proper initial subsequence. +. +When an initial subsequence of authors is used, +the remaining authors are replaced by the string specified by the +.B \%et\-al +command; +this command may also specify additional requirements that must be +met before an initial subsequence can be used. +. +.B @ +tentatively evaluates to a canonical representation of the authors, +such that authors that compare equally for sorting purpose will have +the same representation. +. +. +.TP +.BI % n +.TQ +.B %a +.TQ +.B %A +.TQ +.B %i +.TQ +.B %I +The serial number of the reference formatted according to the +character following the +.BR % . +The serial number of a reference is\~1 plus the number of earlier +references with same tentative label as this reference. +. +These expressions tentatively evaluate to an empty string. +. +.TP +.IB expr * +If there is another reference with the same tentative label as this +reference, +then +.IR expr , +otherwise an empty string. +. +It tentatively evaluates to an empty string. +. +. +.TP +.IB expr + n +.TQ +.IB expr \- n +The first +.RB ( + ) +or last +.RB ( \- ) +.I n +upper or lower case letters or digits of +.IR expr . +. +.I roff +special characters +(such as +.BR \e(\[aq]a ) +count as a single letter. +. +Accent strings are retained but do not count towards the total. +. +. +.TP +.IB expr .l +.I expr +converted to lowercase. +. +. +.TP +.IB expr .u +.I expr +converted to uppercase. +. +. +.TP +.IB expr .c +.I expr +converted to caps and small caps. +. +. +.TP +.IB expr .r +.I expr +reversed so that the last name is first. +. +. +.TP +.IB expr .a +.I expr +with first names abbreviated. +. +Fields specified in the +.B \%abbreviate +command are abbreviated before any labels are evaluated. +. +Thus +.B .a +is useful only when you want a field to be abbreviated in a label +but not in a reference. +. +. +.TP +.IB expr .y +The year part of +.IR expr . +. +. +.TP +.IB expr .+y +The part of +.I expr +before the year, +or the whole of +.I expr +if it does not contain a year. +. +. +.TP +.IB expr .\-y +The part of +.I expr +after the year, +or an empty string if +.I expr +does not contain a year. +. +. +.TP +.IB expr .n +The last name part of +.IR expr . +. +. +.TP +.IB expr1 \[ti] expr2 +.I expr1 +except that if the last character of +.I expr1 +is +.B \- +then it will be replaced by +.IR expr2 . +. +. +.TP +.I expr1 expr2 +The concatenation of +.I expr1 +and +.IR expr2 . +. +. +.TP +.IB expr1 | expr2 +If +.I expr1 +is non-empty then +.I expr1 +otherwise +.IR expr2 . +. +. +.TP +.IB expr1 & expr2 +If +.I expr1 +is non-empty +then +.I expr2 +otherwise an empty string. +. +. +.TP +.IB expr1 ? expr2 : expr3 +If +.I expr1 +is non-empty +then +.I expr2 +otherwise +.IR expr3 . +. +. +.TP +.BI < expr > +The label is in two parts, +which are separated by +.IR expr . +. +Two adjacent two-part labels which have the same first part will be +merged by appending the second part of the second label onto the first +label separated by the string specified in the +.B \%separate\-label\-second\-parts +command +(initially, +a comma followed by a space); +the resulting label will also be a two-part label with the same first +part as before merging, +and so additional labels can be merged into it. +. +It is permissible for the first part to be empty; +this may be desirable for expressions used in the +.B \%short\-label +command. +. +. +.TP +.BI ( expr ) +The same as +.IR expr . +. +Used for grouping. +. +. +.LP +The above expressions are listed in order of precedence +(highest first); +.B & +and +.B | +have the same precedence. +. +. +.\" ==================================================================== +.SS "Macro interface" +.\" ==================================================================== +. +Each reference starts with a call to the macro +.BR ]\- . +. +The string +.B [F +will be defined to be the label for this reference, +unless the +.B \%no\-label\-in\-reference +command has been given. +. +There then follows a series of string definitions, +one for each field: +string +.BI [ X +corresponds to field +.IR X . +. +The register +.B [P +is set to\~1 if the +.B P +field contains a range of pages. +. +The +.BR [T , +.B [A +and +.B [O +registers are set to\~1 according as the +.BR T , +.B A +and +.B O +fields end with any of +.B .?!\& +(an end-of-sentence character). +. +The +.B [E +register will be set to\~1 if the +.B [E +string contains more than one name. +. +The reference is followed by a call to the +.B ][ +macro. +. +The first argument to this macro gives a number representing +the type of the reference. +. +If a reference contains a +.B J +field, +it will be classified as type\~1, +otherwise if it contains a +.B B +field, +it will be type\~3, +otherwise if it contains a +.B G +or +.B R +field it will be type\~4, +otherwise if it contains an +.B I +field it will be type\~2, +otherwise it will be type\~0. +. +The second argument is a symbolic name for the type: +.BR other , +.BR \%journal\-article , +.BR book , +.BR \%article\-in\-book , +or +.BR \%tech\-report . +. +Groups of references that have been accumulated or are produced by the +.B \%bibliography +command are preceded by a call to the +.B ]< +macro and followed by a call to the +.B ]> +macro. +. +. +.br +.ne 4v +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-\-help +displays a usage message, +while +.B \-v +and +.B \-\-version +show version information; +all exit afterward. +. +. +.TP +.B \-R +Don't recognize lines beginning with +.BR .R1 / .R2 . +. +. +.P +Other options are equivalent to +.I @g@refer +commands. +. +. +.TP 16n +.BI \-a\~ n +.B reverse +.BI A n +. +. +.TP +.B \-b +.B "\%no\-label\-in\-text; \%no\-label\-in\-reference" +. +. +.TP +.B \-B +See below. +. +. +.TP +.BI \-c\~ fields +.B capitalize +.I fields +. +. +.TP +.B \-C +.B compatible +. +. +.TP +.B \-e +.B accumulate +. +. +.TP +.BI \-f\~ n +.B \%label +.BI % n +. +. +.TP +.BI \-i\~ fields +.B search\-ignore +.I fields +. +. +.TP +.B \-k +.B \%label +.B L\[ti]%a +. +. +.TP +.BI \-k\~ field +.B \%label +.IB field \[ti]%a +. +. +.TP +.B \-l +.B \%label +.B A.nD.y%a +. +. +.TP +.BI \-l\~ m +.B \%label +.BI A.n+ m D.y%a +. +. +.TP +.BI \-l\~, n +.B \%label +.BI A.nD.y\- n %a +. +. +.TP +.BI \-l\~ m , n +.B \%label +.BI A.n+ m D.y\- n %a +. +. +.TP +.B \-n +.B \%no\-default\-database +. +. +.TP +.BI \-p\~ db-file +.B database +.I db-file +. +. +.TP +.B \-P +.B move\-punctuation +. +. +.TP +.BI \-s\~ spec +.B sort +.I spec +. +. +.TP +.B \-S +.B \%label \[dq](A.n|Q) \[aq], \[aq] (D.y|D)\[dq]; \ +\%bracket-\%label \[dq]\~(\[dq]\~)\~\[dq];\~\[dq] +. +. +.TP +.BI \-t\~ n +.B search\-truncate +.I n +. +. +.P +The +.B B +option has command equivalents with the addition that the file names +specified on the command line are processed as if they were arguments to +the +.B \%bibliography +command instead of in the normal way. +. +. +.TP 16n +.B \-B +.B "annotate X AP; \%no\-label\-in\-reference" +. +. +.TP +.BI \-B\~ field . macro +.B annotate +.I field +.IB macro ; +.B \%no\-label\-in\-reference +. +. +.\" ==================================================================== +.SH Environment +.\" ==================================================================== +. +.TP +.I REFER +If set, +overrides the default database. +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.I @DEFAULT_INDEX@ +Default database. +. +. +.TP +.RI file @INDEX_SUFFIX@ +Index files. +. +. +.TP +.I @MACRODIR@/\:refer\:.tmac +defines macros and strings facilitating integration with macro packages +that wish to support +.IR @g@refer . +. +. +.LP +.I @g@refer +uses temporary files. +. +See the +.MR groff @MAN1EXT@ +man page for details of where such files are created. +. +. +.\" ==================================================================== +.SH Bugs +.\" ==================================================================== +. +In label expressions, +.B <> +expressions are ignored inside +.BI . char +expressions. +. +. +.\" ==================================================================== +.SH Examples +.\" ==================================================================== +. +We can illustrate the operation of +.I @g@refer +with a sample bibliographic database containing one entry and a simple +.I roff +document to cite that entry. +. +. +.P +.RS +.EX +$ \c +.B cat > my\-db\-file +.B %A Daniel P.\[rs]& Friedman +.B %A Matthias Felleisen +.B %C Cambridge, Massachusetts +.B %D 1996 +.B %I The MIT Press +.B %T The Little Schemer, Fourth Edition +$ \c +.B refer -p my\-db\-file +.B Read the book +.B .[ +.B friedman +.B .] +.B on your summer vacation. +.I +\&.lf 1 \- +Read the book\[rs]*([.1\[rs]*(.] +\&.ds [F 1 +\&.]\- +\&.ds [A Daniel P. Friedman and Matthias Felleisen +\&.ds [C Cambridge, Massachusetts +\&.ds [D 1996 +\&.ds [I The MIT Press +\&.ds [T The Little Schemer, Fourth Edition +\&.nr [T 0 +\&.nr [A 0 +\&.][ 2 book +\&.lf 5 \- +on your summer vacation. +.EE +.RE +. +. +.P +The foregoing shows us that +.I @g@refer +(a) produces a label \[lq]1\[rq]; +(b) brackets that label with interpolations of the +.RB \[lq] [. \[rq] +and +.RB \[lq] .] \[rq] +strings; +(c) calls a macro +.RB \[lq] ]\- \[rq]; +(d) defines strings and registers containing the label and bibliographic +data for the reference; +(e) calls a macro +.RB \[lq] ][ \[rq]; +and (f) uses the +.B lf +request to restore the line numbers of the original input. +. +As discussed in subsection \[lq]Macro interface\[rq] above, +it is up to the document or a macro package to employ and format this +information usefully. +. +Let us see how we might turn +.MR groff_ms @MAN7EXT@ +to this task. +. +. +.P +.RS +.EX +$ \c +.B REFER=my\-db\-file groff \-R \-ms +.B .LP +.B Read the book +.B .[ +.B friedman +.B .] +.B on your summer vacation. +.B Commentary is available.\[rs]*{*\[rs]*} +.B .FS \[rs]*{*\[rs]*} +.B Space reserved for penetrating insight. +.B .FE +.EE +.RE +. +. +.LP +.IR ms 's +automatic footnote numbering mechanism is not aware of +.IR @g@refer 's +label numbering, +so we have manually specified a (superscripted) symbolic footnote for +our non-bibliographic aside. +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +\[lq]Some Applications of Inverted Indexes on the Unix System\[rq], +by M.\& E.\& Lesk, +1978, +AT&T Bell Laboratories Computing Science Technical Report No.\& 69. +. +. +.LP +.MR @g@indxbib @MAN1EXT@ , +.MR @g@lookbib @MAN1EXT@ , +.MR lkbib @MAN1EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_refer_1_man_C] +.do rr *groff_refer_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/preproc/refer/refer.am b/src/preproc/refer/refer.am new file mode 100644 index 0000000..273f334 --- /dev/null +++ b/src/preproc/refer/refer.am @@ -0,0 +1,61 @@ +# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# +# This file 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 . + +prefixexecbin_PROGRAMS += refer +refer_CPPFLAGS = $(AM_CPPFLAGS) -I $(top_srcdir)/src/preproc/refer +refer_LDADD = libbib.a libgroff.a $(LIBM) lib/libgnu.a +refer_SOURCES = \ + src/preproc/refer/command.cpp \ + src/preproc/refer/ref.cpp \ + src/preproc/refer/refer.cpp \ + src/preproc/refer/token.cpp \ + src/preproc/refer/label.ypp \ + src/preproc/refer/refer.h \ + src/preproc/refer/ref.h \ + src/preproc/refer/token.h \ + src/preproc/refer/command.h + +PREFIXMAN1 += src/preproc/refer/refer.1 +EXTRA_DIST += \ + src/preproc/refer/TODO \ + src/preproc/refer/refer.1.man + +# Since refer_CPPFLAGS was set, all .o files have a 'refer-' prefix. +src/preproc/refer/refer-command.$(OBJEXT): defs.h +src/preproc/refer/refer-ref.$(OBJEXT): defs.h +src/preproc/refer/refer-refer.$(OBJEXT): defs.h +src/preproc/refer/refer-token.$(OBJEXT): defs.h +src/preproc/refer/refer-label.$(OBJEXT): defs.h + +MAINTAINERCLEANFILES += \ + src/preproc/refer/label.cpp \ + src/preproc/refer/label.hpp \ + src/preproc/refer/label.output + +refer_TESTS = \ + src/preproc/refer/tests/report-correct-line-numbers.sh +TESTS += $(refer_TESTS) +EXTRA_DIST += \ + $(refer_TESTS) \ + src/preproc/refer/tests/artifacts/62124.bib + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/preproc/refer/refer.cpp b/src/preproc/refer/refer.cpp new file mode 100644 index 0000000..a5c291e --- /dev/null +++ b/src/preproc/refer/refer.cpp @@ -0,0 +1,1267 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "refer.h" +#include "refid.h" +#include "ref.h" +#include "token.h" +#include "search.h" +#include "command.h" + +extern "C" const char *Version_string; + +const char PRE_LABEL_MARKER = '\013'; +const char POST_LABEL_MARKER = '\014'; +const char LABEL_MARKER = '\015'; // label_type is added on + +#define FORCE_LEFT_BRACKET 04 +#define FORCE_RIGHT_BRACKET 010 + +static FILE *outfp = stdout; + +string capitalize_fields; +string reverse_fields; +string abbreviate_fields; +string period_before_last_name = ". "; +string period_before_initial = "."; +string period_before_hyphen = ""; +string period_before_other = ". "; +string sort_fields; +int annotation_field = -1; +string annotation_macro; +string discard_fields = "XYZ"; +string pre_label = "\\*([."; +string post_label = "\\*(.]"; +string sep_label = ", "; +int have_bibliography = 0; +int accumulate = 0; +int move_punctuation = 0; +int abbreviate_label_ranges = 0; +string label_range_indicator; +int label_in_text = 1; +int label_in_reference = 1; +int date_as_label = 0; +int sort_adjacent_labels = 0; +// Join exactly two authors with this. +string join_authors_exactly_two = " and "; +// When there are more than two authors join the last two with this. +string join_authors_last_two = ", and "; +// Otherwise join authors with this. +string join_authors_default = ", "; +string separate_label_second_parts = ", "; +// Use this string to represent that there are other authors. +string et_al = " et al"; +// Use et al only if it can replace at least this many authors. +int et_al_min_elide = 2; +// Use et al only if the total number of authors is at least this. +int et_al_min_total = 3; + + +int compatible_flag = 0; + +int short_label_flag = 0; + +static bool recognize_R1_R2 = true; + +search_list database_list; +int search_default = 1; +static int default_database_loaded = 0; + +static reference **citation = 0; +static int ncitations = 0; +static int citation_max = 0; + +static reference **reference_hash_table = 0; +static int hash_table_size; +static int nreferences = 0; + +static int need_syncing = 0; +string pending_line; +string pending_lf_lines; + +static void output_pending_line(); +static unsigned immediately_handle_reference(const string &); +static void immediately_output_references(); +static unsigned store_reference(const string &); +static void divert_to_temporary_file(); +static reference *make_reference(const string &, unsigned *); +static void usage(FILE *stream); +static void do_file(const char *); +static void split_punct(string &line, string &punct); +static void output_citation_group(reference **v, int n, label_type, + FILE *fp); +static void possibly_load_default_database(); + +int main(int argc, char **argv) +{ + program_name = argv[0]; + static char stderr_buf[BUFSIZ]; + setbuf(stderr, stderr_buf); + outfp = stdout; + int finished_options = 0; + int bib_flag = 0; + int done_spec = 0; + + // TODO: Migrate to getopt_long; see, e.g., src/preproc/eqn/main.cpp. + for (--argc, ++argv; + !finished_options && argc > 0 && argv[0][0] == '-' + && argv[0][1] != '\0'; + argv++, argc--) { + const char *opt = argv[0] + 1; + while (opt != 0 && *opt != '\0') { + switch (*opt) { + case 'C': + compatible_flag = 1; + opt++; + break; + case 'B': + bib_flag = 1; + label_in_reference = 0; + label_in_text = 0; + ++opt; + if (*opt == '\0') { + annotation_field = 'X'; + annotation_macro = "AP"; + } + else if (csalnum(opt[0]) && opt[1] == '.' && opt[2] != '\0') { + annotation_field = opt[0]; + annotation_macro = opt + 2; + } + opt = 0; + break; + case 'P': + move_punctuation = 1; + opt++; + break; + case 'R': + recognize_R1_R2 = false; + opt++; + break; + case 'S': + // Not a very useful spec. + set_label_spec("(A.n|Q)', '(D.y|D)"); + done_spec = 1; + pre_label = " ("; + post_label = ")"; + sep_label = "; "; + opt++; + break; + case 'V': + do_verify = true; + opt++; + break; + case 'f': + { + const char *num = 0; + if (*++opt == '\0') { + if (argc > 1) { + num = *++argv; + --argc; + } + else { + error("'f' option requires an argument"); + usage(stderr); + exit(1); + } + } + else { + num = opt; + opt = 0; + } + const char *ptr; + for (ptr = num; *ptr; ptr++) + if (!csdigit(*ptr)) { + error("invalid character '%1' in argument to 'f' option", + *ptr); + break; + } + if (*ptr == '\0') { + string spec; + spec = '%'; + spec += num; + spec += '\0'; + set_label_spec(spec.contents()); + done_spec = 1; + } + break; + } + case 'b': + label_in_text = 0; + label_in_reference = 0; + opt++; + break; + case 'e': + accumulate = 1; + opt++; + break; + case 'c': + capitalize_fields = ++opt; + opt = 0; + break; + case 'k': + { + char buf[5]; + if (csalpha(*++opt)) + buf[0] = *opt++; + else { + if (*opt != '\0') + error("invalid field name '%1' in argument to 'k' option", + *opt++); + buf[0] = 'L'; + } + buf[1] = '~'; + buf[2] = '%'; + buf[3] = 'a'; + buf[4] = '\0'; + set_label_spec(buf); + done_spec = 1; + } + break; + case 'a': + { + const char *ptr; + for (ptr = ++opt; *ptr; ptr++) + if (!csdigit(*ptr)) { + error("'a' option argument must be an integer"); + break; + } + if (*ptr == '\0') { + reverse_fields = 'A'; + reverse_fields += opt; + } + opt = 0; + } + break; + case 'i': + linear_ignore_fields = ++opt; + opt = 0; + break; + case 'l': + { + char buf[INT_DIGITS*2 + 11]; // A.n+2D.y-3%a + strcpy(buf, "A.n"); + if (*++opt != '\0' && *opt != ',') { + char *ptr; + long n = strtol(opt, &ptr, 10); + if (n == 0 && ptr == opt) { + error("invalid integer '%1' in 'l' option argument", opt); + opt = 0; + break; + } + if (n < 0) + n = 0; + opt = ptr; + sprintf(strchr(buf, '\0'), "+%ld", n); + } + strcat(buf, "D.y"); + if (*opt == ',') + opt++; + if (*opt != '\0') { + char *ptr; + long n = strtol(opt, &ptr, 10); + if (n == 0 && ptr == opt) { + error("invalid integer '%1' in 'l' option argument", opt); + opt = 0; + break; + } + if (n < 0) + n = 0; + sprintf(strchr(buf, '\0'), "-%ld", n); + opt = ptr; + if (*opt != '\0') + error("argument to 'l' option not of form 'm,n'"); + } + strcat(buf, "%a"); + if (!set_label_spec(buf)) + assert(0 == "set_label_spec() failed"); + done_spec = 1; + } + break; + case 'n': + search_default = 0; + opt++; + break; + case 'p': + { + const char *filename = 0; + if (*++opt == '\0') { + if (argc > 1) { + filename = *++argv; + argc--; + } + else { + error("option 'p' requires an argument"); + usage(stderr); + exit(1); + } + } + else { + filename = opt; + opt = 0; + } + database_list.add_file(filename); + } + break; + case 's': + if (*++opt == '\0') + sort_fields = "AD"; + else { + sort_fields = opt; + opt = 0; + } + accumulate = 1; + break; + case 't': + { + char *ptr; + long n = strtol(opt, &ptr, 10); + if (n == 0 && ptr == opt) { + error("invalid integer '%1' in 't' option argument", opt); + opt = 0; + break; + } + if (n < 1) + n = 1; + linear_truncate_len = int(n); + opt = ptr; + break; + } + case '-': + if (opt[1] == '\0') { + finished_options = 1; + opt++; + break; + } + if (strcmp(opt, "-version") == 0) { + case 'v': + printf("GNU refer (groff) version %s\n", Version_string); + exit(0); + break; + } + if (strcmp(opt, "-help") == 0) { + usage(stdout); + exit(0); + break; + } + // fall through + default: + error("unrecognized option '%1'", opt); + usage(stderr); + exit(1); + break; + } + } + } + if (!done_spec) + set_label_spec("%1"); + if (argc <= 0) { + if (bib_flag) + do_bib("-"); + else + do_file("-"); + } + else { + for (int i = 0; i < argc; i++) { + if (bib_flag) + do_bib(argv[i]); + else + do_file(argv[i]); + } + } + if (accumulate) + output_references(); + if (fflush(stdout) < 0) + fatal("output error: %1", strerror(errno)); + return 0; +} + +static void usage(FILE *stream) +{ + fprintf(stream, +"usage: %s [-bCenPRS] [-aN] [-cXYZ] [-fN] [-iXYZ] [-kX] [-lM,N]" +" [-p db-file] [-sXYZ] [-tN] [-Bl.m] [file ...]\n" +"usage: %s {-v | --version}\n" +"usage: %s --help\n", + program_name, program_name, program_name); +} + +static void possibly_load_default_database() +{ + if (search_default && !default_database_loaded) { + char *filename = getenv("REFER"); + if (filename) + database_list.add_file(filename); + else + database_list.add_file(DEFAULT_INDEX, 1); + default_database_loaded = 1; + } +} + +static bool is_list(const string &str) +{ + const char *start = str.contents(); + const char *end = start + str.length(); + while (end > start && csspace(end[-1])) + end--; + while (start < end && csspace(*start)) + start++; + return end - start == 6 && memcmp(start, "$LIST$", 6) == 0; +} + +static void do_file(const char *filename) +{ + FILE *fp; + if (strcmp(filename, "-") == 0) { + fp = stdin; + } + else { + errno = 0; + fp = fopen(filename, "r"); + if (fp == 0) { + error("can't open '%1': %2", filename, strerror(errno)); + return; + } + } + string fn(filename); + fn += '\0'; + normalize_for_lf(fn); + current_filename = fn.contents(); + fprintf(outfp, ".lf 1 %s\n", current_filename); + current_lineno = 1; + string line; + for (;;) { + line.clear(); + for (;;) { + int c = getc(fp); + if (EOF == c) { + if (line.length() > 0) + line += '\n'; + break; + } + if (is_invalid_input_char(c)) + error("invalid input character code %1", c); + else { + line += c; + if ('\n' == c) + break; + } + } + int len = line.length(); + if (len == 0) + break; + current_lineno++; + if (len >= 2 && line[0] == '.' && line[1] == '[') { + int start_lineno = current_lineno; + bool at_start_of_line = true; + string str; + string post; + string pre(line.contents() + 2, line.length() - 3); + for (;;) { + int c = getc(fp); + if (EOF == c) { + error_with_file_and_line(current_filename, start_lineno, + "missing '.]' line"); + break; + } + if (at_start_of_line) + current_lineno++; + if (at_start_of_line && '.' == c) { + int d = getc(fp); + if (d == ']') { + while ((d = getc(fp)) != '\n' && d != EOF) { + if (is_invalid_input_char(d)) + error("invalid input character code %1", d); + else + post += d; + } + break; + } + if (d != EOF) + ungetc(d, fp); + } + if (is_invalid_input_char(c)) + error("invalid input character code %1", c); + else + str += c; + at_start_of_line = ('\n' == c); + } + if (is_list(str)) { + output_pending_line(); + if (accumulate) + output_references(); + else + error("found '$LIST$' but not accumulating references"); + } + else { + unsigned flags = (accumulate + ? store_reference(str) + : immediately_handle_reference(str)); + if (label_in_text) { + if (accumulate && outfp == stdout) + divert_to_temporary_file(); + if (pending_line.length() == 0) { + warning("can't attach citation to previous line"); + } + else + pending_line.set_length(pending_line.length() - 1); + string punct; + if (move_punctuation) + split_punct(pending_line, punct); + int have_text = pre.length() > 0 || post.length() > 0; + label_type lt = label_type(flags & ~(FORCE_LEFT_BRACKET + |FORCE_RIGHT_BRACKET)); + if ((flags & FORCE_LEFT_BRACKET) || !have_text) + pending_line += PRE_LABEL_MARKER; + pending_line += pre; + char lm = LABEL_MARKER + (int)lt; + pending_line += lm; + pending_line += post; + if ((flags & FORCE_RIGHT_BRACKET) || !have_text) + pending_line += POST_LABEL_MARKER; + pending_line += punct; + pending_line += '\n'; + } + } + need_syncing = 1; + } + else if (len >= 4 + && '.' == line[0] && 'l' == line[1] && 'f' == line[2] + && (compatible_flag || '\n' == line[3] || ' ' == line[3])) + { + pending_lf_lines += line; + line += '\0'; + if (interpret_lf_args(line.contents() + 3)) + current_lineno--; + } + else if (recognize_R1_R2 + && len >= 4 + && '.' == line[0] && 'R' == line[1] && '1' == line[2] + && (compatible_flag || '\n' == line[3] || ' ' == line[3])) + { + line.clear(); + int start_lineno = current_lineno; + bool at_start_of_line = true; + for (;;) { + int c = getc(fp); + if (c != EOF && at_start_of_line) + current_lineno++; + if (at_start_of_line && '.' == c) { + c = getc(fp); + if ('R' == c) { + c = getc(fp); + if ('2' == c) { + c = getc(fp); + if (compatible_flag || ' ' == c || '\n' == c || EOF == c) + { + while (c != EOF && c != '\n') + c = getc(fp); + break; + } + else { + line += '.'; + line += 'R'; + line += '2'; + } + } + else { + line += '.'; + line += 'R'; + } + } + else + line += '.'; + } + if (EOF == c) { + error_with_file_and_line(current_filename, start_lineno, + "missing '.R2' line"); + break; + } + if (is_invalid_input_char(c)) + error_with_file_and_line(current_filename, start_lineno, + "invalid input character code %1", + c); + else { + line += c; + at_start_of_line = ('\n' == c); + } + } + output_pending_line(); + if (accumulate) + output_references(); + else + nreferences = 0; + process_commands(line, current_filename, start_lineno + 1); + need_syncing = 1; + } + else { + output_pending_line(); + pending_line = line; + } + } + need_syncing = 0; + output_pending_line(); + if (fp != stdin) + fclose(fp); +} + +class label_processing_state { + enum { + NORMAL, + PENDING_LABEL, + PENDING_LABEL_POST, + PENDING_LABEL_POST_PRE, + PENDING_POST + } state; + label_type type; // type of pending labels + int count; // number of pending labels + reference **rptr; // pointer to next reference + int rcount; // number of references left + FILE *fp; + int handle_pending(int c); +public: + label_processing_state(reference **, int, FILE *); + ~label_processing_state(); + void process(int c); +}; + +static void output_pending_line() +{ + if (label_in_text && !accumulate && ncitations > 0) { + label_processing_state state(citation, ncitations, outfp); + int len = pending_line.length(); + for (int i = 0; i < len; i++) + state.process((unsigned char)(pending_line[i])); + } + else + put_string(pending_line, outfp); + pending_line.clear(); + if (pending_lf_lines.length() > 0) { + put_string(pending_lf_lines, outfp); + pending_lf_lines.clear(); + } + if (!accumulate) + immediately_output_references(); + if (need_syncing) { + fprintf(outfp, ".lf %d %s\n", current_lineno, current_filename); + need_syncing = 0; + } +} + +static void split_punct(string &line, string &punct) +{ + const char *start = line.contents(); + const char *end = start + line.length(); + const char *ptr = start; + const char *last_token_start = 0; + for (;;) { + if (ptr >= end) + break; + last_token_start = ptr; + if (*ptr == PRE_LABEL_MARKER || *ptr == POST_LABEL_MARKER + || (*ptr >= LABEL_MARKER + && *ptr < LABEL_MARKER + N_LABEL_TYPES)) + ptr++; + else if (!get_token(&ptr, end)) + break; + } + if (last_token_start) { + const token_info *ti = lookup_token(last_token_start, end); + if (ti->is_punct()) { + punct.append(last_token_start, end - last_token_start); + line.set_length(last_token_start - start); + } + } +} + +static void divert_to_temporary_file() +{ + outfp = xtmpfile(); +} + +static void store_citation(reference *ref) +{ + if (ncitations >= citation_max) { + if (citation == 0) + citation = new reference*[citation_max = 100]; + else { + reference **old_citation = citation; + citation_max *= 2; + citation = new reference *[citation_max]; + memcpy(citation, old_citation, ncitations*sizeof(reference *)); + delete[] old_citation; + } + } + citation[ncitations++] = ref; +} + +static unsigned store_reference(const string &str) +{ + if (reference_hash_table == 0) { + reference_hash_table = new reference *[17]; + hash_table_size = 17; + for (int i = 0; i < hash_table_size; i++) + reference_hash_table[i] = 0; + } + unsigned flags; + reference *ref = make_reference(str, &flags); + ref->compute_hash_code(); + unsigned h = ref->hash(); + reference **ptr; + for (ptr = reference_hash_table + (h % hash_table_size); + *ptr != 0; + ((ptr == reference_hash_table) + ? (ptr = reference_hash_table + hash_table_size - 1) + : --ptr)) + if (same_reference(**ptr, *ref)) + break; + if (*ptr != 0) { + if (ref->is_merged()) + warning("fields ignored because reference already used"); + delete ref; + ref = *ptr; + } + else { + *ptr = ref; + ref->set_number(nreferences); + nreferences++; + ref->pre_compute_label(); + ref->compute_sort_key(); + if (nreferences*2 >= hash_table_size) { + // Rehash it. + reference **old_table = reference_hash_table; + int old_size = hash_table_size; + hash_table_size = next_size(hash_table_size); + reference_hash_table = new reference*[hash_table_size]; + int i; + for (i = 0; i < hash_table_size; i++) + reference_hash_table[i] = 0; + for (i = 0; i < old_size; i++) + if (old_table[i]) { + reference **p; + for (p = (reference_hash_table + + (old_table[i]->hash() % hash_table_size)); + *p; + ((p == reference_hash_table) + ? (p = reference_hash_table + hash_table_size - 1) + : --p)) + ; + *p = old_table[i]; + } + delete[] old_table; + } + } + if (label_in_text) + store_citation(ref); + return flags; +} + +unsigned immediately_handle_reference(const string &str) +{ + unsigned flags; + reference *ref = make_reference(str, &flags); + ref->set_number(nreferences); + if (label_in_text || label_in_reference) { + ref->pre_compute_label(); + ref->immediate_compute_label(); + } + nreferences++; + store_citation(ref); + return flags; +} + +static void immediately_output_references() +{ + for (int i = 0; i < ncitations; i++) { + reference *ref = citation[i]; + if (label_in_reference) { + fputs(".ds [F ", outfp); + const string &label = ref->get_label(NORMAL_LABEL); + if (label.length() > 0 + && (label[0] == ' ' || label[0] == '\\' || label[0] == '"')) + putc('"', outfp); + put_string(label, outfp); + putc('\n', outfp); + } + ref->output(outfp); + delete ref; + } + ncitations = 0; +} + +static void output_citation_group(reference **v, int n, label_type type, + FILE *fp) +{ + if (sort_adjacent_labels) { + // Do an insertion sort. Usually n will be very small. + for (int i = 1; i < n; i++) { + int num = v[i]->get_number(); + reference *temp = v[i]; + int j; + for (j = i - 1; j >= 0 && v[j]->get_number() > num; j--) + v[j + 1] = v[j]; + v[j + 1] = temp; + } + } + // This messes up if !accumulate. + if (accumulate && n > 1) { + // remove duplicates + int j = 1; + for (int i = 1; i < n; i++) + if (v[i]->get_label(type) != v[i - 1]->get_label(type)) + v[j++] = v[i]; + n = j; + } + string merged_label; + for (int i = 0; i < n; i++) { + int nmerged = v[i]->merge_labels(v + i + 1, n - i - 1, type, + merged_label); + if (nmerged > 0) { + put_string(merged_label, fp); + i += nmerged; + } + else + put_string(v[i]->get_label(type), fp); + if (i < n - 1) + put_string(sep_label, fp); + } +} + + +label_processing_state::label_processing_state(reference **p, int n, + FILE *f) +: state(NORMAL), count(0), rptr(p), rcount(n), fp(f) +{ +} + +label_processing_state::~label_processing_state() +{ + int handled = handle_pending(EOF); + assert(!handled); + assert(rcount == 0); +} + +int label_processing_state::handle_pending(int c) +{ + switch (state) { + case NORMAL: + break; + case PENDING_LABEL: + if (POST_LABEL_MARKER == c) { + state = PENDING_LABEL_POST; + return 1; + } + else { + output_citation_group(rptr, count, type, fp); + rptr += count ; + rcount -= count; + state = NORMAL; + } + break; + case PENDING_LABEL_POST: + if (PRE_LABEL_MARKER == c) { + state = PENDING_LABEL_POST_PRE; + return 1; + } + else { + output_citation_group(rptr, count, type, fp); + rptr += count; + rcount -= count; + put_string(post_label, fp); + state = NORMAL; + } + break; + case PENDING_LABEL_POST_PRE: + if (c >= LABEL_MARKER + && c < LABEL_MARKER + N_LABEL_TYPES + && c - LABEL_MARKER == type) { + count += 1; + state = PENDING_LABEL; + return 1; + } + else { + output_citation_group(rptr, count, type, fp); + rptr += count; + rcount -= count; + put_string(sep_label, fp); + state = NORMAL; + } + break; + case PENDING_POST: + if (PRE_LABEL_MARKER == c) { + put_string(sep_label, fp); + state = NORMAL; + return 1; + } + else { + put_string(post_label, fp); + state = NORMAL; + } + break; + } + return 0; +} + +void label_processing_state::process(int c) +{ + if (handle_pending(c)) + return; + assert(state == NORMAL); + switch (c) { + case PRE_LABEL_MARKER: + put_string(pre_label, fp); + state = NORMAL; + break; + case POST_LABEL_MARKER: + state = PENDING_POST; + break; + case LABEL_MARKER: + case LABEL_MARKER + 1: + count = 1; + state = PENDING_LABEL; + type = label_type(c - LABEL_MARKER); + break; + default: + state = NORMAL; + putc(c, fp); + break; + } +} + +extern "C" { + +int rcompare(const void *p1, const void *p2) +{ + return compare_reference(**(reference **)p1, **(reference **)p2); +} + +} + +void output_references() +{ + assert(accumulate); + if (!hash_table_size) { + if (have_bibliography) + error("nothing to reference (probably 'bibliography' before" + " 'sort')"); + accumulate = 0; + nreferences = 0; + return; + } + if (nreferences > 0) { + int j = 0; + int i; + for (i = 0; i < hash_table_size; i++) + if (reference_hash_table[i] != 0) + reference_hash_table[j++] = reference_hash_table[i]; + assert(j == nreferences); + for (; j < hash_table_size; j++) + reference_hash_table[j] = 0; + qsort(reference_hash_table, nreferences, sizeof(reference*), + rcompare); + for (i = 0; i < nreferences; i++) + reference_hash_table[i]->set_number(i); + compute_labels(reference_hash_table, nreferences); + } + if (outfp != stdout) { + rewind(outfp); + { + label_processing_state state(citation, ncitations, stdout); + int c; + while ((c = getc(outfp)) != EOF) + state.process(c); + } + ncitations = 0; + fclose(outfp); + outfp = stdout; + } + if (nreferences > 0) { + fputs(".]<\n", outfp); + for (int i = 0; i < nreferences; i++) { + if (sort_fields.length() > 0) + reference_hash_table[i]->print_sort_key_comment(outfp); + if (label_in_reference) { + fputs(".ds [F ", outfp); + const string &label + = reference_hash_table[i]->get_label(NORMAL_LABEL); + if (label.length() > 0 + && (label[0] == ' ' || label[0] == '\\' || label[0] == '"')) + putc('"', outfp); + put_string(label, outfp); + putc('\n', outfp); + } + reference_hash_table[i]->output(outfp); + delete reference_hash_table[i]; + reference_hash_table[i] = 0; + } + fputs(".]>\n", outfp); + nreferences = 0; + } + clear_labels(); +} + +static reference *find_reference(const char *query, int query_len) +{ + // This is so that error messages look better. + while (query_len > 0 && csspace(query[query_len - 1])) + query_len--; + string str; + for (int i = 0; i < query_len; i++) + str += query[i] == '\n' ? ' ' : query[i]; + str += '\0'; + possibly_load_default_database(); + search_list_iterator iter(&database_list, str.contents()); + reference_id rid; + const char *start; + int len; + if (!iter.next(&start, &len, &rid)) { + error("no matches for '%1'", str.contents()); + return 0; + } + const char *end = start + len; + while (start < end) { + if (*start == '%') + break; + while (start < end && *start++ != '\n') + ; + } + if (start >= end) { + error("found a reference for '%1' but it didn't contain any fields", + str.contents()); + return 0; + } + reference *result = new reference(start, end - start, &rid); + if (iter.next(&start, &len, &rid)) + warning("multiple matches for '%1'", str.contents()); + return result; +} + +static reference *make_reference(const string &str, unsigned *flagsp) +{ + const char *start = str.contents(); + const char *end = start + str.length(); + const char *ptr = start; + while (ptr < end) { + if (*ptr == '%') + break; + while (ptr < end && *ptr++ != '\n') + ; + } + *flagsp = 0; + for (; start < ptr; start++) { + if (*start == '#') + *flagsp = (SHORT_LABEL | (*flagsp & (FORCE_RIGHT_BRACKET + | FORCE_LEFT_BRACKET))); + else if (*start == '[') + *flagsp |= FORCE_LEFT_BRACKET; + else if (*start == ']') + *flagsp |= FORCE_RIGHT_BRACKET; + else if (!csspace(*start)) + break; + } + if (start >= end) { + error("empty reference"); + return new reference; + } + reference *database_ref = 0; + if (start < ptr) + database_ref = find_reference(start, ptr - start); + reference *inline_ref = 0; + if (ptr < end) + inline_ref = new reference(ptr, end - ptr); + if (inline_ref) { + if (database_ref) { + database_ref->merge(*inline_ref); + delete inline_ref; + return database_ref; + } + else + return inline_ref; + } + else if (database_ref) + return database_ref; + else + return new reference; +} + +static void do_ref(const string &str) +{ + if (accumulate) + (void)store_reference(str); + else { + (void)immediately_handle_reference(str); + immediately_output_references(); + } +} + +static void trim_blanks(string &str) +{ + const char *start = str.contents(); + const char *end = start + str.length(); + while (end > start && end[-1] != '\n' && csspace(end[-1])) + --end; + str.set_length(end - start); +} + +void do_bib(const char *filename) +{ + FILE *fp; + if (strcmp(filename, "-") == 0) + fp = stdin; + else { + errno = 0; + fp = fopen(filename, "r"); + if (fp == 0) { + error("can't open '%1': %2", filename, strerror(errno)); + return; + } + current_filename = filename; + } + current_lineno = 1; + enum { + START, MIDDLE, BODY, BODY_START, BODY_BLANK, BODY_DOT + } state = START; + string body; + for (;;) { + int c = getc(fp); + if (EOF == c) + break; + if (is_invalid_input_char(c)) { + error("invalid input character code %1", c); + continue; + } + switch (state) { + case START: + if ('%' == c) { + body = c; + state = BODY; + } + else if (c != '\n') + state = MIDDLE; + break; + case MIDDLE: + if ('\n' == c) + state = START; + break; + case BODY: + body += c; + if ('\n' == c) + state = BODY_START; + break; + case BODY_START: + if ('\n' == c) { + do_ref(body); + state = START; + } + else if ('.' == c) + state = BODY_DOT; + else if (csspace(c)) { + state = BODY_BLANK; + body += c; + } + else { + body += c; + state = BODY; + } + break; + case BODY_BLANK: + if ('\n' == c) { + trim_blanks(body); + do_ref(body); + state = START; + } + else if (csspace(c)) + body += c; + else { + body += c; + state = BODY; + } + break; + case BODY_DOT: + if (']' == c) { + do_ref(body); + state = MIDDLE; + } + else { + body += '.'; + body += c; + state = ('\n' == c) ? BODY_START : BODY; + } + break; + default: + assert(0 == "unhandled case while parsing bibliography file"); + } + if ('\n' == c) + current_lineno++; + } + switch (state) { + case START: + case MIDDLE: + break; + case BODY: + body += '\n'; + do_ref(body); + break; + case BODY_DOT: + case BODY_START: + do_ref(body); + break; + case BODY_BLANK: + trim_blanks(body); + do_ref(body); + break; + } + fclose(fp); +} + +// from the Dragon Book + +unsigned hash_string(const char *s, int len) +{ + const char *end = s + len; + unsigned h = 0, g; + while (s < end) { + h <<= 4; + h += *s++; + if ((g = h & 0xf0000000) != 0) { + h ^= g >> 24; + h ^= g; + } + } + return h; +} + +int next_size(int n) +{ + static const int table_sizes[] = { + 101, 503, 1009, 2003, 3001, 4001, 5003, 10007, 20011, 40009, + 80021, 160001, 500009, 1000003, 2000003, 4000037, 8000009, + 16000057, 32000011, 64000031, 128000003, 0 + }; + + const int *p; + for (p = table_sizes; *p <= n && *p != 0; p++) + ; + assert(*p != 0); + return *p; +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/refer/refer.h b/src/preproc/refer/refer.h new file mode 100644 index 0000000..3ebff27 --- /dev/null +++ b/src/preproc/refer/refer.h @@ -0,0 +1,81 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "lib.h" + +#include +#include + +#include "errarg.h" +#include "error.h" +#include "stringclass.h" +#include "cset.h" +#include "cmap.h" +#include "lf.h" + +#include "defs.h" + +unsigned hash_string(const char *, int); +int next_size(int); + +extern string capitalize_fields; +extern string reverse_fields; +extern string abbreviate_fields; +extern string period_before_last_name; +extern string period_before_initial; +extern string period_before_hyphen; +extern string period_before_other; +extern string sort_fields; +extern int annotation_field; +extern string annotation_macro; +extern string discard_fields; +extern string articles; +extern int abbreviate_label_ranges; +extern string label_range_indicator; +extern int date_as_label; +extern string join_authors_exactly_two; +extern string join_authors_last_two; +extern string join_authors_default; +extern string separate_label_second_parts; +extern string et_al; +extern int et_al_min_elide; +extern int et_al_min_total; + +extern int compatible_flag; + +extern int set_label_spec(const char *); +extern int set_date_label_spec(const char *); +extern int set_short_label_spec(const char *); + +extern int short_label_flag; + +void clear_labels(); +void command_error(const char *, + const errarg &arg1 = empty_errarg, + const errarg &arg2 = empty_errarg, + const errarg &arg3 = empty_errarg); + +class reference; + +void compute_labels(reference **, int); + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/refer/tests/artifacts/62124.bib b/src/preproc/refer/tests/artifacts/62124.bib new file mode 100644 index 0000000..1093837 --- /dev/null +++ b/src/preproc/refer/tests/artifacts/62124.bib @@ -0,0 +1,4 @@ +%A IrritablĂŠ, X. +%T ˆUniversit\*'e de Grenoble. ‰Cours donn\*'es aux Houches. +%Z ˆMon dieu, Consiel !‰ +%Z NOTE: This file is deliberately not valid UTF-8. Try Latin-1. diff --git a/src/preproc/refer/tests/report-correct-line-numbers.sh b/src/preproc/refer/tests/report-correct-line-numbers.sh new file mode 100755 index 0000000..19cae53 --- /dev/null +++ b/src/preproc/refer/tests/report-correct-line-numbers.sh @@ -0,0 +1,136 @@ +#!/bin/sh +# +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +refer="${abs_top_builddir:-.}/refer" + +fail= + +wail () { + echo FAILED >&2 + fail=YES +} + +# Regression-test Savannah #62124. Ensure correct line numbers in +# diagnostics on bibliography files. + +# Locate directory containing our test artifacts. +artifact_dir= + +for buildroot in . .. ../.. +do + d=$buildroot/src/preproc/refer/tests/artifacts + if [ -d "$d" ] + then + artifact_dir=$d + break + fi +done + +# If we can't find it, we can't test. +test -z "$artifact_dir" && exit 77 # skip + +input=". +.R1 +bibliography $artifact_dir/62124.bib +cattywumpus +.R2 +. +.R1 +bibliography $artifact_dir/62124.bib +cattywumpus +.R2" + +# We want standard error _only_. +output=$(echo "$input" | "$refer" -e -p "$artifact_dir"/62124.bib \ + 2>&1 >/dev/null) + +# We should get every complaint about the bibliography twice because it +# is dumped twice; the line numbers should not change because they're +# problems with the bibliography file, not the input file. + +# We're pattern-matching diagnostic output here, which is a delicate +# thing to do. If a test failure occurs, ensure the diagnostic message +# text hasn't changed before assuming a deeper logic problem. + +echo "checking line number of invalid character on bibliography line 1" +count=$(echo "$output" | grep -c "refer:.*/62124.bib:1:.*code 129") +test $count -eq 2 || wail + +echo "checking line number of first invalid character on bibliography" \ + "line 2" +count=$(echo "$output" | grep -c "refer:.*/62124.bib:2:.*code 136") +test $count -eq 2 || wail + +echo "checking line number of second invalid character on" \ + "bibliography line 2" +count=$(echo "$output" | grep -c "refer:.*/62124.bib:2:.*code 137") +test $count -eq 2 || wail + +echo "checking line number of first invalid character on" \ + "bibliography line 3" +count=$(echo "$output" | grep -c "refer:.*/62124.bib:3:.*code 136") +test $count -eq 2 || wail + +echo "checking line number of second invalid character on" \ + "bibliography line 3" +count=$(echo "$output" | grep -c "refer:.*/62124.bib:3:.*code 137") +test $count -eq 2 || wail + +# Problems with the input file should also be accurately located. + +echo "checking line number of invalid refer(1) command on input line 4" +echo "$output" +echo "$output" | grep -q "refer:.*:4:.*unknown command" || wail + +echo "checking line number of invalid refer(1) command on input line 9" +echo "$output" +echo "$output" | grep -q "refer:.*:9:.*unknown command" || wail + +# Regression-test Savannah #62391. + +output=$(printf '\0201\n' | "$refer" 2>&1 >/dev/null) + +echo "checking line number of invalid input character on input line 1" +echo "$output" | grep -q "refer:.*:1:.*invalid input character" \ + || wail + +output=$(printf '.R1\nbogus \0200\n.R2\n' | "$refer" 2>&1 >/dev/null) + +echo "checking line number of invalid input character after refer(1)" \ + "command on input line 2" +echo "$output" | grep -q "refer:.*:2:.*invalid input character" \ + || wail + +output=$(printf '.R1\ndatabase nonexistent.bib\n.R2\n' | "$refer" 2>&1 \ + >/dev/null) + +echo "checking line number of attempt to load nonexistent database" +echo "$output" | grep -q "refer:.*:2:.*can't open 'nonexistent\.bib':" \ + || wail + +output=$(printf '.R1\ninclude nonexistent.bib\n.R2\n' | "$refer" 2>&1 \ + >/dev/null) + +echo "checking line number of attempt to load nonexistent inclusion" +echo "$output" | grep -q "refer:.*:2:.*can't open 'nonexistent\.bib':" \ + || wail +test -z "$fail" || exit 1 + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/preproc/refer/token.cpp b/src/preproc/refer/token.cpp new file mode 100644 index 0000000..e643cbd --- /dev/null +++ b/src/preproc/refer/token.cpp @@ -0,0 +1,377 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "refer.h" +#include "token.h" + +#define TOKEN_TABLE_SIZE 1009 +// I believe in Icelandic thorn sorts after z. +#define THORN_SORT_KEY "{" + +struct token_table_entry { + const char *tok; + token_info ti; + token_table_entry(); +}; + +token_table_entry token_table[TOKEN_TABLE_SIZE]; +int ntokens = 0; + +static void skip_name(const char **ptr, const char *end) +{ + if (*ptr < end) { + switch (*(*ptr)++) { + case '(': + if (*ptr < end) { + *ptr += 1; + if (*ptr < end) + *ptr += 1; + } + break; + case '[': + while (*ptr < end) + if (*(*ptr)++ == ']') + break; + break; + } + } +} + +int get_token(const char **ptr, const char *end) +{ + if (*ptr >= end) + return 0; + char c = *(*ptr)++; + if (c == '\\' && *ptr < end) { + switch (**ptr) { + default: + *ptr += 1; + break; + case '(': + case '[': + skip_name(ptr, end); + break; + case '*': + case 'f': + *ptr += 1; + skip_name(ptr, end); + break; + } + } + return 1; +} + +token_info::token_info() +: type(TOKEN_OTHER), sort_key(0), other_case(0) +{ +} + +void token_info::set(token_type t, const char *sk, const char *oc) +{ + assert(oc == 0 || t == TOKEN_UPPER || t == TOKEN_LOWER); + type = t; + sort_key = sk; + other_case = oc; +} + +void token_info::sortify(const char *start, const char *end, string &result) + const +{ + if (sort_key) + result += sort_key; + else if (type == TOKEN_UPPER || type == TOKEN_LOWER) { + for (; start < end; start++) + if (csalpha(*start)) + result += cmlower(*start); + } +} + +int token_info::sortify_non_empty(const char *start, const char *end) const +{ + if (sort_key) + return *sort_key != '\0'; + if (type != TOKEN_UPPER && type != TOKEN_LOWER) + return 0; + for (; start < end; start++) + if (csalpha(*start)) + return 1; + return 0; +} + + +void token_info::lower_case(const char *start, const char *end, + string &result) const +{ + if (type != TOKEN_UPPER) { + while (start < end) + result += *start++; + } + else if (other_case) + result += other_case; + else { + while (start < end) + result += cmlower(*start++); + } +} + +void token_info::upper_case(const char *start, const char *end, + string &result) const +{ + if (type != TOKEN_LOWER) { + while (start < end) + result += *start++; + } + else if (other_case) + result += other_case; + else { + while (start < end) + result += cmupper(*start++); + } +} + +token_table_entry::token_table_entry() +: tok(0) +{ +} + +static void store_token(const char *tok, token_type typ, + const char *sk = 0, const char *oc = 0) +{ + unsigned n = hash_string(tok, strlen(tok)) % TOKEN_TABLE_SIZE; + for (;;) { + if (token_table[n].tok == 0) { + if (++ntokens == TOKEN_TABLE_SIZE) + assert(0); + token_table[n].tok = tok; + break; + } + if (strcmp(tok, token_table[n].tok) == 0) + break; + if (n == 0) + n = TOKEN_TABLE_SIZE - 1; + else + --n; + } + token_table[n].ti.set(typ, sk, oc); +} + + +token_info default_token_info; + +const token_info *lookup_token(const char *start, const char *end) +{ + unsigned n = hash_string(start, end - start) % TOKEN_TABLE_SIZE; + for (;;) { + if (token_table[n].tok == 0) + break; + if (strlen(token_table[n].tok) == size_t(end - start) + && memcmp(token_table[n].tok, start, end - start) == 0) + return &(token_table[n].ti); + if (n == 0) + n = TOKEN_TABLE_SIZE - 1; + else + --n; + } + return &default_token_info; +} + +static void init_ascii() +{ + const char *p; + for (p = "abcdefghijklmnopqrstuvwxyz"; *p; p++) { + char buf[2]; + buf[0] = *p; + buf[1] = '\0'; + store_token(strsave(buf), TOKEN_LOWER); + buf[0] = cmupper(buf[0]); + store_token(strsave(buf), TOKEN_UPPER); + } + for (p = "0123456789"; *p; p++) { + char buf[2]; + buf[0] = *p; + buf[1] = '\0'; + const char *s = strsave(buf); + store_token(s, TOKEN_OTHER, s); + } + for (p = ".,:;?!"; *p; p++) { + char buf[2]; + buf[0] = *p; + buf[1] = '\0'; + store_token(strsave(buf), TOKEN_PUNCT); + } + store_token("-", TOKEN_HYPHEN); +} + +static void store_letter(const char *lower, const char *upper, + const char *sort_key = 0) +{ + store_token(lower, TOKEN_LOWER, sort_key, upper); + store_token(upper, TOKEN_UPPER, sort_key, lower); +} + +static void init_letter(unsigned char uc_code, unsigned char lc_code, + const char *sort_key) +{ + char lbuf[2]; + lbuf[0] = lc_code; + lbuf[1] = 0; + char ubuf[2]; + ubuf[0] = uc_code; + ubuf[1] = 0; + store_letter(strsave(lbuf), strsave(ubuf), sort_key); +} + +static void init_latin1() +{ + init_letter(0xc0, 0xe0, "a"); + init_letter(0xc1, 0xe1, "a"); + init_letter(0xc2, 0xe2, "a"); + init_letter(0xc3, 0xe3, "a"); + init_letter(0xc4, 0xe4, "a"); + init_letter(0xc5, 0xe5, "a"); + init_letter(0xc6, 0xe6, "ae"); + init_letter(0xc7, 0xe7, "c"); + init_letter(0xc8, 0xe8, "e"); + init_letter(0xc9, 0xe9, "e"); + init_letter(0xca, 0xea, "e"); + init_letter(0xcb, 0xeb, "e"); + init_letter(0xcc, 0xec, "i"); + init_letter(0xcd, 0xed, "i"); + init_letter(0xce, 0xee, "i"); + init_letter(0xcf, 0xef, "i"); + + init_letter(0xd0, 0xf0, "d"); + init_letter(0xd1, 0xf1, "n"); + init_letter(0xd2, 0xf2, "o"); + init_letter(0xd3, 0xf3, "o"); + init_letter(0xd4, 0xf4, "o"); + init_letter(0xd5, 0xf5, "o"); + init_letter(0xd6, 0xf6, "o"); + init_letter(0xd8, 0xf8, "o"); + init_letter(0xd9, 0xf9, "u"); + init_letter(0xda, 0xfa, "u"); + init_letter(0xdb, 0xfb, "u"); + init_letter(0xdc, 0xfc, "u"); + init_letter(0xdd, 0xfd, "y"); + init_letter(0xde, 0xfe, THORN_SORT_KEY); + + store_token("\337", TOKEN_LOWER, "ss", "SS"); + store_token("\377", TOKEN_LOWER, "y", "Y"); +} + +static void init_two_char_letter(char l1, char l2, char u1, char u2, + const char *sk = 0) +{ + char buf[6]; + buf[0] = '\\'; + buf[1] = '('; + buf[2] = l1; + buf[3] = l2; + buf[4] = '\0'; + const char *p = strsave(buf); + buf[2] = u1; + buf[3] = u2; + store_letter(p, strsave(buf), sk); + buf[1] = '['; + buf[4] = ']'; + buf[5] = '\0'; + p = strsave(buf); + buf[2] = l1; + buf[3] = l2; + store_letter(strsave(buf), p, sk); + +} + +static void init_special_chars() +{ + const char *p; + for (p = "':^`~"; *p; p++) + for (const char *q = "aeiouy"; *q; q++) { + // Use a variable to work around bug in gcc 2.0 + char c = cmupper(*q); + init_two_char_letter(*p, *q, *p, c); + } + for (p = "/l/o~n,coeaeij"; *p; p += 2) { + // Use variables to work around bug in gcc 2.0 + char c0 = cmupper(p[0]); + char c1 = cmupper(p[1]); + init_two_char_letter(p[0], p[1], c0, c1); + } + init_two_char_letter('v', 's', 'v', 'S', "s"); + init_two_char_letter('v', 'z', 'v', 'Z', "z"); + init_two_char_letter('o', 'a', 'o', 'A', "a"); + init_two_char_letter('T', 'p', 'T', 'P', THORN_SORT_KEY); + init_two_char_letter('-', 'd', '-', 'D'); + + store_token("\\(ss", TOKEN_LOWER, 0, "SS"); + store_token("\\[ss]", TOKEN_LOWER, 0, "SS"); + + store_token("\\(Sd", TOKEN_LOWER, "d", "\\(-D"); + store_token("\\[Sd]", TOKEN_LOWER, "d", "\\[-D]"); + store_token("\\(hy", TOKEN_HYPHEN); + store_token("\\[hy]", TOKEN_HYPHEN); + store_token("\\(en", TOKEN_RANGE_SEP); + store_token("\\[en]", TOKEN_RANGE_SEP); +} + +static void init_strings() +{ + char buf[6]; + buf[0] = '\\'; + buf[1] = '*'; + for (const char *p = "'`^^,:~v_o./;"; *p; p++) { + buf[2] = *p; + buf[3] = '\0'; + store_token(strsave(buf), TOKEN_ACCENT); + buf[2] = '['; + buf[3] = *p; + buf[4] = ']'; + buf[5] = '\0'; + store_token(strsave(buf), TOKEN_ACCENT); + } + + // -ms special letters + store_letter("\\*(th", "\\*(Th", THORN_SORT_KEY); + store_letter("\\*[th]", "\\*[Th]", THORN_SORT_KEY); + store_letter("\\*(d-", "\\*(D-"); + store_letter("\\*[d-]", "\\*[D-]"); + store_letter("\\*(ae", "\\*(Ae", "ae"); + store_letter("\\*[ae]", "\\*[Ae]", "ae"); + store_letter("\\*(oe", "\\*(Oe", "oe"); + store_letter("\\*[oe]", "\\*[Oe]", "oe"); + + store_token("\\*3", TOKEN_LOWER, "y", "Y"); + store_token("\\*8", TOKEN_LOWER, "ss", "SS"); + store_token("\\*q", TOKEN_LOWER, "o", "O"); +} + +struct token_initer { + token_initer(); +}; + +static token_initer the_token_initer; + +token_initer::token_initer() +{ + init_ascii(); + init_latin1(); + init_special_chars(); + init_strings(); + default_token_info.set(TOKEN_OTHER); +} diff --git a/src/preproc/refer/token.h b/src/preproc/refer/token.h new file mode 100644 index 0000000..9cd688c --- /dev/null +++ b/src/preproc/refer/token.h @@ -0,0 +1,87 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +enum token_type { + TOKEN_OTHER, + TOKEN_UPPER, + TOKEN_LOWER, + TOKEN_ACCENT, + TOKEN_PUNCT, + TOKEN_HYPHEN, + TOKEN_RANGE_SEP +}; + +class token_info { +private: + token_type type; + const char *sort_key; + const char *other_case; +public: + token_info(); + void set(token_type, const char *sk = 0, const char *oc = 0); + void lower_case(const char *start, const char *end, string &result) const; + void upper_case(const char *start, const char *end, string &result) const; + void sortify(const char *start, const char *end, string &result) const; + int sortify_non_empty(const char *start, const char *end) const; + int is_upper() const; + int is_lower() const; + int is_accent() const; + int is_other() const; + int is_punct() const; + int is_hyphen() const; + int is_range_sep() const; +}; + +inline int token_info::is_upper() const +{ + return type == TOKEN_UPPER; +} + +inline int token_info::is_lower() const +{ + return type == TOKEN_LOWER; +} + +inline int token_info::is_accent() const +{ + return type == TOKEN_ACCENT; +} + +inline int token_info::is_other() const +{ + return type == TOKEN_OTHER; +} + +inline int token_info::is_punct() const +{ + return type == TOKEN_PUNCT; +} + +inline int token_info::is_hyphen() const +{ + return type == TOKEN_HYPHEN; +} + +inline int token_info::is_range_sep() const +{ + return type == TOKEN_RANGE_SEP; +} + +int get_token(const char **ptr, const char *end); +const token_info *lookup_token(const char *start, const char *end); diff --git a/src/preproc/soelim/TODO b/src/preproc/soelim/TODO new file mode 100644 index 0000000..f2a3924 --- /dev/null +++ b/src/preproc/soelim/TODO @@ -0,0 +1 @@ +Understand .pso. diff --git a/src/preproc/soelim/soelim.1.man b/src/preproc/soelim/soelim.1.man new file mode 100644 index 0000000..4a1c042 --- /dev/null +++ b/src/preproc/soelim/soelim.1.man @@ -0,0 +1,456 @@ +'\" p +.TH @g@soelim @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +@g@soelim \- recursively interpolate source requests in +.I roff +or other text files +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1989-2020 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_soelim_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +.\" Man pages are seldom preprocessed with pic(1). +.mso pic.tmac +. +. +.\" ==================================================================== +.\" Definitions +.\" ==================================================================== +. +.ie t .ds tx T\h'-.1667m'\v'.224m'E\v'-.224m'\h'-.125m'X +.el .ds tx TeX +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY @g@soelim +.RB [ \-Crt ] +.RB [ \-I +.IR dir ] +.RI [ input-file\~ .\|.\|.] +.YS +. +. +.SY @g@soelim +.B \-\-help +.YS +. +. +.SY @g@soelim +.B \-v +. +.SY @g@soelim +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +GNU +.I soelim \" GNU +is a preprocessor for the +.MR groff @MAN7EXT@ +document formatting system. +. +.I @g@soelim +works as a filter to eliminate source requests in +.MR roff @MAN7EXT@ +input files; +that is, +it replaces lines of the form +.RB \[lq] .so +.IR included-file \[rq] +within each text +.I input-file +with the contents of +.IR included-file , +recursively. +. +By default, +it writes +.B lf +requests as well to record the name and line number of each +.I input-file +and +.IR included-file , +so that any diagnostics produced by later processing can be accurately +traced to the original input. +. +Options allow this information to be suppressed +.RB ( \-r ) +or supplied in \*[tx] comments instead +.RB ( \-t ). +. +In the absence of +.I input-file +arguments, +.I @g@soelim +reads the standard input stream. +. +Output is written to the standard output stream. +. +. +.PP +If the name of a +.I macro-file +contains a backslash, +use +.B \[rs]\[rs] +or +.B \[rs]e +to embed it. +. +To embed a space, +write +.RB \[lq] \[rs]\~ \[rq] +(backslash followed by a space). +. +Any other escape sequence in +.IR macro-file , +including +.RB \[lq] \[rs][rs] \[rq], +prevents +.I @g@soelim +from replacing the source request. +. +. +.PP +The dot must be at the beginning of a line and must be followed by +.RB \[lq] so \[rq] +without intervening spaces or tabs for +.I @g@soelim +to handle it. +. +This convention allows source requests to be \[lq]protected\[rq] from +processing by +.IR @g@soelim , +for instance as part of macro definitions or +.RB \[lq] if \[rq] +requests. +. +. +.PP +There must also be at least one space between +.RB \[lq] so \[rq] +and its +.I macro-file +argument. +. +The +.B \-C +option overrides this requirement. +. +. +.PP +The foregoing is the limit of +.IR @g@soelim 's +understanding of the +.I roff +language; +it does not, +for example, +replace the input line +. +.RS +.EX +\&.if 1 .so otherfile +.EE +.RE +. +with the contents of +.IR otherfile . +. +With its +.B \-r +option, +therefore, +.I @g@soelim +can be used to process text files in general, +to flatten a tree of input documents. +. +. +.PP +.I soelim \" generic +was designed to handle situations where the target of a +.I roff \" generic +source request requires a preprocessor such as +.MR @g@eqn @MAN1EXT@ , +.MR @g@pic @MAN1EXT@ , +.MR @g@refer @MAN1EXT@ , +or +.MR @g@tbl @MAN1EXT@ . +. +The usual processing sequence of +.MR groff @MAN1EXT@ +is as follows. +. +.\" Does this groff installation use a command prefix? In installed +.\" pages, this comparison will not look like it needs to be dynamically +.\" decided. +.\" +.\" This is done so that the box sizes (in the pic(1) diagram) and arrow +.\" alignments (in the text alternative) can remain fixed. +.if !'@g@'\%' \{\ +In the diagrams below, +the traditional names for +.I soelim +and +.I troff +are used; +on this system, +the GNU versions are installed as +.I @g@soelim +and +.IR @g@troff . +.\} +. +. +.PP +.ie t \{\ +.PS +.ps 10 +.vs 12 +box invisible width 0.5 height 0.4 "input" "file"; +move to last box .bottom; +down; +arrow 0.3; +box invisible width 0.8 height 0.2 "preprocessor"; +move to last box .right +right; +arrow 0.3; +A: box invisible width 0.35 height 0.2 "troff"; +move to last box .top; +up; +move 0.3; +box invisible width 0.6 height 0.4 "sourced" "file"; +line <- up 0.3 from A.top; +move to A.right; +right; +arrow 0.3; +box invisible width 0.85 height 0.2 "postprocessor"; +move to last box .bottom; +down; +arrow 0.3; +box invisible width 0.5 height 0.4 "output" "file" +.ps +.vs +.PE +.\} +.el \{\ +.EX + input sourced + file file + \[bv] \[bv] + \[da] \[da] + preprocessor \[an]\[->] troff \[an]\[->] postprocessor + \[bv] + \[da] + output + file +.EE +.\} +.PP +That is, +files sourced with +.RB \[lq] so \[rq] +are normally read +.I only +by the formatter, +.IR @g@troff . +. +.I @g@soelim +is +.I not +required for +.I @g@troff +to source files. +. +. +.PP +If a file to be sourced should also be preprocessed, +it must already be read +.I before +the input file passes through the preprocessor. +. +.IR @g@soelim , +normally invoked via +.IR groff 's +.B \-s +option, +handles this. +. +. +.PP +.ie t \{\ +.PS +.ps 10 +.vs 12 +box invisible width 0.5 height 0.4 "input" "file"; +move to last box .bottom; +down; +arrow 0.3; +A: box invisible width 0.5 height 0.2 "soelim"; +line <- 0.3; +box invisible width 0.5 height 0.4 "sourced" "file"; +move to A.right; +right; +arrow 0.3; +box invisible width 0.8 height 0.2 "preprocessor"; +arrow 0.3; +box invisible width 0.35 height 0.2 "troff"; +arrow 0.3 +box invisible width 0.85 height 0.2 "postprocessor"; +move to last box .bottom; +down; +arrow 0.3; +box invisible width 0.5 height 0.4 "output" "file" +.ps +.vs +.PE +.\} +.el \{\ +.EX + input + file + \[bv] + \[da] + soelim \[an]\[->] preprocessor \[an]\[->] troff \[an]\[->] \ +postprocessor + \[ua] \[bv] + \[bv] \[da] + sourced output + file file +.EE +.\} +. +. +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-\-help +displays a usage message, +while +.B \-v +and +.B \-\-version +show version information; +all exit afterward. +. +. +.TP +.B \-C +Recognize an input line starting with +.B .so +even if a character other than a space or newline follows. +. +.TP +.BI \-I\~ dir +Search the directory +.I dir +path for +.I input- +and +.I included-files. +. +.B \-I +may be specified more than once; +each +.I dir +is searched in the given order. +. +To search the current working directory before others, +add +.RB \[lq] "\-I .\&" \[rq] +at the desired place; +it is otherwise searched last. +. +. +.TP +.B \-r +Write files \[lq]raw\[rq]; +do not add +.B lf +requests. +. +. +.TP +.B \-t +Emit \*[tx] comment lines starting with +.RB \[lq] % \[rq] +indicating the current file and line number, +rather than +.B lf +requests for the same purpose. +. +. +.PP +If both +.B \-r +and +.B \-t +are given, +the last one specified controls. +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.MR groff @MAN1EXT@ +. +. +.\" Clean up. +.rm tx +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_soelim_1_man_C] +.do rr *groff_soelim_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/preproc/soelim/soelim.am b/src/preproc/soelim/soelim.am new file mode 100644 index 0000000..1aa7941 --- /dev/null +++ b/src/preproc/soelim/soelim.am @@ -0,0 +1,31 @@ +# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# +# This file 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 . + +prefixexecbin_PROGRAMS += soelim +soelim_LDADD = libgroff.a $(LIBM) lib/libgnu.a +soelim_SOURCES = src/preproc/soelim/soelim.cpp +PREFIXMAN1 += src/preproc/soelim/soelim.1 +EXTRA_DIST += \ + src/preproc/soelim/TODO \ + src/preproc/soelim/soelim.1.man + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/preproc/soelim/soelim.cpp b/src/preproc/soelim/soelim.cpp new file mode 100644 index 0000000..bafc5cd --- /dev/null +++ b/src/preproc/soelim/soelim.cpp @@ -0,0 +1,315 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "lib.h" + +#include +#include +#include +#include + +#include "errarg.h" +#include "error.h" +#include "stringclass.h" +#include "nonposix.h" +#include "searchpath.h" +#include "lf.h" + +// The include search path initially contains only the current directory. +static search_path include_search_path(0, 0, 0, 1); + +int compatible_flag = 0; +int raw_flag = 0; +int tex_flag = 0; + +extern "C" const char *Version_string; + +int do_file(const char *); + + +void usage(FILE *stream) +{ + fprintf(stream, "usage: %s [-Crt] [-I dir] [file ...]\n" + "usage: %s {-v | --version}\n" + "usage: %s --help\n", + program_name, program_name, program_name); +} + +int main(int argc, char **argv) +{ + program_name = argv[0]; + int opt; + static const struct option long_options[] = { + { "help", no_argument, 0, CHAR_MAX + 1 }, + { "version", no_argument, 0, 'v' }, + { NULL, 0, 0, 0 } + }; + while ((opt = getopt_long(argc, argv, "CI:rtv", long_options, NULL)) != EOF) + switch (opt) { + case 'v': + printf("GNU soelim (groff) version %s\n", Version_string); + exit(0); + break; + case 'C': + compatible_flag = 1; + break; + case 'I': + include_search_path.command_line_dir(optarg); + break; + case 'r': + raw_flag = 1; + break; + case 't': + tex_flag = 1; + break; + case CHAR_MAX + 1: // --help + usage(stdout); + exit(0); + break; + case '?': + usage(stderr); + exit(1); + break; + default: + assert(0); + } + int nbad = 0; + if (optind >= argc) + nbad += !do_file("-"); + else + for (int i = optind; i < argc; i++) + nbad += !do_file(argv[i]); + if (ferror(stdout) || fflush(stdout) < 0) + fatal("output error"); + return nbad != 0; +} + +void set_location() +{ + if (!raw_flag) { + if (!tex_flag) + printf(".lf %d %s\n", current_lineno, current_filename); + else + printf("%% file %s, line %d\n", current_filename, current_lineno); + } +} + +void do_so(const char *line) +{ + const char *p = line; + while (*p == ' ') + p++; + string filename; + int success = 1; + for (const char *q = p; + success && *q != '\0' && *q != '\n' && *q != ' '; + q++) + if (*q == '\\') { + switch (*++q) { + case 'e': + case '\\': + filename += '\\'; + break; + case ' ': + filename += ' '; + break; + default: + success = 0; + break; + } + } + else + filename += char(*q); + if (success && filename.length() > 0) { + filename += '\0'; + const char *fn = current_filename; + int ln = current_lineno; + current_lineno--; + if (do_file(filename.contents())) { + current_filename = fn; + current_lineno = ln; + set_location(); + return; + } + current_lineno++; + } + fputs(".so", stdout); + fputs(line, stdout); +} + +int do_file(const char *filename) +{ + char *file_name_in_path = 0; + FILE *fp = include_search_path.open_file_cautious(filename, + &file_name_in_path); + int err = errno; + string whole_filename(file_name_in_path ? file_name_in_path : filename); + whole_filename += '\0'; + free(file_name_in_path); + if (fp == 0) { + error("can't open '%1': %2", whole_filename.contents(), strerror(err)); + return 0; + } + normalize_for_lf(whole_filename); + current_filename = whole_filename.contents(); + current_lineno = 1; + set_location(); + enum { START, MIDDLE, HAD_DOT, HAD_s, HAD_so, HAD_l, HAD_lf } state = START; + for (;;) { + int c = getc(fp); + if (c == EOF) + break; + switch (state) { + case START: + if (c == '.') + state = HAD_DOT; + else { + putchar(c); + if (c == '\n') { + current_lineno++; + state = START; + } + else + state = MIDDLE; + } + break; + case MIDDLE: + putchar(c); + if (c == '\n') { + current_lineno++; + state = START; + } + break; + case HAD_DOT: + if (c == 's') + state = HAD_s; + else if (c == 'l') + state = HAD_l; + else { + putchar('.'); + putchar(c); + if (c == '\n') { + current_lineno++; + state = START; + } + else + state = MIDDLE; + } + break; + case HAD_s: + if (c == 'o') + state = HAD_so; + else { + putchar('.'); + putchar('s'); + putchar(c); + if (c == '\n') { + current_lineno++; + state = START; + } + else + state = MIDDLE; + } + break; + case HAD_so: + if (c == ' ' || c == '\n' || compatible_flag) { + string line; + for (; c != EOF && c != '\n'; c = getc(fp)) + line += c; + current_lineno++; + line += '\n'; + line += '\0'; + do_so(line.contents()); + state = START; + } + else { + fputs(".so", stdout); + putchar(c); + state = MIDDLE; + } + break; + case HAD_l: + if (c == 'f') + state = HAD_lf; + else { + putchar('.'); + putchar('l'); + putchar(c); + if (c == '\n') { + current_lineno++; + state = START; + } + else + state = MIDDLE; + } + break; + case HAD_lf: + if (c == ' ' || c == '\n' || compatible_flag) { + string line; + for (; c != EOF && c != '\n'; c = getc(fp)) + line += c; + current_lineno++; + line += '\n'; + line += '\0'; + interpret_lf_args(line.contents()); + printf(".lf%s", line.contents()); + state = START; + } + else { + fputs(".lf", stdout); + putchar(c); + state = MIDDLE; + } + break; + default: + assert(0); + } + } + switch (state) { + case HAD_DOT: + fputs(".\n", stdout); + break; + case HAD_l: + fputs(".l\n", stdout); + break; + case HAD_s: + fputs(".s\n", stdout); + break; + case HAD_lf: + fputs(".lf\n", stdout); + break; + case HAD_so: + fputs(".so\n", stdout); + break; + case MIDDLE: + putc('\n', stdout); + break; + case START: + break; + } + if (fp != stdin) + fclose(fp); + current_filename = 0; + return 1; +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/tbl/main.cpp b/src/preproc/tbl/main.cpp new file mode 100644 index 0000000..db105c2 --- /dev/null +++ b/src/preproc/tbl/main.cpp @@ -0,0 +1,1692 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "table.h" + +#define MAX_POINT_SIZE 99 +#define MAX_VERTICAL_SPACING 72 + +extern "C" const char *Version_string; + +int compatible_flag = 0; + +class table_input { + FILE *fp; + enum { START, MIDDLE, + REREAD_T, REREAD_TE, REREAD_E, + LEADER_1, LEADER_2, LEADER_3, LEADER_4, + END, ERROR } state; + string unget_stack; +public: + table_input(FILE *); + int get(); + int ended() { return unget_stack.empty() && state == END; } + void unget(char); +}; + +table_input::table_input(FILE *p) +: fp(p), state(START) +{ +} + +void table_input::unget(char c) +{ + assert(c != '\0'); + unget_stack += c; + if (c == '\n') + current_lineno--; +} + +int table_input::get() +{ + int len = unget_stack.length(); + if (len != 0) { + unsigned char c = unget_stack[len - 1]; + unget_stack.set_length(len - 1); + if (c == '\n') + current_lineno++; + return c; + } + int c; + for (;;) { + switch (state) { + case START: + if ((c = getc(fp)) == '.') { + if ((c = getc(fp)) == 'T') { + if ((c = getc(fp)) == 'E') { + if (compatible_flag) { + state = END; + return EOF; + } + else { + c = getc(fp); + if (c != EOF) + ungetc(c, fp); + if (c == EOF || c == ' ' || c == '\n') { + state = END; + return EOF; + } + state = REREAD_TE; + return '.'; + } + } + else { + if (c != EOF) + ungetc(c, fp); + state = REREAD_T; + return '.'; + } + } + else { + if (c != EOF) + ungetc(c, fp); + state = MIDDLE; + return '.'; + } + } + else if (c == EOF) { + state = ERROR; + return EOF; + } + else { + if (c == '\n') + current_lineno++; + else { + state = MIDDLE; + if (c == '\0') { + error("invalid input character code 0"); + break; + } + } + return c; + } + break; + case MIDDLE: + // handle line continuation and uninterpreted leader character + if ((c = getc(fp)) == '\\') { + c = getc(fp); + if (c == '\n') { + current_lineno++; + c = getc(fp); + } + else if (c == 'a' && compatible_flag) { + state = LEADER_1; + return '\\'; + } + else { + if (c != EOF) + ungetc(c, fp); + c = '\\'; + } + } + if (c == EOF) { + state = ERROR; + return EOF; + } + else { + if (c == '\n') { + state = START; + current_lineno++; + } + else if (c == '\0') { + error("invalid input character code 0"); + break; + } + return c; + } + case REREAD_T: + state = MIDDLE; + return 'T'; + case REREAD_TE: + state = REREAD_E; + return 'T'; + case REREAD_E: + state = MIDDLE; + return 'E'; + case LEADER_1: + state = LEADER_2; + return '*'; + case LEADER_2: + state = LEADER_3; + return '('; + case LEADER_3: + state = LEADER_4; + return PREFIX_CHAR; + case LEADER_4: + state = MIDDLE; + return LEADER_CHAR; + case END: + case ERROR: + return EOF; + } + } +} + +void process_input_file(FILE *); +void process_table(table_input &in); + +void process_input_file(FILE *fp) +{ + enum { START, MIDDLE, HAD_DOT, HAD_T, HAD_TS, HAD_l, HAD_lf } state; + state = START; + int c; + while ((c = getc(fp)) != EOF) + switch (state) { + case START: + if (c == '.') + state = HAD_DOT; + else { + if (c == '\n') + current_lineno++; + else + state = MIDDLE; + putchar(c); + } + break; + case MIDDLE: + if (c == '\n') { + current_lineno++; + state = START; + } + putchar(c); + break; + case HAD_DOT: + if (c == 'T') + state = HAD_T; + else if (c == 'l') + state = HAD_l; + else { + putchar('.'); + putchar(c); + if (c == '\n') { + current_lineno++; + state = START; + } + else + state = MIDDLE; + } + break; + case HAD_T: + if (c == 'S') + state = HAD_TS; + else { + putchar('.'); + putchar('T'); + putchar(c); + if (c == '\n') { + current_lineno++; + state = START; + } + else + state = MIDDLE; + } + break; + case HAD_TS: + if (c == ' ' || c == '\n' || compatible_flag) { + putchar('.'); + putchar('T'); + putchar('S'); + while (c != '\n') { + if (c == EOF) { + error("end of file at beginning of table"); + return; + } + putchar(c); + c = getc(fp); + } + putchar('\n'); + current_lineno++; + { + table_input input(fp); + process_table(input); + set_troff_location(current_filename, current_lineno); + if (input.ended()) { + fputs(".TE", stdout); + while ((c = getc(fp)) != '\n') { + if (c == EOF) { + putchar('\n'); + return; + } + putchar(c); + } + putchar('\n'); + current_lineno++; + } + } + state = START; + } + else { + fputs(".TS", stdout); + putchar(c); + state = MIDDLE; + } + break; + case HAD_l: + if (c == 'f') + state = HAD_lf; + else { + putchar('.'); + putchar('l'); + putchar(c); + if (c == '\n') { + current_lineno++; + state = START; + } + else + state = MIDDLE; + } + break; + case HAD_lf: + if (c == ' ' || c == '\n' || compatible_flag) { + string line; + while (c != EOF) { + line += c; + if (c == '\n') { + current_lineno++; + break; + } + c = getc(fp); + } + line += '\0'; + interpret_lf_args(line.contents()); + printf(".lf%s", line.contents()); + state = START; + } + else { + fputs(".lf", stdout); + putchar(c); + state = MIDDLE; + } + break; + default: + assert(0 == "invalid `state` in switch"); + } + switch(state) { + case START: + break; + case MIDDLE: + putchar('\n'); + break; + case HAD_DOT: + fputs(".\n", stdout); + break; + case HAD_l: + fputs(".l\n", stdout); + break; + case HAD_T: + fputs(".T\n", stdout); + break; + case HAD_lf: + fputs(".lf\n", stdout); + break; + case HAD_TS: + fputs(".TS\n", stdout); + break; + } + if (fp != stdin) + fclose(fp); +} + +struct options { + unsigned flags; + int linesize; + char delim[2]; + char tab_char; + char decimal_point_char; + + options(); +}; + +options::options() +: flags(0), linesize(0), tab_char('\t'), decimal_point_char('.') +{ + delim[0] = delim[1] = '\0'; +} + +// Return non-zero if p and q are the same ignoring case. + +int strieq(const char *p, const char *q) +{ + for (; cmlower(*p) == cmlower(*q); p++, q++) + if (*p == '\0') + return 1; + return 0; +} + +// Handle region options. Return a null pointer if we should give up on +// this table. +options *process_options(table_input &in) +{ + options *opt = new options; + string line; + int level = 0; + for (;;) { + int c = in.get(); + if (c == EOF) { + int i = line.length(); + while (--i >= 0) + in.unget(line[i]); + return opt; + } + if (c == '\n') { + in.unget(c); + int i = line.length(); + while (--i >= 0) + in.unget(line[i]); + return opt; + } + else if (c == '(') + level++; + else if (c == ')') + level--; + else if (c == ';' && 0 == level) { + line += '\0'; + break; + } + line += c; + } + if (line.empty()) + return opt; + char *p = &line[0]; + for (;;) { + while (!csalpha(*p) && *p != '\0') + p++; + if (*p == '\0') + break; + char *q = p; + while (csalpha(*q)) + q++; + char *arg = 0; + if (*q != '(' && *q != '\0') + *q++ = '\0'; + while (csspace(*q)) + q++; + if (*q == '(') { + *q++ = '\0'; + arg = q; + while (*q != ')' && *q != '\0') + q++; + if (*q == '\0') + error("'%1' region option argument missing closing parenthesis", + arg); + else + *q++ = '\0'; + } + if (*p == '\0') { + if (arg) + error("'%1' region option argument cannot be empty", arg); + } + else if (strieq(p, "tab")) { + if (!arg) + error("'tab' region option requires argument in parentheses"); + else { + if (arg[0] == '\0' || arg[1] != '\0') + error("'tab' region option argument must be a single" + " character"); + else + opt->tab_char = arg[0]; + } + } + else if (strieq(p, "linesize")) { + if (!arg) + error("'linesize' region option requires argument in" + " parentheses"); + else { + if (sscanf(arg, "%d", &opt->linesize) != 1) + error("invalid argument to 'linesize' region option: '%1'", + arg); + else if (opt->linesize <= 0) { + error("'linesize' region option argument must be positive"); + opt->linesize = 0; + } + } + } + else if (strieq(p, "delim")) { + if (!arg) + error("'delim' region option requires argument in parentheses"); + else if (arg[0] == '\0' || arg[1] == '\0' || arg[2] != '\0') + error("argument to 'delim' option must be two characters"); + else { + opt->delim[0] = arg[0]; + opt->delim[1] = arg[1]; + } + } + else if (strieq(p, "center") || strieq(p, "centre")) { + if (arg) + error("'center' region option does not take an argument"); + opt->flags |= table::CENTER; + } + else if (strieq(p, "expand")) { + if (arg) + error("'expand' region option does not take an argument"); + opt->flags |= table::EXPAND; + opt->flags |= table::GAP_EXPAND; + } + else if (strieq(p, "box") || strieq(p, "frame")) { + if (arg) + error("'box' region option does not take an argument"); + opt->flags |= table::BOX; + } + else if (strieq(p, "doublebox") || strieq(p, "doubleframe")) { + if (arg) + error("'doublebox' region option does not take an argument"); + opt->flags |= table::DOUBLEBOX; + } + else if (strieq(p, "allbox")) { + if (arg) + error("'allbox' region option does not take an argument"); + opt->flags |= table::ALLBOX; + } + else if (strieq(p, "nokeep")) { + if (arg) + error("'nokeep' region option does not take an argument"); + opt->flags |= table::NOKEEP; + } + else if (strieq(p, "nospaces")) { + if (arg) + error("'nospaces' region option does not take an argument"); + opt->flags |= table::NOSPACES; + } + else if (strieq(p, "nowarn")) { + if (arg) + error("'nowarn' region option does not take an argument"); + opt->flags |= table::NOWARN; + } + else if (strieq(p, "decimalpoint")) { + if (!arg) + error("'decimalpoint' region option requires argument in" + " parentheses"); + else { + if (arg[0] == '\0' || arg[1] != '\0') + error("'decimalpoint' region option argument must be a single" + " character"); + else + opt->decimal_point_char = arg[0]; + } + } + else if (strieq(p, "experimental")) { + opt->flags |= table::EXPERIMENTAL; + } + else { + error("unrecognized region option '%1'", p); + // delete opt; + // return 0; + } + p = q; + } + return opt; +} + +entry_modifier::entry_modifier() +: vertical_alignment(CENTER), zero_width(0), stagger(0) +{ + vertical_spacing.inc = vertical_spacing.val = 0; + point_size.inc = point_size.val = 0; +} + +entry_modifier::~entry_modifier() +{ +} + +entry_format::entry_format() : type(FORMAT_LEFT) +{ +} + +entry_format::entry_format(format_type t) : type(t) +{ +} + +void entry_format::debug_print() const +{ + switch (type) { + case FORMAT_LEFT: + putc('l', stderr); + break; + case FORMAT_CENTER: + putc('c', stderr); + break; + case FORMAT_RIGHT: + putc('r', stderr); + break; + case FORMAT_NUMERIC: + putc('n', stderr); + break; + case FORMAT_ALPHABETIC: + putc('a', stderr); + break; + case FORMAT_SPAN: + putc('s', stderr); + break; + case FORMAT_VSPAN: + putc('^', stderr); + break; + case FORMAT_HLINE: + putc('_', stderr); + break; + case FORMAT_DOUBLE_HLINE: + putc('=', stderr); + break; + default: + assert(0 == "invalid column classifier in switch"); + break; + } + if (point_size.val != 0) { + putc('p', stderr); + if (point_size.inc > 0) + putc('+', stderr); + else if (point_size.inc < 0) + putc('-', stderr); + fprintf(stderr, "%d ", point_size.val); + } + if (vertical_spacing.val != 0) { + putc('v', stderr); + if (vertical_spacing.inc > 0) + putc('+', stderr); + else if (vertical_spacing.inc < 0) + putc('-', stderr); + fprintf(stderr, "%d ", vertical_spacing.val); + } + if (!font.empty()) { + putc('f', stderr); + put_string(font, stderr); + putc(' ', stderr); + } + if (!macro.empty()) { + putc('m', stderr); + put_string(macro, stderr); + putc(' ', stderr); + } + switch (vertical_alignment) { + case entry_modifier::CENTER: + break; + case entry_modifier::TOP: + putc('t', stderr); + break; + case entry_modifier::BOTTOM: + putc('d', stderr); + break; + } + if (zero_width) + putc('z', stderr); + if (stagger) + putc('u', stderr); +} + +struct format { + int nrows; + int ncolumns; + int *separation; + string *width; + char *equal; + char *expand; + entry_format **entry; + char **vline; + + format(int nr, int nc); + ~format(); + void add_rows(int n); +}; + +format::format(int nr, int nc) : nrows(nr), ncolumns(nc) +{ + int i; + separation = ncolumns > 1 ? new int[ncolumns - 1] : 0; + for (i = 0; i < ncolumns-1; i++) + separation[i] = -1; + width = new string[ncolumns]; + equal = new char[ncolumns]; + expand = new char[ncolumns]; + for (i = 0; i < ncolumns; i++) { + equal[i] = 0; + expand[i] = 0; + } + entry = new entry_format *[nrows]; + for (i = 0; i < nrows; i++) + entry[i] = new entry_format[ncolumns]; + vline = new char*[nrows]; + for (i = 0; i < nrows; i++) { + vline[i] = new char[ncolumns+1]; + for (int j = 0; j < ncolumns+1; j++) + vline[i][j] = 0; + } +} + +void format::add_rows(int n) +{ + int i; + char **old_vline = vline; + vline = new char*[nrows + n]; + for (i = 0; i < nrows; i++) + vline[i] = old_vline[i]; + delete[] old_vline; + for (i = 0; i < n; i++) { + vline[nrows + i] = new char[ncolumns + 1]; + for (int j = 0; j < ncolumns + 1; j++) + vline[nrows + i][j] = 0; + } + entry_format **old_entry = entry; + entry = new entry_format *[nrows + n]; + for (i = 0; i < nrows; i++) + entry[i] = old_entry[i]; + delete[] old_entry; + for (i = 0; i < n; i++) + entry[nrows + i] = new entry_format[ncolumns]; + nrows += n; +} + +format::~format() +{ + delete[] separation; + delete[] width; + delete[] equal; + delete[] expand; + for (int i = 0; i < nrows; i++) { + delete[] vline[i]; + delete[] entry[i]; + } + delete[] vline; + delete[] entry; +} + +struct input_entry_format : public entry_format { + input_entry_format *next; + string width; + int separation; + int vline; + int vline_count; + bool is_last_column; + bool is_equal_width; + int expand; + input_entry_format(format_type, input_entry_format * = 0); + ~input_entry_format(); + void debug_print(); +}; + +input_entry_format::input_entry_format(format_type t, input_entry_format *p) +: entry_format(t), next(p) +{ + separation = -1; + is_last_column = false; + vline = 0; + vline_count = 0; + is_equal_width = false; + expand = 0; +} + +input_entry_format::~input_entry_format() +{ +} + +void free_input_entry_format_list(input_entry_format *list) +{ + while (list) { + input_entry_format *tem = list; + list = list->next; + delete tem; + } +} + +void input_entry_format::debug_print() +{ + int i; + for (i = 0; i < vline_count; i++) + putc('|', stderr); + entry_format::debug_print(); + if (!width.empty()) { + putc('w', stderr); + putc('(', stderr); + put_string(width, stderr); + putc(')', stderr); + } + if (is_equal_width) + putc('e', stderr); + if (expand) + putc('x', stderr); + if (separation >= 0) + fprintf(stderr, "%d", separation); + for (i = 0; i < vline; i++) + putc('|', stderr); + if (is_last_column) + putc(',', stderr); +} + +// Interpret a table format specification, like "CC,LR.". Return null +// pointer if we should give up on this table. If this is a +// continuation format line, `current_format` will be the current format +// line. +format *process_format(table_input &in, options *opt, + format *current_format = 0) +{ + input_entry_format *list = 0 /* nullptr */; + bool have_expand = false; + bool is_first_row = true; + int c = in.get(); + for (;;) { + int vline_count = 0; + bool got_format = false; + bool got_period = false; + format_type t = FORMAT_LEFT; + for (;;) { + if (c == EOF) { + error("end of input while processing table format" + " specification"); + free_input_entry_format_list(list); + list = 0 /* nullptr */; + return 0 /* nullptr */; + } + switch (c) { + case 'n': + case 'N': + t = FORMAT_NUMERIC; + got_format = true; + break; + case 'a': + case 'A': + got_format = true; + t = FORMAT_ALPHABETIC; + break; + case 'c': + case 'C': + got_format = true; + t = FORMAT_CENTER; + break; + case 'l': + case 'L': + got_format = true; + t = FORMAT_LEFT; + break; + case 'r': + case 'R': + got_format = true; + t = FORMAT_RIGHT; + break; + case 's': + case 'S': + got_format = true; + t = FORMAT_SPAN; + break; + case '^': + got_format = true; + t = FORMAT_VSPAN; + break; + case '_': + case '-': // tbl also accepts this + got_format = true; + t = FORMAT_HLINE; + if (is_first_row) + opt->flags |= table::HAS_TOP_HLINE; + break; + case '=': + got_format = true; + t = FORMAT_DOUBLE_HLINE; + break; + case '.': + got_period = true; + break; + case '|': + // leading vertical line in row + opt->flags |= table::HAS_TOP_VLINE; + vline_count++; + // list->vline_count is updated later + break; + case ' ': + case '\t': + case '\n': + break; + default: + if (c == opt->tab_char) + break; + error("invalid column classifier '%1'", char(c)); + free_input_entry_format_list(list); + list = 0 /* nullptr */; + return 0 /* nullptr */; + } + if (got_period) + break; + c = in.get(); + if (got_format) + break; + } + if (got_period) + break; + list = new input_entry_format(t, list); + if (vline_count > 2) { + vline_count = 2; + error("more than 2 vertical lines at beginning of row description"); + } + list->vline_count = vline_count; + // Now handle modifiers. + vline_count = 0; + bool is_valid_modifier_sequence = true; + do { + switch (c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + int w = 0; + do { + w = w*10 + (c - '0'); + c = in.get(); + } while (c != EOF && csdigit(c)); + list->separation = w; + } + break; + case 'B': + case 'b': + c = in.get(); + list->font = "B"; + break; + case 'd': + case 'D': + c = in.get(); + list->vertical_alignment = entry_modifier::BOTTOM; + break; + case 'e': + case 'E': + c = in.get(); + list->is_equal_width = true; + // 'e' and 'x' are mutually exclusive + list->expand = 0; + break; + case 'f': + case 'F': + do { + c = in.get(); + } while (c == ' ' || c == '\t'); + if (c == EOF) { + error("'f' column modifier missing font name or mounting" + " position"); + break; + } + if (c == '(') { + for (;;) { + c = in.get(); + if (c == EOF || c == ' ' || c == '\t') { + error("'f' column modifier missing closing parenthesis"); + break; + } + if (c == ')') { + c = in.get(); + break; + } + list->font += char(c); + } + } + else { + list->font = c; + char cc = c; + c = in.get(); + if (!csdigit(cc) + && c != EOF && c != ' ' && c != '\t' && c != '.' && c != '\n') { + list->font += char(c); + c = in.get(); + } + } + break; + case 'I': + case 'i': + c = in.get(); + list->font = "I"; + break; + case 'm': + case 'M': + do { + c = in.get(); + } while (c == ' ' || c == '\t'); + if (c == EOF) { + error("'m' column modifier missing macro name"); + break; + } + if (c == '(') { + for (;;) { + c = in.get(); + if (c == EOF || c == ' ' || c == '\t') { + error("'m' column modifier missing closing parenthesis"); + break; + } + if (c == ')') { + c = in.get(); + break; + } + list->macro += char(c); + } + } + else { + list->macro = c; + char cc = c; + c = in.get(); + if (!csdigit(cc) + && c != EOF && c != ' ' && c != '\t' && c != '.' && c != '\n') { + list->macro += char(c); + c = in.get(); + } + } + break; + case 'p': + case 'P': + { + inc_number &ps = list->point_size; + ps.val = 0; + ps.inc = 0; + c = in.get(); + if (c == '+' || c == '-') { + ps.inc = (c == '+' ? 1 : -1); + c = in.get(); + } + if (c == EOF || !csdigit(c)) { + warning("'p' column modifier must be followed by" + " (optionally signed) integer; ignoring"); + ps.inc = 0; + } + else { + do { + ps.val *= 10; + ps.val += c - '0'; + c = in.get(); + } while (c != EOF && csdigit(c)); + } + if (ps.val > MAX_POINT_SIZE || ps.val < -MAX_POINT_SIZE) { + warning("'p' column modifier argument magnitude of %1" + " points out of range (> %2); ignoring", ps.val, + MAX_POINT_SIZE); + ps.val = 0; + ps.inc = 0; + } + break; + } + case 't': + case 'T': + c = in.get(); + list->vertical_alignment = entry_modifier::TOP; + break; + case 'u': + case 'U': + c = in.get(); + list->stagger = 1; + break; + case 'v': + case 'V': + { + inc_number &vs = list->vertical_spacing; + vs.val = 0; + vs.inc = 0; + c = in.get(); + if (c == '+' || c == '-') { + vs.inc = (c == '+' ? 1 : -1); + c = in.get(); + } + if (c == EOF || !csdigit(c)) { + warning("'v' column modifier must be followed by" + " (optionally signed) integer; ignoring"); + vs.inc = 0; + } + else { + do { + vs.val *= 10; + vs.val += c - '0'; + c = in.get(); + } while (c != EOF && csdigit(c)); + } + if (vs.val > MAX_VERTICAL_SPACING + || vs.val < -MAX_VERTICAL_SPACING) { + warning("'v' column modifier argument magnitude of %1" + " points out of range (> %2); ignoring", vs.val, + MAX_VERTICAL_SPACING); + vs.val = 0; + vs.inc = 0; + } + break; + } + case 'w': + case 'W': + c = in.get(); + while (c == ' ' || c == '\t') + c = in.get(); + if (c == '(') { + list->width = ""; + c = in.get(); + while (c != ')') { + if (c == EOF || c == '\n') { + error("'w' column modifier missing closing parenthesis"); + free_input_entry_format_list(list); + list = 0 /* nullptr */; + return 0 /* nullptr */; + } + list->width += c; + c = in.get(); + } + c = in.get(); + } + else { + if (c == '+' || c == '-') { + list->width = char(c); + c = in.get(); + } + else + list->width = ""; + if (c == EOF || !csdigit(c)) + error("invalid argument to 'w' modifier"); + else { + do { + list->width += char(c); + c = in.get(); + } while (c != EOF && csdigit(c)); + } + } + // 'w' and 'x' are mutually exclusive + list->expand = 0; + break; + case 'x': + case 'X': + c = in.get(); + list->expand = 1; + // 'x' and 'e' are mutually exclusive + list->is_equal_width = false; + // 'x' and 'w' are mutually exclusive + list->width = ""; + break; + case 'z': + case 'Z': + c = in.get(); + list->zero_width = 1; + break; + case '|': + if (is_first_row) + opt->flags |= table::HAS_TOP_VLINE; + c = in.get(); + vline_count++; + break; + case ' ': + case '\t': + c = in.get(); + break; + default: + if (c == opt->tab_char) + c = in.get(); + else + is_valid_modifier_sequence = false; + break; + } + } while (is_valid_modifier_sequence); + if (vline_count > 2) { + vline_count = 2; + error("more than 2 vertical lines after column descriptor"); + } + list->vline += vline_count; + if (c == '\n' || c == ',') { + vline_count = 0; + is_first_row = false; + c = in.get(); + list->is_last_column = true; + } + } + if (c == '.') { + do { + c = in.get(); + } while (c == ' ' || c == '\t'); + if (c != '\n') { + error("'.' is not the last character of the table format"); + free_input_entry_format_list(list); + list = 0 /* nullptr */; + return 0 /* nullptr */; + } + } + if (!list) { + error("table format specification is empty"); + free_input_entry_format_list(list); + list = 0 /* nullptr */; + return 0 /* nullptr */; + } + list->is_last_column = true; + // now reverse the list so that the first row is at the beginning + input_entry_format *rev = 0; + while (list != 0) { + input_entry_format *tem = list->next; + list->next = rev; + rev = list; + list = tem; + } + list = rev; + input_entry_format *tem; + +#if 0 + for (tem = list; tem; tem = tem->next) + tem->debug_print(); + putc('\n', stderr); +#endif + // compute number of columns and rows + int ncolumns = 0; + int nrows = 0; + int col = 0; + for (tem = list; tem; tem = tem->next) { + if (tem->is_last_column) { + if (col >= ncolumns) + ncolumns = col + 1; + col = 0; + nrows++; + } + else + col++; + } + int row; + format *f; + if (current_format) { + if (ncolumns > current_format->ncolumns) { + error("cannot increase the number of columns in a continued format"); + free_input_entry_format_list(list); + list = 0 /* nullptr */; + return 0 /* nullptr */; + } + f = current_format; + row = f->nrows; + f->add_rows(nrows); + } + else { + f = new format(nrows, ncolumns); + row = 0; + } + col = 0; + for (tem = list; tem; tem = tem->next) { + f->entry[row][col] = *tem; + if (col < ncolumns - 1) { + // use the greatest separation + if (tem->separation > f->separation[col]) { + if (current_format) + error("cannot change column separation in continued format"); + else + f->separation[col] = tem->separation; + } + } + else if (tem->separation >= 0) + error("column separation specified for last column"); + if (tem->is_equal_width && !f->equal[col]) { + if (current_format) + error("cannot change which columns are equal in continued format"); + else + f->equal[col] = 1; + } + if (tem->expand && !f->expand[col]) { + if (current_format) + error("cannot change which columns are expanded in continued format"); + else { + f->expand[col] = 1; + have_expand = true; + } + } + if (!tem->width.empty()) { + // use the last width + if (!f->width[col].empty() && f->width[col] != tem->width) + error("multiple widths for column %1", col + 1); + f->width[col] = tem->width; + } + if (tem->vline_count) + f->vline[row][col] = tem->vline_count; + f->vline[row][col + 1] = tem->vline; + if (tem->is_last_column) { + row++; + col = 0; + } + else + col++; + } + free_input_entry_format_list(list); + list = 0 /* nullptr */; + for (col = 0; col < ncolumns; col++) { + entry_format *e = f->entry[f->nrows - 1] + col; + if (e->type != FORMAT_HLINE + && e->type != FORMAT_DOUBLE_HLINE + && e->type != FORMAT_SPAN) + break; + } + if (col >= ncolumns) { + error("last row of format is all lines"); + delete f; + return 0 /* nullptr */; + } + if (have_expand && (opt->flags & table::EXPAND)) { + error("'x' column modifier encountered; ignoring region option" + " 'expand'"); + opt->flags &= ~table::EXPAND; + } + return f; +} + +table *process_data(table_input &in, format *f, options *opt) +{ + char tab_char = opt->tab_char; + int ncolumns = f->ncolumns; + int current_row = 0; + int format_index = 0; + bool give_up = false; + enum { DATA_INPUT_LINE, TROFF_INPUT_LINE, SINGLE_HLINE, DOUBLE_HLINE } type; + table *tbl = new table(ncolumns, opt->flags, opt->linesize, + opt->decimal_point_char); + if (opt->delim[0] != '\0') + tbl->set_delim(opt->delim[0], opt->delim[1]); + for (;;) { + // first determine what type of line this is + int c = in.get(); + if (c == EOF) + break; + if (c == '.') { + int d = in.get(); + if (d != EOF && csdigit(d)) { + in.unget(d); + type = DATA_INPUT_LINE; + } + else { + in.unget(d); + type = TROFF_INPUT_LINE; + } + } + else if (c == '_' || c == '=') { + int d = in.get(); + if (d == '\n') { + if (c == '_') + type = SINGLE_HLINE; + else + type = DOUBLE_HLINE; + if (0 == current_row) + tbl->flags |= table::HAS_TOP_HLINE; + } + else { + in.unget(d); + type = DATA_INPUT_LINE; + } + } + else { + type = DATA_INPUT_LINE; + } + switch (type) { + case DATA_INPUT_LINE: + { + string input_entry; + if (format_index >= f->nrows) + format_index = f->nrows - 1; + // A format row that is all lines doesn't use up a data line. + while (format_index < f->nrows - 1) { + int cnt; + for (cnt = 0; cnt < ncolumns; cnt++) { + entry_format *e = f->entry[format_index] + cnt; + if (e->type != FORMAT_HLINE + && e->type != FORMAT_DOUBLE_HLINE + // Unfortunately tbl treats a span as needing data. + // && e->type != FORMAT_SPAN + ) + break; + } + if (cnt < ncolumns) + break; + for (cnt = 0; cnt < ncolumns; cnt++) + tbl->add_entry(current_row, cnt, input_entry, + f->entry[format_index] + cnt, current_filename, + current_lineno); + tbl->add_vlines(current_row, f->vline[format_index]); + format_index++; + current_row++; + } + entry_format *line_format = f->entry[format_index]; + int col = 0; + bool seen_row_comment = false; + for (;;) { + if (c == tab_char || c == '\n') { + int ln = current_lineno; + if (c == '\n') + --ln; + if ((opt->flags & table::NOSPACES)) + input_entry.remove_spaces(); + while (col < ncolumns + && line_format[col].type == FORMAT_SPAN) { + tbl->add_entry(current_row, col, "", &line_format[col], + current_filename, ln); + col++; + } + if (c == '\n' && input_entry.length() == 2 + && input_entry[0] == 'T' && input_entry[1] == '{') { + input_entry = ""; + ln++; + enum { + START, MIDDLE, GOT_T, GOT_RIGHT_BRACE, GOT_DOT, + GOT_l, GOT_lf, END + } state = START; + while (state != END) { + c = in.get(); + if (c == EOF) + break; + switch (state) { + case START: + if (c == 'T') + state = GOT_T; + else if (c == '.') + state = GOT_DOT; + else { + input_entry += c; + if (c != '\n') + state = MIDDLE; + } + break; + case GOT_T: + if (c == '}') + state = GOT_RIGHT_BRACE; + else { + input_entry += 'T'; + input_entry += c; + state = c == '\n' ? START : MIDDLE; + } + break; + case GOT_DOT: + if (c == 'l') + state = GOT_l; + else { + input_entry += '.'; + input_entry += c; + state = c == '\n' ? START : MIDDLE; + } + break; + case GOT_l: + if (c == 'f') + state = GOT_lf; + else { + input_entry += ".l"; + input_entry += c; + state = c == '\n' ? START : MIDDLE; + } + break; + case GOT_lf: + if (c == ' ' || c == '\n' || compatible_flag) { + string args; + input_entry += ".lf"; + while (c != EOF) { + args += c; + if (c == '\n') + break; + c = in.get(); + } + args += '\0'; + interpret_lf_args(args.contents()); + // remove the '\0' + args.set_length(args.length() - 1); + input_entry += args; + state = START; + } + else { + input_entry += ".lf"; + input_entry += c; + state = MIDDLE; + } + break; + case GOT_RIGHT_BRACE: + if ((opt->flags & table::NOSPACES)) { + while (c == ' ') + c = in.get(); + if (c == EOF) + break; + } + if (c == '\n' || c == tab_char) + state = END; + else { + input_entry += 'T'; + input_entry += '}'; + input_entry += c; + state = MIDDLE; + } + break; + case MIDDLE: + if (c == '\n') + state = START; + input_entry += c; + break; + case END: + default: + assert(0 == "invalid `state` in switch"); + } + } + if (c == EOF) { + error("end of data in middle of text block"); + give_up = true; + break; + } + } + if (col >= ncolumns) { + if (!input_entry.empty()) { + if (input_entry.length() >= 2 + && input_entry[0] == '\\' + && input_entry[1] == '"') + seen_row_comment = true; + else if (!seen_row_comment) { + if (c == '\n') + in.unget(c); + input_entry += '\0'; + error("excess table entry '%1' discarded", + input_entry.contents()); + if (c == '\n') + (void)in.get(); + } + } + } + else + tbl->add_entry(current_row, col, input_entry, + &line_format[col], current_filename, ln); + col++; + if (c == '\n') + break; + input_entry = ""; + } + else + input_entry += c; + c = in.get(); + if (c == EOF) + break; + } + if (give_up) + break; + input_entry = ""; + for (; col < ncolumns; col++) + tbl->add_entry(current_row, col, input_entry, &line_format[col], + current_filename, current_lineno - 1); + tbl->add_vlines(current_row, f->vline[format_index]); + current_row++; + format_index++; + } + break; + case TROFF_INPUT_LINE: + { + string line; + int ln = current_lineno; + for (;;) { + line += c; + if (c == '\n') + break; + c = in.get(); + if (c == EOF) { + break; + } + } + tbl->add_text_line(current_row, line, current_filename, ln); + if (line.length() >= 4 + && line[0] == '.' && line[1] == 'T' && line[2] == '&') { + format *newf = process_format(in, opt, f); + if (newf == 0) + give_up = true; + else + f = newf; + } + if (line.length() >= 3 + && line[0] == '.' && line[1] == 'l' && line[2] == 'f') { + line += '\0'; + interpret_lf_args(line.contents() + 3); + } + } + break; + case SINGLE_HLINE: + tbl->add_single_hline(current_row); + break; + case DOUBLE_HLINE: + tbl->add_double_hline(current_row); + break; + default: + assert(0 == "invalid `type` in switch"); + } + if (give_up) + break; + } + if (!give_up && current_row == 0) { + error("no real data"); + give_up = true; + } + if (give_up) { + delete tbl; + return 0; + } + // Do this here rather than at the beginning in case continued formats + // change it. + int i; + for (i = 0; i < ncolumns - 1; i++) + if (f->separation[i] >= 0) + tbl->set_column_separation(i, f->separation[i]); + for (i = 0; i < ncolumns; i++) + if (!f->width[i].empty()) + tbl->set_minimum_width(i, f->width[i]); + for (i = 0; i < ncolumns; i++) + if (f->equal[i]) + tbl->set_equal_column(i); + for (i = 0; i < ncolumns; i++) + if (f->expand[i]) + tbl->set_expand_column(i); + return tbl; +} + +void process_table(table_input &in) +{ + options *opt = 0 /* nullptr */; + format *fmt = 0 /* nullptr */; + table *tbl = 0 /* nullptr */; + if ((opt = process_options(in)) != 0 /* nullptr */ + && (fmt = process_format(in, opt)) != 0 /* nullptr */ + && (tbl = process_data(in, fmt, opt)) != 0 /* nullptr */) { + tbl->print(); + delete tbl; + } + else { + error("giving up on this table region"); + while (in.get() != EOF) + ; + } + delete opt; + delete fmt; + if (!in.ended()) + error("premature end of file"); +} + +static void usage(FILE *stream) +{ + fprintf(stream, +"usage: %s [-C] [file ...]\n" +"usage: %s {-v | --version}\n" +"usage: %s --help\n", + program_name, program_name, program_name); +} + +int main(int argc, char **argv) +{ + program_name = argv[0]; + static char stderr_buf[BUFSIZ]; + setbuf(stderr, stderr_buf); + int opt; + static const struct option long_options[] = { + { "help", no_argument, 0, CHAR_MAX + 1 }, + { "version", no_argument, 0, 'v' }, + { NULL, 0, 0, 0 } + }; + while ((opt = getopt_long(argc, argv, "vC", long_options, NULL)) + != EOF) + switch (opt) { + case 'C': + compatible_flag = 1; + break; + case 'v': + { + printf("GNU tbl (groff) version %s\n", Version_string); + exit(EXIT_SUCCESS); + break; + } + case CHAR_MAX + 1: // --help + usage(stdout); + exit(EXIT_SUCCESS); + break; + case '?': + usage(stderr); + exit(EXIT_FAILURE); + break; + default: + assert(0 == "unhandled getopt_long return value"); + } + printf(".if !\\n(.g .ab GNU tbl requires groff extensions; aborting\n" + ".do if !dTS .ds TS\n" + ".do if !dT& .ds T&\n" + ".do if !dTE .ds TE\n"); + if (argc > optind) { + for (int i = optind; i < argc; i++) + if (argv[i][0] == '-' && argv[i][1] == '\0') { + current_filename = "-"; + current_lineno = 1; + printf(".lf 1 -\n"); + process_input_file(stdin); + } + else { + errno = 0; + FILE *fp = fopen(argv[i], "r"); + if (fp == 0) { + current_filename = 0 /* nullptr */; + fatal("can't open '%1': %2", argv[i], strerror(errno)); + } + else { + current_lineno = 1; + string fn(argv[i]); + fn += '\0'; + normalize_for_lf(fn); + current_filename = fn.contents(); + printf(".lf 1 %s\n", current_filename); + process_input_file(fp); + } + } + } + else { + current_filename = "-"; + current_lineno = 1; + printf(".lf 1 -\n"); + process_input_file(stdin); + } + if (ferror(stdout) || fflush(stdout) < 0) + fatal("output error"); + return 0; +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/tbl/table.cpp b/src/preproc/tbl/table.cpp new file mode 100644 index 0000000..c391c90 --- /dev/null +++ b/src/preproc/tbl/table.cpp @@ -0,0 +1,3161 @@ +/* Copyright (C) 1989-2023 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "table.h" + +#define BAR_HEIGHT ".25m" +#define DOUBLE_LINE_SEP "2p" +#define HALF_DOUBLE_LINE_SEP "1p" +#define LINE_SEP "2p" +#define BODY_DEPTH ".25m" + +const int DEFAULT_COLUMN_SEPARATION = 3; + +#define DELIMITER_CHAR "\\[tbl]" +#define SEPARATION_FACTOR_REG PREFIX "sep" +#define LEFTOVER_FACTOR_REG PREFIX "leftover" +#define BOTTOM_REG PREFIX "bot" +#define RESET_MACRO_NAME PREFIX "init" +#define LINESIZE_REG PREFIX "lps" +#define TOP_REG PREFIX "top" +#define CURRENT_ROW_REG PREFIX "crow" +#define LAST_PASSED_ROW_REG PREFIX "passed" +#define TRANSPARENT_STRING_NAME PREFIX "trans" +#define QUOTE_STRING_NAME PREFIX "quote" +#define SECTION_DIVERSION_NAME PREFIX "section" +#define SECTION_DIVERSION_FLAG_REG PREFIX "sflag" +#define SAVED_VERTICAL_POS_REG PREFIX "vert" +#define NEED_BOTTOM_RULE_REG PREFIX "brule" +#define USE_KEEPS_REG PREFIX "usekeeps" +#define KEEP_MACRO_NAME PREFIX "keep" +#define RELEASE_MACRO_NAME PREFIX "release" +#define SAVED_FONT_REG PREFIX "fnt" +#define SAVED_SIZE_REG PREFIX "sz" +#define SAVED_FILL_REG PREFIX "fll" +#define SAVED_INDENT_REG PREFIX "ind" +#define SAVED_CENTER_REG PREFIX "cent" +#define SAVED_TABS_NAME PREFIX "tabs" +#define SAVED_INTER_WORD_SPACE_SIZE PREFIX "ss" +#define SAVED_INTER_SENTENCE_SPACE_SIZE PREFIX "sss" +#define TABLE_DIVERSION_NAME PREFIX "table" +#define TABLE_DIVERSION_FLAG_REG PREFIX "tflag" +#define TABLE_KEEP_MACRO_NAME PREFIX "tkeep" +#define TABLE_RELEASE_MACRO_NAME PREFIX "trelease" +#define NEEDED_REG PREFIX "needed" +#define REPEATED_MARK_MACRO PREFIX "rmk" +#define REPEATED_VPT_MACRO PREFIX "rvpt" +#define SUPPRESS_BOTTOM_REG PREFIX "supbot" +#define SAVED_DN_REG PREFIX "dn" +#define SAVED_HYPHENATION_MODE_REG PREFIX "hyphmode" +#define SAVED_HYPHENATION_LANG_NAME PREFIX "hyphlang" +#define SAVED_HYPHENATION_MAX_LINES_REG PREFIX "hyphmaxlines" +#define SAVED_HYPHENATION_MARGIN_REG PREFIX "hyphmargin" +#define SAVED_HYPHENATION_SPACE_REG PREFIX "hyphspace" +#define SAVED_NUMBERING_LINENO PREFIX "linenumber" +#define SAVED_NUMBERING_SUPPRESSION_COUNT PREFIX "linenumbersuppresscnt" +#define STARTING_PAGE_REG PREFIX "starting-page" +#define IS_BOXED_REG PREFIX "is-boxed" +#define PREVIOUS_PAGE_REG PREFIX "previous-page" + +// this must be one character +#define COMPATIBLE_REG PREFIX "c" + +// for use with `ig` requests embedded inside macro definitions +#define NOP_NAME PREFIX "nop" + +#define AVAILABLE_WIDTH_REG PREFIX "available-width" +#define EXPAND_REG PREFIX "expansion-amount" + +#define LEADER_REG PREFIX LEADER + +#define BLOCK_WIDTH_PREFIX PREFIX "tbw" +#define BLOCK_DIVERSION_PREFIX PREFIX "tbd" +#define BLOCK_HEIGHT_PREFIX PREFIX "tbh" +#define SPAN_WIDTH_PREFIX PREFIX "w" +#define SPAN_LEFT_NUMERIC_WIDTH_PREFIX PREFIX "lnw" +#define SPAN_RIGHT_NUMERIC_WIDTH_PREFIX PREFIX "rnw" +#define SPAN_ALPHABETIC_WIDTH_PREFIX PREFIX "aw" +#define COLUMN_SEPARATION_PREFIX PREFIX "cs" +#define ROW_START_PREFIX PREFIX "rs" +#define COLUMN_START_PREFIX PREFIX "cl" +#define COLUMN_END_PREFIX PREFIX "ce" +#define COLUMN_DIVIDE_PREFIX PREFIX "cd" +#define ROW_TOP_PREFIX PREFIX "rt" + +string block_width_reg(int, int); +string block_diversion_name(int, int); +string block_height_reg(int, int); +string span_width_reg(int, int); +string span_left_numeric_width_reg(int, int); +string span_right_numeric_width_reg(int, int); +string span_alphabetic_width_reg(int, int); +string column_separation_reg(int); +string row_start_reg(int); +string column_start_reg(int); +string column_end_reg(int); +string column_divide_reg(int); +string row_top_reg(int); + +void set_inline_modifier(const entry_modifier *); +void restore_inline_modifier(const entry_modifier *); +void set_modifier(const entry_modifier *); +int find_decimal_point(const char *, char, const char *); + +string an_empty_string; +int location_force_filename = 0; + +void printfs(const char *, + const string &arg1 = an_empty_string, + const string &arg2 = an_empty_string, + const string &arg3 = an_empty_string, + const string &arg4 = an_empty_string, + const string &arg5 = an_empty_string); + +void prints(const string &); + +inline void prints(char c) +{ + putchar(c); +} + +inline void prints(const char *s) +{ + fputs(s, stdout); +} + +void prints(const string &s) +{ + if (!s.empty()) + fwrite(s.contents(), 1, s.length(), stdout); +} + +struct horizontal_span { + horizontal_span *next; + int start_col; + int end_col; + horizontal_span(int, int, horizontal_span *); +}; + +class single_line_entry; +class double_line_entry; +class simple_entry; + +class table_entry { +friend class table; + table_entry *next; + int input_lineno; + const char *input_filename; +protected: + int start_row; + int end_row; + int start_col; + int end_col; + const table *parent; + const entry_modifier *mod; +public: + void set_location(); + table_entry(const table *, const entry_modifier *); + virtual ~table_entry(); + virtual int divert(int, const string *, int *, int); + virtual void do_width(); + virtual void do_depth(); + virtual void print() = 0; + virtual void position_vertically() = 0; + virtual single_line_entry *to_single_line_entry(); + virtual double_line_entry *to_double_line_entry(); + virtual simple_entry *to_simple_entry(); + virtual int line_type(); + virtual void note_double_vrule_on_right(int); + virtual void note_double_vrule_on_left(int); +}; + +class simple_entry : public table_entry { +public: + simple_entry(const table *, const entry_modifier *); + void print(); + void position_vertically(); + simple_entry *to_simple_entry(); + virtual void add_tab(); + virtual void simple_print(int); +}; + +class empty_entry : public simple_entry { +public: + empty_entry(const table *, const entry_modifier *); + int line_type(); +}; + +class text_entry : public simple_entry { +protected: + char *contents; + void print_contents(); +public: + text_entry(const table *, const entry_modifier *, char *); + ~text_entry(); +}; + +void text_entry::print_contents() +{ + set_inline_modifier(mod); + prints(contents); + restore_inline_modifier(mod); +} + +class repeated_char_entry : public text_entry { +public: + repeated_char_entry(const table *, const entry_modifier *, char *); + void simple_print(int); +}; + +class simple_text_entry : public text_entry { +public: + simple_text_entry(const table *, const entry_modifier *, char *); + void do_width(); +}; + +class left_text_entry : public simple_text_entry { +public: + left_text_entry(const table *, const entry_modifier *, char *); + void simple_print(int); + void add_tab(); +}; + +class right_text_entry : public simple_text_entry { +public: + right_text_entry(const table *, const entry_modifier *, char *); + void simple_print(int); + void add_tab(); +}; + +class center_text_entry : public simple_text_entry { +public: + center_text_entry(const table *, const entry_modifier *, char *); + void simple_print(int); + void add_tab(); +}; + +class numeric_text_entry : public text_entry { + int dot_pos; +public: + numeric_text_entry(const table *, const entry_modifier *, char *, int); + void do_width(); + void simple_print(int); +}; + +class alphabetic_text_entry : public text_entry { +public: + alphabetic_text_entry(const table *, const entry_modifier *, char *); + void do_width(); + void simple_print(int); + void add_tab(); +}; + +class line_entry : public simple_entry { +protected: + char double_vrule_on_right; + char double_vrule_on_left; +public: + line_entry(const table *, const entry_modifier *); + void note_double_vrule_on_right(int); + void note_double_vrule_on_left(int); + void simple_print(int) = 0; +}; + +class single_line_entry : public line_entry { +public: + single_line_entry(const table *, const entry_modifier *); + void simple_print(int); + single_line_entry *to_single_line_entry(); + int line_type(); +}; + +class double_line_entry : public line_entry { +public: + double_line_entry(const table *, const entry_modifier *); + void simple_print(int); + double_line_entry *to_double_line_entry(); + int line_type(); +}; + +class short_line_entry : public simple_entry { +public: + short_line_entry(const table *, const entry_modifier *); + void simple_print(int); + int line_type(); +}; + +class short_double_line_entry : public simple_entry { +public: + short_double_line_entry(const table *, const entry_modifier *); + void simple_print(int); + int line_type(); +}; + +class block_entry : public table_entry { + char *contents; +protected: + void do_divert(int, int, const string *, int *, int); +public: + block_entry(const table *, const entry_modifier *, char *); + ~block_entry(); + int divert(int, const string *, int *, int); + void do_depth(); + void position_vertically(); + void print() = 0; +}; + +class left_block_entry : public block_entry { +public: + left_block_entry(const table *, const entry_modifier *, char *); + void print(); +}; + +class right_block_entry : public block_entry { +public: + right_block_entry(const table *, const entry_modifier *, char *); + void print(); +}; + +class center_block_entry : public block_entry { +public: + center_block_entry(const table *, const entry_modifier *, char *); + void print(); +}; + +class alphabetic_block_entry : public block_entry { +public: + alphabetic_block_entry(const table *, const entry_modifier *, char *); + void print(); + int divert(int, const string *, int *, int); +}; + +table_entry::table_entry(const table *p, const entry_modifier *m) +: next(0), input_lineno(-1), input_filename(0), + start_row(-1), end_row(-1), start_col(-1), end_col(-1), parent(p), mod(m) +{ +} + +table_entry::~table_entry() +{ +} + +int table_entry::divert(int, const string *, int *, int) +{ + return 0; +} + +void table_entry::do_width() +{ +} + +single_line_entry *table_entry::to_single_line_entry() +{ + return 0; +} + +double_line_entry *table_entry::to_double_line_entry() +{ + return 0; +} + +simple_entry *table_entry::to_simple_entry() +{ + return 0; +} + +void table_entry::do_depth() +{ +} + +void table_entry::set_location() +{ + set_troff_location(input_filename, input_lineno); +} + +int table_entry::line_type() +{ + return -1; +} + +void table_entry::note_double_vrule_on_right(int) +{ +} + +void table_entry::note_double_vrule_on_left(int) +{ +} + +simple_entry::simple_entry(const table *p, const entry_modifier *m) +: table_entry(p, m) +{ +} + +void simple_entry::add_tab() +{ + // do nothing +} + +void simple_entry::simple_print(int) +{ + // do nothing +} + +void simple_entry::position_vertically() +{ + if (start_row != end_row) + switch (mod->vertical_alignment) { + case entry_modifier::TOP: + printfs(".sp |\\n[%1]u\n", row_start_reg(start_row)); + break; + case entry_modifier::CENTER: + // Perform the motion in two stages so that the center is rounded + // vertically upwards even if net vertical motion is upwards. + printfs(".sp |\\n[%1]u\n", row_start_reg(start_row)); + printfs(".sp \\n[" BOTTOM_REG "]u-\\n[%1]u-1v/2u\n", + row_start_reg(start_row)); + break; + case entry_modifier::BOTTOM: + printfs(".sp |\\n[%1]u+\\n[" BOTTOM_REG "]u-\\n[%1]u-1v\n", + row_start_reg(start_row)); + break; + default: + assert(0 == "simple entry vertical position modifier not TOP," + " CENTER, or BOTTOM"); + } +} + +void simple_entry::print() +{ + prints(".ta"); + add_tab(); + prints('\n'); + set_location(); + prints("\\&"); + simple_print(0); + prints('\n'); +} + +simple_entry *simple_entry::to_simple_entry() +{ + return this; +} + +empty_entry::empty_entry(const table *p, const entry_modifier *m) +: simple_entry(p, m) +{ +} + +int empty_entry::line_type() +{ + return 0; +} + +text_entry::text_entry(const table *p, const entry_modifier *m, char *s) +: simple_entry(p, m), contents(s) +{ +} + +text_entry::~text_entry() +{ + free(contents); +} + +repeated_char_entry::repeated_char_entry(const table *p, + const entry_modifier *m, char *s) +: text_entry(p, m, s) +{ +} + +void repeated_char_entry::simple_print(int) +{ + printfs("\\h'|\\n[%1]u'", column_start_reg(start_col)); + set_inline_modifier(mod); + printfs("\\l" DELIMITER_CHAR "\\n[%1]u\\&", + span_width_reg(start_col, end_col)); + prints(contents); + prints(DELIMITER_CHAR); + restore_inline_modifier(mod); +} + +simple_text_entry::simple_text_entry(const table *p, + const entry_modifier *m, char *s) +: text_entry(p, m, s) +{ +} + +void simple_text_entry::do_width() +{ + set_location(); + printfs(".nr %1 \\n[%1]>?\\w" DELIMITER_CHAR, + span_width_reg(start_col, end_col)); + print_contents(); + prints(DELIMITER_CHAR "\n"); +} + +left_text_entry::left_text_entry(const table *p, + const entry_modifier *m, char *s) +: simple_text_entry(p, m, s) +{ +} + +void left_text_entry::simple_print(int) +{ + printfs("\\h'|\\n[%1]u'", column_start_reg(start_col)); + print_contents(); +} + +// The only point of this is to make '\a' "work" as in Unix tbl. Grrr. + +void left_text_entry::add_tab() +{ + printfs(" \\n[%1]u", column_end_reg(end_col)); +} + +right_text_entry::right_text_entry(const table *p, + const entry_modifier *m, char *s) +: simple_text_entry(p, m, s) +{ +} + +void right_text_entry::simple_print(int) +{ + printfs("\\h'|\\n[%1]u'", column_start_reg(start_col)); + prints("\002\003"); + print_contents(); + prints("\002"); +} + +void right_text_entry::add_tab() +{ + printfs(" \\n[%1]u", column_end_reg(end_col)); +} + +center_text_entry::center_text_entry(const table *p, + const entry_modifier *m, char *s) +: simple_text_entry(p, m, s) +{ +} + +void center_text_entry::simple_print(int) +{ + printfs("\\h'|\\n[%1]u'", column_start_reg(start_col)); + prints("\002\003"); + print_contents(); + prints("\003\002"); +} + +void center_text_entry::add_tab() +{ + printfs(" \\n[%1]u", column_end_reg(end_col)); +} + +numeric_text_entry::numeric_text_entry(const table *p, + const entry_modifier *m, + char *s, int pos) +: text_entry(p, m, s), dot_pos(pos) +{ +} + +void numeric_text_entry::do_width() +{ + if (dot_pos != 0) { + set_location(); + printfs(".nr %1 0\\w" DELIMITER_CHAR, + block_width_reg(start_row, start_col)); + set_inline_modifier(mod); + for (int i = 0; i < dot_pos; i++) + prints(contents[i]); + restore_inline_modifier(mod); + prints(DELIMITER_CHAR "\n"); + printfs(".nr %1 \\n[%1]>?\\n[%2]\n", + span_left_numeric_width_reg(start_col, end_col), + block_width_reg(start_row, start_col)); + } + else + printfs(".nr %1 0\n", block_width_reg(start_row, start_col)); + if (contents[dot_pos] != '\0') { + set_location(); + printfs(".nr %1 \\n[%1]>?\\w" DELIMITER_CHAR, + span_right_numeric_width_reg(start_col, end_col)); + set_inline_modifier(mod); + prints(contents + dot_pos); + restore_inline_modifier(mod); + prints(DELIMITER_CHAR "\n"); + } +} + +void numeric_text_entry::simple_print(int) +{ + printfs("\\h'|(\\n[%1]u-\\n[%2]u-\\n[%3]u/2u+\\n[%2]u+\\n[%4]u-\\n[%5]u)'", + span_width_reg(start_col, end_col), + span_left_numeric_width_reg(start_col, end_col), + span_right_numeric_width_reg(start_col, end_col), + column_start_reg(start_col), + block_width_reg(start_row, start_col)); + print_contents(); +} + +alphabetic_text_entry::alphabetic_text_entry(const table *p, + const entry_modifier *m, + char *s) +: text_entry(p, m, s) +{ +} + +void alphabetic_text_entry::do_width() +{ + set_location(); + printfs(".nr %1 \\n[%1]>?\\w" DELIMITER_CHAR, + span_alphabetic_width_reg(start_col, end_col)); + print_contents(); + prints(DELIMITER_CHAR "\n"); +} + +void alphabetic_text_entry::simple_print(int) +{ + printfs("\\h'|\\n[%1]u'", column_start_reg(start_col)); + printfs("\\h'\\n[%1]u-\\n[%2]u/2u'", + span_width_reg(start_col, end_col), + span_alphabetic_width_reg(start_col, end_col)); + print_contents(); +} + +// The only point of this is to make '\a' "work" as in Unix tbl. Grrr. + +void alphabetic_text_entry::add_tab() +{ + printfs(" \\n[%1]u", column_end_reg(end_col)); +} + +block_entry::block_entry(const table *p, const entry_modifier *m, char *s) +: table_entry(p, m), contents(s) +{ +} + +block_entry::~block_entry() +{ + delete[] contents; +} + +void block_entry::position_vertically() +{ + if (start_row != end_row) + switch(mod->vertical_alignment) { + case entry_modifier::TOP: + printfs(".sp |\\n[%1]u\n", row_start_reg(start_row)); + break; + case entry_modifier::CENTER: + // Perform the motion in two stages so that the center is rounded + // vertically upwards even if net vertical motion is upwards. + printfs(".sp |\\n[%1]u\n", row_start_reg(start_row)); + printfs(".sp \\n[" BOTTOM_REG "]u-\\n[%1]u-\\n[%2]u/2u\n", + row_start_reg(start_row), + block_height_reg(start_row, start_col)); + break; + case entry_modifier::BOTTOM: + printfs(".sp |\\n[%1]u+\\n[" BOTTOM_REG "]u-\\n[%1]u-\\n[%2]u\n", + row_start_reg(start_row), + block_height_reg(start_row, start_col)); + break; + default: + assert(0 == "block entry vertical position modifier not TOP," + " CENTER, or BOTTOM"); + } + if (mod->stagger) + prints(".sp -.5v\n"); +} + +int block_entry::divert(int ncols, const string *mw, int *sep, int do_expand) +{ + do_divert(0, ncols, mw, sep, do_expand); + return 1; +} + +void block_entry::do_divert(int alphabetic, int ncols, const string *mw, + int *sep, int do_expand) +{ + int i; + for (i = start_col; i <= end_col; i++) + if (parent->expand[i]) + break; + if (i > end_col) { + if (do_expand) + return; + } + else { + if (!do_expand) + return; + } + printfs(".di %1\n", block_diversion_name(start_row, start_col)); + prints(".if \\n[" SAVED_FILL_REG "] .fi\n" + ".in 0\n"); + prints(".ll "); + for (i = start_col; i <= end_col; i++) + if (mw[i].empty() && !parent->expand[i]) + break; + if (i > end_col) { + // Every column spanned by this entry has a minimum width. + for (int j = start_col; j <= end_col; j++) { + if (j > start_col) { + if (sep) + printfs("+%1n", as_string(sep[j - 1])); + prints('+'); + } + if (parent->expand[j]) + prints("\\n[" EXPAND_REG "]u"); + else + printfs("(n;%1)", mw[j]); + } + printfs(">?\\n[%1]u", span_width_reg(start_col, end_col)); + } + else + // Assign each column with a block entry 1/(n+1) of the line + // width, where n is the column count. + printfs("(u;\\n[%1]>?(\\n[.l]*%2/%3))", + span_width_reg(start_col, end_col), + as_string(end_col - start_col + 1), + as_string(ncols + 1)); + if (alphabetic) + prints("-2n"); + prints("\n"); + prints(".ss \\n[" SAVED_INTER_WORD_SPACE_SIZE "]" + " \\n[" SAVED_INTER_SENTENCE_SPACE_SIZE "]\n"); + prints(".cp \\n(" COMPATIBLE_REG "\n"); + set_modifier(mod); + set_location(); + prints(contents); + prints(".br\n.di\n.cp 0\n"); + if (!mod->zero_width) { + if (alphabetic) { + printfs(".nr %1 \\n[%1]>?(\\n[dl]+2n)\n", + span_width_reg(start_col, end_col)); + printfs(".nr %1 \\n[%1]>?\\n[dl]\n", + span_alphabetic_width_reg(start_col, end_col)); + } + else + printfs(".nr %1 \\n[%1]>?\\n[dl]\n", + span_width_reg(start_col, end_col)); + } + printfs(".nr %1 \\n[dn]\n", block_height_reg(start_row, start_col)); + printfs(".nr %1 \\n[dl]\n", block_width_reg(start_row, start_col)); + prints("." RESET_MACRO_NAME "\n" + ".in \\n[" SAVED_INDENT_REG "]u\n" + ".nf\n"); + // the block might have contained .lf commands + location_force_filename = 1; +} + +void block_entry::do_depth() +{ + printfs(".nr " BOTTOM_REG " \\n[" BOTTOM_REG "]>?(\\n[%1]+\\n[%2])\n", + row_start_reg(start_row), + block_height_reg(start_row, start_col)); +} + +left_block_entry::left_block_entry(const table *p, + const entry_modifier *m, char *s) +: block_entry(p, m, s) +{ +} + +void left_block_entry::print() +{ + printfs(".in +\\n[%1]u\n", column_start_reg(start_col)); + printfs(".%1\n", block_diversion_name(start_row, start_col)); + prints(".in\n"); +} + +right_block_entry::right_block_entry(const table *p, + const entry_modifier *m, char *s) +: block_entry(p, m, s) +{ +} + +void right_block_entry::print() +{ + printfs(".in +\\n[%1]u+\\n[%2]u-\\n[%3]u\n", + column_start_reg(start_col), + span_width_reg(start_col, end_col), + block_width_reg(start_row, start_col)); + printfs(".%1\n", block_diversion_name(start_row, start_col)); + prints(".in\n"); +} + +center_block_entry::center_block_entry(const table *p, + const entry_modifier *m, char *s) +: block_entry(p, m, s) +{ +} + +void center_block_entry::print() +{ + printfs(".in +\\n[%1]u+(\\n[%2]u-\\n[%3]u/2u)\n", + column_start_reg(start_col), + span_width_reg(start_col, end_col), + block_width_reg(start_row, start_col)); + printfs(".%1\n", block_diversion_name(start_row, start_col)); + prints(".in\n"); +} + +alphabetic_block_entry::alphabetic_block_entry(const table *p, + const entry_modifier *m, + char *s) +: block_entry(p, m, s) +{ +} + +int alphabetic_block_entry::divert(int ncols, const string *mw, int *sep, + int do_expand) +{ + do_divert(1, ncols, mw, sep, do_expand); + return 1; +} + +void alphabetic_block_entry::print() +{ + printfs(".in +\\n[%1]u+(\\n[%2]u-\\n[%3]u/2u)\n", + column_start_reg(start_col), + span_width_reg(start_col, end_col), + span_alphabetic_width_reg(start_col, end_col)); + printfs(".%1\n", block_diversion_name(start_row, start_col)); + prints(".in\n"); +} + +line_entry::line_entry(const table *p, const entry_modifier *m) +: simple_entry(p, m), double_vrule_on_right(0), double_vrule_on_left(0) +{ +} + +void line_entry::note_double_vrule_on_right(int is_corner) +{ + double_vrule_on_right = is_corner ? 1 : 2; +} + +void line_entry::note_double_vrule_on_left(int is_corner) +{ + double_vrule_on_left = is_corner ? 1 : 2; +} + +single_line_entry::single_line_entry(const table *p, const entry_modifier *m) +: line_entry(p, m) +{ +} + +int single_line_entry::line_type() +{ + return 1; +} + +void single_line_entry::simple_print(int dont_move) +{ + printfs("\\h'|\\n[%1]u", + column_divide_reg(start_col)); + if (double_vrule_on_left) { + prints(double_vrule_on_left == 1 ? "-" : "+"); + prints(HALF_DOUBLE_LINE_SEP); + } + prints("'"); + if (!dont_move) + prints("\\v'-" BAR_HEIGHT "'"); + printfs("\\s[\\n[" LINESIZE_REG "]]" "\\D'l |\\n[%1]u", + column_divide_reg(end_col+1)); + if (double_vrule_on_right) { + prints(double_vrule_on_left == 1 ? "+" : "-"); + prints(HALF_DOUBLE_LINE_SEP); + } + prints("0'\\s0"); + if (!dont_move) + prints("\\v'" BAR_HEIGHT "'"); +} + +single_line_entry *single_line_entry::to_single_line_entry() +{ + return this; +} + +double_line_entry::double_line_entry(const table *p, + const entry_modifier *m) +: line_entry(p, m) +{ +} + +int double_line_entry::line_type() +{ + return 2; +} + +void double_line_entry::simple_print(int dont_move) +{ + if (!dont_move) + prints("\\v'-" BAR_HEIGHT "'"); + printfs("\\h'|\\n[%1]u", + column_divide_reg(start_col)); + if (double_vrule_on_left) { + prints(double_vrule_on_left == 1 ? "-" : "+"); + prints(HALF_DOUBLE_LINE_SEP); + } + prints("'"); + printfs("\\v'-" HALF_DOUBLE_LINE_SEP "'" + "\\s[\\n[" LINESIZE_REG "]]" + "\\D'l |\\n[%1]u", + column_divide_reg(end_col+1)); + if (double_vrule_on_right) + prints("-" HALF_DOUBLE_LINE_SEP); + prints(" 0'"); + printfs("\\v'" DOUBLE_LINE_SEP "'" + "\\D'l |\\n[%1]u", + column_divide_reg(start_col)); + if (double_vrule_on_right) { + prints(double_vrule_on_left == 1 ? "+" : "-"); + prints(HALF_DOUBLE_LINE_SEP); + } + prints(" 0'"); + prints("\\s0" + "\\v'-" HALF_DOUBLE_LINE_SEP "'"); + if (!dont_move) + prints("\\v'" BAR_HEIGHT "'"); +} + +double_line_entry *double_line_entry::to_double_line_entry() +{ + return this; +} + +short_line_entry::short_line_entry(const table *p, const entry_modifier *m) +: simple_entry(p, m) +{ +} + +int short_line_entry::line_type() +{ + return 1; +} + +void short_line_entry::simple_print(int dont_move) +{ + if (mod->stagger) + prints("\\v'-.5v'"); + if (!dont_move) + prints("\\v'-" BAR_HEIGHT "'"); + printfs("\\h'|\\n[%1]u'", column_start_reg(start_col)); + printfs("\\s[\\n[" LINESIZE_REG "]]" + "\\D'l \\n[%1]u 0'" + "\\s0", + span_width_reg(start_col, end_col)); + if (!dont_move) + prints("\\v'" BAR_HEIGHT "'"); + if (mod->stagger) + prints("\\v'.5v'"); +} + +short_double_line_entry::short_double_line_entry(const table *p, + const entry_modifier *m) +: simple_entry(p, m) +{ +} + +int short_double_line_entry::line_type() +{ + return 2; +} + +void short_double_line_entry::simple_print(int dont_move) +{ + if (mod->stagger) + prints("\\v'-.5v'"); + if (!dont_move) + prints("\\v'-" BAR_HEIGHT "'"); + printfs("\\h'|\\n[%2]u'" + "\\v'-" HALF_DOUBLE_LINE_SEP "'" + "\\s[\\n[" LINESIZE_REG "]]" + "\\D'l \\n[%1]u 0'" + "\\v'" DOUBLE_LINE_SEP "'" + "\\D'l |\\n[%2]u 0'" + "\\s0" + "\\v'-" HALF_DOUBLE_LINE_SEP "'", + span_width_reg(start_col, end_col), + column_start_reg(start_col)); + if (!dont_move) + prints("\\v'" BAR_HEIGHT "'"); + if (mod->stagger) + prints("\\v'.5v'"); +} + +void set_modifier(const entry_modifier *m) +{ + if (!m->font.empty()) + printfs(".ft %1\n", m->font); + if (m->point_size.val != 0) { + prints(".ps "); + if (m->point_size.inc > 0) + prints('+'); + else if (m->point_size.inc < 0) + prints('-'); + printfs("%1\n", as_string(m->point_size.val)); + } + if (m->vertical_spacing.val != 0) { + prints(".vs "); + if (m->vertical_spacing.inc > 0) + prints('+'); + else if (m->vertical_spacing.inc < 0) + prints('-'); + printfs("%1\n", as_string(m->vertical_spacing.val)); + } + if (!m->macro.empty()) + printfs(".%1\n", m->macro); +} + +void set_inline_modifier(const entry_modifier *m) +{ + if (!m->font.empty()) + printfs("\\f[%1]", m->font); + if (m->point_size.val != 0) { + prints("\\s["); + if (m->point_size.inc > 0) + prints('+'); + else if (m->point_size.inc < 0) + prints('-'); + printfs("%1]", as_string(m->point_size.val)); + } + if (m->stagger) + prints("\\v'-.5v'"); +} + +void restore_inline_modifier(const entry_modifier *m) +{ + if (!m->font.empty()) + prints("\\f[\\n[" SAVED_FONT_REG "]]"); + if (m->point_size.val != 0) + prints("\\s[\\n[" SAVED_SIZE_REG "]]"); + if (m->stagger) + prints("\\v'.5v'"); +} + +struct stuff { + stuff *next; + int row; // occurs before row 'row' + char printed; // has it been printed? + + stuff(int); + virtual void print(table *) = 0; + virtual ~stuff(); + virtual int is_single_line() { return 0; }; + virtual int is_double_line() { return 0; }; +}; + +stuff::stuff(int r) : next(0), row(r), printed(0) +{ +} + +stuff::~stuff() +{ +} + +struct text_stuff : public stuff { + string contents; + const char *filename; + int lineno; + + text_stuff(const string &, int, const char *, int); + ~text_stuff(); + void print(table *); +}; + +text_stuff::text_stuff(const string &s, int r, const char *fn, int ln) +: stuff(r), contents(s), filename(fn), lineno(ln) +{ +} + +text_stuff::~text_stuff() +{ +} + +void text_stuff::print(table *) +{ + printed = 1; + prints(".cp \\n(" COMPATIBLE_REG "\n"); + set_troff_location(filename, lineno); + prints(contents); + prints(".cp 0\n"); + location_force_filename = 1; // it might have been a .lf command +} + +struct single_hline_stuff : public stuff { + single_hline_stuff(int); + void print(table *); + int is_single_line(); +}; + +single_hline_stuff::single_hline_stuff(int r) : stuff(r) +{ +} + +void single_hline_stuff::print(table *tbl) +{ + printed = 1; + tbl->print_single_hline(row); +} + +int single_hline_stuff::is_single_line() +{ + return 1; +} + +struct double_hline_stuff : stuff { + double_hline_stuff(int); + void print(table *); + int is_double_line(); +}; + +double_hline_stuff::double_hline_stuff(int r) : stuff(r) +{ +} + +void double_hline_stuff::print(table *tbl) +{ + printed = 1; + tbl->print_double_hline(row); +} + +int double_hline_stuff::is_double_line() +{ + return 1; +} + +struct vertical_rule { + vertical_rule *next; + int start_row; + int end_row; + int col; + char is_double; + string top_adjust; + string bot_adjust; + + vertical_rule(int, int, int, int, vertical_rule *); + ~vertical_rule(); + void contribute_to_bottom_macro(table *); + void print(); +}; + +vertical_rule::vertical_rule(int sr, int er, int c, int dbl, + vertical_rule *p) +: next(p), start_row(sr), end_row(er), col(c), is_double(dbl) +{ +} + +vertical_rule::~vertical_rule() +{ +} + +void vertical_rule::contribute_to_bottom_macro(table *tbl) +{ + printfs(".if \\n[" CURRENT_ROW_REG "]>=%1", + as_string(start_row)); + if (end_row != tbl->get_nrows() - 1) + printfs("&(\\n[" CURRENT_ROW_REG "]<%1)", + as_string(end_row)); + prints(" \\{\\\n"); + printfs(". if %1<=\\n[" LAST_PASSED_ROW_REG "] .nr %2 \\n[#T]\n", + as_string(start_row), + row_top_reg(start_row)); + const char *offset_table[3]; + if (is_double) { + offset_table[0] = "-" HALF_DOUBLE_LINE_SEP; + offset_table[1] = "+" HALF_DOUBLE_LINE_SEP; + offset_table[2] = 0; + } + else { + offset_table[0] = ""; + offset_table[1] = 0; + } + for (const char **offsetp = offset_table; *offsetp; offsetp++) { + prints(". sp -1\n" + "\\v'" BODY_DEPTH); + if (!bot_adjust.empty()) + printfs("+%1", bot_adjust); + prints("'"); + printfs("\\h'\\n[%1]u%3'\\s[\\n[" LINESIZE_REG "]]\\D'l 0 |\\n[%2]u-1v", + column_divide_reg(col), + row_top_reg(start_row), + *offsetp); + if (!bot_adjust.empty()) + printfs("-(%1)", bot_adjust); + // don't perform the top adjustment if the top is actually #T + if (!top_adjust.empty()) + printfs("+((%1)*(%2>\\n[" LAST_PASSED_ROW_REG "]))", + top_adjust, + as_string(start_row)); + prints("'\\s0\n"); + } + prints(".\\}\n"); +} + +void vertical_rule::print() +{ + printfs("\\*[" TRANSPARENT_STRING_NAME "]" + ".if %1<=\\*[" QUOTE_STRING_NAME "]\\n[" LAST_PASSED_ROW_REG "] " + ".nr %2 \\*[" QUOTE_STRING_NAME "]\\n[#T]\n", + as_string(start_row), + row_top_reg(start_row)); + const char *offset_table[3]; + if (is_double) { + offset_table[0] = "-" HALF_DOUBLE_LINE_SEP; + offset_table[1] = "+" HALF_DOUBLE_LINE_SEP; + offset_table[2] = 0; + } + else { + offset_table[0] = ""; + offset_table[1] = 0; + } + for (const char **offsetp = offset_table; *offsetp; offsetp++) { + prints("\\*[" TRANSPARENT_STRING_NAME "].sp -1\n" + "\\*[" TRANSPARENT_STRING_NAME "]\\v'" BODY_DEPTH); + if (!bot_adjust.empty()) + printfs("+%1", bot_adjust); + prints("'"); + printfs("\\h'\\n[%1]u%3'" + "\\s[\\n[" LINESIZE_REG "]]" + "\\D'l 0 |\\*[" QUOTE_STRING_NAME "]\\n[%2]u-1v", + column_divide_reg(col), + row_top_reg(start_row), + *offsetp); + if (!bot_adjust.empty()) + printfs("-(%1)", bot_adjust); + // don't perform the top adjustment if the top is actually #T + if (!top_adjust.empty()) + printfs("+((%1)*(%2>\\*[" QUOTE_STRING_NAME "]\\n[" + LAST_PASSED_ROW_REG "]))", + top_adjust, + as_string(start_row)); + prints("'" + "\\s0\n"); + } +} + +table::table(int nc, unsigned f, int ls, char dpc) +: nrows(0), ncolumns(nc), linesize(ls), decimal_point_char(dpc), + vrule_list(0), stuff_list(0), span_list(0), + entry_list(0), entry_list_tailp(&entry_list), entry(0), + vline(0), row_is_all_lines(0), left_separation(0), + right_separation(0), total_separation(0), allocated_rows(0), flags(f) +{ + minimum_width = new string[ncolumns]; + column_separation = ncolumns > 1 ? new int[ncolumns - 1] : 0; + equal = new char[ncolumns]; + expand = new char[ncolumns]; + int i; + for (i = 0; i < ncolumns; i++) { + equal[i] = 0; + expand[i] = 0; + } + for (i = 0; i < ncolumns - 1; i++) + column_separation[i] = DEFAULT_COLUMN_SEPARATION; + delim[0] = delim[1] = '\0'; +} + +table::~table() +{ + for (int i = 0; i < nrows; i++) { + delete[] entry[i]; + delete[] vline[i]; + } + delete[] entry; + delete[] vline; + while (entry_list) { + table_entry *tem = entry_list; + entry_list = entry_list->next; + delete tem; + } + delete[] minimum_width; + delete[] column_separation; + delete[] equal; + delete[] expand; + while (stuff_list) { + stuff *tem = stuff_list; + stuff_list = stuff_list->next; + delete tem; + } + while (vrule_list) { + vertical_rule *tem = vrule_list; + vrule_list = vrule_list->next; + delete tem; + } + delete[] row_is_all_lines; + while (span_list) { + horizontal_span *tem = span_list; + span_list = span_list->next; + delete tem; + } +} + +void table::set_delim(char c1, char c2) +{ + delim[0] = c1; + delim[1] = c2; +} + +void table::set_minimum_width(int c, const string &w) +{ + assert(c >= 0 && c < ncolumns); + minimum_width[c] = w; +} + +void table::set_column_separation(int c, int n) +{ + assert(c >= 0 && c < ncolumns - 1); + column_separation[c] = n; +} + +void table::set_equal_column(int c) +{ + assert(c >= 0 && c < ncolumns); + equal[c] = 1; +} + +void table::set_expand_column(int c) +{ + assert(c >= 0 && c < ncolumns); + expand[c] = 1; +} + +void table::add_stuff(stuff *p) +{ + stuff **pp; + for (pp = &stuff_list; *pp; pp = &(*pp)->next) + ; + *pp = p; +} + +void table::add_text_line(int r, const string &s, const char *filename, + int lineno) +{ + add_stuff(new text_stuff(s, r, filename, lineno)); +} + +void table::add_single_hline(int r) +{ + add_stuff(new single_hline_stuff(r)); +} + +void table::add_double_hline(int r) +{ + add_stuff(new double_hline_stuff(r)); +} + +void table::allocate(int r) +{ + if (r >= nrows) { + typedef table_entry **PPtable_entry; // work around g++ 1.36.1 bug + if (r >= allocated_rows) { + if (allocated_rows == 0) { + allocated_rows = 16; + if (allocated_rows <= r) + allocated_rows = r + 1; + entry = new PPtable_entry[allocated_rows]; + vline = new char*[allocated_rows]; + } + else { + table_entry ***old_entry = entry; + int old_allocated_rows = allocated_rows; + allocated_rows *= 2; + if (allocated_rows <= r) + allocated_rows = r + 1; + entry = new PPtable_entry[allocated_rows]; + memcpy(entry, old_entry, sizeof(table_entry**)*old_allocated_rows); + delete[] old_entry; + char **old_vline = vline; + vline = new char*[allocated_rows]; + memcpy(vline, old_vline, sizeof(char*)*old_allocated_rows); + delete[] old_vline; + } + } + assert(allocated_rows > r); + while (nrows <= r) { + entry[nrows] = new table_entry*[ncolumns]; + int i; + for (i = 0; i < ncolumns; i++) + entry[nrows][i] = 0; + vline[nrows] = new char[ncolumns+1]; + for (i = 0; i < ncolumns+1; i++) + vline[nrows][i] = 0; + nrows++; + } + } +} + +void table::do_hspan(int r, int c) +{ + assert(r >= 0 && c >= 0 && r < nrows && c < ncolumns); + if (c == 0) { + error("first column cannot be horizontally spanned"); + return; + } + table_entry *e = entry[r][c]; + if (e) { + assert(e->start_row <= r && r <= e->end_row + && e->start_col <= c && c <= e->end_col + && e->end_row - e->start_row > 0 + && e->end_col - e->start_col > 0); + return; + } + e = entry[r][c-1]; + // e can be 0 if we had an empty entry or an error + if (e == 0) + return; + if (e->start_row != r) { + /* + l l + ^ s */ + error("impossible horizontal span at row %1, column %2", r + 1, + c + 1); + } + else { + e->end_col = c; + entry[r][c] = e; + } +} + +void table::do_vspan(int r, int c) +{ + assert(r >= 0 && c >= 0 && r < nrows && c < ncolumns); + if (0 == r) { + error("first row cannot be vertically spanned"); + return; + } + table_entry *e = entry[r][c]; + if (e) { + assert(e->start_row <= r); + assert(r <= e->end_row); + assert(e->start_col <= c); + assert(c <= e->end_col); + assert((e->end_row - e->start_row) > 0); + assert((e->end_col - e->start_col) > 0); + return; + } + e = entry[r-1][c]; + // e can be a null pointer if we had an empty entry or an error + if (0 == e) + return; + if (e->start_col != c) { + /* l s + l ^ */ + error("impossible vertical span at row %1, column %2", r + 1, + c + 1); + } + else { + for (int i = c; i <= e->end_col; i++) { + assert(entry[r][i] == 0); + entry[r][i] = e; + } + e->end_row = r; + } +} + +int find_decimal_point(const char *s, char decimal_point_char, + const char *delim) +{ + if (s == 0 || *s == '\0') + return -1; + const char *p; + int in_delim = 0; // is p within eqn delimiters? + // tbl recognises \& even within eqn delimiters; I don't + for (p = s; *p; p++) + if (in_delim) { + if (*p == delim[1]) + in_delim = 0; + } + else if (*p == delim[0]) + in_delim = 1; + else if (p[0] == '\\' && p[1] == '&') + return p - s; + int possible_pos = -1; + in_delim = 0; + for (p = s; *p; p++) + if (in_delim) { + if (*p == delim[1]) + in_delim = 0; + } + else if (*p == delim[0]) + in_delim = 1; + else if (p[0] == decimal_point_char && csdigit(p[1])) + possible_pos = p - s; + if (possible_pos >= 0) + return possible_pos; + in_delim = 0; + for (p = s; *p; p++) + if (in_delim) { + if (*p == delim[1]) + in_delim = 0; + } + else if (*p == delim[0]) + in_delim = 1; + else if (csdigit(*p)) + possible_pos = p + 1 - s; + return possible_pos; +} + +void table::add_entry(int r, int c, const string &str, + const entry_format *f, const char *fn, int ln) +{ + allocate(r); + table_entry *e = 0; + char *s = str.extract(); + if (str.search('\n') >= 0) { + bool was_changed = false; + for (int i = 0; s[i] != '\0'; i++) + if ((i > 0) && (s[(i - 1)] == '\\') && (s[i] == 'R')) { + s[i] = '&'; + was_changed = true; + } + if (was_changed) + error_with_file_and_line(fn, ln, "repeating a glyph with '\\R'" + " is not allowed in a text block"); + } + if (str == "\\_") { + e = new short_line_entry(this, f); + } + else if (str == "\\=") { + e = new short_double_line_entry(this, f); + } + else if (str == "_") { + single_line_entry *lefte; + if (c > 0 && entry[r][c-1] != 0 && + (lefte = entry[r][c-1]->to_single_line_entry()) != 0 + && lefte->start_row == r + && lefte->mod->stagger == f->stagger) { + lefte->end_col = c; + entry[r][c] = lefte; + } + else + e = new single_line_entry(this, f); + } + else if (str == "=") { + double_line_entry *lefte; + if (c > 0 && entry[r][c-1] != 0 && + (lefte = entry[r][c-1]->to_double_line_entry()) != 0 + && lefte->start_row == r + && lefte->mod->stagger == f->stagger) { + lefte->end_col = c; + entry[r][c] = lefte; + } + else + e = new double_line_entry(this, f); + } + else if (str == "\\^") { + if (r == 0) { + error("first row cannot contain a vertical span entry '\\^'"); + e = new empty_entry(this, f); + } + else + do_vspan(r, c); + } + else { + int is_block = str.search('\n') >= 0; + switch (f->type) { + case FORMAT_SPAN: + assert(str.empty()); + do_hspan(r, c); + break; + case FORMAT_LEFT: + if (!str.empty()) { + if (is_block) + e = new left_block_entry(this, f, s); + else + e = new left_text_entry(this, f, s); + } + else + e = new empty_entry(this, f); + break; + case FORMAT_CENTER: + if (!str.empty()) { + if (is_block) + e = new center_block_entry(this, f, s); + else + e = new center_text_entry(this, f, s); + } + else + e = new empty_entry(this, f); + break; + case FORMAT_RIGHT: + if (!str.empty()) { + if (is_block) + e = new right_block_entry(this, f, s); + else + e = new right_text_entry(this, f, s); + } + else + e = new empty_entry(this, f); + break; + case FORMAT_NUMERIC: + if (!str.empty()) { + if (is_block) { + error_with_file_and_line(fn, ln, "can't have numeric text block"); + e = new left_block_entry(this, f, s); + } + else { + int pos = find_decimal_point(s, decimal_point_char, delim); + if (pos < 0) + e = new center_text_entry(this, f, s); + else + e = new numeric_text_entry(this, f, s, pos); + } + } + else + e = new empty_entry(this, f); + break; + case FORMAT_ALPHABETIC: + if (!str.empty()) { + if (is_block) + e = new alphabetic_block_entry(this, f, s); + else + e = new alphabetic_text_entry(this, f, s); + } + else + e = new empty_entry(this, f); + break; + case FORMAT_VSPAN: + do_vspan(r, c); + break; + case FORMAT_HLINE: + if ((str.length() != 0) && (str != "\\&")) + error_with_file_and_line(fn, ln, + "ignoring non-empty data entry using" + " '_' column classifier"); + e = new single_line_entry(this, f); + break; + case FORMAT_DOUBLE_HLINE: + if ((str.length() != 0) && (str != "\\&")) + error_with_file_and_line(fn, ln, + "ignoring non-empty data entry using" + " '=' column classifier"); + e = new double_line_entry(this, f); + break; + default: + assert(0 == "table column format not in FORMAT_{SPAN,LEFT,CENTER," + "RIGHT,NUMERIC,ALPHABETIC,VSPAN,HLINE,DOUBLE_HLINE}"); + } + } + if (e) { + table_entry *preve = entry[r][c]; + if (preve) { + /* c s + ^ l */ + error_with_file_and_line(fn, ln, "row %1, column %2 already" + " spanned", + r + 1, c + 1); + delete e; + } + else { + e->input_lineno = ln; + e->input_filename = fn; + e->start_row = e->end_row = r; + e->start_col = e->end_col = c; + *entry_list_tailp = e; + entry_list_tailp = &e->next; + entry[r][c] = e; + } + } +} + +// add vertical lines for row r + +void table::add_vlines(int r, const char *v) +{ + allocate(r); + bool lwarned = false; + bool twarned = false; + for (int i = 0; i < ncolumns+1; i++) { + assert(v[i] < 3); + if (v[i] && (flags & (BOX | ALLBOX | DOUBLEBOX)) && (i == 0) + && (!lwarned)) { + error("ignoring vertical line at leading edge of boxed table"); + lwarned = true; + } + else if (v[i] && (flags & (BOX | ALLBOX | DOUBLEBOX)) + && (i == ncolumns) && (!twarned)) { + error("ignoring vertical line at trailing edge of boxed table"); + twarned = true; + } + else + vline[r][i] = v[i]; + } +} + +void table::check() +{ + table_entry *p = entry_list; + int i, j; + while (p) { + for (i = p->start_row; i <= p->end_row; i++) + for (j = p->start_col; j <= p->end_col; j++) + assert(entry[i][j] == p); + p = p->next; + } +} + +void table::print() +{ + location_force_filename = 1; + check(); + init_output(); + determine_row_type(); + compute_widths(); + if (!(flags & CENTER)) + prints(".if \\n[" SAVED_CENTER_REG "] \\{\\\n"); + prints(". in +(u;\\n[.l]-\\n[.i]-\\n[TW]/2>?-\\n[.i])\n" + ". nr " SAVED_INDENT_REG " \\n[.i]\n"); + if (!(flags & CENTER)) + prints(".\\}\n"); + build_vrule_list(); + define_bottom_macro(); + do_top(); + for (int i = 0; i < nrows; i++) + do_row(i); + do_bottom(); +} + +void table::determine_row_type() +{ + row_is_all_lines = new char[nrows]; + for (int i = 0; i < nrows; i++) { + bool had_single = false; + bool had_double = false; + bool had_non_line = false; + for (int c = 0; c < ncolumns; c++) { + table_entry *e = entry[i][c]; + if (e != 0) { + if (e->start_row == e->end_row) { + int t = e->line_type(); + switch (t) { + case -1: + had_non_line = true; + break; + case 0: + // empty + break; + case 1: + had_single = true; + break; + case 2: + had_double = true; + break; + default: + assert(0 == "table entry line type not in {-1, 0, 1, 2}"); + } + if (had_non_line) + break; + } + c = e->end_col; + } + } + if (had_non_line) + row_is_all_lines[i] = 0; + else if (had_double) + row_is_all_lines[i] = 2; + else if (had_single) + row_is_all_lines[i] = 1; + else + row_is_all_lines[i] = 0; + } +} + +int table::count_expand_columns() +{ + int count = 0; + for (int i = 0; i < ncolumns; i++) + if (expand[i]) + count++; + return count; +} + +void table::init_output() +{ + prints(".\\\" initialize output\n"); + prints(".nr " COMPATIBLE_REG " \\n(.C\n" + ".cp 0\n"); + if (linesize > 0) + printfs(".nr " LINESIZE_REG " %1\n", as_string(linesize)); + else + prints(".nr " LINESIZE_REG " \\n[.s]\n"); + if (!(flags & CENTER)) + prints(".nr " SAVED_CENTER_REG " \\n[.ce]\n"); + if (compatible_flag) + prints(".ds " LEADER_REG " \\a\n"); + if (!(flags & NOKEEP)) + prints(".if !r " USE_KEEPS_REG " .nr " USE_KEEPS_REG " 1\n"); + prints(".de " RESET_MACRO_NAME "\n" + ". ft \\n[.f]\n" + ". ps \\n[.s]\n" + ". vs \\n[.v]u\n" + ". in \\n[.i]u\n" + ". ll \\n[.l]u\n" + ". ls \\n[.L]\n" + ". hy \\\\n[" SAVED_HYPHENATION_MODE_REG "]\n" + ". hla \\\\*[" SAVED_HYPHENATION_LANG_NAME "]\n" + ". hlm \\\\n[" SAVED_HYPHENATION_MAX_LINES_REG "]\n" + ". hym \\\\n[" SAVED_HYPHENATION_MARGIN_REG "]\n" + ". hys \\\\n[" SAVED_HYPHENATION_SPACE_REG "]\n" + ". ad \\n[.j]\n" + ". ie \\n[.u] .fi\n" + ". el .nf\n" + ". ce \\n[.ce]\n" + ". ta \\\\*[" SAVED_TABS_NAME "]\n" + ". ss \\\\n[" SAVED_INTER_WORD_SPACE_SIZE "]" + " \\\\n[" SAVED_INTER_SENTENCE_SPACE_SIZE "]\n" + "..\n" + ".nr " SAVED_INDENT_REG " \\n[.i]\n" + ".nr " SAVED_FONT_REG " \\n[.f]\n" + ".nr " SAVED_SIZE_REG " \\n[.s]\n" + ".nr " SAVED_FILL_REG " \\n[.u]\n" + ".ds " SAVED_TABS_NAME " \\n[.tabs]\n" + ".nr " SAVED_INTER_WORD_SPACE_SIZE " \\n[.ss]\n" + ".nr " SAVED_INTER_SENTENCE_SPACE_SIZE " \\n[.sss]\n" + ".nr " SAVED_HYPHENATION_MODE_REG " \\n[.hy]\n" + ".ds " SAVED_HYPHENATION_LANG_NAME " \\n[.hla]\n" + ".nr " SAVED_HYPHENATION_MAX_LINES_REG " (\\n[.hlm])\n" + ".nr " SAVED_HYPHENATION_MARGIN_REG " \\n[.hym]\n" + ".nr " SAVED_HYPHENATION_SPACE_REG " \\n[.hys]\n" + ".nr T. 0\n" + ".nr " CURRENT_ROW_REG " 0-1\n" + ".nr " LAST_PASSED_ROW_REG " 0-1\n" + ".nr " SECTION_DIVERSION_FLAG_REG " 0\n" + ".ds " TRANSPARENT_STRING_NAME "\n" + ".ds " QUOTE_STRING_NAME "\n" + ".nr " NEED_BOTTOM_RULE_REG " 1\n" + ".nr " SUPPRESS_BOTTOM_REG " 0\n" + ".eo\n" + ".de " REPEATED_MARK_MACRO "\n" + ". mk \\$1\n" + ". if !'\\n(.z'' \\!." REPEATED_MARK_MACRO " \"\\$1\"\n" + "..\n" + ".de " REPEATED_VPT_MACRO "\n" + ". vpt \\$1\n" + ". if !'\\n(.z'' \\!." REPEATED_VPT_MACRO " \"\\$1\"\n" + "..\n"); + if (!(flags & NOKEEP)) { + prints(".de " KEEP_MACRO_NAME "\n" + ". if '\\n[.z]'' \\{\\\n" + ". ds " QUOTE_STRING_NAME " \\\\\n" + ". ds " TRANSPARENT_STRING_NAME " \\!\n" + ". di " SECTION_DIVERSION_NAME "\n" + ". nr " SECTION_DIVERSION_FLAG_REG " 1\n" + ". in 0\n" + ". \\}\n" + "..\n" + // Protect '#' in macro name from being interpreted by eqn. + ".ig\n" + ".EQ\n" + "delim off\n" + ".EN\n" + "..\n" + ".de " RELEASE_MACRO_NAME "\n" + ". if \\n[" SECTION_DIVERSION_FLAG_REG "] \\{\\\n" + ". di\n" + ". in \\n[" SAVED_INDENT_REG "]u\n" + ". nr " SAVED_DN_REG " \\n[dn]\n" + ". ds " QUOTE_STRING_NAME "\n" + ". ds " TRANSPARENT_STRING_NAME "\n" + ". nr " SECTION_DIVERSION_FLAG_REG " 0\n" + ". if \\n[.t]<=\\n[dn] \\{\\\n" + ". nr T. 1\n" + ". T#\n" + ". nr " SUPPRESS_BOTTOM_REG " 1\n" + ". sp \\n[.t]u\n" + ". nr " SUPPRESS_BOTTOM_REG " 0\n" + ". mk #T\n" + ". \\}\n"); + if (!(flags & NOWARN)) { + prints(". if \\n[.t]<=\\n[" SAVED_DN_REG "] \\{\\\n"); + // eqn(1) delimiters have already been switched off. + entry_list->set_location(); + // Since we turn off traps, troff won't go into an infinite loop + // when we output the table row; it will just flow off the bottom + // of the page. + prints(". tmc \\n[.F]:\\n[.c]: warning:\n" + ". tm1 \" table row does not fit on page \\n%\n"); + prints(". \\}\n"); + } + prints(". nf\n" + ". ls 1\n" + ". " SECTION_DIVERSION_NAME "\n" + ". ls\n" + ". rm " SECTION_DIVERSION_NAME "\n" + ". \\}\n" + "..\n" + ".ig\n" + ".EQ\n" + "delim on\n" + ".EN\n" + "..\n" + ".nr " TABLE_DIVERSION_FLAG_REG " 0\n" + ".de " TABLE_KEEP_MACRO_NAME "\n" + ". if '\\n[.z]'' \\{\\\n" + ". di " TABLE_DIVERSION_NAME "\n" + ". nr " TABLE_DIVERSION_FLAG_REG " 1\n" + ". \\}\n" + "..\n" + ".de " TABLE_RELEASE_MACRO_NAME "\n" + ". if \\n[" TABLE_DIVERSION_FLAG_REG "] \\{\\\n" + ". br\n" + ". di\n" + ". nr " SAVED_DN_REG " \\n[dn]\n" + ". ne \\n[dn]u+\\n[.V]u\n" + ". ie \\n[.t]<=\\n[" SAVED_DN_REG "] \\{\\\n"); + // Protect characters in diagnostic message (especially :, [, ]) + // from being interpreted by eqn. + prints(". ds " NOP_NAME " \\\" empty\n"); + prints(". ig " NOP_NAME "\n" + ".EQ\n" + "delim off\n" + ".EN\n" + ". " NOP_NAME "\n"); + entry_list->set_location(); + prints(". nr " PREVIOUS_PAGE_REG " (\\n% - 1)\n" + ". tmc \\n[.F]:\\n[.c]: error:\n" + ". tmc \" boxed table does not fit on page" + " \\n[" PREVIOUS_PAGE_REG "];\n" + ". tm1 \" use .TS H/.TH with a supporting macro package" + "\n" + ". rr " PREVIOUS_PAGE_REG "\n"); + prints(". ig " NOP_NAME "\n" + ".EQ\n" + "delim on\n" + ".EN\n" + ". " NOP_NAME "\n"); + prints(". \\}\n" + ". el \\{\\\n" + ". in 0\n" + ". ls 1\n" + ". nf\n" + ". " TABLE_DIVERSION_NAME "\n" + ". \\}\n" + ". rm " TABLE_DIVERSION_NAME "\n" + ". \\}\n" + "..\n"); + } + prints(".ec\n" + ".ce 0\n"); + prints(".nr " SAVED_NUMBERING_LINENO " \\n[ln]\n" + ".nr ln 0\n" + ".nr " SAVED_NUMBERING_SUPPRESSION_COUNT " \\n[.nn]\n" + ".nn 2147483647\n"); // 2^31-1; inelegant but effective + prints(".nf\n"); +} + +string block_width_reg(int r, int c) +{ + static char name[sizeof(BLOCK_WIDTH_PREFIX)+INT_DIGITS+1+INT_DIGITS]; + sprintf(name, BLOCK_WIDTH_PREFIX "%d,%d", r, c); + return string(name); +} + +string block_diversion_name(int r, int c) +{ + static char name[sizeof(BLOCK_DIVERSION_PREFIX)+INT_DIGITS+1+INT_DIGITS]; + sprintf(name, BLOCK_DIVERSION_PREFIX "%d,%d", r, c); + return string(name); +} + +string block_height_reg(int r, int c) +{ + static char name[sizeof(BLOCK_HEIGHT_PREFIX)+INT_DIGITS+1+INT_DIGITS]; + sprintf(name, BLOCK_HEIGHT_PREFIX "%d,%d", r, c); + return string(name); +} + +string span_width_reg(int start_col, int end_col) +{ + static char name[sizeof(SPAN_WIDTH_PREFIX)+INT_DIGITS+1+INT_DIGITS]; + sprintf(name, SPAN_WIDTH_PREFIX "%d", start_col); + if (end_col != start_col) + sprintf(strchr(name, '\0'), ",%d", end_col); + return string(name); +} + +string span_left_numeric_width_reg(int start_col, int end_col) +{ + static char name[sizeof(SPAN_LEFT_NUMERIC_WIDTH_PREFIX)+INT_DIGITS+1+INT_DIGITS]; + sprintf(name, SPAN_LEFT_NUMERIC_WIDTH_PREFIX "%d", start_col); + if (end_col != start_col) + sprintf(strchr(name, '\0'), ",%d", end_col); + return string(name); +} + +string span_right_numeric_width_reg(int start_col, int end_col) +{ + static char name[sizeof(SPAN_RIGHT_NUMERIC_WIDTH_PREFIX)+INT_DIGITS+1+INT_DIGITS]; + sprintf(name, SPAN_RIGHT_NUMERIC_WIDTH_PREFIX "%d", start_col); + if (end_col != start_col) + sprintf(strchr(name, '\0'), ",%d", end_col); + return string(name); +} + +string span_alphabetic_width_reg(int start_col, int end_col) +{ + static char name[sizeof(SPAN_ALPHABETIC_WIDTH_PREFIX)+INT_DIGITS+1+INT_DIGITS]; + sprintf(name, SPAN_ALPHABETIC_WIDTH_PREFIX "%d", start_col); + if (end_col != start_col) + sprintf(strchr(name, '\0'), ",%d", end_col); + return string(name); +} + +string column_separation_reg(int col) +{ + static char name[sizeof(COLUMN_SEPARATION_PREFIX)+INT_DIGITS]; + sprintf(name, COLUMN_SEPARATION_PREFIX "%d", col); + return string(name); +} + +string row_start_reg(int row) +{ + static char name[sizeof(ROW_START_PREFIX)+INT_DIGITS]; + sprintf(name, ROW_START_PREFIX "%d", row); + return string(name); +} + +string column_start_reg(int col) +{ + static char name[sizeof(COLUMN_START_PREFIX)+INT_DIGITS]; + sprintf(name, COLUMN_START_PREFIX "%d", col); + return string(name); +} + +string column_end_reg(int col) +{ + static char name[sizeof(COLUMN_END_PREFIX)+INT_DIGITS]; + sprintf(name, COLUMN_END_PREFIX "%d", col); + return string(name); +} + +string column_divide_reg(int col) +{ + static char name[sizeof(COLUMN_DIVIDE_PREFIX)+INT_DIGITS]; + sprintf(name, COLUMN_DIVIDE_PREFIX "%d", col); + return string(name); +} + +string row_top_reg(int row) +{ + static char name[sizeof(ROW_TOP_PREFIX)+INT_DIGITS]; + sprintf(name, ROW_TOP_PREFIX "%d", row); + return string(name); +} + +void init_span_reg(int start_col, int end_col) +{ + printfs(".nr %1 \\n(.H\n.nr %2 0\n.nr %3 0\n.nr %4 0\n", + span_width_reg(start_col, end_col), + span_alphabetic_width_reg(start_col, end_col), + span_left_numeric_width_reg(start_col, end_col), + span_right_numeric_width_reg(start_col, end_col)); +} + +void compute_span_width(int start_col, int end_col) +{ + printfs(".nr %1 \\n[%1]>?(\\n[%2]+\\n[%3])\n" + ".if \\n[%4] .nr %1 \\n[%1]>?(\\n[%4]+2n)\n", + span_width_reg(start_col, end_col), + span_left_numeric_width_reg(start_col, end_col), + span_right_numeric_width_reg(start_col, end_col), + span_alphabetic_width_reg(start_col, end_col)); +} + +// Increase the widths of columns so that the width of any spanning +// entry is not greater than the sum of the widths of the columns that +// it spans. Ensure that the widths of columns remain equal. + +void table::divide_span(int start_col, int end_col) +{ + assert(end_col > start_col); + printfs(".nr " NEEDED_REG " \\n[%1]-(\\n[%2]", + span_width_reg(start_col, end_col), + span_width_reg(start_col, start_col)); + int i; + for (i = start_col + 1; i <= end_col; i++) { + // The column separation may shrink with the expand option. + if (!(flags & EXPAND)) + printfs("+%1n", as_string(column_separation[i - 1])); + printfs("+\\n[%1]", span_width_reg(i, i)); + } + prints(")\n"); + printfs(".nr " NEEDED_REG " \\n[" NEEDED_REG "]/%1\n", + as_string(end_col - start_col + 1)); + prints(".if \\n[" NEEDED_REG "] \\{\\\n"); + for (i = start_col; i <= end_col; i++) + printfs(". nr %1 +\\n[" NEEDED_REG "]\n", + span_width_reg(i, i)); + int equal_flag = 0; + for (i = start_col; i <= end_col && !equal_flag; i++) + if (equal[i] || expand[i]) + equal_flag = 1; + if (equal_flag) { + for (i = 0; i < ncolumns; i++) + if (i < start_col || i > end_col) + printfs(". nr %1 +\\n[" NEEDED_REG "]\n", + span_width_reg(i, i)); + } + prints(".\\}\n"); +} + +void table::sum_columns(int start_col, int end_col, int do_expand) +{ + assert(end_col > start_col); + int i; + for (i = start_col; i <= end_col; i++) + if (expand[i]) + break; + if (i > end_col) { + if (do_expand) + return; + } + else { + if (!do_expand) + return; + } + printfs(".nr %1 \\n[%2]", + span_width_reg(start_col, end_col), + span_width_reg(start_col, start_col)); + for (i = start_col + 1; i <= end_col; i++) + printfs("+(%1*\\n[" SEPARATION_FACTOR_REG "])+\\n[%2]", + as_string(column_separation[i - 1]), + span_width_reg(i, i)); + prints('\n'); +} + +horizontal_span::horizontal_span(int sc, int ec, horizontal_span *p) +: next(p), start_col(sc), end_col(ec) +{ +} + +void table::build_span_list() +{ + span_list = 0; + table_entry *p = entry_list; + while (p) { + if (p->end_col != p->start_col) { + horizontal_span *q; + for (q = span_list; q; q = q->next) + if (q->start_col == p->start_col + && q->end_col == p->end_col) + break; + if (!q) + span_list = new horizontal_span(p->start_col, p->end_col, span_list); + } + p = p->next; + } + // Now sort span_list primarily by order of end_row, and secondarily + // by reverse order of start_row. This ensures that if we divide + // spans using the order in span_list, we will get reasonable results. + horizontal_span *unsorted = span_list; + span_list = 0; + while (unsorted) { + horizontal_span **pp; + for (pp = &span_list; *pp; pp = &(*pp)->next) + if (unsorted->end_col < (*pp)->end_col + || (unsorted->end_col == (*pp)->end_col + && (unsorted->start_col > (*pp)->start_col))) + break; + horizontal_span *tem = unsorted->next; + unsorted->next = *pp; + *pp = unsorted; + unsorted = tem; + } +} + +void table::compute_overall_width() +{ + prints(".\\\" compute overall width\n"); + if (!(flags & GAP_EXPAND)) { + if (left_separation) + printfs(".if n .ll -%1n\n", as_string(left_separation)); + if (right_separation) + printfs(".if n .ll -%1n\n", as_string(right_separation)); + } + // Compute the amount of horizontal space available for expansion, + // measuring every column _including_ those eligible for expansion. + // This is the minimum required to set the table without compression. + prints(".nr " EXPAND_REG " 0\n"); + prints(".nr " AVAILABLE_WIDTH_REG " \\n[.l]-\\n[.i]"); + for (int i = 0; i < ncolumns; i++) + printfs("-\\n[%1]", span_width_reg(i, i)); + if (total_separation) + printfs("-%1n", as_string(total_separation)); + prints("\n"); + // If the "expand" region option was given, a different warning will + // be issued later (if "nowarn" was not also specified). + if ((!(flags & NOWARN)) && (!(flags & EXPAND))) { + prints(".if \\n[" AVAILABLE_WIDTH_REG "]<0 \\{\\\n"); + // Protect characters in diagnostic message (especially :, [, ]) + // from being interpreted by eqn. + prints(". ig\n" + ".EQ\n" + "delim off\n" + ".EN\n" + ". .\n"); + entry_list->set_location(); + prints(". tmc \\n[.F]:\\n[.c]: warning:\n" + ". tm1 \" table wider than line length minus indentation" + "\n"); + prints(". ig\n" + ".EQ\n" + "delim on\n" + ".EN\n" + ". .\n"); + prints(". nr " AVAILABLE_WIDTH_REG " 0\n"); + prints(".\\}\n"); + } + // Now do a similar computation, this time omitting columns that + // _aren't_ undergoing expansion. The difference is the amount of + // space we have to distribute among the expanded columns. + bool do_expansion = false; + for (int i = 0; i < ncolumns; i++) + if (expand[i]) { + do_expansion = true; + break; + } + if (do_expansion) { + prints(".if \\n[" AVAILABLE_WIDTH_REG "] \\\n"); + prints(". nr " EXPAND_REG " \\n[.l]-\\n[.i]"); + for (int i = 0; i < ncolumns; i++) + if (!expand[i]) + printfs("-\\n[%1]", span_width_reg(i, i)); + if (total_separation) + printfs("-%1n", as_string(total_separation)); + prints("\n"); + int colcount = count_expand_columns(); + if (colcount > 1) + printfs(".nr " EXPAND_REG " \\n[" EXPAND_REG "]/%1\n", + as_string(colcount)); + for (int i = 0; i < ncolumns; i++) + if (expand[i]) + printfs(".nr %1 \\n[%1]>?\\n[" EXPAND_REG "]\n", + span_width_reg(i, i)); + } +} + +void table::compute_total_separation() +{ + if (flags & (ALLBOX | BOX | DOUBLEBOX)) + left_separation = right_separation = 1; + else { + for (int r = 0; r < nrows; r++) { + if (vline[r][0] > 0) + left_separation = 1; + if (vline[r][ncolumns] > 0) + right_separation = 1; + } + } + total_separation = left_separation + right_separation; + for (int c = 0; c < ncolumns - 1; c++) + total_separation += column_separation[c]; +} + +void table::compute_separation_factor() +{ + prints(".\\\" compute column separation factor\n"); + // Don't let the separation factor be negative. + prints(".nr " SEPARATION_FACTOR_REG " \\n[.l]-\\n[.i]"); + for (int i = 0; i < ncolumns; i++) + printfs("-\\n[%1]", span_width_reg(i, i)); + printfs("/%1\n", as_string(total_separation)); + // Store the remainder for use in compute_column_positions(). + if (flags & GAP_EXPAND) { + prints(".if n \\\n"); + prints(". nr " LEFTOVER_FACTOR_REG " \\n[.l]-\\n[.i]"); + for (int i = 0; i < ncolumns; i++) + printfs("-\\n[%1]", span_width_reg(i, i)); + printfs("%%%1\n", as_string(total_separation)); + } + prints(".ie \\n[" SEPARATION_FACTOR_REG "]<=0 \\{\\\n"); + if (!(flags & NOWARN)) { + // Protect characters in diagnostic message (especially :, [, ]) + // from being interpreted by eqn. + prints(".ig\n" + ".EQ\n" + "delim off\n" + ".EN\n" + "..\n"); + entry_list->set_location(); + prints(".tmc \\n[.F]:\\n[.c]: warning:\n" + ".tm1 \" table column separation reduced to zero\n" + ".nr " SEPARATION_FACTOR_REG " 0\n"); + } + prints(".\\}\n" + ".el .if \\n[" SEPARATION_FACTOR_REG "]<1n \\{\\\n"); + if (!(flags & NOWARN)) { + entry_list->set_location(); + prints(".tmc \\n[.F]:\\n[.c]: warning:\n" + ".tm1 \" table column separation reduced to fit line" + " length\n"); + prints(".ig\n" + ".EQ\n" + "delim on\n" + ".EN\n" + "..\n"); + } + prints(".\\}\n"); +} + +void table::compute_column_positions() +{ + prints(".\\\" compute column positions\n"); + printfs(".nr %1 0\n", column_divide_reg(0)); + printfs(".nr %1 %2n\n", column_start_reg(0), + as_string(left_separation)); + // In nroff mode, compensate for width of vertical rule. + if (left_separation) + printfs(".if n .nr %1 +1n\n", column_start_reg(0)); + int i; + for (i = 1;; i++) { + printfs(".nr %1 \\n[%2]+\\n[%3]\n", + column_end_reg(i-1), + column_start_reg(i-1), + span_width_reg(i-1, i-1)); + if (i >= ncolumns) + break; + printfs(".nr %1 \\n[%2]+(%3*\\n[" SEPARATION_FACTOR_REG "])\n", + column_start_reg(i), + column_end_reg(i-1), + as_string(column_separation[i-1])); + // If we have leftover expansion room in a table using the "expand" + // region option, put it prior to the last column so that the table + // looks as if expanded to the available line length. + if ((ncolumns > 2) && (flags & GAP_EXPAND) && (i == (ncolumns - 1))) + printfs(".if n .if \\n[" LEFTOVER_FACTOR_REG "] .nr %1 +(1n>?\\n[" + LEFTOVER_FACTOR_REG "])\n", + column_start_reg(i)); + printfs(".nr %1 \\n[%2]+\\n[%3]/2\n", + column_divide_reg(i), + column_end_reg(i-1), + column_start_reg(i)); + } + printfs(".nr %1 \\n[%2]+%3n\n", + column_divide_reg(ncolumns), + column_end_reg(i-1), + as_string(right_separation)); + printfs(".nr TW \\n[%1]\n", + column_divide_reg(ncolumns)); + if (flags & DOUBLEBOX) { + printfs(".nr %1 +" DOUBLE_LINE_SEP "\n", column_divide_reg(0)); + printfs(".nr %1 -" DOUBLE_LINE_SEP "\n", column_divide_reg(ncolumns)); + } +} + +void table::make_columns_equal() +{ + int first = -1; // index of first equal column + int i; + for (i = 0; i < ncolumns; i++) + if (equal[i]) { + if (first < 0) { + printfs(".nr %1 \\n[%1]", span_width_reg(i, i)); + first = i; + } + else + printfs(">?\\n[%1]", span_width_reg(i, i)); + } + if (first >= 0) { + prints('\n'); + for (i = first + 1; i < ncolumns; i++) + if (equal[i]) + printfs(".nr %1 \\n[%2]\n", + span_width_reg(i, i), + span_width_reg(first, first)); + } +} + +void table::compute_widths() +{ + prints(".\\\" compute column widths\n"); + build_span_list(); + int i; + horizontal_span *p; + // These values get refined later. + prints(".nr " SEPARATION_FACTOR_REG " 1n\n"); + for (i = 0; i < ncolumns; i++) { + init_span_reg(i, i); + if (!minimum_width[i].empty()) + printfs(".nr %1 (n;%2)\n", span_width_reg(i, i), minimum_width[i]); + } + for (p = span_list; p; p = p->next) + init_span_reg(p->start_col, p->end_col); + // Compute all field widths except for blocks. + table_entry *q; + for (q = entry_list; q; q = q->next) + if (!q->mod->zero_width) + q->do_width(); + // Compute all span widths, not handling blocks yet. + for (i = 0; i < ncolumns; i++) + compute_span_width(i, i); + for (p = span_list; p; p = p->next) + compute_span_width(p->start_col, p->end_col); + // Making columns equal normally increases the width of some columns. + make_columns_equal(); + // Note that divide_span keeps equal width columns equal. + // This function might increase the width of some columns, too. + for (p = span_list; p; p = p->next) + divide_span(p->start_col, p->end_col); + compute_total_separation(); + for (p = span_list; p; p = p->next) + sum_columns(p->start_col, p->end_col, 0); + // Now handle unexpanded blocks. + bool had_spanning_block = false; + bool had_equal_block = false; + for (q = entry_list; q; q = q->next) + if (q->divert(ncolumns, minimum_width, + (flags & EXPAND) ? column_separation : 0, 0)) { + if (q->end_col > q->start_col) + had_spanning_block = true; + for (i = q->start_col; i <= q->end_col && !had_equal_block; i++) + if (equal[i]) + had_equal_block = true; + } + // Adjust widths. + if (had_equal_block) + make_columns_equal(); + if (had_spanning_block) + for (p = span_list; p; p = p->next) + divide_span(p->start_col, p->end_col); + compute_overall_width(); + if ((flags & EXPAND) && total_separation != 0) { + compute_separation_factor(); + for (p = span_list; p; p = p->next) + sum_columns(p->start_col, p->end_col, 0); + } + else { + // Handle expanded blocks. + for (p = span_list; p; p = p->next) + sum_columns(p->start_col, p->end_col, 1); + for (q = entry_list; q; q = q->next) + if (q->divert(ncolumns, minimum_width, 0, 1)) { + if (q->end_col > q->start_col) + had_spanning_block = true; + } + // Adjust widths again. + if (had_spanning_block) + for (p = span_list; p; p = p->next) + divide_span(p->start_col, p->end_col); + } + compute_column_positions(); +} + +void table::print_single_hline(int r) +{ + prints(".vs " LINE_SEP ">?\\n[.V]u\n" + ".ls 1\n" + "\\v'" BODY_DEPTH "'" + "\\s[\\n[" LINESIZE_REG "]]"); + if (r > nrows - 1) + prints("\\D'l |\\n[TW]u 0'"); + else { + int start_col = 0; + for (;;) { + while (start_col < ncolumns + && entry[r][start_col] != 0 + && entry[r][start_col]->start_row != r) + start_col++; + int end_col; + for (end_col = start_col; + end_col < ncolumns + && (entry[r][end_col] == 0 + || entry[r][end_col]->start_row == r); + end_col++) + ; + if (end_col <= start_col) + break; + printfs("\\h'|\\n[%1]u", + column_divide_reg(start_col)); + if ((r > 0 && vline[r-1][start_col] == 2) + || (r < nrows && vline[r][start_col] == 2)) + prints("-" HALF_DOUBLE_LINE_SEP); + prints("'"); + printfs("\\D'l |\\n[%1]u", + column_divide_reg(end_col)); + if ((r > 0 && vline[r-1][end_col] == 2) + || (r < nrows && vline[r][end_col] == 2)) + prints("+" HALF_DOUBLE_LINE_SEP); + prints(" 0'"); + start_col = end_col; + } + } + prints("\\s0\n"); + prints(".ls\n" + ".vs\n"); +} + +void table::print_double_hline(int r) +{ + prints(".vs " LINE_SEP "+" DOUBLE_LINE_SEP + ">?\\n[.V]u\n" + ".ls 1\n" + "\\v'" BODY_DEPTH "'" + "\\s[\\n[" LINESIZE_REG "]]"); + if (r > nrows - 1) + prints("\\v'-" DOUBLE_LINE_SEP "'" + "\\D'l |\\n[TW]u 0'" + "\\v'" DOUBLE_LINE_SEP "'" + "\\h'|0'" + "\\D'l |\\n[TW]u 0'"); + else { + int start_col = 0; + for (;;) { + while (start_col < ncolumns + && entry[r][start_col] != 0 + && entry[r][start_col]->start_row != r) + start_col++; + int end_col; + for (end_col = start_col; + end_col < ncolumns + && (entry[r][end_col] == 0 + || entry[r][end_col]->start_row == r); + end_col++) + ; + if (end_col <= start_col) + break; + const char *left_adjust = 0; + if ((r > 0 && vline[r-1][start_col] == 2) + || (r < nrows && vline[r][start_col] == 2)) + left_adjust = "-" HALF_DOUBLE_LINE_SEP; + const char *right_adjust = 0; + if ((r > 0 && vline[r-1][end_col] == 2) + || (r < nrows && vline[r][end_col] == 2)) + right_adjust = "+" HALF_DOUBLE_LINE_SEP; + printfs("\\v'-" DOUBLE_LINE_SEP "'" + "\\h'|\\n[%1]u", + column_divide_reg(start_col)); + if (left_adjust) + prints(left_adjust); + prints("'"); + printfs("\\D'l |\\n[%1]u", + column_divide_reg(end_col)); + if (right_adjust) + prints(right_adjust); + prints(" 0'"); + printfs("\\v'" DOUBLE_LINE_SEP "'" + "\\h'|\\n[%1]u", + column_divide_reg(start_col)); + if (left_adjust) + prints(left_adjust); + prints("'"); + printfs("\\D'l |\\n[%1]u", + column_divide_reg(end_col)); + if (right_adjust) + prints(right_adjust); + prints(" 0'"); + start_col = end_col; + } + } + prints("\\s0\n" + ".ls\n" + ".vs\n"); +} + +void table::compute_vrule_top_adjust(int start_row, int col, string &result) +{ + if (row_is_all_lines[start_row] && start_row < nrows - 1) { + if (row_is_all_lines[start_row] == 2) + result = LINE_SEP ">?\\n[.V]u" "+" DOUBLE_LINE_SEP; + else + result = LINE_SEP ">?\\n[.V]u"; + start_row++; + } + else { + result = ""; + if (start_row == 0) + return; + for (stuff *p = stuff_list; p && p->row <= start_row; p = p->next) + if (p->row == start_row + && (p->is_single_line() || p->is_double_line())) + return; + } + int left = 0; + if (col > 0) { + table_entry *e = entry[start_row-1][col-1]; + if (e && e->start_row == e->end_row) { + if (e->to_double_line_entry() != 0) + left = 2; + else if (e->to_single_line_entry() != 0) + left = 1; + } + } + int right = 0; + if (col < ncolumns) { + table_entry *e = entry[start_row-1][col]; + if (e && e->start_row == e->end_row) { + if (e->to_double_line_entry() != 0) + right = 2; + else if (e->to_single_line_entry() != 0) + right = 1; + } + } + if (row_is_all_lines[start_row-1] == 0) { + if (left > 0 || right > 0) { + result += "-" BODY_DEPTH "-" BAR_HEIGHT; + if ((left == 2 && right != 2) || (right == 2 && left != 2)) + result += "-" HALF_DOUBLE_LINE_SEP; + else if (left == 2 && right == 2) + result += "+" HALF_DOUBLE_LINE_SEP; + } + } + else if (row_is_all_lines[start_row-1] == 2) { + if ((left == 2 && right != 2) || (right == 2 && left != 2)) + result += "-" DOUBLE_LINE_SEP; + else if (left == 1 || right == 1) + result += "-" HALF_DOUBLE_LINE_SEP; + } +} + +void table::compute_vrule_bot_adjust(int end_row, int col, string &result) +{ + if (row_is_all_lines[end_row] && end_row > 0) { + end_row--; + result = ""; + } + else { + stuff *p; + for (p = stuff_list; p && p->row < end_row + 1; p = p->next) + ; + if (p && p->row == end_row + 1 && p->is_double_line()) { + result = "-" DOUBLE_LINE_SEP; + return; + } + if ((p != 0 && p->row == end_row + 1) + || end_row == nrows - 1) { + result = ""; + return; + } + if (row_is_all_lines[end_row+1] == 1) + result = LINE_SEP; + else if (row_is_all_lines[end_row+1] == 2) + result = LINE_SEP "+" DOUBLE_LINE_SEP; + else + result = ""; + } + int left = 0; + if (col > 0) { + table_entry *e = entry[end_row+1][col-1]; + if (e && e->start_row == e->end_row) { + if (e->to_double_line_entry() != 0) + left = 2; + else if (e->to_single_line_entry() != 0) + left = 1; + } + } + int right = 0; + if (col < ncolumns) { + table_entry *e = entry[end_row+1][col]; + if (e && e->start_row == e->end_row) { + if (e->to_double_line_entry() != 0) + right = 2; + else if (e->to_single_line_entry() != 0) + right = 1; + } + } + if (row_is_all_lines[end_row+1] == 0) { + if (left > 0 || right > 0) { + result = "1v-" BODY_DEPTH "-" BAR_HEIGHT; + if ((left == 2 && right != 2) || (right == 2 && left != 2)) + result += "+" HALF_DOUBLE_LINE_SEP; + else if (left == 2 && right == 2) + result += "-" HALF_DOUBLE_LINE_SEP; + } + } + else if (row_is_all_lines[end_row+1] == 2) { + if (left == 2 && right == 2) + result += "-" DOUBLE_LINE_SEP; + else if (left != 2 && right != 2 && (left == 1 || right == 1)) + result += "-" HALF_DOUBLE_LINE_SEP; + } +} + +void table::add_vertical_rule(int start_row, int end_row, + int col, int is_double) +{ + vrule_list = new vertical_rule(start_row, end_row, col, is_double, + vrule_list); + compute_vrule_top_adjust(start_row, col, vrule_list->top_adjust); + compute_vrule_bot_adjust(end_row, col, vrule_list->bot_adjust); +} + +void table::build_vrule_list() +{ + int col; + if (flags & ALLBOX) { + for (col = 1; col < ncolumns; col++) { + int start_row = 0; + for (;;) { + while (start_row < nrows && vline_spanned(start_row, col)) + start_row++; + if (start_row >= nrows) + break; + int end_row = start_row; + while (end_row < nrows && !vline_spanned(end_row, col)) + end_row++; + end_row--; + add_vertical_rule(start_row, end_row, col, 0); + start_row = end_row + 1; + } + } + } + if (flags & (BOX | ALLBOX | DOUBLEBOX)) { + add_vertical_rule(0, nrows - 1, 0, 0); + add_vertical_rule(0, nrows - 1, ncolumns, 0); + } + for (int end_row = 0; end_row < nrows; end_row++) + for (col = 0; col < ncolumns+1; col++) + if (vline[end_row][col] > 0 + && !vline_spanned(end_row, col) + && (end_row == nrows - 1 + || vline[end_row+1][col] != vline[end_row][col] + || vline_spanned(end_row+1, col))) { + int start_row; + for (start_row = end_row - 1; + start_row >= 0 + && vline[start_row][col] == vline[end_row][col] + && !vline_spanned(start_row, col); + start_row--) + ; + start_row++; + add_vertical_rule(start_row, end_row, col, vline[end_row][col] > 1); + } + for (vertical_rule *p = vrule_list; p; p = p->next) + if (p->is_double) + for (int r = p->start_row; r <= p->end_row; r++) { + if (p->col > 0 && entry[r][p->col-1] != 0 + && entry[r][p->col-1]->end_col == p->col-1) { + int is_corner = r == p->start_row || r == p->end_row; + entry[r][p->col-1]->note_double_vrule_on_right(is_corner); + } + if (p->col < ncolumns && entry[r][p->col] != 0 + && entry[r][p->col]->start_col == p->col) { + int is_corner = r == p->start_row || r == p->end_row; + entry[r][p->col]->note_double_vrule_on_left(is_corner); + } + } +} + +void table::define_bottom_macro() +{ + prints(".\\\" define bottom macro\n"); + prints(".eo\n" + // protect # in macro name against eqn + ".ig\n" + ".EQ\n" + "delim off\n" + ".EN\n" + "..\n" + ".de T#\n" + ". if !\\n[" SUPPRESS_BOTTOM_REG "] \\{\\\n" + ". " REPEATED_VPT_MACRO " 0\n" + ". mk " SAVED_VERTICAL_POS_REG "\n"); + if (flags & (BOX | ALLBOX | DOUBLEBOX)) { + prints(". if \\n[T.]&\\n[" NEED_BOTTOM_RULE_REG "] \\{\\\n"); + print_single_hline(0); + prints(". \\}\n"); + } + prints(". ls 1\n"); + for (vertical_rule *p = vrule_list; p; p = p->next) + p->contribute_to_bottom_macro(this); + if (flags & DOUBLEBOX) + prints(". if \\n[T.] \\{\\\n" + ". vs " DOUBLE_LINE_SEP ">?\\n[.V]u\n" + "\\v'" BODY_DEPTH "'\\s[\\n[" LINESIZE_REG "]]" + "\\D'l \\n[TW]u 0'\\s0\n" + ". vs\n" + ". \\}\n" + ". if \\n[" LAST_PASSED_ROW_REG "]>=0 " + ".nr " TOP_REG " \\n[#T]-" DOUBLE_LINE_SEP "\n" + ". sp -1\n" + "\\v'" BODY_DEPTH "'\\s[\\n[" LINESIZE_REG "]]" + "\\D'l 0 |\\n[" TOP_REG "]u-1v'\\s0\n" + ". sp -1\n" + "\\v'" BODY_DEPTH "'\\h'|\\n[TW]u'\\s[\\n[" LINESIZE_REG "]]" + "\\D'l 0 |\\n[" TOP_REG "]u-1v'\\s0\n"); + prints(". ls\n"); + prints(". nr " LAST_PASSED_ROW_REG " \\n[" CURRENT_ROW_REG "]\n" + ". sp |\\n[" SAVED_VERTICAL_POS_REG "]u\n" + ". " REPEATED_VPT_MACRO " 1\n"); + if ((flags & NOKEEP) && (flags & (BOX | DOUBLEBOX | ALLBOX))) + prints(". if (\\n% > \\n[" STARTING_PAGE_REG "]) \\{\\\n" + ". tmc \\n[.F]:\\n[.c]: warning:\n" + ". tmc \" boxed, unkept table does not fit on page\n" + ". tm1 \" \\n[" STARTING_PAGE_REG "]\n" + ". \\}\n"); + prints(". \\}\n" + "..\n" + ".ig\n" + ".EQ\n" + "delim on\n" + ".EN\n" + "..\n" + ".ec\n"); +} + +// is the vertical line before column c in row r horizontally spanned? + +int table::vline_spanned(int r, int c) +{ + assert(r >= 0 && r < nrows && c >= 0 && c < ncolumns + 1); + return (c != 0 && c != ncolumns && entry[r][c] != 0 + && entry[r][c]->start_col != c + // horizontally spanning lines don't count + && entry[r][c]->to_double_line_entry() == 0 + && entry[r][c]->to_single_line_entry() == 0); +} + +int table::row_begins_section(int r) +{ + assert(r >= 0 && r < nrows); + for (int i = 0; i < ncolumns; i++) + if (entry[r][i] && entry[r][i]->start_row != r) + return 0; + return 1; +} + +int table::row_ends_section(int r) +{ + assert(r >= 0 && r < nrows); + for (int i = 0; i < ncolumns; i++) + if (entry[r][i] && entry[r][i]->end_row != r) + return 0; + return 1; +} + +void table::do_row(int r) +{ + printfs(".\\\" do row %1\n", i_to_a(r)); + if (!(flags & NOKEEP) && row_begins_section(r)) + prints(".if \\n[" USE_KEEPS_REG "] ." KEEP_MACRO_NAME "\n"); + bool had_line = false; + stuff *p; + for (p = stuff_list; p && p->row < r; p = p->next) + ; + for (stuff *p1 = p; p1 && p1->row == r; p1 = p1->next) + if (!p1->printed && (p1->is_single_line() || p1->is_double_line())) { + had_line = true; + break; + } + if (!had_line && !row_is_all_lines[r]) + printfs("." REPEATED_MARK_MACRO " %1\n", row_top_reg(r)); + had_line = false; + for (; p && p->row == r; p = p->next) + if (!p->printed) { + p->print(this); + if (!had_line && (p->is_single_line() || p->is_double_line())) { + printfs("." REPEATED_MARK_MACRO " %1\n", row_top_reg(r)); + had_line = true; + } + } + // change the row *after* printing the stuff list (which might contain .TH) + printfs("\\*[" TRANSPARENT_STRING_NAME "].nr " CURRENT_ROW_REG " %1\n", + as_string(r)); + if (!had_line && row_is_all_lines[r]) + printfs("." REPEATED_MARK_MACRO " %1\n", row_top_reg(r)); + // we might have had a .TH, for example, since we last tried + if (!(flags & NOKEEP) && row_begins_section(r)) + prints(".if \\n[" USE_KEEPS_REG "] ." KEEP_MACRO_NAME "\n"); + printfs(".mk %1\n", row_start_reg(r)); + prints(".mk " BOTTOM_REG "\n" + "." REPEATED_VPT_MACRO " 0\n"); + int c; + int row_is_blank = 1; + int first_start_row = r; + for (c = 0; c < ncolumns; c++) { + table_entry *e = entry[r][c]; + if (e) { + if (e->end_row == r) { + e->do_depth(); + if (e->start_row < first_start_row) + first_start_row = e->start_row; + row_is_blank = 0; + } + c = e->end_col; + } + } + if (row_is_blank) + prints(".nr " BOTTOM_REG " +1v\n"); + if (row_is_all_lines[r]) { + prints(".vs " LINE_SEP); + if (row_is_all_lines[r] == 2) + prints("+" DOUBLE_LINE_SEP); + prints(">?\\n[.V]u\n.ls 1\n"); + prints("\\&"); + prints("\\v'" BODY_DEPTH); + if (row_is_all_lines[r] == 2) + prints("-" HALF_DOUBLE_LINE_SEP); + prints("'"); + for (c = 0; c < ncolumns; c++) { + table_entry *e = entry[r][c]; + if (e) { + if (e->end_row == e->start_row) + e->to_simple_entry()->simple_print(1); + c = e->end_col; + } + } + prints("\n"); + prints(".ls\n" + ".vs\n"); + prints(".nr " BOTTOM_REG " \\n[" BOTTOM_REG "]>?\\n[.d]\n"); + printfs(".sp |\\n[%1]u\n", row_start_reg(r)); + } + for (int i = row_is_all_lines[r] ? r - 1 : r; + i >= first_start_row; + i--) { + simple_entry *first = 0; + for (c = 0; c < ncolumns; c++) { + table_entry *e = entry[r][c]; + if (e) { + if (e->end_row == r && e->start_row == i) { + simple_entry *simple = e->to_simple_entry(); + if (simple) { + if (!first) { + prints(".ta"); + first = simple; + } + simple->add_tab(); + } + } + c = e->end_col; + } + } + if (first) { + prints('\n'); + first->position_vertically(); + first->set_location(); + prints("\\&"); + first->simple_print(0); + for (c = first->end_col + 1; c < ncolumns; c++) { + table_entry *e = entry[r][c]; + if (e) { + if (e->end_row == r && e->start_row == i) { + simple_entry *simple = e->to_simple_entry(); + if (simple) { + if (e->end_row != e->start_row) { + prints('\n'); + simple->position_vertically(); + prints("\\&"); + } + simple->simple_print(0); + } + } + c = e->end_col; + } + } + prints('\n'); + prints(".nr " BOTTOM_REG " \\n[" BOTTOM_REG "]>?\\n[.d]\n"); + printfs(".sp |\\n[%1]u\n", row_start_reg(r)); + } + } + for (c = 0; c < ncolumns; c++) { + table_entry *e = entry[r][c]; + if (e) { + if (e->end_row == r && e->to_simple_entry() == 0) { + e->position_vertically(); + e->print(); + prints(".nr " BOTTOM_REG " \\n[" BOTTOM_REG "]>?\\n[.d]\n"); + printfs(".sp |\\n[%1]u\n", row_start_reg(r)); + } + c = e->end_col; + } + } + prints("." REPEATED_VPT_MACRO " 1\n" + ".sp |\\n[" BOTTOM_REG "]u\n" + "\\*[" TRANSPARENT_STRING_NAME "].nr " NEED_BOTTOM_RULE_REG " 1\n"); + if (r != nrows - 1 && (flags & ALLBOX)) { + print_single_hline(r + 1); + prints("\\*[" TRANSPARENT_STRING_NAME "].nr " NEED_BOTTOM_RULE_REG " 0\n"); + } + if (r != nrows - 1) { + if (p && p->row == r + 1 + && (p->is_single_line() || p->is_double_line())) { + p->print(this); + prints("\\*[" TRANSPARENT_STRING_NAME "].nr " NEED_BOTTOM_RULE_REG + " 0\n"); + } + int printed_one = 0; + for (vertical_rule *vr = vrule_list; vr; vr = vr->next) + if (vr->end_row == r) { + if (!printed_one) { + prints("." REPEATED_VPT_MACRO " 0\n"); + printed_one = 1; + } + vr->print(); + } + if (printed_one) + prints("." REPEATED_VPT_MACRO " 1\n"); + if (!(flags & NOKEEP) && row_ends_section(r)) + prints(".if \\n[" USE_KEEPS_REG "] ." RELEASE_MACRO_NAME "\n"); + } +} + +void table::do_top() +{ + prints(".\\\" do top\n"); + prints(".ss \\n[" SAVED_INTER_WORD_SPACE_SIZE "]\n"); + prints(".fc \002\003\n"); + if (flags & (BOX | DOUBLEBOX | ALLBOX)) + prints(".nr " IS_BOXED_REG " 1\n"); + else + prints(".nr " IS_BOXED_REG " 0\n"); + if (!(flags & NOKEEP) && (flags & (BOX | DOUBLEBOX | ALLBOX))) + prints("." TABLE_KEEP_MACRO_NAME "\n"); + if (flags & DOUBLEBOX) { + prints(".ls 1\n" + ".vs " LINE_SEP ">?\\n[.V]u\n" + "\\v'" BODY_DEPTH "'\\s[\\n[" LINESIZE_REG "]]\\D'l \\n[TW]u 0'\\s0\n" + ".vs\n" + "." REPEATED_MARK_MACRO " " TOP_REG "\n" + ".vs " DOUBLE_LINE_SEP ">?\\n[.V]u\n"); + printfs("\\v'" BODY_DEPTH "'" + "\\s[\\n[" LINESIZE_REG "]]" + "\\h'\\n[%1]u'" + "\\D'l |\\n[%2]u 0'" + "\\s0" + "\n", + column_divide_reg(0), + column_divide_reg(ncolumns)); + prints(".ls\n" + ".vs\n"); + } + else if (flags & (ALLBOX | BOX)) + print_single_hline(0); + // On terminal devices, a vertical rule on the first row of the table + // will stick out 1v above it if it the table is unboxed or lacks a + // horizontal rule on the first row. This is necessary for grotty's + // rule intersection detection. We must make room for it so that the + // vertical rule is not drawn above the top of the page. + else if ((flags & HAS_TOP_VLINE) && !(flags & HAS_TOP_HLINE)) + prints(".if n .sp\n"); + prints(".nr " STARTING_PAGE_REG " \\n%\n"); + //printfs(".mk %1\n", row_top_reg(0)); +} + +void table::do_bottom() +{ + prints(".\\\" do bottom\n"); + // print stuff after last row + for (stuff *p = stuff_list; p; p = p->next) + if (p->row > nrows - 1) + p->print(this); + if (!(flags & NOKEEP)) + prints(".if \\n[" USE_KEEPS_REG "] ." RELEASE_MACRO_NAME "\n"); + printfs(".mk %1\n", row_top_reg(nrows)); + prints(".nr " NEED_BOTTOM_RULE_REG " 1\n" + ".nr T. 1\n" + // protect # in macro name against eqn + ".ig\n" + ".EQ\n" + "delim off\n" + ".EN\n" + "..\n" + ".T#\n" + ".ig\n" + ".EQ\n" + "delim on\n" + ".EN\n" + "..\n"); + if (!(flags & NOKEEP) && (flags & (BOX | DOUBLEBOX | ALLBOX))) + prints("." TABLE_RELEASE_MACRO_NAME "\n"); + if (flags & DOUBLEBOX) + prints(".sp " DOUBLE_LINE_SEP "\n"); + // Horizontal box lines take up an entire row on nroff devices (maybe + // a half-row if we ever support [emulators of] devices like the + // Teletype Model 37 with half-line motions). + if (flags & (BOX | DOUBLEBOX | ALLBOX)) + prints(".if n .sp\n"); + // Space again for the doublebox option, until we can draw that more + // attractively; see Savannah #43637. + if (flags & DOUBLEBOX) + prints(".if n .sp\n"); + prints("." RESET_MACRO_NAME "\n" + ".nn \\n[" SAVED_NUMBERING_SUPPRESSION_COUNT "]\n" + ".ie \\n[" SAVED_NUMBERING_LINENO "] " + ".nm \\n[" SAVED_NUMBERING_LINENO "]\n" + ".el .nm\n" + ".fc\n" + ".cp \\n(" COMPATIBLE_REG "\n"); +} + +int table::get_nrows() +{ + return nrows; +} + +const char *last_filename = 0; + +void set_troff_location(const char *fn, int ln) +{ + if (!location_force_filename && last_filename != 0 + && strcmp(fn, last_filename) == 0) + printfs(".lf %1\n", as_string(ln)); + else { + string filename(fn); + filename += '\0'; + normalize_for_lf(filename); + printfs(".lf %1 %2\n", as_string(ln), filename.contents()); + last_filename = fn; + location_force_filename = 0; + } +} + +void printfs(const char *s, const string &arg1, const string &arg2, + const string &arg3, const string &arg4, const string &arg5) +{ + if (s) { + char c; + while ((c = *s++) != '\0') { + if (c == '%') { + switch (*s++) { + case '1': + prints(arg1); + break; + case '2': + prints(arg2); + break; + case '3': + prints(arg3); + break; + case '4': + prints(arg4); + break; + case '5': + prints(arg5); + break; + case '6': + case '7': + case '8': + case '9': + break; + case '%': + prints('%'); + break; + default: + assert(0 == "printfs format character not in [1-9%]"); + } + } + else + prints(c); + } + } +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/tbl/table.h b/src/preproc/tbl/table.h new file mode 100644 index 0000000..62346fa --- /dev/null +++ b/src/preproc/tbl/table.h @@ -0,0 +1,179 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "lib.h" + +#include +#include +#include + +#include "cset.h" +#include "cmap.h" +#include "stringclass.h" +#include "errarg.h" +#include "error.h" +#include "lf.h" + +// PREFIX and PREFIX_CHAR must be the same. +#define PREFIX "3" +#define PREFIX_CHAR '3' + +// LEADER and LEADER_CHAR must be the same. +#define LEADER "a" +#define LEADER_CHAR 'a' + +struct inc_number { + short inc; + short val; +}; + +struct entry_modifier { + inc_number point_size; + inc_number vertical_spacing; + string font; + string macro; + enum { CENTER, TOP, BOTTOM } vertical_alignment; + char zero_width; + char stagger; + + entry_modifier(); + ~entry_modifier(); +}; + +enum format_type { + FORMAT_LEFT, + FORMAT_CENTER, + FORMAT_RIGHT, + FORMAT_NUMERIC, + FORMAT_ALPHABETIC, + FORMAT_SPAN, + FORMAT_VSPAN, + FORMAT_HLINE, + FORMAT_DOUBLE_HLINE +}; + +struct entry_format : public entry_modifier { + format_type type; + + entry_format(format_type); + entry_format(); + void debug_print() const; +}; + +class table_entry; +struct horizontal_span; +struct stuff; +struct vertical_rule; + +class table { + int nrows; + int ncolumns; + int linesize; + char delim[2]; + char decimal_point_char; + vertical_rule *vrule_list; + stuff *stuff_list; + horizontal_span *span_list; + table_entry *entry_list; + table_entry **entry_list_tailp; + table_entry ***entry; + char **vline; + char *row_is_all_lines; + string *minimum_width; + int *column_separation; + char *equal; + int left_separation; // from a vertical rule or box border, in ens + int right_separation; // from a vertical rule or box border, in ens + int total_separation; + int allocated_rows; + void build_span_list(); + void compute_overall_width(); + void do_hspan(int r, int c); + void do_vspan(int r, int c); + void allocate(int r); + void compute_widths(); + void divide_span(int, int); + void sum_columns(int, int, int); + void compute_total_separation(); + void compute_separation_factor(); + void compute_column_positions(); + void do_row(int); + void init_output(); + void add_stuff(stuff *); + void do_top(); + void do_bottom(); + void do_vertical_rules(); + void build_vrule_list(); + void add_vertical_rule(int, int, int, int); + void define_bottom_macro(); + int vline_spanned(int r, int c); + int row_begins_section(int); + int row_ends_section(int); + void make_columns_equal(); + void compute_vrule_top_adjust(int, int, string &); + void compute_vrule_bot_adjust(int, int, string &); + void determine_row_type(); + int count_expand_columns(); +public: + unsigned flags; + enum { + CENTER = 0x00000001, + EXPAND = 0x00000002, + BOX = 0x00000004, + ALLBOX = 0x00000008, + DOUBLEBOX = 0x00000010, + NOKEEP = 0x00000020, + NOSPACES = 0x00000040, + NOWARN = 0x00000080, + // The next few properties help manage nroff mode output. + HAS_TOP_VLINE = 0x00000100, + HAS_TOP_HLINE = 0x00000200, + GAP_EXPAND = 0x00000400, + EXPERIMENTAL = 0x80000000 // undocumented + }; + char *expand; + table(int nc, unsigned flags, int linesize, char decimal_point_char); + ~table(); + + void add_text_line(int r, const string &, const char *, int); + void add_single_hline(int r); + void add_double_hline(int r); + void add_entry(int r, int c, const string &, const entry_format *, + const char *, int lineno); + void add_vlines(int r, const char *); + void check(); + void print(); + void set_minimum_width(int c, const string &w); + void set_column_separation(int c, int n); + void set_equal_column(int c); + void set_expand_column(int c); + void set_delim(char c1, char c2); + void print_single_hline(int r); + void print_double_hline(int r); + int get_nrows(); +}; + +void set_troff_location(const char *, int); + +extern int compatible_flag; + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/preproc/tbl/tbl.1.man b/src/preproc/tbl/tbl.1.man new file mode 100644 index 0000000..4c9a98a --- /dev/null +++ b/src/preproc/tbl/tbl.1.man @@ -0,0 +1,2018 @@ +'\" t +.TH @g@tbl @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +@g@tbl \- prepare tables for +.I groff +documents +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1989-2023 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_tbl_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY @g@tbl +.RB [ \-C ] +.RI [ file\~ .\|.\|.] +.YS +. +. +.SY @g@tbl +.B \-\-help +.YS +. +. +.SY @g@tbl +.B \-v +. +.SY @g@tbl +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +The GNU implementation of +.I tbl \" generic +is part of the +.MR groff @MAN1EXT@ +document formatting system. +. +.I @g@tbl +is a +.MR @g@troff @MAN1EXT@ +preprocessor that translates descriptions of tables embedded in +.MR roff @MAN7EXT@ +input files into the language understood by +.IR @g@troff . +. +It copies the contents of each +.I file +to the standard output stream, +except that lines between +.B .TS +and +.B .TE +are interpreted as table descriptions. +. +While GNU +.IR tbl 's \" GNU +input syntax is highly compatible with AT&T +.IR tbl , \" AT&T +the output GNU +.I tbl \" GNU +produces cannot be processed by AT&T +.IR troff ; \" AT&T +GNU +.I troff \" GNU +(or a +.I troff \" generic +implementing any GNU extensions employed) +must be used. +. +Normally, +.I @g@tbl +is not executed directly by the user, +but invoked by specifying the +.B \-t +option to +.MR groff @MAN1EXT@ . +. +If no +.I file +operands are given on the command line, +or if +.I file +is +.RB \[lq] \- \[rq], +.I @g@tbl +reads the standard input stream. +. +. +.\" ==================================================================== +.SS Overview +.\" ==================================================================== +. +.I @g@tbl +expects to find table descriptions between input lines that begin with +.B .TS +(table start) +and +.B .TE +(table end). +. +Each such +.I table region +encloses one or more table descriptions. +. +Within a table region, +table descriptions beyond the first must each be preceded +by an input line beginning with +.BR .T& . +. +This mechanism does not start a new table region; +all table descriptions are treated as part of their +.BR .TS / .TE +enclosure, +even if they are boxed or have column headings that repeat on subsequent +pages +(see below). +. +. +.P +(Experienced +.I roff +users should observe that +.I @g@tbl +is not a +.I roff +language interpreter: +the default control character must be used, +and no spaces or tabs are permitted between the control character and +the macro name. +. +These +.I @g@tbl +input tokens remain as-is in the output, +where they become ordinary macro calls. +. +Macro packages often define +.BR TS , +.BR T& , +and +.B TE +macros to handle issues of table placement on the page. +. +.I @g@tbl +produces +.I groff +code to define these macros as empty if their definitions do not exist +when the formatter encounters a table region.) +. +. +.P +Each table region may begin with +.I region options, +and must contain one or more +.I table definitions; +each table definition contains a +.I format specification +followed by one or more input lines (rows) of +.I entries. +. +These entries comprise the +.I table data. +. +. +. +.\" ==================================================================== +.SS "Region options" +.\" ==================================================================== +. +The line immediately following the +.B .TS +token may specify region options, +keywords that influence the interpretation or rendering of the region as +a whole or all table entries within it indiscriminately. +. +They must be separated by commas, +spaces, +or tabs. +. +Those that require a parenthesized argument permit spaces and tabs +between the option's name and the opening parenthesis. +. +Options accumulate and cannot be unset within a region once declared; +if an option that takes a parameter is repeated, +the last occurrence controls. +. +If present, +the set of region options must be terminated with a semicolon +.RB ( ; ). +. +. +.P +Any of the +.BR allbox , +.BR box , +.BR doublebox , +.BR frame , +and +.B doubleframe +region options makes a table \[lq]boxed\[rq] for the purpose of later +discussion. +. +. +.TP +.B allbox +Enclose each table entry in a box; +implies +.BR box . +. +. +.TP +.B box +Enclose the entire table region in a box. +. +As a GNU extension, +the alternative option name +.B frame +is also recognized. +. +. +.TP +.B center +Center the table region with respect to the current indentation and line +length; +the default is to left-align it. +. +As a GNU extension, +the alternative option name +.B centre +is also recognized. +. +. +.TP +.BI decimalpoint( c ) +Recognize character +.I c +as the decimal separator in columns using the +.B N +(numeric) classifier +(see subsection \[lq]Column classifiers\[rq] below). +. +This is a GNU extension. +. +. +.TP +.BI delim( xy ) +Recognize characters +.I x +.RI and\~ y +as start and end delimiters, +respectively, +for +.MR @g@eqn @MAN1EXT@ +input, +and ignore input between them. +. +.I x +.RI and\~ y +need not be distinct. +. +. +.TP +.B doublebox +Enclose the entire table region in a double box; +implies +.BR box . +. +As a GNU extension, +the alternative option name +.B \%doubleframe +is also recognized. +. +. +.TP +.B expand +Spread the table horizontally to fill the available space +(line length minus indentation) +by increasing column separation. +. +Ordinarily, +a table is made only as wide as necessary to accommodate the widths of +its entries and its column separations +(whether specified or default). +. +When +.B expand +applies to a table that exceeds the available horizontal space, +column separation is reduced as far as necessary +(even to zero). +. +.I @g@tbl +produces +.I groff +input that issues a diagnostic if such compression occurs. +. +The column modifier +.B x +(see below) +overrides this option. +. +. +.TP +.BI linesize( n ) +Draw lines or rules +(e.g., +from +.BR box ) +with a thickness of +.IR n \~points. +. +The default is the current type size when the region begins. +. +This option is ignored on terminal devices. +. +. +.TP +.B nokeep +Don't use +.I roff +diversions to manage page breaks. +. +Normally, +.I @g@tbl +employs them to avoid breaking a page within a table row. +. +This usage can sometimes interact badly with macro packages' own use of +diversions\[em]when footnotes, +for example, +are employed. +. +This is a GNU extension. +. +. +.TP +.B nospaces +Ignore leading and trailing spaces in table entries. +. +This is a GNU extension. +. +. +.TP +.B nowarn +Suppress diagnostic messages produced at document formatting time when +the line or page lengths are inadequate to contain a table row. +. +This is a GNU extension. +. +. +.\" TODO: How about "right"? (and "left" for symmetry) +.TP +.BI tab( c ) +Use the character +.I c +instead of a tab to separate entries in a row of table data. +. +. +.\" ==================================================================== +.SS "Table format specification" +.\" ==================================================================== +. +The table format specification is mandatory: +it determines the number of columns in the table and directs how the +entries within it are to be typeset. +. +The format specification is a series of column +.I descriptors. +. +Each descriptor encodes a +.I classifier +followed by zero or more +.I modifiers. +. +Classifiers are letters +(recognized case-insensitively) +or punctuation symbols; +modifiers consist of or begin with letters or numerals. +. +Spaces, +tabs, +newlines, +and commas separate descriptors. +. +Newlines and commas are special; +they apply the descriptors following them to a subsequent row of the +table. +. +(This enables column headings to be centered or emboldened while the +table entries for the data are not, +for instance.) +. +We term the resulting group of column descriptors a +.I row definition. +. +Within a row definition, +separation between column descriptors +(by spaces or tabs) +is often optional; +only some modifiers, +described below, +make separation necessary. +. +. +.P +Each column descriptor begins with a mandatory +.I classifier, +a character that selects from one of several arrangements. +. +Some determine the positioning of table entries within a rectangular +cell: +centered, +left-aligned, +numeric +(aligned to a configurable decimal separator), +and so on. +. +Others perform special operations like drawing lines or spanning entries +from adjacent cells in the table. +. +Except for +.RB \[lq] | \[rq], +any classifier can be followed by one or more +.I modifiers; +some of these accept an argument, +which in GNU +.I tbl \" GNU +can be parenthesized. +.\" AT&T tbl allowed parentheses only after 'w'. +.\" TODO: Accept parentheses after 'p' and 'v'. +. +Modifiers select fonts, +set the type size, +.\"define the column width, +.\"adjust inter-column spacing, \" slack text for window/orphan control +and perform other tasks described below. +. +. +.P +The format specification can occupy multiple input lines, +but must conclude with a dot +.RB \[lq] .\& \[rq] +followed by a newline. +. +Each row definition is applied in turn to one row of the table. +. +The last row definition is applied to rows of table data in excess of +the row definitions. +. +. +.P +For clarity in this document's examples, +we shall write classifiers in uppercase and modifiers in lowercase. +. +Thus, +.RB \[lq] CbCb,LR.\& \[rq] +defines two rows of two columns. +. +The first row's entries are centered and boldfaced; +the second and any further rows' first and second columns are left- and +right-aligned, +respectively. +. +.\" slack text for window/orphan control +.\"If more rows of entries are added to the table data, +.\"they reuse the row definition +.\".RB \[lq] LR \[rq]. +. +. +.P +The row definition with the most column descriptors determines the +number of columns in the table; +any row definition with fewer is implicitly extended on the right-hand +side with +.B L +classifiers as many times as necessary to make the table rectangular. +. +. +.\" ==================================================================== +.SS "Column classifiers" +.\" ==================================================================== +. +The +.BR L , +.BR R , +and +.B C +classifiers are the easiest to understand and use. +. +. +.TP +.BR A ,\~ a +Center longest entry in this column, +left-align remaining entries in the column with respect to the centered +entry, +then indent all entries by one en. +. +Such \[lq]alphabetic\[rq] entries +(hence the name of the classifier) +can be used in the same column as +.BR L -classified +entries, +as in +.RB \[lq] LL,AR.\& \[rq]. +. +The +.B A +entries are often termed \[lq]sub-columns\[rq] due to their indentation. +. +. +.TP +.BR C ,\~ c +Center entry within the column. +. +. +.TP +.BR L ,\~ l +Left-align entry within the column. +. +. +.TP +.BR N ,\~ n +Numerically align entry in the column. +. +.I @g@tbl +aligns columns of numbers vertically at the units place. +. +If multiple decimal separators are adjacent to a digit, +it uses the rightmost one for vertical alignment. +. +If there is no decimal separator, +the rightmost digit is used for vertical alignment; +otherwise, +.I @g@tbl +centers the entry within the column. +. +The +.I roff +dummy character +.B \[rs]& +in an entry marks the glyph preceding it +(if any) +as the units place; +if multiple instances occur in the data, +the leftmost is used for alignment. +. +. +.IP +If +.BR N -classified +entries share a column with +.B L +or +.BR R \~entries, +.I @g@tbl +centers the widest +.BR N \~entry +with respect to the widest +.B L +or +.BR R \~entry, +preserving the alignment of +.BR N \~entries +with respect to each other. +. +. +.IP +The appearance of +.I @g@eqn +equations +within +.BR N -classified +columns +can be troublesome due to the foregoing textual scan for a decimal +separator. +. +Use the +.B \%delim +region option to make +.I @g@tbl +ignore the data within +.I eqn +delimiters for that purpose. +. +. +.TP +.BR R ,\~ r +Right-align entry within the column. +. +. +.TP +.BR S ,\~ s +Span previous entry on the left into this column. +. +. +.TP +.B \[ha] +Span entry in the same column from the previous row into this row. +. +. +.TP +.BR _ ,\~ \- +Replace table entry with a horizontal rule. +. +An empty table entry is expected to correspond to this classifier; +if data are found there, +.I @g@tbl +issues a diagnostic message. +. +. +.TP +.B = +Replace table entry with a double horizontal rule. +. +An empty table entry is expected to correspond to this classifier; +if data are found there, +.I @g@tbl +issues a diagnostic message. +. +. +.TP +.B | +Place a vertical rule (line) on the corresponding row of the table +(if two of these are adjacent, +a double vertical rule). +. +This classifier does not contribute to the column count and no table +entries correspond to it. +. +A +.B | +to the left of the first column descriptor or to the right of the last +one produces a vertical rule at the edge of the table; +these are redundant +(and ignored) +in boxed tables. +. +. +.P +To change the table format within a +.I @g@tbl +region, +use the +.B .T& +token at the start of a line. +. +It is followed by a format specification and table data, +but +.I not +region options. +. +The quantity of columns in a new table format thus introduced cannot +increase relative to the previous table format; +in that case, +you must end the table region and start another. +. +If that will not serve because the region uses box options or the +columns align in an undesirable manner, +you must design the initial table format specification to include the +maximum quantity of columns required, +and use the +.B S +horizontal spanning classifier where necessary to achieve the desired +columnar alignment. +. +. +.P +Attempting to horizontally span in the first column or vertically span +on the first row is an error. +. +Non-rectangular span areas are also not supported. +. +. +.\" ==================================================================== +.SS "Column modifiers" +.\" ==================================================================== +. +Any number of modifiers can follow a column classifier. +. +Arguments to modifiers, +where accepted, +are case-sensitive. +. +If the same modifier is applied to a column specifier more than once, +or if conflicting modifiers are applied, +only the last occurrence has effect. +. +The +.RB modifier\~ x +is mutually exclusive with +.B e +.RB and\~ w , +but +.B e +is not mutually exclusive +.RB with\~ w ; +if these are used in combination, +.BR x \~unsets +both +.B e +.RB and\~ w , +while either +.B e +or +.B w +.RB overrides\~ x . +. +. +.br +.ne 4v \" Keep next two tagged paragraphs together. +.TP +.BR b ,\~ B +Typeset entry in boldface, +abbreviating +.BR f(B) . +. +. +.TP +.BR d ,\~ D +Align a vertically spanned table entry to the bottom +(\[lq]down\[rq]), +instead of the center, +of its range. +. +This is a GNU extension. +. +. +.TP +.BR e ,\~ E +Equalize the widths of columns with this modifier. +. +The column with the largest width controls. +. +This modifier sets the default line length used in a text block. +. +. +.TP +.BR f ,\~ F +Select the typeface for the table entry. +. +This modifier must be followed by a font or style name +(one or two characters not starting with a digit), +font mounting position +(a single digit), +or a name or mounting position of any length in parentheses. +. +The last form is a GNU extension. +. +(The parameter corresponds to that accepted by the +.I troff \" generic +.B ft +request.) +. +A one-character argument not in parentheses must be separated by one or +more spaces or tabs from what follows. +. +. +.TP +.BR i ,\~ I +Typeset entry in an oblique or italic face, +abbreviating +.BR f(I) . +. +. +.TP +.BR m ,\~ M +Call a +.I groff +macro before typesetting a text block +(see subsection \[lq]Text blocks\[rq] below). +. +This is a GNU extension. +. +This modifier must be followed by a macro name of one or two characters +or a name of any length in parentheses. +. +A one-character macro name not in parentheses must be separated by one +or more spaces or tabs from what follows. +. +The named macro must be defined before the table region containing this +column modifier is encountered. +. +The macro should contain only simple +.I groff +requests to change text formatting, +like adjustment or hyphenation. +. +The macro is called +.I after +the column modifiers +.BR b , +.BR f , +.BR i , +.BR p , +and +.B v +take effect; +it can thus override other column modifiers. +. +. +.TP +.BR p ,\~ P +Set the type size for the table entry. +. +This modifier must be followed by an +.RI integer\~ n +with an optional leading sign. +. +If unsigned, +the type size is set to +.IR n \~scaled +points. +. +Otherwise, +the type size is incremented or decremented per the sign by +.IR n \~scaled +points. +. +The use of a signed multi-digit number is a GNU extension. +. +(The parameter corresponds to that accepted by the +.I troff \" generic +.B ps +request.) +. +If a type size modifier is followed by a column separation modifier +(see below), +they must be separated by at least one space or tab. +.\" TODO: Allow parentheses so scaling units and fractional values can +.\" be used? +. +. +.TP +.BR t ,\~ T +Align a vertically spanned table entry to the top, +instead of the center, +of its range. +. +. +.TP +.BR u ,\~ U +Move the column up one half-line, +\[lq]staggering\[rq] the rows. +. +This is a GNU extension. +. +. +.TP +.BR v ,\~ V +Set the vertical spacing to be used in a text block. +. +This modifier must be followed by an +.RI integer\~ n +with an optional leading sign. +. +If unsigned, +the vertical spacing is set to +.IR n\~ points. +. +Otherwise, +the vertical spacing is incremented or decremented per the sign by +.IR n\~ points. +. +The use of a signed multi-digit number is a GNU extension. +. +(This parameter corresponds to that accepted by the +.I troff \" generic +.B vs +request.) +. +If a vertical spacing modifier is followed by a column separation +modifier +(see below), +they must be separated by at least one space or tab. +.\" TODO: Allow parentheses so scaling units and fractional values can +.\" be used? +. +. +.TP +.BR w ,\~ W +Set the column's minimum width. +. +This modifier must be followed by a number, +which is either a unitless integer, +or a +.I roff +horizontal measurement in parentheses. +. +Parentheses are required if the width is to be followed immediately by +an explicit column separation +(alternatively, +follow the width with one or more spaces or tabs). +. +If no unit is specified, +ens are assumed. +. +This modifier sets the default line length used in a text block. +. +. +.TP +.BR x ,\~ X +Expand the column. +. +After computing the column widths, +distribute any remaining line length evenly over all columns bearing +this modifier. +. +Applying the +.BR x \~modifier +to more than one column is a GNU extension. +.\" 'x' wasn't documented at all in Lesk 1979. +. +This modifier sets the default line length used in a text block. +. +. +.TP +.BR z ,\~ Z +Ignore the table entries corresponding to this column for width +calculation purposes; +that is, +compute the column's width using only the information in its descriptor. +. +. +.TP +.I n +A numeric suffix on a column descriptor sets the separation distance +(in ens) +from the succeeding column; +the default separation is +.BR 3n . +. +This separation is +proportionally multiplied if the +.B expand +region option is in effect; +in the case of tables wider than the output line length, +this separation might be zero. +. +A negative separation cannot be specified. +. +A separation amount after the last column in a row is nonsensical and +provokes a diagnostic from +.IR @g@tbl . +. +. +.\" ==================================================================== +.SS "Table data" +.\" ==================================================================== +. +The table data come after the format specification. +. +Each input line corresponds to a table row, +except that a backslash at the end of a line of table data continues an +entry on the next input line. +. +(Text blocks, +discussed below, +also spread table entries across multiple input lines.) +. +Table entries within a row are separated in the input by a tab character +by default; +see the +.B tab +region option above. +. +Excess entries in a row of table data +(those that have no corresponding column descriptor, +not even an implicit one arising from rectangularization of the table) +are discarded with a diagnostic message. +. +.I roff +control lines are accepted between rows of table data and within text +blocks. +. +If you wish to visibly mark an empty table entry in the document source, +populate it with the +.B \[rs]& +.I roff +dummy character. +. +The table data are interrupted by a line consisting of the +.B .T& +input token, +and conclude with the line +.BR .TE . +. +. +.P +Ordinarily, +a table entry is typeset rigidly. +. +It is not filled, +broken, +hyphenated, +adjusted, +or populated with additional inter-sentence space. +. +.I @g@tbl +instructs the formatter to measure each table entry as it occurs in the +input, +updating the width required by its corresponding column. +. +If the +.B z +modifier applies to the column, +this measurement is ignored; +if +.B w +applies and its argument is larger than this width, +that argument is used instead. +. +In contrast to conventional +.I roff +input +(within a paragraph, +say), +changes to text formatting, +such as font selection or vertical spacing, +do not persist between entries. +. +. +.P +Several forms of table entry are interpreted specially. +. +. +.IP \[bu] 2n +If a table row contains only an underscore or equals sign +.RB ( _ +or +.BR = ), +a single or double horizontal rule (line), +respectively, +is drawn across the table at that point. +. +. +.IP \[bu] 2n +A table entry containing only +.B _ +or +.B = +on an otherwise populated row is replaced by a single or double +horizontal rule, +respectively, +joining its +neighbors. +. +. +.IP \[bu] 2n +Prefixing a lone underscore or equals sign with a backslash also has +meaning. +. +If a table entry consists only of +.B \[rs]_ +or +.B \[rs]= +on an otherwise populated row, +it is replaced by a single or double horizontal rule, +respectively, +that does +.I not +(quite) join its neighbors. +. +. +.IP \[bu] +A table entry consisting of +.BI \[rs]R x\c +, +where +.IR x \~is +any +.I roff +ordinary or special character, +is replaced by enough repetitions of the glyph corresponding +.RI to\~ x +to fill the column, +albeit without joining its neighbors. +.\" TODO: Bad things happen if there's garbage in the entry after 'x', +.\" which can be a *roff special character escape sequence, so +.\" validation is not trivial. +. +. +.IP \[bu] +On any row but the first, +a table entry of +.B \[rs]\[ha] +causes the entry above it to span down into the current one. +. +. +.P +On occasion, +these special tokens may be required as literal table data. +. +To use either +.B _ +or +.B = +literally and alone in an entry, +prefix or suffix it with the +.I roff +dummy character +.BR \[rs]& . +. +To express +.BR \[rs]_ , +.BR \[rs]= , +or +.BR \[rs]R , +use a +.I roff +escape sequence to interpolate the backslash +.RB ( \[rs]e +or +.BR \[rs][rs] ). +. +A reliable way to emplace the +.B \[rs]\[ha] +glyph sequence within a table entry is to use a pair of +.I groff +special character escape sequences +.RB ( \[rs][rs]\[rs][ha] ). +. +. +.P +Rows of table entries can be interleaved with +.I groff +control lines; +these do not count as table data. +. +On such lines the default control character +.RB ( .\& ) +must be used +(and not changed); +the no-break control character is not recognized. +. +To start the first table entry in a row with a dot, +precede it with the +.I roff +dummy character +.BR \[rs]& . +. +. +.\" ==================================================================== +.SS "Text blocks" +.\" ==================================================================== +. +An ordinary table entry's contents can make a column, +and therefore the table, +excessively wide; +the table then exceeds the line length of the page, +and becomes ugly or is exposed to truncation by the output device. +. +When a table entry requires more conventional typesetting, +breaking across more than one output line +(and thereby increasing the height of its row), +it can be placed within a +.I text block. +. +. +.P +.I @g@tbl +interprets a table entry beginning with +.RB \[lq] T{ \[rq] +at the end of an input line not as table data, +but as a token starting a text block. +. +Similarly, +.RB \[lq] T} \[rq] +at the start of an input line ends a text block; +it must also end the table entry. +. +Text block tokens can share an input line with other table data +(preceding +.B T{ +and following +.BR T} ). +. +Input lines between these tokens are formatted in a diversion by +.IR troff . \" generic +. +Text blocks cannot be nested. +. +Multiple text blocks can occur in a table row. +. +. +.P +Text blocks are formatted as was the text prior to the table, +modified by applicable column descriptors. +. +Specifically, +the classifiers +.BR A , +.BR C , +.BR L , +.BR N , +.BR R , +and +.B S +determine a text block's +.I alignment +within its cell, +but not its +.I adjustment. +. +Add +.B na +or +.B ad +requests to the beginning of a text block to alter its adjustment +distinctly from other text in the document. +. +As with other table entries, +when a text block ends, +any alterations to formatting parameters are discarded. +. +They do not affect subsequent table entries, +not even other text blocks. +. +. +.P +.ne 2v +If +.B w +or +.B x +modifiers are not specified for +.I all +columns of a text block's span, +the default length of the text block +(more precisely, +the line length used to process the text block diversion) +is computed as +.IR L \[tmu] C /( N +1), +.\" ...and rounded to the horizontal motion quantum of the output device +where +.I L +is the current line length, +.I C +the number of columns spanned by the text block, +and +.I N +the number of columns in the table. +. +If necessary, +you can also control a text block's width by including an +.B ll +(line length) +request in it prior to any text to be formatted. +. +Because a diversion is used to format the text block, +its height and width are subsequently available in the registers +.B dn +and +.BR dl , +respectively. +. +. +.\" ==================================================================== +.SS \f[I]roff\f[] interface +.\" ==================================================================== +. +The register +.B TW +stores the width of the table region in basic units; +it can't be used within the region itself, +but is defined before the +.B .TE +token is output so that a +.I groff +macro named +.B TE +can make use of it. +. +.B T.\& +is a Boolean-valued register indicating whether the bottom of the table +is being processed. +. +The +.B #T +register marks the top of the table. +. +Avoid using these names for any other purpose. +. +. +.P +.I @g@tbl +also defines a macro +.B T# +to produce the bottom and side lines of a boxed table. +. +While +.I @g@tbl +itself arranges for the output to include a call of this macro at the +end of such a table, +it can also be used by macro packages to create boxes for multi-page +tables by calling it from a page footer macro that is itself called by +a trap planted near the bottom of the page. +. +See section \[lq]Limitations\[rq] below for more on multi-page tables. +. +. +.P +GNU +.I tbl \" GNU +.\" AT&T tbl used all kinds of registers; many began with "3". +internally employs register, +string, +macro, +and diversion names beginning with the +.RB numeral\~ 3 . +. +A document to be preprocessed with GNU +.I tbl \" GNU +should not use any such identifiers. +.\" XXX: Why are they not named starting with "gtbl*" or something? GNU +.\" tbl turns AT&T troff compatibility mode off anyway. +. +. +.\" ==================================================================== +.SS "Interaction with \f[I]@g@eqn\f[]" +.\" ==================================================================== +. +.I @g@tbl +should always be called before +.MR @g@eqn @MAN1EXT@ . +. +(\c +.MR groff @MAN1EXT@ +automatically arranges preprocessors in the correct order.) +. +Don't call the +.B EQ +and +.B EN +macros within tables; +instead, +set up delimiters in your +.I eqn \" generic +input and use the +.B \%delim +region option so that +.I @g@tbl +will recognize them. +. +. +.br +.ne 5v \" Keep enough space for heading, intro sentence, and first item. +.\" ==================================================================== +.SS "GNU \f[I]tbl\f[] enhancements" +.\" ==================================================================== +. +In addition to extensions noted above, +GNU +.I tbl \" GNU +removes constraints endured by users of AT&T +.IR tbl .\" AT&T +. +. +.IP \[bu] 2n +Region options can be specified in any lettercase. +. +. +.IP \[bu] +There is no limit on the number of columns in a table, +regardless of their classification, +nor any limit on the number of text blocks. +. +. +.IP \[bu] +All table rows are considered when deciding column widths, +not just those occurring in the first 200 input lines of a region. +. +Similarly, +table continuation +.RB ( .T& ) +tokens are recognized outside a region's first 200 input lines. +. +. +.IP \[bu] +Numeric and alphabetic entries may appear in the same column. +. +. +.IP \[bu] +Numeric and alphabetic entries may span horizontally. +. +. +.\" ==================================================================== +.SS "Using GNU \f[I]tbl\f[] within macros" +.\" ==================================================================== +. +You can embed a table region inside a macro definition. +. +However, +since +.I @g@tbl +writes its own macro definitions at the beginning of each table region, +it is necessary to call end macros instead of ending macro definitions +with +.RB \[lq] ..\& \[rq]. +.\" XXX: Why don't we fix that by ending all of tbl's own macro +.\" definitions with a call to a macro in its own reserved name space? +. +Additionally, +the escape character must be disabled. \" XXX: Why? +. +. +.P +Not all +.I @g@tbl +features can be exercised from such macros because +.I @g@tbl +is a +.I roff +preprocessor: +it sees the input earlier than +.I @g@troff +does. +. +For example, +vertically aligning decimal separators fails if the numbers containing +them occur as macro or string parameters; +the alignment is performed by +.I @g@tbl +itself, +which sees only +.BR \[rs]$1 , +.BR \[rs]$2 , +and so on, +and therefore can't recognize a decimal separator that only appears +later when +.I @g@troff +interpolates a macro or string definition. +. +. +.\" XXX: The following is a general caveat about preprocessors; move it. +.P +Using +.I @g@tbl +macros within conditional input +(that is, +contingent upon an +.BR if , +.BR ie , +.BR el , +or +.B while +request) +can result in misleading line numbers in subsequent diagnostics. +. +.I @g@tbl +unconditionally injects its output into the source document, +but the conditional branch containing it may not be taken, +and if it is not, +the +.B lf +requests that +.I @g@tbl +injects to restore the source line number cannot take effect. +. +Consider copying the input line counter register +.B c.\& +and restoring its value at a convenient location after applicable +arithmetic. +. +. +.br +.ne 5v +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-\-help +displays a usage message, +while +.B \-v +and +.B \-\-version +show version information; +all exit afterward. +. +. +.TP +.B \-C +Enable AT&T compatibility mode: +recognize +.B .TS +and +.B .TE +even when followed by a character other than space or newline. +. +Furthermore, +interpret the uninterpreted leader escape sequence +.BR \[rs]a . +. +. +.\" ==================================================================== +.SH Limitations +.\" ==================================================================== +. +Multi-page tables, +if boxed and/or if you want their column headings repeated after page +breaks, +require support at the time the document is formatted. +. +A convention for such support has arisen in macro packages such as +.IR ms , +.IR mm , +and +.IR me . +. +To use it, +follow the +.B .TS +token with a space and then +.RB \[lq] H \[rq]; +this will be interpreted by the formatter +as a +.B TS +macro call with an +.B H +argument. +. +Then, +within the table data, +call the +.B TH +macro; +this informs the macro package where the headings end. +. +If your table has no such heading rows, +or you do not desire their repetition, +call +.B TH +immediately after the table format specification. +. +If a multi-page table is boxed or has repeating column headings, +do not enclose it with keep/release macros, +or divert it in any other way. +. +Further, +the +.B bp +request will not cause a page break in a +.RB \[lq] "TS H" \[rq] +table. +. +Define a macro to wrap +.BR bp : +invoke it normally if there is no current diversion. +. +Otherwise, +pass the macro call to the enclosing diversion using the transparent +line escape sequence +.BR \[rs]!\& ; +this will \[lq]bubble up\[rq] the page break to the output device. +. +See section \[lq]Examples\[rq] below for a demonstration. +. +. +.P +Double horizontal rules are not supported by +.MR grotty @MAN1EXT@ ; +single rules are used instead. +. +.I \%grotty +also ignores half-line motions, +so the +.B u +column modifier has no effect. +. +On terminal devices +.RI (\[lq] nroff\~ mode\[rq]), +horizontal rules and box borders occupy a full vee of space; +this amount is doubled for +.B doublebox +tables. +. +Tables using these features thus require more vertical space in +.I nroff +mode than in +.I troff +mode: +write +.B ne +requests accordingly. +. +Vertical rules between columns are drawn in the space between columns in +.I nroff +mode; +using double vertical rules and/or reducing the column separation below +the default can make them ugly or overstrike them with table data. +. +. +.P +A text block within a table must be able to fit on one page. +. +. +.P +Using +.B \[rs]a +to put leaders in table entries does not work +in GNU +.IR tbl , \" GNU +except in compatibility mode. +. +This is correct behavior: +.B \[rs]a +is an +.I uninterpreted +leader. +. +You can still use the +.I roff +leader character (Control+A) or define a string to use +.B \[rs]a +as it was designed: +to be interpreted only in copy mode. +. +. +.RS +.P +.EX +\&.ds a \[rs]a +\&.TS +\&box center tab(;); +\&Lw(2i)0 L. +\&Population\[rs]*a;6,327,119 +\&.TE +.EE +.RE +. +. +.\" We use a real leader to avoid defining a string in a man page. +.P +.TS +box center tab(;); +Lw(2i)0 L. +Population;6,327,119 +.TE +. +. +.P +A leading and/or trailing +.B | +in a format specification, +such as +.RB \[lq] |LCR|.\& \[rq], +produces an en space between the vertical rules and the content of the +adjacent columns. +. +If no such space is desired +(so that the rule abuts the content), +you can introduce \[lq]dummy\[rq] columns with zero separation and empty +corresponding table entries before and/or after. +. +. +.RS +.P +.EX +\&.TS +\¢er tab(#); +\&R0|L C R0|L. +_ +\&#levulose#glucose#dextrose# +_ +\&.TE +.EE +.RE +. +. +.P +These dummy columns have zero width and are therefore invisible; +unfortunately they usually don't work as intended on terminal devices. +. +. +.if t \{\ +.TS +center tab(#); +R0|L C R0|L. +_ +#levulose#glucose#dextrose# +_ +.TE +.\} +. +. +.\" ==================================================================== +.SH Examples +.\" ==================================================================== +. +It can be easier to acquire the language of +.I tbl \" generic +through examples than formal description, +especially at first. +. +. +.\" Note: This example is nearly at the column limit (78n) for nroff +.\" output. Recast with care. +.RS +.P +.EX +\&.TS +box center tab(#); +Cb Cb +L L. +Ability#Application +Strength#crushes a tomato +Dexterity#dodges a thrown tomato +Constitution#eats a month-old tomato without becoming ill +Intelligence#knows that a tomato is a fruit +Wisdom#chooses \[rs]f[I]not\[rs]f[] to put tomato in a fruit salad +Charisma#sells obligate carnivores tomato-based fruit salads +\&.TE +.EE +.RE +. +. +.P +.TS +box center tab(#); +Cb Cb +L L. +Ability#Application +Strength#crushes a tomato +Dexterity#dodges a thrown tomato +Constitution#eats a month-old tomato without becoming ill +Intelligence#knows that a tomato is a fruit +Wisdom#chooses \f[I]not\f[] to put tomato in a fruit salad +Charisma#sells obligate carnivores tomato-based fruit salads +.TE +. +. +.P +The +.B A +and +.B N +column classifiers can be easier to grasp in visual rendering than in +description. +. +. +.RS +.P +.EX +\&.TS +center tab(;); +CbS,LN,AN. +Daily energy intake (in MJ) +Macronutrients +\&.\[rs]" assume 3 significant figures of precision +Carbohydrates;4.5 +Fats;2.25 +Protein;3 +\&.T& +LN,AN. +Mineral +Pu\-239;14.6 +_ +\&.T& +LN. +Total;\[rs][ti]24.4 +\&.TE +.EE +.RE +. +. +.RS +.P +.TS +center tab(;); +CbS,LN,AN. +Daily energy intake (in MJ) +.\" assume 3 significant figures of precision +Macronutrients +Carbohydrates;4.5 +Fats;2.25 +Protein;3 +.T& +LN,AN. +Mineral +Pu-239;14.6 +_ +.T& +LN. +Total;\[ti]24.4 +.TE +.RE +. +. +.br +.ne 12v +.P +Next, +we'll lightly adapt a compact presentation of spanning, +vertical alignment, +and zero-width column modifiers from the +.I mandoc +reference for its +.I tbl \" generic +interpreter. +. +It rewards close study. +. +. +.RS +.P +.EX +\&.TS +box center tab(:); +Lz S | Rt +Ld| Cb| \[ha] +\[ha] | Rz S. +left:r +l:center: +:right +\&.TE +.EE +.RE +. +. +.RS +.P +.TS +box center tab(:); +Lz S | Rt +Ld| Cb| ^ +^ | Rz S. +left:r +l:center: +:right +.TE +.RE +. +. +.P +.ne 2v +Row staggering is not visually achievable on terminal devices, +but a table using it can remain comprehensible nonetheless. +. +. +.RS +.P +.EX +\&.TS +center tab(|); +Cf(BI) Cf(BI) Cf(B), C C Cu. +n|n\[rs]f[B]\[rs][tmu]\[rs]f[]n|difference +1|1 +2|4|3 +3|9|5 +4|16|7 +5|25|9 +6|36|11 +\&.TE +.EE +.RE +. +. +.RS +.P +.TS +center tab(|); +Cf(BI) Cf(BI) Cf(B), C C Cu. +n|n\f[B]\[tmu]\f[]n|difference +1|1 +2|4|3 +3|9|5 +4|16|7 +5|25|9 +6|36|11 +.TE +.RE +. +. +.P +Some +.I @g@tbl +features cannot be illustrated in the limited environment of a portable +man page. +. +. +.\" TODO: Find a better example than this. +.\".P +.\"As noted above, +.\"we can embed a table region in a +.\".I groff +.\"macro definition. +.\". +.\".IR @g@tbl , +.\"however, +.\"cannot know what will result from any macro argument interpolations, +.\"so we might confine such interpolations to one column of the table and +.\"apply the +.\".B x +.\"modifier to it. +.\". +.\". +.\".RS +.\".P +.\".EX +.\"\&.de END +.\"\&.. +.\"\&.eo +.\"\&.de MYTABLE END +.\"\&.TS +.\"\&allbox tab(;); +.\"\&C Lx. +.\"\&This is table \[rs]$1.;\[rs]$2 +.\"\&.TE +.\"\&.END +.\"\&.ec +.\"\&.MYTABLE 1 alpha +.\"\&.MYTABLE 2 beta +.\"\&.MYTABLE 3 "gamma delta" +.\".EE +.\".RE +.\" +.\" +.P +We can define a macro outside of a +.I tbl \" generic +region that we can call from within it to cause a page break inside a +multi-page boxed table. +. +You can choose a different name; +be sure to change both occurrences of \[lq]BP\[rq]. +. +. +.RS +.P +.ne 4v +.EX +\&.de BP +\&.\& ie \[aq]\[rs]\[rs]n(.z\[aq]\[aq] \&.bp \[rs]\[rs]$1 +\&.\& el \[rs]!.BP \[rs]\[rs]$1 +\&.. +.EE +.RE +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +\[lq]Tbl\[em]A Program to Format Tables\[rq], +by M.\& E.\& Lesk, +1976 +(revised 16 January 1979), +AT&T Bell Laboratories Computing Science Technical Report No.\& 49. +. +. +.P +The spanning example above was taken from +.UR https://man.openbsd.org/tbl.7 +.IR mandoc 's +man page for its +.I tbl \" mandoc +implementation +.UE . +. +. +.P +.MR groff @MAN1EXT@ , +.MR @g@troff @MAN1EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_tbl_1_man_C] +.do rr *groff_tbl_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/preproc/tbl/tbl.am b/src/preproc/tbl/tbl.am new file mode 100644 index 0000000..d4b0edb --- /dev/null +++ b/src/preproc/tbl/tbl.am @@ -0,0 +1,54 @@ +# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# +# This file 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 . + +prefixexecbin_PROGRAMS += tbl +tbl_LDADD = libgroff.a $(LIBM) lib/libgnu.a +tbl_SOURCES = \ + src/preproc/tbl/main.cpp \ + src/preproc/tbl/table.cpp \ + src/preproc/tbl/table.h +PREFIXMAN1 += src/preproc/tbl/tbl.1 +EXTRA_DIST += src/preproc/tbl/tbl.1.man + +tbl_TESTS = \ + src/preproc/tbl/tests/boxes-and-vertical-rules.sh \ + src/preproc/tbl/tests/check-horizontal-line-length.sh \ + src/preproc/tbl/tests/check-line-intersections.sh \ + src/preproc/tbl/tests/check-vertical-line-length.sh \ + src/preproc/tbl/tests/cooperate-with-nm-request.sh \ + src/preproc/tbl/tests/count-continued-input-lines.sh \ + src/preproc/tbl/tests/do-not-overdraw-page-top-in-nroff-mode.sh \ + src/preproc/tbl/tests/do-not-overlap-bottom-border-in-nroff.sh \ + src/preproc/tbl/tests/do-not-segv-on-invalid-vertical-span-entry.sh \ + src/preproc/tbl/tests/do-not-segv-when-backslash-R-in-text-block.sh \ + src/preproc/tbl/tests/expand-region-option-works.sh \ + src/preproc/tbl/tests/format-time-diagnostics-work.sh \ + src/preproc/tbl/tests/save-and-restore-hyphenation-parameters.sh \ + src/preproc/tbl/tests/save-and-restore-inter-sentence-space.sh \ + src/preproc/tbl/tests/save-and-restore-line-numbering.sh \ + src/preproc/tbl/tests/save-and-restore-tab-stops.sh \ + src/preproc/tbl/tests/warn-on-long-boxed-unkept-table.sh \ + src/preproc/tbl/tests/x-column-modifier-works.sh +TESTS += $(tbl_TESTS) +EXTRA_DIST += $(tbl_TESTS) + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/preproc/tbl/tests/boxes-and-vertical-rules.sh b/src/preproc/tbl/tests/boxes-and-vertical-rules.sh new file mode 100755 index 0000000..0471188 --- /dev/null +++ b/src/preproc/tbl/tests/boxes-and-vertical-rules.sh @@ -0,0 +1,174 @@ +#!/bin/sh +# +# Copyright (C) 2023 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +fail= + +wail () { + echo ...FAILED >&2 + fail=YES +} + +# Test behavior of unexpanded tables using boxes and/or vertical rules. + +# Case 1: "naked" table + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +tab(@); +L L L L L. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking unboxed table without vertical rules" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +# 3 spaces between table entries +echo "$output" | sed -n '2p' \ + | grep -qx 'abcdef abcdef abcdef abcdef abcdef' || wail + +# Case 2: left-hand vertical rule + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +tab(@); +| L L L L L. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking unboxed table with left-hand rule" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +# 3 spaces between table entries +echo "$output" | sed -n '3p' \ + | grep -qx '| abcdef abcdef abcdef abcdef abcdef' || wail + +# Case 3: right-hand vertical rule + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +tab(@); +L L L L L |. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking unboxed table with right-hand rule" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +# 3 spaces between table entries +echo "$output" | sed -n '3p' \ + | grep -qx 'abcdef abcdef abcdef abcdef abcdef |' || wail + +# Case 4: vertical rule on both ends + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +tab(@); +| L L L L L |. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking unboxed table with both rules" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +# 3 spaces between table entries +echo "$output" | sed -n '3p' \ + | grep -qx '| abcdef abcdef abcdef abcdef abcdef |' || wail + +# Case 5: vertical rule on both ends and interior rule + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +tab(@); +| L L L | L L |. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking unboxed table with both edge and interior rules" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +# 3 spaces between table entries +echo "$output" | sed -n '3p' \ + | grep -qx '| abcdef abcdef abcdef | abcdef abcdef |' || wail + +# Case 6: boxed table + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +box tab(@); +L L L L L. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking boxed table without interior rules" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +# 3 spaces between table entries +echo "$output" | sed -n '3p' \ + | grep -qx '| abcdef abcdef abcdef abcdef abcdef |' || wail + +# Case 7: boxed table with interior vertical rule + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +box tab(@); +L L L | L L. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking boxed table with interior rules" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +# 3 spaces between table entries +echo "$output" | sed -n '3p' \ + | grep -qx '| abcdef abcdef abcdef | abcdef abcdef |' || wail + +test -z "$fail" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/preproc/tbl/tests/check-horizontal-line-length.sh b/src/preproc/tbl/tests/check-horizontal-line-length.sh new file mode 100755 index 0000000..3d5e2a2 --- /dev/null +++ b/src/preproc/tbl/tests/check-horizontal-line-length.sh @@ -0,0 +1,78 @@ +#!/bin/sh +# +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" +fail= + +wail () { + echo "...FAILED" >&2 + echo "$output" + fail=yes +} + +# GNU tbl draws horizontal lines 1n wider than they need to be on nroff +# devices to enable them to cross a vertical line on the right-hand +# side. + +input='.ll 10n +.TS +L. +_ +1234567890 +.TE +.pl \n(nlu +' + +echo "checking length of plain horizontal rule" >&2 +output=$(printf "%s" "$input" | "$groff" -Tascii -t) +echo "$output" | grep -Eqx -- '-{11}' || wail + +input='.ll 12n +.TS +| L |. +_ +1234567890 +_ +.TE +.pl \n(nlu +' + +echo "checking intersection of vertical and horizontal rules" >&2 +output=$(printf "%s" "$input" | "$groff" -Tascii -t) +echo "$output" | sed -n '1p' | grep -Eqx '\+-{12}\+' || wail +echo "$output" | sed -n '3p' | grep -Eqx '\+-{12}\+' || wail + +input='.ll 12n +.TS +box; +L. +1234567890 +.TE +.pl \n(nlu +' + +echo "checking width of boxed table" >&2 +output=$(printf "%s" "$input" | "$groff" -Tascii -t) +echo "$output" | sed -n '1p' | grep -Eqx '\+-{12}\+' || wail +echo "$output" | sed -n '3p' | grep -Eqx '\+-{12}\+' || wail + +test -z "$fail" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/preproc/tbl/tests/check-line-intersections.sh b/src/preproc/tbl/tests/check-line-intersections.sh new file mode 100755 index 0000000..2012beb --- /dev/null +++ b/src/preproc/tbl/tests/check-line-intersections.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" +fail= + +wail () { + echo "...FAILED" >&2 + echo "$output" + fail=yes +} + +input='.TS +allbox tab(@); +L L L. +a@b@c +d@e@f +g@h@i +.TE +' + +output=$(printf "%s" "$input" | "$groff" -Tascii -t) +echo "$output" + +for l in 1 3 5 7 +do + echo "checking intersections on line $l" + echo "$output" | sed -n ${l}p | grep -Fqx '+---+---+---+' || wail +done + +# TODO: Check `-Tutf8` output for correct crossing glyph identities. + +test -z "$fail" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/preproc/tbl/tests/check-vertical-line-length.sh b/src/preproc/tbl/tests/check-vertical-line-length.sh new file mode 100755 index 0000000..1aafd09 --- /dev/null +++ b/src/preproc/tbl/tests/check-vertical-line-length.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" +fail= + +wail () { + echo "...FAILED" >&2 + echo "$output" + fail=yes +} + +# GNU tbl draws vertical lines 1v taller than they need to be on nroff +# devices to enable them to cross a potential horizontal line in the +# table. + +input='.ll 12n +.TS +| L |. +_ +1234567890 +.TE +.pl \n(nlu +' + +echo "checking length of plain vertical rule" >&2 +output=$(printf "%s" "$input" | "$groff" -Tascii -t) +echo "$output" | sed -n '2p' | grep -Fqx -- '| 1234567890 |' || wail + +test -z "$fail" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/preproc/tbl/tests/cooperate-with-nm-request.sh b/src/preproc/tbl/tests/cooperate-with-nm-request.sh new file mode 100755 index 0000000..cfbd750 --- /dev/null +++ b/src/preproc/tbl/tests/cooperate-with-nm-request.sh @@ -0,0 +1,47 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +set -e + +# Regression-test Savannah #59812. +# +# A nonzero value of \n[ln] should not cause spurious numbering of table +# rows. + +DOC='\ +.nf +foo +.nm 1 +bar +.nm +baz +.TS +l. +qux +.TE +' + +OUTPUT=$(printf "%s" "$DOC" | "$groff" -Tascii -t) + +echo "$OUTPUT" | grep -Fqx qux + +# vim:set ai noet sw=4 ts=4 tw=72: diff --git a/src/preproc/tbl/tests/count-continued-input-lines.sh b/src/preproc/tbl/tests/count-continued-input-lines.sh new file mode 100755 index 0000000..4682788 --- /dev/null +++ b/src/preproc/tbl/tests/count-continued-input-lines.sh @@ -0,0 +1,43 @@ +#!/bin/sh +# +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +set -e + +# Regression-test Savannah #62191. +# +# Line continuation in a row of table data should not make the input +# line counter inaccurate. + +input='.this-is-line-1 +.TS +L. +foo\ +bar\ +baz\ +qux +.TE +.this-is-line-9' + +output=$(printf "%s\n" "$input" | "$groff" -Tascii -t -ww -z 2>&1) +echo "$output" | grep -q '^troff.*:9:.*this-is-line-9' + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/preproc/tbl/tests/do-not-overdraw-page-top-in-nroff-mode.sh b/src/preproc/tbl/tests/do-not-overdraw-page-top-in-nroff-mode.sh new file mode 100755 index 0000000..c4698f1 --- /dev/null +++ b/src/preproc/tbl/tests/do-not-overdraw-page-top-in-nroff-mode.sh @@ -0,0 +1,225 @@ +#!/bin/sh +# +# Copyright (C) 2022-2023 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" +grotty="${abs_top_builddir:-.}/grotty" + +fail= + +wail () { + echo ...FAILED >&2 + fail=YES +} + +# Regression-test Savannah #63449. +# +# In nroff mode, a table at the top of the page (i.e., one starting at +# the first possible output line, with no vertical margin) that has +# vertical rules should not overdraw the page top and provoke a warning +# from grotty about "character(s) above [the] first line [being] +# discarded". + +# Case 1: No horizontal rules; vertical rule at leading column. +input='.TS +| L. +foo +.TE' + +tmp=$(printf "%s\n" "$input" | "$groff" -t -Z -Tascii -P-cbou) +output=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>/dev/null) +error=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>&1 >/dev/null) +echo "$output" + +echo "checking that no diagnostic messages are produced by grotty (1)" +echo "$error" | grep -q 'grotty:' && wail + +echo "checking that a lone vertical rule starts the first output line" +echo "$output" | sed -n '1p' | grep -Fqx '|' || wail + +# Case 2: No horizontal rules; vertical rule between columns. +input='.TS +tab(@); +L | L. +foo@bar +.TE' + +tmp=$(printf "%s\n" "$input" | "$groff" -t -Z -Tascii -P-cbou) +output=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>/dev/null) +error=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>&1 >/dev/null) +echo "$output" + +echo "checking that no diagnostic messages are produced by grotty (2)" +echo "$error" | grep -q 'grotty:' && wail + +echo "checking that a lone vertical rule ends the first output line" +echo "$output" | sed -n '1p' | grep -Eqx ' +\|' || wail + +# Case 3: No horizontal rules; vertical rule at trailing column. +input='.TS +L |. +foo +.TE' + +tmp=$(printf "%s\n" "$input" | "$groff" -t -Z -Tascii -P-cbou) +output=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>/dev/null) +error=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>&1 >/dev/null) +echo "$output" + +echo "checking that no diagnostic messages are produced by grotty (3)" +echo "$error" | grep -q 'grotty:' && wail + +echo "checking that a lone vertical rule ends the first output line" +echo "$output" | sed -n '1p' | grep -Eqx ' +\|' || wail + +# Case 4: Vertical rule with horizontal rule in row description. +input='.TS +_ +L |. +foo +.TE' + +tmp=$(printf "%s\n" "$input" | "$groff" -t -Z -Tascii -P-cbou) +output=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>/dev/null) +error=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>&1 >/dev/null) +echo "$output" + +echo "checking that no diagnostic messages are produced by grotty (4)" +echo "$error" | grep -q 'grotty:' && wail + +echo "checking that intersection is placed on the first output line" +echo "$output" | sed -n '1p' | grep -q '+' || wail + +# Case 5: Vertical rule with horizontal rule as first table datum. +input='.TS +L |. +_ +foo +.TE' + +tmp=$(printf "%s\n" "$input" | "$groff" -t -Z -Tascii -P-cbou) +output=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>/dev/null) +error=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>&1 >/dev/null) +echo "$output" + +echo "checking that no diagnostic messages are produced by grotty (5)" +echo "$error" | grep -q 'grotty:' && wail + +echo "checking that intersection is placed on the first output line" +echo "$output" | sed -n '1p' | grep -q '+' || wail + +# Case 6: Horizontal rule as non-first row description with vertical +# rule. +input='.TS +L,_,L |. +foo +bar +.TE' + +tmp=$(printf "%s\n" "$input" | "$groff" -t -Z -Tascii -P-cbou) +output=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>/dev/null) +error=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>&1 >/dev/null) +echo "$output" + +echo "checking that no diagnostic messages are produced by grotty (6)" +echo "$error" | grep -q 'grotty:' && wail + +echo "checking that table data begin on first output line" +echo "$output" | sed -n '1p' | grep -q 'foo' || wail + +# Also ensure that no collateral damage arises in related cases. + +# Case 7: Horizontal rule as first table datum with no vertical rule. +input='.TS +L. +_ +foo +.TE' + +tmp=$(printf "%s\n" "$input" | "$groff" -t -Z -Tascii -P-cbou) +output=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>/dev/null) +error=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>&1 >/dev/null) +echo "$output" + +echo "checking that no diagnostic messages are produced by grotty (7)" +echo "$error" | grep -q 'grotty:' && wail + +echo "checking that horizontal rule is placed on the first output line" +echo "$output" | sed -n '1p' | grep -q '^---' || wail + +# Case 8: Horizontal rule as last table datum with no vertical rule. +input='.TS +L. +foo +_ +.TE +.ec @ +.pl @n(nlu' + +tmp=$(printf "%s\n" "$input" | "$groff" -t -Z -Tascii -P-cbou) +output=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>/dev/null) +error=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>&1 >/dev/null) +echo "$output" + +echo "checking that no diagnostic messages are produced by grotty (8)" +echo "$error" | grep -q 'grotty:' && wail + +echo "checking that horizontal rule is placed on the last output line" +echo "$output" | sed -n '$p' | grep -q '^---' || wail + +# Case 9: Horizontal rule in row description with no vertical rule. +input='.TS +_ +L. +foo +.TE' + +tmp=$(printf "%s\n" "$input" | "$groff" -t -Z -Tascii -P-cbou) +output=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>/dev/null) +error=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>&1 >/dev/null) +echo "$output" + +echo "checking that no diagnostic messages are produced by grotty (9)" +echo "$error" | grep -q 'grotty:' && wail + +echo "checking that intersection is placed on the first output line" +echo "$output" | sed -n '1p' | grep -q '^---' || wail + +# Case 10: Horizontal rule as non-first row description with no vertical +# rule. +input='.TS +L,_,L. +foo +bar +.TE' + +tmp=$(printf "%s\n" "$input" | "$groff" -t -Z -Tascii -P-cbou) +output=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>/dev/null) +error=$(printf "%s" "$tmp" | "$grotty" -F ./font 2>&1 >/dev/null) +echo "$output" + +echo "checking that no diagnostic messages are produced by grotty (10)" +echo "$error" | grep -q 'grotty:' && wail + +echo "checking that table data begin on first output line" +echo "$output" | sed -n '1p' | grep -q 'foo' || wail + +test -z "$fail" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/preproc/tbl/tests/do-not-overlap-bottom-border-in-nroff.sh b/src/preproc/tbl/tests/do-not-overlap-bottom-border-in-nroff.sh new file mode 100755 index 0000000..4f63eed --- /dev/null +++ b/src/preproc/tbl/tests/do-not-overlap-bottom-border-in-nroff.sh @@ -0,0 +1,62 @@ +#!/bin/sh +# +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +fail= + +wail () { + echo "...FAILED" >&2 + fail=yes +} + +# Regression-test Savannah #49390. + +input='foo +.TS +box; +L. +bar +.TE +baz +.pl \n(nlu +' + +echo "checking for post-table text non-overlap of (single) box border" +output=$(printf "%s" "$input" | "$groff" -t -Tascii) +echo "$output" | grep -q baz || wail + +input='foo +.TS +doublebox; +L. +bar +.TE +baz +.pl \n(nlu +' + +echo "checking for post-table text non-overlap of double box border" +output=$(printf "%s" "$input" | "$groff" -t -Tascii) +echo "$output" | grep -q baz || wail + +test -z "$fail" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/preproc/tbl/tests/do-not-segv-on-invalid-vertical-span-entry.sh b/src/preproc/tbl/tests/do-not-segv-on-invalid-vertical-span-entry.sh new file mode 100755 index 0000000..1d672ec --- /dev/null +++ b/src/preproc/tbl/tests/do-not-segv-on-invalid-vertical-span-entry.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +tbl="${abs_top_builddir:-.}/tbl" + +# Regression-test Savannah #61417. +# +# Don't segfault because we tried to span down from an invalid span that +# tbl neglected to replace with an empty table entry. + +test -f core && exit 77 # skip + +input=$(cat <. +# + +groff="${abs_top_builddir:-.}/test-groff" + +fail= + +wail () { + echo "...FAILED" >&2 + fail=yes +} + +# Regression-test Savannah #62366. +# +# Do not SEGV when a text block begins with a repeating glyph token, and +# do not malformat the output if it ends with one. + +test -f core && exit 77 # skip + +input='.TS +L. +T{ +\Ra +T} +.TE +.TS +L. +T{ +foo +\Ra +T} +.TE +.TS +L. +T{ +foo +\Ra +bar +T} +.TE' + +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii -P-cbou) + +echo "checking that tbl doesn't segfault" >&2 +test -f core && wail + +echo "checking text block starting with repeating glyph" >&2 +echo "$output" | sed -n 1p | grep -qx 'a' || wail + +echo "checking text block ending with repeating glyph" >&2 +echo "$output" | sed -n 2p | grep -qx 'foo a' || wail + +echo "checking text block containing repeating glyph" >&2 +echo "$output" | sed -n 3p | grep -qx 'foo a bar' || wail + +test -z "$fail" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/preproc/tbl/tests/expand-region-option-works.sh b/src/preproc/tbl/tests/expand-region-option-works.sh new file mode 100755 index 0000000..97da39d --- /dev/null +++ b/src/preproc/tbl/tests/expand-region-option-works.sh @@ -0,0 +1,173 @@ +#!/bin/sh +# +# Copyright (C) 2023 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +fail= + +wail () { + echo ...FAILED >&2 + fail=YES +} + +# Ensure that the "expand" region option expands to the line length. + +# Case 1: "naked" table + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +expand tab(@); +L L L L L. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking unboxed table without vertical rules" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +echo "$output" | sed -n '2p' \ + | grep -Eqx '(abcdef {8,9}){4}abcdef' || wail + +# Case 2: left-hand vertical rule + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +expand tab(@); +| L L L L L. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking unboxed table with left-hand rule" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +echo "$output" | sed -n '3p' \ + | grep -Eqx '\| abcdef {8}abcdef {7}abcdef {8}abcdef {9}abcdef' \ + || wail + +# Case 3: right-hand vertical rule + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +expand tab(@); +L L L L L |. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking unboxed table with right-hand rule" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +echo "$output" | sed -n '3p' \ + | grep -Eqx 'abcdef {8}abcdef {7}abcdef {8}abcdef {9}abcdef \|' \ + || wail + +# Case 4: vertical rule on both ends + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +expand tab(@); +| L L L L L |. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking unboxed table with both rules" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +echo "$output" | sed -n '3p' \ + | grep -Eqx '\| abcdef {7}abcdef {7}abcdef {8}abcdef {8}abcdef \|' \ + || wail + +# Case 5: vertical rule on both ends and interior rule + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +expand tab(@); +| L L L | L L |. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking unboxed table with both edge and interior rules" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +echo "$output" | sed -n '3p' \ + | grep -Eqx \ + '\| abcdef {7}abcdef {7}abcdef {4}\| {3}abcdef {8}abcdef \|' || wail + +# Case 6: boxed table + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +box expand tab(@); +L L L L L. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking boxed table without interior rules" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +echo "$output" | sed -n '3p' \ + | grep -Eqx '\| abcdef {7}abcdef {7}abcdef {8}abcdef {8}abcdef \|' \ + || wail + +# Case 7: boxed table with interior vertical rule + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +box expand tab(@); +L L L | L L. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking boxed table with interior rule" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +echo "$output" | sed -n '3p' \ + | grep -Eqx \ + '\| abcdef {7}abcdef {7}abcdef {4}\| {3}abcdef {8}abcdef \|' || wail + +test -z "$fail" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/preproc/tbl/tests/format-time-diagnostics-work.sh b/src/preproc/tbl/tests/format-time-diagnostics-work.sh new file mode 100755 index 0000000..9d422bd --- /dev/null +++ b/src/preproc/tbl/tests/format-time-diagnostics-work.sh @@ -0,0 +1,268 @@ +#!/bin/sh +# +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +set -e + +# Ensure we get diagnostics when we expect to, and not when we don't. +# +# Do NOT pattern-match the text of the diagnostic messages; those should +# be left flexible. (Some day they might even be localized.) + +# As of this writing, there are 5 distinct format-time diagnostic +# messages that tbl writes roff code to generate, one of which can be +# produced two different ways. + +# Diagnostic #1: a row overruns the page bottom +input='.pl 2v +.TS +; +L. +T{ +.nf +1 +2 +3 +T} +.TE +' + +echo "checking for diagnostic when row with text box overruns page" \ + "bottom" +output=$(printf "%s" "$input" | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 1 + +echo "checking 'nowarn' suppression of diagnostic when row with text" \ + "box overruns page bottom" +input_nowarn=$(printf "%s" "$input" | sed 's/;/nowarn;/') +output=$(printf "%s" "$input_nowarn" \ + | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 0 + +echo "checking 'nokeep' suppression of diagnostic when row with text" \ + "box overruns page bottom" +input_nowarn=$(printf "%s" "$input" | sed 's/;/nokeep;/') +output=$(printf "%s" "$input_nowarn" \ + | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 0 + +# The other way to get "diagnostic #1" is to have a row that is too +# tall _without_ involving a text block, for instance by having a font +# or vertical spacing that is too high. +input='.pl 2v +.vs 3v +.TS +; +L. +1 +.TE +' + +echo "checking for diagnostic when row with large vertical spacing" \ + "overruns page bottom" +output=$(printf "%s" "$input" | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 1 + +echo "checking 'nowarn' suppression of diagnostic when row with large" \ + "vertical spacing overruns page bottom" +input_nowarn=$(printf "%s" "$input" | sed 's/;/nowarn;/') +output=$(printf "%s" "$input_nowarn" \ + | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 0 + +echo "checking 'nokeep' suppression of diagnostic when row with large" \ + "vertical spacing overruns page bottom" +input_nowarn=$(printf "%s" "$input" | sed 's/;/nokeep;/') +output=$(printf "%s" "$input_nowarn" \ + | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 0 + +# Diagnostic #2: a boxed table won't fit on a page + +input='.pl 2v +.vs 3v +.TS +box; +L. +1 +.TE +' + +echo "checking for diagnostic when boxed table won't fit on page" +output=$(printf "%s" "$input" | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 1 + +# The above is an error, so the "nowarn" region option won't shut it up. +# +# However, "nokeep" does--but arguably shouldn't. See +# . If that gets fixed, we should +# test that we still get a diagnostic even with the option given. + +# Diagnostic #3: unexpanded columns overrun the line length +# +# Case 1: no 'x' column modifiers used + +input='.pl 2v +.ll 10n +.TS +; +L. +12345678901 +.TE +' + +echo "checking for diagnostic when unexpanded columns overrun line" \ + "length (1)" +output=$(printf "%s" "$input" | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 1 + +echo "checking 'nowarn' suppression of diagnostic when unexpanded" \ + "columns overrun line length (1)" +input_nowarn=$(printf "%s" "$input" | sed 's/;/nowarn;/') +output=$(printf "%s" "$input_nowarn" \ + | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 0 + +# Avoiding keeps won't get you out of this one. +echo "checking 'nokeep' NON-suppression of diagnostic when unexpanded" \ + "columns overrun line length (1)" +input_nowarn=$(printf "%s" "$input" | sed 's/;/nokeep;/') +output=$(printf "%s" "$input_nowarn" \ + | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 1 + +# Case 2: 'x' column modifier used +# +# This worked as a "get out of jail (warning) free" card in groff 1.22.4 +# and earlier; i.e., it incorrectly suppressed the warning. See +# Savannah #61854. + +input='.pl 2v +.ll 10n +.TS +; +Lx. +12345678901 +.TE +' + +echo "checking for diagnostic when unexpanded columns overrun line" \ + "length (2)" +output=$(printf "%s" "$input" | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 1 + +echo "checking 'nowarn' suppression of diagnostic when unexpanded" \ + "columns overrun line length (2)" +input_nowarn=$(printf "%s" "$input" | sed 's/;/nowarn;/') +output=$(printf "%s" "$input_nowarn" \ + | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 0 + +# Avoiding keeps won't get you out of this one. +echo "checking 'nokeep' NON-suppression of diagnostic when unexpanded" \ + "columns overrun line length (2)" +input_nowarn=$(printf "%s" "$input" | sed 's/;/nokeep;/') +output=$(printf "%s" "$input_nowarn" \ + | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 1 + +# Diagnostic #4: expanded table gets all column separation squashed out + +input='.pl 3v +.ll 10n +.TS +tab(;) expand; +L L. +abcde;fghij +.TE +' + +echo "checking for diagnostic when region-expanded table has column" \ + "separation eliminated" +output=$(printf "%s" "$input" | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 1 + +echo "checking 'nowarn' suppression of diagnostic when" \ + "region-expanded table has column separation eliminated" +input_nowarn=$(printf "%s" "$input" | sed 's/;$/ nowarn;/') +output=$(printf "%s" "$input_nowarn" \ + | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 0 + +# Avoiding keeps won't get you out of this one. +echo "checking 'nokeep' NON-suppression of diagnostic when" \ + "region-expanded table has column separation eliminated" +input_nowarn=$(printf "%s" "$input" | sed 's/;$/ nokeep;/') +output=$(printf "%s" "$input_nowarn" \ + | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 1 + +# Diagnostic #5: expanded table gets column separation reduced + +input='.pl 3v +.ll 10n +.TS +tab(;) expand; +L L. +abcd;efgh +.TE +' + +echo "checking for diagnostic when region-expanded table has column" \ + "separation reduced" +output=$(printf "%s" "$input" | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 1 + +echo "checking 'nowarn' suppression of diagnostic when" \ + "region-expanded table has column separation reduced" +input_nowarn=$(printf "%s" "$input" | sed 's/;$/ nowarn;/') +output=$(printf "%s" "$input_nowarn" \ + | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 0 + +# Avoiding keeps won't get you out of this one. +echo "checking 'nokeep' NON-suppression of diagnostic when" \ + "region-expanded table has column separation reduced" +input_nowarn=$(printf "%s" "$input" | sed 's/;$/ nokeep;/') +output=$(printf "%s" "$input_nowarn" \ + | "$groff" -Tascii -t 2>&1 >/dev/null) +nlines=$(echo "$output" | grep . | wc -l) +test $nlines -eq 1 + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/preproc/tbl/tests/save-and-restore-hyphenation-parameters.sh b/src/preproc/tbl/tests/save-and-restore-hyphenation-parameters.sh new file mode 100755 index 0000000..e368b31 --- /dev/null +++ b/src/preproc/tbl/tests/save-and-restore-hyphenation-parameters.sh @@ -0,0 +1,58 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +set -e + +# Regression-test Savannah #59971. +# +# Hyphenation needs to be restored between (and after) text blocks just +# as adjustment is. + +EXAMPLE='.nr LL 78n +.hw a-bc-def-ghij-klmno-pqrstu-vwxyz +.LP +Here is a table with hyphenation disabled in its text block. +. +.TS +l lx. +foo T{ +.nh +abcdefghijklmnopqrstuvwxyz +abcdefghijklmnopqrstuvwxyz +abcdefghijklmnopqrstuvwxyz +T} +.TE +. +Let us see if hyphenation is enabled again as it should be. +abcdefghijklmnopqrstuvwxyz' + +OUTPUT=$(printf "%s\n" "$EXAMPLE" | "$groff" -Tascii -P-cbou -t -ms) + +echo "$OUTPUT" + +echo "testing whether hyphenation disabled in table text block" >&2 +! echo "$OUTPUT" | grep '^foo' | grep -- '-$' + +echo "testing whether hyphenation enabled after table" >&2 +echo "$OUTPUT" | grep -qx 'Let us see.*lmno-' + +# vim:set ai noet sw=4 ts=4 tw=72: diff --git a/src/preproc/tbl/tests/save-and-restore-inter-sentence-space.sh b/src/preproc/tbl/tests/save-and-restore-inter-sentence-space.sh new file mode 100755 index 0000000..e9a06d8 --- /dev/null +++ b/src/preproc/tbl/tests/save-and-restore-inter-sentence-space.sh @@ -0,0 +1,79 @@ +#!/bin/sh +# +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +fail= + +wail () { + echo ...FAILED >&2 + fail=YES +} + +# Regression-test Savannah #61909. +# +# Inter-sentence space should not be applied to the content of ordinary +# table entries. They are set "rigidly" (tbl(1)), also without filling, +# adjustment, hyphenation or breaking. If you want those things, use a +# text block. + +input='.ss 12 120 +Before one. +Before two. +.TS +L. +.\" two spaces +Foo. Bar. +.\" four spaces +Baz. Qux. +.\" two spaces +T{ +Ack. Nak. +T} +.TE +After one. +After two. +' + +output=$(printf "%s\n" "$input" | "$groff" -Tascii -P-cbou -t) +echo "$output" + +echo "checking that inter-sentence space is altered too early" +echo "$output" \ + | grep -Fqx 'Before one. Before two.' || wail # 11 spaces + +echo "checking that inter-sentence space is not applied to ordinary" \ + "table entries (1)" +echo "$output" | grep -Fqx 'Foo. Bar.' || wail # 2 spaces + +echo "checking that inter-sentence space is not applied to ordinary" \ + "table entries (2)" +echo "$output" | grep -Fqx 'Baz. Qux.' || wail # 4 spaces + +echo "checking that inter-sentence space is applied to text blocks" +echo "$output" | grep -Fqx 'Ack. Nak.' || wail # 11 spaces + +echo "checking that inter-sentence space is restored after table" +echo "$output" \ + | grep -Fqx 'After one. After two.' || wail # 11 spaces + +test -z "$fail" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/preproc/tbl/tests/save-and-restore-line-numbering.sh b/src/preproc/tbl/tests/save-and-restore-line-numbering.sh new file mode 100755 index 0000000..592b43a --- /dev/null +++ b/src/preproc/tbl/tests/save-and-restore-line-numbering.sh @@ -0,0 +1,85 @@ +#!/bin/sh +# +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +fail= + +wail () { + echo ...FAILED >&2 + fail=YES +} + +# Regression-test Savannah #60140. +# +# Line numbering needs to be suspended within a table and restored +# afterward. Historical implementations handled line numbering in +# tables badly when text blocks were used. + +input='.nm 1 +Here is a line of output. +Sic transit adispicing meatballs. +We pad it out with more content to ensure that the line breaks. +.TS +L. +This is my table. +There are many like it but this one is mine. +T{ +Ut enim ad minima veniam, +quis nostrum exercitationem ullam corporis suscipitlaboriosam, +nisi ut aliquid ex ea commodi consequatur? +T} +.TE +What is the line number now?' + +output=$(printf "%s\n" "$input" | "$groff" -Tascii -P-cbou -t) +echo "$output" + +echo "testing that line numbering is suppressed in table" >&2 +echo "$output" | grep -Fqx 'This is my table.' || wail + +echo "testing that line numbering is restored after table" >&2 +echo "$output" | grep -Eq '3 +What is the line number now\?' || wail + +input='.nf +.nm 1 +test of line numbering suppression +five +four +.nn 3 +three +.TS +L. +I am a table. +I have two rows. +.TE +two +one +numbering returns here' + +output=$(printf "%s\n" "$input" | "$groff" -Tascii -P-cbou -t) +echo "$output" + +echo "testing that suppressed numbering is restored correctly" >&2 +echo "$output" | grep -Eq '4 +numbering returns here' || wail + +test -z "$fail" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/preproc/tbl/tests/save-and-restore-tab-stops.sh b/src/preproc/tbl/tests/save-and-restore-tab-stops.sh new file mode 100755 index 0000000..b98922a --- /dev/null +++ b/src/preproc/tbl/tests/save-and-restore-tab-stops.sh @@ -0,0 +1,84 @@ +#!/bin/sh +# +# Copyright (C) 2020 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +# Regression-test Savannah #42978. +# +# When tbl changes the tab stops, it needs to restore them. +# +# Based on an example by Bjarni Igni Gislason. + +EXAMPLE='.TH tbl\-tabs\-test 1 2020-10-20 "groff test suite" +.SH Name +tbl\-tabs\-test \- see if tbl messes up the tab stops +.SH Description +Do not use tabs in man pages outside of +.BR .TS / .TE +regions. +.PP +But if you do.\|.\|. +.PP +.TS +l l l. +table entries long enough to change the tab stops +.TE +.PP +.EX +#!/bin/sh +case $# +1) + if foo + then + bar + else + if baz + then + qux + fi + fi +;; +esac +.EE' + +OUTPUT=$(printf "%s\n" "$EXAMPLE" | "$groff" -Tascii -P-cbou -t -man) +FAIL= + +if ! echo "$OUTPUT" | grep -Eq '^ {12}if foo$' +then + FAIL=yes + echo "first tab stop is wrong" >&2 +fi + +if ! echo "$OUTPUT" | grep -Eq '^ {17}bar$' +then + FAIL=yes + echo "second tab stop is wrong" >&2 +fi + +if ! echo "$OUTPUT" | grep -Eq '^ {22}qux$' +then + FAIL=yes + echo "third tab stop is wrong" >&2 +fi + +test -z "$FAIL" + +# vim:set ai noet sw=4 ts=4 tw=72: diff --git a/src/preproc/tbl/tests/warn-on-long-boxed-unkept-table.sh b/src/preproc/tbl/tests/warn-on-long-boxed-unkept-table.sh new file mode 100755 index 0000000..621a752 --- /dev/null +++ b/src/preproc/tbl/tests/warn-on-long-boxed-unkept-table.sh @@ -0,0 +1,56 @@ +#!/bin/sh +# +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +fail= + +wail () { + echo ...FAILED >&2 + fail=YES +} + +# Regression-test Savannah #61878. +# +# A boxed, unkept table that overruns the page bottom will produce ugly +# output; it looks especially bizarre in nroff mode. +# +# We set the page length to 2v to force a problem (any boxed table in +# nroff mode needs 3 vees minimum), and put a page break at the start to +# catch an incorrectly initialized starting page number for the table. + +input='.pl 2v +.bp +.TS +box nokeep; +L. +Z +.TE' + +output=$(printf "%s" "$input" | "$groff" -t -Tascii 2>/dev/null) +error=$(printf "%s" "$input" | "$groff" -t -Tascii 2>&1 >/dev/null) +echo "$output" + +echo "checking that a diagnostic message is produced" +echo "$error" | grep -q 'warning: boxed.*page 2$' || wail + +test -z "$fail" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/preproc/tbl/tests/x-column-modifier-works.sh b/src/preproc/tbl/tests/x-column-modifier-works.sh new file mode 100755 index 0000000..da9b890 --- /dev/null +++ b/src/preproc/tbl/tests/x-column-modifier-works.sh @@ -0,0 +1,172 @@ +#!/bin/sh +# +# Copyright (C) 2023 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +fail= + +wail () { + echo ...FAILED >&2 + fail=YES +} + +# Ensure that the "x" column modifier causes table expansion to the line +# length. + +# Case 1: "naked" table + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +tab(@); +Lx L L L L. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking unboxed table without vertical rules" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +echo "$output" | sed -n '2p' \ + | grep -Eqx 'abcdef {25}(abcdef {3}){3}abcdef' || wail + +# Case 2: left-hand vertical rule + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +tab(@); +| Lx L L L L. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking unboxed table with left-hand rule" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +echo "$output" | sed -n '3p' \ + | grep -Eqx '\| abcdef {23}(abcdef {3}){3}abcdef' || wail + +# Case 3: right-hand vertical rule + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +tab(@); +Lx L L L L |. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking unboxed table with right-hand rule" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +echo "$output" | sed -n '3p' \ + | grep -Eqx 'abcdef {23}(abcdef {3}){3}abcdef \|' || wail + +# Case 4: vertical rule on both ends + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +tab(@); +| Lx L L L L |. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking unboxed table with both rules" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +echo "$output" | sed -n '3p' \ + | grep -Eqx '\| abcdef {21}(abcdef {3}){3}abcdef \|' || wail + +# Case 5: vertical rule on both ends and interior rule + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +tab(@); +| Lx L L | L L |. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking unboxed table with both edge and interior rules" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +echo "$output" | sed -n '3p' \ + | grep -Eqx \ + '\| abcdef {21}abcdef {3}abcdef \| abcdef {3}abcdef \|' \ + || wail + +# Case 6: boxed table + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +box tab(@); +Lx L L L L. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking boxed table without interior rules" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +echo "$output" | sed -n '3p' \ + | grep -Eqx '\| abcdef {21}(abcdef {3}){3}abcdef \|' || wail + +# Case 7: boxed table with interior vertical rule + +input='.ll 64n +.nf +1234567890123456789012345678901234567890123456789012345678901234 +.fi +.TS +box tab(@); +Lx L L | L L. +abcdef@abcdef@abcdef@abcdef@abcdef +.TE +.pl \n(nlu' + +echo "checking boxed table with interior rules" >&2 +output=$(printf "%s\n" "$input" | "$groff" -t -Tascii) +echo "$output" +echo "$output" | sed -n '3p' \ + | grep -Eqx \ + '\| abcdef {21}abcdef {3}abcdef \| abcdef {3}abcdef \|' \ + || wail + +test -z "$fail" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/roff/groff/groff.1.man b/src/roff/groff/groff.1.man new file mode 100644 index 0000000..c551326 --- /dev/null +++ b/src/roff/groff/groff.1.man @@ -0,0 +1,2403 @@ +.TH groff @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +groff \- front end to the GNU +.I roff +document formatting system +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1989-2022 Free Software Foundation, Inc. +.\" +.\" This file is part of groff, the GNU roff type-setting system. +.\" +.\" Permission is granted to copy, distribute and/or modify this +.\" document under the terms of the GNU Free Documentation License, +.\" Version 1.3 or any later version published by the Free Software +.\" Foundation; with no Invariant Sections, with no Front-Cover Texts, +.\" and with no Back-Cover Texts. +.\" +.\" A copy of the Free Documentation License is included as a file +.\" called FDL in the main directory of the groff source package. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_groff_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +.\" Define a string for the TeX logo. +.ie t .ds TeX T\h'-.1667m'\v'.224m'E\v'-.224m'\h'-.125m'X +.el .ds TeX TeX +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY groff +.RB [ \-abcCeEgGijklNpRsStUVXzZ ] +.RB [ \-d\~\c +.IR ctext ] +.RB [ \-d\~\c +.IB string =\c +.IR text ] +.RB [ \-D\~\c +.IR fallback-encoding ] +.RB [ \-f\~\c +.IR font-family ] +.RB [ \-F\~\c +.IR font-directory ] +.RB [ \-I\~\c +.IR inclusion-directory ] +.RB [ \-K\~\c +.IR input-encoding ] +.RB [ \-L\~\c +.IR spooler-argument ] +.RB [ \-m\~\c +.IR macro-package ] +.RB [ \-M\~\c +.IR macro-directory ] +.RB [ \-n\~\c +.IR page-number ] +.RB [ \-o\~\c +.IR page-list ] +.RB [ \-P\~\c +.IR postprocessor-argument ] +.RB [ \-r\~\c +.IR cnumeric-expression ] +.RB [ \-r\~\c +.IB register =\c +.IR numeric-expression ] +.RB [ \-T\~\c +.IR output-device ] +.RB [ \-w\~\c +.IR warning-category ] +.RB [ \-W\~\c +.IR warning-category ] +.RI [ file\~ .\|.\|.] +.YS +. +. +.SY groff +.B \-h +. +.SY groff +.B \-\-help +.YS +. +. +.SY groff +.B \-v +.RI [ option\~ .\|.\|.\&] +.RI [ file\~ .\|.\|.] +. +.SY groff +.B \-\-version +.RI [ option\~ .\|.\|.\&] +.RI [ file\~ .\|.\|.] +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I groff +is the primary front end to the GNU +.I roff +document formatting system. +. +.\" BEGIN Keep parallel with groff.texi node "What Is groff?". +.\" This language is slightly expanded from that in the "ANNOUNCE" file +.\" and on the groff home page. +GNU +.I roff +is a typesetting system that reads plain text input files that include +formatting commands to produce output in PostScript, +PDF, +HTML, +DVI, +or other formats, +or for display to a terminal. +. +Formatting commands can be low-level typesetting primitives, +macros from a supplied package, +or user-defined macros. +. +All three approaches can be combined. +. +If no +.I file +operands are specified, +or if +.I file +is +.RB \[lq] \- \[rq], +.I groff +reads the standard input stream. +. +. +.P +A reimplementation and extension of the typesetter from AT&T Unix, +.I groff +is present on most POSIX systems owing to its long association with Unix +manuals +(including man pages). +. +It and its predecessor are notable for their production of several +best-selling software engineering texts. +. +.I groff +is capable of producing typographically sophisticated documents while +consuming minimal system resources. +.\" END Keep parallel with groff.texi node "What Is groff?". +. +. +.P +The +.I groff +command orchestrates the execution of preprocessors, +the transformation of input documents into a device-independent page +description language, +and the production of output from that language. +. +. +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-h +and +.B \-\-help +display a usage message and exit. +. +. +.P +Because +.I groff +is intended to subsume most users' direct invocations of the +.MR @g@troff @MAN1EXT@ +formatter, +the two programs share a set of options. +. +However, +.I groff +has some options that +.I @g@troff +does not share, +and others which +.I groff +interprets differently. +. +At the same time, +not all valid +.I @g@troff +options can be given to +.IR groff . +. +. +.\" ==================================================================== +.SS "\f[I]groff\f[]-specific options" +.\" ==================================================================== +. +The following options either do not exist in +GNU +.I troff \" GNU +or are interpreted differently by +.IR groff . +. +. +.TP +.BI \-D\~ enc +Set fallback input encoding used by +.MR preconv @MAN1EXT@ +to +.IR enc ; +implies +.BR \-k . +. +. +.TP +.B \-e +Run +.MR @g@eqn @MAN1EXT@ +preprocessor. +. +. +.TP +.B \-g +Run +.MR @g@grn @MAN1EXT@ +preprocessor. +. +. +.TP +.B \-G +Run +.MR grap 1 +preprocessor; +implies +.BR \-p . +. +. +.TP +.BI \-I\~ dir +Works as +.IR @g@troff 's +option +(see below), +but also implies +.B \-g +and +.BR \-s . +. +It is passed to +.MR @g@soelim @MAN1EXT@ +and the output driver, +and +.I @g@grn +is passed an +.B \-M +option with +.I dir +as its argument. +. +. +.TP +.B \-j +Run +.MR @g@chem @MAN1EXT@ +preprocessor; +implies +.BR \-p . +. +. +.TP +.B \-k +Run +.MR preconv @MAN1EXT@ +preprocessor. +. +Refer to its man page for its behavior if neither of +.IR groff 's +.B \-K +or +.B \-D +options is also specified. +. +. +.TP +.BI \-K\~ enc +Set input encoding used by +.MR preconv @MAN1EXT@ +to +.IR enc ; +implies +.BR \-k . +. +. +.TP +.B \-l +Send the output to a spooler program for printing. +. +The +.RB \[lq] print \[rq] +directive in the device description file +specifies the default command to be used; +see +.MR groff_font @MAN5EXT@ . +. +If no such directive is present for the output device, +.ie '@PSPRINT@'' \{\ +this option is ignored. +.\} +.el \{\ +output is piped to +.MR @PSPRINT@ 1 . +.\} +. +See options +.B \-L +and +.BR \-X . +. +. +.TP +.BI \-L\~ arg +Pass +.I arg +to the print spooler program. +. +If multiple +.IR arg s +are required, +pass each with a separate +.B \-L +option. +. +.I groff +does not prefix an option dash to +.I arg +before passing it to the spooler program. +. +. +.TP +.B \-M +Works as +.IR @g@troff 's +option +(see below), +but is also passed to +.MR @g@eqn @MAN1EXT@ , +.MR grap @MAN1EXT@ , +and +.MR @g@grn @MAN1EXT@ . +. +. +.TP +.B \-N +Prohibit newlines between +.I eqn \" language +delimiters: +pass +.B \-N +to +.MR @g@eqn @MAN1EXT@ . +. +. +.TP +.B \-p +Run +.MR @g@pic @MAN1EXT@ +preprocessor. +. +. +.TP +.BI \-P\~ arg +Pass +.I arg +to the postprocessor. +. +If multiple +.IR arg s +are required, +pass each with a separate +.B \-P +option. +. +.I groff +does not prefix an option dash to +.I arg +before passing it to the postprocessor. +. +. +.TP +.B \-R +Run +.MR @g@refer @MAN1EXT@ +preprocessor. +. +No mechanism is provided for passing arguments to +.I @g@refer +because most +.I @g@refer +options have equivalent language elements that can be specified within +the document. +. +. +.TP +.B \-s +Run +.MR @g@soelim @MAN1EXT@ +preprocessor. +. +. +.TP +.B \-S +Operate in \[lq]safer\[rq] mode; +see +.B \-U +below for its opposite. +. +For security reasons, +safer mode is enabled by default. +. +. +.TP +.B \-t +Run +.MR @g@tbl @MAN1EXT@ +preprocessor. +. +. +.TP +.BI \-T\~ dev +Direct +.I @g@troff +to format the input for the output device +.IR dev . +. +.I groff +then calls an output driver to convert +.IR @g@troff 's +output to a form appropriate for +.IR dev ; +see subsection \[lq]Output devices\[rq] below. +. +. +.TP +.B \-U +Operate in unsafe mode: +pass the +.B \-U +option to +.I @g@pic +and +.IR @g@troff . +. +. +.TP +.B \-v +.TQ +.B \-\-version +Write version information for +.I groff +and all programs run by it to the standard output stream; +that is, +the given command line is processed in the usual way, +passing +.B \-v +to the formatter and any pre- or postprocessors invoked. +. +. +.TP +.B \-V +Output the pipeline that +.I groff +would run to the standard output stream, +but do not execute it. +. +If given more than once, +.I groff +both writes and runs the pipeline. +. +. +.TP +.B \-X +Use +.MR gxditview @MAN1EXT@ +instead of the usual postprocessor to (pre)view a document on an X11 +display. +. +Combining this option with +.B \-Tps +uses the font metrics of the PostScript device, +whereas the +.B \-TX75 +and +.B \-TX100 +options use the metrics of X11 fonts. +. +. +.TP +.B \-Z +Disable postprocessing. +. +.I @g@troff +output will appear on the standard output stream +(unless suppressed with +.BR \-z ); +see +.MR groff_out @MAN5EXT@ +for a description of this format. +. +. +.\" ==================================================================== +.SS "Transparent options" +.\" ==================================================================== +. +The following options are passed as-is to the formatter program +.MR @g@troff @MAN1EXT@ +and described in more detail in its man page. +. +. +.TP +.B \-a +Generate a plain text approximation of the typeset output. +. +. +.TP +.B \-b +Write a backtrace to the standard error stream on each error or warning. +. +. +.TP +.B \-c +Start with color output disabled. +. +. +.TP +.B \-C +Enable AT&T +.I troff \" AT&T +compatibility mode; +implies +.BR \-c . +. +. +.TP +.BI \-d\~ cs +.TQ +.BI \-d\~ name = string +Define string. +. +. +.TP +.B \-E +Inhibit +.I @g@troff +error messages; +implies +.BR \-Ww . +. +. +.TP +.BI \-f\~ fam +Set default font family. +. +. +.TP +.BI \-F\~ dir +Search in directory +.I dir +for the selected output device's directory of device and font +description files. +. +. +.TP +.B \-i +Process standard input after the specified input files. +. +. +.TP +.BI \-I\~ dir +Search +.I dir +for input files. +. +. +.TP +.BI \-m\~ name +Process +.RI name .tmac +before input files. +. +. +.TP +.BI \-M\~ dir +Search directory +.I dir +for macro files. +. +. +.TP +.BI \-n\~ num +Number the first page +.IR num . +. +. +.TP +.BI \-o\~ list +Output only pages in +.IR list . +. +. +.TP +.BI \-r\~ cnumeric-expression +.TQ +.BI \-r\~ register = numeric-expression +Define register. +. +. +.TP +.BI \-w\~ name +.TQ +.BI \-W\~ name +Enable +.RB ( \-w ) +or inhibit +.RB ( \-W ) +emission of warnings in category +.IR name . +. +. +.TP +.B \-z +Suppress formatted device-independent output of +.IR @g@troff . +. +. +.\" ==================================================================== +.SH Usage +.\" ==================================================================== +. +The architecture of the GNU +.I roff +system +follows that of other device-independent +.I roff +implementations, +comprising preprocessors, +macro packages, +output drivers +(or \[lq]postprocessors\[rq]), +a suite of utilities, +and the formatter +.I @g@troff +at its heart. +. +See +.MR roff @MAN7EXT@ +for a survey of how a +.I roff +system works. +. +. +.P +The front end programs available in the GNU +.I roff +system make it easier to use than traditional +.IR roff s +that required the construction of pipelines or use of temporary files to +carry a source document from maintainable form to device-ready output. +. +The discussion below summarizes the constituent parts of the GNU +.I roff +system. +. +It complements +.MR roff @MAN7EXT@ +with +.IR groff -specific +information. +. +. +.\" ==================================================================== +.SS "Getting started" +.\" ==================================================================== +. +Those who prefer to learn by experimenting or are desirous of rapid +feedback from the system may wish to start with a \[lq]Hello, +world!\&\[rq] document. +. +. +.P +.EX +$ \c +.B echo \[dq]Hello, world!\[dq] | groff \-Tascii \ +| sed \[aq]/\[ha]$/d\[aq] +Hello, world! +.EE +. +. +.P +We used a +.I sed +command only to eliminate the 65 blank lines that would otherwise flood +the terminal screen. +. +.RI ( roff +systems were developed in the days of paper-based terminals with 66 +lines to a page.) +. +. +.P +Today's users may prefer output to a UTF-8-capable terminal. +. +. +.P +.EX +$ \c +.B echo \[dq]Hello, world!\[dq] | groff \-Tutf8 \ +| sed \[aq]/\[ha]$/d\[aq] +.EE +. +. +.P +Producing PDF, +HTML, +or \*[TeX]'s DVI is also straightforward. +. +The hard part may be selecting a viewer program for the output. +. +. +.P +.EX +$ \c +.B echo \[dq]Hello, world!\[dq] | groff \-Tpdf > hello.pdf +$ \c +.B evince hello.pdf +$ \c +.B echo \[dq]Hello, world!\[dq] | groff \-Thtml > hello.html +$ \c +.B firefox hello.html +$ \c +.B echo \[dq]Hello, world!\[dq] | groff \-Tdvi > hello.dvi +$ \c +.B xdvi hello.html +.EE +. +. +.\" ==================================================================== +.SS "Using \f[I]groff\f[] as a REPL" +.\" ==================================================================== +. +Those with a programmer's bent may be pleased to know that they can use +.I groff +in a read-evaluate-print loop (REPL). +. +Doing so can be handy to verify one's understanding of the formatter's +behavior and/or the syntax it accepts. +. +Turning on all warnings with +.B \-ww +can aid this goal. +. +. +.P +.EX +$ \c +.B groff \-ww \-Tutf8 +.B \[rs]# This is a comment. Let\[aq]s define a register. +.B .nr a 1 +.B \[rs]# Do integer arithmetic with operators evaluated left-to-right. +.B .nr b \[rs]n[a]+5/2 +.ne 2v +.B \[rs]# Let\[aq]s get the result on the standard error stream. +.B .tm \[rs]n[b] +3 +.B \[rs]# Now we\[aq]ll define a string. +.B .ds name Leslie\[rs]" This is another form of comment. +.B .nr b (\[rs]n[a] + (7/2)) +.B \[rs]# Center the next two text input lines. +.B .ce 2 +.B Hi, \[rs]*[name]. +.B Your secret number is \[rs]n[b]. +.B \[rs]# We will see that the division rounded toward zero. +.B It is +.B \[rs]# Here\[aq]s an if-else control structure. +.B .ie (\[rs]n[b] % 2) odd. +.B .el even. +.B \[rs]# This trick sets the page length to the current vertical +.B \[rs]# position, so that blank lines don\[aq]t spew when we\[aq]re \ +done. +.B .pl \[rs]n[nl]u +.I + Hi, Leslie. + Your secret number is 4. +It is even. +.EE +. +. +.\" ==================================================================== +.SS "Paper format" +.\" ==================================================================== +. +In GNU +.IR roff , +the page dimensions for the formatter +.I @g@troff +and for output devices are handled separately. +. +In the formatter, +requests are used to set the page length +.RB ( .pl ), +page offset +(or left margin, +.BR .po ), +and line length +.RB ( .ll ). +. +The right margin is not explicitly configured; +the combination of page offset and line length provides the information +necessary to derive it. +. +The +.I papersize +macro package, +automatically loaded by +.IR @g@troff , +provides an interface for configuring page dimensions by convenient +names, +like \[lq]letter\[rq] or +\[lq]A4\[rq]; +see +.MR groff_tmac @MAN5EXT@ . +. +The formatter's default in this installation is +.RB \[lq] @PAGE@ \[rq]. +. +. +.P +It is up to each macro package to respect the page dimensions configured +in this way. +. +Some offer alternative mechanisms. +. +. +.P +For each output device, +the size of the output medium can be set in its +.I DESC +file. +. +Most output drivers also recognize a command-line option +.B \-p +to override the default dimensions and an option +.B \-l +to use landscape orientation. +. +See +.MR groff_font @MAN5EXT@ +for a description of the +.B papersize +directive, +which takes an argument of the same form as +.BR \-p . +. +The output driver's man page, +such as +.MR grops @MAN1EXT@ , +may also be helpful. +. +.I groff +uses the command-line option +.B \-P +to pass options to output devices; +for example, +use the following for PostScript output on A4 paper in landscape +orientation. +. +. +.IP +.EX +groff \-Tps \-dpaper=a4l \-P\-pa4 \-P\-l \-ms foo.ms > foo.ps +.EE +. +. +.\" ==================================================================== +.SS "Front end" +.\" ==================================================================== +. +The +.I groff +program is a wrapper around the +.MR @g@troff @MAN1EXT@ +program. +. +It allows one to specify preprocessors via command-line options and +automatically runs the appropriate postprocessor for the selected +output device. +. +Doing so, +the manual construction of pipelines or management of temporary files +required of users of traditional +.MR roff @MAN7EXT@ +systems can be avoided. +. +Use the +.MR grog @MAN1EXT@ +program to infer an appropriate +.I groff +command line to format a document. +. +. +.\" ==================================================================== +.SS Language +.\" ==================================================================== +. +Input to a +.I roff +system is in plain text interleaved with control lines and escape +sequences. +. +The combination constitutes a document in one of a family of languages +we also call +.IR roff ; +see +.MR roff @MAN7EXT@ +for background. +. +An overview of GNU +.I roff +language syntax and features, +including lists of all supported escape sequences, +requests, +and predefined registers, +can be found in +.MR groff @MAN7EXT@ . +. +GNU +.I roff +extensions to the AT&T +.I troff +language, +a common subset of +.I roff +dialects extant today, +are detailed in +.MR groff_diff @MAN7EXT@ . +. +. +.\" ==================================================================== +.SS Preprocessors +.\" ==================================================================== +. +A preprocessor interprets a domain-specific language that produces +.I roff +language output. +. +Frequently, +such input is confined to sections or regions of a +.I roff +input file +(bracketed with macro calls specific to each preprocessor), +which it replaces. +. +Preprocessors therefore often interpret a subset of +.I roff +syntax along with their own language. +. +GNU +.I roff +provides reimplementations of most preprocessors familiar to users of +AT&T +.IR troff ; \" AT&T +these routinely have extended features and/or require GNU +.I troff \" GNU +to format their output. +. +. +.br +.ne 10v +.P +.RS +.TS +tab($); +Li Lx. +@g@tbl$lays out tables; +@g@eqn$typesets mathematics; +@g@pic$draws diagrams; +@g@refer$processes bibliographic references; +@g@soelim$preprocesses \[lq]sourced\[rq] input files; +@g@grn$T{ +renders +.MR gremlin 1 +diagrams; +T} +@g@chem$T{ +draws chemical structural formul\[ae] +using +.IR pic ; \" generic +T} +gperl$T{ +populates +.I groff +registers and strings using +.MR perl 1 ; +T} +glilypond$T{ +embeds +.I LilyPond +sheet music; +and +T} +gpinyin$T{ +eases Mandarin Chinese input using Hanyu Pinyin. +T} +.TE +.RE +. +. +.P +A preprocessor unique to GNU +.I roff +is +.MR preconv @MAN1EXT@ , +which converts various input encodings to something GNU +.I troff \" GNU +can understand. +. +When used, +it is run before any other preprocessors. +. +. +.P +Most preprocessors enclose content between a pair of characteristic +tokens. +. +Such a token must occur at the beginning of an input line and use the +dot control character. +. +Spaces and tabs must not follow the control character or precede the +end of the input line. +. +Deviating from these rules defeats a token's recognition by the +preprocessor. +. +Tokens are generally preserved in preprocessor output and interpreted as +macro calls subsequently by +.IR @g@troff . +. +The +.I @g@ideal +preprocessor is not yet available in +.IR groff . +. +. +.P +.TS +box, center, tab (^); +c | c | c +CfCR | CfCR | CfCR. +preprocessor^starting token^ending token += +@g@chem^.cstart^.cend +@g@eqn^.EQ^.EN +grap^.G1^.G2 +@g@grn^.GS^.GE +.\" Keep the .IF line below the @g@ideal line. +@g@ideal^.IS^.IE +^^.IF +.\" Keep the .PF line below the @g@pic line. +@g@pic^.PS^.PE +^^.PF +^^.PY +@g@refer^.R1^.R2 +@g@tbl^.TS^.TE +_ +glilypond^.lilypond start^.lilypond stop +gperl^.Perl start^.Perl stop +gpinyin^.pinyin start^.pinyin stop +.TE +. +. +.\" ==================================================================== +.SS "Macro packages" +.\" ==================================================================== +. +Macro files are +.I roff +input files designed to produce no output themselves but instead ease +the preparation of other +.I roff +documents. +. +When a macro file is installed at a standard location and suitable for +use by a general audience, +it is termed a +.IR "macro package" . +. +. +.P +Macro packages can be loaded prior to any +.I roff +input documents with the +.BR \-m \~option. +. +The GNU +.I roff +system implements most well-known macro packages for AT&T +.I troff \" AT&T +.\" exceptions: mpm, mv +in a compatible way and extends them. +. +These have one- or two-letter names arising from intense practices of +naming economy in early Unix culture, +a laconic approach that led to many of the packages being identified in +general usage with the +.I nroff +and +.I troff +option letter used to invoke them, +sometimes to punning effect, +as with \[lq]man\[rq] +(short for \[lq]manual\[rq]), +and even with the option dash, +as in the case of the +.I s +package, +much better known as +.I ms +or even +.IR \-ms . +. +. +.P +Macro packages serve a variety of purposes. +. +Some are \[lq]full-service\[rq] packages, +adopting responsibility for page layout among other fundamental tasks, +and defining their own lexicon of macros for document composition; +each such package stands alone and a given document can use at most one. +. +. +.TP +.I an +is used to compose man pages in the format originating in Version\~7 +Unix (1979); +see +.MR groff_man @MAN7EXT@ . +. +It can be specified on the command line as +.BR \-man . +. +. +.TP +.I doc +is used to compose man pages in the format originating in 4.3BSD-Reno +(1990); +see +.MR groff_mdoc @MAN7EXT@ . +. +It can be specified on the command line as +.BR \-mdoc . +. +. +.TP +.I e +is the Berkeley general-purpose macro suite, +developed as an alternative to AT&T's +.IR s ; +see +.MR groff_me @MAN7EXT@ . +. +It can be specified on the command line as +.BR \-me . +. +. +.TP +.I m +implements the format used by the +second-generation AT&T macro suite for general documents, +a successor to +.IR s ; +see +.MR groff_mm @MAN7EXT@ . +. +It can be specified on the command line as +.BR \-mm . +. +. +.TP +.I om +(invariably called \[lq]mom\[rq]) +is a modern package written by Peter Schaffter specifically for GNU +.IR roff . +. +Consult the +.UR file://\:@HTMLDOCDIR@/\:mom/\:toc\:.html +.I mom +HTML manual +.UE +for extensive documentation. +. +She\[em]for +.I mom +takes the female pronoun\[em]can be specified on the command line as +.BR \-mom . +. +. +.TP +.I s +is the original AT&T general-purpose document format; +see +.MR groff_ms @MAN7EXT@ . +. +It can be specified on the command line as +.BR \-ms . +. +. +.P +Others are supplemental. +. +For instance, +. +.I \%andoc +is a wrapper package specific to GNU +.I roff +that recognizes whether a document uses +.I man +or +.I mdoc +format and loads the corresponding macro package. +. +It can be specified on the command line as +.BR \%\-mandoc . +. +A +.MR man 1 +librarian program \" such as man-db, since 2001 +may use this macro file to delegate loading of the correct macro +package; +it is thus unnecessary for +.I man +itself to scan the contents of a document to decide the issue. +. +. +.P +Many macro files augment the function of the full-service packages, +or of +.I roff +documents that do not employ such a package\[em]the latter are sometimes +characterized as \[lq]raw\[rq]. +. +These auxiliary packages are described, +along with +details of macro file naming and placement, +in +.MR groff_tmac @MAN5EXT@ . +. +. +.\" ==================================================================== +.SS Formatters +.\" ==================================================================== +. +The formatter, +the program that interprets +.I roff +language input, +is +.MR @g@troff @MAN1EXT@ . +. +It provides the features of the AT&T +.I troff \" AT&T +and +.I nroff \" AT&T +programs as well as many extensions. +. +The command-line option +.B \-C +switches +.I @g@troff +into +.IR "compatibility mode" , +which tries to emulate AT&T +.I troff \" AT&T +as closely as is practical to enable the formatting of documents written +for the older system. +. +. +.P +A shell script, +.MR @g@nroff @MAN1EXT@ , +emulates the behavior of AT&T +.IR nroff . \" AT&T +. +It attempts to correctly encode the output based on the locale, +relieving the user of the need to specify an output device with the +.B \-T +option and is therefore convenient for use with terminal output devices, +described in the next subsection. +. +. +.P +GNU +.I troff \" GNU +generates output in a device-independent, +but not device-agnostic, +page description language detailed in +.MR groff_out @MAN5EXT@ . +. +. +.\" ==================================================================== +.SS "Output devices" +.\" ==================================================================== +. +.I @g@troff +output is formatted for a particular +.IR "output device" , +typically specified by the +.B \-T +option to the formatter or a front end. +. +If neither this option nor the +.I \%GROFF_TYPESETTER +environment variable is used, +the default output device is +.BR @DEVICE@ . +. +An output device may be any of the following. +. +. +.TP 9n \" to fit "X100\-12" even on troff devices +.B ascii +for terminals using the ISO 646 1991:IRV character set and encoding, +also known as US-ASCII. +. +. +.TP +.B cp1047 +for terminals using the IBM code page 1047 character set and encoding. +. +. +.TP +.B dvi +for TeX DVI format. +. +. +.TP +.B html +.TQ +.B xhtml +for HTML and XHTML output, +respectively. +. +. +.TP +.B latin1 +for terminals using the ISO Latin-1 +(ISO 8859-1) +character set and encoding. +. +. +.TP +.B lbp +for Canon CaPSL printers +(LBP-4 and LBP-8 series laser printers). +. +. +.TP +.B lj4 +for HP LaserJet4-compatible +(or other PCL5-compatible) +printers. +. +. +.TP +.B pdf +for PDF output. +. +. +.TP +.B ps +for PostScript output. +. +. +.TP +.B utf8 +for terminals using the ISO 10646 (\[lq]Unicode\[rq]) character set in +UTF-8 encoding. +. +. +.TP +.B X75 +for previewing with +.I \%gxditview +using +75 dpi resolution and a +10-point base type size. +. +. +.TP +.B X75\-12 +for previewing with +.I \%gxditview +using +75 dpi resolution and a +12-point base type size. +. +. +.TP +.B X100 +for previewing with +.I \%gxditview +using +100 dpi resolution and a +10-point base type size. +. +. +.TP +.B X100\-12 +for previewing with +.I \%gxditview +using +100 dpi resolution +and a +12-point base type size. +. +. +.\" ==================================================================== +.SS Postprocessors +.\" ==================================================================== +. +Any program that interprets the output of +GNU +.I troff \" GNU +is a +postprocessor. +. +The postprocessors provided by GNU +.I roff +are +.IR "output drivers" , +which prepare a document for viewing or printing. +. +Postprocessors for other purposes, +such as page resequencing or statistical measurement of a document, +are conceivable. +. +. +.P +An output driver supports one or more output devices, +each with its own device description file. +. +A device determines its postprocessor with the +.B postpro +directive in its device description file; +see +.MR groff_font @MAN5EXT@ . +. +The +.B \-X +option overrides this selection, +causing +.I \%gxditview +to serve as the output driver. +. +. +.TP +.MR grodvi @MAN1EXT@ +provides +.BR dvi . +. +. +.TP +.MR grohtml @MAN1EXT@ +provides +.B html +and +.BR xhtml . +. +. +.TP +.MR grolbp @MAN1EXT@ +provides +.BR lbp . +. +. +.TP +.MR grolj4 @MAN1EXT@ +provides +.BR lj4 . +. +. +.TP +.MR gropdf @MAN1EXT@ +provides +.BR pdf . +. +. +.TP +.MR grops @MAN1EXT@ +provides +.BR ps . +. +. +.TP +.MR grotty @MAN1EXT@ +provides +.BR ascii , +.BR cp1047 , +.BR latin1 , +and +.BR utf8 . +. +. +.TP +.MR gxditview @MAN1EXT@ +provides +.BR X75 , +.BR X75\-12 , +.BR X100 , +and +.BR X100\-12 , +and additionally can preview +.BR ps . +. +. +.\" ==================================================================== +.SS Utilities +.\" ==================================================================== +. +GNU +.I roff +includes a suite of utilities. +. +. +.TP +.MR gdiffmk @MAN1EXT@ +marks differences between a pair of +.I roff +input files. +. +. +.TP +.MR grog @MAN1EXT@ +infers the +.I groff +command a document requires. +. +. +.P +Several utilities prepare descriptions of fonts, +enabling the formatter to use them when producing output for a given +device. +. +. +.TP +.MR addftinfo @MAN1EXT@ +adds information to AT&T +.I troff \" AT&T +font description files to enable their use with +GNU +.IR troff .\" GNU +. +. +.TP +.MR afmtodit @MAN1EXT@ +creates font description files for PostScript Type\~1 fonts. +. +. +.TP +.MR pfbtops @MAN1EXT@ +translates a PostScript Type\~1 font in PFB +(Printer Font Binary) +format to PFA +(Printer Font ASCII), +which can then be interpreted by +.IR \%afmtodit . +. +. +.TP +.MR hpftodit @MAN1EXT@ +creates font description files for the HP LaserJet\~4 family of +printers. +. +. +.TP +.MR tfmtodit @MAN1EXT@ +creates font description files for the TeX DVI device. +. +. +.TP +.MR xtotroff @MAN1EXT@ +creates font description files for X Window System core fonts. +. +. +.P +A trio of tools transform material constructed using +.I roff +preprocessor languages into graphical image files. +. +. +.TP +.MR eqn2graph @MAN1EXT@ +converts an +.I eqn +equation into a cropped image. +. +. +.TP +.MR grap2graph @MAN1EXT@ +converts a +.I grap +diagram into a cropped image. +. +. +.TP +.MR pic2graph @MAN1EXT@ +converts a +.I pic +diagram into a cropped image. +. +. +.P +Another set of programs works with the bibliographic data files used +by the +.MR refer @MAN1EXT@ +preprocessor. +. +. +.TP +.MR @g@indxbib @MAN1EXT@ +makes inverted indices for bibliographic databases, +speeding lookup operations on them. +. +. +.TP +.MR lkbib @MAN1EXT@ +searches the databases. +. +. +.TP +.MR @g@lookbib @MAN1EXT@ +interactively searches +the databases. +. +. +.\" ==================================================================== +.SH "Exit status" +.\" ==================================================================== +. +.I groff +exits with a failure status if there was a problem parsing its arguments +and a successful status if either of the options +.B \-h +or +.B \-\-help +was specified. +. +Otherwise, +.I groff +runs a pipeline to process its input; +if all commands within the pipeline exit successfully, +.I groff +does likewise. +. +If not, +.IR groff 's +exit status encodes a summary of problems encountered, +setting bit\~0 if a command exited with a failure status, +bit\~1 if a command was terminated with a signal, +and bit\~2 if a command could not be executed. +. +(Thus, +if all three misfortunes befell one's pipeline, +.I groff +would exit with status 2\[ha]0 + 2\[ha]1 + 2\[ha]2 = 1+2+4 = 7.) +. +To troubleshoot pipeline problems, +you may wish to re-run the +.I groff +command with the +.B \-V +option and break the reported pipeline down into separate stages, +inspecting the exit status of and diagnostic messages emitted by each +command. +. +. +.\" ==================================================================== +.SH Environment +.\" ==================================================================== +. +Normally, +the path separator in environment variables ending with +.I PATH +is the colon; +this may vary depending on the operating system. +. +For example, +Windows uses a semicolon instead. +. +. +.TP +.I GROFF_BIN_PATH +This search path, +followed by +.IR PATH , +is used to locate commands executed by +.IR groff . +. +If it is not set, +the installation directory of the GNU +.I roff +executables, +.IR @BINDIR@ , +is searched before +.IR PATH . +. +. +.TP +.I GROFF_COMMAND_PREFIX +GNU +.I roff +can be configured at compile time to apply a prefix to the names of the +programs it provides that had a counterpart in AT&T +.IR troff , \" AT&T +so that name collisions are avoided at run time. +. +The default prefix is empty. +. +. +.IP +When used, +this prefix is conventionally the letter \[lq]g\[rq]. +. +For example, +GNU +.I troff \" GNU +would be installed as +.IR gtroff . +. +Besides +.IR troff , \" GNU +the prefix applies to +the formatter +.IR nroff ; \" GNU +the preprocessors +.IR eqn , \" generic +.IR grn , \" generic +.IR pic , \" generic +.IR \%refer , \" generic +.IR tbl , \" generic +and +.IR \%soelim ; \" generic +and the utilities +.I \%indxbib \" generic +and +.IR \%lookbib . \" generic +. +. +.TP +.I GROFF_ENCODING +The value of this variable is passed to the +.IR preconv (@MAN1EXT@) +preprocessor's +.B \-e +option to select the character encoding of input files. +. +This variable's existence implies +the +.I groff +option +.BR \-k . +. +If set but empty, +.I groff +calls +.I preconv +without an +.B \-e +option. +. +.IR groff 's +.B \-K +option overrides +.IR \%GROFF_ENCODING . +. +. +.TP +.I GROFF_FONT_PATH +Seek the selected output device's directory of device and font +description files in this list of directories. +. +See +.MR @g@troff @MAN1EXT@ +and +.MR groff_font @MAN5EXT@ . +. +. +.TP +.I GROFF_TMAC_PATH +Seek macro files in this list of directories. +. +See +.MR @g@troff @MAN1EXT@ +and +.MR groff_tmac @MAN5EXT@ . +. +. +.TP +.I GROFF_TMPDIR +Create temporary files in this directory. +. +If not set, +but the environment variable +.I \%TMPDIR +is set, +temporary files are created there instead. +. +On Windows systems, +if neither of the foregoing are set, +the environment variables +.I TMP +and +.I TEMP +(in that order) +are checked also. +. +Otherwise, +temporary files are created in +.IR /tmp . +. +The +.MR @g@refer @MAN1EXT@ , +.MR grohtml @MAN1EXT@ , +and +.MR grops @MAN1EXT@ +commands use temporary files. +. +. +.TP +.I GROFF_TYPESETTER +Set the default output device. +. +If empty or not set, +.B @DEVICE@ +is used. +. +The +.B \-T +option overrides +.IR \%GROFF_TYPESETTER . +. +. +.TP +.I SOURCE_DATE_EPOCH +A time stamp +(expressed as seconds since the Unix epoch) +to use as the output creation time stamp in place of the current time. +. +The time is converted to human-readable form using +.MR localtime 3 +when the formatter starts up and stored in registers usable by documents +and macro packages. +. +. +.TP +.I TZ +The time zone to use when converting the current time +(or value of +.IR SOURCE_DATE_EPOCH ) +to human-readable form; +see +.MR tzset 3 . +. +. +.\" ==================================================================== +.SH Examples +.\" ==================================================================== +. +.I roff +systems are best known for formatting man pages. +. +Once a +.MR man 1 +librarian program has located a man page, +it may execute a +.I groff +command much like the following. +. +.RS +.EX +groff \-t \-man \-Tutf8 /usr/share/man/man1/groff.1 +.EE +.RE +. +The librarian will also pipe the output through a pager, +which might not interpret the SGR terminal escape sequences +.I groff +emits for boldface, +underlining, +or italics; +see section \[lq]Limitations\[rq] below. +. +. +.P +To process a +.I roff +input file using the preprocessors +.I @g@tbl +and +.I @g@pic +and the +.I me +macro package in the way to which AT&T +.I troff \" AT&T +users were accustomed, +one would type +(or script) +a pipeline. +. +. +.IP +.EX +@g@pic foo.me | @g@tbl | @g@troff \-me \-Tutf8 | grotty +.EE +. +. +.P +Using +.IR groff , +this pipe can be shortened to an equivalent command. +. +.IP +.EX +groff \-p \-t \-me \-T utf8 foo.me +.EE +. +. +.P +An even easier way to do this is to use +.MR grog @MAN1EXT@ +to guess the preprocessor and macro options and execute the result by +using the command substitution feature of the shell. +. +.IP +.EX +$(grog \-Tutf8 foo.me) +.EE +. +. +.P +Each command-line option to a postprocessor must be specified with any +required leading dashes +.RB \[lq] \- \[rq] +.\" No GNU roff postprocessor uses long options for anything except +.\" --help or --version. +.\"or +.\".RB \[lq] \-\- \[rq] +because +.I groff +passes the arguments as-is to the postprocessor; +this permits arbitrary arguments to be transmitted. +. +For example, +to pass a title to the +.I gxditview +postprocessor, +the shell commands +. +.RS +.EX +groff \-X \-P \-title \-P \[aq]trial run\[aq] mydoc.t +.EE +.RE +. +and +. +.RS +.EX +groff \-X \-Z mydoc.t | gxditview \-title \[aq]trial run\[aq] \- +.EE +.RE +. +are equivalent. +. +. +.\" ==================================================================== +.SH Limitations +.\" ==================================================================== +. +When paging output for the +.BR ascii , +.BR cp1047 , +.BR latin1 , +and +.B utf8 +devices, +programs like +.MR more 1 +and +.MR less 1 +may require command-line options to correctly handle some terminal +escape sequences; +see +.MR grotty @MAN1EXT@ . +. +. +.P +On EBCDIC hosts such as OS/390 Unix, +the output devices +.B ascii +and +.B latin1 +aren't available. +. +Conversely, +the output device +.B cp1047 +is not available on systems based on the ISO\~646 or ISO\~8859 character +encoding standards. +. +. +.\" ==================================================================== +.SH "Installation directories" +.\" ==================================================================== +. +GNU +.I roff +installs files in varying locations depending on its compile-time +configuration. +. +On this installation, +the following locations are used. +. +. +.if !'@APPDEFDIR@'' \{\ +.TP +.I @APPDEFDIR@ +Application defaults directory for +.MR gxditview @MAN1EXT@ . +.\} +. +. +.TP +.I @BINDIR@ +Directory containing +.IR groff 's +executable commands. +. +. +.TP +.I @COMMON_WORDS_FILE@ +List of common words for +.MR indxbib @MAN1EXT@ . +. +. +.TP +.I @DATASUBDIR@ +Directory for data files. +. +. +.TP +.I @DEFAULT_INDEX@ +Default index for +.MR lkbib @MAN1EXT@ +and +.MR refer @MAN1EXT@ . +. +. +.TP +.I @DOCDIR@ +Documentation directory. +. +. +.TP +.I @EXAMPLEDIR@ +Example directory. +. +. +.TP +.I @FONTDIR@ +Font directory. +. +. +.TP +.I @HTMLDOCDIR@ +HTML documentation directory. +. +. +.TP +.I @LEGACYFONTDIR@ +Legacy font directory. +. +. +.TP +.I @LOCALFONTDIR@ +Local font directory. +. +. +.TP +.I @LOCALMACRODIR@ +Local macro package +.RI ( tmac +file) directory. +. +. +.TP +.I @MACRODIR@ +Macro package +.RI ( tmac +file) directory. +. +. +.TP +.I @OLDFONTDIR@ +Font directory for compatibility with old versions of +.IR groff ; +see +.MR grops @MAN1EXT@ . +. +. +.TP +.I @PDFDOCDIR@ +PDF documentation directory. +. +. +.if !'@COMPATIBILITY_WRAPPERS@'no' \{\ +.TP +.I @SYSTEMMACRODIR@ +System macro package +.RI ( tmac +file) directory. +.\} +. +. +.\" ==================================================================== +.SS "\f[I]groff\f[] macro directory" +.\" ==================================================================== +. +Most macro files supplied with GNU +.I roff +are stored in +.I @MACRODIR@ +for the installation corresponding to this document. +. +As a rule, +multiple directories are searched for macro files; +see +.MR @g@troff @MAN1EXT@ . +. +For a catalog of macro files GNU +.I roff +provides, +see +.MR groff_tmac @MAN5EXT@ . +. +. +.\" ==================================================================== +.SS "\f[I]groff\f[] device and font description directory" +.\" ==================================================================== +. +Device and font description files supplied with GNU +.I roff +are stored in +.I @FONTDIR@ +for the installation corresponding to this document. +. +As a rule, +multiple directories are searched for device and font description files; +see +.MR @g@troff @MAN1EXT@ . +. +For the formats of these files, +see +.MR groff_font @MAN5EXT@ . +. +. +.\" ==================================================================== +.SH Availability +.\" ==================================================================== +. +Obtain links to +.I groff +releases for download, +its source repository, +discussion mailing lists, +a support ticket tracker, +and further information from the +.UR http://\:www\:.gnu\:.org/\:software/\:groff +.I groff +page of the GNU website +.UE . +. +. +.P +A free implementation of the +.I grap +preprocessor, +written by +.MT faber@\:lunabase\:.org +Ted Faber +.ME , +can be found at the +.UR http://\:www\:.lunabase\:.org/\:\[ti]faber/\:Vault/\:software/\ +\:grap/ +.I grap +website +.UE . +. +.I groff +supports only this +.IR grap . +. +. +.\" ==================================================================== +.SH Authors +.\" ==================================================================== +. +.I groff +(both the front-end command and the overall system) +was primarily written by +.MT jjc@\:jclark\:.com +James Clark +.ME . +. +Contributors to this document include Clark, +Trent A.\& Fisher, +.MT wl@gnu.org +Werner Lemberg +.ME , +.MT groff\-bernd.warken\-72@\:web\:.de +Bernd Warken +.ME , +and +.MT g.branden\:.robinson@\:gmail\:.com +G.\& Branden Robinson +.ME . +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.IR "Groff: The GNU Implementation of troff" , +by Trent A.\& Fisher and Werner Lemberg, +is the primary +.I groff +manual. +. +You can browse it interactively with \[lq]info groff\[rq]. +. +. +.\" groff ships 59 man pages generated from 58 source files. The +.\" numbered comments refer to their sorting order in the source tree, +.\" so that it is easier to tell that we've enumerated all of them. +.TP +Introduction, \c +history, \c +and further reading: +.MR roff @MAN7EXT@ \" #23 +. +. +.TP +.RI "Viewer for\~" groff "\~(and AT&T device-independent\~" troff \ +)\~documents: +.MR gxditview @MAN1EXT@ \" #33 +. +. +.TP +Preprocessors: +.MR @g@chem @MAN1EXT@ , \" #1 +.MR @g@eqn @MAN1EXT@ , \" #34 +.MR @g@neqn @MAN1EXT@ , \" #35 +.MR glilypond @MAN1EXT@ , \" #4 +.MR @g@grn @MAN1EXT@ , \" #36 +.MR preconv @MAN1EXT@ , \" #38 +.MR gperl @MAN1EXT@ , \" #5 +.MR @g@pic @MAN1EXT@ , \" #37 +.MR gpinyin @MAN1EXT@ , \" #6 +.MR @g@refer @MAN1EXT@ , \" #39 +.MR @g@soelim @MAN1EXT@ , \" #40 +.MR @g@tbl @MAN1EXT@ \" #41 +. +. +.TP +Macro packages and package-specific utilities: +.MR groff_hdtbl @MAN7EXT@ , \" #9 +.MR groff_man @MAN7EXT@ , \" #55a +.MR groff_man_style @MAN7EXT@ , \" #55b +.MR groff_mdoc @MAN7EXT@ , \" #56 +.MR groff_me @MAN7EXT@ , \" #57 +.MR groff_mm @MAN7EXT@ , \" # 10 +.MR groff_mmse @MAN7EXT@ , \" # 11 +.MR mmroff @MAN1EXT@ , \" #12 +.MR groff_mom @MAN7EXT@ , \" #13 +.MR pdfmom @MAN1EXT@ , \" #30 +.MR groff_ms @MAN7EXT@ , \" #58 +.MR groff_rfc1345 @MAN7EXT@ , \" 16 +.MR groff_trace @MAN7EXT@ , \" #59 +.MR groff_www @MAN7EXT@ \" #60 +. +. +.TP +Bibliographic database management tools: +.MR @g@indxbib @MAN1EXT@ , \" #49 +.MR lkbib @MAN1EXT@ , \" #50 +.MR @g@lookbib @MAN1EXT@ \" #51 +. +. +.TP +Language, \c +conventions, \c +and GNU extensions: +.MR groff @MAN7EXT@ , \" #17 +.MR groff_char @MAN7EXT@ , \" #18 +.MR groff_diff @MAN7EXT@ , \" #19 +.MR groff_font @MAN5EXT@ , \" #20 +.MR groff_tmac @MAN5EXT@ \" #22 +. +. +.TP +Intermediate output language: +.MR groff_out @MAN5EXT@ \" #21 +. +. +.TP +Formatter program: +.MR @g@troff @MAN1EXT@ \" #45 +. +. +.TP +Formatter wrappers: +.\".MR groff @MAN1EXT@ , \" 42 -- this page +.MR @g@nroff @MAN1EXT@ , \" #44 +.MR pdfroff @MAN1EXT@ \" #14 +. +. +.TP +Postprocessors for output devices: +.MR grodvi @MAN1EXT@ , \" #24 +.MR grohtml @MAN1EXT@ , \" #25 +.MR grolbp @MAN1EXT@ , \" #26 +.MR grolj4 @MAN1EXT@ , \" #27 +.MR gropdf @MAN1EXT@ , \" #29 +.MR grops @MAN1EXT@ , \" #31 +.MR grotty @MAN1EXT@ \" #32 +. +. +.TP +Font support utilities: +.MR addftinfo @MAN1EXT@ , \" #46 +.MR afmtodit @MAN1EXT@ , \" #47 +.MR hpftodit @MAN1EXT@ , \" #48 +.MR pfbtops @MAN1EXT@ , \" #52 +.MR tfmtodit @MAN1EXT@ , \" #53 +.MR xtotroff @MAN1EXT@ \" #54 +. +. +.TP +Graphics conversion utilities: +.MR eqn2graph @MAN1EXT@ , \" #2 +.MR grap2graph @MAN1EXT@ , \" #7 +.MR pic2graph @MAN1EXT@ \" #15 +. +. +.TP +Difference-marking utility: +.MR gdiffmk @MAN1EXT@ \" #3 +. +. +.TP +\[lq]groff guess\[rq] utility: +.MR grog @MAN1EXT@ \" #43 +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_groff_1_man_C] +.do rr *groff_groff_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/roff/groff/groff.am b/src/roff/groff/groff.am new file mode 100644 index 0000000..8937d4c --- /dev/null +++ b/src/roff/groff/groff.am @@ -0,0 +1,87 @@ +# Copyright (C) 1993-2020 Free Software Foundation, Inc. +# +# Original Makefile.sub rewritten by +# Bernd Warken +# and Werner LEMBERG +# +# Automake migration by +# Bertrand Garrigues +# +# This file 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 . + +bin_PROGRAMS += groff +groff_LDADD = \ + libgroff.a \ + lib/libgnu.a \ + $(LIBM) +groff_SOURCES = \ + src/roff/groff/groff.cpp \ + src/roff/groff/pipeline.c \ + src/roff/groff/pipeline.h +src/roff/groff/groff.$(OBJEXT): defs.h +man1_MANS += src/roff/groff/groff.1 +EXTRA_DIST += src/roff/groff/groff.1.man + +groff_TESTS = \ + src/roff/groff/tests/ab_works.sh \ + src/roff/groff/tests/adjustment_works.sh \ + src/roff/groff/tests/break_zero-length_output_line_sanely.sh \ + src/roff/groff/tests/device_control_escapes_express_basic_latin.sh \ + src/roff/groff/tests/do_not_loop_infinitely_when_breaking_cjk.sh \ + src/roff/groff/tests/dot-cp_register_works.sh \ + src/roff/groff/tests/dot-nm_register_works.sh \ + src/roff/groff/tests/dot-nn_register_works.sh \ + src/roff/groff/tests/evc_produces_no_output_if_invalid.sh \ + src/roff/groff/tests/fp_should_not_traverse_directories.sh \ + src/roff/groff/tests/handle_special_input_code_points.sh \ + src/roff/groff/tests/html_works_with_grn_and_eqn.sh \ + src/roff/groff/tests/initialization_is_quiet.sh \ + src/roff/groff/tests/localization_works.sh \ + src/roff/groff/tests/msoquiet_works.sh \ + src/roff/groff/tests/on_latin1_device_oq_is_0x27.sh \ + src/roff/groff/tests/output_driver_C_and_G_options_work.sh \ + src/roff/groff/tests/recognize_end_of_sentence.sh \ + src/roff/groff/tests/regression_savannah_56555.sh \ + src/roff/groff/tests/regression_savannah_58153.sh \ + src/roff/groff/tests/regression_savannah_58162.sh \ + src/roff/groff/tests/regression_savannah_58337.sh \ + src/roff/groff/tests/regression_savannah_59202.sh \ + src/roff/groff/tests/smoke-test_html_device.sh \ + src/roff/groff/tests/some_escapes_accept_newline_delimiters.sh \ + src/roff/groff/tests/soquiet_works.sh \ + src/roff/groff/tests/string_case_xform_errors.sh \ + src/roff/groff/tests/string_case_xform_requests.sh \ + src/roff/groff/tests/string_case_xform_unicode_escape.sh \ + src/roff/groff/tests/substring_works.sh \ + src/roff/groff/tests/use_point_size_escape_with_single_digit_arg.sh +TESTS += $(groff_TESTS) +EXTRA_DIST += $(groff_TESTS) + +# required test artifacts +EXTRA_DIST += \ + src/roff/groff/tests/artifacts/HONEYPOT \ + src/roff/groff/tests/artifacts/devascii/README + +groff_XFAIL_TESTS = \ + src/roff/groff/tests/string_case_xform_unicode_escape.sh +XFAIL_TESTS += $(groff_XFAIL_TESTS) + + +# Local Variables: +# mode: makefile-automake +# fill-column: 72 +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/roff/groff/groff.cpp b/src/roff/groff/groff.cpp new file mode 100644 index 0000000..4eb7329 --- /dev/null +++ b/src/roff/groff/groff.cpp @@ -0,0 +1,866 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +// A front end for groff. + +#include "lib.h" + +#include +#include +#include +#include + +#include "errarg.h" +#include "error.h" +#include "stringclass.h" +#include "cset.h" +#include "font.h" +#include "device.h" +#include "pipeline.h" +#include "nonposix.h" +#include "relocate.h" +#include "defs.h" + +#define GXDITVIEW "gxditview" + +// troff will be passed an argument of -rXREG=1 if the -X option is +// specified +#define XREG ".X" + +#ifdef NEED_DECLARATION_PUTENV +extern "C" { + int putenv(const char *); +} +#endif /* NEED_DECLARATION_PUTENV */ + +// The number of commands must be in sync with MAX_COMMANDS in +// pipeline.h. + +// grap, chem, and ideal must come before pic; +// tbl must come before eqn +const int PRECONV_INDEX = 0; +const int SOELIM_INDEX = PRECONV_INDEX + 1; +const int REFER_INDEX = SOELIM_INDEX + 1; +const int GRAP_INDEX = REFER_INDEX + 1; +const int CHEM_INDEX = GRAP_INDEX + 1; +const int IDEAL_INDEX = CHEM_INDEX + 1; +const int PIC_INDEX = IDEAL_INDEX + 1; +const int TBL_INDEX = PIC_INDEX + 1; +const int GRN_INDEX = TBL_INDEX + 1; +const int EQN_INDEX = GRN_INDEX + 1; +const int TROFF_INDEX = EQN_INDEX + 1; +const int POST_INDEX = TROFF_INDEX + 1; +const int SPOOL_INDEX = POST_INDEX + 1; + +const int NCOMMANDS = SPOOL_INDEX + 1; + +class possible_command { + char *name; + string args; + char **argv; + + void build_argv(); +public: + possible_command(); + ~possible_command(); + void clear_name(); + void set_name(const char *); + void set_name(const char *, const char *); + const char *get_name(); + void append_arg(const char *, const char * = 0 /* nullptr */); + void insert_arg(const char *); + void insert_args(string s); + void clear_args(); + char **get_argv(); + void print(int is_last, FILE *fp); +}; + +extern "C" const char *Version_string; + +int lflag = 0; +char *spooler = 0 /* nullptr */; +char *postdriver = 0 /* nullptr */; +char *predriver = 0 /* nullptr */; +bool need_postdriver = true; +char *saved_path = 0 /* nullptr */; +char *groff_bin_path = 0 /* nullptr */; +char *groff_font_path = 0 /* nullptr */; + +possible_command commands[NCOMMANDS]; + +int run_commands(int no_pipe); +void print_commands(FILE *); +void append_arg_to_string(const char *arg, string &str); +void handle_unknown_desc_command(const char *command, const char *arg, + const char *filename, int lineno); +const char *xbasename(const char *); + +void usage(FILE *stream); + +static char *xstrdup(const char *s) { + if (0 /* nullptr */ == s) + return const_cast(s); + char *str = strdup(s); + if (0 /* nullptr */ == str) + fatal("unable to copy string: %1", strerror(errno)); + return str; +} + +static void xputenv(const char *s) { + if (putenv(const_cast(s)) != 0) + fatal("unable to write to environment: %1", strerror(errno)); + return; +} + +static void xexit(int status) { + free(spooler); + free(predriver); + free(postdriver); + free(saved_path); + free(groff_bin_path); + free(groff_font_path); + exit(status); +} + +int main(int argc, char **argv) +{ + program_name = argv[0]; + static char stderr_buf[BUFSIZ]; + setbuf(stderr, stderr_buf); + assert(NCOMMANDS <= MAX_COMMANDS); + string Pargs, Largs, Fargs; + int Kflag = 0; + int vflag = 0; + int Vflag = 0; + int zflag = 0; + int iflag = 0; + int Xflag = 0; + int oflag = 0; + int safer_flag = 1; + int is_xhtml = 0; + int eflag = 0; + int need_pic = 0; + int opt; + const char *command_prefix = getenv("GROFF_COMMAND_PREFIX"); + const char *encoding = getenv("GROFF_ENCODING"); + if (!command_prefix) + command_prefix = PROG_PREFIX; + commands[TROFF_INDEX].set_name(command_prefix, "troff"); + static const struct option long_options[] = { + { "help", no_argument, 0, 'h' }, + { "version", no_argument, 0, 'v' }, + { NULL, 0, 0, 0 } + }; + while ((opt = getopt_long( + argc, argv, + "abcCd:D:eEf:F:gGhiI:jJkK:lL:m:M:" + "n:No:pP:r:RsStT:UvVw:W:XzZ", + long_options, NULL)) + != EOF) { + char buf[3]; + buf[0] = '-'; + buf[1] = opt; + buf[2] = '\0'; + switch (opt) { + case 'i': + iflag = 1; + break; + case 'I': + commands[GRN_INDEX].set_name(command_prefix, "grn"); + commands[GRN_INDEX].append_arg("-M", optarg); + commands[SOELIM_INDEX].set_name(command_prefix, "soelim"); + commands[SOELIM_INDEX].append_arg(buf, optarg); + // .psbb may need to search for files + commands[TROFF_INDEX].append_arg(buf, optarg); + // \X'ps:import' may need to search for files + Pargs += buf; + Pargs += optarg; + Pargs += '\0'; + break; + case 'D': + commands[PRECONV_INDEX].set_name("preconv"); + commands[PRECONV_INDEX].append_arg("-D", optarg); + break; + case 'K': + commands[PRECONV_INDEX].append_arg("-e", optarg); + Kflag = 1; + // fall through + case 'k': + commands[PRECONV_INDEX].set_name("preconv"); + break; + case 't': + commands[TBL_INDEX].set_name(command_prefix, "tbl"); + break; + case 'J': + // commands[IDEAL_INDEX].set_name(command_prefix, "gideal"); + // need_pic = 1; + break; + case 'j': + commands[CHEM_INDEX].set_name(command_prefix, "chem"); + need_pic = 1; + break; + case 'p': + commands[PIC_INDEX].set_name(command_prefix, "pic"); + break; + case 'g': + commands[GRN_INDEX].set_name(command_prefix, "grn"); + break; + case 'G': + commands[GRAP_INDEX].set_name(command_prefix, "grap"); + need_pic = 1; + break; + case 'e': + eflag = 1; + commands[EQN_INDEX].set_name(command_prefix, "eqn"); + break; + case 's': + commands[SOELIM_INDEX].set_name(command_prefix, "soelim"); + break; + case 'R': + commands[REFER_INDEX].set_name(command_prefix, "refer"); + break; + case 'z': + case 'a': + commands[TROFF_INDEX].append_arg(buf); + // fall through + case 'Z': + zflag++; + need_postdriver = false; + break; + case 'l': + lflag++; + break; + case 'V': + Vflag++; + break; + case 'v': + vflag = 1; + printf("GNU groff version %s\n", Version_string); + printf( + "Copyright (C) 2022 Free Software Foundation, Inc.\n" + "GNU groff comes with ABSOLUTELY NO WARRANTY.\n" + "You may redistribute copies of groff and its subprograms\n" + "under the terms of the GNU General Public License.\n" + "For more information about these matters, see the file\n" + "named COPYING.\n"); + printf("\ncalled subprograms:\n\n"); + fflush(stdout); + // Pass -v to all possible subprograms + commands[PRECONV_INDEX].append_arg(buf); + commands[CHEM_INDEX].append_arg(buf); + commands[IDEAL_INDEX].append_arg(buf); + commands[POST_INDEX].append_arg(buf); + // fall through + case 'C': + commands[SOELIM_INDEX].append_arg(buf); + commands[REFER_INDEX].append_arg(buf); + commands[PIC_INDEX].append_arg(buf); + commands[GRAP_INDEX].append_arg(buf); + commands[TBL_INDEX].append_arg(buf); + commands[GRN_INDEX].append_arg(buf); + commands[EQN_INDEX].append_arg(buf); + commands[TROFF_INDEX].append_arg(buf); + break; + case 'N': + commands[EQN_INDEX].append_arg(buf); + break; + case 'h': + usage(stdout); + break; + case 'E': + case 'b': + commands[TROFF_INDEX].append_arg(buf); + break; + case 'c': + commands[TROFF_INDEX].append_arg(buf); + break; + case 'S': + safer_flag = 1; + break; + case 'U': + safer_flag = 0; + break; + case 'T': + if (strcmp(optarg, "xhtml") == 0) { + // force soelim to aid the html preprocessor + commands[SOELIM_INDEX].set_name(command_prefix, "soelim"); + Pargs += "-x"; + Pargs += '\0'; + Pargs += 'x'; + Pargs += '\0'; + is_xhtml = 1; + device = "html"; + break; + } + if (strcmp(optarg, "html") == 0) + // force soelim to aid the html preprocessor + commands[SOELIM_INDEX].set_name(command_prefix, "soelim"); + if (strcmp(optarg, "Xps") == 0) { + warning("-TXps option is obsolete: use -X -Tps instead"); + device = "ps"; + Xflag++; + } + else + device = optarg; + break; + case 'F': + font::command_line_font_dir(optarg); + if (Fargs.length() > 0) { + Fargs += PATH_SEP_CHAR; + Fargs += optarg; + } + else + Fargs = optarg; + break; + case 'o': + oflag = 1; + // fall through + case 'f': + case 'm': + case 'r': + case 'd': + case 'n': + case 'w': + case 'W': + commands[TROFF_INDEX].append_arg(buf, optarg); + break; + case 'M': + commands[EQN_INDEX].append_arg(buf, optarg); + commands[GRAP_INDEX].append_arg(buf, optarg); + commands[GRN_INDEX].append_arg(buf, optarg); + commands[TROFF_INDEX].append_arg(buf, optarg); + break; + case 'P': + Pargs += optarg; + Pargs += '\0'; + break; + case 'L': + append_arg_to_string(optarg, Largs); + break; + case 'X': + Xflag++; + need_postdriver = false; + break; + case '?': + usage(stderr); + xexit(EXIT_FAILURE); + break; + default: + assert(0 == "no case to handle option character"); + break; + } + } + if (need_pic) + commands[PIC_INDEX].set_name(command_prefix, "pic"); + if (encoding) { + commands[PRECONV_INDEX].set_name("preconv"); + if (!Kflag && *encoding) + commands[PRECONV_INDEX].append_arg("-e", encoding); + } + if (!safer_flag) { + commands[TROFF_INDEX].insert_arg("-U"); + commands[PIC_INDEX].append_arg("-U"); + } + font::set_unknown_desc_command_handler(handle_unknown_desc_command); + const char *desc = font::load_desc(); + if (0 /* nullptr */ == desc) + fatal("cannot load 'DESC' description file for device '%1'", + device); + if (need_postdriver && (0 /* nullptr */ == postdriver)) + fatal_with_file_and_line(desc, 0, "device description file missing" + " 'postpro' directive"); + if (predriver && !zflag) { + commands[TROFF_INDEX].insert_arg(commands[TROFF_INDEX].get_name()); + commands[TROFF_INDEX].set_name(predriver); + // pass the device arguments to the predrivers as well + commands[TROFF_INDEX].insert_args(Pargs); + if (eflag && is_xhtml) + commands[TROFF_INDEX].insert_arg("-e"); + if (vflag) + commands[TROFF_INDEX].insert_arg("-v"); + } + const char *real_driver = 0 /* nullptr */; + if (Xflag) { + real_driver = postdriver; + postdriver = xstrdup(GXDITVIEW); // so we can free() it in xexit() + commands[TROFF_INDEX].append_arg("-r" XREG "=", "1"); + } + if (postdriver) + commands[POST_INDEX].set_name(postdriver); + int gxditview_flag = postdriver + && strcmp(xbasename(postdriver), GXDITVIEW) == 0; + if (gxditview_flag && argc - optind == 1) { + commands[POST_INDEX].append_arg("-title"); + commands[POST_INDEX].append_arg(argv[optind]); + commands[POST_INDEX].append_arg("-xrm"); + commands[POST_INDEX].append_arg("*iconName:", argv[optind]); + string filename_string("|"); + append_arg_to_string(argv[0], filename_string); + append_arg_to_string("-Z", filename_string); + for (int i = 1; i < argc; i++) + append_arg_to_string(argv[i], filename_string); + filename_string += '\0'; + commands[POST_INDEX].append_arg("-filename"); + commands[POST_INDEX].append_arg(filename_string.contents()); + } + if (gxditview_flag && Xflag) { + string print_string(real_driver); + if (spooler) { + print_string += " | "; + print_string += spooler; + print_string += Largs; + } + print_string += '\0'; + commands[POST_INDEX].append_arg("-printCommand"); + commands[POST_INDEX].append_arg(print_string.contents()); + } + const char *p = Pargs.contents(); + const char *end = p + Pargs.length(); + while (p < end) { + commands[POST_INDEX].append_arg(p); + p = strchr(p, '\0') + 1; + } + if (gxditview_flag) + commands[POST_INDEX].append_arg("-"); + if (lflag && !vflag && !Xflag && spooler) { + commands[SPOOL_INDEX].set_name(BSHELL); + commands[SPOOL_INDEX].append_arg(BSHELL_DASH_C); + Largs += '\0'; + Largs = spooler + Largs; + commands[SPOOL_INDEX].append_arg(Largs.contents()); + } + if (zflag) { + commands[POST_INDEX].set_name(0 /* nullptr */); + commands[SPOOL_INDEX].set_name(0 /* nullptr */); + } + commands[TROFF_INDEX].append_arg("-T", device); + if (strcmp(device, "html") == 0) { + if (is_xhtml) { + if (oflag) + fatal("'-o' option is invalid with device 'xhtml'"); + if (zflag) + commands[EQN_INDEX].append_arg("-Tmathml:xhtml"); + else if (eflag) + commands[EQN_INDEX].clear_name(); + } + else { + if (oflag) + fatal("'-o' option is invalid with device 'html'"); + // html renders equations as images via ps + commands[EQN_INDEX].append_arg("-Tps:html"); + } + } + else + commands[EQN_INDEX].append_arg("-T", device); + + commands[GRN_INDEX].append_arg("-T", device); + + int first_index; + for (first_index = 0; first_index < TROFF_INDEX; first_index++) + if (commands[first_index].get_name() != 0 /* nullptr */) + break; + if (optind < argc) { + if (argv[optind][0] == '-' && argv[optind][1] != '\0') + commands[first_index].append_arg("--"); + for (int i = optind; i < argc; i++) + commands[first_index].append_arg(argv[i]); + if (iflag) + commands[first_index].append_arg("-"); + } + if (Fargs.length() > 0) { + string e = "GROFF_FONT_PATH"; + e += '='; + e += Fargs; + char *fontpath = getenv("GROFF_FONT_PATH"); + if (fontpath && *fontpath) { + e += PATH_SEP_CHAR; + e += fontpath; + } + e += '\0'; + groff_font_path = xstrdup(e.contents()); + xputenv(groff_font_path); + } + { + // we save the original path in GROFF_PATH__ and put it into the + // environment -- troff will pick it up later. + char *path = getenv("PATH"); + string g = "GROFF_PATH__"; + g += '='; + if (path && *path) + g += path; + g += '\0'; + saved_path = xstrdup(g.contents()); + xputenv(saved_path); + char *binpath = getenv("GROFF_BIN_PATH"); + string f = "PATH"; + f += '='; + if (binpath && *binpath) + f += binpath; + else { + binpath = relocatep(BINPATH); + f += binpath; + } + if (path && *path) { + f += PATH_SEP_CHAR; + f += path; + } + f += '\0'; + groff_bin_path = xstrdup(f.contents()); + xputenv(groff_bin_path); + } + if (Vflag) + print_commands(Vflag == 1 ? stdout : stderr); + if (Vflag == 1) + xexit(EXIT_SUCCESS); + xexit(run_commands(vflag)); +} + +const char *xbasename(const char *s) +{ + if (!s) + return 0 /* nullptr */; + // DIR_SEPS[] are possible directory separator characters; see + // nonposix.h. We want the rightmost separator of all possible ones. + // Example: d:/foo\\bar. + const char *p = strrchr(s, DIR_SEPS[0]), *p1; + const char *sep = &DIR_SEPS[1]; + + while (*sep) + { + p1 = strrchr(s, *sep); + if (p1 && (!p || p1 > p)) + p = p1; + sep++; + } + return p ? p + 1 : s; +} + +void handle_unknown_desc_command(const char *command, const char *arg, + const char *filename, int lineno) +{ + if (strcmp(command, "print") == 0) { + if (arg == 0 /* nullptr */) + error_with_file_and_line(filename, lineno, "'print' directive" + " requires an argument"); + else + spooler = xstrdup(arg); + return; + } + if (strcmp(command, "prepro") == 0) { + if (arg == 0 /* nullptr */) + error("'prepro' directive requires an argument"); + else { + for (const char *p = arg; *p; p++) + if (csspace(*p)) { + error_with_file_and_line(filename, lineno, "invalid 'prepro'" + " directive argument '%1': program" + " name required", arg); + } + predriver = xstrdup(arg); + } + return; + } + if (strcmp(command, "postpro") == 0) { + if (arg == 0 /* nullptr */) + error_with_file_and_line(filename, lineno, "'postpro' directive" + " requires an argument"); + else { + for (const char *p = arg; *p; p++) + if (csspace(*p)) { + error_with_file_and_line(filename, lineno, "invalid 'postpro'" + " directive argument '%1': program" + " name required", arg); + return; + } + postdriver = xstrdup(arg); + } + return; + } +} + +void print_commands(FILE *fp) +{ + int last; + for (last = SPOOL_INDEX; last >= 0; last--) + if (commands[last].get_name() != 0 /* nullptr */) + break; + for (int i = 0; i <= last; i++) + if (commands[i].get_name() != 0 /* nullptr */) + commands[i].print(i == last, fp); +} + +// Run the commands. Return the code with which to exit. + +int run_commands(int no_pipe) +{ + char **v[NCOMMANDS]; // vector of argv arrays to pipe together + int ncommands = 0; + for (int i = 0; i < NCOMMANDS; i++) + if (commands[i].get_name() != 0 /* nullptr */) + v[ncommands++] = commands[i].get_argv(); + return run_pipeline(ncommands, v, no_pipe); +} + +possible_command::possible_command() +: name(0), argv(0) +{ +} + +possible_command::~possible_command() +{ + free(name); + delete[] argv; +} + +void possible_command::set_name(const char *s) +{ + free(name); + name = xstrdup(s); +} + +void possible_command::clear_name() +{ + delete[] name; + delete[] argv; + name = NULL; + argv = NULL; +} + +void possible_command::set_name(const char *s1, const char *s2) +{ + free(name); + name = (char*)malloc(strlen(s1) + strlen(s2) + 1); + strcpy(name, s1); + strcat(name, s2); +} + +const char *possible_command::get_name() +{ + return name; +} + +void possible_command::clear_args() +{ + args.clear(); +} + +void possible_command::append_arg(const char *s, const char *t) +{ + args += s; + if (t) + args += t; + args += '\0'; +} + +void possible_command::insert_arg(const char *s) +{ + string str(s); + str += '\0'; + str += args; + args = str; +} + +void possible_command::insert_args(string s) +{ + const char *p = s.contents(); + const char *end = p + s.length(); + int l = 0; + if (p >= end) + return; + // find the total number of arguments in our string + do { + l++; + p = strchr(p, '\0') + 1; + } while (p < end); + // now insert each argument preserving the order + for (int i = l - 1; i >= 0; i--) { + p = s.contents(); + for (int j = 0; j < i; j++) + p = strchr(p, '\0') + 1; + insert_arg(p); + } +} + +void possible_command::build_argv() +{ + if (argv) + return; + // Count the number of arguments. + int len = args.length(); + int argc = 1; + char *p = 0 /* nullptr */; + if (len > 0) { + p = &args[0]; + for (int i = 0; i < len; i++) + if (p[i] == '\0') + argc++; + } + // Build an argument vector. + argv = new char *[argc + 1]; + argv[0] = name; + for (int i = 1; i < argc; i++) { + argv[i] = p; + p = strchr(p, '\0') + 1; + } + argv[argc] = 0 /* nullptr */; +} + +void possible_command::print(int is_last, FILE *fp) +{ + build_argv(); + if (IS_BSHELL(argv[0]) + && argv[1] != 0 /* nullptr */ + && strcmp(argv[1], BSHELL_DASH_C) == 0 + && argv[2] != 0 /* nullptr */ && argv[3] == 0 /* nullptr */) + fputs(argv[2], fp); + else { + fputs(argv[0], fp); + string str; + for (int i = 1; argv[i] != 0 /* nullptr */; i++) { + str.clear(); + append_arg_to_string(argv[i], str); + put_string(str, fp); + } + } + if (is_last) + putc('\n', fp); + else + fputs(" | ", fp); +} + +void append_arg_to_string(const char *arg, string &str) +{ + str += ' '; + int needs_quoting = 0; + // Native Windows programs don't support '..' style of quoting, so + // always behave as if ARG included the single quote character. +#if defined(_WIN32) && !defined(__CYGWIN__) + int contains_single_quote = 1; +#else + int contains_single_quote = 0; +#endif + const char*p; + for (p = arg; *p != '\0'; p++) + switch (*p) { + case ';': + case '&': + case '(': + case ')': + case '|': + case '^': + case '<': + case '>': + case '\n': + case ' ': + case '\t': + case '\\': + case '"': + case '$': + case '?': + case '*': + needs_quoting = 1; + break; + case '\'': + contains_single_quote = 1; + break; + } + if (contains_single_quote || arg[0] == '\0') { + str += '"'; + for (p = arg; *p != '\0'; p++) + switch (*p) { +#if !(defined(_WIN32) && !defined(__CYGWIN__)) + case '"': + case '\\': + case '$': + str += '\\'; +#else + case '"': + case '\\': + if (*p == '"' || (*p == '\\' && p[1] == '"')) + str += '\\'; +#endif + // fall through + default: + str += *p; + break; + } + str += '"'; + } + else if (needs_quoting) { + str += '\''; + str += arg; + str += '\''; + } + else + str += arg; +} + +char **possible_command::get_argv() +{ + build_argv(); + return argv; +} + +void usage(FILE *stream) +{ + // Add `J` to the cluster if we ever get ideal(1) support. + fprintf(stream, +"usage: %s [-abcCeEgGijklNpRsStUVXzZ] [-d ctext] [-d string=text]" +" [-D fallback-encoding] [-f font-family] [-F font-directory]" +" [-I inclusion-directory] [-K input-encoding] [-L spooler-argument]" +" [-m macro-package] [-M macro-directory] [-n page-number]" +" [-o page-list] [-P postprocessor-argument] [-r cnumeric-expression]" +" [-r register=numeric-expression] [-T output-device]" +" [-w warning-category] [-W warning-category]" +" [file ...]\n" +"usage: %s {-v | --version}\n" +"usage: %s {-h | --help}\n", + program_name, program_name, program_name); + if (stdout == stream) { + fputs( +"\n" +"groff (GNU roff) is a typesetting system that reads plain text input\n" +"files that include formatting commands to produce output in\n" +"PostScript, PDF, HTML, or DVI formats or for display to a terminal.\n" +"See the groff(1) manual page.\n", + stream); + exit(EXIT_SUCCESS); + } +} + +extern "C" { + +void c_error(const char *format, const char *arg1, const char *arg2, + const char *arg3) +{ + error(format, arg1, arg2, arg3); +} + +void c_fatal(const char *format, const char *arg1, const char *arg2, + const char *arg3) +{ + fatal(format, arg1, arg2, arg3); +} + +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/roff/groff/pipeline.c b/src/roff/groff/pipeline.c new file mode 100644 index 0000000..defafc2 --- /dev/null +++ b/src/roff/groff/pipeline.c @@ -0,0 +1,589 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_STRERROR +#include +#else +extern char *strerror(); +#endif + +#ifdef _POSIX_VERSION + +#include +#define PID_T pid_t + +#else /* not _POSIX_VERSION */ + +/* traditional Unix */ + +#define WIFEXITED(s) (((s) & 0377) == 0) +#define WIFSTOPPED(s) (((s) & 0377) == 0177) +#define WIFSIGNALED(s) (((s) & 0377) != 0 && (((s) & 0377) != 0177)) +#define WEXITSTATUS(s) (((s) >> 8) & 0377) +#define WTERMSIG(s) ((s) & 0177) +#define WSTOPSIG(s) (((s) >> 8) & 0377) + +#ifndef WCOREFLAG +#define WCOREFLAG 0200 +#endif + +#define PID_T int + +#endif /* not _POSIX_VERSION */ + +/* SVR4 uses WCOREFLG; Net 2 uses WCOREFLAG. */ +#ifndef WCOREFLAG +#ifdef WCOREFLG +#define WCOREFLAG WCOREFLG +#endif /* WCOREFLG */ +#endif /* not WCOREFLAG */ + +#ifndef WCOREDUMP +#ifdef WCOREFLAG +#define WCOREDUMP(s) ((s) & WCOREFLAG) +#else /* not WCOREFLAG */ +#define WCOREDUMP(s) (0) +#endif /* WCOREFLAG */ +#endif /* not WCOREDUMP */ + +#include "pipeline.h" + +/* Prototype */ +int run_pipeline(int, char ***, int); + +#ifdef __cplusplus +extern "C" { +#endif + +extern void c_error(const char *, const char *, const char *, + const char *); +extern void c_fatal(const char *, const char *, const char *, + const char *); +extern const char *i_to_a(int); /* from libgroff */ + +#ifdef __cplusplus +} +#endif + +static void sys_fatal(const char *); +static const char *xstrsignal(int); + + +#if defined(__MSDOS__) \ + || (defined(_WIN32) && !defined(_UWIN) && !defined(__CYGWIN__)) \ + || defined(__EMX__) + +#include +#include +#include +#include + +#include "nonposix.h" + +static const char *sh = "sh"; +static const char *cmd = "cmd"; +static const char *command = "command"; + +extern int strcasecmp(const char *, const char *); + +char *sbasename(const char *path) +{ + char *base; + const char *p1, *p2; + + p1 = path; + if ((p2 = strrchr(p1, '\\')) + || (p2 = strrchr(p1, '/')) + || (p2 = strrchr(p1, ':'))) + p1 = p2 + 1; + if ((p2 = strrchr(p1, '.')) + && ((strcasecmp(p2, ".exe") == 0) + || (strcasecmp(p2, ".com") == 0))) + ; + else + p2 = p1 + strlen(p1); + + base = malloc((size_t)(p2 - p1)); + strncpy(base, p1, p2 - p1); + *(base + (p2 - p1)) = '\0'; + + return(base); +} + +/* Get the name of the system shell */ +char *system_shell_name(void) +{ + const char *shell_name; + + /* + Use a Unixy shell if it's installed. Use SHELL if set; otherwise, + let spawnlp try to find sh; if that fails, use COMSPEC if set; if + not, try cmd.exe; if that fails, default to command.com. + */ + + if ((shell_name = getenv("SHELL")) != NULL) + ; + else if (spawnlp(_P_WAIT, sh, sh, "-c", ":", NULL) == 0) + shell_name = sh; + else if ((shell_name = getenv("COMSPEC")) != NULL) + ; + else if (spawnlp(_P_WAIT, cmd, cmd, "/c", ";", NULL) == 0) + shell_name = cmd; + else + shell_name = command; + + return sbasename(shell_name); +} + +const char *system_shell_dash_c(void) +{ + char *shell_name; + const char *dash_c; + + shell_name = system_shell_name(); + + /* Assume that if the shell name ends in 'sh', it's Unixy */ + if (strcasecmp(shell_name + strlen(shell_name) - strlen("sh"), "sh") == 0) + dash_c = "-c"; + else + dash_c = "/c"; + + free(shell_name); + return dash_c; +} + +int is_system_shell(const char *prog) +{ + int result; + char *this_prog, *system_shell; + + if (!prog) /* paranoia */ + return 0; + + this_prog = sbasename(prog); + system_shell = system_shell_name(); + + result = strcasecmp(this_prog, system_shell) == 0; + + free(this_prog); + free(system_shell); + + return result; +} + +#ifdef _WIN32 + +/* + Windows 32 doesn't have fork(), so we need to start asynchronous child + processes with spawn() rather than exec(). If there is more than one + command, i.e., a pipeline, the parent must set up each child's I/O + redirection prior to the spawn. The original stdout must be restored + before spawning the last process in the pipeline, and the original + stdin must be restored in the parent after spawning the last process + and before waiting for any of the children. +*/ + +int run_pipeline(int ncommands, char ***commands, int no_pipe) +{ + int i; + int last_input = 0; /* pacify some compilers */ + int save_stdin = 0; + int save_stdout = 0; + int ret = 0; + char err_str[BUFSIZ]; + PID_T pids[MAX_COMMANDS]; + + for (i = 0; i < ncommands; i++) { + int pdes[2]; + PID_T pid; + + /* If no_pipe is set, just run the commands in sequence + to show the version numbers */ + if (ncommands > 1 && !no_pipe) { + /* last command doesn't need a new pipe */ + if (i < ncommands - 1) { + if (pipe(pdes) < 0) { + sprintf(err_str, "%s: pipe", commands[i][0]); + sys_fatal(err_str); + } + } + /* 1st command; writer */ + if (i == 0) { + /* save stdin */ + if ((save_stdin = dup(STDIN_FILENO)) < 0) + sys_fatal("dup stdin"); + /* save stdout */ + if ((save_stdout = dup(STDOUT_FILENO)) < 0) + sys_fatal("dup stdout"); + + /* connect stdout to write end of pipe */ + if (dup2(pdes[1], STDOUT_FILENO) < 0) { + sprintf(err_str, "%s: dup2(stdout)", commands[i][0]); + sys_fatal(err_str); + } + if (close(pdes[1]) < 0) { + sprintf(err_str, "%s: close(pipe[WRITE])", commands[i][0]); + sys_fatal(err_str); + } + /* + Save the read end of the pipe so that it can be connected to + stdin of the next program in the pipeline during the next + pass through the loop. + */ + last_input = pdes[0]; + } + /* reader and writer */ + else if (i < ncommands - 1) { + /* connect stdin to read end of last pipe */ + if (dup2(last_input, STDIN_FILENO) < 0) { + sprintf(err_str, " %s: dup2(stdin)", commands[i][0]); + sys_fatal(err_str); + } + if (close(last_input) < 0) { + sprintf(err_str, "%s: close(last_input)", commands[i][0]); + sys_fatal(err_str); + } + /* connect stdout to write end of new pipe */ + if (dup2(pdes[1], STDOUT_FILENO) < 0) { + sprintf(err_str, "%s: dup2(stdout)", commands[i][0]); + sys_fatal(err_str); + } + if (close(pdes[1]) < 0) { + sprintf(err_str, "%s: close(pipe[WRITE])", commands[i][0]); + sys_fatal(err_str); + } + last_input = pdes[0]; + } + /* last command; reader */ + else { + /* connect stdin to read end of last pipe */ + if (dup2(last_input, STDIN_FILENO) < 0) { + sprintf(err_str, "%s: dup2(stdin)", commands[i][0]); + sys_fatal(err_str); + } + if (close(last_input) < 0) { + sprintf(err_str, "%s: close(last_input)", commands[i][0]); + sys_fatal(err_str); + } + /* restore original stdout */ + if (dup2(save_stdout, STDOUT_FILENO) < 0) { + sprintf(err_str, "%s: dup2(save_stdout))", commands[i][0]); + sys_fatal(err_str); + } + /* close stdout copy */ + if (close(save_stdout) < 0) { + sprintf(err_str, "%s: close(save_stdout)", commands[i][0]); + sys_fatal(err_str); + } + } + } + if ((pid = spawnvp(_P_NOWAIT, commands[i][0], commands[i])) < 0) { + c_error("couldn't exec %1: %2", + commands[i][0], strerror(errno), (char *)0); + _exit(EXEC_FAILED_EXIT_STATUS); + } + pids[i] = pid; + } + + if (ncommands > 1 && !no_pipe) { + /* restore original stdin if it was redirected */ + if (dup2(save_stdin, STDIN_FILENO) < 0) { + sprintf(err_str, "dup2(save_stdin))"); + sys_fatal(err_str); + } + /* close stdin copy */ + if (close(save_stdin) < 0) { + sprintf(err_str, "close(save_stdin)"); + sys_fatal(err_str); + } + } + + for (i = 0; i < ncommands; i++) { + int status; + PID_T pid; + + pid = pids[i]; + if ((pid = WAIT(&status, pid, _WAIT_CHILD)) < 0) { + sprintf(err_str, "%s: wait", commands[i][0]); + sys_fatal(err_str); + } + else if (status != 0) + ret |= 1; + } + return ret; +} + +#else /* not _WIN32 */ + +/* MS-DOS doesn't have 'fork', so we need to simulate the pipe by + running the programs in sequence with standard streams redirected to + and from temporary files. +*/ + + +/* A signal handler that just records that a signal has happened. */ +static int child_interrupted; + +static RETSIGTYPE signal_catcher(int signo) +{ + child_interrupted++; +} + +int run_pipeline(int ncommands, char ***commands, int no_pipe) +{ + int save_stdin = dup(0); + int save_stdout = dup(1); + char *tmpfiles[2]; + int infile = 0; + int outfile = 1; + int i, f, ret = 0; + + /* Choose names for a pair of temporary files to implement the pipeline. + Microsoft's 'tempnam' uses the directory specified by 'getenv("TMP")' + if it exists; in case it doesn't, try the GROFF alternatives, or + 'getenv("TEMP")' as last resort -- at least one of these had better + be set, since Microsoft's default has a high probability of failure. */ + char *tmpdir; + if ((tmpdir = getenv("GROFF_TMPDIR")) == NULL + && (tmpdir = getenv("TMPDIR")) == NULL) + tmpdir = getenv("TEMP"); + + /* Don't use 'tmpnam' here: Microsoft's implementation yields unusable + file names if current directory is on network share with read-only + root. */ + tmpfiles[0] = tempnam(tmpdir, NULL); + tmpfiles[1] = tempnam(tmpdir, NULL); + + for (i = 0; i < ncommands; i++) { + int exit_status; + RETSIGTYPE (*prev_handler)(int); + + if (i && !no_pipe) { + /* redirect stdin from temp file */ + f = open(tmpfiles[infile], O_RDONLY|O_BINARY, 0666); + if (f < 0) + sys_fatal("open stdin"); + if (dup2(f, 0) < 0) + sys_fatal("dup2 stdin"); + if (close(f) < 0) + sys_fatal("close stdin"); + } + if ((i < ncommands - 1) && !no_pipe) { + /* redirect stdout to temp file */ + f = open(tmpfiles[outfile], O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666); + if (f < 0) + sys_fatal("open stdout"); + if (dup2(f, 1) < 0) + sys_fatal("dup2 stdout"); + if (close(f) < 0) + sys_fatal("close stdout"); + } + else if (dup2(save_stdout, 1) < 0) + sys_fatal("restore stdout"); + + /* run the program */ + child_interrupted = 0; + prev_handler = signal(SIGINT, signal_catcher); + exit_status = spawnvp(P_WAIT, commands[i][0], commands[i]); + signal(SIGINT, prev_handler); + if (child_interrupted) { + c_error("%1: Interrupted", commands[i][0], (char *)0, (char *)0); + ret |= 2; + } + else if (exit_status < 0) { + c_error("couldn't exec %1: %2", + commands[i][0], strerror(errno), (char *)0); + ret |= 4; + } + if (exit_status != 0) + ret |= 1; + /* There's no sense to continue with the pipe if one of the + programs has ended abnormally, is there? */ + if (ret != 0) + break; + /* swap temp files: make output of this program be input for the next */ + infile = 1 - infile; + outfile = 1 - outfile; + } + if (dup2(save_stdin, 0) < 0) + sys_fatal("restore stdin"); + unlink(tmpfiles[0]); + unlink(tmpfiles[1]); + return ret; +} + +#endif /* not _WIN32 */ + +#else /* not __MSDOS__, not _WIN32 */ + +int run_pipeline(int ncommands, char ***commands, int no_pipe) +{ + int i; + int last_input = 0; + PID_T pids[MAX_COMMANDS]; + int ret = 0; + int proc_count = ncommands; + + for (i = 0; i < ncommands; i++) { + int pdes[2]; + PID_T pid; + + if ((i != ncommands - 1) && !no_pipe) { + if (pipe(pdes) < 0) + sys_fatal("pipe"); + } + pid = fork(); + if (pid < 0) + sys_fatal("fork"); + if (pid == 0) { + /* child */ + if (last_input != 0) { + if (close(0) < 0) + sys_fatal("close"); + if (dup(last_input) < 0) + sys_fatal("dup"); + if (close(last_input) < 0) + sys_fatal("close"); + } + if ((i != ncommands - 1) && !no_pipe) { + if (close(1) < 0) + sys_fatal("close"); + if (dup(pdes[1]) < 0) + sys_fatal("dup"); + if (close(pdes[1]) < 0) + sys_fatal("close"); + if (close(pdes[0])) + sys_fatal("close"); + } + execvp(commands[i][0], commands[i]); + c_error("couldn't exec %1: %2", + commands[i][0], strerror(errno), (char *)0); + _exit(EXEC_FAILED_EXIT_STATUS); + } + /* in the parent */ + if (last_input != 0) { + if (close(last_input) < 0) + sys_fatal("close"); + } + if ((i != ncommands - 1) && !no_pipe) { + if (close(pdes[1]) < 0) + sys_fatal("close"); + last_input = pdes[0]; + } + pids[i] = pid; + } + while (proc_count > 0) { + int status; + PID_T pid = wait(&status); + + if (pid < 0) + sys_fatal("wait"); + for (i = 0; i < ncommands; i++) + if (pids[i] == pid) { + pids[i] = -1; + --proc_count; + if (WIFSIGNALED(status)) { + int sig = WTERMSIG(status); +#ifdef SIGPIPE + if (sig == SIGPIPE) { + if (i == ncommands - 1) { + /* This works around a problem that occurred when using the + rerasterize action in gxditview. What seemed to be + happening (on SunOS 4.1.1) was that pclose() closed the + pipe and waited for groff, gtroff got a SIGPIPE, but + gpic blocked writing to gtroff, and so groff blocked + waiting for gpic and gxditview blocked waiting for + groff. I don't understand why gpic wasn't getting a + SIGPIPE. */ + int j; + + for (j = 0; j < ncommands; j++) + if (pids[j] > 0) + (void)kill(pids[j], SIGPIPE); + } + } + else +#endif /* SIGPIPE */ + { + c_error("%1: %2%3", + commands[i][0], + xstrsignal(sig), + WCOREDUMP(status) ? " (core dumped)" : ""); + ret |= 2; + } + } + else if (WIFEXITED(status)) { + int exit_status = WEXITSTATUS(status); + + if (exit_status == EXEC_FAILED_EXIT_STATUS) + ret |= 4; + else if (exit_status != 0) + ret |= 1; + } + else + c_error("unexpected status %1", i_to_a(status), (char *)0, + (char *)0); + break; + } + } + return ret; +} + +#endif /* not __MSDOS__, not _WIN32 */ + +static void sys_fatal(const char *s) +{ + c_fatal("%1: %2", s, strerror(errno), (char *)0); +} + +static const char *xstrsignal(int n) +{ + static char buf[sizeof("Signal ") + 1 + sizeof(int) * 3]; + +#ifdef NSIG +#if HAVE_DECL_STRSIGNAL + if (n >= 0 && n < NSIG && strsignal(n) != 0) + return strsignal(n); +#else +#if HAVE_DECL_SYS_SIGLIST + if (n >= 0 && n < NSIG && sys_siglist[n] != 0) + return sys_siglist[n]; +#endif /* HAVE_DECL_SYS_SIGLIST */ +#endif /* HAVE_DECL_STRSIGNAL */ +#endif /* NSIG */ + sprintf(buf, "Signal %d", n); + return buf; +} + +// Local Variables: +// fill-column: 72 +// mode: C +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/roff/groff/pipeline.h b/src/roff/groff/pipeline.h new file mode 100644 index 0000000..17c02a6 --- /dev/null +++ b/src/roff/groff/pipeline.h @@ -0,0 +1,30 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#ifdef __cplusplus +extern "C" { + int run_pipeline(int, char ***, int); +} +#endif + +/* run_pipeline can handle at most this many commands, + see the const numbers in groff.cpp */ +#define MAX_COMMANDS 15 + +/* Children exit with this status if execvp fails. */ +#define EXEC_FAILED_EXIT_STATUS 0xff diff --git a/src/roff/groff/tests/ab_works.sh b/src/roff/groff/tests/ab_works.sh new file mode 100755 index 0000000..b353837 --- /dev/null +++ b/src/roff/groff/tests/ab_works.sh @@ -0,0 +1,46 @@ +#!/bin/sh +# +# Copyright (C) 2021-2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +# Verify exit status and regression-test Savannah #60782. +# +# We don't test the X11 devices because groff launches an X client, +# which has to be killed. Using "-z" to avoid this masks the bug. + +# Keep preconv from being run. +unset GROFF_ENCODING + +for d in ascii cp1047 dvi html latin1 lbp lj4 pdf ps utf8 +do + echo "verifying exit status of .ab request using $d device" >&2 + printf '.ab\n' | "$groff" -Z -T$d + test $? -eq 1 || exit 1 +done + +echo "verifying empty output of .ab request with no arguments" >&2 +OUT=$(printf '.ab\n' | "$groff" -Z -Tascii 2>&1) +test "$OUT" = "" || exit 1 + +echo "verifying that arguments to .ab request go to stderr" >&2 +OUT=$(printf '.ab foo\n' | "$groff" -Z -Tascii 2>&1 > /dev/null) +test "$OUT" = "foo" || exit 1 + +# vim:set autoindent expandtab shiftwidth=2 tabstop=2 textwidth=72: diff --git a/src/roff/groff/tests/adjustment_works.sh b/src/roff/groff/tests/adjustment_works.sh new file mode 100755 index 0000000..e4cd65d --- /dev/null +++ b/src/roff/groff/tests/adjustment_works.sh @@ -0,0 +1,92 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +set -e + +DOC='.pl 1v +.ll 9n +foo bar\p +.na +foo bar\p +.ad l +foo bar\p +.na +foo bar\p +.ad b +foo bar\p +.na +foo bar\p +.ad c +foo bar\p +.na +foo bar\p +.ad r +foo bar\p +.na +foo bar\p +.ad +foo bar\p +.ad b +.ad 100 +foo bar\p' + +OUTPUT=$(echo "$DOC" | "$groff" -Tascii) +B='foo bar' # 3 spaces +L='foo bar' # left or off +C=' foo bar' # trailing space truncated +R=' foo bar' # 2 leading spaces + +echo "verifying default adjustment mode 'b'" >&2 +echo "$OUTPUT" | sed -n '1p' | grep -Fqx "$B" + +echo "verifying that .na works" >&2 +echo "$OUTPUT" | sed -n '2p' | grep -Fqx "$L" + +echo "verifying adjustment mode 'l'" >&2 +echo "$OUTPUT" | sed -n '3p' | grep -Fqx "$L" + +echo "verifying that .na works after '.ad l'" >&2 +echo "$OUTPUT" | sed -n '4p' | grep -Fqx "$L" + +echo "verifying adjustment mode 'b'" >&2 +echo "$OUTPUT" | sed -n '5p' | grep -Fqx "$B" + +echo "verifying that .na works after '.ad b'" >&2 +echo "$OUTPUT" | sed -n '6p' | grep -Fqx "$L" + +echo "verifying adjustment mode 'c'" >&2 +echo "$OUTPUT" | sed -n '7p' | grep -Fqx "$C" + +echo "verifying that .na works after '.ad c'" >&2 +echo "$OUTPUT" | sed -n '8p' | grep -Fqx "$L" + +echo "verifying adjustment mode 'r'" >&2 +echo "$OUTPUT" | sed -n '9p' | grep -Fqx "$R" + +echo "verifying that .na works after '.ad r'" >&2 +echo "$OUTPUT" | sed -n '10p' | grep -Fqx "$L" + +echo "verifying that '.ad' restores previous adjustment mode" >&2 +echo "$OUTPUT" | sed -n '11p' | grep -Fqx "$R" + +echo "verifying that out-of-range adjustment mode 100 is ignored" >&2 +echo "$OUTPUT" | sed -n '12p' | grep -Fqx "$B" diff --git a/src/roff/groff/tests/artifacts/HONEYPOT b/src/roff/groff/tests/artifacts/HONEYPOT new file mode 100644 index 0000000..51a57dd --- /dev/null +++ b/src/roff/groff/tests/artifacts/HONEYPOT @@ -0,0 +1,15 @@ +name HONEYPOT +spacewidth 24 +charset +a 0 0 77 +b 0 0 79 +d 0 0 76 +e 0 0 82 +i 0 0 105 +l 0 0 65 +m 0 0 109 +o 0 0 86 +r 0 0 73 +s 0 0 115 +w 0 0 69 +y 0 0 121 diff --git a/src/roff/groff/tests/artifacts/devascii/README b/src/roff/groff/tests/artifacts/devascii/README new file mode 100644 index 0000000..d89ba03 --- /dev/null +++ b/src/roff/groff/tests/artifacts/devascii/README @@ -0,0 +1 @@ +This directory is intentionally empty (apart from this file). diff --git a/src/roff/groff/tests/break_zero-length_output_line_sanely.sh b/src/roff/groff/tests/break_zero-length_output_line_sanely.sh new file mode 100755 index 0000000..8d6deb0 --- /dev/null +++ b/src/roff/groff/tests/break_zero-length_output_line_sanely.sh @@ -0,0 +1,43 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +set -e + +# Do not core dump when attempting to distribute a space amount of zero +# if someone sets the line length to zero. See Savannah #61089. +# Reproducer courtesy of John Gardner. + +INPUT='.de _ +. na +. nh +. ll 0 +. di A +\&\\$1 +. di +. br +.. +._ " XYZ" +.A +' + +OUTPUT=$(printf "%s" "$INPUT" | "$groff" -Tascii) +echo "$OUTPUT" | grep -qx XYZ diff --git a/src/roff/groff/tests/device_control_escapes_express_basic_latin.sh b/src/roff/groff/tests/device_control_escapes_express_basic_latin.sh new file mode 100755 index 0000000..6418913 --- /dev/null +++ b/src/roff/groff/tests/device_control_escapes_express_basic_latin.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" +fail= + +# Confirm translation of a groff special character escape sequence to a +# basic Latin character when used in a device control escape sequence. +# +# $1 is the special character escape _without_ the leading backslash. +# $2 is the expected output character _shell-quoted as necessary_. +# $3 is a human-readable glyph description for the test log. +# $4 is the groff -T device name under test. +check_char () { + sc=$1 + output=$2 + description=$3 + device=$4 + printf 'checking conversion of \\%s to %s (%s) on device %s' \ + "$sc" "$output" "$description" "$device" >&2 + if ! printf '\\X#\\%s %s#\n' "$sc" "$desc" | "$groff" -T$device -Z \ + | grep -Fqx 'x X '$output' ' + then + printf '...FAILED' >&2 + fail=yes + fi + printf '\n' >&2 +} + +for device in utf8 html +do + check_char - - "minus sign" $device + check_char '[aq]' "'" "neutral apostrophe" $device + check_char '[dq]' '"' "double quote" $device + check_char '[ga]' '`' "grave accent" $device + check_char '[ha]' ^ "caret/hat" $device + check_char '[rs]' '\' "reverse solidus/backslash" $device + check_char '[ti]' '~' "tilde" $device +done + +test -z "$fail" || exit 1 + +# vim:set autoindent expandtab shiftwidth=2 tabstop=2 textwidth=72: diff --git a/src/roff/groff/tests/do_not_loop_infinitely_when_breaking_cjk.sh b/src/roff/groff/tests/do_not_loop_infinitely_when_breaking_cjk.sh new file mode 100755 index 0000000..4f4a12a --- /dev/null +++ b/src/roff/groff/tests/do_not_loop_infinitely_when_breaking_cjk.sh @@ -0,0 +1,29 @@ +#!/bin/sh +# +# Copyright (C) 2020 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +set -e + +DOC='ン +ああAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +' + +echo "$DOC" | "$groff" -D utf8 -Tutf8 -mja diff --git a/src/roff/groff/tests/dot-cp_register_works.sh b/src/roff/groff/tests/dot-cp_register_works.sh new file mode 100755 index 0000000..ffbb402 --- /dev/null +++ b/src/roff/groff/tests/dot-cp_register_works.sh @@ -0,0 +1,48 @@ +#!/bin/sh +# +# Copyright (C) 2020 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +DOC='.pl 1v +A +.do if 1 \n[.cp] \" Get initial compatibility state (depends on -C). +B +.do if 1 \n[.cp] \" Did observing the state change it? +.cp 1 +C +.do if 1 \n[.cp] \" Saved compatibility state should be 1 now. +.cp 0 +D +.do if 1 \n[.cp] \" Verify 1->0 transition. +.cp 1 +E +.do if 1 \n[.cp] \" Verify 0->1 transition. +.cp 0 +F +.if !\n[.C] \n[.cp] \" Outside of .do context, should return -1. +' + +set -e + +printf "%s" "$DOC" | "$groff" -Tascii \ + | grep -x "A 0 B 0 C 1 D 0 E 1 F -1" + +printf "%s" "$DOC" | "$groff" -C -Tascii \ + | grep -x "A 1 B 1 C 1 D 0 E 1 F -1" diff --git a/src/roff/groff/tests/dot-nm_register_works.sh b/src/roff/groff/tests/dot-nm_register_works.sh new file mode 100755 index 0000000..809bbd3 --- /dev/null +++ b/src/roff/groff/tests/dot-nm_register_works.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +DOC='\ +.nf +foo (\n[.nm]) +.nm 1 +bar (\n[.nm]) +.nn +baz (\n[.nm]) +.nm +qux (\n[.nm]) +.fi +' + +set -e + +printf '%s' "$DOC" | "$groff" -T utf8 | grep -Fqx 'foo (0)' +printf '%s' "$DOC" | "$groff" -T utf8 | grep -Fqx ' 1 bar (1)' +printf '%s' "$DOC" | "$groff" -T utf8 | grep -Fqx 'baz (1)' +printf '%s' "$DOC" | "$groff" -T utf8 | grep -Fqx 'qux (0)' diff --git a/src/roff/groff/tests/dot-nn_register_works.sh b/src/roff/groff/tests/dot-nn_register_works.sh new file mode 100755 index 0000000..0998cb0 --- /dev/null +++ b/src/roff/groff/tests/dot-nn_register_works.sh @@ -0,0 +1,77 @@ +#!/bin/sh +# +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +# Unit test .nn register. + +fail= + +wail () { + echo ...FAILED >&2 + fail=YES +} + +input='.ec @ +.de is-numbered +. nop This line +. ie (@@n[.nm] & (1-@@n[.nn])) IS +. el ISN'"'"'T +. nop numbered. +. br +.. +Test line numbering. +.is-numbered +.nm 1 +.nn 2 +.is-numbered +.is-numbered +.is-numbered +.nm +.is-numbered +.pl @n[nl]u' + +# Apply line numbers to the output externally for easy grepping. +output=$(echo "$input" | $groff -Tascii | nl) +echo "$output" + +echo "verifying that line 1 isn't numbered" >&2 +echo "$output" | \ + grep -Eq "[[:space:]]+1[[:space:]]+Test line numbering\." || wail + +echo "verifying that line 2 isn't numbered" >&2 +echo "$output" | \ + grep -Eq "[[:space:]]+2[[:space:]]+This line ISN'T" || wail + +echo "verifying that line 3 isn't numbered" >&2 +echo "$output" | \ + grep -Eq "[[:space:]]+3[[:space:]]+This line ISN'T" || wail + +echo "verifying that line 4 is numbered" >&2 +echo "$output" | \ + grep -Eq "[[:space:]]+4[[:space:]]+1 +This line IS numbered" || wail + +echo "verifying that line 5 isn't numbered" >&2 +echo "$output" | \ + grep -Eq "[[:space:]]+5[[:space:]]+This line ISN'T" || wail + +test -z "$fail" + +# vim:set autoindent expandtab shiftwidth=2 tabstop=2 textwidth=72: diff --git a/src/roff/groff/tests/evc_produces_no_output_if_invalid.sh b/src/roff/groff/tests/evc_produces_no_output_if_invalid.sh new file mode 100755 index 0000000..47b0d1d --- /dev/null +++ b/src/roff/groff/tests/evc_produces_no_output_if_invalid.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +# Regression-test Savannah #60913. + +test -z "$(printf '.evc foo bar\n' | "$groff")" diff --git a/src/roff/groff/tests/fp_should_not_traverse_directories.sh b/src/roff/groff/tests/fp_should_not_traverse_directories.sh new file mode 100755 index 0000000..f60f42f --- /dev/null +++ b/src/roff/groff/tests/fp_should_not_traverse_directories.sh @@ -0,0 +1,63 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +# Regression-test Savannah #61424. +# +# The `fp` request should not be able to access font description files +# outside of the device and font description search path (configurable +# with the -F option and GROFF_FONT_PATH environment variable). +# +# An absolute file name _won't_ work: it gets dev\*[.T]/ stuck on the +# front of it by libgroff. +# +# Locate directory containing our test artifacts. +artifact_dir= +base=src/roff/groff/tests +device=artifacts + +for buildroot in . .. ../.. +do + d=$buildroot/$base/$device + if [ -d "$d" ] + then + artifact_dir=$d + break + fi +done + +# If we can't find it, we can't test. +test -z "$artifact_dir" && exit 77 # skip + +input='.fp 5 ../HONEYPOT +.ft 5 +word +.fp 5 HONEYPOT ../HONEYPOT +.ft HONEYPOT +.br +my word is able +.pl \n[nl]u' + +output=$(printf "%s" "$input" | "$groff" -b -ww -F "$artifact_dir" \ + -Tascii) +echo "$output" | grep -Fx word + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/roff/groff/tests/handle_special_input_code_points.sh b/src/roff/groff/tests/handle_special_input_code_points.sh new file mode 100755 index 0000000..c996150 --- /dev/null +++ b/src/roff/groff/tests/handle_special_input_code_points.sh @@ -0,0 +1,47 @@ +#!/bin/sh +# +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +# Regression-test Savannah #58962. + +# Keep preconv from being run. +unset GROFF_ENCODING + +input='.if " "\~" .tm input no-break space matches \\~ +.if "­"\%" .tm input soft hyphen matches \\%' + +fail= + +wail () { + echo "...FAILED" + fail=yes +} + +output=$(printf "%s\n" "$input" | "$groff" -Z 2>&1) +echo "$output" + +printf "checking that input no-break space is mapped to \\~\n" +echo "$output" | grep -qx 'input no-break space matches \\~' || wail + +printf "checking that input soft hyphen is mapped to \\%%\n" +echo "$output" | grep -qx 'input soft hyphen matches \\%' || wail + +test -z "$fail" diff --git a/src/roff/groff/tests/html_works_with_grn_and_eqn.sh b/src/roff/groff/tests/html_works_with_grn_and_eqn.sh new file mode 100755 index 0000000..e070944 --- /dev/null +++ b/src/roff/groff/tests/html_works_with_grn_and_eqn.sh @@ -0,0 +1,46 @@ +#!/bin/sh +# +# Copyright (C) 2020 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +# Keep this list of programs in sync with GROFF_CHECK_GROHTML_PROGRAMS +# in m4/groff.m4. +for cmd in pnmcrop pnmcut pnmtopng pnmtops psselect +do + if ! command -v $cmd >/dev/null + then + echo "cannot locate '$cmd' command; skipping test" >&2 + exit 77 # skip + fi +done + +# Commit c71b4ef4aa provoked an infinite loop in post-grohtml with these +# preprocessors. + +input='.EQ +gsize 12 +delim $$ +.EN +.pp +.pp +The faster clocks are $ PN $' + +output=$("$groff" -b -ww -Thtml -eg -me "$input") +test -n "$output" diff --git a/src/roff/groff/tests/initialization_is_quiet.sh b/src/roff/groff/tests/initialization_is_quiet.sh new file mode 100755 index 0000000..38ac81f --- /dev/null +++ b/src/roff/groff/tests/initialization_is_quiet.sh @@ -0,0 +1,59 @@ +#!/bin/sh +# +# Copyright (C) 2021-2023 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +fail= + +wail () { + echo ...FAILED >&2 + fail=YES +} + +# Regression-test Savannah #60874. +# +# groff should start up in any supported locale, in compatibility mode +# or not, without producing diagnostics. + +# Keep preconv from being run. +# +# The "unset" in Solaris /usr/xpg4/bin/sh can actually fail. +if ! unset GROFF_ENCODING +then + echo "unable to clear environment; skipping" >&2 + exit 77 +fi + +for compat in "" " -C" +do + for locale in cs de en fr it ja sv zh + do + echo testing \"-m $locale$compat\" >&2 + output=$("$groff" -ww -m $locale$compat -a /dev/null) + error=$("$groff" -ww -m $locale$compat -z &1) + test -n "$error" && echo "$error" + test -n "$output" && echo "$output" + test -n "$error$output" && wail + done +done + +test -z "$fail" + +# vim:set autoindent expandtab shiftwidth=4 tabstop=4 textwidth=72: diff --git a/src/roff/groff/tests/localization_works.sh b/src/roff/groff/tests/localization_works.sh new file mode 100755 index 0000000..0585259 --- /dev/null +++ b/src/roff/groff/tests/localization_works.sh @@ -0,0 +1,61 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +set -e + +DOC='\*[locale]' + +echo "testing default localization (English)" >&2 +OUTPUT=$(echo "$DOC" | "$groff" -Tascii) +echo "$OUTPUT" | grep -qx english + +echo "testing Czech localization" >&2 +OUTPUT=$(echo "$DOC" | "$groff" -Tascii -m cs) +echo "$OUTPUT" | grep -qx czech + +echo "testing German localization" >&2 +OUTPUT=$(echo "$DOC" | "$groff" -Tascii -m de) +echo "$OUTPUT" | grep -qx german + +echo "testing English localization" >&2 +OUTPUT=$(echo "$DOC" | "$groff" -Tascii -m en) +echo "$OUTPUT" | grep -qx english + +echo "testing French localization" >&2 +OUTPUT=$(echo "$DOC" | "$groff" -Tascii -m fr) +echo "$OUTPUT" | grep -qx french + +echo "testing Italian localization" >&2 +OUTPUT=$(echo "$DOC" | "$groff" -Tascii -m it) +echo "$OUTPUT" | grep -qx italian + +echo "testing Japanese localization" >&2 +OUTPUT=$(echo "$DOC" | "$groff" -Tascii -m ja) +echo "$OUTPUT" | grep -qx japanese + +echo "testing Swedish localization" >&2 +OUTPUT=$(echo "$DOC" | "$groff" -Tascii -m sv) +echo "$OUTPUT" | grep -qx swedish + +echo "testing Chinese localization" >&2 +OUTPUT=$(echo "$DOC" | "$groff" -Tascii -m zh) +echo "$OUTPUT" | grep -qx chinese diff --git a/src/roff/groff/tests/msoquiet_works.sh b/src/roff/groff/tests/msoquiet_works.sh new file mode 100755 index 0000000..80c085a --- /dev/null +++ b/src/roff/groff/tests/msoquiet_works.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +set -e + +# Keep preconv from being run. +unset GROFF_ENCODING + +DOC='.msoquiet nonexistent' + +OUTPUT=$(echo "$DOC" | "$groff" -Tascii 2>&1) +echo "$OUTPUT" + +echo "testing that .msoquiet of nonexistent file produces no warning" \ + >&2 +test -z "$OUTPUT" diff --git a/src/roff/groff/tests/on_latin1_device_oq_is_0x27.sh b/src/roff/groff/tests/on_latin1_device_oq_is_0x27.sh new file mode 100755 index 0000000..b2c17bc --- /dev/null +++ b/src/roff/groff/tests/on_latin1_device_oq_is_0x27.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# +# Copyright (C) 2019-2020 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +# This test fails with some versions of GNU Bash, such as 3.2; the here +# document nested within a command substitution confuses it. +# +# https://lists.gnu.org/archive/html/bug-bash/2017-02/msg00024.html + +expected="' = '" +actual=$(printf '.pl 1v\n\\[oq] = '"'"'\n' | "$groff" -Tlatin1) +test "$actual" = "$expected" diff --git a/src/roff/groff/tests/output_driver_C_and_G_options_work.sh b/src/roff/groff/tests/output_driver_C_and_G_options_work.sh new file mode 100755 index 0000000..2bb1cc3 --- /dev/null +++ b/src/roff/groff/tests/output_driver_C_and_G_options_work.sh @@ -0,0 +1,50 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +# Feed groff empty input documents and verify that expected comments +# emerge from the output drivers. + +# Expect Creator: and CreationDate: comments. +echo "testing presence of Creator: comment in HTML output" >&2 +echo | "$groff" -Thtml | grep -Fq ' state %d pushed\n", n->issue_no); + fflush(stderr); + } +#endif + sp = new stack(n, sp); + } +} + +void mtsm::pop_state() +{ + if (is_html) { +#if defined(DEBUGGING) + if (debug_state) { + fprintf(stderr, "--> state popped\n"); + fflush(stderr); + } +#endif + if (sp == 0) + fatal("empty state machine stack"); + sp->state = 0; + stack *t = sp; + sp = sp->next; + t->next = 0; + delete t; + } +} + +/* + * inherit - scan the stack and collects inherited values. + */ + +void mtsm::inherit(statem *s, int reset_bool) +{ + if (sp && sp->state) { + if (s->units_values[MTSM_IN].is_known + && sp->state->units_values[MTSM_IN].is_known) + s->units_values[MTSM_IN].value += sp->state->units_values[MTSM_IN].value; + s->update(sp->state, s, MTSM_FI); + s->update(sp->state, s, MTSM_LL); + s->update(sp->state, s, MTSM_PO); + s->update(sp->state, s, MTSM_RJ); + s->update(sp->state, s, MTSM_TA); + s->update(sp->state, s, MTSM_TI); + s->update(sp->state, s, MTSM_CE); + if (sp->state->bool_values[MTSM_BR].is_known + && sp->state->bool_values[MTSM_BR].value) { + if (reset_bool) + sp->state->bool_values[MTSM_BR].set(0); + s->bool_values[MTSM_BR].set(1); +#if defined(DEBUGGING) + if (debug_state) + fprintf(stderr, "inherited br from pushed state %d\n", + sp->state->issue_no); +#endif + } + else if (s->bool_values[MTSM_BR].is_known + && s->bool_values[MTSM_BR].value) + if (! s->int_values[MTSM_CE].is_known) + s->bool_values[MTSM_BR].unset(); + if (sp->state->bool_values[MTSM_EOL].is_known + && sp->state->bool_values[MTSM_EOL].value) { + if (reset_bool) + sp->state->bool_values[MTSM_EOL].set(0); + s->bool_values[MTSM_EOL].set(1); + } + } +} + +void mtsm::flush(FILE *fp, statem *s, string tag_list) +{ + if (is_html && s) { + inherit(s, 1); + driver->flush(fp, s); + // Set rj, ce, ti to unknown if they were known and + // we have seen an eol or br. This ensures that these values + // are emitted during the next glyph (as they step from n..0 + // at each newline). + if ((driver->bool_values[MTSM_EOL].is_known + && driver->bool_values[MTSM_EOL].value) + || (driver->bool_values[MTSM_BR].is_known + && driver->bool_values[MTSM_BR].value)) { + if (driver->units_values[MTSM_TI].is_known) + driver->units_values[MTSM_TI].is_known = 0; + if (driver->int_values[MTSM_RJ].is_known + && driver->int_values[MTSM_RJ].value > 0) + driver->int_values[MTSM_RJ].is_known = 0; + if (driver->int_values[MTSM_CE].is_known + && driver->int_values[MTSM_CE].value > 0) + driver->int_values[MTSM_CE].is_known = 0; + } + // reset the boolean values + driver->bool_values[MTSM_BR].set(0); + driver->bool_values[MTSM_EOL].set(0); + // reset space value + driver->int_values[MTSM_SP].set(0); + // lastly write out any direct tag entries + if (tag_list != string("")) { + string t = tag_list + '\0'; + fputs(t.contents(), fp); + } + } +} + +/* + * display_state - dump out a synopsis of the state to stderr. + */ + +void statem::display_state() +{ + fprintf(stderr, " "); + fflush(stderr); +} + +int mtsm::has_changed(int_value_state t, statem *s) +{ + return driver->int_values[t].differs(s->int_values[t]); +} + +int mtsm::has_changed(units_value_state t, statem *s) +{ + return driver->units_values[t].differs(s->units_values[t]); +} + +int mtsm::has_changed(bool_value_state t, statem *s) +{ + return driver->bool_values[t].differs(s->bool_values[t]); +} + +int mtsm::has_changed(string_value_state t, statem *s) +{ + return driver->string_values[t].differs(s->string_values[t]); +} + +int mtsm::changed(statem *s) +{ + if (s == 0 || !is_html) + return 0; + s = new statem(s); + inherit(s, 0); + int result = has_changed(MTSM_EOL, s) + || has_changed(MTSM_BR, s) + || has_changed(MTSM_FI, s) + || has_changed(MTSM_IN, s) + || has_changed(MTSM_LL, s) + || has_changed(MTSM_PO, s) + || has_changed(MTSM_RJ, s) + || has_changed(MTSM_SP, s) + || has_changed(MTSM_TA, s) + || has_changed(MTSM_CE, s); + delete s; + return result; +} + +void mtsm::add_tag(FILE *fp, string s) +{ + fflush(fp); + s += '\0'; + fputs(s.contents(), fp); +} + +/* + * state_set class + */ + +state_set::state_set() +: boolset(0), intset(0), unitsset(0), stringset(0) +{ +} + +state_set::~state_set() +{ +} + +void state_set::incl(bool_value_state b) +{ + boolset |= 1 << (int)b; +} + +void state_set::incl(int_value_state i) +{ + intset |= 1 << (int)i; +} + +void state_set::incl(units_value_state u) +{ + unitsset |= 1 << (int)u; +} + +void state_set::incl(string_value_state s) +{ + stringset |= 1 << (int)s; +} + +void state_set::excl(bool_value_state b) +{ + boolset &= ~(1 << (int)b); +} + +void state_set::excl(int_value_state i) +{ + intset &= ~(1 << (int)i); +} + +void state_set::excl(units_value_state u) +{ + unitsset &= ~(1 << (int)u); +} + +void state_set::excl(string_value_state s) +{ + stringset &= ~(1 << (int)s); +} + +int state_set::is_in(bool_value_state b) +{ + return (boolset & (1 << (int)b)) != 0; +} + +int state_set::is_in(int_value_state i) +{ + return (intset & (1 << (int)i)) != 0; +} + +int state_set::is_in(units_value_state u) +{ + return (unitsset & (1 << (int)u)) != 0; +} + +int state_set::is_in(string_value_state s) +{ + return (stringset & (1 << (int)s)) != 0; +} + +void state_set::add(units_value_state, int n) +{ + unitsset += n; +} + +units state_set::val(units_value_state) +{ + return unitsset; +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/roff/troff/mtsm.h b/src/roff/troff/mtsm.h new file mode 100644 index 0000000..cfca73d --- /dev/null +++ b/src/roff/troff/mtsm.h @@ -0,0 +1,165 @@ +// -*- C++ -*- +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + * + * mtsm.h + * + * written by Gaius Mulley (gaius@glam.ac.uk) + * + * provides a minimal troff state machine which is necessary to + * emit meta tags for the post-grohtml device driver. + */ + +/* +This file 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 . */ + +struct int_value { + int value; + int is_known; + int_value(); + ~int_value(); + void diff(FILE *, const char *, int_value); + int differs(int_value); + void set(int); + void unset(); + void set_if_unknown(int); +}; + +struct bool_value : public int_value { + bool_value(); + ~bool_value(); + void diff(FILE *, const char *, bool_value); +}; + +struct units_value : public int_value { + units_value(); + ~units_value(); + void diff(FILE *, const char *, units_value); + int differs(units_value); + void set(hunits); +}; + +struct string_value { + string value; + int is_known; + string_value(); + ~string_value(); + void diff(FILE *, const char *, string_value); + int differs(string_value); + void set(string); + void unset(); +}; + +enum bool_value_state { + MTSM_EOL, + MTSM_BR, + LAST_BOOL +}; +enum int_value_state { + MTSM_FI, + MTSM_RJ, + MTSM_CE, + MTSM_SP, + LAST_INT +}; +enum units_value_state { + MTSM_IN, + MTSM_LL, + MTSM_PO, + MTSM_TI, + LAST_UNITS +}; +enum string_value_state { + MTSM_TA, + LAST_STRING +}; + +struct statem { +#if defined(DEBUGGING) + int issue_no; +#endif + bool_value bool_values[LAST_BOOL]; + int_value int_values[LAST_INT]; + units_value units_values[LAST_UNITS]; + string_value string_values[LAST_STRING]; + statem(); + statem(statem *); + ~statem(); + void flush(FILE *, statem *); + int changed(statem *); + void merge(statem *, statem *); + void add_tag(int_value_state, int); + void add_tag(bool_value_state); + void add_tag(units_value_state, hunits); + void add_tag(string_value_state, string); + void sub_tag_ce(); + void add_tag_if_unknown(int_value_state, int); + void add_tag_ta(); + void display_state(); + void update(statem *, statem *, int_value_state); + void update(statem *, statem *, bool_value_state); + void update(statem *, statem *, units_value_state); + void update(statem *, statem *, string_value_state); +}; + +struct stack { + stack *next; + statem *state; + stack(); + stack(statem *, stack *); + ~stack(); +}; + +class mtsm { + statem *driver; + stack *sp; + int has_changed(int_value_state, statem *); + int has_changed(bool_value_state, statem *); + int has_changed(units_value_state, statem *); + int has_changed(string_value_state, statem *); + void inherit(statem *, int); +public: + mtsm(); + ~mtsm(); + void push_state(statem *); + void pop_state(); + void flush(FILE *, statem *, string); + int changed(statem *); + void add_tag(FILE *, string); +}; + +class state_set { + int boolset; + int intset; + int unitsset; + int stringset; +public: + state_set(); + ~state_set(); + void incl(bool_value_state); + void incl(int_value_state); + void incl(units_value_state); + void incl(string_value_state); + void excl(bool_value_state); + void excl(int_value_state); + void excl(units_value_state); + void excl(string_value_state); + int is_in(bool_value_state); + int is_in(int_value_state); + int is_in(units_value_state); + int is_in(string_value_state); + void add(units_value_state, int); + units val(units_value_state); +}; diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp new file mode 100644 index 0000000..d17198d --- /dev/null +++ b/src/roff/troff/node.cpp @@ -0,0 +1,6656 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +extern int debug_state; + +#include "troff.h" + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "dictionary.h" +#include "hvunits.h" +#include "stringclass.h" +#include "mtsm.h" +#include "env.h" +#include "request.h" +#include "node.h" +#include "token.h" +#include "div.h" +#include "reg.h" +#include "font.h" +#include "charinfo.h" +#include "input.h" +#include "geometry.h" + +#include "nonposix.h" + +#ifdef _POSIX_VERSION + +#include + +#else /* not _POSIX_VERSION */ + +/* traditional Unix */ + +#define WIFEXITED(s) (((s) & 0377) == 0) +#define WEXITSTATUS(s) (((s) >> 8) & 0377) +#define WTERMSIG(s) ((s) & 0177) +#define WIFSTOPPED(s) (((s) & 0377) == 0177) +#define WSTOPSIG(s) (((s) >> 8) & 0377) +#define WIFSIGNALED(s) (((s) & 0377) != 0 && (((s) & 0377) != 0177)) + +#endif /* not _POSIX_VERSION */ + +// declarations to avoid friend name injections +class tfont; +class tfont_spec; +tfont *make_tfont(tfont_spec &); + + +/* + * how many boundaries of images have been written? Useful for + * debugging grohtml + */ + +int image_no = 0; +static int suppress_start_page = 0; + +#define STORE_WIDTH 1 + +symbol HYPHEN_SYMBOL("hy"); + +// Character used when a hyphen is inserted at a line break. +static charinfo *soft_hyphen_char; + +enum constant_space_type { + CONSTANT_SPACE_NONE, + CONSTANT_SPACE_RELATIVE, + CONSTANT_SPACE_ABSOLUTE + }; + +struct special_font_list { + int n; + special_font_list *next; +}; + +special_font_list *global_special_fonts; +static int global_ligature_mode = 1; +static int global_kern_mode = 1; + +class track_kerning_function { + int non_zero; + units min_size; + hunits min_amount; + units max_size; + hunits max_amount; +public: + track_kerning_function(); + track_kerning_function(units, hunits, units, hunits); + int operator==(const track_kerning_function &); + int operator!=(const track_kerning_function &); + hunits compute(int point_size); +}; + +struct font_lookup_info { + int position; + int requested_position; + char *requested_name; + font_lookup_info(); +}; + +font_lookup_info::font_lookup_info() : position(-1), + requested_position(-1), requested_name(0) +{ +} + +// embolden fontno when this is the current font + +struct conditional_bold { + conditional_bold *next; + int fontno; + hunits offset; + conditional_bold(int, hunits, conditional_bold * = 0); +}; + +class font_info { + tfont *last_tfont; + int number; + font_size last_size; + int last_height; + int last_slant; + symbol internal_name; + symbol external_name; + font *fm; + char is_bold; + hunits bold_offset; + track_kerning_function track_kern; + constant_space_type is_constant_spaced; + units constant_space; + int last_ligature_mode; + int last_kern_mode; + conditional_bold *cond_bold_list; + void flush(); +public: + special_font_list *sf; + font_info(symbol, int, symbol, font *); + int contains(charinfo *); + void set_bold(hunits); + void unbold(); + void set_conditional_bold(int, hunits); + void conditional_unbold(int); + void set_track_kern(track_kerning_function &); + void set_constant_space(constant_space_type, units = 0); + int is_named(symbol); + symbol get_name(); + tfont *get_tfont(font_size, int, int, int); + hunits get_space_width(font_size, int); + hunits get_narrow_space_width(font_size); + hunits get_half_narrow_space_width(font_size); + int get_bold(hunits *); + int is_special(); + int is_style(); + void set_zoom(int); + int get_zoom(); + friend symbol get_font_name(int, environment *); + friend symbol get_style_name(int); +}; + +class tfont_spec { +protected: + symbol name; + int input_position; + font *fm; + font_size size; + char is_bold; + char is_constant_spaced; + int ligature_mode; + int kern_mode; + hunits bold_offset; + hunits track_kern; // add this to the width + hunits constant_space_width; + int height; + int slant; +public: + tfont_spec(symbol, int, font *, font_size, int, int); + tfont_spec(const tfont_spec &spec) { *this = spec; } + tfont_spec plain(); + int operator==(const tfont_spec &); + friend tfont *font_info::get_tfont(font_size fs, int, int, int); +}; + +class tfont : public tfont_spec { + static tfont *tfont_list; + tfont *next; + tfont *plain_version; +public: + tfont(tfont_spec &); + int contains(charinfo *); + hunits get_width(charinfo *c); + int get_bold(hunits *); + int get_constant_space(hunits *); + hunits get_track_kern(); + tfont *get_plain(); + font_size get_size(); + int get_zoom(); + symbol get_name(); + charinfo *get_lig(charinfo *c1, charinfo *c2); + int get_kern(charinfo *c1, charinfo *c2, hunits *res); + int get_input_position(); + int get_character_type(charinfo *); + int get_height(); + int get_slant(); + vunits get_char_height(charinfo *); + vunits get_char_depth(charinfo *); + hunits get_char_skew(charinfo *); + hunits get_italic_correction(charinfo *); + hunits get_left_italic_correction(charinfo *); + hunits get_subscript_correction(charinfo *); + friend tfont *make_tfont(tfont_spec &); +}; + +inline int env_definite_font(environment *env) +{ + return env->get_family()->make_definite(env->get_font()); +} + +/* font_info functions */ + +static font_info **font_table = 0; +static int font_table_size = 0; + +font_info::font_info(symbol nm, int n, symbol enm, font *f) +: last_tfont(0), number(n), last_size(0), + internal_name(nm), external_name(enm), fm(f), + is_bold(0), is_constant_spaced(CONSTANT_SPACE_NONE), last_ligature_mode(1), + last_kern_mode(1), cond_bold_list(0), sf(0) +{ +} + +inline int font_info::contains(charinfo *ci) +{ + return fm != 0 && fm->contains(ci->as_glyph()); +} + +inline int font_info::is_special() +{ + return fm != 0 && fm->is_special(); +} + +inline int font_info::is_style() +{ + return fm == 0; +} + +void font_info::set_zoom(int zoom) +{ + assert(fm != 0); + fm->set_zoom(zoom); +} + +inline int font_info::get_zoom() +{ + if (is_style()) + return 0; + return fm->get_zoom(); +} + +tfont *make_tfont(tfont_spec &spec) +{ + for (tfont *p = tfont::tfont_list; p; p = p->next) + if (*p == spec) + return p; + return new tfont(spec); +} + +int env_get_zoom(environment *env) +{ + int fontno = env->get_family()->make_definite(env->get_font()); + return font_table[fontno]->get_zoom(); +} + +// this is the current_font, fontno is where we found the character, +// presumably a special font + +tfont *font_info::get_tfont(font_size fs, int height, int slant, int fontno) +{ + if (last_tfont == 0 || fs != last_size + || height != last_height || slant != last_slant + || global_ligature_mode != last_ligature_mode + || global_kern_mode != last_kern_mode + || fontno != number) { + font_info *f = font_table[fontno]; + tfont_spec spec(f->external_name, f->number, f->fm, fs, height, slant); + for (conditional_bold *p = cond_bold_list; p; p = p->next) + if (p->fontno == fontno) { + spec.is_bold = 1; + spec.bold_offset = p->offset; + break; + } + if (!spec.is_bold && is_bold) { + spec.is_bold = 1; + spec.bold_offset = bold_offset; + } + spec.track_kern = track_kern.compute(fs.to_scaled_points()); + spec.ligature_mode = global_ligature_mode; + spec.kern_mode = global_kern_mode; + switch (is_constant_spaced) { + case CONSTANT_SPACE_NONE: + break; + case CONSTANT_SPACE_ABSOLUTE: + spec.is_constant_spaced = 1; + spec.constant_space_width = constant_space; + break; + case CONSTANT_SPACE_RELATIVE: + spec.is_constant_spaced = 1; + spec.constant_space_width + = scale(constant_space*fs.to_scaled_points(), + units_per_inch, + 36*72*sizescale); + break; + default: + assert(0); + } + if (fontno != number) + return make_tfont(spec); + // save font for comparison purposes + last_tfont = make_tfont(spec); + // save font related values not contained in tfont + last_size = fs; + last_height = height; + last_slant = slant; + last_ligature_mode = global_ligature_mode; + last_kern_mode = global_kern_mode; + } + return last_tfont; +} + +int font_info::get_bold(hunits *res) +{ + if (is_bold) { + *res = bold_offset; + return 1; + } + else + return 0; +} + +void font_info::unbold() +{ + if (is_bold) { + is_bold = 0; + flush(); + } +} + +void font_info::set_bold(hunits offset) +{ + if (!is_bold || offset != bold_offset) { + is_bold = 1; + bold_offset = offset; + flush(); + } +} + +void font_info::set_conditional_bold(int fontno, hunits offset) +{ + for (conditional_bold *p = cond_bold_list; p; p = p->next) + if (p->fontno == fontno) { + if (offset != p->offset) { + p->offset = offset; + flush(); + } + return; + } + cond_bold_list = new conditional_bold(fontno, offset, cond_bold_list); +} + +conditional_bold::conditional_bold(int f, hunits h, conditional_bold *x) +: next(x), fontno(f), offset(h) +{ +} + +void font_info::conditional_unbold(int fontno) +{ + for (conditional_bold **p = &cond_bold_list; *p; p = &(*p)->next) + if ((*p)->fontno == fontno) { + conditional_bold *tem = *p; + *p = (*p)->next; + delete tem; + flush(); + return; + } +} + +void font_info::set_constant_space(constant_space_type type, units x) +{ + if (type != is_constant_spaced + || (type != CONSTANT_SPACE_NONE && x != constant_space)) { + flush(); + is_constant_spaced = type; + constant_space = x; + } +} + +void font_info::set_track_kern(track_kerning_function &tk) +{ + if (track_kern != tk) { + track_kern = tk; + flush(); + } +} + +void font_info::flush() +{ + last_tfont = 0; +} + +int font_info::is_named(symbol s) +{ + return internal_name == s; +} + +symbol font_info::get_name() +{ + return internal_name; +} + +symbol get_font_name(int fontno, environment *env) +{ + symbol f = font_table[fontno]->get_name(); + if (font_table[fontno]->is_style()) { + return concat(env->get_family()->nm, f); + } + return f; +} + +symbol get_style_name(int fontno) +{ + if (font_table[fontno]->is_style()) + return font_table[fontno]->get_name(); + else + return EMPTY_SYMBOL; +} + +hunits font_info::get_space_width(font_size fs, int space_sz) +{ + if (is_constant_spaced == CONSTANT_SPACE_NONE) + return scale(hunits(fm->get_space_width(fs.to_scaled_points())), + space_sz, 12); + else if (is_constant_spaced == CONSTANT_SPACE_ABSOLUTE) + return constant_space; + else + return scale(constant_space*fs.to_scaled_points(), + units_per_inch, 36*72*sizescale); +} + +hunits font_info::get_narrow_space_width(font_size fs) +{ + charinfo *ci = get_charinfo(symbol("|")); + if (fm->contains(ci->as_glyph())) + return hunits(fm->get_width(ci->as_glyph(), fs.to_scaled_points())); + else + return hunits(fs.to_units()/6); +} + +hunits font_info::get_half_narrow_space_width(font_size fs) +{ + charinfo *ci = get_charinfo(symbol("^")); + if (fm->contains(ci->as_glyph())) + return hunits(fm->get_width(ci->as_glyph(), fs.to_scaled_points())); + else + return hunits(fs.to_units()/12); +} + +/* tfont */ + +tfont_spec::tfont_spec(symbol nm, int n, font *f, + font_size s, int h, int sl) +: name(nm), input_position(n), fm(f), size(s), + is_bold(0), is_constant_spaced(0), ligature_mode(1), kern_mode(1), + height(h), slant(sl) +{ + if (height == size.to_scaled_points()) + height = 0; +} + +int tfont_spec::operator==(const tfont_spec &spec) +{ + if (fm == spec.fm + && size == spec.size + && input_position == spec.input_position + && name == spec.name + && height == spec.height + && slant == spec.slant + && (is_bold + ? (spec.is_bold && bold_offset == spec.bold_offset) + : !spec.is_bold) + && track_kern == spec.track_kern + && (is_constant_spaced + ? (spec.is_constant_spaced + && constant_space_width == spec.constant_space_width) + : !spec.is_constant_spaced) + && ligature_mode == spec.ligature_mode + && kern_mode == spec.kern_mode) + return 1; + else + return 0; +} + +tfont_spec tfont_spec::plain() +{ + return tfont_spec(name, input_position, fm, size, height, slant); +} + +hunits tfont::get_width(charinfo *c) +{ + if (is_constant_spaced) + return constant_space_width; + else if (is_bold) + return (hunits(fm->get_width(c->as_glyph(), size.to_scaled_points())) + + track_kern + bold_offset); + else + return (hunits(fm->get_width(c->as_glyph(), size.to_scaled_points())) + + track_kern); +} + +vunits tfont::get_char_height(charinfo *c) +{ + vunits v = fm->get_height(c->as_glyph(), size.to_scaled_points()); + if (height != 0 && height != size.to_scaled_points()) + return scale(v, height, size.to_scaled_points()); + else + return v; +} + +vunits tfont::get_char_depth(charinfo *c) +{ + vunits v = fm->get_depth(c->as_glyph(), size.to_scaled_points()); + if (height != 0 && height != size.to_scaled_points()) + return scale(v, height, size.to_scaled_points()); + else + return v; +} + +hunits tfont::get_char_skew(charinfo *c) +{ + return hunits(fm->get_skew(c->as_glyph(), size.to_scaled_points(), slant)); +} + +hunits tfont::get_italic_correction(charinfo *c) +{ + return hunits(fm->get_italic_correction(c->as_glyph(), size.to_scaled_points())); +} + +hunits tfont::get_left_italic_correction(charinfo *c) +{ + return hunits(fm->get_left_italic_correction(c->as_glyph(), + size.to_scaled_points())); +} + +hunits tfont::get_subscript_correction(charinfo *c) +{ + return hunits(fm->get_subscript_correction(c->as_glyph(), + size.to_scaled_points())); +} + +inline int tfont::get_input_position() +{ + return input_position; +} + +inline int tfont::contains(charinfo *ci) +{ + return fm->contains(ci->as_glyph()); +} + +inline int tfont::get_character_type(charinfo *ci) +{ + return fm->get_character_type(ci->as_glyph()); +} + +inline int tfont::get_bold(hunits *res) +{ + if (is_bold) { + *res = bold_offset; + return 1; + } + else + return 0; +} + +inline int tfont::get_constant_space(hunits *res) +{ + if (is_constant_spaced) { + *res = constant_space_width; + return 1; + } + else + return 0; +} + +inline hunits tfont::get_track_kern() +{ + return track_kern; +} + +inline tfont *tfont::get_plain() +{ + return plain_version; +} + +inline font_size tfont::get_size() +{ + return size; +} + +inline int tfont::get_zoom() +{ + return fm->get_zoom(); +} + +inline symbol tfont::get_name() +{ + return name; +} + +inline int tfont::get_height() +{ + return height; +} + +inline int tfont::get_slant() +{ + return slant; +} + +symbol SYMBOL_ff("ff"); +symbol SYMBOL_fi("fi"); +symbol SYMBOL_fl("fl"); +symbol SYMBOL_Fi("Fi"); +symbol SYMBOL_Fl("Fl"); + +charinfo *tfont::get_lig(charinfo *c1, charinfo *c2) +{ + if (ligature_mode == 0) + return 0; + charinfo *ci = 0; + if (c1->get_ascii_code() == 'f') { + switch (c2->get_ascii_code()) { + case 'f': + if (fm->has_ligature(font::LIG_ff)) + ci = get_charinfo(SYMBOL_ff); + break; + case 'i': + if (fm->has_ligature(font::LIG_fi)) + ci = get_charinfo(SYMBOL_fi); + break; + case 'l': + if (fm->has_ligature(font::LIG_fl)) + ci = get_charinfo(SYMBOL_fl); + break; + } + } + else if (ligature_mode != 2 && c1->nm == SYMBOL_ff) { + switch (c2->get_ascii_code()) { + case 'i': + if (fm->has_ligature(font::LIG_ffi)) + ci = get_charinfo(SYMBOL_Fi); + break; + case 'l': + if (fm->has_ligature(font::LIG_ffl)) + ci = get_charinfo(SYMBOL_Fl); + break; + } + } + if (ci != 0 && fm->contains(ci->as_glyph())) + return ci; + return 0; +} + +inline int tfont::get_kern(charinfo *c1, charinfo *c2, hunits *res) +{ + if (kern_mode == 0) + return 0; + else { + int n = fm->get_kern(c1->as_glyph(), + c2->as_glyph(), + size.to_scaled_points()); + if (n) { + *res = hunits(n); + return 1; + } + else + return 0; + } +} + +tfont *tfont::tfont_list = 0; + +tfont::tfont(tfont_spec &spec) : tfont_spec(spec) +{ + next = tfont_list; + tfont_list = this; + tfont_spec plain_spec = plain(); + tfont *p; + for (p = tfont_list; p; p = p->next) + if (*p == plain_spec) { + plain_version = p; + break; + } + if (!p) + plain_version = new tfont(plain_spec); +} + +/* output_file */ + +class real_output_file : public output_file { +#ifndef POPEN_MISSING + int piped; +#endif + int printing; // decision via optional page list + int output_on; // \O[0] or \O[1] escape sequences + virtual void really_transparent_char(unsigned char) = 0; + virtual void really_print_line(hunits x, vunits y, node *n, + vunits before, vunits after, hunits width) = 0; + virtual void really_begin_page(int pageno, vunits page_length) = 0; + virtual void really_copy_file(hunits x, vunits y, const char *filename); + virtual void really_put_filename(const char *, int); + virtual void really_on(); + virtual void really_off(); +public: + FILE *fp; + real_output_file(); + ~real_output_file(); + void flush(); + void transparent_char(unsigned char); + void print_line(hunits x, vunits y, node *n, vunits before, vunits after, hunits width); + void begin_page(int pageno, vunits page_length); + void put_filename(const char *, int); + void on(); + void off(); + int is_on(); + int is_printing(); + void copy_file(hunits x, vunits y, const char *filename); +}; + +class suppress_output_file : public real_output_file { +public: + suppress_output_file(); + void really_transparent_char(unsigned char); + void really_print_line(hunits x, vunits y, node *n, vunits, vunits, hunits width); + void really_begin_page(int pageno, vunits page_length); +}; + +class ascii_output_file : public real_output_file { +public: + ascii_output_file(); + void really_transparent_char(unsigned char); + void really_print_line(hunits x, vunits y, node *n, vunits, vunits, hunits width); + void really_begin_page(int pageno, vunits page_length); + void outc(unsigned char c); + void outs(const char *s); +}; + +void ascii_output_file::outc(unsigned char c) +{ + fputc(c, fp); +} + +void ascii_output_file::outs(const char *s) +{ + fputc('<', fp); + if (s) + fputs(s, fp); + fputc('>', fp); +} + +struct hvpair; + +class troff_output_file : public real_output_file { + units hpos; + units vpos; + units output_vpos; + units output_hpos; + int force_motion; + int current_size; + int current_slant; + int current_height; + tfont *current_tfont; + color *current_fill_color; + color *current_glyph_color; + int current_font_number; + symbol *font_position; + int nfont_positions; + enum { TBUF_SIZE = 256 }; + char tbuf[TBUF_SIZE]; + int tbuf_len; + int tbuf_kern; + int begun_page; + int cur_div_level; + string tag_list; + void do_motion(); + void put(char c); + void put(unsigned char c); + void put(int i); + void put(unsigned int i); + void put(const char *s); + void set_font(tfont *tf); + void flush_tbuf(); +public: + troff_output_file(); + ~troff_output_file(); + void trailer(vunits page_length); + void put_char(charinfo *, tfont *, color *, color *); + void put_char_width(charinfo *, tfont *, color *, color *, hunits, hunits); + void right(hunits); + void down(vunits); + void moveto(hunits, vunits); + void start_special(tfont *, color *, color *, int = 0); + void start_special(); + void special_char(unsigned char c); + void end_special(); + void word_marker(); + void really_transparent_char(unsigned char c); + void really_print_line(hunits x, vunits y, node *n, vunits before, vunits after, hunits width); + void really_begin_page(int pageno, vunits page_length); + void really_copy_file(hunits x, vunits y, const char *filename); + void really_put_filename(const char *, int); + void really_on(); + void really_off(); + void draw(char, hvpair *, int, font_size, color *, color *); + void determine_line_limits (char code, hvpair *point, int npoints); + void check_charinfo(tfont *tf, charinfo *ci); + void glyph_color(color *c); + void fill_color(color *c); + int get_hpos() { return hpos; } + int get_vpos() { return vpos; } + void add_to_tag_list(string s); + friend void space_char_hmotion_node::tprint(troff_output_file *); + friend void unbreakable_space_node::tprint(troff_output_file *); +}; + +static void put_string(const char *s, FILE *fp) +{ + for (; *s != '\0'; ++s) + putc(*s, fp); +} + +inline void troff_output_file::put(char c) +{ + putc(c, fp); +} + +inline void troff_output_file::put(unsigned char c) +{ + putc(c, fp); +} + +inline void troff_output_file::put(const char *s) +{ + put_string(s, fp); +} + +inline void troff_output_file::put(int i) +{ + put_string(i_to_a(i), fp); +} + +inline void troff_output_file::put(unsigned int i) +{ + put_string(ui_to_a(i), fp); +} + +void troff_output_file::start_special(tfont *tf, color *gcol, color *fcol, + int no_init_string) +{ + set_font(tf); + glyph_color(gcol); + fill_color(fcol); + flush_tbuf(); + do_motion(); + if (!no_init_string) + put("x X "); +} + +void troff_output_file::start_special() +{ + flush_tbuf(); + do_motion(); + put("x X "); +} + +void troff_output_file::special_char(unsigned char c) +{ + put(c); + if (c == '\n') + put('+'); +} + +void troff_output_file::end_special() +{ + put('\n'); +} + +inline void troff_output_file::moveto(hunits h, vunits v) +{ + hpos = h.to_units(); + vpos = v.to_units(); +} + +void troff_output_file::really_print_line(hunits x, vunits y, node *n, + vunits before, vunits after, hunits) +{ + moveto(x, y); + while (n != 0) { + // Check whether we should push the current troff state and use + // the state at the start of the invocation of this diversion. + if (n->div_nest_level > cur_div_level && n->push_state) { + state.push_state(n->push_state); + cur_div_level = n->div_nest_level; + } + // Has the current diversion level decreased? Then we must pop the + // troff state. + while (n->div_nest_level < cur_div_level) { + state.pop_state(); + cur_div_level = n->div_nest_level; + } + // Now check whether the state has changed. + if ((is_on() || n->force_tprint()) + && (state.changed(n->state) || n->is_tag() || n->is_special)) { + flush_tbuf(); + do_motion(); + force_motion = 1; + flush(); + state.flush(fp, n->state, tag_list); + tag_list = string(""); + flush(); + } + n->tprint(this); + n = n->next; + } + flush_tbuf(); + // This ensures that transparent throughput will have a more predictable + // position. + do_motion(); + force_motion = 1; + hpos = 0; + put('n'); + put(before.to_units()); + put(' '); + put(after.to_units()); + put('\n'); +} + +inline void troff_output_file::word_marker() +{ + flush_tbuf(); + if (is_on()) + put('w'); +} + +inline void troff_output_file::right(hunits n) +{ + hpos += n.to_units(); +} + +inline void troff_output_file::down(vunits n) +{ + vpos += n.to_units(); +} + +void troff_output_file::do_motion() +{ + if (force_motion) { + put('V'); + put(vpos); + put('\n'); + put('H'); + put(hpos); + put('\n'); + } + else { + if (hpos != output_hpos) { + units n = hpos - output_hpos; + if (n > 0 && n < hpos) { + put('h'); + put(n); + } + else { + put('H'); + put(hpos); + } + put('\n'); + } + if (vpos != output_vpos) { + units n = vpos - output_vpos; + if (n > 0 && n < vpos) { + put('v'); + put(n); + } + else { + put('V'); + put(vpos); + } + put('\n'); + } + } + output_vpos = vpos; + output_hpos = hpos; + force_motion = 0; +} + +void troff_output_file::flush_tbuf() +{ + if (!is_on()) { + tbuf_len = 0; + return; + } + + if (tbuf_len == 0) + return; + if (tbuf_kern == 0) + put('t'); + else { + put('u'); + put(tbuf_kern); + put(' '); + } + check_output_limits(hpos, vpos); + check_output_limits(hpos, vpos - current_size); + + for (int i = 0; i < tbuf_len; i++) + put(tbuf[i]); + put('\n'); + tbuf_len = 0; +} + +void troff_output_file::check_charinfo(tfont *tf, charinfo *ci) +{ + if (!is_on()) + return; + + int height = tf->get_char_height(ci).to_units(); + int width = tf->get_width(ci).to_units() + + tf->get_italic_correction(ci).to_units(); + int depth = tf->get_char_depth(ci).to_units(); + check_output_limits(output_hpos, output_vpos - height); + check_output_limits(output_hpos + width, output_vpos + depth); +} + +void troff_output_file::put_char_width(charinfo *ci, tfont *tf, + color *gcol, color *fcol, + hunits w, hunits k) +{ + int kk = k.to_units(); + if (!is_on()) { + flush_tbuf(); + hpos += w.to_units() + kk; + return; + } + set_font(tf); + unsigned char c = ci->get_ascii_code(); + if (c == '\0') { + glyph_color(gcol); + fill_color(fcol); + flush_tbuf(); + do_motion(); + check_charinfo(tf, ci); + if (ci->numbered()) { + put('N'); + put(ci->get_number()); + } + else { + put('C'); + const char *s = ci->nm.contents(); + if (s[1] == 0) { + put('\\'); + put(s[0]); + } + else + put(s); + } + put('\n'); + hpos += w.to_units() + kk; + } + else if (device_has_tcommand) { + if (tbuf_len > 0 && hpos == output_hpos && vpos == output_vpos + && (!gcol || gcol == current_glyph_color) + && (!fcol || fcol == current_fill_color) + && kk == tbuf_kern + && tbuf_len < TBUF_SIZE) { + check_charinfo(tf, ci); + tbuf[tbuf_len++] = c; + output_hpos += w.to_units() + kk; + hpos = output_hpos; + return; + } + glyph_color(gcol); + fill_color(fcol); + flush_tbuf(); + do_motion(); + check_charinfo(tf, ci); + tbuf[tbuf_len++] = c; + output_hpos += w.to_units() + kk; + tbuf_kern = kk; + hpos = output_hpos; + } + else { + // flush_tbuf(); + int n = hpos - output_hpos; + check_charinfo(tf, ci); + // check_output_limits(output_hpos, output_vpos); + if (vpos == output_vpos + && (!gcol || gcol == current_glyph_color) + && (!fcol || fcol == current_fill_color) + && n > 0 && n < 100 && !force_motion) { + put(char(n/10 + '0')); + put(char(n%10 + '0')); + put(c); + output_hpos = hpos; + } + else { + glyph_color(gcol); + fill_color(fcol); + do_motion(); + put('c'); + put(c); + } + hpos += w.to_units() + kk; + } +} + +void troff_output_file::put_char(charinfo *ci, tfont *tf, + color *gcol, color *fcol) +{ + flush_tbuf(); + if (!is_on()) + return; + set_font(tf); + unsigned char c = ci->get_ascii_code(); + if (c == '\0') { + glyph_color(gcol); + fill_color(fcol); + flush_tbuf(); + do_motion(); + if (ci->numbered()) { + put('N'); + put(ci->get_number()); + } + else { + put('C'); + const char *s = ci->nm.contents(); + if (s[1] == 0) { + put('\\'); + put(s[0]); + } + else + put(s); + } + put('\n'); + } + else { + int n = hpos - output_hpos; + if (vpos == output_vpos + && (!gcol || gcol == current_glyph_color) + && (!fcol || fcol == current_fill_color) + && n > 0 && n < 100) { + put(char(n/10 + '0')); + put(char(n%10 + '0')); + put(c); + output_hpos = hpos; + } + else { + glyph_color(gcol); + fill_color(fcol); + flush_tbuf(); + do_motion(); + put('c'); + put(c); + } + } +} + +// set_font calls 'flush_tbuf' if necessary. + +void troff_output_file::set_font(tfont *tf) +{ + if (current_tfont == tf) + return; + flush_tbuf(); + int n = tf->get_input_position(); + symbol nm = tf->get_name(); + if (n >= nfont_positions || font_position[n] != nm) { + put("x font "); + put(n); + put(' '); + put(nm.contents()); + put('\n'); + if (n >= nfont_positions) { + int old_nfont_positions = nfont_positions; + symbol *old_font_position = font_position; + nfont_positions *= 3; + nfont_positions /= 2; + if (nfont_positions <= n) + nfont_positions = n + 10; + font_position = new symbol[nfont_positions]; + memcpy(font_position, old_font_position, + old_nfont_positions*sizeof(symbol)); + delete[] old_font_position; + } + font_position[n] = nm; + } + if (current_font_number != n) { + put('f'); + put(n); + put('\n'); + current_font_number = n; + } + int zoom = tf->get_zoom(); + int size; + if (zoom) + size = scale(tf->get_size().to_scaled_points(), + zoom, 1000); + else + size = tf->get_size().to_scaled_points(); + if (current_size != size) { + put('s'); + put(size); + put('\n'); + current_size = size; + } + int slant = tf->get_slant(); + if (current_slant != slant) { + put("x Slant "); + put(slant); + put('\n'); + current_slant = slant; + } + int height = tf->get_height(); + if (current_height != height) { + put("x Height "); + put(height == 0 ? current_size : height); + put('\n'); + current_height = height; + } + current_tfont = tf; +} + +// fill_color calls 'flush_tbuf' and 'do_motion' if necessary. + +void troff_output_file::fill_color(color *col) +{ + if (!col || current_fill_color == col) + return; + current_fill_color = col; + if (!color_flag) + return; + flush_tbuf(); + do_motion(); + put("DF"); + unsigned int components[4]; + color_scheme cs; + cs = col->get_components(components); + switch (cs) { + case DEFAULT: + put('d'); + break; + case RGB: + put("r "); + put(Red); + put(' '); + put(Green); + put(' '); + put(Blue); + break; + case CMY: + put("c "); + put(Cyan); + put(' '); + put(Magenta); + put(' '); + put(Yellow); + break; + case CMYK: + put("k "); + put(Cyan); + put(' '); + put(Magenta); + put(' '); + put(Yellow); + put(' '); + put(Black); + break; + case GRAY: + put("g "); + put(Gray); + break; + } + put('\n'); +} + +// glyph_color calls 'flush_tbuf' and 'do_motion' if necessary. + +void troff_output_file::glyph_color(color *col) +{ + if (!col || current_glyph_color == col) + return; + current_glyph_color = col; + if (!color_flag) + return; + flush_tbuf(); + // grotty doesn't like a color command if the vertical position is zero. + do_motion(); + put("m"); + unsigned int components[4]; + color_scheme cs; + cs = col->get_components(components); + switch (cs) { + case DEFAULT: + put('d'); + break; + case RGB: + put("r "); + put(Red); + put(' '); + put(Green); + put(' '); + put(Blue); + break; + case CMY: + put("c "); + put(Cyan); + put(' '); + put(Magenta); + put(' '); + put(Yellow); + break; + case CMYK: + put("k "); + put(Cyan); + put(' '); + put(Magenta); + put(' '); + put(Yellow); + put(' '); + put(Black); + break; + case GRAY: + put("g "); + put(Gray); + break; + } + put('\n'); +} + +void troff_output_file::add_to_tag_list(string s) +{ + if (tag_list == string("")) + tag_list = s; + else { + tag_list += string("\n"); + tag_list += s; + } +} + +// determine_line_limits - works out the smallest box which will contain +// the entity, code, built from the point array. +void troff_output_file::determine_line_limits(char code, hvpair *point, + int npoints) +{ + int i, x, y; + + if (!is_on()) + return; + + switch (code) { + case 'c': + case 'C': + // only the h field is used when defining a circle + check_output_limits(output_hpos, + output_vpos - point[0].h.to_units()/2); + check_output_limits(output_hpos + point[0].h.to_units(), + output_vpos + point[0].h.to_units()/2); + break; + case 'E': + case 'e': + check_output_limits(output_hpos, + output_vpos - point[0].v.to_units()/2); + check_output_limits(output_hpos + point[0].h.to_units(), + output_vpos + point[0].v.to_units()/2); + break; + case 'P': + case 'p': + x = output_hpos; + y = output_vpos; + check_output_limits(x, y); + for (i = 0; i < npoints; i++) { + x += point[i].h.to_units(); + y += point[i].v.to_units(); + check_output_limits(x, y); + } + break; + case 't': + x = output_hpos; + y = output_vpos; + for (i = 0; i < npoints; i++) { + x += point[i].h.to_units(); + y += point[i].v.to_units(); + check_output_limits(x, y); + } + break; + case 'a': + double c[2]; + int p[4]; + int minx, miny, maxx, maxy; + x = output_hpos; + y = output_vpos; + p[0] = point[0].h.to_units(); + p[1] = point[0].v.to_units(); + p[2] = point[1].h.to_units(); + p[3] = point[1].v.to_units(); + if (adjust_arc_center(p, c)) { + check_output_arc_limits(x, y, + p[0], p[1], p[2], p[3], + c[0], c[1], + &minx, &maxx, &miny, &maxy); + check_output_limits(minx, miny); + check_output_limits(maxx, maxy); + break; + } + // fall through + case 'l': + x = output_hpos; + y = output_vpos; + check_output_limits(x, y); + for (i = 0; i < npoints; i++) { + x += point[i].h.to_units(); + y += point[i].v.to_units(); + check_output_limits(x, y); + } + break; + default: + x = output_hpos; + y = output_vpos; + for (i = 0; i < npoints; i++) { + x += point[i].h.to_units(); + y += point[i].v.to_units(); + check_output_limits(x, y); + } + } +} + +void troff_output_file::draw(char code, hvpair *point, int npoints, + font_size fsize, color *gcol, color *fcol) +{ + int i; + glyph_color(gcol); + fill_color(fcol); + flush_tbuf(); + do_motion(); + if (is_on()) { + int size = fsize.to_scaled_points(); + if (current_size != size) { + put('s'); + put(size); + put('\n'); + current_size = size; + current_tfont = 0; + } + put('D'); + put(code); + if (code == 'c') { + put(' '); + put(point[0].h.to_units()); + } + else + for (i = 0; i < npoints; i++) { + put(' '); + put(point[i].h.to_units()); + put(' '); + put(point[i].v.to_units()); + } + determine_line_limits(code, point, npoints); + } + + for (i = 0; i < npoints; i++) + output_hpos += point[i].h.to_units(); + hpos = output_hpos; + if (code != 'e') { + for (i = 0; i < npoints; i++) + output_vpos += point[i].v.to_units(); + vpos = output_vpos; + } + if (is_on()) + put('\n'); +} + +void troff_output_file::really_on() +{ + flush_tbuf(); + force_motion = 1; + do_motion(); +} + +void troff_output_file::really_off() +{ + flush_tbuf(); +} + +void troff_output_file::really_put_filename(const char *filename, int po) +{ + flush_tbuf(); + put("x F "); + if (po) + put("<"); + put(filename); + if (po) + put(">"); + put('\n'); +} + +void troff_output_file::really_begin_page(int pageno, vunits page_length) +{ + flush_tbuf(); + if (begun_page) { + if (page_length > V0) { + put('V'); + put(page_length.to_units()); + put('\n'); + } + } + else + begun_page = 1; + current_tfont = 0; + current_font_number = -1; + current_size = 0; + // current_height = 0; + // current_slant = 0; + hpos = 0; + vpos = 0; + output_hpos = 0; + output_vpos = 0; + force_motion = 1; + for (int i = 0; i < nfont_positions; i++) + font_position[i] = NULL_SYMBOL; + put('p'); + put(pageno); + put('\n'); +} + +void troff_output_file::really_copy_file(hunits x, vunits y, + const char *filename) +{ + moveto(x, y); + flush_tbuf(); + do_motion(); + errno = 0; + FILE *ifp = include_search_path.open_file_cautious(filename); + if (ifp == 0) + error("can't open '%1': %2", filename, strerror(errno)); + else { + int c; + while ((c = getc(ifp)) != EOF) + put(char(c)); + fclose(ifp); + } + force_motion = 1; + current_size = 0; + current_tfont = 0; + current_font_number = -1; + for (int i = 0; i < nfont_positions; i++) + font_position[i] = NULL_SYMBOL; +} + +void troff_output_file::really_transparent_char(unsigned char c) +{ + put(c); +} + +troff_output_file::~troff_output_file() +{ + delete[] font_position; +} + +void troff_output_file::trailer(vunits page_length) +{ + flush_tbuf(); + if (page_length > V0) { + put("x trailer\n"); + put('V'); + put(page_length.to_units()); + put('\n'); + } + put("x stop\n"); +} + +troff_output_file::troff_output_file() +: current_slant(0), current_height(0), current_fill_color(0), + current_glyph_color(0), nfont_positions(10), tbuf_len(0), begun_page(0), + cur_div_level(0) +{ + font_position = new symbol[nfont_positions]; + put("x T "); + put(device); + put('\n'); + put("x res "); + put(units_per_inch); + put(' '); + put(hresolution); + put(' '); + put(vresolution); + put('\n'); + put("x init\n"); +} + +/* output_file */ + +output_file *the_output = 0; + +output_file::output_file() +{ + is_dying = false; +} + +output_file::~output_file() +{ +} + +void output_file::trailer(vunits) +{ +} + +void output_file::put_filename(const char *, int) +{ +} + +void output_file::on() +{ +} + +void output_file::off() +{ +} + +real_output_file::real_output_file() +: printing(0), output_on(1) +{ +#ifndef POPEN_MISSING + if (pipe_command) { + if ((fp = popen(pipe_command, POPEN_WT)) != 0) { + piped = 1; + return; + } + error("pipe open failed: %1", strerror(errno)); + } + piped = 0; +#endif /* not POPEN_MISSING */ + fp = stdout; +} + +real_output_file::~real_output_file() +{ + if (!fp) + return; + // Prevent destructor from recursing; see div.cpp:cleanup_and_exit(). + is_dying = true; + // To avoid looping, set fp to 0 before calling fatal(). + if (ferror(fp)) { + fp = 0; + fatal("error on output file stream"); + } + else if (fflush(fp) < 0) { + fp = 0; + fatal("unable to flush output file: %1", strerror(errno)); + } +#ifndef POPEN_MISSING + if (piped) { + int result = pclose(fp); + fp = 0; + if (result < 0) + fatal("unable to close pipe: %1", strerror(errno)); + if (!WIFEXITED(result)) + error("output process '%1' got fatal signal %2", + pipe_command, + WIFSIGNALED(result) ? WTERMSIG(result) : WSTOPSIG(result)); + else { + int exit_status = WEXITSTATUS(result); + if (exit_status != 0) + error("output process '%1' exited with status %2", + pipe_command, exit_status); + } + } + else +#endif /* not POPEN MISSING */ + if (fclose(fp) < 0) { + fp = 0; + fatal("unable to close output file: %1", strerror(errno)); + } +} + +void real_output_file::flush() +{ + // To avoid looping, set fp to 0 before calling fatal(). + if (fflush(fp) < 0) { + fp = 0; + fatal("unable to flush output file: %1", strerror(errno)); + } +} + +int real_output_file::is_printing() +{ + return printing; +} + +void real_output_file::begin_page(int pageno, vunits page_length) +{ + printing = in_output_page_list(pageno); + if (printing) + really_begin_page(pageno, page_length); +} + +void real_output_file::copy_file(hunits x, vunits y, const char *filename) +{ + if (printing && output_on) + really_copy_file(x, y, filename); + check_output_limits(x.to_units(), y.to_units()); +} + +void real_output_file::transparent_char(unsigned char c) +{ + if (printing && output_on) + really_transparent_char(c); +} + +void real_output_file::print_line(hunits x, vunits y, node *n, + vunits before, vunits after, hunits width) +{ + if (printing) + really_print_line(x, y, n, before, after, width); + delete_node_list(n); +} + +void real_output_file::really_copy_file(hunits, vunits, const char *) +{ + // do nothing +} + +void real_output_file::put_filename(const char *filename, int po) +{ + really_put_filename(filename, po); +} + +void real_output_file::really_put_filename(const char *, int) +{ +} + +void real_output_file::on() +{ + really_on(); + if (output_on == 0) + output_on = 1; +} + +void real_output_file::off() +{ + really_off(); + output_on = 0; +} + +int real_output_file::is_on() +{ + return output_on; +} + +void real_output_file::really_on() +{ +} + +void real_output_file::really_off() +{ +} + +/* ascii_output_file */ + +void ascii_output_file::really_transparent_char(unsigned char c) +{ + putc(c, fp); +} + +void ascii_output_file::really_print_line(hunits, vunits, node *n, + vunits, vunits, hunits) +{ + while (n != 0) { + n->ascii_print(this); + n = n->next; + } + fputc('\n', fp); +} + +void ascii_output_file::really_begin_page(int /*pageno*/, vunits /*page_length*/) +{ + fputs("\n", fp); +} + +ascii_output_file::ascii_output_file() +{ +} + +/* suppress_output_file */ + +suppress_output_file::suppress_output_file() +{ +} + +void suppress_output_file::really_print_line(hunits, vunits, node *, vunits, vunits, hunits) +{ +} + +void suppress_output_file::really_begin_page(int, vunits) +{ +} + +void suppress_output_file::really_transparent_char(unsigned char) +{ +} + +/* glyphs, ligatures, kerns, discretionary breaks */ + +class charinfo_node : public node { +protected: + charinfo *ci; +public: + charinfo_node(charinfo *, statem *, int, node * = 0); + int ends_sentence(); + int overlaps_vertically(); + int overlaps_horizontally(); +}; + +charinfo_node::charinfo_node(charinfo *c, statem *s, int pop, node *x) +: node(x, s, pop), ci(c) +{ +} + +int charinfo_node::ends_sentence() +{ + if (ci->ends_sentence()) + return 1; + else if (ci->transparent()) + return 2; + else + return 0; +} + +int charinfo_node::overlaps_horizontally() +{ + return ci->overlaps_horizontally(); +} + +int charinfo_node::overlaps_vertically() +{ + return ci->overlaps_vertically(); +} + +class glyph_node : public charinfo_node { +protected: + tfont *tf; + color *gcol; + color *fcol; /* this is needed for grotty */ +#ifdef STORE_WIDTH + hunits wid; + glyph_node(charinfo *, tfont *, color *, color *, hunits, + statem *, int, node * = 0); +#endif +public: + glyph_node(charinfo *, tfont *, color *, color *, + statem *, int, node * = 0); + ~glyph_node() {} + node *copy(); + node *merge_glyph_node(glyph_node *); + node *merge_self(node *); + hunits width(); + node *last_char_node(); + units size(); + void vertical_extent(vunits *, vunits *); + hunits subscript_correction(); + hunits italic_correction(); + hunits left_italic_correction(); + hunits skew(); + hyphenation_type get_hyphenation_type(); + tfont *get_tfont(); + color *get_glyph_color(); + color *get_fill_color(); + void tprint(troff_output_file *); + void zero_width_tprint(troff_output_file *); + hyphen_list *get_hyphen_list(hyphen_list *, int *); + node *add_self(node *, hyphen_list **); + void ascii_print(ascii_output_file *); + void asciify(macro *); + int character_type(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + void debug_node(); +}; + +class ligature_node : public glyph_node { + node *n1; + node *n2; +#ifdef STORE_WIDTH + ligature_node(charinfo *, tfont *, color *, color *, hunits, + node *, node *, statem *, int, node * = 0); +#endif +public: + void *operator new(size_t); + void operator delete(void *); + ligature_node(charinfo *, tfont *, color *, color *, + node *, node *, statem *, int, node * = 0); + ~ligature_node(); + node *copy(); + node *add_self(node *, hyphen_list **); + hyphen_list *get_hyphen_list(hyphen_list *, int *); + void ascii_print(ascii_output_file *); + void asciify(macro *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class kern_pair_node : public node { + hunits amount; + node *n1; + node *n2; +public: + kern_pair_node(hunits, node *, node *, statem *, int, node * = 0); + ~kern_pair_node(); + node *copy(); + node *merge_glyph_node(glyph_node *); + node *add_self(node *, hyphen_list **); + hyphen_list *get_hyphen_list(hyphen_list *, int *); + node *add_discretionary_hyphen(); + hunits width(); + node *last_char_node(); + hunits italic_correction(); + hunits subscript_correction(); + void tprint(troff_output_file *); + hyphenation_type get_hyphenation_type(); + int ends_sentence(); + void ascii_print(ascii_output_file *); + void asciify(macro *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + void vertical_extent(vunits *, vunits *); +}; + +class dbreak_node : public node { + node *none; + node *pre; + node *post; +public: + dbreak_node(node *, node *, statem *, int, node * = 0); + ~dbreak_node(); + node *copy(); + node *merge_glyph_node(glyph_node *); + node *add_discretionary_hyphen(); + hunits width(); + node *last_char_node(); + hunits italic_correction(); + hunits subscript_correction(); + void tprint(troff_output_file *); + breakpoint *get_breakpoints(hunits width, int ns, breakpoint *rest = 0, + int is_inner = 0); + int nbreaks(); + int ends_sentence(); + void split(int, node **, node **); + hyphenation_type get_hyphenation_type(); + void ascii_print(ascii_output_file *); + void asciify(macro *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +void *ligature_node::operator new(size_t n) +{ + return new char[n]; +} + +void ligature_node::operator delete(void *p) +{ + delete[] (char *)p; +} + +glyph_node::glyph_node(charinfo *c, tfont *t, color *gc, color *fc, + statem *s, int pop, node *x) +: charinfo_node(c, s, pop, x), tf(t), gcol(gc), fcol(fc) +{ +#ifdef STORE_WIDTH + wid = tf->get_width(ci); +#endif +} + +#ifdef STORE_WIDTH +glyph_node::glyph_node(charinfo *c, tfont *t, + color *gc, color *fc, hunits w, + statem *s, int pop, node *x) +: charinfo_node(c, s, pop, x), tf(t), gcol(gc), fcol(fc), wid(w) +{ +} +#endif + +node *glyph_node::copy() +{ +#ifdef STORE_WIDTH + return new glyph_node(ci, tf, gcol, fcol, wid, state, div_nest_level); +#else + return new glyph_node(ci, tf, gcol, fcol, state, div_nest_level); +#endif +} + +node *glyph_node::merge_self(node *nd) +{ + return nd->merge_glyph_node(this); +} + +int glyph_node::character_type() +{ + return tf->get_character_type(ci); +} + +node *glyph_node::add_self(node *n, hyphen_list **p) +{ + assert(ci->get_hyphenation_code() == (*p)->hyphenation_code); + next = 0; + node *nn; + if (n == 0 || (nn = n->merge_glyph_node(this)) == 0) { + next = n; + nn = this; + } + if ((*p)->hyphen) + nn = nn->add_discretionary_hyphen(); + hyphen_list *pp = *p; + *p = (*p)->next; + delete pp; + return nn; +} + +units glyph_node::size() +{ + return tf->get_size().to_units(); +} + +hyphen_list *glyph_node::get_hyphen_list(hyphen_list *tail, int *count) +{ + (*count)++; + return new hyphen_list(ci->get_hyphenation_code(), tail); +} + +tfont *node::get_tfont() +{ + return 0; +} + +tfont *glyph_node::get_tfont() +{ + return tf; +} + +color *node::get_glyph_color() +{ + return 0; +} + +color *glyph_node::get_glyph_color() +{ + return gcol; +} + +color *node::get_fill_color() +{ + return 0; +} + +color *glyph_node::get_fill_color() +{ + return fcol; +} + +node *node::merge_glyph_node(glyph_node *) +{ + return 0; +} + +node *glyph_node::merge_glyph_node(glyph_node *gn) +{ + if (tf == gn->tf && gcol == gn->gcol && fcol == gn->fcol) { + charinfo *lig; + if ((lig = tf->get_lig(ci, gn->ci)) != 0) { + node *next1 = next; + next = 0; + return new ligature_node(lig, tf, gcol, fcol, this, gn, state, + gn->div_nest_level, next1); + } + hunits kern; + if (tf->get_kern(ci, gn->ci, &kern)) { + node *next1 = next; + next = 0; + return new kern_pair_node(kern, this, gn, state, + gn->div_nest_level, next1); + } + } + return 0; +} + +#ifdef STORE_WIDTH +inline +#endif +hunits glyph_node::width() +{ +#ifdef STORE_WIDTH + return wid; +#else + return tf->get_width(ci); +#endif +} + +node *glyph_node::last_char_node() +{ + return this; +} + +void glyph_node::vertical_extent(vunits *min, vunits *max) +{ + *min = -tf->get_char_height(ci); + *max = tf->get_char_depth(ci); +} + +hunits glyph_node::skew() +{ + return tf->get_char_skew(ci); +} + +hunits glyph_node::subscript_correction() +{ + return tf->get_subscript_correction(ci); +} + +hunits glyph_node::italic_correction() +{ + return tf->get_italic_correction(ci); +} + +hunits glyph_node::left_italic_correction() +{ + return tf->get_left_italic_correction(ci); +} + +hyphenation_type glyph_node::get_hyphenation_type() +{ + return HYPHEN_MIDDLE; +} + +void glyph_node::ascii_print(ascii_output_file *ascii) +{ + unsigned char c = ci->get_ascii_code(); + if (c != 0) + ascii->outc(c); + else + ascii->outs(ci->nm.contents()); +} + +void glyph_node::debug_node() +{ + unsigned char c = ci->get_ascii_code(); + fprintf(stderr, "{ %s [", type()); + if (c) + fprintf(stderr, "%c", c); + else + fprintf(stderr, "%s", ci->nm.contents()); + if (push_state) + fprintf(stderr, " "); + if (state) + state->display_state(); + fprintf(stderr, " nest level %d", div_nest_level); + fprintf(stderr, "]}\n"); + fflush(stderr); +} + +ligature_node::ligature_node(charinfo *c, tfont *t, color *gc, color *fc, + node *gn1, node *gn2, statem *s, + int pop, node *x) +: glyph_node(c, t, gc, fc, s, pop, x), n1(gn1), n2(gn2) +{ +} + +#ifdef STORE_WIDTH +ligature_node::ligature_node(charinfo *c, tfont *t, color *gc, color *fc, + hunits w, node *gn1, node *gn2, statem *s, + int pop, node *x) +: glyph_node(c, t, gc, fc, w, s, pop, x), n1(gn1), n2(gn2) +{ +} +#endif + +ligature_node::~ligature_node() +{ + delete n1; + delete n2; +} + +node *ligature_node::copy() +{ +#ifdef STORE_WIDTH + return new ligature_node(ci, tf, gcol, fcol, wid, n1->copy(), n2->copy(), + state, div_nest_level); +#else + return new ligature_node(ci, tf, gcol, fcol, n1->copy(), n2->copy(), + state, div_nest_level); +#endif +} + +void ligature_node::ascii_print(ascii_output_file *ascii) +{ + n1->ascii_print(ascii); + n2->ascii_print(ascii); +} + +hyphen_list *ligature_node::get_hyphen_list(hyphen_list *tail, int *count) +{ + hyphen_list *hl = n2->get_hyphen_list(tail, count); + return n1->get_hyphen_list(hl, count); +} + +node *ligature_node::add_self(node *n, hyphen_list **p) +{ + n = n1->add_self(n, p); + n = n2->add_self(n, p); + n1 = n2 = 0; + delete this; + return n; +} + +kern_pair_node::kern_pair_node(hunits n, node *first, node *second, + statem* s, int pop, node *x) +: node(x, s, pop), amount(n), n1(first), n2(second) +{ +} + +dbreak_node::dbreak_node(node *n, node *p, statem *s, int pop, node *x) +: node(x, s, pop), none(n), pre(p), post(0) +{ +} + +node *dbreak_node::merge_glyph_node(glyph_node *gn) +{ + glyph_node *gn2 = (glyph_node *)gn->copy(); + node *new_none = none ? none->merge_glyph_node(gn) : 0; + node *new_post = post ? post->merge_glyph_node(gn2) : 0; + if (new_none == 0 && new_post == 0) { + delete gn2; + return 0; + } + if (new_none != 0) + none = new_none; + else { + gn->next = none; + none = gn; + } + if (new_post != 0) + post = new_post; + else { + gn2->next = post; + post = gn2; + } + return this; +} + +node *kern_pair_node::merge_glyph_node(glyph_node *gn) +{ + node *nd = n2->merge_glyph_node(gn); + if (nd == 0) + return 0; + n2 = nd; + nd = n2->merge_self(n1); + if (nd) { + nd->next = next; + n1 = 0; + n2 = 0; + delete this; + return nd; + } + return this; +} + +hunits kern_pair_node::italic_correction() +{ + return n2->italic_correction(); +} + +hunits kern_pair_node::subscript_correction() +{ + return n2->subscript_correction(); +} + +void kern_pair_node::vertical_extent(vunits *min, vunits *max) +{ + n1->vertical_extent(min, max); + vunits min2, max2; + n2->vertical_extent(&min2, &max2); + if (min2 < *min) + *min = min2; + if (max2 > *max) + *max = max2; +} + +node *kern_pair_node::add_discretionary_hyphen() +{ + tfont *tf = n1->get_tfont(); + if (tf) { + if (tf->contains(soft_hyphen_char)) { + color *gcol = n2->get_glyph_color(); + color *fcol = n2->get_fill_color(); + node *next1 = next; + next = 0; + node *n = copy(); + glyph_node *gn = new glyph_node(soft_hyphen_char, tf, gcol, fcol, + state, div_nest_level); + node *nn = n->merge_glyph_node(gn); + if (nn == 0) { + gn->next = n; + nn = gn; + } + return new dbreak_node(this, nn, state, div_nest_level, next1); + } + } + return this; +} + +kern_pair_node::~kern_pair_node() +{ + if (n1 != 0) + delete n1; + if (n2 != 0) + delete n2; +} + +dbreak_node::~dbreak_node() +{ + delete_node_list(pre); + delete_node_list(post); + delete_node_list(none); +} + +node *kern_pair_node::copy() +{ + return new kern_pair_node(amount, n1->copy(), n2->copy(), state, + div_nest_level); +} + +node *copy_node_list(node *n) +{ + node *p = 0; + while (n != 0) { + node *nn = n->copy(); + nn->next = p; + p = nn; + n = n->next; + } + while (p != 0) { + node *pp = p->next; + p->next = n; + n = p; + p = pp; + } + return n; +} + +void delete_node_list(node *n) +{ + while (n != 0) { + node *tem = n; + n = n->next; + delete tem; + } +} + +node *dbreak_node::copy() +{ + dbreak_node *p = new dbreak_node(copy_node_list(none), copy_node_list(pre), + state, div_nest_level); + p->post = copy_node_list(post); + return p; +} + +hyphen_list *node::get_hyphen_list(hyphen_list *tail, int *) +{ + return tail; +} + +hyphen_list *kern_pair_node::get_hyphen_list(hyphen_list *tail, int *count) +{ + hyphen_list *hl = n2->get_hyphen_list(tail, count); + return n1->get_hyphen_list(hl, count); +} + +class hyphen_inhibitor_node : public node { +public: + hyphen_inhibitor_node(node * = 0); + node *copy(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + hyphenation_type get_hyphenation_type(); +}; + +hyphen_inhibitor_node::hyphen_inhibitor_node(node *nd) : node(nd) +{ +} + +node *hyphen_inhibitor_node::copy() +{ + return new hyphen_inhibitor_node; +} + +int hyphen_inhibitor_node::same(node *) +{ + return 1; +} + +const char *hyphen_inhibitor_node::type() +{ + return "hyphen_inhibitor_node"; +} + +int hyphen_inhibitor_node::force_tprint() +{ + return 0; +} + +int hyphen_inhibitor_node::is_tag() +{ + return 0; +} + +hyphenation_type hyphen_inhibitor_node::get_hyphenation_type() +{ + return HYPHEN_INHIBIT; +} + +/* add_discretionary_hyphen methods */ + +node *dbreak_node::add_discretionary_hyphen() +{ + if (post) + post = post->add_discretionary_hyphen(); + if (none) + none = none->add_discretionary_hyphen(); + return this; +} + +node *node::add_discretionary_hyphen() +{ + tfont *tf = get_tfont(); + if (!tf) + return new hyphen_inhibitor_node(this); + if (tf->contains(soft_hyphen_char)) { + color *gcol = get_glyph_color(); + color *fcol = get_fill_color(); + node *next1 = next; + next = 0; + node *n = copy(); + glyph_node *gn = new glyph_node(soft_hyphen_char, tf, gcol, fcol, + state, div_nest_level); + node *n1 = n->merge_glyph_node(gn); + if (n1 == 0) { + gn->next = n; + n1 = gn; + } + return new dbreak_node(this, n1, state, div_nest_level, next1); + } + return this; +} + +node *node::merge_self(node *) +{ + return 0; +} + +node *node::add_self(node *n, hyphen_list ** /*p*/) +{ + next = n; + return this; +} + +node *kern_pair_node::add_self(node *n, hyphen_list **p) +{ + n = n1->add_self(n, p); + n = n2->add_self(n, p); + n1 = n2 = 0; + delete this; + return n; +} + +hunits node::width() +{ + return H0; +} + +node *node::last_char_node() +{ + return 0; +} + +int node::force_tprint() +{ + return 0; +} + +int node::is_tag() +{ + return 0; +} + +int node::get_break_code() +{ + return 0; +} + +hunits hmotion_node::width() +{ + return n; +} + +units node::size() +{ + return points_to_units(10); +} + +void node::debug_node() +{ + fprintf(stderr, "{ %s ", type()); + if (push_state) + fprintf(stderr, " "); + if (state) + fprintf(stderr, " "); + fprintf(stderr, " nest level %d", div_nest_level); + fprintf(stderr, " }\n"); + fflush(stderr); +} + +void node::debug_node_list() +{ + node *n = next; + + debug_node(); + while (n != 0) { + n->debug_node(); + n = n->next; + } +} + +hunits kern_pair_node::width() +{ + return n1->width() + n2->width() + amount; +} + +node *kern_pair_node::last_char_node() +{ + node *nd = n2->last_char_node(); + if (nd) + return nd; + return n1->last_char_node(); +} + +hunits dbreak_node::width() +{ + hunits x = H0; + for (node *n = none; n != 0; n = n->next) + x += n->width(); + return x; +} + +node *dbreak_node::last_char_node() +{ + for (node *n = none; n; n = n->next) { + node *last_node = n->last_char_node(); + if (last_node) + return last_node; + } + return 0; +} + +hunits dbreak_node::italic_correction() +{ + return none ? none->italic_correction() : H0; +} + +hunits dbreak_node::subscript_correction() +{ + return none ? none->subscript_correction() : H0; +} + +class italic_corrected_node : public node { + node *n; + hunits x; +public: + italic_corrected_node(node *, hunits, statem *, int, node * = 0); + ~italic_corrected_node(); + node *copy(); + void ascii_print(ascii_output_file *); + void asciify(macro *); + hunits width(); + node *last_char_node(); + void vertical_extent(vunits *, vunits *); + int ends_sentence(); + int overlaps_horizontally(); + int overlaps_vertically(); + int same(node *); + hyphenation_type get_hyphenation_type(); + tfont *get_tfont(); + hyphen_list *get_hyphen_list(hyphen_list *, int *); + int character_type(); + void tprint(troff_output_file *); + hunits subscript_correction(); + hunits skew(); + node *add_self(node *, hyphen_list **); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +node *node::add_italic_correction(hunits *wd) +{ + hunits ic = italic_correction(); + if (ic.is_zero()) + return this; + else { + node *next1 = next; + next = 0; + *wd += ic; + return new italic_corrected_node(this, ic, state, div_nest_level, next1); + } +} + +italic_corrected_node::italic_corrected_node(node *nn, hunits xx, statem *s, + int pop, node *p) +: node(p, s, pop), n(nn), x(xx) +{ + assert(n != 0); +} + +italic_corrected_node::~italic_corrected_node() +{ + delete n; +} + +node *italic_corrected_node::copy() +{ + return new italic_corrected_node(n->copy(), x, state, div_nest_level); +} + +hunits italic_corrected_node::width() +{ + return n->width() + x; +} + +void italic_corrected_node::vertical_extent(vunits *min, vunits *max) +{ + n->vertical_extent(min, max); +} + +void italic_corrected_node::tprint(troff_output_file *out) +{ + n->tprint(out); + out->right(x); +} + +hunits italic_corrected_node::skew() +{ + return n->skew() - x/2; +} + +hunits italic_corrected_node::subscript_correction() +{ + return n->subscript_correction() - x; +} + +void italic_corrected_node::ascii_print(ascii_output_file *out) +{ + n->ascii_print(out); +} + +int italic_corrected_node::ends_sentence() +{ + return n->ends_sentence(); +} + +int italic_corrected_node::overlaps_horizontally() +{ + return n->overlaps_horizontally(); +} + +int italic_corrected_node::overlaps_vertically() +{ + return n->overlaps_vertically(); +} + +node *italic_corrected_node::last_char_node() +{ + return n->last_char_node(); +} + +tfont *italic_corrected_node::get_tfont() +{ + return n->get_tfont(); +} + +hyphenation_type italic_corrected_node::get_hyphenation_type() +{ + return n->get_hyphenation_type(); +} + +node *italic_corrected_node::add_self(node *nd, hyphen_list **p) +{ + nd = n->add_self(nd, p); + hunits not_interested; + nd = nd->add_italic_correction(¬_interested); + n = 0; + delete this; + return nd; +} + +hyphen_list *italic_corrected_node::get_hyphen_list(hyphen_list *tail, + int *count) +{ + return n->get_hyphen_list(tail, count); +} + +int italic_corrected_node::character_type() +{ + return n->character_type(); +} + +class break_char_node : public node { + node *ch; + char break_code; + char prev_break_code; + color *col; +public: + break_char_node(node *, int, int, color *, node * = 0); + break_char_node(node *, int, int, color *, statem *, int, node * = 0); + ~break_char_node(); + node *copy(); + hunits width(); + vunits vertical_width(); + node *last_char_node(); + int character_type(); + int ends_sentence(); + node *add_self(node *, hyphen_list **); + hyphen_list *get_hyphen_list(hyphen_list *, int *); + void tprint(troff_output_file *); + void zero_width_tprint(troff_output_file *); + void ascii_print(ascii_output_file *); + void asciify(macro *); + hyphenation_type get_hyphenation_type(); + int overlaps_vertically(); + int overlaps_horizontally(); + units size(); + tfont *get_tfont(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + int get_break_code(); +}; + +break_char_node::break_char_node(node *n, int bc, int pbc, color *c, node *x) +: node(x), ch(n), break_code(bc), prev_break_code(pbc), col(c) +{ +} + +break_char_node::break_char_node(node *n, int bc, int pbc, color *c, + statem *s, int pop, node *x) +: node(x, s, pop), ch(n), break_code(bc), prev_break_code(pbc), col(c) +{ +} + +break_char_node::~break_char_node() +{ + delete ch; +} + +node *break_char_node::copy() +{ + return new break_char_node(ch->copy(), break_code, prev_break_code, + col, state, div_nest_level); +} + +hunits break_char_node::width() +{ + return ch->width(); +} + +vunits break_char_node::vertical_width() +{ + return ch->vertical_width(); +} + +node *break_char_node::last_char_node() +{ + return ch->last_char_node(); +} + +int break_char_node::character_type() +{ + return ch->character_type(); +} + +int break_char_node::ends_sentence() +{ + return ch->ends_sentence(); +} + +enum break_char_type { + CAN_BREAK_BEFORE = 0x01, + CAN_BREAK_AFTER = 0x02, + IGNORE_HCODES = 0x04, + PROHIBIT_BREAK_BEFORE = 0x08, + PROHIBIT_BREAK_AFTER = 0x10, + INTER_CHAR_SPACE = 0x20 +}; + +node *break_char_node::add_self(node *n, hyphen_list **p) +{ + int have_space_node = 0; + assert((*p)->hyphenation_code == 0); + if (break_code & CAN_BREAK_BEFORE) { + if ((*p)->breakable || break_code & IGNORE_HCODES) { + n = new space_node(H0, col, n); + n->freeze_space(); + have_space_node = 1; + } + } + if (!have_space_node) { + if (prev_break_code & INTER_CHAR_SPACE + || prev_break_code & PROHIBIT_BREAK_AFTER) { + if (break_code & PROHIBIT_BREAK_BEFORE) + // stretchable zero-width space not implemented yet + ; + else { + // breakable, stretchable zero-width space not implemented yet + n = new space_node(H0, col, n); + n->freeze_space(); + } + } + } + next = n; + n = this; + if (break_code & CAN_BREAK_AFTER) { + if ((*p)->breakable || break_code & IGNORE_HCODES) { + n = new space_node(H0, col, n); + n->freeze_space(); + } + } + hyphen_list *pp = *p; + *p = (*p)->next; + delete pp; + return n; +} + +hyphen_list *break_char_node::get_hyphen_list(hyphen_list *tail, int *) +{ + return new hyphen_list(0, tail); +} + +hyphenation_type break_char_node::get_hyphenation_type() +{ + return HYPHEN_MIDDLE; +} + +void break_char_node::ascii_print(ascii_output_file *ascii) +{ + ch->ascii_print(ascii); +} + +int break_char_node::overlaps_vertically() +{ + return ch->overlaps_vertically(); +} + +int break_char_node::overlaps_horizontally() +{ + return ch->overlaps_horizontally(); +} + +units break_char_node::size() +{ + return ch->size(); +} + +tfont *break_char_node::get_tfont() +{ + return ch->get_tfont(); +} + +node *extra_size_node::copy() +{ + return new extra_size_node(n, state, div_nest_level); +} + +extra_size_node::extra_size_node(vunits i, statem *s, int pop) +: node(0, s, pop), n(i) +{ +} + +extra_size_node::extra_size_node(vunits i) +: n(i) +{ +} + +node *vertical_size_node::copy() +{ + return new vertical_size_node(n, state, div_nest_level); +} + +vertical_size_node::vertical_size_node(vunits i, statem *s, int pop) +: node(0, s, pop), n(i) +{ +} + +vertical_size_node::vertical_size_node(vunits i) +: n(i) +{ +} + +node *hmotion_node::copy() +{ + return new hmotion_node(n, was_tab, unformat, col, state, div_nest_level); +} + +node *space_char_hmotion_node::copy() +{ + return new space_char_hmotion_node(n, col, state, div_nest_level); +} + +vmotion_node::vmotion_node(vunits i, color *c) +: n(i), col(c) +{ +} + +vmotion_node::vmotion_node(vunits i, color *c, statem *s, int pop) +: node(0, s, pop), n(i), col(c) +{ +} + +node *vmotion_node::copy() +{ + return new vmotion_node(n, col, state, div_nest_level); +} + +node *dummy_node::copy() +{ + return new dummy_node; +} + +node *transparent_dummy_node::copy() +{ + return new transparent_dummy_node; +} + +hline_node::~hline_node() +{ + if (n) + delete n; +} + +hline_node::hline_node(hunits i, node *c, node *nxt) +: node(nxt), x(i), n(c) +{ +} + +hline_node::hline_node(hunits i, node *c, statem *s, int pop, node *nxt) +: node(nxt, s, pop), x(i), n(c) +{ +} + +node *hline_node::copy() +{ + return new hline_node(x, n ? n->copy() : 0, state, div_nest_level); +} + +hunits hline_node::width() +{ + return x < H0 ? H0 : x; +} + +vline_node::vline_node(vunits i, node *c, node *nxt) +: node(nxt), x(i), n(c) +{ +} + +vline_node::vline_node(vunits i, node *c, statem *s, int pop, node *nxt) +: node(nxt, s, pop), x(i), n(c) +{ +} + +vline_node::~vline_node() +{ + if (n) + delete n; +} + +node *vline_node::copy() +{ + return new vline_node(x, n ? n->copy() : 0, state, div_nest_level); +} + +hunits vline_node::width() +{ + return n == 0 ? H0 : n->width(); +} + +zero_width_node::zero_width_node(node *nd, statem *s, int pop) +: node(0, s, pop), n(nd) +{ +} + +zero_width_node::zero_width_node(node *nd) +: n(nd) +{ +} + +zero_width_node::~zero_width_node() +{ + delete_node_list(n); +} + +node *zero_width_node::copy() +{ + return new zero_width_node(copy_node_list(n), state, div_nest_level); +} + +int node_list_character_type(node *p) +{ + int t = 0; + for (; p; p = p->next) + t |= p->character_type(); + return t; +} + +int zero_width_node::character_type() +{ + return node_list_character_type(n); +} + +void node_list_vertical_extent(node *p, vunits *min, vunits *max) +{ + *min = V0; + *max = V0; + vunits cur_vpos = V0; + vunits v1, v2; + for (; p; p = p->next) { + p->vertical_extent(&v1, &v2); + v1 += cur_vpos; + if (v1 < *min) + *min = v1; + v2 += cur_vpos; + if (v2 > *max) + *max = v2; + cur_vpos += p->vertical_width(); + } +} + +void zero_width_node::vertical_extent(vunits *min, vunits *max) +{ + node_list_vertical_extent(n, min, max); +} + +overstrike_node::overstrike_node() +: list(0), max_width(H0) +{ +} + +overstrike_node::overstrike_node(statem *s, int pop) +: node(0, s, pop), list(0), max_width(H0) +{ +} + +overstrike_node::~overstrike_node() +{ + delete_node_list(list); +} + +node *overstrike_node::copy() +{ + overstrike_node *on = new overstrike_node(state, div_nest_level); + for (node *tem = list; tem; tem = tem->next) + on->overstrike(tem->copy()); + return on; +} + +void overstrike_node::overstrike(node *n) +{ + if (n == 0) + return; + hunits w = n->width(); + if (w > max_width) + max_width = w; + node **p; + for (p = &list; *p; p = &(*p)->next) + ; + n->next = 0; + *p = n; +} + +hunits overstrike_node::width() +{ + return max_width; +} + +bracket_node::bracket_node() +: list(0), max_width(H0) +{ +} + +bracket_node::bracket_node(statem *s, int pop) +: node(0, s, pop), list(0), max_width(H0) +{ +} + +bracket_node::~bracket_node() +{ + delete_node_list(list); +} + +node *bracket_node::copy() +{ + bracket_node *on = new bracket_node(state, div_nest_level); + node *last_node = 0; + node *tem; + if (list) + list->last = 0; + for (tem = list; tem; tem = tem->next) { + if (tem->next) + tem->next->last = tem; + last_node = tem; + } + for (tem = last_node; tem; tem = tem->last) + on->bracket(tem->copy()); + return on; +} + +void bracket_node::bracket(node *n) +{ + if (n == 0) + return; + hunits w = n->width(); + if (w > max_width) + max_width = w; + n->next = list; + list = n; +} + +hunits bracket_node::width() +{ + return max_width; +} + +int node::nspaces() +{ + return 0; +} + +int node::merge_space(hunits, hunits, hunits) +{ + return 0; +} + + +space_node::space_node(hunits nn, color *c, node *p) +: node(p, 0, 0), n(nn), set(0), was_escape_colon(0), col(c) +{ +} + +space_node::space_node(hunits nn, int s, int flag, color *c, statem *st, + int pop, node *p) +: node(p, st, pop), n(nn), set(s), was_escape_colon(flag), col(c) +{ +} + +#if 0 +space_node::~space_node() +{ +} +#endif + +node *space_node::copy() +{ + return new space_node(n, set, was_escape_colon, col, state, div_nest_level); +} + +int space_node::force_tprint() +{ + return 0; +} + +int space_node::is_tag() +{ + return 0; +} + +int space_node::nspaces() +{ + return set ? 0 : 1; +} + +int space_node::merge_space(hunits h, hunits, hunits) +{ + n += h; + return 1; +} + +hunits space_node::width() +{ + return n; +} + +void node::spread_space(int*, hunits*) +{ +} + +void space_node::spread_space(int *n_spaces, hunits *desired_space) +{ + if (!set) { + assert(*n_spaces > 0); + if (*n_spaces == 1) { + n += *desired_space; + *desired_space = H0; + } + else { + hunits extra = *desired_space / *n_spaces; + *desired_space -= extra; + n += extra; + } + *n_spaces -= 1; + set = 1; + } +} + +void node::freeze_space() +{ +} + +void space_node::freeze_space() +{ + set = 1; +} + +void node::is_escape_colon() +{ +} + +void space_node::is_escape_colon() +{ + was_escape_colon = 1; +} + +diverted_space_node::diverted_space_node(vunits d, statem *s, int pop, + node *p) +: node(p, s, pop), n(d) +{ +} + +diverted_space_node::diverted_space_node(vunits d, node *p) +: node(p), n(d) +{ +} + +node *diverted_space_node::copy() +{ + return new diverted_space_node(n, state, div_nest_level); +} + +diverted_copy_file_node::diverted_copy_file_node(symbol s, statem *st, + int pop, node *p) +: node(p, st, pop), filename(s) +{ +} + +diverted_copy_file_node::diverted_copy_file_node(symbol s, node *p) +: node(p), filename(s) +{ +} + +node *diverted_copy_file_node::copy() +{ + return new diverted_copy_file_node(filename, state, div_nest_level); +} + +int node::ends_sentence() +{ + return 0; +} + +int kern_pair_node::ends_sentence() +{ + switch (n2->ends_sentence()) { + case 0: + return 0; + case 1: + return 1; + case 2: + break; + default: + assert(0); + } + return n1->ends_sentence(); +} + +int node_list_ends_sentence(node *n) +{ + for (; n != 0; n = n->next) + switch (n->ends_sentence()) { + case 0: + return 0; + case 1: + return 1; + case 2: + break; + default: + assert(0); + } + return 2; +} + +int dbreak_node::ends_sentence() +{ + return node_list_ends_sentence(none); +} + +int node::overlaps_horizontally() +{ + return 0; +} + +int node::overlaps_vertically() +{ + return 0; +} + +int node::discardable() +{ + return 0; +} + +int space_node::discardable() +{ + return set ? 0 : 1; +} + +vunits node::vertical_width() +{ + return V0; +} + +vunits vline_node::vertical_width() +{ + return x; +} + +vunits vmotion_node::vertical_width() +{ + return n; +} + +int node::set_unformat_flag() +{ + return 1; +} + +int node::character_type() +{ + return 0; +} + +hunits node::subscript_correction() +{ + return H0; +} + +hunits node::italic_correction() +{ + return H0; +} + +hunits node::left_italic_correction() +{ + return H0; +} + +hunits node::skew() +{ + return H0; +} + +/* vertical_extent methods */ + +void node::vertical_extent(vunits *min, vunits *max) +{ + vunits v = vertical_width(); + if (v < V0) { + *min = v; + *max = V0; + } + else { + *max = v; + *min = V0; + } +} + +void vline_node::vertical_extent(vunits *min, vunits *max) +{ + if (n == 0) + node::vertical_extent(min, max); + else { + vunits cmin, cmax; + n->vertical_extent(&cmin, &cmax); + vunits h = n->size(); + if (x < V0) { + if (-x < h) { + *min = x; + *max = V0; + } + else { + // we print the first character and then move up, so + *max = cmax; + // we print the last character and then move up h + *min = cmin + h; + if (*min > V0) + *min = V0; + *min += x; + } + } + else { + if (x < h) { + *max = x; + *min = V0; + } + else { + // we move down by h and then print the first character, so + *min = cmin + h; + if (*min > V0) + *min = V0; + *max = x + cmax; + } + } + } +} + +/* ascii_print methods */ + +static void ascii_print_reverse_node_list(ascii_output_file *ascii, node *n) +{ + if (n == 0) + return; + ascii_print_reverse_node_list(ascii, n->next); + n->ascii_print(ascii); +} + +void dbreak_node::ascii_print(ascii_output_file *ascii) +{ + ascii_print_reverse_node_list(ascii, none); +} + +void kern_pair_node::ascii_print(ascii_output_file *ascii) +{ + n1->ascii_print(ascii); + n2->ascii_print(ascii); +} + +void node::ascii_print(ascii_output_file *) +{ +} + +void space_node::ascii_print(ascii_output_file *ascii) +{ + if (!n.is_zero()) + ascii->outc(' '); +} + +void hmotion_node::ascii_print(ascii_output_file *ascii) +{ + // this is pretty arbitrary + if (n >= points_to_units(2)) + ascii->outc(' '); +} + +void space_char_hmotion_node::ascii_print(ascii_output_file *ascii) +{ + ascii->outc(' '); +} + +/* asciify methods */ + +void node::asciify(macro *m) +{ + m->append(this); +} + +void glyph_node::asciify(macro *m) +{ + unsigned char c = ci->get_asciify_code(); + if (c == 0) + c = ci->get_ascii_code(); + if (c != 0) { + m->append(c); + delete this; + } + else + m->append(this); +} + +void kern_pair_node::asciify(macro *m) +{ + n1->asciify(m); + n2->asciify(m); + n1 = n2 = 0; + delete this; +} + +static void asciify_reverse_node_list(macro *m, node *n) +{ + if (n == 0) + return; + asciify_reverse_node_list(m, n->next); + n->asciify(m); +} + +void dbreak_node::asciify(macro *m) +{ + asciify_reverse_node_list(m, none); + none = 0; + delete this; +} + +void ligature_node::asciify(macro *m) +{ + n1->asciify(m); + n2->asciify(m); + n1 = n2 = 0; + delete this; +} + +void break_char_node::asciify(macro *m) +{ + ch->asciify(m); + ch = 0; + delete this; +} + +void italic_corrected_node::asciify(macro *m) +{ + n->asciify(m); + n = 0; + delete this; +} + +void left_italic_corrected_node::asciify(macro *m) +{ + if (n) { + n->asciify(m); + n = 0; + } + delete this; +} + +void hmotion_node::asciify(macro *m) +{ + if (was_tab) { + m->append('\t'); + delete this; + } + else + m->append(this); +} + +space_char_hmotion_node::space_char_hmotion_node(hunits i, color *c, + statem *s, int pop, + node *nxt) +: hmotion_node(i, c, s, pop, nxt) +{ +} + +space_char_hmotion_node::space_char_hmotion_node(hunits i, color *c, + node *nxt) +: hmotion_node(i, c, 0, 0, nxt) +{ +} + +void space_char_hmotion_node::asciify(macro *m) +{ + m->append(ESCAPE_SPACE); + delete this; +} + +void space_node::asciify(macro *m) +{ + if (was_escape_colon) { + m->append(ESCAPE_COLON); + delete this; + } + else + m->append(this); +} + +void word_space_node::asciify(macro *m) +{ + for (width_list *w = orig_width; w; w = w->next) + m->append(' '); + delete this; +} + +void unbreakable_space_node::asciify(macro *m) +{ + m->append(ESCAPE_TILDE); + delete this; +} + +void line_start_node::asciify(macro *) +{ + delete this; +} + +void vertical_size_node::asciify(macro *) +{ + delete this; +} + +breakpoint *node::get_breakpoints(hunits /*width*/, int /*nspaces*/, + breakpoint *rest, int /*is_inner*/) +{ + return rest; +} + +int node::nbreaks() +{ + return 0; +} + +breakpoint *space_node::get_breakpoints(hunits wd, int ns, + breakpoint *rest, int is_inner) +{ + if (next && next->discardable()) + return rest; + breakpoint *bp = new breakpoint; + bp->next = rest; + bp->width = wd; + bp->nspaces = ns; + bp->hyphenated = 0; + if (is_inner) { + assert(rest != 0); + bp->index = rest->index + 1; + bp->nd = rest->nd; + } + else { + bp->nd = this; + bp->index = 0; + } + return bp; +} + +int space_node::nbreaks() +{ + if (next && next->discardable()) + return 0; + else + return 1; +} + +static breakpoint *node_list_get_breakpoints(node *p, hunits *widthp, + int ns, breakpoint *rest) +{ + if (p != 0) { + rest = p->get_breakpoints(*widthp, + ns, + node_list_get_breakpoints(p->next, widthp, ns, + rest), + 1); + *widthp += p->width(); + } + return rest; +} + +breakpoint *dbreak_node::get_breakpoints(hunits wd, int ns, + breakpoint *rest, int is_inner) +{ + breakpoint *bp = new breakpoint; + bp->next = rest; + bp->width = wd; + for (node *tem = pre; tem != 0; tem = tem->next) + bp->width += tem->width(); + bp->nspaces = ns; + bp->hyphenated = 1; + if (is_inner) { + assert(rest != 0); + bp->index = rest->index + 1; + bp->nd = rest->nd; + } + else { + bp->nd = this; + bp->index = 0; + } + return node_list_get_breakpoints(none, &wd, ns, bp); +} + +int dbreak_node::nbreaks() +{ + int i = 1; + for (node *tem = none; tem != 0; tem = tem->next) + i += tem->nbreaks(); + return i; +} + +void node::split(int /*where*/, node ** /*prep*/, node ** /*postp*/) +{ + assert(0); +} + +void space_node::split(int where, node **pre, node **post) +{ + assert(where == 0); + *pre = next; + *post = 0; + delete this; +} + +static void node_list_split(node *p, int *wherep, node **prep, node **postp) +{ + if (p == 0) + return; + int nb = p->nbreaks(); + node_list_split(p->next, wherep, prep, postp); + if (*wherep < 0) { + p->next = *postp; + *postp = p; + } + else if (*wherep < nb) { + p->next = *prep; + p->split(*wherep, prep, postp); + } + else { + p->next = *prep; + *prep = p; + } + *wherep -= nb; +} + +void dbreak_node::split(int where, node **prep, node **postp) +{ + assert(where >= 0); + if (where == 0) { + *postp = post; + post = 0; + if (pre == 0) + *prep = next; + else { + node *tem; + for (tem = pre; tem->next != 0; tem = tem->next) + ; + tem->next = next; + *prep = pre; + } + pre = 0; + delete this; + } + else { + *prep = next; + where -= 1; + node_list_split(none, &where, prep, postp); + none = 0; + delete this; + } +} + +hyphenation_type node::get_hyphenation_type() +{ + return HYPHEN_BOUNDARY; +} + +hyphenation_type dbreak_node::get_hyphenation_type() +{ + return HYPHEN_INHIBIT; +} + +hyphenation_type kern_pair_node::get_hyphenation_type() +{ + return HYPHEN_MIDDLE; +} + +hyphenation_type dummy_node::get_hyphenation_type() +{ + return HYPHEN_MIDDLE; +} + +hyphenation_type transparent_dummy_node::get_hyphenation_type() +{ + return HYPHEN_MIDDLE; +} + +hyphenation_type hmotion_node::get_hyphenation_type() +{ + return HYPHEN_MIDDLE; +} + +hyphenation_type space_char_hmotion_node::get_hyphenation_type() +{ + return HYPHEN_MIDDLE; +} + +hyphenation_type overstrike_node::get_hyphenation_type() +{ + return HYPHEN_MIDDLE; +} + +hyphenation_type space_node::get_hyphenation_type() +{ + if (was_escape_colon) + return HYPHEN_MIDDLE; + return HYPHEN_BOUNDARY; +} + +hyphenation_type unbreakable_space_node::get_hyphenation_type() +{ + return HYPHEN_MIDDLE; +} + +int node::interpret(macro *) +{ + return 0; +} + +special_node::special_node(const macro &m, int n) +: mac(m), no_init_string(n) +{ + font_size fs = curenv->get_font_size(); + int char_height = curenv->get_char_height(); + int char_slant = curenv->get_char_slant(); + int fontno = env_definite_font(curenv); + tf = font_table[fontno]->get_tfont(fs, char_height, char_slant, fontno); + if (curenv->is_composite()) + tf = tf->get_plain(); + gcol = curenv->get_glyph_color(); + fcol = curenv->get_fill_color(); + is_special = 1; +} + +special_node::special_node(const macro &m, tfont *t, + color *gc, color *fc, + statem *s, int pop, + int n) +: node(0, s, pop), mac(m), tf(t), gcol(gc), fcol(fc), no_init_string(n) +{ + is_special = 1; +} + +int special_node::same(node *n) +{ + return mac == ((special_node *)n)->mac + && tf == ((special_node *)n)->tf + && gcol == ((special_node *)n)->gcol + && fcol == ((special_node *)n)->fcol + && no_init_string == ((special_node *)n)->no_init_string; +} + +const char *special_node::type() +{ + return "special_node"; +} + +int special_node::ends_sentence() +{ + return 2; +} + +int special_node::force_tprint() +{ + return 0; +} + +int special_node::is_tag() +{ + return 0; +} + +node *special_node::copy() +{ + return new special_node(mac, tf, gcol, fcol, state, div_nest_level, + no_init_string); +} + +void special_node::tprint_start(troff_output_file *out) +{ + out->start_special(tf, gcol, fcol, no_init_string); +} + +void special_node::tprint_char(troff_output_file *out, unsigned char c) +{ + out->special_char(c); +} + +void special_node::tprint_end(troff_output_file *out) +{ + out->end_special(); +} + +tfont *special_node::get_tfont() +{ + return tf; +} + +/* suppress_node */ + +suppress_node::suppress_node(int on_or_off, int issue_limits) +: is_on(on_or_off), emit_limits(issue_limits), filename(0), position(0), + image_id(0) +{ +} + +suppress_node::suppress_node(symbol f, char p, int id) +: is_on(2), emit_limits(0), filename(f), position(p), image_id(id) +{ + is_special = 1; +} + +suppress_node::suppress_node(int issue_limits, int on_or_off, + symbol f, char p, int id, + statem *s, int pop) +: node(0, s, pop), is_on(on_or_off), emit_limits(issue_limits), filename(f), + position(p), image_id(id) +{ +} + +int suppress_node::same(node *n) +{ + return ((is_on == ((suppress_node *)n)->is_on) + && (emit_limits == ((suppress_node *)n)->emit_limits) + && (filename == ((suppress_node *)n)->filename) + && (position == ((suppress_node *)n)->position) + && (image_id == ((suppress_node *)n)->image_id)); +} + +const char *suppress_node::type() +{ + return "suppress_node"; +} + +node *suppress_node::copy() +{ + return new suppress_node(emit_limits, is_on, filename, position, image_id, + state, div_nest_level); +} + +/* tag_node */ + +tag_node::tag_node() +: delayed(0) +{ + is_special = 1; +} + +tag_node::tag_node(string s, int delay) +: tag_string(s), delayed(delay) +{ + is_special = !delay; +} + +tag_node::tag_node(string s, statem *st, int pop, int delay) +: node(0, st, pop), tag_string(s), delayed(delay) +{ + is_special = !delay; +} + +node *tag_node::copy() +{ + return new tag_node(tag_string, state, div_nest_level, delayed); +} + +void tag_node::tprint(troff_output_file *out) +{ + if (delayed) + out->add_to_tag_list(tag_string); + else + out->state.add_tag(out->fp, tag_string); +} + +int tag_node::same(node *nd) +{ + return tag_string == ((tag_node *)nd)->tag_string + && delayed == ((tag_node *)nd)->delayed; +} + +const char *tag_node::type() +{ + return "tag_node"; +} + +int tag_node::force_tprint() +{ + return !delayed; +} + +int tag_node::is_tag() +{ + return !delayed; +} + +int tag_node::ends_sentence() +{ + return 2; +} + +// Get contents of register `p` as integer. +// Used only by suppress_node::tprint(). +static int get_register(const char *p) +{ + assert(p != 0 /* nullptr */); + reg *r = (reg *)register_dictionary.lookup(p); + assert(r != 0 /* nullptr */); + units value; + assert(r->get_value(&value)); + return int(value); +} + +// Get contents of register `p` as string. +// Used only by suppress_node::tprint(). +static const char *get_string(const char *p) +{ + assert(p != 0 /* nullptr */); + reg *r = (reg *)register_dictionary.lookup(p); + assert(r != 0 /* nullptr */); + return r->get_string(); +} + +void suppress_node::put(troff_output_file *out, const char *s) +{ + int i = 0; + while (s[i] != (char)0) { + out->special_char(s[i]); + i++; + } +} + +/* + * We need to remember the start of the image and its name (\O5). But + * we won't always need this information; for instance, \O2 is used to + * produce a bounding box with no associated image or position thereof. + */ + +static char last_position = 0; +static const char *image_filename = ""; +static size_t image_filename_len = 0; +static int subimage_counter = 0; + +/* + * tprint - if (is_on == 2) + * remember current position (l, r, c, i) and filename + * else + * if (emit_limits) + * if (html) + * emit image tag + * else + * emit postscript bounds for image + * else + * if (suppress boolean differs from current state) + * alter state + * reset registers + * record current page + * set low water mark. + */ + +void suppress_node::tprint(troff_output_file *out) +{ + int current_page = topdiv->get_page_number(); + // Does the node have an associated position and file name? + if (is_on == 2) { + // Save them for future bounding box limits. + last_position = position; + image_filename = strsave(filename.contents()); + image_filename_len = strlen(image_filename); + } + else { // is_on = 0 or 1 + // Now check whether the suppress node requires us to issue limits. + if (emit_limits) { + const size_t namebuflen = 8192; + char name[namebuflen] = { '\0' }; + // Jump through a flaming hoop to avoid a "format nonliteral" + // warning from blindly using sprintf...and avoid trouble from + // mischievous image stems. + // + // Keep this format string synced with pre-html:makeFileName(). + const char format[] = "%d"; + const size_t format_len = strlen(format); + const char *percent_position = strstr(image_filename, format); + if (percent_position) { + subimage_counter++; + assert(sizeof subimage_counter <= 8); + // A 64-bit signed int produces up to 19 decimal digits. + char *subimage_number = (char *)malloc(20); // 19 digits + \0 + if (0 == subimage_number) + fatal("memory allocation failure"); + // Replace the %d in the filename with this number. + size_t enough = image_filename_len + 19 - format_len; + char *new_name = (char *)malloc(enough); + if (0 == new_name) + fatal("memory allocation failure"); + ptrdiff_t prefix_length = percent_position - image_filename; + strncpy(new_name, image_filename, prefix_length); + sprintf(subimage_number, "%d", subimage_counter); + size_t number_length = strlen(subimage_number); + strcpy(new_name + prefix_length, subimage_number); + // Skip over the format in the source string. + const char *suffix_src = image_filename + prefix_length + + format_len; + char *suffix_dst = new_name + prefix_length + number_length; + strcpy(suffix_dst, suffix_src); + // Ensure the new string fits with room for a terminal '\0'. + const size_t len = strlen(new_name); + if (len > (namebuflen - 1)) + error("constructed file name in suppressed output escape" + " sequence is too long (>= %1 bytes); skipping image", + (int)namebuflen); + else + strncpy(name, new_name, (namebuflen - 1)); + free(new_name); + free(subimage_number); + } + else { + if (image_filename_len > (namebuflen - 1)) + error("file name in suppressed output escape sequence is too" + " long (>= %1 bytes); skipping image", (int)namebuflen); + else + strcpy(name, image_filename); + } + if (is_html) { + switch (last_position) { + case 'c': + out->start_special(); + put(out, "devtag:.centered-image"); + break; + case 'r': + out->start_special(); + put(out, "devtag:.right-image"); + break; + case 'l': + out->start_special(); + put(out, "devtag:.left-image"); + break; + case 'i': + ; + default: + ; + } + out->end_special(); + out->start_special(); + put(out, "devtag:.auto-image "); + put(out, name); + out->end_special(); + } + else { + // postscript (or other device) + if (suppress_start_page > 0 + && (current_page != suppress_start_page)) + error("suppression limit registers span more than a page;" + " grohtml-info for image %1 will be wrong", image_no); + // if (topdiv->get_page_number() != suppress_start_page) + // fprintf(stderr, "end of image and topdiv page = %d and" + // " suppress_start_page = %d\n", + // topdiv->get_page_number(), suppress_start_page); + + // `name` will contain a "%d" in which the image_no is placed. + fprintf(stderr, + "grohtml-info:page %d %d %d %d %d %d %s %d %d" + " %s:%s\n", + topdiv->get_page_number(), + get_register("opminx"), get_register("opminy"), + get_register("opmaxx"), get_register("opmaxy"), + // page offset + line length + get_register(".o") + get_register(".l"), + name, hresolution, vresolution, get_string(".F"), + get_string(".c")); + fflush(stderr); + } + } + else { // We are not emitting limits. + if (is_on) { + out->on(); + reset_output_registers(); + } + else + out->off(); + suppress_start_page = current_page; + } + } // is_on +} + +int suppress_node::force_tprint() +{ + return is_on; +} + +int suppress_node::is_tag() +{ + return is_on; +} + +hunits suppress_node::width() +{ + return H0; +} + +/* composite_node */ + +class composite_node : public charinfo_node { + node *n; + tfont *tf; +public: + composite_node(node *, charinfo *, tfont *, statem *, int, node * = 0); + ~composite_node(); + node *copy(); + hunits width(); + node *last_char_node(); + units size(); + void tprint(troff_output_file *); + hyphenation_type get_hyphenation_type(); + void ascii_print(ascii_output_file *); + void asciify(macro *); + hyphen_list *get_hyphen_list(hyphen_list *, int *); + node *add_self(node *, hyphen_list **); + tfont *get_tfont(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + void vertical_extent(vunits *, vunits *); + vunits vertical_width(); +}; + +composite_node::composite_node(node *p, charinfo *c, tfont *t, statem *s, + int pop, node *x) +: charinfo_node(c, s, pop, x), n(p), tf(t) +{ +} + +composite_node::~composite_node() +{ + delete_node_list(n); +} + +node *composite_node::copy() +{ + return new composite_node(copy_node_list(n), ci, tf, state, div_nest_level); +} + +hunits composite_node::width() +{ + hunits x; + if (tf->get_constant_space(&x)) + return x; + x = H0; + for (node *tem = n; tem; tem = tem->next) + x += tem->width(); + hunits offset; + if (tf->get_bold(&offset)) + x += offset; + x += tf->get_track_kern(); + return x; +} + +node *composite_node::last_char_node() +{ + return this; +} + +vunits composite_node::vertical_width() +{ + vunits v = V0; + for (node *tem = n; tem; tem = tem->next) + v += tem->vertical_width(); + return v; +} + +units composite_node::size() +{ + return tf->get_size().to_units(); +} + +hyphenation_type composite_node::get_hyphenation_type() +{ + return HYPHEN_MIDDLE; +} + +void composite_node::asciify(macro *m) +{ + unsigned char c = ci->get_asciify_code(); + if (c == 0) + c = ci->get_ascii_code(); + if (c != 0) { + m->append(c); + delete this; + } + else + m->append(this); +} + +void composite_node::ascii_print(ascii_output_file *ascii) +{ + unsigned char c = ci->get_ascii_code(); + if (c != 0) + ascii->outc(c); + else + ascii->outs(ci->nm.contents()); + +} + +hyphen_list *composite_node::get_hyphen_list(hyphen_list *tail, int *count) +{ + (*count)++; + return new hyphen_list(ci->get_hyphenation_code(), tail); +} + +node *composite_node::add_self(node *nn, hyphen_list **p) +{ + assert(ci->get_hyphenation_code() == (*p)->hyphenation_code); + next = nn; + nn = this; + if ((*p)->hyphen) + nn = nn->add_discretionary_hyphen(); + hyphen_list *pp = *p; + *p = (*p)->next; + delete pp; + return nn; +} + +tfont *composite_node::get_tfont() +{ + return tf; +} + +node *reverse_node_list(node *n) +{ + node *r = 0; + while (n) { + node *tem = n; + n = n->next; + tem->next = r; + r = tem; + } + return r; +} + +void composite_node::vertical_extent(vunits *minimum, vunits *maximum) +{ + n = reverse_node_list(n); + node_list_vertical_extent(n, minimum, maximum); + n = reverse_node_list(n); +} + +width_list::width_list(hunits w, hunits s) +: width(w), sentence_width(s), next(0) +{ +} + +width_list::width_list(width_list *w) +: width(w->width), sentence_width(w->sentence_width), next(0) +{ +} + +word_space_node::word_space_node(hunits d, color *c, width_list *w, node *x) +: space_node(d, c, x), orig_width(w), unformat(0) +{ +} + +word_space_node::word_space_node(hunits d, int s, color *c, width_list *w, + int flag, statem *st, int pop, node *x) +: space_node(d, s, 0, c, st, pop, x), orig_width(w), unformat(flag) +{ +} + +word_space_node::~word_space_node() +{ + width_list *w = orig_width; + while (w != 0) { + width_list *tmp = w; + w = w->next; + delete tmp; + } +} + +node *word_space_node::copy() +{ + assert(orig_width != 0); + width_list *w_old_curr = orig_width; + width_list *w_new_curr = new width_list(w_old_curr); + width_list *w_new = w_new_curr; + w_old_curr = w_old_curr->next; + while (w_old_curr != 0) { + w_new_curr->next = new width_list(w_old_curr); + w_new_curr = w_new_curr->next; + w_old_curr = w_old_curr->next; + } + return new word_space_node(n, set, col, w_new, unformat, state, + div_nest_level); +} + +int word_space_node::set_unformat_flag() +{ + unformat = 1; + return 1; +} + +void word_space_node::tprint(troff_output_file *out) +{ + out->fill_color(col); + out->word_marker(); + out->right(n); +} + +int word_space_node::merge_space(hunits h, hunits sw, hunits ssw) +{ + n += h; + assert(orig_width != 0); + width_list *w = orig_width; + for (; w->next; w = w->next) + ; + w->next = new width_list(sw, ssw); + return 1; +} + +unbreakable_space_node::unbreakable_space_node(hunits d, color *c, node *x) +: word_space_node(d, c, 0, x) +{ +} + +unbreakable_space_node::unbreakable_space_node(hunits d, int s, + color *c, statem *st, int pop, + node *x) +: word_space_node(d, s, c, 0, 0, st, pop, x) +{ +} + +node *unbreakable_space_node::copy() +{ + return new unbreakable_space_node(n, set, col, state, div_nest_level); +} + +int unbreakable_space_node::force_tprint() +{ + return 0; +} + +int unbreakable_space_node::is_tag() +{ + return 0; +} + +breakpoint *unbreakable_space_node::get_breakpoints(hunits, int, + breakpoint *rest, int) +{ + return rest; +} + +int unbreakable_space_node::nbreaks() +{ + return 0; +} + +void unbreakable_space_node::split(int, node **, node **) +{ + assert(0); +} + +int unbreakable_space_node::merge_space(hunits, hunits, hunits) +{ + return 0; +} + +hvpair::hvpair() +{ +} + +draw_node::draw_node(char c, hvpair *p, int np, font_size s, + color *gc, color *fc) +: npoints(np), sz(s), gcol(gc), fcol(fc), code(c) +{ + point = new hvpair[npoints]; + for (int i = 0; i < npoints; i++) + point[i] = p[i]; +} + +draw_node::draw_node(char c, hvpair *p, int np, font_size s, + color *gc, color *fc, statem *st, int pop) +: node(0, st, pop), npoints(np), sz(s), gcol(gc), fcol(fc), code(c) +{ + point = new hvpair[npoints]; + for (int i = 0; i < npoints; i++) + point[i] = p[i]; +} + +int draw_node::same(node *n) +{ + draw_node *nd = (draw_node *)n; + if (code != nd->code || npoints != nd->npoints || sz != nd->sz + || gcol != nd->gcol || fcol != nd->fcol) + return 0; + for (int i = 0; i < npoints; i++) + if (point[i].h != nd->point[i].h || point[i].v != nd->point[i].v) + return 0; + return 1; +} + +const char *draw_node::type() +{ + return "draw_node"; +} + +int draw_node::force_tprint() +{ + return 0; +} + +int draw_node::is_tag() +{ + return 0; +} + +draw_node::~draw_node() +{ + if (point) + delete[] point; +} + +hunits draw_node::width() +{ + hunits x = H0; + for (int i = 0; i < npoints; i++) + x += point[i].h; + return x; +} + +vunits draw_node::vertical_width() +{ + if (code == 'e') + return V0; + vunits x = V0; + for (int i = 0; i < npoints; i++) + x += point[i].v; + return x; +} + +node *draw_node::copy() +{ + return new draw_node(code, point, npoints, sz, gcol, fcol, state, + div_nest_level); +} + +void draw_node::tprint(troff_output_file *out) +{ + out->draw(code, point, npoints, sz, gcol, fcol); +} + +/* tprint methods */ + +void glyph_node::tprint(troff_output_file *out) +{ + tfont *ptf = tf->get_plain(); + if (ptf == tf) + out->put_char_width(ci, ptf, gcol, fcol, width(), H0); + else { + hunits offset; + int bold = tf->get_bold(&offset); + hunits w = ptf->get_width(ci); + hunits k = H0; + hunits x; + int cs = tf->get_constant_space(&x); + if (cs) { + x -= w; + if (bold) + x -= offset; + hunits x2 = x/2; + out->right(x2); + k = x - x2; + } + else + k = tf->get_track_kern(); + if (bold) { + out->put_char(ci, ptf, gcol, fcol); + out->right(offset); + } + out->put_char_width(ci, ptf, gcol, fcol, w, k); + } +} + +void glyph_node::zero_width_tprint(troff_output_file *out) +{ + tfont *ptf = tf->get_plain(); + hunits offset; + int bold = tf->get_bold(&offset); + hunits x; + int cs = tf->get_constant_space(&x); + if (cs) { + x -= ptf->get_width(ci); + if (bold) + x -= offset; + x = x/2; + out->right(x); + } + out->put_char(ci, ptf, gcol, fcol); + if (bold) { + out->right(offset); + out->put_char(ci, ptf, gcol, fcol); + out->right(-offset); + } + if (cs) + out->right(-x); +} + +void break_char_node::tprint(troff_output_file *t) +{ + ch->tprint(t); +} + +void break_char_node::zero_width_tprint(troff_output_file *t) +{ + ch->zero_width_tprint(t); +} + +void hline_node::tprint(troff_output_file *out) +{ + if (x < H0) { + out->right(x); + x = -x; + } + if (n == 0) { + out->right(x); + return; + } + hunits w = n->width(); + if (w <= H0) { + error("horizontal line drawing character must have positive width"); + out->right(x); + return; + } + int i = int(x/w); + if (i == 0) { + hunits xx = x - w; + hunits xx2 = xx/2; + out->right(xx2); + if (out->is_on()) + n->tprint(out); + out->right(xx - xx2); + } + else { + hunits rem = x - w*i; + if (rem > H0) { + if (n->overlaps_horizontally()) { + if (out->is_on()) + n->tprint(out); + out->right(rem - w); + } + else + out->right(rem); + } + while (--i >= 0) + if (out->is_on()) + n->tprint(out); + } +} + +void vline_node::tprint(troff_output_file *out) +{ + if (n == 0) { + out->down(x); + return; + } + vunits h = n->size(); + int overlaps = n->overlaps_vertically(); + vunits y = x; + if (y < V0) { + y = -y; + int i = y / h; + vunits rem = y - i*h; + if (i == 0) { + out->right(n->width()); + out->down(-rem); + } + else { + while (--i > 0) { + n->zero_width_tprint(out); + out->down(-h); + } + if (overlaps) { + n->zero_width_tprint(out); + out->down(-rem); + if (out->is_on()) + n->tprint(out); + out->down(-h); + } + else { + if (out->is_on()) + n->tprint(out); + out->down(-h - rem); + } + } + } + else { + int i = y / h; + vunits rem = y - i*h; + if (i == 0) { + out->down(rem); + out->right(n->width()); + } + else { + out->down(h); + if (overlaps) + n->zero_width_tprint(out); + out->down(rem); + while (--i > 0) { + n->zero_width_tprint(out); + out->down(h); + } + if (out->is_on()) + n->tprint(out); + } + } +} + +void zero_width_node::tprint(troff_output_file *out) +{ + if (!n) + return; + if (!n->next) { + n->zero_width_tprint(out); + return; + } + int hpos = out->get_hpos(); + int vpos = out->get_vpos(); + node *tem = n; + while (tem) { + tem->tprint(out); + tem = tem->next; + } + out->moveto(hpos, vpos); +} + +void overstrike_node::tprint(troff_output_file *out) +{ + hunits pos = H0; + for (node *tem = list; tem; tem = tem->next) { + hunits x = (max_width - tem->width())/2; + out->right(x - pos); + pos = x; + tem->zero_width_tprint(out); + } + out->right(max_width - pos); +} + +void bracket_node::tprint(troff_output_file *out) +{ + if (list == 0) + return; + int npieces = 0; + node *tem; + for (tem = list; tem; tem = tem->next) + ++npieces; + vunits h = list->size(); + vunits totalh = h*npieces; + vunits y = (totalh - h)/2; + out->down(y); + for (tem = list; tem; tem = tem->next) { + tem->zero_width_tprint(out); + out->down(-h); + } + out->right(max_width); + out->down(totalh - y); +} + +void node::tprint(troff_output_file *) +{ +} + +void node::zero_width_tprint(troff_output_file *out) +{ + int hpos = out->get_hpos(); + int vpos = out->get_vpos(); + tprint(out); + out->moveto(hpos, vpos); +} + +void space_node::tprint(troff_output_file *out) +{ + out->fill_color(col); + out->right(n); +} + +void hmotion_node::tprint(troff_output_file *out) +{ + out->fill_color(col); + out->right(n); +} + +void space_char_hmotion_node::tprint(troff_output_file *out) +{ + out->fill_color(col); + if (is_html) { + // we emit the space width as a negative glyph index + out->flush_tbuf(); + out->do_motion(); + out->put('N'); + out->put(-n.to_units()); + out->put('\n'); + } + out->right(n); +} + +void vmotion_node::tprint(troff_output_file *out) +{ + out->fill_color(col); + out->down(n); +} + +void kern_pair_node::tprint(troff_output_file *out) +{ + n1->tprint(out); + out->right(amount); + n2->tprint(out); +} + +static void tprint_reverse_node_list(troff_output_file *out, node *n) +{ + if (n == 0) + return; + tprint_reverse_node_list(out, n->next); + n->tprint(out); +} + +void dbreak_node::tprint(troff_output_file *out) +{ + tprint_reverse_node_list(out, none); +} + +void composite_node::tprint(troff_output_file *out) +{ + hunits bold_offset; + int is_bold = tf->get_bold(&bold_offset); + hunits track_kern = tf->get_track_kern(); + hunits constant_space; + int is_constant_spaced = tf->get_constant_space(&constant_space); + hunits x = H0; + if (is_constant_spaced) { + x = constant_space; + for (node *tem = n; tem; tem = tem->next) + x -= tem->width(); + if (is_bold) + x -= bold_offset; + hunits x2 = x/2; + out->right(x2); + x -= x2; + } + if (is_bold) { + int hpos = out->get_hpos(); + int vpos = out->get_vpos(); + tprint_reverse_node_list(out, n); + out->moveto(hpos, vpos); + out->right(bold_offset); + } + tprint_reverse_node_list(out, n); + if (is_constant_spaced) + out->right(x); + else + out->right(track_kern); +} + +static node *make_composite_node(charinfo *s, environment *env) +{ + int fontno = env_definite_font(env); + if (fontno < 0) { + error("cannot format composite glyph: no current font"); + return 0; + } + assert(fontno < font_table_size && font_table[fontno] != 0); + node *n = charinfo_to_node_list(s, env); + font_size fs = env->get_font_size(); + int char_height = env->get_char_height(); + int char_slant = env->get_char_slant(); + tfont *tf = font_table[fontno]->get_tfont(fs, char_height, char_slant, + fontno); + if (env->is_composite()) + tf = tf->get_plain(); + return new composite_node(n, s, tf, 0, 0, 0); +} + +static node *make_glyph_node(charinfo *s, environment *env, + bool want_warnings = true) +{ + int fontno = env_definite_font(env); + if (fontno < 0) { + error("cannot format glyph: no current font"); + return 0; + } + assert(fontno < font_table_size && font_table[fontno] != 0); + int fn = fontno; + int found = font_table[fontno]->contains(s); + if (!found) { + macro *mac = s->get_macro(); + if (mac && s->is_fallback()) + return make_composite_node(s, env); + if (s->numbered()) { + if (want_warnings) + warning(WARN_CHAR, "character code %1 not defined in current" + " font", s->get_number()); + return 0; + } + special_font_list *sf = font_table[fontno]->sf; + while (sf != 0 && !found) { + fn = sf->n; + if (font_table[fn]) + found = font_table[fn]->contains(s); + sf = sf->next; + } + if (!found) { + symbol f = font_table[fontno]->get_name(); + string gl(f.contents()); + gl += ' '; + gl += s->nm.contents(); + gl += '\0'; + charinfo *ci = get_charinfo(symbol(gl.contents())); + if (ci && ci->get_macro()) + return make_composite_node(ci, env); + } + if (!found) { + sf = global_special_fonts; + while (sf != 0 && !found) { + fn = sf->n; + if (font_table[fn]) + found = font_table[fn]->contains(s); + sf = sf->next; + } + } + if (!found) + if (mac && s->is_special()) + return make_composite_node(s, env); + if (!found) { + for (fn = 0; fn < font_table_size; fn++) + if (font_table[fn] + && font_table[fn]->is_special() + && font_table[fn]->contains(s)) { + found = 1; + break; + } + } + if (!found) { + if (want_warnings && s->first_time_not_found()) { + unsigned char input_code = s->get_ascii_code(); + if (input_code != 0) { + if (csgraph(input_code)) + warning(WARN_CHAR, "character '%1' not defined", + input_code); + else + warning(WARN_CHAR, "character with input code %1 not" + " defined", int(input_code)); + } + else if (s->nm.contents()) { + const char *nm = s->nm.contents(); + const char *backslash = (nm[1] == 0) ? "\\" : ""; + warning(WARN_CHAR, "special character '%1%2' not defined", + backslash, nm); + } + } + return 0; + } + } + font_size fs = env->get_font_size(); + int char_height = env->get_char_height(); + int char_slant = env->get_char_slant(); + tfont *tf = font_table[fontno]->get_tfont(fs, char_height, char_slant, fn); + if (env->is_composite()) + tf = tf->get_plain(); + color *gcol = env->get_glyph_color(); + color *fcol = env->get_fill_color(); + return new glyph_node(s, tf, gcol, fcol, 0, 0); +} + +node *make_node(charinfo *ci, environment *env) +{ + switch (ci->get_special_translation()) { + case charinfo::TRANSLATE_SPACE: + return new space_char_hmotion_node(env->get_space_width(), + env->get_fill_color()); + case charinfo::TRANSLATE_STRETCHABLE_SPACE: + return new unbreakable_space_node(env->get_space_width(), + env->get_fill_color()); + case charinfo::TRANSLATE_DUMMY: + return new dummy_node; + case charinfo::TRANSLATE_HYPHEN_INDICATOR: + error("translation to \\%% ignored in this context"); + break; + } + charinfo *tem = ci->get_translation(); + if (tem) + ci = tem; + macro *mac = ci->get_macro(); + if (mac && ci->is_normal()) + return make_composite_node(ci, env); + else + return make_glyph_node(ci, env); +} + +bool character_exists(charinfo *ci, environment *env) +{ + if (ci->get_special_translation() != charinfo::TRANSLATE_NONE) + return true; + charinfo *tem = ci->get_translation(); + if (tem) + ci = tem; + if (ci->get_macro()) + return true; + node *nd = make_glyph_node(ci, env, false /* don't want warnings */); + if (nd) { + delete nd; + return true; + } + return false; +} + +node *node::add_char(charinfo *ci, environment *env, + hunits *widthp, int *spacep, node **glyph_comp_np) +{ + node *res; + switch (ci->get_special_translation()) { + case charinfo::TRANSLATE_SPACE: + res = new space_char_hmotion_node(env->get_space_width(), + env->get_fill_color(), this); + *widthp += res->width(); + return res; + case charinfo::TRANSLATE_STRETCHABLE_SPACE: + res = new unbreakable_space_node(env->get_space_width(), + env->get_fill_color(), this); + res->freeze_space(); + *widthp += res->width(); + *spacep += res->nspaces(); + return res; + case charinfo::TRANSLATE_DUMMY: + return new dummy_node(this); + case charinfo::TRANSLATE_HYPHEN_INDICATOR: + return add_discretionary_hyphen(); + } + charinfo *tem = ci->get_translation(); + if (tem) + ci = tem; + macro *mac = ci->get_macro(); + if (mac && ci->is_normal()) { + res = make_composite_node(ci, env); + if (res) { + res->next = this; + *widthp += res->width(); + if (glyph_comp_np) + *glyph_comp_np = res; + } + else { + if (glyph_comp_np) + *glyph_comp_np = res; + return this; + } + } + else { + node *gn = make_glyph_node(ci, env); + if (gn == 0) + return this; + else { + hunits old_width = width(); + node *p = gn->merge_self(this); + if (p == 0) { + *widthp += gn->width(); + gn->next = this; + res = gn; + } + else { + *widthp += p->width() - old_width; + res = p; + } + if (glyph_comp_np) + *glyph_comp_np = res; + } + } + int break_code = 0; + if (ci->can_break_before()) + break_code = CAN_BREAK_BEFORE; + if (ci->can_break_after()) + break_code |= CAN_BREAK_AFTER; + if (ci->ignore_hcodes()) + break_code |= IGNORE_HCODES; + if (ci->prohibit_break_before()) + break_code = PROHIBIT_BREAK_BEFORE; + if (ci->prohibit_break_after()) + break_code |= PROHIBIT_BREAK_AFTER; + if (ci->inter_char_space()) + break_code |= INTER_CHAR_SPACE; + if (break_code) { + node *next1 = res->next; + res->next = 0; + res = new break_char_node(res, break_code, get_break_code(), + env->get_fill_color(), next1); + } + return res; +} + +#ifdef __GNUG__ +inline +#endif +int same_node(node *n1, node *n2) +{ + if (n1 != 0) { + if (n2 != 0) + return n1->type() == n2->type() && n1->same(n2); + else + return 0; + } + else + return n2 == 0; +} + +int same_node_list(node *n1, node *n2) +{ + while (n1 && n2) { + if (n1->type() != n2->type() || !n1->same(n2)) + return 0; + n1 = n1->next; + n2 = n2->next; + } + return !n1 && !n2; +} + +int extra_size_node::same(node *nd) +{ + return n == ((extra_size_node *)nd)->n; +} + +const char *extra_size_node::type() +{ + return "extra_size_node"; +} + +int extra_size_node::force_tprint() +{ + return 0; +} + +int extra_size_node::is_tag() +{ + return 0; +} + +int vertical_size_node::same(node *nd) +{ + return n == ((vertical_size_node *)nd)->n; +} + +const char *vertical_size_node::type() +{ + return "vertical_size_node"; +} + +int vertical_size_node::set_unformat_flag() +{ + return 0; +} + +int vertical_size_node::force_tprint() +{ + return 0; +} + +int vertical_size_node::is_tag() +{ + return 0; +} + +int hmotion_node::same(node *nd) +{ + return n == ((hmotion_node *)nd)->n + && col == ((hmotion_node *)nd)->col; +} + +const char *hmotion_node::type() +{ + return "hmotion_node"; +} + +int hmotion_node::set_unformat_flag() +{ + unformat = 1; + return 1; +} + +int hmotion_node::force_tprint() +{ + return 0; +} + +int hmotion_node::is_tag() +{ + return 0; +} + +node *hmotion_node::add_self(node *nd, hyphen_list **p) +{ + next = nd; + hyphen_list *pp = *p; + *p = (*p)->next; + delete pp; + return this; +} + +hyphen_list *hmotion_node::get_hyphen_list(hyphen_list *tail, int *) +{ + return new hyphen_list(0, tail); +} + +int space_char_hmotion_node::same(node *nd) +{ + return n == ((space_char_hmotion_node *)nd)->n + && col == ((space_char_hmotion_node *)nd)->col; +} + +const char *space_char_hmotion_node::type() +{ + return "space_char_hmotion_node"; +} + +int space_char_hmotion_node::force_tprint() +{ + return 0; +} + +int space_char_hmotion_node::is_tag() +{ + return 0; +} + +node *space_char_hmotion_node::add_self(node *nd, hyphen_list **p) +{ + next = nd; + hyphen_list *pp = *p; + *p = (*p)->next; + delete pp; + return this; +} + +hyphen_list *space_char_hmotion_node::get_hyphen_list(hyphen_list *tail, + int *) +{ + return new hyphen_list(0, tail); +} + +int vmotion_node::same(node *nd) +{ + return n == ((vmotion_node *)nd)->n + && col == ((vmotion_node *)nd)->col; +} + +const char *vmotion_node::type() +{ + return "vmotion_node"; +} + +int vmotion_node::force_tprint() +{ + return 0; +} + +int vmotion_node::is_tag() +{ + return 0; +} + +int hline_node::same(node *nd) +{ + return x == ((hline_node *)nd)->x && same_node(n, ((hline_node *)nd)->n); +} + +const char *hline_node::type() +{ + return "hline_node"; +} + +int hline_node::force_tprint() +{ + return 0; +} + +int hline_node::is_tag() +{ + return 0; +} + +int vline_node::same(node *nd) +{ + return x == ((vline_node *)nd)->x && same_node(n, ((vline_node *)nd)->n); +} + +const char *vline_node::type() +{ + return "vline_node"; +} + +int vline_node::force_tprint() +{ + return 0; +} + +int vline_node::is_tag() +{ + return 0; +} + +int dummy_node::same(node * /*nd*/) +{ + return 1; +} + +const char *dummy_node::type() +{ + return "dummy_node"; +} + +int dummy_node::force_tprint() +{ + return 0; +} + +int dummy_node::is_tag() +{ + return 0; +} + +int transparent_dummy_node::same(node * /*nd*/) +{ + return 1; +} + +const char *transparent_dummy_node::type() +{ + return "transparent_dummy_node"; +} + +int transparent_dummy_node::force_tprint() +{ + return 0; +} + +int transparent_dummy_node::is_tag() +{ + return 0; +} + +int transparent_dummy_node::ends_sentence() +{ + return 2; +} + +int zero_width_node::same(node *nd) +{ + return same_node_list(n, ((zero_width_node *)nd)->n); +} + +const char *zero_width_node::type() +{ + return "zero_width_node"; +} + +int zero_width_node::force_tprint() +{ + return 0; +} + +int zero_width_node::is_tag() +{ + return 0; +} + +int italic_corrected_node::same(node *nd) +{ + return (x == ((italic_corrected_node *)nd)->x + && same_node(n, ((italic_corrected_node *)nd)->n)); +} + +const char *italic_corrected_node::type() +{ + return "italic_corrected_node"; +} + +int italic_corrected_node::force_tprint() +{ + return 0; +} + +int italic_corrected_node::is_tag() +{ + return 0; +} + +left_italic_corrected_node::left_italic_corrected_node(node *xx) +: node(xx), n(0) +{ +} + +left_italic_corrected_node::left_italic_corrected_node(statem *s, int pop, + node *xx) +: node(xx, s, pop), n(0) +{ +} + +left_italic_corrected_node::~left_italic_corrected_node() +{ + delete n; +} + +node *left_italic_corrected_node::merge_glyph_node(glyph_node *gn) +{ + if (n == 0) { + hunits lic = gn->left_italic_correction(); + if (!lic.is_zero()) { + x = lic; + n = gn; + return this; + } + } + else { + node *nd = n->merge_glyph_node(gn); + if (nd) { + n = nd; + x = n->left_italic_correction(); + return this; + } + } + return 0; +} + +node *left_italic_corrected_node::copy() +{ + left_italic_corrected_node *nd = + new left_italic_corrected_node(state, div_nest_level); + if (n) { + nd->n = n->copy(); + nd->x = x; + } + return nd; +} + +void left_italic_corrected_node::tprint(troff_output_file *out) +{ + if (n) { + out->right(x); + n->tprint(out); + } +} + +const char *left_italic_corrected_node::type() +{ + return "left_italic_corrected_node"; +} + +int left_italic_corrected_node::force_tprint() +{ + return 0; +} + +int left_italic_corrected_node::is_tag() +{ + return 0; +} + +int left_italic_corrected_node::same(node *nd) +{ + return (x == ((left_italic_corrected_node *)nd)->x + && same_node(n, ((left_italic_corrected_node *)nd)->n)); +} + +void left_italic_corrected_node::ascii_print(ascii_output_file *out) +{ + if (n) + n->ascii_print(out); +} + +hunits left_italic_corrected_node::width() +{ + return n ? n->width() + x : H0; +} + +void left_italic_corrected_node::vertical_extent(vunits *minimum, + vunits *maximum) +{ + if (n) + n->vertical_extent(minimum, maximum); + else + node::vertical_extent(minimum, maximum); +} + +hunits left_italic_corrected_node::skew() +{ + return n ? n->skew() + x/2 : H0; +} + +hunits left_italic_corrected_node::subscript_correction() +{ + return n ? n->subscript_correction() : H0; +} + +hunits left_italic_corrected_node::italic_correction() +{ + return n ? n->italic_correction() : H0; +} + +int left_italic_corrected_node::ends_sentence() +{ + return n ? n->ends_sentence() : 0; +} + +int left_italic_corrected_node::overlaps_horizontally() +{ + return n ? n->overlaps_horizontally() : 0; +} + +int left_italic_corrected_node::overlaps_vertically() +{ + return n ? n->overlaps_vertically() : 0; +} + +node *left_italic_corrected_node::last_char_node() +{ + return n ? n->last_char_node() : 0; +} + +tfont *left_italic_corrected_node::get_tfont() +{ + return n ? n->get_tfont() : 0; +} + +hyphenation_type left_italic_corrected_node::get_hyphenation_type() +{ + if (n) + return n->get_hyphenation_type(); + else + return HYPHEN_MIDDLE; +} + +hyphen_list *left_italic_corrected_node::get_hyphen_list(hyphen_list *tail, + int *count) +{ + return n ? n->get_hyphen_list(tail, count) : tail; +} + +node *left_italic_corrected_node::add_self(node *nd, hyphen_list **p) +{ + if (n) { + nd = new left_italic_corrected_node(state, div_nest_level, nd); + nd = n->add_self(nd, p); + n = 0; + delete this; + return nd; + } + else { + next = nd; + return this; + } +} + +int left_italic_corrected_node::character_type() +{ + return n ? n->character_type() : 0; +} + +int overstrike_node::same(node *nd) +{ + return same_node_list(list, ((overstrike_node *)nd)->list); +} + +const char *overstrike_node::type() +{ + return "overstrike_node"; +} + +int overstrike_node::force_tprint() +{ + return 0; +} + +int overstrike_node::is_tag() +{ + return 0; +} + +node *overstrike_node::add_self(node *n, hyphen_list **p) +{ + next = n; + hyphen_list *pp = *p; + *p = (*p)->next; + delete pp; + return this; +} + +hyphen_list *overstrike_node::get_hyphen_list(hyphen_list *tail, int *) +{ + return new hyphen_list(0, tail); +} + +int bracket_node::same(node *nd) +{ + return same_node_list(list, ((bracket_node *)nd)->list); +} + +const char *bracket_node::type() +{ + return "bracket_node"; +} + +int bracket_node::force_tprint() +{ + return 0; +} + +int bracket_node::is_tag() +{ + return 0; +} + +int composite_node::same(node *nd) +{ + return ci == ((composite_node *)nd)->ci + && same_node_list(n, ((composite_node *)nd)->n); +} + +const char *composite_node::type() +{ + return "composite_node"; +} + +int composite_node::force_tprint() +{ + return 0; +} + +int composite_node::is_tag() +{ + return 0; +} + +int glyph_node::same(node *nd) +{ + return ci == ((glyph_node *)nd)->ci + && tf == ((glyph_node *)nd)->tf + && gcol == ((glyph_node *)nd)->gcol + && fcol == ((glyph_node *)nd)->fcol; +} + +const char *glyph_node::type() +{ + return "glyph_node"; +} + +int glyph_node::force_tprint() +{ + return 0; +} + +int glyph_node::is_tag() +{ + return 0; +} + +int ligature_node::same(node *nd) +{ + return (same_node(n1, ((ligature_node *)nd)->n1) + && same_node(n2, ((ligature_node *)nd)->n2) + && glyph_node::same(nd)); +} + +const char *ligature_node::type() +{ + return "ligature_node"; +} + +int ligature_node::force_tprint() +{ + return 0; +} + +int ligature_node::is_tag() +{ + return 0; +} + +int kern_pair_node::same(node *nd) +{ + return (amount == ((kern_pair_node *)nd)->amount + && same_node(n1, ((kern_pair_node *)nd)->n1) + && same_node(n2, ((kern_pair_node *)nd)->n2)); +} + +const char *kern_pair_node::type() +{ + return "kern_pair_node"; +} + +int kern_pair_node::force_tprint() +{ + return 0; +} + +int kern_pair_node::is_tag() +{ + return 0; +} + +int dbreak_node::same(node *nd) +{ + return (same_node_list(none, ((dbreak_node *)nd)->none) + && same_node_list(pre, ((dbreak_node *)nd)->pre) + && same_node_list(post, ((dbreak_node *)nd)->post)); +} + +const char *dbreak_node::type() +{ + return "dbreak_node"; +} + +int dbreak_node::force_tprint() +{ + return 0; +} + +int dbreak_node::is_tag() +{ + return 0; +} + +int break_char_node::same(node *nd) +{ + return break_code == ((break_char_node *)nd)->break_code + && col == ((break_char_node *)nd)->col + && same_node(ch, ((break_char_node *)nd)->ch); +} + +const char *break_char_node::type() +{ + return "break_char_node"; +} + +int break_char_node::force_tprint() +{ + return 0; +} + +int break_char_node::is_tag() +{ + return 0; +} + +int break_char_node::get_break_code() +{ + return break_code; +} + +int line_start_node::same(node * /*nd*/) +{ + return 1; +} + +const char *line_start_node::type() +{ + return "line_start_node"; +} + +int line_start_node::force_tprint() +{ + return 0; +} + +int line_start_node::is_tag() +{ + return 0; +} + +int space_node::same(node *nd) +{ + return n == ((space_node *)nd)->n + && set == ((space_node *)nd)->set + && col == ((space_node *)nd)->col; +} + +const char *space_node::type() +{ + return "space_node"; +} + +int word_space_node::same(node *nd) +{ + return n == ((word_space_node *)nd)->n + && set == ((word_space_node *)nd)->set + && col == ((word_space_node *)nd)->col; +} + +const char *word_space_node::type() +{ + return "word_space_node"; +} + +int word_space_node::force_tprint() +{ + return 0; +} + +int word_space_node::is_tag() +{ + return 0; +} + +void unbreakable_space_node::tprint(troff_output_file *out) +{ + out->fill_color(col); + if (is_html) { + // we emit the space width as a negative glyph index + out->flush_tbuf(); + out->do_motion(); + out->put('N'); + out->put(-n.to_units()); + out->put('\n'); + } + out->right(n); +} + +int unbreakable_space_node::same(node *nd) +{ + return n == ((unbreakable_space_node *)nd)->n + && set == ((unbreakable_space_node *)nd)->set + && col == ((unbreakable_space_node *)nd)->col; +} + +const char *unbreakable_space_node::type() +{ + return "unbreakable_space_node"; +} + +node *unbreakable_space_node::add_self(node *nd, hyphen_list **p) +{ + next = nd; + hyphen_list *pp = *p; + *p = (*p)->next; + delete pp; + return this; +} + +hyphen_list *unbreakable_space_node::get_hyphen_list(hyphen_list *tail, int *) +{ + return new hyphen_list(0, tail); +} + +int diverted_space_node::same(node *nd) +{ + return n == ((diverted_space_node *)nd)->n; +} + +const char *diverted_space_node::type() +{ + return "diverted_space_node"; +} + +int diverted_space_node::force_tprint() +{ + return 0; +} + +int diverted_space_node::is_tag() +{ + return 0; +} + +int diverted_copy_file_node::same(node *nd) +{ + return filename == ((diverted_copy_file_node *)nd)->filename; +} + +const char *diverted_copy_file_node::type() +{ + return "diverted_copy_file_node"; +} + +int diverted_copy_file_node::force_tprint() +{ + return 0; +} + +int diverted_copy_file_node::is_tag() +{ + return 0; +} + +// Grow the font_table so that its size is > n. + +static void grow_font_table(int n) +{ + assert(n >= font_table_size); + font_info **old_font_table = font_table; + int old_font_table_size = font_table_size; + font_table_size = font_table_size ? (font_table_size*3)/2 : 10; + if (font_table_size <= n) + font_table_size = n + 10; + font_table = new font_info *[font_table_size]; + if (old_font_table_size) + memcpy(font_table, old_font_table, + old_font_table_size*sizeof(font_info *)); + delete[] old_font_table; + for (int i = old_font_table_size; i < font_table_size; i++) + font_table[i] = 0; +} + +dictionary font_translation_dictionary(17); + +static symbol get_font_translation(symbol nm) +{ + void *p = font_translation_dictionary.lookup(nm); + return p ? symbol((char *)p) : nm; +} + +dictionary font_dictionary(50); + +static bool mount_font_no_translate(int n, symbol name, + symbol external_name, + bool check_only = false) +{ + assert(n >= 0); + // We store the address of this char in `font_dictionary` to indicate + // that we've previously tried to mount the font and failed. + static char a_char; + font *fm = 0 /* nullptr */; + void *p = font_dictionary.lookup(external_name); + if (0 /* nullptr */ == p) { + fm = font::load_font(external_name.contents(), check_only); + if (check_only) + return fm != 0 /* nullptr */; + if (0 /* nullptr */ == fm) { + (void)font_dictionary.lookup(external_name, &a_char); + return false; + } + (void)font_dictionary.lookup(name, fm); + } + else if (p == &a_char) { + return false; + } + else + fm = (font*)p; + if (check_only) + return true; + if (n >= font_table_size) { + if (n - font_table_size > 1000) { + error("font position too much larger than first unused position"); + return false; + } + grow_font_table(n); + } + else if (font_table[n] != 0 /* nullptr */) + delete font_table[n]; + font_table[n] = new font_info(name, n, external_name, fm); + font_family::invalidate_fontno(n); + return true; +} + +bool mount_font(int n, symbol name, symbol external_name) +{ + assert(n >= 0); + name = get_font_translation(name); + if (external_name.is_null()) + external_name = name; + else + external_name = get_font_translation(external_name); + return mount_font_no_translate(n, name, external_name); +} + +int check_font(symbol fam, symbol name) +{ + if (check_style(name)) + name = concat(fam, name); + return mount_font_no_translate(0, name, name, true /* check only */); +} + +int check_style(symbol s) +{ + int i = symbol_fontno(s); + return i < 0 ? 0 : font_table[i]->is_style(); +} + +bool mount_style(int n, symbol name) +{ + assert(n >= 0); + if (n >= font_table_size) { + if (n - font_table_size > 1000) { + error("font position too much larger than first unused position"); + return false; + } + grow_font_table(n); + } + else if (font_table[n] != 0) + delete font_table[n]; + font_table[n] = new font_info(get_font_translation(name), n, + NULL_SYMBOL, 0); + font_family::invalidate_fontno(n); + return true; +} + +/* global functions */ + +void font_translate() +{ + symbol from = get_name(true /* required */); + if (!from.is_null()) { + symbol to = get_name(); + if (to.is_null() || from == to) + font_translation_dictionary.remove(from); + else + (void)font_translation_dictionary.lookup(from, (void *)to.contents()); + } + skip_line(); +} + +void font_position() +{ + int n; + if (get_integer(&n)) { + if (n < 0) + error("negative font position"); + else { + symbol internal_name = get_name(true /* required */); + if (!internal_name.is_null()) { + symbol external_name = get_long_name(); + if (!mount_font(n, internal_name, external_name)) { + string msg; + if (external_name != 0 /* nullptr */) + msg += string(" from file '") + external_name.contents() + + string("'"); + msg += '\0'; + error("cannot load font '%1'%2 for mounting", + internal_name.contents(), msg.contents()); + } + } + } + } + skip_line(); +} + +font_family::font_family(symbol s) +: map_size(10), nm(s) +{ + map = new int[map_size]; + for (int i = 0; i < map_size; i++) + map[i] = -1; +} + +font_family::~font_family() +{ + delete[] map; +} + +// Resolve a requested font mounting position to a mounting position +// usable by the output driver. (Positions 1 through 4 are typically +// allocated to styles, and are not usable thus.) A return value of +// `-1` indicates failure. +int font_family::make_definite(int mounting_position) +{ + assert(mounting_position >= 0); + int pos = mounting_position; + if (pos < 0) + return -1; + if (pos < map_size && map[pos] >= 0) + return map[pos]; + if (!(pos < font_table_size && font_table[pos] != 0)) + return -1; + if (pos >= map_size) { + int old_map_size = map_size; + int *old_map = map; + map_size *= 3; + map_size /= 2; + if (pos >= map_size) + map_size = pos + 10; + map = new int[map_size]; + memcpy(map, old_map, old_map_size * sizeof (int)); + delete[] old_map; + for (int j = old_map_size; j < map_size; j++) + map[j] = -1; + } + if (!(font_table[pos]->is_style())) + return map[pos] = pos; + symbol sty = font_table[pos]->get_name(); + symbol f = concat(nm, sty); + int n; + // Don't use symbol_fontno, because that might return a style and + // because we don't want to translate the name. + for (n = 0; n < font_table_size; n++) + if (font_table[n] != 0 && font_table[n]->is_named(f) + && !font_table[n]->is_style()) + break; + if (n >= font_table_size) { + n = next_available_font_position(); + if (!mount_font_no_translate(n, f, f)) + return -1; + } + return map[pos] = n; +} + +dictionary family_dictionary(5); + +font_family *lookup_family(symbol nm) +{ + font_family *f = (font_family *)family_dictionary.lookup(nm); + if (!f) { + f = new font_family(nm); + (void)family_dictionary.lookup(nm, f); + } + return f; +} + +void font_family::invalidate_fontno(int n) +{ + assert(n >= 0 && n < font_table_size); + dictionary_iterator iter(family_dictionary); + symbol nam; + font_family *fam; + while (iter.get(&nam, (void **)&fam)) { + int mapsize = fam->map_size; + if (n < mapsize) + fam->map[n] = -1; + for (int i = 0; i < mapsize; i++) + if (fam->map[i] == n) + fam->map[i] = -1; + } +} + +void style() +{ + int n; + if (get_integer(&n)) { + if (n < 0) + error("negative font position"); + else { + symbol internal_name = get_name(true /* required */); + if (!internal_name.is_null()) + (void) mount_style(n, internal_name); + } + } + skip_line(); +} + +static void font_lookup_error(font_lookup_info& finfo, + const char *msg) +{ + if (finfo.requested_name) + error("cannot load font '%1' %2", finfo.requested_name, msg); + else + error("cannot load font at position %1 %2", + finfo.requested_position, msg); +} + +// Read the next token and look it up as a font name or position number. +// Return lookup success. Store, in the supplied struct argument, the +// requested name or position, and the position actually resolved; -1 +// means not found (see `font_lookup_info` constructor). +static bool has_font(font_lookup_info *finfo) +{ + int n; + tok.skip(); + if (tok.usable_as_delimiter()) { + symbol s = get_name(true /* required */); + finfo->requested_name = (char *)s.contents(); + if (!s.is_null()) { + n = symbol_fontno(s); + if (n < 0) { + n = next_available_font_position(); + if (mount_font(n, s)) + finfo->position = n; + } + finfo->position = curenv->get_family()->make_definite(n); + } + } + else if (get_integer(&n)) { + finfo->requested_position = n; + if (!(n < 0 || n >= font_table_size || font_table[n] == 0)) + finfo->position = curenv->get_family()->make_definite(n); + } + return (finfo->position != -1); +} + +static int underline_fontno = 2; + +void underline_font() +{ + font_lookup_info finfo; + if (!has_font(&finfo)) + font_lookup_error(finfo, "to make it the underline font"); + else + underline_fontno = finfo.position; + skip_line(); +} + +int get_underline_fontno() +{ + return underline_fontno; +} + +void define_font_special_character() +{ + font_lookup_info finfo; + if (!has_font(&finfo)) { + font_lookup_error(finfo, "to define font-specific fallback glyph"); + // Normally we skip the remainder of the line unconditionally at the + // end of a request-implementing function, but do_define_character() + // will eat the rest of it for us. + skip_line(); + } + else { + symbol f = font_table[finfo.position]->get_name(); + do_define_character(CHAR_FONT_SPECIAL, f.contents()); + } +} + +void remove_font_special_character() +{ + font_lookup_info finfo; + if (!has_font(&finfo)) + font_lookup_error(finfo, "to remove font-specific fallback glyph"); + else { + symbol f = font_table[finfo.position]->get_name(); + while (!tok.is_newline() && !tok.is_eof()) { + if (!tok.is_space() && !tok.is_tab()) { + charinfo *s = tok.get_char(true /* required */); + string gl(f.contents()); + gl += ' '; + gl += s->nm.contents(); + gl += '\0'; + charinfo *ci = get_charinfo(symbol(gl.contents())); + if (!ci) + break; + macro *m = ci->set_macro(0); + if (m) + delete m; + } + tok.next(); + } + } + skip_line(); +} + +static void read_special_fonts(special_font_list **sp) +{ + special_font_list *s = *sp; + *sp = 0; + while (s != 0) { + special_font_list *tem = s; + s = s->next; + delete tem; + } + special_font_list **p = sp; + while (has_arg()) { + font_lookup_info finfo; + if (!has_font(&finfo)) + font_lookup_error(finfo, "to mark it as special"); + else { + special_font_list *tem = new special_font_list; + tem->n = finfo.position; + tem->next = 0; + *p = tem; + p = &(tem->next); + } + } +} + +void font_special_request() +{ + font_lookup_info finfo; + if (!has_font(&finfo)) + font_lookup_error(finfo, "to mark other fonts as special" + " contingently upon it"); // a mouthful :-/ + else + read_special_fonts(&font_table[finfo.position]->sf); + skip_line(); +} + +void special_request() +{ + read_special_fonts(&global_special_fonts); + skip_line(); +} + +void font_zoom_request() +{ + font_lookup_info finfo; + if (!has_font(&finfo)) + font_lookup_error(finfo, "to set a zoom factor for it"); + else { + int n = finfo.position; + if (font_table[n]->is_style()) + warning(WARN_FONT, "can't set zoom factor for a style"); + else { + int zoom; + if (has_arg() && get_integer(&zoom)) { + if (zoom < 0) + warning(WARN_FONT, "can't use negative zoom factor"); + else + font_table[n]->set_zoom(zoom); + } + else + font_table[n]->set_zoom(0); + } + } + skip_line(); +} + +int next_available_font_position() +{ + int i; + for (i = 1; i < font_table_size && font_table[i] != 0; i++) + ; + return i; +} + +int symbol_fontno(symbol s) +{ + s = get_font_translation(s); + for (int i = 0; i < font_table_size; i++) + if (font_table[i] != 0 && font_table[i]->is_named(s)) + return i; + return -1; +} + +int is_good_fontno(int n) +{ + return n >= 0 && n < font_table_size && font_table[n] != 0; +} + +int get_bold_fontno(int n) +{ + if (n >= 0 && n < font_table_size && font_table[n] != 0) { + hunits offset; + if (font_table[n]->get_bold(&offset)) + return offset.to_units() + 1; + else + return 0; + } + else + return 0; +} + +hunits env_digit_width(environment *env) +{ + node *n = make_glyph_node(charset_table['0'], env); + if (n) { + hunits x = n->width(); + delete n; + return x; + } + else + return H0; +} + +hunits env_space_width(environment *env) +{ + int fn = env_definite_font(env); + font_size fs = env->get_font_size(); + if (fn < 0 || fn >= font_table_size || font_table[fn] == 0) + return scale(fs.to_units()/3, env->get_space_size(), 12); + else + return font_table[fn]->get_space_width(fs, env->get_space_size()); +} + +hunits env_sentence_space_width(environment *env) +{ + int fn = env_definite_font(env); + font_size fs = env->get_font_size(); + if (fn < 0 || fn >= font_table_size || font_table[fn] == 0) + return scale(fs.to_units()/3, env->get_sentence_space_size(), 12); + else + return font_table[fn]->get_space_width(fs, env->get_sentence_space_size()); +} + +hunits env_half_narrow_space_width(environment *env) +{ + int fn = env_definite_font(env); + font_size fs = env->get_font_size(); + if (fn < 0 || fn >= font_table_size || font_table[fn] == 0) + return 0; + else + return font_table[fn]->get_half_narrow_space_width(fs); +} + +hunits env_narrow_space_width(environment *env) +{ + int fn = env_definite_font(env); + font_size fs = env->get_font_size(); + if (fn < 0 || fn >= font_table_size || font_table[fn] == 0) + return 0; + else + return font_table[fn]->get_narrow_space_width(fs); +} + +void bold_font() +{ + font_lookup_info finfo; + if (!has_font(&finfo)) + font_lookup_error(finfo, "for emboldening"); + else { + int n = finfo.position; + if (has_arg()) { + // This is a bit non-orthogonal, but faithful to CSTR #54. We can + // only conditionally embolden a font specified by name, not + // position, so ".bd S B 4" works but ".bd 5 3 4" does not. The + // latter bolds the font at position 5 unconditionally, and + // ignores the third argument. + if (tok.usable_as_delimiter()) { + font_lookup_info finfo2; + if (!has_font(&finfo2)) + font_lookup_error(finfo2, "for conditional emboldening"); + else { + int f = finfo2.position; + units offset; + if (has_arg() && get_number(&offset, 'u') && offset >= 1) + font_table[f]->set_conditional_bold(n, hunits(offset - 1)); + else + font_table[f]->conditional_unbold(n); + } + } + else { + font_lookup_info finfo2; + if (!has_font(&finfo2)) + font_lookup_error(finfo2, "for conditional emboldening"); + units offset; + if (get_number(&offset, 'u') && offset >= 1) + font_table[n]->set_bold(hunits(offset - 1)); + else + font_table[n]->unbold(); + } + } + else + font_table[n]->unbold(); + } + skip_line(); +} + +track_kerning_function::track_kerning_function() : non_zero(0) +{ +} + +track_kerning_function::track_kerning_function(int min_s, hunits min_a, + int max_s, hunits max_a) +: non_zero(1), min_size(min_s), min_amount(min_a), max_size(max_s), + max_amount(max_a) +{ +} + +int track_kerning_function::operator==(const track_kerning_function &tk) +{ + if (non_zero) + return (tk.non_zero + && min_size == tk.min_size + && min_amount == tk.min_amount + && max_size == tk.max_size + && max_amount == tk.max_amount); + else + return !tk.non_zero; +} + +int track_kerning_function::operator!=(const track_kerning_function &tk) +{ + if (non_zero) + return (!tk.non_zero + || min_size != tk.min_size + || min_amount != tk.min_amount + || max_size != tk.max_size + || max_amount != tk.max_amount); + else + return tk.non_zero; +} + +hunits track_kerning_function::compute(int size) +{ + if (non_zero) { + if (max_size <= min_size) + return min_amount; + else if (size <= min_size) + return min_amount; + else if (size >= max_size) + return max_amount; + else + return (scale(max_amount, size - min_size, max_size - min_size) + + scale(min_amount, max_size - size, max_size - min_size)); + } + else + return H0; +} + +void track_kern() +{ + font_lookup_info finfo; + if (!has_font(&finfo)) + font_lookup_error(finfo, "for track kerning"); + else { + int n = finfo.position, min_s, max_s; + hunits min_a, max_a; + if (has_arg() + && get_number(&min_s, 'z') + && get_hunits(&min_a, 'p') + && get_number(&max_s, 'z') + && get_hunits(&max_a, 'p')) { + track_kerning_function tk(min_s, min_a, max_s, max_a); + font_table[n]->set_track_kern(tk); + } + else { + track_kerning_function tk; + font_table[n]->set_track_kern(tk); + } + } + skip_line(); +} + +void constant_space() +{ + font_lookup_info finfo; + if (!has_font(&finfo)) + font_lookup_error(finfo, "for constant spacing"); + else { + int n = finfo.position, x, y; + if (!has_arg() || !get_integer(&x)) + font_table[n]->set_constant_space(CONSTANT_SPACE_NONE); + else { + if (!has_arg() || !get_number(&y, 'z')) + font_table[n]->set_constant_space(CONSTANT_SPACE_RELATIVE, x); + else + font_table[n]->set_constant_space(CONSTANT_SPACE_ABSOLUTE, + scale(y*x, + units_per_inch, + 36*72*sizescale)); + } + } + skip_line(); +} + +void ligature() +{ + int lig; + if (has_arg() && get_integer(&lig) && lig >= 0 && lig <= 2) + global_ligature_mode = lig; + else + global_ligature_mode = 1; + skip_line(); +} + +void kern_request() +{ + int k; + if (has_arg() && get_integer(&k)) + global_kern_mode = k != 0; + else + global_kern_mode = 1; + skip_line(); +} + +void set_soft_hyphen_char() +{ + soft_hyphen_char = get_optional_char(); + if (!soft_hyphen_char) + soft_hyphen_char = get_charinfo(HYPHEN_SYMBOL); + skip_line(); +} + +void init_output() +{ + if (suppress_output_flag) + the_output = new suppress_output_file; + else if (ascii_output_flag) + the_output = new ascii_output_file; + else + the_output = new troff_output_file; +} + +class next_available_font_position_reg : public reg { +public: + const char *get_string(); +}; + +const char *next_available_font_position_reg::get_string() +{ + return i_to_a(next_available_font_position()); +} + +class printing_reg : public reg { +public: + const char *get_string(); +}; + +const char *printing_reg::get_string() +{ + if (the_output) + return the_output->is_printing() ? "1" : "0"; + else + return "0"; +} + +void init_node_requests() +{ + init_request("bd", bold_font); + init_request("cs", constant_space); + init_request("fp", font_position); + init_request("fschar", define_font_special_character); + init_request("fspecial", font_special_request); + init_request("fzoom", font_zoom_request); + init_request("ftr", font_translate); + init_request("kern", kern_request); + init_request("lg", ligature); + init_request("rfschar", remove_font_special_character); + init_request("shc", set_soft_hyphen_char); + init_request("special", special_request); + init_request("sty", style); + init_request("tkf", track_kern); + init_request("uf", underline_font); + register_dictionary.define(".fp", new next_available_font_position_reg); + register_dictionary.define(".kern", + new readonly_register(&global_kern_mode)); + register_dictionary.define(".lg", + new readonly_register(&global_ligature_mode)); + register_dictionary.define(".P", new printing_reg); + soft_hyphen_char = get_charinfo(HYPHEN_SYMBOL); +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h new file mode 100644 index 0000000..de82753 --- /dev/null +++ b/src/roff/troff/node.h @@ -0,0 +1,670 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +struct hyphen_list { + unsigned char hyphen; + unsigned char breakable; + unsigned char hyphenation_code; + hyphen_list *next; + hyphen_list(unsigned char code, hyphen_list *p = 0); +}; + +void hyphenate(hyphen_list *, unsigned); + +enum hyphenation_type { HYPHEN_MIDDLE, HYPHEN_BOUNDARY, HYPHEN_INHIBIT }; + +class ascii_output_file; + +struct breakpoint; +struct vertical_size; +class charinfo; + +class macro; + +class troff_output_file; +class tfont; +class environment; + +class glyph_node; +class diverted_space_node; +class token_node; + +struct node { + node *next; + node *last; + statem *state; + statem *push_state; + int div_nest_level; + int is_special; + node(); + node(node *); + node(node *, statem *, int); + node *add_char(charinfo *, environment *, hunits *, int *, node ** = 0); + + virtual ~node(); + virtual node *copy() = 0; + virtual int set_unformat_flag(); + virtual int force_tprint() = 0; + virtual int is_tag() = 0; + virtual int get_break_code(); + virtual hunits width(); + virtual hunits subscript_correction(); + virtual hunits italic_correction(); + virtual hunits left_italic_correction(); + virtual hunits skew(); + virtual int nspaces(); + virtual int merge_space(hunits, hunits, hunits); + virtual vunits vertical_width(); + virtual node *last_char_node(); + virtual void vertical_extent(vunits *, vunits *); + virtual int character_type(); + virtual void set_vertical_size(vertical_size *); + virtual int ends_sentence(); + virtual node *merge_self(node *); + virtual node *add_discretionary_hyphen(); + virtual node *add_self(node *, hyphen_list **); + virtual hyphen_list *get_hyphen_list(hyphen_list *, int *); + virtual void ascii_print(ascii_output_file *); + virtual void asciify(macro *); + virtual int discardable(); + virtual void spread_space(int *, hunits *); + virtual void freeze_space(); + virtual void is_escape_colon(); + virtual breakpoint *get_breakpoints(hunits, int, breakpoint * = 0, int = 0); + virtual int nbreaks(); + virtual void split(int, node **, node **); + virtual hyphenation_type get_hyphenation_type(); + virtual int reread(int *); + virtual token_node *get_token_node(); + virtual int overlaps_vertically(); + virtual int overlaps_horizontally(); + virtual units size(); + virtual int interpret(macro *); + + virtual node *merge_glyph_node(glyph_node *); + virtual tfont *get_tfont(); + virtual color *get_glyph_color(); + virtual color *get_fill_color(); + virtual void tprint(troff_output_file *); + virtual void zero_width_tprint(troff_output_file *); + + node *add_italic_correction(hunits *); + + virtual int same(node *) = 0; + virtual const char *type() = 0; + virtual void debug_node(); + virtual void debug_node_list(); +}; + +inline node::node() +: next(0), last(0), state(0), push_state(0), div_nest_level(0), is_special(0) +{ +} + +inline node::node(node *n) +: next(n), last(0), state(0), push_state(0), div_nest_level(0), is_special(0) +{ +} + +inline node::node(node *n, statem *s, int divlevel) +: next(n), last(0), push_state(0), div_nest_level(divlevel), is_special(0) +{ + if (s) + state = new statem(s); + else + state = 0; +} + +inline node::~node() +{ + if (state != 0) + delete state; + if (push_state != 0) + delete push_state; +} + +// 0 means it doesn't, 1 means it does, 2 means it's transparent + +int node_list_ends_sentence(node *); + +struct breakpoint { + breakpoint *next; + hunits width; + int nspaces; + node *nd; + int index; + char hyphenated; +}; + +class line_start_node : public node { +public: + line_start_node() {} + node *copy() { return new line_start_node; } + int same(node *); + int force_tprint(); + int is_tag(); + const char *type(); + void asciify(macro *); +}; + +class space_node : public node { +private: +protected: + hunits n; + char set; + char was_escape_colon; + color *col; /* for grotty */ + space_node(hunits, int, int, color *, statem *, int, node * = 0); +public: + space_node(hunits, color *, node * = 0); + node *copy(); + int nspaces(); + hunits width(); + int discardable(); + int merge_space(hunits, hunits, hunits); + void freeze_space(); + void is_escape_colon(); + void spread_space(int *, hunits *); + void tprint(troff_output_file *); + breakpoint *get_breakpoints(hunits, int, breakpoint * = 0, int = 0); + int nbreaks(); + void split(int, node **, node **); + void ascii_print(ascii_output_file *); + int same(node *); + void asciify(macro *); + const char *type(); + int force_tprint(); + int is_tag(); + hyphenation_type get_hyphenation_type(); +}; + +struct width_list { + hunits width; + hunits sentence_width; + width_list *next; + width_list(hunits, hunits); + width_list(width_list *); +}; + +class word_space_node : public space_node { +protected: + width_list *orig_width; + unsigned char unformat; + word_space_node(hunits, int, color *, width_list *, int, statem *, int, + node * = 0); +public: + word_space_node(hunits, color *, width_list *, node * = 0); + ~word_space_node(); + node *copy(); + int reread(int *); + int set_unformat_flag(); + void tprint(troff_output_file *); + int same(node *); + void asciify(macro *); + const char *type(); + int merge_space(hunits, hunits, hunits); + int force_tprint(); + int is_tag(); +}; + +class unbreakable_space_node : public word_space_node { + unbreakable_space_node(hunits, int, color *, statem *, int, node * = 0); +public: + unbreakable_space_node(hunits, color *, node * = 0); + node *copy(); + int reread(int *); + void tprint(troff_output_file *); + int same(node *); + void asciify(macro *); + const char *type(); + int force_tprint(); + int is_tag(); + breakpoint *get_breakpoints(hunits, int, breakpoint * = 0, int = 0); + int nbreaks(); + void split(int, node **, node **); + int merge_space(hunits, hunits, hunits); + node *add_self(node *, hyphen_list **); + hyphen_list *get_hyphen_list(hyphen_list *, int *); + hyphenation_type get_hyphenation_type(); +}; + +class diverted_space_node : public node { +public: + vunits n; + diverted_space_node(vunits, node * = 0); + diverted_space_node(vunits, statem *, int, node * = 0); + node *copy(); + int reread(int *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class diverted_copy_file_node : public node { + symbol filename; +public: + vunits n; + diverted_copy_file_node(symbol, node * = 0); + diverted_copy_file_node(symbol, statem *, int, node * = 0); + node *copy(); + int reread(int *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class extra_size_node : public node { + vunits n; +public: + extra_size_node(vunits); + extra_size_node(vunits, statem *, int); + void set_vertical_size(vertical_size *); + node *copy(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class vertical_size_node : public node { + vunits n; +public: + vertical_size_node(vunits, statem *, int); + vertical_size_node(vunits); + void set_vertical_size(vertical_size *); + void asciify(macro *); + node *copy(); + int set_unformat_flag(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class hmotion_node : public node { +protected: + hunits n; + unsigned char was_tab; + unsigned char unformat; + color *col; /* for grotty */ +public: + hmotion_node(hunits i, color *c, node *nxt = 0) + : node(nxt), n(i), was_tab(0), unformat(0), col(c) {} + hmotion_node(hunits i, color *c, statem *s, int divlevel, node *nxt = 0) + : node(nxt, s, divlevel), n(i), was_tab(0), unformat(0), col(c) {} + hmotion_node(hunits i, int flag1, int flag2, color *c, statem *s, + int divlevel, node *nxt = 0) + : node(nxt, s, divlevel), n(i), was_tab(flag1), unformat(flag2), + col(c) {} + hmotion_node(hunits i, int flag1, int flag2, color *c, node *nxt = 0) + : node(nxt), n(i), was_tab(flag1), unformat(flag2), col(c) {} + node *copy(); + int reread(int *); + int set_unformat_flag(); + void asciify(macro *); + void tprint(troff_output_file *); + hunits width(); + void ascii_print(ascii_output_file *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + node *add_self(node *, hyphen_list **); + hyphen_list *get_hyphen_list(hyphen_list *, int *); + hyphenation_type get_hyphenation_type(); +}; + +class space_char_hmotion_node : public hmotion_node { +public: + space_char_hmotion_node(hunits, color *, node * = 0); + space_char_hmotion_node(hunits, color *, statem *, int, node * = 0); + node *copy(); + void ascii_print(ascii_output_file *); + void asciify(macro *); + void tprint(troff_output_file *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + node *add_self(node *, hyphen_list **); + hyphen_list *get_hyphen_list(hyphen_list *, int *); + hyphenation_type get_hyphenation_type(); +}; + +class vmotion_node : public node { + vunits n; + color *col; /* for grotty */ +public: + vmotion_node(vunits, color *); + vmotion_node(vunits, color *, statem *, int); + void tprint(troff_output_file *); + node *copy(); + vunits vertical_width(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class hline_node : public node { + hunits x; + node *n; +public: + hline_node(hunits, node *, node * = 0); + hline_node(hunits, node *, statem *, int, node * = 0); + ~hline_node(); + node *copy(); + hunits width(); + void tprint(troff_output_file *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class vline_node : public node { + vunits x; + node *n; +public: + vline_node(vunits, node *, node * = 0); + vline_node(vunits, node *, statem *, int, node * = 0); + ~vline_node(); + node *copy(); + void tprint(troff_output_file *); + hunits width(); + vunits vertical_width(); + void vertical_extent(vunits *, vunits *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class dummy_node : public node { +public: + dummy_node(node *nd = 0) : node(nd) {} + node *copy(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + hyphenation_type get_hyphenation_type(); +}; + +class transparent_dummy_node : public node { +public: + transparent_dummy_node(node *nd = 0) : node(nd) {} + node *copy(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + int ends_sentence(); + hyphenation_type get_hyphenation_type(); +}; + +class zero_width_node : public node { + node *n; +public: + zero_width_node(node *); + zero_width_node(node *, statem *, int); + ~zero_width_node(); + node *copy(); + void tprint(troff_output_file *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + void append(node *); + int character_type(); + void vertical_extent(vunits *, vunits *); +}; + +class left_italic_corrected_node : public node { + node *n; + hunits x; +public: + left_italic_corrected_node(node * = 0); + left_italic_corrected_node(statem *, int, node * = 0); + ~left_italic_corrected_node(); + void tprint(troff_output_file *); + void ascii_print(ascii_output_file *); + void asciify(macro *); + node *copy(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + hunits width(); + node *last_char_node(); + void vertical_extent(vunits *, vunits *); + int ends_sentence(); + int overlaps_horizontally(); + int overlaps_vertically(); + hyphenation_type get_hyphenation_type(); + tfont *get_tfont(); + int character_type(); + hunits skew(); + hunits italic_correction(); + hunits subscript_correction(); + hyphen_list *get_hyphen_list(hyphen_list *, int *); + node *add_self(node *, hyphen_list **); + node *merge_glyph_node(glyph_node *); +}; + +class overstrike_node : public node { + node *list; + hunits max_width; +public: + overstrike_node(); + overstrike_node(statem *, int); + ~overstrike_node(); + node *copy(); + void tprint(troff_output_file *); + void overstrike(node *); // add another node to be overstruck + hunits width(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + node *add_self(node *, hyphen_list **); + hyphen_list *get_hyphen_list(hyphen_list *, int *); + hyphenation_type get_hyphenation_type(); +}; + +class bracket_node : public node { + node *list; + hunits max_width; +public: + bracket_node(); + bracket_node(statem *, int); + ~bracket_node(); + node *copy(); + void tprint(troff_output_file *); + void bracket(node *); // add another node to be overstruck + hunits width(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class special_node : public node { + macro mac; + tfont *tf; + color *gcol; + color *fcol; + int no_init_string; + void tprint_start(troff_output_file *); + void tprint_char(troff_output_file *, unsigned char); + void tprint_end(troff_output_file *); +public: + special_node(const macro &, int = 0); + special_node(const macro &, tfont *, color *, color *, statem *, int, + int = 0); + node *copy(); + void tprint(troff_output_file *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + int ends_sentence(); + tfont *get_tfont(); +}; + +class suppress_node : public node { + int is_on; + int emit_limits; // must we issue the extent of the area written out? + symbol filename; + char position; + int image_id; +public: + suppress_node(int, int); + suppress_node(symbol, char, int); + suppress_node(int, int, symbol, char, int, statem *, int); + suppress_node(int, int, symbol, char, int); + node *copy(); + void tprint(troff_output_file *); + hunits width(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +private: + void put(troff_output_file *, const char *); +}; + +class tag_node : public node { +public: + string tag_string; + int delayed; + tag_node(); + tag_node(string, int); + tag_node(string, statem *, int, int); + node *copy(); + void tprint(troff_output_file *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + int ends_sentence(); +}; + +struct hvpair { + hunits h; + vunits v; + hvpair(); +}; + +class draw_node : public node { + int npoints; + font_size sz; + color *gcol; + color *fcol; + char code; + hvpair *point; +public: + draw_node(char, hvpair *, int, font_size, color *, color *); + draw_node(char, hvpair *, int, font_size, color *, color *, statem *, int); + ~draw_node(); + hunits width(); + vunits vertical_width(); + node *copy(); + void tprint(troff_output_file *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class charinfo; +node *make_node(charinfo *, environment *); +bool character_exists(charinfo *, environment *); + +int same_node_list(node *, node *); +node *reverse_node_list(node *); +void delete_node_list(node *); +node *copy_node_list(node *); + +int get_bold_fontno(int); + +inline hyphen_list::hyphen_list(unsigned char code, hyphen_list *p) +: hyphen(0), breakable(0), hyphenation_code(code), next(p) +{ +} + +extern void read_desc(); +extern bool mount_font(int, symbol, symbol = NULL_SYMBOL); +extern int check_font(symbol, symbol); +extern int check_style(symbol); +extern bool mount_style(int, symbol); +extern int is_good_fontno(int); +extern int symbol_fontno(symbol); +extern int next_available_font_position(); +extern void init_size_table(int *); +extern int get_underline_fontno(); + +class output_file { + char make_g_plus_plus_shut_up; +public: + output_file(); + bool is_dying; + virtual ~output_file(); + virtual void trailer(vunits); + virtual void flush() = 0; + virtual void transparent_char(unsigned char) = 0; + virtual void print_line(hunits x, vunits y, node *n, + vunits before, vunits after, hunits width) = 0; + virtual void begin_page(int pageno, vunits page_length) = 0; + virtual void copy_file(hunits x, vunits y, const char *filename) = 0; + virtual int is_printing() = 0; + virtual void put_filename(const char *, int); + virtual void on(); + virtual void off(); +#ifdef COLUMN + virtual void vjustify(vunits, symbol); +#endif /* COLUMN */ + mtsm state; +}; + +#ifndef POPEN_MISSING +extern char *pipe_command; +#endif + +extern output_file *the_output; +extern void init_output(); +int in_output_page_list(int); + +class font_family { + int *map; + int map_size; +public: + const symbol nm; + font_family(symbol); + ~font_family(); + int make_definite(int); + static void invalidate_fontno(int); +}; + +font_family *lookup_family(symbol); +symbol get_font_name(int, environment *); +symbol get_style_name(int); +extern search_path include_search_path; diff --git a/src/roff/troff/number.cpp b/src/roff/troff/number.cpp new file mode 100644 index 0000000..348b557 --- /dev/null +++ b/src/roff/troff/number.cpp @@ -0,0 +1,712 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + + +#include "troff.h" +#include "hvunits.h" +#include "stringclass.h" +#include "mtsm.h" +#include "env.h" +#include "token.h" +#include "div.h" + +const vunits V0; // zero in vertical units +const hunits H0; // zero in horizontal units + +int hresolution = 1; +int vresolution = 1; +int units_per_inch; +int sizescale; + +static bool is_valid_expression(units *v, int scaling_unit, + bool is_parenthesized, + bool is_mandatory = false); +static bool is_valid_expression_start(); + +int get_vunits(vunits *res, unsigned char si) +{ + if (!is_valid_expression_start()) + return 0; + units x; + if (is_valid_expression(&x, si, false /* is_parenthesized */)) { + *res = vunits(x); + return 1; + } + else + return 0; +} + +int get_hunits(hunits *res, unsigned char si) +{ + if (!is_valid_expression_start()) + return 0; + units x; + if (is_valid_expression(&x, si, false /* is_parenthesized */)) { + *res = hunits(x); + return 1; + } + else + return 0; +} + +// for \B + +int get_number_rigidly(units *res, unsigned char si) +{ + if (!is_valid_expression_start()) + return 0; + units x; + if (is_valid_expression(&x, si, false /* is_parenthesized */, + true /* is_mandatory */)) { + *res = x; + return 1; + } + else + return 0; +} + +int get_number(units *res, unsigned char si) +{ + if (!is_valid_expression_start()) + return 0; + units x; + if (is_valid_expression(&x, si, false /* is_parenthesized */)) { + *res = x; + return 1; + } + else + return 0; +} + +int get_integer(int *res) +{ + if (!is_valid_expression_start()) + return 0; + units x; + if (is_valid_expression(&x, 0, false /* is_parenthesized */)) { + *res = x; + return 1; + } + else + return 0; +} + +enum incr_number_result { BAD, ABSOLUTE, INCREMENT, DECREMENT }; + +static incr_number_result get_incr_number(units *res, unsigned char); + +int get_vunits(vunits *res, unsigned char si, vunits prev_value) +{ + units v; + switch (get_incr_number(&v, si)) { + case BAD: + return 0; + case ABSOLUTE: + *res = v; + break; + case INCREMENT: + *res = prev_value + v; + break; + case DECREMENT: + *res = prev_value - v; + break; + default: + assert(0 == "unhandled switch case returned by get_incr_number()"); + } + return 1; +} + +int get_hunits(hunits *res, unsigned char si, hunits prev_value) +{ + units v; + switch (get_incr_number(&v, si)) { + case BAD: + return 0; + case ABSOLUTE: + *res = v; + break; + case INCREMENT: + *res = prev_value + v; + break; + case DECREMENT: + *res = prev_value - v; + break; + default: + assert(0 == "unhandled switch case returned by get_incr_number()"); + } + return 1; +} + +int get_number(units *res, unsigned char si, units prev_value) +{ + units v; + switch (get_incr_number(&v, si)) { + case BAD: + return 0; + case ABSOLUTE: + *res = v; + break; + case INCREMENT: + *res = prev_value + v; + break; + case DECREMENT: + *res = prev_value - v; + break; + default: + assert(0 == "unhandled switch case returned by get_incr_number()"); + } + return 1; +} + +int get_integer(int *res, int prev_value) +{ + units v; + switch (get_incr_number(&v, 0)) { + case BAD: + return 0; + case ABSOLUTE: + *res = v; + break; + case INCREMENT: + *res = prev_value + int(v); + break; + case DECREMENT: + *res = prev_value - int(v); + break; + default: + assert(0 == "unhandled switch case returned by get_incr_number()"); + } + return 1; +} + + +static incr_number_result get_incr_number(units *res, unsigned char si) +{ + if (!is_valid_expression_start()) + return BAD; + incr_number_result result = ABSOLUTE; + if (tok.ch() == '+') { + tok.next(); + result = INCREMENT; + } + else if (tok.ch() == '-') { + tok.next(); + result = DECREMENT; + } + if (is_valid_expression(res, si, false /* is_parenthesized */)) + return result; + else + return BAD; +} + +static bool is_valid_expression_start() +{ + while (tok.is_space()) + tok.next(); + if (tok.is_newline()) { + warning(WARN_MISSING, "numeric expression missing"); + return false; + } + if (tok.is_tab()) { + warning(WARN_TAB, "expected numeric expression, got %1", + tok.description()); + return false; + } + if (tok.is_right_brace()) { + warning(WARN_RIGHT_BRACE, "expected numeric expression, got right" + "brace escape sequence"); + return false; + } + return true; +} + +enum { OP_LEQ = 'L', OP_GEQ = 'G', OP_MAX = 'X', OP_MIN = 'N' }; + +#define SCALING_UNITS "icfPmnpuvMsz" + +static bool is_valid_term(units *v, int scaling_unit, + bool is_parenthesized, bool is_mandatory); + +static bool is_valid_expression(units *v, int scaling_unit, + bool is_parenthesized, + bool is_mandatory) +{ + int result = is_valid_term(v, scaling_unit, is_parenthesized, + is_mandatory); + while (result) { + if (is_parenthesized) + tok.skip(); + int op = tok.ch(); + switch (op) { + case '+': + case '-': + case '/': + case '*': + case '%': + case ':': + case '&': + tok.next(); + break; + case '>': + tok.next(); + if (tok.ch() == '=') { + tok.next(); + op = OP_GEQ; + } + else if (tok.ch() == '?') { + tok.next(); + op = OP_MAX; + } + break; + case '<': + tok.next(); + if (tok.ch() == '=') { + tok.next(); + op = OP_LEQ; + } + else if (tok.ch() == '?') { + tok.next(); + op = OP_MIN; + } + break; + case '=': + tok.next(); + if (tok.ch() == '=') + tok.next(); + break; + default: + return result; + } + units v2; + if (!is_valid_term(&v2, scaling_unit, is_parenthesized, + is_mandatory)) + return false; + int overflow = 0; + switch (op) { + case '<': + *v = *v < v2; + break; + case '>': + *v = *v > v2; + break; + case OP_LEQ: + *v = *v <= v2; + break; + case OP_GEQ: + *v = *v >= v2; + break; + case OP_MIN: + if (*v > v2) + *v = v2; + break; + case OP_MAX: + if (*v < v2) + *v = v2; + break; + case '=': + *v = *v == v2; + break; + case '&': + *v = *v > 0 && v2 > 0; + break; + case ':': + *v = *v > 0 || v2 > 0; + break; + case '+': + if (v2 < 0) { + if (*v < INT_MIN - v2) + overflow = 1; + } + else if (v2 > 0) { + if (*v > INT_MAX - v2) + overflow = 1; + } + if (overflow) { + error("addition overflow"); + return false; + } + *v += v2; + break; + case '-': + if (v2 < 0) { + if (*v > INT_MAX + v2) + overflow = 1; + } + else if (v2 > 0) { + if (*v < INT_MIN + v2) + overflow = 1; + } + if (overflow) { + error("subtraction overflow"); + return false; + } + *v -= v2; + break; + case '*': + if (v2 < 0) { + if (*v > 0) { + if ((unsigned)*v > -(unsigned)INT_MIN / -(unsigned)v2) + overflow = 1; + } + else if (-(unsigned)*v > INT_MAX / -(unsigned)v2) + overflow = 1; + } + else if (v2 > 0) { + if (*v > 0) { + if (*v > INT_MAX / v2) + overflow = 1; + } + else if (-(unsigned)*v > -(unsigned)INT_MIN / v2) + overflow = 1; + } + if (overflow) { + error("multiplication overflow"); + return false; + } + *v *= v2; + break; + case '/': + if (v2 == 0) { + error("division by zero"); + return false; + } + *v /= v2; + break; + case '%': + if (v2 == 0) { + error("modulus by zero"); + return false; + } + *v %= v2; + break; + default: + assert(0 == "unhandled switch case while processing operator"); + } + } + return result; +} + +static bool is_valid_term(units *v, int scaling_unit, + bool is_parenthesized, bool is_mandatory) +{ + int negative = 0; + for (;;) + if (is_parenthesized && tok.is_space()) + tok.next(); + else if (tok.ch() == '+') + tok.next(); + else if (tok.ch() == '-') { + tok.next(); + negative = !negative; + } + else + break; + unsigned char c = tok.ch(); + switch (c) { + case '|': + // | is not restricted to the outermost level + // tbl uses this + tok.next(); + if (!is_valid_term(v, scaling_unit, is_parenthesized, is_mandatory)) + return false; + int tem; + tem = (scaling_unit == 'v' + ? curdiv->get_vertical_position().to_units() + : curenv->get_input_line_position().to_units()); + if (tem >= 0) { + if (*v < INT_MIN + tem) { + error("numeric overflow"); + return false; + } + } + else { + if (*v > INT_MAX + tem) { + error("numeric overflow"); + return false; + } + } + *v -= tem; + if (negative) { + if (*v == INT_MIN) { + error("numeric overflow"); + return false; + } + *v = -*v; + } + return true; + case '(': + tok.next(); + c = tok.ch(); + if (c == ')') { + if (is_mandatory) + return false; + warning(WARN_SYNTAX, "empty parentheses"); + tok.next(); + *v = 0; + return true; + } + else if (c != 0 && strchr(SCALING_UNITS, c) != 0) { + tok.next(); + if (tok.ch() == ';') { + tok.next(); + scaling_unit = c; + } + else { + error("expected ';' after scaling unit, got %1", + tok.description()); + return false; + } + } + else if (c == ';') { + scaling_unit = 0; + tok.next(); + } + if (!is_valid_expression(v, scaling_unit, + true /* is_parenthesized */, is_mandatory)) + return false; + tok.skip(); + if (tok.ch() != ')') { + if (is_mandatory) + return false; + warning(WARN_SYNTAX, "expected ')', got %1", tok.description()); + } + else + tok.next(); + if (negative) { + if (*v == INT_MIN) { + error("numeric overflow"); + return false; + } + *v = -*v; + } + return true; + case '.': + *v = 0; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + *v = 0; + do { + if (*v > INT_MAX/10) { + error("numeric overflow"); + return false; + } + *v *= 10; + if (*v > INT_MAX - (int(c) - '0')) { + error("numeric overflow"); + return false; + } + *v += c - '0'; + tok.next(); + c = tok.ch(); + } while (csdigit(c)); + break; + case '/': + case '*': + case '%': + case ':': + case '&': + case '>': + case '<': + case '=': + warning(WARN_SYNTAX, "empty left operand to '%1' operator", c); + *v = 0; + return is_mandatory ? false : true; + default: + warning(WARN_NUMBER, "expected numeric expression, got %1", + tok.description()); + return false; + } + int divisor = 1; + if (tok.ch() == '.') { + tok.next(); + for (;;) { + c = tok.ch(); + if (!csdigit(c)) + break; + // we may multiply the divisor by 254 later on + if (divisor <= INT_MAX/2540 && *v <= (INT_MAX - 9)/10) { + *v *= 10; + *v += c - '0'; + divisor *= 10; + } + tok.next(); + } + } + int si = scaling_unit; + int do_next = 0; + if ((c = tok.ch()) != 0 && strchr(SCALING_UNITS, c) != 0) { + switch (scaling_unit) { + case 0: + warning(WARN_SCALE, "scaling unit invalid in context"); + break; + case 'z': + if (c != 'u' && c != 'z') { + warning(WARN_SCALE, "'%1' scaling unit invalid in context;" + " convert to 'z' or 'u'", c); + break; + } + si = c; + break; + case 'u': + si = c; + break; + default: + if (c == 'z') { + warning(WARN_SCALE, "'z' scaling unit invalid in context"); + break; + } + si = c; + break; + } + // Don't do tok.next() here because the next token might be \s, + // which would affect the interpretation of m. + do_next = 1; + } + switch (si) { + case 'i': + *v = scale(*v, units_per_inch, divisor); + break; + case 'c': + *v = scale(*v, units_per_inch*100, divisor*254); + break; + case 0: + case 'u': + if (divisor != 1) + *v /= divisor; + break; + case 'f': + *v = scale(*v, 65536, divisor); + break; + case 'p': + *v = scale(*v, units_per_inch, divisor*72); + break; + case 'P': + *v = scale(*v, units_per_inch, divisor*6); + break; + case 'm': + { + // Convert to hunits so that with -Tascii 'm' behaves as in nroff. + hunits em = curenv->get_size(); + *v = scale(*v, em.is_zero() ? hresolution : em.to_units(), + divisor); + } + break; + case 'M': + { + hunits em = curenv->get_size(); + *v = scale(*v, em.is_zero() ? hresolution : em.to_units(), + (divisor * 100)); + } + break; + case 'n': + { + // Convert to hunits so that with -Tascii 'n' behaves as in nroff. + hunits en = curenv->get_size() / 2; + *v = scale(*v, en.is_zero() ? hresolution : en.to_units(), + divisor); + } + break; + case 'v': + *v = scale(*v, curenv->get_vertical_spacing().to_units(), divisor); + break; + case 's': + while (divisor > INT_MAX/(sizescale*72)) { + divisor /= 10; + *v /= 10; + } + *v = scale(*v, units_per_inch, divisor*sizescale*72); + break; + case 'z': + *v = scale(*v, sizescale, divisor); + break; + default: + assert(0 == "unhandled switch case when processing scaling unit"); + } + if (do_next) + tok.next(); + if (negative) { + if (*v == INT_MIN) { + error("numeric overflow"); + return false; + } + *v = -*v; + } + return true; +} + +units scale(units n, units x, units y) +{ + assert(x >= 0 && y > 0); + if (x == 0) + return 0; + if (n >= 0) { + if (n <= INT_MAX/x) + return (n*x)/y; + } + else { + if (-(unsigned)n <= -(unsigned)INT_MIN/x) + return (n*x)/y; + } + double res = n*double(x)/double(y); + if (res > INT_MAX) { + error("numeric overflow"); + return INT_MAX; + } + else if (res < INT_MIN) { + error("numeric overflow"); + return INT_MIN; + } + return int(res); +} + +vunits::vunits(units x) +{ + // Don't depend on rounding direction when dividing negative integers. + if (vresolution == 1) + n = x; + else + n = (x < 0 + ? -((-x + (vresolution / 2) - 1) / vresolution) + : (x + (vresolution / 2) - 1) / vresolution); +} + +hunits::hunits(units x) +{ + // Don't depend on rounding direction when dividing negative integers. + if (hresolution == 1) + n = x; + else + n = (x < 0 + ? -((-x + (hresolution / 2) - 1) / hresolution) + : (x + (hresolution / 2) - 1) / hresolution); +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/roff/troff/reg.cpp b/src/roff/troff/reg.cpp new file mode 100644 index 0000000..6b7689d --- /dev/null +++ b/src/roff/troff/reg.cpp @@ -0,0 +1,479 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "troff.h" +#include "dictionary.h" +#include "token.h" +#include "request.h" +#include "reg.h" + +object_dictionary register_dictionary(101); + +bool reg::get_value(units * /*d*/) +{ + return false; +} + +void reg::increment() +{ + error("can't increment read-only register"); +} + +void reg::decrement() +{ + error("can't decrement read-only register"); +} + +void reg::set_increment(units /*n*/) +{ + error("can't automatically increment read-only register"); +} + +void reg::alter_format(char /*f*/, int /*w*/) +{ + error("can't assign format of read-only register"); +} + +const char *reg::get_format() +{ + return "0"; +} + +void reg::set_value(units /*n*/) +{ + error("can't write read-only register"); +} + +general_reg::general_reg() : format('1'), width(0), inc(0) +{ +} + +static char uppercase_array[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', +}; + +static char lowercase_array[] = { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', +}; + +static const char *number_value_to_ascii(int value, char format, int width) +{ + static char buf[128]; // must be at least 21 + switch(format) { + case '1': + if (width <= 0) + return i_to_a(value); + else if (width > int(sizeof(buf) - 2)) + sprintf(buf, "%.*d", int(sizeof(buf) - 2), int(value)); + else + sprintf(buf, "%.*d", width, int(value)); + break; + case 'i': + case 'I': + { + char *p = buf; + // troff uses z and w to represent 10000 and 5000 in Roman + // numerals; I can find no historical basis for this usage + const char *s = format == 'i' ? "zwmdclxvi" : "ZWMDCLXVI"; + int n = int(value); + if (n >= 40000 || n <= -40000) { + error("magnitude of '%1' too big for i or I format", n); + return i_to_a(n); + } + if (n == 0) { + *p++ = '0'; + *p = 0; + break; + } + if (n < 0) { + *p++ = '-'; + n = -n; + } + while (n >= 10000) { + *p++ = s[0]; + n -= 10000; + } + for (int i = 1000; i > 0; i /= 10, s += 2) { + int m = n/i; + n -= m*i; + switch (m) { + case 3: + *p++ = s[2]; + /* falls through */ + case 2: + *p++ = s[2]; + /* falls through */ + case 1: + *p++ = s[2]; + break; + case 4: + *p++ = s[2]; + *p++ = s[1]; + break; + case 8: + *p++ = s[1]; + *p++ = s[2]; + *p++ = s[2]; + *p++ = s[2]; + break; + case 7: + *p++ = s[1]; + *p++ = s[2]; + *p++ = s[2]; + break; + case 6: + *p++ = s[1]; + *p++ = s[2]; + break; + case 5: + *p++ = s[1]; + break; + case 9: + *p++ = s[2]; + *p++ = s[0]; + } + } + *p = 0; + break; + } + case 'a': + case 'A': + { + int n = value; + char *p = buf; + if (n == 0) { + *p++ = '0'; + *p = 0; + } + else { + if (n < 0) { + n = -n; + *p++ = '-'; + } + // this is a bit tricky + while (n > 0) { + int d = n % 26; + if (d == 0) + d = 26; + n -= d; + n /= 26; + *p++ = format == 'a' ? lowercase_array[d - 1] : + uppercase_array[d - 1]; + } + *p-- = 0; + char *q = buf[0] == '-' ? buf + 1 : buf; + while (q < p) { + char temp = *q; + *q = *p; + *p = temp; + --p; + ++q; + } + } + break; + } + default: + assert(0); + break; + } + return buf; +} + +const char *general_reg::get_string() +{ + units n; + if (!get_value(&n)) + return ""; + return number_value_to_ascii(n, format, width); +} + + +void general_reg::increment() +{ + int n; + if (get_value(&n)) + set_value(n + inc); +} + +void general_reg::decrement() +{ + int n; + if (get_value(&n)) + set_value(n - inc); +} + +void general_reg::set_increment(units n) +{ + inc = n; +} + +void general_reg::alter_format(char f, int w) +{ + format = f; + width = w; +} + +static const char *number_format_to_ascii(char format, int width) +{ + static char buf[24]; + if (format == '1') { + if (width > 0) { + int n = width; + if (n > int(sizeof(buf)) - 1) + n = int(sizeof(buf)) - 1; + sprintf(buf, "%.*d", n, 0); + return buf; + } + else + return "0"; + } + else { + buf[0] = format; + buf[1] = '\0'; + return buf; + } +} + +const char *general_reg::get_format() +{ + return number_format_to_ascii(format, width); +} + +class number_reg : public general_reg { + units value; +public: + number_reg(); + bool get_value(units *); + void set_value(units); +}; + +number_reg::number_reg() : value(0) +{ +} + +bool number_reg::get_value(units *res) +{ + *res = value; + return true; +} + +void number_reg::set_value(units n) +{ + value = n; +} + +variable_reg::variable_reg(units *p) : ptr(p) +{ +} + +void variable_reg::set_value(units n) +{ + *ptr = n; +} + +bool variable_reg::get_value(units *res) +{ + *res = *ptr; + return true; +} + +void define_number_reg() +{ + symbol nm = get_name(true /* required */); + if (nm.is_null()) { + skip_line(); + return; + } + reg *r = (reg *)register_dictionary.lookup(nm); + units v; + units prev_value; + if (!r || !r->get_value(&prev_value)) + prev_value = 0; + if (get_number(&v, 'u', prev_value)) { + if (r == 0) { + r = new number_reg; + register_dictionary.define(nm, r); + } + r->set_value(v); + if (tok.is_space() && has_arg() && get_number(&v, 'u')) + r->set_increment(v); + } + skip_line(); +} + +#if 0 +void inline_define_reg() +{ + token start; + start.next(); + if (!start.delimiter(true /* report error */)) + return; + tok.next(); + symbol nm = get_name(true /* required */); + if (nm.is_null()) + return; + reg *r = (reg *)register_dictionary.lookup(nm); + if (r == 0) { + r = new number_reg; + register_dictionary.define(nm, r); + } + units v; + units prev_value; + if (!r->get_value(&prev_value)) + prev_value = 0; + if (get_number(&v, 'u', prev_value)) { + r->set_value(v); + if (start != tok) { + if (get_number(&v, 'u')) { + r->set_increment(v); + if (start != tok) + warning(WARN_DELIM, "closing delimiter does not match"); + } + } + } +} +#endif + +void set_number_reg(symbol nm, units n) +{ + reg *r = (reg *)register_dictionary.lookup(nm); + if (r == 0) { + r = new number_reg; + register_dictionary.define(nm, r); + } + r->set_value(n); +} + +reg *lookup_number_reg(symbol nm) +{ + reg *r = (reg *)register_dictionary.lookup(nm); + if (r == 0) { + warning(WARN_REG, "register '%1' not defined", nm.contents()); + r = new number_reg; + register_dictionary.define(nm, r); + } + return r; +} + +void alter_format() +{ + symbol nm = get_name(true /* required */); + if (nm.is_null()) { + skip_line(); + return; + } + reg *r = (reg *)register_dictionary.lookup(nm); + if (r == 0) { + r = new number_reg; + register_dictionary.define(nm, r); + } + tok.skip(); + char c = tok.ch(); + if (csdigit(c)) { + int n = 0; + do { + ++n; + tok.next(); + } while (csdigit(tok.ch())); + r->alter_format('1', n); + } + else if (c == 'i' || c == 'I' || c == 'a' || c == 'A') + r->alter_format(c); + else if (tok.is_newline() || tok.is_eof()) + warning(WARN_MISSING, "missing register format"); + else + if (!cscntrl(c)) + error("invalid register format '%1'", c); + else + error("invalid register format (got %1)", tok.description()); + skip_line(); +} + +void remove_reg() +{ + for (;;) { + symbol s = get_name(); + if (s.is_null()) + break; + register_dictionary.remove(s); + } + skip_line(); +} + +void alias_reg() +{ + symbol s1 = get_name(true /* required */); + if (!s1.is_null()) { + symbol s2 = get_name(true /* required */); + if (!s2.is_null()) { + if (!register_dictionary.alias(s1, s2)) + warning(WARN_REG, "register '%1' not defined", s2.contents()); + } + } + skip_line(); +} + +void rename_reg() +{ + symbol s1 = get_name(true /* required */); + if (!s1.is_null()) { + symbol s2 = get_name(true /* required */); + if (!s2.is_null()) + register_dictionary.rename(s1, s2); + } + skip_line(); +} + +void print_number_regs() +{ + object_dictionary_iterator iter(register_dictionary); + reg *r; + symbol s; + while (iter.get(&s, (object **)&r)) { + assert(!s.is_null()); + errprint("%1\t", s.contents()); + const char *p = r->get_string(); + if (p) + errprint(p); + errprint("\n"); + } + fflush(stderr); + skip_line(); +} + +void init_reg_requests() +{ + init_request("rr", remove_reg); + init_request("nr", define_number_reg); + init_request("af", alter_format); + init_request("aln", alias_reg); + init_request("rnn", rename_reg); + init_request("pnr", print_number_regs); +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/roff/troff/reg.h b/src/roff/troff/reg.h new file mode 100644 index 0000000..132bcf1 --- /dev/null +++ b/src/roff/troff/reg.h @@ -0,0 +1,74 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + + +class reg : public object { +public: + virtual const char *get_string() = 0; + virtual bool get_value(units *); + virtual void increment(); + virtual void decrement(); + virtual void set_increment(units); + virtual void alter_format(char f, int w = 0); + virtual const char *get_format(); + virtual void set_value(units); +}; + +class readonly_register : public reg { + int *p; +public: + readonly_register(int *); + const char *get_string(); +}; + +class general_reg : public reg { + char format; + int width; + int inc; +public: + general_reg(); + const char *get_string(); + void increment(); + void decrement(); + void alter_format(char f, int w = 0); + void set_increment(units); + const char *get_format(); + void add_value(units); + + void set_value(units) = 0; + bool get_value(units *) = 0; +}; + +class variable_reg : public general_reg { + units *ptr; +public: + variable_reg(int *); + void set_value(units); + bool get_value(units *); +}; + +extern object_dictionary register_dictionary; +extern void set_number_reg(symbol nm, units n); +extern void check_output_limits(int x, int y); +extern void reset_output_registers(); + +reg *lookup_number_reg(symbol); +#if 0 +void inline_define_reg(); +#endif diff --git a/src/roff/troff/request.h b/src/roff/troff/request.h new file mode 100644 index 0000000..0991e49 --- /dev/null +++ b/src/roff/troff/request.h @@ -0,0 +1,97 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +typedef void (*REQUEST_FUNCP)(); + +class macro; + +class request_or_macro : public object { +public: + request_or_macro(); + virtual void invoke(symbol, bool) = 0; + virtual macro *to_macro(); +}; + +class request : public request_or_macro { + REQUEST_FUNCP p; +public: + void invoke(symbol, bool); + request(REQUEST_FUNCP); +}; + +void delete_request_or_macro(request_or_macro *); + +extern object_dictionary request_dictionary; + +class macro_header; +struct node; + +class macro : public request_or_macro { + const char *filename; // where was it defined? + int lineno; + int len; + int empty_macro; + int is_a_diversion; + int is_a_string; // if it contains no newline +public: + macro_header *p; + macro(); + ~macro(); + macro(const macro &); + macro(int); + macro &operator=(const macro &); + void append(unsigned char); + void append(node *); + void append_unsigned(unsigned int); + void append_int(int); + void append_str(const char *); + void set(unsigned char, int); + unsigned char get(int); + int length(); + void invoke(symbol, bool); + macro *to_macro(); + void print_size(); + int empty(); + int is_diversion(); + int is_string(); + void clear_string_flag(); + friend class string_iterator; + friend void chop_macro(); + friend void substring_request(); + friend int operator==(const macro &, const macro &); +}; + +extern void init_input_requests(); +extern void init_markup_requests(); +extern void init_div_requests(); +extern void init_node_requests(); +extern void init_reg_requests(); +extern void init_env_requests(); +extern void init_hyphen_requests(); +extern void init_request(const char *, REQUEST_FUNCP); + +class charinfo; +class environment; + +node *charinfo_to_node_list(charinfo *, const environment *); + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/roff/troff/token.h b/src/roff/troff/token.h new file mode 100644 index 0000000..bd76055 --- /dev/null +++ b/src/roff/troff/token.h @@ -0,0 +1,249 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + + +class charinfo; +struct node; +class vunits; + +class token { + symbol nm; + node *nd; + unsigned char c; + int val; + units dim; + enum token_type { + TOKEN_BACKSPACE, + TOKEN_BEGIN_TRAP, + TOKEN_CHAR, // a normal printing character + TOKEN_DUMMY, // \& + TOKEN_EMPTY, // this is the initial value + TOKEN_END_TRAP, + TOKEN_ESCAPE, // \e + TOKEN_HYPHEN_INDICATOR, + TOKEN_INTERRUPT, // \c + TOKEN_ITALIC_CORRECTION, // \/ + TOKEN_LEADER, // ^A + TOKEN_LEFT_BRACE, + TOKEN_MARK_INPUT, // \k -- 'nm' is the name of the register + TOKEN_NEWLINE, // newline + TOKEN_NODE, + TOKEN_NUMBERED_CHAR, + TOKEN_PAGE_EJECTOR, + TOKEN_REQUEST, + TOKEN_RIGHT_BRACE, + TOKEN_SPACE, // ' ' -- ordinary space + TOKEN_SPECIAL, // a special character -- \' \` \- \(xx \[xxx] + TOKEN_SPREAD, // \p -- break and spread output line + TOKEN_STRETCHABLE_SPACE, // \~ + TOKEN_UNSTRETCHABLE_SPACE, // '\ ' + TOKEN_HORIZONTAL_SPACE, // \|, \^, \0, \h + TOKEN_TAB, // tab + TOKEN_TRANSPARENT, // \! + TOKEN_TRANSPARENT_DUMMY, // \) + TOKEN_ZERO_WIDTH_BREAK, // \: + TOKEN_EOF // end of file + } type; +public: + token(); + ~token(); + token(const token &); + void operator=(const token &); + void next(); + void process(); + void skip(); + int nspaces(); // 1 if space, 0 otherwise + bool is_eof(); + bool is_space(); + bool is_stretchable_space(); + bool is_unstretchable_space(); + bool is_horizontal_space(); + bool is_white_space(); + bool is_special(); + bool is_newline(); + bool is_tab(); + bool is_leader(); + bool is_backspace(); + bool usable_as_delimiter(bool = false); + bool is_dummy(); + bool is_transparent_dummy(); + bool is_transparent(); + bool is_left_brace(); + bool is_right_brace(); + bool is_page_ejector(); + bool is_hyphen_indicator(); + bool is_zero_width_break(); + int operator==(const token &); // need this for delimiters, and for conditions + int operator!=(const token &); // ditto + unsigned char ch(); + charinfo *get_char(bool = false); + int add_to_zero_width_node_list(node **); + void make_space(); + void make_newline(); + const char *description(); + + friend void process_input_stack(); + friend node *do_overstrike(); +}; + +extern token tok; // the current token + +extern symbol get_name(bool = false); +extern symbol get_long_name(bool = false); +extern charinfo *get_optional_char(); +extern char *read_string(); +extern void check_missing_character(); +extern void skip_line(); +extern void handle_initial_title(); + +enum char_mode { + CHAR_NORMAL, + CHAR_FALLBACK, + CHAR_FONT_SPECIAL, + CHAR_SPECIAL +}; + +extern void do_define_character(char_mode, const char * = 0); + +class hunits; +extern void read_title_parts(node **part, hunits *part_width); + +extern int get_number_rigidly(units *result, unsigned char si); + +extern int get_number(units *result, unsigned char si); +extern int get_integer(int *result); + +extern int get_number(units *result, unsigned char si, units prev_value); +extern int get_integer(int *result, int prev_value); + +void interpolate_number_reg(symbol, int); + +const char *asciify(int c); + +inline bool token::is_newline() +{ + return type == TOKEN_NEWLINE; +} + +inline bool token::is_space() +{ + return type == TOKEN_SPACE; +} + +inline bool token::is_stretchable_space() +{ + return type == TOKEN_STRETCHABLE_SPACE; +} + +inline bool token::is_unstretchable_space() +{ + return type == TOKEN_UNSTRETCHABLE_SPACE; +} + +inline bool token::is_horizontal_space() +{ + return type == TOKEN_HORIZONTAL_SPACE; +} + +inline bool token::is_special() +{ + return type == TOKEN_SPECIAL; +} + +inline int token::nspaces() +{ + return (int)(type == TOKEN_SPACE); +} + +inline bool token::is_white_space() +{ + return type == TOKEN_SPACE || type == TOKEN_TAB; +} + +inline bool token::is_transparent() +{ + return type == TOKEN_TRANSPARENT; +} + +inline bool token::is_page_ejector() +{ + return type == TOKEN_PAGE_EJECTOR; +} + +inline unsigned char token::ch() +{ + return type == TOKEN_CHAR ? c : 0; +} + +inline bool token::is_eof() +{ + return type == TOKEN_EOF; +} + +inline bool token::is_dummy() +{ + return type == TOKEN_DUMMY; +} + +inline bool token::is_transparent_dummy() +{ + return type == TOKEN_TRANSPARENT_DUMMY; +} + +inline bool token::is_left_brace() +{ + return type == TOKEN_LEFT_BRACE; +} + +inline bool token::is_right_brace() +{ + return type == TOKEN_RIGHT_BRACE; +} + +inline bool token::is_tab() +{ + return type == TOKEN_TAB; +} + +inline bool token::is_leader() +{ + return type == TOKEN_LEADER; +} + +inline bool token::is_backspace() +{ + return type == TOKEN_BACKSPACE; +} + +inline bool token::is_hyphen_indicator() +{ + return type == TOKEN_HYPHEN_INDICATOR; +} + +inline bool token::is_zero_width_break() +{ + return type == TOKEN_ZERO_WIDTH_BREAK; +} + +bool has_arg(); + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/roff/troff/troff.1.man b/src/roff/troff/troff.1.man new file mode 100644 index 0000000..d83c4a5 --- /dev/null +++ b/src/roff/troff/troff.1.man @@ -0,0 +1,1047 @@ +'\" t +.TH @g@troff @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +@g@troff \- GNU +.I roff +typesetter and document formatter +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1989-2021 Free Software Foundation, Inc. +.\" +.\" This file is part of groff, the GNU roff type-setting system. +.\" +.\" Permission is granted to copy, distribute and/or modify this +.\" document under the terms of the GNU Free Documentation License, +.\" Version 1.3 or any later version published by the Free Software +.\" Foundation; with no Invariant Sections, with no Front-Cover Texts, +.\" and with no Back-Cover Texts. +.\" +.\" A copy of the Free Documentation License is included as a file +.\" called FDL in the main directory of the groff source package. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_troff_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY @g@troff +.RB [ \-abcCEiRUz ] +.RB [ \-d\~\c +.IR ctext ] +.RB [ \-d\~\c +.IB string =\c +.IR text ] +.RB [ \-f\~\c +.IR font-family ] +.RB [ \-F\~\c +.IR font-directory ] +.RB [ \-I\~\c +.IR inclusion-directory ] +.RB [ \-m\~\c +.IR macro-package ] +.RB [ \-M\~\c +.IR macro-directory ] +.RB [ \-n\~\c +.IR page-number ] +.RB [ \-o\~\c +.IR page-list ] +.RB [ \-r\~\c +.IR cnumeric-expression ] +.RB [ \-r\~\c +.IB register =\c +.IR numeric-expression ] +.RB [ \-T\~\c +.IR output-device ] +.RB [ \-w\~\c +.IR warning-category ] +.RB [ \-W\~\c +.IR warning-category ] +.RI [ file\~ .\|.\|.] +.YS +. +. +.SY @g@troff +.B \-\-help +.YS +. +. +.SY @g@troff +.B \-v +. +.SY @g@troff +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +GNU +.I troff \" GNU +transforms +.MR groff @MAN7EXT@ +language input into the device-independent output format described in +.MR groff_out @MAN5EXT@ ; +.I @g@troff +is thus the heart of the GNU +.I roff +document formatting system. +. +If no +.I file +operands are given on the command line, +or if +.I file +is +.RB \[lq] \- \[rq], +the standard input stream is read. +. +. +.P +GNU +.I troff \" GNU +is functionally compatible with the AT&T +.I troff \" AT&T +typesetter and features numerous extensions. +. +Many people prefer to use the +.MR groff @MAN1EXT@ +command, +a front end which also runs preprocessors and output drivers in the +appropriate order and with appropriate options. +. +. +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-h +and +.B \-\-help +display a usage message, +while +.B \-v +and +.B \-\-version +show version information; +all exit afterward. +. +. +.TP +.B \-a +Generate a plain text approximation of the typeset output. +. +The read-only register +.B .A +is set to\~1. +. +This option produces a sort of abstract preview of the formatted output. +. +. +.RS +.IP \[bu] 2n +Page breaks are marked by a phrase in angle brackets; +for example, +\[lq]\[rq]. +. +. +.IP \[bu] +Lines are broken where they would be in the formatted output. +. +. +.IP \[bu] +A horizontal motion of any size is represented as one space. +. +Adjacent horizontal motions are not combined. +. +Inter-sentence space nodes +(those arising from the second argument to the +.B .ss +request) +are not represented. +. +. +.IP \[bu] +Vertical motions are not represented. +. +. +.IP \[bu] +Special characters are rendered in angle brackets; +for example, +the default soft hyphen character appears as +\[lq]\[rq]. +.RE +. +. +.IP +The above description should not be considered a specification; +the details of +.B \-a +output are subject to change. +. +. +.TP +.B \-b +Write a backtrace reporting the state of +.IR @g@troff 's +input parser to the standard error stream with each diagnostic message. +. +The line numbers given in the backtrace might not always be correct, +because +.IR @g@troff 's +idea of line numbers can be confused by requests that append to +.\" strings or (??? strings never contain newlines) +macros. +. +. +.TP +.B \-c +Start with color output disabled. +. +. +.TP +.B \-C +Enable AT&T +.I troff \" AT&T +compatibility mode; +implies +.BR \-c . +. +See +.MR groff_diff @MAN7EXT@ . +. +. +.TP +.BI \-d\~ ctext +.TQ +.BI \-d\~ string = text +Define +.I roff +.RI string\~ c +or +.I string +as +.I text. +. +.IR c \~must +be one character; +.I string +can be of arbitrary length. +. +Such string assignments happen before any macro file is loaded, +including the startup file. +. +Due to +.MR getopt_long 3 +limitations, +.IR c\~ cannot +be, +and +.I string +cannot contain, +an equals sign, +even though that is a valid character in a +.I roff +identifier. +. +. +.TP +.B \-E +Inhibit +.I @g@troff +error messages; +implies +.BR \-Ww . +. +This option does +.I not +suppress messages sent to the standard error stream by documents or +macro packages using +.B tm +or related requests. +. +. +.TP +.BI \-f\~ fam +Use +.I fam +as the default font family. +. +. +.TP +.BI \-F\~ dir +Search in directory +.I dir +for the selected output device's directory of device and font +description files. +. +See the description of +.I GROFF_FONT_PATH +in section \[lq]Environment\[rq] below for the default search locations +and ordering. +. +. +.TP +.B \-i +Read the standard input stream after all named input files have been +processed. +. +. +.TP +.BI \-I\~ dir +Search the directory +.I dir +for files +(those named on the command line; +in +.BR psbb , +.BR so , +and +.B soquiet +requests; +and in +.RB \[lq] "\[rs]X\[aq]ps: import\[aq]" \[rq], +.RB \[lq] "\[rs]X\[aq]ps: file\[aq]" \[rq], +and +.RB \[lq] "\[rs]X\[aq]pdf: pdfpic\[aq]" \[rq] +device control escape sequences). +. +.B \-I +may be specified more than once; +each +.I dir +is searched in the given order. +. +To search the current working directory before others, +add +.RB \[lq] "\-I .\&" \[rq] +at the desired place; +it is otherwise searched last. +. +.B \-I +works similarly to, +and is named for, +the \[lq]include\[rq] +option of Unix C compilers. +. +. +.TP +.BI \-m\~ name +Process the file +.RI name .tmac +prior to any input files. +. +If not found, +.IR tmac. name +is attempted. +. +.I name +(in both arrangements) +is presumed to be a macro file; +see the description of +.I GROFF_TMAC_PATH +in section \[lq]Environment\[rq] below for the default search locations +and ordering. +. +. +.TP +.BI \-M\~ dir +Search directory +.I dir +for macro files. +. +See the description of +.I GROFF_TMAC_PATH +in section \[lq]Environment\[rq] below for the default search locations +and ordering. +. +. +.TP +.BI \-n\~ num +Begin numbering pages at +.I num. +. +The default +.RB is\~ 1 . +. +. +.TP +.BI \-o\~ list +Output only pages in +.I list, +which is a comma-separated list of inclusive page ranges; +.I n +means page +.I n, +.IB m \- n +means every page +.RI between\~ m +.RI and\~ n , +.BI \- n +means every page up +.RI to\~ n , +and +.IB n \- +means every page from +.IR n \~on. +. +.I @g@troff +stops processing and exits after formatting the last page enumerated in +.I list. +. +. +.TP +.BI \-r\~ cnumeric-expression +.TQ +.BI \-r\~ register = numeric-expression +Define +.I roff +.RI register\~ c +or +.I register +as +.I numeric-expression. +. +.IR c \~must +be a one-character name; +.I register +can be of arbitrary length. +. +Such register assignments happen before any macro file is loaded, +including the startup file. +. +Due to +.MR getopt_long 3 +limitations, +.IR c\~ cannot +be, +and +.I register +cannot contain, +an equals sign, +even though that is a valid character in a +.I roff +identifier. +. +. +.TP +.B \-R +Don't load +.I troffrc +and +.IR troffrc\-end . +. +. +.TP +.BI \-T\~ dev +Prepare output for device +.I dev. +. +The default is +.BR @DEVICE@ ; +see +.MR groff @MAN1EXT@ . +. +. +.TP +.B \-U +Operate in +.I unsafe mode, +enabling the +.BR open , +.BR opena , +.BR pi , +.BR pso , +and +.B sy +requests, +which are disabled by default because they allow an untrusted input +document to write to arbitrary file names and run arbitrary commands. +. +This option also adds the current directory to the macro package search +path; +see the +.B \-m +and +.B \-M +options above. +. +. +.TP +.BI \-w\~ name +.TQ +.BI \-W\~ name +Enable +.RB ( \-w ) +or inhibit +.RB ( \-W ) +warnings in category +.I name. +. +See section \[lq]Warnings\[rq] below. +. +. +.TP +.B \-z +Suppress formatted output. +. +. +.\" ==================================================================== +.SH Warnings +.\" ==================================================================== +. +.\" BEGIN Keep parallel with groff.texi node "Warnings". +.\" Caveat: the Texinfo manual sorts them by number, not name. +Warning diagnostics emitted by +.I @g@troff +are divided into named, +numbered categories. +. +The name associated with each warning category is used by the +.B \-w +and +.B \-W +options. +. +Each category is also assigned a power of two; +the sum of enabled category codes is used by the +.B warn +request and the +.B .warn +register. +. +Warnings of each category are produced under the following +circumstances. +. +. +.P +.TS +tab(@), center, box; +c c c | c c c +r rI lB | r rI lB. +Bit@Code@Category@Bit@Code@Category +_ +0@1@char@10@1024@reg +1@2@number@11@2048@tab +2@4@break@12@4096@right\-brace +3@8@delim@13@8192@missing +4@16@el@14@16384@input +5@32@scale@15@32768@escape +6@64@range@16@65536@space +7@128@syntax@17@131072@font +8@256@di@18@262144@ig +9@512@mac@19@524288@color +@@@20@1048576@file +.TE +. +. +.P +.nr x \w'\fBright\-brace'+1n+\w'00000'u +.ta \nxuR +. +. +.TP \nxu+3n +.BR break "\t4" +A filled output line could not be broken such that its length was less +than the output line length +.BR \[rs]n[.l] . +. +This category is enabled by default. +. +. +.TP +.BR char "\t1" +No mounted font defines a glyph for the requested character. +. +This category is enabled by default. +. +. +.TP +.BR color "\t524288" +An undefined color name was selected, +an attempt was made to define a color using an unrecognized color space, +an invalid component in a color definition was encountered, +or an attempt was made to redefine a default color. +. +. +.TP +.BR delim "\t8" +The closing delimiter in an escape sequence was missing or mismatched. +. +. +.TP +.BR di "\t256" +A +.BR di , +.BR da , +.BR box , +or +.B boxa +request was invoked without an argument when there was no current +diversion. +. +. +.TP +.BR el "\t16" +The +.B el +request was encountered with no prior corresponding +.B ie +request. +. +. +.TP +.BR escape "\t32768" +An unsupported escape sequence was encountered. +. +. +.TP +.BR file "\t1048576" +An attempt was made to load a file that does not exist. +. +This category is enabled by default. +. +. +.TP +.BR font "\t131072" +A non-existent font was selected, +or the selection was ignored because a font selection escape sequence +was used after the output line continuation escape sequence on an input +line. +. +This category is enabled by default. +. +. +.TP +.BR ig "\t262144" +An invalid escape sequence occurred in input ignored using the +.B ig +request. +. +This warning category diagnoses a condition that is an error when it +occurs in non-ignored input. +. +. +.TP +.BR input "\t16384" +An invalid character occurred on the input stream. +. +. +.TP +.BR mac "\t512" +An undefined string, +macro, +or diversion was used. +. +When such an object is dereferenced, +an empty one of that name is automatically created. +. +So, +unless it is later deleted, +at most one warning is given for each. +. +. +.IP +This warning is also emitted upon an attempt to move an unplanted trap +macro. +. +In such cases, +the unplanted macro is +.I not +dereferenced, +so it is not created if it does not exist. +. +. +.TP +.BR missing "\t8192" +A request was invoked with a mandatory argument absent. +. +. +.TP +.BR number "\t2" +An invalid numeric expression was encountered. +. +This category is enabled by default. +. +. +.TP +.BR range "\t64" +A numeric expression was out of range for its context. +. +. +.TP +.BR reg "\t1024" +An undefined register was used. +. +When an undefined register is dereferenced, +it is automatically defined with a value of\~0. +. +So, +unless it is later deleted, +at most one warning is given for each. +. +. +.TP +.BR right\-brace "\t4096" +A right brace escape sequence +.B \[rs]} +was encountered where a number was expected. +. +. +.TP +.BR scale "\t32" +A scaling unit inappropriate to its context was used in a numeric +expression. +. +. +.TP +.BR space "\t65536" +A space was missing between a request or macro and its argument. +. +This warning is produced when an undefined name longer than two +characters is encountered and the first two characters of the name +constitute a defined name. +. +No request is invoked, +no macro called, +and an empty macro is not defined. +. +This category is enabled by default. +. +It never occurs in compatibility mode. +. +. +.TP +.BR syntax "\t128" +A self-contradictory hyphenation mode was requested; +an empty or incomplete numeric expression was encountered; +an operand to a numeric operator was missing; +an attempt was made to define a recursive, +empty, +or nonsensical character class; +or a +.I groff +extension conditional expression operator was used while in +compatibility mode. +. +. +.TP +.BR tab "\t2048" +A tab character was encountered where a number was expected, +or appeared in an unquoted macro argument. +. +. +.P +Two warning names group other warning categories for convenience. +. +. +.TP +.B all +All warning categories except +.BR di , +.BR mac , +and +.BR reg . +. +This shorthand is intended to produce all warnings that are useful with +macro packages and documents written for AT&T +.I troff \" AT&T +and its descendants, +which have less fastidious diagnostics than GNU +.IR troff . \" GNU +. +. +.TP +.B w +All warning categories. +. +Authors of documents and macro packages targeting +.I groff +are encouraged to use this setting. +.\" END Keep parallel with groff.texi node "Warnings". +. +. +.\" ==================================================================== +.SH Environment +.\" ==================================================================== +. +.I GROFF_FONT_PATH +and +.I GROFF_TMAC_PATH +each accept a search path of directories; +that is, +a list of directory names separated by the system's path component +separator character. +. +On Unix systems, +this character is a colon (:); +on Windows systems, +it is a semicolon (;). +. +. +.TP +.I GROFF_FONT_PATH +A list of directories in which to seek the selected output device's +directory of device and font description files. +. +.I @g@troff +will scan directories given as arguments to any specified +.B \-F +options before these, +then in a site-specific directory +.RI ( @LOCALFONTDIR@ ), +a standard location +.RI ( @FONTDIR@ ), +and a compatibility directory +.RI ( @LEGACYFONTDIR@ ) +after them. +. +. +.TP +.I GROFF_TMAC_PATH +A list of directories in which to search for macro files. +. +.I @g@troff +will scan directories given as arguments to any specified +.B \-M +options before these, +then the current directory +(only if in unsafe mode), +the user's home directory, +.if !'@COMPATIBILITY_WRAPPERS@'no' \{\ +a platform-specific directory +.RI ( @SYSTEMMACRODIR@ ), +.\} +a site-specific directory +.RI ( @LOCALMACRODIR@ ), +and a standard location +.RI ( @MACRODIR@ ) +after them. +. +. +.TP +.I GROFF_TYPESETTER +Set the default output device. +. +If empty or not set, +.B @DEVICE@ +is used. +. +The +.B \-T +option overrides +.IR \%GROFF_TYPESETTER . +. +. +.TP +.I SOURCE_DATE_EPOCH +A timestamp +(expressed as seconds since the Unix epoch) +to use as the output creation timestamp in place of the current time. +. +The time is converted to human-readable form using +.MR localtime 3 +when the formatter starts up and stored in registers usable by documents +and macro packages. +. +. +.TP +.I TZ +The timezone to use when converting the current time +(or value of +.IR SOURCE_DATE_EPOCH ) +to human-readable form; +see +.MR tzset 3 . +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.I @MACRODIR@/\:\%troffrc +is an initialization macro file loaded before any macro packages +specified with +.B \-m +options. +. +. +.TP +.I @MACRODIR@/\:\%troffrc\-end +is an initialization macro file loaded after all macro packages +specified with +.B \-m +options. +. +. +.TP +.IR @MACRODIR@/\: name \:.tmac +are macro files distributed with +.IR groff . +. +. +.TP +.IR @FONTDIR@/\:\%dev name /\:DESC +describes the output device +.IR name . +. +. +.TP +.IR @FONTDIR@/\:\%dev name / F +describes the font +.I F +of device +.I name. +. +. +.P +.I troffrc +and +.I troffrc\-end +are sought neither in the current nor the home directory by default for +security reasons, +even if the +.B \-U +option is specified. +. +Use the +.B \-M +command-line option or the +.I GROFF_TMAC_PATH +environment variable to add these directories to the search path if +necessary. +. +. +.\" ==================================================================== +.SH Authors +.\" ==================================================================== +. +The GNU version of +.I troff \" generic +was originally written by James Clark; +he also wrote the original version of this document, +which was updated by +.MT wl@\:gnu\:.org +Werner Lemberg +.ME , +.MT groff\-bernd\:.warken\-72@\:web\:.de +Bernd Warken +.ME , +and +.MT g.branden\:.robinson@\:gmail\:.com +G.\& Branden Robinson +.ME . +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.IR "Groff: The GNU Implementation of troff" , +by Trent A.\& Fisher and Werner Lemberg, +is the primary +.I groff +manual. +. +You can browse it interactively with \[lq]info groff\[rq]. +. +. +.TP +.MR groff @MAN1EXT@ +offers an overview of the GNU +.I roff +system +and describes its front end executable. +. +. +.TP +.MR groff @MAN7EXT@ +details the +.I groff +language, +including a short but complete reference of all predefined requests, +registers, +and escape sequences. +. +. +.TP +.MR groff_char @MAN7EXT@ +explains the syntax of +.I groff +special character escape sequences, +and lists all special characters predefined by the language. +. +. +.TP +.MR groff_diff @MAN7EXT@ +enumerates the differences between +AT&T device-independent +.I troff \" AT&T +and +.IR groff . +. +. +.TP +.MR groff_font @MAN5EXT@ +covers the format of +.I groff +device and font description files. +. +. +.TP +.MR groff_out @MAN5EXT@ +describes the format of +.IR @g@troff 's +output. +. +. +.TP +.MR groff_tmac @MAN5EXT@ +includes information about macro files that ship with +.IR groff . +. +. +.TP +.MR roff @MAN7EXT@ +supplies background on +.I roff +systems in general, +including pointers to further related documentation. +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_troff_1_man_C] +.do rr *groff_troff_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/roff/troff/troff.am b/src/roff/troff/troff.am new file mode 100644 index 0000000..42ac7fa --- /dev/null +++ b/src/roff/troff/troff.am @@ -0,0 +1,66 @@ +# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# +# This file 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 . + +prefixexecbin_PROGRAMS += troff +PREFIXMAN1 += src/roff/troff/troff.1 +EXTRA_DIST += \ + src/roff/troff/column.cpp \ + src/roff/troff/troff.1.man \ + src/roff/troff/TODO +troff_LDADD = libgroff.a lib/libgnu.a $(LIBM) +troff_SOURCES = \ + src/roff/troff/dictionary.cpp \ + src/roff/troff/div.cpp \ + src/roff/troff/env.cpp \ + src/roff/troff/input.cpp \ + src/roff/troff/mtsm.cpp \ + src/roff/troff/node.cpp \ + src/roff/troff/number.cpp \ + src/roff/troff/reg.cpp \ + src/roff/troff/env.h \ + src/roff/troff/node.h \ + src/roff/troff/troff.h \ + src/roff/troff/div.h \ + src/roff/troff/reg.h \ + src/roff/troff/dictionary.h \ + src/roff/troff/input.h \ + src/roff/troff/mtsm.h \ + src/roff/troff/token.h \ + src/roff/troff/charinfo.h \ + src/roff/troff/request.h \ + src/roff/troff/hvunits.h + +nodist_troff_SOURCES = src/roff/troff/majorminor.cpp + +src/roff/troff/input.$(OBJEXT): defs.h +CLEANFILES += src/roff/troff/majorminor.cpp + +src/roff/troff/majorminor.cpp: $(top_srcdir)/.version + $(AM_V_at)printf 'const char *major_version = "%s";\n' \ + $(MAJOR_VERSION) > $@.tmp + $(AM_V_at)printf 'const char *minor_version = "%s";\n' \ + $(MINOR_VERSION) >> $@.tmp + $(AM_V_at)printf 'const char *revision = "%s";\n' \ + $(REVISION) >> $@.tmp + $(AM_V_GEN)mv $@.tmp $@ + + +# Local Variables: +# mode: makefile-automake +# fill-column: 72 +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/roff/troff/troff.h b/src/roff/troff/troff.h new file mode 100644 index 0000000..8cef744 --- /dev/null +++ b/src/roff/troff/troff.h @@ -0,0 +1,97 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + + +#include "lib.h" + +#include +#include +#include +#include +#include +#include + +#include "color.h" +#include "device.h" +#include "searchpath.h" + +typedef int units; + +extern units scale(units n, units x, units y); // scale n by x/y + +extern units units_per_inch; + +extern int ascii_output_flag; +extern int suppress_output_flag; +extern int color_flag; +extern int is_html; + +extern bool device_has_tcommand; +extern int vresolution; +extern int hresolution; +extern int sizescale; + +extern search_path *mac_path; + +#include "cset.h" +#include "cmap.h" +#include "errarg.h" +#include "error.h" + +enum warning_type { + WARN_CHAR = 01, + WARN_NUMBER = 02, + WARN_BREAK = 04, + WARN_DELIM = 010, + WARN_EL = 020, + WARN_SCALE = 040, + WARN_RANGE = 0100, + WARN_SYNTAX = 0200, + WARN_DI = 0400, + WARN_MAC = 01000, + WARN_REG = 02000, + WARN_TAB = 04000, + WARN_RIGHT_BRACE = 010000, + WARN_MISSING = 020000, + WARN_INPUT = 040000, + WARN_ESCAPE = 0100000, + WARN_SPACE = 0200000, + WARN_FONT = 0400000, + WARN_IG = 01000000, + WARN_COLOR = 02000000, + WARN_FILE = 04000000 + // change WARN_TOTAL if you add more warning types +}; + +const int WARN_TOTAL = 07777777; + +int warning(warning_type, const char *, + const errarg & = empty_errarg, + const errarg & = empty_errarg, + const errarg & = empty_errarg); +int output_warning(warning_type, const char *, + const errarg & = empty_errarg, + const errarg & = empty_errarg, + const errarg & = empty_errarg); + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/utils/addftinfo/addftinfo.1.man b/src/utils/addftinfo/addftinfo.1.man new file mode 100644 index 0000000..a719136 --- /dev/null +++ b/src/utils/addftinfo/addftinfo.1.man @@ -0,0 +1,236 @@ +.TH addftinfo @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +addftinfo \- add font metrics to +.I troff +fonts for use with +.I groff +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1989-2020 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_addftinfo_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY addftinfo +.RB [ \-asc\-height\~\c +.IR n ] +.RB [ \-body\-depth\~\c +.IR n ] +.RB [ \-body\-height\~\c +.IR n ] +.RB [ \-cap\-height\~\c +.IR n ] +.RB [ \-comma\-depth\~\c +.IR n ] +.RB [ \-desc\-depth\~\c +.IR n ] +.RB [ \-fig\-height\~\c +.IR n ] +.RB [ \-x\-height\~\c +.IR n ] +.I resolution +.I unit-width +.I font +.YS +. +. +.SY addftinfo +.B \-\-help +.YS +. +. +.SY addftinfo +.B \-v +. +.SY addftinfo +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I addftinfo +reads an +.RI AT&T \~troff +font description file +.IR font , +adds additional font metric information required by +.\" We need the "GNU" below because the @g@ prefix might be empty. +.RI GNU \~@g@troff (@MAN1EXT@), +and writes the combined result to the standard output. +. +The information added is derived from the font's existing parameters and +assumptions about traditional +.I troff +names for characters. +. +Among the font metrics added are the heights and depths of characters +(how far each extends vertically above and below the baseline). +. +The +.I resolution +and +.I unit-width +arguments should be the same as the corresponding parameters in the +.I DESC +file. +. +.I font +is the name of the file describing the font; +if +.I font +ends with +.RB \[lq] I \[rq], +the font is assumed to be oblique +(or italic). +. +. +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-\-help +displays a usage message, +while +.B \-v +and +.B \-\-version +show version information; +all exit afterward. +. +. +.P +All other options change parameters that are used to derive the heights +and depths. +. +Like the existing quantities in the font description file, +each +.RI value\~ n +is in +.I "scaled points," +.RI inches/ resolution +for a font whose type size is +.IR unit-width ; +see +.MR groff_font @MAN5EXT@ . +. +. +.TP +.BI \-asc\-height \~n +height of characters with ascenders, +such as \[lq]b\[rq], +\[lq]d\[rq], +or \[lq]l\[rq] +. +. +.TP +.BI \-body\-depth \~n +depth of characters such as parentheses +. +. +.TP +.BI \-body\-height \~n +height of characters such as parentheses +. +. +.TP +.BI \-cap\-height \~n +height of uppercase letters such as \[lq]A\[rq] +. +. +.TP +.BI \-comma\-depth \~n +depth of a comma +. +. +.TP +.BI \-desc\-depth \~n +depth of characters with descenders, +such as \[lq]p\[rq], +\[lq]q\[rq], +or \[lq]y\[rq] +. +. +.TP +.B \-fig\-height +height of figures (numerals) +. +. +.TP +.BI \-x\-height \~n +height of lowercase letters without ascenders such as \[lq]x\[rq] +. +. +.P +.I addftinfo +makes no attempt to use the specified parameters to infer unspecified +parameters. +. +If a parameter is not specified, +the default will be used. +. +The defaults are chosen to produce reasonable values for a Times font. +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.MR groff_font @MAN5EXT@ , +.MR groff @MAN1EXT@ , +.MR groff_char @MAN7EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_addftinfo_1_man_C] +.do rr *groff_addftinfo_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/utils/addftinfo/addftinfo.am b/src/utils/addftinfo/addftinfo.am new file mode 100644 index 0000000..dd51372 --- /dev/null +++ b/src/utils/addftinfo/addftinfo.am @@ -0,0 +1,35 @@ +# Automake rules for 'src utils addftinfo' +# +# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# +# '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 2 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 +# . +# +######################################################################## + +bin_PROGRAMS += addftinfo +man1_MANS += src/utils/addftinfo/addftinfo.1 +EXTRA_DIST += src/utils/addftinfo/addftinfo.1.man +addftinfo_LDADD = libgroff.a lib/libgnu.a +addftinfo_SOURCES = \ + src/utils/addftinfo/addftinfo.cpp \ + src/utils/addftinfo/guess.cpp \ + src/utils/addftinfo/guess.h + + +# Local Variables: +# mode: makefile-automake +# fill-column: 72 +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/utils/addftinfo/addftinfo.cpp b/src/utils/addftinfo/addftinfo.cpp new file mode 100644 index 0000000..6f4facf --- /dev/null +++ b/src/utils/addftinfo/addftinfo.cpp @@ -0,0 +1,237 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "lib.h" + +#include +#include +#include +#include "errarg.h" +#include "error.h" +#include "stringclass.h" +#include "cset.h" +#include "guess.h" + +extern "C" const char *Version_string; + +static void usage(FILE *stream); +static void usage(); +static void usage(const char *problem); +static void version(); +static void convert_font(const font_params &, FILE *, FILE *); + +typedef int font_params::*param_t; + +static struct { + const char *name; + param_t par; +} param_table[] = { + { "asc-height", &font_params::asc_height }, + { "body-depth", &font_params::body_depth }, + { "body-height", &font_params::body_height }, + { "cap-height", &font_params::cap_height }, + { "comma-depth", &font_params::comma_depth }, + { "desc-depth", &font_params::desc_depth }, + { "fig-height", &font_params::fig_height }, + { "x-height", &font_params::x_height }, +}; + +// These are all in thousandths of an em. +// These values are correct for PostScript Times Roman. + +#define DEFAULT_X_HEIGHT 448 +#define DEFAULT_FIG_HEIGHT 676 +#define DEFAULT_ASC_HEIGHT 682 +#define DEFAULT_BODY_HEIGHT 676 +#define DEFAULT_CAP_HEIGHT 662 +#define DEFAULT_COMMA_DEPTH 143 +#define DEFAULT_DESC_DEPTH 217 +#define DEFAULT_BODY_DEPTH 177 + +int main(int argc, char **argv) +{ + program_name = argv[0]; + int i; + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-v") || !strcmp(argv[i],"--version")) + version(); + if (!strcmp(argv[i],"--help")) { + usage(stdout); + exit(0); + } + } + if (argc < 4) + usage("insufficient arguments"); + /* The next couple of usage() calls cannot provide a meaningful + diagnostic because we don't know whether sscanf() failed on a + required parameter or an option. A refactor could fix this. */ + int resolution; + if (sscanf(argv[argc-3], "%d", &resolution) != 1) + usage(); + if (resolution <= 0) + fatal("resolution must be positive"); + int unitwidth; + if (sscanf(argv[argc-2], "%d", &unitwidth) != 1) + usage(); + if (unitwidth <= 0) + fatal("unit width must be positive"); + font_params param; + const char *font = argv[argc-1]; + param.italic = (font[0] != '\0' && strchr(font, '\0')[-1] == 'I'); + param.em = (resolution*unitwidth)/72; + param.x_height = DEFAULT_X_HEIGHT; + param.fig_height = DEFAULT_FIG_HEIGHT; + param.asc_height = DEFAULT_ASC_HEIGHT; + param.body_height = DEFAULT_BODY_HEIGHT; + param.cap_height = DEFAULT_CAP_HEIGHT; + param.comma_depth = DEFAULT_COMMA_DEPTH; + param.desc_depth = DEFAULT_DESC_DEPTH; + param.body_depth = DEFAULT_BODY_DEPTH; + for (i = 1; i < argc && argv[i][0] == '-'; i++) { + if (argv[i][1] == '-' && argv[i][2] == '\0') { + i++; + break; + } + if (i + 1 >= argc) + usage("option requires argument"); + size_t j; + for (j = 0;; j++) { + if (j >= sizeof(param_table)/sizeof(param_table[0])) + fatal("parameter '%1' not recognized", argv[i] + 1); + if (strcmp(param_table[j].name, argv[i] + 1) == 0) + break; + } + if (sscanf(argv[i+1], "%d", &(param.*(param_table[j].par))) != 1) + fatal("invalid option argument '%1'", argv[i+1]); + i++; + } + if (argc - i != 3) + usage("insufficient arguments"); + errno = 0; + FILE *infp = fopen(font, "r"); + if (infp == 0) + fatal("can't open '%1': %2", font, strerror(errno)); + convert_font(param, infp, stdout); + return 0; +} + +static void usage(FILE *stream) +{ + fprintf(stream, "usage: %s", program_name); + size_t len = sizeof(param_table)/sizeof(param_table[0]); + for (size_t i = 0; i < len; i++) + fprintf(stream, " [-%s n]", param_table[i].name); + fputs(" resolution unit-width font\n", stream); + fprintf(stream, "usage: %s {-v | --version}\n" + "usage: %s --help\n", program_name, program_name); +} + +static void usage() +{ + usage(stderr); + exit(1); +} + +static void usage(const char *problem) +{ + error("%1", problem); + usage(); +} + +static void version() +{ + printf("GNU addftinfo (groff) version %s\n", Version_string); + exit(0); +} + +static int get_line(FILE *fp, string *p) +{ + int c; + p->clear(); + while ((c = getc(fp)) != EOF) { + *p += char(c); + if (c == '\n') + break; + } + return p->length() > 0; +} + +static void convert_font(const font_params ¶m, FILE *infp, + FILE *outfp) +{ + string s; + while (get_line(infp, &s)) { + put_string(s, outfp); + if (s.length() >= 8 + && strncmp(&s[0], "charset", 7)) + break; + } + while (get_line(infp, &s)) { + s += '\0'; + string name; + const char *p = s.contents(); + while (csspace(*p)) + p++; + while (*p != '\0' && !csspace(*p)) + name += *p++; + while (csspace(*p)) + p++; + for (const char *q = s.contents(); q < p; q++) + putc(*q, outfp); + char *next; + char_metric metric; + metric.width = (int)strtol(p, &next, 10); + if (next != p) { + printf("%d", metric.width); + p = next; + metric.type = (int)strtol(p, &next, 10); + if (next != p) { + name += '\0'; + guess(name.contents(), param, &metric); + if (metric.sk == 0) { + if (metric.left_ic == 0) { + if (metric.ic == 0) { + if (metric.depth == 0) { + if (metric.height != 0) + printf(",%d", metric.height); + } + else + printf(",%d,%d", metric.height, metric.depth); + } + else + printf(",%d,%d,%d", metric.height, metric.depth, + metric.ic); + } + else + printf(",%d,%d,%d,%d", metric.height, metric.depth, + metric.ic, metric.left_ic); + } + else + printf(",%d,%d,%d,%d,%d", metric.height, metric.depth, + metric.ic, metric.left_ic, metric.sk); + } + } + fputs(p, outfp); + } +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/utils/addftinfo/guess.cpp b/src/utils/addftinfo/guess.cpp new file mode 100644 index 0000000..08bbe05 --- /dev/null +++ b/src/utils/addftinfo/guess.cpp @@ -0,0 +1,489 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "guess.h" + +void guess(const char *s, const font_params ¶m, char_metric *metric) +{ + int &height = metric->height; + int &depth = metric->depth; + + metric->ic = 0; + metric->left_ic = 0; + metric->sk = 0; + height = 0; + depth = 0; + if (s[0] == '\0' || (s[1] != '\0' && s[2] != '\0')) + goto do_default; +#define HASH(c1, c2) (((unsigned char)(c1) << 8) | (unsigned char)(c2)) + switch (HASH(s[0], s[1])) { + default: + do_default: + if (metric->type & 01) + depth = param.desc_depth; + if (metric->type & 02) + height = param.asc_height; + else + height = param.x_height; + break; + case HASH('\\', '|'): + case HASH('\\', '^'): + case HASH('\\', '&'): + // these have zero height and depth + break; + case HASH('f', 0): + height = param.asc_height; + if (param.italic) + depth = param.desc_depth; + break; + case HASH('a', 0): + case HASH('c', 0): + case HASH('e', 0): + case HASH('m', 0): + case HASH('n', 0): + case HASH('o', 0): + case HASH('r', 0): + case HASH('s', 0): + case HASH('u', 0): + case HASH('v', 0): + case HASH('w', 0): + case HASH('x', 0): + case HASH('z', 0): + height = param.x_height; + break; + case HASH('i', 0): + height = param.x_height; + break; + case HASH('b', 0): + case HASH('d', 0): + case HASH('h', 0): + case HASH('k', 0): + case HASH('l', 0): + case HASH('F', 'i'): + case HASH('F', 'l'): + case HASH('f', 'f'): + case HASH('f', 'i'): + case HASH('f', 'l'): + height = param.asc_height; + break; + case HASH('t', 0): + height = param.asc_height; + break; + case HASH('g', 0): + case HASH('p', 0): + case HASH('q', 0): + case HASH('y', 0): + height = param.x_height; + depth = param.desc_depth; + break; + case HASH('j', 0): + height = param.x_height; + depth = param.desc_depth; + break; + case HASH('A', 0): + case HASH('B', 0): + case HASH('C', 0): + case HASH('D', 0): + case HASH('E', 0): + case HASH('F', 0): + case HASH('G', 0): + case HASH('H', 0): + case HASH('I', 0): + case HASH('J', 0): + case HASH('K', 0): + case HASH('L', 0): + case HASH('M', 0): + case HASH('N', 0): + case HASH('O', 0): + case HASH('P', 0): + case HASH('Q', 0): + case HASH('R', 0): + case HASH('S', 0): + case HASH('T', 0): + case HASH('U', 0): + case HASH('V', 0): + case HASH('W', 0): + case HASH('X', 0): + case HASH('Y', 0): + case HASH('Z', 0): + height = param.cap_height; + break; + case HASH('*', 'A'): + case HASH('*', 'B'): + case HASH('*', 'C'): + case HASH('*', 'D'): + case HASH('*', 'E'): + case HASH('*', 'F'): + case HASH('*', 'G'): + case HASH('*', 'H'): + case HASH('*', 'I'): + case HASH('*', 'K'): + case HASH('*', 'L'): + case HASH('*', 'M'): + case HASH('*', 'N'): + case HASH('*', 'O'): + case HASH('*', 'P'): + case HASH('*', 'Q'): + case HASH('*', 'R'): + case HASH('*', 'S'): + case HASH('*', 'T'): + case HASH('*', 'U'): + case HASH('*', 'W'): + case HASH('*', 'X'): + case HASH('*', 'Y'): + case HASH('*', 'Z'): + height = param.cap_height; + break; + case HASH('0', 0): + case HASH('1', 0): + case HASH('2', 0): + case HASH('3', 0): + case HASH('4', 0): + case HASH('5', 0): + case HASH('6', 0): + case HASH('7', 0): + case HASH('8', 0): + case HASH('9', 0): + case HASH('1', '2'): + case HASH('1', '4'): + case HASH('3', '4'): + height = param.fig_height; + break; + case HASH('(', 0): + case HASH(')', 0): + case HASH('[', 0): + case HASH(']', 0): + case HASH('{', 0): + case HASH('}', 0): + height = param.body_height; + depth = param.body_depth; + break; + case HASH('i', 's'): + height = (param.em*3)/4; + depth = param.em/4; + break; + case HASH('*', 'a'): + case HASH('*', 'e'): + case HASH('*', 'i'): + case HASH('*', 'k'): + case HASH('*', 'n'): + case HASH('*', 'o'): + case HASH('*', 'p'): + case HASH('*', 's'): + case HASH('*', 't'): + case HASH('*', 'u'): + case HASH('*', 'w'): + height = param.x_height; + break; + case HASH('*', 'd'): + case HASH('*', 'l'): + height = param.asc_height; + break; + case HASH('*', 'g'): + case HASH('*', 'h'): + case HASH('*', 'm'): + case HASH('*', 'r'): + case HASH('*', 'x'): + case HASH('*', 'y'): + height = param.x_height; + depth = param.desc_depth; + break; + case HASH('*', 'b'): + case HASH('*', 'c'): + case HASH('*', 'f'): + case HASH('*', 'q'): + case HASH('*', 'z'): + height = param.asc_height; + depth = param.desc_depth; + break; + case HASH('t', 's'): + height = param.x_height; + depth = param.desc_depth; + break; + case HASH('!', 0): + case HASH('?', 0): + case HASH('"', 0): + case HASH('#', 0): + case HASH('$', 0): + case HASH('%', 0): + case HASH('&', 0): + case HASH('*', 0): + case HASH('+', 0): + height = param.asc_height; + break; + case HASH('`', 0): + case HASH('\'', 0): + height = param.asc_height; + break; + case HASH('~', 0): + case HASH('^', 0): + case HASH('a', 'a'): + case HASH('g', 'a'): + height = param.asc_height; + break; + case HASH('r', 'u'): + case HASH('.', 0): + break; + case HASH(',', 0): + depth = param.comma_depth; + break; + case HASH('m', 'i'): + case HASH('-', 0): + case HASH('h', 'y'): + case HASH('e', 'm'): + height = param.x_height; + break; + case HASH(':', 0): + height = param.x_height; + break; + case HASH(';', 0): + height = param.x_height; + depth = param.comma_depth; + break; + case HASH('=', 0): + case HASH('e', 'q'): + height = param.x_height; + break; + case HASH('<', 0): + case HASH('>', 0): + case HASH('>', '='): + case HASH('<', '='): + case HASH('@', 0): + case HASH('/', 0): + case HASH('|', 0): + case HASH('\\', 0): + height = param.asc_height; + break; + case HASH('_', 0): + case HASH('u', 'l'): + case HASH('\\', '_'): + depth = param.em/4; + break; + case HASH('r', 'n'): + height = (param.em*3)/4; + break; + case HASH('s', 'r'): + height = (param.em*3)/4; + depth = param.em/4; + break; + case HASH('b', 'u'): + case HASH('s', 'q'): + case HASH('d', 'e'): + case HASH('d', 'g'): + case HASH('f', 'm'): + case HASH('c', 't'): + case HASH('r', 'g'): + case HASH('c', 'o'): + case HASH('p', 'l'): + case HASH('*', '*'): + case HASH('s', 'c'): + case HASH('s', 'l'): + case HASH('=', '='): + case HASH('~', '='): + case HASH('a', 'p'): + case HASH('!', '='): + case HASH('-', '>'): + case HASH('<', '-'): + case HASH('u', 'a'): + case HASH('d', 'a'): + case HASH('m', 'u'): + case HASH('d', 'i'): + case HASH('+', '-'): + case HASH('c', 'u'): + case HASH('c', 'a'): + case HASH('s', 'b'): + case HASH('s', 'p'): + case HASH('i', 'b'): + case HASH('i', 'p'): + case HASH('i', 'f'): + case HASH('p', 'd'): + case HASH('g', 'r'): + case HASH('n', 'o'): + case HASH('p', 't'): + case HASH('e', 's'): + case HASH('m', 'o'): + case HASH('b', 'r'): + case HASH('d', 'd'): + case HASH('r', 'h'): + case HASH('l', 'h'): + case HASH('o', 'r'): + case HASH('c', 'i'): + height = param.asc_height; + break; + case HASH('l', 't'): + case HASH('l', 'b'): + case HASH('r', 't'): + case HASH('r', 'b'): + case HASH('l', 'k'): + case HASH('r', 'k'): + case HASH('b', 'v'): + case HASH('l', 'f'): + case HASH('r', 'f'): + case HASH('l', 'c'): + case HASH('r', 'c'): + height = (param.em*3)/4; + depth = param.em/4; + break; +#if 0 + case HASH('%', '0'): + case HASH('-', '+'): + case HASH('-', 'D'): + case HASH('-', 'd'): + case HASH('-', 'd'): + case HASH('-', 'h'): + case HASH('.', 'i'): + case HASH('.', 'j'): + case HASH('/', 'L'): + case HASH('/', 'O'): + case HASH('/', 'l'): + case HASH('/', 'o'): + case HASH('=', '~'): + case HASH('A', 'E'): + case HASH('A', 'h'): + case HASH('A', 'N'): + case HASH('C', 's'): + case HASH('D', 'o'): + case HASH('F', 'c'): + case HASH('F', 'o'): + case HASH('I', 'J'): + case HASH('I', 'm'): + case HASH('O', 'E'): + case HASH('O', 'f'): + case HASH('O', 'K'): + case HASH('O', 'm'): + case HASH('O', 'R'): + case HASH('P', 'o'): + case HASH('R', 'e'): + case HASH('S', '1'): + case HASH('S', '2'): + case HASH('S', '3'): + case HASH('T', 'P'): + case HASH('T', 'p'): + case HASH('Y', 'e'): + case HASH('\\', '-'): + case HASH('a', '"'): + case HASH('a', '-'): + case HASH('a', '.'): + case HASH('a', '^'): + case HASH('a', 'b'): + case HASH('a', 'c'): + case HASH('a', 'd'): + case HASH('a', 'e'): + case HASH('a', 'h'): + case HASH('a', 'o'): + case HASH('a', 't'): + case HASH('a', '~'): + case HASH('b', 'a'): + case HASH('b', 'b'): + case HASH('b', 's'): + case HASH('c', '*'): + case HASH('c', '+'): + case HASH('f', '/'): + case HASH('f', 'a'): + case HASH('f', 'c'): + case HASH('f', 'o'): + case HASH('h', 'a'): + case HASH('h', 'o'): + case HASH('i', 'j'): + case HASH('l', 'A'): + case HASH('l', 'B'): + case HASH('l', 'C'): + case HASH('m', 'd'): + case HASH('n', 'c'): + case HASH('n', 'e'): + case HASH('n', 'm'): + case HASH('o', 'A'): + case HASH('o', 'a'): + case HASH('o', 'e'): + case HASH('o', 'q'): + case HASH('p', 'l'): + case HASH('p', 'p'): + case HASH('p', 's'): + case HASH('r', '!'): + case HASH('r', '?'): + case HASH('r', 'A'): + case HASH('r', 'B'): + case HASH('r', 'C'): + case HASH('r', 's'): + case HASH('s', 'h'): + case HASH('s', 's'): + case HASH('t', 'e'): + case HASH('t', 'f'): + case HASH('t', 'i'): + case HASH('t', 'm'): + case HASH('~', '~'): + case HASH('v', 'S'): + case HASH('v', 'Z'): + case HASH('v', 's'): + case HASH('v', 'z'): + case HASH('^', 'A'): + case HASH('^', 'E'): + case HASH('^', 'I'): + case HASH('^', 'O'): + case HASH('^', 'U'): + case HASH('^', 'a'): + case HASH('^', 'e'): + case HASH('^', 'i'): + case HASH('^', 'o'): + case HASH('^', 'u'): + case HASH('`', 'A'): + case HASH('`', 'E'): + case HASH('`', 'I'): + case HASH('`', 'O'): + case HASH('`', 'U'): + case HASH('`', 'a'): + case HASH('`', 'e'): + case HASH('`', 'i'): + case HASH('`', 'o'): + case HASH('`', 'u'): + case HASH('~', 'A'): + case HASH('~', 'N'): + case HASH('~', 'O'): + case HASH('~', 'a'): + case HASH('~', 'n'): + case HASH('~', 'o'): + case HASH('\'', 'A'): + case HASH('\'', 'C'): + case HASH('\'', 'E'): + case HASH('\'', 'I'): + case HASH('\'', 'O'): + case HASH('\'', 'U'): + case HASH('\'', 'a'): + case HASH('\'', 'c'): + case HASH('\'', 'e'): + case HASH('\'', 'i'): + case HASH('\'', 'o'): + case HASH('\'', 'u') + case HASH(':', 'A'): + case HASH(':', 'E'): + case HASH(':', 'I'): + case HASH(':', 'O'): + case HASH(':', 'U'): + case HASH(':', 'Y'): + case HASH(':', 'a'): + case HASH(':', 'e'): + case HASH(':', 'i'): + case HASH(':', 'o'): + case HASH(':', 'u'): + case HASH(':', 'y'): + case HASH(',', 'C'): + case HASH(',', 'c'): +#endif + } +} diff --git a/src/utils/addftinfo/guess.h b/src/utils/addftinfo/guess.h new file mode 100644 index 0000000..d763fe0 --- /dev/null +++ b/src/utils/addftinfo/guess.h @@ -0,0 +1,43 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +struct font_params { + int italic; + int em; + int x_height; + int fig_height; + int cap_height; + int asc_height; + int body_height; + int comma_depth; + int desc_depth; + int body_depth; +}; + +struct char_metric { + int width; + int type; + int height; + int depth; + int ic; + int left_ic; + int sk; +}; + +void guess(const char *s, const font_params ¶m, char_metric *metric); diff --git a/src/utils/afmtodit/afmtodit.1.man b/src/utils/afmtodit/afmtodit.1.man new file mode 100644 index 0000000..7b0a39f --- /dev/null +++ b/src/utils/afmtodit/afmtodit.1.man @@ -0,0 +1,635 @@ +.TH afmtodit @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +afmtodit \- adapt Adobe Font Metrics files for +.I groff +PostScript and PDF output +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1989-2020 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_afmtodit_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY afmtodit +.RB [ \-ckmnsx ] +.RB [ \-a\~\c +.IR slant ] +.RB [ \-d\~\c +.IR device-description-file ] +.RB [ \-e\~\c +.IR encoding-file ] +.RB [ \-f\~\c +.IR internal-name ] +.RB [ \-i\~\c +.IR italic-correction-factor ] +.RB [ \-o\~\c +.IR output-file ] +.RB [ \-w\~\c +.IR space-width ] +.I afm-file +.I map-file +.I font-description-file +.YS +. +. +.SY afmtodit +.B \-\-help +.YS +. +. +.SY afmtodit +.B \-v +. +.SY afmtodit +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I \%afmtodit +adapts an +Adobe Font Metric +file, +.IR afm-file , +for use with the +.B ps +and +.B pdf +output devices of +.MR @g@troff @MAN1EXT@ . +. +.I map-file +associates a +.I groff +ordinary or special character name with a PostScript glyph name. +. +Output is written in +.MR groff_font @MAN5EXT@ +format to +.I font-description-file, +a file named for the intended +.I groff +font name +(but see the +.B \-o +option). +. +. +.LP +.I map-file +should contain a sequence of lines of the form +. +.RS +.EX +.I ps-glyph groff-char +.EE +.RE +. +where +.I ps-glyph +is the PostScript glyph name and +.I groff-char +is a +.I groff +ordinary +(if of unit length) +or special +(if longer) +character identifier. +. +The same +.I ps-glyph +can occur multiple times in the file; +each +.I groff-char +must occur at most once. +. +Lines starting with \[lq]#\[rq] and blank lines are ignored. +. +If the file isn't found in the current directory, +it is sought in the +.I devps/generate +subdirectory of the default font directory. +. +. +.LP +If a PostScript glyph is not mentioned in +.IR map-file , +and a +.I groff +character name can't be deduced using the Adobe Glyph List +(AGL, +built into +.IR afmtodit ), +then +.I \%afmtodit +puts the PostScript glyph into the +.I groff +font description file as an unnamed glyph which can only be accessed +by the \[lq]\eN\[rq] escape sequence in a +.I roff +document. +. +In particular, +this is true for glyph variants named in the form +.RI \[lq] foo . bar \[rq]; +all glyph names containing one or more periods are mapped to unnamed +entities. +. +Unless +.B \-e +is specified, +the encoding defined in the AFM file +(i.e., +entries +with non-negative codes) +is used. +. +Refer to section \[lq]Using Symbols\[rq] in +.IR "Groff: The GNU Implementation of troff" , +the +.I groff +Texinfo manual, +or +.MR groff_char @MAN7EXT@ , +which describe how +.I groff +character identifiers are constructed. +. +. +.LP +Glyphs not encoded in the AFM file +(i.e., +entries indexed as \[lq]\-1\[rq]) +are still available in +.IR groff ; +they get glyph index values greater than 255 +(or greater than the biggest code used in the AFM file in the unlikely +case that it is greater than 255) +in the +.I groff +font description file. +. +Unencoded glyph indices don't have a specific order; +it is best to access them only via special character identifiers. +. +. +.P +If the font file proper +(not just its metrics) +is available, +listing it in the files +.I @FONTDIR@/\:\%devps/\:\%download +and +.I @FONTDIR@/\:\%devpdf/\:\%download +enables it to be embedded in the output produced by +.MR grops @MAN1EXT@ +and +.MR gropdf @MAN1EXT@ , +respectively. +. +. +.P +If the +.B \-i +option is used, +.I \%afmtodit +automatically generates an italic correction, +a left italic correction, +and a subscript correction for each glyph +(the significance of these is explained in +.MR groff_font @MAN5EXT@ ); +they can be specified for individual glyphs by +adding to the +.I afm-file +lines of the form: +. +.RS +.EX +.RI italicCorrection \~ps-glyph\~n +.RI leftItalicCorrection \~ps-glyph\~n +.RI subscriptCorrection \~ps-glyph\~n +.EE +.RE +. +where +.I ps-glyph +is the PostScript glyph name, +and +.I n +is the desired value of the corresponding parameter in thousandths of an +em. +. +Such parameters are normally needed only for italic +(or oblique) +fonts. +. +. +.P +The +.B \-s +option should be given if the font is \[lq]special\[rq], +meaning that +.I groff +should search it whenever a glyph is not found in the current font. +. +In that case, +.I font-description-file +should be listed as an argument to the +.B fonts +directive in the output device's +.I DESC +file; +if it is not special, +there is no need to do so, +since +.MR @g@troff @MAN1EXT@ +will automatically mount it when it is first used. +. +. +.br +.ne 7v +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-\-help +displays a usage message, +while +.B \-v +and +.B \%\-\-version +show version information; +all exit afterward. +. +. +.TP +.BI \-a\~ slant +Use +.I slant +as the slant (\[lq]angle\[rq]) parameter in the font description file; +this is used by +.I groff +in the positioning of accents. +. +By default +.I \%afmtodit +uses the negative of the +.B \%ItalicAngle +specified in the AFM file; +with true italic fonts it is sometimes desirable to use a slant that is +less than this. +. +If you find that an italic font places accents over base glyphs +too far to the right, +use +.B \-a +to give it a smaller slant. +. +. +.TP +.B \-c +Include comments in the font description file identifying the PostScript +font. +. +. +.TP +.BI \-d\~ device-description-file +The device description file is +.I desc-file +rather than the default +.IR DESC . +. +If not found in the current directory, +the +.I devps +subdirectory of the default font directory is searched +(this is true for both the default device description file and a file +given with option +.BR \-d ). +. +. +.TP +.BI \-e\~ encoding-file +The PostScript font should be reencoded to use the encoding described +in +.IR enc-file . +. +The format of +.I enc-file +is described in +.MR grops @MAN1EXT@ . +. +If not found in the current directory, +the +.I devps +subdirectory of the default font directory is searched. +. +. +.TP +.BI \-f\~ internal-name +The internal name of the +.I groff +font is set to +.IR name . +. +. +.TP +.BI \-i\~ italic-correction-factor +Generate an italic correction for each glyph so that its width plus its +italic correction is equal to +.I italic-correction-factor +thousandths of an em +plus the amount by which the right edge of the glyph's bounding box is +to the right of its origin. +. +If this would result in a negative italic correction, +use a zero italic correction instead. +. +. +.IP +Also generate a subscript correction equal to the +product of the tangent of the slant of the font and +four fifths of the x-height of the font. +. +If this would result in a subscript correction greater than the italic +correction, +use a subscript correction equal to the italic correction instead. +. +. +.IP +Also generate a left italic correction for each glyph equal to +.I italic-correction-factor +thousandths of an em +plus the amount by which the left edge of the glyph's bounding box is to +the left of its origin. +. +The left italic correction may be negative unless option +.B \-m +is given. +. +. +.IP +This option is normally needed only with italic +(or oblique) +fonts. +. +The font description files distributed with +.I groff +were created using an option of +.B \-i50 +for italic fonts. +. +. +.TP +.BI \-o\~ output-file +Write to +.I output-file +instead of +.I font-description-file. +. +. +.TP +.B \-k +Omit any kerning data from the +.I groff +font; +use only for monospaced (constant-width) fonts. +. +. +.TP +.B \-m +Prevent negative left italic correction values. +. +Font description files for roman styles distributed with +.I groff +were created with +.RB \[lq] \-i0\~\-m \[rq] +to improve spacing with +.MR @g@eqn @MAN1EXT@ . +. +. +.TP +.B \-n +Don't output a +.B ligatures +command for this font; +use with monospaced (constant-width) fonts. +. +. +.TP +.B \-s +Add the +.B special +directive to the font description file. +. +. +.TP +.BI \-w\~ space-width +Use +.I space-width +as the with of inter-word spaces. +. +. +.TP +.B \-x +Don't use the built-in Adobe Glyph List. +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.I @FONTDIR@/\:\%devps/\:DESC +describes the +.B ps +output device. +. +. +.TP +.IR @FONTDIR@/\:\%devps/ F +describes the font known +.RI as\~ F +on device +.BR ps . +. +. +.TP +.I @FONTDIR@/\:\%devps/\:\%download +lists fonts available for embedding within the PostScript document +(or download to the device). +. +. +.TP +.I @FONTDIR@/\:\%devps/\:\%generate/\:\%dingbats.map +.TQ +.I @FONTDIR@/\:\%devps/\:\%generate/\:\%dingbats\-reversed.map +.TQ +.I @FONTDIR@/\:\%devps/\:\%generate/\:\%slanted\-symbol.map +.TQ +.I @FONTDIR@/\:\%devps/\:\%generate/\:\%symbol.map +.TQ +.I @FONTDIR@/\:\%devps/\:\%generate/\:\%text.map +map names in the Adobe Glyph List to +.I groff +special character identifiers for Zapf Dingbats +.RB ( ZD ), +reversed Zapf Dingbats +.RB ( ZDR ), +slanted symbol +.RB ( SS ), +symbol +.RB ( S ), +and text fonts, +respectively. +. +These +.IR map-file s +are used to produce the font description files provided with +.I groff +for the +.I \%grops +output driver. +. +. +.\" ==================================================================== +.SH Diagnostics +.\" ==================================================================== +. +.TP +.RI "AGL name \[aq]" x "\[aq] already mapped to groff name \[aq]" y\c +.RI "\[aq]; ignoring AGL name \[aq]uni" XXXX \[aq] +You can disregard these if they're in the form shown, +where the ignored AGL name contains four hexadecimal digits +.IR XXXX . +. +The Adobe Glyph List (AGL) has its own names for glyphs; +they are often +different from +.IR groff 's +special character names. +. +.I \%afmtodit +is constructing a mapping from +.I groff +special character names to AGL names; +this can be a one-to-one or many-to-one mapping, +but one-to-many will not work, +so +.I \%afmtodit +discards the excess mappings. +. +For example, +if +.I x +is +.BR *D , +.I y +is +.BR \%Delta , +and +.I z +is +.BR uni0394 , +.I \%afmtodit +is telling you that the +.I groff +font description that it is writing cannot map the +.I groff +special character +.B \[rs][*D] +to AGL glyphs +.B \%Delta +and +.B uni0394 +at the same time. +. +. +.IP +If you get a message like this but are unhappy with which mapping is +ignored, +a remedy is to craft an alternative +.I map-file +and re-run +.I \%afmtodit +using it. +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.IR "Groff: The GNU Implementation of troff" , +by Trent A.\& Fisher and Werner Lemberg, +is the primary +.I groff +manual. +. +Section \[lq]Using Symbols\[rq] may be of particular note. +. +You can browse it interactively with \[lq]info \[aq](groff)Using +\%Symbols\[aq]\[rq]. +. +. +.LP +.MR groff @MAN1EXT@ , +.MR gropdf @MAN1EXT@ , +.MR grops @MAN1EXT@ , +.MR groff_font @MAN5EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_afmtodit_1_man_C] +.do rr *groff_afmtodit_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/utils/afmtodit/afmtodit.am b/src/utils/afmtodit/afmtodit.am new file mode 100644 index 0000000..fda095d --- /dev/null +++ b/src/utils/afmtodit/afmtodit.am @@ -0,0 +1,56 @@ +# Automake rules for 'src utils afmtodit' +# +# Copyright (C) 2013-2020 Free Software Foundation, Inc. +# +# This file 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 . +# +######################################################################## + +afmtodit_srcdir = $(top_srcdir)/src/utils/afmtodit + +bin_SCRIPTS += afmtodit +man1_MANS += src/utils/afmtodit/afmtodit.1 +EXTRA_DIST += \ + src/utils/afmtodit/afmtodit.1.man \ + src/utils/afmtodit/afmtodit.pl \ + src/utils/afmtodit/afmtodit.tables \ + src/utils/afmtodit/make-afmtodit-tables + +afmtodit: $(afmtodit_srcdir)/afmtodit.pl $(afmtodit_srcdir)/afmtodit.tables + $(AM_V_GEN)if test -n "$(PERL)"; then \ + sed -e "s|[@]PERL[@]|$(PERL)|" \ + -e "s|[@]VERSION[@]|$(VERSION)|" \ + -e "s|[@]FONTDIR[@]|$(fontdir)|" \ + -e "/[@]afmtodit.tables[@]/ r $(afmtodit_srcdir)/afmtodit.tables" \ + -e "/[@]afmtodit.tables[@]/ d" \ + $(afmtodit_srcdir)/afmtodit.pl \ + >afmtodit; \ + else \ + sed -e "s|[@]VERSION[@]|$(VERSION)|" \ + -e "s|[@]FONTDIR[@]|$(fontdir)|" \ + -e "/[@]afmtodit.tables[@]/ r $(afmtodit_srcdir)/afmtodit.tables" \ + -e "/[@]afmtodit.tables[@]/ d" \ + $(afmtodit_srcdir)/afmtodit.pl \ + >afmtodit; \ + fi \ + && chmod +x afmtodit + + +# Local Variables: +# mode: makefile-automake +# fill-column: 72 +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/utils/afmtodit/afmtodit.pl b/src/utils/afmtodit/afmtodit.pl new file mode 100644 index 0000000..c6b67cc --- /dev/null +++ b/src/utils/afmtodit/afmtodit.pl @@ -0,0 +1,645 @@ +#!@PERL@ +# Copyright (C) 1989-2020 Free Software Foundation, Inc. +# Written by James Clark (jjc@jclark.com) +# +# This file 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 . + +use warnings; +use strict; + +@afmtodit.tables@ + +my $prog = $0; +my $groff_sys_fontdir = "@FONTDIR@"; +my $want_help; +my $space_width = 0; + +our ($opt_a, $opt_c, $opt_d, $opt_e, $opt_f, $opt_i, $opt_k, + $opt_m, $opt_n, $opt_o, $opt_s, $opt_v, $opt_x); + +use Getopt::Long qw(:config gnu_getopt); +GetOptions( "a=s", "c", "d=s", "e=s", "f=s", "i=s", "k", "m", "n", + "o=s", "s", "v", "w=i" => \$space_width, "x", "version" => \$opt_v, + "help" => \$want_help +); + +my $afmtodit_version = "GNU afmtodit (groff) version @VERSION@"; + +if ($opt_v) { + print "$afmtodit_version\n"; + exit 0; +} + +sub croak { + my $msg = shift; + print STDERR "$prog: error: $msg"; + exit(1); +} + +sub usage { + my $stream = *STDOUT; + my $had_error = shift; + $stream = *STDERR if $had_error; + print $stream "usage: $prog [-ckmnsx] [-a slant]" . + " [-d device-description-file] [-e encoding-file]" . + " [-f internal-name] [-i italic-correction-factor]" . + " [-o output-file] [-w space-width] afm-file map-file" . + " font-description-file\n" . + "usage: $prog {-v | --version}\n" . + "usage: $prog --help\n"; + unless ($had_error) { + print $stream "\n" . +"Adapt an Adobe Font Metric file, afm-file, for use with the 'ps'\n" . +"and 'pdf' output devices of groff(1). See the afmtodit(1) manual " . +"page.\n"; + } + my $status = 0; + $status = 2 if ($had_error); + exit($status); +} + +&usage(0) if ($want_help); + +if ($#ARGV != 2) { + print STDERR "$prog: usage error: insufficient arguments\n"; + &usage(1); +} + +my $afm = $ARGV[0]; +my $map = $ARGV[1]; +my $fontfile = $ARGV[2]; +my $outfile = $opt_o || $fontfile; +my $desc = $opt_d || "DESC"; +my $sys_map = $groff_sys_fontdir . "/devps/generate/" . $map; +my $sys_desc = $groff_sys_fontdir . "/devps/" . $desc; + +# read the afm file + +my $psname; +my ($notice, $version, $fullname, $familyname, @comments); +my $italic_angle = 0; +my (@kern1, @kern2, @kernx); +my (%italic_correction, %left_italic_correction); +my %subscript_correction; +# my %ligs +my %ligatures; +my (@encoding, %in_encoding); +my (%width, %height, %depth); +my (%left_side_bearing, %right_side_bearing); + +open(AFM, $afm) || croak("unable to open '$ARGV[0]': $!\n"); + +while () { + chomp; + s/\x0D$//; + my @field = split(' '); + next if $#field < 0; + if ($field[0] eq "FontName") { + $psname = $field[1]; + if($opt_f) { + $psname = $opt_f; + } + } + elsif($field[0] eq "Notice") { + $notice = $_; + } + elsif($field[0] eq "Version") { + $version = $_; + } + elsif($field[0] eq "FullName") { + $fullname = $_; + } + elsif($field[0] eq "FamilyName") { + $familyname = $_; + } + elsif($field[0] eq "Comment") { + push(@comments, $_); + } + elsif($field[0] eq "ItalicAngle") { + $italic_angle = -$field[1]; + } + elsif ($field[0] eq "KPX") { + if ($#field == 3) { + push(@kern1, $field[1]); + push(@kern2, $field[2]); + push(@kernx, $field[3]); + } + } + elsif ($field[0] eq "italicCorrection") { + $italic_correction{$field[1]} = $field[2]; + } + elsif ($field[0] eq "leftItalicCorrection") { + $left_italic_correction{$field[1]} = $field[2]; + } + elsif ($field[0] eq "subscriptCorrection") { + $subscript_correction{$field[1]} = $field[2]; + } + elsif ($field[0] eq "StartCharMetrics") { + while () { + @field = split(' '); + next if $#field < 0; + last if ($field[0] eq "EndCharMetrics"); + if ($field[0] eq "C") { + my $w; + my $wx = 0; + my $n = ""; +# %ligs = (); + my $lly = 0; + my $ury = 0; + my $llx = 0; + my $urx = 0; + my $c = $field[1]; + my $i = 2; + while ($i <= $#field) { + if ($field[$i] eq "WX") { + $w = $field[$i + 1]; + $i += 2; + } + elsif ($field[$i] eq "N") { + $n = $field[$i + 1]; + $i += 2; + } + elsif ($field[$i] eq "B") { + $llx = $field[$i + 1]; + $lly = $field[$i + 2]; + $urx = $field[$i + 3]; + $ury = $field[$i + 4]; + $i += 5; + } +# elsif ($field[$i] eq "L") { +# $ligs{$field[$i + 2]} = $field[$i + 1]; +# $i += 3; +# } + else { + while ($i <= $#field && $field[$i] ne ";") { + $i++; + } + $i++; + } + } + if (!$opt_e && $c != -1) { + $encoding[$c] = $n; + $in_encoding{$n} = 1; + } + $width{$n} = $w; + $height{$n} = $ury; + $depth{$n} = -$lly; + $left_side_bearing{$n} = -$llx; + $right_side_bearing{$n} = $urx - $w; +# foreach my $lig (sort keys %ligs) { +# $ligatures{$lig} = $n . " " . $ligs{$lig}; +# } + } + } + } +} +close(AFM); + +# read the DESC file + +my ($sizescale, $resolution, $unitwidth); +$sizescale = 1; + +open(DESC, $desc) || open(DESC, $sys_desc) || + croak("unable to open '$desc' or '$sys_desc': $!\n"); +while () { + next if /^#/; + chop; + my @field = split(' '); + next if $#field < 0; + last if $field[0] eq "charset"; + if ($field[0] eq "res") { + $resolution = $field[1]; + } + elsif ($field[0] eq "unitwidth") { + $unitwidth = $field[1]; + } + elsif ($field[0] eq "sizescale") { + $sizescale = $field[1]; + } +} +close(DESC); + +if ($opt_e) { + # read the encoding file + + my $sys_opt_e = $groff_sys_fontdir . "/devps/" . $opt_e; + open(ENCODING, $opt_e) || open(ENCODING, $sys_opt_e) || + croak("unable to open '$opt_e' or '$sys_opt_e': $!\n"); + while () { + next if /^#/; + chop; + my @field = split(' '); + next if $#field < 0; + if ($#field == 1) { + if ($field[1] >= 0 && defined $width{$field[0]}) { + $encoding[$field[1]] = $field[0]; + $in_encoding{$field[0]} = 1; + } + } + } + close(ENCODING); +} + +# read the map file + +my (%nmap, %map); + +open(MAP, $map) || open(MAP, $sys_map) || + croak("unable to open '$map' or '$sys_map': $!\n"); +while () { + next if /^#/; + chop; + my @field = split(' '); + next if $#field < 0; + if ($#field == 1) { + if ($field[1] eq "space") { + # The PostScript character "space" is automatically mapped + # to the groff character "space"; this is for grops. + warn "$prog: you are not allowed to map to " . + "the groff character 'space'"; + } + elsif ($field[0] eq "space") { + warn "$prog: you are not allowed to map " . + "the PostScript character 'space'"; + } + else { + $nmap{$field[0]} += 0; + $map{$field[0], $nmap{$field[0]}} = $field[1]; + $nmap{$field[0]} += 1; + + # There is more than one way to make a PS glyph name; + # let us try Unicode names with both 'uni' and 'u' prefixes. + my $utmp = $AGL_to_unicode{$field[0]}; + if (defined $utmp && $utmp =~ /^[0-9A-F]{4}$/) { + foreach my $unicodepsname ("uni" . $utmp, "u" . $utmp) { + $nmap{$unicodepsname} += 0; + $map{$unicodepsname, $nmap{$unicodepsname}} = $field[1]; + $nmap{$unicodepsname} += 1; + } + } + } + } +} +close(MAP); + +$italic_angle = $opt_a if $opt_a; + + +if (!$opt_x) { + my %mapped; + my $i = ($#encoding > 256) ? ($#encoding + 1) : 256; + foreach my $ch (sort keys %width) { + # add unencoded characters + if (!$in_encoding{$ch}) { + $encoding[$i] = $ch; + $i++; + } + if ($nmap{$ch}) { + for (my $j = 0; $j < $nmap{$ch}; $j++) { + if (defined $mapped{$map{$ch, $j}}) { + print STDERR "$prog: AGL name" + . " '$mapped{$map{$ch, $j}}' already mapped to" + . " groff name '$map{$ch, $j}'; ignoring AGL" + . " name '$ch'\n"; + } + else { + $mapped{$map{$ch, $j}} = $ch; + } + } + } + else { + my $u = ""; # the resulting groff glyph name + my $ucomp = ""; # Unicode string before decomposition + my $utmp = ""; # temporary value + my $component = ""; + my $nv = 0; + + # Step 1: + # Drop all characters from the glyph name starting with the + # first occurrence of a period (U+002E FULL STOP), if any. + # ?? We avoid mapping of glyphs with periods, since they are + # likely to be variant glyphs, leading to a 'many ps glyphs -- + # one groff glyph' conflict. + # + # If multiple glyphs in the font represent the same character + # in the Unicode standard, as do 'A' and 'A.swash', for example, + # they can be differentiated by using the same base name with + # different suffixes. This suffix (the part of glyph name that + # follows the first period) does not participate in the + # computation of a character sequence. It can be used by font + # designers to indicate some characteristics of the glyph. The + # suffix may contain periods or any other permitted characters. + # Small cap A, for example, could be named 'uni0041.sc' or + # 'A.sc'. + + next if $ch =~ /\./; + + # Step 2: + # Split the remaining string into a sequence of components, + # using the underscore character (U+005F LOW LINE) as the + # delimiter. + + while ($ch =~ /([^_]+)/g) { + $component = $1; + + # Step 3: + # Map each component to a character string according to the + # procedure below: + # + # * If the component is in the Adobe Glyph List, then map + # it to the corresponding character in that list. + + $utmp = $AGL_to_unicode{$component}; + if ($utmp) { + $utmp = "U+" . $utmp; + } + + # * Otherwise, if the component is of the form 'uni' + # (U+0075 U+006E U+0069) followed by a sequence of + # uppercase hexadecimal digits (0 .. 9, A .. F, i.e., + # U+0030 .. U+0039, U+0041 .. U+0046), the length of + # that sequence is a multiple of four, and each group of + # four digits represents a number in the set {0x0000 .. + # 0xD7FF, 0xE000 .. 0xFFFF}, then interpret each such + # number as a Unicode scalar value and map the component + # to the string made of those scalar values. + + elsif ($component =~ /^uni([0-9A-F]{4})+$/) { + while ($component =~ /([0-9A-F]{4})/g) { + $nv = hex("0x" . $1); + if ($nv <= 0xD7FF || $nv >= 0xE000) { + $utmp .= "U+" . $1; + } + else { + $utmp = ""; + last; + } + } + } + + # * Otherwise, if the component is of the form 'u' (U+0075) + # followed by a sequence of four to six uppercase + # hexadecimal digits {0 .. 9, A .. F} (U+0030 .. U+0039, + # U+0041 .. U+0046), and those digits represent a number + # in {0x0000 .. 0xD7FF, 0xE000 .. 0x10FFFF}, then + # interpret this number as a Unicode scalar value and map + # the component to the string made of this scalar value. + + elsif ($component =~ /^u([0-9A-F]{4,6})$/) { + $nv = hex("0x" . $1); + if ($nv <= 0xD7FF || ($nv >= 0xE000 && $nv <= 0x10FFFF)) { + $utmp = "U+" . $1; + } + } + + # Finally, concatenate those strings; the result is the + # character string to which the glyph name is mapped. + + $ucomp .= $utmp if $utmp; + } + + # Unicode decomposition + while ($ucomp =~ /([0-9A-F]{4,6})/g) { + $component = $1; + $utmp = $unicode_decomposed{$component}; + $u .= "_" . ($utmp ? $utmp : $component); + } + $u =~ s/^_/u/; + if ($u) { + if (defined $mapped{$u}) { + warn "$prog: both $mapped{$u} and $ch map to $u"; + } + else { + $mapped{$u} = $ch; + } + $nmap{$ch} += 1; + $map{$ch, "0"} = $u; + } + } + } +} + +# Check explicitly for groff's standard ligatures -- many afm files don't +# have proper 'L' entries. + +my %default_ligatures = ( + "fi", "f i", + "fl", "f l", + "ff", "f f", + "ffi", "ff i", + "ffl", "ff l", +); + +foreach my $lig (sort keys %default_ligatures) { + if (defined $width{$lig} && !defined $ligatures{$lig}) { + $ligatures{$lig} = $default_ligatures{$lig}; + } +} + +# print it all out + +open(FONT, ">$outfile") || + croak("unable to open '$outfile' for writing: $!\n"); +select(FONT); + +print("# This file was generated with $afmtodit_version.\n"); +print("#\n"); +print("# $fullname\n") if defined $fullname; +print("# $version\n") if defined $version; +print("# $familyname\n") if defined $familyname; + +if ($opt_c) { + print("#\n"); + if (defined $notice || @comments) { + print("# The original AFM file contains the following comments:\n"); + print("#\n"); + print("# $notice\n") if defined $notice; + foreach my $comment (@comments) { + print("# $comment\n"); + } + } + else { + print("# The original AFM file contains no comments.\n"); + } +} + +print("\n"); + +my $name = $fontfile; +$name =~ s@.*/@@; + +my $sw = 0; +$sw = conv($width{"space"}) if defined $width{"space"}; +$sw = $space_width if ($space_width); + +print("name $name\n"); +print("internalname $psname\n") if $psname; +print("special\n") if $opt_s; +printf("slant %g\n", $italic_angle) if $italic_angle != 0; +printf("spacewidth %d\n", $sw) if $sw; + +if ($opt_e) { + my $e = $opt_e; + $e =~ s@.*/@@; + print("encoding $e\n"); +} + +if (!$opt_n && %ligatures) { + print("ligatures"); + foreach my $lig (sort keys %ligatures) { + print(" $lig"); + } + print(" 0\n"); +} + +if (!$opt_k && $#kern1 >= 0) { + print("\n"); + print("kernpairs\n"); + + for (my $i = 0; $i <= $#kern1; $i++) { + my $c1 = $kern1[$i]; + my $c2 = $kern2[$i]; + if (defined $nmap{$c1} && $nmap{$c1} != 0 + && defined $nmap{$c2} && $nmap{$c2} != 0) { + for (my $j = 0; $j < $nmap{$c1}; $j++) { + for (my $k = 0; $k < $nmap{$c2}; $k++) { + if ($kernx[$i] != 0) { + printf("%s %s %d\n", + $map{$c1, $j}, + $map{$c2, $k}, + conv($kernx[$i])); + } + } + } + } + } +} + +my ($asc_boundary, $desc_boundary, $xheight, $slant); + +# characters not shorter than asc_boundary are considered to have ascenders + +$asc_boundary = 0; +$asc_boundary = $height{"t"} if defined $height{"t"}; +$asc_boundary -= 1; + +# likewise for descenders + +$desc_boundary = 0; +$desc_boundary = $depth{"g"} if defined $depth{"g"}; +$desc_boundary = $depth{"j"} if defined $depth{"g"} && $depth{"j"} < $desc_boundary; +$desc_boundary = $depth{"p"} if defined $depth{"p"} && $depth{"p"} < $desc_boundary; +$desc_boundary = $depth{"q"} if defined $depth{"q"} && $depth{"q"} < $desc_boundary; +$desc_boundary = $depth{"y"} if defined $depth{"y"} && $depth{"y"} < $desc_boundary; +$desc_boundary -= 1; + +if (defined $height{"x"}) { + $xheight = $height{"x"}; +} +elsif (defined $height{"alpha"}) { + $xheight = $height{"alpha"}; +} +else { + $xheight = 450; +} + +$italic_angle = $italic_angle*3.14159265358979323846/180.0; +$slant = sin($italic_angle)/cos($italic_angle); +$slant = 0 if $slant < 0; + +print("\n"); +print("charset\n"); +for (my $i = 0; $i <= $#encoding; $i++) { + my $ch = $encoding[$i]; + if (defined $ch && $ch ne "" && $ch ne "space") { + $map{$ch, "0"} = "---" if !defined $nmap{$ch} || $nmap{$ch} == 0; + my $type = 0; + my $h = $height{$ch}; + $h = 0 if $h < 0; + my $d = $depth{$ch}; + $d = 0 if $d < 0; + $type = 1 if $d >= $desc_boundary; + $type += 2 if $h >= $asc_boundary; + printf("%s\t%d", $map{$ch, "0"}, conv($width{$ch})); + my $italic_correction = 0; + my $left_math_fit = 0; + my $subscript_correction = 0; + if (defined $opt_i) { + $italic_correction = $right_side_bearing{$ch} + $opt_i; + $italic_correction = 0 if $italic_correction < 0; + $subscript_correction = $slant * $xheight * .8; + $subscript_correction = $italic_correction if + $subscript_correction > $italic_correction; + $left_math_fit = $left_side_bearing{$ch} + $opt_i; + if (defined $opt_m) { + $left_math_fit = 0 if $left_math_fit < 0; + } + } + if (defined $italic_correction{$ch}) { + $italic_correction = $italic_correction{$ch}; + } + if (defined $left_italic_correction{$ch}) { + $left_math_fit = $left_italic_correction{$ch}; + } + if (defined $subscript_correction{$ch}) { + $subscript_correction = $subscript_correction{$ch}; + } + if ($subscript_correction != 0) { + printf(",%d,%d", conv($h), conv($d)); + printf(",%d,%d,%d", conv($italic_correction), + conv($left_math_fit), + conv($subscript_correction)); + } + elsif ($left_math_fit != 0) { + printf(",%d,%d", conv($h), conv($d)); + printf(",%d,%d", conv($italic_correction), + conv($left_math_fit)); + } + elsif ($italic_correction != 0) { + printf(",%d,%d", conv($h), conv($d)); + printf(",%d", conv($italic_correction)); + } + elsif ($d != 0) { + printf(",%d,%d", conv($h), conv($d)); + } + else { + # always put the height in to stop groff guessing + printf(",%d", conv($h)); + } + printf("\t%d", $type); + printf("\t%d\t%s\n", $i, $ch); + if (defined $nmap{$ch}) { + for (my $j = 1; $j < $nmap{$ch}; $j++) { + printf("%s\t\"\n", $map{$ch, $j}); + } + } + } + if (defined $ch && $ch eq "space" && defined $width{"space"}) { + printf("space\t%d\t0\t%d\tspace\n", conv($width{"space"}), $i); + } +} + +sub conv { + $_[0]*$unitwidth*$resolution/(72*1000*$sizescale) + + ($_[0] < 0 ? -.5 : .5); +} + +# Local Variables: +# fill-column: 72 +# mode: CPerl +# End: +# vim: set cindent noexpandtab shiftwidth=2 softtabstop=2 textwidth=72: diff --git a/src/utils/afmtodit/afmtodit.tables b/src/utils/afmtodit/afmtodit.tables new file mode 100644 index 0000000..16e3647 --- /dev/null +++ b/src/utils/afmtodit/afmtodit.tables @@ -0,0 +1,6163 @@ +# This table was algorithmically derived from the file 'UnicodeData.txt' +# for Unicode 15.0.0, available from unicode.org, +# on 2022-10-09. +my %unicode_decomposed = ( + "00C0", "0041_0300", + "00C1", "0041_0301", + "00C2", "0041_0302", + "00C3", "0041_0303", + "00C4", "0041_0308", + "00C5", "0041_030A", + "00C7", "0043_0327", + "00C8", "0045_0300", + "00C9", "0045_0301", + "00CA", "0045_0302", + "00CB", "0045_0308", + "00CC", "0049_0300", + "00CD", "0049_0301", + "00CE", "0049_0302", + "00CF", "0049_0308", + "00D1", "004E_0303", + "00D2", "004F_0300", + "00D3", "004F_0301", + "00D4", "004F_0302", + "00D5", "004F_0303", + "00D6", "004F_0308", + "00D9", "0055_0300", + "00DA", "0055_0301", + "00DB", "0055_0302", + "00DC", "0055_0308", + "00DD", "0059_0301", + "00E0", "0061_0300", + "00E1", "0061_0301", + "00E2", "0061_0302", + "00E3", "0061_0303", + "00E4", "0061_0308", + "00E5", "0061_030A", + "00E7", "0063_0327", + "00E8", "0065_0300", + "00E9", "0065_0301", + "00EA", "0065_0302", + "00EB", "0065_0308", + "00EC", "0069_0300", + "00ED", "0069_0301", + "00EE", "0069_0302", + "00EF", "0069_0308", + "00F1", "006E_0303", + "00F2", "006F_0300", + "00F3", "006F_0301", + "00F4", "006F_0302", + "00F5", "006F_0303", + "00F6", "006F_0308", + "00F9", "0075_0300", + "00FA", "0075_0301", + "00FB", "0075_0302", + "00FC", "0075_0308", + "00FD", "0079_0301", + "00FF", "0079_0308", + "0100", "0041_0304", + "0101", "0061_0304", + "0102", "0041_0306", + "0103", "0061_0306", + "0104", "0041_0328", + "0105", "0061_0328", + "0106", "0043_0301", + "0107", "0063_0301", + "0108", "0043_0302", + "0109", "0063_0302", + "010A", "0043_0307", + "010B", "0063_0307", + "010C", "0043_030C", + "010D", "0063_030C", + "010E", "0044_030C", + "010F", "0064_030C", + "0112", "0045_0304", + "0113", "0065_0304", + "0114", "0045_0306", + "0115", "0065_0306", + "0116", "0045_0307", + "0117", "0065_0307", + "0118", "0045_0328", + "0119", "0065_0328", + "011A", "0045_030C", + "011B", "0065_030C", + "011C", "0047_0302", + "011D", "0067_0302", + "011E", "0047_0306", + "011F", "0067_0306", + "0120", "0047_0307", + "0121", "0067_0307", + "0122", "0047_0327", + "0123", "0067_0327", + "0124", "0048_0302", + "0125", "0068_0302", + "0128", "0049_0303", + "0129", "0069_0303", + "012A", "0049_0304", + "012B", "0069_0304", + "012C", "0049_0306", + "012D", "0069_0306", + "012E", "0049_0328", + "012F", "0069_0328", + "0130", "0049_0307", + "0134", "004A_0302", + "0135", "006A_0302", + "0136", "004B_0327", + "0137", "006B_0327", + "0139", "004C_0301", + "013A", "006C_0301", + "013B", "004C_0327", + "013C", "006C_0327", + "013D", "004C_030C", + "013E", "006C_030C", + "0143", "004E_0301", + "0144", "006E_0301", + "0145", "004E_0327", + "0146", "006E_0327", + "0147", "004E_030C", + "0148", "006E_030C", + "014C", "004F_0304", + "014D", "006F_0304", + "014E", "004F_0306", + "014F", "006F_0306", + "0150", "004F_030B", + "0151", "006F_030B", + "0154", "0052_0301", + "0155", "0072_0301", + "0156", "0052_0327", + "0157", "0072_0327", + "0158", "0052_030C", + "0159", "0072_030C", + "015A", "0053_0301", + "015B", "0073_0301", + "015C", "0053_0302", + "015D", "0073_0302", + "015E", "0053_0327", + "015F", "0073_0327", + "0160", "0053_030C", + "0161", "0073_030C", + "0162", "0054_0327", + "0163", "0074_0327", + "0164", "0054_030C", + "0165", "0074_030C", + "0168", "0055_0303", + "0169", "0075_0303", + "016A", "0055_0304", + "016B", "0075_0304", + "016C", "0055_0306", + "016D", "0075_0306", + "016E", "0055_030A", + "016F", "0075_030A", + "0170", "0055_030B", + "0171", "0075_030B", + "0172", "0055_0328", + "0173", "0075_0328", + "0174", "0057_0302", + "0175", "0077_0302", + "0176", "0059_0302", + "0177", "0079_0302", + "0178", "0059_0308", + "0179", "005A_0301", + "017A", "007A_0301", + "017B", "005A_0307", + "017C", "007A_0307", + "017D", "005A_030C", + "017E", "007A_030C", + "01A0", "004F_031B", + "01A1", "006F_031B", + "01AF", "0055_031B", + "01B0", "0075_031B", + "01CD", "0041_030C", + "01CE", "0061_030C", + "01CF", "0049_030C", + "01D0", "0069_030C", + "01D1", "004F_030C", + "01D2", "006F_030C", + "01D3", "0055_030C", + "01D4", "0075_030C", + "01D5", "0055_0308_0304", + "01D6", "0075_0308_0304", + "01D7", "0055_0308_0301", + "01D8", "0075_0308_0301", + "01D9", "0055_0308_030C", + "01DA", "0075_0308_030C", + "01DB", "0055_0308_0300", + "01DC", "0075_0308_0300", + "01DE", "0041_0308_0304", + "01DF", "0061_0308_0304", + "01E0", "0041_0307_0304", + "01E1", "0061_0307_0304", + "01E2", "00C6_0304", + "01E3", "00E6_0304", + "01E6", "0047_030C", + "01E7", "0067_030C", + "01E8", "004B_030C", + "01E9", "006B_030C", + "01EA", "004F_0328", + "01EB", "006F_0328", + "01EC", "004F_0328_0304", + "01ED", "006F_0328_0304", + "01EE", "01B7_030C", + "01EF", "0292_030C", + "01F0", "006A_030C", + "01F4", "0047_0301", + "01F5", "0067_0301", + "01F8", "004E_0300", + "01F9", "006E_0300", + "01FA", "0041_030A_0301", + "01FB", "0061_030A_0301", + "01FC", "00C6_0301", + "01FD", "00E6_0301", + "01FE", "00D8_0301", + "01FF", "00F8_0301", + "0200", "0041_030F", + "0201", "0061_030F", + "0202", "0041_0311", + "0203", "0061_0311", + "0204", "0045_030F", + "0205", "0065_030F", + "0206", "0045_0311", + "0207", "0065_0311", + "0208", "0049_030F", + "0209", "0069_030F", + "020A", "0049_0311", + "020B", "0069_0311", + "020C", "004F_030F", + "020D", "006F_030F", + "020E", "004F_0311", + "020F", "006F_0311", + "0210", "0052_030F", + "0211", "0072_030F", + "0212", "0052_0311", + "0213", "0072_0311", + "0214", "0055_030F", + "0215", "0075_030F", + "0216", "0055_0311", + "0217", "0075_0311", + "0218", "0053_0326", + "0219", "0073_0326", + "021A", "0054_0326", + "021B", "0074_0326", + "021E", "0048_030C", + "021F", "0068_030C", + "0226", "0041_0307", + "0227", "0061_0307", + "0228", "0045_0327", + "0229", "0065_0327", + "022A", "004F_0308_0304", + "022B", "006F_0308_0304", + "022C", "004F_0303_0304", + "022D", "006F_0303_0304", + "022E", "004F_0307", + "022F", "006F_0307", + "0230", "004F_0307_0304", + "0231", "006F_0307_0304", + "0232", "0059_0304", + "0233", "0079_0304", + "0340", "0300", + "0341", "0301", + "0343", "0313", + "0344", "0308_0301", + "0374", "02B9", + "037E", "003B", + "0385", "00A8_0301", + "0386", "0391_0301", + "0387", "00B7", + "0388", "0395_0301", + "0389", "0397_0301", + "038A", "0399_0301", + "038C", "039F_0301", + "038E", "03A5_0301", + "038F", "03A9_0301", + "0390", "03B9_0308_0301", + "03AA", "0399_0308", + "03AB", "03A5_0308", + "03AC", "03B1_0301", + "03AD", "03B5_0301", + "03AE", "03B7_0301", + "03AF", "03B9_0301", + "03B0", "03C5_0308_0301", + "03CA", "03B9_0308", + "03CB", "03C5_0308", + "03CC", "03BF_0301", + "03CD", "03C5_0301", + "03CE", "03C9_0301", + "03D3", "03D2_0301", + "03D4", "03D2_0308", + "0400", "0415_0300", + "0401", "0415_0308", + "0403", "0413_0301", + "0407", "0406_0308", + "040C", "041A_0301", + "040D", "0418_0300", + "040E", "0423_0306", + "0419", "0418_0306", + "0439", "0438_0306", + "0450", "0435_0300", + "0451", "0435_0308", + "0453", "0433_0301", + "0457", "0456_0308", + "045C", "043A_0301", + "045D", "0438_0300", + "045E", "0443_0306", + "0476", "0474_030F", + "0477", "0475_030F", + "04C1", "0416_0306", + "04C2", "0436_0306", + "04D0", "0410_0306", + "04D1", "0430_0306", + "04D2", "0410_0308", + "04D3", "0430_0308", + "04D6", "0415_0306", + "04D7", "0435_0306", + "04DA", "04D8_0308", + "04DB", "04D9_0308", + "04DC", "0416_0308", + "04DD", "0436_0308", + "04DE", "0417_0308", + "04DF", "0437_0308", + "04E2", "0418_0304", + "04E3", "0438_0304", + "04E4", "0418_0308", + "04E5", "0438_0308", + "04E6", "041E_0308", + "04E7", "043E_0308", + "04EA", "04E8_0308", + "04EB", "04E9_0308", + "04EC", "042D_0308", + "04ED", "044D_0308", + "04EE", "0423_0304", + "04EF", "0443_0304", + "04F0", "0423_0308", + "04F1", "0443_0308", + "04F2", "0423_030B", + "04F3", "0443_030B", + "04F4", "0427_0308", + "04F5", "0447_0308", + "04F8", "042B_0308", + "04F9", "044B_0308", + "0622", "0627_0653", + "0623", "0627_0654", + "0624", "0648_0654", + "0625", "0627_0655", + "0626", "064A_0654", + "06C0", "06D5_0654", + "06C2", "06C1_0654", + "06D3", "06D2_0654", + "0929", "0928_093C", + "0931", "0930_093C", + "0934", "0933_093C", + "0958", "0915_093C", + "0959", "0916_093C", + "095A", "0917_093C", + "095B", "091C_093C", + "095C", "0921_093C", + "095D", "0922_093C", + "095E", "092B_093C", + "095F", "092F_093C", + "09CB", "09C7_09BE", + "09CC", "09C7_09D7", + "09DC", "09A1_09BC", + "09DD", "09A2_09BC", + "09DF", "09AF_09BC", + "0A33", "0A32_0A3C", + "0A36", "0A38_0A3C", + "0A59", "0A16_0A3C", + "0A5A", "0A17_0A3C", + "0A5B", "0A1C_0A3C", + "0A5E", "0A2B_0A3C", + "0B48", "0B47_0B56", + "0B4B", "0B47_0B3E", + "0B4C", "0B47_0B57", + "0B5C", "0B21_0B3C", + "0B5D", "0B22_0B3C", + "0B94", "0B92_0BD7", + "0BCA", "0BC6_0BBE", + "0BCB", "0BC7_0BBE", + "0BCC", "0BC6_0BD7", + "0C48", "0C46_0C56", + "0CC0", "0CBF_0CD5", + "0CC7", "0CC6_0CD5", + "0CC8", "0CC6_0CD6", + "0CCA", "0CC6_0CC2", + "0CCB", "0CC6_0CC2_0CD5", + "0D4A", "0D46_0D3E", + "0D4B", "0D47_0D3E", + "0D4C", "0D46_0D57", + "0DDA", "0DD9_0DCA", + "0DDC", "0DD9_0DCF", + "0DDD", "0DD9_0DCF_0DCA", + "0DDE", "0DD9_0DDF", + "0F43", "0F42_0FB7", + "0F4D", "0F4C_0FB7", + "0F52", "0F51_0FB7", + "0F57", "0F56_0FB7", + "0F5C", "0F5B_0FB7", + "0F69", "0F40_0FB5", + "0F73", "0F71_0F72", + "0F75", "0F71_0F74", + "0F76", "0FB2_0F80", + "0F78", "0FB3_0F80", + "0F81", "0F71_0F80", + "0F93", "0F92_0FB7", + "0F9D", "0F9C_0FB7", + "0FA2", "0FA1_0FB7", + "0FA7", "0FA6_0FB7", + "0FAC", "0FAB_0FB7", + "0FB9", "0F90_0FB5", + "1026", "1025_102E", + "1B06", "1B05_1B35", + "1B08", "1B07_1B35", + "1B0A", "1B09_1B35", + "1B0C", "1B0B_1B35", + "1B0E", "1B0D_1B35", + "1B12", "1B11_1B35", + "1B3B", "1B3A_1B35", + "1B3D", "1B3C_1B35", + "1B40", "1B3E_1B35", + "1B41", "1B3F_1B35", + "1B43", "1B42_1B35", + "1E00", "0041_0325", + "1E01", "0061_0325", + "1E02", "0042_0307", + "1E03", "0062_0307", + "1E04", "0042_0323", + "1E05", "0062_0323", + "1E06", "0042_0331", + "1E07", "0062_0331", + "1E08", "0043_0327_0301", + "1E09", "0063_0327_0301", + "1E0A", "0044_0307", + "1E0B", "0064_0307", + "1E0C", "0044_0323", + "1E0D", "0064_0323", + "1E0E", "0044_0331", + "1E0F", "0064_0331", + "1E10", "0044_0327", + "1E11", "0064_0327", + "1E12", "0044_032D", + "1E13", "0064_032D", + "1E14", "0045_0304_0300", + "1E15", "0065_0304_0300", + "1E16", "0045_0304_0301", + "1E17", "0065_0304_0301", + "1E18", "0045_032D", + "1E19", "0065_032D", + "1E1A", "0045_0330", + "1E1B", "0065_0330", + "1E1C", "0045_0327_0306", + "1E1D", "0065_0327_0306", + "1E1E", "0046_0307", + "1E1F", "0066_0307", + "1E20", "0047_0304", + "1E21", "0067_0304", + "1E22", "0048_0307", + "1E23", "0068_0307", + "1E24", "0048_0323", + "1E25", "0068_0323", + "1E26", "0048_0308", + "1E27", "0068_0308", + "1E28", "0048_0327", + "1E29", "0068_0327", + "1E2A", "0048_032E", + "1E2B", "0068_032E", + "1E2C", "0049_0330", + "1E2D", "0069_0330", + "1E2E", "0049_0308_0301", + "1E2F", "0069_0308_0301", + "1E30", "004B_0301", + "1E31", "006B_0301", + "1E32", "004B_0323", + "1E33", "006B_0323", + "1E34", "004B_0331", + "1E35", "006B_0331", + "1E36", "004C_0323", + "1E37", "006C_0323", + "1E38", "004C_0323_0304", + "1E39", "006C_0323_0304", + "1E3A", "004C_0331", + "1E3B", "006C_0331", + "1E3C", "004C_032D", + "1E3D", "006C_032D", + "1E3E", "004D_0301", + "1E3F", "006D_0301", + "1E40", "004D_0307", + "1E41", "006D_0307", + "1E42", "004D_0323", + "1E43", "006D_0323", + "1E44", "004E_0307", + "1E45", "006E_0307", + "1E46", "004E_0323", + "1E47", "006E_0323", + "1E48", "004E_0331", + "1E49", "006E_0331", + "1E4A", "004E_032D", + "1E4B", "006E_032D", + "1E4C", "004F_0303_0301", + "1E4D", "006F_0303_0301", + "1E4E", "004F_0303_0308", + "1E4F", "006F_0303_0308", + "1E50", "004F_0304_0300", + "1E51", "006F_0304_0300", + "1E52", "004F_0304_0301", + "1E53", "006F_0304_0301", + "1E54", "0050_0301", + "1E55", "0070_0301", + "1E56", "0050_0307", + "1E57", "0070_0307", + "1E58", "0052_0307", + "1E59", "0072_0307", + "1E5A", "0052_0323", + "1E5B", "0072_0323", + "1E5C", "0052_0323_0304", + "1E5D", "0072_0323_0304", + "1E5E", "0052_0331", + "1E5F", "0072_0331", + "1E60", "0053_0307", + "1E61", "0073_0307", + "1E62", "0053_0323", + "1E63", "0073_0323", + "1E64", "0053_0301_0307", + "1E65", "0073_0301_0307", + "1E66", "0053_030C_0307", + "1E67", "0073_030C_0307", + "1E68", "0053_0323_0307", + "1E69", "0073_0323_0307", + "1E6A", "0054_0307", + "1E6B", "0074_0307", + "1E6C", "0054_0323", + "1E6D", "0074_0323", + "1E6E", "0054_0331", + "1E6F", "0074_0331", + "1E70", "0054_032D", + "1E71", "0074_032D", + "1E72", "0055_0324", + "1E73", "0075_0324", + "1E74", "0055_0330", + "1E75", "0075_0330", + "1E76", "0055_032D", + "1E77", "0075_032D", + "1E78", "0055_0303_0301", + "1E79", "0075_0303_0301", + "1E7A", "0055_0304_0308", + "1E7B", "0075_0304_0308", + "1E7C", "0056_0303", + "1E7D", "0076_0303", + "1E7E", "0056_0323", + "1E7F", "0076_0323", + "1E80", "0057_0300", + "1E81", "0077_0300", + "1E82", "0057_0301", + "1E83", "0077_0301", + "1E84", "0057_0308", + "1E85", "0077_0308", + "1E86", "0057_0307", + "1E87", "0077_0307", + "1E88", "0057_0323", + "1E89", "0077_0323", + "1E8A", "0058_0307", + "1E8B", "0078_0307", + "1E8C", "0058_0308", + "1E8D", "0078_0308", + "1E8E", "0059_0307", + "1E8F", "0079_0307", + "1E90", "005A_0302", + "1E91", "007A_0302", + "1E92", "005A_0323", + "1E93", "007A_0323", + "1E94", "005A_0331", + "1E95", "007A_0331", + "1E96", "0068_0331", + "1E97", "0074_0308", + "1E98", "0077_030A", + "1E99", "0079_030A", + "1E9B", "017F_0307", + "1EA0", "0041_0323", + "1EA1", "0061_0323", + "1EA2", "0041_0309", + "1EA3", "0061_0309", + "1EA4", "0041_0302_0301", + "1EA5", "0061_0302_0301", + "1EA6", "0041_0302_0300", + "1EA7", "0061_0302_0300", + "1EA8", "0041_0302_0309", + "1EA9", "0061_0302_0309", + "1EAA", "0041_0302_0303", + "1EAB", "0061_0302_0303", + "1EAC", "0041_0323_0302", + "1EAD", "0061_0323_0302", + "1EAE", "0041_0306_0301", + "1EAF", "0061_0306_0301", + "1EB0", "0041_0306_0300", + "1EB1", "0061_0306_0300", + "1EB2", "0041_0306_0309", + "1EB3", "0061_0306_0309", + "1EB4", "0041_0306_0303", + "1EB5", "0061_0306_0303", + "1EB6", "0041_0323_0306", + "1EB7", "0061_0323_0306", + "1EB8", "0045_0323", + "1EB9", "0065_0323", + "1EBA", "0045_0309", + "1EBB", "0065_0309", + "1EBC", "0045_0303", + "1EBD", "0065_0303", + "1EBE", "0045_0302_0301", + "1EBF", "0065_0302_0301", + "1EC0", "0045_0302_0300", + "1EC1", "0065_0302_0300", + "1EC2", "0045_0302_0309", + "1EC3", "0065_0302_0309", + "1EC4", "0045_0302_0303", + "1EC5", "0065_0302_0303", + "1EC6", "0045_0323_0302", + "1EC7", "0065_0323_0302", + "1EC8", "0049_0309", + "1EC9", "0069_0309", + "1ECA", "0049_0323", + "1ECB", "0069_0323", + "1ECC", "004F_0323", + "1ECD", "006F_0323", + "1ECE", "004F_0309", + "1ECF", "006F_0309", + "1ED0", "004F_0302_0301", + "1ED1", "006F_0302_0301", + "1ED2", "004F_0302_0300", + "1ED3", "006F_0302_0300", + "1ED4", "004F_0302_0309", + "1ED5", "006F_0302_0309", + "1ED6", "004F_0302_0303", + "1ED7", "006F_0302_0303", + "1ED8", "004F_0323_0302", + "1ED9", "006F_0323_0302", + "1EDA", "004F_031B_0301", + "1EDB", "006F_031B_0301", + "1EDC", "004F_031B_0300", + "1EDD", "006F_031B_0300", + "1EDE", "004F_031B_0309", + "1EDF", "006F_031B_0309", + "1EE0", "004F_031B_0303", + "1EE1", "006F_031B_0303", + "1EE2", "004F_031B_0323", + "1EE3", "006F_031B_0323", + "1EE4", "0055_0323", + "1EE5", "0075_0323", + "1EE6", "0055_0309", + "1EE7", "0075_0309", + "1EE8", "0055_031B_0301", + "1EE9", "0075_031B_0301", + "1EEA", "0055_031B_0300", + "1EEB", "0075_031B_0300", + "1EEC", "0055_031B_0309", + "1EED", "0075_031B_0309", + "1EEE", "0055_031B_0303", + "1EEF", "0075_031B_0303", + "1EF0", "0055_031B_0323", + "1EF1", "0075_031B_0323", + "1EF2", "0059_0300", + "1EF3", "0079_0300", + "1EF4", "0059_0323", + "1EF5", "0079_0323", + "1EF6", "0059_0309", + "1EF7", "0079_0309", + "1EF8", "0059_0303", + "1EF9", "0079_0303", + "1F00", "03B1_0313", + "1F01", "03B1_0314", + "1F02", "03B1_0313_0300", + "1F03", "03B1_0314_0300", + "1F04", "03B1_0313_0301", + "1F05", "03B1_0314_0301", + "1F06", "03B1_0313_0342", + "1F07", "03B1_0314_0342", + "1F08", "0391_0313", + "1F09", "0391_0314", + "1F0A", "0391_0313_0300", + "1F0B", "0391_0314_0300", + "1F0C", "0391_0313_0301", + "1F0D", "0391_0314_0301", + "1F0E", "0391_0313_0342", + "1F0F", "0391_0314_0342", + "1F10", "03B5_0313", + "1F11", "03B5_0314", + "1F12", "03B5_0313_0300", + "1F13", "03B5_0314_0300", + "1F14", "03B5_0313_0301", + "1F15", "03B5_0314_0301", + "1F18", "0395_0313", + "1F19", "0395_0314", + "1F1A", "0395_0313_0300", + "1F1B", "0395_0314_0300", + "1F1C", "0395_0313_0301", + "1F1D", "0395_0314_0301", + "1F20", "03B7_0313", + "1F21", "03B7_0314", + "1F22", "03B7_0313_0300", + "1F23", "03B7_0314_0300", + "1F24", "03B7_0313_0301", + "1F25", "03B7_0314_0301", + "1F26", "03B7_0313_0342", + "1F27", "03B7_0314_0342", + "1F28", "0397_0313", + "1F29", "0397_0314", + "1F2A", "0397_0313_0300", + "1F2B", "0397_0314_0300", + "1F2C", "0397_0313_0301", + "1F2D", "0397_0314_0301", + "1F2E", "0397_0313_0342", + "1F2F", "0397_0314_0342", + "1F30", "03B9_0313", + "1F31", "03B9_0314", + "1F32", "03B9_0313_0300", + "1F33", "03B9_0314_0300", + "1F34", "03B9_0313_0301", + "1F35", "03B9_0314_0301", + "1F36", "03B9_0313_0342", + "1F37", "03B9_0314_0342", + "1F38", "0399_0313", + "1F39", "0399_0314", + "1F3A", "0399_0313_0300", + "1F3B", "0399_0314_0300", + "1F3C", "0399_0313_0301", + "1F3D", "0399_0314_0301", + "1F3E", "0399_0313_0342", + "1F3F", "0399_0314_0342", + "1F40", "03BF_0313", + "1F41", "03BF_0314", + "1F42", "03BF_0313_0300", + "1F43", "03BF_0314_0300", + "1F44", "03BF_0313_0301", + "1F45", "03BF_0314_0301", + "1F48", "039F_0313", + "1F49", "039F_0314", + "1F4A", "039F_0313_0300", + "1F4B", "039F_0314_0300", + "1F4C", "039F_0313_0301", + "1F4D", "039F_0314_0301", + "1F50", "03C5_0313", + "1F51", "03C5_0314", + "1F52", "03C5_0313_0300", + "1F53", "03C5_0314_0300", + "1F54", "03C5_0313_0301", + "1F55", "03C5_0314_0301", + "1F56", "03C5_0313_0342", + "1F57", "03C5_0314_0342", + "1F59", "03A5_0314", + "1F5B", "03A5_0314_0300", + "1F5D", "03A5_0314_0301", + "1F5F", "03A5_0314_0342", + "1F60", "03C9_0313", + "1F61", "03C9_0314", + "1F62", "03C9_0313_0300", + "1F63", "03C9_0314_0300", + "1F64", "03C9_0313_0301", + "1F65", "03C9_0314_0301", + "1F66", "03C9_0313_0342", + "1F67", "03C9_0314_0342", + "1F68", "03A9_0313", + "1F69", "03A9_0314", + "1F6A", "03A9_0313_0300", + "1F6B", "03A9_0314_0300", + "1F6C", "03A9_0313_0301", + "1F6D", "03A9_0314_0301", + "1F6E", "03A9_0313_0342", + "1F6F", "03A9_0314_0342", + "1F70", "03B1_0300", + "1F71", "03B1_0301", + "1F72", "03B5_0300", + "1F73", "03B5_0301", + "1F74", "03B7_0300", + "1F75", "03B7_0301", + "1F76", "03B9_0300", + "1F77", "03B9_0301", + "1F78", "03BF_0300", + "1F79", "03BF_0301", + "1F7A", "03C5_0300", + "1F7B", "03C5_0301", + "1F7C", "03C9_0300", + "1F7D", "03C9_0301", + "1F80", "03B1_0313_0345", + "1F81", "03B1_0314_0345", + "1F82", "03B1_0313_0300_0345", + "1F83", "03B1_0314_0300_0345", + "1F84", "03B1_0313_0301_0345", + "1F85", "03B1_0314_0301_0345", + "1F86", "03B1_0313_0342_0345", + "1F87", "03B1_0314_0342_0345", + "1F88", "0391_0313_0345", + "1F89", "0391_0314_0345", + "1F8A", "0391_0313_0300_0345", + "1F8B", "0391_0314_0300_0345", + "1F8C", "0391_0313_0301_0345", + "1F8D", "0391_0314_0301_0345", + "1F8E", "0391_0313_0342_0345", + "1F8F", "0391_0314_0342_0345", + "1F90", "03B7_0313_0345", + "1F91", "03B7_0314_0345", + "1F92", "03B7_0313_0300_0345", + "1F93", "03B7_0314_0300_0345", + "1F94", "03B7_0313_0301_0345", + "1F95", "03B7_0314_0301_0345", + "1F96", "03B7_0313_0342_0345", + "1F97", "03B7_0314_0342_0345", + "1F98", "0397_0313_0345", + "1F99", "0397_0314_0345", + "1F9A", "0397_0313_0300_0345", + "1F9B", "0397_0314_0300_0345", + "1F9C", "0397_0313_0301_0345", + "1F9D", "0397_0314_0301_0345", + "1F9E", "0397_0313_0342_0345", + "1F9F", "0397_0314_0342_0345", + "1FA0", "03C9_0313_0345", + "1FA1", "03C9_0314_0345", + "1FA2", "03C9_0313_0300_0345", + "1FA3", "03C9_0314_0300_0345", + "1FA4", "03C9_0313_0301_0345", + "1FA5", "03C9_0314_0301_0345", + "1FA6", "03C9_0313_0342_0345", + "1FA7", "03C9_0314_0342_0345", + "1FA8", "03A9_0313_0345", + "1FA9", "03A9_0314_0345", + "1FAA", "03A9_0313_0300_0345", + "1FAB", "03A9_0314_0300_0345", + "1FAC", "03A9_0313_0301_0345", + "1FAD", "03A9_0314_0301_0345", + "1FAE", "03A9_0313_0342_0345", + "1FAF", "03A9_0314_0342_0345", + "1FB0", "03B1_0306", + "1FB1", "03B1_0304", + "1FB2", "03B1_0300_0345", + "1FB3", "03B1_0345", + "1FB4", "03B1_0301_0345", + "1FB6", "03B1_0342", + "1FB7", "03B1_0342_0345", + "1FB8", "0391_0306", + "1FB9", "0391_0304", + "1FBA", "0391_0300", + "1FBB", "0391_0301", + "1FBC", "0391_0345", + "1FBE", "03B9", + "1FC1", "00A8_0342", + "1FC2", "03B7_0300_0345", + "1FC3", "03B7_0345", + "1FC4", "03B7_0301_0345", + "1FC6", "03B7_0342", + "1FC7", "03B7_0342_0345", + "1FC8", "0395_0300", + "1FC9", "0395_0301", + "1FCA", "0397_0300", + "1FCB", "0397_0301", + "1FCC", "0397_0345", + "1FCD", "1FBF_0300", + "1FCE", "1FBF_0301", + "1FCF", "1FBF_0342", + "1FD0", "03B9_0306", + "1FD1", "03B9_0304", + "1FD2", "03B9_0308_0300", + "1FD3", "03B9_0308_0301", + "1FD6", "03B9_0342", + "1FD7", "03B9_0308_0342", + "1FD8", "0399_0306", + "1FD9", "0399_0304", + "1FDA", "0399_0300", + "1FDB", "0399_0301", + "1FDD", "1FFE_0300", + "1FDE", "1FFE_0301", + "1FDF", "1FFE_0342", + "1FE0", "03C5_0306", + "1FE1", "03C5_0304", + "1FE2", "03C5_0308_0300", + "1FE3", "03C5_0308_0301", + "1FE4", "03C1_0313", + "1FE5", "03C1_0314", + "1FE6", "03C5_0342", + "1FE7", "03C5_0308_0342", + "1FE8", "03A5_0306", + "1FE9", "03A5_0304", + "1FEA", "03A5_0300", + "1FEB", "03A5_0301", + "1FEC", "03A1_0314", + "1FED", "00A8_0300", + "1FEE", "00A8_0301", + "1FEF", "0060", + "1FF2", "03C9_0300_0345", + "1FF3", "03C9_0345", + "1FF4", "03C9_0301_0345", + "1FF6", "03C9_0342", + "1FF7", "03C9_0342_0345", + "1FF8", "039F_0300", + "1FF9", "039F_0301", + "1FFA", "03A9_0300", + "1FFB", "03A9_0301", + "1FFC", "03A9_0345", + "1FFD", "00B4", + "2000", "2002", + "2001", "2003", + "2126", "03A9", + "212A", "004B", + "212B", "0041_030A", + "219A", "2190_0338", + "219B", "2192_0338", + "21AE", "2194_0338", + "21CD", "21D0_0338", + "21CE", "21D4_0338", + "21CF", "21D2_0338", + "2204", "2203_0338", + "2209", "2208_0338", + "220C", "220B_0338", + "2224", "2223_0338", + "2226", "2225_0338", + "2241", "223C_0338", + "2244", "2243_0338", + "2247", "2245_0338", + "2249", "2248_0338", + "2260", "003D_0338", + "2262", "2261_0338", + "226D", "224D_0338", + "226E", "003C_0338", + "226F", "003E_0338", + "2270", "2264_0338", + "2271", "2265_0338", + "2274", "2272_0338", + "2275", "2273_0338", + "2278", "2276_0338", + "2279", "2277_0338", + "2280", "227A_0338", + "2281", "227B_0338", + "2284", "2282_0338", + "2285", "2283_0338", + "2288", "2286_0338", + "2289", "2287_0338", + "22AC", "22A2_0338", + "22AD", "22A8_0338", + "22AE", "22A9_0338", + "22AF", "22AB_0338", + "22E0", "227C_0338", + "22E1", "227D_0338", + "22E2", "2291_0338", + "22E3", "2292_0338", + "22EA", "22B2_0338", + "22EB", "22B3_0338", + "22EC", "22B4_0338", + "22ED", "22B5_0338", + "2329", "3008", + "232A", "3009", + "2ADC", "2ADD_0338", + "304C", "304B_3099", + "304E", "304D_3099", + "3050", "304F_3099", + "3052", "3051_3099", + "3054", "3053_3099", + "3056", "3055_3099", + "3058", "3057_3099", + "305A", "3059_3099", + "305C", "305B_3099", + "305E", "305D_3099", + "3060", "305F_3099", + "3062", "3061_3099", + "3065", "3064_3099", + "3067", "3066_3099", + "3069", "3068_3099", + "3070", "306F_3099", + "3071", "306F_309A", + "3073", "3072_3099", + "3074", "3072_309A", + "3076", "3075_3099", + "3077", "3075_309A", + "3079", "3078_3099", + "307A", "3078_309A", + "307C", "307B_3099", + "307D", "307B_309A", + "3094", "3046_3099", + "309E", "309D_3099", + "30AC", "30AB_3099", + "30AE", "30AD_3099", + "30B0", "30AF_3099", + "30B2", "30B1_3099", + "30B4", "30B3_3099", + "30B6", "30B5_3099", + "30B8", "30B7_3099", + "30BA", "30B9_3099", + "30BC", "30BB_3099", + "30BE", "30BD_3099", + "30C0", "30BF_3099", + "30C2", "30C1_3099", + "30C5", "30C4_3099", + "30C7", "30C6_3099", + "30C9", "30C8_3099", + "30D0", "30CF_3099", + "30D1", "30CF_309A", + "30D3", "30D2_3099", + "30D4", "30D2_309A", + "30D6", "30D5_3099", + "30D7", "30D5_309A", + "30D9", "30D8_3099", + "30DA", "30D8_309A", + "30DC", "30DB_3099", + "30DD", "30DB_309A", + "30F4", "30A6_3099", + "30F7", "30EF_3099", + "30F8", "30F0_3099", + "30F9", "30F1_3099", + "30FA", "30F2_3099", + "30FE", "30FD_3099", + "F900", "8C48", + "F901", "66F4", + "F902", "8ECA", + "F903", "8CC8", + "F904", "6ED1", + "F905", "4E32", + "F906", "53E5", + "F907", "9F9C", + "F908", "9F9C", + "F909", "5951", + "F90A", "91D1", + "F90B", "5587", + "F90C", "5948", + "F90D", "61F6", + "F90E", "7669", + "F90F", "7F85", + "F910", "863F", + "F911", "87BA", + "F912", "88F8", + "F913", "908F", + "F914", "6A02", + "F915", "6D1B", + "F916", "70D9", + "F917", "73DE", + "F918", "843D", + "F919", "916A", + "F91A", "99F1", + "F91B", "4E82", + "F91C", "5375", + "F91D", "6B04", + "F91E", "721B", + "F91F", "862D", + "F920", "9E1E", + "F921", "5D50", + "F922", "6FEB", + "F923", "85CD", + "F924", "8964", + "F925", "62C9", + "F926", "81D8", + "F927", "881F", + "F928", "5ECA", + "F929", "6717", + "F92A", "6D6A", + "F92B", "72FC", + "F92C", "90CE", + "F92D", "4F86", + "F92E", "51B7", + "F92F", "52DE", + "F930", "64C4", + "F931", "6AD3", + "F932", "7210", + "F933", "76E7", + "F934", "8001", + "F935", "8606", + "F936", "865C", + "F937", "8DEF", + "F938", "9732", + "F939", "9B6F", + "F93A", "9DFA", + "F93B", "788C", + "F93C", "797F", + "F93D", "7DA0", + "F93E", "83C9", + "F93F", "9304", + "F940", "9E7F", + "F941", "8AD6", + "F942", "58DF", + "F943", "5F04", + "F944", "7C60", + "F945", "807E", + "F946", "7262", + "F947", "78CA", + "F948", "8CC2", + "F949", "96F7", + "F94A", "58D8", + "F94B", "5C62", + "F94C", "6A13", + "F94D", "6DDA", + "F94E", "6F0F", + "F94F", "7D2F", + "F950", "7E37", + "F951", "964B", + "F952", "52D2", + "F953", "808B", + "F954", "51DC", + "F955", "51CC", + "F956", "7A1C", + "F957", "7DBE", + "F958", "83F1", + "F959", "9675", + "F95A", "8B80", + "F95B", "62CF", + "F95C", "6A02", + "F95D", "8AFE", + "F95E", "4E39", + "F95F", "5BE7", + "F960", "6012", + "F961", "7387", + "F962", "7570", + "F963", "5317", + "F964", "78FB", + "F965", "4FBF", + "F966", "5FA9", + "F967", "4E0D", + "F968", "6CCC", + "F969", "6578", + "F96A", "7D22", + "F96B", "53C3", + "F96C", "585E", + "F96D", "7701", + "F96E", "8449", + "F96F", "8AAA", + "F970", "6BBA", + "F971", "8FB0", + "F972", "6C88", + "F973", "62FE", + "F974", "82E5", + "F975", "63A0", + "F976", "7565", + "F977", "4EAE", + "F978", "5169", + "F979", "51C9", + "F97A", "6881", + "F97B", "7CE7", + "F97C", "826F", + "F97D", "8AD2", + "F97E", "91CF", + "F97F", "52F5", + "F980", "5442", + "F981", "5973", + "F982", "5EEC", + "F983", "65C5", + "F984", "6FFE", + "F985", "792A", + "F986", "95AD", + "F987", "9A6A", + "F988", "9E97", + "F989", "9ECE", + "F98A", "529B", + "F98B", "66C6", + "F98C", "6B77", + "F98D", "8F62", + "F98E", "5E74", + "F98F", "6190", + "F990", "6200", + "F991", "649A", + "F992", "6F23", + "F993", "7149", + "F994", "7489", + "F995", "79CA", + "F996", "7DF4", + "F997", "806F", + "F998", "8F26", + "F999", "84EE", + "F99A", "9023", + "F99B", "934A", + "F99C", "5217", + "F99D", "52A3", + "F99E", "54BD", + "F99F", "70C8", + "F9A0", "88C2", + "F9A1", "8AAA", + "F9A2", "5EC9", + "F9A3", "5FF5", + "F9A4", "637B", + "F9A5", "6BAE", + "F9A6", "7C3E", + "F9A7", "7375", + "F9A8", "4EE4", + "F9A9", "56F9", + "F9AA", "5BE7", + "F9AB", "5DBA", + "F9AC", "601C", + "F9AD", "73B2", + "F9AE", "7469", + "F9AF", "7F9A", + "F9B0", "8046", + "F9B1", "9234", + "F9B2", "96F6", + "F9B3", "9748", + "F9B4", "9818", + "F9B5", "4F8B", + "F9B6", "79AE", + "F9B7", "91B4", + "F9B8", "96B8", + "F9B9", "60E1", + "F9BA", "4E86", + "F9BB", "50DA", + "F9BC", "5BEE", + "F9BD", "5C3F", + "F9BE", "6599", + "F9BF", "6A02", + "F9C0", "71CE", + "F9C1", "7642", + "F9C2", "84FC", + "F9C3", "907C", + "F9C4", "9F8D", + "F9C5", "6688", + "F9C6", "962E", + "F9C7", "5289", + "F9C8", "677B", + "F9C9", "67F3", + "F9CA", "6D41", + "F9CB", "6E9C", + "F9CC", "7409", + "F9CD", "7559", + "F9CE", "786B", + "F9CF", "7D10", + "F9D0", "985E", + "F9D1", "516D", + "F9D2", "622E", + "F9D3", "9678", + "F9D4", "502B", + "F9D5", "5D19", + "F9D6", "6DEA", + "F9D7", "8F2A", + "F9D8", "5F8B", + "F9D9", "6144", + "F9DA", "6817", + "F9DB", "7387", + "F9DC", "9686", + "F9DD", "5229", + "F9DE", "540F", + "F9DF", "5C65", + "F9E0", "6613", + "F9E1", "674E", + "F9E2", "68A8", + "F9E3", "6CE5", + "F9E4", "7406", + "F9E5", "75E2", + "F9E6", "7F79", + "F9E7", "88CF", + "F9E8", "88E1", + "F9E9", "91CC", + "F9EA", "96E2", + "F9EB", "533F", + "F9EC", "6EBA", + "F9ED", "541D", + "F9EE", "71D0", + "F9EF", "7498", + "F9F0", "85FA", + "F9F1", "96A3", + "F9F2", "9C57", + "F9F3", "9E9F", + "F9F4", "6797", + "F9F5", "6DCB", + "F9F6", "81E8", + "F9F7", "7ACB", + "F9F8", "7B20", + "F9F9", "7C92", + "F9FA", "72C0", + "F9FB", "7099", + "F9FC", "8B58", + "F9FD", "4EC0", + "F9FE", "8336", + "F9FF", "523A", + "FA00", "5207", + "FA01", "5EA6", + "FA02", "62D3", + "FA03", "7CD6", + "FA04", "5B85", + "FA05", "6D1E", + "FA06", "66B4", + "FA07", "8F3B", + "FA08", "884C", + "FA09", "964D", + "FA0A", "898B", + "FA0B", "5ED3", + "FA0C", "5140", + "FA0D", "55C0", + "FA10", "585A", + "FA12", "6674", + "FA15", "51DE", + "FA16", "732A", + "FA17", "76CA", + "FA18", "793C", + "FA19", "795E", + "FA1A", "7965", + "FA1B", "798F", + "FA1C", "9756", + "FA1D", "7CBE", + "FA1E", "7FBD", + "FA20", "8612", + "FA22", "8AF8", + "FA25", "9038", + "FA26", "90FD", + "FA2A", "98EF", + "FA2B", "98FC", + "FA2C", "9928", + "FA2D", "9DB4", + "FA2E", "90DE", + "FA2F", "96B7", + "FA30", "4FAE", + "FA31", "50E7", + "FA32", "514D", + "FA33", "52C9", + "FA34", "52E4", + "FA35", "5351", + "FA36", "559D", + "FA37", "5606", + "FA38", "5668", + "FA39", "5840", + "FA3A", "58A8", + "FA3B", "5C64", + "FA3C", "5C6E", + "FA3D", "6094", + "FA3E", "6168", + "FA3F", "618E", + "FA40", "61F2", + "FA41", "654F", + "FA42", "65E2", + "FA43", "6691", + "FA44", "6885", + "FA45", "6D77", + "FA46", "6E1A", + "FA47", "6F22", + "FA48", "716E", + "FA49", "722B", + "FA4A", "7422", + "FA4B", "7891", + "FA4C", "793E", + "FA4D", "7949", + "FA4E", "7948", + "FA4F", "7950", + "FA50", "7956", + "FA51", "795D", + "FA52", "798D", + "FA53", "798E", + "FA54", "7A40", + "FA55", "7A81", + "FA56", "7BC0", + "FA57", "7DF4", + "FA58", "7E09", + "FA59", "7E41", + "FA5A", "7F72", + "FA5B", "8005", + "FA5C", "81ED", + "FA5D", "8279", + "FA5E", "8279", + "FA5F", "8457", + "FA60", "8910", + "FA61", "8996", + "FA62", "8B01", + "FA63", "8B39", + "FA64", "8CD3", + "FA65", "8D08", + "FA66", "8FB6", + "FA67", "9038", + "FA68", "96E3", + "FA69", "97FF", + "FA6A", "983B", + "FA6B", "6075", + "FA6C", "242EE", + "FA6D", "8218", + "FA70", "4E26", + "FA71", "51B5", + "FA72", "5168", + "FA73", "4F80", + "FA74", "5145", + "FA75", "5180", + "FA76", "52C7", + "FA77", "52FA", + "FA78", "559D", + "FA79", "5555", + "FA7A", "5599", + "FA7B", "55E2", + "FA7C", "585A", + "FA7D", "58B3", + "FA7E", "5944", + "FA7F", "5954", + "FA80", "5A62", + "FA81", "5B28", + "FA82", "5ED2", + "FA83", "5ED9", + "FA84", "5F69", + "FA85", "5FAD", + "FA86", "60D8", + "FA87", "614E", + "FA88", "6108", + "FA89", "618E", + "FA8A", "6160", + "FA8B", "61F2", + "FA8C", "6234", + "FA8D", "63C4", + "FA8E", "641C", + "FA8F", "6452", + "FA90", "6556", + "FA91", "6674", + "FA92", "6717", + "FA93", "671B", + "FA94", "6756", + "FA95", "6B79", + "FA96", "6BBA", + "FA97", "6D41", + "FA98", "6EDB", + "FA99", "6ECB", + "FA9A", "6F22", + "FA9B", "701E", + "FA9C", "716E", + "FA9D", "77A7", + "FA9E", "7235", + "FA9F", "72AF", + "FAA0", "732A", + "FAA1", "7471", + "FAA2", "7506", + "FAA3", "753B", + "FAA4", "761D", + "FAA5", "761F", + "FAA6", "76CA", + "FAA7", "76DB", + "FAA8", "76F4", + "FAA9", "774A", + "FAAA", "7740", + "FAAB", "78CC", + "FAAC", "7AB1", + "FAAD", "7BC0", + "FAAE", "7C7B", + "FAAF", "7D5B", + "FAB0", "7DF4", + "FAB1", "7F3E", + "FAB2", "8005", + "FAB3", "8352", + "FAB4", "83EF", + "FAB5", "8779", + "FAB6", "8941", + "FAB7", "8986", + "FAB8", "8996", + "FAB9", "8ABF", + "FABA", "8AF8", + "FABB", "8ACB", + "FABC", "8B01", + "FABD", "8AFE", + "FABE", "8AED", + "FABF", "8B39", + "FAC0", "8B8A", + "FAC1", "8D08", + "FAC2", "8F38", + "FAC3", "9072", + "FAC4", "9199", + "FAC5", "9276", + "FAC6", "967C", + "FAC7", "96E3", + "FAC8", "9756", + "FAC9", "97DB", + "FACA", "97FF", + "FACB", "980B", + "FACC", "983B", + "FACD", "9B12", + "FACE", "9F9C", + "FACF", "2284A", + "FAD0", "22844", + "FAD1", "233D5", + "FAD2", "3B9D", + "FAD3", "4018", + "FAD4", "4039", + "FAD5", "25249", + "FAD6", "25CD0", + "FAD7", "27ED3", + "FAD8", "9F43", + "FAD9", "9F8E", + "FB1D", "05D9_05B4", + "FB1F", "05F2_05B7", + "FB2A", "05E9_05C1", + "FB2B", "05E9_05C2", + "FB2C", "05E9_05BC_05C1", + "FB2D", "05E9_05BC_05C2", + "FB2E", "05D0_05B7", + "FB2F", "05D0_05B8", + "FB30", "05D0_05BC", + "FB31", "05D1_05BC", + "FB32", "05D2_05BC", + "FB33", "05D3_05BC", + "FB34", "05D4_05BC", + "FB35", "05D5_05BC", + "FB36", "05D6_05BC", + "FB38", "05D8_05BC", + "FB39", "05D9_05BC", + "FB3A", "05DA_05BC", + "FB3B", "05DB_05BC", + "FB3C", "05DC_05BC", + "FB3E", "05DE_05BC", + "FB40", "05E0_05BC", + "FB41", "05E1_05BC", + "FB43", "05E3_05BC", + "FB44", "05E4_05BC", + "FB46", "05E6_05BC", + "FB47", "05E7_05BC", + "FB48", "05E8_05BC", + "FB49", "05E9_05BC", + "FB4A", "05EA_05BC", + "FB4B", "05D5_05B9", + "FB4C", "05D1_05BF", + "FB4D", "05DB_05BF", + "FB4E", "05E4_05BF", + "1109A", "11099_110BA", + "1109C", "1109B_110BA", + "110AB", "110A5_110BA", + "1112E", "11131_11127", + "1112F", "11132_11127", + "1134B", "11347_1133E", + "1134C", "11347_11357", + "114BB", "114B9_114BA", + "114BC", "114B9_114B0", + "114BE", "114B9_114BD", + "115BA", "115B8_115AF", + "115BB", "115B9_115AF", + "11938", "11935_11930", + "1D15E", "1D157_1D165", + "1D15F", "1D158_1D165", + "1D160", "1D158_1D165_1D16E", + "1D161", "1D158_1D165_1D16F", + "1D162", "1D158_1D165_1D170", + "1D163", "1D158_1D165_1D171", + "1D164", "1D158_1D165_1D172", + "1D1BB", "1D1B9_1D165", + "1D1BC", "1D1BA_1D165", + "1D1BD", "1D1B9_1D165_1D16E", + "1D1BE", "1D1BA_1D165_1D16E", + "1D1BF", "1D1B9_1D165_1D16F", + "1D1C0", "1D1BA_1D165_1D16F", + "2F800", "4E3D", + "2F801", "4E38", + "2F802", "4E41", + "2F803", "20122", + "2F804", "4F60", + "2F805", "4FAE", + "2F806", "4FBB", + "2F807", "5002", + "2F808", "507A", + "2F809", "5099", + "2F80A", "50E7", + "2F80B", "50CF", + "2F80C", "349E", + "2F80D", "2063A", + "2F80E", "514D", + "2F80F", "5154", + "2F810", "5164", + "2F811", "5177", + "2F812", "2051C", + "2F813", "34B9", + "2F814", "5167", + "2F815", "518D", + "2F816", "2054B", + "2F817", "5197", + "2F818", "51A4", + "2F819", "4ECC", + "2F81A", "51AC", + "2F81B", "51B5", + "2F81C", "291DF", + "2F81D", "51F5", + "2F81E", "5203", + "2F81F", "34DF", + "2F820", "523B", + "2F821", "5246", + "2F822", "5272", + "2F823", "5277", + "2F824", "3515", + "2F825", "52C7", + "2F826", "52C9", + "2F827", "52E4", + "2F828", "52FA", + "2F829", "5305", + "2F82A", "5306", + "2F82B", "5317", + "2F82C", "5349", + "2F82D", "5351", + "2F82E", "535A", + "2F82F", "5373", + "2F830", "537D", + "2F831", "537F", + "2F832", "537F", + "2F833", "537F", + "2F834", "20A2C", + "2F835", "7070", + "2F836", "53CA", + "2F837", "53DF", + "2F838", "20B63", + "2F839", "53EB", + "2F83A", "53F1", + "2F83B", "5406", + "2F83C", "549E", + "2F83D", "5438", + "2F83E", "5448", + "2F83F", "5468", + "2F840", "54A2", + "2F841", "54F6", + "2F842", "5510", + "2F843", "5553", + "2F844", "5563", + "2F845", "5584", + "2F846", "5584", + "2F847", "5599", + "2F848", "55AB", + "2F849", "55B3", + "2F84A", "55C2", + "2F84B", "5716", + "2F84C", "5606", + "2F84D", "5717", + "2F84E", "5651", + "2F84F", "5674", + "2F850", "5207", + "2F851", "58EE", + "2F852", "57CE", + "2F853", "57F4", + "2F854", "580D", + "2F855", "578B", + "2F856", "5832", + "2F857", "5831", + "2F858", "58AC", + "2F859", "214E4", + "2F85A", "58F2", + "2F85B", "58F7", + "2F85C", "5906", + "2F85D", "591A", + "2F85E", "5922", + "2F85F", "5962", + "2F860", "216A8", + "2F861", "216EA", + "2F862", "59EC", + "2F863", "5A1B", + "2F864", "5A27", + "2F865", "59D8", + "2F866", "5A66", + "2F867", "36EE", + "2F868", "36FC", + "2F869", "5B08", + "2F86A", "5B3E", + "2F86B", "5B3E", + "2F86C", "219C8", + "2F86D", "5BC3", + "2F86E", "5BD8", + "2F86F", "5BE7", + "2F870", "5BF3", + "2F871", "21B18", + "2F872", "5BFF", + "2F873", "5C06", + "2F874", "5F53", + "2F875", "5C22", + "2F876", "3781", + "2F877", "5C60", + "2F878", "5C6E", + "2F879", "5CC0", + "2F87A", "5C8D", + "2F87B", "21DE4", + "2F87C", "5D43", + "2F87D", "21DE6", + "2F87E", "5D6E", + "2F87F", "5D6B", + "2F880", "5D7C", + "2F881", "5DE1", + "2F882", "5DE2", + "2F883", "382F", + "2F884", "5DFD", + "2F885", "5E28", + "2F886", "5E3D", + "2F887", "5E69", + "2F888", "3862", + "2F889", "22183", + "2F88A", "387C", + "2F88B", "5EB0", + "2F88C", "5EB3", + "2F88D", "5EB6", + "2F88E", "5ECA", + "2F88F", "2A392", + "2F890", "5EFE", + "2F891", "22331", + "2F892", "22331", + "2F893", "8201", + "2F894", "5F22", + "2F895", "5F22", + "2F896", "38C7", + "2F897", "232B8", + "2F898", "261DA", + "2F899", "5F62", + "2F89A", "5F6B", + "2F89B", "38E3", + "2F89C", "5F9A", + "2F89D", "5FCD", + "2F89E", "5FD7", + "2F89F", "5FF9", + "2F8A0", "6081", + "2F8A1", "393A", + "2F8A2", "391C", + "2F8A3", "6094", + "2F8A4", "226D4", + "2F8A5", "60C7", + "2F8A6", "6148", + "2F8A7", "614C", + "2F8A8", "614E", + "2F8A9", "614C", + "2F8AA", "617A", + "2F8AB", "618E", + "2F8AC", "61B2", + "2F8AD", "61A4", + "2F8AE", "61AF", + "2F8AF", "61DE", + "2F8B0", "61F2", + "2F8B1", "61F6", + "2F8B2", "6210", + "2F8B3", "621B", + "2F8B4", "625D", + "2F8B5", "62B1", + "2F8B6", "62D4", + "2F8B7", "6350", + "2F8B8", "22B0C", + "2F8B9", "633D", + "2F8BA", "62FC", + "2F8BB", "6368", + "2F8BC", "6383", + "2F8BD", "63E4", + "2F8BE", "22BF1", + "2F8BF", "6422", + "2F8C0", "63C5", + "2F8C1", "63A9", + "2F8C2", "3A2E", + "2F8C3", "6469", + "2F8C4", "647E", + "2F8C5", "649D", + "2F8C6", "6477", + "2F8C7", "3A6C", + "2F8C8", "654F", + "2F8C9", "656C", + "2F8CA", "2300A", + "2F8CB", "65E3", + "2F8CC", "66F8", + "2F8CD", "6649", + "2F8CE", "3B19", + "2F8CF", "6691", + "2F8D0", "3B08", + "2F8D1", "3AE4", + "2F8D2", "5192", + "2F8D3", "5195", + "2F8D4", "6700", + "2F8D5", "669C", + "2F8D6", "80AD", + "2F8D7", "43D9", + "2F8D8", "6717", + "2F8D9", "671B", + "2F8DA", "6721", + "2F8DB", "675E", + "2F8DC", "6753", + "2F8DD", "233C3", + "2F8DE", "3B49", + "2F8DF", "67FA", + "2F8E0", "6785", + "2F8E1", "6852", + "2F8E2", "6885", + "2F8E3", "2346D", + "2F8E4", "688E", + "2F8E5", "681F", + "2F8E6", "6914", + "2F8E7", "3B9D", + "2F8E8", "6942", + "2F8E9", "69A3", + "2F8EA", "69EA", + "2F8EB", "6AA8", + "2F8EC", "236A3", + "2F8ED", "6ADB", + "2F8EE", "3C18", + "2F8EF", "6B21", + "2F8F0", "238A7", + "2F8F1", "6B54", + "2F8F2", "3C4E", + "2F8F3", "6B72", + "2F8F4", "6B9F", + "2F8F5", "6BBA", + "2F8F6", "6BBB", + "2F8F7", "23A8D", + "2F8F8", "21D0B", + "2F8F9", "23AFA", + "2F8FA", "6C4E", + "2F8FB", "23CBC", + "2F8FC", "6CBF", + "2F8FD", "6CCD", + "2F8FE", "6C67", + "2F8FF", "6D16", + "2F900", "6D3E", + "2F901", "6D77", + "2F902", "6D41", + "2F903", "6D69", + "2F904", "6D78", + "2F905", "6D85", + "2F906", "23D1E", + "2F907", "6D34", + "2F908", "6E2F", + "2F909", "6E6E", + "2F90A", "3D33", + "2F90B", "6ECB", + "2F90C", "6EC7", + "2F90D", "23ED1", + "2F90E", "6DF9", + "2F90F", "6F6E", + "2F910", "23F5E", + "2F911", "23F8E", + "2F912", "6FC6", + "2F913", "7039", + "2F914", "701E", + "2F915", "701B", + "2F916", "3D96", + "2F917", "704A", + "2F918", "707D", + "2F919", "7077", + "2F91A", "70AD", + "2F91B", "20525", + "2F91C", "7145", + "2F91D", "24263", + "2F91E", "719C", + "2F91F", "243AB", + "2F920", "7228", + "2F921", "7235", + "2F922", "7250", + "2F923", "24608", + "2F924", "7280", + "2F925", "7295", + "2F926", "24735", + "2F927", "24814", + "2F928", "737A", + "2F929", "738B", + "2F92A", "3EAC", + "2F92B", "73A5", + "2F92C", "3EB8", + "2F92D", "3EB8", + "2F92E", "7447", + "2F92F", "745C", + "2F930", "7471", + "2F931", "7485", + "2F932", "74CA", + "2F933", "3F1B", + "2F934", "7524", + "2F935", "24C36", + "2F936", "753E", + "2F937", "24C92", + "2F938", "7570", + "2F939", "2219F", + "2F93A", "7610", + "2F93B", "24FA1", + "2F93C", "24FB8", + "2F93D", "25044", + "2F93E", "3FFC", + "2F93F", "4008", + "2F940", "76F4", + "2F941", "250F3", + "2F942", "250F2", + "2F943", "25119", + "2F944", "25133", + "2F945", "771E", + "2F946", "771F", + "2F947", "771F", + "2F948", "774A", + "2F949", "4039", + "2F94A", "778B", + "2F94B", "4046", + "2F94C", "4096", + "2F94D", "2541D", + "2F94E", "784E", + "2F94F", "788C", + "2F950", "78CC", + "2F951", "40E3", + "2F952", "25626", + "2F953", "7956", + "2F954", "2569A", + "2F955", "256C5", + "2F956", "798F", + "2F957", "79EB", + "2F958", "412F", + "2F959", "7A40", + "2F95A", "7A4A", + "2F95B", "7A4F", + "2F95C", "2597C", + "2F95D", "25AA7", + "2F95E", "25AA7", + "2F95F", "7AEE", + "2F960", "4202", + "2F961", "25BAB", + "2F962", "7BC6", + "2F963", "7BC9", + "2F964", "4227", + "2F965", "25C80", + "2F966", "7CD2", + "2F967", "42A0", + "2F968", "7CE8", + "2F969", "7CE3", + "2F96A", "7D00", + "2F96B", "25F86", + "2F96C", "7D63", + "2F96D", "4301", + "2F96E", "7DC7", + "2F96F", "7E02", + "2F970", "7E45", + "2F971", "4334", + "2F972", "26228", + "2F973", "26247", + "2F974", "4359", + "2F975", "262D9", + "2F976", "7F7A", + "2F977", "2633E", + "2F978", "7F95", + "2F979", "7FFA", + "2F97A", "8005", + "2F97B", "264DA", + "2F97C", "26523", + "2F97D", "8060", + "2F97E", "265A8", + "2F97F", "8070", + "2F980", "2335F", + "2F981", "43D5", + "2F982", "80B2", + "2F983", "8103", + "2F984", "440B", + "2F985", "813E", + "2F986", "5AB5", + "2F987", "267A7", + "2F988", "267B5", + "2F989", "23393", + "2F98A", "2339C", + "2F98B", "8201", + "2F98C", "8204", + "2F98D", "8F9E", + "2F98E", "446B", + "2F98F", "8291", + "2F990", "828B", + "2F991", "829D", + "2F992", "52B3", + "2F993", "82B1", + "2F994", "82B3", + "2F995", "82BD", + "2F996", "82E6", + "2F997", "26B3C", + "2F998", "82E5", + "2F999", "831D", + "2F99A", "8363", + "2F99B", "83AD", + "2F99C", "8323", + "2F99D", "83BD", + "2F99E", "83E7", + "2F99F", "8457", + "2F9A0", "8353", + "2F9A1", "83CA", + "2F9A2", "83CC", + "2F9A3", "83DC", + "2F9A4", "26C36", + "2F9A5", "26D6B", + "2F9A6", "26CD5", + "2F9A7", "452B", + "2F9A8", "84F1", + "2F9A9", "84F3", + "2F9AA", "8516", + "2F9AB", "273CA", + "2F9AC", "8564", + "2F9AD", "26F2C", + "2F9AE", "455D", + "2F9AF", "4561", + "2F9B0", "26FB1", + "2F9B1", "270D2", + "2F9B2", "456B", + "2F9B3", "8650", + "2F9B4", "865C", + "2F9B5", "8667", + "2F9B6", "8669", + "2F9B7", "86A9", + "2F9B8", "8688", + "2F9B9", "870E", + "2F9BA", "86E2", + "2F9BB", "8779", + "2F9BC", "8728", + "2F9BD", "876B", + "2F9BE", "8786", + "2F9BF", "45D7", + "2F9C0", "87E1", + "2F9C1", "8801", + "2F9C2", "45F9", + "2F9C3", "8860", + "2F9C4", "8863", + "2F9C5", "27667", + "2F9C6", "88D7", + "2F9C7", "88DE", + "2F9C8", "4635", + "2F9C9", "88FA", + "2F9CA", "34BB", + "2F9CB", "278AE", + "2F9CC", "27966", + "2F9CD", "46BE", + "2F9CE", "46C7", + "2F9CF", "8AA0", + "2F9D0", "8AED", + "2F9D1", "8B8A", + "2F9D2", "8C55", + "2F9D3", "27CA8", + "2F9D4", "8CAB", + "2F9D5", "8CC1", + "2F9D6", "8D1B", + "2F9D7", "8D77", + "2F9D8", "27F2F", + "2F9D9", "20804", + "2F9DA", "8DCB", + "2F9DB", "8DBC", + "2F9DC", "8DF0", + "2F9DD", "208DE", + "2F9DE", "8ED4", + "2F9DF", "8F38", + "2F9E0", "285D2", + "2F9E1", "285ED", + "2F9E2", "9094", + "2F9E3", "90F1", + "2F9E4", "9111", + "2F9E5", "2872E", + "2F9E6", "911B", + "2F9E7", "9238", + "2F9E8", "92D7", + "2F9E9", "92D8", + "2F9EA", "927C", + "2F9EB", "93F9", + "2F9EC", "9415", + "2F9ED", "28BFA", + "2F9EE", "958B", + "2F9EF", "4995", + "2F9F0", "95B7", + "2F9F1", "28D77", + "2F9F2", "49E6", + "2F9F3", "96C3", + "2F9F4", "5DB2", + "2F9F5", "9723", + "2F9F6", "29145", + "2F9F7", "2921A", + "2F9F8", "4A6E", + "2F9F9", "4A76", + "2F9FA", "97E0", + "2F9FB", "2940A", + "2F9FC", "4AB2", + "2F9FD", "29496", + "2F9FE", "980B", + "2F9FF", "980B", + "2FA00", "9829", + "2FA01", "295B6", + "2FA02", "98E2", + "2FA03", "4B33", + "2FA04", "9929", + "2FA05", "99A7", + "2FA06", "99C2", + "2FA07", "99FE", + "2FA08", "4BCE", + "2FA09", "29B30", + "2FA0A", "9B12", + "2FA0B", "9C40", + "2FA0C", "9CFD", + "2FA0D", "4CCE", + "2FA0E", "4CED", + "2FA0F", "9D67", + "2FA10", "2A0CE", + "2FA11", "4CF8", + "2FA12", "2A105", + "2FA13", "2A20E", + "2FA14", "2A291", + "2FA15", "9EBB", + "2FA16", "4D56", + "2FA17", "9EF9", + "2FA18", "9EFE", + "2FA19", "9F05", + "2FA1A", "9F0F", + "2FA1B", "9F16", + "2FA1C", "9F3B", + "2FA1D", "2A600", +); + +# This table was algorithmically derived from the Adobe Glyph List (AGL) +# file 'glyphlist.txt' from the GitHub Adobe Type Tools agl-aglfn +# project, on 2022-10-09. +# +# See "groff:" comments for altered mappings. +my %AGL_to_unicode = ( + "A", "0041", + "AE", "00C6", + "AEacute", "01FC", + "AEmacron", "01E2", + "Aacute", "00C1", + "Abreve", "0102", + "Abreveacute", "1EAE", + "Abrevecyrillic", "04D0", + "Abrevedotbelow", "1EB6", + "Abrevegrave", "1EB0", + "Abrevehookabove", "1EB2", + "Abrevetilde", "1EB4", + "Acaron", "01CD", + "Acircle", "24B6", + "Acircumflex", "00C2", + "Acircumflexacute", "1EA4", + "Acircumflexdotbelow", "1EAC", + "Acircumflexgrave", "1EA6", + "Acircumflexhookabove", "1EA8", + "Acircumflextilde", "1EAA", + "Acyrillic", "0410", + "Adblgrave", "0200", + "Adieresis", "00C4", + "Adieresiscyrillic", "04D2", + "Adieresismacron", "01DE", + "Adotbelow", "1EA0", + "Adotmacron", "01E0", + "Agrave", "00C0", + "Ahookabove", "1EA2", + "Aiecyrillic", "04D4", + "Ainvertedbreve", "0202", + "Alpha", "0391", + "Alphatonos", "0386", + "Amacron", "0100", + "Amonospace", "FF21", + "Aogonek", "0104", + "Aring", "00C5", + "Aringacute", "01FA", + "Aringbelow", "1E00", + "Atilde", "00C3", + "Aybarmenian", "0531", + "B", "0042", + "Bcircle", "24B7", + "Bdotaccent", "1E02", + "Bdotbelow", "1E04", + "Becyrillic", "0411", + "Benarmenian", "0532", + "Beta", "0392", + "Bhook", "0181", + "Blinebelow", "1E06", + "Bmonospace", "FF22", + "Btopbar", "0182", + "C", "0043", + "Caarmenian", "053E", + "Cacute", "0106", + "Ccaron", "010C", + "Ccedilla", "00C7", + "Ccedillaacute", "1E08", + "Ccircle", "24B8", + "Ccircumflex", "0108", + "Cdot", "010A", + "Cdotaccent", "010A", + "Chaarmenian", "0549", + "Cheabkhasiancyrillic", "04BC", + "Checyrillic", "0427", + "Chedescenderabkhasiancyrillic", "04BE", + "Chedescendercyrillic", "04B6", + "Chedieresiscyrillic", "04F4", + "Cheharmenian", "0543", + "Chekhakassiancyrillic", "04CB", + "Cheverticalstrokecyrillic", "04B8", + "Chi", "03A7", + "Chook", "0187", + "Cmonospace", "FF23", + "Coarmenian", "0551", + "D", "0044", + "DZ", "01F1", + "DZcaron", "01C4", + "Daarmenian", "0534", + "Dafrican", "0189", + "Dcaron", "010E", + "Dcedilla", "1E10", + "Dcircle", "24B9", + "Dcircumflexbelow", "1E12", + "Dcroat", "0110", + "Ddotaccent", "1E0A", + "Ddotbelow", "1E0C", + "Decyrillic", "0414", + "Deicoptic", "03EE", + "Delta", "0394", # groff: not U+2206 + "Deltagreek", "0394", + "Dhook", "018A", + "Digammagreek", "03DC", + "Djecyrillic", "0402", + "Dlinebelow", "1E0E", + "Dmonospace", "FF24", + "Dslash", "0110", + "Dtopbar", "018B", + "Dz", "01F2", + "Dzcaron", "01C5", + "Dzeabkhasiancyrillic", "04E0", + "Dzecyrillic", "0405", + "Dzhecyrillic", "040F", + "E", "0045", + "Eacute", "00C9", + "Ebreve", "0114", + "Ecaron", "011A", + "Ecedillabreve", "1E1C", + "Echarmenian", "0535", + "Ecircle", "24BA", + "Ecircumflex", "00CA", + "Ecircumflexacute", "1EBE", + "Ecircumflexbelow", "1E18", + "Ecircumflexdotbelow", "1EC6", + "Ecircumflexgrave", "1EC0", + "Ecircumflexhookabove", "1EC2", + "Ecircumflextilde", "1EC4", + "Ecyrillic", "0404", + "Edblgrave", "0204", + "Edieresis", "00CB", + "Edot", "0116", + "Edotaccent", "0116", + "Edotbelow", "1EB8", + "Efcyrillic", "0424", + "Egrave", "00C8", + "Eharmenian", "0537", + "Ehookabove", "1EBA", + "Eightroman", "2167", + "Einvertedbreve", "0206", + "Eiotifiedcyrillic", "0464", + "Elcyrillic", "041B", + "Elevenroman", "216A", + "Emacron", "0112", + "Emacronacute", "1E16", + "Emacrongrave", "1E14", + "Emcyrillic", "041C", + "Emonospace", "FF25", + "Encyrillic", "041D", + "Endescendercyrillic", "04A2", + "Eng", "014A", + "Enghecyrillic", "04A4", + "Enhookcyrillic", "04C7", + "Eogonek", "0118", + "Eopen", "0190", + "Epsilon", "0395", + "Epsilontonos", "0388", + "Ercyrillic", "0420", + "Ereversed", "018E", + "Ereversedcyrillic", "042D", + "Escyrillic", "0421", + "Esdescendercyrillic", "04AA", + "Esh", "01A9", + "Eta", "0397", + "Etarmenian", "0538", + "Etatonos", "0389", + "Eth", "00D0", + "Etilde", "1EBC", + "Etildebelow", "1E1A", + "Euro", "20AC", + "Ezh", "01B7", + "Ezhcaron", "01EE", + "Ezhreversed", "01B8", + "F", "0046", + "Fcircle", "24BB", + "Fdotaccent", "1E1E", + "Feharmenian", "0556", + "Feicoptic", "03E4", + "Fhook", "0191", + "Fitacyrillic", "0472", + "Fiveroman", "2164", + "Fmonospace", "FF26", + "Fourroman", "2163", + "G", "0047", + "GBsquare", "3387", + "Gacute", "01F4", + "Gamma", "0393", + "Gammaafrican", "0194", + "Gangiacoptic", "03EA", + "Gbreve", "011E", + "Gcaron", "01E6", + "Gcedilla", "0122", + "Gcircle", "24BC", + "Gcircumflex", "011C", + "Gcommaaccent", "0122", + "Gdot", "0120", + "Gdotaccent", "0120", + "Gecyrillic", "0413", + "Ghadarmenian", "0542", + "Ghemiddlehookcyrillic", "0494", + "Ghestrokecyrillic", "0492", + "Gheupturncyrillic", "0490", + "Ghook", "0193", + "Gimarmenian", "0533", + "Gjecyrillic", "0403", + "Gmacron", "1E20", + "Gmonospace", "FF27", + "Gsmallhook", "029B", + "Gstroke", "01E4", + "H", "0048", + "H18533", "25CF", + "H18543", "25AA", + "H18551", "25AB", + "H22073", "25A1", + "HPsquare", "33CB", + "Haabkhasiancyrillic", "04A8", + "Hadescendercyrillic", "04B2", + "Hardsigncyrillic", "042A", + "Hbar", "0126", + "Hbrevebelow", "1E2A", + "Hcedilla", "1E28", + "Hcircle", "24BD", + "Hcircumflex", "0124", + "Hdieresis", "1E26", + "Hdotaccent", "1E22", + "Hdotbelow", "1E24", + "Hmonospace", "FF28", + "Hoarmenian", "0540", + "Horicoptic", "03E8", + "Hzsquare", "3390", + "I", "0049", + "IAcyrillic", "042F", + "IJ", "0132", + "IUcyrillic", "042E", + "Iacute", "00CD", + "Ibreve", "012C", + "Icaron", "01CF", + "Icircle", "24BE", + "Icircumflex", "00CE", + "Icyrillic", "0406", + "Idblgrave", "0208", + "Idieresis", "00CF", + "Idieresisacute", "1E2E", + "Idieresiscyrillic", "04E4", + "Idot", "0130", + "Idotaccent", "0130", + "Idotbelow", "1ECA", + "Iebrevecyrillic", "04D6", + "Iecyrillic", "0415", + "Ifraktur", "2111", + "Igrave", "00CC", + "Ihookabove", "1EC8", + "Iicyrillic", "0418", + "Iinvertedbreve", "020A", + "Iishortcyrillic", "0419", + "Imacron", "012A", + "Imacroncyrillic", "04E2", + "Imonospace", "FF29", + "Iniarmenian", "053B", + "Iocyrillic", "0401", + "Iogonek", "012E", + "Iota", "0399", + "Iotaafrican", "0196", + "Iotadieresis", "03AA", + "Iotatonos", "038A", + "Istroke", "0197", + "Itilde", "0128", + "Itildebelow", "1E2C", + "Izhitsacyrillic", "0474", + "Izhitsadblgravecyrillic", "0476", + "J", "004A", + "Jaarmenian", "0541", + "Jcircle", "24BF", + "Jcircumflex", "0134", + "Jecyrillic", "0408", + "Jheharmenian", "054B", + "Jmonospace", "FF2A", + "K", "004B", + "KBsquare", "3385", + "KKsquare", "33CD", + "Kabashkircyrillic", "04A0", + "Kacute", "1E30", + "Kacyrillic", "041A", + "Kadescendercyrillic", "049A", + "Kahookcyrillic", "04C3", + "Kappa", "039A", + "Kastrokecyrillic", "049E", + "Kaverticalstrokecyrillic", "049C", + "Kcaron", "01E8", + "Kcedilla", "0136", + "Kcircle", "24C0", + "Kcommaaccent", "0136", + "Kdotbelow", "1E32", + "Keharmenian", "0554", + "Kenarmenian", "053F", + "Khacyrillic", "0425", + "Kheicoptic", "03E6", + "Khook", "0198", + "Kjecyrillic", "040C", + "Klinebelow", "1E34", + "Kmonospace", "FF2B", + "Koppacyrillic", "0480", + "Koppagreek", "03DE", + "Ksicyrillic", "046E", + "L", "004C", + "LJ", "01C7", + "Lacute", "0139", + "Lambda", "039B", + "Lcaron", "013D", + "Lcedilla", "013B", + "Lcircle", "24C1", + "Lcircumflexbelow", "1E3C", + "Lcommaaccent", "013B", + "Ldot", "013F", + "Ldotaccent", "013F", + "Ldotbelow", "1E36", + "Ldotbelowmacron", "1E38", + "Liwnarmenian", "053C", + "Lj", "01C8", + "Ljecyrillic", "0409", + "Llinebelow", "1E3A", + "Lmonospace", "FF2C", + "Lslash", "0141", + "M", "004D", + "MBsquare", "3386", + "Macute", "1E3E", + "Mcircle", "24C2", + "Mdotaccent", "1E40", + "Mdotbelow", "1E42", + "Menarmenian", "0544", + "Mmonospace", "FF2D", + "Mturned", "019C", + "Mu", "039C", + "N", "004E", + "NJ", "01CA", + "Nacute", "0143", + "Ncaron", "0147", + "Ncedilla", "0145", + "Ncircle", "24C3", + "Ncircumflexbelow", "1E4A", + "Ncommaaccent", "0145", + "Ndotaccent", "1E44", + "Ndotbelow", "1E46", + "Nhookleft", "019D", + "Nineroman", "2168", + "Nj", "01CB", + "Njecyrillic", "040A", + "Nlinebelow", "1E48", + "Nmonospace", "FF2E", + "Nowarmenian", "0546", + "Ntilde", "00D1", + "Nu", "039D", + "O", "004F", + "OE", "0152", + "Oacute", "00D3", + "Obarredcyrillic", "04E8", + "Obarreddieresiscyrillic", "04EA", + "Obreve", "014E", + "Ocaron", "01D1", + "Ocenteredtilde", "019F", + "Ocircle", "24C4", + "Ocircumflex", "00D4", + "Ocircumflexacute", "1ED0", + "Ocircumflexdotbelow", "1ED8", + "Ocircumflexgrave", "1ED2", + "Ocircumflexhookabove", "1ED4", + "Ocircumflextilde", "1ED6", + "Ocyrillic", "041E", + "Odblacute", "0150", + "Odblgrave", "020C", + "Odieresis", "00D6", + "Odieresiscyrillic", "04E6", + "Odotbelow", "1ECC", + "Ograve", "00D2", + "Oharmenian", "0555", + "Ohm", "2126", + "Ohookabove", "1ECE", + "Ohorn", "01A0", + "Ohornacute", "1EDA", + "Ohorndotbelow", "1EE2", + "Ohorngrave", "1EDC", + "Ohornhookabove", "1EDE", + "Ohorntilde", "1EE0", + "Ohungarumlaut", "0150", + "Oi", "01A2", + "Oinvertedbreve", "020E", + "Omacron", "014C", + "Omacronacute", "1E52", + "Omacrongrave", "1E50", + "Omega", "03A9", # groff: not U+2126 + "Omegacyrillic", "0460", + "Omegagreek", "03A9", + "Omegaroundcyrillic", "047A", + "Omegatitlocyrillic", "047C", + "Omegatonos", "038F", + "Omicron", "039F", + "Omicrontonos", "038C", + "Omonospace", "FF2F", + "Oneroman", "2160", + "Oogonek", "01EA", + "Oogonekmacron", "01EC", + "Oopen", "0186", + "Oslash", "00D8", + "Oslashacute", "01FE", + "Ostrokeacute", "01FE", + "Otcyrillic", "047E", + "Otilde", "00D5", + "Otildeacute", "1E4C", + "Otildedieresis", "1E4E", + "P", "0050", + "Pacute", "1E54", + "Pcircle", "24C5", + "Pdotaccent", "1E56", + "Pecyrillic", "041F", + "Peharmenian", "054A", + "Pemiddlehookcyrillic", "04A6", + "Phi", "03A6", + "Phook", "01A4", + "Pi", "03A0", + "Piwrarmenian", "0553", + "Pmonospace", "FF30", + "Psi", "03A8", + "Psicyrillic", "0470", + "Q", "0051", + "Qcircle", "24C6", + "Qmonospace", "FF31", + "R", "0052", + "Raarmenian", "054C", + "Racute", "0154", + "Rcaron", "0158", + "Rcedilla", "0156", + "Rcircle", "24C7", + "Rcommaaccent", "0156", + "Rdblgrave", "0210", + "Rdotaccent", "1E58", + "Rdotbelow", "1E5A", + "Rdotbelowmacron", "1E5C", + "Reharmenian", "0550", + "Rfraktur", "211C", + "Rho", "03A1", + "Rinvertedbreve", "0212", + "Rlinebelow", "1E5E", + "Rmonospace", "FF32", + "Rsmallinverted", "0281", + "Rsmallinvertedsuperior", "02B6", + "S", "0053", + "SF010000", "250C", + "SF020000", "2514", + "SF030000", "2510", + "SF040000", "2518", + "SF050000", "253C", + "SF060000", "252C", + "SF070000", "2534", + "SF080000", "251C", + "SF090000", "2524", + "SF100000", "2500", + "SF110000", "2502", + "SF190000", "2561", + "SF200000", "2562", + "SF210000", "2556", + "SF220000", "2555", + "SF230000", "2563", + "SF240000", "2551", + "SF250000", "2557", + "SF260000", "255D", + "SF270000", "255C", + "SF280000", "255B", + "SF360000", "255E", + "SF370000", "255F", + "SF380000", "255A", + "SF390000", "2554", + "SF400000", "2569", + "SF410000", "2566", + "SF420000", "2560", + "SF430000", "2550", + "SF440000", "256C", + "SF450000", "2567", + "SF460000", "2568", + "SF470000", "2564", + "SF480000", "2565", + "SF490000", "2559", + "SF500000", "2558", + "SF510000", "2552", + "SF520000", "2553", + "SF530000", "256B", + "SF540000", "256A", + "Sacute", "015A", + "Sacutedotaccent", "1E64", + "Sampigreek", "03E0", + "Scaron", "0160", + "Scarondotaccent", "1E66", + "Scedilla", "015E", + "Schwa", "018F", + "Schwacyrillic", "04D8", + "Schwadieresiscyrillic", "04DA", + "Scircle", "24C8", + "Scircumflex", "015C", + "Scommaaccent", "0218", + "Sdotaccent", "1E60", + "Sdotbelow", "1E62", + "Sdotbelowdotaccent", "1E68", + "Seharmenian", "054D", + "Sevenroman", "2166", + "Shaarmenian", "0547", + "Shacyrillic", "0428", + "Shchacyrillic", "0429", + "Sheicoptic", "03E2", + "Shhacyrillic", "04BA", + "Shimacoptic", "03EC", + "Sigma", "03A3", + "Sixroman", "2165", + "Smonospace", "FF33", + "Softsigncyrillic", "042C", + "Stigmagreek", "03DA", + "T", "0054", + "Tau", "03A4", + "Tbar", "0166", + "Tcaron", "0164", + "Tcedilla", "0162", + "Tcircle", "24C9", + "Tcircumflexbelow", "1E70", + "Tcommaaccent", "0162", + "Tdotaccent", "1E6A", + "Tdotbelow", "1E6C", + "Tecyrillic", "0422", + "Tedescendercyrillic", "04AC", + "Tenroman", "2169", + "Tetsecyrillic", "04B4", + "Theta", "0398", + "Thook", "01AC", + "Thorn", "00DE", + "Threeroman", "2162", + "Tiwnarmenian", "054F", + "Tlinebelow", "1E6E", + "Tmonospace", "FF34", + "Toarmenian", "0539", + "Tonefive", "01BC", + "Tonesix", "0184", + "Tonetwo", "01A7", + "Tretroflexhook", "01AE", + "Tsecyrillic", "0426", + "Tshecyrillic", "040B", + "Twelveroman", "216B", + "Tworoman", "2161", + "U", "0055", + "Uacute", "00DA", + "Ubreve", "016C", + "Ucaron", "01D3", + "Ucircle", "24CA", + "Ucircumflex", "00DB", + "Ucircumflexbelow", "1E76", + "Ucyrillic", "0423", + "Udblacute", "0170", + "Udblgrave", "0214", + "Udieresis", "00DC", + "Udieresisacute", "01D7", + "Udieresisbelow", "1E72", + "Udieresiscaron", "01D9", + "Udieresiscyrillic", "04F0", + "Udieresisgrave", "01DB", + "Udieresismacron", "01D5", + "Udotbelow", "1EE4", + "Ugrave", "00D9", + "Uhookabove", "1EE6", + "Uhorn", "01AF", + "Uhornacute", "1EE8", + "Uhorndotbelow", "1EF0", + "Uhorngrave", "1EEA", + "Uhornhookabove", "1EEC", + "Uhorntilde", "1EEE", + "Uhungarumlaut", "0170", + "Uhungarumlautcyrillic", "04F2", + "Uinvertedbreve", "0216", + "Ukcyrillic", "0478", + "Umacron", "016A", + "Umacroncyrillic", "04EE", + "Umacrondieresis", "1E7A", + "Umonospace", "FF35", + "Uogonek", "0172", + "Upsilon", "03A5", + "Upsilon1", "03D2", + "Upsilonacutehooksymbolgreek", "03D3", + "Upsilonafrican", "01B1", + "Upsilondieresis", "03AB", + "Upsilondieresishooksymbolgreek", "03D4", + "Upsilonhooksymbol", "03D2", + "Upsilontonos", "038E", + "Uring", "016E", + "Ushortcyrillic", "040E", + "Ustraightcyrillic", "04AE", + "Ustraightstrokecyrillic", "04B0", + "Utilde", "0168", + "Utildeacute", "1E78", + "Utildebelow", "1E74", + "V", "0056", + "Vcircle", "24CB", + "Vdotbelow", "1E7E", + "Vecyrillic", "0412", + "Vewarmenian", "054E", + "Vhook", "01B2", + "Vmonospace", "FF36", + "Voarmenian", "0548", + "Vtilde", "1E7C", + "W", "0057", + "Wacute", "1E82", + "Wcircle", "24CC", + "Wcircumflex", "0174", + "Wdieresis", "1E84", + "Wdotaccent", "1E86", + "Wdotbelow", "1E88", + "Wgrave", "1E80", + "Wmonospace", "FF37", + "X", "0058", + "Xcircle", "24CD", + "Xdieresis", "1E8C", + "Xdotaccent", "1E8A", + "Xeharmenian", "053D", + "Xi", "039E", + "Xmonospace", "FF38", + "Y", "0059", + "Yacute", "00DD", + "Yatcyrillic", "0462", + "Ycircle", "24CE", + "Ycircumflex", "0176", + "Ydieresis", "0178", + "Ydotaccent", "1E8E", + "Ydotbelow", "1EF4", + "Yericyrillic", "042B", + "Yerudieresiscyrillic", "04F8", + "Ygrave", "1EF2", + "Yhook", "01B3", + "Yhookabove", "1EF6", + "Yiarmenian", "0545", + "Yicyrillic", "0407", + "Yiwnarmenian", "0552", + "Ymonospace", "FF39", + "Ytilde", "1EF8", + "Yusbigcyrillic", "046A", + "Yusbigiotifiedcyrillic", "046C", + "Yuslittlecyrillic", "0466", + "Yuslittleiotifiedcyrillic", "0468", + "Z", "005A", + "Zaarmenian", "0536", + "Zacute", "0179", + "Zcaron", "017D", + "Zcircle", "24CF", + "Zcircumflex", "1E90", + "Zdot", "017B", + "Zdotaccent", "017B", + "Zdotbelow", "1E92", + "Zecyrillic", "0417", + "Zedescendercyrillic", "0498", + "Zedieresiscyrillic", "04DE", + "Zeta", "0396", + "Zhearmenian", "053A", + "Zhebrevecyrillic", "04C1", + "Zhecyrillic", "0416", + "Zhedescendercyrillic", "0496", + "Zhedieresiscyrillic", "04DC", + "Zlinebelow", "1E94", + "Zmonospace", "FF3A", + "Zstroke", "01B5", + "a", "0061", + "aabengali", "0986", + "aacute", "00E1", + "aadeva", "0906", + "aagujarati", "0A86", + "aagurmukhi", "0A06", + "aamatragurmukhi", "0A3E", + "aarusquare", "3303", + "aavowelsignbengali", "09BE", + "aavowelsigndeva", "093E", + "aavowelsigngujarati", "0ABE", + "abbreviationmarkarmenian", "055F", + "abbreviationsigndeva", "0970", + "abengali", "0985", + "abopomofo", "311A", + "abreve", "0103", + "abreveacute", "1EAF", + "abrevecyrillic", "04D1", + "abrevedotbelow", "1EB7", + "abrevegrave", "1EB1", + "abrevehookabove", "1EB3", + "abrevetilde", "1EB5", + "acaron", "01CE", + "acircle", "24D0", + "acircumflex", "00E2", + "acircumflexacute", "1EA5", + "acircumflexdotbelow", "1EAD", + "acircumflexgrave", "1EA7", + "acircumflexhookabove", "1EA9", + "acircumflextilde", "1EAB", + "acute", "00B4", + "acutebelowcmb", "0317", + "acutecmb", "0301", + "acutecomb", "0301", + "acutedeva", "0954", + "acutelowmod", "02CF", + "acutetonecmb", "0341", + "acyrillic", "0430", + "adblgrave", "0201", + "addakgurmukhi", "0A71", + "adeva", "0905", + "adieresis", "00E4", + "adieresiscyrillic", "04D3", + "adieresismacron", "01DF", + "adotbelow", "1EA1", + "adotmacron", "01E1", + "ae", "00E6", + "aeacute", "01FD", + "aekorean", "3150", + "aemacron", "01E3", + "afii00208", "2015", + "afii08941", "20A4", + "afii10017", "0410", + "afii10018", "0411", + "afii10019", "0412", + "afii10020", "0413", + "afii10021", "0414", + "afii10022", "0415", + "afii10023", "0401", + "afii10024", "0416", + "afii10025", "0417", + "afii10026", "0418", + "afii10027", "0419", + "afii10028", "041A", + "afii10029", "041B", + "afii10030", "041C", + "afii10031", "041D", + "afii10032", "041E", + "afii10033", "041F", + "afii10034", "0420", + "afii10035", "0421", + "afii10036", "0422", + "afii10037", "0423", + "afii10038", "0424", + "afii10039", "0425", + "afii10040", "0426", + "afii10041", "0427", + "afii10042", "0428", + "afii10043", "0429", + "afii10044", "042A", + "afii10045", "042B", + "afii10046", "042C", + "afii10047", "042D", + "afii10048", "042E", + "afii10049", "042F", + "afii10050", "0490", + "afii10051", "0402", + "afii10052", "0403", + "afii10053", "0404", + "afii10054", "0405", + "afii10055", "0406", + "afii10056", "0407", + "afii10057", "0408", + "afii10058", "0409", + "afii10059", "040A", + "afii10060", "040B", + "afii10061", "040C", + "afii10062", "040E", + "afii10065", "0430", + "afii10066", "0431", + "afii10067", "0432", + "afii10068", "0433", + "afii10069", "0434", + "afii10070", "0435", + "afii10071", "0451", + "afii10072", "0436", + "afii10073", "0437", + "afii10074", "0438", + "afii10075", "0439", + "afii10076", "043A", + "afii10077", "043B", + "afii10078", "043C", + "afii10079", "043D", + "afii10080", "043E", + "afii10081", "043F", + "afii10082", "0440", + "afii10083", "0441", + "afii10084", "0442", + "afii10085", "0443", + "afii10086", "0444", + "afii10087", "0445", + "afii10088", "0446", + "afii10089", "0447", + "afii10090", "0448", + "afii10091", "0449", + "afii10092", "044A", + "afii10093", "044B", + "afii10094", "044C", + "afii10095", "044D", + "afii10096", "044E", + "afii10097", "044F", + "afii10098", "0491", + "afii10099", "0452", + "afii10100", "0453", + "afii10101", "0454", + "afii10102", "0455", + "afii10103", "0456", + "afii10104", "0457", + "afii10105", "0458", + "afii10106", "0459", + "afii10107", "045A", + "afii10108", "045B", + "afii10109", "045C", + "afii10110", "045E", + "afii10145", "040F", + "afii10146", "0462", + "afii10147", "0472", + "afii10148", "0474", + "afii10193", "045F", + "afii10194", "0463", + "afii10195", "0473", + "afii10196", "0475", + "afii10846", "04D9", + "afii299", "200E", + "afii300", "200F", + "afii301", "200D", + "afii57381", "066A", + "afii57388", "060C", + "afii57392", "0660", + "afii57393", "0661", + "afii57394", "0662", + "afii57395", "0663", + "afii57396", "0664", + "afii57397", "0665", + "afii57398", "0666", + "afii57399", "0667", + "afii57400", "0668", + "afii57401", "0669", + "afii57403", "061B", + "afii57407", "061F", + "afii57409", "0621", + "afii57410", "0622", + "afii57411", "0623", + "afii57412", "0624", + "afii57413", "0625", + "afii57414", "0626", + "afii57415", "0627", + "afii57416", "0628", + "afii57417", "0629", + "afii57418", "062A", + "afii57419", "062B", + "afii57420", "062C", + "afii57421", "062D", + "afii57422", "062E", + "afii57423", "062F", + "afii57424", "0630", + "afii57425", "0631", + "afii57426", "0632", + "afii57427", "0633", + "afii57428", "0634", + "afii57429", "0635", + "afii57430", "0636", + "afii57431", "0637", + "afii57432", "0638", + "afii57433", "0639", + "afii57434", "063A", + "afii57440", "0640", + "afii57441", "0641", + "afii57442", "0642", + "afii57443", "0643", + "afii57444", "0644", + "afii57445", "0645", + "afii57446", "0646", + "afii57448", "0648", + "afii57449", "0649", + "afii57450", "064A", + "afii57451", "064B", + "afii57452", "064C", + "afii57453", "064D", + "afii57454", "064E", + "afii57455", "064F", + "afii57456", "0650", + "afii57457", "0651", + "afii57458", "0652", + "afii57470", "0647", + "afii57505", "06A4", + "afii57506", "067E", + "afii57507", "0686", + "afii57508", "0698", + "afii57509", "06AF", + "afii57511", "0679", + "afii57512", "0688", + "afii57513", "0691", + "afii57514", "06BA", + "afii57519", "06D2", + "afii57534", "06D5", + "afii57636", "20AA", + "afii57645", "05BE", + "afii57658", "05C3", + "afii57664", "05D0", + "afii57665", "05D1", + "afii57666", "05D2", + "afii57667", "05D3", + "afii57668", "05D4", + "afii57669", "05D5", + "afii57670", "05D6", + "afii57671", "05D7", + "afii57672", "05D8", + "afii57673", "05D9", + "afii57674", "05DA", + "afii57675", "05DB", + "afii57676", "05DC", + "afii57677", "05DD", + "afii57678", "05DE", + "afii57679", "05DF", + "afii57680", "05E0", + "afii57681", "05E1", + "afii57682", "05E2", + "afii57683", "05E3", + "afii57684", "05E4", + "afii57685", "05E5", + "afii57686", "05E6", + "afii57687", "05E7", + "afii57688", "05E8", + "afii57689", "05E9", + "afii57690", "05EA", + "afii57694", "FB2A", + "afii57695", "FB2B", + "afii57700", "FB4B", + "afii57705", "FB1F", + "afii57716", "05F0", + "afii57717", "05F1", + "afii57718", "05F2", + "afii57723", "FB35", + "afii57793", "05B4", + "afii57794", "05B5", + "afii57795", "05B6", + "afii57796", "05BB", + "afii57797", "05B8", + "afii57798", "05B7", + "afii57799", "05B0", + "afii57800", "05B2", + "afii57801", "05B1", + "afii57802", "05B3", + "afii57803", "05C2", + "afii57804", "05C1", + "afii57806", "05B9", + "afii57807", "05BC", + "afii57839", "05BD", + "afii57841", "05BF", + "afii57842", "05C0", + "afii57929", "02BC", + "afii61248", "2105", + "afii61289", "2113", + "afii61352", "2116", + "afii61573", "202C", + "afii61574", "202D", + "afii61575", "202E", + "afii61664", "200C", + "afii63167", "066D", + "afii64937", "02BD", + "agrave", "00E0", + "agujarati", "0A85", + "agurmukhi", "0A05", + "ahiragana", "3042", + "ahookabove", "1EA3", + "aibengali", "0990", + "aibopomofo", "311E", + "aideva", "0910", + "aiecyrillic", "04D5", + "aigujarati", "0A90", + "aigurmukhi", "0A10", + "aimatragurmukhi", "0A48", + "ainarabic", "0639", + "ainfinalarabic", "FECA", + "aininitialarabic", "FECB", + "ainmedialarabic", "FECC", + "ainvertedbreve", "0203", + "aivowelsignbengali", "09C8", + "aivowelsigndeva", "0948", + "aivowelsigngujarati", "0AC8", + "akatakana", "30A2", + "akatakanahalfwidth", "FF71", + "akorean", "314F", + "alef", "05D0", + "alefarabic", "0627", + "alefdageshhebrew", "FB30", + "aleffinalarabic", "FE8E", + "alefhamzaabovearabic", "0623", + "alefhamzaabovefinalarabic", "FE84", + "alefhamzabelowarabic", "0625", + "alefhamzabelowfinalarabic", "FE88", + "alefhebrew", "05D0", + "aleflamedhebrew", "FB4F", + "alefmaddaabovearabic", "0622", + "alefmaddaabovefinalarabic", "FE82", + "alefmaksuraarabic", "0649", + "alefmaksurafinalarabic", "FEF0", + "alefmaksurainitialarabic", "FEF3", + "alefmaksuramedialarabic", "FEF4", + "alefpatahhebrew", "FB2E", + "alefqamatshebrew", "FB2F", + "aleph", "2135", + "allequal", "224C", + "alpha", "03B1", + "alphatonos", "03AC", + "amacron", "0101", + "amonospace", "FF41", + "ampersand", "0026", + "ampersandmonospace", "FF06", + "amsquare", "33C2", + "anbopomofo", "3122", + "angbopomofo", "3124", + "angkhankhuthai", "0E5A", + "angle", "2220", + "anglebracketleft", "3008", + "anglebracketleftvertical", "FE3F", + "anglebracketright", "3009", + "anglebracketrightvertical", "FE40", + "angleleft", "2329", + "angleright", "232A", + "angstrom", "212B", + "anoteleia", "0387", + "anudattadeva", "0952", + "anusvarabengali", "0982", + "anusvaradeva", "0902", + "anusvaragujarati", "0A82", + "aogonek", "0105", + "apaatosquare", "3300", + "aparen", "249C", + "apostrophearmenian", "055A", + "apostrophemod", "02BC", + "approaches", "2250", + "approxequal", "2248", + "approxequalorimage", "2252", + "approximatelyequal", "2245", + "araeaekorean", "318E", + "araeakorean", "318D", + "arc", "2312", + "arighthalfring", "1E9A", + "aring", "00E5", + "aringacute", "01FB", + "aringbelow", "1E01", + "arrowboth", "2194", + "arrowdashdown", "21E3", + "arrowdashleft", "21E0", + "arrowdashright", "21E2", + "arrowdashup", "21E1", + "arrowdblboth", "21D4", + "arrowdbldown", "21D3", + "arrowdblleft", "21D0", + "arrowdblright", "21D2", + "arrowdblup", "21D1", + "arrowdown", "2193", + "arrowdownleft", "2199", + "arrowdownright", "2198", + "arrowdownwhite", "21E9", + "arrowheaddownmod", "02C5", + "arrowheadleftmod", "02C2", + "arrowheadrightmod", "02C3", + "arrowheadupmod", "02C4", + "arrowleft", "2190", + "arrowleftdbl", "21D0", + "arrowleftdblstroke", "21CD", + "arrowleftoverright", "21C6", + "arrowleftwhite", "21E6", + "arrowright", "2192", + "arrowrightdblstroke", "21CF", + "arrowrightheavy", "279E", + "arrowrightoverleft", "21C4", + "arrowrightwhite", "21E8", + "arrowtableft", "21E4", + "arrowtabright", "21E5", + "arrowup", "2191", + "arrowupdn", "2195", + "arrowupdnbse", "21A8", + "arrowupdownbase", "21A8", + "arrowupleft", "2196", + "arrowupleftofdown", "21C5", + "arrowupright", "2197", + "arrowupwhite", "21E7", + "asciicircum", "005E", + "asciicircummonospace", "FF3E", + "asciitilde", "007E", + "asciitildemonospace", "FF5E", + "ascript", "0251", + "ascriptturned", "0252", + "asmallhiragana", "3041", + "asmallkatakana", "30A1", + "asmallkatakanahalfwidth", "FF67", + "asterisk", "002A", + "asteriskaltonearabic", "066D", + "asteriskarabic", "066D", + "asteriskmath", "2217", + "asteriskmonospace", "FF0A", + "asterisksmall", "FE61", + "asterism", "2042", + "asymptoticallyequal", "2243", + "at", "0040", + "atilde", "00E3", + "atmonospace", "FF20", + "atsmall", "FE6B", + "aturned", "0250", + "aubengali", "0994", + "aubopomofo", "3120", + "audeva", "0914", + "augujarati", "0A94", + "augurmukhi", "0A14", + "aulengthmarkbengali", "09D7", + "aumatragurmukhi", "0A4C", + "auvowelsignbengali", "09CC", + "auvowelsigndeva", "094C", + "auvowelsigngujarati", "0ACC", + "avagrahadeva", "093D", + "aybarmenian", "0561", + "ayin", "05E2", + "ayinaltonehebrew", "FB20", + "ayinhebrew", "05E2", + "b", "0062", + "babengali", "09AC", + "backslash", "005C", + "backslashmonospace", "FF3C", + "badeva", "092C", + "bagujarati", "0AAC", + "bagurmukhi", "0A2C", + "bahiragana", "3070", + "bahtthai", "0E3F", + "bakatakana", "30D0", + "bar", "007C", + "barmonospace", "FF5C", + "bbopomofo", "3105", + "bcircle", "24D1", + "bdotaccent", "1E03", + "bdotbelow", "1E05", + "beamedsixteenthnotes", "266C", + "because", "2235", + "becyrillic", "0431", + "beharabic", "0628", + "behfinalarabic", "FE90", + "behinitialarabic", "FE91", + "behiragana", "3079", + "behmedialarabic", "FE92", + "behmeeminitialarabic", "FC9F", + "behmeemisolatedarabic", "FC08", + "behnoonfinalarabic", "FC6D", + "bekatakana", "30D9", + "benarmenian", "0562", + "bet", "05D1", + "beta", "03B2", + "betasymbolgreek", "03D0", + "betdagesh", "FB31", + "betdageshhebrew", "FB31", + "bethebrew", "05D1", + "betrafehebrew", "FB4C", + "bhabengali", "09AD", + "bhadeva", "092D", + "bhagujarati", "0AAD", + "bhagurmukhi", "0A2D", + "bhook", "0253", + "bihiragana", "3073", + "bikatakana", "30D3", + "bilabialclick", "0298", + "bindigurmukhi", "0A02", + "birusquare", "3331", + "blackcircle", "25CF", + "blackdiamond", "25C6", + "blackdownpointingtriangle", "25BC", + "blackleftpointingpointer", "25C4", + "blackleftpointingtriangle", "25C0", + "blacklenticularbracketleft", "3010", + "blacklenticularbracketleftvertical", "FE3B", + "blacklenticularbracketright", "3011", + "blacklenticularbracketrightvertical", "FE3C", + "blacklowerlefttriangle", "25E3", + "blacklowerrighttriangle", "25E2", + "blackrectangle", "25AC", + "blackrightpointingpointer", "25BA", + "blackrightpointingtriangle", "25B6", + "blacksmallsquare", "25AA", + "blacksmilingface", "263B", + "blacksquare", "25A0", + "blackstar", "2605", + "blackupperlefttriangle", "25E4", + "blackupperrighttriangle", "25E5", + "blackuppointingsmalltriangle", "25B4", + "blackuppointingtriangle", "25B2", + "blank", "2423", + "blinebelow", "1E07", + "block", "2588", + "bmonospace", "FF42", + "bobaimaithai", "0E1A", + "bohiragana", "307C", + "bokatakana", "30DC", + "bparen", "249D", + "bqsquare", "33C3", + "braceleft", "007B", + "braceleftmonospace", "FF5B", + "braceleftsmall", "FE5B", + "braceleftvertical", "FE37", + "braceright", "007D", + "bracerightmonospace", "FF5D", + "bracerightsmall", "FE5C", + "bracerightvertical", "FE38", + "bracketleft", "005B", + "bracketleftmonospace", "FF3B", + "bracketright", "005D", + "bracketrightmonospace", "FF3D", + "breve", "02D8", + "brevebelowcmb", "032E", + "brevecmb", "0306", + "breveinvertedbelowcmb", "032F", + "breveinvertedcmb", "0311", + "breveinverteddoublecmb", "0361", + "bridgebelowcmb", "032A", + "bridgeinvertedbelowcmb", "033A", + "brokenbar", "00A6", + "bstroke", "0180", + "btopbar", "0183", + "buhiragana", "3076", + "bukatakana", "30D6", + "bullet", "2022", + "bulletinverse", "25D8", + "bulletoperator", "2219", + "bullseye", "25CE", + "c", "0063", + "caarmenian", "056E", + "cabengali", "099A", + "cacute", "0107", + "cadeva", "091A", + "cagujarati", "0A9A", + "cagurmukhi", "0A1A", + "calsquare", "3388", + "candrabindubengali", "0981", + "candrabinducmb", "0310", + "candrabindudeva", "0901", + "candrabindugujarati", "0A81", + "capslock", "21EA", + "careof", "2105", + "caron", "02C7", + "caronbelowcmb", "032C", + "caroncmb", "030C", + "carriagereturn", "21B5", + "cbopomofo", "3118", + "ccaron", "010D", + "ccedilla", "00E7", + "ccedillaacute", "1E09", + "ccircle", "24D2", + "ccircumflex", "0109", + "ccurl", "0255", + "cdot", "010B", + "cdotaccent", "010B", + "cdsquare", "33C5", + "cedilla", "00B8", + "cedillacmb", "0327", + "cent", "00A2", + "centigrade", "2103", + "centmonospace", "FFE0", + "chaarmenian", "0579", + "chabengali", "099B", + "chadeva", "091B", + "chagujarati", "0A9B", + "chagurmukhi", "0A1B", + "chbopomofo", "3114", + "cheabkhasiancyrillic", "04BD", + "checkmark", "2713", + "checyrillic", "0447", + "chedescenderabkhasiancyrillic", "04BF", + "chedescendercyrillic", "04B7", + "chedieresiscyrillic", "04F5", + "cheharmenian", "0573", + "chekhakassiancyrillic", "04CC", + "cheverticalstrokecyrillic", "04B9", + "chi", "03C7", + "chieuchacirclekorean", "3277", + "chieuchaparenkorean", "3217", + "chieuchcirclekorean", "3269", + "chieuchkorean", "314A", + "chieuchparenkorean", "3209", + "chochangthai", "0E0A", + "chochanthai", "0E08", + "chochingthai", "0E09", + "chochoethai", "0E0C", + "chook", "0188", + "cieucacirclekorean", "3276", + "cieucaparenkorean", "3216", + "cieuccirclekorean", "3268", + "cieuckorean", "3148", + "cieucparenkorean", "3208", + "cieucuparenkorean", "321C", + "circle", "25CB", + "circlemultiply", "2297", + "circleot", "2299", + "circleplus", "2295", + "circlepostalmark", "3036", + "circlewithlefthalfblack", "25D0", + "circlewithrighthalfblack", "25D1", + "circumflex", "02C6", + "circumflexbelowcmb", "032D", + "circumflexcmb", "0302", + "clear", "2327", + "clickalveolar", "01C2", + "clickdental", "01C0", + "clicklateral", "01C1", + "clickretroflex", "01C3", + "club", "2663", + "clubsuitblack", "2663", + "clubsuitwhite", "2667", + "cmcubedsquare", "33A4", + "cmonospace", "FF43", + "cmsquaredsquare", "33A0", + "coarmenian", "0581", + "colon", "003A", + "colonmonetary", "20A1", + "colonmonospace", "FF1A", + "colonsign", "20A1", + "colonsmall", "FE55", + "colontriangularhalfmod", "02D1", + "colontriangularmod", "02D0", + "comma", "002C", + "commaabovecmb", "0313", + "commaaboverightcmb", "0315", + "commaarabic", "060C", + "commaarmenian", "055D", + "commamonospace", "FF0C", + "commareversedabovecmb", "0314", + "commareversedmod", "02BD", + "commasmall", "FE50", + "commaturnedabovecmb", "0312", + "commaturnedmod", "02BB", + "compass", "263C", + "congruent", "2245", + "contourintegral", "222E", + "control", "2303", + "controlACK", "0006", + "controlBEL", "0007", + "controlBS", "0008", + "controlCAN", "0018", + "controlCR", "000D", + "controlDC1", "0011", + "controlDC2", "0012", + "controlDC3", "0013", + "controlDC4", "0014", + "controlDEL", "007F", + "controlDLE", "0010", + "controlEM", "0019", + "controlENQ", "0005", + "controlEOT", "0004", + "controlESC", "001B", + "controlETB", "0017", + "controlETX", "0003", + "controlFF", "000C", + "controlFS", "001C", + "controlGS", "001D", + "controlHT", "0009", + "controlLF", "000A", + "controlNAK", "0015", + "controlRS", "001E", + "controlSI", "000F", + "controlSO", "000E", + "controlSOT", "0002", + "controlSTX", "0001", + "controlSUB", "001A", + "controlSYN", "0016", + "controlUS", "001F", + "controlVT", "000B", + "copyright", "00A9", + "cornerbracketleft", "300C", + "cornerbracketlefthalfwidth", "FF62", + "cornerbracketleftvertical", "FE41", + "cornerbracketright", "300D", + "cornerbracketrighthalfwidth", "FF63", + "cornerbracketrightvertical", "FE42", + "corporationsquare", "337F", + "cosquare", "33C7", + "coverkgsquare", "33C6", + "cparen", "249E", + "cruzeiro", "20A2", + "cstretched", "0297", + "curlyand", "22CF", + "curlyor", "22CE", + "currency", "00A4", + "d", "0064", + "daarmenian", "0564", + "dabengali", "09A6", + "dadarabic", "0636", + "dadeva", "0926", + "dadfinalarabic", "FEBE", + "dadinitialarabic", "FEBF", + "dadmedialarabic", "FEC0", + "dagesh", "05BC", + "dageshhebrew", "05BC", + "dagger", "2020", + "daggerdbl", "2021", + "dagujarati", "0AA6", + "dagurmukhi", "0A26", + "dahiragana", "3060", + "dakatakana", "30C0", + "dalarabic", "062F", + "dalet", "05D3", + "daletdagesh", "FB33", + "daletdageshhebrew", "FB33", + "dalethatafpatah", "05D3_05B2", + "dalethatafpatahhebrew", "05D3_05B2", + "dalethatafsegol", "05D3_05B1", + "dalethatafsegolhebrew", "05D3_05B1", + "dalethebrew", "05D3", + "dalethiriq", "05D3_05B4", + "dalethiriqhebrew", "05D3_05B4", + "daletholam", "05D3_05B9", + "daletholamhebrew", "05D3_05B9", + "daletpatah", "05D3_05B7", + "daletpatahhebrew", "05D3_05B7", + "daletqamats", "05D3_05B8", + "daletqamatshebrew", "05D3_05B8", + "daletqubuts", "05D3_05BB", + "daletqubutshebrew", "05D3_05BB", + "daletsegol", "05D3_05B6", + "daletsegolhebrew", "05D3_05B6", + "daletsheva", "05D3_05B0", + "daletshevahebrew", "05D3_05B0", + "dalettsere", "05D3_05B5", + "dalettserehebrew", "05D3_05B5", + "dalfinalarabic", "FEAA", + "dammaarabic", "064F", + "dammalowarabic", "064F", + "dammatanaltonearabic", "064C", + "dammatanarabic", "064C", + "danda", "0964", + "dargahebrew", "05A7", + "dargalefthebrew", "05A7", + "dasiapneumatacyrilliccmb", "0485", + "dblanglebracketleft", "300A", + "dblanglebracketleftvertical", "FE3D", + "dblanglebracketright", "300B", + "dblanglebracketrightvertical", "FE3E", + "dblarchinvertedbelowcmb", "032B", + "dblarrowleft", "21D4", + "dblarrowright", "21D2", + "dbldanda", "0965", + "dblgravecmb", "030F", + "dblintegral", "222C", + "dbllowline", "2017", + "dbllowlinecmb", "0333", + "dbloverlinecmb", "033F", + "dblprimemod", "02BA", + "dblverticalbar", "2016", + "dblverticallineabovecmb", "030E", + "dbopomofo", "3109", + "dbsquare", "33C8", + "dcaron", "010F", + "dcedilla", "1E11", + "dcircle", "24D3", + "dcircumflexbelow", "1E13", + "dcroat", "0111", + "ddabengali", "09A1", + "ddadeva", "0921", + "ddagujarati", "0AA1", + "ddagurmukhi", "0A21", + "ddalarabic", "0688", + "ddalfinalarabic", "FB89", + "dddhadeva", "095C", + "ddhabengali", "09A2", + "ddhadeva", "0922", + "ddhagujarati", "0AA2", + "ddhagurmukhi", "0A22", + "ddotaccent", "1E0B", + "ddotbelow", "1E0D", + "decimalseparatorarabic", "066B", + "decimalseparatorpersian", "066B", + "decyrillic", "0434", + "degree", "00B0", + "dehihebrew", "05AD", + "dehiragana", "3067", + "deicoptic", "03EF", + "dekatakana", "30C7", + "deleteleft", "232B", + "deleteright", "2326", + "delta", "03B4", + "deltaturned", "018D", + "denominatorminusonenumeratorbengali", "09F8", + "dezh", "02A4", + "dhabengali", "09A7", + "dhadeva", "0927", + "dhagujarati", "0AA7", + "dhagurmukhi", "0A27", + "dhook", "0257", + "dialytikatonos", "0385", + "dialytikatonoscmb", "0344", + "diamond", "2666", + "diamondsuitwhite", "2662", + "dieresis", "00A8", + "dieresisbelowcmb", "0324", + "dieresiscmb", "0308", + "dieresistonos", "0385", + "dihiragana", "3062", + "dikatakana", "30C2", + "dittomark", "3003", + "divide", "00F7", + "divides", "2223", + "divisionslash", "2215", + "djecyrillic", "0452", + "dkshade", "2593", + "dlinebelow", "1E0F", + "dlsquare", "3397", + "dmacron", "0111", + "dmonospace", "FF44", + "dnblock", "2584", + "dochadathai", "0E0E", + "dodekthai", "0E14", + "dohiragana", "3069", + "dokatakana", "30C9", + "dollar", "0024", + "dollarmonospace", "FF04", + "dollarsmall", "FE69", + "dong", "20AB", + "dorusquare", "3326", + "dotaccent", "02D9", + "dotaccentcmb", "0307", + "dotbelowcmb", "0323", + "dotbelowcomb", "0323", + "dotkatakana", "30FB", + "dotlessi", "0131", + "dotlessjstrokehook", "0284", + "dotmath", "22C5", + "dottedcircle", "25CC", + "doubleyodpatah", "FB1F", + "doubleyodpatahhebrew", "FB1F", + "downtackbelowcmb", "031E", + "downtackmod", "02D5", + "dparen", "249F", + "dtail", "0256", + "dtopbar", "018C", + "duhiragana", "3065", + "dukatakana", "30C5", + "dz", "01F3", + "dzaltone", "02A3", + "dzcaron", "01C6", + "dzcurl", "02A5", + "dzeabkhasiancyrillic", "04E1", + "dzecyrillic", "0455", + "dzhecyrillic", "045F", + "e", "0065", + "eacute", "00E9", + "earth", "2641", + "ebengali", "098F", + "ebopomofo", "311C", + "ebreve", "0115", + "ecandradeva", "090D", + "ecandragujarati", "0A8D", + "ecandravowelsigndeva", "0945", + "ecandravowelsigngujarati", "0AC5", + "ecaron", "011B", + "ecedillabreve", "1E1D", + "echarmenian", "0565", + "echyiwnarmenian", "0587", + "ecircle", "24D4", + "ecircumflex", "00EA", + "ecircumflexacute", "1EBF", + "ecircumflexbelow", "1E19", + "ecircumflexdotbelow", "1EC7", + "ecircumflexgrave", "1EC1", + "ecircumflexhookabove", "1EC3", + "ecircumflextilde", "1EC5", + "ecyrillic", "0454", + "edblgrave", "0205", + "edeva", "090F", + "edieresis", "00EB", + "edot", "0117", + "edotaccent", "0117", + "edotbelow", "1EB9", + "eegurmukhi", "0A0F", + "eematragurmukhi", "0A47", + "efcyrillic", "0444", + "egrave", "00E8", + "egujarati", "0A8F", + "eharmenian", "0567", + "ehbopomofo", "311D", + "ehiragana", "3048", + "ehookabove", "1EBB", + "eibopomofo", "311F", + "eight", "0038", + "eightarabic", "0668", + "eightbengali", "09EE", + "eightcircle", "2467", + "eightcircleinversesansserif", "2791", + "eightdeva", "096E", + "eighteencircle", "2471", + "eighteenparen", "2485", + "eighteenperiod", "2499", + "eightgujarati", "0AEE", + "eightgurmukhi", "0A6E", + "eighthackarabic", "0668", + "eighthangzhou", "3028", + "eighthnotebeamed", "266B", + "eightideographicparen", "3227", + "eightinferior", "2088", + "eightmonospace", "FF18", + "eightparen", "247B", + "eightperiod", "248F", + "eightpersian", "06F8", + "eightroman", "2177", + "eightsuperior", "2078", + "eightthai", "0E58", + "einvertedbreve", "0207", + "eiotifiedcyrillic", "0465", + "ekatakana", "30A8", + "ekatakanahalfwidth", "FF74", + "ekonkargurmukhi", "0A74", + "ekorean", "3154", + "elcyrillic", "043B", + "element", "2208", + "elevencircle", "246A", + "elevenparen", "247E", + "elevenperiod", "2492", + "elevenroman", "217A", + "ellipsis", "2026", + "ellipsisvertical", "22EE", + "emacron", "0113", + "emacronacute", "1E17", + "emacrongrave", "1E15", + "emcyrillic", "043C", + "emdash", "2014", + "emdashvertical", "FE31", + "emonospace", "FF45", + "emphasismarkarmenian", "055B", + "emptyset", "2205", + "enbopomofo", "3123", + "encyrillic", "043D", + "endash", "2013", + "endashvertical", "FE32", + "endescendercyrillic", "04A3", + "eng", "014B", + "engbopomofo", "3125", + "enghecyrillic", "04A5", + "enhookcyrillic", "04C8", + "enspace", "2002", + "eogonek", "0119", + "eokorean", "3153", + "eopen", "025B", + "eopenclosed", "029A", + "eopenreversed", "025C", + "eopenreversedclosed", "025E", + "eopenreversedhook", "025D", + "eparen", "24A0", + "epsilon", "03B5", + "epsilontonos", "03AD", + "equal", "003D", + "equalmonospace", "FF1D", + "equalsmall", "FE66", + "equalsuperior", "207C", + "equivalence", "2261", + "erbopomofo", "3126", + "ercyrillic", "0440", + "ereversed", "0258", + "ereversedcyrillic", "044D", + "escyrillic", "0441", + "esdescendercyrillic", "04AB", + "esh", "0283", + "eshcurl", "0286", + "eshortdeva", "090E", + "eshortvowelsigndeva", "0946", + "eshreversedloop", "01AA", + "eshsquatreversed", "0285", + "esmallhiragana", "3047", + "esmallkatakana", "30A7", + "esmallkatakanahalfwidth", "FF6A", + "estimated", "212E", + "eta", "03B7", + "etarmenian", "0568", + "etatonos", "03AE", + "eth", "00F0", + "etilde", "1EBD", + "etildebelow", "1E1B", + "etnahtafoukhhebrew", "0591", + "etnahtafoukhlefthebrew", "0591", + "etnahtahebrew", "0591", + "etnahtalefthebrew", "0591", + "eturned", "01DD", + "eukorean", "3161", + "euro", "20AC", + "evowelsignbengali", "09C7", + "evowelsigndeva", "0947", + "evowelsigngujarati", "0AC7", + "exclam", "0021", + "exclamarmenian", "055C", + "exclamdbl", "203C", + "exclamdown", "00A1", + "exclammonospace", "FF01", + "existential", "2203", + "ezh", "0292", + "ezhcaron", "01EF", + "ezhcurl", "0293", + "ezhreversed", "01B9", + "ezhtail", "01BA", + "f", "0066", + "fadeva", "095E", + "fagurmukhi", "0A5E", + "fahrenheit", "2109", + "fathaarabic", "064E", + "fathalowarabic", "064E", + "fathatanarabic", "064B", + "fbopomofo", "3108", + "fcircle", "24D5", + "fdotaccent", "1E1F", + "feharabic", "0641", + "feharmenian", "0586", + "fehfinalarabic", "FED2", + "fehinitialarabic", "FED3", + "fehmedialarabic", "FED4", + "feicoptic", "03E5", + "female", "2640", + "ff", "FB00", + "ffi", "FB03", + "ffl", "FB04", + "fi", "FB01", + "fifteencircle", "246E", + "fifteenparen", "2482", + "fifteenperiod", "2496", + "figuredash", "2012", + "filledbox", "25A0", + "filledrect", "25AC", + "finalkaf", "05DA", + "finalkafdagesh", "FB3A", + "finalkafdageshhebrew", "FB3A", + "finalkafhebrew", "05DA", + "finalkafqamats", "05DA_05B8", + "finalkafqamatshebrew", "05DA_05B8", + "finalkafsheva", "05DA_05B0", + "finalkafshevahebrew", "05DA_05B0", + "finalmem", "05DD", + "finalmemhebrew", "05DD", + "finalnun", "05DF", + "finalnunhebrew", "05DF", + "finalpe", "05E3", + "finalpehebrew", "05E3", + "finaltsadi", "05E5", + "finaltsadihebrew", "05E5", + "firsttonechinese", "02C9", + "fisheye", "25C9", + "fitacyrillic", "0473", + "five", "0035", + "fivearabic", "0665", + "fivebengali", "09EB", + "fivecircle", "2464", + "fivecircleinversesansserif", "278E", + "fivedeva", "096B", + "fiveeighths", "215D", + "fivegujarati", "0AEB", + "fivegurmukhi", "0A6B", + "fivehackarabic", "0665", + "fivehangzhou", "3025", + "fiveideographicparen", "3224", + "fiveinferior", "2085", + "fivemonospace", "FF15", + "fiveparen", "2478", + "fiveperiod", "248C", + "fivepersian", "06F5", + "fiveroman", "2174", + "fivesuperior", "2075", + "fivethai", "0E55", + "fl", "FB02", + "florin", "0192", + "fmonospace", "FF46", + "fmsquare", "3399", + "fofanthai", "0E1F", + "fofathai", "0E1D", + "fongmanthai", "0E4F", + "forall", "2200", + "four", "0034", + "fourarabic", "0664", + "fourbengali", "09EA", + "fourcircle", "2463", + "fourcircleinversesansserif", "278D", + "fourdeva", "096A", + "fourgujarati", "0AEA", + "fourgurmukhi", "0A6A", + "fourhackarabic", "0664", + "fourhangzhou", "3024", + "fourideographicparen", "3223", + "fourinferior", "2084", + "fourmonospace", "FF14", + "fournumeratorbengali", "09F7", + "fourparen", "2477", + "fourperiod", "248B", + "fourpersian", "06F4", + "fourroman", "2173", + "foursuperior", "2074", + "fourteencircle", "246D", + "fourteenparen", "2481", + "fourteenperiod", "2495", + "fourthai", "0E54", + "fourthtonechinese", "02CB", + "fparen", "24A1", + "fraction", "2044", + "franc", "20A3", + "g", "0067", + "gabengali", "0997", + "gacute", "01F5", + "gadeva", "0917", + "gafarabic", "06AF", + "gaffinalarabic", "FB93", + "gafinitialarabic", "FB94", + "gafmedialarabic", "FB95", + "gagujarati", "0A97", + "gagurmukhi", "0A17", + "gahiragana", "304C", + "gakatakana", "30AC", + "gamma", "03B3", + "gammalatinsmall", "0263", + "gammasuperior", "02E0", + "gangiacoptic", "03EB", + "gbopomofo", "310D", + "gbreve", "011F", + "gcaron", "01E7", + "gcedilla", "0123", + "gcircle", "24D6", + "gcircumflex", "011D", + "gcommaaccent", "0123", + "gdot", "0121", + "gdotaccent", "0121", + "gecyrillic", "0433", + "gehiragana", "3052", + "gekatakana", "30B2", + "geometricallyequal", "2251", + "gereshaccenthebrew", "059C", + "gereshhebrew", "05F3", + "gereshmuqdamhebrew", "059D", + "germandbls", "00DF", + "gershayimaccenthebrew", "059E", + "gershayimhebrew", "05F4", + "getamark", "3013", + "ghabengali", "0998", + "ghadarmenian", "0572", + "ghadeva", "0918", + "ghagujarati", "0A98", + "ghagurmukhi", "0A18", + "ghainarabic", "063A", + "ghainfinalarabic", "FECE", + "ghaininitialarabic", "FECF", + "ghainmedialarabic", "FED0", + "ghemiddlehookcyrillic", "0495", + "ghestrokecyrillic", "0493", + "gheupturncyrillic", "0491", + "ghhadeva", "095A", + "ghhagurmukhi", "0A5A", + "ghook", "0260", + "ghzsquare", "3393", + "gihiragana", "304E", + "gikatakana", "30AE", + "gimarmenian", "0563", + "gimel", "05D2", + "gimeldagesh", "FB32", + "gimeldageshhebrew", "FB32", + "gimelhebrew", "05D2", + "gjecyrillic", "0453", + "glottalinvertedstroke", "01BE", + "glottalstop", "0294", + "glottalstopinverted", "0296", + "glottalstopmod", "02C0", + "glottalstopreversed", "0295", + "glottalstopreversedmod", "02C1", + "glottalstopreversedsuperior", "02E4", + "glottalstopstroke", "02A1", + "glottalstopstrokereversed", "02A2", + "gmacron", "1E21", + "gmonospace", "FF47", + "gohiragana", "3054", + "gokatakana", "30B4", + "gparen", "24A2", + "gpasquare", "33AC", + "gradient", "2207", + "grave", "0060", + "gravebelowcmb", "0316", + "gravecmb", "0300", + "gravecomb", "0300", + "gravedeva", "0953", + "gravelowmod", "02CE", + "gravemonospace", "FF40", + "gravetonecmb", "0340", + "greater", "003E", + "greaterequal", "2265", + "greaterequalorless", "22DB", + "greatermonospace", "FF1E", + "greaterorequivalent", "2273", + "greaterorless", "2277", + "greateroverequal", "2267", + "greatersmall", "FE65", + "gscript", "0261", + "gstroke", "01E5", + "guhiragana", "3050", + "guillemotleft", "00AB", + "guillemotright", "00BB", + "guilsinglleft", "2039", + "guilsinglright", "203A", + "gukatakana", "30B0", + "guramusquare", "3318", + "gysquare", "33C9", + "h", "0068", + "haabkhasiancyrillic", "04A9", + "haaltonearabic", "06C1", + "habengali", "09B9", + "hadescendercyrillic", "04B3", + "hadeva", "0939", + "hagujarati", "0AB9", + "hagurmukhi", "0A39", + "haharabic", "062D", + "hahfinalarabic", "FEA2", + "hahinitialarabic", "FEA3", + "hahiragana", "306F", + "hahmedialarabic", "FEA4", + "haitusquare", "332A", + "hakatakana", "30CF", + "hakatakanahalfwidth", "FF8A", + "halantgurmukhi", "0A4D", + "hamzaarabic", "0621", + "hamzadammaarabic", "0621_064F", + "hamzadammatanarabic", "0621_064C", + "hamzafathaarabic", "0621_064E", + "hamzafathatanarabic", "0621_064B", + "hamzalowarabic", "0621", + "hamzalowkasraarabic", "0621_0650", + "hamzalowkasratanarabic", "0621_064D", + "hamzasukunarabic", "0621_0652", + "hangulfiller", "3164", + "hardsigncyrillic", "044A", + "harpoonleftbarbup", "21BC", + "harpoonrightbarbup", "21C0", + "hasquare", "33CA", + "hatafpatah", "05B2", + "hatafpatah16", "05B2", + "hatafpatah23", "05B2", + "hatafpatah2f", "05B2", + "hatafpatahhebrew", "05B2", + "hatafpatahnarrowhebrew", "05B2", + "hatafpatahquarterhebrew", "05B2", + "hatafpatahwidehebrew", "05B2", + "hatafqamats", "05B3", + "hatafqamats1b", "05B3", + "hatafqamats28", "05B3", + "hatafqamats34", "05B3", + "hatafqamatshebrew", "05B3", + "hatafqamatsnarrowhebrew", "05B3", + "hatafqamatsquarterhebrew", "05B3", + "hatafqamatswidehebrew", "05B3", + "hatafsegol", "05B1", + "hatafsegol17", "05B1", + "hatafsegol24", "05B1", + "hatafsegol30", "05B1", + "hatafsegolhebrew", "05B1", + "hatafsegolnarrowhebrew", "05B1", + "hatafsegolquarterhebrew", "05B1", + "hatafsegolwidehebrew", "05B1", + "hbar", "0127", + "hbopomofo", "310F", + "hbrevebelow", "1E2B", + "hcedilla", "1E29", + "hcircle", "24D7", + "hcircumflex", "0125", + "hdieresis", "1E27", + "hdotaccent", "1E23", + "hdotbelow", "1E25", + "he", "05D4", + "heart", "2665", + "heartsuitblack", "2665", + "heartsuitwhite", "2661", + "hedagesh", "FB34", + "hedageshhebrew", "FB34", + "hehaltonearabic", "06C1", + "heharabic", "0647", + "hehebrew", "05D4", + "hehfinalaltonearabic", "FBA7", + "hehfinalalttwoarabic", "FEEA", + "hehfinalarabic", "FEEA", + "hehhamzaabovefinalarabic", "FBA5", + "hehhamzaaboveisolatedarabic", "FBA4", + "hehinitialaltonearabic", "FBA8", + "hehinitialarabic", "FEEB", + "hehiragana", "3078", + "hehmedialaltonearabic", "FBA9", + "hehmedialarabic", "FEEC", + "heiseierasquare", "337B", + "hekatakana", "30D8", + "hekatakanahalfwidth", "FF8D", + "hekutaarusquare", "3336", + "henghook", "0267", + "herutusquare", "3339", + "het", "05D7", + "hethebrew", "05D7", + "hhook", "0266", + "hhooksuperior", "02B1", + "hieuhacirclekorean", "327B", + "hieuhaparenkorean", "321B", + "hieuhcirclekorean", "326D", + "hieuhkorean", "314E", + "hieuhparenkorean", "320D", + "hihiragana", "3072", + "hikatakana", "30D2", + "hikatakanahalfwidth", "FF8B", + "hiriq", "05B4", + "hiriq14", "05B4", + "hiriq21", "05B4", + "hiriq2d", "05B4", + "hiriqhebrew", "05B4", + "hiriqnarrowhebrew", "05B4", + "hiriqquarterhebrew", "05B4", + "hiriqwidehebrew", "05B4", + "hlinebelow", "1E96", + "hmonospace", "FF48", + "hoarmenian", "0570", + "hohipthai", "0E2B", + "hohiragana", "307B", + "hokatakana", "30DB", + "hokatakanahalfwidth", "FF8E", + "holam", "05B9", + "holam19", "05B9", + "holam26", "05B9", + "holam32", "05B9", + "holamhebrew", "05B9", + "holamnarrowhebrew", "05B9", + "holamquarterhebrew", "05B9", + "holamwidehebrew", "05B9", + "honokhukthai", "0E2E", + "hookabovecomb", "0309", + "hookcmb", "0309", + "hookpalatalizedbelowcmb", "0321", + "hookretroflexbelowcmb", "0322", + "hoonsquare", "3342", + "horicoptic", "03E9", + "horizontalbar", "2015", + "horncmb", "031B", + "hotsprings", "2668", + "house", "2302", + "hparen", "24A3", + "hsuperior", "02B0", + "hturned", "0265", + "huhiragana", "3075", + "huiitosquare", "3333", + "hukatakana", "30D5", + "hukatakanahalfwidth", "FF8C", + "hungarumlaut", "02DD", + "hungarumlautcmb", "030B", + "hv", "0195", + "hyphen", "002D", + "hyphenmonospace", "FF0D", + "hyphensmall", "FE63", + "hyphentwo", "2010", + "i", "0069", + "iacute", "00ED", + "iacyrillic", "044F", + "ibengali", "0987", + "ibopomofo", "3127", + "ibreve", "012D", + "icaron", "01D0", + "icircle", "24D8", + "icircumflex", "00EE", + "icyrillic", "0456", + "idblgrave", "0209", + "ideographearthcircle", "328F", + "ideographfirecircle", "328B", + "ideographicallianceparen", "323F", + "ideographiccallparen", "323A", + "ideographiccentrecircle", "32A5", + "ideographicclose", "3006", + "ideographiccomma", "3001", + "ideographiccommaleft", "FF64", + "ideographiccongratulationparen", "3237", + "ideographiccorrectcircle", "32A3", + "ideographicearthparen", "322F", + "ideographicenterpriseparen", "323D", + "ideographicexcellentcircle", "329D", + "ideographicfestivalparen", "3240", + "ideographicfinancialcircle", "3296", + "ideographicfinancialparen", "3236", + "ideographicfireparen", "322B", + "ideographichaveparen", "3232", + "ideographichighcircle", "32A4", + "ideographiciterationmark", "3005", + "ideographiclaborcircle", "3298", + "ideographiclaborparen", "3238", + "ideographicleftcircle", "32A7", + "ideographiclowcircle", "32A6", + "ideographicmedicinecircle", "32A9", + "ideographicmetalparen", "322E", + "ideographicmoonparen", "322A", + "ideographicnameparen", "3234", + "ideographicperiod", "3002", + "ideographicprintcircle", "329E", + "ideographicreachparen", "3243", + "ideographicrepresentparen", "3239", + "ideographicresourceparen", "323E", + "ideographicrightcircle", "32A8", + "ideographicsecretcircle", "3299", + "ideographicselfparen", "3242", + "ideographicsocietyparen", "3233", + "ideographicspace", "3000", + "ideographicspecialparen", "3235", + "ideographicstockparen", "3231", + "ideographicstudyparen", "323B", + "ideographicsunparen", "3230", + "ideographicsuperviseparen", "323C", + "ideographicwaterparen", "322C", + "ideographicwoodparen", "322D", + "ideographiczero", "3007", + "ideographmetalcircle", "328E", + "ideographmooncircle", "328A", + "ideographnamecircle", "3294", + "ideographsuncircle", "3290", + "ideographwatercircle", "328C", + "ideographwoodcircle", "328D", + "ideva", "0907", + "idieresis", "00EF", + "idieresisacute", "1E2F", + "idieresiscyrillic", "04E5", + "idotbelow", "1ECB", + "iebrevecyrillic", "04D7", + "iecyrillic", "0435", + "ieungacirclekorean", "3275", + "ieungaparenkorean", "3215", + "ieungcirclekorean", "3267", + "ieungkorean", "3147", + "ieungparenkorean", "3207", + "igrave", "00EC", + "igujarati", "0A87", + "igurmukhi", "0A07", + "ihiragana", "3044", + "ihookabove", "1EC9", + "iibengali", "0988", + "iicyrillic", "0438", + "iideva", "0908", + "iigujarati", "0A88", + "iigurmukhi", "0A08", + "iimatragurmukhi", "0A40", + "iinvertedbreve", "020B", + "iishortcyrillic", "0439", + "iivowelsignbengali", "09C0", + "iivowelsigndeva", "0940", + "iivowelsigngujarati", "0AC0", + "ij", "0133", + "ikatakana", "30A4", + "ikatakanahalfwidth", "FF72", + "ikorean", "3163", + "ilde", "02DC", + "iluyhebrew", "05AC", + "imacron", "012B", + "imacroncyrillic", "04E3", + "imageorapproximatelyequal", "2253", + "imatragurmukhi", "0A3F", + "imonospace", "FF49", + "increment", "2206", + "infinity", "221E", + "iniarmenian", "056B", + "integral", "222B", + "integralbottom", "2321", + "integralbt", "2321", + "integraltop", "2320", + "integraltp", "2320", + "intersection", "2229", + "intisquare", "3305", + "invbullet", "25D8", + "invcircle", "25D9", + "invsmileface", "263B", + "iocyrillic", "0451", + "iogonek", "012F", + "iota", "03B9", + "iotadieresis", "03CA", + "iotadieresistonos", "0390", + "iotalatin", "0269", + "iotatonos", "03AF", + "iparen", "24A4", + "irigurmukhi", "0A72", + "ismallhiragana", "3043", + "ismallkatakana", "30A3", + "ismallkatakanahalfwidth", "FF68", + "issharbengali", "09FA", + "istroke", "0268", + "iterationhiragana", "309D", + "iterationkatakana", "30FD", + "itilde", "0129", + "itildebelow", "1E2D", + "iubopomofo", "3129", + "iucyrillic", "044E", + "ivowelsignbengali", "09BF", + "ivowelsigndeva", "093F", + "ivowelsigngujarati", "0ABF", + "izhitsacyrillic", "0475", + "izhitsadblgravecyrillic", "0477", + "j", "006A", + "jaarmenian", "0571", + "jabengali", "099C", + "jadeva", "091C", + "jagujarati", "0A9C", + "jagurmukhi", "0A1C", + "jbopomofo", "3110", + "jcaron", "01F0", + "jcircle", "24D9", + "jcircumflex", "0135", + "jcrossedtail", "029D", + "jdotlessstroke", "025F", + "jecyrillic", "0458", + "jeemarabic", "062C", + "jeemfinalarabic", "FE9E", + "jeeminitialarabic", "FE9F", + "jeemmedialarabic", "FEA0", + "jeharabic", "0698", + "jehfinalarabic", "FB8B", + "jhabengali", "099D", + "jhadeva", "091D", + "jhagujarati", "0A9D", + "jhagurmukhi", "0A1D", + "jheharmenian", "057B", + "jis", "3004", + "jmonospace", "FF4A", + "jparen", "24A5", + "jsuperior", "02B2", + "k", "006B", + "kabashkircyrillic", "04A1", + "kabengali", "0995", + "kacute", "1E31", + "kacyrillic", "043A", + "kadescendercyrillic", "049B", + "kadeva", "0915", + "kaf", "05DB", + "kafarabic", "0643", + "kafdagesh", "FB3B", + "kafdageshhebrew", "FB3B", + "kaffinalarabic", "FEDA", + "kafhebrew", "05DB", + "kafinitialarabic", "FEDB", + "kafmedialarabic", "FEDC", + "kafrafehebrew", "FB4D", + "kagujarati", "0A95", + "kagurmukhi", "0A15", + "kahiragana", "304B", + "kahookcyrillic", "04C4", + "kakatakana", "30AB", + "kakatakanahalfwidth", "FF76", + "kappa", "03BA", + "kappasymbolgreek", "03F0", + "kapyeounmieumkorean", "3171", + "kapyeounphieuphkorean", "3184", + "kapyeounpieupkorean", "3178", + "kapyeounssangpieupkorean", "3179", + "karoriisquare", "330D", + "kashidaautoarabic", "0640", + "kashidaautonosidebearingarabic", "0640", + "kasmallkatakana", "30F5", + "kasquare", "3384", + "kasraarabic", "0650", + "kasratanarabic", "064D", + "kastrokecyrillic", "049F", + "katahiraprolongmarkhalfwidth", "FF70", + "kaverticalstrokecyrillic", "049D", + "kbopomofo", "310E", + "kcalsquare", "3389", + "kcaron", "01E9", + "kcedilla", "0137", + "kcircle", "24DA", + "kcommaaccent", "0137", + "kdotbelow", "1E33", + "keharmenian", "0584", + "kehiragana", "3051", + "kekatakana", "30B1", + "kekatakanahalfwidth", "FF79", + "kenarmenian", "056F", + "kesmallkatakana", "30F6", + "kgreenlandic", "0138", + "khabengali", "0996", + "khacyrillic", "0445", + "khadeva", "0916", + "khagujarati", "0A96", + "khagurmukhi", "0A16", + "khaharabic", "062E", + "khahfinalarabic", "FEA6", + "khahinitialarabic", "FEA7", + "khahmedialarabic", "FEA8", + "kheicoptic", "03E7", + "khhadeva", "0959", + "khhagurmukhi", "0A59", + "khieukhacirclekorean", "3278", + "khieukhaparenkorean", "3218", + "khieukhcirclekorean", "326A", + "khieukhkorean", "314B", + "khieukhparenkorean", "320A", + "khokhaithai", "0E02", + "khokhonthai", "0E05", + "khokhuatthai", "0E03", + "khokhwaithai", "0E04", + "khomutthai", "0E5B", + "khook", "0199", + "khorakhangthai", "0E06", + "khzsquare", "3391", + "kihiragana", "304D", + "kikatakana", "30AD", + "kikatakanahalfwidth", "FF77", + "kiroguramusquare", "3315", + "kiromeetorusquare", "3316", + "kirosquare", "3314", + "kiyeokacirclekorean", "326E", + "kiyeokaparenkorean", "320E", + "kiyeokcirclekorean", "3260", + "kiyeokkorean", "3131", + "kiyeokparenkorean", "3200", + "kiyeoksioskorean", "3133", + "kjecyrillic", "045C", + "klinebelow", "1E35", + "klsquare", "3398", + "kmcubedsquare", "33A6", + "kmonospace", "FF4B", + "kmsquaredsquare", "33A2", + "kohiragana", "3053", + "kohmsquare", "33C0", + "kokaithai", "0E01", + "kokatakana", "30B3", + "kokatakanahalfwidth", "FF7A", + "kooposquare", "331E", + "koppacyrillic", "0481", + "koreanstandardsymbol", "327F", + "koroniscmb", "0343", + "kparen", "24A6", + "kpasquare", "33AA", + "ksicyrillic", "046F", + "ktsquare", "33CF", + "kturned", "029E", + "kuhiragana", "304F", + "kukatakana", "30AF", + "kukatakanahalfwidth", "FF78", + "kvsquare", "33B8", + "kwsquare", "33BE", + "l", "006C", + "labengali", "09B2", + "lacute", "013A", + "ladeva", "0932", + "lagujarati", "0AB2", + "lagurmukhi", "0A32", + "lakkhangyaothai", "0E45", + "lamaleffinalarabic", "FEFC", + "lamalefhamzaabovefinalarabic", "FEF8", + "lamalefhamzaaboveisolatedarabic", "FEF7", + "lamalefhamzabelowfinalarabic", "FEFA", + "lamalefhamzabelowisolatedarabic", "FEF9", + "lamalefisolatedarabic", "FEFB", + "lamalefmaddaabovefinalarabic", "FEF6", + "lamalefmaddaaboveisolatedarabic", "FEF5", + "lamarabic", "0644", + "lambda", "03BB", + "lambdastroke", "019B", + "lamed", "05DC", + "lameddagesh", "FB3C", + "lameddageshhebrew", "FB3C", + "lamedhebrew", "05DC", + "lamedholam", "05DC_05B9", + "lamedholamdagesh", "05DC_05B9_05BC", + "lamedholamdageshhebrew", "05DC_05B9_05BC", + "lamedholamhebrew", "05DC_05B9", + "lamfinalarabic", "FEDE", + "lamhahinitialarabic", "FCCA", + "laminitialarabic", "FEDF", + "lamjeeminitialarabic", "FCC9", + "lamkhahinitialarabic", "FCCB", + "lamlamhehisolatedarabic", "FDF2", + "lammedialarabic", "FEE0", + "lammeemhahinitialarabic", "FD88", + "lammeeminitialarabic", "FCCC", + "lammeemjeeminitialarabic", "FEDF_FEE4_FEA0", + "lammeemkhahinitialarabic", "FEDF_FEE4_FEA8", + "largecircle", "25EF", + "lbar", "019A", + "lbelt", "026C", + "lbopomofo", "310C", + "lcaron", "013E", + "lcedilla", "013C", + "lcircle", "24DB", + "lcircumflexbelow", "1E3D", + "lcommaaccent", "013C", + "ldot", "0140", + "ldotaccent", "0140", + "ldotbelow", "1E37", + "ldotbelowmacron", "1E39", + "leftangleabovecmb", "031A", + "lefttackbelowcmb", "0318", + "less", "003C", + "lessequal", "2264", + "lessequalorgreater", "22DA", + "lessmonospace", "FF1C", + "lessorequivalent", "2272", + "lessorgreater", "2276", + "lessoverequal", "2266", + "lesssmall", "FE64", + "lezh", "026E", + "lfblock", "258C", + "lhookretroflex", "026D", + "lira", "20A4", + "liwnarmenian", "056C", + "lj", "01C9", + "ljecyrillic", "0459", + "lladeva", "0933", + "llagujarati", "0AB3", + "llinebelow", "1E3B", + "llladeva", "0934", + "llvocalicbengali", "09E1", + "llvocalicdeva", "0961", + "llvocalicvowelsignbengali", "09E3", + "llvocalicvowelsigndeva", "0963", + "lmiddletilde", "026B", + "lmonospace", "FF4C", + "lmsquare", "33D0", + "lochulathai", "0E2C", + "logicaland", "2227", + "logicalnot", "00AC", + "logicalnotreversed", "2310", + "logicalor", "2228", + "lolingthai", "0E25", + "longs", "017F", + "lowlinecenterline", "FE4E", + "lowlinecmb", "0332", + "lowlinedashed", "FE4D", + "lozenge", "25CA", + "lparen", "24A7", + "lslash", "0142", + "lsquare", "2113", + "ltshade", "2591", + "luthai", "0E26", + "lvocalicbengali", "098C", + "lvocalicdeva", "090C", + "lvocalicvowelsignbengali", "09E2", + "lvocalicvowelsigndeva", "0962", + "lxsquare", "33D3", + "m", "006D", + "mabengali", "09AE", + "macron", "00AF", + "macronbelowcmb", "0331", + "macroncmb", "0304", + "macronlowmod", "02CD", + "macronmonospace", "FFE3", + "macute", "1E3F", + "madeva", "092E", + "magujarati", "0AAE", + "magurmukhi", "0A2E", + "mahapakhhebrew", "05A4", + "mahapakhlefthebrew", "05A4", + "mahiragana", "307E", + "maichattawathai", "0E4B", + "maiekthai", "0E48", + "maihanakatthai", "0E31", + "maitaikhuthai", "0E47", + "maithothai", "0E49", + "maitrithai", "0E4A", + "maiyamokthai", "0E46", + "makatakana", "30DE", + "makatakanahalfwidth", "FF8F", + "male", "2642", + "mansyonsquare", "3347", + "maqafhebrew", "05BE", + "mars", "2642", + "masoracirclehebrew", "05AF", + "masquare", "3383", + "mbopomofo", "3107", + "mbsquare", "33D4", + "mcircle", "24DC", + "mcubedsquare", "33A5", + "mdotaccent", "1E41", + "mdotbelow", "1E43", + "meemarabic", "0645", + "meemfinalarabic", "FEE2", + "meeminitialarabic", "FEE3", + "meemmedialarabic", "FEE4", + "meemmeeminitialarabic", "FCD1", + "meemmeemisolatedarabic", "FC48", + "meetorusquare", "334D", + "mehiragana", "3081", + "meizierasquare", "337E", + "mekatakana", "30E1", + "mekatakanahalfwidth", "FF92", + "mem", "05DE", + "memdagesh", "FB3E", + "memdageshhebrew", "FB3E", + "memhebrew", "05DE", + "menarmenian", "0574", + "merkhahebrew", "05A5", + "merkhakefulahebrew", "05A6", + "merkhakefulalefthebrew", "05A6", + "merkhalefthebrew", "05A5", + "mhook", "0271", + "mhzsquare", "3392", + "middledotkatakanahalfwidth", "FF65", + "middot", "00B7", + "mieumacirclekorean", "3272", + "mieumaparenkorean", "3212", + "mieumcirclekorean", "3264", + "mieumkorean", "3141", + "mieumpansioskorean", "3170", + "mieumparenkorean", "3204", + "mieumpieupkorean", "316E", + "mieumsioskorean", "316F", + "mihiragana", "307F", + "mikatakana", "30DF", + "mikatakanahalfwidth", "FF90", + "minus", "2212", + "minusbelowcmb", "0320", + "minuscircle", "2296", + "minusmod", "02D7", + "minusplus", "2213", + "minute", "2032", + "miribaarusquare", "334A", + "mirisquare", "3349", + "mlonglegturned", "0270", + "mlsquare", "3396", + "mmcubedsquare", "33A3", + "mmonospace", "FF4D", + "mmsquaredsquare", "339F", + "mohiragana", "3082", + "mohmsquare", "33C1", + "mokatakana", "30E2", + "mokatakanahalfwidth", "FF93", + "molsquare", "33D6", + "momathai", "0E21", + "moverssquare", "33A7", + "moverssquaredsquare", "33A8", + "mparen", "24A8", + "mpasquare", "33AB", + "mssquare", "33B3", + "mturned", "026F", + "mu", "03BC", # groff: not U+00B5 + "mu1", "00B5", + "muasquare", "3382", + "muchgreater", "226B", + "muchless", "226A", + "mufsquare", "338C", + "mugreek", "03BC", + "mugsquare", "338D", + "muhiragana", "3080", + "mukatakana", "30E0", + "mukatakanahalfwidth", "FF91", + "mulsquare", "3395", + "multiply", "00D7", + "mumsquare", "339B", + "munahhebrew", "05A3", + "munahlefthebrew", "05A3", + "musicalnote", "266A", + "musicalnotedbl", "266B", + "musicflatsign", "266D", + "musicsharpsign", "266F", + "mussquare", "33B2", + "muvsquare", "33B6", + "muwsquare", "33BC", + "mvmegasquare", "33B9", + "mvsquare", "33B7", + "mwmegasquare", "33BF", + "mwsquare", "33BD", + "n", "006E", + "nabengali", "09A8", + "nabla", "2207", + "nacute", "0144", + "nadeva", "0928", + "nagujarati", "0AA8", + "nagurmukhi", "0A28", + "nahiragana", "306A", + "nakatakana", "30CA", + "nakatakanahalfwidth", "FF85", + "napostrophe", "0149", + "nasquare", "3381", + "nbopomofo", "310B", + "nbspace", "00A0", + "ncaron", "0148", + "ncedilla", "0146", + "ncircle", "24DD", + "ncircumflexbelow", "1E4B", + "ncommaaccent", "0146", + "ndotaccent", "1E45", + "ndotbelow", "1E47", + "nehiragana", "306D", + "nekatakana", "30CD", + "nekatakanahalfwidth", "FF88", + "newsheqelsign", "20AA", + "nfsquare", "338B", + "ngabengali", "0999", + "ngadeva", "0919", + "ngagujarati", "0A99", + "ngagurmukhi", "0A19", + "ngonguthai", "0E07", + "nhiragana", "3093", + "nhookleft", "0272", + "nhookretroflex", "0273", + "nieunacirclekorean", "326F", + "nieunaparenkorean", "320F", + "nieuncieuckorean", "3135", + "nieuncirclekorean", "3261", + "nieunhieuhkorean", "3136", + "nieunkorean", "3134", + "nieunpansioskorean", "3168", + "nieunparenkorean", "3201", + "nieunsioskorean", "3167", + "nieuntikeutkorean", "3166", + "nihiragana", "306B", + "nikatakana", "30CB", + "nikatakanahalfwidth", "FF86", + "nikhahitthai", "0E4D", + "nine", "0039", + "ninearabic", "0669", + "ninebengali", "09EF", + "ninecircle", "2468", + "ninecircleinversesansserif", "2792", + "ninedeva", "096F", + "ninegujarati", "0AEF", + "ninegurmukhi", "0A6F", + "ninehackarabic", "0669", + "ninehangzhou", "3029", + "nineideographicparen", "3228", + "nineinferior", "2089", + "ninemonospace", "FF19", + "nineparen", "247C", + "nineperiod", "2490", + "ninepersian", "06F9", + "nineroman", "2178", + "ninesuperior", "2079", + "nineteencircle", "2472", + "nineteenparen", "2486", + "nineteenperiod", "249A", + "ninethai", "0E59", + "nj", "01CC", + "njecyrillic", "045A", + "nkatakana", "30F3", + "nkatakanahalfwidth", "FF9D", + "nlegrightlong", "019E", + "nlinebelow", "1E49", + "nmonospace", "FF4E", + "nmsquare", "339A", + "nnabengali", "09A3", + "nnadeva", "0923", + "nnagujarati", "0AA3", + "nnagurmukhi", "0A23", + "nnnadeva", "0929", + "nohiragana", "306E", + "nokatakana", "30CE", + "nokatakanahalfwidth", "FF89", + "nonbreakingspace", "00A0", + "nonenthai", "0E13", + "nonuthai", "0E19", + "noonarabic", "0646", + "noonfinalarabic", "FEE6", + "noonghunnaarabic", "06BA", + "noonghunnafinalarabic", "FB9F", + "noonhehinitialarabic", "FEE7_FEEC", + "nooninitialarabic", "FEE7", + "noonjeeminitialarabic", "FCD2", + "noonjeemisolatedarabic", "FC4B", + "noonmedialarabic", "FEE8", + "noonmeeminitialarabic", "FCD5", + "noonmeemisolatedarabic", "FC4E", + "noonnoonfinalarabic", "FC8D", + "notcontains", "220C", + "notelement", "2209", + "notelementof", "2209", + "notequal", "2260", + "notgreater", "226F", + "notgreaternorequal", "2271", + "notgreaternorless", "2279", + "notidentical", "2262", + "notless", "226E", + "notlessnorequal", "2270", + "notparallel", "2226", + "notprecedes", "2280", + "notsubset", "2284", + "notsucceeds", "2281", + "notsuperset", "2285", + "nowarmenian", "0576", + "nparen", "24A9", + "nssquare", "33B1", + "nsuperior", "207F", + "ntilde", "00F1", + "nu", "03BD", + "nuhiragana", "306C", + "nukatakana", "30CC", + "nukatakanahalfwidth", "FF87", + "nuktabengali", "09BC", + "nuktadeva", "093C", + "nuktagujarati", "0ABC", + "nuktagurmukhi", "0A3C", + "numbersign", "0023", + "numbersignmonospace", "FF03", + "numbersignsmall", "FE5F", + "numeralsigngreek", "0374", + "numeralsignlowergreek", "0375", + "numero", "2116", + "nun", "05E0", + "nundagesh", "FB40", + "nundageshhebrew", "FB40", + "nunhebrew", "05E0", + "nvsquare", "33B5", + "nwsquare", "33BB", + "nyabengali", "099E", + "nyadeva", "091E", + "nyagujarati", "0A9E", + "nyagurmukhi", "0A1E", + "o", "006F", + "oacute", "00F3", + "oangthai", "0E2D", + "obarred", "0275", + "obarredcyrillic", "04E9", + "obarreddieresiscyrillic", "04EB", + "obengali", "0993", + "obopomofo", "311B", + "obreve", "014F", + "ocandradeva", "0911", + "ocandragujarati", "0A91", + "ocandravowelsigndeva", "0949", + "ocandravowelsigngujarati", "0AC9", + "ocaron", "01D2", + "ocircle", "24DE", + "ocircumflex", "00F4", + "ocircumflexacute", "1ED1", + "ocircumflexdotbelow", "1ED9", + "ocircumflexgrave", "1ED3", + "ocircumflexhookabove", "1ED5", + "ocircumflextilde", "1ED7", + "ocyrillic", "043E", + "odblacute", "0151", + "odblgrave", "020D", + "odeva", "0913", + "odieresis", "00F6", + "odieresiscyrillic", "04E7", + "odotbelow", "1ECD", + "oe", "0153", + "oekorean", "315A", + "ogonek", "02DB", + "ogonekcmb", "0328", + "ograve", "00F2", + "ogujarati", "0A93", + "oharmenian", "0585", + "ohiragana", "304A", + "ohookabove", "1ECF", + "ohorn", "01A1", + "ohornacute", "1EDB", + "ohorndotbelow", "1EE3", + "ohorngrave", "1EDD", + "ohornhookabove", "1EDF", + "ohorntilde", "1EE1", + "ohungarumlaut", "0151", + "oi", "01A3", + "oinvertedbreve", "020F", + "okatakana", "30AA", + "okatakanahalfwidth", "FF75", + "okorean", "3157", + "olehebrew", "05AB", + "omacron", "014D", + "omacronacute", "1E53", + "omacrongrave", "1E51", + "omdeva", "0950", + "omega", "03C9", + "omega1", "03D6", + "omegacyrillic", "0461", + "omegalatinclosed", "0277", + "omegaroundcyrillic", "047B", + "omegatitlocyrillic", "047D", + "omegatonos", "03CE", + "omgujarati", "0AD0", + "omicron", "03BF", + "omicrontonos", "03CC", + "omonospace", "FF4F", + "one", "0031", + "onearabic", "0661", + "onebengali", "09E7", + "onecircle", "2460", + "onecircleinversesansserif", "278A", + "onedeva", "0967", + "onedotenleader", "2024", + "oneeighth", "215B", + "onegujarati", "0AE7", + "onegurmukhi", "0A67", + "onehackarabic", "0661", + "onehalf", "00BD", + "onehangzhou", "3021", + "oneideographicparen", "3220", + "oneinferior", "2081", + "onemonospace", "FF11", + "onenumeratorbengali", "09F4", + "oneparen", "2474", + "oneperiod", "2488", + "onepersian", "06F1", + "onequarter", "00BC", + "oneroman", "2170", + "onesuperior", "00B9", + "onethai", "0E51", + "onethird", "2153", + "oogonek", "01EB", + "oogonekmacron", "01ED", + "oogurmukhi", "0A13", + "oomatragurmukhi", "0A4B", + "oopen", "0254", + "oparen", "24AA", + "openbullet", "25E6", + "option", "2325", + "ordfeminine", "00AA", + "ordmasculine", "00BA", + "orthogonal", "221F", + "oshortdeva", "0912", + "oshortvowelsigndeva", "094A", + "oslash", "00F8", + "oslashacute", "01FF", + "osmallhiragana", "3049", + "osmallkatakana", "30A9", + "osmallkatakanahalfwidth", "FF6B", + "ostrokeacute", "01FF", + "otcyrillic", "047F", + "otilde", "00F5", + "otildeacute", "1E4D", + "otildedieresis", "1E4F", + "oubopomofo", "3121", + "overline", "203E", + "overlinecenterline", "FE4A", + "overlinecmb", "0305", + "overlinedashed", "FE49", + "overlinedblwavy", "FE4C", + "overlinewavy", "FE4B", + "overscore", "00AF", + "ovowelsignbengali", "09CB", + "ovowelsigndeva", "094B", + "ovowelsigngujarati", "0ACB", + "p", "0070", + "paampssquare", "3380", + "paasentosquare", "332B", + "pabengali", "09AA", + "pacute", "1E55", + "padeva", "092A", + "pagedown", "21DF", + "pageup", "21DE", + "pagujarati", "0AAA", + "pagurmukhi", "0A2A", + "pahiragana", "3071", + "paiyannoithai", "0E2F", + "pakatakana", "30D1", + "palatalizationcyrilliccmb", "0484", + "palochkacyrillic", "04C0", + "pansioskorean", "317F", + "paragraph", "00B6", + "parallel", "2225", + "parenleft", "0028", + "parenleftaltonearabic", "FD3E", + "parenleftinferior", "208D", + "parenleftmonospace", "FF08", + "parenleftsmall", "FE59", + "parenleftsuperior", "207D", + "parenleftvertical", "FE35", + "parenright", "0029", + "parenrightaltonearabic", "FD3F", + "parenrightinferior", "208E", + "parenrightmonospace", "FF09", + "parenrightsmall", "FE5A", + "parenrightsuperior", "207E", + "parenrightvertical", "FE36", + "partialdiff", "2202", + "paseqhebrew", "05C0", + "pashtahebrew", "0599", + "pasquare", "33A9", + "patah", "05B7", + "patah11", "05B7", + "patah1d", "05B7", + "patah2a", "05B7", + "patahhebrew", "05B7", + "patahnarrowhebrew", "05B7", + "patahquarterhebrew", "05B7", + "patahwidehebrew", "05B7", + "pazerhebrew", "05A1", + "pbopomofo", "3106", + "pcircle", "24DF", + "pdotaccent", "1E57", + "pe", "05E4", + "pecyrillic", "043F", + "pedagesh", "FB44", + "pedageshhebrew", "FB44", + "peezisquare", "333B", + "pefinaldageshhebrew", "FB43", + "peharabic", "067E", + "peharmenian", "057A", + "pehebrew", "05E4", + "pehfinalarabic", "FB57", + "pehinitialarabic", "FB58", + "pehiragana", "307A", + "pehmedialarabic", "FB59", + "pekatakana", "30DA", + "pemiddlehookcyrillic", "04A7", + "perafehebrew", "FB4E", + "percent", "0025", + "percentarabic", "066A", + "percentmonospace", "FF05", + "percentsmall", "FE6A", + "period", "002E", + "periodarmenian", "0589", + "periodcentered", "00B7", + "periodhalfwidth", "FF61", + "periodmonospace", "FF0E", + "periodsmall", "FE52", + "perispomenigreekcmb", "0342", + "perpendicular", "22A5", + "perthousand", "2030", + "peseta", "20A7", + "pfsquare", "338A", + "phabengali", "09AB", + "phadeva", "092B", + "phagujarati", "0AAB", + "phagurmukhi", "0A2B", + "phi", "03C6", + "phi1", "03D5", + "phieuphacirclekorean", "327A", + "phieuphaparenkorean", "321A", + "phieuphcirclekorean", "326C", + "phieuphkorean", "314D", + "phieuphparenkorean", "320C", + "philatin", "0278", + "phinthuthai", "0E3A", + "phisymbolgreek", "03D5", + "phook", "01A5", + "phophanthai", "0E1E", + "phophungthai", "0E1C", + "phosamphaothai", "0E20", + "pi", "03C0", + "pieupacirclekorean", "3273", + "pieupaparenkorean", "3213", + "pieupcieuckorean", "3176", + "pieupcirclekorean", "3265", + "pieupkiyeokkorean", "3172", + "pieupkorean", "3142", + "pieupparenkorean", "3205", + "pieupsioskiyeokkorean", "3174", + "pieupsioskorean", "3144", + "pieupsiostikeutkorean", "3175", + "pieupthieuthkorean", "3177", + "pieuptikeutkorean", "3173", + "pihiragana", "3074", + "pikatakana", "30D4", + "pisymbolgreek", "03D6", + "piwrarmenian", "0583", + "plus", "002B", + "plusbelowcmb", "031F", + "pluscircle", "2295", + "plusminus", "00B1", + "plusmod", "02D6", + "plusmonospace", "FF0B", + "plussmall", "FE62", + "plussuperior", "207A", + "pmonospace", "FF50", + "pmsquare", "33D8", + "pohiragana", "307D", + "pointingindexdownwhite", "261F", + "pointingindexleftwhite", "261C", + "pointingindexrightwhite", "261E", + "pointingindexupwhite", "261D", + "pokatakana", "30DD", + "poplathai", "0E1B", + "postalmark", "3012", + "postalmarkface", "3020", + "pparen", "24AB", + "precedes", "227A", + "prescription", "211E", + "primemod", "02B9", + "primereversed", "2035", + "product", "220F", + "projective", "2305", + "prolongedkana", "30FC", + "propellor", "2318", + "propersubset", "2282", + "propersuperset", "2283", + "proportion", "2237", + "proportional", "221D", + "psi", "03C8", + "psicyrillic", "0471", + "psilipneumatacyrilliccmb", "0486", + "pssquare", "33B0", + "puhiragana", "3077", + "pukatakana", "30D7", + "pvsquare", "33B4", + "pwsquare", "33BA", + "q", "0071", + "qadeva", "0958", + "qadmahebrew", "05A8", + "qafarabic", "0642", + "qaffinalarabic", "FED6", + "qafinitialarabic", "FED7", + "qafmedialarabic", "FED8", + "qamats", "05B8", + "qamats10", "05B8", + "qamats1a", "05B8", + "qamats1c", "05B8", + "qamats27", "05B8", + "qamats29", "05B8", + "qamats33", "05B8", + "qamatsde", "05B8", + "qamatshebrew", "05B8", + "qamatsnarrowhebrew", "05B8", + "qamatsqatanhebrew", "05B8", + "qamatsqatannarrowhebrew", "05B8", + "qamatsqatanquarterhebrew", "05B8", + "qamatsqatanwidehebrew", "05B8", + "qamatsquarterhebrew", "05B8", + "qamatswidehebrew", "05B8", + "qarneyparahebrew", "059F", + "qbopomofo", "3111", + "qcircle", "24E0", + "qhook", "02A0", + "qmonospace", "FF51", + "qof", "05E7", + "qofdagesh", "FB47", + "qofdageshhebrew", "FB47", + "qofhatafpatah", "05E7_05B2", + "qofhatafpatahhebrew", "05E7_05B2", + "qofhatafsegol", "05E7_05B1", + "qofhatafsegolhebrew", "05E7_05B1", + "qofhebrew", "05E7", + "qofhiriq", "05E7_05B4", + "qofhiriqhebrew", "05E7_05B4", + "qofholam", "05E7_05B9", + "qofholamhebrew", "05E7_05B9", + "qofpatah", "05E7_05B7", + "qofpatahhebrew", "05E7_05B7", + "qofqamats", "05E7_05B8", + "qofqamatshebrew", "05E7_05B8", + "qofqubuts", "05E7_05BB", + "qofqubutshebrew", "05E7_05BB", + "qofsegol", "05E7_05B6", + "qofsegolhebrew", "05E7_05B6", + "qofsheva", "05E7_05B0", + "qofshevahebrew", "05E7_05B0", + "qoftsere", "05E7_05B5", + "qoftserehebrew", "05E7_05B5", + "qparen", "24AC", + "quarternote", "2669", + "qubuts", "05BB", + "qubuts18", "05BB", + "qubuts25", "05BB", + "qubuts31", "05BB", + "qubutshebrew", "05BB", + "qubutsnarrowhebrew", "05BB", + "qubutsquarterhebrew", "05BB", + "qubutswidehebrew", "05BB", + "question", "003F", + "questionarabic", "061F", + "questionarmenian", "055E", + "questiondown", "00BF", + "questiongreek", "037E", + "questionmonospace", "FF1F", + "quotedbl", "0022", + "quotedblbase", "201E", + "quotedblleft", "201C", + "quotedblmonospace", "FF02", + "quotedblprime", "301E", + "quotedblprimereversed", "301D", + "quotedblright", "201D", + "quoteleft", "2018", + "quoteleftreversed", "201B", + "quotereversed", "201B", + "quoteright", "2019", + "quoterightn", "0149", + "quotesinglbase", "201A", + "quotesingle", "0027", + "quotesinglemonospace", "FF07", + "r", "0072", + "raarmenian", "057C", + "rabengali", "09B0", + "racute", "0155", + "radeva", "0930", + "radical", "221A", + "radoverssquare", "33AE", + "radoverssquaredsquare", "33AF", + "radsquare", "33AD", + "rafe", "05BF", + "rafehebrew", "05BF", + "ragujarati", "0AB0", + "ragurmukhi", "0A30", + "rahiragana", "3089", + "rakatakana", "30E9", + "rakatakanahalfwidth", "FF97", + "ralowerdiagonalbengali", "09F1", + "ramiddlediagonalbengali", "09F0", + "ramshorn", "0264", + "ratio", "2236", + "rbopomofo", "3116", + "rcaron", "0159", + "rcedilla", "0157", + "rcircle", "24E1", + "rcommaaccent", "0157", + "rdblgrave", "0211", + "rdotaccent", "1E59", + "rdotbelow", "1E5B", + "rdotbelowmacron", "1E5D", + "referencemark", "203B", + "reflexsubset", "2286", + "reflexsuperset", "2287", + "registered", "00AE", + "reharabic", "0631", + "reharmenian", "0580", + "rehfinalarabic", "FEAE", + "rehiragana", "308C", + "rehyehaleflamarabic", "0631_FEF3_FE8E_0644", + "rekatakana", "30EC", + "rekatakanahalfwidth", "FF9A", + "resh", "05E8", + "reshdageshhebrew", "FB48", + "reshhatafpatah", "05E8_05B2", + "reshhatafpatahhebrew", "05E8_05B2", + "reshhatafsegol", "05E8_05B1", + "reshhatafsegolhebrew", "05E8_05B1", + "reshhebrew", "05E8", + "reshhiriq", "05E8_05B4", + "reshhiriqhebrew", "05E8_05B4", + "reshholam", "05E8_05B9", + "reshholamhebrew", "05E8_05B9", + "reshpatah", "05E8_05B7", + "reshpatahhebrew", "05E8_05B7", + "reshqamats", "05E8_05B8", + "reshqamatshebrew", "05E8_05B8", + "reshqubuts", "05E8_05BB", + "reshqubutshebrew", "05E8_05BB", + "reshsegol", "05E8_05B6", + "reshsegolhebrew", "05E8_05B6", + "reshsheva", "05E8_05B0", + "reshshevahebrew", "05E8_05B0", + "reshtsere", "05E8_05B5", + "reshtserehebrew", "05E8_05B5", + "reversedtilde", "223D", + "reviahebrew", "0597", + "reviamugrashhebrew", "0597", + "revlogicalnot", "2310", + "rfishhook", "027E", + "rfishhookreversed", "027F", + "rhabengali", "09DD", + "rhadeva", "095D", + "rho", "03C1", + "rhook", "027D", + "rhookturned", "027B", + "rhookturnedsuperior", "02B5", + "rhosymbolgreek", "03F1", + "rhotichookmod", "02DE", + "rieulacirclekorean", "3271", + "rieulaparenkorean", "3211", + "rieulcirclekorean", "3263", + "rieulhieuhkorean", "3140", + "rieulkiyeokkorean", "313A", + "rieulkiyeoksioskorean", "3169", + "rieulkorean", "3139", + "rieulmieumkorean", "313B", + "rieulpansioskorean", "316C", + "rieulparenkorean", "3203", + "rieulphieuphkorean", "313F", + "rieulpieupkorean", "313C", + "rieulpieupsioskorean", "316B", + "rieulsioskorean", "313D", + "rieulthieuthkorean", "313E", + "rieultikeutkorean", "316A", + "rieulyeorinhieuhkorean", "316D", + "rightangle", "221F", + "righttackbelowcmb", "0319", + "righttriangle", "22BF", + "rihiragana", "308A", + "rikatakana", "30EA", + "rikatakanahalfwidth", "FF98", + "ring", "02DA", + "ringbelowcmb", "0325", + "ringcmb", "030A", + "ringhalfleft", "02BF", + "ringhalfleftarmenian", "0559", + "ringhalfleftbelowcmb", "031C", + "ringhalfleftcentered", "02D3", + "ringhalfright", "02BE", + "ringhalfrightbelowcmb", "0339", + "ringhalfrightcentered", "02D2", + "rinvertedbreve", "0213", + "rittorusquare", "3351", + "rlinebelow", "1E5F", + "rlongleg", "027C", + "rlonglegturned", "027A", + "rmonospace", "FF52", + "rohiragana", "308D", + "rokatakana", "30ED", + "rokatakanahalfwidth", "FF9B", + "roruathai", "0E23", + "rparen", "24AD", + "rrabengali", "09DC", + "rradeva", "0931", + "rragurmukhi", "0A5C", + "rreharabic", "0691", + "rrehfinalarabic", "FB8D", + "rrvocalicbengali", "09E0", + "rrvocalicdeva", "0960", + "rrvocalicgujarati", "0AE0", + "rrvocalicvowelsignbengali", "09C4", + "rrvocalicvowelsigndeva", "0944", + "rrvocalicvowelsigngujarati", "0AC4", + "rtblock", "2590", + "rturned", "0279", + "rturnedsuperior", "02B4", + "ruhiragana", "308B", + "rukatakana", "30EB", + "rukatakanahalfwidth", "FF99", + "rupeemarkbengali", "09F2", + "rupeesignbengali", "09F3", + "ruthai", "0E24", + "rvocalicbengali", "098B", + "rvocalicdeva", "090B", + "rvocalicgujarati", "0A8B", + "rvocalicvowelsignbengali", "09C3", + "rvocalicvowelsigndeva", "0943", + "rvocalicvowelsigngujarati", "0AC3", + "s", "0073", + "sabengali", "09B8", + "sacute", "015B", + "sacutedotaccent", "1E65", + "sadarabic", "0635", + "sadeva", "0938", + "sadfinalarabic", "FEBA", + "sadinitialarabic", "FEBB", + "sadmedialarabic", "FEBC", + "sagujarati", "0AB8", + "sagurmukhi", "0A38", + "sahiragana", "3055", + "sakatakana", "30B5", + "sakatakanahalfwidth", "FF7B", + "sallallahoualayhewasallamarabic", "FDFA", + "samekh", "05E1", + "samekhdagesh", "FB41", + "samekhdageshhebrew", "FB41", + "samekhhebrew", "05E1", + "saraaathai", "0E32", + "saraaethai", "0E41", + "saraaimaimalaithai", "0E44", + "saraaimaimuanthai", "0E43", + "saraamthai", "0E33", + "saraathai", "0E30", + "saraethai", "0E40", + "saraiithai", "0E35", + "saraithai", "0E34", + "saraothai", "0E42", + "saraueethai", "0E37", + "sarauethai", "0E36", + "sarauthai", "0E38", + "sarauuthai", "0E39", + "sbopomofo", "3119", + "scaron", "0161", + "scarondotaccent", "1E67", + "scedilla", "015F", + "schwa", "0259", + "schwacyrillic", "04D9", + "schwadieresiscyrillic", "04DB", + "schwahook", "025A", + "scircle", "24E2", + "scircumflex", "015D", + "scommaaccent", "0219", + "sdotaccent", "1E61", + "sdotbelow", "1E63", + "sdotbelowdotaccent", "1E69", + "seagullbelowcmb", "033C", + "second", "2033", + "secondtonechinese", "02CA", + "section", "00A7", + "seenarabic", "0633", + "seenfinalarabic", "FEB2", + "seeninitialarabic", "FEB3", + "seenmedialarabic", "FEB4", + "segol", "05B6", + "segol13", "05B6", + "segol1f", "05B6", + "segol2c", "05B6", + "segolhebrew", "05B6", + "segolnarrowhebrew", "05B6", + "segolquarterhebrew", "05B6", + "segoltahebrew", "0592", + "segolwidehebrew", "05B6", + "seharmenian", "057D", + "sehiragana", "305B", + "sekatakana", "30BB", + "sekatakanahalfwidth", "FF7E", + "semicolon", "003B", + "semicolonarabic", "061B", + "semicolonmonospace", "FF1B", + "semicolonsmall", "FE54", + "semivoicedmarkkana", "309C", + "semivoicedmarkkanahalfwidth", "FF9F", + "sentisquare", "3322", + "sentosquare", "3323", + "seven", "0037", + "sevenarabic", "0667", + "sevenbengali", "09ED", + "sevencircle", "2466", + "sevencircleinversesansserif", "2790", + "sevendeva", "096D", + "seveneighths", "215E", + "sevengujarati", "0AED", + "sevengurmukhi", "0A6D", + "sevenhackarabic", "0667", + "sevenhangzhou", "3027", + "sevenideographicparen", "3226", + "seveninferior", "2087", + "sevenmonospace", "FF17", + "sevenparen", "247A", + "sevenperiod", "248E", + "sevenpersian", "06F7", + "sevenroman", "2176", + "sevensuperior", "2077", + "seventeencircle", "2470", + "seventeenparen", "2484", + "seventeenperiod", "2498", + "seventhai", "0E57", + "sfthyphen", "00AD", + "shaarmenian", "0577", + "shabengali", "09B6", + "shacyrillic", "0448", + "shaddaarabic", "0651", + "shaddadammaarabic", "FC61", + "shaddadammatanarabic", "FC5E", + "shaddafathaarabic", "FC60", + "shaddafathatanarabic", "0651_064B", + "shaddakasraarabic", "FC62", + "shaddakasratanarabic", "FC5F", + "shade", "2592", + "shadedark", "2593", + "shadelight", "2591", + "shademedium", "2592", + "shadeva", "0936", + "shagujarati", "0AB6", + "shagurmukhi", "0A36", + "shalshelethebrew", "0593", + "shbopomofo", "3115", + "shchacyrillic", "0449", + "sheenarabic", "0634", + "sheenfinalarabic", "FEB6", + "sheeninitialarabic", "FEB7", + "sheenmedialarabic", "FEB8", + "sheicoptic", "03E3", + "sheqel", "20AA", + "sheqelhebrew", "20AA", + "sheva", "05B0", + "sheva115", "05B0", + "sheva15", "05B0", + "sheva22", "05B0", + "sheva2e", "05B0", + "shevahebrew", "05B0", + "shevanarrowhebrew", "05B0", + "shevaquarterhebrew", "05B0", + "shevawidehebrew", "05B0", + "shhacyrillic", "04BB", + "shimacoptic", "03ED", + "shin", "05E9", + "shindagesh", "FB49", + "shindageshhebrew", "FB49", + "shindageshshindot", "FB2C", + "shindageshshindothebrew", "FB2C", + "shindageshsindot", "FB2D", + "shindageshsindothebrew", "FB2D", + "shindothebrew", "05C1", + "shinhebrew", "05E9", + "shinshindot", "FB2A", + "shinshindothebrew", "FB2A", + "shinsindot", "FB2B", + "shinsindothebrew", "FB2B", + "shook", "0282", + "sigma", "03C3", + "sigma1", "03C2", + "sigmafinal", "03C2", + "sigmalunatesymbolgreek", "03F2", + "sihiragana", "3057", + "sikatakana", "30B7", + "sikatakanahalfwidth", "FF7C", + "siluqhebrew", "05BD", + "siluqlefthebrew", "05BD", + "similar", "223C", + "sindothebrew", "05C2", + "siosacirclekorean", "3274", + "siosaparenkorean", "3214", + "sioscieuckorean", "317E", + "sioscirclekorean", "3266", + "sioskiyeokkorean", "317A", + "sioskorean", "3145", + "siosnieunkorean", "317B", + "siosparenkorean", "3206", + "siospieupkorean", "317D", + "siostikeutkorean", "317C", + "six", "0036", + "sixarabic", "0666", + "sixbengali", "09EC", + "sixcircle", "2465", + "sixcircleinversesansserif", "278F", + "sixdeva", "096C", + "sixgujarati", "0AEC", + "sixgurmukhi", "0A6C", + "sixhackarabic", "0666", + "sixhangzhou", "3026", + "sixideographicparen", "3225", + "sixinferior", "2086", + "sixmonospace", "FF16", + "sixparen", "2479", + "sixperiod", "248D", + "sixpersian", "06F6", + "sixroman", "2175", + "sixsuperior", "2076", + "sixteencircle", "246F", + "sixteencurrencydenominatorbengali", "09F9", + "sixteenparen", "2483", + "sixteenperiod", "2497", + "sixthai", "0E56", + "slash", "002F", + "slashmonospace", "FF0F", + "slong", "017F", + "slongdotaccent", "1E9B", + "smileface", "263A", + "smonospace", "FF53", + "sofpasuqhebrew", "05C3", + "softhyphen", "00AD", + "softsigncyrillic", "044C", + "sohiragana", "305D", + "sokatakana", "30BD", + "sokatakanahalfwidth", "FF7F", + "soliduslongoverlaycmb", "0338", + "solidusshortoverlaycmb", "0337", + "sorusithai", "0E29", + "sosalathai", "0E28", + "sosothai", "0E0B", + "sosuathai", "0E2A", + "space", "0020", + "spacehackarabic", "0020", + "spade", "2660", + "spadesuitblack", "2660", + "spadesuitwhite", "2664", + "sparen", "24AE", + "squarebelowcmb", "033B", + "squarecc", "33C4", + "squarecm", "339D", + "squarediagonalcrosshatchfill", "25A9", + "squarehorizontalfill", "25A4", + "squarekg", "338F", + "squarekm", "339E", + "squarekmcapital", "33CE", + "squareln", "33D1", + "squarelog", "33D2", + "squaremg", "338E", + "squaremil", "33D5", + "squaremm", "339C", + "squaremsquared", "33A1", + "squareorthogonalcrosshatchfill", "25A6", + "squareupperlefttolowerrightfill", "25A7", + "squareupperrighttolowerleftfill", "25A8", + "squareverticalfill", "25A5", + "squarewhitewithsmallblack", "25A3", + "srsquare", "33DB", + "ssabengali", "09B7", + "ssadeva", "0937", + "ssagujarati", "0AB7", + "ssangcieuckorean", "3149", + "ssanghieuhkorean", "3185", + "ssangieungkorean", "3180", + "ssangkiyeokkorean", "3132", + "ssangnieunkorean", "3165", + "ssangpieupkorean", "3143", + "ssangsioskorean", "3146", + "ssangtikeutkorean", "3138", + "sterling", "00A3", + "sterlingmonospace", "FFE1", + "strokelongoverlaycmb", "0336", + "strokeshortoverlaycmb", "0335", + "subset", "2282", + "subsetnotequal", "228A", + "subsetorequal", "2286", + "succeeds", "227B", + "suchthat", "220B", + "suhiragana", "3059", + "sukatakana", "30B9", + "sukatakanahalfwidth", "FF7D", + "sukunarabic", "0652", + "summation", "2211", + "sun", "263C", + "superset", "2283", + "supersetnotequal", "228B", + "supersetorequal", "2287", + "svsquare", "33DC", + "syouwaerasquare", "337C", + "t", "0074", + "tabengali", "09A4", + "tackdown", "22A4", + "tackleft", "22A3", + "tadeva", "0924", + "tagujarati", "0AA4", + "tagurmukhi", "0A24", + "taharabic", "0637", + "tahfinalarabic", "FEC2", + "tahinitialarabic", "FEC3", + "tahiragana", "305F", + "tahmedialarabic", "FEC4", + "taisyouerasquare", "337D", + "takatakana", "30BF", + "takatakanahalfwidth", "FF80", + "tatweelarabic", "0640", + "tau", "03C4", + "tav", "05EA", + "tavdages", "FB4A", + "tavdagesh", "FB4A", + "tavdageshhebrew", "FB4A", + "tavhebrew", "05EA", + "tbar", "0167", + "tbopomofo", "310A", + "tcaron", "0165", + "tccurl", "02A8", + "tcedilla", "0163", + "tcheharabic", "0686", + "tchehfinalarabic", "FB7B", + "tchehinitialarabic", "FB7C", + "tchehmedialarabic", "FB7D", + "tchehmeeminitialarabic", "FB7C_FEE4", + "tcircle", "24E3", + "tcircumflexbelow", "1E71", + "tcommaaccent", "0163", + "tdieresis", "1E97", + "tdotaccent", "1E6B", + "tdotbelow", "1E6D", + "tecyrillic", "0442", + "tedescendercyrillic", "04AD", + "teharabic", "062A", + "tehfinalarabic", "FE96", + "tehhahinitialarabic", "FCA2", + "tehhahisolatedarabic", "FC0C", + "tehinitialarabic", "FE97", + "tehiragana", "3066", + "tehjeeminitialarabic", "FCA1", + "tehjeemisolatedarabic", "FC0B", + "tehmarbutaarabic", "0629", + "tehmarbutafinalarabic", "FE94", + "tehmedialarabic", "FE98", + "tehmeeminitialarabic", "FCA4", + "tehmeemisolatedarabic", "FC0E", + "tehnoonfinalarabic", "FC73", + "tekatakana", "30C6", + "tekatakanahalfwidth", "FF83", + "telephone", "2121", + "telephoneblack", "260E", + "telishagedolahebrew", "05A0", + "telishaqetanahebrew", "05A9", + "tencircle", "2469", + "tenideographicparen", "3229", + "tenparen", "247D", + "tenperiod", "2491", + "tenroman", "2179", + "tesh", "02A7", + "tet", "05D8", + "tetdagesh", "FB38", + "tetdageshhebrew", "FB38", + "tethebrew", "05D8", + "tetsecyrillic", "04B5", + "tevirhebrew", "059B", + "tevirlefthebrew", "059B", + "thabengali", "09A5", + "thadeva", "0925", + "thagujarati", "0AA5", + "thagurmukhi", "0A25", + "thalarabic", "0630", + "thalfinalarabic", "FEAC", + "thanthakhatthai", "0E4C", + "theharabic", "062B", + "thehfinalarabic", "FE9A", + "thehinitialarabic", "FE9B", + "thehmedialarabic", "FE9C", + "thereexists", "2203", + "therefore", "2234", + "theta", "03B8", + "theta1", "03D1", + "thetasymbolgreek", "03D1", + "thieuthacirclekorean", "3279", + "thieuthaparenkorean", "3219", + "thieuthcirclekorean", "326B", + "thieuthkorean", "314C", + "thieuthparenkorean", "320B", + "thirteencircle", "246C", + "thirteenparen", "2480", + "thirteenperiod", "2494", + "thonangmonthothai", "0E11", + "thook", "01AD", + "thophuthaothai", "0E12", + "thorn", "00FE", + "thothahanthai", "0E17", + "thothanthai", "0E10", + "thothongthai", "0E18", + "thothungthai", "0E16", + "thousandcyrillic", "0482", + "thousandsseparatorarabic", "066C", + "thousandsseparatorpersian", "066C", + "three", "0033", + "threearabic", "0663", + "threebengali", "09E9", + "threecircle", "2462", + "threecircleinversesansserif", "278C", + "threedeva", "0969", + "threeeighths", "215C", + "threegujarati", "0AE9", + "threegurmukhi", "0A69", + "threehackarabic", "0663", + "threehangzhou", "3023", + "threeideographicparen", "3222", + "threeinferior", "2083", + "threemonospace", "FF13", + "threenumeratorbengali", "09F6", + "threeparen", "2476", + "threeperiod", "248A", + "threepersian", "06F3", + "threequarters", "00BE", + "threeroman", "2172", + "threesuperior", "00B3", + "threethai", "0E53", + "thzsquare", "3394", + "tihiragana", "3061", + "tikatakana", "30C1", + "tikatakanahalfwidth", "FF81", + "tikeutacirclekorean", "3270", + "tikeutaparenkorean", "3210", + "tikeutcirclekorean", "3262", + "tikeutkorean", "3137", + "tikeutparenkorean", "3202", + "tilde", "02DC", + "tildebelowcmb", "0330", + "tildecmb", "0303", + "tildecomb", "0303", + "tildedoublecmb", "0360", + "tildeoperator", "223C", + "tildeoverlaycmb", "0334", + "tildeverticalcmb", "033E", + "timescircle", "2297", + "tipehahebrew", "0596", + "tipehalefthebrew", "0596", + "tippigurmukhi", "0A70", + "titlocyrilliccmb", "0483", + "tiwnarmenian", "057F", + "tlinebelow", "1E6F", + "tmonospace", "FF54", + "toarmenian", "0569", + "tohiragana", "3068", + "tokatakana", "30C8", + "tokatakanahalfwidth", "FF84", + "tonebarextrahighmod", "02E5", + "tonebarextralowmod", "02E9", + "tonebarhighmod", "02E6", + "tonebarlowmod", "02E8", + "tonebarmidmod", "02E7", + "tonefive", "01BD", + "tonesix", "0185", + "tonetwo", "01A8", + "tonos", "0384", + "tonsquare", "3327", + "topatakthai", "0E0F", + "tortoiseshellbracketleft", "3014", + "tortoiseshellbracketleftsmall", "FE5D", + "tortoiseshellbracketleftvertical", "FE39", + "tortoiseshellbracketright", "3015", + "tortoiseshellbracketrightsmall", "FE5E", + "tortoiseshellbracketrightvertical", "FE3A", + "totaothai", "0E15", + "tpalatalhook", "01AB", + "tparen", "24AF", + "trademark", "2122", + "tretroflexhook", "0288", + "triagdn", "25BC", + "triaglf", "25C4", + "triagrt", "25BA", + "triagup", "25B2", + "ts", "02A6", + "tsadi", "05E6", + "tsadidagesh", "FB46", + "tsadidageshhebrew", "FB46", + "tsadihebrew", "05E6", + "tsecyrillic", "0446", + "tsere", "05B5", + "tsere12", "05B5", + "tsere1e", "05B5", + "tsere2b", "05B5", + "tserehebrew", "05B5", + "tserenarrowhebrew", "05B5", + "tserequarterhebrew", "05B5", + "tserewidehebrew", "05B5", + "tshecyrillic", "045B", + "ttabengali", "099F", + "ttadeva", "091F", + "ttagujarati", "0A9F", + "ttagurmukhi", "0A1F", + "tteharabic", "0679", + "ttehfinalarabic", "FB67", + "ttehinitialarabic", "FB68", + "ttehmedialarabic", "FB69", + "tthabengali", "09A0", + "tthadeva", "0920", + "tthagujarati", "0AA0", + "tthagurmukhi", "0A20", + "tturned", "0287", + "tuhiragana", "3064", + "tukatakana", "30C4", + "tukatakanahalfwidth", "FF82", + "tusmallhiragana", "3063", + "tusmallkatakana", "30C3", + "tusmallkatakanahalfwidth", "FF6F", + "twelvecircle", "246B", + "twelveparen", "247F", + "twelveperiod", "2493", + "twelveroman", "217B", + "twentycircle", "2473", + "twentyhangzhou", "5344", + "twentyparen", "2487", + "twentyperiod", "249B", + "two", "0032", + "twoarabic", "0662", + "twobengali", "09E8", + "twocircle", "2461", + "twocircleinversesansserif", "278B", + "twodeva", "0968", + "twodotenleader", "2025", + "twodotleader", "2025", + "twodotleadervertical", "FE30", + "twogujarati", "0AE8", + "twogurmukhi", "0A68", + "twohackarabic", "0662", + "twohangzhou", "3022", + "twoideographicparen", "3221", + "twoinferior", "2082", + "twomonospace", "FF12", + "twonumeratorbengali", "09F5", + "twoparen", "2475", + "twoperiod", "2489", + "twopersian", "06F2", + "tworoman", "2171", + "twostroke", "01BB", + "twosuperior", "00B2", + "twothai", "0E52", + "twothirds", "2154", + "u", "0075", + "uacute", "00FA", + "ubar", "0289", + "ubengali", "0989", + "ubopomofo", "3128", + "ubreve", "016D", + "ucaron", "01D4", + "ucircle", "24E4", + "ucircumflex", "00FB", + "ucircumflexbelow", "1E77", + "ucyrillic", "0443", + "udattadeva", "0951", + "udblacute", "0171", + "udblgrave", "0215", + "udeva", "0909", + "udieresis", "00FC", + "udieresisacute", "01D8", + "udieresisbelow", "1E73", + "udieresiscaron", "01DA", + "udieresiscyrillic", "04F1", + "udieresisgrave", "01DC", + "udieresismacron", "01D6", + "udotbelow", "1EE5", + "ugrave", "00F9", + "ugujarati", "0A89", + "ugurmukhi", "0A09", + "uhiragana", "3046", + "uhookabove", "1EE7", + "uhorn", "01B0", + "uhornacute", "1EE9", + "uhorndotbelow", "1EF1", + "uhorngrave", "1EEB", + "uhornhookabove", "1EED", + "uhorntilde", "1EEF", + "uhungarumlaut", "0171", + "uhungarumlautcyrillic", "04F3", + "uinvertedbreve", "0217", + "ukatakana", "30A6", + "ukatakanahalfwidth", "FF73", + "ukcyrillic", "0479", + "ukorean", "315C", + "umacron", "016B", + "umacroncyrillic", "04EF", + "umacrondieresis", "1E7B", + "umatragurmukhi", "0A41", + "umonospace", "FF55", + "underscore", "005F", + "underscoredbl", "2017", + "underscoremonospace", "FF3F", + "underscorevertical", "FE33", + "underscorewavy", "FE4F", + "union", "222A", + "universal", "2200", + "uogonek", "0173", + "uparen", "24B0", + "upblock", "2580", + "upperdothebrew", "05C4", + "upsilon", "03C5", + "upsilondieresis", "03CB", + "upsilondieresistonos", "03B0", + "upsilonlatin", "028A", + "upsilontonos", "03CD", + "uptackbelowcmb", "031D", + "uptackmod", "02D4", + "uragurmukhi", "0A73", + "uring", "016F", + "ushortcyrillic", "045E", + "usmallhiragana", "3045", + "usmallkatakana", "30A5", + "usmallkatakanahalfwidth", "FF69", + "ustraightcyrillic", "04AF", + "ustraightstrokecyrillic", "04B1", + "utilde", "0169", + "utildeacute", "1E79", + "utildebelow", "1E75", + "uubengali", "098A", + "uudeva", "090A", + "uugujarati", "0A8A", + "uugurmukhi", "0A0A", + "uumatragurmukhi", "0A42", + "uuvowelsignbengali", "09C2", + "uuvowelsigndeva", "0942", + "uuvowelsigngujarati", "0AC2", + "uvowelsignbengali", "09C1", + "uvowelsigndeva", "0941", + "uvowelsigngujarati", "0AC1", + "v", "0076", + "vadeva", "0935", + "vagujarati", "0AB5", + "vagurmukhi", "0A35", + "vakatakana", "30F7", + "vav", "05D5", + "vavdagesh", "FB35", + "vavdagesh65", "FB35", + "vavdageshhebrew", "FB35", + "vavhebrew", "05D5", + "vavholam", "FB4B", + "vavholamhebrew", "FB4B", + "vavvavhebrew", "05F0", + "vavyodhebrew", "05F1", + "vcircle", "24E5", + "vdotbelow", "1E7F", + "vecyrillic", "0432", + "veharabic", "06A4", + "vehfinalarabic", "FB6B", + "vehinitialarabic", "FB6C", + "vehmedialarabic", "FB6D", + "vekatakana", "30F9", + "venus", "2640", + "verticalbar", "007C", + "verticallineabovecmb", "030D", + "verticallinebelowcmb", "0329", + "verticallinelowmod", "02CC", + "verticallinemod", "02C8", + "vewarmenian", "057E", + "vhook", "028B", + "vikatakana", "30F8", + "viramabengali", "09CD", + "viramadeva", "094D", + "viramagujarati", "0ACD", + "visargabengali", "0983", + "visargadeva", "0903", + "visargagujarati", "0A83", + "vmonospace", "FF56", + "voarmenian", "0578", + "voicediterationhiragana", "309E", + "voicediterationkatakana", "30FE", + "voicedmarkkana", "309B", + "voicedmarkkanahalfwidth", "FF9E", + "vokatakana", "30FA", + "vparen", "24B1", + "vtilde", "1E7D", + "vturned", "028C", + "vuhiragana", "3094", + "vukatakana", "30F4", + "w", "0077", + "wacute", "1E83", + "waekorean", "3159", + "wahiragana", "308F", + "wakatakana", "30EF", + "wakatakanahalfwidth", "FF9C", + "wakorean", "3158", + "wasmallhiragana", "308E", + "wasmallkatakana", "30EE", + "wattosquare", "3357", + "wavedash", "301C", + "wavyunderscorevertical", "FE34", + "wawarabic", "0648", + "wawfinalarabic", "FEEE", + "wawhamzaabovearabic", "0624", + "wawhamzaabovefinalarabic", "FE86", + "wbsquare", "33DD", + "wcircle", "24E6", + "wcircumflex", "0175", + "wdieresis", "1E85", + "wdotaccent", "1E87", + "wdotbelow", "1E89", + "wehiragana", "3091", + "weierstrass", "2118", + "wekatakana", "30F1", + "wekorean", "315E", + "weokorean", "315D", + "wgrave", "1E81", + "whitebullet", "25E6", + "whitecircle", "25CB", + "whitecircleinverse", "25D9", + "whitecornerbracketleft", "300E", + "whitecornerbracketleftvertical", "FE43", + "whitecornerbracketright", "300F", + "whitecornerbracketrightvertical", "FE44", + "whitediamond", "25C7", + "whitediamondcontainingblacksmalldiamond", "25C8", + "whitedownpointingsmalltriangle", "25BF", + "whitedownpointingtriangle", "25BD", + "whiteleftpointingsmalltriangle", "25C3", + "whiteleftpointingtriangle", "25C1", + "whitelenticularbracketleft", "3016", + "whitelenticularbracketright", "3017", + "whiterightpointingsmalltriangle", "25B9", + "whiterightpointingtriangle", "25B7", + "whitesmallsquare", "25AB", + "whitesmilingface", "263A", + "whitesquare", "25A1", + "whitestar", "2606", + "whitetelephone", "260F", + "whitetortoiseshellbracketleft", "3018", + "whitetortoiseshellbracketright", "3019", + "whiteuppointingsmalltriangle", "25B5", + "whiteuppointingtriangle", "25B3", + "wihiragana", "3090", + "wikatakana", "30F0", + "wikorean", "315F", + "wmonospace", "FF57", + "wohiragana", "3092", + "wokatakana", "30F2", + "wokatakanahalfwidth", "FF66", + "won", "20A9", + "wonmonospace", "FFE6", + "wowaenthai", "0E27", + "wparen", "24B2", + "wring", "1E98", + "wsuperior", "02B7", + "wturned", "028D", + "wynn", "01BF", + "x", "0078", + "xabovecmb", "033D", + "xbopomofo", "3112", + "xcircle", "24E7", + "xdieresis", "1E8D", + "xdotaccent", "1E8B", + "xeharmenian", "056D", + "xi", "03BE", + "xmonospace", "FF58", + "xparen", "24B3", + "xsuperior", "02E3", + "y", "0079", + "yaadosquare", "334E", + "yabengali", "09AF", + "yacute", "00FD", + "yadeva", "092F", + "yaekorean", "3152", + "yagujarati", "0AAF", + "yagurmukhi", "0A2F", + "yahiragana", "3084", + "yakatakana", "30E4", + "yakatakanahalfwidth", "FF94", + "yakorean", "3151", + "yamakkanthai", "0E4E", + "yasmallhiragana", "3083", + "yasmallkatakana", "30E3", + "yasmallkatakanahalfwidth", "FF6C", + "yatcyrillic", "0463", + "ycircle", "24E8", + "ycircumflex", "0177", + "ydieresis", "00FF", + "ydotaccent", "1E8F", + "ydotbelow", "1EF5", + "yeharabic", "064A", + "yehbarreearabic", "06D2", + "yehbarreefinalarabic", "FBAF", + "yehfinalarabic", "FEF2", + "yehhamzaabovearabic", "0626", + "yehhamzaabovefinalarabic", "FE8A", + "yehhamzaaboveinitialarabic", "FE8B", + "yehhamzaabovemedialarabic", "FE8C", + "yehinitialarabic", "FEF3", + "yehmedialarabic", "FEF4", + "yehmeeminitialarabic", "FCDD", + "yehmeemisolatedarabic", "FC58", + "yehnoonfinalarabic", "FC94", + "yehthreedotsbelowarabic", "06D1", + "yekorean", "3156", + "yen", "00A5", + "yenmonospace", "FFE5", + "yeokorean", "3155", + "yeorinhieuhkorean", "3186", + "yerahbenyomohebrew", "05AA", + "yerahbenyomolefthebrew", "05AA", + "yericyrillic", "044B", + "yerudieresiscyrillic", "04F9", + "yesieungkorean", "3181", + "yesieungpansioskorean", "3183", + "yesieungsioskorean", "3182", + "yetivhebrew", "059A", + "ygrave", "1EF3", + "yhook", "01B4", + "yhookabove", "1EF7", + "yiarmenian", "0575", + "yicyrillic", "0457", + "yikorean", "3162", + "yinyang", "262F", + "yiwnarmenian", "0582", + "ymonospace", "FF59", + "yod", "05D9", + "yoddagesh", "FB39", + "yoddageshhebrew", "FB39", + "yodhebrew", "05D9", + "yodyodhebrew", "05F2", + "yodyodpatahhebrew", "FB1F", + "yohiragana", "3088", + "yoikorean", "3189", + "yokatakana", "30E8", + "yokatakanahalfwidth", "FF96", + "yokorean", "315B", + "yosmallhiragana", "3087", + "yosmallkatakana", "30E7", + "yosmallkatakanahalfwidth", "FF6E", + "yotgreek", "03F3", + "yoyaekorean", "3188", + "yoyakorean", "3187", + "yoyakthai", "0E22", + "yoyingthai", "0E0D", + "yparen", "24B4", + "ypogegrammeni", "037A", + "ypogegrammenigreekcmb", "0345", + "yr", "01A6", + "yring", "1E99", + "ysuperior", "02B8", + "ytilde", "1EF9", + "yturned", "028E", + "yuhiragana", "3086", + "yuikorean", "318C", + "yukatakana", "30E6", + "yukatakanahalfwidth", "FF95", + "yukorean", "3160", + "yusbigcyrillic", "046B", + "yusbigiotifiedcyrillic", "046D", + "yuslittlecyrillic", "0467", + "yuslittleiotifiedcyrillic", "0469", + "yusmallhiragana", "3085", + "yusmallkatakana", "30E5", + "yusmallkatakanahalfwidth", "FF6D", + "yuyekorean", "318B", + "yuyeokorean", "318A", + "yyabengali", "09DF", + "yyadeva", "095F", + "z", "007A", + "zaarmenian", "0566", + "zacute", "017A", + "zadeva", "095B", + "zagurmukhi", "0A5B", + "zaharabic", "0638", + "zahfinalarabic", "FEC6", + "zahinitialarabic", "FEC7", + "zahiragana", "3056", + "zahmedialarabic", "FEC8", + "zainarabic", "0632", + "zainfinalarabic", "FEB0", + "zakatakana", "30B6", + "zaqefgadolhebrew", "0595", + "zaqefqatanhebrew", "0594", + "zarqahebrew", "0598", + "zayin", "05D6", + "zayindagesh", "FB36", + "zayindageshhebrew", "FB36", + "zayinhebrew", "05D6", + "zbopomofo", "3117", + "zcaron", "017E", + "zcircle", "24E9", + "zcircumflex", "1E91", + "zcurl", "0291", + "zdot", "017C", + "zdotaccent", "017C", + "zdotbelow", "1E93", + "zecyrillic", "0437", + "zedescendercyrillic", "0499", + "zedieresiscyrillic", "04DF", + "zehiragana", "305C", + "zekatakana", "30BC", + "zero", "0030", + "zeroarabic", "0660", + "zerobengali", "09E6", + "zerodeva", "0966", + "zerogujarati", "0AE6", + "zerogurmukhi", "0A66", + "zerohackarabic", "0660", + "zeroinferior", "2080", + "zeromonospace", "FF10", + "zeropersian", "06F0", + "zerosuperior", "2070", + "zerothai", "0E50", + "zerowidthjoiner", "FEFF", + "zerowidthnonjoiner", "200C", + "zerowidthspace", "200B", + "zeta", "03B6", + "zhbopomofo", "3113", + "zhearmenian", "056A", + "zhebrevecyrillic", "04C2", + "zhecyrillic", "0436", + "zhedescendercyrillic", "0497", + "zhedieresiscyrillic", "04DD", + "zihiragana", "3058", + "zikatakana", "30B8", + "zinorhebrew", "05AE", + "zlinebelow", "1E95", + "zmonospace", "FF5A", + "zohiragana", "305E", + "zokatakana", "30BE", + "zparen", "24B5", + "zretroflexhook", "0290", + "zstroke", "01B6", + "zuhiragana", "305A", + "zukatakana", "30BA", +); diff --git a/src/utils/afmtodit/make-afmtodit-tables b/src/utils/afmtodit/make-afmtodit-tables new file mode 100755 index 0000000..937bb72 --- /dev/null +++ b/src/utils/afmtodit/make-afmtodit-tables @@ -0,0 +1,139 @@ +#! /bin/sh +# +# make-afmtodit-tables -- script for creating the 'unicode_decomposed' +# and 'AGL_to_unicode' tables +# +# Copyright (C) 2005-2020 Free Software Foundation, Inc. +# Written by Werner Lemberg +# +# This file 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 . + +# +# usage: +# +# make-afmtodit-tables \ +# UnicodeData.txt version-string glyphlist.txt > afmtodit.in +# +# 'UnicodeData.txt' is the central database file from the Unicode +# standard. Unfortunately, it doesn't contain a version number, which +# must be thus provided manually as an additional parameter. +# +# 'glyphlist.txt' holds the Adobe Glyph List (AGL). +# +# This program needs a C preprocessor. +# + +if [ $# -ne 3 ] +then + echo "usage: $0 UnicodeData.txt UNICODE-VERSION-STRING" \ + "glyphlist.txt > afmtodit.tables" + exit 2 +fi + +unicode_data="$1" +unicode_version="$2" +glyph_list="$3" + +for f in "$1" "$3" +do + if ! [ -r "$f" ] + then + echo "$0: '$f' does not exist or is not readable" >&2 + exit 1 + fi +done + +# Handle UnicodeData.txt. +# +# Remove ranges and control characters, +# then extract the decomposition field, +# then remove lines without decomposition, +# then remove all compatibility decompositions. +cat "$1" \ +| sed -e '/^[^;]*; $$1 + +# Prepare input for running cpp. +cat $$1 \ +| sed -e 's/^\([^;]*\);/#define \1 /' \ + -e 's/ / u/g' > $$2 +cat $$1 \ +| sed -e 's/^\([^;]*\);.*$/\1 u\1/' >> $$2 + +# Run C preprocessor to recursively decompose. +"${CPP:-cpp}" $$2 $$3 + +# Convert it back to original format. +cat $$3 \ +| sed -e '/#/d' \ + -e '/^$/d' \ + -e 's/ \+/ /g' \ + -e 's/ *$//' \ + -e 's/u//g' \ + -e 's/^\([^ ]*\) /\1;/' > $$4 + +# Write comment. +cat < $$5 + +# Perform groff replacements. +sed \ + -e 's/\("Delta"\), "2206",$/\1, "0394", # groff: not U+2206/' \ + -e 's/\("Omega"\), "2126",$/\1, "03A9", # groff: not U+2126/' \ + -e 's/\("mu"\), "00B5",$/\1, "03BC", # groff: not U+00B5/' \ + < $$5 > $$6 + +# Emit second table. +echo 'my %AGL_to_unicode = (' +cat $$6 +echo ');' + +# Remove temporary files. +rm $$1 $$2 $$3 $$4 $$5 $$6 + +# Local Variables: +# fill-column: 72 +# End: +# vim: set textwidth=72: diff --git a/src/utils/grog/grog.1.man b/src/utils/grog/grog.1.man new file mode 100644 index 0000000..efcd728 --- /dev/null +++ b/src/utils/grog/grog.1.man @@ -0,0 +1,628 @@ +.TH grog @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +grog \- \(lqgroff guess\(rq\(eminfer the +.I groff +command a document requires +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1989-2021 Free Software Foundation, Inc. +.\" +.\" This file is part of grog, which is part of groff, a free software +.\" project. You can redistribute it and/or modify it under the terms +.\" of the GNU General Public License version 2 (GPL2) as published by +.\" the Free Software Foundation. +.\" +.\" 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. +.\" +.\" The text for GPL2 is available in the internet at +.\" . +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_grog_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY grog +.RB [ \-\-run ] +.RB [ \-\-ligatures ] +.RI [ groff-option\~ .\|.\|.\&] +.RB [ \-\- ] +.RI [ file\~ .\|.\|.] +.YS +. +. +.SY grog +.B \-h +. +.SY grog +.B \-\-help +.YS +. +. +.SY grog +.B \-v +. +.SY grog +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I grog +reads its input +and guesses which +.MR groff @MAN1EXT@ +options are needed to render it. +. +If no operands are given, +or if +.I file +is +.RB \[lq] \- \[rq], +.I grog +reads the standard input stream. +. +The corresponding +.I groff +command is normally written to the standard output stream. +. +With the option +.BR \-\-run , +the inferred command is written to the standard error stream and then +executed. +. +. +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-h +and +.B \-\-help +display a usage message, +whereas +.B \-v +and +.B \-\-version +display version information; +all exit afterward. +. +. +.TP +.B \-\-ligatures +includes the arguments +.B \-P\-y \-PU +in the inferred +.I groff +command. +. +These are supported only by the +.B pdf +output device. +. +. +.TP +.B \-\-run +writes the inferred command to the standard error stream and then +executes it. +. +. +.P +All other specified short options +(that is, +arguments beginning with a minus sign +.RB \[lq] \- \[rq] +followed by a letter) +are interpreted as +.I groff +options or option clusters with or without an option argument. +. +Such options are included in the constructed +.I groff +command line. +. +. +.\" ==================================================================== +.SH Details +.\" ==================================================================== +. +.I grog +reads each +.I file +operand, +pattern-matching strings that are statistically likely to be +characteristic of +.MR roff @MAN7EXT@ +documents. +. +It tries to guess which of the following +.I groff +options are required to correctly render the input: +.BR \-e , +.BR \-g , +.BR \-G , +.BR \-j , +.\" gideal is not implemented yet. +.\" .BR \-J , +.BR \-p , +.BR \-R , +.\".BR \-s , +.B \-t +(preprocessors); +and +.BR \-man , +.BR \-mdoc , +.BR \-mdoc\-old , +.BR \-me , +.BR \-mm , +.BR \-mom , +and +.B \-ms +(macro packages). +. +The inferred +.I groff +command including these options and any +.I file +parameters is written to the standard output stream. +. +. +.P +It is possible to specify arbitrary +.I groff +options on the command line. +. +These are included in the inferred command without change. +. +Choices of +.I groff +options include +.B \-C +to enable AT&T +.I troff +compatibility mode and +.B \-T +to select a non-default output device. +. +If the input is not encoded in US-ASCII, +ISO 8859-1, +or IBM code page 1047, +specification of a +.I groff +option to run the +.MR preconv @MAN1EXT@ +preprocessor is advised; +see the +.BR \-D , +.BR \-k , +and +.B \-K +options of +.MR groff @MAN1EXT@ . +. +For UTF-8 input, +.B \-k +is a good choice. +. +. +.P +.I groff +may issue diagnostic messages when an inappropriate +.B \-m +option, +or multiple conflicting ones, +are specified. +. +Consequently, +it is best to specify no +.B \-m +options to +.I grog +unless it cannot correctly infer all of the +.B \-m +arguments a document requires. +. +A +.I roff +document can also be written without recourse to any macro package. +. +In such cases, +.I grog +will infer a +.I groff +command without an +.B \-m +option. +. +. +.\" ==================================================================== +.SS Limitations +.\" ==================================================================== +. +.I grog +presumes that the input does not change the escape, +control, +or no-break control characters. +. +.I grog +does not parse +.I roff +input line continuation or control structures +(brace escape sequences and the +.RB \[lq] if \[rq], +.RB \[lq] ie \[rq], +and +.RB \[lq] el \[rq] +requests) +nor +.IR groff 's +.RB \[lq] while \[rq]. +. +Thus the input +. +.RS +.EX +\&.if \[rs] +t .NH 1 +\&.if n .SH +Introduction +.EE +.RE +. +will conceal the use of the +.I ms +macros +.B NH +and +.B SH +from +.IR grog . +. +Such constructions are regarded by +.IR grog 's +implementors as insufficiently common to cause many inference problems. +. +Preprocessors can be even stricter when matching macro calls that +bracket the regions of an input file they replace. +. +.IR pic , +for example, +requires +.BR PS , +.BR PE , +and +.B PF +calls to immediately follow the default control character at the +beginning of a line. +. +. +.P +Detection of the +.B \-s +option +(the +.MR @g@soelim @MAN1EXT@ +preprocessor) +is tricky; +to correctly infer its necessity would require +.I grog +to recursively open all files given as arguments to the +.B .so +request under the same conditions that +.I @g@soelim +itself does so; +see its man page. +. +Recall that +.I @g@soelim +is necessary only if sourced files need to be preprocessed. +. +Therefore, +as a workaround, +you may want to run the input through +.I @g@soelim +manually, +piping it to +.IR grog , +and compare the output to running +.I grog +on the input directly. +. +If the +.RI \[lq] @g@soelim \[rq]ed +input causes +.I grog +to infer additional preprocessor options, +then +.B \-s +is likely necessary. +. +. +.RS +.P +.EX +$ \c +.B printf \[dq].TS\[rs]nl.\[rs]nI\[aq]m a table.\[rs]n.TE\[rs]n\[dq] > \ +3.roff +$ \c +.B printf \[dq].so 3.roff\[rs]n\[dq] > 2.roff +$ \c +.B printf \[dq].XP\[rs]n.so 2.roff\[rs]n\[dq] > 1.roff +$ \c +.B grog 1.roff +groff \-ms 1.roff +$ \c +.B @g@soelim 1.roff | grog +groff \-t \-ms \- +.EE +.RE +. +. +.P +In the foregoing example, +we see that this procedure enabled +.I grog +to detect +.MR @g@tbl @MAN1EXT@ +macros, +so we would add +.B \-s +as well as the detected +.B \-t +option to a revised +.I grog +or +.I groff +command. +. +. +.RS +.P +.EX +$ \c +.B grog \-st 1.roff +groff \-st \-ms 1.roff +.EE +.RE +. +. +.\" ==================================================================== +.SH "Exit status" +.\" ==================================================================== +. +.I grog +exits with error status +.B 1 +if a macro package appears to be in use by the input document, +but +.I grog +was unable to infer which one, +or +.B 2 +if there were problems handling an option or operand. +. +It otherwise exits with status +.BR 0 . +. +(If the +.B \-\-run +option is specified, +.IR groff 's +exit status is discarded.) +. +Inferring no preprocessors or macro packages is not an error condition; +a valid +.I roff +document need not use either. +. +Even plain text is valid input, +if one is mindful of the syntax of the control and escape characters. +. +. +.\" ==================================================================== +.SH Examples +.\" ==================================================================== +. +Running +. +.RS +.EX +.B grog @DOCDIR@/meintro.me +.EE +.RE +at the command line results in +.RS +.EX +groff \-me @DOCDIR@/meintro.me +.EE +.RE +. +because +.I grog +recognizes that the file +.I meintro.me +is written using macros from the +.I me +package. +. +The command +. +.RS +.EX +.B grog @DOCDIR@/pic.ms +.EE +.RE +. +outputs +. +.RS +.EX +groff \-e \-p \-t \-ms @DOCDIR@/pic.ms +.EE +.RE +. +on the other hand. +. +Besides discerning the +.I ms +macro package, +.I grog +recognizes that the file +.I pic.ms +additionally needs the combination of +.B \-t +for +.IR tbl , +.B \-e +for +.IR eqn , +and +.B \-p +for +.IR pic . +. +. +.\" XXX: grog no longer (June 2021) attempts to detect this scenario. +.\" It's also not a practical one; full-service macro packages don't +.\" generally support being "unloaded" for subsequent processing of +.\" another document using a different one. We do achieve it, with +.\" care, in groff with man(7) and mdoc(7) (see andoc.tmac). +.\" .P +.\" If both of the former example files are combined in the command +.\" . +.\" .RS +.\" .EX +.\" .B grog meintro.me pic.ms +.\" .EE +.\" .RE +.\" . +.\" a diagnostic message is sent to the standard error stream because +.\" some macro packages cannot be combined. +.\" . +.\" Nevertheless the corresponding output with the wrong options is +.\" written to standard output: +.\" . +.\" .RS +.\" .EX +.\" groff \-t \-e \-p \-ms meintro.me pic.ms +.\" .EE +.\" .RE +.\" . +.\" and +.\" .I grog +.\" terminates with an error exit status. +. +. +.P +Consider a file +.IR \%doc/\:\%grnexampl.me , +which uses the +.I @g@grn +preprocessor to include a +.MR gremlin 1 +picture file in an +.I me \" generic +document. +. +Let's say we want to suppress color output, +produce a DVI file, +and get backtraces for any errors that +.I @g@troff +encounters. +. +The command +. +.RS +.EX +.B grog \-bc \-Idoc \-Tdvi doc/grnexmpl.me +.EE +.RE +. +is processed by +.I grog +into +. +.RS +.EX +groff \-bc \-Idoc \-Tdvi \-e \-g \-me doc/grnexmpl.me +.EE +.RE +. +where we can see that +.I grog +has inferred the +.I me \" generic +macro package along with the +.I eqn \" generic +and +.I grn \" generic +preprocessors. +. +(The input file is located in +.I @DOCDIR@ +if you'd like to try this example yourself.) +. +. +.\" ==================================================================== +.SH Authors +.\" ==================================================================== +. +.I grog +was originally written in Bourne shell by James Clark. +. +The current implementation in Perl was written by +.MT groff\-bernd\:.warken\-72@\:web\:.de +Bernd Warken +.ME +and heavily revised by +.MT g.branden\:.robinson@\:gmail\:.com +G.\& Branden Robinson +.ME . +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.MR groff @MAN1EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_grog_1_man_C] +.do rr *groff_grog_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/utils/grog/grog.am b/src/utils/grog/grog.am new file mode 100644 index 0000000..f7ca5eb --- /dev/null +++ b/src/utils/grog/grog.am @@ -0,0 +1,50 @@ +# Copyright (C) 1993-2021 Free Software Foundation, Inc. +# +# This file 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 . + +grog_srcdir = $(top_srcdir)/src/utils/grog +bin_SCRIPTS += grog +man1_MANS += src/utils/grog/grog.1 +EXTRA_DIST += \ + src/utils/grog/grog.1.man \ + src/utils/grog/grog.pl \ + src/utils/grog/tests/foo.man + +grog: $(grog_srcdir)/grog.pl $(SH_DEPS_SED_SCRIPT) + $(AM_V_GEN)$(RM) $@ \ + && sed -f "$(SH_DEPS_SED_SCRIPT)" \ + -e "s|[@]PERL[@]|$(PERL)|" \ + -e "s|[@]VERSION[@]|$(VERSION)|" \ + -e "$(SH_SCRIPT_SED_CMD)" \ + $(grog_srcdir)/grog.pl \ + >$@ \ + && chmod +x $@ + +grog_TESTS = \ + src/utils/grog/tests/PF-does-not-start-pic-region.sh \ + src/utils/grog/tests/avoid-refer-fakeout.sh \ + src/utils/grog/tests/preserve-groff-options.sh \ + src/utils/grog/tests/recognize-perl-pod.sh \ + src/utils/grog/tests/smoke-test.sh +TESTS += $(grog_TESTS) +EXTRA_DIST += $(grog_TESTS) + + +# Local Variables: +# mode: makefile-automake +# fill-column: 72 +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/utils/grog/grog.pl b/src/utils/grog/grog.pl new file mode 100644 index 0000000..28973c5 --- /dev/null +++ b/src/utils/grog/grog.pl @@ -0,0 +1,721 @@ +#!@PERL@ +# grog - guess options for groff command +# Inspired by doctype script in Kernighan & Pike, Unix Programming +# Environment, pp 306-8. + +# Copyright (C) 1993-2021 Free Software Foundation, Inc. +# Written by James Clark. +# Rewritten in Perl by Bernd Warken . +# Hacked up by G. Branden Robinson, 2021. + +# This file is part of 'grog', 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 2 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 +# . + +use warnings; +use strict; + +use File::Spec; + +my $groff_version = 'DEVELOPMENT'; + +my @command = (); # the constructed groff command +my @requested_package = (); # arguments to '-m' grog options +my @inferred_preprocessor = (); # preprocessors the document uses +my @inferred_main_package = (); # full-service package(s) detected +my $main_package; # full-service package we go with +my $do_run = 0; # run generated 'groff' command +my $use_compatibility_mode = 0; # is -C being passed to groff? + +my %preprocessor_for_macro = ( + 'EQ', 'eqn', + 'G1', 'grap', + 'GS', 'grn', + 'PS', 'pic', + '[', 'refer', + #'so', 'soelim', # Can't be inferred this way; see grog man page. + 'TS', 'tbl', + 'cstart', 'chem', + 'lilypond', 'glilypond', + 'Perl', 'gperl', + 'pinyin', 'gpinyin', +); + +my $program_name = $0; +{ + my ($v, $d, $f) = File::Spec->splitpath($program_name); + $program_name = $f; +} + +my %user_macro; +my %score = (); + +my @input_file; + +# .TH is both a man(7) macro and often used with tbl(1). We expect to +# find .TH in ms(7) documents only between .TS and .TE calls, and in +# man(7) documents only as the first macro call. +my $have_seen_first_macro_call = 0; +# man(7) and ms(7) use many of the same macro names; do extra checking. +my $man_score = 0; +my $ms_score = 0; + +my $had_inference_problem = 0; +my $had_processing_problem = 0; +my $have_any_valid_arguments = 0; + + +sub fail { + my $text = shift; + print STDERR "$program_name: error: $text\n"; + $had_processing_problem = 1; +} + + +sub warn { + my $text = shift; + print STDERR "$program_name: warning: $text\n"; +} + + +sub process_arguments { + my $no_more_options = 0; + my $delayed_option = ''; + my $was_minus = 0; + my $optarg = 0; + my $pdf_with_ligatures = 0; + + foreach my $arg (@ARGV) { + if ( $optarg ) { + push @command, $arg; + $optarg = 0; + next; + } + + if ($no_more_options) { + push @input_file, $arg; + next; + } + + if ($delayed_option) { + if ($delayed_option eq '-m') { + push @requested_package, $arg; + $arg = ''; + } else { + push @command, $delayed_option; + } + + push @command, $arg if $arg; + $delayed_option = ''; + next; + } + + unless ( $arg =~ /^-/ ) { # file name, no opt, no optarg + push @input_file, $arg; + next; + } + + # now $arg starts with '-' + + if ($arg eq '-') { + unless ($was_minus) { + push @input_file, $arg; + $was_minus = 1; + } + next; + } + + if ($arg eq '--') { + $no_more_options = 1; + next; + } + + # Handle options that cause an early exit. + &version() if ($arg eq '-v' || $arg eq '--version'); + &usage(0) if ($arg eq '-h' || $arg eq '--help'); + + if ($arg =~ '^--.') { + if ($arg =~ '^--(run|with-ligatures)$') { + $do_run = 1 if ($arg eq '--run'); + $pdf_with_ligatures = 1 if ($arg eq '--with-ligatures'); + } else { + &fail("unrecognized grog option '$arg'; ignored"); + &usage(1); + } + next; + } + + # Handle groff options that take an argument. + + # Handle the option argument being separated by whitespace. + if ($arg =~ /^-[dfFIKLmMnoPrTwW]$/) { + $delayed_option = $arg; + next; + } + + # Handle '-m' option without subsequent whitespace. + if ($arg =~ /^-m/) { + my $package = $arg; + $package =~ s/-m//; + push @requested_package, $package; + next; + } + + # Treat anything else as (possibly clustered) groff options that + # take no arguments. + + # Our do_line() needs to know if it should do compatibility parsing. + $use_compatibility_mode = 1 if ($arg =~ /C/); + + push @command, $arg; + } + + if ($pdf_with_ligatures) { + push @command, '-P-y'; + push @command, '-PU'; + } + + @input_file = ('-') unless (@input_file); +} # process_arguments() + + +sub process_input { + foreach my $file (@input_file) { + unless ( open(FILE, $file eq "-" ? $file : "< $file") ) { + &fail("cannot open '$file': $!"); + next; + } + + $have_any_valid_arguments = 1; + + while (my $line = ) { + chomp $line; + &do_line($line); + } + + close(FILE); + } # end foreach +} # process_input() + + +# Push item onto inferred full-service list only if not already present. +sub push_main_package { + my $pkg = shift; + if (!grep(/^$pkg/, @inferred_main_package)) { + push @inferred_main_package, $pkg; + } +} # push_main_package() + + +sub do_line { + my $command; # request or macro name + my $args; # request or macro arguments + + my $line = shift; + + # Check for a Perl Pod::Man comment. + # + # An alternative to this kludge is noted below: if a "standard" macro + # is redefined, we could delete it from the relevant lists and + # hashes. + if ($line =~ /\\\" Automatically generated by Pod::Man/) { + $man_score += 100; + } + + # Strip comments. + $line =~ s/\\".*//; + $line =~ s/\\#.*// unless $use_compatibility_mode; + + return unless ($line =~ /^[.']/); # Ignore text lines. + + # Perform preprocessor checks; they scan their inputs using a rump + # interpretation of roff(7) syntax that requires the default control + # character and no space between it and the macro name. In AT&T + # compatibility mode, no space (or newline!) is required after the + # macro name, either. We mimic the preprocessors themselves; eqn(1), + # for instance, does not recognize '.EN' if '.EQ' has not been seen. + my $boundary = '\\b'; + $boundary = '' if ($use_compatibility_mode); + + if ($line =~ /^\.(\S\S)$boundary/ || $line =~ /^\.(\[)/) { + my $macro = $1; + # groff identifiers can have extremely weird characters in them. + # The ones we care about are conventionally named, but me(7) + # documents can call macros like '+c', so quote carefully. + if (grep(/^\Q$macro\E$/, keys %preprocessor_for_macro)) { + my $preproc = $preprocessor_for_macro{$macro}; + if (!grep(/$preproc/, @inferred_preprocessor)) { + push @inferred_preprocessor, $preproc; + } + } + } + + # Normalize control lines; convert no-break control character to the + # regular one and remove unnecessary whitespace. + $line =~ s/^['.]\s*/./; + $line =~ s/\s+$//; + + return if ($line =~ /^\.$/); # Ignore empty request. + return if ($line =~ /^\.\\?\.$/); # Ignore macro definition ends. + + # Split control line into a request or macro call and its arguments. + + # Handle single-letter macro names. + if ($line =~ /^\.(\S)(\s+(.*))?$/) { + $command = $1; + $args = $2; + # Handle two-letter macro/request names in compatibility mode. + } elsif ($use_compatibility_mode) { + $line =~ /^\.(\S\S)\s*(.*)$/; + $command = $1; + $args = $2; + # Handle multi-letter macro/request names in groff mode. + } else { + $line =~ /^\.(\S+)(\s+(.*))?$/; + $command = $1; + $args = $3; + } + + $command = '' unless ($command); + $args = '' unless ($args); + + ###################################################################### + # user-defined macros + + # If the line calls a user-defined macro, skip it. + return if (exists $user_macro{$command}); + + # These are all requests supported by groff 1.23.0. + my @request = ('ab', 'ad', 'af', 'aln', 'als', 'am', 'am1', 'ami', + 'ami1', 'as', 'as1', 'asciify', 'backtrace', 'bd', + 'blm', 'box', 'boxa', 'bp', 'br', 'brp', 'break', 'c2', + 'cc', 'ce', 'cf', 'cflags', 'ch', 'char', 'chop', + 'class', 'close', 'color', 'composite', 'continue', + 'cp', 'cs', 'cu', 'da', 'de', 'de1', 'defcolor', 'dei', + 'dei1', 'device', 'devicem', 'di', 'do', 'ds', 'ds1', + 'dt', 'ec', 'ecr', 'ecs', 'el', 'em', 'eo', 'ev', + 'evc', 'ex', 'fam', 'fc', 'fchar', 'fcolor', 'fi', + 'fp', 'fschar', 'fspecial', 'ft', 'ftr', 'fzoom', + 'gcolor', 'hc', 'hcode', 'hla', 'hlm', 'hpf', 'hpfa', + 'hpfcode', 'hw', 'hy', 'hym', 'hys', 'ie', 'if', 'ig', + 'in', 'it', 'itc', 'kern', 'lc', 'length', 'linetabs', + 'lf', 'lg', 'll', 'lsm', 'ls', 'lt', 'mc', 'mk', 'mso', + 'msoquiet', 'na', 'ne', 'nf', 'nh', 'nm', 'nn', 'nop', + 'nr', 'nroff', 'ns', 'nx', 'open', 'opena', 'os', + 'output', 'pc', 'pev', 'pi', 'pl', 'pm', 'pn', 'pnr', + 'po', 'ps', 'psbb', 'pso', 'ptr', 'pvs', 'rchar', 'rd', + 'return', 'rfschar', 'rj', 'rm', 'rn', 'rnn', 'rr', + 'rs', 'rt', 'schar', 'shc', 'shift', 'sizes', 'so', + 'soquiet', 'sp', 'special', 'spreadwarn', 'ss', + 'stringdown', 'stringup', 'sty', 'substring', 'sv', + 'sy', 'ta', 'tc', 'ti', 'tkf', 'tl', 'tm', 'tm1', + 'tmc', 'tr', 'trf', 'trin', 'trnt', 'troff', 'uf', + 'ul', 'unformat', 'vpt', 'vs', 'warn', 'warnscale', + 'wh', 'while', 'write', 'writec', 'writem'); + + # Add user-defined macro names to %user_macro. + # + # Macros can also be defined with .dei{,1}, ami{,1}, but supporting + # that would be a heavy lift for the benefit of users that probably + # don't require grog's help. --GBR + if ($command =~ /^(de|am)1?$/) { + my $name = $args; + # Strip off any end macro. + $name =~ s/\s+.*$//; + # Handle special cases of macros starting with '[' or ']'. + if ($name =~ /^[][]/) { + delete $preprocessor_for_macro{'['}; + } + # XXX: If the macro name shadows a standard macro name, maybe we + # should delete the latter from our lists and hashes. This might + # depend on whether the document is trying to remain compatible + # with an existing interface, or simply colliding with names they + # don't care about (consider a raw roff document that defines 'PP'). + # --GBR + $user_macro{$name} = 0 unless (exists $user_macro{$name}); + return; + } + + # XXX: Handle .rm as well? + + # Ignore all other requests. Again, macro names can contain Perl + # regex metacharacters, so be careful. + return if (grep(/^\Q$command\E$/, @request)); + # What remains must be a macro name. + my $macro = $command; + + $have_seen_first_macro_call = 1; + $score{$macro}++; + + + ###################################################################### + # macro package (tmac) + ###################################################################### + + # man and ms share too many macro names for the following approach to + # be fruitful for many documents; see &infer_man_or_ms_package. + # + # We can put one thumb on the scale, however. + if ((!$have_seen_first_macro_call) && ($macro eq 'TH')) { + # TH as the first call in a document screams man(7). + $man_score += 100; + } + + ########## + # mdoc + if ($macro =~ /^Dd$/) { + &push_main_package('doc'); + return; + } + + ########## + # old mdoc + if ($macro =~ /^(Tp|Dp|De|Cx|Cl)$/) { + &push_main_package('doc-old'); + return; + } + + ########## + # me + + if ($macro =~ /^( + [ilnp]p| + n[12]| + sh + )$/x) { + &push_main_package('e'); + return; + } + + + ############# + # mm and mmse + + if ($macro =~ /^( + H| + MULB| + LO| + LT| + NCOL| + PH| + SA + )$/x) { + if ($macro =~ /^LO$/) { + if ( $args =~ /^(DNAMN|MDAT|BIL|KOMP|DBET|BET|SIDOR)/ ) { + &push_main_package('mse'); + return; + } + } elsif ($macro =~ /^LT$/) { + if ( $args =~ /^(SVV|SVH)/ ) { + &push_main_package('mse'); + return; + } + } + &push_main_package('m'); + return; + } + + ########## + # mom + + if ($macro =~ /^( + ALD| + AUTHOR| + CHAPTER_TITLE| + CHAPTER| + COLLATE| + DOCHEADER| + DOCTITLE| + DOCTYPE| + DOC_COVER| + FAMILY| + FAM| + FT| + LEFT| + LL| + LS| + NEWPAGE| + NO_TOC_ENTRY| + PAGENUMBER| + PAGE| + PAGINATION| + PAPER| + PRINTSTYLE| + PT_SIZE| + START| + TITLE| + TOC_AFTER_HERE + TOC| + T_MARGIN| + )$/x) { + &push_main_package('om'); + return; + } +} # do_line() + +my @preprocessor = (); + + +sub infer_preprocessors { + my %option_for_preprocessor = ( + 'eqn', '-e', + 'grap', '-G', + 'grn', '-g', + 'pic', '-p', + 'refer', '-R', + #'soelim', '-s', # Can't be inferred this way; see grog man page. + 'tbl', '-t', + 'chem', '-j' + ); + + # Use a temporary list we can sort later. We want the options to show + # up in a stable order for testing purposes instead of the order their + # macros turn up in the input. groff doesn't care about the order. + my @opt = (); + + foreach my $preproc (@inferred_preprocessor) { + my $preproc_option = $option_for_preprocessor{$preproc}; + + if ($preproc_option) { + push @opt, $preproc_option; + } else { + push @preprocessor, $preproc; + } + } + push @command, sort @opt; +} # infer_preprocessors() + + +# Return true (1) if either the man or ms package is inferred. +sub infer_man_or_ms_package { + my @macro_ms = ('RP', 'TL', 'AU', 'AI', 'DA', 'ND', 'AB', 'AE', + 'QP', 'QS', 'QE', 'XP', + 'NH', + 'R', + 'CW', + 'BX', 'UL', 'LG', 'NL', + 'KS', 'KF', 'KE', 'B1', 'B2', + 'DS', 'DE', 'LD', 'ID', 'BD', 'CD', 'RD', + 'FS', 'FE', + 'OH', 'OF', 'EH', 'EF', 'P1', + 'TA', '1C', '2C', 'MC', + 'XS', 'XE', 'XA', 'TC', 'PX', + 'IX', 'SG'); + + my @macro_man = ('BR', 'IB', 'IR', 'RB', 'RI', 'P', 'TH', 'TP', 'SS', + 'HP', 'PD', + 'AT', 'UC', + 'SB', + 'EE', 'EX', + 'OP', + 'MT', 'ME', 'SY', 'YS', 'TQ', 'UR', 'UE'); + + my @macro_man_or_ms = ('B', 'I', 'BI', + 'DT', + 'RS', 'RE', + 'SH', + 'SM', + 'IP', 'LP', 'PP'); + + for my $key (@macro_man_or_ms, @macro_man, @macro_ms) { + $score{$key} = 0 unless exists $score{$key}; + } + + # Compute a score for each package by counting occurrences of their + # characteristic macros. + foreach my $key (@macro_man_or_ms) { + $man_score += $score{$key}; + $ms_score += $score{$key}; + } + + foreach my $key (@macro_man) { + $man_score += $score{$key}; + } + + foreach my $key (@macro_ms) { + $ms_score += $score{$key}; + } + + if (!$ms_score && !$man_score) { + # The input may be a "raw" roff document; this is not a problem, + # but it does mean no package was inferred. + return 0; + } elsif ($ms_score == $man_score) { + # If there was no TH call, it's not a (valid) man(7) document. + if (!$score{'TH'}) { + &push_main_package('s'); + } else { + &warn("document ambiguous; disambiguate with -man or -ms option"); + $had_inference_problem = 1; + } + return 0; + } elsif ($ms_score > $man_score) { + &push_main_package('s'); + } else { + &push_main_package('an'); + } + + return 1; +} # infer_man_or_ms_package() + + +sub construct_command { + my @main_package = ('an', 'doc', 'doc-old', 'e', 'm', 'om', 's'); + my $file_args_included; # file args now only at 1st preproc + unshift @command, 'groff'; + if (@preprocessor) { + my @progs; + $progs[0] = shift @preprocessor; + push(@progs, @input_file); + for (@preprocessor) { + push @progs, '|'; + push @progs, $_; + } + push @progs, '|'; + unshift @command, @progs; + $file_args_included = 1; + } else { + $file_args_included = 0; + } + + foreach (@command) { + next unless /\s/; + # when one argument has several words, use accents + $_ = "'" . $_ . "'"; + } + + my $have_ambiguous_main_package = 0; + my $inferred_main_package_count = scalar @inferred_main_package; + + # Did we infer multiple full-service packages? + if ($inferred_main_package_count > 1) { + $have_ambiguous_main_package = 1; + # For each one the user explicitly requested... + for my $pkg (@requested_package) { + # ...did it resolve the ambiguity for us? + if (grep(/$pkg/, @inferred_main_package)) { + @inferred_main_package = ($pkg); + $have_ambiguous_main_package = 0; + last; + } + } + } elsif ($inferred_main_package_count == 1) { + $main_package = shift @inferred_main_package; + } + + if ($have_ambiguous_main_package) { + # TODO: Alphabetical is probably not the best ordering here. We + # should tally up scores on a per-package basis generally, not just + # for an and s. + for my $pkg (@main_package) { + if (grep(/$pkg/, @inferred_main_package)) { + $main_package = $pkg; + &warn("document ambiguous (choosing '$main_package'" + . " from '@inferred_main_package'); disambiguate with -m" + . " option"); + $had_inference_problem = 1; + last; + } + } + } + + # If a full-service package was explicitly requested, warn if the + # inference differs from the request. This also ensures that all -m + # arguments are placed in the same order that the user gave them; + # caveat dictator. + my @auxiliary_package_argument = (); + for my $pkg (@requested_package) { + my $is_auxiliary_package = 1; + if (grep(/$pkg/, @main_package)) { + $is_auxiliary_package = 0; + if ($pkg ne $main_package) { + &warn("overriding inferred package '$main_package'" + . " with requested package '$pkg'"); + $main_package = $pkg; + } + } + if ($is_auxiliary_package) { + push @auxiliary_package_argument, "-m" . $pkg; + } + } + + push @command, '-m' . $main_package if ($main_package); + push @command, @auxiliary_package_argument; + push @command, @input_file unless ($file_args_included); + + ######### + # execute the 'groff' command here with option '--run' + if ( $do_run ) { # with --run + print STDERR "@command\n"; + my $cmd = join ' ', @command; + system($cmd); + } else { + print "@command\n"; + } +} # construct_command() + + +sub usage { + my $stream = *STDOUT; + my $had_error = shift; + $stream = *STDERR if $had_error; + my $grog = $program_name; + print $stream "usage: $grog [--ligatures] [--run]" . + " [groff-option ...] [--] [file ...]\n" . + "usage: $grog {-v | --version}\n" . + "usage: $grog {-h | --help}\n"; + unless ($had_error) { + print $stream "\n" . +"Read each roff(7) input FILE and attempt to infer an appropriate\n" . +"groff(1) command to format it. See the grog(1) manual page.\n"; + } + exit $had_error; +} + + +sub version { + print "GNU $program_name (groff) $groff_version\n"; + exit 0; +} # version() + + +# initialize + +my $in_unbuilt_source_tree = 0; +{ + my $at = '@'; + $in_unbuilt_source_tree = 1 if ('@VERSION@' eq "${at}VERSION${at}"); +} + +$groff_version = '@VERSION@' unless ($in_unbuilt_source_tree); + +&process_arguments(); +&process_input(); + +if ($have_any_valid_arguments) { + &infer_preprocessors(); + &infer_man_or_ms_package() if (scalar @inferred_main_package != 1); + &construct_command(); +} + +exit 2 if ($had_processing_problem); +exit 1 if ($had_inference_problem); +exit 0; + +# Local Variables: +# fill-column: 72 +# mode: CPerl +# End: +# vim: set cindent noexpandtab shiftwidth=2 softtabstop=2 textwidth=72: diff --git a/src/utils/grog/tests/PF-does-not-start-pic-region.sh b/src/utils/grog/tests/PF-does-not-start-pic-region.sh new file mode 100755 index 0000000..d3b871f --- /dev/null +++ b/src/utils/grog/tests/PF-does-not-start-pic-region.sh @@ -0,0 +1,33 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +grog="${abs_top_builddir:-.}/grog" + +# Regression test Savannah #60772. +# +# .PF does not _start_ a pic(1) region; it ends one. + +DOC='.PF +.PE' + +echo "$DOC" | "$grog" \ + | grep -Fqx 'groff -' + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/utils/grog/tests/avoid-refer-fakeout.sh b/src/utils/grog/tests/avoid-refer-fakeout.sh new file mode 100755 index 0000000..f163bed --- /dev/null +++ b/src/utils/grog/tests/avoid-refer-fakeout.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +grog="${abs_top_builddir:-.}/grog" + +# Regression-test Savannah #61520. +# +# Don't be fooled by documents (like xterm's ctlseqs.ms) that define +# macros with names that start with '[' or ']'. + +input=".de [] +.. +.[] foo" + +echo "$input" | "$grog" | grep -Fqx 'groff -' + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/utils/grog/tests/foo.man b/src/utils/grog/tests/foo.man new file mode 100644 index 0000000..28e9fe6 --- /dev/null +++ b/src/utils/grog/tests/foo.man @@ -0,0 +1,146 @@ +.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. \*(C+ will +.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +.\" nothing in troff, for use with C<>. +.tr \(*W- +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +. ds C` +. ds C' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is >0, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX +.. +.nr rF 0 +.if \n(.g .if rF .nr rF 1 +.if (\n(rF:(\n(.g==0)) \{\ +. if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 +. \} +. \} +.\} +.rr rF +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "FOO 1" +.TH FOO 1 "2021-06-30" "perl v5.28.1" "User Contributed Perl Documentation" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH "Name" +.IX Header "Name" +foo \- a frobnicator +.SH "Description" +.IX Header "Description" +This is my program. diff --git a/src/utils/grog/tests/preserve-groff-options.sh b/src/utils/grog/tests/preserve-groff-options.sh new file mode 100755 index 0000000..3290798 --- /dev/null +++ b/src/utils/grog/tests/preserve-groff-options.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +grog="${abs_top_builddir:-.}/grog" + +# Regression test Savannah #57873. +# +# Don't mangle groff options. + +echo | "$grog" -ww -fN -P-pa5 -ra5=0 \ + | grep -Fqx 'groff -ww -fN -P-pa5 -ra5=0 -' + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/utils/grog/tests/recognize-perl-pod.sh b/src/utils/grog/tests/recognize-perl-pod.sh new file mode 100755 index 0000000..bc13ece --- /dev/null +++ b/src/utils/grog/tests/recognize-perl-pod.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +grog="${abs_top_builddir:-.}/grog" +doc="${abs_top_srcdir:-..}/src/utils/grog/tests/foo.man" + +# Regression test Savannah #59622. +# +# Recognize the strongly-accented dialect of man(7) produced by +# pod2man(1). + +"$grog" "$doc" | grep '^groff -man .*/src/utils/grog/tests/foo\.man' + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/utils/grog/tests/smoke-test.sh b/src/utils/grog/tests/smoke-test.sh new file mode 100755 index 0000000..2da1fc4 --- /dev/null +++ b/src/utils/grog/tests/smoke-test.sh @@ -0,0 +1,153 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +set -e + +grog="${abs_top_builddir:-.}/grog" +src="${abs_top_srcdir:-..}" + +doc=src/preproc/eqn/neqn.1 +echo "testing simple man(7) page $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -man '"$doc" + +doc=src/preproc/tbl/tbl.1 +echo "testing tbl(1)-using man(7) page $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -t -man '"$doc" + +doc=man/groff_diff.7 +echo "testing eqn(1)-using man(7) page $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -e -man '"$doc" + +# BUG: grog doesn't yet handle .if, .ie, .while. +#doc=src/preproc/soelim/soelim.1 +#echo "testing pic(1)-using man(7) page $doc" >&2 +#"$grog" "$doc" | \ +# grep -Fqx 'groff -p -man '"$doc" + +doc=tmac/groff_mdoc.7 +echo "testing tbl(1)-using mdoc(7) page $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -t -mdoc '"$doc" + +doc=$src/doc/meintro.me.in +echo "testing me(7) document $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -me '"$doc" + +doc=$src/doc/meintro_fr.me.in +echo "testing tbl(1)-using me(7) document $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -t -me '"$doc" + +doc=$src/doc/meref.me.in +echo "testing me(7) document $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -me '"$doc" + +doc=$src/doc/grnexmpl.me +echo "testing grn(1)- and eqn(1)-using me(7) document $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -e -g -me '"$doc" + +doc=$src/contrib/mm/examples/letter.mm +echo "testing mm(7) document $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -mm '"$doc" + +doc=$src/contrib/mom/examples/copyright-chapter.mom +echo "testing mom(7) document $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -mom '"$doc" + +doc=$src/contrib/mom/examples/copyright-default.mom +echo "testing mom(7) document $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -mom '"$doc" + +doc=$src/contrib/mom/examples/letter.mom +echo "testing mom(7) document $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -mom '"$doc" + +doc=$src/contrib/mom/examples/mom-pdf.mom +echo "testing mom(7) document $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -mom '"$doc" + +doc=$src/contrib/mom/examples/mon_premier_doc.mom +echo "testing mom(7) document $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -mom '"$doc" + +doc=$src/contrib/mom/examples/sample_docs.mom +echo "testing mom(7) document $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -mom '"$doc" + +doc=$src/contrib/mom/examples/slide-demo.mom +echo "testing mom(7) document $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -e -p -t -mom '"$doc" + +doc=$src/contrib/mom/examples/typesetting.mom +echo "testing mom(7) document $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -mom '"$doc" + +doc=$src/contrib/pdfmark/cover.ms +echo "testing ms(7) document $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -ms '"$doc" + +doc=$src/contrib/pdfmark/pdfmark.ms +echo "testing ms(7) document $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -ms '"$doc" + +doc=$src/doc/ms.ms +echo "testing eqn(1)- and tbl(1)-using ms(7) document $doc" >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -e -t -ms '"$doc" + +doc=$src/doc/pic.ms +echo "testing tbl(1)-, eqn(1)-, and pic(1)-using ms(7) document $doc" \ + >&2 +"$grog" "$doc" | \ + grep -Fqx 'groff -e -p -t -ms '"$doc" + +doc=$src/doc/webpage.ms +echo "testing ms(7) document $doc" >&2 +# BUG: Should detect -mwww (and -mpspic?) too. +"$grog" "$doc" | \ + grep -Fqx 'groff -ms '"$doc" + +# Test manual specification of auxiliary macro packages. +echo "testing ms(7) document $doc with '-m www' option" >&2 +"$grog" "$doc" -m www | \ + grep -Fqx 'groff -ms -mwww '"$doc" + +echo "testing ms(7) document $doc with '-mwww' option" >&2 +"$grog" "$doc" -mwww | \ + grep -Fqx 'groff -ms -mwww '"$doc" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/src/utils/hpftodit/hpftodit.1.man b/src/utils/hpftodit/hpftodit.1.man new file mode 100644 index 0000000..12e3af7 --- /dev/null +++ b/src/utils/hpftodit/hpftodit.1.man @@ -0,0 +1,476 @@ +.TH hpftodit @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +hpftodit \- create font description files for use with +.I groff +and +.I grolj4 +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1994-2020 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_hpftodit_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY hpftodit +.RB [ \-aqs ] +.RB [ \-i\~\c +.IR n ] +.I tfm-file +.I map-file +.I font-description +.YS +. +. +.SY hpftodit +.B \-d +.I tfm-file +.RI [ map-file ] +.YS +. +. +.SY hpftodit +.B \-\-help +.YS +. +. +.SY hpftodit +.B \-v +. +.SY hpftodit +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I hpftodit +creates a font description file for use with a Hewlett-Packard +LaserJet\~4-\%series +(or newer) +printer with the +.MR grolj4 @MAN1EXT@ +output driver of +.MR groff @MAN1EXT@ , +using data from an HP tagged font metric (TFM) file. +. +.I tfm-file +is the name of the font's TFM file; +Intellifont and TrueType TFM files are supported, +but symbol set TFM files are not. +. +.I map-file +is a file giving the +.I groff +special character identifiers for glyphs in the font; +this file should consist of a sequence of lines of the form +.RS +.EX +.IR "m u c1 c2 " "\&.\|.\|.\& [#" " comment" "]" +.EE +.RE +where +.I m +is a decimal integer giving the glyph's MSL +(Master Symbol List) +number, +.I u +is a hexadecimal integer giving its Unicode character code, +and +.IR c1 , +.IR c2 ", .\|.\|." +are its +.I groff +glyph names +(see +.MR groff_char @MAN7EXT@ +for a list). +. +The values can be separated by any number of spaces and/or tabs. +. +The Unicode value must use uppercase hexadecimal digits A\^\[en]\^F, +and must lack a leading +.RB \[lq] 0x \[rq], +.RB \[lq] u \[rq], +or +.RB \[lq] U+ \[rq]. +. +Unicode values corresponding to composite glyphs are decomposed; +that is +.RB \[lq] u00C0 \[rq] +becomes +.RB \[lq] u0041_0300 \[rq]. +. +A glyph without a +.I groff +special character identifier may be named +.BI u XXXX +if the glyph corresponds to a Unicode value, +or as an unnamed glyph +.RB \[lq] \-\-\- \[rq]. +. +If the given Unicode value is in the Private Use Area (PUA) +(0xE000\^\[en]\^0xF8FF), +the glyph is included as an unnamed glyph. +. +Refer to +.MR groff_diff @MAN1EXT@ +for additional information about unnamed glyphs and how to access them. +. +. +.P +Blank lines and lines beginning with +.RB \[lq] # \[rq] +are ignored. +. +A +.RB \[lq] # \[rq] +following one or more +.I groff +names begins a comment. +. +Because +.RB \[lq] # \[rq] +is a valid +.I groff +name, +it must appear first in a list of +.I groff +names if a comment is included, +as in +. +.RS +.EX +3 0023 # # number sign +.EE +.RE +. +or +. +.RS +.EX +3 0023 # sh # number sign +.EE +.RE +. +whereas in +. +.RS +.EX +3 0023 sh # # number sign +.EE +.RE +. +the first +.RB \[lq] # \[rq] +is interpreted as the beginning of the comment. +. +. +.P +Output is written in +.MR groff_font @MAN5EXT@ +format to +.I font-description, +a file named for the intended +.I groff +font name; +if this operand is +.RB \[lq] \- \[rq], +the font description is written to the standard output stream. +. +. +.LP +If the +.B \-i +option is used, +.I hpftodit +automatically will generate an italic correction, +a left italic correction, +and a subscript correction for each glyph +(the significance of these parameters is explained in +.MR groff_font @MAN5EXT@ ). +. +. +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-\-help +displays a usage message, +while +.B \-v +and +.B \-\-version +show version information; +all exit afterward. +. +. +.TP +.B \-a +Include glyphs in the TFM file that are not included in +.IR map-file . +. +A glyph with corresponding Unicode value is given the name +.RI u XXXX ; +a glyph without a Unicode value is included as an unnamed glyph +\[lq]\-\^\-\^\-\[rq]. +. +A glyph with a Unicode value in the Private Use Area +(0xE000\^\[en]\^0xF8FF) +is also included as an unnamed glyph. +. +. +.IP +This option provides a simple means of adding Unicode-named and +unnamed glyphs to a font without including them in the map file, +but it affords little control over which glyphs are placed in a regular +font and which are placed in a special font. +. +The presence or absence of the +.B \-s +option has some effect on which glyphs are included: +without it, +only the \[lq]text\[rq] symbol sets are searched for matching glyphs; +with it, +only the \[lq]mathematical\[rq] symbol sets are searched. +. +Nonetheless, +restricting the symbol sets searched isn't very selective\[em]many +glyphs are placed in both regular and special fonts. +. +Normally, +.B \-a +should be used only as a last resort. +. +. +.TP +.B \-d +Dump information about the TFM file to the standard output stream; +use this to ensure that a TFM file is a proper match for a font, +and that its contents are suitable. +. +The information includes the values of important TFM tags and a listing +(by MSL number for Intellifont TFM files or by Unicode value for +TrueType TFM files) +of the glyphs included in the TFM file. +. +The unit of measure \[lq]DU\[rq] for some tags indicates design units; +there are 8782\~design units per em for Intellifont fonts, +and 2048\~design units per em for TrueType fonts. +. +Note that the accessibility of a glyph depends on its inclusion in a +symbol set; +some TFM files list many glyphs but only a few symbol sets. +. +. +.IP +The glyph listing includes the glyph index within the TFM file, +the MSL or Unicode value, +and the symbol set and character code that will be used to print the +glyph. +. +If +.I map-file +is given, +.I groff +names are given for matching glyphs. +. +If only the glyph index and MSL or Unicode value are given, +the glyph does not appear in any supported symbol set and cannot be +printed. +. +. +.IP +With the +.B \-d +option, +.I map-file +is optional, +and +.I output-font +is ignored if given. +. +. +.TP +.BI \-i\~ n +Generate an italic correction for each glyph so that its width plus its +italic correction is equal to +.I n +thousandths of an em plus the amount by which the right edge of the +glyphs's bounding box is to the right of its origin. +. +If a negative italic correction would result, +use a zero italic correction instead. +. +. +.IP +Also generate a subscript correction equal to the product of the tangent +of the slant of the font and four fifths of the x-height of the font. +. +If a subscript correction greater than the italic correction would +result, +use a subscript correction equal to the italic correction instead. +. +. +.IP +Also generate a left italic correction for each glyph equal to +.I n +thousandths of an em plus the amount by which the left edge of the +glyphs's bounding box is to the left of its origin. +. +The left italic correction may be negative. +. +. +.IP +This option normally is needed only with italic or oblique fonts; +a value of 50 +(0.05\~em) +usually is a reasonable choice. +. +. +.TP +.B \-q +Suppress warnings about glyphs in the map file that were not found in +the TFM file. +. +Warnings never are given for unnamed glyphs or by glyphs named by their +Unicode values. +. +This option is useful when sending the output of +.I hpftodit +to the standard output stream. +. +. +.TP +.B \-s +Add the +.B special +directive to the font description file, +affecting the order in which HP symbol sets are searched for each glyph. +. +Without this option, +the \[lq]text\[rq] sets are searched before the \[lq]mathematical\[rq] +symbol sets. +. +With it, +the search order is reversed. +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.I @FONTDIR@/\:\%devlj4/\:DESC +describes the +.B lj4 +output device. +. +. +.TP +.IR @FONTDIR@/\:\%devlj4/ F +describes the font known +.RI as\~ F +on device +.BR lj4 . +. +. +.TP +.I @FONTDIR@/\:\%devlj4/\:\%generate/\:\%Makefile +is a +.MR make 1 +script that uses +.MR hpftodit @MAN1EXT@ +to prepare the +.I groff +font description files above from HP TFM data; +in can be used to regenerate them in the event the TFM files are +updated. +. +. +.TP +.I @FONTDIR@/\:\%devlj4/\:\%generate/\:\%special\:.awk +is an +.MR awk 1 +script that corrects the Intellifont-based height metrics for several +glyphs in the +.B S +(special) font for TrueType CG Times used in the HP LaserJet\~4000 and +later. +. +. +.TP +.I @FONTDIR@/\:\%devlj4/\:\%generate/\:\%special\:.map +.TQ +.I @FONTDIR@/\:\%devlj4/\:\%generate/\:\%symbol\:.map +.TQ +.I @FONTDIR@/\:\%devlj4/\:\%generate/\:text\:.map +.TQ +.I @FONTDIR@/\:\%devlj4/\:\%generate/\:\%wingdings.map +map MSL indices and HP Unicode PUA assignments to +.I groff +special character identifiers. +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.MR groff @MAN1EXT@ , +.MR groff_diff @MAN1EXT@ , +.MR grolj4 @MAN1EXT@ , +.MR groff_font @MAN5EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_hpftodit_1_man_C] +.do rr *groff_hpftodit_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/utils/hpftodit/hpftodit.am b/src/utils/hpftodit/hpftodit.am new file mode 100644 index 0000000..e31e8f5 --- /dev/null +++ b/src/utils/hpftodit/hpftodit.am @@ -0,0 +1,34 @@ +# Automake rules for 'src utils hpftodit' +# +# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# +# '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 2 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 +# . +# +######################################################################## + +bin_PROGRAMS += hpftodit +man1_MANS += src/utils/hpftodit/hpftodit.1 +EXTRA_DIST += src/utils/hpftodit/hpftodit.1.man +hpftodit_LDADD = libgroff.a $(LIBM) lib/libgnu.a +hpftodit_SOURCES = \ + src/utils/hpftodit/hpftodit.cpp \ + src/utils/hpftodit/hpuni.cpp + + +# Local Variables: +# mode: makefile-automake +# fill-column: 72 +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/utils/hpftodit/hpftodit.cpp b/src/utils/hpftodit/hpftodit.cpp new file mode 100644 index 0000000..4982e19 --- /dev/null +++ b/src/utils/hpftodit/hpftodit.cpp @@ -0,0 +1,1465 @@ +/* Copyright (C) 1994-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +/* +TODO +devise new names for useful characters +option to specify symbol sets to look in +put filename in error messages (or fix lib) +*/ + +#include "lib.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "posix.h" +#include "errarg.h" +#include "error.h" +#include "cset.h" +#include "nonposix.h" +#include "unicode.h" + +extern "C" const char *Version_string; +extern const char *hp_msl_to_unicode_code(const char *); + +#define SIZEOF(v) (sizeof(v)/sizeof(v[0])) +#define equal(a, b) (strcmp(a, b) == 0) +// only valid if is_uname(c) has returned true +#define is_decomposed(c) strchr(c, '_') + +#define NO 0 +#define YES 1 + +#define MSL 0 +#define SYMSET 1 +#define UNICODE 2 + +#define UNNAMED "---" + +static double multiplier = 3.0; // make Agfa-based unitwidth an integer + +inline +int scale(int n) +{ + return int(n * multiplier + 0.5); +} + +// tags in TFM file + +enum tag_type { + min_tag = 400, + type_tag = 400, + copyright_tag = 401, + comment_tag = 402, + charcode_tag = 403, // MSL for Intellifont, Unicode for TrueType + symbol_set_tag = 404, + unique_identifier_tag = 405, + inches_per_point_tag = 406, + nominal_point_size_tag = 407, + design_units_per_em_tag = 408, + posture_tag = 409, + type_structure_tag = 410, + stroke_weight_tag = 411, + spacing_tag = 412, + slant_tag = 413, + appearance_width_tag = 414, + serif_style_tag = 415, + font_name_tag = 417, + typeface_source_tag = 418, + average_width_tag = 419, + max_width_tag = 420, + word_spacing_tag = 421, + recommended_line_spacing_tag = 422, + cap_height_tag = 423, + x_height_tag = 424, + max_ascent_tag = 425, + max_descent_tag = 426, + lower_ascent_tag = 427, + lower_descent_tag = 428, + underscore_depth_tag = 429, + underscore_thickness_tag = 430, + uppercase_accent_height_tag = 431, + lowercase_accent_height_tag = 432, + width_tag = 433, + vertical_escapement_tag = 434, + left_extent_tag = 435, + right_extent_tag = 436, + ascent_tag = 437, + descent_tag = 438, + pair_kern_tag = 439, + sector_kern_tag = 440, + track_kern_tag = 441, + typeface_tag = 442, + panose_tag = 443, + max_tag = 443 +}; + +const char *tag_name[] = { + "Symbol Set", + "Font Type" // MSL for Intellifont, Unicode for TrueType +}; + +// types in TFM file +enum { + BYTE_TYPE = 1, + ASCII_TYPE = 2, // NUL-terminated string + USHORT_TYPE = 3, + LONG_TYPE = 4, // unused + RATIONAL_TYPE = 5, // 8-byte numerator + 8-byte denominator + SIGNED_BYTE_TYPE = 16, // unused + SIGNED_SHORT_TYPE = 17, + SIGNED_LONG_TYPE = 18 // unused +}; + +typedef unsigned char byte; +typedef unsigned short uint16; +typedef short int16; +typedef unsigned int uint32; + +class File { +public: + File(const char *); + void skip(int n); + byte get_byte(); + uint16 get_uint16(); + uint32 get_uint32(); + uint32 get_uint32(char *orig); + void seek(uint32 n); +private: + unsigned char *buf_; + const unsigned char *ptr_; + const unsigned char *end_; +}; + +struct entry { + char present; + uint16 type; + uint32 count; + uint32 value; + char orig_value[4]; + entry() : present(0) { } +}; + +struct char_info { + uint16 charcode; + uint16 width; + int16 ascent; + int16 descent; + int16 left_extent; + uint16 right_extent; + uint16 symbol_set; + unsigned char code; +}; + +const uint16 NO_GLYPH = 0xffff; +const uint16 NO_SYMBOL_SET = 0; + +struct name_list { + char *name; + name_list *next; + name_list(const char *s, name_list *p) : name(strsave(s)), next(p) { } + ~name_list() { delete[] name; } +}; + +struct symbol_set { + uint16 select; + uint16 index[256]; +}; + +#define SYMBOL_SET(n, c) ((n) * 32 + ((c) - 64)) + +uint16 text_symbol_sets[] = { + SYMBOL_SET(19, 'U'), // Windows Latin 1 ("ANSI", code page 1252) + SYMBOL_SET(9, 'E'), // Windows Latin 2, Code Page 1250 + SYMBOL_SET(5, 'T'), // Code Page 1254 + SYMBOL_SET(7, 'J'), // Desktop + SYMBOL_SET(6, 'J'), // Microsoft Publishing + SYMBOL_SET(0, 'N'), // Latin 1 (subset of 19U, + // so we should never get here) + SYMBOL_SET(2, 'N'), // Latin 2 (subset of 9E, + // so we should never get here) + SYMBOL_SET(8, 'U'), // HP Roman 8 + SYMBOL_SET(10, 'J'), // PS Standard + SYMBOL_SET(9, 'U'), // Windows 3.0 "ANSI" + SYMBOL_SET(1, 'U'), // U.S. Legal + + SYMBOL_SET(12, 'J'), // MC Text + SYMBOL_SET(10, 'U'), // PC Code Page 437 + SYMBOL_SET(11, 'U'), // PC Code Page 437N + SYMBOL_SET(17, 'U'), // PC Code Page 852 + SYMBOL_SET(12, 'U'), // PC Code Page 850 + SYMBOL_SET(9, 'T'), // PC Code Page 437T + 0 +}; + +uint16 special_symbol_sets[] = { + SYMBOL_SET(8, 'M'), // Math 8 + SYMBOL_SET(5, 'M'), // PS Math + SYMBOL_SET(15, 'U'), // Pi font + SYMBOL_SET(13, 'J'), // Ventura International + SYMBOL_SET(19, 'M'), // Symbol font + SYMBOL_SET(579, 'L'), // Wingdings + 0 +}; + +entry tags[max_tag + 1 - min_tag]; + +char_info *char_table; +uint32 nchars = 0; + +unsigned int charcode_name_table_size = 0; +name_list **charcode_name_table = NULL; + +symbol_set *symbol_set_table; +unsigned int n_symbol_sets; + +static int debug_flag = NO; +static int special_flag = NO; // not a special font +static int italic_flag = NO; // don't add italic correction +static int italic_sep; +static int all_flag = NO; // don't include glyphs not in mapfile +static int quiet_flag = NO; // don't suppress warnings about symbols not found + +static char *hp_msl_to_ucode_name(int); +static char *unicode_to_ucode_name(int); +static int is_uname(char *); +static char *show_symset(unsigned int); +static void usage(FILE *); +static void usage(); +static const char *xbasename(const char *); +static void read_tags(File &); +static int check_type(); +static void check_units(File &, const int, double *, double *); +static int read_map(const char *, const int); +static void require_tag(tag_type); +static void dump_ascii(File &, tag_type); +static void dump_tags(File &); +static void dump_symbol_sets(File &); +static void dump_symbols(int); +static void output_font_name(File &); +static void output_spacewidth(); +static void output_pclweight(); +static void output_pclproportional(); +static void read_and_output_pcltypeface(File &); +static void output_pclstyle(); +static void output_slant(); +static void output_ligatures(); +static void read_symbol_sets(File &); +static void read_and_output_kernpairs(File &); +static void output_charset(const int); +static void read_char_table(File &); + +inline +entry &tag_info(tag_type t) +{ + return tags[t - min_tag]; +} + +int +main(int argc, char **argv) +{ + program_name = argv[0]; + + int opt; + int res = 1200; // PCL unit of measure for cursor moves + int scalesize = 4; // LaserJet 4 only allows 1/4 point increments + int unitwidth = 6350; + double ppi; // points per inch + double upem; // design units per em + + static const struct option long_options[] = { + { "help", no_argument, 0, CHAR_MAX + 1 }, + { "version", no_argument, 0, 'v' }, + { NULL, 0, 0, 0 } + }; + while ((opt = getopt_long(argc, argv, "adsqvi:", long_options, NULL)) != EOF) { + switch (opt) { + case 'a': + all_flag = YES; + break; + case 'd': + debug_flag = YES; + break; + case 's': + special_flag = YES; + break; + case 'i': + italic_flag = YES; + italic_sep = atoi(optarg); // design units + break; + case 'q': + quiet_flag = YES; // suppress warnings about symbols not found + break; + case 'v': + printf("GNU hpftodit (groff) version %s\n", Version_string); + exit(0); + break; + case CHAR_MAX + 1: // --help + usage(stdout); + exit(0); + break; + case '?': + usage(); + break; + default: + assert(0); + } + } + + if (debug_flag && argc - optind < 1) + usage(); + else if (!debug_flag && argc - optind != 3) + usage(); + File f(argv[optind]); + read_tags(f); + int tfm_type = check_type(); + if (debug_flag) + dump_tags(f); + if (!debug_flag && !read_map(argv[optind + 1], tfm_type)) + exit(1); + else if (debug_flag && argc - optind > 1) + read_map(argv[optind + 1], tfm_type); + current_filename = NULL; + current_lineno = -1; // no line numbers + if (!debug_flag && !equal(argv[optind + 2], "-")) + if (freopen(argv[optind + 2], "w", stdout) == NULL) + fatal("cannot open '%1': %2", argv[optind + 2], strerror(errno)); + current_filename = argv[optind]; + + check_units(f, tfm_type, &ppi, &upem); + if (tfm_type == UNICODE) // don't calculate for Intellifont TFMs + multiplier = double(res) / upem / ppi * unitwidth / scalesize; + if (italic_flag) + // convert from thousandths of an em to design units + italic_sep = int(italic_sep * upem / 1000 + 0.5); + + read_char_table(f); + if (nchars == 0) + fatal("no characters"); + + if (!debug_flag) { + output_font_name(f); + printf("name %s\n", xbasename(argv[optind + 2])); + if (special_flag) + printf("special\n"); + output_spacewidth(); + output_slant(); + read_and_output_pcltypeface(f); + output_pclproportional(); + output_pclweight(); + output_pclstyle(); + } + read_symbol_sets(f); + if (debug_flag) + dump_symbols(tfm_type); + else { + output_ligatures(); + read_and_output_kernpairs(f); + output_charset(tfm_type); + } + return 0; +} + +static void +usage(FILE *stream) +{ + fprintf(stream, +"usage: %s [-aqs] [-i n] tfm-file map-file output-font\n" +"usage: %s -d tfm-file [map-file]\n" +"usage: %s {-v | --version}\n" +"usage: %s --help\n", + program_name, program_name, program_name, program_name); +} + +static void +usage() +{ + usage(stderr); + exit(1); +} + +File::File(const char *s) +{ + // We need to read the file in binary mode because hpftodit relies + // on byte counts. + int fd = open(s, O_RDONLY | O_BINARY); + if (fd < 0) + fatal("cannot open '%1': %2", s, strerror(errno)); + current_filename = s; + struct stat sb; + if (fstat(fd, &sb) < 0) + fatal("cannot stat: %1", strerror(errno)); + if (!S_ISREG(sb.st_mode)) + fatal("not a regular file"); + buf_ = new unsigned char[sb.st_size]; + long nread = read(fd, buf_, sb.st_size); + if (nread < 0) + fatal("read error: %1", strerror(errno)); + if (nread != sb.st_size) + fatal("read unexpected number of bytes"); + ptr_ = buf_; + end_ = buf_ + sb.st_size; +} + +void +File::skip(int n) +{ + if (end_ - ptr_ < n) + fatal("unexpected end of file"); + ptr_ += n; +} + +void +File::seek(uint32 n) +{ + if (uint32(end_ - buf_) < n) + fatal("unexpected end of file"); + ptr_ = buf_ + n; +} + +byte +File::get_byte() +{ + if (ptr_ >= end_) + fatal("unexpected end of file"); + return *ptr_++; +} + +uint16 +File::get_uint16() +{ + if (end_ - ptr_ < 2) + fatal("unexpected end of file"); + uint16 n = *ptr_++; + return n + (*ptr_++ << 8); +} + +uint32 +File::get_uint32() +{ + if (end_ - ptr_ < 4) + fatal("unexpected end of file"); + uint32 n = *ptr_++; + for (int i = 0; i < 3; i++) + n += *ptr_++ << (i + 1)*8; + return n; +} + +uint32 +File::get_uint32(char *orig) +{ + if (end_ - ptr_ < 4) + fatal("unexpected end of file"); + unsigned char v = *ptr_++; + uint32 n = v; + orig[0] = v; + for (int i = 1; i < 4; i++) { + v = *ptr_++; + orig[i] = v; + n += v << i*8; + } + return n; +} + +static void +read_tags(File &f) +{ + if (f.get_byte() != 'I' || f.get_byte() != 'I') + fatal("not an Intel format TFM file"); + f.skip(6); + uint16 ntags = f.get_uint16(); + entry dummy; + for (uint16 i = 0; i < ntags; i++) { + uint16 tag = f.get_uint16(); + entry *p; + if (min_tag <= tag && tag <= max_tag) + p = tags + (tag - min_tag); + else + p = &dummy; + p->present = 1; + p->type = f.get_uint16(); + p->count = f.get_uint32(); + p->value = f.get_uint32(p->orig_value); + } +} + +static int +check_type() +{ + require_tag(type_tag); + int tfm_type = tag_info(type_tag).value; + switch (tfm_type) { + case MSL: + case UNICODE: + break; + case SYMSET: + fatal("cannot handle Symbol Set TFM files"); + break; + default: + fatal("unknown type tag %1", tfm_type); + } + return tfm_type; +} + +static void +check_units(File &f, const int tfm_type, double *ppi, double *upem) +{ + require_tag(design_units_per_em_tag); + f.seek(tag_info(design_units_per_em_tag).value); + uint32 num = f.get_uint32(); + uint32 den = f.get_uint32(); + if (tfm_type == MSL && (num != 8782 || den != 1)) + fatal("design units per em != 8782/1"); + *upem = double(num) / den; + require_tag(inches_per_point_tag); + f.seek(tag_info(inches_per_point_tag).value); + num = f.get_uint32(); + den = f.get_uint32(); + if (tfm_type == MSL && (num != 100 || den != 7231)) + fatal("inches per point not 100/7231"); + *ppi = double(den) / num; +} + +static void +require_tag(tag_type t) +{ + if (!tag_info(t).present) + fatal("tag %1 missing", int(t)); +} + +// put a human-readable font name in the file +static void +output_font_name(File &f) +{ + char *p; + + if (!tag_info(font_name_tag).present) + return; + int count = tag_info(font_name_tag).count; + char *font_name = new char[count]; + + if (count > 4) { // value is a file offset to the string + f.seek(tag_info(font_name_tag).value); + int n = count; + p = font_name; + while (--n) + *p++ = f.get_byte(); + } + else // orig_value contains the string + sprintf(font_name, "%.*s", + count, tag_info(font_name_tag).orig_value); + + // remove any trailing space + p = font_name + count - 1; + while (csspace(*--p)) + ; + *(p + 1) = '\0'; + printf("# %s\n", font_name); + delete[] font_name; +} + +static void +output_spacewidth() +{ + require_tag(word_spacing_tag); + printf("spacewidth %d\n", scale(tag_info(word_spacing_tag).value)); +} + +static void +read_symbol_sets(File &f) +{ + uint32 symbol_set_dir_length = tag_info(symbol_set_tag).count; + uint16 *symbol_set_selectors; + n_symbol_sets = symbol_set_dir_length/14; + symbol_set_table = new symbol_set[n_symbol_sets]; + unsigned int i; + + for (i = 0; i < nchars; i++) + char_table[i].symbol_set = NO_SYMBOL_SET; + + for (i = 0; i < n_symbol_sets; i++) { + f.seek(tag_info(symbol_set_tag).value + i*14); + (void)f.get_uint32(); // offset to symbol set name + uint32 off1 = f.get_uint32(); // offset to selection string + uint32 off2 = f.get_uint32(); // offset to symbol set index array + + f.seek(off1); + uint16 kind = 0; // HP-GL "Kind 1" symbol set value + unsigned int j; + for (j = 0; j < off2 - off1; j++) { + unsigned char c = f.get_byte(); + if ('0' <= c && c <= '9') // value + kind = kind*10 + (c - '0'); + else if ('A' <= c && c <= 'Z') // terminator + kind = kind*32 + (c - 64); + } + symbol_set_table[i].select = kind; + for (j = 0; j < 256; j++) + symbol_set_table[i].index[j] = f.get_uint16(); + } + + symbol_set_selectors = (special_flag ? special_symbol_sets + : text_symbol_sets); + for (i = 0; symbol_set_selectors[i] != 0; i++) { + unsigned int j; + for (j = 0; j < n_symbol_sets; j++) + if (symbol_set_table[j].select == symbol_set_selectors[i]) + break; + if (j < n_symbol_sets) { + for (int k = 0; k < 256; k++) { + uint16 idx = symbol_set_table[j].index[k]; + if (idx != NO_GLYPH + && char_table[idx].symbol_set == NO_SYMBOL_SET) { + char_table[idx].symbol_set = symbol_set_table[j].select; + char_table[idx].code = k; + } + } + } + } + + if (all_flag) + return; + + symbol_set_selectors = (special_flag ? text_symbol_sets + : special_symbol_sets); + for (i = 0; symbol_set_selectors[i] != 0; i++) { + unsigned int j; + for (j = 0; j < n_symbol_sets; j++) + if (symbol_set_table[j].select == symbol_set_selectors[i]) + break; + if (j < n_symbol_sets) { + for (int k = 0; k < 256; k++) { + uint16 idx = symbol_set_table[j].index[k]; + if (idx != NO_GLYPH + && char_table[idx].symbol_set == NO_SYMBOL_SET) { + char_table[idx].symbol_set = symbol_set_table[j].select; + char_table[idx].code = k; + } + } + } + } + return; +} + +static void +read_char_table(File &f) +{ + require_tag(charcode_tag); + nchars = tag_info(charcode_tag).count; + char_table = new char_info[nchars]; + + f.seek(tag_info(charcode_tag).value); + uint32 i; + for (i = 0; i < nchars; i++) + char_table[i].charcode = f.get_uint16(); + + require_tag(width_tag); + f.seek(tag_info(width_tag).value); + for (i = 0; i < nchars; i++) + char_table[i].width = f.get_uint16(); + + require_tag(ascent_tag); + f.seek(tag_info(ascent_tag).value); + for (i = 0; i < nchars; i++) { + char_table[i].ascent = f.get_uint16(); + if (char_table[i].ascent < 0) + char_table[i].ascent = 0; + } + + require_tag(descent_tag); + f.seek(tag_info(descent_tag).value); + for (i = 0; i < nchars; i++) { + char_table[i].descent = f.get_uint16(); + if (char_table[i].descent > 0) + char_table[i].descent = 0; + } + + require_tag(left_extent_tag); + f.seek(tag_info(left_extent_tag).value); + for (i = 0; i < nchars; i++) + char_table[i].left_extent = int16(f.get_uint16()); + + require_tag(right_extent_tag); + f.seek(tag_info(right_extent_tag).value); + for (i = 0; i < nchars; i++) + char_table[i].right_extent = f.get_uint16(); +} + +static void +output_pclweight() +{ + require_tag(stroke_weight_tag); + int stroke_weight = tag_info(stroke_weight_tag).value; + int pcl_stroke_weight; + if (stroke_weight < 128) + pcl_stroke_weight = -3; + else if (stroke_weight == 128) + pcl_stroke_weight = 0; + else if (stroke_weight <= 145) + pcl_stroke_weight = 1; + else if (stroke_weight <= 179) + pcl_stroke_weight = 3; + else + pcl_stroke_weight = 4; + printf("pclweight %d\n", pcl_stroke_weight); +} + +static void +output_pclproportional() +{ + require_tag(spacing_tag); + printf("pclproportional %d\n", tag_info(spacing_tag).value == 0); +} + +static void +read_and_output_pcltypeface(File &f) +{ + printf("pcltypeface "); + require_tag(typeface_tag); + if (tag_info(typeface_tag).count > 4) { + f.seek(tag_info(typeface_tag).value); + for (uint32 i = 0; i < tag_info(typeface_tag).count; i++) { + unsigned char c = f.get_byte(); + if (c == '\0') + break; + putchar(c); + } + } + else + printf("%.4s", tag_info(typeface_tag).orig_value); + printf("\n"); +} + +static void +output_pclstyle() +{ + unsigned pcl_style = 0; + // older tfms don't have the posture tag + if (tag_info(posture_tag).present) { + if (tag_info(posture_tag).value) + pcl_style |= 1; + } + else { + require_tag(slant_tag); + if (tag_info(slant_tag).value != 0) + pcl_style |= 1; + } + require_tag(appearance_width_tag); + if (tag_info(appearance_width_tag).value < 100) // guess + pcl_style |= 4; + printf("pclstyle %d\n", pcl_style); +} + +static void +output_slant() +{ + require_tag(slant_tag); + int slant = int16(tag_info(slant_tag).value); + if (slant != 0) + printf("slant %f\n", slant/100.0); +} + +static void +output_ligatures() +{ + // don't use ligatures for fixed space font + require_tag(spacing_tag); + if (tag_info(spacing_tag).value != 0) + return; + static const char *ligature_names[] = { + "fi", "fl", "ff", "ffi", "ffl" + }; + + static const char *ligature_chars[] = { + "fi", "fl", "ff", "Fi", "Fl" + }; + + unsigned ligature_mask = 0; + unsigned int i; + for (i = 0; i < nchars; i++) { + uint16 charcode = char_table[i].charcode; + if (charcode < charcode_name_table_size + && char_table[i].symbol_set != NO_SYMBOL_SET) { + for (name_list *p = charcode_name_table[charcode]; p; p = p->next) + for (unsigned int j = 0; j < SIZEOF(ligature_chars); j++) + if (strcmp(p->name, ligature_chars[j]) == 0) { + ligature_mask |= 1 << j; + break; + } + } + } + if (ligature_mask) { + printf("ligatures"); + for (i = 0; i < SIZEOF(ligature_names); i++) + if (ligature_mask & (1 << i)) + printf(" %s", ligature_names[i]); + printf(" 0\n"); + } +} + +static void +read_and_output_kernpairs(File &f) +{ + if (tag_info(pair_kern_tag).present) { + printf("kernpairs\n"); + f.seek(tag_info(pair_kern_tag).value); + uint16 n_pairs = f.get_uint16(); + for (int i = 0; i < n_pairs; i++) { + uint16 i1 = f.get_uint16(); + uint16 i2 = f.get_uint16(); + int16 val = int16(f.get_uint16()); + if (char_table[i1].symbol_set != NO_SYMBOL_SET + && char_table[i2].symbol_set != NO_SYMBOL_SET + && char_table[i1].charcode < charcode_name_table_size + && char_table[i2].charcode < charcode_name_table_size) { + for (name_list *p = charcode_name_table[char_table[i1].charcode]; + p; + p = p->next) + for (name_list *q = charcode_name_table[char_table[i2].charcode]; + q; + q = q->next) + if (!equal(p->name, UNNAMED) && !equal(q->name, UNNAMED)) + printf("%s %s %d\n", p->name, q->name, scale(val)); + } + } + } +} + +static void +output_charset(const int tfm_type) +{ + require_tag(slant_tag); + double slant_angle = int16(tag_info(slant_tag).value)*PI/18000.0; + double slant = sin(slant_angle)/cos(slant_angle); + + if (italic_flag) + require_tag(x_height_tag); + require_tag(lower_ascent_tag); + require_tag(lower_descent_tag); + + printf("charset\n"); + unsigned int i; + for (i = 0; i < nchars; i++) { + uint16 charcode = char_table[i].charcode; + + // the glyph is bound to one of the searched symbol sets + if (char_table[i].symbol_set != NO_SYMBOL_SET) { + // the character was in the map file + if (charcode < charcode_name_table_size && charcode_name_table[charcode]) + printf("%s", charcode_name_table[charcode]->name); + else if (!all_flag) + continue; + else if (tfm_type == MSL) + printf("%s", hp_msl_to_ucode_name(charcode)); + else + printf("%s", unicode_to_ucode_name(charcode)); + + printf("\t%d,%d", + scale(char_table[i].width), scale(char_table[i].ascent)); + + int depth = scale(-char_table[i].descent); + if (depth < 0) + depth = 0; + int italic_correction = 0; + int left_italic_correction = 0; + int subscript_correction = 0; + + if (italic_flag) { + italic_correction = scale(char_table[i].right_extent + - char_table[i].width + + italic_sep); + if (italic_correction < 0) + italic_correction = 0; + subscript_correction = int((tag_info(x_height_tag).value + * slant * .8) + .5); + if (subscript_correction > italic_correction) + subscript_correction = italic_correction; + left_italic_correction = scale(italic_sep + - char_table[i].left_extent); + } + + if (subscript_correction != 0) + printf(",%d,%d,%d,%d", + depth, italic_correction, left_italic_correction, + subscript_correction); + else if (left_italic_correction != 0) + printf(",%d,%d,%d", depth, italic_correction, left_italic_correction); + else if (italic_correction != 0) + printf(",%d,%d", depth, italic_correction); + else if (depth != 0) + printf(",%d", depth); + // This is fairly arbitrary. Fortunately it doesn't much matter. + unsigned type = 0; + if (char_table[i].ascent > int16(tag_info(lower_ascent_tag).value)*9/10) + type |= 2; + if (char_table[i].descent < int16(tag_info(lower_descent_tag).value)*9/10) + type |= 1; + printf("\t%d\t%d", type, + char_table[i].symbol_set*256 + char_table[i].code); + + if (tfm_type == UNICODE) { + if (charcode >= 0xE000 && charcode <= 0xF8FF) + printf("\t-- HP PUA U+%04X", charcode); + else + printf("\t-- U+%04X", charcode); + } + else + printf("\t-- MSL %4d", charcode); + printf(" (%3s %3d)\n", + show_symset(char_table[i].symbol_set), char_table[i].code); + + if (charcode < charcode_name_table_size + && charcode_name_table[charcode]) + for (name_list *p = charcode_name_table[charcode]->next; + p; p = p->next) + printf("%s\t\"\n", p->name); + } + // warnings about characters in mapfile not found in TFM + else if (charcode < charcode_name_table_size + && charcode_name_table[charcode]) { + char *name = charcode_name_table[charcode]->name; + // don't warn about Unicode or unnamed glyphs + // that aren't in the TFM file + if (tfm_type == UNICODE && !quiet_flag && !equal(name, UNNAMED) + && !is_uname(name)) { + fprintf(stderr, "%s: warning: symbol U+%04X (%s", + program_name, charcode, name); + for (name_list *p = charcode_name_table[charcode]->next; + p; p = p->next) + fprintf(stderr, ", %s", p->name); + fprintf(stderr, ") not in any searched symbol set\n"); + } + else if (!quiet_flag && !equal(name, UNNAMED) && !is_uname(name)) { + fprintf(stderr, "%s: warning: symbol MSL %d (%s", + program_name, charcode, name); + for (name_list *p = charcode_name_table[charcode]->next; + p; p = p->next) + fprintf(stderr, ", %s", p->name); + fprintf(stderr, ") not in any searched symbol set\n"); + } + } + } +} + +#define em_fract(a) (upem >= 0 ? double(a)/upem : 0) + +static void +dump_tags(File &f) +{ + double upem = -1.0; + + printf("TFM tags\n" + "\n" + "tag# type count value\n" + "---------------------\n"); + + for (int i = min_tag; i <= max_tag; i++) { + enum tag_type t = tag_type(i); + if (tag_info(t).present) { + printf("%4d %4d %5d", i, tag_info(t).type, tag_info(t).count); + switch (tag_info(t).type) { + case BYTE_TYPE: + case USHORT_TYPE: + printf(" %5u", tag_info(t).value); + switch (i) { + case type_tag: + printf(" Font Type "); + switch (tag_info(t).value) { + case MSL: + case SYMSET: + printf("(Intellifont)"); + break; + case UNICODE: + printf("(TrueType)"); + } + break; + case charcode_tag: + printf(" Number of Symbols (%u)", tag_info(t).count); + break; + case symbol_set_tag: + printf(" Symbol Sets (%u): ", + tag_info(symbol_set_tag).count / 14); + dump_symbol_sets(f); + break; + case type_structure_tag: + printf(" Type Structure (%u)", tag_info(t).value); + break; + case stroke_weight_tag: + printf(" Stroke Weight (%u)", tag_info(t).value); + break; + case spacing_tag: + printf(" Spacing "); + switch (tag_info(t).value) { + case 0: + printf("(Proportional)"); + break; + case 1: + printf("(Fixed Pitch: %u DU: %.2f em)", tag_info(t).value, + em_fract(tag_info(t).value)); + break; + } + break; + case appearance_width_tag: + printf(" Appearance Width (%u)", tag_info(t).value); + break; + case serif_style_tag: + printf(" Serif Style (%u)", tag_info(t).value); + break; + case posture_tag: + printf(" Posture (%s)", tag_info(t).value == 0 + ? "Upright" + : tag_info(t).value == 1 + ? "Italic" + : "Alternate Italic"); + break; + case max_width_tag: + printf(" Maximum Width (%u DU: %.2f em)", tag_info(t).value, + em_fract(tag_info(t).value)); + break; + case word_spacing_tag: + printf(" Interword Spacing (%u DU: %.2f em)", tag_info(t).value, + em_fract(tag_info(t).value)); + break; + case recommended_line_spacing_tag: + printf(" Recommended Line Spacing (%u DU: %.2f em)", tag_info(t).value, + em_fract(tag_info(t).value)); + break; + case x_height_tag: + printf(" x-Height (%u DU: %.2f em)", tag_info(t).value, + em_fract(tag_info(t).value)); + break; + case cap_height_tag: + printf(" Cap Height (%u DU: %.2f em)", tag_info(t).value, + em_fract(tag_info(t).value)); + break; + case max_ascent_tag: + printf(" Maximum Ascent (%u DU: %.2f em)", tag_info(t).value, + em_fract(tag_info(t).value)); + break; + case lower_ascent_tag: + printf(" Lowercase Ascent (%u DU: %.2f em)", tag_info(t).value, + em_fract(tag_info(t).value)); + break; + case underscore_thickness_tag: + printf(" Underscore Thickness (%u DU: %.2f em)", tag_info(t).value, + em_fract(tag_info(t).value)); + break; + case uppercase_accent_height_tag: + printf(" Uppercase Accent Height (%u DU: %.2f em)", tag_info(t).value, + em_fract(tag_info(t).value)); + break; + case lowercase_accent_height_tag: + printf(" Lowercase Accent Height (%u DU: %.2f em)", tag_info(t).value, + em_fract(tag_info(t).value)); + break; + case width_tag: + printf(" Horizontal Escapement array"); + break; + case vertical_escapement_tag: + printf(" Vertical Escapement array"); + break; + case right_extent_tag: + printf(" Right Extent array"); + break; + case ascent_tag: + printf(" Character Ascent array"); + break; + case pair_kern_tag: + f.seek(tag_info(t).value); + printf(" Kern Pairs (%u)", f.get_uint16()); + break; + case panose_tag: + printf(" PANOSE Classification array"); + break; + } + break; + case SIGNED_SHORT_TYPE: + printf(" %5d", int16(tag_info(t).value)); + switch (i) { + case slant_tag: + printf(" Slant (%.2f degrees)", double(tag_info(t).value) / 100); + break; + case max_descent_tag: + printf(" Maximum Descent (%d DU: %.2f em)", int16(tag_info(t).value), + em_fract(int16(tag_info(t).value))); + break; + case lower_descent_tag: + printf(" Lowercase Descent (%d DU: %.2f em)", int16(tag_info(t).value), + em_fract(int16(tag_info(t).value))); + break; + case underscore_depth_tag: + printf(" Underscore Depth (%d DU: %.2f em)", int16(tag_info(t).value), + em_fract(int16(tag_info(t).value))); + break; + case left_extent_tag: + printf(" Left Extent array"); + break; + // The type of this tag has changed from SHORT to SIGNED SHORT + // in TFM version 1.3.0. + case ascent_tag: + printf(" Character Ascent array"); + break; + case descent_tag: + printf(" Character Descent array"); + break; + } + break; + case RATIONAL_TYPE: + printf(" %5u", tag_info(t).value); + switch (i) { + case inches_per_point_tag: + printf(" Inches per Point"); + break; + case nominal_point_size_tag: + printf(" Nominal Point Size"); + break; + case design_units_per_em_tag: + printf(" Design Units per Em"); + break; + case average_width_tag: + printf(" Average Width"); + break; + } + if (tag_info(t).count == 1) { + f.seek(tag_info(t).value); + uint32 num = f.get_uint32(); + uint32 den = f.get_uint32(); + if (i == design_units_per_em_tag) + upem = double(num) / den; + printf(" (%u/%u = %g)", num, den, double(num)/den); + } + break; + case ASCII_TYPE: + printf(" %5u ", tag_info(t).value); + switch (i) { + case comment_tag: + printf("Comment "); + break; + case copyright_tag: + printf("Copyright "); + break; + case unique_identifier_tag: + printf("Unique ID "); + break; + case font_name_tag: + printf("Typeface Name "); + break; + case typeface_source_tag: + printf("Typeface Source "); + break; + case typeface_tag: + printf("PCL Typeface "); + break; + } + dump_ascii(f, t); + } + putchar('\n'); + } + } + putchar('\n'); +} +#undef em_fract + +static void +dump_ascii(File &f, tag_type t) +{ + putchar('"'); + if (tag_info(t).count > 4) { + int count = tag_info(t).count; + f.seek(tag_info(t).value); + while (--count) + printf("%c", f.get_byte()); + } + else + printf("%.4s", tag_info(t).orig_value); + putchar('"'); +} + +static void +dump_symbol_sets(File &f) +{ + uint32 symbol_set_dir_length = tag_info(symbol_set_tag).count; + uint32 num_symbol_sets = symbol_set_dir_length / 14; + + for (uint32 i = 0; i < num_symbol_sets; i++) { + f.seek(tag_info(symbol_set_tag).value + i * 14); + (void)f.get_uint32(); // offset to symbol set name + uint32 off1 = f.get_uint32(); // offset to selection string + uint32 off2 = f.get_uint32(); // offset to symbol set index array + f.seek(off1); + for (uint32 j = 0; j < off2 - off1; j++) { + unsigned char c = f.get_byte(); + if ('0' <= c && c <= '9') + putchar(c); + else if ('A' <= c && c <= 'Z') + printf(i < num_symbol_sets - 1 ? "%c," : "%c", c); + } + } +} + +static void +dump_symbols(int tfm_type) +{ + printf("Symbols:\n" + "\n" + " glyph id# symbol set name(s)\n" + "----------------------------------\n"); + for (uint32 i = 0; i < nchars; i++) { + uint16 charcode = char_table[i].charcode; + if (charcode < charcode_name_table_size + && charcode_name_table[charcode]) { + if (char_table[i].symbol_set != NO_SYMBOL_SET) { + printf(tfm_type == UNICODE ? "%4d (U+%04X) (%3s %3d) %s" + : "%4d (MSL %4d) (%3s %3d) %s", + i, charcode, + show_symset(char_table[i].symbol_set), + char_table[i].code, + charcode_name_table[charcode]->name); + for (name_list *p = charcode_name_table[charcode]->next; + p; p = p->next) + printf(", %s", p->name); + putchar('\n'); + } + } + else { + printf(tfm_type == UNICODE ? "%4d (U+%04X) " + : "%4d (MSL %4d) ", + i, charcode); + if (char_table[i].symbol_set != NO_SYMBOL_SET) + printf("(%3s %3d)", + show_symset(char_table[i].symbol_set), char_table[i].code); + putchar('\n'); + } + } + putchar('\n'); +} + +static char * +show_symset(unsigned int symset) +{ + // A 64-bit unsigned int produces up to 20 decimal digits. + assert(sizeof(unsigned int) <= 8); + static char symset_str[22]; // 20 digits + symset char + \0 + sprintf(symset_str, "%u%c", symset / 32, (symset & 31) + 64); + return symset_str; +} + +static char * +hp_msl_to_ucode_name(int msl) +{ + // A 64-bit signed int produces up to 19 decimal digits plus a sign. + assert(sizeof(int) <= 8); + char codestr[21]; // 19 digits + possible sign + \0 + sprintf(codestr, "%d", msl); + const char *ustr = hp_msl_to_unicode_code(codestr); + if (ustr == NULL) + ustr = UNNAMED; + else { + char *nonum; + int ucode = int(strtol(ustr, &nonum, 16)); + // don't allow PUA code points as Unicode names + if (ucode >= 0xE000 && ucode <= 0xF8FF) + ustr = UNNAMED; + } + if (!equal(ustr, UNNAMED)) { + const char *uname_decomposed = decompose_unicode(ustr); + if (uname_decomposed) + // 1st char is the number of components + ustr = uname_decomposed + 1; + } + char *value = new char[strlen(ustr) + 1]; + sprintf(value, equal(ustr, UNNAMED) ? UNNAMED : "u%s", ustr); + return value; +} + +static char * +unicode_to_ucode_name(int ucode) +{ + // A 64-bit signed int produces up to 16 hexadecimal digits. + assert(sizeof(int) <= 8); + const char *ustr; + char codestr[17]; // 16 hex digits + \0 + + // don't allow PUA code points as Unicode names + if (ucode >= 0xE000 && ucode <= 0xF8FF) + ustr = UNNAMED; + else { + sprintf(codestr, "%04X", ucode); + ustr = codestr; + } + if (!equal(ustr, UNNAMED)) { + const char *uname_decomposed = decompose_unicode(ustr); + if (uname_decomposed) + // 1st char is the number of components + ustr = uname_decomposed + 1; + } + char *value = new char[strlen(ustr) + 1]; + sprintf(value, equal(ustr, UNNAMED) ? UNNAMED : "u%s", ustr); + return value; +} + +static int +is_uname(char *name) +{ + size_t i; + size_t len = strlen(name); + if (len % 5) + return 0; + + if (name[0] != 'u') + return 0; + for (i = 1; i < 4; i++) + if (!csxdigit(name[i])) + return 0; + for (i = 5; i < len; i++) + if (i % 5 ? !csxdigit(name[i]) : name[i] != '_') + return 0; + + return 1; +} + +static int +read_map(const char *file, const int tfm_type) +{ + errno = 0; + FILE *fp = fopen(file, "r"); + if (!fp) { + error("can't open '%1': %2", file, strerror(errno)); + return 0; + } + current_filename = file; + char buf[512]; + current_lineno = 0; + char *nonum; + while (fgets(buf, int(sizeof(buf)), fp)) { + current_lineno++; + char *ptr = buf; + while (csspace(*ptr)) + ptr++; + if (*ptr == '\0' || *ptr == '#') + continue; + ptr = strtok(ptr, " \n\t"); + if (!ptr) + continue; + + int msl_code = int(strtol(ptr, &nonum, 10)); + if (*nonum != '\0') { + if (csxdigit(*nonum)) + error("bad MSL map: got hex code (%1)", ptr); + else if (ptr == nonum) + error("bad MSL map: bad MSL code (%1)", ptr); + else + error("bad MSL map"); + fclose(fp); + return 0; + } + + ptr = strtok(NULL, " \n\t"); + if (!ptr) + continue; + int unicode = int(strtol(ptr, &nonum, 16)); + if (*nonum != '\0') { + if (ptr == nonum) + error("bad Unicode value (%1)", ptr); + else + error("bad Unicode map"); + fclose(fp); + return 0; + } + if (strlen(ptr) != 4) { + error("bad Unicode value (%1)", ptr); + return 0; + } + + int n = tfm_type == MSL ? msl_code : unicode; + if (tfm_type == UNICODE && n > 0xFFFF) { + // greatest value supported by TFM files + error("bad Unicode value (%1): greatest value is 0xFFFF", ptr); + fclose(fp); + return 0; + } + else if (n < 0) { + error("negative code value (%1)", ptr); + fclose(fp); + return 0; + } + + ptr = strtok(NULL, " \n\t"); + if (!ptr) { // groff name + error("missing name(s)"); + fclose(fp); + return 0; + } + // leave decomposed Unicode values alone + else if (is_uname(ptr) && !is_decomposed(ptr)) + ptr = unicode_to_ucode_name(strtol(ptr + 1, &nonum, 16)); + + if (size_t(n) >= charcode_name_table_size) { + size_t old_size = charcode_name_table_size; + name_list **old_table = charcode_name_table; + charcode_name_table_size = n + 256; + charcode_name_table = new name_list *[charcode_name_table_size]; + if (old_table) { + memcpy(charcode_name_table, old_table, old_size*sizeof(name_list *)); + delete[] old_table; + } + for (size_t i = old_size; i < charcode_name_table_size; i++) + charcode_name_table[i] = NULL; + } + + // a '#' that isn't the first groff name begins a comment + for (int names = 1; ptr; ptr = strtok(NULL, " \n\t")) { + if (names++ > 1 && *ptr == '#') + break; + charcode_name_table[n] = new name_list(ptr, charcode_name_table[n]); + } + } + fclose(fp); + return 1; +} + +static const char * +xbasename(const char *s) +{ + // DIR_SEPS[] are possible directory separator characters, see + // nonposix.h. We want the rightmost separator of all possible + // ones. Example: d:/foo\\bar. + const char *b = strrchr(s, DIR_SEPS[0]), *b1; + const char *sep = &DIR_SEPS[1]; + + while (*sep) + { + b1 = strrchr(s, *sep); + if (b1 && (!b || b1 > b)) + b = b1; + sep++; + } + return b ? b + 1 : s; +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/utils/hpftodit/hpuni.cpp b/src/utils/hpftodit/hpuni.cpp new file mode 100644 index 0000000..b3f933f --- /dev/null +++ b/src/utils/hpftodit/hpuni.cpp @@ -0,0 +1,697 @@ +// -*- C++ -*- +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + Written by Jeff Conrad (jeff_conrad@msn.com) + +This file 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 . */ + +#include "lib.h" +#include "stringclass.h" +#include "ptable.h" + +#include "unicode.h" + +struct hp_msl_to_unicode { + char *value; +}; + +declare_ptable(hp_msl_to_unicode) +implement_ptable(hp_msl_to_unicode) + +PTABLE(hp_msl_to_unicode) hp_msl_to_unicode_table; + +struct S { + const char *key; + const char *value; +} hp_msl_to_unicode_list[] = { + { "1", "0021", }, // Exclamation Mark + { "2", "0022", }, // Neutral Double Quote + { "3", "0023", }, // Number Sign + { "4", "0024", }, // Dollar Sign + { "5", "0025", }, // Per Cent Sign + { "6", "0026", }, // Ampersand + { "8", "2019", }, // Single Close Quote (9) + { "9", "0028", }, // Left Parenthesis + { "10", "0029", }, // Right Parenthesis + { "11", "002A", }, // Asterisk + { "12", "002B", }, // Plus Sign + { "13", "002C", }, // Comma, or Decimal Separator + { "14", "002D", }, // Hyphen + { "15", "002E", }, // Period, or Full Stop + { "16", "002F", }, // Solidus, or Slash + { "17", "0030", }, // Numeral Zero + { "18", "0031", }, // Numeral One + { "19", "0032", }, // Numeral Two + { "20", "0033", }, // Numeral Three + { "21", "0034", }, // Numeral Four + { "22", "0035", }, // Numeral Five + { "23", "0036", }, // Numeral Six + { "24", "0037", }, // Numeral Seven + { "25", "0038", }, // Numeral Eight + { "26", "0039", }, // Numeral Nine + { "27", "003A", }, // Colon + { "28", "003B", }, // Semicolon + { "29", "003C", }, // Less Than Sign + { "30", "003D", }, // Equals Sign + { "31", "003E", }, // Greater Than Sign + { "32", "003F", }, // Question Mark + { "33", "0040", }, // Commercial At + { "34", "0041", }, // Uppercase A + { "35", "0042", }, // Uppercase B + { "36", "0043", }, // Uppercase C + { "37", "0044", }, // Uppercase D + { "38", "0045", }, // Uppercase E + { "39", "0046", }, // Uppercase F + { "40", "0047", }, // Uppercase G + { "41", "0048", }, // Uppercase H + { "42", "0049", }, // Uppercase I + { "43", "004A", }, // Uppercase J + { "44", "004B", }, // Uppercase K + { "45", "004C", }, // Uppercase L + { "46", "004D", }, // Uppercase M + { "47", "004E", }, // Uppercase N + { "48", "004F", }, // Uppercase O + { "49", "0050", }, // Uppercase P + { "50", "0051", }, // Uppercase Q + { "51", "0052", }, // Uppercase R + { "52", "0053", }, // Uppercase S + { "53", "0054", }, // Uppercase T + { "54", "0055", }, // Uppercase U + { "55", "0056", }, // Uppercase V + { "56", "0057", }, // Uppercase W + { "57", "0058", }, // Uppercase X + { "58", "0059", }, // Uppercase Y + { "59", "005A", }, // Uppercase Z + { "60", "005B", }, // Left Bracket + { "61", "005C", }, // Reverse Solidus, or Backslash + { "62", "005D", }, // Right Bracket + { "63", "005E", }, // Circumflex, Exponent, or Pointer + { "64", "005F", }, // Underline or Underscore Character + { "66", "2018", }, // Single Open Quote (6) + { "67", "0061", }, // Lowercase A + { "68", "0062", }, // Lowercase B + { "69", "0063", }, // Lowercase C + { "70", "0064", }, // Lowercase D + { "71", "0065", }, // Lowercase E + { "72", "0066", }, // Lowercase F + { "73", "0067", }, // Lowercase G + { "74", "0068", }, // Lowercase H + { "75", "0069", }, // Lowercase I + { "76", "006A", }, // Lowercase J + { "77", "006B", }, // Lowercase K + { "78", "006C", }, // Lowercase L + { "79", "006D", }, // Lowercase M + { "80", "006E", }, // Lowercase N + { "81", "006F", }, // Lowercase O + { "82", "0070", }, // Lowercase P + { "83", "0071", }, // Lowercase Q + { "84", "0072", }, // Lowercase R + { "85", "0073", }, // Lowercase S + { "86", "0074", }, // Lowercase T + { "87", "0075", }, // Lowercase U + { "88", "0076", }, // Lowercase V + { "89", "0077", }, // Lowercase W + { "90", "0078", }, // Lowercase X + { "91", "0079", }, // Lowercase Y + { "92", "007A", }, // Lowercase Z + { "93", "007B", }, // Left Brace + { "94", "007C", }, // Long Vertical Mark + { "95", "007D", }, // Right Brace + { "96", "007E", }, // One Wavy Line Approximate + { "97", "2592", }, // Medium Shading Character + { "99", "00C0", }, // Uppercase A Grave + { "100", "00C2", }, // Uppercase A Circumflex + { "101", "00C8", }, // Uppercase E Grave + { "102", "00CA", }, // Uppercase E Circumflex + { "103", "00CB", }, // Uppercase E Dieresis + { "104", "00CE", }, // Uppercase I Circumflex + { "105", "00CF", }, // Uppercase I Dieresis + { "106", "00B4", }, // Lowercase Acute Accent (Spacing) + { "107", "0060", }, // Lowercase Grave Accent (Spacing) + { "108", "02C6", }, // Lowercase Circumflex Accent (Spacing) + { "109", "00A8", }, // Lowercase Dieresis Accent (Spacing) + { "110", "02DC", }, // Lowercase Tilde Accent (Spacing) + { "111", "00D9", }, // Uppercase U Grave + { "112", "00DB", }, // Uppercase U Circumflex + { "113", "00AF", }, // Overline, or Overscore Character + { "114", "00DD", }, // Uppercase Y Acute + { "115", "00FD", }, // Lowercase Y Acute + { "116", "00B0", }, // Degree Sign + { "117", "00C7", }, // Uppercase C Cedilla + { "118", "00E7", }, // Lowercase C Cedilla + { "119", "00D1", }, // Uppercase N Tilde + { "120", "00F1", }, // Lowercase N Tilde + { "121", "00A1", }, // Inverted Exclamation + { "122", "00BF", }, // Inverted Question Mark + { "123", "00A4", }, // Currency Symbol + { "124", "00A3", }, // Pound Sterling Sign + { "125", "00A5", }, // Yen Sign + { "126", "00A7", }, // Section Mark + { "127", "0192", }, // Florin Sign + { "128", "00A2", }, // Cent Sign + { "129", "00E2", }, // Lowercase A Circumflex + { "130", "00EA", }, // Lowercase E Circumflex + { "131", "00F4", }, // Lowercase O Circumflex + { "132", "00FB", }, // Lowercase U Circumflex + { "133", "00E1", }, // Lowercase A Acute + { "134", "00E9", }, // Lowercase E Acute + { "135", "00F3", }, // Lowercase O Acute + { "136", "00FA", }, // Lowercase U Acute + { "137", "00E0", }, // Lowercase A Grave + { "138", "00E8", }, // Lowercase E Grave + { "139", "00F2", }, // Lowercase O Grave + { "140", "00F9", }, // Lowercase U Grave + { "141", "00E4", }, // Lowercase A Dieresis + { "142", "00EB", }, // Lowercase E Dieresis + { "143", "00F6", }, // Lowercase O Dieresis + { "144", "00FC", }, // Lowercase U Dieresis + { "145", "00C5", }, // Uppercase A Ring + { "146", "00EE", }, // Lowercase I Circumflex + { "147", "00D8", }, // Uppercase O Oblique + { "148", "00C6", }, // Uppercase AE Diphthong + { "149", "00E5", }, // Lowercase A Ring + { "150", "00ED", }, // Lowercase I Acute + { "151", "00F8", }, // Lowercase O Oblique + { "152", "00E6", }, // Lowercase AE Diphthong + { "153", "00C4", }, // Uppercase A Dieresis + { "154", "00EC", }, // Lowercase I Grave + { "155", "00D6", }, // Uppercase O Dieresis + { "156", "00DC", }, // Uppercase U Dieresis + { "157", "00C9", }, // Uppercase E Acute + { "158", "00EF", }, // Lowercase I Dieresis + { "159", "00DF", }, // Lowercase Es-zet Ligature + { "160", "00D4", }, // Uppercase O Circumflex + { "161", "00C1", }, // Uppercase A Acute + { "162", "00C3", }, // Uppercase A Tilde + { "163", "00E3", }, // Lowercase A Tilde + { "164", "00D0", }, // Uppercase Eth +//{ "164", "0110", }, // Uppercase D-Stroke + { "165", "00F0", }, // Lowercase Eth + { "166", "00CD", }, // Uppercase I Acute + { "167", "00CC", }, // Uppercase I Grave + { "168", "00D3", }, // Uppercase O Acute + { "169", "00D2", }, // Uppercase O Grave + { "170", "00D5", }, // Uppercase O Tilde + { "171", "00F5", }, // Lowercase O Tilde + { "172", "0160", }, // Uppercase S Hacek + { "173", "0161", }, // Lowercase S Hacek + { "174", "00DA", }, // Uppercase U Acute + { "175", "0178", }, // Uppercase Y Dieresis + { "176", "00FF", }, // Lowercase Y Dieresis + { "177", "00DE", }, // Uppercase Thorn + { "178", "00FE", }, // Lowercase Thorn + { "180", "00B5", }, // Lowercase Greek Mu, or Micro + { "181", "00B6", }, // Pilcrow, or Paragraph Sign + { "182", "00BE", }, // Vulgar Fraction 3/4 + { "183", "2212", }, // Minus Sign + { "184", "00BC", }, // Vulgar Fraction 1/4 + { "185", "00BD", }, // Vulgar Fraction 1/2 + { "186", "00AA", }, // Female Ordinal + { "187", "00BA", }, // Male Ordinal + { "188", "00AB", }, // Left Pointing Double Angle Quote + { "189", "25A0", }, // Medium Solid Square Box + { "190", "00BB", }, // Right Pointing Double Angle Quote + { "191", "00B1", }, // Plus Over Minus Sign + { "192", "00A6", }, // Broken Vertical Mark + { "193", "00A9", }, // Copyright Sign + { "194", "00AC", }, // Not Sign + { "195", "00AD", }, // Soft Hyphen + { "196", "00AE", }, // Registered Sign + { "197", "00B2", }, // Superior Numeral 2 + { "198", "00B3", }, // Superior Numeral 3 + { "199", "00B8", }, // Lowercase Cedilla (Spacing) + { "200", "00B9", }, // Superior Numeral 1 + { "201", "00D7", }, // Multiply Sign + { "202", "00F7", }, // Divide Sign + { "203", "263A", }, // Open Smiling Face + { "204", "263B", }, // Solid Smiling Face + { "205", "2665", }, // Solid Heart, Card Suit + { "206", "2666", }, // Solid Diamond, Card Suit + { "207", "2663", }, // Solid Club, Card Suit + { "208", "2660", }, // Solid Spade, Card Suit + { "209", "25CF", }, // Medium Solid Round Bullet + { "210", "25D8", }, // Large Solid square with White Dot + { "211", "EFFD", }, // Large Open Round Bullet + { "212", "25D9", }, // Large Solid square with White Circle + { "213", "2642", }, // Male Symbol + { "214", "2640", }, // Female Symbol + { "215", "266A", }, // Musical Note + { "216", "266B", }, // Pair Of Musical Notes + { "217", "263C", }, // Compass, or Eight Pointed Sun + { "218", "25BA", }, // Right Solid Arrowhead + { "219", "25C4", }, // Left Solid Arrowhead + { "220", "2195", }, // Up/Down Arrow + { "221", "203C", }, // Double Exclamation Mark + { "222", "25AC", }, // Thick Horizontal Mark + { "223", "21A8", }, // Up/Down Arrow Baseline + { "224", "2191", }, // Up Arrow + { "225", "2193", }, // Down Arrow + { "226", "2192", }, // Right Arrow + { "227", "2190", }, // Left Arrow + { "229", "2194", }, // Left/Right Arrow + { "230", "25B2", }, // Up Solid Arrowhead + { "231", "25BC", }, // Down Solid Arrowhead + { "232", "20A7", }, // Pesetas Sign + { "233", "2310", }, // Reversed Not Sign + { "234", "2591", }, // Light Shading Character + { "235", "2593", }, // Dark Shading Character + { "236", "2502", }, // Box Draw Line, Vert. 1 + { "237", "2524", }, // Box Draw Right Tee, Vert. 1 Horiz. 1 + { "238", "2561", }, // Box Draw Right Tee, Vert. 1 Horiz. 2 + { "239", "2562", }, // Box Draw Right Tee, Vert. 2 Horiz. 1 + { "240", "2556", }, // Box Draw Upper Right Corner, Vert. 2 Horiz. 1 + { "241", "2555", }, // Box Draw Upper Right Corner, Vert. 1 Horiz. 2 + { "242", "2563", }, // Box Draw Right Tee, Vert. 2 Horiz. 2 + { "243", "2551", }, // Box Draw Lines, Vert. 2 + { "244", "2557", }, // Box Draw Upper Right Corner, Vert. 2 Horiz. 2 + { "245", "255D", }, // Box Draw Lower Right Corner, Vert. 2 Horiz. 2 + { "246", "255C", }, // Box Draw Lower Right Corner, Vert. 2 Horiz. 1 + { "247", "255B", }, // Box Draw Lower Right Corner, Vert. 1 Horiz. 2 + { "248", "2510", }, // Box Draw Upper Right Corner, Vert. 1, Horiz. 1 + { "249", "2514", }, // Box Draw Lower Left Corner, Vert. 1, Horiz. 1 + { "250", "2534", }, // Box Draw Bottom Tee, Vert. 1 Horiz. 1 + { "251", "252C", }, // Box Draw Top Tee, Vert. 1 Horiz. 1 + { "252", "251C", }, // Box Draw Left Tee, Vert. 1 Horiz. 1 + { "253", "2500", }, // Box Draw Line, Horiz. 1 + { "254", "253C", }, // Box Draw Cross, Vert. 1 Horiz. 1 + { "255", "255E", }, // Box Draw Left Tee, Vert. 1 Horiz. 2 + { "256", "255F", }, // Box Draw Left Tee, Vert. 2 Horz. 1 + { "257", "255A", }, // Box Draw Lower Left Corner, Vert. 2 Horiz. 2 + { "258", "2554", }, // Box Draw Upper Left Corner, Vert. 2 Horiz. 2 + { "259", "2569", }, // Box Draw Bottom Tee, Vert. 2 Horiz. 2 + { "260", "2566", }, // Box Draw Top Tee, Vert. 2 Horiz. 2 + { "261", "2560", }, // Box Draw Left Tee, Vert. 2 Horiz. 2 + { "262", "2550", }, // Box Draw Lines, Horiz. 2 + { "263", "256C", }, // Box Draw Cross Open Center, Vert. 2 Horiz. 2 + { "264", "2567", }, // Box Draw Bottom Tee, Vert. 1 Horiz. 2 + { "265", "2568", }, // Box Draw Bottom Tee, Vert. 2 Horiz. 1 + { "266", "2564", }, // Box Draw Top Tee, Vert. 1 Horiz. 2 + { "267", "2565", }, // Box Draw Top Tee, Vert. 2 Horiz. 1 + { "268", "2559", }, // Box Draw Lower Left Corner, Vert. 2 Horiz. 1 + { "269", "2558", }, // Box Draw Lower Left Corner, Vert. 1 Horiz. 2 + { "270", "2552", }, // Box Draw Upper Left Corner, Vert. 1 Horiz. 2 + { "271", "2553", }, // Box Draw Upper Left Corner, Vert. 2 Horiz. 1 + { "272", "256B", }, // Box Draw Cross, Vert. 2 Horiz. 1 + { "273", "256A", }, // Box Draw Cross, Vert. 1 Horiz. 2 + { "274", "2518", }, // Box Draw Lower Right Corner, Vert. 1 Horiz. 1 + { "275", "250C", }, // Box Draw Upper Left Corner, Vert. 1, Horiz. 1 + { "276", "2588", }, // Solid Full High/Wide + { "277", "2584", }, // Bottom Half Solid Rectangle + { "278", "258C", }, // Left Half Solid Rectangle + { "279", "2590", }, // Right Half Solid Rectangle + { "280", "2580", }, // Top Half Solid Rectangle + { "290", "2126", }, // Uppercase Greek Omega, or Ohms + { "292", "221E", }, // Infinity Symbol + { "295", "2229", }, // Set Intersection Symbol + { "296", "2261", }, // Exactly Equals Sign + { "297", "2265", }, // Greater Than or Equal Sign + { "298", "2264", }, // Less Than or Equal Sign + { "299", "2320", }, // Top Integral + { "300", "2321", }, // Bottom Integral + { "301", "2248", }, // Two Wavy Line Approximate Sign +//{ "302", "00B7", }, // Middle Dot, or Centered Period (see 2219) +//{ "302", "2219", }, // Centered Period, Middle Dot + { "302", "2219", }, // Math Dot, Centered Period + { "303", "221A", }, // Radical Symbol, Standalone Diagonal + { "305", "25AA", }, // Small Solid Square Box + { "306", "013F", }, // Uppercase L-Dot + { "307", "0140", }, // Lowercase L-Dot + { "308", "2113", }, // Litre Symbol + { "309", "0149", }, // Lowercase Apostrophe-N + { "310", "2032", }, // Prime, Minutes, or Feet Symbol + { "311", "2033", }, // Double Prime, Seconds, or Inches Symbol + { "312", "2020", }, // Dagger Symbol + { "313", "2122", }, // Trademark Sign + { "314", "2017", }, // Double Underline Character + { "315", "02C7", }, // Lowercase Hacek Accent (Spacing) + { "316", "02DA", }, // Lowercase Ring Accent (Spacing) + { "317", "EFF9", }, // Uppercase Acute Accent (Spacing) + { "318", "EFF8", }, // Uppercase Grave Accent (Spacing) + { "319", "EFF7", }, // Uppercase Circumflex Accent (Spacing) + { "320", "EFF6", }, // Uppercase Dieresis Accent (Spacing) + { "321", "EFF5", }, // Uppercase Tilde Accent (Spacing) + { "322", "EFF4", }, // Uppercase Hacek Accent (Spacing) + { "323", "EFF3", }, // Uppercase Ring Accent (Spacing) + { "324", "2215", }, // Vulgar Fraction Bar + { "325", "2014", }, // Em Dash + { "326", "2013", }, // En Dash + { "327", "2021", }, // Double Dagger Symbol + { "328", "0131", }, // Lowercase Undotted I + { "329", "0027", }, // Neutral Single Quote + { "330", "EFF2", }, // Uppercase Cedilla (Spacing) + { "331", "2022", }, // Small Solid Round Bullet + { "332", "207F", }, // Superior Lowercase N + { "333", "2302", }, // Home Plate + { "335", "0138", }, // Lowercase Kra + { "338", "0166", }, // Uppercase T-Stroke + { "339", "0167", }, // Lowercase T-Stroke + { "340", "014A", }, // Uppercase Eng + { "341", "014B", }, // Lowercase Eng + { "342", "0111", }, // Lowercase D-Stroke + { "400", "0102", }, // Uppercase A Breve + { "401", "0103", }, // Lowercase A Breve + { "402", "0100", }, // Uppercase A Macron + { "403", "0101", }, // Lowercase A Macron + { "404", "0104", }, // Uppercase A Ogonek + { "405", "0105", }, // Lowercase A Ogonek + { "406", "0106", }, // Uppercase C Acute + { "407", "0107", }, // Lowercase C Acute + { "410", "010C", }, // Uppercase C Hacek + { "411", "010D", }, // Lowercase C Hacek + { "414", "010E", }, // Uppercase D Hacek + { "415", "010F", }, // Lowercase D Hacek + { "416", "011A", }, // Uppercase E Hacek + { "417", "011B", }, // Lowercase E Hacek + { "418", "0116", }, // Uppercase E Overdot + { "419", "0117", }, // Lowercase E Overdot + { "420", "0112", }, // Uppercase E Macron + { "421", "0113", }, // Lowercase E Macron + { "422", "0118", }, // Uppercase E Ogonek + { "423", "0119", }, // Lowercase E Ogonek + { "428", "0122", }, // Uppercase G Cedilla + { "429", "0123", }, // Lowercase G Cedilla + { "432", "012E", }, // Uppercase I Ogonek + { "433", "012F", }, // Lowercase I Ogonek + { "434", "012A", }, // Uppercase I Macron + { "435", "012B", }, // Lowercase I Macron + { "438", "0136", }, // Uppercase K Cedilla + { "439", "0137", }, // Lowercase K Cedilla + { "440", "0139", }, // Uppercase L Acute + { "441", "013A", }, // Lowercase L Acute + { "442", "013D", }, // Uppercase L Hacek + { "443", "013E", }, // Lowercase L Hacek + { "444", "013B", }, // Uppercase L Cedilla + { "445", "013C", }, // Lowercase L Cedilla + { "446", "0143", }, // Uppercase N Acute + { "447", "0144", }, // Lowercase N Acute + { "448", "0147", }, // Uppercase N Hacek + { "449", "0148", }, // Lowercase N Hacek + { "450", "0145", }, // Uppercase N Cedilla + { "451", "0146", }, // Lowercase N Cedilla + { "452", "0150", }, // Uppercase O Double Acute + { "453", "0151", }, // Lowercase O Double Acute + { "454", "014C", }, // Uppercase O Macron + { "455", "014D", }, // Lowercase O Macron + { "456", "0154", }, // Uppercase R Acute + { "457", "0155", }, // Lowercase R Acute + { "458", "0158", }, // Uppercase R Hacek + { "459", "0159", }, // Lowercase R Hacek + { "460", "0156", }, // Uppercase R Cedilla + { "461", "0157", }, // Lowercase R Cedilla + { "462", "015A", }, // Uppercase S Acute + { "463", "015B", }, // Lowercase S Acute + { "466", "0164", }, // Uppercase T Hacek + { "467", "0165", }, // Lowercase T Hacek + { "468", "0162", }, // Uppercase T Cedilla + { "469", "0163", }, // Lowercase T Cedilla + { "470", "0168", }, // Uppercase U Tilde + { "471", "0169", }, // Lowercase U Tilde + { "474", "0170", }, // Uppercase U Double Acute + { "475", "0171", }, // Lowercase U Double Acute + { "476", "016E", }, // Uppercase U Ring + { "477", "016F", }, // Lowercase U Ring + { "478", "016A", }, // Uppercase U Macron + { "479", "016B", }, // Lowercase U Macron + { "480", "0172", }, // Uppercase U Ogonek + { "481", "0173", }, // Lowercase U Ogonek + { "482", "0179", }, // Uppercase Z Acute + { "483", "017A", }, // Lowercase Z Acute + { "484", "017B", }, // Uppercase Z Overdot + { "485", "017C", }, // Lowercase Z Overdot + { "486", "0128", }, // Uppercase I Tilde + { "487", "0129", }, // Lowercase I Tilde + { "500", "EFBF", }, // Radical, Diagonal, Composite + { "501", "221D", }, // Proportional To Symbol + { "502", "212F", }, // Napierian (italic e) + { "503", "03F5", }, // Alternate Lowercase Greek Epsilon +//{ "503", "EFEC", }, // Alternate Lowercase Greek Epsilon + { "504", "2234", }, // Therefore Symbol + { "505", "0393", }, // Uppercase Greek Gamma + { "506", "2206", }, // Increment Symbol (Delta) + { "507", "0398", }, // Uppercase Greek Theta + { "508", "039B", }, // Uppercase Greek Lambda + { "509", "039E", }, // Uppercase Greek Xi + { "510", "03A0", }, // Uppercase Greek Pi + { "511", "03A3", }, // Uppercase Greek Sigma + { "512", "03A5", }, // Uppercase Greek Upsilon + { "513", "03A6", }, // Uppercase Greek Phi + { "514", "03A8", }, // Uppercase Greek Psi + { "515", "03A9", }, // Uppercase Greek Omega + { "516", "2207", }, // Nabla Symbol (inverted Delta) + { "517", "2202", }, // Partial Differential Delta Symbol + { "518", "03C2", }, // Lowercase Sigma, Terminal + { "519", "2260", }, // Not Equal To Symbol + { "520", "EFEB", }, // Underline, Composite + { "521", "2235", }, // Because Symbol + { "522", "03B1", }, // Lowercase Greek Alpha + { "523", "03B2", }, // Lowercase Greek Beta + { "524", "03B3", }, // Lowercase Greek Gamma + { "525", "03B4", }, // Lowercase Greek Delta + { "526", "03B5", }, // Lowercase Greek Epsilon + { "527", "03B6", }, // Lowercase Greek Zeta + { "528", "03B7", }, // Lowercase Greek Eta + { "529", "03B8", }, // Lowercase Greek Theta + { "530", "03B9", }, // Lowercase Greek Iota + { "531", "03BA", }, // Lowercase Greek Kappa + { "532", "03BB", }, // Lowercase Greek Lambda + { "533", "03BC", }, // Lowercase Greek Mu + { "534", "03BD", }, // Lowercase Greek Nu + { "535", "03BE", }, // Lowercase Greek Xi + { "536", "03BF", }, // Lowercase Greek Omicron + { "537", "03C0", }, // Lowercase Greek Pi + { "538", "03C1", }, // Lowercase Greek Rho + { "539", "03C3", }, // Lowercase Greek Sigma + { "540", "03C4", }, // Lowercase Greek Tau + { "541", "03C5", }, // Lowercase Greek Upsilon + { "542", "03C6", }, // Lowercase Greek Phi + { "543", "03C7", }, // Lowercase Greek Chi + { "544", "03C8", }, // Lowercase Greek Psi + { "545", "03C9", }, // Lowercase Greek Omega + { "546", "03D1", }, // Lowercase Greek Theta, Open + { "547", "03D5", }, // Lowercase Greek Phi, Open + { "548", "03D6", }, // Lowercase Pi, Alternate + { "549", "2243", }, // Wavy Over Straight Approximate Symbol + { "550", "2262", }, // Not Exactly Equal To Symbol + { "551", "21D1", }, // Up Arrow Double Stroke + { "552", "21D2", }, // Right Arrow Double Stroke + { "553", "21D3", }, // Down Arrow Double Stroke + { "554", "21D0", }, // Left Arrow Double Stroke + { "555", "21D5", }, // Up/Down Arrow Double Stroke + { "556", "21D4", }, // Left/Right Arrow Double Stroke + { "557", "21C4", }, // Right Over Left Arrow + { "558", "21C6", }, // Left Over Right Arrow + { "559", "EFE9", }, // Vector Symbol + { "560", "0305", }, // Overline, Composite + { "561", "2200", }, // For All Symbol, or Universal (inverted A) + { "562", "2203", }, // There Exists Symbol, or Existential (inverted E) + { "563", "22A4", }, // Top Symbol + { "564", "22A5", }, // Bottom Symbol + { "565", "222A", }, // Set Union Symbol + { "566", "2208", }, // Element-Of Symbol + { "567", "220B", }, // Contains Symbol + { "568", "2209", }, // Not-Element-Of Symbol + { "569", "2282", }, // Proper Subset Symbol + { "570", "2283", }, // Proper Superset Symbol + { "571", "2284", }, // Not Proper Subset Symbol + { "572", "2285", }, // Not Proper Superset Symbol + { "573", "2286", }, // Subset Symbol + { "574", "2287", }, // Superset Symbol + { "575", "2295", }, // Plus In Circle Symbol + { "576", "2299", }, // Dot In Circle Symbol + { "577", "2297", }, // Times In Circle Symbol + { "578", "2296", }, // Minus In Circle Symbol + { "579", "2298", }, // Slash In Circle Symbol + { "580", "2227", }, // Logical And Symbol + { "581", "2228", }, // Logical Or Symbol + { "582", "22BB", }, // Exclusive Or Symbol + { "583", "2218", }, // Functional Composition Symbol + { "584", "20DD", }, // Large Open Circle + { "585", "22A3", }, // Assertion Symbol + { "586", "22A2", }, // Backwards Assertion Symbol + { "587", "222B", }, // Integral Symbol + { "588", "222E", }, // Curvilinear Integral Symbol + { "589", "2220", }, // Angle Symbol + { "590", "2205", }, // Empty Set Symbol + { "591", "2135", }, // Hebrew Aleph + { "592", "2136", }, // Hebrew Beth + { "593", "2137", }, // Hebrew Gimmel + { "594", "212D", }, // Fraktur Uppercase C + { "595", "2111", }, // Fraktur Uppercase I + { "596", "211C", }, // Fraktur Uppercase R + { "597", "2128", }, // Fraktur Uppercase Z + { "598", "23A1", }, // Top Segment Left Bracket (Left Square Bracket Upper Corner) + { "599", "23A3", }, // Bottom Segment Left Bracket (Left Square Bracket Lower Corner) + { "600", "239B", }, // Top Segment Left Brace (Left Parenthesis Upper Hook) +//{ "600", "23A7", }, // Top Segment Left Brace (Right Curly Bracket Upper Hook) + { "601", "23A8", }, // Middle Segment Left Brace (Right Curly Bracket Middle Piece) + { "602", "239D", }, // Bottom Segment LeftBrace (Left Parenthesis Lower Hook) +//{ "602", "23A9", }, // Bottom Segment Left Brace (Right Curly Bracket Lower Hook) + { "603", "EFD4", }, // Middle Segment Curvilinear Integral + { "604", "EFD3", }, // Top Left Segment Summation + { "605", "2225", }, // Double Vertical Line, Composite + { "606", "EFD2", }, // Bottom Left Segment Summation + { "607", "EFD1", }, // Bottom Diagonal Summation + { "608", "23A4", }, // Top Segment Right Bracket (Right Square Bracket Upper Corner) + { "609", "23A6", }, // Bottom Segment Right Bracket (Right Square Bracket Lower Corner) + { "610", "239E", }, // Top Segment Right Brace (Right Parenthesis Upper Hook) +//{ "610", "23AB", }, // Top Segment Right Brace (Right Curly Bracket Upper Hook) + { "611", "23AC", }, // Middle Segment Right Brace (Right Curly Bracket Middle Piece) + { "612", "23A0", }, // Bottom Segment Right ( Right Parenthesis Lower Hook) +//{ "612", "23AD", }, // Bottom Segment Right Brace (Right Curly Bracket Lower Hook) + { "613", "239C", }, // Thick Vertical Line, Composite (Left Parenthesis Extension) +//{ "613", "239F", }, // Thick Vertical Line, Composite (Right Parenthesis Extension) +//{ "613", "23AA", }, // Thick Vertical Line, Composite (Curly Bracket Extension) +//{ "613", "23AE", }, // Thick Vertical Line, Composite (Integral Extension) + { "614", "2223", }, // Thin Vertical Line, Composite + { "615", "EFDC", }, // Bottom Segment of Vertical Radical + { "616", "EFD0", }, // Top Right Segment Summation + { "617", "EFCF", }, // Middle Segment Summation + { "618", "EFCE", }, // Bottom Right Segment Summation + { "619", "EFCD", }, // Top Diagonal Summation + { "620", "2213", }, // Minus Over Plus Sign + { "621", "2329", }, // Left Angle Bracket + { "622", "232A", }, // Right Angle Bracket + { "623", "EFFF", }, // Mask Symbol + { "624", "2245", }, // Wavy Over Two Straight Approximate Symbol + { "625", "2197", }, // 45 Degree Arrow + { "626", "2198", }, // -45 Degree Arrow + { "627", "2199", }, // -135 Degree Arrow + { "628", "2196", }, // 135 Degree Arrow + { "629", "25B5", }, // Up Open Triangle + { "630", "25B9", }, // Right Open Triangle + { "631", "25BF", }, // Down Open Triangle + { "632", "25C3", }, // Left Open Triangle + { "633", "226A", }, // Much Less Than Sign + { "634", "226B", }, // Much Greater Than Sign + { "635", "2237", }, // Proportional To Symbol (4 dots) + { "636", "225C", }, // Defined As Symbol + { "637", "03DD", }, // Lowercase Greek Digamma + { "638", "210F", }, // Planck's Constant divided by 2 pi + { "639", "2112", }, // Laplace Transform Symbol + { "640", "EFFE", }, // Power Set + { "641", "2118", }, // Weierstrassian Symbol + { "642", "2211", }, // Summation Symbol (large Sigma) + { "643", "301A", }, // Left Double Bracket + { "644", "EFC9", }, // Middle Segment Double Bracket + { "645", "301B", }, // Right Double Bracket + { "646", "256D", }, // Box Draw Left Top Round Corner + { "647", "2570", }, // Box Draw Left Bottom Round Corner + { "648", "EFC8", }, // Extender Large Union/Product + { "649", "EFC7", }, // Bottom Segment Large Union + { "650", "EFC6", }, // Top Segment Large Intersection + { "651", "EFC5", }, // Top Segment Left Double Bracket + { "652", "EFC4", }, // Bottom Segment Left Double Bracket + { "653", "EFFC", }, // Large Open Square Box + { "654", "25C7", }, // Open Diamond + { "655", "256E", }, // Box Draw Right Top Round Corner + { "656", "256F", }, // Box Draw Right Bottom Round Corner + { "657", "EFC3", }, // Bottom Segment Large Bottom Product + { "658", "EFC2", }, // Top Segment Large Top Product + { "659", "EFC1", }, // Top Segment Right Double Bracket + { "660", "EFC0", }, // Bottom Segment Right Double Bracket + { "661", "EFFB", }, // Large Solid Square Box + { "662", "25C6", }, // Solid Diamond + { "663", "220D", }, // Such That Symbol (rotated lc epsilon) + { "664", "2217", }, // Math Asterisk + { "665", "23AF", }, // Horizontal Arrow Extender (Horizontal Line Extension) + { "666", "EFCB", }, // Double Horizontal Arrow Extender + { "667", "EFCC", }, // Inverted Complement of 0xEFCF or MSL 617 + { "668", "221F", }, // Right Angle Symbol + { "669", "220F", }, // Product Symbol (large Pi) + { "684", "25CA", }, // Lozenge, Diamond + { "1000", "2070", }, // Superior Numeral 0 + { "1001", "2074", }, // Superior Numeral 4 + { "1002", "2075", }, // Superior Numeral 5 + { "1003", "2076", }, // Superior Numeral 6 + { "1004", "2077", }, // Superior Numeral 7 + { "1005", "2078", }, // Superior Numeral 8 + { "1006", "2079", }, // Superior Numeral 9 + { "1017", "201C", }, // Double Open Quote (6) + { "1018", "201D", }, // Double Close Quote (9) + { "1019", "201E", }, // Double Baseline Quote (9) + { "1020", "2003", }, // Em Space + { "1021", "2002", }, // En Space + { "1023", "2009", }, // Thin Space + { "1028", "2026", }, // Ellipsis + { "1030", "EFF1", }, // Uppercase Ogonek (Spacing) + { "1031", "017E", }, // Lowercase Z Hacek + { "1034", "2120", }, // Service Mark + { "1036", "211E", }, // Prescription Sign +//{ "1040", "F001", }, // Lowercase FI Ligature + { "1040", "FB01", }, // Lowercase FI Ligature +//{ "1041", "F002", }, // Lowercase FL Ligature + { "1041", "FB02", }, // Lowercase FL Ligature + { "1042", "FB00", }, // Lowercase FF Ligature + { "1043", "FB03", }, // Lowercase FFI Ligature + { "1044", "FB04", }, // Lowercase FFL Ligature + { "1045", "EFF0", }, // Uppercase Double Acute Accent (Spacing) + { "1047", "0133", }, // Lowercase IJ Ligature + { "1060", "2105", }, // Care Of Symbol + { "1061", "011E", }, // Uppercase G Breve + { "1062", "011F", }, // Lowercase G Breve + { "1063", "015E", }, // Uppercase S Cedilla + { "1064", "015F", }, // Lowercase S Cedilla + { "1065", "0130", }, // Uppercase I Overdot + { "1067", "201A", }, // Single Baseline Quote (9) + { "1068", "2030", }, // Per Mill Sign + { "1069", "20AC", }, // Euro + { "1084", "02C9", }, // Lowercase Macron Accent (Spacing) + { "1086", "02D8", }, // Lowercase Breve Accent (Spacing) + { "1088", "02D9", }, // Lowercase Overdot Accent (Spacing) + { "1090", "0153", }, // Lowercase OE Ligature + { "1091", "0152", }, // Uppercase OE Ligature + { "1092", "2039", }, // Left Pointing Single Angle Quote + { "1093", "203A", }, // Right Pointing Single Angle Quote + { "1094", "25A1", }, // Medium Open Square Box + { "1095", "0141", }, // Uppercase L-Stroke + { "1096", "0142", }, // Lowercase L-Stroke + { "1097", "02DD", }, // Lowercase Double Acute Accent (Spacing) + { "1098", "02DB", }, // Lowercase Ogonek (Spacing) + { "1099", "21B5", }, // Carriage Return Symbol + { "1100", "EFDB", }, // Full Size Serif Registered + { "1101", "EFDA", }, // Full Size Serif Copyright + { "1102", "EFD9", }, // Full Size Serif Trademark + { "1103", "EFD8", }, // Full Size Sans Registered + { "1104", "EFD7", }, // Full Size Sans Copyright + { "1105", "EFD6", }, // Full Size Sans Trademark + { "1106", "017D", }, // Uppercase Z Hacek + { "1107", "0132", }, // Uppercase IJ Ligature + { "1108", "25AB", }, // Small Open Square Box + { "1109", "25E6", }, // Small Open Round Bullet + { "1110", "25CB", }, // Medium Open Round Bullet + { "1111", "EFFA", }, // Large Solid Round Bullet + { "3812", "F000", }, // Ornament, Apple +}; + +// global constructor +static struct hp_msl_to_unicode_init { + hp_msl_to_unicode_init(); +} _hp_msl_to_unicode_init; + +hp_msl_to_unicode_init::hp_msl_to_unicode_init() { + for (unsigned int i = 0; + i < sizeof(hp_msl_to_unicode_list)/sizeof(hp_msl_to_unicode_list[0]); + i++) { + hp_msl_to_unicode *ptu = new hp_msl_to_unicode[1]; + ptu->value = (char *)hp_msl_to_unicode_list[i].value; + hp_msl_to_unicode_table.define(hp_msl_to_unicode_list[i].key, ptu); + } +} + +const char *hp_msl_to_unicode_code(const char *s) +{ + hp_msl_to_unicode *result = hp_msl_to_unicode_table.lookup(s); + return result ? result->value : 0; +} diff --git a/src/utils/indxbib/eign b/src/utils/indxbib/eign new file mode 100644 index 0000000..7718c8b --- /dev/null +++ b/src/utils/indxbib/eign @@ -0,0 +1,133 @@ +a +i +the +to +of +and +in +is +it +for +that +if +you +this +be +on +with +not +have +are +or +as +from +can +but +by +at +an +will +no +all +was +do +there +my +one +so +we +they +what +would +any +which +about +get +your +use +some +me +then +name +like +out +when +up +time +other +more +only +just +end +also +know +how +new +should +been +than +them +he +who +make +may +people +these +now +their +here +into +first +could +way +had +see +work +well +were +two +very +where +while +us +because +good +same +even +much +most +many +such +long +his +over +last +since +right +before +our +without +too +those +why +must +part +being +current +back +still +go +point +value +each +did +both +true +off +say +another +state +might +under +start +try diff --git a/src/utils/indxbib/indxbib.1.man b/src/utils/indxbib/indxbib.1.man new file mode 100644 index 0000000..df02fcc --- /dev/null +++ b/src/utils/indxbib/indxbib.1.man @@ -0,0 +1,347 @@ +.TH @g@indxbib @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +@g@indxbib \- make inverted index for bibliographic databases +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1989-2020 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_indxbib_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY @g@indxbib +.RB [ \-w ] +.RB [ \-c\~\c +.IR \%common-words-file ] +.RB [ \-d\~\c +.IR dir ] +.RB [ \-f\~\c +.IR \%list-file ] +.RB [ \-h\~\c +.IR \%min-hash-table-size ] +.RB [ \-i\~\c +.IR \%excluded-fields ] +.RB [ \-k\~\c +.IR \%max-keys-per-record ] +.RB [ \-l\~\c +.IR \%min-key-length ] +.RB [ \-n\~\c +.IR \%threshold ] +.RB [ \-o\~\c +.IR file ] +.RB [ \-t\~\c +.IR \%max-key-length ] +.RI [ file\~ .\|.\|.] +.YS +. +. +.SY @g@indxbib +.B \-\-help +.YS +. +. +.SY @g@indxbib +.B \-v +. +.SY @g@indxbib +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I @g@indxbib +makes an inverted index for the bibliographic databases in each +.I file +for use with +.MR @g@refer @MAN1EXT@ , +.MR @g@lookbib @MAN1EXT@ , +and +.MR lkbib @MAN1EXT@ . +. +Each created index is named +.RI file @INDEX_SUFFIX@ ; +writing is done to a temporary file which is then renamed to this. +. +If no +.I file +operands are given on the command line because the +.B \-f +option has been used, +and no +.B \-o +option is given, +the index will be named +.IR \%@DEFAULT_INDEX_NAME@@INDEX_SUFFIX@ . +. +. +.LP +Bibliographic databases are divided into records by blank lines. +. +Within a record, +each field starts with a +.B % +character at the beginning of a line. +. +Fields have a one letter name that follows the +.B % +character. +. +. +.LP +The values set by the +.BR \-c , +.BR \-l , +.BR \-n , +and +.B \-t +options are stored in the index: +when the index is searched, +keys will be discarded and truncated in a +manner appropriate to these options; +the original keys will be used for verifying that any record +found using the index actually contains the keys. +. +This means that a user of an index need not know whether these +options were used in the creation of the index, +provided that not all the keys to be searched for +would have been discarded during indexing +and that the user supplies at least the part of each key +that would have remained after being truncated during indexing. +. +The value set by the +.B \-i +option is also stored in the index +and will be used in verifying records found using the index. +. +. +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-\-help +displays a usage message, +while +.B \-v +and +.B \-\-version +show version information; +all exit afterward. +. +. +.TP +.BI \-c\~ common-words-file +Read the list of common words from +.I common-words-file +instead of +.IR \%@COMMON_WORDS_FILE@ . +. +. +.TP +.BI \-d\~ dir +Use +.I dir +as the name of the directory to store in the index, +instead of that returned by +.MR getcwd 2 . +. +Typically, +.I dir +will be a symbolic link whose target is the current working directory. +. +. +.TP +.BI \-f\~ list-file +Read the files to be indexed from +.IR list-file . +. +If +.I list-file +is +.BR \- , +files will be read from the standard input stream. +. +The +.B \-f +option can be given at most once. +. +. +.TP +.BI \-h\~ min-hash-table-size +Use the first prime number greater than or equal to +the argument for the size of the hash table. +. +Larger values +will usually make searching faster, +but will make the index file larger +and cause +.I @g@indxbib +to use more memory. +. +The default hash table size is 997. +. +. +.TP +.BI \-i\~ excluded-fields +Don't index the contents of fields whose names are in +.IR excluded-fields . +. +Field names are one character each. +. +If this option is not present, +.I @g@indxbib +excludes fields +.BR X , +.BR Y , +and +.BR Z . +. +. +.TP +.BI \-k\~ max-keys-per-record +Use no more keys per input record than specified in the argument. +. +If this option is not present, +the maximum is 100. +. +. +.TP +.BI \-l\~ min-key-length +Discard any key whose length in characters is shorter than the value of +the argument. +. +If this option is not present, +the minimum key length +is 3. +. +. +.TP +.BI \-n\~ threshold +Discard the +.I threshold +most common words from the common words file. +. +If this option is not present, +the 100 most common words are discarded. +. +. +.TP +.BI \-o\~ basename +Name the index +.RI basename @INDEX_SUFFIX@ . +. +. +.TP +.BI \-t\~ max-key-length +Truncate keys to +.I max-key-length +in characters. +. +If this option is not present, +keys are truncated to 6 characters. +. +. +.TP +.B \-w +Index whole files. +. +Each file is a separate record. +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.RI \%file @INDEX_SUFFIX@ +index for +.I file +. +. +.TP +.I \%@DEFAULT_INDEX_NAME@@INDEX_SUFFIX@ +default index name +. +. +.TP +.I \%@COMMON_WORDS_FILE@ +contains the list of common words. +. +The traditional name, +.RI \[lq] eign \[rq], +is an abbreviation of \[lq]English ignored [word list]\[rq]. +. +. +.TP +.IR \%indxbib XXXXXX +temporary file +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +\[lq]Some Applications of Inverted Indexes on the Unix System\[rq], +by M.\& E.\& Lesk, +1978, +AT&T Bell Laboratories Computing Science Technical Report No.\& 69. +. +. +.LP +.MR @g@refer @MAN1EXT@ , +.MR lkbib @MAN1EXT@ , +.MR @g@lookbib @MAN1EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_indxbib_1_man_C] +.do rr *groff_indxbib_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/utils/indxbib/indxbib.am b/src/utils/indxbib/indxbib.am new file mode 100644 index 0000000..d2a7d5a --- /dev/null +++ b/src/utils/indxbib/indxbib.am @@ -0,0 +1,57 @@ +# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# +# This file 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 . + +indxbib_srcdir = $(top_srcdir)/src/utils/indxbib +prefixexecbin_PROGRAMS += indxbib +indxbib_SOURCES = \ + src/utils/indxbib/indxbib.cpp \ + src/utils/indxbib/signal.c +src/utils/indxbib/indxbib.$(OBJEXT): defs.h +indxbib_LDADD = libbib.a libgroff.a $(LIBM) lib/libgnu.a +PREFIXMAN1 += src/utils/indxbib/indxbib.1 +EXTRA_DIST += \ + src/utils/indxbib/indxbib.1.man \ + src/utils/indxbib/eign + +install-data-local: install_indxbib +install_indxbib: $(indxbib_srcdir)/eign + -test -d $(DESTDIR)$(datadir) \ + || $(mkinstalldirs) $(DESTDIR)$(datadir) + -test -d $(DESTDIR)$(dataprogramdir) \ + || $(mkinstalldirs) $(DESTDIR)$(dataprogramdir) + -test -d $(DESTDIR)$(datasubdir) \ + || $(mkinstalldirs) $(DESTDIR)$(datasubdir) + if test -f /usr/lib/eign; then \ + rm -f $(DESTDIR)$(common_words_file); \ + ln -s /usr/lib/eign $(DESTDIR)$(common_words_file) 2>/dev/null \ + || ln /usr/lib/eign $(DESTDIR)$(common_words_file) 2>/dev/null \ + || cp /usr/lib/eign $(DESTDIR)$(common_words_file); \ + else \ + rm -f $(DESTDIR)$(common_words_file); \ + $(INSTALL_DATA) $(indxbib_srcdir)/eign $(DESTDIR)$(common_words_file); \ + fi + +uninstall-local: uninstall_indxbib +uninstall_indxbib: + rm -f $(DESTDIR)$(common_words_file) + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/utils/indxbib/indxbib.cpp b/src/utils/indxbib/indxbib.cpp new file mode 100644 index 0000000..ad8bb0e --- /dev/null +++ b/src/utils/indxbib/indxbib.cpp @@ -0,0 +1,803 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "lib.h" + +#include +#include +#include + +#include "posix.h" +#include "errarg.h" +#include "error.h" +#include "stringclass.h" +#include "cset.h" +#include "cmap.h" + +#include "defs.h" +#include "index.h" + +#include "nonposix.h" + +extern "C" const char *Version_string; + +#define DEFAULT_HASH_TABLE_SIZE 997 +#define TEMP_INDEX_TEMPLATE "indxbibXXXXXX" + +// (2^n - MALLOC_OVERHEAD) should be a good argument for malloc(). + +#define MALLOC_OVERHEAD 16 + +#ifdef BLOCK_SIZE +#undef BLOCK_SIZE +#endif + +const int BLOCK_SIZE = ((1024 - MALLOC_OVERHEAD - sizeof(struct block *) + - sizeof(int)) / sizeof(int)); +struct block { + block *next; + int used; + int v[BLOCK_SIZE]; + + block(block *p = 0) : next(p), used(0) { } +}; + +struct block; + +union table_entry { + block *ptr; + int count; +}; + +struct word_list { + word_list *next; + char *str; + int len; + word_list(const char *, int, word_list *); +}; + +table_entry *hash_table; +int hash_table_size = DEFAULT_HASH_TABLE_SIZE; +// We make this the same size as hash_table so we only have to do one +// mod per key. +static word_list **common_words_table = 0; +char *key_buffer; + +FILE *indxfp; +int ntags = 0; +string filenames; +char *temp_index_file = 0; + +const char *ignore_fields = "XYZ"; +const char *common_words_file = COMMON_WORDS_FILE; +int n_ignore_words = 100; +int truncate_len = 6; +int shortest_len = 3; +int max_keys_per_item = 100; + +static void usage(FILE *stream); +static void write_hash_table(); +static void init_hash_table(); +static void read_common_words_file(); +static int store_key(char *s, int len); +static void possibly_store_key(char *s, int len); +static int do_whole_file(const char *filename); +static int do_file(const char *filename); +static void store_reference(int filename_index, int pos, int len); +static void check_integer_arg(char opt, const char *arg, int min, int *res); +static void store_filename(const char *); +static void fwrite_or_die(const void *ptr, int size, int nitems, FILE *fp); +static char *get_cwd(); + +extern "C" { + void cleanup(); + void catch_fatal_signals(); + void ignore_fatal_signals(); +} + +int main(int argc, char **argv) +{ + program_name = argv[0]; + static char stderr_buf[BUFSIZ]; + setbuf(stderr, stderr_buf); + + const char *base_name = 0; + typedef int (*parser_t)(const char *); + parser_t parser = do_file; + const char *directory = 0; + const char *foption = 0; + int opt; + static const struct option long_options[] = { + { "help", no_argument, 0, CHAR_MAX + 1 }, + { "version", no_argument, 0, 'v' }, + { NULL, 0, 0, 0 } + }; + while ((opt = getopt_long(argc, argv, "c:o:h:i:k:l:t:n:c:d:f:vw", + long_options, NULL)) + != EOF) + switch (opt) { + case 'c': + common_words_file = optarg; + break; + case 'd': + directory = optarg; + break; + case 'f': + foption = optarg; + break; + case 'h': + { + int requested_hash_table_size; + check_integer_arg('h', optarg, 1, &requested_hash_table_size); + hash_table_size = requested_hash_table_size; + if ((hash_table_size > 2) && (hash_table_size % 2) == 0) + hash_table_size++; + while (!is_prime(hash_table_size)) + hash_table_size += 2; + if (hash_table_size != requested_hash_table_size) + warning("requested hash table size %1 is not prime: using %2" + " instead", optarg, hash_table_size); + } + break; + case 'i': + ignore_fields = optarg; + break; + case 'k': + check_integer_arg('k', optarg, 1, &max_keys_per_item); + break; + case 'l': + check_integer_arg('l', optarg, 0, &shortest_len); + break; + case 'n': + check_integer_arg('n', optarg, 0, &n_ignore_words); + break; + case 'o': + base_name = optarg; + break; + case 't': + check_integer_arg('t', optarg, 1, &truncate_len); + break; + case 'w': + parser = do_whole_file; + break; + case 'v': + printf("GNU indxbib (groff) version %s\n", Version_string); + exit(0); + break; + case CHAR_MAX + 1: // --help + usage(stdout); + exit(0); + break; + case '?': + usage(stderr); + exit(1); + break; + default: + assert(0); + break; + } + if (optind >= argc && foption == 0) + fatal("no files and no -f option"); + if (!directory) { + char *path = get_cwd(); + store_filename(path); + delete[] path; + } + else + store_filename(directory); + init_hash_table(); + store_filename(common_words_file); + store_filename(ignore_fields); + key_buffer = new char[truncate_len]; + read_common_words_file(); + if (!base_name) + base_name = optind < argc ? argv[optind] : DEFAULT_INDEX_NAME; + const char *p = strrchr(base_name, DIR_SEPS[0]), *p1; + const char *sep = &DIR_SEPS[1]; + while (*sep) { + p1 = strrchr(base_name, *sep); + if (p1 && (!p || p1 > p)) + p = p1; + sep++; + } + size_t name_max; + if (p) { + char *dir = strsave(base_name); + dir[p - base_name] = '\0'; + name_max = file_name_max(dir); + delete[] dir; + } + else + name_max = file_name_max("."); + const char *filename = p ? p + 1 : base_name; + if (strlen(filename) + sizeof(INDEX_SUFFIX) - 1 > name_max) + fatal("'%1.%2' is too long for a filename", filename, INDEX_SUFFIX); + if (p) { + p++; + temp_index_file = new char[p - base_name + sizeof(TEMP_INDEX_TEMPLATE)]; + memcpy(temp_index_file, base_name, p - base_name); + strcpy(temp_index_file + (p - base_name), TEMP_INDEX_TEMPLATE); + } + else { + temp_index_file = strsave(TEMP_INDEX_TEMPLATE); + } + catch_fatal_signals(); + int fd = mkstemp(temp_index_file); + if (fd < 0) + fatal("can't create temporary index file: %1", strerror(errno)); + indxfp = fdopen(fd, FOPEN_WB); + if (indxfp == 0) + fatal("fdopen failed"); + if (fseek(indxfp, sizeof(index_header), 0) < 0) + fatal("can't seek past index header: %1", strerror(errno)); + int failed = 0; + if (foption) { + FILE *fp = stdin; + if (strcmp(foption, "-") != 0) { + errno = 0; + fp = fopen(foption, "r"); + if (!fp) + fatal("can't open '%1': %2", foption, strerror(errno)); + } + string path; + int lineno = 1; + for (;;) { + int c; + for (c = getc(fp); c != '\n' && c != EOF; c = getc(fp)) { + if (c == '\0') + error_with_file_and_line(foption, lineno, + "nul character in pathname ignored"); + else + path += c; + } + if (path.length() > 0) { + path += '\0'; + if (!(*parser)(path.contents())) + failed = 1; + path.clear(); + } + if (c == EOF) + break; + lineno++; + } + if (fp != stdin) + fclose(fp); + } + for (int i = optind; i < argc; i++) + if (!(*parser)(argv[i])) + failed = 1; + write_hash_table(); + if (fclose(indxfp) < 0) + fatal("error closing temporary index file: %1", strerror(errno)); + char *index_file = new char[strlen(base_name) + sizeof(INDEX_SUFFIX)]; + strcpy(index_file, base_name); + strcat(index_file, INDEX_SUFFIX); +#ifdef HAVE_RENAME +#ifdef __EMX__ + if (access(index_file, R_OK) == 0) + unlink(index_file); +#endif /* __EMX__ */ + if (rename(temp_index_file, index_file) < 0) { +#ifdef __MSDOS__ + // RENAME could fail on plain MS-DOS filesystems because + // INDEX_FILE is an invalid filename, e.g. it has multiple dots. + char *fname = p ? index_file + (p - base_name) : 0; + char *dot = 0; + + // Replace the dot with an underscore and try again. + if (fname + && (dot = strchr(fname, '.')) != 0 + && strcmp(dot, INDEX_SUFFIX) != 0) + *dot = '_'; + if (rename(temp_index_file, index_file) < 0) +#endif + fatal("can't rename temporary index file: %1", strerror(errno)); + } +#else /* not HAVE_RENAME */ + ignore_fatal_signals(); + if (unlink(index_file) < 0) { + if (errno != ENOENT) + fatal("can't unlink '%1': %2", index_file, strerror(errno)); + } + if (link(temp_index_file, index_file) < 0) + fatal("can't link temporary index file: %1", strerror(errno)); + if (unlink(temp_index_file) < 0) + fatal("can't unlink temporary index file: %1", strerror(errno)); +#endif /* not HAVE_RENAME */ + temp_index_file = 0; + return failed; +} + +static void usage(FILE *stream) +{ + fprintf(stream, +"usage: %s [-w] [-c common-words-file] [-d dir] [-f list-file]" +" [-h min-hash-table-size] [-i excluded-fields]" +" [-k max-keys-per-record] [-l min-key-length]" +" [-n threshold] [-o file] [-t max-key-length] [file ...]\n" +"usage: %s {-v | --version}\n" +"usage: %s --help\n", + program_name, program_name, program_name); +} + +static void check_integer_arg(char opt, const char *arg, int min, int *res) +{ + char *ptr; + long n = strtol(arg, &ptr, 10); + if (n == 0 && ptr == arg) + error("argument to -%1 not an integer", opt); + else if (n < min) + error("argument to -%1 must not be less than %2", opt, min); + else { + if (n > INT_MAX) + error("argument to -%1 greater than maximum integer", opt); + else if (*ptr != '\0') + error("junk after integer argument to -%1", opt); + *res = int(n); + } +} + +static char *get_cwd() +{ + char *buf; + int size = 12; + + for (;;) { + buf = new char[size]; + if (getcwd(buf, size)) + break; + if (errno != ERANGE) + fatal("cannot get current working directory: %1", strerror(errno)); + delete[] buf; + if (size == INT_MAX) + fatal("current working directory longer than INT_MAX"); + if (size > INT_MAX/2) + size = INT_MAX; + else + size *= 2; + } + return buf; +} + +word_list::word_list(const char *s, int n, word_list *p) +: next(p), len(n) +{ + str = new char[n]; + memcpy(str, s, n); +} + +static void read_common_words_file() +{ + if (n_ignore_words <= 0) + return; + errno = 0; + FILE *fp = fopen(common_words_file, "r"); + if (!fp) + fatal("can't open '%1': %2", common_words_file, strerror(errno)); + common_words_table = new word_list * [hash_table_size]; + for (int i = 0; i < hash_table_size; i++) + common_words_table[i] = 0; + int count = 0; + int key_len = 0; + for (;;) { + int c = getc(fp); + while (c != EOF && !csalnum(c)) + c = getc(fp); + if (c == EOF) + break; + do { + if (key_len < truncate_len) + key_buffer[key_len++] = cmlower(c); + c = getc(fp); + } while (c != EOF && csalnum(c)); + if (key_len >= shortest_len) { + int h = hash(key_buffer, key_len) % hash_table_size; + common_words_table[h] = new word_list(key_buffer, key_len, + common_words_table[h]); + } + if (++count >= n_ignore_words) + break; + key_len = 0; + if (c == EOF) + break; + } + n_ignore_words = count; + fclose(fp); +} + +static int do_whole_file(const char *filename) +{ + errno = 0; + FILE *fp = fopen(filename, "r"); + if (!fp) { + error("can't open '%1': %2", filename, strerror(errno)); + return 0; + } + int count = 0; + int key_len = 0; + int c; + while ((c = getc(fp)) != EOF) { + if (csalnum(c)) { + key_len = 1; + key_buffer[0] = c; + while ((c = getc(fp)) != EOF) { + if (!csalnum(c)) + break; + if (key_len < truncate_len) + key_buffer[key_len++] = c; + } + if (store_key(key_buffer, key_len)) { + if (++count >= max_keys_per_item) + break; + } + if (c == EOF) + break; + } + } + store_reference(filenames.length(), 0, 0); + store_filename(filename); + fclose(fp); + return 1; +} + +static int do_file(const char *filename) +{ + errno = 0; + // Need binary I/O for MS-DOS/MS-Windows, because indxbib relies on + // byte counts to be consistent with fseek. + FILE *fp = fopen(filename, FOPEN_RB); + if (fp == 0) { + error("can't open '%1': %2", filename, strerror(errno)); + return 0; + } + int filename_index = filenames.length(); + store_filename(filename); + + enum { + START, // at the start of the file; also in between references + BOL, // in the middle of a reference, at the beginning of the line + PERCENT, // seen a percent at the beginning of the line + IGNORE, // ignoring a field + IGNORE_BOL, // at the beginning of a line ignoring a field + KEY, // in the middle of a key + DISCARD, // after truncate_len bytes of a key + MIDDLE // in between keys + } state = START; + + // In states START, BOL, IGNORE_BOL, space_count how many spaces at + // the beginning have been seen. In states PERCENT, IGNORE, KEY, + // MIDDLE space_count must be 0. + int space_count = 0; + int byte_count = 0; // bytes read + int key_len = 0; + int ref_start = -1; // position of start of current reference + for (;;) { + int c = getc(fp); + if (c == EOF) + break; + // We opened the file in binary mode, so we need to skip + // every CR character before a Newline. + if (c == '\r') { + int peek = getc(fp); + if (peek == '\n') { + byte_count++; + c = peek; + } + else + ungetc(peek, fp); + } +#if defined(__MSDOS__) || defined(_MSC_VER) || defined(__EMX__) + else if (c == 0x1a) // ^Z means EOF in text files + break; +#endif + byte_count++; + switch (state) { + case START: + if (c == ' ' || c == '\t') { + space_count++; + break; + } + if (c == '\n') { + space_count = 0; + break; + } + ref_start = byte_count - space_count - 1; + space_count = 0; + if (c == '%') + state = PERCENT; + else if (csalnum(c)) { + state = KEY; + key_buffer[0] = c; + key_len = 1; + } + else + state = MIDDLE; + break; + case BOL: + switch (c) { + case '%': + if (space_count > 0) { + space_count = 0; + state = MIDDLE; + } + else + state = PERCENT; + break; + case ' ': + case '\t': + space_count++; + break; + case '\n': + store_reference(filename_index, ref_start, + byte_count - 1 - space_count - ref_start); + state = START; + space_count = 0; + break; + default: + space_count = 0; + if (csalnum(c)) { + state = KEY; + key_buffer[0] = c; + key_len = 1; + } + else + state = MIDDLE; + } + break; + case PERCENT: + if (strchr(ignore_fields, c) != 0) + state = IGNORE; + else if (c == '\n') + state = BOL; + else + state = MIDDLE; + break; + case IGNORE: + if (c == '\n') + state = IGNORE_BOL; + break; + case IGNORE_BOL: + switch (c) { + case '%': + if (space_count > 0) { + state = IGNORE; + space_count = 0; + } + else + state = PERCENT; + break; + case ' ': + case '\t': + space_count++; + break; + case '\n': + store_reference(filename_index, ref_start, + byte_count - 1 - space_count - ref_start); + state = START; + space_count = 0; + break; + default: + space_count = 0; + state = IGNORE; + } + break; + case KEY: + if (csalnum(c)) { + if (key_len < truncate_len) + key_buffer[key_len++] = c; + else + state = DISCARD; + } + else { + possibly_store_key(key_buffer, key_len); + key_len = 0; + if (c == '\n') + state = BOL; + else + state = MIDDLE; + } + break; + case DISCARD: + if (!csalnum(c)) { + possibly_store_key(key_buffer, key_len); + key_len = 0; + if (c == '\n') + state = BOL; + else + state = MIDDLE; + } + break; + case MIDDLE: + if (csalnum(c)) { + state = KEY; + key_buffer[0] = c; + key_len = 1; + } + else if (c == '\n') + state = BOL; + break; + default: + assert(0); + } + } + switch (state) { + case START: + break; + case DISCARD: + case KEY: + possibly_store_key(key_buffer, key_len); + // fall through + case BOL: + case PERCENT: + case IGNORE_BOL: + case IGNORE: + case MIDDLE: + store_reference(filename_index, ref_start, + byte_count - ref_start - space_count); + break; + default: + assert(0); + } + fclose(fp); + return 1; +} + +static void store_reference(int filename_index, int pos, int len) +{ + tag t; + t.filename_index = filename_index; + t.start = pos; + t.length = len; + fwrite_or_die(&t, sizeof(t), 1, indxfp); + ntags++; +} + +static void store_filename(const char *fn) +{ + filenames += fn; + filenames += '\0'; +} + +static void init_hash_table() +{ + hash_table = new table_entry[hash_table_size]; + for (int i = 0; i < hash_table_size; i++) + hash_table[i].ptr = 0; +} + +static void possibly_store_key(char *s, int len) +{ + static int last_tagno = -1; + static int key_count; + if (last_tagno != ntags) { + last_tagno = ntags; + key_count = 0; + } + if (key_count < max_keys_per_item) { + if (store_key(s, len)) + key_count++; + } +} + +static int store_key(char *s, int len) +{ + if (len < shortest_len) + return 0; + int is_number = 1; + for (int i = 0; i < len; i++) + if (!csdigit(s[i])) { + is_number = 0; + s[i] = cmlower(s[i]); + } + if (is_number && !(len == 4 && s[0] == '1' && s[1] == '9')) + return 0; + int h = hash(s, len) % hash_table_size; + if (common_words_table) { + for (word_list *ptr = common_words_table[h]; ptr; ptr = ptr->next) + if (len == ptr->len && memcmp(s, ptr->str, len) == 0) + return 0; + } + table_entry *pp = hash_table + h; + if (!pp->ptr) + pp->ptr = new block; + else if (pp->ptr->v[pp->ptr->used - 1] == ntags) + return 1; + else if (pp->ptr->used >= BLOCK_SIZE) + pp->ptr = new block(pp->ptr); + pp->ptr->v[(pp->ptr->used)++] = ntags; + return 1; +} + +static void write_hash_table() +{ + const int minus_one = -1; + int li = 0; + for (int i = 0; i < hash_table_size; i++) { + block *ptr = hash_table[i].ptr; + if (!ptr) + hash_table[i].count = -1; + else { + hash_table[i].count = li; + block *rev = 0; + while (ptr) { + block *tem = ptr; + ptr = ptr->next; + tem->next = rev; + rev = tem; + } + while (rev) { + fwrite_or_die(rev->v, sizeof(int), rev->used, indxfp); + li += rev->used; + block *tem = rev; + rev = rev->next; + delete tem; + } + fwrite_or_die(&minus_one, sizeof(int), 1, indxfp); + li += 1; + } + } + if (sizeof(table_entry) == sizeof(int)) + fwrite_or_die(hash_table, sizeof(int), hash_table_size, indxfp); + else { + // write it out word by word + for (int i = 0; i < hash_table_size; i++) + fwrite_or_die(&hash_table[i].count, sizeof(int), 1, indxfp); + } + fwrite_or_die(filenames.contents(), 1, filenames.length(), indxfp); + if (fseek(indxfp, 0, 0) < 0) + fatal("error seeking on index file: %1", strerror(errno)); + index_header h; + h.magic = INDEX_MAGIC; + h.version = INDEX_VERSION; + h.tags_size = ntags; + h.lists_size = li; + h.table_size = hash_table_size; + h.strings_size = filenames.length(); + h.truncate = truncate_len; + h.shortest = shortest_len; + h.common = n_ignore_words; + fwrite_or_die(&h, sizeof(h), 1, indxfp); +} + +static void fwrite_or_die(const void *ptr, int size, int nitems, FILE *fp) +{ + if (fwrite(ptr, size, nitems, fp) != (size_t)nitems) + fatal("fwrite failed: %1", strerror(errno)); +} + +void fatal_error_exit() +{ + cleanup(); + exit(3); +} + +extern "C" { + +void cleanup() +{ + if (temp_index_file) + unlink(temp_index_file); +} + +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/utils/indxbib/signal.c b/src/utils/indxbib/signal.c new file mode 100644 index 0000000..2231b64 --- /dev/null +++ b/src/utils/indxbib/signal.c @@ -0,0 +1,77 @@ +/* Copyright (C) 1992-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +/* Unfortunately vendors seem to have problems writing a +that is correct for C++, so we implement all signal handling in C. */ + +#include + +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Prototype */ +void catch_fatal_signals(void); + +extern void cleanup(void); + +static RETSIGTYPE handle_fatal_signal(int signum) +{ + signal(signum, SIG_DFL); + cleanup(); +#ifdef HAVE_KILL + kill(getpid(), signum); +#else + /* MS-DOS and Win32 don't have kill(); the best compromise is + probably to use exit() instead. */ + exit(signum); +#endif +} + +void catch_fatal_signals(void) +{ +#ifdef SIGHUP + signal(SIGHUP, handle_fatal_signal); +#endif + signal(SIGINT, handle_fatal_signal); + signal(SIGTERM, handle_fatal_signal); +} + +#ifdef __cplusplus +} +#endif + +#ifndef HAVE_RENAME + +void ignore_fatal_signals() +{ +#ifdef SIGHUP + signal(SIGHUP, SIG_IGN); +#endif + signal(SIGINT, SIG_IGN); + signal(SIGTERM, SIG_IGN); +} + +#endif /* not HAVE_RENAME */ diff --git a/src/utils/lkbib/lkbib.1.man b/src/utils/lkbib/lkbib.1.man new file mode 100644 index 0000000..59ef19f --- /dev/null +++ b/src/utils/lkbib/lkbib.1.man @@ -0,0 +1,212 @@ +.TH lkbib @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +lkbib \- search bibliographic databases +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1989-2020 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_lkbib_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY lkbib +.RB [ \-n ] +.RB [ \-i\~\c +.IR fields ] +.RB [ \-p\~\c +.IR file ] +\&.\|.\|.\& +.RB [ \-t\~\c +.IR n ] +.I key +\&.\|.\|. +.YS +. +. +.SY lkbib +.B \-\-help +.YS +. +. +.SY lkbib +.B \-v +. +.SY lkbib +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I \%lkbib +searches bibliographic databases for references containing keywords +.I key +and writes any references found to the standard output +stream. +. +It reads databases given by +.B \-p +options +and then +(unless +.B \-n +is given) +a default database. +. +The default database is taken from the +.I \%REFER +environment variable if it is set, +otherwise it is +.IR @DEFAULT_INDEX@ . +. +For each database +.I file +to be searched, +if an index +.RI file @INDEX_SUFFIX@ +created by +.MR @g@indxbib @MAN1EXT@ +exists, +then it will be searched instead; +each index can cover multiple databases. +. +. +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-\-help +displays a usage message, +while +.B \-v +and +.B \-\-version +show version information; +all exit afterward. +. +. +.TP +.BI \-i\~ string +When searching files for which no index exists, +ignore the contents of fields whose names are in +.IR string . +. +. +.TP +.B \-n +Suppress search of default database. +. +. +.TP +.BI \-p\~ file +Search +.IR file . +. +Multiple +.B \-p +options can be used. +. +. +.TP +.BI \-t\~ n +Require only the first +.I n +characters of keys to be given. +. +The default +is\~6. +. +. +.\" ==================================================================== +.SH Environment +.\" ==================================================================== +. +.TP +.I REFER +Default database. +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.I \%@DEFAULT_INDEX@ +Default database to be used if the +.I \%REFER +environment variable is not set. +. +. +.TP +.RI file @INDEX_SUFFIX@ +Index files. +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +\[lq]Some Applications of Inverted Indexes on the Unix System\[rq], +by M.\& E.\& Lesk, +1978, +AT&T Bell Laboratories Computing Science Technical Report No.\& 69. +. +. +.LP +.MR @g@refer @MAN1EXT@ , +.MR @g@lookbib @MAN1EXT@ , +.MR @g@indxbib @MAN1EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_lkbib_1_man_C] +.do rr *groff_lkbib_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/utils/lkbib/lkbib.am b/src/utils/lkbib/lkbib.am new file mode 100644 index 0000000..5f75596 --- /dev/null +++ b/src/utils/lkbib/lkbib.am @@ -0,0 +1,30 @@ +# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# +# This file 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 . + +bin_PROGRAMS += lkbib +man1_MANS += src/utils/lkbib/lkbib.1 +EXTRA_DIST += src/utils/lkbib/lkbib.1.man +lkbib_LDADD = libbib.a libgroff.a $(LIBM) lib/libgnu.a +lkbib_SOURCES = src/utils/lkbib/lkbib.cpp +src/utils/lkbib/lkbib.$(OBJEXT): defs.h + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/utils/lkbib/lkbib.cpp b/src/utils/lkbib/lkbib.cpp new file mode 100644 index 0000000..946bd7d --- /dev/null +++ b/src/utils/lkbib/lkbib.cpp @@ -0,0 +1,144 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "lib.h" + +#include +#include +#include + +#include "errarg.h" +#include "error.h" + +#include "defs.h" +#include "refid.h" +#include "search.h" + +extern "C" const char *Version_string; + +static void usage(FILE *stream) +{ + fprintf(stream, + "usage: %s [-n] [-p database] [-i XYZ] [-t N] key ...\n" + "usage: %s {-v | --version}\n" + "usage: %s --help\n", + program_name, program_name, program_name); +} + +int main(int argc, char **argv) +{ + program_name = argv[0]; + static char stderr_buf[BUFSIZ]; + setbuf(stderr, stderr_buf); + int search_default = 1; + search_list list; + int opt; + static const struct option long_options[] = { + { "help", no_argument, 0, CHAR_MAX + 1 }, + { "version", no_argument, 0, 'v' }, + { NULL, 0, 0, 0 } + }; + while ((opt = getopt_long(argc, argv, "nvVi:t:p:", long_options, NULL)) + != EOF) + switch (opt) { + case 'V': + do_verify = true; + break; + case 'n': + search_default = 0; + break; + case 'i': + linear_ignore_fields = optarg; + break; + case 't': + { + char *ptr; + long n = strtol(optarg, &ptr, 10); + if (n == 0 && ptr == optarg) { + error("bad integer '%1' in 't' option", optarg); + break; + } + if (n < 1) + n = 1; + linear_truncate_len = int(n); + break; + } + case 'v': + { + printf("GNU lkbib (groff) version %s\n", Version_string); + exit(0); + break; + } + case 'p': + list.add_file(optarg); + break; + case CHAR_MAX + 1: // --help + usage(stdout); + exit(0); + break; + case '?': + usage(stderr); + exit(1); + break; + default: + assert(0); + } + if (optind >= argc) { + usage(stderr); + exit(1); + } + char *filename = getenv("REFER"); + if (filename) + list.add_file(filename); + else if (search_default) + list.add_file(DEFAULT_INDEX, 1); + if (list.nfiles() == 0) + fatal("no databases"); + int total_len = 0; + int i; + for (i = optind; i < argc; i++) + total_len += strlen(argv[i]); + total_len += argc - optind - 1 + 1; // for spaces and '\0' + char *buffer = new char[total_len]; + char *ptr = buffer; + for (i = optind; i < argc; i++) { + if (i > optind) + *ptr++ = ' '; + strcpy(ptr, argv[i]); + ptr = strchr(ptr, '\0'); + } + search_list_iterator iter(&list, buffer); + const char *start; + int len; + int count; + for (count = 0; iter.next(&start, &len); count++) { + if (fwrite(start, 1, len, stdout) != (size_t)len) + fatal("write error on stdout: %1", strerror(errno)); + // Can happen for last reference in file. + if (start[len - 1] != '\n') + putchar('\n'); + putchar('\n'); + } + return !count; +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/utils/lookbib/lookbib.1.man b/src/utils/lookbib/lookbib.1.man new file mode 100644 index 0000000..5d43bbb --- /dev/null +++ b/src/utils/lookbib/lookbib.1.man @@ -0,0 +1,166 @@ +.TH @g@lookbib @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +@g@lookbib \- search bibliographic databases +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1989-2020 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_lookbib_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY @g@lookbib +.RB [ \-i\~\c +.IR string ] +.RB [ \-t\~\c +.IR n ] +.I file +\&.\|.\|.\& +.YS +. +. +.SY @g@lookbib +.B \-\-help +.YS +. +. +.SY @g@lookbib +.B \-v +. +.SY @g@lookbib +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I @g@lookbib +writes a prompt to the standard error stream +(unless the standard input stream is not +a terminal), +reads from the standard input a line containing a set of keywords, +searches each bibliographic database +.I file +for references containing those keywords, +writes any references found to the standard output stream, +and repeats this process until the end of input. +. +For each database +.I file +to be searched, +if an index +.RI file @INDEX_SUFFIX@ +created by +.MR @g@indxbib @MAN1EXT@ +exists, +then it will be searched instead; +each index can cover multiple databases. +. +. +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-\-help +displays a usage message, +while +.B \-v +and +.B \-\-version +show version information; +all exit afterward. +. +. +.TP +.BI \-i\~ string +When searching files for which no index exists, +ignore the contents of fields whose names are in +.IR string . +. +. +.TP +.BI \-t\~ n +Require only the first +.I n +characters of keys to be given. +. +The default +is\~6. +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.RI file @INDEX_SUFFIX@ +Index files. +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +\[lq]Some Applications of Inverted Indexes on the Unix System\[rq], +by M.\& E.\& Lesk, +1978, +AT&T Bell Laboratories Computing Science Technical Report No.\& 69. +. +. +.LP +.MR @g@refer @MAN1EXT@ , +.MR lkbib @MAN1EXT@ , +.MR @g@indxbib @MAN1EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_lookbib_1_man_C] +.do rr *groff_lookbib_1_man_C +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/utils/lookbib/lookbib.am b/src/utils/lookbib/lookbib.am new file mode 100644 index 0000000..75103c1 --- /dev/null +++ b/src/utils/lookbib/lookbib.am @@ -0,0 +1,29 @@ +# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# +# This file 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 . + +prefixexecbin_PROGRAMS += lookbib +PREFIXMAN1 += src/utils/lookbib/lookbib.1 +EXTRA_DIST += src/utils/lookbib/lookbib.1.man +lookbib_LDADD = libbib.a libgroff.a $(LIBM) lib/libgnu.a +lookbib_SOURCES = src/utils/lookbib/lookbib.cpp + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/utils/lookbib/lookbib.cpp b/src/utils/lookbib/lookbib.cpp new file mode 100644 index 0000000..d8556c6 --- /dev/null +++ b/src/utils/lookbib/lookbib.cpp @@ -0,0 +1,146 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +#include "lib.h" + +#include +#include +#include + +#include "errarg.h" +#include "error.h" +#include "cset.h" + +#include "refid.h" +#include "search.h" + +/* for isatty() */ +#include "posix.h" +#include "nonposix.h" + +extern "C" const char *Version_string; + +static void usage(FILE *stream) +{ + fprintf(stream, + "usage: %s [-i XYZ] [-t N] database ...\n" + "usage: %s {-v | --version}\n" + "usage: %s --help\n", + program_name, program_name, program_name); +} + +int main(int argc, char **argv) +{ + program_name = argv[0]; + static char stderr_buf[BUFSIZ]; + setbuf(stderr, stderr_buf); + int opt; + static const struct option long_options[] = { + { "help", no_argument, 0, CHAR_MAX + 1 }, + { "version", no_argument, 0, 'v' }, + { NULL, 0, 0, 0 } + }; + while ((opt = getopt_long(argc, argv, "vVi:t:", long_options, NULL)) != EOF) + switch (opt) { + case 'V': + do_verify = true; + break; + case 'i': + linear_ignore_fields = optarg; + break; + case 't': + { + char *ptr; + long n = strtol(optarg, &ptr, 10); + if (n == 0 && ptr == optarg) { + error("bad integer '%1' in 't' option", optarg); + break; + } + if (n < 1) + n = 1; + linear_truncate_len = int(n); + break; + } + case 'v': + { + printf("GNU lookbib (groff) version %s\n", Version_string); + exit(0); + break; + } + case CHAR_MAX + 1: // --help + usage(stdout); + exit(0); + break; + case '?': + usage(stderr); + exit(1); + break; + default: + assert(0); + } + if (optind >= argc) { + usage(stderr); + exit(1); + } + search_list list; + for (int i = optind; i < argc; i++) + list.add_file(argv[i]); + if (list.nfiles() == 0) + fatal("no databases"); + char line[1024]; + int interactive = isatty(fileno(stdin)); + for (;;) { + if (interactive) { + fputs("> ", stderr); + fflush(stderr); + } + if (!fgets(line, sizeof(line), stdin)) + break; + char *ptr = line; + while (csspace(*ptr)) + ptr++; + if (*ptr == '\0') + continue; + search_list_iterator iter(&list, line); + const char *start; + int len; + int count; + for (count = 0; iter.next(&start, &len); count++) { + if (fwrite(start, 1, len, stdout) != (size_t)len) + fatal("write error on stdout: %1", strerror(errno)); + // Can happen for last reference in file. + if (start[len - 1] != '\n') + putchar('\n'); + putchar('\n'); + } + fflush(stdout); + if (interactive) { + fprintf(stderr, "%d found\n", count); + fflush(stderr); + } + } + if (interactive) + putc('\n', stderr); + return 0; +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/utils/pfbtops/pfbtops.1.man b/src/utils/pfbtops/pfbtops.1.man new file mode 100644 index 0000000..71140c6 --- /dev/null +++ b/src/utils/pfbtops/pfbtops.1.man @@ -0,0 +1,129 @@ +.TH pfbtops @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +pfbtops \- translate PostScript Printer Font Binary files to Printer +Font ASCII +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1989-2020 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_pfbtops_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY pfbtops +.RI [ pfb-file ] +.YS +. +. +.SY pfbtops +.B \-\-help +.YS +. +. +.SY pfbtops +.B \-v +. +.SY pfbtops +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I pfbtops +translates a PostScript Type\~1 font in Printer Font Binary (PFB) format +to Printer Font ASCII (PFA) format, +splitting overlong lines in text packets into smaller chunks. +. +If +.I pfb-file +is omitted, +the PFB file will be read from the standard input stream. +. +The PFA font will be written on the standard output stream. +. +PostScript fonts for MS-DOS were historically supplied in PFB format. +. +Use of a PostScript Type\~1 font with +.I groff +requires conversion of its metrics +(AFM file) +to a +.I groff +font description file; +see +.MR afmtodit @MAN1EXT@ . +. +. +.P +The +.B \-\-help +option displays a usage message, +while +.B \-v +and +.B \-\-version +show version information; +all exit afterward. +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.MR grops @MAN1EXT@ , +.MR gropdf @MAN1EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_pfbtops_1_man_C] +.do rr *groff_pfbtops_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/utils/pfbtops/pfbtops.am b/src/utils/pfbtops/pfbtops.am new file mode 100644 index 0000000..8b7fd71 --- /dev/null +++ b/src/utils/pfbtops/pfbtops.am @@ -0,0 +1,32 @@ +# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# +# This file 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 . + +bin_PROGRAMS += pfbtops +man1_MANS += src/utils/pfbtops/pfbtops.1 +EXTRA_DIST += src/utils/pfbtops/pfbtops.1.man +pfbtops_SOURCES = src/utils/pfbtops/pfbtops.c +pfbtops_LDADD = libgroff.a $(LIBM) lib/libgnu.a +# We use the following trick to force the use of C++ compiler +# See the Automake manual, "Libtool Convenience Libraries" +nodist_EXTRA_pfbtops_SOURCES = src/utils/pfbtops/dummy.cpp + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/utils/pfbtops/pfbtops.c b/src/utils/pfbtops/pfbtops.c new file mode 100644 index 0000000..8fbe44a --- /dev/null +++ b/src/utils/pfbtops/pfbtops.c @@ -0,0 +1,243 @@ +/* Copyright (C) 1992-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +/* This translates ps fonts in .pfb format to ASCII ps files. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define __GETOPT_PREFIX groff_ + +#include // errno +#include +#include // exit(), EXIT_FAILURE, EXIT_SUCCESS +#include // strerror() +#include + +#include + +#include "nonposix.h" + +/* Binary bytes per output line. */ +#define BYTES_PER_LINE (64/2) +#define MAX_LINE_LENGTH 78 +#define HEX_DIGITS "0123456789abcdef" + +extern const char *Version_string; + +static char *program_name; + +static void error(const char *s) +{ + fprintf(stderr, "%s: error: %s\n", program_name, s); + exit(EXIT_FAILURE); +} + +static void usage(FILE *stream) +{ + fprintf(stream, "usage: %s [pfb-file]\n" + "usage: %s {-v | --version}\n" + "usage: %s --help\n", + program_name, program_name, program_name); +} + +static void get_text(int n) +{ + int c = 0, c1; + int in_string = 0; + int is_comment = 0; + int count = 0; + + while (--n >= 0) { + c = getchar(); + if (c == '(' && !is_comment) + in_string++; + else if (c == ')' && !is_comment) + in_string--; + else if (c == '%' && !in_string) + is_comment = 1; + else if (c == '\\' && in_string) { + count++; + putchar(c); + if (n-- == 0) + break; + c = getchar(); + /* don't split octal character representations */ + if (c >= '0' && c <= '7') { + count++; + putchar(c); + if (n-- == 0) + break; + c = getchar(); + if (c >= '0' && c <= '7') { + count++; + putchar(c); + if (n-- == 0) + break; + c = getchar(); + if (c >= '0' && c <= '7') { + count++; + putchar(c); + if (n-- == 0) + break; + c = getchar(); + } + } + } + } + if (c == EOF) + error("end of file in text packet"); + else if (c == '\r') { + if (n-- == 0) + break; + c1 = getchar(); + if (c1 != '\n') { + ungetc(c1, stdin); + n++; + } + c = '\n'; + } + if (c == '\n') { + count = 0; + is_comment = 0; + } + else if (count >= MAX_LINE_LENGTH) { + if (in_string > 0) { + count = 1; + putchar('\\'); + putchar('\n'); + } + else if (is_comment) { + count = 2; + putchar('\n'); + putchar('%'); + } + else { + /* split at the next whitespace character */ + while (c != ' ' && c != '\t' && c != '\f') { + putchar(c); + if (n-- == 0) + break; + c = getchar(); + } + count = 0; + putchar('\n'); + continue; + } + } + count++; + putchar(c); + } + if (c != '\n') + putchar('\n'); +} + +static void get_binary(int n) +{ + int c; + int count = 0; + + while (--n >= 0) { + c = getchar(); + if (c == EOF) + error("end of file in binary packet"); + if (count >= BYTES_PER_LINE) { + putchar('\n'); + count = 0; + } + count++; + putchar(HEX_DIGITS[(c >> 4) & 0xf]); + putchar(HEX_DIGITS[c & 0xf]); + } + putchar('\n'); +} + +int main(int argc, char **argv) +{ + int opt; + static const struct option long_options[] = { + { "help", no_argument, 0, CHAR_MAX + 1 }, + { "version", no_argument, 0, 'v' }, + { NULL, 0, 0, 0 } + }; + + program_name = argv[0]; + + while ((opt = getopt_long(argc, argv, "v", long_options, NULL)) != EOF) { + switch (opt) { + case 'v': + printf("GNU pfbtops (groff) version %s\n", Version_string); + exit(EXIT_SUCCESS); + break; + case CHAR_MAX + 1: /* --help */ + usage(stdout); + exit(EXIT_SUCCESS); + break; + case '?': + usage(stderr); + exit(2); + break; + } + } + + if (argc - optind > 1) { + usage(stderr); + exit(2); + } + const char *file = argv[optind]; + if (argc > optind && !freopen(file, "r", stdin)) { + fprintf(stderr, "%s: error: unable to open file '%s': %s\n", + program_name, file, strerror(errno)); + exit(EXIT_FAILURE); + } + SET_BINARY(fileno(stdin)); + for (;;) { + int type, c, i; + long n; + + c = getchar(); + if (c != 0x80) + error("first byte of packet not 0x80"); + type = getchar(); + if (type == 3) + break; + if (type != 1 && type != 2) + error("bad packet type"); + n = 0; + for (i = 0; i < 4; i++) { + c = getchar(); + if (c == EOF) + error("end of file in packet header"); + n |= (long)c << (i << 3); + } + if (n < 0) + error("negative packet length"); + if (type == 1) + get_text(n); + else + get_binary(n); + } + exit(EXIT_SUCCESS); +} + +// Local Variables: +// fill-column: 72 +// mode: C +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/utils/tfmtodit/tfmtodit.1.man b/src/utils/tfmtodit/tfmtodit.1.man new file mode 100644 index 0000000..0f21753 --- /dev/null +++ b/src/utils/tfmtodit/tfmtodit.1.man @@ -0,0 +1,415 @@ +.TH tfmtodit @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +tfmtodit \- adapt TeX Font Metrics files for use with +.I groff +and +.I grodvi +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1989-2020 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_tfmtodit_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.\" Definitions +.\" ==================================================================== +. +.ie t .ds tx T\h'-.1667m'\v'.224m'E\v'-.224m'\h'-.125m'X +.el .ds tx TeX +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY tfmtodit +.RB [ \-s ] +.RB [ \-g\~\c +.IR gf-file ] +.RB [ \-k\~\c +.IR skew-char ] +.I tfm-file +.I map-file +.I font-description +.YS +. +. +.SY tfmtodit +.B \-\-help +.YS +. +. +.SY tfmtodit +.B \-v +. +.SY tfmtodit +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I tfmtodit +creates a font description file for use with +.MR groff @MAN1EXT@ 's +.B dvi +output device. +. +.I tfm-file +is the name of the \*(tx font metric file for the font. +. +.I map-file +assigns +.I groff +ordinary or special character identifiers to glyph indices in the font; +it should consist of a sequence of lines of the form +. +.RS +.IR "i c1" \~\&.\|.\|.\&\~ cn +.RE +. +where +.I i +is a position of the glyph in the font in decimal, +and +.I c1 +through +.I cn +are glyph identifiers in the form used by +.I groff +font descriptions. +. +If a glyph has no +.I groff +names but exists in +.I tfm-file, +it is put in the +.I groff +font description file as an unnamed glyph. +. +Output is written in +.MR groff_font @MAN5EXT@ +format to +.I font-description, +a file named for the intended +.I groff +font name. +. +. +.P +If the font is \[lq]special\[rq], +meaning that +.I groff +should search it whenever a glyph is not found in the current font, +use the +.B \-s +option and name +.I font-description +in the +.B fonts +directive in the output device's +.I DESC +file. +. +. +.P +To do a good job of math typesetting, +.I groff +requires font metric information not present in +.I tfm-file. +. +This is because \*(tx has separate math italic fonts, +whereas +.I groff +uses normal italic fonts for math. +. +The additional information required by +.I groff +is given by the two arguments to the +.B math_fit +macro in the Metafont programs for the Computer Modern fonts. +. +In a text font (a font for which +.B math_fit +is false), +Metafont normally ignores these two arguments. +. +Metafont can be made to put this information into the GF +(\[lq]generic font\[rq]) +files it produces by loading the following definition after +.B cmbase +when creating +.IR cm.base . +. +.RS +.EX +def ignore_math_fit(expr left_adjustment,right_adjustment) = + special "adjustment"; + numspecial left_adjustment*16/designsize; + numspecial right_adjustment*16/designsize; + enddef; +.EE +.RE +. +For the EC font family, +load the following definition after +.BR exbase ; +consider patching +.I exbase.mf +locally. +. +.RS +.EX +def ignore_math_fit(expr left_adjustment,right_adjustment) = + ori_special "adjustment"; + ori_numspecial left_adjustment*16/designsize; + ori_numspecial right_adjustment*16/designsize; + enddef; +.EE +.RE +. +The only difference from the previous example is the \[lq]ori_\[rq] +prefix to \[lq]special\[rq] and \[lq]numspecial\[rq]. +. +The GF file created using this modified +.I cm.base +or +.I exbase.mf +should be specified with the +.B \-g +option, +which should +.I not +be given for a font for which +.B math_fit +is true. +. +. +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-\-help +displays a usage message, +while +.B \-v +and +.B \-\-version +show version information; +all exit afterward. +. +. +.TP +.BI \-g \~gf-file +Use the +.I gf-file +produced by Metafont containing +.RB \[lq] special \[rq] +and +.RB \[lq] numspecial \[rq] +commands to obtain additional font metric information. +. +. +.TP +.BI \-k \~skew-char +The skew character of this font is at position +.I skew-char. +. +.I skew-char +should be an integer; +it may be given in decimal, +with a leading 0 in octal, +or with a leading 0x in hexadecimal. +. +Any kerns whose second component is +.I skew-char +are ignored. +. +. +.TP +.B \-s +Add the +.B special +directive to the font description file. +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.I @FONTDIR@/\:\%devdvi/\:DESC +describes the +.B dvi +output device. +. +. +.TP +.IR @FONTDIR@/\:\%devdvi/ F +describes the font known +.RI as\~ F +on device +.BR dvi . +. +. +.TP +.I @FONTDIR@/\:\%devdvi/\:\%generate/\:\%ec.map +.TQ +.I @FONTDIR@/\:\%devdvi/\:\%generate/\:\%msam.map +.TQ +.I @FONTDIR@/\:\%devdvi/\:\%generate/\:\%msbm.map +.TQ +.I @FONTDIR@/\:\%devdvi/\:\%generate/\:\%tc.map +.TQ +.I @FONTDIR@/\:\%devdvi/\:\%generate/\:\%texb.map +.TQ +.I @FONTDIR@/\:\%devdvi/\:\%generate/\:\%texex.map +.TQ +.I @FONTDIR@/\:\%devdvi/\:\%generate/\:\%texi.map +.TQ +.I @FONTDIR@/\:\%devdvi/\:\%generate/\:\%texitt.map +.TQ +.I @FONTDIR@/\:\%devdvi/\:\%generate/\:\%texmi.map +.TQ +.I @FONTDIR@/\:\%devdvi/\:\%generate/\:\%texr.map +.TQ +.I @FONTDIR@/\:\%devdvi/\:\%generate/\:\%texsy.map +.TQ +.I @FONTDIR@/\:\%devdvi/\:\%generate/\:\%textex.map +.TQ +.I @FONTDIR@/\:\%devdvi/\:\%generate/\:\%textt.map +map glyph indices in \*[tx] fonts to +.I groff +ordinary and special character identifiers. +. +.I \%ec.map +is used for +.BR TREC , +.BR TIEC , +.BR TBEC , +.BR TBIEC , +.BR HREC , +.BR HIEC , +.BR HBEC , +.BR HBIEC , +.BR CWEC , +and +.BR CWIEC ; +.I \%msam.map +for +.BR SA ; +.I \%msbm.map +for +.BR SB ; +.I \%tc.map +for +.BR TRTC , +.BR TITC , +.BR TBTC , +.BR TBITC , +.BR HRTC , +.BR HITC , +.BR HBTC , +.BR HBITC , +.BR CWTC , +and +.BR CWITC ; +.I \%texb.map +for +.BR TB , +.BR HR , +.BR HI , +.BR HB , +and +.BR HBI ; +.I \%texex.map +for +.BR EX ; +.I \%texi.map +for +.B TI +and +.BR TBI ; +.I \%texitt.map +for +.BR CWI ; +.I \%texmi.map +for +.BR MI ; +.I \%texr.map +for +.BR TR ; +.I \%texsy.map +for +.BR S ; +.I \%textex.map +for +.BR SC ; +and +.I \%textt.map +for +.BR CW . +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.MR groff @MAN1EXT@ , +.MR grodvi @MAN1EXT@ , +.MR groff_font @MAN5EXT@ +. +. +.\" Clean up. +.rm tx +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_tfmtodit_1_man_C] +.do rr *groff_tfmtodit_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/utils/tfmtodit/tfmtodit.am b/src/utils/tfmtodit/tfmtodit.am new file mode 100644 index 0000000..758fad5 --- /dev/null +++ b/src/utils/tfmtodit/tfmtodit.am @@ -0,0 +1,29 @@ +# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# +# This file 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 . + +bin_PROGRAMS += tfmtodit +man1_MANS += src/utils/tfmtodit/tfmtodit.1 +EXTRA_DIST += src/utils/tfmtodit/tfmtodit.1.man +tfmtodit_SOURCES = src/utils/tfmtodit/tfmtodit.cpp +tfmtodit_LDADD = libgroff.a $(LIBM) lib/libgnu.a + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/utils/tfmtodit/tfmtodit.cpp b/src/utils/tfmtodit/tfmtodit.cpp new file mode 100644 index 0000000..3003733 --- /dev/null +++ b/src/utils/tfmtodit/tfmtodit.cpp @@ -0,0 +1,889 @@ +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +/* I have tried to incorporate the changes needed for TeX 3.0 tfm files, +but I haven't tested them. */ + +/* Groff requires more font metric information than TeX. The reason +for this is that TeX has separate Math Italic fonts, whereas groff +uses normal italic fonts for math. The two additional pieces of +information required by groff correspond to the two arguments to the +math_fit() macro in the Metafont programs for the CM fonts. In the +case of a font for which math_fitting is false, these two arguments +are normally ignored by Metafont. We need to get hold of these two +parameters and put them in the groff font file. + +We do this by loading this definition after cmbase when creating +cm.base. + +def ignore_math_fit(expr left_adjustment,right_adjustment) = + special "adjustment"; + numspecial left_adjustment*16/designsize; + numspecial right_adjustment*16/designsize; + enddef; + +This puts the two arguments to the math_fit macro into the gf file. +(They will appear in the gf file immediately before the character to +which they apply.) We then create a gf file using this cm.base. Then +we run tfmtodit and specify this gf file with the -g option. + +This need only be done for a font for which math_fitting is false; +When it's true, the left_correction and subscript_correction should +both be zero. */ + +#include "lib.h" + +#include +#include +#include +#include + +#include "errarg.h" +#include "error.h" +#include "cset.h" +#include "nonposix.h" + +extern "C" const char *Version_string; + +/* Values in the tfm file should be multiplied by this. */ + +#define MULTIPLIER 1 + +struct char_info_word { + unsigned char width_index; + unsigned char height_index; + unsigned char depth_index; + unsigned char italic_index; + unsigned char tag; + unsigned char remainder; +}; + +struct lig_kern_command { + unsigned char skip_byte; + unsigned char next_char; + unsigned char op_byte; + unsigned char remainder; +}; + +class tfm { + int bc; + int ec; + int nw; + int nh; + int nd; + int ni; + int nl; + int nk; + int np; + int cs; + int ds; + char_info_word *char_info; + int *width; + int *height; + int *depth; + int *italic; + lig_kern_command *lig_kern; + int *kern; + int *param; +public: + tfm(); + ~tfm(); + int load(const char *); + int contains(int); + int get_width(int); + int get_height(int); + int get_depth(int); + int get_italic(int); + int get_param(int, int *); + int get_checksum(); + int get_design_size(); + int get_lig(unsigned char, unsigned char, unsigned char *); + friend class kern_iterator; +}; + +class kern_iterator { + tfm *t; + int c; + int i; +public: + kern_iterator(tfm *); + int next(unsigned char *c1, unsigned char *c2, int *k); +}; + + +kern_iterator::kern_iterator(tfm *p) +: t(p), c(t->bc), i(-1) +{ +} + +int kern_iterator::next(unsigned char *c1, unsigned char *c2, int *k) +{ + for (; c <= t->ec; c++) + if (t->char_info[c - t->bc].tag == 1) { + if (i < 0) { + i = t->char_info[c - t->bc].remainder; + if (t->lig_kern[i].skip_byte > 128) + i = (256*t->lig_kern[i].op_byte + + t->lig_kern[i].remainder); + } + for (;;) { + int skip = t->lig_kern[i].skip_byte; + if (skip <= 128 && t->lig_kern[i].op_byte >= 128) { + *c1 = c; + *c2 = t->lig_kern[i].next_char; + *k = t->kern[256*(t->lig_kern[i].op_byte - 128) + + t->lig_kern[i].remainder]; + if (skip == 128) { + c++; + i = -1; + } + else + i += skip + 1; + return 1; + } + if (skip >= 128) + break; + i += skip + 1; + } + i = -1; + } + return 0; +} + +tfm::tfm() +: char_info(0), width(0), height(0), depth(0), italic(0), lig_kern(0), + kern(0), param(0) +{ +} + +int tfm::get_lig(unsigned char c1, unsigned char c2, unsigned char *cp) +{ + if (contains(c1) && char_info[c1 - bc].tag == 1) { + int i = char_info[c1 - bc].remainder; + if (lig_kern[i].skip_byte > 128) + i = 256*lig_kern[i].op_byte + lig_kern[i].remainder; + for (;;) { + int skip = lig_kern[i].skip_byte; + if (skip > 128) + break; + // We are only interested in normal ligatures, for which + // op_byte == 0. + if (lig_kern[i].op_byte == 0 + && lig_kern[i].next_char == c2) { + *cp = lig_kern[i].remainder; + return 1; + } + if (skip == 128) + break; + i += skip + 1; + } + } + return 0; +} + +int tfm::contains(int i) +{ + return i >= bc && i <= ec && char_info[i - bc].width_index != 0; +} + +int tfm::get_width(int i) +{ + return width[char_info[i - bc].width_index]; +} + +int tfm::get_height(int i) +{ + return height[char_info[i - bc].height_index]; +} + +int tfm::get_depth(int i) +{ + return depth[char_info[i - bc].depth_index]; +} + +int tfm::get_italic(int i) +{ + return italic[char_info[i - bc].italic_index]; +} + +int tfm::get_param(int i, int *p) +{ + if (i <= 0 || i > np) + return 0; + else { + *p = param[i - 1]; + return 1; + } +} + +int tfm::get_checksum() +{ + return cs; +} + +int tfm::get_design_size() +{ + return ds; +} + +tfm::~tfm() +{ + delete[] char_info; + delete[] width; + delete[] height; + delete[] depth; + delete[] italic; + delete[] lig_kern; + delete[] kern; + delete[] param; +} + +int read2(unsigned char *&s) +{ + int n; + n = *s++ << 8; + n |= *s++; + return n; +} + +int read4(unsigned char *&s) +{ + int n; + n = *s++ << 24; + n |= *s++ << 16; + n |= *s++ << 8; + n |= *s++; + return n; +} + +int tfm::load(const char *file) +{ + errno = 0; + FILE *fp = fopen(file, FOPEN_RB); + if (!fp) { + error("can't open '%1': %2", file, strerror(errno)); + return 0; + } + int c1 = getc(fp); + int c2 = getc(fp); + if (c1 == EOF || c2 == EOF) { + fclose(fp); + error("unexpected end of file on '%1'", file); + return 0; + } + int lf = (c1 << 8) + c2; + int toread = lf*4 - 2; + unsigned char *buf = new unsigned char[toread]; + if (fread(buf, 1, toread, fp) != (size_t)toread) { + if (feof(fp)) + error("unexpected end of file on '%1'", file); + else + error("error on file '%1'", file); + delete[] buf; + fclose(fp); + return 0; + } + fclose(fp); + if (lf < 6) { + error("bad TFM file '%1': impossibly short", file); + delete[] buf; + return 0; + } + unsigned char *ptr = buf; + int lh = read2(ptr); + bc = read2(ptr); + ec = read2(ptr); + nw = read2(ptr); + nh = read2(ptr); + nd = read2(ptr); + ni = read2(ptr); + nl = read2(ptr); + nk = read2(ptr); + int ne = read2(ptr); + np = read2(ptr); + if ((6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np) + != lf) { + error("bad TFM file '%1': lengths do not sum", file); + delete[] buf; + return 0; + } + if (lh < 2) { + error("bad TFM file '%1': header too short", file); + delete[] buf; + return 0; + } + char_info = new char_info_word[ec - bc + 1]; + width = new int[nw]; + height = new int[nh]; + depth = new int[nd]; + italic = new int[ni]; + lig_kern = new lig_kern_command[nl]; + kern = new int[nk]; + param = new int[np]; + int i; + cs = read4(ptr); + ds = read4(ptr); + ptr += (lh-2)*4; + for (i = 0; i < ec - bc + 1; i++) { + char_info[i].width_index = *ptr++; + unsigned char tem = *ptr++; + char_info[i].depth_index = tem & 0xf; + char_info[i].height_index = tem >> 4; + tem = *ptr++; + char_info[i].italic_index = tem >> 2; + char_info[i].tag = tem & 3; + char_info[i].remainder = *ptr++; + } + for (i = 0; i < nw; i++) + width[i] = read4(ptr); + for (i = 0; i < nh; i++) + height[i] = read4(ptr); + for (i = 0; i < nd; i++) + depth[i] = read4(ptr); + for (i = 0; i < ni; i++) + italic[i] = read4(ptr); + for (i = 0; i < nl; i++) { + lig_kern[i].skip_byte = *ptr++; + lig_kern[i].next_char = *ptr++; + lig_kern[i].op_byte = *ptr++; + lig_kern[i].remainder = *ptr++; + } + for (i = 0; i < nk; i++) + kern[i] = read4(ptr); + ptr += ne*4; + for (i = 0; i < np; i++) + param[i] = read4(ptr); + assert(ptr == buf + lf*4 - 2); + delete[] buf; + return 1; +} + +class gf { + int left[256]; + int right[256]; + static int sread4(int *p, FILE *fp); + static int uread3(int *p, FILE *fp); + static int uread2(int *p, FILE *fp); + static int skip(int n, FILE *fp); +public: + gf(); + int load(const char *file); + int get_left_adjustment(int i) { return left[i]; } + int get_right_adjustment(int i) { return right[i]; } +}; + +gf::gf() +{ + for (int i = 0; i < 256; i++) + left[i] = right[i] = 0; +} + +int gf::load(const char *file) +{ + enum { + paint_0 = 0, + paint1 = 64, + boc = 67, + boc1 = 68, + eoc = 69, + skip0 = 70, + skip1 = 71, + new_row_0 = 74, + xxx1 = 239, + yyy = 243, + no_op = 244, + pre = 247, + post = 248 + }; + int got_an_adjustment = 0; + int pending_adjustment = 0; + int left_adj = 0, right_adj = 0; // pacify compiler + const int gf_id_byte = 131; + errno = 0; + FILE *fp = fopen(file, FOPEN_RB); + if (!fp) { + error("can't open '%1': %2", file, strerror(errno)); + return 0; + } + if (getc(fp) != pre || getc(fp) != gf_id_byte) { + error("bad gf file"); + return 0; + } + int n = getc(fp); + if (n == EOF) + goto eof; + if (!skip(n, fp)) + goto eof; + for (;;) { + int op = getc(fp); + if (op == EOF) + goto eof; + if (op == post) + break; + if ((op >= paint_0 && op <= paint_0 + 63) + || (op >= new_row_0 && op <= new_row_0 + 164)) + continue; + switch (op) { + case no_op: + case eoc: + case skip0: + break; + case paint1: + case skip1: + if (!skip(1, fp)) + goto eof; + break; + case paint1 + 1: + case skip1 + 1: + if (!skip(2, fp)) + goto eof; + break; + case paint1 + 2: + case skip1 + 2: + if (!skip(3, fp)) + goto eof; + break; + case boc: + { + int code; + if (!sread4(&code, fp)) + goto eof; + if (pending_adjustment) { + pending_adjustment = 0; + left[code & 0377] = left_adj; + right[code & 0377] = right_adj; + } + if (!skip(20, fp)) + goto eof; + break; + } + case boc1: + { + int code = getc(fp); + if (code == EOF) + goto eof; + if (pending_adjustment) { + pending_adjustment = 0; + left[code] = left_adj; + right[code] = right_adj; + } + if (!skip(4, fp)) + goto eof; + break; + } + case xxx1: + { + int len = getc(fp); + if (len == EOF) + goto eof; + char buf[256]; + if (fread(buf, 1, len, fp) != (size_t)len) + goto eof; + if (len == 10 /* strlen("adjustment") */ + && memcmp(buf, "adjustment", len) == 0) { + int c = getc(fp); + if (c != yyy) { + if (c != EOF) + ungetc(c, fp); + break; + } + if (!sread4(&left_adj, fp)) + goto eof; + c = getc(fp); + if (c != yyy) { + if (c != EOF) + ungetc(c, fp); + break; + } + if (!sread4(&right_adj, fp)) + goto eof; + got_an_adjustment = 1; + pending_adjustment = 1; + } + break; + } + case xxx1 + 1: + if (!uread2(&n, fp) || !skip(n, fp)) + goto eof; + break; + case xxx1 + 2: + if (!uread3(&n, fp) || !skip(n, fp)) + goto eof; + break; + case xxx1 + 3: + if (!sread4(&n, fp) || !skip(n, fp)) + goto eof; + break; + case yyy: + if (!skip(4, fp)) + goto eof; + break; + default: + fatal("unrecognized opcode '%1'", op); + break; + } + } + if (!got_an_adjustment) + warning("no adjustment specials found in gf file"); + return 1; + eof: + error("unexpected end of file"); + return 0; +} + +int gf::sread4(int *p, FILE *fp) +{ + *p = getc(fp); + if (*p >= 128) + *p -= 256; + *p <<= 8; + *p |= getc(fp); + *p <<= 8; + *p |= getc(fp); + *p <<= 8; + *p |= getc(fp); + return !ferror(fp) && !feof(fp); +} + +int gf::uread3(int *p, FILE *fp) +{ + *p = getc(fp); + *p <<= 8; + *p |= getc(fp); + *p <<= 8; + *p |= getc(fp); + return !ferror(fp) && !feof(fp); +} + +int gf::uread2(int *p, FILE *fp) +{ + *p = getc(fp); + *p <<= 8; + *p |= getc(fp); + return !ferror(fp) && !feof(fp); +} + +int gf::skip(int n, FILE *fp) +{ + while (--n >= 0) + if (getc(fp) == EOF) + return 0; + return 1; +} + + +struct char_list { + char *ch; + char_list *next; + char_list(const char *, char_list * = 0); +}; + +char_list::char_list(const char *s, char_list *p) : ch(strsave(s)), + next(p) +{ +} + + +int read_map(const char *file, char_list **table) +{ + errno = 0; + FILE *fp = fopen(file, "r"); + if (!fp) { + error("can't open '%1': %2", file, strerror(errno)); + return 0; + } + for (int i = 0; i < 256; i++) + table[i] = 0; + char buf[512]; + int lineno = 0; + while (fgets(buf, int(sizeof(buf)), fp)) { + lineno++; + char *ptr = buf; + while (csspace(*ptr)) + ptr++; + if (*ptr == '\0' || *ptr == '#') + continue; + ptr = strtok(ptr, " \n\t"); + if (!ptr) + continue; + int n; + if (sscanf(ptr, "%d", &n) != 1) { + error("%1:%2: bad map file", file, lineno); + fclose(fp); + return 0; + } + if (n < 0 || n > 255) { + error("%1:%2: code %3 out of range", file, lineno, n); + fclose(fp); + return 0; + } + ptr = strtok(0, " \n\t"); + if (!ptr) { + error("%1:%2: missing names", file, lineno); + fclose(fp); + return 0; + } + for (; ptr; ptr = strtok(0, " \n\t")) + table[n] = new char_list(ptr, table[n]); + } + fclose(fp); + return 1; +} + + +/* Every character that can participate in a ligature appears in the +lig_chars table. 'ch' gives the full-name of the character, 'name' +gives the groff name of the character, 'i' gives its index in +the encoding, which is filled in later (-1 if it does not appear). */ + +struct S { + const char *ch; + int i; +} lig_chars[] = { + { "f", -1 }, + { "i", -1 }, + { "l", -1 }, + { "ff", -1 }, + { "fi", -1 }, + { "fl", -1 }, + { "Fi", -1 }, + { "Fl", -1 }, +}; + +// Indices into lig_chars[]. + +enum { CH_f, CH_i, CH_l, CH_ff, CH_fi, CH_fl, CH_ffi, CH_ffl }; + +// Each possible ligature appears in this table. + +struct S2 { + unsigned char c1, c2, res; + const char *ch; +} lig_table[] = { + { CH_f, CH_f, CH_ff, "ff" }, + { CH_f, CH_i, CH_fi, "fi" }, + { CH_f, CH_l, CH_fl, "fl" }, + { CH_ff, CH_i, CH_ffi, "ffi" }, + { CH_ff, CH_l, CH_ffl, "ffl" }, + }; + +static void usage(FILE *stream); + +int main(int argc, char **argv) +{ + program_name = argv[0]; + int special_flag = 0; + int skewchar = -1; + int opt; + const char *gf_file = 0; + static const struct option long_options[] = { + { "help", no_argument, 0, CHAR_MAX + 1 }, + { "version", no_argument, 0, 'v' }, + { NULL, 0, 0, 0 } + }; + while ((opt = getopt_long(argc, argv, "svg:k:", long_options, NULL)) + != EOF) + switch (opt) { + case 'g': + gf_file = optarg; + break; + case 's': + special_flag = 1; + break; + case 'k': + { + char *ptr; + long n = strtol(optarg, &ptr, 0); + if ((n == 0 && ptr == optarg) + || *ptr != '\0' + || n < 0 + || n > UCHAR_MAX) + error("invalid skew character position '%1'", optarg); + else + skewchar = (int)n; + break; + } + case 'v': + { + printf("GNU tfmtodit (groff) version %s\n", Version_string); + exit(0); + break; + } + case CHAR_MAX + 1: // --help + usage(stdout); + exit(0); + break; + case '?': + usage(stderr); + exit(1); + break; + case EOF: + assert(0 == "EOF encountered in option processing"); + } + if (argc - optind != 3) { + error("insufficient arguments"); + usage(stderr); + exit(1); + } + gf g; + if (gf_file) { + if (!g.load(gf_file)) + return 1; + } + const char *tfm_file = argv[optind]; + const char *map_file = argv[optind + 1]; + const char *font_file = argv[optind + 2]; + tfm t; + if (!t.load(tfm_file)) + return 1; + char_list *table[256]; + if (!read_map(map_file, table)) + return 1; + errno = 0; + if (!freopen(font_file, "w", stdout)) { + error("can't open '%1' for writing: %2", font_file, + strerror(errno)); + return 1; + } + printf("name %s\n", font_file); + if (special_flag) + fputs("special\n", stdout); + char *internal_name = strsave(argv[optind]); + int len = strlen(internal_name); + if (len > 4 && strcmp(internal_name + len - 4, ".tfm") == 0) + internal_name[len - 4] = '\0'; + // DIR_SEPS[] are possible directory separator characters, see + // nonposix.h. We want the rightmost separator of all possible ones. + // Example: d:/foo\\bar. + const char *s = strrchr(internal_name, DIR_SEPS[0]), *s1; + const char *sep = &DIR_SEPS[1]; + while (*sep) + { + s1 = strrchr(internal_name, *sep); + if (s1 && (!s || s1 > s)) + s = s1; + sep++; + } + printf("internalname %s\n", s ? s + 1 : internal_name); + int n; + if (t.get_param(2, &n)) { + if (n > 0) + printf("spacewidth %d\n", n*MULTIPLIER); + } + if (t.get_param(1, &n) && n != 0) + printf("slant %f\n", atan2(n/double(1<<20), 1.0)*180.0/PI); + int xheight; + if (!t.get_param(5, &xheight)) + xheight = 0; + unsigned int i; + // Print the list of ligatures. + // First find the indices of each character that can participate in + // a ligature. + size_t lig_char_entries = sizeof(lig_chars)/sizeof(lig_chars[0]); + size_t lig_table_entries = sizeof(lig_table)/sizeof(lig_table[0]); + for (i = 0; i < 256; i++) + for (unsigned int j = 0; j < lig_char_entries; j++) + for (char_list *p = table[i]; p; p = p->next) + if (strcmp(lig_chars[j].ch, p->ch) == 0) + lig_chars[j].i = i; + // For each possible ligature, if its participants all exist, + // and it appears as a ligature in the tfm file, include in + // the list of ligatures. + int started = 0; + for (i = 0; i < lig_table_entries; i++) { + int i1 = lig_chars[lig_table[i].c1].i; + int i2 = lig_chars[lig_table[i].c2].i; + int r = lig_chars[lig_table[i].res].i; + if (i1 >= 0 && i2 >= 0 && r >= 0) { + unsigned char c; + if (t.get_lig(i1, i2, &c) && c == r) { + if (!started) { + started = 1; + fputs("ligatures", stdout); + } + printf(" %s", lig_table[i].ch); + } + } + } + if (started) + fputs(" 0\n", stdout); + printf("checksum %d\n", t.get_checksum()); + printf("designsize %d\n", t.get_design_size()); + // Now print out the kerning information. + int had_kern = 0; + kern_iterator iter(&t); + unsigned char c1, c2; + int k; + while (iter.next(&c1, &c2, &k)) + if (c2 != skewchar) { + k *= MULTIPLIER; + char_list *q = table[c2]; + for (char_list *p1 = table[c1]; p1; p1 = p1->next) + for (char_list *p2 = q; p2; p2 = p2->next) { + if (!had_kern) { + printf("kernpairs\n"); + had_kern = 1; + } + printf("%s %s %d\n", p1->ch, p2->ch, k); + } + } + printf("charset\n"); + char_list unnamed("---"); + for (i = 0; i < 256; i++) + if (t.contains(i)) { + char_list *p = table[i] ? table[i] : &unnamed; + int m[6]; + m[0] = t.get_width(i); + m[1] = t.get_height(i); + m[2] = t.get_depth(i); + m[3] = t.get_italic(i); + m[4] = g.get_left_adjustment(i); + m[5] = g.get_right_adjustment(i); + printf("%s\t%d", p->ch, m[0]*MULTIPLIER); + int j; + for (j = int(sizeof(m)/sizeof(m[0])) - 1; j > 0; j--) + if (m[j] != 0) + break; + for (k = 1; k <= j; k++) + printf(",%d", m[k]*MULTIPLIER); + int type = 0; + if (m[2] > 0) + type = 1; + if (m[1] > xheight) + type += 2; + printf("\t%d\t%04o\n", type, i); + for (p = p->next; p; p = p->next) + printf("%s\t\"\n", p->ch); + } + return 0; +} + +static void usage(FILE *stream) +{ + fprintf(stream, +"usage: %s [-s] [-g gf-file] [-k skew-char] tfm-file map-file font\n" +"usage: %s {-v | --version}\n" +"usage: %s --help\n", + program_name, program_name, program_name); +} + +// Local Variables: +// fill-column: 72 +// mode: C++ +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/src/utils/xtotroff/xtotroff.1.man b/src/utils/xtotroff/xtotroff.1.man new file mode 100644 index 0000000..17fb0db --- /dev/null +++ b/src/utils/xtotroff/xtotroff.1.man @@ -0,0 +1,237 @@ +.TH xtotroff @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +xtotroff \- convert X font metrics into +.I groff +font metrics +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 2004-2022 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_xtotroff_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY xtotroff +.RB [ \-d\~\c +.IR destination-directory ] +.RB [ \-r\~\c +.IR resolution ] +.RB [ \-s\~\c +.IR type-size ] +.I font-map +.YS +. +. +.SY xtotroff +.B \-\-help +.YS +. +. +.SY xtotroff +.B \-v +. +.SY xtotroff +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I xtotroff +uses +.I font-map +to create +.MR groff @MAN1EXT@ +font description files from X11 fonts. +. +Each line in +.I font-map +consists of a series of lines of paired +.I groff +font names and X font names as X Logical Font Description (XLFD) +patterns, +with the pair members separated by spaces and/or tabs. +. +For example, +an input +.I font-map +file consisting of the line +. +.RS +.EX +TB \-adobe\-times\-bold\-r\-normal\-\-*\-*\-*\-*\-p\-*\-iso8859\-1 +.EE +.RE +. +maps the XLFD on the right to the +.I groff +font name +.BR TB , +conventionally \[lq]Times bold\[rq]. +. +. +.PP +.I xtotroff +opens a connection to the running X server to query its font catalog, +and aborts if it cannot. +. +If necessary, +the wildcards in the XLFD patterns are populated with the arguments to +the +.B \-r +and +.B \-s +options. +. +If a font name is still ambiguous, +.I xtotroff +aborts. +. +For each successful mapping, +.I xtotroff +creates a +.I groff +font description file in the current working directory +(or that specified by the +.B -d +option) +named for each +.I groff +font, +and reports the mapping to the standard output stream. +. +. +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-\-help +displays a usage message, +while +.B \-v +and +.B \-\-version +show version information; +all exit afterward. +. +. +.TP +.BI \-d\~ destination-directory +Write font descriptions to +.I destination-directory +rather than the current working directory. +. +. +.TP +.BI \-r\~ resolution +Set the resolution for all font patterns in +.IR font-map . +. +The value is used for both the horizontal and vertical motion quanta. +. +If not specified, +a resolution of 75dpi is assumed. +. +. +.TP +.BI \-s\~ type-size +Set the type size in points for all font patterns in +.IR font-map . +. +If not specified, +a size of 10 points is assumed. +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.I @FONTDIR@/\:\%FontMap\-X11 +is the font mapping file used to produce the pre-generated font +description files, +supplied with +.IR groff , +of X11 core fonts corresponding to the 13 base Type\~1 fonts for +PostScript level 1. +. +. +.\" ==================================================================== +.SH Bugs +.\" ==================================================================== +. +The only supported font encodings are \[lq]iso8859\-1\[rq] and +\%\[lq]adobe\-\:fontspecific\[rq]. +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.UR https://\:www\:.x\:.org/\:releases/\:X11R7.6/\:doc/\:xorg\-docs/\ +\:specs/\:XLFD/xlfd\:.html +\[lq]X Logical Font Description Conventions\[rq] +.UE , +by Jim Flowers and Stephen Gildea. +. +. +.PP +.MR X 7 , +.MR groff @MAN1EXT@ , +.MR gxditview @MAN1EXT@ , +.MR troff @MAN1EXT@ , +.MR groff_font @MAN5EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_xtotroff_1_man_C] +.do rr *groff_xtotroff_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/utils/xtotroff/xtotroff.am b/src/utils/xtotroff/xtotroff.am new file mode 100644 index 0000000..734d143 --- /dev/null +++ b/src/utils/xtotroff/xtotroff.am @@ -0,0 +1,41 @@ +# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# +# This file 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 . + +if WITHOUT_X11 +XTOTROFF_MAN1 = +else +XTOTROFF_MAN1 = src/utils/xtotroff/xtotroff.1 +bin_PROGRAMS += xtotroff +man1_MANS += $(XTOTROFF_MAN1) +xtotroff_SOURCES = src/utils/xtotroff/xtotroff.c +XLIBS=$(LIBXUTIL) $(LIBGROFF) +xtotroff_LDADD = libxutil.a libgroff.a $(X_LIBS) $(X_PRE_LIBS) \ + -lXaw -lXt -lX11 $(X_EXTRA_LIBS) $(LIBM) lib/libgnu.a +xtotroff_CPPFLAGS = $(AM_CPPFLAGS) $(X_CFLAGS) +endif +EXTRA_DIST += src/utils/xtotroff/xtotroff.1.man + +# Define variable needed only for the targets that regenerate +# descriptions of X11 core fonts (used in "maintainer mode"). +xtotroff=$(top_builddir)/xtotroff + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/utils/xtotroff/xtotroff.c b/src/utils/xtotroff/xtotroff.c new file mode 100644 index 0000000..368761f --- /dev/null +++ b/src/utils/xtotroff/xtotroff.c @@ -0,0 +1,368 @@ +/* Copyright (C) 1992-2022 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file 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 . */ + +/* + * xtotroff + * + * convert X font metrics into troff font metrics + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define __GETOPT_PREFIX groff_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "XFontName.h" +#include "DviChar.h" + +#define charWidth(fi,c) \ + ((fi)->per_char[(c) - (fi)->min_char_or_byte2].width) +#define charHeight(fi,c) \ + ((fi)->per_char[(c) - (fi)->min_char_or_byte2].ascent) +#define charDepth(fi,c) \ + ((fi)->per_char[(c) - (fi)->min_char_or_byte2].descent) +#define charLBearing(fi,c) \ + ((fi)->per_char[(c) - (fi)->min_char_or_byte2].lbearing) +#define charRBearing(fi,c) \ + ((fi)->per_char[(c) - (fi)->min_char_or_byte2].rbearing) + +extern const char *Version_string; +static char *program_name; + +Display *dpy; +unsigned resolution = 75; +unsigned point_size = 10; +char *destdir = NULL; + +static bool charExists(XFontStruct * fi, int c) +{ + XCharStruct *p; + + /* 'c' is always >= 0 */ + if ((unsigned int) c < fi->min_char_or_byte2 + || (unsigned int) c > fi->max_char_or_byte2) + return false; + p = fi->per_char + (c - fi->min_char_or_byte2); + return p->lbearing != 0 || p->rbearing != 0 || p->width != 0 + || p->ascent != 0 || p->descent != 0 || p->attributes != 0; +} + +/* Canonicalize the font name by replacing scalable parts by *s. */ + +static bool CanonicalizeFontName(char *font_name, char *canon_font_name) +{ + unsigned int attributes; + XFontName parsed; + + if (!XParseFontName(font_name, &parsed, &attributes)) { + fprintf(stderr, "%s: not a standard font name: \"%s\"\n", + program_name, font_name); + return false; + } + + attributes &= ~(FontNamePixelSize | FontNameAverageWidth + | FontNamePointSize + | FontNameResolutionX | FontNameResolutionY); + XFormatFontName(&parsed, attributes, canon_font_name); + return true; +} + +static bool +FontNamesAmbiguous(const char *font_name, char **names, int count) +{ + char name1[2048], name2[2048]; + int i; + + if (1 == count) + return false; + + for (i = 0; i < count; i++) { + if (!CanonicalizeFontName(names[i], 0 == i ? name1 : name2)) { + fprintf(stderr, "%s: invalid font name: \"%s\"\n", program_name, + names[i]); + return true; + } + if (i > 0 && strcmp(name1, name2) != 0) { + fprintf(stderr, "%s: ambiguous font name: \"%s\"", program_name, + font_name); + fprintf(stderr, " matches \"%s\"", names[0]); + fprintf(stderr, " and \"%s\"", names[i]); + return true; + } + } + return false; +} + +static void xtotroff_exit(int status) +{ + free(destdir); + exit(status); +} + +static bool MapFont(char *font_name, const char *troff_name) +{ + XFontStruct *fi; + int count; + char **names; + FILE *out; + unsigned int c; + unsigned int attributes; + XFontName parsed; + int j, k; + DviCharNameMap *char_map; + /* 'encoding' needs to hold a CharSetRegistry (256), a CharSetEncoding + (256) [both from XFontName.h], a dash, and a null terminator. */ + char encoding[256 * 2 + 1 + 1]; + char *s; + int wid; + char name_string[2048]; + + if (!XParseFontName(font_name, &parsed, &attributes)) { + fprintf(stderr, "%s: not a standard font name: \"%s\"\n", + program_name, font_name); + return false; + } + + attributes &= ~(FontNamePixelSize | FontNameAverageWidth); + attributes |= FontNameResolutionX; + attributes |= FontNameResolutionY; + attributes |= FontNamePointSize; + parsed.ResolutionX = resolution; + parsed.ResolutionY = resolution; + parsed.PointSize = point_size * 10; + XFormatFontName(&parsed, attributes, name_string); + + names = XListFonts(dpy, name_string, 100000, &count); + if (count < 1) { + fprintf(stderr, "%s: invalid font name: \"%s\"\n", program_name, + font_name); + return false; + } + + if (FontNamesAmbiguous(font_name, names, count)) + return false; + + XParseFontName(names[0], &parsed, &attributes); + size_t sz = sizeof encoding; + snprintf(encoding, sz, "%s-%s", parsed.CharSetRegistry, + parsed.CharSetEncoding); + for (s = encoding; *s; s++) + if (isupper(*s)) + *s = tolower(*s); + char_map = DviFindMap(encoding); + if (!char_map) { + fprintf(stderr, "%s: not a standard encoding: \"%s\"\n", + program_name, encoding); + return false; + } + + fi = XLoadQueryFont(dpy, names[0]); + if (!fi) { + fprintf(stderr, "%s: font does not exist: \"%s\"\n", program_name, + names[0]); + return false; + } + + printf("%s -> %s\n", names[0], troff_name); + char *file_name = (char *)troff_name; + size_t dirlen = strlen(destdir); + + if (dirlen > 0) { + size_t baselen = strlen(troff_name); + file_name = malloc(dirlen + baselen + 2 /* '/' and '\0' */); + if (NULL == file_name) { + fprintf(stderr, "%s: fatal error: unable to allocate memory\n", + program_name); + xtotroff_exit(EXIT_FAILURE); + } + (void) strcpy(file_name, destdir); + file_name[dirlen] = '/'; + (void) strcpy((file_name + dirlen + 1), troff_name); + } + + { /* Avoid race while opening file */ + int fd; + (void) unlink(file_name); + fd = open(file_name, O_WRONLY | O_CREAT | O_EXCL, 0600); + out = fdopen(fd, "w"); + } + + if (NULL == out) { + fprintf(stderr, "%s: unable to create '%s': %s\n", program_name, + file_name, strerror(errno)); + free(file_name); + return false; + } + fprintf(out, "name %s\n", troff_name); + if (!strcmp(char_map->encoding, "adobe-fontspecific")) + fprintf(out, "special\n"); + if (charExists(fi, ' ')) { + int w = charWidth(fi, ' '); + if (w > 0) + fprintf(out, "spacewidth %d\n", w); + } + fprintf(out, "charset\n"); + for (c = fi->min_char_or_byte2; c <= fi->max_char_or_byte2; c++) { + const char *name = DviCharName(char_map, c, 0); + if (charExists(fi, c)) { + int param[5]; + + wid = charWidth(fi, c); + + fprintf(out, "%s\t%d", name ? name : "---", wid); + param[0] = charHeight(fi, c); + param[1] = charDepth(fi, c); + param[2] = 0; /* charRBearing (fi, c) - wid */ + param[3] = 0; /* charLBearing (fi, c) */ + param[4] = 0; /* XXX */ + for (j = 0; j < 5; j++) + if (param[j] < 0) + param[j] = 0; + for (j = 4; j >= 0; j--) + if (param[j] != 0) + break; + for (k = 0; k <= j; k++) + fprintf(out, ",%d", param[k]); + fprintf(out, "\t0\t0%o\n", c); + + if (name) { + for (k = 1; DviCharName(char_map, c, k); k++) { + fprintf(out, "%s\t\"\n", DviCharName(char_map, c, k)); + } + } + } + } + XUnloadFont(dpy, fi->fid); + fclose(out); + free(file_name); + return true; +} + +static void usage(FILE *stream) +{ + fprintf(stream, + "usage: %s [-d destination-directory] [-r resolution]" + " [-s type-size] font-map\n" + "usage: %s {-v | --version}\n" + "usage: %s --help\n", + program_name, program_name, program_name); +} + +int main(int argc, char **argv) +{ + char troff_name[1024]; + char font_name[1024]; + char line[1024]; + char *a, *b, c; + FILE *map; + int opt; + static const struct option long_options[] = { + { "help", no_argument, 0, CHAR_MAX + 1 }, + { "version", no_argument, 0, 'v' }, + { NULL, 0, 0, 0 } + }; + + program_name = argv[0]; + + while ((opt = getopt_long(argc, argv, "d:gr:s:v", long_options, + NULL)) != EOF) { + switch (opt) { + case 'd': + destdir = strdup(optarg); + break; + case 'g': + /* unused; just for compatibility */ + break; + case 'r': + sscanf(optarg, "%u", &resolution); + break; + case 's': + sscanf(optarg, "%u", &point_size); + break; + case 'v': + printf("GNU xtotroff (groff) version %s\n", Version_string); + xtotroff_exit(EXIT_SUCCESS); + break; + case CHAR_MAX + 1: /* --help */ + usage(stdout); + xtotroff_exit(EXIT_SUCCESS); + break; + case '?': + usage(stderr); + xtotroff_exit(EXIT_FAILURE); + break; + } + } + if (argc - optind != 1) { + usage(stderr); + xtotroff_exit(EXIT_FAILURE); + } + + dpy = XOpenDisplay(0); + if (!dpy) { + fprintf(stderr, "%s: fatal error: can't connect to the X server;" + " make sure the DISPLAY environment variable is set" + " correctly\n", program_name); + xtotroff_exit(EXIT_FAILURE); + } + + map = fopen(argv[optind], "r"); + if (NULL == map) { + fprintf(stderr, "%s: fatal error: unable to open map file '%s':" + " %s\n", program_name, argv[optind], strerror(errno)); + xtotroff_exit(EXIT_FAILURE); + } + + while (fgets(line, sizeof(line), map)) { + for (a = line, b = troff_name; *a; a++, b++) { + c = (*b = *a); + if (' ' == c || '\t' == c) + break; + } + *b = '\0'; + while (*a && (' ' == *a || '\t' == *a)) + ++a; + for (b = font_name; *a; a++, b++) + if ((*b = *a) == '\n') + break; + *b = '\0'; + if (!MapFont(font_name, troff_name)) + xtotroff_exit(EXIT_FAILURE); + } + xtotroff_exit(EXIT_SUCCESS); +} + +// Local Variables: +// fill-column: 72 +// mode: C +// End: +// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: diff --git a/test-groff.in b/test-groff.in new file mode 100644 index 0000000..ff61767 --- /dev/null +++ b/test-groff.in @@ -0,0 +1,54 @@ +#! /bin/sh +# +# Copyright (C) 1989-2020 Free Software Foundation, Inc. +# +# This file 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 . +# +# This script runs groff without requiring that it be installed. + +SEP='@PATH_SEPARATOR@' +builddir=@abs_top_builddir@ +srcdir=@abs_top_srcdir@ + +GROFF_BIN_PATH=$builddir + +XENVIRONMENT=$srcdir/src/devices/xditview/GXditview.ad +export XENVIRONMENT + +GROFF_COMMAND_PREFIX= +GROFF_FONT_PATH=$builddir/font\ +$SEP$srcdir/font\ + +GROFF_TMAC_PATH=$srcdir/tmac\ +$SEP$builddir/tmac\ +$SEP$srcdir/contrib/mom\ +$SEP$builddir/contrib/mom\ +$SEP$srcdir/contrib/hdtbl\ +$SEP$builddir/contrib/hdtbl\ +$SEP$srcdir/contrib/mm\ +$SEP$builddir/contrib/mm\ +$SEP$srcdir/contrib/mm/locale\ +$SEP$builddir/contrib/mm/locale\ +$SEP$srcdir/contrib/pdfmark\ +$SEP$builddir/contrib/pdfmark\ +$SEP$srcdir/contrib/rfc1345\ +$SEP$builddir/contrib/rfc1345\ +$SEP$srcdir/contrib/sboxes\ +$SEP$builddir/contrib/sboxes\ + +export GROFF_BIN_PATH GROFF_COMMAND_PREFIX GROFF_FONT_PATH GROFF_TMAC_PATH + +exec $builddir/groff ${1+"$@"} diff --git a/tmac/62bit.tmac b/tmac/62bit.tmac new file mode 100644 index 0000000..f1a593e --- /dev/null +++ b/tmac/62bit.tmac @@ -0,0 +1,203 @@ +.\" 62bit.tmac +.\" +.\" Copyright (C) 2003-2020 Free Software Foundation, Inc. +.\" Written by Werner Lemberg (wl@gnu.org) +.\" +.\" This file 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 +.\" . +.\" +.\" +.\" This file provides macros for addition, multiplication, and division +.\" of 62-bit signed integers. Its main application is to 'scale' +.\" 31-bit values--namely, to perform the operation 'a * b / c' +.\" accurately. +.\" +.\" Note that it is the duty of the user to check whether the input +.\" values fit within 31 bits (this is the range +.\" [-1073741824,1073741823]). +.\" +. +.do nr *groff_62bit_tmac_C \n[.cp] +.cp 0 +. +.if d add31to62 \ +. nx +. +. +.\" .add31to62 +.\" +.\" Add a 31-bit signed integer to a signed 62-bit integer. Result is a +.\" signed 62-bit integer: +.\" +.\" + (h * 2^30 + l) = h * 2^30 + l +.\" +.\" +.\" in: \n[], \n[h], \n[l] +.\" +.\" out: \n[h], \n[l] +.\" +.\" Example: .add31to62 p q r +.\" +.\" -> input registers: \n[p], \n[qh], \n[ql] +.\" output registers: \n[rh], \n[rl] +.\" +.de1 add31to62 +. nr 62bit-lo2 (\\n[\\$2l]) +. nr 62bit-hi2 (\\n[\\$2h]) +. +. nr 62bit-i ((\\n[\\$1] + \\n[62bit-lo2]) / 1073741824) +. nr \\$3l ((\\n[\\$1] + \\n[62bit-lo2]) % 1073741824) +. +. ie ((\\n[62bit-lo2] > 0) & (\\n[\\$3l] < 0)) \{\ +. nr \\$3l +1073741824 +. nr 62bit-i -1 +. \} +. el \ +. if ((\\n[62bit-lo2] < 0) & (\\n[\\$3l] > 0)) \{\ +. nr \\$3l -1073741824 +. nr 62bit-i +1 +. \} +. +. nr \\$3h (\\n[62bit-hi2] + \\n[62bit-i]) +.. +. +. +.\" .mult31by31 +.\" +.\" Multiply two 31-bit signed integers. Result is a 62-bit signed +.\" integer: +.\" +.\" * = h * 2^30 + l +.\" +.\" +.\" in: \n[], \n[] +.\" +.\" out: \n[h], \n[l] +.\" +.\" Example: .mult31by31 a b c +.\" +.\" -> input registers: \n[a], \n[b] +.\" output registers: \n[ch], \n[cl] +.\" +.de1 mult31by31 +. nr 62bit-1 (\\n[\\$1]) +. nr 62bit-2 (\\n[\\$2]) +. +. nr 62bit-sign 1 +. if !\\n[62bit-1] \{\ +. nr 62bit-sign -(\\n[62bit-sign]) +. nr 62bit-1 -(\\n[62bit-1]) +. \} +. if !\\n[62bit-2] \{\ +. nr 62bit-sign -(\\n[62bit-sign]) +. nr 62bit-2 -(\\n[62bit-2]) +. \} +. +. nr 62bit-lo1 (\\n[62bit-1] % 32768) +. nr 62bit-hi1 (\\n[62bit-1] / 32768) +. nr 62bit-lo2 (\\n[62bit-2] % 32768) +. nr 62bit-hi2 (\\n[62bit-2] / 32768) +. +. nr 62bit-lo3 (\\n[62bit-lo1] * \\n[62bit-lo2] % 1073741824) +. nr 62bit-i1 (\\n[62bit-lo1] * \\n[62bit-hi2] % 1073741824) +. nr 62bit-i2 (\\n[62bit-lo2] * \\n[62bit-hi1] % 1073741824) +. nr 62bit-hi3 (\\n[62bit-hi1] * \\n[62bit-hi2] % 1073741824) +. +. nr 62bit-i1 (\\n[62bit-i1] + \\n[62bit-i2] % 1073741824) +. \" check carry overflow of 62bit-i1 + 62bit-i2 +. if (\\n[62bit-i1] < \\n[62bit-i2]) \ +. nr 62bit-hi3 +32768 +. +. nr 62bit-hi3 +(\\n[62bit-i1] / 32768) +. \" multiply by 32768 in small steps to avoid overflow +. nr 62bit-i 16 1 +. while \\n-[62bit-i] \ +. nr 62bit-i1 (\\n[62bit-i1] * 2 % 1073741824) +. +. nr 62bit-lo3 (\\n[62bit-lo3] + \\n[62bit-i1] % 1073741824) +. \" check carry overflow of 62bit-i1 + lo +. if (\\n[62bit-lo3] < \\n[62bit-i1]) \ +. nr 62bit-hi3 +1 +. +. if !\\n[62bit-sign] \{\ +. nr 62bit-lo3 -(\\n[62bit-lo3]) +. nr 62bit-hi3 -(\\n[62bit-hi3]) +. \} +. nr \\$3l \\n[62bit-lo3] +. nr \\$3h \\n[62bit-hi3] +.. +. +. +.\" .div62by31 +.\" +.\" Divide a signed 62-bit integer by a 31-bit integer. Result is a +.\" 31-bit signed integer: +.\" +.\" (h * 2^30 + l) / = +.\" +.\" +.\" in: \n[h], \n[l], \n[] +.\" +.\" out: \n[] +.\" +.\" Example: .div62by31 foo bar baz +.\" +.\" -> input registers: \n[fooh] \n[fool] \n[bar] +.\" output register: \n[baz] +.\" +.de1 div62by31 +. nr 62bit-lo1 \\n[\\$1l] +. nr 62bit-hi1 \\n[\\$1h] +. nr 62bit-2 \\n[\\$2] +. nr 62bit-3 0 +. +. nr 62bit-sign 1 +. if ((\\n[62bit-lo1] < 0) : (\\n[62bit-hi1] < 0)) \{\ +. nr 62bit-sign -(\\n[62bit-sign]) +. nr 62bit-lo1 -(\\n[62bit-lo1]) +. nr 62bit-hi1 -(\\n[62bit-hi1]) +. \} +. if !\\n[62bit-2] \{\ +. nr 62bit-sign -(\\n[62bit-sign]) +. nr 62bit-2 -(\\n[62bit-2]) +. \} +. +. nr 62bit-i 31 1 +. while \\n-[62bit-i] \{\ +. nr 62bit-hi1 (\\n[62bit-hi1] * 2 % 1073741824) +. nr 62bit-3 (\\n[62bit-3] * 2) +. nr 62bit-hi1 +(\\n[62bit-lo1] / 536870912) +. +. if (\\n[62bit-hi1] >= \\n[62bit-2]) \{\ +. nr 62bit-hi1 -\\n[62bit-2] +. nr 62bit-3 +1 +. \} +. nr 62bit-lo1 (\\n[62bit-lo1] * 2 % 1073741824) +. \} +. +. if !\\n[62bit-sign] \ +. nr 62bit-3 -(\\n[62bit-3]) +. nr \\$3 \\n[62bit-3] +.. +. +.cp \n[*groff_62bit_tmac_C] +.do rr *groff_62bit_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/LOCALIZATION b/tmac/LOCALIZATION new file mode 100644 index 0000000..b322a43 --- /dev/null +++ b/tmac/LOCALIZATION @@ -0,0 +1,60 @@ +Localization +------------ + +The localization process involves two groff files and zero or more +hyphenation pattern files. + +1. A locale-dependent file (for example, fr.tmac for French) does one + or several of the following. + + A. A string identifying the groff locale (e.g., "english") is set. + B. Locale-specific strings used by macro packages are (re)defined. + C. Other tweaks to macro package configuration are performed, such + as altering the ordering of the components of a date string. + D. Additional inter-sentence space is set to a language-appropriate + amount with the .ss request. + E. A hyphenation mode appropriate to the hyphenation pattern files + for the locale is set with the .hy request. Here's a mapping + from TeX hyphenation pattern minimums to groff hyphenation + modes. + \lefthyphenmin=2, \righthyphenmin=2 => 1 + \lefthyphenmin=2, \righthyphenmin=3 => 4 + \lefthyphenmin=1, \righthyphenmin=2 => 32 + F. Hyphenation codes appropriate to the hyphenation pattern files + for the locale are set with the .hcode request. + G. The hyphenation language is set with the .hla request. + H. Support for the character encoding used by the hyphenation + pattern files is loaded with the .mso request. + I. Hyphenation pattern and exception files are loaded with the .hpf + and .hpfa requests. + +2. A locale-independent file (trans.tmac) activates the localized + strings set up in item B above. + +See the groff Texinfo manual in doc/groff.texi for descriptions of the +requests referred to above. + +Localization files are named using ISO 639-1 language identifiers. +Further specialization of locales by ISO 3166 territory codes is +tentatively planned as of groff 1.23.0, awaiting expressions of demand. + +After 'trans.tmac' has been loaded, you must redefine the date strings +in order to use the day and month names translated earlier. The date +format also may need to be changed. + +- If the locale's date format is MM/DD/YYYY, use the following. + + for ms: .ds DY \*[MO] \n[dy] \n[year]\" + for mm: .ds cov*new-date \\*[MO\\n[mo]] \\n[dy] \\n[year]\" + for me: .ds td \*(mo \n(dy \n(y4\" + +- If the locale's date format is DD/MM/YYYY, use the following. + + for ms: .ds DY \n[dy] \*[MO] \n[year]\" + for mm: .ds cov*new-date \\n[dy] \\*[MO\\n[mo]] \\n[year]\" + for me: .ds td \n(dy \*(mo \n(y4\" + +Other date formats can be handled similarly. + +Note: For the mm package, in the 'ISODATE' macro, only the first +definition of 'cov*new-date' must be changed (see 'fr.tmac'). diff --git a/tmac/TESTING-HINTS b/tmac/TESTING-HINTS new file mode 100644 index 0000000..6e21564 --- /dev/null +++ b/tmac/TESTING-HINTS @@ -0,0 +1,19 @@ +Here are some hints about testing modifications to macro packages and +manual pages. + +1. Use groff's '-ww' option to catch potential problems. + Ideally, there shouldn't be any warnings. + +2. For a well-formedness check, run doclifter (http://catb.org/~esr/doclifter) + against your page. This tool was written to lift pages to XML, but as a + side effect it acts as a validator that will warn you of potential problems + and non-portable constructs. + +3. The two most important groff client types are X terminal emulators + and Postscript printers. Eyeball-check your output under both. + +4. The colorized man output of the Midnight Commander (what you get by + pressing the F3 key on a man page) is good for making small errors + more visible. + +5. Try different terminal line lengths, say, 80 and 100 characters. diff --git a/tmac/TODO b/tmac/TODO new file mode 100644 index 0000000..89da313 --- /dev/null +++ b/tmac/TODO @@ -0,0 +1,36 @@ +Support multiple line-spacing. + +If we have footnotes in the abstract in RP format, then the footnote +will appear on the cover sheet, which it should, but also on the first +page, which it should not. + +Should we allow multi-page cover-sheets? + +Warn about automatically numbered footnotes in floating keeps. + +When we bring back the footnote overflow at the top of page, it would +be more efficient to avoid diverting it again. (Need to keep track of +footnote height.) + +Possibly have a place above which the footnote trap must not be +placed. + +Improved indexing, not using tm, controlled by string variable (e.g., +-dIDX=file.idx). + +When changing from multi-column to narrower columns, we could avoid +doing a @super-eject. (This might not be a good idea.) + +Think about cutmarks. Possibly implement CM. + +Implement thesis Mode (TM, CT). + +Implement more V10 features. + +Should this + +.LP +.rs +.sp \n(.tu + +print two pages? diff --git a/tmac/X.tmac b/tmac/X.tmac new file mode 100644 index 0000000..31fb20c --- /dev/null +++ b/tmac/X.tmac @@ -0,0 +1,136 @@ +.\" X.tmac +.\" +.do nr *groff_X_tmac_C \n[.cp] +.cp 0 +.ftr CW CR +.ftr C CR +.ftr CO CI +.ftr CX CBI +.ftr H HR +.ftr HO HI +.ftr HX HBI +.ftr NX NBI +.char \[ru] \D'l .5m 0' +.char \[ul] \v'.25m'\D'l .5m 0'\v'-.25m' +.char \[br] \v'.25m'\D'l 0 -1m'\v'.75m' +.char \[rn] \v'-.75m'\D'l .5m 0'\v'.75m' +.char \[or] \h'.1m'\Z'\D'l 0 -.675m''\h'.1m' +.char ~ \v'-.55m'\s[\En(.s/2u]\v'.2m'\[ti]\v'-.2m'\s0\v'.55m' +.char ^ \v'-.55m'\s[\En(.s/2u]\v'.3m'\[ha]\v'-.3m'\s0\v'.55m' +.fchar \[va] \o'\[ua]\[da]' +.fchar \[em] \v'-.25m'\h'.05m'\D'l .9m 0'\h'0.05m'\v'.25m' +.fchar \[en] \- +.fchar \[fi] fi +.fchar \[fl] fl +.fchar \[ff] ff +.fchar \[Fi] f\[fi] +.fchar \[Fl] f\[fl] +.fchar \[ci] \v'-.25m'\h'.05m'\D'c .5m'\h'.05m'\v'.25m' +.fchar \[sq] \h'.05m'\D'l .5m 0'\D'l 0 -.5m'\D'l -.5m 0'\D'l 0 .5m'\h'.55m' +.fchar \[ga] \Z'\v'-.7m'\D'l .22m .18m''\h'.33m' +.fchar \[dg] \Z'\h'.25m'\v'.15m'\D'l 0 -.8m'\v'.2m'\h'-.195m'\ +\D'l .39m 0''\h'.5m' +.fchar \[dd] \Z'\h'.25m'\v'.15m'\D'l 0 -.8m'\v'.2m'\h'-.195m'\ +\D'l .39m 0'\v'.4m'\D'l -.39m 0''\h'.5m' +.fchar \[lq] \[dq] +.fchar \[rq] \[dq] +.fchar \[Bq] ,, +.fchar \[OE] O\h'-.25m'E +.fchar \[oe] o\h'-.14m'e +.fchar \[ah] \v'-.55m'\s[\En[.s]/2u]v\s0\v'.55m' +.fchar \[ao] \v'-.55m'\s[\En[.s]*6u/10u]\D'c .25m'\s0\v'.55m' +.fchar \[ho] \s[\En[.s]/2u]\v'.4m'c\v'-.4m'\s0 +.fchar \[lh] \[lA] +.fchar \[rh] \[rA] +.fchar \[bq] , +.fchar \[IJ] IJ +.fchar \[ij] ij +.fchar \[fo] < +.fchar \[fc] > +.fchar \[OK] \s[\En[.s]*6u/10u]\[rs]\s[0]/ +. +.fchar \[<<] <\h'-.3m'< +.fchar \[>>] >\h'-.3m'> +.fchar \[|=] \v'.1m'\Z'\[mi]'\v'-.2m'\[ap]\v'.1m' +.fchar \[nc] \v'.1m'\Z'\h'.2m'\F[T]\f[R]/'\v'-.1m'\[sp] +.fchar \[ne] \v'.07m'\Z'\h'.2m'\F[T]\f[R]/'\v'-.07m'\[==] +.fchar \[-h] \F[T]\f[I]\v'-.58m'\Z'\h'.1m'\D'l .3m 0''\v'.58m'h +.fchar \[hbar] \[-h] +. +.de X-achar +. \" Note that character definitions are always interpreted with +. \" compatibility mode off. +. fchar \\$1 \ +\\$3\ +\k[acc]\ +\h'(u;-\w'\\$2'-\w'\\$3'/2+\\En[skw]+(\w'x'*0)-\\En[skw])'\ +\v'(u;\w'x'*0+\\En[rst]+(\w'\\$3'*0)-\\En[rst])'\ +\\$2\ +\v'(u;\w'x'*0-\\En[rst]+(\w'\\$3'*0)+\\En[rst])'\ +\h'|\\En[acc]u' +. hcode \\$1\\$4 +.. +. +.X-achar \['C] \' C c +.X-achar \['c] \' c c +.X-achar \[:Y] \[ad] Y y +. +.fchar \[S ,] \o'S\[ac]' +.hcode \[S ,]s +.fchar \[s ,] \o's\[ac]' +.hcode \[s ,]s +. +.de X-frac +. schar \[\\$1\\$2] \ +\v'-.28m'\s[\\En[.s]*6u/10u]\\$1\s0\v'.28m'\ +\h'-.1m'\[f/]\h'-.1m'\ +\s[\\En[.s]*6u/10u]\\$2 +.. +. +.de X-frac-mono +. fschar \\$1 \[\\$2\\$3] \ +\Z'\v'-.28m'\s[\\En[.s]*5u/10u]\\$2\s0\v'.28m''\ +\Z'\h'0.25m'\[f/]'\ +\Z'\h'.35m'\s[\\En[.s]*5u/10u]\\$3\s0'\ +\h'\w'M'u' +.. +. +.X-frac 1 8 +.X-frac 3 8 +.X-frac 5 8 +.X-frac 7 8 +. +.X-frac-mono CR 1 8 +.X-frac-mono CR 3 8 +.X-frac-mono CR 5 8 +.X-frac-mono CR 7 8 +.X-frac-mono CI 1 8 +.X-frac-mono CI 3 8 +.X-frac-mono CI 5 8 +.X-frac-mono CI 7 8 +.X-frac-mono CB 1 8 +.X-frac-mono CB 3 8 +.X-frac-mono CB 5 8 +.X-frac-mono CB 7 8 +.X-frac-mono CBI 1 8 +.X-frac-mono CBI 3 8 +.X-frac-mono CBI 5 8 +.X-frac-mono CBI 7 8 +. +.if '\*[.T]'X100' \ +. char \[radicalex] \h'-\w'\[sr]'u'\[radicalex]\h'\w'\[sr]'u' +.fchar \[sqrtex] \[radicalex] +. +.ie '\[char97]'a' \ +. mso latin1.tmac +.el \ +. mso cp1047.tmac +. +.cp \n[*groff_X_tmac_C] +.do rr *groff_X_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/Xps.tmac b/tmac/Xps.tmac new file mode 100644 index 0000000..aaef0ce --- /dev/null +++ b/tmac/Xps.tmac @@ -0,0 +1,65 @@ +.\" Xps.tmac +.\" +.do nr *groff_Xps_tmac_C \n[.cp] +.cp 0 +. +.mso ps.tmac +. +.\" Use this macro only to replace characters which do really exist in +.\" the devps font definition files. +.de Xps-char +. char \\$1 \Z"\X'ps: invis'\\$2\X'ps: endinvis'"\\$1 +.. +. +.Xps-char \[bu] \f[S]\[bu] +.Xps-char \[f/] \f[S]\[f/] +.Xps-char \[em] "\v'-.25m'\h'.05m'\D'l .9m 0'\h'.05m'" +.Xps-char \[aq] ' +.Xps-char \[bq] , +.Xps-char \[Bq] ,, +.Xps-char \[lq] `` +.Xps-char \[rq] '' +.Xps-char \[OE] OE +.Xps-char \[oe] oe +.Xps-char \[Fn] \f[S]\[Fn] +.Xps-char \[vS] \o'\[ah]S' +.Xps-char \[vs] \o'\[ah]s' +.Xps-char \[vZ] \o'\[ah]Z' +.Xps-char \[vz] \o'\[ah]z' +.Xps-char \[/L] \o'/L' +.Xps-char \[/l] \o'/l' +.Xps-char \[:Y] \o'\[ad]Y' +.Xps-char \[a"] \[sd] +.Xps-char \[a.] \v'-.6m'. +.Xps-char \[ga] "\Z'\v'-.7m'\D'l .22m .18m''" +.Xps-char \[ab] \v'-.55m'\s[\En[.s]*6u/10u]u\s[0] +.Xps-char \[ah] \v'-.55m'\s[\En[.s]/2u]v\s[0] +.Xps-char \[ao] "\v'-.55m'\s[\En[.s]*6u/10u]\D'c .25m'\s[0]" +.Xps-char \[ho] \s[\En[.s]/2u]\v'.4m'c\s[0] +.Xps-char \[.i] i +.Xps-char \[fo] < +.Xps-char \[fc] > +.Xps-char \[OK] \s[\En[.s]*6u/10u]\[rs]\s[0]/ +.Xps-char \[tm] \v'-.3m'\s[\En[.s]*6u/10u]TM\s[0] +.Xps-char \[dd] "\Z'\h'.25m'\v'.15m'\D'l 0 -.8m'\v'.2m'\h'-.195m'\ +\D'l .39m 0'\v'.4m'\D'l -.39m 0''" +.Xps-char \[dg] "\Z'\h'.25m'\v'.15m'\D'l 0 -.8m'\v'.2m'\h'-.195m'\ +\D'l .39m 0''" +.Xps-char \[en] \- +.Xps-char \[%0] %\s[\En[.s]*6u/10u]\f[I]0 +.Xps-char \[lh] \[lA] +.Xps-char \[rh] \[rA] +. +.ie '\[char97]'a' \ +. mso latin1.tmac +.el \ +. mso cp1047.tmac +. +.cp \n[*groff_Xps_tmac_C] +.do rr *groff_Xps_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/an-ext.tmac b/tmac/an-ext.tmac new file mode 100644 index 0000000..5035bb2 --- /dev/null +++ b/tmac/an-ext.tmac @@ -0,0 +1,205 @@ +.\" groff extension macros for man(7) package +.\" +.\" Copyright (C) 2007-2022 Free Software Foundation, Inc. +.\" +.\" Written by Eric S. Raymond +.\" Werner Lemberg +.\" G. Branden Robinson +.\" +.\" You may freely use, modify and/or distribute this file. +.\" +.\" The code below provides extension macros for the 'man' macro +.\" package. Care has been taken to make the code portable; groff +.\" extensions are properly hidden so that all troff implementations can +.\" use it without changes. +.\" +.\" With groff, this file is sourced by the 'man' macro package itself. +.\" Man page authors who are concerned about portability might add the +.\" used macros directly to the prologue of the man page(s). +. +. +.\" Convention: Auxiliary macros and registers start with 'm' followed +.\" by an uppercase letter or digit. +. +.\" Setting the `mG` register to a positive value (e.g., on the command +.\" line) enables usage of macros defined here that have alternative +.\" definitions in the main groff man macro file. This is for testing. +.\" The logic uses subtraction due to frustrating, AT&T troff-compatible +.\" limitations on the '!' operator. +. +. +.\" Protect against being sourced twice. +.nr mZ +1 +.if \n(mZ>1 \ +. nx +. +.\" Define this to your implementation's constant-width typeface. +.ds mC CW +.if n .ds mC R +. +.\" Save the automatic hyphenation mode. +.\" +.\" In AT&T troff, there was no register exposing the hyphenation mode, +.\" and no way to save and restore it. Set `mH` to a reasonable value +.\" for your implementation and preference. +.de mY +. ie !\\n(.g \ +. nr mH 14 +. el \ +. do nr mH \\n[.hy] \" groff extension register +.. +. +.nr mS 0 \" in a synopsis (SY/YS)? +.nr mE 0 \" in an example (EX/EE)? +. +. +.\" Declare start of command synopsis. Sets up hanging indentation. +.de SY +. ie !\\n(mS \{\ +. mY +. nh +. nr mS 1 +. nr mA \\n(.j +. ad l +. nr mI \\n(.i +. \} +. el \{\ +. br +. ns +. \} +. +. nr mT \w'\fB\\$1\fP\ ' +. HP \\n(mTu +. rr mT +. B "\\$1" +.. +. +. +.\" End of command synopsis. Restores adjustment. +.de YS +. in \\n(mIu +. ad \\n(mA +. hy \\n(mH +. rr mA +. rr mI +. nr mS 0 +.. +. +. +.\" Prepare link text for mail/web hyperlinks. `MT` and `UR` call this. +.de mV +. ds m1 \\$1\" +.. +. +. +.\" Emit hyperlink. The optional argument supplies trailing punctuation +.\" after link text. `ME` and `UE` call this. +.de mQ +. mY +. nh +<\\*(m1>\\$1 +. hy \\n(mH +.. +. +. +.\" Start URL. +.if \n(.g-\n(mG \{\ +.de UR +. mV \\$1 +.. +.\} +. +. +.\" End URL. +.if \n(.g-\n(mG \{\ +.de UE +. mQ \\$1 +.. +.\} +. +. +.\" Start email address. +.if \n(.g-\n(mG \{\ +.de MT +. mV \\$1 +.. +.\} +. +. +.\" End email address. +.if \n(.g-\n(mG \{\ +.de ME +. mQ \\$1 +.. +.\} +. +. +.\" Set a man page cross reference. +.\" .MR page-topic page-section [trailing-text] +.if \n(.g-\n(mG \{\ +.de MR +. mY +. nh +. ie \\n(.$=1 \ +. I \\$1 +. el \ +. IR \\$1 (\\$2)\\$3 +. hy \\n(mH +.. +.\} +. +. +.\" Continuation line for .TP header. +.de TQ +. br +. ns +. TP \\$1\" no doublequotes around argument! +.. +. +. +.\" Start example. +.if \n(.g-\n(mG \{\ +.de EX +. br +. if !\\n(mE \{\ +. nr mF \\n(.f +. nr mP \\n(PD +. nr PD 1v +. nf +. ft \\*(mC +. nr mE 1 +. \} +.. +.\} +. +. +.\" End example. +.if \n(.g-\n(mG \{\ +.de EE +. br +. if \\n(mE \{\ +. ft \\n(mF +. nr PD \\n(mP +. fi +. nr mE 0 +. \} +.. +.\} +. +. +.\" Start display. +.de DS +. \" XXX to be written +.. +. +. +.\" End display. +.de DE +. \" XXX to be written +.. +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/an.tmac b/tmac/an.tmac new file mode 100644 index 0000000..9e38ba5 --- /dev/null +++ b/tmac/an.tmac @@ -0,0 +1,1574 @@ +.\" groff implementation of man(7) package +.\" +.\" Copyright (C) 1989-2023 Free Software Foundation, Inc. +.\" Written by James Clark (jjc@jclark.com) +.\" Enhanced by: Werner Lemberg +.\" Larry Kollar +.\" G. Branden Robinson +.\" +.\" Thanks to Deri James for illustrating PDF bookmark features. +.\" +.\" This file 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 +.\" . +. +. +.\" Put site additions in the file man.local, loaded near the end of +.\" this file. To add things to TH, use '.am1 TH'. +. +.if !\n(.g \ +. ab groff man macros require groff extensions; aborting +. +.do if d TH .nx +. +.do nr *groff_an_tmac_C \n[.cp] +.cp 0 +. +.\" Package-internal names start with "an-" and are subject to change, +.\" such as migration to "an*" (in progress). +. +.\" Define a string for use in diagnostic messages. +.ds an an.tmac\" +. +.\" We use the .stringup request from groff 1.23, but nothing breaks if +.\" it is undefined; the output is unchanged in appearance from earlier +.\" releases. +.if (\n[.x]\n[.y] < 118) \{\ +. ds an-msg \*[an]: groff man macros require groff 1.18 or later,\" +. as an-msg " but found groff \n[.x].\n[.y]; aborting\" +. ab \*[an-msg] +.\} +. +.\" === Define macros. === +.\" +.\" Macros that are part of the external interface (TH, SH, P, etc.) or +.\" that are called by traps of any kind must be defined with `de1` +.\" because they might be called from a context where compatibility mode +.\" is enabled. For other macros, `de` suffices. +. +.de an-warn +. tm \*[an]:\\n[.F]:\\n[.c]: warning: \\$* +.. +. +.de an-style-warn +. if \\n[CHECKSTYLE] \ +. tm \*[an]:\\n[.F]:\\n[.c]: style: \\$* +.. +. +.de an-deprecation-warn +. if (\\n[CHECKSTYLE] > 1) \ +. an-style-warn use of deprecated macro: .\\$0 +.. +. +.de1 an-blank-line-trap +. if (\\n[CHECKSTYLE] > 2) \ +. an-style-warn blank line in input +. sp +.. +. +.de1 an-leading-space-trap +. if (\\n[CHECKSTYLE] > 2) \ +. if \\n[.u] \ +. an-style-warn \\n[lsn] leading space(s) on input line +. br +. nop \h'\\n[lss]u'\c +.. +. +.\" Define alternate requests to handle continuous rendering. +.\" +.\" This .ne replacement avoids page breaks; instead, the page length is +.\" increased to the necessary amount. +.de an-ne +. ie \\n[.$] .nr an-amount (v;\\$*) +. el .nr an-amount 1v +. if (\\n[an-amount] >= \\n[.t]) \ +. pl +(\\n[an-amount]u - \\n[.t]u + 1v) +. rr an-amount +.. +. +.\" This .bp replacement for continuous rendering mode adjusts the page +.\" length to the current position so that no empty lines are inserted. +.de an-bp +. pl \\n[nl]u +.. +. +.\" We need an end-of-input macro to flush any pending output line and +.\" write the footer for the final man page rendered. We can also be +.\" called by andoc when switching to an mdoc(7) page, irrespective of +.\" continuous rendering mode. +.de1 an-end +. if !r an-TH-was-called .return +. if \\n[cR] \{\ +. \" We might have a pending output line that is not yet broken, and +. \" also be 1v from the bottom of the page. If we break (or flush) +. \" the output line now, the page will get ejected afterward and +. \" troff will exit because we're in an end-of-input macro--our +. \" footer will never be output. So, if that is the case, further +. \" extend the page length by 1v. +. if ((\\n[.p] - \\n[nl]) <= \\n[.V]) .pl +1v +. br +. pl +1v +. sp 1v +. an-footer +. \" If we're processing multiple documents and have started a new +. \" one, draw a line between this footer and the next header. +. if !'\\n[.F]'' \{\ +. pl +1v +. nf +. ti 0 +. nop \D'l \\n[LL]u 0' +. fi +. \} +. \} +. rr an-TH-was-called +. ch an-header +. an*break-page-with-new-number +.. +. +.\" Move macros into place for continuous rendering. +.de an-set-up-continuous-rendering +. rn ne an-real-ne +. rn bp an-real-bp +. rn an-ne ne +. rn an-bp bp +. em an-end +.. +. +.de an*reset-hyphenation-mode +. ie \\n[HY] \{\ +. \" No page breaks occur in continuous rendering. +. ie \\n[cR] \ +. nr an*hyphenation-mode \\n[\\*[locale]*hyphenation-mode-base] +. el \ +. nr an*hyphenation-mode \\n[\\*[locale]*hyphenation-mode-trap] +. \} +. el \ +. nr an*hyphenation-mode 0 +. hy \\n[an*hyphenation-mode] +.. +. +.de an-reset-tab-stops +. ta T .5i +.. +. +.de an-reset-paragraph-spacing +. ie \\n[.$] .nr PD (v;\\$1) +. el .nr PD (.4v >? \n[.V]) +.. +. +.de an-reset-margin-and-inset-level +. nr an-inset-level 1 +. nr an-margin \\n[IN] +. nr an-saved-margin1 \\n[IN] +. nr an-prevailing-indent \\n[IN] +. nr an-saved-prevailing-indent1 \\n[IN] +.. +. +.\" Break the page and update its number depending on the C (consecutive +.\" numbering) register. +.\" +.\" Corner case: if formatting multiple documents and P (starting page +.\" number) is defined but C is not set, start numbering each document +.\" at \n[P]. Not strictly necessary if not switching macro packages. +.de an*break-page-with-new-number +. ie \\n[C] .bp (\\n[%] + 1) \" argument NOT redundant before page 1 +. el \{\ +. ie r P .bp \\n[P] +. el .bp 1 +. \} +.. +. +.\" Localize manual section titles for English. +.de an*localize-strings +. ds an*section1 General Commands Manual\" +. ds an*section2 System Calls Manual\" +. ds an*section3 Library Functions Manual\" +. ds an*section4 Kernel Interfaces Manual\" +. ds an*section5 File Formats Manual\" +. ds an*section6 Games Manual\" +. ds an*section7 Miscellaneous Information Manual\" +. ds an*section8 System Manager's Manual\" +. ds an*section9 Kernel Developer's Manual\" +.. +. +.\" Write a bookmark/anchor/link target $2 at hierarchical depth $1. +.de an*bookmark +. if \\n[an*is-output-pdf] .pdfbookmark \\$1 \\$2 +.. +. +.\" Begin man page. +.\" .TH topic section[ extra1[ extra2[ extra3]]] +.de1 TH +. if ((\\n[.$] < 2) : (\\n[.$] > 5)) \ +. an-style-warn .\\$0 expects 2 to 5 arguments, got \\n[.$] +. +. blm an-blank-line-trap +. lsm an-leading-space-trap +. +. \" If batch processing (rendering multiple) man page documents, we +. \" must handle the end of a previous document. +. if \\n[an*need-titles-reset] \{\ +. if \\n[cR] .an-end +. +. \" Clear the page header trap so it is not sprung with stale +. \" information. +. ch an-header +. an*break-page-with-new-number +. \} +. if \\n[C] .rr P +. +. nr an-TH-was-called 1 \" an-end can make certain assumptions. +. +. \" Set up rendering parameters. We do this in TH instead of only +. \" once when initializing the package because when rendering multiple +. \" pages, a previous page might have changed them. +. +. fam \\*[an*body-family] +. ft R +. +. nr PS 10z \" default type size +. nr PS-SS 10z +. nr PS-SH 10.95z +. nr VS 12p +. +. \" use sizes similar to LaTeX +. if t \{\ +. ie (\\n[S] == 11) \{\ +. nr PS 10.95z +. nr PS-SS 10.95z +. nr PS-SH 12z +. nr VS 13.6p +. \} +. el \{\ +. if (\\n[S] == 12) \{\ +. nr PS 12z +. nr PS-SS 12z +. nr PS-SH 14.4z +. nr VS 14.5p +. \} +. \} +. \} +. +. \" The previous document rendered in a batch may have been in a +. \" different language. If this one is in English, (re-)init strings. +. if '\\*[locale]'english' .an*localize-strings +. +. ps \\n[PS]u +. vs \\n[VS]u +. ad \\*[AD] +. ll \\n[LL]u +. +. \" We've seen no tbl(1) tables yet in this document. +. rr TW +. nr an-was-tbl-failure-reported 0 +. +. an*reset-hyphenation-mode +. an-reset-tab-stops +. an-reset-paragraph-spacing +. an-reset-margin-and-inset-level +. +. nr an-tag-separation 1n +. nr an-need-no-space-mode 0 +. nr an-need-break 0 +. nr an-is-in-diversion 0 +. nr an*is-in-example 0 +. +. ds an*topic "\\$1\" +. if \\n[CT] .stringup an*topic +. ds an*section "\\$2\" +. ie (\\n[.$] > 4) .ds an-extra3 "\\$5\" +. el \{\ +. \" Simulate switch/case in roff. +. ie '\\$2'1' .ds an-extra3 \\*[an*section1]\" +. el \{.ie '\\$2'2' .ds an-extra3 \\*[an*section2]\" +. el \{.ie '\\$2'3' .ds an-extra3 \\*[an*section3]\" +. el \{.ie '\\$2'4' .ds an-extra3 \\*[an*section4]\" +. el \{.ie '\\$2'5' .ds an-extra3 \\*[an*section5]\" +. el \{.ie '\\$2'6' .ds an-extra3 \\*[an*section6]\" +. el \{.ie '\\$2'7' .ds an-extra3 \\*[an*section7]\" +. el \{.ie '\\$2'8' .ds an-extra3 \\*[an*section8]\" +. el \{.ie '\\$2'9' .ds an-extra3 \\*[an*section9]\" +. el .ds an-extra3 \" empty +. \}\}\}\}\}\}\}\} +. \} +. +. ds an-extra1 "\\$3\" +. ie (\\n[.$] > 3) .ds an-extra2 "\\$4\" +. el .ds an-extra2 \" empty; but .AT/.UC can override +. +. if '\\*[an-extra1]'' \{\ +. ds an-msg .\\$0 missing third argument; suggest document\" +. as an-msg " modification date in ISO 8601 format (YYYY-MM-DD)\" +. an-style-warn \\*[an-msg] +. rm an-msg +. \} +. +. if '\\*[an-extra2]'' \{\ +. ds an-msg .\\$0 missing fourth argument; suggest package/project\" +. \" Yes, that's one double quote, then three, then two. +. as an-msg " name and version (e.g., """groff 1.23.0"")\" +. an-style-warn \\*[an-msg] +. rm an-msg +. \} +. +. if '\\$5\\*[an-extra3]'' \{\ +. ds an-msg .\\$0 missing fifth argument and second argument '\\$2'\" +. as an-msg " not a recognized manual section; specify its title\" +. an-style-warn \\*[an-msg] +. rm an-msg +. \} +. +. \" Initialize environment for headers and footers. +. ev an*env-header-and-footer +. ps \\n[PS]u +. vs \\n[VS]u +. lt \\n[LT]u +. an*abbreviate-page-topic +. \" If AT or UC is called, we will need to abbreviate again. +. an*abbreviate-inner-footer +. ev +. +. \" HTML gets the topic without any abbreviation, since it's metadata. +. if \\n[an*is-output-html] \{\ +. DEVTAG-TL +. nop \\*[an*topic] +. DEVTAG-EO-TL +. \} +. +. \" A bookmark is attached to the page header, but only on the first +. \" page of the document. +. nr an*was-TH-bookmark-emitted 0 +. an-header +. +. if !\\n[cR] \{\ +. wh 0 an-header +. ie r FT .nr an*footer-location \\n[FT] +. el .nr an*footer-location (-.5i) +. wh \\n[an*footer-location]u an-footer +. wh (\\n[an*footer-location]u - .5i) an-break-body-text +. rr an*footer-location +. \} +. \} +. +. nr an*need-titles-reset 1 +.. +. +.\" Support legacy AT&T and BSD Unix man pages. +. +.\" Designate an AT&T Unix man page. +.\" .AT [system-id[ release-id]] +.de1 AT +. nop \\*[an-deprecation-warn]\\ +. ds an-extra2 "7th Edition\" +. if "\\$1"3" .ds an-extra2 "7th Edition\" +. if "\\$1"4" .ds an-extra2 "System III\" +. if "\\$1"5" \{\ +. ie "\\$2"" .ds an-extra2 "System V\" +. el .ds an-extra2 "System V Release \\$2\" +. \} +. ev an*env-header-and-footer +. an*abbreviate-inner-footer +. ev +.. +. +.\" Designate a BSD Unix man page. +.\" .UC [system-id] +.de1 UC +. nop \\*[an-deprecation-warn]\\ +. ds an-extra2 "3rd Berkeley Distribution\" +. if "\\$1"3" .ds an-extra2 "3rd Berkeley Distribution\" +. if "\\$1"4" .ds an-extra2 "4th Berkeley Distribution\" +. if "\\$1"5" .ds an-extra2 "4.2 Berkeley Distribution\" +. if "\\$1"6" .ds an-extra2 "4.3 Berkeley Distribution\" +. if "\\$1"7" .ds an-extra2 "4.4 Berkeley Distribution\" +. ev an*env-header-and-footer +. an*abbreviate-inner-footer +. ev +.. +. +.\" Restore tab stops to defaults. +.de1 DT +. nop \\*[an-deprecation-warn]\\ +. an-reset-tab-stops +.. +. +.\" Restore inter-paragraph spacing to default (or set it to argument). +.\" .PD [distance] +.de1 PD +. nop \\*[an-deprecation-warn]\\ +. nop \\*[an-reset-paragraph-spacing]\\ +.. +. +.\" Write the page header; can be redefined by man.local. +.\" +.\" In continuous rendering mode, we need to extend the page length to +.\" accommodate the vertical size of our header (plus any spacing). +.if d PT .ig +.de1 PT +. ie \\n[cR] .pl +1v +. el .sp .5i +. if !\\n[an*was-TH-bookmark-emitted] \{\ +. an*bookmark 1 \E*[an*page-ref-string] +. nr an*was-TH-bookmark-emitted 1 +. \} +. tl '\\*[an-pageref]'\\*[an-extra3]'\\*[an-pageref]' +. ie \\n[cR] \{\ +. pl +1v +. sp 1v +. \} +. el .sp |1i +.. +. +.\" Write the page footer; can be redefined by man.local. +.\" +.\" In continuous rendering mode, we need to extend the page length to +.\" accommodate the vertical size of our footer (plus any spacing). +.if d BT .ig +.de1 BT +. if \\n[cR] .pl +1v +. ie \\n[D] \{\ +. if o .tl '\\*[an*ifoot]'\\*[an-extra1]'\\*[an*ofoot]' +. if e .tl '\\*[an*ofoot]'\\*[an-extra1]'\\*[an*ifoot]' +. \} +. el \ +. tl '\\*[an*ifoot]'\\*[an-extra1]'\\*[an*ofoot]' +.. +. +.\" Abbreviate the page topic if it's too long for the header. Leaves +.\" string an-pageref defined for use in .PT and .an-footer. Also +.\" leaves an*topic-abbv for possible use by .PT and .BT re-definers. +.\" Call this only from within the header/footer environment. +.de an*abbreviate-page-topic +. ds an*topic-abbv \\*[an*topic]\" might not get abbreviated at all +. ds an*topic-string \\*[an*topic]\" +. ds an-ellipsis \|.\|.\|.\|\" +. \" an*page-ref-string is left unmodified for internal use, such as +. \" PDF bookmarks. +. ds an*page-ref-string \\*[an*topic](\\*[an*section])\" +. ds an-pageref \\*[an*topic-abbv](\\*[an*section])\" +. nr an-header-width \\w'\\*[an-pageref]\\*[an-extra3]\\*[an-pageref]' +. while (\\n[an-header-width] >= \\n[.lt]) \{\ +. \" The page topic is too long; trim some bits out of the middle. +. length an*topic-length \\*[an*topic-string] +. \" roff uses truncating division. Remove an additional character +. \" on each side of the midpoint to account for the ellipsis we add +. \" later. +. nr an-mark1 (\\n[an*topic-length] / 2 - 2) +. nr an-mark2 (\\n[an*topic-length] / 2 + 2) +. ds an-prefix \\*[an*topic-string]\" +. ds an-suffix \\*[an*topic-string]\" +. \" Use extremum operators to ensure that the first and last +. \" characters of the topic remain intact (in cases of pathological +. \" shortening). +. substring an-prefix 0 (\\n[an-mark1] >? 1) +. substring an-suffix (\\n[an-mark2] = \\n[an*topic-length]) \ +. break +. ds an-pageref \\*[an*topic-abbv](\\*[an*section])\" +. nr an-header-width \ + \\w'\\*[an-pageref]\\*[an-extra3]\\*[an-pageref]' +. \} +. ds an-pageref \\*[an-lic]\f[\\*[MF]]\\*[an*topic-abbv]\\*[an-ic]\ +\f[R](\\*[an*section])\" +. rr an*topic-length-prev +. rr an-mark1 +. rr an-mark2 +. rm an-prefix +. rm an-suffix +. rm an*topic-string +. rr an*topic-length +. rr an-header-width +. rm an-ellipsis +.. +. +.\" Iterate through concatenation of arguments as a string. If a bare +.\" backslash is found, make `an*string-contains-backslash` true. Our +.\" caller should delete this register when done with it. +.de an*scan-string-for-backslash +. nr an*string-contains-backslash 0 +. nr an*index 0 +. length an*max-index \\$* +. while (\\n[an*index] < \\n[an*max-index]) \{\ +. ds an*char \\$* +. substring an*char \\n[an*index] \\n[an*index] +. ec @ +. \" Use a weird delimiter to reduce lexical colorizer confusion. +. if _@*[an*char]_\\_ .nr an*string-contains-backslash 1 +. ec +. if \\n[an*string-contains-backslash] .break +. nr an*index +1 +. \} +. rm an*char +. rr an*max-index +. rr an*index +.. +. +.\" Abbreviate the `an-extra2` string (set by .TH) if it's too long for +.\" the footer. The formatted width of the inner footer plus half that +.\" of the center footer must be less than half the title width or we +.\" must abbreviate. By default, `an-extra2` is placed as the inner +.\" footer. We call its (potential) abbreviation `an*ifoot` here and +.\" leave it defined for .BT use. (`an*ofoot` is not treated the same +.\" way. `an-footer` regenerates it on every page because the page +.\" number changes if present.) Shorten the inner footer if necessary +.\" by trimming characters off the end, replacing them with an ellipsis. +.de an*abbreviate-inner-footer +. ds an*ifoot \\*[an-extra2]\" +. nr an*half-title-width (\\n[.lt] / 2u) +. nr an*half-cfoot-width (\w'\\*[an-extra1]' / 2u) +. nr an*half-footer-width \ + (\w'\\*[an*ifoot]' + \\n[an*half-cfoot-width]) +. if (\\n[an*half-footer-width] < \\n[an*half-title-width]) \{\ +. rr an*half-footer-width +. rr an*half-cfoot-width +. rr an*half-title-width +. return +. \} +. an*scan-string-for-backslash \\*[an*ifoot] +. if \\n[an*string-contains-backslash] \{\ +. an-warn not abbreviating fourth argument to 'TH' '\\*[an*ifoot]': \ +contains unsupported escape sequence +. rr an*string-contains-backslash +. rr an*half-footer-width +. rr an*half-cfoot-width +. rr an*half-title-width +. return +. \} +. ds an*saved-ifoot \\*[an*ifoot] +. ds an*ellipsis \|.\|.\|.\|\" +. \" Remeasure with ellipsis added to inner footer so that henceforth, +. \" the measured width strictly decreases. +. nr an*half-footer-width \ + (\w'\\*[an*ifoot]\\*[an*ellipsis]' + \\n[an*half-cfoot-width]) +. nr an*end-index (-2) +. while (\\n[an*half-footer-width] >= \\n[an*half-title-width]) \{\ +. ds an*ifoot \\*[an*saved-ifoot] +. substring an*ifoot 0 \\n[an*end-index] +. \" Measure the string again and give up if we made no progress. +. nr an*new-half-footer-width \ + (\w'\\*[an*ifoot]\\*[an*ellipsis]' + \\n[an*half-cfoot-width]) +. ie (\\n[an*new-half-footer-width] >= \\n[an*half-footer-width]) \ +. break +. nr an*half-footer-width \\n[an*new-half-footer-width] +. nr an*end-index -1 +. \} +. ds an*ifoot \\*[an*ifoot]\\*[an*ellipsis]\" +. rr an*end-index +. rr an*new-half-footer-width +. rm an*ellipsis +. rm an*saved-ifoot +. rr an*string-contains-backslash +. rr an*half-footer-width +. rr an*half-cfoot-width +. rr an*half-title-width +.. +. +.\" Prepare the header for a page of the document. +.de1 an-header +. if \\n[an-suppress-header-and-footer] .return +. ev an*env-header-and-footer +. PT +. ev +. ns +.. +. +.\" Schedule a page break when the next output line is written (not +.\" called if continuously rendering). +.de1 an-break-body-text +' bp +.. +. +.\" Prepare the footer for a page of the document. +.de1 an-footer +. if \\n[an-suppress-header-and-footer] .return +. ev an*env-header-and-footer +. ie \\n[cR] \ +. ds an*ofoot "\\*[an-pageref]\" +. el \{\ +. ds an*ofoot \\n[%]\" +. if r X \{\ +. if (\\n[%] > \\n[X]) \{\ +. nr an-page-letter (\\n[%] - \\n[X]) +. ds an*ofoot \\n[X]\\n[an-page-letter]\" +. \} +. \} +. \} +. BT +. rm an*ofoot +. ev +.. +. +.\" Output the tag of a tagged paragraph, or of an indented paragraph +.\" (IP) that has a tag. Whether we break depends on the tag width. +.de an-write-paragraph-tag +. br +. di +. ad \\*[AD] +. nr an-is-in-diversion 0 +. ll +. \" We must emit the diversion in a separate environment to ensure +. \" that a possible margin character is printed correctly. +. ev an-env-paragraph-tag +. evc 0 +. mc +. nf +. in \\n[an-margin]u +. \" Prevent page break between the tag and the rest of the paragraph. +. ne (2v + 1u) +. \" Does the tag fit within the paragraph indentation? +. nr an-tag-fits \ + (\\n[dl] + \\n[an-tag-separation] <= \\n[an-prevailing-indent]) +. if \\n[an-tag-fits] .DEVTAG-COL 1 +. an-div +. if \\n[an-tag-fits] .sp -1v +. ev +. in (\\n[an-margin]u + \\n[an-prevailing-indent]u) +. if \\n[an-tag-fits] .DEVTAG-COL 2 +. rr an-tag-fits +.. +. +.\" Handle macros that may take an "argument" on the next input line +.\" producing written or drawn output: .SH, .SS, .B, .I, .SM, .SB--and +.\" .TP, which does so mandatorily. +.de1 an-input-trap +. if \\n[an-devtag-needs-end-of-heading] .DEVTAG-EO-H +. nr an-devtag-needs-end-of-heading 0 +. if \\n[an-devtag-needs-second-column] .DEVTAG-COL 2 +. nr an-devtag-needs-second-column 0 +. ft R +. ps \\n[PS]u +. vs \\n[VS]u +. if \\n[an-need-break] \{\ +. br +. nr an-need-break 0 +. \} +. if \\n[an-need-no-space-mode] \{\ +. ns +. nr an-need-no-space-mode 0 +. \} +. if \\n[an-is-in-diversion] .an-write-paragraph-tag +.. +. +.\" Break a paragraph. Restore defaults, except for indentation. +.de an-break-paragraph +. ft R +. ps \\n[PS]u +. vs \\n[VS]u +. sp \\n[PD]u +. ns +.. +. +.\" Set arguments (or next input line producing written or drawn output +.\" if none) as a section heading. +.de1 SH +. fam \\*[an*body-family] +. an-break-paragraph +. an-reset-margin-and-inset-level +. fi +. in \\n[an-margin]u +. ti 0 +. nr an-devtag-needs-end-of-heading 1 +. DEVTAG-SH 1 +. it 1 an-input-trap +. nr an-need-no-space-mode 1 +. nr an-need-break 1 +. ps \\n[PS-SH]u +. ne (2v + 1u) +. ft \\*[HF] +. if \\n[an-remap-I-style-in-headings] .ftr I \\*[an-heading-family]BI +. if \\n[.$] \{\ +. ds an-section-heading \\$*\" +. if \\n[CS] .stringup an-section-heading +. an*bookmark 2 \E*[an-section-heading] +. nop \&\\*[an-section-heading] +. \} +. if \\n[an-remap-I-style-in-headings] .ftr I I +.. +. +.\" Set arguments (or next input line producing written or drawn output +.\" if none) as a subsection heading. +.de1 SS +. fam \\*[an*body-family] +. an-break-paragraph +. an-reset-margin-and-inset-level +. fi +. in \\n[IN]u +. ti \\n[SN]u +. nr an-devtag-needs-end-of-heading 1 +. DEVTAG-SH 2 +. it 1 an-input-trap +. nr an-need-no-space-mode 1 +. nr an-need-break 1 +. ps \\n[PS-SS]u +. ne (2v + 1u) +. ft \\*[HF] +. if \\n[an-remap-I-style-in-headings] .ftr I \\*[an-heading-family]BI +. if \\n[.$] \{\ +. ds an*subsection-heading \\$*\" +. an*bookmark 3 \E*[an*subsection-heading] +. nop \&\\$* +. \} +. if \\n[an-remap-I-style-in-headings] .ftr I I +.. +. +.\" Set arguments (or next input line producing written or drawn output +.\" if none) in bold style. +.de1 B +. it 1 an-input-trap +. ft B +. if \\n[.$] \&\\$* +.. +. +.\" Set arguments (or next input line producing written or drawn output +.\" if none) in italic style. +.de1 I +. it 1 an-input-trap +. ft I +. if \\n[.$] \,\\$*\/ +.. +. +.\" Set arguments (or next input line producing written or drawn output +.\" if none) at smaller type size. +.de1 SM +. it 1 an-input-trap +. ps -1 +. if \\n[.$] \&\\$* +.. +. +.\" Set arguments (or next input line producing written or drawn output +.\" if none) in bold style at smaller type size. +.de1 SB +. it 1 an-input-trap +. ps -1 +. ft B +. if \\n[.$] \&\\$* +.. +. +.\" Set an ordinary paragraph. +.de1 P +. an-break-paragraph +. in \\n[an-margin]u +. nr an-prevailing-indent \\n[IN] +.. +. +.\" Accommodate ms(7) paragraphing refugees. +.als LP P +.als PP P +. +.\" Set a tagged paragraph. The tag must be on the next input line +.\" producing written or drawn output. +.\" .TP [indent] +.de1 TP +. an-break-paragraph +. if \\n[.$] .nr an-prevailing-indent (n;\\$1) +. itc 1 an-input-trap +. in 0 +. if !\\n[an-is-in-diversion] \{\ +. ll -\\n[an-margin]u +. di an-div +. na +. \} +. nr an-is-in-diversion 1 +.. +. +.\" Set an indented paragraph. +.\" .IP [marker[ indentation-amount]] +.de1 IP +. an-break-paragraph +. ie !\\n[.$] \{\ +. ne (1v + 1u) +. in (\\n[an-margin]u + \\n[an-prevailing-indent]u) +. \} +. el \{\ +. ie (\\n[.$] > 1) .TP "\\$2" +. el .TP +. nop \&\\$1 +. \} +.. +. +.\" Set a paragraph with a hanging indentation. +.\" .HP [indent] +.de1 HP +. if !\\n[mS] \\*[an-deprecation-warn]\c +. an-break-paragraph +. ne (1v + 1u) +. if \\n[.$] .nr an-prevailing-indent (n;\\$1) +. in (\\n[an-margin]u + \\n[an-prevailing-indent]u) +. ti \\n[an-margin]u +. DEVTAG-COL 1 +. nr an-devtag-needs-second-column 1 +.. +. +.\" === Define alternating font macros. === +.\" +.\" Implementation notes: +.\" +.\" We always emit a dummy character \& before the first argument. This +.\" is necessary only when the calling man page is in compatibility +.\" mode; it works around the surprising AT&T semantics of \f escapes at +.\" the beginning of an input line. See "Implementation differences" in +.\" groff_diff(7) or the groff Texinfo manual. +.\" +.\" The italic correction escapes can be visually confusing. We apply +.\" the following rules, always on the same input line. +.\" (1) Before any italic argument, emit a left italic correction \, +.\" before switching to the italic style. +.\" (2) After any italic argument, emit an italic correction \/ +.\" before switching to another style. +.\" It is true that these macros cannot know what style is used in the +.\" input stream before or after they are called. We can make +.\" assumptions based on pragmatics. In most cases, the caller will not +.\" precede a call to one of these macros with \c, or add it to the +.\" final argument given to one of these calls; when \c is absent, what +.\" is adjacent must be a word space or output line boundary, so italic +.\" corrections don't matter. If \c _is_ used by the caller, we can +.\" assume that the adjacent glyphs before an IB or IR call, or the +.\" following ones after a BI or RI call, will not be italic (and thus +.\" will benefit from the italic correction we provide); otherwise the +.\" caller would simply have added the relevant characters to the +.\" arguments of the macro call. +.\" +. +.\" Set each argument in bold and italics, alternately. +.de1 BI +. if (\\n[.$] < 2) \ +. an-style-warn .\\$0 expects at least 2 arguments, got \\n[.$] +. if \\n[.$] \{\ +. ds an-result \&\" +. while (\\n[.$] >= 2) \{\ +. as an-result \f[B]\\$1\,\f[I]\\$2\/\" +. shift 2 +. \} +. if \\n[.$] .as an-result \f[B]\\$1\" +. nop \\*[an-result] +. rm an-result +. ft R +. \} +.. +. +.\" Set each argument in bold and roman, alternately. +.de1 BR +. if (\\n[.$] < 2) \ +. an-style-warn .\\$0 expects at least 2 arguments, got \\n[.$] +. if \\n[.$] \{\ +. ds an-result \&\" +. while (\\n[.$] >= 2) \{\ +. as an-result \f[B]\\$1\f[R]\\$2\" +. shift 2 +. \} +. if \\n[.$] .as an-result \f[B]\\$1\" +. nop \\*[an-result] +. rm an-result +. ft R +. \} +.. +. +.\" Set each argument in italics and bold, alternately. +.de1 IB +. if (\\n[.$] < 2) \ +. an-style-warn .\\$0 expects at least 2 arguments, got \\n[.$] +. if \\n[.$] \{\ +. ds an-result \&\" +. while (\\n[.$] >= 2) \{\ +. as an-result \,\f[I]\\$1\/\f[B]\\$2\" +. shift 2 +. \} +. if \\n[.$] .as an-result \,\f[I]\\$1\/\" +. nop \\*[an-result] +. rm an-result +. ft R +. \} +.. +. +.\" Set each argument in italics and roman, alternately. +.de1 IR +. if (\\n[.$] < 2) \ +. an-style-warn .\\$0 expects at least 2 arguments, got \\n[.$] +. if \\n[.$] \{\ +. ds an-result \&\" +. while (\\n[.$] >= 2) \{\ +. as an-result \,\f[I]\\$1\/\f[R]\\$2\" +. shift 2 +. \} +. if \\n[.$] .as an-result \,\f[I]\\$1\/\" +. nop \\*[an-result] +. rm an-result +. ft R +. \} +.. +. +.\" Set each argument in roman and bold, alternately. +.de1 RB +. if (\\n[.$] < 2) \ +. an-style-warn .\\$0 expects at least 2 arguments, got \\n[.$] +. if \\n[.$] \{\ +. ds an-result \&\" +. while (\\n[.$] >= 2) \{\ +. as an-result \f[R]\\$1\f[B]\\$2\" +. shift 2 +. \} +. if \\n[.$] .as an-result \f[R]\\$1\" +. nop \\*[an-result] +. rm an-result +. ft R +. \} +.. +. +.\" Set each argument in roman and italics, alternately. +.de1 RI +. if (\\n[.$] < 2) \ +. an-style-warn .\\$0 expects at least 2 arguments, got \\n[.$] +. if \\n[.$] \{\ +. ds an-result \&\" +. while (\\n[.$] >= 2) \{\ +. as an-result \f[R]\\$1\,\f[I]\\$2\/\" +. shift 2 +. \} +. if \\n[.$] .as an-result \f[R]\\$1\" +. nop \\*[an-result] +. rm an-result +. ft R +. \} +.. +. +.\" Start a relative inset level (by the amount given in the argument). +.\" .RS [inset-amount] +.de1 RS +. nr an-saved-margin\\n[an-inset-level] \\n[an-margin] +. nr an-saved-prevailing-indent\\n[an-inset-level] \ + \\n[an-prevailing-indent] +. ie \\n[.$] .nr an-margin +(n;\\$1) +. el .nr an-margin +\\n[an-prevailing-indent] +. in \\n[an-margin]u +. nr an-prevailing-indent \\n[IN] +. nr an-inset-level +1 +.. +. +.\" End relative inset level, backing up by one level (or to the level +.\" given by the argument). +.\" .RE [inset-level] +.de1 RE +. ie \\n[.$] .nr an-RE-requested-level \\$1 +. el .nr an-RE-requested-level (\\n[an-inset-level] - 1) +. ie \\n[.$] \{\ +. if (\\n[an-RE-requested-level] = \\n[an-inset-level]) \ +. ds an-RE-problem already at level \\n[an-inset-level]\" +. if (\\n[an-RE-requested-level] > \\n[an-inset-level]) \ +. ds an-RE-problem too large\" +. if (\\n[an-RE-requested-level] < 1) \ +. ds an-RE-problem too small\" +. if d an-RE-problem \ +. an-style-warn argument """\\$1""" to .\\$0 \\*[an-RE-problem] +. rm an-RE-problem +. \} +. el .if !(\\n[an-RE-requested-level]) .an-style-warn unbalanced .\\$0 +. rr an-RE-requested-level +. ie \\n[.$] .nr an-inset-level ((;\\$1) ? \\n[an-inset-level]) +. nr an-margin \\n[an-saved-margin\\n[an-inset-level]] +. nr an-prevailing-indent \ + \\n[an-saved-prevailing-indent\\n[an-inset-level]] +. in \\n[an-margin]u +.. +. +.\" Deprecated: Style an option with an argument (mandatory if +.\" specified) for a command synopsis. +.\" .OP flag [option-parameter] +.de1 OP +. nop \\*[an-deprecation-warn]\\ +. if ((\\n[.$] < 1) : (\\n[.$] > 2)) \ +. an-style-warn .\\$0 expects 1 or 2 arguments, got \\n[.$] +. ie (\\n[.$] > 1) \ +. RI [\\f[B]\\$1\f[] \~\\$2 ] +. el \ +. RB [ \\$1 ] +.. +. +.\" Begin an example (typically of source code or shell input). +.de1 EX +. br +. if \\n[an*is-in-example] \{\ +. an-style-warn ignoring .\\$0 while already in example +. return +. \} +. ds an*saved-family \\n[.fam] +. nr an*saved-font \\n[.f] +. nr an*saved-paragraph-distance \\n[PD] +. nr PD 1v +. nf +. \" If using the DVI output device, we have no constant-width fonts of +. \" bold weight and, relatedly, no constant-width family (because that +. \" requires all four styles). Remap the bold styles to normal ones. +. ie '\*[.T]'dvi' \{\ +. ftr R CW +. ftr B CW +. ftr I CWI +. ftr BI CWI +. \} +. el .fam \\*[an*example-family] +. ft R +. nr an*is-in-example 1 +.. +. +.\" End example. +.de EE +. br +. if !\\n[an*is-in-example] \{\ +. an-style-warn ignoring .\\$0 while not in example +. return +. \} +. \" Undo the remappings from `EX`. +. ie '\*[.T]'dvi' \{\ +. ftr R +. ftr B +. ftr I +. ftr BI +. \} +. fam \\*[an*saved-family] +. ft \\n[an*saved-font] +. nr PD \\n[an*saved-paragraph-distance] +. fi +. rr an*saved-paragraph-distance +. rr an*saved-font +. rm an*saved-family +. nr an*is-in-example 0 +.. +. +.\" Store the argument and begin a diversion for link text. +.de an*begin-hyperlink +. ds an*hyperlink \\$1\" +. \" We want the diversion to format as if it has an indentation of +. \" zero (that comes for free when we switch environments), and we +. \" want the line length reduced by the amount of indentation that +. \" obtains when we output it. +. nr an*saved-line-length \\n[.l] +. nr an*saved-indentation \\n[.i] +. \" We can only hyperlink if we're not in a diversion. +. \" XXX: There's no fundamental reason for that, just a simple matter +. \" of macro programming. +. nr an*is-in-link-text-diversion 0 +. if '\\n(.z'' .nr an*is-in-link-text-diversion 1 +. if (\\n[an*is-in-link-text-diversion] & \\n[an*do-hyperlink]) \{\ +. \" Start diversion in a new environment. +. ev an*link-text-env +. di an*link-text-div +. ll (\\n[an*saved-line-length]u - \\n[an*saved-indentation]u) +. \} +. rr an*saved-indentation +. rr an*saved-line-length +.. +. +.\" Emit hyperlinked text with optional trailing text. +.\" +.\" The caller should set the `an*prefix` string if the hyperlink should +.\" be prefixed with a scheme; for example, email addresses get +.\" "mailto:", but this need not be visible when rendering an email +.\" address on a device incapable of hyperlinking. +.de an*end-hyperlink +. ie (\\n[an*is-in-link-text-diversion] & \\n[an*do-hyperlink]) \{\ +. br +. di +. ev +. +. \" Was any link text present? +. ie \\n[dn] \{\ +. if \\n[an*is-output-html] \ +. nop \X^html:^\c +. if \\n[an*is-output-terminal] \ +. nop \X^tty: link \\*[an*prefix]\\*[an*hyperlink]^\c +. \" Strip off the final newline of the diversion and emit it. +. chop an*link-text-div +. an*link-text-div +\c\" XXX: If we .nop this, HTML output is corrupted (Savannah #63470). +. if \\n[an*is-output-html] \ +. nop \X^html:^\c +. if \\n[an*is-output-terminal] \ +. nop \X^tty: link^\c +. \} +. \" If there was no link text, format URI as its own link text. We +. \" don't add angle brackets here. +. el \{\ +. if \\n[an*is-output-html] \ +. nop \X^html:\ +\\*[an*hyperlink]^\c +. if \\n[an*is-output-terminal] \ +. nop \X^tty: link \\*[an*prefix]\\*[an*hyperlink]^\ +\\*[an*hyperlink]\X^tty: link^\c +. \} +. nop \&\\$1\" +. \} +. \" If not hyperlinking, format URI in angle brackets. There was no +. \" diversion, so the link text has already been formatted normally. +. el \{\ +. nh +. nop \\[la]\\*[an*hyperlink]\\[ra]\\$1 +. hy \\n[an*hyphenation-mode] +. \} +. +. rr an*is-in-link-text-diversion +.. +. +.\" Begin email hyperlink. Input until the next `ME` call is stored in +.\" a diversion; it becomes the link text for the hyperlinked address. +.\" .MT nobody@example.com +.de1 MT +. if !(\\n[.$] = 1) \ +. an-style-warn .\\$0 expects 1 argument, got \\n[.$] +. ds an*prefix mailto: +. an*begin-hyperlink \\$1 +.. +. +.\" End email hyperlink. The optional argument supplies trailing +.\" punctuation (or, rarely, other text) after link text. +.\" .ME [trailing-text] +.de1 ME +. an*end-hyperlink \\$1 +. rm an*prefix +.. +. +.\" Begin web hyperlink. Input until the next `UE` call is stored in +.\" a diversion; it becomes the link text for the hyperlinked address. +.\" .UR nobody@example.com +.de1 UR +. if !(\\n[.$] = 1) \ +. an-style-warn .\\$0 expects 1 argument, got \\n[.$] +. ds an*prefix \" empty +. an*begin-hyperlink \\$1 +.. +. +.\" End web hyperlink. The optional argument supplies trailing +.\" punctuation (or, rarely, other text) after link text. +.\" .UE [trailing-text] +.de1 UE +. an*end-hyperlink \\$1 +. rm an*prefix +.. +. +.\" There is no standardized format for man page URLs, but the default +.\" is expected to work (or be harmlessly ignored) everywhere except +.\" macOS. Override in man.local if desired. +.nr an*MR-URL-format 1 +. +.\" Set a man page cross reference. +.\" .MR page-topic page-section [trailing-text] +.de1 MR +. if ((\\n[.$] < 2) : (\\n[.$] > 3)) \ +. an-style-warn .\\$0 expects 2 or 3 arguments, got \\n[.$] +. ds an*url man:\\$1(\\$2)\" used everywhere but macOS +. if (\\n[an*MR-URL-format] = 2) \ +. ds an*url x-man-page://\\$2/\\$1\" macOS/Mac OS X since 10.3 +. if (\\n[an*MR-URL-format] = 3) \ +. ds an*url man:\\$1.\\$2\" Bwana (Mac OS X) +. if (\\n[an*MR-URL-format] = 4) \ +. ds an*url x-man-doc://\\$2/\\$1\" ManOpen (Mac OS X pre-2005) +. nh +. if \\n[an*do-hyperlink] \{\ +. if \\n[an*is-output-html] \ +. nop \X^html:^\c +. if \\n[an*is-output-terminal] \ +. nop \X^tty: link \\*[an*url]^\c +. \} +. nop \&\\*[an-lic]\f[\\*[MF]]\\$1\\*[an-ic]\f[R](\\$2)\c +. if \\n[an*do-hyperlink] \{\ +. if \\n[an*is-output-html] \ +. nop \X^html:^\c +. if \\n[an*is-output-terminal] \ +. nop \X^tty: link^\c +. \} +. nop \&\\$3 +. hy \\n[an*hyphenation-mode] +.. +. +.\" tbl(1) table support +. +.\" Start table. +.de1 TS +. \" If continuous rendering, tell tbl not to use keeps. +. ie \\n[cR] .nr 3usekeeps 0 +. el .nr 3usekeeps 1 +. if \\n[an*is-output-html] \{\ +. nr an-TS-ll \\n[.l] +. ll 1000n +. \} +. HTML-IMAGE +.. +. +.\" Start another table in the same region (ignored). +.de1 T& +.. +. +.\" End table. +.de1 TE +. HTML-IMAGE-END +. if \\n[an*is-output-html] .ll \\n[an-TS-ll]u +. if !r TW .if !\\n[an-was-tbl-failure-reported] \{\ +. ds an-msg tbl preprocessor failed, or it or soelim was not run;\" +. as an-msg " table(s) likely not rendered\" +. as an-msg " (TE macro called with TW register undefined)\" +. an-warn \\*[an-msg] +. rm an-msg +. nr an-was-tbl-failure-reported 1 +. \} +.. +. +.\" eqn(1) equation support +. +.\" Start equation. +.de1 EQ +. if \\n[an*is-output-html] \{\ +. nr an-EQ-ll \\n[.l] +. ll 1000n +. \} +. HTML-IMAGE +.. +. +.\" End equation. +.de1 EN +. HTML-IMAGE-END +. if \\n[an*is-output-html] .ll \\n[an-EQ-ll]u +.. +. +. +.\" === Define strings. === +.\" +.\" These strings must work in compatibility mode also. +. +.ds S \s'\\n(PSu'\" +.ie c\[rg] .ds R \(rg\" +.el .ds R (Reg.)\" +.ie c\[tm] .ds Tm \(tm\" +.el .ds Tm (TM)\" +.ie c\[lq] .ds lq \(lq\" +.el .ds lq ""\" +.ie c\[rq] .ds rq \(rq\" +.el .ds rq ""\" +. +.\" === Define/remap characters. === +. +.\" For UTF-8, map the minus sign to the hyphen-minus to facilitate +.\" copy and paste of code examples, file names, and URLs embedding it. +.if '\*[.T]'utf8' \ +. char \- \N'45' +. +.\" === Initialize. === +. +.mso devtag.tmac +.nr an-devtag-needs-end-of-heading 0 +.nr an-devtag-needs-second-column 0 +. +.\" Track whether the strings that set header and footer text need to be +.\" reconfigured. This happens when batch-rendering and starting a new +.\" page. +.nr an*need-titles-reset 0 +. +.nr an*is-output-html 0 +.if '\*[.T]'html' .nr an*is-output-html 1 +.nr an*is-output-pdf 0 +.if '\*[.T]'pdf' .nr an*is-output-pdf 1 +.nr an*is-output-terminal 0 +.if '\*(.T'ascii' .nr an*is-output-terminal 1 +.if '\*(.T'cp1047' .nr an*is-output-terminal 1 +.if '\*(.T'latin1' .nr an*is-output-terminal 1 +.if '\*(.T'utf8' .nr an*is-output-terminal 1 +. +.nr an*can-hyperlink 0 +.if ( \n[an*is-output-html] \ + : \n[an*is-output-pdf] \ + : \n[an*is-output-terminal]) \ +. nr an*can-hyperlink 1 +. +.ds an*body-family T \" Times +.ds an*example-family C \" Courier +. +.\" Map monospaced fonts to standard styles for groff's nroff devices. +.if n \{\ +. ftr CR R +. ftr CI I +. ftr CB B +. ftr CBI BI +.\} +. +.\" undocumented register; unset to test an-ext.tmac extension macros +.if !r mG \ +. nr mG 1 +. +.\" Load man macro extensions. +.mso an-ext.tmac +. +.\" Load site modifications. +.msoquiet man.local +. +.\" Set each rendering parameter only if its -[dr] option or man.local +.\" did not. +. +.if \n[an*is-output-pdf] \{\ +. \" FIXME: The following registers are documented only in pdf.tmac. +. if !r PDFOUTLINE.FOLDLEVEL .nr PDFOUTLINE.FOLDLEVEL 1 +. if !r PDFHREF.VIEW.LEADING .nr PDFHREF.VIEW.LEADING 10p +.\} +. +.\" continuous rendering (one long page) +.if !r cR \{\ +. ie n .nr cR 1 +. el .nr cR 0 +.\} +. +.\" consecutive page numbering across multiple documents +.\" +.\" We must use consecutive page numbers when using PostScript to +.\" generate HTML images; we must not reset the page number at the +.\" beginning of each document (the 'ps4html' register is automatically +.\" added to the command line by the pre-HTML preprocessor). +.ie !r C \ +. nr C 0 +.el \ +. if !\n[C] \ +. if \n[an*is-output-html] \{\ +. tm \*[an]: consecutive page numbering required for HTML output +. nr C 1 +. \} +.if \n[an*is-output-html] \ +. nr C 1 +.if r ps4html \ +. nr C 1 +. +.\" diagnostics desired for man page style problems +.if !r CHECKSTYLE \ +. nr CHECKSTYLE 0 +. +.\" full capitalization of section headings +.if !r CS \ +. nr CS 0 +. +.\" full capitalization of page topic +.if !r CT \ +. nr CT 0 +. +.\" double-sided layout +.ie !r D \ +. nr D 0 +.el \ +. if \n[D] \ +. if \n[an*is-output-html] \{\ +. tm \*[an]: ignoring double-sided layout in HTML output +. nr D 0 +. \} +. +.\" footer distance +.\" +.\" Unlike most of these parameters, we do not set a default for FT; the +.\" TH macro places page location traps only if not continuously +.\" rendering. +.if r FT \{\ +. \" Validate it. Continuous rendering ignores FT. Measuring a footer +. \" distance from the page top isn't done. A footer distance of over +. \" half the page length is unlikely. A footer distance of less than +. \" one line height is too. +. ie \n[cR] \ +. ds an-msg footer distance when continuously rendering\" +. el \{\ +. nr an*tmp 1v +. ds an*help " (1v=\n[an*tmp]u)\" +. ie (\n[FT] : (\n[FT] = 0)) \ +. ds an-msg non-negative footer distance: \n[FT]u\*[an*help]\" +. el \{\ +. ie (-(\n[FT]) > (\n[.p] / 2)) \{\ +. ds an-msg implausibly large footer distance:\" +. as an-msg " \n[FT]u\*[an*help]\" +. \} +. el \ +. if (-(\n[FT]) < 1v) \{\ +. ds an-msg implausibly small footer distance:\" +. as an-msg " \n[FT]u\*[an*help]\" +. \} +. rm an*help +. rr an*tmp +. \} +. \} +. if d an-msg \{\ +. tm \*[an]: ignoring \*[an-msg] +. rr FT +. rm an-msg +. \} +.\} +. +.\" hyphenation enablement +.if !r HY \ +. nr HY 1 +. +.\" standard indentation +.if !r IN \{\ +. \" We select an integer indentation value in nroff mode because this +. \" value is used additively for multiple purposes; rounding of +. \" accumulating fractions would produce inconsistent results. +. ie t .nr IN 7.2n +. el .nr IN 7n +.\} +. +.\" line length +.if !r LL \{\ +. \" If in troff mode, respect device default. +. ie t .nr LL \n[.l] +. \" Otherwise, override nroff mode default of 65n. +. el .nr LL 78n +.\} +. +.\" title (header, footer) length +.if !r LT \ +. nr LT \n[LL]u +. +.\" starting page number +.\" +.\" Unlike most of these parameters, we do not set a default for P; +.\" troff supplies a default starting page number (1). When rendering +.\" for the HTML output device, page numbers are concealed and used for +.\" internal purposes like image embedding. Page numbers are not +.\" rendered at all in continuous rendering mode. +.if r P \{\ +. if \n[an*is-output-html] \ +. if !(\n[P] = 1) \ +. ds an-msg in HTML output\" +. if \n[cR] \ +. ds an-msg when continuously rendering +.\} +.if d an-msg \{\ +. tm \*[an]: ignoring starting page number \*[an-msg] +. rr P +. rm an-msg +.\} +. +.\" Setting the page number turns out to be tricky when batch rendering +.\" and switching macro packages. We must use different techniques +.\" depending on whether the transition to the first output page has +.\" happened yet. If it has not, `nl` will be `-1` and we use `pn`. If +.\" it has, we set `%`. Technically this is fragile since in theory a +.\" page could assign a negative value to `nl`. We might then be +.\" justified in saying they've broken the macro package and they get to +.\" keep both pieces. But if not, consider using a nonce register, +.\" initially set but then permanently cleared adjacent to this logic, +.\" and whose state is shared with mdoc (and andoc.tmac, if necessary). +.\" +.\" Also, we can't use the `P` register with grohtml at all. +.ie r ps4html \{\ +. if r P \{\ +. tm \*[an]: ignoring starting page number in HTML output +. rr P +. \} +.\} +.el \{\ +. if r P \{\ +. ie (\n[nl] = -1) .pn 0\n[P] +. el .nr % 0\n[P] +. \} +.\} +. +.\" type size +.if !r S \{\ +. nr S 10 +. if '\*[.T]'X75-12' \ +. nr S 12 +. if '\*[.T]'X100-12' \ +. nr S 12 +.\} +. +.\" subsection indentation +.if !r SN \ +. nr SN 3n +. +.\" URI enablement desired +.if !r U \ +. nr U 1 +. +.nr an*do-hyperlink 0 +.if (\n[U] & \n[an*can-hyperlink]) .nr an*do-hyperlink 1 +. +.\" page number after which to apply letter suffixes +.\" +.\" Unlike most of these parameters, we do not set a default for X; only +.\" the macro an-footer uses it. Page numbers are not rendered at all +.\" in continuous rendering mode. +.if r X \{\ +. af an-page-letter a +. if \n[an*is-output-html] \ +. ds an-msg in HTML output\" +. if \n[cR] \ +. ds an-msg when continuously rendering +.\} +.if d an-msg \{\ +. tm \*[an]: ignoring page number suffix \*[an-msg] +. rr X +. rm an-msg +.\} +. +.\" adjustment mode +.if !d AD \ +. ds AD b\" +. +.\" (sub)section heading font +.if !d HF \ +. ds HF B\" +. +.\" If HF is a bold style, use bold italics for italics in headings. +.ds an-heading-style \*[HF]\" +.substring an-heading-style -1 -1 +.ds an-heading-family \" empty +.length an-HF-length \*[HF] +.if (\n[an-HF-length] > 1) \{\ +. as an-heading-family \*[HF]\" +. substring an-heading-family 0 -2 +.\} +.if '\*[an-heading-style]'B' \ +. if F \*[an-heading-family]BI \ +. nr an-remap-I-style-in-headings 1 +.rr an-HF-length +.rm an-heading-style +. +.\" man page topic font +.if !d MF \ +. ds MF I\" +. +.\" Define italic correction strings. Initially, they are empty. If MF +.\" is an oblique style, append the corrections. +.ds an-lic \" left italic correction +.ds an-ic \" italic correction +.ds an*topic-style \*[MF]\" +.substring an*topic-style -1 -1 +.if '\*[an*topic-style]'I' \{\ +. as an-lic \,\" +. as an-ic \/\" +.\} +.rm an*topic-style +. +.if \n[cR] \ +. an-set-up-continuous-rendering +. +.\" If rendering HTML, suppress headers and footers. +.nr an-suppress-header-and-footer 0 +.if \n[an*is-output-html] .nr an-suppress-header-and-footer 1 +.if r ps4html .nr an-suppress-header-and-footer 1 +. +.cp \n[*groff_an_tmac_C] +.do rr *groff_an_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/andoc.tmac b/tmac/andoc.tmac new file mode 100644 index 0000000..2778a29 --- /dev/null +++ b/tmac/andoc.tmac @@ -0,0 +1,115 @@ +.\" andoc.tmac +.\" +.\" Load either an.tmac or doc.tmac. Multiple man pages can be handled. +.\" +.\" +.\" Copyright (C) 1991-2020 Free Software Foundation, Inc. +.\" Written by Werner Lemberg (wl@gnu.org), +.\" based on a patch from Tadziu Hoffmann. +.\" +.\" This file 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 +.\" . +.\" +. +.if !\n(.g \ +. ab andoc.tmac: macros require groff extensions; aborting +. +.do nr *groff_andoc_tmac_C \n[.cp] +.cp 0 +. +.als andoc-em em +.als andoc-bp bp +.als andoc-ne ne +. +. +.\" We must not use '.de1' for 'reload-doc' or 'reload-man'! 'doc.tmac' +.\" unconditionally switches compatibility mode off, but '.de1' would +.\" ignore this, restoring the mode that was active before. Similarly, +.\" we have to switch back to the original compatibility mode for man +.\" documents in case there is a mix of mdoc and man input files. +.\" +.\" Due to a bug in GNU troff it necessary to have a no-op line between +.\" '.do' and '\*'. +. +. +.de reload-doc +. \" Flush any partially collected output line and write page footer in +. \" continuous rendering mode. +. do if d an-end \ +. do an-end +. +. \" Remove traps planted by an.tmac. +. do ch an-header +. do ch an-break-body-text +. do ch an-footer +. +. do als em andoc-em +. do als bp andoc-bp +. do als ne andoc-ne +. do blm \" no blank line trap +. do lsm \" no leading space trap +. em \" no end-of-input trap +. +. do rm Dd \" force reinitialization of doc.tmac +. do mso doc.tmac +. +. do als TH reload-man +. +\\*(Dd\\ +.. +. +.de reload-man +. \" Flush any partially collected output line and write page footer in +. \" continuous rendering mode. +. do if d doc-end-macro \ +. do doc-end-macro +. +. \" Remove traps planted by mdoc/doc-{common,{n,dit}roff}. +. do ch doc-break-body-text +. do ch doc-header +. do ch doc-footer +. +. do als em andoc-em +. do als bp andoc-bp +. do als ne andoc-ne +. do blm \" no blank line trap +. em \" no end-of-input trap +. +. do rm TH \" force reinitialization of an.tmac +. do mso an.tmac +. +. do als Dd reload-doc +. +\\*(TH\\ +.. +. +.als TH reload-man +.als Dd reload-doc +. +.\" dummy equation macros -- eqnrc is read before .TH or .Dd is parsed +.de EQ +.. +.de EN +.. +. +.cp \n[*groff_andoc_tmac_C] +.do rr *groff_andoc_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/composite.tmac b/tmac/composite.tmac new file mode 100644 index 0000000..87ffe50 --- /dev/null +++ b/tmac/composite.tmac @@ -0,0 +1,30 @@ +.\" composite.tmac +. +.do composite ga u0300 +.do composite ` u0300 +.do composite aa u0301 +.do composite ' u0301 +.do composite a^ u0302 +.do composite ^ u0302 +.do composite a~ u0303 +.do composite ~ u0303 +.do composite a- u0304 +.do composite - u0304 +.do composite ab u0306 +.do composite a. u0307 +.do composite . u0307 +.do composite ad u0308 +.do composite : u0308 +.do composite ao u030A +.do composite a" u030B +.do composite " u030B +.do composite ah u030C +.do composite ac u0327 +.do composite , u0327 +.do composite ho u0328 +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/cp1047.tmac b/tmac/cp1047.tmac new file mode 100644 index 0000000..0e04194 --- /dev/null +++ b/tmac/cp1047.tmac @@ -0,0 +1,108 @@ +.\" cp1047.tmac +.\" +.do nr *groff_cp1047_tmac_C \n[.cp] +.cp 0 +.\" char65 (no-break space) is translated on input +.trin \[char66]\[^a] +.trin \[char67]\[:a] +.trin \[char68]\[`a] +.trin \[char69]\['a] +.trin \[char70]\[~a] +.trin \[char71]\[oa] +.trin \[char72]\[,c] +.trin \[char73]\[~n] +.trin \[char74]\[ct] +.trin \[char81]\['e] +.trin \[char82]\[^e] +.trin \[char83]\[:e] +.trin \[char84]\[`e] +.trin \[char85]\['i] +.trin \[char86]\[^i] +.trin \[char87]\[:i] +.trin \[char88]\[`i] +.trin \[char89]\[ss] +.trin \[char98]\[^A] +.trin \[char99]\[:A] +.trin \[char100]\[`A] +.trin \[char101]\['A] +.trin \[char102]\[~A] +.trin \[char103]\[oA] +.trin \[char104]\[,C] +.trin \[char105]\[~N] +.trin \[char106]\[bb] +.trin \[char112]\[/o] +.trin \[char113]\['E] +.trin \[char114]\[^E] +.trin \[char115]\[:E] +.trin \[char116]\[`E] +.trin \[char117]\['I] +.trin \[char118]\[^I] +.trin \[char119]\[:I] +.trin \[char120]\[`I] +.trin \[char128]\[/O] +.trin \[char138]\[Fo] +.trin \[char139]\[Fc] +.trin \[char140]\[Sd] +.trin \[char141]\['y] +.trin \[char142]\[Tp] +.trin \[char143]\[t+-] +.trin \[char144]\[de] +.trin \[char154]\[Of] +.trin \[char155]\[Om] +.trin \[char156]\[ae] +.trin \[char157]\[ac] +.trin \[char158]\[AE] +.trin \[char159]\[Cs] +.trin \[char160]\[mc] +.trin \[char170]\[r!] +.trin \[char171]\[r?] +.trin \[char172]\[-D] +.trin \[char174]\[TP] +.trin \[char175]\[rg] +.trin \[char176]\[tno] +.trin \[char177]\[Po] +.trin \[char178]\[Ye] +.trin \[char179]\[pc] +.trin \[char180]\[co] +.trin \[char181]\[sc] +.trin \[char182]\[ps] +.trin \[char183]\[14] +.trin \[char184]\[12] +.trin \[char185]\[34] +.trin \[char186]\['Y] +.trin \[char187]\[ad] +.trin \[char188]\[a-] +.trin \[char190]\[aa] +.trin \[char191]\[tmu] +.\" char202 (soft hyphen) is translated on input +.trin \[char203]\[^o] +.trin \[char204]\[:o] +.trin \[char205]\[`o] +.trin \[char206]\['o] +.trin \[char207]\[~o] +.trin \[char218]\[S1] +.trin \[char219]\[^u] +.trin \[char220]\[:u] +.trin \[char221]\[`u] +.trin \[char222]\['u] +.trin \[char223]\[:y] +.trin \[char225]\[tdi] +.trin \[char234]\[S2] +.trin \[char235]\[^O] +.trin \[char236]\[:O] +.trin \[char237]\[`O] +.trin \[char238]\['O] +.trin \[char239]\[~O] +.trin \[char250]\[S3] +.trin \[char251]\[^U] +.trin \[char252]\[:U] +.trin \[char253]\[`U] +.trin \[char254]\['U] +.cp \n[*groff_cp1047_tmac_C] +.do rr *groff_cp1047_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/cs.tmac b/tmac/cs.tmac new file mode 100644 index 0000000..725c1cf --- /dev/null +++ b/tmac/cs.tmac @@ -0,0 +1,214 @@ +.\" Czech localization for groff +.\" +.\" Copyright (C) 2007-2022 Free Software Foundation, Inc. +.\" Written by Marcela Mašláňová (mmaslano@redhat.com) +.\" +.\" This file 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 +.\" . +.\" +.\" Please send comments to mmaslano@redhat.com. +. +.do nr *groff_cs_tmac_C \n[.cp] +.cp 0 +. +. +.\" If changing from an existing locale, we need to preserve the state +.\" of the "suppress hyphenation before a page location trap" bit. +.nr locale*use-trap-hyphenation-mode 0 +.if d locale \ +. if \n[.hy]=\n[\*[locale]*hyphenation-mode-trap] \ +. nr locale*use-trap-hyphenation-mode 1 +. +. +.ds locale czech\" +. +. +.\" Predefined text translations +. +.ds \*[locale]-abstract ABSTRAKT\" +.ds \*[locale]-app DODATEK\" +.ds \*[locale]-appendix_string Dodatek\" +.ds \*[locale]-april Duben\" +.ds \*[locale]-attribute_string z\" +.ds \*[locale]-august Říjen\" +.ds \*[locale]-chapter_string Kapitola\" +.ds \*[locale]-december Prosinec\" +.ds \*[locale]-draft_string Koncept\" +.ds \*[locale]-endnote_string POZNÁMKY\" +.ds \*[locale]-february Únor\" +.ds \*[locale]-finis_string KONEC\" +.ds \*[locale]-friday Pátek\" +.ds \*[locale]-january Leden\" +.ds \*[locale]-july Červenec\" +.ds \*[locale]-june Červen\" +.ds \*[locale]-le SEZNAM ROVNIC\" +.ds \*[locale]-letapp LICENCE\" +.ds \*[locale]-letat ADRESÁT:\" +.ds \*[locale]-letcn DŮVĚRNĚ\" +.ds \*[locale]-letdate Datum\" +.ds \*[locale]-letfc S úctou,\" +.ds \*[locale]-letns!0 Kopie\" +.ds \*[locale]-letns!1 Kopie (příjemci)\" +.ds \*[locale]-letns!10 Kopie (příjemcům)\" +.ds \*[locale]-letns!11 Kopie (bez příjemců) \[a `]\" +.ds \*[locale]-letns!12 Shrnutí\" +.ds \*[locale]-letns!13 Celková zpráva\" +.ds \*[locale]-letns!14 Cc:\" +.ds \*[locale]-letns!2 Kopie (bez příjemce)\" +.ds \*[locale]-letns!3 Dodatek\" +.ds \*[locale]-letns!4 Dodatky\" +.ds \*[locale]-letns!5 Příloha\" +.ds \*[locale]-letns!6 Přílohy\" +.ds \*[locale]-letns!7 Separátní\" +.ds \*[locale]-letns!8 Dopis\" +.ds \*[locale]-letns!9 Zpráva\" +.ds \*[locale]-letns!copy Kopie \" (neodstraňovat mezeru)\" +.ds \*[locale]-letns!to " pro\" +.ds \*[locale]-letrn Vzhldem k:\" +.ds \*[locale]-letsa Do vlastních rukou:\" +.ds \*[locale]-letsj TÉMA:\" +.ds \*[locale]-lf REJSTŘÍK ILUSTRACÍ\" +.ds \*[locale]-licon REJSTŘÍK\" +.ds \*[locale]-liec Citace\" +.ds \*[locale]-liex Dokument\" +.ds \*[locale]-lifg Ilustrace\" +.ds \*[locale]-litb Tabulka\" +.ds \*[locale]-lt REJSTŘÍK TABULEK\" +.ds \*[locale]-lx REJSTŘÍK DOKUMENTŮ\" +.ds \*[locale]-man-section1 Manuál uživatelských příkazů\" +.ds \*[locale]-man-section2 Manuál systémových volání\" +.ds \*[locale]-man-section3 Manuál funkcí knihovny\" +.ds \*[locale]-man-section4 Manuál rozhraní jádra\" +.ds \*[locale]-man-section5 Manuál pro formáty souborů\" +.ds \*[locale]-man-section6 Herní manuál\" +.ds \*[locale]-man-section7 Různé informační manuál\" +.ds \*[locale]-man-section8 Manuál správce systému\" +.ds \*[locale]-man-section9 Manuál vývojáře jádra\" +.ds \*[locale]-march Březen\" +.ds \*[locale]-may Květen\" +.ds \*[locale]-monday Pondělí\" +.ds \*[locale]-november Listopad\" +.ds \*[locale]-october Říjen\" +.ds \*[locale]-paper A4\" +.ds \*[locale]-qrf Viz. kapitola\~\\*[Qrfh], stránka\~\\*[Qrfp].\" +.ds \*[locale]-references Literatura\" +.ds \*[locale]-revision_string Rev.\" +.ds \*[locale]-rp LITERATURA\" +.ds \*[locale]-saturday Sobota\" +.ds \*[locale]-september Září\" +.ds \*[locale]-sunday Neděle\" +.ds \*[locale]-thursday Čtvrtek\" +.ds \*[locale]-toc Seznam literatury\" +.ds \*[locale]-toc_header_string Seznam literatury\" +.ds \*[locale]-tuesday Úterý\" +.ds \*[locale]-wednesday Středa\" +. +. +.\" Activate the translations +. +.mso trans.tmac +. +. +.\" ms package +.if r GS \{\ +. \" update the date +. ds DY \n[dy] \*[MO] \n[year] +. \" set hyphenation flags +. nr HY 2 +.\} +. +. +.\" mm package +.if d PH \{\ +. \" update the date with the new strings +. ds cov*new-date \\n[dy] \\*[MO\\n[mo]] \\n[year] +. +. \" ISODATE and DT update +. de ISODATE +. nr cov*mm \\n[mo] +. nr cov*dd \\n[dy] +. af cov*mm 01 +. af cov*dd 01 +. ie '0'\\$1' \ +. ds cov*new-date \\n[dy] \\*[MO\\n[mo]] \\n[year] +. el \ +. ds cov*new-date \\n[year]-\\n[cov*mm]-\\n[cov*dd] +. . +. +. als DT cov*new-date +.\} +. +. +.\" Default encoding +.mso latin2.tmac +. +.ss 12 0 +. +.\" Set up hyphenation. +. +.\" Czech hyphenation (\lefthyphenmin=2, \righthyphenmin=2) +.nr \*[locale]*hyphenation-mode-base 1 +.nr \*[locale]*hyphenation-mode-trap 2 +. +.ie \n[locale*use-trap-hyphenation-mode] \ +. hy \n[\*[locale]*hyphenation-mode-trap] +.el \ +. hy \n[\*[locale]*hyphenation-mode-base] +. +.rr locale*use-trap-hyphenation-mode +. +.hcode á á Á á +.hcode č č Č č +.hcode ď ď Ď ď +.hcode é é É é +.hcode ě ě Ě ě +.hcode í í Í í +.hcode ň ň Ň ň +.hcode ó ó Ó ó +.hcode ř ř Ř ř +.hcode š š Š š +.hcode ť ť Ť ť +.hcode ú ú Ú ú +.hcode ů ů Ů ů +.hcode ý ý Ý ý +.hcode ž ž Ž ž +. +.hla cs +.hpf hyphen.cs +.hpfa hyphenex.cs +. +. +.\" man package +.if d an \ +. an*reset-hyphenation-mode +. +. +.\" me package +.if d @R \{\ +. ds _td_format \En(dy \E*(mo \En(y4 +. ld +.\} +. +. +.cp \n[*groff_cs_tmac_C] +.do rr *groff_cs_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" coding: latin-2 +.\" fill-column: 72 +.\" End: +.\" vim: set fileencoding=iso-8859-2 filetype=groff textwidth=72: diff --git a/tmac/de.tmac b/tmac/de.tmac new file mode 100644 index 0000000..aaa97cb --- /dev/null +++ b/tmac/de.tmac @@ -0,0 +1,218 @@ +.\" German localization for groff +.\" +.\" Copyright (C) 2006-2022 Free Software Foundation, Inc. +.\" Written by Werner Lemberg (wl@gnu.org) +.\" +.\" This file 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 +.\" . +.\" +.\" Please send comments to groff@gnu.org. +. +.do nr *groff_de_tmac_C \n[.cp] +.cp 0 +. +. +.\" If changing from an existing locale, we need to preserve the state +.\" of the "suppress hyphenation before a page location trap" bit. +.nr locale*use-trap-hyphenation-mode 0 +.if d locale \ +. if \n[.hy]=\n[\*[locale]*hyphenation-mode-trap] \ +. nr locale*use-trap-hyphenation-mode 1 +. +. +.ds locale german\" +. +. +.\" Predefined text translations +. +.ds \*[locale]-abstract Zusammenfassung\" +.ds \*[locale]-app Anhang\" +.ds \*[locale]-appendix_string Anhang\" +.ds \*[locale]-april April\" +.ds \*[locale]-attribute_string von\" +.ds \*[locale]-august August\" +.ds \*[locale]-chapter_string Kapitel\" +.ds \*[locale]-december Dezember\" +.ds \*[locale]-draft_string Entwurf\" +.ds \*[locale]-endnote_string Bemerkungen\" +.ds \*[locale]-february Februar\" +.ds \*[locale]-finis_string Ende\" +.ds \*[locale]-friday Freitag\" +.ds \*[locale]-january Januar\" +.ds \*[locale]-july Juli\" +.ds \*[locale]-june Juni\" +.ds \*[locale]-le Verzeichnis der Gleichungen\" +.ds \*[locale]-letapp Genehmigt:\" +.ds \*[locale]-letat An\" +.ds \*[locale]-letcn Vertraulich\" +.ds \*[locale]-letdate Datum\" +.ds \*[locale]-letfc Hochachtungsvoll\" +.ds \*[locale]-letns!0 Kopie an\" +.ds \*[locale]-letns!1 Kopie (mit Anhang) an\" +.ds \*[locale]-letns!10 Kopie (mit Anhängen) an\" +.ds \*[locale]-letns!11 Kopie (ohne Anhänge) an\" +.ds \*[locale]-letns!12 Nur Zusammenfassung an\" +.ds \*[locale]-letns!13 Kompletter Bericht an\" +.ds \*[locale]-letns!14 Cc:\" +.ds \*[locale]-letns!2 Kopie (ohne Anhang) an\" +.ds \*[locale]-letns!3 Anhang\" +.ds \*[locale]-letns!4 Anhänge\" +.ds \*[locale]-letns!5 Beilage\" +.ds \*[locale]-letns!6 Beilagen\" +.ds \*[locale]-letns!7 Separat\" +.ds \*[locale]-letns!8 Brief an\" +.ds \*[locale]-letns!9 Bericht an\" +.ds \*[locale]-letns!copy Kopie \" don't remove the space!) +.ds \*[locale]-letns!to " an\" +.ds \*[locale]-letrn In Bezug auf:\" +.ds \*[locale]-letsa An die zuständige Abteilung:\" +.ds \*[locale]-letsj Betreff:\" +.ds \*[locale]-lf Verzeichnis der Abbildungen\" +.ds \*[locale]-licon Inhalt\" +.ds \*[locale]-liec Gleichung\" +.ds \*[locale]-liex Beleg\" +.ds \*[locale]-lifg Abbildung\" +.ds \*[locale]-litb Tabelle\" +.ds \*[locale]-lt Verzeichnis der Tabellen\" +.ds \*[locale]-lx Verzeichnis der Belege\" +.ds \*[locale]-man-section1 Handbuch für allgemeine Befehle\" +.ds \*[locale]-man-section2 Handbuch für Systemaufrufe\" +.ds \*[locale]-man-section3 Handbuch zu Bibliotheksfunktionen\" +.ds \*[locale]-man-section4 Handbuch zu Kernel-Schnittstellen\" +.ds \*[locale]-man-section5 Handbuch zu Dateiformaten\" +.ds \*[locale]-man-section6 Spielehandbuch\" +.ds \*[locale]-man-section7 Sonstiges Informationshandbuch\" +.ds \*[locale]-man-section8 Handbuch des Systemmanagers\" +.ds \*[locale]-man-section9 Handbuch für Kernel-Entwickler\" +.ds \*[locale]-march März\" +.ds \*[locale]-may Mai\" +.ds \*[locale]-monday Montag\" +.ds \*[locale]-november November\" +.ds \*[locale]-october Oktober\" +.ds \*[locale]-paper A4\" +.ds \*[locale]-qrf Siehe Kapitel\~\\*[Qrfh], Seite\~\\*[Qrfp].\" +.ds \*[locale]-references Literaturverzeichnis\" +.ds \*[locale]-revision_string Rev.\" +.ds \*[locale]-rp Literaturverzeichnis\" +.ds \*[locale]-saturday Samstag\" +.ds \*[locale]-september September\" +.ds \*[locale]-sunday Sonntag\" +.ds \*[locale]-thursday Donnerstag\" +.ds \*[locale]-toc Inhaltsverzeichnis\" +.ds \*[locale]-toc_header_string Inhaltsverzeichnis\" +.ds \*[locale]-tuesday Dienstag\" +.ds \*[locale]-wednesday Mittwoch\" +. +. +.\" Activate the translations +. +.mso trans.tmac +. +. +.\" ms package +.if r GS \{\ +. \" update the date +. ds DY \n[dy].\~\*[MO] \n[year] +. \" set hyphenation flags +. nr HY 2 +.\} +. +. +.\" mm package +.if d PH \{\ +. \" update the date with the new strings +. ds cov*new-date \\n[dy].\& \\*[MO\\n[mo]] \\n[year] +. +. \" ISODATE and DT update +. de ISODATE +. nr cov*mm \\n[mo] +. nr cov*dd \\n[dy] +. af cov*mm 01 +. af cov*dd 01 +. ie '0'\\$1' \ +. ds cov*new-date \\n[dy].\~\\*[MO\\n[mo]] \\n[year] +. el \ +. ds cov*new-date \\n[year]-\\n[cov*mm]-\\n[cov*dd] +. . +. +. als DT cov*new-date +.\} +. +. +.\" Default encoding +.mso latin1.tmac +. +.ss 12 0 +. +.\" Set up hyphenation. +. +.\" German hyphenation (\lefthyphenmin=2, \righthyphenmin=2) +.nr \*[locale]*hyphenation-mode-base 1 +.nr \*[locale]*hyphenation-mode-trap 2 +. +.ie \n[locale*use-trap-hyphenation-mode] \ +. hy \n[\*[locale]*hyphenation-mode-trap] +.el \ +. hy \n[\*[locale]*hyphenation-mode-base] +. +.rr locale*use-trap-hyphenation-mode +. +.hcode ä ä â â ŕ ŕ á á ă ă ĺ ĺ ć ć +.hcode ç ç +.hcode é é č č ë ë ę ę +.hcode í í ě ě î î ď ď +.hcode ń ń +.hcode ó ó ň ň ô ô ö ö ř ř +.hcode ú ú ü ü ű ű +. +.hcode Ä ä Â â Ŕ ŕ Á á Ă ă Ĺ ĺ Ć ć +.hcode Ç ç +.hcode É é Č č Ë ë Ę ę +.hcode Í í Ě ě Î î Ď ď +.hcode Ń ń +.hcode Ó ó Ň ň Ô ô Ö ö Ř ř +.hcode Ú ú Ü ü Ű ű +. +.hcode ß ß +. +.hla de +.ie r \*[locale]-new-hyphenation-patterns \ +. hpf hyphen.den +.el \ +. hpf hyphen.det +. +. +.\" man package +.if d an \ +. an*reset-hyphenation-mode +. +. +.\" me package +.if d @R \{\ +. ds _td_format \En(dy.\~\E*(mo.\& \En(y4 +. ld +.\} +. +. +.cp \n[*groff_de_tmac_C] +.do rr *groff_de_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" coding: latin-1 +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/den.tmac b/tmac/den.tmac new file mode 100644 index 0000000..813e15b --- /dev/null +++ b/tmac/den.tmac @@ -0,0 +1,31 @@ +.\" German localization for groff (new orthography) +.\" +.\" Copyright (C) 2006-2020 Free Software Foundation, Inc. +.\" Written by Werner Lemberg (wl@gnu.org) +.\" +.\" This file 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 +.\" . +.\" +.\" Please send comments to groff@gnu.org. +. +.do nr german-new-hyphenation-patterns 1 +.do mso de.tmac +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/devtag.tmac b/tmac/devtag.tmac new file mode 100644 index 0000000..8a6204a --- /dev/null +++ b/tmac/devtag.tmac @@ -0,0 +1,124 @@ +.ig +devtag.tmac - macro package for adding tags to roff documents. + +------------------------------------------------------------------------ + Legalese +------------------------------------------------------------------------ + +This file is part of groff, the GNU roff type-setting system. + +Copyright (C) 2004-2020 Free Software Foundation, Inc. +written by Gaius Mulley . + +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 . + + +------------------------------------------------------------------------ + Description +------------------------------------------------------------------------ + +A simple set of macros to provide markup devices (currently only +grohtml) with tags that define the meaning of the formatted text and +also basic formatting instructions. It generalizes the tag concept used +within grohtml and in the future it is hoped that more markup based +devices can capitalize on this work. It also clearly defines those tags +which are honoured by grohtml. Note that not all tags are included +here. Some of the grohtml specific tags (header specific and jobname, +etc.) are called directly from within www.tmac. The tags defined here +are reasonably generic and could be applied to other devices. +.. +. +.do if d DEVTAG-NH .nx +. +.do nr *groff_devtag_tmac_C \n[.cp] +.cp 0 +. +.\" -------------------------------------------------------------------- +.\" DEVTAG +.\" +.\" Emit a tag +.\" +.de1 DEVTAG +. tag devtag:\\$* +.. +.\" -------------------------------------------------------------------- +.\" DEVTAG-NEXT +.\" +.\" When the troff state changes, emit tag +.\" +.de1 DEVTAG-NEXT +. taga devtag:\\$* +.. +. +.\" -------------------------------------------------------------------- +.\" SH +.\" NH +.\" tell device we are starting a numbered heading +.\" Takes a single parameter . 1 +.\" is the outer most level. +. +.de1 DEVTAG-NH +. DEVTAG ".NH \\$1" +.. +.als DEVTAG-SH DEVTAG-NH +. +.\" -------------------------------------------------------------------- +.\" COL +.\" indicate that the following text is aligned for the column +.\" n: [1..MAX(n)] +. +.de1 DEVTAG-COL +. DEVTAG ".col \\$1" +.. +. +.\" -------------------------------------------------------------------- +.\" EO-H +.\" indicate that a header has finished. +. +.de1 DEVTAG-EO-H +. DEVTAG ".eo.h" +.. +.\" -------------------------------------------------------------------- +.\" EO-TL +.\" indicate that a title has finished. +. +.de1 DEVTAG-EO-TL +. DEVTAG ".eo.tl" +.. +.\" -------------------------------------------------------------------- +.\" TL +.\" indicate that the following text forms a title. +. +.de1 DEVTAG-TL +. DEVTAG ".tl" +.. +. +.\" -------------------------------------------------------------------- +.\" COL-NEXT +.\" emit a column tag just before the next glyph. +. +.de1 DEVTAG-COL-NEXT +. DEVTAG-NEXT ".col \\$1" +.. +. +. +.cp \n[*groff_devtag_tmac_C] +.do rr *groff_devtag_tmac_C +. +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/doc-old.tmac b/tmac/doc-old.tmac new file mode 100644 index 0000000..e6bd74f --- /dev/null +++ b/tmac/doc-old.tmac @@ -0,0 +1,1862 @@ +.\" Copyright (c) 1990 The Regents of the University of California. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" 3. [Deleted. See +.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] +.\" 4. Neither the name of the University nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" +.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +.\" PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR +.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)doc-old.tmac 5.2 (Berkeley) 3/13/91 +.\" Slightly modified by jjc@jclark.com to work with groff as well. +.\" +.\" Assume nroff on crt's only if cR==1 +.if n .nr cR 1 +.\" STRING CONSTANTS +.\" DITROFF +.if t \{\ +.\" Address Style +.ds aD \fI +.\" Argument Reference Style +.ds aR \f(CO +.\" Interactive Command Modifier (flag) +.ds cM \f(CB +.\" Emphasis (in the English sense - usually italics) +.ds eM \fI +.\" Errno Style +.ds eR \fC +.\" Environment Variable Style +.ds eV \fC +.\" Command Line Flag Style +.ds fL \f(CB +.\" Header String Style +.ds Hs \fR +.\" Interactive Command Style +.ds iC \f(CB +.\" Literal Style +.ds lI \fC +.\" Left Parenthesis Style +.ds lP \fR\|(\|\fP +.\" Right Parenthesis Style +.ds rP \fR\|)\|\fP +.\" Options Open Bracket Style +.ds lB \fR\^[\^\fP +.\" Options Open Bracket Style +.ds rB \fR\^]\fP +.\" Name (subject of manpage) Style +.ds nM \f(CB +.\" Pathname Style +.ds pA \fC +.\" Accepted punctuation string for -mdoc syntax +.ds Pu \fR[.,:;(\^)[\^]\fR] +.\" Section Header Style +.ds Sp \s12\fB +.\" .ds sT \s-2\fR +.\" Symbolic Emphasis (boldface) +.ds sY \f(CB +.\" Generic Variable Style +.ds vA \fI +.\" Volume Title Style +.ds Vs \fR +.\" Cross Reference STyle (man page only) +.ds xR \fC +.\" Math * +.tr *\(** +.\} +.\" NROFF +.if n \{\ +.\" Address Style +.ds aD \fI +.\" Argument Reference Style +.ds aR \fI +.\" Interactive Command Modifier (flag) +.ds cM \fB +.\" Emphasis (in the English sense - usually italics) +.ds eM \fI +.\" Errno Style +.ds eR \fR +.\" Environment Variable Style +.ds eV \fR +.\" Command Line Flag Style +.ds fL \fB +.\" Header String Style +.ds Hs \fR +.\" Interactive Command Style +.ds iC \fB +.\" Literal Style +.ds lI \fR +.\" Left Parenthesis Style +.ds lP \fR\|(\fP +.\" Right Parenthesis Style +.ds rP \fR\|)\fP +.\" Options Open Bracket Style +.ds lB \fR\|[\|\fP +.\" Options Open Bracket Style +.ds rB \fR\|]\fP +.\" Name (subject of manpage) Style +.ds nM \fB +.\" Pathname Style +.ds pA \fI +.\" Accepted punctuation string for -mdoc syntax +.ds Pu [.,;:()[]] +.\" Section Header Style +.ds Sp \s12\fB +.\" .ds sT \s-2\fR +.\" .ds sT \s-2\fR +.\" Symbol, Mode or Mask Style +.ds sY \fB +.\" Generic Variable Style +.ds vA \fI +.\" Volume Title Style +.ds Vs \fR +.\" Cross Reference Style (man page only) +.ds xR \fR +.\} +.\" INDENTS - Subheaders(sI), Text(Ti) between Section Headers and Subsects +.if t \{\ +. nr sI \w'\fC,'u*5 +. nr Ti \n(sIu +.\} +.if n \{\ +. nr sI .5i +. nr Ti .5i +.\} +.\" Flags for macros names which are used only for .Ds +.nr dI 6n +.nr dC 1 +.nr dL 1 +.nr dR 1 +.\" INDENT WIDTHS (for Lists) +.\" Width Needed for Address Tag (indented amount) +.nr Ad 12n +.\" Angle Quote Width +.nr Aq 12n +.\" Width Needed for Argument +.nr Ar 12n +.\" Width Needed for Column offset +.nr Cl 15n +.\" Width needed for Interactive Command Modifier +.nr Cm 10n +.\" Width Needed for Complex Expressions +.nr Cx 20n +.\" Indent Width Needed for Display (right and left margins) +.nr Ds 6n +.\" Double Quote Width +.nr Dq 12n +.\" tI is dependent on Ds and used by .Dp +.nr tI \n(Dsu +.\" Width Needed for Display +.nr Em 10n +.\" Width Needed for Errno Types +.nr Er 15n +.\" Width Needed for Environment Variables +.nr Ev 15n +.\" Width Needed for Example Indent +.nr Ex 10n +.\" Width Needed for Flag +.nr Fl 10n +.\" Width Needed for Function +.nr Fn 16n +.\" Width needed for Interactive Command Name +.nr Ic 10n +.\" Width Needed for Constant +.nr Li 16n +.\" Width Needed for Math Symbol ? not sure if needed +.nr Ms 6n +.\" Width Needed for Name +.nr Nm 10n +.\" Width Needed for Option Begin +.nr Ob 14n +.\" Width Needed for Option End +.nr Oe 14n +.\" Width Needed for Option (one line) +.nr Op 14n +.\" Width Needed for Pathname +.nr Pa 32n +.\" Parenthesis Quote Width +.nr Pq 12n +.\" Single Quote Width +.nr Sq 12n +.\" Width Needed for Symbols, Modes or Masks +.nr Sy 6n +.\" Width needed for default or unknown text width +.nr Tx 22n +.\" Width Needed for Generic Variable +.nr Va 12n +.\" Width Needed for Cross Reference, should the cross ref be annotated. +.nr Xr 10n +.\" PARAGRAPH SPACE +.if t \{\ +. nr Pp .5v +.\} +.if n \{\ +. nr Pp 1v +.\} +.\" PAGE LAYOUT +.\" .Li Tagged Paragraph Style - zero if break on oversized tag +.\" one if add em space and continue filling line. +.nr tP 0 +.\" Page Layout Macro +.de pL +.\" DITROFF +.ie t \{\ +.\" Header Margin +. nr Hm .5i +.\" Footer Margin +. nr Fm .5i +.\" Line length +. nr ll 5.5i +.\" Line length +. ll 5.5i +.\" Title length +. nr lt 5.5i +.\" Title length +. lt 5.5i +.\" Page offset +. nr po 1.56i +.\" Page offset +. po 1.56i +.\" Vertical space distance (from Section headers/Lists/Subsections) +. nr vV .5v +.\" em space +. ds tP \|\|\|\|\|\| +.\} +.el \{\ +.\" Line length +. nr ll 78n +. ll 78n +.\" Title length +. nr lt 78n +.\" Title length +. lt 78n +.\" Page offset +. nr po 0i +.\" Page offset +. po 0i +.\" Vertical space distance (from Section headers/Lists/Subsections) +. nr vV 1v +.\" em space +. ds tP \0\0 +.\" Test for crt +. ie \\n(cR .nr Hm 0 +. el .nr Hm .5i +.\" Footer Margin +. nr Fm .5i +.\} +.. +.\" Adjustment mode +.if n \{\ +.ad l +.na +.. +.\} +.\" PREDEFINED STRINGS +.if t \{\ +. ds <= \(<= +. ds >= \(>= +. ds Lq \&`` +. ds Rq \&'' +. ds ua \(ua +. ds aa \(aa +. ds ga \(ga +. ds sR \(aa +. ds sL \(ga +.\} +.if n \{\ +. ds <= \&<\&= +. ds >= \&>\&= +. ds Rq '' +. ds Lq `` +. ds ua ^ +. ds aa ' +. ds ga ` +. ds sL ` +. ds sR ' +.\} +.\" Note: The distances from the bottom or top of the page are set +.\" in headers (macro .hK): to -1.25 for troff, and -1.167 for nroff +.\" bottoms, and top is 0. +.\" +.\" .Dt Document/manpage_title section/chapter volume +.\" The \{ and \} is necessary as roff doesn't nest if-elses +.\" properly, especially with .ds. +.\" TODO: separate Dt into Dt, Ch and Vt for supp docs. +.de Dt +.ds dT UNTITLED +.ds vT Local +.ds cH Null +.\" Volume and Section Number or Chapter Number +.if !"\\$1"" .ds dT \\$1 +.if !"\\$2"" \{\ +. ds cH \\$2 +. if "\\$3"" \{\ +. \" Volume Title if none given +. if \\$2>=1 .if \\$2<=8 \{\ +. ds vT UNIX Reference Manual +. if \\$2>1 .if \\$2<6 .ds vT UNIX Programmer's Manual +. if "\\$2"8" .ds vT UNIX System Manager's Manual +. \} +. if "\\$2"unass" .ds vT DRAFT +. if "\\$2"draft" .ds vT DRAFT +. if "\\$2"paper" .ds vT Null +. \} +.\} +.if !"\\$3"" \{\ +. \" Volume Title if given +. if "\\$3"USD" .ds vT UNIX User's Supplementary Documents +. if "\\$3"PS1" .ds vT UNIX Programmers's Supplementary Documents +. if "\\$3"AMD" .ds vT UNIX Ancestral Manual Documents +. if "\\$3"SMM" .ds vT UNIX System Manager's Manual +. if "\\$3"URM" .ds vT UNIX Reference Manual +. if "\\$3"PRM" .ds vT UNIX Programmers's Manual +. if "\\$3"IND" .ds vT UNIX Manual Master Index +. if "\\$3"CON" .ds vT UNIX Contributed Software Manual +. if "\\$3"IMP" .ds vT UNIX Implementation Notes +. if "\\$3"HOW" .ds vT UNIX How Pocket Manual +. if "\\$3"LOCAL" .ds vT UNIX Local Manual +. if "\\*(vT"Local" .ds vT \\$3 +.\} +.. +.\" +.\" .Os Operating System/Standard and Release or Version Number +.\" +.de Os +.ds oS Null +.if "\\$1"" \{\ +. ds oS \fIBSD Experimental\fP +.\" . ds oS (\fIBag o' Bits\fP) +.\} +.if "\\$2"" \{\ +. ds o1 Non-Null +.\} +.if "\\$1"ATT" \{\ +. ds oS AT&T +. if "\\$2"" .as oS \0UNIX +. if "\\$2"7th" .as oS \07th Edition +. if "\\$2"7" .as oS \07th Edition +. if "\\$2"III" .as oS \0System III +. if "\\$2"3" .as oS \0System III +. if "\\$2"V" .as oS \0System V +. if "\\$2"V.2" .as oS \0System V Release 2 +. if "\\$2"V.3" .as oS \0System V Release 3 +. if "\\$2"V.4" .as oS \0System V Release 4 +.\} +.if "\\$1"BSD" \{\ +. if "\\$2"3" .ds oS 3rd Berkeley Distribution +. if "\\$2"4" .ds oS 4th Berkeley Distribution +. if "\\$2"4.1" .ds oS 4.1 Berkeley Distribution +. if "\\$2"4.2" .ds oS 4.2 Berkeley Distribution +. if "\\$2"4.3" .ds oS 4.3 Berkeley Distribution +. if "\\$2"4.3+" .ds oS 4.3+tahoe Berkeley Distribution +.\} +.if "\\*(oS"Null" .ds oS \\$1 +.if "\\*(o1"Non-Null" .as oS \0\\$2 +.rm o1 +.. +.\" +.\" Standards +.\" +.\" .de St +.\" .ds sT Null +.\" .if "\\$1"POSIX" \{\ +.\" . ds sT IEEE Standard POSIX +.\" . if \\$2 .as sT \0\\$2 +.\" .\} +.\" .if "\\$1"ANSI" \{\ +.\" . ds sT ANSI Standard +.\" . if \\$2 .as sT \0\\$2 +.\" .\} +.\" .if "\\$1"ISO" \{\ +.\" . ds sT ISO Standard +.\" . if \\$2 .as sT \0\\$2 +.\" .\} +.\" .if "\\*(sT"Null" .ds sR \\$3 +.\" .. +.\" +.\" .de Gp +.\" .ie !"\\$1"" .ds gP \&\\$1 \\$2 \\$3 \\$4 \\$5 +.\" .el .ds gP Null +.\" .. +.\" +.\" +.de Dd +.nr aa 0 +.ie \\n(.$>0 \{\ +. ie \\n(.$<4 \{\ +. ds dD \\$1 \\$2 \\$3 +. \} +. el .tm Usage: .Dd Month Day, Year (e.g July 4, 1977). +.\} +.el \{\ +. ds dD Epoch +.\} +.. +.\" +.\" House Keeping Macro - Make sense of dT, cH, vT, sT, gP and dS +.\" TODO: Try to get else's for efficiency +.\" TODO: GET RID OF .wh -1.167i (its in v7) +.\" +.\" +.de hK +.nr % 1 +.ds hT \\*(dT +.if !"\\*(cH"Null" \{\ +. ie !"\\*(gP"Null" .as hT \|(\|\\*(cH\\*(gP\|) +. el .as hT \\|(\\|\\*(cH\\|) +.\} +.if "\\*(cH"Null" .if !"\\*(gP"Null" .as hT \&\|(\|\\*(gP\|) +.if t \{\ +. wh 0 hM +. wh -1.25i fM +.\} +.if n \{\ +. ie \\n(cR \{\ +. hM +. wh -0v fM +. \} +. el \{\ +. wh 0 hM +. wh -1.167i fM +. \} +.\} +.if n \{\ +. if \\n(nl==0:\\n(nl==-1 'bp +.\} +.if t 'bp +.em lM +.. +.\" Header Macro +.\" +.de hM +.ev 1 +.pL +.if !\\n(cR 'sp \\n(Hmu +.tl @\\*(Hs\\*(hT\fP@\\*(Vs\\*(vT\fP@\\*(Hs\\*(hT\fP@ +'sp \\n(Hmu +.ev +.. +.\" +.de fM +.ev 1 +.pL +.if !\\n(cR \{\ +' sp \\n(Fmu +. tl @\\*(Hs\\*(oS\fP@\\*(Vs\\*(dD\fP@%@ +' bp +.\} +.if \\n(cR \{\ +.\" . tl @\\*(Hs\\*(oS\fP@\\*(Vs\\*(dD\fP@%@ +.\" ' bp +.\} +.ev +.. +.de lM +.fl +.if \\n(cR \{\ +. fM +. pl \\n(nlu +.\} +.. +.de Pp +.sp \\n(Ppu +.ne 2 +.ns +.. +.de Lp +.Pp +.. +.de LP +.tm Not a \-mdoc command: .LP +.. +.de PP +.tm Not a \-mdoc command: .PP +.. +.de pp +.tm Not a \-mdoc command: .pp +.. +.de Co +.tm Not a \-mdoc command: .Co +.. +.nr z. 1 +.nr z, 1 +.nr z: 1 +.nr z; 1 +.nr z) 1 +.nr z( 1 +.nr z[ 1 +.nr z] 1 +.\" This is disgusting, troff not parse if stmt properly +.nr z1 0 +.nr z2 0 +.nr z3 0 +.nr z4 0 +.nr z5 0 +.nr z6 0 +.nr z7 0 +.nr z8 0 +.nr z9 0 +.nr z0 0 +.nr z# 0 +.\" +.de Ad +.ie \\n(.$==0 \{\ +. tm Usage: .Ad address [...] \\*(Pu +.\} +.el \{\ +. ds sV \\*(aD +. nr cF \\n(.f +. ie "\\*(iM"" .ds f1 \&\\*(sV +. el .as f1 \&\\*(sV +. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. ft \\n(cF +.\} +.. +.\" +.\" Command Line Argument Macro +.\" +.de Ar +.ie \\n(.$==0 \{\ +. ie !"\\*(iM"" .as f1 \&[\|\\*(aRfile\ ...\fP\|] +. el \&[\|\\*(aRfile\ ...\fP\|] +.\} +.el \{\ +. ds sV \\*(aR +. nr cF \\n(.f +. ie "\\*(iM"" .ds f1 \&\\*(sV +. el .as f1 \&\\*(sV +. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. ft \\n(cF +.\} +.. +.\" +.de Em +.ie \\n(.$==0 \{\ +. tm Usage: .Em text ... \\*(Pu +.\} +.el \{\ +. ds sV \\*(eM +. nr cF \\n(.f +. ie "\\*(iM"" .ds f1 \&\\*(sV +. el .as f1 \&\\*(sV +. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. ft \\n(cF +.\} +.. +.\" +.de Er +.ie \\n(.$==0 \{\ +. tm Usage: .Er ERRNOTYPE ... \\*(Pu +. \} +.el \{\ +. ds sV \\*(eR +. nr cF \\n(.f +. ie "\\*(iM"" .ds f1 \&\\*(sV +. el .as f1 \&\\*(sV +. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. ft \\n(cF +.\} +.. +.\" +.de Ev +.ie \\n(.$==0 \{\ +. tm Usage: .Ev ENVIRONMENT_VARIABLE(s) ... \\*(Pu +. \} +.el \{\ +. ds sV \\*(eV +. nr cF \\n(.f +. ie "\\*(iM"" .ds f1 \&\\*(sV +. el .as f1 \&\\*(sV +. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. ft \\n(cF +.\} +.. +.\" +.\" Flag Name Macro +.\" +.de Fl +.ie \\n(.$==0 \{\ +. ie !"\\*(iM"" .as f1 \&\\*(fL\-\fP +. el \&\\*(fL\-\fP +.\} +.el \{\ +. nr rZ 0 +. sW \\$1 +. if (\\n(sW==1&\\n(.$==1) .rZ \\$1 +. ds sV \\*(fL +. nr cF \\n(.f +. ie \\n(rZ \{\ +. ie "\\*(iM"" .ds f1 \&\\*(sV\-\f\\n(cF\\$1 +. el \&\\*(sV\-\f\\n(cF\\$1 +. \} +. el \{\ +. ie "\\*(iM"" .ds f1 \&\\*(sV +. el .as f1 \&\\*(sV +. fB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. ft \\n(cF +. \} +.\} +.. +.\" Interactive Commands Macro +.\" +.de Ic +.ie \\n(.$==0 \{\ +. tm Usage: .Ic Interactive Commands(s) ... \\*(Pu +.\} +.el \{\ +. ds sV \\*(iC +. nr cF \\n(.f +. ie "\\*(iM"" .ds f1 \&\\*(sV +. el .as f1 \&\\*(sV +. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. ft \\n(cF +.\} +.. +.\" +.\" Interactive Command Modifiers (flags) +.\" +.de Cm +.ie \\n(.$==0 \{\ +. tm Usage: .Cm Interactive Command Modifier(s) ... \\*(Pu +.\} +.el \{\ +. ds sV \\*(cM +. nr cF \\n(.f +. ie "\\*(iM"" .ds f1 \&\\*(sV +. el .as f1 \&\\*(sV +. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. ft \\n(cF +.\} +.. +.\" +.de Li +.ie \\n(.$==0 \{\ +. tm Usage: .Li literal ... \\*(Pu +. \} +.el \{\ +. ds sV \\*(lI +. nr cF \\n(.f +. ie "\\*(iM"" .ds f1 \&\\*(sV +. el .as f1 \&\\*(sV +. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. ft \\n(cF +.\} +.. +.\" If in nroff or any other case where the default font +.\" is constant width, and literal means zilch, single quote instead. +.ie n \{\ +.de Ql +. ie \\n(.$==0 \{\ +. tm Usage: .Ql literal ... \\*(Pu +. \} +. el \{\ +. Sq \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. \} +.. +.\} +.el \{\ +.de Ql +. ie \\n(.$==0 \{\ +. tm Usage: .Ql literal ... \\*(Pu +. \} +. el \{\ +. Li \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. \} +.. +.\} +.\" +.de Nm +.ie \\n(.$==0 \{\ +. if "\\*(n1"" .tm Usage: .Nm Name(s) ... \\*(Pu +. ie !"\\*(iM"" .as f1 \&\\*(nM\\*(n1\\$1\fP +. el \&\\*(nM\\*(n1\\$1\fP +.\} +.el \{\ +. ds sV \\*(nM +. nr cF \\n(.f +. if \\n(nS \{\ +. rs +. in -\\n(iSu +. ie \\n(nS>1 .br +. el \{\ +. sW \\$1 +. nr iS ((\\n(sW+1)*\\n(fW)u +. \} +. in +\\n(iSu +. ti -\\n(iSu +. nr nS \\n(nS+1 +. \} +. if "\\*(n1"" .ds n1 \\$1 +. ie "\\*(iM"" .ds f1 \&\\*(sV +. el .as f1 \&\\*(sV +. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. ft \\n(cF +.\} +.. +.\" +.de Pa +.ie \\n(.$==0 \{\ +\&\\*(pA~\fP +.\} +.el \{\ +. ds sV \\*(pA +. nr cF \\n(.f +. ie "\\*(iM"" .ds f1 \&\\*(sV +. el .as f1 \&\\*(sV +. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. ft \\n(cF +.\} +.. +.\" +.de Sy +.ie \\n(.$==0 \{\ +. tm Usage: .Sy Symbolic Text ... \\*(Pu +. \} +.el \{\ +. ds sV \\*(sY +. nr cF \\n(.f +. ie "\\*(iM"" .ds f1 \&\\*(sV +. el .as f1 \&\\*(sV +. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. ft \\n(cF +.\} +.. +.\" +.de Ms +.ie \\n(.$==0 \{\ +. tm Usage: .Ms Math Symbol ... \\*(Pu +. \} +.el \{\ +. ds sV \\*(sY +. nr cF \\n(.f +. ie "\\*(iM"" .ds f1 \&\\*(sV +. el .as f1 \&\\*(sV +. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. ft \\n(cF +.\} +.. +.\" +.de Va +.ie \\n(.$==0 \{\ +. tm Usage: .Va variable_name(s) ... \\*(Pu +.\} +.el \{\ +. ds sV \\*(vA +. nr cF \\n(.f +. ie "\\*(iM"" .ds f1 \&\\*(sV +. el .as f1 \&\\*(sV +. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. ft \\n(cF +.\} +.. +.\" +.de nB +.hy 0 +.if \\n(.$==0 .tm Usage error: called with empty arguments (empty quotes)? +.ie \\n(.$>1 \{\ +. rZ \\$1 +. ie \\n(rZ .as f1 \&\f\\n(cF\\$1\fP +. el .as f1 \&\\$1 +. rZ \\$2 +. if !\\n(rZ \{\ +. ie !"\\*(iM""\{\ +.\" I surrender +. if "\\*(iM"Tp" .as f1 \&\ \& +. if "\\*(iM"Dp" .as f1 \&\ \& +. if "\\*(iM"Op" .as f1 \&\ \& +. if "\\*(iM"Cx" .as f1 \&\ \& +. if "\\*(iM"Dq" .as f1 \& \& +. if "\\*(iM"Sq" .as f1 \& \& +. if "\\*(iM"Pq" .as f1 \& \& +. if "\\*(iM"Aq" .as f1 \& \& +. \} +. el .as f1 \& \& +. \} +. nB \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +.\} +.el \{\ +. rZ \\$1 +. ie \\n(rZ .as f1 \&\f\\n(cF\\$1 +. el .as f1 \&\\$1\f\\n(cF +. if "\\*(iM"" \{\&\\*(f1 +. ds f1 +. \} +. hy +.\} +.. +.de fB +.hy 0 +.if \\n(.$==0 .tm Usage error: called with empty arguments (empty quotes)? +.ie \\n(.$>1 \{\ +. rZ \\$1 +. ie \\n(rZ .as f1 \&\f\\n(cF\\$1\fP +. el \{\ +. ie "\\$1"-" .as f1 \&\-\- +. el .as f1 \&\-\\$1 +. \} +. rZ \\$2 +. if !\\n(rZ \{\ +. ie !"\\*(iM""\{\ +.\" I surrender +. if "\\*(iM"Tp" .as f1 \&\ \& +. if "\\*(iM"Dp" .as f1 \&\ \& +. if "\\*(iM"Op" .as f1 \&\ \& +. if "\\*(iM"Cx" .as f1 \&\ \& +. if "\\*(iM"Dq" .as f1 \& \& +. if "\\*(iM"Sq" .as f1 \& \& +. if "\\*(iM"Pq" .as f1 \& \& +. if "\\*(iM"Aq" .as f1 \& \& +. \} +. el .as f1 \& \& +. \} +. fB \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +.\} +.el \{\ +. rZ \\$1 +. ie \\n(rZ .as f1 \&\f\\n(cF\\$1 +. el \{\ +. ie "\\$1"-" .as f1 \&\-\-\f\\n(cF +. el .as f1 \&\-\\$1\f\\n(cF +. \} +. if "\\*(iM"" \{\&\\*(f1 +. ds f1 +. \} +. hy +.\} +.. +.\" +.\" Single quoted Items +.\" eF, sB g[0-9] and f2 +.de Sq +.nr eF 0 +.ie \\n(.$==0 \{\ +. ie "\\*(iM"" \&\\*(sL\&\\*sR +. el .as f1 \&\\*(sL\&\\*(sR +.\} +.el \{\ +. ie "\\*(iM"" \{\ +. ds f1 \&\\*(sL +. ds iM Sq +. \} +. el .as f1 \&\\*(sL +. sB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. ie \\n(eF>0 .\\*(g1 \\*(g2 \\*(g3 \\*(g4 \\*(g5 \\*(g6 \\*(g7 \\*(g8 +. el .as f1 \\*(g0 +. as f1 \\*(sR +. if !"\\*(f2"" .as f1 \\*(f2 +. if "\\*(iM"Sq" \{\ +\&\\*(f1 +. ds f1 +. ds iM +. \} +. ds f2 +. rm g0 g1 g2 g3 g4 g5 g6 g7 g8 g9 +. nr eF 0 +.\} +.. +.\" +.\" Double quoted Items +.de Dq +.nr Ef 0 +.ie \\n(.$==0 \{\ +. ie "\\*(iM"" \&\\*(Lq\&\\*(Rq +. el .as f1 \&\\*(Lq\&\\*(Rq +.\} +.el \{\ +. ie "\\*(iM"" \{\ +. ds f1 \&\\*(Lq +. ds iM Dq +. \} +. el .as f1 \&\\*(Lq +. Sb \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. ie \\n(Ef>0 .\\*(k1 \\*(k2 \\*(k3 \\*(k4 \\*(k5 \\*(k6 \\*(k7 \\*(k8 +. el .as f1 \\*(k0 +. as f1 \\*(Rq +. if !"\\*(f4"" .as f1 \\*(f4 +. if "\\*(iM"Dq" \{\ +\&\\*(f1 +. ds f1 +. ds iM +. \} +. ds f4 +. rm k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 +. nr Ef 0 +.\} +.. +.\" +.\" Parenthesis quoted Items +.de Pq +.nr pQ 0 +.ie \\n(.$==0 \{\ +. ie "\\*(iM"" \&(\&) +. el .as f1 \&(\&) +.\} +.el \{\ +. ie "\\*(iM"" \{\ +. ds f1 \&( +. ds iM Pq +. \} +. el .as f1 \&( +. pB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. ie \\n(pQ>0 .\\*(y1 \\*(y2 \\*(y3 \\*(y4 \\*(y5 \\*(y6 \\*(y7 \\*(y8 +. el .as f1 \\*(y0 +. as f1 \&) +. if !"\\*(f3"" .as f1 \\*(f3 +. if "\\*(iM"Pq" \{\ +\&\\*(f1 +. ds f1 +. ds iM +. \} +. ds f3 +. rm y0 y1 y2 y3 y4 y5 y6 y7 y8 y9 +. nr pQ 0 +.\} +.. +.\" eF, sB g[0-9] and f2 +.de sB +.hy 0 +.ie \\n(.$==0 .tm Sick Logic: macro sB +.el \{\ +. ie \\n(eF>=1 .nr eF \\n(eF+1 +. el \{\ +. mN \\$1 +. if \\n(mN .nr eF \\n(eF+1 +. \} +. rZ \\$1 +. ie \\n(rZ .as f2 \\$1 +. el \{\ +. ie \\n(eF<1 .as g\\n(eF \\$1 +. el .as g\\n(eF \\$1 +. \} +. if \\n(.$>1 \{\ +. rZ \\$2 +. if \\n(rZ==0 \{\ +. if \\n(eF<1 \{\ +. as g\\n(eF \& \& +. \} +. \} +. sB \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. \} +.\} +.. +.de Sb +.hy 0 +.ie \\n(.$==0 .tm Sick Logic: macro Sb +.el \{\ +. ie \\n(Ef>=1 .nr Ef \\n(Ef+1 +. el \{\ +. mN \\$1 +. if \\n(mN .nr Ef \\n(Ef+1 +. \} +. rZ \\$1 +. ie \\n(rZ .as f4 \\$1 +. el \{\ +. ie \\n(Ef<1 .as k\\n(Ef \\$1 +. el .as k\\n(Ef \\$1 +. \} +. if \\n(.$>1 \{\ +. rZ \\$2 +. if \\n(rZ==0 \{\ +. if \\n(Ef<1 \{\ +. as k\\n(Ef \& \& +. \} +. \} +. Sb \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. \} +.\} +.. +.de pB +.hy 0 +.ie \\n(.$==0 .tm Sick Logic: macro pB +.el \{\ +. ie \\n(pQ>=1 .nr pQ \\n(pQ+1 +. el \{\ +. mN \\$1 +. if \\n(mN .nr pQ \\n(pQ+1 +. \} +. rZ \\$1 +. ie \\n(rZ .as f3 \\$1 +. el \{\ +. ie \\n(pQ<1 .as y\\n(pQ \\$1 +. el .as y\\n(pQ \\$1 +. \} +. if \\n(.$>1 \{\ +. rZ \\$2 +. if \\n(rZ==0 \{\ +. if \\n(pQ<1 \{\ +. as y\\n(pQ \& \& +. \} +. \} +. pB \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. \} +.\} +.. +.de aQ +.hy 0 +.ie \\n(.$==0 .tm Bad Syntax: .Aq +.el \{\ +. ie \\n(aQ>=1 .nr aQ \\n(aQ+1 +. el \{\ +. mN \\$1 +. if \\n(mN .nr aQ \\n(aQ+1 +. \} +. rZ \\$1 +. ie \\n(rZ .as aZ \\$1 +. el \{\ +. ie \\n(aQ<1 .as a\\n(aQ \\$1 +. el .as a\\n(aQ \\$1 +. \} +. if \\n(.$>1 \{\ +. rZ \\$2 +. if \\n(rZ==0 \{\ +. if \\n(aQ<1 \{\ +. as a\\n(aQ \& \& +. \} +. \} +. aQ \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. \} +.\} +.. +.\" Angle Bracket Quoted Items +.de Aq +.nr aQ 0 +.ie \\n(.$==0 \{\ +. ie "\\*(iM"" \&<\&> +. el .as f1 \&<\&> +.\} +.el \{\ +. ie "\\*(iM"" \{\ +. ds f1 \&< +. ds iM Aq +. \} +. el .as f1 \&< +. aQ \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 +. ie \\n(aQ>0 .\\*(a1 \\*(a2 \\*(a3 \\*(a4 \\*(a5 \\*(a6 \\*(a7 \\*(a8 +. el .as f1 \\*(a0 +. as f1 \&> +. if !"\\*(aZ"" .as f1 \\*(aZ +. if "\\*(iM"Aq" \{\ +\&\\*(f1 +. ds f1 +. ds iM +. \} +. ds aZ +. rm a0 a1 a2 a3 a4 a5 a6 a7 a8 +. nr aQ 0 +.\} +.. +.\" macro Name test, return macro register value if true +.if \n(.g .ig +.de mN +.nr mN 0 +.sW \\$1 +.if \\n(sW==2 \{\ +. if \\n(\\$1 .nr mN \\n(\\$1 +.\} +.. +.if !\n(.g .ig +.de mN +.nr mN 0 +.if \A'\\$1' \{\ +. sW \\$1 +. if \\n(sW==2 \{\ +. if \\n(\\$1 .nr mN \\n(\\$1 +. \} +.\} +.. +.\" Punctuation test (using z registers), return 1 if true +.if \n(.g .ig +.de rZ +.nr rZ 0 +.sW \\$1 +.if \\n(sW==1 \{\ +. if \\n(z\\$1==1 \{\ +. nr rZ 1 +. \} +.\} +.. +.if !\n(.g .ig +.de rZ +.nr rZ 0 +.if \A'\\$1' \{\ +. sW \\$1 +. if \\n(sW==1 \{\ +. if \\n(z\\$1==1 \{\ +. nr rZ 1 +. \} +. \} +.\} +.. +.\" +.\" sW returns number of characters in a string +.if t \{\ +.nr fW \w'\fC,' +.de sW +.nr sW \w'\fC\\$1' +.\} +.if n \{\ +.nr fW \w'0' +.de sW +.nr sW \w'\\$1' +.\} +.ie \\n(sW>=\\n(fW \{\ +. ie \\n(sW%\\n(fW .nr sW (\\n(sW/\\n(fW)+1 +. el .nr sW \\n(sW/\\n(fW +.\} +.el .nr sW 0 +.. +.\" Option Expression - +.\" TODO - add line overflow check (right!) +.nr eP 0 +.ds e1 +.nr oE 0 +.nr hP 0 +.ds hP +.nr Ep 0 +.de Op +.hy 0 +.if "\\*(iM"" \{\ +. ds iM Op +. ds f1 \& +.\} +.as f1 \&\\*(lB +.\" .tm Op: \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +.dO \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +.ie !"\\$1"Cx" .oE +.el .nr oE \\n(oE+1 +.. +.\" +.\" just for mike, with every bite of garlic in mind (oops, i mean burp). +.\" dO: go dOwn an argument vector and test each argument to see if +.\" a macro name or punctuation. stash in respective place along +.\" with its arguments. +.nr oO 0 +.nr oP 0 +.nr aO 0 +.de dO +.mN \\$1 +.ie \\n(mN \{\ +. if \\n(oP \{\ +. if \\n(hP \{\ +. nr oZ 1 +. oZ +. Oz +. \} +. if \\n(e1==1 \{\ +.\\*(e1 \\*(e2 \\*(e3 \\*(e4 \\*(e5 \\*(e6 \\*(e7 \\*(e8 \\*(e9 +. \} +. uO +. if !(\\n(oO:\\n(aO) .as f1 \& \& +. \} +. ie "\\$1"Op" \{\ +. as f1 \&\\*(lB +. nr aO \\n(aO+1 +. \} +. el \{\ +. nr eP \\n(eP+1 +. ds e\\n(eP \\$1 +. nr e\\n(eP 1 +. \} +.\} +.el \{\ +.\" .tm dO: $1: \\$1: eP \\n(eP e[\\n(eP]: \\*(e\\n(ePEE +. rZ \\$1 +. ie \\n(rZ \{\ +.\" .tm dO:rZ: $1: \\$1: eP \\n(eP e[\\n(eP]: \\*(e\\n(eP +. nr hP \\n(hP+1 +. ds h\\n(hP \\$1 +. \} +. el \{\ +.\" .tm dO:word $1: \\$1: eP \\n(eP e[\\n(eP]: \\*(e\\n(ePEE +. if \\n(eP==0:\\n(e\\n(eP==1 .nr eP \\n(eP+1 +. if \\n(eZ .as e\\n(eP \& \& +. as e\\n(eP " \&\\$1 +.\" . ds e\\n(eP \&\\$1 +. nr eZ \\n(eZ+1 +. \} +.\} +.nr oP 1 +.ie \\n(.$>1 \{\ +. dO \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +.\} +.el \{\ +. ie \\n(e1 \{\ +.\\*(e1 \\*(e2 \\*(e3 \\*(e4 \\*(e5 \\*(e6 \\*(e7 \\*(e8 \\*(e9 +. \} +. el \{\ +. as f1 \\*(e1 +. \} +.\} +.. +.\" handle old style arguments such as the arg -Idir +.\" in adb, .Oo is a toggle. +.de Oo +.ie \\n(oO .nr oO 0 +.el .nr oO 1 +.. +.\" stash punctuation +.de oZ +.if \\n(hP>=\\n(oZ \{\ +. nr eP \\n(eP+1 +. ds e\\n(eP \\*(h\\n(oZ +. nr oZ \\n(oZ+1 +. oZ +.\} +.. +.\" clean up punctuation vector +.de Oz +.if \\n(hP>0 \{\ +. rm h\\n(hP +. nr hP \\n(hP-1 +. Oz +.\} +.. +.\" uO: go back up created vector cleaning it up along the way +.de uO +.if \\n(eP>0 \{\ +. rm e\\n(eP +. rr e\\n(eP +. nr eP \\n(eP-1 +. nr oP 0 +. nr eZ 0 +. uO +.\} +.. +.\" option end +.de oE +.uO +.ie \\n(hP \{\ +. as f1 \\*(rB\\*(h1\\*(h2\\*(h3 +. Oz +. nr oZ 0 +.\} +.el \{\ +. as f1 \\*(rB +.\} +.ie "\\*(iM"Op" \{\ +. if \\n(aO .aO +.if t \{\ +. if (\\n(.lu-\\n(.ku-\\n(.ou-(2*\\n(fWu))<\w'\fC\\*(f1'u .br +.\} +.if n \{\ +. nr aa \w'\\*(f1'u +.\" . nr qq \\n(.lu-\\n(.ku-\\n(.ou +.\" \&aa == \\n(aa, f1==\\*(f1, qq==\\n(qq +. if (\\n(.lu-\\n(.ku-\\n(.ou-\\n(aau)<=(8*\\n(fWu) .br +.\} +\&\\*(f1 +. ds iM +. ds f1 +. hy +.\} +.el .nr oE \\n(oE-1 +.. +.de aO +.as f1 \\*(rB +.nr aO \\n(aO-1 +.if \\n(aO >0 .aO +.. +.\" +.de Xr +.if \\n(.$<=1 \{\ +. ie \\n(.$==1 \{\ +. if !"\\*(iM"" .as f1 \&\\*(xR\\$1\fP +. if "\\*(iM"" \&\\*(xR\\$1\fP +. \} +. el .tm Xr Usage: .Xr manpage_name [section#] \\*(Pu +.\} +.if \\n(.$==2 \{\ +. rZ \\$2 +. ie "\\*(iM"" \{\ +. ie \\n(rZ \&\\*(xR\\$1\fP\\$2 +. el \&\\*(xR\\$1\fP(\\$2) +. \} +. el \{\ +. ie \\n(rZ .as f1 \&\\*(xR\\$1\fP\\$2 +. el .as f1 \&\\*(xR\\$1\fP(\\$2) +. \} +.\} +.if \\n(.$>=3 \{\ +. rZ \\$2 +. ie \\n(rZ \{\ +. ie !"\\*(iM"" .as f1 \&\\*(xR\\$1\fP\\$2\\$3\\$4\\$5\\$6\\$7\\$8 +. el \&\\*(xR\\$1\fP\\$2\\$3\\$4\\$5\\$6\\$7\\$8 +. \} +. el \{\ +. rZ \\$3 +. ie \\n(rZ \{\ +. if !"\\*(iM"" \{\ +. as f1 \&\\*(xR\\$1\fP(\\$2)\\$3\\$4\\$5\\$6\\$7\\$8 +. \} +. if "\\*(iM"" \{\ +\&\\*(xR\\$1\fP(\\$2)\\$3\\$4\\$5\\$6\\$7\\$8 +. \} +. \} +. el \{\ +. tm rZ = \\n(rZ the arg is \\$3 +. tm Xr-XX Usage: .Xr manpage_name [section#] \\*(Pu +. \} +. \} +.\} +.. +.\" +.\" +.de Ex +.tm Ex defunct, Use .Dl: \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +.. +.\" Display (one) Line of text. +.de Dl +.ie "\\*(iM"" \{\ +' ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i +. in \\n(.iu+\\n(Dsu +. mN \\$1 +. ie \\n(mN .\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. el \{\ +. nr cF \\n(.f +.\" Literal font is none specified +\&\\*(lI\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. ft \\n(cF +. \} +. in \\n(.iu-\\n(Dsu +.\} +.el \{\ +. mN \\$1 +. ie \\n(mN .\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 +. el \{\ +. nr cF \\n(.f +. ds f1 \&\\*(lI\\&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 +. as f1 \&\f\\n(cF +. \} +.\} +.. +.\" +.\" +.\" user set Tagged Paragraph Width (used in both Dp and Tp) +.de Tw +.ie \\n(.$==0 \{\ +. nr aa 0 +.\} +.el \{\ +. mN \\$1 +. ie \\n(sW>2 \{\ +. nr tW (\\n(sW+3)*\\n(fWu) +. \} +. el \{\ +. ie \\n(mN .nr tW \\n(mN +. el .nr tW \\$1 +. \} +. nr tF 1 +.\} +.. +.\" +.de Dw +.Tw \\$1 +.. +.\" +.de Di +.ie \\n(.$==0 \{\ +. nr tI \\n(Dsu +.\} +.el \{\ +. sW \\$1 +. if \\n(sW>=2 \{\ +. nr tI \\$1u +. \} +. if \\n(sW<2 \{\ +. if "\\$1"L" \{\ +. nr tI 0 +. \} +. \} +.\} +.. +.\" tagged paragraph +.\" initialize baby stack variables +.nr np 0 +.nr p1 0 +.ds s\n(np +.\" +.de Tp +.ie "\\$1"" .pE p s np +.el \{\ +. ds iM Tp +. mN \\$1 +. ie \\n(tF \{\ +. ds tC Tw +. nr tC 1 +. nr tF 0 +. \} +. el \{\ +. if !"Tw"\\*(s\\n(np" \{\ +. ie \\n(mN \{\ +. ds tC \\$1 +. nr tW \\n(mN +. \} +. el \{\ +. ds tC Tx +. nr tW \\n(Tx +. \} +. if !"\\*(tC"\\*(s\\n(np" .nr tC 1 +. \} +. \} +. sp \\n(vVu +. if !\\n(cR .ne 2 +. if \\n(tC \{\ +. nr np \\n(np+1 +. nr p\\n(np \\n(tW +. ds s\\n(np \\*(tC +. nr tC 0 +. ds tC +. in \\n(.iu+\\n(p\\n(npu +. \} +. ie \\n(mN \{\ +. ds f1 +. \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. if !"\\$1"Cx" .pT st p np +. \} +. el \{\ +. br +. ev 1 +. fi +. di Td +\&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. br +. di +. ev +. na +. ds tD \\*(Td\\ +. pT di p np +. \} +.\} +.. +.\" +.\" +.\" Complex Expression Macro +.\" +.\" TODO: add length across line boundary check (like Li) +.de Cx +.hy 0 +.ie \\n(.$==0 \{\ +. if "\\*(iM"Cx" \{\ +. ds iM +. if \\n(oE .oE +\&\\*(f1 +. ds f1 +. \} +. if "\\*(iM"Tp" .pT st p np +. if "\\*(iM"Dp" .pT st q mp +.\} +.el \{\ +. if "\\*(iM"" \{\ +. ds iM Cx +. ds f1 \& +. \} +. mN \\$1 +.\" Here are the args: '\\$1' '\\$2' '\\$3' '\\$4' +. ie \\n(mN .\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. el \{\ +. as f1 \&\\$1 +. if \\n(.$>1 .Cx \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. \} +.\} +.. +.\" Prefix string in default font to content specified string +.de Pf +.Cx \\$1 +.\\$2 \\$3 \\$4 \\$5 +.Cx +.. +.\" Suffix string in default font to content specified string +.de Sf +.Cx \\$1 \\$2 +.Cx \\$3 +.Cx +.. +.\" Simple Option Begin +.de Ob +.hy 0 +.ie "\\*(iM"" \{\ +. ev 2 +. fi +. di oB +.\} +.el \{\ +.tm shouldn't be here +. as f1 \&[ +. mN \\$1 +. ie \\n(mN .\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. el \{\ +. as f1 \&\\$1 +. if \\n(.$>1 .Oc \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. \} +.\} +.. +.de Oc +.as f1 \&\\$1 +.if \\n(.$>1 .Oc \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +.. +.de Oe +.hy 0 +.ie "\\*(iM"" \{\ +. br +. di +. ev +. ds bO \\*(oB\\ +\&[\\*(bO\&] +.\} +.el \{\ +. as f1 \&] +.\} +.. +.\" White space for Cx +.de Ws +.Cx \&\ \& +.. +.\" tagged paragraph +.\" initialize baby stack variables +.nr mp 0 +.nr q1 0 +.ds r\n(np +.\" +.\" Complex Dp tag +.de Dc +.Dp Cx \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 +.. +.\" Complex Tp tag +.de Tc +.Tp Cx \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 +.. +.\" Tag with a flag and an argument with a space +.de Ta +.if "\\$2"" \{\ +. Tp Fl \\$1 +.\} +.el \{\ +. Tp Fl \\$1 +. Cx \&\ \& +. Ar \\$2 \\$3 +. Cx +.\} +.. +.de Da +.Dp Cx Fl \\$1 +.Ws +.Ar \\$2 \\$3 +.Cx +.. +.de To +.Tp Cx Fl \\$1 +.Ar \\$2 \\$3 +.Cx +.. +.de Do +.Dp Cx Fl \\$1 +.Ar \\$2 \\$3 +.Cx +.. +.\" Blended tag toggle +.de Bt +.ie \\n(tP==0 .nr tP 1 +.el .nr tP 0 +.. +.\" Bullet paragraph +.de Bu +.Tp Sy \&\(bu +.. +.\" Display tagged paragraph +.de Dp +.ie "\\$1"" \{\ +. pE q r mp +. sp \\n(vVu +.\} +.el \{\ +. ds iM Dp +. mN \\$1 +. ie \\n(tF \{\ +. ds tC Tw +. nr tC 1 +. nr tF 0 +. \} +. el \{\ +. if !"Tw"\\*(r\\n(mp" \{\ +. ie \\n(mN \{\ +. ds tC \\$1 +. nr tW \\n(mN +. \} +. el \{\ +. ds tC Tx +. nr tW \\n(Tx +. \} +. if !"\\*(tC"\\*(r\\n(mp" .nr tC 1 +. \} +. \} +. if !\\n(cR .ne 2 +. if \\n(tC \{\ +. nr mp \\n(mp+1 +. nr q\\n(mp \\n(tW +. ds r\\n(mp \\*(tC +. nr tC 0 +. ds tC +. ie \\n(tIu==\\n(Dsu .nr i\\n(mp \\n(Dsu +. el \{\ +. nr i\\n(mp \\n(tIu +. nr tI \\n(Dsu +. \} +. in \\n(.iu+\\n(i\\n(mpu +. sp \\n(vVu +. in \\n(.iu+\\n(\\q\\n(mpu +. \} +. ie \\n(mN \{\ +. \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. if !"\\$1"Cx" .pT st q mp +. \} +. el \{\ +. br +. ev 1 +. fi +. di Td +\&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. br +. di +. ev +. na +. ds tD \\*(Td\\ +. pT di q mp +. \} +.\} +.. +.\" +.\" .pE number_stack string_stack counter +.de pE +.ie "\\$3"mp" \{\ +. in \\n(.iu-(\\n(\\$1\\n(\\$3u)-(\\n(i\\n(mpu) +. rr i\\n(mp +.\} +.el .in \\n(.iu-\\n(\\$1\\n(\\$3u +.\" .in \\n(.iu-\\n(\\$1\\n(\\$3u +.if \\n(\\$3<=0 .tm Extraneous call .Tp or .Dp +.rr \\$1\\n(\\$3 +.rm \\$2\\n(\\$3 +.nr \\$3 \\n(\\$3-1 +.ds iM +.. +.\" +.\" .pT [st or di] number_stack counter +.de pT +.ie "\\$1"st" \{\ +. nr bb \\n(\\$2\\n(\\$3u +. ti -\\n(bbu +. ie (\\n(\\$2\\n(\\$3u-2n)<=\w'\\*(f1'u \{\&\\*(f1\\*(tP +. if \\n(tP==0 .br +. \} +. el \\*(f1\h'|\\n(\\$2\\n(\\$3u'\c +.\} +.el \{\ +. ti -\\n(\\$2\\n(\\$3u +. ie (\\n(\\$2\\n(\\$3u-2n)<=\\n(dlu \{\&\\*(tD\\*(tP +. if !\\n(tP .br +. \} +. el \\*(tD\h'|\\n(\\$2\\n(\\$3u'\c +. if t 'ad +.\} +. ds iM +. ds f1 +'fi +.. +.\" +.\" The new SH +.\" +.de Sh +.\" set Sh state off, check for list state before calling indent (.In) +.nr nS 0 +.nr sE 0 +.ie "\\$1"NAME" \{\ +.\" name state on, housekeep (headers & footers) +. hK +' in 0 +.\} +.el \{\ +. if "\\$1"SYNOPSIS" .nr nS 1 +. in 0 +.\} +.pL +'sp +.ns +.ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i +.if !\\n(cR .ne 3 +'fi +\&\fB\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6 \|\\$7 \|\\$8 \|\\$9 +\&\fP\& +.in \\n(.iu+\\n(Tiu +.if "\\$1"SEE" .nr sE 1 +.ns +.. +.\" +.\" Nd minus sign for an en dash used in .Sh Name +.de Nd +\&\-\& \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +.. +.de Ss +.sp +.ti -.25i +\&\fB\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6 \|\\$7 \|\\$8 \|\\$9 +\&\fP\& +.ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i +.if !\\n(cR .ne 2 +.br +.. +.\" .if "\\$1"Ss" .in \\n(.iu+\\n(sIu +.\".. +.\" +.\" +.\" Column Macro +.\" +.hy 0 +.de Cw +.ie \\n(.$==0 \{\ +. br +. in \\n(.iu-\\n(eWu +. ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i +.\} +.el \{\ +. Pp +. if \\n(.$==1 \{\ +. ta \w'\\$1 'u +. nr eW \w'\\$1 'u +' in \\n(.iu+\\n(eWu +. \} +. if \\n(.$==2 \{\ +. ta \w'\\$1 'u +\w'\\$2 'u +. nr eW \w'\\$1 'u+\w'\\$2 'u +' in \\n(.iu+\\n(eWu +. \} +. if \\n(.$==3 \{\ +. ta \w'\\$1 'u +\w'\\$2 'u +\w'\\$3 'u +. nr eW \w'\\$1 'u+\w'\\$2 'u+\w'\\$3 'u +' in \\n(.iu+\\n(eWu +. \} +. if \\n(.$==4 \{\ +. ta \w'\\$1 'u +\w'\\$2 'u +\w'\\$3 'u +\w'\\$4 'u +. nr eW \w'\\$1 'u+\w'\\$2 'u+\w'\\$3 'u +\w'\\$4 'u +' in \\n(.iu+\\n(eWu +. \} +. if \\n(.$==5 \{\ +.ta \w'\\$1 'u +\w'\\$2 'u +\w'\\$3 'u +\w'\\$4 'u +\w'\\$5 'u +.nr eW \w'\\$1 'u +\w'\\$2 'u +\w'\\$3 'u +\w'\\$4 'u +\w'\\$5 'u +' in \\n(.iu+\\n(eWu +. \} +.\} +.. +.de Cl +.ti -\\n(eWu +.mN \\$1 +.ie \\n(mN .\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +.el \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +.. +.nr dQ 0 +.de Ds +.ie !"\\$1"" \{\ +. mN d\\$1 +. if \\n(mN \{\ +. nr dQ \\n(dQ+1 +. d\\$1 +. \} +.\} +.el .br +.nf +.. +.de Df +.ie !"\\$1"" \{\ +. mN d\\$1 +. if \\n(mN \{\ +. nr dQ \\n(dQ+1 +. d\\$1 +. \} +.\} +.el .br +.. +.de Dn +\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +.nf +.. +.de dI +.nr d\\n(dQ \\n(dIu +.in \\n(.iu+\\n(dIu +.. +.de dC +.nr d\\n(dQ (\\n(.l-\\n(.i)/4u +.in \\n(.iu+\\n(d\\n(dQu +.. +.de dR +.nr d\\n(dQ (\\n(.l/3)u +.in \\n(.iu+\\n(d\\n(dQu +.. +.de dL +.nr aa 0 +.. +.de De +.br +.if \\n(d\\n(dQ \{\ +. in \\n(.iu-\\n(d\\n(dQu +. rr d\\n(dQ +. nr dQ \\n(dQ-1 +.\} +.fi +.. +.\" +.de Fn +.ie \\n(.$==0 \{\ +. tm Usage: .Fn function_name function_arg(s) ... \\*(Pu +.\} +.el \{\ +. nr cF \\n(.f +. ie \\n(.$==1 .ds f1 \&\\*(nM\\$1\fP\\*(lP\fP\\*(rP\fP +. el \{\ +. ds f1 \\*(nM\\$1\fP\\*(lP +. nr aa 0 +. rC \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +. \} +. if "\\*(iM"" \{\\&\\*(f1 +. ds f1 +. \} +.\} +.. +.\" +.de rC +.rZ \\$1 +.ie \\n(rZ \{\ +. as f1 \f\\n(cF\\*(rP\f\\n(cF\\$1\\$2\\$3\\$4\\$5\\$6\\$7 +.\} +.el \{\ +. ie \\n(aa .as f1 \fP, \\*(aR\\$1 +. el .as f1 \\*(aR\\$1 +. nr aa 1 +. ie \\n(.$>1 .rC \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 +. el .as f1 \fP\\*(rP\fP +.\} +.. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=nroff textwidth=72: diff --git a/tmac/doc.tmac b/tmac/doc.tmac new file mode 100644 index 0000000..70ec41e --- /dev/null +++ b/tmac/doc.tmac @@ -0,0 +1,6957 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" 3. [Deleted. See +.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] +.\" 4. Neither the name of the University nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" +.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +.\" PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR +.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)doc 8.1 (Berkeley) 06/08/93 +.\" +.\" Modified by jjc@jclark.com as follows: the doc-* files are assumed +.\" to be installed as mdoc/doc-* rather than tmac.doc-* (the filename +.\" 'tmac.doc-common' would be too long); when using groff, the doc-* +.\" files are loaded using the 'mso' request. +.\" +.\" Modified by +.\" +.\" Werner LEMBERG and +.\" Ruslan Ermilov +.\" +.\" to make it more readable: using long names and many groff features, +.\" updating and extending documentation, etc. +. +. +.if !\n(.g \ +. ab groff mdoc macros require groff extensions; aborting +. +. +.do if d Dd .nx +. +. +.cp 0 +. +. +.if (\n[.x]\n[.y] < 118) \{\ +. ds doc-msg doc.tmac: groff mdoc macros require groff 1.18 or later, +. as doc-msg " but found groff \n[.x].\n[.y]; aborting +. ab \*[doc-msg] +.\} +. +.\" Handle most rendering options. +. +.nr doc-is-output-html 0 +.if '\*[.T]'html' .nr doc-is-output-html 1 +. +.\" Use -dAD to set the adjustment mode for ordinary body text. +.if !d AD \ +. ds AD b\" +. +.\" Use -rC1 to consecutively number pages across multiple documents. +.\" +.\" We must use consecutive page numbers when using PostScript to +.\" generate HTML images; we must not reset the page number at the +.\" beginning of each document (the 'ps4html' register is automatically +.\" added to the command line by the pre-HTML preprocessor). +.ie !r C \ +. nr C 0 +.el \ +. if !\n[C] \ +. if \n[doc-is-output-html] \{\ +. tm mdoc: consecutive page numbering required for HTML output +. nr C 1 +. \} +.if \n[doc-is-output-html] \ +. nr C 1 +.if r ps4html \ +. nr C 1 +. +.\" Use -rCS=1 to force capitalization of section headings. +.if !r CS .nr CS 0 +. +.\" Use -rCT=1 to force capitalization of page titles in headers. +.if !r CT .nr CT 0 +. +.\" Use -rcR=0 for multiple pages instead of a single, very long page. +.if !r cR \{\ +. if t .nr cR 0 +. if n .nr cR 1 +.\} +. +.\" If continuous rendering, tell tbl not to use keeps. +.ie \n[cR] \ +. nr 3usekeeps 0 +.el \ +. nr 3usekeeps 1 +. +.\" double-sided layout +.ie !r D \ +. nr D 0 +.el \ +. if \n[D] \ +. if \n[doc-is-output-html] \{\ +. tm mdoc: ignoring double-sided layout in HTML output +. nr D 0 +. \} +. +.\" footer distance +.\" +.\" Unlike most of these parameters, we do not set a default for FT; the +.\" doc-set-up-titles macro places page location traps only if not +.\" continuously rendering. +.if r FT \{\ +. \" Validate it. Continuous rendering ignores FT. Measuring a footer +. \" distance from the page top isn't done. A footer distance of over +. \" half the page length is unlikely. A footer distance of less than +. \" one line height is too. +. ie \n[cR] \ +. ds doc-msg footer distance when continuously rendering\" +. el \{\ +. nr doc-tmp 1v +. ds doc-help " (1v=\n[doc-tmp]u)\" +. ie (\n[FT] : (\n[FT] = 0)) \ +. ds doc-msg non-negative footer distance: \n[FT]u\*[doc-help]\" +. el \{\ +. ie (-(\n[FT]) > (\n[.p] / 2)) \{\ +. ds doc-msg implausibly large footer distance:\" +. as doc-msg " \n[FT]u\*[doc-help]\" +. \} +. el \ +. if (-(\n[FT]) < 1v) \{\ +. ds doc-msg implausibly small footer distance:\" +. as doc-msg " \n[FT]u\*[doc-help]\" +. \} +. rm doc-help +. rr doc-tmp +. \} +. \} +. if d doc-msg \{\ +. tm mdoc: ignoring \*[doc-msg] +. rr FT +. rm doc-msg +. \} +.\} +. +.\" (sub)section heading font +.if !d HF \ +. ds HF B\" +. +.\" If HF is a bold style, use bold italics for italics in headings. +.ds doc-heading-style \*[HF]\" +.substring doc-heading-style -1 -1 +.ds doc-heading-family \" empty +.length doc-HF-length \*[HF] +.if (\n[doc-HF-length] > 1) \{\ +. as doc-heading-family \*[HF]\" +. substring doc-heading-family 0 -2 +.\} +.if '\*[doc-heading-style]'B' \ +. if F \*[doc-heading-family]BI \ +. nr doc-remap-I-style-in-headings 1 +.rr doc-HF-length +.rm doc-heading-style +. +.\" \n[HY] is recognized for groff_man(7) compatibility, particularly +.\" via andoc.tmac and man(1); see \n[doc-hyphen-flags] in doc-common. +.if !r HY .nr HY 1 +. +.\" Use -rIN= to set the paragraph indentation amount. +.if !r IN \{\ +. \" We select an integer indentation value in nroff mode because this +. \" value is used additively for multiple purposes; rounding of +. \" accumulating fractions would produce inconsistent results. +. ie t .nr IN 7.2n +. el .nr IN 7n +.\} +. +.\" LL and LT registers are handled by the doc-setup-page-layout macro. +. +.\" TODO: Implement MF string. +. +.\" starting page number +.\" +.\" Unlike most of these parameters, we do not set a default for P; +.\" troff supplies a default starting page number (1). When rendering +.\" for the HTML output device, page numbers are concealed and used for +.\" internal purposes like image embedding. Page numbers are not +.\" rendered at all in continuous rendering mode. +.if r P \{\ +. if \n[doc-is-output-html] \ +. if !(\n[P] = 1) \ +. ds doc-msg in HTML output\" +. if \n[cR] \ +. ds doc-msg when continuously rendering +.\} +.if d doc-msg \{\ +. tm mdoc: ignoring starting page number \*[doc-msg] +. rr P +. rm doc-msg +.\} +. +.\" Setting the page number turns out to be tricky when batch rendering +.\" and switching macro packages. We must use different techniques +.\" depending on whether the transition to the first output page has +.\" happened yet. If it has not, `nl` will be `-1` and we use `pn`. If +.\" it has, we set `%`. Technically this is fragile since in theory a +.\" page could assign a negative value to `nl`. We might then be +.\" justified in saying they've broken the macro package and they get to +.\" keep both pieces. But if not, consider using a nonce register, +.\" initially set but then permanently cleared adjacent to this logic, +.\" and whose state is shared with man (and andoc.tmac, if necessary). +.\" +.\" Also, we can't use the `P` register with grohtml at all. +.ie r ps4html \{\ +. if r P \{\ +. tm mdoc: ignoring starting page number in HTML output +. rr P +. \} +.\} +.el \{\ +. if r P \{\ +. ie (\n[nl] = -1) .pn 0\n[P] +. el .nr % 0\n[P] +. \} +.\} +. +.\" Use -rSN= to set the subsection heading indentation amount. +.if !r SN .nr SN 3n +. +.\" TODO: Implement U register. +. +.\" page number after which to apply letter suffixes +.\" +.\" Unlike most of these parameters, we do not set a default for X; only +.\" the macro an-footer uses it. Page numbers are not rendered at all +.\" in continuous rendering mode. +.if r X \{\ +. af doc-page-letter a +. if \n[doc-is-output-html] \ +. ds doc-msg in HTML output\" +. if \n[cR] \ +. ds doc-msg when continuously rendering +.\} +.if d doc-msg \{\ +. tm mdoc: ignoring page number suffix \*[doc-msg] +. rr X +. rm doc-msg +.\} +. +. +.\" Load startup files. +.ie t \ +. mso mdoc/doc-ditroff +.el \ +. mso mdoc/doc-nroff +. +.mso mdoc/doc-common +.mso mdoc/doc-syms +. +. +.\" NS doc-macro-name global string +.\" NS name of calling request (set in each user-requestable macro) +. +.ds doc-macro-name +.als doc-arg0 doc-macro-name +. +. +.\" NS doc-arg-count global register +.\" NS total number of arguments +.\" XXX: This register name and description aren't quite right, but its +.\" old name `doc-arg-limit` doesn't seem accurate either. Demystify. +. +.nr doc-arg-count 0 +. +. +.\" NS doc-num-args global register +.\" NS number of arguments to handle (must be set to \n[.$] prior to +.\" NS 'doc-parse-arg-vector' request) +. +.nr doc-num-args 0 +. +. +.\" NS doc-arg-ptr global register +.\" NS argument pointer +. +.nr doc-arg-ptr 0 +. +. +.\" NS doc-argXXX global string +.\" NS argument vector +.\" NS +.\" NS limit: +.\" NS doc-arg-count +. +.ds doc-arg1 +. +. +.\" NS doc-typeXXX global register +.\" NS argument type vector (macro=1, string=2, punctuation suffix=3, +.\" NS punctuation prefix=4) +.\" NS +.\" NS limit: +.\" NS doc-arg-count +. +.nr doc-type1 0 +. +. +.\" NS doc-spaceXXX global string +.\" NS space vector +.\" NS +.\" NS limit: +.\" NS doc-arg-count +. +.ds doc-space1 +. +. +.\" NS doc-parse-args macro +.\" NS parse arguments (recursively) ('.doc-parse-args arg ...') +.\" NS +.\" NS modifies: +.\" NS doc-arg-count +.\" NS doc-arg-ptr +.\" NS doc-argXXX +.\" NS doc-spaceXXX +.\" NS doc-typeXXX +.\" NS doc-arg-ptr +.\" NS doc-have-space +.\" NS +.\" NS local variables: +.\" NS doc-reg-dpa +.\" NS doc-reg-dpa1 +.\" NS doc-str-dpa +. +.eo +.de doc-parse-args +. if !\n[doc-arg-count] \ +. doc-set-spacing-1 +. +. nr doc-have-space 0 +. +. if !\n[.$] \ +. return +. +. nr doc-arg-count +1 +. +. \" handle '|' and '...' specially +. ie "\$1"|" \ +. ds doc-arg\n[doc-arg-count] \f[R]|\f[] +. el \{ .ie "\$1"..." \ +. ds doc-arg\n[doc-arg-count] \|.\|.\|. +. el \ +. ds doc-arg\n[doc-arg-count] "\$1 +. \} +. +. \" get argument type and set spacing +. doc-get-arg-type* \n[doc-arg-count] +. nr doc-type\n[doc-arg-count] \n[doc-arg-type] +. doc-set-spacing-\n[doc-arg-type] +. +. \" check whether we have processed the last parameter +. ie (\n[.$] == 1) \ +. nr doc-arg-ptr 0 +. el \{\ +. shift +. doc-parse-args \$@ +. \} +. +. nh +.. +.ec +. +. +.\" NS doc-parse-arg-vector macro +.\" NS parse argument vector (recursive) +.\" NS +.\" NS cf. comments in doc-parse-args +.\" NS +.\" NS modifies: +.\" NS doc-arg-count +.\" NS doc-arg-ptr +.\" NS doc-argXXX +.\" NS doc-num-args +.\" NS doc-spaceXXX +.\" NS doc-typeXXX +.\" NS +.\" NS local variables: +.\" NS doc-reg-dpav +.\" NS doc-reg-dpav1 +.\" NS doc-str-dpav +. +.eo +.de doc-parse-arg-vector +. if !\n[doc-arg-count] \ +. doc-set-spacing-1 +. +. nr doc-arg-count +1 +. +. ie "\*[doc-arg\n[doc-arg-count]]"|" \ +. ds doc-arg\n[doc-arg-count] \f[R]|\f[] +. el \{ .if "\*[doc-arg\n[doc-arg-count]]"..." \ +. ds doc-arg\n[doc-arg-count] \|.\|.\|. +. \} +. +. doc-get-arg-type* \n[doc-arg-count] +. nr doc-type\n[doc-arg-count] \n[doc-arg-type] +. doc-set-spacing-\n[doc-arg-type] +. +. ie (\n[doc-num-args] == 1) \{\ +. nr doc-arg-ptr 0 +. nr doc-num-args 0 +. \} +. el \{\ +. nr doc-num-args -1 +. doc-parse-arg-vector +. \} +. +. nh +.. +.ec +. +. +.\" NS doc-parse-space-vector macro +.\" NS parse space vector (recursive) +.\" NS +.\" NS modifies: +.\" NS doc-arg-count +.\" NS doc-num-args +.\" NS doc-spaceXXX +. +.eo +.de doc-parse-space-vector +. nr doc-arg-count +1 +. +. doc-set-spacing-\n[doc-type\n[doc-arg-count]] +. +. ie (\n[doc-num-args] == 1) \ +. nr doc-num-args 0 +. el \{\ +. nr doc-num-args -1 +. doc-parse-space-vector +. \} +.. +.ec +. +. +.\" NS doc-remaining-args macro +.\" NS output remaining arguments as-is, separated by spaces (until +.\" NS 'doc-num-args' is exhausted) +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-num-args +. +.eo +.de doc-remaining-args +. nr doc-arg-ptr +1 +. nop \)\*[doc-arg\n[doc-arg-ptr]]\c +. +. ie (\n[doc-num-args] == 1) \{\ +. nr doc-arg-ptr 0 +. nr doc-num-args 0 +. \} +. el \{\ +. nop \)\*[doc-space]\c +. nr doc-num-args -1 +. doc-remaining-args +. \} +.. +.ec +. +. +.\" NS doc-append-arg macro +.\" NS append one argument to argument vector: +.\" NS '.doc-append-arg [arg] [type]' +.\" NS +.\" NS modifies: +.\" NS doc-arg-count +.\" NS doc-argXXX +.\" NS doc-typeXXX +. +.eo +.de doc-append-arg +. nr doc-arg-count +1 +. ds doc-arg\n[doc-arg-count] "\$1 +. nr doc-type\n[doc-arg-count] \$2 +. doc-set-spacing-\$2 +.. +.ec +. +. +.\" NS doc-print-and-reset macro +.\" NS finish input line and clean up argument vectors +. +.eo +.de doc-print-and-reset +. if \n[doc-space-mode] \ +. nop \) +. doc-reset-args +.. +.ec +. +. +.\" NS doc-reset-args macro +.\" NS reset argument counters +.\" NS +.\" NS modifies: +.\" NS doc-arg-count +.\" NS doc-arg-ptr +.\" NS doc-have-slot +. +.eo +.de doc-reset-args +. nr doc-arg-count 0 +. nr doc-arg-ptr 0 +. nr doc-have-slot 0 +. +. hy \n[doc-hyphen-flags] +.. +.ec +. +. +.\" NS doc-curr-font global register +.\" NS saved current font +. +.nr doc-curr-font \n[.f] +. +. +.\" NS Fl user macro +.\" NS handle flags (appends '-' and prints flags): '.Fl [arg ...]' +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS +.\" NS local variables: +.\" NS doc-reg-Fl (for communication with doc-flag-recursion) +.\" NS +.\" NS width register 'Fl' set in doc-common +. +.eo +.de Fl +. nr doc-curr-font \n[.f] +. nop \*[doc-Fl-font]\c +. +. if !\n[doc-arg-count] \{\ +. ds doc-macro-name Fl +. doc-parse-args \$@ +. +. \" no arguments +. if !\n[.$] \ +. nop \|\-\|\f[] +. \} +. +. if !\n[doc-arg-count] \ +. return +. +. nr doc-arg-ptr +1 +. ie (\n[doc-arg-count] < \n[doc-arg-ptr]) \{\ +. \" last argument +. nop \|\-\f[]\c +. doc-print-and-reset +. \} +. el \{\ +. ie (\n[doc-type\n[doc-arg-ptr]] == 1) \{\ +. nop \|\-\f[]\c +. \*[doc-arg\n[doc-arg-ptr]] +. \} +. el \{\ +. if (\n[doc-type\n[doc-arg-ptr]] == 3) \ +. nop \|\-\|\c +. +. nr doc-reg-Fl 1 +. doc-flag-recursion +. \}\} +.. +.ec +. +. +.\" NS doc-flag-recursion macro +.\" NS 'Fl' flag recursion routine (special handling) +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS +.\" NS local variables: +.\" NS doc-reg-dfr +.\" NS doc-reg-dfr1 +.\" NS doc-str-dfr +. +.eo +.de doc-flag-recursion +. nr doc-reg-dfr1 \n[doc-type\n[doc-arg-ptr]] +. ds doc-str-dfr "\*[doc-arg\n[doc-arg-ptr]] +. +. ie (\n[doc-reg-dfr1] == 1) \{\ +. nop \f[]\c +. \*[doc-str-dfr] +. \} +. el \{\ +. nr doc-reg-dfr \n[doc-arg-ptr] +. +. ie (\n[doc-reg-dfr1] == 2) \{\ +. \" handle vertical bar -- doc-reg-Fl is set for the first call of +. \" doc-flag-recursion only; we need this to make '.Fl | ...' work +. \" correctly +. ie "\*[doc-str-dfr]"\*[Ba]" \{\ +. if \n[doc-reg-Fl] \ +. nop \|\-\*[doc-space]\c +. nop \)\*[Ba]\c +. \} +. el \{\ +. ie "\*[doc-str-dfr]"\f[R]|\f[]" \{\ +. if \n[doc-reg-Fl] \ +. nop \|\-\*[doc-space]\c +. nop \f[R]|\f[]\c +. \} +. el \{\ +. \" two consecutive hyphen characters? +. ie "\*[doc-str-dfr]"-" \ +. nop \|\-\^\-\|\c +. el \ +. nop \|\%\-\*[doc-str-dfr]\&\c +. \}\}\} +. el \{\ +. nop \f[\n[doc-curr-font]]\c +. nop \)\*[doc-str-dfr]\f[]\c +. \} +. +. ie (\n[doc-arg-count] == \n[doc-arg-ptr]) \{\ +. \" last argument +. if (\n[doc-reg-dfr1] == 4) \ +. nop \|\-\c +. nop \f[\n[doc-curr-font]]\c +. doc-print-and-reset +. \} +. el \{\ +. nr doc-arg-ptr +1 +. ie (\n[doc-type\n[doc-arg-ptr]] == 3) \{\ +. ie (\n[doc-type\n[doc-reg-dfr]] == 4) \ +. nop \|\-\c +. el \ +. nop \)\*[doc-space\n[doc-reg-dfr]]\c +. \} +. el \ +. nop \)\*[doc-space\n[doc-reg-dfr]]\c +. +. shift +. nr doc-reg-Fl 0 +. doc-flag-recursion \$@ +. \}\} +.. +.ec +. +. +.\" NS doc-print-recursive macro +.\" NS general name recursion routine (print remaining arguments) +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS +.\" NS local variables: +.\" NS doc-reg-dpr +.\" NS doc-reg-dpr1 +.\" NS doc-str-dpr +. +.eo +.de doc-print-recursive +. nr doc-reg-dpr1 \n[doc-type\n[doc-arg-ptr]] +. ds doc-str-dpr "\*[doc-arg\n[doc-arg-ptr]] +. +. if \n[doc-do-capitalize] .stringup doc-str-dpr +. +. ie (\n[doc-reg-dpr1] == 1) \{\ +. nop \f[\n[doc-curr-font]]\c +. \*[doc-str-dpr] +. \} +. el \{\ +. nr doc-reg-dpr \n[doc-arg-ptr] +. +. \" the '\%' prevents hyphenation on a dash ('-') +. ie (\n[doc-reg-dpr1] == 2) \ +. nop \%\*[doc-str-dpr]\&\c +. el \{\ +. \" punctuation character +. nop \f[\n[doc-curr-font]]\c +. nop \)\*[doc-str-dpr]\f[]\c +. \} +. +. nr doc-arg-ptr +1 +. ie (\n[doc-arg-count] < \n[doc-arg-ptr]) \{\ +. \" last argument +. nop \f[\n[doc-curr-font]]\c +. doc-print-and-reset +. \} +. el \{\ +. nop \)\*[doc-space\n[doc-reg-dpr]]\c +. doc-print-recursive +. \}\} +.. +.ec +. +. +.\" NS doc-print-prefixes macro +.\" NS print leading prefixes +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +. +.eo +.de doc-print-prefixes +. while (\n[doc-arg-count] >= \n[doc-arg-ptr]) \{\ +. if !(\n[doc-type\n[doc-arg-ptr]] == 4) \ +. break +. nop \f[\n[doc-curr-font]]\c +. nop \)\*[doc-arg\n[doc-arg-ptr]]\f[]\c +. nr doc-arg-ptr +1 +. \} +.. +.ec +. +. +.\" NS doc-generic-macro macro +.\" NS this is the skeleton for most simple macros +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +. +.eo +.de doc-generic-macro +. if !\n[doc-arg-count] \{\ +. ie \n[.$] \{\ +. ds doc-macro-name \$0 +. doc-parse-args \$@ +. \} +. el \ +. tm Usage: .\$0 \*[doc-\$0-usage] ... (#\n[.c]) +. \} +. +. if !\n[doc-arg-count] \ +. return +. +. nr doc-arg-ptr +1 +. ie (\n[doc-arg-count] >= \n[doc-arg-ptr]) \{\ +. if (\n[doc-type\n[doc-arg-ptr]] == 1) \{\ +. tmc mdoc warning: Using a macro as first argument +. tm1 " cancels effect of .\$0 (#\n[.c]) +. +. \" the right action here would be to reset the argument counters +. \" and bail out -- unfortunately, a small number of manual pages +. \" (less than 2% for FreeBSD which has been used for testing) +. \" relied on the old behaviour (silently ignore this error), +. \" so it is commented out +. +.\" doc-reset-args +. \} +.\" el \{\ +. nr doc-curr-font \n[.f] +. nop \*[doc-\$0-font]\c +. doc-print-recursive +.\" \} +. \} +. el \{\ +. tm Usage: .\$0 \*[doc-\$0-usage] ... (#\n[.c]) +. doc-reset-args +. \} +.. +.ec +. +. +.\" NS Ar user macro +.\" NS command-line 'argument' macro: '.Ar [args ...]' +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS +.\" NS local variable: +.\" NS doc-str-Ar-default +.\" NS +.\" NS width register 'Ar' set in doc-common +. +.ds doc-str-Ar-default "file\ .\|.\|. +. +.eo +.de Ar +. nr doc-curr-font \n[.f] +. nop \*[doc-Ar-font]\c +. +. if !\n[doc-arg-count] \{\ +. ds doc-macro-name Ar +. doc-parse-args \$@ +. +. \" no argument +. if !\n[.$] \ +. nop \)\*[doc-str-Ar-default]\&\f[] +. \} +. +. if !\n[doc-arg-count] \ +. return +. +. nr doc-arg-ptr +1 +. doc-print-prefixes +. ie (\n[doc-arg-count] < \n[doc-arg-ptr]) \{\ +. nop \)\*[doc-str-Ar-default]\&\f[]\c +. doc-print-and-reset +. \} +. el \{\ +. if !(\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +. \" replace previous argument (Ar) with default value +. nr doc-arg-ptr -1 +. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Ar-default] +. nr doc-type\n[doc-arg-ptr] 2 +. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +. +. \" recompute space vector for remaining arguments +. nr doc-num-args (\n[doc-arg-count] - \n[doc-arg-ptr]) +. nr doc-arg-count \n[doc-arg-ptr] +. doc-parse-space-vector +. \} +. doc-print-recursive +. \} +.. +.ec +. +. +.\" NS Ad user macro +.\" NS Addresses +.\" NS +.\" NS width register 'Ad' set in doc-common +. +.als Ad doc-generic-macro +.ds doc-Ad-usage address +. +. +.\" NS doc-indent-synopsis global register +.\" NS indentation in synopsis +. +.nr doc-indent-synopsis 0 +. +. +.\" NS doc-indent-synopsis-active global register (bool) +.\" NS indentation in synopsis active +. +.nr doc-indent-synopsis-active 0 +. +. +.\" NS Cd user macro +.\" NS config declaration (for section 4 SYNOPSIS) +.\" NS +.\" NS this function causes a break; it uses the 'Nm' font +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-indent-synopsis +.\" NS doc-macro-name +.\" NS +.\" NS width register 'Cd' set in doc-common +. +.eo +.de Cd +. if !\n[doc-arg-count] \{\ +. ie \n[.$] \{\ +. ds doc-macro-name Cd +. doc-parse-args \$@ +. \} +. el \ +. tm Usage: .Cd configuration_file_declaration ... (#\n[.c]) +. \} +. +. if !\n[doc-arg-count] \ +. return +. +. nr doc-arg-ptr +1 +. ie (\n[doc-arg-count] >= \n[doc-arg-ptr]) \{\ +. nr doc-curr-font \n[.f] +. +. ie \n[doc-in-synopsis-section] \{\ +. ie "\*[doc-macro-name]"Cd" \{\ +. br +. if !\n[doc-indent-synopsis] \ +. nr doc-indent-synopsis \n[doc-display-indent]u +. if !\n[doc-indent-synopsis-active] \ +. in +\n[doc-indent-synopsis]u +. ti -\n[doc-indent-synopsis]u +. nop \*[doc-Nm-font]\c +. doc-print-recursive +. if !\n[doc-indent-synopsis-active] \ +. in -\n[doc-indent-synopsis]u +. \} +. el \{\ +. nop \*[doc-Nm-font]\c +. doc-print-recursive +. \}\} +. el \{\ +. nop \*[doc-Nm-font]\c +. doc-print-recursive +. \}\} +. el \{\ +. tm Usage: .Cd configuration_file_declaration ... (#\n[.c]) +. doc-reset-args +. \} +.. +.ec +. +. +.\" NS Cm user macro +.\" NS interactive command modifier (flag) +.\" NS +.\" NS width register 'Cm' set in doc-common +. +.als Cm doc-generic-macro +.ds doc-Cm-usage interactive_command_modifier +. +. +.\" NS Dv user macro +.\" NS defined variable +.\" NS +.\" NS this function uses the 'Er' font +.\" NS +.\" NS width register 'Dv' set in doc-common +. +.als Dv doc-generic-macro +.ds doc-Dv-usage defined_variable +.als doc-Dv-font doc-Er-font +. +. +.\" NS Em user macro +.\" NS emphasis +.\" NS +.\" NS width register 'Em' set in doc-common +. +.als Em doc-generic-macro +.ds doc-Em-usage text +. +. +.\" NS Er user macro +.\" NS errno type +.\" NS +.\" NS width register 'Er' set in doc-common +. +.als Er doc-generic-macro +.ds doc-Er-usage text +. +. +.\" NS Ev user macro +.\" NS environment variable +.\" NS +.\" NS width register 'Ev' set in doc-common +. +.als Ev doc-generic-macro +.ds doc-Ev-usage text +. +. +.\" NS doc-have-decl global register (bool) +.\" NS subroutine test (in synopsis only) +. +.nr doc-have-decl 0 +. +. +.\" NS doc-have-var global register (bool) +.\" NS whether last type is a variable type +. +.nr doc-have-var 0 +. +. +.\" NS doc-do-func-decl macro +.\" NS do something special while in SYNOPSIS +.\" NS +.\" NS modifies: +.\" NS doc-curr-font +.\" NS doc-have-decl +.\" NS doc-have-var +. +.eo +.de doc-do-func-decl +. if \n[doc-in-synopsis-section] \{\ +. \" if a variable type was the last thing given, want vertical space +. if \n[doc-have-var] \{\ +. doc-paragraph +. nr doc-have-var 0 +. \} +. \" if a subroutine was the last thing given, want vertical space +. if \n[doc-have-func] \{\ +. ie \n[doc-have-decl] \ +. br +. el \ +. doc-paragraph +. \} +. nr doc-have-decl 1 +. \} +. +. nr doc-curr-font \n[.f] +.. +.ec +. +. +.\" NS Fd user macro +.\" NS function declaration -- not callable +.\" NS +.\" NS this function causes a break +.\" NS +.\" NS width register 'Fd' set in doc-common +. +.eo +.de Fd +. ie ((\n[.$] >= 1) & (\n[doc-arg-count] == 0)) \{\ +. doc-do-func-decl +. nop \*[doc-Fd-font]\$* +. br +. ft \n[doc-curr-font] +. \} +. el \{\ +. tm Usage: .Fd function_declaration -- Fd is not callable (#\n[.c]) +. doc-reset-args +. \} +.. +.ec +. +. +.\" NS In user macro +.\" NS #include statement in SYNOPSIS +.\" NS if not in SYNOPSIS +.\" NS +.\" NS this function causes a break; it uses the 'Fd' font +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-indent-synopsis +.\" NS doc-macro-name +.\" NS +.\" NS width register 'In' set in doc-common +. +.eo +.de In +. if !\n[doc-arg-count] \{\ +. ie \n[.$] \{\ +. ds doc-macro-name In +. doc-parse-args \$@ +. \} +. el \ +. tm Usage: .In include_file ... (#\n[.c]) +. \} +. +. if !\n[doc-arg-count] \ +. return +. +. nr doc-arg-ptr +1 +. doc-print-prefixes +. ie ((\n[doc-arg-count] >= \n[doc-arg-ptr]) & (\n[doc-type\n[doc-arg-ptr]] == 2)) \{\ +. nr doc-curr-font \n[.f] +. +. ie \n[doc-in-synopsis-section] \{\ +. ie "\*[doc-macro-name]"In" \{\ +. doc-do-func-decl +. nop \*[doc-Fd-font]#include <\*[doc-arg\n[doc-arg-ptr]]> +. ft \n[doc-curr-font] +. br +. nr doc-arg-ptr +1 +. ie (\n[doc-arg-count] >= \n[doc-arg-ptr]) \ +. doc-print-recursive +. el \ +. doc-reset-args +. \} +. el \{\ +. ds doc-arg\n[doc-arg-ptr] "<\*[doc-Pa-font]\*[doc-arg\n[doc-arg-ptr]] +. as doc-arg\n[doc-arg-ptr] \f[\n[doc-curr-font]]> +. doc-print-recursive +. \}\} +. el \{\ +. ds doc-arg\n[doc-arg-ptr] "<\*[doc-Pa-font]\*[doc-arg\n[doc-arg-ptr]] +. as doc-arg\n[doc-arg-ptr] \f[\n[doc-curr-font]]> +. doc-print-recursive +. \}\} +. el \{\ +. tm Usage: .In include_file ... (#\n[.c]) +. doc-reset-args +. \} +.. +.ec +. +. +.\" NS Fr user macro +.\" NS function return value +.\" NS +.\" NS this function uses the 'Ar' font +.\" NS +.\" NS width register 'Fr' set in doc-common +. +.als Fr doc-generic-macro +.ds doc-Fr-usage function_return_value +.als doc-Fr-font doc-Ar-font +. +. +.\" NS Ic user macro +.\" NS interactive command +.\" NS +.\" NS width register 'Ic' set in doc-common +. +.als Ic doc-generic-macro +.ds doc-Ic-usage interactive_command +. +. +.\" NS Li user macro +.\" NS literals +.\" NS +.\" NS width register 'Li' set in doc-common +. +.als Li doc-generic-macro +.ds doc-Li-usage argument +. +. +.\" NS Ms user macro +.\" NS math symbol +.\" NS +.\" NS this function uses the 'Sy' font +.\" NS +.\" NS width register 'Ms' set in doc-common +. +.als Ms doc-generic-macro +.ds doc-Ms-usage math_symbol +.als doc-Ms-font doc-Sy-font +. +. +.\" NS doc-topic-name global string +.\" NS save first invocation of .Nm +. +.ds doc-topic-name \" empty +. +. +.\" NS Nm user macro +.\" NS name of command or page topic +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-topic-name +.\" NS doc-curr-font +.\" NS doc-indent-synopsis +.\" NS doc-indent-synopsis-active +.\" NS doc-macro-name +.\" NS +.\" NS width register 'Nm' set in doc-common +. +.eo +.de Nm +. if !\n[doc-arg-count] \{\ +. ds doc-macro-name Nm +. ie \n[.$] \{\ +. \" Handle '.Nm ...' in "Name" section: don't use a special font. +. ie \n[doc-in-name-section] \{\ +. if "\*[doc-topic-name]"" \ +. ds doc-topic-name "\$1\" +. No \$@ +. \} +. el \ +. doc-parse-args \$@ +. \} +. el \{\ +. ie "\*[doc-topic-name]"" \ +. tm Usage: .Nm name ... (#\n[.c]) +. el \ +. doc-parse-args \*[doc-topic-name] +. \}\} +. +. if !\n[doc-arg-count] \ +. return +. +. nr doc-arg-ptr +1 +. doc-print-prefixes +. ie (\n[doc-arg-count] < \n[doc-arg-ptr]) \{\ +. \" last argument +. ie "\*[doc-topic-name]"" \{\ +. tm Usage: .Nm name ... (#\n[.c]) +. doc-reset-args +. \} +. el \{\ +. nop \*[doc-Nm-font]\*[doc-topic-name]\f[]\c +. doc-print-and-reset +. \}\} +. el \{\ +. nr doc-curr-font \n[.f] +. +. ie !(\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +. ie "\*[doc-topic-name]"" \ +. tm Usage: .Nm name ... (#\n[.c]) +. el \{\ +. \" replace previous argument (Nm) with default value +. nr doc-arg-ptr -1 +. ds doc-arg\n[doc-arg-ptr] "\*[doc-Nm-font]\*[doc-topic-name]\f[] +. nr doc-type\n[doc-arg-ptr] 2 +. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +. +. \" recompute space vector for remaining arguments +. nr doc-num-args (\n[doc-arg-count] - \n[doc-arg-ptr]) +. nr doc-arg-count \n[doc-arg-ptr] +. doc-parse-space-vector +. \}\} +. el \{\ +. \" Handle '.Nm ...' in "Synopsis" section. +. if \n[doc-in-synopsis-section] \{\ +. if "\*[doc-macro-name]"Nm" \{\ +. br +. if !\n[doc-indent-synopsis] \{\ +. doc-get-width "\*[doc-arg\n[doc-arg-ptr]]" +. nr doc-indent-synopsis ((\n[doc-width]u + 1u) * \n[doc-fixed-width]u) +. \} +. if !\n[doc-indent-synopsis-active] \{\ +. in +\n[doc-indent-synopsis]u +. nr doc-indent-synopsis-active 1 +. \} +. ti -\n[doc-indent-synopsis]u +. \}\} +. +. nop \*[doc-Nm-font]\c +. \} +. doc-print-recursive +. \} +.. +.ec +. +. +.\" NS Pa user macro +.\" NS pathname: '.Pa [arg ...]' +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS +.\" NS width register 'Pa' set in doc-common +. +.eo +.de Pa +. if !\n[doc-arg-count] \{\ +. ds doc-macro-name Pa +. doc-parse-args \$@ +. +. \" default value +. if !\n[.$] \ +. nop \*[doc-Pa-font]\[ti]\f[] +. \} +. +. if !\n[doc-arg-count] \ +. return +. +. nr doc-arg-ptr +1 +. doc-print-prefixes +. ie (\n[doc-arg-count] >= \n[doc-arg-ptr]) \{\ +. nr doc-curr-font \n[.f] +. nop \*[doc-Pa-font]\c +. if !(\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +. \" replace previous argument (Pa) with default value +. nr doc-arg-ptr -1 +. ds doc-arg\n[doc-arg-ptr] \[ti] +. nr doc-type\n[doc-arg-ptr] 2 +. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +. +. \" recompute space vector for remaining arguments +. nr doc-num-args (\n[doc-arg-count] - \n[doc-arg-ptr]) +. nr doc-arg-count \n[doc-arg-ptr] +. doc-parse-space-vector +. \} +. doc-print-recursive +. \} +. el \{\ +. nop \*[doc-Pa-font]\[ti]\f[]\c +. doc-print-and-reset +. \} +.. +.ec +. +. +.\" NS Sy user macro +.\" NS symbolics +.\" NS +.\" NS width register 'Sy' set in doc-common +. +.als Sy doc-generic-macro +.ds doc-Sy-usage symbolic_text +. +. +.\" NS Me user macro +.\" NS menu entries +.\" NS +.\" NS width register 'Me' set in doc-common +. +.als Me doc-generic-macro +.ds doc-Me-usage menu_entry +. +. +.\" NS Tn user macro +.\" NS trade name +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS +.\" NS width register 'Tn' set in doc-common +. +.eo +.de Tn +. if !\n[doc-arg-count] \{\ +. ie \n[.$] \{\ +. ds doc-macro-name Tn +. doc-parse-args \$@ +. \} +. el \ +. tm Usage: .Tn trade_name ... (#\n[.c]) +. \} +. +. if !\n[doc-arg-count] \ +. return +. +. nr doc-arg-ptr +1 +. ie (\n[doc-arg-count] >= \n[doc-arg-ptr]) \{\ +. nr doc-curr-font \n[.f] +. nop \)\c +. ie !\n[doc-is-reference] \{\ +. nop \)\*[doc-Tn-font]\c +. doc-print-recursive +. \} +. el \ +. doc-do-references +. \} +. el \{\ +. tm Usage: .Tn trade_name ... (#\n[.c]) +. doc-reset-args +. \} +.. +.ec +. +. +.\" NS Va user macro +.\" NS variable name +.\" NS +.\" NS width register 'Va' set in doc-common +. +.als Va doc-generic-macro +.ds doc-Va-usage variable_name +. +. +.\" NS No user macro +.\" NS normal text macro (default text style if mess up) +.\" NS +.\" NS width register 'No' set in doc-common +. +.als No doc-generic-macro +.ds doc-No-usage normal_text +. +. +.\" NS doc-quote-left global string +.\" NS left quotation character for 'doc-enclose-string' and +.\" NS 'doc-enclose-open' +. +.ds doc-quote-left +. +. +.\" NS doc-quote-right global string +.\" NS right quotation character for 'doc-enclose-string' and +.\" NS 'doc-enclose-close' +. +.ds doc-quote-right +. +. +.\" NS Op user macro +.\" NS option expression (i.e., enclose string in square brackets) +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Op' set in doc-common +. +.eo +.de Op +. if !\n[doc-arg-count] \ +. ds doc-macro-name Op +. +. ds doc-quote-left "\*[doc-left-bracket] +. ds doc-quote-right "\*[doc-right-bracket] +. +. doc-enclose-string \$@ +.. +.ec +. +. +.\" NS Aq user macro +.\" NS enclose string in angle brackets +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Aq' set in doc-common +. +.eo +.de Aq +. if !\n[doc-arg-count] \ +. ds doc-macro-name Aq +. +. ie "\*[doc-macro-name]"An" \{\ +. ds doc-quote-left < +. ds doc-quote-right > +. \} +. el \{\ +. ds doc-quote-left \[la] +. ds doc-quote-right \[ra] +. \} +. +. doc-enclose-string \$@ +.. +.ec +. +. +.\" NS Bq user macro +.\" NS enclose string in square brackets +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Bq' set in doc-common +. +.eo +.de Bq +. if !\n[doc-arg-count] \ +. ds doc-macro-name Bq +. +. ds doc-quote-left "\*[doc-left-bracket] +. ds doc-quote-right "\*[doc-right-bracket] +. +. doc-enclose-string \$@ +.. +.ec +. +. +.\" NS Brq user macro +.\" NS enclose string in braces +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Brq' set in doc-common +. +.eo +.de Brq +. if !\n[doc-arg-count] \ +. ds doc-macro-name Brq +. +. ds doc-quote-left { +. ds doc-quote-right } +. +. doc-enclose-string \$@ +.. +.ec +. +. +.\" NS Dq user macro +.\" NS enclose string in double quotes +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Dq' set in doc-common +. +.eo +.de Dq +. if !\n[doc-arg-count] \ +. ds doc-macro-name Dq +. +. ds doc-quote-left "\*[Lq] +. ds doc-quote-right "\*[Rq] +. +. doc-enclose-string \$@ +.. +.ec +. +. +.\" NS Eq user macro +.\" NS enclose string in user-defined quotes (args 1 and 2) +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Eq' set in doc-common +. +.eo +.de Eq +. if !\n[doc-arg-count] \ +. ds doc-macro-name Eq +. +. ds doc-quote-left "\$1 +. ds doc-quote-right "\$2 +. +. shift 2 +. doc-enclose-string \$@ +.. +.ec +. +. +.\" NS Pq user macro +.\" NS enclose string in parentheses +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Pq' set in doc-common +. +.eo +.de Pq +. if !\n[doc-arg-count] \ +. ds doc-macro-name Pq +. +. ds doc-quote-left "\*[doc-left-parenthesis] +. ds doc-quote-right "\*[doc-right-parenthesis] +. +. doc-enclose-string \$@ +.. +.ec +. +. +.\" NS Ql user macro +.\" NS quoted literal +.\" +.\" is in file doc-[dit|n]roff +. +. +.\" NS Qq user macro +.\" NS enclose string in straight double quotes +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Qq' set in doc-common +. +.eo +.de Qq +. if !\n[doc-arg-count] \ +. ds doc-macro-name Qq +. +. ds doc-quote-left "\*[q] +. ds doc-quote-right "\*[q] +. +. doc-enclose-string \$@ +.. +.ec +. +. +.\" NS Sq user macro +.\" NS enclose string in single quotes +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Sq' set in doc-common +. +.eo +.de Sq +. if !\n[doc-arg-count] \ +. ds doc-macro-name Sq +. +. ds doc-quote-left "\*[doc-left-singlequote] +. ds doc-quote-right "\*[doc-right-singlequote] +. +. doc-enclose-string \$@ +.. +.ec +. +. +.\" NS Es user macro +.\" NS set up arguments (i.e., the left and right quotation character +.\" NS as first and second argument) for .En call +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS doc-quote-right +. +.eo +.de Es +. if !\n[doc-arg-count] \{\ +. ie (\n[.$] > 2) \{\ +. ds doc-macro-name Es +. doc-parse-args \$@ +. \} +. el \{\ +. ds doc-quote-left "\$1 +. ds doc-quote-right "\$2 +. \}\} +. +. if !\n[doc-arg-count] \ +. return +. +. nr doc-arg-ptr +1 +. ds doc-quote-left "\*[doc-arg\n[doc-arg-ptr]] +. nr doc-arg-ptr +1 +. ds doc-quote-right "\*[doc-arg\n[doc-arg-ptr]] +. nr doc-arg-ptr +1 +. ie (\n[doc-arg-count] >= \n[doc-arg-ptr]) \ +. doc-do-\n[doc-type\n[doc-arg-ptr]] +. el \ +. doc-print-and-reset +.. +.ec +. +. +.\" NS doc-have-slot global register (bool) +.\" NS set if 'doc-enclose-string' has created a slot for closing +.\" NS delimiter +. +.nr doc-have-slot 0 +. +. +.\" NS doc-enclose-string macro +.\" NS enclose string with given args (e.g. [ and ]) +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-argXXX +.\" NS doc-have-slot +.\" NS +.\" NS local variables: +.\" NS doc-reg-des +.\" NS doc-reg-des1 +.\" NS doc-reg-des2 +.\" NS +.\" NS requires: +.\" NS doc-quote-left +.\" NS doc-quote-right +. +.eo +.de doc-enclose-string +. if \n[doc-in-synopsis-section] \ +. doc-set-hard-space +. +. if !\n[doc-arg-count] \{\ +. ie \n[.$] \ +. doc-parse-args \$@ +. el \{\ +. nop \)\*[doc-quote-left]\*[doc-quote-right] +. \}\} +. +. if !\n[doc-arg-count] \ +. return +. +. nr doc-curr-font \n[.f] +. +. nr doc-arg-ptr +1 +. doc-print-prefixes +. \" the final '\)' prevents hyphenation in case next character is '\%' +. nop \)\*[doc-quote-left]\)\c +. ie (\n[doc-arg-count] < \n[doc-arg-ptr]) \{\ +. \" last argument +. nop \)\*[doc-quote-right]\)\c +. doc-print-and-reset +. \} +. el \{\ +. \" test whether last arguments are of type closing punctuation +. \" resp. suffix +. ie (\n[doc-type\n[doc-arg-count]] == 3) \{\ +. nr doc-reg-des (\n[doc-arg-count] - 1) +. while (\n[doc-type\n[doc-reg-des]] == 3) \ +. nr doc-reg-des -1 +. +. \" prepend closing delimiter +. nr doc-reg-des +1 +. ds doc-arg\n[doc-reg-des] "\*[doc-quote-right]\)\*[doc-arg\n[doc-reg-des]] +. \} +. el \{\ +. \" test whether last arguments are macros which continue the line +. \" logically +. nr doc-reg-des \n[doc-arg-count] +. while (\n[doc-reg-des] >= \n[doc-arg-ptr]) \{\ +. if !\A'\*[doc-arg\n[doc-reg-des]]' \ +. break +. if !d doc-after-\*[doc-arg\n[doc-reg-des]] \ +. break +. nr doc-reg-des -1 +. \} +. +. \" if there are no trailing macros to be skipped, append argument +. ie (\n[doc-reg-des] == \n[doc-arg-count]) \ +. doc-append-arg "\)\*[doc-quote-right]\)" 3 +. el \{\ +. \" if a previous call to 'doc-enclose-string' has already +. \" created a slot, prepend argument +. ie \n[doc-have-slot] \ +. ds doc-arg\n[doc-reg-des] "\*[doc-quote-right]\)\*[doc-arg\n[doc-reg-des]] +. el \{\ +. \" we have to shift all arguments to the right +. nr doc-reg-des +1 +. nr doc-reg-des1 \n[doc-arg-count] +. nr doc-reg-des2 (\n[doc-arg-count] + 1) +. while (\n[doc-reg-des1] >= \n[doc-reg-des]) \{\ +. rn doc-arg\n[doc-reg-des1] doc-arg\n[doc-reg-des2] +. rnn doc-type\n[doc-reg-des1] doc-type\n[doc-reg-des2] +. rn doc-space\n[doc-reg-des1] doc-space\n[doc-reg-des2] +. nr doc-reg-des1 -1 +. nr doc-reg-des2 -1 +. \} +. nr doc-arg-count +1 +. +. \" finally, insert closing delimiter into the freed slot and +. \" recompute spacing vector +. ds doc-arg\n[doc-reg-des] "\)\*[doc-quote-right]\) +. nr doc-type\n[doc-reg-des] 3 +. nr doc-num-args (\n[doc-arg-count] - \n[doc-reg-des] + 1) +. nr doc-arg-count (\n[doc-reg-des] - 1) +. doc-parse-space-vector +. nr doc-have-slot 1 +. \}\}\} +. +. doc-do-\n[doc-type\n[doc-arg-ptr]] +. \} +. +. if \n[doc-in-synopsis-section] \ +. doc-set-soft-space +.. +.ec +. +. +.\" NS En user macro +.\" NS enclose arguments with quotation characters set up with '.Es' +. +.als En doc-enclose-string +. +. +.\" NS Ao user macro +.\" NS angle open +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS +.\" NS width register 'Ao' set in doc-common +. +.eo +.de Ao +. if !\n[doc-arg-count] \ +. ds doc-macro-name Ao +. +. ie "\*[doc-macro-name]"An" \ +. ds doc-quote-left < +. el \ +. ds doc-quote-left \[la] +. +. doc-enclose-open \$@ +.. +.ec +. +. +.\" NS Ac user macro +.\" NS angle close +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Ac' set in doc-common +. +.eo +.de Ac +. if !\n[doc-arg-count] \ +. ds doc-macro-name Ac +. +. ie "\*[doc-macro-name]"An" \ +. ds doc-quote-right > +. el \ +. ds doc-quote-right \[ra] +. +. doc-enclose-close \$@ +.. +.ec +. +. +.\" NS Bo user macro +.\" NS bracket open +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS +.\" NS width register 'Bo' set in doc-common +. +.eo +.de Bo +. if !\n[doc-arg-count] \ +. ds doc-macro-name Bo +. +. ds doc-quote-left "\*[doc-left-bracket] +. +. doc-enclose-open \$@ +.. +.ec +. +. +.\" NS Bc user macro +.\" NS bracket close +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Bc' set in doc-common +. +.eo +.de Bc +. if !\n[doc-arg-count] \ +. ds doc-macro-name Bc +. +. ds doc-quote-right "\*[doc-right-bracket] +. +. doc-enclose-close \$@ +.. +.ec +. +. +.\" NS Bro user macro +.\" NS brace open +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS +.\" NS width register 'Bro' set in doc-common +. +.eo +.de Bro +. if !\n[doc-arg-count] \ +. ds doc-macro-name Bo +. +. ds doc-quote-left { +. +. doc-enclose-open \$@ +.. +.ec +. +. +.\" NS Brc user macro +.\" NS brace close +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Brc' set in doc-common +. +.eo +.de Brc +. if !\n[doc-arg-count] \ +. ds doc-macro-name Bc +. +. ds doc-quote-right } +. +. doc-enclose-close \$@ +.. +.ec +. +. +.\" NS Do user macro +.\" NS double quote open +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS +.\" NS width register 'Do' set in doc-common +. +.eo +.de Do +. if !\n[doc-arg-count] \ +. ds doc-macro-name Do +. +. ds doc-quote-left "\*[Lq] +. +. doc-enclose-open \$@ +.. +.ec +. +. +.\" NS Dc user macro +.\" NS double quote close +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Dc' set in doc-common +. +.eo +.de Dc +. if !\n[doc-arg-count] \ +. ds doc-macro-name Dc +. +. ds doc-quote-right "\*[Rq] +. +. doc-enclose-close \$@ +.. +.ec +. +. +.\" NS Eo user macro +.\" NS enclose open (using first argument as beginning of enclosure) +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS +.\" NS width register 'Eo' set in doc-common +. +.eo +.de Eo +. if !\n[doc-arg-count] \ +. ds doc-macro-name Eo +. +. ds doc-quote-left "\$1 +. +. shift +. doc-enclose-open \$@ +.. +.ec +. +. +.\" NS Ec user macro +.\" NS enclose close (using first argument as end of enclosure) +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Ec' set in doc-common +. +.eo +.de Ec +. if !\n[doc-arg-count] \ +. ds doc-macro-name Ec +. +. ds doc-quote-right "\$1 +. +. shift +. doc-enclose-close \$@ +.. +.ec +. +. +.\" NS Oo user macro +.\" NS option open +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS +.\" NS width register 'Oo' set in doc-common +. +.eo +.de Oo +. if !\n[doc-arg-count] \ +. ds doc-macro-name Oo +. +. ds doc-quote-left [ +. +. doc-enclose-open \$@ +.. +.ec +. +. +.\" NS Oc user macro +.\" NS option close +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Oc' set in doc-common +. +.eo +.de Oc +. if !\n[doc-arg-count] \ +. ds doc-macro-name Oc +. +. ds doc-quote-right ] +. +. doc-enclose-close \$@ +.. +.ec +. +. +.\" NS Po user macro +.\" NS parenthesis open +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS +.\" NS width register 'Po' set in doc-common +. +.eo +.de Po +. if !\n[doc-arg-count] \ +. ds doc-macro-name Po +. +. ds doc-quote-left "\*[doc-left-parenthesis] +. +. doc-enclose-open \$@ +.. +.ec +. +. +.\" NS Pc user macro +.\" NS parenthesis close +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Pc' set in doc-common +. +.eo +.de Pc +. if !\n[doc-arg-count] \ +. ds doc-macro-name Pc +. +. ds doc-quote-right "\*[doc-right-parenthesis] +. +. doc-enclose-close \$@ +.. +.ec +. +. +.\" NS Qo user macro +.\" NS straight double quote open +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS +.\" NS width register 'Qo' set in doc-common +. +.eo +.de Qo +. if !\n[doc-arg-count] \ +. ds doc-macro-name Qo +. +. ds doc-quote-left "\*[q] +. +. doc-enclose-open \$@ +.. +.ec +. +. +.\" NS Qc user macro +.\" NS straight double quote close +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Qc' set in doc-common +. +.eo +.de Qc +. if !\n[doc-arg-count] \ +. ds doc-macro-name Qc +. +. ds doc-quote-right "\*[q] +. +. doc-enclose-close \$@ +.. +.ec +. +. +.\" NS So user macro +.\" NS single quote open +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS +.\" NS width register 'So' set in doc-common +. +.eo +.de So +. if !\n[doc-arg-count] \ +. ds doc-macro-name So +. +. ds doc-quote-left "\*[doc-left-singlequote] +. +. doc-enclose-open \$@ +.. +.ec +. +. +.\" NS Sc user macro +.\" NS single quote close +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Sc' set in doc-common +. +.eo +.de Sc +. if !\n[doc-arg-count] \ +. ds doc-macro-name Sc +. +. ds doc-quote-right "\*[doc-right-singlequote] +. +. doc-enclose-close \$@ +.. +.ec +. +. +.\" NS Xo user macro +.\" NS extend open +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS +.\" NS width register 'Xo' set in doc-common +. +.eo +.de Xo +. if !\n[doc-arg-count] \ +. ds doc-macro-name Xo +. +. ds doc-quote-left +. +. doc-enclose-open \$@ +.. +.ec +. +. +.\" NS Xc user macro +.\" NS extend close +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Xc' set in doc-common +. +.eo +.de Xc +. if !\n[doc-arg-count] \ +. ds doc-macro-name Xc +. +. ds doc-quote-right +. +. doc-enclose-close \$@ +.. +.ec +. +. +.\" NS doc-nesting-level global register +.\" NS used by 'doc-enclose-open' and 'doc-enclose-close' +. +.nr doc-nesting-level 0 +. +. +.\" NS doc-in-list global register (bool) +.\" NS whether we are in (logical) .It +. +.nr doc-in-list 0 +. +. +.\" NS doc-enclose-open macro +.\" NS enclose string open +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-nesting-level +. +.eo +.de doc-enclose-open +. if !\n[doc-arg-count] \ +. doc-parse-args \$@ +. +. nr doc-arg-ptr +1 +. doc-print-prefixes +. nr doc-arg-ptr -1 +. +. nop \)\*[doc-quote-left]\)\c +. +. \" start enclosure box +. box doc-enclosure-box\n[doc-nesting-level] +. ev doc-enclosure-env\n[doc-nesting-level] +. evc 0 +. in 0 +. nf +. \" we insert something to make .chop always work +. nop \&\c +. +. \" increase nesting level *after* parsing of arguments +. nr doc-nesting-level +1 +. +. if \n[doc-arg-count] \{\ +. nr doc-arg-ptr +1 +. ie (\n[doc-arg-count] >= \n[doc-arg-ptr]) \ +. doc-print-recursive +. el \ +. doc-reset-args +. \} +.. +.ec +. +. +.\" NS doc-enclose-close macro +.\" NS enclose string close +.\" NS +.\" NS modifies: +.\" NS doc-nesting-level +. +.eo +.de doc-enclose-close +. nr doc-nesting-level -1 +. +. \" finish enclosure box +. br +. ev +. box +. chop doc-enclosure-box\n[doc-nesting-level] +. unformat doc-enclosure-box\n[doc-nesting-level] +. +. nh +. nop \*[doc-enclosure-box\n[doc-nesting-level]]\c +. nop \)\*[doc-quote-right]\)\c +. +. if !\n[doc-arg-count] \{\ +. doc-parse-args \$@ +. +. if !\n[.$] \ +. doc-print-and-reset +. \} +. +. if \n[doc-arg-count] \{\ +. ie (\n[doc-arg-count] > \n[doc-arg-ptr]) \{\ +. nop \)\*[doc-space\n[doc-arg-ptr]]\c +. nr doc-arg-ptr +1 +. doc-print-recursive +. \} +. el \ +. doc-print-and-reset +. \} +. +. \" shall we finish .It macro? +. if !"\*[doc-macro-name]"It" \ +. if \n[doc-in-list] \ +. if !\n[doc-nesting-level] \ +. doc-\*[doc-list-type-stack\n[doc-list-depth]] +.. +.ec +. +. +.\" NS Pf user macro +.\" NS prefix: '.Pf prefix arg ...' +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS +.\" NS width register 'Pf' set in doc-common +. +.eo +.de Pf +. if !\n[doc-arg-count] \ +. ds doc-macro-name Pf +. +. ie \n[doc-arg-count] \{\ +. ie ((\n[doc-arg-count] - \n[doc-arg-ptr]) > 1) \{\ +. nr doc-arg-ptr +1 +. nop \)\*[doc-arg\n[doc-arg-ptr]]\c +. \} +. el \ +. tm mdoc warning: .Pf: trailing prefix (#\n[.c]) +. \} +. el \{\ +. nop \)\$1\)\c +. shift +. ie \n[.$] \ +. doc-parse-args \$@ +. el \{\ +. tm mdoc warning: .Pf: missing arguments (#\n[.c]) +. nop \) +. \}\} +. +. if \n[doc-arg-count] \{\ +. nr doc-arg-ptr +1 +. ie (\n[doc-arg-count] < \n[doc-arg-ptr]) \ +. doc-print-and-reset +. el \ +. doc-do-\n[doc-type\n[doc-arg-ptr]] +. \} +.. +.ec +. +. +.\" NS Ns user macro +.\" NS remove space (space removal done by 'doc-parse-args') +.\" NS +.\" NS modifies: +.\" NS doc-argXXX +.\" NS doc-macro-name +.\" NS +.\" NS width register 'Ns' set in doc-common +. +.eo +.de Ns +. if !\n[doc-arg-count] \{\ +. ie \n[.$] \{\ +. ds doc-macro-name Ns +. doc-parse-args \$@ +. \} +. el \ +. tm Usage: .Ns must be called with arguments (#\n[.c]) +. \} +. +. if \n[doc-arg-count] \{\ +. nr doc-arg-ptr +1 +. ie (\n[doc-arg-count] >= \n[doc-arg-ptr]) \ +. doc-print-recursive +. el \ +. doc-reset-args +. \} +.. +.ec +. +. +.\" NS Ap user macro +.\" NS append an apostrophe +.\" NS +.\" NS width register 'Ap' set in doc-common +. +.eo +.de Ap +. ie !\n[doc-arg-count] \ +. tm Usage: 'Ap' cannot be first macro on a line (no '.Ap') (#\n[.c]) +. el \{\ +. nop \)'\)\c +. nr doc-arg-ptr +1 +. ie (\n[doc-arg-count] >= \n[doc-arg-ptr]) \ +. doc-print-recursive +. el \ +. doc-reset-args +. \} +.. +.ec +. +. +.\" NS doc-space global string +.\" NS current inter-argument space +. +.ds doc-space "\*[doc-soft-space] +. +. +.\" NS doc-soft-space constant string +.\" NS soft (stretchable) space (defined in doc-common) +. +. +.\" NS doc-hard-space constant string +.\" NS hard (unpaddable) space (defined in doc-common) +. +. +.\" NS doc-set-hard-space macro +.\" NS set current space string to hard (unpaddable) space. +.\" NS +.\" NS modifies: +.\" NS doc-saved-space +.\" NS doc-space +. +.eo +.de doc-set-hard-space +. ie "\*[doc-space]"" \ +. ds doc-saved-space "\*[doc-hard-space] +. el \ +. ds doc-space "\*[doc-hard-space] +.. +.ec +. +. +.\" NS doc-set-soft-space macro +.\" NS set current space string to soft space +.\" NS +.\" NS modifies: +.\" NS doc-saved-space +.\" NS doc-space +. +.eo +.de doc-set-soft-space +. ie "\*[doc-space]"" \ +. ds doc-saved-space "\*[doc-soft-space] +. el \ +. ds doc-space "\*[doc-soft-space] +.. +.ec +. +. +.\" NS doc-space-mode global register (bool) +.\" NS default is one (space mode on) +. +.nr doc-space-mode 1 +. +. +.\" NS doc-saved-space global string +.\" NS saved value of 'doc-space' +. +.ds doc-saved-space "\*[doc-space] +. +. +.\" NS doc-have-space global register (bool) +.\" NS set if last command was horizontal space +. +.nr doc-have-space 0 +. +. +.\" NS Sm user macro +.\" NS space mode ('.Sm'/'.Sm on'/'.Sm off') +.\" NS +.\" NS without argument, toggle space mode +.\" NS +.\" NS modifies: +.\" NS doc-arg-count +.\" NS doc-arg-ptr +.\" NS doc-argXXX +.\" NS doc-macro-name +.\" NS doc-num-args +.\" NS doc-saved-space +.\" NS doc-space +.\" NS doc-space-mode +.\" NS doc-spaceXXX +.\" NS +.\" NS local variables: +.\" NS doc-reg-Sm +.\" NS +.\" NS width register 'Sm' set in doc-common +. +.eo +.de Sm +. ie \n[doc-have-space] \ +. nr doc-reg-Sm 0 +. el \ +. nr doc-reg-Sm 1 +. +. if !\n[doc-arg-count] \{\ +. ie \n[.$] \{\ +. ds doc-macro-name Sm +. doc-parse-args \$@ +. \} +. el \{\ +. ie \n[doc-space-mode] \{\ +. ds doc-saved-space "\*[doc-space] +. ds doc-space +. nr doc-space-mode 0 +. \} +. el \{\ +. ds doc-space "\*[doc-saved-space] +. nr doc-space-mode 1 +. +. \" finish line only if it is interrupted and 'doc-have-space' +. \" isn't set +. if \n[doc-reg-Sm] \ +. if \n[.int] \ +. nop \) +. \} +. \}\} +. +. if !\n[doc-arg-count] \ +. return +. +. nr doc-arg-ptr +1 +. +. \" avoid a warning message in case 'Sm' is the last parameter +. if !d doc-arg\n[doc-arg-ptr] \ +. ds doc-arg\n[doc-arg-ptr] +. +. ie "\*[doc-arg\n[doc-arg-ptr]]"on" \{\ +. ds doc-space "\*[doc-saved-space] +. nr doc-space-mode 1 +. \} +. el \{\ +. ie "\*[doc-arg\n[doc-arg-ptr]]"off" \{\ +. ds doc-saved-space "\*[doc-space] +. ds doc-space +. nr doc-space-mode 0 +. \} +. el \{\ +. \" no argument for Sm +. nr doc-arg-ptr -1 +. ie \n[doc-space-mode] \{\ +. ds doc-saved-space "\*[doc-space] +. ds doc-space +. nr doc-space-mode 0 +. \} +. el \{\ +. ds doc-space "\*[doc-saved-space] +. nr doc-space-mode 1 +. \} +. \}\} +. +. ie \n[doc-space-mode] \{\ +. \" recompute space vector for remaining arguments +. nr doc-num-args (\n[doc-arg-count] - \n[doc-arg-ptr]) +. nr doc-arg-count \n[doc-arg-ptr] +. if \n[doc-num-args] \ +. doc-parse-space-vector +. +. \" finish line only if it is interrupted and 'doc-have-space' +. \" isn't set +. if \n[doc-reg-Sm] \ +. if \n[.int] \ +. nop \) +. \} +. el \{\ +. \" reset remaining space vector elements +. nr doc-reg-Sm (\n[doc-arg-ptr] + 1) +. while (\n[doc-reg-Sm] <= \n[doc-arg-count]) \{\ +. ds doc-space\n[doc-reg-Sm] +. nr doc-reg-Sm +1 +. \" the body of a 'while' request must end with the fitting '\}'! +. \} +. \} +. +. \" do we have parameters to print? +. ie (\n[doc-arg-count] > \n[doc-arg-ptr]) \{\ +. \" skip 'Sm' argument +. nr doc-arg-ptr +1 +. doc-print-recursive +. \} +. el \ +. doc-reset-args +.. +.ec +. +. +.\" NS doc-arg-type immediate register +.\" NS argument type (macro=1, string=2, punctuation suffix=3, +.\" NS punctuation prefix=4) +. +.nr doc-arg-type 0 +. +. +.\" NS doc-get-arg-type macro +.\" NS get argument type +.\" NS +.\" NS this macro expects the width of the argument in 'doc-width' +.\" NS +.\" NS modifies: +.\" NS doc-arg-type +. +.eo +.de doc-get-arg-type +. nr doc-arg-type 2 +. +. if ((\n[doc-width] < 4) & \A'\$1') \{\ +. ie (\n[doc-width] == 1) \{\ +. if r doc-punct\$1 \ +. nr doc-arg-type \n[doc-punct\$1] +. \} +. el \ +. if r \$1 \ +. if d \$1 \ +. nr doc-arg-type 1 +. \} +.. +.ec +. +. +.\" NS doc-get-arg-type* macro +.\" NS similar to as 'doc-get-arg-type' but uses doc-argXXX strings +.\" NS +.\" NS this macro sets the 'doc-width' register using the 'length' +.\" NS request to get the number of characters in a string literally +.\" NS +.\" NS modifies: +.\" NS doc-arg-type +.\" NS doc-width +. +.eo +.de doc-get-arg-type* +. nr doc-arg-type 2 +. length doc-width "\*[doc-arg\$1] +. +. if ((\n[doc-width] < 4) & \A'\*[doc-arg\$1]') \{\ +. ie (\n[doc-width] == 1) \{\ +. if r doc-punct\*[doc-arg\$1] \ +. nr doc-arg-type \n[doc-punct\*[doc-arg\$1]] +. \} +. el \ +. if r \*[doc-arg\$1] \ +. if d \*[doc-arg\$1] \ +. nr doc-arg-type 1 +. \} +.. +.ec +. +. +.\" NS doc-set-spacing-1 macro +.\" NS set spacing for macros +.\" NS +.\" NS modifies: +.\" NS doc-spaceXXX +.\" NS +.\" NS local variables: +.\" NS doc-reg-dssfm +.\" NS doc-reg-dssfm1 +. +.eo +.de doc-set-spacing-1 +. nr doc-reg-dssfm1 \n[\*[doc-arg\n[doc-arg-count]]] +. +. \" closing macros like .Ac, Bc., etc. have value 3 (remove space +. \" before argument) +. ie (\n[doc-reg-dssfm1] == 3) \{\ +. if \n[doc-arg-count] \{\ +. nr doc-reg-dssfm (\n[doc-arg-count] - 1) +. ds doc-space\n[doc-reg-dssfm] +. \} +. ds doc-space\n[doc-arg-count] "\*[doc-space] +. \} +. el \{\ +. \" macros like .Ap and .Ns have value 2 (remove space before and +. \" after argument) +. ie (\n[doc-reg-dssfm1] == 2) \{\ +. if \n[doc-arg-count] \{\ +. nr doc-reg-dssfm (\n[doc-arg-count] - 1) +. ds doc-space\n[doc-reg-dssfm] +. \} +. ds doc-space\n[doc-arg-count] +. \} +. el \ +. ds doc-space\n[doc-arg-count] +. \} +.. +.ec +. +. +.\" NS doc-set-spacing-2 macro +.\" NS set spacing for strings +.\" NS +.\" NS modifies: +.\" NS doc-spaceXXX +. +.eo +.de doc-set-spacing-2 +. ds doc-space\n[doc-arg-count] "\*[doc-space] +.. +.ec +. +. +.\" NS doc-set-spacing-3 macro +.\" NS set spacing for punctuation suffixes +.\" NS +.\" NS modifies: +.\" NS doc-spaceXXX +.\" NS +.\" NS local variables: +.\" NS doc-reg-dssfps +. +.eo +.de doc-set-spacing-3 +. if \n[doc-arg-count] \{\ +. nr doc-reg-dssfps (\n[doc-arg-count] - 1) +. ds doc-space\n[doc-reg-dssfps] +. \} +. +. ds doc-space\n[doc-arg-count] "\*[doc-space] +.. +.ec +. +. +.\" NS doc-set-spacing-4 macro +.\" NS set spacing for punctuation prefixes +.\" NS +.\" NS modifies: +.\" NS doc-spaceXXX +. +.eo +.de doc-set-spacing-4 +. ds doc-space\n[doc-arg-count] +.. +.ec +. +. +.\" type switches (on current argument doc-arg-ptr) +. +. +.\" NS doc-do-1 macro +.\" NS call request if macro +. +.eo +.de doc-do-1 +. \*[doc-arg\n[doc-arg-ptr]] +.. +.ec +. +. +.\" NS doc-do-2 macro +.\" NS call .doc-print-recursive if string +. +.als doc-do-2 doc-print-recursive +. +. +.\" NS doc-do-3 macro +.\" NS call .doc-print-recursive if punctuation suffix +. +.als doc-do-3 doc-print-recursive +. +. +.\" NS doc-do-4 macro +.\" NS call .doc-print-recursive if punctuation prefix +. +.als doc-do-4 doc-print-recursive +. +. +.\" NS doc-fontmode-depth global register +.\" NS font mode level +. +.nr doc-fontmode-depth 0 +. +. +.\" NS doc-fontmode-font-stackXXX global register +.\" NS stack of saved current font values from 'Bf' macro +.\" NS +.\" NS limit: +.\" NS doc-fontmode-depth +. +.nr doc-fontmode-font-stack0 0 +. +. +.\" NS doc-fontmode-size-stackXXX global register +.\" NS stack of saved current size values from 'Bf' macro +.\" NS +.\" NS limit: +.\" NS doc-fontmode-depth +. +.nr doc-fontmode-size-stack0 0 +. +. +.\" NS Bf user macro +.\" NS begin font mode (will be begin-mode/end-mode in groff & TeX) +.\" NS +.\" NS modifies: +.\" NS doc-fontmode-depth +.\" NS doc-fontmode-font-stackXXX +.\" NS doc-fontmode-size-stackXXX +.\" NS doc-macro-name +.\" NS +.\" NS width register 'Bf' set in doc-common +. +.eo +.de Bf +. ds doc-macro-name Bf +. +. ie \n[.$] \{\ +. nr doc-fontmode-depth +1 +. +. \" save current font and size +. nr doc-fontmode-font-stack\n[doc-fontmode-depth] \n[.f] +. nr doc-fontmode-size-stack\n[doc-fontmode-depth] \n[.ps] +. +. ie "\$1"Em" \ +. nop \*[doc-Em-font]\c +. el \{ .ie "\$1"Li" \ +. nop \*[doc-Li-font]\c +. el \{ .ie "\$1"Sy" \ +. nop \*[doc-Sy-font]\c +. el \{ .ie "\$1"-emphasis" \ +. nop \*[doc-Em-font]\c +. el \{ .ie "\$1"-literal" \ +. nop \*[doc-Li-font]\c +. el \{ .ie "\$1"-symbolic" \ +. nop \*[doc-Sy-font]\c +. el \{\ +. tmc mdoc warning: Unknown keyword '\$1' in .Bf macro +. tm1 " (#\n[.c]) +. \}\}\}\}\}\}\} +. el \ +. tm Usage: .Bf [Em | -emphasis | Li | -literal | Sy | -symbolic] (#\n[.c]) +.. +.ec +. +. +.\" NS Ef user macro +.\" NS end font mode +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS +.\" NS width register 'Ef' set in doc-common +. +.eo +.de Ef +. ds doc-macro-name Ef +. +. ie \n[doc-fontmode-depth] \{\ +. \" restore saved font and size +. nop \)\f[\n[doc-fontmode-font-stack\n[doc-fontmode-depth]]]\c +. nop \)\s[\n[doc-fontmode-size-stack\n[doc-fontmode-depth]]u]\c +. +. nr doc-fontmode-font-stack\n[doc-fontmode-depth] 0 +. nr doc-curr-font \n[.f] +. nr doc-fontmode-size-stack\n[doc-fontmode-depth] 0 +. nr doc-fontmode-depth -1 +. \} +. el \ +. tm mdoc warning: Extraneous .Ef (#\n[.c]) +.. +.ec +. +. +.\" NS doc-keep-type global register +.\" NS current keep type; 1 is '-words', 2 is '-lines', 3 is unknown +. +.nr doc-keep-type 0 +. +. +.\" NS Bk user macro +.\" NS begin keep +.\" NS +.\" NS modifies: +.\" NS doc-keep-type +.\" NS doc-macro-name +.\" NS +.\" NS width register 'Bk' set in doc-common +. +.eo +.de Bk +. ds doc-macro-name Bk +. +. if \n[doc-keep-type] \ +. tm .Bk: nesting keeps not implemented yet. (#\n[.c]) +. +. ie "\$1"-lines" \{\ +. nr doc-keep-type 2 +. tm .Bk -lines: Not implemented yet. (#\n[.c]) +. \} +. el \{ .ie "\$1"-words" \{\ +. nr doc-keep-type 1 +. doc-set-hard-space +. \} +. el \{ .ie "\$1"" \{\ +. \" default +. nr doc-keep-type 1 +. doc-set-hard-space +. \} +. el \{\ +. tm mdoc warning: Unknown keyword '\$1' in .Bk macro (#\n[.c]) +. nr doc-keep-type 3 +. \}\}\} +. +\#. nr doc-nesting-level +1 +.. +.ec +. +. +.\" NS Ek user macro +.\" NS end keep +.\" NS +.\" NS modifies: +.\" NS doc-keep-type +.\" NS doc-macro-name +.\" NS +.\" NS width register 'Ek' set in doc-common +. +.eo +.de Ek +. ds doc-macro-name Ek +. +\#. nr doc-nesting-level -1 +. +. ie \n[.$] \ +. tm Usage: .Ek (does not take arguments) (#\n[.c]) +. el \{\ +. if !\n[doc-keep-type] \ +. tm mdoc warning: .Ek found without .Bk before (#\n[.c]) +. +. ie (\n[doc-keep-type] == 1) \ +. doc-set-soft-space +. el \{ .if (\n[doc-keep-type] == 2) \ +. tm .Bk -lines: Not implemented yet. (#\n[.c]) +. \}\} +. +. nr doc-keep-type 0 +. +\#. if !"\*[doc-out-string]"" \ +\#. doc-print-out-string +.. +.ec +. +. +.\" NS doc-display-depth global register +.\" NS display level +. +.nr doc-display-depth 0 +. +. +.\" NS doc-is-compact global register (bool) +.\" NS set if the 'compact' keyword is given +. +.nr doc-is-compact 0 +. +. +.\" NS doc-display-type-stackXXX global string +.\" NS the display type stack +.\" NS +.\" NS limit: +.\" NS doc-display-depth +. +.ds doc-display-type-stack0 +. +. +.\" NS doc-display-indent-stackXXX global register +.\" NS stack of display indentation values +.\" NS +.\" NS limit: +.\" NS doc-display-depth +. +.nr doc-display-indent-stack0 0 +. +. +.\" NS doc-display-ad-stackXXX global register +.\" NS stack of saved adjustment modes +.\" NS +.\" NS limit: +.\" NS doc-display-depth +. +.nr doc-display-ad-stack0 0 +. +. +.\" NS doc-display-fi-stackXXX global register +.\" NS stack of saved fill modes +.\" NS +.\" NS limit: +.\" NS doc-display-depth +. +.nr doc-display-fi-stack0 0 +. +. +.\" NS doc-display-ft-stackXXX global register +.\" NS stack of saved fonts +.\" NS +.\" NS limit: +.\" NS doc-display-depth +. +.nr doc-display-ft-stack0 0 +. +. +.\" NS doc-display-ps-stackXXX global register +.\" NS stack of saved font sizes +.\" NS +.\" NS limit: +.\" NS doc-display-depth +. +.nr doc-display-ps-stack0 0 +. +. +.\" NS Bd user macro +.\" NS begin display +.\" NS +.\" NS width register 'Bd' set in doc-common +.\" NS +.\" NS modifies: +.\" NS doc-curr-font +.\" NS doc-display-depth +.\" NS doc-display-ad-stackXXX +.\" NS doc-display-fi-stackXXX +.\" NS doc-display-ft-stackXXX +.\" NS doc-display-ps-stackXXX +.\" NS doc-display-file +.\" NS doc-display-indent-stackXXX +.\" NS doc-display-type-stackXXX +.\" NS doc-is-compact +.\" NS doc-macro-name +.\" NS +.\" NS local variables: +.\" NS doc-reg-Bd +. +.eo +.de Bd +. ds doc-macro-name Bd +. +. if !\n[.$] \{\ +. tm1 "Usage: .Bd {-literal | -filled | -ragged | -centered | -unfilled} +. tm1 " [-offset [string]] [-compact] [-file name] (#\n[.c]) +. return +. \} +. +. nr doc-is-compact 0 +. ds doc-display-file +. nr doc-reg-Bd 1 +. nr doc-display-depth +1 +. +. \" save current adjustment and fill modes +. nr doc-display-ad-stack\n[doc-display-depth] \n[.j] +. nr doc-display-fi-stack\n[doc-display-depth] \n[.u] +. +. ie "\$1"-literal" \{\ +. ds doc-display-type-stack\n[doc-display-depth] literal +. nr doc-display-ft-stack\n[doc-display-depth] \n[.f] +. nr doc-display-ps-stack\n[doc-display-depth] \n[.ps] +. +. ie t \ +. ta T 9n +. el \ +. ta T 8n +. nf +. \} +. el \{ .ie "\$1"-filled" \{\ +. ds doc-display-type-stack\n[doc-display-depth] filled +. ad b +. fi +. \} +. el \{ .ie "\$1"-ragged" \{\ +. ds doc-display-type-stack\n[doc-display-depth] ragged +. na +. fi +. \} +. el \{ .ie "\$1"-centered" \{\ +. ds doc-display-type-stack\n[doc-display-depth] centered +. ad c +. fi +. \} +. el \{ .ie "\$1"-unfilled" \{\ +. ds doc-display-type-stack\n[doc-display-depth] unfilled +. nf +. \} +. el \{\ +. tm1 "mdoc warning: Unknown keyword '\$1' (or missing display type) +. tm1 " in .Bd macro (#\n[.c]) +. nr doc-reg-Bd 0 +. \}\}\}\}\} +. +. \" have we seen an argument? +. if \n[doc-reg-Bd] \{\ +. shift +. \" check other arguments +. if \n[.$] \ +. doc-do-Bd-args \$@ +. \} +. +. \" avoid warning about non-existent register +. if !r doc-display-indent-stack\n[doc-display-depth] \ +. nr doc-display-indent-stack\n[doc-display-depth] 0 +. +. if \n[doc-display-indent-stack\n[doc-display-depth]] \ +. in +\n[doc-display-indent-stack\n[doc-display-depth]]u +. +. if !\n[doc-is-compact] \ +. sp \n[doc-display-vertical]u +. +. if "\*[doc-display-type-stack\n[doc-display-depth]]"literal" \ +. if t \ +. nop \*[doc-Li-font]\c +. +. if !\n[cR] \ +. ne 2v +. +. if !"\*[doc-display-file]"" \ +. so \*[doc-display-file] +. +. nr doc-is-compact 0 +. ds doc-display-file +.. +.ec +. +. +.\" NS doc-do-Bd-args macro +.\" NS resolve remaining .Bd arguments +.\" NS +.\" NS modifies: +.\" NS doc-display-file +.\" NS doc-display-indent-stackXXX +.\" NS doc-is-compact +.\" NS +.\" NS local variables: +.\" NS doc-reg-ddBa +.\" NS doc-reg-ddBa1 +.\" NS doc-reg-ddBa2 +.\" NS doc-reg-ddBa3 +.\" NS doc-reg-ddBa4 +.\" NS doc-str-ddBa +. +.eo +.de doc-do-Bd-args +. nr doc-reg-ddBa 1 +. +. ie "\$1"-offset" \{\ +. nr doc-reg-ddBa 2 +. +. ie "\$2"left" \ +. nr doc-display-indent-stack\n[doc-display-depth] 0 +. el \{ .ie "\$2"right" \ +. nr doc-display-indent-stack\n[doc-display-depth] (\n[.l]u / 3u) +. el \{ .ie "\$2"center" \ +. nr doc-display-indent-stack\n[doc-display-depth] ((\n[.l]u - \n[.i]u) / 4u) +. el \{ .ie "\$2"indent" \ +. nr doc-display-indent-stack\n[doc-display-depth] \n[doc-display-indent]u +. el \{ .ie "\$2"indent-two" \ +. nr doc-display-indent-stack\n[doc-display-depth] (\n[doc-display-indent]u + \n[doc-display-indent]u) +. el \ +. nr doc-reg-ddBa 1 +. \}\}\}\} +. +. \" not a known keyword +. if (\n[doc-reg-ddBa] == 1) \{\ +. nr doc-reg-ddBa 2 +. +. nr doc-reg-ddBa1 0 +. if \B'(\$2)' \{\ +. \" disable warnings related to scaling indicators (32) +. nr doc-reg-ddBa2 \n[.warn] +. warn (\n[.warn] - (\n[.warn] / 32 % 2 * 32)) +. +. \" values without a scaling indicator are taken as strings; +. \" we test whether the parameter string with and without the +. \" last character yields identical numerical results (ignoring +. \" the scaling indicator) +. ds doc-str-ddBa "\$2 +. substring doc-str-ddBa 0 -2 +. if \B'(\*[doc-str-ddBa])' \{\ +. nr doc-reg-ddBa3 (;(\$2)) +. nr doc-reg-ddBa4 (\*[doc-str-ddBa]) +. if (\n[doc-reg-ddBa3] == \n[doc-reg-ddBa4]) \ +. nr doc-reg-ddBa1 1 +. \} +. +. \" enable all warnings again +. warn \n[doc-reg-ddBa2] +. \} +. +. ie \n[doc-reg-ddBa1] \ +. nr doc-display-indent-stack\n[doc-display-depth] \$2 +. el \{\ +. doc-get-width "\$2" +. ie (\n[doc-width] <= 3) \{\ +. \" if the offset parameter is a macro, use the macro's +. \" width as specified in doc-common +. doc-get-arg-type "\$2" +. ie (\n[doc-arg-type] == 1) \ +. nr doc-display-indent-stack\n[doc-display-depth] \n[\$2] +. el \ +. nr doc-display-indent-stack\n[doc-display-depth] (\n[doc-width]u * \n[doc-fixed-width]u) +. \} +. el \ +. nr doc-display-indent-stack\n[doc-display-depth] (\n[doc-width]u * \n[doc-fixed-width]u) +. \}\} +. \} +. el \{ .ie "\$1"-compact" \ +. nr doc-is-compact 1 +. el \{ .ie "\$1"-file" \{\ +. ie !"\$2"" \{\ +. ds doc-display-file "\$2 +. nr doc-reg-ddBa 2 +. \} +. el \ +. tm mdoc warning: .Bd '-file' keyword requires argument (#\n[.c]) +. \} +. el \ +. tm mdoc warning: Unknown keyword '\$1' in .Bd macro (#\n[.c]) +. \}\} +. +. if (\n[doc-reg-ddBa] < \n[.$]) \{\ +. shift \n[doc-reg-ddBa] +. doc-do-Bd-args \$@ +. \} +.. +.ec +. +. +.\" NS Ed user macro +.\" NS end display +.\" NS +.\" NS modifies: +.\" NS doc-display-depth +.\" NS doc-display-indent-stackXXX +.\" NS doc-display-type-stackXXX +.\" NS doc-macro-name +.\" NS +.\" NS width register 'Ed' set in doc-common +. +.eo +.de Ed +. ds doc-macro-name Ed +. +. br +. +. if !\n[doc-display-depth] \{\ +. tm mdoc warning: Extraneous .Ed (#\n[.c]) +. nr doc-display-depth 1 +. \} +. +. if "\*[doc-display-type-stack\n[doc-display-depth]]"literal" \{\ +. ft \n[doc-display-ft-stack\n[doc-display-depth]] +. ps \n[doc-display-ps-stack\n[doc-display-depth]]u +. \} +. +. in -\n[doc-display-indent-stack\n[doc-display-depth]]u +. +. \" restore saved adjustment and fill modes +. ie \n[doc-display-fi-stack\n[doc-display-depth]] \ +. fi +. el \ +. nf +. ad \n[doc-display-ad-stack\n[doc-display-depth]] +. +. nr doc-display-indent-stack\n[doc-display-depth] 0 +. ds doc-display-type-stack\n[doc-display-depth] +. nr doc-display-depth -1 +.. +.ec +. +. +.\" NS doc-list-type-stackXXX global string +.\" NS stack of list types +.\" NS +.\" NS limit: +.\" NS doc-list-depth +. +.ds doc-list-type-stack1 +. +. +.\" NS doc-list-indent-stackXXX global register +.\" NS stack of list indentation values +.\" NS +.\" NS limit: +.\" NS doc-list-depth +. +.nr doc-list-indent-stack1 0 +. +. +.\" NS doc-list-have-indent-stackXXX global register (bool) +.\" NS an indentation value is active +.\" NS +.\" NS limit: +.\" NS doc-list-depth +. +.nr doc-list-have-indent-stack1 0 +. +. +.\" NS Bl user macro +.\" NS begin list +.\" NS +.\" NS width register 'Bl' set in doc-common +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-argXXX +.\" NS doc-list-depth +.\" NS doc-list-have-indent-stackXXX +.\" NS doc-list-indent-stackXXX +.\" NS doc-list-type-stackXXX +.\" NS doc-macro-name +.\" NS doc-num-args +.\" NS doc-num-columns +.\" NS +.\" NS local variables: +.\" NS doc-reg-Bl +. +.eo +.de Bl +. if !\n[.$] \{\ +. doc-Bl-usage +. return +. \} +. +. ds doc-macro-name Bl +. nr doc-list-depth +1 +. nr doc-arg-ptr 1 +. +. ie "\$1"-hang" \{\ +. ds doc-list-type-stack\n[doc-list-depth] hang-list +. nr doc-list-indent-stack\n[doc-list-depth] 6n +. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +. \} +. el \{ .ie "\$1"-tag" \{\ +. ds doc-list-type-stack\n[doc-list-depth] tag-list +. nr doc-list-indent-stack\n[doc-list-depth] 6n +. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +. \} +. el \{ .ie "\$1"-item" \{\ +. ds doc-list-type-stack\n[doc-list-depth] item-list +. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +. \} +. el \{ .ie "\$1"-enum" \{\ +. ds doc-list-type-stack\n[doc-list-depth] enum-list +. nr doc-list-indent-stack\n[doc-list-depth] 3n +. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +. \} +. el \{ .ie "\$1"-bullet" \{\ +. ds doc-list-type-stack\n[doc-list-depth] bullet-list +. nr doc-list-indent-stack\n[doc-list-depth] 2n +. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +. \} +. el \{ .ie "\$1"-dash" \{\ +. ds doc-list-type-stack\n[doc-list-depth] dash-list +. nr doc-list-indent-stack\n[doc-list-depth] 2n +. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +. \} +. el \{ .ie "\$1"-hyphen" \{\ +. ds doc-list-type-stack\n[doc-list-depth] dash-list +. nr doc-list-indent-stack\n[doc-list-depth] 2n +. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +. \} +. el \{ .ie "\$1"-inset" \{\ +. ds doc-list-type-stack\n[doc-list-depth] inset-list +. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +. \} +. el \{ .ie "\$1"-diag" \{\ +. ds doc-list-type-stack\n[doc-list-depth] diag-list +. \} +. el \{ .ie "\$1"-ohang" \{\ +. ds doc-list-type-stack\n[doc-list-depth] ohang-list +. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +. \} +. el \{ .ie "\$1"-column" \{\ +. ds doc-list-type-stack\n[doc-list-depth] column-list +. linetabs 1 +. \} +. el \{\ +. tm1 "mdoc warning: Unknown list type '\$1' (or missing list type) +. tm1 " in .Bl macro +. tm +. nr doc-arg-ptr 0 +. \}\}\}\}\}\}\}\}\}\}\} +. +. \" we have seen a list type +. if !\n[doc-arg-ptr] \{\ +. doc-Bl-usage +. doc-reset-args +. nr doc-list-depth -1 +. return +. \} +. +. shift +. +. \" fill argument vector +. nr doc-reg-Bl 1 +. while (\n[doc-reg-Bl] <= \n[.$]) \{\ +. ds doc-arg\n[doc-reg-Bl] "\$[\n[doc-reg-Bl]] +. \" dummy type and space so that doc-save-global-vars() doesn't warn +. nr doc-type\n[doc-reg-Bl] 0 +. ds doc-space\n[doc-reg-Bl] +. nr doc-reg-Bl +1 +. \} +. +. doc-increment-list-stack +. +. if \n[.$] \{\ +. nr doc-arg-count \n[.$] +. nr doc-arg-ptr 0 +. doc-do-Bl-args +. +. in +\n[doc-list-offset-stack\n[doc-list-depth]]u +. +. \" initialize column list +. if "\*[doc-list-type-stack\n[doc-list-depth]]"column-list" \{\ +. doc-set-column-tab \n[doc-num-columns] +' in -\n[doc-column-indent-width]u +. if !\n[doc-compact-list-stack\n[doc-list-depth]] \ +. sp \n[doc-display-vertical]u +. +. nf +. nr doc-num-columns 0 +. \}\} +. +. doc-reset-args +.. +.ec +. +. +.\" NS doc-Bl-usage macro +. +.eo +.de doc-Bl-usage +. tm1 "Usage: .Bl {-hang | -ohang | -tag | -diag | -inset} +. tm1 " [-width ] +. tm1 " [-offset ] [-compact] +. tm1 " .Bl -column [-offset ] ... +. tm1 " .Bl {-item | -enum [-nested] | -bullet | -hyphen | -dash} +. tm1 " [-offset ] [-compact] (#\n[.c]) +.. +.ec +. +. +.\" NS doc-do-Bl-args macro +.\" NS resolve remaining .Bl arguments +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-argXXX +.\" NS doc-compact-list-stackXXX +.\" NS doc-list-indent-stackXXX +.\" NS doc-list-offset-stackXXX +.\" NS doc-num-columns +.\" NS doc-tag-prefix-stackXXX +.\" NS +.\" NS local variables: +.\" NS doc-box-dBla +.\" NS doc-env-dBla +.\" NS doc-reg-dBla +.\" NS doc-reg-dBla1 +.\" NS doc-reg-dBla2 +.\" NS doc-reg-dBla3 +.\" NS doc-reg-dBla4 +.\" NS doc-str-dBla +.\" NS doc-str-dBla1 +. +.eo +.de doc-do-Bl-args +. nr doc-arg-ptr +1 +. +. if (\n[doc-arg-count] < \n[doc-arg-ptr]) \ +. return +. +. \" avoid a warning message in case e.g. '-offset' has no parameter +. nr doc-reg-dBla (\n[doc-arg-ptr] + 1) +. if (\n[doc-arg-count] < \n[doc-reg-dBla]) \ +. ds doc-arg\n[doc-reg-dBla] +. +. nr doc-reg-dBla 1 +. +. ie "\*[doc-arg\n[doc-arg-ptr]]"-compact" \ +. nr doc-compact-list-stack\n[doc-list-depth] 1 +. +. el \{ .ie "\*[doc-arg\n[doc-arg-ptr]]"-nested" \{\ +. ie (\n[doc-list-depth] > 1) \{\ +. nr doc-reg-dBla1 (\n[doc-list-depth] - 1) +. ds doc-tag-prefix-stack\n[doc-list-depth] "\*[doc-tag-prefix-stack\n[doc-reg-dBla1]] +. as doc-tag-prefix-stack\n[doc-list-depth] \n[doc-enum-list-count-stack\n[doc-reg-dBla1]]. +. length doc-reg-dBla1 "\*[doc-tag-prefix-stack\n[doc-list-depth]] +. nr doc-list-indent-stack\n[doc-list-depth] +\n[doc-reg-dBla1]n +. \} +. el \ +. tm mdoc warning: '-nested' allowed with nested .Bl macros only (#\n[.c]) +. \} +. +. el \{ .ie "\*[doc-arg\n[doc-arg-ptr]]"-width" \{\ +. nr doc-arg-ptr +1 +. ds doc-str-dBla "\*[doc-arg\n[doc-arg-ptr]] +. substring doc-str-dBla 0 0 +. ie '.'\*[doc-str-dBla]' \{\ +. ds doc-str-dBla "\*[doc-arg\n[doc-arg-ptr]] +. substring doc-str-dBla 1 +. doc-first-parameter \*[doc-str-dBla] +. doc-get-width "\*[doc-str-dfp] +. doc-get-arg-type "\*[doc-str-dfp] +. ie (\n[doc-arg-type] == 1) \ +. nr doc-reg-dBla1 1 +. el \ +. nr doc-reg-dBla1 0 +. \} +. el \ +. nr doc-reg-dBla1 0 +. ds doc-str-dBla "\*[doc-arg\n[doc-arg-ptr]] +. +. ie \n[doc-reg-dBla1] \{\ +. \" execute string in a box to get the width of the diversion +. ds doc-str-dBla \*[doc-arg\n[doc-arg-ptr]] +. doc-save-global-vars +. doc-reset-args +. box doc-box-dBla +. ev doc-env-dBla +. evc 0 +. in 0 +. nf +. nop \*[doc-str-dBla] +. br +. ev +. box +. doc-restore-global-vars +. doc-get-width \h'\n[dl]u' +. nr doc-list-indent-stack\n[doc-list-depth] (\n[doc-width]u * \n[doc-fixed-width]u) +. \} +. el \{\ +. \" test whether argument is a valid numeric expression +. nr doc-reg-dBla1 0 +. if \B'(\*[doc-str-dBla])' \{\ +. \" disable warnings related to scaling indicators (32) +. nr doc-reg-dBla2 \n[.warn] +. warn (\n[.warn] - (\n[.warn] / 32 % 2 * 32)) +. +. \" values without a scaling indicator are taken as strings; +. \" we test whether the parameter string with and without the +. \" last character yields identical numerical results (ignoring +. \" the scaling indicator) +. ds doc-str-dBla1 "\*[doc-str-dBla] +. substring doc-str-dBla1 0 -2 +. if \B'(\*[doc-str-dBla1])' \{\ +. nr doc-reg-dBla3 (;(\*[doc-str-dBla])) +. nr doc-reg-dBla4 (\*[doc-str-dBla1]) +. if (\n[doc-reg-dBla3] == \n[doc-reg-dBla4]) \ +. nr doc-reg-dBla1 1 +. \} +. +. \" enable all warnings again +. warn \n[doc-reg-dBla2] +. \} +. +. ie \n[doc-reg-dBla1] \ +. nr doc-list-indent-stack\n[doc-list-depth] (\*[doc-str-dBla]) +. el \{\ +. doc-get-arg-width \n[doc-arg-ptr] +. ie (\n[doc-width] == 2) \{\ +. \" if the width parameter is a macro, use the macro's +. \" width as specified in doc-common +. doc-get-arg-type \*[doc-str-dBla] +. ie (\n[doc-arg-type] == 1) \ +. nr doc-list-indent-stack\n[doc-list-depth] \n[\*[doc-str-dBla]] +. el \ +. nr doc-list-indent-stack\n[doc-list-depth] (\n[doc-width]u * \n[doc-fixed-width]u) +. \} +. el \ +. nr doc-list-indent-stack\n[doc-list-depth] (\n[doc-width]u * \n[doc-fixed-width]u) +. \}\}\} +. +. el \{ .ie "\*[doc-arg\n[doc-arg-ptr]]"-offset" \{\ +. nr doc-arg-ptr +1 +. +. ie "\*[doc-arg\n[doc-arg-ptr]]"indent" \ +. nr doc-list-offset-stack\n[doc-list-depth] \n[doc-display-indent]u +. el \{\ +. ds doc-str-dBla "\*[doc-arg\n[doc-arg-ptr]] +. nr doc-reg-dBla1 0 +. if \B'(\*[doc-str-dBla])' \{\ +. nr doc-reg-dBla2 \n[.warn] +. warn (\n[.warn] - (\n[.warn] / 32 % 2 * 32)) +. +. ds doc-str-dBla1 "\*[doc-str-dBla] +. substring doc-str-dBla1 0 -2 +. if \B'(\*[doc-str-dBla1])' \{\ +. nr doc-reg-dBla3 (;(\*[doc-str-dBla])) +. nr doc-reg-dBla4 (\*[doc-str-dBla1]) +. if (\n[doc-reg-dBla3] == \n[doc-reg-dBla4]) \ +. nr doc-reg-dBla1 1 +. \} +. +. warn \n[doc-reg-dBla2] +. \} +. +. ie \n[doc-reg-dBla1] \ +. nr doc-list-offset-stack\n[doc-list-depth] \*[doc-str-dBla] +. el \{\ +. doc-get-arg-width \n[doc-arg-ptr] +. ie (\n[doc-width] <= 3) \{\ +. \" if the offset parameter is a macro, use the macro's +. \" width as specified in doc-common +. doc-get-arg-type \*[doc-str-dBla] +. ie (\n[doc-arg-type] == 1) \ +. nr doc-list-offset-stack\n[doc-list-depth] \n[\*[doc-str-dBla]] +. el \ +. nr doc-list-offset-stack\n[doc-list-depth] (\n[doc-width]u * \n[doc-fixed-width]u) +. \} +. el \ +. nr doc-list-offset-stack\n[doc-list-depth] (\n[doc-width]u * \n[doc-fixed-width]u) +. \}\}\} +. el \ +. nr doc-reg-dBla 0 +. \}\}\} +. +. \" not a known keyword, so it specifies the width of the next column +. \" (if it is a column list) +. if !\n[doc-reg-dBla] \{\ +. ie "\*[doc-list-type-stack\n[doc-list-depth]]"column-list" \{\ +. nr doc-num-columns +1 +. ds doc-str-dBla \*[doc-arg\n[doc-arg-ptr]] +. substring doc-str-dBla 0 0 +. ie '.'\*[doc-str-dBla]' \{\ +. ds doc-str-dBla "\*[doc-arg\n[doc-arg-ptr]] +. substring doc-str-dBla 1 +. doc-first-parameter \*[doc-str-dBla] +. doc-get-width "\*[doc-str-dfp] +. doc-get-arg-type "\*[doc-str-dfp] +. ie (\n[doc-arg-type] == 1) \ +. nr doc-reg-dBla1 1 +. el \ +. nr doc-reg-dBla1 0 +. \} +. el \ +. nr doc-reg-dBla1 0 +. ds doc-str-dBla "\*[doc-arg\n[doc-arg-ptr]] +. +. ie \n[doc-reg-dBla1] \{\ +. \" execute string in a box to get the width of the diversion +. ds doc-str-dBla \*[doc-arg\n[doc-arg-ptr]] +. doc-save-global-vars +. doc-reset-args +. box doc-box-dBla +. ev doc-env-dBla +. evc 0 +. in 0 +. nf +. nop \*[doc-str-dBla] +. br +. ev +. box +. doc-restore-global-vars +. ds doc-arg\n[doc-num-columns] "\h'\n[dl]u' +. \} +. el \ +. ds doc-arg\n[doc-num-columns] "\*[doc-arg\n[doc-arg-ptr]] +. \} +. el \{\ +. tmc mdoc warning: Unknown keyword '\*[doc-arg\n[doc-arg-ptr]]' +. tm1 " in .Bl macro (#\n[.c]) +. \}\} +. +. if (\n[doc-arg-count] > \n[doc-arg-ptr]) \ +. doc-do-Bl-args +.. +.ec +. +. +.\" NS doc-save-global-vars macro +.\" NS save all global variables +.\" NS +.\" NS local variables: +.\" NS doc-reg-dsgv +. +.eo +.de doc-save-global-vars +. ds doc-macro-name-saved "\*[doc-macro-name] +. nr doc-arg-count-saved \n[doc-arg-count] +. nr doc-num-args-saved \n[doc-num-args] +. nr doc-arg-ptr-saved \n[doc-arg-ptr] +. +. nr doc-reg-dsgv 1 +. while (\n[doc-reg-dsgv] <= \n[doc-arg-count]) \{\ +. ds doc-arg\n[doc-reg-dsgv]-saved "\*[doc-arg\n[doc-reg-dsgv]] +. nr doc-type\n[doc-reg-dsgv]-saved \n[doc-type\n[doc-reg-dsgv]] +. ds doc-space\n[doc-reg-dsgv]-saved "\*[doc-space\n[doc-reg-dsgv]] +. nr doc-reg-dsgv +1 +. \} +. +. nr doc-curr-font-saved \n[doc-curr-font] +. nr doc-in-name-section-saved \n[doc-in-name-section] +. nr doc-in-synopsis-section-saved \n[doc-in-synopsis-section] +. nr doc-in-library-section-saved \n[doc-in-library-section] +. nr doc-indent-synopsis-saved \n[doc-indent-synopsis] +. nr doc-indent-synopsis-active-saved \n[doc-indent-synopsis-active] +. nr doc-have-decl-saved \n[doc-have-decl] +. nr doc-have-var-saved \n[doc-have-var] +. ds doc-topic-name-saved "\*[doc-topic-name] +. ds doc-quote-left-saved "\*[doc-quote-left] +. ds doc-quote-right-saved "\*[doc-quote-right] +. nr doc-nesting-level-saved \n[doc-nesting-level] +. nr doc-in-list-saved \n[doc-in-list] +. ds doc-space-saved "\*[doc-space] +. ds doc-saved-space-saved "\*[doc-saved-space] +. nr doc-space-mode-saved \n[doc-space-mode] +. nr doc-have-space-saved \n[doc-have-space] +. nr doc-have-slot-saved \n[doc-have-slot] +. nr doc-keep-type-saved \n[doc-keep-type] +. nr doc-display-depth-saved \n[doc-display-depth] +. nr doc-is-compact-saved \n[doc-is-compact] +. +. nr doc-reg-dsgv 0 +. while (\n[doc-reg-dsgv] <= \n[doc-display-depth]) \{\ +. ds doc-display-type-stack\n[doc-reg-dsgv]-saved "\*[doc-display-type-stack\n[doc-reg-dsgv]] +. nr doc-display-indent-stack\n[doc-reg-dsgv]-saved \n[doc-display-indent-stack\n[doc-reg-dsgv]] +. nr doc-display-ad-stack\n[doc-reg-dsgv]-saved \n[doc-display-ad-stack\n[doc-reg-dsgv]] +. nr doc-display-fi-stack\n[doc-reg-dsgv]-saved \n[doc-display-fi-stack\n[doc-reg-dsgv]] +. nr doc-display-ft-stack\n[doc-reg-dsgv]-saved \n[doc-display-ft-stack\n[doc-reg-dsgv]] +. nr doc-display-ps-stack\n[doc-reg-dsgv]-saved \n[doc-display-ps-stack\n[doc-reg-dsgv]] +. nr doc-reg-dsgv +1 +. \} +. +. nr doc-fontmode-depth-saved \n[doc-fontmode-depth] +. +. nr doc-reg-dsgv 1 +. while (\n[doc-reg-dsgv] <= \n[doc-fontmode-depth]) \{\ +. nr doc-fontmode-font-stack\n[doc-reg-dsgv]-saved \n[doc-fontmode-font-stack\n[doc-reg-dsgv]] +. nr doc-fontmode-size-stack\n[doc-reg-dsgv]-saved \n[doc-fontmode-size-stack\n[doc-reg-dsgv]] +. nr doc-reg-dsgv +1 +. \} +. +. nr doc-list-depth-saved \n[doc-list-depth] +. +. nr doc-reg-dsgv 1 +. while (\n[doc-reg-dsgv] <= \n[doc-list-depth]) \{\ +. ds doc-list-type-stack\n[doc-reg-dsgv]-saved "\*[doc-list-type-stack\n[doc-reg-dsgv]] +. nr doc-list-have-indent-stack\n[doc-reg-dsgv]-saved \n[doc-list-have-indent-stack\n[doc-reg-dsgv]] +. nr doc-list-indent-stack\n[doc-reg-dsgv]-saved \n[doc-list-indent-stack\n[doc-reg-dsgv]] +. nr doc-compact-list-stack\n[doc-reg-dsgv]-saved \n[doc-compact-list-stack\n[doc-reg-dsgv]] +. ds doc-tag-prefix-stack\n[doc-reg-dsgv]-saved "\*[doc-tag-prefix-stack\n[doc-reg-dsgv]] +. nr doc-list-offset-stack\n[doc-reg-dsgv]-saved \n[doc-list-offset-stack\n[doc-reg-dsgv]] +. nr doc-enum-list-count-stack\n[doc-reg-dsgv]-saved \n[doc-enum-list-count-stack\n[doc-reg-dsgv]] +. nr doc-reg-dsgv +1 +. \} +. +. nr doc-curr-type-saved \n[doc-curr-type] +. ds doc-curr-arg-saved "\*[doc-curr-arg] +. nr doc-diag-list-input-line-count-saved \n[doc-diag-list-input-line-count] +. nr doc-num-columns-saved \n[doc-num-columns] +. nr doc-column-indent-width-saved \n[doc-column-indent-width] +. nr doc-is-func-saved \n[doc-is-func] +. nr doc-have-old-func-saved \n[doc-have-old-func] +. nr doc-func-arg-count-saved \n[doc-func-arg-count] +. ds doc-func-arg-saved "\*[doc-func-arg] +. nr doc-num-func-args-saved \n[doc-num-func-args] +. nr doc-func-args-processed-saved \n[doc-func-args-processed] +. nr doc-have-func-saved \n[doc-have-func] +. nr doc-is-reference-saved \n[doc-is-reference] +. nr doc-reference-count-saved \n[doc-reference-count] +. nr doc-author-count-saved \n[doc-author-count] +. +. nr doc-reg-dsgv 0 +. while (\n[doc-reg-dsgv] <= \n[doc-author-count]) \{\ +. ds doc-author-name\n[doc-reg-dsgv]-saved "\*[doc-author-name\n[doc-reg-dsgv]] +. nr doc-reg-dsgv +1 +. \} +. +. nr doc-book-count-saved \n[doc-book-count] +. ds doc-book-name-saved "\*[doc-book-name] +. nr doc-city-count-saved \n[doc-city-count] +. ds doc-city-name-saved "\*[doc-city-name] +. nr doc-date-count-saved \n[doc-date-count] +. ds doc-date-saved "\*[doc-date] +. nr doc-publisher-count-saved \n[doc-publisher-count] +. ds doc-publisher-name-saved "\*[doc-publisher-name] +. nr doc-journal-count-saved \n[doc-journal-count] +. ds doc-journal-name-saved "\*[doc-journal-name] +. nr doc-issue-count-saved \n[doc-issue-count] +. ds doc-issue-name-saved "\*[doc-issue-name] +. nr doc-optional-count-saved \n[doc-optional-count] +. ds doc-optional-string-saved "\*[doc-optional-string] +. nr doc-page-number-count-saved \n[doc-page-number-count] +. ds doc-page-number-string-saved "\*[doc-page-number-string] +. nr doc-corporate-count-saved \n[doc-corporate-count] +. ds doc-corporate-name-saved "\*[doc-corporate-name] +. nr doc-report-count-saved \n[doc-report-count] +. ds doc-report-name-saved "\*[doc-report-name] +. nr doc-reference-title-count-saved \n[doc-reference-title-count] +. ds doc-reference-title-name-saved "\*[doc-reference-title-name] +. ds doc-reference-title-name-for-book-saved "\*[doc-reference-title-name-for-book] +. nr doc-url-count-saved \n[doc-url-count] +. ds doc-url-name-saved "\*[doc-url-name] +. nr doc-volume-count-saved \n[doc-volume-count] +. ds doc-volume-name-saved "\*[doc-volume-name] +. nr doc-have-author-saved \n[doc-have-author] +. +. ds doc-page-topic-saved "\*[doc-page-topic] +. ds doc-volume-saved "\*[doc-volume] +. ds doc-section-saved "\*[doc-section] +. ds doc-operating-system-saved "\*[doc-operating-system] +. ds doc-date-string-saved "\*[doc-date-string] +. nr doc-display-vertical-saved \n[doc-display-vertical] +. nr doc-in-see-also-section-saved \n[doc-in-see-also-section] +. nr doc-in-files-section-saved \n[doc-in-files-section] +. nr doc-in-authors-section-saved \n[doc-in-authors-section] +.. +.ec +. +. +.\" NS doc-restore-global-vars macro +.\" NS restore all global variables +.\" NS +.\" NS local variables: +.\" NS doc-reg-drgv +. +.eo +.de doc-restore-global-vars +. ds doc-macro-name "\*[doc-macro-name-saved] +. nr doc-arg-count \n[doc-arg-count-saved] +. nr doc-num-args \n[doc-num-args-saved] +. nr doc-arg-ptr \n[doc-arg-ptr-saved] +. +. nr doc-reg-drgv 1 +. while (\n[doc-reg-drgv] <= \n[doc-arg-count]) \{\ +. ds doc-arg\n[doc-reg-drgv] "\*[doc-arg\n[doc-reg-drgv]-saved] +. nr doc-type\n[doc-reg-drgv] \n[doc-type\n[doc-reg-drgv]-saved] +. ds doc-space\n[doc-reg-drgv] "\*[doc-space\n[doc-reg-drgv]-saved] +. nr doc-reg-drgv +1 +. \} +. +. nr doc-curr-font \n[doc-curr-font-saved] +. nr doc-in-name-section \n[doc-in-name-section-saved] +. nr doc-in-synopsis-section \n[doc-in-synopsis-section-saved] +. nr doc-in-library-section \n[doc-in-library-section-saved] +. nr doc-indent-synopsis \n[doc-indent-synopsis-saved] +. nr doc-indent-synopsis-active \n[doc-indent-synopsis-active-saved] +. nr doc-have-decl \n[doc-have-decl-saved] +. nr doc-have-var \n[doc-have-var-saved] +. ds doc-topic-name "\*[doc-topic-name-saved] +. ds doc-quote-left "\*[doc-quote-left-saved] +. ds doc-quote-right "\*[doc-quote-right-saved] +. nr doc-nesting-level \n[doc-nesting-level-saved] +. nr doc-in-list \n[doc-in-list-saved] +. ds doc-space "\*[doc-space-saved] +. ds doc-saved-space "\*[doc-saved-space-saved] +. nr doc-space-mode \n[doc-space-mode-saved] +. nr doc-have-space \n[doc-have-space-saved] +. nr doc-have-slot \n[doc-have-slot-saved] +. nr doc-keep-type \n[doc-keep-type-saved] +. nr doc-display-depth \n[doc-display-depth-saved] +. nr doc-is-compact \n[doc-is-compact-saved] +. +. nr doc-reg-drgv 0 +. while (\n[doc-reg-drgv] <= \n[doc-display-depth]) \{\ +. ds doc-display-type-stack\n[doc-reg-drgv] "\*[doc-display-type-stack\n[doc-reg-drgv]-saved] +. nr doc-display-indent-stack\n[doc-reg-drgv] \n[doc-display-indent-stack\n[doc-reg-drgv]-saved] +. nr doc-display-ad-stack\n[doc-reg-drgv] \n[doc-display-ad-stack\n[doc-reg-drgv]-saved] +. nr doc-display-fi-stack\n[doc-reg-drgv] \n[doc-display-fi-stack\n[doc-reg-drgv]-saved] +. nr doc-display-ft-stack\n[doc-reg-drgv] \n[doc-display-ft-stack\n[doc-reg-drgv]-saved] +. nr doc-display-ps-stack\n[doc-reg-drgv] \n[doc-display-ps-stack\n[doc-reg-drgv]-saved] +. nr doc-reg-drgv +1 +. \} +. +. nr doc-fontmode-depth \n[doc-fontmode-depth-saved] +. +. nr doc-reg-drgv 1 +. while (\n[doc-reg-drgv] <= \n[doc-fontmode-depth]) \{\ +. nr doc-fontmode-font-stack\n[doc-reg-drgv] \n[doc-fontmode-font-stack\n[doc-reg-drgv]]-saved +. nr doc-fontmode-size-stack\n[doc-reg-drgv] \n[doc-fontmode-size-stack\n[doc-reg-drgv]]-saved +. nr doc-reg-drgv +1 +. \} +. +. nr doc-list-depth \n[doc-list-depth-saved] +. +. nr doc-reg-drgv 1 +. while (\n[doc-reg-drgv] <= \n[doc-list-depth]) \{\ +. ds doc-list-type-stack\n[doc-reg-drgv] "\*[doc-list-type-stack\n[doc-reg-drgv]-saved] +. nr doc-list-have-indent-stack\n[doc-reg-drgv] \n[doc-list-have-indent-stack\n[doc-reg-drgv]-saved] +. nr doc-list-indent-stack\n[doc-reg-drgv] \n[doc-list-indent-stack\n[doc-reg-drgv]-saved] +. nr doc-compact-list-stack\n[doc-reg-drgv] \n[doc-compact-list-stack\n[doc-reg-drgv]-saved] +. ds doc-tag-prefix-stack\n[doc-reg-drgv] "\*[doc-tag-prefix-stack\n[doc-reg-drgv]-saved] +. nr doc-list-offset-stack\n[doc-reg-drgv] \n[doc-list-offset-stack\n[doc-reg-drgv]-saved] +. nr doc-enum-list-count-stack\n[doc-reg-drgv] \n[doc-enum-list-count-stack\n[doc-reg-drgv]-saved] +. nr doc-reg-drgv +1 +. \} +. +. nr doc-curr-type \n[doc-curr-type-saved] +. ds doc-curr-arg "\*[doc-curr-arg-saved] +. nr doc-diag-list-input-line-count \n[doc-diag-list-input-line-count-saved] +. nr doc-num-columns \n[doc-num-columns-saved] +. nr doc-column-indent-width \n[doc-column-indent-width-saved] +. nr doc-is-func \n[doc-is-func-saved] +. nr doc-have-old-func \n[doc-have-old-func-saved] +. nr doc-func-arg-count \n[doc-func-arg-count-saved] +. ds doc-func-arg "\*[doc-func-arg-saved] +. nr doc-num-func-args \n[doc-num-func-args-saved] +. nr doc-func-args-processed \n[doc-func-args-processed-saved] +. nr doc-have-func \n[doc-have-func-saved] +. nr doc-is-reference \n[doc-is-reference-saved] +. nr doc-reference-count \n[doc-reference-count-saved] +. nr doc-author-count \n[doc-author-count-saved] +. +. nr doc-reg-drgv 0 +. while (\n[doc-reg-drgv] <= \n[doc-author-count]) \{\ +. ds doc-author-name\n[doc-reg-drgv] "\*[doc-author-name\n[doc-reg-drgv]-saved] +. nr doc-reg-drgv +1 +. \} +. +. nr doc-book-count \n[doc-book-count-saved] +. ds doc-book-name "\*[doc-book-name-saved] +. nr doc-city-count \n[doc-city-count-saved] +. ds doc-city-name "\*[doc-city-name-saved] +. nr doc-date-count \n[doc-date-count-saved] +. ds doc-date "\*[doc-date-saved] +. nr doc-publisher-count \n[doc-publisher-count-saved] +. ds doc-publisher-name "\*[doc-publisher-name-saved] +. nr doc-journal-count \n[doc-journal-count-saved] +. ds doc-journal-name "\*[doc-journal-name-saved] +. nr doc-issue-count \n[doc-issue-count-saved] +. ds doc-issue-name "\*[doc-issue-name-saved] +. nr doc-optional-count \n[doc-optional-count-saved] +. ds doc-optional-string "\*[doc-optional-string-saved] +. nr doc-page-number-count \n[doc-page-number-count-saved] +. ds doc-page-number-string "\*[doc-page-number-string-saved] +. nr doc-corporate-count \n[doc-corporate-count-saved] +. ds doc-corporate-name "\*[doc-corporate-name-saved] +. nr doc-report-count \n[doc-report-count-saved] +. ds doc-report-name "\*[doc-report-name-saved] +. nr doc-reference-title-count \n[doc-reference-title-count-saved] +. ds doc-reference-title-name "\*[doc-reference-title-name-saved] +. ds doc-reference-title-name-for-book "\*[doc-reference-title-name-for-book-saved] +. nr doc-url-count \n[doc-url-count-saved] +. ds doc-url-name "\*[doc-url-name-saved] +. nr doc-volume-count \n[doc-volume-count-saved] +. ds doc-volume-name "\*[doc-volume-name-saved] +. nr doc-have-author \n[doc-have-author-saved] +. +. ds doc-page-topic "\*[doc-page-topic-saved] +. ds doc-volume "\*[doc-volume-saved] +. ds doc-section "\*[doc-section-saved] +. ds doc-operating-system "\*[doc-operating-system-saved] +. ds doc-date-string "\*[doc-date-string-saved] +. nr doc-display-vertical \n[doc-display-vertical-saved] +. nr doc-in-see-also-section \n[doc-in-see-also-section-saved] +. nr doc-in-files-section \n[doc-in-files-section-saved] +. nr doc-in-authors-section \n[doc-in-authors-section-saved] +.. +.ec +. +. +.\" NS El user macro +.\" NS end list +.\" NS +.\" NS modifies: +.\" NS doc-list-depth +.\" NS doc-macro-name +.\" NS +.\" NS local variables: +.\" NS doc-str-El +.\" NS +.\" NS width register 'El' set in doc-common +. +.eo +.de El +. if \n[.$] \{\ +. tm Usage: .El (does not take arguments) (#\n[.c]) +. return +. \} +. +. ds doc-macro-name El +. ds doc-str-El \*[doc-list-type-stack\n[doc-list-depth]] +. +. ie "\*[doc-str-El]"diag-list" \ +. doc-end-list 0 +. el \{ .ie "\*[doc-str-El]"column-list" \ +. doc-end-column-list +. el \{ .ie "\*[doc-str-El]"item-list" \ +. doc-end-list 0 +. el \{ .ie "\*[doc-str-El]"ohang-list" \ +. doc-end-list 0 +. el \{ .ie "\*[doc-str-El]"inset-list" \ +. doc-end-list 0 +. el \ +. doc-end-list 1 +. \}\}\}\} +. +. br +.. +.ec +. +. +.\" NS doc-curr-type global register +.\" NS current argument type +. +.nr doc-curr-type 0 +. +. +.\" NS doc-curr-arg global string +.\" NS current argument +. +.ds doc-curr-arg +. +. +.\" NS doc-item-boxXXX global box +.\" NS item boxes associated list depth +.\" NS +.\" NS limit: +.\" NS doc-list-depth +. +. +.\" NS It user macro +.\" NS list item +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-argXXX +.\" NS doc-curr-arg +.\" NS doc-curr-type +.\" NS doc-in-list +.\" NS doc-macro-name +.\" NS doc-num-args +.\" NS +.\" NS local variables: +.\" NS doc-reg-It +.\" NS doc-str-It +.\" NS doc-XXX-list-type +.\" NS +.\" NS width register 'It' set in doc-common +. +.nr doc-bullet-list-type 1 +.nr doc-column-list-type 0 +.nr doc-dash-list-type 1 +.nr doc-diag-list-type 0 +.nr doc-enum-list-type 1 +.nr doc-hang-list-type 2 +.nr doc-inset-list-type 2 +.nr doc-item-list-type 1 +.nr doc-ohang-list-type 2 +.nr doc-tag-list-type 2 +. +.eo +.de It +. ds doc-str-It \*[doc-list-type-stack\n[doc-list-depth]] +. +. if "\*[doc-str-It]"" \ +. tm mdoc error: .It without preceding .Bl (#\n[.c]) +. +. if \n[doc-nesting-level] \{\ +. tmc "mdoc error: .It found in enclosing (e.g. .Ac ... .It ... .Ao) +. tm1 " (#\n[.c]) +. \} +. +. br +. if !\n[cR] \ +. ne 3v +. +. if \n[.$] \{\ +. ds doc-macro-name It +. +. \" fill argument vector +. nr doc-reg-It 1 +. while (\n[doc-reg-It] <= \n[.$]) \{\ +. ds doc-arg\n[doc-reg-It] "\$[\n[doc-reg-It]] +. nr doc-reg-It +1 +. \} +. +. nr doc-num-args \n[.$] +. nr doc-arg-ptr 0 +. \} +. +. nr doc-reg-It \n[doc-\*[doc-str-It]-type] +. +. if \n[doc-reg-It] \{\ +. \" start item box +. box doc-item-box\n[doc-list-depth] +. ev doc-item-env\n[doc-list-depth] +. evc 0 +. in 0 +. nf +. \} +. +. ie (\n[doc-reg-It] == 1) \{\ +. if \n[.$] \{\ +. tm1 "mdoc warning: .It macros in lists of type '\*[doc-str-It]' +. tm1 " don't take arguments (#\n[.c]) +. \}\} +. el \{\ +. ie \n[.$] \{\ +. if (\n[doc-reg-It] == 2) \{\ +. \" handle list types with arguments +. doc-parse-arg-vector +. +. nr doc-in-list 1 +. nr doc-arg-ptr 1 +. nr doc-curr-type \n[doc-type1] +. ds doc-curr-arg "\*[doc-arg1] +. +. ie (\n[doc-type1] == 1) \ +. \*[doc-arg1] +. el \{\ +. nr doc-arg-ptr 1 +. doc-print-recursive +. \}\}\} +. el \{\ +. tm1 "mdoc warning: .It macros in lists of type '\*[doc-str-It]' +. tm1 " require arguments (#\n[.c]) +. \} +. \} +. +. \" the previous call of '.doc-print-recursive' can contain calls to +. \" opening macros like '.Ao'; we then defer the call of +. \" 'doc-xxx-list' +. if !\n[doc-nesting-level] \ +. doc-\*[doc-str-It] +.. +.ec +. +. +.\" NS doc-inset-list macro +.\" NS .It item of list-type inset +.\" NS +.\" NS modifies: +.\" NS doc-in-list +. +.eo +.de doc-inset-list +. \" finish item box +. br +. ev +. box +. unformat doc-item-box\n[doc-list-depth] +. +. doc-set-vertical-and-indent 0 +. br +. +. nh +. doc-item-box\n[doc-list-depth] +. +. nr doc-in-list 0 +. doc-reset-args +.. +.ec +. +. +.\" NS doc-hang-list macro +.\" NS .It item of list-type hanging tag (as opposed to tagged) +.\" NS +.\" NS modifies: +.\" NS doc-have-space +.\" NS doc-in-list +.\" NS +.\" NS local variables: +.\" NS doc-reg-dhl +.\" NS doc-reg-dhl1 +. +.eo +.de doc-hang-list +. \" finish item box +. br +. ev +. box +. unformat doc-item-box\n[doc-list-depth] +. +. doc-set-vertical-and-indent 1 +. nr doc-reg-dhl (\n[doc-list-indent-stack\n[doc-list-depth]]u + \n[doc-digit-width]u) +. ti -\n[doc-reg-dhl]u +. +. nh +. ie (\n[dl]u > \n[doc-list-indent-stack\n[doc-list-depth]]u) \ +. doc-item-box\n[doc-list-depth] +. el \{\ +. chop doc-item-box\n[doc-list-depth] +. nr doc-reg-dhl1 \n[.k]u +. nop \*[doc-item-box\n[doc-list-depth]]\c +. nop \h'|(\n[doc-reg-dhl1]u - \n[.k]u + \n[doc-reg-dhl]u)'\c +. nr doc-have-space 1 +. \} +. +. nr doc-in-list 0 +. doc-reset-args +.. +.ec +. +. +.\" NS doc-ohang-list macro +.\" NS .It item of list-type overhanging tag +.\" NS +.\" NS modifies: +.\" NS doc-in-list +. +.eo +.de doc-ohang-list +. \" finish item box +. br +. ev +. box +. unformat doc-item-box\n[doc-list-depth] +. +. doc-set-vertical-and-indent 0 +. nh +. doc-item-box\n[doc-list-depth] +. br +. +. nr doc-in-list 0 +. doc-reset-args +.. +.ec +. +. +.\" NS doc-item-list macro +.\" NS .It item of list-type [empty tag] +. +.eo +.de doc-item-list +. \" finish (dummy) item box +. br +. ev +. box +. +. doc-set-vertical-and-indent 0 +. br +. +. doc-reset-args +.. +.ec +. +. +.\" NS doc-enum-list-count-stackXXX global register +.\" NS stack of current enum count values +.\" NS +.\" NS limit: +.\" NS doc-list-depth +. +.nr doc-enum-list-count-stack1 0 +. +. +.\" NS doc-enum-list macro +.\" NS enumerated list +.\" NS +.\" NS modifies: +.\" NS doc-enum-list-count-stackXXX +.\" NS doc-in-list +. +.eo +.de doc-enum-list +. nr doc-in-list 1 +. nr doc-enum-list-count-stack\n[doc-list-depth] +1 +\# XXX +\#.ll \n[doc-list-indent-stack\n[doc-list-depth]]u +\#.rj +. nop \*[doc-tag-prefix-stack\n[doc-list-depth]]\c +. nop \n[doc-enum-list-count-stack\n[doc-list-depth]].\& +. doc-do-list +.. +.ec +. +. +.\" NS doc-bullet-list macro +.\" NS bullet paragraph list +.\" NS +.\" NS modifies: +.\" NS doc-in-list +. +.eo +.de doc-bullet-list +. nr doc-in-list 1 +. nop \)\*[doc-Sy-font]\[bu]\f[] +. doc-do-list +.. +.ec +. +. +.\" NS doc-dash-list macro +.\" NS hyphen paragraph list (sub bullet list) +.\" NS +.\" NS modifies: +.\" NS doc-in-list +. +.eo +.de doc-dash-list +. nr doc-in-list 1 +. nop \)\*[doc-Sy-font]\-\f[] +. doc-do-list +.. +.ec +. +. +.\" NS doc-do-list macro +.\" NS .It item of list-type enum/bullet/hyphen +. +.als doc-do-list doc-hang-list +. +. +.\" NS doc-diag-list-input-line-count global register +.\" NS saved line number to be checked in next diag-list item +. +.nr doc-diag-list-input-line-count 0 +. +. +.\" NS doc-diag-list macro +.\" NS .It item of list-type diagnostic-message +.\" NS +.\" NS modifies: +.\" NS doc-curr-font +.\" NS doc-diag-list-input-line-count +. +.eo +.de doc-diag-list +. nr doc-curr-font \n[.f] +. +. ie ((\n[.c] - \n[doc-diag-list-input-line-count]) > 1) \{\ +. ie !\n[doc-compact-list-stack\n[doc-list-depth]] \ +. doc-paragraph +. el \ +. br +. \} +. el \ +. br +. nr doc-diag-list-input-line-count \n[.c] +. +. nh +. nop \*[doc-Sy-font]\c +. if \n[doc-num-args] \ +. doc-remaining-args +. nop \f[\n[doc-curr-font]]\*[doc-hard-space]\c +. +. doc-print-and-reset +.. +.ec +. +. +.\" NS doc-tag-list macro +.\" NS .It item of list-type 'tag' +.\" NS +.\" NS modifies: +.\" NS doc-have-space +.\" NS doc-in-list +.\" NS +.\" NS local variables: +.\" NS doc-box-dtl +.\" NS doc-reg-dtl +.\" NS doc-reg-dtl1 +. +.eo +.de doc-tag-list +. \" finish item box +. br +. ev +. box +. unformat doc-item-box\n[doc-list-depth] +. +. \" we use a box without '.nf' to compute the tag width (via 'dl' register) +. box doc-box-dtl +. ev doc-env-dtl +. evc 0 +. fi +. ad l +. in 0 +. doc-item-box\n[doc-list-depth] +. br +. ev +. box +. +. doc-set-vertical-and-indent 1 +. nr doc-reg-dtl (\n[doc-list-indent-stack\n[doc-list-depth]]u + \n[doc-digit-width]u) +. ti -\n[doc-reg-dtl]u +. +. nh +. doc-item-box\n[doc-list-depth] +. ie (\n[dl]u > \n[doc-list-indent-stack\n[doc-list-depth]]u) \ +. br +. el \{\ +. \" format the tag separately to prevent stretching of spaces +. vpt 0 +. br +. sp -1 +. vpt 1 +. nop \&\c +. nr doc-have-space 1 +. \} +. +. nr doc-in-list 0 +. doc-reset-args +.. +.ec +. +. +.\" NS doc-set-vertical-and-indent macro +.\" NS set up vertical spacing (if not compact) and indentation (with +.\" NS offset if argument is non-zero) +.\" NS +.\" NS modifies: +.\" NS doc-list-have-indent-stackXXX +. +.eo +.de doc-set-vertical-and-indent +. if !\n[doc-compact-list-stack\n[doc-list-depth]] \ +. sp \n[doc-display-vertical]u +. +. if \n[doc-list-have-indent-stack\n[doc-list-depth]] \{\ +. nr doc-list-have-indent-stack\n[doc-list-depth] 0 +. if \$1 \ +. in +(\n[doc-list-indent-stack\n[doc-list-depth]]u + \n[doc-digit-width]u) +. \} +. +. if !\n[cR] \ +. ne 2v +.. +.ec +. +. +.\" NS doc-list-depth global register +.\" NS list type stack counter +. +.nr doc-list-depth 0 +. +. +.\" NS doc-num-columns global register +.\" NS number of columns +. +.nr doc-num-columns 0 +. +. +.\" NS doc-compact-list-stackXXX global register (bool) +.\" NS stack of flags to indicate whether a particular list is compact +.\" NS +.\" NS limit: +.\" NS doc-list-depth +. +.nr doc-compact-list-stack1 0 +. +. +.\" NS doc-tag-prefix-stackXXX global string +.\" NS stack of tag prefixes (currently used for -nested -enum lists) +.\" NS +.\" NS limit: +.\" NS doc-list-depth +. +.ds doc-tag-prefix-stack1 +. +. +.\" NS doc-list-offset-stackXXX global register +.\" NS stack of list offsets +.\" NS +.\" NS limit: +.\" NS doc-list-depth +. +.nr doc-list-offset-stack1 0 +. +. +.\" NS doc-end-list macro +.\" NS list end function; resets indentation (and offset if argument +.\" NS is non-zero) +.\" NS +.\" NS modifies: +.\" NS doc-list-depth +.\" NS doc-list-offset-stackXXX +. +.eo +.de doc-end-list +. if \$1 \ +' in -(\n[doc-list-indent-stack\n[doc-list-depth]]u + \n[doc-digit-width]u) +. +' in -\n[doc-list-offset-stack\n[doc-list-depth]]u +. +. if (\n[doc-list-depth] <= 0) \ +. tm mdoc warning: extraneous .El call (#\n[.c]) +. +. doc-decrement-list-stack +. nr doc-list-depth -1 +.. +.ec +. +. +.\" NS doc-increment-list-stack macro +.\" NS set up next block for list +.\" NS +.\" NS modifies: +.\" NS doc-compact-list-stackXXX +.\" NS doc-list-have-indent-stackXXX +.\" NS doc-list-indent-stackXXX +.\" NS doc-list-offset-stackXXX +.\" NS doc-list-type-stackXXX +.\" NS doc-tag-prefix-stackXXX +.\" NS doc-enum-list-count-stackXXX +.\" NS +.\" NS local variables: +.\" NS doc-reg-dils +. +.eo +.de doc-increment-list-stack +. nr doc-reg-dils (\n[doc-list-depth] + 1) +. nr doc-list-have-indent-stack\n[doc-reg-dils] 0 +. nr doc-list-indent-stack\n[doc-reg-dils] 0 +. nr doc-list-offset-stack\n[doc-reg-dils] 0 +. ds doc-tag-prefix-stack\n[doc-reg-dils] +. ds doc-list-type-stack\n[doc-reg-dils] +. nr doc-compact-list-stack\n[doc-reg-dils] 0 +. nr doc-enum-list-count-stack\n[doc-reg-dils] 0 +.. +.ec +. +. +.\" NS doc-decrement-list-stack macro +.\" NS decrement stack +.\" NS +.\" NS modifies: +.\" NS doc-compact-list-stackXXX +.\" NS doc-list-have-indent-stackXXX +.\" NS doc-list-indent-stackXXX +.\" NS doc-list-offset-stackXXX +.\" NS doc-list-type-stackXXX +.\" NS doc-tag-prefix-stackXXX +.\" NS doc-enum-list-count-stackXXX +. +.eo +.de doc-decrement-list-stack +. ds doc-list-type-stack\n[doc-list-depth] +. nr doc-list-have-indent-stack\n[doc-list-depth] 0 +. nr doc-list-indent-stack\n[doc-list-depth] 0 +. nr doc-list-offset-stack\n[doc-list-depth] 0 +. ds doc-tag-prefix-stack\n[doc-list-depth] +. nr doc-compact-list-stack\n[doc-list-depth] 0 +. nr doc-enum-list-count-stack\n[doc-list-depth] 0 +.. +.ec +. +. +.\" NS Xr user macro +.\" NS cross reference (for man pages only) +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-macro-name +.\" NS +.\" NS local variables: +.\" NS doc-reg-Xr +.\" NS +.\" NS width register 'Xr' set in doc-common +. +.eo +.de Xr +. if !\n[doc-arg-count] \{\ +. ie \n[.$] \{\ +. ds doc-macro-name Xr +. doc-parse-args \$@ +. \} +. el \ +. doc-Xr-usage +. \} +. +. if !\n[doc-arg-count] \ +. return +. +. nr doc-arg-ptr +1 +. doc-print-prefixes +. ie (\n[doc-arg-count] >= \n[doc-arg-ptr]) \{\ +. \" first argument must be a string +. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +. nr doc-curr-font \n[.f] +. ds doc-arg\n[doc-arg-ptr] \*[doc-Xr-font]\*[doc-arg\n[doc-arg-ptr]]\f[] +. +. if (\n[doc-arg-count] > \n[doc-arg-ptr]) \{\ +. nr doc-reg-Xr (\n[doc-arg-ptr] + 1) +. \" modify second argument if it is a string and +. \" remove space in between +. if (\n[doc-type\n[doc-reg-Xr]] == 2) \{\ +. ds doc-arg\n[doc-reg-Xr] \*[lp]\*[doc-arg\n[doc-reg-Xr]]\*[rp] +. ds doc-space\n[doc-arg-ptr] +. \} +. \} +. doc-print-recursive +. \} +. el \ +. doc-Xr-usage +. \} +. el \ +. doc-Xr-usage +.. +.ec +. +. +.\" NS doc-Xr-usage macro +. +.eo +.de doc-Xr-usage +. tm Usage: .Xr manpage_name [section#] ... (#\n[.c]) +. doc-reset-args +.. +.ec +. +. +.\" NS Sx user macro +.\" NS cross section reference +.\" NS +.\" NS width register 'Sx' set in doc-common +.\" +.\" TODO: This duplicates the definition of `Dq`; figure out how to +.\" simply wrap that macro if possible. (It's not trivial to do so +.\" because of mdoc's design feature of recursively calling macro +.\" arguments as macros.) +. +.eo +.de Sx +. if !\n[doc-arg-count] \ +. ds doc-macro-name Sx +. +. ds doc-quote-left "\*[Lq] +. ds doc-quote-right "\*[Rq] +. +. doc-enclose-string \$@ +.. +.ec +. +. +.\" NS doc-end-column-list macro +.\" NS column-list end-list +.\" NS +.\" NS modifies: +.\" NS doc-list-depth +. +.eo +.de doc-end-column-list +. linetabs 0 +' in -(\n[doc-list-offset-stack\n[doc-list-depth]]u + \n[doc-list-indent-stack\n[doc-list-depth]]u) +. ta T .5i +. fi +. doc-decrement-list-stack +. nr doc-list-depth -1 +.. +.ec +. +. +.\" NS doc-column-indent-width global register +.\" NS holds the indent width for a column list +. +.nr doc-column-indent-width 0 +. +. +.\" NS doc-set-column-tab macro +.\" NS establish tabs for list-type column: '.doc-set-column-tab num_cols' +.\" NS +.\" NS modifies: +.\" NS doc-column-indent-width +.\" NS +.\" NS local variables: +.\" NS doc-reg-dsct +.\" NS doc-str-dsct +.\" NS doc-str-dsct1 +. +.eo +.de doc-set-column-tab +. ds doc-str-dsct +. nr doc-reg-dsct 1 +. nr doc-column-indent-width 0 +. +. ie (\$1 < 5) \ +. ds doc-str-dsct1 " \" +. el \{\ +. ie (\$1 == 5) \ +. ds doc-str-dsct1 " \" +. el \{\ +. \" XXX: this is packed abnormally close -- intercolumn width +. \" should be configurable +. ds doc-str-dsct1 " \" +. \}\} +. +. while (\n[doc-reg-dsct] <= \$1) \{\ +. as doc-str-dsct " +\w'\*[doc-arg\n[doc-reg-dsct]]\*[doc-str-dsct1]'u +. nr doc-column-indent-width +\w'\*[doc-arg\n[doc-reg-dsct]]\*[doc-str-dsct1]'u +. nr doc-reg-dsct +1 +. \} +. +. ta \*[doc-str-dsct] +' in +\n[doc-column-indent-width]u +.. +.ec +. +. +.\" NS doc-column-list macro +.\" NS column items +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-list-indent-stackXXX +.\" NS doc-spaceXXX +.\" NS +.\" NS local variables: +.\" NS doc-reg-dcl +. +.eo +.de doc-column-list +. if \n[doc-num-args] \ +. doc-parse-arg-vector +. nr doc-arg-ptr +1 +. +. if (\n[doc-arg-count] < \n[doc-arg-ptr]) \{\ +. tm Usage: .It column_string [Ta [column_string ...] ] (#\n[.c]) +. return +. \} +. +. if "\*[doc-arg\n[doc-arg-ptr]]"Ta" \{\ +. nr doc-reg-dcl (\n[doc-arg-ptr] - 1) +. ds doc-space\n[doc-reg-dcl] +. \} +. +. if !\n[doc-list-indent-stack\n[doc-list-depth]] \ +. nr doc-list-indent-stack\n[doc-list-depth] \n[doc-column-indent-width]u +. if !\n[.u] \{\ +. fi +. in +\n[doc-column-indent-width]u +. \} +. ti -\n[doc-column-indent-width]u +. +. doc-do-\n[doc-type\n[doc-arg-ptr]] +.. +.ec +. +. +.\" NS Ta user macro +.\" NS append tab (\t) +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS +.\" NS width register 'Ta' set in doc-common +. +.eo +.de Ta +. ie \n[doc-arg-count] \{\ +. nr doc-arg-ptr +1 +. nop \*[doc-tab]\c +. ie (\n[doc-arg-count] >= \n[doc-arg-ptr]) \ +. doc-do-\n[doc-type\n[doc-arg-ptr]] +. el \ +. doc-reset-args +. \} +. el \{\ +. tm1 "Usage: Ta must follow column entry: e.g. +. tm1 " .It column_string [Ta [column_string ...]] (#\n[.c]) +. \} +.. +.ec +. +. +.\" NS Dl user macro +.\" NS display (one line) literal +.\" NS +.\" NS this function uses the 'Li' font +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS +.\" NS width register 'Dl' set in doc-common +. +.eo +.de Dl +. ta T .5i +. in +\n[doc-display-indent]u +. +. ie \n[doc-arg-count] \{\ +. tm Usage: .Dl not callable by other macros (#\n[.c]) +. doc-reset-args +. \} +. el \{\ +. ie \n[.$] \{\ +. ds doc-macro-name Dl +. doc-parse-args \$@ +. nr doc-arg-ptr 1 +. nr doc-curr-font \n[.f] +. nop \*[doc-Li-font]\c +. doc-print-recursive +. \} +. el \ +. tm Usage: .Dl argument ... (#\n[.c]) +. \} +. +. in -\n[doc-display-indent]u +.. +.ec +. +. +.\" NS D1 user macro +.\" NS display (one line) +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-macro-name +.\" NS +.\" NS width register 'D1' set in doc-common +. +.eo +.de D1 +. ta T .5i +. in +\n[doc-display-indent]u +. +. ie \n[doc-arg-count] \{\ +. tm Usage: .D1 not callable by other macros (#\n[.c]) +. doc-reset-args +. \} +. el \{\ +. ie \n[.$] \{\ +. ds doc-macro-name D1 +. doc-parse-args \$@ +. nr doc-arg-ptr 1 +. doc-print-recursive +. \} +. el \ +. tm Usage: .D1 argument ... (#\n[.c]) +. \} +. +. in -\n[doc-display-indent]u +.. +.ec +. +. +.\" NS Vt user macro +.\" NS variable type (for forcing old style variable declarations); +.\" NS this is not done in the same manner as .Ot for fortrash -- +.\" NS clean up later +.\" NS +.\" NS modifies: +.\" NS doc-curr-font +.\" NS doc-have-decl +.\" NS doc-have-var +.\" NS doc-macro-name +.\" NS +.\" NS width register 'Vt' set in doc-common +. +.eo +.de Vt +. if !\n[doc-arg-count] \{\ +. ie \n[.$] \{\ +. ds doc-macro-name Vt +. doc-parse-args \$@ +. \} +. el \ +. tm Usage: .Vt variable_type ... (#\n[.c]) +. \} +. +. if !\n[doc-arg-count] \ +. return +. +. nr doc-arg-ptr +1 +. if (\n[doc-arg-count] < \n[doc-arg-ptr]) \{\ +. tm Usage: .Vt variable_type ... (#\n[.c]) +. doc-reset-args +. return +. \} +. +. if \n[doc-in-synopsis-section] \{\ +. \" if a function declaration was the last thing given, +. \" want vertical space +. if \n[doc-have-decl] \{\ +. doc-paragraph +. nr doc-have-decl 0 +. \} +. +. \" if a subroutine was the last thing given, want vertical space +. if \n[doc-have-func] \{\ +. ie \n[doc-have-var] \ +. br +. el \ +. doc-paragraph +. \} +. +. nr doc-have-var 1 +. \} +. +. nr doc-curr-font \n[.f] +. nop \*[doc-Ft-font]\c +. doc-print-recursive +. +. if \n[doc-in-synopsis-section] \{\ +. ie \n[doc-have-old-func] \ +. nop \*[doc-soft-space]\c +. el \ +. br +. \} +.. +.ec +. +. +.\" NS doc-is-func global register (bool) +.\" NS set if subroutine (in synopsis only) (fortran only) +. +.nr doc-is-func 0 +. +. +.\" NS Ft user macro +.\" NS function type +.\" NS +.\" NS modifies: +.\" NS doc-curr-font +.\" NS doc-have-decl +.\" NS doc-have-var +.\" NS doc-is-func +.\" NS doc-macro-name +.\" NS +.\" NS width register 'Ft' set in doc-common +. +.eo +.de Ft +. if !\n[doc-arg-count] \{\ +. ie \n[.$] \{\ +. ds doc-macro-name Ft +. doc-parse-args \$@ +. \} +. el \ +. tm Usage: .Ft function_type ... (#\n[.c]) +. \} +. +. if !\n[doc-arg-count] \ +. return +. +. nr doc-arg-ptr +1 +. if (\n[doc-arg-count] < \n[doc-arg-ptr]) \{\ +. tm Usage: .Ft function_type ... (#\n[.c]) +. doc-reset-args +. return +. \} +. +. if \n[doc-in-synopsis-section] \{\ +. if (\n[doc-have-func] : \n[doc-have-decl]) \{\ +. doc-paragraph +. nr doc-have-decl 0 +. nr doc-have-var 0 +. \} +. +. if \n[doc-have-var] \{\ +. doc-paragraph +. nr doc-have-var 0 +. \} +. +. nr doc-is-func 1 +. \} +. +. nr doc-curr-font \n[.f] +. nop \*[doc-Ft-font]\c +. doc-print-recursive +.. +.ec +. +. +.\" NS doc-have-old-func global register (bool) +.\" NS set if 'Ot' has been called +. +.nr doc-have-old-func 0 +. +. +.\" NS Ot user macro +.\" NS old function type (fortran -- no newline) +.\" NS +.\" NS modifies: +.\" NS doc-have-decl +.\" NS doc-have-old-func +.\" NS doc-have-var +.\" NS doc-is-func +.\" NS +.\" NS width register 'Ot' set in doc-common +. +.eo +.de Ot +. nr doc-have-old-func 1 +. +. if \n[doc-in-synopsis-section] \{\ +. if (\n[doc-have-func] : \n[doc-have-decl]) \{\ +. doc-paragraph +. nr doc-have-decl 0 +. nr doc-have-var 0 +. \} +. +. if \n[doc-have-var] \{\ +. doc-paragraph +. nr doc-have-var 0 +. \} +. +. nr doc-is-func 1 +. \} +. +. if \n[.$] \ +. nop \*[doc-Ft-font]\$*\c +. nop \ \f[]\c +.. +.ec +. +. +.\" NS Fa user macro +.\" NS function arguments +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS +.\" NS width register 'Fa' set in doc-common +. +.eo +.de Fa +. if !\n[doc-arg-count] \{\ +. ie \n[.$] \{\ +. ds doc-macro-name Fa +. doc-parse-args \$@ +. \} +. el \ +. tm Usage: .Fa function_arguments ... (#\n[.c]) +. \} +. +. ie \n[doc-func-arg-count] \ +. doc-do-func +. el \{\ +. nr doc-arg-ptr +1 +. if (\n[doc-arg-count] >= \n[doc-arg-ptr]) \{\ +. nr doc-curr-font \n[.f] +. nop \*[doc-Fa-font]\c +. doc-print-recursive +. +. if \n[doc-in-synopsis-section] \ +. if \n[doc-have-func] \ +. br +. \}\} +.. +.ec +. +. +.\" NS doc-func-arg-count global register +.\" NS how many function arguments have been processed so far +. +.nr doc-func-arg-count 0 +. +. +.\" NS doc-func-arg global string +.\" NS work buffer for function name strings +. +.ds doc-func-arg +. +. +.\" NS doc-num-func-args global register +.\" NS number of function arguments +. +.nr doc-num-func-args 0 +. +. +.\" NS doc-func-args-processed global register +.\" NS function arguments processed so far +. +.nr doc-func-args-processed 0 +. +. +.\" NS doc-do-func macro +.\" NS internal .Fa for .Fc +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-argXXX +.\" NS doc-func-arg +.\" NS doc-func-arg-count +.\" NS doc-func-args-processed +.\" NS doc-num-func-args +. +.eo +.de doc-do-func +. if (\n[doc-arg-count] <= \n[doc-arg-ptr]) \{\ +. doc-reset-args +. return +. \} +. +. nr doc-arg-ptr +1 +. +. ds doc-func-arg +. nr doc-num-func-args 0 +. nr doc-func-args-processed 0 +. +. doc-build-func-string \*[doc-arg\n[doc-arg-ptr]] +. if (\n[doc-num-func-args] > 1) \ +. ds doc-arg\n[doc-arg-ptr] "\*[doc-func-arg] +. +. if (\n[doc-func-arg-count] > 1) \{\ +. nop \f[\n[doc-curr-font]]\|\c +. if !"\*[doc-arg\n[doc-arg-ptr]]"/*" \ +. if !"\*[doc-arg\n[doc-arg-ptr]]"*/" \ +. nop ,\)\c +. nop \)\*[doc-space\n[doc-arg-ptr]]\*[doc-Fa-font]\c +. nop \)\*[doc-arg\n[doc-arg-ptr]]\f[]\c +. \} +. +. if (\n[doc-func-arg-count] == 1) \{\ +. nop \)\*[doc-Fa-font]\*[doc-arg\n[doc-arg-ptr]]\c +. nop \f[]\c +. \} +. nr doc-func-arg-count +1 +. doc-do-func +.. +.ec +. +. +.\" NS doc-have-func global register (bool) +.\" NS whether we have more than one function in synopsis +. +.nr doc-have-func 0 +. +. +.\" NS Fn user macro +.\" NS functions +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-have-decl +.\" NS doc-have-func +.\" NS doc-have-var +.\" NS doc-indent-synopsis +.\" NS doc-is-func +.\" NS doc-macro-name +.\" NS +.\" NS width register 'Fn' set in doc-common +. +.eo +.de Fn +. if !\n[doc-arg-count] \{\ +. ie \n[.$] \{\ +. ds doc-macro-name Fn +. doc-parse-args \$@ +. \} +. el \ +. tm Usage: .Fn function_name [function_arg] ... (#\n[.c]) +. \} +. +. if !\n[doc-arg-count] \ +. return +. +. if \n[doc-in-synopsis-section] \{\ +. \" if there is/has been more than one subroutine declaration +. ie \n[doc-is-func] \{\ +. br +. nr doc-have-var 0 +. nr doc-have-decl 0 +. nr doc-is-func 0 +. \} +. el \{\ +. if \n[doc-have-func] \{\ +. doc-paragraph +. nr doc-have-var 0 +. nr doc-have-decl 0 +. \}\} +. +. if \n[doc-have-decl] \{\ +. doc-paragraph +. nr doc-have-var 0 +. \} +. +. if \n[doc-have-var] \{\ +. doc-paragraph +. nr doc-have-decl 0 +. \} +. +. nr doc-have-func 1 +. nr doc-is-func 0 +. +. br +. if !\n[doc-indent-synopsis] \ +. nr doc-indent-synopsis (4u * \n[doc-fixed-width]u) +. if !\n[doc-indent-synopsis-active] \ +. in +\n[doc-indent-synopsis]u +. ti -\n[doc-indent-synopsis]u +. \} +. +. nr doc-arg-ptr +1 +. doc-print-prefixes +. if (\n[doc-arg-count] < \n[doc-arg-ptr]) \{\ +. tm Usage: .Fn function_name [function_arg] ... (#\n[.c]) +. doc-reset-args +. return +. \} +. +. nr doc-curr-font \n[.f] +. nop \*[doc-Fn-font]\*[doc-arg\n[doc-arg-ptr]]\c +. nop \f[]\*[lp]\)\c +. +. nr doc-arg-ptr +1 +. if (\n[doc-arg-count] >= \n[doc-arg-ptr]) \{\ +. if (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +. nop \*[doc-Fa-font]\c +. doc-do-func-args +. nop \f[\n[doc-curr-font]]\c +. \}\} +. +. nop \)\*[rp]\)\c +. if \n[doc-in-synopsis-section] \ +. nop \);\)\c +. +. ie (\n[doc-arg-count] >= \n[doc-arg-ptr]) \{\ +. \" output the space (if needed) +. nr doc-arg-ptr -1 +. nop \)\*[doc-space\n[doc-arg-ptr]]\c +. nr doc-arg-ptr +1 +. +. doc-print-recursive +. \} +. el \ +. doc-print-and-reset +. +. if \n[doc-in-synopsis-section] \ +. if !\n[doc-indent-synopsis-active] \ +. in -\n[doc-indent-synopsis]u +.. +.ec +. +. +.\" NS doc-do-func-args macro +.\" NS handle function arguments +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-argXXX +.\" NS doc-func-arg +.\" NS doc-func-args-processed +.\" NS doc-num-func-args +.\" NS +.\" NS local variables: +.\" NS doc-reg-ddfa +. +.eo +.de doc-do-func-args +. if \n[doc-in-synopsis-section] \{\ +. ds doc-func-arg +. nr doc-num-func-args 0 +. nr doc-func-args-processed 0 +. +. doc-build-func-string \*[doc-arg\n[doc-arg-ptr]] +. if (\n[doc-num-func-args] > 1) \ +. ds doc-arg\n[doc-arg-ptr] "\*[doc-func-arg] +. \} +. +. nop \)\*[doc-arg\n[doc-arg-ptr]]\c +. nr doc-arg-ptr +1 +. +. if (\n[doc-arg-count] >= \n[doc-arg-ptr]) \{\ +. if (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +. nr doc-reg-ddfa (\n[doc-arg-ptr] - 1) +. nop \f[\n[doc-curr-font]]\|\c +. if !"\*[doc-arg\n[doc-arg-ptr]]"/*" \ +. if !"\*[doc-arg\n[doc-arg-ptr]]"*/" \ +. nop ,\)\c +. nop \)\*[doc-space\n[doc-reg-ddfa]]\f[]\|\c +. doc-do-func-args +. \}\} +.. +.ec +. +. +.\" NS doc-saved-nesting-level global register +. +.nr doc-saved-nesting-level 0 +. +. +.\" NS doc-in-func-enclosure global register (bool) +. +.nr doc-in-func-enclosure 0 +. +. +.\" NS Fo user macro +.\" NS function open +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-func-arg-count +.\" NS doc-have-decl +.\" NS doc-have-func +.\" NS doc-have-var +.\" NS doc-in-func-enclosure +.\" NS doc-indent-synopsis +.\" NS doc-is-func +.\" NS doc-macro-name +.\" NS doc-saved-nesting-level +.\" NS +.\" NS width register 'Fo' set in doc-common +. +.eo +.de Fo +. if (\n[doc-in-func-enclosure]) \{\ +. tm mdoc error: .Fo/.Fc can't be nested (#\n[.c]) +. return +. \} +. +. nr doc-saved-nesting-level \n[doc-nesting-level] +. nr doc-in-func-enclosure 1 +. +. if !\n[doc-arg-count] \{\ +. ie \n[.$] \{\ +. ds doc-macro-name Fo +. doc-parse-args \$@ +. \} +. el \ +. tm Usage: .Fo function_name (#\n[.c]) +. \} +. +. if \n[doc-in-synopsis-section] \{\ +. \" if there is/has been more than one subroutine declaration +. ie \n[doc-is-func] \{\ +. br +. nr doc-have-var 0 +. nr doc-have-decl 0 +. nr doc-is-func 0 +. \} +. el \{\ +. if \n[doc-have-func] \{\ +. doc-paragraph +. nr doc-have-var 0 +. nr doc-have-decl 0 +. \}\} +. +. if \n[doc-have-decl] \{\ +. doc-paragraph +. nr doc-have-var 0 +. \} +. +. if \n[doc-have-var] \{\ +. doc-paragraph +. nr doc-have-decl 0 +. \} +. +. nr doc-have-func 1 +. nr doc-is-func 0 +. +. br +. if !\n[doc-indent-synopsis] \ +. nr doc-indent-synopsis (4u * \n[doc-fixed-width]u) +. \} +. +. \" start function box +. box doc-func-box +. ev doc-func-env +. evc 0 +. in 0 +. nf +. +. nr doc-arg-ptr +1 +. doc-print-prefixes +. if (\n[doc-arg-count] >= \n[doc-arg-ptr]) \{\ +. nr doc-func-arg-count 1 +. nr doc-curr-font \n[.f] +. +. nop \*[doc-Fn-font]\*[doc-arg\n[doc-arg-ptr]]\c +. nop \f[]\*[lp]\)\c +. doc-reset-args +. \} +.. +.ec +. +. +.\" NS Fc user macro +.\" NS function close +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-func-arg-count +.\" NS doc-in-func-enclosure +.\" NS doc-saved-nesting-level +.\" NS doc-macro-name +.\" NS +.\" NS width register 'Fc' set in doc-common +. +.eo +.de Fc +. if !\n[doc-in-func-enclosure] \{\ +. tm mdoc warning: Extraneous .Fc (#\n[.c]) +. return +. \} +. +. if \n[.$] \{\ +. ds doc-macro-name Fc +. \" the first (dummy) argument is used to get the correct spacing +. doc-parse-args \) \$@ +. \} +. +. if !(\n[doc-saved-nesting-level] == \n[doc-nesting-level]) \ +. tm mdoc warning: Unbalanced enclosure commands within .Fo/.Fc +. +. nr doc-func-arg-count 0 +. nr doc-in-func-enclosure 0 +. +. ie \n[doc-in-synopsis-section] \ +. nop \|\*[rp];\) +. el \ +. nop \|\*[rp]\) +. +. \" finish function box +. br +. ev +. box +. chop doc-func-box +. unformat doc-func-box +. +. if \n[doc-in-synopsis-section] \{\ +. if !\n[doc-indent-synopsis-active] \ +. in +\n[doc-indent-synopsis]u +. ti -\n[doc-indent-synopsis]u +. \} +. +. nh +. nop \*[doc-func-box]\c +. +. nr doc-arg-ptr +1 +. ie (\n[doc-arg-count] >= \n[doc-arg-ptr]) \{\ +. nr doc-curr-font \n[.f] +. doc-print-recursive +. \} +. el \ +. doc-print-and-reset +. +. if \n[doc-in-synopsis-section] \ +. if !\n[doc-indent-synopsis-active] \ +. in -\n[doc-indent-synopsis]u +.. +.ec +. +. +.\" NS doc-build-func-string macro +.\" NS collect function arguments and set hard spaces in between +.\" NS +.\" NS modifies: +.\" NS doc-func-arg +.\" NS doc-func-args-processed +.\" NS doc-num-func-args +. +.eo +.de doc-build-func-string +. if !\n[doc-num-func-args] \{\ +. nr doc-num-func-args \n[.$] +. nr doc-func-args-processed 0 +. ds doc-func-arg +. \} +. +. nr doc-func-args-processed +1 +. as doc-func-arg "\$1 +. +. if (\n[doc-func-args-processed] < \n[doc-num-func-args]) \{\ +. as doc-func-arg "\*[doc-hard-space] +. +. shift +. doc-build-func-string \$@ +. \} +.. +.ec +. +. +.\" Very crude references: Stash all reference info into boxes, print +.\" out reference on .Re macro and clean up. Ordering very limited, no +.\" fancy citations, but can do articles, journals, and books -- need to +.\" add several missing options (like city etc). Should be able to grab +.\" a refer entry, massage it a wee bit (prefix a '.' to the %[A-Z]) and +.\" not worry (ha!). +. +. +.\" NS doc-is-reference global register (bool) +.\" NS set if in reference +. +.nr doc-is-reference 0 +. +. +.\" NS doc-reference-count global register +.\" NS reference element counter +. +.nr doc-reference-count 0 +. +. +.\" NS Rs user macro +.\" NS reference start +.\" NS +.\" NS modifies: +.\" NS doc-is-reference +.\" NS doc-reference-count +.\" NS +.\" NS width register 'Rs' set in doc-common +. +.eo +.de Rs +. ie \n[.$] \ +. tm Usage: .Rs (does not take arguments) (#\n[.c]) +. el \{\ +. nr doc-is-reference 1 +. doc-reset-reference +. if \n[doc-in-see-also-section] \ +. doc-paragraph +. nr doc-reference-count 0 +. \} +.. +.ec +. +. +.\" NS Re user macro +.\" NS reference end +.\" NS +.\" NS modifies: +.\" NS doc-is-reference +.\" NS +.\" NS width register 'Re' set in doc-common +. +.eo +.de Re +. ie \n[.$] \ +. tm Usage: .Re (does not take arguments) (#\n[.c]) +. el \{\ +. if !\n[doc-is-reference] \{\ +. tm mdoc warning: Extraneous .Re (#\n[.c]) +. return +. \} +. doc-print-reference +. doc-reset-reference +. nr doc-is-reference 0 +. \} +.. +.ec +. +. +.\" NS doc-reset-reference macro +.\" NS reference cleanup +.\" NS +.\" NS modifies: +.\" NS doc-author-count +.\" NS doc-author-nameXXX +.\" NS doc-book-count +.\" NS doc-book-name +.\" NS doc-city-count +.\" NS doc-city-name +.\" NS doc-corporate-count +.\" NS doc-corporate-name +.\" NS doc-date +.\" NS doc-date-count +.\" NS doc-issue-count +.\" NS doc-issue-name +.\" NS doc-journal-count +.\" NS doc-journal-name +.\" NS doc-optional-count +.\" NS doc-optional-string +.\" NS doc-page-number-count +.\" NS doc-page-number-string +.\" NS doc-publisher-count +.\" NS doc-publisher-name +.\" NS doc-reference-count +.\" NS doc-reference-title-count +.\" NS doc-reference-title-name +.\" NS doc-reference-title-name-for-book +.\" NS doc-report-count +.\" NS doc-report-name +.\" NS doc-url-count +.\" NS doc-url-name +.\" NS doc-volume-count +.\" NS doc-volume-name +. +.eo +.de doc-reset-reference +. while (\n[doc-author-count]) \{\ +. ds doc-author-name\n[doc-author-count] +. nr doc-author-count -1 +. \} +. nr doc-journal-count 0 +. nr doc-issue-count 0 +. nr doc-optional-count 0 +. nr doc-corporate-count 0 +. nr doc-report-count 0 +. nr doc-reference-title-count 0 +. nr doc-url-count 0 +. nr doc-volume-count 0 +. nr doc-city-count 0 +. nr doc-date-count 0 +. nr doc-page-number-count 0 +. nr doc-book-count 0 +. nr doc-publisher-count 0 +. nr doc-reference-count 0 +. +. ds doc-journal-name +. ds doc-issue-name +. ds doc-optional-string +. ds doc-corporate-name +. ds doc-report-name +. ds doc-reference-title-name +. ds doc-reference-title-name-for-book +. ds doc-url-name +. ds doc-volume-name +. ds doc-city-name +. ds doc-date +. ds doc-page-number-string +. ds doc-book-name +. ds doc-publisher-name +.. +.ec +. +. +.\" NS doc-finish-reference macro +.\" NS auxiliary macro for doc-print-reference +.\" NS +.\" NS modifies: +.\" NS doc-reference-count +. +.eo +.de doc-finish-reference +. nr doc-reference-count -\$1 +. ie \n[doc-reference-count] \ +. nop \), +. el \ +. nop \). +.. +.ec +. +. +.\" NS doc-print-reference macro +.\" NS reference print +.\" NS +.\" NS modifies: +.\" NS doc-reference-count +. +.eo +.de doc-print-reference +. +. nh +. +. if \n[doc-author-count] \{\ +. doc-print-reference-authors +. nr doc-reference-count -\n[doc-author-count] +. \} +. +. if \n[doc-reference-title-count] \{\ +. unformat doc-reference-title-name +. chop doc-reference-title-name +. unformat doc-reference-title-name-for-book +. chop doc-reference-title-name-for-book +. ie ((\n[doc-journal-count] == 1) : (\n[doc-book-count] == 1)) \{\ +. nop \)\*[Lq]\)\*[doc-reference-title-name-for-book]\)\*[Rq]\c +. doc-finish-reference \n[doc-reference-title-count] +. \} +. el \{\ +. nop \*[doc-reference-title-name]\c +. doc-finish-reference \n[doc-reference-title-count] +. \}\} +. +. if \n[doc-book-count] \{\ +. unformat doc-book-name +. chop doc-book-name +. nop \*[doc-book-name]\c +. doc-finish-reference \n[doc-book-count] +. \} +. +. if \n[doc-publisher-count] \{\ +. unformat doc-publisher-name +. chop doc-publisher-name +. nop \*[doc-publisher-name]\c +. doc-finish-reference \n[doc-publisher-count] +. \} +. +. if \n[doc-journal-count] \{\ +. unformat doc-journal-name +. chop doc-journal-name +. nop \*[doc-journal-name]\c +. doc-finish-reference \n[doc-journal-count] +. \} +. +. if \n[doc-report-count] \{\ +. unformat doc-report-name +. chop doc-report-name +. nop \*[doc-report-name]\c +. doc-finish-reference \n[doc-report-count] +. \} +. +. if \n[doc-issue-count] \{\ +. unformat doc-issue-name +. chop doc-issue-name +. nop \*[doc-issue-name]\c +. doc-finish-reference \n[doc-issue-count] +. \} +. +. if \n[doc-volume-count] \{\ +. unformat doc-volume-name +. chop doc-volume-name +. nop \*[doc-volume-name]\c +. doc-finish-reference \n[doc-volume-count] +. \} +. +. if \n[doc-url-count] \{\ +. unformat doc-url-name +. chop doc-url-name +. nop \*[doc-url-name]\c +. doc-finish-reference \n[doc-url-count] +. \} +. +. if \n[doc-page-number-count] \{\ +. unformat doc-page-number-string +. chop doc-page-number-string +. nop \*[doc-page-number-string]\c +. doc-finish-reference \n[doc-page-number-count] +. \} +. +. if \n[doc-corporate-count] \{\ +. unformat doc-corporate-name +. chop doc-corporate-name +. nop \*[doc-corporate-name]\c +. doc-finish-reference \n[doc-corporate-count] +. \} +. +. if \n[doc-city-count] \{\ +. unformat doc-city-name +. chop doc-city-name +. nop \*[doc-city-name]\c +. doc-finish-reference \n[doc-city-count] +. \} +. +. if \n[doc-date-count] \{\ +. unformat doc-date +. chop doc-date +. nop \*[doc-date]\c +. doc-finish-reference \n[doc-date-count] +. \} +. +. if \n[doc-optional-count] \{\ +. unformat doc-optional-string +. chop doc-optional-string +. nop \*[doc-optional-string]\c +. doc-finish-reference \n[doc-optional-count] +. \} +. +. if \n[doc-reference-count] \ +. tm mdoc warning: unresolved reference problem +. +. hy \n[doc-hyphen-flags] +.. +.ec +. +. +.\" NS doc-print-reference-authors macro +.\" NS print out reference authors +.\" NS +.\" NS local variables: +.\" NS doc-reg-dpra +.\" NS doc-str-dpra +. +.ds doc-str-dpra "and +. +.eo +.de doc-print-reference-authors +. nr doc-reg-dpra 1 +. +. while (\n[doc-reg-dpra] < \n[doc-author-count]) \{\ +. unformat doc-author-name\n[doc-reg-dpra] +. chop doc-author-name\n[doc-reg-dpra] +. ie (\n[doc-author-count] > 2) \ +. nop \)\*[doc-author-name\n[doc-reg-dpra]], +. el \ +. nop \)\*[doc-author-name\n[doc-reg-dpra]] +. nr doc-reg-dpra +1 +. \} +. +. unformat doc-author-name\n[doc-reg-dpra] +. chop doc-author-name\n[doc-reg-dpra] +. if (\n[doc-author-count] > 1) \ +. nop \)\*[doc-str-dpra] +. nop \)\*[doc-author-name\n[doc-reg-dpra]], +.. +.ec +. +. +.\" NS doc-author-count global register +.\" NS counter of author references +. +.nr doc-author-count 0 +. +. +.\" NS doc-author-nameXXX global box +.\" NS array of author names +.\" NS +.\" NS limit: +.\" NS doc-author-count +. +.ds doc-author-name0 +. +. +.\" NS %A user macro +.\" NS reference author(s) +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-author-count +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS doc-reference-count +.\" NS +.\" NS local variables: +.\" NS doc-env-%A +.\" NS +.\" NS width register '%A' set in doc-common +. +.eo +.de %A +. if (\n[doc-arg-count] : (\n[.$] == 0)) \{\ +. tm Usage: .%A author_name ... (#\n[.c]) +. return +. \} +. +. nr doc-author-count +1 +. nr doc-reference-count +1 +. +. ds doc-macro-name %A +. doc-parse-args \$@ +. +. nr doc-arg-ptr +1 +. nr doc-curr-font \n[.f] +. +. \" save to reference box +. box doc-author-name\n[doc-author-count] +. ev doc-env-%A +. evc 0 +. in 0 +. nf +. doc-do-references +.. +.ec +. +. +.\" NS doc-book-count global register +.\" NS counter of book references +. +.nr doc-book-count 0 +. +. +.\" NS doc-book-name global box +.\" NS string of collected book references +. +.ds doc-book-name +. +. +.\" NS %B user macro +.\" NS [reference] book name +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-book-count +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS doc-reference-count +.\" NS +.\" NS local variables: +.\" NS doc-env-%B +.\" NS +.\" NS width register '%B' set in doc-common +. +.eo +.de %B +. if (\n[doc-arg-count] : (\n[.$] == 0)) \{\ +. tm Usage: .%B book_name ... (#\n[.c]) +. return +. \} +. +. if \n[doc-is-reference] \{\ +. nr doc-book-count +1 +. nr doc-reference-count +1 +. \} +. +. ds doc-macro-name %B +. doc-parse-args \$@ +. +. nr doc-arg-ptr +1 +. nr doc-curr-font \n[.f] +. +. ie \n[doc-is-reference] \{\ +. \" append to reference box +. boxa doc-book-name +. ev doc-env-%B +. evc 0 +. in 0 +. nf +. nop \*[doc-Em-font]\c +. doc-do-references +. \} +. el \{\ +. nop \*[doc-Em-font]\c +. doc-print-recursive +. \} +.. +.ec +. +. +.\" NS doc-city-count global register +.\" NS counter of city references +. +.nr doc-city-count 0 +. +. +.\" NS doc-city-name global box +.\" NS string of collected city references +. +.ds doc-city-name +. +. +.\" NS %C user macro +.\" NS [reference] city +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-city-count +.\" NS doc-macro-name +.\" NS doc-reference-count +.\" NS +.\" NS local variables: +.\" NS doc-env-%C +.\" NS +.\" NS width register '%C' set in doc-common +. +.eo +.de %C +. if (\n[doc-arg-count] : (\n[.$] == 0)) \{\ +. tm Usage: .%C city_name ... (#\n[.c]) +. return +. \} +. +. nr doc-city-count +1 +. nr doc-reference-count +1 +. +. ds doc-macro-name %C +. doc-parse-args \$@ +. +. nr doc-arg-ptr +1 +. nr doc-curr-font \n[.f] +. +. \" append to reference box +. boxa doc-city-name +. ev doc-env-%C +. evc 0 +. in 0 +. nf +. doc-do-references +.. +.ec +. +. +.\" NS doc-date-count global register +.\" NS counter of date references +. +.nr doc-date-count 0 +. +. +.\" NS doc-date global box +.\" NS string of collected date references +. +.ds doc-date +. +. +.\" NS %D user macro +.\" NS [reference] date +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-date-count +.\" NS doc-macro-name +.\" NS doc-reference-count +.\" NS +.\" NS local variables: +.\" NS doc-env-%D +.\" NS +.\" NS width register '%D' set in doc-common +. +.eo +.de %D +. if (\n[doc-arg-count] : (\n[.$] == 0)) \{\ +. tm Usage: .%D date ... (#\n[.c]) +. return +. \} +. +. nr doc-date-count +1 +. nr doc-reference-count +1 +. +. ds doc-macro-name %D +. doc-parse-args \$@ +. +. nr doc-arg-ptr +1 +. nr doc-curr-font \n[.f] +. +. \" append to reference box +. boxa doc-date +. ev doc-env-%D +. evc 0 +. in 0 +. nf +. doc-do-references +.. +.ec +. +. +.\" NS doc-publisher-count global register +.\" NS counter of publisher references +. +.nr doc-publisher-count 0 +. +. +.\" NS doc-publisher-name global box +.\" NS string of collected publisher references +. +.ds doc-publisher-name +. +. +.\" NS %I user macro +.\" NS [reference] issuer/publisher name +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS doc-publisher-count +.\" NS doc-reference-count +.\" NS +.\" NS local variables: +.\" NS doc-env-%I +.\" NS +.\" NS width register '%I' set in doc-common +. +.eo +.de %I +. if (\n[doc-arg-count] : (\n[.$] == 0)) \{\ +. tm Usage: .%I issuer/publisher_name ... (#\n[.c]) +. return +. \} +. +. nr doc-publisher-count +1 +. nr doc-reference-count +1 +. +. ds doc-macro-name %I +. doc-parse-args \$@ +. +. nr doc-arg-ptr +1 +. nr doc-curr-font \n[.f] +. +. \" append to reference box +. boxa doc-publisher-name +. ev doc-env-%I +. evc 0 +. in 0 +. nf +. nop \*[doc-Em-font]\c +. doc-do-references +.. +.ec +. +. +.\" NS doc-journal-count global register +.\" NS counter of journal references +. +.nr doc-journal-count 0 +. +. +.\" NS doc-journal-name global box +.\" NS string of collected journal references +. +.ds doc-journal-name +. +. +.\" NS %J user macro +.\" NS [reference] Journal Name +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-journal-count +.\" NS doc-macro-name +.\" NS doc-reference-count +.\" NS +.\" NS local variables: +.\" NS doc-env-%J +.\" NS +.\" NS width register '%J' set in doc-common +. +.eo +.de %J +. if (\n[doc-arg-count] : (\n[.$] == 0)) \{\ +. tm Usage: .%J journal_name ... (#\n[.c]) +. return +. \} +. +. nr doc-journal-count +1 +. nr doc-reference-count +1 +. +. ds doc-macro-name %J +. doc-parse-args \$@ +. +. nr doc-arg-ptr +1 +. nr doc-curr-font \n[.f] +. +. \" append to reference box +. boxa doc-journal-name +. ev doc-env-%J +. evc 0 +. in 0 +. nf +. nop \*[doc-Em-font]\c +. doc-do-references +.. +.ec +. +. +.\" NS doc-issue-count global register +.\" NS counter of issue number references +. +.nr doc-issue-count 0 +. +. +.\" NS doc-issue-name global box +.\" NS string of collected issue number references +. +.ds doc-issue-name +. +. +.\" NS %N user macro +.\" NS [reference] issue number +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-issue-count +.\" NS doc-macro-name +.\" NS doc-reference-count +.\" NS +.\" NS local variables: +.\" NS doc-env-%N +.\" NS +.\" NS width register '%N' set in doc-common +. +.eo +.de %N +. if (\n[doc-arg-count] : (\n[.$] == 0)) \{\ +. tm Usage: .%N issue_number ... (#\n[.c]) +. return +. \} +. +. nr doc-issue-count +1 +. nr doc-reference-count +1 +. +. ds doc-macro-name %N +. doc-parse-args \$@ +. +. nr doc-arg-ptr +1 +. nr doc-curr-font \n[.f] +. +. \" append to reference box +. boxa doc-issue-name +. ev doc-env-%N +. evc 0 +. in 0 +. nf +. doc-do-references +.. +.ec +. +. +.\" NS doc-optional-count global register +.\" NS counter of optional information references +. +.nr doc-optional-count 0 +. +. +.\" NS doc-optional-string global box +.\" NS string of collected optional information references +. +.ds doc-optional-string +. +. +.\" NS %O user macro +.\" NS [reference] optional information +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS doc-optional-count +.\" NS doc-reference-count +.\" NS +.\" NS local variables: +.\" NS doc-env-%O +.\" NS +.\" NS width register '%O' set in doc-common +. +.eo +.de %O +. if (\n[doc-arg-count] : (\n[.$] == 0)) \{\ +. tm Usage: .%O optional_information ... (#\n[.c]) +. return +. \} +. +. nr doc-optional-count +1 +. nr doc-reference-count +1 +. +. ds doc-macro-name %O +. doc-parse-args \$@ +. +. nr doc-arg-ptr +1 +. nr doc-curr-font \n[.f] +. +. \" append to reference box +. boxa doc-optional-string +. ev doc-env-%O +. evc 0 +. in 0 +. nf +. doc-do-references +.. +.ec +. +. +.\" NS doc-page-number-count global register +.\" NS counter of page number references +. +.nr doc-page-number-count 0 +. +. +.\" NS doc-page-number-string global box +.\" NS string of collected page number references +. +.ds doc-page-number-string +. +. +.\" NS %P user macro +.\" NS [reference] page numbers +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS doc-page-number-count +.\" NS doc-reference-count +.\" NS +.\" NS local variables: +.\" NS doc-env-%P +.\" NS +.\" NS width register '%P' set in doc-common +. +.eo +.de %P +. if (\n[doc-arg-count] : (\n[.$] == 0)) \{\ +. tm Usage: .%P page_number ... (#\n[.c]) +. return +. \} +. +. nr doc-page-number-count +1 +. nr doc-reference-count +1 +. +. ds doc-macro-name %P +. doc-parse-args \$@ +. +. nr doc-arg-ptr +1 +. nr doc-curr-font \n[.f] +. +. \" append to reference box +. boxa doc-page-number-string +. ev doc-env-%P +. evc 0 +. in 0 +. nf +. doc-do-references +.. +.ec +. +. +.\" NS doc-corporate-count global register +.\" NS counter of corporate references +. +.nr doc-corporate-count 0 +. +. +.\" NS doc-corporate-name global box +.\" NS string of collected corporate references +. +.ds doc-corporate-name +. +. +.\" NS %Q user macro +.\" NS corporate or foreign author +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-corporate-count +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS doc-reference-count +.\" NS +.\" NS local variables: +.\" NS doc-env-%Q +.\" NS +.\" NS width register '%Q' set in doc-common +. +.eo +.de %Q +. if (\n[doc-arg-count] : (\n[.$] == 0)) \{\ +. tm Usage: .%Q corporate_or_foreign_author ... (#\n[.c]) +. return +. \} +. +. nr doc-corporate-count +1 +. nr doc-reference-count +1 +. +. ds doc-macro-name %Q +. doc-parse-args \$@ +. +. nr doc-arg-ptr +1 +. nr doc-curr-font \n[.f] +. +. \" append to reference box +. boxa doc-corporate-name +. ev doc-env-%Q +. evc 0 +. in 0 +. nf +. doc-do-references +.. +.ec +. +. +.\" NS doc-report-count global register +.\" NS counter of report references +. +.nr doc-report-count 0 +. +. +.\" NS doc-report-name global box +.\" NS string of collected report references +. +.ds doc-report-name +. +. +.\" NS %R user macro +.\" NS [reference] report name +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS doc-reference-count +.\" NS doc-report-count +.\" NS +.\" NS local variables: +.\" NS doc-env-%R +.\" NS +.\" NS width register '%R' set in doc-common +. +.eo +.de %R +. if (\n[doc-arg-count] : (\n[.$] == 0)) \{\ +. tm Usage: .%R reference_report ... (#\n[.c]) +. return +. \} +. +. nr doc-report-count +1 +. nr doc-reference-count +1 +. +. ds doc-macro-name %R +. doc-parse-args \$@ +. +. nr doc-arg-ptr +1 +. nr doc-curr-font \n[.f] +. +. \" append to reference box +. boxa doc-report-name +. ev doc-env-%R +. evc 0 +. in 0 +. nf +. doc-do-references +.. +.ec +. +. +.\" NS doc-reference-title-count global register +.\" NS counter of reference title references +. +.nr doc-reference-title-count 0 +. +. +.\" NS doc-reference-title-name global box +.\" NS string of collected reference title references +. +.ds doc-reference-title-name +. +. +.\" NS doc-reference-title-name-for-book global box +.\" NS string of collected reference title references +.\" NS (saved with another font; this is a shortcoming of groff) +. +.ds doc-reference-title-name-for-book +. +. +.\" NS %T user macro +.\" NS reference title +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS doc-reference-title-count +.\" NS doc-report-count +.\" NS +.\" NS local variables: +.\" NS doc-env-%T +.\" NS +.\" NS width register '%T' set in doc-common +. +.eo +.de %T +. if (\n[doc-arg-count] : (\n[.$] == 0)) \{\ +. tm Usage: .%T reference_title ... (#\n[.c]) +. return +. \} +. +. if \n[doc-is-reference] \{\ +. nr doc-reference-title-count +1 +. nr doc-reference-count +1 +. \} +. +. ds doc-macro-name %T +. doc-parse-args \$@ +. +. nr doc-arg-ptr +1 +. nr doc-curr-font \n[.f] +. ie \n[doc-is-reference] \{\ +. \" append to reference box +. boxa doc-reference-title-name-for-book +. ev doc-env-%T +. evc 0 +. in 0 +. nf +. nop \*[doc-No-font]\c +. doc-do-references +. +. \" do it a second time with another font +. ds doc-macro-name %T +. doc-parse-args \$@ +. +. nr doc-arg-ptr +1 +. nr doc-curr-font \n[.f] +. boxa doc-reference-title-name +. ev doc-env-%T +. evc 0 +. in 0 +. nf +. nop \*[doc-Em-font]\c +. doc-do-references +. \} +. el \{\ +. nop \*[doc-Em-font]\c +. doc-print-recursive +. \} +.. +.ec +. +. +.\" NS doc-url-count global register +.\" NS counter of hypertext references +. +.nr doc-url-count 0 +. +. +.\" NS doc-url-name global box +.\" NS string of collected hypertext references +. +.ds doc-url-name +. +. +.\" NS doc-volume-count global register +.\" NS counter of reference title references +. +.nr doc-volume-count 0 +. +. +.\" NS doc-volume-name global box +.\" NS string of collected volume references +. +.ds doc-volume-name +. +. +.\" NS %U user macro +.\" NS hypertext reference +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS doc-reference-count +.\" NS doc-url-count +.\" NS +.\" NS local variables: +.\" NS doc-env-%U +.\" NS +.\" NS width register '%U' set in doc-common +. +.eo +.de %U +. if (\n[doc-arg-count] : (\n[.$] == 0)) \{\ +. tm Usage: .%U URL ... (#\n[.c]) +. return +. \} +. +. nr doc-url-count +1 +. nr doc-reference-count +1 +. +. ds doc-macro-name %U +. doc-parse-args \$@ +. +. nr doc-arg-ptr +1 +. nr doc-curr-font \n[.f] +. +. \" append to reference box +. boxa doc-url-name +. ev doc-env-%U +. evc 0 +. in 0 +. nf +. doc-do-references +.. +.ec +. +. +.\" NS %V user macro +.\" NS reference volume +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS doc-reference-count +.\" NS doc-volume-count +.\" NS +.\" NS local variables: +.\" NS doc-env-%V +.\" NS +.\" NS width register '%V' set in doc-common +. +.eo +.de %V +. if (\n[doc-arg-count] : (\n[.$] == 0)) \{\ +. tm Usage: .%V volume ... (#\n[.c]) +. return +. \} +. +. nr doc-volume-count +1 +. nr doc-reference-count +1 +. +. ds doc-macro-name %V +. doc-parse-args \$@ +. +. nr doc-arg-ptr +1 +. nr doc-curr-font \n[.f] +. +. \" append to reference box +. boxa doc-volume-name +. ev doc-env-%V +. evc 0 +. in 0 +. nf +. doc-do-references +.. +.ec +. +. +.\" NS doc-do-references macro +.\" NS reference recursion routine +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS +.\" NS local variables: +.\" NS doc-reg-ddr +.\" NS doc-reg-ddr1 +. +.eo +.de doc-do-references +. if !\n[doc-is-reference] \ +. tm mdoc error: .\*[doc-macro-name] found outside of .Rs ... .Re (#\n[.c]) +. +. nr doc-reg-ddr1 \n[doc-type\n[doc-arg-ptr]] +. +. ie (\n[doc-reg-ddr1] == 1) \{\ +. \" .nop \f[\n[doc-curr-font]]\c +. doc-append-arg \c 3 +. \*[doc-arg\n[doc-arg-ptr]] +. \} +. el \{\ +. nop \)\*[doc-arg\n[doc-arg-ptr]]\c +. +. ie (\n[doc-arg-count] == \n[doc-arg-ptr]) \{\ +. \" finish reference box +. br +. ev +. boxa +. +. doc-reset-args +. \} +. el \{\ +. nr doc-reg-ddr \n[doc-arg-ptr] +. nr doc-arg-ptr +1 +. nop \)\*[doc-space\n[doc-reg-ddr]]\c +. doc-do-references +. \}\} +.. +.ec +. +. +.\" NS Hf user macro +.\" NS source include header files. +.\" NS +.\" NS modifies: +.\" NS doc-curr-font +.\" NS +.\" NS width register 'Hf' set in doc-common +. +.eo +.de Hf +. ie ((\n[.$] == 1) & (\n[doc-arg-count] == 0)) \{\ +. doc-paragraph +. nop File: +. Pa \$1 +. +. Bd -literal +. so \$1 +. Ed +. +. doc-paragraph +. \} +. el \ +. Usage: .Hf file (#\n[.c]) +.. +.ec +. +. +.\" NS doc-have-author global register (bool) +.\" NS set in 'An' +. +.nr doc-have-author 0 +. +. +.\" NS An user macro +.\" NS author name +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-have-author +.\" NS doc-macro-name +.\" NS +.\" NS width register 'An' set in doc-common +. +.eo +.de An +. if !\n[doc-arg-count] \{\ +. ie \n[.$] \{\ +. ie "\$1"-nosplit" \ +. nr doc-in-authors-section 0 +. el \{ .ie "\$1"-split" \ +. nr doc-in-authors-section 1 +. el \{\ +. ds doc-macro-name An +. doc-parse-args \$@ +. \}\}\} +. el \{\ +. tm1 "Usage: .An {-nosplit | -split} +. tm1 " .An author_name ... (#\n[.c]) +. \}\} +. +. if \n[doc-in-authors-section] \{\ +. ie \n[doc-have-author] \ +. br +. el \ +. nr doc-have-author 1 +. \} +. +. if \n[doc-arg-count] \{\ +. nr doc-arg-ptr +1 +. ie (\n[doc-arg-count] >= \n[doc-arg-ptr]) \{\ +. nr doc-curr-font \n[.f] +. doc-print-recursive +. \} +. el \{\ +. tm Usage: .An author_name ... (#\n[.c]) +. doc-reset-args +. \}\} +.. +.ec +. +. +.\" NS Rv user macro +.\" NS return values +.\" NS +.\" NS width register 'Rv' set in doc-common +.\" NS +.\" NS local variables: +.\" NS doc-str-Rv-std-prefix +.\" NS doc-str-Rv-std-suffix +.\" NS doc-str-Rv-stds-prefix +.\" NS doc-str-Rv-stds-and +.\" NS doc-str-Rv-stds-suffix +.\" NS doc-str-Rv-std0 +. +.eo +.ds doc-str-Rv-std-prefix "The +.ds doc-str-Rv-std-suffix "function returns the value\~0 if successful; +.as doc-str-Rv-std-suffix " otherwise the value\~\-1 is returned and +.as doc-str-Rv-std-suffix " the global variable \*[doc-Va-font]errno\f[] +.as doc-str-Rv-std-suffix " is set to indicate the error. +. +.ds doc-str-Rv-stds-prefix "The +.ds doc-str-Rv-stds-and "and +.ds doc-str-Rv-stds-suffix "functions return the value\~0 if successful; +.as doc-str-Rv-stds-suffix " otherwise the value\~\-1 is returned and +.as doc-str-Rv-stds-suffix " the global variable \*[doc-Va-font]errno\f[] +.as doc-str-Rv-stds-suffix " is set to indicate the error. +. +.ds doc-str-Rv-std0 "Upon successful completion, the value\~0 is returned; +.as doc-str-Rv-std0 " otherwise the value\~\-1 is returned and +.as doc-str-Rv-std0 " the global variable \*[doc-Va-font]errno\f[] +.as doc-str-Rv-std0 " is set to indicate the error. +.ec +. +.eo +.de Rv +. +.\" XXX: what does this function without '-std'? +. +. if \n[doc-arg-count] \{\ +. tm Usage: .Rv not callable by other macros (#\n[.c]) +. doc-reset-args +. return +. \} +. +. if !\n[.$] \{\ +. tm Usage: .Rv [-std] [ ...] (#\n[.c]) +. return +. \} +. +. if "\$1"-std" \{\ +. nr doc-reg-Rv \*[doc-section] +. if ((\n[doc-reg-Rv] < 2) : (\n[doc-reg-Rv] > 3)) \ +. tm Usage: .Rv -std in sections 2 and 3 only (#\n[.c]) +. br +. shift +. ie (\n[.$] > 1) \{\ +. nop \)\*[doc-str-Rv-stds-prefix] +. nr doc-reg-Rv 1 +. while (\n[doc-reg-Rv] < \n[.$]) \{\ +. ie (\n[.$] > 2) \ +. Fn \$\n[doc-reg-Rv] , +. el \ +. Fn \$\n[doc-reg-Rv] +. nr doc-reg-Rv +1 +. \} +. nop \)\*[doc-str-Rv-stds-and] +. Fn \$\n[.$] +. nop \)\*[doc-str-Rv-stds-suffix] +. \} +. el \{ .ie (\n[.$] == 1) \{\ +. nop \)\*[doc-str-Rv-std-prefix] +. Fn \$1 +. nop \)\*[doc-str-Rv-std-suffix] +. \} +. el \{\ +. nop \)\*[doc-str-Rv-std0] +. \}\}\} +.. +.ec +. +. +.\" NS Ex user macro +.\" NS exit status +.\" NS +.\" NS width register 'Ex' set in doc-common +.\" NS +.\" NS local variables: +.\" NS doc-str-Ex-std-prefix +.\" NS doc-str-Ex-std-suffix +. +.ds doc-str-Ex-std-prefix "The +.ds doc-str-Ex-std-suffix "utility exits\~0 on success, +.as doc-str-Ex-std-suffix " and\~>0 if an error occurs. +. +.ds doc-str-Ex-stds-prefix "The +.als doc-str-Ex-stds-and doc-str-Rv-stds-and +.ds doc-str-Ex-stds-suffix "utilities exit\~0 on success, +.as doc-str-Ex-stds-suffix " and\~>0 if an error occurs. +. +.eo +.de Ex +. +.\" XXX: what does this function without '-std'? +. +. if \n[doc-arg-count] \{\ +. tm Usage: .Ex not callable by other macros (#\n[.c]) +. doc-reset-args +. return +. \} +. +. if !\n[.$] \{\ +. tm Usage: .Ex [-std] [ ...] (#\n[.c]) +. return +. \} +. +. if "\$1"-std" \{\ +. nr doc-reg-Ex \*[doc-section] +. if !((\n[doc-reg-Ex] == 1) : (\n[doc-reg-Ex] == 6) : (\n[doc-reg-Ex] == 8)) \ +. tm Usage: .Ex -std in sections 1, 6 and 8 only (#\n[.c]) +. br +. shift +. ie (\n[.$] > 1) \{\ +. nop \)\*[doc-str-Ex-stds-prefix] +. nr doc-reg-Ex 1 +. while (\n[doc-reg-Ex] < \n[.$]) \{\ +. ie (\n[.$] > 2) \ +. Nm \$\n[doc-reg-Ex] , +. el \ +. Nm \$\n[doc-reg-Ex] +. nr doc-reg-Ex +1 +. \} +. nop \)\*[doc-str-Ex-stds-and] +. Nm \$\n[.$] +. nop \)\*[doc-str-Ex-stds-suffix] +. \} +. el \{\ +. nop \)\*[doc-str-Ex-std-prefix] +. Nm \$1 +. nop \)\*[doc-str-Ex-std-suffix] +. \}\} +.. +.ec +. +. +.\" NS Mt user macro +.\" NS mailto (for conversion to HTML) +. +.eo +.de Mt +. \" XXX: error handling missing +. Pa \$@ +.. +.ec +. +. +.\" NS Lk user macro +.\" NS link (for conversion to HTML) +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS +.\" NS local variables: +.\" NS doc-lasttext-Lk +.\" NS doc-target-Lk +. +.eo +.de Lk +. if !\n[doc-arg-count] \{\ +. ds doc-macro-name Lk +. doc-parse-args \$@ +. \} +. +. if !\n[doc-arg-count] \ +. return +. +. \" The first argument is the target URI. +. nr doc-arg-ptr +1 +. ds doc-target-Lk "\*[doc-arg\n[doc-arg-ptr]] +. nr doc-arg-ptr +1 +. +. \" Search backwards for the first closing punctuation. +. nr doc-lasttext-Lk \n[doc-arg-count] +. while (\n[doc-lasttext-Lk] >= \n[doc-arg-ptr]) \{\ +. if !(\n[doc-type\n[doc-lasttext-Lk]] == 3) \ +. break +. nr doc-lasttext-Lk -1 +. \} +. +. \" Format the link text, if any. +. \" XXX: The forced use of the emphasis font and a trailing colon +. \" seems intrusive. +. nr doc-curr-font \n[.f] +. if (\n[doc-arg-ptr] <= \n[doc-lasttext-Lk]) \{\ +. nop \*[doc-Em-font]\c +. while (\n[doc-arg-ptr] < \n[doc-lasttext-Lk]) \{\ +. nop \&\*[doc-arg\n[doc-arg-ptr]] +. nr doc-arg-ptr +1 +. \} +. nop \&\*[doc-arg\n[doc-arg-ptr]]\c +. nop \f[\n[doc-curr-font]]: +. nr doc-arg-ptr +1 +. \} +. +. \" Format the link target. +. nop \*[doc-Lk-font]\*[doc-target-Lk]\c +. nop \f[\n[doc-curr-font]]\c +. +. \" Format trailing arguments, like punctuation, if any. +. ie (\n[doc-arg-ptr] <= \n[doc-arg-count]) \ +. doc-print-recursive +. el \{\ +. nop \& +. doc-reset-args +. \} +.. +.ec +. +. +.\" NS doc-defunct-macro macro +.\" NS this is the skeleton for defunct macros +.\" NS +. +.eo +.de doc-defunct-macro +. tmc mdoc error: .\$0 defunct +. if d doc-\$0-usage \ +. tmc , \*[doc-\$0-usage] +. tm1 " (#\n[.c]) +.. +.ec +. +. +.\" obsolete macros +. +.als Db doc-defunct-macro +. +.als Ds doc-defunct-macro +. +.als Or doc-defunct-macro +.ds doc-Or-usage use '|' +. +.als Sf doc-defunct-macro +.ds doc-Sf-usage use .Pf or .Ns +. +. +.rn em e@ +. +.eo +.de em +. tm1 "mdoc error: end-macro (.em) respecification is not allowed. (#\n[.c]) +. tm1 " Should this have been '.Em ...'? +. ab +.. +.ec +. +. +.\" NS doc-empty-line macro +.\" NS emit warning and print empty line +. +.eo +.de doc-empty-line +. if !\n[doc-display-depth] \ +. tm mdoc warning: Empty input line #\n[.c] +. sp +.. +.ec +. +.blm doc-empty-line +. +. +.ec +. +. +.\" For UTF-8, map the minus sign to the hyphen-minus to facilitate +.\" copy and paste of code examples, file names, and URLs embedding it. +.if '\*[.T]'utf8' \ +. char \- \N'45' +. +. +.\" load local modifications +.mso mdoc.local +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/dvi.tmac b/tmac/dvi.tmac new file mode 100644 index 0000000..5ce2c4c --- /dev/null +++ b/tmac/dvi.tmac @@ -0,0 +1,802 @@ +.\" dvi.tmac +.\" +.do nr *groff_dvi_tmac_C \n[.cp] +.cp 0 +. +.ftr CR CW +.ftr C CW +.ftr CO CWI +.ftr CI CWI +.ftr CB CW +.ftr CBI CWI +.ftr TT CW +.ftr H HR +. +.special TR TI MI S SA SB CW +.fspecial TI CWI +.fspecial TBI CWI +.fspecial HI CWI +.fspecial HBI CWI +.fspecial CW SC +.fspecial CWI SC +. +.\" This uses the dvi-char-_-1 string in fixed-width fonts, dvi-char-_-0 +.\" otherwise. +.fchar _ \R'dvi-char (\w'M' == \w'i')'\E*[dvi-char-_-\\n[dvi-char]] +.\" Normally use a rule. +.ds dvi-char-_-0 \Z'\v'.08m'\D'R .54m .04m''\h'.5m' +.\" In fixed-width fonts (CW and CWI) use a real _ character. +.ds dvi-char-_-1 _ +. +.fchar \[/l] \ +\R'dvi-char ((\w'M' == \w'i') + \ + (\En[.f] == \f[CWI]\En[.f]\f[]))'\E*[dvi-char-/l-\\n[dvi-char]] +.ds dvi-char-/l-0 \[slash@for@l]l +.ds dvi-char-/l-1 \Z'\v'0.22v'\h'-0.02m'\''l +.ds dvi-char-/l-2 \Z'\v'0.22v'\h'-0.13m'\''l +. +.fchar \[/L] \ +\R'dvi-char ((\w'M' == \w'i') + \ + (\En[.f] == \f[CWI]\En[.f]\f[]))'\E*[dvi-char-/L-\\n[dvi-char]] +.ds dvi-char-/L-0 \h'\w'L'u-\w'\[slash@for@l]L'u'\[slash@for@l]L +.ds dvi-char-/L-1 \Z'\v'0.22v'\h'-0.14m'\''L +.ds dvi-char-/L-2 \Z'\v'0.22v'\h'-0.21m'\''L +. +.\" This is designed so that \(ul, \(rn and \(br form corners. +.char \[br] \Z'\v'.25m'\D'R .04m -1m'' +.char \[ul] \Z'\v'.23m'\D'R .54m .04m''\h'.5m' +.char \[rn] \Z'\v'-.77m'\D'R .54m .04m''\h'.5m' +. +.char \[or] \h'.1m'\Z'\D'l 0 -.675m''\h'.1m' +.char \[ru] \Z'\v'-.02m'\D'R .54m .04m''\h'.5m' +. +.fchar \[sr] \v'-.75m'\[sqrt]\v'.75m' +.fchar \[sqrtex] \D'R .5m -.04m'\v'.04m' +.fchar \[radicalex] \v'-.75m'\D'R .5m -.04m'\v'.79m' +.fchar \[co] \ +\z\s-2\[ci]\s0\ +\h'\w'\s-2\[ci]\s0'u-\w'\s-4C\s0'u/2u'\ +\s-4C\s0\ +\h'\w'\s-2\[ci]\s0'u-\w'\s-4C\s0'u/2u' +.fchar \[rg] \ +\z\s-2\[ci]\s0\ +\h'\w'\s-2\[ci]\s0'u-\w'\s-4R\s0'u/2u'\ +\s-4R\s0\ +\h'\w'\s-2\[ci]\s0'u-\w'\s-4R\s0'u/2u' +.fchar \[fm] \v'-.35m'\s[\En[.s]*7u/10u]\[prime]\s0\v'.35m' +.fchar \[sd] \v'-.35m'\s[\En[.s]*7u/10u]\[prime]\[prime]\s0\v'.35m' +.fchar \[de] \h'.05m'\v'-.54m'\D'c .3m'\v'.54m'\h'.05m' +.fchar \[ct] \o'c/' +.fchar \[sq] \ +\Z'\h'.05m'\D'R .4m -.04m'\v'.04m'\h'-.04m'\ +\D'R .04m -.4m'\v'.04m'\D'R -.4m -.04m'\D'R .04m .4m''\h'.5m' +.\"char \[sq] \h'.05m'\D'l .4m 0'\D'l 0 -.4m'\D'l -.4m 0'\D'l 0 .4m'\h'.45m' +.\" SC contains a real \[!=] glyph +.schar \[!=] \[slashnot]\[eq] +.schar \[nm] \o'\F[T]\f[R]/\[mo]' +.fschar CW \[nm] \o'/\[mo]' +.fschar CWI \[nm] \o'\f[CW]/\[mo]' +.schar \[ne] \[slashnot]\[==] +.fschar CW \[ne] \o'/\[==]' +.fschar CWI \[ne] \o'\f[CW]/\[==]' +.fchar \[=~] \v'.1m'\Z'\[eq]'\v'-.4m'\[ap]\v'.3m' +.fchar \[tm] \v'-.3m'\s[\En[.s]/2u]TM\s0\v'.3m' +.\" TC fonts contain real \[aq] glyphs +.fschar TR \[aq] \f[TRTC]\[aq] +.fschar TI \[aq] \f[TITC]\[aq] +.fschar TB \[aq] \f[TBTC]\[aq] +.fschar TBI \[aq] \f[TBITC]\[aq] +.fschar HR \[aq] \f[HRTC]\[aq] +.fschar HI \[aq] \f[HITC]\[aq] +.fschar HB \[aq] \f[HBTC]\[aq] +.fschar HBI \[aq] \f[HBITC]\[aq] +.fschar CW \[aq] \f[CWTC]\[aq] +.fschar CWI \[aq] \f[CWITC]\[aq] +.fchar \[bq] , +.fchar \[Bq] ,\h'\w'\[rq]'u-(2u*\w"'"u)', +.fchar \[ho] \s[\En[.s]/2u]\v'.4m'c\v'-.4m'\s0 +.fchar \[-D] \Z'\v'-.1m'\h'.05m'-'D +.fchar \[Sd] \Z'\v'-.3m'\h'.35m'-'\[pd] +.fchar \[TP] \ +I\h'-.25m'\v'-.33m'\s[\En[.s]*6u/10u]\v'.33m'\ +D\v'-.33m'\s0\v'.33m' +.fchar \[Tp] \zlp +.fchar \[nb] \[slashnot]\[sb] +.fchar \[nc] \[slashnot]\[sp] +.cflags 8 \[an] +.schar \[an] \h'-.167m'\[mi]\h'-.167m' +.fschar CW \[an] - +.fschar CWI \[an] \f[CW]\[mi] +.\" we follow the EC ligatures for fixed-width dashes +.fchar \[em] -- +.fchar \[en] - +.fchar \[hy] - +.fschar CW \[va] \o'\[ua]\[da]' +.fschar CWI \[va] \o'\[ua]\[da]' +.fschar CW \[<>] \o'\[<-]\[->]' +.fschar CWI \[<>] \o'\[<-]\[->]' +.fchar \[lh] \[lA] +.fchar \[rh] \[rA] +. +.fchar \[f/] / +. +.\" Define some fractions. +.de dvi-frac +. fchar \[\\$1\\$2] \ +\v'-.25m'\s[\\En[.s]*7u/10u]\\$1\s0\v'.25m'\ +\h'-.2m'\[f/]\h'-.2m'\ +\v'.25m'\s[\\En[.s]*7u/10u]\\$2\s0\v'-.25m' +.. +. +.dvi-frac 1 2 +.dvi-frac 3 4 +.dvi-frac 1 4 +.dvi-frac 1 8 +.dvi-frac 3 8 +.dvi-frac 5 8 +.dvi-frac 7 8 +. +.\" support for ISO Latin-1 +.fchar \[S1] \v'-.2m'\s-31\s+3\v'+.2m' +.fchar \[S2] \v'-.2m'\s-32\s+3\v'+.2m' +.fchar \[S3] \v'-.2m'\s-33\s+3\v'+.2m' +.fchar \[Of] \v'-.2m'\s'\En[.s]*6u/10u'\o'_a'\s0\v'.2m' +.fchar \[Om] \v'-.2m'\s'\En[.s]*6u/10u'\o'_o'\s0\v'.2m' +.fchar \[fo] \v'-.1m'\s-3<\s+3\v'+.1m' +.fchar \[fc] \v'-.1m'\s-3>\s+3\v'+.1m' +.fchar \[Fo] \v'-.1m'\s-3<\h'-.3m'<\s+3\v'+.1m' +.fchar \[Fc] \v'-.1m'\s-3>\h'-.3m'>\s+3\v'+.1m' +.fchar \[bb] | +.fchar \[Cs] \o'\[mu]o' +. +.fchar \[IJ] IJ +.fchar \[ij] ij +. +.de dvi-achar +. \" Note that character definitions are always interpreted with +. \" compatibility mode off. +. fchar \\$1 \ +\\$3\ +\k[acc]\ +\h'(u;-\w'\\$2'-\w'\\$3'/2+\\En[skw]+(\w'x'*0)-\\En[skw])'\ +\v'(u;\w'x'*0+\\En[rst]+(\w'\\$3'*0)-\\En[rst])'\ +\\$2\ +\v'(u;\w'x'*0-\\En[rst]+(\w'\\$3'*0)+\\En[rst])'\ +\h'|\\En[acc]u' +. hcode \\$1\\$4 +.. +. +.dvi-achar \[`A] \` A a +.dvi-achar \['A] \' A a +.dvi-achar \[^A] ^ A a +.dvi-achar \[~A] ~ A a +.dvi-achar \[:A] \[ad] A a +.dvi-achar \[oA] \[ao] A a +.dvi-achar \['C] \' C c +.dvi-achar \[`E] \` E e +.dvi-achar \['E] \' E e +.dvi-achar \[^E] ^ E e +.dvi-achar \[:E] \[ad] E e +.dvi-achar "\[G ab]" \[ab] G g +.dvi-achar \[`I] \` I i +.dvi-achar \['I] \' I i +.dvi-achar \[^I] ^ I i +.dvi-achar \[:I] \[ad] I i +.dvi-achar "\[I .]" \[a.] I i +.dvi-achar \[~N] ~ N n +.dvi-achar \[`O] \` O o +.dvi-achar \['O] \' O o +.dvi-achar \[^O] ^ O o +.dvi-achar \[~O] ~ O o +.dvi-achar \[:O] \[ad] O o +.dvi-achar \[`U] \` U u +.dvi-achar \['U] \' U u +.dvi-achar \[^U] ^ U u +.dvi-achar \[:U] \[ad] U u +.dvi-achar \['Y] \' Y y +.dvi-achar \[:Y] \[ad] Y y +.dvi-achar \[`a] \` a a +.dvi-achar \['a] \' a a +.dvi-achar \[^a] ^ a a +.dvi-achar \[~a] ~ a a +.dvi-achar \[:a] \[ad] a a +.dvi-achar \[oa] \[ao] a a +.dvi-achar \['c] \' c c +.dvi-achar \[`e] \` e e +.dvi-achar \['e] \' e e +.dvi-achar \[^e] ^ e e +.dvi-achar \[:e] \[ad] e e +.dvi-achar "\[g ab]" \[ab] g g +.dvi-achar \[`i] \` \[.i] i +.dvi-achar \['i] \' \[.i] i +.dvi-achar \[^i] ^ \[.i] i +.dvi-achar \[:i] \[ad] \[.i] i +.dvi-achar \[~n] ~ n n +.dvi-achar \[`o] \` o o +.dvi-achar \['o] \' o o +.dvi-achar \[^o] ^ o o +.dvi-achar \[~o] ~ o o +.dvi-achar \[:o] \[ad] o o +.dvi-achar \[`u] \` u u +.dvi-achar \['u] \' u u +.dvi-achar \[^u] ^ u u +.dvi-achar \[:u] \[ad] u u +.dvi-achar \['y] \' y y +.dvi-achar \[:y] \[ad] y y +.dvi-achar \[vs] \[ah] s s +.dvi-achar \[vS] \[ah] S s +.dvi-achar \[vz] \[ah] z z +.dvi-achar \[vZ] \[ah] Z z +. +.fchar \[,C] \o'\[ac]C' +.hcode \[,C]c +.fchar \[,c] \o'\[ac]c' +.hcode \[,c]c +.fchar \[S ,] \o'S\[ac]' +.hcode \[S ,]s +.fchar \[s ,] \o's\[ac]' +.hcode \[s ,]s +. +.\" now for color definitions +.\" +.\" this is a composite of MIT's X Consortium red/green/blue (rgb) color +.\" specifications, X Consortium version 10.41, 1994. +.\" +.defcolor black rgb #000000 +.defcolor grey rgb #bebebe +.defcolor dimgrey rgb #696969 +.defcolor lightgray rgb #d3d3d3 +.defcolor lightslategrey rgb #778899 +.defcolor slategray rgb #708090 +.defcolor slategray1 rgb #c6e2ff +.defcolor slategray2 rgb #b9d3ee +.defcolor slategray3 rgb #9fb6cd +.defcolor slategray4 rgb #6c7b8b +.defcolor slategrey rgb #708090 +.defcolor grey0 rgb #000000 +.defcolor grey1 rgb #030303 +.defcolor grey2 rgb #050505 +.defcolor grey3 rgb #080808 +.defcolor grey4 rgb #0a0a0a +.defcolor grey5 rgb #0d0d0d +.defcolor grey6 rgb #0f0f0f +.defcolor grey7 rgb #121212 +.defcolor grey8 rgb #141414 +.defcolor grey9 rgb #171717 +.defcolor grey10 rgb #1a1a1a +.defcolor grey11 rgb #1c1c1c +.defcolor grey12 rgb #1f1f1f +.defcolor grey13 rgb #212121 +.defcolor grey14 rgb #242424 +.defcolor grey15 rgb #262626 +.defcolor grey16 rgb #292929 +.defcolor grey17 rgb #2b2b2b +.defcolor grey18 rgb #2e2e2e +.defcolor grey19 rgb #303030 +.defcolor grey20 rgb #333333 +.defcolor grey21 rgb #363636 +.defcolor grey22 rgb #383838 +.defcolor grey23 rgb #3b3b3b +.defcolor grey24 rgb #3d3d3d +.defcolor grey25 rgb #404040 +.defcolor grey26 rgb #424242 +.defcolor grey27 rgb #454545 +.defcolor grey28 rgb #474747 +.defcolor grey29 rgb #4a4a4a +.defcolor grey30 rgb #4d4d4d +.defcolor grey31 rgb #4f4f4f +.defcolor grey32 rgb #525252 +.defcolor grey33 rgb #545454 +.defcolor grey34 rgb #575757 +.defcolor grey35 rgb #595959 +.defcolor grey36 rgb #5c5c5c +.defcolor grey37 rgb #5e5e5e +.defcolor grey38 rgb #616161 +.defcolor grey39 rgb #636363 +.defcolor grey40 rgb #666666 +.defcolor grey41 rgb #696969 +.defcolor grey42 rgb #6b6b6b +.defcolor grey43 rgb #6e6e6e +.defcolor grey44 rgb #707070 +.defcolor grey45 rgb #737373 +.defcolor grey46 rgb #757575 +.defcolor grey47 rgb #787878 +.defcolor grey48 rgb #7a7a7a +.defcolor grey49 rgb #7d7d7d +.defcolor grey50 rgb #7f7f7f +.defcolor grey51 rgb #828282 +.defcolor grey52 rgb #858585 +.defcolor grey53 rgb #878787 +.defcolor grey54 rgb #8a8a8a +.defcolor grey55 rgb #8c8c8c +.defcolor grey56 rgb #8f8f8f +.defcolor grey57 rgb #919191 +.defcolor grey58 rgb #949494 +.defcolor grey59 rgb #969696 +.defcolor grey60 rgb #999999 +.defcolor grey61 rgb #9c9c9c +.defcolor grey62 rgb #9e9e9e +.defcolor grey63 rgb #a1a1a1 +.defcolor grey64 rgb #a3a3a3 +.defcolor grey65 rgb #a6a6a6 +.defcolor grey66 rgb #a8a8a8 +.defcolor grey67 rgb #ababab +.defcolor grey68 rgb #adadad +.defcolor grey69 rgb #b0b0b0 +.defcolor grey70 rgb #b3b3b3 +.defcolor grey71 rgb #b5b5b5 +.defcolor grey72 rgb #b8b8b8 +.defcolor grey73 rgb #bababa +.defcolor grey74 rgb #bdbdbd +.defcolor grey75 rgb #bfbfbf +.defcolor grey76 rgb #c2c2c2 +.defcolor grey77 rgb #c4c4c4 +.defcolor grey78 rgb #c7c7c7 +.defcolor grey79 rgb #c9c9c9 +.defcolor grey80 rgb #cccccc +.defcolor grey81 rgb #cfcfcf +.defcolor grey82 rgb #d1d1d1 +.defcolor grey83 rgb #d4d4d4 +.defcolor grey84 rgb #d6d6d6 +.defcolor grey85 rgb #d9d9d9 +.defcolor grey86 rgb #dbdbdb +.defcolor grey87 rgb #dedede +.defcolor grey88 rgb #e0e0e0 +.defcolor grey89 rgb #e3e3e3 +.defcolor grey90 rgb #e5e5e5 +.defcolor grey91 rgb #e8e8e8 +.defcolor grey92 rgb #ebebeb +.defcolor grey93 rgb #ededed +.defcolor grey94 rgb #f0f0f0 +.defcolor grey95 rgb #f2f2f2 +.defcolor grey96 rgb #f5f5f5 +.defcolor grey97 rgb #f7f7f7 +.defcolor grey98 rgb #fafafa +.defcolor grey99 rgb #fcfcfc +.defcolor grey100 rgb #ffffff +.defcolor aliceblue rgb #f0f8ff +.defcolor blueviolet rgb #8a2be2 +.defcolor cadetblue rgb #5f9ea0 +.defcolor cadetblue1 rgb #98f5ff +.defcolor cadetblue2 rgb #8ee5ee +.defcolor cadetblue3 rgb #7ac5cd +.defcolor cadetblue4 rgb #53868b +.defcolor cornflowerblue rgb #6495ed +.defcolor darkslateblue rgb #483d8b +.defcolor darkturquoise rgb #00ced1 +.defcolor deepskyblue rgb #00bfff +.defcolor deepskyblue1 rgb #00bfff +.defcolor deepskyblue2 rgb #00b2ee +.defcolor deepskyblue3 rgb #009acd +.defcolor deepskyblue4 rgb #00688b +.defcolor dodgerblue rgb #1e90ff +.defcolor dodgerblue1 rgb #1e90ff +.defcolor dodgerblue2 rgb #1c86ee +.defcolor dodgerblue3 rgb #1874cd +.defcolor dodgerblue4 rgb #104e8b +.defcolor lightblue rgb #add8e6 +.defcolor lightblue1 rgb #bfefff +.defcolor lightblue2 rgb #b2dfee +.defcolor lightblue3 rgb #9ac0cd +.defcolor lightblue4 rgb #68838b +.defcolor lightcyan rgb #e0ffff +.defcolor lightcyan1 rgb #e0ffff +.defcolor lightcyan2 rgb #d1eeee +.defcolor lightcyan3 rgb #b4cdcd +.defcolor lightcyan4 rgb #7a8b8b +.defcolor lightskyblue rgb #87cefa +.defcolor lightskyblue1 rgb #b0e2ff +.defcolor lightskyblue2 rgb #a4d3ee +.defcolor lightskyblue3 rgb #8db6cd +.defcolor lightskyblue4 rgb #607b8b +.defcolor lightslateblue rgb #8470ff +.defcolor lightsteelblue rgb #b0c4de +.defcolor lightsteelblue1 rgb #cae1ff +.defcolor lightsteelblue2 rgb #bcd2ee +.defcolor lightsteelblue3 rgb #a2b5cd +.defcolor lightsteelblue4 rgb #6e7b8b +.defcolor mediumaquamarine rgb #66cdaa +.defcolor mediumblue rgb #0000cd +.defcolor mediumslateblue rgb #7b68ee +.defcolor mediumturquoise rgb #48d1cc +.defcolor midnightblue rgb #191970 +.defcolor navyblue rgb #000080 +.defcolor paleturquoise rgb #afeeee +.defcolor paleturquoise1 rgb #bbffff +.defcolor paleturquoise2 rgb #aeeeee +.defcolor paleturquoise3 rgb #96cdcd +.defcolor paleturquoise4 rgb #668b8b +.defcolor powderblue rgb #b0e0e6 +.defcolor royalblue rgb #4169e1 +.defcolor royalblue1 rgb #4876ff +.defcolor royalblue2 rgb #436eee +.defcolor royalblue3 rgb #3a5fcd +.defcolor royalblue4 rgb #27408b +.defcolor skyblue rgb #87ceeb +.defcolor skyblue1 rgb #87ceff +.defcolor skyblue2 rgb #7ec0ee +.defcolor skyblue3 rgb #6ca6cd +.defcolor skyblue4 rgb #4a708b +.defcolor slateblue rgb #6a5acd +.defcolor slateblue1 rgb #836fff +.defcolor slateblue2 rgb #7a67ee +.defcolor slateblue3 rgb #6959cd +.defcolor slateblue4 rgb #473c8b +.defcolor steelblue rgb #4682b4 +.defcolor steelblue1 rgb #63b8ff +.defcolor steelblue2 rgb #5cacee +.defcolor steelblue3 rgb #4f94cd +.defcolor steelblue4 rgb #36648b +.defcolor aquamarine rgb #7fffd4 +.defcolor aquamarine1 rgb #7fffd4 +.defcolor aquamarine2 rgb #76eec6 +.defcolor aquamarine3 rgb #66cdaa +.defcolor aquamarine4 rgb #458b74 +.defcolor azure rgb #f0ffff +.defcolor azure1 rgb #f0ffff +.defcolor azure2 rgb #e0eeee +.defcolor azure3 rgb #c1cdcd +.defcolor azure4 rgb #838b8b +.defcolor blue rgb #0000ff +.defcolor blue1 rgb #0000ff +.defcolor blue2 rgb #0000ee +.defcolor blue3 rgb #0000cd +.defcolor blue4 rgb #00008b +.defcolor cyan rgb #00ffff +.defcolor cyan1 rgb #00ffff +.defcolor cyan2 rgb #00eeee +.defcolor cyan3 rgb #00cdcd +.defcolor cyan4 rgb #008b8b +.defcolor navy rgb #000080 +.defcolor turquoise rgb #40e0d0 +.defcolor turquoise1 rgb #00f5ff +.defcolor turquoise2 rgb #00e5ee +.defcolor turquoise3 rgb #00c5cd +.defcolor turquoise4 rgb #00868b +.defcolor darkslategray rgb #2f4f4f +.defcolor darkslategray1 rgb #97ffff +.defcolor darkslategray2 rgb #8deeee +.defcolor darkslategray3 rgb #79cdcd +.defcolor darkslategray4 rgb #528b8b +.defcolor rosybrown rgb #bc8f8f +.defcolor rosybrown1 rgb #ffc1c1 +.defcolor rosybrown2 rgb #eeb4b4 +.defcolor rosybrown3 rgb #cd9b9b +.defcolor rosybrown4 rgb #8b6969 +.defcolor saddlebrown rgb #8b4513 +.defcolor sandybrown rgb #f4a460 +.defcolor beige rgb #f5f5dc +.defcolor brown rgb #a52a2a +.defcolor brown1 rgb #ff4040 +.defcolor brown2 rgb #ee3b3b +.defcolor brown3 rgb #cd3333 +.defcolor brown4 rgb #8b2323 +.defcolor burlywood rgb #deb887 +.defcolor burlywood1 rgb #ffd39b +.defcolor burlywood2 rgb #eec591 +.defcolor burlywood3 rgb #cdaa7d +.defcolor burlywood4 rgb #8b7355 +.defcolor chocolate rgb #d2691e +.defcolor chocolate1 rgb #ff7f24 +.defcolor chocolate2 rgb #ee7621 +.defcolor chocolate3 rgb #cd661d +.defcolor chocolate4 rgb #8b4513 +.defcolor peru rgb #cd853f +.defcolor tan rgb #d2b48c +.defcolor tan1 rgb #ffa54f +.defcolor tan2 rgb #ee9a49 +.defcolor tan3 rgb #cd853f +.defcolor tan4 rgb #8b5a2b +.defcolor darkgreen rgb #006400 +.defcolor darkkhaki rgb #bdb76b +.defcolor darkolivegreen rgb #556b2f +.defcolor darkolivegreen1 rgb #caff70 +.defcolor darkolivegreen2 rgb #bcee68 +.defcolor darkolivegreen3 rgb #a2cd5a +.defcolor darkolivegreen4 rgb #6e8b3d +.defcolor darkseagreen rgb #8fbc8f +.defcolor darkseagreen1 rgb #c1ffc1 +.defcolor darkseagreen2 rgb #b4eeb4 +.defcolor darkseagreen3 rgb #9bcd9b +.defcolor darkseagreen4 rgb #698b69 +.defcolor forestgreen rgb #228b22 +.defcolor greenyellow rgb #adff2f +.defcolor lawngreen rgb #7cfc00 +.defcolor lightseagreen rgb #20b2aa +.defcolor limegreen rgb #32cd32 +.defcolor mediumseagreen rgb #3cb371 +.defcolor mediumspringgreen rgb #00fa9a +.defcolor mintcream rgb #f5fffa +.defcolor olivedrab rgb #6b8e23 +.defcolor olivedrab1 rgb #c0ff3e +.defcolor olivedrab2 rgb #b3ee3a +.defcolor olivedrab3 rgb #9acd32 +.defcolor olivedrab4 rgb #698b22 +.defcolor palegreen rgb #98fb98 +.defcolor palegreen1 rgb #9aff9a +.defcolor palegreen2 rgb #90ee90 +.defcolor palegreen3 rgb #7ccd7c +.defcolor palegreen4 rgb #548b54 +.defcolor seagreen rgb #2e8b57 +.defcolor seagreen1 rgb #54ff9f +.defcolor seagreen2 rgb #4eee94 +.defcolor seagreen3 rgb #43cd80 +.defcolor seagreen4 rgb #2e8b57 +.defcolor springgreen rgb #00ff7f +.defcolor springgreen1 rgb #00ff7f +.defcolor springgreen2 rgb #00ee76 +.defcolor springgreen3 rgb #00cd66 +.defcolor springgreen4 rgb #008b45 +.defcolor yellowgreen rgb #9acd32 +.defcolor chartreuse rgb #7fff00 +.defcolor chartreuse1 rgb #7fff00 +.defcolor chartreuse2 rgb #76ee00 +.defcolor chartreuse3 rgb #66cd00 +.defcolor chartreuse4 rgb #458b00 +.defcolor green rgb #00ff00 +.defcolor green1 rgb #00ff00 +.defcolor green2 rgb #00ee00 +.defcolor green3 rgb #00cd00 +.defcolor green4 rgb #008b00 +.defcolor khaki rgb #f0e68c +.defcolor khaki1 rgb #fff68f +.defcolor khaki2 rgb #eee685 +.defcolor khaki3 rgb #cdc673 +.defcolor khaki4 rgb #8b864e +.defcolor darkorange rgb #ff8c00 +.defcolor darkorange1 rgb #ff7f00 +.defcolor darkorange2 rgb #ee7600 +.defcolor darkorange3 rgb #cd6600 +.defcolor darkorange4 rgb #8b4500 +.defcolor darksalmon rgb #e9967a +.defcolor lightcoral rgb #f08080 +.defcolor lightsalmon rgb #ffa07a +.defcolor lightsalmon1 rgb #ffa07a +.defcolor lightsalmon2 rgb #ee9572 +.defcolor lightsalmon3 rgb #cd8162 +.defcolor lightsalmon4 rgb #8b5742 +.defcolor peachpuff rgb #ffdab9 +.defcolor peachpuff1 rgb #ffdab9 +.defcolor peachpuff2 rgb #eecbad +.defcolor peachpuff3 rgb #cdaf95 +.defcolor peachpuff4 rgb #8b7765 +.defcolor bisque rgb #ffe4c4 +.defcolor bisque1 rgb #ffe4c4 +.defcolor bisque2 rgb #eed5b7 +.defcolor bisque3 rgb #cdb79e +.defcolor bisque4 rgb #8b7d6b +.defcolor coral rgb #ff7f50 +.defcolor coral1 rgb #ff7256 +.defcolor coral2 rgb #ee6a50 +.defcolor coral3 rgb #cd5b45 +.defcolor coral4 rgb #8b3e2f +.defcolor honeydew rgb #f0fff0 +.defcolor honeydew1 rgb #f0fff0 +.defcolor honeydew2 rgb #e0eee0 +.defcolor honeydew3 rgb #c1cdc1 +.defcolor honeydew4 rgb #838b83 +.defcolor orange rgb #ffa500 +.defcolor orange1 rgb #ffa500 +.defcolor orange2 rgb #ee9a00 +.defcolor orange3 rgb #cd8500 +.defcolor orange4 rgb #8b5a00 +.defcolor salmon rgb #fa8072 +.defcolor salmon1 rgb #ff8c69 +.defcolor salmon2 rgb #ee8262 +.defcolor salmon3 rgb #cd7054 +.defcolor salmon4 rgb #8b4c39 +.defcolor sienna rgb #a0522d +.defcolor sienna1 rgb #ff8247 +.defcolor sienna2 rgb #ee7942 +.defcolor sienna3 rgb #cd6839 +.defcolor sienna4 rgb #8b4726 +.defcolor deeppink rgb #ff1493 +.defcolor deeppink1 rgb #ff1493 +.defcolor deeppink2 rgb #ee1289 +.defcolor deeppink3 rgb #cd1076 +.defcolor deeppink4 rgb #8b0a50 +.defcolor hotpink rgb #ff69b4 +.defcolor hotpink1 rgb #ff6eb4 +.defcolor hotpink2 rgb #ee6aa7 +.defcolor hotpink3 rgb #cd6090 +.defcolor hotpink4 rgb #8b3a62 +.defcolor indianred rgb #cd5c5c +.defcolor indianred1 rgb #ff6a6a +.defcolor indianred2 rgb #ee6363 +.defcolor indianred3 rgb #cd5555 +.defcolor indianred4 rgb #8b3a3a +.defcolor lightpink rgb #ffb6c1 +.defcolor lightpink1 rgb #ffaeb9 +.defcolor lightpink2 rgb #eea2ad +.defcolor lightpink3 rgb #cd8c95 +.defcolor lightpink4 rgb #8b5f65 +.defcolor mediumvioletred rgb #c71585 +.defcolor mistyrose rgb #ffe4e1 +.defcolor mistyrose1 rgb #ffe4e1 +.defcolor mistyrose2 rgb #eed5d2 +.defcolor mistyrose3 rgb #cdb7b5 +.defcolor mistyrose4 rgb #8b7d7b +.defcolor orangered rgb #ff4500 +.defcolor orangered1 rgb #ff4500 +.defcolor orangered2 rgb #ee4000 +.defcolor orangered3 rgb #cd3700 +.defcolor orangered4 rgb #8b2500 +.defcolor palevioletred rgb #db7093 +.defcolor palevioletred1 rgb #ff82ab +.defcolor palevioletred2 rgb #ee799f +.defcolor palevioletred3 rgb #cd6889 +.defcolor palevioletred4 rgb #8b475d +.defcolor violetred rgb #d02090 +.defcolor violetred1 rgb #ff3e96 +.defcolor violetred2 rgb #ee3a8c +.defcolor violetred3 rgb #cd3278 +.defcolor violetred4 rgb #8b2252 +.defcolor firebrick rgb #b22222 +.defcolor firebrick1 rgb #ff3030 +.defcolor firebrick2 rgb #ee2c2c +.defcolor firebrick3 rgb #cd2626 +.defcolor firebrick4 rgb #8b1a1a +.defcolor pink rgb #ffc0cb +.defcolor pink1 rgb #ffb5c5 +.defcolor pink2 rgb #eea9b8 +.defcolor pink3 rgb #cd919e +.defcolor pink4 rgb #8b636c +.defcolor red rgb #ff0000 +.defcolor red1 rgb #ff0000 +.defcolor red2 rgb #ee0000 +.defcolor red3 rgb #cd0000 +.defcolor red4 rgb #8b0000 +.defcolor tomato rgb #ff6347 +.defcolor tomato1 rgb #ff6347 +.defcolor tomato2 rgb #ee5c42 +.defcolor tomato3 rgb #cd4f39 +.defcolor tomato4 rgb #8b3626 +.defcolor darkorchid rgb #9932cc +.defcolor darkorchid1 rgb #bf3eff +.defcolor darkorchid2 rgb #b23aee +.defcolor darkorchid3 rgb #9a32cd +.defcolor darkorchid4 rgb #68228b +.defcolor darkviolet rgb #9400d3 +.defcolor lavenderblush rgb #fff0f5 +.defcolor lavenderblush1 rgb #fff0f5 +.defcolor lavenderblush2 rgb #eee0e5 +.defcolor lavenderblush3 rgb #cdc1c5 +.defcolor lavenderblush4 rgb #8b8386 +.defcolor mediumorchid rgb #ba55d3 +.defcolor mediumorchid1 rgb #e066ff +.defcolor mediumorchid2 rgb #d15fee +.defcolor mediumorchid3 rgb #b452cd +.defcolor mediumorchid4 rgb #7a378b +.defcolor mediumpurple rgb #9370db +.defcolor mediumpurple1 rgb #ab82ff +.defcolor mediumpurple2 rgb #9f79ee +.defcolor mediumpurple3 rgb #8968cd +.defcolor mediumpurple4 rgb #5d478b +.defcolor lavender rgb #e6e6fa +.defcolor magenta rgb #ff00ff +.defcolor magenta1 rgb #ff00ff +.defcolor magenta2 rgb #ee00ee +.defcolor magenta3 rgb #cd00cd +.defcolor magenta4 rgb #8b008b +.defcolor maroon rgb #b03060 +.defcolor maroon1 rgb #ff34b3 +.defcolor maroon2 rgb #ee30a7 +.defcolor maroon3 rgb #cd2990 +.defcolor maroon4 rgb #8b1c62 +.defcolor orchid rgb #da70d6 +.defcolor orchid1 rgb #ff83fa +.defcolor orchid2 rgb #ee7ae9 +.defcolor orchid3 rgb #cd69c9 +.defcolor orchid4 rgb #8b4789 +.defcolor plum rgb #dda0dd +.defcolor plum1 rgb #ffbbff +.defcolor plum2 rgb #eeaeee +.defcolor plum3 rgb #cd96cd +.defcolor plum4 rgb #8b668b +.defcolor purple rgb #a020f0 +.defcolor purple1 rgb #9b30ff +.defcolor purple2 rgb #912cee +.defcolor purple3 rgb #7d26cd +.defcolor purple4 rgb #551a8b +.defcolor thistle rgb #d8bfd8 +.defcolor thistle1 rgb #ffe1ff +.defcolor thistle2 rgb #eed2ee +.defcolor thistle3 rgb #cdb5cd +.defcolor thistle4 rgb #8b7b8b +.defcolor violet rgb #ee82ee +.defcolor antiquewhite rgb #faebd7 +.defcolor antiquewhite1 rgb #ffefdb +.defcolor antiquewhite2 rgb #eedfcc +.defcolor antiquewhite3 rgb #cdc0b0 +.defcolor antiquewhite4 rgb #8b8378 +.defcolor floralwhite rgb #fffaf0 +.defcolor ghostwhite rgb #f8f8ff +.defcolor navajowhite rgb #ffdead +.defcolor navajowhite1 rgb #ffdead +.defcolor navajowhite2 rgb #eecfa1 +.defcolor navajowhite3 rgb #cdb38b +.defcolor navajowhite4 rgb #8b795e +.defcolor oldlace rgb #fdf5e6 +.defcolor whitesmoke rgb #f5f5f5 +.defcolor gainsboro rgb #dcdcdc +.defcolor ivory rgb #fffff0 +.defcolor ivory1 rgb #fffff0 +.defcolor ivory2 rgb #eeeee0 +.defcolor ivory3 rgb #cdcdc1 +.defcolor ivory4 rgb #8b8b83 +.defcolor linen rgb #faf0e6 +.defcolor seashell rgb #fff5ee +.defcolor seashell1 rgb #fff5ee +.defcolor seashell2 rgb #eee5de +.defcolor seashell3 rgb #cdc5bf +.defcolor seashell4 rgb #8b8682 +.defcolor snow rgb #fffafa +.defcolor snow1 rgb #fffafa +.defcolor snow2 rgb #eee9e9 +.defcolor snow3 rgb #cdc9c9 +.defcolor snow4 rgb #8b8989 +.defcolor wheat rgb #f5deb3 +.defcolor wheat1 rgb #ffe7ba +.defcolor wheat2 rgb #eed8ae +.defcolor wheat3 rgb #cdba96 +.defcolor wheat4 rgb #8b7e66 +.defcolor white rgb #ffffff +.defcolor blanchedalmond rgb #ffebcd +.defcolor darkgoldenrod rgb #b8860b +.defcolor darkgoldenrod1 rgb #ffb90f +.defcolor darkgoldenrod2 rgb #eead0e +.defcolor darkgoldenrod3 rgb #cd950c +.defcolor darkgoldenrod4 rgb #8b6508 +.defcolor lemonchiffon rgb #fffacd +.defcolor lemonchiffon1 rgb #fffacd +.defcolor lemonchiffon2 rgb #eee9bf +.defcolor lemonchiffon3 rgb #cdc9a5 +.defcolor lemonchiffon4 rgb #8b8970 +.defcolor lightgoldenrod rgb #eedd82 +.defcolor lightgoldenrod1 rgb #ffec8b +.defcolor lightgoldenrod2 rgb #eedc82 +.defcolor lightgoldenrod3 rgb #cdbe70 +.defcolor lightgoldenrod4 rgb #8b814c +.defcolor lightgoldenrodyellow rgb #fafad2 +.defcolor lightyellow rgb #ffffe0 +.defcolor lightyellow1 rgb #ffffe0 +.defcolor lightyellow2 rgb #eeeed1 +.defcolor lightyellow3 rgb #cdcdb4 +.defcolor lightyellow4 rgb #8b8b7a +.defcolor palegoldenrod rgb #eee8aa +.defcolor papayawhip rgb #ffefd5 +.defcolor cornsilk rgb #fff8dc +.defcolor cornsilk1 rgb #fff8dc +.defcolor cornsilk2 rgb #eee8cd +.defcolor cornsilk3 rgb #cdc8b1 +.defcolor cornsilk4 rgb #8b8878 +.defcolor gold rgb #ffd700 +.defcolor gold1 rgb #ffd700 +.defcolor gold2 rgb #eec900 +.defcolor gold3 rgb #cdad00 +.defcolor gold4 rgb #8b7500 +.defcolor goldenrod rgb #daa520 +.defcolor goldenrod1 rgb #ffc125 +.defcolor goldenrod2 rgb #eeb422 +.defcolor goldenrod3 rgb #cd9b1d +.defcolor goldenrod4 rgb #8b6914 +.defcolor moccasin rgb #ffe4b5 +.defcolor yellow rgb #ffff00 +.defcolor yellow1 rgb #ffff00 +.defcolor yellow2 rgb #eeee00 +.defcolor yellow3 rgb #cdcd00 +.defcolor yellow4 rgb #8b8b00 +. +.ie '\[char97]'a' \ +. mso latin1.tmac +.el \ +. mso cp1047.tmac +. +.cp \n[*groff_dvi_tmac_C] +.do rr *groff_dvi_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/e.tmac b/tmac/e.tmac new file mode 100644 index 0000000..b30a614 --- /dev/null +++ b/tmac/e.tmac @@ -0,0 +1,2255 @@ +.\" Copyright (c) 1988, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" 3. [Deleted. See +.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] +.\" 4. Neither the name of the University nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" +.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +.\" PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR +.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)e.tmac 8.1 (Berkeley) 06/05/93 +.\" +.\" Modified by James Clark for use with groff. +.\" Further modifications by Werner Lemberg, George Helffrich, and +.\" G. Branden Robinson. +.\" +.\"************************************************************** +.\"* * +.\"* **** - M E N R O F F / T R O F F M A C R O S **** * +.\"* * +.\"* Produced for your edification and enjoyment by: * +.\"* Eric Allman * +.\"* Electronics Research Laboratory * +.\"* U.C. Berkeley. * +.\"* * +.\"* VERSION 8.1 First Release: 11 Sept 1978 * +.\"* * +.\"* Documentation is available. * +.\"* * +.\"************************************************************** +.\" +.\" Macro definitions are annotated with a code: +.\" *** user interface macro +.\" $$$ macro which may be redefined by the user +.\" to provide variant functions +.\" --- internal macro; not to be called by user +.\" +. +.do nr devtag-needs-end-of-heading 0 +.do nr devtag-needs-end-of-title 0 +.do nr devtag-needs-title 1 +. +.do mso devtag.tmac +. +.if !\n(.g .ig +.de @R \" --- initialize number register to 0, if undefined +.do if !r\\$1 .nr \\$1 0 +.. +. +.ds _e e.tmac\" name of macro package, for diagnostic messages +. +.\" emit error diagnostic +.do de1 @err +.ds @file \" empty +.ds @line \" empty +.if !'\\n[.F]'' .ds @file \\n[.F]:\" +.if !'\\n[.c]'0' .ds @line \\n[.c]:\" +.tm \\*(_e:\\*[@file]\\*[@line] \\$* +.rm @file +.rm @line +.. +. +.\" --- check whether grohtml needs end of title/heading +.do de1 @html_check_need_title +.if \\n[devtag-needs-end-of-title] \ +\{\ +. nr devtag-needs-end-of-title 0 +. DEVTAG-EO-TL +.\} +.if \\n[devtag-needs-title] \ +\{\ +. DEVTAG-TL +. nr devtag-needs-title 0 +. nr devtag-needs-end-of-title 1 +.\} +.if \\n[devtag-needs-end-of-heading] .DEVTAG-EO-H +.nr devtag-needs-end-of-heading 0 +.. +. +.\" If this macro were non-empty, we'd want to define it with .de1. +.do de @check_need_title +.. +. +.ie '\*(.T'html' \ +. do als check_need_title @html_check_need_title +.el \ +. do als check_need_title @check_need_title +. +.@R pf +.if \n(pf .nx +. +.if !\n(.g .ig +.de @S \" --- initialize string/macro to empty, if undefined +.do if !d\\$1 .ds \\$1\" empty +.. +. +.@R @\" \" debugging level +. +. +.\" *** INTERNAL GP MACROS *** +. +. +.de @C \" --- change environments, taking info with us +.nr _S \\n(.s +.nr _V \\n(.v +.nr _F \\n(.f +.nr _J \\n(.j +.do ds _A \\n[.fam] +.nr _I \\n(.i +.ev \\$1 +.ps \\n(_S +.vs \\n(_Vu +.ft \\n(_F +.ad \\n(_J +.do @fam \\*(_A +'in \\n(_Iu +.xl \\n($lu +.lt \\n($lu +.rr _S +.rr _V +.rr _F +.rr _I +.rr _J +.ls 1 +'ce 0 +.. +. +.de @D \" --- determine display type (Indent, Left, Center) +.ds |p "\\$3 +.nr _d 0 +.if "\\$2"C" \ +. nr _d 1 +.if "\\$2"L" \ +. nr _d 2 +.if "\\$2"I" \ +. nr _d 3 +.if "\\$2"M" \ +. nr _d 4 +.if !\\n(_d \ +\{\ +. nr _d \\$1 +. ds |p "\\$2 +.\} +. +.. +. +.rn nm @# \" --- save troff request +.de nm \" --- turn on number mode, preserving font info +.ie \\n(.$ \ +\{\ +. nr _S \\n(.s +. nr _F \\n(.f +. do if r _#p .do ps \\n[_#p] +. do if r _#f .do ft \\n[_#f] +. @# \\$1 \\$2 \\$3 \\$4 +. ft \\n(_F +. ps \\n(_S +. rr _F +. rr _S +.\} +.el .@# +.. +. +.de @z \" --- end macro +.if \n@>1 .tm >> @z, .z=\\n(.z ?a=\\n(?a +.if !"\\n(.z"" \ +\{\ +. do @err unclosed block, footnote, or other diversion (\\n(.z) +. di +. ex +.\} +.if \\n(?a \ +. bp\" \" force out final table +.ds bp +.ds @b\" \" don't start another page +.br +.if \n@>1 .tm << @z +.. +. +. +.\" *** STANDARD HEADERS AND FOOTERS *** +. +. +.ie \n(.g .ds $* \\\\$* +.el .ds $* \\\\$1 \\\\$2 \\\\$3 \\\\$4 \\\\$5 \\\\$6 \\\\$7 \\\\$8 \\\\$9 +. +.de he \" *** define header +.ie !\\n(.$ \ +\{\ +. rm |4 +. rm |5 +.\} +.el \ +\{\ +. ds |4 "\*($* +. ds |5 "\*($* +.\} +.. +. +.de eh \" *** define even header +.ie !\\n(.$ \ +. rm |4 +.el \ +. ds |4 "\*($* +.. +. +.de oh \" *** define odd header +.ie !\\n(.$ \ +. rm |5 +.el \ +. ds |5 "\*($* +.. +. +.de fo \" *** define footer +.ie !\\n(.$ \ +\{\ +. rm |6 +. rm |7 +.\} +.el \ +\{\ +. ds |6 "\*($* +. ds |7 "\*($* +.\} +.. +. +.de ef \" *** define even footer +.ie !\\n(.$ \ +. rm |6 +.el \ +. ds |6 "\*($* +.. +. +.de of \" *** define odd footer +.ie !\\n(.$ \ +. rm |7 +.el \ +. ds |7 "\*($* +.. +. +.de ep \" *** end page (must be followed by a .bp) +.if \\n(nl>0 \ +\{\ +. wh 0 +. rs +. @b +.\} +.. +. +. +.\" *** INTERNAL HEADER AND FOOTER MACROS *** +. +. +.de @h \" --- header +.if \n@>1 .tm >> @h %=\\n% ?a=\\n(?a ?b=\\n(?b ?w=\\n(?w +.do if (u;\\n(tm+\\n(bm+\\n(.V>\\n(.p) \{\ +. do @err insufficient page length; aborting +. pl \\n(nlu +. ab +.\} +.do if (u;\\n(.i+\\n(.o>=\\n(.l) \ +. do @err page offset plus indentation exceeds line length +.\" initialize a pile of junk +.nr ?h \\n(?H \" transfer "next page" to "this page" +.nr ?H 0 +.nr ?c \\n(?C +.nr ?C 0 +.do if d |4 .rn |4 |0 +.do if d |5 .rn |5 |1 +.do if d |6 .rn |6 |2 +.do if d |7 .rn |7 |3 +.nr _w 0 \" reset max footnote width +.nr ?W 0 \" no wide floats this page (yet) +.nr ?I 1 +.\" begin actual header stuff +.ev 2 +.rs +.if \\n(hm>0 \ +. if !'\*(.T'html' \ +. sp |\\n(hmu \" move to header position +.@t $h\" \" output header title +.if \\n(tm<=0 \ +. nr tm \n(.Vu +.if !'\*(.T'html' \ +. sp |\\n(tmu \" move to top of text +.ev +.mk _k \" for columned output +.if \\n(?n=1 .nm 1\" restore line numbering if n1 mode +.nr $c 1 \" set first column +.if \n@>4 .tm -- @h >> .ns nl=\\n(nl %=\\n% _k=\\n(_k tm=\\n(tm +.ie \\n(?s \ +\{\ +. nr ?s 0 +. rs +' @b +.\} +.el \ +. @n\" \" begin the column +.if \n@>2 .tm << @h +.. +. +.de @n \" --- new column or page +.if \n@>3 .tm >> @n nl=\\n(nl %=\\n% ?f=\\n(?f ?o=\\n(?o +.if \\n(bm<=0 \ +. nr bm \\n(.Vu +.if (\\n(_w<=\\n($l)&(\\n(?W=0) \ +\{\ +. \" Compute fudge factor (must be < 1P). +. nr _b (\\n(ppp*\\n(tvu)/200u +. if \\n(_bu>((\\n(bmu-\\n(fmu-((\\n(tpp*\\n(tvu)/100u))/2u) \ +. nr _b (\\n(ppp*\\n(tvu)/100u-\n(.Vu +. nr _b +\\n(bmu +.\} +.nr _B \\n(_bu +.ch @f +.wh -\\n(_bu @f +.nr _b +(\\n(ppp*\\n(tvu)/100u \" add 1 paragraph v in case sweep past +.if \n@>2 .tm @n .p=\\n(.p bm=\\n(bm _b=\\n(_b _B=\\n(_B +.nr ?f 0 \" reset footnote flag +.if \\n(?o \ +\{\ +. (f _\" \" reprocess footnotes which run off page +. nf +. |o +. fi +. )f +. rm |o +.\} +.nr ?o 0 +.if \\n(?T \ +\{\ +. nr _i \\n(.i +. if \\n(?n \ +. nm \\n(ln +. in 0 +. |h\" \" output the table header +. in \\n(_iu +. if \\n(?n \ +. nm +. rr _i +. mk #T \" for tbl commands +. ns +.\} +.if (\\n(?a)&((\\n($c<2):(\\n(?w=0)) \ +\{\ +. nr ?a 0 \" output floating keep +. @k |t +. if \\n(?w \ +. mk _k \" don't overstrike wide keeps +. nr ?w 0 +.\} +.os +.$H\" \" special column header macro +.ns +.. +. +.de @f \" --- footer +.if \n@>1 .tm >> @f %=\\n% nl=\\n(nl ?a=\\n(?a ?b=\\n(?b ?f=\\n(?f +.if \n@>2 .nr __ \\n(.pu-\\n(nlu +.if \n@>2 .tm @f bm=\\n(bm _B=\\n(_B _b=\\n(_b .p-nl=\\n(__ +.if \n@>2 .rr __ +.if \\n(?T \ +\{\ +. nr T. 1 \" for tbl commands (to output bottom line) +. T# 1\" \" output the sides and bottom lines +. br +.\} +.ev 2 +.ce 0 +.if \\n(?b \ +\{\ +. nr ?b 0 +. @k |b\" \" output bottom of page tables +.\} +.if \\n(?f \ +. @o\" \" output footnote if present +.ie \\n($c<\\n($m \ +. @c\" \" handle new column +.el \ +. @e\" \" new page +.ev +.if \n@>2 .tm << @f +.. +. +.de @o \" --- output footnote +.nf +.ls 1 +.in 0 +.if \n@>2 .tm @o last printed text = \\n(nl placing @r trap at -\\n(_B +.wh -\\n(_Bu @r +.if \\n(?n \ +. nm \\n(ln +.if \\n(_f \ +. if !\\n(_f=\\n($m \ +. do @err writing \\n($m-column footnote in \ +\\n(_f-column layout +.|f +.nr _f 0 +.if \\n(?n \ +. nm +.fi +.if \n@>2 .tm @o triggered @r (?o) = \\n(?o +.if \\n(?o \ +\{\ +. di \" just in case triggered @r +. if \\n(dn=0 \ +\{\ +. rm |o +. nr ?o 0 +. \} +. nr dn \\n(_D +. rr _D +.\} +.rm |f +.ch @r +.. +. +.de @c \" --- new column +.if \n@>2 .tm >> @c %=\\n% +.rs +.sp |\\n(_ku +.@O +\\n($lu+\\n($su +.nr $c +1 +.@n +.. +. +.de @e \" --- end page +.if \n@>2 .tm >> @e +.@O \\n(_ou +.rs +.\" Move to footer position. +.sp |\\n(.pu-\\n(fmu-((\\n(tpp*\\n(tvu)/100u) +.@t $f\" \" output footer title +.nr ?h 0 +.bp +.. +. +.de @t \" --- output header or footer title +.if !\\n(?h \ +\{\ +. sz \\n(tp\" \" set header/footer type fonts, etc. +. @F \\n(tf +. lt \\n(_Lu \" make title span entire page +. if \\n(?n \ +. nm \\n(ln +. nf +. \\$1 +. br +. if \\n(?n \ +. nm +.\} +.. +. +.de $h \" $$$ print header +.ds |z +.if !\\n(?c \ +\{\ +. if e .ds |z "\\*(|0 +. if o .ds |z "\\*(|1 +.\} +.if !\(ts\\*(|z\(ts\(ts \ +' tl \\*(|z +.rm |z +.. +. +.de $f \" $$$ print footer +.ds |z +.if \\n(?c \ +\{\ +. if e .ds |z "\\*(|0 +. if o .ds |z "\\*(|1 +.\} +.if \(ts\\*(|z\(ts\(ts \ +\{\ +. if e .ds |z "\\*(|2 +. if o .ds |z "\\*(|3 +.\} +.if !\(ts\\*(|z\(ts\(ts \ +' tl \\*(|z +.rm |z +.. +. +.de @r \" --- reprocess overflow footnotes +.if \n@>3 .tm >> @r .z=\\n(.z ?f=\\n(?f ?a=\\n(?a ?b=\\n(?b _b=\\n(_b +.di |o \" save overflow footnote +.nr ?o 1 +.nr _D \\n(dn +.ns +.. +. +. +.\" *** COMMANDS WITH VARIANT DEFINITIONS *** +. +. +.ie '\*(.T'html' .ds @b \" empty +.el .rn bp @b \" --- begin page +. +.de bp \" *** begin new page (overrides columns) +.nr $c \\n($m \" force new page, not new column +.ie \\n(nl>0 \ +. @b \\$1 +.el \ +\{\ +. if \\n(.$>0 \ +. pn \\$1 +. if \\n(?I \ +. @h\" \" 'spring' the header trap +.\} +.br +.wh 0 @h \" reset header +.. +. +.rn ll xl \" *** special line length (local) +.de ll +.xl \\$1 +.lt \\$1 +.nr $l \\n(.l \" *** line length (copied among ev 0, 1, and 2) +.if (\\n($m<=1):(\\n($l>\\n(_L) \ +. nr _L \\n(.l +.. +. +.rn po @O \" --- local page offset +. +.de po \" *** page offset +.@O \\$1 +.if \\n(.o<0 \ +. do @err page offset is negative (\\n(.ou) +.nr _o \\n(.o +.. +. +.\" Redefine the groff fam request to set the family in +.\" environment 2 as well as the current environment. +.if !\n(.g .ig +.do rn fam @fam \" --- set family in current environment +.do de fam \" *** set font family in ev 2 and current ev +.do @fam \\$1 +.ev 2 +.do @fam \\$1 +.ev +.. +. +. +.\" *** MISCELLANEOUS ROFF COMMANDS *** +. +. +.de hx \" *** suppress headers and footers next page +.nr ?H 1 +.. +. +.de ix \" *** indent, no break +'in \\$1 +.. +. +.de bl \" *** contiguous blank lines +.br +.@s \\$1 +.sp \\$1 +.. +. +.de @s \" --- diversion-surviving space test +.ne \\$1 +.rs +.if !'\\n(.z'' \!.@s \\$1 +.. +. +.\" Even with the following facilities, this package's simulation of +.\" roff(1) line numbering features does not exhibit complete fidelity +.\" to that program's Unix V7 behavior. roff(1) always increased the +.\" page offset by 5n and set a three-digit line number, leaving _two_ +.\" spaces between the number and the start of unindented text. This +.\" package indents by \n(no instead. Further, roff(1) did _not_ reduce +.\" the line length to compensate for the increase in page offset. GBR +.\" presumes that the document author was expected to use an `ll` +.\" request to perform that action if desired, but has no corpus of +.\" idiomatic, line-numbered roff(1) documents to examine. +.\" +.de n1 \" *** line numbering 1 +.ie \\n(.$ \ +. if '\\$1'C' \ +\{\ +. nr ?N 1 +. nr _l \\n(.l +. ll -\\n(nou +.\} +.if !\\n(?N \ +. po -\\n(nou +.nr ?n 1 +.do nr _#p \\n(.s +.do nr _#f \\n(.f +.nm 1 +.. +. +.de n2 \" *** line numbering 2 +.nr _n \\n(ln-1\" save last line number that may have been output +.ie \\n(.$ \ +\{\ +. do ie \\B`\\$1` \ +\{\ +. ds |i \\$1 +. ds |j \\$1 +. nr |l 0 +. \" Pick off leading char and rest to check. +. do substring |i 0 0 \" +. do length |l \\$1 +. if \\n(|l>1 .do substring |j 1\" \" for +N / -N +. ie `\\*(|i`+` \ +. nr ln (\\n(_n)+\\*(|j +.\" This file's brace style doesn't permit indentation of \{. --GBR +. el \ +\{\ +. ie `\\*(|i`-` \ +. nr ln (\\n(_n)-\\*(|j +. el \ +. nr ln \\$1 \" unsigned N +. \} +. do nr _#p \\n(.s +. do nr _#f \\n(.f +. nm \\n(ln +. nr ?n 2 +. rm |i |j +. rr |l +.\} +. el \ +. do @err invalid numeric argument to 'n2': '\\$1' +.\} +.el \ +\{\ +. nm +. ie \\n(?N \ +\{\ +. ll \\n(_lu +. rr _l +. nr ?N 0 +.\} +. el \ +. po +\\n(nou +. nr ?n 0 +. nr ln 0 +.\} +.rr _n +.. +. +.de pa \" *** new page +.bp \\$1 +.. +. +.de ro \" *** roman page numbers +.af % i +.. +. +.de ar \" *** arabic page numbers +.af % 1 +.. +. +.de m1 \" *** position one space +.nr _0 \\n(hmu +.nr hm \\$1v +.nr tm +\\n(hmu-\\n(_0u +.rr _0 +.. +. +.de m2 \" *** position two space +.nr tm \\n(hmu+\\n(tpp+\\$1v +.. +. +.de m3 \" *** position three space +.nr bm \\n(fmu+\\n(tpp+\\$1v +.. +. +.de m4 \" *** position four space +.nr _0 \\n(fmu +.nr fm \\$1v +.nr bm +\\n(fmu-\\n(_0u +.. +. +.de sk \" *** leave a blank page (next page) +.if \\n(.$>0 \ +. do @err ignoring argument(s) to 'sk' +.nr ?s 1 +.. +. +. +.\" *** MISCELLANEOUS USER SUPPORT COMMANDS *** +. +. +.if !\n(.g .ig +.de re \" *** reset tabs (TROFF defines 15 stops default) +.ta T 0.5i +.. +. +.if \n(.g .ig +.de re +.ta 0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +.. +. +.de ba \" *** set base indent +.ie \\n(.$ \ +. nr $i \\$1n +.el \ +. nr $i \\n(siu*\\n($0u +.. +. +.de hl \" *** draw horizontal line +.br +.if '\*(.T'html' \ +\{\ +. HR +. do return +.\} +.ie \n(.g .do nr _I \\n[.in] +.el .nr _I \\n(.i +\l'\\n(.lu-\\n(_Iu' +.sp +.. +. +. +.\" *** PARAGRAPHING *** +. +. +.de pp \" *** paragraph +.lp \\n(piu +.. +. +.de lp \" *** left aligned paragraph +.@p +.if \\n(.$ \ +. ti +\\$1 +.nr $p 0 1 +.. +. +.de ip \" *** indented paragraph w/ optional tag +.if (\\n(ii>0)&(\\n(ii<1n) \ +. nr ii \\n(iin +.nr _0 \\n(ii +.if \\n(.$>1 \ +. nr _0 \\$2n +.@p \\n(_0u +.nr _I \\n(.iu +.in 0 +.nm +.di |i +\&\\$1 +.br +.di +.if \\n(?n \ +. nm \\n(ln +.in \\n(_Iu +.ds |j \\*(|i\\ +.ie \\w"\\*(|j" \ +\{\ +. ti -\\n(_0u +. ie \\w"\\*(|j">=\\n(_0 \ +\{\ +. do DEVTAG-COL 1 +\\*(|j +. do DEVTAG-COL-NEXT 2 +. br +. \} +. el \ +\{\ +. do DEVTAG-COL 1 +\\*(|j\h'|\\n(_0u'\c +. do DEVTAG-COL 2 +. \} +.\} +.el .do DEVTAG-COL 2 +.rr _0 +.rm |i |j +.. +. +.de np \" *** numbered paragraph +.\" use output comparison in case user has changed format of $p +.if '\\n($p'-1' \ +. nr $p 0 \" reset number after .bu +.nr $p +1 \" increment paragraph number +.@p \w'\0(000)\0'u +.ti -\w'\0(000)\0'u +\0(\\n($p)\h'|\w'\0(000)\0'u'\c +.. +. +.de bu \" *** bulleted paragraph +.br +.\" use output comparison in case user has changed format of $p +.if '\\n($p'-1' \ +. ns \" don't space between .bu paragraphs +.nr $p 0-1 \" mark "bulleted paragraph" mode +.@p \w'\0\(bu\0'u +.ti -\w'\0\(bu\0'u +\0\(bu\0\c +.. +. +.de @p \" --- initialize for paragraph +.do check_need_title +.if "\\n(.z"|e" .do @err eqn equation continuation unfulfilled +.in \\n($iu+\\n(pou +.if \\n(.$ \ +. in +\\$1n +.ce 0 +.rj 0 +.fi +.@F \\n(pf +.sz \\n(pp +.sp \\n(psu +.ne \\n(.Lv+\\n(.Vu +.ns +.. +. +. +.\" *** SECTION HEADINGS *** +. +. +.de sh \" *** section heading +.fi +.do check_need_title +.if (\\n(si>0)&(\\n(si<1n) \ +. nr si \\n(sin +.if '\*(.T'html' .nr si 0 +.ce 0 +.if '\*(.T'html' \ +\{\ +. do DEVTAG-SH \\$1 +. do nr devtag-needs-end-of-heading 1 +.\} +.@d "\\$1" +1 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 +.if !"\\$2"_" \ +\{\ +. ds |n \&\\$2 +. $p "\\*(|n" "\\*($n" \\n($0 +. $0 "\\*(|n" "\\*($n" \\n($0 +. rm |n +.\} +.nr $p 0 1 \" reset .np count +.. +. +.de @d \" --- change section depth +.if !""\\$1" \ +. nr $0 \\$1 +.if \\n($0&(\\n(.$>1) \ +. nr $\\n($0 \\$2 +.ds $n \&\" +.ie \\n($0>=1 \ +\{\ +. if '\\n($1'0' \ +. nr $1 1 +. if (\\n(.$>=3) .if !"\\$3"-" \ +. nr $1 \\$3 +. as $n \\n($1 +.\} +.el \ +. nr $1 0 +.ie \\n($0>=2 \ +\{\ +. if '\\n($2'0' \ +. nr $2 1 +. if (\\n(.$>=4) .if !"\\$4"-" \ +. nr $2 \\$4 +. as $n .\\n($2 +.\} +.el \ +. nr $2 0 +.ie \\n($0>=3 \ +\{\ +. if '\\n($3'0' \ +. nr $3 1 +. if (\\n(.$>=5) .if !"\\$5"-" \ +. nr $3 \\$5 +. as $n .\\n($3 +.\} +.el \ +. nr $3 0 +.ie \\n($0>=4 \ +\{\ +. if '\\n($4'0' \ +. nr $4 1 +. if (\\n(.$>=6) .if !"\\$6"-" \ +. nr $4 \\$6 +. as $n .\\n($4 +.\} +.el \ +. nr $4 0 +.ie \\n($0>=5 \ +\{\ +. if '\\n($5'0' \ +. nr $5 1 +. if (\\n(.$>=7) .if !"\\$7"-" \ +. nr $5 \\$7 +. as $n .\\n($5 +.\} +.el \ +. nr $5 0 +.ie \\n($0>=6 \ +\{\ +. if '\\n($6'0' \ +. nr $6 1 +. if (\\n(.$>=8) .if !"\\$8"-" \ +. nr $6 \\$8 +. as $n .\\n($6 +.\} +.el \ +. nr $6 0 +.. +. +.de sx \" *** heading up, no increment (2.1.1 -> 2.1) +.ce 0 +.ul 0 +.nr _0 \\n($0-1 +.if \\n(.$ .nr _0 +1 +.if \\n(.$ .nr _0 \\$1 +.@d \\n(_0 +.rr _0 +.$p "" "" \\n($0 +.nr $p 0 1 \" reset .np count +.. +. +.de uh \" *** unnumbered section heading +.$p "\\$1" +.$0 "\\$1" +.. +. +.de $p \" $$$ print section heading +.if (\\n(si>0)&(\\n(.$>2) \ +. nr $i \\$3*\\n(si +.in \\n($iu +.ie !"\\$1\\$2"" \ +\{\ +. sp \\n(ssu \" one of them is non-null +. ne \\n(.Lv+\\n(.Vu+\\n(psu+((\\n(spp*\\n(tvu*\\n(.Lu)/100u) +. \" exdent if \\$3 > 0 +. ie 0\\$3 \ +. ti -(\\n(siu-\\n(sou) +. el \ +. ti +\\n(sou +. @F \\n(sf +. sz \\n(sp +. if 0\\$3 \ +. $\\$3 +. if \w"\\$2">0 \\$2. +. if \w"\\$1">0 \\$1\f1\ \ \& +.\} +.el \ +. sp \\n(psu +.@F \\n(pf +.sz \\n(pp +.. +. +. +.\" *** COLUMNED OUTPUT *** +. +. +.de 2c \" *** double columned output +.do if d |f .do @err changing columnation with footnote pending +.br +.if \\n($m>1 \ +. 1c\" \" revert to 1c if already 2c +.nr $c 1 +.nr $m 2 +.if \\n(.$>1 \ +. nr $m \\$2 \" param 2: column quantity +.if \\n(.$>0 \ +. if !'\\$1'' \ +. nr $s \\$1n \" param 1: column separation +.nr $l (\\n(.l-((\\n($m-1)*\\n($s))/\\n($m +.xl \\n($lu +.mk _k +.ns +.. +. +.de 1c \" *** single columned output +.do if d |f .do @err changing columnation with footnote pending +.br +.nr $c 1 +.nr $m 1 +.ll \\n(_Lu\" return to normal output +.sp |\\n(.hu +.@O \\n(_ou +.. +. +.de bc \" *** begin column +.sp \\n(.pu +.. +. +. +.\" *** FLOATING TABLES AND NONFLOATING BLOCKS *** +. +. +.de (z \" *** begin floating keep +.if \n@>4 .tm >> (z, .z=\n(.z +.@D 4 \\$1 \\$2 +.@( +.. +. +.de )z \" *** end floating keep +.if \n@>4 .tm >> )z, .z=\n(.z +.sp \\n(zsu +.@) +.if \n@>4 .tm -- )z << @), .z=\n(.z +.rr _0 +.if !\\n(?b \ +. nr dn +(\\n(ppp*\\n(tvu)/200u+\\n(zsu +.nr dl -\n(.H \" fudge factor necessary to make it work +.ie ((\\n(dn+\n(.V)>=\\n(.t):(\\n(?a):((\\n(dl>\\n($l)&(\\n($c>1)) \ +\{\ +. nr ?a 1 +. if (\\n(dl>\\n($l)&(\\n($m>1) \ +. nr ?w 1 \" mark wider than one column (top) +. ds |x |t +.\} +.el \ +\{\ +. nr ?b 1 +. if (\\n(dl>\\n($l)&(\\n($m>1) \ +. nr ?W 1 \" mark wider than one column (bottom) +. nr _b +\\n(dnu +. \" avoid moving @f back past the current position +. if \\n(.p-\\n(nl-\n(.V<\\n(_b \ +. nr _b \\n(.p-\\n(nl-\n(.V +. ch @f -\\n(_bu +. ds |x |b +.\} +.da \\*(|x \" copy to save macro +.nf +.ls 1 +.nr ?k 1 +.if \n@>4 .tm -- )z >> \\*(|x +\!.if \\\\n(nl>(\\\\n(tm+2v) .ne \\n(dnu-\\n(zsu +.|k\" \" and the body +.if \n@>4 .tm -- )z << \\*(|x, .z=\\n(.z +.nr ?k 0 +.rm |k\" \" remove the temp macro +.da +.in 0 +.ls 1 +.xl \\n($lu +.ev +.if \n@>4 .tm << )z, .z=\\n(.z +.. +. +.de @k \" --- output keep +.if \n@>4 .tm >> @k, $1=\\$1, .z=\\n(.z +.ev 1 +.nf +.ls 1 +.in 0 +.if !`\\$2`ns` .sp \\n(zsu \" no pre-spacing if (b .. )b +.if \\n(?n \ +. nm \\n(ln +.\\$1 +.if \\n(?n \ +. nm +.br +.rm \\$1 +.ev +.. +. +.de (t \" XXX temp ref to (z +.(z \\$1 \\$2 +.. +. +.de )t \" XXX temp ref to )t +.)z \\$1 \\$2 +.. +. +.de (b \" *** begin block +.br +.@D 3 \\$1 \\$2 +.sp \\n(bsu +.@( +.if '\*(.T'html' .sp \\n(bsu +.. +. +.de )b \" *** end block +.br +.@) +.if (\\n(bt=0):(\\n(.t<\\n(bt) \ +. ne \\n(dnu \" make it all on one page +.@k |k ns +.ev \" return from display environment +.sp \\n(bsu+\\n(.Lv-1v +.. +. +.de @( \" --- begin keep +.if !"\\n(.z"" .do @err invalid nested keep (\\n(.z) +.@M +.di |k +\!'rs +.. +. +.de @M \" --- set modes for display +.nr ?k 1 +.@C 1 +.@F \\n(df +.if \\n($R .@V +.vs \\n(.sp*\\n(dvu/100u +.nf +.if "\\*(|p"F" \ +. fi \" set fill mode if "F" parameter +.if \\n(_d=4 \ +. in 0 +.if \\n(_d=3 \ +\{\ +. in +\\n(biu +. xl -\\n(biu +.\} +.if \\n(_d=1 \ +. ce 10000 +.. +. +.de @) \" --- end keep +.br +.if !"\\n(.z"|k" .do @err attempted close of never-opened keep +.nr ?k 0 +.di +.in 0 +.ce 0 +.. +. +.de (c \" *** begin block centered text +.br +.if "\\n(.z"|c" .do @err block centering calls cannot be nested +.if \\n(?n .nm +.if ``\\n(.z` \ +\{\ +. @C 1\" \" Ensure env. set up for centering in open text +. ev +.\} +.di |c +.. +. +.de )c \" *** end block centered text +.if !"\\n(.z"|c" .do @err unmatched block centering call +.br \" force out final line +.di +.if \n@>4 .tm >> .)c .l=\\n(.l .i=\\n(.i $i=\\n($i dl=\\n(dl +.ev 1 +.ls 1 +.nr __ (\\n(.lu-\\n(.iu-\\n(dlu)/2u +.if \\n(__u<0 .nr __ 0 +.in \\n(__u +.rr __ +.if \n@>4 .tm -- .)c << .in .l=\\n(.l .i=\\n(.i dl=\\n(dl +.if \\n(?n \ +. nm \\n(ln +.nf +.|c +.in +.ls +.if \\n(?n \ +. nm +.ev +.rm |c +.if \\n(?n \ +. nm \\n(ln +.. +. +. +.\" *** BLOCK QUOTES (OR WHATEVER) AND LISTS *** +. +. +.de (q \" *** begin block quote +.br +.@C 1 +.fi +.sp \\n(qsu +.in +\\n(qiu +.xl -\\n(qiu +.sz \\n(qp +.if \\n(?n \ +. nm \\n(ln +.. +. +.de )q \" *** end block quote +.br +.if \\n(?n \ +. nm +.ev +.sp \\n(qsu+\\n(.Lv-1v +.nr ?k 0 +.. +. +.de (l \" *** begin list +.br +.sp \\n(bsu +.@D 3 \\$1 \\$2 +.@M +.if \\n(?n \ +. nm \\n(ln +.if '\*(.T'html' .sp \\n(bsu +.. +. +.de )l \" *** end list +.\" XXX: Check for keep underflow here. +.br +.ev +.if \\n(?n \ +. nm \\n(ln +.sp \\n(bsu+\\n(.Lv-1v +.nr ?k 0 +.. +. +. +.\" *** PREPROCESSOR SUPPORT *** +. +. +.\" +.\" EQN +.\" +.de EQ \" *** equation start +.do if \\n[devtag-needs-end-of-heading] .do DEVTAG-EO-H +.do nr devtag-needs-end-of-heading 0 +.if "\*(.T"html" \ +\{\ +. do nr e-EQ-ll \\n(.l +. ll 1000n +.\} +.do HTML-IMAGE +.if !\\n(?e \ +\{\ +. if "\\n(.z"|e" .do @err nested eqn equation start +. @D 1 "\\$1" "\\$2" +. @C 2 +. di |e +.\} +.ls 1 +.in 0 +.nf +.. +. +.de EN \" *** equation end +.br +.do HTML-IMAGE-END +.if "\*(.T"html" \ +. do ll \\n[e-EQ-ll]u +.ie "\\$1"C" \ +\{\ +. nr ?e 1 +. sp \\n(esu +.\} +.el \ +\{\ +. nr ?e 0 +. di +. if \\n(dn \ +. @q\" \" actual equation output +. rm |e +. ev +.\} +.. +. +.de @q \" --- equation output +.nr _Q \\n(dnu +.ev +.sp \\n(esu \" output rest of preceding text +.if !"\\n(.z"" \!.ne \\n(_Qu +.ne \\n(_Qu+\n(.Vu \" keep it on one page +.@C 2\" \" .ev 2 may be jumbled from header +.if \\n(_d=1 \ +. in (\\n(.lu+\\n($iu-\\n(dlu)/2u +.if \\n(_d=2 \ +. in \\n($iu +.if \\n(_d=3 \ +. in \\n(biu+\\n($iu +.if \\n(_d=4 \ +. in 0 +.mk _q +.if \n@>1 .tm --@q: _Q=\\n(_Q _q=\\n(_q nl=\\n(nl |p=\\*(|p +.if !"\\*(|p"" \ +\{\ +. rs +. sp (\\n(_Qu-\\n(.vu)/2u +. tl """\\*(|p" +. rt \\n(_qu +.\} +.if \\n(?n \ +. nm \\n(ln +.|e +.if \\n(?n \ +. nm +.sp |\\n(_qu+\\n(_Qu +.sp \\n(esu+\\n(.Lv-1v +.rr _q +.rr _Q +.. +. +.\" +.\" TBL +.\" +.de TS \" *** table start +.sp \\n(bsu +.if "\*(.T"html" \ +\{\ +. do nr e-TS-ll \\n(.l +. ll 1000n +.\} +.do HTML-IMAGE +.@C 1 +.fi \" drop into fill mode for text boxes +.if "\\$1"H" \ +\{\ +. di |h \" save header part +. nr ?T 1 +.\} +.ls 1 +.ch @f -(\\n(_bu+1v) \" set pseudo-trap for bottom line +.if \\n(.p-\\n(_b-1v<=\\n(nl \ +. ch @f \\n(nlu+\n(.Vu +.. +. +.de TH \" *** end header part of table +.nr T. 0 +.T# 0 +.if \\n(?n \!.nm +.di +.nr _T \\n(?T +.nr ?T 0 +.ne \\n(dnu+1v +.nr ?T \\n(_T +.nr _i \\n(.i +.if \\n(?n .nm \\n(ln +.in 0 +.|h\" \" put in the initial header +.in \\n(_iu +.rr _i +.mk #T +.. +. +.de TE \" *** table end +.nr ?T 0 +.ch @f -\\n(_bu \" reset pseudo-trap +.if \\n(.p-\\n(_b<=\\n(nl \ +. ch @f \\n(nlu+\n(.Vu +.ev +.do HTML-IMAGE-END +.if "\*(.T"html" \ +. do ll \\n[e-TS-ll]u +.sp \\n(bsu+\\n(.Lv-1v +.re +.. +. +.de T& +.. +. +.\" +.\" REFER +.\" +.do mso refer-me.tmac +. +.\" +.\" IDEAL +.\" +.de IS \" *** start ideal picture +.nr g7 \\n(.u +.ls 1 +.. +. +.de IF +.if \\n(g7 .fi +.ls +.. +. +.de IE \" *** end ideal picture +.if \\n(g7 .fi +.ls +.. +. +.de && \" no-op so we can define and end one macro inside another +.. +. +.\" +.\" PIC +.\" +.de PS \" *** start picture: $1=height, $2=width in units or inches +.sp 0.3 +.do HTML-IMAGE +.nr g7 \\$2 +.in (u;\\n(.l-\\n(g7>?0/2) +.ne \\$1u +.nr g7 \\n(.u +.ls 1 +.ie \\n(?n \ +\{\ +. do nr PS_nm_cnt 0 +. do de PS_nm_check && \" define macro to emit .nm at top diversion +. if \n@>4 .tm -- PS: \\\\$1 \\\\$2 .z=\\\\n(.z PS_nm_cnt=\\\\n[PS_nm_cnt] +. \" Multiple .PS/.PE in a keep. +. if `\\\\$2`init` \ +. do nr PS_nm_cnt \\\\n[PS_nm_cnt]+1 +. ie `\\\\n(.z`` \ +\{\ +. if `\\\\$1`suspend` \ +. nm +. if `\\\\$1`resume` \ +\{\ +. nm \\\\n(ln +. do nr PS_nm_cnt \\\\n[PS_nm_cnt]-1 +. do if !\\\\n[PS_nm_cnt] \ +\{\ +. do rm PS_nm_check +. do rr PS_nm_cnt +.\} +.\} +.\} +.el \!.PS_nm_check \\\\$1 +. && +. mk _q \" emit a single numbered line for PS picture +. rs +\&\ \" space +. br +. rt \\n(_qu +. do PS_nm_check suspend init +.\} +.. +. +.rm && +. +.de PF \" *** end picture; "fly back" to top +.if \\n(?n .do PS_nm_check resume +.ls +.in +.if \\n(g7 .fi +.do HTML-IMAGE-END +.. +. +.de PE \" *** end picture +.PF +.sp .6 +.. +. +.\" +.\" GREMLIN +.\" +.de GS \" *** start gremlin picture +.ie '\*(.T'html' \ +\{\ +. ie "\\$1"L" .do HTML-IMAGE-LEFT +. el .ie "\\$1"R" .do HTML-IMAGE-RIGHT +. el .do HTML-IMAGE +.\} +.el \ +\{\ +. nr g7 (\\n(.lu-\\n(g1u)/2u +. if "\\$1"L" .nr g7 \\n(.iu +. if "\\$1"R" .nr g7 \\n(.lu-\\n(g1u +. in \\n(g7u +. nr g7 \\n(.u +. ls 1 +. nf +. ne \\n(g2u +.\} +.. +. +.de GE \" *** end gremlin picture +.ie '\*(.T'html' .do HTML-IMAGE-END +.el \ +\{\ +. GF +. sp .6 +.\} +.. +. +.de GF \" *** finish gremlin picture; stay at top +.ls +.in +.if \\n(g7 .fi +.. +. +. +.\" *** FONT AIDS *** +. +. +.de sz \" *** set point size and vertical spacing +.ps \\$1 +.if \\n($r .@v +.vs \\n(.sp*\\n(tvu/100u \" default vs at pointsize + 20% +.. +. +.de @v \" --- possibly set tv from $r +.if (1i>=240u)&(1p<=\\n($r)&(\\n($r<=4p) .nr tv \\n($r00/1p +.. +. +.de @V \" --- possibly set dv from $R +.if (1i>=240u)&(1p<=\\n($R)&(\\n($R<=4p) .nr dv \\n($R00/1p +.. +. +.de @E \" --- store in _F argument to \f for restoring font +.ie \\n(.f<10 \ +. ds _F \\n(.f +.el \ +\{\ +. ie \\n(.f<100&\n(.g \ +. ds _F (\\n(.f +. el \ +. ds _F P +.\} +.. +. +.de r \" *** enter roman font +.do check_need_title +.@E +.ft 1 +.if \\n(.$ \&\\$1\f\\*(_F\\$2 +.do check_need_title +.. +. +.de i \" *** enter italic +.do check_need_title +.@E +.ft 2 +.if \\n(.$ \&\,\\$1\/\f\\*(_F\\$2 +.do check_need_title +.. +. +.de b \" *** enter boldface +.do check_need_title +.@E +.ft 3 +.if \\n(.$ \&\\$1\f\\*(_F\\$2 +.do check_need_title +.. +. +.de rb \" *** enter real boldface +.do check_need_title +.@E +.ft 3 +.if \\n(.$ \&\\$1\f\\*(_F\\$2 +.do check_need_title +.. +. +.de bi \" *** enter bold italic +.do check_need_title +.@E +.ft 4 +.if \\n(.$ \&\,\\$1\/\f\\*(_F\\$2 +.do check_need_title +.. +. +.de u \" *** enter underlined word +.\" If the first argument would break, then (in troff mode), this +.\" underlines only the words appearing only the last output line, with +.\" the underline extending all the way into the left margin. +.ie t \\$1\l'|0\(ul'\\$2 +.el \(ul\\$1\(ul\\$2 +.. +. +.\" This alternative version of the `u` macro uses the groff \Z +.\" extension to get the underlining to accurately fit under the words +.\" at the expense of no longer adjusting them. If the first argument +.\" would break, the output line is overset. +.if !\n(.g .ig +.de u +.ie t .do nop \Z'\\$1'\v'.25m'\D'l \w'\\$1'u 0'\v'-.25m'\\$2 +.el \(ul\\$1\(ul\\$2 +.. +. +.de q \" *** enter quoted word +\&\\*(lq\\$1\\*(rq\\$2 +.. +. +.de bx \" *** enter boxed word +.ie t \ +\{\ +. ie '\\*(.T'html' \\$1\\$2 +. el \k~\(br\|\\$1\|\(br\l'|\\n~u\(rn'\l'|\\n~u\(ul'\^\\$2 +.\} +.el \ +\{\ +. ie \\n(.g .do nop \m[black]\M[white]\Z'\\$1'\h'\w'\\$1'u'\ +\m[]\M[]\\$2 +. el |\\$1|\\$2 +.\} +.. +. +.de sm \" *** print in smaller font +\s-1\\$1\\s+1\\$2 +.. +. +.de @F \" --- change font (0 -> no change) +.nr ~ \\$1 +.if \\n~>0 \ +. ft \\n~ +.rr ~ +.. +. +. +.\" *** FOOTNOTING *** +. +. +.de (f \" *** begin footnote +.if "\\n(.z"|f" .do @err footnotes cannot be nested +.if \\n(_f \ +. if !\\n(_f=\\n($m \ +. do @err queueing \\n($m-column footnote after \ +\\n(_f-column footnote +.nr _f \\n($m +.ie "\\n(.z"" \ +\{\ +. nr _D \\n(dn +. nr _0 1v+\\n(nlu +. ev 2 +. nm +. da |f +. in 0 +. xl \\n($lu-\\n(fuu +. @F \\n(ff +. sz \\n(fp +. vs \\n(.sp*\\n(dvu/100u +. if !\\n(?f \ +\{\ +. nr _b +1v \" allow space for $s +. $s +. \} +. br +. if \\n(.p-\\n(_b-\\n(_0-\\n(.h-1v-\\n(fs<0 \ +\{\ +. da\" \" won't fit on page at all +. bc +. if !\\n(?f \ +. rm |f +. da |f +.\" Next 5 lines could be dropped if headers had their own environment. +. in 0 \" reset everything from .bc +. xl \\n($lu-\\n(fuu +. @F \\n(ff +. sz \\n(fp +. vs \\n(.sp*\\n(dvu/100u +. if !\\n(?f \ +. $s +. br +. \} +. rr _0 +. sp \\n(fsu +. nr ?f 1 +. fi +. if !"\\$1"_" \ +. ti \\n(fiu +. if \n@>2 .tm << (f $f=\\n($f +.\} +.el \ +\{\ +. ev 2 +. nm +. in 0 +. xl \\n($lu-\\n(fuu +. @F \\n(ff +. sz \\n(fp +. vs \\n(.sp*\\n(dvu/100u +. fi +\!.(f \\$1 +\!.@N +.\} +.. +. +.de @N \" --- set no fill mode in the top-level diversion +.ie "\\n(.z"" .nf +.el \!.@N +.. +. +.de )f \" *** end footnote +.ie "\\n(.z"|f" \ +\{\ +. if \\n* .nr $f +1 +. nr * 0 +. in 0 +. da +. ev +. if \\n(_w<\\n(dl \ +. nr _w \\n(dl \" compute maximum fn width +. nr _b +\\n(dn +. ch @f -\\n(_bu +. if \\n(.p-\\n(_b<=\\n(nl \ +. ch @f \\n(nlu+\n(.Vu +. nr dn \\n(_D +. rr _D +.\} +.el \ +\{\ +. br +\!.)f +. ev +.\} +.. +. +.@R ff +.if \n(ff<=0 \ +. nr ff 1 \" footnote font: Times Roman +.@R fp +.if \n(fp<=0 \ +. nr fp 8 \" footnote pointsize +. +.de $s \" $$$ footnote separator +.nr __ 2i +.if \\n($lu<\\n(__u .nr __ \\n($lu +\l'\\n(__u' +.rr __ +.. +. +. +.\" *** DELAYED TEXT *** +. +. +.de (d \" *** begin delayed text +.am |d )d +.sp \\n(bsu +.vs \\n(.sp*\\n(dvu/100u +.. +. +.de )d \" *** end delayed text +.vs \\n(.sp*\\n(tvu/100u +.nr $d +1 +.. +. +.de pd \" *** print delayed text +.|d +.rm |d +.nr $d 1 +.. +. +. +.\" *** INDEXES (TABLE OF CONTENTS) *** +. +. +.nr _x 0 1 +.do nr _xn 0 +.af _x a +. +.de (x \" *** begin index entry +.if \n@>4 .tm >> (x, .z=\\n(.z +.ds |X x +.if \\n(.$>0 \ +. ds |X \\$1 +.ie "\\n(.z"" \ +. nr _z 0 +.el \ +. nr _z 1 +.@\\n(_z +.. +. +.de @0 \" --- finish (x if no current diversion +.am %\\*(|X )x +.sp \\n(xsu +.ti -\\n(piu +.. +. +.de @1 \" --- finish (x if current diversion +.if "\\n(_x"z" .nr _x 0 +.de =\\n+(_x )x +.. +. +.de )x \" *** end index entry +.if \n@>4 .tm >> )x, .z=\\n(.z +.ie "\\n(.z"" \ +\{\ +. ds |x \\n% +. if \\n(.$>0 \ +. ds |x \\$1 +. if "\\*(|x"_" \ +. ig .. +. am %\\*(|X .. +. if \w"\\$2">(\\n(.l-\\n(.i-\\n(.k) \ +. ti +\\n(xuu +\\\\a\\\\t\\$2\\*(|x +... +. rm |x +. rm |X +.\} +.el \ +\{\ +\!.(x \\*(|X +\!\\\\*(=\\n(_x\\\\ +\!.)x \\$1 \\$2 +\!.rm =\\n(_x +.\} +.. +. +.de xp \" *** print the index +.br +.@C 2 +.ls 1 +.vs \\n(.sp*\\n(dvu/100u +.fi +.in +\\n(piu +.ds |X x +.if \\n(.$>0 \ +. ds |X \\$1 +.xl -(\\n(xuu+\w'...'u) +.di |x +.%\\*(|X +.br +.di +.rm %\\*(|X +.xl \\n($lu +.rm |X +.ev +.nf +.in 0 +.ta \\n(.lu-\\n(xuuR \\n(.luR +.|x +.fi +.in +.rm |x +.. +. +. +.\" *** HTML VERSIONS OF .x(, .x), AND .xp *** +. +. +.do de1 (x-html \" --- create TAG and divert text +.nr _x +1 +.nr _xn +1 +.TAG "_x\\n[_x] +.br +.di |x\\n[_xn] +.br +.. +. +.do de1 )x-html \" --- end diversion +.br +.di +.. +. +.do de1 xp-html \" --- create list of links +.nr _xx 1 +.br +.ev xp-html-ev +.sp +.ULS +.while \\n[_xx]<=\\n[_xn] \ +\{\ +. br +. unformat |x\\n[_xx] +. di xp-html-div +. br +. ll 100i +. fi +. |x\\n[_xx] +. br +. di +. asciify xp-html-div +. rm xp-html-as +. as xp-html-as # +. as xp-html-as _x\\n[_xx] +. ll +. LI +. URL \\*[xp-html-as] "\\*[xp-html-div] +. rm xp-html-as +. nr _xx +1 +.\} +.ULE +.sp +.ev +.. +. +.if '\*(.T'html' \ +\{\ +. rm (x +. do als (x (x-html +. rm )x +. do als )x )x-html +. rm xp +. do als xp xp-html +.\} +. +. +.\" *** CHAPTERS AND TITLES *** +. +. +.de +c \" *** begin chapter +.ep\" \" force out footnotes +.if \\n(?o:\\n(?a \ +\{\ +. bp \" force out a table or more footnote +. rs +. ep +.\} +.nr ?C 1 +.nr $f 1 +.if \\n(?R \ +. pn 1 +.bp +.in \\n($iu \" reset the indent +.rs +.ie \\n(.$ \ +. $c "\\$1" +.el \ +. sp 3 +.. +. +.de ++ \" *** declare chapter type +.nr _0 0 +.if "\\$1"C" \ +. nr _0 1 \" chapter +.if "\\$1"RC" \ +. nr _0 11 \" renumbered chapter +.if "\\$1"A" \ +. nr _0 2 \" appendix +.if "\\$1"RA" \ +. nr _0 12 \" renumbered appendix +.if "\\$1"P" \ +. nr _0 3 \" preliminary material +.if "\\$1"B" \ +. nr _0 4 \" bibliographic material +.if "\\$1"AB" \ +. nr _0 5 \" abstract +.if \\n(_0=0 \ +. do @err invalid segment type to '++': '\\$1' +.nr ?R 0 +.if \\n(_0>10 \ +\{\ +. nr ?R 1 +. nr _0 -10 +.\} +.nr ch 0 1 +.if (\\n(_0=3):(\\n(_0=5) \ +. pn 1 \" must do before .ep +.if !\\n(_0=\\n(_M .if \\n(_M=3 \ +. pn 1 \" must do before .ep +.ep\" \" end page for correct page number types +.if \\n(_0=1 \ +\{\ +. af ch 1 +. af % 1 +.\} +.if \\n(_0=2 \ +\{\ +. af ch A +. af % 1 +.\} +.if \\n(_0=3 \ +. af % i +.if \\n(_0=4 \ +. af % 1 +.if \\n(_0=5 \ +. af % 1 +.if \\n(.$>1 \ +. he \\$2 +.nr _M \\n(_0 +.rr _0 +.. +. +.de $c \" $$$ print chapter title +.sz 12 +.ft 3 +.ce 1000 +.if \\n(_M<3 \ +. nr ch +1 +.ie \\n(_M=1 \\*(wc\~\\n(ch +.el .if \\n(_M=2 \\*(wa\~\\n(ch +.if \w"\\$1" .sp 3-\\n(.L +.if \w"\\$1" \\$1 +.if (\\n(_M<3):(\w"\\$1") \ +. sp 4-\\n(.L +.ce 0 +.ft +.sz +.ie \\n(_M=1 \ +. $C "\\*(wc" \\n(ch "\\$1" +.el .if \\n(_M=2 \ +. $C "\\*(wa" \\n(ch "\\$1" +.. +. +.de tp \" *** title page +.hx +.bp +.br +.rs +.pn \\n% +.. +. +.\" *** DATE AND LOCALIZATION *** +.ds wa Appendix\" +.ds wc Chapter\" +.do ds _mo1 January\" +.do ds _mo2 February\" +.do ds _mo3 March\" +.do ds _mo4 April\" +.do ds _mo5 May\" +.do ds _mo6 June\" +.do ds _mo7 July\" +.do ds _mo8 August\" +.do ds _mo9 September\" +.do ds _mo10 October\" +.do ds _mo11 November\" +.do ds _mo12 December\" +.do ds _dw1 Sunday\" +.do ds _dw2 Monday\" +.do ds _dw3 Tuesday\" +.do ds _dw4 Wednesday\" +.do ds _dw5 Thursday\" +.do ds _dw6 Friday\" +.do ds _dw7 Saturday\" +.do ds _td_format \\*(mo \\n(dy, \\n(y4\" +. +.de ld \" *** (re-)initialize date and localization +.\" Work around troff `yr` register's y2k problem. +.nr y2 \\n(yr%100 +.af y2 00 +.nr y4 \\n(yr+1900 +. +.do ds dw \\*[_dw\\n(dw] +.do ds mo \\*[_mo\\n(mo] +.do ds td \\*[_td_format] +. +.\" Set package default hyphenation mode, but override it with groff's +.\" localized value if available. +.hy 6 +.do if r \\*[locale]*hyphenation-mode-trap \ +. do hy \\n[\\*[locale]*hyphenation-mode-trap] +.. +. +.ld +. +.\" *** PARAMETRIC INITIALIZATIONS *** +. +. +.\" In groff 1.23, we keep $v and $V to maintain 30 years of continuity, +.\" but expose new names `tv` and `dv`, respectively, making it more +.\" obvious that user alteration of these register values is supported. +.\" See discussion of `$R` and `$r` below. +.nr tv \n(.v00+\n(.sp-1/\n(.sp \" vs as % of ps for .sz request +.nr dv \n(tv \" same for displays & footnotes +.do aln $v tv +.do aln $V dv +.nr hm 4v \" header margin +.nr tm 7v \" top margin +.nr bm 6v \" bottom margin +.nr fm 3v \" footer margin +.nr tf 3 \" title font: (real) Times Bold +.nr tp 10 \" title point size +.nr bi 4m \" indent for blocks +.nr pi 5n \" indent for paragraphs +.nr pf 1 \" normal text font +.nr pp 10 \" normal text point size +.nr qi 4n \" indent for quotes +.nr qp -1 \" down one point +.nr ii 5n \" indent for .ip's and .np's +.nr $m 1 \" max number of columns +.nr $s 4n \" column separation +.nr sf 3 \" section font -- Times Bold +.nr sp 10 \" section title pointsize +.nr ss 12p \" section prespacing +.nr si 0 \" section indent +.nr sx 0.2m \" super/subscript x-height adjustment +.nr no \w'0000'u \" offset for line numbers +. +.@R 0x\" set by GNU pic to _disable_ \x in super/scripting +. +.\" *** OTHER INITIALIZATION *** +. +.\" Define strings for super- and subscripting. groff me does not +.\" bother with half-line motions in nroff mode, since we have no output +.\" driver (for that mode) that supports them; consequently we don't +.\" emit \x escape sequences in that case either. If someone implements +.\" a Model 37 or line printer emulator we can target, this decision +.\" could be revisited. +.\" +.\" Adjust the line height with \x if the `0x` register is zero (a +.\" pic(1) convention) by the amount in `sx` (a groff 1.23 extension). +.ie t \ +\{\ +.ds { \v'-0.4m'\x'\\n(0x=0*-1u*\\n(sxu'\s-3 +.ds } \s+3\v'0.4m' +.\} +.el \ +\{\ +.ds { [\" +.ds } ]\" +.\} +.\" for compatibility with traditional -me +.\" (the first will work only in compatibility mode) +.ds [ \*{ +.ds ] \*} +.ds @< <\" +.ds @> >\" +.if \n(.g \ +\{\ +.do if c \(la .ds @< \(la\" +.do if c \(ra .ds @> \(ra\" +.\} +.ie t \ +\{\ +.ds < \v'0.4m'\x'\\n(0x=0*\\n(sxu'\s-3 +.ds > \s+3\v'-0.4m' +.\} +.el \ +\{\ +.ds < \*(@< +.ds > \*(@> +.\} +.ds - \(em +.\" Avoid warnings from groff -ww. +.@S |0 +.@S |1 +.@S |2 +.@S |3 +.@S $C +.@S $H +.@S $0 +.@S $1 +.@S $2 +.@S $3 +.@S $4 +.@S $5 +.@S $6 +.@S $7 +.@S $8 +.@S $9 +.@S .. +. +.@R po\" \" simulated page offset +.@R $0\" \" section depth +.@R $1\" \" section numbers a.b.c.d.e.f +.@R $2\" +.@R $3\" +.@R $4\" +.@R $5\" +.@R $6\" +.@R $i\" \" paragraph base indent +.@R $p\" \" numbered paragraph number +.\" [Before groff 1.06] the groff -me macros treated the $r and $R +.\" number registers in a way that was incompatible with the BSD -me +.\" macros. The reason for this was that the approach used by the BSD +.\" -me macros does not work with low resolution devices such as -TX75 +.\" and -TX100. However, this caused problems with existing -me +.\" documents. In [groff 1.06], the vertical spacing is controlled by +.\" the $v and $V registers which have the same meaning as $r and $R in +.\" earlier groff releases. In addition, if the $r or $R register is +.\" set to a value that would be correct for the BSD -me macros and a +.\" low resolution device is not being used, then an appropriate value +.\" for the $v or $V register is derived from the $r or $R register. +.\" +.\" Thirty years later, we rename `$v` to `tv` and `$V` to `dv`. +.@R $r\" \" ratio of vs to ps (may override tv) +.@R $R\" \" same for displays (may override dv) +.@R df\" \" display font: same as surrounding text +.@R so\" \" additional section title offset +.@R fu\" \" footnote undent +.@R bt\" \" block keep threshold +.@R *\" \" has \** been referenced? +.@R ?a\" \" pending floating keep at page top? +.@R ?b\" \" pending floating keep at page bottom? +.@R ?C\" \" at chapter header? +.@R ?e\" \" in equation? +.@R ?f\" \" inside footnote? +.@R _f\" \" column count of previous footnote +.@R ?H\" \" suppress headers and footers next page? +.@R ?I\" \" has the header trap been sprung? +.@R ?N\" \" numbering with shorter line length? +.@R ?n\" \" n1 mode? +.@R ?o\" \" footnote overflow? +.@R ?R\" \" renumbered chapter? +.@R ?s\" \" skip next page? +.@R ?T\" \" inside .TS H? +.@R ?W\" \" wide floating keep at page bottom? +.@R ?w\" \" wide floating keep at page top? +. +.nr fi 0.3i +.nr _o \n(.o +.nr $b 3 \" bold +.nr ps 0.35v +.if \n(ps<\n(.V .nr ps \n(.V +.nr bs \n(ps \" block pre/post spacing +.nr qs \n(ps \" quote pre/post spacing +.nr zs 1v \" float-block pre/postspacing +.nr xs 0.2v \" index prespacing +.nr xu 0.5i \" index undent +.nr fs 0.2v \" footnote prespacing +.nr es 0.5v \" equation pre/postspacing +.if \n(es<\n(.V .nr es \n(.V +.wh 0 @h \" set header +.nr $l \n(.lu \" line length (of column) +.nr _L \n(.lu \" line length of page +.nr $c 1 \" current column number +.nr $f 1 \" footnote number +.ds * \\*{\\n($f\\*}\k*\" \" footnote mark +.nr $d 1 \" delayed text number +.ds # [\\n($d]\" \" delayed text mark +.nr _M 1 \" encoded document segment type +.ds lq \(lq\" \" left quote +.ds rq \(rq\" \" right quote +.em @z +. +.\" Set line length and get .lt side effect. +.if t .ll \n(_Lu +.if n .ll 6.0i +. +.\" *** FOREIGN LETTERS AND SPECIAL CHARACTERS *** +. +. +.ds #h ((1u-(\\\\n(.fu%2u))*0.13m) +.ds #v 0.6m +. +.\" \" accents +.ds ' \h'0'\k_\h'-(\\n(.wu*8/10-\*(#h)'\(aa\h'|\\n_u' +.ds ` \h'0'\k_\h'-(\\n(.wu*7/10-\*(#h)'\(ga\h'|\\n_u' +. +.\" \" umlaut +.ds : \h'0'\k_\h'-(\\n(.wu*8/10-\*(#h+0.1m)'\v'-\*(#v'\z.\h'0.2m'.\h'|\\n_u'\v'\*(#v' +. +.\" \" circumflex and tilde +.ds ^ \h'0'\k_\h'-(\\n(.wu-\*(#h-0.05m)'^\h'|\\n_u' +.ds ~ \h'0'\k_\h'-(\\n(.wu-\*(#h-0.05m)'~\h'|\\n_u' +. +.\" \" cedilla and czech +.ds , \h'0'\k_\h'-(\\n(.wu)',\h'|\\n_u' +.ds v \h'0'\k_\h'-(\\n(.wu*9/10-\*(#h)'\v'-\*(#v'\s-4v\s0\v'\*(#v'\h'|\\n_u' +. +.\" \" Norwegian A or angstrom +.ds o \h'0'\k_\h'-(\\n(.wu+\w'\(de'u-\*(#h)/2u'\v'-0.4n'\z\(de\v'0.4n'\h'|\\n_u' +. +.\" \" there exists, for all +.ds qe \s-2\v'0.45m'\z\(em\v'-0.625m'\z\(em\v'-0.625m'\(em\v'0.8m'\s0\h'-0.1m'\v'-0.05m'\(br\v'0.05m'\h'0.1m' +.ds qa \z\e\h'0.35m'\z\(sl\h'-0.33m'\v'-0.3m'\s-4\(em\s0\v'0.3m'\h'0.15m' +.rm #h #v +. +.de @U +.do @err the '\\$1' macro is not supported by this version of 'me' +.. +. +.de lo +.@U lo +.. +. +.de th +.@U th +.. +. +.de ac +.@U ac +.. +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=nroff textwidth=72: diff --git a/tmac/ec.tmac b/tmac/ec.tmac new file mode 100644 index 0000000..9f04a13 --- /dev/null +++ b/tmac/ec.tmac @@ -0,0 +1,71 @@ +.\" Switch to EC fonts. +.\" +.\" Load this file before any language-specific stuff. +.\" +.\" hcode values are not handled. +.\" +. +.do nr *groff_ec_tmac_C \n[.cp] +.cp 0 +. +.ftr TR TREC +.ftr TI TIEC +.ftr TB TBEC +.ftr TBI TBIEC +. +.ftr HR HREC +.ftr HI HIEC +.ftr HB HBEC +.ftr HBI HBIEC +. +.ftr CW CWEC +.ftr CWI CWIEC +. +.ftr CR CWEC +.ftr C CWEC +.ftr CO CWIEC +.ftr CI CWIEC +.ftr CB CWEC +.ftr CBI CWIEC +.ftr TT CWEC +.ftr H HREC +. +.special MI S +.fspecial TREC TRTC TR +.fspecial TIEC TITC TI +.fspecial TBEC TBTC TB +.fspecial TBIEC TBITC TBI +.fspecial HREC HRTC HR +.fspecial HIEC HITC HI +.fspecial HBEC HBTC HB +.fspecial HBIEC HBIEC HBI +.fspecial CWEC CWTC SC CW +.fspecial CWIEC CWITC SC CWI +. +.\" remove definitions of glyphs which are in TC fonts +.rchar \[co] \[rg] +.rchar \[ct] +.rchar \[tm] +.rchar \[f/] +.rchar \[S1] \[S2] \[S3] +.rchar \[Of] \[Om] +.rchar \[Cs] +.rchar \[de] +. +.\" \[pl] and \[eq] must be roman +.char \[pl] \f[TREC]+ +.char \[eq] \f[TREC]= +. +.schar \[nm] \o'\f[TREC]/\[mo]' +. +.\" an ID register +.nr ECFONTS 1 +. +.cp \n[*groff_ec_tmac_C] +.do rr *groff_ec_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/en.tmac b/tmac/en.tmac new file mode 100644 index 0000000..441ca29 --- /dev/null +++ b/tmac/en.tmac @@ -0,0 +1,77 @@ +.\" English localization for groff +.\" +.\" Copyright (C) 2021-2022 Free Software Foundation, Inc. +.\" Written by G. Branden Robinson +.\" +.\" This file 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 +.\" . +.\" +.\" Please send comments to groff@gnu.org. +. +.do nr *groff_en_tmac_C \n[.cp] +.cp 0 +. +. +.\" If changing from an existing locale, we need to preserve the state +.\" of the "suppress hyphenation before a page location trap" bit. +.nr locale*use-trap-hyphenation-mode 0 +.if d locale \ +. if \n[.hy]=\n[\*[locale]*hyphenation-mode-trap] \ +. nr locale*use-trap-hyphenation-mode 1 +. +. +.ds locale english\" +. +.ss 12 +. +.\" Set up hyphenation. +. +.\" English hyphenation (\lefthyphenmin=2, \righthyphenmin=3) +.nr \*[locale]*hyphenation-mode-base 4 +.nr \*[locale]*hyphenation-mode-trap 6 +. +.ie \n[locale*use-trap-hyphenation-mode] \ +. hy \n[\*[locale]*hyphenation-mode-trap] +.el \ +. hy \n[\*[locale]*hyphenation-mode-base] +. +.rr locale*use-trap-hyphenation-mode +. +.hla en +.hpf hyphen.en +.hpfa hyphenex.en +. +. +.\" man package +.if d an \ +. an*reset-hyphenation-mode +. +. +.\" me package +.if d @R \{\ +. ds _td_format \\*(mo \\n(dy, \\n(y4\" +. ld +.\} +. +. +.cp \n[*groff_en_tmac_C] +.do rr *groff_en_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/eqnrc b/tmac/eqnrc new file mode 100644 index 0000000..84f8cf9 --- /dev/null +++ b/tmac/eqnrc @@ -0,0 +1,67 @@ +.\" -*- nroff -*- +.\" +.\" Startup file for eqn. +.do if !d EQ .ds EQ +.do if !d EN .ds EN +.EQ +sdefine << %{ < back 20 < }% +sdefine >> %{ > back 20 > }% + +sdefine dot %accent "\fR\(a.\fP"% +sdefine dotdot %accent "\fR\(ad\fP"% +sdefine vec %accent {up 52 "\s[\En[.s]/2u]\(->\s0"}% +sdefine dyad %accent {up 52 "\s[\En[.s]/2u]\(<>\s0"}% + +sdefine cdot %type "binary" \(md% + +ifdef X75 ! define X %1% ! +ifdef X100 ! define X %1% ! +ifdef X75-12 ! define X %1% ! +ifdef X100-12 ! define X %1% ! + +ifdef ps ! define ps|X|html %1% ! +ifdef X ! define ps|X|html %1% ! +ifdef html ! define ps|X|html %1% ! + +ifdef ps|X|html ! sdefine inf %"\s[\En[.s]*13u/10u]\v'12M'\(if\v'-12M'\s0"% ! + +ifdef dvi ! +sdefine int %{type "operator" vcenter \[integral]}% +sdefine sum %{type "operator" vcenter \[sum]}% +sdefine prod %{type "operator" vcenter \[product]}% +sdefine coprod %{type "operator" vcenter \[coproduct]}% +set num1 68 +set num2 39 +set denom1 69 +set denom2 34 +set sup1 41 +set sup2 36 +set sup3 29 +set sup_drop 39 +set sub_drop 5 +set axis_height 25 +set x_height 43 +set default_rule_thickness 4 +set big_op_spacing1 11 +set big_op_spacing2 16 +set big_op_spacing3 20 +set big_op_spacing4 60 +set big_op_spacing5 10 +! + +ifdef X ! set axis_height 32 ! + +ifdef ps|X|html ! set draw_lines 1 ! + +ifdef ascii ! define n %1% ! +ifdef latin1 ! define n %1% ! +ifdef utf8 ! define n %1% ! +ifdef cp1047 ! define n %1% ! +ifdef n ! +set nroff 1 +! + +undef X +undef ps|X|html +undef n +.EN diff --git a/tmac/europs.tmac b/tmac/europs.tmac new file mode 100644 index 0000000..c9236ac --- /dev/null +++ b/tmac/europs.tmac @@ -0,0 +1,44 @@ +.\" -*- nroff -*- +.\" +.\" europs.tmac +. +.do char \[eu] \f[EURO]\N'0' +. +.do if F AB .do fschar AB \[Eu] \f[EURO]\N'1' +.do if F ABI .do fschar ABI \[Eu] \f[EURO]\N'3' +.do if F AI .do fschar AI \[Eu] \f[EURO]\N'2' +.do if F AR .do fschar AR \[Eu] \f[EURO]\N'0' +.do if F BMB .do fschar BMB \[Eu] \f[EURO]\N'5' +.do if F BMBI .do fschar BMBI \[Eu] \f[EURO]\N'7' +.do if F BMI .do fschar BMI \[Eu] \f[EURO]\N'6' +.do if F BMR .do fschar BMR \[Eu] \f[EURO]\N'4' +.do if F CB .do fschar CB \[Eu] \f[EURO]\N'13' +.do if F CBI .do fschar CBI \[Eu] \f[EURO]\N'15' +.do if F CI .do fschar CI \[Eu] \f[EURO]\N'14' +.do if F CR .do fschar CR \[Eu] \f[EURO]\N'12' +.do if F HB .do fschar HB \[Eu] \f[EURO]\N'9' +.do if F HBI .do fschar HBI \[Eu] \f[EURO]\N'11' +.do if F HI .do fschar HI \[Eu] \f[EURO]\N'10' +.do if F HR .do fschar HR \[Eu] \f[EURO]\N'8' +.do if F HNB .do fschar HNB \[Eu] \f[EURO]\N'9' +.do if F HNBI .do fschar HNBI \[Eu] \f[EURO]\N'11' +.do if F HNI .do fschar HNI \[Eu] \f[EURO]\N'10' +.do if F HNR .do fschar HNR \[Eu] \f[EURO]\N'8' +.do if F NB .do fschar NB \[Eu] \f[EURO]\N'5' +.do if F NBI .do fschar NBI \[Eu] \f[EURO]\N'7' +.do if F NI .do fschar NI \[Eu] \f[EURO]\N'6' +.do if F NR .do fschar NR \[Eu] \f[EURO]\N'4' +.do if F PB .do fschar PB \[Eu] \f[EURO]\N'5' +.do if F PBI .do fschar PBI \[Eu] \f[EURO]\N'7' +.do if F PI .do fschar PI \[Eu] \f[EURO]\N'6' +.do if F PR .do fschar PR \[Eu] \f[EURO]\N'4' +.do if F TB .do fschar TB \[Eu] \f[EURO]\N'5' +.do if F TBI .do fschar TBI \[Eu] \f[EURO]\N'7' +.do if F TI .do fschar TI \[Eu] \f[EURO]\N'6' +.do if F TR .do fschar TR \[Eu] \f[EURO]\N'4' +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/fallbacks.tmac b/tmac/fallbacks.tmac new file mode 100644 index 0000000..162e57e --- /dev/null +++ b/tmac/fallbacks.tmac @@ -0,0 +1,214 @@ +.\" Define device-independent fallbacks for unavailable glyphs. +.\" +.\" These are designed such that "troffrc" loads them early, after +.\" composite glyph setup but before any device-specific fallbacks. +.\" Macro files specific to an output device can therefore override the +.\" definitions below as necessary. +. +.do nr *groff_fallbacks_tmac_C \n[.cp] +.cp 0 +. +.\" The early loading observation above also means that the conditional +.\" expressions 'n' and 't' are not reliable. Define ersatz substitute. +.nr fallbacks*troff-mode 1 +.if '\*[.T]'ascii' .nr fallbacks*troff-mode 0 +.if '\*[.T]'cp1047' .nr fallbacks*troff-mode 0 +.if '\*[.T]'latin1' .nr fallbacks*troff-mode 0 +.if '\*[.T]'utf8' .nr fallbacks*troff-mode 0 +. +.\" MODIFIER LETTER CIRCUMFLEX ACCENT -> CIRCUMFLEX ACCENT +.fchar \[u02C6] ^ +.\" SMALL TILDE -> TILDE +.fchar \[u02DC] ~ +.\" INCREMENT -> GREEK CAPITAL LETTER DELTA +.fchar \[u2206] \[u0394] +. +. +.\" NB: as per http://unicode.org/Public/UNIDATA/NamesList.txt +.\" +.\" #!/usr/bin/perl +.\" ## Ivan Shmakov, 2012. +.\" ## This code is in the public-domain. +.\" my $u; +.\" while (<>) { +.\" $u = oct ("0x" . $1) +.\" if (/^([[:xdigit:]]{4})/); +.\" next unless (defined ($u) && $u >= 0x2160 && $u <= 0x217F); +.\" if (/^\s+#\s+([[:xdigit:][:blank:]]+)(\s.*)?$/) { +.\" ## NB: may make sense to map to \[uXXXX]'s instead +.\" printf (".fchar \\[u%04x] %s\n", $u, +.\" pack ("U*", map { oct ("0x" . $_); } split (/ /, $1))); +.\" $u = undef; +.\" } +.\" } +. +.fchar \[u2160] I +.fchar \[u2161] II +.fchar \[u2162] III +.fchar \[u2163] IV +.fchar \[u2164] V +.fchar \[u2165] VI +.fchar \[u2166] VII +.fchar \[u2167] VIII +.fchar \[u2168] IX +.fchar \[u2169] X +.fchar \[u216a] XI +.fchar \[u216b] XII +.fchar \[u216c] L +.fchar \[u216d] C +.fchar \[u216e] D +.fchar \[u216f] M +.fchar \[u2170] i +.fchar \[u2171] ii +.fchar \[u2172] iii +.fchar \[u2173] iv +.fchar \[u2174] v +.fchar \[u2175] vi +.fchar \[u2176] vii +.fchar \[u2177] viii +.fchar \[u2178] ix +.fchar \[u2179] x +.fchar \[u217a] xi +.fchar \[u217b] xii +.fchar \[u217c] l +.fchar \[u217d] c +.fchar \[u217e] d +.fchar \[u217f] m +. +.\" Fonts often lack precomposed glyphs for accented Latin letters that +.\" were not defined in ISO 8859-1 (Latin-1). +.\" +.\" Some of these can be ugly; on typesetter devices, much depends on +.\" the design of the fonts used. +.\" +.\" groff defines no dot-above accent so we cannot construct some +.\" composite glyphs in this way. Turkish is an especial challenge +.\" because dotting an I (or not) results in a different base glyph. +.\" In any case, dotless 'i' base glyphs are rare in old fonts. +.\" +.\" Latin-2 fallbacks +.fchar \[A ab] \z\[ab]A +.fchar \[A ho] \z\[ho]A +.fchar \[C aa] \z\[aa]C +.fchar \[C ah] \z\[ah]C +.fchar \[D ah] \z\[ah]D +.fchar \[u110] \z-D\" capital letter d with stroke +.fchar \[E ah] \z\[ah]E +.fchar \[E ho] \z\[ho]E +.fchar \[/L] \z/L +.fchar \[L aa] \z\[aa]L +.fchar \[L ho] \z\[ho]L +.fchar \[N aa] \z\[aa]N +.fchar \[N ah] \z\[ah]N +.fchar \[O a"] \z\[a"]O +.fchar \[R aa] \z\[aa]R +.fchar \[R ah] \z\[ah]R +.fchar \[S aa] \z\[aa]S +.fchar \[S ac] \z\[ac]S +.fchar \[vS] \z\[ah]S +.fchar \[T ac] \z\[ac]T +.fchar \[T ah] \z\[ah]T +.fchar \[U ao] \z\[ao]U +.fchar \[U a"] \z\[a"]U +.fchar \[Z aa] \z\[aa]Z +.fchar \[Z a.] \z\[a.]Z +.fchar \[vZ] \z\[ah]Z +. +.fchar \[a ab] \z\[ab]a +.fchar \[a ho] \z\[ho]a +.fchar \[c aa] \z\[aa]c +.fchar \[c ah] \z\[ah]c +.fchar \[d ah] \z\[ah]d +.fchar \[u110] \z-d\" small letter d with stroke +.fchar \[e ah] \z\[ah]e +.fchar \[e ho] \z\[ho]e +.fchar \[/l] \z/l +.fchar \[l aa] \z\[aa]l +.fchar \[l ho] \z\[ho]l +.fchar \[n aa] \z\[aa]n +.fchar \[n ah] \z\[ah]n +.fchar \[o a"] \z\[a"]o +.fchar \[r aa] \z\[aa]r +.fchar \[r ah] \z\[ah]r +.fchar \[s aa] \z\[aa]s +.fchar \[s ac] \z\[ac]s +.fchar \[vs] \z\[ah]s +.fchar \[t ac] \z\[ac]t +.fchar \[t ah] \z\[ah]t +.fchar \[u ao] \z\[ao]u +.fchar \[u a"] \z\[a"]u +.fchar \[z aa] \z\[aa]z +.fchar \[z a.] \z\[a.]z +.fchar \[vz] \z\[ah]z +. +.\" Latin-5 fallbacks +.fchar \[G ab] \z\[ab]G +.fchar \[g ab] \z\[ab]g +. +.\" Latin-9 fallbacks +.fchar \[OE] OE +.fchar \[oe] oe +.fchar \[:Y] \z\[ad]Y +. +.fchar \[u2000] \[u2002]\" en quad +.fchar \[u2001] \[u2003]\" em quad +.fchar \[u2002] \h'1/2u'\" en space +.fchar \[u2003] \h'1'\" em space +.fchar \[u2004] \h'1/3u'\" three-per-em space +.fchar \[u2005] \h'1/4u'\" four-per-em space +.fchar \[u2006] \h'1/6u'\" six-per-em space +.fchar \[u2007] \0\" figure space +.fchar \[u2008] \^\" punctuation space +.fchar \[u2009] \|\" thin space +.fchar \[u200A] \^\" hair space +.\" Mapping U+200B awaits resolution of Savannah #58958. +.\"fchar \[u200B] \h'0'\" zero-width space +.\" \[u2010] is always defined thanks to uniglyph.cpp. +.\"fchar \[u2010] -\:\" hyphen +.\" Mapping U+2011 awaits resolution of Savannah #63354. +.\"fchar \[u2011] -\" non-breaking hyphen (won't break w/o .hcode or \:) +.ie \n[fallbacks*troff-mode] \ +. fchar \[u2012] \^\v'-.3m'\l'\w"\0"u'\v'+.3m'\^\" figure dash +.el \ +. fchar \[u2012] \- +.fchar \[u2013] \[en]\" en dash +.fchar \[u2014] \[em]\" em dash +.fchar \[u2015] \[em]\" horizontal bar (quotation dash) +.fchar \[u2016] \[ba]\[ba]\" double vertical line (matrix norm) +.if \n[fallbacks*troff-mode] \ +. fchar \[u2017] \Z'\[ul]'\v'+.1m'\[ul]\v'-.1m'\" double low line +.\" Mapping U+201[89CD] awaits resolution of Savannah #59932. +.\"fchar \[u2018] \[oq]\" left single quotation mark +.\"fchar \[u2019] \[cq]\" right single quotation mark +.\"fchar \[u201C] \[lq]\" left double quotation mark +.\"fchar \[u201D] \[rq]\" right double quotation mark +.\" XXX: The next two are troublesome; see Savannah #63332. +.\"fchar \[u2020] \[dg]\" dagger +.\"fchar \[u2021] \[dd]\" double dagger +.fchar \[u2022] \[bu]\" bullet +.fchar \[u2024] .\" one dot leader +.fchar \[u2025] .\|.\" two dot leader +.fchar \[u2026] .\|.\|.\" horizontal ellipsis +.fchar \[u2027] \[pc]\" hyphenation point +.\"fchar \[u2030] \[%0]\" per mille sign \" Savannah #63332 again +.fchar \[u2032] \[fm]\" prime +.fchar \[u2033] \[sd]\" double prime +.fchar \[u2039] \[fo]\" left single chevron +.fchar \[u203A] \[fc]\" right single chevron +.if \n[fallbacks*troff-mode] \ +. fchar \[u203D] \o'?!'\" interrobang +.\"fchar \[u203E] \[rn]\" overline \" Savannah #63332 again +.fchar \[u2044] \[f/]\" fraction slash +.fchar \[u2052] %\" commercial minus sign +.fchar \[u2053] \[ti]\" swung dash +. +.rr fallbacks*troff-mode +. +.cp \n[*groff_fallbacks_tmac_C] +.do rr *groff_fallbacks_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/fixmacros.sed b/tmac/fixmacros.sed new file mode 100644 index 0000000..56caf9f --- /dev/null +++ b/tmac/fixmacros.sed @@ -0,0 +1,7 @@ +# try to fix macros for AT&T troff so that they work without groff's -C switch +s/^\([.'][ ]*[^\\ ][^ \\]\)\([^ ]\)/\1 \2/ +s/^\(\\![.'][ ]*[^\\ ][^ \\]\)\([^ ]\)/\1 \2/ +s/\([.'][ ]*i[ef] *[^ ]* [.'][ ]*[^\\0-9 ][^ \\]\)\([^ ]\)/\1 \2/ +s/\([.'][ ]*i[ef] *[^ ]* \\{[.'][ ]*[^\\0-9 ][^ \\]\)\([^ ]\)/\1 \2/ +s/\([.'][ ]*[da]s *[^ \\][^ \\]\)\([^ ]\)/\1 \2/ +s/\\\*\[/\\*[[]/ diff --git a/tmac/fr.tmac b/tmac/fr.tmac new file mode 100644 index 0000000..c4719d1 --- /dev/null +++ b/tmac/fr.tmac @@ -0,0 +1,213 @@ +.\" French localization for groff +.\" +.\" Copyright (C) 2006-2022 Free Software Foundation, Inc. +.\" Written by Fabrice Ménard (menard.fabrice@wanadoo.fr) +.\" +.\" This file 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 +.\" . +.\" +.\" Please send comments to menard.fabrice@wanadoo.fr. +. +.do nr *groff_fr_tmac_C \n[.cp] +.cp 0 +. +. +.\" If changing from an existing locale, we need to preserve the state +.\" of the "suppress hyphenation before a page location trap" bit. +.nr locale*use-trap-hyphenation-mode 0 +.if d locale \ +. if \n[.hy]=\n[\*[locale]*hyphenation-mode-trap] \ +. nr locale*use-trap-hyphenation-mode 1 +. +. +.ds locale french\" +. +. +.\" Predefined text translations +. +.ds \*[locale]-abstract R\[E ']SUM\[E ']\" +.ds \*[locale]-app ANNEXE\" +.ds \*[locale]-appendix_string Annexe\" +.ds \*[locale]-april Avril\" +.ds \*[locale]-attribute_string par\" +.ds \*[locale]-august Ao\[u ^]t\" +.ds \*[locale]-chapter_string Chapitre\" +.ds \*[locale]-december D\[e ']cembre\" +.ds \*[locale]-draft_string Jet\" +.ds \*[locale]-endnote_string NOTES\" +.ds \*[locale]-february F\[e ']vrier\" +.ds \*[locale]-finis_string FIN\" +.ds \*[locale]-friday Vendredi\" +.ds \*[locale]-january Janvier\" +.ds \*[locale]-july Juillet\" +.ds \*[locale]-june Juin\" +.ds \*[locale]-le LISTE DES \[E ']QUATIONS\" +.ds \*[locale]-letapp LU ET APPROUV\[E ']\" +.ds \*[locale]-letat \[A `] L'ATTENTION DE:\" +.ds \*[locale]-letcn CONFIDENTIEL\" +.ds \*[locale]-letdate Date\" +.ds \*[locale]-letfc Veuillez agr\[e ']er, Monsieur, mes salutations distingu\[e ']es.\" +.ds \*[locale]-letns!0 Copie \[a `]\" +.ds \*[locale]-letns!1 Exemplaire (avec destinataire) \[a `]\" +.ds \*[locale]-letns!10 Exemplaire (avec destinataires) \[a `]\" +.ds \*[locale]-letns!11 Exemplaire (sans destinataires) \[a `]\" +.ds \*[locale]-letns!12 R\[e ']sum\[e '] \[a `]\" +.ds \*[locale]-letns!13 Memorandum complet \[a `]\" +.ds \*[locale]-letns!14 Cc:\" +.ds \*[locale]-letns!2 Exemplaire (sans destinataire) \[a `]\" +.ds \*[locale]-letns!3 Destinataire\" +.ds \*[locale]-letns!4 Destinataires\" +.ds \*[locale]-letns!5 Pi\[e `]ce jointe\" +.ds \*[locale]-letns!6 Pi\[e `]ces jointes\" +.ds \*[locale]-letns!7 Sous pli s\[e ']par\[e ']\" +.ds \*[locale]-letns!8 Lettre \[a `]\" +.ds \*[locale]-letns!9 Memorandum \[a `]\" +.ds \*[locale]-letns!copy Copie \" (il faut un espace)\" +.ds \*[locale]-letns!to " \[a `]\" +.ds \*[locale]-letrn En r\[e ']f\[e ']rence \[a `]:\" +.ds \*[locale]-letsa \[A `] la personne concern\[e ']e:\" +.ds \*[locale]-letsj SUJET:\" +.ds \*[locale]-lf LISTE DES ILLUSTRATIONS\" +.ds \*[locale]-licon SOMMAIRE\" +.ds \*[locale]-liec \[E ']quation\" +.ds \*[locale]-liex Document\" +.ds \*[locale]-lifg Illustration\" +.ds \*[locale]-litb Tableau\" +.ds \*[locale]-lt LISTE DES TABLEAUX\" +.ds \*[locale]-lx LISTE DES DOCUMENTS\" +.ds \*[locale]-man-section1 Manuel des commandes générales\" +.ds \*[locale]-man-section2 Manuel des appels systčme\" +.ds \*[locale]-man-section3 Manuel des fonctions de la bibliothčque\" +.ds \*[locale]-man-section4 Manuel des interfaces du noyau\" +.ds \*[locale]-man-section5 Manuel des formats de fichiers\" +.ds \*[locale]-man-section6 Manuel des jeux\" +.ds \*[locale]-man-section7 Manuel d'informations diverses\" +.ds \*[locale]-man-section8 Manuel du gestionnaire de systčme\" +.ds \*[locale]-man-section9 Manuel du développeur de noyau\" +.ds \*[locale]-march Mars\" +.ds \*[locale]-may Mai\" +.ds \*[locale]-monday Lundi\" +.ds \*[locale]-november Novembre\" +.ds \*[locale]-october Octobre\" +.ds \*[locale]-paper A4\" +.ds \*[locale]-qrf Cf. chapitre \\*[Qrfh], page \\*[Qrfp].\" +.ds \*[locale]-references Bibliographie\" +.ds \*[locale]-revision_string R\[e ']v.\" +.ds \*[locale]-rp BIBLIOGRAPHIE\" +.ds \*[locale]-saturday Samedi\" +.ds \*[locale]-september Septembre\" +.ds \*[locale]-sunday Dimanche\" +.ds \*[locale]-thursday Jeudi\" +.ds \*[locale]-toc Table des mati\[e `]res\" +.ds \*[locale]-toc_header_string Table des mati\[e `]res\" +.ds \*[locale]-tuesday Mardi\" +.ds \*[locale]-wednesday Mercredi\" +. +. +.\" Activate the translations +. +.mso trans.tmac +. +. +.\" ms package +.if r GS \{\ +. \" update the date +. ds DY \n[dy] \*[MO] \n[year] +. \" set hyphenation flags +. nr HY 6 +.\} +. +. +.\" mm package +.if d PH \{\ +. \" update the date with the new strings +. ds cov*new-date \\n[dy] \\*[MO\\n[mo]] \\n[year] +. +. \" ISODATE and DT update +. de ISODATE +. nr cov*mm \\n[mo] +. nr cov*dd \\n[dy] +. af cov*mm 01 +. af cov*dd 01 +. ie '0'\\$1' \ +. ds cov*new-date \\n[dy] \\*[MO\\n[mo]] \\n[year] +. el \ +. ds cov*new-date \\n[year]-\\n[cov*mm]-\\n[cov*dd] +. . +. +. als DT cov*new-date +.\} +. +. +.\" Default encoding +.mso latin9.tmac +. +.ss 12 0 +. +.\" Set up hyphenation. +. +.\" French hyphenation (\lefthyphenmin=2, \righthyphenmin=3) +.nr \*[locale]*hyphenation-mode-base 4 +.nr \*[locale]*hyphenation-mode-trap 6 +. +.ie \n[locale*use-trap-hyphenation-mode] \ +. hy \n[\*[locale]*hyphenation-mode-trap] +.el \ +. hy \n[\*[locale]*hyphenation-mode-base] +. +.rr locale*use-trap-hyphenation-mode +. +.hcode ŕ ŕ Ŕ ŕ +.hcode â â Â â +.hcode ç ç Ç ç +.hcode č č Č č +.hcode é é É é +.hcode ę ę Ę ę +.hcode ë ë Ë ë +.hcode î î Î î +.hcode ď ď Ď ď +.hcode ô ô Ô ô +.hcode ů ů Ů ů +.hcode ű ű Ű ű +.hcode ü ü Ü ü +.hcode ˙ ˙ ž ˙ +.hcode ˝ ˝ ź ˝ +. +.hla fr +.hpf hyphen.fr +. +. +.\" man package +.if d an \ +. an*reset-hyphenation-mode +. +. +.\" me package +.if d @R \{\ +. ds _td_format \En(dy \E*(mo \En(y4 +. ld +.\} +. +. +.cp \n[*groff_fr_tmac_C] +.do rr *groff_fr_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" coding: latin-9 +.\" fill-column: 72 +.\" End: +.\" vim: set fileencoding=iso-8859-15 filetype=groff textwidth=72: diff --git a/tmac/groff_man.7.man.in b/tmac/groff_man.7.man.in new file mode 100644 index 0000000..f98bee6 --- /dev/null +++ b/tmac/groff_man.7.man.in @@ -0,0 +1,4287 @@ +divert(-1) +Note to maintainers of this document: while it is desirable to bracket +material that differs between groff_man(7) and groff_man_style(7) as +tightly as possible to honor the Don't Repeat Yourself principle, in +GBR's opinion this maxim has limits. + +Consider this ghastly example: + +If no scaling unit is given, +the +.I man +package assumes \(lqn\(rq\c +_ifstyle()dnl +; that is, +approximately the width of the letter \(lqn\(rq in the font current when +the macro is called +(see section \(lqMeasurements\(rq in +.MR groff @MAN7EXT@ )\c +_endif()dnl +\&. + +These man pages serve multiple goals, one of which is to serve as a +model for good man page writing by people who examine their sources. + +After processing by m4, both child pages in the above case will carry \c +escape sequences followed by text lines starting with punctuation one +normally does not find in that position (and in the case of the period, +which has to be protected from interpretation as a control line). + +This is ugly, fragile, and unnecessary; all of these traits are +offensive to good pedagogy. + +Consequently, it is better to repeat a small amount of material than +write a man page that looks like the output of docbook-to-man. + +define(`_ifstyle',`ifdef(`_groff_man_style',,`divert(-1)')') +define(`_ifnotstyle',`ifdef(`_groff_man_style',`divert(-1)')') +define(`_endif',`divert`'') +divert`'dnl +'\" t +.\" This page is generated by m4 from tmac/groff_man.7.man.in. +_ifnotstyle()dnl +.TH groff_man @MAN7EXT@ "@MDATE@" "groff @VERSION@" +_endif()dnl +_ifstyle()dnl +.TH groff_man_style @MAN7EXT@ "@MDATE@" "groff @VERSION@" +_endif()dnl +.SH Name +_ifnotstyle()dnl +groff_man \- compose manual pages with GNU +.I roff +_endif()dnl +_ifstyle()dnl +groff_man_style \- GNU +.I roff +man page tutorial and style guide +_endif()dnl +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1999-2018, 2020-2021 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_groff_man_7_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY "groff \-man" +.RI [ option\~ .\|.\|.\&] +.RI [ file\~ .\|.\|.] +. +.SY "groff \-m man" +.RI [ option\~ .\|.\|.\&] +.RI [ file\~ .\|.\|.] +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +The GNU implementation of the +.I man +macro package is part of the +.I groff +document formatting system. +. +It is used to produce manual pages +.\" We use an unbreakable space \~ here to keep the phrase intact for +.\" its introduction; in subsequent discussion, that is not important. +(\(lqman\~pages\(rq) +like the one you are reading. +. +. +.P +This document presents the macros thematically; +for those needing only a quick reference, +the following table lists them alphabetically, +with cross references to appropriate subsections below. +. +. +_ifnotstyle()dnl +.P +Man page authors and maintainers who are not already experienced +.I groff +users should consult +.MR groff_man_style @MAN7EXT@ , +an expanded version of this document, +for additional explanations and advice. +. +It covers only those concepts required for man page document +maintenance, +and not the full breadth of the +.I groff +typesetting system. +. +. +_endif()dnl +.P +.TS +l l l. +Macro Meaning Subsection +.T& +lB l l. +_ +\&.B Bold Font style macros +\&.BI Bold, italic alternating Font style macros +\&.BR Bold, roman alternating Font style macros +\&.EE Example end Document structure macros +\&.EX Example begin Document structure macros +\&.I Italic Font style macros +\&.IB Italic, bold alternating Font style macros +\&.IP Indented paragraph Paragraphing macros +\&.IR Italic, roman alternating Font style macros +\&.LP Begin paragraph Paragraphing macros +\&.ME Mail-to end Hyperlink macros +\&.MR Man page cross reference Hyperlink macros +\&.MT Mail-to start Hyperlink macros +\&.P Begin paragraph Paragraphing macros +\&.PP Begin paragraph Paragraphing macros +\&.RB Roman, bold alternating Font style macros +\&.RE Relative inset end Document structure macros +\&.RI Roman, italic alternating Font style macros +\&.RS Relative inset start Document structure macros +\&.SB Small bold Font style macros +\&.SH Section heading Document structure macros +\&.SM Small Font style macros +\&.SS Subsection heading Document structure macros +\&.SY Synopsis start Command synopsis macros +\&.TH Title heading Document structure macros +\&.TP Tagged paragraph Paragraphing macros +\&.TQ Supplemental paragraph tag Paragraphing macros +\&.UE URI end Hyperlink macros +\&.UR URI start Hyperlink macros +\&.YS Synopsis end Command synopsis macros +.TE +. +. +.P +We discuss other macros +.RB ( .AT , +.BR .DT , +.BR .HP , +.BR .OP , +.BR .PD , +and +.BR .UC ) +in subsection \(lqDeprecated features\(rq below. +. +. +.P +Throughout Unix documentation, +a manual entry is referred to simply as a \(lqman page\(rq, +regardless of its length, +without gendered implication, +and irrespective of the macro package selected for its composition. +_ifstyle()dnl +. +. +.\" ==================================================================== +.\" .SS "Input file format" +.\" ==================================================================== +.P +Man pages should be encoded using Unicode basic Latin code points +exclusively, +and employ the Unix line-ending convention +(U+000A only). +.\" What about rare English words that require diacritics, and +.\" proper names that require more than basic Latin? +.\" +.\" sentence (including end-of-sentence detection) +.\" The above distinction works well with filling. +.\" Don't fill your input text yourself; let groff do the work. +.\" Also good for diffs. +.\" escape sequences--pretty much just "see Portability" +. +.\" ==================================================================== +.SS "Fundamental concepts" +.\" ==================================================================== +.\" font (family, style [elsewhere known as face]) +.\" type size +.\" typesetter (troff device, PostScript, PDF) +.\" terminal (nroff device, emulator, typewriter, TTY) +.I groff +is a programming system for typesetting: +we thus often use the verb \(lqto set\(rq in the sense +\(lqto typeset\(rq. +. +The formatter +.MR @g@troff @MAN1EXT@ +collects words from the input and +.I fills +output lines with as many as will fit. +. +.I Words +are separated by spaces and newlines. +.\" Also tabs and leaders, but let's not discuss those in man(7). +. +A transition to a new output line is called a +.I break. +. +When formatted, +a word may be broken at hyphens, +at +.B \e% +or +.B \e: +escape sequences +(see subsection \(lqPortability\(rq below), +or at predetermined locations +if automatic hyphenation is enabled +(see the +.B \-rHY +option in section \(lqOptions\(rq below). +. +An output line may be supplemented with +.I inter-sentence space, +and then optionally +.I adjusted +with more space to a consistent line length +(see the +.B \-dAD +option). +. +.MR roff @MAN7EXT@ +details these processes. +. +. +.P +An input line that starts with a dot (.\&) +or neutral apostrophe (\(aq) +is a +.I control line. +. +To call a macro, +put its name after a dot on a control line. +.\" You never need to indent macro calls in man(7), or call them with +.\" the no-break control character. +. +We refer to macros in this document using this leading dot. +. +Some macros interpret +.I arguments, +words that follow the macro name. +. +A newline, +unless escaped +(see subsection \(lqPortability\(rq below), +marks the end of the macro call. +. +An input line consisting of a dot followed by a newline +is called the +.I empty request; +it does nothing. +. +.I Text lines +are input lines that are not control lines. +. +. +.P +We describe below several +.I man +macros that plant one-line +.I input traps: +the next input line that directly produces formatted output is treated +specially. +. +For +.I man +documents that follow the advice in section +\[lq]Portability\[rq] below, +this means that control lines using the empty request +and uncommented input lines ending with an escaped newline +do not spring the trap; +anything else does +(but see the +.B .TP +macro description). +. +. +.\" ==================================================================== +.\" .SS "Why have a tutorial and style guide?" +.\" ==================================================================== +.\" the processing pipeline in brief +.\" preprocessors, roff itself, various output devices +.\" Things that aren't groff--why you want the man page language to be +.\" small (mandoc, Kerrisk's man7.org, manpages.debian.org, non-expert +.\" humans). +.\" possibly exhibit a horrorshow docbook-to-man example +_endif()dnl +. +. +.br +.ne 6v +.\" ==================================================================== +.SS "Macro reference preliminaries" +.\" ==================================================================== +. +A tagged paragraph describes each macro. +. +We present coupled pairs together, +as with +.B .EX +and +.BR .EE . +. +. +.br +.ne 2v +.P +_ifstyle()dnl +Optional macro arguments are indicated by surrounding them with square +brackets. +. +If a macro accepts multiple arguments, +those containing space \" or tab (in Plan 9 troff [only?]) +characters must be double-quoted to be interpreted correctly. +. +_endif()dnl +An empty macro argument can be specified with a pair of double-quotes +(""), +but the +.I man +package is designed such that this should seldom be necessary. +_ifstyle()dnl +. +See section \(lqNotes\(rq below for examples of cases where better +alternatives to empty arguments in macro calls are available. +_endif()dnl +. +Most macro arguments will be formatted as text in the output; +exceptions are noted. +. +. +.\" ==================================================================== +.SS "Document structure macros" +.\" ==================================================================== +. +Document structure macros organize a man page's content. +. +All of them break the output line. +. +.B .TH +(title heading) +identifies the document as a man page and configures the page headers +and footers. +. +Section headings +.RB ( .SH ), +one of which is mandatory and many of which are conventionally expected, +facilitate location of material by the reader and aid the man page +writer to discuss all essential aspects of the topic. +. +Subsection headings +.RB ( .SS ) +are optional and permit sections that grow long to develop in a +controlled way. +. +Many technical discussions benefit from examples; +lengthy ones, +especially those reflecting multiple lines of input to or output from +the system, +are usefully bracketed by +.B .EX +and +.BR .EE . +. +When none of the foregoing meets a structural demand, +use +.BR .RS / .RE +to inset a region within a (sub)section. +. +. +.TP +.BI .TH " topic section"\c +.RI " [" footer-middle ]\c +.RI " [" footer-inside ]\c +.RI " [" header-middle ] +Determine the contents of the page header and footer. +_ifstyle()dnl +. +.I roff +systems refer to these collectively as \(lqtitles\(rq. +_endif()dnl +. +The subject of the man page is +.I topic +and the section of the manual to which it belongs is +.I section. +_ifstyle()dnl +. +This use of \(lqsection\(rq has nothing to do with the section headings +otherwise discussed in this page; +it arises from the organizational scheme of printed and bound Unix +manuals. +_endif()dnl +. +See +.MR man 1 +or +.MR intro 1 +for the manual sectioning applicable to your system. +. +.I topic +and +.I section +are positioned together at the left and right in the header +(with +.I section +in parentheses immediately appended to +.IR topic ). +. +.I footer-middle +is centered in the footer. +. +The arrangement of the rest of the footer depends on whether +double-sided layout is enabled with the option +.BR \-rD1 . +. +When disabled (the default), +.I footer-inside +is positioned at the bottom left. +. +Otherwise, +.I footer-inside +appears at the bottom left on recto (odd-numbered) pages, +and at the bottom right on verso (even-numbered) pages. +. +The outside footer is the page number, +except in the continuous-rendering mode enabled by the option +.BR \-rcR=1 , +in which case it is the +.I topic +and +.I section, +as in the header. +. +.I header-middle +is centered in the header. +. +If +.I section +is an integer between 1 and\~9 (inclusive), +there is no need to specify +.I header-middle; +.I an.tmac +will supply text for it. +. +The macro package may also abbreviate +.I topic +and +.I footer-inside +with ellipses +_ifstyle()dnl +.RB ( .\|.\|.\& ) +_endif()dnl +if they would overrun the space available in the header and footer, +respectively. +. +For HTML output, +headers and footers are suppressed. +. +. +.IP +Additionally, +this macro breaks the page, +resetting the number to\~1 +(unless the +.B \-rC1 +option is given). +. +This feature is intended only for formatting multiple +.I man +documents in sequence. +. +. +.IP +A valid +.I man +document calls +.B .TH +once, +early in the file, +prior to any other macro calls. +_ifstyle()dnl +. +. +.IP +By convention, +.I footer-middle +is the date of the most recent modification to the man page source +document, +and +.I footer-inside +is the name and version or release of the project providing it. +_endif()dnl +. +. +.TP +.BR .SH " ["\c +.IR heading-text ] +Set +.I heading-text +as a section heading. +. +If no argument is given, +a one-line input trap is planted; +text on the next line +.\", which can be formatted with a macro, \" true but discouraged +becomes +.I heading-text. +. +The left margin is reset to zero to set the heading text in bold +(or the font specified by the string +.BR HF ), +and, +on typesetting devices, +slightly larger than the base type size. +. +If the heading font +.B \[rs]*[HF] +is bold, +use of an italic style in +.I heading-text +is mapped to the bold-italic style if available in the font family. +. +The inset level is reset to 1, +setting the left margin to the value of the +.B IN \" TODO: future: BP or BI register ("base paragraph indentation") +register. +. +Text after +.I heading-text +is set as an ordinary paragraph +.RB ( .P ). +. +. +.IP +The content of +.I heading-text +and ordering of sections follows a set of common practices, +as has much of the layout of material within sections. +. +For example, +a section called \(lqName\(rq or \(lqNAME\(rq must exist, +must be the first section after the +.B .TH +call, +and must contain only text of the form +.RS \" Invisibly move left margin to current .IP indentation. +.RS \" Now indent further, visibly. +.IR topic [\c +.BI , " another-topic"\c +.RB "].\|.\|.\& \e\- "\c +.I summary-description +.RE \" Move left margin back to .IP indentation. +for a man page to be properly indexed. +. +See +_ifnotstyle()dnl +.MR groff_man_style @MAN7EXT@ +for suggestions and +_endif()dnl +.MR man 7 +for the conventions prevailing on your system. +.RE \" Move left margin back to standard position. +. +. +.TP +.BR .SS " ["\c +.IR subheading-text ] +Set +.I subheading-text +as a subsection heading indented between a section heading and an +ordinary paragraph +.RB ( .P ). +. +If no argument is given, +a one-line input trap is planted; +text on the next line +.\", which can be formatted with a macro, \" true but discouraged +becomes +.I subheading-text. +. +The left margin is reset to the value of the +.B SN +register to set the heading text in bold +(or the font specified by the string +.BR HF ). +. +If the heading font +.B \[rs]*[HF] +is bold, +use of an italic style in +.I subheading-text +is mapped to the bold-italic style if available in the font family. +. +The inset level is reset to 1, +setting the left margin to the value of the +.B IN \" TODO: future: BP or BI register ("base paragraph indentation") +register. +. +Text after +.I subheading-text +is set as an ordinary paragraph +.RB ( .P ). +. +. +.TP +.B .EX +.TQ +.B .EE +Begin and end example. +. +After +.BR .EX , +filling is disabled and a constant-width (monospaced) font is selected. +. +Calling +.B .EE +enables filling and restores the previous font. +. +. +_ifstyle()dnl +.IP +Example regions are useful for formatting code, +shell sessions, +and text file contents. +. +An example region is not +a \(lqliteral mode\(rq +of any sort: +special character escape sequences must still be used to produce correct +glyphs for +.BR \(aq , +.BR \- , +.BR \(rs , +.BR \(ha , +.BR \(ga , +and +.BR \(ti , +and sentence endings are still detected and additional inter-sentence +space applied. +. +If the amount of additional inter-sentence spacing is altered, +the rendering of, +for instance, +regular expressions using +.B .\& +or +.B ?\& +followed by multiple spaces can change. +. +Use the dummy character escape sequence +.B \(rs& +before the spaces. +. +. +_endif()dnl +.IP +.\" Also see subsection "History" below... +These macros are extensions introduced in Ninth Edition Research Unix. +. +Systems running that +.IR troff , \" AT&T Research Unix +or those from +Documenter's Workbench, +Heirloom Doctools, +or Plan\~9 +.I troff +support them. +.\" Solaris 10 troff does not support .EX/.EE. Neatroff doesn't ship +.\" (m)an macros. +. +To be certain your page will be portable to systems that do not, +copy their definitions from the +.I \%an\-ext.tmac +file of a +.I groff +installation. +. +. +.TP +.BR .RS " ["\c +.IR inset-amount ] +Start a new relative inset level. +. +The position of the left margin is saved, +then moved right by +.I inset-amount, +if specified, +and by the amount of the +.B IN +register otherwise. +. +Calls to +.B .RS +can be nested; +each increments by\~1 +the inset level used by +.BR .RE . +. +The level prior to any +.B .RS +calls is\~1. +. +. +.TP +.BR .RE " ["\c +.IR level ] +End a relative inset. +. +The left margin corresponding to inset level +.I level +is restored. +. +If no argument is given, +the inset level is reduced by\~1. +. +. +.\" ==================================================================== +.SS "Paragraphing macros" +.\" ==================================================================== +. +An ordinary paragraph +.RB ( .P ) +_ifstyle()dnl +like this one +_endif()dnl +is set without a first-line indentation at the current left margin. +. +In man pages and other technical literature, +definition lists are frequently encountered; +these can be set as \(lqtagged paragraphs\(rq, +which have one +.RB ( .TP ) +or more +.RB ( .TQ ) +leading tags followed by a paragraph that has an additional indentation. +. +The indented paragraph +.RB ( .IP ) +macro is useful to continue the indented content of a narrative started +with +.BR .TP , +or to present an itemized or ordered list. +. +All of these macros break the output line. +. +If another paragraph macro has occurred since the previous +.B .SH +or +.BR .SS , +they +(except for +.BR .TQ ) +follow the break with a default amount of vertical space, +which can be changed by the deprecated +.B .PD +macro; +see subsection \(lqHorizontal and vertical spacing\(rq below. +. +They also reset the type size and font style to defaults +.RB ( .TQ +again excepted); +see subsection \(lqFont style macros\(rq below. +. +. +.br +.ne 4v +.TP +.B .P +.TQ +.B .LP +.TQ +.B .PP +Begin a new paragraph; +these macros are synonymous. +. +The indentation is reset to the default value; +the left margin, +as affected by +.B .RS +and +.BR .RE , +is not. +. +. +.TP +.BR .TP " ["\c +.IR indentation ] +Set a paragraph with a leading tag, +and the remainder of the paragraph indented. +. +A one-line input trap is planted; +text on the next line, +which can be formatted with a macro, +becomes the tag, +which is placed at the current left margin. +. +The tag can be extended with the +.B \(rsc +escape sequence. +. +Subsequent text is indented by +.I indentation, +if specified, +and by the amount of the +.B IN +register otherwise. +. +If the tag is not as wide as the indentation, +the paragraph starts on the same line as the tag, +at the applicable indentation, +and continues on the following lines. +. +Otherwise, +the descriptive part of the paragraph begins on the line following the +tag. +_ifstyle()dnl +. +. +.IP +The line containing the tag can `include' a macro call, +for instance to set the tag in bold with +.BR .B . +. +.B .TP +was used to write the first paragraph of this description of +.BR .TP , +and +.B .IP +the subsequent one. +_endif()dnl +. +. +.TP +.B .TQ +Set an additional tag for a paragraph tagged with +.BR .TP . +. +An input trap is planted as with +.BR .TP . +. +. +.IP +This macro is a GNU extension not defined on systems running +AT&T, +Plan\~9, +or +Solaris +.IR troff ; +see +.I \%an\-ext.tmac +in section \(lqFiles\(rq below. +_ifstyle()dnl +. +. +.IP +The descriptions of +.BR .P , +.BR .LP , +and +.B .PP +above were written using +.B .TP +and +.BR .TQ . +_endif()dnl +. +. +.TP +.BR .IP " ["\c +.IR tag "] "\c +.RI [ indentation ] +Set an indented paragraph with an optional tag. +. +The +.I tag +and +.I indentation +arguments, +if present, +are handled as with +.BR .TP , +with the exception that the +.I tag +argument to +.B .IP +cannot `include' a macro call. +. +. +_ifstyle()dnl +.IP +Two convenient uses for +.B .IP +are +. +. +.RS \" Invisibly move left margin to current .IP indentation. +.RS 4n \" Now indent further, visibly. +.IP (1) 4n +to start a new paragraph with the same indentation as an immediately +preceding +.B .IP +or +.B .TP +paragraph, +if no +.I indentation +argument is given; +and +. +. +.IP (2) +to set a paragraph with a short +.I tag +that is not semantically important, +such as a bullet (\(bu)\(emobtained with the +.B \e(bu +special character escape sequence\(emor list enumerator, +as seen in this very paragraph. +.RE \" Move left margin back to .IP indentation. +.RE \" Move left margin back to standard position. +. +. +_endif()dnl +.\" ==================================================================== +.SS "Command synopsis macros" +.\" ==================================================================== +. +.B .SY +and +.B .YS +aid you to construct a command synopsis that has the classical Unix +appearance. +. +They break the output line. +. +.\" TODO: Determine whether this (is still? was ever?) true. +.\" Furthermore, +.\" some tools are able to interpret these macros semantically and treat +.\" them appropriately for localization and/or presentation. +. +. +.P +These macros are GNU extensions not defined on systems running +AT&T, +Plan\~9, +or +Solaris +.IR troff ; +see +.I \%an\-ext.tmac +in section \(lqFiles\(rq below. +. +. +.TP +.BI .SY " command" +Begin synopsis. +. +A new paragraph begins at the left margin +_ifstyle()dnl +(as with +.BR .P ) +_endif()dnl +unless +.B .SY +has already been called without a corresponding +.BR .YS , +in which case only a break is performed. +. +Adjustment and automatic hyphenation are disabled. +. +.I command +is set in bold. +. +If a break is required, +lines after the first are indented by the width of +.I command +plus a space. +. +. +.TP +.B .YS +End synopsis. +. +Indentation, +adjustment, +and hyphenation +are restored to their previous states. +_ifstyle()dnl +. +. +.P +Multiple +.BR .SY / .YS +blocks can be specified, +for instance to distinguish differing modes of operation of a complex +command like +.MR tar 1 ; +each will be vertically separated as paragraphs are. +. +. +.P +.B .SY +can be repeated before +.B .YS +to indicate synonymous ways of invoking a particular mode of operation. +. +. +.br +.ne 2v +.P +.IR groff 's +own command-line interface serves to illustrate most of the specimens +of synopsis syntax one is likely to encounter. +. +. +.IP +.\" from src/roff/groff/groff.1.man +.EX +\&.SY groff +\&.RB [ \e-abcCeEgGijklNpRsStUVXzZ ] +\&.RB [ \e-d\e\(ti\ec +\&.IR cs ] +\&.RB [ \e-d\e\(ti\ec +\&.IB name =\ec +\&.IR string ] +\&.RB [ \e-D\e\(ti\ec +\&.IR enc ] +.EE +. +.I (and so on similarly) +. +.EX +\&.RI [ file\e\(ti .\e|.\e|.] +\&.YS +\&. +\&. +\&.SY groff +\&.B \e-h +\&. +\&.SY groff +\&.B \e-\e-help +\&.YS +\&. +\&. +\&.SY groff +\&.B \e-v +\&.RI [ option\e\(ti .\e|.\e|.\e&] +\&.RI [ file\e\(ti .\e|.\e|.] +\&. +\&.SY groff +\&.B \e-\e-version +\&.RI [ option\e\(ti .\e|.\e|.\e&] +\&.RI [ file\e\(ti .\e|.\e|.] +\&.YS +.EE +. +. +.P +produces the following output. +. +. +.RS +.SY groff +.RB [ \-abcCeEgGijklNpRsStUVXzZ ] +.RB [ \-d\~\c +.IR cs ] +.RB [ \-d\~\c +.IB name =\c +.IR string ] +.RB [ \-D\~\c +.IR enc ] +.RB [ \-f\~\c +.IR fam ] +.RB [ \-F\~\c +.IR dir ] +.RB [ \-I\~\c +.IR dir ] +.RB [ \-K\~\c +.IR enc ] +.RB [ \-L\~\c +.IR arg ] +.RB [ \-m\~\c +.IR name ] +.RB [ \-M\~\c +.IR dir ] +.RB [ \-n\~\c +.IR num ] +.RB [ \-o\~\c +.IR list ] +.RB [ \-P\~\c +.IR arg ] +.RB [ \-r\~\c +.IR cn ] +.RB [ \-r\~\c +.IB reg =\c +.IR expr ] +.RB [ \-T\~\c +.IR dev ] +.RB [ \-w\~\c +.IR name ] +.RB [ \-W\~\c +.IR name ] +.RI [ file\~ .\|.\|.] +.YS +. +. +.SY groff +.B \-h +. +.SY groff +.B \-\-help +.YS +. +. +.SY groff +.B \-v +.RI [ option\~ .\|.\|.\&] +.RI [ file\~ .\|.\|.] +. +.SY groff +.B \-\-version +.RI [ option\~ .\|.\|.\&] +.RI [ file\~ .\|.\|.] +.YS +.RE +. +. +.P +Several features of the above example are of note. +. +. +.IP \(bu 2n +The empty request (.), +which does nothing, +is used to vertically space the input file for readability by the +document maintainer. +. +Do not put blank (empty) lines in a man page source document. +. +. +.IP \(bu +Command and option names are presented in +.B bold +to cue the user that they should be input literally. +. +. +.IP \(bu +Option dashes are specified with the +.B \e\- +escape sequence; +this is an important practice to make them clearly visible and to +facilitate copy-and-paste from the rendered man page to a shell prompt +or text file. +. +. +.IP \(bu +Option arguments and command operands are presented in +.I italics +(but see subsection \(lqFont style macros\(rq below regarding terminals) +to cue the user that they must be replaced with appropriate text. +. +. +.IP \(bu +Symbols that are neither to be typed literally nor replaced at the +user's discretion appear in the roman style; +brackets surround optional arguments, +and an ellipsis indicates that the previous syntactical element may be +repeated arbitrarily. +. +. +.IP \(bu +The non-breaking adjustable space escape sequence +.B \e\(ti +is used to prevent the output line from being broken within the option +brackets; +see subsection \(lqPortability\(rq below. +. +. +.IP \(bu +The output line continuation escape sequence +.B \ec +is used with font style alternation macros to allow all three font +styles to be set without (breakable) space among them; +see subsection \(lqPortability\(rq below. +. +. +.IP \(bu +The dummy character escape sequence +.B \e& +follows the ellipsis when further text will follow after space on the +output line, +keeping its last period from being interpreted as the end of a +sentence +.\" ...because it is followed by characters that are transparent to +.\" end-of-sentence detection, and a newline... +and causing additional inter-sentence space to be placed after it. +. +See subsection \(lqPortability\(rq below. +_endif()dnl +. +. +.\" ==================================================================== +.SS "Hyperlink macros" +.\" ==================================================================== +. +Man page cross references +_ifstyle()dnl +like +.MR ls 1 +_endif()dnl +are best presented with +.BR .MR . +. +Text may be hyperlinked to email addresses with +.BR .MT / .ME +or other URIs with +.BR .UR / .UE . +. +Hyperlinked text is supported on HTML +.\", PDF, +and terminal output devices; +terminals and pager programs must support ECMA-48 OSC\~8 escape +sequences +(see +.MR grotty @MAN1EXT@ ). +. +When device support is unavailable or disabled with the +.B U +register +(see section \[lq]Options\[rq] below), +.B .MT +and +.B .UR +URIs are rendered between angle brackets after the linked text. +. +. +.P +.BR .MT , +.BR .ME , +.BR .UR , +and +.B .UE +are GNU extensions not defined on systems running +AT&T, +Plan\~9, +or +Solaris +.IR troff ; \" Solaris +see +.I \%an\-ext.tmac +in section \(lqFiles\(rq below. +. +Plan\~9 from User Space's +.I troff \" plan9port +implements +.BR .MR . +. +. +.P +The arguments to +.BR .MR , +.BR .MT , +and +.B .UR +should be prepared for typesetting since they can appear in the +output. +. +Use special character escape sequences to encode Unicode basic Latin +characters where necessary, +particularly the hyphen-minus. +_ifstyle()dnl +. +(See section \[lq]Portability\[rq] below.) +. +URIs can be lengthy; +rendering them can result in jarring adjustment or variations in line +length, +or +.I @g@troff +warnings when a hyperlink is longer than an output line. +. +The application of non-printing break point escape sequences +.B \e: +after each slash +(or series thereof), +and before each dot +(or series thereof) +is recommended as a rule of thumb. +. +The former practice avoids forcing a trailing slash in a URI onto a +separate output line, +and the latter helps the reader to avoid mistakenly interpreting a dot +at the end of a line as a period +(or multiple dots as an ellipsis). +. +Thus, +.RS +.EX +\&.UR http://\e:example\e:.com/\e:fb8afcfbaebc74e\e:.cc +.EE +.RE +has several potential break points in the URI shown. +. +Consider adding break points before or after at signs in email +addresses, +and question marks, +ampersands, +and number signs in HTTP(S) URIs. +. +_endif()dnl +The formatter removes +.B \e: +escape sequences from hyperlinks when supplying device control commands +to output drivers. +. +. +.TP +.BI .MR "\~topic manual-section"\c +.RI \~[ trailing-text ] +.IR (since\~ groff \~1.23) \" TODO: remove note once novelty dies down +Set a man page cross reference as +\[lq]\c +.IB topic ( manual-section )\c +\[rq]. +. +If +.I trailing-text +(typically punctuation) +is specified, +it follows the closing parenthesis without intervening space. +. +Hyphenation is disabled while the cross reference is set. +. +.I topic +is set in the font specified by the +.B MF +string. +. +The cross reference hyperlinks to a URI of the form +.RB \[lq] man:\c +.IR topic ( manual-section )\[rq]. +_ifstyle()dnl +. +. +.RS +.IP +.EX +The output driver +\&.MR grops @MAN1EXT@ +produces PostScript from +\&.I troff +output. +\&. +The Ghostscript program (\[rs]c +\&.MR gs 1 ) +interprets PostScript and PDF. +.EE +.RE +_endif()dnl +. +. +.TP +.BI .MT " address" +.TQ +.BR .ME " ["\c +.IR trailing-text ] +Identify +.I address +as an RFC 6068 +.I addr-spec +for a \(lqmailto:\(rq URI with the text between the two macro +calls as the link text. +. +An argument to +.B .ME +is placed after the link text without intervening space. +. +.I address +may not be visible in the rendered document if hyperlinks are enabled +and supported by the output driver. +. +If they are not, +.I address +is set in angle brackets after the link text and before +.I trailing-text. +. +If hyperlinking is enabled but there is no link text, +.I address +is formatted and hyperlinked +.I without +angle brackets. +_ifstyle()dnl +. +. +.br +.ne 6v +.IP +When rendered by +.I groff +to a PostScript device, +.RS +.IP +.EX +Contact +\&.MT fred\e:.foonly@\e:fubar\e:.net +Fred Foonly +\&.ME +for more information. +.EE +.RE +. +. +.IP +displays as \(lqContact Fred Foonly \(lafred\:.foonly@\:fubar\:.net\(ra +for more information.\(rq. +_endif()dnl +. +. +.TP +.BI .UR " uri" +.TQ +.BR .UE " ["\c +.IR trailing-text ] +Identify +.I uri +as an RFC 3986 URI hyperlink with the text between the two macro calls +as the link text. +. +An argument to +.B .UE +is placed after the link text without intervening space. +. +.I uri +may not be visible in the rendered document if hyperlinks are enabled +and supported by the output driver. +. +If they are not, +.I uri +is set in angle brackets after the link text and before +.I trailing-text. +. +If hyperlinking is enabled but there is no link text, +.I uri +is formatted and hyperlinked +.I without +angle brackets. +_ifstyle()dnl +. +. +.IP +When rendered by +.I groff +to a PostScript device, +.RS +.IP +.EX +The GNU Project of the Free Software Foundation +hosts the +\&.UR https://\e:www\e:.gnu\e:.org/\e:software/\e:groff/ +\&.I groff +home page +\&.UE . +.EE +.RE +. +. +.IP +displays as \(lqThe GNU Project of the Free Software Foundation hosts +the +.I groff +home page +\(lahttps://\:www\:.gnu\:.org/\:software/\:groff/\(ra.\(rq. +_endif()dnl +. +. +.P +The hyperlinking of +.B .TP +paragraph tags with +.BR .UR / .UE +and +.BR .MT / .ME +is not yet supported; +if attempted, +the hyperlink will be typeset at the beginning of the indented paragraph +even on hyperlink-supporting devices. +. +. +.\" ==================================================================== +.SS "Font style macros" +.\" ==================================================================== +. +The +.I man +macro package is limited in its font styling options, +offering only +.BR bold \~( .B ), +.I italic\c +.RB \~( .I ), +and roman. +. +Italic text is usually set underscored instead on terminal devices. +. +The +.B .SM +and +.B .SB +macros set text in roman or bold, +respectively, +at a smaller type size; +these differ visually from regular-sized roman or bold text only on +typesetting devices. +. +It is often necessary to set text in different styles without +intervening space. +. +The macros +.BR .BI , +.BR .BR , +.BR .IB , +.BR .IR , +.BR .RB , +and +.BR .RI , +where \(lqB\(rq, +\(lqI\(rq, +and \(lqR\(rq indicate bold, +italic, +and roman, +respectively, +set their odd- and even-numbered arguments in alternating styles, +with no space separating them. +_ifstyle()dnl +. +. +.P +Because font styles are presentational rather than semantic, +conflicting traditions have arisen regarding which font styles should be +used to mark file or path names, +environment variables, +and inlined literals. +_endif()dnl +. +. +.br +.ne 2v +.P +The default type size and family for typesetting devices is 10-point +Times, +except on the +.B \%X75\-12 +and +.B \%X100\-12 +devices where the type size is 12 points. +. +The default style is roman. +. +. +.TP +.BR .B \~[\c +.IR text ] +Set +.I text +in bold. +. +If no argument is given, +a one-line input trap is planted; +text on the next line, +which can be further formatted with a macro, +is set in bold. +. +. +_ifstyle()dnl +.IP +Use bold +for literal portions of syntax synopses, +for command-line options in running text, +and for literals that are major topics of the subject under discussion; +for example, +this page uses bold for macro, +string, +and register names. +. +In an +.BR .EX / .EE +example of interactive I/O +(such as a shell session), +set only user input in bold. +. +. +. +_endif()dnl +.TP +.BR .I \~[\c +.IR text ] +Set +.I text +in an italic or oblique face. +. +If no argument is given, +a one-line input trap is planted; +text on the next line, +which can be further formatted with a macro, +is set in an italic or oblique face. +. +. +_ifstyle()dnl +.IP +Use italics +for file and path names, +for environment variables, +for C data types, +for enumeration or preprocessor constants in C, +for variant (user-replaceable) portions of syntax synopses, +for the first occurrence (only) of a technical concept being introduced, +for names of journals and of literary works longer than an article, +and anywhere a parameter requiring replacement by the user is +encountered. +. +An exception involves variant text in a context already typeset in +italics, +such as file or path names with replaceable components; +in such cases, +follow the convention of mathematical typography: +set the file or path name in italics as usual +but use roman for the variant part +(see +.B .IR +and +.B .RI +below), +and italics again in running roman text when referring to the variant +material. +. +. +_endif()dnl +.TP +.BR .SM \~[\c +.IR text ] +Set +.I text +one point smaller than the default type size on typesetting devices. +. +If no argument is given, +a one-line input trap is planted; +text on the next line, +which can be further formatted with a macro, +is set smaller. +. +. +_ifstyle()dnl +.IP +.I Note: +terminals will render +.I text +at normal size instead. +. +Do not rely upon +.B .SM +to communicate semantic information distinct from using roman style at +normal size; +it will be hidden from readers using such devices. +. +. +_endif()dnl +.TP +.BR .SB \~[\c +.IR text ] +Set +.I text +in bold and +(on typesetting devices) +one point smaller than the default type size. +. +If no argument is given, +a one-line input trap is planted; +text on the next line, +which can be further formatted with a macro, +is set smaller and in bold. +. +This macro is an extension introduced in SunOS\~4.0. +. +. +_ifstyle()dnl +.IP +.I Note: +terminals will render +.I text +in bold at the normal size instead. +. +Do not rely upon +.B .SB +to communicate semantic information distinct from using bold style at +normal size; +it will be hidden from readers using such devices. +. +. +.P +Observe what is +.I not +prescribed for setting in bold or italics above: +elements of \(lqsynopsis language\(rq such as ellipses and brackets +around options; +proper names and adjectives; +titles of anything other than major works of literature; +identifiers for standards documents or technical reports such as +CSTR\~#54, +RFC\~1918, +Unicode\~13.0, +or +POSIX.1-2017; +acronyms; +and occurrences after the first of a technical term. +. +. +.P +Be frugal with italics for emphasis, +and particularly with bold. +. +Article titles and brief runs of literal text, +such as references to individual characters or short strings, +including section and subsection headings of man pages, +are suitable objects for quotation; +see the +.BR \e(lq , +.BR \e(rq , +.BR \e(oq , +and +.B \e(cq +escape sequences in subsection \(lqPortability\(rq below. +. +. +_endif()dnl +.P +Unlike the above font style macros, +the font style alternation macros below set no input traps; +they must be given arguments to have effect. +. +Italic corrections are applied as appropriate. +. +_ifstyle()dnl +If a space is required within an argument, +first consider whether the same result could be achieved with as much +clarity by using single-style macros on separate input lines. +. +When it cannot, +double-quote an argument containing embedded space characters. +. +Setting all three different styles within a word +presents challenges; +it is possible with the +.B \ec +and/or +.B \ef +escape sequences. +. +See subsection \(lqPortability\(rq +below for approaches. +_endif()dnl +. +. +.TP +.BI .BI " bold-text italic-text "\c +\&.\|.\|.\& +Set each argument in bold and italics, +alternately. +. +. +_ifstyle()dnl +.RS +.IP +.\" from src/roff/troff/troff.1.man +.EX +\&.BI \-r\~ register = numeric-expression +.EE +.RE +. +. +_endif()dnl +.TP +.BI .BR " bold-text roman-text "\c +\&.\|.\|.\& +Set each argument in bold and roman, +alternately. +. +. +_ifstyle()dnl +.RS +.IP +.\" from tmac/groff_ms.7.man +.EX +After +\&.B .NH +is called, +.EE +.RE +. +. +_endif()dnl +.TP +.BI .IB " italic-text bold-text "\c +\&.\|.\|.\& +Set each argument in italics and bold, +alternately. +. +. +_ifstyle()dnl +.RS +.IP +.\" from src/preproc/pic/pic.1.man +.EX +In places where +\&.IB n th +is allowed, +.EE +.RE +. +. +_endif()dnl +.TP +.BI .IR " italic-text roman-text "\c +\&.\|.\|.\& +Set each argument in italics and roman, +alternately. +. +. +_ifstyle()dnl +.RS +.IP +.\" from src/preproc/pic/pic.1.man +.EX +Use GNU +\&.IR pic \[aq]s +\&.B figname +command to change the name of the vbox. +.EE +.RE +. +. +_endif()dnl +.TP +.BI .RB " roman-text bold-text "\c +\&.\|.\|.\& +Set each argument in roman and bold, +alternately. +. +. +_ifstyle()dnl +.RS +.IP +.\" from src/preproc/pic/pic.1.man +.EX +if +\&.I file +is +\&.RB \[rs][lq] \[rs]\- \[rs][rq], +the standard input stream is read. +.RE +.EE +. +. +_endif()dnl +.TP +.BI .RI " roman-text italic-text "\c +\&.\|.\|.\& +Set each argument in roman and italics, +alternately. +. +. +_ifstyle()dnl +.RS +.IP +.\" from src/preproc/pic/pic.1.man +.EX +\&.RI ( tpic +was a fork of AT&T +\&.I pic \" AT&T +by Tim Morgan of the University of California at Irvine +.EE +.RE +. +. +_endif()dnl +.\" ==================================================================== +.SS "Horizontal and vertical spacing" +.\" ==================================================================== +. +The +.I indentation +argument accepted by +.BR .IP , +.BR .TP , +and the deprecated +.B .HP +is a number plus an optional scaling unit, +as is +.BR .RS 's +.IR inset-amount . +. +If no scaling unit is given, +the +.I man +_ifstyle()dnl +package assumes \(lqn\(rq; +that is, +the width of a letter \(lqn\(rq in the font current when the macro is +called +(see section \(lqMeasurements\(rq in +.MR groff @MAN7EXT@ ). +_endif()dnl +_ifnotstyle()dnl +package assumes \(lqn\(rq. +_endif()dnl +. +An indentation specified in a call to +.BR .IP , +.BR .TP , +or the deprecated +.B .HP +persists until +(1) another of these macros is called with an +.I indentation +argument, +or +(2) +.BR .SH , +.BR .SS , +or +.B .P +or its synonyms is called; +these clear the indentation entirely. +. +. +.P +The left margin used by ordinary paragraphs set with +.B .P +(and its synonyms) +not within an +.BR .RS / .RE +relative inset +.\" TODO: future: BP or BI register ("base paragraph indentation") +is 7.2n for typesetting devices +and 7n for terminal devices +(but see the +.B \-rIN +option). +. +Headers, +footers +(both set with +.BR .TH ), +and section headings +.RB ( .SH ) +are set at the page offset +(see +.MR groff @MAN7EXT@ ) +and subsection headings +.RB ( .SS ) +indented from it by 3n +(but see the +.B \-rSN +option). +. +.\" XXX: This is not true, but they do handle it badly. +.\" HTML output devices ignore indentation. +_ifstyle()dnl +. +. +.P +It may be helpful to think of the left margin and indentation as related +but distinct concepts; +.IR groff 's +implementation of the +.I man +macro package tracks them separately. +. +The left margin is manipulated by +.B .RS +and +.B .RE +(and by +.\".BR .TH ,\" True but not to be encouraged within a document. +.B .SH +and +.BR .SS , +which reset it to the default). +. +Indentation is controlled by the paragraphing macros +(though, +again, +.\".BR .TH , +.B .SH +and +.B .SS +reset it); +it is imposed by the +.BR .TP , +.BR .IP , +and deprecated +.B .HP +macros, +and cancelled by +.B .P +and its synonyms. +. +An extensive example follows. +. +. +.P +This ordinary +.RB ( .P ) +paragraph is not in a relative inset nor does it possess an indentation. +. +. +.RS +.P +Now we have created a relative inset +(in other words, +moved the left margin) +with +.B .RS +and started another ordinary paragraph with +.BR .P . +. +. +.TP +.B tag +This tagged paragraph, +set with +.BR .TP , +is still within the +.B .RS +region, +but lines after the first have a supplementary indentation that the +tag lacks. +. +. +.IP +A paragraph like this one, +set with +.BR .IP , +will appear to the reader as also associated with the tag above, +because +.B .IP +re-uses the previous paragraph's indentation unless given an argument +to change it. +. +This paragraph is affected both by the moved left margin +.RB ( .RS ) +and indentation +.RB ( .IP ). +. +.TS +box; +l. +This table is affected both by +the left margin and indentation. +.TE +. +. +.IP \(bu +This indented paragraph has a bullet for a tag, +making it more obvious that the left margin and indentation are +distinct; +only the former affects the tag, +but both affect the text of the paragraph. +. +. +.br +.ne 3v +.P +This ordinary +.RB ( .P ) +paragraph resets the indentation, +but the left margin is still inset. +. +.TS +box; +l. +This table is affected only +by the left margin. +.TE +.RE +. +. +.P +Finally, +we have ended the relative inset by using +.BR .RE , +which +(because we used only one +.BR .RS / .RE +pair) +has reset the left margin to the default. +. +This is an ordinary +.B .P +paragraph. +. +. +.P +Resist the temptation to mock up tabular or multi-column output with +tab characters or the indentation arguments to +.BR .IP , +.BR .TP , +.BR .RS , +or the deprecated +.BR .HP ; +the result may not render comprehensibly on an output device you fail to +check, +or which is developed in the future. +. +The table preprocessor +.MR @g@tbl @MAN1EXT@ +can likely meet your needs. +_endif()dnl +. +. +.P +Several macros insert vertical space: +.BR .SH , +.BR .SS , +.BR .TP , +.B .P +(and its synonyms), +.BR .IP , +and the deprecated +.BR .HP . +. +The default inter-section and inter-paragraph spacing is +is 1v for terminal devices +_ifstyle()dnl +and 0.4v for typesetting devices +(\(lqv\(rq is a unit of vertical distance, +where 1v is the distance between adjacent text baselines in a +single-spaced document). +_endif()dnl +_ifnotstyle()dnl +and 0.4v for typesetting devices. +_endif()dnl +. +(The deprecated macro +.B .PD +can change this vertical spacing, +but its use is discouraged.) +. +Between +.B .EX +and +.B .EE +calls, +the inter-paragraph spacing is 1v regardless of output +device. +. +. +.\" ==================================================================== +.SS Registers +.\" ==================================================================== +. +Registers are described in section \(lqOptions\(rq below. +. +They can be set not only on the command line but in the site +.I man.local +file as well; +see section \(lqFiles\(rq below. +. +. +.br +.ne 7v +.\" ==================================================================== +.SS Strings +.\" ==================================================================== +. +The following strings are defined for use in man pages. +. +_ifnotstyle()dnl +None of these is necessary in a contemporary man page; +see +.MR groff_man_style @MAN7EXT@ . +_endif()dnl +. +Others are supported for configuration of rendering parameters; +see section \(lqOptions\(rq below. +. +. +.TP +.B \e*R +interpolates a special character escape sequence for the \(lqregistered +sign\(rq glyph, +.BR \e(rg , +if available, +and \(lq(Reg.)\(rq otherwise. +. +. +. +.TP +.B \e*S +interpolates an escape sequence setting the type size to the document +default. +. +. +.TP +.B \e*(lq +.TQ +.B \e*(rq +interpolate special character escape sequences for left and right +double-quotation marks, +.B \e(lq +and +.BR \e(rq , +respectively. +. +. +.TP +.B \e*(Tm +interpolates a special character escape sequence for the \(lqtrade mark +sign\(rq glyph, +.BR \e(tm , +if available, +and \(lq(TM)\(rq otherwise. +_ifstyle()dnl +. +. +.P +None of the above is necessary in a contemporary man page. +. +.B \e*S +is superfluous, +since type size changes are invisible on terminal devices and macros +that change it restore its original value afterward. +. +Better alternatives exist for the rest; +simply use the +.BR \(rs(rg , \" Heirloom Doctools, mandoc, neatmkfn, Plan 9, Solaris +.BR \(rs(lq , \" Heirloom Doctools, mandoc, neatmkfn, Plan 9 +.BR \(rs(rq , \" Heirloom Doctools, mandoc, neatmkfn, Plan 9 +and +.B \(rs(tm \" Heirloom Doctools, mandoc, neatmkfn, Plan 9 +special character escape sequences directly. +. +Unless a man page author is aiming for a pathological level of +portability, +such as the composition of pages for consumption on simulators of 1980s +Unix systems +(or Solaris +.IR troff , +though even it supports +.BR \(rs(rg ), +the above strings should be avoided. +. +. +.\" ==================================================================== +.SS Portability +.\" ==================================================================== +. +It is wise to quote multi-word section and subsection headings; +the +.B .SH +and +.B .SS +macros of +.MR man 7 +implementations descended from Seventh Edition Unix supported six +arguments at most. +. +A similar restriction applied to the +.BR .B , +.BR .I , +.BR .SM , +and font style alternation macros. +. +. +.P +The two major syntactical categories for formatting control in the +.I roff +language are requests and escape sequences. +. +Since the +.I man +macros are implemented in terms of +.I groff +requests and escape sequences, +one can, +in principle, +supplement the functionality of +.I man +with these lower-level elements where necessary. +. +. +.br +.ne 2v +.P +However, +using raw +.I groff +requests +(apart from the empty request +.RB \(lq . \(rq)\& +is likely to make your page render poorly when processed by other tools; +many of these attempt to interpret page sources directly for conversion +to HTML. +. +Some requests make implicit assumptions about things like character +and page sizes that may not hold in an HTML environment; +also, +many of these viewers don't interpret the full +.I groff +vocabulary, +a problem that can lead to portions of your text being omitted +or presented incomprehensibly. +. +. +.P +For portability to modern viewers, +it is best to write your page solely with the macros described in this +page +(except for the ones identified as deprecated, +which should be avoided). +. +The macros we have described as extensions +.RB ( .EX / .EE , +.BR .SY / .YS , +.BR .TQ , +.BR .UR / .UE , +.BR .MT / .ME , +.BR .MR , +and +.BR .SB ) +should be used with caution, +as they may not be built in to some viewer that is important to your +audience. +. +See +.I \%an\-ext.tmac +in section \(lqFiles\(rq below. +. +. +.P +Similar caveats apply to escape sequences. +. +Some escape sequences are however required for correct typesetting +even in man pages and usually do not cause portability problems. +. +Several of these render glyphs corresponding to punctuation code points +in the Unicode basic Latin range +(U+0000\(enU+007F) +that are handled specially in +.I roff +input; +the escape sequences below must be used to render them correctly and +portably when documenting material that uses them +syntactically\(emnamely, +any of the set +.B \(aq \- \(rs \(ha \(ga \(ti +(apostrophe, +dash or minus, +backslash, +caret, +grave accent, +tilde). +. +. +.br +.ne 2v +.TP +.B \e\(dq +Comment. +. +Everything after the double-quote to the end of the input line is +ignored. +. +Whole-line comments should be placed immediately after the empty request +.RB (\(lq . \(rq). +. +. +.TP +.BI \e newline +Join the next input line to the current one. +. +Except for the update of the input line counter +(used for diagnostic messages and related purposes), +a series of lines ending in backslash-newline appears to +.I groff +as a single input line. +. +Use this escape sequence to split excessively long input lines for +document maintenance. +. +. +.TP +.B \e% +Control hyphenation. +. +The location of this escape sequence within a word marks a hyphenation +point, +supplementing +.IR groff 's +automatic hyphenation patterns. +. +At the beginning of a word, +it suppresses any hyphenation breaks within +.I except +those specified with +.BR \e% . +. +. +.TP +.B \e: +Insert a non-printing break point. +. +A word can break at such a point, +but a hyphen glyph is not written to the output if it does. +. +This escape sequence is an input word boundary, +so the remainder of the word is subject to hyphenation as normal. +. +You can use +.B \e: +and +.B \e% +in combination to control breaking of a file name or URI or to permit +hyphenation only after certain explicit hyphens within a word. +. +See subsection \[lq]Hyperlink macros\[rq] above for an example. +. +. +.IP +This escape sequence is a +.I groff +extension also supported by Heirloom Doctools +.I troff \" Heirloom +050915 (September 2005), +.I mandoc +1.14.5 (2019-03-10), +and +.I neatroff +(commit 399a4936, +2014-02-17), +but not by Plan\~9, +Solaris, +or Documenter's Workbench +.IR troff s. \" Plan 9, Solaris, DWB +.\" as of this writing, 2022-08-13 +. +. +.TP +.B \e\(ti +Adjustable non-breaking space. +. +Use this escape sequence to prevent a break inside a short phrase or +between a numerical quantity and its corresponding unit(s). +. +. +.RS +.IP +.EX +Before starting the motor, +set the output speed to\e\(ti1. +There are 1,024\e\(tibytes in 1\e\(tiKiB. +CSTR\e\(ti#8 documents the B\e\(tilanguage. +.EE +.RE +. +. +.\" BEGIN Keep in sync with groff.texi node "Other Differences" and +.\" groff_diff(7). +.IP +This escape sequence is a +.I groff +extension also supported by Heirloom Doctools +.I troff \" Heirloom +050915 (September 2005), +.I mandoc +1.9.5 (2009-09-21), +.I neatroff +(commit 1c6ab0f6e, +2016-09-13), +and +Plan\~9 from User Space +.I troff \" Plan 9 +(commit 93f8143600, +2022-08-12), +but not by Solaris +or Documenter's Workbench +.IR troff s. \" Solaris, DWB +.\" as of this writing, 2022-08-13 +.\" END Keep in sync with groff.texi node "Other Differences" and +.\" groff_diff(7). +. +. +.TP +.B \e& +Dummy character. +. +Insert at the beginning of an input line to prevent a dot or apostrophe +from being interpreted as beginning a +.I roff +control line. +. +Append to an end-of-sentence punctuation sequence to keep it from being +recognized as such. +. +. +.TP +.B \e| +Thin space +(one-sixth em on typesetters, +zero-width on terminals); +a non-breaking space. +. +Used primarily in ellipses +(\(lq.\e|.\e|.\(rq) +to space the dots more pleasantly on typesetting devices like +.BR dvi , +.BR pdf , +and +.BR ps . +. +. +.TP +.B \ec +End a text line without inserting space or attempting a break. +. +.\" TODO: When we explain what a "sentence" is, move this parenthetical +.\" there. +Normally, +if filling is enabled, +the end of a text line is treated like a space; +.\" end-of-sentence detection is performed, and... +an output line +.I may +be broken there +(if not, +an adjustable space is inserted); +if filling is disabled, +the line +.I will +be broken there, +as in +.BR .EX / .EE +examples. +. +The next line is interpreted as usual and can `include' a macro call +(contrast with +.BI \e newline\/\c +). +. +.B \(rsc +is useful when three font styles are +needed in a single word, +as in a command synopsis. +. +. +.RS +.IP +.\" from contrib/pdfmark/pdfroff.1.man +.EX +\&.RB [ \e\-\e\-stylesheet=\ec +\&.IR name ] +.EE +.RE +. +. +.IP +It also helps when changing font styles in +.BR .EX / .EE +examples, +since they are not filled. +. +. +.RS +.IP +.\" from src/devices/grotty/grotty.1.man +.EX +\&.EX +$ \ec +\&.B groff \e\-T utf8 \e\-Z \ec +\&.I file \ec +\&.B | grotty \e\-i +\&.EE +.EE +.RE +. +. +.IP +Alternatively, +and perhaps with better portability, +the +.B \ef +font selection escape sequence can be used; +see below. +. +Using +.B \ec +to continue a +.B .TP +paragraph tag across multiple input lines will render incorrectly with +.I groff +1.22.3, +.I mandoc +1.14.1, +older versions of these programs, +and perhaps with some other formatters. +. +. +.TP +.B \ee +Format the current escape character on the output; +widely used in man pages to render a backslash glyph. +. +.\" Don't bold the .ec request in this discussion; it's not a major +.\" topic of _this_ page as it would be in groff(7). Also, we don't +.\" want to encourage people to mess with this old kludge by drawing +.\" attention to it. +It works reliably as long as the \[lq].ec\[rq] request is not used, +which should never happen in man pages, +and it is slightly more portable than the more explicit +.B \e(rs +(\(lqreverse solidus\(rq) special character escape sequence. +. +. +.TP +.BR \efB ,\~ \efI ,\~ \efR ,\~ \efP +Switch to bold, +italic, +roman, +or back to the previous style, +respectively. +. +Either +.B \ef +or +.B \ec +is needed when three different font styles are required in a word. +. +. +.RS +.IP +.\" second example from contrib/pdfmark/pdfroff.1.man +.EX +\&.RB [ \e\-\e\-reference\e\-dictionary=\efI\e,name\e/\efP ] +.IP +\&.RB [ \e\-\e\-reference\e\-dictionary=\ec +\&.IR name ] +.EE +.RE +. +. +.IP +Style escape sequences may be more portable than +.BR \ec . +. +As shown above, +it is up to you to account for italic corrections with +.\" Normally we don't quote escape sequences, but these use +.\" potentially-confusing prose punctuation. +.RB \(lq \^\e\|/\^ \(rq +and +.RB \(lq \^\e\^, \(rq, +which are themselves GNU extensions, +if desired and if supported by your implementation. +. +. +.IP +.B \efP +reliably returns to the style in use immediately preceding the +previous +.B \ef +escape sequence only if no +sectioning, +paragraph, +or style macro calls have intervened. +. +. +.IP +As long as at most two styles are needed in a word, +style macros like +.B .B +and +.B .BI +usually result in more readable +.I roff +source than +.B \ef +escape sequences do. +. +. +.P +Several special characters are also widely portable. +.\" meaning: groff, Heirloom Doctools troff, neatroff, mandoc +. +Except for +.BR \[rs]\- , +.BR \[rs](em , +and +.BR \[rs](ga , +AT&T +.I troff +did not consistently `define' the characters listed below, +.\" Only \-, \(em, and \(ga were documented in CSTR #54 (1976). CSTR +.\" #54 (1992) offers no _comprehensive_ list but shows \(en in its +.\" PostScript DESC file example. In DWB 3.3, \(aq was supported by the +.\" "post" device, and \(dq by "pcl" and "Latin1". +but its descendants, +like Plan\~9 or Solaris +.IR troff , \" Plan 9, Solaris +can be made to support them by defining them in font description files, +making them aliases of existing glyphs if necessary; +see +.MR groff_font @MAN5EXT@ . +. +. +.TP +.B \e\- +Minus sign or basic Latin hyphen-minus. +. +This escape sequence produces the Unix command-line option dash in the +output. +. +.RB \(lq \- \(rq +is a hyphen in the +.I roff +language; +some output devices replace it with U+2010 +(hyphen) +or similar. +. +. +.TP +.B \e(aq +Basic Latin neutral apostrophe. +. +Some output devices format +.RB \(lq\| \(aq \|\(rq +as a right single quotation mark. +. +. +.br +.ne 3v +.TP +.B \e(oq +.TQ +.B \e(cq +Opening (left) and closing (right) single quotation marks. +. +Use these for paired directional single quotes, +\(oqlike this\(cq. +. +. +.TP +.B \e(dq +Basic Latin quotation mark +(double quote). +. +Use in macro calls to prevent +.\" This page prefers double quotes, but not here because they are more +.\" confusing to the eye when another double quote is what is quoted! +.RB \(oq\| \(dq \|\(rq +.\" AT&T: .RB ` """' +from being interpreted as beginning a quoted argument, +or simply for readability. +. +. +.RS +.IP +.\" from src/preproc/eqn/eqn.1.man +.EX +\&.TP +\&.BI \(dqsplit \e(dq\(dq text \e(dq +.EE +.RE +. +. +.br +.\" XXX: We need only 2v, but 2v more are necessary due to bad +.\" interaction with TP's own use of the ne request. +.ne 4v +.TP +.B \e(lq +.TQ +.B \e(rq +Left and right double quotation marks. +. +Use these for paired directional double quotes, +\(lqlike this\(rq. +. +. +.TP +.B \e(em +Em-dash. +. +Use for an interruption\(emsuch as this one\(emin a sentence. +. +. +.TP +.B \e(en +En-dash. +. +Use to separate the ends of a range, +particularly between numbers; +for example, +\(lqthe digits 1\(en9\(rq. +. +. +.TP +.B \e(ga +Basic Latin grave accent. +. +Some output devices format +.RB \(lq\| \(ga \|\(rq +as a left single quotation mark. +. +. +.TP +.B \e(ha +Basic Latin circumflex accent +(\(lqhat\(rq). +. +Some output devices format +.RB \(lq \(ha \(rq +as U+02C6 +(modifier letter circumflex accent) +or similar. +. +. +.TP +.B \e(rs +Reverse solidus +(backslash). +. +The backslash is the default escape character in the +.I roff +language, +so it does not represent itself in output. +. +Also see +.B \ee +above. +. +. +.TP +.B \e(ti +Basic Latin tilde. +. +Some output devices format +.RB \(lq \(ti \(rq +as U+02DC +(small tilde) +or similar. +. +. +.P +For maximum portability, +escape sequences and special characters not listed above are better +avoided in man pages. +_endif()dnl +. +. +.\" ==================================================================== +.SS Hooks +.\" ==================================================================== +. +Two macros, +both GNU extensions,\" from groff 1.19 +are called internally by the +.I groff man +package to format page headers and footers and can be redefined by the +administrator in a site's +.I man.local +file +(see section \(lqFiles\(rq below). +. +The presentation of +.B .TH +above describes the default headers and footers. +. +Because these macros are hooks for +.I groff man +internals, +man pages have no reason to call them. +. +Such hook definitions will likely consist of \[lq].sp\[rq] and +\[lq].tl\[rq] requests. +. +They must also increase the page length with \[lq].pl\[rq] requests in +continuous rendering mode; +.B .PT +furthermore has the responsibility of emitting a PDF bookmark after +writing the first page header in a document. +. +Consult the existing implementations in +.I an.tmac +when drafting replacements. +. +. +.TP +.B .BT +Set the page footer text +(\(lqbottom trap\(rq). +. +. +.TP +.B .PT +Set the page header text +(\(lqpage trap\(rq). +. +. +.P +To remove a page header or footer entirely, +`define' the appropriate macro as empty rather than deleting it. +. +. +.\" ==================================================================== +.SS "Deprecated features" +.\" ==================================================================== +. +Use of the following in man pages for public distribution is +discouraged. +. +. +.TP +.BR .AT " ["\c +.IR system " [" release ]] +Alter the footer for use with legacy AT&T man pages, +overriding any definition of the +.I footer-inside +argument to +.BR .TH . +. +This macro exists only to render man pages from historical systems. +. +. +.IP +.I system +can be any of the following. +. +. +.RS \" Invisibly move left margin to current .IP indentation. +.RS \" Now indent further, visibly. +.TP +3 +7th edition +.I (default) +. +. +.TP +4 +System III +. +. +.TP +5 +System V +.RE \" Move left margin back to .IP indentation. +.RE \" Move left margin back to standard position. +. +. +.IP +The optional +.I release +argument specifies the release number, +as in \(lqSystem\~V Release\~3\(rq. +. +. +.TP +.B .DT +Reset tab stops to the default +_ifnotstyle()dnl +(every 0.5i). +_endif()dnl +_ifstyle()dnl +(every 0.5i [inches]). +_endif()dnl +. +.IP +Use of this presentation-oriented macro is deprecated. +. +It translates poorly to HTML, +under which exact space control and tabulation are not readily +available. +. +Thus, +information or distinctions that you use tab stops to express are likely +to be lost. +. +If you feel tempted to change the tab stops such that calling this macro +later is desirable to restore them, +you should probably be composing a table using +.MR @g@tbl @MAN1EXT@ +instead. +. +. +.TP +.BR .HP " ["\c +.IR indentation ] +Set up a paragraph with a hanging left indentation. +. +The +.I indentation +argument, +if present, +is handled as with +.BR .TP . +. +. +.IP +Use of this presentation-oriented macro is deprecated. +. +A hanging indentation cannot be expressed naturally under HTML, +and +.RI non- roff -based +man page interpreters may treat +.B .HP +as an ordinary paragraph. +. +Thus, +information or distinctions you mean to express with indentation may be +lost. +. +. +.TP +.BI .OP " option-name"\/\c +.RI " [" option-argument ] +Indicate an optional command parameter called +.IR option-name , +which is set in bold. +. +If the option takes an argument, +specify +.I option-argument +using a noun, +abbreviation, +or hyphenated noun phrase. +. +If present, +.I option-argument +is preceded by a space and set in italics. +. +Square brackets in roman surround both arguments. +. +. +.IP +Use of this quasi-semantic macro, +.\" https://github.com/n-t-roff/DWB3.3/blob/master/macros/man/an.sr#L37 +an extension originating in Documenter's Workbench +.IR troff ,\" DWB +is deprecated. +. +It cannot easily be used to annotate options that take optional +arguments or options whose arguments have internal structure +(such as a mixture of literal and variable components). +. +One could work around these limitations with font selection escape +sequences, +but it is preferable to use font style alternation macros, +which afford greater flexibility. +. +. +.TP +.BR .PD " ["\c +.IR vertical-space ] +Define the vertical space between paragraphs or (sub)sections. +. +The optional argument +.I vertical-space +specifies the amount; +the default scaling unit is \(lqv\(rq. +. +Without an argument, +the spacing is reset to its default value; +see subsection \(lqHorizontal and vertical spacing\(rq above. +. +. +.IP +Use of this presentation-oriented macro is deprecated. +. +It translates poorly to HTML, +under which exact control of inter-paragraph spacing is not readily +available. +. +Thus, +information or distinctions that you use +.B .PD +to express are likely to be lost. +. +. +.TP +.BR .UC " ["\c +.IR version ] +Alter the footer for use with legacy BSD man pages, +overriding any definition of the +.I footer-inside +argument to +.BR .TH . +. +This macro exists only to render man pages from historical systems. +. +. +.IP +.I version +can be any of the following. +. +. +.RS \" Invisibly move left margin to current .IP indentation. +.RS \" Now indent further, visibly. +.TP +3 +3rd Berkeley Distribution +.I (default) +. +. +.TP +4 +4th Berkeley Distribution +. +. +.TP +5 +4.2 Berkeley Distribution +. +. +.TP +6 +4.3 Berkeley Distribution +. +. +.TP +7 +4.4 Berkeley Distribution +.RE \" Move left margin back to .IP indentation. +.RE \" Move left margin back to standard position. +. +. +.\" ==================================================================== +.SS History +.\" ==================================================================== +. +.MT m.douglas.mcilroy@dartmouth.edu +M.\& Douglas McIlroy +.ME +designed, +implemented, +and documented the AT&T +.I man +macros +for +Unix Version\~7 (1979) and employed them +to edit the first volume of its +.IR "Programmer's Manual" , +a compilation of all man pages supplied by the system. +. +That +.I man +supported the macros listed in this page not described as extensions, +except +.B .P +.\" .SS was implemented in tmac.an but not documented in man(7). +and the deprecated +.B .AT +and +.BR .UC . +. +The only strings defined were +.B R +and +.BR S ; +no registers were documented. +. +. +.P +.B .UC +appeared in 3BSD (1980). +. +.\" per https://archive.org/details/\ +.\" bitsavers_attunixSysalRelease3Jun80_33886798 +Unix System\~III (1980) introduced +.B .P +.\" ...and de-documented .LP... +and exposed the registers +.B IN +and +.BR LL , +.\" ...as well as \n[PD], which we implement but don't expose. +which had been internal to Seventh Edition Unix +.IR man . +. +.\" This inference is based on RCS idents of "PWB Manual Entry Macros" +.\" from various forms of "an.src" distributed with System III (an.src +.\" 1.35, dated 5/6/80, lacks the Tm string), Research Unix Version 10 +.\" (1.36, dated 11/11/80, has it), Ultrix 3.1 (1.37, dated 12/19/80, +.\" retains it) and "pdp11v" (also 1.37). One source (S. S. Pirzada) +.\" says PWB 2.0 was released in June 1979. I found no record of later +.\" releases and cannot account for the discrepancy (field updates?). +.\" -- GBR +PWB/UNIX 2.0 (1980) added the +.B Tm +string. +. +4BSD (1980) added +.\" undocumented .VS and .VE macros to mark regions with 12-point box +.\" rules (\[br]) as margin characters, as well as... +.B lq +and +.B rq +strings. +. +.\" The SunOS inferences here and below are based on inspection of SunOS +.\" 2.0 (May 1985), 3.2 (September 1986), 3.5 (January 1988), and 4.0 +.\" (December 1988) tape archives (only). +SunOS\~2.0 (1985) recognized +.BR C , +.BR D , +.BR P , +and +.B X +registers. +. +4.3BSD (1986) added +.\" undocumented .DS and .DE macros for "displays", which are .RS/.RE +.\" wrappers with filling disabled and vertical space of 1v before and +.\" .5v after, as well as... +.B .AT +and +.BR .P . +. +.\" Per Doug McIlroy in +.\" ... +Ninth Edition Research Unix (1986) introduced +.B .EX +and +.BR .EE . +. +SunOS\~4.0 (1988) added +.BR .SB . +. +. +.P +The foregoing features were what James Clark implemented in early +versions of +.IR groff . +. +. +Later, +.I groff +1.20 (2009) originated +.BR .SY / .YS , +.BR .TQ , +.BR .MT / .ME , +and +.BR .UR / .UE . +.\" ...along with implementations of OP, EX, and EE. +. +Plan\~9 from User Space's +.I troff \" plan9port +introduced +.B .MR +in 2020. +.\" https://github.com/9fans/plan9port/commit/\ +.\" 977b25a76ae8263e53fb4eb1abfc395769f23e3d +.\" d32deab17bfffa5bffc5fab3e6577558e40888c5 +.\" 36cd4c58c1346375b98f517fb8568be5bb47618d +. +. +.br +.ne 4v +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +The following +.I groff +options set registers +(with +.BR \-r ) +and strings +(with +.BR \-d ) +recognized and used by the +.I man +macro package. +. +To ensure rendering consistent with output device capabilities and +reader preferences, +man pages should never manipulate them. +. +. +.TP +.BI \-dAD= adjustment-mode +Set line adjustment to +.I adjustment-mode, +which is typically +.RB \[lq] b \[rq] +for adjustment to both margins +(the default), +or +.RB \[lq] l \[rq] +for left alignment +(ragged right margin). +. +Any valid argument to +.IR groff 's +\[lq].ad\[rq] request may be used. +. +See +.MR groff @MAN7EXT@ +for less-common choices. +. +. +.TP +.B \-rcR=1 +Enable continuous rendering. +. +Output is not paginated; +instead, +one +(potentially very long) +page is produced. +. +This is the default for terminal and HTML devices. +. +Use +.B \-rcR=0 +to disable it on terminal devices; +on HTML devices, +it cannot be disabled. +. +. +.TP +.B \-rC1 +Number output pages consecutively, +in strictly increasing sequence, +rather than resetting the page number to\~1 +(or the value of register +.BR P ) +with each new +.I man +document. +. +. +.TP +.B \-rCS=1 +Set section headings +(the argument(s) to +.BR .SH ) +in full capitals. +. +This transformation is off by default because it discards case +distinction information. +. +. +.TP +.B \-rCT=1 +Set the man page topic +(the first argument to +.BR .TH ) +in full capitals in headers and footers. +. +This transformation is off by default because it discards case +distinction information. +. +. +.TP +.B \-rD1 +Enable double-sided layout, +formatting footers for even and odd pages differently; +see the description of +.B .TH +in subsection \(lqDocument structure macros\(rq above. +. +. +.TP +.BI \-rFT= footer-distance +Set distance of the footer relative to the bottom of the page to +.I footer-distance; +this amount is always negative. +. +At one half-inch above this location, +the page text is broken before writing the footer. +. +Ignored if continuous rendering is enabled. +. +The default is \-0.5i. +. +. +.TP +.BI \-dHF= heading-font +Set the font used for section and subsection headings; +the default is +.RB \(lq B \(rq +(bold style of the default family). +. +Any valid argument to +.IR groff 's +\[lq].ft\[rq] request may be used. +. +See +.MR groff @MAN7EXT@ . +. +. +.TP +.B \-rHY=0 +Disable automatic hyphenation. +. +Normally, +it is enabled\~(1). +. +The hyphenation mode is determined by the +.I groff +locale; +see section \[lq]Localization\[lq] of +.MR groff @MAN7EXT@ . +. +. +.TP +.BI \-rIN= standard-indentation +Set the amount of indentation used for ordinary paragraphs +.RB ( .P +and its synonyms) +and the default indentation amount used by +.BR .IP , +.BR .RS , +.BR .TP , +.\" .TQ inherits its indentation from the preceding .TP. +and the deprecated +.BR .HP . +. +See subsection \(lqHorizontal and vertical spacing\(rq above for the +default. +. +For +terminal devices, +.I standard-indentation +should always be an integer multiple of unit \(lqn\(rq to get consistent +indentation. +. +. +.TP +.BI \-rLL= line-length +Set line length; +the default is 78n for terminal devices +and 6.5i for typesetting devices. +. +. +.TP +.BI \-rLT= title-length +Set the line length for titles. +_ifstyle()dnl +. +(\(lqTitles\(rq is the +.I roff +term for headers and footers.) +_endif()dnl +. +By default, +it is set to the line length +(see +.B \-rLL +above). +. +. +.TP +.BI \-dMF= man-page-topic-font +Set the font used for man page topics named in +.B .TH +and +.B .MR +calls; +the default is +.RB \(lq I \(rq +(italic style of the default family). +. +Any valid argument to +.IR groff 's +\[lq].ft\[rq] request may be used. +. +If the +.B MF +string ends in \[lq]I\[rq], +it is assumed to be an oblique typeface, +and italic corrections are applied before and after man page topics. +. +. +.TP +.BI \-rP n +Start enumeration of pages at +.IR n . +. +The default is\~1. +. +. +.TP +.BI \-rS type-size +Use +.I type-size +for the document's body text; +acceptable values are 10, +11, +or 12 points. +. +See subsection \(lqFont style macros\(rq above for the default. +. +. +.TP +.BI \-rSN= subsection-indentation +Set indentation of subsection headings to +.I subsection-indentation. +. +See subsection \(lqHorizontal and vertical spacing\(rq above for the +default. +. +. +.br +.ne 4v +.TP +.B \-rU1 +Enable generation of URI hyperlinks in the +.I grohtml +and +.I grotty +output drivers. +. +.I grohtml +enables them by default; +.I grotty +does not, +pending more widespread pager support for OSC\~8 escape sequences. +. +Use +.B \-rU0 +to disable hyperlinks; +this will make the arguments to +.B MT +and +.B UR +calls visible in the document text produced by link-capable drivers. +. +. +.TP +.BI \-rX p +Number successors of +.RI page\~ p +as +.IR p a, +.IR p b, +.IR p c, +and so forth. +. +The register tracking the suffixed page letter uses format \(lqa\(rq +(see the \(lq.af\(rq request in +.MR groff @MAN7EXT@ ). +. +_ifstyle()dnl +For example, +the option +.B \-rX2 +produces the following page +numbers: 1, +2, +2a, +2b, +\&.\|.\|.\|, +2aa, +2ab, +and so on. +_endif()dnl +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.I @MACRODIR@/\:an\:.tmac +Most +.I man +macros are defined in this file. +. +It also loads extensions from +.I \%an\-ext.tmac +(see below). +. +. +.TP +.I @MACRODIR@/\:\%andoc\:.tmac +This brief +.I groff +program detects whether the +.I man +or +.I mdoc +macro package is being used by a document and loads the correct macro +definitions, +taking advantage of the fact that pages using them must call +.B .TH +or +.BR .Dd , +respectively, +before any other macros. +. +A +.I man +program or user typing, +for example, +.RB \[lq] "groff \-mandoc page.1" \[rq], +need not know which package the file +.I page.1 +uses. +. +Multiple man pages, +in either format, +can be handled; +.I \%andoc +reloads each macro package as necessary. +. +. +.TP +.I @MACRODIR@/\:\%an\-ext\:.tmac +Except for +.BR .SB , +definitions of macros described above as extensions +are contained in this file; +in some cases, +they are simpler versions of definitions appearing in +.IR an.tmac , +and are ignored if the formatter is GNU +.IR troff .\" GNU +. +They are written to be compatible with AT&T +.I troff \" AT&T +and permissively licensed\(emnot copylefted. +. +To reduce the risk of name space collisions, +string and register names begin only with +.RB \[lq] m \[rq] . +. +We encourage man page authors +who are concerned about portability to legacy Unix systems +to copy these definitions into their pages, +and maintainers of +.I troff \" generic +implementations or work-alike systems that format man pages +to re-use them. +. +. +.IP +The definitions for these macros are read after a page calls +.BR .TH , +so they will replace any macros of the same names preceding it in your +file. +. +If you use your own implementations of these macros, +they must be defined after +.B .TH +is called to have any effect. +. +Furthermore, +it is wise to `define' such page-local macros +(if at all) +after the \(lqName\(rq section to accommodate timid +.I makewhatis +or +.I mandb +implementations that may give up their scan for indexing material early. +. +. +.TP +.I @MACRODIR@/\:man\:.tmac +This is a wrapper that loads +.IR an.tmac . +. +. +.TP +.I @MACRODIR@/\:\%mandoc\:.tmac +This is a wrapper that loads +.IR \%andoc.tmac . +. +. +.TP +.I @LOCALMACRODIR@/\:\%man\:\%.local +Put site-local changes and customizations into this file. +_ifstyle()dnl +. +. +.RS +.RS +.P +.EX +\&.\e" Use narrower indentation on terminals and similar. +\&.if n .nr IN 4n +\&.\e" Put only one space after the end of a sentence. +\&.ss 12 0 \e" See groff(@MAN7EXT@). +\&.\e" Keep pages narrow even on wide terminals. +\&.if n .if \(rsn[LL]>78n .nr LL 78n +\&.\e" Ensure hyperlinks are enabled for terminals. +\&.nr U 1 +.EE +.RE +.RE +. +. +.IP +On multi-user systems, +it is more considerate to users whose preferences may differ from the +administrator's to be less aggressive with such settings, +or to permit their override with a user-specific +.I man.local +file. +. +Place the requests below at the end of the site-local file to +manifest courtesy. +. +.br +.ne 3v +.RS +.RS +.EX +\&.soquiet \eV[XDG_CONFIG_HOME]/man.local +\&.soquiet \eV[HOME]/.man.local +.EE +.RE +. +However, +a security-sandboxed +.MR man 1 \" such as man-db 2.8.5 +program may lack permission to open such files. +.RE +. +. +.\" ==================================================================== +.SH Notes +.\" ==================================================================== +. +Some tips on troubleshooting your man pages follow. +. +. +.TP +\(bu Some ASCII characters look funny or copy and paste wrong. +. +On devices with large glyph repertoires, +like UTF-8-capable terminals and PDF, +several keyboard glyphs are mapped to code points outside the Unicode +basic Latin range because that usually results in better typography in +the general case. +. +When documenting GNU/Linux command or C language syntax, +however, +this translation is sometimes not desirable. +. +. +.IP +.if t .ne 2v +.if n .ne 3v \" account for horizontal rule +.TS +c c +rfCB lfCB. +To get a \(lqliteral\(rq.\|.\|. .\|.\|.should be input. +_ +\(aq \(rs(aq +\- \(rs\- +\(rs \(rs(rs +\(ha \(rs(ha +\(ga \(rs(ga +\(ti \(rs(ti +_ +.TE +. +. +.IP +Additionally, +if a neutral double quote (") is needed in a macro argument, +you can use +.B \(rs(dq +to get it. +. +You should +.I not +use +.B \(rs(aq +for an ordinary apostrophe +(as in \(lqcan't\(rq) +or +.B \(rs\- +for an ordinary hyphen +(as in \(lqword-aligned\(rq). +. +Review subsection \(lqPortability\(rq above. +. +. +.TP +\(bu Do I ever need to use an empty macro argument ("")? +. +Probably not. +. +When this seems necessary, +often a shorter or clearer alternative is available. +. +. +.IP +.if t .ne 10v +.if n .ne 16v \" account for horizontal rules +.TS +c c +lfCB lfCB. +Instead of.\|.\|. .\|.\|.should be considered. +_ +\&.TP \(dq\(dq .TP +_ +\&.BI \(dq\(dq \fIitalic-text bold-text .IB \fIitalic-text bold-text +_ +\&.TH foo 1 \(dq\(dq \(dqfoo 1.2.3\(dq .TH foo 1 \ +\f(CIyyyy\fP-\f(CImm\fP-\f(CIdd\fP \(dqfoo 1.2.3\(dq +_ +\&.IP \(dq\(dq 4n .IP +_ +\&.IP \(dq\(dq 4n .RS 4n +\fIparagraph .P +\fR.\|.\|. \fIparagraph +\fR.\|.\|. .RE +_ +\&.B one two \(dq\(dq three .B one two three +.TE +. +. +.IP +In the title heading +.RB ( .TH ), +the date of the page's last revision is more important than packaging +information; +it should not be omitted. +. +Ideally, +a page maintainer will keep both up to date. +. +. +.IP +.B .IP +is sometimes ill-understood and misused, +especially when no marker argument is supplied\(eman indentation +argument is not required. +. +By setting an explicit indentation, +you may be overriding the reader's preference as set with the +.B \-rIN +option. +. +If your page renders adequately without one, +use the simpler form. +. +If you need to indent multiple (unmarked) paragraphs, +consider setting an inset region with +.B .RS +and +.B .RE +instead. +. +. +.IP +In the last example, +the empty argument does have a subtly different effect than its +suggested replacement: +the empty argument causes an additional space character to be +interpolated between the arguments \(lqtwo\(rq and \(lqthree\(rq\(embut +it is a regular breaking space, +so it can be discarded at the end of an output line. +. +It is better not to be subtle, +particularly with space, +which can be overlooked in source and rendered forms. +. +. +.TP +.RB \(bu " .RS" " doesn't indent relative to my indented paragraph." +. +The +.B .RS +macro sets the left margin; +that is, +the position at which an +.I ordinary +paragraph +.RB ( .P +and its synonyms) +will be set. +. +.BR .IP , +.BR .TP , +and the deprecated +.B .HP +use the same default indentation. +. +If not given an argument, +.B .RS +moves the left margin by this same amount. +. +To create an inset relative to an indented paragraph, +call +.B .RS +repeatedly until an acceptable indentation is achieved, +or give +.B .RS +an indentation argument that is at least as much as the paragraph's +indentation amount relative to an adjacent +.B .P +paragraph. +. +See subsection \(lqHorizontal and vertical spacing\(rq above for the +values. +. +. +.IP +Another approach you can use with tagged paragraphs is to place an +.B .RS +call immediately after the paragraph tag; +this will also force a break regardless of the width of the tag, +which some authors prefer. +. +Follow-up paragraphs under the tag can then be set with +.B .P +instead of +.BR .IP . +. +Remember to use +.B .RE +to end the indented region before starting the next tagged paragraph +(at the appropriate nesting level). +. +. +.TP +.RB \(bu " .RE" " doesn't move the inset back to the expected level." +.TQ +\(bu warning: scaling unit invalid in context +.TQ +\(bu warning: register \(aqan\-saved\-margin\c +.IR n "\(aq not defined" +.TQ +\(bu warning: register \(aqan\-saved\-prevailing\-indent\c +.IR n "\(aq not defined" +. +The +.B .RS +macro takes an +.I indentation amount +as an argument; +the +.B .RE +macro's argument is a specific +.I inset level. +. +.B .RE\~1 +goes to the level before any +.B .RS +macros were called, +.B .RE\~2 +goes to the level of the first +.B .RS +call you made, +and so forth. +. +If you desire symmetry in your macro calls, +simply issue one +.B .RE +without an argument +for each +.B .RS +that precedes it. +. +. +.IP +After calls to the +.B .SH +and +.B .SS +sectioning macros, +all relative insets are cleared and calls to +.B .RE +have no effect until +.B .RS +is used again. +. +. +.TP +\(bu Do I need to keep typing the indentation in a series of \c +.BR .IP " calls?" +. +Not if you don't want to change it. +. +Review subsection \(lqHorizontal and vertical spacing\(rq above. +. +. +.IP +.if t .ne 5v +.if n .ne 7v \" account for horizontal rules +.TS +c c +lfCB lfCB. +Instead of.\|.\|. .\|.\|.should be considered. +_ +\&.IP \(rs(bu 4n .IP \(rs(bu 4n +\fIparagraph \fIparagraph +\&.IP \(rs(bu 4n .IP \(rs(bu +\fIanother-paragraph \fIanother-paragraph +_ +.TE +. +. +.TP +\(bu Why doesn't the package provide a string to insert an ellipsis? +. +Examples of ellipsis usage are shown above, +in subsection \[lq]Command synopsis macros\[rq]. +. +The idiomatic +.I roff +ellipsis is three dots (periods) +with thin space escape sequences +.B \[rs]| +internally separating them. +. +Since dots both begin control lines and are candidate end-of-sentence +characters, +however, +it is sometimes necessary to prefix and/or suffix an ellipsis with the +dummy character escape sequence +.BR \[rs]& . +. +That fact stands even if a string is defined to contain the sequence; +further, +if the string ends with +.BR \[rs]& , +end-of-sentence detection is defeated when you use the string at the end +of an actual sentence. +. +(Ending a sentence with an ellipsis is often poor style, +but not always.) +. +A hypothetical string +.B EL +that contained an ellipsis, +but not the trailing dummy character +.BR \[rs]& , +would then need to be suffixed with the latter +when not ending a sentence. +. +. +.IP +.if t .ne 5v +.if n .ne 7v \" account for horizontal rules +.TS +C C +LfCB LfCB. +Instead of.\|.\|. .\|.\|.do this. +_ +\&.ds EL \[rs]&.\[rs]|.\[rs]|. Arguments are +Arguments are .IR src-file\[rs]\[ti] .\[rs]|.\[rs]|.\[rs]& +\&.IR src-file\[rs]\[ti] \[rs]*(EL\[rs]& .IR dest-dir . +\&.IR dest-dir . +_ +.TE +. +. +.IP +The first column practices a false economy; +the savings in typing is offset by the cost of obscuring even the +suggestion of an ellipsis to a casual reader of the source document, +and reduced portability to +.RI non- roff +man page formatters that cannot handle string definitions. +. +. +.IP +There is an ellipsis code point in Unicode, +and some fonts have an ellipsis glyph, +which some man pages have accessed in a non-portable way with the +font-dependent +.B \[rs]N +escape sequence. +. +We discourage the use of these; +on terminals, +they may crowd the dots into a half-width character cell, +and will not render at all if the output device doesn't have the glyph. +. +In syntax synopses, +missing ellipses can cause great confusion. +. +Dots and space are universally supported. +.\" XXX: Does an unconditional _preceding_ dummy character cause +.\" problems? +_endif()dnl +. +. +.\" ==================================================================== +.SH Authors +.\" ==================================================================== +. +The initial GNU implementation of the +.I man +macro package was written by James Clark. \" by 1.01 +. +Later, +.MT wl@\:gnu\:.org +Werner Lemberg +.ME +supplied the +.BR S , \" 1.16 +.BR LT , \" 1.18 +and +.B cR \" 1.17 +registers, +the last a 4.3BSD-Reno +.IR mdoc (7) +feature. +.\" "Assume nroff on crt's [sic] only if cR==1" +.\" https://minnie.tuhs.org/cgi-bin/utree.pl +.\" ?file=4.3BSD-Reno/share/tmac/tmac.doc +. +.MT kollar@\:alltel\:.net +Larry Kollar +.ME +added the +.BR FT , +.BR HY , +and +.B SN +registers; +the +.B HF +string; +and the +.B PT +and +.B BT +macros. +. +.MT g.branden\:.robinson@\:gmail\:.com +G.\& Branden Robinson +.ME +implemented the +.B AD +and +.B MF +strings; +.BR CS , +.BR CT , +and +.B U +registers; +and the +.B MR +macro. \" all 1.23 +. +. +Except for +.BR .SB , \" Clark, as noted above +the extension macros were written by +Lemberg, +.MT esr@\:thyrsus\:.com +Eric S.\& Raymond +.ME , +and +Robinson. \" 1.23: MR +. +. +.br +.ne 3v +.P +This document was originally written for the Debian GNU/Linux system by +.MT sgk@\:debian\:.org +Susan G.\& Kleinmann +.ME . +. +It was corrected and updated by Lemberg and Robinson. +. +The extension macros were documented by Raymond and Robinson. +_ifstyle()dnl +Raymond also originated the portability section, +to which +.MT schwarze@\:usta\:.de +Ingo Schwarze +.ME +contributed most of the material on escape sequences. +_endif()dnl +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.MR @g@tbl @MAN1EXT@ , +.MR @g@eqn @MAN1EXT@ , +and +.MR @g@refer @MAN1EXT@ +are preprocessors used with man pages. +. +.MR man 1 +describes the man page librarian on your system. +. +.MR groff_mdoc @MAN7EXT@ +details the +.I groff +version of the BSD-originated alternative macro package for man pages. +. +. +.P +_ifstyle()dnl +.MR groff_man @MAN7EXT@ , +_endif()dnl +_ifnotstyle()dnl +.MR groff_man_style @MAN7EXT@ , +_endif()dnl +.MR groff @MAN7EXT@ , +.MR groff_char @MAN7EXT@ , +.MR man 7 +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_groff_man_7_man_C] +.do rr *groff_groff_man_7_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/groff_mdoc.7.man b/tmac/groff_mdoc.7.man new file mode 100644 index 0000000..d161c86 --- /dev/null +++ b/tmac/groff_mdoc.7.man @@ -0,0 +1,5375 @@ +'\" t +.\" groff_mdoc.man +.\" +.\" A complete reference of the mdoc macro package for GNU troff. +.\" +.\" Based on NetBSD's mdoc.samples.7, version 1.21. +.\" +.\" +.\" Warning: You can't format this file with the old mdoc macros! +.\" +.\" +.\" Copyright (C) 1990, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" 3. [Deleted. See +.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] +.\" 4. Neither the name of the University nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" +.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +.\" PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR +.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)mdoc.samples.7 8.2 (Berkeley) 12/30/93 +.\" +.\" This reference invokes every macro in the package several times and +.\" is guaranteed to give worst-case performance for an already +.\" extremely slow package. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_groff_mdoc_7_man_C \n[.cp] +.cp 0 +. +. +.Dd @MDATE@ +.Dt groff_mdoc 7 +.Os groff @VERSION@ +. +. +.Sh Name +. +.Nm groff_mdoc +.Nd compose BSD-style manual (man) pages with GNU +.Xr roff +. +. +.Sh Synopsis +. +.Nm groff Fl m Ns Cm doc Ar file No ... +. +. +.Sh Description +. +The GNU implementation of the +.Xr mdoc +macro package is part of the +.Xr groff @MAN1EXT@ +document formatting system. +. +.Xr mdoc +is a +structurally- and semantically-oriented package for writing +.Ux +manual pages with +.Xr @g@troff @MAN1EXT@ . +. +Its predecessor, +the +.Xr man 7 +package, +primarily addressed page layout and presentational concerns, +leaving the selection of fonts and other typesetting details to the +individual author. +. +This discretion has led to divergent styling practices among authors +using it. +. +. +.Pp +.Xr mdoc +organizes its macros into +.Em domains . +. +The +.Em "page structure domain" +lays out the page and +comprises titles, +section headings, +displays, +and lists. +. +The +.Em "general text domain" +supplies macros to quote or style text, +or to interpolate common noun phrases. +. +The +.Em "manual domain" +offers semantic macros corresponding to the terminology used by +practitioners in discussion of +.Ux +commands, +routines, +and files. +. +Manual domain macros distinguish +command-line arguments and options, +function names, +function parameters, +pathnames, +variables, +cross references to other manual pages, +and so on. +. +These terms are meaningful both to the author and the readers of a +manual page. +. +It is hoped that the resulting increased consistency of the man page +corpus will enable easier translation to future documentation tools. +. +. +.Pp +Throughout +.Ux +documentation, +a manual entry is referred to simply as a +.Dq "man page" , +regardless of its length, +without gendered implication, +and irrespective of the macro package selected for its composition. +. +. +.Sh "Getting started" +. +The +.Xr mdoc +package attempts to simplify man page authorship and maintenance without +requiring mastery of the +.Xr roff +language. +. +This document presents only essential facts about +.Xr roff. +. +For further background, +including a discussion of basic typographical concepts like +.Dq breaking , +.Dq filling , +and +.Dq adjustment , +see +.Xr roff @MAN7EXT@ . +. +Specialized units of measurement also arise, +namely +ens, +vees, +inches, +and points, +abbreviated +.Dq n , +.Dq v , +.Dq i , +and +.Dq p , +respectively; +see section +.Sx Measurements +of +.Xr groff @MAN7EXT@ . +. +. +.Pp +For brief examples, +we employ an arrow notation illustrating a transformation of input on +the left to rendered output on the right. +. +Consider the +.Pf . Ic \&Dq +macro, +which double-quotes its arguments. +. +.Bl -tag -width ".Dq\ man page" -offset indent -compact +.It Li ".Dq man page" +\[->] +.Dq man page +.El +. +. +.Ss Usage +. +An +.Xr mdoc +.Em macro +is +.Em called +by placing the +.Xr roff +control character, +.Ql .\& +(dot) +at the beginning of a line followed by its name. +.\" XXX; All mdoc macro names except Brq, Bro, Brc are 2 characters long +.\" and thus portable to old troffs. Why the innovation here, when +.\" `Cq`, `Co`, and `Cc` were available? Try to sell this reform to +.\" Ingo Schwarze. +. +In this document, +we often discuss a macro name with this leading dot to identify it +clearly, +but the dot is +.Em not +part of its name. +. +Space or tab characters can separate the dot from the macro name. +. +Arguments may follow, +separated from the macro name and each other by spaces, +but +.Em not +tabs. +. +The dot at the beginning of the line prepares the formatter to expect a +macro name. +. +A dot followed immediately by a newline is ignored; +this is called the +.Em "empty request" . +. +To begin an input line with a dot +(or a neutral apostrophe +.Ql \[aq] ) +in some context other than a macro call, +precede it with the +.Ql \e& +escape sequence; +this is a dummy character, +not formatted for output. +. +The backslash is the +.Xr roff +escape character; +it can appear anywhere and it always followed by at least one more +character. +. +If followed by a newline, +the backslash escapes the input line break; +you can thus keep input lines to a reasonable length without affecting +their interpretation. +. +. +.Pp +Macros in GNU +.Xr troff +accept an unlimited number of arguments, +in contrast to other +.Xr troff Ns No s +that often can't handle more than nine. +. +In limited cases, +arguments may be continued or extended on the next input line without +resort to the +.Ql \[rs] Ns Em newline +escape sequence; +see subsection +.Sx "Extended arguments" +below. +. +Neutral double quotes +.Li \[dq] +can be used to group multiple words into an argument; +see subsection +.Sx "Passing space characters in an argument" +below. +. +. +.Pp +Most of +.Xr mdoc Ns No 's +general text and manual domain macros +.Em parse +their argument lists +for +.Em callable +macro names. +. +This means that an argument in the list matching a general text or +manual domain macro name +(and defined to be callable) +will be called with the remaining arguments when it is encountered. +. +In such cases, +the argument, +although the name of a macro, +is not preceded by a dot. +. +Macro calls can thus be nested. +. +This approach to macro argument processing is a unique characteristic of +the +.Xr mdoc +package, +not a general feature of +.Xr roff +syntax. +. +. +.Pp +For example, +the option macro, +.Pf . Ic \&Op , +may call the flag and argument macros, +.Pf . Ic \&Fl +and +.Pf . Ic \&Ar , +to specify an optional flag with an argument. +. +.\" Use width of second example below. +.Bl -tag -width ".Op\ \e&Fl\ s\ \e&Ar bytes" -offset indent -compact +.It Li ".Op Fl s Ar bytes" +\[->] +.Op Fl s Ar bytes +.El +. +To prevent a word from being interpreted as a macro name, +precede it with the dummy character. +. +.Bl -tag -width ".Op\ \e&Fl\ s\ \e&Ar bytes" -offset indent -compact +.It Li ".Op \e&Fl s \e&Ar bytes" +\[->] +.Op \&Fl s \&Ar bytes +.El +. +. +.Pp +In this document, +macros whose argument lists are parsed for callable arguments are +referred to as +.Em parsed , +and those that may be called from an argument list are referred to as +.Em callable . +. +This usage is a technical +.Em "faux pas" , +since all +.Xr mdoc +macros are in fact interpreted +(unless prevented with +.Ql \e& ) , +but as it is cumbersome to constantly refer to macros as +.Dq "being able to call other macros" , +we employ the term +.Dq parsed +instead. +. +Except where explicitly stated, +all +.Xr mdoc +macros are parsed and callable. +. +. +.Pp +In the following, +we term an +.Xr mdoc +macro that starts a line +(with a leading dot) +a +.Em command +if a distinction from those appearing as arguments of other macros is +necessary. +. +. +.Ss "Passing space characters in an argument" +. +Sometimes it is desirable to give a macro an argument containing one or +more space characters, +for instance to specify a particular arrangement of arguments demanded +by the macro. +. +Additionally, +quoting multi-word arguments that are to be treated the same makes +.Xr mdoc +work faster; +macros that parse arguments do so once +(at most) +for each. +. +For example, +the function command +.Pf . Ic \&Fn +expects its first argument to be the name of a function and any +remaining arguments to be function parameters. +. +Because C language standards mandate the inclusion of types +.Em and +identifiers in the parameter lists of function definitions, +each +.Ql \&Fn +parameter after the first will be at least two words in length, +as in +.Dq Ar "int foo" . +. +. +.Pp +There are a few ways to embed a space in a macro argument. +. +One is to use the unadjustable space escape sequence +.Li \[rs] Ns Em space . +. +The formatter treats this escape sequence as if it were any other +printable character, +and will not break a line there as it would a word space when the +output line is full. +. +This method is useful for macro arguments that are not expected to +straddle an output line boundary, +but has a drawback: +this space does not adjust as others do when the output line is +formatted. +. +An alternative is to use the unbreakable space escape sequence, +.Ql \[rs]\[ti] , +which cannot break but does adjust. +. +This +.Xr groff +extension is widely but not perfectly portable. +. +Another method is to enclose the string in double quotes. +. +.Bl -tag -width ".Fn\ fetch\ \[dq]char\ *str\[dq]" -offset indent \ +-compact +.It Li ".Fn fetch char\e *str" +\[->] +.Fn fetch char\ *str +.It Li ".Fn fetch char\e\[ti]*str" +\[->] +.Fn fetch char\~*str +.It Li ".Fn fetch \[dq]char *str\[dq]" +\[->] +.Fn fetch "char *str" +.El +. +If the +.Ql \[rs] +before the space in the first example +or the double quotes in the third example +were omitted, +.Ql .Fn +would see three arguments, +and the result would contain an undesired comma. +. +.\" Use same width as before so it's easier to see the discrepancy. +.Bl -tag -width ".Fn\ fetch\ \[dq]char\ *str\[dq]" -offset indent \ +-compact +.It Li ".Fn fetch char *str" +\[->] +.Fn fetch char *str +.El +. +. +.\".Pp +.\" For an example of what happens when the parameter list overlaps a +.\" newline boundary, +.\" see the +.\" .Sx Bugs +.\" section. +. +. +.Ss "Trailing space characters" +. +.\" XXX: This claim of confusion is nonsense. The formatter ignores +.\" them. If mdoc doesn't, that's a bug or design flaw. It's still +.\" good style not to have them. Whitespace churn makes diff(1) and +.\" revision control users unhappy. +.\" +.\".Xr @g@troff +.\"can be confused by space characters at the end of a line. +. +It is wise to remove trailing spaces from the ends of input lines. +. +Should the need arise to put a formattable space at the end of a line, +do so with the unadjustable or unbreakable space escape sequences. +. +. +.Ss "Formatting the backslash glyph" +. +When you need the +.Xr roff +escape character +.Ql \[rs] +to appear in the output, +use +.Ql \[rs]e +or +.Ql \[rs](rs +instead. +. +Technically, +.Ql \[rs]e +formats the current escape character; +it works reliably as long as no +.Xr roff +request is used to change it, +which should never happen in man pages. +. +.Ql \[rs](rs +is a +.Xr groff +special character escape sequence that explicitly formats the +.Dq "reverse solidus" +(backslash) glyph. +. +. +.Ss "Other possible pitfalls" +. +.Xr "groff mdoc" +warns when an empty input line is found outside of a +.Em display , +a topic presented in subsection +.Sx "Examples and displays" +below. +. +Use empty requests to space the source document for maintenance. +. +. +.Pp +Leading spaces cause a break and are formatted. +. +Avoid this behaviour if possible. +. +Similarly, +do not put more than one space between words in an ordinary text line; +they are not +.Dq normalized +to a single space as other text formatters might do. +. +. +.Pp +Don't try to use the neutral double quote character +.Ql \[dq] +to represent itself in an argument. +. +Use the special character escape sequence +.Ql \[rs](dq +to format it. +.\" That's NOT a groffism, but showed up in the "post" and "Latin1" +.\" devices of Tenth Edition Research Unix. +. +Further, +this glyph should not be used for conventional quotation; +.Xr mdoc +offers several quotation macros. +. +See subsection +.Sx "Enclosure and quoting macros" +below. +. +. +.Pp +The formatter attempts to detect the ends of sentences and by default +puts the equivalent of two spaces between sentences on the same output +line; +see +.Xr roff @MAN7EXT@ . +. +To defeat this detection in a parsed list of macro arguments, +put +.Ql \e& +before the punctuation mark. +. +Thus, +. +.Bd -literal -offset indent -compact +The +\&.Ql . +character. +\&.Pp +The +\&.Ql \e&. +character. +\&.Pp +\&.No test . +test +\&.Pp +\&.No test. +test +.Ed +. +gives +. +.Bd -filled -offset indent -compact +The +.Ql . +character +. +. +.Pp +The +.Ql \&. +character. +. +. +.Pp +.No test . +test +. +. +.Pp +.No test. +test +.Ed +. +as output. +. +As can be seen in the first and third output lines, +.Xr mdoc +handles punctuation characters specially in macro arguments. +. +This will be explained in section +.Sx "General syntax" +below. +. +. +.Pp +A comment in the source file of a man page can begin with +.Sq Li .\e" +at the start of an input line, +.Sq Li \e" +after other input, +or +.Sq Li \e# +anywhere +(the last is a +.Xr groff +extension); +the remainder of any such line is ignored. +. +. +.Sh "A man page template" +. +Use +.Xr mdoc +to construct a man page from the following template. +. +.Bd -literal -offset indent +\&.\e" The following three macro calls are required. +\&.Dd date +\&.Dt topic [section-identifier [section-keyword-or-title]] +\&.Os [package-or-operating system [version-or-release]] +\&.Sh Name +\&.Nm topic +\&.Nd summary-description +\&.\e" The next heading is used in sections 2 and 3. +\&.\e" .Sh Library +\&.\e" The next heading is used in sections 1-4, 6, 8, and 9. +\&.Sh Synopsis +\&.Sh Description +\&.\e" Uncomment and populate the following sections as needed. +\&.\e" .Sh \[dq]Implementation notes\[dq] +\&.\e" The next heading is used in sections 2, 3, and 9. +\&.\e" .Sh \[dq]Return values\[dq] +\&.\e" The next heading is used in sections 1, 3, 6, and 8. +\&.\e" .Sh Environment +\&.\e" .Sh Files +\&.\e" The next heading is used in sections 1, 6, and 8. +\&.\e" .Sh \[dq]Exit status\[dq] +\&.\e" .Sh Examples +\&.\e" The next heading is used in sections 1, 4, 6, 8, and 9. +\&.\e" .Sh Diagnostics +\&.\e" .Sh Compatibility +\&.\e" The next heading is used in sections 2, 3, 4, and 9. +\&.\e" .Sh Errors +\&.\e" .Sh \[dq]See also\[dq] +\&.\e" .Sh Standards +\&.\e" .Sh History +\&.\e" .Sh Authors +\&.\e" .Sh Caveats +\&.\e" .Sh Bugs +.Ed +. +. +.Pp +The first items in the template are the commands +.Pf . Ic \&Dd , +.Pf . Ic \&Dt , +and +.Pf . Ic \&Os . +. +They identify the page and are discussed below in section +.Sx "Title macros" . +. +. +.Pp +The remaining items in the template are section headings +.Pf ( Pf . Ic \&Sh ) ; +of which +.Sx Name +and +.Sx Description +are mandatory. +. +These headings are discussed in section +.Sx "Page structure domain" , +which follows section +.Sx "Manual domain" . +. +Familiarize yourself with manual domain macros first; +we use them to illustrate the use of page structure domain macros. +. +. +.Sh Conventions +. +In the descriptions of macros below, +square brackets surround optional arguments. +. +An ellipsis +.Pf ( Sq ... ) +represents repetition of the preceding argument zero or more times. +. +Alternative values of a parameter are separated with +.Ql | . +. +If a mandatory parameter can take one of several alternative values, +use braces to enclose the set, +with spaces and +.Ql | +separating the items. +. +.\" XXX: Angle brackets should only be necessary when space doesn't +.\" separate parameters. +.\" . +.\" Metasyntactic variables are specified within angle brackets. +.\"Bl -tag -width 6n -offset indent -compact +.Bl -tag -offset indent -compact +.It Nm ztar Xo +.Brq Cm c | Cm x +.Op Fl w Op Fl y | Fl z +.Op Fl f Ar archive +.Ar member No ... +.Xc +.El +. +An alternative to using braces is to separately synopsize distinct +operation modes, +particularly if the list of valid optional arguments is dependent on the +user's choice of a mandatory parameter. +. +.Bl -tag -offset indent -compact +.It Nm ztar Xo +.Cm c +.Op Fl w Op Fl y | Fl z +.Op Fl f Ar archive +.Ar member No ... +.Xc +.It Nm ztar Xo +.Cm x +.Op Fl w Op Fl y | Fl z +.Op Fl f Ar archive +.Ar member No ... +.Xc +.El +. +. +.Pp +Most macros affect subsequent arguments until another macro or a newline +is encountered. +. +For example, +.Sq Li ".Li ls Bq Ar file" +doesn't produce +.Sq Li "ls [file]" , +but +.Sq Li ls Bq Ar file . +. +Consequently, +a warning message is emitted for many commands if the first argument is +itself a macro, +since it cancels the effect of the preceding one. +.\" XXX: I don't think it is made clear which macros eat only one +.\" argument and which ones devour tokens until another macro is +.\" encountered. -- GBR +. +On rare occasions, +you might want to format a word along with surrounding brackets as a +literal. +. +.\" XXX: Why do we need the extra "\ " for the width parameter? Without +.\" it, the line breaks before the arrow on a 78n terminal. But there +.\" should be room anyway...bug? +.\" +.\" XXX: Arguably, Bq should respect the altered font family in a `Bl`, +.\" but it sets the brackets and argument in Times roman. Maybe all the +.\" enclosures work this way. +.Bl -tag -width "Li\ \[dq]ls\ [file]\[dq]\ " -offset indent -compact +.It Li ".Li \[dq]ls [file]\[dq]" +\[->] +.Li "ls [file]" +.Em "# list any files named e, f, i, or l" +.El +. +. +.Pp +Many macros possess an implicit width, +used when they are contained in lists and displays. +. +If you avoid relying on these default measurements, +you escape potential conflicts with site-local modifications of the +.Xr mdoc +package. +. +Explicit +.Fl width +and +.Fl offset +arguments to the +.Pf . Ic \&Bl +and +.Pf . Ic \&Bd +macros are preferable. +. +. +.Sh "Title macros" +. +We present the +.Sy mandatory +title macros first due to their importance even though they formally +belong to the page structure domain macros. +.\" XXX: This was formerly "...for someone who wishes to start writing a +.\" man page yesterday." +.\" +.\" Cute joke, but we're 800+ lines into this page source and four pages +.\" into the document when formatted for U.S. letter paper. We lost +.\" that kind of reader last _week_. +. +They designate the +topic, +date of last revision, +and the operating system or software project associated with the page. +. +Call each once at the beginning of the document. +. +They populate the page headers and footers, +which are in +.Xr roff +parlance termed +.Dq titles . +. +. +.Bl -tag -width 6n +.It Li .Dd Xo +.Ar date +.Xc +This first macro of any +.Xr mdoc +manual records the last modification date of the document source. +. +Arguments are concatenated and separated with space characters. +. +. +.Pp +Historically, +.Ar date +was written in U.S.\& traditional format, +.Do +.\" XXX: Em -> Ar when we de-Courierize .Ar. +.Em Month day Li , Em year +.Dc +where +.Em Month +is the full month name in English, +.Em day +an integer without a leading zero, +and +.Em year +the four-digit year. +. +This localism is not enforced, +however. +. +You may prefer ISO 8601 format, +.Em YYYY-MM-DD. +. +A +.Ar date +of the form +.Sq Li $Mdocdate: Ar Month day year Li $ +is also recognized. +. +It is used in +.Ox +manuals to automatically insert the current date when committing. +. +. +.Pp +This macro is neither callable nor parsed. +. +. +.br +.ne 5v +.It Li .Dt Ar topic Op Ar section-identifier \ +Op Ar section-keyword-or-title +. +.Ar topic +is the subject of the man page. +. +A +.Ar section-identifier +that begins with an integer in the range 1\[en]9 +or is one of the words +.Ql unass , +.Ql draft , +or +.Ql paper +selects a predefined section title. +. +This use of +.Dq section +has nothing to do with the section headings otherwise discussed in this +page; +it arises from the organizational scheme of printed and bound Unix +manuals. +. +. +.br +.ne 3v +.Pp +In this implementation, +the following titles are defined for integral section numbers. +. +. +.Bd -unfilled -offset indent +.TS +Lf(CR) L. +1 \*[doc-volume-ds-1] +2 \*[doc-volume-ds-2] +3 \*[doc-volume-ds-3] +4 \*[doc-volume-ds-4] +5 \*[doc-volume-ds-5] +6 \*[doc-volume-ds-6] +7 \*[doc-volume-ds-7] +8 \*[doc-volume-ds-8] +9 \*[doc-volume-ds-9] +.TE +.Ed +. +. +.Pp +A section title may be arbitrary or one of the following abbreviations. +. +. +.Bd -unfilled -offset indent +.TS +Lf(CR) L. +USD \*[doc-volume-ds-USD] +PS1 \*[doc-volume-ds-PS1] +AMD \*[doc-volume-ds-AMD] +SMM \*[doc-volume-ds-SMM] +URM \*[doc-volume-ds-URM] +PRM \*[doc-volume-ds-PRM] +KM \*[doc-volume-ds-KM] +IND \*[doc-volume-ds-IND] +LOCAL \*[doc-volume-ds-LOCAL] +CON \*[doc-volume-ds-CON] +.TE +.Ed +. +. +.Pp +For compatibility, +.Ql MMI +can be used for +.Ql IND , +and +.Ql LOC +for +.Ql LOCAL . +. +Values from the previous table will specify a new section title. +. +If +.Ar section-keyword-or-title +designates a computer architecture recognized by +.Xr "groff mdoc" , +its value is prepended to the default section title as specified by the +second parameter. +.\" mandoc(1) appears to put the architecture string after (or in place +.\" of) the section title, in parentheses. +. +By default, +the following architecture keywords are defined. +. +\# we use 'No' to avoid hyphenation +.\" Resort to ps/vs violence if necessary because this macro package is +.\" obsessed with dumping gigantic piles of identifiers on users, and I +.\" need the space to keep this macro description to a single page in +.\" PS/PDF(!). Lists of information like this simply beg to bit-rot. +.\" -- GBR +.br +.ps -2 +.vs -2 +.Bd -ragged -offset 4n +.No acorn26 , acorn32 , algor , alpha , amd64 , amiga , amigappc , +.No arc , arm , arm26 , arm32 , armish , atari , aviion , +.No beagle , bebox , cats , cesfic , cobalt , dreamcast , +.No emips , evbarm , evbmips , evbppc , evbsh3 , ews4800mips , +.No hp300 , hp700 , hpcarm , hpcmips , hpcsh , hppa , hppa64 , +.No i386 , ia64 , ibmnws , iyonix , landisk , loongson , luna68k , +.No luna88k , m68k , mac68k , macppc , mips , mips64 , mipsco , mmeye , +.No mvme68k , mvme88k , mvmeppc , netwinder , news68k , newsmips , +.No next68k , ofppc , palm , pc532 , playstation2 , pmax , pmppc , +.No powerpc , prep , rs6000 , sandpoint , sbmips , sgi , sgimips , sh3 , +.No shark , socppc , solbourne , sparc , sparc64 , sun2 , sun3 , +.No tahoe , vax , x68k , x86_64 , xen , zaurus +.Ed +.vs +.ps +. +. +.Pp +If a section title is not determined after the above matches have been +attempted, +.Ar section-keyword-or-title +is used. +. +. +.br +.ne 10v \" Keep explanatory paragraph with the following table. +.Pp +The effects of varying +.Ql .Dt +arguments on the page header content +are shown below. +. +Observe how +.Ql \[rs]& +prevents the numeral\~2 from being used to look up a predefined section +title. +. +. +.Pp +.\" On terminals, 2n is as far as we can offset without overrunning a +.\" 78n width. +.Bd -unfilled -offset 2n +.TS +tab(@); +Lf(CR)1 L2 L C R. +\&.Dt foo 2@\[->]@foo(2)@System Calls Manual@foo(2) +\&.Dt foo 2 m68k@\[->]@foo(2)@m68k System Calls Manual@foo(2) +\&.Dt foo 2 baz@\[->]@foo(2)@System Calls Manual@foo(2) +\&.Dt foo \[rs]&2 baz@\[->]@foo(2)@baz@foo(2) +\&.Dt foo \[dq]\[dq] baz@\[->]@foo@baz@foo +\&.Dt foo M Z80@\[->]@foo(M)@Z80@foo(M) +.TE +.Ed +. +. +.Pp +.Xr roff +strings define section titles and architecture identifiers. +. +Site-specific additions might be found in the file +.Pa mdoc.local ; +see section +.Sx Files +below. +. +. +.Pp +This macro is neither callable nor parsed. +. +. +.It Li .Os Op Ar operating-system-or-package-name \ +Op Ar version-or-release +. +This macro associates the document with a software distribution. +. +When composing a man page to be included in the base installation of an +operating system, +do not provide an argument; +.Xr mdoc +will supply it. +. +In this implementation, +that default is +.Dq "\*[doc-default-operating-system]" . +. +It may be overridden in the site configuration file, +.Pa mdoc.local ; +see section +.Sx Files +below. +. +A portable software package maintaining its own man pages can supply +its name and version number or release identifier as optional arguments. +. +A +.Em version-or-release +argument should use the standard nomenclature for the software +specified. +. +In the following table, +recognized +.Em version-or-release +arguments for some predefined operating systems are listed. +. +As with +.Pf . Ic \&Dt , +site additions might be defined in +.Pa mdoc.local . +. +.Bd -ragged -compact +.Bl -tag -width ".No DragonFly" -offset indent +.It ATT +7th, 7, III, 3, V, V.2, V.3, V.4 +.It BSD +3, 4, 4.1, 4.2, 4.3, 4.3t, 4.3T, 4.3r, 4.3R, 4.4 +.It NetBSD +0.8, 0.8a, 0.9, 0.9a, 1.0, 1.0a, 1.1, 1.2, 1.2a, 1.2b, 1.2c, 1.2d, 1.2e, +1.3, 1.3a, 1.4, 1.4.1, 1.4.2, 1.4.3, 1.5, 1.5.1, 1.5.2, 1.5.3, 1.6, +1.6.1, 1.6.2, 1.6.3, 2.0, 2.0.1, 2.0.2, 2.0.3, 2.1, 3.0, 3.0.1, 3.0.2, +3.0.3, 3.1, 3.1.1, 4.0, 4.0.1, 5.0, 5.0.1, 5.0.2, 5.1, 5.1.2, 5.1.3, +5.1.4, 5.2, 5.2.1, 5.2.2, 6.0, 6.0.1, 6.0.2, 6.0.3, 6.0.4, 6.0.5, 6.0.6, +6.1, 6.1.1, 6.1.2, 6.1.3, 6.1.4, 6.1.5, 7.0, 7.0.1, 7.0.2, 7.1, 7.1.1, +7.1.2, 7.2, 8.0, 8.1 +.It FreeBSD +1.0, 1.1, 1.1.5, 1.1.5.1, 2.0, 2.0.5, 2.1, 2.1.5, 2.1.6, 2.1.7, 2.2, +2.2.1, 2.2.2, 2.2.5, 2.2.6, 2.2.7, 2.2.8, 2.2.9, 3.0, 3.1, 3.2, 3.3, +3.4, 3.5, 4.0, 4.1, 4.1.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.6.2, 4.7, 4.8, +4.9, 4.10, 4.11, 5.0, 5.1, 5.2, 5.2.1, 5.3, 5.4, 5.5, 6.0, 6.1, 6.2, +6.3, 6.4, 7.0, 7.1, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, 8.3, 8.4, 9.0, 9.1, +9.2, 9.3, 10.0, 10.1, 10.2, 10.3, 10.4, 11.0, 11.1, 11.2, 11.3, 12.0, +12.1 +.It OpenBSD +2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.1, 3.2, 3.3, +3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4.0, 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, +4.8, 4.9, 5.0, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 5.9, 6.0, 6.1, +6.2, 6.3, 6.4, 6.5, 6.6 +.It DragonFly +1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.8.1, 1.9, 1.10, 1.11, +1.12, 1.12.2, 1.13, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, +2.9.1, 2.10, 2.10.1, 2.11, 2.12, 2.13, 3.0, 3.0.1, 3.0.2, 3.1, 3.2, +3.2.1, 3.2.2, 3.3, 3.4, 3.4.1, 3.4.2, 3.4.3, 3.5, 3.6, 3.6.1, 3.6.2, +3.7, 3.8, 3.8.1, 3.8.2, 4.0, 4.0.1, 4.0.2, 4.0.3, 4.0.4, 4.0.5, 4.0.6, +4.1, 4.2, 4.2.1, 4.2.2, 4.2.3, 4.2.4, 4.3, 4.4, 4.4.1, 4.4.2, 4.4.3, +4.5, 4.6, 4.6.1, 4.6.2, 4.7, 4.8, 4.8.1, 4.9, 5.0, 5.0.1, 5.0.2, 5.1, +5.2, 5.2.1, 5.2.2, 5.3, 5.4, 5.4.1, 5.4.2, 5.4.3, 5.5, 5.6, 5.6.1, 5.6.2 +.It Darwin +8.0.0, 8.1.0, 8.2.0, 8.3.0, 8.4.0, 8.5.0, 8.6.0, 8.7.0, 8.8.0, 8.9.0, +8.10.0, 8.11.0, 9.0.0, 9.1.0, 9.2.0, 9.3.0, 9.4.0, 9.5.0, 9.6.0, 9.7.0, +9.8.0, 10.0.0, 10.1.0, 10.2.0, 10.3.0, 10.4.0, 10.5.0, 10.6.0, 10.7.0, +10.8.0, 11.0.0, 11.1.0, 11.2.0, 11.3.0, 11.4.0, 11.5.0, 12.0.0, 12.1.0, +12.2.0, 13.0.0, 13.1.0, 13.2.0, 13.3.0, 13.4.0, 14.0.0, 14.1.0, 14.2.0, +14.3.0, 14.4.0, 14.5.0, 15.0.0, 15.1.0, 15.2.0, 15.3.0, 15.4.0, 15.5.0, +15.6.0, 16.0.0, 16.1.0, 16.2.0, 16.3.0, 16.4.0, 16.5.0, 16.6.0, 17.0.0, +17.1.0, 17.2.0, 17.3.0, 17.4.0, 17.5.0, 17.6.0, 17.7.0, 18.0.0, 18.1.0, +18.2.0, 18.3.0, 18.4.0, 18.5.0, 18.6.0, 18.7.0, 19.0.0, 19.1.0, 19.2.0 +.El +.Ed +. +. +.Pp +Historically, +the first argument used with +.Pf . Ic \&Dt +was +.Li BSD +or +.Li ATT . +. +An unrecognized version argument after +.Li ATT +is replaced with +.Dq Ux ; +for other predefined abbreviations, +it is ignored and a warning diagnostic emitted. +. +Otherwise, +unrecognized arguments are displayed verbatim in the page footer. +. +For instance, +this page uses +.Dq Li .Os groff @VERSION@ +whereas a locally produced page might employ +.Dq Li .Os \[dq]UXYZ CS Department\[dq] , +omitting versioning. +. +. +.Pp +This macro is neither callable nor parsed. +.El +. +. +.br +.ne 4v +.Sh "Introduction to manual and general text domains" +. +. +.Ss "What's in a Name" Ns ... \" XXX: Ns not scrubbed for PDF bookmark +. +The manual domain macro names are derived from the day to day informal +language used to describe commands, subroutines and related files. +Slightly different variations of this language are used to describe the +three different aspects of writing a man page. +First, there is the description of +.Xr mdoc +macro command usage. +Second is the description of a +.Ux +command +.Em with +.Xr mdoc +macros, and third, the description of a command to a user in the verbal +sense; that is, discussion of a command in the text of a man page. +. +. +.Pp +In the first case, +.Xr @g@troff +macros are themselves a type of command; +the general syntax for a +.Xr troff +command is: +. +.Bd -filled -offset indent +.Li ".Xx argument1 argument2" ... +.Ed +. +. +.Pp +. +.Ql .Xx +is a macro command, and anything following it are arguments to +be processed. +In the second case, the description of a +.Ux +command using the manual domain macros is a bit more involved; +a typical +.Sx Synopsis +command line might be displayed as: +. +.Bd -filled -offset indent +.Nm filter +.Op Fl flag +.Ao Ar infile Ac Ao Ar outfile Ac +.Ed +. +. +.Pp +Here, +.Nm filter +is the command name and the +bracketed string +.Fl flag +is a +.Em flag +argument designated as optional by the option brackets. +In +.Xr mdoc +terms, +.Ao Ar infile Ac +and +.Ao Ar outfile Ac +are called +.Em meta arguments ; +in this example, the user has to replace the meta expressions given in angle +brackets with real file names. +Note that in this document meta arguments are used to describe +.Xr mdoc +commands; in most man pages, meta variables are not specifically written +with angle brackets. +. +The macros that formatted the above example: +. +.Bd -literal -offset indent +\&.Nm filter +\&.Op Fl flag +\&.Ao Ar infile Ac Ao Ar outfile Ac +.Ed +. +. +.Pp +In the third case, +discussion of commands and command syntax includes both examples above, +but may add more detail. +. +The arguments +.Ao Ar infile Ac +and +.Ao Ar outfile Ac +from the example above might be referred to as +.Em operands +or +.Em file arguments . +. +Some command-line argument lists are quite long: +. +.Bd -ragged +.Bl -tag -width ".Nm make" -offset indent -compact +.It Nm make +.Op Fl eiknqrstv +.Op Fl D Ar variable +.Op Fl d Ar flags +.Op Fl f Ar makefile +.Op Fl I Ar directory +.Op Fl j Ar max_jobs +.Op Ar variable Ns = Ns Ar value +.Bk +.Op Ar target No ... +.Ek +.El +.Ed +. +. +.Pp +Here one might talk about the command +.Xr make +and qualify the argument, +.Ar makefile , +as an argument to the flag, +.Fl f , +or discuss the optional file operand +.Ar target . +In the verbal context, such detail can prevent confusion, however the +.Xr mdoc +package does not have a macro for an argument +.Em to +a flag. +Instead the +.Ql \&Ar +argument macro is used for an operand or file argument like +.Ar target +as well as an argument to a flag like +.Ar variable . +The make command line was produced from: +. +.Bd -literal -offset indent +\&.Nm make +\&.Op Fl eiknqrstv +\&.Op Fl D Ar variable +\&.Op Fl d Ar flags +\&.Op Fl f Ar makefile +\&.Op Fl I Ar directory +\&.Op Fl j Ar max_jobs +\&.Op Ar variable Ns = Ns Ar value +\&.Bk +\&.Op Ar target ... +\&.Ek +.Ed +. +. +.Pp +The +.Ql .Bk +and +.Ql .Ek +macros are explained in +.Sx Keeps . +. +. +.Ss "General Syntax" +. +The manual domain and general text domain macros share a similar syntax +with a few minor deviations; +most notably, +.Ql .Ar , +.Ql .Fl , +.Ql .Nm , +and +.Ql .Pa +differ only when called without arguments; and +.Ql .Fn +and +.Ql .Xr +impose an order on their argument lists. +. +All manual domain macros are capable of recognizing and properly +handling punctuation, +provided each punctuation character is separated by a leading space. +. +If a command is given: +. +. +.Pp +.Dl \&.Ar sptr, ptr), +. +. +.Pp +The result is: +. +. +.Pp +.Dl Ar sptr, ptr), +. +. +.Pp +The punctuation is not recognized and all is output in the +font used by +.Ql .Ar . +If the punctuation is separated by a leading white space: +. +. +.Pp +.Dl \&.Ar "sptr , ptr ) ," +. +. +.Pp +The result is: +. +. +.Pp +.Dl Ar sptr , ptr ) , +. +. +.Pp +The punctuation is now recognized and output in the default font +distinguishing it from the argument strings. +. +To remove the special meaning from a punctuation character, +escape it with +.Ql \e& . +. +. +.Pp +The following punctuation characters are recognized by +.Xr mdoc : +. +.Bl -column -offset indent-two XXXXXX XXXXXX XXXXXX XXXXXX +.It Li .\& Ta Li ,\& Ta Li :\& Ta Li ;\& Ta Li (\& +.It Li )\& Ta Li [\& Ta Li ]\& Ta Li ?\& Ta Li !\& +.El +. +. +.Pp +. +.Xr troff +is limited as a macro language, +and has difficulty when presented with a string containing certain +mathematical, +logical, +or quotation character sequences: +. +.Bd -literal -offset indent-two +{+,\-,/,*,%,<,>,<=,>=,=,==,&,\[ga],\[aq],"} +.Ed +. +. +.Pp +The problem is that +.Xr troff +may assume it is supposed to actually perform the operation or +evaluation suggested by the characters. +. +To prevent the accidental evaluation of these characters, +escape them with +.Ql \e& . +. +Typical syntax is shown in the first manual domain macro displayed +below, +.Ql .Ad . +. +. +.Sh "Manual domain" +. +. +.Ss Addresses +. +The address macro identifies an address construct. +. +. +.Pp +.Dl Usage: .Ad Ao address Ac ... +. +. +.Pp +.Bl -tag -width ".Li .Ad\ f1\ ,\ f2\ ,\ f3\ :" -compact -offset 15n +.It Li ".Ad addr1" +.Ad addr1 +.It Li ".Ad addr1 ." +.Ad addr1 . +.It Li ".Ad addr1 , file2" +.Ad addr1 , file2 +.It Li ".Ad f1 , f2 , f3 :" +.Ad f1 , f2 , f3 : +.It Li ".Ad addr ) ) ," +.Ad addr ) ) , +.El +. +. +.Pp +The default width is 12n. +. +.Ss "Author Name" +. +The +.Ql .An +macro is used to specify the name of the author of the item being +documented, or the name of the author of the actual manual page. +. +. +.Pp +.Dl Usage: .An Ao author name Ac ... +. +. +.Pp +.Bl -tag -width ".Li .An\ \[dq]Joe\ Author\[dq]\ )\ )\ ," -offset 15n +.It Li ".An \[dq]Joe Author\[dq]" +.An "Joe Author" +.It Li ".An \[dq]Joe Author\[dq] ," +.An "Joe Author" , +.It Li ".An \[dq]Joe Author\[dq] Aq nobody@FreeBSD.org" +.An "Joe Author" Aq nobody@FreeBSD.org +.It Li ".An \[dq]Joe Author\[dq] ) ) ," +.An "Joe Author" ) ) , +.El +. +. +.Pp +The default width is 12n. +. +. +.Pp +In a section titled +.Dq Authors , +.Ql \&An +causes a break, +allowing each new name to appear on its own line. +. +If this is not desirable, +. +.Bd -literal -offset indent +\&.An \-nosplit +.Ed +. +. +.Pp +. +call will turn this off. +To turn splitting back on, write +. +.Bd -literal -offset indent +\&.An \-split +.Ed +. +. +.Ss Arguments +. +The +.Li .Ar +argument macro may be used whenever an argument is referenced. +. +If called without arguments, +.Sq Ar +is output. +. +This places the ellipsis in italics, +which is ugly and incorrect, +and will be noticed on terminals that underline text instead of using an +oblique typeface. +. +We recommend using +.Ql ".Ar file \&No ..." +instead. +. +. +.Pp +.Dl Usage: .Ar Oo Ao argument Ac Oc No ... +. +. +.Pp +.Bl -tag -width ".Li .Ar\ file1\ file2" -compact -offset 15n +.It Li .Ar +.Ar +.It Li .Ar file \&No ... +.Ar file No ... +.It Li ".Ar file1" +.Ar file1 +.It Li ".Ar file1 ." +.Ar file1 . +.It Li ".Ar file1 file2" +.Ar file1 file2 +.It Li ".Ar f1 f2 f3 :" +.Ar f1 f2 f3 : +.It Li ".Ar file ) ) ," +.Ar file ) ) , +.El +. +. +.Pp +. +The default width is 12n. +. +. +.Ss "Configuration Declaration (Section Four Only)" +. +The +.Ql .Cd +macro is used to demonstrate a +.Xr config 8 +declaration for a device interface in a section four manual. +. +. +.Pp +.Dl Usage: .Cd Ao argument Ac ... +. +. +.Pp +.Bl -tag -width ".Li .Cd\ Xdevice\ le0\ at\ scode?X" -offset 15n +.It Li ".Cd \[dq]device le0 at scode?\[dq]" +.Cd "device le0 at scode?" +.El +. +. +.Pp +In a section titled +.Dq Synopsis , +.Ql \&Cd +causes a break before and after its arguments. +. +. +.Pp +The default width is 12n. +. +. +.Ss "Command Modifiers" +. +The command modifier is identical to the +.Ql .Fl +(flag) command with the exception that the +.Ql .Cm +macro does not assert a dash in front of every argument. +Traditionally flags are marked by the preceding dash, however, some commands +or subsets of commands do not use them. +Command modifiers may also be specified in conjunction with interactive +commands such as editor commands. +See +.Sx Flags . +. +. +.Pp +The default width is 10n. +. +. +.Ss "Defined Variables" +. +A variable +(or constant) +that is defined in an include file is specified by the macro +.Ql .Dv . +. +. +.Pp +.Dl Usage: .Dv Ao defined-variable Ac ... +. +. +.Pp +.Bl -tag -width ".Li .Dv\ MAXHOSTNAMELEN" -compact -offset 15n +.It Li ".Dv MAXHOSTNAMELEN" +.Dv MAXHOSTNAMELEN +.It Li ".Dv TIOCGPGRP )" +.Dv TIOCGPGRP ) +.El +. +. +.Pp +. +The default width is 12n. +. +. +.Ss Errnos +. +The +.Ql .Er +errno macro specifies the error return value for section 2, +3, +and\~9 library routines. +. +The second example below shows +.Ql .Er +used with the +.Ql .Bq +general text domain macro, +as it would be used in a section two manual page. +. +. +.Pp +.Dl Usage: .Er Ao errno type Ac ... +.Pp +.Bl -tag -width ".Li .Bq\ Er\ ENOTDIR" -compact -offset 15n +.It Li ".Er ENOENT" +.Er ENOENT +.It Li ".Er ENOENT ) ;" +.Er ENOENT ) ; +.It Li ".Bq Er ENOTDIR" +.Bq Er ENOTDIR +.El +.Pp +. +The default width is 17n. +. +. +.Ss "Environment Variables" +. +The +.Ql .Ev +macro specifies an environment variable. +.Pp +.Dl Usage: .Ev Ao argument Ac ... +.Pp +.Bl -tag -width ".Li .Ev\ PRINTER\ )\ )\ ," -compact -offset 15n +.It Li ".Ev DISPLAY" +.Ev DISPLAY +.It Li ".Ev PATH ." +.Ev PATH . +.It Li ".Ev PRINTER ) ) ," +.Ev PRINTER ) ) , +.El +.Pp +. +The default width is 15n. +. +. +.Ss Flags +. +The +.Ql .Fl +macro handles command-line flags. +It prepends a dash, +.Ql \- , +to the flag. +. +For interactive command flags that are not prepended with a dash, +the +.Ql .Cm +(command modifier) +macro is identical, +but without the dash. +. +. +.Pp +.Dl Usage: .Fl Ao argument Ac ... +.Pp +.Bl -tag -width ".Li .Fl\ xyz\ )\ ," -compact -offset 15n +.It Li .Fl +.Fl +.It Li ".Fl cfv" +.Fl cfv +.It Li ".Fl cfv ." +.Fl cfv . +.It Li ".Cm cfv ." +.Cm cfv . +.It Li ".Fl s v t" +.Fl s v t +.It Li ".Fl \- ," +.Fl \- , +.It Li ".Fl xyz ) ," +.Fl xyz ) , +.It Li ".Fl |" +.Fl | +.El +.Pp +The +.Ql .Fl +macro without any arguments results in a dash representing stdin/stdout. +Note that giving +.Ql .Fl +a single dash will result in two dashes. +.Pp +The default width is 12n. +. +. +.Ss "Function Declarations" +. +The +.Ql .Fd +macro is used in the +.Sx Synopsis +section with section two or three functions. +It is neither callable nor parsed. +.Pp +.Dl Usage: .Fd Ao argument Ac ... +.Pp +.Bl -tag -width ".Li .Fd\ X#include\ X" -compact -offset 15n +.It Li ".Fd \[dq]#include \[dq]" +.Fd "#include " +.El +. +. +.Pp +In a section titled +.Dq Synopsis , +.Ql \&Fd +causes a break if a function has already been presented and a break has +not occurred, +leaving vertical space between one function declaration and the next. +.\" XXX: that's not what "break" means +. +. +.Pp +In a section titled +.Dq Synopsis , +the +.Ql \&In +macro represents the +.Li #include +statement, +and is the short form of the above example. +. +It specifies the C\~header file as being included in a C\~program. +. +It also causes a break. +. +. +.Pp +While not in the +.Dq Synopsis +section, +it represents the header file enclosed in angle brackets. +. +. +.Pp +.Dl Usage: .In Ao header file Ac +. +. +.Pp +.Bl -tag -width ".Li .In\ stdio.h" -compact -offset 15n +.nr in-synopsis-section 1 +.It Li ".In stdio.h" +.In stdio.h +.nr in-synopsis-section 0 +.It Li ".In stdio.h" +.In stdio.h +.El +. +. +.Ss "Function Types" +. +This macro is intended for the +.Dq Synopsis +section. +. +It may be used anywhere else in the man page without problems, +but its main purpose is to present the function type +(in BSD kernel normal form) +for the +.Dq Synopsis +of sections two and three. +. +(It causes a break, +allowing the function name to appear on the next line.) +. +. +.Pp +.Dl Usage: .Ft Ao type Ac ... +.Pp +.Bl -tag -width ".Li .Ft\ struct\ stat" -compact -offset 15n +.It Li ".Ft struct stat" +.Ft struct stat +.El +. +. +.Ss "Functions (Library Routines)" +. +The +.Ql .Fn +macro is modeled on +.Tn ANSI\~C +conventions. +.Pp +.Dl Usage: .Fn Ao function Ac Oo Ao parameter Ac Oc ... +.Pp +.Bl -tag -width ".Li .Fn\ align\ Xchar\ *ptrX\ ," -compact -offset 15n +.It Li ".Fn getchar" +.Fn getchar +.It Li ".Fn strlen ) ," +.Fn strlen ) , +.It Li ".Fn align \[dq]char *ptr\[dq] ," +.Fn align "char *ptr" , +.El +.Pp +Note that any call to another macro signals the end of the +.Ql .Fn +call (it will insert a closing parenthesis at that point). +. +. +.Pp +For functions with many parameters +(which is rare), +the macros +.Ql .Fo +(function open) +and +.Ql .Fc +(function close) +may be used with +.Ql .Fa +(function argument). +.Pp +Example: +. +.Bd -literal -offset indent +\&.Ft int +\&.Fo res_mkquery +\&.Fa "int op" +\&.Fa "char *dname" +\&.Fa "int class" +\&.Fa "int type" +\&.Fa "char *data" +\&.Fa "int datalen" +\&.Fa "struct rrec *newrr" +\&.Fa "char *buf" +\&.Fa "int buflen" +\&.Fc +.Ed +.Pp +. +Produces: +. +.Bd -ragged -offset indent +.Ft int +.Fo res_mkquery +.Fa "int op" +.Fa "char *dname" +.Fa "int class" +.Fa "int type" +.Fa "char *data" +.Fa "int datalen" +.Fa "struct rrec *newrr" +.Fa "char *buf" +.Fa "int buflen" +.Fc +.Ed +. +. +.Pp +Typically, +in a +.Dq Synopsis +section, +the function delcaration will begin the line. +. +If more than one function is presented in the +.Dq Synopsis +section and a function type has not been given, +a break will occur, +leaving vertical space between the current and prior function names. +.\" XXX: that's not what "break" means +. +. +.Pp +The default width values of +.Ql .Fn +and +.Ql .Fo +are 12n and 16n, +respectively. +. +. +.Ss "Function Arguments" +. +The +.Ql .Fa +macro is used to refer to function arguments (parameters) outside of the +.Sx Synopsis +section of the manual or inside the +.Sx Synopsis +section if the enclosure macros +.Ql .Fo +and +.Ql .Fc +instead of +.Ql .Fn +are used. +.Ql .Fa +may also be used to refer to structure members. +.Pp +.Dl Usage: .Fa Ao function argument Ac ... +.Pp +.Bl -tag -width ".Li .Fa\ d_namlen\ )\ )\ ," -compact -offset 15n +.It Li ".Fa d_namlen ) ) ," +.Fa d_namlen ) ) , +.It Li ".Fa iov_len" +.Fa iov_len +.El +.Pp +. +The default width is 12n. +. +. +.Ss "Return Values" +. +The +.Ql .Rv +macro generates text for use in the +.Sx Return values +section. +.Pp +.Dl Usage: .Rv Oo \-std Oc Op Ao function Ac ... +.Pp +For example, +.Ql ".Rv \-std atexit" +produces: +. +.Bd -ragged -offset indent +\# a small hack to suppress a warning message +.ds doc-section-old "\*[doc-section] +.ds doc-section 3 +.Rv -std atexit +.ds doc-section "\*[doc-section-old] +.Ed +.Pp +. +The +.Fl std +option is valid only for manual page sections\~2 and\~3. +Currently, this macro does nothing if used without the +.Fl std +flag. +. +. +.Ss "Exit Status" +. +The +.Ql .Ex +macro generates text for use in the +.Sx Diagnostics +section. +.Pp +.Dl Usage: .Ex Oo \-std Oc Op Ao utility Ac ... +.Pp +For example, +.Ql ".Ex \-std cat" +produces: +. +.Bd -ragged -offset indent +\# a small hack to suppress a warning message +.ds doc-section-old "\*[doc-section] +.ds doc-section 1 +.Ex -std cat +.ds doc-section "\*[doc-section-old] +.Ed +.Pp +. +The +.Fl std +option is valid only for manual page sections 1, 6 and\~8. +Currently, this macro does nothing if used without the +.Fl std +flag. +. +. +.Ss "Interactive Commands" +. +The +.Ql .Ic +macro designates an interactive or internal command. +.Pp +.Dl Usage: .Ic Ao argument Ac ... +.Pp +.Bl -tag -width ".Li .Ic\ setenv\ ,\ unsetenv" -compact -offset 15n +.It Li ".Ic :wq" +.Ic :wq +.It Li ".Ic \[dq]do while {...}\[dq]" +.Ic "do while {...}" +.It Li ".Ic setenv , unsetenv" +.Ic setenv , unsetenv +.El +.Pp +. +The default width is 12n. +. +. +.Ss "Library Names" +. +The +.Ql .Lb +macro is used to specify the library where a particular function is compiled +in. +.Pp +.Dl Usage: .Lb Ao argument Ac ... +.Pp +Available arguments to +.Ql .Lb +and their results are: +. +.Pp +.Bl -tag -width ".Li librpcsec_gss" -compact -offset indent +.It Li libarchive +.Lb libarchive +.It Li libarm +.Lb libarm +.It Li libarm32 +.Lb libarm32 +.It Li libbluetooth +.Lb libbluetooth +.It Li libbsm +.Lb libbsm +.It Li libc +.Lb libc +.It Li libc_r +.Lb libc_r +.It Li libcalendar +.Lb libcalendar +.It Li libcam +.Lb libcam +.It Li libcdk +.Lb libcdk +.It Li libcipher +.Lb libcipher +.It Li libcompat +.Lb libcompat +.It Li libcrypt +.Lb libcrypt +.It Li libcurses +.Lb libcurses +.It Li libdevinfo +.Lb libdevinfo +.It Li libdevstat +.Lb libdevstat +.It Li libdisk +.Lb libdisk +.It Li libdwarf +.Lb libdwarf +.It Li libedit +.Lb libedit +.It Li libelf +.Lb libelf +.It Li libevent +.Lb libevent +.It Li libfetch +.Lb libfetch +.It Li libform +.Lb libform +.It Li libgeom +.Lb libgeom +.It Li libgpib +.Lb libgpib +.It Li libi386 +.Lb libi386 +.It Li libintl +.Lb libintl +.It Li libipsec +.Lb libipsec +.It Li libipx +.Lb libipx +.It Li libiscsi +.Lb libiscsi +.It Li libjail +.Lb libjail +.It Li libkiconv +.Lb libkiconv +.It Li libkse +.Lb libkse +.It Li libkvm +.Lb libkvm +.It Li libm +.Lb libm +.It Li libm68k +.Lb libm68k +.It Li libmagic +.Lb libmagic +.It Li libmd +.Lb libmd +.It Li libmemstat +.Lb libmemstat +.It Li libmenu +.Lb libmenu +.It Li libnetgraph +.Lb libnetgraph +.It Li libnetpgp +.Lb libnetpgp +.It Li libossaudio +.Lb libossaudio +.It Li libpam +.Lb libpam +.It Li libpcap +.Lb libpcap +.It Li libpci +.Lb libpci +.It Li libpmc +.Lb libpmc +.It Li libposix +.Lb libposix +.It Li libprop +.Lb libprop +.It Li libpthread +.Lb libpthread +.It Li libpuffs +.Lb libpuffs +.It Li librefuse +.Lb librefuse +.It Li libresolv +.Lb libresolv +.It Li librpcsec_gss +.Lb librpcsec_gss +.It Li librpcsvc +.Lb librpcsvc +.It Li librt +.Lb librt +.It Li libsdp +.Lb libsdp +.It Li libssp +.Lb libssp +.It Li libSystem +.Lb libSystem +.It Li libtermcap +.Lb libtermcap +.It Li libterminfo +.Lb libterminfo +.It Li libthr +.Lb libthr +.It Li libufs +.Lb libufs +.It Li libugidfw +.Lb libugidfw +.It Li libulog +.Lb libulog +.It Li libusbhid +.Lb libusbhid +.It Li libutil +.Lb libutil +.It Li libvgl +.Lb libvgl +.It Li libx86_64 +.Lb libx86_64 +.It Li libz +.Lb libz +.El +. +. +.Pp +Site-specific additions might be found in the file +.Pa mdoc.local ; +see section +.Sx Files +below. +. +. +.Pp +In a section titled +.Dq Library , +.Ql \&Lb +causes a break before and after its arguments. +. +. +.Ss Literals +. +The +.Ql \&Li +literal macro may be used for special characters, +symbolic constants, +and other syntactical items that should be typed exactly as displayed. +. +. +.Pp +.Dl Usage: .Li Ao argument Ac ... +.Pp +.Bl -tag -width ".Li .Li\ cntrl\-D\ )\ ," -compact -offset 15n +.It Li ".Li \een" +.Li \en +.It Li ".Li M1 M2 M3 ;" +.Li M1 M2 M3 ; +.It Li ".Li cntrl\-D ) ," +.Li cntrl-D ) , +.It Li ".Li 1024 ..." +.Li 1024 ... +.El +.Pp +. +The default width is 16n. +. +. +.Ss Names +. +The +.Ql \&Nm +macro is used for the document title or page topic. +. +Upon its first call, +it has the peculiarity of remembering its argument, +which should always be the topic of the man page. +. +When subsequently called without arguments, +.Ql \&Nm +regurgitates this initial name for the sole purpose of making less work +for the author. +. +Use of +.Ql \&Nm +is also appropriate when presenting a command synopsis for the topic of +a man page in section 1, +6, +or 8. +. +Its behavior changes when presented with arguments of various forms. +. +. +.Pp +.Bl -tag -width ".Li .Nm\ groff_mdoc" -compact -offset 15n +.It Li ".Nm groff_mdoc" +.Nm groff_mdoc +.It Li ".Nm" +.Nm +.It Li ".Nm \e\-mdoc" +.Nm \-mdoc +.It Li ".Nm foo ) ) ," +.Nm foo ) ) , +.It Li ".Nm :" +.Nm : +.El +. +. +.Pp +By default, +the topic is set in boldface to reflect its prime importance in the +discussion. +. +Cross references to other man page topics should use +.Ql \&Xr ; +including a second argument for the section number enables them to be +hyperlinked. +. +By default, +cross-referenced topics are set in italics to avoid cluttering the page +with boldface. +. +. +.Pp +The default width is 10n. +. +. +.Ss Options +The +.Ql .Op +macro places option brackets around any remaining arguments on the +command line, +and places any trailing punctuation outside the brackets. +. +The macros +.Ql .Oo +and +.Ql .Oc +(which produce an opening and a closing option bracket, +respectively) +may be used across one or more lines or to specify the exact position of +the closing parenthesis. +. +. +.Pp +.Dl Usage: .Op Oo Ao option Ac Oc ... +.Pp +.Bl -tag -width ".Li .Op\ Fl\ c\ Ar\ objfil\ Op\ Ar\ corfil\ ," -compact -offset 15n +.It Li .Op +.Op +.It Li ".Op Fl k" +.Op Fl k +.It Li ".Op Fl k ) ." +.Op Fl k ) . +.It Li ".Op Fl k Ar kookfile" +.Op Fl k Ar kookfile +.It Li ".Op Fl k Ar kookfile ," +.Op Fl k Ar kookfile , +.It Li ".Op Ar objfil Op Ar corfil" +.Op Ar objfil Op Ar corfil +.It Li ".Op Fl c Ar objfil Op Ar corfil ," +.Op Fl c Ar objfil Op Ar corfil , +.It Li ".Op word1 word2" +.Op word1 word2 +.It Li ".Li .Op Oo Ao option Ac Oc ..." +.Li .Op Oo Ao option Ac Oc ... +.El +.Pp +Here a typical example of the +.Ql .Oo +and +.Ql .Oc +macros: +. +.Bd -literal -offset indent +\&.Oo +\&.Op Fl k Ar kilobytes +\&.Op Fl i Ar interval +\&.Op Fl c Ar count +\&.Oc +.Ed +.Pp +. +Produces: +. +.Bd -filled -offset indent +.Oo +.Op Fl k Ar kilobytes +.Op Fl i Ar interval +.Op Fl c Ar count +.Oc +.Ed +.Pp +. +The default width values of +.Ql .Op +and +.Ql .Oo +are 14n and 10n, respectively. +. +. +.Ss Pathnames +. +The +.Ql .Pa +macro formats file specifications. +. +If called without arguments, +.Sq Pa +(recognized by many shells) +is output, +representing the user's home directory. +. +. +.Pp +.Dl Usage: .Pa Oo Ao pathname Ac Oc ... +.Pp +.Bl -tag -width ".Li .Pa\ /tmp/fooXXXXX\ )\ ." -compact -offset 15n +.It Li .Pa +.Pa +.It Li ".Pa /usr/share" +.Pa /usr/share +.It Li ".Pa /tmp/fooXXXXX ) ." +.Pa /tmp/fooXXXXX ) . +.El +.Pp +. +The default width is 32n. +. +. +.Ss Standards +. +The +.Ql .St +macro replaces standard abbreviations with their formal names. +.Pp +.Dl Usage: .St Ao abbreviation Ac ... +.Pp +Available pairs for +.Dq Abbreviation/Formal Name +are: +. +.Pp +.Tn ANSI/ISO C +.Pp +.Bl -tag -width ".Li \-p1003.1g\-2000" -compact -offset indent +.It Li \-ansiC +.St -ansiC +.It Li \-ansiC\-89 +.St -ansiC-89 +.It Li \-isoC +.St -isoC +.It Li \-isoC\-90 +.St -isoC-90 +.It Li \-isoC\-99 +.St -isoC-99 +.It Li \-isoC\-2011 +.St -isoC-2011 +.El +.Pp +. +.Tn POSIX +Part 1: System API +.Pp +.Bl -tag -width ".Li \-p1003.1g\-2000" -compact -offset indent +.It Li \-iso9945\-1\-90 +.St -iso9945-1-90 +.It Li \-iso9945\-1\-96 +.St -iso9945-1-96 +.It Li \-p1003.1 +.St -p1003.1 +.It Li \-p1003.1\-88 +.St -p1003.1-88 +.It Li \-p1003.1\-90 +.St -p1003.1-90 +.It Li \-p1003.1\-96 +.St -p1003.1-96 +.It Li \-p1003.1b\-93 +.St -p1003.1b-93 +.It Li \-p1003.1c\-95 +.St -p1003.1c-95 +.It Li \-p1003.1g\-2000 +.St -p1003.1g-2000 +.It Li \-p1003.1i\-95 +.St -p1003.1i-95 +.It Li \-p1003.1\-2001 +.St -p1003.1-2001 +.It Li \-p1003.1\-2004 +.St -p1003.1-2004 +.It Li \-p1003.1\-2008 +.St -p1003.1-2008 +.El +.Pp +. +.Tn POSIX +Part 2: Shell and Utilities +.Pp +.Bl -tag -width ".Li \-p1003.1g\-2000" -compact -offset indent +.It Li \-iso9945\-2\-93 +.St -iso9945-2-93 +.It Li \-p1003.2 +.St -p1003.2 +.It Li \-p1003.2\-92 +.St -p1003.2-92 +.It Li \-p1003.2a\-92 +.St -p1003.2a-92 +.El +.Pp +. +X/Open +.Pp +.Bl -tag -width ".Li \-p1003.1g\-2000" -compact -offset indent +.It Li \-susv1 +.St -susv1 +.It Li \-susv2 +.St -susv2 +.It Li \-susv3 +.St -susv3 +.It Li \-susv4 +.St -susv4 +.It Li \-svid4 +.St -svid4 +.It Li \-xbd5 +.St -xbd5 +.It Li \-xcu5 +.St -xcu5 +.It Li \-xcurses4.2 +.St -xcurses4.2 +.It Li \-xns5 +.St -xns5 +.It Li \-xns5.2 +.St -xns5.2 +.It Li \-xpg3 +.St -xpg3 +.It Li \-xpg4 +.St -xpg4 +.It Li \-xpg4.2 +.St -xpg4.2 +.It Li \-xsh5 +.St -xsh5 +.El +.Pp +. +Miscellaneous +.Pp +.Bl -tag -width ".Li \-p1003.1g\-2000" -compact -offset indent +.It Li \-ieee754 +.St -ieee754 +.It Li \-iso8601 +.St -iso8601 +.It Li \-iso8802\-3 +.St -iso8802-3 +.El +. +. +.Ss "Variable Types" +The +.Ql .Vt +macro may be used whenever a type is referenced. +. +In a section titled +.Dq Synopsis , +.Ql \&Vt +causes a break +(useful for old-style C variable declarations). +. +. +.Pp +.Dl Usage: .Vt Ao type Ac ... +.Pp +.Bl -tag -width ".Li .Vt\ extern\ char\ *optarg\ ;" -compact -offset 15n +.It Li ".Vt extern char *optarg ;" +.Vt extern char *optarg ; +.It Li ".Vt FILE *" +.Vt FILE * +.El +. +. +.Ss Variables +. +Generic variable reference. +.Pp +.Dl Usage: .Va Ao variable Ac ... +.Pp +.Bl -tag -width ".Li .Va\ Xchar\ sX\ ]\ )\ )\ ," -compact -offset 15n +.It Li ".Va count" +.Va count +.It Li ".Va settimer ," +.Va settimer , +.It Li ".Va \[dq]int *prt\[dq] ) :" +.Va "int *prt" ) : +.It Li ".Va \[dq]char s\[dq] ] ) ) ," +.Va "char s" ] ) ) , +.El +.Pp +. +The default width is 12n. +. +. +.Ss "Manual Page Cross References" +. +The +.Ql .Xr +macro expects the first argument to be a manual page name. +. +The optional second argument, +if a string +(defining the manual section), +is +put into parentheses. +. +. +.Pp +.Dl Usage: .Xr Ao man page name Ac Oo Ao section Ac Oc ... +. +. +.Pp +.Bl -tag -width ".Li .Xr\ xinit\ 1x\ ;" -compact -offset 15n +.It Li ".Xr mdoc" +.Xr mdoc +.It Li ".Xr mdoc ," +.Xr mdoc , +.It Li ".Xr mdoc 7" +.Xr mdoc 7 +.It Li ".Xr xinit 1x ;" +.Xr xinit 1x ; +.El +. +. +.Pp +The default width is 10n. +. +. +.Sh "General text domain" +. +. +.Ss "AT&T Macro" +. +.Pp +.Dl Usage: .At Oo Ao version Ac Oc ... +.Pp +.Bl -tag -width ".Li .At\ v6\ ." -compact -offset 15n +.It Li .At +.At +.It Li ".At v6 ." +.At v6 . +.El +.Pp +The following values for +.Ao version Ac +are possible: +.Pp +.Dl 32v, v1, v2, v3, v4, v5, v6, v7, III, V, V.1, V.2, V.3, V.4 +. +. +.Ss "BSD Macro" +. +.Pp +.Dl "Usage: .Bx" Bro \-alpha | \-beta | \-devel Brc ... +.Dl " .Bx" Oo Ao version Ac Oo Ao release Ac Oc Oc ... +.Pp +.Bl -tag -width ".Li .Bx\ -devel" -compact -offset 15n +.It Li .Bx +.Bx +.It Li ".Bx 4.3 ." +.Bx 4.3 . +.It Li ".Bx \-devel" +.Bx -devel +.El +.Pp +.Ao version Ac +will be prepended to the string +.Sq Bx . +The following values for +.Ao release Ac +are possible: +.Pp +.Dl Reno, reno, Tahoe, tahoe, Lite, lite, Lite2, lite2 +. +. +.Ss "NetBSD Macro" +. +.Pp +.Dl Usage: .Nx Oo Ao version Ac Oc ... +.Pp +.Bl -tag -width ".Li .Nx\ 1.4\ ." -compact -offset 15n +.It Li .Nx +.Nx +.It Li ".Nx 1.4 ." +.Nx 1.4 . +.El +.Pp +For possible values of +.Ao version Ac +see the description of the +.Ql .Os +command above in section +.Sx "Title macros" . +. +. +.Ss "FreeBSD Macro" +. +.Pp +.Dl Usage: .Fx Oo Ao version Ac Oc ... +.Pp +.Bl -tag -width ".Li .Fx\ 2.2\ ." -compact -offset 15n +.It Li .Fx +.Fx +.It Li ".Fx 2.2 ." +.Fx 2.2 . +.El +.Pp +For possible values of +.Ao version Ac +see the description of the +.Ql .Os +command above in section +.Sx "Title macros" . +. +. +.Ss "DragonFly Macro" +. +.Pp +.Dl Usage: .Dx Oo Ao version Ac Oc ... +.Pp +.Bl -tag -width ".Li .Dx\ 1.4\ ." -compact -offset 15n +.It Li .Dx +.Dx +.It Li ".Dx 1.4 ." +.Dx 1.4 . +.El +.Pp +For possible values of +.Ao version Ac +see the description of the +.Ql .Os +command above in section +.Sx "Title macros" . +. +. +.Ss "OpenBSD Macro" +. +.Pp +.Dl Usage: .Ox Oo Ao version Ac Oc ... +.Pp +.Bl -tag -width ".Li .Ox\ 1.0" -compact -offset 15n +.It Li ".Ox 1.0" +.Ox 1.0 +.El +. +. +.Ss "BSD/OS Macro" +. +.Pp +.Dl Usage: .Bsx Oo Ao version Ac Oc ... +.Pp +.Bl -tag -width ".Li .Bsx\ 1.0" -compact -offset 15n +.It Li ".Bsx 1.0" +.Bsx 1.0 +.El +. +. +.Ss "Unix Macro" +. +.Pp +.Dl Usage: .Ux ... +.Pp +.Bl -tag -width ".Li .Ux" -compact -offset 15n +.It Li .Ux +.Ux +.El +. +. +.Ss "Emphasis Macro" +. +Text may be stressed or emphasized with the +.Ql .Em +macro. +The usual font for emphasis is italic. +.Pp +.Dl Usage: .Em Ao argument Ac ... +.Pp +.Bl -tag -width ".Li .Em\ vide\ infra\ )\ )\ ," -compact -offset 15n +.It Li ".Em does not" +.Em does not +.It Li ".Em exceed 1024 ." +.Em exceed 1024 . +.It Li ".Em vide infra ) ) ," +.Em vide infra ) ) , +.El +.Pp +. +The default width is 10n. +. +. +.Ss "Font Mode" +. +The +.Ql .Bf +font mode must be ended with the +.Ql .Ef +macro (the latter takes no arguments). +Font modes may be nested within other font modes. +.Pp +.Ql .Bf +has the following syntax: +.Pp +.Dl .Bf Ao font mode Ac +.Pp +.Ao font mode Ac +must be one of the following three types: +.Pp +.Bl -tag -width ".Sy \&Sy | Fl symbolic" -compact -offset indent +.It Sy \&Em | Fl emphasis +Same as if the +.Ql .Em +macro was used for the entire block of text. +.It Sy \&Li | Fl literal +Same as if the +.Ql .Li +macro was used for the entire block of text. +.It Sy \&Sy | Fl symbolic +Same as if the +.Ql .Sy +macro was used for the entire block of text. +.El +.Pp +Both macros are neither callable nor parsed. +. +. +.Ss "Enclosure and Quoting Macros" +. +The concept of enclosure is similar to quoting. +The object being to enclose one or more strings between a pair of characters +like quotes or parentheses. +The terms quoting and enclosure are used interchangeably throughout this +document. +Most of the one-line enclosure macros end in small letter +.Ql q +to give a hint of quoting, but there are a few irregularities. +. +For each enclosure macro, +there is a pair of opening and closing macros that end with the +lowercase letters +.Ql o +and +.Ql c +respectively. +.Pp +\# XXX +.if t \ +. ne 10 +. +.TS +lb lb lb lb lb +l l l l l. +Quote Open Close Function Result +\&.Aq .Ao .Ac Angle Bracket Enclosure +\&.Bq .Bo .Bc Bracket Enclosure [string] +\&.Brq .Bro .Brc Brace Enclosure {string} +\&.Dq .Do .Dc Double Quote \[lq]string\[rq] +\&.Eq .Eo .Ec Enclose String (in XY) XstringY +\&.Pq .Po .Pc Parenthesis Enclosure (string) +\&.Ql Quoted Literal \[lq]string\[rq] or string +\&.Qq .Qo .Qc Straight Double Quote "string" +\&.Sq .So .Sc Single Quote \[oq]string\[cq] +.TE +.Pp +All macros ending with +.Sq q +and +.Sq o +have a default width value of 12n. +. +.Bl -tag -width ".Li .Ec , .Eo" +.It Li .Eo , .Ec +These macros expect the first argument to be the opening and closing +strings, +respectively. +. +.It Li .Es , .En +To work around the nine-argument limit in the original +.Xr troff \" generic +program, +.Xr mdoc +supports two other macros that are now obsolete. +. +.Ql .Es +uses its first and second parameters as opening and closing marks which +are then used to enclose the arguments of +.Ql .En . +. +The default width value is 12n for both macros. +. +.It Li .Eq +The first and second arguments of this macro are the opening and +closing strings respectively, followed by the arguments to be enclosed. +.It Li .Ql +The quoted literal macro behaves differently in +.Xr troff \" mode +and +.Xr nroff \" mode +modes. +. +If formatted with +.Xr @g@nroff @MAN1EXT@ , +a quoted literal is always quoted. +. +If formatted with +.Xr @g@troff , +an item is only quoted if the width of the item is less than three +constant-width characters. +. +This is to make short strings more visible where the font change to +literal (constant-width) is less noticeable. +. +. +.Pp +The default width is 16n. +. +.It Li .Pf +The prefix macro suppresses the whitespace between its first and second +argument: +. +.Bl -tag -width ".Li .Pf\ (\ Fa\ name2" -offset indent +.It Li ".Pf ( Fa name2" +.Pf ( Fa name2 +.El +.Pp +. +The default width is 12n. +.Pp +The +.Ql .Ns +macro (see below) performs the analogous suffix function. +.It Li .Ap +The +.Ql .Ap +macro inserts an apostrophe and exits any special text modes, continuing in +.Ql .No +mode. +.El +.Pp +. +Examples of quoting: +. +.Pp +.Bl -tag -width ".Li .Bq\ Em\ Greek\ ,\ French\ ." -compact -offset indent +.It Li .Aq +.Aq +.It Li ".Aq Pa ctype.h ) ," +.Aq Pa ctype.h ) , +.It Li .Bq +.Bq +.It Li ".Bq Em Greek , French ." +.Bq Em Greek , French . +.It Li .Dq +.Dq +.It Li ".Dq string abc ." +.Dq string abc . +.It Li ".Dq \[aq]\[rs][ha][A\-Z]\[aq]" +.Dq '\[ha][A-Z]' +.It Li ".Ql man mdoc" +.Ql man mdoc +.It Li .Qq +.Qq +.It Li ".Qq string ) ," +.Qq string ) , +.It Li ".Qq string Ns )," +.Qq string Ns ), +.It Li .Sq +.Sq +.It Li ".Sq string" +.Sq string +.It Li ".Em or Ap ing" +.Em or Ap ing +.El +.Pp +. +For a good example of nested enclosure macros, see the +.Ql .Op +option macro. +It was created from the same underlying enclosure macros as those presented +in the list above. +The +.Ql .Xo +and +.Ql .Xc +extended argument list macros are discussed below. +. +. +.Ss "Normal text macro" +. +.Ql \&No +formats subsequent argument(s) normally, +ending the effect of +.Ql \&Em +and similar. +. +Parsing is +.Em not +suppressed, +so you must prefix words like +.Ql \&No +with +.Ql \e& +to avoid their interpretation as +.Xr mdoc +macros. +. +. +.Pp +.Dl Usage: .No Ar argument No ... +. +. +.Pp +.Bl -tag -width ".Li .Em\ Use\ caution\ No\ here\ ." \ +-compact -offset 15n +.It Li ".Em Use caution No here ." +\[->] +.Em Use caution No here . +.It Li ".Em No dogs allowed ." +\[->] +.\" We cheat here to prevent a diagnostic warning. We want to +.\" illustrate output that may surprise the novice. +.Em \&No No dogs allowed . +.It Li ".Em \e&No dogs allowed ." +\[->] +.Em \&No dogs allowed . +.El +. +. +.Pp +The default width is 12n. +. +. +.Ss "No-Space Macro" +. +The +.Ql .Ns +macro suppresses insertion of a space between the current position and its +first parameter. +For example, it is useful for old style argument lists where there is no +space between the flag and argument: +.Pp +.Dl "Usage:" ... Ao argument Ac \&Ns Oo Ao argument Ac Oc ... +.Dl " " .Ns Ao argument Ac ... +.Pp +.Bl -tag -width ".Li .Op\ Fl\ I\ Ns\ Ar\ directory" -compact -offset 15n +.It Li ".Op Fl I Ns Ar directory" +.Op Fl I Ns Ar directory +.El +.Pp +Note: The +.Ql .Ns +macro always invokes the +.Ql .No +macro after eliminating the space unless another macro name follows it. +If used as a command (i.e., the second form above in the +.Sq Usage +line), +.Ql .Ns +is identical to +.Ql .No . +. +. +.Ss "(Sub)section cross references" +. +Use the +.Ql .Sx +macro to cite a (sub)section heading within the given document. +. +. +.Pp +.Dl Usage: .Sx Ao section-reference Ac ... +. +. +.Pp +.Bl -tag -width ".Li .Sx\ Files" -offset 15n +.It Li ".Sx Files" +\[->] +.Sx Files +.El +. +. +.Pp +The default width is 16n. +. +. +.Ss Symbolics +. +The symbolic emphasis macro is generally a boldface macro in either the +symbolic sense or the traditional English usage. +. +. +.Pp +.Dl Usage: .Sy Ao symbol Ac ... +. +. +.Pp +.Bl -tag -width ".Li .Sy\ Important\ Notice" -compact -offset 15n +.It Li ".Sy Important Notice" +\[->] +.Sy Important Notice +.El +. +. +.Pp +The default width is 6n. +. +. +.Ss "Mathematical Symbols" +. +Use this macro for mathematical symbols and similar things. +. +. +.Pp +.Dl Usage: .Ms Ao math symbol Ac ... +. +. +.Pp +.Bl -tag -width ".Li .Ms\ sigma" -compact -offset 15n +.It Li ".Ms sigma" +\[->] +.Ms sigma +.El +. +. +.Pp +The default width is 6n. +. +. +.Ss "References and Citations" +. +The following macros make a modest attempt to handle references. +. +At best, +the macros make it convenient to manually drop in a subset of +.Xr @g@refer @MAN1EXT@ +style references. +. +. +.Pp +.Bl -tag -width 6n -offset indent -compact +.It Li .Rs +Reference start +(does not take arguments). +. +In a section titled +.Dq "See also" , +it causes a break +and begins collection of reference information until the reference end +macro is read. +. +.It Li .Re +Reference end (does not take arguments). +The reference is printed. +.It Li .%A +Reference author name; one name per invocation. +.It Li .%B +Book title. +.It Li .%C +City/place. +.It Li .%D +Date. +.It Li .%I +Issuer/publisher name. +.It Li .%J +Journal name. +.It Li .%N +Issue number. +.It Li .%O +Optional information. +.It Li .%P +Page number. +.It Li .%Q +Corporate or foreign author. +.It Li .%R +Report name. +.It Li .%T +Title of article. +.It Li .%U +Optional hypertext reference. +.It Li .%V +Volume. +.El +.Pp +Macros beginning with +.Ql % +are not callable but accept multiple arguments in the usual way. +Only the +.Ql .Tn +macro is handled properly as a parameter; other macros will cause strange +output. +.Ql .%B +and +.Ql .%T +can be used outside of the +.Ql .Rs/.Re +environment. +.Pp +Example: +. +.Bd -literal -offset indent +\&.Rs +\&.%A "Matthew Bar" +\&.%A "John Foo" +\&.%T "Implementation Notes on foobar(1)" +\&.%R "Technical Report ABC\-DE\-12\-345" +\&.%Q "Drofnats College" +\&.%C "Nowhere" +\&.%D "April 1991" +\&.Re +.Ed +.Pp +produces +. +.Bd -ragged -offset indent +.Rs +.%A "Matthew Bar" +.%A "John Foo" +.%T "Implementation Notes on foobar(1)" +.%R "Technical Report ABC-DE-12-345" +.%Q "Drofnats College" +.%C "Nowhere" +.%D "April 1991" +.Re +.Ed +. +.Ss "Trade Names or Acronyms" +. +The trade name macro prints its arguments at a smaller type size. +. +It is intended to imitate a small caps fonts for fully capitalized +acronyms. +. +. +.Pp +.Dl Usage: .Tn Ao symbol Ac ... +.Pp +.Bl -tag -width ".Li .Tn\ ASCII" -compact -offset 15n +.It Li ".Tn DEC" +.Tn DEC +.It Li ".Tn ASCII" +.Tn ASCII +.El +.Pp +. +The default width is 10n. +. +. +.Ss "Extended Arguments" +. +The +.Li .Xo +and +.Li .Xc +macros allow one to extend an argument list on a macro boundary for the +.Ql .It +macro (see below). +Note that +.Li .Xo +and +.Li .Xc +are implemented similarly to all other macros opening and closing an +enclosure (without inserting characters, of course). +This means that the following is true for those macros also. +.Pp +Here is an example of +.Ql .Xo +using the space mode macro to turn spacing off: +. +.Bd -literal -offset indent +\&.Bd \-literal \-offset indent +\&.Sm off +\&.It Xo Sy I Ar operation +\&.No \een Ar count No \een +\&.Xc +\&.Sm on +\&.Ed +.Ed +.Pp +. +produces +. +.Bd -filled -offset indent +.Bl -tag -compact +.Sm off +.It Xo Sy I Ar operation +.No \en Ar count No \en +.Xc +.Sm on +.El +.Ed +.Pp +. +Another one: +. +.Bd -literal -offset indent +\&.Bd \-literal \-offset indent +\&.Sm off +\&.It Cm S No / Ar old_pattern Xo +\&.No / Ar new_pattern +\&.No / Op Cm g +\&.Xc +\&.Sm on +\&.Ed +.Ed +.Pp +. +produces +. +.Bd -filled -offset indent +.Bl -tag -compact +.Sm off +.It Cm S No \&/ Ar old_pattern Xo +.No \&/ Ar new_pattern +.No \&/ Op Cm g +.Xc +.Sm on +.El +.Ed +.Pp +. +Another example of +.Ql .Xo +and enclosure macros: Test the value of a variable. +. +.Bd -literal -offset indent +\&.Bd \-literal \-offset indent +\&.It Xo +\&.Ic .ifndef +\&.Oo \e&! Oc Ns Ar variable Oo +\&.Ar operator variable No ... +\&.Oc Xc +\&.Ed +.Ed +.Pp +. +produces +. +.Bd -filled -offset indent +.Bl -tag -width flag -compact +.It Xo +.Ic .ifndef +.Oo \&! Oc Ns Ar variable Oo +.Ar operator variable No ... +.Oc Xc +.El +.Ed +.Pp +. +. +.Sh "Page structure domain" +. +. +.Ss "Section headings" +. +The following +.Ql .Sh +section heading macros are required in every man page. +. +The remaining section headings are recommended at the discretion of the +author writing the manual page. +The +.Ql .Sh +macro is parsed but not generally callable. +It can be used as an argument in a call to +.Ql .Sh +only; it then reactivates the default font for +.Ql .Sh . +.Pp +The default width is 8n. +. +.Bl -tag -width ".Li .Sh\ Return\ values" +.It Li ".Sh Name" +The +.Ql ".Sh Name" +macro is mandatory. +. +If not specified, +headers, +footers, +and page layout defaults will not be set and things will be rather +unpleasant. +. +The +.Em Name +section consists of at least three items. +The first is the +.Ql .Nm +name macro naming the subject of the man page. +The second is the name description macro, +.Ql .Nd , +which separates the subject name from the third item, which is the +description. +The description should be the most terse and lucid possible, as the space +available is small. +.Pp +.Ql .Nd +first prints +.Ql \- , +then all its arguments. +. +.It Li ".Sh Library" +This section is for section two and three function calls. +It should consist of a single +.Ql .Lb +macro call; +see +.Sx "Library Names" . +. +.It Li ".Sh Synopsis" +The +.Sx Synopsis +section describes the typical usage of the subject of a man page. +The macros required are either +.Ql .Nm , +.Ql .Cd , +or +.Ql .Fn +(and possibly +.Ql .Fo , +.Ql .Fc , +.Ql .Fd , +and +.Ql .Ft ) . +The function name macro +.Ql .Fn +is required for manual page sections\~2 and\~3; the command and general name +macro +.Ql .Nm +is required for sections 1, 5, 6, 7, and\~8. +Section\~4 manuals require a +.Ql .Nm , +.Ql .Fd +or a +.Ql .Cd +configuration device usage macro. +Several other macros may be necessary to produce the synopsis line as shown +below: +. +.Bd -filled -offset indent +.Nm cat +.Op Fl benstuv +.Op Fl +.Ar file No ... +.Ed +.Pp +. +The following macros were used: +.Pp +.Dl ".Nm cat" +.Dl ".Op Fl benstuv" +.Dl ".Op Fl" +.Dl ".Ar file No ..." +. +.It Li ".Sh Description" +In most cases the first text in the +.Sx Description +section is a brief paragraph on the command, function or file, followed by a +lexical list of options and respective explanations. +To create such a list, the +.Ql .Bl +(begin list), +.Ql .It +(list item) and +.Ql .El +(end list) +macros are used (see +.Sx Lists and Columns +below). +. +.It Li ".Sh Implementation notes" +Implementation specific information should be placed here. +. +.It Li ".Sh Return values" +Sections 2, 3 and\~9 function return values should go here. +The +.Ql .Rv +macro may be used to generate text for use in the +.Sx Return values +section for most section 2 and 3 library functions; +see +.Sx "Return Values" . +.El +.Pp +. +The following +.Ql .Sh +section headings are part of the preferred manual page layout and must +be used appropriately to maintain consistency. +They are listed in the order in which they would be used. +. +.Bl -tag -width ".Li .Sh\ Compatibility" +.It Li ".Sh Environment" +The +.Em Environment +section should reveal any related environment variables and clues to their +behavior and/or usage. +. +.It Li ".Sh Files" +Files which are used or created by the man page subject should be listed via +the +.Ql .Pa +macro in the +.Sx Files +section. +. +.It Li ".Sh Examples" +There are several ways to create examples. +See subsection +.Sx "Examples and Displays" +below for details. +. +.It Li ".Sh Diagnostics" +Diagnostic messages from a command should be placed in this section. +The +.Ql .Ex +macro may be used to generate text for use in the +.Sx Diagnostics +section for most section 1, 6 and\~8 commands; +see +.Sx "Exit Status" . +. +.It Li ".Sh Compatibility" +Known compatibility issues (e.g.\& deprecated options or parameters) +should be listed here. +. +.It Li ".Sh Errors" +Specific error handling, especially from library functions (man page +sections 2, 3, and\~9) should go here. +The +.Ql .Er +macro is used to specify an error (errno). +. +.It Li ".Sh See also" +References to other material on the man page topic and cross references +to other relevant man pages should be placed in the +.Sx "See also" +section. +. +Cross references are specified using the +.Ql .Xr +macro. +. +Currently +.Xr @g@refer @MAN1EXT@ +style references are not accommodated. +. +. +.Pp +It is recommended that the cross references be sorted by section number, +then alphabetically by name within each section, +then separated by commas. +. +Example: +. +. +.Pp +.Xr ls 1 , +.Xr ps 1 , +.Xr group 5 , +.Xr passwd 5 +. +.It Li ".Sh Standards" +If the command, +library function, +or file adheres to a specific implementation such as +.St -p1003.2 +or +.St -ansiC +this should be noted here. +. +If the command does not adhere to any standard, +its history should be noted in the +.Em History +section. +. +.It Li ".Sh History" +Any command which does not adhere to any specific standards should be +outlined historically in this section. +. +.It Li ".Sh Authors" +Credits should be placed here. +. +Use the +.Ql .An +macro for names and the +.Ql .Aq +macro for email addresses within optional contact information. +. +Explicitly indicate whether the person authored the initial manual page +or the software or whatever the person is being credited for. +.It Li ".Sh Bugs" +Blatant problems with the topic go here. +.El +.Pp +. +User-specified +.Ql .Sh +sections may be added; for example, this section was set with: +. +.Bd -literal -offset 15n +\&.Sh "Page structure domain" +.Ed +. +. +.Ss "Subsection headings" +. +Subsection headings have exactly the same syntax as section headings: +.Ql .Ss +is parsed but not generally callable. +It can be used as an argument in a call to +.Ql .Ss +only; it then reactivates the default font for +.Ql .Ss . +.Pp +The default width is 8n. +. +. +.Ss "Paragraphs and Line Spacing" +. +.Bl -tag -width ".Li .Pp" +.It Li .Pp +The +.Ql .Pp +paragraph command may be used to specify a line space where necessary. +The macro is not necessary after a +.Ql .Sh +or +.Ql .Ss +macro or before a +.Ql .Bl +or +.Ql .Bd +macro (which both assert a vertical distance unless the +.Fl compact +flag is given). +.Pp +The macro is neither callable nor parsed and takes no arguments; an +alternative name is +.Ql .Lp . +.El +. +.\" XXX +. +.\" This worked with version one, need to redo for version three +.\" .Pp +.\" .Ds I +.\" .Cw (ax+bx+c) \ is\ produced\ by\ \& +.\" .\".Cw (ax+bx+c) \&.Va_by_) \&_and_\& \&[?/]m_b1_e1_f1[?/]\& +.\" .Cl Cx \t\t +.\" .Li \&.Cx\ ( +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Va ax +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Sy \+ +.\" .Cx +.\" .Cl Cx \&(\& +.\" .Va ax +.\" .Cx + +.\" .Va by +.\" .Cx + +.\" .Va c ) +.\" .Cx \t +.\" .Em is produced by +.\" .Cx \t +.\" .Li \&.Va by +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Sy \+ +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Va c ) +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Cx +.\" .Cx +.\" .Cw +.\" .De +.\" .Pp +.\" This example shows the same equation in a different format. +.\" The spaces +.\" around the +.\" .Li \&+ +.\" signs were forced with +.\" .Li \e : +.\" .Pp +.\" .Ds I +.\" .Cw (ax\ +\ bx\ +\ c) \ is\ produced\ by\ \& +.\" .\".Cw (ax+bx+c) \&.Va_by_) \&_and_\& \&[?/]m_b1_e1_f1[?/]\& +.\" .Cl Cx \t\t +.\" .Li \&.Cx\ ( +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Va a +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Sy x +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Cx \e\ +\e\ \e& +.\" .Cx +.\" .Cl Cx \&(\& +.\" .Va a +.\" .Sy x +.\" .Cx \ +\ \& +.\" .Va b +.\" .Sy y +.\" .Cx \ +\ \& +.\" .Va c ) +.\" .Cx \t +.\" .Em is produced by +.\" .Cl Cx \t\t +.\" .Li \&.Va b +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Sy y +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Cx \e\ +\e\ \e& +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Va c ) +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Cx +.\" .Cx +.\" .Cw +.\" .De +.\" .Pp +.\" The incantation below was +.\" lifted from the +.\" .Xr adb 1 +.\" manual page: +.\" .Pp +.\" .Ds I +.\" .Cw \&[?/]m_b1_e1_f1[?/]\& is\ produced\ by +.\" .Cl Cx \t\t +.\" .Li \&.Cx Op Sy ?/ +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Nm m +.\" .Cx +.\" .Cl Cx Op Sy ?/ +.\" .Nm m +.\" .Ad \ b1 e1 f1 +.\" .Op Sy ?/ +.\" .Cx \t +.\" .Em is produced by +.\" .Cx \t +.\" .Li \&.Ar \e\ b1 e1 f1 +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Op Sy ?/ +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Cx +.\" .Cx +.\" .Cw +.\" .De +.\" .Pp +. +. +.Ss Keeps +. +The only keep that is implemented at this time is for words. +. +The macros are +.Ql .Bk +(begin keep) +and +.Ql .Ek +(end keep). +. +The only option that +.Ql .Bk +currently accepts is +.Fl words +(also the default); +this prevents breaks in the middle of options. +. +In the example for +.Nm make +command-line arguments +(see +.Sx What's in a Name ) , +the keep prevents +.Xr @g@nroff +from placing the flag and the argument on separate lines. +. +. +.Pp +Neither macro is callable or parsed. +. +. +.Pp +More work needs to be done on the keep macros; +specifically, +a +.Fl line +option should be added. +. +. +.Ss "Examples and Displays" +. +There are seven types of displays. +. +. +.Pp +.Bl -tag -width ".Li .D1" +.It Li .D1 +(This is D-one.) +Display one line of indented text. +This macro is parsed but not callable. +. +. +.Pp +.D1 Fl ldghfstru +. +. +.Pp +The above was produced by: +.Li ".D1 Fl ldghfstru" . +. +.It Li .Dl +(This is D-ell.) +Display one line of indented +.Em literal +text. +The +.Ql .Dl +example macro has been used throughout this file. +It allows the indentation (display) of one line of text. +Its default font is set to constant width (literal). +.Ql .Dl +is parsed but not callable. +. +. +.Pp +.Dl % ls \-ldg /usr/local/bin +. +. +.Pp +The above was produced by: +.Li ".Dl % ls \e\-ldg /usr/local/bin" . +. +.It Li .Bd +Begin display. +The +.Ql .Bd +display must be ended with the +.Ql .Ed +macro. +It has the following syntax: +. +. +.Pp +.Bd -ragged -compact +.Bl -tag -width ".Li .Bd" -offset indent +.It Li .Bd Xo +.Bro \-literal | \-filled | \-unfilled | \-ragged | \-centered Brc +.Oo \-offset Ao string Ac Oc Oo \-file Ao file name Ac Oc Oo \-compact Oc Xc +.El +.Ed +. +. +.Pp +.Bl -tag -width ".Fl file Ao Ar file name Ac " -compact +.It Fl ragged +Fill, but do not adjust the right margin (only left-justify). +. +.It Fl centered +Center lines between the current left and right margin. +. +Note that each single line is centered. +. +.It Fl unfilled +Do not fill; +break lines where their input lines are broken. +. +This can produce overlong lines without warning messages. +. +.It Fl filled +Display a filled block. +The block of text is formatted (i.e., the text is justified on both the left +and right side). +. +.It Fl literal +Display block with literal font (usually fixed-width). +. +Useful for source code or simple tabbed or spaced text. +. +.It Fl file Ao Ar file name Ac +The file whose name follows the +.Fl file +flag is read and displayed before any data enclosed with +.Ql .Bd +and +.Ql .Ed , +using the selected display type. +. +Any +.Xr @g@troff/ Ns Xr mdoc +commands in the file will be processed. +. +.It Fl offset Ao Ar string Ac +If +.Fl offset +is specified with one of the following strings, the string is interpreted to +indicate the level of indentation for the forthcoming block of text: +. +. +.Pp +.Bl -tag -width ".Ar indent-two" -compact +.It Ar left +Align block on the current left margin; this is the default mode of +.Ql .Bd . +.It Ar center +Supposedly center the block. +At this time unfortunately, the block merely gets left aligned about an +imaginary center margin. +.It Ar indent +Indent by one default indent value or tab. +The default indent value is also used for the +.Ql .D1 +and +.Ql .Dl +macros, so one is guaranteed the two types of displays will line up. +The indentation value is normally set to\~6n or about two thirds of an inch +(six constant width characters). +.It Ar indent\-two +Indent two times the default indent value. +.It Ar right +This +.Em left +aligns the block about two inches from the right side of the page. +This macro needs work and perhaps may never do the right thing within +.Xr @g@troff . +.El +. +. +.Pp +If +.Ao string Ac +is a valid numeric expression instead +.Pf ( Em with a scaling indicator other than +.Sq Em u ) , +use that value for indentation. +The most useful scaling indicators are +.Sq m +and +.Sq n , +specifying the so-called +.Em \&Em +and +.Em "En square" . +. +This is approximately the width of the letters +.Sq m +and +.Sq n +respectively +of the current font +(for +.Xr nroff +output, +both scaling indicators give the same values). +. +If +.Ao string Ac +isn't a numeric expression, it is tested whether it is an +.Xr mdoc +macro name, and the default offset value associated with this macro is used. +Finally, if all tests fail, +the width of +.Ao string Ac +(typeset with a fixed-width font) is taken as the offset. +.It Fl compact +Suppress insertion of vertical space before begin of display. +.El +. +.It Li .Ed +End display (takes no arguments). +.El +. +. +.Ss "Lists and Columns" +. +There are several types of lists which may be initiated with the +.Ql .Bl +begin-list macro. +. +Items within the list are specified with the +.Ql .It +item macro, +and each list must end with the +.Ql .El +macro. +. +Lists may be nested within themselves and within displays. +. +The use of columns inside of lists or lists inside of columns is +untested. +. +. +.Pp +In addition, +several list attributes may be specified such as the width of a tag, +the list offset, +and compactness +(blank lines between items allowed or disallowed). +. +Most of this document has been formatted with a tag style list +.Pf ( Fl tag ) . +. +. +.Pp +It has the following syntax forms: +. +. +.Pp +.Bd -ragged -compact +.Bl -tag -width ".Li .Bl" -offset indent -compact +.It Li .Bl Xo +.Bro \-hang | \-ohang | \-tag | \-diag | \-inset Brc +.Oo \-width Ao string Ac Oc +.Oo \-offset Ao string Ac Oc Oo \-compact Oc Xc +.It Li .Bl Xo +.No \-column Oo \-offset Ao string Ac Oc +.Ao string1 Ac Ao string2 Ac ... Xc +.It Li .Bl Xo +.Bro \-item | \-enum Oo \-nested Oc | \-bullet | \-hyphen | \-dash Brc +.Oo \-offset Ao string Ac Oc Oo \-compact Oc Xc +.El +.Ed +. +. +.Pp +And now a detailed description of the list types. +. +. +.Pp +.Bl -tag -width ".Fl column" -compact +.It Fl bullet +A bullet list. +. +.Bd -literal -offset indent +\&.Bl \-bullet \-offset indent \-compact +\&.It +Bullet one goes here. +\&.It +Bullet two here. +\&.El +.Ed +. +. +.Pp +Produces: +. +. +.Pp +.Bl -bullet -offset indent -compact +.It +Bullet one goes here. +.It +Bullet two here. +.El +. +. +.Pp +. +.It Fl dash No ( or Fl hyphen ) +A dash list. +. +.Bd -literal -offset indent +\&.Bl \-dash \-offset indent \-compact +\&.It +Dash one goes here. +\&.It +Dash two here. +\&.El +.Ed +. +. +.Pp +Produces: +. +. +.Pp +.Bl -dash -offset indent -compact +.It +Dash one goes here. +.It +Dash two here. +.El +. +. +.Pp +.It Fl enum +An enumerated list. +. +.Bd -literal -offset indent +\&.Bl \-enum \-offset indent \-compact +\&.It +Item one goes here. +\&.It +And item two here. +\&.El +.Ed +. +. +.Pp +The result: +. +. +.Pp +.Bl -enum -offset indent -compact +.It +Item one goes here. +.It +And item two here. +.El +. +. +.Pp +If you want to nest enumerated lists, +use the +.Fl nested +flag +(starting with the second-level list): +. +.Bd -literal -offset indent +\&.Bl \-enum \-offset indent \-compact +\&.It +Item one goes here +\&.Bl \-enum \-nested \-compact +\&.It +Item two goes here. +\&.It +And item three here. +\&.El +\&.It +And item four here. +\&.El +.Ed +. +. +.Pp +Result: +. +. +.Pp +.Bl -enum -offset indent -compact +.It +Item one goes here. +.Bl -enum -nested -compact +.It +Item two goes here. +.It +And item three here. +.El +.It +And item four here. +.El +. +. +.Pp +. +.It Fl item +A list of type +.Fl item +without list markers. +. +.Bd -literal -offset indent +\&.Bl \-item \-offset indent +\&.It +Item one goes here. +Item one goes here. +Item one goes here. +\&.It +Item two here. +Item two here. +Item two here. +\&.El +.Ed +. +. +.Pp +Produces: +. +. +.Pp +.Bl -item -offset indent +.It +Item one goes here. +Item one goes here. +Item one goes here. +.It +Item two here. +Item two here. +Item two here. +.El +. +. +.Pp +.It Fl tag +A list with tags. +Use +.Fl width +to specify the tag width. +. +. +.Pp +.Bl -tag -width "PPID" -compact -offset indent +.It SL +sleep time of the process (seconds blocked) +.It PAGEIN +number of disk I/O operations resulting from references by the process +to pages not loaded in core. +.It UID +numerical user-id of process owner +.It PPID +numerical id of parent of process priority +(non-positive when in non-interruptible wait) +.El +. +. +.Pp +The raw text: +. +.Bd -literal -offset indent +\&.Bl \-tag \-width "PPID" \-compact \-offset indent +\&.It SL +sleep time of the process (seconds blocked) +\&.It PAGEIN +number of disk I/O operations resulting from references +by the process to pages not loaded in core. +\&.It UID +numerical user\-id of process owner +\&.It PPID +numerical id of parent of process priority +(non\-positive when in non\-interruptible wait) +\&.El +.Ed +. +. +.Pp +.It Fl diag +Diag lists create section four diagnostic lists and are similar to inset +lists except callable macros are ignored. +The +.Fl width +flag is not meaningful in this context. +. +. +.Pp +Example: +. +.Bd -literal -offset indent +\&.Bl \-diag +\&.It You can't use Sy here. +The message says all. +\&.El +.Ed +. +. +.Pp +produces +. +.Bl -diag +.It You can't use Sy here. +The message says all. +.El +. +. +.Pp +.It Fl hang +A list with hanging tags. +. +.Bl -hang -offset indent +.It Em Hanged +labels appear similar to tagged lists when the +label is smaller than the label width. +.It Em Longer hanged list labels +blend into the paragraph unlike +tagged paragraph labels. +.El +. +. +.Pp +And the unformatted text which created it: +. +.Bd -literal -offset indent +\&.Bl \-hang \-offset indent +\&.It Em Hanged +labels appear similar to tagged lists when the +label is smaller than the label width. +\&.It Em Longer hanged list labels +blend into the paragraph unlike +tagged paragraph labels. +\&.El +.Ed +. +. +.Pp +.It Fl ohang +Lists with overhanging tags do not use indentation for the items; +tags are written to a separate line. +. +. +.Pp +.Bl -ohang -offset indent +.It Sy SL +sleep time of the process (seconds blocked) +.It Sy PAGEIN +number of disk I/O operations resulting from references by the process +to pages not loaded in core. +.It Sy UID +numerical user-id of process owner +.It Sy PPID +numerical id of parent of process priority +(non-positive when in non-interruptible wait) +.El +. +. +.Pp +The raw text: +. +.Bd -literal -offset indent +\&.Bl \-ohang \-offset indent +\&.It Sy SL +sleep time of the process (seconds blocked) +\&.It Sy PAGEIN +number of disk I/O operations resulting from references +by the process to pages not loaded in core. +\&.It Sy UID +numerical user\-id of process owner +\&.It Sy PPID +numerical id of parent of process priority +(non\-positive when in non\-interruptible wait) +\&.El +.Ed +. +. +.Pp +.It Fl inset +Here is an example of inset labels: +.Bl -inset -offset indent +.It Em Tag +The tagged list (also called a tagged paragraph) +is the most common type of list used in the +Berkeley manuals. +Use a +.Fl width +attribute as described below. +.It Em Diag +Diag lists create section four diagnostic lists +and are similar to inset lists except callable +macros are ignored. +.It Em Hang +Hanged labels are a matter of taste. +.It Em Ohang +Overhanging labels are nice when space is constrained. +.It Em Inset +Inset labels are useful for controlling blocks of +paragraphs and are valuable for converting +.Xr mdoc +manuals to other formats. +.El +. +. +.Pp +Here is the source text which produced the above example: +. +.Bd -literal -offset indent +\&.Bl \-inset \-offset indent +\&.It Em Tag +The tagged list (also called a tagged paragraph) +is the most common type of list used in the +Berkeley manuals. +\&.It Em Diag +Diag lists create section four diagnostic lists +and are similar to inset lists except callable +macros are ignored. +\&.It Em Hang +Hanged labels are a matter of taste. +\&.It Em Ohang +Overhanging labels are nice when space is constrained. +\&.It Em Inset +Inset labels are useful for controlling blocks of +paragraphs and are valuable for converting +\&.Xr mdoc +manuals to other formats. +\&.El +.Ed +. +. +.Pp +. +.It Fl column +This list type generates multiple columns. +The number of columns and the width of each column is determined by the +arguments to the +.Fl column +list, +.Aq Ar string1 , +.Aq Ar string2 , +etc. +If +.Aq Ar stringN +starts with a +.Ql .\& +(dot) immediately followed by a valid +.Xr mdoc +macro name, interpret +.Aq Ar stringN +and use the width of the result. +Otherwise, the width of +.Aq Ar stringN +(typeset with a fixed-width font) is taken as the +.Ar N Ns th +column width. +. +. +.Pp +Each +.Ql .It +argument is parsed to make a row, each column within the row is a separate +argument separated by a tab or the +.Ql .Ta +macro. +. +. +.Pp +The table: +. +.Bl -column -offset indent ".Sy String" ".Sy Nroff" ".Sy Troff" +.It Sy String Ta Sy Nroff Ta Sy Troff +.It Li <= Ta <= Ta \*(<= +.It Li >= Ta >= Ta \*(>= +.El +. +. +.Pp +was produced by: +. +.Bd -literal +\&.Bl \-column \-offset indent ".Sy String" ".Sy Nroff" ".Sy Troff" +\&.It Sy String Ta Sy Nroff Ta Sy Troff +\&.It Li <= Ta <= Ta \e*(<= +\&.It Li >= Ta >= Ta \e*(>= +\&.El +.Ed +. +. +.Pp +Don't abuse this list type! +. +For more complicated cases it might be far better and easier to use +.Xr @g@tbl @MAN1EXT@ , +the table preprocessor. +.El +. +. +.Pp +Other keywords: +. +.Bl -tag -width ".Fl indent Ao Ar string Ac" +.It Fl width Ao Ar string Ac +If +.Aq Ar string +starts with a +.Ql .\& +(dot) immediately followed by a valid +.Xr mdoc +macro name, interpret +.Aq Ar string +and use the width of the result. +. +Almost all lists in this document use this option. +. +. +.Pp +Example: +. +.Bd -literal -offset indent +\&.Bl \-tag \-width ".Fl test Ao Ar string Ac" +\&.It Fl test Ao Ar string Ac +This is a longer sentence to show how the +\&.Fl width +flag works in combination with a tag list. +\&.El +.Ed +. +. +.Pp +gives: +. +.Bl -tag -width ".Fl test Ao Ar string Ac" +.It Fl test Ao Ar string Ac +This is a longer sentence to show how the +.Fl width +flag works in combination with a tag list. +.El +. +. +.Pp +(Note that the current state of +.Xr mdoc +is saved before +.Aq Ar string +is interpreted; +afterwards, +all variables are restored again. +. +However, +boxes +(used for enclosures) +can't be saved in +.Tn GNU +.Xr @g@troff @MAN1EXT@ ; +as a consequence, +arguments must always be +.Em balanced +to avoid nasty errors. +. +For example, +do not write +.Ql ".Ao Ar string" +but +.Ql ".Ao Ar string Xc" +instead if you really need only an opening angle bracket.) +. +. +.Pp +Otherwise, +if +.Aq Ar string +is a valid numeric expression +.Em ( with a scaling indicator other than +.Sq Em u ) , +use that value for indentation. +The most useful scaling indicators are +.Sq m +and +.Sq n , +specifying the so-called +.Em \&Em +and +.Em "En square" . +This is approximately the width of the letters +.Sq m +and +.Sq n +respectively +of the current font +(for +.Xr @g@nroff +output, +both scaling indicators give the same values). +. +If +.Aq Ar string +isn't a numeric expression, it is tested whether it is an +.Xr mdoc +macro name, and the default width value associated with this macro is used. +Finally, if all tests fail, +the width of +.Aq Ar string +(typeset with a fixed-width font) is taken as the width. +. +. +.Pp +If a width is not specified for the tag list type, +.Sq 6n +is used. +.It Fl offset Ao Ar string Ac +If +.Aq Ar string +is +.Ar indent , +a default indent value (normally set to\~6n, +similar to the value used in +.Ql .Dl +or +.Ql .Bd ) +is used. +If +.Aq Ar string +is a valid numeric expression instead +.Pf ( Em with a scaling indicator other than +.Sq Em u ) , +use that value for indentation. +The most useful scaling indicators are +.Sq m +and +.Sq n , +specifying the so-called +.Em \&Em +and +.Em "En square" . +. +This is approximately the width of the letters +.Sq m +and +.Sq n +respectively +of the current font +(for +.Xr nroff +output, +both scaling indicators give the same values). +. +If +.Aq Ar string +isn't a numeric expression, it is tested whether it is an +.Xr mdoc +macro name, and the default offset value associated with this macro is used. +Finally, if all tests fail, +the width of +.Aq Ar string +(typeset with a fixed-width font) is taken as the offset. +.It Fl compact +Suppress insertion of vertical space before the list and between list items. +.El +. +. +.Sh "Miscellaneous macros" +. +A double handful of macros fit only uncomfortably into one of the above +sections. +. +Of these, +we couldn't find attested examples for +.Ql \&Me +or +.Ql \&Ot . +. +They are documented here for completeness\[em]if you know their proper +usage, +please send a mail to +.Mt groff@gnu.org +and include a specimen with its provenance. +. +. +.Bl -tag -width ".Li .Bt" +.It Li .Bt +formats boilerplate text. +. +.\" XXX: .Bt gets parsed (i.e., called) _and_ measured even _with_ a +.\" leading dot. See Savannah #63672. +.Bl -tag -width \&.Bt -offset indent +.It Li .Bt +\[->] +.Bt +.El +. +. +.Pp +It is neither callable nor parsed and takes no arguments. +. +Its default width is 6n. +. +. +.It Li .Fr +is an obsolete means of specifying a function return value. +. +. +.Pp +.D1 Usage: Pf . Ic \&Fr Ar return-value No ... +. +. +.Pp +.Ql \&Fr +allows a break right before the return value +(usually a single digit) +which is bad typographical behaviour. +. +Instead, +set the return value with the rest of the code, +using +.Ql \[rs]\[ti] +to tie the return value to the previous word. +. +. +.Pp +Its default width is 12n. +. +. +.It Li .Hf +Inlines the contents of a (header) file into the document. +. +. +.Pp +.D1 Usage: Pf . Ic \&Hf Ar file +. +. +.Pp +It first prints +.Ql File: +followed by the file name, +then the contents of +.Ar file . +. +It is neither callable nor parsed. +. +. +.It Li .Lk +Embed hyperlink. +. +. +.Pp +.D1 Usage: Pf . Ic \&Lk Ar uri Op Ar link-text +. +. +.Pp +Its default width is 6n. +. +. +.It Li .Me +Usage unknown. +. +The +.Xr mdoc +sources describe it as a macro for +.Dq "menu entries" . +. +. +.Pp +Its default width is 6n. +. +. +.It Li .Mt +Embed email address. +. +. +.Pp +.D1 Usage: Pf . Ic \&Mt Ar email-address +. +. +.Pp +Its default width is 6n. +. +. +.It Li .Ot +Usage unknown. +The +.Xr mdoc +sources describe it as +.Dq "old function type (fortran)" . +. +. +.It Li .Sm +Manipulate or toggle argument-spacing mode. +. +. +.Pp +.D1 Usage: Pf . Ic \&Sm Oo Li on | Li off Oc ... +. +. +.Pp +If argument-spacing mode is off, +no spaces between macro arguments are inserted. +. +If called without a parameter +(or if the next parameter is neither +.Ql on +nor +.Ql off ) , +.Ql \&Sm +toggles argument-spacing mode. +. +. +.Pp +Its default width is 8n. +.\" XXX: The package demands it, but how is that meaningful? +. +. +.It Li .Ud +formats boilerplate text. +. +.\" XXX: .Ud gets parsed (i.e., called) _and_ measured even _with_ a +.\" leading dot. See Savannah #63672. +.Bl -tag -width \&.Ud -offset indent +.It Li .Ud +\[->] +.Ud +.El +. +. +.Pp +It is neither callable nor parsed and takes no arguments. +. +Its default width is 8n. +.El +. +. +.Sh "Predefined strings" +. +The following strings are predefined for compatibility with legacy +.Xr mdoc +documents. +. +Contemporary ones should use the alternatives shown in the +.Dq Prefer +column below. +. +See +.Xr groff_char @MAN7EXT@ +for a full discussion of these special character escape sequences. +. +. +.Pp +.\" Note: This table pushes 80-column ASCII and Latin-1 terminals to +.\" the limits of their capacity. Observe the spacing parameters of the +.\" 2nd and 3rd columns; we had to steal a character cell from each (the +.\" default is 3) because in the UCS column, the word "infinity" gets +.\" written out in full, which in turn pushes the >= and Ge rows past +.\" the 78n norm. Update with caution. See Savannah #59424. +.TS +Cb Lb2 Lb2 Lb Lb Lb +Lf(CR) L2 L2 L Lf(CR) L. +String 7-bit 8-bit UCS Prefer Meaning +\[rs]*(<= <= <= \*[<=] \[rs](<= less than or equal to +\[rs]*(>= >= >= \*[>=] \[rs](>= greater than or equal to +\[rs]*(Rq " " \*[Rq] \[rs](rq right double quote +\[rs]*(Lq " " \*[Lq] \[rs](lq left double quote +\[rs]*(ua \[ha] \[ha] \*[ua] \[rs](ua vertical arrow up +\[rs]*(aa \[aq] \' \*[aa] \[rs](aa acute accent +\[rs]*(ga \` \` \*[ga] \[rs](ga grave accent +\[rs]*(q \&" \&" \*[q] \[rs](dq neutral double quote +\[rs]*(Pi pi pi \*[Pi] \[rs](*p lowercase pi +\[rs]*(Ne != != \*[Ne] \[rs](!= not equals +\[rs]*(Le <= <= \*[Le] \[rs](<= less than or equal to +\[rs]*(Ge >= >= \*[Ge] \[rs](>= greater than or equal to +\[rs]*(Lt < < \*[Lt] < less than +\[rs]*(Gt > > \*[Gt] > greater than +\[rs]*(Pm +\- \[+-] \*[Pm] \[rs](+\- plus or minus +\[rs]*(If infinity infinity \*[If] \[rs](if infinity +\[rs]*(Am \*[Am] \*[Am] \*[Am] & ampersand +\[rs]*(Na \*[Na] \*[Na] \*[Na] NaN not a number +\[rs]*(Ba \*[Ba] \*[Ba] \*[Ba] | bar +.TE +. +. +.Pp +Some column headings are shorthand for standardized character encodings; +\[lq]7-bit\[rq] for ISO 646:1991 IRV (US-ASCII), +\[lq]8-bit\[rq] for ISO 8859-1 (Latin-1) and IBM code page 1047, +and +\[lq]UCS\[rq] for ISO 10646 (Unicode character set). +. +Historically, \" (\[ti]1989) +.Xr mdoc +configured the string definitions to fit the capabilities expected of +the output device. +. +Old typesetters \" like the C/A/T +lacked directional double quotes, +producing repeated directional single quotes +\[oq]\[oq]like this\[cq]\[cq]; +early versions of +.Xr mdoc +in fact defined the +.Ql Lq +and +.Ql Rq +strings this way. \" thanks to Ingo Schwarze for the research +. +Nowadays, +output drivers \" technically, their macro files or font descriptions +take on the responsibility of glyph substitution, +as they possess relevant knowledge of their available repertoires. +. +. +.Sh Diagnostics +. +The debugging macro +.Ql .Db +offered by +previous versions of +.Xr mdoc +is unavailable in +.Tn GNU +.Xr @g@troff @MAN1EXT@ +since the latter provides better facilities to check parameters; +additionally, +.Xr "groff mdoc" +implements many error and warning messages, +making the package more robust and more verbose. +. +. +.Pp +The remaining debugging macro is +.Ql .Rd , +which dumps the package's global register and string contents to the +standard error stream. +. +A normal user will never need it. +. +. +.Sh Options +. +The following +.Xr groff +options set registers +(with +.Fl r ) +and strings +(with +.Fl d ) +recognized and used by the +.Xr mdoc +macro package. +. +To ensure rendering consistent with output device capabilities and +reader preferences, +man pages should never manipulate them. +. +. +.Pp +Setting string +.Ql AD +configures the adjustment mode for most formatted text. +. +Typical values are +.Ql b +for adjustment to both margins +(the default), +or +.Ql l +for left alignment +(ragged right margin). +. +Any valid argument to +.Xr groff Ns 's +.Ql ad +request may be used. +. +See +.Xr groff @MAN7EXT@ +for less-common choices. +. +.Dl groff \-Tutf8 \-dAD=l \-mdoc groff_mdoc.7 | less \-R +. +. +.Pp +Setting register +.Ql C +to\~1 numbers output pages consecutively, +rather than resetting the page number to\~1 +(or the value of register +.Ql P ) +with each new +.Xr mdoc +document. +. +. +.Pp +By default, +the package inhibits page breaks, +headers, +and footers in the midst of the document text if it is being displayed +with a terminal device such as +.Sq latin1 +or +.Sq utf8 , +to enable more efficient viewing of the page. +. +This behavior can be changed to format the page as if for 66-line +Teletype output by setting the continuous rendering register +.Ql cR +to zero while calling +.Xr groff @MAN1EXT@ . +. +.Dl groff \-Tlatin1 \-rcR=0 \-mdoc foo.man > foo.txt +. +On HTML devices, +it cannot be disabled. +. +. +.Pp +Section headings +(defined with +.Ql .Sh ) +and page titles in headers +(defined with +.Ql .Dt ) +can be presented in full capitals by setting the registers +.Ql CS +and +.Ql CT , +respectively, +to 1. +. +These transformations are off by default because they discard case +distinction information. +. +. +.Pp +Setting register +.Ql D +to\~1 enables double-sided page layout, +which is only distinct when not continuously rendering. +. +It places the page number at the bottom right on odd-numbered (recto) +pages, +and at the bottom left on even-numbered (verso) pages, +swapping places with the arguments to +.Ql .Os . +. +.Dl groff \-Tps \-rD1 \-mdoc foo.man > foo.ps +. +. +.Pp +The value of the +.Ql FT +register determines the footer's distance from the page bottom; +this amount is always negative and should specify a scaling unit. +. +At one half-inch above this location, +the page text is broken before writing the footer. +. +It is ignored if continuous rendering is enabled. +. +The default is \-0.5i. +. +. +.Pp +The +.Ql HF +string sets +the font used for section and subsection headings; +the default is +.Ql B +(bold style of the default family). +. +Any valid argument to +.Xr groff Ns 's +.Ql ft +request may be used. +. +. +.Pp +Normally, +automatic hyphenation is enabled using a mode appropriate to the +.Xr groff +locale; +see section \[lq]Localization\[lq] of +.Xr groff @MAN7EXT@ . +. +It can be disabled by setting the +.Ql HY +register to zero. +. +.Dl groff \-Tutf8 \-rHY=0 \-mdoc foo.man | less \-R +. +. +.Pp +The paragraph and subsection heading indentation amounts can be changed +by setting the registers +.Ql IN +and +.Ql SN . +. +.Dl groff \-Tutf8 \-rIN=5n \-rSN=2n \-mdoc foo.man | less \-R +. +The default paragraph indentation is 7.2n on typesetters and 7n on +terminals. +. +The default subsection heading indentation amount is 3n; +section headings are set with an indentation of zero. +. +. +.Pp +The line and title lengths can be changed by setting the registers +.Ql LL +and +.Ql LT , +respectively: +. +.Dl groff \-Tutf8 \-rLL=100n \-rLT=100n \-mdoc foo.man | less \-R +. +If not set, +both registers default to 78n for terminal devices and 6.5i otherwise. +. +. +.Pp +Setting the +.Ql P +register starts enumeration of pages at its value. +. +The default is\~1. +. +. +.Pp +To change the document font size to 11p or 12p, +set register +.Ql S +accordingly: +. +.Dl groff \-Tdvi \-rS11 \-mdoc foo.man > foo.dvi +. +Register +.Ql S +is ignored when formatting for terminal devices. +. +. +.Pp +Setting the +.Ql X +register to a page number +.Ar p +numbers its successors as +.Ar p Ns Li a , +.Ar p Ns Li b , +.Ar p Ns Li c , +and so forth. +. +The register tracking the suffixed page letter uses format +.Ql a +(see the +.Ql af +request in +.Xr groff @MAN7EXT@ ) . +. +. +.br +.ne 4v +.Sh Files +. +.Bl -tag +.It Pa @MACRODIR@/\:andoc\:.tmac +This brief +.Xr groff +program detects whether the +.Xr man +or +.Xr mdoc +macro package is being used by a document and loads the correct macro +definitions, +taking advantage of the fact that pages using them must call +.Li TH +or +.Li Dd , +respectively, +before any other macros. +. +A user typing, +for example, +.Dl groff \-mandoc page.1 +need not know which package the file +.Pa page.1 +uses. +. +Multiple man pages, +in either format, +can be handled; +.Pa \%andoc\:.tmac +reloads each macro package as necessary. +. +. +.It Pa @MACRODIR@/\:doc\:.tmac +implements the bulk of the +.Xr groff Xr mdoc +package and loads further components as needed from the +.Pa mdoc +subdirectory. +. +. +.It Pa @MACRODIR@/\:mdoc\:.tmac +is a wrapper that loads +.Pa doc.tmac . +. +. +.It Pa @MACRODIR@/\:mdoc/\:doc\-common +defines macros, +registers, +and strings +concerned with the production of formatted output. +.\" XXX: This is a weak explanation. The boundary between doc.tmac's +.\" concerns and doc-common's is not at all clear to GBR. Should some +.\" of these files be merged? +. +It includes strings of the form +.Ql doc\-volume\-ds\- Ns Ar X +and +.Ql doc\-volume\-as\- Ns Ar X +for manual section titles and architecture identifiers, +respectively, +where +.Ar X +is an argument recognized by +.Pf . Ic \&Dt . +. +. +.It Pa @MACRODIR@/\:mdoc/\:doc\-nroff +defines parameters appropriate for rendering to terminal devices. +. +. +.It Pa @MACRODIR@/\:mdoc/\:doc\-ditroff +defines parameters appropriate for rendering to typesetter devices. +. +. +.It Pa @MACRODIR@/\:mdoc/\:doc\-syms +defines many strings and macros that interpolate formatted text, +such as names of operating system releases, +*BSD libraries, +and standards documents. +. +The string names are of the form +.Ql doc\-str\- Ns Ar O Ns Li \- Ns Ar V , +.Ql doc\-str\-St Ns Li \-\- Ns Ar S Ns Li \- Ns Ar I +(observe the double dashes), +or +.Ql doc\-str\-Lb\- Ns Ar L , +where +.Ar O +is one of the operating system macros from section +.Sx "General text domain" +above, +.Ar V +is an encoding of an operating system release +(sometimes omitted along with the +.Ql \- +preceding it), +.Ar S +an identifier for a standards body or committee, +.Ar I +one for an issue of a standard promulgated by +.Ar S , +and +.Ar L +a keyword identifying a *BSD library. +. +. +.It Pa @LOCALMACRODIR@/\:mdoc\:.local +This file houses local additions and customizations to the package. +. +It can be empty. +.El +. +. +.Sh "See also" +. +The +.Lk https://mandoc.bsd.lv/ mandoc +project maintains an independent implementation of the +.Xr mdoc +language and a renderer that directly parses its markup as well as that +of +.Xr man . +. +. +.Pp +.Xr groff @MAN1EXT@ , +.Xr man 1 , +.Xr @g@troff @MAN1EXT@ , +.Xr groff_man @MAN7EXT@ , +.Xr mdoc 7 +. +. +.Sh Bugs +. +Section 3f has not been added to the header routines. +. +. +.Pp +.Ql .Fn +needs to have a check to prevent splitting up the line if its length is +too short. +. +Occasionally it separates the last parenthesis, +and sometimes looks ridiculous if output lines are being filled. +. +. +.Pp +The list and display macros do not do any keeps and certainly should be +able to. +. +. +.Pp +As of +.Xr groff +1.23, +.Ql \&Tn +no longer changes the type size; +this functionality may return in the next release. +.\" Note what happens if the parameter list overlaps a newline +.\" boundary. +.\" to make sure a line boundary is crossed: +.\" .Bd -literal +.\" \&.Fn struct\e\ dictionarytable\e\ *dictionarylookup struct\e\ dictionarytable\e\ *tab[] +.\" .Ed +.\" . +.\" . +.\" .Pp +.\" produces, nudge nudge, +.\" .Fn struct\ dictionarytable\ *dictionarylookup char\ *h struct\ dictionarytable\ *tab[] , +.\" .Fn struct\ dictionarytable\ *dictionarylookup char\ *h struct\ dictionarytable\ *tab[] , +.\" nudge +.\" .Fn struct\ dictionarytable\ *dictionarylookup char\ *h struct\ dictionarytable\ *tab[] . +.\" . +.\" . +.\" .Pp +.\" If double quotes are used, for example: +.\" .Bd -literal +.\" \&.Fn \*qstruct dictionarytable *dictionarylookup\*q \*qchar *h\*q \*qstruct dictionarytable *tab[]\*q +.\" .Ed +.\" . +.\" . +.\" .Pp +.\" produces, nudge nudge, +.\" .Fn "struct dictionarytable *dictionarylookup" "char *h" "struct dictionarytable *tab[]" , +.\" nudge +.\" .Fn "struct dictionarytable *dictionarylookup" "char *h" "struct dictionarytable *tab[]" , +.\" nudge +.\" .Fn "struct dictionarytable *dictionarylookup" "char *h" "struct dictionarytable *tab[]" . +.\" . +.\" . +.\" .Pp +.\" Not a pretty sight... +.\" In a paragraph, a long parameter containing unpaddable spaces as +.\" in the former example will cause +.\" .Xr @g@troff +.\" to break the line and spread +.\" the remaining words out. +.\" The latter example will adjust nicely to +.\" justified margins, but may break in between an argument and its +.\" declaration. +.\" In +.\" .Xr @g@nroff +.\" the right margin is normally ragged and the problem is not as +.\" severe. +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_groff_mdoc_7_man_C] +.do rr *groff_groff_mdoc_7_man_C +. +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/groff_me.7.man b/tmac/groff_me.7.man new file mode 100644 index 0000000..38735d1 --- /dev/null +++ b/tmac/groff_me.7.man @@ -0,0 +1,601 @@ +'\" t +.TH groff_me @MAN7EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +groff_me \- \(lqme\(rq macro package for formatting +.I roff +documents +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1980, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" 3. [Deleted. See +.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] +.\" 4. Neither the name of the University nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" +.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +.\" PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR +.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)me.7 8.1 (Berkeley) 06/05/93 +.\" +.\" Modified for groff by jjc@jclark.com +.\" Changed to use TBL and eliminate low-level troff hackery by ESR +.\" (this enables it to be lifted to structural markup). +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_groff_me_7_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY "groff \-me" +.RI [ option\~ .\|.\|.\&] +.RI [ file\~ .\|.\|.] +. +.SY "groff \-m me" +.RI [ option\~ .\|.\|.\&] +.RI [ file\~ .\|.\|.] +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +The GNU implementation of the +.I me +macro package is part of the +.I groff +document formatting system. +. +The +.I me +package of macro definitions for the +.I roff +language provides a convenient facility for preparing technical papers +in various formats. +. +This version is based on the +.I me +distributed with 4.4BSD and can be used with the GNU +.I troff +formatter as well as those descended from AT&T +.IR troff . +. +. +.P +Some formatter requests affect page layout unpredictably when used in +conjunction with this package; +however, +the following may be used with impunity after the first call to a +paragraphing macro like +.B lp +or +.BR pp . +. +Some arguments are optional; +see +.MR groff @MAN7EXT@ +for details, +particularly of requests whose argument list is designated with an +ellipsis. +. +An asterisk +.B * +marks +.I groff +extensions. +. +. +.P +.TS +Lb1 Li L. +ad c set text adjustment mode to \fIc +af r f assign format \fIf\fP to register \fIr +am m e append to macro \fIm\fP until \fIe\fP called +as s t append rest of line \fIt\fP to string \fIs +bp n begin new page numbered \fIn +br \& break output line +ce n center next \fIn\fP output lines +cp n en-/disable AT&T \fItroff\fP compatibility mode\fB* +de m e define macro \fIm\fP until \fIe\fP called +do t interpret input \fIt\fP with compatibility mode off\fB* +ds s t define rest of line \fIt\fP as string \fIs +el t interpret \fIt\fP if corresponding \fBie\fP false +fc c d set field delimiter \fIc\fP and padding glyph \fId +fi \& enable filling +hc c set hyphenation character to \fIc +hy m set automatic hyphenation mode to \fIm +ie p t as \fBif\fP, but enable interpretation of later \fBel +if p t if condition \fIp\/\fP, interpret rest of line \fIt +in h set indentation to distance \fIh\fP +lc c set leader repetition glyph to \fIc +ls n set line spacing to \fIn +mc c h set (right) margin glyph to \fIc\fP at distance \fIh +mk r mark vertical position in register \fIr\fP +na \& disable adjustment of text +ne v need vertical space of distance \fIv +nf \& disable filling +nh \& disable automatic hyphenation +nr r n i assign register \fIr\fP value \fIn\fP with \ +auto-increment \fIi +ns \& begin no-space mode +pl v set page length to \fIv +pn n set next page number to \fIn +po h set page offset to \fIh +rj n right-align next \fIn\fP output lines\fB* +rm m remove macro, string, or request \fIm +rn m n rename macro, string, or request \fIm\fP to \fIn +rr r remove register \fIr +rs \& resume spacing (end no-space mode) +rt v return to vertical position set by \fBmk\fP, or \fIv +so f source (interpolate) input file \fIf +sp n insert \fIn\fP lines of vertical space +ta \fR.\|.\|. set tab stops +tc c set tab repetition glyph to \fIc +ti h set temporary indentation (next line only) to \fIh +tl \fR.\|.\|. output three-part title +tr \fR.\|.\|. translate characters +ul n underline next \fIn\fP output lines +.TE +. +. +.P +Except on title pages +(produced by calling +.BR tp ), +.I me +suppresses the output of vertical space at the tops of pages +(after the output of any page header); +the +.B sp +request will thus not work there. +. +You can instead call +.B bl +or enclose the desired spacing request in a diversion, +for instance by calling +.B (b +and +.BR )b . +. +.I me +also intercepts the +.B ll +request; +see the +.RI \[lq] me +Reference Manual\[rq] +for details. +. +. +.\" ==================================================================== +.SS "Name space" +.\" ==================================================================== +. +Objects in +.I me +follow a rigid naming convention. +. +To avoid conflict, +any user-defined register, +string, +or macro +names should be single numerals or uppercase letters, +or any longer sequence of letters and numerals +with at least one uppercase letter. +. +(For portability between BSD and +.I groff +.IR me , +limit names to +two characters, +and avoid the name +.B [ +(left square bracket).) +. +The names employed +by any preprocessors in use +should also not be repurposed. +. +. +.\" ==================================================================== +.SS Macros +.\" ==================================================================== +. +.ne 2v \" Keep at least the first entry together with the heading. +.TS +Lb L. +$0 post-section heading hook +$1 pre-section depth 1 hook +$2 pre-section depth 2 hook +$3 pre-section depth 3 hook +$4 pre-section depth 4 hook +$5 pre-section depth 5 hook +$6 pre-section depth 6 hook +$C post-chapter title hook +$H page/column heading hook +$c output chapter number and title +$f output footer +$h output header +$p output section heading +$s output footnote area separator +(b begin block +(c begin centered block +(d begin delayed text +(f begin footnote +(l begin list +(q begin long quotation +(x begin index entry +(z begin floating keep +)b end block +)c end centered block +)d end delayed text +)f end footnote +)l end list +)q end long quotation +)x end index entry +)z end floating keep +++ set document segment type ++c begin chapter +1c end multi-column layout +2c begin multi-column layout +EN end \fI@g@eqn\fP equation +EQ begin \fI@g@eqn\fP equation +GE end \fI@g@grn\fP picture with drawing position at bottom +GF end \fI@g@grn\fP picture with drawing position at top +GS start \fI@g@grn\fP picture +IE end \fIideal\fP picture with drawing position at bottom +IF end \fIideal\fP picture with drawing position at top +IS start \fIideal\fP picture +PE end \fI@g@pic\fP picture with drawing position at bottom +PF end \fI@g@pic\fP picture with drawing position at top +PS start \fI@g@pic\fP picture +TE end \fI@g@tbl\fP table +TH end heading for multi-page \fI@g@tbl\fP table +TS start \fI@g@tbl\fP table +b embolden argument +ba set base indentation +bc begin new column +bi embolden and italicize argument +bx box argument +ef set even-numbered page footer +eh set even-numbered page header +ep end page +fo set footer +he set header +hl draw horizontal line +hx suppress next page's headers/footers +i italicize argument +ip begin indented paragraph +ld reset localization and date registers and strings\fB* +ll set line length +lp begin fully left-aligned paragraph +np begin numbered paragraph +of set odd-numbered page footer +oh set odd-numbered page header +pd output delayed text +pp begin first-line indented paragraph +q quote argument +r set argument in roman +re reset tab stops +sh begin numbered section +sm set argument at smaller type size +sx change section depth +sz set type size and vertical spacing +tp begin title page +u underline argument +uh begin unnumbered section +xl set line length (local) +xp output index +.TE +. +. +.P +Some macros are provided for \(lqold\(rq +.MR roff 1 +compatibility. +. +The +.RI \(lq me +Reference Manual\(rq +describes alternatives for modern documents. +. +. +.P +.ne 2v \" Keep at least the first entry together with the heading. +.TS +Lb L. +ar use Arabic numerals for page numbers +bl insert space (even at page top; cf.\& \fBsp\fP) +ix set indentation without break +m1 set page top to header distance +m2 set header to text distance +m3 set text to footer distance +m4 set footer to page bottom distance +n1 begin output line numbering +n2 end or alter output line numbering +pa begin page +ro use Roman numerals for page numbers +sk skip next page +.TE +. +. +.\" ==================================================================== +.SS Registers +.\" ==================================================================== +. +.ne 2v \" Keep at least the first entry together with the heading. +.TS +Lb L. +$0 section depth +$1 first section number component +$2 second section number component +$3 third section number component +$4 fourth section number component +$5 fifth section number component +$6 sixth section number component +$c current column number +$d delayed text number +$f footnote number +$i paragraph base indentation +$l column width +$m number of available columns +$p numbered paragraph number +$s column spacing (indentation) +bi display (block) indentation +bm distance from text area to page bottom +bs display (block) pre/post space +bt block threshold for keeps +ch current chapter number +df display font +dv vertical spacing of displayed text (as percentage)\fB* +es equation pre/post space +ff footnote font +fi footnote indentation (first line only) +fm footer margin +fp footnote type size in points +fs footnote prespace +fu footnote undent (right indentation) +hm header margin +ii indented paragraph indentation +no line numbering offset\fB* +pf paragraph font +pi paragraph indentation +po page offset +pp paragraph type size in points +ps paragraph prespace +qi long quotation left/right indentation +qp long quotation type size in points +qs long quotation pre/post space +sf section title font +si section indentation per level of depth +so additional section title offset +sp section title type size in points +ss section prespace +sx super/subscript line height increase\fB* +tf title font +tm distance from page top to text area +tp title type size in points +tv vertical spacing of text (as percentage)\fB* +xs index entry prespace +xu index undent (right indentation) +y2 year of the century\fB* +y4 year\fB* +yr year minus 1900 +zs floating keep pre/post space +.TE +. +. +.\" ==================================================================== +.SS Strings +.\" ==================================================================== +. +.ne 2v \" Keep at least the first entry together with the heading. +.TS +Lb L. +# delayed text marker +$n concatenated section number +* footnote marker +\- em dash +< begin subscripting +> end subscripting +dw weekday name +lq left double quotation mark +mo month name +rq right double quotation mark +td date +wa term for \(lqappendix\(rq used by \fB.$c* +wc term for \(lqchapter\(rq used by \fB.$c* +{ begin superscripting +} end superscripting +.TE +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.I @MACRODIR@/e.tmac +implements the package. +. +. +.TP +.I @MACRODIR@/refer\-me.tmac +implements +.MR @g@refer @MAN1EXT@ +support for +.IR me . +. +. +.TP +.I @MACRODIR@/me.tmac +is a wrapper enabling the package to be loaded with +.RB \[lq] "groff \-m me" \[rq]. +. +. +.\" ==================================================================== +.SH Notes +.\" ==================================================================== +. +Early +.I roff +macro packages often limited their names to a single letter, +which followed the formatter's +.B m +flag letter, +resulting in +.IR mm , +.IR ms , +.IR mv , +.IR mn , +and so on. +. +.\" 'When I started writing the -me macros it began as something in my +.\" private tree (I don't remember what I called it). Then some other +.\" folks on the INGRES project wanted to use it, but our system admin +.\" at the time didn't want to dicker with the system namespace at the +.\" behest of a mere undergraduate, so he didn't like anything that was +.\" actually descriptive lest people think it was "official". He +.\" finally consented to "-meric" (which I always hated), since it was +.\" obviously non-official. By the time my macros became popular around +.\" Berkeley it got shortened to "-me", much to my relief. +.\" +.\" Of course, if AT&T had been willing to let Berkeley have -ms then +.\" most likely -me would never have happened at all. Without a macro +.\" package, nroff/troff is basically unusable; -me stepped into the +.\" vacuum.' -- Eric Allman +.\" +.\" https://minnie.tuhs.org/pipermail/tuhs/2018-November/017033.html +. +The \(lqe\(rq in \(lqme\(rq stands for \(lqEric P.\& Allman\(rq, +who wrote the macro package and the original technical papers +documenting it while an undergraduate at the University of California. +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +. +Two manuals are available in source and rendered form. +. +On your system, +they may be compressed and/or available in additional formats. +. +. +.br +.ne 3v +.TP +.I @DOCDIR@/meintro.me +.TQ +.I @DOCDIR@/meintro.ps +is +\[lq]Writing Papers with +.I Groff +Using +.RI \- me \[rq], +by Eric P.\& Allman, +adapted for +.I groff +by James Clark. +. +. +.br +.ne 4v +.TP +.I @DOCDIR@/meref.me +.TQ +.I @DOCDIR@/meref.ps +is the +.RI \[lq] me +Reference Manual\[rq], +by Eric P.\& Allman, +adapted for +.I groff +by James Clark and G.\& Branden Robinson. +. +. +.P +.IR "Groff: The GNU Implementation of troff" , +by Trent A.\& Fisher and Werner Lemberg, +is the primary +.I groff +manual. +. +You can browse it interactively with \[lq]info groff\[rq]. +. +. +.P +For preprocessors supported by +.IR me , +see +.MR @g@eqn @MAN1EXT@ , +.MR @g@grn @MAN1EXT@ , +.MR @g@pic @MAN1EXT@ , +.MR @g@refer @MAN1EXT@ , +and +.MR @g@tbl @MAN1EXT@ . +. +. +.P +.MR groff @MAN1EXT@ , +.MR @g@troff @MAN1EXT@ , +.MR groff @MAN7EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_groff_me_7_man_C] +.do rr *groff_groff_me_7_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/groff_ms.7.man b/tmac/groff_ms.7.man new file mode 100644 index 0000000..5d154f8 --- /dev/null +++ b/tmac/groff_ms.7.man @@ -0,0 +1,2906 @@ +'\" t +.TH groff_ms @MAN7EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +groff_ms \- GNU +.I roff +manuscript macro package for formatting documents +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1989-2023 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_groff_ms_7_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY "groff \-m@TMAC_S_PREFIX@s" +.RI [ option\~ .\|.\|.\&] +.RI [ file\~ .\|.\|.] +. +.SY "groff \-m m@TMAC_S_PREFIX@s" +.RI [ option\~ .\|.\|.\&] +.RI [ file\~ .\|.\|.] +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +The GNU implementation of the +.I ms +macro package is part of the +.I groff +document formatting system. +. +The +.I ms +package is suitable for the composition of +letters, +memoranda, +reports, +and books. +. +. +.LP +These +.I groff +macros support cover page and table of contents generation, +automatically numbered headings, +several paragraph styles, +a variety of text styling options, +footnotes, +and multi-column page layouts. +. +.I ms +supports the +.MR @g@tbl @MAN1EXT@ , +.MR @g@eqn @MAN1EXT@ , +.MR @g@pic @MAN1EXT@ , +and +.MR @g@refer @MAN1EXT@ +preprocessors for inclusion of tables, +mathematical equations, +diagrams, +and standardized bibliographic citations. +. +. +.LP +This implementation is mostly compatible with the documented interface +and behavior of AT&T Unix Version\~7 +.IR ms . +. +Many extensions from 4.2BSD (Berkeley) +.\" Few changes were made in 4.3, Reno, Tahoe, or 4.4. +and Tenth Edition Research Unix have been recreated. +. +. +.\" ==================================================================== +.SH Usage +.\" ==================================================================== +. +The +.I ms +macro package expects a certain amount of structure: +a well-formed document contains at least one paragraphing or heading +macro call. +. +.\" This sentence is unique to the man page because we omit the "Basic +.\" information" section from ms.ms. +To compose a simple document from scratch, +begin it by calling +.B .LP +or +.BR .PP . +. +Longer documents have a structure as follows. +. +. +.TP +.B Document type +Calling the +.B RP +macro at the beginning of your document puts the document description +(see below) +on a cover page. +. +Otherwise, +.I ms +places this information +on the first page, +followed immediately by the body text. +. +Some document types found in other +.I ms +implementations are specific to AT&T or Berkeley, +and are not supported in +.IR "groff ms" . +. +. +.TP +.B "Format and layout" +By setting registers and strings, +you can configure your document's typeface, +margins, +spacing, +headers and footers, +and footnote arrangement. +. +See subsection \[lq]Document control settings\[rq] below. +. +. +.TP +.B Document description +A document description consists of any of: +a title, +one or more authors' names and affiliated institutions, +an abstract, +and a date or other identifier. +. +See subsection \[lq]Document description macros\[rq] below. +. +. +.TP +.B Body text +The main matter of your document follows its description +(if any). +. +.I ms +supports highly structured text consisting of paragraphs interspersed +with multi-level headings +(chapters, +sections, +subsections, +and so forth) +and augmented by lists, +footnotes, +tables, +diagrams, +and similar material. +. +The preponderance of subsections below covers these matters. +. +. +.TP +.B "Table of contents" +Macros enable the collection of entries for a table of contents +(or index) +as the material they discuss appears in the document. +. +You then call a macro to emit the table of contents at the end of +your document. +. +The table of contents must necessarily follow the rest of the text since +GNU +.I troff \" GNU +is a single-pass formatter; +it thus cannot determine the page number of a division of the text until +it has been set and output. +. +Since +.I ms +output was designed for the production of hard copy, +the traditional procedure was to manually relocate the pages containing +the table of contents between the cover page and the body text. +. +Today, +page resequencing is more often done in the digital domain. +. +An index works similarly, +but because it typically needs to be sorted after collection, +its preparation requires separate processing. +. +. +.\" ==================================================================== +.SS "Document control settings" +.\" ==================================================================== +. +The following tables list the document control registers, +strings, +and special characters. +. +For any parameter whose default is unsatisfactory, +define it before calling any +.I ms +macro other than +.BR RP . +. +. +.LP +.ne 7v +.TS +cb s s s +cb cb cb cb +lf(CR) lx l lf(CR). +Margin settings +Parameter Definition Effective Default +_ +\[rs]n[PO] Page offset (left margin) next page 1i (0) +\[rs]n[LL] Line length next paragraph 6.5i (65n) +\[rs]n[LT] Title line length next paragraph 6.5i (65n) +\[rs]n[HM] Top (header) margin next page 1i +\[rs]n[FM] Bottom (footer) margin next page 1i +_ +.TE +. +. +.LP +.ne 8v +.TS +cb s s s +cb cb cb cb +lf(CR) lx l lf(CR). +Titles (headers, footers) +Parameter Definition Effective Default +_ +\[rs]*[LH] Left header text next header \f[I]empty +\[rs]*[CH] Center header text next header \-\[rs]n[%]\- +\[rs]*[RH] Right header text next header \f[I]empty +\[rs]*[LF] Left footer text next footer \f[I]empty +\[rs]*[CF] Center footer text next footer \f[I]empty +\[rs]*[RF] Right footer text next footer \f[I]empty +_ +.TE +. +. +.LP +.ne 6v +.TS +cb s s s +cb cb cb cb +lf(CR) lx l lf(CR). +Text settings +Parameter Definition Effective Default +_ +\[rs]n[PS] Point size next paragraph 10p +\[rs]n[VS] Vertical spacing (leading) next paragraph 12p +\[rs]n[HY] Hyphenation mode next paragraph 6 +\[rs]*[FAM] Font family next paragraph T +_ +.TE +. +. +.LP +.ne 6v +.TS +cb s s s +cb cb cb cb +lf(CR)2 lx l lf(CR). +Paragraph settings +Parameter Definition Effective Default +_ +\[rs]n[PI] Indentation next paragraph 5n +\[rs]n[PD] Paragraph distance (spacing) next paragraph 0.3v\ + \f[R](\f[]1v\f[R]) +\[rs]n[QI] Quotation indentation next paragraph 5n +\[rs]n[PORPHANS] # of initial lines kept next paragraph 1 +_ +.TE +. +. +.ne 10v \" Keep table and subsequent paragraph together. +.LP +.TS +cb s s s +cb cb cb cb +lf(CR) lx l lf(CR). +Heading settings +Parameter Definition Effective Default +_ +\[rs]n[PSINCR] Point size increment next heading 1p +\[rs]n[GROWPS] Size increase depth limit next heading 0 +\[rs]n[HORPHANS] # of following lines kept next heading 1 +\[rs]*[SN\-STYLE] Numbering style (alias) next heading \[rs]*[SN\-DOT] +_ +.TE +. +. +.LP +.B \[rs]*[SN\-STYLE] +can alternatively be made an alias of +.B \[rs]*[SN\-NO\-DOT] +with the +.B als +request. +. +. +.LP +.ne 8v +.TS +cb s s s +cb cb cb cb +lf(CR) lx l lf(CR). +Footnote settings +Parameter Definition Effective Default +_ +\[rs]n[FI] Indentation next footnote 2n +\[rs]n[FF] Format next footnote 0 +\[rs]n[FPS] Point size next footnote \[rs]n[PS]\-2p +\[rs]n[FVS] Vertical spacing (leading) next footnote \[rs]n[FPS]+2p +\[rs]n[FPD] Paragraph distance (spacing) next footnote \[rs]n[PD]/2 +\[rs]*[FR] Line length ratio \f[I]special 11/12 +_ +.TE +. +. +.LP +.ne 4v +.TS +cb s s s +cb cb cb cb +lf(CR) lx l lf(CR). +Display settings +Parameter Definition Effective Default +_ +\[rs]n[DD] Display distance (spacing) \f[I]special 0.5v\ + \f[R](\f[]1v\f[R]) +\[rs]n[DI] Display indentation \f[I]special 0.5i +_ +.TE +. +. +.LP +.ne 3v +.TS +cb s s s +cb cb cb cb +lf(CR) lx l lf(CR). +Other settings +Parameter Definition Effective Default +_ +\[rs]n[MINGW] Minimum gutter width next page 2n +\[rs]n[TC\-MARGIN] TOC page number margin width \ +next \f[B]PX\f[] call \[rs]w\[aq]000\[aq] +\[rs][TC\-LEADER] TOC leader character next \f[B]PX\f[] call\ + .\[rs]h\[aq]1m\[aq] +_ +.TE +. +. +.LP +For entries marked +.RI \[lq] special \[rq] +in the \[lq]Effective\[rq] column, +see the discussion in the applicable section below. +. +The +.BR PO , +.BR LL , +and +.B LT +register defaults vary by output device and paper format; +the values shown are for typesetters using U.S.\& letter paper, +and then terminals. +. +See section \[lq]Paper format\[rq] of +.MR groff @MAN1EXT@ . +. +The +.B PD +and +.B DD +registers use the larger value if the vertical motion quantum of the +output device is too coarse for the smaller one; +usually, +this is the case only for output to terminals and emulators thereof. +. +The \[lq]gutter\[rq] affected by +.B \[rs]n[MINGW] +is the gap between columns in multiple-column page arrangements. +. +The +.B TC\-MARGIN +register and +.B TC\-LEADER +special character affect the formatting of tables of contents assembled +by the +.BR XS , +.BR XA , +and +.B XE +macros. +. +. +.\" ==================================================================== +.SS "Document description macros" +.\" ==================================================================== +. +Define information describing the document by calling the macros below +in the order shown; +.B .DA +or +.B .ND +can be called to set the document date +(or other identifier) +at any time before (a) the abstract, +if present, +or (b) its information is required in a header or footer. +. +Use of these macros is optional, +except that +.B .TL +is mandatory if any of +.BR .RP , +.BR .AU , +.BR .AI , +or +.B .AB +is called, +and +.B .AE +is mandatory if +.B .AB +is called. +. +. +.TP +.BR .RP\~ [ no\-repeat\-info ]\~[ no\-renumber ] +Use the \[lq]report\[rq] +(AT&T: \[lq]released paper\[rq]) +format for your document, +creating a separate cover page. +. +The default arrangement is to place most of the document description +(title, +author names and institutions, +and abstract, +but not the date) +at the top of the first page. +. +If the optional +.B no\-\:\%repeat\-\:\%info +argument is given, +.I ms +produces a cover page but does not repeat any of its information on +subsequently +(but see the +.B DA +macro below regarding the date). +. +Normally, +.B .RP +sets the page number following the cover page to\~1. +. +Specifying the optional +.B no\-\:\%renumber +argument suppresses this alteration. +. +Optional arguments can occur in any order. +. +.RB \[lq] no \[rq] +is recognized as a synonym of +.B no\-\:\%repeat\-\:\%info +for AT&T compatibility. +. +. +.TP +.B .TL +Specify the document title. +. +.I ms +collects text on input lines following this call into the title until +reaching +.BR .AU , +.BR .AB , +or a heading or paragraphing macro call. +. +. +.TP +.B .AU +Specify an author's name. +. +.I ms +collects text on input lines following this call into the author's name +until reaching +.BR .AI , +.BR .AB , +another +.BR .AU , +or a heading or paragraphing macro call. +. +Call it repeatedly to specify multiple authors. +. +. +.TP +.B .AI +Specify the preceding author's institution. +. +An +.B .AU +call is usefully followed by at most one +.B .AI +call; +if there are more, +the last +.B .AI +call controls. +. +.I ms +collects text on input lines following this call into the author's +institution until reaching +.BR .AU , +.BR .AB , +or a heading or paragraphing macro call. +. +. +.TP +.BR .DA \~[\c +.IR x \~.\|.\|.] +Typeset the current date, +or any +.RI arguments\~ x , +in the center footer, +and, +if +.B .RP +is also called, +left-aligned at the end of the document description on the cover page. +. +. +.TP +.BR .ND \~[\c +.IR x \~.\|.\|.] +Typeset the current date, +or any +.RI arguments\~ x , +if +.B .RP +is also called, +left-aligned at the end of the document description on the cover page. +. +This is +.IR "groff ms" 's +default. +. +. +.TP +.BR ".AB " [ no ] +Begin the abstract. +. +.I ms +collects text on input lines following this call into the abstract until +reaching an +.B .AE +call. +. +By default, +.I ms +places the word \[lq]ABSTRACT\[rq] centered and in italics above the +text of the abstract. +. +The optional argument +.RB \[lq] no \[rq] +suppresses this heading. +. +. +.TP +.B .AE +End the abstract. +. +. +.\" ==================================================================== +.SS "Text settings" +.\" ==================================================================== +. +The +.B FAM +string, +a GNU extension, +sets the font family for body text; +the default is +.RB \[lq] T \[rq]. +. +The +.B PS +and +.B VS +registers set the type size and vertical spacing +(distance between text baselines), +respectively. +. +The font family and type size are ignored on terminal devices. +. +Setting these parameters before the first call of a heading, +paragraphing, +or (non-date) document description macro also applies them to headers, +footers, +and +(for +.BR FAM ) +footnotes. +. +. +.br +.ne 2v +.P +The +.B HY +register defines the automatic hyphenation mode used with the +.B hy +request. +. +Setting +.B \[rs]n[HY] +.RB to\~ 0 +is equivalent to using the +.B nh +request. +. +This is a Tenth Edition Research Unix extension. +. +. +.\" ==================================================================== +.SS "Typographical symbols" +.\" ==================================================================== +. +.I ms +provides a few strings to obtain typographical symbols not easily +entered with the keyboard. +. +These and many others are available as special character escape +sequences\[em]see +.MR groff_char @MAN7EXT@ . +. +. +.TP +.B \[rs]*[\-] +Interpolate an em dash. +. +. +.TP +.B \[rs]*[Q] +.TQ +.B \[rs]*[U] +Interpolate typographer's quotation marks where available, +and neutral double quotes otherwise. +. +.B \[rs]*[Q] +is the left quote and +.B \[rs]*[U] +the right. +. +. +.\" ==================================================================== +.SS Paragraphs +.\" ==================================================================== +. +Paragraphing macros +.IR break , +or terminate, +any pending output line so that a new paragraph can begin. +. +Several paragraph types are available, +differing in how indentation +applies to them: +to left, +right, +or both margins; +to the first output line of the paragraph, +all output lines, +or all but the first. +. +All paragraphing macro calls cause the insertion of vertical space in +the amount stored in the +.B PD +register, +except at page or column breaks, +or adjacent to displays. +. +. +.PP +The +.B PORPHANS +register defines the minimum number of initial lines of any paragraph +that must be kept together to avoid isolated lines at the bottom of a +page. +. +If a new paragraph is started close to the bottom of a page, +and there is insufficient space to accommodate +.B \[rs]n[PORPHANS] +lines before an automatic page break, +then a page break is forced before the start of the paragraph. +. +This is a GNU extension. +. +. +.TP +.B .LP +Set a paragraph without any (additional) indentation. +. +. +.TP +.B .PP +Set a paragraph with a first-line left indentation in the amount stored +in the +.B PI +register. +. +. +.TP +.BR .IP \~[\c +.IR marker \~[ width ]] +Set a paragraph with a left indentation. +. +The optional +.I marker +is not indented and is empty by default. +. +.I width +overrides the indentation amount in +.BR \[rs]n[PI] ; +its default unit is +.RB \[lq] n \[rq]. +. +Once specified, +.I width +applies to further +.B .IP +calls until specified again or a heading or different paragraphing macro +is called. +. +. +.TP +.B .QP +Set a paragraph indented from both left and right margins by +.BR \[rs]n[QI] . +. +. +.TP +.B .QS +.TQ +.B .QE +Begin +.RB ( QS ) +and end +.RB ( QE ) +a region where each paragraph is indented from both margins by +.BR \[rs]n[QI] . +. +The text between +.B .QS +and +.B .QE +can be structured further by use of other paragraphing macros. +. +. +.TP +.B .XP +Set an \[lq]exdented\[rq] paragraph\[em]one with a left indentation of +.B \[rs]n[PI] +on every line +.I except +the first +(also known as a hanging indent). +. +This is a Berkeley extension. +. +. +.\" ==================================================================== +.SS Headings +.\" ==================================================================== +. +Use headings to create a hierarchical structure for your document. +. +The +.I ms +macros print headings in +.B bold +using the same font family and, +by default, +type size as the body text. +. +Headings are available with and without automatic numbering. +. +Text on input lines following the macro call becomes the heading's +title. +. +Call a paragraphing macro to end the heading text and start the +section's content. +. +. +.TP +.BR .NH \~[\c +.IR depth ] +Set an automatically numbered heading. +. +.I ms +produces a numbered heading in the form +.IR a . b . c .\|.\|., +to any level desired, +with the numbering of each depth increasing automatically and being +reset to zero when a more significant depth is increased. +. +.RB \[lq] 1 \[rq]\~is +the most significant or coarsest division of the document. +. +Only non-zero values are output. +. +If +.I depth +is omitted, +it is taken to be +.BR 1 . +. +If you specify +.I depth +such that an ascending gap occurs relative to the previous +.B NH +call\[em]that is, +you \[lq]skip a depth\[rq], +as by +.RB \[lq] ".NH\~1" \[rq] +and then +.RB \[lq] ".NH\~3" \[rq], +.I groff ms +emits a warning on the standard error stream. +. +. +.TP +.BI ".NH S\~" heading-depth-index\~\c +\&.\|.\|. +Alternatively, +you can give +.B NH +a first argument +.RB of\~\[lq] S \[rq], +followed by integers to number the heading depths explicitly. +. +Further automatic numbering, +if used, +resumes using the specified indices as their predecessors. +. +.\" Although undocumented in Tuthill's 4.2BSD ms.diffs paper... +This feature is a Berkeley extension. +. +. +.P +After +.B .NH +is called, +the assigned number is made available in the strings +.B SN\-DOT +(as it appears in a printed heading with default formatting, +followed by a terminating period) +and +.B SN\-NO\-DOT +(with the terminating period omitted). +. +These are GNU extensions. +. +. +.P +You can control the style used to print numbered headings by defining an +appropriate alias for the string +.BR SN\-STYLE . +. +By default, +.B \[rs]*[SN\-STYLE] +is aliased to +.BR \[rs]*[SN\-DOT] . +. +If you prefer to omit the terminating period from numbers appearing in +numbered headings, +you may alias it to +.BR \[rs]*[SN\-NO\-DOT] . +. +Any such change in numbering style becomes effective from the next use +of +.B .NH +following redefinition of the alias for +.BR \[rs]*[SN\-STYLE] . +. +The formatted number of the current heading is available in +.B \[rs]*[SN] +(a feature first documented by Berkeley); +this string facilitates its inclusion in, +for example, +table captions, +equation labels, +and +.BR .XS / .XA / .XE +table of contents entries. +. +. +.TP +.BR .SH \~[\c +.IR depth ] +Set an unnumbered heading. +. +The optional +.I depth +argument is a GNU extension indicating the heading depth corresponding +to the +.I depth +argument of +.BR .NH . +. +It matches the type size at which the heading is set to that of a +numbered heading at the same depth when the +.B \[rs]n[GROWPS] +and +.B \[rs]n[PSINCR] +heading size adjustment mechanism is in effect. +. +. +.P +The +.B PSINCR +register defines an increment in type size to be applied to a heading at +a lesser depth than that specified in +.BR \[rs]n[GROWPS] . +. +The value of +.B \[rs]n[PSINCR] +should be specified in points with the +.RB \[lq] p \[rq] +scaling unit and may include a fractional component. +. +. +.P +The +.B GROWPS +register defines the heading depth above which the type size increment +set by +.B \[rs]n[PSINCR] +becomes effective. +. +For each heading depth less than the value of +.BR \[rs]n[GROWPS] , +the type size is increased by +.BR \[rs]n[PSINCR] . +. +Setting +.B \[rs]n[GROWPS] +to a value less than\~2 disables the incremental heading size feature. +. +. +.P +In other words, +if the value of +.B GROWPS +register is greater than the +.I depth +argument to a +.B .NH +or +.B .SH +call, +the type size of a heading produced by these macros increases by +.B \[rs]n[PSINCR] +units over +.B \[rs]n[PS] +multiplied by the difference of +.B \[rs]n[GROWPS] +and +.IR depth . +. +. +.P +The +.B \[rs]n[HORPHANS] +register operates in conjunction with the +.B NH +and +.B SH +macros to inhibit the printing of isolated headings at the bottom of a +page; +it specifies the minimum number of lines of the subsequent paragraph +that must be kept on the same page as the heading. +. +If insufficient space remains on the current page to accommodate the +heading and this number of lines of paragraph text, +a page break is forced before the heading is printed. +. +Any display macro call or +.IR tbl , +.IR pic , +or +.I eqn +region between the heading and the subsequent paragraph suppresses this +grouping. +. +. +.\" ==================================================================== +.SS "Typeface and decoration" +.\" ==================================================================== +. +. +.P +The +.I ms +macros provide a variety of ways to style text. +. +Attend closely to the ordering of arguments labeled +.I pre +and +.I post, +which is not intuitive. +. +Support for +.I pre +arguments is a GNU extension. +. +. +.TP +.BR .B \~[\c +.IR text \~[ post \~[ pre ]]] +Style +.I text +in bold, +followed by +.I post +in the previous font style without intervening space, +and preceded by +.I pre +similarly. +. +Without arguments, +.I ms +styles subsequent text in bold +until the next +paragraphing, +heading, +or no-argument typeface macro call. +. +. +.TP +.BR .R \~[\c +.IR text \~[ post \~[ pre ]]] +As +.BR .B , +but use the roman style +(upright text of normal weight) +instead of bold. +. +Argument recognition is a GNU extension. +. +. +.TP +.BR .I \~[\c +.IR text \~[ post \~[ pre ]]] +As +.BR .B , +but use an italic or oblique style instead of bold. +. +. +.TP +.BR .BI \~[\c +.IR text \~[ post \~[ pre ]]] +As +.BR .B , +but use a bold italic or bold oblique style instead of upright bold. +. +This is a Tenth Edition Research Unix extension. +.\" possibly 9th, but definitely not Berkeley +. +. +.TP +.BR .CW \~[\c +.IR text \~[ post \~[ pre ]]] +As +.BR .B , +but use a constant-width (monospaced) roman typeface instead of bold. +. +This is a Tenth Edition Research Unix extension. +.\" possibly 9th, but definitely not Berkeley +. +. +.TP +.BR .BX \~[\c +.IR text ] +Typeset +.I text +and draw a box around it. +. +On terminal devices, +reverse video is used instead. +. +If you want +.I text +to contain space, +use unbreakable space or horizontal motion escape sequences +.RB ( \[rs]\[ti] , +.BI \[rs] space\c +, +.BR \[rs]\[ha] , +.BR \[rs]| , +.BR \[rs]0 , +or +.BR \[rs]h ). +. +. +.TP +.BR .UL \~[\c +.IR text \~[ post ]] +Typeset +.I text +with an underline. +. +.I post, +if present, +is set after +.I text +with no intervening space. +. +. +.TP +.B .LG +Set subsequent text in larger type +(2\~points larger than the current size) +until the next +type size, +paragraphing, +or heading macro call. +. +You can specify this macro multiple times to enlarge the type size as +needed. +. +. +.TP +.B .SM +Set subsequent text in smaller type +(2\~points smaller than the current size) +until the next +type size, +paragraphing, +or heading macro call. +. +You can specify this macro multiple times to reduce the type size as +needed. +. +. +.TP +.B .NL +Set subsequent text at the normal type size +.RB ( \[rs]n[PS] ). +. +. +.P +When +.I pre +is used, +a hyphenation control escape sequence +.B \[rs]% +that would ordinarily start +.I text +must start +.I pre +instead. +. +. +.P +.I groff ms +also offers strings to begin and end super- and subscripting. +. +These are GNU extensions. +. +. +.TP +.B \[rs]*{ +.TQ +.B \[rs]*} +Begin and end superscripting, +respectively. +. +. +.TP +.B \[rs]*< +.TQ +.B \[rs]*> +Begin and end subscripting, +respectively. +. +. +.\" ==================================================================== +.SS "Indented regions" +.\" ==================================================================== +. +You may need to indent a region of text while otherwise formatting it +normally. +. +Indented regions can be nested. +. +. +.TP +.B .RS +Begin a region where headings, +paragraphs, +and displays are indented (further) by +.BR \[rs]n[PI] . +. +. +.TP +.B .RE +End the (next) most recent indented region. +. +. +.\" ==================================================================== +.SS "Keeps, boxed keeps, and displays" +.\" ==================================================================== +. +On occasion, +you may want to +.I keep +several lines of text, +or a region of a document, +together on a single page, +preventing an automatic page break within certain boundaries. +. +This can cause a page break to occur earlier than it normally would. +. +. +.P +You can alternatively specify a +.I floating keep: +if a keep cannot fit on the current page, +.I ms +holds its contents and allows text following the keep +(in the source document) +to fill in the remainder of the current page. +. +When the page breaks, +whether by reaching the end or +.B bp +request, +.I ms +puts the floating keep at the beginning of the next page. +. +. +.TP +.B .KS +Begin a keep. +. +. +.TP +.B .KF +Begin a floating keep. +. +. +.TP +.B .KE +End (floating) keep. +. +. +.P +As an alternative to the keep mechanism, +the +.B ne +request forces a page break if there is not at least the amount of +vertical space specified in its argument remaining on the page. +. +. +.PP +A +.I boxed keep +has a frame drawn around it. +. +. +.TP +.B .B1 +Begin a keep with a box drawn around it. +. +. +.TP +.B .B2 +End boxed keep. +. +. +.P +Boxed keep macros cause breaks; +if you need to box a word or phrase within a line, +see the +.B BX +macro in section \[lq]Highlighting\[rq] above. +. +Box lines are drawn as close as possible to the text they enclose so +that they are usable within paragraphs. +. +If you wish to place one or more paragraphs in a boxed keep, +you may improve their appearance by calling +.B .B1 +after the first paragraphing macro, +and by adding a small amount of vertical space before calling +.BR .B2 . +. +. +.br +.ne 2v +.P +If you want a boxed keep to float, +you will need to enclose the +.B .B1 +and +.B .B2 +calls within a pair of +.B .KF +and +.B .KE +calls. +. +. +.P +.I Displays +turn off filling; +lines of verse or program code are shown with their lines broken as in +the source document without requiring +.B br +requests between lines. +. +Displays can be kept on a single page or allowed to break across pages. +. +The +.B DS +macro begins a kept display of the layout specified in its first +argument; +non-kept displays are begun with dedicated macros corresponding to their +layout. +. +. +.TP +.B .DS L +.TQ +.B .LD +Begin +.RB ( DS ": kept)" +left-aligned display. +. +. +.TP +.BR .DS \~\c +.RB [ I \~\c +.RI [ indent ]] +.TQ +.BR .ID \~\c +.RI [ indent ] +Begin +.RB ( DS ": kept)" +display indented by +.I indent +if specified, +.B \[rs]n[DI] +otherwise. +. +. +.TP +.B .DS B +.TQ +.B .BD +Begin +.RB ( DS ": kept)" +block display: +the entire display is left-aligned, +but indented such that the longest line in the display is centered on +the page. +. +. +.TP +.B .DS C +.TQ +.B .CD +Begin +.RB ( DS ": kept)" +centered display: +each line in the display is centered. +. +. +.TP +.B .DS R +.TQ +.B .RD +Begin +.RB ( DS ": kept)" +right-aligned display. +. +This is a GNU extension. +. +. +.TP +.B .DE +End any display. +. +. +.P +The distance stored in +.B \[rs]n[DD] +is inserted before and after each pair of display macros; +this is a Berkeley extension. +. +In +.IR "groff ms" , +this distance replaces any adjacent inter-paragraph distance +or subsequent spacing prior to a section heading. +. +The +.B DI +register is a GNU extension; +its value is an indentation applied to displays created with +.B .DS +and +.B .ID +without arguments, +to +.RB \[lq] .DS\~I \[rq] +without an indentation argument, +and to equations set with +.RB \[lq] .EQ\~I \[rq]. +. +Changes to either register take effect at the next display boundary. +. +. +.\" ==================================================================== +.SS "Tables, figures, equations, and references" +.\" ==================================================================== +. +The +.I ms +package is often used with the +.IR @g@tbl , +.IR @g@pic , +.IR @g@eqn , +and +.I @g@refer +preprocessors. +. +The +.B \[rs]n[DD] +distance is also applied to regions of the document preprocessed with +.IR @g@eqn , +.IR @g@pic , +and +.IR @g@tbl . +. +Mark text meant for preprocessors by enclosing it in pairs of tokens as +follows, +with nothing between the dot and the macro name. +. +The preprocessors match these tokens only at the start of an input line. +. +. +.TP +.BR .TS " [" H "] +.TQ +.B .TE +Demarcate a table to be processed by the +.I tbl +preprocessor. +. +The optional +.BR H "\~argument" +instructs +.I ms +to repeat table rows +(often column headings) +at the top of each new page the table spans, +if applicable; +calling the +.B TH +macro marks the end of such rows. +. +.MR @g@tbl @MAN1EXT@ +provides a comprehensive reference to the preprocessor and offers +examples of its use. +. +. +.TP +.B .PS +.TQ +.B .PE +.TQ +.B .PF +.B .PS +begins a picture to be processed by the +.I pic +preprocessor; +either of +.B .PE +or +.B .PF +ends it, +the latter with \[lq]flyback\[rq] to the vertical position at its top. +. +. +.TP +.BR .EQ \~[\c +.IR align \~[\c] +.IR label ]] +.TQ +.B .EN +Demarcate an equation to be processed by the +.I eqn +preprocessor. +. +The equation is centered by default; +.I align +can be +.BR C , +.BR L , +.RB or\~ I +to (explicitly) center, +left-align, +or indent it by +.BR \[rs]n[DI] , +respectively. +. +If specified, +.I label +is set right-aligned. +. +. +.TP +.B .[ +.TQ +.B .] +Demarcate a bibliographic citation to be processed by the +.I refer +preprocessor. +. +.MR @g@refer @MAN1EXT@ +provides a comprehensive reference to the preprocessor and the format of +its bibliographic database. +. +. +.P +When +.I @g@refer +emits collected references +(as might be done on a \[lq]Works Cited\[rq] page), +it interpolates the string +.B \[rs]*[REFERENCES] +as an unnumbered heading +.RB ( .SH ). +. +. +.br +.ne 2v +.P +Attempting to place a multi-page table inside a keep can lead to +unpleasant results, +particularly if the +.I tbl \" generic +.RB \[lq] allbox \[rq] +option is used. +. +. +.\" ==================================================================== +.SS Footnotes +.\" ==================================================================== +. +A footnote is typically anchored to a place in the text with a +.I marker, +which is a small integer, +a symbol, +or arbitrary user-specified text. +. +. +.TP +.B \[rs]** +Place an +.I automatic number, +an automatically generated numeric footnote marker, +in the text. +. +Each time this string is interpolated, +the number it produces increments by one. +. +Automatic numbers start at 1. +. +This is a Berkeley extension. +. +. +.P +Enclose the footnote text in +.B FS +and +.B FE +macro calls to set it at the nearest available \[lq]foot\[rq], +or bottom, +of a text column or page. +. +. +.TP +.BR .FS \~[\c +.IR marker ] +Begin a footnote. +. +The +.B .FS\-MARK +hook +(see below) +is called with any supplied +.I marker +argument, +which is then also placed at the beginning of the footnote text. +. +If +.I marker +is omitted, +the next pending automatic number enqueued by interpolation of the +.B * +string is used, +and if none exists, +nothing is prefixed. +. +. +.TP +.B .FE +End footnote text. +. +. +.P +.I groff ms +provides a hook macro, +.BR FS\-MARK , +for user-determined operations to be performed when the +.B FS +macro is called. +. +It is passed the same arguments as +.B .FS +itself. +. +By default, +this macro has an empty definition. +. +.B .FS\-MARK +is a GNU extension. +. +. +.P +Footnote text is formatted as paragraphs are, +using analogous parameters. +. +The registers +.BR FI , +.BR FPD , +.BR FPS , +and +.B FVS +correspond to +.BR PI , +.BR PD , +.BR PS , +and +.BR VS , +respectively; +.BR FPD , +.BR FPS , +and +.B FVS +are GNU extensions. +. +. +.P +The +.B FF +register controls the formatting of automatically numbered footnote +paragraphs, +and those for which +.B .FS +is given a +.I marker +argument, +at the bottom of a column or page as follows. +. +. +.RS +.TP +0 +Set an automatic number, +or a specified +.B FS +.I marker +argument, +as a superscript +(on typesetter devices) +or surrounded by square brackets +(on terminals). +. +The footnote paragraph is indented as with +.B .PP +if there is an +.B .FS +argument or an automatic number, +and as with +.B .LP +otherwise. +. +This is the default. +. +. +.TP +1 +As +.BR 0 , +but set the marker as regular text, +and follow an automatic number with a period. +. +. +.TP +2 +As +.BR 1 , +but without indentation +(like +.BR .LP ). +. +. +.TP +3 +As +.BR 1 , +but set the footnote paragraph with the marker hanging +(like +.BR .IP ). +.RE +. +. +.\" ==================================================================== +.SS "Language and localization" +.\" ==================================================================== +. +.I groff ms +provides several strings that you can customize for your own purposes, +or redefine to adapt the macro package to languages other than English. +. +It is already localized for +.\" cs, de, fr, it, sv +Czech, +German, +French, +Italian, +and +Swedish. +. +Load the desired localization macro package after +.IR ms ; +see +.MR groff_tmac @MAN5EXT@ . +. +. +.P +.RS +.TS +cb cb +lf(CR) lf(CR). +String Default +_ +\[rs]*[REFERENCES] References +\[rs]*[ABSTRACT] \[rs]f[I]ABSTRACT\[rs]f[] +\[rs]*[TOC] Table of Contents +\[rs]*[MONTH1] January +\[rs]*[MONTH2] February +\[rs]*[MONTH3] March +\[rs]*[MONTH4] April +\[rs]*[MONTH5] May +\[rs]*[MONTH6] June +\[rs]*[MONTH7] July +\[rs]*[MONTH8] August +\[rs]*[MONTH9] September +\[rs]*[MONTH10] October +\[rs]*[MONTH11] November +\[rs]*[MONTH12] December +_ +.TE +.RE +. +The default for +.B ABSTRACT +includes font selection escape sequences to set the word in italics. +. +. +.\" ==================================================================== +.SS "Headers and footers" +.\" ==================================================================== +. +There are multiple ways to produce headers and footers. +. +One is to define the strings +.BR LH , +.BR CH , +and +.B RH +to set the left, +center, +and right headers, +respectively; +and +.BR LF , +.BR CF , +and +.B RF +to set the left, +center, +and right footers. +. +This approach suffices for documents that do not distinguish odd- and +even-numbered pages. +. +. +.P +Another method is to call macros that set headers or footers for odd- or +even-numbered pages. +. +Each such macro takes a delimited argument separating the left, +center, +and right header or footer texts from each other. +. +You can replace the neutral apostrophes (\[aq]) shown below with any +character not appearing in the header or footer text. +. +These macros are Berkeley extensions. +. +. +.br +.ne 5v +.TP +.BR .OH \~\[aq]\c +.IR left \[aq] center \[aq] right \[aq] +.TQ +.BR .OF \~\[aq]\c +.IR left \[aq] center \[aq] right \[aq] +.TQ +.BR .EH \~\[aq]\c +.IR left \[aq] center \[aq] right \[aq] +.TQ +.BR .EF \~\[aq]\c +.IR left \[aq] center \[aq] right \[aq] +The +.B OH +and +.B EH +macros define headers for odd- (recto) and even-numbered (verso) pages, +respectively; +the +.B OF +and +.B EF +macros define footers for them. +. +. +.P +With either method, +a percent sign +.B % +in header or footer text is replaced by the current page number. +. +By default, +.I ms +places no header on a page numbered \[lq]1\[rq] +(regardless of its number format). +. +. +.TP +.B .P1 +Typeset the header even on page\~1. +. +To be effective, +this macro must be called before the header trap is sprung on any page +numbered \[lq]1\[rq]. +. +This is a Berkeley extension. +. +. +.P +For even greater flexibility, +.I ms +permits redefinition of the macros called when the page header and +footer traps are sprung. +. +.B PT +(\[lq]page trap\[rq]) +is called by +.I ms +when the header is to be written, +and +.B BT +(\[lq]bottom trap\[rq]) +when the footer is to be. +. +The +.I groff +page location trap that +.I ms +sets up to format the header also calls the +(normally undefined) +.B HD +macro after +.BR .PT ; +you can define +.B .HD +if you need additional processing after setting the header. +. +.\" Although undocumented in Tuthill's 4.2BSD ms.diffs paper... +The +.B HD +hook is a Berkeley extension. +. +Any such macros you (re)define must implement any desired specialization +for odd-, +even-, +or first numbered pages. +. +. +.\" ==================================================================== +.SS "Tab stops" +.\" ==================================================================== +. +Use the +.B ta +request to set tab stops as needed. +. +. +.TP +.B .TA +Reset the tab stops to the +.I ms +default +(every 5 ens). +. +Redefine this macro to create a different set of default tab stops. +. +. +.\" ==================================================================== +.SS Margins +.\" ==================================================================== +. +Control margins using the registers summarized in the \[lq]Margins\[rq] +portion of the table in section \[lq]Document control settings\[rq] +above. +. +There is no setting for the right margin; +the combination of page offset +.B \[rs]n[PO] +and line length +.B \[rs]n[LL] +determines it. +. +. +.\" ==================================================================== +.SS "Multiple columns" +.\" ==================================================================== +. +.I ms +can set text in as many columns as reasonably fit on the page. +. +The following macros force a page break if a multi-column layout is +active when they are called. +. +.B \[rs]n[MINGW] +is the default minimum gutter width; +it is a GNU extension. +. +When multiple columns are in use, +keeps +and the +.B \%HORPHANS +and +.B \%PORPHANS +registers +work with respect to column breaks instead of page breaks. +. +. +.TP +.B .1C +Arrange page text in a single column +(the default). +. +. +.TP +.B .2C +Arrange page text in two columns. +. +. +.TP +.BR .MC \~[\c +.IR column-width " [" gutter-width ]] +Arrange page text in multiple columns. +. +If you specify no arguments, +it is equivalent to the +.B 2C +macro. +. +Otherwise, +.I column-width +is the width of each column and +.I gutter-width +is the minimum distance between columns. +. +. +.\" ==================================================================== +.SS "Creating a table of contents" +.\" ==================================================================== +. +Define an entry to appear in the table of contents by bracketing its +text between calls to the +.B XS +and +.B XE +macros. +. +A typical application is to call them immediately after +.B NH +or +.B SH +and repeat the heading text within them. +. +The +.B XA +macro, +used within +.BR .XS / .XE +pairs, +supplements an entry\[em]for instance, +when it requires multiple output lines, +whether because a heading is too long to fit or because style dictates +that page numbers not be repeated. +. +You may wish to indent the text thus wrapped to correspond to its +heading depth; +this can be done in the entry text by prefixing it with tabs or +horizontal motion escape sequences, +or by providing a second argument to the +.B XA +macro. +. +.B .XS +and +.B .XA +automatically associate the page number where they are called with the +text following them, +but they accept arguments to override this behavior. +. +At the end of the document, +call +.B TC +or +.B PX +to emit the table of contents; +.B .TC +resets the page number +.RB to\~ i +(Roman numeral one), +and then calls +.BR PX . +. +All of these macros are Berkeley extensions. +. +. +.TP +.BR .XS \~[\c +.IR page-number ] +.TQ +.BR .XA \~[\c +.IR page-number \~[ indentation ]] +.TQ +.B .XE +Begin, +supplement, +and end a table of contents entry. +. +Each entry is associated with +.I page-number +(otherwise the current page number); +a +.I page-number +of +.RB \[lq] no \[rq] +prevents a leader and page number from being emitted for that entry. +. +Use of +.B .XA +within +.BR .XS / .XE +is optional; +it can be repeated. +. +If +.I indentation +is present, +a supplemental entry is indented by that amount; +ens are assumed if no unit is indicated. +. +Text on input lines between +.B .XS +and +.B .XE +is stored for later recall by +.BR .PX . +. +. +.TP +.BR .PX \~[ no ] +Switch to single-column layout. +. +Unless +.RB \[lq] no \[rq] +is specified, +center and interpolate +.B \[rs]*[TOC] +in bold and two points larger than the body text. +. +Emit the table of contents entries. +. +. +.TP +.BR .TC \~[ no ] +Set the page number to\~1, +the page number format to lowercase Roman numerals, +and call +.B PX +(with a +.RB \[lq] no \[rq] +argument, +if present). +. +. +.P +The remaining features in this subsection are GNU extensions. +. +.I groff ms +obviates the need to repeat heading text after +.B .XS +calls. +. +Call +.B .XN +and +.B .XH +after +.B .NH +and +.BR .SH , +respectively. +. +Text to be appended to the formatted section heading, +but not to appear in the table of contents entry, +can follow these calls. +. +. +.TP +.BI .XN\~ heading-text +Format +.I heading-text +and create a corresponding table of contents entry; +the indentation is computed from the +.I depth +argument of the preceding +.B NH +call. +. +. +.TP +.BI .XH\~ "depth heading-text" +As +.BR .XN , +but use +.I depth +to determine the indentation. +. +. +.P +.I groff ms +encourages customization of table of contents entry production. +. +(Re-)define any of the following macros as desired. +. +. +.TP +.BI \%.XN\-REPLACEMENT\~ heading-text +.TQ +.BI \%.XH\-REPLACEMENT\~ "depth heading-text" +These hook macros implement +.B .XN +and +.BR .XH , +and call +.B \%XN\-INIT +and +.BR \%XH\-INIT , +respectively, +then call +.B \%XH\-UPDATE\-TOC +with the arguments given them. +. +. +.TP +.B \%.XH\-INIT +.TQ +.B \%.XN\-INIT +These hook macros do nothing by default. +. +. +.TP +.BI \%.XH\-UPDATE\-TOC\~ "depth heading-text" +Bracket +.I heading-text +with +.B XS +and +.B XE +calls, +indenting it by 2 ens per level of +.I depth +beyond the first. +. +. +.P +You can customize the style of the leader that bridges each table of +contents entry with its page number; +define the +.B TC\-LEADER +special character by using the +.B char +request. +. +A typical leader combines the dot glyph +.RB \[lq] .\& \[rq] +with a horizontal motion escape sequence to spread the dots. +. +The width of the page number field is stored in the +.B TC\-MARGIN +register. +. +. +.\" ==================================================================== +.SH "Differences from AT&T \f[I]ms\f[]" +.\" ==================================================================== +. +The +.I groff ms +macros are an independent reimplementation, +using no AT&T code. +. +Since they take advantage of the extended features of +.IR groff , +they cannot be used with AT&T +.IR troff . +. +.I groff ms +supports features described above as Berkeley and Tenth Edition Research +Unix extensions, +and adds several of its own. +. +. +.IP \[bu] 3n +The internals of +.I groff ms +differ from the internals of AT&T +.IR ms . +. +Documents that depend upon implementation details of AT&T +.I ms +may not format properly with +.IR "groff ms" . +. +Such details include macros whose function was not documented in the +AT&T +.I ms +manual +(\[lq]Typing Documents on the UNIX System: Using the \-ms Macros with +Troff and Nroff\[rq], +M.\& E.\& Lesk, +Bell Laboratories, +1978). +.\" TODO: Use refer(1)? +.\" XXX: We support RT anyway; maybe we should stop? +. +. +.IP \[bu] +The error-handling policy of +.I groff ms +is to detect and report errors, +rather than to ignore them silently. +. +. +.IP \[bu] +Tenth Edition \" possibly 9th +Research Unix supported +.BR P1 / P2 +macros to bracket code examples; +.I groff ms +does not. +. +. +.IP \[bu] +.I groff ms +does not work in GNU +.IR troff 's \" GNU +AT&T compatibility mode. +. +If loaded when that mode is enabled, +it aborts processing with a diagnostic message. +. +. +.IP \[bu] +Multiple line spacing is not supported. +. +Use a larger vertical spacing instead. +. +. +.IP \[bu] +.I groff ms +uses the same header and footer defaults in both +.I nroff +and +.I troff +modes +as AT&T +.I ms +does in +.I troff +mode; +AT&T's default in +.I nroff +mode is to put the date, +in U.S.\& traditional format +(e.g., +\[lq]January 1, 2021\[rq]), +in the center footer +(the +.B CF +string). +. +. +.IP \[bu] +Many +.I groff ms +macros, +including those for paragraphs, +headings, +and displays, +cause a reset of paragraph rendering parameters, +and may change the indentation; +they do so not by incrementing or decrementing it, +but by setting it absolutely. +. +This can cause problems for documents that define additional macros of +their own that try to manipulate indentation. +. +Use +.B .RS +and +.B .RE +instead of the +.B in +request. +. +. +.IP \[bu] +AT&T +.I ms +interpreted the values of the registers +.B PS +and +.B VS +in points, +and did not support the use of scaling units with them. +. +.I groff ms +interprets values of the registers +.BR PS , +.BR VS , +.BR FPS , +and +.BR FVS , +equal to or larger than\~1,000 +(one thousand) +as decimal fractions multiplied by\~1,000. +. +(Register values are converted to and stored as basic +units. +. +See \[lq]Measurements\[rq] in the +.I groff +Texinfo manual or in +.MR groff @MAN7EXT@ ). +. +This threshold makes use of a scaling unit with these parameters +practical for high-resolution devices while preserving backward +compatibility. +. +It also permits expression of non-integral type sizes. +. +For example, +.RB \[lq] "groff \-rPS=10.5p" \[rq] +at the shell prompt is equivalent to placing +.RB \[lq] ".nr PS 10.5p" \[rq] +at the beginning of the document. +. +. +.IP \[bu] +AT&T +.IR ms 's +.B AU +macro supported arguments used with some document types; +.I groff ms +does not. +. +. +.IP \[bu] +Right-aligned displays are available. +. +The AT&T +.I ms +manual observes that \[lq]it is tempting to assume that +.RB \[lq] ".DS R" \[rq] +will right adjust lines, +but it doesn't work\[rq]. +. +In +.IR "groff ms" , +it does. +. +. +.IP \[bu] +To make +.I groff ms +use the default page offset +(which also specifies the left margin), +the +.B PO +register must stay undefined until the first +.I ms +macro is called. +. +This implies that +.B \[rs]n[PO] +should not be used early in the document, +unless it is changed also: +accessing an undefined register automatically defines it. +. +. +.IP \[bu] +.I groff ms +supports the +.B PN +register, +but it is not necessary; +you can access the page number via the usual +.B % +register and invoke the +.B af +request to assign a different format to it if desired. +. +(If you redefine the +.I ms +.B PT +macro \" I wouldn't mention that, but Lesk 1978 encourages doing so. :-/ +and desire special treatment of certain page numbers\[em]like +.RB \[lq] 1 \[rq]\[em]you +may need to handle a non-Arabic page number format, +as +.IR "groff ms" 's +.B .PT +does; +see the macro package source. +. +.I groff ms +aliases the +.B PN +register to +.BR % .) +. +. +.IP \[bu] +The AT&T +.I ms +manual documents registers +.B CW +and +.B GW +as setting the default column width and \[lq]intercolumn gap\[rq], +respectively, +and which applied when +.B .MC +was called with fewer than two arguments. +. +.I groff ms +instead treats +.B .MC +without arguments as synonymous with +.BR .2C ; +there is thus no occasion for a default column width register. +. +Further, +the +.B MINGW +register +and the second argument to +.B .MC +specify a +.I minimum +space between columns, +not the fixed gutter width of AT&T +.IR ms . +. +. +.IP \[bu] +The AT&T +.I ms +manual did not document the +.B QI +register; +Berkeley and +.I "groff ms" +do. +. +. +.IP \[bu] +The register +.B GS +is set to\~1 by the +.I groff ms +macros, +but is not used by the AT&T +.I ms +package. +. +Documents that need to determine whether they are being formatted with +.I groff ms +or another implementation should test this register. +. +. +.\" ==================================================================== +.SS "Unix Version\~7 macros not implemented by \f[I]groff ms\f[]" +.\" ==================================================================== +. +Several macros described in the Unix Version\~7 +.I ms +documentation are unimplemented by +.I groff ms +because they are specific to the requirements of documents produced +internally by Bell Laboratories, +some of which also require a glyph for the Bell System logo that +.I groff +does not support. +. +These macros implemented several document type formats +(\c +.BR EG , \" engineer's notes +.BR IM , \" internal memorandum +.BR MF , \" memorandum for file +.BR MR , \" memorandum for record +.BR TM , \" technical memorandum +.BR TR ), \" technical report +were meaningful only in conjunction with the use of certain document +types +(\c +.BR AT , \" attachments +.BR CS , \" cover sheet info for `TM` documents +.BR CT , \" copies to +.BR OK , \" "other keywords" for `TM` documents +.BR SG ), \" signatures for `TM` documents +stored the postal addresses of Bell Labs sites +(\c +.BR HO , \" Holmdel +.BR IH , \" Naperville +.BR MH , \" Murray Hill +.BR PY , \" Piscataway +.BR WH ), \" Whippany +or lacked a stable definition over time +(\c +.BR UX ). \" Unix; on 1st use, add footnote identifying trademark owner +. +. +.\" ==================================================================== +.SH "Legacy features" +.\" ==================================================================== +. +.I "groff ms" +retains some legacy features solely to support formatting of historical +documents; +contemporary ones should not use them because they can render poorly. +. +See +.MR groff_char @MAN7EXT@ +instead. +. +. +.\" ==================================================================== +.SS "AT&T \f[I]ms\f[] accent mark strings" +.\" ==================================================================== +. +AT&T +.I ms +defined +accent mark strings as follows. +. +. +.P +.TS +Cb Lb +Lf(CR) L. +String Description +_ +\[rs]*[\[aq]] Apply acute accent to subsequent glyph. +\[rs]*[\[ga]] Apply grave accent to subsequent glyph. +\[rs]*[:] Apply dieresis (umlaut) to subsequent glyph. +\[rs]*[\[ha]] Apply circumflex accent to subsequent glyph. +\[rs]*[\[ti]] Apply tilde accent to subsequent glyph. +\[rs]*[C] Apply caron to subsequent glyph. +.\" \*v was an undocumented (in Lesk 1978-11-13) synonym for \*C. +\[rs]*[,] Apply cedilla to subsequent glyph. +.TE +. +. +.\" ==================================================================== +.SS "Berkeley \f[I]ms\f[] accent mark and glyph strings" +.\" ==================================================================== +. +Berkeley +.I ms +offered an +.B AM +macro; +calling it redefined the AT&T accent mark strings +(except for +.BR \[rs]*C ), +applied them to the +.I preceding +glyph, +and defined additional strings, +some for spacing glyphs. +. +. +.TP +.B .AM +Enable alternative accent mark and glyph-producing strings. +. +. +.P +.TS +Cb Lb +Lf(CR) L. +String Description +_ +\[rs]*[\[aq]] Apply acute accent to preceding glyph. +\[rs]*[\[ga]] Apply grave accent to preceding glyph. +\[rs]*[:] Apply dieresis (umlaut) to preceding glyph. +\[rs]*[\[ha]] Apply circumflex accent to preceding glyph. +\[rs]*[\[ti]] Apply tilde accent to preceding glyph. +\[rs]*[,] Apply cedilla to preceding glyph. +\[rs]*[/] Apply stroke (slash) to preceding glyph. +\[rs]*[v] Apply caron to preceding glyph. +\[rs]*[_] Apply macron to preceding glyph. +\[rs]*[.] Apply underdot to preceding glyph. +\[rs]*[o] Apply ring accent to preceding glyph. +_ +\[rs]*[?] Interpolate inverted question mark. +\[rs]*[!] Interpolate inverted exclamation mark. +\[rs]*[8] Interpolate small letter sharp s. +\[rs]*[q] Interpolate small letter o with hook accent (ogonek). +\[rs]*[3] Interpolate small letter yogh. +\[rs]*[d-] Interpolate small letter eth. +\[rs]*[D-] Interpolate capital letter eth. +\[rs]*[th] Interpolate small letter thorn. +\[rs]*[TH] Interpolate capital letter thorn. +\[rs]*[ae] Interpolate small ae ligature. +\[rs]*[AE] Interpolate capital ae ligature. +\[rs]*[oe] Interpolate small oe ligature. +\[rs]*[OE] Interpolate capital oe ligature. +.TE +. +. +.\" ==================================================================== +.SH "Naming conventions" +.\" ==================================================================== +. +The following conventions are used for names of macros, +strings, +and registers. +. +External names available to documents that use the +.I groff ms +macros contain only uppercase letters and digits. +. +. +.LP +Internally, +the macros are divided into modules. +. +Conventions for identifier names are as follows. +. +.IP \[bu] 3n +Names used only within one module are of the form +.IB \%module * name\c +\&. +. +.IP \[bu] +Names used outside the module in which they are defined are of the form +.IB \%module @ name\c +\&. +. +.IP \[bu] +Names associated with a particular environment are of the form +.IB \%environment : name\c +\&; +these are used only within the +.B par +module. +. +.IP \[bu] +.I name +does not have a module prefix. +. +.IP \[bu] +Constructed names used to implement arrays are of the form +.IB \%array ! index\c +\&. +. +. +.PP +Thus the +.I groff ms +macros reserve the following names: +. +.IP \[bu] 3n +Names containing the characters +.BR * , +.BR @ , +and\~\c +.BR : . +. +.IP \[bu] +Names containing only uppercase letters and digits. +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.I @MACRODIR@/\:@TMAC_S_PREFIX@s\:.tmac +implements the package. +. +. +.TP +.I @MACRODIR@/refer\-ms.tmac +implements +.MR @g@refer @MAN1EXT@ +support for +.IR ms . +. +. +.TP +.I @MACRODIR@/\:ms\:.tmac +is a wrapper enabling the package to be loaded with +.RB \[lq] "groff \-m ms" \[rq]. +. +. +. +.\" ==================================================================== +.SH Authors +.\" ==================================================================== +. +The GNU version of the +.I ms +macro package was written by James Clark and contributors. +. +This document was written by Clark, +.MT lkollar@\:despammed\:.com +Larry Kollar +.ME , +and +.MT g.branden\:.robinson@\:gmail\:.com +G.\& Branden Robinson +.ME . +. +. +.br +.ne 8v +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +A manual is available in source and rendered form. +. +On your system, +it may be compressed and/or available in additional formats. +. +. +.TP +.I @DOCDIR@/\:ms\:.ms +.TQ +.I @DOCDIR@/\:ms\:.ps +\[lq]Using +.I groff +with the +.I ms +Macro Package\[rq]; +Larry Kollar and \%G.\~Branden Robinson. +. +. +.br +.ne 5v +.TP +.I @DOCDIR@/\:\%msboxes\:.ms +.TQ +.I @DOCDIR@/\:\%msboxes\:.pdf +\[lq]Using PDF boxes with +.I groff +and the +.I ms +macros\[rq]; +Deri James. +. +.B \%BOXSTART +and +.B \%BOXSTOP +macros are available via the +.I sboxes +extension package, +enabling colored, +bordered boxes when the +.B pdf +output device is used. +. +. +.PP +.IR "Groff: The GNU Implementation of troff" , +by Trent A.\& Fisher and Werner Lemberg, +is the primary +.I groff +manual. +. +You can browse it interactively with \[lq]info groff\[rq]. +. +. +.PP +.MR groff @MAN1EXT@ , +.MR @g@troff @MAN1EXT@ , +.MR @g@tbl @MAN1EXT@ , +.MR @g@pic @MAN1EXT@ , +.MR @g@eqn @MAN1EXT@ , +.MR @g@refer @MAN1EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_groff_ms_7_man_C] +.do rr *groff_groff_ms_7_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/groff_trace.7.man b/tmac/groff_trace.7.man new file mode 100644 index 0000000..63da8ab --- /dev/null +++ b/tmac/groff_trace.7.man @@ -0,0 +1,335 @@ +.TH groff_trace @MAN7EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +groff_trace \- macros for debugging GNU +.I roff +documents +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 2002-2022 Free Software Foundation, Inc. +.\" +.\" This file is part of groff, the GNU roff type-setting system. +.\" +.\" Permission is granted to copy, distribute and/or modify this +.\" document under the terms of the GNU Free Documentation License, +.\" Version 1.3 or any later version published by the Free Software +.\" Foundation; with no Invariant Sections, with no Front-Cover Texts, +.\" and with no Back-Cover Texts. +.\" +.\" A copy of the Free Documentation License is included as a file +.\" called FDL in the main directory of the groff source package. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_groff_trace_7_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY "groff \-m trace" +.RI [ option\~ .\|.\|.\&] +.RI [ file\~ .\|.\|.] +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I trace +is a macro package for the +.MR groff @MAN7EXT@ +document formatting system, +designed as an aid for debugging documents written in its language. +. +It issues a message to the standard error stream upon entry to and exit +from each macro call. +. +This can ease the process of isolating errors in macro definitions. +. +. +.P +Activate the package by specifying the command-line option +.RB \[lq] \-m\~trace \[rq] +to the formatter program +(often +.MR groff @MAN1EXT@ ). +. +You can achieve finer control by including the macro file within the +document; +invoke the +.B mso +request, +as in +.RB \[lq] .mso\~trace.tmac \[rq]. +. +Only macros that are defined after this invocation are traced. +. +If the +.B trace\-full +register is set to a true value, +as with the command-line option +.RB \[lq] \-r\~trace\-full=1 \[rq], +register and string assignments, +along with some other requests, +are traced also. +. +If another macro package should be traced as well, +specify it after +.RB \[lq] \-m\~trace \[rq] +on the command line. +. +. +.P +The macro file +.I trace.tmac +is unusual because it does not contain any macros to be called by a +user. +. +Instead, +.IR groff 's +macro definition and alteration facilities are wrapped such that they +display diagnostic messages. +. +. +.\" ==================================================================== +.SS Limitations +.\" ==================================================================== +. +Because +.I trace.tmac +wraps the +.B de +request +(and its cousins), +macro arguments are expanded one level more. +. +This causes problems if an argument uses four or more backslashes to +delay interpretation of an escape sequence. +. +For example, +the macro call +. +.RS +.EX +\&.foo \[rs]\[rs]\[rs]\[rs]n[bar] +.EE +.RE +. +normally passes \[lq]\[rs]\[rs]n[bar]\[rq] to macro \[lq]foo\[rq], +but with +.B de +redefined, +it passes \[lq]\[rs]n[bar]\[rq] instead. +. +. +.P +The solution to this problem is to use +.IR groff 's +.B \[rs]E +escape sequence, +an escape character that is not interpreted in copy mode. +. +.RS +.EX +\&.foo \[rs]En[bar] +.EE +.RE +. +. +.\" ==================================================================== +.SH Examples +.\" ==================================================================== +. +We will illustrate +.I trace.tmac +using the shell's \[lq]here document\[rq] feature to supply +.I groff +with a document +on the standard input stream. +. +Since we are interested only in diagnostic messages appearing on the +standard error stream, +we discard the formatted output by redirecting the standard output +stream to +.IR /dev/null . +. +. +.\" ==================================================================== +.SS "Observing nested macro calls" +.\" ==================================================================== +. +Macro calls can be nested, +even with themselves. +. +Tracing recurses along with them; +this feature can help to detangle complex call stacks. +. +. +.RS +.P +.EX +.RB $\~ "cat < /dev/null +.B .de countdown +.B . nop \[rs]\[rs]$1 +.B . nr count (\[rs]\[rs]$1 - 1) +.B . if \[rs]\[rs]n[count] .countdown \[rs]\[rs]n[count] +.B .. +.B .countdown 3 +.B blastoff +.B EOF +\~*** .de countdown +\~*** de trace enter: .countdown "3" +\~\~*** de trace enter: .countdown "2" +\~\~\~*** de trace enter: .countdown "1" +\~\~\~*** trace exit: .countdown "1" +\~\~*** trace exit: .countdown "2" +\~*** trace exit: .countdown "3" +.EE +.RE +. +. +.\" ==================================================================== +.SS "Tracing with the mso request" +.\" ==================================================================== +. +Now let us activate tracing within the document, +not with a command-line option. +. +We might do this when using a macro package like +.I ms +or +.IR mom , +where we may not want to be distracted by traces of macros we didn't +write. +. +. +.RS +.P +.EX +.RB $\~ "cat < /dev/null" +.B .LP +.B This is my introductory paragraph. +.B .mso trace.tmac +.B .de Mymac +.B .. +.B .Mymac +.B .PP +.B Let us review the existing literature. +.B EOF +\~*** .de Mymac +\~*** de trace enter: .Mymac +\~*** trace exit: .Mymac +.EE +.RE +. +. +.P +As tracing was not yet active when the macros \[lq]LP\[rq] and +\[lq]PP\[rq] were defined +(by +.IR s.tmac ), +their calls were not traced; +contrast with the macro \[lq]Mymac\[rq]. +. +. +.br +.ne 3v +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.I @MACRODIR@/\:trace\:.tmac +implements the package. +. +. +.\" ==================================================================== +.SH Authors +.\" ==================================================================== +. +.I trace.tmac +was written by James Clark. +. +This document was written by +.MT groff\-bernd\:.warken\-72@\:web\:.de +Bernd Warken +.ME +and +.MT g.branden\:.robinson@\:gmail\:.com +G.\& Branden Robinson +.ME . +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.IR "Groff: The GNU Implementation of troff" , +by Trent A.\& Fisher and Werner Lemberg, +is the primary +.I groff +manual. +. +You can browse it interactively with \[lq]info groff\[rq]. +. +. +.TP +.MR groff @MAN1EXT@ +gives an overview of the +.I groff +document formatting system. +. +. +.TP +.MR troff @MAN1EXT@ +supplies details of the +.B \-m +command-line option. +. +. +.TP +.MR groff_tmac @MAN5EXT@ +offers a survey of +.I groff +macro packages. +. +. +.TP +.MR groff @MAN7EXT@ +is a reference manual for the +.I groff +language. +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_groff_trace_7_man_C] +.do rr *groff_groff_trace_7_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/groff_www.7.man b/tmac/groff_www.7.man new file mode 100644 index 0000000..599c3b7 --- /dev/null +++ b/tmac/groff_www.7.man @@ -0,0 +1,760 @@ +.TH groff_www @MAN7EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +groff_www \- GNU +.I roff +macros for authoring web pages +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 2000-2020 Free Software Foundation, Inc. +.\" +.\" This file is part of groff, the GNU roff type-setting system. +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, but +.\" WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +.\" General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see +.\" . +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_groff_www_7_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY "groff \-m www" +.RI [ option\~ .\|.\|.\&] +.RI [ file\~ .\|.\|.] +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +This manual page describes the GNU +.I www +macro package, +which is part of the +.MR groff @MAN7EXT@ +document formatting system. +. +This macro file is automatically loaded by the default +.I troffrc +file when the formatter +(usually +.MR groff @MAN1EXT@ ) +is called with either of the options +.B \-Thtml +or +.BR \-Txhtml . +. +To see hyperlinks in action, +format this man page using one of those options. +. +. +.P +This document is a basic guide; +the HTML output driver +.RI ( \%grohtml ) +remains in an alpha state. +. +It has been included with the distribution to encourage testing. +. +. +.P +Here is a summary of the functions found in this macro set. +. +. +.P +.TS +tab(@); +l l. +\&.JOBNAME@split output into multiple files +\&.HX@automatic heading level cut off +\&.BCL@specify colours on a web page +\&.BGIMG@specify background image +\&.URL@create a URL using two parameters +\&.FTP@create an FTP reference +\&.MTO@create an HTML email address +\&.TAG@generate an HTML name +\&.IMG@include an image file +\&.PIMG@include PNG image +\&.MPIMG@place PNG on the margin and wrap text around it +\&.HnS@begin heading +\&.HnE@end heading +\&.LK@emit automatically collected links. +\&.HR@produce a horizontal rule +\&.NHR@suppress automatic generation of rules. +\&.HTL@only generate HTML title +\&.HEAD@add data to block +\&.ULS@unorder list begin +\&.ULE@unorder list end +\&.OLS@ordered list begin +\&.OLE@ordered list end +\&.DLS@definition list begin +\&.DLE@definition list end +\&.LI@insert a list item +\&.DC@generate a drop capital +\&.HTML@pass an HTML raw request to the device driver +\&.CDS@code example begin +\&.CDE@code example end +\&.ALN@place links on left of main text. +\&.LNS@start a new two-column table with links in the left. +\&.LNE@end the two-column table. +\&.LINKSTYLE@initialize default URL attributes. +.TE +. +. +.\" ==================================================================== +.SH Macros +.\" ==================================================================== +. +.TP +.B .JOBNAME filename +Split output into multiple HTML files. +. +A file is split whenever a \&.SH or \&.NH\ 1 is encountered. +. +Its argument is the file stem name for future output files. +. +This option is equivalent to +.IR \%grohtml 's +.B \-j +option. +. +.TP +.B .HX n +Specify the cut off depth when generating links from section headings. +. +For example, a parameter of\~2 would cause +.I \%grohtml +to generate a list of links for +.B .NH\ 1 +and +.B .NH\ 2 +but not for +.BR .NH\ 3 . +. +Whereas +. +. +.RS +.IP +.EX +\&.HX 0 +.EE +.RE +. +. +.IP +tells +.I \%grohtml +that no heading links should be created at all. +. +Another method for turning automatic headings off is by issuing the +command-line switch +.B \-P\-l +to +.IR groff . +. +. +.TP +.BI .BCL\~ "foreground background active not-visited visited" +This macro takes five parameters: +foreground, +background, +active hypertext link, +hypertext link not yet visited, +and visited hypertext link colour. +. +.TP +.B .BGIMG imagefile +the only parameter to this macro is the background image file. +. +.TP +.B .URL url [description] [after] +generates a URL using either one, +two, +or three arguments. +. +The first parameter is the actual URL, the second is the name of the +link, and the third is optional stuff to be printed immediately +afterwards. +. +If +.B description +and +.B after +are absent then the +.B URL +becomes the anchor text. +. +Hyphenation is disabled while printing the actual URL; +explicit breakpoints should be inserted with the +.B \[rs]: +escape sequence. +. +Here is how to encode +.UR http://\:foo\:.org/ +foo +.UE : +.RS +.IP +.B .URL http://\[rs]:foo\[rs]:.org/ "foo" : +.RE +. +.IP +If this is processed by a device other than +.B \-Thtml +or +.B \-Txhtml +it appears as: +.RS +.IP +foo \[la]\f[CR]http://\:foo\:.org\f[]\[ra]: +.RE +. +.IP +The URL macro can be of any type; +for example, we can reference +.UR pic\:.html +Eric Raymond's +.I pic +guide +.UE +by: +.RS +.IP +.B .URL pic\[rs]:.html \[dq]Eric Raymond\[aq]s pic guide\[dq] +.RE +. +.TP +.B .MTO address [description] [after] +Generate an email HTML reference. +. +The first argument is mandatory as the email address. +. +The optional second argument is the text you see in your browser. +. +If an empty argument is given, +.B address +is used instead. +. +An optional third argument is stuff printed immediately afterwards. +. +Hyphenation is disabled while printing the actual email address. +. +For example, +.MT joe@\:user\:.org +Joe User +.ME +can be achieved by the following macro: +.RS +.IP +.B .MTO joe@user.org \[dq]Joe User\[dq] +.RE +. +.IP +All URLs currently are treated as consuming no textual +space in +.IR groff . +. +This could be considered as a bug since it causes some problems. +. +To circumvent this, +.B www.tmac +inserts a zero-width character which expands to a harmless space (only +if run with +.B \-Thtml +or +.BR \-Txhtml ). +. +.TP +.B .FTP url [description] [after] +indicates that data can be obtained via FTP. +. +The first argument is the URL and the second is the browser text. +. +A third argument, similar to the macros above, is intended for stuff +printed immediately afterwards. +. +The second and the third parameter are optional. +. +Hyphenation is disabled while printing the actual URL. +. +As an example, here is the location of the +.UR ftp://\:ftp\:.gnu\:.org/ +GNU FTP server +.UE . +. +The macro example above can be specified as: +.RS +.IP +.B .FTP ftp://\[rs]:ftp\[rs]:.gnu\[rs]:.org/ \[dq]GNU FTP server\[dq] . +.RE +. +.TP +.B .TAG name +Generates an HTML name tag from its argument. +. +This can then be referenced using the +.UR #URL +URL +.UE +macro. +. +As you can see, you must precede the tag name with +.B # +since it is a local reference. +. +This link was achieved via placing a TAG in the URL description above; +the source looks like this: +. +. +.RS +.IP +.EX +\&.TP +\&.B URL +generates +\&.TAG URL +a URL using either two or three arguments. +\&.\|.\|. +.EE +.RE +. +. +.TP +.B .IMG [\-R|\-L|\-C] filename [width] [height] +Include a picture into the document. +. +The first argument is the horizontal location: right, left, or center +.RB ( \-R , +.BR \-L , +or +.BR \-C ). +. +Alignment is centered by default +.RB ( \-C ). +. +The second argument is the filename. +. +The optional third and fourth arguments are the width and height. +. +If the width is absent it defaults to 1\~inch. +. +If the height is absent it defaults to the width. +. +This maps onto an HTML img tag. +. +If you are including a PNG image then it is advisable to use the +.B PIMG +macro. +. +.TP +.B .PIMG [\-R|\-L|\-C] filename [width [height]] +Include an image in PNG format. +. +This macro takes exactly the same parameters as the +.B IMG +macro; it has the advantage of working with PostScript and HTML devices +also since it can automatically convert the image into the EPS format, +using the following programs of the +.B netpbm +package: +.BR pngtopnm , +.BR pnmcrop , +and +.BR pnmtops . +. +If the document isn't processed with +.B \-Thtml +or +.B \-Txhtml +it is necessary to use the +.B \-U +option of +.IR groff . +. +.TP +.B .MPIMG [\-R|\-L] [\-G gap] filename [width [height]] +Place a PNG image on the margin and wrap text around it. +. +The first parameters are optional. +. +The alignment: left or right +.RB ( \-L +or +.BR \-R ) +specifies the margin where the picture is placed at. +. +The default alignment is left +.RB ( \-L ). +. +Optionally, +.BI \-G \~gap +can be used to arrange a gap between the picture and the text that +wraps around it. +. +The default gap width is zero. +. +.br +The first non-optional argument is the filename. +. +The optional following arguments are the width and height. +. +If the width is absent it defaults to 1\~inch. +. +If the height is absent it defaults to the width. +. +Example: +. +. +.RS +.IP +.EX +\&.MPIMG \-L \-G 2c foo.png 3c 1.5c +.EE +.RE +. +. +.IP +The height and width may also be given as percentages. +. +The PostScript device calculates the width from the +.B .l +register and the height from the +.B .p +register. +. +For example: +. +. +.RS +.IP +.EX +\&.MPIMG \-L \-G 2c foo.png 15% +.EE +.RE +. +. +.TP +.B .HnS n +Begin heading. +. +The numeric heading level +.I n +is specified by the first parameter. +. +Use this macro if your headings contain URL, FTP or MTO macros. +. +Example: +. +. +.RS +.IP +.EX +\&.HnS 1 +\&.HR +GNU Troff +\&.URL https://\[rs]:www\[rs]:.gnu\[rs]:.org/\[rs]:software/\[rs]:groff/ +\&\[rs][em]a +\&.URL http://www\[rs]:.gnu\[rs]:.org/ GNU +\&project. +\&.HR +\&.HnE +.EE +.RE +. +. +.IP +In this case you might wish to disable automatic links to headings. +. +This can be done via +.B \-P\-l +from the command line. +.\" or by using a call to \[lq].HX 0\[rq]. +. +. +.TP +.B .HnE +End heading. +. +. +.TP +.B .LK +Force +.I \%grohtml +to place the automatically generated links at this position. +. +. +.TP +.B .HR +Generate a full-width horizontal rule for +.B \-Thtml +and +.BR \-Txhtml . +. +No effect for all other devices. +. +.TP +.B .NHR +Suppress generation of the top and bottom rules which +.I \%grohtml +emits by default. +. +.TP +.B .HTL +Generate an HTML title only. +. +This differs from the +.B TL +macro of the +.B ms +macro package which generates both an HTML title and an

heading. +. +Use it to provide an HTML title as search engine fodder but a graphic +title in the document. +. +The macro terminates when a space or break is seen (.sp, \&.br). +. +.TP +.B .HEAD +Add arbitrary HTML data to the block. +. +Ignored if not processed with +.B \-Thtml +or +.BR \-Txhtml . +. +Example: +. +. +.RS +.IP +.EX +\&.HEAD \[dq]\[dq] +.EE +.RE +. +. +.TP +.B .HTML +All text after this macro is treated as raw HTML. +. +If the document is processed without +.B \-Thtml +or +.B \-Txhtml +then the macro is ignored. +. +Internally, this macro is used as a building block for other +higher-level macros. +. +.IP +For example, the +.B BGIMG +macro is defined as +. +. +.RS +.IP +.EX +\&.de BGIMG +\&.\& HTML +\&.. +.EE +.RE +. +. +.TP +.B .DC l text [color] +Produce a drop capital. +. +The first parameter is the letter to be dropped and enlarged, the second +parameter +.B text +is the adjoining text whose height the first letter should not exceed. +. +The optional third parameter is the color of the dropped letter. +. +It defaults to black. +. +.TP +.B ".CDS" +Start displaying a code section in constant width font. +. +.TP +.B ".CDE" +End code display +. +.TP +.B ".ALN [color] [percentage]" +Place section heading links automatically to the left of the main text. +. +The color argument is optional and if present indicates which HTML +background color is to be used under the links. +. +The optional percentage indicates the amount of width to devote to +displaying the links. +. +The default values are #eeeeee and 30 for color and percentage width, +respectively. +. +This macro should only be called once at the beginning of the document. +. +After calling this macro each section heading emits an HTML table +consisting of the links in the left and the section text on the right. +. +.TP +.B ".LNS" +Start a new two-column table with links in the left column. +. +This can be called if the document has text before the first \&.SH and +if \&.ALN is used. +. +Typically this is called just before the first paragraph and after the +main title as it indicates that text after this point should be +positioned to the right of the left-hand navigational links. +. +.TP +.B ".LNE" +End a two-column table. +. +This should be called at the end of the document if \&.ALN was used. +. +.TP +.B ".LINKSTYLE color [ fontstyle [ openglyph closeglyph ] ]" +Initialize default URL attributes to be used if this macro set is not +used with the HTML device. +. +The macro set initializes itself with the following call +. +. +.RS +.IP +.EX +\&.LINKSTYLE blue CR \e[la] \e[ra] +.EE +.RE +. +. +.IP +but these values will be superseded by a user call to LINKSTYLE. +. +. +.\" ==================================================================== +.SH "Section heading links" +.\" ==================================================================== +. +By default +.I \%grohtml +generates links to all section headings and places these at the top of +the HTML document. +. +(See +.UR #LK +LINKS +.UE +for details of how to switch this off or alter the position). +. +. +.\" ==================================================================== +.SH "Limitations of \f[I]grohtml\f[]" +.\" ==================================================================== +. +.MR @g@tbl @MAN1EXT@ +tables are rendered as PNG images. +. +Paul DuBois's approach with +.MR tblcvt 1 , +part of the +.UR http://\:www\:.snake\:.net/\:software/\:troffcvt/ +.I troffcvt +distribution +.UE , +should be explored. +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.I @MACRODIR@/\:www\:.tmac +. +. +.\" ==================================================================== +.SH Authors +.\" ==================================================================== +. +The +.I www +macro package +was written by +.MT gaius@\:glam\:.ac\:.uk +Gaius Mulley +.ME , +with additions by +.MT wl@\:gnu\:.org +Werner Lemberg +.ME +and +.MT groff\-bernd\:.warken\-72@\:web\:.de +Bernd Warken +.ME . +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.MR groff @MAN1EXT@ , +.MR @g@troff @MAN1EXT@ , +.MR grohtml @MAN1EXT@ , +.MR netpbm 1 +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_groff_www_7_man_C] +.do rr *groff_groff_www_7_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/html-end.tmac b/tmac/html-end.tmac new file mode 100644 index 0000000..827d46c --- /dev/null +++ b/tmac/html-end.tmac @@ -0,0 +1,31 @@ +.\" -*- nroff -*- +.\" +.\" html-end.tmac +.\" +.do nr *groff_html-end_tmac_C \n[.cp] +.cp 0 +. +.\" turn off all headers and footers for ms, me, and mm macro sets +.if d EF .EF '''' +.if d EH .EH '''' +.if d OF .OF '''' +.if d OH .OH '''' +.if d ef .ef '''' +.if d of .of '''' +.if d oh .oh '''' +.if d eh .eh '''' +.tl '''' +. +.\" tell grohtml some default parameter values +.pl 99999i +.po 0 +.ll \n[.l]u +.ta \n[.tabs] +. +.cp \n[*groff_html-end_tmac_C] +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/html.tmac b/tmac/html.tmac new file mode 100644 index 0000000..887b288 --- /dev/null +++ b/tmac/html.tmac @@ -0,0 +1,550 @@ +.\" -*- nroff -*- +.\" +.\" html.tmac +.\" +.do nr *groff_html_tmac_C \n[.cp] +.cp 0 +. +.nroff +. +.ftr CW CR +.ftr C CR +.ftr CO CI +.ftr CX CBI +.ftr H HR +.ftr HO HI +.ftr HX HBI +.ftr NX NBI +. +.fchar \[fi] fi +.fchar \[fl] fl +.fchar \[ff] ff +.fchar \[Fi] ffi +.fchar \[Fl] ffl +. +.\" +.\" remove hyphenation +.\" +.nh +.nr HY 0 +. +.de hy +.. +.de nh +.. +. +.\" avoid line breaks after hyphen-like characters. +.cflags 0 -\[hy]\[em]\[en] +. +.\" Now set any characters defined in devps/S but not in devhtml to nul -- +.\" these are generated by eqn but not used by grohtml. grops generated +.\" images during the alternative pass. +.if !c\[radicalex] .tr \[radicalex] +.if !c\[arrowverttp] .tr \[arrowverttp] +.if !c\[arrowvertbt] .tr \[arrowvertbt] +.if !c\[arrowvertex] .tr \[arrowvertex] +.if !c\[barex] .tr \[barex] +.if !c\[sqrtex] .tr \[sqrtex] +. +.\" now for the color definitions +.\" +.\" html-4.0 colors +.\" +.defcolor white rgb #ffffff +.defcolor fuchsia rgb #ff00ff +. +.\" these colors are compliant with html-3.0 and above +.defcolor aliceblue rgb #eff7ff +.defcolor antiquewhite rgb #f9e8d2 +.defcolor antiquewhite1 rgb #feedd6 +.defcolor antiquewhite2 rgb #ebdbc5 +.defcolor antiquewhite3 rgb #c8b9a6 +.defcolor antiquewhite4 rgb #817468 +.defcolor aquamarine rgb #43b7ba +.defcolor aquamarine1 rgb #87fdce +.defcolor aquamarine2 rgb #7deabe +.defcolor aquamarine3 rgb #69c69f +.defcolor aquamarine4 rgb #417c64 +.defcolor azure rgb #efffff +.defcolor azure2 rgb #deecec +.defcolor azure3 rgb #bcc7c7 +.defcolor azure4 rgb #7a7d7d +.defcolor beige rgb #f5f3d7 +.defcolor bisque rgb #fde0bc +.defcolor bisque2 rgb #ead0ae +.defcolor bisque3 rgb #c7af92 +.defcolor bisque4 rgb #816e59 +.defcolor black rgb #000000 +.defcolor blanchedalmond rgb #fee8c6 +.defcolor blue rgb #0000ff +.defcolor blue1 rgb #1535ff +.defcolor blue2 rgb #1531ec +.defcolor blue3 rgb #1528c7 +.defcolor blue4 rgb #151b7e +.defcolor blueviolet rgb #7931df +.defcolor brown rgb #980517 +.defcolor brown1 rgb #f63526 +.defcolor brown2 rgb #e42d17 +.defcolor brown3 rgb #c22217 +.defcolor burlywood1 rgb #fcce8e +.defcolor burlywood2 rgb #eabe83 +.defcolor burlywood3 rgb #c6a06d +.defcolor burlywood4 rgb #806341 +.defcolor cadetblue rgb #578693 +.defcolor cadetblue1 rgb #99f3ff +.defcolor cadetblue2 rgb #8ee2ec +.defcolor cadetblue3 rgb #77bfc7 +.defcolor cadetblue4 rgb #4c787e +.defcolor chartreuse rgb #8afb17 +.defcolor chartreuse2 rgb #7fe817 +.defcolor chartreuse3 rgb #6cc417 +.defcolor chartreuse4 rgb #437c17 +.defcolor chocolate rgb #c85a17 +.defcolor coral rgb #f76541 +.defcolor coral2 rgb #e55b3c +.defcolor coral3 rgb #c34a2c +.defcolor coral4 rgb #7e2817 +.defcolor cornflowerblue rgb #151b8d +.defcolor cornsilk rgb #fff7d7 +.defcolor cornsilk2 rgb #ece5c6 +.defcolor cornsilk3 rgb #c8c2a7 +.defcolor cornsilk4 rgb #817a68 +.defcolor cyan rgb #00ffff +.defcolor cyan1 rgb #57feff +.defcolor cyan2 rgb #50ebec +.defcolor cyan3 rgb #46c7c7 +.defcolor cyan4 rgb #307d7e +.defcolor darkgoldenrod rgb #af7817 +.defcolor darkgoldenrod1 rgb #fbb117 +.defcolor darkgoldenrod2 rgb #e8a317 +.defcolor darkgoldenrod3 rgb #c58917 +.defcolor darkgoldenrod4 rgb #7f5217 +.defcolor darkgreen rgb #254117 +.defcolor darkkhaki rgb #b7ad59 +.defcolor darkolivegreen rgb #4a4117 +.defcolor darkolivegreen1 rgb #ccfb5d +.defcolor darkolivegreen2 rgb #bce954 +.defcolor darkolivegreen3 rgb #a0c544 +.defcolor darkolivegreen4 rgb #667c26 +.defcolor darkorange rgb #f88017 +.defcolor darkorange1 rgb #f87217 +.defcolor darkorange2 rgb #e56717 +.defcolor darkorange3 rgb #c35617 +.defcolor darkorange4 rgb #7e3117 +.defcolor darkorchid rgb #7d1b7e +.defcolor darkorchid1 rgb #b041ff +.defcolor darkorchid2 rgb #a23bec +.defcolor darkorchid3 rgb #8b31c7 +.defcolor darkorchid4 rgb #571b7e +.defcolor darksalmon rgb #e18b6b +.defcolor darkseagreen rgb #8bb381 +.defcolor darkseagreen1 rgb #c3fdb8 +.defcolor darkseagreen2 rgb #b5eaaa +.defcolor darkseagreen3 rgb #99c68e +.defcolor darkseagreen4 rgb #617c58 +.defcolor darkslateblue rgb #2b3856 +.defcolor darkslategray rgb #25383c +.defcolor darkslategray1 rgb #9afeff +.defcolor darkslategray2 rgb #8eebec +.defcolor darkslategray3 rgb #78c7c7 +.defcolor darkslategray4 rgb #4c7d7e +.defcolor darkturquoise rgb #3b9c9c +.defcolor darkviolet rgb #842dce +.defcolor deeppink rgb #f52887 +.defcolor deeppink2 rgb #e4287c +.defcolor deeppink3 rgb #c12267 +.defcolor deeppink4 rgb #7d053f +.defcolor deepskyblue rgb #3bb9ff +.defcolor deepskyblue2 rgb #38acec +.defcolor deepskyblue3 rgb #3090c7 +.defcolor deepskyblue4 rgb #25587e +.defcolor dimgray rgb #463e41 +.defcolor dodgerblue rgb #1589ff +.defcolor dodgerblue2 rgb #157dec +.defcolor dodgerblue3 rgb #1569c7 +.defcolor dodgerblue4 rgb #153e7e +.defcolor firebrick rgb #800517 +.defcolor firebrick1 rgb #f62817 +.defcolor firebrick2 rgb #e42217 +.defcolor firebrick3 rgb #c11b17 +.defcolor floralwhite rgb #fff9ee +.defcolor forestgreen rgb #4e9258 +.defcolor gainsboro rgb #d8d9d7 +.defcolor ghostwhite rgb #f7f7ff +.defcolor gold rgb #d4a017 +.defcolor gold1 rgb #fdd017 +.defcolor gold2 rgb #eac117 +.defcolor gold3 rgb #c7a317 +.defcolor gold4 rgb #806517 +.defcolor goldenrod rgb #edda74 +.defcolor goldenrod1 rgb #fbb917 +.defcolor goldenrod2 rgb #e9ab17 +.defcolor goldenrod3 rgb #c68e17 +.defcolor goldenrod4 rgb #805817 +.defcolor gray rgb #736f6e +.defcolor gray0 rgb #150517 +.defcolor gray100 rgb #ffffff +.defcolor gray18 rgb #250517 +.defcolor gray21 rgb #2b1b17 +.defcolor gray23 rgb #302217 +.defcolor gray24 rgb #302226 +.defcolor gray25 rgb #342826 +.defcolor gray26 rgb #34282c +.defcolor gray27 rgb #382d2c +.defcolor gray28 rgb #3b3131 +.defcolor gray29 rgb #3e3535 +.defcolor gray30 rgb #413839 +.defcolor gray31 rgb #41383c +.defcolor gray32 rgb #463e3f +.defcolor gray34 rgb #4a4344 +.defcolor gray35 rgb #4c4646 +.defcolor gray36 rgb #4e4848 +.defcolor gray37 rgb #504a4b +.defcolor gray38 rgb #544e4f +.defcolor gray39 rgb #565051 +.defcolor gray40 rgb #595454 +.defcolor gray41 rgb #5c5858 +.defcolor gray42 rgb #5f5a59 +.defcolor gray43 rgb #625d5d +.defcolor gray44 rgb #646060 +.defcolor gray45 rgb #666362 +.defcolor gray46 rgb #696565 +.defcolor gray47 rgb #6d6968 +.defcolor gray48 rgb #6e6a6b +.defcolor gray49 rgb #726e6d +.defcolor gray50 rgb #747170 +.defcolor gray51 rgb #787473 +.defcolor gray52 rgb #7a7777 +.defcolor gray53 rgb #7c7979 +.defcolor gray54 rgb #807d7c +.defcolor gray55 rgb #82807e +.defcolor gray56 rgb #858381 +.defcolor gray57 rgb #878583 +.defcolor gray58 rgb #8b8987 +.defcolor gray59 rgb #8d8b89 +.defcolor gray60 rgb #8f8e8d +.defcolor gray61 rgb #939190 +.defcolor gray62 rgb #959492 +.defcolor gray63 rgb #999795 +.defcolor gray64 rgb #9a9998 +.defcolor gray65 rgb #9e9c9b +.defcolor gray66 rgb #a09f9d +.defcolor gray67 rgb #a3a2a0 +.defcolor gray68 rgb #a5a4a3 +.defcolor gray69 rgb #a9a8a6 +.defcolor gray70 rgb #acaba9 +.defcolor gray71 rgb #aeadac +.defcolor gray72 rgb #b1b1af +.defcolor gray73 rgb #b3b3b1 +.defcolor gray74 rgb #b7b6b4 +.defcolor gray75 rgb #b9b8b6 +.defcolor gray76 rgb #bcbbba +.defcolor gray77 rgb #bebebc +.defcolor gray78 rgb #c1c1bf +.defcolor gray79 rgb #c3c4c2 +.defcolor gray80 rgb #c7c7c5 +.defcolor gray81 rgb #cacac9 +.defcolor gray82 rgb #cccccb +.defcolor gray83 rgb #d0cfcf +.defcolor gray84 rgb #d2d2d1 +.defcolor gray85 rgb #d5d5d4 +.defcolor gray86 rgb #d7d7d7 +.defcolor gray87 rgb #dbdbd9 +.defcolor gray88 rgb #dddddc +.defcolor gray89 rgb #e0e0e0 +.defcolor gray90 rgb #e2e3e1 +.defcolor gray91 rgb #e5e6e4 +.defcolor gray92 rgb #e8e9e8 +.defcolor gray93 rgb #ebebea +.defcolor gray94 rgb #eeeeee +.defcolor gray95 rgb #f0f1f0 +.defcolor gray96 rgb #f4f4f3 +.defcolor gray97 rgb #f6f6f5 +.defcolor gray98 rgb #f9f9fa +.defcolor gray99 rgb #fbfbfb +.defcolor green rgb #00ff00 +.defcolor green1 rgb #5ffb17 +.defcolor green2 rgb #59e817 +.defcolor green3 rgb #4cc417 +.defcolor green4 rgb #347c17 +.defcolor greenyellow rgb #b1fb17 +.defcolor honeydew rgb #f0feee +.defcolor honeydew2 rgb #deebdc +.defcolor honeydew3 rgb #bcc7b9 +.defcolor honeydew4 rgb #7a7d74 +.defcolor hotpink rgb #f660ab +.defcolor hotpink1 rgb #f665ab +.defcolor hotpink2 rgb #e45e9d +.defcolor hotpink3 rgb #c25283 +.defcolor hotpink4 rgb #7d2252 +.defcolor indianred rgb #5e2217 +.defcolor indianred1 rgb #f75d59 +.defcolor indianred2 rgb #e55451 +.defcolor indianred3 rgb #c24641 +.defcolor indianred4 rgb #7e2217 +.defcolor ivory rgb #ffffee +.defcolor ivory2 rgb #ececdc +.defcolor ivory3 rgb #c9c7b9 +.defcolor ivory4 rgb #817d74 +.defcolor khaki rgb #ada96e +.defcolor khaki1 rgb #fff380 +.defcolor khaki2 rgb #ede275 +.defcolor khaki3 rgb #c9be62 +.defcolor khaki4 rgb #827839 +.defcolor lavender rgb #e3e4fa +.defcolor lavenderblush rgb #fdeef4 +.defcolor lavenderblush2 rgb #ebdde2 +.defcolor lavenderblush3 rgb #c8bbbe +.defcolor lavenderblush4 rgb #817679 +.defcolor lawngreen rgb #87f717 +.defcolor lemonchiffon rgb #fff8c6 +.defcolor lemonchiffon2 rgb #ece5b6 +.defcolor lemonchiffon3 rgb #c9c299 +.defcolor lemonchiffon4 rgb #827b60 +.defcolor lightblue rgb #addfff +.defcolor lightblue1 rgb #bdedff +.defcolor lightblue2 rgb #afdcec +.defcolor lightblue3 rgb #95b9c7 +.defcolor lightblue4 rgb #5e767e +.defcolor lightcoral rgb #e77471 +.defcolor lightcyan rgb #e0ffff +.defcolor lightcyan2 rgb #cfecec +.defcolor lightcyan3 rgb #afc7c7 +.defcolor lightcyan4 rgb #717d7d +.defcolor lightgoldenrod rgb #ecd872 +.defcolor lightgoldenrod1 rgb #ffe87c +.defcolor lightgoldenrod2 rgb #ecd672 +.defcolor lightgoldenrod3 rgb #c8b560 +.defcolor lightgoldenrod4 rgb #817339 +.defcolor lightgoldenrodyellow rgb #faf8cc +.defcolor lightpink rgb #faafba +.defcolor lightpink1 rgb #f9a7b0 +.defcolor lightpink2 rgb #e799a3 +.defcolor lightpink3 rgb #c48189 +.defcolor lightpink4 rgb #7f4e52 +.defcolor lightsalmon rgb #f9966b +.defcolor lightsalmon2 rgb #e78a61 +.defcolor lightsalmon3 rgb #c47451 +.defcolor lightsalmon4 rgb #7f462c +.defcolor lightseagreen rgb #3ea99f +.defcolor lightskyblue rgb #82cafa +.defcolor lightskyblue2 rgb #a0cfec +.defcolor lightskyblue3 rgb #87afc7 +.defcolor lightskyblue4 rgb #566d7e +.defcolor lightslateblue rgb #736aff +.defcolor lightslategray rgb #6d7b8d +.defcolor lightsteelblue rgb #728fce +.defcolor lightsteelblue1 rgb #c6deff +.defcolor lightsteelblue2 rgb #b7ceec +.defcolor lightsteelblue3 rgb #9aadc7 +.defcolor lightsteelblue4 rgb #646d7e +.defcolor lightyellow rgb #fffedc +.defcolor lightyellow2 rgb #edebcb +.defcolor lightyellow3 rgb #c9c7aa +.defcolor lightyellow4 rgb #827d6b +.defcolor limegreen rgb #41a317 +.defcolor linen rgb #f9eee2 +.defcolor magenta rgb #ff00ff +.defcolor magenta1 rgb #f43eff +.defcolor magenta2 rgb #e238ec +.defcolor magenta3 rgb #c031c7 +.defcolor maroon rgb #810541 +.defcolor maroon1 rgb #f535aa +.defcolor maroon2 rgb #e3319d +.defcolor maroon3 rgb #c12283 +.defcolor maroon4 rgb #7d0552 +.defcolor mediumaquamarine rgb #348781 +.defcolor mediumblue rgb #152dc6 +.defcolor mediumforestgreen rgb #347235 +.defcolor mediumgoldenrod rgb #ccb954 +.defcolor mediumorchid rgb #b048b5 +.defcolor mediumorchid1 rgb #d462ff +.defcolor mediumorchid2 rgb #c45aec +.defcolor mediumorchid3 rgb #a74ac7 +.defcolor mediumorchid4 rgb #6a287e +.defcolor mediumpurple rgb #8467d7 +.defcolor mediumpurple1 rgb #9e7bff +.defcolor mediumpurple2 rgb #9172ec +.defcolor mediumpurple3 rgb #7a5dc7 +.defcolor mediumpurple4 rgb #4e387e +.defcolor mediumseagreen rgb #306754 +.defcolor mediumslateblue rgb #5e5a80 +.defcolor mediumspringgreen rgb #348017 +.defcolor mediumturquoise rgb #48cccd +.defcolor mediumvioletred rgb #ca226b +.defcolor midnightblue rgb #151b54 +.defcolor mintcream rgb #f5fff9 +.defcolor mistyrose rgb #fde1dd +.defcolor mistyrose2 rgb #ead0cc +.defcolor mistyrose3 rgb #c6afac +.defcolor mistyrose4 rgb #806f6c +.defcolor moccasin rgb #fde0ac +.defcolor navajowhite rgb #fddaa3 +.defcolor navajowhite2 rgb #eac995 +.defcolor navajowhite3 rgb #c7aa7d +.defcolor navajowhite4 rgb #806a4b +.defcolor navy rgb #150567 +.defcolor oldlace rgb #fcf3e2 +.defcolor olivedrab rgb #658017 +.defcolor olivedrab1 rgb #c3fb17 +.defcolor olivedrab2 rgb #b5e917 +.defcolor olivedrab3 rgb #99c517 +.defcolor olivedrab4 rgb #617c17 +.defcolor orange rgb #f87a17 +.defcolor orange1 rgb #fa9b17 +.defcolor orange2 rgb #e78e17 +.defcolor orange3 rgb #c57717 +.defcolor orange4 rgb #7f4817 +.defcolor orangered rgb #f63817 +.defcolor orangered2 rgb #e43117 +.defcolor orangered3 rgb #c22817 +.defcolor orangered4 rgb #7e0517 +.defcolor orchid rgb #e57ded +.defcolor orchid1 rgb #f67dfa +.defcolor orchid2 rgb #e473e7 +.defcolor orchid3 rgb #c160c3 +.defcolor orchid4 rgb #7d387c +.defcolor palegoldenrod rgb #ede49e +.defcolor palegreen rgb #79d867 +.defcolor palegreen1 rgb #a0fc8d +.defcolor palegreen2 rgb #94e981 +.defcolor palegreen3 rgb #7dc56c +.defcolor palegreen4 rgb #4e7c41 +.defcolor paleturquoise rgb #aeebec +.defcolor paleturquoise1 rgb #bcfeff +.defcolor paleturquoise2 rgb #adebec +.defcolor paleturquoise3 rgb #92c7c7 +.defcolor paleturquoise4 rgb #5e7d7e +.defcolor palevioletred rgb #d16587 +.defcolor palevioletred1 rgb #f778a1 +.defcolor palevioletred2 rgb #e56e94 +.defcolor palevioletred3 rgb #c25a7c +.defcolor palevioletred4 rgb #7e354d +.defcolor papayawhip rgb #feeccf +.defcolor peachpuff rgb #fcd5b0 +.defcolor peachpuff2 rgb #eac5a3 +.defcolor peachpuff3 rgb #c6a688 +.defcolor peachpuff4 rgb #806752 +.defcolor peru rgb #c57726 +.defcolor pink rgb #faafbe +.defcolor pink2 rgb #e7a1b0 +.defcolor pink3 rgb #c48793 +.defcolor pink4 rgb #7f525d +.defcolor plum rgb #b93b8f +.defcolor plum1 rgb #f9b7ff +.defcolor plum2 rgb #e6a9ec +.defcolor plum3 rgb #c38ec7 +.defcolor plum4 rgb #7e587e +.defcolor powderblue rgb #addce3 +.defcolor purple rgb #8e35ef +.defcolor purple1 rgb #893bff +.defcolor purple2 rgb #7f38ec +.defcolor purple3 rgb #6c2dc7 +.defcolor purple4 rgb #461b7e +.defcolor red rgb #ff0000 +.defcolor red1 rgb #f62217 +.defcolor red2 rgb #e41b17 +.defcolor rosybrown rgb #b38481 +.defcolor rosybrown1 rgb #fbbbb9 +.defcolor rosybrown2 rgb #e8adaa +.defcolor rosybrown3 rgb #c5908e +.defcolor rosybrown4 rgb #7f5a58 +.defcolor royalblue rgb #2b60de +.defcolor royalblue1 rgb #306eff +.defcolor royalblue2 rgb #2b65ec +.defcolor royalblue3 rgb #2554c7 +.defcolor royalblue4 rgb #15317e +.defcolor salmon1 rgb #f88158 +.defcolor salmon2 rgb #e67451 +.defcolor salmon3 rgb #c36241 +.defcolor salmon4 rgb #7e3817 +.defcolor sandybrown rgb #ee9a4d +.defcolor seagreen rgb #4e8975 +.defcolor seagreen1 rgb #6afb92 +.defcolor seagreen2 rgb #64e986 +.defcolor seagreen3 rgb #54c571 +.defcolor seagreen4 rgb #387c44 +.defcolor seashell rgb #fef3eb +.defcolor seashell2 rgb #ebe2d9 +.defcolor seashell3 rgb #c8bfb6 +.defcolor seashell4 rgb #817873 +.defcolor sienna rgb #8a4117 +.defcolor sienna1 rgb #f87431 +.defcolor sienna2 rgb #e66c2c +.defcolor sienna3 rgb #c35817 +.defcolor sienna4 rgb #7e3517 +.defcolor skyblue rgb #6698ff +.defcolor skyblue1 rgb #82caff +.defcolor skyblue2 rgb #79baec +.defcolor skyblue3 rgb #659ec7 +.defcolor skyblue4 rgb #41627e +.defcolor slateblue rgb #737ca1 +.defcolor slateblue1 rgb #7369ff +.defcolor slateblue2 rgb #6960ec +.defcolor slateblue3 rgb #574ec7 +.defcolor slateblue4 rgb #342d7e +.defcolor slategray rgb #657383 +.defcolor slategray1 rgb #c2dfff +.defcolor slategray2 rgb #b4cfec +.defcolor slategray3 rgb #98afc7 +.defcolor slategray4 rgb #616d7e +.defcolor snow rgb #fff9fa +.defcolor snow2 rgb #ece7e6 +.defcolor snow3 rgb #c8c4c2 +.defcolor snow4 rgb #817c7b +.defcolor springgreen rgb #4aa02c +.defcolor springgreen1 rgb #5efb6e +.defcolor springgreen2 rgb #57e964 +.defcolor springgreen3 rgb #4cc552 +.defcolor springgreen4 rgb #347c2c +.defcolor steelblue rgb #4863a0 +.defcolor steelblue1 rgb #5cb3ff +.defcolor steelblue2 rgb #56a5ec +.defcolor steelblue3 rgb #488ac7 +.defcolor steelblue4 rgb #2b547e +.defcolor tan rgb #d8af79 +.defcolor tan1 rgb #fa9b3c +.defcolor tan2 rgb #e78e35 +.defcolor thistle rgb #d2b9d3 +.defcolor thistle1 rgb #fcdfff +.defcolor thistle2 rgb #e9cfec +.defcolor thistle3 rgb #c6aec7 +.defcolor thistle4 rgb #806d7e +.defcolor tomato rgb #f75431 +.defcolor tomato2 rgb #e54c2c +.defcolor tomato3 rgb #c23e17 +.defcolor turquoise rgb #43c6db +.defcolor turquoise1 rgb #52f3ff +.defcolor turquoise2 rgb #4ee2ec +.defcolor turquoise3 rgb #43bfc7 +.defcolor turquoise4 rgb #30787e +.defcolor violet rgb #8d38c9 +.defcolor violetred rgb #e9358a +.defcolor violetred1 rgb #f6358a +.defcolor violetred2 rgb #e4317f +.defcolor violetred3 rgb #c12869 +.defcolor violetred4 rgb #7d0541 +.defcolor wheat rgb #f3daa9 +.defcolor wheat1 rgb #fee4b1 +.defcolor wheat2 rgb #ebd3a3 +.defcolor wheat3 rgb #c8b189 +.defcolor wheat4 rgb #816f54 +.defcolor yellow rgb #ffff00 +.defcolor yellow1 rgb #fffc17 +.defcolor yellowgreen rgb #52d017 +. +.mso www.tmac +. +.ie '\[char97]'a' \ +. mso latin1.tmac +.el \ +. mso cp1047.tmac +. +.cp \n[*groff_html_tmac_C] +.do rr *groff_html_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/hyphen.cs b/tmac/hyphen.cs new file mode 100644 index 0000000..c1a91d4 --- /dev/null +++ b/tmac/hyphen.cs @@ -0,0 +1,3672 @@ +% This is the groff hyphenation pattern file 'hyphen.cs' for Czech. +% +% It is based on the TeX pattern file 'czhyphen.tex', version 3 (1995), +% prepared by Pavel Ševeček . +% +% Here is the copyright message: +% +% This is free software; you can redistribute it and/or modify it +% under the terms of the GNU General Public License as published by +% the Free Software Foundation; either version 2 of the License, or +% (at your option) any later version. +% +% This file is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program; if not, write to the Free Software +% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +% 02110-1301 USA. +% +% Please check the original file for more details. +% +% It has been made suitable for groff by expanding all macros to real +% characters in latin-2 encoding. +% +\patterns{ +.a2 +.a4da +.a4de +.a4di +.a4do +.a4dé +.a4kl +.a4ko +.a4kr +.a4ku +.ale3x +.a4ra +.a4re +.a4ri +.a4ro +.a4ry +.a4rá +.a4sa +.a4se +.a4so +.as3t3 +.a4sy +.a4ta +.a4te +.at3l +.a4to +.a4tr +.a4ty +.a4ve +.b2 +.c2 +.ch2 +.cyk3 +.d2 +.dez3 +.d4na +.dne4 +.dneš4k +.d4ny +.dos4 +.d4ve +.d4vě +.d4ví +.e2 +.e4ch +.e4ko +.es3k +.es3t +.e4ve +.f4ri +.g2 +.h2 +.h4le +.h4ne +.i2 +.i4na +.i4ni +.i4no +.is3l +.j2 +.j4ak +.je4dl +.j4se +.j4zd +.jád4 +.k2 +.k4li +.k4ly +.kří3d +.l2 +.le4gr +.li3kv +.m2 +.mi3st4 +.moud3 +.na3č4 +.ne3c +.neč4 +.ne3š +.ni2t +.no4s3t +.n4vp +.ná1 +.nář4k +.o2 +.o4bé +.ode3 +.od3l +.od3rá +.o4ka +.o4ko +.o4na +.o4ne +.o4ni +.o4no +.o4nu +.o4ny +.o4ně +.o4ní +.o4pe +.o4po +.o4se +.o4sl +.os4to +.os3t3r +.os4tě +.ot3rá +.ot3v +.o4tí +.o4tř +.ově4t +.o4za +.oz3do +.o4zi +.o4zo +.o4zu +.o4šk +.o4šl +.o4ži +.p2 +.pa4re +.pa3tř +.polk4l +.po3č4 +.p4ro +.p4rý +.p4se +.pu3b +.r2 +.rej4 +.re3s +.ro4k +.roze3 +.roz3r +.ru4dl +.s2 +.s4ch +.s4ci +.sem4 +.se3pn +.s4ke +.sk4l +.s4ká +.s4le +.s4na +.s4ny +.s4pe +.s4po +.st2 +.s4tá +.s4ži +.t2 +.u2 +.u4ba +.u4be +.u4bi +.u4bo +.u4de +.u4di +.u4do +.u4du +.u4dí +.uh4n +.uj4m +.u4ko +.u4ku +.ul4h +.u4ma +.u4me +.u4mi +.u4mu +.u4ne +.u4ni +.u4pa +.u4pe +.u4pi +.up4n +.u4po +.u4pu +.u4pá +.u4pě +.u4pí +.u4ra +.u4ro +.u4rá +.us2 +.u4so +.u4st +.u4sy +.u4sí +.ut2 +.u4vi +.u4ze +.u4če +.u4či +.u4čí +.u4še +.u4ši +.u4šk +.uš4t +.u4ší +.u4ži +.už4n +.u4žo +.u4ží +.v2 +.va4dl +.v4po +.vy3 +.v4zá +.vý1 +.v4ži +.y4or +.y4ve +.z2 +.za3 +.zao3s +.zar2 +.zač2 +.zd2 +.z4di +.z4dr +.z4ky +.z4mn +.z4no +.z4nu +.z4ně +.z4ní +.z4pe +.z4po +.z4tř +.z4ve +.z4vi +.č2 +.č4te +.é2 +.í2 +.ó2 +.š2 +.še3t +.š4ka +.š4ke +.š4ky +.š4ťo +.š4ťá +.ú2 +.ú4dů +.ž2 +a1 +2a. +aa3t2 +ab3lon +ab4lý +ab3ri +ab4sb +ab2st +ac4ci +a2d +a3da +a3de +a3di +ad2la +a4dli +a4dlá +a4dlé +ad4me +ad4mu +a3do +ado4s +a3d3ra +ad3ri +a3drž +a3du +a4duž +3a3dva +ad3vo +a3dy +a3dá +a3dé +a3dě +a3dí +ad4úz +ad4úř +a3dů +a3dý +ae4vi +afi2a +a2g +a3ga +ag4fa +a3go +ag3ro +a3gu +a3gá +ah4li +ah3v +a2i +a3in +ai4re +a3iv +a2jd +a2jm +aj4me +aj2o +a2k +a3ke +a3ki +a3kl +ak4ni +a3ko +a3kr +a3ku +a3ky +a3ká +a3ké +a3kó +a3ků +a3ký +al4fb +al4kl +al4tz +al3ží +am4bd +am4kl +am4nu +amo3s +am4ži +a4nae +a4name +an4dt +ane4sk +aneu4 +an4sc +an4sg +an4sl +an4sm +an2sp +an4sv +an4tč +an4žh +ao4ed +ao4hm +ao4stř +ao4tč +ap4r. +a4pso +ap3t +a4př. +a2r +a3ra +ar4dw +a3re +a4rer +ar4gl +a3ri +ar4kh +a3ro +a4rox +ar3st +a3ru +ar2va +a3ry +a3rá +a3ró +ar3š2 +ar4šr +a3rů +arůs3 +a3rý +a2s +a3sa +a3se +a3sh +a3sin +as3ná +a3so +as3pi +as4tat +a4stk +as4tm +a4stru. +as3tv +a3su +a3sv +a3sy +a3sá +a3sé +a3sí +a3sů +a2t +a3ta +at4ch +a3te +a3ti +a4tio +at4kl +at3lo +a3to +a3tr +at3re +at3ron +at3rov +a4tru +at4rá +at4th +a3tu +a3tv +a3ty +a3tá +a3té +a3tě +a3tí +a3tó +at1ř +a4tří. +a3tů +a3tý +a2u +au4gs +a3uj +auj4m +aus3t +a3uč +2av +av3d +av4d. +av3lo +a4vlu +a4vlí +av3t +av4ti +2ay +ay4on +az3k +az3la +az4lé +az3ni +a3zp +a2č +a3ča +a3če +a3či +a3čl +ač4má +a3čo +a3ču +a3čá +a3čí +a3čů +a2ň +a3ňo +a3ňu +aře4k +a3ří +a4špl +a4špy +a2ť +aú3t +2b. +3ba. +ba4br +ba4chr +ba3ka +ba4se +2b1c +b1d +be4ef +be4et +bej4m +be3p +beu4r +be2z3 +beze3 +b1h +1bi +bi2b3 +bis3 +bist4 +bi4tr +b1j +2bk +3bl. +bl4bl +b2lem +b2les +3blk +b4lán +b2lém +b1m +2bn +1bo +bo4et +bo4jm +bo4ok +bo4tr +bou3s +bo4šk +b2ral +b2ran +2bri +b4rodit +b4rou +broz4 +b2ru +b3ru. +b3rub +b2rán +2b1s2 +bs3tr +2b1t +btáh4 +bu2c +bu4en +3by. +bys3 +by4sm +by4tč +by4zn +b2z +1bá +2b1č +bé4rc +1bě. +bě3ta +1bí +3bín +bí4rc +2bň +b3řa +b3ře. +bře4s +b1ří +2bš2 +2c. +1ca +cad4l +ca4es +2cc +1ce +cech4 +ced4l +celo3 +ce4ns +ce4ov +ce4ps +cer4v +ce2u +2ch. +1cha +4chalg +3che +4che. +2chl +ch4ly +ch4mb +2ch3n +2cht +4chte +1chu +ch4u. +1chy +1chá +2chř +1ci +cien4c +cik4l +2ck2 +c4ket +ckte4rý +2cl +c3la +c3lé +2cn +1co +co4at +co4mm +co4žp +c2p +2ct +c2ti +ctis4 +ct4la +ct2n +c3tv +c2tě +cuk1 +1c2v +cy2 +1cá +1cí +cí4pl +2cň +1ců +2d. +1da +da3d +da4jš +da4kl +da4tr +d1b +d2ba +4dbat. +d2bá +2d1c +dch4l +3dch4n +d1d +dd4ha +1de +de4bre +de3hn +de3jd +dej4mo +de3kl +de3kv +de2na +de2oz +de3sl +de4sm +de4so +de2sp +des4t +de3str +de1x +de4xt +de2z +de3zn +dez3o +de3čt +de4žp +2d1h +1di +di4gg +4dind +dis3k +di4so +d1j +dj4us +2dk +d3kv +3dl. +d1la +d4lab +d4lak +d3li +1dln +d2lou +d3lou. +d2lu +d3luč +d4láž +d1lé +2d1lí +d2lů +d1m +1dmd +dmýš4 +2dn +1do +4dobl +4doboj +dob4rat +do3by +do3bě +do3bý +do1d +4do4dd +4do4dj +dod4n +do3h +doj4m +4dokn +4doly +do3mn +domoh4 +do3p +do4pc +dop4n +dor2v +do1s +dos4p +dos4tiv +do3t +do3uk +do3uč +do3z2 +doz4n +do3č +4do4čn +doč4t +do4žp +4dran +d4rap +d1re +d4ren +3drobn +d3ros +d3rou +d3roš +dr4sc +d3ruš +d3ré +d3rý +d4rýv +2d1s2 +ds4ků +ds4po +d1t +d3tl +d3tř +1du +dum3ř +du3na +du3p +du4pn +2dur +du3si +du4í. +d2v +d4vac +d3ve +d3vl +d3vr +d3vy +d3vá +d3vě +d3ví +1dy +dy4su +d3zb +d3zd +d3zn +1dá +2d1č +1dé +1dě +3děj +1dí +2dň +d1řa +dře4k +d4řep +dře4pn +d4řev +d1ří +d2řít +2dš2 +d3šk +d3št +1dů +3dů. +dů3s +1dý +d2ž2 +2e. +e1a +ea3dr +e2ar +e1b +eb4er +ebez2 +eb4li +e2bř +e4ch. +e3chl. +e4chm +e3cho +e2chr +e3chv +e4chť +ed4be +ed4kv +ed1l +ed2ma +e3dmn +ed3v +ed4ří +e1e +ee4th +ee3xi +eg4gi +e1ha +e1he +ehno4 +eh4ně +e1ho +e1hr +e1hu +e1hy +e1há +e1hý +e1i +eilus3 +ej3ag +e3jas +e1je +e3jed +ej3ele +e3jez +ej3in +e3jis +ej1m +ej3mo +e3jmu +ej1o +ej1u +eju3st +ej3v +e2k +e3ka +e3ke +e4kly +e3ko +e3kr +e3ku +e3ky +e3ká +e3ké +e3kó +e3kř +e3ků +e1la +e4lau +el4dv +e1le +e1lo +e1lu +e1ly +el4ze +e1lá +e1lé +e1lí +e1ml +e4mlí +emo3k +e1mr +e1my +e3má +e1mě +e1mí +e3mř +e3mů +e1mý +em3že +en4dv +enitos4 +en4sc +en4si +ent3r +e1o +eo3by +eoch3r +eod3l +eo4du +e4ole +eo1s +eo2st +eo4tř +eo3z +eo4zb +eo4zd +eoše3 +epa3t +e2pl +e4pni +ep2no +e4pný +epoč3t +epro4zř +ep4tl +ep4tm +ep4tn +e4ptu +epy3 +2er +e1ra +er4a. +e1re +e1ri +e1ro +er3s +er4s. +er4sn +e1ru +e1ry +e1rá +e1ré +e1rů +e1rý +e1s +e4sag +e2sce +e4sin +esi4s +e2sk +es4k. +e4s4kn +es3ku. +es3ky +es3ké +e2sl +e4s3li +e4sly +es2m +e4sp. +es4pe +e2st +e4st. +e4ste +es3tiž +es4tol +e4strou +es3tán +e1t +e4tki +e4tkr +e4tli +e4tly +et3ri +et3ro +et3rů +et1ř +et4ún +e1u +eu3b +eu3ct +eu3d +eu3k +eu3m +eu4m. +eu3n +eu3p +eu3r +eu4r. +e4ura +eu4ras +eu4rg +eu3s2 +eu3t +e4u4t. +eu4tra +eu4ts +eu3v +eu3z +eu3ž +e3vd +eve4š +e3v2k +e4vsk +evy3 +evyjad4 +evypá4t +evy4čk +evě4tr +ex4ta +e3xu +ey4or +ey4ov +ezaos3 +ez4ap +ez4bo +ez3de +ez3dov +ez3du +ez4dě +e3ze +ez4ed2 +ez4ej +ez4el +ez4er +ez4es +ez4ez +ez4eš +ezis4 +ez4it +ez4le +ez4ná +ez4ně +ez4py +ez2t +ez4ác +ez4áh +ez4če +e3zí +e3zř +ez4ře +e1á +eč4kat +e1čt +eč4te +e4čti +e4čtí +e2ň +e3ňo +e3ňu +e3ňá +e3ón +e1ř +eře4k +eř4ku +e3ří +e2š +e3še +e3ši +e4ška +e3šl +eš4lá +e3šo +eš4to +eštíh4 +e3ší +eú1 +eúmy4 +eú3n +eú3p +eú3t +eú3č +ežíš4 +1f +2f. +fe4in +fene4 +fe4ue +fi4em +fi4fl +f2l +f3lí +fló4r +fm4no +2fn +2fr +f4ran +f4ras +3frek +f1ri +2fs +fs4te +2ft +fu4ch +2fé +f2ú +1g +2g. +ga4uč +ge2s +ghou4 +3gic +3gin +gi4ím +g4lom +2g1m +2gn +g4noi +g4nos +go1 +go4hm +3graf +gu4el +gu4it +gu3m +gu4m. +gus4t +gu3v +2h. +ha4ag +ha4ar +ha4bl +ha4br +ha3dl +ha4dla +ha4ke +has3t +hatos4 +ha4yd +h2b +h2c +2hd +he4br +he4id +hej4s +he2s +he2u +he3x +hi4an +hi3er +hi4gh +hi4re +2hk +4hla. +h4led +h3len +2hli +4h3lo. +h3lob +h3lop +h3lov +h3luj +2h1ly +4hlá. +h4lás +h3lí. +4hlík +2hlý +h2m +2h2n +h3ne +h4ned +h3niv +h4noj +3hněd +3hodin +ho3str +hos4tě +4hove +4hovna +4hovny +4hovná +4hovně +h2r +hra4p +2h1t +h4tin +h2tě +h4tít +hu4ch +hu3mo +hu4tň +2h2v +hyd1 +hy4do +hy4ps +hys3 +hy2t3r +hy4zd +h1č +2hň +hř2 +hř4by +hý4bl +h2ž +2i. +i1a +ia3d +ia3g2 +i4al. +ias4t +ia4tr +i1b +ib2l +i2b1r +i1ch +i4chž +i1d +id4ge +id2l +id4lo. +i4dlý +i1em +i1en +i1et +if1r +ig4ne +i1h +i2hl +i3hl. +i4hli +ih3n +ih4na +i3im +i1j +ijed4 +ij4me +ij4mi +i2kl +ik3le +ik3lo. +ik3m +ik4ry +i4kve +ik4úř +i1l +il4ba +ilič4n +i4lnu +ilu3 +i1m +i4mla +i4mly +i4mun +i2n +i3na +ina3d +in4cm +in4dl +i3ne +3infe +in4gh +in4gp +in4gs +in4gt +i3ni +i3no +i3nu +i3ny +i3ná +i3né +i3ně +i3ní +in4šp +i3nů +i3ný +i1o +io4sk +i2ps +i1r +iro4s +i1sa +is3c +is4ch +is4k. +is3ka +is3ke +is3ko. +is3kr +is3ku +is3kv +is3ky +i3slav +is3lo +is3lé +is3pl +is3po +is1t +is4tal +is4tat +is4th +ist3v +is3tí +i1sy +i3sá +i1t +it1r +it4rh +it4rp +it4se +it4su +i2tv +i1um +iv3d +i1x +ix4td +i3zp +iz1r +i1á +i1čl +ič3t +ič4tl +ič4to +i2ď +i1é +ié4re. +i1íc +i1ím +i1ó +i1ř +iř4kl +iř4če +i2š +i3še +i3ši +iš3k +iš4kr +iš4kv +i3šo +iš4to +i3šu +i3šá +i3ší +i2ž +i3ža +i3že +i3ži +i3žo +i3žu +i3žá +2j. +ja2b2 +jac4k +ja4cq +ja3d +ja3g +j3akt +j1b2 +jbyst3 +2j1c +j2d +j3dob +j3dok +j3dos +j3dr +j3dá +jd4ří +j3dů +jech4 +j3ef +j3ex +jez3dí +jg4ra +2j1h +1ji +ji4ch +jih3l +ji4mž +j4ina +jis3k +jit4ro +ji2zv +j1j +2jk +j3kv +2j1l +j2m +j3ma +j3mi +jmou3d +2jmí +2jn +jne3 +j1ob +j1od +jod2ř +j1oh +j1op +j4ora +j1os +jo3sv +j2ov +j3ovl +j1o3z2 +2jp +jpor4 +jpo4zv +jpříz4 +2j1r +2j1s2 +j4sem +j4si. +j4sk. +js4ko +js4ká +j4s4ků +j4s4me +j3sn +j4sou. +j4souc +js4po +j4s4te +2j1t +j3tl +ju4an +ju3na +ju3p +j1us +ju3sp +ju3t +ju4t. +ju3v +ju4xt +ju3z +j1už +ju3ži +2jv2 +j3vd +j3vn +2jz +j3zb +j3zd +j3zk +j3zn +j3zp +jád2r +2j1č +2jď +1jí +j3št +jš4ti +j3šť +2jú1 +jú3n +jú3č +jú3ž +2jž +1k +2k. +ka4bl +ka4ch +ka3dl +3kaj +ka3ka +3kami +3kaně +ka2p3l +ka2p3r +ka2ps +ka4pv +ka2př +kas3t +kast3r +3kat +ka4uč +3kav +3kač +3kař +kaš3l +ka4šp +2k1c +k2d +k2e +ke4bl +ke3jo +ke4pr +ke4ps +3ket +2kf +2kk +k2l +3kl. +4k3la. +k3lej +4k3li. +k4lib +k3lic +4klička +4klo. +k3los +2k3ly +k3lá. +k3lé +k3ló +k3lý +2k2m +k3mě +2kn +kna4s +ko3by +3kof +ko4jm +ko2př +ko4sk +ko2t3v +kous3k +3kov +ko3zá +4kroa +k3rob +k3rof +kr2s +kr4ú. +2ks +2k1t +kt2r +kuch4 +ku4fř +ku4hr +3kuj +ku3se +ku3si +ku3su +ku4th +ku3v +2k2v +k4vrň +3kyn +ky2pr +kyp3ř +ky4zn +3kác +ká4pl +3kár +3kář +2kč +k2ň +k2ř2 +k3řej +kš4ti +3ků. +2l. +1la. +la4br +lab4s +la3ka +la4nq +la4ps +4la3si +la4vš +la4y. +la2zm +2l1b +2l1c +2l1d +ld4ne +le4ad +le4au +lech3t +leh3n +le2i +1lej +le3jo +4lejšk +1lel +4lench +lepa3d +lepo4s +le4pr +le4ps +le4sc +le4sm +le4sv +let4li +let3m +le2tr +le4tč +le4uk +le4vh +le4vk +le3xi +lez3n +2lf +2lg +2lh +3lhan +1li +li4az +li4bl +li4bv +li4dm +lind4 +3lio +li4tň +li4vr +2liž +2lj +2lk +l4kat +l2kl +lk4nu +2ll +2l1m +2ln +l4nul +lo3br +lo4id +lo4is +1los +lo3sp +lo3stř +lo3sv +lo2tr +lo4tř +lo4u. +lo3z +loz4d +lo4šk +2lp +l2pě +2l1s2 +l4sla +ls3n +lst4n +l4stí +2l1t +lt4ra +lt4ru +lt4ry +lu4id +lu4j. +lu4k. +lu4lk +lu4m. +lu4mn +lu3pr +lu3va +lu3vl +lu3vy +lu3ví +2lv +2lz +1lá. +lá4jš +lá4vš +2l1č +1lé. +1lík +lí4pl +lí4zn +1líř +2lň +2lš2 +l3št +l4štý +1lů +1lý +lý2t +2l2ž +2m. +1ma +maj4s +ma4kl +ma4kr +4mald +mas3k +mat3r +ma4tra +ma4vš +maz3l +2m1b +2m1c +2m1d2 +m2dl +1me +3me. +me4go +me4is +met3re +me3x +mezi3s +2mf +mh4le +1mi +mid3l +mik3r +mi4xt +2mk2 +3m2kl +mk4la +mk4li +m2l +4mla. +2mle +ml3h +ml4h. +2mli +ml4sc +ml4sk +4mlu. +2mn +m3na +mna4s +m4noh +m3nos +m4noz +3množ +m3ná +m3né +m4néz +m3něj +m3ný +1mo +mod3r +mo2hl +mo2k +mo2s +mo4s. +mot3ř +4mout +moza4 +mo3zř +moú3 +2mp +m4plo +mpo4s +m2ps +mp4se +mp2t +mr2s +2m1s2 +m4stl +2m1t +1mu +mu4fl +mu3n +mu4n. +mu4nd +mu4nn +mu4ns +mu4nš +2muš +2mv +mys3lo +my4šk +2mz +3má. +málo3 +má2s +2mč +m2če +mí1c +mí4rň +2m2š +mš4či +mš3ť +mš4ťan. +3mů. +3mý. +m2ž +1n +2n. +3na. +na3ch +na4do +na4em +na3h +na4h. +na3jd +na3ka +nam4ne +na3p2 +na3s2 +na4s. +nat2 +na3tl +na3tř +na3z +naz4k +na4zš +na4č. +na3š +naž4n +2nb +2n1c +n4chc +2n1d +nd4hi +ndo4t +nd2re +nd4ri +nd4ří +ne1d +ne4gl +ne1h +ne3h4n +ne2j +nej3t +nej3u +ne3kl +ne4kro +ne3kv +ne4m. +ne3p +ne3s2 +ne4s. +nes4le +ne4ss +4nesti +ne3tl +net4r +ne3ud +ne3v2 +ne4v. +ne3z +nez4n +ne3šk +ne3šť +2nf +n3fr +2ng +ng1l +ng4la +ng4le +ng4lí +n4gro +ng4vi +nik4t +ni4mr +ni4mž +3nio +3nisk +2nitř +n1j +2nk +2n1l +2nn +no3b2 +no4bs +no3hn +no4hs +no4ir +no4mž +no4sky +no3sm +no3str +not4r +no3z +no4zd +no4šk +2nož +2n1s2 +n2sa +ns3ak +ns4ko +n4soc +ns3po +nst4ra +2n1t +nte4r3a +nt4lem +nt4r. +nt3ru +nt3rá +2nub +nu4gg +3ny. +2nz +3nák +ná3s2 +ná4s. +2n1č +2nď +2nív +2níž +2nó +2nš2 +n3št +nš4ťo +nů2 +2nž +2o. +o1a +oang4 +o1ba +o1be +obe3j +obe3s +obe3z +ob1l +ob1r +ob4rň +o1bu +obys4 +ob3z +o3bé +ob3řez +o1c +o4chl +o2chr +oc4ke +oc4ko +o4ct. +oct3n +ocy3 +oc4ún +od3b +odej4m +ode3p +ode3s +od1l +o4doc +odos4 +odo4tk +od3ra +od4ran +od3rů +o3drž +od3v +od1ř +o1e2 +oe3g +oe3ti +o2fl +ofrek4 +og2 +o3gn +o1h +oh4ne +o1i +oi4ce +o4int +o1j +o4jar +oje4dl +o4jmi +o4jmov +o4jmu +o4jmů +oj2o +o4juz +2oka +ok2te +o1l +ol4gl +ol4to +o1m +om4kl +om2n +o2n +o3na +ona4s +o3ne +o3ni +o3no +ont4ra +o3nu +o3ny +o3ná +onář4ka +o3ně +o3ní +o3nů +o3ný +o1o +oo4hř +oote2 +opoč3t +opro4s +o2ps +o4ptu +opá4t +o4př. +opřej4 +opře4jm +o1ra +o4rae +or4dm +o1re +o1ri +o1ro +or3st +o1ru +or4vá +o1ry +o1rá +o3ré +o1rů +orůs3 +o3rý +o1sa +o4sai +ose4s +osi4d +o1sk +o4s3ke +o4sku +osk3v +o4ská +o4ský +o1sl +os4la +os4li +os4lý +os3mo +os4mu +o4st. +o4stg +o4stm +os4tor +os3trů +o4sté +o4stš +o4stý +o1sy +o1t +ot4kl +o4tlý +oto3s +ot3ro +ot3ví +o3tí +o3tř +ot3ři +o2u +ou3bě +ou3dě +ou4fl +ou4il +ou4is +ou4k. +ou3ka +o4ukl +ou3kr +ou3ká +ou3m +oup3n +oupo4 +ou4s. +ou3sa +ou3se +ou4sk +ou3sm +ou4tv +ou3v +ou4vl +ou4vn +ouz3d +o4učk +ou3ži +ovi4dla +o4vsk +ovy2p +o2všt +o1x +o2z +o3za +oz1b +oz4d. +oz3dá +oz3dě +oz3dí +o3ze +oze3d2 +ozer4 +oz1h +o3zi +oz3j +oz3k +oz4ko +oz1l +oz3m +o4zn. +o3zo +oz3p +oz4py +oz4pě +oz4pí +oz3ro +oz3ru +oz3rů +oz3t +o3zu +o4zut +oz3vr +oz3vá +o3zí +o3zů +ozů4s +o1č +oč2k +oč4ka +o2ň +o3ňa +o3ňo +o1ř +oři2s +o3šk +o4šku +o4šky +o3šl +oš4lá +oš4mo +oš4ti +oš4ťu +o3žl +ož4mo +1p +2p. +pa4ed +pa4es +pa4kl +pa3si +pa4t. +pat4ri +2p1c +pe4al +pede4 +pe4ig +pe4np +peri3 +pes3t3 +pe4tra +3peč +pi4kr +pi4pl +2pk +p2kl +p2l +3pl. +4p3la. +pl3h +pl4h. +4p3li. +4plo. +2pn +p2nu +po1b2 +po3c2 +3pod +podbě4h +pod4nes +po3dru +po3drá +po3h +poly3 +po3m2 +po4mp +po4ol +po3p +po4p. +po4pm +po1s2 +pos4p +post4r +po3t2 +po4t. +po4tn +po3uk +po3uč +po3už +3po3v +po3z2 +po4zd +poč2 +po3čk +poč3te +po3ří +po4šv +2pp +4pra. +pra3st +pr2c +pro1 +prob2 +pro3p +pro3t4 +pro3z +pr2s +4prán +prů3 +pse4s +2p1sk +p4sut +2pt +p4tej +p4ter +p4tev +pt4ri +p3tu +p4tá. +pu4dl +pu4tr +pyt3l +pá1 +pá2c +pád3l +pá4nv +pá4sl +2pč +pé4rh +2př. +pře3h +pře3j +pře3t4 +pře3z +pře3č2 +při3 +přih4 +2pš +pš4ti +2pť +qu2 +2r. +1ra. +ra4br +ra4em +ra4es +ra4ff +ra4hl +ra4hm +ra4jg +ra4jš +2rak +ra4nh +ra3si +rast4r +ra4vv +ra4wl +ra4y. +ra4yo +ra4ďm +4raži +r1b +r2bl +r1c +rca3 +r3cha +r3cho +rc4ki +r1d +r4dla +rdo2s +re4ad +re4au +red4r +re4et +re3kl +re3kvi +re4mr +re2sb +res3l +retis4 +ret4r +re4um +r1ha +r3hl. +rh3n +r1ho +r3hu +r1há +ri4bb +1ric +ric4ku +ri4dg +ri4dr +ri4fl +ri4gh +ri4zm +2rk +r2kl +r1l +2r1m +r4mio +2rn +rna4vš +rn4dr +ro4ad +ro3by +rod2l +ro3d4r +3rofy +ro3h +ro4h. +ro4jb +ro4kš +rom3n +romy4s +ropát4 +ro2sb +ro4skv +ro4sky +ro3sv +ro3ti +ro3tl +ro4tč +ro3vd +rově4t +3rový +roz3d +roz3n +ro4zo +roz3v +ro3zá +ro4čp +rpa3d +2rr +rr4ha +rr4ho +2r1s +r2st +r4stu +rs3tvě +rs3tvý +2r1t +r2th +r4trá +rt4sm +rtu3 +r2t3v +rt4zu +1ru. +ru3se +ru3si +rus3k +ru3ži +3rvaní +r1x +1ry. +rych3 +ryd2 +rys3ky +rys3t +ry4zk +ry4zn +ry4í. +ry4šk +2rz +rz3d +rz3l +rád4l +rá4dž +1rák +rá3ri +1rář +r1č +4rčitý. +rč3t +3ré. +2ró +2rš +rš4ní +rů4m. +růs3ta +rů4v. +3rý. +rý4zn +2s. +sa4pf +sa4pr +sas3k +s2b2 +s2c +s3ca +s3ce. +sch2 +sch4l +sch4n +3schop +s3ci +sci4e +s3cí +s2d +1se +se4au +se3h +se4ig +se4il +sej4m +se4ku +3sel +se3lh +3sem +ser4va +se3s2 +ses4k +se4ss +se4stra +se4stru +se4stř +set2 +se3tk +se3tř +se4ur +se3z +se3čt +2sf +s3fo +3sfé +s3fú +1si +3sic +3sif +si4fl +sig4no +3sik +si3ste +3sit +s2j +s3ju +s2k +4skac +s4kak +4skam +s4kok +2skon +skos4 +4skot +sk4ra +sk4ru +sk4ry +4skve +sk4vo +s3kán +s3ků +3sl. +4s3la. +s4lav +s3le. +s4led +s3lem +s3len +s3let +s4lib +s4liči +3sln +4s3lo. +s2ly +s3ly. +s1lí +s2ma +s4mek +s2mo +2sn +s2na +s3nat +s2ne +s3ne. +sn4tl +s2ná +s3ná. +s4níd +1so +sob4l +so3br +so4sk +so4tv +sou3h +sou3s +souz4 +so4šk +s2p +s4pol +spro4s +1sr +2ss +ss4sr +2st. +4sta. +s3taj +s2tan +st4at +4stec +s4tep +st4er +s4tero +s4tich +2stil +s4tink +4stit. +4stič +st3lo +2stn +4sto. +s4tona +4stou. +4str. +4stram +s4trik +4strn +4strác +4stupni +s2tv +st4ve +3ství +4sty. +s4tyl +3styš +s2tá +4stá. +s3tář +4stě. +s4těd +3stěh +s2těr +s2těž +s1tí +2stí. +s3třej +1su +su4ba +su4bo +suma4 +su3ve +s2v +sy3c +sych3r +sy4nes +sá2d +3sáh +sá2kl +2s2č +s3či +1sé +1sí +2sň +2sť +s3ťo +1sů +s2ž +2t. +1ta. +ta2bl +tac4tvo +t2a3d +1taj +ta4jf +ta4jg +4talt +4tand +3taně +t1ao +2tark +tast4 +ta3str +ta4čk +2t1b +2t1c +1te +3te. +te4ak +te4fl +te4in +4teném +teob4 +tep3l +ters4 +tes3ta +te4tr +te4uc +te4ur +te4ut +2tf +2tg +1ti +ti4gr +2tih +ti3kl +tin4g +ti4pl +ti3sl +tis4tr +ti4tr +2titu +tiz4r +4tizí +tiú3 +2tiž +2tk2 +t4kal +4t2kan +t4kat +t2kl +tk4la +tk4li +4tkně +t2ká +2tl +3tl. +4tla. +t1le +tles3 +3tlm +t3lo. +t4lou +tlu3 +tlu4s +t1ly +t1lé +2tm +t2ma +2tn +t3ní +1to +to4as +to3b +tob4l +to3dr +to4hm +to4ir +2toj +tol4s +to4ol +4top. +4topt +4topu +2torn +2toup +2tp +t3rant +t4rea +t4ref +tre4t +4tric. +trip4 +t4rit +t4rog +t3rol +tro4sk +t4rou +4trouh +4troň. +4trun +t4rus +4t4ruž +t3ráln +4tráš +2trč +t3rům +t3rův +2trý +2t1s +ts4ko +ts2t +2t1t +tt4ch +tt4ri +1tu. +tu4ff +1tuj +tu4lk +2tup +tu4r. +tu3ry +tu4s. +tu4ť. +tu3ži +t2v +2tve +2t3vi +t4vinn +t4viš +t4výc +1ty. +ty4gř +ty2la +ty4ře +ty4řh +ty4řj +ty4řo +ty4řr +ty4řú +3tá. +tá4fl +t2č +t3či +2tčí +1té +té2bl +3tém +1tě +tě3d4l +2těh +2těnn +2těp +1tíc +4tíc. +4tíce +1tím +2tín +2tír +2tř +t4řeb +třeh3n +t2řel +t2řic +t3řil +tř4ti +t1řu +t2řá +3třáb +tří4s +2tš +t3št +tš4ti +1tů +1tý. +1tým +1týř +3týš +u1 +2u. +u2at +u2b +u3ba +u3be +u3bi +u3bo +ubs4t +u3bu +u3bá +u3bí. +u3bů +uc4tí +2u2d +u3de +u3di +u3do +u3dru +u3du +u3dy +u3dí +ue4fa +2uf +u2hl +uh3lá +uh3no +u2in +u2jm +u2k +u3ka. +uk4aj +uk4al +uk4at +u3ke +uk3la +uk3le +u3ko +u3ku +u3ky +uk4á. +u3ků +ul4fa +ul1h +ul4pí +u2m +u3ma +u3me +u3mi +um4pl +um4ru +u3mu +u3má +3umř +u2n +un4dl +u3ne +u3no +u3nu +u3ně +u3ní +u3nů +un4žr +u2p +u3pa +u3pe +upe2r3 +u3pi +u3pln +u3pu +u3py +u3pá +u3pě +u3pí +u3pů +u2r +u3ra +u3re +u3ri +2u3ro +u3ru +u3ry. +u3rá +1urč +u3rů +u2s +us3ky +us3ká +us3ké +us3ký +us1l +us2lo +u3so +u4ste +u4sty +u4sté +u4stě +u3stř +u4stš +u4stý +u3su. +u3sy +u3sá +u3sí +u3sů +u4tro +u4trá +u2v +u3vi +u3vu +u2z +u3ze +u3zi +uz1l +u3zo +u3zu +u3zí +u2č +u3ča +u3če +u3či +u3čo +uč3t +u3ču +u3čá +u3čí +u2ď +u2ň +u2š +u3še +u3ši +uš4kl +u3šo +uš3tí +u3šu +u3šá +u3ší +u2ž +u3že +u3žo +u3žu +u3žá +u3ží +1v +2v. +va3dl +va4jť +va4kl +2v1b +2v1c +v2ch +2v2d +v4dal +v3di +v4děk +v4děč +ve3dle +ve3jd +3ven +ve2p +ve3ps +vep3ř +ves3l +ve4sm +ves4p +ve3sta +ve3t4ř +ve2z3m +vi4ch +vide2 +vi4dr +vi4et +vi4kr +vi2tr +2vk +v2kr +v2l +2v3la. +4vle. +4vlem +2vlo +2vm +2vn +v4nad +vo3b +vo4ic +vo4ja +vo4jb +vo4jd +vo4jj +vo4jm +vo4jř +vo2s +vo4tř +vou3 +vous2 +v2p +vr2c +vr2dl +4vrny +v1ro +vr4st +vrst3v +vrs4tvě +2vs2 +v1sk +v3stv +2v2t +vy3c +vy3d2 +vy4dra +vyp2 +vy3s2 +vy4sn +vys4t +vy3t +vy3č +vyč4k +vyš2 +vy4š. +vy4šm +vy4šš +vy4žl +v2z2 +vz4no +vz4né +vz4ně +vz4ní +vá3ri +2v2č +v3čá +v3čí +v4čír +vě4cm +vě3t4a +více3 +ví4hat +3vín +2vň +2vří +v3řín +v2š2 +vše3s +v3ští. +3výs +vý3t +3vý3z +v2ž2 +wa4fd +3war +wa4re +we2 +2x. +xand4 +2xf +xisk4 +2xn +3xov +x1t +xt4ra +xy4sm +y1 +y2a +y2bl +yb3ri +y2ch +y4chr +y2d1l +yd4lá +y2dr +yd4y. +y2e +y2gr +y3hn +yh4ne +yj4ma +yj4me +y2kl +yk3la +y3klop +yk4ly +ymané4 +ym4kl +yna4s +y3ni +ype4r +yp4si +yp4tá +y2př +yr2v +y2s +y3sa +y3se +y3si +ys3lu +y3sm +y3so +y3sp +ys2t +ys3te +yst4r +y3su +y3sv +y3sy +y3sá +y3sé +y3sí +yt4me +yu3ž +y3vs +yvě4t +y3zb +y3zd +y3zk +y3zn +yz4ně +yz4ní +y3zp +yz4po +yč2k +y2ň +yř3b +yřk4n +yř4če +y3ří +y2š +y3še +y3ši +y3šk +yš1l +y3šo +y3šp +y3šu +y3ší +yž2 +y3žd +1z +2z. +zab2l +za4bs +za4dk +za3dl +za4dn +za3h +za3i +za3j +za4jk +za3k +za4kt +zal4k +zam4n +za3p2 +za3s2 +zat2 +za3tl +zat4r +za4ut +za3z +zaz4n +za4zš +za4č. +za3š +zaš4k +za4šs +2zb +zban4 +z2by +zbys4 +2z1c +2z2d +z3di +zdně4ní +z4doba +z4dobný +zd4re +zd4ví +z2e +ze3h +ze3p2 +4zerot +ze3s2 +zes4p +zet2 +zev2 +ze3vn +ze3z +ze4z. +2z2f +z1há +z4ine +z2j +z3jí +2z2k +z3ka. +z3ky +z3ké +z3ků +z3ký +2zl +3zl. +zlhos4 +zlik3 +z3ly. +z2m2 +2zme +z3mn +z3my +z4měn +2z2n +3znak +z4nal +z3ne. +z3nic +z3no +z3nu +z3ny +z3né +z3ně +z4něl +z3ní +z4nít +z4nív +z3ný +zo4tr +zo4šk +2z2p +z3pt +z4pát +3zrak +2z1s2 +2zt +ztros3 +z4trá +z3tř +3zu. +zu3mo +zu3mě +zu3mí +zu3š +z2v +zva4d +z3vař +z3vi +zvik4 +zv4ně +z3vod +z3voj +z4von +zv4ro +z4ván +z4věs +z3víj +3zy. +2zz +zá1 +záh2 +zá4kl. +3záp +zá3s2 +zá3z +záš2 +2zč +z3čl +2zň +z2ř +zřej3 +z3řez +z3řeš +2zš2 +z3šk +zš4ka +z3št +2z2ú1 +zú3č +zú3ž +zů3s +á1b +á2bl +áb4ry +á4bř. +á3cho +ác3ti3 +á1d +á2dl +ádo4s +ádos4ti +ád1ř +á1ha +á3he +áh1l +á3hl. +áh3n +á1ho +á1hr +á1há +á1j +á4jmu +áj4mů +á4kli +ák4ni +á1la +á1le +á1lo +á1lu +á1ly +á3lé +á1lí +á3my +á3mé +á1mě +á3mí +á3mý +áne4v +á1ra +á1re +ár2m +á1ro +á1ru +á3rů +á1s +á2sc +á2s3k +ás4k. +ás4kl +ás4kn +á2sla +ás4ly +á2sm +ás4po +á2st +át3k +át1r +á1tu +á1ty +á1tí +á3tý +áv4si +áv4sí +áz3k +áz3ni +ázni4c +áz4vi +á2ň +á1ř +ář4ke +ář4ků +á2š +á3še +á3ší +2č. +1ča +ča4br +2čb +2č1c +1če +3če. +če1c +čes3k +1či +2čk +č3ka. +č3ko +č3ku +č3ky +2č1m +2čn +č2ne +1čo +č2p +2čs +č1sk +čs4la +čs4sr +2č2t +č4tené. +č4tený +čt4la +č4tový. +3čtv +4čtěn +č3tí +1ču +1čá +1čí +čís3l +1čů +2ď. +1ďa +1ďo +ďs4te +2ď1t +3ďuj +é1 +é2d +é3di +é3do +é2f +é3fo +éf1r +é2kl +é2l +é2m +é3ma +é3me +é3mi +é3mo +é3mu +é3mů +4ére. +é2s +é2t +é3ta +é3to +é3tá +é2š +é2ž +ě1c +ěd3r +ě3ha +ě3he +ě3hl. +ěh3lo +ěh3n +ě1ho +ě3hu +ě3hů +ě3ja +ě1je +ě1jo +ě3jů +ě4klé +ě3k2t +ě1l +ě1ra +ěra3d +ě1re +ě1ro +ěr3s +ěrs4t +ě1ru +ě1ry +ě1rů +ěs3k +ěs3n +ět1a3 +ět4ac +ět1l +ě1tr +ět3ra +ě4traj +ět3v +ě1tí +ět3ří +ě2v +ě3va +ě3ve +ě3vl +ě3vo +ě3vu +ě3vá +ěv3č +ě2z +ě3ze +ě3zi +ěz3n +ě3zo +ě3zí +ě1ř +ě2š +ě3še +ě3ši +ě3šo +ě3šu +ě3šá +ě3ší +ěš3ť +ěš4ťs +ě2ť +ě3ťo +ě2ž +ě3že +ě3ži +ě3žo +ě3žu +ě3ží +í1b +íb3ř +í3cho +ích4t +íd1l +í1h +í2hl +íh3n +í1j +íjed4 +íj4mů +í2kr +í1l +í1má +í3mé +í1mě +í1r +í1sa +í2s3k +ís4kl +ís4kn +ís4l. +ís3le +ís4ln +ísáh2 +í1t +ít3k +í3t3ře +íz3da +íz3de +íz3k +í3zna +í3z3ni +í3zněn +í2ň +í1ř +í2š +í3še +í3ši +í3šo +í3ší +1ň +2ň. +2ňa +ňa3d +2ňk +2ňm +3ňov +ň1s +2ň1t +ó1 +ó2z +ó3za +ó3zi +ó3zo +ó3zy +2ř. +řa4pl +řa4ďm +2ř2b +2řc +2řd +ře3ch +ře4dob +ře1h +ře3jd +ře3kl +ře3kv +ře4kří +řeo4r +ře3p2 +ře4p. +ře4pk +ře4pč +řer4v +2řes +ře3ska +ře3sko +ře2sp +řes3po +ře4sr +ře3sta +ře3stu +ře3stá +ře3stř +ře3tl +řet4ř +ře3zd +ře3zk +4řezl +ře3čt +ři1 +řia3 +ři3h +ři4h. +ři4hn +ři4jď +ři4l. +ři4lb +řil2n +4řine +řis2 +3ři4t. +ři4v. +ři4vk +ři4vn +ři3z +řič4t +ři3ř +ři4š. +2řk +ř2kl +řk4la +řk4li +řk4ly +řk4no +2ř1l +2ř1m +2řn +1řo +2řou +2ř2p +2ř1s +řs4to +2ř1t +ř2v +2řz +řá4pl +řá2sl +2ř1č +2říd +ří4kř +ří1s +2řš +ř3št +řš4ti +1š +2š. +šab3 +ša4vl +2š1c +šej4d +šep3t +ši4mr +2š2k +š3ka +š3ke +š3k3li +4š3kou +4škov +3škr +šk4ro +š3ku. +š3ky +2šl +š2la +š2li +š3liv +š2lo +šlá2 +š2lé +š2lý +2š1m +šmi4d +2šn +š2p +2š1s +2št +š4tip +št4ka +št4kl +š4těk +š2těs +š4těv +š4típ +š2v +ší3d +š2ň +š3ší +2š2ť +š3ťo +š3ťu +š3ťá +1ť +2ť. +3ťal +2ťk +2ťm +2ťt +ťáč4k +1ú +ú2c2 +ú2d +új4ma +ú2k +ú2l +ú2n +ú2p +ú2t +út4ko +ú2v +ú2z +úz3k +ú2č +3úče +úře4z +úš4ti +ú2ž +ů1b +ů1c +ů1hl +ů3jd +ů4jmový +ů1le +ů1my +ů1mě +ů1ra +ůr4va +ůr4vy +ů1s2 +ů2st +ůs3te +ůs3tán +ůt2 +ů3tkl +ů2v +ů3va +ů3vo +ů3vě +ů2z +ů3zo +ů2ž +ů3že +ů3ži +ů3žo +ý1b +ý3cho +ý1d +ýd4la +ý1h +ý1j +ý1l +ý1ml +ý1mě +ý2n +ý3no +ýpo3č4 +ý1r +ý1s2 +ý2sk +ý1t +ýt4ku +ýt4ky +ý1u +ý4vli +ý3zk +ý3zn +ý4zvu +ýč4ně +ý1ř +ýš3l +1ž +2ž. +ža3d +ža4tv +3žač +2ž1b +2ž1c +2ž1d +že2b3 +žeh3n +že4ml +že4zg +ži4dl +ži4jm +3žil +ži2vl +2žk +žk4ni +2žl +ž4lic +3žlo +2ž1m +2žn +žon2 +2ž1s2 +2ž1t +ž2v +žá4br +žá4nr +2žď +ží4zn +2žň +2žš +žš4ti +žš4tě +} + +% Local Variables: +% mode: tex +% coding: latin-2 +% fill-column: 72 +% End: +% vim: set filetype=tex textwidth=72: diff --git a/tmac/hyphen.den b/tmac/hyphen.den new file mode 100644 index 0000000..3148e30 --- /dev/null +++ b/tmac/hyphen.den @@ -0,0 +1,23437 @@ +% This is the groff hyphenation pattern file 'hyphen.den' for German +% with hyphenation rules for the new orthography. +% +% It is based on the file 'dehyphn-x-2017-03-31.pat' taken from the +% 'dehyph-exptl-0.41' package, converted to latin-1 encoding. +% +% Below is the original copyright message. +% +% ------------------------------------------------------------------------- +% +% TeX-Trennmuster für die reformierte (2006) deutsche Rechtschreibung +% +% Copyright (c) 2013-2017 +% Stephan Hennig, Werner Lemberg, Guenter Milde, Sander van Geloven, +% Georg Pfeiffer, Gisbert W. Selke, Tobias Wendorf +% +% Licensed under the MIT license. Full license text available from +% +% http://opensource.org/licenses/mit-license.php +% +% +% The word list is available from +% +% http://repo.or.cz/w/wortliste.git?a=commit;h=5fd786fcb1ed48448e058672f1f58d185653d8c6 +% +% The used patgen parameters are +% +% 1 1 | 2 5 | 1 1 1 +% 2 2 | 2 5 | 1 2 1 +% 3 3 | 2 6 | 1 1 1 +% 4 4 | 2 6 | 1 4 1 +% 5 5 | 2 7 | 1 1 1 +% 6 6 | 2 7 | 1 6 1 +% 7 7 | 2 13 | 1 4 1 +% 8 8 | 2 13 | 1 8 1 + +\patterns{% +.ab1a +.abi4t +.ab3l +.abo2 +.ab3ol +.ab1or +.ab3s2 +.ab3u +.ade3n +.ae3 +.aft2 +.ag4n +.ag4r +.ag2u +.ai2s +.akt2a +.al2e +.al3k +.al3lei +.al5len +.al3se +.al4tan +.al4tei +.alter6s5 +.alt3s4 +.al2tu +.ampe4 +.amt2s1 +.amt4sc +.ana1c +.an3d2 +.anden6k +.and4ri +.an1er +.ang2 +.an3g4li +.angs4 +.angst3 +.ani2s +.an3k4 +.an3na +.an3s2 +.an4si. +.an3z2 +.ap5p6le. +.aps2 +.ari1e +.ar3k2a +.ar4m3ac +.ar4mun +.ar2sc +.ar4tan +.ar4t3ei +.arter4 +.ar6t5erh +.ar2tr +.arz2 +.asbe2 +.as4ta +.as3tr +.ata1 +.ate2 +.at4h +.at4r +.au3d +.aue2 +.au4f3 +.aufs4 +.au2s3 +.auss2 +.auß2 +.ax2 +.äm3 +.är6schl +.ät2h +.ät2s +.bahn3 +.bah6ner +.baus4 +.be3erb +.bel2a +.be3r4a +.be3r2e +.ber4g3a +.ber6g5e6b +.ber4g3r +.ber4tr +.bi4os +.bi2t +.bit1a +.boge2 +.bogen3 +.bogens6 +.bo4s3k +.bu4ser +.by4t +.ca2s3t +.ch4 +.char8mes +.chi3er +.dab4 +.da2r1 +.dar3in +.darm1 +.da4te. +.da4tes +.de2al +.de1i +.dein2 +.de3lo +.de8ments +.den4ka +.den4kl +.den4ko +.de1o2 +.de3r4en +.de1s +.de3sk +.des2t +.di3el +.di4en +.dien4e +.dien6st +.dienst7a8d +.do3b +.do2mo +.don4a +.do1pe +.dor2f1 +.dy2s3 +.ebe2r1 +.edu3s +.eg2o +.eh2e +.ehe1i +.ei3e2 +.ei3f2e +.ei3k +.ein3d +.eine2 +.ei4neb +.ein6erl +.eise4 +.ei2sp +.eis3s4 +.ei2s3t +.ei4tr +.eke2 +.ek3li +.el2a +.el2bi +.el2bl +.elb3s +.el4fei +.el2fl +.el2i +.el6st +.em3m2 +.en1 +.en4da +.en4d3er4 +.en2d3r +.end3s +.en4dü +.en2gl +.enn2 +.ent3 +.en2ta +.en4tei +.en4tio +.en4t1r +.en5trop +.ents4 +.er4bei +.er8brecht +.er2bu +.er4dan +.er4dei +.erden6k +.er4dep +.er4d3er +.er1e +.ere3c +.erf4 +.er1i +.ers2 +.er8stein +.erster6 +.er8stritt. +.er8stritten. +.er4z3el +.er4zen4 +.ese3le +.es3p +.es3ta +.est6e +.es3th +.es3t3r +.et2s +.eu1 +.eu3g4 +.eu3r4 +.eu3t +.ext4 +.fe3la +.fer4no +.fi3est +.fi4le. +.fi4len +.fi2s +.flug1 +.for2t +.fs4 +.fu2sc +.ga2me +.ga4s1 +.gas3e +.ga4t +.gd2 +.gebe4a +.geb2l +.gee4 +.gel4b3r +.gel2d1 +.ge3lu +.ge5nar +.ge3n4e +.gene7cke +.ge3n2o +.ge3r4a +.ge3r2e +.ge3ro +.ger4s +.ge3s4a +.ge3u +.glan2 +.gol6der +.gs4 +.halt4e +.hau2t1 +.he2 +.he4bei +.he3fe +.he3le +.her3an +.he3rat +.her6b5ra +.he3rer +.he3ri +.he6r5inn +.hin3u +.hips4 +.hi4s +.hof1e +.ho4fen +.ho4met +.ho4st +.ia4 +.im2a +.ima4ge +.im5m2 +.in1 +.ind4 +.in3gl +.ink2 +.in3n2e +.in3sk +.inu1 +.ioni1 +.ire3 +.is2a +.is3t +.it2h +.iv2 +.ivo3 +.joni1 +.jor3 +.ka2b3l +.ka2i +.ka3le +.ka3ta +.ka4t3io +.ki4e +.klang3 +.ko3b +.kopf1 +.kor4da +.kraf2 +.ks4 +.kus2 +.la3be +.la3ho +.lase2 +.le4ar +.le4gas +.le3n2i +.len3z +.lich8t7er8s +.li2f +.li4ve. +.lo4g3in +.lo2sc +.los3s4 +.lo3ver +.luster6 +.lus4tr +.lut4h +.ma3d +.ma3ge +.mal4e +.ma2st +.mat4c +.matu3 +.md2 +.me3l2a +.me3ne +.me3no +.men8schl +.men8schw +.ment4 +.mes4sp +.mi2f +.mik4 +.mil2z +.mi2st +.mi4t1 +.mm2 +.mutter5 +.na3no +.na3t +.nat2h +.näs1c +.nebe4n +.ner2f +.ne1ro +.ne2s +.nich2 +.nicht5e +.ni4e +.ni3k4l +.no4th +.nus4 +.oa3s +.ob1a +.obe2 +.ober5ei +.of2e +.oper4 +.or2a +.ord4e +.ort2 +.ort4h +.orts3e +.os3s +.os4tal +.os5t6alg +.oste2 +.os4t3el +.ost5end +.os8ten8de +.oste6re +.os8terwe +.os4t3r +.os2tu +.ot1 +.ozo4 +.öd2 +.öl3l +.pab4 +.pa2r1e +.par3t4h +.pe2c +.pe3la +.pe3le +.pf4 +.ph4 +.poka2 +.po4st +.pro1 +.ps2 +.rabe4 +.ra3ch4e +.ra3me +.ra3sa +.rau2m +.rau8schl +.räu3sc +.re3ale +.reb3s2 +.re3cha +.re5insz +.reis6e5i +.rei4st +.reli1 +.res6tr +.ri4as +.richt6e +.ro4a +.ro3be +.ro2h +.ro3m4a +.ro2tr +.rö2s +.ruf3s +.ruh2r1 +.runder6 +.rü1b +.rü6cker6 +.sa3br +.sali3e +.sami1 +.sau1c +.sau5er. +.sch4 +.schaf8t7end +.scheiner8 +.se3ck +.se2ei +.se2ha +.sen4f +.sen3s +.se3re +.se1ro +.se2t1 +.sha2 +.si3gn +.si4te +.ski1e +.skis2 +.sour2 +.spani7er. +.spiege8lei +.st4 +.ste2i +.steiner8k +.sto4re +.sucher6 +.tage4s +.tan4k3a +.tan4k3l +.ta3ra +.tar3t +.ta2t3h +.ta2to +.ta4tor +.ta2t1u +.te2e +.te2f +.tehe3 +.teiler8s +.tei8l7ersc +.te3l +.te3no +.ten3s +.te1ra +.te2s +.te4st +.tester8g +.tester8h +.test3r +.th4 +.ti2e +.ti2me +.ti4mes +.ti2s +.ti8sch7end +.tite4 +.tode4 +.to4der +.todes5 +.to2n +.to4nat +.to4nin +.to4pl +.to2pr +.to2w +.tri3es +.tro2s +.ts4 +.tsa3 +.tse3 +.tu3ra +.tu3ri +.turm1 +.tur4ma +.ub2 +.ufe2 +.ufer1 +.ul2b3 +.um3 +.uma2 +.ume2 +.umo2 +.un3a2 +.un3d +.une2 +.un3g +.uni4t +.un3s +.uns4t +.ur3a2d +.uran6fa +.ur1c +.ur1e +.ur4inf +.ur3o4m +.ur1o2p +.ur3s2 +.ut2a +.ut3r +.übe4 +.ve5n2e +.voll1 +.vo4r +.wah4l +.wa2s +.weg5s +.wei4ta +.welter8e +.welter8kl +.wer6ker +.wer4kr +.wer4tr +.wetterer8s +.wi4e +.wor2 +.wort5en6 +.wor8tend +.wor4tu +.wur2f1 +.xe3 +.ya4l +.zahn3 +.zel4la +.zelle4 +.zel6leb +.zeug4i +.zi2e +.zie4l3u +.zin4ka +.zin4s3c +.zin4st +.zuch2 +.zucht3 +.zug3l +.zu4gra +.zu2pf +.zwe2 +.zweigen8 +.zwei8g7end +a1ab +aa2be +aa1c +a1a2ce +aa2gr +a1akt +aals2t +a1a2n +a2ans +a1aq +2a2ar +aa2r3a +aar3b +aar3d +aa3rea +aa2rei +aarf4 +aar3g2 +aar3k4 +aar3t4 +1aas +aata2 +aa2th +aa4t3r +aat4s3 +2a3au +a1ä +a1b +2aba +ab1alt +ab2am +ab2ant +ab1au +ab1ä +ab2är +ab2äu +2abbat +2abbin +1abd +4a3be. +4a3bec +abe1e +ab1eic +abe3i4d +ab1eil +ab1ein +4ab2el +abe2la2 +abe4l3in +1abent +2aber +a2berd +a3beri +ab1er2k +ab1er2r +ab1er2z +4abes +abe2s1e +ab3esse +2ab2et +2abew +1abf +1abg +3abga +1abh +2abi +4abil +ab1ins +ab1ir +abi3s4t +3ab1it +1abk +ab1l +1a2bla +a4blag +a3blat +a4blau +1a2blä +3ab3lei +2ablet +ab3li +a2blin +ab4lit +2ablo +1a2blö +2ablu +1abn +2abo +3a2bo. +ab2of +3a2bon +4abot +2abö +ab3r +a4brä +a2bre +2abro +ab4ros +2abrö +1ab5sc +1ab3s2p +abst2 +ab3sz +1abtei +abte2s +3abtr +2abu +a2bum +ab1ur +2abü +1abw +2aby +aby4t +3abz +2a3ca +ac1c +a1cem +a1cen +a2ceo +ach1a +a1chal +a3chari +ach3as +ach3au +2achb +a1che +a2ch1e4c +ach1ei +ach4ei. +a2chep +a4cherf +ach5erfa +a4ch3erh +a4ch3erl +a4cherö +a4ch3erw +2achf +2a1chi +a2chim +ach3l +2ach3m +ach3n +a1cho +a3cho. +ach1ob +a2cho2r +ach3ö +2ach3r +2achsc +achs4el +ach3s4i +ach3skr +achs4or +ach3su +a4cht +ach4tak +ach8tersp +ach6t5erw +ach4t1o +ach8traum +ach8träume. +ach8träumen. +ach6trit +acht6sal +ach4tum +a1chu +ach1u2f +ach3ü +2achv +4ach1w +a2chy +2a1ci +4ack. +a1ckar +a3ckel +a2ckin +ack2sp +acksta4 +2a1cl +acon4n +2acu +a1ç +a1d +2ad. +2ada. +4adab +a2dac +a2dad +ad2ag +ad1ama +a2d1an +3adap +4a3d2a2r3 +2adat +a2d1au +a3dau. +1a2dä +ad1c +1add +2ade. +ade2al +a3dec +a3dee +adefi2 +2adeg +4aden +ade1ra +4ade1s +ade3s2p +ades4s +2adf +4adh +4adi +adi3en +adi3er. +adie4sc +adi4st +3adj +2adli +3admi +4admu +ad2ob +1a2dop +2adp +2adq +2ad3rec +ad3rei +ad3run +2ads2 +ad3st +ad3sz +2ad2t1 +ad4te2 +adt3h +1adv +2a1e1 +ae2b +a2ec +ae2ck +ae2d +ae2i +a2ek +a3el. +a2ela +a2ele +a2eli +a3els +ae2m +ae2o3 +ae2p +a3er. +3a2er2o1 +aes2a +ae2sc +aes5t +a2ew +ae2x +2afa +af1ab +a2f1a2n +a3far +a2f1au +2afä +a2f1än +2afe +a2f1ec +a4fentl +a4f1ep +aff4a +af2f3l +af4flu +aff2s +2afi +afi2e1i +afi6kanz +afi4kat +afi2t +2af3l +a1flu +2afo +a2f3oc +a2ford +afo1s +2afra +af3rau +af3rä +af3re +2afro +af3rö +af4rü +af3s2a +af3s2h +af2si +af2sp +afs4t +af2t1a +af2tei +af2te2l +aft4erk +af2t1o +af2tö +aft3r +af2tra +af4t5re +aft4stä +af2tur +a2f3ur +2afü +afür3 +a1g +2ag. +2aga +ag1a2b +ag1a2d +ag1ar +a2g1au +agd1 +ag2del +ag2di +ag2dr +ag2du +4age. +age1i +agein4s +age4ler +ag2em +4a3gen. +age4neb +a2gent +2ages +age4sam +age4s3i +age2s3p +ages6sen +age4s3ti +3aggr +a2g1id +a2gim +2a2g1l +ag4lan +ag4las +ag3le +a4glö +2agm +ag2n +ag4nat +a4gnä +ag4ne. +ag4nu +ag3rat +a2g3re +a2g3ri +ag4ro +2ags +ag3s2ah +ag4sam +ag3s4eid +ags8porta +ags4tan +ag1ste +ag3stö +2agt +ag2th +2agu +a2gund +2ah. +a1ha +ah2an +ah4at +a1hä +2a1he +ahe1in +a2h1er2h +ahe1s +ahe1u +a1h2i +ahin3 +ah2l3a2 +ah2l1ä +ah4l1ei +ahle4na +ah4l3erd +ah4l3erh +ahl1o2 +ah2lö +ahl3sz +ahme1i +ahme3s +ah3mu +ah4n3a +ah3nee +ahn3el +ah4nerd +ahner4e +ahner6le +ahner4n +ah2nin +ah2no +1a2hor +ah1os +a2h3ö +4ahr +ahr1a +ah3r2e +ahren6sc +ahre4s +ah3ri +ahr6tage +ahr6teng +ahr2ti +ahr4tri +ahr4tro +ahr4tun +ah2ta +ah2te2l +ah2t1ex +ah4t5r +aht3s6 +a1hu +ah1w +a1hy +2ai. +ai3a4 +a1ia. +2aib +ai2bl +aid2s +ai1e4 +ai3en3 +aif4 +ai1fr +ai3g4 +a3ik. +ai3ke +ai2lar +ail3d4 +ai2lei +ail3g +ai2lo +4ain +ain2a +a1ind +ai5n4e +ain3s +ains2p +3airb +ai2sa +a3isch. +ai5schw +ai3s2e +ait4 +a3iv. +a3ivl +a3ivs +a1j +a2jat +aje2 +ajekt4o +2ak. +a3ka. +2aka3b4 +a2ka3d2 +2akal +2a3kam +2akar +ak4at +aka4tak +1akaz +4akä +2akb +2akc +2akd +2a1ke +a2kef +a2k1em +a2k1ent +a2kes +a2keu +4a1ki +ak1ins +aki1s +1akku +2ak3l +ak4li +a1kna +2ako +2a1kr +4akra +ak4ri +2aks +ak3sh +ak2t1a2b +2aktb +ak2tel +akt2er +2aktik +2aktis +2aktm +ak2tö +ak2t3r +akt4ri +2aktsi +2aktsp +2aktst +2aktw +a1ku +2akun +a2kup +2akur +aku2s +4a3kü +1akz +3akze +a1la +2ala. +4alabo +al2abr +al1af +al1age +2alai +al3akr +al1am +al1ana +4aland +a2lang +al1anz +al1app +a3lar. +al3arc +a3lare +al2arm +2al3arr +a2lart +ala2s +al1asi +al1ass +ala2t1a +al4atm +alat3z +al1au +al3aug +a1lä +a2l1äm +al1än +al1äu +3albat +al2bär +alber4e +al4berh +al4b3er4w +al2b1l +al2boh +alb3ru +alb3s +al2dä +al4d3erl +al4d3ern +alde2s +ald3inn +al2dr +alds2 +2ale +4a3le. +ale4ar +al1eb +ale2be +al1ec +a4l3ef +a2l1ei +a3l2eic +a4l3ein +a2l1el +3a2lema +alen1 +4a3len. +3alenc +alende4 +al3endr +a4l3ends +a2leng +al2enn +a3lentf +ale2p +al1epo +4aler. +a2l1erb +a2l1erf +a2l1erh +aler4kl +a2l3erl +al1erm +aler4mi +a2l1er4r +a2l1ert +3a4l3erwä +4ales +a2l1e4sk +a2less +a2l1eu +al3exi +alf4r +2alg. +3algi +al2gli +al3glo +1algo +3algor +2ali +al2imb +al1imm +ali4nal +al1ind +a2l1inq +al1ins +alken1 +al2klö +al2kne +1alkoh +alk3s +alks4t +al2lab +al2l1an +al2l1ap +al2l1a2r +al2l1au +al3le. +al4lec +3allee +al3lend +all3erk +al3les +al2lid +alli5er. +alli7ers. +al2lob +al2lop +al2löf +al2map +al4m3ast +almo6de. +a2l1ob +3aloe +a2lof +4alog +alo2ga +alo2gr +al1ont +al1ort +a2l1ö +al2ös +3alp. +3alpe. +1alph +al2pho +alrat4 +al3sak +al6schei +alsch3s +al3ska +al5s6terb +al2stu +al2sum +al2t1ak +al3tam +alt1an +1altä +al4temu +al4t3er5f +al2teu +al2tin +alt1op +al2tö +al4t3rat +al2tre +al4t3ri +al2t3ro +alt4stü +2altu +a1lu +alu3b4 +al2u3f +alu3g +al1u2k +a2lum +al1umb +al1ur +a3lus +4aly +al2zar +al2zau +alz4erk +al2zw +2am. +am2a +ama3d2 +ama3g +a2malg +2a3m4an +a2m3ap +3a2maz +2amä +4ame. +a2meb +2amel +am4e4n1 +amen6spr +ame3r2a +a2m1erf +a2meri +ame5r2u +ame1s +a4mesh +a3met +2amf +am4ing +2amir +2amis +2amit +2amk +2aml +2amm. +2ammal +am4mant +am2mar +am2mei +am2mid +ammi2e +am2min +am2mor +am2mö +ammu2 +amni1 +a2mö +2ampe. +2ampen +am4pf +amp2f1a2 +ampf1o +2am2ple +2ampo +am3pr +2am2s +am3sa +4amsc +am4schl +3amse +am3s2h +am3so +am3sp +am3su +1amt. +am2t1a2 +am4tau +am2t1ä +am2tei +amt3eig +am4tel +am4t3ern +am2t1ex +am4tis +am2tit +am2to4 +am6tou +am2tö +am2t3r +am6tre +am4tri +am2t1u +2amu +3a2mul +2ana. +2anab +ana3c +4anad +anadi1 +an2ag +2a3nak +an1alg +ana4lin +an4a3ma +2anan +an4and +2ana1s +a5nat. +ana4th +a5n4atm +ana4tr +an3aug +1an1äs +1anb +2anbas +2anbu +an3ch +2and. +3an3d2ac +and3arm +and3ei +anden6ga +an4d3ent +and5erob +ande2s +an2d1ex +and4sas +and2so +and6spar +and6spas +and2su +4andu2 +an2d1ur +andy1 +2ane +4ane. +an3e2c +a3nee +an2ei. +an3eif +3aneig +a4neis +3a2n1e4k +ane2mi +4anen +aner4fa +an2erh +a4nerke +4anern +a4nerz. +an4erze +an1eth +1anf +2anf. +2anfab +3anfä +an3fe +2anfi +an4fj +anf3le +4anfors +anf5rau +2anfs +an3f2u +2ang. +1angab +an2gan +an2g1ar +2ange. +1angeb +1angeh +an2g1ei +an4g3erf +an4g3er4w +an4g3erz +2angh +2angie +ang1l +an2gla +ang3n +ang1r +ang3ra +1an3gri +2angs. +angt4 +1anh +2a3n2i +ani3d +ani3els +ani5ers. +ani3g2 +ani3ke +3a4nim +a4n3ind +a4n3ins +ani2o +an3i4on +a4niso +2anj +2ank. +an2kab +an2k1ak +an2kan +an2kei +2anken +ank5erfa +2anki +an2klö +an2klu +ank3no +an4k3opf +an2ko4r +ank1r +ank3ra +an4kras +ank3rä +an2kro +2anks +ank3se +anks2p +2ankt +1anl +2anlad +3anlag +2anmo +1anmu +2ann. +1annah +an2nar +an3ne +an4nef +annen3s4 +2anns +ann4s3p +2annt +2ano. +ano3b +an1od +2anof +2anog +anoi3 +a3nol +ano2la +1a2nom +a3nom. +a2n1or +2a3nos +2a1nö +2anpu +1anr +2anrö +an3sar +1an3s2ä +3anschr +an3skr +ans1pa +ans3pon +1anspr +1anst +ans4tr +an3s2z +2ant. +an2t3ar +anta4re +an3t2ä +1antá +3antei +an3tha +2antie +3antise +2anto +anton2 +1antr +ant3rin +1antw +2anu +an4ut +a1nü +1anw +2anwi +an2zä +2anzb +2anzd +1anzei +anze4n +2anzg +2anzh +an2zid +an2z1i4n +2anzk +2anzm +2anzr +2anzs +2anzt +1anzü +3anzün +2anzv +2anzw +an2zwa +an2zwi +2anzy +2ao +aof4 +ao3i +a1op +aopf4 +a1or +a1os5 +aost2 +a3ot. +aot4r +ao3t2s +2a1ö2 +a1p +4ap. +2apa +a2pe. +a3pel +a2pé +a2pf +ap2fa +1apfel +2apfes +a3pfl +a2pht +2api +2ap3l +ap4la +ap4lä +ap4lo +ap2n +a2pot +ap3pu +2apr +4apro +aps4ter +ap5t2 +2a3pu +2ar. +a1ra +a3ra. +ar2ab +2ar3abb +ar3abf +ar3abt +ara3d2 +ar3adr +ara3ge +a2r3al +a3r4ale +a3rali +a3ralo +2aran +a2r1ang +a2r1anz +2arap +a2r3app +2arar +a3ras +ara2st +a2r1au +a1rä +1arb +2arb. +2arba +ar2bak +ar2b3at +ar2bau +4arbef +ar4b3ein +2arbek +2arben +2arber +arb3erl +4arbi +2ar2bl +2arbo +2arb1r +ar2b3re +2arbs2 +arb3sk +arb3so +2arb3t4 +2arbu +1ar1c +2archl +2archr +ar2dau +arde2l +ar2dob +ar2dop +ar2d3r +ar2du +a2rea +are5aler +a2reb4 +aree2 +ar1eff +ar1ehr +ar1eid +a3reih +areim3 +a2rein +arein4b +arein4s +arein4t +a2rele +4arem +4a5ren. +a5reni +aren6sem +are3r2a +arer2e +a4r3erei +a2rerg +a2r1er3h +a2reri +a2rerk +a2rerl +ar2erw +are3u +arf1r +arf3ra +arf2sp +4arg. +ar3gan +ar2gl +ar2gn +2arg4o +ar3g4r +2arh +2ari +ar2ia +a2rid +ari3e2n +ari3erd +ari3erg +ar3inf +arin3it +arin3s4 +ar1int +a3rio +ar2ir +ar4is +ari2su +a3riu +ar2kal +ar2k1ar +ark3aue +ar2kil +2ark3l +ar4klag +ar2kle +ar2klo +ark4lö +ar2kor +ark3s4a +ark2se +ark3she +ark6tre +ar2les +ar3mad +ar2m1au +ar3m2ä +3armee +ar2m1eg +ar2m1ei +ar4merk +arm2or +ar2mum +4armü +ar2nan +arn2el +ar3ni +ar4nin +a1ro +4aroc +aro8ckeng +ar1o2d +ar1of +aro2fe +a3rol +aro3m +aron2 +a2r1o2p +a2ror +aros3 +a2r1ö +2arp +arp3fe +2arr +ar2r1ad +ar2r3as +arre4n1 +ar2r3or +2arsa +ar3se +ar3s2h +2ar3s2i +ar2tau +2artb +ar3t2e +2artei +arter6la +ar2the +art3ho +ar3t2i +2arto +art3r +art4res +2arts +art3ske +2artuc +2aru +a2r1uh +ar1um +a3rumm +a2rü +2arv +arwa2 +2ary +ar2zau +ar2zä +2arze +2arzi +ar2zö +1arzt +arz4tei +arz4tem +arz2t3r +2arzu +ar2z1w +2asa +a4s3aa +a2s3af +a3sag +as2al +as1am +as3art +asa2s +as3at +asau4f +a2s3aug +a2sä +as3ät +a6sca +a4schec +a4schef +a4sch3ei +a6scherg +a3s4chi +a2schm +2ascht +a3schu +a4schum +4a3se +a4seb +a4sec +a4s1ef +as1eie +as1emi +a5sen. +ase4na +ase4n3o +as2er +a4s3erke +as4es +ase4t +a4sex +a3s2hi +as3hir +a2s3i2k +2asim +asin2g +as1inn +2asis +aska3s +as3ob +as1of +a5sol +a5som +as1o2p +as1or +a4soz +a2sö +a2s1p +aspek6to +as2ph +a3s2pi +as3pio +a4spir +as2pra +2as3sa +ass2ab +ass6aus. +ass2e +ass3ein +asse3le +as3s2i +as3ski +as3so +as2spo +as2spr +as2st +as3sta +as3stei +as3sti +as3str +as3stu +2as3ta +a1stas +as4tati +as4tau +a3stä +as3te +ast2el +ast2er +as4t3ese +as4tex +a4s2th +as3tie +as3til +as3to +as4tof +ast3orc +a1str +ast3re +as3t4ren +ast5roll +as3tub +2asu +as2ur +a3sus +a2sü +aswa2s +2asy. +3asyl +a1ß +aße4 +aßen3 +2a1t +4ata +at1abe +at1abr +at2a1f +a5t2a3g +at1akt +ata3l +a3tam +at1apf +at2asc +at3att +a2t1au +a3tau. +at2ax +at1än +4atb +at2c +a2teb +a3tec +ateien6d +at1eig +3a2teli +3a2temg +at2en +ate4na +atens4e +a2tep +ate3r4al +ate3ran +atern2 +ater3st +ate2ru +4ates +ates4sa +a3tet +at2eu +a2tew +at2ex +at3hag +a3t4heb +a2th3in +3athl +a4thr +at2hu +4a3ti +ati3ka +ati4kab +ati6k5erw +a4tinf +ation4 +at2is +ati2sa +ati2se +atis3s +3atla +4atli +3atm +4atma +4atmä +4atmus +ato4man +ato4men +3atomk +ato2mo +at1ort +ato3s +atra4t +a2trau +a2t3rä +at3re +4atri +at3rin +a2t3rom +at4ron +at3rot +at3rü +at2sa +at4schn +at2se +at2si +at2s1o +at2s1p +ats3tät +at3ta +3attac +at4tad +at4t1ak +at4tang +at4tar +at4tau +at2tä +4atte. +at2t3ec +at2tei +att2el +at5ter +at3thä +4atto +at2t3rä +att3s4 +at3t2u +a3tub +atu2n +a3tü +atze4l +atz3ela +atz3elt +at2z1er +a3tzere +at2z1in +at2zo +atz3t4 +at2z1w +a2u +2au. +2au3a2 +2aub +au2bab +au2ban +au2bau +aube4n +au2beu +au2blä +au2bli +au2blo +au2blu +aub2si +4auc +aude4r3i +au2dr +2aue +aue2b +au2ere +aue3rei +au5erein +auer3ö +au5erst. +au3ert +aue2s +au2fa +auf1an +2aufe. +2aufeh +4aufen. +3aufent +auf1er +au4ferk +au2feu +auff4 +auf3ind +1aufla +1aufn +2aufo +auf3ski +auf3t4 +2auft. +2aug +aug2ar +4augeb +4augeh +4augel +aug2er +4augl +4augr +au3gu +au3h +2au1i +au3in +au2is +2auj +auk3t +aule2s +aul4les +au3lü +4aum +au2mal +au4m3ent +au2m1e2r1 +aum3eri +au2mid +au2mil +aum1o +au2mor +aum3p2 +aum3s6 +au4mun +4aun +au3n2a +aun2e +au4nei +au2nio +au2no +au3nu +a4unz +au1o +2aup2 +aup4ter +2aur2 +au3ra +au1rh +aurü3 +au2s1ah +ausan8ne. +au2sau +2ausc +au6schmi +1ausd +2ause. +au4s1eh +2ausen +au4s3erb +au4s3erf +au4s3erk +aus3erp +au4serw +1ausf +1ausg +au2sin +au2sis +1ausl +au2so +aus1or +au2spr +1ausr +3aussag +aus4se. +aus3s4t +aust2a +2auste +au5stein +aust2o +3ausü +1ausw +1ausz +auße2 +2aut. +au2t1äu +2autb +2aute +au4t1e2l +au4ten4g +au4t3erh +2autg +1auto +au4trö +2auts2 +2auu +2auv +auve4 +2auw +2aux +2auz +au3ze +auz2w +2a1ü +a1v +av2a +a3vang +avas4 +ava3t2 +avener4 +2avi +a2vr +2a1w +awi3e +a1x +ax2am +a2xans +ax2e +a3xid +a2xio +ay1 +2a1ya +ay2al +ay2as +a1yeu +ayma4 +ays2 +aysi1 +ay3t +ay2u +2a1z +a3z4a +aza3d +3a4zal +az2i +az2o3 +a3z2u +az2zen +az2z1in +az2zw +ä1a +1ää +ä1b +ä2b3l +äb2s +ä1ce +ä1che +äche1e +äche4n +ä1chi +äch3l +ä2chr +äch4s3a +äch2s1o +äch2sp +äch2st +ächt4e +ä1chu +ä1ck +ä1d +ä2da +äde1s2 +ä2d1ia +ä2dr +äd2s +2ä1e +äe2x +äfe4n +äf2fl +äfig3 +äfigs4 +äf3l +äf3r +äf4ro +äf2s +äf3t2e +äft4s3 +ä1g +ä2g1a +1ä2gä +ägd2 +äge1i +äge2r3a +äge3s +ä2g3l +äg2n +ä2g3r +äg4ra +äg3s4ta +äg3s4tr +1ä2gy +äh1a +2ä3he +ä4h1ei +äher8gebn +äher5t +ä1hi +äh1in +ähl1a +äh3l2e +äh4l3e4be +äh5ler +2ähm +äh3na +äh3ne +1ähnl +2ähr +äh2rel +äh3ri +2ähs +2äht +ä1hu +äh1w +2äi +ä1im +ä1is. +ä3isch. +ä1isk +ä1j +ä1k +äka2la +äk3l +ä2kle +äk4li +ä2k3r +ä1la +älbe2 +äl2bl +älk3 +älks4 +äl2l1a +äl2p3 +äl4schl +äl2st +äl3te +ä1lu +2äma +ä3me +ämer2s +ämi3en +2äml +ämoni3e +2ämp +ämp7f4e +äm2s +ämt2e +2än. +änd2e +än2dr +2än2e +äne2n1 +äne1s +2än2f5 +änft2 +2än3g2e +änge4ra +2än2g3l +än2gr +äng3se +2ä3n2i +än3k2e +än2k3l +än2kr +änk2s +än3n4e4 +2äns +än4s1a +än2s1c +äns2e +änte3le +2änz +ä1on +äo3s2 +ä1pa +1äpfel +äp2pl +äp2pr +äp2s1c +äp4st +1äq +ä2r3a4 +är4af +är1ä +är2b3le +är1c +2ärd +ärde4s +2äre +ä2r1ei +ä2r1e2l +är2em +äre2n +ä2rene +är2er +är2es +ärf2s +är3ge +ä2rind +är1int +är3ke +ärk2s +ärm3arm +ärme1e +ärm3ent +ärm2s +är1ob +är1of +äro2p +ä1rö +är3re +ärse2 +är2seb +är4seh +ärs1er +är2si +är3spu +är2st +är3str +2ärt +ärt4e +är2th +ärt2s3 +ä2rü +1ärz +är3ze +är2zu +är2zw +2ä3s2e +äse3g +äse1i4 +äse5ref +äser4ei +äse4ren +äser2i +äse3t +ä3s2kr +ä2s1p +2äs2s1c +äss2e +äss5erkr +äss5ersa +äss3erw +äs2sp +äs2s3t +ä4s3t +äst2e +1ästh +äs4tr +ä3su +ä1ß +äß1erk +äß1ers +ä2t3a2 +2ä3te +äte3a +äte1e +äte1i +äte3l2 +äte2n +äteo2 +ät1ob +ä2t3r +ät2s3a +ät2sä +ät4schl +ät4schr +ät2s1i2 +äts3l +äts1or +ät2s1p +ät2s3t +ät2tei +ätte4n +ät4tr +ätze3l +ät2zw +2äub +äu2b3l +äu2br +äu1c +äu3d +äude3 +äuder2 +äu3el +2ä2uf +1äug +äug3l +2äul +2äum +äu2ma +äum3p +äumpf4 +äum4s5 +2ä2un +äun2e +äu3nu +2äu3r2 +äure1 +2ä3us. +2äusc +äu4schi +äu4schm +äu3s2e +äuse1i +ä3usg +ä3usk +ä3usn +äu2sp +äus2s1c +1äuß +äut2e +äu2tr +ä1v +1äx +ä1z +â1t +á1n +3ba. +b3a2ba +2babf +2babg +ba2bl +ba2br +2b1abs +bach7t4e +ba4ck3er +back3s4 +ba3d2e +bade1i +2b1adel +2b1adl +2b1adm +b1a2dr +ba2du +2b1af +bah6nene +bais2 +b2ak +ba2ka +ba2k1er +ba2k1i +bak1l +bak3r +ba2kra +ba2kre +ba2lab +ba2l1ak +ba3lal +ba2lau +ba4l3erk +balk4a +balke4 +bal4l3eh +bal4l3ei +baller6e +bal6ler6g +ball6erk +bal3ti +2b1am +b2ama +ba2me +ban2a +3b2and +band1a +ban4dal +ban4dan +ban4dar +ban6deng +ban2dr +ba3n2e +2banf +b1ang +ban3gl +ban4k1a +banker4 +ban2kl +ban2kn +ban2kr +ban2ku +2banl +b1anna +ban2o +2b1ans4 +b1an3t +2banw +b1anz +ba2r3ab +ba2rad +bar3ast +ba2r3at +bar3de +ba2rei +ba3r2en +barer5ei +bar3n +b2aro +3bar2s +bar3sc +b1arz +bar3zw +3bas +ba3sa +ba2sc +bas2i +bas4sa +bas4sei +bas4st +ba2st +ba4t3ent +bat2o +3bau. +bau3b +bauer4l +bauer4s +bau1fl +bau1fr +bau3g2 +b2auk +bau3r +bau1s +bau3s2k +baus4t +b1a2x +ba1yo +3b2ä1c +3b2äd +2b1äh +b2äl +2bärz +b2äs +2bäug +4b1b +b3be +bbe4n3 +bbens2 +bbe4p +bb3le. +bb3ler +bb2lö +b3brec +b3bru +bbru2c +bb2s +bbu1 +2b1c +2b5d4 +bde1s +bdome4 +1be. +3bea +be3an +be3ar +3beb +b1ebb +1be1c +2becht +2b1e2del +bedi4 +be1e2h +bee2l +be1ela +bee4rei +be1erl +be1ert +be1eta +bef4 +2b1eff +be3g2 +begas1 +be2he. +beh5ri +bei3b +2b1eier +bei1f4 +bei4ge. +bei3k4 +bei3l2a +2b1eime +be1ind +be1inh +bein6hal +bein4hi +bei3sc +beis2e +bei1s4t +beit2s +3bek +3bel +be3lag +be3las +be3lec +4be2lek +be2l1en +bel3ere +be2let +bel3f +be3l2i +beli4e +bel3la +belle4n3 +bel3li +be2l3om +be2löf +bel3sz +bel3t +bel4un +1bem +2b1emp +2bemul +1ben +be5nabe +ben3ar +be4nas +be4nat +b2ene +be3nei +be4n3end +be4ners +be4ness +ben2eu +3beng +be4nis +ben3n +5benp +b2ens +ben4s3pa +ben4spr +benst4 +3bensz +2b1entb +2bentd +4benteu +2bentf +ben3th +ben6thei +bent4r +2b1ents +2b3entw +ben3un +ben3z2 +be1o +2b1epi +be1ra +be2r3am +be2ran +ber3a2s +berb2 +ber3d +b4ere +be2re2b +ber2ec +bere3ck +ber4ei. +be4r3eiw +be4rene +ber4erg +ber4erw +bere4sc +berf4 +3berg. +ber4g3af +ber4gal +berg3as +ber4hab +ber4in. +be5r6inne +berin4s +ber3iss +ber3kr +ber3n2a +b1ernt +be2rö +3bers. +ber3st4a +bert2a +bert2e +bert2i +b4eru +ber3ze +ber2zö +3b2e1s +be3s2a +bes4abb +be4sap +be4sar +be2s1er +be2s1id +be3s4lo +bes2po +bes3sa +bess4e +b3esst. +bes3sz +be4stab +beste2 +be6stein +bester4 +bes6terh +best2i +bes3tin +be4stol +bes4to4r +bes3tos +best4r +be4s5trä +be4s3tur +be3s4ze +3bet +be3tam +bet2sp +be1un +be1ur +3bev +3b2ew +2b3e2x +3b2ez +2b5f4 +bfal2 +bfal3t +2b1g4 +b5ga +bge3 +bgel2e +bge5n +bges4 +2b1h2 +b5hä +1bi +3bib2 +bibe2 +biber1 +bi2c +bien3s +bieres4 +bie2s +biet2s +3bietu +bik2a +bi2ke. +bi2kes +bi2k3re +3bil +bi3la +bil2an +bi4l3ans +bi4lau +bil4deb +bi2lei +4billu +bi2lu +2bimp +2b1inb +bin2e +b1inf +2b1inh +bi2nok +2b1int +2b1inv +bi2o3 +biri1 +3bis +b1iso +bi2sp +bis2s1c +bi2st4 +bi3sta +3b2it. +b2ita +bit2an +b2ite +bi3ti +bi2tu +bi3z2 +4b1j +bjek4to +2b5k4 +bl4 +2bl. +bla3b4 +2b1lac +b3lad +b2lanc +b3late +b2latt +b2lau. +b3laus4 +2b3law +2b1län +b2läse +3blät +b2le +3ble2a +b3leb +3blec +b3leg +2bleh +b4lei. +2b3leid +2bleih +b3lein +blei3sc +2bleit +ble3l +2b3lenk +b3lese +2blesu +ble3s4z +b4let +b3leu +2blich +3blick +b2lie +2blief +2blig +bling4 +b2lis +2blis. +b2lit +b3lite +3blitz +b2lo +3b4loc +b3los +3b4lum +2blun +b2lus +3blut +blu4tem +blut1o +3blü +2b1m +4b5n2 +bnas4 +bni2 +bnis1 +bo4a +bo5as +b1o2b +bo3ben +bob3r +bo2c +bo3ch2 +bo3d2 +boe1 +bo2e3i +2b1of +bo3fe +boh3re +boh4rei +boh2u +bo1is +bo2lan +bo2lau +bol5le +3bon. +bon2an +bon2da +bon2d1e +bo2ne +2b1onk +3bons +boo2l +boo2ti +b1op +3bor. +bo1r2an +bo2r3as +bo4rä +bor2da +bor2d3r +bo2rei +bo4rig +bor2s +b1ort +bor4ter +bor6t5rat +bo4ruh +bo2sc +bo3se +bo4s3p +3bot +bote3n4e +bo3th +bot2st +bot3t +3b2ox +bo2xo +bö2b3 +2böf +2b1öl +bölk3 +2b1p4 +bpa2g +2b1q +b2r4 +2br. +b4ra. +2b3rad +2b4rah +b4ra3k +brast4 +2b3rat. +bra4t3er4 +2b3ratg +3brä +4bräd +brä4u +2bre. +6b5rechte +2b3red +2b3ref +2breg +b3reif +2brek +breli1 +3b4rem +2b3rent +2breo +2b3rep +b4rer +bret6t5en +bri2da +brie4fa +2b3riem +b4rien +bri2er +b3ries +2brigk +b4rina +2b3rind +b4rio +b4risc +b3ritt +2b3roh +2b3rol +b4ron +2b3rost +bro4tr +brot3t4 +2b3rou +3b4rö +b4ruc +2bruf +b4rum +2b3rund +brus4 +brust3 +bru2th +3brü +4b3rüb +2b1s +b2s1ad +bs2am +bs3amb +b4s3amt +bsat2 +bsau2r +b4s3är +b3s2äu +b3sc +bsch2 +b4schan +b6schef +bs2chi +b4sco +bs2cu +b3se. +bse2b +b3sel. +bse2n1 +b3sen. +b2s1ent +bs1erf +bs1erg +bs3e4r3in +bs1erk +bs1ers +b3s2es +b3set +b2sim +bsi4t +b4ski +bs2ku +b4sl +b2s1of +b3s2oh +b4sop +bso2r +b2sö +b3s2pi +bs2pl +bs2pu +bss2 +bs2t +bst1a2b +bst1ak +bst3ank +bs4t1as +b3stä +bs3tät +bst1er +bst3h +b3stic +bst3ink +b2stip +b3sto +b4stob +b4stod +bs4tol +b4stor +b3stö +b4strac +b2s3trä +b4s3treu +bs4tri +bst3ro +b3stü +b4stüb +b2s1un +bs2zep +bs2zi +4b1t +bta2s +btast3r +b5te +b2t3h +b3ti +bti2s +bt4r +btran2 +bts2 +b3tü1 +buche4 +bu4chec +bucher4 +bu6ch5ers +bu2chi +buch3sp +bu2e3 +bu2f +bul2l3a +2bumf +2b3umk +2buml +2b3umr +bun4d3er +bunde4s +b1une +bung4 +b3un3gn +2b1unh +bur1c +b2urg +burg1a +bur4gan +bur4gar +bur4gin +bur2gr +bu3r2i +2burn +b3ursa +burts3 +bu2sa +bu2sc +bus3cha +bu3sche +bu6schei +busch3w +bu2sin +bu2s1p +bu2su +bus1un +2büb +bü1c +bügel3e +2b1v +4b5w +3b2y1 +by3p2 +bys4 +2b1z4 +b5ze +bzeit1 +1c2a +cab4 +ca3bl +ca2c +ca2e3 +ca3g2 +ca1h +cal2a +cal2f3 +cal3t +3cam +2can +cana3 +ca2pe +car3b +car5n +carri1 +car2s +ca3s2a3 +cas5to +ca3t2h +ca1y2 +cä3 +cäs2 +c1b +2cc +c1ce +c1ch2 +cchi1 +c2d2 +c3do +2cec +1ced +ce2dr +ce1er +2cef +ce1i +ce3in +2cek +3cels +cen3a +ce3nu +ceo2 +1ce1r +cere1 +cere3u +ce3r2i +ce3s4h +1cet +ceta2 +cet1am +ce1u +1cé +c1f +c1g +c2h +4ch. +2chab +ch3a2b3i +cha2ck +2chaf +2ch1a2g +2ch1ak +chal6l5ei +3chanc +chan3f +ch1ang +4chanl +4chanz +3chao +4char. +3chara +3chard +3charta +cha2sc +chasi1 +1chato +2chatt +ch5austr +chau3t +ch1äh +ch1ärm +ch1äs +1châ +2chb +2chc +2chd +che3b4 +ch3e4ben +ch3echt +ch1edi +1chef +3chef. +che4fer +3chefs +2cheh +2chei +ch1eim +4chelem +che4ler +3chemi +2chemp +che4neb +che2no +4chents +4chentw +cher3a +4ch3erbs +6chergeb +4cherke +cher6zie +ch3es4s +ches5t +2ch1e4ta +2ch3e4x +1ché +2chf +2chg +2chh +1chia +4chic +chi3na +4chind +3chines +2chinf +2chinh +2ch1ins +2ch1int +2ch1inv +1chip. +1chiru +2chiso +2chj +2chk +2chl4 +ch2le +chle2i +ch2lu +4ch2m +2chn4 +chner8ei. +c4ho +2chob +cho2f +ch1off +chof4s +ch1oh +cho3l2a +ch1orc +ch1ori +ch2os +ch3öl +3chör +2chp +ch2r4 +2chra +ch3rad +2chre +ch3rh +4chrit +3chromo +3chron +4chs +ch2spo +ch4stal +2cht +ch2tru +2chuf +2chuh +2chum +2ch1unf +2chunm +2chunt +2chur +ch1urs +2chut +chut4t +4chü +2chv +4chw +1chy +2chz +ci2ak +ci1c +ci1es +cill2 +ci2na2 +c1int +ci2s1 +1cit +c1j +c2k +4ck. +ck1a +1cka. +2cka2b +2cka2c +ck2ad +1ck2ag +2ckal +cka2m +2ckan +2ckap +cka4r1 +1ckat +ck1ä +2ckb +2ckc +2ckd +1cke +2ckef +4ckeff +2ck1eh +4ck1ei +2ckemp +cke4na +6cken6sem +4ckentf +4ckentw +cke2ra +ck2ere +6ckergeb +4ck3er4hö +ckerk4 +ck2ern +2cke2ro +ck1err +6ckerzeu +4ckese +4ckex +2ckf +2ckg +2ckh +1cki +2ck1id +ck1in +3ck4is +2ckk +2ck3l +2ckm +2ck3n +2ck1o2 +ck3ot +ck3ö2 +2ckp +2ck3r +4cks +cks2al +ck3sc +ck4spen +cks4tri +2ckt +ck3te +ckt2i +1cku +2ck1uh +2ck1um3 +2ckunt +2ck1up +2ckü +2ckv +2ckw +1cky +2ckz +c2l2 +cle4a +clet4 +clin2g +cli2p1 +clip3a +clo1 +clo2ck +1clu +clu4b +c2m2 +c3me +c3mu +1c2o +3coa +co2c +co3ch +3co2d2 +co4de. +co3di +cof3f2 +coi4 +co1it +co2ke +co3la3 +co2leu +co5l2o +3com +com4te. +comtes4 +con2ne +co2pe +co1ra +cor2da +co4re +cor3t +cos3t +co4te +coti2 +cô4 +2cp +2c1q +1c2r2 +c3rä +3cre2 +4cree +cre4mes +cros4 +cry2 +2cs +cs2a +cs4f +c2si +c1s2ti +c1s4tr +4c1t +c3ti4 +ctio2 +ctur6 +1c2u +2cua +cu2e +cu2p3 +cussi4 +c1w +1cy +c1z +3da. +da1a +2d1ab +d3a2bak +d2abä +d2abe +d3a2ben +d3a2bi +d3a2bo +dab4ra +da2bri +da3brie +d2ab4rü +d1ac +d2ac. +dach3a +da2cho +4d3achse +d1ad +da2de +dad4r +d1af +2daff +dafo4n +d1ag +dagi4 +dag2o +dah3l +da1h2o +dail5 +da1in +2d1air +da1is +da2kro +dal2a +2d1a2lar +dal3b2 +4d1all +da3lö +2d1alp +d1alt2 +2dalte +da1lü +3dam +d1amma +4d1ammä +damo3 +d2amp +damp7f8erf +4d1amt +3d2an. +d1ana +da2nan +da4nat +2danb +dan4ce. +d1and2 +2danda +d2andy +3dane +4d3anei +2danf +d1ang +2danh +d2ank +dan2kl +dan2k1o +dan2kr +2danna +d1a2no +2d1ans +2danw +d2anz. +2danzi +2danzü +2d1ap +d2aph +da2por +4dapp +4daq +da2r1a +2darb2 +2d3arc +dar2da +dar2d1e +dare2 +daren1 +dar3g +3darl +dar2m1a +dar2m1i +dar4mu +da2r3o +3dars +2d1art +dar2th +dar2tr +da2ru +d1arz +da1s2 +da3sh +d1as3p +das4t +d1asy +da3t2e2 +date4n +4d3atl +4datm +da2tom +dat2st +2d3atta +3daub +2daud +dau3e2 +dauer3e +2d3au2f +2d3aug +2dauk +da3unt +2d1aus3 +3daw +d1ax +3däc +2d1äg +2d1äh +2d1ämt +2d1änd +2d1äng +2d1äp +2däq +2därz +2d1ä2u +dä3us +2däx +2d1b4 +dbe2e +dbu2c +2dc +d3ch +4d1d2 +d3da +d3dä +d3de +d3dh +d5do +1de +dea2d +de3alo +de3ar +de3a2t +d2eb4 +3debü +de1c +de4ca. +de2cka +deco3 +de2del +de2dit +2de3e4 +de2fa. +2d1eff +def4l +deg2 +de3gl +deh2a +dehe2 +3dehn +2d1ehr +d1ei +3d2eic +2deid +de3i4den +4deie +2deig +de3il +3d2eim +4deime +4deinb +dein2d +de3inse +dein6sta +4deinw +2deise +d4e1ism +dei2sp +2dekz +de2l1ac +del4ade +de3lak +de4l3aug +del3änd +del3b2 +del1ec +delei4g +de3lein +2delek +2delem +de2len +deler2 +deler4r +2delf. +2delfm +3delik +del2la +dell3au +del2l1ä +delle2 +del4l3eb +del4lei +del4l3er +de2l1ob +del2se +del2so +del2s1p +del3t4 +dem2ar +2d1emb +dement4 +de6mentg +dem5ents +de3min +2d1emot +2d1emp +d2en. +den2am +dend2 +de2n1e2d +de4n3end +4denerg +den2es +4d3en4ge. +de2ni +denk3li +denko4 +de2nos +dens4am +den6scho +4den4sem +den6sere +den6s5tau +2dentd +4dentf +2d1entg +den3th +2dentn +2dentw +2dentz +de3nu +den6zers +de2ob +2deol +de1on +depi2 +dep4l +2depoc +dep5t +d4er. +dera2b +der3af +dera2n +de3rand +de2r3ap +de1ra4s +de4r3asi +der2bl +4d1erbs +2derdb +de2re2b +de4reck +de4r3ei4s +d4eren +de4r3end +de3r4erb +de3r4erf +derer3n +der3ero +derer4t +derer6ze +de2r1eu +derf4 +d4erfl +d2erhü +derin4f +de6rinnu +derin8teg +der3k2 +4derklä +d2erm +de1ro +de2rop +derö2 +der3r +derst2 +der3sta +dert7ende. +dert4ra +6dertrag +der8trage +3de3ru +de4ruh +de4rum +2d1erz. +2d1erzv +d2es. +de2sa +des1ah +de4sam +de2s1än +de2seb +de4se2h +de2sei +2d1esel +des3elt +de3sem +des4end +desen3e +de2set +de4sin +des1o +de2sor +de2s1p +de3spe +dess2 +dess4t +dest5alt +de3stel +des6temp +de5stern +des4tex +de1sto +dest5rat +de3stri +des4tum +de2su +des1un +3desw +det2 +de3ta +deten4t +de2thi +2d3etw +2d1eul +de1un +de1url +de3us +2d1e2vid +devil2 +de2xer +de2xis +2d1f6 +2d1g2 +dgas3tr +d2ge. +dge3r +dger2e +dge3s +d2gesh +dge2t3a +dge4t1e +2d1h2 +dha1s4 +4dho +d3hu +1di +di2a +di3ar +dia3s4 +diat4 +di4ath +3dic +di1ce +di3chl +dicht6er +4d3i2co +d2ida +2d1ide +2didy +di2e +di3e4d +di3enb +die4neb +diener6l +di3e2ni +dienst5r +dien3z +di3ers. +dies1c +di3e2th +3dif +3dig +dige2s +dig4n +dik2a +dil2s3 +2d1imb +2dimp +din4a +2d1ind +di3n2e +2d1inf +3ding +2d1inh +2d1in1it +2d1inj +2d1ins +2d3int +2d1inv +di2o3b +dio4n3i +dion3s4 +di3ora +dio5s2 +di2osk +di1p4 +di3pt +d1i2ra +di4re. +di2ren +di2rin +di2ris +2d1irl +2d1irr +di2s1a2 +2diso +di2sp +di3s4per +2d1isr +dist2 +di1s4ta +di2s3te +di4stra +di4sz +di2ta +dite1c +di4t3erl +di4t3erm +di4t3ers +di1the +di2tin +di2tob +di4t3r +dit3s +di2t1u +di5v2 +di3z2 +2d1j +2d1k4 +4d1l2 +d3la +dla3g +dlap4 +d3le +dle2ra +dli4f +dl3m +dl3s +2d3m2 +4d3n2 +d5ne +dni2 +dnis1 +do5a +d1ob +3d2oba +d1of +do2fe +2d1oh +doll2 +d3o2ly +do2mal +do2mar +dom2e +domen1 +do4ming +do2mu +do5n2a +do3nan +donau1 +doni1e +2dope +2d1opf +do1r4a +2d1orc +2d1ord +dor2f1a +dor2fä +dor2f1i +dor2fl +dor2fo +dor2fr +dor2f3u +2d1org +dori1 +d2orn +2dort +dor4ter +dor4tr +d2os. +dose4 +do5s2k +2dosm +dos3s +dost1 +dos4t3a +doste4c +dos4tel +dos6teng +dos4tes +dos4ti +dos4tr +do4s2tu +do3ta +do2t3o +do2tre +do3un +dow2s +dox2 +d1ö +dö2d +dö2f +4döl1 +döll2 +d2ön +3d2ör +dö2s1c +2d3p2 +dpass3 +dpo2st +2d1q +d2r4 +3d4ra. +3d4rab +2d3rad +2drahm +2d3rak +3d4ral +d3ramp +d3rand +dran3k +2d3rast +2draub +2d3rauc +d4rauf +2draum +2draup +2dräd +d4räh +2d3rät +2d3räu +4dre. +2d3rea +d4rea. +d4reas +3d4reck +2d3ref +2dreg +3d4reh +dre2ha +2d3reic +3d4reie +d4reiv +d4rej +2drek +dreli1 +4drem +4d3ren +4d3rep +4d3rer +4dres. +d4resc +2drese +dres6sei +d4rew +2d3rez +2d3rh +d3ri +d4ri. +3d4ria +d4rib +2d5ric +d4rid +d4rie +d5rieg +3drif +4driff +d4rift +d4rik +d4ril +d4rin. +2d5rind +2drip +3d4risc +2drisi +2driss +3d4rit +4dritu +2d3rob +d3roc +d3rod +d4rog +2drohr +3d4rohu +d4roi +2d3roll +2d3rose +d4ross +2d3rost +2d3rot +2d3rou +2d3rov +d3row +drö2sc +d5rub +3d4ruc +2d3rud +2d3ruh +4d5rut +drü1b +drü5cke +3d4rüs +2d1s +ds3ab +d2s1alk +d4s1amt +d2san +ds3ane +ds3assi +dsau2 +d2saut +ds1än +ds2äu +4dsb +d4schef +d4schin +dsch4r +d3s2co +d2scr +d2s1e2b +dse2e +d2s1ef +ds1eh +d4sehe +ds4eign +d2sein +d2s1emb +dsen3er +d2s1eng +d2s1ent +d2s1erf +d2serh +d2s1erk +ds1err +d2s1ers +d2s1ert +d2serz +dse4t +d2s1eta +d2s1ev +d2sex +d3sha2 +ds2hak +d4shal +d3sho +d4shor +d2sid +d2s1im +d3s2inf +d3s2kal +d3s2kel +4dsl +d4sli +d3soh +d2sop +dso2r +ds1ori +d2sö +ds3part +ds1pas +d2s1pat +d2spä +d2s1pec +d4speri +d2s3ph +d3s2pi +ds2por +d6sporto +d3spri +d2spro +ds2pu +dss4 +dst2 +d4stag +d2stas +ds3tauf +d4s3täti +d2ste +d3stec +d3stei +d4steil +d5stell +d4stem +d4sten +d3s4tern +ds2ti +ds4til +ds4tip +d4stoch +ds4tol +d5strei +ds4tri +d3s4tro +ds2tur +ds1ums +d2sun +ds2zen +2d1t +dta2be +d3t2ac +dtach3 +dta2d +dt2ag +dta2n +d3t2as +dt2ax +d5tea +d2th +d4thei +dt3hi +dt3ho +dt4hy +d3to2 +d4to4b +dt2op +d3tö +dt3r +dtran2 +dts2 +dt3sa +dt5st +dtt4 +dt2un +d3t2ur +d3tü +d3ty +1du +du1alv +du1ar +dub3l +du2bli +du1ce +du2f +2d1ufe +duf4ter +duf4to +duf2tr +2d1uh +du1i +du2kr +du4l3art +2d1umb +2dumd +2d1u2m1e +2dumf +2dumg +4d3umk +2duml +d2ump +2dumr +2d1ums +d2ums. +2d1umv +du2n +2d3un3d +dund2a +dun4de +2d1unf +dung4 +2d1ungl +2d1uni +dun3ke +dun2kl +2dunr +dun2s +2dunsi +dunst3r +2dunt +2dunw +2d3unz +du1os +dur2 +dur3au +durch3 +2d1urk +2d1url +2d1urn +2d1ursa +2d1ur3t +du4schn +du4schr +du4sch3w +2düb +d3über +düns3 +2d1v2 +4d1w +dwa2 +dwa4r +dwes2 +dwest1 +1d2y +4dyl +3dyn +dy2sp +4d3z2 +2e1a +e3ab +ea2be +e4abi +ea2b3l +ea2bo +ea4br +ea2c +eadli4 +ea2dr +ea2g +ea3ga4 +ea3g4l +eakt2 +e2akta +e3akto +ea2la +e3alei +e4alem +ea4l3ent +ealer2 +e3a4lerg +ealer4t +e3alex +e3a2lin +e2alo +e2alti2 +eal3tr +ea2l3u2 +eam3 +e2am4e +eam1o +eamt2 +ea4na +ean3a2r +ea4nä +e3anf +e2ano +e3ar. +ea2ra +e2are +e4are. +ea2r1ei +ea4rene +e4arer +e4ares +ea2ro +e3arz +e3a2sc +easin4 +ea4sp +eas3s +eate2 +eater1 +e3ath +eat3s2 +e3at5t4 +eatu3 +e3aue +e3auf +eau2fe +e4aufo +eau3g +eau3n +e2av +e3ä2 +e1b +2eba +e3bak +eba2p +e3bän +2ebea +2ebec +2ebed +ebe1er +2ebeg +eb2el +ebe4ler +ebe2lo +ebenen3 +2eber +ebe4ras +ebert4 +4ebes +ebese2 +ebe4s3eh +2ebet +ebet4s +2ebew +2ebh +2ebi +2ebl +e3blä +eb3le. +eb3ler +eb4leu +e3blie +eb3lo +eb2lö +2ebo +e2bob +ebot2 +ebö2s +2ebr +eb4rea +2eb2s1 +eb4sche +ebse2 +ebs3in +ebs3pa +ebs3tau +eb4stät +ebs3tem +ebs3t4h +ebs3ti +eb3str +2ebu +e2bunt +ebu2t1 +eby4t +2e3ca +2e3ce +ech1am +ech1ä +2e1che +ech1ei +ech2en1 +e6ch5erzi +e1chi +ech3l +ech3m +ech3n +e2cho. +ech1ob +ech3ö2 +ech3r +ech4ri +ech5sel +ech3ser +echst5re +ech3t4ei +ech6terh +echter8ha +e1chu +ech1w +e1ci +eci4a +ec4k +ecke4n1 +e4ckerr +eck4sta +2eckt +3eckty +2e1cl +2eco +e3cr +ec1s +2ect +e1d +ed2a +ed2dr +ed2e +ede2al +ede3n4er +edens1 +eden4se +eden4sp +edeo2 +ede2r +eder3a +ede4ran +eder3t2 +edes2t +ed2i +e3di. +edi3an +2edip +edi6teng +e3d2o +ed2ö +e3drei +ed2sal +ed4seh +ed2s1es +ed2si +ed2s1o +ed2s1p +ed2s3tr +ed2s1u +edu2s +e3dy1 +edys4 +2ee +ee3a4 +eeb2l +ee1c +ee4ce +ee2cho +e1e2ck +e2ed +eede3 +eede1s +eed3s2 +ee3e2 +e1eff +eef4l +eeg4 +e1ei +ee3ing +eein4se +eeis3s +eel2e +e3e2lek +eele4n +eel2ö +e2e3m2a +ee3mä +e1emb +e1emp +e1en +eena2g +e2e3nä +e2enc +e2e3ne +een1er +e2eno +een3s +een2z +ee3o +e2ep +ee3po +eer3as +e1erbt +e1erd +ee3re +eer1ei +ee4r3en4g +eer2e2s +eer3k +ee1ro +ee1rö2 +eer2ös +eerst4 +eert2 +ee3r2un +e1erz +e2e1s2 +ee3sh +ees3k +ee3sp +ee3s4t +e2et. +eet2a +ee2tat +ee2th +eet2i +eet4r +ee2tu +ee1u2 +e2ew +eewa4r +e1e2x +e1f +e2f1ad +ef1ana +ef1ar +e2farc +e2fat +2efä +e2fäu +2efe +e2f1e2b +e3fef +efe4l3ei +ef1em +e2femi +efe2n1 +3e2f1ene +e2fent +efer5f +efeuil4 +3effek +1effi +ef2fl +2efi +ef1id +e2f1ins +efi2s +2efl +ef4le +e3f4lu +e3flü +2e3f2o +2efr +ef4reih +ef3rol +ef3rom +ef4ru +ef4rü +efs2 +ef3so +ef3sp +ef2tan +ef2tei +2efu +e2fum +2efü +e1g +eg1a2m +eg2anz +egd4 +e3ge +ege4l3au +ege8l7ei8er +ege4ler +ege2lo +eg2en +ege4n1a +ege6nero +ege2ra +ege4s5tr +ege1u +2egi +2egl +e2glo +e2glu +e2gn +eg3nä +eg3ni +ego1p +eg4rö +eg4run +egs2ag +eg4sal +eg4s3an +egsau3g +eg3se +eg4sei +egs2e3l +eg4sin +eg4sk +eg4so +egs2pe +egst2 +eg4sto +eg2th +egung4 +egus3 +2e1ha +eh1ach +e3h2ah +eh2al +ehalt4s +e3hand +eh1arm +e2harz +e3haut +e1hä +e1he +eh1eff +eh1ein +e3helf +eh1elt +e4hense +e4h3ente +ehen4tr +1e2hep +2eher +ehe1ra +e2h1erf +e2h1er2l +ehe3str +2e1hi +eh3im +eh1lam +eh2l3au +eh1lä +ehl3ein +eh4lent +eh5l2er +ehlo2 +ehl1or +ehl2se +ehls2t +2ehm +eh2mab +eh4mant +eh3mu +2ehn +eh3na +eh3no +2e1ho +eho2f +eho2l +eh3oly +ehö4rer +eh2r1a2 +ehr1ä +ehr1e2c +eh2rei +eh2rel +ehr6erle +ehr4ern +ehre3s +eh4rin +ehr1ob +eh1roc +ehr1of +eh1rö +ehs2 +eh3sh +ehst2 +eh1ste +2eht2 +eh3ta +eht4r +2e1hu +eh1unf +e2huni +e3hur +e1hü +eh3üb +eh1w +e1hy +2ei3a2 +ei2bar +ei2bli +ei4blu +eibu4t +ei4b3ute +e4ic +ei1ce +ei2cho +e2id +ei2d1a +ei3de +eid4ein +ei4deis +eid5erre +2eidn +ei3do +ei4ds +ei1e +eie2b +ei3e2l +eie2m +4ei3e2n +eienge4 +eien3s +eie2t +4eif. +ei1flo +1eifr +2eig. +2eiga +eig2ar +2eigä +2eigeb +2eigeh +4eigeno +5eigensc +2eig2er +2eiges +2eigew +2eigi +ei3gl +ei4glo +1ei2g3n +ei4g3rat +2eigre +2eigrö +2eigru +2eigrü +2eigs +2eigt +2eigu +4eih +ei2hum +ei2kak +eik4am +eik2ar +eik2i +eik2l +ei3k4la +ei3klä +e2il +2eil. +ei2lam +eila2n +eil3ane +ei4lant +ei4lanz +ei2lar +2eilb +eil3d4 +ei4lein +eile2n1 +ei2let +eil3f4 +eilm2 +ei2lob +eil2ö +2eim. +ei2mab +ei2m1ag +eim3all +eim3alp +ei2m1or +2eimp +eim2p4l +eim3sa +ei2mur +e4i2n1a +ei4nac +eina2d +ei4n3an +ei4na4s +ei4n3at +ei4n3ä +ein6derk +ein3ebe +ei2nel +ei4n3en4g +ei6nen6se +ein5erbe +ei4nerf +ei4nerk +einer6sc +ei2neu +ein4fiz +2einfo +ein4fo. +ein4fos +ein3g2 +3einger +e4ingr +e2inhä +ei2n3ie +e1init +ein3k4 +ein6karn +3einkä +e2inl +ein3n2 +ein4nen +ei2n1o2 +3einric +e4insa +3einsat +e2insc +5einschä +ein6stal +ein6terv +ein4tol +3eintö +1einu +ei3o2 +ei1p +eip2f +2eir +eir2c +ei3re +e1irr +e4is. +ei2sa +ei3sas +ei6schwu +ei4serg +ei4s3erl +ei6s5erst +ei4s3erw +1eisho +ei3s2ky +eis2pe +e2iss +eisser6s +ei1sto +eis4tol +ei2sum +ei2sur +1eiswo +e2it +ei2t1a2b +ei2tal +ei2tan +ei2tap +ei2tar +ei4tat +2eitä +ei2tän +eite4ra +ei4tess +ei2t3h +ei2tin +ei2tor +ei4trau +ei4tro +eitsa4g +eitt4 +4eitu +ei4t1um +ei2t1ur +eit3z2 +eiv2 +eive4 +ei2zar +eiz1in +2e3j +e1k +e3k2a +2ekä +1ekd +ek2e +e3ke. +e3ke4n +e3kes +e3key +e3k2l +ek4n +e3k2o +ekor4da +2e3kr +ek4s1p +2ekt +ek2tan +ek5t6ante +ek2t3at +ek2tä +ek2te2l +ekt3erf +ekt3erk +ek4t3er4z +ekt2o +ek2t3o4b +2e3ku +ekur2a +e3k2w +1ekz +e1la +ela2br +el2abt +el3abu +ela2ck +el3ader +el1af +2elai +e2l1ak +el1a2m +el2a3mi +e3lamp +el1ana +e4landa +e2l3a2ne +e2lanm +e4l1ans +e2l1ant +e4lanw +e2l1anz +2elao +e2l1ap +e2l1ar +ela2re +el3a2ri +el3arr +ela2s +el1a4si +el1asp +ela3su +2elat +el3aufw +2e1lä +2eld +el4d3erf +elder4p +elder4s +eld5erst +el3des +el3dri +eld3s2 +4e3le. +e3lea +elea2r +ele2c +el3echt +4eleh +el3ehe. +2elei +e6l5ei6ern +e2l1ein +e3leine +1elek +e2l1el +1e2lem +2e3lem. +e3lema +ele2mi +2el1emp +2e3len. +elen1e +elen4k3l +e4lense +e2l1ent +e3lep +2eler +e3ler. +eler2a +el1erd +e6lereig +el1erf +e4ler4fa +e4lerfi +e2lerg +el1erh +el1erk +e2l1erl +e4l3ernä +eler2ö +e2l1err +el1eru +el1erw +eles2 +e2l1ess +e2l1e4ta +ele2ti +elet4ta +el1evo +el1ex +e3lex. +1elf. +elf2er +1elfm +1elft +elgi5er. +elgi5ers +el3g2l +eli4are +e2l1id +2e3lie +eli3ef. +2elig +e2lim +elin3a +eli3no +el1ita +2elk +elk3s2c +el4larb +el4lart +el3lär +el5le. +ell3ein +ell3eis +el4lel +el5lend +ellenen5 +ellen5s +ell2er +el3les +el2lim +1ellip +el2lor +ell2ö +ell3sp +elm2e +elm3ein +2eln +2elo +e2l3oa +el1obe +e2lof +e2lol +e2lonk +e2l1or +e3lore +elo2ri +e3lot +e3l2ov +2elö +elö2s +el3p4 +el4s5ein +els2ph +el5stern +el2sum +el4tans +elte4m +el5ten. +el4t3ent +elter4b +elter4f +elter6le +3elter4n +elter6sc +elte2s +el4tesc +el3the +2e1lu +el1uf +e2l1um +el1ur +el3use +elu2t +el3uto +e1lü +2ely +e2lya +el3z2ac +el2zar +el4zene +el2zwa +2elzy +e1m +e2m3a2b +em1alk +e2manf +e2m1ano +e2m1ans +em1app +e4m1a4s3p +em1aus +2emä +em2äh +e3mäs +1emba +1embo +3embry +em2dä +emd1r +em2dra +2eme +e2m1e2b +e2mef +e2mele +e3m2en +emen6gel +emen3ta +emen4t3h +e2m1erl +em1erw +e4mesu +3e2meti +e2m1i2d +2emie +emi2ei +e2mig +emi3k2 +em1im +2emin +emi3n2a +e3mind +em1int +1e2mir +e3misc +1emiss +emi3tr +emma3u +em2m1ei +e2moa +e2mof +e2mop +emo3s +1empf4 +em3pfl +em3po +empo1s +em2sa +em4scha +em2sim +em2spr +em2st +em3t4 +1e2mul +e3mur +2emü +e2na +4ena. +e4n3a2b +4ena2c +e4n3ack +2e3nad +enadi4 +e4naf +4enah +en3ak +en1al +e4nalb +e3nale +en2alg +ena3l2i +e4nalk +e4nalm +e4nalo +enal3p +4en1am +ena4n +e4nand +en3ane +e4nant +e4nanz +e4n3a2p +en3a2re +en3ark +en3aro +en1as +ena2sc +e4nast +2enat +4e5nati +e4natl +enat4s +e4n3att +4enatu +enau2f +en3aug +e4n3aur +e4naut +en1a2x +en3a2z +e2n1ä +e4när +en2ce. +1ency +end2ac +en2dal +en4dang +2endel +ende4lä +en4d3es4s +en2dex +en3d4ort +end3rom +end3s4au +end3s2l +end3s2p +end3sz +en3d2um +en3d2ü +2ene. +ene4ben +en1e2c +e2neff +en2eid +e3neien +e4neige +4eneigu +e4nein +e4neis +en1e4kl +e2n1el +ene4le +2ene2m +e2nemi +2enen +e4nense +e4n1ent +en4entr +e2n1ep +4e3ner. +en2era +e2n1erd +e4n3erei +e2nerf +en4erfr +1energ +e2nerh +e2nerk +e2n1erl +e4nermi +e4n3ermo +4enern +e4n3erne +ene2ro +e2n1err +en1ers +4eners. +e2n1ert +en4ert. +e2n1eru +e2n1erw +2enes +e4n1e2sc +e2n1ess +en1eta +e2neth +en1eul +e2n1ev +e4ne2x +en3f +enf2a +enf2u +1engad +1engag +en3g2al +enge3r4a +en3g2i +en3gn +eng2o +1engp +eng4ra +eng3se +2eni +e3ni. +e3nic +e2nid +4e3nie +eni3er. +eni3erp +eni5ers. +en3i2ko +en3ill +eni4m +en1ima +en1imi +e2nin +e3nio +eni2ö +e2nir +e4n3iso +e3nit2 +e3niv +enk3aus +enk3erg +en4k3erk +en3k2ü +en2nef +en2nel +en4ner4f +enn3erg +en4n3erl +enni6ger +2enniv +enns2 +enn3ste +e2n3oa +e2n1ob +e3nobel +eno2br +e2n3oc +e2nof +en3ol +eno2ma +e2n1op +e2n1o2r +en2ora +eno4ri +4enorm +en1ost +4e3not +eno2w +2e1nö +en1ö2d +en3sabb +en3sac +en2san +en5sche +en2seb +1ensem +ensen3e +ens3ere +en2sid +en3spo +ens4por +enst5alt +en4s3tät +ens4tel +ens6temp +ens2th +2ens4to +enst2ü +ens3umf +en5t2ag +en4tanm +en4tanw +ent4ark +1entd +en3t2el +ente2n +en4terb +1entf +2entfo +2entfö +1entga +3entgeg +en2thi +1enthu +1enthü +en4tid +1entla +1entn +en2t1os +2entö +en4t3rol +1entsc +1entso +ent4sto +1entw +4entwet +3entwic +1entz +e2n1u +e3nu. +e4nur +2enu4t +e4nuto +e1nü +enü1st +4enwü +2e1ny2 +enz2äp +1enzep +enz3erg +en4z3erk +en4zerl +en4z3erm +enz5ersc +enzlan4 +enzo2l +e1ń +4eo +e1o2b1 +eo3ben +eo3bl +eo3br +eo1c +eoch2 +eo3dr +e1of +eo3g2 +e1oh +eo3la +e3o2ly +eom2 +e1on. +e1ond +e1onf +e1onh +e1onl +e1onp +e1onr +e1ons +eo1o +e1opf +e1or +e3or. +eo1ra +e3orb +e3ord +e3ors +eort2 +e3orw +eo1s2 +e3os. +eo3se +e1oste +eot2e +eo1ul +e1ö2 +e1p +2ep2a +epa2g +epas6ser +2eper +e3p2f4 +1e2pid +e2pig +e2pik +1e2pile +e3pio +1epis +2epist +1e2pit +ep3le +1e2poc +eport4 +1e2pos. +ep2p1a +ep2pei +eppe3l +ep4pl +ep2pr +2epr +ep3sh +ep2tal +ept2an +ep2tau +e3pu +epu2s +4e3q +er1a +e3ra. +e2rach +e3rad. +e3radi +e2radj +e2radm +e4radmi +e4r3adr +eraf4a +era2g +e1rah +e1rai +er3aic +e2rak +e3rake +e1rald +eral4eb +er3alke +e2r3all +er2an. +era4na +eran3d4 +e3rand. +e4rangr +e2ranh +e2rano +e1rap +er3apf +er3apr +e2rar +er3are +e3rari +er3arr +e3ras. +er3asc +e1rast +era2ß +e3rati +e2ratl +er3att +e1raub +e1rauc +er3aue +erau2f +er3aug +e2ra2v +e1raw +e2r3ax +e1raz +e1rä +er1äf +er1äh +er1ä2m +er1äp +e2r1äs +er1ätz +3erbarm +erb2au +erb2e +erb2sp +er1c +er3chl +erch2o +erda3me +1erdb +er3de +2erdec +2erdel +er4d3en4g +erd3erw +erdes4t +erdeu2 +1erdg +er2dob +erd3st +2erdy +4ere. +er1eb +ere4ben +e3r2ech +er3echs +er1e2ck +er1edi +ere4dit +er1eff +er1e2h +ere4i +6e3rei. +6e3reib +er1eig +4ereih +e4r3eime +e2rein +er3eis. +er5eisar +er3eisb +er3eisf +er3eisr +erei5str +er1e2l +e2rele +ere3lev +ereli1 +2e3rem +e4r1ema +er1emb +e2remp +e4remu +2eren +e3ren. +e3rena +eren1e +e4rense +e4rentn +e4rents +e3renz +eren8z7en8d +er1epe +2erer. +2ererb +er3erf +erer3fa +e4rerfo +e2r1erh +e2rerk +erer4kl +e2rerl +4erern. +e4rerne +e2rer2o +erer4ri +er1ers +4erers. +e8rersche +e2rert +2ererv +2ererw +2eres +er1ess +eres3sk +er1e4ta +ere2th +e4r1e2ti +3er1eul +ere4vid +erf2e +er3for +erf4r +4erfür +er4g3are +4ergebi +3ergebn +4ergebü +4ergeha +4ergehä +ergel6s3 +erg5elst +4ergeni +3ergiee +er2gop +4ergrem +erg3s +ergs2o +ergs2p +ergs4t +e4rh +1erhab +2erhai +4erhals +2erham +2erhas +3erhebu +er3hei +2erher +er3hu +2eri +e2riat +e3rib +4e3ric +e4r3ico +e2r1id +eri2de +4e3rie +eri3e2n1 +e3ri3k +erik4l +4e3rin. +er1inb +e2rind +e2r1ini +er1ink +er1inl +er1int +e3rio +4eris +e2risr +3eritr +e3riv +2erk. +2erkaj +er3ker +1erklä +2erkm +2erkre +erk5t4 +2erl. +2erlag +3erlaub +3erlebn +4erleh +erm2 +er3mag +er3me +ermen4s +er4m3ers +er3mi +er4n3alt +er3ne +er4nene +er4nerf +er4nerk +3erneue +ern1os +2e1ro. +e1roa +er1ob +ero2bl +ero2br +e2r1o2f +e1rog +e1roh +4e1rok +e1rol +er3oly +e1rom +er3omb +2e3ron +er3onk +e2roo +er1o2p +e4ro4r +eror2a +e1ros +1erosi +e3rosit +e1rou +e1row +er1ox +e1roz +erö2d +2eröh +erö4l +er1ös +er3p +er3rä +2erren +er3ror +2errü +er3s2a +ers4ana +ersch4 +erse4h3u +ers2el +er3sen +er5s2i +er3sk +er3sp +4ersted +er3stel +erst5ers +4erstil +ers4tod +ers6tr +er3swi +er3sz +ert1ab +erta2d +er3tat +4erteig +er4t3erf +er4t3er4g +er4ter4h +er4terk +er4ters +er2tho +4ertö +4ertru +erts2e +ert3s2p +2eru +eruf4s3 +e4r3uhr +er1u2m1 +er1und +e4rundu +erung4 +3erup +er3use +e2r3uz +erü4b +3erweck +er4zerk +er4z3ers +es3ab +e4sabe +e3sac +es2ach +e2s1a2d +e3saf +es3ak +e2s3all +es3ampl +es2ank +es2anm +es2anr +es3anz +e3sap +es3apf +es3a2ra +e3sarg +e3sa2s +es2ast +es3ato +es3aus +esa2v +es1ax +2esb +esbi5er. +e3s2ce +esch2 +es4chem +es4chi +e2s3ec +es1ehr +e2s3ein +ese3in4s +es2el +ese4nal +ese4neu +esen3o +es2ens +esen3sk +eser4at +ese4r1u2 +eses2k +e2s3e2x +2esf +2esh +es2har +es3he +2esi +esi3er. +e2s1il +esi2st +es2kat +e4s3ke +e4s3kl +es3ku +e4sky +es3l +2esm +es3ob +es2oh +eso2r +eso3re +es2ort +e3s2ö +e3spal +e3s4pan +es4park +es2pek +e2spel +e4spers +e2sph +e3s2pi +e3s2por +e3spra +e3spu +2esr +2ess. +es2s1ag +essali3 +essau4s +1essay +2essä +2es3sc +es3se +ess4erf +ess3erg +es4serh +2essk +2esso +es2sof +2essp +es2s1pa +es2spu +es4stab +es3str +es3stu +estab4b +esta3ge +est1ak +es4tanb +es4tang +e4stant +e1stap +e1star +e4starb +e2st1a4s +e1stat +e4staum +e4staus +es2tec +est5eing +est5eink +est5einl +e1stel +e4sten +es4t3eng +est5erha +ester6ke +es4ter4ö +es4t3erz +es4t3ess +es2th +es2tid +e4stig +e1stil +e2stip +estmo6de +1estni +est1ob +e2s3tom +est3ori +es4tr +es5trac +e3strec +e1stu +est3ums +es2tur +e1s6tü +e3sty +e3suh +es1um +e2s3ums +es3unt +es1ur +2es3w +e3sy +es3z +es4zene +2e1ß +e2ß1el +e2ßent +eße3re +e2ß1er2g +e1t +etab4 +et2abl +eta2c +2e3taf +2etal +et1a2mi +et4an. +et1ant +et4at +etat3r +et2ax +et1äh +2etb +2e3te +ete2e +e4t1ein +ete3ke +et2en +eten3d2 +ete2o +eter4hö +eter4tr +ete2s +2etg +et2h +2eth. +e3tha +e4t3hal +et3hä +1et4hi +e2thik +1ethn +e4thot +et3hü +e2tid +eti2m +etin1 +e4tinf +e2tinh +et1ini +eti2ta +eti2th +2eto +e2t1o2f +et2on +eto4n3al +etons4 +e4torg +2etr +e4traum +et3rec +e2t3res +et4ros +ets2c +etscher7e +etsch3w +et4sh +ets1p +et2spe +et2ste +et3su +et4sum +ett1a +et2ta2b +et2tad +et2t3ak +etta2m +et4tang +et4tans +ett2as +et2tau +et2tei +ette4n1 +et2t3h +et4tim +et2t3r +et2t1um +3e2tui +e3tur +e3tü +2etw +etwa4r +1etym +2etz +et2zw +eu1a2 +eu3b4 +2euc +euch4ta +2eud +eude1s +eudi4e +eu2eb +euer3ei +eue6reif +eue6reis +eueren4 +euerer6s +euerer6t +eu3eri +eu3erk +eu3err +eu2esc +4euf +euf2a +eu2fer +eu2g1a +eu6gense +eu3g2er +eu4g3ing +eu2gre +eu2gri +eugs4 +eug3sp +eu3h +eu1id +eu1in1 +1e4uk +eu2kä +eulan2 +euland3 +eu3l2e +eul2i +2e1um +e3um. +eu3ma +e3umb +e3umf +e3uml +e3um2s +eum4se +eum4s1p +e3umw +2euna +eun2e +eu4nei +e3un2g +eu2nio +eu4nis +eunk2 +eun3ka +eu1o2 +eu1p +eu3p2f +eu2ral +eu4r1an +eu4r3ast +e2ure +euren2 +eu4rens +eur4er +eur3f4 +1euro +e3usar +eu2sis +eu3sp +eust4 +eu1sta +eu1sto +eu1s4tr +eut2e +eut2h +1eu3tha +eu5t2o +eut6scha +eut6schn +eut6schr +2eux +eu2za +eu2zo +eu2z1w +e3ü +e1v +e2vak +e3var +eva2s +2ev2e +eve5ri +evie3le +2evor +e1w +ewä2s +e2we. +ewei4sc +ewert4 +e3wir +ewi2s +e3wit +2ex. +e2xam +2exas +ex3at +2exc +2exd +e2xel +e2xem +ex1er +2exes +e1xi +2exik +e2xil +e2x1in +1exis +ex3l +3exp +2exs +2ext. +2ex2ta +ex2tin +1extr +2extu +2extv +2exu +e2xum +2e3xy +2ey1 +ey2n +ey4ne +eys2 +e1z +e3z2a +ez2ä +e2z1enn +e3zi +ezi2s +ez2o +e3zoh +ez2w +é1b +é1c +é1g +égi2 +é1h +é1l +élu2 +é1o +é1p +é1r +é1s +é1t2 +é1u2 +é1v +é1z2 +č1c +č1m +č1n +č1r +1ën +ę1p +ę4t +1fa +fab4 +2f1ab5b +fa2ben +2fabf +2fabg +2f1a2b5l +2fabn +3f2abr +2f1ab5s +2fabw +fa4cheb +fa4chel +fa2ch3i +fa2cho +fach3s4p +fa2del +f1ader +fa2di +fa2dr +fa3ec +fah6l5ent +5fahrt +fai3b +f1a2ka +fa2ke +f3aktio +f2akto +3f2aku +fa3la +fa3le +fal2kl +fal4l3ei +fall5ent +fal6lerk +faller6s +fal6scha +fal6schl +fal6schm +fal2tr +f1amt +3f2an. +fa2nar +2fanb +fand2a +fan2gr +2f1an3k +2fanl +4fann +f1anp +2fanr +2fanw +2f1an3z +2f1a2p +f2ar +far2b1a +far4bel +far4b3er +far4bin +farb1l +far2bo +far2b3r +far2b3u +f3arc +3fa5ri +far2r1a +far2rh +farr3s +2f3art +2f3arz +fa3s4a +fa3sh +fa2st +2f1astr +fa2ß +f3at +f4at. +fa2to +f4ats +2f1auf +f3aug +f1ausb +faus4t3r +3f4av +fa2xa +1fä +fä1c +fäh4rin +fäh2r1u +f1älte +2fäq +2f1ärm +2färz +fässer4 +fäs6serk +fäs6serw +fä2ßer +2f1ätz +2fäug +2fäx +4f1b2 +fbau1 +fber2 +2f1c +f3ch +2f3d4 +fdien2 +1fe +3fe. +featu4 +fe2c +f2ech +fe3che +fe2dr +fe2e1i +feein5 +fe1em +2f1e2he +feh4lei +f2eie +f2eind +2f1eing +fe3ins. +2f1einw +f1eis +5fek +fe2l1a +fel3au +fe2l1ä +fel2da +felde4m +feld6erh +fel2dr +fel4d5ri +2fe2lek +2felem +fe2l1er +fe2les +fe2l1o +fel4s3oh +fels2t +felt2 +6fel6tern +f2em. +fem4m +2f1emp +fen1a +fen3au +4fenerg +fe2ni +fe2no +fen3s2a +fen5s2c +fenst2 +f1ent +2f3entf +f2enti +4f3entla +f2ento +2f3entw +2f3entz +3fep +fe2pi +f2er. +fe1ra +fe2rab +fe2ral +fe4rang +fer4ant +fe4ranz +fe2rau +fe2r1ä +2ferd. +fer3da +ferd2e3 +f2ere +fe2re2b +fe2rec +3ferei +4f3ereig +fe4r3eis +f4erel +fer3ell +fe4rer4g +fer4fah +ferg4 +f4ergr +ferie4n3 +4fer4leb +f2ern. +fer4nei +fe2rö +f4erpa +f4erpf +f4erpl +f4erra +fer4reg +ferri2 +f2ers. +f2ert +fert4r +f2erz +fess2e +fe2st +fest3a4b +fest3an +fest3ei +fes4t1o +fest3r +2f1e2ta +fe4tag +3fete +fet4t3a +fetti3s +2feu. +feuer3ö +3few +2f1ex +3fez +1fé +4f1f +ffab6s +ff1a2d +f3f2ak +ff3ar +f3fas +ff1au +f2f1e2b +ffe2e +f2f1ef +f2f1ei +ffe3in. +ffe5inha +ffe2m +f2f1emi +ff2en +ff3erle +fff4 +ffi3k +f2fim +ffin3s +ff1lag +ff3le +ff3li +f3flu +f3flü +ff1ox +ff1rak +f3f4rä +ff3ro +ffs2am +ff2s1p +ffs3tan +ffs3ti +ff3stü +fft2 +ffus3s +4f3g2 +fgeb2 +fge3s +4f3h2 +1fi +3fi. +fi2ar +fi3at +fid2 +fi2do +fien3 +fi1er2f +fi2k1as +fi2kel +fi2kin +fi2kn +fi2k1o4 +fi2k3r +f2il +fi2l1an +fil3d +fi2les +fi3li +fi4lin +fil2ip +fil2ma +fil2mä +fil4med +fil4mei +fi2lo +2fimp +3f2ina +2f1inf +fing2 +fing4e +fing4s4 +fi3ni +f2ink +fin2s +fin3sc +fin3sti +2f1int +fi2o +fi3ol +fi2r +fi3ra +fi4re +fir3me +fi3s2a +fi4sch3a +fi6schei +fisch3l +fisch3o +fi4schr +fi4sch3w +fi3s2h +2f1i2so +fis2p +fi2s3t +fite2 +fi2tin +fit1o2 +fi4tor +five4 +fi2xel +2f1j +3f2jo +4f1k4 +fka4t3 +f2l2 +2fl. +f3lad +f5land +f4lans +f3lap +f4lasc +f3lats +flauma4 +3f4läc +4fläd +f3län +f3läu +fl4e +f5le. +2f3leb +f4lee +2f5lein +flek3 +flekt2 +f3ler +f4lex +f3li. +3f4lim +fli4ne +f3ling +2flins +2f5lon +1f4lop +f4lor +1floß +1f4lot +flo2w +f3lö +4flöf +f4lög +1f4luc +1f4lug +flu4gen +flu4ger +1f4luss +f4lut +flut1o +f4lü +f5lüm +4f3m2 +fma5che +fma2d +2f3n2 +fni2s +1fo +f1ob +fo2be +2fober +fob2l +2f1o2f +3foli3 +fol2k3 +fo2na +fo4nan +fon3au +fon3dr +fo3n2er +fo4nin +fo2nop +fons4 +fo2nu +2f1op +4f3org +fo3rin +3form +for4m3a4g +for4mas +for4m3ei +forni7er. +for6schl +for4st +for4t3ei +for4ter +for2th +for2t3r +fort3s2 +for3tu +for2u +fot4r +fo2x +1fö +2fö2f +2f1ök +4f1öl +för4s5 +4f3p4 +2f1q +f2r2 +f3ra. +frach6tr +2f3rad +2f3rah +fra4m +f3rand +f5rap +f3rat +1frau. +f3rauc +2fräd +1f4rän +2fre. +f3rec +f3red +2fref +2freg +f4rei. +f3reic +f4reie +frei1f +f4reig +frei3k2 +2freim +2frein +2frek +2f3rep +2frest +3f4reu +2f3ric +fricht6e +fri3d +fri2e +2frig +f4ri3k +f3rip +1fris +f4risc +f4rist +2f3roc +2frol +1f4ro2n +fro4n1a +f4rop +fro2s +f3rot +frös2 +f3ru +f4ruc +f3rü +4f1s +f2s1al +f2sa2n +fs3ane +fs3ar +f2s1a2s +f2saut +fs2än +f3sc +f4sca +f4sce +f4schan +f4schef +f4schro +f4scr +f2s1e2b +f4s1ehr +fse2n +fs1en1e +f2s1ent +f2s1er +fse4t +f2s1eta +f2s1i2d +f3s2ky +f2s1o2 +f3soh +f3sol +fs2on +f3spann +f2s1pas +f2sph +f3s2pl +f3s2por +f2spre +f2spro +fs2pul +fs3s4 +fs2t +fs3tak +f2stas +f3stat +fs3tät +f4stäti +f3stel +f3stern +fs3th +f2stip +fs4tol +fst4r +f4s3tres +fs3trü +fs3tut +f4stüte +fs1ums +f2s1un +f3sy +4f1t +f4ta. +ft1a2be +ft1abl +ft1af +ft2ag +ft1ala +ft1an +ft1a2r +f3tat +ft3att +f2t1äu +fte2c +ft1eck +ft1edi +ft1eh +fte2he +ft1eig +ft1ein +ft1eis +ft1eli +ft1emi +f4t1ent +ft3erfü +ft1erk +f2t1erl +f2t1erz +f2t1e2ti +f2t1ex +f2t3h +f4t5hei +f3ti +f4tid +ft1in +f4tinf +f4tins +fto2 +f2t1of +ft3om +f2t3ot +f3t4ran +ft3res +f4tric +ft3ro +ft3ruh +ft2s1 +ft4sam +ft3s2c +ft4sche +ftse2 +ft4seh +ftsen1 +fts3i +ft3st +ft4staf +fts3tät +ft4stei +ft4stem +ft6stier +ft6s5treu +ftstro4 +ft4stru +f2tum +ft1urk +ft1url +f3tü +ftwa4 +ft3z2 +ftze3d +1fu +3fuc +3fug +f2uh +fuku3 +f1um +fun6derg +2f1unf +fung4 +2f1ungl +2f1u2ni +fun2kl +fun2ko +fun2k3r +fun2ku +2f1unm +2funr +2funt +f2ur +furch2 +fu4re. +2f3url +fus2sa +fus2s1p +fus2st +fu2ß1er +3fut +1fü +2füb +fühl4sc +fün2 +fü2r +2f1v +4f1w +f1ya +4f1z +fz2a +fzeiten6 +fzei8t7end +fz2ö +fzu2ga +fz2w +3ga. +2gabf +2gabg +g4abi +ga2b3l +gab2o +g1abr +gab4ri +2gabsc +2gabtr +ga3bu +2gabw +2gabz +ga1c +gade2r +ga3di +gadi4e +2gadl +2ga2dr +gae2 +ga1fl +5gag. +ga1k +ga2ka +ga2ku +gal2a +ga3laf +ga2lar +2g1alau +2g1alg +gal3lo +2g1alp +2g1alta +2g1altd +g1a2lu +ga2mec +ga3mel +gam3ma +5g4amo +2g1amt +g1ana +2ganb +gan3d2 +2ganf +gan2g1a +4gangeb +gan2gr +gang4sp +gan2g1u +2g1ank +2ganl +2ganmu +3g2ano +2ganr +gans2 +g2ans. +2g1ansi +2ganst +2ganw +ga1ny +g1anz +ga3pe +2g1app +ga1q +3gar. +g2ara +2garc +3g2ard +ga3r2i +2g1arm +ga3r2o +gar2s +2g1arti +ga3ru +2g1arz +ga2s +g2as. +gas3al +ga5schu +gase2 +ga5se. +ga4sei +ga4sel +ga4se4m +ga4sent +gas3s2 +5g4asse. +g4assen +6gassess +gas4t3el +gast3rä +ga3t2a +gat2h +2gatm +gat4r +gau1c +2g1auf +2g3aug +g2auk +gau5ne +2g1aus +2g1aut +2g1äp +gär3th +2gärz +gä4u +2g1b4 +gber2 +gbi2 +gbon2 +gby4t +2g1c +2gd +g1da +gd2ad +gda3de +g2dak +g2dan +g2dar +g2dau +g1dä1 +g2dei4 +gdel6s +gd2en +g2d3ent +g2der +gd2es +g1do +g2dop +gd2or +g1dö +g1d3r +gd3s2 +gdt4 +ge3a2 +geb2a +ge3ble +geb4lin +gebot4 +3gebü +ge1c +ge3ck +ged4 +ge1e2 +ge3ec +geest3 +3gefä +4g1eff +gef4l +gef4r +ge3fu +gegen1 +gegen3s4 +ge3g2l +ge3hei +2g1eid +ge4ie2 +2g1eif +ge4ig +g2eil +gein1 +ge1ini +ge1inn +2g1einr +gein5sti +gein2v +ge1ir +ge2is +2g1eise +gei3sh +geis4sc +gei2st +2gek. +gelb1r +gel4b3ra +gelb3s +gelder4 +gel6derh +gel6ders +ge3lec +gele5cke +2ge2lek +2gelem +ge4lene +gel3ere +ge4lerk +geler3ö +ge4l3ers +ge2lev +gel3f +gel1i4m +gel3la +gell2i +gel2ö +gel3sa +gels2p +gels2t +gel3ste +gel3sz +gel3ta +gelt4r +gel3z2 +gem2 +ge4ma. +gem6e +4g1emp +ge3mu +g4en. +ge3na +ge4n1ac +ge4nak +ge4n3al +ge4nam +ge4nar +ge4nat +gen4aug +ge3nä +ge4näu +g2enc +4genda. +4g3endmo +gen2dr +gen3eid +gener4f +4generg +ge4n3ern +gen6erwe +gener4z +ge4ness +ge3nid +ge2nim +gen3k4 +gen3n +gen4sam +gen3sk +gen3sz +gen3tä +2gentf +gen3t4h +gen5tr +2gentw +geo2ri +ge1ou +g2e3p4 +ge1ra +ge2ra2b +ge2r3al +ge3rann +ge4rant +ge4r3a2r +2gerdg +ge4rene +ge4reng +ge4ren4s +ge4r3ent +ger2er +gerin4f +ger4inn +gerin4t +4ger4klä +g3erlas +ger5me +ger3no +2g1ernt +ge1ro +ge2rob +ge2rop +ge1r2ö +ger4sat +4ger4seh +ge3r2u +g1erzä +ge1s2 +g2es. +ges3auf +3gesc +gesch4 +ge6sche. +ge2s3eb +4g3e4sel. +ge4s3elt +ge2s3er +ge3sha +ge3si +ges4pi +ges3s4t +gest2 +gest4a +ge3stak +ge3st6e +ge4s3ter +ges3th +ge4s3tur +ge3t2a +ge4tang +ge4tant +g1etap +ge3ti +get4ri +get3s +ge5t4u +2g1e1ul +ge3u4t +ge3wa +4g1e2x +2g5f4 +gfi2l +4g1g +gga4t +g5ge +gge2ne +gg2l +g3gla +g3glo +g2g3n +gg4r +ggs2 +2g1h +4gh. +gh2a +3ghale +gh2e +3g2het +3g2hie +gh1l +3gh2r +ghs2 +gh3sc +g2hu +gh1w +gich2 +gicht1 +gi2eb +gie3g +gi2e1i +gi2e3l +giel2a +gie3n +gien2e +gi4eno +gie3re +gie1st +giet2 +gif2tr +gift5s +gi2gu +gi2kel +2g1ill +gi2me. +gi4mes +gi2met +2gimp +2gind +gi3ne +2g1inf +gin2ga +2ginh +2g1ins +2g1int +2ginv +gi2ob +2giok +2g3isel +git2a +gi3tu +gi4us +2g1j +4g5k4 +gl2 +4gl. +4g1lab +2g1lac +2gladu +2g1lag +2g1lam +2gland +3glanz1 +gla2s1c +glas3t4 +3g2laub +2g1lauf +2gläuf +gl3b +g2l4e +2g3le. +3glea +2g3leb +g3lec +4g3led +g3lee +2g3leg +2gleh +g4leic +4g3lein +gleiter8s +glei4t5r +g3len +4glenk +4g3ler +glerei4 +2gles +3gles. +g3lese +g3lev +g2lia +2glib +3g2lid +g2lie +2g3lieb +2glif +g2lik +4glil +g2lim +4glin +g2lio +2glis +3g2lit +g3lite +g2liz +g3lize +g2loa +g2lob +g2loc +2g3loch +g2lok +g2lom +g2lop +g2lor +2glos +g2lot +2glöch +2glös +2glöw +2gls +g1lu +2g3luf +2gluk +4g3lun +g2lut +3glü +g1lüg +2glw +3g2ly +2g1m2 +g1n +2gn. +g2n2a +g4na. +2gnac +2g5nah +gn4al +gna4l3er +2gnanl +3g2nä +2gnb +2gnc +2gnd +gn2e +g3neh +2gn3ent +gne2tr +2gnf +2gng +2gnh +g2nie +g2nif +g4nin +2gnint +2gni4s3 +gnise2 +2gnk +2gnl +2gnm +g2no +g4non +gno1r +g3not +2gnp +2gnr +2gns +2gnt +2gnu +3g2num. +g2nü +2gnv +2gnw +g2ny +2gnz +go4a +goa3li +g1ob +go3be +2gobj +gob2l +2g1o2f +2gog +2g1oh2 +goh3ren +go1i +go3in +gol2a +gol2fr +3gon. +gon2e +3gons +goo2 +2gope +gopf4 +go4pos +2gopt +gor2a +2gord +2g1org +go2s1 +gos3p +gost2 +2g1osz +go3t2h +got6terb +got6t5erg +3gou +go1y +gö2f +g1öl +3göt +2g3p4 +2g1q +g2r4 +g4rab +gra2ba +gra2bi +gra4bl +2g3radl +2g3rah +2g3rak +gram1 +gram8m7en8d +gram6mer +g3rand. +2gra2r +grar1e +gra2s3a +gra4sh +gra4sp +gra2st +2g3raub +grau3f +2graum +grau3sk +2gräd +gräs1c +g3räu +2g5re. +g4reb +2g3rec +g3rede +g4re2e +2g3ref +2grege +2g3reic +grei4fr +2g3reih +g3rein +g3reit +g4rem +2g3renn +gre3no +gren6z5ei +grenz3w +g4rer +gres6ser6 +g3ret +g3rev +2g3ric +gri2e +2g3riem +g3riese +g4rif +2grig +gril4la +4g3ring +4g3rinn +g4rip +gro2ba +gro3ber +gro2bl +gro2b3r +2groc +2groh +2g3rol +gron4 +2g3rose +g4ross +gros6sel +2g3rost +g4rot +2gröh +2gruf. +g4ruft +2g3ruh +g3rui +2g3rum +grun2g +3g4rup +3grus +3gruß +2g3rut +2g3rüc +g4rün +4g2s1 +g4s3a2b +g3sack +g4sa2d +g4s3a2k +g3sal +g4salb +g4sall +g4salm +g4salt +gs2am +g4s3ama +gs3amb +g4s3amp +g4sant +gsa4p +gs3a2r +g3sat +gsau2g +g3sau4r +gsa2v +g3säu +g3s2c +g4sca +g4s3ce +gsch4 +g4schef +g4s3co +gse2 +gs2e3h +g3s2eil +g3s2eis +gse4kl +g3sel. +g4sela +g3seln +gs3em +gsen1 +g4sent +g4ser +g3sere +gs3er1i +g4se4s +gse4t +g4seu +gsfi2l +gsh4 +gs3ha +gsi2d +gs3i2k +g3sil +gs3in +g4s3ita +gs2ki1e +g4sm +g4sn +gso2 +gso4b +g3sol +g4s3op +g5s4orge +gs2pac +gs4pant +g4spas +g3s2pek +g3s2pi +g5s4pie +g4s3pl +g3spor +gs6port. +g6sporto +g4s3pru +gsrat4 +gsrü2c +gs3s4 +gs3ta +g3stan +g4stanz +g3star +gs4tati +gs3tä +g3steh +g3stein +g3stel +gs4tell +gste2r +gst3err +g1steu +gs2thy +g3stif +g3stil +g3stim +g3stir +g3sto +g4stoch +g4stod +g4stor +gs3tö +gs4tör +gs3tr +gst4ra +g3s4tras +gs4trat +gst5reit +gst4res +g4streu +gst3rit +gst3ros +g3stun +gs3tü +g4sw +g3sy +2g1t +g3te +gtei3s +gt3h +gt4hy +g3t2i +gti2m +g3to +gt4r +gt2s +g3tü +gu4ale +gu3am +gu1an. +gu1ant +gu1as +gu1c +gu4d3r +gu2e +2gued +guet4 +2g1u2f +2g1uh +gu1ins +gu1is +gum2e +3gumm +gummi1 +gun2e +2g1unf +g2ung. +gunge2 +4gungew +2g1ungl +2g1u2ni +2g3unk +2gunr +gun2s +2gunt +gure4 +2g1url +gur2th +gur2tr +gurt3s +guru1 +gu2s +gus3a +gu3sc +guschi5 +gu3se +gus4ser +gus2s1o +gus2sp +gus4st +gu4st +gust3a4b +gus3te +gust3en +gus6tend +gus6terl +gus4tr +gu2t +gut1a +gut3er4h +gut3h +gut4sa +gut2sp +2güb +3gür3 +güs3 +2g1v +2g1w +gy3n +gyp2a +2g3z2 +gzeu4gi +hab2a +hab2e +h3abf +hab2i +2habn +h1a2br +h1abs +2habw +ha4ch3en +ha2cho +hacks4 +ha2del +hade2n +h1adle +hado2 +h1a2dr +2hae +ha4far +haf2e +h1affä +haf3f4l +h2aft +haf4to +haf2tr +haft4s3p +h2agg +h1ah +h2ahs +h2ai +3hai. +h2aj +2haka +ha1k4l +2h2al. +halan4c +h1a2lar +ha2lau +hal2ba +hal4bel +hal4bin +hal2b3r +hal2bu +2hale +hal6lere +hal6lerf +hal6lerg +ha3lo +4halp +hal4sei +hal4sk +hal2sp +hal2st +hal4tal +hal4tei +hal6t3r +h2ame +2h1amt +h2an. +2hana +ha2nal +ha2nan +2hanb +h2anbe +h2and +han2da +han2d3r +hand3s +ha2nem +han2f1 +han6g5end +2hani +han2kr +2hanl +2hano +2hanr +h1ansc +2hanz +2h1ap +3h2ape +ha2pl +ha2po +ha2pr +h2a3ra +ha4rab +2harb +h2ard +har2fr +h1arm. +har3ma +h2arme +har4me. +har4ne +ha2rom +hart4e +har2th +h1arti +har2tr +har4tri +har2za +h2as +4ha3sa +has4c +has2h3 +has4sa +hasser4 +has4s3t +has3t +ha2str +h1a2ß +ha2ta +h3atl +ha2t3r +2hats +hatt2 +h3attr +h1audi +h1aufb +hau5f6lie +hau3f4lo +2h1aufm +h1aufs +h3au3g +h1aukt +hau2sa +hau4san +hau2sc +h2ause +hau4sel +hau6s5ent +hau4spa +hau4spe +haussen6 +hau4sur +hau2ta +4hauto +hau4t3r +ha2ve. +häde2 +h1äff +hä2kl +2härz +hä6s5chen +2häug +häu2s1c +hä3usp +2h3b4 +hba4ras +hbe3r2e +2h1c +2h3d4 +hdan2 +4hea +he3be +heb3eis +he2b3l +he3br +he3bu +he3ch2e +he3chi +he1cho +h3echs +he3cke +hed2g +he2dit +he2el +hee3le +he1e4m +hee2s +he1e2t +h2ef. +he2fan +he2fau +he2f1ei +he3f2em +hef3erm +2heff +he2fid +he4f3ing +he2f5l +2hefr +hef4ra +he2fre +3heft +he2fu +he3gu +he2hel +h4eib +h1eie +h1eif +h1eig +he2im +hei4mal +hei4man +hei4mar +hei4mei +heim3p +hei4mu +2hein +heine2 +hei4neb +hei6nene +hei4n3er +h3eintr +4heio +he1ism +he1ist +heit4s3 +h1eiw +hekt3a +he2l1an +he2l3au +hel1ec +he2lek +h3elem +he2len +h2elf +he3li +hel4l3au +hel4mei +he3lo +he4lof +hel2or +he2lö +2helt +2h1emb +3hemd +he3mi +he4mia +h3e4miss +3hemm +2h3emp +h2en. +hen3a2 +he4nas +he4nat +hen3ebe +henen1 +hen3end +he4nene +he4nens +hen3erg +he4nerm +he2n1e4t +henfal4 +2henga +hen4gag +hen4kan +hen4kau +henst2 +hen3str +hent2a +hen3te +hen3tr +h1ents +2h3entw +h3entz +he4n3u +hen3z2 +4he2o +he3on +he3op +he3pa +he3ph +h1e2pi +hept2 +h2er. +her3a2b +he2rad +4herap +he4r3a2r +he2rat +herb2 +h2ere +he2re2b +he4reck +her4eif +4he3reig +he6reis. +her7eises +he2rel +he4rene +he6rersc +he4rerw +h1er2fo +6hergebn +2herif +herin4d +herin4f +he6rin6nu +herin4s +h1erke +her4klä +h5erkran +her3la +h2ern +he3ro +he4r3o2b +he4rof +he4rop +he4rot +h1erör +hert4 +her3th +her3tr +her3um +her4zap +h3erzeu +her2z1w +he3s4a +4hese +he3si +he3s2p +hes6tä +he3stro +he2tap +he3tä +heter2 +he3th +het2i +he3t4s +h2eu +heu3g +he2um +3heusc +he3x +he1x2a +2hexp +he1y2 +1hč +2h3f4 +hfaller6 +hfan2 +hfel2l3 +hfi2s +hflei2 +2h3g4 +hgas1 +hget4 +2h1h2 +hhoh2 +4hi. +4hia +hi2ac +hi2ang +h1iat +4hic +hi1ce +hich6t5er +hicht6sp +2hid +hi3d2e +hi2e +hi3ens +hier3i +hie4rin +hiers2 +hif3f4r +hi2k3r +hi2l3a4 +hile3n2 +hil2fr +h2im +2hima +h3i4mit +h4imm +h3impe +hi2n +hi3nak +hi3nam +hi3nap +hi5nas +h2inde +hi3nel +hin2en1 +h1inf +h1inh +2hi3n2i +hin3n2 +hi3no +hin3s2 +hin2t1a +2hio +hi3ob +hi4on +hi3or +hi2p3 +hi4pl +hips2 +hi4pu +hi2r +hi3ra +2hi3re +hi3ri +hir2m1a +hir2mi +hirn1 +hir4ner +hir2s +1hirt +2his. +his2a +hi2se +h1i2so +hi3tac +hi2tan +hi2tel +hi1th +hit2i +hit3z2e +hi2v1o +2h1j +2h1k4 +hkamp2 +h2keu +h3kö +4hl +hl2ag +hla2gr +hla2l +hlan4d3a +hl1ans +hl1anz +h1las +h1lat +h1laut +h1lay +h3läche +h1läs +h1läu +hlb4 +hl3d4 +h3le. +hle3a +h3leb +h3led +hle3e4 +h3lein +h2leis +h3leist +h5len. +hle4nas +hlenen3 +hl2enn +h4l3entr +h4lents +hl2enz +h3ler +hle2r3a +hl4ere +h2lerg +hl2erk +h6l3er4nä +hle3run +hl1erw +h4lerz +h3les +h4lesi +hles4t +hlf4 +h2lie +h3lied +h2lif +h2lim +hl1ind +h2lip +h2lis +h2lit1 +hl3l2 +hlm2 +h2lo +hl1ob +h3loc +h3log +hlo2re +h4lorm +h3los. +h3losi +hlos4st +hl2ö +h2lös +hl4sar +hl2ser +hls3ka +hl3s2lo +hl5s6tern +hls3tie +hl5str +hl2su +hl3t2 +h3luf +h3luk +h3lumpe +h1lüf +hlz2 +2h1m +h3mad +h3mag +h3mak +h3man +h2mant +h3mar +h4marc +h3mä +h4mäc +h4mäh +h4mäl +hm2e +h3me. +h3med +hme1e4 +hmeer4s +h3mein +h3meld +hme3le +h3men +hmen2s +hme2ra +hme1s2t +h3mex +hmi2e +h3mil +h3mind +h3mini +h3minz +h3mirr +h2mo +h3mop +h3mot +h3m2ö +h4möl +hm3p2 +hm2s +hm3sa +hms1p +h2mu +h3mul +2hn +h2na +hna2c +h3nag +h3nam +h4nar +h4natt +h3nau. +h2nä +hn1äh +hn3d4 +hn2e +hne3b +hne2e3 +h2n3ef +hn3eig +hn3ein +h2nel +hne4n1 +hn4eng +hne4pf +h3ner +hner4de +hner3ei +h4n3e2ro +h4n3ersa +hn4es +hn3ex +hn3f4 +hnflei4 +hnhof8stras +h2nic +h2nid +h2nie +hn1im +h2nip +hnk4 +h2nor +hn3sa +hn3s2p +hns4to +hnsuch4 +hnts2 +h2nul +h2n1unf +hn3z2 +ho4ar +ho3bern +ho2b3l +ho2ch3 +ho4cha +hoche2 +ho2cka +hocker4 +ho6ckerl +hock3t +4hocy +2hod +2ho2e +ho2f1a2 +ho2fä +ho2feu +hof3f4a +ho2f3l +ho2f1o +ho2f3r +ho2fu +2hoi +ho2l1a2 +hol3ar +4holdy +3hole +ho2l1ei +hol3g4 +hol3k +holl2 +ho2l1op +hol3s +2holy +h3olym +3holz +hol6zene +hom2e +ho2me. +ho2mec +ho2med +h2on +4hon. +hond4 +4hone +hon2er +4hong +4honh +4honk +4hons +4hony +ho1on +hoo2r +2hope +ho1ra +ho2rak +h1o2r2an +ho2rar +ho2rau +h1or3d +2hore +ho4rens +ho3ret +2h1org +horo2 +ho2rop +hor3ta +hor4ter +h1ortu +hose2 +ho2sei +ho3sl +ho4sla +4hosö +ho2sp +ho3spr +ho4ßene +2hot. +ho3th +4hotr +2hot3s2 +2ho2w1 +h1o2x +ho1y2 +4hoz +1h2ö +2hö. +hö2c +hö3ck +h4öh +5höhe +hö2s1 +h3öst +2h3p4 +h1q +4hr +hra2b +hr3a2c +hr3ad +hr1a2g +h1r4ah +h1rai +h1rane +hr3ap +hr3ass +h3rat +h3räu +hrb4 +hr1c +hr3d +h2rec +h3r2ech +h3red +h3ref +hr1eh +h4rei. +hrei4ba +hrei4br +h3reic +h3reif +h4r3eig +hr4eini +h4reinl +h4reins +hrei3th +hreli1 +h3rep +hrer6geb +hr2erk +h4rerla +h6rer6leb +hr2erm +hrer3s +hrer4sa +hrer6tüc +hr2erw +hr2erz +h3re2s3 +hress2 +hrest2 +hre4t +h2r1eta +h2r1eu +h2rev +h3rez +hrg2 +h2ri +h3ric +h4rick +hri4e +h3riesl +h3rin +hr1int +h4rist +hrit6tel +hrk4 +hr3l +hrm2 +h3rog +h3roh +h1ro2l +h4romat +h4rome +h4romi +h4romo +h4ron +h1ropa +hro4r +h3rou +h3rö2s +hrr4 +hr2s1ac +hr4s3and +hr3schl +hr2sen +hr2s1er +hr2set +hr4sh +hr2sin +hrs3k +hrs3l +hr4s1of +hr3spa +hrst2 +hr2su +hr2tab +hr2tan +hr2te2l +hr2th +hr2top +hrt3ric +hrt2sa +hrt2se +hrt4sin +hrt2sp +h3ruh +hr1ums +h3rut +h3rü +h4rüb +h4ry +hrz2 +4hs +h4s3acht +h2s1a2d +h2s1alk +h2sall +h4samt +h2san +h2s1as +h2sath +h2saud +h2s3aur +h2saut +h2säh +h2säug +h4schan +hs4cr +h2s3ec +hse2e +h4s1ehr +h2s1eie +h4seind +h6seinst +h3sele +hse4lin +hse4mis +h4s3endw +h2s1erf +h2s1erg +h2serh +h2s1erk +h2s1erl +hs1ern +h4sernä +hs4erne +h2serö +h2s1erw +h2serz +h2seth +h2sex +h3s2ext +hsha2k +h2s1i2d +hs2im +h2s3ing +h3s4inni +h4s3ita +hs2kal +h3skand +hs1of +h2sofe +h2sop +hs1org +h2spac +h4s3pani +h2s1par +h2s1pat +h3spec +h3spei +h3sperb +h2sph +hs4pie +h3spoi +h2sprä +h2spro +hss4 +h1sta +hs3tabl +h2staf +hst3alt +h3st2an +h2s3tau +h2s3täu +h1stec +h1stei +h1stel +h4stele +h3s4terb +h3s4tern +h1s2ti +hs3tie +hs4tief +h2stit +h1sto +h2stol +h2stor +h1str +hst3ran +h4s3treu +hs4tri +hstro2 +hs3tum +h1stun +h1stü +h2s1u +hs2ung +4h1t +ht1a +h2ta2d +ht2ag +ht4akt. +ht4akte +h2tall +h4talo +h2talt +h4ta2m +h2ta2n +ht3ane +h3t2ank +h3tanz +h2tap +h2ta2r +ht3arr +ht2a2s +h2t3asi +h2tasy +h2t3a2t +h3tat. +h3tate +h2tau +h4tax +ht1ä +h2tär +ht3e4ber +ht1e2c +hte3cha +h2t1e2d +ht1eff +ht1e2he +h2teif +h2t1eig +h4t3eilz +h2t1eim +ht1ein +h2t1eis +h2t1eke +h4t3elas +hte6l5ei. +h4telek +h4t3elfe +h4t3elit +hte4m +h2t1emi +h2temp +h4tenga +h4t3engl +h4t3enta +h4tentf +h4tents +hter6de. +hterer6s +ht3erfü +h6terfül +h6tergeb +ht3ergr +hter6gri +ht1erh +hter6häl +hter8höhu +h6terleb +h6t5erleu +h6terneu +ht5erspa +hter8spar +ht3erst +h6tersta +ht3erwä +ht3erze +h4t1e2se +h4t1ess +h3tet +h4t1e2th +h2t1eu +h4textr +h2t3h2 +h4thei +h3thera +h3thes +ht4heu +h4tho +h2ti2d +h2t1im +h2t1i6n3 +ht3ine +h4tisr +htni2 +hto2 +h2t1ob +htod1 +h2t1of +h4t3oly +h2tope +ht1or +h4tord +ht3rak +h3tran +ht3rand +h4t3ras +ht3rat +ht6rates +ht3rau +h4traub +ht6raume +ht3rec +h5treck +h4tref +ht3rei +h2trek +h2t3res +ht4ri +h4t5ric +h4t5rieg +h4t5rin +h2t3rol +h2t3ros +ht3röm +ht3ru +h2t3rü +h4ts +ht2sah +ht2sal +ht4s3a4n +ht2scr +ht4sein +ht2sel +ht4s3end +ht4seng +htse2r1 +ht4s3eri +htsha2 +ht3s4hak +hts3k +ht3skal +ht2s1o +ht2sp +hts3tät +hts2ti +hts5trau +ht4s3tur +ht4s3tür +htt4 +htti2 +h3tub +htu2e +h2t1urs +h3tü +ht3z2 +hu2b1a +hu2b1ei +hu4bel +hu2b1en2 +hu2bi +hu2b3l +hu4b5r +hu2bu +hu1c +hu2fa +hu2h3a +hu2h1i +h1uhr +h1uhu +hu2kä +hu2k1i +huko1 +huk3t4 +hu2l3a2 +hu2lä +hule2 +hu2l1eb +hu2l1ei +hu2lem +hu4l3eng +hu4lent +hu2l1er +hu2let +hu2lid +hu2l3in +hull2 +hu2lo +hu2lö +hul3s4 +hu3m2a +h1umh +2h1ums +hu2n +h1una +hun3d2e +hunde3i +hunde3s +2hunf +hung2 +hun3ge +hung4s +hungsa4 +h1uni +h1unm +2hunt +h1ups +2hur +hur3g2 +hur2th +hu3sa +hu2so +hus2s3a +hus4ser4 +hus2s1o +hus2sp +hus2st +hu2tab +hu2ti +hu2t1o4 +hu2t3r +hut2t +hut4zen +hut4z3er +hut2zu +h2ü +hübe4 +h3über +h4übs +h3übu +hüf2 +hühne4 +hüs3 +2h1v +hvil2 +2hw2 +h2wall +hwe1c +h1weib +h1weih +hwein6sa +h2wirr +hy2lor +3hym +h1yo +3hyp +hy2pe. +2hy2t +2h1z +hz2a +h3z2o +hzug4 +h3z2w +i1a +i2aa +i2ab +i2ache +i3ad. +ia3do +i2af +iaf4l +i2ag +i4ago +i2a1h2 +i2aj +ia2kei +ia2kr +i2aku +i3al. +i3a2l1a2 +ial3ar +ial3as +ia2lä +i3al3b4 +i3alc +i3al3d4 +i3a2leb +i3alef +i3alei +ia3lek +i3alel +i3aleng +i3alent +i3alerb +i3alerf +i3alerh +i3a4lerm +i3a2l1et +i3alex +i3alf +i3alg +i3a2lia +i3alim +i3a2lin +i3alj +i3alk +i5al3l +iall2a +ial4ler +iall2i +i3alm +i3aln +ia2lon +ia2l1o2r +ial3p +i3alr +i3als +i3al3t4 +ia2l3u4 +i3alv +i3al3z2 +i2am +i3am. +i3amp +iampe4 +i3an. +ian2a +ia2nal +ian3alt +ia2nau +i3and2 +ia2n1e2b +ian2er +i3anl +i3ans +ian2s1p +i3ant +i3anw +i3anz +ia1o +i2ap +ia3pf +i2a1q +i3ar. +i2a2ra +i4ari +i3as. +ia3sh +i2asi +ia3s2p +ias3s +iast4 +i3at. +i4ate +i3at2h +i4athe +1iatr +i3ats +i3au +ia3un +i2av +2iä +i1ä2m +i1äp +iär2 +i1är. +iär3m +i1ärs +i1ät +i3ä4tem +iä2ti +iä4tr +iät3s4 +2i1b +ib1art +i2b1auf +i2b1aus +i2baut +ib2bli +i2b1eig +i2b1eis +ibe4n1 +i2b1ep +i6ber6geb +ibe1ro +i2bim +i2b1in +i2blad +i2bleu +i3blu +ib2o +i2bö +i2b3rau +i2b3ren +ib3ric +i2b3roc +ib2ser +ib4ste +ib2un +i2b3unk +i2b3unt +ibus1 +2ic +i3ca +ic1c +ice1s +ich1a +ich6art. +ich1ä +i1che +ich1ei +ich2er +icherin5 +i1chi +ich1l +ich3le +ich3li +i3ch4lo +ich5m +ich3n +i1cho +ich3ort +i2ch3r +ich6sele +ichsen3 +ich2s1i +ich4spe +ich6stie +ich4tab +ich4tan +ich2tr +i1chu +ich1w +i1ci +ic1in +i3cke +ick1s +ickt2 +i1cl +ic3la +i5cu +i1d +id2ab +i3d2ac +id1a2n +i3d2ans +i3dat +id1au +id2ax +idä1 +i2dea +1idee +2idel +idel4ä +i4demu +ide4n1o +iden4se +ide2on +i3der +4ider. +iderin8nu +ide1rö +ider6reg +ide3so +ides2p +2idia +1i2dio +idi1s +idni3 +id2o +i2dol +2idoo +i2dö +2i2d3r +id4ru +i3dsc +id2set +id2s1p +idt4 +2idu +1i2dy +ie3a2 +ie2bä +ie2bl +ie2b3re +ie2bri +ie4b3rü +ieb4sto +ie1c +ie2cho +iech3t +ie2ck +ie2d3an +ie3de +ie2dr +ie1e2 +ie2f1an +ie2fau +ie2fäh +ief1ei +iefe2m +ief3f4 +ief2i +ie2f3l +ie4fonk +ief1r +ie2fro +ie2gl +ie4g5li +ie3g4n +ieg3r +ieg4ra +ie2gre +ieg4s3c +ieg4se +ieg4st +ie2h1in +ieh3r4 +i1ei +ie1ind +i2e2l1a +iel3d4 +i2ele +ie2l1e2b +iel1ec +iel3eid +ie2lek +i4elen +ie4lene +ie4leng +ieler4e +ieler6fi +ieler8geb +ieler6ke +ieler6la +ieler8lebn +iel4erw +ieles4 +ielf4 +ieli2d +i1ell2 +ie2lo2b +ie4lor +i2els2 +iel3sz +ielt2 +iel3ta +iem2e +2i1en +i3en. +i3ena +ien1ag +ien4am +ie4nas +i3enä +i3end +i2ene +ien1eb +i3enec +i3e2nek +iener6fo +ien3er4g +iener6la +i3enex +i3enf +i3eng4 +ienge4f +ienge4z +i3enh +ie2nim +ie4n3in +i3enj +i3enk +i3enla +i3enle +i3enm +i3enn +i3e2no +i3enö +i3enp +i3enr +ien2s +i3ens. +i3en3sa +i3en3sc +i3en3s2e +ien3si +ien3s2k +i3en3s2p +iens6t5er +ienst5rä +i3en3sz +ien4tar +i3enth +i3enty +ie3nu +ie4num +i3env +i3enw +i3enz +ie1o4 +ier3a2 +ie2rad +ie2rap +i3erbun +i2ere +ie4reck +ie4r3eis +ie3r2er +ierer3k +ie4r3erz +ie2ret +ierf4 +ierg4 +i1ergi +ierk2 +i1ern +i3ern. +i2erni +ie1ro +ie2rö +ier4re. +ier4s3eh +ier3sei +iers2t +ier3sta +ier3ste +ier3te +ierts4 +ier3z2 +ie2san +i2esc +i2ese +iesen3s4 +ie3s4pa +ie4spu +ies6ser6g +ies2st +iess3ti +iest6e +ie1str +iet1a +ie4tag +ie2tan +ie2tap +ie2tat +ie2tau +ie4t3ent +ie4t3erh +ie4t3ert +ie4tha +i4ethe +iet3her +ie2t3ho +ie2thy +ie2t1o4b +ie2t1ö2s +ie4t3ri +ie2t3ru +iet2se +i1ett +iet3zw +ieu2e +i2e1un +ie2w1u +i1e2x +2if +if1ar +i2f3arm +if4at +i2f1au +if1än +i2fec +i2f1ef +if1ein +if2e4n +i2f1erg +if1erh +if2far +if2f3l +if2fro +iff2s +iff4ste +if3l +if1lac +i1f4lä +iflo4 +if4los +i1flü +if3r +i1fre +if4rev +if2s +if3sa +if3se +if3sp +if3sta +if4t3a +if2ted +if2t3ef +if4t1ei +if2te2l +if2tep +if4terk +ifte2s +if4t3esc +if2t1op +ift1r +if2tra +if4t3ri +if2tro +ift3sp +ifts2t +ift3sz +if2tur +i1fy +2i1g +iga1i +i2garb +ig1art +iga3s4 +i2g3att +igd4 +i6gebrau +i4gefar +ig1ein +ige4na +ige6nene +ige4nid +ige2ra +ig5erwer +ig1erz +iger4ze +i2g1ess +i2gim +i2gl +i4glag +i4g3lim +ig4na +i4gnä +i3g4neu +ig4no +i3g2o +igo1p +ig3rad +ig3re +ig4ren +i2grou +ig3sa +igs2ag +ig4sal +ig3sä +ig4schr +ig3s2o +ig3sp +ig4spa +ig3stei +ig4sti +ig4s3to +ig3str +ig6stras +ig3s4tü +igung4 +2i1h +i2har +i5hea +ihe1e +ih1elt +ihe4n +ihe1u +ih3m +ih3n +ih3r +ihs2 +ih1um. +ih1w +ii2 +ii3a4 +i1ie +i3ig +ii3h +i1im +i3in +i1i4s +i2is. +ii3t +i1it. +i1j +1i2js +2i1k +ika2ge +ik1ak +ikaken3 +i2kakt +ik3amt +i4k1ang +i6kantei +ikanten8n +ik1art +ik3att +i2k1au +i3kaz +ik1äh +i2kär +4ike +i2keb +ik1ebe +ike2c +i2k1ed +i2kef +i2k1ei +ike4l1 +ike2n1 +i2k1ens +ike2ra +i2k1e4r2e +i2k1er2f +i5kerfam +i2k1er2h +i2ker2l +i2kero +i2ke3ru +i2k1eta +i3ki. +i3kie +ik1in +i2kins +iki1s +i2k3l +ik4län +i3k4leri +i3k4let +ik4lim +i3klu +i2kne +i2k1off +iko1p2 +ik1o4ri +iko1s +i2köl +ik3rä +i2kres +ik4ris +i2krö +iks2 +ik3sa +ik3ste +ik3sz +ikt3erk +ik4t3esk +ik2t3re +ikt2u +i2k1uh +i2kup +i3kus +i2kü +i1la +i2lab +ila2br +i4labs +i2l1ac +i2l1ak +il3a2ma +il1anm +il1ans +ilan6zer +i2larb +il1asp +i2l1au +i3laub +i3l4aufb +i1lä1 +i2lär +2ilb +ilb4l +il2c +il5chen +il2da +ild3ebe +il4d3en4t +il3der +ild4erp +ilde2s +ildi2 +ild1o +il2dor +il2dr +2ile +il1e2c +il1ein +il1el +i2lemb +il1ent +i4lentl +i4lents +i2l1erd +iler4ei +i6lereig +il1erf +iler4fo +i2ler2g +i2l1er2h +i4lerkl +il1err +i4lerri +il2erz +ile4th +il1ex +ilf2 +ilfe3s +il2f3l +il2f3re +ilf4s3 +il2gl +2ilh +2ili +ili3e4n3 +iliga2 +ili4g3ab +ilik4 +i2l1ind +i4l3init +il1ins +i2l1ip +i3lip. +i3lips +ill2an +il4lenn +il3l2er +1illu +il2mak +il2m1ap +il2m1au +ilm1ei +il2min +il2mor +2ilo +il1ob +il2of +il2oh +il2op +i2l1or +i3lou +il1ox +il4sein +ils4to +ilt2 +il3t4h +i1lu +i2lum +ilung4 +il1ur +i3lus +ilü4 +2ilv4 +il2zar +il2zau +ilz1er +il2zwa +imad2 +ima3i +im2al +i2m3anh +im1ans +i2marc +im3aren +i2m1arm +i2m1art +im4at +imat5sc +ima4tur +i2m1aus +i2maut +1imbi +i2meg +im1ein +i2mej +i2mek +i2mele +i2melf +im2en +i2m1erf +i2m1erl +i2m1erz +i4me3sh +i2meti +i2mew +i2m1i2d +i2mim +i2m1ind +i2minf +i2m1ins +im2mä +im2mei +immen1 +imm3ent +im6menth +1immo +2imo +i2m1ob +i2mo2p +i2mö +1imp +imp2fa +im3pfo +imp2s +im3pse +im3sph +2imt +imt2e +im3t2i +imt3s2 +imtu2 +2imu +im2um +im1urk +2in. +in3ab +ina2be +in1a2c +in1ad +i4n3ae +i3nald +inaler4 +ina6lere +in2alp +in1am +in2an +in3ana +in3ann +i2narb +i2narm +in2ars +in3att +i2n3au +2inä +i2n1äh +in2är +in1äs +2ind. +inda2 +ind2ac +in2dal +in2dan +2indä +in3de +2inde. +ind4eid +2inden +ind5erke +inde3sp +1index +ind2i +1indik +in3dö +2indr +ind4ri +ind3se +1indus +in3d2ü +2ine +i4ne4ben +in1e2c +i3nee +i2neff +in4elen +in2em +ine3nä +i2neng +i4n3enzy +i5ner. +i4n3erbi +in2erh +in3erle +i6ner6leb +iner4lö +i4n3er4tr +i4nesk +in2et +in1eu +ine3un +ine2x +in3f4 +1infiz +1info +2ing +4inga +in2g1af +in2g1ag +in2g1al +in2gam +ing1ar +in2g3at +3ingeni +in3g2er +in4g3erw +in2gl +in3gla +in3glä +in2gor +ing4s3am +ings6por +ing4s3pr +1inhab +2inhar +2inhau +2inhe +in2i3d +2inie +2inig +ini3k4r +2inis +ini3se +init2 +i3nitz +3inkarn +1inkas +in4k3ent +ink4er +in3k2ü +inma4le +4inn. +inne4n +in4ner4m +4innl +in2nor +1innta +2ino +in1od +in3ols +in1or +ino1s +inost2 +i3no3t +i2n1ou +i1nö +in1ö2d +2inri +ins2am +in6samt. +insch2 +2inse. +in2seb +2insed +2insen +ins2i +2insk +in4sm +3instal +in4s3tät +2inst2e +ins4tip +3instit +ins4to +4instra +ins4tri +in4strü +1insuf +ins3umz +in2sur +in3s2z +2inta +in3te +2inte. +1integ +2inth +inthi1 +int2o +2intö +2in3t4r +4inträ +3intrig +int3s +i2n1u +i4nuh +in3unz +4inverm +invil2 +i1ny2 +in3z2e +inz2i +inz2u +in3zwä +i1ń +2i1o +io1c +io2d +io3e4 +i2of +iof4l +i2oh +io3k6r +i3ol. +i3om. +io3me +i3oms +ion2 +i3on. +ion3an +io2n3au +ion3d2 +io4nee +i3ong +i3onn +io2nor +i3ons3 +i2ony +i2oo +i2o1p +i3o4pf +i3opt +i2or +i3or. +i3orc +ior2e +iore4n +io1r2h +i3orp +i3ors +i3ort +i3os. +io3sh +io5ska +ios2p +i2o1st +ios2u +i2o3sz +io3t +i3ot. +iot4r +i3ots +i2ou +i2ov +i3o2x +i3oz. +i1ö2k +i1ön +i1ös. +i1öst +2ip. +i1pa +ip2an +i1pe +i3per +2ipf2 +i3pfan +iph2 +2i1pi +ipi3el +ipi3en +ip2pan +ip3pe +ipp1f +ip4pl +ip3pu +i1pr +2ips +ip2sa +ip2sei +ip2sp +ips3t +ip4sta +ip4stü +ipt2a +ipt2u +2ipu +2i1q +i1r4a +i3ra. +2i3rad +i3ras +irat2 +i1rä +ir1äh +ir2b3l +ir1c +ir2ch1o +ir4e +i3ree +2irek +ire4na +i3ré +irg4s +ir2he +ir2i +iri3a +2i5rig +2irk +irke4n +ir4kene +ir2k3l +irli4n +ir2m1ag +ir2mak +ir2mau +ir2mä +ir2m1ei +irme4n1 +ir2m1o2 +irm4th +ir2mum +ir4munt +2irn +ir2n3a +ir4nat +ir2no +i3ro +1iron +i1rö +irpla4 +irre4l +ir2rh +ir3sche +ir4schl +ir4schm +ir4sch3r +ir4sch3w +ir3se3 +ir3s2h +ir2st +irt2s3t +2iru +ir1u2m +iru2s1 +i3r2ü +i3sac +i4samp +i4s1amt +is2ap +isa2r +is3are +i3sat +i2sau +is3auf +isau2g +i2säh +i2s1än +2isb +i2sca +i4schar +i3s2che +i4schef +i4sch3e4h +isch3ei +i6schemi +i6scher6z +i4schin +i5sching +i2schl +i2schm +isch3ma +i4schna +i4sch3re +isch3ru +i4schüb +i4schwa +i6schwir +i4schwo +isch3wu +i4schwü +i2scr +2ise +ise3a +ise1e +iseh2a +ise3hi +is4eind +i4seint +is4e3li +i6sel6ter +ise2n1 +ise4n3a2 +is2end +isen3s +ise4r3ei +is1erg +i2serh +i2s1erm +i2s1es4s +is2et +i4s3etat +i3s2eu +2isf +4ish +isi2a +i2s1i2d +isin3g4 +isi1s +i4ski +i4sku +is3la +3islam +2isma +2ismi +i2s1of +1i2sol +3isom +is2o2n3 +isonen4 +iso6nend +i2sop +is1org +is1ort +3i2sot +2isp +is1pa +i2spar +is1pe +is1pic +is2por +i2spro +is3sa +is4s1ac +is4sau +iss3che +is6schen +iss3erf +iss2po +is2st +is3sta +iss3tr +is3stu +is2sum +is4tab +ist3a2c +ist2an +is3tang +i1stat +is3täu +ist4e +i1stel +iste4n +istes3 +i1steu +ist2id +i1stil +is3t6o +is4toc +is3tör +is3tr +ist4ra +ist3rei +i1stro +is4tru +i1stü +i3suf +isum3p +i2sü +i1ß +iß1er2s +it1ab. +it1abs +ital3a +it1alt +it1a2m +it1an +ita3ne +it3anr +ita2po +it1app +it1a2re +it1art +i3tat +it1au +i3tauc +i2taut +4itä +it1änd +i2t1äs +ität2 +it1eff +i2t1ei +it2eic +2itel +ite4l1a +i4telek +i2temp +ite2n +iten3s2 +i4tents +i2tepo +i6tereig +it2erö +i8t7ersche +i4t1esk +i2t1ex +i3text +i5thr +i2thy +i5tic +i2tid +i5tig +1itii +iti3ker +it1in1 +i4tiso +iti3sp +iti2v5a +itmen2 +4ito +it1ob +ito4be +i5toc +i2t1of +it1o2p +it2os +2itr +it3raf +it3ras +it3rau +it3räu +it3re +i4tref +it4ret +it3rob +it3rom +i2t3run +it2sa +its1ag +it2s1e +it4se2h +it4s3e2r1 +it2s1o +2itt +it2teb +itt3hä +it2t1o4b +it2top +it4tri +itt3rol +itt6schi +itt4seh +itt4sei +itt4sor +itt2sp +itt4sti +it1uh +it1ums +it2ung +i2tuns +ituran4 +it1urg +itut4 +i3tü +it2ze2c +itz2er +itz3erg +it6zergr +it4z3erl +it2z1w +2i3u2 +iu4m1 +iuma2 +ium4se +iun2 +ius3t +i1ü4 +2i1v +i2v1ad +i2v1ak +i2v1am +iv1an +i2v1ä +i2veb +i2v1ef +iv1ei +iv1elt +ive4n +iv1ene +i2v1ent +ive3re +iver8folge +iv1erh +iver4kl +iv1erl +iver3s +ive3s +i2v1e4x +iv1ins +i3vol +i2vr +i2vun +i2v1ur +2i1w +2i1x +i2xa +ix2em +i3xi +ixt2 +4i1z +i2z1ag +i2zan +i2z1ap +i3z2as +iz1au +i2zaus +i2zän +izei3c +izeits4 +i2zele +ize2n +i4zener +i2z1erl +iz1ir +i2zo2f +i2zö +i2zuna +i2z1w +i3z2wi +izz4a +í1l +j2a +jab4 +ja1c +jah4r3ei +jahr2s +ja3l2a +ja3ne +jani1 +jani3t4 +ja5ru +jas2o +ja1st +jat2 +je2a +jean2s +je2g +jek2ta +jek4ter +jek4tin +jekt3o2 +jektor4 +jek4t3r +je2p +jes3t +je2t1a +je4t3h +je2tin +je4tor +je2t3r +jet3s2 +jet3t +je2t1u2 +je3v +je3w +ji2a +jit3 +ji2v +joa3 +jo2b1 +job3r +jo4da +jo2i +jong2 +jo1r2a +jord2 +jo2sc +3jou +jou2l +j2u +ju2b3l +jugen6 +jugend3 +ju1i +ju2k +ju3l2 +jung3s4 +ju3ni +ju3r4a +jur2o +jus3t +ju3t2e1 +2j1v +1ka +ka3ar +2k1abb +kab2bl +2kabd +2k1a2ben +2kabf +2kabg +2kabh +2kabn +2k3a2bo +2k1abs +2k1abt +2kabw +2kabz +ka1c +kade2r +2k1adm +2k3a2dr +3kadu +2kadv +ka1f4l +ka1fr +kaf3t2 +kag2 +kaga3 +2k1age +3kah +ka1ho +ka1in +kaken2 +ka1k4l +2k1akt. +4kala. +kala3b4 +ka2lan +kal3d +ka2leb +ka4l1eh +ka4lens +kal3eri +3k2alk +kal2k1a +kal4kan +kal2k3l +kall2i +2k1allt +ka2lop +ka2l1os +kal4tex +kal4th +ka2lu +k2amt +kan4al +ka4n1a2s +ka2nau +3kanä +2kanb +kan3d4 +2kanda +2kandä +kan2e +2kanf +2kanim +kank4 +2kanl +2kanom +2k1anor +2k1ans +k2ans. +kan4tar +6k5antenn +2k1anth +ka3nu +4kanw +2k1anzu +2kanzü +ka2o1 +3kara +2karbe +2karc +k2ard +kar3d2a +k1area +k2arg +ka3r2i +kari3es +k2ark +2k1arm +kar2pf +k2ars +k2ar3ta +k2arte +k1arti +4kartik +karu2 +k2arw +3k2asc +kasi1 +kas2o +ka4sp +ka2s3t +2k1ast. +ka4ste +kas6tras +3kasu +ka3sz +ka2tan +3kateg +ka3t2h +ka4t3r +2katt4 +kau4fer +kau2f1o +kauf4s3a +kauf4sp +kaufs7tem +k2aus. +2k1auss +2kausw +kau3t2 +2kauto +2kaz +1kä +k1ämi +2k1änd +kär2 +2k1ärg +kä2s1c +käse3 +4k3b4 +kbo4n +kbu2s +kby4 +2k3c +2k3d4 +ke2ben +2k1e1c +ke2di +k1ef +2keff +kefi2 +kege2 +ke2gl +ke2he. +ke2hen +kehr2s +kehr4s3o +2k1eic +2k1eig +kei2li +ke2im +2k1ein +ke1in2d +kein4e +k1ei1s +2keise +keit2 +ke2la +kel1ac +ke3lag +ke4l3am +kel1au +ke2lä +kel3b4 +keld4 +kel3eis +2ke2lek +ke2l1en +ke2l1er +kel7l4e +kell2i +ke2l1o2 +ke2lö +kel3sk +k4elt +ke2mi +2k1emp +k2en. +ken1a +ken3au +kend4 +ken3dr +ke2n1e2b +kenen1 +ke4nene +ke4nens +kener4n +4ken4gag +k5en6gel. +ke2nim +ken3in +4kenlad +4kenläd +kenn2a +kenn2e +ke2no +4kensem +ken3si +ken3s2k +ken5s6tei +ken3sz +k3en4te. +ken6ten. +2kentf +2k1entg +ken3th +2k1entl +2k1ents +2kentw +2kentz +ken3z2 +2ke1o2 +2kep +ke2pl +k2er. +ke1ra +ke2ran +ke2rau +ke2r1ä +ker4ble +k2erc +2kerd +ke2re2b +ke3reig +ker3ein +4kerfah +k4erfam +ker2fo +ker5g +k3ergeb +2kergu +ke6rin6nu +kerin6st +kerin4t +k3erken +k2erko +k2erl +k3er4lau +k3erleb +k6erlebe +ker2na +ker4nei +4k3erneu +ker6n5eur +k1ero +ker8oberung. +ke1rod +2k3eros +ker4reg +k2ers. +2kersa +kerz2 +k1erz. +ker4zeu +2k1er2zi +k6es. +ke2sa +k1ese +ke2sel +kes2sa +ke4t1a +ket2ag +kete4 +ke4t1eb +ke4tel +ke4th +ket3ha +ke2tu +ke1up +keu6schl +2k1e2va +2k1e2x +key3 +4k3f4 +2k3g2 +kga4s1 +kge3s4 +2k1h4 +kho3m +k3hu +ki3a +ki4ad +kia2r +ki1c +2ki2de +ki3d4r +k2ids +2kidy +ki2el +kie4lei +kiel3o +2kiern +kier2s +kier4st +kie2z +ki1f4l +ki1f4r +ki3k4 +2ki3l2a +2kilä +ki3lo +3kin. +4kindex +2k1indi +2k1indu +2k1inf +king3s +2kinh +k2ini +kini3k2 +k2inn +ki3n4o3 +kinos2 +kin3s +2k1inse +2k1inst +2k1int +ki3or +kio4s +3kir +2k1i2so +kis2p +kis3s +kist2 +kis4to +kiv2 +kive4 +2kiz +2k3j +2k1k4 +kkab4 +kl4 +4kl. +4kla. +2k1lac +klan2 +2kland +klan3du +k4lar +k1last +k1lauf +k3laug +2kläd +k2lär +k2le +4k3le. +kle2br +k3leg +2kleh +k3leit +k3lem. +2k3ler +kle2ra +2k3leu +kle3us +2klic +k2lien +k2lif +2klig +3k2lim +k2lin +k3lin. +3k4lina +k4link +k2lip +k2lir +k2lisc +2klist +klit2s +2k3liz +2k3loc +klo2i3 +2klok +3k4lop +k3lor +2klose +klost6 +2klöc +2klöf +k2löst +k4löt +k1lu +klu4b +k2lud +k2lug +k2lum +klung4 +2klux +2k1lüc +2kly +2k1m +4kma +kma2la +k2n2 +2k5nach +2k3nad +2knah +2k5nam +2k3näp +k3ne +k4nec +kne1e +2knes +2knetz +2k5neu +2kney +2k5niv +kno2b3l +k4nol +2knorm +2knov +k3nu +2knum +k6nur +1ko +ko5ad +ko2al +2k3oas +kobal2 +2kobj +kob4s +2k1o2fe +kof3f2 +koh4a +kohl2e +kohle3i +koh3lu +koka3 +ko3l2a +ko3le +kol2k3 +3kom +4k3omn +ko4mu +k2on +ko2nem +kon2i +kon3s4 +kont6e +ko2nu +2kop. +2ko1pe +kopfa2 +kop4fen +kop6f5err +2kop3s +ko3pte +2kopz +ko3r2a +kor2ba +kor2bl +kor2br +2k1orc +korden3 +korder4 +kor6derg +ko2rel +2k1org +ko3ri +kor3m +kor4nac +kor2n3ä +kor4no2 +2korpi +k2os +ko4sk +ko2sp +3kost +ko2stü +k3osz +ko2ter +ko3ti +kot4r +kot3s2 +kot4tak +k1ou +ko3un +3kow +ko2we +2k1o2x +1kö +k2öf +k1öl +2k1p2 +2k3q +k2r2 +2k3rad +2k3rah +k4ral +k3rats +2kraum +k4raw +k4raz +k4räc +2kräd +k4rän +2k3räum +2k5re. +2k3reak +2k3real +2k3rec +2kred. +2k3rede +2kredn +2kredu +2k3ref +4kreg +2k3reic +kre1i2e4 +kreier4 +k3reif +2k3reih +2kreim +krei6sei +krei4st +kreli1 +k3ren +k3res +2kresu +k3rev +2k3rh +2krib +2k3ric +2k3ries +2krip +k3risi +krob4 +k4roch +4k3roh +k4roi +k4rok +k4ron +k4rop +2krot +3kroth +k3rou +2kröh +2kruf +2k3run +4ks +ks3a2b +k3sac +ksa2k +k4s1amt +k2san +ks3a2r +k2sau +k2sav +k2säh +ksch4 +ks2chi +k2s1e2b +k2s1ec +ks1ei +ks2eid +ks2eif +k4seind +ks2end +k2s1eng +k2s1ent +ks1er +ks2ere +k2serf +k2serg +k2serk +k2serl +k2sers +k2serw +k2s1e2v +k2sex +ks3ha +k2s1i2d +k2s1in +k2s1is +ks3kl +k4sm +ks1o +ks2on +k2sop +k2so2r +k2sö +ks1pa +k2spal +k3s2pat +k2spä +k3spe +ks2pel +k2sph +ks2por +ks2pul +ks3s4 +k1st2 +k2stal +k4s3tanz +k3stat4 +k3stäl +ks4tel +ks2tep +k4stier +k2stit +ks4tol +k2stor +k4strop +k2stuc +k2stum +k2stur +k2stüt +k2s1u +k3sul +ks2zen +4k1t +kt1abr +kt1abs +k2t1ad +kt1akt +k3tal +kt1am +kt1an +kt2and +k2t1a2r +kta4re +kta3ri +k2t1au +kt3aug +ktä3s +kt1äu +kt1ein +k4t1ela +kte4n1 +kten3s2 +k2tent +k4tentf +k4tents +kten3z +kte1ra +kt4ere +k4t3erfo +kt1erg +k2t1erh +k2terö +kte3ru +kt1eta +k2tex +k2t3h +k2ti2d +kti2me +kt3ing +kt1ini +kt3inn +k2tins +ktion4 +kt2is +kti2s1e +kti4ter +k2t1of +k3t4ran +kt3ras +k2t3rau +k4tref +kt4ro +ktro1s +kt3run +kt3rü +kt3s +kts4a +kts2el +ktsen1 +kts1o +kt4sor +kts2pa +kts4t +kts2ti +kt1s2z +ktt2 +k3tub +kt1ums +k2tuns +kturen4 +k3tü +kt3z +ku2al +ku1c +kud4r +3kug +ku2h +2k1uhr +ku3la +ku3l2e +ku3l2i +4kulp +kul4to +kul2tr +kum2e +2kumg +2k3uml +kum2s1 +k2u3n2a +kun3da +kunden3 +kung4 +kun4s4 +kunst3 +2kunt +2kunw +2k1up. +kur2bl +ku2rei +kuri2e +kuri4er +2k1urk +ku2ro +kurs1c +kur2sp +kur4ste +kur4str +2k1urt +kus3a2r +ku4schl +ku2sp +ku2s3t +ku2su +2kut. +1kü +kü1c +3küne +3kür +kür4s +2k3v +2k1w +k3wa +2k3z2 +kze3l +3la. +la3ar +l1ab +3l2ab. +la3b2a +l2abä +2labb +lab2br +2labd +2la2ben +4labf +4labg +2labh +3labil +la2bit +2la2b3l +2labn +3lab2o +4labo. +la3b4ra +2labs +la2bus +2labw +2labz +la1ce +la2ce. +l2ache +lacks2 +1lad +2l1ada +2ladd +3laden +la3d2i +2ladj +2l1adl +2ladm +2l1a2dr +3l2adu +2laf +la2fa +la2f1ei +laf1r +laf3s +laf3t4 +la2fu +3lafü +la2g1a +lag3d +l2ager +4lagg +la2gio +lag3l +la4g3n +lago4 +la2gob +2la1ho +3lai +lake2 +la2kin +l2akk +la1k4l +la2kro +lak3t +2l1al +3lala. +la2lar +3lali +4lalt +l2ama +lami3t +lam2m1a +1lammf +2lamn +la2mor +l2amp +2l1amt +lamt4s +la4mun +la2na +la3nad +la3nan +la4nat +la4nau +2la4nä +3l2and +lan2da +lan4dam +land3au +lan6d5erw +lan6d5erz +lan6d5inn +lan2d3r +la2nem +lan3erd +laner4f +2lanf +lan6g5esc +lang3s4 +2lanha +l2anhe +2lanl +2l1ann +l1ano +la2nof +2l1anp +2lans2 +l1ansi +2lantw +2lanw +lan2z1w +3lao +2l1apf +la2ph +l1a2po +lap2pl +la2r1an +2larc +lar1e2b +la2r1ei +la2rel +la4rene +larf4 +lar3g +lar3ini +2larm. +la2ro +2l1arom +l1ar3t +lart4h +l3arti +3laru +l2as. +la4sam +la4sä +4lasd +la5seb +la4sei +la4s1e2l +l2asg +2lash +la2sin +la2sis +2lask +la2so +2la4sp +3lasser +lass4tr +l2a2st +las4t3an +la4ste +las4t3ri +la4stu +lat2ak +la3t2e +la4tel +la5t4i +2l3atl +2latm +lat2o +la2tö +la2t3ra +lat4ri +lat2s +lat3st +2lat2t1a +lat4tan +lat4tex +lat2th +lat4t3in +lat2t3r +latzer4 +1laub. +lauben6s5 +lau2b3r +laubs1 +laub4se +lau4fin +lau2fo +lau4fri +1laug +lau3gl +2laun. +la4us +3l2aus. +2l1ausb +lau6scha +2lausd +2lausf +2lausg +2lausl +2lausr +2l1auss +2lausw +2lausz +2lauto +lau2tr +la3va +lave4n +1law +lawa4 +l2ay +lä1c +3läd +2l1ähn +2lämt +1länd +2l1äpf +2läq +lär4mar +l1ärme +2lärz +lä2s1c +2lät +2läub +2läuc +2läue +1läuf +2läug +2läx +1lŕ +4l1b +l3bac +l2bant +lb3a2ri +lbau1c +lb1ärm +lbb4 +lbby4 +l4b3eink +l4b3eise +lbe4ral +lbe3rei +lberin5 +lbe7s +l4b1e4ta +l2b1id +l2b1ins +l3b2lat +l3blä +lb3le +l2bled +l2bli +l3blo +l3b2lö +l3b2lu +l2b1o2ra +lb3rea +lb2s +lb3sa +lb3se +lb4sh +lb3si +lb4sk +lb3so +lb3sp +lbs4t +lbst3ac +lbst3ei +lbst1u +l2b1uf +l3bum +lbu4n +lbzei2 +2l1c +l3ca +l3che +l4chei +l4chent +l3chi +lch3le +lch3li +l3chlo +lch3n +lch1ob +lch3r +lch3s2 +lch3ü +lch1w +l2ck +l3cl +l3co +4l1d +ld3a2b1 +ld2ac +ld3a2ck +l2dad +l2daf +lda2g +l2d1ah +l2d1ak +l2d1al +l2d1a4n +ld3ane +lda2r +l2d3ari +ld1arm +ld1ass +l3dat +l4d3ato +l2d1au +ld3aus +l3däm +ld1är +ld1ät +l3de. +lde4ben +l2dein7 +l2deis +l2d1elf +l2d1e2mi +l2d1ems +lde4na +lden5erg +l4dentl +l3der. +l4d3erfa +l6der6geb +ld1erh +l4der4he +l3d2erl +l6d5erlas +l3d2ern +l2d1er2p +lder4tr +lde3sa +l2d1es2s +lde3str +l2dex +ld1id +ld1i4mi +l2dob +l2dop +ldo2r +l2d1ori +ld2os +ld2ö2 +ld3r +ld4ram +l2dran +l2drec +ld5rie +ld4ris +l3d4ru +l2drüc +ld3sa +lds4an +ld3st +ldt4 +ld3th +ldt5s +ld3tu +l2d1ul +l2d1um +ldwes4 +1le +le2ad +le3ar +le2as +leben4s3 +le2bl +le2b3re +2lec +lech1a +le2chi +lech7t6e +le2er +le3f2a +2l1eff +le2g1ab +leg1as +le2gä +lege1i +le2gl +lego3 +leg4r +3leh +4lehe. +leh3r2e +4lehs +4leht +lei4ble +l2eid +leif1a +lei4fan +lei4fei +leifer6g +leif3s +2l1eig +3leih +lei3l2 +leim3p +l2ein. +l2eind +lein4du +l4eine +lei6nerb +le2inf +le2ini +4leink +4l3einsa +2leint +l2einu +le4is +leisch5a +lei8schei +lei6scho +lei6sern +l1eisf +leis6s5er +l4eist +lei4str +lei4ßer +l2eit +lei2ta +lei4to +leit3sk +leit3s4t +3leko +2lektr +2lekz +3l2ela +le2le +le3lei +2lelek +4leleme +le3len +le3les +2lelf. +l2eli +l2em. +le2mau +le2m1ei +3lemes +3lemet +lem1o2 +le2mor +2lemp +lem3s +le2mu +le4mun +l4en. +len1a +le4na2d +le4n3an +le4n3a4t +2lency +4lendet +l1endp +4lendun +le2n1ed +4lenerg +le4neur +4leneuv +len4gag +len4kau +len4k3lo +len4klu +l1enni +len6sein +4len4sem +len3ska +len3sz +2lentf +2l1entk +4lentla +2lentn +4l3en4tro +4l3entw +lent4wä +5lentwet +2lentz +2l1enzy +leo2f +le1os +2lep +3lepa +3lepf +4l1e2pi +3lepr +lep5t +l2er. +l2e1ra +le2rag +le2rap +le2ra2s +le2rau +le2r1ä +le2re2b +ler2e3c +l3ereig +le4r3ei4m +le4r3eis +le2rel +le4reng +le4rerg +lerer5k +le4rers +l3erfas +2l1erfo +l2erfr +l2erfü +l1erg +l2erga +l4ergef +3lergeh +6lergen. +l4erger +l4erges +3l4ergew +2lergi +l2ergl +l2ergr +4l3erhol +lerin4s +lerk2 +l2erka +2lerke +l1erkl +4lerklä +l4erkle +l2erko +ler3kr +ler3l +5l6erlebe +3l4erlei +2lermä +ler4nal +3l4erne +ler4nei +2l1erö +3l2erra +ler4ric +l4ers. +l1ersa +lers2t +ler4sto +le2rup +l4erwa +ler4wer +2ler2wo +2l1erz +ler2zä +l3erzeu +ler2zo +l4es. +les2am +les4e +le3sei +2l1esel +le3s4h +lesi1 +le3sk +les4ki +les2ko +le2spo +lest6 +le1sta +leste3r +lester6i +les2ti +le1sto +le1str +3lesu +4lesw +2lesy +2le2tap +2le2tat +le2thi +let2i +letsche6 +let4tel +let4top +lett1r +letts2 +le2u +4leue +3le3u2f +l2euk +2l1eul +le3unt +2leuro +3l2eut +le2vol +2lex +3lexik +le2xis +4l1f +l3fah +l2f1ec +lfe1e +lf3einh +l2feis +lf2en +l4ferei +lfe4rel +lf1erl +l3fi +l3f4lä +lf3led +lf3lo +l3f4lu +lf3ram +lf3res +lf4ru +lf4rü +lf2spe +lf2s3ti +lf2su +lfun2 +lfur1 +2l1g +l3gas +lga3t +lgd4 +lgen2a +lgens4 +lgeräu3 +l2geti +l3g2i +lg2lö +l3go +lg4p +l3g4ra +l3g4ro +lgung4 +2l3h2 +4lhe +3lhi. +1li +li2ad +li4am. +lian2g +li2ast +3lib4 +libi1 +li1c +lich4ta +lich4to +4lick +li2cka +li2cl +li3d2a +2l1ido +li4ds +3lie. +liebe4s5 +li1efa +3liefer +li1efk +li3efl +lie4n1a2 +li3ene +lien3s +lie4rei +lier4sp +lie2s1c +3lig +li4g3ers +lig4n +lig4ra +li2gre +li3ker +lik2o +likop4 +lik2sp +lik4ter +lik4t1o2 +lik2u +li3l +lil2a +li3m2a1 +limas4 +limat4 +2limm +3limo +2limp +lin2a +li3nar +2l1indu +li2nef +li2neh +li2nep +li2nes +2l1inf +2l1inh +li5nie +lin1it +2l1inj +lin4kan +lin4kar +link2s +li2nol +l2ins. +l2insa +4linsel +2linsp +2linst +2l1insu +2linsz +2l1int +li3nu +2l1inv +2linz +li2o +li4om +3li1pf +3lipt +3lis. +li3s2a +li3schm +li4schu +4lis2h +li3shi +2l1isl +2lisol +2lisot +li2sp +liss4 +3list +lit4a +li2tal +li3t2ä +l2i3t2e +li4t3r +lit1s2 +lit3se +lit3sz +li3tu +li6tun +li4tur +litz4er +3liu +liv2e +li2vea +li2ves +livi3e +li3vr +4lixi +li2zau +li2z3ä +lizei3 +4l3j +2l1k +l3kale +lk1alp +l3k2an +l3kap +l3kar. +lk1erd +lke3r2e +lk2l +lk3lad +l3k4las +lk3lic +l3k4lu +lk2men +lk4ne +lk5ner +lkor2b1 +l2k3ru +lk2s1 +lkse2 +lk4spe +lks3t +lkt2 +lk2ü +4l1l +l2labk +ll2abr +l2labt +l3labu +l3lage +lla3gl +l2l1am +ll3a2ma +l3lame +ll2anb +lla4ner +l3lans. +ll4anwa +ll1anz +ll1arm +l4latm +ll3att +ll3aufg +ll1aus +ll1äm +l2lär +llb4 +llch4 +lld4 +ll5ebene +l3lec +ll1ech +lle3er +l2l1ef +ll1eic +ll1eim +ll2eis +l4leise +lle2la +l3len. +lle4na +llen3dr +ll5en6dun +l4lentf +l4lents +l3lep +l3ler. +lle2ra +ll2ere +l6lereig +ller4fo +l8lergene +l4lergo +l4l3ermi +l4l3ernt +ll3ertr +ll2es +ll1exe +llf4 +llg2 +lli4gan +l2limb +l2l1ind +l4linf +ll1ins +ll3k4 +ll3l2 +ll5m2 +ll3n2 +ll1ob +l2lobe +l2lof +ll3ol +ll1opf +ll1or +l4lorb +l2lo2ri +l2l1ou +l3low +ll2säu +ll2s1es +ll3ska +ll2spr +ll3t +llt2e +llt2i +llti2m +llts2 +ll1ur +llus5t6 +l3ly +ll3z2 +2l1m +l2m3a2b +l2m1ad +lm1a2ge +lm1aka +l2m1a2m +l3mana +lm1apf +lm1art +lm3att +lm1äst +lmbu2 +lm1c +lmd2 +lm3e4dit +l2m1ef +l2m1e2p +lmer2 +l2m1erf +l2m1erl +l2m1erz +l4messa +l2m1id +lm1ind +lm1ins +l2mof +lm1orc +lm3p2 +lmpf4 +lm3s2k +lms6t +lm3ste +lm3s2z +lm3t4 +l2mum +l4munt +4ln +lna2r +ln3are +lnd2 +l3n2e +lnes2s +l2nin +lnus2 +l1nü +l1ny +1lo +lo4ak +3lob. +l2oba +3lobb +lobe2s +2lobj +l1o2bl +l2obr +lob4ri +lo4chel +2loe +l1of +lo2fe +lo4gh +lo2gl +lo2gor +lo2gre +loh2e +4l1ohr +loi4r +3lok +4l3okk +lo2k3r +5loks +l4ole +2l3o2ly +lomä3 +lo2min +lo4nin +lo2n1o +lo2o +2lope +lop2p1a +2lopt +lor3am +lor2an +lo4rä +3lorb +2l1orc +2l1ord +lo3r2en +4l1or3g2 +4lork +4lorp +2lort2 +lo4sa +3lose +lo4ske +lo2spe +lo2spr +lo4ste +los3to +los3t4r +4loß +lo2ta +lot4e +lot2h +lo3tha +loti4o +2l1ov +lo2ve +2lox +1lö +lö2b3 +2löck +2löd +lö2f +2l3öfe +2l1öhr +2lök +2l1öl3 +2löp +3lösc +3lösu +4löß +4löz +2l1p +lp2ar +l4p1är +lp2f +lph4 +l3phä +l2phir +lp1ho +l3phr +lpt4 +l3pu +2l1q +2l3r2 +lrau2s +lrebs2 +lre1s +lrö2 +lrut4 +4l1s +ls3a2b +l3sac +l2s1a2d +ls2al +l4s1amb +l4samp +ls2amt +l2san +ls3ane +l3sare +l3sarg +l3sark +lsau2 +lsau4m +lsau4r +l3s2äm +ls2äug +ls1äus +l4schin +l4schmü +lschs2 +l2s1e2b +l3seil +ls2ele +ls1eli +ls1er +l2serf +l2serg +l2serh +l2serk +l2serl +l2sers +l2serw +lse2t +ls1eta +ls2ext +ls3ha +l2s1id +l2simp +ls2kal +l3s4kele +ls2ky +l2sop +l4s3ort. +l3s2öl +l2spac +l2s3ph +l2s1pir +l3s2pit +ls2po +l3spri +ls2pu +l3spul +ls3s4 +lst2a +lstab6 +ls3tabl +ls4taf +lstahl3 +l2stas +l4stat. +l4state +l4s3täti +l2ste +l3stea +l3stec +l3steh +l3stei +l4steil +l3stel +l3stemp +l4sten +ls4t3erk +ls6terne +ls6terns +ls2tie +ls4tip +l2stit +l4stoch +ls4tol +ls4tri +ls6tru +l2s3trü +ls2tu +ls4tüm +l3suf +ls1um +l2s1un +ls2und +ls3unk +4l1t +l2tab +lt1abs +ltag4 +lt1alg +lt1am +l4tame +ltampe4 +l5t2an. +ltan3d +l2t1ap +lt1ara +lt1art +l3tarta +l3tartu +l2t3ato +l2t1au +lt3aut +lt1äh +ltbau1 +lte2c +lt1eh +l3tehu +lt1eig +lt1ein +l2t1eis +l4t1elt +lte3mi +lt2en +lten6gel +lten4sp +lt3ents +lte4ral +lter4fa +l3t2erg +lter6ken +lter4nä +lt2erö +lter4se +l4t1esk +lt2est +lte3str +l2t3h +l3thas +l4thei +lt4hem +l3t4hu +l3tic +l2ti2d +ltimo4 +l3tine +lti3t +l2t1o4b +l2t1o2f +l4tord +l4torg +l4t1o2ri +lto2w +lt1öl +lt1ös +l4t1öt +ltra3l +lt3räu +lt3rec +lt3rei +lt3ris +lt3rol +l2t3rö +l4ts +lts2eh +lt2se2l +lt4s3ort +lt2s1pe +lt3s2ph +lt2sti +lt3t +l3tub +lt1uh +l2t1um +lturan4 +ltu2r1i +l3tü +lu1an +4lu2b3 +luba2 +lubs2 +lu2dr +lu2es +1lu2f2 +2l1ufe +2luff +lu3fo +luf4t1a +luft3e +luf4tei +luft3r +lu2g1a +lu2g1e2b +lu2gei +lugen1 +lu2g3i +lug3l +lu2go +lu2g3r +lug3sp +lu2gu +2l1uh +lu1id +lu1is. +lul2ö +lumbi1 +2lumd +lume4 +2lumf +2lumg +2l1umh +2lumk +2luml +l2ump +1lumpe +lum2ph +2lumr +2l1ums +lu3mu +2l1umw +2lumz +1lu2n +2l1una +2l1unf +lung4sc +2l1uni +2lunr +2l1uns +2lunt +2lunw +4luo +2lur +l2ura +lu2r1an +lu2rei +lu2ri +l1urn +lu2ro +l1urt +lu4ru +2luse +lu2sp +lus4s3a +lus2s1c +lus4sei +lus4s3er4 +lus2s1o +lus4s1p +lus2s3t +lus4stä +1lu2st +lus6terl +lus4t1o2 +lust3re +lu2s1u +lu2t3a +lu4tas +lu4tau +lu2tä +lu2t1e4g +lu2tel +luter2 +lu4t3erg +luter4s +lu6t5ersa +2luto +lu2t1o4f +lu2top +lu4t1or +lu4t3r +lut5schl +3lux +2lüb +3lübd +lück4e2 +lücker3 +5lüd +2lüh +lü2hel +lüh1l +2l1v2 +lva3 +l3vl +lv3r +4l3w +2lx +1ly +ly1a +ly3c +2lymp +3lyn +ly3no +ly1o +ly3onn +3lys +ly3t +2l1z +l2z1ac +l2z1ag +l2zan +l2z1ap +l2zat +lz1aus +l2zäp +l2zär +lze2l +l2zele +l4z3enth +l2z1er2h +l2z1id +lzi4m +lz1imi +lz3l +l2zo2f +l2zö +lz3t2 +l2z1u4fe +l2z1ur +lzvol2 +lz1w +lz2wec +l2zwu +1ma +3ma. +maa2 +m1ab +m3a2bar +m2abä +2mabb +m2abe +2m3abf +2mabg +2mabk +m2abli +2mabm +m2ab4ra +ma2bri +2mabs +2mabt +ma3chan +mach2e +mach8terh +mach8t7ers +mach4tr +ma2ci +mack2s +ma3dac +mada2m +m2adä +ma2del +2m1adm +2m1a2d4r +ma4d2s +mae4 +ma1f4 +mag2a +ma2ge. +ma2geb +ma2gef +ma2geg +ma2gek +ma2gep +ma4ges. +ma2get +ma2gev +ma2gew +2m1agg +magi5er. +magi5ers +ma3gl +ma3g4n +2m1ago +mahl4st +ma1ho +mai4s3e +ma2ke. +2m1akt +mal2ag +mal1ak +ma4lakt +ma2lan +ma2l3at +ma2lau +2mal2de +m2aldi +ma3l2e +ma4lex +mali1e +mal3lo +2mallt +m2alp +mal3t +malu4 +ma2l3ut +3malv +ma2mid +mam3m +2m1a2nal +ma2nar +2m1a4nat +ma2nau +2m1anä +2manb +man2ce +man3d4 +man3ers +ma2net +m2anfr +man3g2 +m4angel +man4gl +2m1angr +m2anh +3manip +2manl +m2anle +5m2ann +2m1ansa +2mansä +man2th +mant3he +2mantw +manu3 +2manw +2manz +m1anza +ma2or +ma1q +4marag +mar2an +2marb +mar3g2 +3ma1rh +ma3r2i +m2ark +mar2kr +4mar2o +maro3d +4marr +mar6schl +mar6schm +mar6schr +mar2sp +mar2su +2m1arti +ma3r2u +m1arz +3mas +ma3s4a +mas2e +ma3s2p +massen3 +mas4st +mas4ta +mas4tel +mas4ti +mas4to +mas4tr +ma4s3z +3maß +ma2ta2b +ma2tan +ma2tä +m3a2tel +ma4t3erd +ma4t3erz +m4atme +2matmo +ma4tort +mat3se +mat3sp +matt4r +mat3url +2m1au2f +3maul +3ma3un +mau3r +2mausd +mau2ta +m4ay +ma1yo +1mä +2m1ähn +mäh1r +2m1änd +2mäo +2m1äp +2mäq +mär1 +mär2kl +mär2z +mär4zer +3mäß +mä3t4r +mäu2s1c +2m1b2 +mbe2e +mbera2 +mbe3r2e +mbert4 +mb4l +mble1i +m3b4r +mbu3sc +mbut2 +mby4t +2mc +m3ch +2m1d +m2dan +m2d1a2s +md3ato +md1är +mde2a +m2dei +mder2 +m2d1erl +md3ras +md3s2e +mdt4 +m2d1um +1me +me3a +meb4 +me2ben +3mebr +me1c +medi3e4 +me1ef +me3e4n1 +mee4rei +2m1eff +meg4 +mega3 +me4gel +3meh +meh6l3er +meh6rert +2m1eif +2m1eig +m2ei3l2 +mein4da +meinde3 +meiner6k +3m2einu +3m2eist +me3l4ant +me2l1au +melb2 +mel3d2 +melde3i +me2lek +2melem +me2ler +melet4 +2melf. +3melk +mel4k3ei +mell2 +3melo +me2lob +mel2se +mel3t4 +6mel6tern +2m1e2mis +2m1emp +2m1e2mu +me3nage +me4n3an +men3ar +me4nas +men3au +2m1endl +menen1 +4men4gag +men3ge +me2nim +men3k4 +men2on +men4se. +6mensemb +men4sen +men4ser +men6ses +men2so +menst4 +m4enta +men4t3ak +ment5eig +men6t5ers +2mentn +ment4sp +me1o +2meou +2meö +2mepa +2m1e2pi +3m4er. +me1ra +me3rak +mer4a3s4 +mera3um +me2re2b +me4rens +mer4err +mer4erw +mer3f +4m3ergän +me3rid +merin4d +merin4t +4merklä +mern3s2 +m4ersh +mer3sm +mer4sto +mert4r +merz6eng +3mes +me2sal +me4sä +4meser +mes2po +mes1pr +2mes2sa +mess3an +mes6ser6g +mes4s1o +mes2sp +mes2st +me1sto +me3sze +me3ta +meta1s +me3th +me4trig +met6t5en6d +me3tu +meu1 +2m1ex +me2xe +1mé +2m1f4 +mfi2le +2m1g2 +2m1h4 +1mi +mi3a2b +mia2n +mi1ä +mibi1 +mic1e +mi1ch +mi2ci +mi3da +mi2di. +mi3dr +2midy +mie3dr +mi3ele +mi4e3no +mien3s +mierer4 +mie4rob +mie1s +mie2ti +mie4to +mie2tr +mi1f4 +3mige +mi3h +mi2k1an +mi2kar +mi2kel +mi2kin +mi3k4l +mi3kr +mi2ku +mi3l2a +milch1 +mil4che +mild4s +mi3l2i +4milz +m2im2a +2m1imm +2mimp +min2ac +min5anze +m2inde +minde4s +2m1indu +mi2nef +miner1 +mi4n3e4ri +min2eu +2minfo +min2ga +ming3s +2minh +mi3ni +mini3k4 +mi3n2o +mi4n3of +2m1inse +mi3nu +mioni1 +mi1p +3mir. +3miri +3mirs +3mirw +3mirz +3mis. +mi2sa +mi3sau +mi4scha +mi4schr +mi4sch3w +mise1 +mis2p +mis5sar +mis4ser +mi2ste +mi1sto +mi1s4tr +3mit +mi2ta +mite2 +mi2t3h +mi2to +mi2tr +mit3s2 +mit5sa +mitt2e +mi2t1u +4mitz +mi3v2 +2m1j +4m1k4 +m3kn +4m1l2 +ml3c +m3le +ml3f +ml3k +m3lo +ml3p +ml3s +2m1m +mma3a +m2mab +m2m1ak +m2m1al +m2m1ans +mm1anz +mm1art +mma1st +m2m1au +mm1äu +m2m1e2b +m2m1ef +mm1ein +mme4lin +mme4na +mm2ene +m4mentl +m4mentw +mme4r3a2 +mme4rec +mme2s +mme3sc +mmes5t +mme4sz +m2m1eu +mmgas4 +mmi3el +mmi3k +mm1inb +mm1inh +m2m1ins +mm1int +mmi3sc +mmi1s4t +mmi5tw +mm3p2 +mmpf4 +mm2s +mm3sa +mm3s2i +mm3so +mm3s2p +mm3sta +mm3sti +mmt2 +mm3te +m2mum +mm2un +mmu3r +mmül2 +mmüll1 +2m3n2 +m4nesi +1mo +mo2be +2mobj +2m1obs +3m2od +mo3de +mode3s +mo2dr +m1of +mo2fe +3mog +2mog. +mo2g1al +3m2oh +moh2a +moi3r +mo2k1l +mol3d +3mom +mom2e +3m2on +mo2nä +mon4dac +mon4del +mon2do +mo2ner +mon2i +mon2s3 +mon3sa +mons4e +mon3s4u +mont2a +mon3th +mo1ny +3m2o2o +2mo1pe +mo2per +2m1opf +2mopt +mo1ra +mo2rak +mor2an +mo2rar +mor2d3a +mor2dr +morf4 +mor3g +morgen5s6 +mor3t2 +3mos +moster4 +mos2ti +mo3ti +mo5to +mot4r +mous2 +2m1o2x +mo1y +1mö +möbe2 +mö2c +2mö2f +4mök +2m1öl +m1ört +4m1p +mpa3ne +mpe4lin +mpe2n1 +m2p1ene +m2pf +mpf1ef +mp4f3erf +mpf3erg +mp6fer6ge +mpf3erp +mp6ferpr +mp4f3err +mp4f3er4z +mpf3l +mp2fr +mp1haf +mp1hos +mp3lei +m4p3lem. +m2p3len +m2p3les +mp4lis +m3pon +mpor6tag +mpor6ter6 +mp3sh +mp3str +m3pu +2m1q +2m3r2 +4m1s +m2sam +m2san +m4sap +ms1as +m3sat +m2sau +msau3e +m3sä +m4s1än +m3sc +msch2 +m4sco +m3se +m4s1e2d +m4s1ef +m4sein +m4se2le +mse2n +m4s1ene +m4sent +ms2erh +m4s1eu +m4sex +mso2r +ms1ori +m2spä +m2sped +ms2po +m2spot +m2spro +ms2pu +ms3s4 +m3stä +m3steh +m3stei +m3stel +ms2ti +m2stit +m3s4to +m3s4tr +ms5trä +m3s2tu +ms4tü +ms1ums +m2sü +m3sy +2m1t +mt1ab +mt1ak +mta2m +mt1ar +mt3arr +mt3aug +m2t1e2d +mt1ein +mt1eis +mt1elt +m4tenga +m4t3engl +mt1ent +m4tentf +m4tentg +m4tentr +m4tents +m2t1erb +m4t3erei +m2t1erf +m2t1erg +m2t3e2r1i +m2t1erk +m2t1erl +m2t1ers +m2t1ert +m2t1eta +m2t1eu +m2t1ev +m2t3h +m2ti2d +m2tim +m2t1in +m2t1i2r +mti2s +mt1ita +mtmen2 +mt1ob +mt1op +m2t1öl +mt1ös +m2t3ro +m2trö +m4ts +mt2sa +mt3sco +mt2s1e +mt3send +mt3s2ka +mt3s4kel +mts3tät +mt3stu +mt1um +mtu3re +m3tü +mt3z +1mu +mu1a +mu3cke +mu4ckel +2m1uh +mu3la +3muld +mul4lau +3mult +m4umb +3mumi +m1ums +mum2s1p +3mun +mun6derf +mu2ner2 +4m1unf +4m3ungeb +mu3ni +mu4nin +4mu4niv +4munw +4munz +muru2 +mu4r1uf +3m4us +mu4s1a +mu2s1o +mu2sp +mu2s3t +4must. +must4e +mu2su +mut1au +mut4str +1mü +2müb +3müh +mü2her +mühl1a +mül4len +3mün +3müt +mütter3 +2m1v +mvoll1 +2m1w2 +mwa2 +mwa4r +mweg4s +mwel4 +mwelt3 +mwu1 +3my +my1al +my3l2 +my2s3 +2m1z2 +1na +3na. +2n1ab +na2bä +naben3s4 +n3abh +3nabi +na2b3l +na2bor +na2br +nab4rü +4n3abs2 +na2b3u +3nac +na2ch1 +nachen4 +na5chen. +n3achse +nach3sp +nach8t7ersc +nacht8raum +5nachw +na3dab +4nadd +nade4l1 +na2der +4n1adl +4n1adm +4n1a2dr +4nadv +3nae +2n1af +na1fra +nag2a +na2gem +4n1agg +n1a2gi +na3gin +na3g4r +3n2ah +na2h1a +4n3ahn +4n3aho +3nai +nai2e +n1aig +4n1air +nai4re +n2ais +2n1ak +na2ka +3nakä +3nako +na2kro +4nakt +n4al. +na2l1a2 +nal3am +na4lar +na2lä +2n1albk +n2ald +nal3da +n4ale +na2leb +nal3ei +na4l3ent +na6lerei +na4ler4g +na4lerm +na4l3erw +nales2 +nal1et +nal1ex +nalf4 +nalg2 +nal3gl +na2lid +nal3l2a +nal2ph +n2als. +nal3t2 +nal5tr +n2alty +na2lu +2naly +na2mat +3name +na3me. +4na2mei +n4a3men +namens3 +4n1a2mer +na2mid +na3m4n +3n2amo +n1amp +nam4sp +2n1amt +namt4s +n1an +2n3an. +4na2na +na4nat +n3a4nä +4n3anb +n3and2 +nan1eu +4n3anf +4n3ang +4nanh +2nani +4n3ank +4n3anl +3n2ann +4n3anna +4nano +4n3anp +2nanr +4n3ans4 +2nantr +2nanw +n2anz. +nanzen4 +nan6zene +nan6zeng +na3ot +na2per +n1apfe +4napfel +na2pos +na2pr +nap2si +n1aq +n1ar +3nar. +na2r1a +2narc +n2ard +n2are +3nar2i +n2ark +n2arle +n2aro +na2rom +nar2rh +2nart +n2arta +n2arth +na3r2u +3nas +n4as. +na3sä +na4schw +n2asf +4n1a4sp +nas2s1c +4n1assi +nas4ta +na2str +4nasy +nasyl2 +na2sym +3nat +na4t3au +nat1ei +na2tem +na2th +4natm +nat2o +4natom +5nats1 +nat4sa +n1au +4nauf +nauf4fr +nau2fr +5naui +3n2aul +4nausb +4nausd +4nausf +4nausg +4nausl +n2auso +4nausr +4n3auss +4nausw +4nausz +3nav +nave4 +navi5er. +navi5ers +1nä +4näb +3n4äc +3näe +n1äf +3näg +3nähe +nä2hi +3nähm +4n1ähn +nä2hu +3näi +2n1ä2m +4n1än +4näpfel +2näq +när4s5t +3näs +nä2sc +n2äss +4näst +2näu +3nä1um +4näuß +4n3b4 +nbe2in +nbe3r2e +nbes2 +nby4 +2n1c +n2c3ab +n3can +n3ce4n3 +n3ces. +n3chl +nch3m +n2ck +ncor2 +n5cu +4n1d +n2da2d +nda1f +nd2ag +n3dai +n2d1ak +n4dakt +n2dana +n2dani +n2danl +nd1ann +n2d1anz +n3dap +nd3arr +n3dat +nd3att +nd1au +n2daut +n2dax +nd1c +nde4al. +n2d1ede +n3dee +n2dei +n4dei. +nd3elfe +ndel3l +ndel4s3a +ndels5en +nde4mot +nden3sk +n4dentl +n4dents +nde3o +n5der. +n5deren +nderer3 +nd2erh +n5deri +nder6läs +nde4rob +n4de4ros +n6der6sat +nder5ste +n3d2es1 +nde2se +ndes3s +n2deth +ndia3 +nd1imm +n2dob +ndo1c +n2dof +ndo6na +n2dopt +nd1or +n2do2ri +ndo1st +n2d3ott +n2dö +nd2ös +nd4ram +n2d3rat +nd3rau +n2d3re +n2drif +n2droc +n2drod +n2d3rö +n2drui +n2d3run +nd4sene +nd2spr +nd3th +nd3ti +ndt4r +n2duns +ndwa5re +ndy3 +1ne +3ne. +ne2ap +3neas +ne3at +ne3au +ne2bl +2n1ebn +neb4r +2nec +3neca +3nece +ne1ck +neck2a +ne2dit +2nee +neei2 +ne3e4in +ne3eis +neen2 +nee1r2 +nee3t +n1ef +n2ef. +n2e3f2a +2nefr +2n1egg +neg4l +n1e2go +neg4r +n1e2he +2nehe. +2nehem +2nehen2 +ne3her +3nehm +4n3ehr +2n1ei +3neia +4neic +nei4dei +4neier +3neigt +3neigu +4neing +4neinh +4neinl +4neinz +4neip +neiss4 +ne2ke +2n1eks +nek3t2 +ne2l +3ne3lä +nel3b +n1ele +4nelek +4nelem +ne3len +ne3l2i +ne4lim +ne4lit +3nelk +n2ell +nel2l1a +nel4lei +3ne3l2o +3nelu +n2em. +4n1emb +n1emi +4n3emp +2n1ems +4nemu +3nen +n4en. +n2e4n3a +ne5nac +n2enb +n2enc +nen4dar +4n1endb +4n1endd +4n1endf +n1endg +4n1endh +4n1endk +n1endl +4n1endp +4n1endt +4n1endw +ne2n1e2b +nen3ei +nene4m +nenen1 +ne4nene +ne2neu +n2enf +4n1engb +nen4gen +4n1engs +4n1engt +n1engu +n2enh +ne4n3i +n2enj +n2enk4 +n2enm +nen4nar +ne2no4 +nen3s2e +nen3sk +nen3s2p +5n2en3t2a +4n1entb +4nentd +4nentf +5n2enti +4n1entl +4nentn +5nentr +4n1ents +4n3entw +4nentz +ne4n3u +n2env +n2enw +nen5z2e +ne2o3b +ne2oh +ne2or +neos4 +3nepa +ne2pen +2nepf +ne2pi +ne2pos +nept4 +n4er. +ne1ra +ne2ra2b +ne2rac +ne2r3af +ne2rag +ne3r4al +ne2ram +ne2ran +ne2r3ap +n2erat +ne2rau +nerb2a +4n3erbe. +4n3erben +2nerdb +nere2 +ne2reb +ne2rec +5nerei. +n1erf +4nerfas +3nerfr +2nerfü +2ner3g4 +3nergr +n1erh +4n3erhö +3neri +n2erj +n1erk4 +5nerka +n2erkö +n2erli +2n1erlö +n1ermi +n2ern. +2n1ernä +4n3erneu +2n1ernt +n1eros +n1eröf +ne1rös +n2ers. +2n1ersa +4n3ersts +nert4 +3nert. +ne2rup +n2erv +4nerwar +2n1erz +nerz2a +3nes +n2es. +ne2sal +nes2an +ne2sei +ne2s1ev +2ne3sh +nesi1 +ne3ska +ne2s1of +ne2s1or +ne2s1pa +4n1es2si +nes4sig +ne1sta +ne2ste +nes3ti +4n1est3r +4nesyn +3neß +ne2tab +2ne4tag +net1ak +ne2t1an +2ne2tap +2n1e2tat +ne4te2l +ne2th +ne4t3ha +ne3the +ne3ti +ne4tin +n4ett +net3ta +net3te +net3tr +2n1e2tu +net4zer +net2z1i +ne2u +neu1c +neu4ere +neuer4f +neuer4k +neuer4r +neuer4s +neuer4w +neu3g4 +n2eun +2n1eup +neur2 +3n2evi +ne2vol +n2ew +2n1ex +5ney +3nez +3né +2n1f +n3f2al +nfalt4 +n3f2ang +nf4ar +n3f2ä +n3f2en +n3f2er +nf2es +n4fex +nff4 +n3fi +nfi4le. +nf4le +nf2o +nfo1s +nf4r +nf3s2 +nf2tan +nf2t3r +nft4st +nfts3tr +nf3tu +n2f1u +4n1g +n2g1a2c +ng1ad +n2g1ak +ng1a2me +ng1ams +nga2n +ng1and +n2g1ans +ng1ant +n3g2ars +n2g1a2v +n2g1äl +ng3d4 +n2g1ein +ngelb4 +nge3l4ei +n3g4en +n5gene +nge5nerw +ngen3sa +nge4ram +n2g1erg +ng3erse +nger4zä +n3g4es +nge3s4a +nge3sp +ngg3s +ng3hu +n2g1id +ng2lad +ng2läs +n2glic +ng4lok +n3glot +n2gn +ng3ne +n4g3ni +ng4nom +ng2nu +ng2ob +ng1opf +ng1or +n2gö +n2g3rai +ng4ran +n2g3rat +ng3roc +ngs3au +ng4scr +ng4s3e4h +ng4sek +ng4sens +n4gt +ng3ts +n2gum +ngung4 +ngzei4t +4n3h2 +n7halts +n5he +nhe2r +1ni +3n2ia +ni3ak +nibb4 +ni1ce +n1id +3n2id. +ni2de +3n2i3de. +4nidee +n2idi +ni3d4r +2n3idy +n2ie +nie3b +ni1el +nie3l2a +nie4n3 +ni3ene +ni3eni +nie4rei +ni4erna +nie2sa +ni2eu +nife4s3 +ni1fl +ni2g1a2 +2n3i2gel +2niget +nig3li +ni2gn +ni2gre +nig4san +nig4sp +nihi3 +ni2kar +3nike +ni2kel +ni3k4erh +ni2ki +nik3ing +ni2kor +ni2k3r +nik3t4 +3n2il +ni3l2a +ni3l2i +4n3imp +n1in1 +3nin. +n2ina +nin2ac +ni2nal +3n2inb +2nind +2ninf +3ning +ning4s +2ninh +4nink2 +3nino +ni2nor +3n2inp +2nins +n2ins. +4n3int +n2i3nu +4n3inv +3n2inw +ni2ob +ni3ok +ni3ol +ni3ora +n2ip +ni4ron +n1irr +3n2is +ni4sam +ni2san +ni2sä +nis3cha +ni4schw +ni2s1e +ni3se. +ni2som +4nisot +ni2sp +ni3spi +nis3s4 +ni2s1u +2nit +3nita +ni2ti +nit2o +3nitr +nit3s4 +nit2ta +nit6tele +nit6ter6g +nit6t5er6k +nit4tra +nitt3ri +nitt4sa +ni3v2 +3nix +2n1j +4n1k +nk1abr +n2k1ac +nka2ge +n3kal +n4kalg +nk1ang +nk1apf +nk3art. +nka3sc +n2katm +nk1aus +n2kaut +n2k1äh +n2k1äp +nke2c +nk1ei. +nke4lei +n4kelem +nke4na +nken4te +nk2er +n4k3erle +nke4ros +nk3ersa +nke2t +nk1eti +n2ketu +nk1id +n2kim +nk1inh +n2k1ins +n4klade +n3klag +nk3leis +n2k3len +nk3les +n3klin +nk2lo +nk4nac +nk4neb +n2knis +n2knit +n2k1o4be +n2kopt +nko2r +nkord2 +nk1ori +n2k1ort +n2köl +nk4rab +nk3rät +n4kre. +n2k3rel +n2kren +nk3rep +n2k3rez +nk3ro +n2krol +nk2sal +nk2se +nk3sen +nk2so +nks2ti +nk3s2z +nk2tak +nk2tan +nk4tau +nk4tent +nk4terg +nk4t3ern +nkte3sk +nkt2et +nk2tin +nkt1it +nk2top +nkt1r +nkt3ric +nk2tro +nk2tru +nkt4sen +n2kum +nk1ums +nku2n +nk1urh +n2küb +2n3l2 +nla3ge +nle2ga +nle3x +2n1m2 +n3ma +n3mä +nmen2s +n5mi +4n1n +nna2be +n2nada +n2nalg +n2n1all +n2nan +nna3st +n2nau +n3nec +nn2ei. +n4nein +n3nelb +nne4le +nne3lu +nn2ens +nner4ei +n6n5ereig +nner4fü +nner6geb +nn4ergr +nn2erh +nn2erk +nner4la +nn2ero +nne2rö +nn3erwa +nner6war +nner2z +nne4s1e +nn2eu +nn2ex +nn3f +nng4 +n3n2i +n4n3iso +nnis3t +nno2b +nno3be +n2nof +n2nop +nno2r +nn1ori +nn4sam +nn3se +nn3s2p +nnst4 +nn4stoc +nn2stö +nn5t2a +nn2th +n2n1uf +n2n1unf +nn1ur +nnvoll4 +nnvol5le +1no +3no. +no5at +n2obel +2nobj +no2bla +n2oble +3noblo +3noblö +2n1ob2s +no1c +noche4 +noch4r +2no2d +no3dr +no2ed +n1of +no2fe +2noff +2n1oh +n2ohe +no3id. +2n3okk +nok2l +n4ol. +n3ole +no2leu +no4lig +no2liv +2no2ly +3nom2e3 +3nomp +non2e +n1onk +nons4 +n1ont +2nony +3n2opa +no2per +no2pi +n1ops +3nor. +nor2a +no2rad +n2o1rak +no3ral +no3r4ar +2norc +nor4da +3nordb +nor4des +nor2d5r +no3r2e +2n1org +3norh +3n2orl +5norm +norm2a +nor3mal +3norö +3nors +2n1ort +3n2os. +nos2e1 +no3sh +no5sk +no2s3p +2no2sti +nost1r +2nostv +nos2u +no2tan +no3tart +no2tä +not1e4i +no6tentr +no2ter2 +noterb3 +no2tex +not3h +no2tho +no2t3in +no2t3op +no2tr +3nov +2n1o2x +3noz +2nöd +4nö2f +4n1ök +4n1öl +n2ör +1n2öt +4n3p4 +npa2ge +npa2s +npf4 +npro1 +npsy3 +2n1q +6n3r2 +nran2 +nräu3s +nrebe2 +nreli1 +nre3s4z +nrö2s +nrücker6 +4n1s +n3sabo +n2s1a2d +n2s1agi +ns3a2k +n2sall +ns4alp +n2salt +ns4anat +n2sanm +nsa2r +n3s2arg +n3sark +nsa2s +ns4ath +nsau4r +nsau2s +n2saut +ns2av +ns2ax +n2s1än +ns2äug +n2s1äus +n3sche. +n4schef +nsch5eul +n4schl. +nscht4 +n3schu +nsch7werd +ns4cr +ns1eb +ns2eh +nse2ha2 +nseh5ere +nsei4n3 +n4seinf +n4seint +ns2ele +ns3elem +n2sem. +n2sene +nsen4sp +n2sepo +n2s1erf +ns1erg +n2serh +n2s1erk +ns4erko +ns3erle +n4s3erne +n2serö +ns1ers +n4sersc +ns3ertr +n2s1erw +n2serz +n2seth +n2sety +n2s1eu +ns2ext +nsfi2l +ns1id +nsi4den +n3sil +n2simp +ns2inf +n2sini +nsinn2 +nsinns3 +ns3int +n3sis +n4siso +nsi4te +nsi2tr +n3s2kal +n3s2kel +ns2kis +n3skle +n3s2ky +n3smara +n2s1o2d +ns1of +n2soff +ns4om +n4s1ont +n2s1op +ns2orc +n4s3ort. +ns2pac +nspa2g +n3spe +ns4pek +ns2pel +n5s4pen +n4speri +n4spers +n2sph +n3s2pi +ns4pie +ns4pir +n2spo +n2sprä +n4s3prie +n2spro +nsrü2 +ns3s4 +ns3tabl +ns8tagent +nst1ak +n4stale +nsta2n1 +n3stand +nst3ane +n3star +n2stas +n4stat. +n6staten +ns4tati +n4stats +n3stäm +n3s4tän +nst5eife +nst7einhe +ns4tent +ns2tep +nst5erge +n3steri +n5s6terne +n5s6terns +ns4teu +ns2ti +n3s4tic +n3stif +n4stilg +n3stim +n2stob +nst5opfe +ns4tor +ns4tric +n4strie +n4strik +ns4trip +ns6trun +ns2tu +nst3u4t +ns4tüm +n3suf +ns2um +ns1un +ns2ung +ns4unk +ns2unw +ns4unz +n2s1urs +n2sut +n3sy +ns4zene +4n1t +n3t2a3c +ntak4ta +nta4lin +n4t1all +nta2lo +nt2alp +nta3ne +n4tansp +nt1ant +n4tanza +n3t2arb +nt1ark +n3t2arm +n3taro +nt1ar3t +n4tarti +nt3artu +n3t2arz +n2tath +nt1äm +n2t1äu +nte3au +nte1e +nte3g6 +nt1eh +n3tehe +n2teig +n4t1ein +n2t1eis +nte4lin +n2t1e2mo +nt4en +nte4na +nten6te. +ntera2 +nte6r5eis +nt4erh +nt4erk +nt4erm +nt4ern +nt4ers +nt4ert +nte3sa +n4t1es4s +nte2st +n6testri +n2t1e4ta +nteu3 +nteu6eri +nte3v +ntge4n +nt3hel +nt3ho +nt4hos +n3thr +nt4hu +n2t5hum +nt4hy +n3t2i +nti3c +ntim3p +ntine4 +n4t3inf +n4t3inh +ntini1 +n5t4lem +ntmen2 +ntmo4 +ntni2 +ntnis1 +ntopf3e +n4torg +n4t3o4rie +nto1s +nt4ral +nt1rau +nt4raum +nt3rea +nt3rec +n5t4ree +nt3reif +n5trep +nt4repr +nt3rich +n4t3rieg +nt4rig +n2troh +n3trop +n2t3rü +n4ts +nts2ah +nt3sp +nt4spar +nt5spe +nts2t +ntt2 +n3tub +ntu4re. +ntu1s +n3tü +nt3z +1nu +3nu1a +nu4ale +nu3a2r3 +nubi1 +2nu1c +3nud +nude2 +3nue +nu2es +nuf2 +nu2fe +3nug +2n1uh +3nuhi +4nuhr +3nui +nuk4 +nu3kl +nu2kr +nul2l1a +nulle2 +nul4l3eb +nul4lei +n2um. +nu2ma +2n3umb +4numf +4numg +2numl +3numm +2numr +2n1ums +2n1umv +4numw +2n3umz +nu4n +4nuna +4n1une +3n2ung4 +4n3ungl +4n1uni +n3unk +2nunr +nun3s +4nunt +4nunv +4nunw +3nuo +2nup +2nur +nu2ra +nu4r2i +nur3s +nur2z +3nu2s +nu3sc +nu3se +nu3spo +nuss3er4 +nus6serl +3nut +nu2t1a +n3uto +nu4t3r +3nuu +3nux +3nuz +3nü. +2nü4b +nür1c +3nüs +1nüt +2n1v2 +n3ver +n3vl +nvoran4 +2n3w +1ny. +1nyh +n1yo +1nyr +1nys +1nyw +4n1z +n2z1ach +n2z1a2g +nza2k +n2zan +nz3a4ne +n3zani +n2zar +nza2s +n2zat +n2z1au +n2zän +n2zär +nze4l3a +n6zenerg +n4zen4se +n4zentl +nz3erem +n2z1erh +nz1erl +nzer4lö +nz5erste +nzer6tra +n4zerwe +n3z2es +nze3sk +nze2t +nz1eta +nze3u4t +nz1id +nzi2ga +nzig4s +n2zinh +n2z1ini +nz1int +nz3le +n2zof +n2z1op +n2zöl +nz3s +nz1wa +n2z1wä +n2zwet +n2zwir +n2zwö +n2z1wu +ńo1 +2o3a2 +o4a3bi +o4ac +oa3che +oa3chi +o4ad +oa3de +oad4st +oa3in +oa3k2e +oak1l +o4a3la +o4a3mi +oa4n +o2a4r +o2as +o5ass +o4at +o5au +o1ä +o1b +2ob. +o3b2al +ob2am +ob2as +ob1auf +2o3b2ä +2obb +ob2e +2obe. +2obea +2o3bec +2obef +o2b3ein +2oben +obe4na +oben3d4 +o2ber +o3ber. +o4berb +ober5eis +1oberf +ober3in +oberin6g +obe4ris +7oberungs +2obev +2obez +2o3b2i +obi4t +ob3ite +3obj +ob1la +ob3lei +1ob3li +2oblo2 +2ob2lö +ob2lu +2obo +ob1or +2obö +ob3rei +2obrü +ob3s2h +ob3sk +obs2p +ob3sz +2o3bu +o4bunt +obu2s +obu2t3 +2o3bü +o4büb +2oby +oby4t +2oc +o3ca +oc1c +o1ce +och1a +ocha2b +ocha2r +o1che +oche4b +o2ch1e4c +och1eh +och1ei +oche2l +ocher4k +ochi4d +och3l +och3m +och1o +och3ö2 +och3r +och1s +ocht4 +o1chu +ochu2f +och3u4t +och1w +o1ci +o1ck +o2ckar +o2ckau +o3cke +o6ck5ersc +o3cki +o4ckin +ock3sz +ock3ta +o1cl +o3cu +o1ç +o1d +2o3d2a +od3ak +od2dr +o3dec +o3d2e3i +odein3 +ode4l3ag +ode2n1 +ode2s1e +ode3sp +o3dex +2o3dia +odi3c +2odif +2o3dir +odium4 +2odn +o2don +odo4s +2odr +o2dre +odt4 +2o3du +o3dy +2o1e2 +oe3di +oe4m +oen1e +o3er +o4e3s +oe4sc +o2e3t +o3et. +oet4h +o3ets +2ofa +ofa2c +of1a2d +of1a2g +of2ang +of1au +2ofä +o2f1e2b +o2f1ec +o2f1e2d +o2f1ei +o2fent +2o3fer +o4f1erb +2o3f2es +o2f1e2t +of1eun +of2f1a +off3erz +of2f1in +1offiz +of2f3l +of2fo +of2f3r +offs2 +off3sh +off3si +off3sp +off3t4 +of2fu +2ofi +ofi3k4l +ofi3s4 +2o1fl +of3le +of3li +of4lö +2ofo +2ofö +2o1fr +of3rä +of4rü +of2s1 +of4sam +of3sä +ofs2ch +of4sen +of3sta +of4staf +of3str +2oft +oft2a +of2tei +of3th +2ofu +of3ur +2o1g +o2g1ab +o2g1ac +oga3d +og1ang +og1ans +o2g1ei +ogeld2 +oge2l1i +ogener4 +ogeni3 +ogen4id +ogerätein8 +og2gl +o3gh +ogi2er +ogin1 +o2g1ini +og1l +og3le +og2lo +o3g4n +ogo4i +og1o2ri +og3s2p +og1ste +og3sti +2o1ha +oh1alk +o1hä +o1he +o3he. +oh1eis +o3hem +o3hen. +ohen3s +o3her. +o3here +oh1er4t +oh1er2z +o3hes +2o1hi +2ohl +ohl1a +oh2la2d +oh2lä +oh3lec +ohl1ei +oh3lep +ohler2 +oh4lerg +oh4l3erh +oh4lerw +oh3lo +oh4l1o2r +ohls2e +oh2lu +ohm2 +1ohmi +oh4n1ac +ohn1ap +oh3nee +oh2ni +1ohnm +oh2n1o +ohn3sk +2o1ho +ohol1e +oho4len +o2h1o2p +2ohö +oh3öl +ohr3a2 +oh4rat +oh2rel +oh2rem +ohren3s +ohrer2 +oh4rerg +oh3rie +oh4rin +oh2rol +ohrt4r +oh1s +o1hu +oh1w +2o1hy +2oi +o1i2d +oi4da +o3ie +o1im +o1in +o4ine +oi2r +o2isc +o3isch. +o1ism +oiss2 +oi1th +o1i4tu +2o1j +ojek8tori +2o1k +ok2a +oka3b2 +ok3ac +oka3i +oka2la +okale2 +oka6lere +okas4t +ok2e +3o2kel +oki4o +ok1lä +ok2li +ok2o +oko4pt +ok2so +ok2s1p +ok5t2 +3okw +2ol +o1la +ol3abu +olaf4 +ol1ant +ol2ar +ol4arm +olar3s2 +o3l2as +olast4 +ol1a2v +4o1lä +ol1ät +4olc +ol2chr +ol4d1am +ol2dä +ol2d1ed +ol2dei +ol4d3eng +old5ersa +olde2s +ol2deu +ol2dim +ol2d3o +ol4dr +4ole. +o2l1ef +ol1eie +o2l1eis +oler2 +o2l1ert +ole1s +ole3s2t +ol2e3u2 +ol1exz +o1lé +ol2fa +ol2fem +olf3ere +ol2f3l +olf1r +ol2f3ra +olft4 +olge4ne +ol2gl +ol2g3r +ol2i +olie4n1 +oli2er +oli3k4 +oli5tu +3oliv +oli3ze +ol3ke +ol2kl +ol2k3re +ol2l1ac +ol2lad +ol2l1ak +oll3am +ol2l1au +ol2l1e2b +ol4l1e2c +ol2l1ei +ol2lel +oller6ge +ol4ler4k +ol4l3erw +ol4l3ess +oll3s2a +oll3sp +4olo +ol2of +olo1p +ol1ort +ol3s2k +ol4ster +ol3t4h +o1lu +olu2th +ol2y +ol2z1a2 +ol3zan +ol4z3ern +ol2zim +ol2zo +ol2zw +2om +o2mab +oma2bl +o2m1a2ge +om1alg +om1all +oma4ner +om3ansc +o4mante +o2m1ap +o2m1ars +o2m1art +omar4te +o4m1a2sy +o3mat +o2m1au +o2meb +om1ebe +o2m1ef +o2m1ei +o2mel +o3meld +o5men. +om1ene +o4mep +om1er2h +omer4s +o2meru +om1er2z +omi2c3 +omiet1 +o3mig +om1ind +om3ing +om1ins +o2m1int +om3ma +omm2e +o4mn +3omni +4omo +o2m3oa +o2m1org +om1o2ri +om3pf +oms2 +om3sk +om3t4 +o2mum +o4munt +2ona +on3a2b +ona3g +o3nal +onaler6e +on3ann +onan6z5ei +on1ap +o2narb +ona3th +onat2s +on2au +on3auf +2onä +on1äh +2onc +on2dan +onderer5 +onde8rers +ond1r +on2dra +on4drin +ond3sk +2one +on1e2c +o3nee +o2nef +one3h +on3ein +one2m +on1ema +one2n1 +o4n3ends +on2eng +onen3s2 +o3ner. +o2n1erb +on1erd +oner4fa +on1erg +o2nerh +on4erka +on1erö +on1ers +o3nett +on2eu +on3f2 +2ong +on3gla +ong4r +ong3s2 +on2gue +2o3ni +on2i3d +onie3g +o4nikr +o4nim +o4nind +on3ing +o4ninh +on2inn +o4nins +on3k2 +1onke +3onkel +onli4 +onlo2c +2onn +on3n2an +on3n2e +ono1 +o3nod +o2nof +o2noke +on1orc +on3ord +ono3s +onot4 +ons1a +on4sam +on2seb +onsen1 +onse4t +onsi2d +ons3ing +on4s3l +ons1p +onst2a +onst4r +ons5tri +on3ta +on2t1eb +on2te2l +ont5end +on4t3erl +on2th +on4t3rat +2onuk +o3nur +2onut +on3v +1ony +on3z2 +onze3in +o1ń +1oog +oo2ka +oo2k3l +oo2kn +oo2mo +o1op +o1or +oor3d +oo4sk +oos3s4 +oo2su +oo2t1a +oot1ei +oo4t3h +oo2tr +oot2st +oo2tur +2o1ö2 +2op. +o1pa +opab4 +op1akt +opa2le +o3pa5s +opa3s4t +1ope +2ope. +o1pec +2o1ped +op1ef +2o1pei +o1pek +2opel +ope3l4a3 +2o1pen +o2pera +op1erh +2opf. +op2f3a +op3fah +op2fä +o2pfe +op2fin +opf3la +op1flü +op2fo +4oph2 +o3phe +o1p2i +opi5a4 +opi3er. +opi5ers. +opie4r3u +opin2 +2opl +op3lag +o2p3le +op3li +o3p2n +2o3po +opo2la +op2pan +op4pl +1oppo +op2p3r +2oppt +2o1pr +3o4psi +op3sz +1op3t4 +o2pum +2opy +2o1q +2or. +or1a +2ora. +o1raa +2or3a2b +o2rabb +o2r3add +or3adr +o1r2ag +1orake +o1ral +oral3l +o4r3alm +or4alt +or2am +or3a2mi +o1ran3d4 +oran2f +o4rang +oran2m +oran4ze +or3ap +2orar +or3arr +o1ras +o2r3att +2orau +oraus6wa +2o1raw +o3rä +or1änd +or1ät +orb2l +or1c +2orca +or2ce +2ord. +4orda +ord1am +or2dar +or2dau +2ordb +ord3eng +orde4s +or2deu +or4d3ing +or2d1ir +or2dit +1ordn +or2do2 +2ordr +ord3s2t +ord3t +2ordu +2ordw +2ore +ore2a +o2r1e2b +o2r1e2ck +o5ree +or1eff +ore2h +or1eig +oreli1 +orems2 +o2r1er +o3r2ere +orer1i +o3r2ero +or1e2th +o2r1eu +2orf +or2far +orf3li +or3g4a +2orget +or3ghi +2orgia +orgi1e +or2gl +or3gla +or3gle +or2gn +2orgr +2orh +2oria +2oric +4o3rie. +o3rien. +o6rienti +o3rier +4oril +or1ima +ori4mi +4orin1 +o2rind +2oris +2oriu +2ork +or3k2a +or4k3ar +ork4r +ork2s +2orm +or2mam +or4mans +orm3asp +or2m1eb +or4m3erf +or4m3er4g +or2mor +orm3ord +or2mum +ormu4n +or4muni +or4munt +ormwa5 +or2n1a2c +or2nal +or2nar +or5ne. +or3ni +or4nin +or3no1 +2o1ro +o2r1ob +or3oly +oro3n2a +oro2pe +or1opf +o2ro2r +o3rou +o2r1ox +2o1rö +2orp +2orq +2orr +orr4a +or3r2e +or3rh +2ors2 +or3s4a +or3sh +or3si +or3sk +or3sz +or2t1ak +or2t1an +orta2r +or2t1au +or2tef +orte4n +or4ten5g +ort3erb +or4t3ere +ort3erf +orter6fa +ort3erg +or4terk +or4t3erl +orter6sc +or2t3e2v +or2the +or2tin +or4t3off +or4to2r +or2tö +or4trau +or4t3räu +ort3re +or2t1um +2o3ru +or2uf +or1uh +orum4s +o4r3un +o5rus +o2rü +o2rya +or3z2e +2o3s2a +os3ad +osal2 +osa1s +2osc +o2s3ca +osch3ar +o3sche +osch3le +os2co +2ose +ose1e +ose1in2 +os2el +ose2n +o2s1er4k +os2ex +2osh +o3s2hi +os2ho +os4hu +2osi +o3sk +o4ska +os2kal +o4ski +2os2kl +2os2ko +o4skr +os2lo +1osm +os4mog +2oso +osol1 +o2sö +2os1p +os2pac +os2pe +os3pec +o3sphä +o3s2po +os4pot +os2pra +2oss +os6s3a2c +oss3ala +os2san +oss3and +os4sä +os2sei +os4s3en4k +os4s3enz +os2s1ep +oss2er +os4s3er4b +osser4e +oss5erei +os4s3er4f +os2sik +os2sim +os2s1o2 +os4son +os2sp +oss1pa +os2s3t +os4sto +ost1a +os4tam +os3tarr +osta4s +os4tat +ost1ei +oste2n +oster3e +ost5erwe +oster8wei +ostes5s +ost3eur +os2t3h +os2tid +os3til +os2tit +ost1o4b +os3toc +os4t1or +o2stö +ost3ran +ost3rä +ost3re +ost3rot +ost3uf +os2tug +2osu4 +os1um +2o3sy +o3s4ze +2oß +o2ß1el +o2ß1en2k +o2ß1enz +oßer2 +o2ß1erb +o2ß1ere +o2ß1erf +oß1is +2o1t +o3tabe +o2t1abi +o2t1ah +o2t1ak +o3tal +o3tam +ot1ant +ota2s +ot1ast +o2t1au +o3tau. +ot1ä +o2teb +ote1i +o4t1eib +o4t1eic +ote3i4n +o4t1eis +ote4l1a +ote4lin +o3tem +o4t1emi +ot2em3p2 +ote4na +o4tentb +ot3entr +ot1erb +o4t1er2l +o4t1erw +ote2s +o3the +o4them +o2t3hi +o2thr +4oti +ot2id +o2til +o2t1i2m +ot2in +ot3inh +otli4 +ot2o +otob4 +ot3opf +oto4rei +oto1s +o2t1ö +o3tran +ot3rat +ot4rau +ot3re +ot3rin +ot3roc +ot3rus +ot2s3at +ot3sch +ots2en +ots1o +ots1p +ots2pe +ot2spr +ots3tau +ot3sti +ot3stra +ott1a +ot2tan +ot4ta2s +ot2teb +ot4terh +ot4terk +otte2s5 +ot2t3h +ot4tim +ott2o +ot2t3r +ot3t4ra +ot4tri +ot3t4ru +ot1url +o3tü +ouff6 +ou1f4l +ou4ge +ou3gl +o1uh +ou1is. +ou2le. +ou2les +2o1um +2o2u2n +oun4ge. +4o4ur +oure2 +ou2ret +ouri4 +ourie4 +ourme4 +our4ne. +ou3s2i +3outp +out3s2 +ou3tu4 +2o1ü +o1v +ov2a +2ovel +o3ven +ove3s4 +2ovi +oviso3 +2ovo +2o1w +o3wec +owe2r1 +o2wh +o3wi +o2wu +o1x +2ox. +ox2a +2oxk +ox3l +o2xu +1oxy +o1yo +oy1s2 +2o3z2 +3o4zea +ozen4ta +ozes4sc +4ozi +ozir3 +ozon1a +oz3z +órd2 +ö1b +öbe4l3i +öb2l +ö2b3le +ö2b3r +öb2s3 +ö1c +öch1l +ö2chr +öch2s +öch4ste +öchst5ei +öchst3r +öchs4tu +ö3cke +ö1d +ödel3l +öde1r +ödi3 +ödien3 +ödin3 +öd2st +1ödu +ö1e +1öf +öf2fl +öf3l +ö1g +öge3le +ögen2s1 +ö2g3l +ö2g3r +ö1he +öhe4n1 +öhl2e4 +öhre4 +öh3ri +ö1hu +ö3ig. +ö3isch. +ö1ke +1ö2ko3 +ök3r +ök2s +ö2l +3öl. +öl1a2 +öl1ei +öl1em +öl4en +öl2f1ei +ölf2er +öl1in +ölk4e +öl2k3l +ölks4 +öll1a +öl3le +3ölm +öl2nar +ölo2 +öls2 +öl3sa +öl3sz +öl3tu +1ölu +ölz2w +ö1m +öm2s +ön2e +ö3ni +önizi1 +önn2e +ön2s +ön3sc +ön3sp +öo1 +öo2ta +öoti1 +2öp +ö1pe +öpf3l +öp4s3t +ör3a2 +ör2b3l +ör1c +ör2dr +ör3dra +ö2r1ec +ö2r1ei +ö2r1e2l +ö2r1em +öre2n1 +ö2r1ene +ö2rent +ö3r2erb +ö2r1er2e +örer2f +ö2rer2g +ö2rer2l +ör2err +ör2erw +ö3r2erz +ör1ess +ör2f3l +ör2gl +ö2rim +ör2kl +örn2e +örner4v +ör1o2 +örpe2 +örs2e +ör3sk +ört2e +öru4 +ö2r1une +ö2sa +2ösc +ö2sch3a +ösche2 +ö4sch3ei +öscher3 +ö6sch5erf +ö6sch5eri +ö2schi +ö2sch1l +ö2sch3m +ö2schn +ö2schw +ös1ei +ö2sein +öse3str +ö3set +2ösl +ö2sp +ös2s1c +ös2st +ö2st +öst1a2 +ös3te +ös2th +ös3tr +ö3su +ö1ß +ößen3 +öß2ti +ö1t +ö4t3a +öte4n1 +ö2t3r +öts2 +öt2sc +öt2tr +ö1v2 +ö1w +ö1z +öze3 +özes4 +1pa. +1paa +1pac +p2ad +pa3da +2p3a2dr +pa1fr +1pag4 +pa3gh +pa1ho +1pak +pa1k4l +pak4to +3pala +pala3t +3palä +3pal2e +pa3l2i +1palm +pal2ma +pal2mä +pal2m1o +2palt +pal2ta +pal4tei +pal2tr +pa2m3a +pa2nar +pa4n3at +pan3d +pan4ds +pa2neu +panf4 +pang4 +pa4nisl +pank4 +2panl +2pann +panne2 +pan4n3eb +1pa2no +pan3sl +pan3t4h +1panto +2pantr +panz2 +pan5ze +1pap +papi2 +papieren8 +papie8r7end +pap2pr +pap4s +pa1q +1para +pa4r3aff +par3akt +pa4rant +2parb +1p2arc +par3d +2parer +parer8geb +1parf +2parfö +2parg +pargel6d +1park. +par4k3am +par4kau +par4kr +1park1s +par3m2 +par3ne +1pa2ro +2parp4 +2parr +4parta +1parti +1partn +3party +par3z +pas2e +pa3s2p +pas6sein +passer4 +pas6serg +pas2s1p +pa4st +2paß +pat1a +pat4c +pa5t4e2 +2patel +1pat4h +1pati +1pat4r +1pau +2p1auf +pa3uni +2pausz +1pav +pay2 +1pä +3pä2c +pä3cke +pä4ck3er +3päd +päde2 +pä2d1er +3pär +3päs +pä4t1e2h +pä4tent +pä4tep +pä4t3erb +pä2t3h +pä2to +pä4tr +pät3s4 +2p1b +2p3c +2p1d2 +pda4 +1pe. +pe2a2 +pea4r +pea4s +p1e2b +pech1 +1peda +1peel +pe2en +2pef +4p1eff +1peg +pei1 +2peic +1peil +p2eim +2peis +pekt4i +pekt4sp +2peku +1p4el +3pel. +pe2l1a2 +pe4lai +pe2l1ä +peld4 +3pele +pe4l1e2h +pe2l1er +pe2let +pe2leu +peli2d +peli4n +pe4l3ink +pel3inn +pel3k +pel3l2a +pell4e +pell2i +pe2lob +3pels +pel3sp +1pem +pe3nal +pe4nas +pen3d2a +pe4nen1 +pe4ni2t +pe2n1o +pens2a +3pen3si +pen3s2o3 +pens2p +pen6ster +1pensu +pen3sz +pent2a +2pentw +penty2 +1pep +pe3pi +pept2 +pe1ra +per2am +per3as +pe2rau +pe2r1ä +pere2b +perer2 +perer3z +pere1s +pe3r2i3d +3perio +1perle +3pero +per4r3an +1pers +2perse +2persi +3persp +peru2 +pe3run +1perü +perwa4r +pe3s2a +pese2n +1pes5s2 +pe2st +pes4ter +pest1o +3pet +pet4r +2pex +1pé +2pf. +p2f1ab +p2fad +p2faf +pf1ai +p2f1ak +pf1am +pf1ans +p2fa2r +pf3are +p2f1au +1pfä +p2fär +p2f1äu +4pfe. +p2fef +p2fei +pf1eim +pf1ein +pfe2l +p3fen. +p4fener +p2fent +p4f1ep +pfe2r5a +p4ferde +pfer6pro +pf4es +pf3f4 +p2f1i2d +pf1inn +p2f1in3s +pfi2s +pf1lam +pf4lan +pf3lä +pf4leg +pf3lei +pf3lo +p2f3om +p2for +pf3r +pf1ra +pf4rü +2pfs2 +pf3sa +pf3se +pf3sl +pf3sz +2pf3t4 +p2fum +2p3g2 +pgra2 +1ph +2ph. +ph2a +phal4te4 +p1hand +3pha1s +p1hau +phä1 +3phän +4phär +2phb +2phd +2p1hei +phen3d2 +phe4n1e +phen3s2 +2ph1ers +2phf +2phg +phien3 +phik1a +phi4kan +2phk +ph2l +2phm +2phn +p2ho. +p2hob +2phö +ph4r +2phro +2phs +ph3t4 +2phthe +phu4s +phu3t +2p1hü +3phy +2phz +pi2a1 +piab4 +pia3k4 +pi4ali +pia3n +piap2 +pias4 +pi1ce +pid2 +pi2el +piel3a +3pier +pie2ra +pie4reb +pi3gl +1pil +pi3le +3pilo +pil4zer +pil2zw +p2im +3pin. +pi2nad +3ping +pingen4 +ping3s +3pins. +3pinse +pin3s2p +pi2o +pi3o2i3 +pi3onu +pi3os +3pip +pi2pe +3pirate +pi3ri +3pirin +1pis +2piso +pit2a +pi3t2h +pit2s +pitz2e +pi2z1in +2p1j +2p1k2 +pku2 +1p2l2 +2pl. +3pla +4p3lad +p1lah +pla3na +p4lau +pla2y +3plä +2p3le. +ple1c +ple2e +p4leg +ple3n2 +2p3ler +2plig +3p4lik +p4liz +2p3lu +plu2s +2p3m2 +2p1n2 +1p2o +pob2 +po1c +3pock +3pod +3poe +po2el +2poh +po2i +po3id +3poin +3pol +po2lan +po2l1au +pold2e +po3li +polo3p +pol3z2 +pom2ph +2pond +pont2 +po1ob +po2p1ak +po2p1ar +po1pe +po2pl +po3pt +po1rau +porf4 +por3s +3portal +por2th +3porti +3porto. +3portos +3portr +por4tre +por6tric +poss2 +po4sta +pos4tag +po2stä +pos4tei +pos3tel +pos4tem +po1s4tr +post3ra +po2ta +pot1ar +3potä +3pote +pot2h +po2t3in +pott1r +po2t1u +po3un +po2w4 +po3x +pö2bl +pö2c +2p1p +p2p1ab +pp1ans +p2pat +pp1au +ppe3e +pp1ei +ppeli5ne +ppels2 +ppel5ste +pp2e2n1 +ppe4na +p2p1erz +p2pf4 +pp1fr +p2p1h +p4p1i4a +pp3l +p4p1lac +p4plan +pp1lä +p2ple +pp3oh +p2p1ö2 +pp3p4 +p2p3ra +p2p5rä +p2pri +pp3rol +pp3rot +p2p3ru +p4ps +pp3s4a +pps2p +pp3sy +ppt4 +pp5te +p4p1um +p2r2 +1prak +1prax +p4rä +1präd +1präf +1präg +1präl +3präm +1präp +3präs +1präv +2pre. +2prec +3pred +2pree1 +pre2ei +2preg +1prei +3preis +prei4s3c +prei6sei +2preiz +1prem +pren4ga +2p3rer +1pres +press4e +pri4e +2prig +pri2l1 +2pring +prings4 +1prinz +pri2t1 +prit3a +priter4 +prit5t +1priv +1pro +3prob +pro3be +2proc +7p4rod +3p4rog +3proj +4pross +pro1st +prot2e +3proto +2prott +2prö +1prüf +1prüg +2prüh +2prün +2p1s +4ps. +ps1ad +ps2hi +ps1id +p2sö +ps4pi +pss4 +p2st +p3sta +pst1au +p3stä +p3stea +p3stel +pst3erh +ps2th +p3s2ti +ps4to +p3stö +ps2tu +p3stü +3p2sy +4psys +ps2ze +2p1t +pt1a +pt2ab +pta2g +pt3a4t +p3te +p4t1e2b +p4t3ec +p4t1ei +p4tele +p4temp +4pten +p4t1en2g +p4t1ent +p4t1ep +pt3erei +p4t1erw +p4t1erz +p4t1e2ti +p2t3h +p3ti +p4t1in1 +pt3ing +pto2mo +pto2p +p4tos +pto2w +pt3r +pt3s2 +pt4sl +pts4t +pt1uh +pt1um +p3tung +pt1urs +ptü4 +3p2ty +pt3z2 +1pu +pu1a +pub4 +2puc +pu2dr +2p1uh +2puk +pu2kl +pu2k1o +pu2lin +pul2sp +pul2s5t +2pulw +pum2pl +3pun +4pund +pun2e +pun2s +4punt +2pur +pu2ra +pu2rei +pus2h +pu3she +pu2s3t +3put +pu5t2e +put2s +puzi3 +1püf +2pül +pül3l2 +2p1v +2p1w +pwa4r +3py1 +py3t +2p1z2 +qu4 +que3rel +quer5n +que4te. +1queu +1ra. +r1aa +ra2ab +2raac +2raal +ra3ar +r2a1as +r1ab +ra2b1ar +r2abä +1rabbi +rab2bl +2rabd +rabdru4 +ra2bei +rab2er +rab3erd +2rabf +2rabg +2rabh +1r4abi +2rabk +r2able +ra2bli +ra4b5lo +2ra2br +2rabs4 +2rabt +2r3abw +1raby +2rabz +r2ac. +ra2ce +2r1acet +ra4cheb +ra2cho +rach6t5rä +ra2chu +r2ack +1r2ad +r4ad. +rada2 +ra4dam +2radap +3radar +ra2dei +3radf +3radh +3radio +3rado +3radp +ra4d1r +rad5ri +rad5t4 +ra2el +r2af +raf3ahn +raf3ar +rafe2 +ra2f1er +raf3r +raft5s +rages4 +2ragg +ra3g4le +4ragm +ra2gn +r2ago +1rah. +rahle4n +5r4ahm +r1ahn +2ra1ho +ra3hö +4raht +r2ai +2raic +rail2l +2r3air +ra3ke +2rakk +3ra1k4l +ra2kre +r3a2kro +2rakti +ra2kus +3rakü +2rakz +r2al +r4al. +ra2la2 +ra4l3ab +ral1ak +ra3lamp +rala4s +ra2lä +ral3b4 +3r4ald +ra4l3end +ra4lent +ra4l5ern +ra3lex +r4ali +ra2lid +rali1e +ra4lind +ra4l3ing +2r3alk. +2r3alm. +2ralp. +4ralpe +r4als +ral3sk +ral3su +r3alt +3r4al5t4h +ra2l3u +3raly +rama3s +ra2mei +ra2mer +r2ami +r2amm +ram4man +ram6mens +ram6m5ers +ram4m3u +2ramn +3ramsc +2r1amt +ramt4s +ran3ade +r1a2nal +ra2nan +ra2nar +ra2nau +2ranb +r2anbe +r4anda +r4ande +ran4dep +ran4d3er +3r2andi +rand3s +rand5se +3raner +2ranf +2ranga +ran6g5e6be +1rangi +r2angl +rangs2 +rang5ste +rani1e +r3a4nil +ran3ka +ran2kr +ran2kü +4ranl +2r1anm +r2anmi +r2anmu +2ranna +rano2i +2r1anp +2ranr +2rans +r2ans. +r1ansc +ran4spa +4r5antei +r1anth +2rantr +1ranu +2ranw +r2anz. +r2ap +2rapf +2rapo +ra2pok +ra2pos +rap2pr +2ra2pri +2r1aq +r1ar +r2ar1a +2rarc +r2are +3r4arei +raren1 +r2arf4 +ra3rie +rar3in +ra3ris +r3a4rist +4r3arit +r2ark +raro2 +ra2rom +2rart +2rarz +rar3zw +r2as +r4as. +ras2a +ra4schl +ra3spr +ra2sta +r4aste +ras4t3ei +r3asth +ras4to +2rasyl +2raß +1rat +r4at. +rat1a +rat2ak +ra2tan +ra2t1ei +r3atel +ra4tid +2ratm +rat2o +2r3a2tom +ra5tor +rat4r +2ratta +2rattr +4ratz +rat3ze +4rau. +3raub. +rau3e4n +2rauf +rau3fä +2rau3g2 +3raum +rau4m3ag +rau4man +rau2m1i +3raup +4raur +2rausb +3raus2c +2rausd +2rausf +2rausg +raus8gewä +2raush +2rausl +rau2sp +2rauss +raus8scheidu +raus5se +2rausv +2rausw +2rauto +raut1r +rau4tra +rau4tro +raut5s +1raü +r2ax +raxe3 +r3axt +4räb +3r2äd +4räf +rä1fr +4räg +2räh +4räm +3rän. +3räni +3räns +2räp +2räq +2r1är +r2är. +rä3ra +rä1ro +rä2sc +räse2 +räte1s +3rätse +4rätz +rä2u +4räue +räu2s +räus4c +räu7schen. +2räuss +2räuß +4räut +2räx +4r1b +r2b1ab +r3bac +rba4del +rb2al +r2bang +r2bant +rba3re +rb1art +r2barz +rb1auf +rbb2 +rb1ech +rbe3erf +rbei5d2 +rbe3inf +rb3einh +rbe3int +r4belä +rbel2o +r3ben. +rbe3r2e +rber6gin +rbe3rum +r2bim +r2binf +rbit2a +rbi3tu +rb4la2d +r2blan +r8blasser +r4b3last +r3blat +r3blau +r2b3le. +r3blen +rb3ler +r2bleu +rb2lin +rb2lö +rb2ob +rb3ras +rb3rea +r8b7rechts +rb4sam +rb2sei +rb2ser +rb2s1o +rb4stä +rb2su +rb2u +rbü4b +rby4t +4rc +r1ce +rce4n +r1che. +r1chen +r1ch2i +rch3l +r3ch4lo +rch3m +rch3r +rch1s4 +rch3sp +rch3t2a +rchter6r +rch1w +r1ci +r2ck +r1cl +r1ç +4r1d +rd2ac +r2daf +r2d1ak +r2d1a2l +rd2amm +rd1an +rdani1 +rd1ara +rd1ark +r2darz +rdär2 +r3de. +r2dei +rd2ei. +r4deis +r2d1elb +r2delf +rdem6 +rden3d +r4dengl +rde4nu +rde3ob +rde3r4er +rderin6s +r4d3ernt +r3des +rde3sp +r4d1ex +r2d1inn +rd1iri +rd1ita +r2dof +r3don +rd1os +rd3oss +rdo4st +r2dö +rd3rat +r2drau +rd4ri +rd5ris +rd4rö +r3d4rü +rd2sän +rd3s2k +rd3s2z +rdt4 +rd3th +rdt2s +r2d1uk +1re +3re. +rea2d +rea6l5erw +4re2am +re3at. +re3ats +2reä +re2b1a +re2b1l +reb1r +reb3ra +reb3so +rech3ar +4rechs +2reck. +2recki +3red. +re3da +4redd +2redi +re2dik +3redn +3redu +re1e +3refe +4reff +r2eff. +3refl +3refo +3reg +rege4l3ä +4r1egg +re3gi +2reh +re2hac +re2har +rehen1 +re4hene +re4h3ent +re2hi +reh1l4 +re2h1o +re3hol +re2hü +r2ei. +r2eib +rei4bel +rei4ble +2reid +r2eie +4reier. +rei4fei +4reifel +2reig +3reigä +3reigeh +r4eigel +6reigens +3reigi +4reign +3reigru +rei3l2a +rei3l2i +2r1eilt +3reim +reim2p +r1ein +rein2a +rei5nac +rei3nal +2reinb +rein4du +rei3n4e3c +reinen5 +2reinf +re4info +4reinn +4r3einr +rein8s7tre +rein4sz +rein6teg +re1in2v +4reisar +4reisb +reises4 +2reisf +2reish +2reisr +reister6 +2reisw +4reiti +reit3s2 +3rek +4re2ke +4rekk +r2el. +re3lat +2relb +rel2e +relea4 +re5lei +re2lek +4relem +r2elev +2relf +2relit +2relix +r2ell +rel4lar +rel4lei +re3lo +r2els +2relt +relu2 +r4em. +4remb +rem2da +re2m1ei +r2emi +re3mig +2remis +4remit +4rempf +rems1c +rem4str +2rem2u +r4en. +r2ena +2rena. +re4nac +re3nal +re4n3an +2r1endg +3rendi +ren3dr +ren2eu +5renf +4rengag +2rengp +3renh +re2ni +3renl +3renm +ren4nar +ren6nene +renns4 +renrü2 +ren6sein +ren6serg +rens2p +2rentd +2rentf +3rentfo +2r1entg +r3enthä +2r1entl +2r1ents +2rentw +2rentz +r2enz +ren6z5er6f +renzer6l +ren6z5er6s +renzer6w +ren4z3in +ren2zw +re2ob +re1on +re3or +3repe +4re2pen +2repi +re2pis +2repoc +2r1e2pos +4repp +3repu +3r4er. +rera2 +2r1erb +rer2bi +3r2erbr +2r1erd +rere2 +4r3ereig +r1e4rek +re2r1ep +r2erer +2r1erf +4rerfah +r4erfe +3r2erfr +rer2fü +r1erg +4r3ergeb +5rergebü +r4ergen +3r4erges +2rergo +rer2gr +r4ergru +rer2hö +r1erk +rer4kan +rer2ke +4r3erken +3r2erki +3r2erko +r1erl +2r3er2la +5r4erlag +r3erleb +r2erli +2rerlö +2r1erm +rer2n +2r1ernä +r1erne +2r1erni +4r3erns +4r1ernt +re1ro +re2rob +re4rosi +2r1er2ö +r1erre +rer4reg +rer4rei +r1erri +5r2ers. +2r1ersa +rer3sc +r6erschi +r2erse +2rersp +rer2st +r6erstad +r1ert4 +r2erte +4rerträ +r1erw +2rerwa +rer4wac +rer4wec +r4erwes +2r1erz +rer2zä +3r2erzy +3r4es. +re2sa +re4sam +re3sar +re4schw +3rese +re4se2h +3resol +3reson +res2po +2ress +4resse +res6s5erw +4ressu +re1sta +res4tas +res4tex +2res2tu +3resu +re2t1ak +re2tau +re2thy +re4trol +re2u +reu4eri +reu3g2 +2reul +re3uni +2r1eur +4reuu +2reü +4r3eva +2r1evid +rewa4r +re2wi +2rewo +2r1e2x1 +2rezi +1ré +4r1f +r3fam +r2fent +r3f2es +rff2 +rf3fe +rfi4le. +r4fland +r3f4lä +rf3lic +rf4lö +r3flü +r2fo2b +rfolg4s +r3fot +r4frauc +rf4ru +rf4rü +rf4sam +rf2s1ä +rf2su +rf2ta +rft4r +rf2u +rfzu3 +4r1g +r2g1a2d +r2g1ah +r2g1ak +rga4ner +r2g1ap +r2garb +rg3art. +r2g1ask +rgas4ta +rga3su +rgd2 +rge4an +rge2bl +r2g1e2c +r3g2el +rge4l3er +rgen6sem +rgen4z3w +r4ge4tap +r2geto +r7gie +rgi4sel +r2glan +r2gleu +r2glig +rg2log +rg2lu +r2g3na +r2gne +r2g3ni +r2g3no +r2g3oa +r2go4b +r3gog +rg3op +r2g1or +rgö2 +r2g1öd +r2g3ral +rg4rau +r2greg +r2g3res +r2gret +rg3rin +r3grun +rg3rüs +rg3sä +rg3se +rgs2ei +rg4sel +rg3s4i +rg3sp +rgs2pe +rgs2po +rgs2ti +rgs4tr +rgs2tu +rg3su +r1h4 +2rh. +2rha +r2ha. +r4haltb +r3han +2rhä +r2he. +r5hea +2rheb +2rhef +2rheit +2rher +2rhi +2rhof +rho2i3 +2rhol +2rhot +2rhöl +2rhs +rhu2s +2rhü +1ri +ria3ne +ri2ano +ria1s +ri2ast +ri3at +ri4atr +rib2bl +ri1ce +ri1cha +richt8spo +3richtu +ri2con +ri2dau +ri3de. +4ridee +ri2de2l +ri4ds +r2ie +rief1a +4riefm +rie2f3r +ri2e1i +riein1 +ri1el +rie3l2a +ri3els +ri4enä +riene2 +ri3eni +rien3s +rie4nu +ri1er. +rie3re +riere4n +ri3ers. +rie3sa +ri1eu +ri2f1a +ri2fä +ri2fei +ri2fer +rif6f5end +rif4fer +ri2f1o +ri2fr +rif3s +rif4ter +3rig +4riga +4r3i2gel +ri4gene +5rigj +rig1l +4rigr +4rij +ri2kar +ri2kä +ri2kin +ri2kn +ri4kone +ri2kor +2rima +ri2mag +ri2mau +ri2me. +2rimm +2rimp +rim2s +rim4sc +rim4st +rin2c +r1ind +rin4dex +rin6dize +2rindu +ri3n2e +rine1i +2r1inf +rin2fo +3r2infr +rin2ga +ring3le +rin2gr +2r1inh +2rinit +4rinj +4rink +rin2kl +rin2ko +rin2kr +2rinl +6r5innenm +4r3inner +2r1innr +r1innu +2r1inq +2r1ins +3r2ins. +rin4sek +rin2so +r4inspi +3r2insy +2rint +4rinte +rin4t5re +2r1inv +ri2ob +4r1ir +r2is +ris2a +ri3san +ri4sch3o +ri4schw +3risik +ri3s2ko +rismu2 +r3iso +2risol +ri4s3p +r3isr +3riss +ri4s3t +ris6t5ers +ris4t3r +r2it +rit2a +r3i2tal +rit3ant +2ri3t4r +rits2 +rit2t3a +3ritter +rit4to +rit2t1r +5ritu +rix1 +1rí +2r1j +4r1k +rka2b3l +r2k1ak +rk1all +rk2am +rk1are +rk1asp +rkauf4s +r2k1äh +r2kef +r3kel +r4kelem +rke2n1 +rken3s4t +rk5ersta +r2k1erw +r3ket +r2k1im +rk4las +rk4lau +rk4lim +r2klis +rk2lo +rk2lu +rk4n +rk5nu +r2kob +r3kol +r3kon +rk1o4ri +r2kou +rk2ö +rk3räu +r3kri +rk3rin +r2k3rom +r2krou +rk2sei +rk2sel +rk2ser +rk3shi +rk2so +rk2sp +rkstati6 +rk4stec +rk4stoc +rk2ta +rk2tel +rk4t3eng +rk4tent +rk4t3erf +rk4terg +rk4t3erl +rkt3ers +rk6tersc +rk4t3erw +rk4t3erz +rk4teta +rk2tin +rk4t1o2 +rkto4b +rk2t3r +rk4tri +rk2tum +rk2um +rku2n +rku2sa +r2küb +2r1l +rl2ab +r3lag +r5land +rlan4d3i +r2l1ar +r2l1a2sc +r2l3aug +rle2a +r3lec +r3lep +r3lex +rlg4 +r3l2i +rli4ne. +rli2s +r3l2o +rlou1 +rl2ö +rlös3s +rls2a +rl2spr +rl3ste +rl2s5to +rl3t +r3l2u +r3ly +rlz2 +4r1m +r2mab +r2m1ad +rma2la +rm1ald +rm1ami +r2m1ank +r4mantr +rm1anz +r2m3aph +r2marc +r2marz +rma4s3pe +rmat2o +rm2är +rm3d2 +rm1ef +r4m3einh +rme4na +rm2ene +r2ment +r2meo +r2m1erh +r2m1erl +r2m1erp +rm2es +rme1st +rmes4z +rmeta2 +r2mide +rmi6nanz +rminen4 +rmi6neng +rmon3s4 +rm1o2ri +rmo1s +rm3p2 +rm3sa +rm3s2k +rm3t2 +rmu2n +r4muna +r2muni +4rn +rna2b +r3nad +rn4ade +r3nage +r2n1all +rna4n +rn4and +rn3ani +r2nanz +rna2r +rn3are +r4n3ari +r4n1ast +r4n3att +r2nau +rn3aug +rnd4 +rn3de +rn3dr +r4nef +rn2eid +r4neif +r4neis +rn1ema +rne2n +rn1ene +rn2eng +r2n1ep +r4n1erg +rn4erhi +r4n1erl +r4n1ert +r4n1erw +r4nerz +r5nes +rn2e2t +rne4tem +rne4to +rn2eu +rne3uf +r4nex +rn3f +rn3g2 +r2nid +r2nin +r3nit +rnk2 +rnn2 +r3nod +rn2oh +rn3oly +r2n1op +r2n1or +rn1ö +rnö2d +rn3s2a +rn3s2ä +rn3s4p +rns2u +rn3s2z +rn3t2a +rn3t2e +rn1ur +r1nü +r1ny +rnz2 +2robj +rob2l +1robo +ro2bo2r +ro2bre +2robs +ro1c +roch2a +3rock. +r2o3de +ro3e4 +2roff +ro3fl +4rog. +rog2a +3rogg +roh1l +4rohn +ro2hö +3rohr +3roi +ro3in +ro1ir +rok2l +ro3le +ro2liv +rol4lan +rolle4 +rol6lerg +rolls2 +rol3s +2roly +4rom. +ro2mad +ro2mal +3roman. +2romb +romen3e +ro2m1er2 +2romn +rom3s +4romt +r2on +ro3n4ab +ro2nan +3rond +4ronk +3ronn +rons2 +ron4tan +ron6tend +ron4t3r +ron2t1u +ro1ny +ro1o2f +ro1pe +2ropf +1ropl +2ropt +r1or +ro2r3al +ro2rat +2rorc +ro2rel +ro2ro +ror3th +rort2s +ror2ü +ro3sh +ro3s2i +ro5s2k +ros4sal +ros4san +ros2s1c +ros4st +ro1sta +ros6t1r +ro2sum +4r3osz +4roß +ro2ßi +ro2tan +ro4tas +ro4t3au +ro2tä +ro3te +ro2tei +ro2t3ho +ro2tru +rot3s +rots2o +rot2ta +ro3tu +3roul +ro3unt +5rout +4roy +rö2b3l +rö2du +2rö2f +3röh +2r1ök +1röl +2röl. +rö3le +röl2l +r1ölp +3römi +r1ör +r2ös. +rös1c +r2öse +1rösl +4röß +3rötu +4r1p2 +r3pa +r3pe +rper3in +rpf4 +r2pli +rp4lu +rpo2st +rpro1 +rp3se +rps3t +r4pt +r3pu +2r1q +2r1r +rr2ab +rrat2s +rr1auf +rr1äm +rrb2 +rr1c +r5rega +r5regi +rr2ei +rre2le +rre2pa +rr2er +rrer4s +r3res +rre2ve +rr2hen +rr2hos +rr2i +rri3k2 +rrm2 +rrn3au +rr2o +rr3obs +rro3m +rro2re +rrr2 +rr2st +rr3str +rr3stu +rr2th +r3r2u +r3r2ü +rrz2 +4r1s +r3sabo +r2s1a2d +rs2al +r4samp +r4s1amt +rs2an +r4sanf +r4s3ang +rs3anm +r4sanp +rs3ant +rs3anz +rs3ar +rs4ark +r4sarm +r4sch3e4b +r6scherl +r3schu +r2s1ebe +rse2e +r2s1ef +r2sein +rse2n +rs2end +rse4ne +r2sepi +rs1ere +r2serh +rs1ers +r2serz +rse2t +rs1eta +rs2ext +r3s2hav +r3shir +r3sho +rs2hor +r4shu +rs2il +rs2ka +rs2kel +rs2ki +rs2kl +r4skor +r3s4kri +r4sky +rs4mog +r3s4no +r3so +r4sob +r4s1op +r4sord +r4sorie +r4s3ort. +rs2p +r4spara +r3spe +r4s3ph +rs4por +r4sput +rss2 +rst3abl +rst3ala +r4stale +r4stans +r4stant +r2stas +r7stati +r7statu +r3stä +rst5eing +r6st5eint +rs4temp +rster2 +rs4t4erb +rst3erl +r3s4tern +rst3erw +rs2tev +rs2t3h +rs2ti +r3stie +r2stin +rst3ing +r3stink +r2stip +r2stit +r3sto +rs4tol +rs4tor +r4stot +rs4tr +r3stra +rst3ran +r6strang +rs2tu +rs4tuc +r3s4tü +rsuch4s +r3suf +r3sy +r1ß +4r1t +r2tabo +rt1abs +rta2ck +r2t1ad +r2t3ae +r3taf +rt3akr +r4t3albe +rta3l2e +r2t1all +rt1am +rt2ame +r3t2anb +r2t1ang +rt1ann +rt1ant +r2t1ar +rt3att +r3taufe +rt3äh +rt1änd +rt1ärm +rte1e2 +r3teh +rt1ein +rt4eind +r4t3einh +rtei1s4 +r2telf +rtels4t +r2temo +rte2n1 +rte4na +rten3s4 +r4t3ents +rten3z +rteo2 +rt3erei +r6tereig +r4terfa +r4ter4fo +rt1erh +rt1erk +r4t3erla +rter8löse +rter6mit +r4t3ernä +r2terö +rter4re +rt1ers +rt4ersp +rt1erz +rte3s2k +r2texa +rt3he +r2t3hi +rt3hol +rt2hum +r3tic +r2tid +rtik2 +r2t1ima +r4t3inf +rt2is +r2t1o4b +r5top. +rto1pf +rt1or +r4torg +r4trak +rt3rams +rt3rand +rt3rati +rt3rec +r3tre1s +r4t3ris +rt3rol +rt3roma +r3trop +r2trou +rtrü2c +r4ts +rt4seh +rts2el +rt3sex +rts3ing +rt2s1o +rt2spa +rt2spr +rt4s3tan +rts4tie +rt3t4 +rt1umb +rt2u3na +r2t1up +r2t1urt +rtu4t +r2t3ute +r3tü +rt3z2 +1ru +ru1a +ru4ale +ru3a2r3 +rube4 +ruben3 +rubens4 +rub2i +ru6ckerl +ru2cku +rude2a +ru2dr +3ruf +ru2fa +ruff4 +ruf2s +rufs1p +ruf4ter +ru2g3r +3ruhm +2r1uhr +3ruin +ru1ins +ru1is +2rum +4r3umd +4r3umf +4r3umg +ru2mi +4r3uml +4r3umsa +4r3umw +4rumz +2r1una +2rund +run4d1a +runden5e +run4d3er +runds2 +run2e +runei2 +4r1unf +run2ga +2rungl +4r1u2ni +r3unio +ru4nis. +run2kr +4r1unl +2r1unm +4runn +4runr +r1unse +4r3unt +4runw +2rupd +ru3pr +4r3u2r +rur1e +5ru3ro +ru2si +rus2p +rus2s1p +rus4st +ru2st +ru2tab +rute4 +ru4tei +ru4t1el +rut3h +ru4t1o4 +ru2t3r +rut6scha +4ruz +ru2z1w +1rü +2rüb +4rübu +rü1ch +rü4ckel +rücks4 +rü2hel +rüher2 +rüh1l +4rümm +rün3z +2r1v +rv2el +rve4n1e +rvenen4 +r4ventz +rve3s +r3v2o +2r1w +rwe4gel +r3wei +rwelt4s +r5werk +r5wert +r2wo. +r3woh +r3wort +rwun3s +4r1x +1ry +ry2c +ry3sth +rysti1 +2r1z +rz2ans +r2zant +r2zar +r2zat +r3zähn +rz2än +r5zene +rz1eng +r4z3ents +rze2p +rze2ra +r2z1erd +r2z1erf +r2z1erg +rz1erk +r2z1erl +r2z1erw +r2z1ess +rz1id +rz1int +rzir3 +rz2of +r2z3ot +rz2tan +rz3te +rz2th +rzu4g3l +r2zwä +r3z2wec +r2zwir +1sa +3sa. +3s2aa +2s1ab +sab2ä +4sabd +sa2be +3sabet +s3abi +sa2bit +sa2bl +4sabm +sa2bor +sa2br +4s3abs +4s1acc +5s2ache +sa2cho +sach3t +s2ack +2s1ada +2s1adm +2s1a2dr +3safa +sa4fe +4s3aff +sa1f4r +s2aft +saf4tr +3saga +sag2e +5sagen. +4s3agent +2s1agg +sa2gio +sa2git +sag4n +s1a2gr +s2ahs +3s2ai +sa3i2k1 +sail2 +sai4r +2s1ak +sa2ka +sak2e +3saki +4sakk +4sakt +3s2al. +s2al2a +sa2l3an +sa2lar +sa3lat +3salb +sal3bl +3sald +sa4lerk +3sali +sa2l1id +s1all +sal4le. +3salo +sal2se +s1alt +s2al3t4h +3salz +3sam +4s1a2mat +4s1a2mei +s3ameri +5samm +6s1amma +4s1amn +s1am3p4 +4samph +sam4ta +sam4to +samt3st +s1an +s2an. +2s3a2na +sa4nä +2s3anb +s2an2c +3s2and +san4dan +san4dri +sand3s +sa2ner +3sang. +2s3anh +3sani +3sanken +2s3anl +2sa2no +2s3anp +2s3ans +s4anse +san4sk +san3sp +4santei +4s3antr +4s3anw +2sanz +2s1ap +sa2pe +sa2po +sap3p +3sapr +2s1aq +2s1ar +3s4ar. +3sara +4s3arb +3s2ard +s2are +s3area +sar2ga +sa3rin +s2ark +4sarm. +sa2rom +s3arr +s2ars +4sart +sa4r1u2 +sas2a +2s1asc +2s1a4si +2s1a4sp +sas2tu +4s1asy +sat2a +sa4t3ant +sat1ei +2s3a4tem +s3ath +3sat2i +2s3atl +2satm +sat2o +sa4tol +sa2tom +sa2tr +s3atta +4s3attr +3satz +5satza +sat4zel +sat4z3en +s1au +3sau. +3sauc +3sau2e +2sauf +4s3aufb +saug3le +sau2gr +3saum +sauri1 +2saus +3saus. +4s3ausb +4sausf +4sausg +sau2sp +4sauss +3sauste +4s3ausw +2sauß +s1av +sa2ve +sa2xi +sa2y +1sä +3s2äb +3s2äc +3s2äg +s1äh +4s3ähn +3säl +4s1ält +2s1äm +4s3änd +4s3äp +2säq +2s1är +3s2ärg +3s2ät +3säul +4säuß +4s3b4 +sba4ne +sbau6men +sbe3r2e +1sc +2sc. +2scab +2scac +2scal +2scam +2scar +2s1ce +4s3cei +sc4h +4sch. +3schaf +3s2chal +sch3ana +4schanc +4schang +4schao +4schara +4sch3ar5m +s2chä +2schäq +4schb +4schc +2schd +sch2e +4schech +6schef. +6schefi +6schefs +s4chei +4sch3ei. +sch6ein. +4schemp +s4cher +sch5erfü +3sches +4schess +s2cheu +4schex +2schf +2schg +2schh +schi4d +schi4e +s4chif +4schiru +3schis +2schk +s4chl +sch4lac +4schle. +6schlein +4schloc +4schlöc +4schmas +4schmed +2schmö +4schmüh +2schmy +2schn. +4schneb +4schnut +4schobj +4schorc +2schox +4schör +4schp +2schq +4schrad +4schre. +4schrin +4s3chris +sch3rom +4schron +4schrou +4schs +schs2e +sch3s2k +schs4ti +4sch3t +scht2a +scht2i +scht2o +s4chu +4schunt +2schv +sch4web +4schweg +6schwerk +4schwet +4schwid +3schwu +2schz +2scj +4s3cl +2sco +3s2cop +s2cr +2scs +2scu +4s3d2 +sda3me +sde1s2 +sdien4e +sdi1st +sd4r +1se +se3ar +se3at. +seb2 +5sebä +2s1e2ben +2s1echo +sech4st +2s1echt +4s1e2ck +se2dik +3see +see1i4 +se2e3ig +se2el +see3len +se3en. +seen2e +se3er. +see1ra +seer2e +se3e2r1i +se1ers +see3s4 +see3t +4s3eff +sef4l +3s2eg +4s3e2gal +se2gl +seg4r +3seh +seh1a +se2hag +se2hel +seher4e +se4herk +se2h1in +seh3l +se2h3ö +seh3re +seh5r2i +seh1s +seh3t +se2hüb +2sei. +2s1eic +2s1eid. +sei3da +4s3eifer +4s1eig +sei3le +s2eim +s1ein +5s4ein. +2seinb +sein4du +2sei3n2e +seine3i +4seinfl +sein4fo +4seing +2s3einh +2seini +2seink +2seinl +2seinn +4seinr +s4eins. +4seinsc +4seinsp +sein8stit +sein6str +4seintr +2seinw +2s3einz +2s1eis +3s2eit +seit2s +3sek +4s1e2kel +4sekz +s2el. +se2l1a +se3lad +3s2elb +sel1ec +se2lef +2s3e2leg +4selem +se2ler +sel3ers +2self. +s3e2lit +2s1elix +s2ell +se2lob +s2els +sel3sz +selz2 +sem2a +sem2e +2s1emis +4s3emp +s4en. +3sena +se4nad +se3nal +se4nas +sen3au +s2enb +2s1endl +sen3d4r +senen1 +se4nene +4senerg +se4ners +se4ness +s2enf +3s4eni +se2n1im +3s2enk +se2no +se4nott +se4noz +3sens +s2ensa +sen4s3e4h +4sensem +s4ensi +s2enso +senst2 +sen8s7turm +sent2a +sen3tä +2sentd +4sentf +4s1entg +4sentla +4sentn +sen3tr +4s1ents +2sentw +4sentwu +4sentwü +2sentz +se4n3u +sen4zer +sen3zw +seo2r +se2pen +3seq +s4er. +se2r3a2d +ser3al +ser3ass +ser3äus +serb2 +s3erbe. +se2re2b +6sereign +se4r3eim +5s4eren +se4r3enk +s4erfe +s2erfr +s1erfü +4serfül +ser3g2 +s2ergr +s1erh +2serhö +3seri +5serie +ser3k4 +4s3ermit +s2ern. +s3erneu +4s3ernt +2s1e2ros +s1erot +s1erö +4seröf +3s2ers. +2sersa +4serseh +ser6sehn +4ser4set +se3ru +se4ruh +ser2um +se4rup +5s4er3v +s1erz +5s4es. +se3s4a +se2sel +se3sk +2s1essa +se1sta +se3stec +se3stei +se5stemp +sest3ri +set2a +2s3e4tap +se2tat +s1e2th +4s1e2tik +se3tun +se2ty +3setz +3seuc +4s1eul +seum4sc +se1u2n +s1ex +5sex. +2sexa +se2x3en +s2exi +s2exo +4sexp +sex3t4r +4sexz +1sé +4s3f4 +sfal6l5er +4s3g4 +sgang4 +sga3su +sge3s4a +2s1h +4sh. +sh2a +3s2ha. +shal4li +shalt2 +shalt4s +4shan +s2has. +s3hä +sh2e +3shi. +3shid +s2hip +shi4r +sh3n +4s3hoc +4s3hof +4shom +3s2hop +sho4re +3s4how +4s3hö +sh4r2 +4shs +s3hu +1si +si2ad +2siat +5s4i1c +si2cha +sid2 +s2ide. +s2i3do +2sidy +3s4ie +sie2bu +sieh1e +sie4hes +si3e2n3 +si1err +si1f4 +3s4ig +si2g1a2 +si2gei +sig4n +si2g3r +sig4st +si2k1ab +si2kak +si2kar +si2k1ä +si2k1el +siken2 +sik3erl +si2ket +si2k3i +sikin1 +si2k3n +siko3 +si2k3r +sik3s +sik3t4 +si2ku +sil2br +sil2e +3sili +s1ill +3silo +2s1imm +sim4st +3simu +si3n4a +2s1ind +2s1inf +s3infor +sing1a +sin3g4le +sin2g3r +sings2 +sing3sa +sing3so +2s1inh +s1in1i +sini1e +sinner4 +2s1inno +2s1inq +2s1ins +s2ins. +2s1int +2s1inv +3sio +sion4 +sirn4 +2sirr +3siru +si2sa +si4sam +3s2isc +si4schu +si2s1e2 +si2sis +s1i2so +si2s3p +sis3s4 +3s4ist +si2su +3s2it +si2tal +si2tau +si2tra +sit2u +si2va +sive3 +si4v3erf +siv1o4 +si2vor +siz2 +1sí +2s3j +2s1k2 +4sk. +sk4a +4s3kab +s3kad +4skalk +4s3kam +4s3kana +4skanä +3skanda +4s3kap +4s3kar +4s3kas +ska4te. +4skateg +ska4tes +ska4to +4skä +4skb +ske2li +4sken +3skep +4sker +s3kh +3s2ki. +3s2kif +3s2kik +s3kin +4skir +ski1s +s2kis. +3skiz +sk4l +4s3klas +3s2klav +4s3klu +4sk4n +4skoh +4skol +4skom +4s3kon +3skop. +sko2pr +4skos +4skow +4skö +4s3kra +s3kre +4s3kro +4sk3s +4sk3t2 +skto2 +3skulp +4skun +sku2s1 +4skü +4skv +2s1l2 +sl4a +s3lab +3slal +sla2ve +s2law +s3lä +sl3b +4s3le +sler3s +s3li +3s4lip +s3lo. +slo3be +s3loc +s3loe +s3lof +3s2low +s3ly +2s3m2 +sma3b4 +sma3sc +sme3na +smi2t +2s3n2 +snab4 +sni4a +sni3er. +sni3ers +4s5not +1so +3so. +2s3oas +2s1o2b +3s2o3ba +4sobj +4s3obo +so1c +so3et +s1o2fe +3soft +3sog +sog4l +s1o2he +3sohl +sohle2 +2s3ohng +2s1ohr +3soi +2s3ok +3sol. +so3la +so4lau +3sold +3sole +so2l1ei +so3li +sol2la +sol4ler +so3l2o +4s3o2ly +som2e +3son +son2a +sone4 +son3sä +son4s1o +so3o +2sope +2s1opf +3sopr +sop3s +s1orc +2s3ord +sore2 +so2rei +so2rel +4s1orga +so1rh +2s1o2rie +so2ro +3sorp +3s2orti +so4ru +3sos +s2os. +4so4sk +4sosm +4s1ost +4s1osz +3so3ß +soth1o +3sott +soun2 +sound1 +so3unds +so3unt +s1out +3sov +3sow +2s1ox +3soz +s3o4ze +1sö +sö2c +s1ö2d +2sö2f +2s1ök +2s1öl +2s1ös +1sp2 +2sp. +4spaa +s2pace +2spack +2spag +2spak +2spala +2spalä +3spalt +spa2m +s2pan. +3spannu +3spant +2spanz +2spap +2s3para +s4parka +2sparo +5s6parten +4spartn +4sparty +3spaß +3spat. +2spati +4spatr +2spau +3s2paz +s2pä +2späd +3späh +2spär +2späs +2s3pe. +2speg +3speic +4spein +4spensi +spe3p4 +s2pera +3s2perg +s1peri +4sperle +2spero +s2perr +2spers +2sperü +4spet +3s4pez +4s3pf4 +2spha +s2phä +3sphär +s3phe +s4phin +3s2pi4e +4spier +spier4r +s3pi2k +4s3pil +3spio +2spip +4s3pis +2sp4l +4spla +4splä +4sple +sp5le. +3s2pli +4s3plu +2s3pn +2spod +4spoe +2spog +s2poi +4s3pok +4spol +s2pons +2spop +s2pore +s2porn +spor6tag +4s3pos +4spote +4spr. +3s2prac +2sprak +s2pran +2sprax +3spräc +2spräm +s2prän +4spräs +3s4prec +4spred +4spreis +5s2pren +2s3pres +s2pric +3spring +4sprinz +s2prit +2sprob +4sprog +4sproj +4sprop +3spross +2sproz +3sprö +3s2pru +3sprüc +2sprüf +3sprün +4s3ps +2s4pt +2spub +2spud +3spuk +3s2pule +2spun +4spunk +2spup +3s4pur +spu4rer +2sput +4spy +2s1q +4s3r4 +srat2s +sre3cha +sreli1 +sre4th +srö2s +srücker6 +6s1s +ssa3bl +ssa3bo +s5sack +ss4agi +s2s1aj +ss3alba +s2sall +s4samt +s2sanf +s4sang +ss2ann +s4sano +s4sans +ss2ant +s4sanz +ss2ara +s3sars +ssa1s +ss3att +ssau3e +ssau4r +s3s2ä +s4sce +ssch2 +s3schw +s4sco +s2scr +s4seben +ss1ec +sse1e +sseh2a +ss4eind +sse3int +s4seis +s3sel +sse2lö +s3sen. +ssen6sem +ss1epe +sse6ratt +ss2erf +ss3erfü +ss4ergr +sser4hö +sser6mit +sser4öf +ss3erse +ss4eru +sser6wei +sses4sa +s4s3estr +sse3ta +ss3i2ko +s2sill +s2simp +ssing3s +s2s1isr +s3skala +ss3l +ss1off +ssoi4 +s3sol +s4sop +ss2orc +ss2phi +s3spi +ss2pot +s3sprä +s3spri +s2spro +ssquet4 +ss3s4 +sssau4 +sst2a +s4stag +ss3tak +s3stä +sst2e +s3stel +s3s2tep +s3s4tern +ss4teu +ss2ti +s3sto +ss4tör +s3stran +s3s4tras +s3s4trat +s3strä +s3strec +s3strom +s3strö +ss2tur +s3stü +s2sumg +s2sumr +ss1ums +ss2ur +s3sy +s1t +4st. +s2ta +2sta. +3staa +3stab. +2stabb +4stabel +4stabit +2stabl +st2ac +3s4tad +4stadm +3staff +2stag +3stagl +3s4tagr +3s4tah +2stak +3staks +2stala +sta3lak +2s3talb +s4talg +s3ta3l2i +2stalk +st1alp +st1alr +st1a2mi +1stamm +1stan +2stanb +s4tand +2stanf +s4tanh +2stanl +s4tanm +4st1ann +st3ansp +2stanw +stapo1 +4stapol +4s3tapos4 +4s3tapot +st1app +s4tar. +s4tarb +sta6rens +4stari +s4tark +s4tarm +s4t2ars +s4tart +s4tase +s4tasi +stast4 +s3tat. +2statb +3stati +7statth +s4tau. +2stauf +2staug +3s4taur +4stausb +4stausg +4stausr +4stauss +s4taut +s4t1a2ve +4stax +1s2tä +3stäb +3städ +4stäg +4stäp +5s4tär +3stätt +2s3täus +2stb +2st3c +2std +4ste. +4steam +4stechn +s2te2d +st1edi +2stee +3s2teg +ste2g3r +1steh +s2tei +2steic +st1eid +3steig +stei4gr +2steil +6steinga +s4teins +stein6sp +s2tel +2stel. +s3tele +s3telf +st2ell +stel6l5än +2steln +2stels +2stem +ste4mar +ste6ment +3stemm +2sten +s5ten. +ste4na +s4t3ends +st2ens4 +s4tentf +s4tents +st1e2po +2ster +4s5ter. +ste2r3a +s6terben +3sterbo +3s4tereo +st3erfü +6sterinf +6sterinh +4sterm +3s4ternb +4ste2s1 +ste3sc +stes4se +s4testn +stes5tr +2s3tet +ste4tag +3s4teti +3s4tett +3s2teu +1steue +4steuf +st1eun +st1ev +s2tew +4stex +s2texa +2stf +2stg +2sth +st4hen +s2t3hi +st3ho +s2thu +2stia +2stib +1stich +2stie. +4stief. +4stiefl +s2tieg +s2tiel +2stien +1s2tif +2stig +3s4tigm +2s3tik +s2t2il +1s2tim +4stimma +2stimp +st1inb +s4tinf +s3tinn +s2tins +2s2tint +2stio +2stip. +s4tipe +4stipp. +s2ti2r +st1ira +st1iri +4stis +s4tisl +st1ita +2stite +1stitu +2stiv +2stj +2stk +4stl +2stm +2stn +s2to +2sto. +sto2bl +4stocht +2stod +4stod. +1stof +s4toff +2stok +4s5tole +sto3mi +4ston +s4to4ne +4stoo +2stopo +4stor. +s4torb +2store +2s4torg +2stori +2storp +2stors +2stort +s4tory +sto3s2t +1stoß +4stote +2stotr +4stou +2stow +2stoz +1s2tö +4stöch +2s3töl +2stön +3stör +2stöt +2stp +2stq +s2tr +2strac +4s3trad +st4rade +stra4fa +4s5trag +3strah +4strahi +4strai +4strak +2stral +s5trank +4strans +1strap +1stras +3straß +4straum +4sträc +4s5träg +4sträne +2stre. +s4trea +4stref +4streib +3st6reif +2strep +2stret +4streuh +2strib +strie3s4 +2s4trig +1s4trik +2s5tris +2striu +s3troc +s3trog +3s4troh +3strom. +s4trome +4stropf +2stros +st4ross +1strö +2ströp +1stru +2strua +2strub +s4trud +2strug +3struk +2strun +4strup +1strü +4s4t3s2 +sts4t +2st3t4 +st2u +1stub +4stuch +3s4tud +2stue +3stuf +2stug +st3uga +3stuh +s2t3uk +2stumo +2stum2s +stum4sc +2stumt +2stun. +st3una +1stund +2stune +2stung +s2t3uni +4stunn +2stuns +2stunt +2stuö +stu3ra +stu5re +2st3url +4sturn +2st3urt +3s2turz +2stus +1s2tut +1stüc +4stüch +3s4tück +3stüh +4stür. +4stüre +3stürz +1stüt +2stütc +2stv +2stw +stwor2 +2sty +4sty. +1s2tyl +4styp +4stys +2st3z2 +1su +su1an +3su2b3 +su4ba2 +4subi +su4br +3su1c +su2cha +su2cho +suchs3p +3sud +su2eb +2s1u2f +su3fi +2s1uh +3sui +su1is +su1it. +su2k +su3l2i +sul3t +3sulta +su2m1a +s2ume +su2mei +su2mel +sument4 +su6ments +2sumf +s3umfa +s3umfe +su2min +3summ +sum1o2 +su2mor +3s2ump +s3umsa +2sumse +s2umsp +2s3umst +2s3umwa +su2n +3sun. +2s1una +sunder4 +sun6d5erh +sunds4 +su4ne +4s1unf +6sungena +s1ungl +sung4s +4s1uni +2s1unm +2s1uns +s4uns. +s4unst +2sunt +2sunw +s4unwa +3s2up +sup3p4 +su2ra +sure4 +su2rer +3surf +2s1urk +s1url +su2r1o +s1urt +su2s1 +su3s2a +s3u2t +su4te +su3tr +3suv +1sü +2sü4b +3süc +sü2d1 +süden4 +3sün +3s2üs +3süß +4s3v2 +svoran4 +2s1w +4s3we +swe6gers +sweh2 +4swie +4swil +4swis +4swit +1s4y +2sy2l1 +sym3 +sy2n3 +sy4nä +3sy4s3 +2s1z2 +4s3za +4szä +4s3zei +4szel +3s2zena +3s2ze3n2e +4s3zent +4s3zer +s2zes +4szet +4szeu +3s2zew +4s3zie +4s3zo +4s3zu +4s3zü +4s3zw +2ß3a4 +2ß1ä +2ß1b4 +2ß1c +2ß1d2 +1ße +2ß1e2b +2ß1ec +2ß1ef +2ß1e2g +2ß1ei +ße2la +ße2le +2ßelek +2ß1emp +ße4n3a2 +4ßenerg +ße2ni +ße2no +ßens4t +2ß1entl +2ßentz +2ß1e2p +ßer3b +ßer2ei +ß2ers. +2ßer4se +ßer3t +ß1erw +2ß1es2s +2ß1est3r +2ß1ex +2ß1f4 +2ß3g2 +ßge2bl +2ß1h +1ßi +ßi2g1a2 +ßig4s +2ß3i2k +2ß1il +2ß1im +2ß1in +2ß1j +2ß3k4 +2ß1l +ßler3 +2ß1m +2ß1n2 +2ß3o2 +ßos2 +2ß1ö2 +2ß1p2 +ß1q +2ß3r2 +ßrö2 +2ß3s4 +ßsau4 +ßsch2 +2ß1t +ßt1in +ß3tü +2ß1um +ß1unf +2ßunt +2ß1ü4 +2ß1v +2ß1w +2ß1z2 +1ta +3ta. +4taa +5taan +4tab. +ta2b3an +2t1abb +2tabd +3tabel +2taben +4tabf +2tabg +4tabh +2t1a2bit +2tabk +2tabla +4tabm +2t3abn +2ta4br +4tabs +t1abst +2t3abt +4tabw +4tabz +2t1ac +4tachs +3tacu +t1ada +2tadd +ta2der +tadi3 +t1adm +ta2dol +t1a2dr +ta3d2s +tad6t3 +ta2er +3taf. +3tafe +4tafet +4taff +t1afg +t1afr +3tag +ta2ga +ta2g1e2i +tagen1 +t3agent +4t1agg +4ta3gl +4t1a2go +tag4san +tags3c +tag4st +tah2 +tahls4t +ta3i2k +tai2l1 +ta1ins +tai4r +ta1ir. +ta1i2s +2t1a2ka +ta3kes +2t1akk +ta2kro +tak4t1o2 +t2aktu +2takz +3t2al. +ta2la +ta3lag +tal1an +ta3lat +tal3au +4talb. +4talbk +tal3d4 +3tale +ta4l3end +tal3eng +ta4lens +tal6ents +ta4lerg +ta2let +tal2ga +tali6ene +tal4l3ac +tall3ei +tal2l1ö2 +tall3s2 +2t1alm. +3talo +ta2lop +ta2l1o2r +tal2se +tals3en +t1alta +tal3th +talt4r +ta2lu +2tam +3tam. +3tame +5t2amen +t1a2mer +tamm1a +tam4m3er +t1ampl +3tams +t1amt +2t1a2na +tan3ab +4tanal +ta4nat +2t1a4nä +2tanb +3tanc +tan3da +tand4ar +tan2dr +tand4st +ta4nerf +4tanf +4tangeb +tan4gra +2tanh +t2anho +t4ani +3tanj +tan2kl +4t3anl +t1anm +4t1anna +3t2anne +t1ano +2tanp +t1ans +t2ans. +4tansi +tan4tan +t4ante. +4tantei +2tantr +2tanwa +2tanwä +t2anz. +t1anza +4tanzei +2t1anzu +4tanzü +tan2z1w +tao2 +ta3or +t4ape +ta2pes +2tapf +ta2pl +ta4poka +3tapol +t2appe +ta2ra +2tarab +3tarabb +ta3rak +2taram +tar3ap +t2arau +2tarb +3tarba +3tarbek +3tarber +3tarbi +3tar3bl +2tarc +3tarchr +t2ard +t2arei +ta2rel +ta2r1er +tar3g +ta1r2h +3tari +tark4l +t2arko +4tarkt +t2arl +2t1arm +t2armä +ta2rom +2tart +t2ar2ta +tar6ter6e +3t2arth +t1arti +3t4artis +tar4to +tar2tr +ta2ru +2t1arz +3tarzu +3t2as. +ta3sa +3tasc +ta5se +4t1asp +2t3assi +3tast +tas4tem +tas4to +t4at. +ta2ta2b +ta2tan +3tatb +t4ate +tat1ei +t5a2tel +ta2tem +3taten +ta2t1er +t3atl +ta2tom +ta2tr +3tatsa +2tatt +tau2b1a +3taubh +tau2bl +tau2br +tauchs4 +tauch5sp +4taud +2t1auf +3taufe. +4taufg +4taufl +tau3f4li +t3aufo +taufs4 +3taug +4t3auge +t1auk +3taum +2t1ausb +3tausc +tau6scha +tau6schm +tau6schr +tau6schw +2tausd +t2ause +4tausf +4t3ausg +t1ausk +4tausl +2tausr +4t3auss +2t5ausw +4tausz +4tauu +3tav +4tava +ta2van +3tax +4t1axt +3taz +1tä +2tää +4täb +tä1c +4täd +t2äf +3täg +4tägä +4tägy +2täh +4täll +2t1ält +4tä2m +t1ämt +t1ängs +3tänz +4t1äp +2täq +tä4reng +tä2ru +2tärz +tä2s +t2ät +3tätigk +4tätt +2täug +2täuß +2täx +1tŕ +4t3b4 +tbauer4 +tbe3r2e +tblock5e +tblocken8 +tby4t +4t1c +t3cha +t3che +tch2i +tch3l +t3chr +t2ch1u +tch1w +t4ck +t3cl +tcor2 +t3cr +4t5d4 +tdar2m1 +tdun2 +1te +3te. +te2a2 +tea3c +te3ad +te3ag +2teak +te3al +3team +te3an +te3ar +tea4s +3teba +t4ebb +2t1e2ben +t2ech +2teche +3techn +te2chu +2teck +te2cki +tecks4 +2t1ecu +te2dit +te1em +teen1 +te2er. +te1erw +tee3t +3tefa +2teff +2t1egg +2teh +3teha +te2hac +3tehä +3tehi +te2him +3tehö +t1ehr +3tei. +3teic +tei1fl +teik2 +3t2eil +tei2la +tei6lent +teim2 +2tein +t2ein. +t2eine +teinen4 +tei6nens +tein6hab +t3einkü +te2is +t1eis. +t1eisb +te5isch. +t1eiw +tei3z +te2kel +tekt4 +3tel. +3te2la +tel3ab +tel1ac +te3lan +te4lant +tel1au +te2lä +3telb4 +3teld4 +tel1ec +tel3ehr +2telem +tel3eng +te2ler +tele3s +te2leu +4t3elf. +3telg +tel1in +te2lit +3telk +tel6lant +tel3le +tel6lein +tel3li +4tellu +3teln +te2lob +te4lost +te2l1ö +3telp +3tels +tel3s2k +3telt4 +tel3ta +3tem. +3tema +te2map +te2mau +t2emb +te2m1ei +te2m1er +te2mi +tem3i2m +tem3ing +2temm +te2m1o2r +3temper +2tempf +4tempfi +tem3s +te2mu +te4mun +3ten +t6en. +ten1a2 +te4nad +te4n3an +te4nas +te4nat +ten3au +ten3ä +ten3da +4t3endal +tend4an +4tendap +4t5endf +4t1endl +t6endo +4t5endp +ten3d4r +te2n1e2b +te2nef +te2neh +ten3ei +te3n4ei. +tene4m +tenen1 +te4n3end +te4nene +te4neng +te4nens +4t3energ +te4n3ern +te4ness +tenf4 +4t1eng. +teng2a +ten4gag +4t3engla +te2ni +te4nil +ten1im +te4n3in +tenk4 +ten3n2 +te2nol +te3nö +ten3se +4t3ensem +ten6serg +tens2p +tens3th +t1entb +4tentd +ten3te +4t3entl +4t3entn +ten6tric +4t3en4tro +2t1ents +4t5entw +4tentz +te2ny +teo2f +2tep. +2t1e2pi +2teppu +tept2 +3t4er. +t4era +tera2b +ter3a2c +te2rad +te1ral +tera2m +ter4ane +te2r3ap +ter3a2s +4terbos +2t1erbs +2t1erbt +3terc +ter3d +4t3erde. +terd2s +3tere. +te2re2b +te2rec +t3ereig +3tere2m +te4r3emi +3teren +te4r3end +te4rene +te4reng +te4r3ent +3terer +terer3k +terer3l +te4r3erp +te4rers +te4rerw +3teres +te2ret +t4erfr +terg2 +ter3ga +6tergebn +t6ergem +t6erges +t6ergew +ter3gl +6tergrei +t4ergru +t6erhall +t4erhan +t4erhau +t4erhäu +t4erhei +7t2erhi +t2erho +6terhöhu +t2erhu +te3ria +ter3iko +2teril +terin5d +3terinf +3terinh +ter3k +4terklä +t4erlä +t4erli +3term +t2ern. +ter4nar +2t6ernc +ter4obe +2teros +t1e2r1ö +t4erp +t4erra +ter4re. +t4erro +t4ers. +t2erse +terst4 +t4erst. +t6erstad +ter6stat +t4erstä +t4ersti +t4erstr +t4erstu +t4erstü +tert4 +ter3ta +t4eru2 +te4r1uf +t4erv +4t3erwäh +4tery +ter3z2a +2t1erzb +t4erzei +4terzeu +ter5zo +ter3zw +3tes +tes3a2c +tesa2k +tes2c +tes4pen +te2spr +2t1essa +tes3si +tes3tan +tes4tel +tes6terg +tes6terh +tes6terk +t3est3ri +te2su +tet2 +3t2et. +te4tabl +2te2tap +te2tat +4tetl +3teuf +3teum +3te1u2n +4teunu +2t1eup +3teur. +te2va +te2vi +tewa2s +3tewo +t1e1xa +2t1e2xe +te3xel +2t1e2xi +4texp +tex4ta +2t1exz +6t3f6 +4t1g2 +tga4s3er +t3ge +tgenen3 +tger2a +tger2i +tg4r +t1h +4th. +2th2a +3t4ha. +3t2hag +4thak +3thal. +t2hali +3thalp +t2han. +t3hand +t3hap +4t3hau +2thä +4thäl +2thb +t2h2e +1the. +3thea +2t3heb +2t3hef +2t3hei +t4he1in +t4hek +3t4hema +2themd +t4heme +2themm +1then +t4hene +t4heni +3theo +t3herd +t4herm +thero3 +t3herr +2t3herz +4t3hess +2thf +1t2hi +3thi. +thic3k4 +t3hiel +thi3er. +2t3hil +2t3him +t3hin +thi3nu +2t3hir +2thk +2th3l +4th3m2 +thmu2 +2th3n +1t2ho +2t3hob +t3hoc +tho3chr +t3hof +2t3hoh +t4hol. +t4holo +2tholz +tho1s +2t3hot +3thotr +2thou4 +t3hov +4t3hö +2thp +1th2r2 +2ths +2tht2 +2thub +2thuh +4t5hun +2thut +2thü +2thv +t2hy +1ti +ti2ad +ti3ag +tial2l +ti3a2m +ti2are +3tib +2tic +3ticc +ti1ce +t1id +t2id. +4tidee +ti4d3en4d +tie3br +3tief. +4tiefel +3tiefl +tie2fr +tieg4 +2tieh +ti2e1i +ti1el +ti2el. +tiel3a +ti3e4n1 +tien3s +3tiera +tie4rei +tie4reu +ti2ern +tie3s2t +4tieß +ti1eu +3tif. +ti3fe +ti1f4r +3tig +ti2gan +4t3i2gel +ti4gerz +ti2git +tih2 +ti2kam +ti2kar +ti4kau +ti3k2en +tik4ere +ti2kin +ti4klu +ti2kn +tik1r +ti2kra +ti2krä +ti4k3rei +ti4lant +ti2lar +ti2lei +ti2lel +3tilg +2tillu +ti3lo +ti2lö +tilt4 +ti2lu +ti2ma2g +4timm +timm1a +tim4man +t3immat +timmer4 +tim6merg +3timo +2timp +tim2s +3tin. +ti3naf +ti3nak +ti2nam +ti2n3an +4t3ind +ti5n2e +tine1i +2t1inf +tin2g1a +tin4g3l +ting3s +t1inh +3tinis +t1in1it +4tinj +2t1inka +tin2k1l +tin2kn +tin2kr +2t1inku +t2inn +ti2nor +t1ins +3t2ins. +t3insa +t2insä +4t3inse +tin4spa +tin4sum +t1int +ti3nu +tin2um +4t1inv +3tio +ti2osk +tioxi3 +3tip +ti3p4l +ti4que. +3tirad +ti1rh +ti4ron +3tis +ti6schei +tisch3l +tisch3w +ti2sei +tis2el +ti3sk +2t1isl +ti2sp +2t1isr +tiss4 +ti3s2th +tis3ti +ti1s4tr +ti2su +tit2a +ti2tal +3ti3te +ti1th +ti3ti +2ti3tu +tium4s +3tiv +ti2van +ti2vel +ti4vene +tiver2 +ti4verh +ti4verk +ti4verl +ti2v1o +ti4v3r +ti2za +ti2zir +2t1j +4t3k4 +4t3l2 +6tla +tlan2g +tl4e +t2lef +tlei6der +tle2ra +6tli +tlings5 +tlit1 +t5lö +tlung4 +4t3m4 +tma2st +tmen8schl +tmen6t5 +tmo4des +4t3n4 +t5na +tnes2 +tnes4s +1to +3to. +to4as +to5at +t2oba +to3be +2tobj +tob2l +t1obs +3tobt +to1c +t3ochs +3tocht +to6ck5ent +3t4od +tod1er2 +to4d1un +tof4fa +tof6f5ent +tof4f3er +2toffi +toff3s +3tog +2t3ohr +3toi +toi4r +4toiz +3toj +3tok4 +3tol +to3le +4tolp +4tolz +tomar4b +2tomg +to2min +2tomk +3tomo +to2m1u +to4mun +3ton +to2nan +tond2 +to2n2eh +toner6ke +to4n3ig +to3ny +3too +3top. +to2pak +to2pan +to2pat +to4pfe +top1hi +3topo +2to4pt +3tor +t4or. +to4rän +4torc +t1ord +t2ordi +4t3ordn +t4ore +to4rein +to2rel +to2rem +to3ren +tor4fan +t1or3g +4torga +t5orient +tor3int +5tork +to2rop +to2rö +t4ors +4t1ort. +tor3ta +t1orth +4tortn +4tort2s +to4ru +t2orw +tos2e +to3s2h +tos2p +4toss +3tost +4toß +to1ßu +to2tä +3tote +to2tho +3totr +tots2 +5t2ou +touil2 +to3un +3tow +3toz +1tö +3töch +4töck +2t1ö2d +2tö2f +4t1ök +2töl. +3tön +t1öst +3töt +2t3p4 +tpf4 +tpi2n +2t1q +1t2r4 +2tr. +5tra. +3trac +tra3cha +tra3chl +2t3rad. +5trade +tra4dem +t3radie +2tradp +tra4fah +tra4far +3t4rag +3trahi +6trahl +2trahm +5t4rai +3trak +4t3rake +5t4rakt +5tral +tra4leb +tral3l +3t4ran. +4trand +4trang +t3rann +5t4rans +tra2st +6traß +4traub. +4trauc +t4raue +t4rauf +2traup +5träc +2träd +3träg +5träne +4träng +4träs +4träß +t1räts +2träuc +4träus +4träuß +4t5re. +2trea +t3reak +4treb +tre2br +4trec +t3rech +t4reck +5treck. +tre5cke +2t3red +3tref +4trefe +5treff +4trefl +4trefo +4treg +2t3reh +t4rei. +3t4reib +4treic +4treif +2t3reig +2t3reih +t4reik +4t3rein +2t3reis +tre7isch. +4treit +t3reiz +4t3rel +t4rem +t4ren. +5trend +6trendi +5trennu +t3rent +2trepe +2t3repo +3trepp +t3repr +t4rer +t4res. +tre2ta +t4rete +tret3r +tre4tri +2t3rett +3treuh +4t3rev +2t3rez +5t4ré +2t3rh +3tri +t4rib +t4rick +t4rid2 +5trieb +trie3fr +tri4ena +tri2er +tri4ers +4trig. +2trige +5t4rigg +tri3gl +t4rik +tri4ke. +tri4kes +5triko +t3rind +4tring +tri3ni +4t3rinn +t4rip +4tript +4t5riv +tri2x +trizi1 +3tro. +tro3b4 +4trock. +3troe +t4roi +tro4kes +trol4la +6trom. +tro6mans +4tromb +tro4men +tro2mi +4tromk +4troml +4troms +4tromt +3tron +tro3na +t4rop +3tropf +tro3sm +3trost +2trout +5troy +4t3röc +2tröh +6tröm +3tröp +3trös +4t3röss +3tröt +3trua +3trub +2t3ruc +4truf +4truk +trum2 +t3rumä +trums1 +t3rund +5trunk +5t4rup +t3russ +2t3rut +tru2th +4truw +trü1be +trü1bu +2t3rüc +trücker6 +t4rüg +3trümm +try1 +2ts +4ts. +ts3ab +t3sac +t4sachs +t2s1a2d +ts1ahn +ts5alben +t2sall +ts2ame +t4samp +t4s1amt +t2san +ts3ane +ts3a2r +t2s1a2s3 +t2sau +ts2av +t2säh +ts1än +ts1äus +t4sch3am +t6schart +t3sche +t4schef +t3schl +tsch4li +t4schro +t3schü +ts2cor +t2s1e2b +tse2e +t2sef +ts1eh +tse4he. +t3seil +t3seme +ts1eng +ts2ens +t2s1ent +t2s1ep +t2s1er +t6s5essen +tse2t +ts1eta +t2seth +t2s1eti +t2s1e2v +t2sex +t3sexi +t2s1i2d +t2si2k +ts3iko +tsing4 +t2sini +ts1ir +4tsk +t3skala +ts4kele +t4s3ko +ts1off +t3sol +t3som +t2s1op +tso2r +t2s1ori +ts3ort. +t3s2ouv +t2sö +t2spac +t2spal +ts1par +ts4pare +ts1pas +t2spat +ts3pate +t2spä +t3sped +t3spei +t3s2pek +t2sph +t3s2pi +t4s3pic +t4spins +t2spo +t3s2pon +t3s2por +t2spro +ts2pul +ts4put +ts5s4 +t1st4 +t4stabe +t2staf +t4stag +ts3tak +t4stale +t4s3tanz +t4stas +t4stat. +t4s3täti +t2stea +t3stein +ts4terb +t3s4tern +t3s4tero +t4s5th +t3stif +t3stim +t4stit +t4stoch +t4stoi +ts4tol +t4stren +ts4tric +t4strie +ts2tu +t5stub +ts4tüm +t4sty +t2s1u +5tsubi +ts3un +t4sw +tswa2s +t3sy +4t1t +tt1ab +tt2ac +tt3achs +tt1ad +tt2ag +tta6g5ess +t4t1ah +tta2ke +tt2al +tta4n +t4tana +t2tanm +tt2ant +t4t1ap +tt1art +tt1äh +tt1ebe +tt1eif +tt1ein +t2t1eis +t3tel +tte4la +tte4l3e4b +tte4len +tte4lin +ttel1o +t2temu +tte4na +t4tentb +t4tentf +t4tents +t2teo +tt4ere +tte4rik +tte2ro +tt2erö +tt2es1 +tte4sa +tte4s3ä2 +tte2so +tt2häu +tt3hi +t2t3ho +t3ti +t4tid +t4t3igi +t4tinf +t4tins +tt2int +tt4lef +t4torg +tto1s +t2trou +tt3rü +tt2sal +tt2sen +tts1p +tt2spe +tt2spr +tt4s3tät +tt3s2z +tt1u2f +t3tü +tt3z2 +1tu +3tua +tu4ale +tu1alm +tu1alv +tu3an +2tub2 +tuba3b +3tuc +tu2chi +tu1cho +2tud +tudie4n3 +3tue +tu2ere +2tuf +tuf2e +tu3fen +t3u2fer +3tuff +tu2gan +4tuh +tuh4ler +tu1ist +tu2kr +tul2i +3tum. +tum2b5l +3tume +4t3umf +2t3umg +2t1umh +2t3umk +2tuml +3t2umo +2t3umr +4t3umsat +2t1umsc +tum2si +tum2so +tum4s5tr +2t3umt +2t1umw +2t3umz +3tun. +2t1una +2t1und +tund2e +3tune +tun2en +2t3unf +3tung. +t3unga +3tunge +tung4s +2tunif +2tu2nio +2tuniv +2t1unm +3tunn +t1u2no +t3uns +3tuns. +4t3unt +2t1unv +2t1up. +tu2r1ag +tu2ran +turan4l +tu2ras +tu2rä +tur1c +tu2r1e2b +tu2rei +tur3eis +tu4rene +tu2r1er +tu4res +tu2re4t +tu2r3e2v +tur3f4 +turg2 +tu2rid +turin1 +tur4mun +3turn +tu2r3o +turo2p +tu4ru +3tus +tu2sa +tu4schl +tu2se +tu2so +tu3ta +2tü +4tüb +tü3ber. +3tüch +tück2s +3tüf +4tüh +3tüm +3tür. +tür1c +3türe +3türg +3tür3s +3türw +4türz +3tütc +3tüte +4tütz +4t1v2 +t3vo +tvoran4 +4t3w +t5wa2 +twi4e +t4wist +1ty1 +2t1y2a +3typ +ty2pa +tys2 +2t1z +t2za2 +tz1ag +tz3ar +tz1au +t2z1ä +t3zäh +tz1ec +t2z1e2d +tz1ehr +t2z1eie +t4z1eis +tze4n1 +tz2ene +tzen5s4t +t4z3entg +t4zentl +t4z3ents +tz2ere +tzer6gre +tz1erw +t3zer3z +t3ze2s3 +tze2t +tz1eti +t2z1i2d +tzig4s +tz1int +t2z3om +tz2th +tz2tin +tzu2gu +t2zuni +tzwan4d3 +tz1wä +tz1wi +t3zwie +tz1wu +2ua +u3a2b +u1a2c +uad4r +ua2g +u1al. +u1a2l1a +u1a2l1ä +u1alb +u1ald +uale2 +u3a2leb +u3a4lent +u3aler2 +ua4lerg +ual3erk +u3a2let +u1alf +u1alg +u1alh +u3a2lid +u1aln +ua2lo +u1alp +u1alr +u1als +u1al5t4 +ua2lu +u1alw +u1alz +u1am +uan2a +u1ans +uant2 +uan3ta +u3ar. +uara2b +u1ars +uar4t3an +ua3sa +uasi1 +ua2th +uat2i +uat2o +u3au +u1ay +u1äm +uä2s +u1äu +2u1b +ubb2l +ube2be +u8be8cken. +ube2e +u2b1ehe +u4b3eins +ube4n1a +uben3o +ub2er +u4b3erde +ubert4 +ub4es +ub1eul +u3bit +ub2l +ub3läu +ub3lic +ub3lu +ub4lut +u2bob +u2bop +u2b3oz +ub3ric +u2b3rit +ub4rü +ub2san +ubsau2 +ub4sche +ub2s1o +ub2sp +ubst2 +ub3t4h +4uc +uc1c +uch1a +u1cha. +uch1ä +u1che +uch1ec +u2ched +uch1ei +ucherin8t +u3ches +u1chi +uch3im +uch1in +uch3l +uch3m +uch3n +uch1op +u2ch3r +uch4sel +uch2so +uch2sp +uchst2 +uch6t5erf +uch6t5ert +ucht3re +u1chu +uch3ü +uch1w +u1ci +uck3elf +u2ckem +u4ckent +uck2er +ucker8geb +u2ck3i +uck4sti +u1cl +2u1d +u3d2a +ud2e +ude3i4 +udein7 +udel3se +ude2n1 +uden3e +uden3s2 +udert4 +udes2 +udi3en +uditi4 +ud2ob +u2don +ud3ra +u3dru +2u1e +ue2ck +u2ed +ue2en4 +u2eg +u2eh +ue2k +u4ela +ue2le +ueli4 +uel4lau +ue2mi +uen1 +u3en. +ue4n3a2 +u3end +uene2 +ue2ner +uen4gag +uenge2 +uen2gl +u3e2ni +uenk4 +ue2no +uen6zene +uen2zu +uen2zw +u2ep +ue2r3a2 +uera4t +ue2r1ä +uerb2 +uer6baut +uer3d2 +uere2 +ue2rec +uer4ei. +ue4rein +ue4r3emi +u3eremp +u3e4r3ent +ue3r4erb +u3ererf +ue4rer4g +uerer4h +uerer4l +uerer4m +ue6rersc +uerer6sp +ue6rerst +uer3esk +ue2ret +u3erex +uer3g2 +u3erin4t +u3erl. +u3ern +uer4nan +uer4ne +uern3s4t +ue2r3o4 +uer2ö +u3errü +uer3sc +uerst6 +uer3t4 +u3eruh +u3erum +u3erunf +u3erunt +u3erwi +uer3z2 +ue2ta +ue4tek +ue2ti +u2ev +ue2x1 +uf1ab +u3fac +ufa2ck +u3fah +uf1ak +u3fal +ufall4 +u3fam +ufa2n +uf3ane +u2f3a2r +u3fas +uf1aß +ufa2t +uf1au +u2f1än +u2f1äs +u2f1ä2ß +u2f1ei +ufel4s3a +u2f1em +u3fen. +u2fent +u2ferf +u2f1erh +u4ferla +u4ferle +u4ferne +u2f1et +2uff +uf3fe +uff4l +uf2fro +u2f1id +u2fim +u2f1ins +uf3l +u2fob +ufo2r +uf1ori +uf3r +uf5sä +uf2spo +uf4stab +uf4s3tic +2uft +ufta2b +uft1eb +uft3erd +uft3er4g +ufter4l +uf4tin +uft3s2 +u2fum +2u1g +ug2abe +u4gabte +u2g1a2d +u2g1ak +u2gani +u2g1ans +u2ganz +u2g1ap +ug1ar +ug1au +ug3d4 +u3ge. +ug1ei +u2geig +u2gein +uge4lob +ugen3s2 +u2g1erf +u2g1erl +u2gerr +u2gerv +u2g1esk +ug2et +ugg2 +ugge4st +ug2gl +ug3g4t +ug3hu +u2g1i2d +u2gim +ug1in +u2gl +u4g1lä +u6gleitb +u6gleitu +u4glic +u4glis +ug3liz +u4g3lo +u4glu +u4g3n +ugo3 +ugo4b +ug3oc +ug3om +u3gon +ugo4p +ug1or +u3gos +u2gö +u2g3rä +u2greg +u4g3reis +u2gres +ug3rie +ug3ro +u2grou +ug3rüs +ug3sei +ug3span +ugs4por +ug4spr +ug4spu +ugs4tan +ug3stä +ugs4to +ug3s4tr +ug3stu +ug4stur +ug3s4tü +u2gum +ug4unge +ug2uns +ugu3te +u2gü +u1h +uh2a +2u5he +uhe3a2 +uhe1s +2uhi +2uhl +uh1la +uh2lar +uh1lä +uh4l3ent +uhl3erb +uh2li +2uhm +uhr1a +uhrei4s +uh2r3er3 +2uh3ri +uh4rin +uh2r3o +uh2ru +uh4rü +uhs4 +u2hu +2uhü +uh1w +2ui +ui1ch +ui2che +ui4cker +u1ie +ui1em +u3ig +u4ige +uil4les +u1im +u3in. +u3isch. +u3ischs +uis2e +uisi4n +ui4s5t +uit3s +u1j +uk2a +ukä2 +uk1äh +u3käu +u1k2e +uke2n1 +u1ki +2u1k2l +ukle1i +uk4n +uko2m1 +uk2ö +u1kr +uk2ta +uk2t1el +uk4tent +uk2t1er +uk2tin +uk4t3o4ri +uk4t3r +ukts2 +uk2tum +u1ku +uku2s +uk2ü +u1l +ul1am +ulan2e +ul2ar +ula2s +ul1äm +ulb4l +ul4dan +ul2dei +ul2dr +uld2se +2ule +u2l1el +ul1emb +ule4n +ul1er2h +ule2t +ul1eta +2ul3f4 +ul1id +uli2k +ul1ins +ul3ka +ul2kn +ull1au +ul3le +ul4lerk +ul3l2i +ul2lo +ull3s2 +ulm2e +ulni2 +ulo2i +u2lop +u2l1or +ulp1h +ul2pha +ul2sa +ul4sam +ul2s1ec +ul2sei +ul2ser +uls2th +ul2sum +4ult2a +ult3ar +ul4tri +ult3s +u2lü +ul2vr +ulz2w +u2mab +u2m1ad +u2m1a2k +um1all +um1ang +um1anz +u2m1ap +um1a2r +u2marc +u2marm +u2mart +u3mat +u4matl +u4matm +u2m1aus +u2maut +u2m1äh +1umd2 +u3me. +u2m1ef +u2m1ein +umen1e +um5engel +umer2a +u2m1erf +um1erg +u3merk +u2m1erl +um1erw +umes2t +1umf +1umg +um1ide +um1ind +um1inh +um1ir +1umk +1uml +2umm +um2mei +u2m3ot +ump2fa +ump4fin +umpf4li +um2pho +1umr +um4sam +um4s3an +1umsat +um4s1er +um2sim +um2s1pe +um2sum +um3t4 +u2m3um +u2m1u2r +1umz +un1 +4un. +2una. +1unab +un2a3br +un2ag +un2al +u3n2am +u2n3an +u2nap +u2narb +2un2a1s4 +un3at +un2är +2und. +un2da +unda2b +und3ak +un4dap +1undd +2unde +un3de. +underer6 +und3erf +und3erö +underten8 +under8tend +und3erz +un2dex +1undf +2undg +un2dim +1undn +undo2b +un2dop +un2dor +4un2d3r +4unds. +2undsc +und3sp +und3st +un2d1um +undü4 +1undv +1undz +u3ne +une2b +une2d +un3eid +un3ein +un3eis +un2emi +une4n1 +unen2t +u4nerk +u4n3erz. +un2es4 +unf2 +un3fa +unft4s +un2gam +un2gat +3ungena +unge3r4e +1unget +1ungew +ung5h +un2glu +1unglü +un2go +un2gr +ung3ri +ungs3 +ung4sa +ungs5tr +u3nic +3u2nif +uni3k4 +un2im +1unio +un2ir +un3iro +un3isl +u3n2it +1u2niv +2unk +un2k1a2 +un3ker +un2k1es +un2ket +un2kne +unko2p +un2kro +unk3s2 +unk4tit +unk2tr +unk4tri +unlö2 +unna2 +un2n1ad +unn2e2 +unne4n +u2nob +uno4r +un2os +1unr +uns2 +2uns. +unsch5el +un3se +1un3si +un3sk +un3sp +unsta4g +unste4c +uns4t1r +4unsy +4unsz +1unt +un3ta +un3te +unte4ri +4unti +un3tr +unt3s +2untu +3unty +2u2nu +u3nuc +unvol2 +unvoll3 +1unw +4unwä +3unwe +u2ny +2unz +un3z2a +unz2e +2uo +u1o2b +u3of +u3or. +u1or3c +uore4 +u3o2ret +u3ors +u1ort +u1orw +uos2 +u1os. +uote2 +u1o2x +uö2d +u1ök +u1pa +3upd +u1pe2 +uper1 +upe4re +uperer4 +up2fa +u2pfe +u2pf1i +up2fu +3upg +u3p4i +up4lu +up2pl +u1pr +upra3 +u2p3ras +up4t3a2 +upten1 +up4tene +upt3erf +upt3erg +upt3erk +upt3ers +up4tid +up4tim +up4t1o +up4tr +u1q +4ur. +u1ra +u2rab +u3raba +ura2be +u2r1akt +u2ral4t +u2r1a2m +ura4na +uran3a4t +u3rand +ur1ang +uran4ge +ur2anh +uran5s +ur1anz +ur3ap +u2r3ar +ura4ri +u3rasc +ur3asp +ura4str +ur4ate +ura3to +u2r3att +u2r1au +2u1rä +ur1äl +ur1ä2m +ur1än +ur3b2a +2urc +urch1 +urcht3e +urd2 +ur3da +ur3di +ur1eff +ur1eig +u2rele +ure2n +ure4na +uren6gag +u4rense +u4rentn +u2r1ep +ur1er3h +urer3k +ur2ert +u2rerw +ur1eta +ur2eth +ure3u +2urf +ur2f3l +ur2fro +urf4spr +urf3t +ur6gense +urg3inn +urg1l +ur2gla +ur2gri +urgros4 +urg3s4 +uri2c +ur1ide +uri3en +u2rind +urin8stin +ur3ku +ur3l +ur4mant +ur4matt +ur2mau +urm2ei +ur4mern +urmet1 +ur2mum +ur2mun +ur3n2e +4u1ro +ur1off +uro1s4 +urost2 +2u1rö +ur3p4 +2urr +ur3re +3ur3sac +ur2san +ursau4 +ur2s1er +ur4s1of +ur2spa +urst4r +ur3sze +urt2 +2urta +ur2tai +urt3ein +ur3ti +ur2tro +urt3sc +u3ru +uruf4 +urü2 +ur2z1a2 +ur2zä +ur2z1ec +ur2zep +ur2zi +ur2z1op +urzt4 +ur2z1w +2us +us3a2b +u4s3af +usa2gi +u4s1amb +u4samt +u2sang +us2ann +us3ark +u2s1a2s3 +u2säh +u4schab +u4schak +u3sche. +u4schef +usch5eic +u4sch3eu +u3schi +usch3mü +u3schu +usch5wer +u3se. +u3s2e3b +u2s1ec +u2s1ei +u3seid +u4sense +u4sentl +u3sep +use3ran +use4rec +u2s1erl +u2serp +us1erw +u2s1ese +u2sex +u3si. +u2sid +usi3er. +usi5ers. +us1inn +us1is. +us3kl +us3oc +us1oh +u3sol +u2sop +us1ou +u2spac +us3part +u2s1pas +us1pe +u3s2pec +u3s2pek +u2sph +us1pic +u3spit +u3s4piz +u2spo +us2por +u2spu +usrich7 +us2s1eb +usse4g +uss2el +usse4n +us2sep +us5ser. +uss3erf +usser4z +us4sesp +us2sez +us2sof +us2sum +u1stal +us3tau +us4tein +u1stel +ust3erl +us2th +us3ther +us3t2in +us3tr +u3s4tras +us6tris +u1stu +u2stun +u2stur +u2sumd +u2sumg +u2sumz +3usus +u2sü +2u1ß +u2ß1u +2u1t +u3taf +u2t1alt +u4t1a2m +ut2ans +u2t1ap +u2t1ar +uta2s +u2taut +ut1äh +u2tär +ut3c +ut1e2d +u3teh +ut1ei. +ut1eie +ut1ein +u3tek +ut1ela +u3tem +ute2n1 +uten2a +u2tent +u4tentf +uter3a +ute4ral +ute5r4er +ute6ring +ute4ros +ut2es +u3t2et +u2t2ev +u2t1ex +utfi2 +ut3hel +u2t3hi +u2t3ho +u2thu +u2thy +u2tid +uti2vi +utli4n +uto3 +uto4ber +u3tom +u2tops +utor2a +u4tord +utos4 +u2töl +4utr +ut3rea +u2trou +ut3rü +4uts +ut3sau2 +ut2säu +ut4schl +ut4schm +ut4scho +ut4schö +ut3ser +ut3s2k +ut3te +ut5t2l +utt4le +utts2 +utu2b +u2tum +utu4n +u4t1une +utu4re +utu3ro +utu5ru +u3tü +u4tz +ut2zeh +utz3eng +utz2er +ut2zet +ut2z1in +ut2z1w +2u3u4 +uufe2 +uum1 +uuma4 +u1ü2 +2u1v4 +u2ve. +uve3rä +u1w +2u1x +ux2e +ux2o +ux3t2 +u1ya +2u1z +u2z1ec +uz2er +uzo2f +uz3ot +uz1we +uz3z2 +1üb +üb1ä +2übc +2übd +üb4e2 +übe3c +übe3le +übe4na +übe3ne +über3 +ü4bet +üb3l +üb3r +üb2s3t +2üc +ü1che +üch3l +üch2s1c +ücht4e +ü3cke4n +ück1er +ück3eri +ücker6ke +ü4ckers +ü2ckin +ü4d3a4 +üde2c +üde2l +ü3den. +üden2g +ü3d2ens +üd3o4 +üd3r +üd3s2 +üd3t4 +üdu2 +üe2 +üeb3 +ü1ei +ü2f1a +ü2f1ä +ü2f1ei +ü2fent +üfer2 +ü2f1erg +üf2fl +ü2f3i +üf3l +ü2fo +üf3ter +ü2fum +ü1g +üg2e +üge2l1a2 +üge2lä +üge4lec +üge6lei6s +üge2lo +ügen3s +ü2g3l +ü2gn +üg3s2 +üg4s3t +üh3a2 +ü1he +ü2h1ei +ü2h1eng +ü2h1ent +üh1er +ü2herf +ü2her2k +ü2her2z +ü2hex +üh1i4 +ühla2 +üh1lä +ühl2er +ühl4sta +ühl4sti +üh3mo +üh3ne +ühn2s +üh1o2 +üh3r2e +ühr3ei. +ühre2n1 +ühren3s4 +üh1ro +ühr3ta +üh1s +ühs2p +üh3t2 +üht4r +ü1hu +üh1w +ü1k2 +ül1a +ül2c +ü3l2e +ü4l3ef +üle2ra +ül2l1a2 +ül2l1ei +üll2er +ül2lid +ül2lo +ül2lö +ülls2 +ü2lö +ü1lu +ü2ma +ü2ment +üme2ra +ü2m1id +ü2m1in +ü2m1u +2ün +ü4n3a2 +ün2da +ün2dr +ünd3s +ü2n1erd +ünf1 +ünf3li +ün2g3l +ün2s +ün3sc +ün3se +ün3sp +ünster3 +ün3str +ün2za +ünzu2 +ün2zun +ün2zw +ü1pe +üpf3l +ü1pi +üp2pl +ür1a +ü2r1ei +ü2r1e2l +ür2fl +ür2fr +ür4g3en4g +ürge4ra +ürk2e +ü1r2o3 +ürom2 +üror2 +ürr2 +ür2s +ür3sc +ür3se +ür3si +ür3sp +ürte2l3 +ürt4h +ürz2a +ür2z1in +ür2zö +ür2z1w +üs2a +ü2schl +üs2e +üse1e2 +üse3l2 +üse4n +üse1r4 +üse1s +üse3t +üs2s3a +üs2s1c +üss2e +üs4s1o +üs2st +üst3a2 +üste2n +2ü1ß +2üt +ü2t1al +üte3m +üte4n +üten3s +ütent4 +üten3z2 +üte2ra +üte2r1e +üterich6 +üter3n +ü2t3h +ü2t3r +üt2s1 +ütte4n +üt2tr +üt3z2e +üt2zw +ü1v +ü1z +3va. +2v1ab +vab4r +va1c +va1f4 +vag2a +va2la +2valu +2vanb +2vang +2varb +v1arm +va1s2 +2v1ass +v4at +va2t1a2 +va2tei +va4t3eng +va4tess +va2t3h +va4tid +vatik2 +va4tim +va4t1in +vati8ons. +va4tord +va4t3r +vat3s4 +va2t1u +2v1au +2v1b +2v1c +2v1d2 +1ve2 +ve3an +ve3ar +veau1s +ve3b4 +ve3d +ve3fa +ve3g +ve3h2 +2veig +v2eil +2vein +veit2 +veits3 +ve3la +2velan +ve4l1au +v1ele +ve3lei +ve3li +ve3lo +ve3ma +ve3me +2vemu +ve3nal +ve4nas +ven2c +ve3ne +ve3ni +ve4nin +ve3nö +ven6t3ag +ve3of +ver1 +ver3a +ve3rad +2veral +ve3rand +ver4ane +vera4s +ver6bart +ver3b2l +ver3d2 +vere2 +ve4rek +verf4 +ver3fa +ver3g4 +ve3ri +ve4rin +ver3k +vern2 +ver4sep +vert4 +ver5te +ver3u4 +ves1 +ve3sa +2ve3s2c +2ve3s2e +ves3ti +ve3t +vete1 +vete3r +2veü +ve3v +ve3w +ve3x +2v1f4 +2v1g +2v1h +vi2ad +vi3ar +vi4a3t +vi2ä +vi2c +vi3de +vid3s2t +vie2h1a +vi2el +viela2 +viele2 +vi2er +vie4rec +vie2w1 +vig2 +2vii +v2il +vi2l1a +vi2lä +vi4l1e2h +vi2lei +vi4lers +vi2l3in +2v1i2m +vima2 +vi4na +2v1in3d +ving5 +2v1int +vi3sa +vise4 +vi3s2i +vi3s2o +vi2sp +vis2u +viv2 +vi3z +vize1 +2v1k +2v1l2 +v3le3 +v2lie +2v1m +vm2e +2v1n2 +1vo +2v1ob +vo2be +vob4l +vo3ga +voge2l1 +vo2gu +vol2a +vol2l1a +vollen6 +vol6lend +vol6lert +vol2li +2v1op +vo2r1 +vor3a +voran8schl +vore2 +vor3g +vo3ri +vo4rie +vo5rig +vorm2 +vormen4 +vor3o +vort4 +vot2a +voy1 +vö2c +2v1p +vr2 +v1ra +v2ree +3v2ri +v1ro +2vs +vs2c +vs2e +vs2p +v1sta +v1steu +v3s2z +2v1t +vue3 +vu2enu +vu2et +2vumf +2vumg +2vumk +2v1ü +2v1v +2v1w +2v1z +w2a +1waa +wab2bl +wa3che +wach8stub +wach4t4r +1wack +waffe2 +waffel3 +1wag +wa5ge +3wage4n +wa2g3n +wa3go +1wah +wahl5ent +wah4ler +wah2l1i +1wal +wala3c +wa2lar +2walb +wal2d3a +wal4din +wa2les +wa3li +wal2m1 +wals2 +wal2t1a +wal6tere +wal6terl +wal4to +wal4tur +3walz +wa3na +wan2d1a2 +wandels6 +wan2dr +w3anf +2wang +wan3g2e +wang4s +1wann +wan6z5en6d +wan4zer +wa2p +1war2e +ware1i +wa3ren +1warn +wart4e +war2th +1was +wa3sa +was2c +wa4scha +wa3sche +wa4sch3l +wa4schw +wa3sh +was3s +wass4e2 +wa3su +w2ä +1wäh +1wäl +2wäng +1wäs +wäs2c +wäss4e +2w3äu +2w1b2 +wbu2 +2w1c +2w1d +we2a +we2b1a +webe1i +we2b3l +we2bo +we2b3r +webs2c +we3cke. +we5cken. +we3ckes +we2e2 +weed3 +we2fl +1weg +we2g1a +we4g1ei +weg5ersc +we4g3l +we4gn +we2g1o2 +we2g3r +weg3s +wegs2a +wegs4t +1weh +weh4r3er +wei2bl +weib4r +wei3dr +2weie +weifel6d +wei2gr +weigs4 +wei3k4 +3weil +wei3nel +weins3a +weinsau6 +wei3sc +weis6sel +weis6spi +wei2t3r +wei5ze +wel5le4 +wel6schl +wel6schr +wel2t1 +wel4t3a2 +welte2 +wel6t5en6d +wel4th +welt3i +wel4to +wel4t3r +wen3a2 +wendes4 +wen2gl +we3n2i +wen2ka +wen4kla +wen4k3ri +we2r3a2 +wer5be +werbe3i +wer2bl +werb2s +1werbu +werd2 +werde3i +5werdens +1werdu +werer2 +wer2fl +2werg +wer6gels +wer2g3o +wer2gr +werin2 +we4r3io +1werk. +wer2k1a +1werke +wer2ki +wer2k3l +wer2kn +wer2ko +wer4kre +wer2ku +we2rö +wer2s +wer2t1a +wer2tä +wer3t3ei +wer6teig +werter6k +wer6t5erm +wer2th +wer4t1o2 +wer4tre +wer4t3ri +wer4tum +1wes2e +we2s1p +we4st +wes4t1a +weste2 +west3ei +wes6ten6d +wes4tex +wes4ti +wes4t1o4 +west3r +wes2tu +1wet +2wets +wett3s +2w3ey +2w1g +whi4 +w3ho +w2i +wicht4s +wi1cka +1wid +wi2e +2wieb +1wied +wie3l +wie3n2e +1wild +wim2ma +wim4m3u +win2a +win4d3e4c +win4dei +win6d5erz +1win2d5r +2wing +win2g3r +win2kl +win8n7er8sc +win2no +win3s +wint2 +1wi4r +wire3 +wisch3l +wi5s2e +wi2sp +1wiss +wiss4z +wi3th +1witz. +1witzl +wiz2 +2w1k +2w1l +2w1m +2wn +wns2a +wn3sh +1wo1c +wo2cha +woch2e4 +1woh +woh4lei +1wolf +wolf2s3 +wol2la +wol4ler +wor3a +wor3d +wo2r3i +worn2 +wort1a +wor4tel +wor6terh +wor4t3r +wort3s2 +wo4r3u +wor3ü +wot2 +1wöc +wöl2fo +wört4h +2w1p +w2r +w3ro +4w1s +ws2e +w3s2h +w3s2k +ws2t +2w1t +wti2 +1wuc +wuch4sc +wuch4st +w1u2f +wul2 +wul3se +wund4e +wung3r +wungs4 +wun2s +wunsch5l +4wur. +wur2fa +wur2f1o +wur2fr +wur2s +1wurst +wus2 +wus3te +1wu4t1 +1wüh +wül2 +wün3 +1würf +1würst +2w1w +2w1z +x1a +1xa. +2xa2b +1x2ad +1xae +xa1fl +1x2a3g2 +2xal +xal2l +xa2m +xand4 +x2an3t2 +x2anz +1x2as +2x1b4 +2xc +x1ce +x1ch +x1cl +4x1d +xda4 +1xe +2x1e4g +2xek +xe2l +x1ele +x1em +3x2em. +x2ems +x2en +xen3s2 +x2er. +x2ere +2xerl +xers2 +2x1eu +2x1ex +4x1f +2x1g +2x1h +xi1c +xich2 +2xid +xi2dan +xide2 +xi2dei +xi2d1em +x1i2do +xi4ds +3x2ie +xie3l +xi3g +xi2ler +xi2lo +xi2l1u +xim2 +xin3s2 +x2is1 +xi2sa +xis2c +xi2se +xi2so2 +xi2sp +xis3s2 +xis3t +xis4tä +xi2su +x1i4tu +xive4 +2x1j +2x1k2 +xkal2 +4x2l2 +x3lä +x3le +2x1m +2x1n +2xod +2x3oe4 +x1or +2x1ö2 +4x1p +xpor6ter +xpor4t3r +x1q +2x1r +4x3s2 +4x1t +xt1a +x3tan +xt2ant +x3tas +x2t1ä +x3tät +xtblo4 +x2t1e2d +xt1ein +x2t1el +x4tent +x2t1er2f +x2t1ev +xtfi2 +x2t3h +x2tid +xti2la +x2til2l +xt1o2 +x4tor +xtra3b4 +x2t3ran +x2trau +xt3rec +xt3s2 +x2t1um +x2t1un +1xu +xu1a +2x1u2n +xu2s3 +xuss4 +2xv +2x1w +2xy +3xy. +3xys +2x1z +2yab +1ya2c +y2ach +y2ag +ya1h +y1al. +y1a2m +y2ana +yan2g +y1ank +y2a3ra +ya2s3 +yat2 +ya3z +y1ät +y1b +y1c +y2chi +y3chis +ych3n +y1d4 +y3dr +ydri4 +ydrid1 +y1e +y2ec +ye2d +y2ef +y2el +yen4n +y2ere +yer2n1 +y2es +yes2p +y3est +ye2th +y1f2 +y1g +ygi2 +ygie5 +yg2l +y1h +yhr2 +y3i4 +y1j +y1k2 +yke3n +yk4l +yk3s2 +y1l +yl1a2c +y2l1a2m +yla2n +yl3ane +y3lant +yl4ante +yl4anti +y4lantr +y3lat +ylau2 +yl3c +yle2 +y2le. +yl1em +y2l1es +y2l1et +yli4n +yloi4 +yloid1 +yloni1 +yl1ora +yl3s2 +ym4a +ym4e +ymp4 +ym2pha +ympi1 +yn2eu +yn3k2 +y2n1o +yno4d +yno4t +yob2 +yoga3 +yom4 +yon2a +yon4i +y1ont +y1o1s2 +y2ost +y1ou +2y1p +ypa2 +yp1ab3 +yp1an +yp2e2 +y2pf +y2p1i2d +y2p1in +y2p3l +ypo3 +y4p3s +yp3t +ypu2 +y2p1um +y1q +y1r +yra3k +y3r2e +y3ri +yri2a +yri1e +yri3en +y3ro +yros3t +yrr2 +ys2an +ys2c +ys2e1 +ysein2 +y3s2h +y4s3l +ysme3 +ys4po +ys1pr +yst2e +yst4h +ys2the +ys3to +ys3tr +ys4tra +y4stro +y3s2ty +ysu2 +y2s1ur +y3s2z +y1t2 +y2te. +y2tes +yt4h +ythe1 +y3to1 +ytos2 +y4t3r +yt3t +y1u2r +y1v +y1w +y1y +y1z2 +yze3r2 +2z1a2b +zab3l +za1c +2z1a2d +2z1af +za3gr +3z2ah +zah3le +zah4ner4 +2z3ak +4zakk +2z1al +3zali +2z1a2m +z1a2n +z2an. +4za4na +2zanb +za3ne +2zanf +2zangs +3z2ank +zan2ka +2zanr +zans4 +zanti1 +za4pf +z1aq +z1ar +3zar. +2zarb +2zarm +3z2aro +zar2tr +2z1as +za2sc +zast4 +z3at +zat2e +za2to +3zaub +z1au2f +2z3aug +3zaun +z3aur +2z1aut +zä2 +2z1äc +z2äh +zä3hi +2z1äm +z1än +z1äp +z1är +2z1äus +2zäuß +4z3b4 +zbe3r2e +zbü1b +zbübe3 +2z3c +2z3d2 +zdan2 +zdä1 +zdi1st +3ze. +2z1e2ben +ze1c +2z1e2cho +ze1e2 +zeeu3 +2z1eff +z1e2ga +zehe4 +zehen1 +zeh2l +ze3ho +z2ei1f4 +zeil2 +zei3la +zeile4 +2z1ein +ze3in. +z2e1ind +zei4ne +z2eino +ze3inse +ze2i1s4 +zei3sk +zeist4 +3zeit +zei2t1a +zei4t3er +zei4to +zei2tr +zei4t3ri +ze2l1a +zela2d +ze2l1ä +zel3d +2ze2lek +2zelem +ze2len +ze2l1er +ze2l1in +2z1e2lit +zel3la +zel4l3ac +zel6lein +zel6ler6t +zell3s2 +zelm4 +ze2l1o +zels2 +zel3sa +zel3sz +zelu2 +zembe2 +2z1emp +5zen. +ze4n1ac +ze4nas +zen3au +ze3n2em +zenen1 +4zenge. +z4engl +2zengp +zen3n +ze2n3o +ze4not +4zensem +zens2p +zen4tha +z2entn +zent3s +2zentw +2zentz +zen4z3er +zen2zw +zeo4r +3z2er. +ze2rad +ze1ral +ze2re2b +z2erfe +2z1ergä +4z3ergeb +z4erges +z4ergl +zer4gon +2z1ergu +z2erhe +2z3erhö +zerin6te +z2erko +3zerl. +zer4lau +zer4le. +4zerleb +zer4len +2zerlö +3z2ern +zer4nan +zer4n3e4b +zer4nei +2z1erö +zer2öf +2z1erq +4z3erreg +zers2 +z2ers. +2z1er4sa +zerta2 +zer4t3ag +zert4an +zer6teng +zer6tere +zer6terl +zer4tin +zer4to +6z5ertrag +zer6trau +z1erwe +2z1erz +zer2ze +4z3erzi +ze2sä +ze3sch +zes1e +ze2sp +ze4spo +ze4spr +zes2sa +zes4seb +zes4sei +zessen4 +zes6s5end +zes6sent +zes4ser4 +zes2sp +zes2st +ze1sta +ze3stau +zes5tr +zes6tra +2zeta +2z1e2th +ze2tr +2zetts +zeu2g3r +2z1eul +ze1ur +2z1e2x1 +4z3f4 +zfeue2 +2z3g4 +zger2a +zger4s3 +2z1h2 +z2hen +zhir3 +zi3ar +zich2o +zi2dei +zie4ler +zie2l1i +zien3s +zi1erh +zi1es +zi3ess +z2il +zil2e +zill2 +2zimp +zim4t3 +2z1ind +zin2e +zin3ei +2z1inf +z1inh +zi4n3in +zin1it +2z1inj +zin2na +zin4o +zin2sa +zin4ser +4zinsuf +2zint +2z1inv +zi2o3 +zirk2 +zirk6s +2z1i2so +zisse4 +zi3s2z +zi2tan +zite4 +zi1th +zithe2 +zi4t1o4 +ziv2 +2z1j +4z1k4 +2z1l2 +zlei3ti +zle1s +z3ly +2z1m2 +zme2e +2z3n2 +z3oas +2z1ob +z1of +zo2gl +zog4s3 +2z1oh +zol2la +zoller4 +zol6lert +zon3s4 +zon4t3er +zo2o +2zope +2z1o2r +zo3re +3z2orn +zor4ne +2z1osz +2z1ou +2zö2f +2z1ök +z1öl +3z2öll +2zöls +2zön +4z3p4 +2z1q +4z3r2 +4z1s4 +z3sa +zsau2 +z3sh +z3sk +zspor2 +z3sz +2z1t +zta2n +zt3ane +z2t1au +z4tehe +ztein1 +zt3eins +zt2el +z4t1ent +z4t1erz +zte3str +zt3he +z3t4hem +z3t4her +zt3hi +zt3ho +z3thr +z3thy +z3tic +zt3rec +zt3s2 +z3tü +zu1 +zu3a +zub4 +3zuc +zuch2e +zud4 +zudi4 +zu2el +zu3e2r1 +zu3f4 +zu2gar +zu4gent +zu3g1l +zu4gla +zu4glö +zu2go +zug1un +2z1uhr +zu3hu +zui2 +zu3k +zul2 +2z1um. +zum2a +2z1umb +zumen2 +2zumf +2zumg +zum2i +2zuml +2zumr +2z1ums +zum2u +2zunab +zun2e +2z1unem +zunf4 +zung4 +4zunget +2z1ungl +z1uni +2zu2nio +2zuniv +2zunr +2z1uns +2zunt +zuo2 +zup2fi +zu3pl +zu3r4a +2z1urk +2z1url +2z1urn +2z1urs +2z1urt +zu3s4 +zusch4 +zu3t2 +zut4r +zut4u +zut3z +zuz2 +2zü4b +3züc +zür1c +2z1v +zw2 +z1wac +2zwag +2zwah +2zwal +2zwap +z1war +2zwa2s +2zwäs +2z1wed +2zweg +2zweh +z2weig +2zweil +zweiter6 +2z1wel +2z1wen +2z1wer +2z1wes +z2wic +zwi4e +3zwing +2zwirt +z2wisc +2zwiss +z2wit +2z1wo +z1wör +z1wur +2z1wü +zy1an. +zy2le +4z1z +z3z2a +zza3b4 +z4z3al +zz4at +z2z1id +zzin1 +zz1ini +zzi1s4 +zz2ö +zzug4s +} + +\endinput + +% Local Variables: +% mode: tex +% coding: latin-1 +% fill-column: 72 +% End: +% vim: set filetype=tex textwidth=72: diff --git a/tmac/hyphen.det b/tmac/hyphen.det new file mode 100644 index 0000000..65a5ca8 --- /dev/null +++ b/tmac/hyphen.det @@ -0,0 +1,23515 @@ +% This is the groff hyphenation pattern file 'hyphen.det' for German +% with hyphenation rules for the traditional orthography. +% +% It is based on the file 'dehypht-x-2017-03-31.pat' taken from the +% 'dehyph-exptl-0.41' package, converted to latin-1 encoding. +% +% Below is the original copyright message. +% +% ------------------------------------------------------------------------- +% +% TeX-Trennmuster für die traditionelle deutsche Rechtschreibung +% +% Copyright (c) 2013-2017 +% Stephan Hennig, Werner Lemberg, Guenter Milde, Sander van Geloven, +% Georg Pfeiffer, Gisbert W. Selke, Tobias Wendorf +% +% Licensed under the MIT license. Full license text available from +% +% http://opensource.org/licenses/mit-license.php +% +% +% The word list is available from +% +% http://repo.or.cz/w/wortliste.git?a=commit;h=5fd786fcb1ed48448e058672f1f58d185653d8c6 +% +% The used patgen parameters are +% +% 1 1 | 2 5 | 1 1 1 +% 2 2 | 2 5 | 1 2 1 +% 3 3 | 2 6 | 1 1 1 +% 4 4 | 2 6 | 1 4 1 +% 5 5 | 2 7 | 1 1 1 +% 6 6 | 2 7 | 1 6 1 +% 7 7 | 2 13 | 1 4 1 +% 8 8 | 2 13 | 1 8 1 + +\patterns{% +.ab1a +.ab3l +.abo2 +.ab3ol +.ab1or +.ab3s2 +.ab3u +.ade3n +.ae3 +.aft2 +.ag2a +.ag4r +.ag2u +.ai2s +.akt2a +.al2e +.al3k +.al3lei +.al5len +.al3se +.al4tei +.alter6s5 +.alt1s +.al2tu +.ampe4 +.amt2s +.ana1c +.an3d2 +.anden6k +.and4ri +.an1er +.ang2 +.an3gli +.ang4s2 +.angst3 +.ani2s +.an3k4 +.an3na +.an3s2 +.an4si. +.an3z2 +.aos4 +.ap5p6le. +.aps2 +.ari1e +.ar3k2a +.ar4m3ac +.ar4mun +.ar2sc +.ar4tan +.ar4t3ei +.arter4 +.ar6t5erh +.ar2tr +.arz2 +.as6sest +.as2t +.ata1 +.ate2 +.at4h +.au3d +.aue2 +.au4f3 +.aufs2 +.au2s1 +.au6stes +.auß2 +.ax2 +.äm3 +.är6schl +.ät2h +.ät2s +.äu3 +.bahn3 +.bah6ner +.baus4 +.be3erb +.bel2a +.be3r4a +.be3r2e +.ber4g3a +.ber6g5e6b +.ber4g3r +.ber4tr +.bi4os +.bi2t +.bit1a +.boge2 +.bo4s3k +.bu4ser +.bus3se +.bu7s8ser. +.bussy8stem. +.ch4 +.char8mes +.chi3er +.dab4 +.da2r1 +.dar3in +.darm1 +.da4te. +.da4tes +.de2al +.de1i +.dein2 +.de3lo +.de8ments +.den4ka +.den4kl +.den4ko +.de1o2 +.de3r4en +.derma3 +.dermas6 +.de3sk +.di3el +.di4en2 +.dien8sta +.dienst7a8d +.do3b +.do2mo +.do1pe +.dor2f1 +.dy2s3 +.ebe2r1 +.edu3s +.eg2o +.eh2e +.ehe1i +.ei3e2 +.ei3f2e +.ei3k +.einbus6 +.ein3d +.eine2 +.ei4neb +.ein6erl +.eise4 +.ei2sp +.eis3s2 +.ei4s1t +.ei2tr +.eke2 +.ek3li +.el2bi +.el2bl +.el4fei +.el2fl +.el2i +.em3m2 +.en1 +.en4da +.en4d3er4 +.en2d3r +.en4dü +.en2gl +.enn2 +.ent3 +.en2ta +.en4tei +.en4tio +.en2t1r +.ents2 +.epi1 +.ep3p +.er4bei +.er8brecht +.er2bu +.er4dan +.er4dei +.erden6k +.er4dep +.er4d3er +.er1e +.ere3c +.erf4 +.er1i +.ers2 +.er8stein +.erster6 +.er8sterb +.er8stritt. +.er8stritten. +.ert2 +.er4z3el +.er4zen4 +.ese3le +.es3p +.es2st +.es2t +.est6e +.est3r +.et2s +.eu1 +.eu3g4 +.eu3r4 +.eu3t +.eve4r +.ext4 +.fe3la +.fer4no +.fe4sta +.fid2 +.fi4le. +.fi4len +.fi2s +.flö8s7se. +.flö8s7sen. +.flö8s7ses +.flug1 +.fs4 +.fu2sc +.ga2me +.gangs4 +.ga4s3e +.ga6sten +.ga2t +.gd2 +.gebe4a +.geb2l +.gel4b3r +.gel2d1 +.ge3lu +.ge5nar +.ge3n4e +.ge3n2o +.gente4 +.ge3r4a +.ge3r2e +.ge3ro +.ge3s2 +.get4 +.ge3u +.glan2 +.gla4s3t +.gol6der +.grif8fes +.gus2 +.haft3s +.hal5le +.hal2s +.halt4e +.hau4sa +.hau2t1 +.he2 +.he4bei +.he3fe +.he3le +.her3an +.he3rat +.her6b5ra +.he3rer +.he3ri +.he6r5inn +.hin3u +.hof1e +.ho4fen +.ho4met +.höch2 +.ia2 +.il3 +.im2a +.ima4ge +.im5m2 +.in1 +.ind4 +.in3gl +.ink2 +.in3n2e +.in3sk +.inu1 +.ioni1 +.ire3 +.is2a +.it2h +.iv2 +.ivo3 +.joni1 +.jor3 +.ka2b5l +.ka2i +.ka3le +.ka3ta +.ka4t3io +.ken6num +.ker3s +.ki4e +.klang3 +.ko3b +.kopf1 +.kor4da +.kraf2 +.ks4 +.kus2 +.la3be +.la3ho +.lase2 +.le4ar +.le4gas +.le3n2i +.len3z +.lich8t7er8s +.li2f +.li3po +.li4ve. +.lo4g3in +.lo2sc +.los3s2 +.lo3ver +.lö4ss +.lus2 +.luster6 +.lu4str +.lut4h +.ma3d +.mal4e +.mas8sen. +.ma4str +.mat4c +.matu3 +.md2 +.me3l2a +.me3ne +.me3no +.men8schl +.men8schw +.ment4 +.mes4sp +.mi2f +.mik4 +.mil2z +.mi2t1 +.mm2 +.na3no +.na3t +.nat2h +.näs5c +.nebe4n +.ner2f +.ne1ro +.nich2 +.nicht5e +.ni2e +.ni3k4l +.nob4 +.no2c +.no2s +.no4th +.nul2 +.nus4 +.oa5s +.ob1a +.obe2 +.ober5ei +.of2e +.ohr5s +.oper4 +.or2a +.ord4e +.ort2 +.ort4h +.orts3e +.os3s +.os5t6alg +.oste2 +.ost3el +.ost5end +.osten8de +.oste6re +.ost3r +.ot1 +.ozo4 +.öl3l +.pab4 +.pa2r1e +.par3t4h +.pe2c +.pe3la +.pe3le +.pe4ste +.pf4 +.ph4 +.poka2 +.po6stei +.po4str +.ps2 +.rabe4 +.ra3ch4e +.ra3me +.ra4sp +.ra4s3s +.rau2m +.rau8schl +.re3ale +.rebs2 +.re3cha +.re5insz +.reis6e5i +.reli1 +.res2t +.re4stu +.ri4as +.richt6e +.ro4a +.ro3be +.ro2ha +.ro3m4a +.ro2tr +.ro3tu +.rö2sc +.rö4ss +.rös3se +.ruf3s +.ruh2r1 +.runder6 +.ru5s6ses +.rü1b +.rücker6 +.rü4ss +.sa3br +.sali1 +.sami1 +.sas2 +.sa3sse +.sau1c +.sau5er. +.sä5s4 +.sch4 +.schaf8t7end +.scheiner8 +.scho7s8se. +.scho7s8ses. +.se2ei +.se2ha +.sein2 +.sen4f +.sen3s +.se3re +.se1ro +.se2t1 +.sha2 +.si3gn +.si2te +.ski1e +.sour2 +.spani7er. +.spä5s4 +.spiege8lei +.st4 +.ste2i +.steiner8k +.sto4re +.stras4 +.sucher6 +.tage4s +.tan4k3a +.tan4k3l +.ta3ra +.tar3t +.ta2t3h +.ta2to +.ta2t1u +.te2e +.te2f +.tehe3 +.teiler8s +.tei8l7ersc +.te3l +.te3no +.ten3s +.te1ra +.te6stei +.te6stel +.tester8g +.tester8h +.th4 +.ti2e +.ti2me +.ti4mes +.ti2s +.ti8sch7end +.tite4 +.tode2 +.to4der +.to2n +.to4nat +.to3nes +.to4nin +.to4pl +.to2pr +.to2w +.tras3 +.tra4ss +.tri3e4s +.trockenmas8 +.ts4 +.tsa3 +.tse3 +.tu3ra +.tu3ri +.turm1 +.tur4ma +.ub2 +.ufe2 +.ufer1 +.ul2b3 +.um3 +.ume2 +.umo2 +.ums2 +.un3a2 +.un3d +.une4 +.un3g +.uni2t +.ur3a2d +.ural4 +.uran6fa +.ur1c +.ur1e +.ur4inf +.ur3o4m +.ur1o2p +.ur3s2 +.ut2a +.ut3r +.übe4 +.ve5n2e +.vol2 +.vo4r +.wah4l +.wa2s +.weg5s +.wei4ta +.welter8e +.welter8kl +.wer6ker +.wer4kr +.wer4tr +.wetterer8s +.wi4e +.wor2 +.wort5en6 +.wur2f1 +.xe3 +.ya4l +.zahn3 +.zeit3s +.zel4la4 +.zelle4 +.zel6lei +.zel4li +.zeug4i +.zi2e +.zie4l3u +.zin4ka +.zin4s3c +.zin4st +.zol2 +.zuch2 +.zucht3 +.zug3l +.zu4gra +.zu2pf +.zweigen8 +.zwei8g7end +a1ab +aa2be +aa1c +a1a2ce +aa2gr +a1akt +a1a2n +a2ans +a1aq +2a2ar +aa2r3a +aar3b +aar3d +aa3rea +aa2rei +aarf4 +aar3g2 +aar3k4 +aar3t4 +1aas +aas1t +aa2th +aa2t3r +aat4s1 +2a3au +a1ä +a1b +2aba +ab1alt +ab2am +ab2ant +ab1au +ab2aut +ab1ä +ab2är +ab2äu +2abbat +2abbin +1abd +4a3be. +4a3bec +abe1e +ab1eic +abe3i4d +ab1eil +ab1ein +4ab2el +abe2la +abela4d +abe2le +abe4l3in +1abent +2aber +a2berd +a3beri +ab1er2k +ab1er2r +ab1er2z +4abes +abe2s1e +ab3esse +abes2t +ab1eß +2ab2et +2abew +1abf +1abg +3abga +1abh +2abi +4abil +ab1ins +ab1ir +3ab1it +1abk +ab1l +1a2bla +a4blag +a3blat +a4blau +1a2blä +ab4le. +3ab3lei +2ablet +ab3li +a2blin +ab4lit +2ablo +1a2blö +2ablu +abma3s +1abn +2a3bo +3a4bo. +ab2of +3a4bon +4abot +2abö +ab3r +a4brä +a2bre +2abro +ab4ros +2abrö +1absc +1ab3s2p +abs2t2 +1abtei +3abtr +2abu +a2bum +ab1ur +2abü +1abw +2aby +3abz +2a3ca +ac1c +a1cem +a1cen +a1cet +ach1a +a1chal +a3chari +ach3as +ach3au +2achb +a1che +a2ch1e2c +ach1ei +ach4ei. +a2chep +a4cherf +ach5erfa +a4ch3erh +a4ch3erl +a4cherö +a4ch3erw +2achf +2a1chi +a2chim +ach3l +2ach3m +ach3n +a1cho +a3cho. +ach1ob +a2cho2r +ach3ö +2ach3r +2achsc +achs4el +ach3s4i +ach3skr +achs4or +ach3su +a4cht +ach4tak +ach8tersp +ach6t5erw +ach4tin +ach2t1o +ach8traum +ach8träume. +ach8träumen. +ach6trit +ach4tum +a1chu +ach1u2f +ach3ü +2achv +4ach1w +a2chy +2a1ci +4ack. +ackmu4 +ackmus3 +ack2sp +acksta4 +2a1cl +a3co +acon4n +2acu +a1ç +a1d +2ad. +2ada. +4adab +a2dac +a2dad +ad2ag +adai4 +ad1ama +a2d1an +3adap +4a3d2a2r3 +2adat +a2d1au +a3dau. +1a2dä +ad1c +1add +2ade. +ade2al +a3dec +a3dee +adefi4 +2adeg +4aden +a3dena +ade1ra +4ades2 +ade3sp +ades4s +2adf +4adh +4adi +adi3en +adi3er. +adie4sc +3adj +2adli +4admu +ad2ob +1a2dop +2adp +2adq +2ad3rec +ad3rei +ad3run +2ads2 +ad3sz +2ad2t1 +adte2 +adt3h +1adv +2a1e1 +ae2b +a2ec +ae2d +ae2i +a2ek +a3el. +a2ela +a2ele +a2eli +a3els +ae2m +ae2o3 +ae2p +a3er. +3a2er2o +aes2a +ae4sc +ae2ta +a2ew +ae2x +2afa +af1ab +a2f1a2n +a3far +a2f1au4 +2afä +a2f1än +2afe +a2f1ec +a4fentl +a4f1ep +aff4a +af2f3l +af4flu +2afi +afi2e1i +afi6kanz +afi4kat +afi2t +2af3l +af1la +a1flu +2afo +a2f3oc +a2ford +2afra +af3rau +af3rä +af3re +2afro +af3rö +af4rü +af3s2a +af3sh +af2si +af2sp +af2t1a +af2tei +af2te2l +aft4erk +af2t1o +af2tö +aft3r +af2tra +af2t5re +af2tur +a2f3ur +2afü +a1g +2ag. +2aga +ag1a2b +ag1a2d +ag1am +ag1ar +a2g1au +agd1 +ag2del +ag2di +ag2dr +ag2du +4age. +age1i +agein4s +age4ler +ag2em +2agen. +age4neb +a4gentu +2ages +age4sam +age4s3i +age2s3p +ages5s +ages6sen +age4s3ti +3aggr +a2g1id +a2gim +2a2g1l +ag4lan +ag4las +a4glö +2agm +ag2n +ag4nat +a4gnä +ag4ne. +ag4nu +ag3rat +a2g3re +a2g3ri +ag4ro +2ags +ag3sah +ag4sam +ag3s4eid +ags8porta +ag2s1tr +2agt +ag2th +2agu +a2gund +2ah. +a1ha +ah2an +ah4at +a1hä +2a1he +ahe1in +a2h1er2h +ahe1u +a1h2i +ahin3 +ah2l3a2 +ah2l1ä +ah4l1ei +ah2lel +ahle4na +ah4l3erd +ah4l3erh +ahl1o2 +ah2lö +ahl3sz +ahme1i +ah3mu +ah4n3a +ah2nä +ah3nee +ahn3el +ah4nerd +ahner4e +ahner6le +ahner4n +ah2nin +ah2no +1a2hor +ah1os +a2h3ö +4ahr +ahr1a +ah3r2e +ahren6sc +ahre4s3 +ah3ri +ahrta2 +ahr2ti +ahr4tri +ahr4tro +ahr4tun +ah2ta +ah2te2l +ah2t1ex +ah2t5r +aht1s2 +a1hu +ah1w +a1hy +2ai. +ai3a4 +a1ia. +2aib +ai2bl +aid4s +aids1t +ai1e4 +ai3en1 +aif4 +ai1fr +ai3g4 +a3ik. +ai3ke +ai2lar +ail3d4 +ai2lei +ail3g +ai2lo +4ain +ain2a +a1ind +ai5n4e +ain3s +ains2p +3airb +ai2sa +a3isch. +ai5schw +ai3s2e +ais3sen +ais5st +ait4 +a3iv. +a3ivl +a3ivs +a1j +a2jat +ajekt4o +2ak. +2aka3b4 +a2ka3d2 +2akal +2a3kam +2akar +ak4at +aka4tak +1akaz +4akä +2akb +2akc +2akd +2a1ke +a2kef +a2k1em +a2k1ent +a2kes +a2keu +4a1ki +ak1ins +1akku +2ak3l +ak4li +a1kna +2ako +2a1kr +ak4ri +3akro3 +2aks +ak3sh +ak2t1a2b +ak4tag +ak3tan +2aktb +ak2tel +ak3ten +akt2er +2aktik +2aktis +2aktm +ak2tö +ak2t3r +ak3t4ri +2aktsi +2aktsp +2aktst +2aktw +a1ku +2akun +a2kup +2akur +4a3kü +1akz +3akze +a1la +2ala. +4alabo +al2abr +al1af +al1age +2alai +al1akr +al1am +al1ana +4aland +a2lang +al1anz +al1app +a3lar. +al3arc +a3lare +al2arm +2al3arr +a2lart +ala2s +al1asi +al1ass +ala2t1a +al4atm +alat3z +al1au +al3aug +a1lä +a2l1äm +al1än +al1äu +3albat +al2bär +alber4e +al4berh +al4b3er4w +al2b3l +al2boh +alb3ru +alb5st +al2dä +al4d3erl +al4d3ern +alde2s +ald3inn +al2dr +alds2 +2ale +4ale. +ale4ar +al1eb +ale2be +al1ec +a4l3ef +a2l1ei +a3l2eic +a4l3ein +a2l1el +5a2lema +alen1 +4a3len. +3alenc +alende4 +al3endr +a4l3ends +a2leng +al2enn +ale2p +al1epo +4aler. +a2l1erb +a2l1erf +a2l1erh +aler4kl +a2l3erl +al1erm +aler4mi +a2l1er4r +a2l1ert +3a4l3erwä +4ales +a2l1e4sk +a2less +a2l1eu +al3exi +alf4r +2alg. +3algi +al2gli +al3glo +1algo +3algor +2ali +al2imb +al1imm +ali4nal +al1ind +a2l1inq +al1ins +alken1 +al2klö +al2kne +1alkoh +alk3s +al2lab +alla3d +alla2m +al2lan +al2l1ap +al2l1a2r +al6later +al2lä +al3läu +al4lec +3allee +alle4gi +al4leh +al3lend +all3erk +al3les +alle3se +al2leu +al2lid +alli5er. +alli7ers. +al2lob +al2lo2c +al2lop +al2lo2s +al2lö2 +all3öse +al2luf +allu4s +al2lü4s +al2map +al3mas +al4m3ast +almo6de. +a2l1ob +3aloe +a2lof +4alog +alo2ga +alo2gr +al1ont +al1ort +a2l1ö +al2ös +3alp. +3alpe. +1alph +al2pho +alp4r +alrat2 +al3sak +al6schei +al3ses +al4sh +al3skl +al2stu +al2sum +al2t1ak +al2t1an +1altä +al4temu +al4t3er5f +al2teu +al2tin +alt1op +al2tö +al4t3rat +al2tre +al2t3ri +al2t3ro +alt4stü +2altu +a1lu +alu3b4 +al2u3f +alu3g +al1u2k +a2lum +al1umb +al1ur +a3lus +4aly +al2zar +al2zau +alz4erk +al2zw +2am. +am2a +ama3d2 +ama3g +2amah +a2malg +2a3m4an +a2m3ap +2amar +ama4sta +a2maz +2amä +4ame. +a2meb +2amel +am4e4n1 +amen6s5pr +ame3r2a +a2m1erf +a2meri +ame5r2u +a4mesh +a3met +2amf +am4ing +2amir +2amis +2amit +2amk +2aml +2amm. +am2ma2c +2ammal +amma2n +am2mar +am2mas +amma4sc +am2maß +am4ma4te +ammen8ge. +ammes3 +am2mid +ammi2e +am2min +am2mit +am4mo2d +am2mö +ammu2 +amm3unt +am4mus +am4mü +amni1 +a2mö +2ampe. +2ampen +am4pf +amp2f1a2 +ampf1o +2am2ple +2ampo +am3pr +4amsc +am4schl +am3sh +1amt. +am2t1a2 +am2t1ä +am2tei +amt3eig +am2tel +2amtem +am4t3ern +am2t1ex +am2tis +am2tit +am2to4 +am2tö +am2t3r +am2t1u +2amu +3a2mul +2ana. +2anab +ana3c +anadi1 +an2ag +2a3nak +an1alg +ana4lin +ana3ma +2anan +an4and +2anas +a5nat. +ana4th +a5n4atm +ana2tr +an3aug +1an1äs +1anb +2anbas +2anbu +an3ch +2and. +3an3d2ac +and3arm +and3ei +anden6ga +an4d3ent +and5erob +ande2s +an2d1ex +and4sas +and2so +and6spar +and6spas +and6s5paß +and2su +4andu2 +an2d1ur +2ane +4ane. +an3ec +a3nee +an2ei. +an3eif +3aneig +a4neis +3a2n1e4k +ane2mi +4anen +aner4fa +an2erh +a4nerke +4anern +a4nerz. +an4erze +an1eth +1anf +2anf. +2anfab +3anfä +an3fe +2anfi +an4fj +anf3le +4anfors +anf5rau +2anfs +an3f2u +4ang. +1angab +an2gan +an2g1ar +2ange. +1angeb +1angeh +an2g1ei +an4g3erf +an4g3er4w +an4g3erz +2angh +2angie +ang1l +an2gla +ang3n +ang1r +ang3ra +1an3gri +4angs. +angt4 +1anh +2a3n2i +ani3d +4anie +ani3els +ani5ers. +ani3g2 +ani3ke +3a4nim +a4n3ind +a4n3ins +ani2o +an3i4on +a4niso +anis2t +2anj +2ank. +an2kab +an2k1ak +an2kan +an2kei +2anken +ank5erfa +2anki +an2klö +an2klu +ank3no +an4k3opf +an2ko4r +ank1r +ank3ra +an4kras +ank3rä +an2kro +2anks2 +ank3se +2ankt +3ankü +1anl +2anlad +3anlag +anma3s2 +2anmo +1anmu +2ann. +1annah +an2nar +an3ne +an4nef +2anns +ann4s3p +2annt +2ano. +ano3b +an1od +2anof +2anog +anoi3 +a3nol +ano2la +1a2nom +a3nom. +a2n1or +2a3nos +2a1nö +2anpu +1anr +2anrö +an3s4ar +1an3s2ä +1ansc +an3skr +ans1pa +ans3pon +1anspr +1anst +an3s2z +2ant. +an2t3ar +anta4re +an3t2ä +1antá +3antei +an3tha +2antie +3antise +2anto +anton2 +3antr +ant3rin +1antw +2anu +anus3s +an4ut +a1nü +1anw +2anwi +an2zä +2anzb +2anzd +1anzei +anze2n +2anzes +2anzg +2anzh +an2zid +an2z1i4n +2anzk +2anzm +2anzr +2anzs +2anzt +1anzü +3anzün +2anzv +2anzw +an2zwa +an2zwi +2anzy +2ao +aof4 +ao3i4 +a1op +aopf4 +a1or +a1os3 +aost2 +a3ot. +aot4r +ao3t2s +2a1ö4 +a1p +4ap. +2apa +a2pe. +a3pel +a2pé +a2pf +ap2fa +1apfel +2apfes +a3pfl +a2pht +2api +2ap3l +ap4la +ap4lä +ap4lo +ap2n +a2pot +2apr +4apro +ap4ster +ap2sto +ap2str +ap3t2 +2a3pu +2ar. +a1ra +a3ra. +ar2ab +2ar3abb +ar3abf +ar3abt +ara3d2 +ar3adr +a2r3al +a3rale +a3ra3li +a3ralo +2aran +a2r1ang +a2r1anz +2arap +a2r3app +2arar +a3ras +a2r1au +a1rä +1arb +2arb. +2arba +ar2bak +ar2b3at +ar2bau +2arbef +ar4b3ein +2arbek +2arben +2arber +4arbi +2ar2bl +2arbo +2arb1r +ar2bre +2arbs2 +arb3se +arb3sk +arb3so +2arb3t4 +2arbu +1ar1c +2archl +2archr +ar2dau +arde2l +ar2dob +ar2dop +ar2d3r +ar2du +a2rea +are5aler +a2reb4 +aree2 +ar1eff +ar1ehr +ar1eid +a3reih +areim3 +a2rein +arein4b +arein4s +arein4t +a2rele +4arem +4a5ren. +a5reni +aren6sem +are3r2a +arer2e +a4r3erei +a2rerg +a2r1er3h +a2reri +a2rerk +a2rerl +ar2erw +are3u +arf1r +arf3ra +arf2sp +4arg. +ar3gan +ar2gl +ar2gn +2arg4o +ar3g4r +2arh +2ari +ar2ia +a2rid +ari3e2n +ari3erd +ari3erg +ari5ers. +ar3inf +arin3it +ar1int +a3rio +ar2ir +ar4is +ari2su +a3riu +ar2kal +ar2k1ar +ark3aue +ar2kil +2ark3l +ar4klag +ar2kle +ar2klo +ark4lö +ar2kor +ark3s2a +ark2se +ark3she +arku2 +ar2les +ar3mad +ar2mau +ar3m2ä +3armee +ar2m1eg +ar2m1ei +ar4merk +arm2or +ar2mum +4armü +ar2nan +arn2el +ar3ni +ar4nin +a1ro +4aroc +ar1o2d +ar1of +aro2fe +a3rol +aro3m +aron2 +a2r1op +a2ror +a2r1ö +2arp +arp3fe +2arr +ar2r3ad +ar2r3as +ar2rek +arre4n1 +ar2r3or +2arsa +ar3s2h +2ar3s2i +ar3sse +ar2tau +2artb +ar3t2e +2artei +artel6li6 +arter6la +ar2the +art3ho +art2i +2arto +art3r +art4res +2arts +art3ske +2artuc +2aru +a2r1uh +ar1um +a3rumm +a2rü +2arv +arwa2 +2ary +ar2zau +ar2zä +2arze +2arzi +ar2zö +1arzt +arz2t3r +2arzu +ar2z1w +2asa +a4s3aa +as2ad +a4s3af +as2al +as1am +as3art +asa2s2 +asa3sse +as3at +asau4f +a2s3aug +asau2s1 +as3ät +a2sca +a4schec +a4schef +a4sch3ei +a6scherg +as4chi +a2schm +2ascht +a3schu +a4schum +4a3se +a4seb +a4sec +a4s1ef +as1eie +as1emi +a5sen. +ase4na +ase4n3o +asens2 +as1ent +as2er +a4s3erke +as4es +ase2t +as1eta +a4sex +a4s3ha +as2hi +as3hir +a2s3i2k +2asim +asin2g +as1inn +2asis +a4s3l +a4sm +a4sn +a1so +as3ob +as1o2f +a3sol +a3som +aso2p +as1or +a4soz +as1p +as3pe +aspek6to +a4spel +as4pen +a4s2ph +as2pi +as4pin +as3pio +a4spir +a4spl +as3sa +ass2ab +ass6aus. +ass2e +ass3ein +as3sel +asse3le +as3ser +asserma6 +a4ss2i +as3sin +as3ski +as3so +as2spo +as2spr +as4st +as5sta +as5stei +as5sti +as5str +as5stu +2asta +a4stab +a3stä +a4s1tec +as2tee +ast2el +a4stemp +a4s3tep +ast2er +a4st3ese +as2tex +a4s2th +a2stoc +ast3orc +as4trau +a2st3re +ast4ren +a3stro +a4strol +ast5roll +a4s1tub +a4stuf +a2stum +2a1su +as2ur +a3sus +a4sw +aswa2s +2asy. +3a4syl +as3z +aße4 +aß2en3 +a2ß1er +aß2th +2a1t +4ata +at1abe +at1abr +at2a1f +a3t2a3g +a3tah +at1akt +ata3l +a3tam +at3ank +at1apf +at2asc +at3att +a2t1au +a3tau. +at1än +4atb +at2c +4ate. +a2teb +ateien6d +at1eig +3a2teli +a3tell +3atemg +at2en +ate4na +atens4 +a2tep +ate3r4al +ate3ran +atern2 +ate2ru +4ates +at2eu +a2tew +at2ex +at3hag +a3t4heb +a2th3in +3athl +a4thr +at2hu +4a3ti +ati3ka +ati4kab +ati6k5erw +a4tinf +at2is +ati2sa +ati2se +atis3s +3atla +4atli +4atlo +3atm +4atma +4atmä +4atmus +ato4man +ato4men +3atomk +ato2mo +at1ort +a3tra. +atra2t +a2trau +a2t3rä +at3re +4atri +at3rin +a2t3rom +a3t4ron +at3rot +at3rü +at2sa +at4schn +at2se +at2si +ats1o +ats1p +ats3tät +at3ta +3attac +at4tad +at2ta2g +at4t1ak +at2ta2l +at4tang +at4tar +at4tau +at2tä +4atte. +at2tec +at2tei +at3t2el +at4temp +at5ter +attes2 +at3thä +4atto +at2t3rä +att3s2 +at3t2u +at2ty2 +atu2n +atze4l +atz3ela +atz3elt +at2z1er +a3tzere +at2z1i +at2zo +atz3t4 +at2z1w +a2u +2au. +2au1a2 +2aub +au2bab +au2ban +au2bau +au2bei +aube4n +au2beu +au2blä +au2bli +au2blo +au2blu +aub2si +aubu4s +4auc +aude4r3i +au2dr +2aue +aue2b +au2ere +aue3rei +au5erein +auer3ö +au5erst. +au3ert +au2fa +auf1an +aufas2 +3aufber +2aufe. +2aufeh +4aufen. +3aufent +auf1er +au4ferk +au2feu +auff4 +auf3ind +1aufla +1aufn +2aufo +auf3ski +auf3t4 +2auft. +5aufzeic +3aufzug +1aufzü +2aug +aug2ar +4augeb +4augeh +4augel +aug2er +4augl +4augr +au3gu +2auh +au3ha +auh1u +2au1i +au3in +au2is +2auj +auk3t +aule2s +aul4les +au3lü +4aum +au2mal +au4m3ent +au2m1e2r1 +aum3eri +au2mid +au2mil +aum1o +au2mor +aum3p2 +aum3s2 +au4mun +4aun +au3n2a +aun2e +au4nei +au2nio +au2no +au3nu +a4unz +2aup2 +aup4ter +2aur2 +au3ra +au1rh +au4sag +au2s1ah +ausan8ne. +au2sau +2ausc +au6schmi +1ausd +2ause. +au4s1eh +2ausen +au4s3erb +au4s3erf +aus3erk +aus3erp +au4serw +1ausf +1ausg +au2sin +au4sis +1ausl +au2so +aus1or +au2spr +1ausr +1auss2 +au3sse +aus4se. +au8ssende +aus4ser +aus4ses +au2st2a +aus3tau +2auste +au4stec +aus3tie +aust2o +au2stö +aus3tri +3ausü +1ausw +1ausz +auße2 +au3ßen +a4ut +au2t1äu +2autb +au2t1e2l +auten4g +au4t3erh +2autg +1auto +au2trö +2auts2 +2auu +2auv +auve4 +2auw +2aux +2auz +au3ze +auz2w +2a1ü +a1v +av2a +a3vang +ava3t2 +avener4 +2avi +a2vr +av2s +2a1w +awi3e +a1x +ax2am +a2xans +ax2e +a3xid +a2xio +axi2s +ay1 +2a1ya +ay2al +ay2as +a1yeu +ayma2 +aysi1 +ay3t +ay2u +2a1z +a3z4a +aza3d +3a4zal +az2i +az2o3 +a3z2u +az2zen +az2z1in +az2zw +ä1a +1ää +ä1b +ä2b3l +äb2s +ä1ce +ä1che +äche1e +äche4n +ächenma5 +ächenmas8 +ä1chi +äch3l +ä2chr +äch4s3a +äch2s1o +äch2sp +ächt4e +ä1chu +ä1d +ä2da +ä2d1ia +ä2dr +äd2s +äd3te +2ä1e +äe2x +äfe4n +äf2f3l +äf3l +äf3r +äf4ro +äf2s +äft2 +äft4s +ä1g +ä2g1a +1ä2gä +ägd2 +ä5ge +äge1i +äge2r3a +ä2g3l +äg2n +ä2g3r +äg4ra +äg2s +äg3sc +äg3sta +äg3str +1ä2gy +äh1a +2ä1he +äh1ein +äher8gebn +äher3t +ä1hi +äh1in +ähl1a +äh3l2e +äh4l3e4be +äh5ler +4ähm +äh3na +äh3ne +1ähnl +2ähr +äh2rel +äh3ri +2äh2s +2äht +ä1hu +äh1w +2äi +ä1im +ä1is. +ä3isch. +ä1isk +ä1j +ä1k +äka2la +äk3l +ä2kle +äk4li +ä2k3r +ä1la +älbe2 +äl2bl +älk3 +älks2 +äl2l1a +äl2p3 +äl4schl +ä1lu +2äma +ämer2s +ämi3en +2äml +äm2ma4 +ämmas2 +ämoni3e +2ämp +ämp7f4e +äm2s +ämt2e +2än. +änd2e +än2dr +2än2e +äne2n1 +2än2f3 +änft2 +2än3g2e +änge4ra +2än2g3l +än2gr +ängs2 +äng3se +2ä3n2i +än3k2e +än2k3l +än2kr +än3n4e4 +2äns +än4s1a +än2s1c +äns2e +änte3le +2änz +ä1on +äo3s2 +ä1pa +1äpfel +äp2pl +äp2pr +äp2s1c +1äq +ä2r3a4 +är4af +är1ä +är2b3le +är1c +2ärd +ärde4s +2äre +ä2r1ei +ä2r1e2l +är2em +äre2n +ä2rene +är2er +är2es +är3ge +ä2rind +är1int +är3ke +ärm3arm +ärme1e +ärm3ent +är1ob +är1of +ä1rö +är3re +ärse2 +är2seb +är4seh +ärs1er +är2si +är3spu +2ärt +ärt4e +är2th +ärt4s1 +ä2rü +1ärz +ärz3te +är2zu +är2zw +ä1s +äs4c +2ä3s2e +äse3g +äse1i4 +äse5ref +äser4ei +äse4ren +äser2i +äse3t +ä5si +ä3s2kr +ä2s1p +ä3s2s +2äs4s1c +äss2e +äss5erkr +äss5ersa +äss3erw +ä5sses +äs4sh +äs4s1t +äs4t2e +1ästh +ä2str +ä1ß +2äßc +äß1erk +äß1ers +ä2t3a4 +2ä3te +äte3a +äte1e +äte1i +äte3l2 +äte2n +äteo2 +äte3se +ä2th +ä1ti +ä1to +ät1ob +ät3r +ät2sa +äts3au +ät2sä +ät4schl +ät4schr +ät2s1i2 +äts3l +äts1or +äts1p +ät4s1t +äts3te +ät2tei +ätte4n +ät2tr +ä1tu +ätze3l +ät2zw +äu2b3l +äu2br +äu1c +äu3d +äude3 +äuder2 +äu3el +2ä2uf +1äug +äu4g3l +2äul +2äum +äu2ma +äum3p +äumpf4 +äum2s1 +2ä2un +äun2e +äu3nu +2äu3r2 +äure1 +äu1s +2ä3us. +2äusc +äu4schi +äu4schm +äu6schü +äu3s2e +äuse1i +ä3usg +ä3usk +ä3usn +äu2s1p +äu3s2s +äuss1c +1äuß +äut2e +äu2tr +ä1v +1äx +ä1z +â1t +á1n +5ba. +b3a2ba +2babf +2babg +ba2bl +ba2br +2b1abs +bach7t4e +back3er +back3s2 +ba3d2e +bade1i +2b1adel +2b1adl +2b1adm +b1a2dr +ba2du +2b1af +bah6nene +bais2 +b2ak +ba2ka +ba2k1er +ba2k1i +bak1l +bak3r +ba2kra +ba2kre +ba2lab +ba2l1ak +ba3lal +ba2lau +ba4l3erk +balk4a +balke4 +bal4lan +balle4b +bal4l3ei +baller6e +bal6ler6g +ball6erk +bal4li4g +bal4lo4k +ballö3s +bal3ti +2b1am +b2ama +ba2me +ban2a +3b2and +band1a +ban4dal +ban4dan +ban4dar +ban6deng +ban2dr +ba3n2e +2banf +b1ang +ban3gl +ban4k1a +banker4 +ban2kl +ban2kn +ban2kr +ban2ku +2banl +b1anna +ban2o +2b1ans +b1an3t +2banw +b1anz +ba2r3ab +ba2rad +bar3ast +ba2r3at +bar3de +ba2rei +ba3r2en +barer5ei +bar3n +b2aro +3bars +b1arz +bar3zw +3bas +ba3sa +ba2sc +bas2i +bas4sa +bas4sei +bas6st +bas4t +ba2str +ba2ß1 +ba4t3ent +bat2o +3bau. +bau3b +bauer4l +bauer4s +bau3fa +bau1fl +bau1fr +bau3g2 +b2auk +bau3r +bau3s2k +bau3sta +b1a2x +ba1yo +3b2äc +bä1ch +3b2äd +2b1äh +b2äl +2bärz +b2ä4s3 +2bäug +4b1b +bbe4n +bbe4p +b4be2se +bb3ler +bb2lö +b3brec +b3bru +bbru2c +bb2s +bbu1 +2b1c +bch2 +2b5d4 +bdome4 +1be. +3bea +be3an +be3ar +3beb +b1ebb +1bec +be1ch +2becht +2b1e2del +bedi4 +be1e2h +bee2l +be1ela +bee4rei +be1erl +be1ert +be1eta +bef4 +2b1eff +be3g2 +begas1 +be2he. +beh5ri +bei3b +2b1eier +bei1f4 +bei4ge. +bei3k4 +bei3l2a +2b1eime +be1ind +be1inh +bein6hal +bein4hi +bei3s2 +bei5st +beit2s +3bek +3bel +be3lag +be3las +be3lec +4be2lek +be2l1en +bel3ere +be2let +bel3f +be3l2i +beli4e +bel3la +belle4n3 +bel3li +be2l3om +be2löf +bel3sz +bel3t +bel4un +1bem4 +2b1emp +2bemul +1ben +3ben. +be5nabe +ben3ar +be4nas +be4nat +benä4 +bend3s2 +b2ene +be3nei +be4n3end +be4ners +ben2eu +3beng +be4nis +ben3n +5benp +b2ens +ben4s3pa +ben4spr +benst4 +3bensv +3bensz +2b1entb +2bentd +4benteu +2bentf +ben3th +ben6thei +bent4r +2b1ents +2b3entw +be2nu +ben3un +ben3z2 +be1o +2b1epi +be1ra +be2r3am +be2ran +ber3a4s +berb2 +ber3d +b4ere +be2re2b +ber2ec +ber4ei. +be4r3eiw +be4rene +ber4erg +ber4erw +bere4sc +berf4 +3berg. +ber4g3af +ber4gal +berg3a4s +ber4hab +ber4in. +be5r6inne +berin4s +ber3iss +ber3kr +bermas4 +berma7sse +ber3n2a +b1ernt +be2rö4 +3bers. +ber5se +ber3st4a +ber3t2a +bert2e +bert2i +b4eru +ber3ze +ber2zö +3b2es +be3sa +bes4abb +bes2am +be4sap +be4sar +bes2au +be2s1er +be2s1id +be5s4lo +bes2po +bes3sa +bess4e +b3esst. +bes3sz +beste2 +be6stein +bester4 +be6sterh +best2i +bes3tin +be4s3tol +be4sto4r +best4r +be4strä +be4s3tur +be3s2ze +3bet +be3tam +bet2to +be1un +be1ur +3bev +3b2ew +2b3e2x +3b2ez +2b5f4 +bfal2 +bflö4 +bflös3 +2b1g4 +b5ga +bgas1 +bga4st +bge3 +bgel2e +bge5n +bges2 +2b1h2 +b5hä +1bi +3bib2 +bibe2 +biber1 +bi2c +bieres4 +bie4str +biet4s +3bietu +bik2a +bi2ke. +bi2kes +bi2k3re +3bil +bi3la +bi4lans +bi4lau +bil4deb +bi2lei +4billu +bi2lu +2bimp +2b1inb +3bin2e +b1inf +2b1inh +bi2nok +2b1int +2b1inv +bi2o3 +biri1 +3bis +bis2a +b1iso +bi2sp +bis4s1c +bist4 +bi3sta +bi2s1to +bi2stu +bi2stü +3b2it. +b2ita +bit2an +b2ite +bit2ta2 +bi2tu +bi3tum +bi3tus +bi3z2 +4b1j +bjek4to +2b5k4 +bl4 +2bl. +bla3b4 +2b3lac +b3lad +b5lag +b2lanc +b3late +b2latt +b4lau. +b3laus +2b3law +2b1län +b2läse +3blät +b2le +3ble2a +b3leb +3blec +b3lee +b3leg +2bleh +2b3leid +2bleih +b3lein +blei3s +2bleit +ble3l +2b3lenk +b3lese +2blesu +ble3sz +b4let +b3leu +2blich +3blick +b2lie +2blief +2blig +bling4 +b2lis +2blis. +b2lit +3blitz +b2lo +3b4loc +b3los2 +blo3sse +3b4lum +2blun +b2lus +3blut +blut1o +3blü +2b1m +bmas2 +4b5n2 +bnas4 +bni2 +bnis1 +bo4a +bo5as +b1o2b +bo3ben +bob3r +bo1ch2 +bo3d2 +boe1 +bo2e3i +2b1of +bo3fe +boh3re +boh4rei +boh2u +bo1is +bo2lan +bo2lau +bol3le +5bon. +bon2an +bon2da +bon2d1e +bo2ne +2b1onk +5bons +boo4l +boo2ti +b1op +bo1r2an +bo2r3as +bo4rä +bor2da +bor2d3r +bo2rei +bo4rig +b1ort +bor4ter +bor6t5rat +bo4ruh +bo2sc +bo3se +bo4s3p +3bot +bote3n4e +bo3th +bot2st +bot3t +3b2ox +bo2xo +bö2b3 +2böf +2b1ö4l +2b1p4 +bpa2g +2b1q +b2r4 +2br. +b4ra. +2b3rad +2b4rah +b4ra3k +bra4ss +brast4 +2b3rat. +bra4t3er4 +2b3ratg +3brä +4bräd +brä4u +2bre. +6b5rechte +2b3red +2b3ref +2breg +b3reif +2b3rek +breli1 +3b4rem +2b3rent +2breo +2b3rep +b4rer +bret6t5en +bri2da +brie4fa +2b3riem +b4rien +bri2er +b3ries +2brigk +b4rina +2b3rind +b4rio +b4risc +2briß +b3ritt +2b3roh +2b3rol +b4ron +2b3rost +bro2tr +brot3t4 +2b3rou +3b4rö +b4ruc +2bruf +b4rum +2b3rund +bru4s +brust3 +bru2th +3brü +4b3rüb +brü4ss +2b1s +b2sad +bs1amb +b4samt +bsas2 +bsa3sse +bsau2r +bs1än +b4s3är +b3säu +b5sc +bsch2a +b6schan +b6schef +b6sco +bs2cu +b3se. +bs1e2b +b3sel. +bse2n1 +b3sen. +b2s1ent +bs1er +bs3e4r3in +b3ses +b3set +b2sim +bsi2t +b4ski +bs3ko +bs2ku +b2s1of +b3s2oh +b4sop +bso2r +b2sö +b3s2pi +bs2pl +bs2pu +bs3s2 +bst1a2b +bs2t1ak +bst3ank +bs2t1a4s +bs2tau +b3stä +bs1tät +bst1er +b4stern +bst3h +b3stic +bst3ink +b2stip +b3sto +b4stob +b4stod +b4stor +b3stö +b3stra +b2s1trä +b4s3treu +bst3ro +bs2tu +b3stü +b4stüb +bs1ums +b2s1un +b3sz +bs2zep +bs2zi +4b1t +bta4st3r +b5te +b2t3h +bti2s +bt4r +btran2 +bts2 +btü1 +bu4chec +bucher6 +bu6ch5ers +bu3ches +bu2chi +buch3s4p +bu2e3 +bu2f +bull3a +2bumf +2b3umk +2buml +2b3umr +bun4d3er +bunde4s +b1une +b3un3gn +2b1unh +bur1c +b2urg +burg1a +bur4gan +bur4gar +bur4gin +bur2gr +bu3r2i +2burn +b3ursa +burt4s +bu2sa +bu2sc +bus3cha +bu3sche +bu6schei +busch3w +bu2si +bu2s1p +bu4sses +bu6s5term +bu2s1tr +bu2su +bus1un +2büb +bü1c +bügel3e +bü3s4 +2b1v +4b5w +3b2y1 +by3p2 +bys2 +2b1z4 +b5ze +bzeit1 +bzu1 +1c2a +cab4 +ca3bl +ca2c +ca2e3 +ca3g2 +ca1h +cal2a +cal2f3 +cal3t +2can +cana3 +ca2pe +car3b +car3n +carri1 +ca3s2a3 +ca3t2h +ca1y2 +cä3 +cäs2 +c1b +2cc +c1ce +c1ch2 +cchi1 +c2d2 +c3do +2cec +1ced +ce2dr +ce1e +2cef +ce1i +ce3in +2cek +3cels +cen3a +ce3nu +ceo2 +1ce1r +cere1 +cere3u +ce3r2i +ce3s4h +cet1am +ce1u +1cé +c1f +c1g +c2h +4ch. +2chab +ch3a2b3i +2chac +2ch1a2g +2ch1ak +3chanc +chan3f +ch1ang +4chanl +2chanz +1chao +2char. +1chara +3chard +3charta +cha2sc +chasi1 +1chato +2chatt +2chatu +ch5austr +chau3t +ch1äh +ch1ärm +ch1äs +1châ +2chb +6chc +2chd +che3b +ch3e4ben +ch3echt +ch1edi +1chef +3chef. +che4fer +3chefs +2chei +ch1eim +4chelem +che4ler +1chemi +3chemik +2chemp +che4neb +che2no +4chents +4chentw +cher3a +4ch3erbs +6chergeb +4cherke +cher6zie +ch3es2s +2ch1e2ta +2ch3e4x +1ché +2chf +2chg +2chh +1chia +2chic +chi3na +4chind +3chines +2chinf +2chinh +2ch1ins +2ch1int +2ch1inv +1chip. +1chiru +2chiso +2chj +2chk +2chl4 +ch2le +chle2i +ch2lu +4ch2m4 +2chn4 +chner8ei. +ch2neu +c4ho +2chob +cho2f +ch1off +chof2s +ch1oh +cho3l2a +ch1orc +ch1ori +ch2os +ch3öl +2chön +3chör +2chp +ch2r4 +2chra +ch3rad +chra3g +2chre +chre3s +ch3rh +2chrit +3chromo +3chron +4chs +ch4stal +2cht +ch2tru +2chuf +2chuh +2ch1unf +2chunm +2chunt +2chur +ch1urs +2chut +2chü +2chv +2chw +1chy +2chz +ci2ak +ci1c +ci1es +cill2 +ci2na2 +c1int +ci2s1 +cisch2 +1cit +c1j +4c2k +c4k1a +cka2b +ck2ad +ck2ag +cka2m +cka4r1 +ck1ä +ck1eh +ck1ei +cke4na +cken6sem +cke2ra +ck2ere +ck3er4hö +ckerk4 +ck2ern +cke2ro +ck1err +cket2t +ck1id +ck1in +ck4is +ck3l +ck3n +ck1o2 +ck3ot +ck3ö2 +ck3r +cks2al +ck3sc +ck4spen +ck3te +ckt2i +ck1uh +ck1um3 +ck1up +c2l2 +c4le +cle4a +clet2 +clin2g +cli2p1 +clip3a +clo1c +1clu +clu4b +c2m2 +c3me +c3mu +1c2o +co1ch +co2d2 +co4de. +co3di +cof3f2 +coi2 +co1it +co2ke +co3la1 +co2leu +co5l2o +com4te. +comtes4 +con2ne +co2pe +co1ra +cor2da +co4re +cor3t +cos4 +co2te +coti2 +2cp +c1q +1c2r2 +cra4s +c3rä +3cre2 +4cree +cre4mes +cros4 +cry2 +2c1s2 +cs4f +c2si +cs3so +4c1t +cti4 +ctio2 +ction5 +ctur6 +1c2u +2cua +cu2e +cu2p3 +cussi4 +c1w +3cy +c1z +3da. +da1a +2d1ab +d3a2bak +d2abä +d2abe +d3a2ben +d3a2bi +d3a4bo +dab4ra +da2bri +da3brie +d2ab4rü +d1ac +d2ac. +dach3a +da2cho +4d3achse +d1ad +da2de +dad4r +d1af +2daff +dafo4n +d1ag +dagi4o +dag2o +dah3l +da1h2o +dai2 +dail5 +da1in +2d1air +da1is +da2kro +dal2a +2d1a2lar +dal3b4 +4d1all +da3lö +2d1alp +d1al3t2 +2dalte +da1lü +3dam +d1amma +4d1ammä +damo3 +d2amp +damp7f8erf +4d1amt +3d2an. +d1ana +da2nan +da4nat +2danb +dan4ce. +d1and2 +2danda +d2andy +3dane +4d3anei +2danf +d1ang +2danh +d2ank +dan2kl +dan2k1o +dan2kr +2danna +d1a2no +2d1ans +2danw +d2anz. +2danzi +2danzü +2d1ap +d2aph +da2por +4dapp +2daq +da2r1a +2darb2 +2d3arc +dar2da +dar2d1e +dare2 +daren1 +dar3g +3darl +dar2m1a +dar2m1i +dar4mu +da2r3o +3dars4 +2d1art +dar2th +dar2tr +da2ru +d1arz +das2 +da3sh +d1asp +das3s +d1asy +dat2e2 +da3tei +date4n +4d3atl +4datm +da2tom +dat2st +2d3atta +3daub +2daud +dau3e2 +dauer3e +2d3au2f +2d3aug +2dauk +da3unt +2d1aus +3daw +d1ax +3däc +2d1äg +2d1äh +2d1ämt +2d1änd +2d1äng +2d1äp +2däq +2därz +2d1ä2u +dä3us +2däx +2d1b4 +dbe2e +dbu2c +dbu3s +2dc +d3ch +4d1d2 +d3da +d3dä +d3de +d3dh +d5do +1de +dea2d +de3alo +de3ar +de3a2t +d2eb4 +3debü +de1ch +deco3 +de2del +de2dit +2de3e4 +de2fa. +2d1eff +def4l +deg2 +de3gl +deh2a +dehe2 +3dehn +2d1ehr +d1ei +3d2eic +2deid +de3i4den +4deie +2deig +de3il +3d2eim +4deime +4deinb +dein2d +de3inse +dein6sta +4deinw +2deise +d4e1ism +dei2sp +2dekz +de2l1ac +del4ade +de3lak +de4l3aug +del3änd +del3b2 +del1ec +delei4g +de3lein +2delek +2delem +de2len +deler2 +deler4r +2delf. +2delfm +3delik +del4lan +del4lar +dell3au +del2l1ä +dell3eb +del4lei +del4ler +del2lö2 +de2l1ob +del2se +del2so +del2s1p +del3t +dem2ar +2d1emb +dement4 +de6mentg +dem5ents +de3min +2d1emot +2d1emp +d2en. +den2am +de2n1e2d +de4n3end +4denerg +de3n2es +4d3en4ge. +de2ni +denk3li +de2nos +dens4am +den6s5cho +4den4sem +den6sere +den6s5tau +2dentd +den3te +4dentf +2d1entg +den3th +2dentn +2dentw +2dentz +den6zers +de2ob +2deol +de1on +depi4so +dep4l +2depoc +dep5t +d4er. +dera2b +der3af +dera2n +de3rand +de2r3ap +de1ras +de4r3asi +der2bl +4d1erbs +2derdb +de2re2b +de4reck +de3reie +de4r3ei4s +d4eren +de4r3end +de3r4erb +de3r4erf +derer3n +der3ero +derer4t +de2r1eu +derf4 +d4erfl +d2erhü +derin4f +de6rinnu +derin8teg +der3k2 +4derklä +d4erlan +d2erm +de1ro +de2rop +derö4 +der3r +derst2 +der3sta +dert7ende. +dert4ra +6dertrag +der8trage +3de3ru +de4ruh +de4rum +2d1erz. +2d1erzv +d2es. +de2sa +de4s1a2g +des1ah +de4s1am +des3an +de2s1än +de2seb +de4s1e2h +de2sei +des3eil +2d1esel +des3elt +de3sem +des4end +desen3e +de3sens +des3erm +de2set +de4s1in +3desk +des1o +de2sor +de2s1p +de3spe +dess2 +des3se +des5st +de6st5alt +de6stant +de8steige +de8steins +des4tex +de4stit +de6st5rat +de4stre +de2su +des1un +3desw +de3ta +deten4t +de2thi +2d3etw +2d1eul +deum3 +de1un +de1url +de3us +2d1e2vid +devil4 +de2xer +de2xis +2d1f6 +2d1g2 +dgas3tr +d2ge. +dge3r +dger2e +dge3s +d2gesh +dge2t3a +dge4t1e +2d1h2 +4dho +d3hu +1di +di2a +di3ar +dia3s +diat4 +di4ath +dib4 +3dic +di1ce +di3chl +dicht6er +4d3i2co +d2ida +2d1ide +2didy +di2e +di3e4d +di3enb +di3end +die4neb +diener6l +di3e2ni +dienst5r +dien3z +di3ers. +dies3c +di3e2th +3dif +3dig +dige4s +dig4n +dik2a +dil2s1 +2d1imb +2dimp +din4a +2d1ind +di3n2e +2d1inf +3ding +2d1inh +2d1in1it +2d1inj +2d1ins +2d3int +2d1inv +di2o3b +dio4n3i +dion5s2 +di3ora +dio5s2 +di2osk +di1p4 +di3pt +d1i2ra +di4re. +di2ren +di2rin +di2ris +2d1irl +2d1irr +di4s1a2 +2diso +di2sp +di3s4per +2d1isr +dist2 +distel3 +di2s1to +di4s3tra +di4sz +di2ta +dite1c +di4t3erl +di4t3erm +di4t3ers +di2tin +di2tob +di2t3r +dit3s +di2t1u +di5v2 +diz2 +2d1j +2d1k4 +4d1l2 +dlap4 +d3le +dle2ra +dli4f +dl3m +dl3s +2d3m2 +4d3n2 +d5ne +dni2 +dnis1 +dni3v +do5a +d1ob +3d2oba +dob4l +do1chi +d1of +do2fe +2d1oh +doll2 +d3o2ly +do2mal +do2mar +domen1 +do4ming +do2mu +don2a +do5nan +doni1 +2dope +2d1opf +do1r4a +2d1orc +2d1ord +dor2f1a +dor2fä +dor2f1i +dor2fl +dor2fo +dor2fr +dor2f3u +2d1org +dori1 +d2orn +2dort +dor4ter +dor2tr +d2os. +dose4 +do5s2k +2dosm +do2st1 +dost3a +do3ta +do2t3o +do2tre +do3un +dow2s +dox2 +d1ö +dö2d +dö2f +4dö4l3 +dölla3 +d2ön +3d2ör +dö2s1c +2d3p2 +dpass3 +dpo4st +2d1q +d2r4 +3d4ra. +3d4rab +2d3rad +2drahm +2d3rak +3d4ral +d3ramp +d3rand +dran3k +dra4s3s +2d3rast +2draub +2d3rauc +d4rauf +2draum +2draup +2dräd +d4räh +2d3rät +2d3räu +4dre. +2d3rea +d4rea. +d4reas +3d4reck +2d3ref +2dreg +3d4reh +dre2ha +2d3reic +3d4reie +d4reiv +d4rej +2drek +dreli1 +4drem +4d3ren +4d3rep +4d3rer +4dres. +d4resc +2drese +dres6sei +d4rew +2d3rez +2d3rh +d3ri +3d4ri. +3d4ria +d4rib +2d5ric +d4rid +d4rie +d5rieg +3drif +4driff +d4rift +d4rik +d4ril +d4rin. +2d5rind +2drip +3d4risc +2drisi +2driss +2driß +3d4rit +4dritu +2d3rob +d3roc +d3rod +d4rog +2drohr +3d4rohu +d4roi +2d3roll +2d3rose +d4ross +2d3rost +2d3rot +2d3rou +2d3rov +d3row +drö2sc +d5rub +3d4ruc +2d3rud +2d3ruh +4d5rut +drü1b +3d4rüs +2d1s +ds3ab +d2s1alk +d4s1amt +d2san +ds3ane +ds3assi +dsau2 +d2saut +ds1än +ds2äu +4dsb +d4schef +d4schin +dsch4r +d3s2co +d2scr +d2s1e2b +dse2e +d2s1ef +ds1eh +d4sehe +ds4eign +d2sein +d2s1emb +dsen3er +d2s1eng +d2s1ent +d2s1erf +d2serh +d2s1erk +ds1err +d2s1ers +d2s1ert +d2serz +dse2t +d2s1eta +d2s1ev +d2sex +d3sha2 +ds2hak +d4shal +d3sho +d4shor +d2sid +d2s1im +d3s2inf +d3s2kal +d3s2kel +4dsl +d4sli +d3soh +d2sop +dso2r +ds1ori +d2sö +ds3part +ds1pa4s3 +d2s1pat +d2spä +d2s1pec +ds2pen +d4speri +d2s3ph +d3s2pi +ds2por +d6sporto +d3spri +d2spro +ds2pu +dss2 +dst2 +d4stabe +d2stas +ds3tauf +d4s3täti +d4stea +d4stele +ds2til +d2s1tis +d4stoch +d2stod +dstras4 +d4stren +d3s2tro +ds1ums +d2sun +ds2zen +2d1t +dta2be +d3t2ac +dtach3 +dta2d +d3t2ag +dtam3m +dta2n +d3t2as +d3tea +d2th +d4thei +dt3hi +dt3ho +dt4hy +d3to2 +d4to4b +dt2op +d3tö +dt3r +dtran2 +dt1s2 +dt3sa +dt5st +dtt4 +dt2un +d3t2ur +d3ty +1du +du1alv +du1ar +dub3l +du2bli +du1ce +du2f +2d1ufe +duf4ter +duf2to +duf2tr +2d1uh +du1i +du2kr +du4l3art +dult4 +2d1umb +2dumd +2d1u2m1e +2dumf +2dumg +4d3umk +2duml +d2ump +2dumr +2d1ums +d2ums. +2d1umv +du2n +2d3un3d +dund2a +dun4de +2d1unf +2d1ungl +2d1uni +dun3ke +dun2kl +2dunr +2dunsi +dun4st3r +2dunt +2dunw +2d3unz +du1os +dur2c +durch3 +2d1urk +2d1url +2d1urn +2d1ursa +2d1urt +du4schn +du4schr +du4sch3w +dus2t +2düb +d3über +2d1v2 +4d1w +dwa2 +dwa4r +dwe2s +dwest1 +1d2y +4dyl +3dyn +dys1 +dy2sp +4d3z2 +2e1a +e3ab +ea2be +e4abi +ea2b3l +ea4bo +ea4br +eadli4 +ea2dr +ea2g +ea3ga2 +ea3g4l +eakt2 +e2akta +e3akto +ea2la +e3alei +e4alem +ea4l3ent +ealer2 +e3a4lerg +e3alex +e3a2lin +eal5le +eal3lö +eallö3s +e2alo +e2alti2 +eal3tr +ea2l3u2 +eam3 +e2am4e +eam1o +eams2 +eamt2 +ea4na +ean3a2r +e3anf +e2ano +e3ar. +ea2ra +e2are +e4are. +ea2r1ei +ea4rene +e4arer +e4ares +ea2ro +e3arz +e3a4sc +easin4 +ea2sp +eas5s +eate2 +eater1 +e3ath +eat3s +e3at3t4 +eatu3 +e3aue +e3auf +eau2fe +e4aufo +eau3g +eau3n +eaus3s +e2av +e3ä4 +e1b +2eba +e3bak +eba2p +e3bän +2ebea +2ebec +2ebed +ebe1er +2ebeg +eb2el +ebe4ler +ebe2lo +ebenen3 +2e3ber +ebe4ras +ebert4 +4ebes +ebese2 +ebe4s3eh +2ebet +ebet4s +2ebew +2ebh +2ebi +2ebl +eb2laß +e3blä +eb3ler +eb4leu +e3blie +eb3lo +eb2lö +2ebo +e2bob +ebö2s +2ebr +eb4rea +2eb2s +eb6sche +ebse2 +ebs3in +ebs1o +ebs1p +ebs3pa +ebs3tau +eb4stät +ebst4h +ebs1ti +eb4stot +eb3str +eb4sz +2ebu +e2bunt +ebus3s +ebu2t1 +2eca +2e1ce +ech1am +ech1ä +2e1che +ech1ei +ech2en1 +e6ch5erzi +e1chi +ech3l +ech3m +ech3n +e2cho. +ech1ob +ech3ö2 +ech3r +ech4ri +ech3ser +echst5re +ech3t4ei +ech6terh +echter8ha +e1chu +ech1w +e1ci +eci4a +ec4k +ecke4n1 +eck3ser +eck4sta +2eckt +3eckty +2e1cl +2eco +2ect +e1d +ed2a +ed2dr +ed2e +ede2al +ede3n4er +eden4s3e +eden4s3p +edeo2 +ede2r +eder3a +ede4ran +ederer4 +edert2 +ed2i +e3di. +edi3an +2edip +edma3 +edmas2 +e3d2o +ed2ö +e3drei +ed4seh +ed2s1es +ed2si +ed2s1o +ed2s1p +ed2s1tr +ed2s1u +edu2s +e3dy +edys2 +2ee +ee3a2 +eeb2l +ee1c +ee2ce +ee2cho +e1eck +e2ed +eed3s2 +ee3e2 +e1eff +eef4l +eeg4 +e1ei +ee3ing +eein4se +eei5se +eeis3s +eel2e +e3e2lek +eele4n +eel2ö +e2e3m2a +eemas3s +ee3mä +e1emb +e1emp +e1en +eena2g +e2e3nä +e2enc +e2e3ne +een1er +e2eno +een3s +een2z +ee3o +e2ep +ee3po +eer3as +e1erbt +e1erd +ee3re +eer1ei +ee4r3en4g +eer2e4s1 +eer3k +ee1ro +ee1rö +eer2ös +eers2 +eerst4 +eert2 +ee3r2un +e1erz +e2es +ee3sh +ee3sp +ees2t +e2et. +eet2a +ee2tat +ee2th +eet2i +eet4r +ee2tu +ee1u2 +e2ew +eewa4r +eeweis4 +e1e2x +e1f +e2f1ad +ef1ana +ef1ar +e2farc +e2fat +2efä +efäs4 +efä5sse +e2fäu +2efe +e2f1e2b +e3fef +efe4l3ei +ef1em +e2femi +efe2n1 +3e2f1ene +e2fent +efer5f +efer5r +efeuil4 +ef2fä2 +3effek +1effi +ef2fl +2efi +ef1id +e2f1ins +efi2s +2efl +ef4le +e3f4lu +e3flü +2e3f2o +2efr +ef4reih +ef3rol +ef3rom +ef4ru +ef4rü +efs2 +ef3sc +ef3so +ef3sp +ef2tan +ef2tei +2efu +e2fum +2efü +e1g +eg1a2m +eg2anz +egd4 +e3ge +ege4l3au +ege8l7ei8er +ege4ler +ege2lo +eg2en +ege4n1a2 +ege6nero +ege2ra +ege4s3to +ege4s3tr +ege1u +2egi +2egl +e2glo +e2glu +e2gn +eg3nä +eg3ni +ego1p +egro5sse +eg4rö +eg4run +eg4sal +eg4s3an +eg3sau +egsau3g +eg3se +eg4sei +egs2e3l +egs2pe +egst2 +eg2th +2e1ha +eh1ach +e3h2ah +eh2al +ehalt4s +e3hand +eh1arm +e2harz +e3haut +e1hä +ehäs3 +e1he +eh1eff +eh1ein +e3helf +eh1elt +e4hense +e4h3ente +ehen4tr +1e2hep +2eher +ehe1ra +e2h1erf +e2h1er2l +2e1hi +eh3im +ehis4 +ehl1a +eh1lam +eh2l3au +eh1lä +ehl3ein +eh4lent +eh5l2er +ehlo2 +ehl1or +ehl2se +2ehm +eh2mab +eh4mant +eh3mu +2ehn +eh3na +eh3no +2e1ho +eho2f +eho2l +eh3oly +ehö4rer +eh2r1a4 +ehr1ä +ehr1ec +eh2rei +eh2rel +ehr6erle +ehr4ern +ehre3s +eh4rin +ehr1ob +eh1roc +ehr1of +eh1rö +eh2s2 +eh3sa +eh3se +eh3sh +eh3si +eh3so +eh3sp +ehst2 +eh3sta +eh3sto +eh3str +2eht2 +eh3ta3 +eht4r +2e1hu +eh1unf +e2huni +e3hur +e1hü +eh3üb +eh1w +e1hy +2ei3a4 +ei2bar +ei2bli +ei4blu +eibu2t +ei4b3ute +ei1ce +ei2cho +e2id +ei2d1a +ei3de +eid4ein +ei4deis +eid5erre +2eidn +ei3do +ei4ds +ei1e +eie2b +ei3e2l +eie2m +4ei3e2n +eienge4 +eie4s +eie2t +4eif. +ei1flo +1eifr +2eig. +2eiga +eig2ar +2eigä +2eigeb +2eigeh +4eigeno +5eigensc +2eig2er +2eiges +2eigew +2eigi +ei3gl +ei4glo +1ei2g3n +ei4g3rat +2eigre +2eigrö +2eigru +2eigrü +2eigs +2eigt +2eigu +4eih +ei2hum +ei2kak +eik4am +eik2ar +eik2i +eik2l +ei3k4la +ei3klä +e2il +2eil. +ei2lam +eila2n +eil3ane +ei4lant +ei4l3anz +ei2lar +2eilb +eil3d4 +ei4lein +eile2n1 +ei2let +eil3f4 +eilm2 +ei2lob +eil2ö +2eim. +ei2mab +ei2m1a2g +eim3all +eim3alp +ei2m1or +2eimp +eim2p4l +eim3sa +ei2mur +e4i2n1a +ei4nac +eina2d +ei4n3an +ei4na4s +ei4n3at +ei2n3ä +ein6derk +ein3ebe +ei2nel +ei4n3en4g +ei6nen6se +ein5erbe +ei4nerf +ei4nerk +einer6sc +ei2neu +ein4fiz +5einflus +5einfluß +2einfo +ein4fo. +ein4fos +ein3g2 +3einger +e4ingr +e2inhä +ei2n3ie +e1init +ein3k4 +ein6karn +3einkä +e2inl +ein3n2 +ein4nen +ei2n1o4 +1einri +e4insa +einsas6s +einsa7sse +3einsat +e2insc +5einschä +ein6stal +ein6terv +3eintö +3einträ +1einu +ei3o2 +ei1p +eip2f +2eir +eir2c +ei3re +e1irr +e4is. +ei2sa +ei3sas +ei6schwu +ei4serg +ei4s3erl +ei6s5erst +ei4s3erw +1eisho +ei3s2ky +eis2pe +e2i3s2s +eisser6s +ei2str +eistra6s +ei2sum +ei2sur +1eiswo +e2it +ei2t1a2b +ei2tal +ei2tan +ei2tap +ei2tar +ei4tat +2eitä +ei2tän +ei3tei +eite4ra +ei2t3h +ei2tin +ei2tor +ei4trau +ei2tro +eit4sag +eit3t4 +ei2t1um +ei2t1ur +eit3z2 +eiv2 +eive4 +ei2zar +ei2z1in +2e3j +e1k +e3k2a +2ekä +1ekd +ek2e +e3ke. +e3ke4n +e3kes +e3key +e3k2l +ek4n +e3k2o +ekor4da +e3kr +ek4s1p +2ekt +ek5t6ante +ek2t3at +ek2tä +ek2te2l +ekt3erf +ekt3erk +ek4t3er4z +ekt2o +ek2t3o4b +2e3ku +ekur2a +e3k2w +1ekz +e1la +ela2br +el2abt +el3abu +el3ader +el1af +2elai +e2l1ak +el1a2m +el2a3mi +e3lamp +el1ana +e4landa +e2l3a2ne +e2lanm +e4lans +e2l1ant +e4lanw +e2l1anz +2elao +e2l1ap +e2l1ar +ela2re +el3a2ri +el3arr +el1a4si +el1asp +2elat +el3aufw +2e1lä +e3läd +2eld +el4d3erf +eld3erl +elder4p +elder4s +eld5erst +el3des +el3dri +eld3s2 +4ele. +e3lea +elea2r +el3echt +4eleh +el3ehe. +2elei +e6l5ei6ern +e2l1ein +e3leine +1elek +e2l1el +1e2lem +2e3lem. +e3lema +ele2mi +2el1emp +2e3len. +elen1e +elen4k3l +e4lense +e2l1ent +e3lep +2eler +e3ler. +eler2a +el1erd +e6lereig +el1erf +e4ler4fa +e4lerfi +e2lerg +el1erh +el1erk +e2l1erl +e4l3ernä +eler2ö +e2l1err +el1eru +el1erw +eles2 +e2l1ess +e2l1e2ta +ele2ti +elet4ta +el1evo +el1ex +e3lex. +1elf. +elf2er +1elfm +1elft +elgi5er. +elgi5ers +el3g2l +eli4are +e2l1id +2e3lie +eli3ef. +2elig +e2lim +elin3a +eli3no +el1ita +2elk +elks2 +elk3sc +ella3d +el2lap +el4larb +el4lart +ella2s +ell2ei +ell3ein +el4lel +ellenen5 +ell2er +el3lie +el2lil +1ellip +el2lo2g +el2lor +el2lot +ell2ö +ell3sp +el2lu2m +el2lü +elm2a +elm2e +elm3ein +2eln +2elo +e2l3oa +el1obe +e2lof +e2lol +e2lonk +e2l1or +e3lore +elo2ri +e3lot +e3l2ov +2elö +el3p4 +el4s5ein +el2sum +el4tans +el3te. +elte4m +el5ten. +el4t3ent +elter4b +elter4f +elter6le +3elter4n +elter6sc +el3the +elt3se +2e1lu +el1uf +e2l1um +el1ur +el3use +elu2t +el3uto +e1lü +2ely +e2lya +el3z2ac +el2zar +el4zene +el2zwa +2elzy +e1m +e2m3a2b +em1alk +e2manf +e2m1ano +e2m1ans +em1app +e4m1a2sp +emas2s +ema3sse +e3maß +2emä +em2äh +emb6 +1emba +1embo +3embry +em2dä +emd1r +em2dra +2eme +e2m1e2b +e2mef +e2mele +e3m2en +emen6gel +emen3ta +emen4t3h +e2m1erl +em1erw +e4mesu +3e2meti +e2m1i2d +2emie +emi2ei +e2mig +emi3k2 +em1im +2emin +emi3n2a +e3mind +em1int +1e2mir +e3misc +1emiss +em2map +emma3u +em2mec +e2moa +e2mof +e2mop +emo3s +1empf4 +em3pfl +em3po +empo5s +em2sa +em4scha +em2sim +em2spr +em3t4 +1e2mul +e3mur +e3mus +2emü +emü3s2 +e2na +4ena. +e4n3a2b +4enac +e4n3ack +2e3nad +enadi4 +e4naf +4enah +en3ak +en1al +e4nalb +e3nale +en2alg +ena3l2i +e4nalk +e4nalm +e4nalo +enal3p +4en1am +ena4n +e4nand +en3ane +e4nant +e4nanz +e4n3a2p +en3a2re +en3ark +en3aro +en1a2s +ena4sc +e4na4st +2enat +4e5nati +e4natl +enat2s +e4n3att +4enatu +e4nau2f +en3aug +e4n3aur +e4naut +en1a2x +en3a2z +e2n1ä +e4när +enbu4s3 +en2ce. +1ency +end2ac +en2dal +en4dang +2endel +ende4lä +endermas8 +en4d3es4s +en2dex +en3d4ort +end3rom +end3s2l +end3s2p +end3sz +en3d2um +en3d2ü +2ene. +ene4ben +en1ec +e2neff +en2eid +e3neien +e4neige +4eneigu +e4nein +e4neis +en1e4kl +e2n1el +ene4le +2ene2m +e2nemi +2enen +e4nense +e4n1ent +en4entr +e2n1ep +4e3ner. +en2era +e2n1erd +e4n3erei +e2nerf +en4erfr +1energ +e2nerh +e2nerk +e2n1erl +e4nermi +e4n3ermo +4enern +e4n3erne +ene2ro +e2n1err +en1ers +4eners. +e2n1ert +en4ert. +e2n1eru +e2n1erw +2enes +e2n1e4sc +e2n1ess +en1eta +e2neth +en1eul +e2n1ev +e4ne2x +en3f +enf2a +enf2u +1engad +1engag +en3g2al +enge3r4a +en3g2i +en3gn +eng2o +1engp +eng4ra +eng3s2 +2eni +e3ni. +e3nic +e2nid +4e3nie +eni3er. +eni3erp +eni5ers. +en3i2ko +en3ill +eni4m +en1ima +en1imi +e2nin +e3nio +eni2ö +e2nir +e4n3iso +e3nit2 +e3niv +enk3aus +enk3erg +en4k3erk +en3k2ü +en2nef +en2nel +en4ner4f +enn3erg +en4n3erl +enni6ger +2enniv +e2n3oa +e2n1ob +e3nobel +enob4le +eno2br +e2n3oc +e2nof +en3ol +eno2ma +e2n1op +e2n1o2r +en2ora +eno4ri +4enorm +eno4s +en1ost +4e3not +eno2w +2e1nö +en1ö2d +en3sabb +en2san +ensas4s +ensa5sse +en5sche +en2seb +1ensem +en4sen3e +ens3ere +en2sid +en3spo +ens4por +ens4tak +enst5alt +en4s3tät +ens4tel +en6stele +en6s5test +2ensto +enst2ü +ens3umf +en2sun +en3t2ag +2entan +en4tanm +en4tanw +ent4ark +1entd +en3t2el +ente2n +en4terb +1entf +2entfo +2entfö +1entga +3entgeg +en2thi +1enthu +1enthü +en2tid +1entla +1entn +en2t1os +2entö +en4t3rol +1entsc +1entso +ent4sto +1entw +4entwet +3entwic +1entz +en1u +e2nuf +e2num +2enu2t +e4nuto +e1nü +4enwü +2e1ny2 +enz2äp +1enzep +enz3erg +en4z3erk +en4zerl +en4z3erm +enz5ersc +enzlan4 +enzo2l +e1ń +4eo +e1o2b1 +eo3ben +eo3bl +eo3br +eo1c +eoch2 +eo3dr +e1of +eo3g2 +e1oh +eo3la +e3o2ly +e1on. +e1ond +e1onf +e1onh +e1onl +e1onp +e1onr +e1ons +eo1o +e1opf +e1or +e3or. +eo1ra +e3orb +e3ord +e3ors +eort4 +e3orw +eos2 +e3os. +eo3se +e1o4ste +eot2e +eo1ul +e1ö4 +e1p +2ep2a +epa2g +epas6ser +2eper +e3p2f4 +eph2 +1e2pid +e2pig +e2pik +1e2pile +e3pio +1epis +2epist +1e2pit +ep3le +1e2poc +eport4 +1e2pos. +ep2pa +ep2pei +eppe3l +ep2pin +ep4p3l +ep2pr +2epr +ep3sh +ep2tal +ept2an +ep2tau +e3pu +epu2s +2e3q +er1a +e3ra. +e2rach +e3rad. +e3radi +e2radj +e2r3adm +e4radmi +e4r3adr +eraf4a +era2g +e1rah +e1rai +er3aic +e2rak +e3rake +e1rald +eral4eb +er3alke +e2r3all +er2an. +era4na +eran3d4 +e3rand. +e4rangr +e2ranh +e2rano +e1rap +er3apf +er3apr +e2rar +er3are +e3rari +er3arr +e3ras. +er3asc +era4sie +era2sp +era4s3s +e1rast +era2ß +era3te. +e3rati +er3att +e1raub +e1rauc +er3aue +erau2f +er3aug +e2ra2v +e1raw +e2r3ax +e1raz +e1rä +er1äf +er1äh +er1ä2m +er1äp +e2r1ä4s +er1ätz +3erbarm +erb2au +erb2e +erb2sp +er1c +er3chl +erch2o +erda3me +1erdb +er3de +2erdec +2erdel +er4d3en4g +erd3erw +erdeu2 +1erdg +er2dob +2erdy +4ere. +er1eb +ere4ben +e3r2ech +er3echs +er1eck +er1edi +ere4dit +er1eff +er1e2h +ere4i +6e3rei. +6e3reib +er1eig +4ereih +e3reik +e4r3eime +e2rein +er3eis. +er5eisar +er3eisb +er3eisf +er3eisr +erei5str +er1e2l +e2rele +ere3lev +ereli1 +2e3rem +e4r1ema +er1emb +e2remp +e4remu +2eren +e3ren. +e3rena +eren1e +e4rense +e4rentn +e4rents +e3renz +eren8z7en8d +er1epe +2erer. +2ererb +er3erf +e4rerfo +e2r1erh +e2rerk +erer4kl +e2rerl +4erern. +e4rerne +e2rer2o +erer4ri +er1ers +4erers. +e8rersche +e2rert +2ererv +2ererw +2eres +er1ess +eres3sk +er1eß +er1eta +ere2th +e4r1e2ti +3er1eul +ere4vid +erf2e +er3for +erf4r +4erfür +er4g3are +4ergebi +3ergebn +4ergebü +4ergeha +4ergehä +erg5elst +4ergeni +3ergiee +er2gop +4ergrem +erg1s2o +ergs2p +e4rh +1erhab +2erhai +4erhals +2erham +2erhas +3erhebu +er3hei +2erher +er3hu +2eri +e2riat +e3rib +4e3ric +e4r3ico +e2r1id +eri2de +4e3rie +eri3e2n1 +eri5ers. +e3ri3k +erik4l +4e3rin. +er1inb +e2rind +e2r1ini +er1ink +er1inl +er1int +e3rio +4eris +e2risr +3eritr +e3riv +2erk. +2erkaj +er3ker +1erklä +2erkm +2erkre +erk3t4 +2erl. +2erlag +3erlaub +3erlebn +4erleh +erm2 +er3mag +er3me +ermen4s +er4m3ers +er3mi +er4n3alt +er3ne +er4nene +er4nerf +er4nerk +3erneue +ern1os +2e1ro. +e1roa +er1ob +ero2bl +ero2br +e2r1o2f +e1rog +e1roh +4e1rok +e1rol +er3oly +e1rom +er3omb +2e3ron +er3onk +e2roo +er1op +e4ro4r +eror2a +e1ros +1erosi +e3rosit +e1rou +e1row +er1ox +e1roz +erö2d +2eröh +erö4l +er1ö2s +er3p +er4rade +er3rä +2erren +erri3er +er3ror +2errü +er3s2a +ers4ana +ersch4 +erse4h3u +ers2el +er5s2i +er3sk +ersma3s4 +4ersted +er6st5ers +4erstil +er3swi +er3sz +er2t1ab +erta2d +er3tat +4erteig +er4t3erf +er4t3er4g +er4ter4h +er4terk +er4ters +er2tho +4ertö +4ertru +ert3s2e +ert1s2p +2eru +eruf4s +e4r3uhr +er1u2m1 +er1und +e4rundu +3erup +er3use +e2r3uz +erü4b +3erweck +er4zerk +er4z3ers +e1s +es3ab +es2abb +e4sabe +e3sac +esa2d +e3saf +e2sall +es2an +es4and +es3anf +es3ant +esa2ra +e3sarg +e3sa1s2 +esa3ss +es3ato +esa2v +es1ax +esäs4 +es2äu +2esb +esbi5er. +e3s2ce +es2chi +esch2l +esch2n +e4sco +e3se. +es1ebe +e2s1ec +es1ehr +e2sein +ese3in4s +es2el +ese4nal +ese4neu +e3senk +esen3o +esen3sk +eser4at +ese4r1u2 +eses2k +es1eta +es3e2x +2esf +2esh +es3ha +es4ham +es4har +es3he +2esi +esi3er. +e2s1il +e4s3ins +e4siso +es2kat +e4s3ke +e4skl +e4sky +e4s3l +2e4sm +e4sn +es2oh +es2opa +eso2r +eso3re +es2ort +e3s2ö +e3spal +e3s4pan +es4park +es2pek +e2spel +e4spers +e4sph +e3s2pi +e3s2por +e3spra +e3s2pu +2esr +2ess. +es4s1a2g +essali3 +essau4s +1essay +2essä +2essc +e4ssel +e4ssent +ess4erf +e4ss3erg +es4serh +2essk +2esso +es2sof +2essp +es2s1pa +es2spu +es4stab +es4ste +estab4b +e4stabs +esta5ge +est1ak +e3s2tan +e4starb +es2t1a4s +e3stat +es2tau +e4staum +es2te. +este2c +est5eing +e6st5eink +e6st5einl +e4st3eng +est5erha +ester6ke +e4ster4ö +e4st3erz +estes2 +e4st3ess +e3sti +e4stid +e4stip +estmo6de +1estni +es2t1ob +e2stod +est3ori +e4strad +e5strec +e5strick +es2tu +est3ums +e3s2tü +e3s2ty +e3suh +es1um +e2sums +es1ur +2e4sw +e3sy +e2ß1el +e2ßent +eße3re +e2ß1erg +e1t +e3ta. +etab4 +et2abl +et2a2c +2e3taf +2etal +etal4la4 +etal6li6n +et1a2mi +e3t4an. +et1ant +etari1 +et4at +etat3r +et1äh +2etb +2e3te +ete2e +e4t1ein +ete3ke +et2en +eten3d2 +ete2o +eter4hö +eter4tr +ete4sp +2etg +et2h +2eth. +e3tha +e4t3hal +et3hä +1et4hi +e2thik +1ethn +e4thot +et3hü +e2tid +eti2m +etin1 +e2tinh +et1ini +eti2ta +eti2th +e4tl +2eto +e2t1o2f +et2on +eto4n3al +etons4 +e2torg +2etr +e4traum +et3rec +e2t3res +et4ros +ets2c +etscher7e +etsch3w +et4sh +et1so +ets1p +et1su +ett1a +et2ta2b +et2tad +et2tak +etta2m +ett2as +et2tau +et2tä +et2tei +ette4n1 +et4th +et2tö4 +et2t3r +et2t1um +et2tur +et2tü4 +3e2tui +e3tur +2e4tw +etwa4r +1etym +e3typ +2etz +etze4s +et2zw +eu1a2 +eu3b4 +2euc +euch4ta +2eud +eudi4e +eu2eb +euer3ei +eue6reif +eue6reis +eueren4 +euerer6s +euerer6t +eu3eri +eu3erk +eu3err +eue3s +eu2e5sc +4euf +euf2a +eu2fer +eu2g1a +eu6gense +eu3g2er +eu4g3ing +eu2gre +eu2gri +eug1s2 +eu3h +eu1id +eu1in1 +1e4uk +eu2kä +eulan2 +euland3 +eu3l2e +eul2i +2e1um +e3um. +eu3ma +euma3s2 +e3umb +e3umf +e3uml +e3um2s +eums1p +eum3st +e3umw +2euna +eun2e +eu4nei +e3un2g +eu2nio +eu4nis +eunk2 +eun3ka +eu1o2 +eu1p +eup2f +eu2ral +eu4r1an +eu4r3ast +e2ure +euren2 +eu4rens +eur4er +eur3f4 +1euro +eu1s4 +e3usar +eu4sis +eus5k +eu3sp +eu3ss +eust4 +eut2e +eu5ted +eut2h +1eu3tha +eu3t2o +eut6scha +eut6schn +eut6schr +2eux +eu2za +eu2zo +eu2z1w +e3ü +e1v +e2vak +e3var +eva2s3 +2ev2e +eve5ri +evie3le +2evor +ev2s +e1w +ewä4 +ewä6s +e2we. +ewei4sc +ewert4 +e3wir +ewi2s +e3wit +2ex. +e2xam +2exas +ex3at +2exc +2exd +e2xel +e2xem +ex1er +2exes +e1xi +e3xie +2exik +e2xil +e2x1in +1exis +ex3l +3exp +2exs +2ext. +2ex2ta +ex2tin +1extr +2extu +2extv +2exu +e2xum +2e3xy +ey2n +ey3no +eys2 +e1z +e3z2a +ez2ä +e2z1enn +e3zi +ezi2s +ez2o +e3zoh +ez2w +é1b +é1c +é1g +égi2 +é1h +é1l +élu2 +é1o +é1p +é1r +é1s +é1t2 +é1u2 +é1v +é1z2 +č1c4 +č1m +č1n +č1r +1ën +ę1p +1fa +fab4 +2f1ab5b +fa2ben +2fabf +2f1a2bl +2fabn +f2abr +2f1ab5s +fa4cheb +fa4chel +fa2ch3i +fa2cho +fachs2 +fach3sp +fa2ci +fa2del +f1ader +fa2di +fa2dr +fa3ec +fah6l5ent +fai3b4 +f1a2ka +fa2ke +f3aktio +f2akto +3f2aku +fa3la +fa3le +fal2kl +falla2 +fal4lei +fal6lenk +fall5ent +fal6lerk +faller6s +fal2li4 +fal6scha +fal6schl +fal6schm +fal3te +fal2tr +3fam +4famp +f1amt +3f2an. +fa2nar +2fanb +fand2a +fan2gr +2f1an3k +2fanl +4fann +f1anp +2fanr +2fanw +2f1an3z +2f1a2p +f2ar +far2b1a +far4bel +far4b3er +far4bin +farb3l +far2bo +far2b3r +far2b3u +f3arc +3fa5ri +far2r1a +farre2 +far4rec +far4reg +far2rh +2f3art +2f3arz +3fas. +fa3s4a +fa3sh +f1assi +fas2t +2f1a4str +fa2ß +f1aße +f3at +f4at. +fa2to +f4ats +2f1auf +f3aug +fau2s +f1ausb +faust3r +3f4av +fa2xa +1fä +fä1c +fäh4rin +fäh2r1u +f1älte +2fäq +2f1ärm +2färz +fä4s +fä6s3ser4 +3fäßc +fä2ßer +2f1ätz +2fäug +2fäx +4f1b2 +fbau1 +fber2 +2f1c +f3ch +2f3d4 +fdien4e +1fe +3fe. +featu4 +f2ech +fe2dr +fe2e1i +feein5 +fe1em +2f1e2he +feh4lei +f2eie +f2eind +2f1eing +fe3ins. +2f1einw +f1ei3s +5fek +fe2l1a +fel3au +fe2l1ä +fel2da +felde4m +feld6erh +fel2dr +fel4d5ri +2fe2lek +2felem +fe2l1er +fe2les +fel3la +fel4lan +fel2lä +fe2l1o +fel4s3oh +6fel6tern +felt4r +fel3tu +f2em. +fem4m +2f1emp +fen1a +fena2g +fen3au +4fenerg +fe2ni +fe2no +fen3s2a +fen5s2c +fenst2 +fen6stri +f1ent +2f3entf +f2enti +4f3entla +f2ento +2f3entw +2f3entz +fe2nu +3fep +fe2pi +f2er. +fe1ra +fe2rab +fe2ral +fe4rang +fer4ant +fe4ranz +fe2rau +fe2r1ä +2ferd. +fer3da +ferd2e3 +f2ere +fe2re2b +fe2rec +3ferei +4f3ereig +fe4r3eis +f4erel +fer3ell +fe4rer4g +fer4fah +ferg4 +f4ergr +ferie4n3 +4fer4leb +f2ern. +fer4nei +fe2rö +f4erpa +f4erpf +f4erpl +f4erra +fer4reg +ferri2 +f2ers. +f2ert +fert4r +f2erz +fess2e +fes2t +fe2sta +fest3a4b +fest3an +fe4st3ei +fe4stin +fe2st1o +fe2st3r +2f1e2ta +3fete +fet4t3a +fetti3s +2feu. +feuer3ö +3few +2f1ex +3fez +1fé +4f1f +f3fa. +f2fa2b +ffa2ce +ff1a2d +f3fak +f3fal +ff1alt +ff1ans +ff3ar +ff4arb +ffa4s +ff1au +ffa2z +f2f1e2b +ffe2e +f2f1ef +f2f1ei +ffe3in. +ffe5inha +ffel3l +ffe2m +f2f1emi +ff2en +ff3erle +f2fetz +fff4 +ffi3k +f2fil +f2fim +ffi2xi +ff1lag +ff3li +f3flu +f3flü +ffo2 +ff1ox +f2fö +ff1rak +f3f4rä +ff3ro +ffs2am +ff3sch +ff2s1p +ffs4tau +ffs1ti +ff3stü +fft2 +ffus3s +4f3g2 +fgeb2 +fge3s2 +4f3h2 +1fi +3fi. +fi2ar +fi3at +fiden2 +fi2do +fi1er2f +fi2k1as +fi2kel +fi2kin +fi2kn +fi2k1o4 +fi2k3r +f2il +fi2l3an +fil3d +fi2les +fi3li +fi4lin +fil2ip +fil2ma +fil2mä +fil4med +fil4mei +fi2lo +2fimp +3f2ina +2f1inf +fing2 +fing4e +fings2 +fi3ni +f2ink +2f1int +fi2o +fi3ol +fi2r +fi3ra +fi4re +fir3me +fi3s4a +fi4sch3a +fi6schei +fisch3l +fisch3o +fi4schr +fi4sch3w +fi3s2h +2f1i2so +fis2p +fite2 +fi2tin +fit1o2 +fi2tor +five4 +fi2xel +2f1j +3f2jo +4f1k4 +fka4t3 +f2l2 +2fl. +f3lad +f5land +f4lans +f3lap +f4lasc +f3lats +flauma4 +3f4läc +4f3läd +f3län +f3läu +fl4e +f5le. +2f3leb +2f5lein +flek3 +flekt2 +f3ler +f4lex +f3li. +3f4lim +fli4ne +f3ling +2flins +2f5lon +1f4lop +f4lor +flo7s8ses. +1f4loß +1f4lot +flo2w +f3lö +4flöf +1f4luc +1f4lug +flu4gen +flu4ger +1f4luss +1fluß +f4lut +flut1o +f4lü +f5lüd +f5lüm +4f3m2 +fma5che +fma2d +fmas2s +fma3sse +2f3n2 +fni2s +1fo +f1ob +fo2be +2fober +fob2l +2f1o2f +foli3 +fol2k3 +fo2na +fo4nan +fon3au +fon3dr +fo3n2er +fo4nin +fo2nop +fons2 +fo2nu +2f1op +4f3org +fo3rin +for4m3a4g +for4mas +for4m3ei +forni7er. +for6schl +for4sta +for4sti +for4t3ei +for4ter +for2th +for2t3r +fort3s2 +for3tu +for2u +fot4r +fo2x +1fö +2fö2f +2f1ök +4f1ö4l +4f3p4 +2f1q +f2r2 +f3ra. +frach6tr +2f3rad +2f3rah +fra4m +f3rand +f5rap +f3rat +1frau. +f3rauc +2fräd +1f4rän +2fre. +f3rec +f3red +2fref +2freg +f4rei. +f3reic +f4reie +frei1f +f4reig +frei3k2 +2freim +2frein +2f3rek +2f3rep +2frest +3f4reu +2f3ric +fricht6e +fri3d +fri2e +2frig +f4ri3k +f3rip +1fris +f4risc +f4rist +fri6ster +2f3roc +2frol +1f4ro2n +fro4n1a +f4rop +fro2sc +f3rot +frös2 +f3ru +f4ruc +f3rü +4f1s +f2s1al +f2sa2n +fs3ane +fs3ar +f2s1a4s +f2saut +fs2än +f2sca +f4sce +f4schan +f4schef +f4schro +f2scr +f2s1e2b +f4sehr +fse2n +fs1en1e +f2s1ent +f2s1er +fse2t +f2s1eta +f2s1i2d +f3s2ky +f2s1o2 +f3soh +f3sol +f3s2on +fsp4 +f3spann +f2s1pas +f2sph +fs2pie +f3s2pl +f3s2por +f2spre +f2spro +fs2pul +fs3s2 +fs2tal +f2stas +f3s2tat +f4s3täti +f2stip +f2s1tis +fst4r +f4s3tres +fs1trü +fs1tut +f4stüte +fs1ums +f2s1un +f3sy +4f1t +f2ta. +ft1a2be +ft1abl +ft1af +f3t2ag +ft1ala +ft1an +ft1a2r +f3tat +ft3att +f2t1äu +ft1eck +ft1edi +ft1eh +fte2he +ft1eig +ft1ein +ft1eis +ft1eli +ft1emi +f2t1ent +ft3erfü +ft1erk +f2t1erl +f2t1erz +f2t1e2ti +f2t1ex +f2t3h +f4t5hei +f3ti +f4tid +ft1in +f4tinf +f4tins +fto2 +f2t1of +ft3om +f3tor. +f2t3ot +f3t4ran +ft3ro +ft3ruh +fts1 +ft2sa +ft4sa2g +ft4sam +fts2c +ft2se2 +ft4seh +ftsen1 +ft2s3i +ft4stem +ft4ster +ft4stes +ft3stie +ft6stier +ft3stri +fttra4 +f2tum +ft1urk +ft1url +ftwa4 +ft3z2 +ftze3d +1fu +3fuc +3fug +f2uh +fuku3 +f1um +fun6derg +2f1unf +2f1ungl +2f1u2ni +fun2kl +fun2ko +fun2k3r +fun2ku +2f1unm +2funr +2funt +f2ur +furch2 +fu4re. +2f3url +fus2 +fu3sse +fus6sen +fu4sser +fuss1p +fuss1t +fus4ste +fu2ß1er +3fut +1fü +2füb +fühl4sc +fün2 +fü2r +fü3s2 +2f1v +4f1w +f1ya +4f1z +fz2a +fzeiten6 +fzei8t7end +fz2ö +fzu2ga +fz2w +3ga. +2gabf +2gabg +g4abi +ga2b5l +gab2o +g1abr +gab4ri +2gabsc +2gabtr +ga3bu +2gabw +2gabz +gade2r +ga3di +gadi4e +2gadl +2ga2dr +gae2 +ga1fl +5gag. +ga1k +ga2ka +ga2ku +gal2a +ga3laf +ga2lar +2g1alau +2g1alg +gall4e +gal3lo +2g1alp +2g1alta +2g1altd +g1a2lu +ga2mec +ga3mel +gam3ma +5g4amo +2g1amt +g1ana +2ganb +gan3d2 +2ganf +gan2g1a +4gangeb +gan2gr +gang4sp +gan2g1u +2g1ank +2ganl +2ganmu +3g2ano +2ganr +gans2 +2g1ansi +2ganst +2ganw +ga1ny +g1anz +ga3pe +2g1app +ga1q +3gar. +g2ara +2garc +3g2ard +ga3r2i +2g1arm +ga3r2o +2g1arti +ga3ru +2g1arz +ga2s +g2as. +gas3al +ga4sam +gase2 +ga5se. +ga4sei +ga4sel +ga4se4m +ga5ses +ga4set +gas5s2 +5g4asse. +g4assen +6gassess +ga5ssest +ga4st3el +ga3sti +ga4stin +gastra4 +gastras5 +gas4t3rä +ga3stri +ga6strom +gas1tu +ga3t2a +gat2h +2gatm +gat4r +gau1c +2g1auf +2g3aug +g2auk +gau5ne +2g1au4s +2g1aut +2g1äp +gär3th +2gärz +gäs2 +gä4u +2g3b4 +gbau5s +gber2 +gbi2 +gbon2 +2g1c +2gd +g1da +gd2ad +gda3de +g2dak +g2dan +g2dar +g2dau +g1dä1 +g2dei4 +gd2en +g2d3ent +g2der +gd2es +g1do +g2dop +gd2or +g1dö +g1d3r +gd3s2 +gdt4 +1ge +ge3a2 +geb2a +ge3ble +geb4lin +gebot2 +3gebü +ge1c +ged4 +ge1e2 +ge3ec +geest3 +3gefä +4g1eff +gef4l +gef4r +ge3fu +gegen1 +ge3g2l +ge3hei +2g1eid +ge4ie2 +2g1eif +ge4ig +g2eil +gein1 +ge1ini +ge1inn +2g1einr +gein5sti +gein2v +ge1ir +ge2is4 +2g1eise +gei3sh +gei4sta +2gek. +gelb1r +gel4b3ra +gelb5s +gelder4 +gel6derh +gel6ders +ge3lec +2ge2lek +2gelem +ge4lene +gel3ere +ge4lerk +geler3ö +ge4l3ers +ge2lev +gel3f +gel1i4m +gel3l2a +gel3le +gell2i +gel2ö +gel3s2a +gels2p +gel3sz +gel3ta +gelt4r +gel3z2 +gem2 +ge4ma. +gem6e +4g1emp +gem3s +ge3mu +ge3na +ge4n1ac +ge4nak +ge4n3al +ge4nam +ge4nar +ge4nat +gen4aug +ge3nä +ge4näu +g2enc +4genda. +4g3endmo +gen2dr +gen3eid +gener4f +4generg +ge4n3ern +gen6erwe +gener4z +ge3nid +ge2nim +gen3k4 +genma7sse. +gen3n +gen3sk +gen3sz +gen3tä +2gentf +gen3t4h +gen3tr +2gentw +ge2nun +genzma3 +genzmas6 +geo2ri +ge1ou +g2e3p4 +ge1ra +ge2ra2b +ge2r3al +ge3rann +ge4rant +ge4r3a2r +2gerdg +ge4rene +ge4reng +ge4ren4s +ge4r3ent +ger2er +gerin4f +ger4inn +gerin4t +4ger4klä +g3erlas +germas6s +ger5me +ger3no +2g1ernt +ge1ro +ge2rob +ge2rop +ge1r2ö +ger4sat +4ger4seh +ge3r2u +g1erzä +g6es. +3ges2c +ge6sche. +ge2seb +4g3e4sel. +ge4s3elt +ge2s1er +ge3sha +ge3s2i +ges2p +ges4pi +gess2t +gest2 +gest4a +gest6e +ge4s3tur +get2a +g1etap +get3s +ge3t4u +2g1e1ul +ge3u2t +ge3wa +4g1e2x +2g3f4 +gfi4l +2g1g +gga2t +g5ge +gge2ne +gg2l +g3gla +g3glo +g2g3n +gg4r +2g1h +4gh. +gh2a +3ghale +gh2e +3g2het +3g2hie +gh1l +3gh2r +ghs2 +g2hu +gh1w +gia2s +gich2 +gicht1 +gi2eb +gie3g +gi2e1i +gi2e3l +giel2a +gie3n +gien2e +gi4eno +gie3re +gies4 +giet2 +gif2tr +gift5s +gi2gu +gi2kel +2g1ill +3gime +gi2me. +gi4mes +gi2met +2gimp +2gind +gi3ne +2g1inf +gin2ga +2ginh +2g1ins +2g1int +2ginv +gi2ob +2giok +2g3isel +git2a +gi4us +2g1j +4g3k4 +gl2 +4gl. +4g1lab +2g1lac +2gladu +2g1lag +2g1lam +2gland +3glanz1 +gla2s1c +glast4 +gla4str +gla4stu +3g2laub +2g1lauf +g1läd +g1läß +2gläuf +gl3b +g2l4e +2gle. +3glea +2g3leb +g3lec +4g3led +g3lee +2g3leg +2gleh +g4leic +4g3lein +gleiter8s +glei4t5r +g3len +4glenk +4g3ler +glerei4 +2gles +3gles. +g3lese +g3lev +g2lia +2glib +3g2lid +g2lie +2g3lieb +2glif +g2lik +4glil +g2lim +4glin +g2lio +2glis +3g2lit +g3lite +g2liz +g3lize +g2loa +g2lob +g2loc +2g3loch +g2lok +g2lom +g2lop +g2lor +2glos +g2lot +2glöch +2glös +2glöw +2gls +g1lu +2g3luf +2gluk +4g3lun +g2lut +3glü +g1lüg +2glw +3g2ly +2g1m2 +g1n +2gn. +g2n2a +g4na. +2gnac +2g5nah +gn4al +gna4l3er +2gnanl +3g2nä +2gnb +2gnc +2gnd +gn2e +g3neh +2gn3ent +gne2tr +2gnf +2gng +2gnh +g2nie +g2nif +g4nin +2gnint +2gni2s3 +gnise2 +2gnk +2gnl +2gnm +g2no1 +g4non +g3not +2gnp +2gnr +2gns +2gnt +2gnu +3g2num. +g2nü +2gnv +2gnw +g2ny +2gnz +go4a +goa3li +g1ob +go3be +2gobj +gob2l +go4c +2g1o2f +2gog +2g1oh2 +goh3ren +go1i2 +go3in +gol2a +gol2fr +3gon. +gon2e +3gons +goo2 +2gope +gopf4 +go2pos +2gopt +gor2a +2gord +2g1org +go2si +go2sp +gost2 +2g1osz +go3t2h +got6terb +got6t5erg +3gou +go1y +gö2f +g1ö4l +3göt +2g3p4 +2g1q +g2r4 +g4rab +gra2ba +gra2bi +gra4bl +2g3radl +2g3rah +2g3rak +gram1 +gram8m7en8d +gram6mer +g3rand. +2gra2r +grar1e +gra4s3a +gra4sh +gra4sp +gra4str +2g3raub +grau3f +2graum +grau3sk +2gräd +gräs5c +g3räu +2g5re. +g4reb +2g3rec +g3rede +g4re2e +2g3ref +2grege +2g3reic +grei4fr +2g3reih +g3rein +g3reit +g3rek +g4rem +2g3renn +gre3no +gren6z5ei +grenz3w +g4rer +gres6ser6 +g3ret +g3rev +2g3ric +gri2e +2g3riem +g3riese +g4rif +2grig +gril4la +4g3ring +4g3rinn +g4rip +gro2ba +gro3ber +gro2bl +gro2b3r +2groc +2groh +2g3rol +gron4 +gros2 +2g3rose +g4ross +gro5sse. +gro7ssen. +gro7sser. +gro7sses. +2g3rost +g4roß +g4rot +2gröh +2gruf. +g4ruft +2g3ruh +g3rui +2g3rum +grun2g +3g4rup +3grus +grus2s +gru3sse +3gruß +2g3rut +2g3rüc +g4rün +grüs2 +4gs +g2sa +g4s3ab +gs3ach +g3sack +g4sa2d +g4s3a2k +g3s1al +g4salb +g4sall +g4salm +g4salt +g4sama +gs1amb +g4samp +gs3ane +g4sant +gsa4p +gs3a2r +gs1as +g3sat +gs3ato +gsau2g +g3sau4r +gsa2v +gs1ä +g3sch4 +g4schef +gs2chi +gs3d +g2s1e2 +gs2e3h +g3s2eil +g3s2eis +gse4kl +g3sel. +g4s3ela +g3seln +gs3em +gsen1 +gs2enk +g4sent +g4ser +g3sere +gs3er1i +g4se4s +g4seu +gsfi4l +gsh4 +gs3ha +g2s1i +gsi2d +g3sig +gs3i2k +g3sil +gs3in +g4sis +g4sita +gs2ki1e +gsmas8sen +gs1o2 +gso4b +g3son +g2s3op +g5s4orge +g5soz +gs1p4 +gs2pac +gs4pant +g3s2pek +g3s2pi +g5spie +gs3pl +g3spor +gs6port. +g6sporto +g4s3pru +gs3s2 +g2s1tab +g2s1tät +gs2te. +gs4tem. +g4stemp +gs4ten. +gste2r +gs4ter. +gs4tere +g6sterei +g4sterm +gst3err +gs4tes. +g4stest +gs2thy +g3s2ti +gs3tie +gs3tis +gs1tot +gst4ra +g3stras +gst5reit +gst4res +g4s3treu +gst3rit +gst3ros +g2stru +gs1trü +gs1tur +gs1u +gsü3s +g3sy +4g1t +g3te +gt3h +gt4hy +gt2i +gti2m +g3to +gt4r +1gu +gu4ale +gu3am +gu1an. +gu1ant +gu1as +gu4d3r +gu2e +2gued +guet2 +2g1u2f +2g1uh +guil3 +gu1ins +gu1i4s +gum2e +3gumm +gummi1 +gun2e +2g1unf +g2ung. +gunge2 +4gungew +2g1ungl +2g1u2ni +2g3unk +2gunr +2gunt +3gur +gure4 +4g1url +gur2th +gur2tr +gurt3s +gu2s3a +gu2sä +guschi5 +gus3se. +gus3ses +guss1o +gus2sp +gus4st +gust3a4b +gu4stap +gu6stein +gust3en +gu3sti +gu2str +gu2ß1 +gußt4 +gu2t +gut1a +gu3te +gu4t3er4h +gut3h +gut4sa +gut2s3p +2güb +3gür3 +gü3st +2g3v +2g1w +gy3n +gyp2a +2g3z2 +gzeu4gi +hab2a +hab2e +hab2i +2habn +h1a2br +h1abs +2habw +ha4ch3en +ha2cho +ha2del +hade2n +h1adle +hado2 +h1a2dr +2hae +ha4far +haf2e +h1affä +haf3f4l +h2aft +haf2tr +haft2s +hafts3p +h2agg +h1ah +h2ahs +h2ai +3hai. +h2aj +2haka +ha1k4l +2h2al. +halan4c +h1a2lar +ha2lau +hal2ba +hal4bel +hal4bin +hal2b3r +hal2bu +2hale +2halk +hal4lei +hal6lere +hal6lerf +hal6lerg +hal4leu +hal4lo4k +ha3lo +4halp +hal2sp +hal4tal +hal4tei +hal2t5r +h2ame +2h1amt +ham3te +h2an. +2hana +ha2nal +ha2nan +2hanb +h2anbe +h2and +han2da +han2d3r +ha2nem +han2f1 +han6g5end +hang3s +2hani +han2kr +2hanl +2hano +2hanr +2hanz +hao2s +2h1ap +3h2ape +ha2pl +ha2po +ha2pr +h2a3ra +ha4rab +2harb +h2ard +har2fr +h1arm. +har3ma +h2arme +har4me. +har4ne +ha2rom +hart4e +har2th +h1arti +har2tr +har2za +h2as +4ha3sa +has2c +has4h3 +has4sa +hasser4 +has6s1t +ha4str +ha2ß1 +h1aße +ha2ta +h3atl +ha2t3r +2hats +hatt2 +h3attr +h1audi +h1aufb +hau5f6lie +hau3f4lo +2h1aufm +h1aufs +h3au3g +h1aukt +hau2sa +hau4san +hau2sc +h2ause +hau4sel +hau6s5ent +hau4spa +hau4spe +hau4ss +haus5sen6 +hau4s3ti +hau4sto +hau4sur +h2aut. +hau2ta +4hauto +hau2t3r +ha2ve. +3hax +häde2 +h1äff +hä2kl +2härz +hä4s +hä5sc +hä6s5chen +2häug +häu2s1c +hä3usp +2h1b4 +hba4ras +hbe3r2e +2h1c +2h3d4 +hdan2 +4hea +he3be +heb3eis +he2bl +he3br +he3bu +he3ch2e +he3chi +he1cho +h3echs +hed2g +he2dit +he2el +hee3le +he1e4m +hee2s +he1e2t +h2ef. +he2fan +he2fau +he2f1ei +he3f2em +hef3erm +2heff +he2fid +he4f3ing +he2f5l +2hefr +hef4ra +he2fre +3heft +he2fu +he3gu +he2hel +h4eib +h1eie +h1eif +h1eig +he2im +hei4mal +hei4mar +hei4mei +heim3p +hei4mu +2hein +heine2 +hei4neb +hei6nene +hei4n3er +h3eintr +4heio +he1ism +heis4s +he1i4st +heit4s1 +h1eiw +hekt3a +he2l1an +he2l3au +hel1ec +he2lek +h3elem +he2len +h2elf +he3li +hell3au +hel4lic +hel4mei +he3lo +he4lof +hel2or +he2lö +2helt +hema4s3 +2h1emb +3hemd +he3mi +he4mia +h3e4miss +3hemm +2h3emp +h2en. +hen3a2 +he4nas +he4nat +hen3ebe +henen1 +hen3end +he4nene +he4nens +hen3erg +he4nerm +he2n1e4t +henfal4 +2henga +hen4gag +hen4kan +hen4kau +hen3st2 +hent2a +hen3te +hen3tr +h1ents +2h3entw +h3entz +he4n3u +hen3z2 +4he2o +he3on +he3op +he3pa +he3ph +h1e2pi +hept2 +h2er. +her3a2b +he2rad +4herap +he4r3a2r +he2rat +herau2 +herb2 +h2ere +he2re2b +he4reck +her4eif +4he3reig +he6reis. +her7eises +he2rel +he4rene +he6rersc +he4rerw +h1er2fo +6hergebn +2herif +herin4d +herin4f +he6rin6nu +herin4s +h1erke +her4klä +h5erkran +her3la +herma3s +h2ern +he3ro +he4r3o4b +he4rof +he4rop +he4rot +h1erör +her3sta +hert4 +her3th +her3um +her4zap +h3erzeu +her2z1w +he3sa +4hese +he3si +he3s2p +hes2t +he2tap +he3tä +heter2 +he3th +het2i +he3t2s +h2eu +heu3g +he2um +3heusc +he3x +he1x2a +2hexp +he1y2 +1hč +4h1f4 +hfaller6 +hfan2 +hfel2l3 +hfi2s +hflei2 +2h3g4 +hgas1 +hga4sen +hget4 +2h1h2 +hhoh2 +4hi. +4hia +hi2ac +hi2ang +h1iat +4hic +hi1ce +hich6t5er +hicht6sp +2hid +hi3d2e +hi2e +hi3ens +hier3i +hie4rin +hiers2 +hif3f4r +hi2k3r +hi2l3a4 +hile3n2 +hil2fr +h2im +2hima +h1imb +h3i4mit +h4imm +h3impe +hi2n +hi3nak +hi3nam +hi3nap +hi5nas +h2inde +hi3nel +hin2en1 +h1inf +h1inh +2hi3n2i +hin3n2 +hi3no +hin2t1a +2hio +hi3ob +hi4on +hi3or +hi2p1 +hip3f +hi4pl +hip3o +hi2r +hi3ra +hi3re +hi3ri +hir2m1a +hir2mi +hirn1 +hir4ner +hir2s +1hirt +2his. +his2a +hi2se +h1i2so +hi2spa +hi3tac +hi2tan +hi2tel +hit2i +hit3z2e +hi2v1o +2h1j +2h1k4 +hkamp2 +h2keu +hklo3s +4hl +hl2ag +hla2gr +hla2l +hlam8meng +hlan4d3a +h1las +h1lat +h3laus. +h1laut +h1lay +h3läche +h3läd +h1läs +h1läß +h1läu +hl3d4 +hle3a +h3leb +h3led +hle3e4 +h3lein +h2leis +h3leist +h5len. +hle4nas +hlenen3 +hl2enn +h4l3entr +h4lents +hl2enz +h3ler +hle2r3a +hl4ere +h2lerg +hl2erk +h6l3er4nä +hle3run +hl1erw +h4lerz +h3les +h4lesi +hlf4 +h2lie +h3lied +h2lif +h2lim +hl1ind +h2lip +h2lis +h3list +h2lit1 +hl3l2 +hlle3b +hlm2 +hlma3s2 +h2lo +hl1ob +h3loc +h3log +hlo2re +h4lorm +h3los. +h3losi +hlos4st +hlo2ß1 +hl2ö +h2lös3 +hlö4ss +hl4sar +hl2ser +hls3ka +hl3s2lo +hls3tie +hl3str +hl2su +hl3t4 +h3luf +h3luk +h3lumpe +h1lüf +hlz2 +2h1m +h3mad +h3mag +h3mak +h3man +h2mant +h3mar +h4marc +h3mas +hma3sse +h3maß +h3mä +h4mäc +h4mäh +h4mäl +hm2e +h3me. +h3med +hme1e4 +hmeer4s +h3mein +h3meist +h3meld +hme3le +h3men +hmen2s +hme2ra +h3mex +hmi2e +h3mil +h3mind +h3mini +h3minz +h3mirr +h2mo +h3mop +h3mot +h3m2ö +h4möl +hm3p2 +hm2s1p +h2mu +h3mul +h3musi +2hn +h2na +h3nag +h3nam +h4nar +h4natt +h3nau. +hn1äh +hn3d4 +hn2e +hne3b +hne2e3 +h2n3ef +hn3eig +hn3ein +h2nel +hne4n1 +hn4eng +hne4pf +h3ner +hner4de +hner3ei +h4n3e2ro +h4n3ersa +hn4es +hn3ex +hn3f4 +hnflei4 +hnhof8stra8s +h2nic +h2nid +h2nie +hn1im +h2nip +hnk4 +h2nor +hn3sa +hn3s2p +hns2t +hnsuch4 +hntra4 +hnts2 +h2nul +h2n1unf +hn3z2 +ho4ar +ho3bern +ho2bl +ho2c +hoch3 +hoche2 +hocker4 +hock3t +4hocy +2hod +2ho2e +hoe3n +ho4f1a4 +ho2fä +ho2feu +hof3f4a +ho2f3l +ho2f1o +ho2f3r +ho2fu +2hoi +ho2l1a +hol3ar +4holdy +3hole +ho2l1ei +hol3g4 +hol3k +holl2 +ho2l1op +holt4 +2holy +h3olym +3holz +hol6zene +hom2e +ho2me. +ho2mec +ho2med +h2on +4hon. +hond4 +4hone +hon2er +4hong +4honh +4honk +4hons +4hony +ho1on +hoo2r +2hope +ho1ra +ho2rak +h1o2r2an +ho2rar +ho2rau +h1or3d +2hore +ho4rens +ho3ret +2h1org +ho2rop +hor3ta +hor4ter +hort3s +h1ortu +hos3a +ho3se2 +ho4sei +ho3sl +ho4sla +4hosö +ho2str +ho4ßene +2hot. +ho3th +4hotr +2hot1s2 +2ho2w1 +h1o2x +ho1y2 +4hoz +hô1 +1h2ö +2hö. +hö2c +h4öh +5höhe +hö4l +hö4s +hös1c +hös3se +h3öst +2h3p2 +h1q +4hr +hra2b +hr3ac +hr3ad +hr1a2g +h1r4ah +h1rai +h1rane +hr3ap +hr3as3s +h3rat +h3räu +hrb4 +hr1c +hr3d +h2rec +h3r2ech +h3red +h3ref +hr1eh +h4rei. +hrei4ba +hrei4br +h3reic +h3reif +h4r3eig +hr4eini +h4reinl +h4reins +hrei3th +hreli1 +h3rep +hrer6geb +hr2erk +h4rerla +h6rer6leb +hr2erm +hrer4sa +hrer5st +hrer6tüc +hr2erw +hr2erz +h3re2s1 +hres5s2 +hrest2 +hre4t +h2r1eta +h2r1eu +h2rev +h3rez +hrg2 +hrga4 +hrgu4 +h2ri +h3ric +h4rick +hri4e +h3riesl +h3rin +hr1int +h4rist +hrk4 +hr3l +hrm2 +h3rog +h3roh +h1ro2l +h4romat +h4rome +h4romi +h4romo +h4ron +h1ropa +hro4r +h3rou +h3rö2s +hr2s1ac +hr4s3and +hr3sch +hr2sen +hr2s1er +hr2set +hr4sh +hr2sin +hrs3k +hrs3l +hr2s1of +hr3spa +hrst2 +hr4stec +hr6stele +hr2su +hr2tab +hr2tan +hr2te2l +hr2th +hr2top +hrt3ric +hrt2sa +hrt2se +hrt4sin +hrt2sp +hrt4ste +h3ruh +hr1ums +h3rut +h3rü +h4rüb +h4ry +hrz2 +4h1s +h4s3acht +h2sa2d +h2s1alk +h2sall +h4samt +h2san +h2s1as +h2sath +h2saud +h2s3aur +h2saut +h2säh +h2säug +h3sc +h4schan +hs4cr +h2s3ec +hse2e +h4s1ehr +h2s1eie +h4seind +h6seinst +hsela2 +h3sele +hse4lin +hse4mis +h4s3endw +h2s1erf +h2s1erg +h2serh +h2s1erk +h2s1erl +hs1ern +hs4erne +h2serö +h2s1erw +h2serz +h2seth +h2sex +h3s2ext +hsha2k +h2s1i2d +hs2im +h2s3ing +h3s4inni +h4s1ita +hs2kal +h3skand +hs1of +h2sofe +h2sop +hs1org +h2spac +h4s3pani +h2s1par +h2s1pat +h3spec +h3spei +h2sper +h2sph +h2spo +h3spoi +h2sprä +h2spro +hss2 +h2staf +hst3alt +hst2an +h2stau +h2stäl +h2stäu +h4stea +h4stele +h4sterm +hs1tie +h2stin +h2stit +h2s1tol +h2s1tor +h3stö +hst3ran +h4s3treu +hstro2 +h2stu +h3stun +h3stü +h2s1u +hs2ung +h3sy +4h1t +ht1a +h2ta2d +ht2ag +ht4akt. +ht4akte +h2tall +h2talo +h2talt +hta2m +h2ta2n +ht3ane +h3tank +h3tanz +h2tap +h2ta2r +ht3arr +ht2as +h2t3asi +h2tasy +h2t3a2t +h3tat. +h3ta3te +h2tau +h3taug +h4t3ax +ht1ä +h2tär +h3te. +ht3e4ber +ht1ec +hte3cha +h2t1e2d +ht1eff +ht1e2he +h2teif +h2t1eig +h4t3eilz +h2t1eim +ht1ein +h2t1eis +h2t1eke +ht3elas +hte6l5ei. +h4telek +h4t3elfe +h4t3elit +hte4m +h2t1emi +h2temp +h3ten. +ht3engl +ht3enta +h4tentf +hter6de. +hterer6s +ht3erfü +h6terfül +h6tergeb +ht3ergr +hter6gri +ht1erh +hter6häl +hter8höhu +h6terleb +h6t5erleu +h6terneu +ht5erspa +hter8spar +ht3erst +h6tersta +ht3erwä +ht3erze +h2t1ese +h2t1ess +h2t1e2th +h2t1eu +h3teum +h3teun +h4textr +h2t3h2 +h4thei +h3thera +h3thes +ht4heu +h4tho +h2ti2d +h3tig +h2t1im +ht1i6n3 +h2t3ine +h2tins +h2tisr +htni2 +hto2 +h2t1ob +htod1 +h2t1of +h2t3oly +h2tope +ht1or +h2tord +ht3rak +h3tran +ht3rand +h2t3ras +ht3rat +ht6rates +ht3rau +h4traub +ht6raume +ht3rec +h3treck +ht3rei +h2trek +h2t3res +ht4ri +ht5ric +h4t5rieg +h2t5rin +h3trit +h2t3rol +h2t3ros +h2t3roß +ht3röm +ht3ru +h2t3rü +ht2sah +ht2sal +ht4s3a4n +ht2scr +ht4sein +ht2sel +ht4s3end +ht4seng +htse2r1 +hts3eri +htsha2 +ht3s4hak +hts3k +ht3skal +hts1o +hts3tät +ht4s3tem +hts2ti +ht4s3tur +ht4s3tür +htt4 +htti2 +htu2e +h2t1urs +ht3z2 +hu2a +hu2b1a +hu2bei +hu4bel +hu2b1en2 +hu2bi +hu2b3l +hu4b5r +hu2bu +hu2fa +hu2h3a +hu2h1i +h1uhr +h1uhu +hu2kä +hu2k1i +huk3t2 +hu2l3a2 +hu2lä +hule2 +hu2l1eb +hu2l1ei +hu2lem +hu4l3eng +hu4lent +hu2l1er +hu2let +hu2lid +hu2l3in +hul3l2 +hu2lo +hu2lö +hul3s +hu3m2a +h1umh +2h1ums +hu2n +h1una +h2und +hun3d2e +hunde3i +2hunf +hung2 +hun3ge +h1uni +h1unm +2hunt +h1ups +2hur +hur3g2 +hur2th +hu3sa +hus3h +hu2so +hus2s3a +hus3sen +husser4 +hus2s1o +hus2sp +hus4st +hu2ß1 +hu2tab +hu2ti +hu2t1o4 +hu2t3r +hut2t +hut4zen +hut4z3er +hut2zu +h2ü +hübe4 +h3über +h4übs +h3übu +hüf2 +hühne4 +2h1v +hvil4 +2hw2 +h2wall +hwe1c +h1weib +h1weih +hwein6sa +hweis4s +h2wirr +hyle4 +hyl4l +hy2lor +3hym +h1yo +3hyp +hy2pe. +2hy2t +2h1z +hz2a +h3z2o +hzug4 +h3z2w +i1a +i2aa +i2ab +iab4l +i2ache +i3ad. +ia3do +i2af +iaf4l +i2ag +i4ago +i2a1h2 +i2aj +ia2kei +ia2kr +i2aku +i3al. +i3a2l1a2 +ial3ar +ial3as +ia2lä +i3al3b4 +i3alc +i3al3d4 +i3a2leb +i3alef +i3alei +ia3lek +i3alel +i3aleng +i3alent +i3alerb +i3alerf +i3alerh +i3a4lerm +i3a2l1et +i3alex +i3alf +i3alg +i3a2lia +i3alim +i3a2lin +i3alj +i3alk +i5al3l +ial4ler +iall2i +i3alm +i3aln +ia2lon +ia2l1o2r +ial3p +i3alr +i3al3s +i3al3t4 +ia2l3u2 +i3alv +i3al3z2 +i2am +i3am. +i3amp +iampe4 +i3an. +ian2a +ia2nal +ian3alt +ia2nau +i3and2 +ia2n1e2b +ian2er +i3anl +i3ans +ian2s1p +i3ant +i3anw +i3anz +ia1o +i2ap +ia3pf +i2a1q +i3ar. +i2a2ra +i4ari +i3as. +ia3sh +i2asi +ia1s2p +ias5s +iast4 +i3at. +i4ate +i3at2h +i4athe +1iatr +i3ats +i3au +ia3un +iau2s1 +i2av +2iä +i1ä2m +i1äp +i1är. +i1ärs +i1ät +i3ä4tem +iä2ti +iät3s2 +2i1b +ib1art +i2b1auf +i2b1aus +i2baut +ib3be +ib2bli +i2b1eig +i2b1eis +ibe4n1 +i2b1ep +i6ber6geb +ibe1ro +i2bim +i2b1in +i2blad +i2bleu +i3blu +ib2o +i2bö +i2b3rau +i2b3ren +ib3ric +i2b3roc +ib2ser +ib4ste +ib2un +i2b3unk +i2b3unt +ibus1c +ibus3s +2ic +i3ca +ic1c +ich1a +ich6art. +ich1ä +i1che +ich1ei +ich2er +icherin5 +ichermas8 +ichgro3 +i1chi +ich1l +ich3le +ich3li +i3ch4lo +ich5m +ichmas4 +ich3n +i1cho +ich3ort +i2ch3r +ich6sele +ichsen3 +ich2s1i +ich6stie +ich4tab +ich4tan +ich4tin +ich2tr +i1chu +ich1w +i1ci +ic1in +ickt2 +i1cl +ic3la +i5cu +i1d +id2ab4 +i3d2ac +id1a2n +i3d2ans +i3dat +id1au +id2ax +idä1 +idbu4 +i2dea +1idee +2idel +idel4ä +i4demu +ide4n1o +iden4se +ide2on +i3der +4ider. +iderin8nu +ide1rö +ider6reg +ide3so +ides2p +2idia +1i2dio +idni3 +id2o +i2dol +2idoo +i2dö +2i2dr +i3dsc +id2set +id2s1p +idt4 +2idu +1i2dy +ie3a2 +ie2bä +ie2bl +ie2b3re +ie2bri +ie4b3rü +ieb4sto +ie1c +ie2cho +iech3t +ie2d3an +ie3de +ie2dr +ie1e2 +ie2f1an +ie2fau +ie2fäh +ief1ei +iefe2m +ief3f4 +ief2i +ie2f3l +ie4fonk +ief1r +ie2fro +ie2gl +ie4g5li +ie3g4n +ieg3r +ieg4ra +ie2gre +ieg2s +ieg4s3c +ieg4se +ieg4s1t +ie2h1in +ieh3r4 +i1ei +ie1ind +i2e2l1a +iel3d4 +i2ele +ie2l1e2b +iel1ec +iel3eid +ie2lek +i4elen +ie4lene +ie4leng +ieler4e +ieler6fi +ieler8geb +ieler6ke +ieler6la +ieler8lebn +iel4erw +ieles4 +ielf4 +ieli2d +i1ell +ie2lo4b +ie4lor +i2els2 +iel3sz +ielt2 +iel3ta +iem2e +2i1en +i3en. +i3ena +ien1a2g +ien2am +ie4nas +i3enä +i2ene +ien1eb +i3enec +i3e2nek +iener6fo +ien3er4g +iener6la +i3enex +i3enf +i3eng4 +ienge4f +ienge4z +i3enh +ie2nim +ie4n3in +i3enj +i3enk +i3enla +i3enle +i3enm +ienma3s4 +i3enn +i3e2no +i3enö +i3enp +i3enr +i3ens. +i3ensa +i3ensc +i3ens2e +ien3s2k +i3ens2p +ien6st5er +ien6stop +iens4tr +ienst5rä +i3en3sz +ien4tar +i3enth +i3enty +i3env +i3enw +i3enz +ie1o4 +ier3a2 +ie2rad +ie2rap +i2ere +ie4reck +ie4r3eis +ie3r2er +ierer3k +ie4r3erz +ie2ret +ierf4 +ierg4 +i1ergi +ierk4 +ierken4 +ierma6ss +i1ern +i3ern. +i2erni +ie1ro +ie2rö +ier4re. +ier4s3eh +ier3sei +ier3sta +ier3te +ier3z2 +ie3s2 +ie4san +i2esc +i2ese +ie4sh +ie4s3k +ie4spu +iesser6g +iess3ti +iest6e +ie4stin +ießer4g +iet1a +ie2ta2g +ie2tan +ie2tap +ie2tat +ie2tau +ie4t3ent +ie4t3erh +ie4t3ert +ie4tha +i4ethe +iet3her +ie2t3ho +ie2thy +ie2t1o4b +ie2t1ö2s +ie2t3ri +ie2t3ru +iet2se +i1ett +iet3zw +ieu2e +i2e1un +ie2w1u +i1e2x +2if +if1ab +if1ar +i2f3arm +if4at +i2f1au +if1än +i2fec +i2f1ef +if1ein +if2e4n +i2f1erg +if1erh +if2fa +iffe4s +if6feste +if2f3l +if4form +if2fro +iff2s +iff4ste +if3l +if1lac +i1f4lä +iflo4 +if4los +i1flü +if3r +i1fre +if4rev +ifrü4 +if3sa +if4t3a +if2ted +if2t3ef +if2t1ei +if2te2l +if2tep +if4terk +ifte4s +if4t3esc +if2t1op +ift1r +if2tra +if2t3ri +if2tro +ift1sp +ifts2t +ift3sz +if2tur +i1fy +2i1g +iga1i +i2garb +ig1art +iga3s +i2g3att +igd4 +i6gebrau +i4gefar +ig1ein +ige4na +ige6nene +ige4nid +igen5s +ige2ra +igerma3 +ig5erwer +ig1erz +iger4ze +i2g1ess +i2gim +i2gl +i4glag +i4g3lim +ig4na +i4gnä +i3g4neu +ig4no +i3g2o +igo1p +ig3rad +ig3re +ig4ren +igro3 +i2grou +ig3sa +ig4sal +ig3sä +ig4schr +ig1s2o +ig1sp +ig2spa +ig4sti +ig2s1to +ig2stö +ig6stra6s +ig4stur +2i1h +i2har +i5hea +ihe1e +ih1elt +ihe4n +ihe1u +ih3m +ih3n +ih3r +ih2s +ih3sp +ih3sti +ih1um. +ih1w +ii2 +ii3a4 +i1ie +i3ig +ii3h +i1im +i3in +i1i4s +i2is. +ii3t +i1it. +i1j +1i2js +2i1k +ika2ge +ik1ak +ikaken3 +i2kakt +ik3amt +i4k1ang +i6kantei +ikanten8n +ik1art +ik3att +i2k1au +i3kaz +ik1äh +i2k1än +i2kär +4ike +i2keb +ik1ebe +i2k1ed +i2kef +i2k1ei +ike4l1 +ike2n1 +i2k1ens +ike2ra +i2k1e4r2e +i2k1er2f +i5kerfam +i2k1er2h +i2ker2l +i2kero +i2ke3ru +i2k1eta +i3ki. +i3kie +ik1in +i2kins +i2k3l +ik4län +i3k4leri +i3k4let +ik4lim +i3klu +i2kne +i2k1off +iko1p2 +ik1o4ri +ikot3t +i2köl +ik3rä +i2kres +ik4ris +i2krö +ik3sa +ik3s2z +ik3ta +ikt3erk +ik4t3esk +ik2t3re +ikt2u +i2k1uh +i2kup +i3kus +i2kü +i1la +i2lab +ila2br +i4labs +i2l1ac +i2l1ak +il3a2ma +il1anm +il2anz +ilan6zer +i2larb +il1asp +i2l1au +i3laub +i3l4aufb +ilau2s1 +i1lä1 +i2lär +2ilb +il2c +il5chen +il2da +ild3ebe +il4d3en4t +il3der +ild4erp +ildi2 +ild1o +il2dor +il2dr +ildwe4 +2ile +il1ec +ileid4 +il1ein +il1el +i2lemb +il1ent +i4lentl +i4lents +i2l1erd +iler4ei +i6lereig +il1erf +iler4fo +i2ler2g +i2l1er2h +i4lerkl +il1err +i4lerri +il2erz +ile4th +il1ex +ilf2 +il2f3l +il2f3re +ilf4s1 +il2gl +2ilh +2ili +ili3e4n3 +iliga2 +ili4g3ab +ilik4 +i2l1ind +i4l3init +il1ins +i2l1ip +i3lip. +i3lips +il2lad +ill2an +ill4ant +il2lä2 +il2leg +ille4ge +il4lenn +il3l2er +1illu +il2mak +il2m1ap +il2mau +ilm1ei +il2min +il2mor +2ilo +il1ob +il2of +il2oh +il4on +il2op +i2l1or +i3lou +il1ox +il4sein +ils2to +ilt2 +il3t4h +i1lu +i2lum +il1ur +i3lus +ilü4 +2ilv4 +il2zar +il2zau +ilz1er +il2zwa +imad2 +ima3i +im2al +i2m3anh +i2mans +i2marc +im3aren +i2m1arm +i2m1art +im4at +imat5sc +ima4tur +i2maus +i2maut +i2meg +im1ein +i2mej +i2mek +i2mele +i2melf +im2en +i2m1erf +i2m1erl +i2m1erz +i4me3sh +imes3s +i2meti +i2mew +i2m1i2d +i2mim +i2m1ind +i2minf +i2m1ins +3immatr +immen1 +imm3ent +im6menth +im2mit +1immo +im4mo2d +im2mö +imni2 +2imo +i2m1ob +i2mo2p +i2mö +1imp +imp2fa +im3pfo +imp2s +im3pse +2imt +imt2e +im3t2i +imts2 +imtu2 +2imu +im2um +im1urk +2in. +in3ab +ina2be +in1ac +in1ad +i4n3ae +i3nald +inaler4 +ina6lere +in2alp +in1am +in2an +in3ana +in3ann +i2narb +i2narm +in2ars +in3att +i2n3au2 +inaus1 +2inä +i2n1äh +in2är +in1äs +2ind. +inda2 +ind2ac +in2dal +in2dan +2indä +in3de +2inde. +ind4eid +2inden +ind5erke +inde3sp +indes4t +1index +ind2i +1indik +in3dö +2indr +ind4ri +ind3se +1indus +in3d2ü +2ine +i4ne4ben +in1ec +i3nee +i2neff +in4elen +in2em +ine3nä +i2neng +i4n3enzy +i5ner. +i4n3erbi +in2erh +in3erle +i6ner6leb +iner4lö +i4n3er4tr +i3nes +in2et +in1eu +ine3un +ine2x +in3f4 +1infiz +1info +2ing +4inga +in2g1af +in2g1a2g +in2g1al +in2gam +ing1ar +in2g3at +3ingeni +in3g2er +in4g3erw +in2gl +in3gla +in3glä +ingmas4 +in2gor +ing4sam +ings6por +ing4s3pr +1inhab +2inhar +2inhau +2inhe +in2i3d +2inie +2inig +ini3k4r +2inis +ini3se +init2 +i3nitz +3inkarn +1inkas +in4k3ent +ink4er +inks1t +ink4ste +in3k2ü +inma4le +4inn. +inne4n +in4ner4m +in2neu +in4ni2v +4innl +in2nor +1innta +2ino +in1od +in3ols +in1or +inost2 +i3no3t +i2n1ou +i1nö +in1ö2d +2inri +ins2am +in6samt. +insch2 +2inse. +in2seb +2insed +2insen +ins2i +2insk +in4sm +3instal +in4s3tät +2inst2e +3instit +4instra +in4strü +1insuf +ins3umz +in2sur +in3s2z +2inta +in3te +2inte. +1integ +2inth +inthi1 +in3ti +int2o +2intö +2in3t4r +4inträ +3intrig +int3s +i2n1u +i4nuh +in3unz +inu3t +4inverm +invil4 +i1ny2 +in3z2e +inz2i +inz2u +in3zwä +i1ń +2i1o +ioa4 +io1c +io2d +io3du +io3e4 +i2of +iof4l +i2oh +io3k6r +i3ol. +i3om. +io3me +i3oms +ion2 +i3on. +ion3an +io2n3au +ion3d2 +io4nee +i3onn +io2nor +i3on4s1 +ions3a +ions3el +i2ony +i2oo +i2o1p +i3o4pf +i3opt +i2or +i3or. +i3orc +ior2e +iore4n +io1r2h +i3orp +i3ors +i3ort +i3os. +io3sh +io5ska +i2ost +ios2u +i2o3sz +io3t +i3ot. +iot4r +i3ots +i2ou +i2ov +i3o2x +i3oz. +i1ö2k +i1ön +i1ös. +i1ö4st +2ip. +i1pa +ip2an +i1pe +i3per +2ipf2 +i3pfan +iph2 +2i1pi +ipi3el +ipi3en +i2poi +ip2pan +ip3pe +ipp1f +ip4pl +i1pr +2ips +ip2sa +ip2sei +ip2sp +ip2sta +ip2stü +ipt2a +ipt2u +2ipu +2i1q +i1r4a +i3ra. +2i3rad +i3ras +irat2 +i1rä +ir1äh +ir2bl +ir1c +ir2ch1o +ir4e +i3ree +2irek +ire4na +i3ré +irg2 +irg4s +ir2he +ir2i +iri3a +2i5rig +2irk +irke4n +ir4kene +ir2k3l +irli4n +ir2m1a2g +ir2mak +ir2mau +ir2mä +ir2m1ei +irme4n1 +ir2m1o2 +irm4th +ir2mum +ir4munt +2irn +ir2n3a +ir4nat +ir2no +i3ro +1iron +i1rö +irpla2 +ir2rei +irre4l +ir4reli +ir2rh +irs2 +ir4schl +ir4schm +ir4sch3r +ir4sch3w +ir3se3 +ir3sh +irt2s1t +2iru +ir1u2m +iru2s1 +i3r2ü +i1s +i3sac +i4samp +i4s1amt +is2ap +isa2r +is3are +i3sat +i2sau +is3auf +isau2g +i2säh +i2s1än +2isb +i2sca +i2sce +i4schar +i3s2che +i4schef +i4sch3e4h +isch3ei +i6schemi +i6scher6z +i4schin +i5sching +i2schl +i2schm +isch3ma +i4schna +i4sch3re +isch3ru +i6schüb +i4schwa +i6schwir +i4schwo +isch3wu +i4schwü +i2scr +2ise +ise3a +ise1e +iseh2a +ise3hi +is4eind +i4seint +is2el +ise3li +i6sel6ter +ise2n1 +ise4n3a2 +is2end +isen3s +ise4r3ei +is1erg +i2serh +i2s1erm +i2s1es2s +is2et +i4s3etat +i3s2eu +2isf +4ish +isi2a +i2s1i2d +i3sin3g4 +i4ski +i4sku +is3la +3islam +2isma +2ismi +i2s1of +1i2sol +3isom +is2o2n3 +isonen4 +iso6nend +i2sop +is1org +is1ort +3i2sot +2isp +is1pa +i2spar +is1pe +is1pic +is2por +i2spro +is3sa +is4s1ac +is4sau +is3sc +iss3che +is3senk +iss3erf +issermas8 +is3so +is3sp +iss2po +is2st +is3sta +is4ste +is3strä +is3stu +is2su +i2stab +ist3ac +is4tal +i4stam +ist2an +i4s3tang +ist4e +i4stea +i4s1tec +iste4n +ist2id +ist6o +ist4ra +is3tras3 +ist3rei +i3stro +i2stur +is1tüm +i3suf +isum3p +i2sü +i1ß +iß1er4s +i1ta +it1ab. +it1abs +i3tag +ital3a +ital5l +it1alt +it1a2m +it1an +ita3ne +it3anr +ita2po +it1app +it1a2re +it1art +i3tat +it1au +i3tauc +i2tauf +i2taut +4i1tä +it1änd +i2t1äs +ität2 +i1te +it1eff +i2t1ei +it2eic +i4teig +i4tein +i4teis +2itel +ite4l1a +i4telek +i2temp +ite2n +i3ten. +i2tepo +i6tereig +it2erö +i8t7ersche +i2t1esk +i2t1ex +i3text +i3thr +i1ti +i3tic +i2tid +i3tig +1itii +iti3ker +it1in1 +i3tis +i4tiso +iti3sp +i4tiss +i3tiv +iti2v5a +itmen2 +4i1to +i3to. +it1ob +ito4be +i3toc +i2t1of +it1o2p +it2os +i1tö +2i1tr +it3raf +it3ras +it3rau +it3räu +it3re +i2tref +it4ret +it3rob +it3rom +i2t3run +it2sa +its1a2g +it2s1e +it4se2h +its3e2r1 +its1o +it4stec +it4s3tem +it4sten +it4s3tes +itstra6s +2itt +it2teb +it4temp +itt3hä +it2t1o4b +it2top +it2tri +itt3rol +itt6schi +itt4seh +itt4sei +itt4sti +i1tu +it1uh +it1ums +it2ung +i2tuns +ituran4 +it1urg +itut4 +i1tü +2itz +it2zec +itz2er +itz3erg +it6zergr +it4z3erl +it2z1w +2i3u2 +ium1 +iuma4 +ium2se +iun2 +iungs3 +ius1t +i1ü4 +2i1v +i2v1ad +i2v1ak +i2v1am +iv1an +i2v1ä +i2veb +i2v1ef +iv1ei +iv1elt +ive4n +iv1ene +i2v1ent +ive3re +iver8folge +iv1erh +iver4kl +iv1erl +iver3s +i2v1e4x +iv1ins +i3vol +i2vr +i2vun +i2v1ur +2i1w +2i1x +i2xa +ix2em +ixt2 +4i1z +i2z1ag +i2zan +i2z1ap +i3z2as +iz1au +i2zaus +i2zän +izei3c +izeit3s4 +i2zele +ize2n +i4zener +iz1erg +i2z1erl +iz1ir +i2zo2f +i2zö +i2zuna +i2z1w +i3z2wi +izz4a +í1l +j2a +jab4 +jah4r3ei +jahr4s +ja3l2a +ja3ne +jani1 +jani3t4 +ja5ru +jas2o +jat2 +je2a +jean2s +je2g +jek2t3a +jek4ter +jek4tin +jekt3o2 +jektor4 +jek2t3r +je2p +je2t1a +je4t3h +je2tin +je2tor +je2t3r +jet3t +je2t1u2 +ji2a +ji2v +joa3 +jo2b1 +job3r +jo4da +jo2i +jong2 +jo1r2a +jord2 +jo2sc +3jou +jou4l +j2u +ju2bl +jude2 +jugen6 +jugend3 +ju1i +ju2k +ju3l2 +jung5s2 +ju3ni +ju3r4a +jur2o +ju3t2e1 +2j1v +1ka +3ka. +ka3ar +2k1abb +kab2bl +2kabd +2k1a2ben +2kabf +2kabg +2kabh +2kabn +2k3a4bo +2k1abs +2k1abt +2kabw +2kabz +ka1c +kade2r +2k1adm +2k3a2dr +3kadu +2kadv +ka1f4l +ka1fr +kaf3t2 +kag2 +2k1age +3kah +ka1ho +ka1in +kaken2 +ka1k4l +2k1akt. +4kala. +kala3b4 +ka2lan +kal3d +ka2leb +ka4l1eh +ka4lens +kal3eri +3k2alk +kal2k1a +kal4kan +kal2k3l +kal3l +kall2i +kallö3 +2k1allt +ka2lop +ka2l1os +kals2 +kal4tex +kal4th +ka2lu +k2amt +3kana +kan4al +ka4n1a4s +ka2nau +3kanä +2kanb +kan3d4 +2kanda +2kandä +kan2e +2kanf +3kani +4kanim +kank4 +2kanl +2kanom +2k1anor +2k1ans +k2ans. +kan4tar +6k5antenn +2k1anth +ka3nu +4kanw +2k1anzu +2kanzü +ka2o1 +3kara +2karbe +2karc +k2ard +kar3d2a +k1area +k2arg +ka3r2i +kari3es +k2ark +2k1arm +kar2pf +k2ars +k2ar3ta +k2arte +k1arti +4kartik +karu2 +k2arw +3k2asc +kasi1 +kas2o +ka2sp +kas2t +2k1ast. +ka3sta +ka4ster +3kasu +ka3sz +ka2tan +3kateg +ka3t2h +ka2t3r +kat3se +2katt4 +kau4fer +kau2f1o +kauf4s3a +kauf4sp +kauf8s7tem +k2aus. +2kauss +2kausw +kau3t2 +2kauto +2kaz +1kä +k1ä2mi +kär2 +2k1ärg +kä2s5c +käse3 +kä3th +4k3b4 +kbe1 +kbo4n +kby2 +2k3c +2k3d4 +ke2ben +2k1ec +ke2di +k1ef +2keff +kefi4 +kege2 +ke2gl +ke2he. +ke2hen +kehr2s +kehrs3o +2k1eic +2k1eig +kei2li +2k1ein +ke1in2d +kein4e +k1eis +2keise +keit2s +ke2la +kel1ac +ke3lade +ke3lag +ke4l3am +kel1au +ke2lä +kel3b +keld4 +kel3eis +2ke2lek +ke2l1en +ke2l1er +kel3la +kel7l4e +kell2i +ke2l1o2 +ke2lö +kel3sk +k4elt +ke2mi +2k1emp +k2en. +ken1a +ken3au +kenbu5s4 +ken3dr +ke2n1e2b +kenen1 +ke4nene +ke4nens +kener4n +4ken4gag +k5en6gel. +ke2nim +ken3in +4kenlad +4kenläd +kenmas8sen +kenn2a +kenn2e +ke2no +4kensem +ken3s2i +ken3s2k +ken5s4te +ken3sz +k3en4te. +ken6ten. +4kentf +2k1entg +ken3th +2k1entl +2k1ents +2kentw +2kentz +ken3z2 +2ke1o2 +2kep +ke2pl +k2er. +ke1ra +ke2ran +ke2rau +ke2r1ä +ker4ble +k2erc +4kerd +ke2re2b +ke3reig +ker3ein +4kerfah +k4erfam +ker2fo +ker5g +k3ergeb +2kergu +ke6rin6nu +kerin6st +kerin4t +k3erken +k2erko +k2erl +k3er4lau +k3erleb +k6erlebe +ker2na +ker4nei +4k3erneu +ker6n5eur +k1ero +ker8oberung. +ke1rod +2k3eros +ker4reg +k2ers. +2kersa +kerz2 +k1erz. +ker4zeu +2k1er2zi +k6es. +ke2s3a +k1ese +ke2sel +kes2sa +ke2t1a +ket2ag +kete4 +ke4t1eb +ke4tel +ke4th +ket3ha +ket3s +ketta4s +kett3h +ke2tu +ke1up +keu6schl +2k1e2va +2k1e2x +4k3f4 +2k3g2 +kga4s1 +kge3s2 +2k1h4 +kho3m +k3hu +ki3a +ki4ad +kia2r +ki1ch +2ki2de +ki3dr +k2ids +2kidy +ki2el +kie4lei +kiel3o +2kiern +kier2s +kie4sa +kie2z +ki1f4l +ki1f4r +ki3k4 +2ki3l2a +2kilä +ki3lo +3kin. +4kindex +2k1indi +2k1indu +2k1inf +king3s +2kinh +k2ini +kini3k2 +k2inn +ki3n4o +kin3s +2k1inse +2k1inst +2k1int +ki3or +kio4s +3kir +2k1i2so +kis2p +kis5s +kist2 +kiv2 +kive4 +2kiz +2k3j +2k1k4 +kkab4 +kl4 +4kl. +4kla. +2k1lac +klan2 +2kland +klan3du +k4lar +k1last +k1lauf +k3laug +2k1läd +k2lär +k2le +4kle. +kle2br +k3leg +2kleh +k3leit +k3lem. +2k3ler +kle2ra +2k3leu +kle3us +2klic +k2lien +k2lif +2klig +3k2lim +k2lin +k3lin. +3k4lina +k4link +k2lip +k2lir +k2lisc +2klist +klit2s +2k3liz +2k3loc +klo2i3 +2klok +3k4lop +k3lor +klos2 +2klose +klo3sse +klost6 +2klöc +2klöf +k2löst +k4löt +k1lu +klu4b +k2lud +k2lug +k2lum +2klux +2k1lüc +2kly +2k1m2 +4kma +kma2la +kmas2 +kma3sse +k2n2 +2k5nach +2k3nad +2knah +2k5nam +2k3näp +k3ne +k4nec +kne1e +2knes +2knetz +2k5neu +2kney +kni4e +2k5niv +kno2bl +k4nol +2knorm +2knov +k3nu +2knum +k6nur +1ko +ko5ad +ko2al +2k3oas +kobal2 +2kobj +kob4s +2k1o2fe +kof3f2 +koh4a +kohl2e +kohle3i +koh3lu +ko3l2a +ko3le +kol2k3 +3kom +4k3omn +ko4mu +k2on +ko2nem +kon2i +kon3s4 +kont6e +ko2nu +2kop. +2ko1pe +kopfa2 +kop4fen +kop6f5err +2kops +ko3pte +2kopz +ko3r2a +kor2ba +kor2bl +kor2br +2k1orc +korden3 +korder4 +kor6derg +ko2rel +2k1org +ko3ri +kor3m +kor4nac +kor2n3ä +kor4no2 +2korpi +k2os +ko4sk +ko2s1p +3kost +k3osz +ko2ter +ko3ti +kot4r +kot1s2 +kot4tak +k1ou +ko3un +3kow +ko2we +2k1o2x +1kö +k2öf +k1ö4l +2k1p2 +2k3q +k2r2 +2k3rad +2k3rah +k4ral +kras3 +kra4ss +k3rats +2kraum +k4raw +k4raz +k4räc +2kräd +k4rän +2k3räum +2k5re. +2k3reak +2k3real +2k3rec +2kred. +2k3rede +2kredn +2kredu +2k3ref +4kreg +2k3reic +kre1i2e4 +kreier4 +k3reif +2k3reih +2kreim +krei6sei +kreli1 +k3ren +k3res +2kresu +k3rev +2k3rh +2krib +2k3ric +2k3ries +2krip +k3risi +krob4 +k4roch +4k3roh +k4roi +k4rok +k4ron +k4rop +kro4ss +kro3st +2krot +3kroth +k3rou +2kröh +2kruf +2k3run +4k1s +ks3ab +k3sac +ksa2k +k4s1amt +k2san +ks3a2r +k2sau +k2sav +k2säh +ksch4 +ks2chi +k2s1e2b +k2s1ec +ks1ei +ks2eid +ks2eif +k4seind +ks2end +k2s1eng +k2s1ent +ks1er +ks2ere +k2serf +k2serg +k2serk +k2serl +k2sers +k2serw +k2s1e2v +k2sex +k2s1i2d +k2s1in +k4s1is +ks3kl +k4sm +kso2 +k3s2on +k2sop +k2s1or +k2sö +ks1pa +k2spal +k3s2pat +k2spä +k3spe +ks2pel +ks2pen +k2sph +ks2por +ks2pul +ks5s2 +kst2 +k2stal +k4s3tanz +kstat4 +ks3tat. +k3stäl +ks4tel +ks1tie +k4stier +k2s1tis +k2stit +k2s1tor +k4strop +k2stuc +k2stum +k2s1tur +k2stüt +k2s1u +k3sul +ks2zen +4k1t +kt1abr +kt1abs +k2t1ad +k3tag +kt1akt +k3tal +kt1am +k2t1an +kt2and +k2t1a2r +kta4re +kta3ri +k2t1au +kt3aug +ktau2s +ktä3s +kt1äu +kt1ein +k2t1ela +kte3li +kte4n1 +k2t1ent +k4tentl +kten3z +kte1ra +kt4ere +k4t3erfo +kt1erg +k2t1erh +k2terö +kte3ru +kt1eta +k2tex +k2t3h +k2ti2d +kti2me +kt3ing +kt1ini +kt3inn +k2tins +kt2is +kti2s1e +kti2st +kti4ter +k2t1of +k3t4ran +kt3ras +k2t3rau +kt4ro +ktro3me +kt3run +kt3rü +kt1s +kt3s4a +kt3sä +kt3se +kts2el +ktsen1 +kts1o +kt2sor +kts2pa +kt3s2z +ktt2 +kt1ums +k2tuns +kturen4 +kt3z +ku2al +ku1c +kud4r +3kug +ku2h +2k1uhr +kuh3s +ku3la +ku3l2e2 +ku3l2i +2kulp +kul2to +kul2tr +kum2e +2kumg +2k3uml +kum2s +k2u3n2a +kun3da +kun4s +kunst3 +2kunt +2kunw +2k1up. +kur2bl +ku2rei +kuri2e +2k1urk +ku2ro +kurs1c +kur2sp +kur4ste +kur4str +2k1urt +kus3a2r +ku4schl +ku2sp +kus3ses +kus1ta +ku2su +ku2ß +2kut. +1kü +kü1c +3küne +3kür +kür2s +2k3v +2k1w +k3wa +2k3z2 +kze3l +3la. +la3ar +l1ab +3l2ab. +la3b2a +l2abä +2labb +lab2br +2labd +2la2ben +4labf +4labg +2labh +3labil +la2bit +2la2b3l +2labn +3lab2o +4labo. +la3b4ra +2labs +la2bus +2labw +2labz +la1ceb +l2ache +lacks2 +1lad +2l1ada +2ladd +la3de. +la3d2i +2ladj +2l1adl +2ladm +2l1a4dr +3l2adu +2laf +la2fa +la2f1ei +laf1r +laf3t4 +la2fu +3lafü +la2ga +lag3d +l2ager +4lagg +la2gio +lag3l +la4g3n +lago4 +la2gob +2la1ho +3lai +lai4s1t +lake2 +la2kin +l2akk +la1k4l +la2kro +lak3t +2l1al +3lala. +la2lar +3lali +4lalt +l2ama +lami3t +lam2m1a +lammen8ge +1lammf +2lamn +la2mor +l2amp +l3ampu +2l1amt +lamt2s +la4mun +la2na +la3nad +l1anal +la3nan +la4nat +la4nau +2la2nä +3l2and +lan2da +lan4dam +land3au +lan6d5erw +lan6d5erz +lan6d5inn +lan2d3r +la2nem +lan3erd +laner4f +2lanf +lan6g5esc +lang3s2 +2lanha +l2anhe +2lanl +2l1ann +l1ano +la2nof +2l1anp +2lans2 +l1ansi +l4ant. +2lantw +2lanw +lan2z1w +3lao +2l1apf +la2ph +l1a2po +lap2pl +la2r1an +2larc +lar1e2b +la2r1ei +la2rel +la4rene +larf4 +lar3g +lar3ini +la2ro +2l1arom +l1ar3t +lart4h +l3arti +3laru +l2as. +la4sam +la4sä +4lasd +la5seb +la4sei +la4s1e2l +l2asg +2lash +la2sin +la4sis +2lask +la2so +2la2sp +3lasser +l2ast +la2sta +last3an +la4steu +las2to +la2str +last3ri +las3tro +las3tur +la2stü +1la2ß3 +lat2ak +la3t2e +la4tel +la5t4i +2l3atl +2latm +lat2o +la2tö +la2t3ra +lat4ri +lat6schm +2lat4ta +lat4tex +lat2th +lat4t3in +lat2t3r +latzer4 +1laub. +lauben6s5 +lau2b3r +laub4se +laub4st +lau4fin +lau2fo +lau4fri +1laug +lau3gl +3laun +4laun. +la4us +2l1ausb +lau6scha +2lausd +2lausf +2lausg +2lausl +2lausr +2lauss +2lausz +2lauto +lau2tr +la3va +lave4n +1law +lawa4 +l2ay +lä1c +2l1ähn +1länd +l1äpf +2läq +lär4mar +l1ärme +2lärz +lä2s5c +lä4s3s +2lät +2läub +2läuc +2läue +1läuf +2läug +2läx +1lŕ +4l1b +l3bac +l2bant +lb3a2ri +lbau1c +lb1ärm +lbb4 +l4b3eink +l4b3eise +lbe4ral +lbe3rei +lberin5 +lbe7s +l4b1e2ta +l2b1id +l2b1ins +l3b4lat +l3b4lä +l2b3led +l2bli +l3b4lo +l3b4lö +l3b4lu +l2b1o2ra +lb3rea +lb2s2 +lb3sa +lb3se +lb3si +lb3so +lb3sp +lbst3ac +lb4ste +lbst3ei +lbst1u +l2b1uf +l3bum +lbu4n +lbus3s +lbzei2 +2l1c +l3ca +lch2au +l3che +l4chei +l4chent +lchermas8 +l3chi +lch3le +lch3li +l3chlo +lch3n +lch1ob +lch3r +lch3s2 +lch3ü +lch1w +l3cl +l3co +4l1d +ld3a2b1 +ld2ac +ld3ack +l2dad +l2daf +lda2g +l2d1ah +l2d1ak +l2d1al +l2d1a4n +ld3ane +lda2r +l2d3ari +ld1arm +ld1ass +l3dat +l4d3ato +l2d1au +ld3au4s +l3däm +ld1är +ld1ät +ldbus2 +l3de. +lde4ben +l2dein7 +l2deis +l2d1elf +l2d1e2mi +l2d1ems +lde4na +lden5erg +l4dentl +l3der. +l4d3erfa +l6der6geb +ld1erh +l4der4he +l3d2erl +l6derlas +l6derlaß +l3d2ern +l2d1er2p +lder4tr +lde3sa +lde4sel +l2d1es2s +l2dex +ldi2c +ld1id +ld1i4mi +l2dob +l2dop +ldo2r +l2d1ori +ld2os +ld2ö2 +ld3r +ld4ram +l2dran +l2drec +ld5rie +ld4ris +l3d4ru +l2drüc +ld3sa +ldt4 +ld3th +ldt5s +ld3tu +l2d1ul +l2d1um +ldy2 +1le +3le. +le2ad +le3ar +le2as +3le3ba +leben4s3 +le2bl +le2b3re +2lec +lech1a +le2chi +lech7t6e +le2er +le3f2a +2l1eff +le2g1ab +leg1as +le2gä +lege1i +le2gl +3leg4r +3leh +4lehe. +leh3r2e +4lehs +4leht +lei4ble +l2eid +leif1a +lei4fan +lei4fei +leifer6g +2l1eig +3leih +lei3l2 +leim3p +l2ein. +leinbu4 +leinbus5 +l2eind +lein4du +l4eine +lei6nerb +le2inf +le2ini +4leink +4l1einn +l3einsa +2leint +l2einu +le4is +leisch5a +lei8schei +lei6scho +lei6sern +l1eisf +lei6ss5er +leis3st +lei4ßer +l2eit +lei2ta +leit3sk +leits4t +3leko +2lektr +2lekz +3l2ela +le2le +le3lei +2lelek +6leleme +le3len +le3les +2lelf. +l2eli +lel3s +l2em. +le2m1au +le2m1ei +3lemes +3lemet +lem1o2 +le2mor +2lemp +le2mu +le4mun +l4en. +len1a +le4na2d +le4n3an +le4n3a2t +2lency +l1endp +4lendun +l4endur +le2n1ed +4lenerg +le4neur +4leneuv +len4gag +len4kau +len4k3lo +len4klu +l1enni +len6sein +4len4sem +len6serk +len3ska +len3sz +2l1entk +4lentla +2lentn +4l3en4tro +4l3entw +lent4wä +5lentwet +2lentz +2l1enzy +leo2f +le1os +2lep +3lepa +3lepf +4l1e2pi +lep4pi +3lepr +lep5t +l2er. +l2e1ra +le2rag +le2rap +le2ra4s +le2rau +le2r1ä +le2re2b +ler2ec +l3ereig +le4r3ei4m +le4r3eis +le2rel +le4reng +le4rerg +lerer5k +le4rers +l3erfas +2l1erfo +l2erfr +l2erfü +l1erg +l2erga +l4ergef +3lergeh +6lergen. +l4erger +l4erges +3l4ergew +2lergi +l2ergl +l2ergr +lergro3 +4l3erhol +lerin4s +lerk2 +l2erka +2lerke +l1erkl +4lerklä +l4erkle +l2erko +ler3kr +ler3l +5l6erlebe +3l4erlei +2lermä +ler4nal +3l4erne +ler4nei +2l1erö +3l2erra +ler4ric +l4ers. +l1ersa +ler4sto +le2rup +l4erwa +ler4wer +2ler2wo +2l1erz +ler2zä +l3erzeu +ler2zo +l4es. +les2am +les2e +le3seb +le3sei +2l1esel +le3s4h +lesi1 +le3sk +les4ki +les2ko +le2spo +les3se +les3si +lest6 +leste3r +lester6i +3lesu +4lesw +2lesy +2le2tap +2le2tat +le2thi +let2i +letsche6 +let2to2 +lett1r +lett1s2 +le2u +4leue +3le3u2f +l2euk +2l1eul +le3unt +3l2eut +le2vol +2lex +3lexik +le2xis +3ley +4l1f +l3fah +lfäs3 +l2f1ec +lfe1e +lf3einh +l2feis +lf2en +l4ferei +lfe4rel +lf1erl +l3fi +l3f4lä +lf3led +lf3lo +l3f4lu +lf3ram +lf3res +lf4ru +lf4rü +lf2spe +lf2s1ti +lf2su +lfun2 +lfur1 +2l1g +l3gas +lga3t +lgd4 +lgen2a +lgeräu3 +l2geti +l3g2i +lg2lö +l3go +lgoa3 +lg4p +l3g4ra +l3g4ro +lgro3s +lg2s +lg4s3t +2l3h2 +4lhe +3lhi. +1li +l4ia +li2ad +li4am. +lian2g +li2ast +3lib4 +libi3 +li1c +lich4ta +lich4to +4lick +li2cl +li3d2a +2l1ido +li4ds +liebe4s3 +li1efa +3liefer +li1efk +li3efl +lie4n1a2 +li3ene +lie4rei +lie4s3c +lie4sta +lif4fes +lif2fo +3lig +li4g3ers +lig4n +lig4ra +li2gre +ligs2 +li3ker +li3k2o +likop4 +lik2sp +lik4tau +lik4ter +lik2t1o2 +lik2u +li3l +lil2a +li3m2a +lima1c +limat4 +2l1imb +2limm +3limo +2limp +lin2a +li3nar +2l1indu +li2nef +li2neh +li2nep +li5ner +li2nes +2l1inf +2l1inh +lin1it +2l1inj +lin4kan +lin4kar +link2s +li2nol +l2ins. +l2insa +4linsel +2linsp +2linst +2l1insu +2linsz +2l1int +li3nu +2l1inv +2linz +li2o +li4om +lion5s +3li1pf +3lipt +3lis. +li3s2a +li3schm +li4schu +4lis2h +li3shi +2l1isl +2lisol +2lisot +li2sp +liss4 +2liß +lit4a +li2tal +li3t2ä +l2i3t2e +li1th +li2t3r +lit1s2 +lit3se +lit3sz +li4tun +li2tur +litz4er +3liu +liv2e +li2vea +li2ves +livi3e +li3vr +4lixi +li2zau +li2z3ä +lizei3 +4l3j +2l1k +l3kale +lk1alp +l3k2an +l3kap +l3kar. +l3ke +lk1erd +lke3r2e +lk2l +lk3lad +l3k4las +lk3lic +l3k4lu +lk2men +lk4ne +lk5ner +lkor2b +l2k3ru +lk2s1 +lkse2 +lk4spe +lkt2 +lk2ü +4l1l +lla2be +l2labk +ll2abr +l2labt +l3labu +ll3acht +lla2de +ll1aff +lla3gl +l2l1am +ll3a2ma +ll2anb +lla4ner +l2lani +l3lans. +ll4anwa +ll1anz +ll3appr +ll1arm +lla6tern +l2lath +l4latm +l2l3att +l2lau +ll3aufg +ll3aufk +llau2s1 +l4lausf +ll3aust +l2la2w +l2l1äm +l3läs +l2läu +llb2 +llch4 +lld4 +l2le2b +ll5ebene +l3lec +ll1ech +lle3er +l2l1ef +lle2gu +lle2he +l2leib +ll1eic +ll1eim +l4l3eise +lle2la +l3len. +lle4na +ll3endl +llen3dr +ll3endu +llen6dun +llen5se +l4lentf +l4lents +l3lep +l3ler. +lle2ra +l3lere +l6lereig +ller4fo +l8lergene +l4lergo +l4l3ermi +l4l3ernt +ll3ertr +ll6erwei +ll2es +l3les. +l2le2se +l2leuc +l3leur. +ll1exe +llf4 +llg2 +l2lieb +l2lieg +lli4gan +l3lik +lli4la +l2l1ind +l4linf +ll1ins +llin6sen +l2lipo +ll3k4 +ll5m2 +ll3n2 +ll1ob +l2lobe +l2lo2d +l2lof +llo2ge +ll3ol +ll1opf +ll1or +l4lorb +l2lo2ri +llo2te +l2l1ou +l3low +llö2g +l3löh +ll2säu +ll2s1es +ll3ska +ll2spr +ll4stor +ll3t +llt2e +llt2i +llti2m +llt4r +llts2 +llu2d +llu2me +l3lung +l2lu2p +ll1ur +llust6 +l3lut +l2lüc +llü2d +l2lü2g +l3ly +ll3z2 +4l1m +l2m3a2b +l2m1ad +lm1a2ge +lm1aka +l2m1a2m +l3mana +lm1apf +lm1art +lm3att +lmä2s +lm1ä4st +lm1c +lmd2 +lm3e4dit +l2m1ef +l2m1e2p +lmer2 +l2m1erf +l2m1erl +l2m1erz +l4messa +l2m1id +lm1ind +lm1ins +lm3m +l2mof +lm1orc +lm3p2 +lmpf4 +lm3s2k +lms2t +lm3str +lm3s2z +lm3t4 +l2mum +l4munt +4ln +lna2r +ln3are +l3n2e +lnes2 +l2nin +lnus2 +l1nü +l1ny +1lo +lo4ak +3lob. +l2oba +3lobb +lobe4s +2lobj +l1o2bl +l2obr +lob4ri +lo4chel +3lodr +2loe +l1of +lo2fe +lo4gh +lo2gl +lo2gor +lo2gre +lo3h2e +4l1ohr +loi4r +3lok +4l3okk +lo2k3r +5loks +l4ole +2l3o2ly +lomä3 +lo2min +lo4nin +lo2n1o +lo2o +2lope +lop2p1a +lop2pr +2lopt +lor3am +lor2an +lo4rä +3lorb +2l1orc +2l1ord +lo3r2en +4l1or3g2 +4lork +4lorp +2lort4 +lo4sa +3lose +lo4ske +lo2spe +lo2s1pr +los3ta +lo4stel +lo4steu +lo2s3to +lo2s3t4r +lo2ßu +lo2t1a +lot4e +lot2h +lo3tha +loti4o +lots2 +2l1ov +lo2ve +2lox +1lö +lö2b3 +2löck +2löd +lö2f +2l3öfe +4lög +2l1öhr +2lök +2l1ö4l +2löp +3lösc +4löß +4löz +2l1p +lp2ar +l4p1är +lp2f +lph4 +l3phä +l2phir +lp1ho +l3phr +lpt4 +l3pu +2l1q +2l3r2 +lra4ss +lrau2s +lrebs2 +lrö4 +lrös3 +lrut4 +4l1s +ls3a4b +l3sac +l2sa2d +l3s2al +l4s1amb +l4samp +l2san +ls3ane +l3sare +l3sarg +l3sark +lsau2 +lsau4m +lsau4r +l3s2äm +lsä6s +ls2äug +ls1äus +l4schin +l4schmü +l3se. +l2s1e2b +l3seil +ls2ele +ls1eli +ls1er +l2serf +l2serg +l2serh +l2serk +l2serl +l2sers +l2serw +lse2t +ls1eta +ls3ha +l2s1id +l2simp +ls2kal +l3s4kele +l4skla +l4sko +ls2ky +l2sop +l4s3ort. +l3sos +l3s2öl +l2spac +ls2pe +l2s3ph +l2s1pir +ls2po +l3spri +ls2pu +l3spul +l2spun +l4s3s2 +lst2a +lstab6 +ls2taf +l2stas +l4s3tat. +l4state +l3stau +l4s3täti +l4st3erk +l4s3terr +l2s1tis +l2stit +l4stoch +ls1tor +l4stor. +l4store +l4stors +ls2tra +l2s1trü +l3suf +ls1um +l2s1un +ls2und +ls3unk +4l1t +l3ta. +l2tab +lt1abs +ltag4 +lt1alg +lt1am +l3tami +ltampe4 +l3t2an. +ltan3d +l2t1ap +lt1ara +lt1art +l3tarta +l3tartu +l2t3ato +l2t1au +lt3aut +lt1äh +ltbau1 +lt1eh +lt1eig +l4t1ein +l2t1eis +l2t1elt +lte3mi +l3t2en +lten6gel +lten4sp +l4tentl +lt3ents +lte4ral +lter4fa +l3t2erg +lter6ken +lter4nä +lt2erö +lter4se +l2t1esk +l3t2est +l3tet. +l2t3h +l3thas +l4thei +lt4hem +l3t4hu +l2ti2d +ltimo4 +l3tine +lti3t +l2t1o4b +l2t1o2f +l2tord +l2torg +l2t1o2ri +lto2w +lt1öl +l3tön +lt1ös +lt1öt +ltra3l +lt3räu +lt3re +lt3ris +lt3rol +l2t3rö +l4ts +lts2eh +lt2se2l +lts3ort +lts1pe +lt1s2ph +lt4stec +lt2sti +lt3t +lt1uh +l2t1um +lt2um. +lturan4 +ltu2r1i +lu1an +4lu2b3 +luba2 +lub5s2 +lu2dr +lu2es +1lu2f2 +2l1ufe +2luff +lu3fo +luf4t1a +luft3e +luft3r +lu2g1a +lu2g1e2b +lu2gei +lugen1 +lu2g3i +lug3l +lu2go +lu2g3r +lug3se +lu2gu +2l1uh +lu1id +lu1is. +lul2ö +lumbi1 +lume4 +2lumf +2lumg +l1umh +2lumk +2luml +l2ump +1lumpe +lum2ph +2lumr +2l1ums +lu3mu +2l1umw +2lumz +1lu2n +2l1una +2l1unf +2l1uni +2lunr +2l1uns +2lunt +2lunw +4lu2o +lu2pf +2lur +l2ura +lu2r1an +lu2rei +lu2ri +l1urn +lu2ro +l1urt +lu4ru +lu2san +2luse +lu2sp +lus4s3a +lus2s1c +lus4sei +lus3sen +luss3er6 +lus2s1o +lus2s1p +lus4s1t +1lust +lu2sta +lu2stä +lu6sterl +lu2st1o2 +lu3str +lust3re +lu2s1u +4lu2ß1 +lu2t3a4 +lu2tä +lu2t1e4g +lu2tel +luter2 +lut3erg +luter4s +lu6t5ersa +2luto +lu2t1o2f +lu2top +lu2t1or +lu2t3r +lut5schl +3lux +2lüb +3lübd +lück4e2 +lücker3 +2lüd +2lüh +lü2hel +lüh1l +2l1v2 +lva3 +l3vl +l3vo +lv3r +4l3w +lweis4s +2lx +1ly +ly1a +ly3c +2lymp +3lyn +ly3no +ly1o +ly3onn +3lys4 +ly3t +2l1z +lza2 +l2z1ac +l2z1ag +l2zan +l2z1ap +l2zat +lz1aus +l2zäp +l2zär +lze2l +l2zele +l4z3enth +l2z1er2h +l2z1id +lzi4m +lz1imi +lz3l +l2zo2f +l2zö +lz3t2 +l2z1u4fe +lzug4s +l2z1ur +lzvol2 +lz1w +lz2wec +l2zwu +1ma +3ma. +maa2 +m1ab +m3a2bar +m2abä +2mabb +m2abe +2m3abf +2mabg +2mabk +m2abli +2mabm +m2ab4ra +ma2bri +2mabs +2mabt +ma3chan +mach2e +mach8terh +mach8t7ers +mach4tr +ma2ci +mack2s +ma3dac +mada2m +m2adä +ma2del +2m1adm +2m1a2d4r +ma4d2s +ma2es +ma1f4 +mag2a +ma2ge. +ma2geb +ma2gef +ma2geg +ma2gek +ma2gep +ma4ges. +ma2get +ma2gev +ma2gew +2m1agg +magi5er. +magi5ers +ma3gl +2magm +ma3g4n +2m1ago +mahl2s +ma1ho +mai4s3e +ma2ke. +2m1akt +mal2ag +mal1ak +ma4lakt +ma2lan +ma2l3at +ma2lau +2mal2de +m2aldi +ma3l2e +ma4lex +mali1 +mal3lo +mal3lö3 +2mallt +m2alp +mal3t4 +malu2 +ma2l3ut +3malv +ma2mid +mam3m +2m1a2nal +ma2nar +2m1a4nat +ma2nau +2m1anä +2manb +man2ce +man3d4 +man3ers +ma2net +m2anfr +man3g2 +m4angel +man4gl +2m1angr +m2anh +3manip +2manl +m2anle +man3s +2m1ansa +2mansä +man4sh +man2th +mant3he +2mantw +manu3 +2manw +2manz +m1anza +ma2or +ma1q +4marag +mar2an +2marb +mar3g2 +3ma1rh +ma3r2i +m2ark +mar2kr +4mar2o +maro3d +4marr +mar6schl +mar6schm +mar6schr +mar2sp +mar2su +2m1arti +ma3r2u +m1arz +ma3s4a +mas2e +3ma1s2p +ma3sses +mas6ses. +mas6sest +mass1t +ma3s2su +3mas2t +ma2sti +ma4sz +ma2ta2b +ma2tan +ma2tä +m3a2tel +ma4t3erd +ma4t3erz +m4atme +2matmo +ma4tort +3matr +mat3se +mat1sp +matta3g +matt4r +mat3url +2m1au2f +3maul +3ma3un +mau3r +2mausd +mau4ss +mau2ta +m4ay +ma1yo +1mä +3mäc +2m1ähn +mäh1r +4m1änd +3männ +2mäo +2m1äp +mär1 +mär2kl +mär2z +mä1t4r +mäu2s1c +2m1b4 +mbe2e +mbera2 +mbe3r2e +mbert4 +mble1i +m3br +mbu3sc +mbut2 +2mc +m3ch +2m1d +m2dan +m2d1a4s +md3ato +md1är +mde2a +m2dei +mder2 +m2d1erl +md3ras +md3s2e +mdt4 +m2d1um +1me +me3a +meau2 +meb4 +me2ben +3mebr +me1c +medi3e4 +me1ef +me3e4n1 +mee4rei +2m1eff +meg4 +mega3 +me4gel +3meh +meh6l3er +meh6rert +2m1eif +2m1eig +m2ei3l2 +mein4da +meiner6k +3m2einu +m2eist +me3l4ant +me2l1au +melb2 +mel3d2 +melde3i +me2lek +2melem +me2ler +melet2 +2melf. +3melk +mel4k3ei +mell2i +3melo +me2lob +mel2se +mel3t4 +6mel6tern +2m1e2mis +2m1emp +2m1e2mu +m2en. +me3nage +me4n3an +men3ar +me4nas +men3au +2mendl +menen1 +4men4gag +men3ge +me2nim +men3k4 +men2on +men4se. +6mensemb +men4sen +men4ser +men4ses +men2so +menst4 +m4enta +men4t3ak +ment5eig +men6t5ers +2mentn +ment4sp +me1o +2meou +2meö +2mepa +2m1e2pi +3m4er. +me1ra +me3rak +mer4as +mera3um +me2re2b +me4rens +mer4err +mer4erw +mer3f +4m3ergän +me3rid +merin4d +merin4t +4merklä +m4ersh +mer3sm +mert4r +merz6eng +3mes +me2sal +me2sä +mes2e +4meser +mes2po +2mes2sa +mess3an +mes6ser6g +mes2s1o +mes2sp +mes2st +me2str +me3sze +3me2ß3 +me3ta +me3th +met6t5en6d +meu1 +2m1ex +me2xe +1mé +2m1f4 +mfi4le +2m1g2 +2m1h4 +1mi +mi3a2b +mia2n +mi1ä +mibi1 +mic1e +mi1ch +mi2ci +mi3da +mi2di. +mi3dr +2midy +mie3dr +mi3ele +mi4e3no +mierer4 +mie4rob +mie2ti +mie2to +mie2tr +mi1f4 +3mige +mi3h +mi2k1an +mi2kar +mi2kel +mi2kin +mi3k4l +mi3kr +mi2ku +mi3la +milch1 +mil4che +mi3l2i +mil3le +4milz +m2im2a +2m1imm +2mimp +min2ac +min5anze +m2inde +2m1indu +mi2nef +miner1 +mi4n3e4ri +min2eu +2minfo +min2ga +mings2 +2minh +mi3ni +mini3k4 +mi3n2o +mi4n3of +2m1inse +mi3nu +mioni1 +mi1p +3mir. +3miri +3mirs +3mirw +3mirz +3mis. +mi2sa +mi3sau +mi4scha +mi4schr +mi4sch3w +mise1 +mis2p +mis5sar +mis4ser +mis4s1t +mi2sta +mi2ß1 +3mit +mi2ta +mite2 +mi2t3h +mi2to +mi2tr +mi3tra +mit3s2 +mit5sa +mit3ta +mit3t2e +mi2t1u +4mitz +mi3v2 +2m1j +2m1k4 +m3kn +2m1l2 +ml3c +m3le +ml3f +ml3k +m3lo +ml3p +ml3s +2m1m +mma3a +m2mab +m2m1ak +m2m1al +m2mans +mm1anz +mm1art +mm2as +mmas4p +mma2ß +m2m1au +m2mä4 +mm1äu +m2m1e2b +mme2c +m2m1ef +m4meh +m2mei +mm1ein +mm3eise +mme4lin +mme4na +mm2ene +m4mentl +m4mentw +m2me2nü +mme4r3a2 +mme4rec +mme2s1 +mmes3a +mme3sc +mme4sz +m2me4te +m2m1eu +mmi3el +mmi3k +mmi3m +mm1inb +mm1inh +m2m1ins +mm1int +mmi3sc +m4mita +mmi3tw +m2mo2l +m2mor +mm3p2 +mmpf4 +mms2 +mm3sa +mm3si +mmt2 +mm3te +m2mum +mm2un +mmu3r +m2mus +mmül2 +2m3n2 +m4nesi +1mo +mo2be +2mobj +2m1obs +3m2od +mo3de +mode3s +mo2dr +m1of +mo2fe +3mog +2mog. +mo2g1al +3m2oh +moh2a +moi3r +mo2k1l +2mol. +mol3d +3mom +mom2e +3m2on +mo2nä +mon4dac +mon4del +mon2do +mo2ner +mon2i +mon3s2 +mont2a +mon3th +mo1ny +3m2o2o +2mo1pe +mo2per +2m1opf +2mopt +mo1ra +mo2rak +mor2an +mo2rar +mor2d3a +mor2dr +morf4 +mor3g +mor3t2 +3mos +moster4 +mo2sto +mot4r +mous2 +2m1o2x +mo1y +1mö +möbe2 +mö2c +2mö2f +4mök +2m1ö4l +m1ört +4m1p +mpa3ne +mpe4lin +mpe2n1 +m2p1ene +m2pf +mpf1ef +mp4f3erf +mpf3erg +mp6fer6ge +mpf3erp +mp6ferpr +mp4f3err +mp4f3er4z +mpf3l +mp2fr +mp1haf +mp1hos +mp3lei +m4p3lem. +m2p3len +m2ples +m3pon +mpor6ter6 +mpot2 +mps2 +mp3sh +m3pu +2m1q +2m3r2 +4m1s +m2san +ms1as +m3sat +msau3e +m2s1än +msch2 +m3se. +m2s1e2d +m2s1ef +m2sein +m2se2le +mse2n +m2s1ene +m2sent +ms1erf +ms2erh +m3set +m2s1eu +m2sex +mso2r +ms1ori +m2spä +m2sped +ms2por +m2spot +m2spro +ms2pu +ms3s4 +m4stag +m2stal +m2stit +ms1ums +m2sü +2m1t +mt1ab +mt1ak +mta2m +mt1ar +mt3arr +mt3aug +m2t1e2d +m3tei. +mt1ein +mt1eis +mt1elt +m4tenga +m4t3engl +mt1ent +m4tentf +m4tentg +m4tentr +m2t1erb +m4t3erei +m2t1erf +m2t1erg +m2t3e2r1i +m2t1erk +m2t1erl +m2t1ers +m2t1ert +m2t1eta +m2t1eu +m2t1ev +m2t3h +m2ti2d +m2tim +m2t1in +m2t1i2r +mti2s +mt1ita +mtmen2 +mt1ob +mt1op +m2t1öl +mt1ös +mtra4s3 +m2t3ro +m2trö +m4ts +mt2sa +mts3chi +mt3sco +mt2s1e +mt3send +mt3s2ka +mt3s4kel +mt1sor +mts3tät +mt1um +mtu3re +mt3z +1mu +mu1a +2m1uh +mu3la +3muld +3mult +m4umb +3mumi +m1ums +mum2s1p +3mun +mun6derf +mu2ner2 +4m1unf +4m3ungeb +mu3ni +mu4nin +4mu4niv +4munw +4munz +muru2 +mu4r1uf +m4us +3mus. +mu4s1a +3musc +mu2s1o +mu2sp +mu3s4se. +mu3s4ses +mus4ste +must4e +mu2s1to +mu2str +mu2su +muße3 +mut4str +1mü +2müb +3müh +mü2her +mühl1a +mül4len +3mün +mü3s2si +3müt +2m1v +mvoll1 +2m1w2 +mwa2 +mwa4r +mweg2 +mwel4t3 +mwu1 +3my +my1al +my3l2 +2m1z2 +mzel4li +mzu1 +mzug4 +1na +3na. +2n1ab +na2bä +n3abh +3nabi +na2b3l +na4bor +na4bos +na2br +nab4rü +4n3abs2 +na2b3u +3na2c +nach1 +nachen4 +na5chen. +n3achse +nach3sp +nach8t7ersc +nacht8raum +5nachw +na3dab +4nadd +nade4l1 +na2der +4n1adl +4n1adm +4n1a2dr +4nadv +3nae +2n1af +na1fra +nag2a +na2gem +4n1agg +n1a2gi +na3gin +na3g4r +3n2ah +na2h1a +4n3ahn +4n3aho2 +3nai +nai2e +n1aig +4n1air +nai4re +n2ais +2n1ak +na2ka +3nakä +3nako +na2kro +4nakt +n4al. +na2l1a2 +nal3am +na4lar +na2lä +2n1albk +n2ald +nal3da +n4ale +na2leb +nal3ei +na4l3ent +na6lerei +na4ler4g +na4lerm +na4l3erw +nales2 +nal1et +nal1ex +nalf4 +nalg2 +nal3gl +na2lid +nal3la +nal2ph +nal3s +n2als. +nal3t2 +n2alty +na2lu +2naly +na2mat +3name +na3me. +4na2mei +n4a3men +4n1a2mer +na2mid +na3m4n +3n2amo +n1amp +nam2sp +2n1amt +namt2s +n1an +2n3an. +4na2na +na4nat +n3a2nä +4n3anb +n3and2 +nan1eu +4n3anf +4n3ang +4nanh +2nani +4n3ank +4n3anl +3n2ann +4n3anna +4nano +4n3anp +2nanr +4n3ans +2nantr +2nanw +n2anz. +nanzen4 +nan6zene +nan6zeng +na3ot +na2per +n1apfe +4napfel +na2pos +na2pr +nap2si +n1aq +n1ar +3nar. +na2r1a +2narc +n2ard +n2are +3nar2i +n2ark +n2arle +n2aro +na2rom +nar2rh +2nart +n2arta +n2arth +na3r2u +3nas +n4as. +na4schw +n2asf +4n1a2sp +nas2s1c +4n1assi +4nasy +nasyl4 +3naß +3nat +nat3au +nat1ei +na2th +4natm +nat2o +4natom +5nats1 +nat4sa +n1au +nauf4fr +nau2fr +5naui +3n2aul +4nausb +4nausd +4nausf +4nausg +4nausl +n2auso +4nausr +4n3auss +4nausw +4nausz +nau3te +3nav +nave4 +navi5er. +navi5ers +1nä +4näb +3n4äc +3näe +n1äf +3näg +3nähe +nä2hi +3nähm +4n1ähn +nä2hu +3näi +2n1ä2m +4n1än +2näp +2näq +nä2sc +n2ä6s3s +2näu +3nä1um +4näuß +2n3b4 +nbe2in +nbe3r2e +nbu3s +nby2 +2n1c +n2c3ab +n3can +n3ce4n3 +n3ces. +nch2a +n3chl +nch3m +ncor2 +n3cu +4n1d +n2da2d +nda1f +nd2ag +n3dai +n2d1ak +n4dakt +n2dana +n2dani +n2danl +nd1ann +n2d1anz +n3dap +nd3arr +n3dat +nd3att +nd1au +n2daut +n2dax +nd1c +nde4al. +n2d1ede +n3dee +n2dei +n4dei. +nd3elfe +ndel3l +ndel4sa +ndels5en +nde4mot +nden3sk +n4dentl +n4dents +nde3o +n5der. +n5deren +nderer3 +nd2erh +n5deri +nder6läs +nde4rob +n4de4ros +n6der6sat +n3d2es +nde2se +ndes3s +n2deth +ndia3 +nd1imm +n2dob +n2dof +ndo2n3a +n2dopt +nd1or +n2do2ri +ndo3st +n2d3ott +n2dö +nd2ös +nd4ram +n2d3rat +nd3rau +n2d3re +n2drif +n2droc +n2drod +n2d3rö +n2drui +n2d3run +nd4sene +nd2spr +nd3th +ndt4r +n2duns +ndwa5re +ndy3 +1ne +3ne. +ne2ap +3nea4s +ne3at +ne3au +ne2bl +2n1ebn +neb4r +2nec +3neca +3nece +neck2a +ne2dit +2nee +neei2 +ne3e4in +ne3eis +neema4 +neen2 +nee1r2 +nee3t +n1ef +n2ef. +n2e3f2a +2nefr +2n1egg +neg4l +n1e2go +neg4r +n1e2he +2nehe. +2nehem +2nehen2 +ne3her +3nehm +4n3ehr +2n1ei +3neia +4neic +nei4dei +4neier +3neigt +3neigu +4neing +4neinh +4neinl +4neinz +4neip +neiss4 +ne2ke +2n1eks +nek3t2 +ne2l +3ne3lä +nel3b +n1ele +4nelek +4nelem +ne3len +ne3l2i +ne4lim +ne4lit +3nelk +n2ell +nel2la4 +nel4lei +nel4lif +3ne3l2o +3nelu +n2em. +ne3mas +4n1emb +n1emi +4n3emp +2n1ems +4nemu +3nen +n4en. +n2e4n3a4 +ne5nac +n2enb +n2enc +nen4dar +4n1endb +4n1endd +4n1endf +n1endg +4n1endh +4n1endk +n1endl +4n1endp +4n1endt +4n1endw +ne2n1e2b +nen3ei +nene4m +nenen1 +ne4nene +ne2neu +n2enf +4n1engb +nen4gen +4n1engs +4n1engt +n1engu +nen4gun +n2enh +ne4n3i +n2enj +n2enk4 +n2enm +nen4nar +ne2no4 +nen3s2e +nen3sk +nen3s2p +5n2en3t2a +4n1entb +4nentd +4nentf +5n2enti +4n1entl +4nentn +nen3to +5nentr +4n1ents +4n3entw +4nentz +ne4n3u +n2env +n2enw +nen5z2e +ne2o3b +ne2oh +ne2or +3nepa +ne2pen +2nepf +ne2pi +ne2pos +nept4 +n4er. +ne1ra +ne2ra2b +ne2rac +ne2r3af +ne2rag +ne3r4al +ne2ram +ne2ran +ne2r3ap +n2erat +ne2rau +nerb2a +4n3erbe. +4n3erben +2nerdb +ne2re2b +ne2rec +5nerei. +n1erf +4nerfas +3nerfr +2nerfü +2ner3g4 +3nergr +n1erh +4n3erhö +3neri +n2erj +n1erk4 +5nerka +n2erkö +n2erli +2n1erlö +nerma3 +nermas4 +n1ermi +n2ern. +2n1ernä +4n3erneu +2n1ernt +n1eros +n1eröf +ne1rös +n2ers. +2n1ersa +4n3ersts +nert4 +3nert. +ne2rup +n2erv +4nerwar +2n1erz +nerz2a +n2es. +ne2sei +ne2s1ev +2ne3sh +nesi1 +ne3ska +ne2s1of +ne2s1or +ne2s1pa +4n1es2si +2n1e2st3r +4nesyn +3n2eß +ne2tab +2ne2tag +net1ak +ne2t1an +2ne2tap +2n1e2tat +ne2tau +ne4te2l +ne2th +ne4t3ha +ne3the +ne3ti +ne4tin +net1s2 +n4ett +net3ta +net3te +net3tr +2n1e2tu +net4zer +net2z1i +ne2u +neu1c +neu4ere +neuer4f +neuer4k +neuer4r +neuer4s +neuer4w +neu3g4 +n2eun +2n1eup +neur2 +3n2evi +ne2vol +n2ew +2n1ex +5ney +3nez +3né +2n1f +n3f2al +nfalt2 +n3f2ang +nf4ar +n3f2ä +n3f2en +n3f2er +nf2es +n4fex +nff4 +n3fi +nfi4le. +nf4le +nf2o +nf4r +nf3s2 +nf2tan +nf3tei +nf2t3r +nft2st +nft4ste +n2f1u +4n1g +n2g1ac +ng1ad +n2g1ak +ng1a2me +ng1ams +nga2n +ng1and +ngang6st +n2gans +ng1ant +n3g2ars +n2g1a2v +n2g1äl +ng3d4 +n2g1ein +nge3l4ei +n3g4en +n5gene +nge5nerw +ngenmas6 +ngen3s2 +nge4ram +n2g1erg +ng3erse +nger4zä +n3g4es +nge3s2a +nge3sp +ng3hu +n2g1id +ng2lad +ng2läs +n2glic +ng4lok +n3glot +ngma7sse. +n2gn +ng3ne +n4g3ni +ng4nom +ng2nu +ng2ob +ng1opf +ng1or +n2gö +n2g3rai +ng4ran +n2g3rat +ng3roc +ngro3s +ng2s1 +ngsa2g +ngs3an +ngs3au +ng5schr +ng4s3e4h +ngs3pa +ng4stec +ngt2 +ng3ts +n2gum +ngzei4t +4n3h2 +n7halts +n5he +nhe2r +1ni +3n2ia +ni3ak +nibb4 +nib4l +ni1ce +n1id +3n2id. +ni2de +3n2i3de. +4nidee +n2idi +ni3dr +2n3idy +n2ie +nie3b +ni1el +nie3l2a +nie4n +ni3ene +ni3eni +nie4rei +ni4erna +nie4sa +ni2eu +ni1fl +ni2g1a2 +2n3i2gel +2niget +nig3li +ni2gn +ni2gre +nig4san +nig4sp +nihi3 +ni2kar +3nike +ni2kel +ni3k4erh +ni2ki +nik3ing +ni2kor +ni2k3r +nik3t4 +3n2il +ni3l2a +ni3l2i +nil3l +4n3imp +n1in1 +3nin. +n2ina +nin2ac +ni2nal +3n2inb +2nind +2ninf +3ning +2ninh +4nink2 +3nino +ni2nor +3n2inp +2nins +n2ins. +4n3int +n2i3nu +4n3inv +3n2inw +ni2ob +ni3ok +ni3ol +ni3ora +n2ip +ni4ron +n1irr +3n2is +ni4sam +ni2san +ni2sä +nis3cha +ni4schw +ni2s1e +ni3se. +nis3el +ni2som +4nisot +ni2sp +ni3spi +nis5s4 +ni2stu +ni3stun +ni2s1u +2nit +3nita +ni1th +ni2ti +nit2o +3nitr +nit3s4 +nit4tec +nit6tell +nit6ter6g +nit6t5er6k +nit4tie +nit4tra +nitt3ri +nitt4sa +niv2 +3nix +2n1j +4n1k +nk1abr +n2k1ac +nka2ge +n3kal +n4kalg +nk1ang +nk1apf +nk3art. +nka3sc +n2katm +nk1aus +n2kaut +n2k1äh +n2k1äp +nk1ei. +nke4lei +n4kelem +nkelma3 +nkelmas6 +nke4na +nken4te +nk2er +n4k3erle +nke4ros +nk3ersa +nke2t +nk1eti +n2ketu +nk1id +n2kim +nk1inh +n2k1ins +n4klade +n3klag +nk3leis +n2k3len +nk3les +n3klin +nk2lo +nk4nac +nk4neb +n2knis +n2knit +n2k1o4be +n2kopt +nko2r +nkord2 +nk1ori +nko4rie +n2k1ort +n2köl +nk4rab +nk3rät +n4kre. +n2k3rel +n2kren +nk3rep +n2k3rez +nk3ro +n2krol +nk2sal +nk2se +nk3sen +nk2so +nks2ti +nk3s2z +nk2tak +nk4terg +nk4t3ern +nkte3sk +nkt2et +nk2tin +nkt1it +nk2top +nkt1r +nkt3ric +nk2tro +nk2tru +nkt4sen +n2kum +nk1ums +nku2n +nk1urh +n2küb +2n3l2 +nle2ga +nle3x +nli4ne +2n1m2 +n3ma +n3mä +nmen2s +n5mi +4n1n +nna2be +n2nada +n2nalg +n2n1all +n2nan +n2nau +n3nä +n3nec +nn2ei. +n4nein +n3nelb +nne4le +nne3lu +nn2ens +nner4ei +n6n5ereig +nner4fü +nner6geb +nn4ergr +nn2erh +nn2erk +nner4la +nn2ero +nne2rö4 +nn3erwa +nner6war +nner2z +nne4s1e +n2ness +nn2eu +nn2ex +nn3f +nng4 +n3n2i +n4n3iso +nno2b +nno3be +n2nof +n2nop +nno2r +nn1ori +nn4sam +nn3se +nn3s2p +nnst4 +nns3tat +nn4stoc +nn2stö +nn3t2a +nn2th +n2n1uf +n2n1unf +nn1ur +1no +3no. +no5at +n2obel +2nobj +no2bla +n2oble +3noblo +3noblö +2n1obs +no1c +noche4 +noch4r +2no2d +no3dr +no2ed +n1of +no2fe +2noff +2n1oh +n2ohe +no3id. +2n3okk +nok2l +n4ol. +n3ole +no2leu +no4lig +no2liv +2no2ly +3nome3 +3nomp +non2e +n1onk +n1ont +2nony +3n2opa +no2per +no2pi +n1ops +3nor. +nor2a +no2rad +n2o1rak +no3ral +no3r4ar +2norc +nor4da +3nordb +nor4des +nor2d5r +no3r2e +2n1org +3norh +3n2orl +5norm +norm2a +nor3mal +3norö +3nors +2n1ort +3n2os. +nos2e1 +no3sh +no5sk +no2sp +2nosti +nost1r +2nostv +nos2u +no2tan +no3tart +no2tä +not1e4i +no6tentr +no2ter2 +noterb3 +no2tex +not3h +no2tho +no2t3in +no2t3op +no2tr +3nov +2n1o2x +3noz +2nöd +4nö2f +4n1ök +4n1ö4l +n2ör +nö4s3s +1n2öt +4n3p4 +npa2ge +npf4 +npsy3 +2n1q +6n3r2 +nran2 +nra4s3s +nräu3s +nrebe2 +nreli1 +nre3sz +nrö2s +nrücker6 +4n1s +n3sabo +n2sa2d +n4s1agi +ns3a2k +n2sall +nsa2r +ns3are +n3s2arg +ns3ari +n3sark +nsa4s +ns4ath +nsau4r +nsau4se +n2saut +ns2av +ns2ax +n2s1än +ns2äug +n2s1äus +n4schef +nsch5eul +n4schl. +nscht4 +n3schu +nsch7werd +ns4cr +ns1eb +ns2eh +nse2ha2 +nseh5ere +nsei4n +n4seinf +n4seint +ns2ele +ns3elem +n2sem. +nsen4sp +n2sepo +n2s1erf +ns1erg +n2serh +n3seri +ns1erk +ns3erle +n4s3erne +n2serö +ns1ers +n4sersc +ns3ertr +n2s1erw +n2serz +n2seth +n2s1eu +nsfi4l +ns3hor +ns1id +nsi4den +n2simp +n2sini +nsinn2 +ns3int +nsi2te +nsi2tr +n3s2kal +n3s2kel +ns2kis +n3skle +n3s2ky +n3smara +n2s1o2d +ns1of +n2soff +ns4om +n2s1ont +n2sop +ns2orc +n4s3ort. +nsp4 +ns2pac +n3s2pek +ns2pel +n5s4pen +n4speri +n2sph +ns2pi +n5spie +n2spo +n2sprä +n4s3prie +n2spro +n4s3s2 +nst1ak +n4stale +nsta2n1 +nst3ane +n2stas +n4s3tat. +n6staten +n4stats +ns2tau +n5s2te. +n4steif +nst5eife +nst7einhe +ns4tem. +ns4ten. +n4stent +ns4ter. +nst5erge +n7stern +ns4tes. +n5steu +n5s2tic +n4stilg +n2stob +n4stole +nst5opfe +n4strac +n4strad +n6strieb +n4strik +ns4trun +ns2tum +nst3u2t +n3suf +ns2um +ns1un +ns2ung +n2s1urs +n2sut +n3sy +ns2zin +4n1t +n3t2a3c +ntak4ta +nta4lin +n4t1all +nta2lo +nt2alp +nta3ne +n4tansp +nt1ant +n4tanza +n3t2arb +nt1ark +n3t2arm +n3taro +nt1art +n4tarti +nt3artu +n3t2arz +n2tath +n2tauf +nt1äm +n2t1äu +n3te. +nte3au +nte1e +nte3g6 +n2t1eh +n3tehe +n2teig +n4t1ein +n2t1eis +nt1e2mo +nt4en +n3ten. +nte4na +nten6te. +ntera4 +nte6r5eis +nt4erh +nt4erk +nt4erm +nt4ern +nt4ers +nt4ert +n3tes2 +nte3sa +n4t1ess +n6testri +n3tet. +n2t1e2ta +nteu3 +nteu6eri +nte3v +ntge4n +nt3hel +nt3ho +nt4hos +n3thr +nt4hu +n2t5hum +nt4hy +nt2i +ntim3p +nt3inf +n2t3inh +ntini1 +n3t4lem +ntmen2 +ntmo4 +ntni2 +ntnis1 +ntopf3e +n2torg +n4t3o4rie +nt4ral +ntras3s +nt1rau +nt4raum +nt3rea +nt3rec +n3t4ree +nt3reif +n3trep +nt4repr +nt3rich +n4t3rieg +nt4rig +n2troh +n3trop +n2t3rü +n4t1s +nts2ah +nts2p +nt4s3par +nt5spe +nts2ti +nt2sur +ntt2 +nttü3 +ntu4re. +n4tw +nt3z +1nu +3nu1a +nu4ale +nu3a2r3 +nubi1 +2nuc +nude2 +3nue +nu2es +nuf2 +nu2fe +2n1uh +3nuhi +3nui +nuk4 +nu3kl +nu2kr +null3eb +nul4lin +n2um. +nu2ma +2n3umb +2numf +2numg +2numl +3numm +2numr +2n1ums +2n1umv +2n3umz +nu4n +2nuna +2n1une +3n2ung +4n3ungl +4n1uni +n3unk +2nunr +2nunt +2nunv +2nunw +3nuo +2nup +2nur +nu2ra +nu4r2i +nurs2 +nur2z +3nu2s +nu3sc +nu3se +nus1p +nu3spo +nuss3er4 +nu4s1t +nu2ß1 +3nut +nu2t1a +n3uto +nu2t3r +3nuu +3nux +3nuz +2nü4b +nür1c +1nüt +2n1v2 +n3ver +n3vl +nvoran4 +2n3w +nwei4st +1ny. +1nyh +nyle4 +n1yo +1nyr +1nys +1nyw +4n1z +n2z1ach +n2z1a2g +nza2k +n2zan +nz3a4ne +n3zani +n2zar +nza4s +n2zat +n2z1au +n2zän +n2zär +nze4l3a +nzel3l +n6zenerg +n4zen4se +n4zentl +nz3erem +n2z1erh +nz1erl +nzer4lö +nz5erste +nzer6tra +n4zerwe +n3z2es +nze3sk +nze3str +nze2t +nz1eta +nze3u2t +nz1id +nzi2ga +n2zinh +n2z1ini +nz1int +nz3le +nzlei3 +n2zof +n2z1op +n2zöl +nzug2s +nz1wa +n2z1wä +n2zwet +n2zwir +n2zwö +n2z1wu +ńo1 +2o3a2 +o4a3bi +o4ac +oa3che +oa3chi +o4ad +oa3de +oa3in +oa3k2e +oak1l +o4a3la +o4a3mi +oa4n +o2a4r +o2a3s +oa4si +o5ass +o4at +oa3te +o5au +o1ä +o1b +2ob. +o3b2al +obal3l +ob2am +ob2as +ob1auf +2o3b2ä +2obb +ob2e +2obe. +2obea +2o3bec +2obef +o2b3ein +2oben +obe4na +oben3d4 +o2ber +o3ber. +o4berb +ober5eis +1oberf +ober3in +oberin6g +obe4ris +7oberungs +2obev +2obez +2o3b2i +obi2t +ob3ite +3obj +ob1la +ob3lei +1ob3li +2oblo +2ob2lö +ob2lu +2obo +ob1or +2obö +ob3rei +2obrü +ob3s2h +ob3sk +obs2p +2o3bu +o4bunt +obus3s +obu2t3 +2o3bü +o4büb +2oby +2oc +o3ca +oc1c +o1ce +och1a +ocha2b +ocha2r +o1che +oche4b +o2ch1ec +och1eh +och1ei +oche2l +ocher4k +ochi4d +och3l +och3m +och1o +och3ö2 +och3r +ocht4 +o1chu +ochu2f +och3u2t +och1w +o3ci +ock5ersc +ock3sz +ock3ta +o1cl +o3co +o1ç +o1d +2o3d2a +od3ak +od2dr +o3de2c +o3d2e3i +odein3 +ode4l3ag +ode2n1 +ode2s1e +ode3sp +o3dex +2o3dia +odi3c +2odif +2o3dir +2odn +o2don +odo4s +2odr +o2dre +odt4 +2odu +o3dy +2o1e2 +oe4b +oe3di +oe4m +oen1e +o3er +o4e3s +oe4sc +o2e3t +o3et. +oet4h +o3ets +2ofa +of1a2d +of1a2g +of2ang +of1au +2ofä +o2f1e2b +o2f1ec +o2f1e2d +o2f1ei +o2fent +2o3fer +o4f1erb +2o3f2es +o2f1e2t +of1eun +of2fa2 +of4fal +of4fam +off1an +off3erz +of2f1in +of2fir +of2fix +1offiz +of2f3l +of2fo +of2f3r +offs2 +off3sh +off3si +off3sp +off3t4 +of2fu +of2fü +2ofi +ofi3k4l +2o1fl +of3le +of3li +of4lö +2ofo +2ofö +2o1fr +of3rä +of4rü +ofs1 +of2sa +of4sam +ofs2ch +of2se +of2si +of2sp +of4staf +of2sto +ofs2tr +ofstra8ssen +of2su +2oft +oft2a +of2tei +of3th +2ofu +of3ur +2o1g +o2g1ab +o2g1ac +oga3d +og1ang +o2g1ei +ogeld2 +oge2l1i +ogener4 +ogeni3 +ogen4id +ogenmas6 +ogerätein8 +og2gl +o3gh +ogi2er +ogin1 +o2g1ini +o3gis +og1l +og2lo +o3g4n +ogo4i3 +og1o2ri +og2s +og3sc +og3si +og3s2p +ogs1t +2o1ha +oh1alk +o1hä +o1he +o2h1eis +o2h1er2t +o2h1er2z +2o1hi +2ohl +ohl1a +oh2la2d +oh2lä +oh3lec +ohl1ei +oh3lep +ohler2 +oh4lerg +oh4l3erh +oh4lerw +oh3lo2 +oh4l1or +ohls2 +oh2lu +ohm2a +1ohmi +oh3mu +oh4n1ac +ohn1ap +oh3nee +oh2ni +1ohnm +oh2n1o +ohn3sk +2o1ho +ohol1e +oho4len +o2h1o2p +2ohö +oh3öl +ohr3a2 +oh4rat +oh2rel +oh2rem +ohren3s +ohrer2 +oh4rerg +oh3rie +oh4rin +oh2rol +ohrt4r +o1hu +oh1w +2o1hy +2oi +o1i2d +oi4da +o3ie +o1im +o1in +o4ine +oi2r +o2isc +o3isch. +oi3se +o1ism +oiss2 +oi4st +o1i2tu +2o1j +2o1k +ok2a +oka3b2 +ok3ac +oka3i +oka2la +okale2 +oka6lere +ok2e +3o2kel +oki4o +ok1lä +ok2li +ok2o +oko4pt +ok2so +ok2s1p +oks2t +ok3t2 +3okw +2ol +o1la +ol3abu +olaf4 +ol1ant +ol2ar +ol4arm +o3l2a3s +olast4 +ol1a2v +4o1lä +ol1ät +4olc +ol2chr +ol4d1am +ol2dä +ol2d1ed +ol2dei +ol4d3eng +old5ersa +ol2deu +ol2dim +ol2d3o +ol4dr +4ole. +o2l1ef +ol1eie +o2l1eis +oler2 +o2l1er3t +ol2e3u2 +ol1exz +o1lé +ol2fa +ol2fem +olf3ere +ol2f3l +olf1r +ol2f3ra +olft4 +olge4ne +ol2gl +ol2g3r +ol2i +olie4n1 +oli2er +oli3k4 +oli3tu +3oliv +oli3ze +ol2kl +olk3re +oll1ac +ol4la4d +ol2l1ak +ollä2 +ol2läd +oll1eb +ol4l1ec +ol2lei +oll3ein +ol3lem +oller6ge +ol4ler4k +oll3erw +oll3ess +ol2lic +ol4li4st +ol2lo2c +ol2lo2g +ol2lö2 +olls2 +oll3sa +oll3sp +ol2lu +ol3lus +4olo +ol2of +olo1p +ol1ort +ol3s2k +ol3te +ol3t4h +ol3ti +o1lu +olu2th +ol2y +ol2z1a +ol3zan +ol4z3ern +ol2zim +ol2zo +ol2zw +2om +o2mab +oma2bl +o2m1a2ge +om1alg +om1all +oma4ner +o4mante +o2m1ap +o2m1ars +o2m1art +omar4te +o2m1a2sy +o3mat +o2m1au +o2meb +om1ebe +o2m1ef +o2m1ei +o2mel +o3meld +o5men. +o4mep +om1er2h +omer2s +o2meru +om1er2z +omi2c3 +omiet1 +o3mig +om1ind +om3ing +om1ins +o2m1int +om3ma +om3mä +om3m2e +om3mu +o4mn +3omni +4omo +o2m3oa +o2m1org +om1o2ri +om3pf +omp4l +oms2 +om3sk +om3t4 +o2mum +o4munt +o3mus +2ona +on3a2b +ona3g +o3nal +onaler6e +on3ann +onan6z5ei +on1ap +o2narb +ona3th +onat2s +on2au +2onä +on1äh +2onc +on2dan +onderer5 +onde8rers +ond1r +on2dra +on4drin +ond3sk +2one +on1ec +o3nee +o2nef +one3h +on3ein +one2m +on1ema +one2n1 +o4n3ends +on2eng +o3ner. +o2n1erb +on1erd +oner4fa +on1erg +o2nerh +on4erka +on1erö +on1ers +o3nett +on2eu +on3f2 +on3gla +ong4r +ong3s +on2gue +2o3ni +on2i3d +onie3g +o4nikr +o4nim +o4nind +on3ing +o4ninh +on2inn +o4nins +on3k2 +1onke +3onkel +onli2 +onli6n +onlo2c +2onn +on3n2an +on3n2e +ono1 +o3nod +o2nof +o2noke +on1orc +on3ord +ono3s +onot4 +ons1a2 +on2seb +onsen1 +onse2t +on4sho +onsi2d +ons3ing +on4s3l +ons1p +onst2a +ons3tie +onst4r +on3ta +on2t1eb +on2te2l +ont5end +on4t3erl +on2th +on4t3rat +2onuk +o3nur +2onut +on3v +1ony +on3z2 +onze3in +o1ń +oofs2 +1oog +oo2ka +oo2k3l +oo2kn +oo2mo +o1op +o1or +oor3d +oo4sk +oo2su +oo2t1a +oot1ei +oo4t3h +oo2tr +oot2s1t +oo2tur +2o1ö4 +2op. +o1pa +opab4 +op1akt +opa2le +o3pas +1ope +2ope. +o1pec +2o1ped +op1ef +2o1pei +o1pek +2opel +ope3l4a3 +2open +o2pera +op1erh +o1pes +2opf. +op2f3a +op3fah +op2fä +o2pfe +op2fin +opf3la +op1flü +op2fo +op3for +4oph2 +o3phe +o1p2i +opi5a2 +opi3er. +opi5ers. +opie4r3u +opin2 +2opl +op3lag +o2p3le +op3li +o3p2n +2opo +opo2la +op2pan +op4pl +1oppo +2oppt +2o1pr +3o4psi +ops2t +op3sz +1op3t4 +o2pum +2opy +2o1q +2or. +or1a +2ora. +o1raa +2or3a2b +o2rabb +o2r3add +or3adr +o1r2ag +1orake +o1ral +oral5l +o4r3alm +or4alt +or2am +or3a2mi +o1ran3d4 +oran2f +oran2m +oran4ze +or3ap +2orar +or3arr +o1ras +o2r3att +2orau4 +orau2s +oraus6wa +2o1raw +o3rä +or1änd +or1ät +orb2l +or1c +2orca +or2ce +2ord. +2orda +ord1am +or2dar +or2dau +2ordb +ord3eng +orde4s +or2deu +or4d3ing +or2d1ir +or2dit +1ordn +or2do4 +2ordr +ord3t +2ordu +2ordw +2ore +ore2a +o2r1e2b +o2r1eck +o5ree +or1eff +ore2h +or1eig +oreli1 +orems2 +o2r1er +o3r2ere +orer1i +o3r2ero +or1e2th +o2r1eu +2orf +or2far +orf3li +or3g4a +2orget +or3ghi +2orgia +orgi1e +or2gl +or3gla +or3gle +or2gn +2orgr +2orh +2oria +2oric +4o3rie. +o3rien. +o6rienti +o3rier +4oril +or1ima +ori4mi +4orin1 +o2rind +2oris +2oriu +2ork +or3k2a +or4k3ar +ork4r +ork3s +2orm +or2mam +or4mans +orm3asp +or2m1eb +or4m3erf +or4m3er4g +or2mor +orm3ord +or2mum +ormu4n +or4muni +or4munt +ormvol4 +ormwa5 +or2n1ac +or2nal +or2nar +or5ne. +or3ni +or4nin +or3no +2o1ro +o2r1ob +or3oly +oro3n2a +or1opf +o2ro2r +o3rou +o2r1ox +2o1rö +2orp +2orq +2orr +orr4a +or3r2e +or3rh +2ors2 +or3s4a +or3sh +or3si +or3sk +or3sz +or2t1ak +or2tan +orta2r +or2tau +or2tef +orte4n +or4ten5g +ort3erb +or4t3ere +ort3erf +orter6fa +ort3erg +or4terk +or4t3erl +orter6sc +or2t3e2v +or2the +or2tin +or4t3off +or2to2r +or2tö +or4trau +or4t3räu +ort3re +or2t1um +2o3ru +or2uf +or1uh +orum4s +o4r3un +o5rus3 +o2rü +o2rya +or3z2e +o1s +2o3s2a +osa3b +os3ad +osal2 +2osc +o4s3ca +osch3ar +o3sche +osch3le +2ose +ose1e +ose1in2 +os2el +ose2n +osens2 +o2s1er4k +os2ex +2osh +o3s2hi +os4hu +2osi +o3sk +o4ska +os2kal +o4ski +2os2kl +2os2ko +o4skr +os2lo +1osm +os4mog +2os2o +osol1 +o2sö +2osp +os1pec +o3s2po +2oss +os6s3ac +oss3ala +oss3and +os4sä +o6ssel +o3ssem. +oss3en4k +o3ssent +oss3enz +oss1ep +oss2er +oss3er4b +osser4e +oss5erei +oss3er4f +o4ssi +os2s1o2 +os2sp +oss1pa +os2s1t +os2su +os2t +ost1a +o2stab +o3stal. +osta4s +ost1ei +oste2n +o4s3tep +o4sterd +oster3e +ost5erwe +oster8wei +ost3eur +ost3h +o2stid +o2stin +ost1o4b +os3ton +o2st1or +ost3ran +o2st3rä +ost3re +ost3rot +ost3uf +2osu4 +os1um +2osy +o3s4ze +2oß +o2ß1el +o2ß1en2k +o2ß1enz +oßer2 +o2ß1erb +o2ß1ere +o2ß1erf +oß1is +oß1u +2o1t +o2t1abi +ot1ah +o2t1ak +o3tal +o3tam +ot1ant +ota4s +ot1ast +o2t1au +o3tau. +ot1ä +o2teb +ote1i +o4t1eib +o4t1eic +ote3i4n +o4t1eis +ote4l1a +o3tem +o4t1emi +ot2em3p2 +ote4na +o4tentb +ot3entr +ot1erb +o4t1er4l +o4t1erw +o3the +o4them +o2t3hi +o2thr +4oti +ot2id +o2til +o2t1i2m +ot2in +ot3inh +o4tl +otli4 +ot2o +otob4 +ot3opf +oto4rei +o2t1ö +o3tran +otra4s3 +ot3rat +ot4rau +ot3re +ot3rin +ot3roc +ot3ru +ot2s3at +ots1o +ots1p +ots2pe +ot3s4tra +ott3akt +ott3an +ot2t1a4s +ot2tau +ot2teb +ot4terh +ot4terk +ot3te4s3 +ot2t3h +ott2o +ot2t3r +ot3t4ra +ot3t4ru +ot1url +oub4 +ouff6 +ou1f4l +ou4ge +ou3gl +o1uh +ou1is. +ou4le. +ou2les +2o1um +2o2u2n +oung5 +oun4ge. +oungs2 +o4up +4our +oure2 +ou2ret +ouri2e4 +ourme4 +our4ne. +ou3s2i +ou3s2t +o4ut +3outp +out3s2 +outu4 +2o1ü +o1v +ov2a +2ovel +o3ven +2ovi +oviso3 +2ovo +2o1w +o3wec +owe2r1 +o2wh +o3wi +o2wu +o1x +2ox. +ox2a +2oxk +ox3l +o2xu +1oxy +o1yo +2o3z2 +3o4zea +ozen4ta +ozes4sc +ozir3 +ozon1a +oz3z +órd2 +ö1b +öbe4l3i +öb2l +ö2ble +ö2b3r +ö1ch +öch3l +ö2chr +öchs2t +öch6st5ei +öchst3r +ö1d +öde1r +ödi3 +ödin3 +1ödu +ö1e +1öf +öf2fa +öf2fl +öf3l +öge3le +ögen4s1 +ög3l +ög3r +ög2s +ö1he +öhe4n1 +öhl2e4 +öhre4 +öh3ri +öh2s +ö1hu +ö3ig. +ö3isch. +ö1ke +1ö2ko3 +ök3r +ök2s +ö2l +3öl. +öl1a2 +öl1ei +öl1em +öl2f1ei +ölf2er +öl1in +ölk4e +öl2k3l +öl2la2 +öll1an +3ölm +öl2nar +ölo2 +öls2 +öl3sa +öl3sz +öl3tu +1ölu +ölz2w +ö1m +öm2s +ön2e +ö3ni +önizi1 +önn2e +öo1 +öo2ta +öoti1 +2öp +ö1pe +öpf3l +ör3a2 +örb2e +ör2b3l +ör1c +ör2dr +ör3dra +ö2r1ec +ö2r1ei +ö2r1e2l +ö2r1em +öre2n1 +ö2r1ene +ö2rent +ö3r2erb +ö2r1er2e +örer2f +ö2rer2g +ö2rer2l +ör2err +ör2erw +ö3r2erz +ör1ess +ör2f3l +ör2gl +ö2rim +ör2kl +örn2e +örner4v +ör1o +örpe2 +örs2e +ör3sk +ört2e +öru4 +ö2r1une +ö1s +ö2sa +2ösc +ö2sch3a +ösche2 +ö4sch3ei +öscher3 +ö6sch5erf +ö6sch5eri +ö2schi +ö2sch1l +ö2sch3m +ö2schn +ö2schw +ös1ei +ö2sein +ös4en +ös4es +2ösl +ös2o +ö2sp +ö3s2s +ös4s1c +ö4s3set +ös4st +ös4t +ö2st1a2 +ös4u +ö1ß +ößen3 +öß2ti +ö1t +ö2t3a +öte4n1 +ö2t3r +öt2sc +öt2tr +ö1v2 +ö1w +ö1z +öze3 +özes4 +1pa. +1paa +1pac +p2ad +pa3da +2p3a2dr +pa1fr +1pag4 +pa3gh +pa1ho +1pak +pa1k4l +pak2to +3pala +pala3t2 +3palä +3pal2e +pa3l2i +1palm +pal2ma +pal2mä +pal2m1o +2palt +pal2ta +pal4tei +pal2tr +pa2m3a +pa2nar +pa4n3at +pan3d +pan4ds +pa2neu +panf4 +pang4 +pa4nisl +pank4 +2panl +2pann +panne2 +pan4n3eb +4pannu +1pa2no +pan3sl +pan3t4h +1panto +2pantr +panz2 +pan5ze +1pap +papi2 +papieren8 +papie8r7end +pap2pr +pa1q +1para +pa4r3aff +par3akt +pa4rant +2parb +1p2arc +par3d +2parer +parer8geb +1parf +2parfö +2parg +pargel6d +1park. +par4k3am +par4kau +par4kr +1parks +par3m2 +par3ne +1pa2ro +2parp4 +2parr +4parta +1parti +1partn +3party +par3z +pas2e +pa1s2p +pas6sein +passer4 +pas6serg +pas2s1p +pas2t +pa2ßu +pat1a +pat4c +pa3t4e2 +2patel +1pat4h +1pati +1pat4r +1pau +2p1auf +pa3uni +2pausz +1pav +pay2 +1pä +3päc +päck3er +3päd +päde2 +pä2d1er +3pär +3pä4s3 +pä4t1e2h +pä4tent +pä4tep +pä4t3erb +pät3h +pä2to +pä2tr +pät5s +2p1b +pbe1 +2p3c +2p1d2 +pda2 +1pe. +pe2a2 +pea4r +pea4s +p1e2b +pech1 +1peda +1peel +pe2en +2pef +4p1eff +1peg +pei1 +2peic +1peil +p2eim +2peis +1peit +pekt4i +1p2el +3pel. +pe2l1a2 +pe4lai +pe2l1ä +peld4 +3pele +pe4l1e2h +pe2l1er +pe2let +pe2leu +peli2d +peli4n +pe4l3ink +pel3inn +pel3k +pel3l2a +pel3lä +pel3l4e +pell2i +pe2lob +3pels4 +pel3sp +1pem +1pen +pe3nal +pe4nas +pen3d2a +pe4nen1 +pe4ni2t +pe2n1o +pens2 +3pen3si +pen3so3 +pen3sz +pent2a +2pentw +penty2 +pe2nu +1pep +pe3pi +pept2 +pe1ra +per2am +per3as +pe2r1ä +pere2b +perer4f +pe3r2i3d +3perio +1perle +1perlh +3pero +perra2 +per4r3an +per4rä2 +per4ric +per6rieg +1pers +2perse +2persi +3perso +3persp +peru2 +pe3run +1perü +perwa4r +pe3s2a +pes2e +pese2n +1pes5s2 +pes2t +pest1o +pe4stop +3pet +pet4r +1pé +2pf. +p2f1ab +p2fad +p2faf +pf1ai +p2f1ak +pf1am +pf1ans +p2fa2r +pf3are +p2f1au +1pfä +p2fär +p2f1äu +4pfe. +p2fef +p2fei +pf1eim +pf1ein +pfe2l +p3fen. +p4fener +p2fent +p4f1ep +pfe2r5a +p4ferde +pfer6pro +pf4es +pf3f4 +pffa3 +p2f1i2d +pf1inn +p2f1ins +pf1lam +pf4lan +pf3lä +pf4leg +pf3lei +pf3lo +p2f3om +p2for +pf3r +pf1ra +pf4rü +pfs2 +pf3sa +pf3se +pf3sl +pf3so +pf3sz +pf3t4 +p2fum +2p3g2 +pgra2 +1ph +2ph. +phal4te +p1hand +3phas +p1hau +phä1 +3phän +2phb +2phd +2p1hei +phen3d2 +phe4n1e +phen3s +2ph1ers +2phf +2phg +phik1a +phi4kan +2phk +ph2l +2phm +2phn +p2ho. +p2hob +pho2s +2phö +ph4r +2phro +2phs +ph3t4 +2phthe +phu4s +phu3t +2p1hü +3phy +2phz +pi2a1 +piab4 +pia3k4 +pi4ali +pia3n +piap2 +pia3s +pi1ce +pi2el +piel3a2 +1pier +pie2ra +pie4reb +pies4 +1pig +pi3gl +1pil +pi3le +3pilo +pil4zer +pil2zw +p2im +3pin. +pi2nad +3ping +pingen4 +ping3s +3pins. +3pinse +pin3s2p +pi2o +pi3o2i3 +pi3onu +pi3os +3pip +pi2pe +3pirate +pi3ri +3pirin +1pis +2piso +pis2t +pi3sto +pit2a +pi3t2h +pit2s +pitz2e +pi2z1in +2p1j +2p1k2 +pku2 +1p2l2 +2pl. +3pla +p3lab +4p3lad +p3lah +pla3na +pla2y +3plä +2ple. +ple1c +ple2e +p4leg +ple3n2 +2p3ler +p3les +p3lic +2plig +3plik +2p3lu +2p3m2 +2p1n2 +1p2o +pob2 +po1c +3pock +3pod +3poe +po2el +2poh +po2i +po3id +3poin +3pol +po2lan +po2l1au +pold2e +po3li +pol3lo +polo3p +pol3z2 +pom2ph +2pond +pont2 +po1ob +po2p1ak +po2p1ar +po2pl +po3pt +po1rau +porf4 +3portal +por2th +3porti +3porto. +3portos +3portr +por4tre +por6tric +pos3s2 +pos4t +po2sta +po4stad +po2stä +po4stei +po4stem +post3ra +po2ta +pot1ar +3potä +3pote +pot2h +po2t3in +pott1r +po2t1u +po3un +po2w4 +po3x +pö2bl +pö2c +2p1p +p2p1ab +pp1ang +pp1ans +ppa2p +p2pat +pp1au +ppe3e +pp1ei +ppeli5ne +pp2e2n1 +ppe4na +p2p1erz +p2pf4 +pp1fr +p2p1h2 +p2p1i4a +p4p3lac +p4plan +pp3lä +p2p3le +pp3lis +pp3oh +p2p1ö2 +pp3p2 +p2p3ra +p2p5rä +pp3ren +p2pri +pp3rol +pp3rot +p2p3ru +p4ps2 +pp3sa +pp3sy +ppt4 +pp5te +p3puc +p2pul +p2p1um +p2punk +p3pur +p2r2 +1prak +pra4s3 +pra5sp +1prax +p4rä +1präd +1präf +1präg +1präl +3präm +1präp +3präs +1präv +2pre. +2prec +3pred +2pree1 +pre2ei +2preg +1prei +3preis +prei4s3c +prei6sei +prei4ss +2preiz +1prem +pren4ga +2p3rer +1pres +press4e +1preß +pri4e +2prig +pri2l1 +2pring +prings4 +1prinz +pri2t1 +prit3a +priter4 +prit3t +1priv +1pro1 +3prob +pro3be +2proc +7prod +3prog +3proj +2pross +2proß +prot2e +3proto +2prott +2prö +1prüf +1prüg +2prüh +2prün +2p1s +4ps. +p3sat +ps1id +ps3k +p2sö +ps4pi +pss2 +p2st1au +pst3erh +p2stu +3p2sy +4psys +ps2ze +2p1t +pt1a +pt2ab +pta2g +pt3a2t +pt3ax +p3te +p4t1e2b +p4t3ec +p4t1ei +p4tele +p4temp +4pten +p4t1en2g +p4t1ent +p4t1ep +pt3erei +p4t1erw +p4t1erz +p4t1e2ti +p2t3h +p3ti +p4t1in1 +pt3ing +pto2mo +pto2p +p4tos +pto2w +ptpo4 +pt3r +pt1s2 +pts4t +pt1uh +pt1um +p3tung +pt1urs +p2tü4 +3p2ty +pt3z2 +1pu +pu1a +pub4 +2puc +pu2dr +2p1uh +2puk +pu2kl +pu2k1o +pu2lin +pul2sp +pul2s1t +3pulv +2pulw +pum2pl +4pund +pun2e +pun2s +2punt +2pur +pu2ra +pu2rei +pus2h +pu3she +3put +pu5t2e +put2s +puzi3 +1püf +pül3l +2p1v +2p1w +pwa4r +3py1 +py3t +2p1z2 +qu4 +quel4la +que3rel +quer5n +que4te. +1queu +1ra. +r1aa +ra2ab +2raac +2raal +ra3ar +r2a1as +r1ab +ra2b1ar +r2abä +1rabbi +rab2bl +2rabd +ra2bei +rab2er +rab3erd +2rabf +2rabg +2rabh +1r4abi +2rabk +r2able +ra2bli +ra4b5lo +2ra2br +2rabs2 +2rabt +2r3abw +1raby +2rabz +r2ac. +ra2ce +2r1acet +ra4cheb +ra2cho +4racht +rach6t5rä +ra2chu +r2ack +1r2ad +r4ad. +rada2 +ra4dam +2radap +3radar +ra2dei +rade5s +3radf +3radh +3radio +4radit +3rado +3radp +ra4d1r +rad5ri +rad3t4 +ra2el +r2af +raf3ahn +raf3ar +rafe2 +ra2f1er +raf3r +rages4 +2ragg +ra3gle +4ragm +ra2gn +r2ago +rag4sta +1rah. +rahle4n +5r4ahm +r1ahn +2ra1ho +ra3hö +4raht +r2ai +2raic +rail4l +2r3air +ra3ke +2rakk +3ra1k4l +ra2kre +ra2kro +2rakti +ra2kus +3rakü +2rakz +r2al +r4al. +ra2la2 +ra4l3ab +ral1ak +ra3lamp +rala4s +ra2lä +ral3b4 +3r4ald +r4ale +ra4l3end +ra4lent +ra4l5ern +ra3lex +r4ali +ra2lid +rali1e +ra4lind +ra4l3ing +2r3alk. +2r3alm. +2ralp. +4ralpe +r4als +ral3su +r3alt +3r4al3t4h +ra2l3u +3raly +ra2mei +ra2mer +r2ami +r2amm +ram4man +ram6mens +ram6m5ers +ram4mit +ram4mu +2ramn +3ramsc +2r1amt +ramt2s +ran3ade +r1a2nal +ra2nan +ra2nar +ra2nau +2ranb +r2anbe +r4anda +r4ande +ran4dep +ran4d3er +3r2andi +rand3s +3raner +2ranf +2ranga +ran6g5e6be +1rangi +r2angl +rangs2 +rani1e +r3a4nil +ran2kr +ran2kü +4ranl +2r1anm +r2anmi +r2anmu +2ranna +rano2i +2r1anp +2ranr +2rans +r2ans. +ran4spa +4r5antei +r1anth +2rantr +1ranu +2ranw +r2anz. +r2ap +2rapf +2rapo +ra2pok +ra2pos +rap2pr +2ra2pri +2r1aq +r1ar +r2ar1a +2rarc +r2are +3r4arei +raren1 +r2arf4 +ra3rie +rar3in +ra3ris +r3a4rist +4r3arit +r2ark +raro2 +ra2rom +2rart +2rarz +rar3zw +r2a3s2 +r4as. +ra4schl +ra4sk +ras3si +ras3sp +r4aste +ra4st3ei +r3asth +ra4sto +ras3tri +2rasyl +2raß +1rat +r4at. +rat1a +rat2ak +ra2tan +ra2t1ei +r3atel +ra3tes +ra4tid +2ratla +2ratm +rat2o +2r3a2tom +ra3tor +rat4r +r4ats +2ratta +2rattr +4ratz +rat3ze +4rau. +3raub. +4raue +rau3e4n +2rauf +rau3fä +2rau3g +3raum +rau4m3ag +rau4man +rau5mes +rau2m1i +3raup +4raur +2rausb +3raus2c +2rausd +2rausf +2rausg +raus8gewä +2raush +2rausl +rau2sp +2rauss +raus8scheidu +raus3tr +2rausv +2rausw +2raut +raut1r +rau4tra +rau4tro +raut5s +1raü +r2ax +raxe3 +raxi4s1 +r3axt +4räb +räch4s +3r2äd +4räf +rä1fr +4räg +2räh +4räm +3rän. +3räni +3räns +2räp +2räq +2r1är +r2är. +rä3ra +rä1ro +rä4sc +räse2 +rä2st +3rätse +4rätz +rä2u +4räue +räu2s +räus2c +räu7schen. +2räuss +2räuß +4räut +2räx +4r1b +r2b1ab +r3bac +rba4del +rb2al +r2bang +r2bant +rba3re +rb1art +r2barz +rb1auf +rbb2 +rb1ech +rbe3erf +rbei5d2 +rbe3inf +rb3einh +rbe3int +r4belä +rbel2o +rbe3r2e +rber6gin +rb1erl +rbe3rum +r2bim +r2binf +rbit2a +rbi3tu +rb2la +rb4la2d +r2blan +r8blasser +r4b3last +r3blat +r3blau +r2ble. +r3blen +rb3ler +r2bleu +rb2lin +rb2lö +rb3lös +rbmas3 +rb2ob +rb3ras +rb3rea +r8b7rechts +rb4sam +rb2sei +rb2ser +rb2s1o +rb4stä +rb2su +rb4sz +rb2u +rbü4b +4rc +r1ce +rce4n +r1che. +r1chen +r1ch2i +rch3l +r3ch4lo +rch3m +rch3r +rchs2 +rch3sp +rch3t2a +rchter6r +rch1w +r1ci +r1cl +r1ç +4r1d +rd2ac +r2daf +r2d1ak +r2d1a2l +rd2amm +rd1an +rdani1 +rd1ara +rd1ark +r2darz +rdär2 +r3de. +r2dei +rd2ei. +r4deis +r2d1elb +r2delf +rdels2 +rdem6 +rden3d2 +r4dengl +rde3ob +rde3r4er +rderin6s +r4d3ernt +r3des +rde3sp +r4d1ex +r2d1inn +rd1iri +rd1ita +r2dof +r3don +rd1os +rd3oss +r2dö +rd3rat +r2drau +rd4ri +rd5ris +rd4rö +r3d4rü +rd2sän +rd3s2k +rd3s2z +rd3th +rdt4r +rdt2s +r2d1uk +1re +3re. +rea2d +rea6l5erw +4re2am +re3at. +re3ats +2reä +re2b1a +re2b1l +reb1r +reb3ra +reb3so +rech3ar +4rechs +2reck. +2recki +3red. +4redd +2redi +re2dik +3redn +3redu +re1e +3refe +4reff +r2eff. +3refl +3refo +3reg +rege4l3ä +4r1egg +2reh +re2hac +re2har +rehen1 +re4hene +re4h3ent +re2hi +reh1l4 +re2h1o +re3hol +re2hü +r2ei. +r2eib +rei4bel +rei4ble +2reid +r2eie +4reier. +rei4fei +4reifel +2reig +3reigä +3reigeh +r4eigel +6reigens +3reigi +4reign +3reigru +rei3l2a +rei3l2i +2r1eilt +3reim +reim2p +r1ein +rein2a +rei5nac +rei3nal +2reinb +rein4du +rei3n4ec +reinen5 +2reinf +re4info +4reinn +4r3einr +rein8s7tre +rein4sz +rein6teg +re1in2v +4reisar +4reisb +2reisf +2reish +2reisr +reister6 +rei6s5tro +2reisw +4reiti +reit3s2 +re2ke +4rekk +r2el. +re3lat +2relb +rel2e +relea4 +re5lei +re2lek +4relem +r2elev +2relf +2relit +2relix +r2ell +rel4lar +rel4lei +re3lo +r2els +2relt +relu2 +r4em. +4remb +rem2da +re2m1ei +r2emi +re3mig +2remis +4remit +4rempf +rems1c +rem4str +2rem2u +r4en. +r2ena +2rena. +re4nac +re3nal +re4n3an +r1endg +3rendi +ren3dr +ren2eu +5renf +4rengag +2rengp +3renh +re2ni +3renl +3renm +ren4nar +ren6nene +ren6sein +ren6serg +rens2p +2rentd +2rentf +3rentfo +2r1entg +r3enthä +2r1entl +2r1ents +2rentw +2rentz +r2enz +ren6z5er6f +renzer6l +ren6z5er6s +renzer6w +ren4z3in +ren2zw +re2ob +re1on +re3or +3repe +4re2pen +2repi +re2pis +2repoc +2r1e2pos +4repp +3repu +3r4er. +rera2 +2r1erb +rer2bi +3r2erbr +2r1erd +rere2 +4r3ereig +r1erek +re2r1ep +r2erer +2r1erf +4rerfah +r4erfe +3r2erfr +rer2fü +r1erg +4r3ergeb +5rergebü +r4ergen +3r4erges +2rergo +rer2gr +r4ergru +rer2hö +re3rin +r1erk +rer4kan +rer2ke +4r3erken +3r2erki +3r2erko +r1erl +2r3er2la +5r4erlag +r3erleb +r2erli +2rerlö +2r1erm +rer2n +2r1ernä +r1erne +2r1erni +4r3erns +4r1ernt +re1ro +re2rob +re4rosi +2r1er2ö +r1erre +rer4reg +rer4rei +r1erri +5r2ers. +2r1ersa +rer5sc +r6erschi +r2erse +2rersp +rer4sta +r6erstad +r1ert4 +r2erte +4rerträ +r1erw +rer4wac +rer4wec +r4erwes +2r1erz +rer2zä +3r2erzy +3r4es. +re2sa +re4sam +re3sar +re4schw +3rese +re4se2h +3reson +res2po +2ress +4resse +res6s5erw +res4sto +4ressu +3rest +re6stent +re4stra +4restu +3resu +2re2ß1 +re2t1ak +re2tau +re2thy +re4trol +re2u +reu4eri +reu3g2 +2reul +re3uni +2r1eur +2reü +4r3eva +2r1evid +rewa4r +re2wi +2rewo +2r1e2x1 +2rezi +1ré +4r1f +r5fahrt +rfall4s +rfäs3 +r2fent +r3f2es +rff2 +rf3fe +rfi4le. +r4fland +r3f4lä +rf3lic +rf4lö +r3flü +r2fo2b +rfolg4s +r3foli +r3fot +r4frauc +rf4ru +rf4rü +rf4sam +rf2s1ä +rf2su +rf2ta +rf4tin +rft4r +rf2u +rfzu3 +2r1g +r2g1a2d +r2g1ah +r2g1ak +rga4ner +r2g1ap +r2garb +rg3art. +r2g1ask +rgas2t +rga5stes +rga3su +rgd2 +rge4an +rge2bl +r2g1e2c +r3g2el +rge4l3er +rgen6sem +rgen4z3w +r4ge4tap +r2geto +r7gie +rgi4sel +r2glan +rgleich8s7 +r2gleu +r2glig +rg2log +rg2lu +r2g3na +r2gne +r2g3ni +r2g3no +r2g3oa +r2go4b +r3gog +rg3op +r2g1or +rgö2 +r2g1öd +r2g3ral +rg4rau +r2greg +r2gres +r2gret +rg3rin +rgro5sse +r3grun +rg3rüs +rg3se +rgs2ei +rg4sel +rg3s4i +rg1sp +rgs2pe +rgs2po +rgs4ti +rgs2tu +rg1su +r1h4 +2rh. +2rha +r2ha. +r4haltb +r3han +2rhä +r2he. +r5hea +2rheb +2rhef +2rheit +2rher +2rhi +2rhof +rho2i3 +2rhol +2rhot +2rhöl +2rhs +2rhü +1ri +ria3ne +ri2ano +ri2ast +ri3at +ri4atr +rib2bl +ri1ce +ri1cha +richt8spo +3richtu +ri2con +ri2dau +ri3de. +4ridee +ri2de2l +rid3r +ri4ds +r2ie +rieb6ste +rief1a +4riefm +rie2f3r +rieg4s +ri2e1i +riein1 +ri1el +rie3l2a +ri3els +ri4enä +riene2 +ri3eni +rie2nu +ri1er. +rie3re +riere4n +ri1eu +ri2f1a +ri2fä +ri2fei +ri2fer +rif6f5end +rif4fer +ri2f1o +ri2fr +rif4ter +3rig +4riga +4r3i2gel +ri4gene +5rigj +rig1l +4rigr +4rij +ri2kar +ri2kä +ri2kin +ri2kn +ri4kone +ri2kor +2rima +ri2mag +ri2mau +ri2me. +2rimm +2rimp +rim2s +rin2c +r1ind +rin4dex +rin6dize +2rindu +ri3n2e +rine1i +2r1inf +rin2fo +3r2infr +rin2ga +ring3le +rin2gr +2r1inh +2rinit +4rinj +4rink +rin2kl +rin2ko +rin2kr +2rinl +6r5innenm +4r3inner +2r1innr +r1innu +4r1inq +2r1ins2 +3r2ins. +rin4sek +rin2so +r4inspi +3r2insy +2rint +4rinte +rin4t5re +2r1inv +ri2ob +4r1ir +r2is +ris2a +ri3s4an +ri4sch3o +ri4schw +3risik +ri3s2ko +rismu2 +r3iso +2risol +ri4s3p +r3isr +3riss +rist5ers +ristes4 +ri6stess +ri4st3r +3ri2ß1 +r2it +rit2a +r3i2tal +rit3ant +2ri3t4r +rit1s2 +rit4t3au +rit4tei +3ritter +rit2to +rit2t1r +5ritu +rix1 +ri3xi +1rí +2r1j +4r1k +rka2b5l +r2k1ak +rk1all +rk2am +rk1are +rk1asp +rkauf4s +r2k1äh +r2kef +r3kel +r4kelem +rke2n1 +rk5ersta +r2k1erw +r3ket +r2k1im +rk4las +rk4lau +rk4lim +r2klis +rk2lo +rk2lu +rk4n +rk5nu +r2kob +r3kol +r3kon +rk1o4ri +r2kou +rk2ö +rk3räu +r3kri +rk3rin +r2k3rom +r2krou +rk2sei +rk2sel +rk2ser +rk2so +rk2sp +rk3spi +rkstati6 +rk4stec +rk4stoc +rk2ta +rk2tel +rk4t3eng +rk4t3erf +rk4terg +rk4t3erl +rkt3ers +rk6tersc +rk4t3erw +rk4t3erz +rk4teta +rk2tin +rk2t1o2 +rkto4b +rk2t3r +rk2tum +rk2um +rku2n +rku2sa +rkus3s +rku2s1t +r2küb +2r1l +rl2ab +r3lag +r5land +rlan4d3i +r2l1ar +r2l1a4sc +rlas2t +r2l3aug +rle2a +r3lec +r3lep +r3lex +rlg4 +r3l2i +rli4ne. +r3l2o +rlou1 +rl2ö +rlös5s +rls2a +rl2spr +rl2sto +rl3t +r3l2u +rlus2t +rlu6ster +rlu4str +r3ly +rlz2 +4r1m +r2mab +r2m1ad +rma2la +rm1ald +rm1ami +r2m1ank +r4mantr +rm1anz +r2m3aph +r2marc +r2marz +rma4spe +rma5ssen +rmas8sens +rmat2o +rm2är +rm3d2 +r4m3einh +rme4na +rm2ene +r2ment +r2meo +r2m1erh +r2m1erl +r2m1erp +rm2es +rme3sa +rme3st +rmeta2 +r2mide +rmi6nanz +rminen4 +rmi6neng +rm3m +rm1o2ri +rm3p2 +rms2 +rm3sa +rm3sk +rm3sta +rm3t2 +rmu2n +r4muna +r2muni +2rn +rna2b +r3nad +rn4ade +r3nage +r2n1all +rna4n +rn4and +rn3ani +r2nanz +rna2r +rn3are +r4n3ari +r4n1a4st +r4n3att +r2nau +rn3aug +rn3de +rn3d4r +r4nef +rn2eid +r4neif +r4neis +rn1ema +rne2n +rn1ene +rn2eng +r2n1ep +r4n1erg +rn4erhi +r4n1erl +r4n1ert +r4n1erw +r4nerz +r5nes +rn2e2t +rne4tem +rn2eu +rne3uf +r4nex +rn3f +rn3g2 +r2nid +r2nin +r3nit +rnk2 +rnn2 +r3nod +rn2oh +rn3oly +r2n1op +r2n1or +rn1ö +rnö2d +rn3s2a +rn3s2ä +rn3s4p +rns2u +rn3s2z +rn3t2a +rn3t2e +rn1ur +r1nü +r1ny +rnz2 +2robj +rob2l +1robo +ro2bo2r +ro2bre +2robs +ro1ch +roch2a +3rock. +r2o3de +ro3e4 +2roff +ro3fl +4rog. +rog2a +3rogg +roh1l +4rohn +ro2hö +3rohr +3roi +ro3in +rok2l +ro3le +ro2liv +rol4lan +rolle4 +roll4en +rol6lerg +rol6lerw +rolli4n +rol6lini +2roly +4rom. +ro2mad +ro2mal +3roman. +2romb +romen3e +ro2m1er2 +2romn +4romt +r2on +ro3n4ab +ro2nan +3rond +4ronk +3ronn +rons2 +ron4tan +ron6tend +ron2t3r +ron2t1u +ro1ny +ro1o2f +2ro2pf +1ropl +2ropt +r1or +ro2r3al +ro2rat +2rorc +ro2rel +ro2ro +ror3th +rort4s +ror2ü +ro3sh +ro3s2i +ro5s2k +ros2p +ros4san +ross1c +ros4st +ro3sta +ros3tel +ro2st1r +ro2sum +4r3osz +ro2ßi +ro2ßu +ro2tan +rot3au +ro2tä +ro3te +ro2tei +ro2t3ho +ro2tru +rot1s +rots2o +3roul +ro3unt +5rout +4roy +rö2b3l +rö2du +2rö2f +3röh +2r1ök +1röl +2röl. +rö3le +r1ölp +3römi +r1ör +r2ös. +rös1c +r2ö3se +1rösl +4röß +3rötu +2r1p2 +r3pa +r3pe +rperer5 +rper3in +rpf4 +r2pli +rp4lu +rpo4str +rp3se +rps1t +r4pt +r3pu +2r1q +2r1r +rr2ab +rra4s3s +rrat2s +rr1auf +rr1äm +rrb2 +rr1c +r5rega +rr2ei +rre2le +rre2pa +rr2er +rrer2s +r3res +rres2t +rre2ve +rr2hen +rr2hos +rr2i +rri3k2 +rrm2 +rrn3au +rr2o +rr3obs +rro3m +rro2re +rr2th +r3r2u +r3r2ü +rrz2 +4r1s +r3sabo +r2sa2d +rs2al +r4samp +r4s1amt +rs2an +rs3ana +r4sanf +r4s3ang +rs3anm +r4sanp +rs3ar +rs4ark +r4sarm +rsch3e4b +r3schen +r6scherl +r3schu +r2s1ebe +rse2e +r2s1ef +r2sein +rse2n +r3sena +rs2end +rse4ne +r2sepi +rs1ere +r2serh +rs1ers +r2serz +rse2t +rs1eta +rs2ext +r3s2hav +r3shir +r3sho +rs2hor +r4shu +rs2il +rs2ka +rs2kel +rs2ki +rs2kl +r4skor +r3s4kri +r4sky +rs4mog +r3s4no +r2sop +r4s3ort. +rs2p4 +rspa3s +r2s3ph +r3spi +r3spl +rs4por +r2spun +rs3s2 +rst3abl +r5stad +rst3ala +r4stale +r4stans +r4stant +r2stas +rs2tau +rs2tea +rs2tee +rst5eing +r6st5eint +rster2 +rst4erb +r6sterbt +r4st3erl +r4sterö +r4st3erw +rs2t3h +rst3ing +r2stip +r2stit +rs2tob +r2s1tot +rs2tra +rst3ran +r6strang +r4stris +rs2tu +rsuch4s +r3suf +rsü3s +r3sy +rs2zin +r1ß +4r1t +rt1abs +r2t1ad +r2t3ae +rt1akr +r4t3albe +rta3l2e +r2t1all +rt1am +r3t2ame +rt1an +rt2anb +r2tang +r2tanw +r2t1ar +rt3att +r4tauft +rt3äh +rt1änd +rt1ärm +r3te. +rte1e2 +rt1ein +rt4eind +r4t3einh +r2telf +rte3li +rtel6lei +rte2n1 +r3ten. +rte4na +rten3s2 +r4t3ents +rten3z +rteo2 +rt3erei +r6tereig +r4terfa +r4ter4fo +rt1erh +rt1erk +r4t3erla +rter8löse +rter6mit +r4t3ernä +r2terö +rter4re +rt1ers +rt4ersp +rt1erz +r3tes2 +rte3sk +r2texa +rt3he +r2t3hi +rt3hol +rt2hum +r2tid +rtik2 +r2t1ima +rt3inf +rt2is +r2t1o4b +r3top. +rto1pf +rt1or +r2torg +r3tork +rt3rams +rt3rand +rtra4s3 +rt3rati +rt3rec +r3tres +rt3ris +rt3rol +rt3roma +r3trop +r2trou +r4ts +rt3sän +rt3sch +rt4seh +rts2el +rt3sex +rts3ing +rts1o +rt1spe +rt4s3tan +rts4tie +rt3t4 +rt1umb +rt2u3na +r4tunt +r2t1up +r2t1urt +rtu2t +r2t3ute +rt3z2 +1ru +ru1a +ru4ale +ru3a2r3 +rube4 +rub2i +ru3ches +rucht3s +rude2a +ru2dr +3ruf +ru2fa +ruff4 +ruf2s1 +ruf4ter +ru2g3r +3ruhm +2r1uhr +3ruin +ru1ins +ru1is +2rum +4r3umd +4r3umf +4r3umg +ru2mi +4r3uml +4r3umsa +4r3umw +4rumz +2r1una +2rund +run4d1a +runden5e +run4d3er +run2e +runei2 +4r1unf +run2ga +2rungl +4r1u2ni +r3unio +ru4nis. +run2kr +4r1unl +2r1unm +4runn +4runr +r1unse +4r3unt +4runw +2rupd +ru3pr +4r3u2r +rur1e +5ru3ro +ru2si +rus2p +rus3sen +rus2s1p +rus6st +rus2t +ru2tab +rute4 +ru2tei +ru2t1el +rut3h +ru2t1o2 +ru2t3r +rut6scha +4ruz +ru2z1w +1rü +2rüb +4rübu +rü1ch +rücks2 +rück5sta +rü2hel +rüher2 +rüh1l +4rümm +rün3z +rü3ss +rü4ssi +2r1v +rv2el +rve4n1e +rvenen4 +r4ventz +rve5s +r3v2o +rv2s +2r1w +rwe4gel +r3wei +rwelt4s +r5werk +r5wert +r2wo. +r3woh +r3wort +rwun3s +4r1x +1ry +ry2c +ry3s2t +rysti1 +2r1z +rz2ans +r2zant +r2zar +r2zat +r3zähn +rz2än +rzell4a +r5zene +rz1eng +r4z3ents +rze2p +rze2ra +r2z1erd +r2z1erf +r2z1erg +rz1erk +r2z1erl +r2z1erw +rzes2 +r2z1ess +rz1id +rz1int +rzir3 +rz2of +r2z3ot +rz2tan +rz2th +rzu4g3l +r2zwä +r3z2wec +r2zwir +1sa +3sa. +3s2aa +2s1a2b +sa3b2ä +4sabd +3sabet +s3abi +4sabm +sa4bor +4s3abs +4s1acc +5s2ache +sa2cho +sachs2 +sach3t +s2ack +s1ad +2s3ada +2s3adm +2s3a2dr +sa4fe +4s1aff +sa1f4r +3saft +saf2tr +3sag +sag2e +sa3ge. +5sa3gen. +4s3a4gent +4s1agg +sa2git +sag4n +4s1a2gr +3sahs +3s2ai +sa3i2k1 +sail4 +sai4r +2s1ak +sa2ka +sak2e +3saki +4sakk +4sakt +3s2al. +s2al2a +sa2l3an +sa2lar +sa3lat +sal3bl +3sald +sa4lerk +3sali +sa2l1id +s1all +sal4le. +sallo3 +3salo +sal2se +2s1alt +s2al3t4h +3salz +3sam +s1ama +4sa2mat +s2ame +4s3a2mei +s3ameri +5s2amm +6s3amma +4s1amn +s1am3p4 +4samph +s2ams +s1an +s2an. +2sa2na +sa2nä +2s3anb +s2an2c +3s2and +san4dan +san4dri +sand3s +sa2ner +3sang. +2s3anh +3sani +3sanken +2s3anl +2sanm +2sa2no +2s3anp +2s3ans +s4anse +san4sk +san3sp +4santei +4santr +4s3anw +2s3anz +s4anz. +2s1ap +sa2pe +sa2po +sap3p +3sapr +2s1aq +2s1ar +3s4ar. +3sara +4sarb +3s2ard +s2are +s3area +sar2ga +sa3rin +s2ark +sa2rom +s3arr +s2ars +4sart +sa4r1u2 +2s1asc +2s1a4si +2s1a2sp +4s1asy +3saß +sat2a +sa4t3ant +sat1ei +2s3a2tem +s3ath +3sat2i +2s3atl +2satm +sat2o +sa2tol +sa2tom +sa2tr +s3atta +4s3attr +3satz +5satza +sat4zel +sat4z3en +s1au +3sau. +3sauc +3sau2e +2sauf +4s3aufb +saug3le +sau2gr +sau3h +3saum +sauri1 +2saus +3saus. +4s3ausb +4sausf +4sausg +sau2sp +4sauss +3sauste +4s3ausw +2sauß +s1av +sa2ve +sa2xi +sa3xo +sa2y +1s2äb +3s2äc +3s2äg +s1äh +4s3ähn +2s1ält +2s1äm +4s3änd +3sänf +4s3äp +2säq +2s1är +3s2ärg +sä4s3 +sä5sse +3s2ät +1säu +2säuß +4s3b4 +sba4ne +sbau6men +sbe3r2e +sbus3 +1sc +2sc. +2scab +2scac +2scaf +2scal +2scam +2scar +s1ce +4s3cei +sc4h +6sch. +s2chal +sch3ana +4schanc +4schang +5schanz +4schao +4s3chara +4sch3ar5m +s2chä +2schäq +2schb +2schc +2schd +sch2e +3sche. +4schech +6schef. +6schefi +6schefs +4sch3ei. +sch6ein. +4schemp +s4cher +sch5erfü +3sches +4schess +s2cheu +4schex +2schf +2schg +2schh +schi4d +schi4e +5schif +4schiru +3schis +2schk +sch4lac +4schle. +6schlein +4schloc +4schlöc +4schmas +4schmed +4schmoh +2schmö +4schmüh +2schmy +2schn. +4schneb +4schnut +4schobj +4schorc +2schox +4schör +4schp +2schq +4schrad +4schre. +4schrep +4schrin +s3chris +sch3rom +4schron +4schrou +6schs2 +sch3sk +6scht +sch3t2a +sch3te +scht2i +scht2o +scht1s +s4chu +4schunt +5schü +2schv +sch4web +4schweg +6schwerk +4schwet +4schwid +s5chy +2schz +2scj +6s1cl +2sco +3s2cop +s2cr +2scs +2scu +4s1d2 +sda3me +sdien4e +s3do +sd4r +1se +se3ar +se3at. +seau4 +seb2 +5sebä +2s1e2ben +2s1echo +sech6str +2s1echt +2s1eck +se2dik +3see +see1i4 +se2e3ig +se2el +see3len +se3en. +seen2e +se3er. +see1ra +seer2e +se3e2r1i +se1ers +see5s2 +see3t +2s3eff +sef4l +3s2eg +s3e2gal +se2gl +seg4r +3seh +seh1a +se2ha2g +se2hel +seher4e +se4herk +se2h1in +seh3l +se2h3ö +seh3re +seh5r2i +seh3s +seh3t +se2hüb +2sei. +2s1eic +2s1eid. +sei3da +4s3eifer +2s1eig +sei3le +s2eim +s1ein +5s2ein. +2seinb +seinbus6 +sein4du +2sei3ne +seine3i +4seinfl +sein4fo +2seing +2s3einh +2seini +2seink +2seinl +2seinn +2seinr +s4eins. +4seinsc +4seinsp +sein8stit +sein6str +4seintr +2seinw +2s3einz +2s1eis +3s2eit +seits1 +3sek +4s1e2kel +4sekz +s2el. +se2l1a +se3lad +3s2elb +sel1ec +se2lef +2s3e2leg +2selem +se2ler +sel3ers +2self. +s1e2lit +2s1elix +s2ell +sel3le +se2lob +s2els +sel3sz +selz2 +sem2a +sem2e +2s1emis +2s3emp +s4en. +se4nad +se3nal +se4nas +sen3au +s2enb +3sendet +4s1endl +sen3d4r +senen1 +se4nene +4senerg +se4ners +s2enf +5seni +se2n1im +3senku +se2no +se4nott +se4noz +s2ensa +sen4s3e4h +4sensem +s2enso +senst2 +sen8s7turm +sent2a +sen3tä +2sentd +2sentf +4sentg +4sentn +sen3tr +2s1ents +2sentw +2sentz +se4n3u +3senva +sen4zer +sen3zw +seo2r +se2pen +5seq +s4er. +se2r3a2d +ser3al +ser3ass +ser3äus +serb2 +s3erbe. +se2re2b +se4r3eim +s4eren +se4r3enk +s4erfe +s2erfr +s1erfü +4serfül +ser3g2 +s1ergä +s2ergr +s1erh +5serie +ser3k4 +3serl. +4s3ermit +s2ern. +2s1ernä +s3erneu +4s3ernt +s1e2ros +s1erot +s1erö +s2ers. +2sersa +ser6sehn +4ser4set +se3ru +se4ruh +ser2um +s1e4rup +3s4er3v +s1erz +s4es. +se3s2a +se2sel +2sesh +se3sk +s1essa +sest3ri +set2a +2s1e4tap +se2tat +s1e2th +2s1e2tik +set1s +se3tun +2se2ty +3setz +3seuc +4s3eul +se1u2n +s1ex +5sex. +2sexa +se2x3en +s2exi +s2exo +4sexp +sex3t4r +2sexz +6s3f4 +sfal6l5er +4s3g4 +sgang4 +sga3su +sge3s2 +sgro3 +2s1h +4sh. +sh2a +3s2ha. +s3hac +shal4li +shalt2 +4shan +4shc +sh2e +1shen +4shf +3shi. +3shid +s4hig +s2hip +s2hi4r +4shk +sh3n +4shoc +4shof +4shom +3s2hop +sho4re +5show +4shö +sh4r2 +4shs +4sht +s3hu +4s3hü +1si +si2ad +sial5l +sia4s +2siat +sib4 +5s4i1c +si2cha +sid2 +s2ide. +s2i3do +2sidy +3s4ie +sie2bu +sieh1 +sie4hes +si3e2n +si1err +si1f4 +si2g1a +si2gei +sig4n +si2g3r +sigs2 +si2k1ab +si2kak +si2kar +si2k1ä +si2k1el +siken2 +sik3erl +si2ket +si2k3i +sikin1 +si2k3n +siko3 +si2k3r +sik3s2 +sik3t4 +si2ku +sil2br +sil2e +3sili +s1ill +3silo +3sim. +2s1imm +sim2st +3simu +si3n4a +2s1ind +2s1inf +sing1a +sin3g4le +sin2g3r +sing3s2 +2s1inh +s1in1i1 +sinner4 +2s1inno +2s1inq +2s1ins +s2ins. +2s1int +2s1inv +3sio +sirn4 +2sirr +3siru +3sis +si2sa +si4sam +si4schu +si2s1e2 +si4sis +s1i2so +si2s3p +sis3s +s2ist +si4star +si3sto +si2stu +si2su +3sit +si2tal +si2tau +si2tra +s2it2u +3siu +si2va +sive3 +si4v3erf +siv1o4 +si2vor +siz2 +1sí +4s3j +2s1k2 +4sk. +sk4a +4s3kab +s3kad +1skala +4skalk +4s3kam +4skana +4skanä +3skanda +4s3kap +4s3kar +4s3kas +ska4te. +4skateg +ska4tes +ska2to +4skä +4skb +ske2li +4sken +3skep +4sker +s3kh +3s2ki. +3s2kif +3s2kik +s3kin +4skir +s2kis. +3skiz +sk4l +4s3klas +3s2klav +4s3klu +4sk4n +4skoh +4skol +4skom +4skon +3skop. +sko2pr +4skos +4skow +4skö +4skra +4skro +4sk3s +4sk3t2 +skto2 +3skulp +4skun +sku2s3 +4skü +4skv +2s1l2 +4sl. +s3lab +3slal +sla2ve +s2law +sl3b +4s5le +s3li +3s4lip +4sln +s3lo. +slo3be +s3loc +s3loe +s3lof +3s2low +s3lu +s3ly +2s3m4 +sma3b4 +sma3sc +sme3na +smi2t3 +2s3n2 +snab4 +sni4a +sni3er. +sni3ers +4s5not +3so. +2s3oas +2s1o2b +3s2o3ba +4sobj +4s3obo +so1ch +so3et +s1ofe +so2fen +3soft +3sog +s1o2he +3sohl +sohle2 +2s3ohng +2s1ohr +3soi +2s3ok +1sol +3sol. +so3la +so4lau +3sold +3sole +so2l1ei +so3li +sol2la2 +sol4ler +so3l2o +4s3o2ly +1som +1son +son2a +sone4 +son3sä +son4s1o +so3o +s1op +2sope +2sopf +3sopr +1sorb +s1orc +2s1ord +sore2 +so2rei +so2rel +2s1orga +so1rh +2s1o2rie +so2ro +3sorp +3s2orti +so4ru +1so3s2 +3s2os. +3sosc +so4sk +2so4sm +2s1o4st +s1o4sz +3so3ß +soth1o +3sott +soun2 +sound1 +so3unds +so3unt +s1out +3sov +3sow +2s1ox +3soz +s3o4ze +s1ö2d +2sö2f +2s1ök +2s1ö4l +2s1ö4s +sp2 +2sp. +2spaa +s2pace +2spack +2spag +spa2ge +2spak +2spala +2spalä +3spalt +spa2m +1span +s2pan. +3spannu +2spano +3spant +2spanz +4spap +2s3para +1spare +s4parka +2sparo +1sparr +5s6parten +4spartn +4sparty +spas2 +spa3sse +spa5ssi +1spat. +2spati +2spatr +2spau +3s2paz +s2pä +2späd +3späh +2spär +2späs +2spe. +2speg +1spei +3speic +4spein +1spend +4spensi +spe3p4 +s2pera +3sperb +3s2perg +s1peri +4sperle +2spero +s2perr +sper4ra +2spers +4spet +3s4pez +2s3pf4 +4spha +s2phä +3sphär +s3phe +1spi +3spi4e +4s3pier +spier4r +s3pi2k +4s3pil +2spip +4s3pis +3s2pit +3s2piz +2spl +4spla +4splä +3s2pli +4s3p4lu +2s3pn +2spod +4spoe +s2poi +2s3pok +4spol +1spon +s2pons +2spop +1spor +s2pore +s2porn +4s3pos +4spote +4spr. +3s2prac +s2pran +2sprax +3spräc +2spräm +s2prän +2spräs +3sprec +2spred +4spreis +5s2pren +2s3pres +3spring +4sprinz +s2prit +4sprob +4sprod +2sprog +4sproj +2sprop +5spross +2sproz +3sprö +3s2pru +3sprüc +2sprüf +1sprün +2s3ps +2spt +2spub +2spud +1spuk +3s2pule +s3pun +2spup +3spur +spu4rer +2sput +1spü +2spy +2s1q +4s3r4 +sra4s3s +srat2s +sre3cha +sreli1 +sre4th +sro3tu +srö2s +srücker6 +2s1s +6ss. +4ssa +s3sa3ba +ssa3bl +ssa5bo +s5sack +ss2ad +ss4agi +s2s1aj +ss3alba +s2sall +s4samt +s2sanf +s4sang +s4sano +s4sans +ss2ant +s4sanz +ss2ara +s3sars +ss3att +ssau3e +ssau4r +4s3s2ä +4ssb +6ssc +s2sce +ssch2 +s2scr +4ssd +4ss1ec +4sse1e +4ssef +4sseg +4sseh +sseh2a +4ssei +ss4eind +sse3int +4ssek +4sselek +sse2lö +4ssemp +6ssendet +4s3sendu +6ssenerg +ssenmas6 +ssen6sem +4ssentl +4ssentz +ss1epe +sse6ratt +ss2erf +ss3erfü +ss4ergr +sser4hö +sser6mit +s2serö +sser4öf +4ss3erse +ss4eru +sser6wei +4ssesc +3ssesh +sses4sa +4ss3e4str +sse3ta +s3sety +4ssez +4ssf +4ssg +4ssh +ss3hi +4ssic +ss3i2ko +s2simp +6ssio +s4s1isr +4ssit +4ssj +4ssk +s3skala +4s4s3l +4ssm +4ssn +4sso +sso2f +ss1off +ssoi4 +s3sol +s4sop +ss2orc +4ssö +4ssp +ss2pen +ss2phi +s3sprä +s3spri +ssquet4 +4ssr +4s4s3s4 +sssau4 +4sst +sst2a +s5stad +s6stag +s3stä +ss1t2e +s4ste. +s5stel +s5s2tep +s5stern +s4stes +s4stet +s5steu +ss1tis +s3sto +s5stop +ss1tor +s3stras +s3strat +s3strö +s3stü +4ssum +s2sumg +s2sumr +ss1ums +4ssunt +4ssup +ss2ur +s3sus +4ssü +4ssv +4ssw +4s3sy +4ssz +1st +6st. +3s4ta. +5staa +5stab. +2stabb +4stabel +2stabg +2stabh +4stabit +2stabl +2stabn +2stabt +2stabz +st2ac +3s2tad +4stada +4stadm +4stadr +2stag +3s2tagr +3stah +2stak +2stala +sta3lak +2stalb +2stalg +3sta3l2i +2stalk +st1alp +st1alr +3stam +st1a2mi +4stampl +4stamt +4stanb +s2tand +4stanf +6stangeh +4stanh +4stanl +4stanm +4st1ann +st3ansp +4stanst +2stanw +4stanza +2st1app +s2tar. +sta6rens +s2t2ars +2stasc +stast4 +2statb +7s2tati +7statth +7statu +2stauf +2staug +5staur +2staus +st1a2ve +2stax +3stäb +3städ +2stäg +2stält +2stämt +3ständ +4stäp +5s2tär +3stätt +2stäus +4stb +2st3c +4std +3ste +4steam +s2tean +4stechn +4stecu +ste2d +st1edi +ste2g3r +s2teh +4stehr +4steic +4st1eid +5s2teig +stei4gr +4steil +6steinga +6steinhe +stein6sp +s2tel +s3tele +5st2ell +stel6l5än +ste4mar +ste6ment +6stemper +4stempf +ste4na +4st3ends +st2ens +4stentf +4stentl +4stents +4stentw +4stepi +st1e2po +ste2r3a +s2terb +4sterbs +6stereig +s2terf +st3erfü +st2erg +s2terh +s2terj +s2terk +sterma7sse +s2tern +6sterras +s2ters +ste4s1e +stes3ta +4stestb +4stestn +stes3tr +4stests +ste4tag +s2teu +4steuf +st1eun +st1ev +4stex +s2texa +4stf +2stg +2sth +st4hen +st3hi +st3ho +4stief. +4stiefl +3s4tiel +3stif +st2il +4stimma +2stimp +2st1inb +2stinf +3sting +2stins +4stint +s4tio +2stip. +sti2r +st1ira +st1iri +st1ita +2stite +2stj +2stk +4stl +4stm +stma3s2 +2stn +sto2bl +4stocht +s2tode +3s2tof +stof8fens +6stoffiz +3stoj +sto3mi +2stomn +2ston +s2to4ne +2stope +2stopo +2stord +2storg +s2tory +3stos +4stou +4stöch +2stöl +5s2tör +2stöst +2stöt +4stp +2stq +st4rade +3straf +stra4fa +2strag +3s2trah +2strai +3s2tral +4strans +s2tras +3straß +4straum +2sträc +2s3träg +4sträne +2stre. +4strech +2stref +2streg +4streib +5st6reif +2strep +2stret +2strev +3s4tria +2strib +4strig +4strisi +2striu +4stroc +3s2trof +3stroh +3s2trok +4stropf +3s4tropo +st4ross +4strost +3stroy +2ströp +2strub +3struk +s2trum +2strun +4strup +4st3s2 +stsas2 +2st3t4 +st2u +3stub +4stuch +3stud +2stue +3stuf +2stug +st3uga +3stuh +2stuk +2stumo +2stumr +2stum2s +s3tumsc +2stumt +2stumz +2stun. +2st3una +2stune +2stunf +2st3uni +2stuns +2stunt +3stuö +stu3ra +stu5re +2st3url +2s3turn +2st3urt +3s2turz +4stüch +3s2tück +3stüh +2stür. +2stüre +2stürg +2stürs +2stürw +2stütc +2stv +2stw +stwor2 +2sty +4sty. +4s3typ +4stys +2st3z2 +1su. +su1an +3su2b3 +su4ba2 +4subi +su4br +5su1c +su2cha +su2cho +3sud +su2eb +2s1u2f +su3fi +2s1uh +1sui +su1is +su1it. +su2k +su3l2i +su2m1a +s2ume +su2mei +su2mel +sument4 +su6ments +2sumf +s3umfa +s3umfe +su2min +3summ +sum1o2 +su2mor +s2ump +s3umsa +2sumse +s2umsp +2s3umst +2s3umwa +su2n +2s1una +sunder4 +sun6d5erh +sunds4 +su4ne +4s1unf +6sungena +s3ungl +4s1uni +2s1unm +s1uns +2sunt +3s2up +sup3p4 +su2ra +sure4 +su2rer +3surf +2s1urk +s1url +su2r1o +s1urt +su2s +su3s2a +sus1e +sus1i +s3u2t +su3tr +2sü4b +3süc +sü2d1 +süden4 +sü3den. +3sün +1süs4 +sü3sse +sü3ssi +1süß +4s3v2 +svoran4 +2s1w +s3we +swe6gers +sweh2 +4swie +4swil +4swis +4swit +s3wö +s3wu +1s2y +2sy2l3 +sym3 +sy2n3 +3sy5s +2s1z2 +4s3za +4szä +4s3zei +4szel +3s2zena +3s2ze3n2e +4s3zent +4s3zer +s2zes +s2zeß +s4zew +4s3zie +s3zins +4s3zo +sz3ta +4s3zu +4s3zü +4s3zw +4szy +2ß3a4 +ßan1 +ßat3 +2ß1ä +2ß1b4 +ßbus3 +2ß1c +2ß1d4 +1ße +2ß1e2b +2ß1ec +2ß1ef +2ß1e2g +2ß1ei +ße2l +2ßelek +ße3lu +2ß1emp +ße4n3a4 +4ßenerg +ße2ni +ße2no +2ß1entl +2ßentz +ße2nu +2ß1e2p +3ß2er. +ßer3b +ßer2ei +ße2ro +ß2ers. +2ßerse +ßer3t +ß1erw +ße2s +2ß1es2s +2ß1est3r +ße2t +2ß1ex +2ß1f4 +2ß3g2 +ßge2bl +2ß1h2 +1ßi +ßi2g1a +2ß3i2k +2ß1il +2ß1im +2ß1in +ß1j +2ß3k4 +2ß1l2 +2ß1m2 +2ß3n2 +2ß3o2 +ß1ö4 +2ß1p2 +2ß1q +ßquet2 +4ß3r2 +ßreli1 +ßrö2 +ßrus3 +2ß3s4 +ßsau4 +ßsch2 +2ß1t +ßt3h +ßt1in +ßts2 +1ßu2 +ß1uf +2ß1uh +2ß1um +ß2ung +ß1uni +2ßunt +ß1ü4 +2ß1v +2ß1w +2ß1z2 +2taa +2tab. +ta2b3an +2t1abb +2tabd +1tabel +2tabf +2tabg +2tabh +2t1a2bit +2tabk +2tabla +1table +4tabm +2t3abn +2ta4br +4tabs +t1abst +2t3abt +4tabw +4tabz +2t1ac +3tacu +t1ada +2tadd +ta2der +tadi3 +tadi4s +t1adm +ta2dol +t1a2dr +ta3d2s +tad4t3 +ta2er +1tafe +2tafet +t1afg +t1afr +1tag +ta2ga +ta2g1e2i +tagen1 +4t3a4gent +2t1agg +ta3gl +2t1a2go +tag2s1 +tag4san +tag4st +2tah +tah2li +3tai +ta3i2k +tai2l1 +ta1ins +tai4r +ta1ir. +ta1i2s +1tak +2t1a2ka +ta3kes +2t1akk +ta2kro +2taks +tak2t1o2 +t2aktu +2takz +3t2al. +ta2la +ta3lag +tal1an +ta3lat +tal3au +1talb +tal3d4 +1tale +ta4l3end +tal3eng +ta4lens +tal6ents +ta4lerg +ta2let +tal2ga +tali6ene +tal4l3ac +tal4leg +tal4lei +tal4let +tal6leut +tal6lin6s +tal4los +tall2ö +tall3s +tal4lus +2t1alm. +ta2lop +ta2l1o2r +tal2se +tals3en +t1al3ta +tal3th +talt4r +ta2lu +2tam +3tam. +t2amen +t1a2mer +tam2ma2 +tam4m3er +tam4mi +tam4mut +t1ampl +3t2ams +t1amt +t1a2na +tan3ab +4tanal +ta4nat +2t1a2nä +tan3da +tand4ar +tan2dr +ta4nerf +4tanf +4tangeb +tan4gra +2tanh +t2anho +t4ani +3tanj +1t2ank +tan2kl +2t3anl +t1anm +4t1anna +3t2anne +t1ano +t1ans +t2ans. +4tansi +tan4tan +t4ante. +4tantei +2tantr +2tanwa +2tanwä +t2anz. +t1anza +4tanzei +t1anzu +4tanzü +tan2z1w +tao2 +ta3or +t4ape +ta2pes +2tapf +ta2pl +ta4poka +t2appe +ta2ra +2tarab +3tarabb +ta3rak +2taram +tar3ap +t2arau +2tarb +3tarba +3tarbek +3tarber +3tarbi +3tar3bl +2tarc +3tarchr +t2ard +t2arei +ta2rel +ta2r1er +tar3g +ta1r2h +3tari +tark4l +t2arko +4tarkt +t2arl +2t1arm +t2armä +ta2rom +2tart +t2arta +tar6ter6e +3t2arth +t1arti +3t4artis +tar2to +tar2tr +ta2ru +2t1arz +3tarzu +t2as. +ta3sa +1tasc +ta5se +4t1asp +2t3assi +1tast +ta4stem +ta2sto +ta3str +t4at. +ta2ta2b +ta2tan +3tatb +t4ate +tat1ei +t5a2tel +ta2tem +1taten +ta2t1er +t3atl +ta2tom +ta2tr +1tatsa +2tatt +tau2b1a +1taubh +tau2bl +tau2br +tauchs4 +tauch5sp +2taud +t1auf +3taufe. +4taufg +tau3f4li +2taufn +t3aufo +taufs2 +2taufw +1taug +4t3auge +t1auk +3taum +1taume +1taus +2t1ausb +tau6scha +tau6schm +tau6schr +tau6schw +2tausd +t2ause +2tausf +t3ausg +t1ausk +2tausl +2tausr +2t3auss +2t5ausw +2tausz +ta2van +3t2ax +taxi3s +4t3axt +2tää +2täb +tä1c +2täd +t2äf +1täg +2tägy +2täh +3täle +2täll +2t1ält +4tä2m +t1ämt +t1ängs +1tänz +2t1äp +2täq +tä4reng +tä2ru +2tärz +tä2s +t2ät +3tätigk +4tätt +2täug +1täus +2täuß +2täx +1tŕ +4t3b4 +tbauer4 +tbe3r2e +tblock5e +tblocken8 +tbus3 +2t1c +t3cha +t3che +tch2i +tch3l +t3chr +t2ch1u +tch1w +t3cl +tcor2 +t3cr +4t5d4 +tdar2m1 +tdun2 +1te2a2 +tea3c +te3ad +te3ag +2teak +te3al +teamma3 +te3an +te3ar +tea4s +3teba +t4ebb +2t1e2ben +t2ech +1techn +te2chu +2teck +t1ecu +te2dit +1tee +te1em +teen1 +te2er. +te1erw +tee3t +3tefa +2teff +2t1egg +te2hac +2tehe +te2him +2t1ehr +1teic +tei1fl +teik2 +1t2eil +tei2la +tei6lent +teim2 +2tein +t2ein. +teinbus6 +t2eine +teinen4 +tei6nens +tein6hab +t3einkü +te2i3s +t1eis. +t1eisb +te5isch. +tei3t +t1eiw +tei3z +te2kel +tek3t4 +te2la +tel3ab +tel1ac +te3lan +te4lant +tel1au +te2lä +teld4 +tel1ec +1telef +1teleg +tel3ehr +2telem +tel3eng +te2ler +te2leu +4t3elf. +te4lim +te2l1in +te2lit +tel6lant +tel3le +tel6lein +tel3li +tel6li6st +te2lob +te4lost +te2l1ö +tel3s2k +tel3ta +telt4r +te2map +te2m1au +te3mä +t2emb +te2m1ei +te2m1er +2temg +te2mi +tem3i2m +tem3ing +2teml +2temn +2temo +te2m1o2r +3temper +2tempf +1tempo +te2mu +te4mun +t6en. +ten1a2 +te4nad +te4n3an +te4nas +te4nat +ten3au +ten3ä4 +ten3da +t3endal +tend4an +4tendap +2t5endf +2t1endl +t6endo +2t5endp +ten3d4r +te2n1e2b +te2nef +te2neh +ten3ei +te3n4ei. +tene4m +tenen1 +te4n3end +te4nene +te4neng +te4nens +4t3energ +te4n3ern +tenf4 +t1eng. +teng2a +4ten4gag +t3engla +te2ni +te4nil +ten1im +te4n3in +tenk4 +ten3n2 +te2nol +te3nö +4t3ensem +ten6serg +1tenso +tens2p +t2enta +t1entb +2tentd +ten3te +2t3entl +2t3entn +ten6tric +t3en4tro +2t1ents +4t5entw +2tentz +te2nu +te2ny +teo2f +2t1e2pi +tept2 +t4er. +t4era +tera2b +ter3ac +te2rad +te1ral +tera2m +ter4ane +te2r3ap +ter3as +2t1erbs +2t1erbt +ter3d +4t3erde. +terd2s +te2re2b +te2rec +t3ereig +tere2m +te4r3emi +te4r3end +te4rene +te4reng +te4r3ent +terer3k +terer3l +te4r3erp +te4rers +te4rerw +te2ret +t4erfr +terg2 +ter3ga +6tergebn +t6ergem +t6erges +t6ergew +ter3gl +6tergrei +t4ergru +2t1ergu +2tergü +t6erhall +t4erhan +t4erhau +t4erhäu +t4erhei +t2erhi +t2erho +6terhöhu +t2erhu +te3ria +ter3iko +terin5d +ter3k +4terklä +t4erlä +t4erli +termas4 +1termi +t2ern. +ter4nar +t6ernc +ter4obe +2teros +t1e2r1ö +t4erp +t4erra +3terras +ter4re. +t4erro +t4ers. +t2erse +terst4 +t4erst. +t6erstad +ter6stat +t4erstä +t4ersti +t4erstr +t4erstu +t4erstü +ter3t4a +tert2o +t4eru2 +te4r1uf +t4erv +4t3erwäh +4tery +ter3z2a +2t1erzb +t4erzei +4terzeu +ter5zo +ter3zw +te2s +tes3ac +tesa2k +te3sä +te3sc +tes3eli +te3ser +te3si +te3so +te3sp +tes1pe +te4spr +2t1essa +3tesse. +tes3si +tes2t +tes3tät +1testb +te6sterg +te6sterh +te6sterk +test3r +t3estri +1tests +t2et. +te4tabl +2te2tap +te2tat +4tetl +3teuf +te1u2n +2t1eup +te2va +te2vi +tewa2s +3tewo +1tex +t1e1xa +2t1e2xe +te3xel +2t1e2xi +4texp +tex4ta +2t1exz +2t3f6 +tfäs3 +2t1g2 +tga4s3er +t3ge +tgenen3 +tger2a +tger2i +tg4r +tgro3 +t1h +4th. +2th2a +3t4ha. +3t2hag +4thak +3thal. +t2hali +3thalp +t2han. +t3hand +t3hap +4t3hau +2thä +4thäl +2thb +4thc +1t2h2e +3thea +2t3heb +2t3hef +2t3hei +t4he1in +3t4hek +t4hema +2themd +t4heme +2themm +t4hene +t4heni +3theo +t3herd +t4herm +thero3 +2t3herr +2t3herz +4t3hess +2thf +t2hi +3thi. +thic3k4 +t3hiel +thi3er. +2t3hil +2t3him +t3hin +thi3nu +2t3hir +2thk +2th3l +4th3m2 +thmu2 +2th3n +t2ho +2t3hob +t3hoc +tho3chr +t3hof +2t3hoh +t4hol. +t4holo +2tholz +2t3hot +3thotr +2thou4 +t3hov +2t3hö +2thp +1th2r2 +2ths +2tht2 +2thub +2thuh +4t5hun +2thut +2thü +2thv +t2hy +ti2ad +ti3ag +tial2l +ti3a2m +ti2are +tib4 +ti1ce +ti3chr +t1id +t2id. +4tidee +ti4d3en4d +tie3br +1tief. +4tiefel +1tiefl +tie2fr +tieg4 +ti2e1i +ti1el +ti2el. +tiel3a +ti3e2n1 +tie4rei +tie4reu +tiermas6 +ti2ern +1tierr +2tieß +ti1eu +1tif. +ti3fe +tif3f +ti1f4r +ti2gan +2t3i2gel +ti4gerz +ti2git +tih2 +tihi4 +ti2kam +ti2kar +ti4kau +ti3k2en +tik4ere +ti2kin +ti4klu +ti2kn +tik1r +ti2kra +ti2krä +ti4k3rei +tiks2 +ti4lant +ti2lar +ti2lei +ti2lel +1tilg +3tilgu +tille4b +2tillu +ti3lo +ti2lö +tilt4 +ti2lu +ti2ma2g +2timm +tim2ma +timma6te +timmer4 +tim6merg +tim4mit +2timp +ti3naf +ti3nak +ti2nam +ti2n3an +2t3ind +ti5n2e +tine1i +2t1inf +tin2g1a +tin4g3l +ting3s2 +t1inh +3tinis +t1in1it +4tinj +t1inka +tin2k1l +tin2kn +tin2kr +t1inku +t2inn +ti2nor +t1ins +t2ins. +t3insa +t2insä +4t3inse +tin4spa +tin4sum +t1int +ti3nu +tin2um +4t1inv +3tio +ti2osk +tioxi3 +1tip. +ti3p4l +3tips +ti4que. +1tirad +ti1rh +ti4ron +ti6schei +tisch3l +tisch3w +ti2sei +ti3sk +t1isl +ti2sp +t1isr +ti3s2th +ti4s3tic +ti2su +2t1iß +tit2a +ti2tal +3ti3te +tium2s +ti2van +ti2vel +ti4vene +tiver2 +ti4verh +ti4verk +ti4verl +ti2v1o +ti4v3r +ti2za +ti2zir +2t1j +4t3k4 +2t3l2 +4tla +tlan2g +tl4e +tlei6der +tle2ra +4tli +tlings3 +tli5ni +tlit1 +t5lö +2t1m2 +tmen8schl +tmen4t5 +tmo4des +t3mu +4t3n4 +t5na +tnes4 +tni3v +to4as +to5a4t +t2oba +1to3be +2tobj +tob2l +t1obs +1tobt +to1ch +2t3ochs +1tocht +2tock +tock5ent +1t4od +tod1er2 +todes3t +to2d1un +toffen8st +tof6f5ent +tof4f3er +2toffi +2t3ohr +toi4r +tok4 +to3le +1toler +tomar4b +tom1en +2tomg +to2min +2tomk +1tomo +to2m1u +to4mun +1ton +to2nan +ton3au +tond2 +to2n2eh +toner6ke +to4n3ig +to3ny +3too +to3om +to2pak +to2pan +to2pat +top1hi +1topo +2to4pt +t4or. +to4rän +t1ord +t2ordi +2t3ordn +t4ore +to4rein +to2rel +to2rem +to3ren +tor4fan +t1or3g +2torga +6t5orient +tor3int +to2rop +to2rö +1torp +t4ors +2t1ort. +tor3ta +1torte +t1orth +tort4s +to4ru +to3rü +to4rüb +t2orw +to3s2 +tos4s +to2tä +1toten +to2tho +1t2ou +touil4 +to3un +tö2c +1töch +2töck +2t1ö2d +2tö2f +4t1ök +1tö4l +2töl. +1tön +t1ö4st +1töt +2t3p4 +tpf4 +tpi2n +2t1q +t2r4 +2tr. +t4rab +1trac +tra3cha +tra3chl +2t3rad. +tra4dem +1tradi +t3radie +2tradp +tra4fah +tra4far +1t4rag +tra5gen +2trahm +3t4rai +2t3rake +t4rakt +tra4leb +tral3l +1tram +3t4ran. +4trand +1trank +t3rann +5t4rans +1trapp +tra4sta +tra4str +2traß +1trau +4traub. +4trauc +t4rauf +2traup +traus2 +2trauß +1träc +2träd +1träg +1träne +t1räts +2träuc +1träum +4t5re. +2trea +t3reak +2treb +tre2br +2trec +t3rech +t4reck +3treck. +2t3red +1tref +2trefe +2trefl +2trefo +2treg +2t3reh +t4rei. +1t4reib +2treif +2t3reig +2t3reih +t4reik +2t3rein +2t3reis +tre7isch. +2treit +t3reiz +t3rek +2t3rel +t4rem +t4ren. +1trend +1trenn +t3rent +2trepe +2t3repo +1trepp +t3repr +t4rer +t4res. +1tret +tre2ta +t4rete +tret3r +tre4tri +2t3rett +t4reu +2t3rev +2t3rez +3t4ré +2t3rh +3t4rib +t4rick +t4rid2 +1trieb +1trief +trie3fr +tri4ena +tri2er +2trig. +2trige +t4rigg +tri3gl +t4rik +tri4ke. +tri4kes +1triko +1tril +1trin +t3rind +2tring +tri3ni +t3rinn +3trio +t4rip +2triß +1triu +2t5riv +tri2x +trizi1 +tro3b4 +1troc +4trock. +t4roi +tro4kes +trol4la +2trom. +tro6mans +tro4men +tro2mi +1tromp +tro3na +t4rop +tro1pe +3tropf +tro3sm +1trost +2trout +4t3röc +2tröh +2tröm +1tröp +2t3rö4s3s +1tröt +1trub +2t3ruc +4truf +1trug +4t4ruk +trum2 +t3rumä +trums1 +t3rund +1trunk +3t4rup +t3russ +2t3ruß +2t3rut +tru2th +trü1be +trü1bu +2t3rüc +trücker6 +t4rüg +3trümm +try1 +2ts +4ts. +ts3ab +t3sac +t4sachs +t2sa2d +ts1ahn +ts5alben +t2sall +t4samp +t4s1amt +t2san +ts3ane +ts3a2r +t2s1a4s +tsa5ssen +t2sau +ts2av +t1sä +t2säh +t2s1än +ts1äus +t2sce +t4sch3am +t6schart +t4schef +t3schl +tsch4li +t3schra +t4schro +ts2cor +t2s1e2b +tse2e +t2sef +ts1eh +tse4he. +t3seil +t3seme +ts1eng +t3s2ens +t2s1ent +t2s1ep +t2s1er +t6s5essen +tse2t +ts1eta +t2seth +t2s1eti +t2s1e2v +t2sex +t3sexi +t2s1i2d +t2si2k +ts3iko +tsing4 +t2sini +ts1ir +4tsk +t1skal +t3skala +ts4kele +t4s3ko +tsmas4s +tsma5sse +ts1off +tso2r +ts1ori +ts3ort. +t3sos +t1s2ouv +ts1par +ts4pare +ts1pas +ts3pate +t1sped +t1s2pek +ts4pend +ts2pi +t2s3pic +t4spins +ts3ple +ts2pon +ts2por +ts4put +ts5s4 +tst4 +t4stabe +t2staf +t4stale +ts3tanz +t2stas +t4s3tat. +t4s3täti +t2stea +t4stee +t4s1tep +t4sterm +t4s3terr +ts1tie +t3s2til +t3stim +t2s1tis +t2stit +t4stoch +t2stoi +t2stor +t4strac +t4strad +ts4traf +t4stren +ts4tric +t4strie +ts2tro2 +ts2tub +ts2tüm +ts1u +3tsubi +t2sumz +ts3un +t1sü +tsü3s +tswa2s +4t1t +tt1ab +tt2ac +tt3achs +t5tack +tt1ad +tt2ag +tta6g5ess +t4t1ah +tta2ke +tt2al +t2ta4n +tt4anke +t3t2ant +t4t1ap +tt1art +tt1äh +t2tän +tt1ebe +tt3echs +tt1eif +tt1ein +t2t1eis +tte4la +tte4l3e4b +t4te4leg +tte4len +ttel3l +ttel1o +t2temu +tte4na +ttens2 +t4tentb +t4tentf +t2teo +t3ter +tt4ere +tt2erg +tte4rik +ttermas7s +tter3nä +tte2ro +tt2erö +tt2es +tte4sa +tte4s3ä +tte4s1o +t4teuf +tt2häu +tt3hi +t2t3ho +t2tid +t2t3igi +t2tins +tt2int +tt4lef +t3to. +t2torg +t3tos +ttras3s +t2trou +tt3rü1 +tt2sen +tts1p +tt4s3tät +tt4s3tem +tt4ster +tt3s2z +ttu2 +ttu3b +t2tuc +tt1uf +t4tunt +t2tu4s +ttü2 +tt3z2 +3tua +tu4ale +tu1alm +tu1alv +tu3an +tub2 +tuba3b +1tuc +tu2chi +tu1cho +tudie4n3 +3tue +tu3en +tu2ere +2tuf +tuf2e +tu3fen +t3u2fer +3tuff +tuf4fel +tu2gan +3tuge +2tuh +tuh4ler +tu1ist +t3u2kr +tul2i +1tum +tum2b5l +4t3umf +2t3umg +2t1umh +2t3umk +2tuml +3t2umo +2tump +2t3umr +4t3umsat +2t1umsc +tum2si +tum2so +2t3umt +2t1umw +t3umz +1tun. +2t1una +2t1und +tund2e +1tune +tun2en +2t3unf +t3unga +2tunif +2tu2nio +2tuniv +2t1unm +3tunn +t1u2no +t3uns +1tuns. +2t3unt +2t1unv +2t1up. +tu2r1a2g +tu2ran +turan4l +tu2ras +tu2rä +tur1c +tu2r1e2b +tu2rei +tur3eis +tu4rene +tu2r1er +tu4res +tu2re2t +tu2r3e2v +tur3f4 +turg2 +tu2rid +turin1 +tur4mun +1turn +tu2r3o +tur3s2 +tu4ru +tu2sa +tu4schl +tu2se +tu2so +tu3ta +2tüb +tü3ber. +1tüch +tück2s +1tüf +2tüh +1tür. +tür1c +1türe +1türg +1türs +1türw +2türz +1tütc +1tüte +2tütz +2t1v2 +t3vo +tvoran4 +2t3w +twa2 +twä4 +twi4e +t4wist +1ty +3ty. +2t1ya +ty2pa +3tys +2t1z +t2za2 +tz1ag +tz3ar +tz1au +t2z1ä +t3zäh +tz1ec +t2z1e2d +tz1ehr +t2z1eie +t4z1eis +tze4n1 +tz2ene +t4z3entg +t4zentl +t4z3ents +tz2ere +tzer6gre +tz1erw +t3zer3z +tzes1 +tze2t +tz1eti +tz1i2d +tz1int +t2z3om +tz2th +tz2tin +tzu2gu +t2zuni +tzwan4d3 +tz1wä +tz1wi +t3zwie +tz1wu +2ua +u3a4b +u1a2c +uad4r +u1a2g +u1ah +u1al. +u1a2l1a +u1a2l1ä +u1alb +u1ald +uale2 +u3a2leb +u3a4lent +u3aler2 +ua4lerg +ual3erk +u3a2let +u1alf +u1alg +u1alh +u3a2lid +ual3l +ualle2 +u1aln +ua2lo +u1alp +u1alr +u1als +u1al3t4 +ua2lu +u1alw +u1alz +u1am +uan2a +u1ans +uant2 +u3ar. +uara2b +u1ars +uar4t3an +ua3sa +ua2th +uat2i +uat2o +u3au +uau2s +u1ay +u1äm +u1än +uäs4 +u1äu +2u1b +ubb2l +ube2be +u8becken. +ube2e +u2b1ehe +ub1ein +ube4n1a +uben3o +ub2er +u4b3erde +ubert4 +ub4es +ub1eul +u3bit +ub2l +ub3läu +ub3lic +ub3lu +ub4lut +u2bob +u2bop +u2b3oz +ub3ric +u2b3rit +ub4rü +ub2san +ubsau2 +ub6s3che +ub2s1o +ub2sp +ubst2 +ub4sz +ub3t4h +ubu3s +2uc +uc1c +uch1a +u1cha. +uch1ä +u1che +uch1ec +u2ched +uch1ei +ucherin8t +ucherma8s +u1chi +uch3im +uch1in +uch3l +uch3m +uchma6ss +uch3n +uch1op +u2ch3r +uch4sel +uch2so +uch2sp +uchst2 +uch6t5erf +uch6t5ert +ucht3re +u1chu +u2chum +uch3ü +uch1w +u1ci +uck3elf +uck2er +ucker8geb +uck3i +uck4sti +uck3t +u1cl +2u1d +u3d2a +ud2e +ude3i4 +udein7 +udel3se +uden1 +uden3e +udert4 +udi3en +uditi4 +ud2ob +u2don +ud3ra +u3dru +2u1e +u2ed +ue2en4 +u2eg +u2eh +ue2k +u4ela +ue2le +ueli4 +uel2la +uel3lan +uel2lä +ue2mi +uen1 +u3en. +ue4n3a2 +u3end +uene2 +ue2ner +uen4gag +uenge2 +uenge4m +uen2gl +u3e2ni +uenk4 +ue2no +ue2nu +uen6zene +uen2zu +uen2zw +u2ep +ue2r3a2 +ue2r1ä +uerb2 +uer6baut +uer3d2 +uere2 +ue2rec +uer4ei. +ue4rein +ue4r3emi +u3eremp +u3e4r3ent +ue3r4erb +u3ererf +ue4rer4g +uerer4h +uerer4l +uerer4m +ue6rersc +uerer6sp +ue6rerst +uer3esk +ue2ret +u3erex +uer3g2 +u3erin4t +u3erl. +uerma6s +u3ern +uer4nan +uer4ne +ue2r3o4 +uer2ö +uer3r +u3errü +uer3sc +uerst6 +uer3t4 +u3eruh +u3erum +u3erunf +u3erunt +u3erwi +uer3z2 +ue4s +ue5se +ue5sp +ue2ta +ue4tek +ue2ti +u2ev +ue2x1 +uf1ab +u3fac +u3fah +uf1ak +u3fal +ufall4 +ufa2n +uf3ane +u2f3a2r +ufa2t +uf1au +u2f1än +u2f1ä6s +u2f1ä2ß +u2f1ei +ufel4s3a +u2f1em +u3fen. +u2fent +u2ferf +u2f1erh +u4ferla +u4ferle +u4ferne +u2f1eß +u2f1et +2uff +uf3fe +uffel2 +uff4l +uf2fro +u2f1id +u2fim +u2f1ins +uf3l +u2fob +ufo2r +uf1ori +uf3r +uf5sä +uf3sc +uf2spo +uf4stab +uf4ster +uf4s3tic +2uft +ufta2b +uft1eb +uf3ten +uft3erd +uft3er4g +ufter4l +uf4tin +uft3s2 +u2fum +2u1g +ug2abe +u4gabte +u2g1a2d +u2g1ak +ugang4 +u2gani +u2gans +u2ganz +u2g1ap +ug1ar +uga4s +ug1au +ug3d4 +u3ge. +ug1ei +u2geig +u2gein +uge4lob +ugenma3 +ugenmas6 +u2g1erf +u2g1erl +u2gerr +u2gerv +u2g1esk +ug2et +ugg2 +ug2gl +ug5g4t +ug3hu +u2g1i2d +u2gim +ug1in +u2gl +u4g1lä +u6gleitb +u6gleitu +u4glic +u4glis +ug3liz +u4g3lo +u4glu +u4g3n +ugo3 +u2go4b +u2g3oc +u2g3om +ugo4p +u2g1or +u2gö +u2g3rä +u2greg +u4g3reis +u2gres +ug3rie +ug3ro +ugro3s +u2grou +ug3rüs +ug3sei +ugsma3 +ugsmas4 +ug2spe +ugs4por +ug3stä +ugs1te +ug4stur +u2gum +ug4unge +ug2uns +ugu6sten +ugu6ster +u2gü +u1h +uh2a +2u5he +uhe3a +2uhi +2uhl +uh1la +uh2lar +uh1lä +uh4l3ent +uhl3erb +uh2li +2uhm +uhr1a +uhrei4s +uh2r3er5 +2uh3ri +uh4rin +uh2r3o +uh2ru +uh4rü +uhs4 +u2hu +2uhü +uh1w +2ui +ui1ch +ui2che +u1ie +ui1em +u3ig +u4ige +uil4les +u1im +u3in. +uin3n +u3isch. +u3ischs +uis2e +uisi4n +ui2st +uit3s +u1j +uk2a +uk1äh +u3käu +u1k2e +uke2n1 +u1ki +2u1k2l +ukle1i +u1k4n +uko2m1 +uk2ö +u1kr +uk2ta +uk2t1el +uk2t1er +uk2tin +uk4t3o4ri +uk2t3r +ukts2 +uk2tum +u1ku +uku2s +uk2ü +u1l +ul1am +ulan2e +ul2ar +ula2sc +ul1äm +ul4dan +ul2dei +ul2dr +uld2se +2ule +u2l1el +ul1emb +ule4n +ul1er2h +ule4s1t +ule2t +ul1eta +2ulf4 +ul1id +uli2k +ul1ins +ul3ka +ul2kn +ulla2g +ull1au +ul2lä +ul3len +ul3l2i +ulli2n +ul2lo +ul2lö2 +ull3s2 +ulm2e +ulni2 +ulo2i +u2lop +u2l1or +ulp1h +ul2pha +ul2sa +ul4sam +ul2s1ec +ul2sei +ul2ser +ul2sum +2ult2a +ult3ar +ul2tri +ult3s +u2lü +ul2vr +ulz2w +u2mab +u2m1ad +u2m1a2k +um1all +um1ang +u5mann +um1anz +u2m1ap +um1a2r +u2marc +u2marm +u2mart +u3mat +u4matl +u4matm +u2maus +u2maut +u2m1äh +1umd2 +u3me. +u2m1ef +u2m1ein +umen1e +um5engel +umens2 +umer2a +u2m1erf +um1erg +u3merk +u2m1erl +um1erw +ume4s +1umf +1umg +um1ide +um1ind +um1inh +um1ir +1umk +1uml +2umm +um3mä +um4mess +u2m3ot +ump2fa +ump4fin +umpf4li +um2pho +1umr +um4sam +um4s3an +1umsat +um2s1er +um2sim +um2s1pe +um4stem +um2sum +um3t4 +u2m3um +u2m1u2r +1umz +un1 +2un. +2una. +1unab +3unabh +un2a3br +un2ag +un2al +u3n2am +u2n3an +u2nap +u2narb +2un2as +un3at +unau2s +un2är +2und. +un2da +unda2b +un4dap +1undd +2unde +un3de. +underer6 +und3erf +und3erö +underten8 +under8tend +und3erz +un2dex +1undf +2undg +un2dim +1undn +undo2b +un2dop +un2dor +2un2d3r +4unds. +2undsc +und3sp +un2d1um +undü4 +1undv +1undz +u3ne +une2b +une2d +un3eid +un3ein +un3eis +un2emi +une4n1 +unen2t +u4nerk +u4n3erz. +un2es2 +unf2 +un3fa +unft2s +un2gam +un2gat +3ungena +unge3r4e +1unget +1ungew +un2glu +1unglü +un2go +un2gr +ung3ri +ung4s +ungs3tr +ungstra8s7 +u3nic +3u2nif +uni3k4 +un2im +1unio +un2ir +un3iro +un3isl +u3n2it +1u2niv +2unk +un2k1a2 +un3ker +un2k1es +un2ket +un2kne +unko2p +un2kro +unk3s2 +unk4tit +unk2tr +unlö2 +un2n1ad +unn2e2 +unne4n +u2nob +uno4r +un2os +1unr +uns2 +2uns. +unsch5el +1unsi +un3sk +un3sp +uns4t +unsta4g +unst1r +2unsy +2unsz +1unt +un3ta +un3te +unte4ri +2unti +un3tr +unt3s +2untu +3unty +2u2nu +u3nuc +u1nü +unvol2 +unvoll3 +1unw +2unwä +u2ny +2unz +un3z2a +unz2e +2uo +u1o2b +u3of +u1op +u1or +u3or. +u3or3c +uore4 +u3o2ret +u3ors +u3ort +u3orw +u1os. +uote2 +u3o2x +u1ö2d +u1ök +u1pa +3upd +u1pe2 +uper1 +upe4re +uperer4 +up2fa +upf1i +u1pfl +u1p2fu +3upg +u3p4i +up4lu +up2pl +u1pr +upra3 +u2p3ras +up4t3a2 +upten1 +up4tene +upt3erf +upt3erg +upt3erk +upt3ers +up4tid +up4tim +upt1o +u1q +4ur. +u1ra +u2rab +u3raba +ura2be +u2r1akt +u2ral2t +u2r1a2m +ura4na +uran3a4t +u3rand +ur1ang +uran4ge +ur2anh +uran5s +ur1anz +ur3ap +u2r3ar +ura4ri +u3rasc +ur3a4sp +ura4str +ur4ate +ura3to +u2r3att +u2r1au +2u1rä +ur1äl +ur1ä2m +ur1än +ur3b2a +2urc +urch1 +urchas4 +urcht3e +ur3d2a +ur3d2i +ur1eff +ur1eig +u2rele +ure2n +ure4na +uren6gag +u4rense +u4rentn +u2r1ep +ur1er3h +urer3k +ur2ert +u2rerw +ur1eta +ur2eth +ure3u +2urf +ur2f3l +ur2fro +urf4spr +urf3t +ur6gense +urg3inn +urg1l +ur2gla +ur2gri +uri2c +ur1ide +uri3en +u2rind +urin8stin +ur4mant +ur4matt +ur2mau +urm2ei +ur4mern +urmet1 +ur2mum +ur2mun +ur3n2e +4u1ro +ur1off +urost2 +2u1rö +ur3p4 +2urr +ur3re +3ursac +ur2san +ursau4 +ur2s1er +ur2s1of +ur2spa +urst4r +ur2sun +urt2 +2urta +ur4tai +urt3ein +ur2tro +u3ru +ur2z1a +ur2zä +ur2z1ec +ur2zep +ur2zi +ur2z1op +urzt4 +ur2z1w +2us +us3a4b +u4s3af +usa2gi +u3sal +u4sall +u4s1amb +u4samt +u2sang +us2ann +us3ark +us5art +u2s1a4s +us3ate +u1sä +u2säh +u2sce +u4schab +u4schak +u4schef +usch5eic +u4sch3eu +u3schi +usch3mü +u3schu +usch5wer +u3se. +u3s2e3b +u2s1ec +u2s1ei +u3seid +u4sense +u4sentl +u3sep +use3ran +use4rec +u2s1erl +u2serp +us1erw +u2s1ese +u2sex +u3si. +u2sid +usi3er. +usi5ers. +u3sig +us1inn +us5is. +us3kl +usmas2 +usma5sse +u1so +us3oc +us1oh +u3sol +u2sop +us1ou +u1sö +u1sp +u2spac +us3part +u2s1pas +u3spec +u3spek +u2sph +us1pic +u2spo +us2por +u2spu +usrich7 +us2s3eb +usse4g +u4s3sel +us2se4n +us5sende +us6seni +us2sep +us2ser +us3ser. +uss3erf +usser4z +u4sset +us2sez +u3s2sig +uss3k +us2sof +us2sum +u2stab +u3stal +us2ten +us2ter +ust3erl +ust2in +u3stis +u2s1tor +u3stras +u2s3trä +u4strit +u2s1tur +us3ty +u1su +u2sumd +u2sumg +u2sumz +3usus +2uß +u2ß1u +2u1t +u3ta. +u3taf +u2t1alt +ut1a2m +ut2ans +u2t1ap +u2t1ar +u2taut +ut1äh +u2tär +ut3c +u3te. +u4t1e2d +ut1ei. +ut1eie +ut1ein +ut1ela +ute2n1 +u3ten. +uten2a +u2tent +uter3a +ute4ral +ute5r4er +ute6ring +ute4ros +u3t2es +u3t2et +u2t2ev +u2t1ex +utfi4 +ut3hel +u2t3hi +u2t3ho +u2thu +u2thy +u2tid +uti2vi +utli4n +utmas2 +utma5sse +u3to. +uto4ber +uto3c +u5to3m +uto1p +uto3pa +u2tops +utor2a +u2tord +u2töl +4utr +ut3rea +u2trou +ut3rü +ut3sau2 +ut2säu +ut3sche +ut4schl +ut4schm +ut4scho +ut4schö +ut3ser +ut3s2k +ut1so +ut1s2p +ut3sto +ut3tan +ut3t2l +utt4le +utt1s2 +utu2b +u2tum +utu4n +u2t1une +utu4re +utu3ro +utu5ru +u4tz +utze2 +ut2zeh +utz3eng +utz2er +ut2zet +ut2z1in +ut2z1w +2u3u4 +uum1 +uuma2 +uungsma5 +uungsmas8 +u1ü4 +u1v4 +u2ve. +uve3rä +u1w +2u1x +ux2e +ux2o +uxt2 +u1ya +2u1z +u2z1ec +uz2er +uzo2f +uz3ot +uz1we +uz3z2 +uzz4l +1üb +üb1ä +2übc +2übd +üb4e2 +übe3le +übe4na +übe3ne +über3 +überas4 +ü4bet +üb3l +üb3r +2üc +ü1che +üch3l +üch4s1c +ücht4e +ücke4n +ück1er +ück3eri +ücker6ke +ü4d3a4 +üde2l +üden2g +ü3d2ens +üd3o4 +üdö4 +üd3r +üd3s2 +üd3t4 +üdu2 +üdwe4 +üe2 +üeb3 +ü1ei +ü4f1a +ü2f1ä +ü2f1ei +ü2fent +üfer2 +ü2f1erg +üf2fl +ü2f3i +üf3l +ü2fo +üf3te +üf4tei +ü2fum +ü1g +üg2e +üge2l1a2 +üge2lä +üge4lec +üge6lei6s +üge2lo +ügen3s +ü2g3l +ü2gn +üg3s +üh3a4 +ü1he +ü2h1ei +ü2h1eng +ü2h1ent +üh1er +ü2herf +ü2her2k +ü2her2z +ü2hex +üh1i4 +üh1lä +ühl2er +ühl4sta +ühl4sti +üh3mo +üh3ne +üh1o2 +üh3r2e +ühr3ei. +ühre2n1 +üh1ro +ühr3ta +ühs2 +üh3sp +üh3stu +üh3t2 +üht4r +ü1hu +üh1w +ü1k2 +ül1a +ül2c +ü3l2e +ü4l3ef +üle2ra +ül2la4 +üll1ad +üll1au +ül2lei +üll2er +ül4leu +ül2lic +ül2lid +ül2li2n +ül2lo +ül2lö +ülls2 +ü2lö +ü1lu +ü2ma +ü2ment +üme2ra +ü2m1id +ü2m1in +ü2m1u +2ün +ü4n3a +ün2da +ün2dr +ü2n1erd +ünf1 +ünf3li +ün2g3l +üngs2 +ünster3 +ün2za +ünzu2 +ün2zun +ün2zw +ü1pe +üpf3l +ü1pi +üp2p3l +ür1a +ü2r1ei +ü2r1e2l +ür2fl +ür2fr +ür4g3en4g +ürge4ra +ürk2e +ü1r2o3 +ürom2 +üror2 +ür4ster +ürte2l1 +ürt4h +ürz2a +ür2z1in +ür2zö +ür2z1w +üs2a +ü2schl +üs2e +üse1e2 +üse3l2 +üse4n +üse1r4 +üse3t +ü1sp +üs2s3a +üs2s1c +üss2e +ü4s3sel +üs2s1o +üs4st +üs2su +üs4t +ü2st3a2 +ü4stei +üste2n +ü2str +ü1su +ü1ß +2üt +ü1ta +ü2t1al +ü1te +üte3m +üte4n +üten3s +ütent4 +üten3z2 +üte2ra +üte2r1e +üterich6 +üter3n +ü2t3h +ü1ti +üt3r +üt2s1 +ütte4n +üt2tr +ü1tu +üt3z2e +üt2zw +ü1v +ü1z +3va. +2v1ab +vab4r +va1c +va1f4 +vag2a +va2la +2valu +2vanb +2vang +2varb +v1arm +vas2 +2v1ass +v4at +va2t1a2 +va2tei +va4t3eng +vates2 +va2t3h +va4tid +vatik2 +va4tim +va4t1in +vati8ons. +va4tord +va2t3r +vat3s2 +va2t1u +vat3z +2v1au +vä1 +2v1b +2v1c +2v1d2 +1ve2 +ve3an +ve3ar +veau3s +ve3b4 +ve3c +ve3d +ve3fa +ve3g +ve3h2 +2veig +v2eil +2vein +veit2 +veits1 +ve3la +2velan +ve4l1au +v1ele +ve3lei +ve3li +ve3lo +ve3ma +ve3me +2ve3mu +ve3nal +ve4nas +ven2c +ve3ne +ve3ni +ve4nin +ve3nö +ven5st +ven4t3ag +ve3nü +ve3of +ver1 +ver3a +ve3rad +2veral +ve3rand +ver4ane +vera4s +ver6bart +ver3b2l +ver3d2 +vere2 +verf4 +ver3fa +ver3g4 +vergas6 +verga7sse +ve3ri +ve4rin +ver3k +vermas8sen +vern2 +ver4sep +ver3sta +vert4 +ver5te +ver3u4 +ve3s +2vesc +2vese +ve4sh +ve4s1p +ves4t +ve3t +vete1 +vete3r +2veü +ve3v +ve3w +ve3x +2v1f4 +2v1g +2v1h +vi2ad +vi3ar +vi4a3t +vi2ä +vi3de +vie2ha +vi2el +viela2 +viele2 +vi2er +vie4rec +vie2w1 +vig2 +2vii +v2il +vi2l1a +vi2lä +vi4l1e2h +vi2lei +vi4lers +vi2l3in +vil3l +2v1i2m +vima2 +vi4na +2v1in3d +ving3 +2v1int +vi3sa +vise4 +vi3s2i +vi3s2o +vi2sp +vis2u +viv2 +vi3z +vize3 +2v1k +2v1l2 +v3le3 +v2lie +2v1m +vm2e +2v1n2 +1vo +2v1ob +vo2be +vob4l +vo3ga +voge2l1 +vo2gu +vol2a +voll3ar +voll7auf. +vollen6 +voll5end +2v1op +vo2r1 +vor3a +voran8schl +vore4 +vor3g +vo3ri +vo4rie +vo5rig +vorm2 +vormen4 +vor3o +vorö4 +vort4 +vot2a +voy1 +2v1p +vr2 +v1ra +v2ree +3v2ri +v1ro +2v1s2 +v3sz +2v1t +vue3 +vu2enu +vu2et +2vumf +2vumg +2vumk +2v1ü +2v1v +2v1w +2v1z +w2a +1waa +wab2bl +wa3che +wach8stub +wach4t4r +1wack +waffe2 +waffel3 +1wag +wa5ge +wage4n +wa2g3n +wa3go +1wah +wahl5ent +wah4ler +wah2l1i +1wal +wala3c +wa2lar +2walb +wal2d3a +wal4din +wa2les +wa3li +wal4li4n +wal2m1 +wals2 +walt1a +wal6tere +wal6terl +wal2to +wal4tur +wa3na +wan2d1a2 +wan2dr +w3anf +2wang +wan3g2e +wang4s +1wann +wan6z5en6d +wan4zer +wa2p +1war2e +ware1i +wa3ren +1warn +wart4e +war2th +1was +wa3sa +was2c +wa4scha +wa3sche +wa3schi +wa4sch3l +wa4schw +wa3sh +wass4e2 +wa3su +w2ä +1wäh +1wäl +wäm3 +2wäng +1wäs3 +wä5sc +wä4ss +wäss4e +2w3äu3 +2w1b2 +wbu2 +2w1c +2w1d +we2a +we2b1a +webe1i +we2b3l +we2bo +we2b3r +we2e2 +weed3 +we2fl +1weg +we2g1a +we4g1ei +weg5ersc +we4g3l +we4gn +we2g1o2 +we2g3r +weg1s +wegs2a +1weh +weh4r3er +wei2bl +weib4r +wei3dr +2weie +weifel6d +wei2gr +wei3k4 +1weil +wei3nel +weins3a +weinsau6 +wei3sc +wei2t3r +weit1s +wei5ze +welle4 +wel6schl +wel6schr +wel2t1 +welt3a2 +welte4 +wel6t5en6d +wel4th +welt3i +welt3r +wem2ma2 +wen3a2 +wen2gl +we3n2i +wen2ka +wen4kla +wen4k3ri +we2r3a2 +wer5be +werbe3i +wer2bl +werb2s +1werbu +werd2 +werde3i +5werdens +1werdu +werer2 +wer2fl +2werg +wer6gels +wer2g3o +wer2gr +werin2 +we4r3io +1werk. +wer4k1a +1werke +wer2ki +wer2k3l +wer2kn +wer2ko +wer4kre +wer2ku +we2rö +wer4sta +wer2ta +wer2tä +wer3t3ei +wer6teig +werter6k +wer6t5erm +wer2th +wer2t1o2 +wer4tre +wer4t3ri +wer4tum +1we3s2e +wesen4s3 +we2sp +wes4t +we4st1a +we4stec +we4st3ei +we5sten. +we6sten6d +we5stens +we4steu +we4sti +we4st1o4 +we2st3r +we4stu +1wet +2wets +wett3s +2w1ey +2w1g +whi2 +w3ho +w2i +wicht4s +1wid +wi2e +2wieb +1wied +wie3l2 +wie3n2e +wie4st +1wild +wim2ma +wim4m3u +win2a +win4d3ec +win4dei +win6d5erz +1win2d5r +2wing +win2g3r +win2kl +win8n7er8sc +win2no +win4num +win3s +wint2 +1wi4r +wire3 +wisch3l +wi3s2e +wi2sp +1wiss +wiss4z +wi3st +wi3th +1witz. +1witzl +wiz2 +2w1k +2w1l +2w1m +2wn +wns2a +wn3sh +1wo1c +wo2cha +woch2e4 +1woh +woh4lei +1wolf +wolf2s +wol4la +wol2lä +wol4ler +wor3a +wor3d +wo2r3i +worn2 +wort1a +wor4tel +wor6terh +wor2t3r +worts2 +wo4r3u +wor3ü +wot2 +1wöc +wöl2fo +wört4h +2w1p +w2r +w3ro +2w1s +ws2e +w3s2h +w3s2k +2w1t +wti2 +1wuc +wuch4sc +wuch4st +w1u2f +wuls2 +wul3se +wund4e +wung3r +wung5s2 +wun2s +wunsch5l +4wur. +wur2fa +wur2f1o +wur2fr +wurs4 +1wurst +wus4 +1wu2t1 +1wüh +1würf +1würst +wüs4 +2w1w +2w1z +x1a +1xa. +2xa2b +1x2ad +1xae +xa1fl +1x2a3g2 +2xal +xal2l +xa2m +xand4 +x2an3t2 +x2anz +1x2as +xau3 +xaus2 +2x1b4 +2xc +x1ce +x1ch +x1cl +4x1d +xda2 +xdy2 +1xe +2x1e4g +2xek +xe2l +x1ele +x1em +3x2em. +x2ems +x2en +xen3s2 +x2er. +x2ere +2xerl +xers2 +2x1eu +2x1ex +4x1f +2x1g +2x1h +xib4 +xi1c +xich2 +2xid +xi2dan +xide2 +xi2dei +xi2d1em +x1i2do +xi4ds +x2ie +xie3l +xi3g +xi2ler +xi2lo +xi2l1u +xim2 +xin3s2 +x2is +xi2sa +xi2s1e +xi2s1o2 +xi2sp +xis5s2 +xi3stä +xi2su +x1i2tu +xive4 +2x1j +2x1k2 +xkal2 +4x2l2 +x3lä +x3le +2x1m +2x1n +2xod +2x3oe4 +x1or +2x1ö2 +4x1p +xpor6ter +xpor4t3r +x1q +2x1r +4x3s2 +4x1t +xt1a +x3ta. +x3tan +xt2ant +x3tas +x2t1ä +x3tät +x2t1e2d +xt1ein +x2t1el +x2tent +x2t1er2f +x2t1ev +xtfi4 +x2t3h +x2tid +xti2la +x2til2l +xt1o2 +x2tor +xtra3b4 +x2t3ran +x2trau +xt3rec +xt3s2 +x2t1um +x2t1un +1xu +xu1a +2x1u2n +xu2s3 +xuss2 +2xv +2x1w +2xy +3xy. +3xys +2x1z +2yab +1ya2c +y2ach +y2ag +ya1h +y1al. +y1a2m +y2ana +yan2g +y1ank +y2a3ra +ya4s +yat2 +y1ät +y1b +y1c4 +y2chi +y3chis +ych3n +y1d4 +y3dr +ydri4 +ydrid1 +y1e +y2ec +ye2d +y2ef +y2el +yen4n +y2ere +yer2n1 +y2es +yes2p +y3e4st +ye2th +y1f2 +y1g +ygi2 +ygie5 +yg2l +y1h +yhr2 +y3i4 +y1j +y1k2 +yke3n +yk3s +y1l +yl1a2c +y2l1a2m +yla2n +y3lant +yl4ante +yl4anti +y4lantr +y3lat +ylau2 +yl3c +yle2 +y4le. +yl1em +y2l1es +y2l1et +yli4n +yl2lo2 +yl2lö2 +yloi4 +yloid1 +yloni1 +yl1ora +ym4a +ym4e +ymp2 +ym2pha +ympi1 +yn2eu +yn3k2 +y2n1o +yno4d +yno2t +yob2 +yoga3 +yom4 +yon2a +yon4i +y1ont +y1os +y2ost +y1ou +2y1p +ypa2 +yp1ab3 +yp1an +yp2e2 +y2pf +y2p1i2d +y2p1in +y2p3l +ypo3 +y4p3s +yp3t +ypu2 +y2p1um +y1q +y1r +yra3k +y3r2e +y3ri +yri2a +yri1e +yri3en +y3ro +yro6ste +yrr2 +y1s +ys2an +ys2c +ys2e1 +ysein2 +y3s2h +y4s3l +ysme3 +ys2o +ys2pa +ys2pi +yst2e +yst4h +ys2tra +y4stro +y3s2ty +ysu2 +y2sur +y3s2z +y1t2 +y2te. +y2tes +yt4h +ythe1 +y3to +y4t3r +yt3t +y1u2r +y1v +y1w +y1y +y1z2 +yzer2 +2z1a2b +zab3l +za1cha +za1chä +2z1a2d +2z1af +za3gr +3z2ah +zah3le +zah4ner4 +2z3ak +4zakk +2z1al +3zali +2z1a2m +z1a2n +z2an. +4za4na +2zanb +za3ne +2zanf +2zangs +3z2ank +zan2ka +2zanr +zanti1 +za4pf +z1aq +z1ar +3zar. +2zarb +2zarm +3z2aro +zar2tr +2z1as +za4sc +za3st4 +2z1aß +z3at +zat2e +za2to +3zaub +z1au2f +2z3aug +3zaun +z3aur +2z1aut +2z1äc +z2äh +2z1äm +z1än +z1äp +z1är +2z1äus +2zäuß +4z3b4 +zbe3r2e +zbü1b +zbübe3 +2z3c +2z3d2 +zdan2 +zdä1 +3ze. +zeau3 +zeaus4 +2z1e2ben +2z1echo +ze1e2 +zeeu3 +2z1eff +z1e2ga +zehe4 +zehen1 +zeh2l +ze3ho +z2ei1f4 +zeil2 +zei3la +zeile4 +2z1ein +ze3in. +zeinbus6 +z2e1ind +zei4ne +z2eino +ze3inse +ze2i3s2 +zeist4 +3zeit +zei2t1a +zei4t3er +zei2tr +zeit3ri +ze2l1a +zela2d +zelau2 +ze2l1ä +zel3d +2ze2lek +2zelem +ze2len +ze2l1er +ze2l1in +2z1e2lit +zel3la +zel4l3ac +zel2lä +zel4leh +zel6lein +zel6ler6t +zelli4n +zelm4 +ze2l1o +zels2 +zel3sa +zel3sz +zelu2 +zembe2 +2z1emp +5zen. +ze4n1ac +ze4nas +zen3au +ze3n2em +zenen1 +4zenge. +z4engl +2zengp +zen3n +ze2n3o +ze4not +4zensem +zens2p +zen4tha +z2entn +zent3s +2zentw +2zentz +ze2nu +zen4z3er +zen2zw +zeo4r +3z2er. +zer3a +ze1ral +zere2b +z2erfe +z2erga +2z1ergä +4z3ergeb +z4erges +z4ergl +zer4gon +2zergu +z2erhe +2z3erhö +ze3ri +zerin6te +z2erko +3zerl. +zer4lau +zer4le. +4zerleb +zer4len +2zerlö +3z2ern +zer4nan +zer4n3e4b +zer4nei +2z1erö +zer2öf +2z1erq +4z3erreg +z2ers. +2z1er4sa +zerta2 +zer4t3ag +zert4an +zer6tere +zer6terl +zer4tin +zer2to +6z5ertrag +zer6trau +z1erwe +2z1erz +zer2ze +4z3erzi +ze2s +3zes. +ze3sc +zes1e +zes3er +ze4s3po +ze4spr +zes2sa +zes4sei +zessen4 +zes6s5end +zes4ser4 +zes2sp +ze3sta +zes2th +ze2ß1 +2zeta +2z1e2th +ze2tr +2zetts +zeu2g3r +2z1eul +ze1ur +2z1e2x1 +2z3f4 +zfäs3 +zfeue2 +2z3g4 +zgang5 +zger2a +zger2s1 +2z1h2 +z2hen +zhir3 +3zi. +zial5l +zi3ar +zich2o +zi2dei +zid3r +zie4ler +zie2l1i +zi1erh +zi1es +zi3ess +3zig +3z2il +zil2e +zill2 +z2imm +2zimp +zim2t3 +2z1ind +zin2e +zin3ei +2z1inf +z1inh +zi4n3in +zin1it +2z1inj +zin2na +zin4o +zin2sa +zin4ser +4zinsuf +z1inv +zi2o3 +zirk2 +zirk6s +2z1i2so +zisse4 +zis4t +zistras6 +zi3s2z +zi2tan +zite4 +zithe2 +zi2t1o4 +ziv2 +2z1j +4z1k4 +2z1l2 +z3ly +2z1m2 +zmas6sen +zme2e +2z3n2 +z3oas +2z1ob +z1of +zo2gl +2z1oh +zolla2 +zol3le +zol4lei +zoller4 +zol6lert +zol2li2 +zon3au +zon3s4 +zon4t3er +zo2o +2zope +2z1o2r +zo3re +3z2orn +zor4ne +2z1osz +2z1ou +2zö2f +2z1ök +z1öl +zö4le +3z2öll +2zöls +2zön +2z3p4 +2z1q +2z3r2 +4z1s2 +z3sa +zsau2 +z3sh +z3sk +zspor2 +z3str +z3sz +2z1t +zta2n +zt3ane +z2t1au +ztein1 +zt3eins +zt2el +z2t1ent +z2t1erz +z3tes +zte3str +zt3he +z3t4hem +z3t4her +zt3hi +zt3ho +z3thr +z3thy +zt3rec +zt3s +zu3a +zu1ä2 +zub4 +zubus2 +3zuc +zuch2e +zud4 +zudi4 +zu2el +zu3e2r1 +zu3f4 +zu2gar +zu4gent +zu3g1l +zu4gla +zu4glö +zug4ste +zug1un +2z1uhr +zu3hu +zu1i2 +zu3k +zul2 +2z1um. +zum2a +2z1umb +zumen2 +2zumf +2zumg +zum2i +2zuml +2zumr +2z1ums +zum2u +2zunab +zun2e +2z1unem +4zunget +2z1ungl +z1uni +2zu2nio +2zuniv +2zunr +2z1uns +2zunt +zuo2 +zup2fi +zu3pl +zu3r4a +2z1urk +2z1url +2z1urn +2z1urs +2z1urt +zu3s2 +zusch4 +zu3t2 +zut4r +zut4u +zut3z +zuz2 +2zü4b +3züc +zür1c +2z1v +zw2 +z1wac +2zwag +2zwah +2zwal +2zwap +z1war +2zwa2s +2zwäs +2z1wed +2zweg +2zweh +z2weig +2zweil +zwei3s +zweiter6 +2z1wel +2z1wen +2z1wer +2z1wes +z2wic +zwi4e +3zwing +2zwirt +z2wisc +2zwiss +z2wit +2z1wo +z1wör +z1wur +2z1wü +zy1an. +zy2le4 +4z1z +z3z2a +zza3b4 +z4z3al +zz4at +zze3s +z2z1id +zzin1 +zz1ini +zz2ö +zzug4s +} + +\endinput + +% Local Variables: +% mode: tex +% coding: latin-1 +% fill-column: 72 +% End: +% vim: set filetype=tex textwidth=72: diff --git a/tmac/hyphen.en b/tmac/hyphen.en new file mode 100644 index 0000000..bd9b757 --- /dev/null +++ b/tmac/hyphen.en @@ -0,0 +1,5018 @@ +% title: Hyphenation patterns for American English +% copyright: Copyright (C) 1990, 2004, 2005 Gerard D.C. Kuiken +% notice: This file is part of the hyph-utf8 package. +% See http://www.hyphenation.org/tex for more information. +% language: +% name: English, American spelling +% tag: en-us +% version: 2005-05-30 +% authors: +% - +% name: Gerard D.C. Kuiken +% licence: +% text: > +% Copying and distribution of this file, with or without modification, +% are permitted in any medium without royalty provided the copyright +% notice and this notice are preserved. +% hyphenmins: +% typesetting: +% left: 2 +% right: 3 +% changes: +% March 1, 1990 Initial release +% May 30, 2005 Added copyright notice, no patterns change. +% texlive: +% encoding: ascii +% babelname: usenglishmax +% legacy_patterns: ushyphmax.tex +% message: Hyphenation patterns for American English +% package: english +% known_bugs: +% de-mo-c-rat: 'instead of dem-o-crat (see GitHub issue #15)' +% ========================================== +% +% ushyphmax.tex -- patterns for more hyphenation pattern memory (12000+). +% Also known as ushyphen.max. +% +% Needs extended pattern memory. +% Hyphenation trie becomes 7283 with 377 ops. +% +% These patterns are based on the Hyphenation Exception Log +% published in TUGboat, Volume 10 (1989), No. 3, pp. 337-341, +% and a large number of incorrectly hyphenated words not yet published. +% If added to Liang's before the closing bracket } of \patterns, +% the patterns run errorfree as far as known at this moment. +% +% These patterns find all admissible hyphens of the words in +% the Exception Log. ushyph2.tex is a smaller set. +% +% Please send bugs or suggestions to tex-live (at) tug.org. +% +% 2005-05-30 (karl): in the past, ushyphmax.tex was a file containing +% only the additional patterns, without the \patterns command, etc. +% This turned out not to be very useful, since in practice the TeX +% distributions need one self-contained file for a language. Therefore, +% ushyphmax.tex now contains both the additional patterns from +% Dr. Kuiken, and the original patterns and hyphenations from Knuth's +% hyphen.tex. +% +% The Plain TeX hyphenation tables. +\patterns{ % just type if you're not using INITEX +.ach4 +.ad4der +.af1t +.al3t +.am5at +.an5c +.ang4 +.ani5m +.ant4 +.an3te +.anti5s +.ar5s +.ar4tie +.ar4ty +.as3c +.as1p +.as1s +.aster5 +.atom5 +.au1d +.av4i +.awn4 +.ba4g +.ba5na +.bas4e +.ber4 +.be5ra +.be3sm +.be5sto +.bri2 +.but4ti +.cam4pe +.can5c +.capa5b +.car5ol +.ca4t +.ce4la +.ch4 +.chill5i +.ci2 +.cit5r +.co3e +.co4r +.cor5ner +.de4moi +.de3o +.de3ra +.de3ri +.des4c +.dictio5 +.do4t +.du4c +.dumb5 +.earth5 +.eas3i +.eb4 +.eer4 +.eg2 +.el5d +.el3em +.enam3 +.en3g +.en3s +.eq5ui5t +.er4ri +.es3 +.eu3 +.eye5 +.fes3 +.for5mer +.ga2 +.ge2 +.gen3t4 +.ge5og +.gi5a +.gi4b +.go4r +.hand5i +.han5k +.he2 +.hero5i +.hes3 +.het3 +.hi3b +.hi3er +.hon5ey +.hon3o +.hov5 +.id4l +.idol3 +.im3m +.im5pin +.in1 +.in3ci +.ine2 +.in2k +.in3s +.ir5r +.is4i +.ju3r +.la4cy +.la4m +.lat5er +.lath5 +.le2 +.leg5e +.len4 +.lep5 +.lev1 +.li4g +.lig5a +.li2n +.li3o +.li4t +.mag5a5 +.mal5o +.man5a +.mar5ti +.me2 +.mer3c +.me5ter +.mis1 +.mist5i +.mon3e +.mo3ro +.mu5ta +.muta5b +.ni4c +.od2 +.odd5 +.of5te +.or5ato +.or3c +.or1d +.or3t +.os3 +.os4tl +.oth3 +.out3 +.ped5al +.pe5te +.pe5tit +.pi4e +.pio5n +.pi2t +.pre3m +.ra4c +.ran4t +.ratio5na +.ree2 +.re5mit +.res2 +.re5stat +.ri4g +.rit5u +.ro4q +.ros5t +.row5d +.ru4d +.sci3e +.self5 +.sell5 +.se2n +.se5rie +.sh2 +.si2 +.sing4 +.st4 +.sta5bl +.sy2 +.ta4 +.te4 +.ten5an +.th2 +.ti2 +.til4 +.tim5o5 +.ting4 +.tin5k +.ton4a +.to4p +.top5i +.tou5s +.trib5ut +.un1a +.un3ce +.under5 +.un1e +.un5k +.un5o +.un3u +.up3 +.ure3 +.us5a +.ven4de +.ve5ra +.wil5i +.ye4 +4ab. +a5bal +a5ban +abe2 +ab5erd +abi5a +ab5it5ab +ab5lat +ab5o5liz +4abr +ab5rog +ab3ul +a4car +ac5ard +ac5aro +a5ceou +ac1er +a5chet +4a2ci +a3cie +ac1in +a3cio +ac5rob +act5if +ac3ul +ac4um +a2d +ad4din +ad5er. +2adi +a3dia +ad3ica +adi4er +a3dio +a3dit +a5diu +ad4le +ad3ow +ad5ran +ad4su +4adu +a3duc +ad5um +ae4r +aeri4e +a2f +aff4 +a4gab +aga4n +ag5ell +age4o +4ageu +ag1i +4ag4l +ag1n +a2go +3agog +ag3oni +a5guer +ag5ul +a4gy +a3ha +a3he +ah4l +a3ho +ai2 +a5ia +a3ic. +ai5ly +a4i4n +ain5in +ain5o +ait5en +a1j +ak1en +al5ab +al3ad +a4lar +4aldi +2ale +al3end +a4lenti +a5le5o +al1i +al4ia. +ali4e +al5lev +4allic +4alm +a5log. +a4ly. +4alys +5a5lyst +5alyt +3alyz +4ama +am5ab +am3ag +ama5ra +am5asc +a4matis +a4m5ato +am5era +am3ic +am5if +am5ily +am1in +ami4no +a2mo +a5mon +amor5i +amp5en +a2n +an3age +3analy +a3nar +an3arc +anar4i +a3nati +4and +ande4s +an3dis +an1dl +an4dow +a5nee +a3nen +an5est. +a3neu +2ang +ang5ie +an1gl +a4n1ic +a3nies +an3i3f +an4ime +a5nimi +a5nine +an3io +a3nip +an3ish +an3it +a3niu +an4kli +5anniz +ano4 +an5ot +anoth5 +an2sa +an4sco +an4sn +an2sp +ans3po +an4st +an4sur +antal4 +an4tie +4anto +an2tr +an4tw +an3ua +an3ul +a5nur +4ao +apar4 +ap5at +ap5ero +a3pher +4aphi +a4pilla +ap5illar +ap3in +ap3ita +a3pitu +a2pl +apoc5 +ap5ola +apor5i +apos3t +aps5es +a3pu +aque5 +2a2r +ar3act +a5rade +ar5adis +ar3al +a5ramete +aran4g +ara3p +ar4at +a5ratio +ar5ativ +a5rau +ar5av4 +araw4 +arbal4 +ar4chan +ar5dine +ar4dr +ar5eas +a3ree +ar3ent +a5ress +ar4fi +ar4fl +ar1i +ar5ial +ar3ian +a3riet +ar4im +ar5inat +ar3io +ar2iz +ar2mi +ar5o5d +a5roni +a3roo +ar2p +ar3q +arre4 +ar4sa +ar2sh +4as. +as4ab +as3ant +ashi4 +a5sia. +a3sib +a3sic +5a5si4t +ask3i +as4l +a4soc +as5ph +as4sh +as3ten +as1tr +asur5a +a2ta +at3abl +at5ac +at3alo +at5ap +ate5c +at5ech +at3ego +at3en. +at3era +ater5n +a5terna +at3est +at5ev +4ath +ath5em +a5then +at4ho +ath5om +4ati. +a5tia +at5i5b +at1ic +at3if +ation5ar +at3itu +a4tog +a2tom +at5omiz +a4top +a4tos +a1tr +at5rop +at4sk +at4tag +at5te +at4th +a2tu +at5ua +at5ue +at3ul +at3ura +a2ty +au4b +augh3 +au3gu +au4l2 +aun5d +au3r +au5sib +aut5en +au1th +a2va +av3ag +a5van +ave4no +av3era +av5ern +av5ery +av1i +avi4er +av3ig +av5oc +a1vor +3away +aw3i +aw4ly +aws4 +ax4ic +ax4id +ay5al +aye4 +ays4 +azi4er +azz5i +5ba. +bad5ger +ba4ge +bal1a +ban5dag +ban4e +ban3i +barbi5 +bari4a +bas4si +1bat +ba4z +2b1b +b2be +b3ber +bbi4na +4b1d +4be. +beak4 +beat3 +4be2d +be3da +be3de +be3di +be3gi +be5gu +1bel +be1li +be3lo +4be5m +be5nig +be5nu +4bes4 +be3sp +be5str +3bet +bet5iz +be5tr +be3tw +be3w +be5yo +2bf +4b3h +bi2b +bi4d +3bie +bi5en +bi4er +2b3if +1bil +bi3liz +bina5r4 +bin4d +bi5net +bi3ogr +bi5ou +bi2t +3bi3tio +bi3tr +3bit5ua +b5itz +b1j +bk4 +b2l2 +blath5 +b4le. +blen4 +5blesp +b3lis +b4lo +blun4t +4b1m +4b3n +bne5g +3bod +bod3i +bo4e +bol3ic +bom4bi +bon4a +bon5at +3boo +5bor. +4b1ora +bor5d +5bore +5bori +5bos4 +b5ota +both5 +bo4to +bound3 +4bp +4brit +broth3 +2b5s2 +bsor4 +2bt +bt4l +b4to +b3tr +buf4fer +bu4ga +bu3li +bumi4 +bu4n +bunt4i +bu3re +bus5ie +buss4e +5bust +4buta +3butio +b5uto +b1v +4b5w +5by. +bys4 +1ca +cab3in +ca1bl +cach4 +ca5den +4cag4 +2c5ah +ca3lat +cal4la +call5in +4calo +can5d +can4e +can4ic +can5is +can3iz +can4ty +cany4 +ca5per +car5om +cast5er +cas5tig +4casy +ca4th +4cativ +cav5al +c3c +ccha5 +cci4a +ccompa5 +ccon4 +ccou3t +2ce. +4ced. +4ceden +3cei +5cel. +3cell +1cen +3cenc +2cen4e +4ceni +3cent +3cep +ce5ram +4cesa +3cessi +ces5si5b +ces5t +cet4 +c5e4ta +cew4 +2ch +4ch. +4ch3ab +5chanic +ch5a5nis +che2 +cheap3 +4ched +che5lo +3chemi +ch5ene +ch3er. +ch3ers +4ch1in +5chine. +ch5iness +5chini +5chio +3chit +chi2z +3cho2 +ch4ti +1ci +3cia +ci2a5b +cia5r +ci5c +4cier +5cific. +4cii +ci4la +3cili +2cim +2cin +c4ina +3cinat +cin3em +c1ing +c5ing. +5cino +cion4 +4cipe +ci3ph +4cipic +4cista +4cisti +2c1it +cit3iz +5ciz +ck1 +ck3i +1c4l4 +4clar +c5laratio +5clare +cle4m +4clic +clim4 +cly4 +c5n +1co +co5ag +coe2 +2cog +co4gr +coi4 +co3inc +col5i +5colo +col3or +com5er +con4a +c4one +con3g +con5t +co3pa +cop3ic +co4pl +4corb +coro3n +cos4e +cov1 +cove4 +cow5a +coz5e +co5zi +c1q +cras5t +5crat. +5cratic +cre3at +5cred +4c3reta +cre4v +cri2 +cri5f +c4rin +cris4 +5criti +cro4pl +crop5o +cros4e +cru4d +4c3s2 +2c1t +cta4b +ct5ang +c5tant +c2te +c3ter +c4ticu +ctim3i +ctu4r +c4tw +cud5 +c4uf +c4ui +cu5ity +5culi +cul4tis +3cultu +cu2ma +c3ume +cu4mi +3cun +cu3pi +cu5py +cur5a4b +cu5ria +1cus +cuss4i +3c4ut +cu4tie +4c5utiv +4cutr +1cy +cze4 +1d2a +5da. +2d3a4b +dach4 +4daf +2dag +da2m2 +dan3g +dard5 +dark5 +4dary +3dat +4dativ +4dato +5dav4 +dav5e +5day +d1b +d5c +d1d4 +2de. +deaf5 +deb5it +de4bon +decan4 +de4cil +de5com +2d1ed +4dee. +de5if +deli4e +del5i5q +de5lo +d4em +5dem. +3demic +dem5ic. +de5mil +de4mons +demor5 +1den +de4nar +de3no +denti5f +de3nu +de1p +de3pa +depi4 +de2pu +d3eq +d4erh +5derm +dern5iz +der5s +des2 +d2es. +de1sc +de2s5o +des3ti +de3str +de4su +de1t +de2to +de1v +dev3il +4dey +4d1f +d4ga +d3ge4t +dg1i +d2gy +d1h2 +5di. +1d4i3a +dia5b +di4cam +d4ice +3dict +3did +5di3en +d1if +di3ge +di4lato +d1in +1dina +3dine. +5dini +di5niz +1dio +dio5g +di4pl +dir2 +di1re +dirt5i +dis1 +5disi +d4is3t +d2iti +1di1v +d1j +d5k2 +4d5la +3dle. +3dled +3dles. +4dless +2d3lo +4d5lu +2dly +d1m +4d1n4 +1do +3do. +do5de +5doe +2d5of +d4og +do4la +doli4 +do5lor +dom5iz +do3nat +doni4 +doo3d +dop4p +d4or +3dos +4d5out +do4v +3dox +d1p +1dr +drag5on +4drai +dre4 +drea5r +5dren +dri4b +dril4 +dro4p +4drow +5drupli +4dry +2d1s2 +ds4p +d4sw +d4sy +d2th +1du +d1u1a +du2c +d1uca +duc5er +4duct. +4ducts +du5el +du4g +d3ule +dum4be +du4n +4dup +du4pe +d1v +d1w +d2y +5dyn +dy4se +dys5p +e1a4b +e3act +ead1 +ead5ie +ea4ge +ea5ger +ea4l +eal5er +eal3ou +eam3er +e5and +ear3a +ear4c +ear5es +ear4ic +ear4il +ear5k +ear2t +eart3e +ea5sp +e3ass +east3 +ea2t +eat5en +eath3i +e5atif +e4a3tu +ea2v +eav3en +eav5i +eav5o +2e1b +e4bel. +e4bels +e4ben +e4bit +e3br +e4cad +ecan5c +ecca5 +e1ce +ec5essa +ec2i +e4cib +ec5ificat +ec5ifie +ec5ify +ec3im +eci4t +e5cite +e4clam +e4clus +e2col +e4comm +e4compe +e4conc +e2cor +ec3ora +eco5ro +e1cr +e4crem +ec4tan +ec4te +e1cu +e4cul +ec3ula +2e2da +4ed3d +e4d1er +ede4s +4edi +e3dia +ed3ib +ed3ica +ed3im +ed1it +edi5z +4edo +e4dol +edon2 +e4dri +e4dul +ed5ulo +ee2c +eed3i +ee2f +eel3i +ee4ly +ee2m +ee4na +ee4p1 +ee2s4 +eest4 +ee4ty +e5ex +e1f +e4f3ere +1eff +e4fic +5efici +efil4 +e3fine +ef5i5nite +3efit +efor5es +e4fuse. +4egal +eger4 +eg5ib +eg4ic +eg5ing +e5git5 +eg5n +e4go. +e4gos +eg1ul +e5gur +5egy +e1h4 +eher4 +ei2 +e5ic +ei5d +eig2 +ei5gl +e3imb +e3inf +e1ing +e5inst +eir4d +eit3e +ei3th +e5ity +e1j +e4jud +ej5udi +eki4n +ek4la +e1la +e4la. +e4lac +elan4d +el5ativ +e4law +elaxa4 +e3lea +el5ebra +5elec +e4led +el3ega +e5len +e4l1er +e1les +el2f +el2i +e3libe +e4l5ic. +el3ica +e3lier +el5igib +e5lim +e4l3ing +e3lio +e2lis +el5ish +e3liv3 +4ella +el4lab +ello4 +e5loc +el5og +el3op. +el2sh +el4ta +e5lud +el5ug +e4mac +e4mag +e5man +em5ana +em5b +e1me +e2mel +e4met +em3ica +emi4e +em5igra +em1in2 +em5ine +em3i3ni +e4mis +em5ish +e5miss +em3iz +5emniz +emo4g +emoni5o +em3pi +e4mul +em5ula +emu3n +e3my +en5amo +e4nant +ench4er +en3dic +e5nea +e5nee +en3em +en5ero +en5esi +en5est +en3etr +e3new +en5ics +e5nie +e5nil +e3nio +en3ish +en3it +e5niu +5eniz +4enn +4eno +eno4g +e4nos +en3ov +en4sw +ent5age +4enthes +en3ua +en5uf +e3ny. +4en3z +e5of +eo2g +e4oi4 +e3ol +eop3ar +e1or +eo3re +eo5rol +eos4 +e4ot +eo4to +e5out +e5ow +e2pa +e3pai +ep5anc +e5pel +e3pent +ep5etitio +ephe4 +e4pli +e1po +e4prec +ep5reca +e4pred +ep3reh +e3pro +e4prob +ep4sh +ep5ti5b +e4put +ep5uta +e1q +equi3l +e4q3ui3s +er1a +era4b +4erand +er3ar +4erati. +2erb +er4bl +er3ch +er4che +2ere. +e3real +ere5co +ere3in +er5el. +er3emo +er5ena +er5ence +4erene +er3ent +ere4q +er5ess +er3est +eret4 +er1h +er1i +e1ria4 +5erick +e3rien +eri4er +er3ine +e1rio +4erit +er4iu +eri4v +e4riva +er3m4 +er4nis +4ernit +5erniz +er3no +2ero +er5ob +e5roc +ero4r +er1ou +er1s +er3set +ert3er +4ertl +er3tw +4eru +eru4t +5erwau +e1s4a +e4sage. +e4sages +es2c +e2sca +es5can +e3scr +es5cu +e1s2e +e2sec +es5ecr +es5enc +e4sert. +e4serts +e4serva +4esh +e3sha +esh5en +e1si +e2sic +e2sid +es5iden +es5igna +e2s5im +es4i4n +esis4te +esi4u +e5skin +es4mi +e2sol +es3olu +e2son +es5ona +e1sp +es3per +es5pira +es4pre +2ess +es4si4b +estan4 +es3tig +es5tim +4es2to +e3ston +2estr +e5stro +estruc5 +e2sur +es5urr +es4w +eta4b +eten4d +e3teo +ethod3 +et1ic +e5tide +etin4 +eti4no +e5tir +e5titio +et5itiv +4etn +et5ona +e3tra +e3tre +et3ric +et5rif +et3rog +et5ros +et3ua +et5ym +et5z +4eu +e5un +e3up +eu3ro +eus4 +eute4 +euti5l +eu5tr +eva2p5 +e2vas +ev5ast +e5vea +ev3ell +evel3o +e5veng +even4i +ev1er +e5verb +e1vi +ev3id +evi4l +e4vin +evi4v +e5voc +e5vu +e1wa +e4wag +e5wee +e3wh +ewil5 +ew3ing +e3wit +1exp +5eyc +5eye. +eys4 +1fa +fa3bl +fab3r +fa4ce +4fag +fain4 +fall5e +4fa4ma +fam5is +5far +far5th +fa3ta +fa3the +4fato +fault5 +4f5b +4fd +4fe. +feas4 +feath3 +fe4b +4feca +5fect +2fed +fe3li +fe4mo +fen2d +fend5e +fer1 +5ferr +fev4 +4f1f +f4fes +f4fie +f5fin. +f2f5is +f4fly +f2fy +4fh +1fi +fi3a +2f3ic. +4f3ical +f3ican +4ficate +f3icen +fi3cer +fic4i +5ficia +5ficie +4fics +fi3cu +fi5del +fight5 +fil5i +fill5in +4fily +2fin +5fina +fin2d5 +fi2ne +f1in3g +fin4n +fis4ti +f4l2 +f5less +flin4 +flo3re +f2ly5 +4fm +4fn +1fo +5fon +fon4de +fon4t +fo2r +fo5rat +for5ay +fore5t +for4i +fort5a +fos5 +4f5p +fra4t +f5rea +fres5c +fri2 +fril4 +frol5 +2f3s +2ft +f4to +f2ty +3fu +fu5el +4fug +fu4min +fu5ne +fu3ri +fusi4 +fus4s +4futa +1fy +1ga +gaf4 +5gal. +3gali +ga3lo +2gam +ga5met +g5amo +gan5is +ga3niz +gani5za +4gano +gar5n4 +gass4 +gath3 +4gativ +4gaz +g3b +gd4 +2ge. +2ged +geez4 +gel4in +ge5lis +ge5liz +4gely +1gen +ge4nat +ge5niz +4geno +4geny +1geo +ge3om +g4ery +5gesi +geth5 +4geto +ge4ty +ge4v +4g1g2 +g2ge +g3ger +gglu5 +ggo4 +gh3in +gh5out +gh4to +5gi. +1gi4a +gia5r +g1ic +5gicia +g4ico +gien5 +5gies. +gil4 +g3imen +3g4in. +gin5ge +5g4ins +5gio +3gir +gir4l +g3isl +gi4u +5giv +3giz +gl2 +gla4 +glad5i +5glas +1gle +gli4b +g3lig +3glo +glo3r +g1m +g4my +gn4a +g4na. +gnet4t +g1ni +g2nin +g4nio +g1no +g4non +1go +3go. +gob5 +5goe +3g4o4g +go3is +gon2 +4g3o3na +gondo5 +go3ni +5goo +go5riz +gor5ou +5gos. +gov1 +g3p +1gr +4grada +g4rai +gran2 +5graph. +g5rapher +5graphic +4graphy +4gray +gre4n +4gress. +4grit +g4ro +gruf4 +gs2 +g5ste +gth3 +gu4a +3guard +2gue +5gui5t +3gun +3gus +4gu4t +g3w +1gy +2g5y3n +gy5ra +h3ab4l +hach4 +hae4m +hae4t +h5agu +ha3la +hala3m +ha4m +han4ci +han4cy +5hand. +han4g +hang5er +hang5o +h5a5niz +han4k +han4te +hap3l +hap5t +ha3ran +ha5ras +har2d +hard3e +har4le +harp5en +har5ter +has5s +haun4 +5haz +haz3a +h1b +1head +3hear +he4can +h5ecat +h4ed +he5do5 +he3l4i +hel4lis +hel4ly +h5elo +hem4p +he2n +hena4 +hen5at +heo5r +hep5 +h4era +hera3p +her4ba +here5a +h3ern +h5erou +h3ery +h1es +he2s5p +he4t +het4ed +heu4 +h1f +h1h +hi5an +hi4co +high5 +h4il2 +himer4 +h4ina +hion4e +hi4p +hir4l +hi3ro +hir4p +hir4r +his3el +his4s +hith5er +hi2v +4hk +4h1l4 +hlan4 +h2lo +hlo3ri +4h1m +hmet4 +2h1n +h5odiz +h5ods +ho4g +hoge4 +hol5ar +3hol4e +ho4ma +home3 +hon4a +ho5ny +3hood +hoon4 +hor5at +ho5ris +hort3e +ho5ru +hos4e +ho5sen +hos1p +1hous +house3 +hov5el +4h5p +4hr4 +hree5 +hro5niz +hro3po +4h1s2 +h4sh +h4tar +ht1en +ht5es +h4ty +hu4g +hu4min +hun5ke +hun4t +hus3t4 +hu4t +h1w +h4wart +hy3pe +hy3ph +hy2s +2i1a +i2al +iam4 +iam5ete +i2an +4ianc +ian3i +4ian4t +ia5pe +iass4 +i4ativ +ia4tric +i4atu +ibe4 +ib3era +ib5ert +ib5ia +ib3in +ib5it. +ib5ite +i1bl +ib3li +i5bo +i1br +i2b5ri +i5bun +4icam +5icap +4icar +i4car. +i4cara +icas5 +i4cay +iccu4 +4iceo +4ich +2ici +i5cid +ic5ina +i2cip +ic3ipa +i4cly +i2c5oc +4i1cr +5icra +i4cry +ic4te +ictu2 +ic4t3ua +ic3ula +ic4um +ic5uo +i3cur +2id +i4dai +id5anc +id5d +ide3al +ide4s +i2di +id5ian +idi4ar +i5die +id3io +idi5ou +id1it +id5iu +i3dle +i4dom +id3ow +i4dr +i2du +id5uo +2ie4 +ied4e +5ie5ga +ield3 +ien5a4 +ien4e +i5enn +i3enti +i1er. +i3esc +i1est +i3et +4if. +if5ero +iff5en +if4fr +4ific. +i3fie +i3fl +4ift +2ig +iga5b +ig3era +ight3i +4igi +i3gib +ig3il +ig3in +ig3it +i4g4l +i2go +ig3or +ig5ot +i5gre +igu5i +ig1ur +i3h +4i5i4 +i3j +4ik +i1la +il3a4b +i4lade +i2l5am +ila5ra +i3leg +il1er +ilev4 +il5f +il1i +il3ia +il2ib +il3io +il4ist +2ilit +il2iz +ill5ab +4iln +il3oq +il4ty +il5ur +il3v +i4mag +im3age +ima5ry +imenta5r +4imet +im1i +im5ida +imi5le +i5mini +4imit +im4ni +i3mon +i2mu +im3ula +2in. +i4n3au +4inav +incel4 +in3cer +4ind +in5dling +2ine +i3nee +iner4ar +i5ness +4inga +4inge +in5gen +4ingi +in5gling +4ingo +4ingu +2ini +i5ni. +i4nia +in3io +in1is +i5nite. +5initio +in3ity +4ink +4inl +2inn +2i1no +i4no4c +ino4s +i4not +2ins +in3se +insur5a +2int. +2in4th +in1u +i5nus +4iny +2io +4io. +ioge4 +io2gr +i1ol +io4m +ion3at +ion4ery +ion3i +io5ph +ior3i +i4os +io5th +i5oti +io4to +i4our +2ip +ipe4 +iphras4 +ip3i +ip4ic +ip4re4 +ip3ul +i3qua +iq5uef +iq3uid +iq3ui3t +4ir +i1ra +ira4b +i4rac +ird5e +ire4de +i4ref +i4rel4 +i4res +ir5gi +ir1i +iri5de +ir4is +iri3tu +5i5r2iz +ir4min +iro4g +5iron. +ir5ul +2is. +is5ag +is3ar +isas5 +2is1c +is3ch +4ise +is3er +3isf +is5han +is3hon +ish5op +is3ib +isi4d +i5sis +is5itiv +4is4k +islan4 +4isms +i2so +iso5mer +is1p +is2pi +is4py +4is1s +is4sal +issen4 +is4ses +is4ta. +is1te +is1ti +ist4ly +4istral +i2su +is5us +4ita. +ita4bi +i4tag +4ita5m +i3tan +i3tat +2ite +it3era +i5teri +it4es +2ith +i1ti +4itia +4i2tic +it3ica +5i5tick +it3ig +it5ill +i2tim +2itio +4itis +i4tism +i2t5o5m +4iton +i4tram +it5ry +4itt +it3uat +i5tud +it3ul +4itz. +i1u +2iv +iv3ell +iv3en. +i4v3er. +i4vers. +iv5il. +iv5io +iv1it +i5vore +iv3o3ro +i4v3ot +4i5w +ix4o +4iy +4izar +izi4 +5izont +5ja +jac4q +ja4p +1je +jer5s +4jestie +4jesty +jew3 +jo4p +5judg +3ka. +k3ab +k5ag +kais4 +kal4 +k1b +k2ed +1kee +ke4g +ke5li +k3en4d +k1er +kes4 +k3est. +ke4ty +k3f +kh4 +k1i +5ki. +5k2ic +k4ill +kilo5 +k4im +k4in. +kin4de +k5iness +kin4g +ki4p +kis4 +k5ish +kk4 +k1l +4kley +4kly +k1m +k5nes +1k2no +ko5r +kosh4 +k3ou +kro5n +4k1s2 +k4sc +ks4l +k4sy +k5t +k1w +lab3ic +l4abo +laci4 +l4ade +la3dy +lag4n +lam3o +3land +lan4dl +lan5et +lan4te +lar4g +lar3i +las4e +la5tan +4lateli +4lativ +4lav +la4v4a +2l1b +lbin4 +4l1c2 +lce4 +l3ci +2ld +l2de +ld4ere +ld4eri +ldi4 +ld5is +l3dr +l4dri +le2a +le4bi +left5 +5leg. +5legg +le4mat +lem5atic +4len. +3lenc +5lene. +1lent +le3ph +le4pr +lera5b +ler4e +3lerg +3l4eri +l4ero +les2 +le5sco +5lesq +3less +5less. +l3eva +lev4er. +lev4era +lev4ers +3ley +4leye +2lf +l5fr +4l1g4 +l5ga +lgar3 +l4ges +lgo3 +2l3h +li4ag +li2am +liar5iz +li4as +li4ato +li5bi +5licio +li4cor +4lics +4lict. +l4icu +l3icy +l3ida +lid5er +3lidi +lif3er +l4iff +li4fl +5ligate +3ligh +li4gra +3lik +4l4i4l +lim4bl +lim3i +li4mo +l4im4p +l4ina +1l4ine +lin3ea +lin3i +link5er +li5og +4l4iq +lis4p +l1it +l2it. +5litica +l5i5tics +liv3er +l1iz +4lj +lka3 +l3kal +lka4t +l1l +l4law +l2le +l5lea +l3lec +l3leg +l3lel +l3le4n +l3le4t +ll2i +l2lin4 +l5lina +ll4o +lloqui5 +ll5out +l5low +2lm +l5met +lm3ing +l4mod +lmon4 +2l1n2 +3lo. +lob5al +lo4ci +4lof +3logic +l5ogo +3logu +lom3er +5long +lon4i +l3o3niz +lood5 +5lope. +lop3i +l3opm +lora4 +lo4rato +lo5rie +lor5ou +5los. +los5et +5losophiz +5losophy +los4t +lo4ta +loun5d +2lout +4lov +2lp +lpa5b +l3pha +l5phi +lp5ing +l3pit +l4pl +l5pr +4l1r +2l1s2 +l4sc +l2se +l4sie +4lt +lt5ag +ltane5 +l1te +lten4 +ltera4 +lth3i +l5ties. +ltis4 +l1tr +ltu2 +ltur3a +lu5a +lu3br +luch4 +lu3ci +lu3en +luf4 +lu5id +lu4ma +5lumi +l5umn. +5lumnia +lu3o +luo3r +4lup +luss4 +lus3te +1lut +l5ven +l5vet4 +2l1w +1ly +4lya +4lyb +ly5me +ly3no +2lys4 +l5yse +1ma +2mab +ma2ca +ma5chine +ma4cl +mag5in +5magn +2mah +maid5 +4mald +ma3lig +ma5lin +mal4li +mal4ty +5mania +man5is +man3iz +4map +ma5rine. +ma5riz +mar4ly +mar3v +ma5sce +mas4e +mas1t +5mate +math3 +ma3tis +4matiza +4m1b +mba4t5 +m5bil +m4b3ing +mbi4v +4m5c +4me. +2med +4med. +5media +me3die +m5e5dy +me2g +mel5on +mel4t +me2m +mem1o3 +1men +men4a +men5ac +men4de +4mene +men4i +mens4 +mensu5 +3ment +men4te +me5on +m5ersa +2mes +3mesti +me4ta +met3al +me1te +me5thi +m4etr +5metric +me5trie +me3try +me4v +4m1f +2mh +5mi. +mi3a +mid4a +mid4g +mig4 +3milia +m5i5lie +m4ill +min4a +3mind +m5inee +m4ingl +min5gli +m5ingly +min4t +m4inu +miot4 +m2is +mis4er. +mis5l +mis4ti +m5istry +4mith +m2iz +4mk +4m1l +m1m +mma5ry +4m1n +mn4a +m4nin +mn4o +1mo +4mocr +5mocratiz +mo2d1 +mo4go +mois2 +moi5se +4mok +mo5lest +mo3me +mon5et +mon5ge +moni3a +mon4ism +mon4ist +mo3niz +monol4 +mo3ny. +mo2r +4mora. +mos2 +mo5sey +mo3sp +moth3 +m5ouf +3mous +mo2v +4m1p +mpara5 +mpa5rab +mpar5i +m3pet +mphas4 +m2pi +mpi4a +mp5ies +m4p1in +m5pir +mp5is +mpo3ri +mpos5ite +m4pous +mpov5 +mp4tr +m2py +4m3r +4m1s2 +m4sh +m5si +4mt +1mu +mula5r4 +5mult +multi3 +3mum +mun2 +4mup +mu4u +4mw +1na +2n1a2b +n4abu +4nac. +na4ca +n5act +nag5er. +nak4 +na4li +na5lia +4nalt +na5mit +n2an +nanci4 +nan4it +nank4 +nar3c +4nare +nar3i +nar4l +n5arm +n4as +nas4c +nas5ti +n2at +na3tal +nato5miz +n2au +nau3se +3naut +nav4e +4n1b4 +ncar5 +n4ces. +n3cha +n5cheo +n5chil +n3chis +nc1in +nc4it +ncour5a +n1cr +n1cu +n4dai +n5dan +n1de +nd5est. +ndi4b +n5d2if +n1dit +n3diz +n5duc +ndu4r +nd2we +2ne. +n3ear +ne2b +neb3u +ne2c +5neck +2ned +ne4gat +neg5ativ +5nege +ne4la +nel5iz +ne5mi +ne4mo +1nen +4nene +3neo +ne4po +ne2q +n1er +nera5b +n4erar +n2ere +n4er5i +ner4r +1nes +2nes. +4nesp +2nest +4nesw +3netic +ne4v +n5eve +ne4w +n3f +n4gab +n3gel +nge4n4e +n5gere +n3geri +ng5ha +n3gib +ng1in +n5git +n4gla +ngov4 +ng5sh +n1gu +n4gum +n2gy +4n1h4 +nha4 +nhab3 +nhe4 +3n4ia +ni3an +ni4ap +ni3ba +ni4bl +ni4d +ni5di +ni4er +ni2fi +ni5ficat +n5igr +nik4 +n1im +ni3miz +n1in +5nine. +nin4g +ni4o +5nis. +nis4ta +n2it +n4ith +3nitio +n3itor +ni3tr +n1j +4nk2 +n5kero +n3ket +nk3in +n1kl +4n1l +n5m +nme4 +nmet4 +4n1n2 +nne4 +nni3al +nni4v +nob4l +no3ble +n5ocl +4n3o2d +3noe +4nog +noge4 +nois5i +no5l4i +5nologis +3nomic +n5o5miz +no4mo +no3my +no4n +non4ag +non5i +n5oniz +4nop +5nop5o5li +nor5ab +no4rary +4nosc +nos4e +nos5t +no5ta +1nou +3noun +nov3el3 +nowl3 +n1p4 +npi4 +npre4c +n1q +n1r +nru4 +2n1s2 +ns5ab +nsati4 +ns4c +n2se +n4s3es +nsid1 +nsig4 +n2sl +ns3m +n4soc +ns4pe +n5spi +nsta5bl +n1t +nta4b +nter3s +nt2i +n5tib +nti4er +nti2f +n3tine +n4t3ing +nti4p +ntrol5li +nt4s +ntu3me +nu1a +nu4d +nu5en +nuf4fe +n3uin +3nu3it +n4um +nu1me +n5umi +3nu4n +n3uo +nu3tr +n1v2 +n1w4 +nym4 +nyp4 +4nz +n3za +4oa +oad3 +o5a5les +oard3 +oas4e +oast5e +oat5i +ob3a3b +o5bar +obe4l +o1bi +o2bin +ob5ing +o3br +ob3ul +o1ce +och4 +o3chet +ocif3 +o4cil +o4clam +o4cod +oc3rac +oc5ratiz +ocre3 +5ocrit +octor5a +oc3ula +o5cure +od5ded +od3ic +odi3o +o2do4 +odor3 +od5uct. +od5ucts +o4el +o5eng +o3er +oe4ta +o3ev +o2fi +of5ite +ofit4t +o2g5a5r +og5ativ +o4gato +o1ge +o5gene +o5geo +o4ger +o3gie +1o1gis +og3it +o4gl +o5g2ly +3ogniz +o4gro +ogu5i +1ogy +2ogyn +o1h2 +ohab5 +oi2 +oic3es +oi3der +oiff4 +oig4 +oi5let +o3ing +oint5er +o5ism +oi5son +oist5en +oi3ter +o5j +2ok +o3ken +ok5ie +o1la +o4lan +olass4 +ol2d +old1e +ol3er +o3lesc +o3let +ol4fi +ol2i +o3lia +o3lice +ol5id. +o3li4f +o5lil +ol3ing +o5lio +o5lis. +ol3ish +o5lite +o5litio +o5liv +olli4e +ol5ogiz +olo4r +ol5pl +ol2t +ol3ub +ol3ume +ol3un +o5lus +ol2v +o2ly +om5ah +oma5l +om5atiz +om2be +om4bl +o2me +om3ena +om5erse +o4met +om5etry +o3mia +om3ic. +om3ica +o5mid +om1in +o5mini +5ommend +omo4ge +o4mon +om3pi +ompro5 +o2n +on1a +on4ac +o3nan +on1c +3oncil +2ond +on5do +o3nen +on5est +on4gu +on1ic +o3nio +on1is +o5niu +on3key +on4odi +on3omy +on3s +onspi4 +onspir5a +onsu4 +onten4 +on3t4i +ontif5 +on5um +onva5 +oo2 +ood5e +ood5i +oo4k +oop3i +o3ord +oost5 +o2pa +ope5d +op1er +3opera +4operag +2oph +o5phan +o5pher +op3ing +o3pit +o5pon +o4posi +o1pr +op1u +opy5 +o1q +o1ra +o5ra. +o4r3ag +or5aliz +or5ange +ore5a +o5real +or3ei +ore5sh +or5est. +orew4 +or4gu +4o5ria +or3ica +o5ril +or1in +o1rio +or3ity +o3riu +or2mi +orn2e +o5rof +or3oug +or5pe +3orrh +or4se +ors5en +orst4 +or3thi +or3thy +or4ty +o5rum +o1ry +os3al +os2c +os4ce +o3scop +4oscopi +o5scr +os4i4e +os5itiv +os3ito +os3ity +osi4u +os4l +o2so +os4pa +os4po +os2ta +o5stati +os5til +os5tit +o4tan +otele4g +ot3er. +ot5ers +o4tes +4oth +oth5esi +oth3i4 +ot3ic. +ot5ica +o3tice +o3tif +o3tis +oto5s +ou2 +ou3bl +ouch5i +ou5et +ou4l +ounc5er +oun2d +ou5v +ov4en +over4ne +over3s +ov4ert +o3vis +oviti4 +o5v4ol +ow3der +ow3el +ow5est +ow1i +own5i +o4wo +oy1a +1pa +pa4ca +pa4ce +pac4t +p4ad +5pagan +p3agat +p4ai +pain4 +p4al +pan4a +pan3el +pan4ty +pa3ny +pa1p +pa4pu +para5bl +par5age +par5di +3pare +par5el +p4a4ri +par4is +pa2te +pa5ter +5pathic +pa5thy +pa4tric +pav4 +3pay +4p1b +pd4 +4pe. +3pe4a +pear4l +pe2c +2p2ed +3pede +3pedi +pedia4 +ped4ic +p4ee +pee4d +pek4 +pe4la +peli4e +pe4nan +p4enc +pen4th +pe5on +p4era. +pera5bl +p4erag +p4eri +peri5st +per4mal +perme5 +p4ern +per3o +per3ti +pe5ru +per1v +pe2t +pe5ten +pe5tiz +4pf +4pg +4ph. +phar5i +phe3no +ph4er +ph4es. +ph1ic +5phie +ph5ing +5phisti +3phiz +ph2l +3phob +3phone +5phoni +pho4r +4phs +ph3t +5phu +1phy +pi3a +pian4 +pi4cie +pi4cy +p4id +p5ida +pi3de +5pidi +3piec +pi3en +pi4grap +pi3lo +pi2n +p4in. +pind4 +p4ino +3pi1o +pion4 +p3ith +pi5tha +pi2tu +2p3k2 +1p2l2 +3plan +plas5t +pli3a +pli5er +4plig +pli4n +ploi4 +plu4m +plum4b +4p1m +2p3n +po4c +5pod. +po5em +po3et5 +5po4g +poin2 +5point +poly5t +po4ni +po4p +1p4or +po4ry +1pos +pos1s +p4ot +po4ta +5poun +4p1p +ppa5ra +p2pe +p4ped +p5pel +p3pen +p3per +p3pet +ppo5site +pr2 +pray4e +5preci +pre5co +pre3em +pref5ac +pre4la +pre3r +p3rese +3press +pre5ten +pre3v +5pri4e +prin4t3 +pri4s +pris3o +p3roca +prof5it +pro3l +pros3e +pro1t +2p1s2 +p2se +ps4h +p4sib +2p1t +pt5a4b +p2te +p2th +pti3m +ptu4r +p4tw +pub3 +pue4 +puf4 +pul3c +pu4m +pu2n +pur4r +5pus +pu2t +5pute +put3er +pu3tr +put4ted +put4tin +p3w +qu2 +qua5v +2que. +3quer +3quet +2rab +ra3bi +rach4e +r5acl +raf5fi +raf4t +r2ai +ra4lo +ram3et +r2ami +rane5o +ran4ge +r4ani +ra5no +rap3er +3raphy +rar5c +rare4 +rar5ef +4raril +r2as +ration4 +rau4t +ra5vai +rav3el +ra5zie +r1b +r4bab +r4bag +rbi2 +rbi4f +r2bin +r5bine +rb5ing. +rb4o +r1c +r2ce +rcen4 +r3cha +rch4er +r4ci4b +rc4it +rcum3 +r4dal +rd2i +rdi4a +rdi4er +rdin4 +rd3ing +2re. +re1al +re3an +re5arr +5reav +re4aw +r5ebrat +rec5oll +rec5ompe +re4cre +2r2ed +re1de +re3dis +red5it +re4fac +re2fe +re5fer. +re3fi +re4fy +reg3is +re5it +re1li +re5lu +r4en4ta +ren4te +re1o +re5pin +re4posi +re1pu +r1er4 +r4eri +rero4 +re5ru +r4es. +re4spi +ress5ib +res2t +re5stal +re3str +re4ter +re4ti4z +re3tri +reu2 +re5uti +rev2 +re4val +rev3el +r5ev5er. +re5vers +re5vert +re5vil +rev5olu +re4wh +r1f +rfu4 +r4fy +rg2 +rg3er +r3get +r3gic +rgi4n +rg3ing +r5gis +r5git +r1gl +rgo4n +r3gu +rh4 +4rh. +4rhal +ri3a +ria4b +ri4ag +r4ib +rib3a +ric5as +r4ice +4rici +5ricid +ri4cie +r4ico +rid5er +ri3enc +ri3ent +ri1er +ri5et +rig5an +5rigi +ril3iz +5riman +rim5i +3rimo +rim4pe +r2ina +5rina. +rin4d +rin4e +rin4g +ri1o +5riph +riph5e +ri2pl +rip5lic +r4iq +r2is +r4is. +ris4c +r3ish +ris4p +ri3ta3b +r5ited. +rit5er. +rit5ers +rit3ic +ri2tu +rit5ur +riv5el +riv3et +riv3i +r3j +r3ket +rk4le +rk4lin +r1l +rle4 +r2led +r4lig +r4lis +rl5ish +r3lo4 +r1m +rma5c +r2me +r3men +rm5ers +rm3ing +r4ming. +r4mio +r3mit +r4my +r4nar +r3nel +r4ner +r5net +r3ney +r5nic +r1nis4 +r3nit +r3niv +rno4 +r4nou +r3nu +rob3l +r2oc +ro3cr +ro4e +ro1fe +ro5fil +rok2 +ro5ker +5role. +rom5ete +rom4i +rom4p +ron4al +ron4e +ro5n4is +ron4ta +1room +5root +ro3pel +rop3ic +ror3i +ro5ro +ros5per +ros4s +ro4the +ro4ty +ro4va +rov5el +rox5 +r1p +r4pea +r5pent +rp5er. +r3pet +rp4h4 +rp3ing +r3po +r1r4 +rre4c +rre4f +r4reo +rre4st +rri4o +rri4v +rron4 +rros4 +rrys4 +4rs2 +r1sa +rsa5ti +rs4c +r2se +r3sec +rse4cr +rs5er. +rs3es +rse5v2 +r1sh +r5sha +r1si +r4si4b +rson3 +r1sp +r5sw +rtach4 +r4tag +r3teb +rten4d +rte5o +r1ti +rt5ib +rti4d +r4tier +r3tig +rtil3i +rtil4l +r4tily +r4tist +r4tiv +r3tri +rtroph4 +rt4sh +ru3a +ru3e4l +ru3en +ru4gl +ru3in +rum3pl +ru2n +runk5 +run4ty +r5usc +ruti5n +rv4e +rvel4i +r3ven +rv5er. +r5vest +r3vey +r3vic +rvi4v +r3vo +r1w +ry4c +5rynge +ry3t +sa2 +2s1ab +5sack +sac3ri +s3act +5sai +salar4 +sal4m +sa5lo +sal4t +3sanc +san4de +s1ap +sa5ta +5sa3tio +sat3u +sau4 +sa5vor +5saw +4s5b +scan4t5 +sca4p +scav5 +s4ced +4scei +s4ces +sch2 +s4cho +3s4cie +5scin4d +scle5 +s4cli +scof4 +4scopy +scour5a +s1cu +4s5d +4se. +se4a +seas4 +sea5w +se2c3o +3sect +4s4ed +se4d4e +s5edl +se2g +seg3r +5sei +se1le +5self +5selv +4seme +se4mol +sen5at +4senc +sen4d +s5ened +sen5g +s5enin +4sentd +4sentl +sep3a3 +4s1er. +s4erl +ser4o +4servo +s1e4s +se5sh +ses5t +5se5um +5sev +sev3en +sew4i +5sex +4s3f +2s3g +s2h +2sh. +sh1er +5shev +sh1in +sh3io +3ship +shiv5 +sho4 +sh5old +shon3 +shor4 +short5 +4shw +si1b +s5icc +3side. +5sides +5sidi +si5diz +4signa +sil4e +4sily +2s1in +s2ina +5sine. +s3ing +1sio +5sion +sion5a +si2r +sir5a +1sis +3sitio +5siu +1siv +5siz +sk2 +4ske +s3ket +sk5ine +sk5ing +s1l2 +s3lat +s2le +slith5 +2s1m +s3ma +small3 +sman3 +smel4 +s5men +5smith +smol5d4 +s1n4 +1so +so4ce +soft3 +so4lab +sol3d2 +so3lic +5solv +3som +3s4on. +sona4 +son4g +s4op +5sophic +s5ophiz +s5ophy +sor5c +sor5d +4sov +so5vi +2spa +5spai +spa4n +spen4d +2s5peo +2sper +s2phe +3spher +spho5 +spil4 +sp5ing +4spio +s4ply +s4pon +spor4 +4spot +squal4l +s1r +2ss +s1sa +ssas3 +s2s5c +s3sel +s5seng +s4ses. +s5set +s1si +s4sie +ssi4er +ss5ily +s4sl +ss4li +s4sn +sspend4 +ss2t +ssur5a +ss5w +2st. +s2tag +s2tal +stam4i +5stand +s4ta4p +5stat. +s4ted +stern5i +s5tero +ste2w +stew5a +s3the +st2i +s4ti. +s5tia +s1tic +5stick +s4tie +s3tif +st3ing +5stir +s1tle +5stock +stom3a +5stone +s4top +3store +st4r +s4trad +5stratu +s4tray +s4trid +4stry +4st3w +s2ty +1su +su1al +su4b3 +su2g3 +su5is +suit3 +s4ul +su2m +sum3i +su2n +su2r +4sv +sw2 +4swo +s4y +4syc +3syl +syn5o +sy5rin +1ta +3ta. +2tab +ta5bles +5taboliz +4taci +ta5do +4taf4 +tai5lo +ta2l +ta5la +tal5en +tal3i +4talk +tal4lis +ta5log +ta5mo +tan4de +tanta3 +ta5per +ta5pl +tar4a +4tarc +4tare +ta3riz +tas4e +ta5sy +4tatic +ta4tur +taun4 +tav4 +2taw +tax4is +2t1b +4tc +t4ch +tch5et +4t1d +4te. +tead4i +4teat +tece4 +5tect +2t1ed +te5di +1tee +teg4 +te5ger +te5gi +3tel. +teli4 +5tels +te2ma2 +tem3at +3tenan +3tenc +3tend +4tenes +1tent +ten4tag +1teo +te4p +te5pe +ter3c +5ter3d +1teri +ter5ies +ter3is +teri5za +5ternit +ter5v +4tes. +4tess +t3ess. +teth5e +3teu +3tex +4tey +2t1f +4t1g +2th. +than4 +th2e +4thea +th3eas +the5at +the3is +3thet +th5ic. +th5ica +4thil +5think +4thl +th5ode +5thodic +4thoo +thor5it +tho5riz +2ths +1tia +ti4ab +ti4ato +2ti2b +4tick +t4ico +t4ic1u +5tidi +3tien +tif2 +ti5fy +2tig +5tigu +till5in +1tim +4timp +tim5ul +2t1in +t2ina +3tine. +3tini +1tio +ti5oc +tion5ee +5tiq +ti3sa +3tise +tis4m +ti5so +tis4p +5tistica +ti3tl +ti4u +1tiv +tiv4a +1tiz +ti3za +ti3zen +2tl +t5la +tlan4 +3tle. +3tled +3tles. +t5let. +t5lo +4t1m +tme4 +2t1n2 +1to +to3b +to5crat +4todo +2tof +to2gr +to5ic +to2ma +tom4b +to3my +ton4ali +to3nat +4tono +4tony +to2ra +to3rie +tor5iz +tos2 +5tour +4tout +to3war +4t1p +1tra +tra3b +tra5ch +traci4 +trac4it +trac4te +tras4 +tra5ven +trav5es5 +tre5f +tre4m +trem5i +5tria +tri5ces +5tricia +4trics +2trim +tri4v +tro5mi +tron5i +4trony +tro5phe +tro3sp +tro3v +tru5i +trus4 +4t1s2 +t4sc +tsh4 +t4sw +4t3t2 +t4tes +t5to +ttu4 +1tu +tu1a +tu3ar +tu4bi +tud2 +4tue +4tuf4 +5tu3i +3tum +tu4nis +2t3up. +3ture +5turi +tur3is +tur5o +tu5ry +3tus +4tv +tw4 +4t1wa +twis4 +4two +1ty +4tya +2tyl +type3 +ty5ph +4tz +tz4e +4uab +uac4 +ua5na +uan4i +uar5ant +uar2d +uar3i +uar3t +u1at +uav4 +ub4e +u4bel +u3ber +u4bero +u1b4i +u4b5ing +u3ble. +u3ca +uci4b +uc4it +ucle3 +u3cr +u3cu +u4cy +ud5d +ud3er +ud5est +udev4 +u1dic +ud3ied +ud3ies +ud5is +u5dit +u4don +ud4si +u4du +u4ene +uens4 +uen4te +uer4il +3ufa +u3fl +ugh3en +ug5in +2ui2 +uil5iz +ui4n +u1ing +uir4m +uita4 +uiv3 +uiv4er. +u5j +4uk +u1la +ula5b +u5lati +ulch4 +5ulche +ul3der +ul4e +u1len +ul4gi +ul2i +u5lia +ul3ing +ul5ish +ul4lar +ul4li4b +ul4lis +4ul3m +u1l4o +4uls +uls5es +ul1ti +ultra3 +4ultu +u3lu +ul5ul +ul5v +um5ab +um4bi +um4bly +u1mi +u4m3ing +umor5o +um2p +unat4 +u2ne +un4er +u1ni +un4im +u2nin +un5ish +uni3v +un3s4 +un4sw +unt3ab +un4ter. +un4tes +unu4 +un5y +un5z +u4ors +u5os +u1ou +u1pe +uper5s +u5pia +up3ing +u3pl +up3p +upport5 +upt5ib +uptu4 +u1ra +4ura. +u4rag +u4ras +ur4be +urc4 +ur1d +ure5at +ur4fer +ur4fr +u3rif +uri4fic +ur1in +u3rio +u1rit +ur3iz +ur2l +url5ing. +ur4no +uros4 +ur4pe +ur4pi +urs5er +ur5tes +ur3the +urti4 +ur4tie +u3ru +2us +u5sad +u5san +us4ap +usc2 +us3ci +use5a +u5sia +u3sic +us4lin +us1p +us5sl +us5tere +us1tr +u2su +usur4 +uta4b +u3tat +4ute. +4utel +4uten +uten4i +4u1t2i +uti5liz +u3tine +ut3ing +ution5a +u4tis +5u5tiz +u4t1l +ut5of +uto5g +uto5matic +u5ton +u4tou +uts4 +u3u +uu4m +u1v2 +uxu3 +uz4e +1va +5va. +2v1a4b +vac5il +vac3u +vag4 +va4ge +va5lie +val5o +val1u +va5mo +va5niz +va5pi +var5ied +3vat +4ve. +4ved +veg3 +v3el. +vel3li +ve4lo +v4ely +ven3om +v5enue +v4erd +5vere. +v4erel +v3eren +ver5enc +v4eres +ver3ie +vermi4n +3verse +ver3th +v4e2s +4ves. +ves4te +ve4te +vet3er +ve4ty +vi5ali +5vian +5vide. +5vided +4v3iden +5vides +5vidi +v3if +vi5gn +vik4 +2vil +5vilit +v3i3liz +v1in +4vi4na +v2inc +vin5d +4ving +vio3l +v3io4r +vi1ou +vi4p +vi5ro +vis3it +vi3so +vi3su +4viti +vit3r +4vity +3viv +5vo. +voi4 +3vok +vo4la +v5ole +5volt +3volv +vom5i +vor5ab +vori4 +vo4ry +vo4ta +4votee +4vv4 +v4y +w5abl +2wac +wa5ger +wag5o +wait5 +w5al. +wam4 +war4t +was4t +wa1te +wa5ver +w1b +wea5rie +weath3 +wed4n +weet3 +wee5v +wel4l +w1er +west3 +w3ev +whi4 +wi2 +wil2 +will5in +win4de +win4g +wir4 +3wise +with3 +wiz5 +w4k +wl4es +wl3in +w4no +1wo2 +wom1 +wo5ven +w5p +wra4 +wri4 +writa4 +w3sh +ws4l +ws4pe +w5s4t +4wt +wy4 +x1a +xac5e +x4ago +xam3 +x4ap +xas5 +x3c2 +x1e +xe4cuto +x2ed +xer4i +xe5ro +x1h +xhi2 +xhil5 +xhu4 +x3i +xi5a +xi5c +xi5di +x4ime +xi5miz +x3o +x4ob +x3p +xpan4d +xpecto5 +xpe3d +x1t2 +x3ti +x1u +xu3a +xx4 +y5ac +3yar4 +y5at +y1b +y1c +y2ce +yc5er +y3ch +ych4e +ycom4 +ycot4 +y1d +y5ee +y1er +y4erf +yes4 +ye4t +y5gi +4y3h +y1i +y3la +ylla5bl +y3lo +y5lu +ymbol5 +yme4 +ympa3 +yn3chr +yn5d +yn5g +yn5ic +5ynx +y1o4 +yo5d +y4o5g +yom4 +yo5net +y4ons +y4os +y4ped +yper5 +yp3i +y3po +y4poc +yp2ta +y5pu +yra5m +yr5ia +y3ro +yr4r +ys4c +y3s2e +ys3ica +ys3io +3ysis +y4so +yss4 +ys1t +ys3ta +ysur4 +y3thin +yt3ic +y1w +za1 +z5a2b +zar2 +4zb +2ze +ze4n +ze4p +z1er +ze3ro +zet4 +2z1i +z4il +z4is +5zl +4zm +1zo +zo4m +zo5ol +zte4 +4z1z2 +z4zy +% hyphen.tex patterns end here, and additional patterns begin: +.con5gr +.de5riva +.dri5v4 +.eth1y6l1 +.eu4ler +.ev2 +.ever5si5b +.ga4s1om1 +.ge4ome +.ge5ot1 +.he3mo1 +.he3p6a +.he3roe +.in5u2t +.kil2n3i +.ko6r1te1 +.le6ices +.me4ga1l +.met4ala +.mim5i2c1 +.mi1s4ers +.ne6o3f +.noe1th +.non1e2m +.poly1s +.post1am +.pre1am +.rav5en1o +.semi5 +.sem4ic +.semid6 +.semip4 +.semir4 +.sem6is4 +.semiv4 +.sph6in1 +.spin1o +.ta5pes1tr +.te3legr +.to6pog +.to2q +.un3at5t +.un5err5 +.vi2c3ar +.we2b1l +.re1e4c +a5bolic +a2cabl +af6fish +am1en3ta5b +anal6ys +ano5a2c +ans5gr +ans3v +anti1d +an3ti1n2 +anti1re +a4pe5able +ar3che5t +ar2range +as5ymptot +ath3er1o1s +at6tes. +augh4tl +au5li5f +av3iou +back2er. +ba6r1onie +ba1thy +bbi4t +be2vie +bi5d2if +bil2lab +bio5m +bi1orb +bio1rh +b1i3tive +blan2d1 +blin2d1 +blon2d2 +bor1no5 +bo2t1u1l +brus4q +bus6i2er +bus6i2es +buss4ing +but2ed. +but4ted +cad5e1m +cat1a1s2 +4chs. +chs3hu +chie5vo +cig3a3r +cin2q +cle4ar +co6ph1o3n +cous2ti +cri3tie +croc1o1d +cro5e2co +c2tro3me6c +1cu2r1ance +2d3alone +data1b +dd5a5b +d2d5ib +de4als. +de5clar1 +de2c5lina +de3fin3iti +de2mos +des3ic +de2tic +dic1aid +dif5fra +3di1methy +di2ren +di2rer +2d1lead +2d1li2e +3do5word +dren1a5l +drif2t1a +d1ri3pleg5 +drom3e5d +d3tab +du2al. +du1op1o1l +ea4n3ies +e3chas +edg1l +ed1uling +eli2t1is +e1loa +en1dix +eo3grap +1e6p3i3neph1 +e2r3i4an. +e3spac6i +eth1y6l1ene +5eu2clid1 +feb1rua +fermi1o +3fich +fit5ted. +fla1g6el +flow2er. +3fluor +gen2cy. +ge3o1d +ght1we +g1lead +get2ic. +4g1lish +5glo5bin +1g2nac +gnet1ism +gno5mo +g2n1or. +g2noresp +2g1o4n3i1za +graph5er. +griev1 +g1utan +hair1s +ha2p3ar5r +hatch1 +hex2a3 +hite3sid +h3i5pel1a4 +hnau3z +ho6r1ic. +h2t1eou +hypo1tha +id4ios +ifac1et +ign4it +ignit1er +i4jk +im3ped3a +infra1s2 +i5nitely. +irre6v3oc +i1tesima +ith5i2l +itin5er5ar +janu3a +japan1e2s +je1re1m +1ke6ling +1ki5netic +1kovian +k3sha +la4c3i5e +lai6n3ess +lar5ce1n +l3chai +l3chil6d1 +lead6er. +lea4s1a +1lec3ta6b +le3g6en2dre +1le1noid +lith1o5g +ll1fl +l2l3ish +l5mo3nell +lo1bot1o1 +lo2ges. +load4ed. +load6er. +l3tea +lth5i2ly +lue1p +1lunk3er +1lum5bia. +3lyg1a1mi +ly5styr +ma1la1p +m2an. +man3u1sc +mar1gin1 +medi2c +med3i3cin +medio6c1 +me3gran3 +m2en. +3mi3da5b +3milita +mil2l1ag +mil5li5li +mi6n3is. +mi1n2ut1er +mi1n2ut1est +m3ma1b +5maph1ro1 +5moc1ra1t +mo5e2las +mol1e5c +mon4ey1l +mono3ch +mo4no1en +moro6n5is +mono1s6 +moth4et2 +m1ou3sin +m5shack2 +mu2dro +mul2ti5u +n3ar4chs. +n3ch2es1t +ne3back +2ne1ski +n1dieck +nd3thr +nfi6n3ites +4n5i4an. +nge5nes +ng1ho +ng1spr +nk3rup +n5less +5noc3er1os +nom1a6l +nom5e1no +n1o1mist +non1eq +non1i4so +5nop1oly. +no1vemb +ns5ceiv +ns4moo +ntre1p +obli2g1 +o3chas +odel3li +odit1ic +oerst2 +oke1st +o3les3ter +oli3gop1o1 +o1lo3n4om +o3mecha6 +onom1ic +o3norma +o3no2t1o3n +o3nou +op1ism. +or4tho3ni4t +orth1ri +or5tively +o4s3pher +o5test1er +o5tes3tor +oth3e1o1s +ou3ba3do +o6v3i4an. +oxi6d1ic +pal6mat +parag6ra4 +par4a1le +param4 +para3me +pee2v1 +phi2l3ant +phi5lat1e3l +pi2c1a3d +pli2c1ab +pli5nar +poin3ca +1pole. +poly1e +po3lyph1ono +1prema3c +pre1neu +pres2pli +pro2cess +proc3i3ty. +pro2g1e +3pseu2d +pseu3d6o3d2 +pseu3d6o3f2 +pto3mat4 +p5trol3 +pu5bes5c +quain2t1e +qu6a3si3 +quasir6 +quasis6 +quin5tes5s +qui3v4ar +r1abolic +3rab1o1loi +ra3chu +r3a3dig +radi1o6g +r2amen +3ra4m5e1triz +ra3mou +ra5n2has +ra1or +r3bin1ge +re2c3i1pr +rec5t6ang +re4t1ribu +r3ial. +riv1o1l +6rk. +rk1ho +r1krau +6rks. +r5le5qu +ro1bot1 +ro5e2las +ro5epide1 +ro3mesh +ro1tron +r3pau5li +rse1rad1i +r1thou +r1treu +r1veil +rz1sc +sales3c +sales5w +5sa3par5il +sca6p1er +sca2t1ol +s4chitz +schro1ding1 +1sci2utt +scrap4er. +scy4th1 +sem1a1ph +se3mes1t +se1mi6t5ic +sep3temb +shoe1st +sid2ed. +side5st +side5sw +si5resid +sky1sc +3slova1kia +3s2og1a1my +so2lute +3s2pace +1s2pacin +spe3cio +spher1o +spi2c1il +spokes5w +sports3c +sports3w +s3qui3to +s2s1a3chu1 +ss3hat +s2s3i4an. +s5sign5a3b +1s2tamp +s2t1ant5shi +star3tli +sta1ti +st5b +1stor1ab +strat1a1g +strib5ut +st5scr +stu1pi4d1 +styl1is +su2per1e6 +1sync +1syth3i2 +swimm6 +5tab1o1lism +ta3gon. +talk1a5 +t1a1min +t6ap6ath +5tar2rh +tch1c +tch3i1er +t1cr +teach4er. +tele2g +tele1r6o +3ter1gei +ter2ic. +t3ess2es +tha4l1am +tho3don +th1o5gen1i +tho1k2er +thy4l1an +thy3sc +2t3i4an. +ti2n3o1m +t1li2er +tolo2gy +tot3ic +trai3tor1 +tra1vers +travers3a3b +treach1e +tr4ial. +3tro1le1um +trof4ic. +tro3fit +tro1p2is +3trop1o5les +3trop1o5lis +t1ro1pol3it +tsch3ie +ttrib1ut1 +turn3ar +t1wh +ty2p5al +ua3drati +uad1ratu +u5do3ny +uea1m +u2r1al. +uri4al. +us2er. +v1ativ +v1oir5du1 +va6guer +vaude3v +1verely. +v1er1eig +ves1tite +vi1vip3a3r +voice1p +waste3w6a2 +wave1g4 +w3c +week1n +wide5sp +wo4k1en +wrap3aro +writ6er. +x1q +xquis3 +y5che3d +ym5e5try +y1stro +yes5ter1y +z3ian. +z3o1phr +z2z3w +% end of additional patterns. +} +% DEK's hyphenation exception list, from hyphen.tex; not changed. +\hyphenation{ +as-so-ciate +as-so-ciates +dec-li-na-tion +oblig-a-tory +phil-an-thropic +present +presents +project +projects +reci-procity +re-cog-ni-zance +ref-or-ma-tion +ret-ri-bu-tion +ta-ble +} diff --git a/tmac/hyphen.fr b/tmac/hyphen.fr new file mode 100644 index 0000000..5a71aee --- /dev/null +++ b/tmac/hyphen.fr @@ -0,0 +1,1325 @@ +% This is the file 'hyphen.fr'. +% +% It contains the same hyphenation patterns as 'frhyph.tex'. Here is +% the copyright message: +% +% frhyph.tex % French hyphenation patterns +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% This file is available for free and can used and redistributed +% asis for free. Modified versions should have another name. +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % \message{frhyph.tex - French hyphenation patterns (V2.11) <2002/01/16>} +% +% Please check the original file for more details. +% +% To make the patterns workable with groff, all accent macros in the +% patterns have been converted to use latin-9 characters directly +% (this is, the oe ligature '˝' is used), and everything except the +% \patterns command has been discarded since it isn't needed (and groff +% doesn't understand this stuff anyway). +% +\patterns{ +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%* +2'2 +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%a +.a4 +'a4 +.â4 +'â4 +ab2h % df-bg 1998/02/07 for abhorrer + .ab3réa + 'ab3réa +ad2h % df-bg 1998/02/07 for adh\`esion & co + a1č2dre + .ae3s4ch + 'ae3s4ch + 1alcool + a2l1algi + .amino1a2c + 'amino1a2c + .ana3s4tr + 'ana3s4tr + 1a2nesthési + .anti1a2 + 'anti1a2 + .anti1e2 + 'anti1e2 + .anti1é2 + .anti2enne + 'anti2enne + 'anti1é2 + .anti1s2 + 'anti1s2 + .apo2s3ta + 'apo2s3ta + apo2s3tr + archi1é2pis + .as2ta + 'as2ta + a2s3tro +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%b +1ba +1bâ + .bai2se3main % hyphen disappeared from french 5/2/94 +1be +1bé +1bč +1bę +4be. +4bes. +2bent. % mute syllable: tombent (df) 22/02/94 +1bi +1bî + .bi1a2c + .bi1a2t % like .tri1a2t for tri-athlon bg 12/27/93 + .bi1au + .bio1a2 + .bi2s1a2 + .bi1u2 +1b2l +4ble. +4bles. +2blent. % mute syllable: troublent (df) 28/02/94 +1bo +1bô +1b2r +4bre. +4bres. +2brent. % mute syllable: palabrent (df) 28/02/94 +1bu +1bű +1by +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%c +1ç +1ca +1câ +ca3ou3t2 % for caoutchou... added 3/1/94 df-bg +1ce +1cé +1cč +1cę +4ce. +4ces. +% words ending with -cent (df) 22/02/94 + 2cent. + ja3cent. + ac3cent. + é3cent. + munifi3cent. + réti3cent. +privatdo3cent. + inno3cent. + es3cent. + acquies4cent. + is3cent. + immis4cent. +% +.ch4 +1c2h +4ch. +2chb +4che. +4ches. +2chent. % mute syllable: touchent (df) 22/02/94 + .chč2vre3feuille % hyphen disappeared from french 5/2/94 +2chg +ch2l +4chle. +4chles. + chlo2r3a2c + chlo2r3é2t +2chm +2chn +2chp +ch2r +4chre. +4chres. +2chs +2cht +2chw +1ci +1cî + .ci2s1alp +1c2k +4ck. +2ckb +4cke. +4ckes. +2ckent. % mute syllable: stockent (df) 22/02/94 +2ckf +2ckg +2ck3h +2ckp +2cks +2ckt +1c2l +4cle. +4cles. +2clent. % mute syllable: encerclent (df) 28/02/94 +1co +1cô + co1acc + co1acq + co1a2d + co1ap + co1ar + co1assoc + co1assur + co1au + co1ax +1c˝0 % final zero essential to terminate cs + co1é2 + co1ef + co1en + co1ex + .con4 % missing from nb list + .cons4 % missing from nb list + .contre1s2c + .contre3maître % hyphen disappeared from french 5/2/94 + co2nurb + .co1o2 + .co2o3lie +1c2r +4cre. +4cres. +2crent. % mute syllable: massacrent (df) 28/02/94 +1cu +1cű +1cy +.cul4 % -- as .con4 .cons4 (march 92) +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%d +1d' +1da +1dâ + .dacryo1a2 +d1d2h +1de +1dé +1dč +1dę +4de. +4des. +% words ending with -dent (df) 22/02/94 + 2dent. +déca3dent. + é3dent. + cci3dent. + inci3dent. + confi3dent. + tri3dent. + dissi3dent. + chien3dent. + .ar3dent. + impu3dent. + pru3dent. +% + .dé1a2 + .dé1io + .dé1o2 + .dé2s % originally in JD file + %.d\'e2s1a2 removed 09/17/92 because wrong for the + % original JD 500 words test + .dé3s2a3cr + .dés2a3m % .d\'es2a2mi introduced 09/17/92 bec. i + % can't see why d\'esamidonner ran in JD. + % Moved to .d\'es2a3m df 12/27/93. + .dé3s2a3tell + .dé3s2astr + .dé3s2c % 1 moved 3 due to .d\'e2s 09/17/92 + %.d\'e2s1e2 removed 09/17/92 because wrong for the + % original JD 500 words test + .dé2s1é2 + .dé3s2é3gr + .dé3s2ensib + .dé3s2ert + .dé3s2exu + %.d\'e2s3h removed 09/17/92 because wrong for the + % original JD 500 words test + .dé2s1i2 + .dé3s2i3d + .dé3s2i3gn + .dé3s2i3li + .dé3s2i3nen + .dé3s2invo + .dé3s2i3r + .dé3s2ist + %.d\'e2s1o2 removed 09/17/92 because wrong for the + % original JD 500 words test + .dé3s2o3dé + .dé2s1˝0 % final zero essential to terminate cs + .dé3s2o3l + .dé3s2o3pil + .dé3s2orm + .dé3s2orp + .dé3s2oufr + .dé3s2p % 1 moved 3 due to .d\'e2s 09/17/92 + .dé3s2t % 1 moved 3 due to .d\'e2s 09/17/92 + .dé2s1u2n + 3d2hal + 3d2houd +1di +1dî + di2s3cop + .di1a2cé + .di1a2cid + .di1ald + .di1a2mi + .di1a2tom + .di1e2n + .di2s3h +2dlent. % mute syllable: jodlent (df) 28/02/94 +1do +1dô +1d2r +4dre. +4dres. +2drent. % mute syllable: engendrent (df) 28/02/94 +d1s2 +1du +1dű +1dy + .dy2s3 + .dy2s1a2 + .dy2s1i2 + .dy2s1o2 % missing from nb list + .dy2s1u2 +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%e +.e4 +'e4 +.ę4 +'ę4 +.é4 +'é4 +.č4 +'č4 +éd2hi % df-bg 1998/02/07 for r\'edhibitoire + 1é2drie + 1é2drique + 1é2lectr + 1é2lément + .en1a2 + 'en1a2 + 1é2nerg + e2n1i2vr + .en1o2 + 'en1o2 + épi2s3cop + épi3s4cope + e2s3cop + .eu2r1a2 + 'eu2r1a2 + eu1s2tat + extra1 + extra2c + extra2i +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%f +1fa +1fâ +1fe +1fé +1fč +1fę +4fe. +4fes. +2fent. % mute syllable: agrafent chauffent (df) 22/02/94 +% +1fi +1fî +1f2l +4fle. +4fles. +2flent. % mute syllable: gonflent (df) 28/02/94 +1fo +1fô +1f2r +4fre. +4fres. +2frent. % mute syllable: balafrent (df) 28/02/94 +f1s2 +1fu +1fű +1fy +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%g +1ga +1gâ +1ge +1gé +1gč +1gę +4ge. +4ges. +% words ending with -gent (df) 22/02/94 + 2gent. + ré3gent. + entre3gent. + indi3gent. + dili3gent. +intelli3gent. + indul3gent. + tan3gent. + rin3gent. + contin3gent. + .ar3gent. + 'ar3gent. + ser3gent. + ter3gent. +résur3gent. +% +1g2ha +1g2he +1g2hi +1g2ho +1g2hy +1gi +1gî +1g2l +4gle. +4gles. +2glent. % mute syllable: meuglent (df) 28/02/94 + 1g2n + 'a2g3nat % (df) 16/01/02 + .a2g3nat % (df) 16/01/02 + a2g3nos % (df) 16/01/02 (pattern dia2g3n deleted) + co2g3niti % (df) 16/01/02 + 'i2g3né % (df) 16/01/02 + .i2g3né % (df) 16/01/02 + 'i2g3ni % (df) 16/01/02 + .i2g3ni % (df) 16/01/02 + .ma2g3nicide % (df) 16/01/02 + .ma2g3nificat % (df) 16/01/02 + .ma2g3num % (df) 16/01/02 + o2g3nomoni % (df) 16/01/02 + o2g3nosi % (df) 16/01/02 +.pro2g3nath % (df) 16/01/02 + pu2g3nable % (df) 16/01/02 + pu2g3nac % (df) 16/01/02 +.sta2g3n +.syn2g3nath % (df) 16/01/02 + wa2g3n +4gne. +4gnes. +2gnent. % mute syllable: accompagnent (df) 28/02/94 +1go +1gô +1g2r +4gre. +4gres. +2grent. % mute syllable: immigrent (df) 28/02/94 +1gu +1gű +g1s2 +4gue. +4gues. +% words ending with -guent (df) 22/02/94 + 2guent. +.on3guent. +'on3guent. +% +1gy +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%h +1ha +1hâ +1he +1hé +1hč +1hę + hémi1é + hémo1p2t +4he. +4hes. +1hi +1hî +1ho +1hô +1hu +1hű +1hy + hypera2 + hypere2 + hyperé2 + hyperi2 + hypero2 + hypers2 + hype4r1 + hyperu2 + hypo1a2 + hypo1e2 % missing from nb list + hypo1é2 + hypo1i2 + hypo1o2 + hypo1s2 + hypo1u2 +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%i +.i4 +'i4 +.î4 +'î4 + i1algi + i1arthr + i1č2dre +% ill patterns missing from nb list + il2l + cil3l + rcil4l + ucil4l + vacil4l + gil3l + hil3l + lil3l + l3lion + mil3l + mil4let +émil4l + semil4l + rmil4l + armil5l + capil3l + papil3la + papil3le + papil3li + papil3lom + pupil3l + piril3l + thril3l + cyril3l + ibril3l + pusil3l + .stil3l +distil3l +instil3l +fritil3l +boutil3l + vanil3lin + vanil3lis + vil3l + avil4l +chevil4l + uevil4l + uvil4l + xil3l +% end of ill patterns + 1informat % missing from nb list + .in1a2 + 'in1a2 + .in2a3nit + 'in2a3nit + .in2augur + 'in2augur + .in1e2 + 'in1e2 + .in1é2 + 'in1é2 + .in2effab % missing from nb list + 'in2effab + .in2é3lucta + 'in2é3lucta + .in2é3narra + 'in2é3narra + .in2ept + 'in2ept + .in2er + 'in2er + .in2exora % missing from nb list + 'in2exora + .in1i2 + 'in1i2 + .in2i3miti + 'in2i3miti + .in2i3q + 'in2i3q + .in2i3t + 'in2i3t + .in1o2 + 'in1o2 + .in2o3cul + 'in2o3cul + .in2ond + 'in2ond + .in1s2tab + 'in1s2tab + 'inte4r3 + .intera2 + 'intera2 + .intere2 + 'intere2 + .interé2 + 'interé2 + .interi2 + 'interi2 + .intero2 + 'intero2 + .inte4r3 + .interu2 + 'interu2 + .inters2 + 'inters2 + .in1u2 + 'in1u2 + .in2uit + 'in2uit + .in2u3l + 'in2u3l + io1a2ct + i1oxy + i1s2tat +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%j +1j +2jk +4je. +4jes. +2jent. % mute syllable: gal\`ejent (df) 22/02/94 +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%k +1ka +1kâ +1ke +1ké +1kč +1kę +4ke. +4kes. +2kent. % mute syllable: jerkent (df) 22/02/94 +1k2h +4kh. +.kh4 +1ki +1kî +1ko +1kô +1k2r +1ku +1kű +1ky +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%l +1la +1lâ +1lŕ + la2w3re +1le +1lé +1lč +1lę +4le. +4les. +% words ending with -lent (df) 22/02/94 + 2lent. + .ta3lent. + iva3lent. +équiva4lent. + monova3lent. + polyva3lent. + re3lent. + .do3lent. + indo3lent. + inso3lent. + turbu3lent. + succu3lent. + fécu3lent. + trucu3lent. + opu3lent. + corpu3lent. + ru3lent. + sporu4lent. +% +1li +1lî +1lo +1lô +l1s2t +1lu +1lű +1ly +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%m +1ma +1mâ + .ma2c3k + .macro1s2c + .ma2l1a2dres + .ma2l1a2dro + .ma2l1aisé + .ma2l1ap + .ma2l1a2v + .ma2l1en + .ma2l1int + .ma2l1oc + .ma2l1o2d + .ma2r1x % nb (jbb: ?) +1me +1mé +1mé +1mé + .mé2g1oh + .mé2sa % missing from nb list + .mé3san % missing from nb list + .mé2s1es + .mé2s1i + .mé2s1u2s + .méta1s2ta +4me. +4mes. +% words ending with -ment (df) 22/02/94 + â2ment. + da2ment. + fa2ment. + amalga2ment. + cla2ment. + ra2ment. +tempéra3ment. + ta2ment. + testa3ment. + qua2ment. + č2ment. + carę2ment. + diaphrag2ment. + ryth2ment. + ai2ment. + rai3ment. + abî2ment. + éci2ment. + vidi2ment. + subli2ment. + éli2ment. + reli2ment. + mi2ment. + ani2ment. + veni2ment. + ri2ment. + détri3ment. + nutri3ment. + inti2ment. + esti2ment. + l2ment. + flam2ment. + gram2ment. + .gem2ment. + om2ment. + .com3ment. + ô2ment. + slalo2ment. + chro2ment. + to2ment. + ar2ment. + .sar3ment. + er2ment. + antifer3ment. + .ser3ment. + fir2ment. + or2ment. + as2ment. + au2ment. + écu2ment. + fu2ment. + hu2ment. + fichu3ment. + llu2ment. + plu2ment. + bou2ment. + bru2ment. + su2ment. + tu2ment. +% +1mi +1mî + .milli1am + 1m2némo + 1m2nčs + 1m2nési +1mo +1mô +1m˝0 % final zero essential to terminate cs + .mono1a2 + .mono1e2 + .mono1é2 + .mono1i2 + .mono1ď2dé + .mono1o2 + .mono1u2 + .mono1s2 + mon2t3réal % missing from nb list +m1s2 +1mu +1mű +1my + moye2n1â2g +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%n +1na +1nâ +1ne +1né +1nč +1nę +4ne. +4nes. +% words ending with -nent (df) 22/02/94 + 2nent. % fric-tionnent - syllable muette - bg 27/12/93 + réma3nent. + imma3nent. + perma3nent. + .émi3nent. +préémi3nent. + proémi3nent. + surémi3nent. + immi3nent. + conti3nent. + perti3nent. + absti3nent. +% +1ni +1nî +1no +1nô +1n˝0 % final zero essential to terminate cs + .no2n1obs +1nu +1nű + n3s2at. + n3s2ats. +n1x +1ny +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%o +.o4 +'o4 +'ô4 +.ô4 +%'\"o2 % mjf % deleted 3/1/94 df-bg + o2b3long + 1octet % missing from nb list + o1d2l + o1č2dre + o1ioni + ombud2s3 + omni1s2 + o1s2tas + o1s2tat + o1s2téro + o1s2tim + o1s2tom + o1s2trad + o1s2tratu + o1s2triction + .oua1ou + 'oua1ou + .ovi1s2c + 'ovi1s2c + oxy1a2 +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%p +1pa +1pâ + paléo1é2 + .pa2n1a2f + .pa2n1a2mé + .pa2n1a2ra + .pa2n1is + .pa2n1o2ph + .pa2n1opt + .pa2r1a2che + .pa2r1a2chč + .para1s2 + .pa2r3hé +1pe +1pé +1pč +1pę +4pe. +4pes. +% words ending with -pent (df) 22/02/94 + 2pent. + re3pent. +.ar3pent. +'ar3pent. +ser3pent. +% + .pen2ta % pent- or penta- but never pen-ta bg 12/27/93 + per3h + pé2nul % p\'e2n1ul moved back 09/17/92 to JD def. + .pe4r + .per1a2 + .per1e2 + .per1é2 + .per1i2 + .per1o2 + .per1u2 + pé1r2é2q % 2r1 moved 09/17/92 to 1r2(it was a typo) + .péri1os + .péri1s2 + .péri2s3s + .péri2s3ta + .péri1u2 +1p2h +.ph4 +4ph. + .phalan3s2t +4phe. +4phes. +2phent. % mute syllable: triomphent (df) 22/02/94 +ph2l +4phle. +4phles. +2phn + photo1s2 +ph2r +4phre. +4phres. +2phs +2pht + 3ph2talé + 3ph2tis +%%%% Here is an example of a pb involving phonetic and etymologic patterns 5/94 +%%%% .phyto3ph2 % originally, but wrong for phy-toph-thora 9/92 +%%%% .phy2topha % for -pharmacie but wrong for phyto-biol.. 5/94 +1pi +1pî +1p2l +4ple. +4ples. +2plent. % mute syllable: accouplent (df) 28/02/94 + .pluri1a + 1p2né + 1p2neu +1po +1pô + po1astre + poly1a2 + poly1e2 + poly1é2 + poly1č2 + poly1i2 + poly1o2 + poly1s2 + poly1u2 + .pon2tet % JD hyphenated it asis 09/17/92, exception + .pos2t3h + .pos2t1in + .pos2t1o2 + .pos2t3r + .post1s2 +1p2r +4pre. +4pres. +2prent. % mute syllable: empourprent (df) 28/02/94 + .pré1a2 + .pré2a3la % missing from nb list + .pré2au + .pré1é2 + .pré1e2 + .pré1i2 + .pré1o2 + .pré1u2 + .pré1s2 + .pro1é2 + .pro1s2cé + pro2s3tat + .prou3d2h + 1p2sych + .psycho1a2n + 1p2tčr + 1p2tér +1pu + .pud1d2l +1pű +1py +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%q +1q +4que. +4ques. +% words ending with -quent (df) 22/02/94 + 2quent. + é3quent. + élo3quent. +grandilo3quent. +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%r +1ra +1râ + radio1a2 % missing from nb list +1re +1ré +1rč +1rę + .ré1a2 + .ré2a3le + .ré2a3lis + .ré2a3lit + .ré2aux + .ré1é2 + .ré1e2 + .ré2el + .ré2er + .ré2čr + .ré1i2 + .ré2i3fi + .ré1o2 + .re1s2 + .re2s3cap + .re2s3cisi % for res-cision 09/17/92 (missing from nb) + .re2s3ciso % for res-cisoire 09/17/92(missing from nb) + .re2s3cou + .re2s3cri + .re2s3pect + .re2s3pir + .re2s3plend + .re2s3pons + .re2s3quil + .re2s3s + .re2s3t + .re3s4tab + .re3s4tag + .re3s4tand + .re3s4tat + .re3s4tén + .re3s4tér + .re3s4tim + .re3s4tip + .re3s4toc + .re3s4top + .re3s4tr + .re4s5trein + .re4s5trict + .re4s5trin + .re3s4tu + .re3s4ty + .réu2 %.r\'e1u2 % pattern rejected 12/2/92 + % (don't hyphenate as r\'e-union nor r\'eu-nion) + .ré2uss + .rétro1a2 +4re. +4res. +% words ending with -rent (df) 22/02/94 + 2rent. % es-p\`erent - syllable muette - bg 27/12/93 + .pa3rent. + appa3rent. +transpa3rent. + é3rent. + tor3rent. + cur3rent. +% +1r2h +4rhe. +4rhes. + 2r3heur + 2r3hydr +1ri +1rî +1ro +1rô +1ru +1rű +1ry +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%s +1sa +1sâ +.sch4 + 1s2caph + 1s2clér + 1s2cop + 1s2ch +e2s3ch +i2s3ché +i2s3chia +i2s3chio +4sch. +4sche. +4sches. +2schs +1se +1sé +1sč +1sę + sesqui1a2 +4se. +4ses. +% words ending with -sent (df) 22/02/94 + 2sent. % massent - syllable muette - bg 27/12/93 + ab3sent. +pré3sent. + .res3sent. +% +.seu2le % jbb +.sh4 +1s2h +4sh. +4she. +4shes. +2shent. % mute syllable: smashent (df) 22/02/94 +2shm + 2s3hom +2shr +2shs +1si +1sî + 1s2lav + 1s2lov +1so +1sô +1s˝0 % final zero essential to terminate cs + 1s2patia + 1s2perm + 1s2por + 1s2phčr + 1s2phér + 1s2piel + 1s2piros + 1s2tandard + 1s2tein + stéréo1s2 + 1s2tigm + 1s2tock + 1s2tomos + 1s2troph + 1s2tructu + 1s2tyle +1su +1sű + .su2b1a2 + .su3b2alt + .su2b1é2 + .su3b2é3r + .su2b1in + .su2b3limin + .su2b3lin + .su2b3lu + sub1s2 + .su2b1ur + supero2 + supe4r1 + supers2 + .su2r1a2 + su3r2ah + .su3r2a3t + .su2r1e2 + .su3r2eau + .su3r2ell + .su3r2et + .su2r1é2 + .su2r3h + .su2r1i2m + .su2r1inf + .su2r1int + .su2r1of + .su2r1ox +1sy +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%t +1ta +1tâ +1tŕ + tachy1a2 + tchin3t2 +1te +1té +1tč +1tę + télé1e2 + télé1i2 + télé1o2b + télé1o2p + télé1s2 +4te. +4tes. +% words ending with -tent (df) 22/02/94 + 2tent. % mentent - syllable muette - bg 27/12/93 + .la3tent. + .pa3tent. + compé3tent. + éni3tent. + mécon3tent. + omnipo3tent. +ventripo3tent. +équipo3tent. + impo3tent. + mit3tent. +% +.th4 +1t2h +4th. +4the. +4thes. + thermo1s2 + 2t3heur +2thl % th2l was wrong for ...ath-lon (jd said 2thl) df 12/27/93 +2thm +2thn +th2r +4thre. +4thres. +2ths +1ti +1tî +1to +1tô +1t2r + tran2s1a2 + tran3s2act + tran3s2ats + tran2s3h + tran2s1o2 + tran2s3p + tran2s1u2 +4tre. +4tres. +2trent. % mute syllable: infiltrent (df) 28/02/94 + .tri1a2c + .tri1a2n + .tri1a2t + .tri1o2n + t1t2l +1tu +1tű +tung2s3 +1ty +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%u +.u4 +'u4 +.ű4 +'ű4 + uni1o2v + uni1a2x + u2s3tr +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%v +1va +1vâ +1ve +1vé +1vč +1vę + vélo1s2ki +4ve. +4ves. +% words ending with -vent (df) 22/02/94 + 2vent. +conni3vent. + .sou3vent. +% +1vi +1vî +1vo +1vô + vol2t1amp +1v2r +4vre. +4vres. +2vrent. % mute syllable: recouvrent (df) 28/02/94 +1vu +1vű +1vy +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%w +1wa +1we +4we. +4wes. +2went. % mute syllable: interviewent (df) 22/02/94 +1wi +1wo +1wu +1w2r +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%x +2xent. % mute syllable: malaxent (df) 22/02/94 +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%y +.y4 +'y4 + y1asth + y1s2tom + y1algi +%-------------------%-----------------------% +% phonetic patterns % etymological patterns % +%-------------------%-----------------------% +%%z +1za +1ze +1zé +1zč +4ze. +4zes. +% words ending with -zent (df) 22/02/94 + 2zent. +privatdo3zent. +% +1zi +1zo +1zu +1zy +} + +\endinput + +% Local Variables: +% mode: tex +% coding: latin-9 +% fill-column: 72 +% End: +% vim: set filetype=tex textwidth=72: diff --git a/tmac/hyphen.it b/tmac/hyphen.it new file mode 100644 index 0000000..552bb5d --- /dev/null +++ b/tmac/hyphen.it @@ -0,0 +1,431 @@ +% title: Hyphenation patterns for Italian +% copyright: Copyright (C) 2008-2011 Claudio Beccari +% notice: This file is part of the hyph-utf8 package. +% See http://www.hyphenation.org/tex for more information. +% language: +% name: Italian +% tag: it +% version: 4.9 2014/04/22 +% authors: +% - +% name: Claudio Beccari +% contact: claudio.beccari (at) gmail.com +% licence: +% - This file is available under any of the following licences: +% - +% name: LPPL +% version: 1.3 +% or_later: true +% url: http://www.latex-project.org/lppl.txt +% status: maintained +% maintainer: Claudio Beccari, e-mail claudio dot beccari at gmail dot com +% - +% name: MIT +% url: https://opensource.org/licenses/MIT +% text: > +% Permission is hereby granted, free of charge, to any person +% obtaining a copy of this software and associated documentation +% files (the "Software"), to deal in the Software without +% restriction, including without limitation the rights to use, +% copy, modify, merge, publish, distribute, sublicense, and/or sell +% copies of the Software, and to permit persons to whom the +% Software is furnished to do so, subject to the following +% conditions: +% +% The above copyright notice and this permission notice shall be +% included in all copies or substantial portions of the Software. +% +% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +% OTHER DEALINGS IN THE SOFTWARE. +% hyphenmins: +% typesetting: +% left: 2 +% right: 2 +% changes: +% - 2014-04-22 - Add few patterns involving `h' +% - 2011-08-16 - Change the licence from GNU LGPL into LPPL v1.3. +% - 2010-05-24 - Fix for Italian patterns for proper hyphenation of -ich and Ljubljana. +% - 2008-06-09 - Import of original ithyph.tex into hyph-utf8 package. +% - 2008-03-08 - (last change in ithyph.tex) +% texlive: +% encoding: ascii +% babelname: italian +% legacy_patterns: ithyph.tex +% message: Italian hyphenation patterns +% description: |- +% Hyphenation patterns for Italian in ASCII encoding. +% Compliant with the Recommendation UNI 6461 on hyphenation +% issued by the Italian Standards Institution +% (Ente Nazionale di Unificazione UNI). +% ========================================== +% +% These hyphenation patterns for the Italian language are supposed to comply +% with the Recommendation UNI 6461 on hyphenation issued by the Italian +% Standards Institution (Ente Nazionale di Unificazione UNI). No guarantee +% or declaration of fitness to any particular purpose is given and any +% liability is disclaimed. +% +\patterns{ +.a3p2n % After the Garzanti dictionary: a-pnea, a-pnoi-co,... +.anti1 +.anti3m2n +.bio1 +.ca4p3s +.circu2m1 +.contro1 +.di2s3cine +.e2x1eu +.fran2k3 +.free3 +.li3p2sa +.narco1 +.opto1 +.orto3p2 +.para1 +.ph2l +.ph2r +.poli3p2 +.pre1 +.p2s +.re1i2scr +.sha2re3 +.tran2s3c +.tran2s3d +.tran2s3l +.tran2s3n +.tran2s3p +.tran2s3r +.tran2s3t +.su2b3lu +.su2b3r +.wa2g3n +.wel2t1 +2'2 +a1ia +a1ie +a1io +a1iu +a1uo +a1ya +2at. +e1iu +e2w +o1ia +o1ie +o1io +o1iu +1b +2bb +2bc +2bd +2bf +2bm +2bn +2bp +2bs +2bt +2bv +b2l +b2r +2b. +2b' +1c +2cb +2cc +2cd +2cf +2ck +2cm +2cn +2cq +2cs +2ct +2cz +2chh +c2h +2ch. +2ch'. +2ch''. +2chb +ch2r +2chn +c2l +c2r +2c. +2c' +.c2 +1d +2db +2dd +2dg +2dl +2dm +2dn +2dp +d2r +2ds +2dt +2dv +2dw +2d. +2d' +.d2 +1f +2fb +2fg +2ff +2fn +f2l +f2r +2fs +2ft +2f. +2f' +1g +2gb +2gd +2gf +2gg +g2h +g2l +2gm +g2n +2gp +g2r +2gs +2gt +2gv +2gw +2gz +2gh2t +2g. +2g' +.h2 +1h +2hb +2hd +2hh +hi3p2n +h2l +2hm +2hn +2hr +2hv +2h. +2h' +.j2 +1j +2j. +2j' +.k2 +1k +2kg +2kf +k2h +2kk +k2l +2km +k2r +2ks +2kt +2k. +2k' +1l +2lb +2lc +2ld +2l3f2 +2lg +l2h +l2j +2lk +2ll +2lm +2ln +2lp +2lq +2lr +2ls +2lt +2lv +2lw +2lz +2l. +2l'. +2l'' +1m +2mb +2mc +2mf +2ml +2mm +2mn +2mp +2mq +2mr +2ms +2mt +2mv +2mw +2m. +2m' +1n +2nb +2nc +2nd +2nf +2ng +2nk +2nl +2nm +2nn +2np +2nq +2nr +2ns +n2s3fer +2nt +2nv +2nz +n2g3n +2nheit +2n. +2n' +1p +2pd +p2h +p2l +2pn +3p2ne +2pp +p2r +2ps +3p2sic +2pt +2pz +2p. +2p' +1q +2qq +2q. +2q' +1r +2rb +2rc +2rd +2rf +r2h +2rg +2rk +2rl +2rm +2rn +2rp +2rq +2rr +2rs +2rt +r2t2s3 +2rv +2rx +2rw +2rz +2r. +2r' +1s2 +2shm +2sh. +2sh' +2s3s +s4s3m +2s3p2n +2stb +2stc +2std +2stf +2stg +2stm +2stn +2stp +2sts +2stt +2stv +2sz +4s. +4s'. +4s'' +.t2 +1t +2tb +2tc +2td +2tf +2tg +t2h +2th. +t2l +2tm +2tn +2tp +t2r +t2s +3t2sch +2tt +t2t3s +2tv +2tw +t2z +2tzk +tz2s +2t. +2t'. +2t'' +1v +2vc +v2l +v2r +2vv +2v. +2v'. +2v'' +1w +w2h +wa2r +2w1y +2w. +2w' +1x +2xb +2xc +2xf +2xh +2xm +2xp +2xt +2xw +2x. +2x' +y1ou +y1i +1z +2zb +2zd +2zl +2zn +2zp +2zt +2zs +2zv +2zz +2z. +2z'. +2z'' +.z2 +} % Pattern end + diff --git a/tmac/hyphen.sv b/tmac/hyphen.sv new file mode 100644 index 0000000..f623901 --- /dev/null +++ b/tmac/hyphen.sv @@ -0,0 +1,4765 @@ +% ---------------------------------------------------------------------- +% Swedish hyphenation patterns. +% +% Copyright 1994 by Jan Michael Rynning. All rights reserved. +% +% This program may be distributed and/or modified under the conditions +% of the LaTeX Project Public License, either version 1.2 of this +% license or (at your option) any later version. The latest version of +% this license is in http://www.latex-project.org/lppl.txt and version +% 1.2 or later is part of all distributions of LaTeX version 1999/12/01 +% or later. +% +% Last update: 1994-03-03 (March 3, 1994). +% Revision history: +% 1991-01-08: First version available for anonymous FTP. +% 1991-08-08: Changed \aa to \aa0 at end of line, to stop TeX from +% concatenating the patterns. +% 1991-09-03: Cleaned up lots of inconsistencies in the dictionary. +% As a consequence, the patterns shrunk a lot. Also +% added some 4000 one-syllable words, some of which were +% hyphenated by the old patterns, and some 1500 compound +% words, about half of which were incorrectly hyphenated +% by the old patterns. +% 1991-11-01: Added another some 6200 compound words, all of which were +% incorrectly hyphenated by the old patterns. +% 1991-11-13: Added another some 6500 compound words, all of which were +% incorrectly hyphenated by the old patterns. +% 1992-01-30: Changed macros to ^^, for use with LaTeX and dc fonts. +% 1994-03-03: The hyphenated dictionary now contains about 118,000 +% words. The hyphenation now works much better for compound +% words. Patgen parameters: 1 2 20, 2 1 8, 1 4 7, 3 2 1, 1 +% 10000 4. +% +% This file contains Swedish hyphenation patterns for TeX. It assumes +% that you have fonts with the Swedish letters in the positions where +% they occur in ISO Latin 1 (ISO 8859/1): +% Letter: \AA \"A \"O \'E \aa \"a \"o \'e +% Position: "C5 "C4 "D6 "C9 "E5 "E4 "F6 "E9 +% +% Load this file into initex after plain.tex (or lplain.tex, splain.tex, +% or whatever). +% +% The patterns were generated in such a way that they will hyphenate +% correctly if \lefthyphenmin>=1 and \righthyphenmin>=2. +% +% These hyphenation patterns work quite well for simple words, but not +% quite as well for compound words. I'm working on improving the +% quality, by adding more words. If you know any Swedish words which +% are not correctly hypheneted using these patterns, or if you have +% questions or comments, please contact me: +% +% Jan Michael Rynning +% ---------------------------------------------------------------------- +\message{Swedish hyphenation patterns, Jan Michael Rynning, 1994-03-03.} +{ +% Set \catcode, \uccode, and \lccode for the Swedish letters. +% This should be done for all letters, really. +\catcode`^^c5=11 \catcode`^^c4=11 \catcode`^^d6=11 \catcode`^^c9=11 +\catcode`^^e5=11 \catcode`^^e4=11 \catcode`^^f6=11 \catcode`^^e9=11 +\uccode`^^c5=`^^c5 \uccode`^^c4=`^^c4 \uccode`^^d6=`^^d6 \uccode`^^c9=`^^c9 +\uccode`^^e5=`^^c5 \uccode`^^e4=`^^c4 \uccode`^^f6=`^^d6 \uccode`^^e9=`^^c9 +\lccode`^^c5=`^^e5 \lccode`^^c4=`^^e4 \lccode`^^d6=`^^f6 \lccode`^^c9=`^^e9 +\lccode`^^e5=`^^e5 \lccode`^^e4=`^^e4 \lccode`^^f6=`^^f6 \lccode`^^e9=`^^e9 +\patterns{ % just type if you're not using INITEX +.a4b +.ab5i +.ab5ol +.ab3r +.ac3 +.a4d +.a3dr +.ad3s +.a5g4ra +.a5gre +.a5kl +.a5le +.al4pr +.a3lu +.am4br +.amp3l +.a5mu +.and4rar +.a2n5es +.ang4er +.an5go +.an5s +.ap1p +.as2k +.a3sket +.as4t +.a5sten +.a3sti +.a5ta +.at3t +.au3st +.a4val +.av3s4 +.b4 +.bak5s +.ben5s +.bild3s +.bo2k +.bort1 +.cis4 +.cy5klop +.d4 +.d^^e4r3 +.ek1v +.e3l4a +.e2l5in +.en5st +.e4n^^e4 +.e2r3i +.e2s +.e5skad +.es3kal +.es5kap +.es4t +.e5strad +.e3tr +.evan5 +.ex3 +.f4 +.feb3r +.fram3 +.fres5 +.f^^e5gel3 +.f^^f6r1a +.f^^f6r1en +.g2 +.gu4l^^e4 +.gus3 +.he2m +.hu5sa +.ib4 +.ik4 +.im3p +.i2n1 +.i4na +.in3d +.in4ger +.ink2 +.in3s2 +.in3t +.is5ka +.i3so +.k4 +.kans4k +.ko5li +.kort5s +.kring3 +.krings2 +.k^^f6p5s +.l2 +.lak5r +.lek5tr +.lu2st +.m2 +.mas2ke +.ma5skeri +.me4re +.minis4 +.mj^^f6lk5s +.mon2s +.m^^e5n3s +.m^^e54st +.m^^e4n5sko +.m^^f6rk5r +.n4 +.ner1 +.no4n +.n^^f6d5r +.oc1ku +.ok3t +.o3kv +.o2ma +.o2mo +.om3s4 +.o3mu +.on4k +.o3o +.ord3s +.o5sc +.o1s4k +.o3sl +.o3stra +.o3sv +.o3tr +.o1u +.p4 +.papp5s +.pa3ste +.pa5sti +.pi5sti +.pres2s +.pub3lika +.r2 +.re4gr +.re2ste +.runs4 +.rym2d +.r^^f6ve5 +.s4 +.sa2k +.seg3r +.si5o +.sj^^f61 +.sk4 +.skott3s +.slut3s +.st4 +.sta2m +.sten3s +.string4 +.sup3p +.t4 +.ta3bl +.ta4k +.tak5l +.tes3ta +.tig3r +.til4l +.ti3o +.topp5s +.tred2s +.tre3s +.tr^^e45k +.u3k +.ult5r +.ung2e +.up2 +.u4ra +.ur3s +.u2t1 +.u4ta +.u5trer +.ut5s +.v2 +.var4t +.vatten3 +.ved5s +.v^^e42g +.v^^e4g3s +.x2 +.y2a +.y4e +.^^e5ng3 +.^^e5r4s5 +.^^e53st +.^^e5ter1 +.^^e43ro +.^^f63ro +a2b +ab4bu +a5be +abel4s +abe2s +ab1l +ab3la +ab3ort +ab5ric +ab3rio +ab4sc +ab4sk +a5bu +ac4kes +ac4kis +ack3sk +ack3u4p +a5dag +a5dek +a5del +ad5ep +ad3j +ad3op +a5dran +a3dre +1adres +ad3ril +ad3ru +ad2s +a5ed +af4fo +3aff^^e4 +1af3ri +af4tor +a1ga +aga4ra +a1ge +a2ge. +ag1gr +ag1l +ag5ord +ag3ro +a4gur +a4hj +aib4 +a3iv +a1j +a3ka +a4kart +a5ke +a1ki +ak3n +a1ko +ak5ram +akri5s +ak3rob +ak4sta +1aktig +ak3tri +a1ku +a5kvari +ak3ve +a5k^^e5r +ak5^^e5t +4ak^^f6 +a1la +al5adm +ali2br +a2lin +a5lin. +a3line +al3ins +ali5stik +a4lj +alk3ak +al2kv +al4k^^e4 +all3st +al3l^^e5 +alms4k +a1lo +al5ort +als5pa +al3tr +al4tu +al4t^^e4 +a1lu +alu5s +alv3s +a1ly +a4maf +am4i +am4pr +am1s +am3^^e5t +a3m^^f6 +ana4bo +an3alf +an3ark +an3c +anci5 +an5dak +andel2s +an4dun +an4d^^e4n +a4nef +ang4es +an3gi +an1gr +aniu4 +ank3r +ano2i +a4nok +a4nop +an5sce +ansis3t +an4sj +ans5ku +ans3li +ans3par +an1st +an4sto +an4sty +1ansvar +an4tj +an4tre +a1nu +a5ny +a3n^^f6 +a1o +a1pe +a2pe. +ape4n3 +a1pi +ap4lan +apo3str +1appara +apps4k +ap3ric +ap3rif +a5pris +ap2s +ap3se +aps5l +aps3p +apu5s +a5py +a5p^^e4 +2ara +a4rann +a4rarv +1arb +4arbi +2arbo +4arbr +ar3dr +ard5st +a4rend +arg5si +2arh +a1ri +a4rigen +ar3ka +ark3lan +ar5kr +4arl +4arn. +ar4nal +a1ro +a2rob +4arp +ar2sa +ar5skal +arsk5l +ar2sv +ar4tro +arts5p +ar4tur +4aru +a4rur +a5rus +ar4v^^e4g +a3ry +a3r^^e4 +2asa +asbe4 +a1sc +as2h +asis5t +as3kis +a2sko +a4skr +as3ku +as5l +as3pa +as3pig +as2sk +as2s5op +as2sp +as2st +ass5up +as3ta +a5stard +as5ter +as5tiker +asti5o +as3to +as4tr +ast5rak +a5stral +ast3rol +as5t^^f6r +a3su +a4sul +a4sund +as2ut +as3v +a1sy +a2s5^^e5 +a2s^^f6 +a1t +ata5ra +a5te +ati5^^f6 +a4tj +a2tr +a3tral +4atrar +a4t3re +at3ria +a3tric +at3rie +a5trik +a3tris +a3t4ro +a4tro. +at4ska +1attac +at2tak +at4tj +at4tos +att3s +a4tung +2au +au5b +au2t5a +3autom +aut5s +2a1va +a4vart +1avg +2a1vi +av3r +4a3v^^e4 +a5^^e5 +1b2 +3ba +ba4di +ba4do +bad3s4 +bak5l +ba4ko +ba4ku +bank5l +bas4ta +ba5stu +4bb +b4bak +b4batt +bbb4 +bb3l +bb4ler +b4b3r +bb4so +4b3d +3be +be3d4r +be5e +be1k +4beld +be5lu +be3ly +be3l^^e5 +be5l^^f6 +beng4 +be3n^^e5 +be1r^^f6 +be1s +be3sl +bes5s +be4sta +be4ste +be5su +be3tr +be3tv +be3u +4bex +2b3f +2b5h +3bi +bi3d4 +4binv +bis3ko +bi5skv +b3je +b3k +b5lar +b5lat +ble4mo +b5len +5blera +3bles +5blid +3blikr +3bliks +4b3m +2b3n +3bo +bo4gr +bo2kl +bo1mu +5bon +bors5te +bor4ti +bort3r +borts2 +bort3sl +bo1s +bo4sc +boy5 +4b3p +2b5raf +4brar +2b5rati +3brik. +b3rika +3brike +3briks +b5rik^^f6 +bru4st +3bry +3br^^f6 +4b3s +b5sce +bs3ch +b4slan +b4sof +b4sp +bst4 +b4stj +4b3t +3bu +bund4s +bus2st +b3v +3by +by5r +3b^^e5 +b^^e5ng3 +b^^e5t2s +3b^^e4 +3b^^f6 +b^^f6r2s +c2 +5cap +c3c +1c4e +cens3t +3centr +ceu4s +4ch. +3chau +3chef +5choc +4cht +ch^^e4s3 +ch^^f6r4 +1ci +ci4lu +cim2 +cipp4 +4ck +c3ka +c3ke +c3ki +ck5j +ck1l +ck5lis +ck3n +c3ko +c4kordn +ck3org +c4kort +ck3r +ck4re +ck3sla +ckus2 +ck3va +ck3ve +ck3v^^e4 +ck5^^e4 +ck3^^f6 +cle2a +co2a +co4m +4cr +cros2 +4cs +1cy +1d +3da +5da. +4dadr +dags3 +2dak +5dako +da3li +5dam +da3m^^e5 +4dand. +4d1ap +4darb +4dart +da4tr +dat5t +4dax +2db +4dc +dcen3 +2dd +ddd4 +ddi4s +d3dj +d4dos +dd3ra +dd3re +dd3ri +d3dr^^e4 +dd2s +dds3v +3d2e +de1k4 +4deko +4deld +del2sa +dels5ti +de5lut +d4en +denti5^^f6 +den2to +de3pr +5der +der1k +de2ro +de5rol +der5sti +de4ru +de2s +de3se +de3sp +des3ti +d4et +de3tr +4dex +2d1f +df^^f63ra +2d1g +d3gl +2d5h +3di +dias4 +di5el +di2gr +di3ka +di5ku +4dinf +din3g4o +4dinr +4dins +2dinsp +4dint +di1o +di4od +di3sc +di4sj +dis3ko +dis1kr +dis1p +dis5to +dis3tra +di4tre +2dj +d3jor +djup5p +3djur +2d3k2 +4d5l +2d1m +2d1n +3do +d2ol +do5lo +4domr +dom2sk +5don +do4pak +4d5ord +4dori +4dort +d5ost +do3y +2d1p +2d2r2 +d3rad +3d4rag +d3rand +d5rarb +d5rassera +d5ratu +3drej +d3ren +5dres +d3ret +d4ric +3drif +d3rig +4d5rik +d3rin +3d4riv +d5roc +3dropp +d3ror +4drot +drotts3 +d3r^^e4kn +3dr^^e4kt +5dr^^e4n +d3r^^e4t +d5r^^f6d +4ds +d2s1an +d2se +ds5enh +d4sf +d2si +ds3ins +d2sj +dsk2 +d3skef +ds4ken +d3ski +ds3kl +ds5kn +ds1l +ds4lot +ds4mo +d4sm^^e5 +ds5n^^e5 +d2so +ds3pl +ds3s4 +ds3tal +d5stat +ds4te +dste4a +d5stig +ds3tin +ds5tro +d2su +ds1v +d2s^^f6 +2d3t +3du +dub3ble +4dup +du1s +du2sc +du4ste +du5s^^f6 +4dut +du4vu +2d1v +d3vr +2d3w +3dy +dy4kan +dy4ro +4dz +5d^^e5g +2d^^e5s +4d^^e5t +4d^^e4g +d^^e42r +3d^^f6 +d^^f6ds1 +4d^^f6g +4d^^f6p +d5^^f6st +d^^e94 +e1a +e2ake +e4am +4eb +e2br +eb3ril +4ec +e3ch +echiff5 +ecis4 +e3co +e2d +e4dans +edd4r +edi4u +ed3j +e5dral +ed1sk +ed2sko +ed3s2l +edso4 +e3d^^e5 +e1e +e2ed +e4ei +ee2k5 +e4en. +e4ene +e1f +ef4s +3efte +e1g +e3ga +e3ge +ege2l +eg1l +eg2ler +e3glera +e5gleri +e4gran +eg5rat +eg3rin +e5gru +egs3 +e5g^^e5 +eig2 +ei5gn +e3ik +e1in +ei5sh +e1isk +e1jo +e3ju +e3j^^e4 +e5j^^f6 +e3ka +e1ki +e1kl +ek3lat +ek4le +ek3n +e1ko +ekord5s +ek3orr +ek4ret. +ek5ro +e1ku +e1kve +ek5vis +e1ky +e1k^^e4 +e1la +el1akt +el4arb +3eld. +eleb3r +elekt3ri +el4fra +eli5ku +el3k4 +el3li +ell3s +el3l^^e4 +e1lo +e4lob +el3p +el2si +el5ug +e5luv +2e1l^^e4 +e1m +e5mat +e5mis +emon1s +em5ort +emp5le +en5art +e2nav +en4ce +e4ned +e4nek +ene3r^^f6 +2enj +en5klo +en3kn +en5kr +en5k^^e4 +enning5 +ennings2 +eno2m +en3si +ens5ke +ens2m +en2sp +ens4te +ens4vin +en4s^^e5 +ent4ha +en2t1r +ent4rat. +ent3rati +ent3ri +ent5ru +e5nus +2eny +2e1n^^e4 +e1o +e2og +eo4i +e5or +2ep +e1pe +e1pi +e3pla +ep5le +epp2s3 +epps5t +e1pr +ep3s +ep4tr +epu3b +e3p^^e5 +er1ak +4eras +er3d4 +erg4l +er4gu +er4g^^e5s +e1ri +e5rib +e4rinf +erings3 +eri5stik +erk4lin +erl^^e44 +er5na +e1ro +e3rob +e2rom +erp4 +er3ra +er5sc +ers4ken +er3sl +ers4le +er4sta +er2ste +er3str +er3sv +e1ru +e5rum +e3ry +e5r^^e5d +e1r^^e4 +e2sal +es5all +es3arm +e1sc +2ese +es4hi +esi4u +es2k +e4skan +es5kar +e4s3ken +es3ker +es5kul +e1sl +e5slag +es2mi +e1sp +es3pl +es2sk +ess5l^^e4 +es2st +e3stal +es5ten. +esti2ge +es3tin +es5tor. +es4tr +est5rer +e3stru +est4r^^f6 +e3st^^e5 +es2u +e1sy +eta3b +e5ti +eti3^^f6 +e1to +e5tri. +et3ris +e5tr^^e4 +et2s +ets2ad +ets3kr +ets1l +ets3m +ets5pa +et4sv +ett3r +e1tu +etu4ri +et4va +et5vu +e1ty +2etz +e1t^^e4 +et^^e4c4 +euk4 +e5um. +e5up4 +4eur +eu4se. +eu5tro +e1v +e4varm +e4vj +ev3r +3exp +ext4r +4e^^e4 +f2 +3fa +fac4 +fac5ke +4fans +4farb +fa3sh +fa4st +fa4t^^f6 +4fav +4f3b +f3d +3fe +4fef +fe2l +fes5ta +fe3sto +4fex +2f1f +fff4 +ff3l +ff3n +f3fo +ff3r +ffs4 +f3f^^e4 +ff^^f65re +f3g2 +f5h +3fi +fi2br +fib5rig +fi3li +fin5sm +fi3skal +fisk3r +fi2ti +2f3k +1fl +flo4da +4f3m +fma4 +1fo +4fof +fol2 +folk1 +2f5om +fo2na +for4mo +fost3r +4f3p +fra2m +fram5p +f4rer +5freri +fre4s +f4ri. +fri5sp +5frit +fros5ta +fru5str +fr^^e5n5 +2f3s +fs2k +f4sl +f4sm +f4sn +f4sp +f4st +f4sv +2ft +f3ta +f4taf +f4tak +f4tap +f4tarm +fte4r +f4tex +f3ti +f4tin +f3to +f4t3r +ft2sa +ft4set +ft2s5i +ft4sj +fts4t +fts5v^^e4 +ft5t +ft1v +3fu +furs5te +fu5ru +fu3tu +4fv +5fy +fy4ma +f^^e53t^^f6 +1f^^e4 +f^^e4s5ti +3f^^f6 +f^^f62ra +f^^f62ren +f^^f62ri +f^^f6r3k +f^^f6r3sm +f^^f6r3su +f^^f6rt4 +f^^f6r1^^f6 +ga5br +3g2ag +4gakt +3g2al +gall3s +ga5l^^e4 +ga4no +2garb +4garm +ga2ro +4gart +ga4st +ga4su +5g2ati +gaus4 +g4av +g5avsn +4gax +2gb +2gd +g3d4r +ge2a +ge5b4 +2gef +2ge4j +g2eli +3gelis +gel5st +gel5y +3gel^^e4 +gel5^^e4n +g4em +ge4nap +gen5g +3g2eni +3genj +4genm +genom5 +gen4sa +g4ense +1g2ent +4genv +ge5ny +3gen^^e4 +ge2o +1g2era +4gerarb +3g2eri +gers5n +5gese +ge4to +get5s +5g2ett +2g1f +2gg +g1ga +g4gap +g1ge +gg5g +gg1l +g4gos +ggs4la +ggs4m +gg3s4t +gg3s4v +g4gu +2gh +gh4te +1g2i +gi1o +gi5sn +gi4ste +gis4tr +gi5stral +gi5st4rat +3giv +gi2^^f6 +g2jo +3gjor +g3j^^e4 +2g3k2 +2gl +g4lans +g1lar +g2las +5glase +glas5k +5glas^^f6 +g4lid +4glj +g4l^^f6g +5gl^^f6m +2g1m +2g1n +g4nag +g2no +1g2o +3go. +3gol +gon3s4 +4gont +2gord +4gorm +4gort +go3sl +2g1p +g2r4 +3graf +5gral +gra2m5 +5grans +4gras +5grec +5grett +g3rig +4g5rik +5grip +3gris +g5roi +gro2v +4grum +grus5t +g4r^^e5 +5gr^^e5. +gr^^e44n +5gr^^e4ns +2g2s +gs1an +g5satt +g3sel +g4sf +gsi4d +g3sju +g5skaf +gs4ki +gs3kn +gs4kot +g3sky +gs1l +gs1m +g4sme +gs3n +gs4ni +gs4n^^f6 +gs1or +gs3pl +gs3po +gs4por +gs5pre +gs3pu +gs3s +gs3tak +gs3tal +g3stark +gs4ten +g3stif +gs3till +gs3tj +g3stol +gs3tra +gst4re +g3st^^e4m +g4sug +gs1v +g4s3ve +gs3vi +gs3v^^e5 +gs3yt +gs1^^e4 +2g1t +g3tr +1g2u +4gug +guld3 +gul4da +4gul^^e4 +gu2ma +4gup +gu5ru +gus4k +2gut +g3utb +2g1v +4gw +3gy +gytt3j +1g2^^e5 +g^^e5rds5 +2g5^^e5ri +g4^^e4l +g2^^e4r +g^^e44s +1g2^^f6 +4g^^f6g +g^^f65ro +2g5^^f6rt +1h +ha3bl +ha5ge +ha4li +hal4so +halv3^^e5 +ham4st +handels3 +hands4l +han5g2a +ha5ra +ha4sc +ha4sp +hasp5l +has3t +hav2 +havs3 +h5c +4hd +he4at +he4fr +he4l^^e4 +hets1 +hets3t +hets3v +h3g +h2i +4hir +his2sk +hi4t +hj^^e4l3s +h1k +2hl +h4le +2hm +4hn +h2na +h2nit +ho5nu +hop5plo +hop3s +hos3p +hos5ti +4how +h3p +h5ru +h1s +2ht +hu2s +hust5r +hyg5r +hys4t +hys5ta +hy3ster +h^^e5rd5s4 +h^^e4ll2 +h^^e4lls1 +h^^e4lso3 +h^^e44ri +h^^e44s +h^^e44var +h2^^f6 +h^^f62g +h^^f65gen +h^^f6g5r +h^^f6rn5s +h^^f64s +h^^f6st5r +i1a +ia3fr +ia3g +ia4lu +ia4sk +ia3tr +i2b3l +i5bril +i3ca +i4ce. +i5cha +ic4kord +ick3u4 +i5co +i2d +iden3s +id4ge +i4dom +id1r +id3ro +id2s +ids3v +i4dun +i3d^^e5 +i4d^^f6 +2i1e +ifes4 +i5fn +i1fr +3ifr^^e5n +i1g +4igan +i2geb +ig5ej +ig1l +ig3no +i3i +i4kart +i1ki +i3klo +ik5l^^e4n +ik3n +i1ko +ik3re +i5krob +ik5rof +ik5ros +ik5s2h +ik5skor +i3kul +i3kum +ik5u4t +ik1v +i3ky +i3k^^e5 +i3k^^f6 +i1la +il4dan +i2lin +il1j^^f6 +il5k +il5lak +il4lik +ill3s2 +3illu +il5l^^e4r +il2min +i1lo +il2tj +i3lu +ilufts5 +i4lup +i5l^^e4 +im2b3r +im5sm +im4so +i1mu +i5m^^e5 +i3m^^e4 +i5m^^f6 +i4nau +ind5sk^^e4 +ind5sti +1indu +in4ga +in4ge. +ing4es. +ing5is +in5glas +ings5te +i3ni +i4nif +in5j +in5kve +1inneh +5inre +1inri +3inr^^e4 +in4sem +in3skr^^e4 +in3sl +ins4m +in3sn +1inspe +5inspeln +in5spr +3instink +3instru +in4st^^e5 +in5te +1intr +in4tra +int3s +i1nu +i4nun +in3ym +i1n^^e4 +i5oc +i1og +i3ok +io4kr +i1ol +io5li +i5om +ion2 +i3ono +ions3 +i1op +i1or +i1os +i1ot +i1pe +i1pi +ipos4 +ip5pi +i3ra +i4res +i1ri +irk5l +i1ro +iro3p +i1ru +i5sce +isel4 +is2h +i2sk +is5kep +isk5na +is3kopa +is3ku +is4kun +is3ky +i5slam +is3l^^e4n +is3m +is3n +i2s3p +is4pri +is3sa +is3se +iss5n +is4s3tr +iss3t^^e4 +i1stal +i1stans +ist5att +is5ten. +i1stent +is4tes +is3tig +is5ting +is5tor. +is5tore +ist5ro +ist^^e54 +is5v +i3sy +i4s^^e5 +i1t +it5c +i4tei +i4tex +i4tj +it5ran +i5trin +i3tris +it2t5op +it4t3r +it4tu +i2t5^^e5 +4i1u +i1va +i2vak +i1vi +i4vin +iv3r +iv2s +i1v^^e5 +ix2t +ix5tu +i1^^f6 +1ja +3jakt. +4jarb +jas5p +2jb +2jd +jd3r +jd4sty +j4du +1je +je2a +5jef +je5sta +2j1f +4j3g +4jh +1ji +4jin +4jk +j4kl +j3ko +jk3v +2j1l +2jm +2j1n +j2o +3job +jo4kr +4jolj +jo5l^^f6 +jor4din +jord3s4 +3jou +4jp +j5pl +2j3r +2j1s +j5sa +j4sk +js4me +js4te +2jt +jts4 +2j2u +ju4kos +juk3s +jul3k +4jur +jus5kr +juss4 +jus4t +jus5ta +jut4sta +j^^e45lo +j^^e4l4p5r +j^^e4l4sa +j^^e4rn3sk +j^^e4r5s +j^^f6r2s +j^^f6s4t +5j^^e9 +1k2a +3ka. +3kad. +3kade. +ka4dr +2kaf +5kaf^^e4 +ka3i +ka5ju +2kak +k3akti +4kalf +4kalg +kal4lo +kall3s +3kamp +3kamr +3kan. +4kand. +5kano +2kap +3kapi +ka5pla +kap4pr +kaps5t +5kapten +3kar. +ka3ra +4karb +k5arbet +ka5ri +4kark +3karna +4karp +karp5s +4kart. +4karte +4karv +3kas +ka4sk +kas3ti +3kat. +3kats. +4kau +2kb +4kc +2k3d4 +kdom4 +1k2e +3ke. +2ked. +2keda +ke3dr +ked4s +ke4er +2kefu +4keld +kels4 +4kense +ke5n^^e5 +2kep +3kern +ke2s +kes3s +4kex +2k1f +kf^^f62 +kf^^f63ri +2k5g4 +2kh4 +kid3s +4kif +1kig +kik4s +kilt4 +5kim^^e5 +king3r +4kinne +4kins +2kint +ki4nu +ki4tr +kiv3s +4kj +5kjol +k3j^^e4 +2k3k +kl2 +1klag +k2lama +kla4mi +3klang. +3klass +2klat +5klav +2kle +k2lej +2klig +k2lim +3klip +k2lis +5klist3r +k5lock. +5klocka +3klos +1klub +4kluk +1kl^^e4d +2k3l^^e4g +2k1m +2k2n +k4nal +3k4nap +5knip +3k4niv +3k4nu +k4ny +k5nyk +k2o +4koc +ko5de +k5odl +kog3n +ko4gr +kog4s3 +4kola +ko2lin +4kolj +kol5tr +5kolv. +1kom +3komm +5komp +2k3omr +kom4s +1kon +3konf +3konst +3kont +ko3nu +1kor +3korg +ko3ri +2korr +3korres +5kortera +ko5s4k +ko3sl +3kost +ko4str +4k3ou +2k1p +k2r4 +3kraf +5kra3ge +4krang +5krera +k4reten +krid5s2 +1krig +krigs3 +krings2k +4kriv +3kropp +kropps5 +kru5stad +k3ryg +kr^^e5k5s +kr^^e54pa +k5r^^e4dd. +kr^^e4k5l +4kr^^e4l +k3r^^e4t +2ks +ksaks5 +k2s5as +ks3ch +k4ser +ks2k4 +ks3kl +ks5kra +ks5kv +k3sk^^e4 +k3sk^^f6 +k5slag. +ks2li +k5sly +k2so +ks3pl +k1s4t +kstavs3 +ks5tid +k2su +4k1t +k4tex +kti5ge +k4tinn +k2tins +k2tod +k2tom +k2tr +kt3re +kt3rin +k5trod +kt5rog +kt3rol +kt5r^^e4t +kt2st +kt5t4 +k4tug +k2tut +k4t^^e4l +4kug +k5ugn +ku5la +4kuld +3kul^^f6 +kum5pl +kungs5 +5kunn +ku4pen +ku4ro +3kurs +3kus +kust3a +kv4 +3kvali +k5vare +3kvarn +kvar3s +3kvart +k4vato +k2ve +2kvente +1kvinn +5kvire +k4vo +k1v^^e5 +3kv^^e4ll +k1v^^e4r +kydds3 +ky4lin +3kyrk +k^^e4l4m +5k^^e4mp +5k^^e4nn +3k^^e4ns +3k^^e4rl +4k^^f6g +k^^f6ks5t +5k^^f6p. +k^^f6r4l +k^^f6r4sl +3la. +1lade. +2ladm +4ladr +2laf +3lagd. +la4gin +5lagm +lag3r +2lak +5lakan. +5laki +3laktis +la5lo +3lande. +lan4di +2lappara +2larb +1larn +lar5s +4lart +las3h +4lask +la4st +5laste. +1lat. +la5tr +lat4tis +2lau +2lav +la5vu +2lb4 +4l1c +2l2d +lder4s +l3dj +ld3ra +l5dry +lds4an +1le +3le. +le4ge. +le5ig +le2kl +le4kv +lem4s^^f6 +2l5enl +3ler. +ler5k +3lern +ler3ste +le5s2l +le5t^^e5 +le3um +le4vu +2lex +2l1f +2l1g +l2gj +l3g2l +lgs4 +lg5st +2lh +1li +li5ch +3lif +3lig +li4go +lig3s +lik2l +li5kli +lik3s +5limer +2lind +2linga. +ling5o +4lingr +lings5t +2lini +5linj +2lint +li1o +2lip +lis3c +li4sta +li3str^^f6 +li4vo +livs1 +l2jak +4l1jo +1lju +l5j^^e5 +l1j^^e4 +l3j^^f6r +2l1k +l3ke +l5kju +l2kl +lk5lag +l5kl^^e4 +l2kr +l3k4ra +lk3t +l1la +lld4 +ll3dr +lle5b +ll3k +ll1l +l1lo +llok5v +ll3p +ll4san +ll2se +ll3ska +ll2so +ll4sva +ll4tig +ll3tr +l1lu +ll5un +llust3ra +ll5v +l5ly +ll^^e4ggs5 +l5l^^f6d +ll^^f6r4 +ll5^^f6rt +4l1m +l4mol +lm3st +l1n +lo2af +loc4ku +4lodl +lo4do +lod3st +lo2ge. +2lolj +2lom +4lord +2lorg +lor4s +lo4vo +l4pak +l1pe +l1pi +l5pla +lp5l^^f6 +lp4st +4l3r +2l1s +l2sc +l4sjo +l4sj^^e4 +l2sk +l4skensv +l3ski +lsk3n +l5skot +l3skr^^e4 +l3sky +l3sk^^e5 +lsk^^e54p +l3sk^^e4 +l3slu +l4sm +ls4mo +ls5nyt +l2sp +l3spe +ls3pl +ls3pol +ls5s +l2st +l3sta +l4stak +ls4te +ls5ter +l3sto +l3sty +l4styg +l3st^^e5 +l3st^^e4 +l5st^^f6 +l2su +l5sur +l2sv +l4svi +ls5vid +l4s^^e5 +4l1t +lta2tu +l4tef +l4tif +l4tih +l4tos +lt5rati +l4tret +l4tr^^f6 +lt5sk +ltu4 +lu5i +luk4to +4lull. +2lun +lung3 +2lupp +lu4pu +lus2s5p +5lust. +4lutb +4luts +2lv +l1va +l4varm +lvers4 +l1vi +l4vos +lv3ri +lv3sp +l1v^^e4 +lv^^e4v4 +lycks5t +ly4gat +lyg3r +lyg3s2 +3lyste +5lystn +ly4str +2l^^e5. +l^^e5g3s +1l^^e5ng +l^^e5ng3s +l^^e54sk +l^^e5s5te +l^^e54st^^e5 +4l^^e4c +l^^e4g5r +1l^^e4nds +5l^^e4ngder +l^^e44san +l^^e44sp +l^^e4tt3s +4l^^f6l +4l^^f6m +3l^^f6n +3l^^f6rer +1l^^f6s +l^^f64v^^e4 +3l^^e9 +1ma +ma5fr +mag5n +mag5s +ma5ju +mak3r +ma3li +mand4 +mang2a +man5g4o +ma5ni +mani1k +5ma3ri +mash5 +mas3ko +mask3ro +ma5sk^^f6 +mas3ti +mas4v +2mb +mb4sk +2mc +2md +m4dat +m4di +m4do +m3d4r +1me +2meds +me4du +me4kl +me4ko +4meld +melo5 +me5lu +men5k +me5nu +me5ny +mer2sko +me4so +mes4t +me3sti +2meta +me5trin +met3ro +meu4 +2mex +2m1f +m4fes +m4fn +2m1g4 +2mh +1mi +mid3s +mi4lu +2mind +ming4o +4mink +min4kr +4minv +mi3n^^f6 +mis2 +mi5sf +mi4sp +miss3t +mi4te. +mi4tr +mitt3s +2m1k +2m3l +2m1m2 +mme5d +mm3s4 +m4mul +2m1n +m2nam +mnas3t +m4nav +mn5dr +mn3g4 +mn5st +mn5tu +m2n3^^e5 +1mo +m4od +mo4i +2momr +mo3na +mos3k +mo2ta +mo4tin +mo4tu +mot3v +2m1p +m2pak +m4part +m2pl +mp3lad +m5plane +mp3lat +mp3lin +mpos4 +mp5p4 +mps4k +mp5sp +m4p^^e5 +2m1r +4ms +m4sal +m4ske +m3slag +ms3l^^e4 +ms2m +mste2 +m1sto +m2str +mst3rin +ms5^^e4p +2m1t +4mud +mulls3 +mult5r +5mum +4mun3g4 +mun4ko +3mur +3musi +mu3sta +mut4sl +2m3v +1myn +mys4te +m^^e5g4 +1m^^e5l. +5m^^e5let. +5m^^e5n. +4m^^e5r +m^^e51s +4m^^e4g +m^^e4k3 +1m^^e4n +m^^e4ns4 +3m^^e4rk +1m^^e4s +m^^e4s5ta +1m^^e4t +m^^f64bl +m^^f64gen. +3m^^f6j +m^^f6r4kl +3m^^f6s +4m^^f6v +1na +3na. +3nad +nads3 +2naf +na5gr +2nak +3nako +3nakr +na3kro +n1akt +2nalf +5nalfl +4nalg +nal3s +na2lu +n5amb +5namn +4nand. +4nanv +na4rap +2narb +2nark +4narm +2nart +nast3r +2nb4 +2n1c +n2ch +n3cha +n3che +n3chi +ncis4 +ncyk3l +2nd +n4dak +n4dav +nd3d4 +n5de +nde3s +n4dil +nd5rak +nd5ras +nd3rat +nd3ri +n5dril +n3drop +nd5ros +nd5skal +nd3sn +nds3or +nds5v^^e4 +nd5^^e5s +1ne +3ne. +ne4di +5nedl +ne4d3r +ned3s +ne4d^^f6 +ne2gr +ne5gres +4nek. +ne5ly +4nenl +ner5sm +nes3s4 +ne4sta +ne5s4ti +ne3tre +ne1ut +2nex +2n1f4 +nfalls5 +nfis3 +2ng1 +n4gar +n4gen. +n4gend +n4gens +n4genti +n4germ +n4get +n2gi +ng3ig +ngi4s +ng4ly +n2go +ng5om +ng3or +ng3rad +n4gr^^f6 +ng4ser +ngs1k +ngs3pa +ngs5tim +ngs3val +n4g^^f6d +2nh +1n2i +4nid +ni5ec +ni4ki +ni5li +3nin +nings1 +nings3k +nings5v +ni1o +4nip +nip4pr +ni5steri +nist3ra +ni3t4r +niv5sk +niv5st +2n1j +n4jar +n3jun +nju4s +n3j^^e4 +2nk +n4kart +n1ki +n4kis. +n3kny +n1ko +nkrafts5 +nk3ri +n1kro +nkrus4 +nk5sl +nk3sp +nk4tin +n1ku +n1k^^f6 +2n1l +2n1m +2n1n +nn3d +n3ne +nnis4 +nn3k +nn3s4t +1no +2nodl +no4kl +2nolj +2nomr +nom3s4 +2nord +2norg +no5sa +no5sc +no4tu +2n1p +2n1r +4ns +ns2i +n4sint +n4sis. +n4sise +ns2k +ns3kan +n1ski +ns3kor +nslags5 +ns5las +ns5mit +n4soc +n1spi +ns3pl +ns3po +ns3s4 +n3stans +n3stap +ns4tel +n3stif +ns3tig +ns4tra +n2strik +nst5up +nst5vil +n3s4ty +n1sva +ns3vi +ns3v^^e4r +2n1t +n4tark +nter5s4 +n4tinf +n2t5omb +nt3rad +n3trah +n3trak +n5trala +nt3rali +n5tram +nt3rep +n3trer +nt3ria +nt3rin +nt3ris +n4tropin +n4tror +n4tr^^f6 +nts3c +nt4se +nts5kor +nt4str +n4tut +n3tv^^e5 +nufts4 +4nug +n5ugn +3nui +3num +nums5 +2nup +n3upp +2nutb +2n1v +ny5gr +n5z +4n^^e5r +4n^^e4. +4n^^e4c +3n^^e4m +3n^^e4t +4n^^f6g4 +3n^^f6j +n^^f62ja +n^^f65kr +4n^^f6l +n^^f6s4 +n^^f6s5ke +o1a +o2ard +o2b +5o4bj +o4bli +oby4 +oc4k5r +ock3sk +oc3ku +o2d +ode4k +odi4a +1odli +o5dral +o3dro +ods4k +od2st +ods4ti +od5stu +o3d^^e4 +o1e +offs5t +o4fl +o3fr +of^^f6rm^^e54 +o1g +o4gav +og3gr +o4gj +o5glo +o5gly +ognos4 +ogno5st +o4gri +o4gr^^f6 +og3se +og4s3t +o4g^^e4 +o1i +o4il +o1j +o1k +o4kli +ok3n +ok3sl +ok4su +o2kv +o1la +o5lak +ol5au +olf^^f64 +1olj +ol3ka +olk3r +ol4ku +ol4k^^e4 +oll4si +oll5sl^^e4 +ol3l^^e4 +olm4s +oln3s +o1lo +olo5kv +ol4sa +ol4t^^e5 +o1lu +o4lug +o4lur +o1ly +ol5^^e5r +o1l^^e4 +om4br^^e4 +o3men +o4mord +om5pa +om3pl +1omr +4omra +om1sk +om4ste +3oms^^e4t +om4tr +om3tv +on3c +on5gi +on1gr +ongs4l +o4nins +on3j +on1k4 +ons3c +onsi3s +ons3m +on5stel +ons4ter +on3tras +on4tre +ont4s +o1ny +on5^^e5 +o1n^^e4 +o3n^^f6 +oo4d +oom5s +o3or +o1pe +o1pi +o5pline +op4pl +opp3le +op4pr +op4pu +o3pri +op4st +o3p^^e5 +o5q +4ora +o3rak +oran3g4 +o2rap +1ordn +or4d5^^e4 +o4reh +1orga +5organi +or4gr +or4g^^e5 +o1ri +3orient +4ork +or4m^^f6 +or4nu +or4n^^e4 +o1ro +or4pl +or5pr +or4spa +ors5tig +or5te +or2tr +ort3re +ort3ro +o1ru +o3ry +o1r^^e4 +o1r^^f6 +o3s2f^^e4 +osk4l +o1skop +o3som +os5pig +os4sk +os4s4t +os3tig +os5tiker +o5still +os4tr +ost5ron +ost5r^^f6 +os3tul +ota2lan +4oti. +4otie +4otin +o1to +o5tro +ot5run +ot3sv +ot5ti +ot4tr^^e4 +ott2s +o1tu +o5tun +otvin4 +o1ty +o5t^^e5 +o3t^^e4 +oun4 +oup4 +4our +ou3r^^f6 +ou4s +o3ut3t +o1va +ova4n +o1vi +ov3r +ov4si +ov3sl +ovs4me +o1v^^e4 +o3we +ox5 +oy2 +o3^^e5 +o3^^e4n +o3^^f6 +1pa +4paf +pag4 +paki3 +pakis4 +pa5la +pals5 +pa5l^^e4 +4pand. +pan4tr +3pap +2parb +4parm +par3s +2pask +pa5ski +pa2st +3patr +pa3u +2pb4 +2pc +2p3d4 +pek5tri +pekt3ro +4peld +pel3s4i +4pem +5peng +3penn +pent5r +per4bl +3perio +3pers +per4sl +pe5tro +4pex +2p1f +4p3g +2ph +pi4el +1pig +pi1o +3pip +pi5so +pi5sta +pi5sto +p2j +3pj^^e4s +4p3k2 +p2l +p4lac +5plan. +p4lane +p3larn +p3lev +3plex +3plic +1plik +4plit +p3lj +1plom +p3lop +2p1m +4p1n +p3ni +1po +5poa +2poc +2pof +po2i +3polit +4polj +poly3 +2porg +3pos +pos4ter +4pov +po4v^^e4 +2pp +p4part +pp5ask +p4pax +p3pe +p1pi +p4pins +pp3j +pp1l +pp3la +pp3lin +pp5lis +pp5lu +pp3ly +pp3l^^e5n +pp3l^^e5t +pp3l^^e4 +pp3l^^f6 +pp5oc +pp3of +pp3p4 +pp1r +pp3ra +pp3ri +pp3ru +pp3ry +pp3r^^e4 +pp3tr +p2pu +p5py +pp3^^e5 +p2r2 +2pra +5prax +1pres +pres4t +pre3sta +pres5to +p3rig +p3rik +5pril +3princ +pring3 +p5riol +3pro +pro3g +p3ror +4pr^^e5 +3pr^^e4s +3pr^^f6v +2ps +p2sal +3psalm +p5s2ho +ps4ken +ps2li +p3sna +4pso +p3sod +p1s4t +p4stak +p4st^^e4v +p2s^^f6 +2p1t +p3tri +1pu +4pug +pul2l5ov +pul5tr +5pung +3punk +pus3t +2p1v +p^^e53dr +3p^^e4l +p^^e45ro +4p^^f6r +3p^^e9 +qu4 +3que +1ra +3ra. +raci4t +3rade. +4radr +ra4du +5ra1e +2raff^^e4 +ra3fr +ra5is +2rak +ra2lo +r4ande +3rande. +4ran4d3r +rand3s +2ransv +ra3pl +3rar +r4ar. +4rarb +r4are +4rarg +r4ark +4rarm +r4arn +r4ars +4rart +r3arta +ra5r^^f6 +r4as +ras3h +ra2st +3raste. +3rativ +ra3tri +2rav +ra5yo +2rb +2r1c +2r2d +r4daf +rda5gr +r3dj +r4dos +rd3ran +rd3rat +r4dul +r3d^^e5 +r3d^^e4 +r4d^^f6s +1re +3re. +4reaus +re3b +4rec +5reco +re3d4r +re5du +4reft +4regg +3regn. +re1kr +rek5tri +4reld +re3lu +rem5p +3rems +r4en. +2reni +2renk +2renl +re3n^^f6 +re3o +3rer. +3rern +3reso +ress5k +re1sti +3ret. +4retet +ret3ro +4rety +re5t^^e5 +2revig +4rex +2r1f +rf^^f63ri +2r1g +rg3g2 +rgs5top +2rh +rhands5 +3rial +4rib +3rifi +2rifr +r3ifr^^e5 +3rifu +3rigt +rik2s +3riktn +ri4mo +2rind +rind3s +5ringen. +ring3r +2rinr +2rins +2rint +ri1o +3riot +ri5ple +ri2st^^e4 +ri4tut +ri4vis +riv3s +4rj +r4jis +r3jo +r5ju +r5j^^f6 +2rk +rk3akt +r4kek +rkes3 +r1ki +r3klas +rk2le +r4kl^^f6 +rk3n +rk4ne +r1ko +r4kod +rk3tr +r1ku +r4kup +r1k^^e4 +r5k^^f6r +2r1l +r5laka +r5lav +rld2 +rlds3 +rl5sp +2r1m +r4marb +r4mil +rm2s5j +rm5tr +2r1n +rnal4 +rn3g4 +rn1k +r2nom +rns4k +rns4t +rn3t +ro3b +ro4gro +ro2kr +2rolj +rol4li +rom4a +5roman +5ronau +5rond. +ron4v +ro3pl +ropp2s +ro4ra +2rord +2rorg +2rorie +3rorn +ro4sin +ro4sn +ros3v +ro5te +2r1p +r4pl^^f6 +r4p^^f6 +4r1r +rra4n +rrd4 +rreligi5 +rres4 +r5rib +rr5k4 +r4rob +r4rom +rr1s +rrs2k +r4rur +2rs +r4seld +r4sex +r2sin +r1ski +r4skid +rsk3na +rs5koll +rs4kos +rskotts3 +r2sku +r3sk^^f6 +rslags4v +r4sle +r4slo +r4s5l^^f6 +rs4mo +rs5nat +rs5n^^e4 +r1sp +r2spl +r2spo +rs3s4 +rs5tak +rs4te +r5stek +rs5tend +r5steni +rs5till +r1sto +r4ston +rst4r +r3str^^f6 +r3stu +r1sv +rs4vag +r2sv^^e4 +r1sy +2r1t +r2taf +r2takti +rt4an +r4tins +r4tom +r5trit +r3tr^^e4 +rt3t +r4tut +rubb5l +ru3br +ru4dan +ruks1 +ruks3v +5rullera +3rum. +runn2 +runns5 +4rupp +rus2h +ru5sha +2rut +5rutig +rut4ra +ru4vi +5ru^^f6 +2r1v +rv4sj +rv2s5k^^e4 +r3w +rydd5s +ry5o +r^^e5ge5l +4r^^e5l +r^^e5ng3s +r^^e55ra +r^^e53st +r^^e4ck5s +4r^^e4kt +4r^^e4m +r^^e4ng3s +r^^e4ns5t +4r^^e4s +r^^e44san +r^^e4s3s +r^^e45sti +r^^e4v5s +r^^f6d5el +r^^f6d5r +r^^f6d3s +2r^^f6g +r3^^f6i +r^^f6k3s +r^^f6ns4t +4r^^f6p +3r^^f6r +r^^f6r4s +r^^f64st +r^^f6st3r +r1^^f6vr +1sa +3sa. +3sad. +3sade +4sadj +2sa3dr +sad5s +2saf +sa3i +sak5ri +2s1akt +sa5lo +3s2am +sa2ma +samman3 +sa2mor +sand3s +4sang +2sanl +s3anl^^e4 +san3sla +2sap +3s4ar. +2sarb +2sarm +s5arm. +3sarn +2sart +4sarv +4sass +5sat. +sa4tu +2sau +s3auk +2s1av +4sb +s2c +2sch. +1scha +2schau +4schb +1schen +1scher +1schet +1schi +4schk +4schm +4schp +3schy +3sch^^f6 +sci3p +4s3d +1se +se4at. +se2g +2s3egg +3segl +seg3ra +sek5le +sek3r +sek5tr +3sel. +se5ly +sem2 +3sen. +s5ers^^e4 +3set. +2sexp +2s1f +s4f^^e4r. +sf^^f62 +4s3g2 +2sh +5s2haw +shi1s +s5h^^f6 +1si +sid5s +5sie +si4eri +si4esk +si2ett +3s2ig +3sik +sikts3 +5sill. +silver3 +silv3r +2s1ind +2s1inf +sinne2s3 +3sinni +4sinr +2sin1s +s1inst +5sint. +2sintr +3sio +sis4t +siu4 +1s2j +2sjak +s3jakt +4sjn +4sjt +s4ju +5sjuk +4sjur +sj^^e4ls3 +3sj^^f6 +4sk. +2ska. +3s2kada +s2kado +3skaffn +1skaft +s4kag +s2kal +3skal. +1skap +5skap. +5skapet +4skapi +skaps1 +4skar +s4kara +5skarv +4skas +s2kat +s4kav +4ske. +3sked. +s4kene +3skepp +4skh +sk4i +3skif +5skin +4skis. +5skiv +5skjor +3skju +4skl +sk5lap +s3klas +4skn +3s4ko. +1s4kog +4skogsg +1skol +3skola +s4kolo +s4korp +skor1st +1skot +s5kran. +3skrat +sk4ret +3skrev +1skri +3skrif +s3krig +5skrin +3skrip +s5kris +3skriv +s5kron +s4kru +5skrub +3skruv +5skr^^e4c +sk3s +2skt +3skulp +s3kup +2skv +s4kve +1s2ky +s4kyn +2skyrk +1sk^^e5 +s4k^^e5l +5sk^^e5p. +4sk^^e5r +5sk^^e4nk +3sk^^e4rv +2sl2 +4sla. +s5lad. +s3land +3s2lang +s4lant +s3lar. +4slas +s1lat +s2lev +3slev. +s4lic +slins3 +4slis +s2lit +s5lor +slotts3 +s2lu +s3luc +s3luf +4slus +s3lust +3slut +slu4to +3sl^^e5. +5s4l^^e5r +s4l^^e4k +s5l^^e4m +s5l^^e4nn +3s4l^^e4p +4s3l^^e4r +s2l^^e4t +3s2l^^f6j +2sm +s2mak +3smak. +s3makt +s2mal +s2met. +s2mid +s2mit +3smitta +s3mj +5smug +5smyg +sm^^e55g +sm^^e53k +sm^^e53s +3sm^^e4d +3sm^^e4l +4sm^^e4s +3sm^^f6r +2s2n4 +3snab +3s4nac +s3nam +s5nare +s3nast +s5ner +3snib +3snil +3snit +1snitt +s3niv +3snut +s4n^^e5 +5sn^^e5r +5sn^^e4c +s4n^^e4r +3sn^^f6. +sn^^f65g +3sn^^f6r +sn^^f63s +1so +3soc +5sock +2sod +5soi +2solj +sol3s2 +2som +5somm +3son +son4st +so5pra +so4pu +3sor. +2sord +s5ord. +2sorg +3sorn +3sot +4sott +s2p2 +5spann. +s4park +5sparv +4spas +s3pass +spa5tr +1spe +4sped +3s4pek +3s4pel +4spelsl +2spen +2sper +5spets +3spill +3spir +4spl +s1pla +s3plan +s3plats +spli4 +s4plin +5split +s5pl^^e4 +4spre +s3pres +4s3pris +3sprit +2spro +s3pry +3spr^^e5 +5spr^^e4n +s3ps +1s4p^^e5 +3sp^^e5n +3sp^^e5r +5sp^^e4n +3sp^^f6 +4s1r +4s1s +s5sad +sse4lin +s5sil +ss2k +ss5kl +ss3kun +ss1l +ss2lag. +ss2l^^e4 +ss2l^^f6 +ss3na +sss4 +ss3unn +s2sv +ss3vi +s2t +2st. +4sta. +5stac +3stadi +s4taf +5stalgis +3stalla +2stalli +5stam. +5stamm +1stant +5stark. +5startad +1state +3statl +1stau +st3c +2s5te. +4stea +5steg. +s4tek. +2stekn +5stekt +s4tell +3stem. +3steme +5stenar +3s4tene +3stense +5stensm +1stera +1stering +s4teriu +3sterne +5stetis +2stia +2stib +3stick +2stid +s4tiken +2stil +3stil. +3stink +3stisc +1stit +2stj +s5tju +3stj^^e4l +3stj^^e4r +2stm +5stoc +1stol +4stolk +4stom +stori4eu +5storis +stor3s +3straff +4strativ +3strato +3strec +3strej +st3ren +1strer +2stria +1strid +5stride +2striel +st4rif +1strikt +st5risk +1stru +3struk +2strumm +s3tryc +5stryk +5str^^e5k +3str^^e5l +3str^^e4c +4str^^e4d +3str^^e4ng +5str^^e4v +3str^^f6m +2st3s4 +st3t +4stv +s3tvis +1sty +2styp +1st^^e5 +4st^^e5g +5st^^e5l +1st^^e4 +3st^^e4l +1st^^f6 +1su +su4b +3sug +su3i +3sum +2sun +5sun. +s1under +5sune +s5ung +2sup +5supa +su2pu +5sus +2s1ut +su4to +su4tr +s2v2 +5svag. +s3vagn +4s3vak +5svam +4svap +svars3 +3svart +4svas +s3vat +4svec +3sven +5svep +4s3ver +s5ves +4s3vil +s4vine +4svis +s5vitt +s5v^^e5d +3sv^^e5ri +3sv^^e4ng +5sv^^e4rm. +s3v^^e4s +s3v^^e4t +4syk +5syl +3syn +syn3k +s3yrk +3sys +sys4t +sys5ter +syt2 +sy5th +1s^^e5 +5s^^e5g +4s^^e5k +2s^^e5lde +s^^e5ng3 +1s^^e4 +s4^^e4d +2s5^^e4gg +s4^^e4l +2s^^e4p +5s^^e4s +3s^^e4t +4s^^e4ta +1s^^f6 +4s^^f6d +2s^^f6g +s5^^f6ga +s^^f64ko +4s^^f6l +4s^^f6p +s^^f6r2s +2s3^^f6rt +1ta +3ta. +ta1ch +3tade. +4tadi +4tads5 +2taff +3taga +5tak. +ta5kre +2taktig +tak4to +4talf +5tallise +tall5s +4talv +3tame +3tami +3tan. +ta4nab +3tande. +2t3anfa +4tanl +t4ap3l +2tappar +3tar. +4tarb +tar4mi +3tarn +tars4 +4tart +5tartavl +4tarv +4task +3tast +ta1str +tat2 +ta4tan +tats3 +2tatt +2tav +4tave +5tavla. +3tavlan +3tavlo +tav2s +3tax +2tb4 +2tc +t3cha +t3che +2t3d4 +3t2e +te4as +te3b4 +5tec +4teg +te2g1r +te3gre +te3i +te4int +4tej +tej2s +te4kl +5teknik +5teknis +4teld +5te5l^^f6 +5tema +4temo +te4mu +ten3g4 +5tensi +ten3tr +te4n^^e4 +te5n^^f6r +5ter. +5teri^^f6 +ter3k4 +5term +5terna +5ters +ter3t +te4ru +5tes. +5test +tes4te +te5stik +te5stu +5tetik +tets3 +4texa +2texp +2t1f4 +2t3g4 +2th +t4hen +1ti +3tial +5tib +5tici +3tid +5tide +ti4du +4tid^^f6 +ti4ed +tifts5 +ti2gel +3tigh +ti4go +ti2gr +3tigt +tik3l +3tiks +5tikul +t2il +5tilj +3tillst +3tillv +3till^^e4 +5time +2tind +2tinr +2tint +ti4od +3tion +ti2os +3tis +4tisc +5tisk +3tiva +ti4van +5tivite +ti2^^f6 +t2j +4tje +4tjob +2tjou +4tj^^e4l +4tj^^e4m +3tj^^e4n +2t3k2 +2t3l +2t1m +2t5n4 +tne4r +4todl +3tok +4tol. +4tolj +2tomr +4toms +t2op +5torap +t5ord. +5toriett +4torm +torm3s +3torn +tor1st +4tort. +tos4k +t5ost. +t4ov +2t1p +t2r4 +2tra +t4raf +3trafi +3t4ral. +t4rala +3t4rale +5tralo +3trals +t4ralt +3trans +tran2s5a +4trar +t3ras. +t3rat. +t4rato +4treg +4tren +4trer. +4trern +t3rets. +2tri +3tribu +5trick +trids3 +t5riel +t1ring +t3ring. +2troc +t3rock +t4rog +t5ronik +t3rono +4tropi. +5tross +5trotn +t4rump +t4rup +3trupp +trus5ta +1tryc +5tryck. +5tryggh +4tr^^e5k +5tr^^e4. +3tr^^e4d +tr^^e4ds4 +3tr^^e4f +3tr^^e4g +4tr^^e4k +t3r^^e4kn +t4r^^e4n +5tr^^e4ni +5tr^^f6ja +t4r^^f6t +5tr^^e9 +2ts +t5s4and +ts5art +t3s4at +t3se +t4seg +ts4en +t4sex +ts2k +t5skall +t3skatt +t1ski +ts3kl +tskotts5 +t5slot +ts5l^^e4k +ts3n^^e4 +t3sn^^f6 +t2so +ts3ord +ts3pl +tss4 +t1st +ts4te +ts5ter +ts5tillf +ts3tj +t3stol +t4ston +t2stra +t4stry +t4stur +t5styr +t2su +t3sud +t5sy +2tt +t3tac +t4tau +t4ted +tte5g4 +t4tem +tte2n +ttes4 +t4tex +t4tins +t4tip +tt3ja +t1to +tt3rad +tt3rand +tt3rat +tt3re +tt3ri +tt4ry +tt4se +tt2si +tt4sta +t3tu +t4tug +tt1v +tt4v^^e5 +t3ty +t3t^^e4 +t3t^^f6r +4t5ugn +2tund +3tunga +tung3s +5tunn +2tupp +tu5re +2tutb +t3utv +t3ut^^f6 +tu4vu +5tu^^f6 +2tv +t1va +4tve +t3vig +3tving +t3vit +3tviv +t3v^^e5g +3tv^^e5n +t3v^^e4n +tv^^e4r3s +3tv^^e4tt +ty5da +5tyg. +3tyngd +3typ +ty3pi +5tys +2tz +3t^^e5g +t^^e5s4 +4t^^e5t +t^^e4c4ko +4t5^^e4g +4t^^e4m +4t^^e4rm +3t^^e4vl +4t^^f64d +t^^f65de +4t^^f6g +4t^^f6p +t^^f64pi +3t^^f6rer +t^^f6rs3t +t^^f64vas +5t^^e9 +u1a +u2b +ub5al +ubb4le +ub3lic +u4bo +u3cha +u5cl +u2d +u4dak +u5de +ud3r +ud4ret +uds4a +u4du +u4dy +u1e +u2es +uf4f^^e4 +uf4tan +uf4to +4u1ga +u1ge +ugg3s +ugn4 +ugns5 +ug3s4 +u5ie +u1in +u3is +u3itet +u3j +u2keb +u5ki +u4kl +uk5la +uk3n +u1ko +ukos4 +uk2s +uks5ko +uk3tris +ukt5s +uk4t^^e4 +u3ku +uk3v +u1la +ul4di +ulds2m +ul4du +ul4d^^f6 +ull3ste +ull3^^e4n +u1lo +uls5ti +ul2tr +u3lu +u1l^^e4 +u1l^^f6 +um4f^^e4 +um4so +ums4t +u1mu +u3m^^f6r +5underl +1unders^^f6 +1underv +un4dom +und3r +un4d^^e5 +un5g2ef +un3gersk +ung5it +ung3r +ungs4p +3unif +unk3l +unk3n +un4kr +un1sk +un4tr +un5trati +u5nu +u1o +u1pe +u4pern +u1pi +u2pl +u3plet +up3lik +3uppfa +1uppg +up4pin +1uppla +5uppl^^e4 +up4p3r +upp3s +upp5sp +up5ut +ur5ak +ur5arv +u3re +u1ri +u1ro +u4rob +u4rom +urs5tin +ur4st^^e4 +u5ry +u2sak +us5anl +u3scha +u3se +usen3 +u2s1k +us3ka +us4kla +us4kr +u5sky +us4k^^e5 +us5l^^e4 +us3n +u2sp +us3pen +us5tat +us3tig +u3stik +us5tin +ust5ro +u4st^^e5 +u4st^^e4 +us3v +u4s^^e5 +u4s^^e4 +u2s^^f6 +u4tak +1utb +u4tef +ute3s +utik2 +u5til +uti3^^f6 +ut3j +3utj^^e4m +utlands3 +u1to +u3top +uto5s +ut3r +ut4rer +ut4ro +ut5rop +1utru +2utsid +ut3sl +3utsl^^e4 +2utt +utt4j +ut1v +3utvec +u5ty +ut3^^f6v +u5u +2u1v +u2vak +u4vj +u4v^^e4 +u5^^e5 +u3^^f6 +va5dro +1vagn +2v1akti +val3k +val4li +val4st +5valv +5vama +4vand. +4vanp +van4st +van5tr +5vap +2varb +va4res +va4ri. +4vark +var2s +vart5r +va1ru +vas5ti +5vattn +4vau +4vav +5vavi +2vb4 +2v1c +2v3d4 +1ve +5vec +ve2k +ve3ke +4veld +vensk3^^e4 +5ventera +ve3ny +ve5n^^f6 +4vep +ver5g +3verk +ves4 +ve2s5p +ve1st +3veta +3vete +vet5sa +vett5s +2v1f +2v1g +2vh +v4i +vi4c +vid3s +vild3s +vil4t +3vind. +ving3s4 +3vinkl +vi2no +5vinst. +5vinste +vi5ny +3vis. +vi5sa +vis5h +vis5ko +vi4st +vis3ta +vi2tr +vi4var +4vjo +2v3k2 +2v1l +2v1m +vm^^f6rk4 +2v1n4 +1vo +4vok. +2vom +4vord +2vorg +vos4 +2v1p +2v2r +5vrak +3vrera +v3ru +2vs +v4sc +v1s2k +v2skri +vs4mi +v3sni +v2so +v1st +vs4te +vs5tr^^e5 +v5styc +vs3v^^e5 +v2s^^f6 +2v1t +vu4d1 +v1und +4v5up +4vut +2v1v +3vy +5v^^e5ld +v^^e5ngs3 +3v^^e5rd +4v^^e5ri +v^^e53ru +3v^^e4g +v^^e4gg5s +v^^e44l +v^^e4ll4s3 +3v^^e4nl +3v^^e4rde +v^^e44ril +4v^^e4rj +5v^^e4rk +3v^^e4rld +2v^^e4t +3v^^e4x +4v^^f6g +4v^^f6p +3v^^f6r +1wa +we2 +w2h +whi2 +wi2e +w4na +x1 +xan5d4 +xem3pla +xis4 +xk2 +xli4 +xs4 +xti2 +x4t^^e5 +2y +y1a +y4bris +yb4s +y2d +y4da +y5dan +y4do +yd3r +yds4 +y4du +y4d^^f6 +y1e +y1ga +y1ge +ygg3r +yg4g^^e5 +ygs4p +y1i +y1ki +y5klist +yk5lon +yk3n +y1ko +y1la +yl4gj +y3li +yl5k +yl5l^^e4 +y1lo +yl4tr +ym2fl +ym4for +y3m^^e5 +yng3r +ynk5l +yn4sa +yns4t +y3or +y5ou +y1pe +y5po +yp3ri +yre4s +y1ri +yr4ku +yrk5v +y1ro +yrs4k +yr5st +yr5tu +y1r^^e53 +y5scho +ys2st +ys3ta +ys3ti +ys4tik. +yst3ra +y2tak +y4te. +y4tea +y1to +ytt3r +yt5v +y3va +y3vi +y3v^^e4 +y5w +y5^^e5 +1za +1ze +ze4ro +1zi +1zo +zo4nal +4zp +z5s +3zu +z4zin +^^e51a +^^e53dj +^^e5ds4l +^^e51e +^^e51f +^^e51ga +^^e51ge +^^e5ge2l +^^e5g3l +^^e5g3s4k +^^e5g3st +^^e5g^^e54 +^^e53i +^^e51ki +5^^e5klag +^^e5k4str^^e4 +^^e51la +1^^e5lder +^^e52lin +^^e5l3k +^^e5ll4sp +^^e5l2s5e +^^e5l3st +^^e51l^^e4 +^^e51m +^^e5man4s +^^e5nd4r +^^e5n4du +^^e5ns4t +^^e5ns4v +^^e53o +^^e51p +^^e52pl +^^e55pla +^^e54p^^f6 +^^e5r4do +^^e5rd4ra +^^e5rd2s +^^e5rd4s3t +^^e54rel +^^e51ri +^^e55ror +5^^e5rsav +^^e5r5s2li +^^e5r2sv +^^e5r5^^f6 +^^e5s4ke +^^e5s3n +^^e5ss4 +^^e5s4skr +^^e5s4t +^^e5te2 +^^e5t3ri +^^e53tr^^e5 +^^e5t2sj +^^e5tt5s +^^e51v +^^e41a +^^e42b +2^^e4c +^^e4ck5v +^^e42d +^^e4dd3s +^^e4d4du +^^e4de4s +^^e4d3r +^^e4d5se +^^e4d3st +^^e43e +^^e41ga +^^e41ge +^^e4g4go +^^e4g1l +^^e4g3r +^^e4g4re +^^e4g3se +^^e43i +^^e45jo +4^^e4k +^^e41ki +^^e4k3n +^^e4k3r +^^e41la +^^e4l4pap +^^e4l4seg +^^e4ls5kog +^^e4l4slu +^^e4l2t3r +^^e4l2tu +^^e4l4vin +^^e4mp3l +4^^e4ndligh +^^e4nd3r +^^e4nd1st +^^e4ng5r +^^e4nni3s +^^e4nn3s +^^e44no +^^e4ns1l +^^e4n4st +^^e4ns5te +^^e4n4sv +^^e4n2t3r +^^e43pe +^^e4pp3l +^^e44pr +^^e4p4st +^^e44rap +^^e4r2bre +^^e4rg5l +^^e4r4gr +^^e41ri +^^e4rib4 +^^e4r4k^^e4 +^^e4r4nis +^^e4rn3st +^^e4r2n^^e5 +^^e4r4n^^f6 +^^e4r5ob +^^e45rol +^^e43rop +^^e45ror +^^e45ros +^^e4r2si +^^e4r4sko +^^e4r2so +^^e4r4sp +^^e4r2sv +^^e4r4tand +^^e4r2tr +^^e4rt3s +4^^e4s +^^e4s3pa +^^e4s5pi +^^e4s4sk +^^e4s4sp +^^e4s3ta +^^e4st3r +^^e44st^^e4 +^^e44s^^e5 +2^^e4t +^^e43to +^^e45tre +^^e4t4s3k +^^e4t5te +^^e4t4top +^^e4tt3r +^^e4t4tu +^^e4t4tv +^^e41va +^^e42vak +^^e43vi +^^e45vu +^^f61a +^^f62d +^^f64dak +^^f64dal +^^f64darv +^^f6de4s5 +^^f64dis +^^f6d3ra +^^f6d2s +^^f6d3se +^^f64du +^^f64d^^f6 +^^f61e +^^f61ga +^^f6g5ak +^^f65gar +1^^f6gd +^^f61ge +^^f65ger +^^f6gg4 +^^f6g1l +^^f6g2n +^^f6gn3e +1^^f6go +^^f6g3si +^^f6g3sk +^^f61i +^^f63jo +^^f6j4sv +^^f64karm +^^f61ki +^^f6k3n +^^f6k2s +^^f6k3sl +^^f61la +^^f6l4kv +^^f6l4k^^f6 +^^f6l2p +^^f65l^^e4 +^^f6man4 +^^f6m2kl +^^f64nal +^^f62nom +^^f6ns3ke +^^f6n4so +^^f6nst3r +^^f63pe +^^f64pel +^^f63pi +^^f6p5li +^^f65plo +1^^f6ppn +^^f64pr +^^f63rande +^^f63ras +^^f64rask +^^f6rb4 +^^f6r3d4r +^^f6r1eni +^^f63res +^^f64restr +^^f63ret +^^f6r5evig +^^f6r3g +^^f61ri +^^f65rig +^^f63ring +^^f6r3int +^^f6r5ir +^^f6r5iv +^^f6r4kal +^^f6r1k2l +^^f6r5kli +^^f6r4nis +^^f6r3ol +^^f6r1or +^^f6r2p5la +^^f6r1s2k +^^f6r3sl +^^f6r4sl^^e4 +^^f6r5te +^^f6rt5s +^^f6r1u +^^f6r3vr +^^f6r3y +^^f6r1^^e4 +^^f6r^^f64d +^^f62sak +^^f6s3n +^^f6s4sj +^^f6s2sk +^^f6s4sp +^^f6s3ta +^^f6st3v +^^f62tak +^^f6ts5ko +^^f6t4st +^^f61v +^^f6ve4 +^^f6ver1 +5^^f6vere +^^f62vj +^^f6v3ra +^^f6v3ri +^^f6v4sk +^^e93e +} +} + +% Local Variables: +% mode: tex +% fill-column: 72 +% End: +% vim: set filetype=tex textwidth=72: diff --git a/tmac/hyphenex.cs b/tmac/hyphenex.cs new file mode 100644 index 0000000..753359c --- /dev/null +++ b/tmac/hyphenex.cs @@ -0,0 +1,18 @@ +% List of exceptions created by Karel Horak +% (Mathamatical Institute of Czechoslovak Acadamy of Science) +% Prague, April 1, 1991 +% +\hyphenation{ + koe-fi-ci-ent + koe-fi-ci-en-ty + pro-jek-ční + úhlo-příč-ka + úhlo-příč-ky +} + +% Local Variables: +% mode: tex +% coding: latin-2 +% fill-column: 72 +% End: +% vim: set filetype=tex textwidth=72: diff --git a/tmac/hyphenex.en b/tmac/hyphenex.en new file mode 100644 index 0000000..768c0af --- /dev/null +++ b/tmac/hyphenex.en @@ -0,0 +1,115 @@ +% Hyphenation exceptions for US English, +% based on hyphenation exception log articles in TUGboat. +% +% Copyright 2008 TeX Users Group. +% You may freely use, modify and/or distribute this file. +% +% Stripped down by the GNU roff project to only include the patterns +% that hyphenate differently when using the hyph-utf8 project's +% hyph-en-us.tex file (version 2005-05-30). +% +% Please contact the TUGboat editorial staff +% for corrections and omissions. +% +\hyphenation{ + anti-deriv-a-tive + anti-deriv-a-tives + bathy-scaphe + co-designer + co-designers + electro-mechan-i-cal + electro-mechano-acoustic + fluoro-car-bon + free-loaders + grand-uncle + grand-uncles + griev-ances + ignore-spaces + im-ped-ances + input-enc + line-spacing + meta-stable + meta-table + meta-tables + micro-eco-nomic + micro-eco-nomics + micro-econ-omy + micro-en-ter-prise + micro-en-ter-prises + micro-organ-ism + micro-organ-isms + mid-after-noon + mine-sweepers + mono-spacing + nitro-meth-ane + non-euclid-ean + ortho-nitro-toluene + para-di-methyl-benzene + para-fluoro-toluene + phe-nol-phthalein + phtha-lam-ic + phthal-ate + phthi-sis + pre-proces-sor + pre-proces-sors + re-imple-ment + re-imple-ments + re-imple-mented + re-imple-men-ta-tion + ring-leaders + round-table + round-tables + single-space + single-spaced + single-spacing + sky-scrapers + sports-writers + sub-tables + super-deri-va-tion + super-deri-va-tions + super-ego + super-egos + waste-water + Bembo + Chiang + Cohen + Duane + Engle + Engel + Hibbs + Hoek-water + Huber + Image-Magick + Krishna + Krish-na-ism + Krish-nan + Le-gendre + Lucas + MacBeth + Nietz-sche + Noord-wijker-hout + Open-Office + Pres-by-terian + Pres-by-terians + Pyong-yang + Ra-dha-krish-nan + Ravi-kumar + Reich-lin + Schwert + Skoup + Thiruv-ananda-puram + Vieth + viiith + viith + xviiith + xviith + xxiiird + xxiind + Ying-yong Shu-xue Ji-suan +} +% Here's an erratum from the aforementioned hyph-en-us.tex. +\hyphenation{ + dem-o-crat +} + +% EOF diff --git a/tmac/hyphenex.pl b/tmac/hyphenex.pl new file mode 100644 index 0000000..aee5845 --- /dev/null +++ b/tmac/hyphenex.pl @@ -0,0 +1,91 @@ +#! /usr/bin/env perl +# +# +# hyphenex.pl +# +# This small filter converts a hyphenation exception log article for +# TUGBoat to a real \hyphenation block. +# +# Written by Werner Lemberg . +# +# Version 1.2 (2007/11/16) +# +# Public domain. +# +# +# Usage: +# +# [perl] hyphenex.pl < tugboat-article > hyphenation-exceptions + +# print header +print "% Hyphenation exceptions for US English,\n"; +print "% based on hyphenation exception log articles in TUGboat.\n"; +print "%\n"; +print "% Copyright 2007 TeX Users Group.\n"; +print "% You may freely use, modify and/or distribute this file.\n"; +print "%\n"; +print "% This is an automatically generated file. Do not edit!\n"; +print "%\n"; +print "% Please contact the TUGboat editorial staff \n"; +print "% for corrections and omissions.\n"; +print "\n"; +print "\\hyphenation{\n"; + +unshift @ARGV, '-' unless @ARGV; +foreach my $filename (@ARGV) { + my $input; + if ($filename eq '-') { + $input = \*STDIN; + } elsif (not open $input, '<', $filename) { + warn $!; + next; + } + while (<$input>) { + # retain only lines starting with \1 ... \6 or \tabalign + next if not (m/^\\[123456]/ || m/^\\tabalign/); + # remove final newline + chop; + # remove all TeX commands except \1 ... \6 + s/\\[^123456\s{]+//g; + # remove all paired { ... } + 1 while s/{(.*?)}/\1/g; + # skip lines which now have only whitespace before '&' + next if m/^\s*&/; + # remove comments + s/%.*//; + # remove trailing whitespace + s/\s*$//; + # remove trailing '*' (used as a marker in the document) + s/\*$//; + # split at whitespace + @field = split(' '); + if ($field[0] eq "\\1" || $field[0] eq "\\4") { + print " $field[2]\n"; + } + elsif ($field[0] eq "\\2" || $field[0] eq "\\5") { + print " $field[2]\n"; + # handle multiple suffixes separated by commata + @suffix_list = split(/,/, "$field[3]"); + foreach $suffix (@suffix_list) { + print " $field[2]$suffix\n"; + } + } + elsif ($field[0] eq "\\3" || $field[0] eq "\\6") { + # handle multiple suffixes separated by commata + @suffix_list = split(/,/, "$field[3],$field[4]"); + foreach $suffix (@suffix_list) { + print " $field[2]$suffix\n"; + } + } + else { + # for '&', split at '&' with trailing whitespace + @field = split(/&\s*/); + print " $field[1]\n"; + } + } +} + +# print trailer +print "}\n"; +print "\n"; +print "% EOF\n"; diff --git a/tmac/it.tmac b/tmac/it.tmac new file mode 100644 index 0000000..0cec529 --- /dev/null +++ b/tmac/it.tmac @@ -0,0 +1,194 @@ +.\" Italian localization for groff +.\" +.\" Copyright (C) 2021-2022 Free Software Foundation, Inc. +.\" Written by Edmond Orignac (edmond.orignac@wanadoo.fr) +.\" +.\" This file 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 +.\" . +.\" +.\" Please send comments/corrections to edmond.orignac@wanadoo.fr. +. +.do nr *groff_it_tmac_C \n[.cp] +.cp 0 +. +. +.\" If changing from an existing locale, we need to preserve the state +.\" of the "suppress hyphenation before a page location trap" bit. +.nr locale*use-trap-hyphenation-mode 0 +.if d locale \ +. if \n[.hy]=\n[\*[locale]*hyphenation-mode-trap] \ +. nr locale*use-trap-hyphenation-mode 1 +. +. +.ds locale italian\" +. +. +.\" Predefined text translations +. +.ds \*[locale]-abstract RIASSUNTO\" +.ds \*[locale]-app ALLEGATO\" +.ds \*[locale]-appendix_string Appendice\" +.ds \*[locale]-april Aprile\" +.ds \*[locale]-attribute_string da\" +.ds \*[locale]-august Agosto\" +.ds \*[locale]-chapter_string Capitolo\" +.ds \*[locale]-december Dicembre\" +.ds \*[locale]-draft_string Brutta Copia\" +.ds \*[locale]-endnote_string ANNOTAZIONI\" +.ds \*[locale]-february Febbraio\" +.ds \*[locale]-finis_string FINE\" +.ds \*[locale]-friday Venerd\[i `]\" +.ds \*[locale]-january Gennaio\" +.ds \*[locale]-july Luglio\" +.ds \*[locale]-june Giugno\" +.ds \*[locale]-le ELENCO DEI EQUAZIONI\" +.ds \*[locale]-letapp LETTO E APPROVATO\" +.ds \*[locale]-letat ALLA CORTESE ATTENZIONE DI:\" +.ds \*[locale]-letcn CONFIDENZIALE\" +.ds \*[locale]-letdate Data\" +.ds \*[locale]-letfc Accolga, signore, l'espressione dei miei sentimenti pi\[u `] distinti.\" +.ds \*[locale]-letns!0 Copia ad\" +.ds \*[locale]-letns!1 Esemplare (con destinatario) a\" +.ds \*[locale]-letns!10 Esemplare (con destinatarie) a\" +.ds \*[locale]-letns!11 Esemplare (sin destinatarie) a\" +.ds \*[locale]-letns!12 Riassunto ad\" +.ds \*[locale]-letns!13 Promemoria completa ad\" +.ds \*[locale]-letns!14 Cc:\" +.ds \*[locale]-letns!2 Esemplare (sin destinatario) a\" +.ds \*[locale]-letns!3 Destinatario\" +.ds \*[locale]-letns!4 Destinatarie\" +.ds \*[locale]-letns!5 Allegato\" +.ds \*[locale]-letns!6 Allegati\" +.ds \*[locale]-letns!7 In plico a parte\" +.ds \*[locale]-letns!8 Lettere ad\" +.ds \*[locale]-letns!9 Promemoria ad\" +.ds \*[locale]-letns!copy Copia \" (a space is needed)\" +.ds \*[locale]-letns!to ad\" +.ds \*[locale]-letrn In relazione a:\" +.ds \*[locale]-letsa A chiunque riguardate:\" +.ds \*[locale]-letsj Soggetto:\" +.ds \*[locale]-lf ELENCO DELLE FIGURE\" +.ds \*[locale]-licon SOMMARIO\" +.ds \*[locale]-liec Equatio\" +.ds \*[locale]-liex Documento\" +.ds \*[locale]-lifg Figura\" +.ds \*[locale]-litb Tabella\" +.ds \*[locale]-lt ELENCO DEI TABELLE\" +.ds \*[locale]-lx ELENCO DEI DOCUMENTI\" +.ds \*[locale]-man-section1 Manuale dei comandi generali\" +.ds \*[locale]-man-section2 Manuale delle chiamate di sistema\" +.ds \*[locale]-man-section3 Manuale delle funzioni di libreria\" +.ds \*[locale]-man-section4 Manuale delle interfacce del kernel\" +.ds \*[locale]-man-section5 Manuale dei formati di file\" +.ds \*[locale]-man-section6 Manuale dei giochi\" +.ds \*[locale]-man-section7 Manuale di informazioni varie\" +.ds \*[locale]-man-section8 Manuale del gestore di sistema\" +.ds \*[locale]-man-section9 Manuale dello sviluppatore del kernel\" +.ds \*[locale]-march Marzo\" +.ds \*[locale]-may Maggio\" +.ds \*[locale]-monday Luned\[i `]\" +.ds \*[locale]-november Novembre\" +.ds \*[locale]-october Ottobre\" +.ds \*[locale]-paper A4\" +.ds \*[locale]-qrf Cf. capitulo \\*[Qrfh], pagina \\*[Qrfp].\" +.ds \*[locale]-references Bibliografia\" +.ds \*[locale]-revision_string Revisione\" +.ds \*[locale]-rp BIBLIOGRAFIA\" +.ds \*[locale]-saturday Sabato\" +.ds \*[locale]-september Settembre\" +.ds \*[locale]-sunday Domenica\" +.ds \*[locale]-thursday Gioved\[i `]\" +.ds \*[locale]-toc Indice\" +.ds \*[locale]-toc_header_string Indice\" +.ds \*[locale]-tuesday Marted\[i `]\" +.ds \*[locale]-wednesday Mercoled\[i `]\" +. +. +.\" Activate the translations +. +.mso trans.tmac +. +. +.\" ms package +.if r GS \{\ +. \" update the date +. ds DY \n[dy] \*[MO] \n[year] +. \" set hyphenation flags +. nr HY 2 +.\} +. +. +.\" mm package +.if d PH \{\ +. \" update the date with the new strings +. ds cov*new-date \\n[dy] \\*[MO\\n[mo]] \\n[year] +. +. \" ISODATE and DT update +. de ISODATE +. nr cov*mm \\n[mo] +. nr cov*dd \\n[dy] +. af cov*mm 01 +. af cov*dd 01 +. ie '0'\\$1' \ +. ds cov*new-date \\n[dy] \\*[MO\\n[mo]] \\n[year] +. el \ +. ds cov*new-date \\n[year]-\\n[cov*mm]-\\n[cov*dd] +. . +. +. als DT cov*new-date +.\} +. +. +.ss 12 0 +. +.\" Set up hyphenation. +. +.\" Italian hyphenation (\lefthyphenmin=2, \righthyphenmin=2) +.nr \*[locale]*hyphenation-mode-base 1 +.nr \*[locale]*hyphenation-mode-trap 2 +. +.ie \n[locale*use-trap-hyphenation-mode] \ +. hy \n[\*[locale]*hyphenation-mode-trap] +.el \ +. hy \n[\*[locale]*hyphenation-mode-base] +. +.rr locale*use-trap-hyphenation-mode +. +.hla it +.hpf hyphen.it +. +. +.\" man package +.if d an \ +. an*reset-hyphenation-mode +. +. +.\" me package +.if d @R \{\ +. ds _td_format \En(dy \E*(mo \En(y4 +. ld +.\} +. +. +.cp \n[*groff_it_tmac_C] +.do rr *groff_it_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" coding: latin-1 +.\" fill-column: 72 +.\" End: +.\" vim: set fileencoding=iso-8859-1 filetype=groff textwidth=72: diff --git a/tmac/ja.tmac b/tmac/ja.tmac new file mode 100644 index 0000000..4b1db08 --- /dev/null +++ b/tmac/ja.tmac @@ -0,0 +1,62 @@ +.\" Japanese localization for groff +.\" +.\" Copyright (C) 2009-2020 Free Software Foundation, Inc. +.\" Written by Fumitoshi UKAI and +.\" Colin Watson +.\" +.\" This file 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 +.\" . +.\" +.\" Please send comments to groff@gnu.org. +. +.do nr *groff_ja_tmac_C \n[.cp] +.cp 0 +. +. +.ds locale japanese\" +. +. +.class [CJKprepunct] \ + , : ; > } \ + \[u3001] \[u3002] \[uFF0C] \[uFF0E] \[u30FB] \[uFF1A] \[uFF1B] \[uFF1F] \ + \[uFF01] \[uFF09] \[u3015] \[uFF3D] \[uFF5D] \[u300D] \[u300F] \[u3011] \ + \[u3041] \[u3043] \[u3045] \[u3047] \[u3049] \[u3063] \[u3083] \[u3085] \ + \[u3087] \[u30FC] \ + \[u30A1] \[u30A3] \[u30A5] \[u30A7] \[u30A9] \[u30C3] \[u30E3] \[u30E5] \ + \[u30E7] +.class [CJKpostpunct] \ + \[uFF08] \[u3014] \[uFF3B] \[uFF5B] \[u300C] \[u300E] \[u3010] +. +.\" Hiragana, Katakana, and Kanji glyphs. +.class [CJKnormal] \ + \[u3041]-\[u3096] \[u30A0]-\[u30FF] \[u4E00]-\[u9FFF] +. +.cflags 128 \C'[CJKprepunct]' +.cflags 266 \C'[CJKpostpunct]' +.cflags 512 \C'[CJKnormal]' +. +.\" Japanese hyphenation (disabled) +.nr \*[locale]*hyphenation-mode-base 0 +.nr \*[locale]*hyphenation-mode-trap 0 +. +.cp \n[*groff_ja_tmac_C] +.do rr *groff_ja_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/latin1.tmac b/tmac/latin1.tmac new file mode 100644 index 0000000..3dff03b --- /dev/null +++ b/tmac/latin1.tmac @@ -0,0 +1,114 @@ +.\" latin1.tmac +.\" +.do nr *groff_latin1_tmac_C \n[.cp] +.cp 0 +.\" 0xA0 +.\" char160 (no-break space) is translated on input +.trin \[char161]\[r!] +.trin \[char162]\[ct] +.trin \[char163]\[Po] +.trin \[char164]\[Cs] +.trin \[char165]\[Ye] +.trin \[char166]\[bb] +.trin \[char167]\[sc] +.trin \[char168]\[ad] +.trin \[char169]\[co] +.trin \[char170]\[Of] +.trin \[char171]\[Fo] +.trin \[char172]\[tno] +.\" char173 (soft hyphen) is translated on input +.trin \[char174]\[rg] +.trin \[char175]\[a-] +.\" 0xB0 +.trin \[char176]\[de] +.trin \[char177]\[t+-] +.trin \[char178]\[S2] +.trin \[char179]\[S3] +.trin \[char180]\[aa] +.trin \[char181]\[mc] +.trin \[char182]\[ps] +.trin \[char183]\[pc] +.trin \[char184]\[ac] +.trin \[char185]\[S1] +.trin \[char186]\[Om] +.trin \[char187]\[Fc] +.trin \[char188]\[14] +.trin \[char189]\[12] +.trin \[char190]\[34] +.trin \[char191]\[r?] +.\" 0xC0 +.trin \[char192]\[`A] +.trin \[char193]\['A] +.trin \[char194]\[^A] +.trin \[char195]\[~A] +.trin \[char196]\[:A] +.trin \[char197]\[oA] +.trin \[char198]\[AE] +.trin \[char199]\[,C] +.trin \[char200]\[`E] +.trin \[char201]\['E] +.trin \[char202]\[^E] +.trin \[char203]\[:E] +.trin \[char204]\[`I] +.trin \[char205]\['I] +.trin \[char206]\[^I] +.trin \[char207]\[:I] +.\" 0xD0 +.trin \[char208]\[-D] +.trin \[char209]\[~N] +.trin \[char210]\[`O] +.trin \[char211]\['O] +.trin \[char212]\[^O] +.trin \[char213]\[~O] +.trin \[char214]\[:O] +.trin \[char215]\[tmu] +.trin \[char216]\[/O] +.trin \[char217]\[`U] +.trin \[char218]\['U] +.trin \[char219]\[^U] +.trin \[char220]\[:U] +.trin \[char221]\['Y] +.trin \[char222]\[TP] +.trin \[char223]\[ss] +.\" 0xE0 +.trin \[char224]\[`a] +.trin \[char225]\['a] +.trin \[char226]\[^a] +.trin \[char227]\[~a] +.trin \[char228]\[:a] +.trin \[char229]\[oa] +.trin \[char230]\[ae] +.trin \[char231]\[,c] +.trin \[char232]\[`e] +.trin \[char233]\['e] +.trin \[char234]\[^e] +.trin \[char235]\[:e] +.trin \[char236]\[`i] +.trin \[char237]\['i] +.trin \[char238]\[^i] +.trin \[char239]\[:i] +.\" 0xF0 +.trin \[char240]\[Sd] +.trin \[char241]\[~n] +.trin \[char242]\[`o] +.trin \[char243]\['o] +.trin \[char244]\[^o] +.trin \[char245]\[~o] +.trin \[char246]\[:o] +.trin \[char247]\[tdi] +.trin \[char248]\[/o] +.trin \[char249]\[`u] +.trin \[char250]\['u] +.trin \[char251]\[^u] +.trin \[char252]\[:u] +.trin \[char253]\['y] +.trin \[char254]\[Tp] +.trin \[char255]\[:y] +.cp \n[*groff_latin1_tmac_C] +.do rr *groff_latin1_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/latin2.tmac b/tmac/latin2.tmac new file mode 100644 index 0000000..f73f4e8 --- /dev/null +++ b/tmac/latin2.tmac @@ -0,0 +1,242 @@ +.\" latin2.tmac +.\" +.do nr *groff_latin2_tmac_C \n[.cp] +.cp 0 +. +.if '\*[.T]'latin1' \{\ +.\" Replace characters that ISO Latin-1 has but Latin-2 doesn't. +.char \[r!] \ \" space +.char \[ct] \ \" space +.char \[Po] \ \" space +.char \[Ye] \ \" space +.char \[bb] \ \" space +.char \[co] \ \" space +.char \[Of] \ \" space +.char \[Fo] \ \" space +.char \[no] \ \" space +.char \[rg] \ \" space +.char \[a-] \ \" space +.char \[+-] \ \" space +.char \[S2] \ \" space +.char \[S3] \ \" space +.char \[mc] \ \" space +.char \[ps] \ \" space +.char \[pc] \ \" space +.char \[S1] \ \" space +.char \[Om] \ \" space +.char \[Fc] \ \" space +.char \[14] 1/4 +.char \[12] 1/2 +.char \[34] 3/4 +.char \[r?] \ \" space +.char \[`A] A +.char \[~A] A +.char \[oA] A +.char \[AE] AE +.char \[`E] E +.char \[^E] E +.char \[`I] I +.char \[:I] I +.char \[-D] \ \" space +.char \[~N] N +.char \[`O] O +.char \[~O] O +.char \[/O] O +.char \[`U] U +.char \[^U] U +.char \[TP] \ \" space +.char \[`a] a +.char \[~a] a +.char \[oa] A +.char \[ae] ae +.char \[`e] e +.char \[^e] e +.char \[`i] i +.char \[:i] i +.char \[Sd] \ \" space +.char \[~n] n +.char \[`o] o +.char \[~o] o +.char \[/o] o +.char \[`u] u +.char \[^u] u +.char \[tp] \ \" space +.char \[:y] y +.\" Map characters that ISO Latin-2 has and Latin-1 doesn't to their +.\" numeric code points. +.\" 0xA0 +.char \[A ho] \N'161' +.char \[ab] \N'162' +.char \[/L] \N'163' +.char \[L ah] \N'165' +.char \[S aa] \N'166' +.char \[vS] \N'169' +.char \[S ac] \N'170' +.char \[T ah] \N'171' +.char \[Z aa] \N'172' +.char \[vZ] \N'174' +.char \[Z a.] \N'175' +.\" 0xB0 +.char \[a ho] \N'177' +.char \[ho] \N'178' +.char \[/l] \N'179' +.char \[l ah] \N'181' +.char \[s aa] \N'182' +.char \[ah] \N'183' +.char \[vs] \N'185' +.char \[s ac] \N'186' +.char \[t ah] \N'187' +.char \[z aa] \N'188' +.char \[a"] \N'189' +.char \[vz] \N'190' +.char \[z a.] \N'191' +.\" 0xC0 +.char \[R aa] \N'192' +.char \[A ab] \N'195' +.char \[L aa] \N'197' +.char \[C aa] \N'198' +.char \[C ah] \N'200' +.char \[E ho] \N'202' +.char \[E ah] \N'204' +.char \[D ah] \N'207' +.\" 0xD0 +.char \[u0110] \N'208' +.char \[N aa] \N'209' +.char \[N ah] \N'210' +.char \[O a"] \N'213' +.char \[R ah] \N'216' +.char \[U ao] \N'217' +.char \[U a"] \N'219' +.char \[T ac] \N'222' +.\" 0xE0 +.char \[r aa] \N'224' +.char \[a ab] \N'227' +.char \[l aa] \N'229' +.char \[c aa] \N'230' +.char \[c ah] \N'232' +.char \[e ho] \N'234' +.char \[e ah] \N'236' +.char \[d ah] \N'239' +.\" OxF0 +.char \[u0111] \N'240' +.char \[n aa] \N'241' +.char \[n ah] \N'242' +.char \[o a"] \N'245' +.char \[r ah] \N'248' +.char \[u ao] \N'249' +.char \[u a"] \N'251' +.char \[t ac] \N'254' +.char \[a.] \N'255' +.\} \" using -Tlatin1 +. +.\" Translate eight-bit input characters. +.\" 0xA0 +.\" char160 (no-break space) is translated on input +.trin \[char161]\[A ho] +.trin \[char162]\[ab] +.trin \[char163]\[/L] +.trin \[char164]\[Cs] +.trin \[char165]\[L ah] +.trin \[char166]\[S aa] +.trin \[char167]\[sc] +.trin \[char168]\[ad] +.trin \[char169]\[vS] +.trin \[char170]\[S ac] +.trin \[char171]\[T ah] +.trin \[char172]\[Z aa] +.\" char173 (soft hyphen) is translated on input +.trin \[char174]\[vZ] +.trin \[char175]\[Z a.] +.\" 0xB0 +.trin \[char176]\[de] +.trin \[char177]\[a ho] +.trin \[char178]\[ho] +.trin \[char179]\[/l] +.trin \[char180]\[aa] +.trin \[char181]\[l ah] +.trin \[char182]\[s aa] +.trin \[char183]\[ah] +.trin \[char184]\[ac] +.trin \[char185]\[vs] +.trin \[char186]\[s ac] +.trin \[char187]\[t ah] +.trin \[char188]\[z aa] +.trin \[char189]\[a"] +.trin \[char190]\[vz] +.trin \[char191]\[z a.] +.\" C0 +.trin \[char192]\[R aa] +.trin \[char193]\['A] +.trin \[char194]\[^A] +.trin \[char195]\[A ab] +.trin \[char196]\[:A] +.trin \[char197]\[L aa] +.trin \[char198]\[C aa] +.trin \[char199]\[,C] +.trin \[char200]\[C ah] +.trin \[char201]\['E] +.trin \[char202]\[E ho] +.trin \[char203]\[:E] +.trin \[char204]\[E ah] +.trin \[char205]\['I] +.trin \[char206]\[^I] +.trin \[char207]\[D ah] +.\" 0xD0 +.trin \[char208]\[u0110] +.trin \[char209]\[N aa] +.trin \[char210]\[N ah] +.trin \[char211]\['O] +.trin \[char212]\[^O] +.trin \[char213]\[O a"] +.trin \[char214]\[:O] +.trin \[char215]\[tmu] +.trin \[char216]\[R ah] +.trin \[char217]\[U ao] +.trin \[char218]\['U] +.trin \[char219]\[U a"] +.trin \[char220]\[:U] +.trin \[char221]\['Y] +.trin \[char222]\[T ac] +.trin \[char223]\[ss] +.\" 0xE0 +.trin \[char224]\[r aa] +.trin \[char225]\['a] +.trin \[char226]\[^a] +.trin \[char227]\[a ab] +.trin \[char228]\[:a] +.trin \[char229]\[l aa] +.trin \[char230]\[c aa] +.trin \[char231]\[,c] +.trin \[char232]\[c ah] +.trin \[char233]\['e] +.trin \[char234]\[e ho] +.trin \[char235]\[:e] +.trin \[char236]\[e ah] +.trin \[char237]\['i] +.trin \[char238]\[^i] +.trin \[char239]\[d ah] +.\" 0xF0 +.trin \[char240]\[u0111] +.trin \[char241]\[n aa] +.trin \[char242]\[n ah] +.trin \[char243]\['o] +.trin \[char244]\[^o] +.trin \[char245]\[o a"] +.trin \[char246]\[:o] +.trin \[char247]\[tdi] +.trin \[char248]\[r ah] +.trin \[char249]\[u ao] +.trin \[char250]\['u] +.trin \[char251]\[u a"] +.trin \[char252]\[:u] +.trin \[char253]\['y] +.trin \[char254]\[t ac] +.trin \[char255]\[a.] +.cp \n[*groff_latin2_tmac_C] +.do rr *groff_latin2_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/latin5.tmac b/tmac/latin5.tmac new file mode 100644 index 0000000..63a4871 --- /dev/null +++ b/tmac/latin5.tmac @@ -0,0 +1,134 @@ +.\" latin5.tmac +.\" +.do nr *groff_latin5_tmac_C \n[.cp] +.cp 0 +. +.if '\*[.T]'latin1' \{\ +.\" Replace characters that ISO Latin-1 has but Latin-5 doesn't. +.char \[-D] \ \" space +.char \[Sd] \ \" space +.char \[TP] \ \" space +.char \[Tp] \ \" space +.char \['Y] Y +.char \['y] y +.\" Map characters that ISO Latin-5 has and Latin-1 doesn't to their +.\" numeric code points. +.char \[G ab] \N'208' +.char \[g ab] \N'240' +.char \[u0130] \N'221' +.char \[.i] \N'253' +.char \[S ac] \N'222' +.char \[s ac] \N'254' +.\} \" using -Tlatin1 +. +.\" Translate eight-bit input characters. +.\" 0xA0 +.\" char160 (no-break space) is translated on input +.trin \[char161]\[r!] +.trin \[char162]\[ct] +.trin \[char163]\[Po] +.trin \[char164]\[Cs] +.trin \[char165]\[Ye] +.trin \[char166]\[bb] +.trin \[char167]\[sc] +.trin \[char168]\[ad] +.trin \[char169]\[co] +.trin \[char170]\[Of] +.trin \[char171]\[Fo] +.trin \[char172]\[tno] +.\" char173 (soft hyphen) is translated on input +.trin \[char174]\[rg] +.trin \[char175]\[a-] +.\" 0xB0 +.trin \[char176]\[de] +.trin \[char177]\[t+-] +.trin \[char178]\[S2] +.trin \[char179]\[S3] +.trin \[char180]\[aa] +.trin \[char181]\[mc] +.trin \[char182]\[ps] +.trin \[char183]\[pc] +.trin \[char184]\[ac] +.trin \[char185]\[S1] +.trin \[char186]\[Om] +.trin \[char187]\[Fc] +.trin \[char188]\[14] +.trin \[char189]\[12] +.trin \[char190]\[34] +.trin \[char191]\[r?] +.\" 0xC0 +.trin \[char192]\[`A] +.trin \[char193]\['A] +.trin \[char194]\[^A] +.trin \[char195]\[~A] +.trin \[char196]\[:A] +.trin \[char197]\[oA] +.trin \[char198]\[AE] +.trin \[char199]\[,C] +.trin \[char200]\[`E] +.trin \[char201]\['E] +.trin \[char202]\[^E] +.trin \[char203]\[:E] +.trin \[char204]\[`I] +.trin \[char205]\['I] +.trin \[char206]\[^I] +.trin \[char207]\[:I] +.\" 0xD0 +.trin \[char208]\[G ab] +.trin \[char209]\[~N] +.trin \[char210]\[`O] +.trin \[char211]\['O] +.trin \[char212]\[^O] +.trin \[char213]\[~O] +.trin \[char214]\[:O] +.trin \[char215]\[tmu] +.trin \[char216]\[/O] +.trin \[char217]\[`U] +.trin \[char218]\['U] +.trin \[char219]\[^U] +.trin \[char220]\[:U] +.trin \[char221]\[I .] +.trin \[char222]\[S ,] +.trin \[char223]\[ss] +.\" 0xE0 +.trin \[char224]\[`a] +.trin \[char225]\['a] +.trin \[char226]\[^a] +.trin \[char227]\[~a] +.trin \[char228]\[:a] +.trin \[char229]\[oa] +.trin \[char230]\[ae] +.trin \[char231]\[,c] +.trin \[char232]\[`e] +.trin \[char233]\['e] +.trin \[char234]\[^e] +.trin \[char235]\[:e] +.trin \[char236]\[`i] +.trin \[char237]\['i] +.trin \[char238]\[^i] +.trin \[char239]\[:i] +.\" 0xF0 +.trin \[char240]\[g ab] +.trin \[char241]\[~n] +.trin \[char242]\[`o] +.trin \[char243]\['o] +.trin \[char244]\[^o] +.trin \[char245]\[~o] +.trin \[char246]\[:o] +.trin \[char247]\[tdi] +.trin \[char248]\[/o] +.trin \[char249]\[`u] +.trin \[char250]\['u] +.trin \[char251]\[^u] +.trin \[char252]\[:u] +.trin \[char253]\[.i] +.trin \[char254]\[s ,] +.trin \[char255]\[:y] +.cp \n[*groff_latin5_tmac_C] +.do rr *groff_latin5_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/latin9.tmac b/tmac/latin9.tmac new file mode 100644 index 0000000..1bedd45 --- /dev/null +++ b/tmac/latin9.tmac @@ -0,0 +1,138 @@ +.\" latin9.tmac +.\" +.do nr *groff_latin9_tmac_C \n[.cp] +.cp 0 +. +.if '\*[.T]'latin1' \{\ +.\" Replace characters that ISO Latin-1 has but Latin-9 doesn't. +.char \[Cs] \ \" space +.char \[bb] \ \" space +.char \[ad] \ \" space +.char \[aa] \ \" space +.char \[ac] \ \" space +.char \[12] 1/2 +.char \[14] 1/4 +.char \[34] 3/4 +.\" Map characters that ISO Latin-9 has and Latin-1 doesn't to their +.\" numeric code points. +.char \[Eu] \N'164' +.char \[vS] \N'166' +.char \[vs] \N'168' +.char \[vZ] \N'180' +.char \[vz] \N'184' +.char \[OE] \N'188' +.char \[oe] \N'189' +.char \[:Y] \N'190' +.\} \" using -Tlatin1 +. +.\" Translate eight-bit input characters. +.\" 0xA0 +.\" char160 (no-break space) is translated on input +.trin \[char161]\[r!] +.trin \[char162]\[ct] +.trin \[char163]\[Po] +.trin \[char164]\[Eu] +.trin \[char165]\[Ye] +.trin \[char166]\[vS] +.trin \[char167]\[sc] +.trin \[char168]\[vs] +.trin \[char169]\[co] +.trin \[char170]\[Of] +.trin \[char171]\[Fo] +.trin \[char172]\[tno] +.\" char173 (soft hyphen) is translated on input +.trin \[char174]\[rg] +.trin \[char175]\[a-] +.\" 0xB0 +.trin \[char176]\[de] +.trin \[char177]\[t+-] +.trin \[char178]\[S2] +.trin \[char179]\[S3] +.trin \[char180]\[vZ] +.trin \[char181]\[mc] +.trin \[char182]\[ps] +.trin \[char183]\[pc] +.trin \[char184]\[vz] +.trin \[char185]\[S1] +.trin \[char186]\[Om] +.trin \[char187]\[Fc] +.trin \[char188]\[OE] +.trin \[char189]\[oe] +.trin \[char190]\[:Y] +.trin \[char191]\[r?] +.\" 0xC0 +.trin \[char192]\[`A] +.trin \[char193]\['A] +.trin \[char194]\[^A] +.trin \[char195]\[~A] +.trin \[char196]\[:A] +.trin \[char197]\[oA] +.trin \[char198]\[AE] +.trin \[char199]\[,C] +.trin \[char200]\[`E] +.trin \[char201]\['E] +.trin \[char202]\[^E] +.trin \[char203]\[:E] +.trin \[char204]\[`I] +.trin \[char205]\['I] +.trin \[char206]\[^I] +.trin \[char207]\[:I] +.\" 0xD0 +.trin \[char208]\[-D] +.trin \[char209]\[~N] +.trin \[char210]\[`O] +.trin \[char211]\['O] +.trin \[char212]\[^O] +.trin \[char213]\[~O] +.trin \[char214]\[:O] +.trin \[char215]\[tmu] +.trin \[char216]\[/O] +.trin \[char217]\[`U] +.trin \[char218]\['U] +.trin \[char219]\[^U] +.trin \[char220]\[:U] +.trin \[char221]\['Y] +.trin \[char222]\[TP] +.trin \[char223]\[ss] +.\" 0xE0 +.trin \[char224]\[`a] +.trin \[char225]\['a] +.trin \[char226]\[^a] +.trin \[char227]\[~a] +.trin \[char228]\[:a] +.trin \[char229]\[oa] +.trin \[char230]\[ae] +.trin \[char231]\[,c] +.trin \[char232]\[`e] +.trin \[char233]\['e] +.trin \[char234]\[^e] +.trin \[char235]\[:e] +.trin \[char236]\[`i] +.trin \[char237]\['i] +.trin \[char238]\[^i] +.trin \[char239]\[:i] +.\" 0xF0 +.trin \[char240]\[Sd] +.trin \[char241]\[~n] +.trin \[char242]\[`o] +.trin \[char243]\['o] +.trin \[char244]\[^o] +.trin \[char245]\[~o] +.trin \[char246]\[:o] +.trin \[char247]\[tdi] +.trin \[char248]\[/o] +.trin \[char249]\[`u] +.trin \[char250]\['u] +.trin \[char251]\[^u] +.trin \[char252]\[:u] +.trin \[char253]\['y] +.trin \[char254]\[Tp] +.trin \[char255]\[:y] +.cp \n[*groff_latin9_tmac_C] +.do rr *groff_latin9_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/lbp.tmac b/tmac/lbp.tmac new file mode 100644 index 0000000..ad913a7 --- /dev/null +++ b/tmac/lbp.tmac @@ -0,0 +1,103 @@ +.\" -*- nroff -*- +.\" +.\" lbp.tmac +.\" +.do nr *groff_lbp_tmac_C \n[.cp] +.cp 0 +. +.ftr CW CR +.ftr C CR +.ftr CO CI +.ftr H HR +.ftr HO HI +.ftr HX HBI +.ftr Hr HNR +.ftr Hi HNI +.ftr Hb HNB +.ftr Hx HNBI +.ftr EBI EI +.ftr CBI CI +. +.fchar \[fi] fi +.fchar \[fl] fl +.fchar \[ff] ff +.fchar \[Fi] f\[fi] +.fchar \[Fl] f\[fl] +.fchar \[OE] OE +.fchar \[oe] oe +.fchar \[IJ] IJ +.fchar \[ij] ij +.fchar \[.i] i +.fchar \[lq] `` +.fchar \[rq] '' +.fchar \[fo] \v'-.1m'\s-3<\s+3\v'+.1m' +.fchar \[fc] \v'-.1m'\s-3>\s+3\v'+.1m' +.fchar \[em] \v'-.25m'\h'.05m'\D'l .9m 0' +. +.char \[or] \h'.1m'\Z'\D'l 0 -.675m''\h'.1m' +. +.\" This is designed so that \[ul], \[rn], and \[br] form corners. +.char \[br] \Z'\v'.25m'\D'R .04m -1m'' +.char \[rn] \Z'\v'-.77m'\D'R .54m .04m''\h'.5m' +.char \[ul] \Z'\v'.23m'\D'R .54m .04m''\h'.5m' +. +.char \[ru] \Z'\v'-.02m'\D'R .54m .04m''\h'.5m' +. +.fchar \[|=] \v'.075m'\Z'\[mi]'\v'-.15m'\[ap]\v'.075m' +. +.de lbp-achar +. \" Note that character definitions are always interpreted with +. \" compatibility mode off. +. fchar \\$1 \ +\\$3\ +\k[acc]\ +\h'(u;-\w'\\$2'-\w'\\$3'/2+\\En[skw]+(\w'x'*0)-\\En[skw])'\ +\v'(u;\w'x'*0+\\En[rst]+(\w'\\$3'*0)-\\En[rst])'\ +\\$2\ +\v'(u;\w'x'*0-\\En[rst]+(\w'\\$3'*0)+\\En[rst])'\ +\h'|\\En[acc]u' +. hcode \\$1\\$4 +.. +. +.lbp-achar \['A] \' A a +.lbp-achar \[`A] \` A a +.lbp-achar \[^A] ^ A a +.lbp-achar \['C] \' C c +.lbp-achar \['c] \' c c +.lbp-achar \[`E] \` E e +.lbp-achar \[:E] \[ad] E e +.lbp-achar \[^E] ^ E e +.lbp-achar "\[G ab]" \[ab] G g +.lbp-achar "\[g ab]" \[ab] g g +.lbp-achar \['I] \' I i +.lbp-achar \[`I] \` I i +.lbp-achar \[:I] \[ad] I i +.lbp-achar \[^I] ^ I i +.lbp-achar "\[I .]" \[a.] I i +.lbp-achar \['O] \' O o +.lbp-achar \[`O] \` O o +.lbp-achar \[^O] ^ O o +.lbp-achar \[~O] ~ O o +.lbp-achar \[~o] ~ o o +.lbp-achar \['U] \' U u +.lbp-achar \[`U] \` U u +.lbp-achar \[^U] ^ U u +.lbp-achar \['Y] \' Y y +.lbp-achar \['y] \' y y +.lbp-achar \[:Y] \[ad] Y y +. +.fchar \[S ,] \o'S\[ac]' +.hcode \[S ,]s +.fchar \[s ,] \o's\[ac]' +.hcode \[s ,]s +. +.mso latin1.tmac +. +.cp \n[*groff_lbp_tmac_C] +.do rr *groff_lbp_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/lj4.tmac b/tmac/lj4.tmac new file mode 100644 index 0000000..60c8c1a --- /dev/null +++ b/tmac/lj4.tmac @@ -0,0 +1,41 @@ +.\" -*- nroff -*- +.\" +.\" lj4.tmac +.\" +.do nr *groff_lj4_tmac_C \n[.cp] +.cp 0 +. +.ftr CW CR +.ftr C CR +.ftr CX CBI +.ftr H UR +.ftr HR UR +.ftr HB UB +.ftr HBI UBI +.ftr HI UI +.ftr HO UI +.ftr HX UBI +. +.char \[or] \h'.1m'\Z'\D'l 0 -.675m''\h'.1m' +. +.\" This is designed so that \[ul], \[rn], and \[br] form corners. +.char \[br] \Z'\v'.25m'\D'R .04m -1m'' +.char \[rn] \Z'\v'-.77m'\D'R .54m .04m''\h'.5m' +.char \[ul] \Z'\v'.23m'\D'R .54m .04m''\h'.5m' +. +.char \[ru] \Z'\v'-.02m'\D'R .54m .04m''\h'.5m' +. +.fchar \[OK] \s[\En[.s]*6u/10u]\[rs]\s[0]/ +. +.fchar \[sqrtex] \[radicalex] +. +.mso latin1.tmac +. +.cp \n[*groff_lj4_tmac_C] +.do rr *groff_lj4_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/man.local b/tmac/man.local new file mode 100644 index 0000000..5daa507 --- /dev/null +++ b/tmac/man.local @@ -0,0 +1,31 @@ +.\" This file is loaded by an.tmac. +.\" +.\" Put local modifications to groff_man(7)'s behavior here. +.\" +.\" Change "0" to "1" to enable OSC 8 links on SGR-capable grotty(1) +.\" output devices. +.if !'\*[.T]'html' \ +. if !r U \ +. nr U 0 +.\" +.\" "CW" is not a portable font name, but some man pages use it anyway. +.\" Uncomment this to suppress warnings produced by such pages. This +.\" test remaps the font to roman ("R") on nroff (terminal) devices. You +.\" might prefer to remap it to bold ("B") instead. +.\" .if n .ftr CW R +.\" +.\" A de facto standard URL format for man pages is recognized +.\" everywhere except Apple, where different macOS applications expect +.\" different formats. +.\" 1: man:groff(1) -- package default +.\" 2: x-man-page://1/groff -- macOS/Mac OS X since 10.3 (Panther) +.\" 3: man:groff.1 -- Bwana (Mac OS X) +.\" 4: x-man-doc://1/groff -- ManOpen (Mac OS X pre-2005) +.\" Set this register to configure which the `MR` macro uses. +.\" .nr an*MR-URL-format 1 +.\" +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/man.tmac b/tmac/man.tmac new file mode 100644 index 0000000..b017e5a --- /dev/null +++ b/tmac/man.tmac @@ -0,0 +1,5 @@ +.\" -*- nroff -*- +.\" +.\" man.tmac +.\" +.do mso an.tmac diff --git a/tmac/man.ultrix b/tmac/man.ultrix new file mode 100644 index 0000000..2af9789 --- /dev/null +++ b/tmac/man.ultrix @@ -0,0 +1,105 @@ +.\" -*- nroff -*- +.\" +.\" Install this as man.local if you're using Ultrix. +.\" Ultrix specific additions to groff -man macros. +.\" Written by James Clark from a specification by Martyn.Johnson@cl.cam.ac.uk. +.\" +.\" I1 and I2 are unimplemented. +.de CT + +.. +.de CW +.ft CR +.. +.de Ds +.br +.nf +.ft R +.. +.de De +.ce 0 +.fi +.. +.de EX +.br +.if \\n[.$] .in +(n;\\$1) +.ft CR +.nf +.. +.de EE +.fi +.ft R +.in \\n[an-margin]u +.. +.de G +.it 1 an-trap +.ft H +.if \\n[.$] \&\\$* +.. +.de GL +.it 1 an-trap +.ft HI +.if \\n[.$] \&\\$* +.. +.if n .ig +.de HB +.ie \\n[.$] .ft HB +.el \f[HB]\\$*\fP +.. +.if t .ig +.de HB +.ie \\n[.$] .ul 999 +.el .ul +\\$* +.. +.als TB HB +.de MS +\&\f[CR]\\$1\fR(\\$2)\\$3 +.. +.de NT +.br +.ds an-note Note +.ce 1 +.if \\n[.$] \{\ +. ie '\\$1'C' \{\ +. ce 99 +. if \\n[.$]>1 .ds an-note \\$2 +. \} +. el \{\ +. ds an-note \\$1 +. if '\\$2'C' .ce 99 +. \} +.\} +.in \\n[an-margin]u+5n +.ll \\n[LL]u-5n +.sp .5v>?\n[.V]u +\&\\*[an-note] +.sp .5v>?\n[.V]u +. +.. +.de NE +.ll \\n[LL]u +.in \\n[an-margin]u +.ce 0 +.sp .5v>?\n[.V]u +.. +.de PN +\&\f[CR]\\$1\fP\\$2 +.. +.de Pn +.ie \\n(.$>1 \&\\$1\f[CR]\\$2\fP\\$3 +.el \&\f[CR]\\$1\fP\\$2 +.. +.de R +.ft R +.ul 0 +.. +.de RN + +.. +.de VS +.if '\\$1'4' .mc \[br] +.. +.de VE +.mc +.. diff --git a/tmac/mandoc.tmac b/tmac/mandoc.tmac new file mode 100644 index 0000000..e0a1502 --- /dev/null +++ b/tmac/mandoc.tmac @@ -0,0 +1,5 @@ +.\" -*- nroff -*- +.\" +.\" mandoc.tmac +.\" +.do mso andoc.tmac diff --git a/tmac/mdoc.local b/tmac/mdoc.local new file mode 100644 index 0000000..94688ab --- /dev/null +++ b/tmac/mdoc.local @@ -0,0 +1,15 @@ +.\" This file is loaded by mdoc.tmac. +.\" +.\" Put local modifications to groff_mdoc(7)'s behavior here. +.\" +.\" "CW" is not a portable font name, but some man pages use it anyway. +.\" Uncomment this to suppress warnings produced by such pages. This +.\" test remaps the font to roman ("R") on nroff (terminal) devices. You +.\" might prefer to remap it to bold ("B") instead. +.\" .if n .ftr CW R +.\" +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/mdoc.tmac b/tmac/mdoc.tmac new file mode 100644 index 0000000..2f18a0d --- /dev/null +++ b/tmac/mdoc.tmac @@ -0,0 +1,5 @@ +.\" -*- nroff -*- +.\" +.\" mdoc.tmac +.\" +.do mso doc.tmac diff --git a/tmac/mdoc/doc-common b/tmac/mdoc/doc-common new file mode 100644 index 0000000..53a2565 --- /dev/null +++ b/tmac/mdoc/doc-common @@ -0,0 +1,1729 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" 3. [Deleted. See +.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] +.\" 4. Neither the name of the University nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" +.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +.\" PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR +.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)doc-common 8.1 (Berkeley) 06/08/93 +. +. +.\" Macro Identifiers. For each user macro a corresponding register +.\" with the same name must exist. Its value must not be zero. +. +.nr %A 1 +.nr %B 1 +.nr %C 1 +.nr %D 1 +.nr %I 1 +.nr %J 1 +.nr %N 1 +.nr %O 1 +.nr %P 1 +.nr %Q 1 +.nr %R 1 +.nr %T 1 +.nr %U 1 +.nr %V 1 +.nr Ac 3 +.nr Ad 12n +.nr An 12n +.nr Ao 12n +.nr Ap 2 +.nr Aq 12n +.nr Ar 12n +.nr At 1 +.nr Bc 3 +.nr Bf 8n\" ? +.nr Bk 8n\" ? +.nr Bl 1 +.nr Bo 12n +.nr Bq 12n +.nr Brc 3 +.nr Bro 12n +.nr Brq 12n +.nr Bsx 1 +.nr Bt 8n\" ? +.nr Bx 1 +.nr Cd 12n +.nr Cm 10n +.nr D1 8n\" ? +.nr Dc 3 +.nr Dl 8n\" ? +.nr Dt 8n\" ? +.nr Do 12n +.nr Dq 12n +.nr Ds 6n\" many manpages still use this as a -width value +.nr Dv 12n +.nr Dx 1 +.nr Ec 3 +.nr Ef 8n\" ? +.nr Ek 8n\" ? +.nr El 1 +.nr Em 10n +.nr En 12n +.nr Eo 12n +.nr Eq 12n +.nr Er 17n +.nr Es 12n +.nr Ev 15n +.nr Ex 1 +.nr Fa 12n +.nr Fc 3 +.nr Fd 12n\" ? +.nr Fl 10n +.nr Fn 16n +.nr Fo 16n +.nr Fr 12n\" ? +.nr Ft 8n\" ? +.nr Fx 1 +.nr Ic 10n +.nr In 12n +.nr It 8n\" ? +.nr Lb 11n +.nr Li 16n +.nr Lk 6n\" ? +.nr Lp 8n\" ? +.nr Me 6n +.nr Ms 6n +.nr Mt 6n\" ? +.nr Nd 8n\" ? +.nr Nm 10n +.nr No 12n +.nr Ns 2 +.nr Nx 1 +.nr Oc 3 +.nr Oo 10n +.nr Op 14n +.nr Os 6n\" ? +.nr Ox 1 +.nr Pa 32n +.nr Pc 3 +.nr Pf 12n +.nr Po 12n +.nr Pp 8n\" ? +.nr Pq 12n +.nr Qc 3 +.nr Ql 16n +.nr Qo 12n +.nr Qq 12n +.nr Rv 1 +.nr Sc 3 +.nr Sh 8n +.nr Sm 8n\" ? +.nr So 12n +.nr Sq 12n +.nr Ss 8n +.nr St 8n\" ? +.nr Sx 16n +.nr Sy 6n +.nr Ta 2 +.nr Tn 10n +.nr Ud 8n\" ? +.nr Ux 1 +.nr Va 12n +.nr Vt 8n\" ? +.nr Xc 3 +.nr Xo 1 +.nr Xr 10n +. +. +.\" macros which must be processed after the closing delimiter of 'Op' +.\" and friends +.ds doc-after-Ao +.ds doc-after-Bo +.ds doc-after-Bro +.ds doc-after-Do +.ds doc-after-Eo +.ds doc-after-Fo +.ds doc-after-Ns +.ds doc-after-Oo +.ds doc-after-Po +.ds doc-after-Qo +.ds doc-after-So +.ds doc-after-Xo +. +. +.nr doc-display-indent 6n +. +. +.\" space strings +. +.ds doc-soft-space " \" +.ds doc-hard-space \~ +.ds doc-tab \t +. +. +.\" punctuation values (suffix=3, prefix=4) +. +.nr doc-punct. 3 +.nr doc-punct, 3 +.nr doc-punct: 3 +.nr doc-punct; 3 +.nr doc-punct( 4 +.nr doc-punct) 3 +.nr doc-punct[ 4 +.nr doc-punct] 3 +.nr doc-punct? 3 +.nr doc-punct! 3 +. +. +.\" Define alternate requests to handle continuous rendering. +.\" +.\" This .ne replacement avoids page breaks; instead, the page length is +.\" increased to the necessary amount (this is needed for tables). +. +.eo +.de doc-ne +. ie \n[.$] .nr doc-amount (v;\$*) +. el .nr doc-amount 1v +. if (\n[doc-amount] >= \n[.t]) \ +. pl +(\n[doc-amount]u - \n[.t]u + 1v) +. rr doc-amount +.. +.ec +. +.\" This .bp replacement for continuous rendering mode adjusts the page +.\" length to the current position so that no empty lines are inserted. +. +.eo +.de doc-bp +. pl \n[nl]u +.. +.ec +. +. +.\" NS doc-set-up-continuous-rendering +.\" Move macros into place for continuous rendering. An end-of-input +.\" macro is set up by doc-set-up-titles. +.de doc-set-up-continuous-rendering +. rn ne doc-real-ne +. rn bp doc-real-bp +. rn doc-ne ne +. rn doc-bp bp +.. +. +.if \n[cR] \ +. doc-set-up-continuous-rendering +. +. +.\" header assembly macros +. +.\" NS doc-page-topic global string +.\" NS the title of the manual page +. +.ds doc-page-topic UNTITLED\" +. +. +.\" NS doc-volume global string +.\" NS the volume to which the manual page belongs +. +.ds doc-volume LOCAL\" +. +. +.\" NS doc-section global string +.\" NS the manual section (1, 2, 3, ..., 3perl, 9) +. +.ds doc-section \" empty +. +. +.\" NS doc-set-up-titles macro +.\" NS install and initialize header and footer support +.\" NS +.\" NS local variables: +.\" NS doc-footer-location +. +.eo +.de doc-set-up-titles +. br +. +. if !\n[cR] \{\ +. wh 0 doc-header +. ie r FT .nr doc-footer-location \n[FT] +. el .nr doc-footer-location (-.5i) +. wh \n[doc-footer-location]u doc-footer +. wh (\n[doc-footer-location]u - .5i) doc-break-body-text +. rr doc-footer-location +. \} +. +. e@ doc-end-macro +.. +.ec +. +. +.\" NS doc-date-string global string +.\" NS the manual page date as set by 'Dd' +. +.ds doc-date-string UNDATED\" +. +. +.\" NS Dd user macro (not parsed, not callable) +.\" NS set document date +.\" NS +.\" NS modifies: +.\" NS doc-date-string +.\" NS +.\" NS width register 'Dd' set above +. +.eo +.de Dd +. \" If batch processing (rendering multiple) man page documents, we +. \" must handle the end of a previous document. +. \" +. \" If also continuously rendering, cause a page transition to a new +. \" mdoc(7) document. +. if \n[doc-need-titles-reset] \{\ +. if \n[cR] .doc-end-macro +. +. \" Clear the page header trap so it is not sprung with stale +. \" information. +. ch doc-header +. doc-break-page-with-new-number +. \} +. if \n[C] .rr P +. +. if !\n[.$] \ +. tm mdoc warning: .Dd directive expects an argument (#\n[.c]) +. if \n[.$] \{\ +. ie "\$1"$Mdocdate:" .ds doc-date-string \$2\~\$3, \$4\" +. el .ds doc-date-string \$*\" +. \} +.. +.ec +. +. +.\" NS Dt user macro (not parsed, not callable) +.\" NS document title +.\" NS +.\" NS modifies: +.\" NS doc-page-topic +.\" NS doc-section +.\" NS doc-volume +.\" NS +.\" NS local variables: +.\" NS doc-volume-as-XXX +.\" NS doc-volume-ds-XXX +.\" NS +.\" NS width register 'Dt' set above +. +.\" an alternative, more detailed scheme for naming the manual sections +.\" +.ds doc-volume-ds-1 General Commands Manual +.ds doc-volume-ds-2 System Calls Manual +.ds doc-volume-ds-3 Library Functions Manual +.ds doc-volume-ds-4 Kernel Interfaces Manual +.ds doc-volume-ds-5 File Formats Manual +.ds doc-volume-ds-6 Games Manual +.ds doc-volume-ds-7 Miscellaneous Information Manual +.ds doc-volume-ds-8 System Manager's Manual +.ds doc-volume-ds-9 Kernel Developer's Manual +. +.ds doc-volume-ds-USD User's Supplementary Documents +.ds doc-volume-ds-PS1 Programmer's Supplementary Documents +.ds doc-volume-ds-AMD Ancestral Manual Documents +.ds doc-volume-ds-SMM System Manager's Manual +.ds doc-volume-ds-URM User's Reference Manual +.ds doc-volume-ds-PRM Programmer's Manual +.ds doc-volume-ds-KM Kernel Manual +.ds doc-volume-ds-IND Manual Master Index +.ds doc-volume-ds-LOCAL Local Manual +.ds doc-volume-ds-CON Contributed Software Manual +. +.als doc-volume-ds-MMI doc-volume-ds-IND +.als doc-volume-ds-LOC doc-volume-ds-LOCAL +. +.ds doc-volume-as-alpha alpha +.als doc-volume-as-Alpha doc-volume-as-alpha +.ds doc-volume-as-acorn26 acorn26 +.ds doc-volume-as-acorn32 acorn32 +.ds doc-volume-as-algor algor +.ds doc-volume-as-amd64 amd64 +.ds doc-volume-as-amiga amiga +.ds doc-volume-as-amigappc amigappc +.ds doc-volume-as-arc arc +.ds doc-volume-as-arm arm +.ds doc-volume-as-arm26 arm26 +.ds doc-volume-as-arm32 arm32 +.ds doc-volume-as-armish armish +.ds doc-volume-as-atari atari +.ds doc-volume-as-aviion aviion +.ds doc-volume-as-beagle beagle +.ds doc-volume-as-bebox bebox +.ds doc-volume-as-cats cats +.ds doc-volume-as-cesfic cesfic +.ds doc-volume-as-cobalt cobalt +.ds doc-volume-as-dreamcast dreamcast +.ds doc-volume-as-emips emips +.ds doc-volume-as-evbarm evbarm +.ds doc-volume-as-evbmips evbmips +.ds doc-volume-as-evbppc evbppc +.ds doc-volume-as-evbsh3 evbsh3 +.ds doc-volume-as-ews4800mips ews4800mips +.ds doc-volume-as-hp300 hp300 +.ds doc-volume-as-hp700 hp700 +.ds doc-volume-as-hpcarm hpcarm +.ds doc-volume-as-hpcmips hpcmips +.ds doc-volume-as-hpcsh hpcsh +.ds doc-volume-as-hppa hppa +.ds doc-volume-as-hppa64 hppa64 +.ds doc-volume-as-i386 i386 +.ds doc-volume-as-ia64 ia64 +.ds doc-volume-as-ibmnws ibmnws +.ds doc-volume-as-iyonix iyonix +.ds doc-volume-as-landisk landisk +.ds doc-volume-as-loongson loongson +.ds doc-volume-as-luna68k luna68k +.ds doc-volume-as-luna88k luna88k +.ds doc-volume-as-m68k m68k +.ds doc-volume-as-mac68k mac68k +.ds doc-volume-as-macppc macppc +.ds doc-volume-as-mips mips +.ds doc-volume-as-mips64 mips64 +.ds doc-volume-as-mipsco mipsco +.ds doc-volume-as-mmeye mmeye +.ds doc-volume-as-mvme68k mvme68k +.ds doc-volume-as-mvme88k mvme88k +.ds doc-volume-as-mvmeppc mvmeppc +.ds doc-volume-as-netwinder netwinder +.ds doc-volume-as-news68k news68k +.ds doc-volume-as-newsmips newsmips +.ds doc-volume-as-next68k next68k +.ds doc-volume-as-ofppc ofppc +.ds doc-volume-as-palm palm +.ds doc-volume-as-pc532 pc532 +.ds doc-volume-as-playstation2 playstation2 +.ds doc-volume-as-pmax pmax +.ds doc-volume-as-pmppc pmppc +.ds doc-volume-as-powerpc powerpc +.ds doc-volume-as-prep prep +.ds doc-volume-as-rs6000 rs6000 +.ds doc-volume-as-sandpoint sandpoint +.ds doc-volume-as-sbmips sbmips +.ds doc-volume-as-sgi sgi +.ds doc-volume-as-sgimips sgimips +.ds doc-volume-as-sh3 sh3 +.ds doc-volume-as-shark shark +.ds doc-volume-as-socppc socppc +.ds doc-volume-as-solbourne solbourne +.ds doc-volume-as-sparc sparc +.ds doc-volume-as-sparc64 sparc64 +.ds doc-volume-as-sun2 sun2 +.ds doc-volume-as-sun3 sun3 +.ds doc-volume-as-tahoe tahoe +.ds doc-volume-as-vax vax +.ds doc-volume-as-x68k x68k +.ds doc-volume-as-x86_64 x86_64 +.ds doc-volume-as-xen xen +.ds doc-volume-as-zaurus zaurus +. +.eo +.de Dt +. if !\n[.$] \ +. tm mdoc warning: .Dt directive expects one or more arguments \ +(#\n[.c]) +. if !"\$1"" \ +. ds doc-page-topic "\$1 +. +. if \n[CT] \ +. stringup doc-page-topic +. +. if !"\$2"" \{\ +. ds doc-section \$2 +. ie \B'\$2' \{\ +. if ((\$2 >= 1) & (\$2 <= 9)) \{\ +. ds doc-volume \" empty (not "LOCAL") +. if \A'\$3' \{\ +. if d doc-volume-as-\$3 \ +. as doc-volume "\*[doc-volume-as-\$3] +. \} +. as doc-volume " \*[doc-volume-ds-\$2] +. \} +. \} +. el \{\ +. ie "\$2"unass" \ +. ds doc-volume DRAFT +. el \{ .ie "\$2"draft" \ +. ds doc-volume DRAFT +. el .if "\$2"paper" \ +. ds doc-volume UNTITLED +. \} +. \} +. if \A'\$3' \{\ +. if d doc-volume-ds-\$3 \ +. ds doc-volume "\*[doc-volume-ds-\$3] +. \} +. \} +. +. if !"\$3"" \ +. if "\*[doc-volume]"LOCAL" \ +. ds doc-volume \$3 +.. +.ec +. +. +.\" NS doc-default-operating-system global string +.\" NS the default OS to associate with man pages +.\" NS +.\" NS override this in 'mdoc.local', if necessary +. +.ds doc-default-operating-system GNU\" +. +. +.\" NS doc-operating-system global string +.\" NS the OS or software project associated with the man page +. +.ds doc-operating-system \" empty +. +. +.\" NS Os user macro (not parsed, not callable) +.\" NS operating system +.\" NS +.\" NS modifies: +.\" NS doc-operating-system +.\" NS +.\" NS local variables: +.\" NS doc-operating-system-XXX-XXX +.\" NS +.\" NS width register 'Os' set above +. +.ds doc-operating-system-ATT-7 7th\~Edition +.als doc-operating-system-ATT-7th doc-operating-system-ATT-7 +.ds doc-operating-system-ATT-3 System\~III +.als doc-operating-system-ATT-III doc-operating-system-ATT-3 +.ds doc-operating-system-ATT-V System\~V +.ds doc-operating-system-ATT-V.2 System\~V Release\~2 +.ds doc-operating-system-ATT-V.3 System\~V Release\~3 +.ds doc-operating-system-ATT-V.4 System\~V Release\~4 +. +.ds doc-operating-system-BSD-3 3rd\~Berkeley Distribution +.ds doc-operating-system-BSD-4 4th\~Berkeley Distribution +.ds doc-operating-system-BSD-4.1 4.1\~Berkeley Distribution +.ds doc-operating-system-BSD-4.2 4.2\~Berkeley Distribution +.ds doc-operating-system-BSD-4.3 4.3\~Berkeley Distribution +.ds doc-operating-system-BSD-4.3T 4.3-Tahoe Berkeley Distribution +.ds doc-operating-system-BSD-4.3R 4.3-Reno Berkeley Distribution +.als doc-operating-system-BSD-4.3t doc-operating-system-BSD-4.3T +.als doc-operating-system-BSD-4.3r doc-operating-system-BSD-4.3R +.ds doc-operating-system-BSD-4.4 4.4BSD +. +.ds doc-operating-system-NetBSD-0.8 0.8 +.ds doc-operating-system-NetBSD-0.8a 0.8A +.ds doc-operating-system-NetBSD-0.9 0.9 +.ds doc-operating-system-NetBSD-0.9a 0.9A +.ds doc-operating-system-NetBSD-1.0 1.0 +.ds doc-operating-system-NetBSD-1.0a 1.0A +.ds doc-operating-system-NetBSD-1.1 1.1 +.ds doc-operating-system-NetBSD-1.2 1.2 +.ds doc-operating-system-NetBSD-1.2a 1.2A +.ds doc-operating-system-NetBSD-1.2b 1.2B +.ds doc-operating-system-NetBSD-1.2c 1.2C +.ds doc-operating-system-NetBSD-1.2d 1.2D +.ds doc-operating-system-NetBSD-1.2e 1.2E +.ds doc-operating-system-NetBSD-1.3 1.3 +.ds doc-operating-system-NetBSD-1.3a 1.3A +.ds doc-operating-system-NetBSD-1.4 1.4 +.ds doc-operating-system-NetBSD-1.4.1 1.4.1 +.ds doc-operating-system-NetBSD-1.4.2 1.4.2 +.ds doc-operating-system-NetBSD-1.4.3 1.4.3 +.ds doc-operating-system-NetBSD-1.5 1.5 +.ds doc-operating-system-NetBSD-1.5.1 1.5.1 +.ds doc-operating-system-NetBSD-1.5.2 1.5.2 +.ds doc-operating-system-NetBSD-1.5.3 1.5.3 +.ds doc-operating-system-NetBSD-1.6 1.6 +.ds doc-operating-system-NetBSD-1.6.1 1.6.1 +.ds doc-operating-system-NetBSD-1.6.2 1.6.2 +.ds doc-operating-system-NetBSD-1.6.3 1.6.3 +.ds doc-operating-system-NetBSD-2.0 2.0 +.ds doc-operating-system-NetBSD-2.0.1 2.0.1 +.ds doc-operating-system-NetBSD-2.0.2 2.0.2 +.ds doc-operating-system-NetBSD-2.0.3 2.0.3 +.ds doc-operating-system-NetBSD-2.1 2.1 +.ds doc-operating-system-NetBSD-3.0 3.0 +.ds doc-operating-system-NetBSD-3.0.1 3.0.1 +.ds doc-operating-system-NetBSD-3.0.2 3.0.2 +.ds doc-operating-system-NetBSD-3.0.3 3.0.3 +.ds doc-operating-system-NetBSD-3.1 3.1 +.ds doc-operating-system-NetBSD-3.1.1 3.1.1 +.ds doc-operating-system-NetBSD-4.0 4.0 +.ds doc-operating-system-NetBSD-4.0.1 4.0.1 +.ds doc-operating-system-NetBSD-5.0 5.0 +.ds doc-operating-system-NetBSD-5.0.1 5.0.1 +.ds doc-operating-system-NetBSD-5.0.2 5.0.2 +.ds doc-operating-system-NetBSD-5.1 5.1 +.ds doc-operating-system-NetBSD-5.1.2 5.1.2 +.ds doc-operating-system-NetBSD-5.1.3 5.1.3 +.ds doc-operating-system-NetBSD-5.1.4 5.1.4 +.ds doc-operating-system-NetBSD-5.2 5.2 +.ds doc-operating-system-NetBSD-5.2.1 5.2.1 +.ds doc-operating-system-NetBSD-5.2.2 5.2.2 +.ds doc-operating-system-NetBSD-6.0 6.0 +.ds doc-operating-system-NetBSD-6.0.1 6.0.1 +.ds doc-operating-system-NetBSD-6.0.2 6.0.2 +.ds doc-operating-system-NetBSD-6.0.3 6.0.3 +.ds doc-operating-system-NetBSD-6.0.4 6.0.4 +.ds doc-operating-system-NetBSD-6.0.5 6.0.5 +.ds doc-operating-system-NetBSD-6.0.6 6.0.6 +.ds doc-operating-system-NetBSD-6.1 6.1 +.ds doc-operating-system-NetBSD-6.1.1 6.1.1 +.ds doc-operating-system-NetBSD-6.1.2 6.1.2 +.ds doc-operating-system-NetBSD-6.1.3 6.1.3 +.ds doc-operating-system-NetBSD-6.1.4 6.1.4 +.ds doc-operating-system-NetBSD-6.1.5 6.1.5 +.ds doc-operating-system-NetBSD-7.0 7.0 +.ds doc-operating-system-NetBSD-7.0.1 7.0.1 +.ds doc-operating-system-NetBSD-7.0.2 7.0.2 +.ds doc-operating-system-NetBSD-7.1 7.1 +.ds doc-operating-system-NetBSD-7.1.1 7.1.1 +.ds doc-operating-system-NetBSD-7.1.2 7.1.2 +.ds doc-operating-system-NetBSD-7.2 7.2 +.ds doc-operating-system-NetBSD-8.0 8.0 +.ds doc-operating-system-NetBSD-8.1 8.1 +. +.ds doc-operating-system-OpenBSD-2.0 2.0 +.ds doc-operating-system-OpenBSD-2.1 2.1 +.ds doc-operating-system-OpenBSD-2.2 2.2 +.ds doc-operating-system-OpenBSD-2.3 2.3 +.ds doc-operating-system-OpenBSD-2.4 2.4 +.ds doc-operating-system-OpenBSD-2.5 2.5 +.ds doc-operating-system-OpenBSD-2.6 2.6 +.ds doc-operating-system-OpenBSD-2.7 2.7 +.ds doc-operating-system-OpenBSD-2.8 2.8 +.ds doc-operating-system-OpenBSD-2.9 2.9 +.ds doc-operating-system-OpenBSD-3.0 3.0 +.ds doc-operating-system-OpenBSD-3.1 3.1 +.ds doc-operating-system-OpenBSD-3.2 3.2 +.ds doc-operating-system-OpenBSD-3.3 3.3 +.ds doc-operating-system-OpenBSD-3.4 3.4 +.ds doc-operating-system-OpenBSD-3.5 3.5 +.ds doc-operating-system-OpenBSD-3.6 3.6 +.ds doc-operating-system-OpenBSD-3.7 3.7 +.ds doc-operating-system-OpenBSD-3.8 3.8 +.ds doc-operating-system-OpenBSD-3.9 3.9 +.ds doc-operating-system-OpenBSD-4.0 4.0 +.ds doc-operating-system-OpenBSD-4.1 4.1 +.ds doc-operating-system-OpenBSD-4.2 4.2 +.ds doc-operating-system-OpenBSD-4.3 4.3 +.ds doc-operating-system-OpenBSD-4.4 4.4 +.ds doc-operating-system-OpenBSD-4.5 4.5 +.ds doc-operating-system-OpenBSD-4.6 4.6 +.ds doc-operating-system-OpenBSD-4.7 4.7 +.ds doc-operating-system-OpenBSD-4.8 4.8 +.ds doc-operating-system-OpenBSD-4.9 4.9 +.ds doc-operating-system-OpenBSD-5.0 5.0 +.ds doc-operating-system-OpenBSD-5.1 5.1 +.ds doc-operating-system-OpenBSD-5.2 5.2 +.ds doc-operating-system-OpenBSD-5.3 5.3 +.ds doc-operating-system-OpenBSD-5.4 5.4 +.ds doc-operating-system-OpenBSD-5.5 5.5 +.ds doc-operating-system-OpenBSD-5.6 5.6 +.ds doc-operating-system-OpenBSD-5.7 5.7 +.ds doc-operating-system-OpenBSD-5.8 5.8 +.ds doc-operating-system-OpenBSD-5.9 5.9 +.ds doc-operating-system-OpenBSD-6.0 6.0 +.ds doc-operating-system-OpenBSD-6.1 6.1 +.ds doc-operating-system-OpenBSD-6.2 6.2 +.ds doc-operating-system-OpenBSD-6.3 6.3 +.ds doc-operating-system-OpenBSD-6.4 6.4 +.ds doc-operating-system-OpenBSD-6.5 6.5 +.ds doc-operating-system-OpenBSD-6.6 6.6 +. +.ds doc-operating-system-FreeBSD-1.0 1.0 +.ds doc-operating-system-FreeBSD-1.1 1.1 +.ds doc-operating-system-FreeBSD-1.1.5 1.1.5 +.ds doc-operating-system-FreeBSD-1.1.5.1 1.1.5.1 +.ds doc-operating-system-FreeBSD-2.0 2.0 +.ds doc-operating-system-FreeBSD-2.0.5 2.0.5 +.ds doc-operating-system-FreeBSD-2.1 2.1 +.ds doc-operating-system-FreeBSD-2.1.5 2.1.5 +.ds doc-operating-system-FreeBSD-2.1.6 2.1.6 +.ds doc-operating-system-FreeBSD-2.1.7 2.1.7 +.ds doc-operating-system-FreeBSD-2.2 2.2 +.ds doc-operating-system-FreeBSD-2.2.1 2.2.1 +.ds doc-operating-system-FreeBSD-2.2.2 2.2.2 +.ds doc-operating-system-FreeBSD-2.2.5 2.2.5 +.ds doc-operating-system-FreeBSD-2.2.6 2.2.6 +.ds doc-operating-system-FreeBSD-2.2.7 2.2.7 +.ds doc-operating-system-FreeBSD-2.2.8 2.2.8 +.ds doc-operating-system-FreeBSD-2.2.9 2.2.9 +.ds doc-operating-system-FreeBSD-3.0 3.0 +.ds doc-operating-system-FreeBSD-3.1 3.1 +.ds doc-operating-system-FreeBSD-3.2 3.2 +.ds doc-operating-system-FreeBSD-3.3 3.3 +.ds doc-operating-system-FreeBSD-3.4 3.4 +.ds doc-operating-system-FreeBSD-3.5 3.5 +.ds doc-operating-system-FreeBSD-4.0 4.0 +.ds doc-operating-system-FreeBSD-4.1 4.1 +.ds doc-operating-system-FreeBSD-4.1.1 4.1.1 +.ds doc-operating-system-FreeBSD-4.2 4.2 +.ds doc-operating-system-FreeBSD-4.3 4.3 +.ds doc-operating-system-FreeBSD-4.4 4.4 +.ds doc-operating-system-FreeBSD-4.5 4.5 +.ds doc-operating-system-FreeBSD-4.6 4.6 +.ds doc-operating-system-FreeBSD-4.6.2 4.6.2 +.ds doc-operating-system-FreeBSD-4.7 4.7 +.ds doc-operating-system-FreeBSD-4.8 4.8 +.ds doc-operating-system-FreeBSD-4.9 4.9 +.ds doc-operating-system-FreeBSD-4.10 4.10 +.ds doc-operating-system-FreeBSD-4.11 4.11 +.ds doc-operating-system-FreeBSD-5.0 5.0 +.ds doc-operating-system-FreeBSD-5.1 5.1 +.ds doc-operating-system-FreeBSD-5.2 5.2 +.ds doc-operating-system-FreeBSD-5.2.1 5.2.1 +.ds doc-operating-system-FreeBSD-5.3 5.3 +.ds doc-operating-system-FreeBSD-5.4 5.4 +.ds doc-operating-system-FreeBSD-5.5 5.5 +.ds doc-operating-system-FreeBSD-6.0 6.0 +.ds doc-operating-system-FreeBSD-6.1 6.1 +.ds doc-operating-system-FreeBSD-6.2 6.2 +.ds doc-operating-system-FreeBSD-6.3 6.3 +.ds doc-operating-system-FreeBSD-6.4 6.4 +.ds doc-operating-system-FreeBSD-7.0 7.0 +.ds doc-operating-system-FreeBSD-7.1 7.1 +.ds doc-operating-system-FreeBSD-7.2 7.2 +.ds doc-operating-system-FreeBSD-7.3 7.3 +.ds doc-operating-system-FreeBSD-7.4 7.4 +.ds doc-operating-system-FreeBSD-8.0 8.0 +.ds doc-operating-system-FreeBSD-8.1 8.1 +.ds doc-operating-system-FreeBSD-8.2 8.2 +.ds doc-operating-system-FreeBSD-8.3 8.3 +.ds doc-operating-system-FreeBSD-8.4 8.4 +.ds doc-operating-system-FreeBSD-9.0 9.0 +.ds doc-operating-system-FreeBSD-9.1 9.1 +.ds doc-operating-system-FreeBSD-9.2 9.2 +.ds doc-operating-system-FreeBSD-9.3 9.3 +.ds doc-operating-system-FreeBSD-10.0 10.0 +.ds doc-operating-system-FreeBSD-10.1 10.1 +.ds doc-operating-system-FreeBSD-10.2 10.2 +.ds doc-operating-system-FreeBSD-10.3 10.3 +.ds doc-operating-system-FreeBSD-10.4 10.4 +.ds doc-operating-system-FreeBSD-11.0 11.0 +.ds doc-operating-system-FreeBSD-11.1 11.1 +.ds doc-operating-system-FreeBSD-11.2 11.2 +.ds doc-operating-system-FreeBSD-11.3 11.3 +.ds doc-operating-system-FreeBSD-12.0 12.0 +.ds doc-operating-system-FreeBSD-12.1 12.1 +. +.ds doc-operating-system-Darwin-8.0.0 8.0.0 +.ds doc-operating-system-Darwin-8.1.0 8.1.0 +.ds doc-operating-system-Darwin-8.2.0 8.2.0 +.ds doc-operating-system-Darwin-8.3.0 8.3.0 +.ds doc-operating-system-Darwin-8.4.0 8.4.0 +.ds doc-operating-system-Darwin-8.5.0 8.5.0 +.ds doc-operating-system-Darwin-8.6.0 8.6.0 +.ds doc-operating-system-Darwin-8.7.0 8.7.0 +.ds doc-operating-system-Darwin-8.8.0 8.8.0 +.ds doc-operating-system-Darwin-8.9.0 8.9.0 +.ds doc-operating-system-Darwin-8.10.0 8.10.0 +.ds doc-operating-system-Darwin-8.11.0 8.11.0 +.ds doc-operating-system-Darwin-9.0.0 9.0.0 +.ds doc-operating-system-Darwin-9.1.0 9.1.0 +.ds doc-operating-system-Darwin-9.2.0 9.2.0 +.ds doc-operating-system-Darwin-9.3.0 9.3.0 +.ds doc-operating-system-Darwin-9.4.0 9.4.0 +.ds doc-operating-system-Darwin-9.5.0 9.5.0 +.ds doc-operating-system-Darwin-9.6.0 9.6.0 +.ds doc-operating-system-Darwin-9.7.0 9.7.0 +.ds doc-operating-system-Darwin-9.8.0 9.8.0 +.ds doc-operating-system-Darwin-10.0.0 10.0.0 +.ds doc-operating-system-Darwin-10.1.0 10.1.0 +.ds doc-operating-system-Darwin-10.2.0 10.2.0 +.ds doc-operating-system-Darwin-10.3.0 10.3.0 +.ds doc-operating-system-Darwin-10.4.0 10.4.0 +.ds doc-operating-system-Darwin-10.5.0 10.5.0 +.ds doc-operating-system-Darwin-10.6.0 10.6.0 +.ds doc-operating-system-Darwin-10.7.0 10.7.0 +.ds doc-operating-system-Darwin-10.8.0 10.8.0 +.ds doc-operating-system-Darwin-11.0.0 11.0.0 +.ds doc-operating-system-Darwin-11.1.0 11.1.0 +.ds doc-operating-system-Darwin-11.2.0 11.2.0 +.ds doc-operating-system-Darwin-11.3.0 11.3.0 +.ds doc-operating-system-Darwin-11.4.0 11.4.0 +.ds doc-operating-system-Darwin-11.5.0 11.5.0 +.ds doc-operating-system-Darwin-12.0.0 12.0.0 +.ds doc-operating-system-Darwin-12.1.0 12.1.0 +.ds doc-operating-system-Darwin-12.2.0 12.2.0 +.ds doc-operating-system-Darwin-13.0.0 13.0.0 +.ds doc-operating-system-Darwin-13.1.0 13.1.0 +.ds doc-operating-system-Darwin-13.2.0 13.2.0 +.ds doc-operating-system-Darwin-13.3.0 13.3.0 +.ds doc-operating-system-Darwin-13.4.0 13.4.0 +.ds doc-operating-system-Darwin-14.0.0 14.0.0 +.ds doc-operating-system-Darwin-14.1.0 14.1.0 +.ds doc-operating-system-Darwin-14.2.0 14.2.0 +.ds doc-operating-system-Darwin-14.3.0 14.3.0 +.ds doc-operating-system-Darwin-14.4.0 14.4.0 +.ds doc-operating-system-Darwin-14.5.0 14.5.0 +.ds doc-operating-system-Darwin-15.0.0 15.0.0 +.ds doc-operating-system-Darwin-15.1.0 15.1.0 +.ds doc-operating-system-Darwin-15.2.0 15.2.0 +.ds doc-operating-system-Darwin-15.3.0 15.3.0 +.ds doc-operating-system-Darwin-15.4.0 15.4.0 +.ds doc-operating-system-Darwin-15.5.0 15.5.0 +.ds doc-operating-system-Darwin-15.6.0 15.6.0 +.ds doc-operating-system-Darwin-16.0.0 16.0.0 +.ds doc-operating-system-Darwin-16.1.0 16.1.0 +.ds doc-operating-system-Darwin-16.2.0 16.2.0 +.ds doc-operating-system-Darwin-16.3.0 16.3.0 +.ds doc-operating-system-Darwin-16.4.0 16.4.0 +.ds doc-operating-system-Darwin-16.5.0 16.5.0 +.ds doc-operating-system-Darwin-16.6.0 16.6.0 +.ds doc-operating-system-Darwin-17.0.0 17.0.0 +.ds doc-operating-system-Darwin-17.1.0 17.1.0 +.ds doc-operating-system-Darwin-17.2.0 17.2.0 +.ds doc-operating-system-Darwin-17.3.0 17.3.0 +.ds doc-operating-system-Darwin-17.4.0 17.4.0 +.ds doc-operating-system-Darwin-17.5.0 17.5.0 +.ds doc-operating-system-Darwin-17.6.0 17.6.0 +.ds doc-operating-system-Darwin-17.7.0 17.7.0 +.ds doc-operating-system-Darwin-18.0.0 18.0.0 +.ds doc-operating-system-Darwin-18.1.0 18.1.0 +.ds doc-operating-system-Darwin-18.2.0 18.2.0 +.ds doc-operating-system-Darwin-18.3.0 18.3.0 +.ds doc-operating-system-Darwin-18.4.0 18.4.0 +.ds doc-operating-system-Darwin-18.5.0 18.5.0 +.ds doc-operating-system-Darwin-18.6.0 18.6.0 +.ds doc-operating-system-Darwin-18.7.0 18.7.0 +.ds doc-operating-system-Darwin-19.0.0 19.0.0 +.ds doc-operating-system-Darwin-19.1.0 19.1.0 +.ds doc-operating-system-Darwin-19.2.0 19.2.0 +. +.ds doc-operating-system-DragonFly-1.0 1.0 +.ds doc-operating-system-DragonFly-1.1 1.1 +.ds doc-operating-system-DragonFly-1.2 1.2 +.ds doc-operating-system-DragonFly-1.3 1.3 +.ds doc-operating-system-DragonFly-1.4 1.4 +.ds doc-operating-system-DragonFly-1.5 1.5 +.ds doc-operating-system-DragonFly-1.6 1.6 +.ds doc-operating-system-DragonFly-1.7 1.7 +.ds doc-operating-system-DragonFly-1.8 1.8 +.ds doc-operating-system-DragonFly-1.8.1 1.8.1 +.ds doc-operating-system-DragonFly-1.9 1.9 +.ds doc-operating-system-DragonFly-1.10 1.10 +.ds doc-operating-system-DragonFly-1.11 1.11 +.ds doc-operating-system-DragonFly-1.12 1.12 +.ds doc-operating-system-DragonFly-1.12.2 1.12.2 +.ds doc-operating-system-DragonFly-1.13 1.13 +.ds doc-operating-system-DragonFly-2.0 2.0 +.ds doc-operating-system-DragonFly-2.1 2.1 +.ds doc-operating-system-DragonFly-2.2 2.2 +.ds doc-operating-system-DragonFly-2.3 2.3 +.ds doc-operating-system-DragonFly-2.4 2.4 +.ds doc-operating-system-DragonFly-2.5 2.5 +.ds doc-operating-system-DragonFly-2.6 2.6 +.ds doc-operating-system-DragonFly-2.7 2.7 +.ds doc-operating-system-DragonFly-2.8 2.8 +.ds doc-operating-system-DragonFly-2.9 2.9 +.ds doc-operating-system-DragonFly-2.9.1 2.9.1 +.ds doc-operating-system-DragonFly-2.10 2.10 +.ds doc-operating-system-DragonFly-2.10.1 2.10.1 +.ds doc-operating-system-DragonFly-2.11 2.11 +.ds doc-operating-system-DragonFly-2.12 2.12 +.ds doc-operating-system-DragonFly-2.13 2.13 +.ds doc-operating-system-DragonFly-3.0 3.0 +.ds doc-operating-system-DragonFly-3.0.1 3.0.1 +.ds doc-operating-system-DragonFly-3.0.2 3.0.2 +.ds doc-operating-system-DragonFly-3.1 3.1 +.ds doc-operating-system-DragonFly-3.2 3.2 +.ds doc-operating-system-DragonFly-3.2.1 3.2.1 +.ds doc-operating-system-DragonFly-3.2.2 3.2.2 +.ds doc-operating-system-DragonFly-3.3 3.3 +.ds doc-operating-system-DragonFly-3.4 3.4 +.ds doc-operating-system-DragonFly-3.4.1 3.4.1 +.ds doc-operating-system-DragonFly-3.4.2 3.4.2 +.ds doc-operating-system-DragonFly-3.4.3 3.4.3 +.ds doc-operating-system-DragonFly-3.5 3.5 +.ds doc-operating-system-DragonFly-3.6 3.6 +.ds doc-operating-system-DragonFly-3.6.1 3.6.1 +.ds doc-operating-system-DragonFly-3.6.2 3.6.2 +.ds doc-operating-system-DragonFly-3.7 3.7 +.ds doc-operating-system-DragonFly-3.8 3.8 +.ds doc-operating-system-DragonFly-3.8.1 3.8.1 +.ds doc-operating-system-DragonFly-3.8.2 3.8.2 +.ds doc-operating-system-DragonFly-4.0 4.0 +.ds doc-operating-system-DragonFly-4.0.1 4.0.1 +.ds doc-operating-system-DragonFly-4.0.2 4.0.2 +.ds doc-operating-system-DragonFly-4.0.3 4.0.3 +.ds doc-operating-system-DragonFly-4.0.4 4.0.4 +.ds doc-operating-system-DragonFly-4.0.5 4.0.5 +.ds doc-operating-system-DragonFly-4.0.6 4.0.6 +.ds doc-operating-system-DragonFly-4.1 4.1 +.ds doc-operating-system-DragonFly-4.2 4.2 +.ds doc-operating-system-DragonFly-4.2.1 4.2.1 +.ds doc-operating-system-DragonFly-4.2.2 4.2.2 +.ds doc-operating-system-DragonFly-4.2.3 4.2.3 +.ds doc-operating-system-DragonFly-4.2.4 4.2.4 +.ds doc-operating-system-DragonFly-4.3 4.3 +.ds doc-operating-system-DragonFly-4.4 4.4 +.ds doc-operating-system-DragonFly-4.4.1 4.4.1 +.ds doc-operating-system-DragonFly-4.4.2 4.4.2 +.ds doc-operating-system-DragonFly-4.4.3 4.4.3 +.ds doc-operating-system-DragonFly-4.5 4.5 +.ds doc-operating-system-DragonFly-4.6 4.6 +.ds doc-operating-system-DragonFly-4.6.1 4.6.1 +.ds doc-operating-system-DragonFly-4.6.2 4.6.2 +.ds doc-operating-system-DragonFly-4.7 4.7 +.ds doc-operating-system-DragonFly-4.8 4.8 +.ds doc-operating-system-DragonFly-4.8.1 4.8.1 +.ds doc-operating-system-DragonFly-4.9 4.9 +.ds doc-operating-system-DragonFly-5.0 5.0 +.ds doc-operating-system-DragonFly-5.0.1 5.0.1 +.ds doc-operating-system-DragonFly-5.0.2 5.0.2 +.ds doc-operating-system-DragonFly-5.1 5.1 +.ds doc-operating-system-DragonFly-5.2 5.2 +.ds doc-operating-system-DragonFly-5.2.1 5.2.1 +.ds doc-operating-system-DragonFly-5.2.2 5.2.2 +.ds doc-operating-system-DragonFly-5.3 5.3 +.ds doc-operating-system-DragonFly-5.4 5.4 +.ds doc-operating-system-DragonFly-5.4.1 5.4.1 +.ds doc-operating-system-DragonFly-5.4.2 5.4.2 +.ds doc-operating-system-DragonFly-5.4.3 5.4.3 +.ds doc-operating-system-DragonFly-5.5 5.5 +.ds doc-operating-system-DragonFly-5.6 5.6 +.ds doc-operating-system-DragonFly-5.6.1 5.6.1 +.ds doc-operating-system-DragonFly-5.6.2 5.6.2 +. +.eo +.de Os +. ie "\$1"" \ +. ds doc-operating-system "\*[doc-default-operating-system] +. el \{ .ie "\$1"ATT" \{\ +. ds doc-operating-system AT&T +. if \A'\$2' \{\ +. ie d doc-operating-system-ATT-\$2 \ +. as doc-operating-system " \*[doc-operating-system-ATT-\$2] +. el \ +. as doc-operating-system " UNIX +. \}\} +. el \{ .ie "\$1"BSD" \{\ +. if \A'\$2' \{\ +. ie d doc-operating-system-BSD-\$2 \ +. ds doc-operating-system "\*[doc-operating-system-BSD-\$2] +. el \ +. tm mdoc warning: .Os: Unknown BSD version '\$2' (#\n[.c]) +. \}\} +. el \{ .ie "\$1"FreeBSD" \{\ +. ds doc-operating-system FreeBSD +. if \A'\$2' \{\ +. ie d doc-operating-system-FreeBSD-\$2 \ +. as doc-operating-system \~\*[doc-operating-system-FreeBSD-\$2] +. el \ +. tm mdoc warning: .Os: Unknown FreeBSD version '\$2' (#\n[.c]) +. \}\} +. el \{ .ie "\$1"DragonFly" \{\ +. ds doc-operating-system DragonFly +. if \A'\$2' \{\ +. ie d doc-operating-system-DragonFly-\$2 \ +. as doc-operating-system \~\*[doc-operating-system-DragonFly-\$2] +. el \ +. tm mdoc warning: .Os: Unknown DragonFly version '\$2' (#\n[.c]) +. \}\} +. el \{ .ie "\$1"NetBSD" \{\ +. ds doc-operating-system NetBSD +. if \A'\$2' \{\ +. ie d doc-operating-system-NetBSD-\$2 \ +. as doc-operating-system \~\*[doc-operating-system-NetBSD-\$2] +. el \ +. tm mdoc warning: .Os: Unknown NetBSD version '\$2' (#\n[.c]) +. \}\} +. el \{ .ie "\$1"OpenBSD" \{\ +. ds doc-operating-system OpenBSD +. if \A'\$2' \{\ +. ie d doc-operating-system-OpenBSD-\$2 \ +. as doc-operating-system \~\*[doc-operating-system-OpenBSD-\$2] +. el \ +. tm mdoc warning: .Os: Unknown OpenBSD version '\$2' (#\n[.c]) +. \}\} +. el \{ .ie "\$1"Darwin" \{\ +. ds doc-operating-system Darwin +. if \A'\$2' \{\ +. ie d doc-operating-system-Darwin-\$2 \ +. as doc-operating-system \~\*[doc-operating-system-Darwin-\$2] +. el \ +. tm mdoc warning: .Os: Unknown Darwin version '\$2' (#\n[.c]) +. \}\} +. el \{\ +. ds doc-operating-system \$1 +. if !"\$2"" \ +. as doc-operating-system " \$2 +. \}\}\}\}\}\}\}\} +. +. doc-set-up-titles +. +. if '\*[.T]'pdf' \ +. pdfbookmark 1 "\*[doc-page-topic](\*[doc-section])" +. +. doc-header +. nr doc-need-titles-reset 1 +.. +.ec +. +. +.\" NS doc-hyphen-flags global register +.\" NS the parameter for the '.hy' request +.ie \n[HY] \{\ +. ie \n[cR] .nr doc-hyphen-flags \n[\*[locale]*hyphenation-mode-base] +. el .nr doc-hyphen-flags \n[\*[locale]*hyphenation-mode-trap] +.\} +.el .nr doc-hyphen-flags 0 +. +. +.\" NS doc-header macro +.\" NS print page header +.\" NS +.\" NS local variables: +.\" NS doc-xref +.\" NS doc-abbv +.\" NS doc-reg-dh +.\" NS doc-reg-dh1 +.\" NS doc-hs-len +.\" NS doc-hs-len-prev +. +.eo +.de doc-header +. ds doc-xref \*[doc-page-topic-font]\*[doc-page-topic]\f[]\" +. as doc-xref \*[doc-page-section-font](\*[doc-section])\f[]\" +. ds doc-abbv \*[doc-page-topic]\" +. ev doc-env-dh +. doc-setup-page-layout +. ie \n[cR] .pl +1v +. el .sp .5i +. nr doc-reg-dh \w'\*[doc-page-topic-font]\*[doc-xref]\f[]' +. nr doc-reg-dh1 \w'\*[doc-volume]' +. if (\n[doc-reg-dh] + \n[doc-reg-dh1] + \n[doc-reg-dh] >= \n[.lt]) \{\ +. while (\n[doc-reg-dh] + \n[doc-reg-dh1] + \n[doc-reg-dh] >= \n[.lt]) \{\ +. ds doc-xref \*[doc-page-topic-font]\*[doc-abbv]\f[]\" +. as doc-xref \*[doc-page-section-font](\*[doc-section])\f[]\" +. length doc-abbv-len-prev \*[doc-abbv] +. substring doc-abbv 0 -2 +. length doc-abbv-len \*[doc-abbv] +. nr doc-reg-dh \w'\*[doc-page-topic-font]\*[doc-abbv]\|.\|.\|.\f[]' +. \" If header string didn't actually get shorter, stop trying. +. if (\n[doc-abbv-len-prev] <= \n[doc-abbv-len]) \ +. break +. \} +. rr doc-abbv-len +. rr doc-abbv-len-prev +. as doc-abbv \|.\|.\|. +. \} +. tl '\*[doc-xref]'\*[doc-volume]\f[]'\*[doc-xref]' +. ie \n[cR] \{\ +. pl +1v +. sp 1v +. \} +. el .sp |1i +. ev +. ns +. rm doc-xref +. rm doc-abbv +.. +.ec +. +. +.\" NS doc-break-body-text +.\" NS Schedule a page break when the next output line is written (not +.\" NS called if continuously rendering). +.de doc-break-body-text +' bp +.. +. +. +.\" NS doc-footer macro +.\" NS print page footer +.\" +.\" NS local variables: +.\" NS doc-xref +.\" NS doc-page-id +. +.eo +.de doc-footer +. ds doc-xref \*[doc-page-topic-font]\*[doc-page-topic]\f[]\" +. as doc-xref \*[doc-page-section-font](\*[doc-section])\f[]\" +. ds doc-page-id \n[%] +. if r X \{\ +. if (\n[%] > \n[X]) \{\ +. nr doc-page-letter (\n[%] - \n[X]) +. ds doc-page-id \n[X]\n[doc-page-letter]\" +. \} +. \} +. ev doc-caption-enviroment +. doc-setup-page-layout +. ie \n[D] \{\ +. ie e \ +. tl '%'\*[doc-date-string]'\*[doc-operating-system]' +. el \ +. tl '\*[doc-operating-system]'\*[doc-date-string]'\*[doc-page-id]' +. \} +. el \{\ +. ie \n[cR] \ +. tl '\*[doc-operating-system]'\*[doc-date-string]'\*[doc-xref]' +. el \ +. tl '\*[doc-operating-system]'\*[doc-date-string]'\*[doc-page-id]' +. \} +. if !\n[cR] .bp +. ev +. rm doc-page-id +. rm doc-xref +.. +.ec +. +. +.\" NS doc-check-depth macro +.\" NS check paired macros +. +.eo +.de doc-check-depth +. if \n[doc-list-depth] \{\ +. tm mdoc warning: A .Bl directive has no matching .El (#\n[.c]) +. nr doc-list-depth 0 +. \} +. if \n[doc-display-depth] \{\ +. tm mdoc warning: A .Bd directive has no matching .Ed (#\n[.c]) +. nr doc-display-depth 0 +. \} +. if \n[doc-fontmode-depth] \{\ +. tm mdoc warning: A .Bf directive has no matching .Ef (#\n[.c]) +. nr doc-fontmode-depth 0 +. \} +.. +.ec +. +. +.\" NS doc-end-macro macro +.\" NS finish output +.\" NS +.\" NS modifies: +.\" NS doc-need-titles-reset +. +.eo +.de doc-end-macro +. doc-check-depth +. +. if \n[cR] \{\ +. \" We might have a pending output line that is not yet broken, and +. \" also be 1v from the bottom of the page. If we break (or flush) +. \" the output line now, the page will get ejected afterward and +. \" troff will exit because we're in an end-of-input macro--our +. \" footer will never be output. So, if that is the case, further +. \" extend the page length by 1v. +. if ((\n[.p] - \n[nl]) <= \n[.V]) .pl +1v +. br +. pl +1v +. sp 1v +. doc-footer +. \" If we're processing multiple documents and have started a new +. \" one, draw a line between this footer and the next header. +. if !'\n[.F]'' \{\ +. pl +1v +. nf +. ti 0 +\D'l \n[doc-line-length]u 0' +. fi +. \} +. \" suppress empty lines after the footer +. pl \n[nl]u +. \} +. ch doc-header +. doc-break-page-with-new-number +. +. \" Reset strings to reduce info leaks from one man page to the next. +. ds doc-date-string UNDATED\" +. ds doc-page-topic UNTITLED\" +. ds doc-volume LOCAL\" +. ds doc-section \" empty +. ds doc-operating-system \" empty +. ds doc-topic-name \" empty +.. +.ec +. +. +.\" NS doc-break-page-with-new-number macro +.\" NS Break the page and update its number depending on the C +.\" NS (consecutive numbering) register. +.\" NS +.\" NS Corner case: if formatting multiple documents and P (starting +.\" NS page number) is defined but C is not set, start numbering each +.\" NS document at \n[P]. Not strictly necessary if not switching +.\" NS macro packages. +. +.eo +.de doc-break-page-with-new-number +. ie \n[C] .bp (\n[%] + 1) \" argument NOT redundant before page 1 +. el \{\ +. ie r P .bp \n[P] +. el .bp 1 +. \} +.. +.ec +. +. +.\" NS doc-paragraph macro +.\" NS insert a paragraph +. +.eo +.de doc-paragraph +. sp \n[doc-paragraph-space]u +. if !\n[cR] \ +. ne 2 +. ns +.. +.ec +. +. +.\" NS Pp user macro (not parsed, not callable) +.\" NS new paragraph +.\" NS +.\" NS width register 'Pp' set above +. +.als Pp doc-paragraph +. +. +.\" NS Lp user macro (not parsed, not callable) +.\" NS same as .Pp +.\" NS +.\" NS width register 'Lp' set above +. +.als Lp doc-paragraph +. +. +.eo +.de LP +. tm Not a \-mdoc command: .LP (#\n[.c]) +.. +.ec +. +. +.eo +.de PP +. tm Not a \-mdoc command: .PP (#\n[.c]) +.. +.ec +. +. +.eo +.de pp +. tm Not a \-mdoc command: .pp (#\n[.c]) +.. +.ec +. +. +.eo +.de SH +. tm Not a \-mdoc command: .SH (#\n[.c]) +.. +.ec +. +. +.\" NS Nd user macro (not parsed, not callable) +.\" NS print name description +.\" NS +.\" NS width register 'Nd' set above +. +.eo +.de Nd +. nop \[em] \$* +.. +.ec +. +. +.\" NS doc-in-name-section global register (bool) +.\" NS whether we are in the 'name' section +. +.nr doc-in-name-section 0 +. +. +.\" NS doc-in-synopsis-section global register (bool) +.\" NS whether we are in the 'synopsis' section +. +.nr doc-in-synopsis-section 0 +. +. +.\" NS doc-in-library-section global register (bool) +.\" NS whether we are in the 'library' section +. +.nr doc-in-library-section 0 +. +. +.\" NS doc-in-see-also-section global register (bool) +.\" NS whether we are in the 'see also' section +. +.nr doc-in-see-also-section 0 +. +. +.\" NS doc-in-files-section global register (bool) +.\" NS whether we are in the 'files' section +. +.nr doc-in-files-section 0 +. +. +.\" NS doc-in-authors-section global register (bool) +.\" NS whether we are in the 'authors' section +. +.nr doc-in-authors-section 0 +. +. +.\" NS doc-need-titles-reset global register (bool) +.\" NS whether the strings that set header and footer text need to be +.\" NS reconfigured +.\" NS +.\" NS This happens when batch-rendering and starting a new page. +. +.nr doc-need-titles-reset 0 +. +. +.\" NS doc-first-parameter macro +.\" NS return first parameter +.\" NS +.\" NS local variables: +.\" NS doc-str-dfp +. +.eo +.de doc-first-parameter +. ds doc-str-dfp "\$1 +.. +.ec +. +. +.\" NS doc-prepare-section-heading macro +.\" NS define `doc-sec-head`, `macro` prepared for string matching +.\" +.\" NS +.\" NS local variables: +.\" NS doc-str-tmp1 +.\" NS doc-str-tmp2 +.\" NS doc-tmp-strlen +. +.eo +.de doc-prepare-section-heading +. ds doc-str-tmp1 "\$* +. ds doc-str-tmp2 "\$* +. length doc-tmp-strlen \$* +. \" Leave (nonstandard) section headings of length 0 or 1 unchanged. +. ie \n[doc-tmp-strlen]>1 \{\ +. substring doc-str-tmp1 0 0 +. substring doc-str-tmp2 1 +. stringdown doc-str-tmp2 +. ds doc-sec-head \*[doc-str-tmp1]\*[doc-str-tmp2]\" +. \} +. el \ +. ds doc-sec-head "\$* +. rm doc-str-tmp1 +. rm doc-str-tmp2 +. rr doc-tmp-strlen +.. +.ec +. +. +.\" NS Sh user macro (not callable) +.\" NS section headers +.\" NS +.\" NS modifies: +.\" NS doc-func-args-processed +.\" NS doc-func-count +.\" NS doc-in-authors-section +.\" NS doc-in-files-section +.\" NS doc-in-library-section +.\" NS doc-in-name-section +.\" NS doc-in-see-also-section +.\" NS doc-in-synopsis-section +.\" NS doc-indent-synopsis +.\" NS doc-indent-synopsis-active +.\" NS doc-is-func +.\" NS doc-num-func-args +.\" NS +.\" NS local variables: +.\" NS doc-reg-Sh +.\" NS doc-reg-Sh1 +.\" NS doc-section-XXX +.\" NS +.\" NS width register 'Sh' set in doc-common +. +.ds doc-section-name Name\" +.ds doc-section-synopsis Synopsis\" +.ds doc-section-library Library\" +.ds doc-section-description Description\" +.ds doc-section-see-also See also\" +.ds doc-section-files Files\" +.ds doc-section-authors Authors\" +. +.eo +.de Sh +. \" Tell doc-print-recursive whether to force capitalization. +. nr doc-do-capitalize \n[CS] +. +. \" Normalize capitalization of section heading. +. doc-prepare-section-heading \$* +. +. ie "\*[doc-sec-head]"\*[doc-section-name]" \ +. nr doc-in-name-section 1 +. el \ +. nr doc-in-name-section 0 +. +. ie \n[doc-arg-count] \{\ +. \" we only allow 'Sh' within 'Sh'; it will change the font back to +. \" 'doc-Sh-font' +. ie "\*[doc-macro-name]"Sh" \{\ +. nr doc-arg-ptr +1 +. ie (\n[doc-arg-count] >= \n[doc-arg-ptr]) \{\ +. nr doc-curr-font \n[.f] +. nop \*[doc-Sh-font]\c +. doc-print-recursive +. \} +. el \{\ +. tm Usage: .Sh section_name ... (#\n[.c]) +. doc-reset-args +. \}\} +. el \{\ +. tm Usage: .Sh not callable by other macros (#\n[.c]) +. doc-reset-args +. \}\} +. el \{\ +. if !\n[.$] \{\ +. tm Usage: .Sh section_name ... (#\n[.c]) +. return +. \} +. +. ds doc-macro-name Sh +. doc-parse-args \$@ +. +. ad \*[AD] +. +. ie "\*[doc-sec-head]"\*[doc-section-name]" \{\ +. doc-set-up-titles +. in 0 +. \} +. el \{\ +. nr doc-in-name-section 0 +. nr doc-in-synopsis-section 0 +. nr doc-in-library-section 0 +. nr doc-in-see-also-section 0 +. nr doc-in-files-section 0 +. nr doc-in-authors-section 0 +. +. ie "\*[doc-sec-head]"\*[doc-section-synopsis]" \{\ +. if t \ +. na +. nr doc-in-synopsis-section 1 +. nr doc-indent-synopsis 0 +. nr doc-indent-synopsis-active 0 +. \} +. el \{ .ie "\*[doc-sec-head]"\*[doc-section-library]" \{\ +. nr doc-in-library-section 1 +. \} +. el \{ .ie "\*[doc-sec-head]"\*[doc-section-description]" \{\ +. nr doc-is-func 0 +. nr doc-func-count 0 +. nr doc-func-args-processed 0 +. nr doc-num-func-args 0 +. \} +. el \{ .ie "\*[doc-sec-head]"\*[doc-section-see-also]" \{\ +. if t \ +. na +. nr doc-in-see-also-section 1 +. \} +. el \{ .ie "\*[doc-sec-head]"\*[doc-section-files]" \ +. nr doc-in-files-section 1 +. el .if "\*[doc-sec-head]"\*[doc-section-authors]" \ +. nr doc-in-authors-section 1 +. \}\}\}\} +. +. in 0 +. nr doc-have-author 0 +. \} +. +. doc-setup-page-layout +. sp \n[doc-paragraph-space]u +. ns +. ta T .5i +. if !\n[cR] \ +. ne 3 +. fi +. +. if '\*[.T]'pdf' \ +. pdfbookmark 2 "\*[doc-sec-head]" +. +. if t \{\ +. nr doc-reg-Sh \n[.ss] +. nr doc-reg-Sh1 \n[.sss] +. ss (\n[.ss] * 5 / 3) (\n[.sss] * 5 / 3) +. \} +. +. if \n[doc-remap-I-style-in-headings] \ +. ftr \*[doc-heading-family]I \*[doc-heading-family]BI +. +. nr doc-arg-ptr +1 +. nr doc-curr-font \n[.f] +. nop \*[doc-Sh-font]\c +. doc-print-recursive +. +. if t \ +. ss \n[doc-reg-Sh] \n[doc-reg-Sh1] +. +. in \n[IN]u +. ns +. +. doc-check-depth +. if \n[doc-remap-I-style-in-headings] \ +. ftr \*[doc-heading-family]I \*[doc-heading-family]I +. \} +. +. +. \" Don't let doc-print-recursive force caps on anything else. +. nr doc-do-capitalize 0 +.. +.ec +. +. +.\" NS Ss user macro (not callable) +.\" NS subsection +.\" NS +.\" NS modifies: +.\" NS doc-subsection-heading +.\" NS +.\" NS local variable: +.\" NS doc-reg-Ss +.\" NS doc-reg-Ss1 +.\" NS +.\" NS width register 'Ss' set above +. +.eo +.de Ss +. ie \n[doc-arg-count] \{\ +. \" we only allow 'Ss' within 'Ss'; it will change the font back to +. \" 'doc-Sh-font' +. ie "\*[doc-macro-name]"Ss" \{\ +. nr doc-arg-ptr +1 +. ie (\n[doc-arg-count] >= \n[doc-arg-ptr]) \{\ +. nr doc-curr-font \n[.f] +. nop \*[doc-Sh-font]\c +. doc-print-recursive +. \} +. el \{\ +. tm Usage: .Ss subsection_name ... (#\n[.c]) +. doc-reset-args +. \}\} +. el \{\ +. tm Usage: .Ss not callable by other macros (#\n[.c]) +. doc-reset-args +. \}\} +. el \{\ +. if !\n[.$] \{\ +. tm Usage: .Ss subsection_name ... (#\n[.c]) +. return +. \} +. +. ds doc-macro-name Ss +. doc-parse-args \$@ +. +. ds doc-subsection-heading \$* +. +. sp \n[doc-paragraph-space]u +. if !\n[cR] \ +. ne 3 +. in \n[SN]u +. +. if '\*[.T]'pdf' \ +. pdfbookmark 3 "\*[doc-subsection-heading]" +. +. nr doc-reg-Ss \n[.ss] +. nr doc-reg-Ss1 \n[.sss] +. ss (\n[.ss] * 5 / 4) (\n[.sss] * 5 / 4) +. +. if \n[doc-remap-I-style-in-headings] \ +. ftr \*[doc-heading-family]I \*[doc-heading-family]BI +. +. nr doc-arg-ptr +1 +. nr doc-curr-font \n[.f] +. nop \*[doc-Sh-font]\c +. doc-print-recursive +. +. ss \n[doc-reg-Ss] \n[doc-reg-Ss1] +. +. ta T .5i +. in +. if !\n[cR] \ +. ne 2 +. br +. ns +. +. doc-check-depth +. if \n[doc-remap-I-style-in-headings] \ +. ftr \*[doc-heading-family]I \*[doc-heading-family]I +. \} +. +.. +.ec +. +. +.\" NS Rd macro (not parsed, not callable) +.\" NS print global register dump to stderr +.\" NS +.\" NS local variables: +.\" NS doc-reg-Rd +. +.eo +.de Rd +. tm MDOC GLOBAL REGISTER DUMP +. tm doc-macro-name == '\*[doc-macro-name]' +. tm doc-arg-count == \n[doc-arg-count] +. tm doc-num-args == \n[doc-num-args] +. tm doc-arg-ptr == \n[doc-arg-ptr] +. +. nr doc-reg-Rd 1 +. while (\n[doc-reg-Rd] <= \n[doc-arg-count]) \{\ +. tm doc-arg\n[doc-reg-Rd] == '\*[doc-arg\n[doc-reg-Rd]]' +. tm doc-type\n[doc-reg-Rd] == \n[doc-type\n[doc-reg-Rd]] +. tm doc-space\n[doc-reg-Rd] == '\*[doc-space\n[doc-reg-Rd]]' +. nr doc-reg-Rd +1 +. \} +. +. tm doc-curr-font == \n[doc-curr-font] +. tm doc-indent-synopsis == \n[doc-indent-synopsis] +. tm doc-indent-synopsis-active == \n[doc-indent-synopsis-active] +. tm doc-have-decl == \n[doc-have-decl] +. tm doc-have-var == \n[doc-have-var] +. tm doc-topic-name == '\*[doc-topic-name]' +. tm doc-quote-left == '\*[doc-quote-left]' +. tm doc-quote-right == '\*[doc-quote-right]' +. tm doc-nesting-level == \n[doc-nesting-level] +. tm doc-in-list == \n[doc-in-list] +. tm doc-space == '\*[doc-space]' +. tm doc-saved-space == '\*[doc-saved-space]' +. tm doc-space-mode == \n[doc-space-mode] +. tm doc-have-space == \n[doc-have-space] +. tm doc-have-slot == \n[doc-have-slot] +. tm doc-keep-type == \n[doc-keep-type] +. tm doc-display-depth == \n[doc-display-depth] +. tm doc-is-compact == \n[doc-is-compact] +. +. nr doc-reg-Rd 0 +. while (\n[doc-reg-Rd] <= \n[doc-display-depth]) \{\ +. tm doc-display-type-stack\n[doc-reg-Rd] == '\*[doc-display-type-stack\n[doc-reg-Rd]]' +. tm doc-display-indent-stack\n[doc-reg-Rd] == \n[doc-display-indent-stack\n[doc-reg-Rd]] +. tm doc-display-ad-stack\n[doc-reg-Rd] == \n[doc-display-ad-stack\n[doc-reg-Rd]] +. tm doc-display-fi-stack\n[doc-reg-Rd] == \n[doc-display-fi-stack\n[doc-reg-Rd]] +. tm doc-display-ft-stack\n[doc-reg-Rd] == \n[doc-display-ft-stack\n[doc-reg-Rd]] +. tm doc-display-ps-stack\n[doc-reg-Rd] == \n[doc-display-ps-stack\n[doc-reg-Rd]] +. nr doc-reg-Rd +1 +. \} +. +. tm doc-fontmode-depth == \n[doc-fontmode-depth] +. +. nr doc-reg-Rd 1 +. while (\n[doc-reg-Rd] <= \n[doc-fontmode-depth]) \{\ +. tm doc-fontmode-font-stack\n[doc-reg-Rd] == '\n[doc-fontmode-font-stack\n[doc-reg-Rd]]' +. tm doc-fontmode-size-stack\n[doc-reg-Rd] == '\n[doc-fontmode-size-stack\n[doc-reg-Rd]]' +. nr doc-reg-Rd +1 +. \} +. +. tm doc-list-depth == \n[doc-list-depth] +. +. nr doc-reg-Rd 1 +. while (\n[doc-reg-Rd] <= \n[doc-list-depth]) \{\ +. tm doc-list-type-stack\n[doc-reg-Rd] == '\*[doc-list-type-stack\n[doc-reg-Rd]]' +. tm doc-list-have-indent-stack\n[doc-reg-Rd] == \n[doc-list-have-indent-stack\n[doc-reg-Rd]] +. tm doc-list-indent-stack\n[doc-reg-Rd] == \n[doc-list-indent-stack\n[doc-reg-Rd]] +. tm doc-compact-list-stack\n[doc-reg-Rd] == \n[doc-compact-list-stack\n[doc-reg-Rd]] +. tm doc-tag-prefix-stack\n[doc-reg-Rd] == '\*[doc-tag-prefix-stack\n[doc-reg-Rd]]' +. tm doc-tag-width-stack\n[doc-reg-Rd] == '\*[doc-tag-width-stack\n[doc-reg-Rd]]' +. tm doc-list-offset-stack\n[doc-reg-Rd] == \n[doc-list-offset-stack\n[doc-reg-Rd]] +. tm doc-enum-list-count-stack\n[doc-reg-Rd] == \n[doc-enum-list-count-stack\n[doc-reg-Rd]] +. nr doc-reg-Rd +1 +. \} +. +. tm doc-saved-Pa-font == '\*[doc-saved-Pa-font]' +. tm doc-curr-type == \n[doc-curr-type] +. tm doc-curr-arg == '\*[doc-curr-arg]' +. tm doc-diag-list-input-line-count == \n[doc-diag-list-input-line-count] +. tm doc-num-columns == \n[doc-num-columns] +. tm doc-column-indent-width == \n[doc-column-indent-width] +. tm doc-is-func == \n[doc-is-func] +. tm doc-have-old-func == \n[doc-have-old-func] +. tm doc-func-arg-count == \n[doc-func-arg-count] +. tm doc-func-arg == '\*[doc-func-arg]' +. tm doc-num-func-args == \n[doc-num-func-args] +. tm doc-func-args-processed == \n[doc-func-args-processed] +. tm doc-have-func == \n[doc-have-func] +. tm doc-is-reference == \n[doc-is-reference] +. tm doc-reference-count == \n[doc-reference-count] +. tm doc-author-count == \n[doc-author-count] +. +. nr doc-reg-Rd 0 +. while (\n[doc-reg-Rd] <= \n[doc-author-count]) \{\ +. tm doc-author-name\n[doc-reg-Rd] == '\*[doc-author-name\n[doc-reg-Rd]]' +. nr doc-reg-Rd +1 +. \} +. +. tm doc-book-count == \n[doc-book-count] +. tm doc-book-name == '\*[doc-book-name]' +. tm doc-date-count == \n[doc-date-count] +. tm doc-date == '\*[doc-date]' +. tm doc-publisher-count == \n[doc-publisher-count] +. tm doc-publisher-name == '\*[doc-publisher-name]' +. tm doc-journal-count == \n[doc-journal-count] +. tm doc-journal-name == '\*[doc-journal-name]' +. tm doc-issue-count == \n[doc-issue-count] +. tm doc-issue-name == '\*[doc-issue-name]' +. tm doc-optional-count == \n[doc-optional-count] +. tm doc-optional-string == '\*[doc-optional-string]' +. tm doc-page-number-count == \n[doc-page-number-count] +. tm doc-page-number-string == '\*[doc-page-number-string]' +. tm doc-corporate-count == \n[doc-corporate-count] +. tm doc-corporate-name == '\*[doc-corporate-name]' +. tm doc-report-count == \n[doc-report-count] +. tm doc-report-name == '\*[doc-report-name]' +. tm doc-reference-title-count == \n[doc-reference-title-count] +. tm doc-reference-title-name == '\*[doc-reference-title-name]' +. tm doc-reference-title-name-for-book == '\*[doc-reference-title-name-for-book]' +. tm doc-url-count == \n[doc-url-count] +. tm doc-url-name == '\*[doc-url-name]' +. tm doc-volume-count == \n[doc-volume-count] +. tm doc-volume-name == '\*[doc-volume-name]' +. tm doc-have-author == \n[doc-have-author] +. +. tm doc-page-topic == '\*[doc-page-topic]' +. tm doc-volume == '\*[doc-volume]' +. tm doc-section == '\*[doc-section]' +. tm doc-operating-system == '\*[doc-operating-system]' +. tm doc-date-string == '\*[doc-date-string]' +. tm doc-display-vertical == \n[doc-display-vertical] +. tm doc-in-name-section == \n[doc-in-name-section] +. tm doc-in-synopsis-section == \n[doc-in-synopsis-section] +. tm doc-in-library-section == \n[doc-in-library-section] +. tm doc-in-see-also-section == \n[doc-in-see-also-section] +. tm doc-in-files-section == \n[doc-in-files-section] +. tm doc-in-authors-section == \n[doc-in-authors-section] +. +. tm END OF GLOBAL REGISTER DUMP +.. +.ec +. +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/mdoc/doc-ditroff b/tmac/mdoc/doc-ditroff new file mode 100644 index 0000000..96cb2f7 --- /dev/null +++ b/tmac/mdoc/doc-ditroff @@ -0,0 +1,287 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" 3. [Deleted. See +.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] +.\" 4. Neither the name of the University nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" +.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +.\" PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR +.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)doc-ditroff 8.1 (Berkeley) 06/08/93 +. +. +.\" Use -rS={11,12} to change the font size from 10pt to 11pt or 12pt. +.if !r S .nr S 10 +. +.ie (\n[S] == 11) \{\ +. ps 10.95z +. vs 13.6p +.\} +.el \{ .ie (\n[S] == 12) \{\ +. ps 12z +. vs 14.5p +.\} +.el \{\ +. ps 10z +. vs 12p +.\}\} +. +. +.\" the 'doc-xx-font' strings must not be empty! +. +.ds doc-page-topic-font \f[I] +.ds doc-page-section-font \f[R] +.ds doc-Ad-font \f[I] +.ds doc-Ar-font \f[CI] +.ds doc-Cm-font \f[CR] +.ds doc-Em-font \f[I] +.ds doc-Er-font \f[CR] +.ds doc-Ev-font \f[CR] +.ds doc-Fa-font \f[CI] +.ds doc-Fd-font \f[CB] +.ds doc-Fl-font \f[CR] +.ds doc-Fn-font \f[CB] +.ds doc-Ft-font \f[CI] +.ds doc-Ic-font \f[CB] +.ds doc-Li-font \f[CR] +.ds doc-Lk-font \f[R]\" +.ds doc-Me-font \f[B] +.ds doc-Nm-font \f[CB] +.ds doc-No-font \f[R] +.ds doc-Pa-font \f[I] +.ds doc-Sh-font \f[\*[HF]]\" +.ds doc-Sy-font \f[B] +.ds doc-Tn-font \f[R] +.ds doc-Va-font \f[I] +.ds doc-Xr-font \f[I] +. +.ds doc-left-parenthesis \f[R](\f[] +.ds doc-right-parenthesis \f[R])\f[] +.ds lp \f[R](\f[] +.ds rp \f[R])\f[] +.ds doc-left-bracket \f[R][\f[] +.ds doc-right-bracket \f[R]]\f[] +. +.tr *\[**] +. +.\" miscellaneous +.nr doc-paragraph-space .4v +. +.nr doc-digit-width \w'\0'u +.nr doc-fixed-width \w'\f[CR]0' +. +. +.\" NS doc-display-vertical global register +.\" NS vertical space between list elements etc. +. +.nr doc-display-vertical 0 +. +. +.\" NS doc-setup-page-layout macro +.\" NS set up page layout +.\" NS +.\" NS modifies: +.\" NS doc-display-vertical +.\" NS doc-line-length +. +.eo +.de doc-setup-page-layout +. ie r LL \ +. ll \n[LL]u +. el \ +. ll \n[.l]u +. +. ie r LT \ +. lt \n[LT]u +. el \ +. lt \n[.l]u +. +. po 1i +. +. nr doc-display-vertical .5v +. nr doc-line-length \n[.l] +.. +.ec +. +. +.ds doc-left-singlequote \[oq] +.ds doc-right-singlequote \[cq] +. +.\" the following strings are 'official' +.ds <= \[<=] +.ds >= \[>=] +.ds Lq \[lq] +.ds Rq \[rq] +.ds ua \[ua] +.ds aa \[aa] +.ds ga \[ga] +.ds q \[dq] +.ds Pi \[*p] +.ds Ne \[!=] +.ds Le \[<=] +.ds Ge \[>=] +.ds Lt < +.ds Gt > +.ds Pm \[+-] +.ds If \[if] +.ds Na \f[I]NaN\f[] +.ds Ba \f[R]|\f[] +.ds Am & +. +. +.\" NS doc-get-width macro +.\" NS computes the width of a string as a multiple of +.\" NS 'doc-fixed-width': '.doc-get-width string' +.\" NS +.\" NS modifies: +.\" NS doc-width +. +.eo +.de doc-get-width +. nr doc-width \w'\f[CR]\$1' +. ie (\n[doc-width] >= \n[doc-fixed-width]) \{\ +. ie (\n[doc-width] % \n[doc-fixed-width]) \ +. nr doc-width ((\n[doc-width] / \n[doc-fixed-width]) + 1) +. el \ +. nr doc-width (\n[doc-width] / \n[doc-fixed-width]) +. \} +. el \{\ +. ie \n[doc-width] \ +. nr doc-width 1 +. el \ +. nr doc-width 0 +. \} +.. +.ec +. +. +.\" NS doc-get-arg-width macro +.\" NS computes the width of an argument as a multiple of +.\" NS 'doc-fixed-width': '.doc-get-arg-width arg-index' +.\" NS +.\" NS modifies: +.\" NS doc-width +. +.eo +.de doc-get-arg-width +. nr doc-width \w'\f[CR]\*[doc-arg\$1]' +. ie (\n[doc-width] >= \n[doc-fixed-width]) \{\ +. ie (\n[doc-width] % \n[doc-fixed-width]) \ +. nr doc-width ((\n[doc-width] / \n[doc-fixed-width]) + 1) +. el \ +. nr doc-width (\n[doc-width] / \n[doc-fixed-width]) +. \} +. el \{\ +. ie \n[doc-width] \ +. nr doc-width 1 +. el \ +. nr doc-width 0 +. \} +.. +.ec +. +. +.\" NS Ql user macro +.\" NS quoted literal define +.\" NS +.\" NS modifies: +.\" NS doc-argXXX +.\" NS doc-arg-count +.\" NS doc-arg-ptr +.\" NS doc-macro-name +.\" NS doc-spaceXXX +.\" NS doc-typeXXX +.\" NS doc-quote-left +.\" NS doc-quote-right +.\" NS +.\" NS local variables: +.\" NS doc-reg-Ql +.\" NS doc-reg-Ql1 +.\" NS doc-reg-Ql2 +.\" NS +.\" NS width register 'Ql' set in doc-common +. +.eo +.de Ql +. if !\n[doc-arg-count] \{\ +. ie \n[.$] \{\ +. ds doc-macro-name Ql +. doc-parse-args \$@ +. \} +. el \ +. tm Usage: .Ql argument ... (#\n[.c]) +. \} +. +. nr doc-reg-Ql (\n[doc-arg-ptr] + 1) +. doc-get-arg-width \n[doc-reg-Ql] +. +. \" don't use quotes if we have more than two succeeding string +. \" arguments +. nr doc-reg-Ql +1 +. if (\n[doc-arg-count] >= \n[doc-reg-Ql]) \ +. if (\n[doc-type\n[doc-reg-Ql]] == 2) \ +. nr doc-width 3 +. +. \" make a difference in quotation style for strings longer +. \" than two characters +. ie (\n[doc-width] > 2) \ +. Li +. el \{\ +. ie \n[doc-arg-ptr] \{\ +. \" we replace 'Ql' with 'Li' +. ds doc-arg\n[doc-arg-ptr] Li +. nr doc-arg-ptr -1 +. \} +. el \{\ +. \" if .Ql has been called directly, we must shift all elements in +. \" the argument vector to the right so that we can insert 'Li' +. nr doc-reg-Ql \n[doc-arg-count] +. nr doc-reg-Ql1 (\n[doc-arg-count] + 1) +. while \n[doc-reg-Ql] \{\ +. rn doc-arg\n[doc-reg-Ql] doc-arg\n[doc-reg-Ql1] +. rnn doc-type\n[doc-reg-Ql] doc-type\n[doc-reg-Ql1] +. rn doc-space\n[doc-reg-Ql] doc-space\n[doc-reg-Ql1] +. nr doc-reg-Ql -1 +. nr doc-reg-Ql1 -1 +. \} +. ds doc-arg1 Li +. nr doc-type1 1 +. ds doc-space1 +. nr doc-arg-count +1 +. \} +. +. ds doc-quote-left "\*[doc-left-singlequote] +. ds doc-quote-right "\*[doc-right-singlequote] +. doc-enclose-string +. \} +.. +.ec +. +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/mdoc/doc-nroff b/tmac/mdoc/doc-nroff new file mode 100644 index 0000000..5167af3 --- /dev/null +++ b/tmac/mdoc/doc-nroff @@ -0,0 +1,229 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" 3. [Deleted. See +.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] +.\" 4. Neither the name of the University nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" +.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +.\" PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR +.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)doc-nroff 8.1 (Berkeley) 06/08/93 +. +. +.\" nroff devices can't change the type size; this value is notional. +.nr S 10 +. +.\" Map monospaced fonts to standard styles. +.ftr CR R +.ftr CI I +.ftr CB B +.ftr CBI BI +. +.\" the 'doc-xx-font' strings must not be empty! +. +.ds doc-page-topic-font \f[I] +.ds doc-page-section-font \f[R] +.ds doc-Ad-font \f[I] +.ds doc-Ar-font \f[I] +.ds doc-Cm-font \f[B] +.ds doc-Em-font \f[I] +.ds doc-Er-font \f[R] +.ds doc-Ev-font \f[R] +.ds doc-Fa-font \f[I] +.ds doc-Fd-font \f[B] +.ds doc-Fl-font \f[B] +.ds doc-Fn-font \f[B] +.ds doc-Ft-font \f[I] +.ds doc-Ic-font \f[B] +.ds doc-Li-font \f[B] +.ds doc-Lk-font \f[R]\" +.ds doc-Me-font \f[B] +.ds doc-Nm-font \f[B] +.ds doc-No-font \f[R] +.ds doc-Pa-font \f[I] +.ds doc-Sh-font \f[\*[HF]]\" +.ds doc-Sy-font \f[B] +.ds doc-Tn-font \f[R] +.ds doc-Va-font \f[I] +.ds doc-Xr-font \f[I] +. +.ds doc-left-parenthesis \f[R](\f[] +.ds doc-right-parenthesis \f[R])\f[] +.ds lp \f[R](\f[] +.ds rp \f[R])\f[] +.ds doc-left-bracket \f[R][\f[] +.ds doc-right-bracket \f[R]]\f[] +. +.\" miscellaneous +.nr doc-paragraph-space 1v +. +.nr doc-digit-width \w'\0\0'u +.nr doc-fixed-width \w'0' +. +. +.\" NS doc-display-vertical global register +.\" NS vertical space between list elements etc. +. +.nr doc-display-vertical 0 +. +. +.\" NS doc-setup-page-layout macro +.\" NS set up page layout +.\" NS +.\" NS modifies: +.\" NS doc-display-vertical +.\" NS doc-line-length +. +.eo +.de doc-setup-page-layout +. ie r LL \ +. ll \n[LL]u +. el \ +. ll 78n +. +. ie r LT \ +. lt \n[LT]u +. el \ +. lt \n[.l]u +. +. po 0i +. +. nr doc-display-vertical 1v +. nr doc-line-length \n[.l] +.. +.ec +. +.ds doc-left-singlequote \[oq] +.ds doc-right-singlequote \[cq] +. +.\" the following strings are 'official' +.ds <= \[<=] +.ds >= \[>=] +.ds aa \[aa] +.ds ga \[ga] +.ds q \[dq] +.ds Lq \[lq] +.ds Rq \[rq] +.ds Ne \[!=] +.ds Le \[<=] +.ds Ge \[>=] +.ds Lt < +.ds Gt > +.ds Pm \[+-] +.ds Na \f[I]NaN\f[] +.ds Ba \f[R]|\f[] +.ds Am & +. +.\" Unicode TTYs have all glyph forms; for other TTY character sets we +.\" need character representations which are different from GNU troff's +.\" standard forms. +.ie '\*[.T]'utf8' \{\ +. ds ua \[ua] +. ds Pi \[*p] +. ds If \[if] +.\} +.el \{\ +. ds ua ^ +. ds Pi pi +. ds If infinity +.\} +. +. +.\" NS doc-get-width macro +.\" NS computes the width of a string as a multiple of +.\" NS 'doc-fixed-width': '.doc-get-width string' +.\" NS +.\" NS modifies: +.\" NS doc-width +. +.eo +.de doc-get-width +. nr doc-width \w'\$1' +. ie (\n[doc-width] >= \n[doc-fixed-width]) \{\ +. ie (\n[doc-width] % \n[doc-fixed-width]) \ +. nr doc-width ((\n[doc-width] / \n[doc-fixed-width]) + 1) +. el \ +. nr doc-width (\n[doc-width] / \n[doc-fixed-width]) +. \} +. el \ +. nr doc-width 0 +.. +.ec +. +. +.\" NS doc-get-arg-width macro +.\" NS computes the width of an argument as a multiple of +.\" NS 'doc-fixed-width': '.doc-get-arg-width arg-index' +.\" NS +.\" NS modifies: +.\" NS doc-width +. +.eo +.de doc-get-arg-width +. nr doc-width \w'\*[doc-arg\$1]' +. ie (\n[doc-width] >= \n[doc-fixed-width]) \{\ +. ie (\n[doc-width] % \n[doc-fixed-width]) \ +. nr doc-width ((\n[doc-width] / \n[doc-fixed-width]) + 1) +. el \ +. nr doc-width (\n[doc-width] / \n[doc-fixed-width]) +. \} +. el \ +. nr doc-width 0 +.. +.ec +. +. +.\" NS Ql user macro +.\" NS quoted literal define +.\" NS +.\" NS modifies: +.\" NS doc-macro-name +.\" NS doc-quote-left +.\" NS doc-quote-right +.\" NS +.\" NS width register 'Ql' set in doc-common +. +.eo +.de Ql +. if !\n[doc-arg-count] \{\ +. ie \n[.$] \ +. ds doc-macro-name Ql +. el \ +. tm Usage: .Ql argument ... (#\n[.c]) +. \} +. +. ds doc-quote-left "\*[doc-left-singlequote] +. ds doc-quote-right "\*[doc-right-singlequote] +. +. doc-enclose-string \$@ +.. +.ec +. +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/mdoc/doc-syms b/tmac/mdoc/doc-syms new file mode 100644 index 0000000..8f5998c --- /dev/null +++ b/tmac/mdoc/doc-syms @@ -0,0 +1,908 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" 3. [Deleted. See +.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] +.\" 4. Neither the name of the University nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" +.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +.\" PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR +.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)doc-syms 8.1 (Berkeley) 06/08/93 +. +. +.\" NS Ux user macro +.\" NS format Unix +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS +.\" NS local variable: +.\" NS doc-str-Ux +.\" NS +.\" NS width register 'Ux' defined in doc-common +. +.eo +.de Ux +. nr doc-curr-font \n[.f] +. ds doc-str-Ux \f[\n[doc-curr-font]] +. +. if !\n[doc-arg-count] \ +. if \n[.$] \{\ +. ds doc-macro-name Ux +. doc-parse-args \$@ +. \} +. +. \" replace current argument with result +. ds doc-arg\n[doc-arg-ptr] Unix\*[doc-str-Ux] +. rm doc-str-Ux +. nr doc-type\n[doc-arg-ptr] 2 +. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +. +. \" recompute space vector for remaining arguments +. nr doc-num-args (\n[doc-arg-count] - \n[doc-arg-ptr]) +. nr doc-arg-count \n[doc-arg-ptr] +. if \n[doc-num-args] \ +. doc-parse-space-vector +. +. doc-print-recursive +.. +.ec +. +. +.\" NS Bx user macro +.\" NS print BSD (fix smaller nroff version) +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS +.\" NS local variable: +.\" NS doc-str-Bx +.\" NS doc-str-Bx1 +.\" NS doc-str-Bx-XXX +.\" NS +.\" NS width register 'Bx' defined in doc-common +. +.ds doc-str-Bx-Reno \-Reno +.ds doc-str-Bx-reno \-Reno +.ds doc-str-Bx-Tahoe \-Tahoe +.ds doc-str-Bx-tahoe \-Tahoe +.ds doc-str-Bx-Lite \-Lite +.ds doc-str-Bx-lite \-Lite +.ds doc-str-Bx-Lite2 \-Lite2 +.ds doc-str-Bx-lite2 \-Lite2 +. +.eo +.de Bx +. nr doc-curr-font \n[.f] +. ds doc-str-Bx \f[\n[doc-curr-font]] +. +. \" default value if no argument +. ds doc-str-Bx1 BSD\*[doc-str-Bx] +. +. if !\n[doc-arg-count] \ +. if \n[.$] \{\ +. ds doc-macro-name Bx +. doc-parse-args \$@ +. \} +. +. if (\n[doc-arg-count] > \n[doc-arg-ptr]) \{\ +. nr doc-arg-ptr +1 +. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +. ie "\*[doc-arg\n[doc-arg-ptr]]"-alpha" \ +. as doc-str-Bx1 " (currently in alpha test) +. el \{ .ie "\*[doc-arg\n[doc-arg-ptr]]"-beta" \ +. as doc-str-Bx1 " (currently in beta test) +. el \{ .ie "\*[doc-arg\n[doc-arg-ptr]]"-devel" \ +. as doc-str-Bx1 " (currently under development) +. el \{\ +. ds doc-str-Bx1 \&\*[doc-arg\n[doc-arg-ptr]]\^ +. as doc-str-Bx1 BSD\*[doc-str-Bx] +. +. if (\n[doc-arg-count] > \n[doc-arg-ptr]) \{\ +. nr doc-arg-ptr +1 +. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +. ie d doc-str-Bx-\*[doc-arg\n[doc-arg-ptr]] \ +. as doc-str-Bx1 "\*[doc-str-Bx-\*[doc-arg\n[doc-arg-ptr]]] +. el \ +. nr doc-arg-ptr -1 +. \} +. el \ +. nr doc-arg-ptr -1 +. \} +. el \ +. nr doc-arg-ptr -1 +. \}\}\}\}\} +. el \ +. nr doc-arg-ptr -1 +. \} +. +. \" replace current argument with result +. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Bx1] +. nr doc-type\n[doc-arg-ptr] 2 +. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +. +. \" recompute space vector for remaining arguments +. nr doc-num-args (\n[doc-arg-count] - \n[doc-arg-ptr]) +. nr doc-arg-count \n[doc-arg-ptr] +. if \n[doc-num-args] \ +. doc-parse-space-vector +. +. doc-print-recursive +.. +.ec +. +. +.\" NS Ud user macro (not parsed, not callable) +.\" NS print "currently under development" (HISTORY section) +.\" NS +.\" NS width register 'Ud' defined in doc-common +. +.eo +.de Ud +. nop \¤tly under development. +.. +.ec +. +. +.\" NS At user macro +.\" NS print AT&T UNIX +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS +.\" NS local variable: +.\" NS doc-str-At +.\" NS doc-str-At1 +.\" NS doc-str-At-XXX +.\" NS +.\" NS width register 'At' defined in doc-common +. +.eo +.ds doc-str-At-32v \&Version\~7 +.as doc-str-At-32v " AT&T UNIX\*[doc-str-At]/32V +.ds doc-str-At-v1 \&Version\~1 +.as doc-str-At-v1 " AT&T UNIX\*[doc-str-At] +.ds doc-str-At-v2 \&Version\~2 +.as doc-str-At-v2 " AT&T UNIX\*[doc-str-At] +.ds doc-str-At-v3 \&Version\~3 +.as doc-str-At-v3 " AT&T UNIX\*[doc-str-At] +.ds doc-str-At-v4 \&Version\~4 +.as doc-str-At-v4 " AT&T UNIX\*[doc-str-At] +.ds doc-str-At-v5 \&Version\~5 +.as doc-str-At-v5 " AT&T UNIX\*[doc-str-At] +.ds doc-str-At-v6 \&Version\~6 +.as doc-str-At-v6 " AT&T UNIX\*[doc-str-At] +.ds doc-str-At-v7 \&Version\~7 +.as doc-str-At-v7 " AT&T UNIX\*[doc-str-At] +.ds doc-str-At-III AT&T\*[doc-str-At] System\~III +.as doc-str-At-III " UNIX\*[doc-str-At] +.ds doc-str-At-V AT&T\*[doc-str-At] System\~V +.as doc-str-At-V " UNIX\*[doc-str-At] +.ds doc-str-At-V.1 AT&T\*[doc-str-At] System\~V Release\~1 +.as doc-str-At-V.1 " UNIX\*[doc-str-At] +.ds doc-str-At-V.2 AT&T\*[doc-str-At] System\~V Release\~2 +.as doc-str-At-V.2 " UNIX\*[doc-str-At] +.ds doc-str-At-V.3 AT&T\*[doc-str-At] System\~V Release\~3 +.as doc-str-At-V.3 " UNIX\*[doc-str-At] +.ds doc-str-At-V.4 AT&T\*[doc-str-At] System\~V Release\~4 +.as doc-str-At-V.4 " UNIX\*[doc-str-At] +. +.de At +. nr doc-curr-font \n[.f] +. ds doc-str-At \f[\n[doc-curr-font]] +. +. \" default value if no argument +. ds doc-str-At1 AT&T UNIX\*[doc-str-At] +. +. if !\n[doc-arg-count] \ +. if \n[.$] \{\ +. ds doc-macro-name At +. doc-parse-args \$@ +. \} +. +. if (\n[doc-arg-count] > \n[doc-arg-ptr]) \{\ +. nr doc-arg-ptr +1 +. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +. ie \A'\*[doc-arg\n[doc-arg-ptr]]' \{\ +. ie d doc-str-At-\*[doc-arg\n[doc-arg-ptr]] \ +. ds doc-str-At1 "\*[doc-str-At-\*[doc-arg\n[doc-arg-ptr]]] +. el \{\ +. tmc mdoc warning: .At: Unknown AT&T UNIX version +. tm1 " '\*[doc-arg\n[doc-arg-ptr]]' (#\n[.c]) +. nr doc-arg-ptr -1 +. \}\} +. el \ +. nr doc-arg-ptr -1 +. \} +. el \ +. nr doc-arg-ptr -1 +. \} +. +. \" replace current argument with result +. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-At1] +. nr doc-type\n[doc-arg-ptr] 2 +. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +. +. \" recompute space vector for remaining arguments +. nr doc-num-args (\n[doc-arg-count] - \n[doc-arg-ptr]) +. nr doc-arg-count \n[doc-arg-ptr] +. if \n[doc-num-args] \ +. doc-parse-space-vector +. +. doc-print-recursive +.. +.ec +. +. +.\" NS Dx user macro +.\" NS print DragonFly +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS +.\" NS local variable: +.\" NS doc-str-Dx +.\" NS doc-str-Dx1 +.\" NS +.\" NS width register 'Dx' defined in doc-common +. +.\" we use the doc-operating-system-DragonFly-* strings defined in +.\" doc-common +. +.eo +.de Dx +. nr doc-curr-font \n[.f] +. ds doc-str-Dx \f[\n[doc-curr-font]] +. +. \" default value if no argument +. ds doc-str-Dx1 \%DragonFly\*[doc-str-Dx] +. +. if !\n[doc-arg-count] \ +. if \n[.$] \{\ +. ds doc-macro-name Dx +. doc-parse-args \$@ +. \} +. +. if (\n[doc-arg-count] > \n[doc-arg-ptr]) \{\ +. nr doc-arg-ptr +1 +. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +. ie \A'\*[doc-arg\n[doc-arg-ptr]]' \{\ +. ie d doc-operating-system-DragonFly-\*[doc-arg\n[doc-arg-ptr]] \ +. as doc-str-Dx1 \~\*[doc-operating-system-DragonFly-\*[doc-arg\n[doc-arg-ptr]]] +. el \{\ +. tmc mdoc warning: .Dx: Unknown DragonFly version +. tm1 " '\*[doc-arg\n[doc-arg-ptr]]' (#\n[.c]) +. as doc-str-Dx1 \~\*[doc-arg\n[doc-arg-ptr]] +. \}\} +. el \ +. as doc-str-Dx1 \~\*[doc-arg\n[doc-arg-ptr]] +. \} +. el \ +. nr doc-arg-ptr -1 +. \} +. +. \" replace current argument with result +. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Dx1] +. nr doc-type\n[doc-arg-ptr] 2 +. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +. +. \" recompute space vector for remaining arguments +. nr doc-num-args (\n[doc-arg-count] - \n[doc-arg-ptr]) +. nr doc-arg-count \n[doc-arg-ptr] +. if \n[doc-num-args] \ +. doc-parse-space-vector +. +. doc-print-recursive +.. +.ec +. +. +.\" NS Fx user macro +.\" NS print FreeBSD +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS +.\" NS local variable: +.\" NS doc-str-Fx +.\" NS doc-str-Fx1 +.\" NS +.\" NS width register 'Fx' defined in doc-common +. +.\" we use the doc-operating-system-FreeBSD-* strings defined in +.\" doc-common +. +.eo +.de Fx +. nr doc-curr-font \n[.f] +. ds doc-str-Fx \f[\n[doc-curr-font]] +. +. \" default value if no argument +. ds doc-str-Fx1 \%FreeBSD\*[doc-str-Fx] +. +. if !\n[doc-arg-count] \ +. if \n[.$] \{\ +. ds doc-macro-name Fx +. doc-parse-args \$@ +. \} +. +. if (\n[doc-arg-count] > \n[doc-arg-ptr]) \{\ +. nr doc-arg-ptr +1 +. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +. ie \A'\*[doc-arg\n[doc-arg-ptr]]' \{\ +. ie d doc-operating-system-FreeBSD-\*[doc-arg\n[doc-arg-ptr]] \ +. as doc-str-Fx1 \~\*[doc-operating-system-FreeBSD-\*[doc-arg\n[doc-arg-ptr]]] +. el \{\ +. tmc mdoc warning: .Fx: Unknown FreeBSD version +. tm1 " '\*[doc-arg\n[doc-arg-ptr]]' (#\n[.c]) +. as doc-str-Fx1 \~\*[doc-arg\n[doc-arg-ptr]] +. \}\} +. el \ +. as doc-str-Fx1 \~\*[doc-arg\n[doc-arg-ptr]] +. \} +. el \ +. nr doc-arg-ptr -1 +. \} +. +. \" replace current argument with result +. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Fx1] +. nr doc-type\n[doc-arg-ptr] 2 +. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +. +. \" recompute space vector for remaining arguments +. nr doc-num-args (\n[doc-arg-count] - \n[doc-arg-ptr]) +. nr doc-arg-count \n[doc-arg-ptr] +. if \n[doc-num-args] \ +. doc-parse-space-vector +. +. doc-print-recursive +.. +.ec +. +. +.\" NS Nx user macro +.\" NS print NetBSD +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS +.\" NS local variable: +.\" NS doc-str-Nx +.\" NS doc-str-Nx1 +.\" NS +.\" NS width register 'Nx' defined in doc-common +. +.\" we use the doc-operating-system-NetBSD-* strings defined in +.\" doc-common +. +.eo +.de Nx +. nr doc-curr-font \n[.f] +. ds doc-str-Nx \f[\n[doc-curr-font]] +. +. \" default value if no argument +. ds doc-str-Nx1 \%Net +. as doc-str-Nx1 BSD\*[doc-str-Nx] +. +. if !\n[doc-arg-count] \ +. if \n[.$] \{\ +. ds doc-macro-name Nx +. doc-parse-args \$@ +. \} +. +. if (\n[doc-arg-count] > \n[doc-arg-ptr]) \{\ +. nr doc-arg-ptr +1 +. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +. ie \A'\*[doc-arg\n[doc-arg-ptr]]' \{\ +. ie d doc-operating-system-NetBSD-\*[doc-arg\n[doc-arg-ptr]] \ +. as doc-str-Nx1 \~\*[doc-operating-system-NetBSD-\*[doc-arg\n[doc-arg-ptr]]] +. el \{\ +. tmc mdoc warning: .Nx: Unknown NetBSD version +. tm1 " '\*[doc-arg\n[doc-arg-ptr]]' (#\n[.c]) +. as doc-str-Nx1 \~\*[doc-arg\n[doc-arg-ptr]] +. \}\} +. el \ +. as doc-str-Nx1 \~\*[doc-arg\n[doc-arg-ptr]] +. \} +. el \ +. nr doc-arg-ptr -1 +. \} +. +. \" replace current argument with result +. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Nx1] +. nr doc-type\n[doc-arg-ptr] 2 +. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +. +. \" recompute space vector for remaining arguments +. nr doc-num-args (\n[doc-arg-count] - \n[doc-arg-ptr]) +. nr doc-arg-count \n[doc-arg-ptr] +. if \n[doc-num-args] \ +. doc-parse-space-vector +. +. doc-print-recursive +.. +.ec +. +. +.\" NS Ox user macro +.\" NS print OpenBSD +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS +.\" NS local variable: +.\" NS doc-str-Ox +.\" NS doc-str-Ox1 +.\" NS +.\" NS width register 'Ox' defined in doc-common +. +.eo +.de Ox +. nr doc-curr-font \n[.f] +. ds doc-str-Ox \f[\n[doc-curr-font]] +. +. \" default value if no argument +. ds doc-str-Ox1 \%OpenBSD\*[doc-str-Ox] +. +. if !\n[doc-arg-count] \ +. if \n[.$] \{\ +. ds doc-macro-name Ox +. doc-parse-args \$@ +. \} +. +. if (\n[doc-arg-count] > \n[doc-arg-ptr]) \{\ +. nr doc-arg-ptr +1 +. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \ +. as doc-str-Ox1 \~\*[doc-arg\n[doc-arg-ptr]] +. el \ +. nr doc-arg-ptr -1 +. \} +. +. \" replace current argument with result +. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Ox1] +. nr doc-type\n[doc-arg-ptr] 2 +. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +. +. \" recompute space vector for remaining arguments +. nr doc-num-args (\n[doc-arg-count] - \n[doc-arg-ptr]) +. nr doc-arg-count \n[doc-arg-ptr] +. if \n[doc-num-args] \ +. doc-parse-space-vector +. +. doc-print-recursive +.. +.ec +. +. +.\" NS Bsx user macro +.\" NS print BSD/OS +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS +.\" NS local variable: +.\" NS doc-str-Bsx +.\" NS doc-str-Bsx1 +.\" NS +.\" NS width register 'Bsx' defined in doc-common +. +.eo +.de Bsx +. nr doc-curr-font \n[.f] +. ds doc-str-Bsx \f[\n[doc-curr-font]] +. +. \" default value if no argument +. ds doc-str-Bsx1 BSD/OS\*[doc-str-Bsx] +. +. if !\n[doc-arg-count] \ +. if \n[.$] \{\ +. ds doc-macro-name Bsx +. doc-parse-args \$@ +. \} +. +. if (\n[doc-arg-count] > \n[doc-arg-ptr]) \{\ +. nr doc-arg-ptr +1 +. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \ +. as doc-str-Bsx1 \~\*[doc-arg\n[doc-arg-ptr]] +. el \ +. nr doc-arg-ptr -1 +. \} +. +. \" replace current argument with result +. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Bsx1] +. nr doc-type\n[doc-arg-ptr] 2 +. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +. +. \" recompute space vector for remaining arguments +. nr doc-num-args (\n[doc-arg-count] - \n[doc-arg-ptr]) +. nr doc-arg-count \n[doc-arg-ptr] +. if \n[doc-num-args] \ +. doc-parse-space-vector +. +. doc-print-recursive +.. +.ec +. +. +.\" The Bt macro should go away now +. +.\" NS Bt user macro (not parsed, not callable) +.\" NS print "is currently in beta test." (HISTORY section) +.\" NS +.\" NS width register 'Bt' defined in doc-common +. +.eo +.de Bt +. nop \&is currently in beta test. +.. +.ec +. +. +.\" NS Px user macro +.\" NS print POSIX +. +.eo +.ds Px \%POSIX +.ec +. +. +.\" NS Ai user macro +.\" NS print ANSI +. +.eo +.ds Ai \%ANSI +.ec +. +. +.\" NS St user macro +.\" NS standards (posix, ansi - formal standard names) +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS +.\" NS local variable: +.\" NS doc-reg-St +.\" NS doc-str-St +.\" NS doc-str-St1 +.\" NS doc-str-St-XXX +.\" NS +.\" NS width register 'St' defined in doc-common +. +.\" ANSI/ISO C +.eo +.ds doc-str-St--ansiC-89 \*[Ai] \*[doc-str-St]X\^3.159-1989 +.as doc-str-St--ansiC-89 " (\*[Lq]\)\*[Ai]\~C89\*[doc-str-St]\*[Rq]) +.als doc-str-St--ansiC doc-str-St--ansiC-89 +.ds doc-str-St--isoC ISO/IEC\*[doc-str-St] 9899:1990 +.as doc-str-St--isoC " (\*[Lq]ISO\~C\^90\*[doc-str-St]\*[Rq]) +.als doc-str-St--isoC-90 doc-str-St--isoC +.ds doc-str-St--isoC-2011 ISO/IEC\*[doc-str-St] 9899:2011 +.as doc-str-St--isoC-2011 " (\*[Lq]ISO\~C\^11\*[doc-str-St]\*[Rq]) +.ds doc-str-St--isoC-99 ISO/IEC\*[doc-str-St] 9899:1999 +.as doc-str-St--isoC-99 " (\*[Lq]ISO\~C\^99\*[doc-str-St]\*[Rq]) +.ds doc-str-St--isoC-amd1 ISO/IEC\*[doc-str-St] 9899/AMD1:1995 +.as doc-str-St--isoC-amd1 " (\*[Lq]ISO\~C\^90\*[doc-str-St], Amendment 1\*[Rq]) +.ds doc-str-St--isoC-tcor1 ISO/IEC\*[doc-str-St] 9899/TCOR1:1994 +.as doc-str-St--isoC-tcor1 " (\*[Lq]ISO\~C\^90\*[doc-str-St], Technical Corrigendum 1\*[Rq]) +.ds doc-str-St--isoC-tcor2 ISO/IEC\*[doc-str-St] 9899/TCOR2:1995 +.as doc-str-St--isoC-tcor2 " (\*[Lq]ISO\~C\^90\*[doc-str-St], Technical Corrigendum 2\*[Rq]) +.ec +. +.\" POSIX Part 1: System API +.eo +.ds doc-str-St--p1003.1 \%IEEE\*[doc-str-St] Std 1003.1 +.as doc-str-St--p1003.1 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +.ds doc-str-St--p1003.1b \%IEEE\*[doc-str-St] Std 1003.1b +.as doc-str-St--p1003.1b " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +.ds doc-str-St--p1003.1-88 \%IEEE\*[doc-str-St] Std 1003.1-1988 +.as doc-str-St--p1003.1-88 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +.ds doc-str-St--p1003.1-90 ISO/IEC\*[doc-str-St] 9945-1:1990 +.as doc-str-St--p1003.1-90 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +.als doc-str-St--iso9945-1-90 doc-str-St--p1003.1-90 +.ds doc-str-St--p1003.1b-93 \%IEEE\*[doc-str-St] Std 1003.1b-1993 +.as doc-str-St--p1003.1b-93 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +.ds doc-str-St--p1003.1c-95 \%IEEE\*[doc-str-St] Std 1003.1c-1995 +.as doc-str-St--p1003.1c-95 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +.ds doc-str-St--p1003.1i-95 \%IEEE\*[doc-str-St] Std 1003.1i-1995 +.as doc-str-St--p1003.1i-95 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +.ds doc-str-St--p1003.1-96 ISO/IEC\*[doc-str-St] 9945-1:1996 +.as doc-str-St--p1003.1-96 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +.als doc-str-St--iso9945-1-96 doc-str-St--p1003.1-96 +.ds doc-str-St--p1003.1g-2000 \%IEEE\*[doc-str-St] Std 1003.1g-2000 +.as doc-str-St--p1003.1g-2000 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +.ds doc-str-St--p1003.1-2001 \%IEEE\*[doc-str-St] Std 1003.1-2001 +.as doc-str-St--p1003.1-2001 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +.ds doc-str-St--p1003.1-2004 \%IEEE\*[doc-str-St] Std 1003.1-2004 +.as doc-str-St--p1003.1-2004 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +.ds doc-str-St--p1003.1-2008 \%IEEE\*[doc-str-St] Std 1003.1-2008 +.as doc-str-St--p1003.1-2008 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +.ec +. +.\" POSIX Part 2: Shell and Utilities +.eo +.ds doc-str-St--p1003.2 \%IEEE\*[doc-str-St] Std 1003.2 +.as doc-str-St--p1003.2 " (\*[Lq]\)\*[Px]\*[doc-str-St].2\*[Rq]) +.ds doc-str-St--p1003.2-92 \%IEEE\*[doc-str-St] Std 1003.2-1992 +.as doc-str-St--p1003.2-92 " (\*[Lq]\)\*[Px]\*[doc-str-St].2\*[Rq]) +.ds doc-str-St--p1003.2a-92 \%IEEE\*[doc-str-St] Std 1003.2a-1992 +.as doc-str-St--p1003.2a-92 " (\*[Lq]\)\*[Px]\*[doc-str-St].2\*[Rq]) +.ds doc-str-St--iso9945-2-93 ISO/IEC\*[doc-str-St] 9945-2:1993 +.as doc-str-St--iso9945-2-93 " (\*[Lq]\)\*[Px]\*[doc-str-St].2\*[Rq]) +.ec +. +.\" X/Open +.eo +.ds doc-str-St--susv1 Version\~1 of the Single UNIX\*[doc-str-St] Specification +.as doc-str-St--susv1 " (\*[Lq]SUSv1\*[doc-str-St]\*[Rq]) +.ds doc-str-St--susv2 Version\~2 of the Single UNIX\*[doc-str-St] Specification +.as doc-str-St--susv2 " (\*[Lq]SUSv2\*[doc-str-St]\*[Rq]) +.ds doc-str-St--susv3 Version\~3 of the Single UNIX\*[doc-str-St] Specification +.as doc-str-St--susv3 " (\*[Lq]SUSv3\*[doc-str-St]\*[Rq]) +.ds doc-str-St--susv4 Version\~4 of the Single UNIX\*[doc-str-St] Specification +.as doc-str-St--susv4 " (\*[Lq]SUSv4\*[doc-str-St]\*[Rq]) +.ds doc-str-St--svid4 System\~V Interface Definition, Fourth Edition +.as doc-str-St--svid4 " (\*[Lq]SVID\*[doc-str-St]\^4\*[Rq]) +.ds doc-str-St--xbd5 X/Open\*[doc-str-St] Base Definitions Issue\~5 +.as doc-str-St--xbd5 " (\*[Lq]XBD\*[doc-str-St]\^5\*[Rq]) +.ds doc-str-St--xcu5 X/Open\*[doc-str-St] Commands and Utilities Issue\~5 +.as doc-str-St--xcu5 " (\*[Lq]XCU\*[doc-str-St]\^5\*[Rq]) +.ds doc-str-St--xcurses4.2 X/Open\*[doc-str-St] Curses Issue\~4, Version\~2 +.as doc-str-St--xcurses4.2 " (\*[Lq]XCURSES\*[doc-str-St]\^4.2\*[Rq]) +.ds doc-str-St--xns5 X/Open\*[doc-str-St] Networking Services Issue\~5 +.as doc-str-St--xns5 " (\*[Lq]XNS\*[doc-str-St]\^5\*[Rq]) +.ds doc-str-St--xns5.2 X/Open\*[doc-str-St] Networking Services Issue\~5.2 +.as doc-str-St--xns5.2 " (\*[Lq]XNS\*[doc-str-St]\^5.2\*[Rq]) +.ds doc-str-St--xpg3 X/Open\*[doc-str-St] Portability Guide Issue\~3 +.as doc-str-St--xpg3 " (\*[Lq]XPG\*[doc-str-St]\^3\*[Rq]) +.ds doc-str-St--xpg4 X/Open\*[doc-str-St] Portability Guide Issue\~4 +.as doc-str-St--xpg4 " (\*[Lq]XPG\*[doc-str-St]\^4\*[Rq]) +.ds doc-str-St--xpg4.2 X/Open\*[doc-str-St] Portability Guide Issue\~4, Version\~2 +.as doc-str-St--xpg4.2 " (\*[Lq]XPG\*[doc-str-St]\^4.2\*[Rq]) +.ds doc-str-St--xsh5 X/Open\*[doc-str-St] System Interfaces and Headers Issue\~5 +.as doc-str-St--xsh5 " (\*[Lq]XSH\*[doc-str-St]\^5\*[Rq]) +.ec +. +.\" Miscellaneous +.eo +.ds doc-str-St--ieee754 \%IEEE\*[doc-str-St] Std 754-1985 +.ds doc-str-St--ieee1275-94 \%IEEE\*[doc-str-St] Std 1275-1994 +.as doc-str-St--ieee1275-94 " (\*[Lq]Open Firmware\*[doc-str-St]\*[Rq]) +.ds doc-str-St--iso8601 ISO\*[doc-str-St] 8601 +.ds doc-str-St--iso8802-3 ISO/IEC\*[doc-str-St] 8802-3:1989 +.ec +. +.eo +.de St +. if !\n[doc-arg-count] \{\ +. ie \n[.$] \{\ +. ds doc-macro-name St +. doc-parse-args \$@ +. \} +. el \ +. doc-St-usage +. \} +. +. if !\n[doc-arg-count] \ +. return +. +. nr doc-arg-ptr +1 +. ie (\n[doc-arg-count] >= \n[doc-arg-ptr]) \{\ +. nr doc-curr-font \n[.f] +. ds doc-str-St \f[\n[doc-curr-font]] +. +. ds doc-str-St1 +. ie \A'\*[doc-arg\n[doc-arg-ptr]]' \{\ +. ie d doc-str-St-\*[doc-arg\n[doc-arg-ptr]] \ +. ds doc-str-St1 "\*[doc-str-St-\*[doc-arg\n[doc-arg-ptr]]] +. el \{\ +. tmc "mdoc warning: .St: Unknown standard abbreviation +. tm1 " '\*[doc-arg\n[doc-arg-ptr]]' (#\n[.c]) +. tm1 " Please refer to the groff_mdoc(7) manpage for a +. tm1 " list of available standard abbreviations. +. \}\} +. el \ +. doc-St-usage +. +. \" replacing argument with result +. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-St1] +. +. doc-print-recursive +. \} +. el \{\ +. doc-St-usage +. doc-reset-args +. \} +.. +.ec +. +. +.\" NS doc-St-usage macro +. +.eo +.de doc-St-usage +. tm1 "Usage: .St standard (#\n[.c]) +. tm1 " Please refer to the groff_mdoc(7) manpage for a list of +. tm1 " available standard abbreviations. +.. +.ec +. +. +.\" NS Lb user macro +.\" NS formal library names for LIBRARY sections +.\" NS +.\" NS modifies: +.\" NS doc-arg-ptr +.\" NS doc-curr-font +.\" NS doc-macro-name +.\" NS +.\" NS local variable: +.\" NS doc-reg-Lb +.\" NS doc-str-Lb +.\" NS doc-str-Lb1 +.\" NS doc-str-Lb-XXX +.\" NS +.\" NS width register 'Lb' defined in doc-common +. +.eo +.ds doc-str-Lb-libarchive Reading and Writing Streaming Archives Library (libarchive, \-larchive) +.ds doc-str-Lb-libarm ARM Architecture Library (libarm, \-larm) +.ds doc-str-Lb-libarm32 ARM32 Architecture Library (libarm32, \-larm32) +.ds doc-str-Lb-libbluetooth Bluetooth Library (libbluetooth, \-lbluetooth) +.ds doc-str-Lb-libbsm Basic Security Module Library (libbsm, \-lbsm) +.ds doc-str-Lb-libc Standard C\~Library (libc, \-lc) +.ds doc-str-Lb-libc_r Reentrant C\~Library (libc_r, \-lc_r) +.ds doc-str-Lb-libcalendar Calendar Arithmetic Library (libcalendar, \-lcalendar) +.ds doc-str-Lb-libcam Common Access Method User Library (libcam, \-lcam) +.ds doc-str-Lb-libcdk Curses Development Kit Library (libcdk, \-lcdk) +.ds doc-str-Lb-libcipher FreeSec Crypt Library (libcipher, \-lcipher) +.ds doc-str-Lb-libcompat Compatibility Library (libcompat, \-lcompat) +.ds doc-str-Lb-libcrypt Crypt Library (libcrypt, \-lcrypt) +.ds doc-str-Lb-libcurses Curses Library (libcurses, \-lcurses) +.ds doc-str-Lb-libdevinfo Device and Resource Information Utility Library (libdevinfo, \-ldevinfo) +.ds doc-str-Lb-libdevstat Device Statistics Library (libdevstat, \-ldevstat) +.ds doc-str-Lb-libdisk Interface to Slice and Partition Labels Library (libdisk, \-ldisk) +.ds doc-str-Lb-libdwarf DWARF Access Library (libdwarf, \-ldwarf) +.ds doc-str-Lb-libedit Command Line Editor Library (libedit, \-ledit) +.ds doc-str-Lb-libelf ELF Access Library (libelf, \-lelf) +.ds doc-str-Lb-libevent Event Notification Library (libevent, \-levent) +.ds doc-str-Lb-libfetch File Transfer Library for URLs (libfetch, \-lfetch) +.ds doc-str-Lb-libform Curses Form Library (libform, \-lform) +.ds doc-str-Lb-libgeom Userland API Library for kernel GEOM subsystem (libgeom, \-lgeom) +.ds doc-str-Lb-libgpib General-Purpose Instrument Bus (GPIB) library (libgpib, \-lgpib) +.ds doc-str-Lb-libi386 i386 Architecture Library (libi386, \-li386) +.ds doc-str-Lb-libintl Internationalized Message Handling Library (libintl, \-lintl) +.ds doc-str-Lb-libipsec IPsec Policy Control Library (libipsec, \-lipsec) +.ds doc-str-Lb-libipx IPX Address Conversion Support Library (libipx, \-lipx) +.ds doc-str-Lb-libiscsi iSCSI protocol library (libiscsi, \-liscsi) +.ds doc-str-Lb-libjail Jail Library (libjail, \-ljail) +.ds doc-str-Lb-libkiconv Kernel side iconv library (libkiconv, \-lkiconv) +.ds doc-str-Lb-libkse N:M Threading Library (libkse, \-lkse) +.ds doc-str-Lb-libkvm Kernel Data Access Library (libkvm, \-lkvm) +.ds doc-str-Lb-libm Math Library (libm, \-lm) +.ds doc-str-Lb-libm68k m68k Architecture Library (libm68k, \-lm68k) +.ds doc-str-Lb-libmagic Magic Number Recognition Library (libmagic, \-lmagic) +.ds doc-str-Lb-libmd Message Digest (MD4, MD5, etc.) Support Library (libmd, \-lmd) +.ds doc-str-Lb-libmemstat Kernel Memory Allocator Statistics Library (libmemstat, \-lmemstat) +.ds doc-str-Lb-libmenu Curses Menu Library (libmenu, \-lmenu) +.ds doc-str-Lb-libnetgraph Netgraph User Library (libnetgraph, \-lnetgraph) +.ds doc-str-Lb-libnetpgp Netpgp signing, verification, encryption and decryption (libnetpgp, \-lnetpgp) +.ds doc-str-Lb-libossaudio OSS Audio Emulation Library (libossaudio, \-lossaudio) +.ds doc-str-Lb-libpam Pluggable Authentication Module Library (libpam, \-lpam) +.ds doc-str-Lb-libpcap Packet Capture Library (libpcap, \-lpcap) +.ds doc-str-Lb-libpci PCI Bus Access Library (libpci, \-lpci) +.ds doc-str-Lb-libpmc Performance Counters Library (libpmc, \-lpmc) +.ds doc-str-Lb-libposix \*[Px] \*[doc-str-Lb]Compatibility Library (libposix, \-lposix) +.ds doc-str-Lb-libprop Property Container Object Library (libprop, \-lprop) +.ds doc-str-Lb-libpthread \*[Px] \*[doc-str-Lb]Threads Library (libpthread, \-lpthread) +.ds doc-str-Lb-libpuffs puffs Convenience Library (libpuffs, \-lpuffs) +.ds doc-str-Lb-librefuse File System in Userspace Convenience Library (librefuse, \-lrefuse) +.ds doc-str-Lb-libresolv DNS Resolver Library (libresolv, \-lresolv) +.ds doc-str-Lb-librpcsec_gss RPC GSS-API Authentication Library (librpcsec_gss, \-lrpcsec_gss) +.ds doc-str-Lb-librpcsvc RPC Service Library (librpcsvc, \-lrpcsvc) +.ds doc-str-Lb-librt \*[Px] \*[doc-str-Lb]Real-time Library (librt, \-lrt) +.ds doc-str-Lb-libsdp Bluetooth Service Discovery Protocol User Library (libsdp, \-lsdp) +.ds doc-str-Lb-libssp Buffer Overflow Protection Library (libssp, \-lssp) +.ds doc-str-Lb-libSystem System Library (libSystem, \-lSystem) +.ds doc-str-Lb-libtermcap Termcap Access Library (libtermcap, \-ltermcap) +.ds doc-str-Lb-libterminfo Terminal Information Library (libterminfo, \-lterminfo) +.ds doc-str-Lb-libthr 1:1 Threading Library (libthr, \-lthr) +.ds doc-str-Lb-libufs UFS File System Access Library (libufs, \-lufs) +.ds doc-str-Lb-libugidfw File System Firewall Interface Library (libugidfw, \-lugidfw) +.ds doc-str-Lb-libulog User Login Record Library (libulog, \-lulog) +.ds doc-str-Lb-libusbhid USB Human Interface Devices Library (libusbhid, \-lusbhid) +.ds doc-str-Lb-libutil System Utilities Library (libutil, \-lutil) +.ds doc-str-Lb-libvgl Video Graphics Library (libvgl, \-lvgl) +.ds doc-str-Lb-libx86_64 x86_64 Architecture Library (libx86_64, \-lx86_64) +.ds doc-str-Lb-libz Compression Library (libz, \-lz) +.ec +. +.eo +.de Lb +. if !\n[doc-arg-count] \{\ +. ie \n[.$] \{\ +. ds doc-macro-name Lb +. doc-parse-args \$@ +. \} +. el \ +. tm Usage: .Lb library_name ... (#\n[.c]) +. \} +. +. if !\n[doc-arg-count] \ +. return +. +. nr doc-arg-ptr +1 +. ie (\n[doc-arg-count] >= \n[doc-arg-ptr]) \{\ +. nr doc-curr-font \n[.f] +. ds doc-str-Lb \f[\n[doc-curr-font]] +. +. ie d doc-str-Lb-\*[doc-arg\n[doc-arg-ptr]] \ +. ds doc-str-Lb1 "\*[doc-str-Lb-\*[doc-arg\n[doc-arg-ptr]]] +. el \{\ +. tmc "mdoc warning: .Lb: no description for library +. tm1 " '\*[doc-arg\n[doc-arg-ptr]]' available (#\n[.c]) +. ds doc-str-Lb1 library \*[Lq]\*[doc-arg\n[doc-arg-ptr]]\*[Rq] +. \} +. +. \" replacing argument with result +. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Lb1] +. +. if \n[doc-in-library-section] \ +. br +. doc-print-recursive +. if \n[doc-in-library-section] \ +. br +. \} +. el \{\ +. tm Usage: .Lb library_name ... (#\n[.c]) +. doc-reset-args +. \} +.. +.ec +. +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/me.tmac b/tmac/me.tmac new file mode 100644 index 0000000..639ed66 --- /dev/null +++ b/tmac/me.tmac @@ -0,0 +1,5 @@ +.\" -*- nroff -*- +.\" +.\" me.tmac +.\" +.do mso e.tmac diff --git a/tmac/ms.tmac b/tmac/ms.tmac new file mode 100644 index 0000000..6d49fdf --- /dev/null +++ b/tmac/ms.tmac @@ -0,0 +1,5 @@ +.\" -*- nroff -*- +.\" +.\" ms.tmac +.\" +.do mso s.tmac diff --git a/tmac/papersize.tmac b/tmac/papersize.tmac new file mode 100644 index 0000000..6d5ad14 --- /dev/null +++ b/tmac/papersize.tmac @@ -0,0 +1,167 @@ +.\" Set up GNU troff for various paper sizes. +.\" +.\" Usage: +.\" +.\" groff ... -dpaper= ... +.\" +.\" Possible values for 'format' are the same as the predefined +.\" 'papersize' values (see the groff_font man page) except a7-d7. An +.\" appended 'l' (ell) character denotes landscape orientation. +.\" Examples: 'a4', 'c3l', 'letterl'. +.\" +.\" Most output drivers need additional command-line switches '-p' and +.\" '-l' to override the default paper length and orientation as set in +.\" the driver specific DESC file. +.\" +.\" For example, use the following for PostScript output on A4 paper in +.\" landscape orientation: +.\" +.\" groff -Tps -dpaper=a4l -P-pa4 -P-l -ms foo.ms > foo.ps +. +.do nr *groff_papersize_tmac_C \n[.cp] +.cp 0 +. +.if d paper \{\ +. ds paper-a0-length 118.9c +. ds paper-a0-width 84.1c +. ds paper-a1-length 84.1c +. ds paper-a1-width 59.4c +. ds paper-a2-length 59.4c +. ds paper-a2-width 42c +. ds paper-a3-length 42c +. ds paper-a3-width 29.7c +. ds paper-a4-length 29.7c +. ds paper-a4-width 21c +. ds paper-a5-length 21c +. ds paper-a5-width 14.8c +. ds paper-a6-length 14.8c +. ds paper-a6-width 10.5c +. +. ds paper-b0-length 141.4c +. ds paper-b0-width 100c +. ds paper-b1-length 100c +. ds paper-b1-width 70.7c +. ds paper-b2-length 70.7c +. ds paper-b2-width 50c +. ds paper-b3-length 50c +. ds paper-b3-width 35.3c +. ds paper-b4-length 35.3c +. ds paper-b4-width 25c +. ds paper-b5-length 25c +. ds paper-b5-width 17.6c +. ds paper-b6-length 17.6c +. ds paper-b6-width 12.5c +. +. ds paper-c0-length 129.7c +. ds paper-c0-width 91.7c +. ds paper-c1-length 91.7c +. ds paper-c1-width 64.8c +. ds paper-c2-length 64.8c +. ds paper-c2-width 45.8c +. ds paper-c3-length 45.8c +. ds paper-c3-width 32.4c +. ds paper-c4-length 32.4c +. ds paper-c4-width 22.9c +. ds paper-c5-length 22.9c +. ds paper-c5-width 16.2c +. ds paper-c6-length 16.2c +. ds paper-c6-width 11.4c +. +. ds paper-d0-length 109.0c +. ds paper-d0-width 77.1c +. ds paper-d1-length 77.1c +. ds paper-d1-width 54.5c +. ds paper-d2-length 54.5c +. ds paper-d2-width 38.5c +. ds paper-d3-length 38.5c +. ds paper-d3-width 27.2c +. ds paper-d4-length 27.2c +. ds paper-d4-width 19.2c +. ds paper-d5-length 19.2c +. ds paper-d5-width 13.6c +. ds paper-d6-length 13.6c +. ds paper-d6-width 9.6c +. +. ds paper-letter-length 11i +. ds paper-letter-width 8.5i +. ds paper-legal-length 14i +. ds paper-legal-width 8.5i +. ds paper-tabloid-length 17i +. ds paper-tabloid-width 11i +. ds paper-ledger-length 11i +. ds paper-ledger-width 17i +. ds paper-statement-length 8.5i +. ds paper-statement-width 5.5i +. \" These dimensions for executive paper format are what all printer +. \" manufacturers use. +. ds paper-executive-length 10.5i +. ds paper-executive-width 7.25i +. +. ds paper-com10-length 9.5i +. ds paper-com10-width 4.125i +. ds paper-monarch-length 7.5i +. ds paper-monarch-width 3.875i +. ds paper-dl-length 22c +. ds paper-dl-width 11c +. +. \" Save the input parameter for a later diagnostic. +. ds paper-arg \*[paper]\" +. ds paper \*[paper-arg]\" +. stringdown paper +. ds paper-p \*[paper] +. ds paper-l \*[paper] +. length paper-n \*[paper] +. if (\n[paper-n] > 1) \{\ +. substring paper-p 0 -2 +. substring paper-l -1 -1 +. if !d paper-\*[paper-p]-length \{\ +. ds paper-p \*[paper] +. ds paper-l +. \} +. \} +. +. nr paper-w 0 +. +. ie d paper-\*[paper-p]-length \{\ +. ie '\*[paper-l]'l' \{\ +. pl \*[paper-\*[paper-p]-width] +. ll (\*[paper-\*[paper-p]-length] - 2i) +. \} +. el \{\ +. ie '\*[paper-l]'' \{\ +. pl \*[paper-\*[paper-p]-length] +. ll (\*[paper-\*[paper-p]-width] - 2i) +. \} +. el \ +. nr paper-w 1 +. \} +. \} +. el \ +. nr paper-w 1 +. +. ie \n[paper-w] \{\ +. tmc papersize.tmac: warning: ignoring unrecognized paper format +. tm1 " '\*[paper-arg]' +. \} +. el \{\ +. if !r LL \ +. nr LL \n[.l]u \" for ms, mdoc, man +. if !r #R_MARGIN \ +. nr R_MARGIN 1i \" for mom +. \" for mm +. if !r W \{\ +. nr W \n[.l]u +. if !r O \ +. nr O 1i +. \} +. \} +.\} +. +.cp \n[*groff_papersize_tmac_C] +.do rr *groff_papersize_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/pdf.tmac b/tmac/pdf.tmac new file mode 100644 index 0000000..6a2fa7b --- /dev/null +++ b/tmac/pdf.tmac @@ -0,0 +1,834 @@ +.ig + +pdf.tmac + + Copyright (C) 2011-2020 Free Software Foundation, Inc. + Written by Deri James + +This file 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 . + +Author's Note +============= + +Much of the code in this macro has come from the excellent original work by +Keith Marshall (see attribution in the pdfmark.tmac file). I, however, +am solely responsible for any bugs I may have introduced into this file. +.. +. +.do nr *groff_pdf_tmac_C \n[.cp] +.cp 0 +. +.if d pdfmark .nx +. +.mso ps.tmac +. +.de pdf:SS +. fchar \\$1 \\S'16'\\$1\\S'0' +.. +.pdf:SS \[+h] +.pdf:SS \[ts] +.pdf:SS \[*a] +.pdf:SS \[*b] +.pdf:SS \[*x] +.pdf:SS \[*d] +.pdf:SS \[*e] +.pdf:SS \[*f] +.pdf:SS \[*g] +.pdf:SS \[*y] +.pdf:SS \[*i] +.pdf:SS \[+f] +.pdf:SS \[*k] +.pdf:SS \[*l] +.pdf:SS \[*m] +.pdf:SS \[*n] +.pdf:SS \[*o] +.pdf:SS \[*p] +.pdf:SS \[*h] +.pdf:SS \[*r] +.pdf:SS \[*s] +.pdf:SS \[*t] +.pdf:SS \[*u] +.pdf:SS \[+p] +.pdf:SS \[*w] +.pdf:SS \[*c] +.pdf:SS \[*q] +.pdf:SS \[*z] +.char \[lh] \X'pdf: xrev'\[rh]\X'pdf: xrev' +.nr pdf:bm.nl 1 +.de pdfmark +. nop \!x X ps:exec [\\$* pdfmark +.. +. +.ds pdf pdf.tmac\" for use in diagnostic messages +. +.de pdf:warn +. tm \\*[pdf]:\\n[.F]:\\n[.c]: warning: \\$* +.. +.de pdf:error +. tm \\*[pdf]:\\n[.F]:\\n[.c]: error: \\$* +.. +.de pdfinfo +.\" ------------------------------------------------------------------- +.\" Usage: +.\" .pdfinfo /FieldName field content ... +.\" Examples: +.\" .pdfinfo /Title A PDF Document +.\" .pdfinfo /Author Keith Marshall +.\" ------------------------------------------------------------------- +.\" +.ds pdf:meta.field \\$1 +.shift +.ie '\\n(.z'' .pdfmark \\*[pdf:meta.field] (\\$*) /DOCINFO +.el \!.pdfmark \\*[pdf:meta.field] (\\$*) /DOCINFO +.rm pdf:meta.field +.. +.de pdfview +.\" ------------------------------------------------------------------- +.\" Usage: +.\" .pdfview view parameters ... +.\" Examples: +.\" .pdfview /PageMode /UseOutlines +.\" .pdfview /Page 2 /View [/FitH \n(.p u] +.\" ------------------------------------------------------------------- +.\" +.ie '\\n(.z'' .pdfmark \\$* /DOCVIEW +.el \!.pdfmark \\$* /DOCVIEW +.. +.\" ===================================================================== +.\" Module PDFNOTE: Insert "Sticky Note" Style Comments in a PDF Document +.\" ===================================================================== +.\" +.\" "PDFNOTE.WIDTH" and "PDFNOTE.HEIGHT" set the preferred size for +.\" display of the "sticky note" pane, when opened. Acrobat Reader +.\" seems not to honour these -- perhaps GhostScript doesn't encode +.\" them correctly! Anyway, let's set some suitable default values, +.\" in case the user has a set up which does work as advertised. +.\" +.nr PDFNOTE.WIDTH 3.5i +.nr PDFNOTE.HEIGHT 2.0i +.\" +.\" "pdf:bbox" defines the expression used to set the size and location +.\" of the bounding rectangle for display of notes and link "hot-spots". +.\" This is defined, such that a note is placed at troff's current text +.\" position on the current page, with its displayed image size defined +.\" by the "PDFNOTE.WIDTH" and "PDFNOTE.HEIGHT" registers, while the +.\" bounds for a link "hot-spot" are matched to the text region which +.\" defines the "hot-spot". +.\" +.ds pdf:bbox \\n[pdf:llx] u \\n[pdf:lly] u \\n[pdf:urx] u \\n[pdf:ury] u +.\" +.\" Getting line breaks into the text of a PDFNOTE is tricky -- we need +.\" to get a "\n" into the Postscript stream, but three levels of "\" are +.\" swallowed, when we invoke "pdfnote". The following definition of "PDFLB", +.\" (for LineBreak), is rather ugly, but does allow us to use +.\" +.\" .pdfnote Some text.\*[PDFLB]Some more text, on a new line. +.\" +.ds PDFLB \\\\\\\\\\\\\\\\n +.\" +.de pdfnote +.\" ---------------------------------------------------------------------- +.\" Usage: +.\" .pdfnote [-T "Text for Title"] Text of note ... +.\" ---------------------------------------------------------------------- +.\" +.\" First, compute the bounding rectangle, +.\" for this PDFNOTE instance +.\" +. mk pdf:ury +. nr pdf:llx \\n(.k+\\n(.o+\\n[.in] +. nr pdf:lly \\n[pdf:ury]-\\n[PDFNOTE.HEIGHT] +. nr pdf:urx \\n[pdf:llx]+\\n[PDFNOTE.WIDTH] +. ds pdf:note.instance /Rect [\\*[pdf:bbox]] +.\" +.\" Parse any specified (recognisable) PDFNOTE options +.\" +. while dpdf:note\\$1 \{\ +. pdf:note\\$1 \\$@ +. shift \\n[pdf:note.argc] +. \} +.\" +.\" Emit the note, and clean up +.\" +. pdfmark \\*[pdf:note.instance] /Subtype /Text /Contents (\\$*) /ANN +. rm pdf:note.instance +. rr pdf:note.argc +.. +.de pdf:note-T +.nr pdf:note.argc 2 +.as pdf:note.instance " /Title (\\$2) +.. +.\" ===================================================================== +.\" Module PDFBOOKMARK: Add an Outline Reference in the PDF Bookmark Pane +.\" ===================================================================== +.\" +.\" "PDFBOOKMARK.VIEW" controls how the document will be displayed, +.\" when the user selects a bookmark. This default setting will fit +.\" the page width to the viewing window, with the bookmarked entry +.\" located at the top of the viewable area. +.\" +.ds PDFBOOKMARK.VIEW /FitH \\n[PDFPAGE.Y] u +.\" +.\" "PDFOUTLINE.FOLDLEVEL" controls how the document outline will be +.\" displayed. It is a number, defining the maximum heading level +.\" which will be visible, without outline expansion by the user, in +.\" the initial view of the document outline. Assuming that no sane +.\" document will ever extend to 10,000 levels of nested headings, +.\" this initial default value causes outlines to be fully expanded. +.\" +.nr PDFOUTLINE.FOLDLEVEL 10000 +.\" +.\" The actual job of creating an outline reference +.\" is performed by the "pdfbookmark" macro. +.\" +.de pdfbookmark +.\" ------------------------------------------------------------------ +.\" Usage: +.\" .pdfbookmark [-T tag] level "Text of Outline Entry" +.\" +.\" $1 = nesting level for bookmark (1 is top level) +.\" $2 = text for bookmark, (in PDF viewer bookmarks list) +.\" ------------------------------------------------------------------ +.\" +.ie '\\n(.z'' \{\ +.\" +.\" When we are at the top diversion level, i.e. actually emitting text +.\" to the output device stream, then we compute the location of, and +.\" plant this bookmark immediately. +.\" +. \" Make the bookmark name "untagged" by default, +. \" then parse any specified options, to set a "tag", if required +. \" +. ds pdf:href-T +. while dpdf:href.opt\\$1 \{\ +. pdf:href.opt\\$1 \\$@ +. shift \\n[pdf:href.argc] +. \} +. rr pdf:href.argc +. \" +. \" If we found "--" to mark the end of the options, discard it +. \" +. if '\\$1'--' .shift +. \" +. nr pdf:bm.lev 0+\\$1 +. if \\n[pdf:bm.lev]==0 .nr pdf:bm.lev 1 +. if \\n[pdf:bm.lev]-1==\\n[PDFOUTLINE.FOLDLEVEL] .nr pdf:bm.lev \\n[pdf:bm.lev]*-1 +. nr pdf:bm.abslev 0+\\n[pdf:bm.lev] +. if \\n[pdf:bm.lev]<0 .nr pdf:bm.abslev 0+\\n[pdf:bm.abslev]*-1 +. if \\n[pdf:bm.abslev]>\\n[pdf:bm.nl] .nr pdf:bm.nl \\n[pdf:bm.nl]+1 +. ie \\n[pdf:bm.abslev]>\\n[pdf:bm.nl] \{\ +. pdf:warn adjusted level \\n[pdf:bm.abslev] bookmark; should be <= \\n[pdf:bm.nl] +. nr pdf:bm.abslev 0+\\n[pdf:bm.nl] +. if \\n[pdf:bm.abslev]-1==\\n[PDFOUTLINE.FOLDLEVEL] .nr pdf:bm.lev \\n[pdf:bm.abslev]*-1 +. \} +. el .nr pdf:bm.nl \\n[pdf:bm.abslev] +. if \\n[pdf:bm.lev]<0 .nr pdf:bm.abslev \\n[pdf:bm.abslev]*-1 +. nr pdf:bm.lev 0+\\n[pdf:bm.abslev] +. rr pdf:bm.abslev +. shift +. \" +. \" Increment the bookmark serialisation index +. \" in order to generate a uniquely serialised bookmark name, +. \" ( which we return in the string "PDFBOOKMARK.NAME" ), +. \" +. nr pdf:bm.nr +1 +. ie '\\*[pdf:href-T]'' .ds PDFBOOKMARK.NAME pdf:bm\\n[pdf:bm.nr] +. el .ds PDFBOOKMARK.NAME \\*[pdf:href-T] +. pdf:href.sety +. ds pdf:cleaned \\$* +. ev pdfcln +. tr \[em]- +. nf +. box pdf:clean +. nop \\$* +. fl +. box +. chop pdf:clean +. asciify pdf:clean +. length pdf:clean:len \\*[pdf:clean] +. ds pdf:cleaned \\*[pdf:clean] +. rm pdf:clean +. ev +. tr \[em]\[em] +. ds pdf:look(\\*[PDFBOOKMARK.NAME]) \\*[pdf:cleaned] +. if dPDF.EXPORT .tm .ds pdf:look(\\*[PDFBOOKMARK.NAME]) \\*[pdf:cleaned] +. pdfmark /Dest /\\*[PDFBOOKMARK.NAME] /View [\\*[PDFBOOKMARK.VIEW]] /DEST +. nop \!x X ps:exec [/Dest /\\*[PDFBOOKMARK.NAME] /Title (\\*[pdf:cleaned]) /Level \\n[pdf:bm.lev] /OUT pdfmark +.\". pdfmark /Dest /\\*[PDFBOOKMARK.NAME] /Title "(\\*[pdf:cleaned])" /Level \\n[pdf:bm.lev] /OUT +. pdf:href.options.clear +. rr PDFPAGE.Y +. rm pdf:cleaned +. rm pdf:clean +. \} +. \} +.el \{\ +.\" +.\" But when we are collecting a diversion which will be written out later, +.\" then we must defer bookmark placement, until we emit the diversion. +.\" (don't rely on $0 == pdfbookmark here; it may be a volatile alias). +.\" +. nop \!.pdfbookmark \\$@ +. \} +.. +. +.de pdfclean +. ie '\\n(.z'' \{\ +. ds pdfcleaned \\$* +. ev pdfcln +. tr \[em]- +. nf +. box pdf:clean +. nop \\*[\\*[pdfcleaned]] +. fl +. box +. chop pdf:clean +. asciify pdf:clean +. ev +. ds \\*[pdfcleaned] "\\*[pdf:clean] +. rm pdf:clean +. tr \[em]\[em] +. el .nop \!.pdfclean \\$@ +.. +.\" +.\" ============================================================= +.\" Module PDFHREF: Create Hypertext References in a PDF Document +.\" ============================================================= +.\" +.\" "PDFHREF.VIEW" controls how the document will be displayed, +.\" when the user follows a link to a named reference. +.\" +.ds PDFHREF.VIEW /FitH \\n[PDFPAGE.Y] u +.\" +.\" This default setting will fit the page width to the viewing +.\" window, with the bookmarked entry located close to the top +.\" of the viewable area. "PDFHREF.VIEW.LEADING" controls the +.\" actual distance below the top of the viewing window, where +.\" the reference will be positioned; 5 points is a reasonable +.\" default offset. +.\" +.nr PDFHREF.VIEW.LEADING 5.0p +.\" +.\" Yuk!!! +.\" PDF view co-ordinates are mapped from the bottom left corner, +.\" of the page, whereas page printing co-ordinates are mapped +.\" conventionally, from top left. +.\" +.\" Macro "pdf:href.sety" transforms the vertical position of the +.\" last printed baseline, from the printing co-ordinate domain to +.\" the PDF view domain. +.\" +.de pdf:href.sety +.\" ---------------------------------------------------------------- +.\" Usage: +.\" .pdf:href.sety +.\" ---------------------------------------------------------------- +.\" +.\" This computation yields the vertical view co-ordinate +.\" in groff's basic units; don't forget to append grops' "u" +.\" conversion operator, when writing the pdfmark! +.\" +.nr PDFPAGE.Y (\\n[PDFHREF.VIEW.LEADING]-\\n(nl) +.. +.\" When we create a link "hot-spot" ... +.\" "PDFHREF.LEADING" sets the distance above the top of the glyph +.\" bounding boxes, in each line of link text, over which the link +.\" hot-spot will extend, while "PDFHREF.HEIGHT" sets the hot-spot +.\" height, PER LINE of text occupied by the reference. +.\" +.\" Since most fonts specify some leading space within the bounding +.\" boxes of their glyphs, a better appearance may be achieved when +.\" NEGATIVE leading is specified for link hot-spots; indeed, when +.\" the default 10pt Times font is used, -1.0 point seems to be a +.\" reasonable default value for "PDFHREF.LEADING" -- it may be +.\" changed, if desired. +.\" +.\" "PDFHREF.HEIGHT" is initially set as one vertical spacing unit; +.\" note that it is defined as a string, so it will adapt to changes +.\" in the vertical spacing. Changing it is NOT RECOMMENDED. +.\" +.nr PDFHREF.LEADING 2.0p +.ds PDFHREF.HEIGHT 1.0v +.\" +.\" PDF readers generally place a rectangular border around link +.\" "hot-spots". Within text, this looks rather ugly, so we set +.\" "PDFHREF.BORDER" to suppress it -- the three zeroes represent +.\" the border parameters in the "/Border [0 0 0]" PDFMARK string, +.\" and may be changed to any valid form, as defined in Adobe's +.\" PDFMARK Reference Manual. +.\" +.ds PDFHREF.BORDER 0 0 0 +.\" +.\" "PDFHREF.COLOUR" (note British spelling) defines the colour to +.\" be used for display of link "hot-spots". This will apply both +.\" to borders, if used, and, by default to text; however, actual +.\" text colour is set by "PDFHREF.TEXT.COLOUR", which may be reset +.\" independently of "PDFHREF.COLOUR", to achieve contrasting text +.\" and border colours. +.\" +.\" "PDFHREF.COLOUR" must be set to a sequence of three values, +.\" each in the range 0.0 .. 1.0, representing the red, green, and +.\" blue components of the colour specification in the RGB colour +.\" domain, which is shared by "groff" and the PDF readers. +.\" +.ds PDFHREF.COLOUR 0.35 0.00 0.60 +.defcolor pdf:href.colour rgb \*[PDFHREF.COLOUR] +.\" +.\" "PDFHREF.TEXT.COLOUR", on the other hand, is simply defined +.\" using any "groff" colour name -- this default maps it to the +.\" same colour value as "PDFHREF.COLOUR". +.\" +.ds PDFHREF.TEXT.COLOUR pdf:href.colour +.\" +.\" Accommodate users who prefer the American spelling, COLOR, to +.\" the British spelling, COLOUR. +.\" +.als PDFHREF.COLOR PDFHREF.COLOUR +.als PDFHREF.TEXT.COLOR PDFHREF.TEXT.COLOUR +.\" +.\" All PDF "Hypertext" reference capabilities are accessed +.\" through the "pdfhref" macro +.\" +.de pdfhref +.\" ----------------------------------------------------------------- +.\" Usage: +.\" .pdfhref ... +.\" ----------------------------------------------------------------- +.\" +.\" +.\" Loop over all subcommands specified in the argument list +.\" +. while \\n(.$ \{\ +. \" +. \" Initially, assume each subcommand will complete successfully +. \" +. nr pdf:href.ok 1 +. \" +. \" Initialise -E and -X flags in the OFF state +. \" +. nr pdf:href-E 0 +. nr pdf:href-X 0 +. \" +. \" Handle the case where subcommand is specified as "-class", +. \" setting up appropriate macro aliases for subcommand handlers. +. \" +. if dpdf*href\\$1 .als pdf*href pdf*href\\$1 +. if dpdf*href\\$1.link .als pdf*href.link pdf*href\\$1.link +. if dpdf*href\\$1.file .als pdf*href.file pdf*href\\$1.file +. \" +. \" Repeat macro alias setup +. \" for the case where the subcommand is specified as "class", +. \" (without a leading hyphen) +. \" +. if dpdf*href-\\$1 .als pdf*href pdf*href-\\$1 +. if dpdf*href-\\$1.link .als pdf*href.link pdf*href-\\$1.link +. if dpdf*href-\\$1.file .als pdf*href.file pdf*href-\\$1.file +. \" +. \" Process one subcommand ... +. \" +. ds pdf*href.class \\$1 +. ie dpdf*href \{\ +. \" +. \" Subcommand "class" is recognised ... +. \" discard the "class" code from the argument list, +. \" set the initial argument count to swallow all arguments, +. \" and invoke the selected subcommand handler. +. \" +. shift +. nr pdf:argc \\n(.$ +. pdf*href \\$@ +. \" +. \" When done, +. \" discard all arguments actually consumed by the handler, +. \" before proceeding to the next subcommand (if any). +. \" +. shift \\n[pdf:argc] +. \} +. el \{\ +. \" +. \" Subcommand "class" is not recognised ... +. \" issue a warning, and discard the entire argument list, +. \" so aborting this "pdfhref" invocation +. \" +. pdf:warn \\$0: undefined reference class '\\$1' ignored +. shift \\n(.$ +. \} +. \" +. \" Clean up temporary reference data, +. \" to ensure it doesn't propagate to any future reference +. \" +. rm pdf*href pdf:href.link pdf:href.files +. rr pdf:href-E +. pdf:href.options.clear +. \} +. rr pdf:href.ok +.. +.\" +.\" Macros "pdf:href.flag" and "pdf:href.option" +.\" provide a generic mechanism for switching on flag type options, +.\" and for decoding options with arguments, respectively +.\" +.de pdf:href.flag +.\" ---------------------------------------------------------------------- +.\" ---------------------------------------------------------------------- +.nr pdf:href\\$1 1 +.nr pdf:href.argc 1 +.. +.de pdf:href.option +.\" ---------------------------------------------------------------------- +.\" ---------------------------------------------------------------------- +.ds pdf:href\\$1 \\$2 +.nr pdf:href.argc 2 +.. +.\" +.\" Valid PDFHREF options are simply declared +.\" by aliasing option handlers to "pdf:href.option", +.\" or to "pdf:href.flag", as appropriate +.\" +.als pdf:href.opt-A pdf:href.option \" affixed text +.als pdf:href.opt-D pdf:href.option \" destination name +.als pdf:href.opt-E pdf:href.flag \" echo link descriptor +.als pdf:href.opt-F pdf:href.option \" remote file specifier +.als pdf:href.opt-N pdf:href.option \" reference name +.als pdf:href.opt-P pdf:href.option \" prefixed text +.als pdf:href.opt-T pdf:href.option \" bookmark "tag" +.als pdf:href.opt-X pdf:href.flag \" cross reference +.\" +.\" For references to another document file +.\" we also need to support OS dependent file name specifiers +.\" +.als pdf:href.opt-DF pdf:href.option \" /DOSFile specifier +.als pdf:href.opt-MF pdf:href.option \" /MacFile specifier +.als pdf:href.opt-UF pdf:href.option \" /UnixFile specifier +.als pdf:href.opt-WF pdf:href.option \" /WinFile specifier +.\" +.\" Macro "pdf:href.options.clear" ensures that ALL option +.\" argument strings are deleted, after "pdfhref" has completed +.\" all processing which depends on them +.\" +.de pdf:href.options.clear +.\" ----------------------------------------------------------------- +.\" Usage: +.\" .pdf:href.options.clear [option ...] +.\" ----------------------------------------------------------------- +.\" +.\" When an option list is specified ... +.\" +.ie \\n(.$ \{\ +. \" +. \" then loop through the list, +. \" deleting each specified option argument string in turn +. \" +. while \\n(.$ \{\ +. if dpdf:href-\\$1 .rm pdf:href-\\$1 +. shift +. \} +. \} +.\" +.\" ... but when no list is specified, +.\" then recurse, to clear all known option argument strings +.\" +.el .pdf:href.options.clear A D F N P T DF MF UF WF +.. +.\" +.\" Macro "pdf*href-M" is the handler invoked by "pdfhref", when +.\" called with the "M" reference class specifier, to create a +.\" named cross reference mark, and to emit a cross reference +.\" data record, as specified by "PDFHREF.INFO". +.\" +.de pdf*href-M +.\" ----------------------------------------------------------------- +.\" Usage: +.\" .pdfhref M [-N name | -D name] [-E] descriptive text ... +.\" ----------------------------------------------------------------- +.\" +.\" Initially, declare the -D and -N string options as empty, +.\" so we avoid warning messages when we try to use them, and find +.\" that they are undefined. +.\" +.ds pdf:href-D +.ds pdf:href-N +.\" +.\" Parse, interpret, and strip any specified options from the +.\" argument list. (Note that only options with a declared handler +.\" will be processed; there is no provision for detecting invalid +.\" options -- anything which is not recognised is assumed to start +.\" the "descriptive text" component of the argument list). +.\" +.while dpdf:href.opt\\$1 \{\ +. pdf:href.opt\\$1 \\$@ +. shift \\n[pdf:href.argc] +. \} +.\" +.\" If we found "--", to mark the end of the options, +.\" then we should discard it. +.\" +.if '\\$1'--' .shift +.\" +.\" All PDF reference markers MUST be named. The name may have been +.\" supplied using the "-N Name" option, (or the "-D Name" option); +.\" if not, deduce it from the first "word" in the "descriptive text", +.\" if any, and set the marker -- if we still can't identify the name +.\" for the destination, then this marker will not be created. +.\" +.ds PDFBOOKMARK.NAME "\\*[pdf:href-N]\\*[pdf:href-D] +.pdf*href.set \\*[PDFBOOKMARK.NAME] \\$1 +.ds pdf:look(\\*[PDFBOOKMARK.NAME]) \\$* +.if dPDF.EXPORT .tm .ds pdf:look(\\*[PDFBOOKMARK.NAME]) \\$* +.\" +.\" +.\" Irrespective of whether this marker is created, or not, +.\" the descriptive text will be copied to the groff output stream, +.\" provided the "-E" option was specified +.\" +.if \\n[pdf:href-E] \&\\$* +.. +.de pdf*href-F +.\"do nothing +.. +.\" +.de pdf*href.set +.\" ---------------------------------------------------------------------- +.\" ---------------------------------------------------------------------- +.ie \\n(.$ \{\ +. \" +. \" a marker name has been supplied ... +. \" if we are formatting for immediate output, +. \" emit PDFMARK code to establish the associated view +. \" +. ie '\\n(.z'' \{\ +. pdf:href.sety +. pdfmark /Dest /\\$1 /View [\\*[PDFHREF.VIEW]] /DEST +. ds PDFHREF.NAME \\$1 +. rr PDFPAGE.Y +. \} +. \" +. \" but, when formatting a diversion ... +. \" delay output of the PDFMARK code, until the diversion +. \" is eventually written out +. \" +. el \!.\\$0 \\$@ +. \" +. \} +.el \{\ +. \" marker is unnamed ... +. \" issue error message; do not emit reference data +. \" +. pdf:warn pdfhref destination marker must be named +. \} +.. +.\" +.de pdf*href +.\" ------------------------------------------------------------------ +.\" Usage: +.\" .pdf*href class [options ...] [link text ...] +.\" ------------------------------------------------------------------ +.\" +.\" First, we initialise an empty string, which will be affixed to +.\" the end of the "link text". (This is needed to cancel the effect +.\" of a "\c" escape, which is placed at the end of the "link text" +.\" to support the "-A" option -- any text supplied by the user, when +.\" the "-A" option is specified, will replace this empty string). +.\" +.ds pdf:href-A +.\" +.\" Now we interpret, and remove any specified options from the +.\" argument list. (Note that only options with a declared handler +.\" will be processed; there is no provision for detecting invalid +.\" options -- anything which is not recognised is assumed to start +.\" the "link text" component of the argument list). +.\" +.while dpdf:href.opt\\$1 \{\ +. pdf:href.opt\\$1 \\$@ +. shift \\n[pdf:href.argc] +. \} +.\" +.\" If we found "--", to mark the end of the options, then we should +.\" discard it. +.\" +.if '\\$1'--' .shift +.\" +.\" All PDF link classes REQUIRE a named destination. This may have +.\" been supplied using the "-D Name" option, but, if not, deduce it +.\" from the first "word" in the "link text", if any -- if we still +.\" can't identify the destination, then set "pdf:href.ok" to zero, +.\" so this link will not be created. +.\" +.if !dpdf:href-D .pdf:href.option -D \\$1 +.if '\\*[pdf:href-D]'' \{\ +. pdf:error pdfhref has no destination +. nr pdf:href.ok 0 +. \} +.\" +.\" Now, initialise a string, defining the PDFMARK code sequence +.\" to create the reference, using the appropriate type indicators. +.\" +.ds pdf:href.link /Subtype /Link \\*[pdf*href.link] +.\" +.\" And now, we have no further use for "pdf*href.link". +.\" +.rm pdf*href.link +.\" +.\" If the user specified any "link prefix" text, (using the "-P text" +.\" option), then emit it BEFORE processing the "link text" itself. +.\" +.if dpdf:href-P \&\\*[pdf:href-P]\c +.ie \\n[pdf:href.ok] \{\ +. \" +. \" This link is VALID (so far as we can determine) ... +. \" Modify the "link text" argument specification, as required, +. \" to include any pre-formatted cross reference information +. \" +. ie \\n(.$ \{\ +. \" +. \" One or more "link text" argument(s) are present, +. \" so, set the link description from the argument(s) ... +. \" +. ds PDFHREF.DESC \\\\$* +. \} +. el \{\ +. ie dpdf:look(\\*[pdf:href-D]) .ds PDFHREF.DESC \\*[pdf:look(\\*[pdf:href-D])] +. el .ds PDFHREF.DESC Unknown +. \} +. \" Apply border and colour specifications to the PDFMARK string +. \" definition, as required. +. \" +. if dPDFHREF.BORDER .as pdf:href.link " /Border [\\*[PDFHREF.BORDER]] +. if dPDFHREF.COLOUR .as pdf:href.link " /Color [\\*[PDFHREF.COLOUR]] +. \" +. \" Emit the "link text", in its appropriate colour, marking the +. \" limits of its bounding box(es), as the before and after output +. \" text positions. +. \" +\#. if dPDFHREF.COLOUR .defcolor pdf:href.colour rgb \\*[PDFHREF.COLOUR] +. nr pdf:bm.width \\w'\\*[PDFHREF.DESC]' +. nop \&\m[\\*[PDFHREF.TEXT.COLOUR]]\c +. device pdf: markstart \\n[rst] \\n[rsb] \\n[PDFHREF.LEADING] \\*[pdf:href.link] +. nop \&\\*[PDFHREF.DESC]\X'pdf: markend'\m[]\c +. \" +. \" Clean up the temporary registers and strings, used to +. \" compute the "hot-spot" bounds, and format the reference, +. \" +. rm PDFHREF.DESC +. \} +.\" +.\" But when we identify an INVALID link ... +.\" We simply emit the "link text", with no colour change, no border, +.\" and no associated "hot-spot". +.\" +.el \&\\$*\c +.\" +.\" And then, if the user specified any affixed text, (using the +.\" "-A text" option), we tack it on at the end. +.\" +.nop \&\\*[pdf:href-A] +.. +.\" Macro "pdf*href-I" is used for one time initialisation of special +.\" "pdfhref" features; (currently, only the above page trap hook is +.\" supported, but it is implemented with one level of indirection, to +.\" accommodate possible future expansion). +. +.de pdf*href-I +.\" ---------------------------------------------------------------------- +.\" Usage: +.\" .pdfhref I -

+and +.CR +HTML tags: The contents of +.CR .TH +is horizontally and vertically centered and typeset in boldface. +. +.IP +.RS +.XB predecessor: .TR .TD .TH .ETB "cell contents" +.XB successor: .TD .TH .TR .ETB "cell contents" +.XB arguments: +. +.RS +.XAA colspan= m +The width of this cell is the sum of the widths of the\~\c +.CI m +cells above and below this row. +. +.XAA rowspan= m +The height of this cell is the sum of the heights of the +.CI m +cells left and right of this column. +. +.IP +.B Remark: +Overlapping of column and row spanning, +as in the following table fragment +(the overlapping happens in the second cell in the second row), +is invalid and causes incorrect results. +. +. +.RS +.IP +.EX +\&.TR .TD 1*1 \[dq].TD 1*2 rowspan=2\[dq] .TD 1*3 +\&.TR \[dq].TD 2*1 colspan=2\[dq] .TD 2*3 +.EE +.RE +. +. +.PP +A working example for headers and cells with +.B colspan +is +. +. +.PP +.RS +.EX +\&.TBL cols=3 +\&.\& TR \[dq].TH colspan=2\[dq] header1+2 .TH header3 +\&.\& TR .TD 1*1 .TD 1*2 .TD 1*3 +\&.\& TR .TD 2*1 \[dq].TD colspan=2\[dq] 2*2+3 +\&.ETB +.EE +.RE +. +. +.PP +This looks like +. +. +.PP +.if t .ne 7v +.RS +.EX +.tr -\- ++------------------------------+---------------+ +| header1+2 | header3 | ++--------------+---------------+---------------+ +| 1*1 | 1*2 | 1*3 | ++--------------+---------------+---------------+ +| 2*1 | 2*2+3 | ++--------------+-------------------------------+ +.tr -- +.EE +.RE +. +. +.PP +A working example with +.B rowspan +is +. +. +.PP +.RS +.EX +\&.TBL cols=3 +\&.\& TR +\&.\& TD 1*1 +\&.\& TD rowspan=2 1+2*2 +\&.\& TD 1*3 +\&.\& +\&.\& TR +\&.\& TD 2*1 +\&.\& TD 2*3 +\&.ETB +.EE +.RE +. +. +.PP +which looks like +. +. +.PP +.if t .ne 5v +.RS +.EX +.tr -\- ++--------------+---------------+---------------+ +| 1*1 | 1+2*2 | 1*3 | ++--------------+ +---------------+ +| 2*1 | | 2*3 | ++--------------+---------------+---------------+ +.tr -- +.EE +.RE +.RE +.RE +. +.\"================================================================== +. +. +.TP +.CB ".ETB \[lB]hold\[rB]" +End of the table. +. +.IP +This macro finishes a table. +. +It causes one of the following actions. +. +.RS +.IP \[bu] 3 +If the argument +.CR \[oq]hold\[cq] +is given, the table is held until it is freed by calling the macro +.CR .t*free\c +, which in turn prints the table immediately, +either at the current position or at the top of the next page if its +height is larger than the remaining space on the page. +. +.IP \[bu] 3 +Otherwise, if the table is higher than the remaining space on the page, +it is printed at the top of the next page. +. +.IP \[bu] 3 +If neither of the two above constraints hold, the table is printed +immediately at the place of its definition. +.RE +. +.IP +.RS +.XB predecessor: .TD .TH .ETB "cell contents" +.XB successor: .TBL .TR .TD .TH .ETB "cell contents" +.XB arguments: +. +.RS +.XAA hold +Prevent the table from being printed until it is freed by calling the +macro +.CR .t*free\c +\&. +. +This argument is ignored for inner (nested) tables. +.RE +.RE +. +.\"================================================================== +. +.TP +.CBI ".t*free " \[lB]n\[rB] +Free the next held table or +.CI n\~\c +.RI held "" +tables. +. +Call this utility macro to print tables which are held by using the +.CR \[oq]hold\[cq] +argument of the +.CR .ETB +macro. +. +. +.\" ==================================================================== +.SS "Arguments common to \f[CB].TBL\f[], \f[CB].TR\f[], \f[CB].TD\f[], \ +and \f[CB].TH\f[]" +.\" ==================================================================== +. +The arguments described in this section can be specified with the +.CR .TBL +and +.CR .TR +macros, but they are eventually passed on to the table cells. +. +If omitted, +the defaults take place, +which the user can change by setting the corresponding default registers +or strings, +as documented below. +. +Setting an argument with the +.CR .TBL +macro has the same effect as setting it for all rows in the table. +. +Setting an argument with a +.CR .TR +macro has the same effect as setting it for all the +.CR .TH +or +.CR .TD +macro in this row. +. +.IP +.XAA bgc= \[lB]c\[rB] +The background color of the table cells. +. +This includes the area specified with the +.CR \[oq]csp\[cq] +argument. +. +The argument +.CR \[oq]bgc=\[cq] +(no value) suppresses a background color; this makes the background +transparent. +. +.XDEFS bgc=bisque t*bgc +. +.XAA fgc= c +The foreground color of the cell contents. +. +.XDEFS fgc=red4 t*fgc +. +.XAA ff= name +The font family for the table. +. +.CI name +is a +.I groff +font family identifier, +such as +.CR A +for Avant Garde or +.CR HN +for Helvetica Narrow. +. +.XDEF +The font family found before the table (string +.CR \[oq]t*ff\[cq]\c +). +. +.XAA fst= style +The font style for the table. +. +One of +.CR R\c +, +.CR B\c +, +.CR I\c +, or +.CR BI +for roman, +.BR bold , +.IR italic , +or \f[BI]bold italic\f[], \" \f[BI] is not portable man(7) +respectively. +. +As with +.IR roff 's +.B .ft +request, +the +.CR \[oq]fst\[cq] +argument can be used to specify the font family and font style together, +for example +.CR \[oq]fst=HNBI\[cq] +instead of +.CR \[oq]ff=HN\[cq] +and +.CR \[oq]fst=BI\[cq]\c +\&. +. +.XDEF +The font style in use right before the table (string +.CR \[oq]t*fst\[cq]\c +). +. +.XAA "fsz=\[aq]" "d1 \[lB]d2\[rB]" \[aq] +A decimal or fractional factor +.CI d1\c +.RI , "" +by which the point size for the table is changed, and +.CI d2\c +.RI , "" +by which the vertical line spacing is changed. +. +If +.CI d2 +is omitted, value +.CI d1 +is taken for both. +. +.XDEFS "fsz=\[aq]1.0 1.0\[aq]" t*fsz +. +.XAA hal=l\[or]c\[or]b\[or]r +Horizontal alignment of the cell contents in the table. +. +.CR \[oq]hal=l\[cq]\c +: left alignment. +. +.CR \[oq]hal=c\[cq]\c +: centered alignment. +. +.CR \[oq]hal=b\[cq]\c +: both (left and right) alignment. +. +.CR \[oq]hal=r\[cq]\c +: right alignment. +. +.XDEFS hal=b t*hal +. +.XAA val=t\[or]m\[or]b +Vertical alignment of the cell contents in the table for cells lower +than the current row. +. +.CR \[oq]val=t\[cq]\c +: alignment below the top of the cell. +. +.CR \[oq]val=m\[cq]\c +: alignment in the middle of the cell. +. +.CR \[oq]val=b\[cq]\c +: alignment above the cell bottom. +. +.XDEFS val=t t*val +. +.XAA hl=\[lB]s\[or]d\[rB] +Horizontal line between the rows. +. +If specified with +.CR .TD +or +.CR .TH +this is a separator line to the cell below. +. +.CR \[oq]hl=\[cq] +(no value): no separator line. +. +.CR \[oq]hl=s\[cq]\c +: a single separator line between the rows. +. +.CR \[oq]hl=d\[cq]\c +: a double separator line. +. +.IP +The thickness of the separator lines is the half of the border +thickness, +but at least 0.1\~inches. +. +The distance between the double lines is equal to the line thickness. +. +.IP +.B Remark: +Together with +.CR \[oq]border=0\[cq] +for proper formatting the value of +.CR \[oq]csp\[cq] +must be at least \&.05\~inches for single separator lines and +\&.15\~inches for double separator lines. +. +.XDEFS hl=s t*hl +. +.XAA vl=\[lB]s\[or]d\[rB] +Vertical separator line between the cells. +. +If specified with +.CR .TD +or +.CR .TH +this is a separator line to the cell on the right. +. +.CR \[oq]vl=s\[cq]\c +: a single separator line between the cells. +. +.CR \[oq]vl=d\[cq]\c +: a double separator line. +. +.CR \[oq]vl=\[cq] +(no value): no vertical cell separator lines. +. +For more information see the documentation of the +.CR \[oq]hl\[cq] +argument above. +. +.XDEFS vl=s t*vl +. +. +.\" ==================================================================== +.SH "\f[I]hdtbl\f[] customization" +.\" ==================================================================== +. +.PP +Before creating the first table, you should configure default values +to minimize the markup needed in each table. +. +The following example sets up defaults suitable for typical papers: +. +. +.PP +.RS +.EX +\&.ds t*bgc white\[rs]\[dq] background color +\&.ds t*fgc black\[rs]\[dq] foreground color +\&.ds t*bc black\[rs]\[dq] border color +\&.nr t*cpd 0.1n\[rs]\[dq] cell padding +.EE +.RE +. +. +.PP +The file +.I @EXAMPLEDIR@/\:hdtbl/\:\%common\:.roff +provides another example setup +in the \[lq]minimal Page setup\[rq] section. +. +. +.PP +A table which does not fit on a partially filled page is printed +automatically on the top of the next page if you append the little +utility macro +.CR t*hm +to the page header macro of your document's main macro package. +. +For example, say +. +. +.PP +.RS +.EX +\&.am pg@top +\&.\& t*hm +\&.. +.EE +.RE +. +. +.PP +if you use the +.I ms +macro package. +. +. +.PP +The macro +.CR t*EM +checks for held or kept tables, +and for missing +.CR ETB +macros (table not closed). +. +You can call this macro by appending it the to end-of-input macro of +the main, +or \[lq]full-service\[rq], +macro package your document uses. +. +For example, +try +. +. +.RS +.EX +\&.am pg@end\-text +\&.\& t*EM +\&.. +.EE +.RE +. +if you use the +.I ms +package. +. +. +.\" ==================================================================== +.SH "Bugs and suggestions" +.\" ==================================================================== +. +Please send your comments to the +.MT groff@\:gnu\:.org +.I groff +mailing list +.ME +or directly to the author. +. +. +.\" ==================================================================== +.SH Authors +.\" ==================================================================== +. +The +.I hdtbl +macro package was written by +.MT Joachim\:.Walsdorff@\:urz\:.uni\-heidelberg\:.de +Joachim Walsdorff +.ME . +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.TP +.MR groff @MAN1EXT@ +provides an overview of GNU +.I roff +and details how to invoke +.I groff +at the command line. +. +. +.TP +.MR groff @MAN7EXT@ +summarizes the +.I roff +language and GNU extensions to it. +. +. +.TP +.MR @g@tbl @MAN1EXT@ +describes the traditional +.I roff +preprocessor for tables. +. +. +.\" Unwind (some of) the stuff we've done. +.rchar \[lB] +.rchar \[rB] +.rchar \[or] +.rchar \[ell] +.rchar \[oq] +.rchar \[cq] +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_groff_hdtbl_7_man_C] +.do rr *groff_groff_hdtbl_7_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/contrib/hdtbl/hdmisc.tmac b/contrib/hdtbl/hdmisc.tmac new file mode 100644 index 0000000..9709bd8 --- /dev/null +++ b/contrib/hdtbl/hdmisc.tmac @@ -0,0 +1,327 @@ +.ig + +hdmisc.tmac + +This file is part of groff, the GNU roff type-setting system. + +Copyright (C) 2005-2020 Free Software Foundation, Inc. +written by Joachim Walsdorff . + +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 . + +.. +. +. +.if d t*getarg \ +. nx +. +. +.\" ****************************************************************** +.\" ** Some macros and default settings needed by hdtbl ** +.\" ****************************************************************** +. +. +.\" Utility macro: .getarg ... +.\" +.\" Get macro argument. This macro searches in the +.\" remaining arguments and assigns its value to a string +.\" register named . The following syntax forms are +.\" recognized. +.\" +.\" = Assign to string . +.\" must not contain spaces. +.\" ='' Assign to string . +.\" can contain spaces. +.\" = Assign '=' to string . +.\" Assign 'key' to string . +.\" +.\" After return, the string 'args' contains the remaining +.\" arguments. +.\" +.\" Example: With the definition of string 'foo' as +.\" +.\" .ds foo aaa=xxx bbb ccc='yyy zzz' ddd= eee +.\" +.\" a call to 'getarg' with +.\" +.\" .getarg ccc \*[foo] +.\" +.\" sets string 'ccc' to value 'yyy zzz'. The string 'args' +.\" now contains 'aaa=xxx bbb ddd= eee'. An additional call +.\" like +.\" +.\" .getarg ddd \*[args] +.\" +.\" sets string 'ddd' to value '=', and 'args' contains +.\" 'aaa=xxx bbb eee'. +.de t*getarg +. ds \\$1 +. ds args +. +. if (\\n[.$] < 2) \ +. return +. +. ds $1 \\$1\" +. shift +. +. length * \\*[$1] +. while \\n[.$] \{\ +. ds * "\\$1\" +. ds ** "\\$1\" +. length ** \\*[**] +. shift +. if (\\n[*] > \\n[**]) \{\ +. as args " "\\*[**]"\" value too short, repeat +. continue +. \} +. substring * 0 (\\n[*] - 1) +. \" The surrounding \? escapes emulate string comparison. +. ie !"\?\\*[$1]\?"\?\\*[*]\?" \{\ +. as args " "\\*[**]"\" key not found, repeat +. continue +. \} +. el \{\ +. ie "\?\\*[**]\?"\?\\*[$1]\?" \ +. ds \\*[$1] \\*[$1]\" return key as string +. el \{\ +. ie "\?\\*[**]\?"\?\\*[$1]=\?" \ +. ds \\*[$1] =\" return '=' +. el \{\ +. substring ** (\\n[*] + 1) -1 +. ds * \\*[**]\" +. substring * 0 0 +. +. \" check whether value starts with quote +. if "\?\\*[*]\?"\?'\?" \{\ +. substring ** 1 -1 +. ds * \\*[**]\" +. substring * -1 -1 +. +. \" search final quote +. ie "\?\\*[*]\?"\?'\?" \ +. substring ** 0 -2 +. el \{\ +. as \\*[$1] \\*[**] \" not found, append argument +. +. while 1 \{\ +. ds ** \\$1\" get next argument +. ds * \\$1\" +. shift +. substring * -1 -1 +. +. if "\?\\*[*]\?"\?'\?" \{\ +. substring ** 0 -2 +. break \" break if no final quote +. \} +. +. as \\*[$1] \\*[**] \" otherwise append and repeat +. \} +. \}\} +. +. as \\*[$1] \\*[**]\" +. \} +. +. as args " \\$@\" +. \}\} +. +. return +. \} +.. +. +. +.\" Utility macro: .index +.\" +.\" Check whether is a substring of and +.\" return its position in number register 't*index', starting +.\" with 1. If not found, return 0. If is empty, +.\" set 't*index' to -999. +.de t*index +. if "\\$2"" \{\ +. nr t*index -999 +. return +. \} +. +. length ** \\$1 +. length $2 \\$2 +. nr * 0-1 1 +. +. while (\\n+[*] < \\n[**]) \{\ +. ds * \\$1\" +. substring * \\n[*] (\\n[*] + \\n[$2] - 1) +. \" The surrounding \? escapes emulate string comparison. +. if "\?\\*[*]\?"\?\\$2\?" \ +. break +. \} +. +. ie (\\n[*] == \\n[**]) \ +. nr t*index 0 +. el \ +. nr t*index (\\n[*] + 1) +.. +. +. +.\" ****************************************************************** +.\" ******** non-accumulating space .t*SP [v] ********** +.\" ** ** +.\" ** nl vor erster Seite -1, oben auf Seite 0 resp. tH ** +.\" ** .k nach .sp oder .br 0, ** +.\" ** sonst Laenge der angefangenen Zeile ** +.\" ** Der Merker M# fuer vorangegangenes .t*SP wird in .HM am ** +.\" ** Seitenanfang zurueckgesetzt. ** +.\" ** ganz richtig ist .sp + .br = .br + .sp = .sp ** +.\" ****************************************************************** +.de t*SP +. if (\\n[nl] < 0) \ +. br \" start very first page +. nr * \\n[.p] \" save current page length +. +. ie "\\$1"" \ +. pl +1 \" without arg increase page length by 1v +. el \ +. pl +\\$1 \" otherwise use \\$1 +. +. nr ** (\\n[.p] - \\n[*]) \" ** now holds arg for .t*SP in base units +. pl \\n[*]u \" restore page length +. +. \" we do nothing at start of new page or column +. if ((\\n[nl] - \\n[tH]) & (\\n[nl] - \\n[<<]) : \\n[.k]) \{\ +. ie ((\\n[.d] - \\n[M#]) : \\n[.k]) \{\ +. sp \\n[**]u \" execute .sp +. nr S# \\n[**] \" store ** in S# +. \} +. el \{\ +. if (\\n[**] - \\n[S#]) \{\ +. sp (\\n[**]u - \\n[S#]u)\" emit difference to previous .t*SP +. nr S# \\n[**] \" store ** in S# +. \}\} +. +. nr M# \\n[.d] \" store vertical position .d in M# +. \} +.. +. +. +.\" ****************************************************************** +.\" ** Perform all arguments once ** +.\" ** P1 is nestable ** +.\" ****************************************************************** +.de t*P1 +. \" 'while' command is about five times faster than recursion! +. while \\n[.$] \{\ +. nop \\$1 +. shift +. \} +.. +. +. +.\" ****************************************************************** +.\" ** Hilfsmakro zum Einstellen von Schriftgroesse und ** +.\" ** Zeilenabstand, bezogen auf Anfangswerte \n[t*s] ** +.\" ** und \n[t*v] sowie fuer Hyphenation: ** +.\" ** .t*pv s v hy# hart; macht .br ** +.\" ** Bei 4. Argument setzen der Register s und v und hy. ** +.\" ** Fuer angefangene Zeile die vorgefundenen Einstellungen ** +.\" ** ** +.\" ** Auxiliary macro to set internal registers for font size ** +.\" ** and line spacing, relative to initial values \n[t*s] and ** +.\" ** \n[t*v]. Optionally sets hyphenation. A fourth argument ** +.\" ** initializes internal registers to global default values. ** +.\" ****************************************************************** +.de t*pv +. br +. +. if \\n[.$] \ +. ps (\\n[t*s]u * \\$1z / 1z) +. +. ie (\\n[.$] - 1) \ +. vs (\\n[t*v]u * \\$2p / 1p) +. el \{\ +. vs (\\n[t*v]u * \\$1p / 1p) +. return +. \} +. +. if !""\\$3" \ +. hy \\$3 +. +. if !""\\$4" \{\ +. nr t*v \\n[.v] +. nr t*s \\n[.ps] +. nr t*hy \\n[.hy] +. \} +.. +. +. +.\" ****************************************************************** +.\" ** Hilfsmakros pop/pops/popr (pop stackelement): ** +.\" ** pop or popr: pop register ** +.\" ** pops: pop string ** +.\" ** .pop[s|r] reg|string stackname ** +.\" ** reg|string: name of reg/string to get the ** +.\" ** popped element ** +.\" ** stack: name of stack ** +.\" ****************************************************************** +.de *pop +. ie "\\$1"pops" \ +. ds \\$2 \\$4\" pop first stackelement +. el \ +. nr \\$2 \\$4 +. +. ds $3 \\$3\" remember stackname +. shift 4 \" shift four args +. +. ds \\*[$3] "\\$@\" fill stack with remaining elements +.. +. +.de pop +. *pop \\$0 \\$1 \\$2 \\*[\\$2] +.. +. +.als popr pop +.als pops pop +. +. +.\" ****************************************************************** +.\" ** process diversion ** +.\" ****************************************************************** +.de t*DI +. nr * \\n[.u] +. nf \" diversion is already formatted - output it unchanged +. \\$1 \" output the diversion ... +. rm \\$1 \" ... and remove it +. if \\n[*] \ +. fi \" reactivate formatting +.. +. +.\" ****************************************************************** +.\" ** error checking at end ** +.\" ****************************************************************** +.de t*EM +. +. if !"\\*[t*kept]"" \{\ +. tm1 "hdtbl: Not all tables have been printed. +. tm1 " Add '.bp' at the end of your document. +. \} +. if !"\\*[t*held]"" \{\ +. tm1 "hdtbl: There are held tables which haven't been printed. +. tm1 " Add '.t*free' at the end of your document. +. \} +. if \\n[t*#] \ +. tm hdtbl: Missing '.ETB' macro; last .TBL in \\*[t*FN] at line \\*[t*LN]. +.. +. +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/contrib/hdtbl/hdtbl.am b/contrib/hdtbl/hdtbl.am new file mode 100644 index 0000000..3dd60cf --- /dev/null +++ b/contrib/hdtbl/hdtbl.am @@ -0,0 +1,136 @@ +# Copyright (C) 2006-2020 Free Software Foundation, Inc. +# Written by Werner Lemberg +# Automake migration by Bertrand Garrigues +# +# +# This file 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 . + +hdtbl_srcdir = $(top_srcdir)/contrib/hdtbl + +man7_MANS += contrib/hdtbl/groff_hdtbl.7 + +# Groff command used to generate .ps files +HDTBLGROFF = \ + GROFF_COMMAND_PREFIX= \ + GROFF_BIN_PATH="$(GROFF_BIN_PATH)" \ + $(GROFFBIN) $(FFLAG) $(MFLAG) -M$(hdtbl_srcdir) -t -p -e -U + +HDTBLTMACFILES = \ + contrib/hdtbl/hdtbl.tmac \ + contrib/hdtbl/hdmisc.tmac +hdtbltmacdir = $(tmacdir) +dist_hdtbltmac_DATA = $(HDTBLTMACFILES) + +hdtbl_test_template = contrib/hdtbl/examples/test-hdtbl.sh.in + +# Files installed in $(exampledir)/hdtbl. HDTBLEXAMPLEFILES are +# located in the source tree, while HDTBLPROCESSEDEXAMPLEFILES are +# generated in the build tree. + +# These files are handled by the '.in.roff' rule. +HDTBLGENFILES = \ + contrib/hdtbl/examples/fonts_n.roff \ + contrib/hdtbl/examples/fonts_x.roff +EXTRA_DIST += \ + contrib/hdtbl/examples/fonts_n.in \ + contrib/hdtbl/examples/fonts_x.in \ + $(hdtbl_test_template) + +HDTBLEXAMPLEFILES = \ + contrib/hdtbl/examples/common.roff \ + contrib/hdtbl/examples/chess_board.roff \ + contrib/hdtbl/examples/color_boxes.roff \ + contrib/hdtbl/examples/color_nested_tables.roff \ + contrib/hdtbl/examples/color_table_cells.roff \ + contrib/hdtbl/examples/color_transitions.roff \ + contrib/hdtbl/examples/col_rowspan_colors.roff \ + contrib/hdtbl/examples/mixed_pickles.roff \ + contrib/hdtbl/examples/rainbow.roff \ + contrib/hdtbl/examples/short_reference.roff + +HDTBLPROCESSEDEXAMPLEFILES = \ + contrib/hdtbl/examples/chess_board.ps \ + contrib/hdtbl/examples/color_boxes.ps \ + contrib/hdtbl/examples/color_nested_tables.ps \ + contrib/hdtbl/examples/color_table_cells.ps \ + contrib/hdtbl/examples/color_transitions.ps \ + contrib/hdtbl/examples/col_rowspan_colors.ps \ + contrib/hdtbl/examples/fonts_n.ps \ + contrib/hdtbl/examples/fonts_x.ps \ + contrib/hdtbl/examples/mixed_pickles.ps \ + contrib/hdtbl/examples/rainbow.ps \ + contrib/hdtbl/examples/short_reference.ps + +hdtblexampledir = $(exampledir)/hdtbl +dist_hdtblexample_DATA = $(HDTBLEXAMPLEFILES) +nodist_hdtblexample_DATA = \ + $(HDTBLGENFILES) \ + $(HDTBLPROCESSEDEXAMPLEFILES) \ + $(DOC_GNU_EPS) + +$(hdtblexample_DATA): $(HDTBLTMACFILES) + +MOSTLYCLEANFILES += $(HDTBLGENFILES) $(HDTBLPROCESSEDEXAMPLEFILES) + +EXTRA_DIST += \ + contrib/hdtbl/ChangeLog \ + contrib/hdtbl/TODO \ + contrib/hdtbl/groff_hdtbl.7.man + +hdtbl_TESTS = contrib/hdtbl/examples/test-hdtbl.sh +TESTS += $(hdtbl_TESTS) +contrib/hdtbl/examples/test-hdtbl.sh: \ + $(top_builddir)/config.status \ + $(HDTBLPROCESSEDEXAMPLEFILES) \ + $(top_srcdir)/$(hdtbl_test_template) + $(AM_V_GEN)sed \ + -e "s|[@]abs_top_builddir[@]|$(abs_top_builddir)|g" \ + -e "s|[@]GHOSTSCRIPT[@]|$(GHOSTSCRIPT)|g" \ + $(top_srcdir)/$(hdtbl_test_template) > $@ \ + && chmod +x $@ +MOSTLYCLEANFILES += $(hdtbl_TESTS) + +# Rule to generate ps and roff files +SUFFIXES += .roff .in .ps + +.roff.ps: + $(GROFF_V)$(MKDIR_P) `dirname $@` \ + && $(HDTBLGROFF) -I $(doc_builddir) -I $(doc_srcdir) -Tps \ + -dfontpath=$(top_srcdir)/font \ + -dsopath=$(hdtbl_srcdir)/ \ + -mhdtbl $< >$@ + +.in.roff: + $(AM_V_GEN)$(MKDIR_P) `dirname $@` \ + && sed -e "s|[@]fontdir[@]|$(fontdir)|" \ + -e "s|[@]EGREP[@]|$(EGREP)|" $< >$@ + + +$(HDTBLPROCESSEDEXAMPLEFILES): $(DOC_GNU_EPS) groff troff eqn pic tbl \ + grops font/devps/stamp contrib/hdtbl/examples/common.roff + +uninstall_groffdirs: uninstall-hdtbl-hook +uninstall-hdtbl-hook: + if test -d $(DESTDIR)$(hdtblexampledir); then \ + rmdir $(DESTDIR)$(hdtblexampledir); \ + fi + + +# Local Variables: +# mode: makefile-automake +# fill-column: 72 +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/contrib/hdtbl/hdtbl.tmac b/contrib/hdtbl/hdtbl.tmac new file mode 100644 index 0000000..422ede7 --- /dev/null +++ b/contrib/hdtbl/hdtbl.tmac @@ -0,0 +1,1003 @@ +.ig + +hdtbl.tmac + +This file is part of groff, the GNU roff type-setting system. + +Copyright (C) 2005-2020 Free Software Foundation, Inc. +written by Joachim Walsdorff . + +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 . + +.. +. +. +.\" ***************************************************************** +.\" * hdtbl - Heidelberger table macros * +.\" * Vers. 0.91 December 2005 * +.\" ***************************************************************** +. +.if d TBL \ +. nx +. +.mso hdmisc.tmac +.mso 62bit.tmac +. +. +.\" ***************************************************************** +.\" * default values for some arguments * +.\" ***************************************************************** +. +.ds t*hl s\" +.ds t*vl s\" +.ds t*tal l\" +.ds t*hal b\" +.ds t*val t\" +.ds t*ff \\n[.fam]\" +.ds t*fst \\n[.f]\" +.ds t*fsz 1 1\" +.ds t*fgc red4\" +.ds t*bgc bisque\" +.ds t*bc red4\" +.nr t*cpd .5n +.nr t*csp .5n +.nr t*b .1n +.nr t*cols 1 +.nr t*v \n[.v] +.nr t*s \n[.ps] +.nr t*hy \n[.hy] +.nr t*l \n[.ll] +. +. +.\" defaults for table captions +.nr t*cptn 0 1 +.ds t*cptn "".sp .4" \ + ".t*pv 1.0 1.0" \ + ".ad l" \ + "\m[\\*[t*fgc]]Table \\n+[t*cptn]:\0\k*\c"\" +. +. +.\" for better error messages +.ds nth-1 st\" +.ds nth-2 nd\" +.ds nth-3 rd\" +. +.\" initialization of various registers +.nr t*# 0 \" table nesting level +.nr t*numb 0 1 \" held table diversion # +. +.ds *#trc* +. +. +.\" ***************************************************************** +.\" * The four base macros and the two optional macros * +.\" ***************************************************************** +. +.ie n \ +. ds g tty:\" +.el \ +. ds g ps: exec\" +. +.\" TBL: table start +.\" predecessor: text, TD or ETB +.\" successor: CPTN or TR +.de TBL +. ds t*m\\n[t*#] \\n[.m]\" +. ie \\n[t*#] \ +. br +. el \{\ +. ds * \\n[.ev]\" +. ev t*tbl +. evc \\*[*] +. di t*tbl0 +. sp .4 \" XXX: hard-coded value +. nr t*i \\n[.i] +. ll -\\n[.i]u +. in 0 +. \} +. nr t*# +1 +. +. \" Save current location for error checking at end +. ds t*FN \\[.F]\" +. ds t*LN \\[.c]\" +. +. t*getarg cols \\$@\" from here string 'args' contains the rest of \\$@ +. ie "\\*[cols]"" \ +. nr t*cols\\n[t*#] \\n[t*cols] +. el \{\ +. ie \B\\*[cols] \ +. nr t*cols\\n[t*#] \\*[cols] +. el \ +. tm \\n[.F]:\\n[.c]: Invalid number of columns value '\\*[cols]'. +. \} +. +. t*getarg cpd \\*[args] \" cell padding +. ie "\\*[cpd]"" \ +. nr t*cpd\\n[t*#] \\n[t*cpd] +. el \{\ +. ie \B\\*[cpd] \ +. nr t*cpd\\n[t*#] \\*[cpd] +. el \ +. tm \\n[.F]:\\n[.c]: Invalid cell padding value '\\*[cpd]'. +. \} +. +. t*getarg csp \\*[args] \" cell spacing +. ie "\\*[csp]"" \ +. nr t*csp\\n[t*#] \\n[t*csp] +. el \{\ +. ie \B\\*[csp] \ +. nr t*csp\\n[t*#] \\*[csp] +. el \ +. tm \\n[.F]:\\n[.c]: Invalid cell spacing value '\\*[csp]'. +. \} +. +. t*getarg border \\*[args] \" border thickness +. ie "\\*[border]"=" \ +. nr t*b\\n[t*#] 0-1 +. el \{\ +. ie "\\*[border]"" \ +. nr t*b\\n[t*#] \\n[t*b] +. el \{\ +. ie \B\\*[border] \ +. nr t*b\\n[t*#] \\*[border] +. el \ +. tm \\n[.F]:\\n[.c]: Invalid border thickness value '\\*[border]'. +. \}\} +. +. t*getarg bc \\*[args] \" border color +. ds t*bc\\n[t*#] \\*[t*bc]\" +. if !"\\*[bc]"" \{\ +. ie m\\*[bc] \ +. ds t*bc\\n[t*#] \\*[bc]\" +. el \{\ +. ie "\\*[bc]"=" \ +. ds t*bc\\n[t*#] =\" +. el \ +. tm \\n[.F]:\\n[.c]: Invalid border color '\\*[bc]'. +. \}\} +. ie "\\*[bc]"=" \ +. ds t*bc\\n[t*#] +. el \{\ +. ie "\\*[bc]"" \ +. ds t*bc\\n[t*#] \\*[t*bc]\" +. el \ +. ds t*bc\\n[t*#] \\*[bc]\" +. \} +. +. t*getarg width \\*[args] \" table/col widths +. if "\\*[width]"=" \ +. ds width +. +. nr b/2\\n[t*#] (\\n[t*b\\n[t*#]] / 2)\" shortcut +. nr cscp\\n[t*#] (\\n[t*csp\\n[t*#]] + \\n[t*cpd\\n[t*#]])\" aux. register +. +. t*getarg height \\*[args] \" table outline height +. ie "\\*[height]"" \ +. nr t*height\\n[t*#] 0 +. el \{\ +. ie \B\\*[height] \ +. nr t*height\\n[t*#] (\\*[height] \ + - ((2 * \\n[cscp\\n[t*#]]) \ + + (3 * \\n[b/2\\n[t*#]]))) +. el \ +. tm \\n[.F]:\\n[.c]: Invalid height value '\\*[height]'. +. \} +. +. t*cl \\*[width] \" get cell widths and offsets +. t*args \\n[t*#] \" look for common arguments +. +. t*getarg tal \\*[args] \" table horizontal alignment +. if "\\*[tal]"" \ +. ds tal \\*[t*tal]\" +. ie "\\*[tal]"l" \ +. nr in\\n[t*#] \\n[.i] +. el \{\ +. ie "\\*[tal]"c" \ +. nr in\\n[t*#] (\\n[.l] - \\n[ll\\n[t*#]]/2 + \\n[.i]) +. el \{\ +. ie "\\*[tal]"r" \ +. nr in\\n[t*#] (\\n[.l] - \\n[ll\\n[t*#]] + \\n[.i]) +. el \{\ +. tmc \\n[.F]:\\n[.c]: Invalid horizontal table alignment '\\*[tal]': +. tm1 " must be 'l', 'c' or 'r'. +. \}\}\} +. +. nr t*r#\\n[t*#] 0 \" initialize row index +. mk toptbl\\n[t*#] +. +. t*P1 \\*[args] +.. +. +. +.\" CPTN: optional table caption +.\" predecessor: TBL +.\" successor: TR +.de CPTN +. ft 1 +. +. if "\\$0"CPTN" \ +. if \\n[t*r#\\n[t*#]] \{\ +. tmc \\n[.F]:\\n[.c]: Invalid placement of '.CPTN'; +. tm1 " must be called immediately after '.TBL'. +. return +. \} +. +. t*getarg val \\$@ +. ds args\\n[t*#] "\\*[args]\" +. +. t*index "\\*[args]" .TR +. ie \\n[t*index] \{\ +. ds *a\\n[t*#] "\\*[args]\" +. substring args\\n[t*#] 0 \\n[t*index] +. substring *a\\n[t*#] \\n[t*index]-2 -1 +. \} +. el \ +. ds *a\\n[t*#] +. +. ie "\\*[val]"b" \{\ +. de t*cptn\\n[t*#] +. *CPTN \\*[args\\n[t*#]] +. rm t*cptn\\n[t*#] +\\.. +. \} +. el \{\ +. ll (\\n[ll\\n[t*#]]u + \\n[in\\n[t*#]]u) +. in \\n[in\\n[t*#]]u +. t*P1 \\*[t*cptn] +' in +\\n[*]u +. t*P1 \\*[args\\n[t*#]] +. t*pv 1 1 +. in +. mk toptbl\\n[t*#] +. \} +. +. t*P1 \\*[*a\\n[t*#]] +.. +. +.als *CPTN CPTN +. +. +.\" TR: table row +.\" predecessor: TBL, CPTN, text, TD or ETB +.\" successor: TD +.de TR +. ft 1 +. if !\\n[t*#] \{\ +. tm \\n[.F]:\\n[.c]: Table row (.TR) without preceding table start (.TBL). +. return +. \} +. +. \" finish previous data cell, if any +. if \\n[t*r#\\n[t*#]] \ +. t*dntr 1 \\n[c#\\*[#t#r]] \\n[t*cols\\n[t*#]] \\*[*#trc*] +. +. nr t*r#\\n[t*#] +1 \" row number in this table +. ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" table row identifier +. \" (*) +. nr c#\\*[#t#r] 0 1 \" clear cell counter +. nr dntr\\*[#t#r] 0 1 \" clear accumulated row height +. +. t*getarg height \\$@ +. ie "\\*[height]"" \ +. nr t*height\\*[#t#r] 0 +. el \{\ +. ie \B\\*[height] \ +. nr t*height\\*[#t#r] \\*[height] +. el \ +. tm \\n[.F]:\\n[.c]: Invalid table row height '\\*[height]'. +. \} +. +. \" If there is a TR with height 'height', the total height of the table +. \" is too high by 3/2 b, independent of the number of TR with 'height'. +. t*args \\*[#t#r] \\n[t*#] \" look for common arguments +. +. t*P1 \\*[args] +.. +. +. +.\" TH: optional table header cell +.\" predecessor: text, TD or TR +.\" successor: text, TD, TR, TBL or ETB +.\" +.\" cell content bolded and horizontally and vertically centered, +.\" else like .TD +.de TH +. ft 1 +. t*getarg hal \\$@ +. if "\\*[hal]"" \ +. ds hal c\" +. +. t*getarg val \\*[args] +. if "\\*[val]"" \ +. ds val m\" +. +. t*getarg fst \\*[args] +. if "\\*[fst]"" \ +. ds fst B\" +. +. TD hal=\\*[hal] val=\\*[val] fst=\\*[fst] \\*[args] +.. +. +. +.\" TD: table data cell +.\" predecessor: text, TD or TR +.\" successor: text, TD, TR, TBL or ETB +.de TD +. ft 1 +. \" finish previous data cell -- note the use of \E +. t*dntr 0 \\n[c#\\*[#t#r]]-1 \En[c#\\*[#t#r]] \\*[*#trc*] +. +. ds *#trc* \\*[#t#r]*\\n[c#\\*[#t#r]]\" table cell identifier +. \" (**) +. +. t*getarg rowspan \\$@ +. nr rowspan 1 +. if !"\\*[rowspan]"" \{\ +. ie \B\\*[rowspan] \{\ +. nr rowspan (\\*[rowspan] >? 1) +. nr *rsp*\\*[*#trc*] (\\n[rowspan] - 1) +. \} +. el \ +. tm \\n[.F]:\\n[.c]: Invalid value of 'rowspan' keyword. +. \} +. +. t*getarg colspan \\*[args] +. nr colspan 1 +. if !"\\*[colspan]"" \{\ +. ie \B\\*[colspan] \ +. nr colspan (\\*[colspan] >? 1) +. el \ +. tm \\n[.F]:\\n[.c]: Invalid value of 'colspan' keyword. +. \} +. +. t*args \\*[#trc] \\*[#t#r] \" look for common arguments +. +. nr in\\*[#trc] \\n[in\\n[t*#]*\\n[c#\\*[#t#r]]] +. nr *cl \\n[cll\\n[t*#]*\\n[c#\\*[#t#r]]] +. nr * 0 1 +. nr *r \\n[t*r#\\n[t*#]] +. +. if (\\n[rowspan] - 1) \ +. while (\\n+[*] <= \\n[rowspan]) \{\ +. nr rspan\\n[t*#]*\\n[*r]*\\n[c#\\*[#t#r]] \\n[colspan] +. if (\\n[*] > 1) \ +. nr cspan\\n[t*#]*\\n[*r]*\\n[c#\\*[#t#r]] \\n[colspan] +. nr *r +1 +. \} +. +. nr * 1 1 +. nr *c \\n[c#\\*[#t#r]] +. +. if (\\n[colspan] - 1) \{\ +. nr vline\\*[*#trc*] 0-1 \" set 'no vl' flag +. +. while (\\n+[*] <= \\n[colspan]) \{\ +. nr *c +1 +. nr *cl +(2 * \\n[cscp\\n[t*#]] \ + + \\n[b/2\\n[t*#]] \ + + \\n[cll\\n[t*#]*\\n[*c]]) +. nr c#\\*[#t#r] +1 +. \} +. \} +. +. if (\\n[c#\\n[t*#]*\\n[t*r#\\n[t*#]]] > \\n[t*cols\\n[t*#]]) \{\ +. ds * are\" +. ds ** columns\" +. if (\\n[c#\\*[#t#r]] == 1) \{\ +. ds * is\" +. ds ** column\" +. \} +. tmc \\n[.F]:\\n[.c]: There \\*[*] \\n[c#\\*[#t#r]] table \\*[**] (.TD) +. +. ds * are\" +. if (\\n[t*cols\\n[t*#]] == 1) \ +. ds * is\" +. tm1 " but only \\n[t*cols\\n[t*#]] \\*[*] expected. +. +. ds * +. length * \\n[.F]:\\n[.c]: +. +. while \\n-[*] \ +. ds * " \\*[*]\" +. +. tm1 "\\*[*] Remaining .TDs and its contents are ignored. +. +. di *t*dummy* \" bypass superfluous input +. return +. \} +. +. di t*\\*[#trc] \" open cell diversion and set locals +. in 0 +. nr cll\\*[#trc] \\n[*cl] +. ll \\n[*cl]u +. nr *cl\\n[t*#] \\n[.l] +. gcolor \\*[t*fgc\\*[#trc]] +. ad \\*[t*hal\\*[#trc]] +. fam \\*[t*ff\\*[#trc]] +. ft \\*[t*fst\\*[#trc]] +. t*pv \\*[t*fsz\\*[#trc]] +. +. t*P1 \\*[args] +.. +. +. +.\" ETB: end of table +.\" predecessor: text, TD or ETB +.\" successor: text, TD, TR or TBL +.de ETB +. ie \\n[t*#] \ +. if !\\n[t*r#\\n[t*#]] \{\ +. tmc \\n[.F]:\\n[.c]: Each table (.TBL) +. tm1 " should contain at least one table row (.TR)! +. \} +. el \{\ +. tmc \\n[.F]:\\n[.c]: Table end (.ETB) +. tm1 " without corresponding table start (.TBL)! +. \} +. +. ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" refresh table row identifier +. t*dntr 2 \\n[c#\\*[#t#r]] \\n[t*cols\\n[t*#]] \\*[*#trc*] +. +. t*divs \" print this table +. +. sp \\n[b/2\\n[t*#]]u +. t*cptn\\n[t*#] +. nr t*# -1 +. +. ll \\n[*cl\\n[t*#]]u \" restore ll outside this table +. in 0 \" reset indent +. gcolor \\*[t*m\\n[t*#]] \" reset previous fgc +. +. t*getarg hold \\$@ +. if !\\n[t*#] \{\ +. sp .5 +. di +. in \\n[t*i]u +. ie "\\*[hold]"" \{\ +. ie (\\n[.t] - \\n[dn]) \ +. t*DI t*tbl0 +. el \{\ +. rn t*tbl0 t*tbl\\n+[t*numb] +. ds t*kept \\*[t*kept] t*tbl\\n[t*numb] \\n[dn]\" +. \} +. \} +. el \{\ +. rn t*tbl0 t*hold\\n+[t*numb] +. tm \\n[.F]:\\n[.c]: Table t*hold\\n[t*numb] held. +. ds t*held \\*[t*held] t*hold\\n[t*numb] \\n[dn]\" +. \} +. +. ev \" restore previous environment +. \} +. +. t*P1 \\*[args] +.. +. +. +.\" ***************************************************************** +.\" * Following the definition of five utility macros * +.\" * special to hdtbl. * +.\" * Other utility macros common to hdtbl and hdgroff * +.\" * are defined in the file hdmisc.tmac. * +.\" ***************************************************************** +. +. +.\" .t*free [n] +.\" print the next [n] held table[s]. +.\" Don't call it within a table! +.\" If the table is higher than the remaining space +.\" on the page, the table is printed on the next page. +.de t*free +. if "\\$0"CPTN" \ +. if \\n[t*r#\\n[t*#]] \{\ +. tmc \\n[.F]:\\n[.c]: Invalid placement of '.t*free' within a table; +. tm1 " it must be called outside of any table. +. return +. \} +. +. if "\\*[t*held]"" \{\ +. tm \\n[.F]:\\n[.c]: No held tables. +. return +. \} +. +. nr ** (\\$1 >? 1) 1 +. while !""\\*[t*held]" \{\ +. pops * t*held +. popr * t*held +. +. ie (\\n[.t] - \\n[*]) \{\ +. ev t*tbl +. t*DI \\*[*] +. ev +. \} +. el \{\ +. rn \\*[*] t*tbl\\n+[t*numb] +. ds t*kept \\*[t*kept] t*tbl\\n[t*numb] \\n[*]\" +. \} +. +. if !(\\n-[**] - 1) \ +. return +. \} +.. +. +. +.\" The main utility macro for tables: +.\" If a table is closed by ETB, this macro is called. It +.\" processes one complete table, i.e., all the table cell +.\" diversions, paints the cell backgrounds, draws +.\" horizontal and vertical table lines and the table border. +.\" +.\" Nested tables are processed from inside to outside. +. +.de t*divs +. ll (\\n[t*l]u + 1c) \" avoid warning 'can't break line' +. nf +. +. nr b/2 \\n[b/2\\n[t*#]] \" some abbreviations +. nr cscp \\n[cscp\\n[t*#]] +. nr cscpb (\\n[b/2] + \\n[cscp]) +. +. nr topdiv (\\n[.d] + \\n[b/2] - \\n[cscp])\" top of cell diversion +. nr cscpb2 (\\n[b/2] / 2 + \\n[cscp]) +. +. nr #r 0 1 +. \" outer loop for rows +. while (\\n+[#r] <= \\n[t*r#\\n[t*#]]) \{\ +. \" TODO: insert code here for multipage tables +. nr * (\\n[#r] - 1) +. nr topdiv +(\\n[dntr\\n[t*#]*\\n[*]] + \\n[cscp] + \\n[cscpb]) +. +. \" if table still smaller than specified table height, increase it +. if ((\\n[#r] == \\n[t*r#\\n[t*#]]) & \\n[t*height\\n[t*#]]) \ +. nr dntr\\n[t*#]*\\n[#r] (\\n[cscpb] \ + + \\n[toptbl\\n[t*#]] \ + + \\n[t*height\\n[t*#]] \ + - (\\n[topdiv] >? \\n[dntr\\n[t*#]*\\n[#r]])) +. +. nr #c 0 1 +. \" inner loop for cells +. while (\\n+[#c] <= \\n[t*cols\\n[t*#]]) \{\ +. ds #trc \\n[t*#]*\\n[#r]*\\n[#c]\" +. \" continue if the diversion is empty +. if !d t*\\*[#trc] \ +. continue +. +. sp |\\n[topdiv]u +. in (\\n[in\\n[t*#]]u + \\n[in\\*[#trc]]u)\" cell offset +. nr $1 \\n[dntr\\n[t*#]*\\n[#r]] \" cell height +. +. \" if we have spanned rows, calculate resulting row height +. \" and position of lower horizontal line +. if \\n[*rsp*\\*[#trc]] \{\ +. nr * \\n[#r] 1 +. nr rspan\\*[#trc] 0-1 \" set 'no hl' flag +. nr corr (\\n[dn\\*[#trc]] - \\n[dntr\\n[t*#]*\\n[#r]]) +. +. \" clear row span flags in following rows and update row height +. while \\n[*rsp*\\*[#trc]] \{\ +. nr *rsp*\\*[#trc] -1 +. nr rspan\\n[t*#]*\\n+[*]*\\n[#c] 0 +. nr ** (\\n[dntr\\n[t*#]*\\n[*]] + \\n[cscp] + \\n[cscpb]) +. nr corr -\\n[**] +. nr $1 +\\n[**] +. \} +. +. if (\\n-[*] == \\n[t*r#\\n[t*#]]) \ +. nr $1 ((\\n[t*height\\n[t*#]] \ + - \\n[.d] \ + + \\n[toptbl\\n[t*#]] \ + + \\n[cscpb]) \ + >? \\n[$1]) +. nr dntr\\n[t*#]*\\n[*] +(\\n[corr] >? 0) +. \} +. +. \" paint cell background +. nr * (2 * \\n[t*cpd\\n[t*#]] + \\n[cll\\*[#trc]])\" background width +. nr $1 (\\n[$1] >? \\n[dn\\*[#trc]])\" cell height +. +. if !"\\*[t*bgc\\*[#trc]]"=" \{\ +. nop \h'\\n[t*csp\\n[t*#]]u'\ +\M[\\*[t*bgc\\*[#trc]]]\ +\v'(-.67v - \\n[t*cpd\\n[t*#]]u)'\ +\D'P \\n[*]u 0 \ + 0 (2u * \\n[t*cpd\\n[t*#]]u + \\n[$1]u) \ + -\\n[*]u 0'\ +\M[] +. sp -1 +. \} +. +. \" *** horizontal and vertical single or double lines *** +. \" double and single lines have the same thickness; +. \" the double lines' distance is the line thickness. +. \" +. \" 'border=x': horizontal/vertical lines x/2 thick, minimum .1n +. \" 'border=0': no border; horizontal/vertical lines .1n thick +. \" 'border=': neither border nor horizontal/vertical lines +. +. nr *t (.1n >? \\n[b/2]) \" thickness of hl/vl; min. .1n +. in +\\n[cscp]u +. +. \" check for vertical and horizontal lines +. if (1 + \\n[t*b\\n[t*#]]) \{\ +. if !"\\*[t*bc\\n[t*#]]"=" \{\ +. \" draw horizontal line between this cell and the one below +. if (\\n[t*r#\\n[t*#]] - \\n[#r] + \\n[rspan\\*[#trc]]) \{\ +. if !"\\*[t*hl\\*[#trc]]"=" \{\ +. sp \\n[$1]u +. nr * (\\n[cscp] + \\n[cscpb] + \\n[cll\\*[#trc]]) +. nop \X'\*[g] 1 setlinecap'\ +\h'(-\\n[cscpb2]u - \\n[*t]u)'\ +\v'(\\n[cscpb2]u - .67v)'\ +\m[\\*[t*bc\\n[t*#]]]\ +\D't \\n[*t]u'\c +. +. ie "\\*[t*hl\\*[#trc]]"d" \ +. nop \v'-\\n[*t]u'\ +\D'l \\n[*]u 0'\ +\v'(2u * \\n[*t]u)'\ +\D'l -\\n[*]u 0'\ +\D't 0' +. el \ +. nop \D'l \\n[*]u 0'\ +\D't 0' +. +. sp (-\\n[$1]u - 1v) +. \}\} +. +. nr rspan\\*[#trc] 0 +. +. \" draw vertical line between this cell and the one to the right +. if (\\n[t*cols\\n[t*#]] - \\n[#c] + \\n[vline\\*[#trc]]) \{\ +. if !"\\*[t*vl\\*[#trc]]"=" \{\ +. nop \X'\*[g] 1 setlinecap'\ +\v'(-\\n[cscpb2]u - .67v)'\ +\m[\\*[t*bc\\n[t*#]]]\ +\h'(\\n[cscpb2]u - \\n[*t]u + \\n[cll\\*[#trc]]u)'\c +. +. ie "\\*[t*vl\\*[#trc]]"d" \ +. nop \h'-\\n[*t]u'\ +\D't \\n[*t]u'\ +\D'l 0 (2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\ +\h'(2u * \\n[*t]u)'\ +\D'l 0 -(2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\ +\D't 0' +. el \ +. nop \D't \\n[*t]u'\ +\D'l 0 (2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\ +\D't 0' +. sp -1 +. \}\}\}\} +. +. nr vline\\*[#trc] 0 +. +. \" vert. cell content alignment +. nr ** 0 +. +. ie "\\*[t*val\\*[#trc]]"m" \ +. nr ** ((\\n[$1] - \\n[dn\\*[#trc]]) / 2)\" val=m +. el \ +. if "\\*[t*val\\*[#trc]]"b" \ +. nr ** (\\n[$1] - \\n[dn\\*[#trc]])\" val=b +. +. sp \\n[**]u \" vertical content position +. +. \" finally output the diversion +. t*\\*[#trc] +. rm t*\\*[#trc] +. \} +. \} +. +. \" draw the box border +. in \\n[in\\n[t*#]]u +. nr ** (\\n[topdiv] + \\n[dntr\\n[t*#]*\\n-[#r]]) +. +. if \\n[t*b\\n[t*#]] \{\ +. sp |(\\n[toptbl\\n[t*#]]u + \\n[b/2]u) +. nr $1 (\\n[toptbl\\n[t*#]] - \\n[**] - \\n[cscp]) +. nr * (\\n[ll\\n[t*#]] - \\n[t*b\\n[t*#]]) +. +. if !"\\*[t*bc\\n[t*#]]"=" \ +. nop \X'\*[g] 0 setlinejoin 2 setlinecap'\ +\v'-.67v'\ +\h'-\\n[b/2]u'\ +\m[\\*[t*bc\\n[t*#]]]\ +\D't \\n[t*b\\n[t*#]]u'\ +\D'l \\n[*]u 0'\ +\D'l 0 -\\n[$1]u'\ +\D'l -\\n[*]u 0'\ +\D'l 0 \\n[$1]u'\ +\D't 0' +. \} +. +. sp |(\\n[**]u + \\n[cscpb]u) +. fi +.. +. +. +.\" Utility macro: .t*cl [width1 [width2 [...]]] +.\" +.\" Calculate cell widths, table width, and cell offsets. +.de t*cl +. nr t*cols\\n[t*#] (\\n[.$] >? \\n[t*cols\\n[t*#]]) +. nr ll\\n[t*#] 0 \" accumulated cell widths +. nr ** (\\n[.l] / \\n[t*cols\\n[t*#]])\" width for remaining cells +. nr * 0 1 \" counter +. +. \" while-loop: Parse user arguments to get each cell's width. +. while (\\n[t*cols\\n[t*#]] >= \\n+[*]) \{\ +. nr $\\n[*] \\n[**] +. if !"\\$[\\n[*]]"" \{\ +. \" check for '%' pseudo scaling indicator +. ds * \\$\\n[*]\" +. substring * -1 -1 +. ie "\\*[*]"%" \{\ +. ds ** \\$[\\n[*]]\" +. substring ** 0 -2 +. ie \B\\*[**] \ +. nr $\\n[*] (\\*[**] * \\n[.l] / 100) +. el \ +. tm \\n[.F]:\\n[.c]: Invalid relative cell width '\\*[**]%'. +. \} +. el \{\ +. ie \B\\$[\\n[*]] \ +. nr $\\n[*] \\$[\\n[*]] +. el \ +. tm \\n[.F]:\\n[.c]: Invalid cell width '\\$[\\n[*]]'. +. \}\} +. +. nr ll\\n[t*#] +\\n[$\\n[*]] +. nr ** \\n[$\\n[*]] +. \} +. +. if (\\n[ll\\n[t*#]] > \\n[.l]) \ +. tm \\n[.F]:\\n[.c]: Table width larger than column width. +. +. nr ** (0 >? \\n[t*b\\n[t*#]]) +. nr * 0 1 +. +. \" second while loop: Compute final cell widths. +. while (\\n[t*cols\\n[t*#]] >= \\n+[*]) \{\ +. \" Remove border width, if any. +. if \\n[t*b\\n[t*#]] \{\ +. \" cell_width := cell_width * (length - 1.5*border) / length +. nr #* (\\n[ll\\n[t*#]] - (3 * \\n[t*b\\n[t*#]] / 2)) +. nr *** (\\n[ll\\n[t*#]] / 2) +. \" avoid multiplication overflow +. mult31by31 $\\n[*] #* **** +. add31to62 *** **** **** +. div62by31 **** ll\\n[t*#] $\\n[*] +. \} +. +. \" Get cell widths without padding, spacing, and separator line. +. nr cll\\n[t*#]*\\n[*] (\\n[$\\n[*]] \ + - (2 * \\n[cscp\\n[t*#]]) \ + - \\n[b/2\\n[t*#]]) +. +. \" Check whether value is non-positive. +. if !\\n[cll\\n[t*#]*\\n[*]] \{\ +. nr #* (\\n[ll\\n[t*#]] - (3 * \\n[t*b\\n[t*#]] / 2)) +. nr *** (\\n[#*] / 2) +. nr *h (2 * \\n[cscp\\n[t*#]] + \\n[b/2\\n[t*#]]) +. mult31by31 *h ll\\n[t*#] **** +. add31to62 *** **** **** +. div62by31 **** #* *h +. ds * \\n[*]th\" +. nr *** (\\n[*] % 10) +. if d nth-\\n[***] \ +. ds * \\n[*]\\*[nth-\\n[***]]\" +. tmc \\n[.F]:\\n[.c]: The \\*[*] width value (\\$\\n[*]) is too small. +. tm1 " It should be greater than \\n[*h]. +. \} +. +. nr in\\n[t*#]*\\n[*] \\n[**] \" cell offset +. nr ** +\\n[$\\n[*]] +. \} +.. +. +. +.\" Utility macro: .t*dntr ? +.\" +.\" Close TD diversion, make some calculations, and set +.\" some help strings and registers. is 0, 1, +.\" or 2 if the call of .t*dntr occurs in .TD, .TR, or +.\" .ETB, respectively. +.de t*dntr +. nr dn 0 \" reset diversion height +. br \" finish cell data +. +. if "\\n[.z]"*t*dummy*" \ +. return +. +. ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" refresh table row identifier +. +. if \\n[c#\\*[#t#r]] \{\ +. di \" close diversion +. nr dn\\$4 \\n[dn] \" save height of this cell +. if !\\n[rspan\\*[#trc]] \{\ +. \" update row height if not in a row span +. nr dntr\\*[#t#r] (\\n[dntr\\*[#t#r]] >? \\n[dn]) +. if \\$2 \ +. nr dntr\\*[#t#r] ((\\n[t*height\\*[#t#r]] \ + - (2 * \\n[cscp\\n[t*#]] + \\n[b/2\\n[t*#]])) \ + >? \\n[dntr\\*[#t#r]]) +. \}\} +. +. nr c#\\*[#t#r] +1 +. nr * \\$2 +. +. \" update column span registers +. while (\\n+[*] <= \\$3) \{\ +. if r cspan\\*[#t#r]*\\n[*] \ +. nr c#\\*[#t#r] +\\n[cspan\\*[#t#r]*\\n[*]] +. nr cspan\\*[#t#r]*\\n[*] 0 +. \} +. +. ds #trc \\*[#t#r]*\\n[c#\\*[#t#r]]\" +. +. \" only check for cell underflow if called by .TR or .ETB +. if (\\$1 & (\\n[c#\\*[#t#r]] <= \\n[t*cols\\n[t*#]])) \{\ +. ds * are\" +. ds ** columns\" +. if (\\n-[c#\\*[#t#r]] == 1) \{\ +. ds * is\" +. ds ** column\" +. \} +. tmc \\n[.F]:\\n[.c]: There \\*[*] only \\n[c#\\*[#t#r]] \\*[**] +. +. nr * \\n[t*r#\\n[t*#]] +. ds * \\n[*]th\" +. nr *** (\\n[*] % 10) +. if d nth-\\n[***] \ +. ds * \\n[*]\\*[nth-\\n[***]]\" +. tmc " in the \\*[*] row +. +. ds * are\" +. if (\\n[t*cols\\n[t*#]] == 1) \ +. ds * is\" +. tm1 " but \\n[t*cols\\n[t*#]] \\*[*] expected. +. \} +.. +. +. +.\" Utility-macro: .t*args level_1 [level_2] +.\" +.\" Get the arguments common to TBL, TR, and TD for the level +.\" in argument 1, using default values from the level in +.\" argument 2. If argument 2 is missing, use the global +.\" default values. +.\" +.de t*args +. ds t*bgc\\$1 \\*[t*bgc\\$2]\" +. ds t*fgc\\$1 \\*[t*fgc\\$2]\" +. ds t*hl\\$1 \\*[t*hl\\$2]\" +. ds t*vl\\$1 \\*[t*vl\\$2]\" +. ds t*hal\\$1 \\*[t*hal\\$2]\" +. ds t*val\\$1 \\*[t*val\\$2]\" +. ds t*ff\\$1 \\*[t*ff\\$2]\" +. ds t*fst\\$1 \\*[t*fst\\$2]\" +. ds t*fsz\\$1 \\*[t*fsz\\$2]\" +. +. if "\\*[args]"" \ +. return +. +. t*getarg bgc \\*[args] \" background color +. if !"\\*[bgc]"" \{\ +. ie m\\*[bgc] \ +. ds t*bgc\\$1 \\*[bgc]\" +. el \{\ +. ie "\\*[bgc]"=" \ +. ds t*bgc\\$1 =\" +. el \ +. tm \\n[.F]:\\n[.c]: Invalid background color '\\*[bgc]'. +. \}\} +. if "\\*[args]"" \ +. return +. +. t*getarg fgc \\*[args] \" foreground color +. if !"\\*[fgc]"" \{\ +. ie m\\*[fgc] \ +. ds t*fgc\\$1 \\*[fgc]\" +. el \{\ +. ie "\\*[fgc]"=" \ +. ds t*fgc\\$1 =\" +. el \ +. tm \\n[.F]:\\n[.c]: Invalid foreground color '\\*[fgc]'. +. \}\} +. if "\\*[args]"" \ +. return +. +. t*getarg hl \\*[args] \" horizontal line between cells +. if !"\\*[hl]"" \ +. ds t*hl\\$1 \\*[hl]\" +. if "\\*[args]"" \ +. return +. +. t*getarg vl \\*[args] \" vertical line between cells +. if !"\\*[vl]"" \ +. ds t*vl\\$1 \\*[vl]\" +. if "\\*[args]"" \ +. return +. +. t*getarg hal \\*[args] \" horizontal table cell alignment +. if !"\\*[hal]"" \{\ +. t*index bcrl \\*[hal] +. ie \\n[t*index] \ +. ds t*hal\\$1 \\*[hal]\" +. el \{\ +. tmc \\n[.F]:\\n[.c]: Invalid horizontal alignment '\\*[hal]': +. tm1 " must be 'b', 'c', 'l' or 'r'. +. \}\} +. if "\\*[args]"" \ +. return +. +. t*getarg val \\*[args] \" vertical table cell alignment +. if !"\\*[val]"" \{\ +. t*index tmb \\*[val] +. ie \\n[t*index] \ +. ds t*val\\$1 \\*[val]\" +. el \{\ +. tmc \\n[.F]:\\n[.c]: Invalid vertical alignment '\\*[val]': +. tm1 " must be 't', 'm' or 'b'. +. \}\} +. if "\\*[args]"" \ +. return +. +. t*getarg ff \\*[args] \" font family +. if !"\\*[ff]"" \ +. ds t*ff\\$1 \\*[ff]\" +. if "\\*[args]"" \ +. return +. +. t*getarg fst \\*[args] \" font style +. if !"\\*[fst]"" \ +. ds t*fst\\$1 \\*[fst]\" +. if "\\*[args]"" \ +. return +. +. t*getarg fsz \\*[args] \" font size and spacing factor +. if !"\\*[fsz]"" \ +. ds t*fsz\\$1 \\*[fsz]\" +.. +. +. +.\" Append to your page header macro ('pg@top' for MS) +.\" to enable tables to span pages. +.de t*hm +. ev t*tbl +. nr ** \\n[.t] +. while !""\\*[t*kept]" \{\ +. pops * t*kept +. popr * t*kept +. if (\\n[*] - \\n[**]) \{\ +. tm \\n[.F]:\\n[.c]: Table \\*[*] higher than page -- ignored! +. break +. \} +. +. if (\\n[*] - \\n[.t]) \{\ +. ds t*kept \\n[*] \\*[t*kept]\" +. ds t*kept \\*[*] \\*[t*kept]\" +. tmc \\n[.F]:\\n[.c]: Remaining table(s), +. tm1 " because not all fit onto this page. +. break +. \} +. +. t*DI \\*[*] +. \} +. ev +.. +. +.\" Local Variables: +.\" mode: nroff +.\" End: +.\" vim: filetype=groff: diff --git a/contrib/mm/ChangeLog b/contrib/mm/ChangeLog new file mode 100644 index 0000000..6c17811 --- /dev/null +++ b/contrib/mm/ChangeLog @@ -0,0 +1,1672 @@ +2023-05-25 G. Branden Robinson + + * groff_mm.7.man (Macros) : Clarify operation. + + Fixes . + +2023-02-17 G. Branden Robinson + + [mm]: Add `--help` option support to mmroff. + + * mmroff.pl: Recognize `--help` option. + * mmroff.1.man (Synopsis, Options): Document. + +2023-02-01 G. Branden Robinson + + * m.tmac (H, SETR): Trivially refactor. Rename register to + conform to convention: `hd-mark-trimmed` -> `hd@mark-trimmed`. + This register is used outside of its "module", "hd". + +2023-02-01 G. Branden Robinson + + * m.tmac (H, LI): Trivially refactor. Annotate and test + threshold registers consistently. + +2023-02-01 G. Branden Robinson + + * m.tmac: Fix code style nit. Except for initial register + tests for GNU troff formatter and compatibility mode, migrate + special character, register, and string interpolation escape + sequences from `(xx` form to `[xx]`. Also rewrite an instance + of `\nP` to `\n[P]`. + +2023-01-24 G. Branden Robinson + + When register `Pt` was 2, paragraphs immediately following + displays and lists were being indented, contrary to DWB mm + behavior. + + * m.tmac: Replace `par@ind-flag` register with two separate + state bits, `par*indentation-eligible` and + `par@suppress-indentation`. + (P, nP): Remove complex test for deciding whether the current + paragraph is being set immediately after a heading. + (P): Set `par*indentation-eligible` to the logical complement of + `par@suppress-indentation`. Call `par@doit` (which underlies + both `P` and `nP`) unconditionally. + (nP): Force `par*indentation-eligible` off, since numbered + paragraphs are not influenced by a `Pt` value of "2" in DWB mm. + {The paragraph number occupies the indentation space.} + (par@doit): Introduce local register `par*do-indent`, + manipulate it, and use it to control `ti` request instead of + scattering the request across multiple locations. Remove this + register when done. Clear `par@suppress-indentation` at end, + since after indentation is suppressed once, it should not happen + again until a special circumstance (the setting of a heading, + display, or list) arises. + (H): Convert test of `hd*htype` register, which tells us if + we're setting a run-in heading or not, from `if` to `ie`. (The + first paragraphing macro call after a run-in heading should + _not_ have its indentation suppressed, because the material + after the heading title constitutes a first pagraph.) In the + true arm, set `par@suppress-indentation`; in the new else arm, + clear it. This replaces the "complex test" above, and seems + much more straightforward and reliable. Stop manipulating + `par@ind-flag`. + (df@end, ds@end, LC): Set `par@suppress-indentation` instead of + clearing `par@ind-flag`. + (LE): Set `par@suppress-indentation`. + + Fixes . Thanks to Jeff + Conrad for the report. + +2023-01-24 G. Branden Robinson + + Regression-test Savannah #54909. + + * tests/P-indentation-works.sh: Do it. + * mm.am (mm_TESTS): Run test. + +2023-01-24 G. Branden Robinson + + * m.tmac (df@print-float): Eliminate spew at high debug levels. + This macro gets called even when there aren't any floating + displays pending, so we cannot assume that related registers are + defined. + +2023-01-24 G. Branden Robinson + + * m.tmac (P): Fix missing backslash after brace escape sequence. + Problem introduced by me in 3b1afbdb8e, 6 January. + +2023-01-22 G. Branden Robinson + + * m.tmac: Help user navigate the document type macros. Stop + setting up the formatter to throw "unrecognized macro" + diagnostics for macros that are plainly documented in + groff_mm(7). + (@disable): New macro takes a list of macros whose definitions + are replaced with a warning diagnostic about how they're no + longer unavailable due to use of another document type macro + already called, identified by new string `@cover`. + (TL, MT, COVER, LT, LO): Define `@cover` and call `@disable`. + Drop existing diagnostics that did a similar thing as above, + more verbosely. + +2023-01-17 G. Branden Robinson + + * m.tmac: Revise diagnostic messages. Use a consistent message + format, including a space after a colon and the name of the + complaining macro. + (pg@header): Drop unnecessary empty comment at end of macro + call. Macro call syntax differs from `ds` request syntax. + (2C, MC, FD, FS, FE, DF, LB, LI, LE, LC, AL, ML, VL, BL, DL, RL) + (BVL, TH, TE, PS, B1, B2, APPSK, AS, SETR, GETST, GETHN, GETPN) + (INITI, IND, LT, LO): Refer to self with `\$0` escape sequence + instead of a literal. + (2C, MC, PS): Throw fatal error immediately instead of doing + other processing first. + (2C, MC, FD, FS, FE, DF, ds@set-format, ds@end, LB, LI, LE, LC) + (AL, ML, VL, BL, DL, RL, BVL, TH, TE, B1, B2, APPSK, AS, SETR) + (GETST, GETHN, GETPN, INITI, IND, let*lt-sign, LT, LO): Stop + unnecessarily quoting arguments to @error macro. + (FD, LB, VL, BVL, APPSK, SETR, GETST, GETHN, GETPN, INITI): + State quantities of expected and actual arguments. + (FS, FE, LC, B1, INITI): Clarify message. + (DF, DS): Store macro name in `ds@macro` for use in later + diagnostics thrown by internal macros. + (DS): Drop dead store to register `XXX`; debugging detritus? + (ds@set-format): Use `ds@macro`. + (ds@set-format, let*lt-sign, LT, LO): Bracket unrecognized + argument in single quotes. + (ds@set-format): Characterize argument as "unrecognized", not + "wrong". Similarly with the fill style. + (LI, LE, IND): Offer advice. + (LE): Describe problem in same terms as `LI` ("no list active"). + (LC): Validate argument as numeric expression and die with + diagnostic if it isn't one. + (AL, ML, VL, BL, DL, RL, BVL): Weaken fatal diagnostic to + warning; excess arguments are not a serious problem. + (PS): Simplify control flow; since @error does not return, + convert `ie` request to `if` and make `el` branch unconditional. + (RP): Weaken fatal diagnostic to warning and return early; + calling this macro without any references defined does no + structural damage to a document. + (INITI): Remove redundant conditional. + +2023-01-16 G. Branden Robinson + + * m.tmac (IX): Delete. + +2023-01-16 G. Branden Robinson + + * m.tmac (MC): Throw internal error if we don't leave + `pg*cols-per-page` in a valid state after invalidating it to + count columns. Also simplify expression. + +2023-01-16 G. Branden Robinson + + * m.tmac (1C): Warn and return early instead of bombing out if + called when multiple columnation is inactive. A no-op should + not be a fatal error. + +2023-01-16 G. Branden Robinson + + * m.tmac (@abort): Introduce macro for internal errors, + unconditionally reporting a backtrace... + (misc@pop-set, hd@split, MULN, df@print-float, IND): ..and use + it instead of `@error` for problems with internal state. + (IND): Also fix botch in reported error. + +2023-01-16 G. Branden Robinson + + * m.tmac (SA): Reject an argument value > 1 as invalid. + +2023-01-16 G. Branden Robinson + + * m.tmac (P): Quote unrecognized argument in warning diagnostic. + (OK, PM): Refactor to use `\$0`. + (1C): Clarify that formatting can go wrong if you suppress a + page break when returning from multi- to single-column mode with + a footnote pending. + +2023-01-16 G. Branden Robinson + + * m.tmac (Tm): Align with definition of `Sm`, with analogous + fallback definitions. + +2023-01-16 G. Branden Robinson + + * m.tmac (Sm): Implement string for service mark, for DWB mm + compatibility. + * groff_mm.7.man: Document it. + +2023-01-16 G. Branden Robinson + + * m.tmac (CS): Define to throw diagnostic when used without ".MT + 4". (Later, if the "4.MT" file is sourced, this definition is + replaced.) + * groff_mm.7.man (Description): Clarify `CS` support status. + +2023-01-16 G. Branden Robinson + + * m.tmac (MOVE, SM, AT, LO): Weaken diagnostics when given no + arguments from (fatal) errors to warnings, then return. + +2023-01-16 G. Branden Robinson + + * m.tmac (PIC): Bomb out (with diagnostic) if either of the + width or height arguments are not numeric expressions. + +2023-01-16 G. Branden Robinson + + * m.tmac (EPIC): Handle and shift off a leading "-L" argument + before checking argument count. Then, if fewer than two + arguments remain, throw warning diagnostic and return early + instead of bombing out. Do bomb out (with diagnostic) if either + of the width or height arguments are not numeric expressions. + Fix bug which prevented third argument from being interpreted. + Annotate potential future development. + +2023-01-16 G. Branden Robinson + + * m.tmac (AU): Partially revert commit 4fd984adc9, 2021-07-17. + `AU` can be called for the sole purpose of "closing" a document + title "opened" with `TL`. + * groff_mm.7.man (Macros) : Update description. + +2023-01-16 G. Branden Robinson + + * m.tmac (TM): Warn if called without arguments. + +2023-01-16 G. Branden Robinson + + * m.tmac (AST): Preserve any user-specified leading spaces in + argument. + +2023-01-06 G. Branden Robinson + + * m.tmac (P): Warn if argument is non-numeric, and discard it. + Also warn if argument is out of range; people accustomed to + setting the `Pt` register to 2 might mistakenly believe it to be + meaningful here. + +2023-01-03 G. Branden Robinson + + * mm/0.MT: + * mm/5.MT: Drop never-read register `cov*mt0-ind`. + +2023-01-03 G. Branden Robinson + + Improve cover sheet diagnostics. + + * m.tmac (MT): Warn and ignore if `COVER` or self already + called. + (COVER): Warn and ignore if `MT` already called. + * mm/0.MT (cov@print-title): Abort if title not defined; tell + user how to use the macros. + (cov@print-authors): Add similar paranoid diagnostic that I + don't think is reachable (since you _have_ to call `AU` to + "close" `TL`). + * mm/4.MT (cov@print-title, cov@print-authors): + * mm/5.MT (cov@print-title): As "0.MT". + + * mm/4.MT: Get rid of spurious blank line in file. + +2023-01-03 G. Branden Robinson + + Fix Savannah #63613. + + * mm/0.MT (cov*print-authors): Iterate through _all_ technical + memorandum numbers instead of stopping one shy of the last. + Problem appears to date back to introduction of TM support for + memorandum type 1 in commit a48ab7b6d (groff 1.05, 1992-03-18). + + Fixes . + +2023-01-03 G. Branden Robinson + + Regression-test Savannah #63613. + + * tests/MT-1-reports-all-TM-numbers.sh: Do it. + * mm.am (mm_TESTS): Run test. + +2022-12-17 G. Branden Robinson + + * m.tmac (let*mt-sign): Check strings populated by optional + arguments to `AU` macro for existence before interpolating them. + + Fixes . Thanks to Werner + Lemberg for the report. + +2022-11-22 G. Branden Robinson + + * mse.tmac: Set `pg*footer-size` to four vees, not four basic + units; the latter is too small by orders of magnitude on + typesetting output devices. + + Fixes . Thanks to Hans + Bezemer for the report. + +2022-11-21 G. Branden Robinson + + Regression-test Savannah #63398. + + * tests/mse_has-sufficient-footnote-space.sh: Do it. + * mm.am (mm_TESTS): Run test. + +2022-10-09 G. Branden Robinson + + [mm]: Add `--version` option support to mmroff. + + * mm.am (mmroff): Replace `@VERSION@` token in script. + * mmroff.pl: Recognize `--version` option. + * mmroff.1.man (Synopsis, Options): Document. + +2022-10-09 G. Branden Robinson + + * mmroff.pl: Add proper diagnostic subroutine. Add "progname" + scalar to store the name of the program. + (Die): New subroutine. + (print_index, top level): Call Die() when encountering + prohibitive problems instead of flinging a string into a void + context. + +2022-10-09 G. Branden Robinson + + * mmroff.pl: Enable Perl warnings. + +2022-10-09 G. Branden Robinson + + [mm]: Refactor generation of "mmroff" script. + + * mmroff.pl: Replace absolute filespec with `@PERL@` replacement + token. This is documentary; the filespec was getting replaced + anyway. + * mm.am (mmroff): Use more idiomatic token replacement strategy. + Also create target as a .tmp-suffixed file at first since it is + not initially executable, so that we don't race against anything + needing to run it in a parallelized build. (This is a + hypothetical concern; at present, nothing runs mmroff during the + build.) + +2022-10-02 G. Branden Robinson + + * m.tmac (pg@header): Add page length sufficiency check. + + Fixes . Thanks to Werner + Lemberg for the report. + +2022-10-02 G. Branden Robinson + + Regression-test Savannah #24048. + + * tests/short-pages-do-not-overflow-stack.sh: Test it. + * mm.am (mm_TESTS): Run test. + +2022-09-17 Nikita Ivanov + + * mm/ms.cov (cov@print-title, cov@print-authors): Escape + newlines when beginning conditional blocks. + + Fixes . [Problems + introduced by me in commits 59d1fd7a5e and 4fd984adc9, both + 2021-07-17. --GBR] + +2022-09-16 Nikita Ivanov + + * m.tmac (misc@ev-keep): Select configured default font family, + as with `.fam H` at the top of the document, for example, when + switching to new environment. + + Fixes . + +2022-08-14 G. Branden Robinson + + * m.tmac (PY): Add new macro. + (PE): Replace `init@reset` call with `PY` (and then space by + half a vee as before). + + * groff_mm.7.man (PY): Document it. + + Fixes . + +2022-08-14 G. Branden Robinson + + * m.tmac (@warning, @error): Stop pointlessly using no-break + control character when invoking the `tm` request, which never + causes a break in formatted output. (Management of the standard + output and standard error streams is the user's responsibility.) + (@error): Drop old-fashioned asterisk banners around error + diagnostics. Stop invoking `ab` with redundant and sometimes + misleading arguments. In groff 1.23, `ab` exits silently if + given none. We've already issued a diagnostic and moreover not + all problems are with "syntax"; some are semantic. + +2022-08-14 G. Branden Robinson + + * m.tmac (PS): Validate better; check for 2 arguments exactly. + +2022-08-14 G. Branden Robinson + + * m.tmac (PS): Refactor; drop dead code. The `pic*in` register + was used only for dead stores; it was never read or tested. + +2022-08-04 G. Branden Robinson + + * m.tmac (initialization): In nroff mode, surround automatically + numbered footnote markers in body text with square brackets, as + groff me(7) and ms(7) do. + +2022-08-04 G. Branden Robinson + + * m.tmac (initialization): Recognize new register `V` for + setting the vertical spacing from the command line, instead of + blindly setting the vertical spacing two points larger than the + type size. Handle setting of `V` and type size `S` in case they + are given with an appended scaling unit, using the same + technique as groff ms(7)--if the values are over 1,000, assume + that conversion to basic units by the formatter has already + taken place. + * groff_mm.7.man (Registers) : Document it. + +2022-08-03 G. Branden Robinson + + * m.tmac (:p): Define register as an alias of `ft*nr`; the + former name is a documented DWB mm feature. + +2022-08-01 G. Branden Robinson + + * groff_mm.7.man: Document more features. + (Macros) <)E, VM>: Document these DWB mm internals as exposed by + groff mm. + (Macros) : Document as GNU extensions. + (Strings) : Document. + (Registers) <:R, Au, Ex, Fg, H8...H14, Oc, S>: Document. + +2022-07-29 G. Branden Robinson + + * groff_mm.7.man: Document further differences between DWB mm + and groff mm, including several unimplemented features. + +2022-07-29 G. Branden Robinson + + * m.tmac: Remove pointless conditionals in initialization. + Simplify if-else request pairs that did the same thing in both + branches. + +2022-07-28 G. Branden Robinson + + * groff_mm.7.man: Document `NE` macro. + +2022-03-15 Damian McGuckin + + * m.tmac (eq@check): Compensate for display indentation when + setting equation label. + + Fixes . + +2022-04-27 G. Branden Robinson + + Regression-test Savannah #62190. + + * tests/place-equation-labels-correctly-in-displays.sh: Test it. + * mm.am (mm_TESTS): Run test. + +2021-08-12 G. Branden Robinson + + * m.tmac (R): Alter to work analogously to `B` and `I` macros; + accept multiple arguments if given, and alternate roman with + previous font. Stop explicitly turning off underlining. + +2021-07-17 G. Branden Robinson + + Refactor author title handling. + + * m.tmac (AU): Initialize `cov*at!` array element to zero for + current author number (`AT` already updates it). + + * mm/ms.cov (cov@print-authors): Enforce requirement documented + in groff_mm(7) that .AU is mandatory if .COVER is used. Emit + diagnostic if `cov*au` is not defined, and skip remainder of + macro definition. Test for existence of authors' titles + differently; now that `cov*at!` (a count of titles for the + current author) is guaranteed to be initialized, we can use it + as part of a while loop condition, instead of the hard-coded "9" + as an arbitrary limit on the allowed quantity of author titles + {though surely even that is obnoxiously high in practice}, and + more importantly avoid using a \w escape to measure the width of + the interpolation of a potentially undefined string. Use `nop` + to indent text output. Delete apparent typo causing `mac` + warning with respect to undefined `.` macro. Introduce + temporary strings for the author and author title "loop indices" + to shorten and clarify logic. Remove them when done. + + Fixes . + +2021-07-17 G. Branden Robinson + + * mm/ms.cov (cov@print-title): Enforce requirement documented in + groff_mm(7) that .TL is mandatory if .COVER is used. Emit + diagnostic if `cov*title` is not defined, and skip remainder of + macro definition. + +2021-07-17 G. Branden Robinson + + * mm/ms.cov (COVEND): Fix thinko; test for existence of + `cov*abs-arg` register with `r` conditional operator, not `d`. + +2021-07-17 G. Branden Robinson + + * m.tmac: Stop emitting debugging diagnostic using undefined + string. Problem exposed by commit + d6d98d2b3e0ad070037073bb288bbaee3fc04cf0, 8 December 2013. + + Fixes . + +2021-07-17 G. Branden Robinson + + Stop installing empty macro files. + + * mm.am: Delete variable `MMLOCALE`. + (install_mm): Delete `for` loop that touches the files. + (uninstall_mm): Delete `for` loop that deletes the files. + * m.tmac: Update initializtion. + - Load the `\*[@country]_locale` file with `msoquiet` instead + of `mso`. + - Add version check to require groff 1.23 or later, since + the `msoquiet` request is now being used. + - Move "include guard" to follow the compatibility mode and + groff version checks. Remove its `do` prefix. + * groff_mm.7.man (Localization): Migrate topic into its own + subsection and update discussion. + + Fixes . + +2021-07-17 G. Branden Robinson + + * mm/ms.cov (cov@print-firm): Do nothing if the `cov*firm` + string is not defined. Silences a `mac` warning and prevents + the document date from being incorrectly aligned. + + * tests/ms_cover_sheet_robust_to_missing_AF.sh: Test it. + * mm.am (mm_TESTS): Run test. + + Fixes . + +2021-07-14 G. Branden Robinson + + * m.tmac: Rename `cov*mt-addresse` to `cov*mt-addressee`. + * NOTES: Update the only place the foregoing is documented. + +2021-05-31 G. Branden Robinson + + * groff_mm.7.man (Description/Macros) : Document the "SP" + {simplified} letter style more completely. Salutations and + formal closings are omitted. + + Solves the remaining part of bug #60373, "the formal closing is + omitted completely". And, regarding the salutation, #60390. + + Fixes and + . + +2021-05-30 Bjarni Ingi Gislason + + * m.tmac (let@sg_SP): Stop placing a comma after the first + argument (an author name set by AU) if the second argument is + empty (an author title set by AT). + + Solves another part of bug #60373, "the writer's name at the + bottom is followed by a trailing comma". + + Fixes . + +2021-05-30 Bjarni Ingi Gislason + + * m.tmac (let@print-head): Quote the interpolation of the string + `let*lo-SJ`. + + Solves part of bug #60373, "[t]he subject line shows only the + first word". + + Fixes . + +2021-05-30 G. Branden Robinson + + Add regression tests for Savannah #60373. + + * tests/LT_SP_AU_without_AT_works.sh: + * tests/LT_SP_multi-word_LO_SJ_works.sh: Add tests. + * mm.am (mm_TESTS): Run tests. + +2021-05-30 Tadziu Hoffman + + Fix Savannah #57034. + + * m.tmac (AT): Count author title declarations. + (let*mt-sign): Use correct index when iterating author names. + Prevent page break between author names and titles. Iterate + author titles and write them. + + Fixes . + +2021-05-30 G. Branden Robinson + + Add regression test for Savannah #57034. + + * tests/MT_5_includes_AT_in_SG.sh: Test it. Thanks to Ken + Mandelberg for the reproducer. + * mm.am (mm_TESTS): Add variable storing script name. + (TESTS): Append `mm_TESTS` to run it. + (EXTRA_DIST): Append `mm_TESTS` to ship it. + +2021-05-30 Bjarni Ingi Gislason + + * mm/5.MT (cov@print-title): Fix missing diagnostic. Memorandum + type 5 now requires a title to be declared with .TL. + + Fixes . + +2021-05-30 G. Branden Robinson + + [mm]: Cease warning level manipulation. + + Stop mm macro package from manipulating warnings. + + * m.tmac: Remove code that attempted to enable all warnings if + none were given on the command line. It did this by simply + comparing the value of the warning register (\n[.warn]) against + the default value; but of course, a user could specify -w + options that exactly matched the default and the test would not + be able to tell, causing puzzling and undesired behavior. + Furthermore, the hard-coded default was out of date and did not + correspond to recent releases of groff. If you want all + warnings on, use the ".warn" request with no arguments in your + mm document or pass "-w w" to groff (see troff(1) or the Texinfo + manual for more on warnings). + + See commit 5aa934e7, 20 February 2020. + +2021-05-30 G. Branden Robinson + + * examples/letter.mm: Revise to be a better example: use macro + package more effectively, follow *roff input conventions more + carefully, and incorporate more accurate comments. + +2021-05-30 G. Branden Robinson + + * m.tmac: Update diagnostics. When aborting, explicitly tell + the user we are doing so (see + a334cc97abbdfb9c41e28fcd7c187b81a0a3ceac, 25 September 2020). + (@mm): Define new string to hold prefix for diagnostic messages. + (@warning, @error): Use @mm. Reorder diagnostic messages to + conform with GNU Coding Standards. + (OK, PM): Use @warning instead of `tm` request directly. + +2019-09-10 G. Branden Robinson + + * Makefile.sim: Delete sed transformation of @G@. It is no + longer needed. + +2018-03-01 Werner LEMBERG + + * m.tmac: Fix `.hy' value. + + * groff_mm.7.man: Updated. + +2018-02-28 Werner LEMBERG + + * mm.am (mmroff): Use $(AM_V_GEN) to silence file generation. + +2017-11-02 G. Branden Robinson + + * examples/letter.mm: New; simple example of mm usage. + * mm.am: Ship the file. + +2015-08-22 Bernd Warken + + * mmroff.1.man: Rename `mmroff.man'. + + * groff_mm.7.man: Rename `groff_mm.man'. + + * groff_mmse.7.man: Rename `groff_mmse.man'. + + * mm.am: Include renamings. + +2015-08-05 Bernd Warken + + * mm.am, Makefile.sim: Add `Last update'. Setup Emacs mode. + +Thu Jul 16 11:52:03 2015 Carsten Kunze + + Fix line length of `.DS' with indentation (#45452). + + If `.DS' with first argument `1' or `I' is used the output should + use an indentation of `\n[Si]n'. To make this work, the line length + within the `.DS' diversion must be set to zero, otherwise the + effective line length is too large. + + * m.tmac (DS): Call `ds@set-new-ev' with correct indentation value. + +Fri Apr 3 16:33:22 2015 Werner LEMBERG + + Make man pages work in compatibility mode. + + * groff_mm.man, groff_mmse.man, mmroff.man: Do it. + +Wed Sep 3 21:29:00 2014 Bernd Warken + + * all files in contrib/mm: Copying and Emacs setting. + +Thu Aug 28 07:20:00 2014 Werner LEMBERG + + * m.tmac (misc@tag): Fix horizontal position. + Problem reported by Blake McBride . + +Sun Mar 30 21:45:00 2014 Steffen Nurpmeso + + * Makefile.sim, Makefile.sub: Put straight error-prevention prefixes + for `rm'. + +Wed Mar 6 22:18:00 2013 Deri James + + * groff_mm.man: Document .PIC flag -B (box). Default position of + picture is left (-L) + +Fri Mar 1 08:41:18 2013 Jim Avera + + * m.tmac (ds@set-format, LI): s/.ie/.if/ if no else clause. + +Sat Nov 17 18:36:56 2012 Anton Shepelev + + Fixed the format of header numbers in references. + + * m.tmac (hd-mark-trimmed): New string to hold `hd-mark' without + spaces. + (SETR): Use it. + +Sun Aug 14 07:36:29 2011 Anton Shepelev + + Fix indents in nested static displays. + + * m.tmac (DS, ds@end): Save indent with a stack. + See http://lists.gnu.org/archive/html/groff/2011-07/msg00068.html + for an example. + +Sun Mar 27 09:25:01 2011 Anton Shepelev + + * m.tmac (misc@tag): Fix last patch. + +Sat Mar 19 13:46:50 2011 James Avera + + * m.tmac (RD): Don't use `.ie' but `.if'. + +Fri Mar 18 09:10:19 2011 Anton Shepelev + + * m.tmac (misc@tag): Retain temporary indentation. + +Sat Feb 5 08:06:39 2011 Anton Shepelev + + Fix vertical space around displays. + + * m.tmac (ds@end): Use `.SP', not `.sp'. + +Fri Jan 28 11:15:29 2011 Werner LEMBERG + + Handle `refer-mm.tmac' file. + + * refer-mm.tmac: New file. + * Makefile.sub (install_data, uninstall_sub): Handle it. + +Fri Jan 28 10:56:29 2011 Werner LEMBERG + + Add `refer' support. + + * m.tmac: Include `refer-mm.tmac'. + +Fri Jan 28 10:26:29 2011 Werner LEMBERG + + Prepare `refer' support. + + * m.tmac (\n[Rpe]): New register to control page eject status of the + `RP' macro. + (RP): Updated. + (ref@start-print): Move the trailing full stop in reference number + to... + (RS): This macro. + + * groff_mm.man: Document `Rpe' register. + +Fri Jan 28 10:05:29 2011 Werner LEMBERG + + * mmroff.man, groff_mm.man: s/reference/cross reference/ where + appropriate. + +Wed Jan 5 15:05:47 2011 Werner LEMBERG + + Fix use of .DEVTAG-* macros. + Reported by Anton Shepelev . + + * m.tmac (misc@tag): Wrapper around .DEVTAG-* to compensate unwanted + vertical space. + (H): Use it. + +Mon Dec 27 09:39:20 2010 Werner LEMBERG + + * groff_mm.man: Fix indentation. + +Thu Jun 24 12:43:27 2010 Tadziu Hoffmann + + * m.tmac (misc@pop-nr): Fix assignment. + Reported as + http://lists.gnu.org/archive/html/groff/2010-06/msg00096.html + +Sat Jun 5 08:06:21 2010 Larry Jones + + * m.tmac (\*[BU]): Always define. + +Sat Jun 5 08:00:10 2010 Larry Jones + + Improve compatibility. + + * m.tmac (}b, }f, }p): Define aliases for orthogonality with the + already available }t, }e, and }o for page headers. + +Wed Jun 2 16:03:39 2010 Larry Jones + + Fix .EOP handling and non-numeric format of \n[P]. + + * m.tmac (pg@header): Set `.af' temporarily to numeric format. + (pg@print-footer): Disable vertical traps for call to .EOP also. + +Wed Jun 2 16:03:39 2010 Larry Jones + + * m.tmac (toc@entry): Use MM page number (\nP). + +Sun May 30 07:14:15 2010 Larry Jones + + * m.tmac (P, nP): Fix handling of short paragraphs. + Otherwise, + + .H 1 Bug + .P + one + .P + two + .P + three + + results in: + + 1. Bug + + one two three + + whereas it should, of course, produce: + + 1. Bug + + one + + two + + three + +Sat Jan 3 08:55:15 2009 Werner LEMBERG + + * groff_mm.man: Use new `x' table modifier for all tables which use + T{...T}. This greatly improves formatting. + +Tue Feb 6 00:00:00 2007 Eric S. Raymond + + * groff_mm.man: Typo fix. + +Sat Feb 3 00:00:00 2007 Eric S. Raymond + + * groff_mm.man: Eliminate nonportable macro hackery in the + definition of T2 in favor or TBL tables. + +Fri Jan 5 14:35:35 2007 Werner LEMBERG + + Fix installation. Reported by Jennifer Sayers. + + * Makefile.sub (install, install_mm): Remove. + (install_bin, install_data): New targets. + +Sat Aug 12 23:33:45 2006 Nick Stoughton + + * m.tmac (P): Ignore P after H, as documented. + +Tue Apr 4 07:19:57 2006 Werner LEMBERG + + * groff_mm.man: Document strings TPh, TPeh, and TPoh. + +Wed Mar 29 06:58:24 2006 Werner LEMBERG + + * m.tmac (pg@print-footer): Disable vertical traps while emitting + the footer. This fixes an endless loop caused by + + .S 27 59 + foo + .SK + + Problem reported by Bill Brelsford . + + (LI): Remove superfluous line which sets number register `x' without + reason. Problem reported by Morris Stern . + + (eq@check): Correctly flush labels to the right. + Problem reported by Morris Stern . + Fix vertical positions of labels. + + (ds@end): Emit pre-display space earlier. + + * groff_mm.man: Document that only the last equation label of + .EQ/.EN blocks within .DS/.DE is printed. + +Tue Mar 28 14:00:06 2006 Werner LEMBERG + + . Hardwire first four font positions with R, I, B, and BI -- the + documentation explicitly refers to this feature (cf. the `HF' + string register). + + . Don't use `%' register in numeric calculations because it is + affected by `.af'. + + Patches for both problems have been contributed by Nick Stoughton + . + + * m.tmac: s/@language/@country/. + s/\n[%]/\n[P]/ where appropriate. + s/\fR/\f1/. + s/.ft R/.ft 1/. + s/\fI/\f2/. + s/.ft I/.ft 2/. + s/\fB/\f3/. + s/.ft B/.ft 3/. + + * mse.tmac: s/@language/@country/. + + * groff_mm.man (Fonts): New subsection. + + * groff_mmse.man: Load `sv.tmac'. + Reformatted. + + examples/README: Cleanups and updates. + +Mon Mar 27 15:44:24 2006 Werner LEMBERG + + * groff_mm.man: Completely revised and reformatted to use as many + man macros as possible. + +Thu Mar 2 09:12:06 2006 Werner LEMBERG + + * mse.tmac: Remove common Swedish strings and load sv.tmac instead. + +Sun Feb 26 13:57:13 2006 Claudio Fontana + + * Makefile.sub: Add DESTDIR to install and uninstall targets + to support staged installations. + +Fri Nov 25 14:31:02 2005 Werner LEMBERG + + * mm/ms.cov (COVEND): Protect argument for `cov@print-abstract' + with doublequotes. Reported by Fabrice Ménard + . + +Tue Oct 25 21:59:04 2005 Bob Diertens + + * m.tmac (lix@print-line): Add parentheses to if-else clause to + fix logic. + +Thu May 26 08:23:40 2005 Werner LEMBERG + + * m.tmac: Load devtag.tmac. + +Mon May 16 00:00:00 CEST 2005 Keith Marshall + + * mmroff.pl: Add space in shebang prototype for generated + conftest.sh script, conforming to portability recommendation in + autoconf docs. + +Wed Mar 16 06:56:02 2005 Larry Kollar + + Add rudimentary support for grohtml. + + * m.tmac (H): Call DEVTAG-NH and DEVTAG-EO-H. + (pg@enable-trap, pg@header): Do nothing for devhtml. + +Sun Mar 7 16:34:46 2004 Jeff Conrad + + * m.tmac (S): Improve debug message. + +Wed Mar 05:38:57 2004 Joergen Haegg + + * Changed default value for Hy in manual to 0 + * Check Hy at each new page + +Mon Mar 1 22:16:38 2004 Jeff Conrad + + * m.tmac (S): Fix scaling indicator for vertical spacing. + +Tue Nov 05:14:45 2003 Joergen Haegg + + * another patch from ulrich lauther to fix the + TOC up to 14 heading levels. + +Mon Oct 13:48:25 2003 Joergen Haegg + + * problem with more than 7 levels of headings fixed with + patch from ulrich lauther. + +Wed Apr 06:42:35 2003 Joergen Haegg + + * the footer was not adjusted by VM due to a missing + pg*extra-footer-size in the calculation of pg*last-pos + +Wed Apr 06:04:58 2003 Joergen Haegg + + * space adjustments in 4.MT to make it more like + the original + +Sun Mar 21:45:10 2003 Joergen Haegg + + * removed error check i 4.MT, .AF is not mandatory anymore + +Sat Mar 21:56:57 2003 Joergen Haegg + + * cov*firm now defined only if arg to AF is non-empty + That will also enable cov*default-firm from the mm locale-file + to work. + +Sat Mar 21:05:29 2003 Joergen Haegg + + * added .ll in pg@set-env to initialize the + header environment properly + +Wed Mar 19 23:02:16 2003 Werner LEMBERG + + * groff_mm.man: Some fixes from Robert D. Goulding + . + +Wed Sep 09:53:06 2002 Joergen Haegg + + * added implicit -mm to mmroff, it's now possible + to use mmroff with or without -mm as argument. + +Thu Aug 08 00:31:00 Bob Diertens + + * m.tmac (VM): Add missing backslash. + +Fri Jun 10:37:58 2002 Joergen Haegg + + * added init@reset for LT-macros so .S works for letters + +Thu May 06:30:06 2002 Joergen Haegg + + * adding -T to VM for setting the total + header and footer size. + * changing pg*extra-header-size unit from v to u in DS-size + calculation + +Mon May 05:40:16 2002 Joergen Haegg + + * All lists now get an empty line before the list + even if there is no empty lines between the items (bug in LB) + +Sat May 07:36:08 2002 Joergen Haegg + + * PIC is now drawn 1v higher, making it + possible to put a picture at 0,0. + * Indentbug in P fixed, Pt=2 now behaves as it should + +Wed May 10:18:26 2002 Joergen Haegg + + * added L, W and O in groff_mm.man + * extra space in expression removed in EPIC + * EPIC can leftadjust with -L + * EPIC was drawing 1v down + * forgot to add mmse.tmac and mm.tmac to cvs + +Fri May 20:35:32 2002 Joergen Haegg + + * Clarified manual about INITR + * Added mm.tmac and mmse.tmac wrappers + * Fixed bug in mmroff so a .qrf-file always will be created + * .EQ mark was not correctly positioned anymore. + * changed SP to sp in DS/DE to further correct .EQ + +Sun Dec 9 00:00:00 2001 Werner LEMBERG (wl@gnu.org) + + * Makefile.sim, groff_mm.man, groff_mmse.man: Minor fixes. + * mmroff.man: This is a section 1 man page. + Minor fixes. + * Makefile.sub: Install mmroff.man in section 1. + +Wed Nov 28 00:00:00 2001 Werner LEMBERG (wl@gnu.org) + + * m.tmac: Assure that the macro package is loaded only once. + +Wed Sep 5 00:00:00 2001 Werner LEMBERG (wl@gnu.org) + + * m.tmac: Enable all warnings only if no -W or -w option is given on + the command line (or rather, if only the default warnings are + set). + +Mon Sep 3 00:00:00 2001 Werner LEMBERG (wl@gnu.org) + + * groff_mm.man: Don't use .ne for TTY devices. + +Thu Jul 26 00:00:00 2001 Werner LEMBERG (wl@gnu.org) + + * groff_mm.man: Start always a new line after end of sentence. Add + some compatibility info to the HF variable. + +Thu Jul 26 00:00:00 2001 Larry Jones (larry.jones@sdrc.com) + + * m.tmac: Fix initialization of Hps1 and Hps2. + +Wed May 16 00:00:00 2001 Bruce Lilly (blilly@erols.com) + + * m.tmac (TH): Fix incorrect error message. + +Thu Apr 12 00:00:00 2001 Ruslan Ermilov (ru@FreeBSD.org) + + * groff_mm.man: Fixing some typos. + +Mon Mar 5 09:30:18 2001 Jörgen Hägg (jh@axis.com) + + * S didn't reset to default point size + * (dummy line to force cvs update...) + +Sat Jan 06 10:30:00 2001 Werner LEMBERG (wl@gnu.org) + + * Fixed assignment of page offset given as a command line argument. + +Fri Nov 17 05:34:17 2000 Jörgen Hägg (jh@axis.com) + + * Renamed tmac.m and tmac.mse to m.tmac and mse.tmac + +Thu Sep 14 05:52:48 2000 Jörgen Hägg (jh@axis.com) + + * New Changelog-format, it will show changes better. + Easier for other to use. (Somehow I didn't really + understand why the e-mail address was supposed to be + 'jh at axis.com' in the Changelog. :-) + +Mon Aug 28 00:00:00 2000 Bruno Haible (haible at clisp.cons.org) + + * Makefile.sub: New target 'all', makes all prerequisites of + 'install'. + +Thu Sep 7 06:17:42 2000 Jörgen Hägg (jh at axis.com) + + * version 2.0 + * Had to do something about my version numbering. + The main CVS archive was not in sync with mine. + So, now it is 2.0. :-) + +Sat Jun 17 23:00:00 2000 Eli Zaretskii (eliz@is.elta.co.il) + + * Makefile.sim (.man.n): Replace `;' with `|', since DOS/Windows + path lists use the semicolon as a separator. + +Sun Jun 4 21:39:00 2000 Kaneda Hiroshi (vanitas at ma3.seikyou.ne.jp) + + * Fixing a lot of typos in groff_mm.man + +Tue Mar 7 00:00:00 2000 OKAZAKI Tetsurou (okazaki at be.to) + + * Makefile.sub: Use $(INSTALL_SCRIPT) for script files. + +Sun Jan 30 22:52:20 2000 Jörgen Hägg (jh at axis.com) + + * version 1.34 + * Changed the version number in the CVS repository + * MC had a bug in column calculation, (thanks to T. Kurt Bond) + +Fri Sep 3 07:33:14 1999 Jörgen Hägg (jh at axis.com) + + * version 1.33 + * At last! I finally tracked down the PGFORM bug! + It didn't setup the @pl, @ll and @po as it should, now it does. + * mgm_ref/mgm_roff renamed to mmroff [-x] + * fixed y2k-bug in \*[DT] + * \n[cov*year] removed, hope no one used that. + * ISODATE added with Iso as command line flag + (iso-date suggested by Paul Eggert) + * Added ISODATE to tmac.mse and removed local settings + of new-date. + * INITI syntax changed and enhanced. Index processing is now + done with mmroff. + * A few examples has been added, new subdirectory 'examples'. + * Fixed bug with SETR, header references are now only saved + when Ref > 0 + * Problem with register H1h fixed + * Added test for missing abstract in 4.MT + * Updated Makefile.sub, using tmac_m_prefix. + +Mon Mar 15 22:22:42 1999 Jörgen Hägg (jh at axis.com) + + * OK, let's release this as a beta, 1.33 will be better. :-) + * version 1.32 + * fixed .el-error + * Added number variable Hss + * Changed Hps1 and Hps2 to units + * added hd*h1-text to be used in user defined macro TP. + * -U needed for SETR (I really need 'mv', 'echo', 'rm' + and 'test' builtin!) + * Rewritten the reference system, SETR now prints to stderr + if the number register Qrf > 0. Store in the filename + that is the argument to .INITR + The old behaviour is returned if number register Initr > 0. + * Fixed bug with List of XXXX, long lines messed up the result. + * added number register H1dot. + * added string variable H1txt + * added string variable Tcst + * added number register Dsp. + * added alias APPX for user-defined appendix title. + * added string variable Apptxt + * added H1h for use in TP in headers + * added macro EPIC + * added macro PIC (safe replacement for PSPIC) + * fixed Hps-bug, should be 1, not 1v. + * fixed bug with APPSK, variable not set. + +Wed Feb 4 15:46:04 1998 Jörgen Hägg (jh at axis.se) + + * version 1.31 + * .LI will now honor a space mark. + * Another fix for .AU to let it be used without arguments. + * uninitialized eq*label fixed + +Fri Sep 6 07:13:07 1996 Jörgen Hägg (jh at axis.se) + + * version 1.30 + * This is more like a beta-release, bugs might pop up. :-) + * last line in TOC was not correctly terminated (missing .br) + * changed the indentation for displays, it will now + indent to the current indent, not the one at the definition + of the display. + * Equation marks should now work better, indentation also. + * included these bug fixes from Larry Jones: + * The documentation for the argument to .AS was incorrect for MT 4. + * \*(EM should be a double-dash for nroff. + * \nS is in points, not units. + * If \nO isn't set, the default page offset should be .75i for nroff + and .963i for troff. + * .S D should set the point size to \nS, not 10. + * .S was setting the vertical spacing based on the old point size + instead of the new point size. + * Got rid of a spurious .br that prevented run-in headings from + working. + * Reset the .SP counters in pg@header so that spacing on one page + won't affect spacing on subsequent pages. + * Allow .AU and .AF with no arguments (real mm does, even though it + isn't documented). + * Do .init@reset first thing to initialize the default environment. + * For MT 4, the title should be 4 points larger than the default size, + not 12 point. + * The cover environment needs to be initialized. + * Printing the abstract on the first page needs to be controlled by + the .AS argument. + * Heading eject should be suppressed if the heading immediately + follows the first page stuff (title, author, etc.). + * support for table of contents numbering style (.nr Oc) + * changes the troff empty line height from .25v to .5v + * fixed section page numbering + * fixed a really nasty bug in footnotes that could cause you + to lose the page footer completely if the very first + footnote on the page occurred at just the wrong place + + +Wed May 15 07:39:32 1996 Jörgen Hägg (jh at axis.se) + + * version 1.29 + * Syntax and scaling error fixed, (thanks to Frazer Williams) + * DF/DE will now do a line-break before printing the display. + * Updated the manual for TB,FG,EX and EC. + * Added support for the ms- (and mgs-)macro .IX + * Added indexmacro IX, INITI, IND and INDP, support for + TXIND, TYIND and TZIND. + * PGFORM will now always really reset to the default + values for unspecified arguments. + * Floating displays tested and repaired, it should + now (finanlly) work exactly as the original (I hope :-). + * Should now set year correctly even after 2000. + * Stupid bug in PGNH fixed. + * Corrected line length for figure caption (FG and friends) + + +Mon Apr 24 07:37:52 1995 Jörgen Hägg (jh at axis.se) + + * version 1.28 + * Added AVL (AV without date) + * Fixed nroff scaling for W and L. + * Added support for register E and roman/bold + for all Subject/Date/From strings. + * Added support for register C (1-4), (for DRAFTs and other types) + * Will protest if not used with groff. + * Change of the internal number registers @ps and @vs, they + are now in units, and is set in the new macros .@ps and .@vs. + @ps and @vs is now corrected to the real point and vertical size. + * Macro EQ has now correct pointsize. + * Figures should now get the right page number in the index. + * User-defined macros can now be defined for list of + figures, tables, equations and exhibits (T{X,Y}{FG,TB,EC,EX}. + * Space may be omitted between prefix and mark in automatic lists (.AL) + See .LI + +Tue Jan 10 07:51:37 1995 Jörgen Hägg (jh at axis.se) + + * version 1.27 + * Manual updated + * More bugs fixed in DS/DF + * added alias for :g + * LC can now be used without argument (as the manual says. :-) + * Register :R now supported (RS/RF) + * footnote line was printed even if there was no room for + any footnotes. Fixed. + * Fixed 1C so that it can be used without page eject + * Added support for EOP (TPs twin) + * Hyphenation turned off by default. (Hy == 0) + +Fri Nov 4 08:14:50 1994 Jörgen Hägg (jh at axis.se) + + * version 1.25 + * DS/DF separated and several bugs fixed. Watch out for new though. :-) + * string DT was emptied by mistake in the previous version. + * RD made prettier. + * typo in AV and let@print-head fixed. + +Mon Oct 31 08:19:24 1994 Jörgen Hägg (jh at axis.se) + + * version 1.24 + * Bug fixed and format extended in .SG and .FC. + * date is always printed unless .ND without argument is used. + (I wonder what's the right thing to do, this might change.) + * Swedish letter-standards implemented in tmac.mse. + * .ND can be used to turn off the date. (Empty argument) + +Mon Oct 31 08:14:09 1994 Jörgen Hägg (jh at axis.se) + + * version 1.23 + * An attempt to get in sync with RCS. This is the distributed + version. + +Thu Oct 27 08:29:34 1994 Jörgen Hägg (jh at axis.se) + + * version 1.22 + * (version 1.21 lost... :-) + * Letter macros added!! + * The following macros are added: + * AV, FC, IA ,IE, LT, LO, NE, NS, SG, WA, WE + * nP also added. + +Tue Dec 14 16:26:36 1993 Joergen Haegg (jh at efd.lth.se) + + * version 1.20 + * spelling-corrections + * Makefile.sim updated to the correct version, and a uninstall + target added. + * @cur-lib removed from tmac.m (obsolete) + * fixed check for references i .TC, .RP now resets the flag correctly. + * floating display should now be printed if there is space. + * first version using RCS. I've been avoiding version control until it + became necessary. + * WC WD now works in two-column-mode. + +Tue Sep 7 08:37:00 1993 Jörgen Hägg (jh at efd.lth.se) + + * version 1.19 + * .lt is called in the header for .TP also. + * Variable Pgps added to control the header and footer point-size. + * Error-text printed with .APP removed. + * Error with .FG, .TB, .EC and .EX indentation fixed. + * header and footer line-length is not changed by MC or 2C. + * Default for page-length and page-offset is now taken from + \n[.p] and \n[.o]. + * Argument to .ab (abort) is supplied. + * Argument to .1C added. + * Argument to .PGFORM added. + * RP/RS/RF totally rewritten. Should work with 2C now. + +Fri Apr 23 10:37:25 1993 Joergen Haegg (jh at efd.lth.se) + + * version 1.18 + * Height of display is now more exactly calculated. + * tabs and blankspaces where wrong in .VERBON. + * error in manual for escape-character in VERBON. + * Makefile.sub: installed tmac.m as tmac.m and tmac.mse + * Installation of tmac.mse now supports TMAC_M. + * bug with N fixed. + +Mon Apr 5 09:36:01 1993 Joergen Haegg (jh at efd.lth.se) + + * version 1.17 + * MULB preserves size. + * bug in VERBON fixed, causing strange errors. + * section-page footer fixed. + * added support for numberregister S + * fixed bug with floating displays which made floats to + generate space on a page, but broke page anyway. + * end-of-page trap reinstalled. + +Mon Mar 29 10:53:13 1993 Joergen Haegg (jh at efd.lth.se) + + * version 1.16 + * MUL* now use the previous font and family. + * extra blank page at end-of-text eliminated. + +Mon Mar 8 10:27:47 1993 Joergen Haegg (jh at efd.lth.se) + + * version 1.15 + * Didn't restore pointsize to current size in .H. + * B1/B2 did not work with indent. (MULE and friends) + * fixed old problem with trailing empty pages. + +Fri Mar 5 15:20:49 1993 Joergen Haegg (jh at efd.lth.se) + + * version 1.14 + * Sigh. Amazing what a missing \} can do. If the string + HP was set, then all text disappeared... + +Fri Mar 5 14:12:43 1993 Joergen Haegg (jh at efd.lth.se) + + * version 1.13 + * Fixed bug with handling ps/vs in .H. (again, sigh... ) + +Wed Mar 3 09:21:20 1993 Joergen Haegg (jh at efd.lth.se) + + * version 1.12 + * Line-break added to PGFORM. + * added more features to VERBON + * .S is not used anymore in H, it caused confusion with + normal text, but it will still set .vs. + * SK was broken, will now produce the requested number of + empty pages. + * dotted lines added to LIST OF FIGURES and friends. + Also better linespacing. + +Mon Feb 22 12:41:06 1993 Joergen Haegg (jh at efd.lth.se) + + * version 1.11 + * missing left-parenthesis gave ") .sp" when N=4. + * N=4 removed user-specified header also. + * MOVE made linelength pageoffset wider than wanted. + * fixed (again) parenthesis in RP. + +Thu Jan 21 12:10:39 1993 Joergen Haegg (jh at efd.lth.se) + + * version 1.10 + * changed PROG_PREFIX to g in the manual-pages. + * Better check if new page is needed in .H, when Ej>0. + * Usage of variable Lsp now more complete. + * Space added in TOC when mark is equal to size. + * Usermacro HY moved after font-calulations. + * .S used instead of .ps, which will use .vs correct. + * Now possible to set Hps1/2 inside HX. + * .FD "" 1 is now fixed. + * section-page numbering bug fixed. + * several bugs in VERBON/OFF fixed. + +Tue Dec 8 16:43:15 1992 Joergen Haegg (jh at efd.lth.se) + + * version 1.09 + * N==4 gives no default header + +Sat Nov 21 14:28:20 1992 Joergen Haegg (jh at efd.lth.se) + + * version 1.08 + * Escape-character disabled between + VERBON/VERBOFF (turned on by an argument). + Pointsize and fontchange also added as arguments. + * MULB, MULN and MULE added to get multicolumn output + with different width. + * Number register N can now use 1-5. + * Register Sectp and Sectf added. + * Register P is now updated correctly for "section-page" numbering. + +Thu Nov 19 11:19:33 1992 Joergen Haegg (jh at efd.lth.se) + + * version 1.07 + * .OP fixed to eject a blank page if not odd. + +Fri Nov 13 09:46:09 1992 Joergen Haegg (jh at efd.lth.se) + + * version 1.06 + * Macro TL rewritten. TL depends now on a following .AU. + * NOTES updated. + * .lt is now used more frequent when linelength is changed. + * macro AST added. + * removed PH/EH/OH not needed in ?.MT. + +Wed Oct 28 14:35:43 1992 Joergen Haegg (jh at efd.lth.se) + + * version 1.05 + * .VM implemented. + * Possible bug in page heading fixed. Changed .sp to 'sp in HEADER. + +Thu Aug 20 13:56:31 1992 Joergen Haegg (jh at efd.lth.se) + + * version 1.04 + * page-break in .EQ moved. + * changed unit for footer-size and header-size from units to lines. + Fixes problems with .S and page-breaks. + * \n[%] is now treated as a string, which makes it possible + to assign new formats to it. Unfortunately, it was necessary + to change the page-number-variable in GETPN to a string. + * Makefile.sub included. (Thank you, James) + +Thu May 7 16:14:10 1992 Joergen Haegg (jh at efd.lth.se) + + * version 1.03 + * Typo and centering in DS/DE fixed. + Even and odd pageheaders were reversed. + * LI: pad and mark-indent was lost in some earlier versions. Now fixed. + * fixed bug in reference to .FG, .TB, ... + * APP did not clear headercounters. + * Pointsize in titles is now only set at the beginning and + when PH, PF, OH, OF, EH and EF are used. + +Thu May 6 16:01:35 1992 Joergen Haegg (jh at efd.lth.se) + + * version 1.02 + * OP fixed. + +Fri Mar 6 09:36:09 1992 Joergen Haegg (jh at efd.lth.se) + + * version 1.01 + * two .LI without text between should not be printed + on the same row. Now fixed. + * figure titles and friends fixed, now possible with many .FG + in a DS/DE. Didn't always position correctly in previous version, + but is now always printed as it should. + * Makefile fixed for Ultrix. + * DS/DF could not handle empty arguments correct + * Missing .br i EQ added. + +Sat Jan 25 15:47:21 1992 Joergen Haegg (jh at efd.lth.se) + + * version 1.00 + * No betaversion anymore! + * Fixed headernumbers within appendixes. + * DS did not keep the same font as before DS. + * mmse did a line break. + +Fri Jan 24 14:38:16 1992 Joergen Haegg (jh at efd.lth.se) + + * version 0.16 + * bug in TC, multiple line headers did not wrap correctly. + * added support for mm/locale and mm/language_locale. + * cov*default-firm in locale sets name of firm in the MT covers. + * cov*location-xxxx in locale sets location xxxx to the contents + of cov*location-xxxx. Used in the MT covers. + * hanging indent in lists fixed. + * use larger empty lines if .nroff is defined. + * macros, like .P, can now be used inside abstracts. + * .S do not reset indentation anymore. + * .RS aA now sets a string, not an integer. + * appendix with .APP or .APPSK added. + +Thu Nov 28 22:00:59 1991 Joergen Haegg (jh at efd.lth.se) + + * version 0.15 + * Fixed .AU in MT 0-3, added support for variable Au. + * Bug in the positioning of the foot-notes. + * lists not indented properly. + * Hps1 and Hps2 added. + * COVER had to have an argument. + * table of contents can now have multiline header. + * .HU now increments headingvariable H? + * added the inclusion of a locale file. + +Sat Nov 23 14:40:17 1991 Joergen Haegg (jh at efd.lth.se) + + * version 0.14 + * bug when using -rO fixed. + * MT 1-4 added. + * default is now MT 1 + * .EQ/.EN can be used outside of .DS/.DE without complaints. But + I don't recommend it. Neither does the DWB books. + * LI don't break lines now if arg too big. + * PGFORM did not reset indent. + * Added the numbervariable Hps. + * Rewritten and added MT 0-5 + "string". + * Added TM. + * Indent to AS added + +Wed Nov 6 15:18:40 1991 Joergen Haegg (jh at efd.lth.se) + + * version 0.13 + * ds*format nod defined if PS/PE is used without DS/DE. + * GETST added, fourth argument to EX, FG, TB and EC added. + +Mon Nov 4 13:38:01 1991 Joergen Haegg (jh at efd.lth.se) + + * version 0.12 + * Fixed C,D,P,+-size in .S + +Sun Jan 1 00:00:00 1991 Joergen Haegg (jh at efd.lth.se) + * Next version will have ChangeLog entries... + * Bug in INITR fixed. + * VERBON/VERBOFF added to include programlistings + * Bug in .DE fixed, addition overflow +Sun Jan 1 00:00:00 1991 Joergen Haegg (jh at efd.lth.se) + * spelling error in month-names. + * WC should work now (no warranty :-) + * FD almost finished, some details missing. + * incorrect calculation of foot-notes fixed. + * DS/DE did not break page when the size was smaller than the paper + * Forward/backward referencesystem added. Se .INITR in README. + * mgmsw changed name to mgmse. +Sun Jan 1 00:00:00 1991 Joergen Haegg (jh at efd.lth.se) + * embarrassing bug in .P fixed + * .H did always eject page, now fixed. + * lost floating displays now found. + * accents added (from mgs) + * empty line in .EQ/.EN removed + * indentation in .TC corrected. + * indentation of DS/DE in lists fixed. + * .TB and friends now work inside DS/DE and outside. + * .WC partially implemented (WF and WD). Still working on it. + * .mso used if version>=1.02 +Sun Jan 1 00:00:00 1991 Joergen Haegg (jh at efd.lth.se) + * register P was not working. + * support for register Fg, Tb, Ec and Ex. + * list items was left on the previous page at a page break. + * tlevel in .TC now defaults to 2. + * string DT, EM and Tm supported. + * new macro: PGNH, see comments. + * bug in MOVE fixed. + * pagenumber in .TC fixed. + * a blank page was ejected if Ej==1, now fixed + * bug in floating display fixed (did break and SP wrong) + * bug in .SP fixed, no lines is now printed at top of page + * There are still problems with footnotes and displays in two column mode. +Sun Jan 1 00:00:00 1991 Joergen Haegg (jh at efd.lth.se) + * register P added (same as %) + * bug in floating displays fixed + * MOVE added + * MT added, see comment below + * COVER/COVEND added + * fixed bug in figure titles + * extended S, se comment below + * MT 0 added + * ms-cover added (COVER ms) +Sun Jan 1 00:00:00 1991 Joergen Haegg (jh at efd.lth.se) + * bugs in RD and comb. fonts fixed +Sun Jan 1 00:00:00 1991 Joergen Haegg (jh at efd.lth.se) + * HC added + * Combined fonts (IB,BI...) + * HM added + * RD added + * OP added + * TP&PX supported + * warnings for unimplemented macros + +________________________________________________________________________ + +Copyright 1991-2020 Free Software Foundation, Inc. + +Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. + +Local Variables: +fill-column: 72 +mode: change-log +version-control: never +End: +vim:set autoindent textwidth=72: diff --git a/contrib/mm/Makefile.sim b/contrib/mm/Makefile.sim new file mode 100644 index 0000000..2d2d6b6 --- /dev/null +++ b/contrib/mm/Makefile.sim @@ -0,0 +1,84 @@ +# Copyright 1991-2020 Free Software Foundation, Inc. +# +# This file 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 . +# +# Makefile.sim +# +# To install mm separately as gm.tmac: +# make -f Makefile.sub tmacdir=/usr/local/lib/groff/tmac srcdir=. \ +# INSTALL_DATA='install -m 644' tmac_m=gm install +# +# or as m.tmac: +# +# tmacdir is the destination for your groff/tmac-directory, srcdir is +# this directory and INSTALL_DATA is the command to install a file with. +# If you dont have 'install': use 'cp'. + + +# change this to whatever you like +tmacdir=/usr/local/lib/groff/tmac +#tmac_m = gm +tmac_m = m +indexdir = xx +install = install -m 644 + +# Do not change anything below this line +srcdir = . +version = 2.8 +mdate = 2002-05-11 + +.SUFFIXES: .n .man + +all: + +install: groff_mm.n groff_mmse.n + $(MAKE) -f Makefile.sub tmacdir=$(tmacdir) srcdir=$(srcdir) \ + INSTALL_DATA='$(install)' tmac_m=$(tmac_m) install + +uninstall: groff_mm.n groff_mmse.n + $(MAKE) -f Makefile.sub tmacdir=$(tmacdir) srcdir=$(srcdir) \ + INSTALL_DATA='$(install)' tmac_m=$(tmac_m) uninstall_sub + +.man.n: + @echo Making $@ from $< + @rm -f $@ + @sed -e "s|@HYPHENFILE@|$(hyphenfile)|g" \ + -e "s|@FONTDIR@|$(fontdir)|g" \ + -e "s|@FONTPATH@|$(fontpath)|g" \ + -e "s|@MACRODIR@|$(tmacdir)|g" \ + -e "s|@MACROPATH@|$(tmacpath)|g" \ + -e "s|@DEVICE@|$(DEVICE)|g" \ + -e "s|@DEFAULT_INDEX@|$(indexdir)/$(indexname)|g" \ + -e "s|@DEFAULT_INDEX_NAME@|$(indexname)|g" \ + -e "s|@INDEX_SUFFIX@|$(indexext)|g" \ + -e "s|@COMMON_WORDS_FILE@|$(common_words_file)|g" \ + -e "s|@MAN1EXT@|$(man1ext)|g" \ + -e "s|@MAN5EXT@|$(man5ext)|g" \ + -e "s|@MAN7EXT@|$(man7ext)|g" \ + -e "s|@TMAC_S@|$(tmac_s)|g" \ + -e "s|@TMAC_M@|$(tmac_m)|g" \ + -e "s|@TMAC_MDIR@|$(tmacdir)/mm|g" \ + -e "s|@BROKEN_SPOOLER_FLAGS@|$(BROKEN_SPOOLER_FLAGS)|g" \ + -e "s|@VERSION@|$(version)|g" \ + -e "s|@MDATE@|$(mdate)|g" \ + -e "s|@g@|$(g)|g" \ + $< >$@ + +# Local Variables: +# mode: makefile +# fill-column: 72 +# End: +# vim: set filetype=make textwidth=72: diff --git a/contrib/mm/NOTES b/contrib/mm/NOTES new file mode 100644 index 0000000..1c35133 --- /dev/null +++ b/contrib/mm/NOTES @@ -0,0 +1,116 @@ + Copyright (C) 1989-2020 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. + +###################################################################### + +Beware! +This may be old information. Trust only the source. :-) + +Implementation notes. (Or how to make your own national mm) + +Different commands: + +COVER [arg] +MT [arg [addressee]] +The arg is part of a filename in mm/*.MT or mm/*.cov. +This file is read when the macro is executed. Therefore it must be +put before any text output. +In each file there are definitions of all extra macros needed for the +cover sheet. MT files is only for compatibility reasons, and has several +limits due to that it don't know when the cover starts, and cannot +change sizes. Use COVER for new coversheet macros. + +But with MT it is possible to write all of the AT&T covers. +An example can be found in mm/0.MT. + +When writing a new cover using COVER, have in mind that the cover +should print the page with the COVEND macro. This macro +should be defined by the new macrofile. + +Here is a part of ms.cov: +> .\"----------------- +> .de COVEND +> .sp |4.2c +> .cov@print-title +> .cov@print-authors +> .cov@print-firm +> .cov@print-abstract +> .cov@print-date +This is important, since COVER disables the page header. +> .pg@enable-top-trap +Should begin with page one (normally). +> .bp 1 +And enable the trap at the page footer. +> .pg@enable-trap +> .. + +######################### + +Variables for covers: +I = integer +S = string +D = diversion +M = macro + +Name Type Desc. +cov*au I The number of authors. + +cov*title M Title collected with .TL. + +cov*au!x!y S Author(s) given to .AU +cov*at!x!y S Author(s) title given to .AT + x is the author-index [1-cov*au], + y is the argument-index [1-9]. + Look at the table with indexes. + +cov*firm I Author(s) firm. + +cov*abs-arg I Argument to abstract. + +cov*abs-ind I Indent for abstract. + +cov*abs-name S The string 'ABSTRACT', changed with .AST + +cov*abstract M The abstract. + +cov*new-date S date (today if .ND not used) + +cov*mt-type S memorandum type set by .MT +cov*mt-addressee S memorandum addressee set by .MT + + +########################## +Argument-index for cov*au: + +Index Desc. +1 name +2 initials +3 location +4 department +5 extension +6 room +7 arg 7 +8 arg 8 +9 arg 9 + +The location is set to the contents of string cov*location-xxxx +if location is equal to xxxx and cov*location-xxxx is defined +in the file locale. + + +Argument-index for cov*at: + +Index Desc. +1 title 1 +. . +. . +9 title 9 + + +##### Editor settings +Local Variables: +mode: text +End: diff --git a/contrib/mm/README b/contrib/mm/README new file mode 100644 index 0000000..6c6ca5b --- /dev/null +++ b/contrib/mm/README @@ -0,0 +1,27 @@ + Copyright (C) 1989-2020 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. + +This is mm, a macro package for groff. + +It is supposed to be compatible with the Documenter's Workbench (DWB) mm +macros, and has several extensions. + +Please submit bug reports using groff's 'BUG-REPORT' file to +http://savannah.gnu.org/bugs/?group=groff. + +Any new ideas or improvements are welcome. + +This README should be bigger :-) + +/Jörgen Hägg + +Thanks to everyone who have sent me bug reports and fixes. + + +##### Editor settings +Local Variables: +mode: text +End: diff --git a/contrib/mm/examples/APP b/contrib/mm/examples/APP new file mode 100644 index 0000000..e2c017f --- /dev/null +++ b/contrib/mm/examples/APP @@ -0,0 +1,359 @@ +.\" -*- nroff -*- +.\" Copyright (C) 1989-2014 Free Software Foundation, Inc. +.\" +.\" Copying and distribution of this file, with or without modification, +.\" are permitted in any medium without royalty provided the copyright +.\" notice and this notice are preserved. +. +.H 1 " granary grand grandchild grandchildren granddaughter grandeur" +granary +grapheme +graphic +graphite +grapple +grasp +grass +grassland +grassy +grata +grate +grateful +grater +gratify +gratis +gratitude +gratuitous +gratuity +grave +gravel +.H 2 "grapefruit grapevine graph grapheme graphic graphite" +granary +grand +graphic +graphite +grapple +grasp +grass +grassland +grassy +grata +grate +grateful +grater +gratify +gratis +gratitude +gratuitous +gratuity +grave +gravel +.H 3 "grapple" +granary +grand +grandchild +grandchildren +granddaughter +grandeur +grandfather +grandiloquent +grandiose +grandma +grandmother +grateful +grater +gratify +gratis +gratitude +gratuitous +gratuity +grave +gravel +.H 1 "Graves gravestone graveyard gravid gravitate gravy gray" +granary +grand +grandchild +grandchildren +granddaughter +grandeur +grandfather +grandiloquent +grandiose +grata +grate +grateful +grater +gratify +gratis +gratitude +gratuitous +gratuity +grave +gravel +.H 1 "Greenfield greengrocer greenhouse greenish Greenland Greensboro" +granary +grand +grandchild +grandchildren +granddaughter +grandeur +grandfather +grandiloquent +grassy +grata +grate +grateful +grater +gratify +gratis +gratitude +gratuitous +gratuity +grave +gravel +.H 1 "greensward greenware Greenwich greenwood Greer greet" +graven +Graves +gravestone +graveyard +gravid +gravitate +gravy +gray +graybeard +grayish +Grayson +graywacke +graze +grease +.APP "" "Graves app a gravestone graveyard gravid gravitate gravy gray" +granary +grand +grandchild +grandchildren +granddaughter +grandeur +grandfather +grandiloquent +grandiose +grata +grate +grateful +grater +gratify +gratis +gratitude +gratuitous +gratuity +grave +gravel +.APP "" "Greenfield app b greengrocer greenhouse greenish Greenland Greensboro" +granary +grand +grandchild +grandchildren +granddaughter +grandeur +.H 2 "grandfather grandiloquent grandiose grandma grandmother grandnephew" +.H 2 "grandniece grandpa grandparent grandson grandstand granite granitic" +.H 2 "granny granola grant grantee grantor granular granulate" +.H 2 "granule Granville grape" +.H 2 "grapefruit grapevine graph grapheme graphic graphite" +.H 3 "grapple" +grandfather +grandiloquent +grassy +grata +grate +grateful +grater +gratify +gratis +gratitude +gratuitous +gratuity +grave +gravel +.APP ABC "greensward app abc greenware Greenwich greenwood Greer greet" +graven +Graves +.APP "" "handstand app f handwrite handwritten handy handyman handymen" +gravestone +graveyard +gravid +gravitate +gravy +gray +graybeard +grayish +Grayson +graywacke +graze +grease +.APPSK "" 10 "Handel app c 10 handhold handicap handicapped handicapper" +.APPSK "" 23 "handicapping app d 23 handicraftsmen handiwork" +.APPSK "" 99 "handmade app e 99 handset handshake handsome handspike" +.nr Aph 0 +.APP "" "handstand app f handwrite handwritten handy handyman handymen" +headsmen +headstand +headstone +headstrong +headwall +headwater +headway +headwind +.H 2 "graybeard grayish Grayson graywacke graze grease greasy great greatcoat" +.H 2 "greater grebe Grecian Greece greed greedy Greek green Greenbelt Greenberg" +.H 2 "Greenblatt Greenbriar Greene greenery" +.H 3 "Greenfield greengrocer greenhouse greenish Greenland Greensboro" +.H 3 "greensward greenware Greenwich greenwood Greer greet" +heady +heal +Healey +health +healthful +healthy +Healy +heap +hear +heard +hearken +hearsay +hearse +Hearst +heart +heartbeat +heartbreak +hearten +heartfelt +hearth +hearty +heat +heater +heath +heathen +heathenish +Heathkit +heave +heaven +heavenward +heavy +heavyweight +Hebe +hebephrenic +Hebraic +Hebrew +Hecate +hecatomb +heck +heckle +Heckman +hectic +hector +.APP "" "hang hangable app f hangar hangman hangmen hangout hangover hank" +Hecuba +he'd +hedge +.H 2 "graybeard grayish Grayson graywacke graze grease greasy great greatcoat" +hedgehog +hedonism +hedonist +heed +heel +.H 2 "greater grebe Grecian Greece greed greedy Greek green Greenbelt Greenberg" +heft +hefty +Hegelian +hegemony +Heidelberg +heigh +height +heighten +Heine +Heinrich +Heinz +heir +heiress +Heisenberg +held +Helen +Helena +Helene +Helga +helical +helicopter +heliocentric +heliotrope +helium +helix +he'll +hell +hellbender +hellebore +Hellenic +hellfire +hellgrammite +hellish +hello +helm +helmet +Helmholtz +helmsman +helmsmen +Helmut +help +helpful +helpmate +.APP "" "Hankel app g Hanley Hanlon Hanna Hannah Hannibal Hanoi Hanover" +Helsinki +Helvetica +hem +hematite +Hemingway +hemisphere +hemispheric +hemlock +hemoglobin +hemolytic +hemorrhage +hemorrhoid +hemosiderin +hemp +Hempstead +hen +henbane +hence +henceforth +henchman +henchmen +.H 2 "greater grebe Grecian Greece greed greedy Greek green Greenbelt Greenberg" +Henderson +Hendrick +Hendricks +Hendrickson +henequen +Henley +henpeck +Henri +Henrietta +henry +hepatica +hepatitis +Hepburn +heptane +her +Hera +Heraclitus +herald +herb +Herbert +Herculean +Hercules +herd +herdsman +here +hereabout +hereafter +hereby +hereditary +.TC diff --git a/contrib/mm/examples/B1B2 b/contrib/mm/examples/B1B2 new file mode 100644 index 0000000..5847d67 --- /dev/null +++ b/contrib/mm/examples/B1B2 @@ -0,0 +1,98 @@ +.\" -*- nroff -*- +.\" Copyright (C) 1989-2014 Free Software Foundation, Inc. +.\" +.\" Copying and distribution of this file, with or without modification, +.\" are permitted in any medium without royalty provided the copyright +.\" notice and this notice are preserved. +. +abetting +abeyance +abeyant +abhorred +abhorrent +abide +Abidjan +Abigail +abject +ablate +ablaze +able +ablution +Abner +abnormal +Abo +aboard +abode +abolish +.B1 +abolition +abominable +abominate +aboriginal +AAA +ABORIGINE +ABORNING +ABORT +ABOUND +ABOUT +ABOVE +ABOVEBOARD +ABOVEGROUND +abovementioned +abrade +Abraham +Abram +Abramson +abrasion +abrasive +abreact +.B2 +abreast +abrogate +abrupt +abscess +abscissa +abscissae +absence +absent +absentee +absenteeism +absentia +absentminded +absinthe +absolute +absolution +absolve +absorb +absorbent +absorption +absorptive +abstain +abstention +abstract +abstracter +abstractor +ABSURD +ABUILDING +ABUNDANT +ABUSABLE +ABUSE +ABUSIVE +ABUT +ABUTTED +ABUTTING +ABYSMAL +ABYSS +ABYSSINIA +AC +ACADEME +ACADEMIA +ACADEMIC +ACADEMICIAN +ACADEMY +ACADIA +ACANTHUS +ACAPULCO +ACCEDE +ACCELERATE +ACCELEROMETER diff --git a/contrib/mm/examples/COVER b/contrib/mm/examples/COVER new file mode 100644 index 0000000..affdd2d --- /dev/null +++ b/contrib/mm/examples/COVER @@ -0,0 +1,242 @@ +.\" -*- nroff -*- +.\" Copyright (C) 1989-2014 Free Software Foundation, Inc. +.\" +.\" Copying and distribution of this file, with or without modification, +.\" are permitted in any medium without royalty provided the copyright +.\" notice and this notice are preserved. +. +.COVER +.ND 911123 +.TL "charge" "filing" +This is a test +granary +grand +grandchild +grandchildren +granddaughter +grandeur +grandfather +grandiloquent +grandiose +grandma +grandmother +grandnephew +grandniece +grandpa +grandparent +grandson +.AU "Nisse Svensson" "DGY" "BF" "Computer Center" "5488" "5-2115" "nisse@vira.sture.elm" +.AF "MT GRANDSTAND GRANITE GRANITIC" +.AS 1 10 +grant +grantee +grantor +granular +granulate +granule +Granville +grape +grapefruit +grapevine +graph +grapheme +graphic +graphite +grapple +grasp +grass +grassland +grassy +grata +grate +grateful +grater +gratify +gratis +gratitude +gratuitous +gratuity +grave +gravel +graven +Graves +gravestone +graveyard +gravid +gravitate +gravy +gray +graybeard +grayish +Grayson +graywacke +graze +grease +greasy +great +greatcoat +greater +grebe +Grecian +.AE +.COVEND +Greece +greed +greedy +Greek +green +Greenbelt +Greenberg +Greenblatt +Greenbriar +Greene +greenery +Greenfield +greengrocer +greenhouse +greenish +Greenland +Greensboro +greensward +greenware +Greenwich +greenwood +Greer +greet +Greg +gregarious +Gregg +Gregory +gremlin +grenade +Grendel +Grenoble +Gresham +Greta +Gretchen +grew +grey +greyhound +greylag +grid +griddle +gridiron +grief +grievance +grieve +grievous +griffin +Griffith +grill +grille +grilled +grillwork +grim +grimace +Grimaldi +grime +Grimes +Grimm +grin +grind +grindstone +grip +gripe +grippe +grisly +grist +gristmill +Griswold +grit +gritty +grizzle +granary +grand +grandchild +grandchildren +granddaughter +grandeur +grandfather +grandiloquent +grandiose +grandma +grandmother +grandnephew +grandniece +grandpa +grandparent +grandson +grandstand +granite +granitic +granny +granola +grant +grantee +grantor +granular +granulate +granule +Granville +grape +grapefruit +grapevine +graph +grapheme +graphic +graphite +grapple +grasp +grass +grassland +grassy +grata +grate +grateful +grater +gratify +gratis +gratitude +gratuitous +gratuity +grave +gravel +graven +Graves +gravestone +graveyard +gravid +gravitate +gravy +gray +graybeard +grayish +Grayson +graywacke +graze +grease +greasy +great +greatcoat +greater +grebe +Grecian +Greece +greed +greedy +Greek +green +Greenbelt +Greenberg +Greenblatt +Greenbriar +Greene +greenery +Greenfield +greengrocer +greenhouse +greenish +Greenland +Greensboro +greensward +greenware diff --git a/contrib/mm/examples/IND b/contrib/mm/examples/IND new file mode 100644 index 0000000..ad4ee5a --- /dev/null +++ b/contrib/mm/examples/IND @@ -0,0 +1,4198 @@ +.\" -*- nroff -*- +.\" Copyright (C) 1989-2014 Free Software Foundation, Inc. +.\" +.\" Copying and distribution of this file, with or without modification, +.\" are permitted in any medium without royalty provided the copyright +.\" notice and this notice are preserved. +. +.de foo +a=\\$1, b=\\$2 +.br +.. +.INITI N ind-data +.H 1 "halve" +.IND granary +grand +grandchild +grandchildren +granddaughter +grandeur +grandfather +grandiloquent +grandiose +grandma +grandmother +.IND grandnephew +grandniece +grandpa +grandparent +grandson +grandstand +granite +granitic +granny +granola +grant +grantee +grantor +granular +.IND granulate +granule +Granville +grape +.H 2 "grandfather grandiloquent grandiose grandma grandmother grandnephew" +grapefruit +grapevine +graph +grapheme +graphic +.H 1 "halo halocarbon halogen Halpern Halsey Halstead halt halvah" +graphite +grapple +grasp +grass +grassland +grassy +grata +grate +grateful +grater +gratify +gratis +gratitude +gratuitous +gratuity +.IND grave +gravel +graven +Graves +gravestone +graveyard +gravid +gravitate +gravy +gray +graybeard +grayish +Grayson +graywacke +graze +grease +greasy +great +greatcoat +greater +.H 1 "Han Hancock hand handbag handbook handclasp handcuff Handel handful" +grebe +Grecian +Greece +greed +greedy +.IND Greek +green +Greenbelt +Greenberg +.H 1 " granary grand grandchild grandchildren granddaughter grandeur" +Greenblatt +Greenbriar +Greene +greenery +Greenfield +greengrocer +greenhouse +greenish +Greenland +Greensboro +greensward +.H 1 "handgun" +greenware +Greenwich +greenwood +Greer +greet +Greg +gregarious +Gregg +Gregory +.IND gremlin +grenade +Grendel +Grenoble +Gresham +Greta +Gretchen +grew +grey +greyhound +greylag +grid +griddle +gridiron +grief +grievance +grieve +grievous +griffin +Griffith +grill +grille +grilled +grillwork +grim +.IND grimace +Grimaldi +grime +Grimes +Grimm +grin +grind +grindstone +grip +gripe +grippe +grisly +grist +gristmill +Griswold +grit +gritty +grizzle +grizzly +groan +groat +grocer +grocery +groggy +.IND groin +grommet +groom +groove +grope +grosbeak +gross +.H 1 "handicapped handicapper handicapping handicraft handicraftsman" +Grosset +Grossman +Grosvenor +grotesque +Groton +ground +groundsel +groundskeep +groundwork +group +groupoid +grout +grove +grovel +Grover +grow +growl +grown +grownup +.IND growth +grub +grubby +grudge +gruesome +gruff +grumble +Grumman +grunt +gryphon +g's +GSA +GU +Guam +guanidine +guanine +guano +guarantee +guaranteeing +guarantor +guaranty +guard +guardhouse +.IND Guardia +guardian +Guatemala +.IND gubernatorial +Guelph +Guenther +guerdon +guernsey +guerrilla +guess +guesswork +guest +guffaw +Guggenheim +Guiana +guidance +guide +guidebook +guideline +guidepost +guiding +guignol +guild +.H 1 "handicraftsmen handiwork handkerchief handle" +guildhall +guile +Guilford +guillemot +guillotine +guilt +.IND guilty +guinea +guise +guitar +gules +gulf +.H 1 "handleable handlebar handline handmade handmaiden handout" +gull +Gullah +gullet +gullible +gully +gulp +gum +gumbo +gumdrop +gummy +gumption +gumshoe +gun +Gunderson +.IND gunfight +gunfire +gunflint +gunk +gunky +gunman +.IND gunmen +gunnery +gunny +gunplay +gunpowder +gunshot +gunsling +Gunther +gurgle +Gurkha +guru +Gus +gush +gusset +gust +Gustafson +Gustav +Gustave +Gustavus +gusto +gusty +gut +.H 1 "handset" +Gutenberg +Guthrie +gutsy +guttural +.IND guy +Guyana +guzzle +Gwen +Gwyn +gym +gymnasium +gymnast +gymnastic +gymnosperm +gyp +gypsite +gypsum +gypsy +gyrate +gyrfalcon +gyro +.IND gyrocompass +gyroscope +h +ha +Haag +Haas +habeas +haberdashery +Haberman +.IND Habib +habit +habitant +habitat +habitation +habitual +habituate +hacienda +hack +hackberry +Hackett +hackle +hackmatack +.H 1 "handshake handsome handspike handstand handwaving handwrite handwritten" +hackney +hackneyed +hacksaw +had +Hadamard +Haddad +haddock +Hades +Hadley +hadn't +Hadrian +hadron +hafnium +.IND Hagen +Hager +haggard +haggle +Hagstrom +Hague +Hahn +Haifa +haiku +hail +hailstone +hailstorm +Haines +hair +.IND haircut +hairdo +hairpin +hairy +Haiti +Haitian +Hal +halcyon +hale +Haley +half +halfback +.IND halfhearted +halfway +halibut +halide +.H 1 "handy handyman handymen Haney Hanford hang hangable hangar" +Halifax +halite +hall +hallelujah +Halley +hallmark +hallow +Halloween +hallucinate +hallway +halma +halo +halocarbon +halogen +Halpern +Halsey +Halstead +halt +halvah +halve +Halverson +ham +.IND Hamal +Hamburg +hamburger +Hamilton +hamlet +Hamlin +hammerhead +hammock +Hammond +hamper +Hampshire +.IND Hampton +hamster +Han +.H 1 "hangman hangmen hangout hangover hank Hankel Hanley" +Hancock +hand +handbag +handbook +handclasp +handcuff +Handel +handful +handgun +handhold +handicap +handicapped +.IND handicapper +handicapping +handicraft +handicraftsman +handicraftsmen +handiwork +handkerchief +handle +handleable +handlebar +handline +handmade +handmaiden +handout +handset +handshake +handsome +handspike +handstand +handwaving +.H 1 "Hanlon Hanna Hannah Hannibal Hanoi Hanover Hanoverian Hans" +handwrite +handwritten +handy +handyman +handymen +Haney +.IND Hanford +hang +hangable +hangar +hangman +hangmen +hangout +hangover +.IND hank +Hankel +Hanley +Hanlon +Hanna +Hannah +Hannibal +Hanoi +Hanover +Hanoverian +Hans +Hansel +Hansen +hansom +Hanson +Hanukkah +hap +.H 1 "Hansel" +haphazard +.IND haploid +haploidy +haplology +happen +happenstance +happy +Hapsburg +harangue +harass +Harbin +harbinger +Harcourt +hard +hardbake +hardboard +hardboiled +hardcopy +harden +hardhat +Hardin +.H 1 "Hansen hansom Hanson Hanukkah hap haphazard haploid haploidy" +Harding +hardscrabble +hardtack +hardtop +hardware +hardwood +.IND hardworking +hardy +hare +harelip +harem +.IND hark +Harlan +Harlem +Harley +harm +harmful +Harmon +harmonic +harmonica +harmonious +.H 1 "haplology happen happenstance happy Hapsburg harangue harass Harbin" +harmony +harness +Harold +harp +harpoon +harpsichord +Harpy +Harriet +Harriman +Harrington +Harris +.IND Harrisburg +Harrison +harrow +harry +harsh +harshen +hart +Hartford +Hartley +Hartman +Harvard +harvest +harvestman +Harvey +hash +hashish +hasn't +hasp +hassle +hast +haste +hasten +Hastings +hasty +hat +hatch +.IND hatchet +hatchway +.IND hate +hateful +hater +Hatfield +hath +Hathaway +hatred +Hatteras +Hattie +Hattiesburg +Haugen +haughty +haul +haulage +haunch +haunt +Hausdorff +Havana +have +haven +haven't +Havilland +havoc +haw +.IND Hawaii +Hawaiian +hawk +Hawkins +Hawley +hawthorn +.H 2 "hammock Hammond hamper Hampshire Hampton hamster" +Hawthorne +hay +Hayden +Haydn +Hayes +hayfield +Haynes +Hays +haystack +Hayward +hayward +hazard +hazardous +haze +hazel +hazelnut +hazy +he +head +.IND headache +.IND headboard +headdress +headland +headlight +headline +headmaster +headphone +headquarter +headquarters +headroom +headset +headsman +headsmen +headstand +headstone +headstrong +headwall +headwater +headway +headwind +heady +heal +Healey +health +healthful +healthy +.IND Healy +heap +hear +heard +hearken +hearsay +hearse +Hearst +heart +heartbeat +heartbreak +hearten +heartfelt +hearth +hearty +heat +heater +heath +heathen +heathenish +Heathkit +heave +.IND heaven +heavenward +heavy +heavyweight +.IND Hebe +hebephrenic +Hebraic +Hebrew +Hecate +hecatomb +heck +heckle +Heckman +hectic +hector +Hecuba +he'd +hedge +hedgehog +hedonism +hedonist +heed +heel +heft +hefty +Hegelian +hegemony +Heidelberg +heigh +height +.IND heighten +Heine +Heinrich +Heinz +heir +heiress +Heisenberg +held +Helen +Helena +Helene +Helga +helical +helicopter +heliocentric +heliotrope +helium +helix +he'll +.IND hell +hellbender +hellebore +Hellenic +hellfire +hellgrammite +hellish +.IND hello +helm +helmet +.H 1 "Halverson ham Hamal Hamburg hamburger Hamilton hamlet Hamlin hammerhead" +Helmholtz +helmsman +helmsmen +Helmut +help +helpful +helpmate +Helsinki +Helvetica +hem +hematite +Hemingway +hemisphere +hemispheric +hemlock +hemoglobin +hemolytic +hemorrhage +hemorrhoid +hemosiderin +hemp +Hempstead +hen +.IND henbane +hence +henceforth +henchman +henchmen +Henderson +Hendrick +Hendricks +Hendrickson +henequen +Henley +henpeck +Henri +Henrietta +henry +hepatica +.IND hepatitis +Hepburn +heptane +her +Hera +Heraclitus +herald +herb +Herbert +Herculean +.IND Hercules +herd +herdsman +here +hereabout +hereafter +hereby +hereditary +heredity +Hereford +herein +hereinabove +hereinafter +hereinbelow +hereof +heresy +heretic +hereto +heretofore +hereunder +hereunto +herewith +heritable +heritage +Herkimer +Herman +.IND Hermann +hermeneutic +Hermes +hermetic +Hermite +hermitian +Hermosa +Hernandez +hero +Herodotus +heroes +heroic +heroin +.IND heroine +heroism +heron +herpes +herpetology +Herr +herringbone +Herschel +herself +Hershel +Hershey +hertz +Hertzog +.IND hesitant +hesitate +hesitater +Hesperus +Hess +Hesse +Hessian +Hester +heterocyclic +heterodyne +heterogamous +heterogeneity +heterogeneous +heterosexual +heterostructure +heterozygous +Hetman +Hettie +Hetty +Heublein +heuristic +Heusen +Heuser +hew +Hewett +Hewitt +.IND Hewlett +hewn +hex +hexachloride +hexadecimal +hexafluoride +hexagon +hexagonal +hexameter +hexane +.IND hey +heyday +hi +Hiatt +hiatus +Hiawatha +hibachi +Hibbard +hibernate +Hibernia +hick +Hickey +Hickman +hickory +Hicks +hid +.IND hidalgo +hidden +hide +hideaway +hideous +hideout +hierarchal +hierarchic +hierarchy +hieratic +hieroglyphic +Hieronymus +hifalutin +Higgins +high +highball +highboy +highest +highfalutin +highhanded +highland +highlight +highroad +hightail +highway +highwayman +.IND highwaymen +hijack +hijinks +hike +hilarious +hilarity +Hilbert +.IND Hildebrand +hill +hillbilly +Hillcrest +Hillel +hillman +hillmen +hillock +hillside +hilltop +hilly +hilt +Hilton +hilum +him +Himalaya +himself +hind +hindmost +.IND hindrance +hindsight +Hindu +Hinduism +Hines +hinge +Hinman +hint +hinterland +hip +hippo +Hippocrates +Hippocratic +hippodrome +hippopotamus +hippy +hipster +Hiram +hire +hireling +Hiroshi +Hiroshima +Hirsch +hirsute +his +Hispanic +.IND hiss +histamine +histidine +histochemic +.IND histochemistry +histogram +histology +historian +historic +historiography +history +histrionic +hit +Hitachi +hitch +Hitchcock +.H 1 "harbinger" +hither +hitherto +Hitler +hive +ho +hoagie +Hoagland +hoagy +hoar +hoard +.IND hoarfrost +hoarse +hob +Hobart +Hobbes +hobble +Hobbs +hobby +hobbyhorse +hobgoblin +hobo +Hoboken +hoc +hock +hockey +hocus +hodge +hodgepodge +Hodges +Hodgkin +hoe +Hoff +Hoffman +hog +hogan +hogging +.IND hoi +.IND Hokan +Holbrook +Holcomb +hold +holden +holdout +holdover +holdup +hole +holeable +holiday +Holland +Hollandaise +holler +Hollerith +Hollingsworth +Hollister +hollow +Holloway +hollowware +holly +hollyhock +Hollywood +Holm +Holman +.IND Holmdel +Holmes +holmium +holocaust +Holocene +hologram +holography +Holst +Holstein +holster +holt +Holyoke +.IND holystone +.INDP +inject injudicious Injun injunct injunction injure injurious injury +injustice ink inkling inlaid inland inlay inlet Inman inmate inn innards +innate inner innermost innkeeper innocent innocuous innovate innuendo +innumerable inoculate inoffensive inoperable inoperative inopportune +inordinate inorganic input inputting inquest inquire inquiry inquisition +inquisitive inquisitor inroad insane insatiable inscribe inscription +inscrutable insect insecticide insecure inseminate insensible insensitive +inseparable insert inset inshore inside insidious insight insightful +insignia insignificant insincere insinuate insipid insist insistent +insofar insolent insoluble insolvable insolvent insomnia insomniac +insouciant inspect inspector inspiration inspire instable install +installation instalment instance instant instantaneous instantiate +.INITI H ind-data2 +.H 1 "halve" +.IND granary +grand +grandchild +grandchildren +granddaughter +grandeur +grandfather +grandiloquent +grandiose +grandma +grandmother +.IND grandnephew +grandniece +grandpa +grandparent +grandson +grandstand +granite +granitic +granny +granola +grant +grantee +grantor +granular +.IND granulate +granule +Granville +grape +.H 2 "grandfather grandiloquent grandiose grandma grandmother grandnephew" +grapefruit +grapevine +graph +grapheme +graphic +.H 1 "halo halocarbon halogen Halpern Halsey Halstead halt halvah" +graphite +grapple +grasp +grass +grassland +grassy +grata +grate +grateful +grater +gratify +gratis +gratitude +gratuitous +gratuity +.IND grave +gravel +graven +Graves +gravestone +graveyard +gravid +gravitate +gravy +gray +graybeard +grayish +Grayson +graywacke +graze +grease +greasy +great +greatcoat +greater +.H 1 "Han Hancock hand handbag handbook handclasp handcuff Handel handful" +grebe +Grecian +Greece +greed +greedy +.IND Greek +green +Greenbelt +Greenberg +.H 1 " granary grand grandchild grandchildren granddaughter grandeur" +Greenblatt +Greenbriar +Greene +greenery +Greenfield +greengrocer +greenhouse +greenish +Greenland +Greensboro +greensward +.H 1 "handgun" +greenware +Greenwich +greenwood +Greer +greet +Greg +gregarious +Gregg +Gregory +.IND gremlin +grenade +Grendel +Grenoble +Gresham +Greta +Gretchen +grew +grey +greyhound +greylag +grid +griddle +gridiron +grief +grievance +grieve +grievous +griffin +Griffith +grill +grille +grilled +grillwork +grim +.IND grimace +Grimaldi +grime +Grimes +Grimm +grin +grind +grindstone +grip +gripe +grippe +grisly +grist +gristmill +Griswold +grit +gritty +grizzle +grizzly +groan +groat +grocer +grocery +groggy +.IND groin +grommet +groom +groove +grope +grosbeak +gross +.H 1 "handicapped handicapper handicapping handicraft handicraftsman" +Grosset +Grossman +Grosvenor +grotesque +Groton +ground +groundsel +groundskeep +groundwork +group +groupoid +grout +grove +grovel +Grover +grow +growl +grown +grownup +.IND growth +grub +grubby +grudge +gruesome +gruff +grumble +Grumman +grunt +gryphon +g's +GSA +GU +Guam +guanidine +guanine +guano +guarantee +guaranteeing +guarantor +guaranty +guard +guardhouse +.IND Guardia +guardian +Guatemala +.IND gubernatorial +Guelph +Guenther +guerdon +guernsey +guerrilla +guess +guesswork +guest +guffaw +Guggenheim +Guiana +guidance +guide +guidebook +guideline +guidepost +guiding +guignol +guild +.H 1 "handicraftsmen handiwork handkerchief handle" +guildhall +guile +Guilford +guillemot +guillotine +guilt +.IND guilty +guinea +guise +guitar +gules +gulf +.H 1 "handleable handlebar handline handmade handmaiden handout" +gull +Gullah +gullet +gullible +gully +gulp +gum +gumbo +gumdrop +gummy +gumption +gumshoe +gun +Gunderson +.IND gunfight +gunfire +gunflint +gunk +gunky +gunman +.IND gunmen +gunnery +gunny +gunplay +gunpowder +gunshot +gunsling +Gunther +gurgle +Gurkha +guru +Gus +gush +gusset +gust +Gustafson +Gustav +Gustave +Gustavus +gusto +gusty +gut +.H 1 "handset" +Gutenberg +Guthrie +gutsy +guttural +.IND guy +Guyana +guzzle +Gwen +Gwyn +gym +gymnasium +gymnast +gymnastic +gymnosperm +gyp +gypsite +gypsum +gypsy +gyrate +gyrfalcon +gyro +.IND gyrocompass +gyroscope +h +ha +Haag +Haas +habeas +haberdashery +Haberman +.IND Habib +habit +habitant +habitat +habitation +habitual +habituate +hacienda +hack +hackberry +Hackett +hackle +hackmatack +.H 1 "handshake handsome handspike handstand handwaving handwrite handwritten" +hackney +hackneyed +hacksaw +had +Hadamard +Haddad +haddock +Hades +Hadley +hadn't +Hadrian +hadron +hafnium +.IND Hagen +Hager +haggard +haggle +Hagstrom +Hague +Hahn +Haifa +haiku +hail +hailstone +hailstorm +Haines +hair +.IND haircut +hairdo +hairpin +hairy +Haiti +Haitian +Hal +halcyon +hale +Haley +half +halfback +.IND halfhearted +halfway +halibut +halide +.H 1 "handy handyman handymen Haney Hanford hang hangable hangar" +Halifax +halite +hall +hallelujah +Halley +hallmark +hallow +Halloween +hallucinate +hallway +halma +halo +halocarbon +halogen +Halpern +Halsey +Halstead +halt +halvah +halve +Halverson +ham +.IND Hamal +Hamburg +hamburger +Hamilton +hamlet +Hamlin +hammerhead +hammock +Hammond +hamper +Hampshire +.IND Hampton +hamster +Han +.H 1 "hangman hangmen hangout hangover hank Hankel Hanley" +Hancock +hand +handbag +handbook +handclasp +handcuff +Handel +handful +handgun +handhold +handicap +handicapped +.IND handicapper +handicapping +handicraft +handicraftsman +handicraftsmen +handiwork +handkerchief +handle +handleable +handlebar +handline +handmade +handmaiden +handout +handset +handshake +handsome +handspike +handstand +handwaving +.H 1 "Hanlon Hanna Hannah Hannibal Hanoi Hanover Hanoverian Hans" +handwrite +handwritten +handy +handyman +handymen +Haney +.IND Hanford +hang +hangable +hangar +hangman +hangmen +hangout +hangover +.IND hank +Hankel +Hanley +Hanlon +Hanna +Hannah +Hannibal +Hanoi +Hanover +Hanoverian +Hans +Hansel +Hansen +hansom +Hanson +Hanukkah +hap +.H 1 "Hansel" +haphazard +.IND haploid +haploidy +haplology +happen +happenstance +happy +Hapsburg +harangue +harass +Harbin +harbinger +Harcourt +hard +hardbake +hardboard +hardboiled +hardcopy +harden +hardhat +Hardin +.H 1 "Hansen hansom Hanson Hanukkah hap haphazard haploid haploidy" +Harding +hardscrabble +hardtack +hardtop +hardware +hardwood +.IND hardworking +hardy +hare +harelip +harem +.IND hark +Harlan +Harlem +Harley +harm +harmful +Harmon +harmonic +harmonica +harmonious +.H 1 "haplology happen happenstance happy Hapsburg harangue harass Harbin" +harmony +harness +Harold +harp +harpoon +harpsichord +Harpy +Harriet +Harriman +Harrington +Harris +.IND Harrisburg +Harrison +harrow +harry +harsh +harshen +hart +Hartford +Hartley +Hartman +Harvard +harvest +harvestman +Harvey +hash +hashish +hasn't +hasp +hassle +hast +haste +hasten +Hastings +hasty +hat +hatch +.IND hatchet +hatchway +.IND hate +hateful +hater +Hatfield +hath +Hathaway +hatred +Hatteras +Hattie +Hattiesburg +Haugen +haughty +haul +haulage +haunch +haunt +Hausdorff +Havana +have +haven +haven't +Havilland +havoc +haw +.IND Hawaii +Hawaiian +hawk +Hawkins +Hawley +hawthorn +.H 2 "hammock Hammond hamper Hampshire Hampton hamster" +Hawthorne +hay +Hayden +Haydn +Hayes +hayfield +Haynes +Hays +haystack +Hayward +hayward +hazard +hazardous +haze +hazel +hazelnut +hazy +he +head +.IND headache +.IND headboard +headdress +headland +headlight +headline +headmaster +headphone +headquarter +headquarters +headroom +headset +headsman +headsmen +headstand +headstone +headstrong +headwall +headwater +headway +headwind +heady +heal +Healey +health +healthful +healthy +.IND Healy +heap +hear +heard +hearken +hearsay +hearse +Hearst +heart +heartbeat +heartbreak +hearten +heartfelt +hearth +hearty +heat +heater +heath +heathen +heathenish +Heathkit +heave +.IND heaven +heavenward +heavy +heavyweight +.IND Hebe +hebephrenic +Hebraic +Hebrew +Hecate +hecatomb +heck +heckle +Heckman +hectic +hector +Hecuba +he'd +hedge +hedgehog +hedonism +hedonist +heed +heel +heft +hefty +Hegelian +hegemony +Heidelberg +heigh +height +.IND heighten +Heine +Heinrich +Heinz +heir +heiress +Heisenberg +held +Helen +Helena +Helene +Helga +helical +helicopter +heliocentric +heliotrope +helium +helix +he'll +.IND hell +hellbender +hellebore +Hellenic +hellfire +hellgrammite +hellish +.IND hello +helm +helmet +.H 1 "Halverson ham Hamal Hamburg hamburger Hamilton hamlet Hamlin hammerhead" +Helmholtz +helmsman +helmsmen +Helmut +help +helpful +helpmate +Helsinki +Helvetica +hem +hematite +Hemingway +hemisphere +hemispheric +hemlock +hemoglobin +hemolytic +hemorrhage +hemorrhoid +hemosiderin +hemp +Hempstead +hen +.IND henbane +hence +henceforth +henchman +henchmen +Henderson +Hendrick +Hendricks +Hendrickson +henequen +Henley +henpeck +Henri +Henrietta +henry +hepatica +.IND hepatitis +Hepburn +heptane +her +Hera +Heraclitus +herald +herb +Herbert +Herculean +.IND Hercules +herd +herdsman +here +hereabout +hereafter +hereby +hereditary +heredity +Hereford +herein +hereinabove +hereinafter +hereinbelow +hereof +heresy +heretic +hereto +heretofore +hereunder +hereunto +herewith +heritable +heritage +Herkimer +Herman +.IND Hermann +hermeneutic +Hermes +hermetic +Hermite +hermitian +Hermosa +Hernandez +hero +Herodotus +heroes +heroic +heroin +.IND heroine +heroism +heron +herpes +herpetology +Herr +herringbone +Herschel +herself +Hershel +Hershey +hertz +Hertzog +.IND hesitant +hesitate +hesitater +Hesperus +Hess +Hesse +Hessian +Hester +heterocyclic +heterodyne +heterogamous +heterogeneity +heterogeneous +heterosexual +heterostructure +heterozygous +Hetman +Hettie +Hetty +Heublein +heuristic +Heusen +Heuser +hew +Hewett +Hewitt +.IND Hewlett +hewn +hex +hexachloride +hexadecimal +hexafluoride +hexagon +hexagonal +hexameter +hexane +.IND hey +heyday +hi +Hiatt +hiatus +Hiawatha +hibachi +Hibbard +hibernate +Hibernia +hick +Hickey +Hickman +hickory +Hicks +hid +.IND hidalgo +hidden +hide +hideaway +hideous +hideout +hierarchal +hierarchic +hierarchy +hieratic +hieroglyphic +Hieronymus +hifalutin +Higgins +high +highball +highboy +highest +highfalutin +highhanded +highland +highlight +highroad +hightail +highway +highwayman +.IND highwaymen +hijack +hijinks +hike +hilarious +hilarity +Hilbert +.IND Hildebrand +hill +hillbilly +Hillcrest +Hillel +hillman +hillmen +hillock +hillside +hilltop +hilly +hilt +Hilton +hilum +him +Himalaya +himself +hind +hindmost +.IND hindrance +hindsight +Hindu +Hinduism +Hines +hinge +Hinman +hint +hinterland +hip +hippo +Hippocrates +Hippocratic +hippodrome +hippopotamus +hippy +hipster +Hiram +hire +hireling +Hiroshi +Hiroshima +Hirsch +hirsute +his +Hispanic +.IND hiss +histamine +histidine +histochemic +.IND histochemistry +histogram +histology +historian +historic +historiography +history +histrionic +hit +Hitachi +hitch +Hitchcock +.H 1 "harbinger" +hither +hitherto +Hitler +hive +ho +hoagie +Hoagland +hoagy +hoar +hoard +.IND hoarfrost +hoarse +hob +Hobart +Hobbes +hobble +Hobbs +hobby +hobbyhorse +hobgoblin +hobo +Hoboken +hoc +hock +hockey +hocus +hodge +hodgepodge +Hodges +Hodgkin +hoe +Hoff +Hoffman +hog +hogan +hogging +.IND hoi +.IND Hokan +Holbrook +Holcomb +hold +holden +holdout +holdover +holdup +hole +holeable +holiday +Holland +Hollandaise +holler +Hollerith +Hollingsworth +Hollister +hollow +Holloway +hollowware +holly +hollyhock +Hollywood +Holm +Holman +.IND Holmdel +Holmes +holmium +holocaust +Holocene +hologram +holography +Holst +Holstein +holster +holt +Holyoke +.IND holystone +.INDP +inject injudicious Injun injunct injunction injure injurious injury +injustice ink inkling inlaid inland inlay inlet Inman inmate inn innards +innate inner innermost innkeeper innocent innocuous innovate innuendo +innumerable inoculate inoffensive inoperable inoperative inopportune +inordinate inorganic input inputting inquest inquire inquiry inquisition +.INITI B ind-data3 +.H 1 "halve" +.IND granary +grand +grandchild +grandchildren +granddaughter +grandeur +grandfather +grandiloquent +grandiose +grandma +grandmother +.IND grandnephew +grandniece +grandpa +grandparent +grandson +grandstand +granite +granitic +granny +granola +grant +grantee +grantor +granular +.IND granulate +granule +Granville +grape +.H 2 "grandfather grandiloquent grandiose grandma grandmother grandnephew" +grapefruit +grapevine +graph +grapheme +graphic +.H 1 "halo halocarbon halogen Halpern Halsey Halstead halt halvah" +graphite +grapple +grasp +grass +grassland +grassy +grata +grate +grateful +grater +gratify +gratis +gratitude +gratuitous +gratuity +.IND grave +gravel +graven +Graves +gravestone +graveyard +gravid +gravitate +gravy +gray +graybeard +grayish +Grayson +graywacke +graze +grease +greasy +great +greatcoat +greater +.H 1 "Han Hancock hand handbag handbook handclasp handcuff Handel handful" +grebe +Grecian +Greece +greed +greedy +.IND Greek +green +Greenbelt +Greenberg +.H 1 " granary grand grandchild grandchildren granddaughter grandeur" +Greenblatt +Greenbriar +Greene +greenery +Greenfield +greengrocer +greenhouse +greenish +Greenland +Greensboro +greensward +.H 1 "handgun" +greenware +Greenwich +greenwood +Greer +greet +Greg +gregarious +Gregg +Gregory +.IND gremlin +grenade +Grendel +Grenoble +Gresham +Greta +Gretchen +grew +grey +greyhound +greylag +grid +griddle +gridiron +grief +grievance +grieve +grievous +griffin +Griffith +grill +grille +grilled +grillwork +grim +.IND grimace +Grimaldi +grime +Grimes +Grimm +grin +grind +grindstone +grip +gripe +grippe +grisly +grist +gristmill +Griswold +grit +gritty +grizzle +grizzly +groan +groat +grocer +grocery +groggy +.IND groin +grommet +groom +groove +grope +grosbeak +gross +.H 1 "handicapped handicapper handicapping handicraft handicraftsman" +Grosset +Grossman +Grosvenor +grotesque +Groton +ground +groundsel +groundskeep +groundwork +group +groupoid +grout +grove +grovel +Grover +grow +growl +grown +grownup +.IND growth +grub +grubby +grudge +gruesome +gruff +grumble +Grumman +grunt +gryphon +g's +GSA +GU +Guam +guanidine +guanine +guano +guarantee +guaranteeing +guarantor +guaranty +guard +guardhouse +.IND Guardia +guardian +Guatemala +.IND gubernatorial +Guelph +Guenther +guerdon +guernsey +guerrilla +guess +guesswork +guest +guffaw +Guggenheim +Guiana +guidance +guide +guidebook +guideline +guidepost +guiding +guignol +guild +.H 1 "handicraftsmen handiwork handkerchief handle" +guildhall +guile +Guilford +guillemot +guillotine +guilt +.IND guilty +guinea +guise +guitar +gules +gulf +.H 1 "handleable handlebar handline handmade handmaiden handout" +gull +Gullah +gullet +gullible +gully +gulp +gum +gumbo +gumdrop +gummy +gumption +gumshoe +gun +Gunderson +.IND gunfight +gunfire +gunflint +gunk +gunky +gunman +.IND gunmen +gunnery +gunny +gunplay +gunpowder +gunshot +gunsling +Gunther +gurgle +Gurkha +guru +Gus +gush +gusset +gust +Gustafson +Gustav +Gustave +Gustavus +gusto +gusty +gut +.H 1 "handset" +Gutenberg +Guthrie +gutsy +guttural +.IND guy +Guyana +guzzle +Gwen +Gwyn +gym +gymnasium +gymnast +gymnastic +gymnosperm +gyp +gypsite +gypsum +gypsy +gyrate +gyrfalcon +gyro +.IND gyrocompass +gyroscope +h +ha +Haag +Haas +habeas +haberdashery +Haberman +.IND Habib +habit +habitant +habitat +habitation +habitual +habituate +hacienda +hack +hackberry +Hackett +hackle +hackmatack +.H 1 "handshake handsome handspike handstand handwaving handwrite handwritten" +hackney +hackneyed +hacksaw +had +Hadamard +Haddad +haddock +Hades +Hadley +hadn't +Hadrian +hadron +hafnium +.IND Hagen +Hager +haggard +haggle +Hagstrom +Hague +Hahn +Haifa +haiku +hail +hailstone +hailstorm +Haines +hair +.IND haircut +hairdo +hairpin +hairy +Haiti +Haitian +Hal +halcyon +hale +Haley +half +halfback +.IND halfhearted +halfway +halibut +halide +.H 1 "handy handyman handymen Haney Hanford hang hangable hangar" +Halifax +halite +hall +hallelujah +Halley +hallmark +hallow +Halloween +hallucinate +hallway +halma +halo +halocarbon +halogen +Halpern +Halsey +Halstead +halt +halvah +halve +Halverson +ham +.IND Hamal +Hamburg +hamburger +Hamilton +hamlet +Hamlin +hammerhead +hammock +Hammond +hamper +Hampshire +.IND Hampton +hamster +Han +.H 1 "hangman hangmen hangout hangover hank Hankel Hanley" +Hancock +hand +handbag +handbook +handclasp +handcuff +Handel +handful +handgun +handhold +handicap +handicapped +.IND handicapper +handicapping +handicraft +handicraftsman +handicraftsmen +handiwork +handkerchief +handle +handleable +handlebar +handline +handmade +handmaiden +handout +handset +handshake +handsome +handspike +handstand +handwaving +.H 1 "Hanlon Hanna Hannah Hannibal Hanoi Hanover Hanoverian Hans" +handwrite +handwritten +handy +handyman +handymen +Haney +.IND Hanford +hang +hangable +hangar +hangman +hangmen +hangout +hangover +.IND hank +Hankel +Hanley +Hanlon +Hanna +Hannah +Hannibal +Hanoi +Hanover +Hanoverian +Hans +Hansel +Hansen +hansom +Hanson +Hanukkah +hap +.H 1 "Hansel" +haphazard +.IND haploid +haploidy +haplology +happen +happenstance +happy +Hapsburg +harangue +harass +Harbin +harbinger +Harcourt +hard +hardbake +hardboard +hardboiled +hardcopy +harden +hardhat +Hardin +.H 1 "Hansen hansom Hanson Hanukkah hap haphazard haploid haploidy" +Harding +hardscrabble +hardtack +hardtop +hardware +hardwood +.IND hardworking +hardy +hare +harelip +harem +.IND hark +Harlan +Harlem +Harley +harm +harmful +Harmon +harmonic +harmonica +harmonious +.H 1 "haplology happen happenstance happy Hapsburg harangue harass Harbin" +harmony +harness +Harold +harp +harpoon +harpsichord +Harpy +Harriet +Harriman +Harrington +Harris +.IND Harrisburg +Harrison +harrow +harry +harsh +harshen +hart +Hartford +Hartley +Hartman +Harvard +harvest +harvestman +Harvey +hash +hashish +hasn't +hasp +hassle +hast +haste +hasten +Hastings +hasty +hat +hatch +.IND hatchet +hatchway +.IND hate +hateful +hater +Hatfield +hath +Hathaway +hatred +Hatteras +Hattie +Hattiesburg +Haugen +haughty +haul +haulage +haunch +haunt +Hausdorff +Havana +have +haven +haven't +Havilland +havoc +haw +.IND Hawaii +Hawaiian +hawk +Hawkins +Hawley +hawthorn +.H 2 "hammock Hammond hamper Hampshire Hampton hamster" +Hawthorne +hay +Hayden +Haydn +Hayes +hayfield +Haynes +Hays +haystack +Hayward +hayward +hazard +hazardous +haze +hazel +hazelnut +hazy +he +head +.IND headache +.IND headboard +headdress +headland +headlight +headline +headmaster +headphone +headquarter +headquarters +headroom +headset +headsman +headsmen +headstand +headstone +headstrong +headwall +headwater +headway +headwind +heady +heal +Healey +health +healthful +healthy +.IND Healy +heap +hear +heard +hearken +hearsay +hearse +Hearst +heart +heartbeat +heartbreak +hearten +heartfelt +hearth +hearty +heat +heater +heath +heathen +heathenish +Heathkit +heave +.IND heaven +heavenward +heavy +heavyweight +.IND Hebe +hebephrenic +Hebraic +Hebrew +Hecate +hecatomb +heck +heckle +Heckman +hectic +hector +Hecuba +he'd +hedge +hedgehog +hedonism +hedonist +heed +heel +heft +hefty +Hegelian +hegemony +Heidelberg +heigh +height +.IND heighten +Heine +Heinrich +Heinz +heir +heiress +Heisenberg +held +Helen +Helena +Helene +Helga +helical +helicopter +heliocentric +heliotrope +helium +helix +he'll +.IND hell +hellbender +hellebore +Hellenic +hellfire +hellgrammite +hellish +.IND hello +helm +helmet +.H 1 "Halverson ham Hamal Hamburg hamburger Hamilton hamlet Hamlin hammerhead" +Helmholtz +helmsman +helmsmen +Helmut +help +helpful +helpmate +Helsinki +Helvetica +hem +hematite +Hemingway +hemisphere +hemispheric +hemlock +hemoglobin +hemolytic +hemorrhage +hemorrhoid +hemosiderin +hemp +Hempstead +hen +.IND henbane +hence +henceforth +henchman +henchmen +Henderson +Hendrick +Hendricks +Hendrickson +henequen +Henley +henpeck +Henri +Henrietta +henry +hepatica +.IND hepatitis +Hepburn +heptane +her +Hera +Heraclitus +herald +herb +Herbert +Herculean +.IND Hercules +herd +herdsman +here +hereabout +hereafter +hereby +hereditary +heredity +Hereford +herein +hereinabove +hereinafter +hereinbelow +hereof +heresy +heretic +hereto +heretofore +hereunder +hereunto +herewith +heritable +heritage +Herkimer +Herman +.IND Hermann +hermeneutic +Hermes +hermetic +Hermite +hermitian +Hermosa +Hernandez +hero +Herodotus +heroes +heroic +heroin +.IND heroine +heroism +heron +herpes +herpetology +Herr +herringbone +Herschel +herself +Hershel +Hershey +hertz +Hertzog +.IND hesitant +hesitate +hesitater +Hesperus +Hess +Hesse +Hessian +Hester +heterocyclic +heterodyne +heterogamous +heterogeneity +heterogeneous +heterosexual +heterostructure +heterozygous +Hetman +Hettie +Hetty +Heublein +heuristic +Heusen +Heuser +hew +Hewett +Hewitt +.IND Hewlett +hewn +hex +hexachloride +hexadecimal +hexafluoride +hexagon +hexagonal +hexameter +hexane +.IND hey +heyday +hi +Hiatt +hiatus +Hiawatha +hibachi +Hibbard +hibernate +Hibernia +hick +Hickey +Hickman +hickory +Hicks +hid +.IND hidalgo +hidden +hide +hideaway +hideous +hideout +hierarchal +hierarchic +hierarchy +hieratic +hieroglyphic +Hieronymus +hifalutin +Higgins +high +highball +highboy +highest +highfalutin +highhanded +highland +highlight +highroad +hightail +highway +highwayman +.IND highwaymen +hijack +hijinks +hike +hilarious +hilarity +Hilbert +.IND Hildebrand +hill +hillbilly +Hillcrest +Hillel +hillman +hillmen +hillock +hillside +hilltop +hilly +hilt +Hilton +hilum +him +Himalaya +himself +hind +hindmost +.IND hindrance +hindsight +Hindu +Hinduism +Hines +hinge +Hinman +hint +hinterland +hip +hippo +Hippocrates +Hippocratic +hippodrome +hippopotamus +hippy +hipster +Hiram +hire +hireling +Hiroshi +Hiroshima +Hirsch +hirsute +his +Hispanic +.IND hiss +histamine +histidine +histochemic +.IND histochemistry +histogram +histology +historian +historic +historiography +history +histrionic +hit +Hitachi +hitch +Hitchcock +.H 1 "harbinger" +hither +hitherto +Hitler +hive +ho +hoagie +Hoagland +hoagy +hoar +hoard +.IND hoarfrost +hoarse +hob +Hobart +Hobbes +hobble +Hobbs +hobby +hobbyhorse +hobgoblin +hobo +Hoboken +hoc +hock +hockey +hocus +hodge +hodgepodge +Hodges +Hodgkin +hoe +Hoff +Hoffman +hog +hogan +hogging +.IND hoi +.IND Hokan +Holbrook +Holcomb +hold +holden +holdout +holdover +holdup +hole +holeable +holiday +Holland +Hollandaise +holler +Hollerith +Hollingsworth +Hollister +hollow +Holloway +hollowware +holly +hollyhock +Hollywood +Holm +Holman +.IND Holmdel +Holmes +holmium +holocaust +Holocene +hologram +holography +Holst +Holstein +holster +holt +Holyoke +.IND holystone +.INDP +inject injudicious Injun injunct injunction injure injurious injury +injustice ink inkling inlaid inland inlay inlet Inman inmate inn innards +innate inner innermost innkeeper innocent innocuous innovate innuendo +innumerable inoculate inoffensive inoperable inoperative inopportune +inordinate inorganic input inputting inquest inquire inquiry inquisition +.INITI B ind-data4 foo +.H 1 "halve" +.IND granary +grand +grandchild +grandchildren +granddaughter +grandeur +grandfather +grandiloquent +grandiose +grandma +grandmother +.IND grandnephew +grandniece +grandpa +grandparent +grandson +grandstand +granite +granitic +granny +granola +grant +grantee +grantor +granular +.IND granulate +granule +Granville +grape +.H 2 "grandfather grandiloquent grandiose grandma grandmother grandnephew" +grapefruit +grapevine +graph +grapheme +graphic +.H 1 "halo halocarbon halogen Halpern Halsey Halstead halt halvah" +graphite +grapple +grasp +grass +grassland +grassy +grata +grate +grateful +grater +gratify +gratis +gratitude +gratuitous +gratuity +.IND grave +gravel +graven +Graves +gravestone +graveyard +gravid +gravitate +gravy +gray +graybeard +grayish +Grayson +graywacke +graze +grease +greasy +great +greatcoat +greater +.H 1 "Han Hancock hand handbag handbook handclasp handcuff Handel handful" +grebe +Grecian +Greece +greed +greedy +.IND Greek +green +Greenbelt +Greenberg +.H 1 " granary grand grandchild grandchildren granddaughter grandeur" +Greenblatt +Greenbriar +Greene +greenery +Greenfield +greengrocer +greenhouse +greenish +Greenland +Greensboro +greensward +.H 1 "handgun" +greenware +Greenwich +greenwood +Greer +greet +Greg +gregarious +Gregg +Gregory +.IND gremlin +grenade +Grendel +Grenoble +Gresham +Greta +Gretchen +grew +grey +greyhound +greylag +grid +griddle +gridiron +grief +grievance +grieve +grievous +griffin +Griffith +grill +grille +grilled +grillwork +grim +.IND grimace +Grimaldi +grime +Grimes +Grimm +grin +grind +grindstone +grip +gripe +grippe +grisly +grist +gristmill +Griswold +grit +gritty +grizzle +grizzly +groan +groat +grocer +grocery +groggy +.IND groin +grommet +groom +groove +grope +grosbeak +gross +.H 1 "handicapped handicapper handicapping handicraft handicraftsman" +Grosset +Grossman +Grosvenor +grotesque +Groton +ground +groundsel +groundskeep +groundwork +group +groupoid +grout +grove +grovel +Grover +grow +growl +grown +grownup +.IND growth +grub +grubby +grudge +gruesome +gruff +grumble +Grumman +grunt +gryphon +g's +GSA +GU +Guam +guanidine +guanine +guano +guarantee +guaranteeing +guarantor +guaranty +guard +guardhouse +.IND Guardia +guardian +Guatemala +.IND gubernatorial +Guelph +Guenther +guerdon +guernsey +guerrilla +guess +guesswork +guest +guffaw +Guggenheim +Guiana +guidance +guide +guidebook +guideline +guidepost +guiding +guignol +guild +.H 1 "handicraftsmen handiwork handkerchief handle" +guildhall +guile +Guilford +guillemot +guillotine +guilt +.IND guilty +guinea +guise +guitar +gules +gulf +.H 1 "handleable handlebar handline handmade handmaiden handout" +gull +Gullah +gullet +gullible +gully +gulp +gum +gumbo +gumdrop +gummy +gumption +gumshoe +gun +Gunderson +.IND gunfight +gunfire +gunflint +gunk +gunky +gunman +.IND gunmen +gunnery +gunny +gunplay +gunpowder +gunshot +gunsling +Gunther +gurgle +Gurkha +guru +Gus +gush +gusset +gust +Gustafson +Gustav +Gustave +Gustavus +gusto +gusty +gut +.H 1 "handset" +Gutenberg +Guthrie +gutsy +guttural +.IND guy +Guyana +guzzle +Gwen +Gwyn +gym +gymnasium +gymnast +gymnastic +gymnosperm +gyp +gypsite +gypsum +gypsy +gyrate +gyrfalcon +gyro +.IND gyrocompass +gyroscope +h +ha +Haag +Haas +habeas +haberdashery +Haberman +.IND Habib +habit +habitant +habitat +habitation +habitual +habituate +hacienda +hack +hackberry +Hackett +hackle +hackmatack +.H 1 "handshake handsome handspike handstand handwaving handwrite handwritten" +hackney +hackneyed +hacksaw +had +Hadamard +Haddad +haddock +Hades +Hadley +hadn't +Hadrian +hadron +hafnium +.IND Hagen +Hager +haggard +haggle +Hagstrom +Hague +Hahn +Haifa +haiku +hail +hailstone +hailstorm +Haines +hair +.IND haircut +hairdo +hairpin +hairy +Haiti +Haitian +Hal +halcyon +hale +Haley +half +halfback +.IND halfhearted +halfway +halibut +halide +.H 1 "handy handyman handymen Haney Hanford hang hangable hangar" +Halifax +halite +hall +hallelujah +Halley +hallmark +hallow +Halloween +hallucinate +hallway +halma +halo +halocarbon +halogen +Halpern +Halsey +Halstead +halt +halvah +halve +Halverson +ham +.IND Hamal +Hamburg +hamburger +Hamilton +hamlet +Hamlin +hammerhead +hammock +Hammond +hamper +Hampshire +.IND Hampton +hamster +Han +.H 1 "hangman hangmen hangout hangover hank Hankel Hanley" +Hancock +hand +handbag +handbook +handclasp +handcuff +Handel +handful +handgun +handhold +handicap +handicapped +.IND handicapper +handicapping +handicraft +handicraftsman +handicraftsmen +handiwork +handkerchief +handle +handleable +handlebar +handline +handmade +handmaiden +handout +handset +handshake +handsome +handspike +handstand +handwaving +.H 1 "Hanlon Hanna Hannah Hannibal Hanoi Hanover Hanoverian Hans" +handwrite +handwritten +handy +handyman +handymen +Haney +.IND Hanford +hang +hangable +hangar +hangman +hangmen +hangout +hangover +.IND hank +Hankel +Hanley +Hanlon +Hanna +Hannah +Hannibal +Hanoi +Hanover +Hanoverian +Hans +Hansel +Hansen +hansom +Hanson +Hanukkah +hap +.H 1 "Hansel" +haphazard +.IND haploid +haploidy +haplology +happen +happenstance +happy +Hapsburg +harangue +harass +Harbin +harbinger +Harcourt +hard +hardbake +hardboard +hardboiled +hardcopy +harden +hardhat +Hardin +.H 1 "Hansen hansom Hanson Hanukkah hap haphazard haploid haploidy" +Harding +hardscrabble +hardtack +hardtop +hardware +hardwood +.IND hardworking +hardy +hare +harelip +harem +.IND hark +Harlan +Harlem +Harley +harm +harmful +Harmon +harmonic +harmonica +harmonious +.H 1 "haplology happen happenstance happy Hapsburg harangue harass Harbin" +harmony +harness +Harold +harp +harpoon +harpsichord +Harpy +Harriet +Harriman +Harrington +Harris +.IND Harrisburg +Harrison +harrow +harry +harsh +harshen +hart +Hartford +Hartley +Hartman +Harvard +harvest +harvestman +Harvey +hash +hashish +hasn't +hasp +hassle +hast +haste +hasten +Hastings +hasty +hat +hatch +.IND hatchet +hatchway +.IND hate +hateful +hater +Hatfield +hath +Hathaway +hatred +Hatteras +Hattie +Hattiesburg +Haugen +haughty +haul +haulage +haunch +haunt +Hausdorff +Havana +have +haven +haven't +Havilland +havoc +haw +.IND Hawaii +Hawaiian +hawk +Hawkins +Hawley +hawthorn +.H 2 "hammock Hammond hamper Hampshire Hampton hamster" +Hawthorne +hay +Hayden +Haydn +Hayes +hayfield +Haynes +Hays +haystack +Hayward +hayward +hazard +hazardous +haze +hazel +hazelnut +hazy +he +head +.IND headache +.IND headboard +headdress +headland +headlight +headline +headmaster +headphone +headquarter +headquarters +headroom +headset +headsman +headsmen +headstand +headstone +headstrong +headwall +headwater +headway +headwind +heady +heal +Healey +health +healthful +healthy +.IND Healy +heap +hear +heard +hearken +hearsay +hearse +Hearst +heart +heartbeat +heartbreak +hearten +heartfelt +hearth +hearty +heat +heater +heath +heathen +heathenish +Heathkit +heave +.IND heaven +heavenward +heavy +heavyweight +.IND Hebe +hebephrenic +Hebraic +Hebrew +Hecate +hecatomb +heck +heckle +Heckman +hectic +hector +Hecuba +he'd +hedge +hedgehog +hedonism +hedonist +heed +heel +heft +hefty +Hegelian +hegemony +Heidelberg +heigh +height +.IND heighten +Heine +Heinrich +Heinz +heir +heiress +Heisenberg +held +Helen +Helena +Helene +Helga +helical +helicopter +heliocentric +heliotrope +helium +helix +he'll +.IND hell +hellbender +hellebore +Hellenic +hellfire +hellgrammite +hellish +.IND hello +helm +helmet +.H 1 "Halverson ham Hamal Hamburg hamburger Hamilton hamlet Hamlin hammerhead" +Helmholtz +helmsman +helmsmen +Helmut +help +helpful +helpmate +Helsinki +Helvetica +hem +hematite +Hemingway +hemisphere +hemispheric +hemlock +hemoglobin +hemolytic +hemorrhage +hemorrhoid +hemosiderin +hemp +Hempstead +hen +.IND henbane +hence +henceforth +henchman +henchmen +Henderson +Hendrick +Hendricks +Hendrickson +henequen +Henley +henpeck +Henri +Henrietta +henry +hepatica +.IND hepatitis +Hepburn +heptane +her +Hera +Heraclitus +herald +herb +Herbert +Herculean +.IND Hercules +herd +herdsman +here +hereabout +hereafter +hereby +hereditary +heredity +Hereford +herein +hereinabove +hereinafter +hereinbelow +hereof +heresy +heretic +hereto +heretofore +hereunder +hereunto +herewith +heritable +heritage +Herkimer +Herman +.IND Hermann +hermeneutic +Hermes +hermetic +Hermite +hermitian +Hermosa +Hernandez +hero +Herodotus +heroes +heroic +heroin +.IND heroine +heroism +heron +herpes +herpetology +Herr +herringbone +Herschel +herself +Hershel +Hershey +hertz +Hertzog +.IND hesitant +hesitate +hesitater +Hesperus +Hess +Hesse +Hessian +Hester +heterocyclic +heterodyne +heterogamous +heterogeneity +heterogeneous +heterosexual +heterostructure +heterozygous +Hetman +Hettie +Hetty +Heublein +heuristic +Heusen +Heuser +hew +Hewett +Hewitt +.IND Hewlett +hewn +hex +hexachloride +hexadecimal +hexafluoride +hexagon +hexagonal +hexameter +hexane +.IND hey +heyday +hi +Hiatt +hiatus +Hiawatha +hibachi +Hibbard +hibernate +Hibernia +hick +Hickey +Hickman +hickory +Hicks +hid +.IND hidalgo +hidden +hide +hideaway +hideous +hideout +hierarchal +hierarchic +hierarchy +hieratic +hieroglyphic +Hieronymus +hifalutin +Higgins +high +highball +highboy +highest +highfalutin +highhanded +highland +highlight +highroad +hightail +highway +highwayman +.IND highwaymen +hijack +hijinks +hike +hilarious +hilarity +Hilbert +.IND Hildebrand +hill +hillbilly +Hillcrest +Hillel +hillman +hillmen +hillock +hillside +hilltop +hilly +hilt +Hilton +hilum +him +Himalaya +himself +hind +hindmost +.IND hindrance +hindsight +Hindu +Hinduism +Hines +hinge +Hinman +hint +hinterland +hip +hippo +Hippocrates +Hippocratic +hippodrome +hippopotamus +hippy +hipster +Hiram +hire +hireling +Hiroshi +Hiroshima +Hirsch +hirsute +his +Hispanic +.IND hiss +histamine +histidine +histochemic +.IND histochemistry +histogram +histology +historian +historic +historiography +history +histrionic +hit +Hitachi +hitch +Hitchcock +.H 1 "harbinger" +hither +hitherto +Hitler +hive +ho +hoagie +Hoagland +hoagy +hoar +hoard +.IND hoarfrost +hoarse +hob +Hobart +Hobbes +hobble +Hobbs +hobby +hobbyhorse +hobgoblin +hobo +Hoboken +hoc +hock +hockey +hocus +hodge +hodgepodge +Hodges +Hodgkin +hoe +Hoff +Hoffman +hog +hogan +hogging +.IND hoi +.IND Hokan +Holbrook +Holcomb +hold +holden +holdout +holdover +holdup +hole +holeable +holiday +Holland +Hollandaise +holler +Hollerith +Hollingsworth +Hollister +hollow +Holloway +hollowware +holly +hollyhock +Hollywood +Holm +Holman +.IND Holmdel +Holmes +holmium +holocaust +Holocene +hologram +holography +Holst +Holstein +holster +holt +Holyoke +.IND holystone +.INDP +inject injudicious Injun injunct injunction injure injurious injury +injustice ink inkling inlaid inland inlay inlet Inman inmate inn innards +innate inner innermost innkeeper innocent innocuous innovate innuendo +innumerable inoculate inoffensive inoperable inoperative inopportune +inordinate inorganic input inputting inquest inquire inquiry inquisition diff --git a/contrib/mm/examples/LT b/contrib/mm/examples/LT new file mode 100644 index 0000000..2dbf189 --- /dev/null +++ b/contrib/mm/examples/LT @@ -0,0 +1,1065 @@ +.\" -*- nroff -*- +.\" Copyright (C) 1989-2014 Free Software Foundation, Inc. +.\" +.\" Copying and distribution of this file, with or without modification, +.\" are permitted in any medium without royalty provided the copyright +.\" notice and this notice are preserved. +. +.ND 1994-10-26 +.\" .WA "Nisse Nilsson" notitle +.\" .WE +.WA "Sven Olsson" title +Return address +Street +City, State Zip Code +Text +.WE +.IA "Inside address" title +Addressee name XXXXXXX +Title XXXXXXXXXXXXXXX +Company xxxxxxxxxxxx +Street xxxxxxxxxxxxxx +City, State Zip Code +Text xxxxxxxxxxxxxxxxxx +.IE +.LO CN +.LO RN "referens" +.LO AT Attention +.LO SA "Hej hopp" +.LO SJ "Subject line" +.LT BL +hepp +granary +grand +grandchild +grandchildren +granddaughter +grandeur +grandfather +grandiloquent +grandiose +grandma +grandmother +grandnephew +grandniece +grandpa +grandparent +grandson +grandstand +granite +granitic +granny +granola +grant +grantee +grantor +granular +granulate +granule +Granville +grape +grapefruit +grapevine +graph +grapheme +graphic +graphite +grapple +grasp +grass +grassland +grassy +grata +grate +grateful +grater +gratify +gratis +gratitude +gratuitous +gratuity +grave +gravel +graven +Graves +gravestone +graveyard +gravid +gravitate +gravy +gray +graybeard +grayish +Grayson +graywacke +graze +grease +greasy +great +greatcoat +greater +grebe +Grecian +Greece +greed +greedy +Greek +green +Greenbelt +Greenberg +Greenblatt +Greenbriar +Greene +greenery +Greenfield +greengrocer +greenhouse +greenish +Greenland +Greensboro +greensward +greenware +Greenwich +greenwood +Greer +greet +Greg +gregarious +Gregg +Gregory +gremlin +grenade +Grendel +Grenoble +Gresham +Greta +Gretchen +grew +grey +greyhound +greylag +grid +griddle +gridiron +grief +grievance +grieve +grievous +griffin +Griffith +grill +grille +grilled +grillwork +grim +grimace +Grimaldi +grime +Grimes +Grimm +grin +grind +grindstone +grip +.P +gripe +grippe +grisly +grist +gristmill +Griswold +grit +gritty +grizzle +grizzly +groan +groat +grocer +grocery +groggy +groin +grommet +groom +groove +grope +grosbeak +gross +Grosset +Grossman +Grosvenor +grotesque +Groton +ground +groundsel +groundskeep +groundwork +group +groupoid +grout +grove +grovel +Grover +grow +growl +grown +grownup +growth +grub +grubby +grudge +gruesome +gruff +grumble +Grumman +grunt +gryphon +g's +GSA +GU +Guam +guanidine +guanine +guano +guarantee +guaranteeing +guarantor +guaranty +guard +guardhouse +Guardia +guardian +Guatemala +gubernatorial +Guelph +Guenther +guerdon +guernsey +guerrilla +guess +guesswork +guest +guffaw +Guggenheim +Guiana +guidance +guide +guidebook +guideline +guidepost +guiding +guignol +guild +guildhall +guile +Guilford +guillemot +guillotine +guilt +guilty +guinea +guise +guitar +gules +gulf +gull +Gullah +gullet +gullible +gully +gulp +gum +gumbo +gumdrop +gummy +gumption +gumshoe +gun +Gunderson +gunfight +gunfire +gunflint +gunk +gunky +gunman +gunmen +gunnery +gunny +gunplay +gunpowder +gunshot +gunsling +Gunther +gurgle +Gurkha +guru +Gus +gush +gusset +gust +Gustafson +Gustav +Gustave +Gustavus +gusto +gusty +gut +Gutenberg +Guthrie +gutsy +guttural +guy +.P +Guyana +guzzle +Gwen +Gwyn +gym +gymnasium +gymnast +gymnastic +gymnosperm +gyp +gypsite +gypsum +gypsy +gyrate +gyrfalcon +gyro +gyrocompass +gyroscope +h +ha +Haag +Haas +habeas +haberdashery +Haberman +Habib +habit +habitant +habitat +habitation +habitual +habituate +hacienda +hack +hackberry +Hackett +hackle +hackmatack +hackney +hackneyed +hacksaw +had +Hadamard +Haddad +haddock +Hades +Hadley +hadn't +Hadrian +hadron +hafnium +Hagen +Hager +haggard +haggle +Hagstrom +Hague +Hahn +Haifa +haiku +hail +hailstone +hailstorm +Haines +hair +haircut +hairdo +hairpin +hairy +Haiti +Haitian +Hal +halcyon +hale +Haley +half +halfback +halfhearted +halfway +halibut +halide +Halifax +halite +hall +hallelujah +Halley +hallmark +hallow +Halloween +hallucinate +hallway +halma +halo +halocarbon +halogen +Halpern +Halsey +Halstead +halt +halvah +halve +Halverson +ham +Hamal +Hamburg +hamburger +Hamilton +hamlet +Hamlin +hammerhead +hammock +Hammond +hamper +Hampshire +Hampton +hamster +Han +Hancock +hand +handbag +handbook +handclasp +handcuff +Handel +handful +handgun +handhold +handicap +handicapped +handicapper +handicapping +handicraft +handicraftsman +handicraftsmen +handiwork +handkerchief +handle +handleable +handlebar +handline +handmade +handmaiden +handout +handset +handshake +handsome +handspike +handstand +handwaving +handwrite +handwritten +handy +handyman +handymen +Haney +Hanford +hang +hangable +hangar +hangman +hangmen +hangout +hangover +hank +Hankel +Hanley +Hanlon +Hanna +Hannah +Hannibal +Hanoi +Hanover +Hanoverian +Hans +Hansel +Hansen +hansom +Hanson +Hanukkah +hap +haphazard +haploid +haploidy +haplology +happen +happenstance +happy +Hapsburg +harangue +harass +Harbin +harbinger +Harcourt +hard +hardbake +hardboard +hardboiled +hardcopy +harden +hardhat +Hardin +Harding +hardscrabble +hardtack +hardtop +hardware +hardwood +hardworking +hardy +hare +harelip +harem +hark +Harlan +Harlem +Harley +harm +harmful +Harmon +harmonic +harmonica +harmonious +harmony +harness +Harold +harp +harpoon +harpsichord +Harpy +Harriet +Harriman +Harrington +Harris +Harrisburg +Harrison +harrow +harry +harsh +harshen +hart +Hartford +Hartley +Hartman +Harvard +.P +harvest +harvestman +Harvey +hash +hashish +hasn't +hasp +hassle +hast +haste +hasten +Hastings +hasty +hat +hatch +hatchet +hatchway +hate +hateful +hater +Hatfield +hath +Hathaway +hatred +Hatteras +Hattie +Hattiesburg +Haugen +haughty +haul +haulage +haunch +haunt +Hausdorff +Havana +have +haven +haven't +Havilland +havoc +haw +Hawaii +Hawaiian +hawk +Hawkins +Hawley +hawthorn +Hawthorne +hay +Hayden +Haydn +Hayes +hayfield +Haynes +Hays +haystack +Hayward +hayward +hazard +hazardous +haze +hazel +hazelnut +hazy +he +head +headache +headboard +headdress +headland +headlight +headline +headmaster +headphone +headquarter +headquarters +headroom +headset +headsman +headsmen +headstand +headstone +headstrong +headwall +headwater +headway +headwind +heady +heal +Healey +health +healthful +healthy +Healy +heap +hear +heard +hearken +hearsay +hearse +Hearst +heart +heartbeat +heartbreak +hearten +heartfelt +hearth +hearty +heat +heater +heath +heathen +heathenish +Heathkit +heave +heaven +heavenward +heavy +heavyweight +Hebe +hebephrenic +Hebraic +Hebrew +Hecate +hecatomb +heck +heckle +Heckman +hectic +hector +Hecuba +he'd +hedge +hedgehog +hedonism +hedonist +heed +heel +heft +hefty +Hegelian +hegemony +Heidelberg +heigh +height +heighten +Heine +Heinrich +Heinz +heir +heiress +Heisenberg +held +Helen +Helena +Helene +Helga +helical +helicopter +heliocentric +heliotrope +helium +helix +he'll +hell +hellbender +hellebore +Hellenic +hellfire +hellgrammite +hellish +hello +helm +helmet +Helmholtz +helmsman +helmsmen +Helmut +help +helpful +helpmate +Helsinki +Helvetica +hem +hematite +Hemingway +hemisphere +hemispheric +hemlock +hemoglobin +hemolytic +hemorrhage +hemorrhoid +hemosiderin +hemp +Hempstead +hen +henbane +hence +henceforth +henchman +henchmen +Henderson +Hendrick +Hendricks +Hendrickson +henequen +Henley +henpeck +Henri +Henrietta +henry +hepatica +hepatitis +Hepburn +heptane +her +Hera +Heraclitus +herald +herb +Herbert +Herculean +Hercules +herd +herdsman +here +hereabout +hereafter +hereby +hereditary +heredity +Hereford +herein +hereinabove +hereinafter +hereinbelow +hereof +heresy +heretic +hereto +heretofore +hereunder +hereunto +.P +herewith +heritable +heritage +Herkimer +Herman +Hermann +hermeneutic +Hermes +hermetic +Hermite +hermitian +Hermosa +Hernandez +hero +Herodotus +heroes +heroic +heroin +heroine +heroism +heron +herpes +herpetology +Herr +herringbone +Herschel +herself +Hershel +Hershey +hertz +Hertzog +hesitant +hesitate +hesitater +Hesperus +Hess +Hesse +Hessian +Hester +heterocyclic +heterodyne +heterogamous +heterogeneity +heterogeneous +heterosexual +heterostructure +heterozygous +Hetman +Hettie +Hetty +Heublein +heuristic +Heusen +Heuser +hew +Hewett +Hewitt +Hewlett +hewn +hex +hexachloride +hexadecimal +hexafluoride +hexagon +hexagonal +hexameter +hexane +hey +heyday +hi +Hiatt +hiatus +Hiawatha +hibachi +Hibbard +hibernate +Hibernia +hick +Hickey +Hickman +hickory +Hicks +hid +hidalgo +hidden +hide +hideaway +hideous +hideout +hierarchal +hierarchic +hierarchy +hieratic +hieroglyphic +Hieronymus +hifalutin +Higgins +high +highball +highboy +highest +highfalutin +highhanded +highland +highlight +highroad +hightail +highway +highwayman +highwaymen +hijack +hijinks +hike +hilarious +hilarity +Hilbert +Hildebrand +hill +hillbilly +Hillcrest +Hillel +hillman +hillmen +hillock +hillside +hilltop +hilly +hilt +Hilton +hilum +him +Himalaya +himself +hind +hindmost +hindrance +hindsight +Hindu +Hinduism +Hines +hinge +Hinman +hint +hinterland +hip +hippo +Hippocrates +Hippocratic +hippodrome +hippopotamus +hippy +hipster +Hiram +hire +hireling +Hiroshi +Hiroshima +Hirsch +hirsute +his +Hispanic +hiss +histamine +histidine +histochemic +histochemistry +histogram +histology +historian +historic +historiography +history +histrionic +hit +Hitachi +hitch +Hitchcock +hither +hitherto +Hitler +hive +ho +hoagie +Hoagland +hoagy +hoar +hoard +hoarfrost +hoarse +hob +Hobart +Hobbes +hobble +Hobbs +hobby +.P +hobbyhorse +hobgoblin +hobo +Hoboken +hoc +hock +hockey +hocus +hodge +hodgepodge +Hodges +Hodgkin +hoe +Hoff +Hoffman +hog +hogan +hogging +hoi +Hokan +Holbrook +Holcomb +hold +holden +holdout +holdover +holdup +hole +holeable +holiday +Holland +Hollandaise +holler +Hollerith +Hollingsworth +Hollister +hollow +Holloway +hollowware +holly +hollyhock +Hollywood +Holm +Holman +Holmdel +Holmes +holmium +holocaust +Holocene +hologram +holography +Holst +Holstein +holster +holt +Holyoke +holystone +.FC +.SG +.NS 7 +text text text +text text text +.NS 12 +Holyoke +holystone +.NS +holt +.NE diff --git a/contrib/mm/examples/LT.se b/contrib/mm/examples/LT.se new file mode 100644 index 0000000..6635c70 --- /dev/null +++ b/contrib/mm/examples/LT.se @@ -0,0 +1,1069 @@ +.\" -*- nroff -*- +.\" Copyright (C) 1989-2014 Free Software Foundation, Inc. +.\" +.\" Copying and distribution of this file, with or without modification, +.\" are permitted in any medium without royalty provided the copyright +.\" notice and this notice are preserved. +. +.\" groff -mmse LT.se +.ND 1994-10-26 +.WA "Sven Olsson" title +Return address +Street +City, State Zip Code +Text +.WE +.IA "Inside address" title +Addressee name XXXXXXX +Title XXXXXXXXXXXXXXX +Company xxxxxxxxxxxx +Street xxxxxxxxxxxxxx +City, State Zip Code +Text xxxxxxxxxxxxxxxxxx +.IE +.LO DNAMN Dokumentnamn +.LO MDAT 1994-01-01 +.LO BIL 2 +.LO KOMP Kompletteringsuppgift +.LO DBET dokumentnummer +.LO BET ärendebeteckning +.LO MBET "Mottagarens b" +.LO SIDOR 22 +.\" vänster eller högerställt brev +.\" .LT SVH +.LT SVV +hepp +granary +grand +grandchild +grandchildren +granddaughter +grandeur +grandfather +grandiloquent +grandiose +grandma +grandmother +grandnephew +grandniece +grandpa +grandparent +grandson +grandstand +granite +granitic +granny +granola +grant +grantee +grantor +granular +granulate +granule +Granville +grape +grapefruit +grapevine +graph +grapheme +graphic +graphite +grapple +grasp +grass +grassland +grassy +grata +grate +grateful +grater +gratify +gratis +gratitude +gratuitous +gratuity +grave +gravel +graven +Graves +gravestone +graveyard +gravid +gravitate +gravy +gray +graybeard +grayish +Grayson +graywacke +graze +grease +greasy +great +greatcoat +greater +grebe +Grecian +Greece +greed +greedy +Greek +green +Greenbelt +Greenberg +Greenblatt +Greenbriar +Greene +greenery +Greenfield +greengrocer +greenhouse +greenish +Greenland +Greensboro +greensward +greenware +Greenwich +greenwood +Greer +greet +Greg +gregarious +Gregg +Gregory +gremlin +grenade +Grendel +Grenoble +Gresham +Greta +Gretchen +grew +grey +greyhound +greylag +grid +griddle +gridiron +grief +grievance +grieve +grievous +griffin +Griffith +grill +grille +grilled +grillwork +grim +grimace +Grimaldi +grime +Grimes +Grimm +grin +grind +grindstone +grip +.P +gripe +grippe +grisly +grist +gristmill +Griswold +grit +gritty +grizzle +grizzly +groan +groat +grocer +grocery +groggy +groin +grommet +groom +groove +grope +grosbeak +gross +Grosset +Grossman +Grosvenor +grotesque +Groton +ground +groundsel +groundskeep +groundwork +group +groupoid +grout +grove +grovel +Grover +grow +growl +grown +grownup +growth +grub +grubby +grudge +gruesome +gruff +grumble +Grumman +grunt +gryphon +g's +GSA +GU +Guam +guanidine +guanine +guano +guarantee +guaranteeing +guarantor +guaranty +guard +guardhouse +Guardia +guardian +Guatemala +gubernatorial +Guelph +Guenther +guerdon +guernsey +guerrilla +guess +guesswork +guest +guffaw +Guggenheim +Guiana +guidance +guide +guidebook +guideline +guidepost +guiding +guignol +guild +guildhall +guile +Guilford +guillemot +guillotine +guilt +guilty +guinea +guise +guitar +gules +gulf +gull +Gullah +gullet +gullible +gully +gulp +gum +gumbo +gumdrop +gummy +gumption +gumshoe +gun +Gunderson +gunfight +gunfire +gunflint +gunk +gunky +gunman +gunmen +gunnery +gunny +gunplay +gunpowder +gunshot +gunsling +Gunther +gurgle +Gurkha +guru +Gus +gush +gusset +gust +Gustafson +Gustav +Gustave +Gustavus +gusto +gusty +gut +Gutenberg +Guthrie +gutsy +guttural +guy +.P +Guyana +guzzle +Gwen +Gwyn +gym +gymnasium +gymnast +gymnastic +gymnosperm +gyp +gypsite +gypsum +gypsy +gyrate +gyrfalcon +gyro +gyrocompass +gyroscope +h +ha +Haag +Haas +habeas +haberdashery +Haberman +Habib +habit +habitant +habitat +habitation +habitual +habituate +hacienda +hack +hackberry +Hackett +hackle +hackmatack +hackney +hackneyed +hacksaw +had +Hadamard +Haddad +haddock +Hades +Hadley +hadn't +Hadrian +hadron +hafnium +Hagen +Hager +haggard +haggle +Hagstrom +Hague +Hahn +Haifa +haiku +hail +hailstone +hailstorm +Haines +hair +haircut +hairdo +hairpin +hairy +Haiti +Haitian +Hal +halcyon +hale +Haley +half +halfback +halfhearted +halfway +halibut +halide +Halifax +halite +hall +hallelujah +Halley +hallmark +hallow +Halloween +hallucinate +hallway +halma +halo +halocarbon +halogen +Halpern +Halsey +Halstead +halt +halvah +halve +Halverson +ham +Hamal +Hamburg +hamburger +Hamilton +hamlet +Hamlin +hammerhead +hammock +Hammond +hamper +Hampshire +Hampton +hamster +Han +Hancock +hand +handbag +handbook +handclasp +handcuff +Handel +handful +handgun +handhold +handicap +handicapped +handicapper +handicapping +handicraft +handicraftsman +handicraftsmen +handiwork +handkerchief +handle +handleable +handlebar +handline +handmade +handmaiden +handout +handset +handshake +handsome +handspike +handstand +handwaving +handwrite +handwritten +handy +handyman +handymen +Haney +Hanford +hang +hangable +hangar +hangman +hangmen +hangout +hangover +hank +Hankel +Hanley +Hanlon +Hanna +Hannah +Hannibal +Hanoi +Hanover +Hanoverian +Hans +Hansel +Hansen +hansom +Hanson +Hanukkah +hap +haphazard +haploid +haploidy +haplology +happen +happenstance +happy +Hapsburg +harangue +harass +Harbin +harbinger +Harcourt +hard +hardbake +hardboard +hardboiled +hardcopy +harden +hardhat +Hardin +Harding +hardscrabble +hardtack +hardtop +hardware +hardwood +hardworking +hardy +hare +harelip +harem +hark +Harlan +Harlem +Harley +harm +harmful +Harmon +harmonic +harmonica +harmonious +harmony +harness +Harold +harp +harpoon +harpsichord +Harpy +Harriet +Harriman +Harrington +Harris +Harrisburg +Harrison +harrow +harry +harsh +harshen +hart +Hartford +Hartley +Hartman +Harvard +.P +harvest +harvestman +Harvey +hash +hashish +hasn't +hasp +hassle +hast +haste +hasten +Hastings +hasty +hat +hatch +hatchet +hatchway +hate +hateful +hater +Hatfield +hath +Hathaway +hatred +Hatteras +Hattie +Hattiesburg +Haugen +haughty +haul +haulage +haunch +haunt +Hausdorff +Havana +have +haven +haven't +Havilland +havoc +haw +Hawaii +Hawaiian +hawk +Hawkins +Hawley +hawthorn +Hawthorne +hay +Hayden +Haydn +Hayes +hayfield +Haynes +Hays +haystack +Hayward +hayward +hazard +hazardous +haze +hazel +hazelnut +hazy +he +head +headache +headboard +headdress +headland +headlight +headline +headmaster +headphone +headquarter +headquarters +headroom +headset +headsman +headsmen +headstand +headstone +headstrong +headwall +headwater +headway +headwind +heady +heal +Healey +health +healthful +healthy +Healy +heap +hear +heard +hearken +hearsay +hearse +Hearst +heart +heartbeat +heartbreak +hearten +heartfelt +hearth +hearty +heat +heater +heath +heathen +heathenish +Heathkit +heave +heaven +heavenward +heavy +heavyweight +Hebe +hebephrenic +Hebraic +Hebrew +Hecate +hecatomb +heck +heckle +Heckman +hectic +hector +Hecuba +he'd +hedge +hedgehog +hedonism +hedonist +heed +heel +heft +hefty +Hegelian +hegemony +Heidelberg +heigh +height +heighten +Heine +Heinrich +Heinz +heir +heiress +Heisenberg +held +Helen +Helena +Helene +Helga +helical +helicopter +heliocentric +heliotrope +helium +helix +he'll +hell +hellbender +hellebore +Hellenic +hellfire +hellgrammite +hellish +hello +helm +helmet +Helmholtz +helmsman +helmsmen +Helmut +help +helpful +helpmate +Helsinki +Helvetica +hem +hematite +Hemingway +hemisphere +hemispheric +hemlock +hemoglobin +hemolytic +hemorrhage +hemorrhoid +hemosiderin +hemp +Hempstead +hen +henbane +hence +henceforth +henchman +henchmen +Henderson +Hendrick +Hendricks +Hendrickson +henequen +Henley +henpeck +Henri +Henrietta +henry +hepatica +hepatitis +Hepburn +heptane +her +Hera +Heraclitus +herald +herb +Herbert +Herculean +Hercules +herd +herdsman +here +hereabout +hereafter +hereby +hereditary +heredity +Hereford +herein +hereinabove +hereinafter +hereinbelow +hereof +heresy +heretic +hereto +heretofore +hereunder +hereunto +.P +herewith +heritable +heritage +Herkimer +Herman +Hermann +hermeneutic +Hermes +hermetic +Hermite +hermitian +Hermosa +Hernandez +hero +Herodotus +heroes +heroic +heroin +heroine +heroism +heron +herpes +herpetology +Herr +herringbone +Herschel +herself +Hershel +Hershey +hertz +Hertzog +hesitant +hesitate +hesitater +Hesperus +Hess +Hesse +Hessian +Hester +heterocyclic +heterodyne +heterogamous +heterogeneity +heterogeneous +heterosexual +heterostructure +heterozygous +Hetman +Hettie +Hetty +Heublein +heuristic +Heusen +Heuser +hew +Hewett +Hewitt +Hewlett +hewn +hex +hexachloride +hexadecimal +hexafluoride +hexagon +hexagonal +hexameter +hexane +hey +heyday +hi +Hiatt +hiatus +Hiawatha +hibachi +Hibbard +hibernate +Hibernia +hick +Hickey +Hickman +hickory +Hicks +hid +hidalgo +hidden +hide +hideaway +hideous +hideout +hierarchal +hierarchic +hierarchy +hieratic +hieroglyphic +Hieronymus +hifalutin +Higgins +high +highball +highboy +highest +highfalutin +highhanded +highland +highlight +highroad +hightail +highway +highwayman +highwaymen +hijack +hijinks +hike +hilarious +hilarity +Hilbert +Hildebrand +hill +hillbilly +Hillcrest +Hillel +hillman +hillmen +hillock +hillside +hilltop +hilly +hilt +Hilton +hilum +him +Himalaya +himself +hind +hindmost +hindrance +hindsight +Hindu +Hinduism +Hines +hinge +Hinman +hint +hinterland +hip +hippo +Hippocrates +Hippocratic +hippodrome +hippopotamus +hippy +hipster +Hiram +hire +hireling +Hiroshi +Hiroshima +Hirsch +hirsute +his +Hispanic +hiss +histamine +histidine +histochemic +histochemistry +histogram +histology +historian +historic +historiography +history +histrionic +hit +Hitachi +hitch +Hitchcock +hither +hitherto +Hitler +hive +ho +hoagie +Hoagland +hoagy +hoar +hoard +hoarfrost +hoarse +hob +Hobart +Hobbes +hobble +Hobbs +hobby +.P +hobbyhorse +hobgoblin +hobo +Hoboken +hoc +hock +hockey +hocus +hodge +hodgepodge +Hodges +Hodgkin +hoe +Hoff +Hoffman +hog +hogan +hogging +hoi +Hokan +Holbrook +Holcomb +hold +holden +holdout +holdover +holdup +hole +holeable +holiday +Holland +Hollandaise +holler +Hollerith +Hollingsworth +Hollister +hollow +Holloway +hollowware +holly +hollyhock +Hollywood +Holm +Holman +Holmdel +Holmes +holmium +holocaust +Holocene +hologram +holography +Holst +Holstein +holster +holt +Holyoke +holystone +.FC +.SG +.NS 7 +text text text +text text text +.NS 12 +Holyoke +holystone +.NS +holt +.NE diff --git a/contrib/mm/examples/ML b/contrib/mm/examples/ML new file mode 100644 index 0000000..3ca16ad --- /dev/null +++ b/contrib/mm/examples/ML @@ -0,0 +1,176 @@ +.\" -*- nroff -*- +.\" Copyright (C) 1989-2014 Free Software Foundation, Inc. +.\" +.\" Copying and distribution of this file, with or without modification, +.\" are permitted in any medium without royalty provided the copyright +.\" notice and this notice are preserved. +. +granary +grand +grandchild +grandchildren +granddaughter +grandeur +grandfather +grandiloquent +grandiose +grandma +grandmother +grandnephew +grandniece +grandpa +.ML MARK +.LI "LOCALMARK" +granola +grant +grantee +grantor +granular +granulate +granule +Granville +grape +grapefruit +grapevine +.LI +.DS +Where shall we put this. +Where shall we put this. +Where shall we put this. +.DE +.LI +granola +grant +grantee +grantor +granular +granulate +granule +Granville +grape +grapefruit +grapevine +.LI +.DS +Where shall we put this. +.DE +.LI +graphic +graphite +grapple +grasp +grass +grassland +grassy +.LI +grata +grate +grateful +grater +gratify +gratis +gratitude +gratuitous +.LI +gratuity +grave +gravel +.LE +.SP 3 +.ML $ 1c +.LI +graven +Graves +gravestone +graveyard +gravid +gravitate +gravy +gray +.LI +graybeard +grayish +Grayson +graywacke +graze +grease +greasy +great +greatcoat +.LI +greater +grebe +Grecian +Greece +greed +greedy +Greek +green +.LI +Greenbelt +Greenberg +Greenblatt +Greenbriar +Greene +greenery +.LE +.SP 3 +.ML X 1c 1 +.LI +Greenfield +greengrocer +grandson +grandstand +granite +granitic +granny +graph +.LI +grapheme +greenhouse +greenish +Greenland +Greensboro +granary +grand +grandchild +grandchildren +granddaughter +grandeur +grandfather +grandiloquent +grandiose +.LI +grandma +grandmother +grandnephew +grandniece +grandpa +grandparent +grandson +grandstand +granite +granitic +granny +.LI +granola +grant +grantee +grantor +granular +granulate +granule +Granville +grape +grapefruit +.LI +grapevine +graph +grapheme +graphic +graphite +grapple +grasp +grass +grassland +.LE diff --git a/contrib/mm/examples/MOVE b/contrib/mm/examples/MOVE new file mode 100644 index 0000000..d2a31e5 --- /dev/null +++ b/contrib/mm/examples/MOVE @@ -0,0 +1,182 @@ +.\" -*- nroff -*- +.\" Copyright (C) 1989-2014 Free Software Foundation, Inc. +.\" +.\" Copying and distribution of this file, with or without modification, +.\" are permitted in any medium without royalty provided the copyright +.\" notice and this notice are preserved. +. +.PH "'hej'hopp'i skogen'" +.PF "'livet'är'härligt'" +.OH "'ojämn'%'sida'" +.EH "'ojämn'%'sida'" +.OF "'ojämn'%'sida'" +.EF "'ojämn'%'sida'" +10th +1st +2nd +3rd +4th +5th +6th +7th +8th +9th +a +AAA +AAAS +Aarhus +Aaron +AAU +ABA +Ababa +aback +abacus +abalone +abandon +abase +abash +abate +abater +abbas +abbe +abbey +abbot +Abbott +abbreviate +abc +abdicate +abdomen +abdominal +abet +abetted +abetting +abeyance +abeyant +abhorred +abhorrent +abide +Abidjan +Abigail +abject +ablate +ablaze +able +ablution +Abner +.MOVE 50 20 +abnormal +Abo +aboard +abode +abolish +abolition +abominable +abominate +aboriginal +AAA +ABORIGINE +ABORNING +ABORT +ABOUND +ABOUT +ABOVE +ABOVEBOARD +ABOVEGROUND +abovementioned +abrade +Abraham +Abram +Abramson +abrasion +abrasive +abreact +abreast +BBB +ABRIDGE +ABRIDGMENT +ABROAD +abrogate +abrupt +abscess +abscissa +abscissae +absence +absent +absentee +absenteeism +absentia +absentminded +.MOVE 30 10 +absinthe +absolute +absolution +absolve +absorb +absorbent +absorption +absorptive +abstain +abstention +abstinent +abstract +abstracter +abstractor +CCC +ABSTRUSE +ABSURD +ABUILDING +ABUNDANT +ABUSABLE +ABUSE +ABUSIVE +ABUT +ABUTTED +ABUTTING +ABYSMAL +ABYSS +ABYSSINIA +AC +ACADEME +ACADEMIA +ACADEMIC +ACADEMICIAN +ACADEMY +ACADIA +ACANTHUS +ACAPULCO +ACCEDE +ACCELERATE +ACCELEROMETER +ACCENT +ACCENTUAL +ACCENTUATE +ACCEPT +ACCEPTANT +acceptor +access +.MOVE 62 0 20 +accessible +accession +accessory +accident +accidental +accipiter +acclaim +acclamation +acclimate +accolade +accommodate +accompaniment +accompanist +accompany +accomplice +accomplish +accord +accordant +DDD +ACCORDION +ACCOST +ACCOUNT +ACCOUNTANT +ACCRA +.PGFORM diff --git a/contrib/mm/examples/MUL b/contrib/mm/examples/MUL new file mode 100644 index 0000000..bd8cf22 --- /dev/null +++ b/contrib/mm/examples/MUL @@ -0,0 +1,542 @@ +.\" -*- nroff -*- +.\" Copyright (C) 1989-2014 Free Software Foundation, Inc. +.\" +.\" Copying and distribution of this file, with or without modification, +.\" are permitted in any medium without royalty provided the copyright +.\" notice and this notice are preserved. +. +inject +injudicious +Injun +injunct +injunction +injure +injurious +injury +injustice +ink +inkling +inlaid +inland +inlay +inlet +Inman +inmate +inn +innards +innate +inner +innermost +innkeeper +innocent +innocuous +innovate +innuendo +innumerable +inoculate +inoffensive +inoperable +inoperative +inopportune +inordinate +inorganic +input +inputting +inquest +inquire +inquiry +inquisition +inquisitive +inquisitor +inroad +insane +insatiable +inscribe +inscription +inscrutable +insect +insecticide +insecure +inseminate +insensible +insensitive +inseparable +insert +inset +inshore +inside +insidious +insight +insightful +insignia +insignificant +insincere +insinuate +insipid +insist +insistent +insofar +insolent +insoluble +insolvable +insolvent +insomnia +insomniac +insouciant +inspect +inspector +inspiration +inspire +instable +install +installation +instalment +instance +instant +instantaneous +instantiate +instead +instep +instigate +instill +instillation +instinct +instinctual +institute +institution +instruct +instructor +instrument +instrumentation +insubordinate +insubstantial +insufferable +insufficient +insular +insulate +insulin +insult +insuperable +insupportable +insuppressible +insurance +insure +insurgent +insurmountable +insurrect +insurrection +intact +intake +intangible +integer +integrable +.MULB 4c 1 5c 1 4c 1 3c +Grenoble +Gresham +Greta +Gretchen +grew +grieve +grievous +griffin +Griffith +grill +grille +grilled +grillwork +grim +grimace +Grimaldi +grime +Grimes +Grimm +grin +grind +grindstone +grip +gripe +grippe +grisly +grist +gristmill +Griswold +grit +gritty +grizzle +grizzly +groan +groat +grocer +grocery +groggy +groin +grommet +groom +groove +grope +grosbeak +gross +.MULN +h +ha +Haag +Haas +habeas +haberdashery +Haberman +Habib +habit +habitant +habitat +habitation +habitual +habituate +hacienda +hack +hackberry +Hackett +hackle +hackmatack +hackney +hackneyed +hacksaw +had +Hadamard +Haddad +haddock +Hades +Hadley +hadn't +Hadrian +hadron +hafnium +Hagen +Hager +haggard +haggle +Hagstrom +Hague +Hahn +Haifa +haiku +hail +hailstone +hailstorm +Haines +hair +haircut +hairdo +hairpin +hairy +Haiti +Haitian +Hal +halcyon +hale +Haley +half +halfback +halfhearted +halfway +halibut +halide +Halifax +halite +hall +hallelujah +Halley +hallmark +hallow +Halloween +hallucinate +hallway +halma +halo +halocarbon +halogen +Halpern +Halsey +Halstead +halt +halvah +halve +Halverson +ham +Hamal +Hamburg +hamburger +Hamilton +hamlet +Hamlin +hammerhead +hammock +Hammond +hamper +Hampshire +Hampton +hamster +Han +Hancock +hand +handbag +handbook +handclasp +handcuff +.MULN +coliform +coliseum +collaborate +collage +collagen +collapse +collapsible +collar +collarbone +collard +collate +collateral +colleague +collect +collectible +collector +college +collegial +collegian +collegiate +collet +collide +collie +Collier +collimate +collinear +Collins +collision +collocation +colloidal +Colloq +colloquia +colloquial +colloquium +colloquy +command +commandant +commandeer +commando +commemorate +commend +commendation +commendatory +commensurable +commensurate +comment +commentary +commentator +commerce +commercial +commingle +commiserate +commissariat +commissary +commission +commit +committable +committal +committed +committee +committeeman +committeemen +committeewoman +committeewomen +committing +commodious +commodity +commodore +common +commonality +.MULN +locoweed +lunch +luncheon +lunchroom +lunchtime +Lund +Lundberg +Lundquist +lung +lunge +lupine +Lura +lurch +lure +lurid +lurk +Lusaka +luscious +lush +lust +lustful +lustrous +lusty +lutanist +lute +lutetium +Luther +Lutheran +Lutz +lymphocyte +lymphoma +lynch +Lynchburg +Lynn +lynx +Lyon +Lyons +Lyra +lyric +lyricism +Lysenko +lysergic +lysine +.MULE +m +ma +Mabel +Mac +macabre +macaque +MacArthur +Macassar +Macbeth +MacDonald +MacDougall +mace +Macedon +Macedonia +MacGregor +Mach +Machiavelli +machination +machine +machinelike +machinery +machismo +macho +macintosh +mack +MacKenzie +mackerel +Mackey +Mackinac +Mackinaw +mackintosh +MacMillan +Macon +macrame +macro +macromolecular +macromolecule +macrophage +macroprocessor +macroscopic +macrostructure +mad +Madagascar +madam +Madame +madcap +madden +Maddox +made +Madeira +Madeleine +Madeline +madhouse +Madison +madman +madmen +Madonna +Madras +Madrid +madrigal +Madsen +madstone +Mae +Maelstrom +maestro +Mafia +magazine +Magdalene +magenta +Maggie +maggot +maggoty +magi +magic +magician +magisterial +magistrate +magma +magna +magnanimity +magnanimous +magnate +magnesia +magnesite +magnesium +magnet +magnetic +magnetite +magneto +magnetron +magnificent +magnify +magnitude +magnolia +magnum +Magnuson +Magog +magpie +Magruder +Mahayana +Mahayanist +mahogany +Mahoney +maid +maiden +maidenhair +maidservant +Maier +mail +mailbox +mailman +mailmen +maim +main +Maine +mainland +mainline +mainstay +mainstream +maintain +maintenance +maitre +majestic +majesty +major +make +makeshift +makeup +Malabar +maladapt +maladaptive +maladjust +maladroit +malady +Malagasy +malaise +malaprop +malaria +malarial +Malawi +Malay +Malaysia diff --git a/contrib/mm/examples/NCOL b/contrib/mm/examples/NCOL new file mode 100644 index 0000000..8a5e001 --- /dev/null +++ b/contrib/mm/examples/NCOL @@ -0,0 +1,203 @@ +.\" -*- nroff -*- +.\" Copyright (C) 1989-2014 Free Software Foundation, Inc. +.\" +.\" Copying and distribution of this file, with or without modification, +.\" are permitted in any medium without royalty provided the copyright +.\" notice and this notice are preserved. +. +granary +grand +grandchild +grandchildren +granddaughter +grandeur +grandfather +grandiloquent +grandiose +grandma +grandmother +grandnephew +grandniece +grandpa +grandparent +grandson +grandstand +granite +granitic +granny +granola +grant +grantee +grantor +granular +granulate +granule +Granville +grape +grapefruit +grapevine +graph +grapheme +graphic +graphite +grapple +grasp +grass +grassland +grassy +.MC 3c +grata +grate +grateful +grater +gratify +gratis +gratitude +gratuitous +gratuity +grave +gravel +graven +Graves +gravestone +graveyard +gravid +gravitate +gravy +gray +graybeard +grayish +Grayson +graywacke +graze +grease +greasy +great +greatcoat +greater +grebe +Grecian +Greece +greed +greedy +.NCOL +Greek +green +Greenbelt +Greenberg +Greenblatt +Greenbriar +Greene +greenery +Greenfield +greengrocer +greenhouse +greenish +Greenland +Greensboro +greensward +greenware +Greenwich +greenwood +Greer +greet +Greg +gregarious +Gregg +Gregory +gremlin +grenade +Grendel +Grenoble +Gresham +Greta +Gretchen +grew +grey +greyhound +greylag +grid +griddle +gridiron +grief +grievance +grieve +grievous +griffin +Griffith +grill +grille +grilled +grillwork +.NCOL +grim +grimace +Grimaldi +grime +Grimes +Grimm +grin +grind +grindstone +grip +gripe +grippe +grisly +grist +gristmill +Griswold +grit +gritty +grizzle +grizzly +groan +groat +grocer +grocery +groggy +groin +grommet +groom +groove +grope +grosbeak +gross +Grosset +Grossman +Grosvenor +grotesque +Groton +ground +groundsel +groundskeep +groundwork +group +groupoid +grout +grove +grovel +Grover +grow +growl +grown +grownup +growth +grub +grubby +grudge +gruesome +gruff +grumble +Grumman +grunt +gryphon +g's +GSA +GU +Guam +guanidine +guanine +guano +guarantee +guaranteeing +guarantor diff --git a/contrib/mm/examples/ND b/contrib/mm/examples/ND new file mode 100644 index 0000000..fdbc55d --- /dev/null +++ b/contrib/mm/examples/ND @@ -0,0 +1,24 @@ +.\" -*- nroff -*- +.\" Copyright (C) 1989-2014 Free Software Foundation, Inc. +.\" +.\" Copying and distribution of this file, with or without modification, +.\" are permitted in any medium without royalty provided the copyright +.\" notice and this notice are preserved. +. +.nf +---------------------------------------------------------------------- +.ce +Testing +---------------------------------------------------------------------- +Date = \*[DT] +.ISODATE +Date = \*[DT] +.ISODATE 0 + +.ND "13 August 1992" +Date = \*[DT] + +.ISODATE +.ND "14 August 1992" +Date = \*[DT] +---------------------------------------------------------------------- diff --git a/contrib/mm/examples/README b/contrib/mm/examples/README new file mode 100644 index 0000000..cb0956a --- /dev/null +++ b/contrib/mm/examples/README @@ -0,0 +1,40 @@ + -*- text -*- + Copyright (C) 1989-2020 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. + + +This directory contains examples of my enhancements to MM. + +APP The appendix macro. +B1B2 Box macro with text. +COVER My general cover macro, this example is using + ms.cov. +IND A general indexing method, see manual for INITI. +LT The letter macro. +LT.se A Swedish example with extra Swedish macros for + composing a letter conforming to Swedish standard style, + adjusted to left and right margins. +ML Marked list, an extended list type. +MOVE The MOVE macro, how to begin to print on an exact position. +MUL Enhanced multicolumn mode. +NCOL Start on next column. (Not for MUL*) +ND New date, with ISO date example. +References How to use references. +SETR General reference system, see manual for INITR. + + +Examples that I should have: + +PIC How to include postscript pictures, see manual for PIC. +VERBON Begin verbatim output. + + +And remember, check the manual for all string and number registers, +I've made sure that mm is useful in several languages; +all English output can be redefined. + +For Swedish localization, check the manual for groff_mse and the +macro files 'mse.tmac' and 'sv.tmac'. diff --git a/contrib/mm/examples/References b/contrib/mm/examples/References new file mode 100644 index 0000000..7b54471 --- /dev/null +++ b/contrib/mm/examples/References @@ -0,0 +1,982 @@ +.\" -*- nroff -*- +.\" Copyright (C) 1989-2014 Free Software Foundation, Inc. +.\" +.\" Copying and distribution of this file, with or without modification, +.\" are permitted in any medium without royalty provided the copyright +.\" notice and this notice are preserved. +. +.PH "'this'is'a header'" +.PF "'this'is'a footer'" +.OH "'odd'%'page'" +.EH "'even'%'page'" +.OF "'odd'%'page'" +.EF "'even'%'page'" +10th +1st +2nd +3rd +4th +5th +6th +7th +8th +9th +a +AAA +.B +AAAS +Aarhus +Aaron +.R +AAU +ABA +Ababa +aback +abacus +abalone +abandon +abase +.H 1 "hej hopp" +abash +abate +abater +abbas +abbe +abbey +abbot +Abbott +abbreviate +abc +abdicate +abdomen +abet +abetted +abetting +abeyance +abeyant +.H 2 "hej hopp" +abhorred +abhorrent +abide +Abidjan +Abigail +abject +ablate +ablaze +able +ablution +Abner +abnormal +.H 2 "hej hopp" +Abo +aboard +abode +abolish +.HU "hej hopp" +.B1 +abolition +abominable +abominate\*(Rf +aboriginal +.RS +AAA +ABORIGINE +ABORNING +ABORT +ABOUND +ABOUT +ABOVE +ABOVEBOARD +ABOVEGROUND +.RF +abovementioned +abrade +Abraham\*(Rf +Abram\*(Rf +Abramson\*(Rf +abrasion\*(Rf +abrasive\*(Rf +abreact\*(Rf +.B2 +abreast\*(Rf +.RS +BBB +ABRIDGE +ABRIDGMENT +ABROAD +.RF +abrogate +abrupt +abscess\*(Rf +abscissa\*(Rf +abscissae\*(Rf +absence\*(Rf +absent +absentee +absenteeism +absentia +.H 3 "hej hopp" +absentminded +absinthe +absolute +absolution +absolve +absorb +absorbent +absorption +absorptive +abstain +abstention +abstinent\*(Rf +abstract +abstracter +abstractor +.RS nisse +CCC +ABSTRUSE +ABSURD +ABUILDING +ABUNDANT +ABUSABLE +ABUSE +ABUSIVE +ABUT +ABUTTED +ABUTTING +ABYSMAL +ABYSS +ABYSSINIA +AC +ACADEME +ACADEMIA +ACADEMIC +ACADEMICIAN +ACADEMY +ACADIA +ACANTHUS +ACAPULCO +ACCEDE +ACCELERATE +ACCELEROMETER +ACCENT +ACCENTUAL +ACCENTUATE +ACCEPT +ACCEPTANT +.RF +acceptor +access +accessible +accession +Ref \*[nisse] +accessory +.H 4 "hej hopp" +accident +accidental +accipiter +acclaim +acclamation +acclimate +accolade +accommodate +accompaniment +accompanist +accompany +accomplice +accomplish\*(Rf +accord +accordant +.RS +DDD +ACCORDION +ACCOST +ACCOUNT +ACCOUNTANT +ACCRA +ACCREDIT +ACCREDITATE +ACCREDITATION +ACCRETION +ACCRUAL +ACCRUE +.RF +acculturate +accumulate +accuracy +accurate +accusation +accusative +accusatory +accuse +accustom +ace +acerbic +acerbity +acetate +acetic +acetone +acetylene +ache +achieve +Achilles +aching +achromatic +acid +acidic +acidulous +.H 5 "hej hopp" +Ackerman +Ackley +acknowledge +acknowledgeable +ACM +acme +acolyte +acorn +acoustic +acquaint +acquaintance +acquiesce +acquiescent +acquire +acquisition +acquisitive +acquit +acquittal +acquitting +acre +acreage +acrid +acrimonious +acrimony +acrobacy +acrobat +acrobatic +acronym +acropolis +across +acrylate +acrylic +ACS +act +Actaeon +actinic +actinide +actinium +actinolite +actinometer +activate +activation +activism +Acton +actor +actress +Acts +actual +actuarial +actuate +.H 6 "hej hopp" +acuity +acumen +acute +acyclic +ad +Ada +adage +adagio +Adair +Adam +adamant +Adams +Adamson +adapt +adaptation +adaptive +add +added +addend +addenda +addendum +addict +Addis +Addison +addition +additional +additive +addle +address +addressee +Addressograph +adduce +Adelaide +Adele +Adelia +Aden +adenine +adenoma +adenosine +adept +adequacy +adequate +adhere +adherent +adhesion +adhesive +adiabatic +adieu +adipic +Adirondack +.H 7 "hej hopp" +adjacent +adject +adjectival +adjective +adjoin +adjoint +adjourn +adjudge +adjudicate +adjunct +adjust +adjutant +Adkins +Adler +administer +administrable +administrate +administratrix +admiral +admiralty +admiration +admire +admissible +admission +admit +admittance +admitted +admitting +admix +admixture +admonish +admonition +ado +adobe +adolescent +Adolph +Adolphus +Adonis +adopt +adoption +adoptive +adore +adorn +adposition +adrenal +adrenaline +Adrian +Adriatic +Adrienne +adrift +adroit +adsorb +adsorbate +adsorption +adsorptive +adulate +adult +adulterate +adulterous +adultery +adulthood +advance +advantage +advantageous +advent +adventitious +adventure +adventurous +adverb +adverbial +adversary +adverse +advert +advertise +advice +advisable +advise +advisee +advisor +advisory +advocacy +advocate +Aegean +aegis +Aeneas +Aeneid +aeolian +Aeolus +aerate +aerial +Aerobacter +aerobic +aerodynamic +aerogene +aeronautic +aerosol +aerospace +Aeschylus +aesthete +aesthetic +10th +1st +2nd +3rd +4th +5th +6th +7th +8th +9th +a +AAA +AAAS +Aarhus +Aaron +AAU +ABA +Ababa +aback +abacus +abalone +abandon +abase +.H 1 "hej hopp" +abash +abate +abater +abbas +abbe +abbey +abbot +Abbott +abbreviate +abc +abdicate +abdomen +abdominal +abduct +Abe +abed +Abel +Abelian +Abelson +Aberdeen +Abernathy +aberrant +aberrate +abet +abetted +abetting +abeyance +abeyant +.H 2 "hej hopp" +abhorred +abhorrent +abide +Abidjan +Abigail +abject +ablate +ablaze +able +ablution +Abner +abnormal +Abo +aboard +abode +abolish +abolition +abominable +abominate +aboriginal +aborigine +aborning +abort +abound +about +above +aboveboard +aboveground +abovementioned +abrade +Abraham +Abram +Abramson +abrasion +abrasive +abreact +abreast +abridge +abridgment +abroad +abrogate +abrupt +abscess +abscissa +abscissae +absence +absent +absentee +absenteeism +absentia +.H 3 "hej hopp" +absentminded +absinthe +absolute +absolution +absolve +absorb +absorbent +absorption +absorptive +abstain +abstention +abstinent +abstract +abstracter +abstractor +abstruse +absurd +abuilding +abundant +abusable +abuse +abusive +abut +abutted +abutting +abysmal +abyss +Abyssinia +AC +academe +academia +academic +academician +academy +Acadia +acanthus +Acapulco +accede +accelerate +accelerometer +accent +accentual +accentuate +accept +acceptant +acceptor +access +accessible +accession +accessory +.H 4 "hej hopp" +accident +accidental +accipiter +acclaim +acclamation +acclimate +accolade +accommodate +accompaniment +accompanist +accompany +accomplice +accomplish +accord +accordant +accordion +accost +account +accountant +Accra +accredit +accreditate +accreditation +accretion +accrual +accrue +acculturate +accumulate +accuracy +accurate +accusation +accusative +accusatory +accuse +accustom +ace +acerbic +acerbity +acetate +acetic +acetone +acetylene +ache +achieve +Achilles +aching +achromatic +acid +acidic +acidulous +.H 5 "hej hopp" +Ackerman +Ackley +acknowledge +acknowledgeable +ACM +acme +acolyte +acorn +acoustic +acquaint +acquaintance +acquiesce +acquiescent +acquire +acquisition +acquisitive +acquit +acquittal +acquitting +acre +acreage +acrid +acrimonious +acrimony +acrobacy +acrobat +acrobatic +acronym +acropolis +across +acrylate +acrylic +ACS +act +Actaeon +actinic +actinide +actinium +actinolite +actinometer +activate +activation +activism +Acton +actor +actress +Acts +actual +actuarial +actuate +.H 6 "hej hopp" +acuity +acumen +acute +acyclic +ad +Ada +adage +adagio +Adair +Adam +adamant +Adams +Adamson +adapt +adaptation +adaptive +add +added +addend +addenda +addendum +addict +Addis +Addison +addition +additional +additive +addle +address +addressee +Addressograph +adduce +Adelaide +Adele +Adelia +Aden +adenine +adenoma +adenosine +adept +adequacy +adequate +adhere +adherent +adhesion +adhesive +adiabatic +adieu +adipic +Adirondack +.H 7 "hej hopp" +adjacent +adject +adjectival +adjective +adjoin +adjoint +adjourn +adjudge +adjudicate +adjunct +adjust +adjutant +Adkins +Adler +administer +administrable +administrate +administratrix +admiral +admiralty +admiration +admire +admissible +admission +admit +admittance +admitted +admitting +admix +admixture +admonish +admonition +ado +adobe +adolescent +Adolph +Adolphus +Adonis +adopt +adoption +adoptive +adore +adorn +adposition +adrenal +adrenaline +Adrian +Adriatic +Adrienne +adrift +adroit +adsorb +adsorbate +adsorption +adsorptive +adulate +adult +adulterate +adulterous +adultery +adulthood +advance +advantage +advantageous +advent +adventitious +adverse +advert +advertise +advice +advisable +advise +advisee +advisor +advisory +advocacy +advocate +Aegean +aegis +Aeneas +Aeneid +aeolian +Aeolus +aerate +aerial +Aerobacter +aerobic +aerodynamic +aerogene +aeronautic +aerosol +aerospace +Aeschylus +aesthete +aesthetic +.H 1 "hej hopp" +acuity +acumen +acute +acyclic +ad +Ada +adage +adagio +Adair +Adam +adamant +Adams +Adamson +adapt +adaptation +adaptive +add +added +addend +addenda +addendum +addict +Addis +Addison +addition +additional +additive +addle +address +addressee +Addressograph +adduce +Adelaide +Adele +Adelia +Aden +adenine +adenoma +adenosine +adept +adequacy +adequate +adhere +adherent +adhesion +adhesive +adiabatic +adieu +adipic +Adirondack +.H 2 "hej hopp" +adjacent +adject +adjectival +adjective +adjoin +adjoint +adjourn +adjudge +adjudicate +.H 2 "hej hopp" +adjunct +adjust +adjutant +Adkins +Adler +administer +administrable +administrate +administratrix +admiral +admiralty +admiration +admire +admissible +admission +admit +admittance +admitted +admitting +admix +admixture +admonish +admonition +ado +adobe +adolescent +Adolph +Adolphus +Adonis +adopt +adoption +adoptive +adore +adorn +adposition +adrenal +adrenaline +Adrian +Adriatic +Adrienne +adrift +adroit +adsorb +adsorbate +adsorption +adsorptive +adulate +adult +adulterate +adulterous +adultery +adulthood +advance +advantage +advantageous +advent +adventitious +adverse +advert +advertise +advice +advisable +advise +advisee +advisor +advisory +advocacy +advocate +Aegean +aegis +Aeneas +Aeneid +aeolian +Aeolus +aerate +aerial +Aerobacter +aerobic +aerodynamic +aerogene +aeronautic +aerosol +aerospace +Aeschylus +aesthete +aesthetic +.RP 0 1 +.TC diff --git a/contrib/mm/examples/SETR b/contrib/mm/examples/SETR new file mode 100644 index 0000000..e2fcbd5 --- /dev/null +++ b/contrib/mm/examples/SETR @@ -0,0 +1,116 @@ +.\" -*- nroff -*- +.\" Copyright (C) 1989-2014 Free Software Foundation, Inc. +.\" +.\" Copying and distribution of this file, with or without modification, +.\" are permitted in any medium without royalty provided the copyright +.\" notice and this notice are preserved. +. +.nr Cl 6 +.INITR setr +.H 1 " granary grand grandchild grandchildren granddaughter grandeur" +.SETR ref1 +.H 2 "grandfather grandiloquent grandiose grandma grandmother grandnephew" +.H 2 "grandniece grandpa grandparent grandson grandstand granite granitic" +.H 2 "granny granola grant grantee grantor granular granulate" +.SETR ref2 +.H 2 "granule Granville grape" +grant +grantee +grantor +granular +granulate +.br +granule +.B +REF 9: +.GETHN ref9 +, page number +.GETPN ref9 +.R +Granville +grape +.br +grapefruit +grapevine +graph +grapheme +graphic +graphite +\fBExhibit\fP +.GETHN ex1 + +grapple +grasp +grass +grassland +grassy +grata +grate +.H 2 "grapefruit grapevine graph grapheme graphic graphite" +.H 3 "grapple" +.SETR ref3 +.H 3 "grasp grass grassland grassy grata grate grateful" +.H 3 "grater gratify gratis gratitude" +.H 4 "gratuitous gratuity grave" +.H 4 "gravel graven" +.SETR ref4 +.H 1 "Graves gravestone graveyard gravid gravitate gravy gray" +.H 2 "graybeard grayish Grayson graywacke graze grease greasy great greatcoat" +.H 2 "greater grebe Grecian Greece greed greedy Greek green Greenbelt Greenberg" +.H 2 "Greenblatt Greenbriar Greene greenery" +.SETR ref5 +.H 1 "Greenfield greengrocer greenhouse greenish Greenland Greensboro" +.H 1 "greensward greenware Greenwich greenwood Greer greet" +grant +grantee +.DS + +Advertisements contain the only truths to be relied on in a newspaper. + -- Thomas Jefferson +.EX fortune "" "" ex1 +.DE +grantor +granular +.GETR ref1 +granulate +granule +.H 2 "Using variables" +.B +REF 2: +.GETHN ref2 c +.GETPN ref2 bbb +\*c, page number \*[bbb] +.R +Granville +grape +grapefruit +grapevine +graph +grapheme +.H 2 "Greg gregarious Gregg Gregory gremlin grenade Grendel" +.H 2 "Grenoble Gresham Greta Gretchen" +.SETR ref6 +.H 2 "grew" +.H 1 "grey greyhound greylag grid griddle gridiron grief" +.H 1 "grievance grieve grievous griffin Griffith grill grille grilled grillwork" +.H 3 "grim grimace Grimaldi grime Grimes Grimm grin grind grindstone" +.H 3 "grip gripe grippe grisly grist gristmill Griswold grit" +.SETR ref7 +.H 3 "gritty grizzle grizzly groan groat grocer grocery groggy groin" +.H 1 "grommet groom groove grope grosbeak gross Grosset Grossman Grosvenor grotesque" +.H 1 "Groton ground groundsel groundskeep groundwork group groupoid" +.H 4 "grout grove grovel Grover grow growl grown grownup growth grub grubby" +.H 4 "grudge gruesome gruff grumble Grumman grunt gryphon g's" +.SETR ref8 +.H 4 "GSA GU Guam guanidine guanine guano guarantee guaranteeing guarantor" +.H 4 "guaranty" +.H 1 "guard guardhouse Guardia guardian Guatemala gubernatorial Guelph Guenther" +.H 1 "guerdon guernsey guerrilla guess guesswork guest guffaw Guggenheim" +.SETR ref9 +.H 1 "Guiana guidance guide guidebook guideline guidepost guiding" +.H 1 "guignol" +.GETR ref6 +.H 1 "guild guildhall guile Guilford guillemot guillotine guilt" +.SETR ref10 +.H 1 "guilty guinea guise guitar gules gulf gull Gullah" +.H 1 "gullet gullible gully gulp gum gumbo gumdrop gummy gumption" diff --git a/contrib/mm/examples/letter.mm b/contrib/mm/examples/letter.mm new file mode 100644 index 0000000..3683849 --- /dev/null +++ b/contrib/mm/examples/letter.mm @@ -0,0 +1,51 @@ +.\" Set a blank page header; our letter is a single page and does not +.\" require the default numbering. +.PH ''' +.\" Set point size to 14. +.S 14 +.\" Set paragraph type to "indented". +.nr Pt 1 +.\" Put the date in a right-aligned display. +.DS R +30 May 2021 +.DE +.\" Start display (left-aligned). +.DS +Mr. Ty Coon +President of Vice, Intellectual Property and Licensing +Very Big Corporation of America +Silly Valley, CA 94043 +.\" End display. +.DE +Dear Mr. Coon, +. +. +.\" Start new paragraph. +.P +I would like to request that your wholly-owned subsidiary, +Yoyodyne, Inc., +disclaim all copyright interest in the program `Gnomovision' +(which makes passes at compilers) +written by Juliet Hacker prior to her employment with Yoyodyne. +. +. +.P +Our colleagues at the Software Freedom Conservancy have determined and +informed us that Ms.\& Hacker's employment agreement is a contract of +adhesion. +. +. +.P +Thank you for your prompt attention to this matter. +. +. +.\" Put the closing and signature in a right-aligned display as well. +.DS R +Sincerely yours, +.\" Leave three "vees" (3 text line heights) of room for signature. +.SP 3v +. +. +Tracy T.\& Jordan +.DE +.\" vim: set noexpandtab textwidth=72: diff --git a/contrib/mm/groff_mm.7.man b/contrib/mm/groff_mm.7.man new file mode 100644 index 0000000..4f94191 --- /dev/null +++ b/contrib/mm/groff_mm.7.man @@ -0,0 +1,5428 @@ +'\" t +.TH groff_mm @MAN7EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +groff_mm \- memorandum macros for GNU +.I roff +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1989-2023 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_groff_mm_7_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY "groff \-m@TMAC_M_PREFIX@m" +.RI [ option\~ .\|.\|.\&] +.RI [ file\~ .\|.\|.] +. +.SY "groff \-m m@TMAC_M_PREFIX@m" +.RI [ option\~ .\|.\|.\&] +.RI [ file\~ .\|.\|.] +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +The GNU implementation of the +.I mm +macro package is part of the +.I groff +document formatting system. +. +The +.I mm +package is suitable for the composition of +letters, +memoranda, +reports, +and books. +. +. +.P +Call an +.I mm +macro at the beginning of a document to initialize the package. +. +A simple +.I mm +document might use only +.B P +for paragraphing. +. +Set numbered and unnumbered section headings with +.B H +and +.BR HU , +respectively. +. +Change the style of the typeface with +.BR B , +.BR I , +and +.BR R ; +you can alternate styles with +.BR BI , +.BR BR , +.BR IB , +.BR IR , +.BR RB , +and +.BR RI . +. +Several nestable list types are available via +.BR AL , +.BR BL , +.BR BVL , +.BR DL , +.BR ML , +.BR RL , +and +.BR VL ; +each of these begins a list, +to which +.B LI +adds an item and +.B LE +ends the (nested) list. +. +Customized list arrangements are supported by +.BR LB . +. +.B DS +and +.B DF +start static and floating displays, +respectively; +either is terminated with +.BR DE . +. +. +.P +.I groff mm +is intended to be compatible with the +.I mm +implementation found in the AT&T Documenter's Workbench (DWB), +with the following limitations. +. +. +.IP \[bu] 2n +Omitted features include +the logo and company name strings, +.B }Z +and +.BR ]S , +respectively; +the encoded company site location addresses recognized as the third +argument to the +.B AU +macro; +the +.B Pv +(\[lq]private\[rq] heading) +register; +and the +.B OK +(other keywords), +and +.B PM +(proprietary markings) +macros. +. +. +.IP \[bu] 2n +The +.B CS +(output cover sheet) +macro is implemented only for memorandum type 4. +. +. +.IP \[bu] +The +.I grap +preprocessor is not explicitly supported; +no +.B G1 +and +.B G2 +macros +are defined. +. +. +.IP \[bu] +The registers +.BR A , +.BR C , +.BR E , +.BR T , +and +.BR U , +typically set from the +.I troff \" generic +or +.I nroff \" generic +command lines with DWB +.IR mm , +are not recognized. +. +. +.IP \[bu] +When setting the registers +.B L +or +.B W +from the command line, +use an explicit scaling unit to avoid surprises. +. +. +.IP \[bu] +DWB +.IR mm 's +.B nP +macro indented the second line of a paragraph to align it with the start +of the text of the first +(after the paragraph number); +.IR "groff mm" 's +does not. +. +. +.IP \[bu] +Cut marks are not supported. +. +. +.P +DWB +.I mm +supported only seven levels of heading. +. +As a compatible extension, +.I groff mm +supports fourteen, +introducing new registers +.B H8 +through +.BR H14 , +and affecting the interpretation of the +.B HF +and +.B HP +strings. +. +. +.P +Macro, +register, +and string descriptions in this page frequently mention each other; +most cross references are to macros. +. +Where a register or string is referenced, +its type is explicitly identified. +. +.IR mm 's +macro names are usually in full capitals; +registers and strings tend to have mixed-case names. +. +. +.\" ==================================================================== +.SS "Document styles" +.\" ==================================================================== +. +.I groff mm +offers three different frameworks for document organization. +. +.BR \%COVER /\: \%COVEND +is a flexible means of preparing any document requiring a cover page. +. +.BR LT / LO +aids preparation of typical Anglophone correspondence +(business letters, +for example). +. +The +.B MT +memorandum type mechanism implements a group of formal styles +historically used by AT&T Bell Laboratories. +. +Your document can select at most one of these approaches; +when used, +each disables the others. +. +. +.\" ==================================================================== +.SS Localization +.\" ==================================================================== +. +.I groff mm +is designed to be easily localized. +. +For languages other than English, +strings that can appear in output are collected in the file +.IR @MACRODIR@/\: xx \:.tmac , +where +.I xx +is an ISO\~639 two-letter language identifier. +. +Localization packages should be loaded after +.IR mm ; +for example, +you might format a Swedish +.I mm +document with the command +.RB \[lq] "groff \-mm \-msv" \[rq]. +. +. +.P +This package can also be localized by site or territory; +for example, +.I @MACRODIR@/\:@TMAC_M_PREFIX@mse\:.tmac +illustrates how to adapt the output to a national standard using its ISO +3166 territory code. +. +Such a package can define a string that causes a macro file +.IR @MACRODIR@/\:mm/\:\% territory _locale +to be loaded at package initialization. +. +If this mechanism is not used, +.I @MACRODIR@/\:mm/\:\%locale +is loaded instead. +. +No diagnostic is produced if these files do not exist. +. +. +.\" ==================================================================== +.SS "Registers and strings" +.\" ==================================================================== +. +Much +.I mm +behavior can be configured by registers and strings. +. +A register is assigned with the +.B nr +request. +. +. +.RS +.P +.B .nr +.I ident +.RB [ \[+-] ]\c +.I n +.RI [ i ] +.RE +. +. +.P +.I ident +is the name of the register, +and +.IR n \~is +the value to be assigned. +. +.IR n \~can +be prefixed with a plus or minus sign if incrementation or +decrementation (respectively) of the register's existing value +.RI by\~ n +is desired. +. +If assignment of a (possibly) negative +.IR n \~is +required, +further prefix it with a zero or enclose it in parentheses. +. +If +.IR i \~is +specified, +the register is automatically modified +.RI by \~i +prior to interpolation if a plus or minus sign is included in the escape +sequence as follows. +. +. +.RS +.P +.B \[rs]n\c +.RB [ \[+-] ]\c +.BI [ ident ] +.RE +. +. +.P +.IR i \~can +be negative; +it combines algebraically with the sign in the interpolation escape +sequence. +. +. +.P +Strings are defined with the +.B ds +request. +. +. +.RS +.P +.B .ds +.I ident contents +.RE +. +. +.P +.I contents +consumes everything up to the end of the line, +including trailing spaces. +. +It is a good practice to end +.I contents +with a comment escape sequence +.RB ( \[rs]\[dq] ) +so that extraneous spaces do not intrude during document maintenance. +. +To include leading spaces in +.IR contents , +prefix it with a double quote. +. +Strings are interpolated with the +.B \[rs]* +escape sequence. +. +. +.RS +.P +.B \[rs]*\c +.BI [ ident ] +.RE +. +. +.P +Register and string name spaces are distinct, +but strings and macros share a name space. +. +Defining a string with the same name as an +.I mm +macro is not supported and may cause incorrect rendering, +the emission of diagnostic messages, +and an error exit status from +.IR @g@troff . +. +. +.\" ==================================================================== +.SS "Register format" +.\" ==================================================================== +. +A register is interpolated using Arabic numerals if no other format has +been assigned to it. +. +Assign a format to a register with the +.B af +request. +. +. +.RS +.LP +.BI .af\~ "R c" +.RE +. +. +.LP +.IR R \~is +the name of the register, +and +.IR c \~is +the format. +. +If +.IR c \~is +a sequence of Arabic numerals, +their quantity defines a zero-padded minimum width for the interpolated +register value. +. +. +.RS +.LP +.TS +tab(@); +lb lb +l l. +Form@Sequence +1@0, 1, 2, 3, .\|.\|., 10, .\|.\|. +001@000, 001, 002, 003, .\|.\|., 1000, .\|.\|. +i@0, i, ii, iii, iv, .\|.\|. +I@0, I, II, III, IV, .\|.\|. +a@0, a, b, c, .\|.\|., z, aa, ab, .\|.\|. +A@0, A, B, C, .\|.\|., Z, AA, AB, .\|.\|. +.TE +.RE +. +. +.\" ==================================================================== +.SS Fonts +.\" ==================================================================== +. +In +.IR "groff mm" , +the fonts +(or rather, +font styles) +.BR R \~(roman), +.BR I \~(italic), +and +.BR B \~(bold) +are mounted at font positions +.BR 1 , +.BR 2 , +.RB and\~ 3 , +respectively. +. +Internally, +font positions are used for backward compatibility. +. +From a practical point of view, +it doesn't make a big difference\[em]a different font family can still +be selected by invoking +.IR groff 's +.B fam +request or using its +.B \-f +command-line option. +. +On the other hand, +if you want to replace just, +for example, +.RB font\~ I +with Zapf Chancery Medium italic +(available on +.IR groff 's +.B pdf +and +.B ps +output devices), +you have to use the +.B fp +request, +replacing the font at position\~2 with +.RB \[lq] .fp\~2\~ZCMI \[rq]). +. +Because the cover sheet, +memorandum type, +and +.MR @g@refer @MAN1EXT@ +integration macros explicitly request fonts named +.BR B , +.BR I , +and +.BR R , +you will also need to remap these font names with the +.B ftr +request, +for instance with +.RB \[lq] .ftr\~I\~ZCMI \[rq]. +. +. +.\" ==================================================================== +.SH Macros +.\" ==================================================================== +. +An explicitly empty argument may be specified with a pair of double +quotes; +to call a macro +.B XX +with an empty second argument but non-empty first and third ones, +you could input the following. +. +. +.P +.RS +.EX +\&.XX foo \[dq]\[dq] baz +.EE +.RE +. +. +.P +Macro names longer than two characters are GNU extensions; +some shorter names were not part of DWB +.IR mm 's +published interface but are documented aspects of +.I groff mm. +. +. +.TP +.BI )E\ "level text" +Add heading text +.I text +to the table of contents with +.IR level , +which is either\~0 or in the range 1 to\~7. +. +See also +.BR H . +. +This undocumented DWB +.I mm +macro is exposed by +.I groff mm +to enable customized tables of contents. +. +. +.TP +.BR 1C\~ [ 1 ] +Format page text in one column. +. +The page is broken. +. +.RB A\~ 1 +argument suppresses this break; +its use may cause body text and a pending footnote to overprint. +. +See +.BR 2C , +.BR MC , +and +.BR NCOL . +. +. +.TP +.B 2C +Begin two-column formatting. +. +This is a special case of +.BR MC . +. +See +.B 1C +and +.BR NCOL . +. +. +.TP +.B AE +Abstract end; +stop collecting abstract text. +. +See +.BR AS . +. +. +.\" In DWB mm, the mnemonic for `AF` was "alternate first-page format", +.\" and was described in the context of the `A` and `E` registers and +.\" `}Z` and `]S` strings, none of which we support. +.TP +.BR AF \~[\c +.IR firm-name ] +Specify firm associated with the document. +. +At most one can be declared; +the firm name is used by memorandum types and available to cover sheets. +. +.B AF +terminates a document title started with +.BR TL , +and can be called without an argument for that purpose. +. +See +.B MT +and +.BR COVER . +. +. +.TP +.BR AL \~[\c +.IR type \~[ text-indent \~[\c +.BR 1 ]]] +Begin an auto-incrementing numbered list. +. +Item numbers start at one. +. +The +.I type +argument assigns the register format +(see above) +of the list item enumerators. +. +The default +.RB is\~ 1 . +. +An explicitly empty +.I type +also indicates the default. +. +A +.I text-indent +argument overrides register +.BR Li . +. +A third argument suppresses the blank line that normally precedes each +list item. +. +Use +.B LI +to declare list items, +and +.B LE +to end the list. +. +. +.TP +.BR APP \~\c +.RI [ id\~ [ title ]] +Begin an appendix. +. +If the identifier +.I id +is omitted, +it is incremented +(or initialized, +if necessary). +. +The register format used for +.I id +is \[lq]A\[rq]. +. +The page is broken. +. +The register +.B Aph +determines whether an appendix heading is then formatted. +. +This heading uses the string +.B App +followed by +.IR id . +. +Appendices appear in any table of contents +(see +.BR TC ). +. +The string +.B Apptxt +is set to +.I title +if the latter is present, +and made empty otherwise. +. +. +.TP +.BI APPSK\~ "id n" \~\c +.RI [ title ] +As +.BR APP , +but increment the page number by +.IR n . +. +Use this macro to \[lq]skip pages\[rq] when diagrams or other materials +not formatted by +.I @g@troff +are included in appendices. +. +. +.TP +.BR AS\~ [\c +.IR placement \~[ indentation ]] +Abstract start; +begin collecting abstract. +. +Input up to the next +.B AE +call is included in the abstract. +. +.I placement +influences the location of the abstract on the cover sheet of a +memorandum +(see +.BR MT ). +. +.BR \%COVER , +by contrast, +ignores +.I placement +by default, +but can be customized to interpret it. +. +. +.IP +.TS +tab(@); +lf(BI) lb +l lx. +placement@Effect +0@T{ +The abstract appears on page\~1 and cover sheet if the document is a +\[lq]released paper\[rq] memorandum +.RB (\[lq] ".MT 4" \[rq]); +otherwise, +it appears on page\~1 without a cover sheet. +T} +1@T{ +The abstract appears only on the cover sheet +.RB (\[lq] ".MT 4" \[rq] +only). +T} +.\" XXX: This does not appear to be implemented. +.\"2@T{ +.\"The abstract is printed only on the cover sheet (if not +.\".BR ".MT 4" ) +.\". +.\"The cover sheet is printed without a need for \fBCS\fP. +.\"T} +.TE +. +. +.IP +An abstract does not appear at all in external letters +.RB (\[lq] ".MT 5" \[rq]). +. +.RI A\~ placement +of +.B 2 +was supported by DWB +.I mm +but is not by +.IR "groff mm" . +. +. +.IP +A second argument increases the indentation by +.I indentation +and reduces the line length by twice this amount. +. +A scaling unit of ens is assumed. +. +The default is\~0. +. +. +.\" XXX: Do we need a macro for this? Why is it not a string like App +.\" or Licon? It is usefully localizable. +.TP +.BR AST \~\c +.RI [ caption ] +Set the caption above the abstract to +.IR caption , +or clear it if there is no argument. +. +The default is \[lq]ABSTRACT\[rq]. +. +. +.TP +.BI AT\~ title\c +\~.\|.\|. +Specify author's title(s). +. +If present, +.B AT +must appear just after the corresponding author's +.BR AU . +. +Each +.I title +occupies an output line beneath the author's name in the signature block +used by +.B LT +letters +(see +.BR SG ) +and in +.B MT +memoranda. +. +The +.B ms +cover sheet style also uses it. +. +. +.br +.ne 7v +.TP +.BR AU \~\c +.RI [ name\~\c +.RI [ initials\~\c +.RI [ loc\~\c +.RI [ dept\~\c +.RI [ ext\~\c +.RI [ room\~\c +.RI [ arg1\~\c +.RI [ arg2\~\c +.RI [ arg3 ]]]]]]]]] +Specify author. +. +.B AU +terminates a document title started with +.BR TL , +and can be called without arguments for that purpose. +. +Author information is used by cover sheets, +.B MT +memoranda, +and +.BR SG . +. +Further arguments comprise +initials, +location, +department, +telephone extension, +room number or name, +and up to three additional items. +. +Repeat +.B AU +to identify multiple authors. +. +. +.IP +Use +.BR WA / WE +instead to identify the author for documents employing +.BR LT . +. +. +.TP +.BR AV \~[\c +.IR name \~[\c +.BR 1 ]] +Format approval lines for a handwritten signature and date. +. +Two horizontal rules are drawn, +with the specified +.I name +and the text of the string +.B Letdate +beneath them. +. +Above these rules, +the text in the string +.B Letapp +is formatted; +a second argument replaces this text with a blank line. +. +See +.BR LT . +. +. +.\" XXX: AVL is misnamed; it should have been called SGL or similar. +.TP +.BR AVL \~[\c +.IR name ] +As +.BR AV , +but the date, +date rule, +and approval notation +.B Letapp +are omitted. +. +. +.TP +.BR B \~\c \" space in roman; we must use 2-font macro with \c +.RI [ bold-text\~\c +.RI [ previous-font-text ]]\~.\|.\|. +Join +.I bold-text +in boldface with +.I previous-font-text +in the previous font, +without space between the arguments. +. +If no arguments, +switch font to bold style. +. +. +.TP +.B B1 +Begin boxed, +kept display. +. +The text is indented one character, +and the right margin is one character shorter. +. +This is a GNU extension. +. +. +.TP +.B B2 +End boxed, +kept display. +. +This is a GNU extension. +. +. +.TP +.B BE +End bottom block; see +.BR BS . +. +. +.TP +.BR BI \~\c \" space in roman; we must use 2-font macro with \c +.RI [ bold-text\~\c +.RI [ italic-text ]]\~.\|.\|. +Join +.I bold-text +in boldface with +.I italic-text +in italics, +without space between the arguments. +. +. +.TP +.BR BL \~[\c +.IR text-indent \~[\c +.BR 1 ]] +Begin bulleted list. +. +Items are prefixed with a bullet and a space. +. +A +.I text-indent +argument overrides register +.BR Pi . +. +A second argument suppresses blank lines between items. +. +Use +.B LI +to declare list items, +and +.B LE +to end the list. +. +. +.TP +.BR BR \~\c \" space in roman; we must use 2-font macro with \c +.RI [ bold-text\~\c +.RI [ roman-text ]]\~.\|.\|. +Join +.I bold-text +in boldface with +.I roman-text +in roman style, +without space between the arguments. +. +. +.TP +.B BS +Begin bottom block. +. +Input is collected until +.B BE +is called, +and output between the footnote area and footer of each page. +. +. +.\" XXX: Couldn't this have been done with an extra parameter to `VL`? +.\" Or a register influencing VL behavior? +.TP +.BR BVL \~[\c +.IR text-indent \~[ mark-indent \~[\c +.BR 1 ]]] +Begin broken variable-item +(or \[lq]tagged\[rq]) +list. +. +Each item is expected to supply its own mark. +. +The line is always broken after the mark; +contrast +.BR VL . +. +.I text-indent +sets the indentation of the text, +and +.I mark-indent +the distance from the current list indentation to the mark. +. +A third argument suppresses the blank line that normally precedes each +list item. +. +Use +.B LI +to declare list items, +and +.B LE +to end the list. +. +. +.TP +.BR \%COVER \~\c \" space in roman; we must use 2-font macro with \c +.RI [ style ] +Begin a cover page description. +. +.B \%COVER +must appear before the body text +(or main matter) +of a document. +. +The argument +.I style +is used to construct the file name +.IR @TMAC_MDIR@/\: style \:.cov +and load it with the +.B mso +request. +. +The default +.I style +is +.BR ms ; +the +.I ms.cov +file prepares a cover page resembling those of the +.I ms +package. +. +A +.I .cov +file must define a +.B \%COVEND +macro, +which a document must call at the end of the cover description. +. +Use cover description macros in the following order; +only +.B TL +and +.B AU +are required. +. +. +.IP +.EX +\&.COVER +\&.TL +\&.AF +\&.AU +\&.AT +\&.AS +.ne 2v +\&.AE +\&.COVEND +.EE +. +. +.TP +.B COVEND +End the cover description. +. +. +.TP +.B DE +End static or floating display begun with +.B DS +or +.BR DF . +. +. +.TP +.BR DF\~ [\c +.IR format \~[ fill \~[ right-indentation ]]] +Begin floating display. +. +A floating display is saved in a queue and output in the order entered. +. +Arguments are handled as in +.BR DS . +. +Floating displays cannot be nested. +. +Placement of floating displays is controlled by the registers +.B De +and +.BR Df . +. +. +.TP +.BR DL \~[\c +.IR text-indent \~[\c +.BR 1 ]] +Begin dashed list. +. +Items are prefixed with an em dash and a space. +. +A +.I text-indent +argument overrides register +.BR Pi . +. +A second argument suppresses blank lines between items. +. +Use +.B LI +to declare list items, +and +.B LE +to end the list. +. +. +.TP +.BR DS \~[\c +.IR format \~[\c +.IR fill \~[\c +.IR right-indentation ]]] +Begin static display. +. +Input until +.B DE +is called is collected into a display. +. +The display is output on a single page unless it is taller than the +height of the page. +. +.B DS +can be nested +(contrast with +.BR DF ). +. +. +.IP +.TS +tab(@); +Lf(BI) Lb +L Lx. +format@Effect +\f[I]none\f[]@Do not indent the display. +L@Do not indent the display. +I@T{ +Indent text by +.BR \[rs]n[Si] . +T} +C@Center each line. +CB@Center the whole display as a block. +R@Right-adjust the lines. +RB@Right-adjust the whole display as a block. +.TE +. +. +.IP +The values \[lq]L\[rq], +\[lq]I\[rq], +\[lq]C\[rq], +and \[lq]CB\[rq] can also be specified as \[lq]0\[rq], +\[lq]1\[rq], +\[lq]2\[rq], +and +\[lq]3\[rq], +respectively, +for compatibility with +.RI DWB\~ mm. +. +. +.IP +.TS +tab(@); +Lf(BI) Lb +L Lx. +fill@Effect +\f[I]none\f[]@Disable filling. +N@Disable filling. +F@Enable filling. +.TE +. +. +.IP +\[lq]N\[rq] and \[lq]F\[rq] can also be specified as \[lq]0\[rq] and +\[lq]1\[rq], +respectively, +for compatibility with +.RI DWB\~ mm. +. +. +.IP +A third argument +reduces the line length by +.I right-indentation. +. +. +.IP +.I mm +normally +places blank lines before and after the display. +. +Set register +.B Ds +to\~0 to suppress these. +. +. +.TP +.BR EC \~\c +.RI [ title \~[ override \~[ flag \~[ refname ]]]] +Caption an equation. +. +The caption consists of the string +.B Liec +followed by an automatically incrementing counter stored in the register +.BR Ec , +punctuation configured by the register +.BR Of , +then +.I title +(if any). +. +Use the +.B af +request to configure +.BR Ec 's +number format. +. +.I override +and +.I flag +alter the equation number as follows. +. +Omitting +.I flag +and specifying +.B 0 +in its place are equivalent. +. +. +.IP +.TS +tab(@); +Lf(BI) Lb +L Lx. +flag@Effect +0@T{ +Prefix number with +.IR override . +T} +1@T{ +Suffix number with +.IR override . +T} +2@T{ +Replace number with +.IR override . +T} +.TE +. +. +.IP +Equation captions are centered irrespective of the alignment of any +enclosing display. +. +. +.IP +.I refname +stores the equation number using +.BR SETR ; +it can be retreived with +.RB \[lq] .GETST +.IR refname \[rq]. +. +This argument is a GNU extension. +. +. +.IP +Captioned equations are listed in a table of contents +(see +.BR TC ) +if the Boolean register +.B Le +is true. +. +Such a list uses the string +.B Le +as a heading. +. +. +.TP +.BR EF\~ [ \[dq]\|\[aq]\c +.IB left \[aq] center \[aq] right \[aq]\|\[dq]\c +] +Define the even-page footer, +which is formatted just above the normal page footer on even-numbered +pages. +. +See +.BR PF . +. +.B EF +defines the string +.BR EOPef . +. +. +.TP +.BR EH\~ [ \[dq]\|\[aq]\c +.IB left \[aq] center \[aq] right \[aq]\|\[dq]\c +] +Define the even-page header, +which is formatted just below the normal page header on even-numbered +pages. +. +See +.BR PH . +. +.B EH +defines the string +.BR TPeh . +. +. +.TP +.B EN +End equation input preprocessed by +.MR @g@eqn @MAN1EXT@ ; +see +.BR EQ . +. +. +.TP +.B EOP +If defined, +this macro is called in lieu of normal page footer layout. +. +Headers and footers are formatted in a separate environment. +. +See +.BR TP . +. +. +.IP +.TS +tab(@); +Cb S +Lb L. +Strings available to EOP +_ +EOPf@argument to \fBPF\fP +EOPef@argument to \fBEF\fP +EOPof@argument to \fBOF\fP +.TE +. +. +.TP +.BI EPIC\ "\fR[\fP\fB\-L\fP\fR]\fP width height \fR[\fPname\fR]\fP" +Draw a box with the given +.I width +and +.IR height . +. +It also prints the text +.I name +or a default string if +.I name +is not specified. +. +This is used to include external pictures; +just give the size of the picture. +. +.B \-L +left-aligns the picture; +the default is to center. +. +See +.BR PIC . +. +. +.TP +.BR EQ \~[\c +.IR label ] +Start equation input preprocessed by +.MR @g@eqn @MAN1EXT@ . +. +.B EQ +and +.B EN +macro calls bracket an equation region. +. +Such regions must be contained in displays +.RB ( DS / DE ), +except when the region is used only to configure +.I @g@eqn +and not to produce output. +. +If present, +.I label +appears aligned to the right and +centered vertically within the display; +see register +.BR Eq . +. +. +If multiple +.I eqn \" generic +regions occur within a display, +only the last +.I label +(if any) +is used. +. +. +.TP +.BR EX \~\c +.RI [ title \~[ override \~[ flag \~[ refname ]]]] +Caption an exhibit. +. +Arguments are handled analogously to +.BR EC . +. +The register +.B Ex +is the exhibit counter. +. +The string +.B Liex +precedes the exhibit number and any +.I title. +. +Exhibit captions are centered irrespective of the alignment of any +enclosing display. +. +. +.IP +Captioned exhibits are listed in a table of contents +(see +.BR TC ) +if the Boolean register +.B Lx +is true. +. +Such a list uses the string +.B Lx +as a heading. +. +. +.TP +.BR FC \~[\c +.IR closing-text ] +Output the string +.BR Letfc , +or the specified +.I closing-text, +as the formal closing of a letter. +. +. +.TP +.BR FD \~[\c +.IR arg \~[\c +.BR 1 ]] +Configure display of footnotes. +. +The first argument encodes enablement of +automatic hyphenation, +adjustment to the right margin, +indentation of footnote text, +and left- vs.\& right-alignment of the footnote label within the space +allocated for it. +. +. +.br +.ne 5v +.IP +.\" XXX: We can fit one more row using "nokeep" vs. not using it. +.TS +tab(@) nokeep; +Lf(BI) Lb Lb Lb Lb +L L L L L. +arg@Hyphenate?@Adjust?@Indent?@Label alignment +0@no@yes@yes@left +1@yes@yes@yes@left +2@no@no@yes@left +3@yes@no@yes@left +4@no@yes@no@left +5@yes@yes@no@left +6@no@no@no@left +7@yes@no@no@left +8@no@yes@yes@right +9@yes@yes@yes@right +10@no@no@yes@right +11@yes@no@yes@right +.TE +. +. +.IP +An +.I arg +greater than 11 is treated +.RB as\~ 0 . +. +.IR mm 's +default +.RB is\~ 0 . +. +. +.IP +If a second argument, +conventionally +.BR 1 , +is given, +footnote numbering is reset when a first-level heading is encountered. +. +See +.BR FS . +. +. +.TP +.B FE +End footnote; +see +.BR FS . +. +. +.TP +.BR FG \~\c +.RI [ title \~[ override \~[ flag \~[ refname ]]]] +Caption a figure. +. +Arguments are handled analogously to +.BR EC . +. +The register +.B Fg +is the figure counter. +. +The string +.B Lifg +precedes the figure number and any +.I title. +. +Figure captions are centered irrespective of the alignment of any +enclosing display. +. +. +.IP +Captioned figures are listed in a table of contents +(see +.BR TC ) +if the Boolean register +.B Lf +is true. +. +Such a list uses the string +.B Lf +as a heading. +. +. +.TP +.BR FS \~[\c +.IR label ] +Start footnote. +. +Input until +.B FE +is called is collected into a footnote. +. +By default, +footnotes are automatically numbered starting at 1; +the number is available in register +.B :p +and, +with a trailing period, +in +.RB string\~ F . +. +This string precedes the footnote text at the bottom of the column or +page. +. +Footnotes are vertically separated by the product of +.RB registers\~ Fs +and +.BR Lsp . +. +In +.IR "groff mm" , +footnotes may be used in displays. +. +. +.IP +A +.I label +argument replaces the contents of the string +.BR F ; +it need not be numeric. +. +In this event, +the footnote marker in the body text must be explicitly written. +. +. +.TP +.BI GETHN\ "refname \fR[\fPvarname\fR]\fP" +Include the heading number where the corresponding +.RB \[lq] .SETR +.IR refname \[rq] +was placed. +. +This is displayed as \[lq]X.X.X.\[rq] in pass\~1. +. +See +.BR INITR . +. +If +.I varname +is used, +.B GETHN +sets the string +.I varname +to the heading number. +. +.TP +.BI GETPN\ "refname \fR[\fPvarname\fR]\fP" +Include the page number where the corresponding +.RB \[lq] .SETR +.IR refname \[rq] +was placed. +. +This is displayed as \[lq]9999\[rq] in pass\~1. +. +See +.BR INITR . +. +If +.I varname +is used, +.B GETPN +sets the string +.I varname +to the page number. +. +.TP +.BI GETR\ refname +Combine +.B GETHN +and +.B GETPN +with the text \[lq]chapter\[rq] and \[lq],\~page\[rq]. +. +The string +.B Qrf +contains the text for the cross reference: +. +.RS +.IP +\&.ds Qrf See chapter \[rs]\[rs]*[Qrfh], page \[rs]\[rs]*[Qrfp]. +.RE +. +.IP +.B Qrf +may be changed to support other languages. +. +Strings +.B Qrfh +and +.B Qrfp +are set by +.B GETR +and contain the page and heading number, +respectively. +. +.TP +.BI GETST\ "refname \fR[\fPvarname\fR]\fP" +Include the string saved with the second argument to +.BR .SETR . +. +This is a dummy string in pass\~1. +. +If +.I varname +is used, +.B GETST +sets it to the saved string. +. +See +.BR INITR . +. +. +.TP +.BI H\~ level\~\c +.RI [ title \~[ suffix ]] +Set a numbered section heading at +.IR level . +. +.I mm +produces numbered +.I "heading marks" +of the form +.IR a . b . c .\|.\|., +with up to fourteen levels of nesting. +. +Each level's number increases automatically with each +.B H +call and is reset to zero when a more significant +.I level +is specified. +. +.RB \[lq] 1 \[rq]\~is +the most significant or coarsest division of the document. +. +Text after an +.B H +call is formatted as a paragraph; +calling +.B P +is unnecessary. +. +. +.IP +.I title +specifies an optional title; +it must be double-quoted if it contains spaces. +. +.I mm +appends +.I suffix +to +.I title +in the body of the document, +but omits it from any table of contents +(see +.BR TC ). +. +This facility can be used to annotate the heading title with a footnote. +. +.I suffix +should not interpolate +.RB the\~ F +string; +specify a footnote mark explicitly. +. +See +.BR FS . +. +. +.IP +Heading behavior is highly configurable. +. +Several registers set a +.I threshold, +where heading levels at or below the threshold value are handled in one +way, +and those above it another. +. +For example, +a heading level within the threshold of register +.B Cl +is included in the table of contents +(see +.BR TC ). +. +. +.IP +.I Heading layout. +. +Register +.B Ej +sets a threshold for page breaking (ejection) prior to a heading. +. +If not preceded by a page break, +a heading level below the threshold in register +.B Hps +is preceded by the amount of vertical space in register +.BR Hps1 , +and by the amount in +.B Hps2 +otherwise. +. +The +.B Hb +register sets a threshold below which a break occurs after the heading, +and register +.B Hs +sets a threshold below which vertical space follows it. +. +If the heading level is not less than both of these, +a +.I run-in heading +is produced; +paragraph text follows on the same output line. +. +Otherwise, +register +.B Hi +configures the indentation of text after headings. +. +Threshold register +.B Hc +enables the centering of headings; +a heading level below both of the +.B Hb +and +.B Hc +thresholds is centered. +. +. +.IP +.I Heading typeface and size. +. +The fonts used for heading numbers and titles at each level are +configured by the +.B HF +string. +. +The string +.B HP +likewise assigns a type size to each heading level. +. +.\" XXX: Why not an "Hvs" string? +The vertical spacing used by headings may be controlled by +the user-definable macros +.B HX +and/or +.BR HZ . +. +. +.IP +.I Heading number format. +. +Registers named +.B H1 +through +.B H14 +store counters for each heading level. +. +Their values are printed using Arabic numerals by default; +see +.BR HM . +. +The heading levels are catenated with dots for formatting; +to typeset only the deepest, +set the +.B Ht +register. +. +Heading numbers are not suffixed with a trailing dot except when only +the first level is output; +to omit a dot in this case as well, +clear the +.B H1dot +register. +. +. +.IP +.I Customizing heading behavior. +. +.I mm +calls +.I hook +macros to enable further customization of headings. +. +(DWB +.I mm +called these \[lq]exits\[rq].) +. +They can be used to change the heading's +.I mark +(the numbered portion before any heading title), +its vertical spacing, +and its vertical space requirements +(for instance, +to require a minimum quantity of subsequent output lines). +. +Define hook macros in expectation of the following parameters. +. +The argument +.I declared-level +is the +.I level +argument to +.BR H , +.RB or\~ 0 +for unnumbered headings (see +.BR HU ). +. +.I actual-level +is the same as +.I declared-level +for numbered headings, +and the value of +.RB register\~ Hu +for unnumbered headings. +. +.I title +is the corresponding argument to +.B H +or +.BR HU . +. +. +.RS +.TP +.BI HX\~ "declared-level actual-level title" +.I mm +calls +.B HX +before setting the heading. +. +Your definition may alter +.BR }0 , +.BR }2 , +and +.BR ;3 . +. +. +.\" XXX: These names are ugly and of no obvious meaning. Make +.\" documented aliases for them. +.RS +.TP +.BR }0\~ (string) +contains the heading mark plus two spaces if +.I declared-level +is non-zero, +and otherwise is empty. +. +. +.TP +.BR ;0\~ (register) +encodes a position for the text after the heading. +. +0\~means that the heading is to be run in, +1\~means that a break is to occur before the text, +and 2\~means that vertical space is to separate heading and text. +. +. +.TP +.BR }2\~ (string) +is the suffix that separates a run-in heading from the text. +. +It contains two spaces if register +.B ;0 +is\~0, +and otherwise is empty. +. +. +.TP +.BR ;3\~ (register) +contains the vertical space required for the heading to be typeset. +. +If that amount is not available, +the page is broken prior to the heading. +. +The default is +.BR 2v . +.RE +. +. +.TP +.BI HY\~ "declared-level actual-level title" +.I mm +calls +.B HY +after determing the heading typeface and size. +. +It could be used to change indentation. +. +. +.TP +.BI HZ\~ "declared-level actual-level title" +.I mm +calls +.B HZ +after formatting the heading, +just before +.B H +or +.B HU +returns. +. +It could be used to change the page header to include a section heading. +.\" XXX: ...but only for the _next_ page, not the current one. See +.\" Savannah #62825. +.RE +. +. +.TP +.BI HC\ \fR[\fPhyphenation-character\fR]\fP +Set hyphenation character. +. +Default value is \[lq]\[rs]%\[rq]. +. +Resets to the default if called without argument. +. +Hyphenation can be turned off by setting register +.B Hy +to\~0 at the beginning of the file. +. +. +.TP +.BI HM\ "\fR[\fParg1 \fR[\fParg2 \fR[.\|.\|.\& [\fParg14\fR]]]]\fP" +Set the heading mark style. +. +Each argument assigns the specified register format +(see above) +to the corresponding heading level. +. +The default +.RB is\~ 1 +for all levels. +. +An explicitly empty argument also indicates the default. +. +. +.TP +.BI HU\~ heading-text +Set an unnumbered section heading. +. +Except for a heading number, +it is treated as a numbered heading of the level stored in +.RB register\~ Hu ; +.RB see\~ H . +. +. +.TP +.BR I \~\c \" space in roman; we must use 2-font macro with \c +.RI [ italic-text\~\c +.RI [ previous-font-text ]]\~.\|.\|. +Join +.I italic-text +in italics with +.I previous-font-text +in the previous font, +without space between the arguments. +. +If no arguments, +switch font to italic style. +. +. +.TP +.BR IA \~[\c +.IR recipient-name \~[\c +.IR title ]] +Specify the inside address in a letter. +. +Input is collected into the inside address until +.B IE +is called, +and then output. +. +You can specify multiple recipients with empty +.BR IA / IE +pairs; +only the last address is used. +. +The arguments give each recipient a name and title. +. +See +.BR LT . +. +. +.TP +.BR IB \~\c \" space in roman; we must use 2-font macro with \c +.RI [ italic-text\~\c +.RI [ bold-text ]]\~.\|.\|. +Join +.I italic-text +in italics with +.I bold-text +in boldface, +without space between the arguments. +. +. +.TP +.B IE +End the inside address begun with +.BR IA . +. +. +.TP +.BI IND\~ argument\~\c +\&.\|.\|. +If the Boolean register +.B Ref +is true, +write an index entry as a specially prepared +.I roff +comment to the standard error stream, +with each +.I argument +separated from its predecessor by a tab character. +. +The entry's location information is arranged as configured by the most +recent +.B INITI +call. +. +. +.TP +.B INDP +Output the index set up by +.B INITI +and populated by +.B IND +calls. +. +By default, +.B INDP +calls +.B SK +and writes a centered caption interpolating the string +.BR Index . +. +It then disables filling and calls +.BR 2C ; +afterward, +it restores filling and calls +.BR 1C . +. +. +.IP +Define macros to customize this behavior. +. +.B INDP +calls +.B TXIND +before the caption, +.B TYIND +.I instead +of writing the caption, +and +.B TZIND +after formatting the index. +. +. +.TP +.BI INITI\~ "location-type file-name\~"\c +.RI [ macro ] +Initialize +.IR "groff mm" 's +indexing system. +. +Argument +.I location-type +selects how the location of each index entry is reported. +. +.I file-name +populates an internal string used later by +.BR INDP . +. +. +.IP +.TS +tab(@); +Lf(BI) Lb +L Lx. +location-type@Entry format +N@page number +H@heading mark +B@page number, tab character, heading mark +.TE +. +. +.IP +If +.I macro +is specified, +it is called for each index entry +with the arguments given to +.BR IND . +. +. +.TP +.BI INITR\~ id +Initialize the cross reference macros. +. +Cross references are written to the standard error stream, +which should be redirected into a file named +.RI id .qrf . +. +.MR mmroff @MAN1EXT@ +handles this and the two formatting passes it requires. +.\". +.\"This program exists because +.\".MR groff @MAN1EXT@ +.\"by default deactivates the unsafe operations that are required by +.\".BR INITR . +. +The first pass identifies cross references, +and the second one includes them. +.\" +.\".B INITR +.\"can be used several times, +.\"but it is only the first occurrence of +.\".B INITR +.\"that is active. +. +. +.IP +See +.BR SETR , +.BR GETPN , +and +.BR GETHN . +. +. +.TP +.BR IR \~\c \" space in roman; we must use 2-font macro with \c +.RI [ italic-text\~\c +.RI [ roman-text ]]\~.\|.\|. +Join +.I italic-text +in italics with +.I roman-text +in roman style, +without space between the arguments. +. +. +.TP +.BR ISODATE\~ [ 0 ] +Use ISO\~8601 format for the date string +.B DT +used by some cover sheet and memorandum types; +that is, +.IR YYYY - MM - DD . +. +Must be called before +.B ND +to be effective. +. +If given an argument +.RB of\~ 0, +the traditional date format for the +.I groff +locale is used; +this is also the default. +. +. +.TP +.BI LB\~ "text-indent mark-indent pad type"\~\c +.RI [ mark \~[ pre-item-space \~[ pre-list-space ]]] +Begin list. +. +The macros +.BR AL , +.BR BL , +.BR BVL , +.BR DL , +.BR ML , +.BR RL , +and +.B VL +call +.B LB +in various ways; +they are simpler to use and may be preferred if they suit the desired +purpose. +. +. +.br +.ne 5v +.IP +The nesting level of lists is tracked by +.I mm; +the outermost level is\~0. +. +The text of each list item is indented by +.I text-indent; +the default is taken from the +.B Li +register +(in ens). +. +Each item's mark is indented by +.I mark-indent; +the default is +.BR 0n . +. +The mark is normally left-aligned. +. +If +.I pad +is greater than zero, +.I mark-indent +is overridden such that +.I pad +ens of space follow the mark. +. +.I type +selects one of six possible ways to display the mark. +. +. +.IP +.TS +tab(@); +Lf(BI) Lb +L L. +type@Output for a mark \[lq]x\[rq] +1@x. +2@x) +3@(x) +4@[x] +5@ +6@{x} +.TE +. +. +.IP +If +.I type +is\~0 and +.I mark +is unspecified, +the items are set with a hanging indent. +. +Otherwise, +.I mark +is interpreted as a string defining the mark. +. +If +.I type +is greater than zero, +items are automatically numbered; +.I mark +is interpreted as a register format. +. +The default +.I type +.RB is\~ 0 . +. +. +.IP +The last two arguments manage vertical space. +. +Unless a list's nesting level is greater than the value of register +.BR Ls , +its items are preceded by +.I pre-item-space +multiplied by the register +.BR Lsp ; +the default +.RB is\~ 1 . +. +.B LB +precedes the list by +.I pre-list-space +multiplied by the register +.BR Lsp ; +the default +.RB is\~ 0 . +. +. +.TP +.BR LC \~[\c +.IR list-level ] +Clear list state. +. +Active lists are terminated as if with +.BR LE , +either all +(the default) +or only those from the current level down to +.I list-level +if specified. +. +.B H +calls +.B LC +automatically. +. +. +.TP +.BR LE \~[ 1 ] +End list. +. +The current list is terminated. +. +An argument +.RB of\~ 1 +causes +vertical space in the amount of register +.B Lsp +to follow the list. +. +. +.TP +.BR LI \~[\c +.IR mark \~[ item-mark-mode ]] +Begin a list item. +. +Input is collected into a list item until the current list is terminated +or +.B LI +is called again. +. +By default, +the item's text is preceded by any mark configured by the current list. +. +If only +.I mark +is specified, +it replaces the configured mark. +. +A second argument +prefixes +.I mark +to the configured mark; +an +.I item-mark-mode +value of\~1 places an unbreakable space after +.I mark, +while +a value of\~2 does not +(rendering the two adjacent). +. +Also see register +.BR Limsp . +. +. +.TP +.BI LO\~ option\~\c +.RI [ value ] +Specify letter options; +see +.BR LT . +. +Standard options are as follows. +. +See +.B IA +regarding the inside address and string +.B DT +regarding the date. +. +. +.IP +.TS +tab(@); +Lf(BI) Lb +L Lx. +option@Effect +AT@T{ +Attention; +put contents of string +.B LetAT +and +.I value +left-aligned after the inside address. +T} +CN@T{ +Confidential; +put +.I value, +or contents of string +.BR LetCN , +left-aligned after the date. +T} +RN@T{ +Reference; +put contents of string +.B LetRN +and +.I value +after the confidental notation +(if any) +and the date, +aligned with the latter. +T} +SA@T{ +Salutation; +put +.I value, +or contents of string +.BR LetSA , +left-aligned after the inside address +and the confidental notation +(if any). +T} +SJ@T{ +Subject; +put contents of string +.B LetSJ +and +.I value +left-aligned after the inside address +and the attention and salutation notations +(if any). +. +In letter type \[lq]SP\[rq], +.B LetSJ +is ignored and +.I value +is set in full capitals. +T} +.TE +. +. +.br +.ne 5v +.TP +.BR LT \~[\c +.IR style ] +Format a letter in the designated +.I style, +defaulting to +.B BL +(see below). +. +A letter begins with the writer's address +.RB ( WA / WE ), +followed by the date +.RB ( ND ), +the inside address +.RB ( IA / IE ), +the body of the letter +.RB ( P +and other general-purpose +.I mm +macros), +the formal closing +.RB ( FC ), +the signature +.RB ( SG ), +and notations +.RB ( NS / NE ). +. +Any of these may be omitted. +. +Letter options specified with +.B LO +add further annotations, +which are extensible; +see section \[lq]Internals\[rq] below. +. +. +.br +.ne 6v +.IP +.TS +tab(@); +Lf(BI) Lb +Lb Lx. +style@Description +BL@T{ +Blocked: +the writer's address, +date, +formal closing, +and signature are indented to the center of the line. +. +Everything else is left-aligned. +T} +SB@T{ +Semi-blocked: +as +.BR BL , +but the first line of each paragraph is indented by +.BR 5m . +.\" XXX: https://savannah.gnu.org/bugs/?64315 +T} +FB@T{ +Fully blocked: +everything begins at the left margin. +T} +SP@T{ +Simplified: +as +.BR FB , +but a formal closing is omitted, +and the signature is set in full capitals. +T} +.TE +. +. +.TP +.BI MC\~ column-width\~\c +.RI [ gutter-width ] +Begin multi-column layout. +. +.I groff mm +creates as many columns of +.I column-width +as the line length will permit. +. +.I gutter-width +is the interior spacing between columns. +. +It defaults to +.IR column-width /15. +. +.B 1C +returns to single-column layout. +. +.B MC +is a GNU extension. +. +See +.B MULB +for an alternative. +. +. +.TP +.BI ML\~ "mark \fR[\fPtext-indent\~" \fR[\fP1\fR]]\fP +Start a list with the +.I mark +argument preceding each list item. +. +.I text-indent +overrides the default indentation of the list items set by register +.BR Li . +. +If a third argument, +conventionally +.BR 1 , +is given, +the blank line that normally precedes each list item is suppressed. +. +Use +.B LI +to declare list items, +and +.B LE +to end the list. +. +. +.TP +.BR MT \~\c \" space in roman; we must use 2-font macro with \c +.RI [ type \~[ addressee ]] +Select memorandum type. +. +These correspond to formats used by AT&T Bell Laboratories, +where the +.I mm +package was initially developed, +affecting the document layout. +. +Some of these included a cover page with a caption categorizing the +document. +. +.I groff mm +uses +.I type +to construct the file name +.IR @TMAC_MDIR@/\:\% type \:.MT +and load it with the +.B mso +request. +. +Memorandum types 0 to\~5 are supported; +any other value of +.I type +is mapped to type\~6. +. +If +.I type +is omitted, +.B 0 +is implied. +. +.I addressee +sets a string analogous to one used by AT&T cover sheet macros that are +not implemented in +.IR "groff mm" . +. +. +.IP +.TS +tab(@); +Lf(BI) Lb +L L. +type@Description +0@normal memorandum; no caption +1@captioned \[lq]MEMORANDUM FOR FILE\[rq] +2@captioned \[lq]PROGRAMMER'S NOTES\[rq] +3@captioned \[lq]ENGINEER'S NOTES\[rq] +4@released paper +5@external letter +.TE +. +. +.IP +See +.B \%COVER +for a more flexible cover sheet mechanism. +. +. +.TP +.BI MOVE\ "y-pos \fR[\fPx-pos \fR[\fPline-length\fR]]\fP" +Move to a position, setting page offset to +.IR x-pos . +. +If +.I line-length +is not given, the difference between current and new page offset is +used. +. +Use +.B PGFORM +without arguments to return to normal. +. +. +.TP +.BR MULB \~\c \" space in roman; we must use 2-font macro with \c +.IR "cw1 space1\~" [ "cw2 space2" "] .\|.\|.\~" cwn +Begin alternative multi-column mode. +. +All column widths must be specified, +as must the amount of space between each column pair. +. +The arguments' default scaling unit is +.BR n . +. +.B MULB +uses a diversion and operates in a separate environment. +. +. +.TP +.B MULN +Begin next column in alternative column mode. +. +. +.TP +.B MULE +End alternative multi-column mode and emit the columns. +. +. +.TP +.B NCOL +Move to the start of the next column +(only when using +.B 2C +or +.BR MC ). +. +Contrast with +.BR MULN . +. +. +.TP +.BR ND \~[\c +.IR arg ] +Set the document's date. +. +.I mm +does not interpret +.IR arg ; +it can be a revision identifier +(or empty). +. +. +.TP +.B NE +End notation begun with +.BR NS ; +filling is enabled. +. +. +.TP +.BI nP\ \fR[\fPtype\fR]\fP +Begin a numbered paragraph at heading level two. +. +See +.BR P . +. +. +.br +.ne 6v +.TP +.BR NS \~[\c +.IR code \~[\c +.BR 1 ]] +Declare notations, +typically for letters or memoranda, +of the type specified by +.IR code . +. +The text corresponding to +.I code +is output, +and filling is disabled +until +.B NE +is called. +. +Typically, +a list of names or attachments lies within +.BR NS / NE . +. +If +.I code +is absent or does not match one of the values listed under the +.B Letns +string description below, +each line of notations is formatted as +.RI "\[lq]Copy (" line ") to\[rq]." +. +If a second argument, +conventionally +.BR 1 , +is given, +.I code +becomes the entire notation and +.B NE +is not necessary. +. +In +.IR "groff mm" , +you can set up further notations to be recognized by +.BR NS ; +see the strings +.B Letns +and +.B Letnsdef +below. +. +. +.TP +.BR OF\~ [ \[dq]\|\[aq]\c +.IB left \[aq] center \[aq] right \[aq]\|\[dq]\c +] +Define the odd-page footer, +which is formatted just above the normal page footer on odd-numbered +pages. +. +See +.BR PF . +. +.B OF +defines the string +.BR EOPof . +. +. +.TP +.BR OH\~ [ \[dq]\|\[aq]\c +.IB left \[aq] center \[aq] right \[aq]\|\[dq]\c +] +Define the odd-page header, +which is formatted just below the normal page header on odd-numbered +pages. +. +See +.BR PH . +. +.B OH +defines the string +.BR TPoh . +. +. +.TP +.B OP +Make sure that the following text is printed at the top of an +odd-numbered page. +. +Does not output an empty page if currently at the top of an odd page. +. +. +.br +.ne 4v +.TP +.BR P \~[\c +.IR type ] +Begin new paragraph. +. +If +.I type +is missing or\~ 0, +.BR P \~sets +the paragraph fully left\-aligned. +. +A +.I type +of\~1 +idents the first line by +.B \[rs][Pi] +ens. +. +Set the register +.B Pt +to select a default paragraph indentation style. +. +The register +.B Ps +controls the vertical spacing between paragraphs. +. +. +.TP +.B PE +Picture end; +see +.MR @g@pic @MAN1EXT@ . +. +. +.TP +.BR PF\~ [ \[dq]\|\[aq]\c +.IB left \[aq] center \[aq] right \[aq]\|\[dq]\c +] +Define the page footer. +. +The footer is formatted at the bottom of each page; +the argument is otherwise as described in +.BR PH . +. +.B PF +defines the string +.BR EOPf . +. +See +.BR EF , +.BR OF , +and +.BR EOP . +. +.TP +.BI PGFORM\ "\fR[\fPlinelength \fR[\fPpagelength \fR[\fPpageoffset\ " \fR[\fP1\fR]]]]\fP +Set line length, page length, and/or page offset. +. +This macro can be used for letterheads and similar. +. +It is normally the first macro call in a file, +though it is not necessary. +. +.B PGFORM +can be used without arguments to reset everything after a +.B MOVE +call. +. +A line break is done unless the fourth argument is given. +. +This can be used to avoid the page number on the first page +while setting new width and length. +. +(It seems as if this macro sometimes doesn't work too well. +. +Use the command-line arguments to change +line length, page length, and page offset instead.) +. +.TP +.B PGNH +Suppress header on the next page. +. +This macro must be called before any macros that produce output to +affect the layout of the first page. +. +. +.TP +.BR PH\~ [ \[dq]\|\[aq]\c +.IB left \[aq] center \[aq] right \[aq]\|\[dq]\c +] +.RS +Define the page header, +formatted at the top of each page, +as the argument, +where +.IR left , +.IR center , +and +.I right +are aligned to the respective locations on the line. +. +A +.RB \[lq] % \[rq] +character in +.I arg +is replaced by the page number. +. +If the argument is absent, +no page header is set. +. +The default page header is +. +.RS +.EX +\[dq]\[aq]\[aq]\- % \-\[aq]\[aq]\[dq] +.EE +.RE +. +which centers the page number between hyphens and formats nothing at the +upper left and right. +. +Header macros call +.B PX +(if defined) +after formatting the header. +. +.B PH +defines the string +.BR TPh . +. +See +.BR EH , +.BR OH , +and +.BR TP . +.RE +. +. +.TP +.BR PIC \~\c +.RB [ \-B ]\~\c +.RB [ \-C |\c +.BI \-I\~ n\c +.RB | \-L \c +.RB | \-R ]\~\c +.IR file \~[ width \~[ height ]] +Include PostScript document +.IR file . +. +The optional +.B \-B +argument draws a box around the picture. +. +The optional +.BR \-L , +.BR \-C , +.BR \-R , +and +.BI \-I\~ n +arguments align the picture or indent it by +.I n +(assuming a scaling unit of +.BR m ). +. +By default, +the picture is left-aligned. +. +Optional +.I width +and +.I height +arguments resize the picture. +. +Use of this macro requires two-pass processing; +see +.B INITR +and +.MR mmroff @MAN1EXT@ . +. +. +.TP +.B PS +Picture start; see +.MR @g@pic @MAN1EXT@ . +. +. +.TP +.B PY +Picture end with flyback. +. +Ends a +.MR @g@pic @MAN1EXT@ +picture, +returning the vertical position to where it was prior to the picture. +. +This is a GNU extension. +. +. +.TP +.BR R \~\c \" space in roman; we must use 2-font macro with \c +.RI [ roman-text\~\c +.RI [ previous-font-text ]]\~.\|.\|. +Join +.I roman-text +in roman style with +.I previous-font-text +in the previous font, +without space between the arguments. +. +If no arguments, +switch font to roman style. +. +. +.TP +.BR RB \~\c \" space in roman; we must use 2-font macro with \c +.RI [ roman-text\~\c +.RI [ bold-text ]]\~.\|.\|. +Join +.I roman-text +in roman style with +.I bold-text +in boldface, +without space between the arguments. +. +. +.TP +.BI RD\ "\fR[\fPprompt \fR[\fPdiversion \fR[\fPstring\fR]]]\fP" +Read from standard input to diversion and/or string. +. +The text is saved in a diversion named +.IR diversion . +. +Recall the text by writing the name of the diversion after a dot +on an empty line. +. +A string is also defined if +.I string +is given. +. +.I Diversion +and/or +.I prompt +can be empty (\[dq]\[dq]). +. +.TP +.B RF +Reference end. +. +Ends a reference definition and returns to normal processing. +. +See +.BR RS . +. +. +.TP +.BR RI \~\c \" space in roman; we must use 2-font macro with \c +.RI [ roman-text\~\c +.RI [ italic-text ]]\~.\|.\|. +Join +.I roman-text +in roman style with +.I italic-text +in italics, +without space between the arguments. +. +. +.TP +.BR RL \~[\c +.IR text-indent \~[\c +.BR 1 ]] +Begin reference list. +. +Each item is preceded by an automatically incremented number between +square brackets; +compare +.BR AL . +. +.I text-indent +changes the default indentation. +. +Use +.B LI +to declare list items, +and +.B LE +to end the list. +. +A second argument, +conventionally +.BR 1 , +suppresses the blank line that normally precedes each list item. +. +. +.TP +.BR RP \~\c \" space in roman; we must use 2-font macro with \c +.RI [ suppress-counter-reset \~[ page-ejection-policy ]] +Format a reference page, +listing items accumulated within +.BR RS / RF +pairs. +. +The reference counter is reset unless the first argument +.RB is\~ 1 . +. +Normally, +page breaks occur before and after the references are output; +the register +.B Rpe +configures this behavior, +and a second argument overrides its value. +. +.B TC +calls +.B RP +automatically if references have accumulated. +. +. +.IP +References are list items, +and thus are vertically separated +(see +.BR LB ). +. +Setting register +.B Ls +.RB to\~ 0 +suppresses this spacing. +. +The string +.B Rp +contains the reference page caption. +. +. +.br +.ne 5v +.TP +.BR RS \~[\c +.IR reference-string ] +Begin an automatically numbered reference definition. +. +By default, +references are numbered starting at 1; +the number is available in register +.BR :R . +. +Interpolate the string +.B Rf +where the reference mark should be and write the reference between +.BR RS / RF +on an input line after the reference mark. +. +If +.I reference-string +is specified, +.I "groff ms" +also stores the reference mark in a string of that name, +which can be interpolated as +.BI \[rs]*[ reference-string ] +subsequently. +. +. +.TP +.BR S \~[\c +.IR type-size \~[ vertical-spacing ]] +Set type size and vertical spacing. +. +Each argument is a +.I groff +measurement, +using an appropriate scaling unit and an optional +.B + +or +.B \- +prefix to increment or decrement the current value. +. +An argument of +.B P +restores the previous value, +.B C +indicates the current value, +and +.B D +requests the default. +. +An empty or omitted argument is treated as +.BR P . +. +. +.TP +.BR SA \~\c +.RI [ mode ] +Set or restore the default enablement of adjustment. +. +Specify +.B 0 +or +.B 1 +as +.I mode +to set a document's default explicitly; +.B 1 +is assumed by +.IR mm . +. +Adjustment can be temporarily suspended with the +.B na +request. +. +When the +.B H +or +.B HU +macros are used to format a heading, +or when +.B SA +is called without a +.I mode +argument, +the default adjustment is restored. +. +. +.TP +.BI SETR\ "refname \fR[\fPstring\fR]\fP" +Remember the current heading and page numbers as +.IR refname . +. +Saves +.I string +if +.I string +is defined. +. +.I string +is retrieved with +.BR GETST . +. +See +.BR INITR . +. +.TP +.BI SG\ \fR[\fParg\ \fR[\fP1\fR]]\fP +Signature line. +. +Prints the authors name(s) after the formal closing. +. +The argument is appended to the reference data, printed at either the +first or last author. +. +The reference data is the location, department, and initials specified +with +.BR AU . +. +It is printed at the first author if the second argument is given, +otherwise at the last. +. +No reference data is printed if the author(s) is specified through +.BR WA / WE . +. +See section \[lq]Internals\[rq] below. +. +. +.TP +.BR SK \~\c +.RI [ n ] +Skip +.I n +pages. +. +If +.I n +is\~0 or omitted, +the page is broken unless the drawing position is already at the top of +a page. +. +Otherwise, +.I n +pages, +blank except for any headers and footers, +are printed. +. +. +.br +.ne 4v \" XXX: 3v should suffice +.TP +.BI SM\~ text\~\c +.RI [ post ] +.TQ +.BI SM\~ "pre text post" +Format +.I text +at a smaller type size, +joined with any specified +.I pre +and +.I post +at normal size. +. +. +.TP +.BI SP\ \fR[\fPlines\fR]\fP +Space vertically. +. +.I lines +can have any scaling factor, +like \[lq]3i\[rq] or \[lq]8v\[rq]. +. +Several +.B SP +calls in a line only produces the maximum number of lines, not the sum. +. +.B SP +is ignored also until the first text line in a page. +. +Add +.B \[rs]& +before a call to +.B SP +to avoid this. +. +. +.TP +.B TAB +Reset tab stops to every 5\~ens. +. +. +.br +.ne 4v +.TP +.BR TB \~\c +.RI [ title \~[ override \~[ flag \~[ refname ]]]] +Caption a table. +. +Arguments are handled analogously to +.BR EC . +. +The register +.B Tb +is the table counter. +. +The string +.B Litb +precedes the table number and any +.I title. +. +Table captions are centered irrespective of the alignment of any +enclosing display. +. +. +.IP +Captioned tables are listed in a table of contents +(see +.BR TC ) +if the Boolean register +.B Lt +is true. +. +Such a list uses the string +.B Lt +as a heading. +. +. +.TP +.BR TC \~\c +.RI [ slevel\~\c +.RI [ spacing\~\c +.RI [ tlevel\~\c +.RI [ tab\~\c +.RI [ h1\~\c +.RI [ h2\~\c +.RI [ h3\~\c +.RI [ h4\~\c +.RI [ h5 ]]]]]]]]] +Output table of contents. +. +This macro is normally the last called in the document. +. +It flushes any pending displays and, +if any references are pending +(see +.BR RS ), +calls +.BR RP . +. +It then begins a new page with the contents caption, +stored in the string +.BR Licon , +centered at the top. +. +The entries follow after three vees of space. +. +Each entry is a +saved section +(number and) +heading title +(see the +.B Cl +register), +along with its associated page number. +. +By default, +an entry is indented by an amount corresponding to its heading level +and the maximum heading length encountered at that heading level; +if defined, +the string +.B Ci +overrides these indentations. +. +Entries at heading levels up to and including +.I slevel +are preceded by +.I spacing +vees of space. +. +Entries at heading levels up to and including +.I tlevel +are followed by a leader and a right-aligned page number. +. +If the Boolean-valued +.I tab +argument is true, +the leader is replaced with horizontal motion in the same amount. +. +For entries above heading level +.IR tlevel , +the page number follows the heading text after a word space. +. +Each argument +.IR h1 .\|.\|. h5 +appears in order on its own line, +centered, +above the contents caption. +. +Page numbering restarts at 1, +in register format \[lq]i\[rq]. +. +If the +.B Oc +register is true, +numbering of these pages is suppressed. +. +. +.IP +If +.B TC +is called with at most four arguments, +it calls the user-defined macro +.B TX +(if defined) +prior to formatting the contents caption, +and +.B TY +(if defined) +.I instead +of formatting the contents caption. +. +. +.IP +Analogous handling of lists of figures, +tables, +equations, +and exhibits is achieved by defining +.BI TX xx +and +.BI TY xx +macros, +where +.I xx +is \[lq]FG\[rq], +\[lq]TB\[rq], +\[lq]EC\[rq], +or \[lq]EX\[rq], +respectively. +. +Similarly, +the strings +.BR Lifg , +.BR Litb , +.BR Liex , +and +.B Liec +determine captions for their respective lists. +. +. +.TP +.B TE +Table end. +. +See +.BR TS . +. +.TP +.B TH +End table heading. +. +It is repeated after page breaks within a table. +. +See +.BR TS . +. +The +.B N +argument supported by DWB +.I mm +is not implemented by +.I "groff mm." +. +. +.TP +.BR TL \~[\c +.IR charging-case-number \~[\c +.IR filing-case-number ]] +Begin document title. +. +Input is collected into the title until +.B AF +or +.B AU +is called, +and output as directed by the cover page. +. +.I charging-case-number +and +.I filing-case-number +are saved for use in memorandum types 0 and 5. +. +See +.BR MT . +. +. +.TP +.BI TM\~ number\c +\~.\|.\|. +Declare technical memorandum number(s) used by +.BR MT . +. +. +.br +.ne 6v +.TP +.B TP +If defined, +this macro is called in lieu of normal page header layout. +. +Headers and footers are formatted in a separate environment. +. +See +.BR EOP . +. +. +.IP +.TS +tab(@); +Cb S +Lb L. +Strings available to TP +_ +TPh@argument to \fBPH\fP +TPeh@argument to \fBEH\fP +TPoh@argument to \fBOH\fP +.TE +. +. +.TP +.B TS \fR[\fPH\fR]\fP +Table start. +. +Argument \[lq]H\[rq] tells +.I mm +that the table has a heading. +. +See +.BR TE , +.BR TH , +and +.MR @g@tbl @MAN1EXT@ . +. +. +.TP +.BR VERBON \~\c \" space in roman; we must use 2-font macro with \c +.RI [ format \~[ type-size \~[ font ]]] +Begin verbatim display, +where characters have equal width. +. +.I format +controls several parameters. +. +Add up the values of desired features; +the default +.RB is\~ 0 . +. +On typesetting devices, +further arguments configure the +.I type-size +in scaled points, +and the face +.RI ( font ); +the default is +.B CR +(Courier roman). +. +. +.IP +.TS +tab(@); +lb lb +l lx. +Value@Effect +1@Disable the formatter's escape character (\[rs]). +2@Vertically space before the display. +4@Vertically space after the display. +8@T{ +Number output lines; call formatter's +.B nm +request with arguments in string +.BR Verbnm . +T} +16@T{ +Indent by the amount stored in register +.BR Verbin . +T} +.TE +. +. +.TP +.B VERBOFF +End verbatim display. +. +. +.TP +.BR VL \~[\c +.IR text-indent \~[ mark-indent \~[\c +.BR 1 ]]] +Begin variable-item +(or \[lq]tagged\[rq]) +list. +. +Each item should supply its own mark, +or tag. +. +If the mark is wider than +.I mark-indent, +one space separates it from subsequent text; +contrast +.BR BVL . +. +.I text-indent +sets the indentation of the text, +and +.I mark-indent +the distance from the current list indentation to the mark. +. +A third argument suppresses the blank line that normally precedes each +list item. +. +Use +.B LI +to declare list items, +and +.B LE +to end the list. +. +. +.TP +.BI "VM \fR[\fP\-T\fR] [\fP" "top \fR[\fPbottom\fR]]\fP" +Vertical margin. +. +Increase the top and bottom margin by +.I top +and +.IR bottom , +respectively. +. +If option +.B \-T +is specified, set those margins to +.I top +and +.IR bottom . +. +If no argument is given, reset the margin to zero, or to the default +(\[lq]7v 5v\[rq]) +if +.B \-T +is used. +. +It is highly recommended that macros +.B TP +and/or +.B EOP +are defined if using +.B \-T +and setting top and/or bottom margin to less than the default. +. +This undocumented DWB +.I mm +macro is exposed by +.I groff mm +to increase user control of page layout. +. +. +.TP +.BR WA \~[\c +.IR writer's-name \~[\c +.IR title ]] +Specify the writer(s) of an +.B LT +letter. +. +Input is collected into the writer's address until +.B WA +is called, +and then output. +. +You can specify multiple writers with empty +.BR WA / WE +pairs; +only the last address is used. +. +The arguments give each writer a name and title. +. +. +.TP +.BR WC \~[\c +.IR format \~.\|.\|.] +Control width of footnotes and displays. +. +. +.IP +.RS +.TS +tab(@); +Lf(BI) Lb +Lb Lx. +format@Effect +N@T{ +equivalent to +.RB \[lq] "\-WF \-FF \-WD" \[rq] +.\" FB \" XXX: see Savannah ticket reference below +(default) +T} +WF@T{ +set footnotes at full line length, +even in two-column mode +.\" XXX: what about multi-column modes more generally? +T} +\-WF@T{ +set footnotes using column line length +T} +FF@T{ +apply width of first footnote to encountered to subsequent ones +T} +\-FF@T{ +footnote width determined by +.B WF +and +.B \-WF +T} +WD@T{ +set displays at full line length, +even in two-column mode +.\" XXX: what about multi-column modes more generally? +T} +\-WD@T{ +set displays using column line length +T} +.TE +.RE +.\" XXX: See . +.\"FB@T{ +.\"Break when outputting floating displays. +.\"T} +.\"\-FB@T{ +.\"Do not break when outputting floating displays. +.\"T} +. +. +.TP +.B WE +End the writer's address begun with +.BR WA . +. +. +.br +.ne 4v +.\" ==================================================================== +.SH Strings +.\" ==================================================================== +. +Many +.I mm +strings interpolate predefined, +localizable text. +. +These are presented in quotation marks. +. +. +.TP +.B App +\[lq]APPENDIX\[rq] +. +. +.TP +.B Apptxt +stores the +.I title +argument to the last +.B APP +call. +. +. +.TP +.B BU +interpolates a bullet +(see +.BR BL ). +. +. +.TP +.B Ci +is a list of indentation amounts to use for table of contents heading +levels, +overriding their automatic computation. +. +Each word must be a horizontal measurement +(like +.RB \[lq] 1i \[rq]) +and is mapped one-to-one to heading levels 1, +2, +and so on. +. +. +.TP +.B DT +The date; +set by the +.B ND +macro +(defaults to the date the document is formatted). +. +The format is the conventional one for the +.I groff +locale, +but see the +.B ISODATE +macro and +.B Iso +register. +. +. +.TP +.B EM +interpolates an em dash. +. +. +.TP +.B F +interpolates an automatically numbered footnote marker; +the number is used by the next +.B FS +call without an argument. +. +In +.I troff +mode, +the marker is superscripted; +in +.I nroff +mode, +it is surrounded by square brackets. +. +. +.TP +.B H1txt +Updated by +.B .H +and +.B .HU +to the current heading text. +. +Also updated in table of contents & friends. +. +. +.TP +.B HF +assigns font identifiers, +separated by spaces, +to heading levels in one-to-one correspondence. +. +Each identifier may be a font mounting position, +font name, +or style name. +. +Omitted values are assumed to be\~1. +. +The default is +.RB \[lq] "2 2 2 2 2 2 2 2 2 2 2 2 2 2" \[rq], +which places all headings in italics. +. +DWB +.IR mm 's +default was +.RB \[lq] "3 3 2 2 2 2 2" \[rq]. +. +. +.TP +.B HP +assigns type sizes, +separated by spaces, +to heading levels in one-to-one correspondence. +. +Each size is interpreted in scaled points; +zero values are translated to +.BR 10 . +. +Omitted values are assumed to be\~0 +(and are translated accordingly). +. +The default is +.RB \[lq] "0 0 0 0 0 0 0 0 0 0 0 0 0 0" \[rq]. +. +. +.TP +.B Index +\[lq]INDEX\[rq] +. +. +.TP +.B Le +\[lq]LIST OF EQUATIONS\[rq] +. +. +.TP +.B Letfc +\[lq]Yours very truly,\[rq] +(see +.BR FC ) +. +. +.TP +.B Letapp +\[lq]APPROVED:\[rq] +(see +.BR AV ) +. +. +.TP +.B LetAT +\[lq]ATTENTION:\[rq] +(see +.BR LO ) +. +. +.TP +.B LetCN +\[lq]CONFIDENTIAL\[rq] +(see +.BR LO ) +. +. +.TP +.B Letdate +\[lq]Date\[rq] +(see +.BR AV ) +. +. +.TP +.B Letns +is a group of strings structuring the notations produced by +.BR NS . +. +If the +.I code +argument to +.B NS +has no corresponding string, +the notation is included between parentheses, +prefixed with +.BR Letns!copy , +and suffixed with +.BR Letns!to . +. +Observe the spaces after \[lq]Copy\[rq] and before \[lq]to\[rq]. +. +. +.RS +.P +.TS +tab(@); +Lb Lb Lb +L L L. +NS code@String@Contents +0@Letns!0@Copy to +1@Letns!1@Copy (with att.\&) to +2@Letns!2@Copy (without att.\&) to +3@Letns!3@Att. +4@Letns!4@Atts. +5@Letns!5@Enc. +6@Letns!6@Encs. +7@Letns!7@Under separate cover +8@Letns!8@Letter to +9@Letns!9@Memorandum to +10@Letns!10@Copy (with atts.\&) to +11@Letns!11@Copy (without atts.\&) to +12@Letns!12@Abstract Only to +13@Letns!13@Complete Memorandum to +14@Letns!14@CC +\[em]@Letns!copy@Copy \fI(with trailing space)\fP +\[em]@Letns!to@ to \fI(note leading space)\fP +.TE +.RE +. +. +.TP +.B Letnsdef +Select the notation format used by +.B NS +when it is given no argument. +. +The default is +.RB \[lq] 0 \[rq]. +. +. +.TP +.B LetRN +\[lq]In reference to:\[rq] +(see +.BR LO ) +. +. +.TP +.B LetSA +\[lq]To Whom It May Concern:\[rq] +(see +.BR LO ) +. +. +.TP +.B LetSJ +\[lq]SUBJECT:\[rq] +(see +.BR LO ) +. +. +.TP +.B Lf +\[lq]LIST OF FIGURES\[rq] +. +. +.TP +.B Licon +\[lq]CONTENTS\[rq] +. +. +.TP +.B Liec +\[lq]Equation\[rq] +. +. +.TP +.B Liex +\[lq]Exhibit\[rq] +. +. +.TP +.B Lifg +\[lq]Figure\[rq] +. +. +.TP +.B Litb +\[lq]TABLE\[rq] +. +. +.TP +.B Lt +\[lq]LIST OF TABLES\[rq] +. +. +.TP +.B Lx +\[lq]LIST OF EXHIBITS\[rq] +. +. +.TP +.BR MO1 \|.\|.\|.\| MO12 +\[lq]January\[rq] through \[lq]December\[rq] +. +. +.TP +.B Qrf +\[lq]See chapter \[rs]\[rs]*[Qrfh], +page \[rs]\[rs]n[Qrfp].\[rq] +. +. +.TP +.B Rf +interpolates an automatically numbered reference mark; +the number is used by the next +.B RS +call. +. +In +.I troff +mode, +the marker is superscripted; +in +.I nroff +mode, +it is surrounded by square brackets. +. +. +.TP +.B Rp +\[lq]REFERENCES\[rq] +. +. +. +.TP +.B Sm +interpolates +.if c \[u2120] \[u2120], +the service mark sign. +. +. +.TP +.B Tcst +interpolates an indicator of the +.B TC +macro's processing status. +. +If +.B TC +is not operating, +it is empty. +. +User-defined +.B TP +or +.B EOP +macros might condition page headers or footers on its contents. +. +. +.IP +.TS +tab(@); +lb lb +l l. +Value@Meaning +co@Table of contents +fg@List of figures +tb@List of tables +ec@List of equations +ex@List of exhibits +ap@Appendix +.TE +. +. +.TP +.B Tm +interpolates +.if c \[tm] \[tm], +the trade mark sign. +. +. +.TP +.B Verbnm +supplies argument(s) to the +.B nm +request employed by the +.B VERBON +macro. +. +The default is\~\[lq]1\[rq]. +. +. +.br +.ne 4v +.\" ==================================================================== +.SH Registers +.\" ==================================================================== +. +Default register values, +where meaningful, +are shown in parentheses. +. +Many are also marked as Boolean-valued, +meaning that they are considered \[lq]true\[rq] +(on, +enabled) +when they have a positive value, +and \[lq]false\[rq] +(off, +disabled) +otherwise. +. +. +.TP +.B .mgm +indicates that +.I groff mm +is in use +(Boolean-valued; +.BR 1 ). +. +. +.TP +.B :p +is an auto-incrementing footnote counter; +see +.BR FS . +. +. +.TP +.B :R +is an auto-incrementing reference counter; +see +.BR RS . +. +. +.TP +.B Aph +formats an appendix heading +(and title, +if supplied); +see +.B APP +(Boolean-valued; +.BR 1 ). +. +. +.TP +.B Au +includes supplemental author information +(the third and subsequent arguments to +.BR AU ) +in memorandum \[lq]from\[rq] information; +see +.B COVER +and +.B MT +(Boolean-valued; +.BR 1 ). +. +. +.TP +.B Cl +sets the threshold for inclusion of headings in a table of contents. +. +Headings at levels above this value are excluded; +see +.B H +and +.B TC +.RB ( 2 ). +. +The +.B Cl +register controls whether a heading is +.I saved +for output in the table of contents at the time +.B H +or +.B HU +is called; +if you change +.BR Cl 's +value immediately prior to calling +.BR TC , +you are unlikely to get the result you want. +. +. +.TP +.B Cp +suppresses page breaks before lists of captioned +equations, +exhibits, +figures, +and tables, +and before an index; +see +.BR EC , +.BR EX , +.BR FG , +.BR TB , +and +.B INDP +(Boolean-valued; +.\" DWB 3.3's manual said this was 1, but the code said 0. +.BR 0 ). +. +. +.TP +.B D +produces debugging information for the +.I mm +package on the standard error stream. +. +A value of\~0 outputs nothing; +1\~reports formatting progress. +. +Higher values communicate internal state information of increasing +verbosity +.RB ( 0 ). +. +. +.TP +.B De +causes a page break after a floating display is output; +see +.B DF +(Boolean-valued; +.BR 0 ). +. +. +.TP +.B Df +configures the behavior of +.BR DF . +. +The following values are recognized; +4 and 5 do not override the +.B De +register +.RB ( 5 ). +. +. +.IP +.TS +tab(@); +Lb Lb +L Lx. +Value@Effect +0@T{ +Flush pending displays +at the end of each section +when section-page numbering is active, +otherwise at the end of the document. +T} +1@T{ +Flush a pending display +on the current page or column +if there is enough space, +otherwise at the end of the document. +T} +2@T{ +Flush one pending display +at the top of each page or column. +T} +3@T{ +Flush a pending display +on the current page or column +if there is enough space, +otherwise at the top of the next. +T} +4@T{ +Flush as many pending displays +as possible in a new page or column. +T} +5@T{ +Fill columns or pages with flushed displays +until none remain. +T} +.TE +. +. +.TP +.B Ds +puts vertical space in the amount of register +.B Dsp +(if defined) or +.B Lsp +before and after each static display; +see +.B DS +(Boolean-valued; +.BR 1 ). +. +. +.TP +.B Dsp +configures the amount of vertical space placed +before and after static displays; +see +.B DS +and register +.B Ds +.RI ( undefined ). +. +. +.TP +.B Ec +is an auto-incrementing equation counter; +see +.BR EC . +. +. +.TP +.B Ej +sets the threshold for page breaks (ejection) prior to the format of +headings. +. +Headings at levels above this value are set on the same page and column +if possible; +see +.B H +.RB ( 0 ). +. +. +.TP +.B Eq +aligns an equation label to the left of a display instead of the right +(Boolean-valued; +.BR 0 ). +. +. +.TP +.B Ex +is an auto-incrementing exhibit counter; +see +.BR EX . +. +. +.TP +.B Fg +is an auto-incrementing figure counter; +see +.BR FG . +. +. +.TP +.B Fs +is multiplied by register +.B Lsp +to vertically separate footnotes; +see +.B FS +.RB ( 1 ). +. +. +.TP +.BR H1 \|.\|.\|.\| H14 +are auto-incrementing counters corresponding to each heading level; +see +.BR H . +. +. +.\" XXX: This could be generalized to an "Hdot" threshold register with +.\" a default of 2. +.TP +.B H1dot +appends a period to the number of a level one heading; +see +.B H +(Boolean-valued; +.BR 1 ). +. +. +.\" XXX: This may be insufficiently general; see Savannah #62825. +.TP +.B H1h +is a copy of +A copy of register +.RB register\~ H1 , +but it is incremented just before a page break. +. +This can be useful in user-defined macros; +see +.B H +and +.BR HX . +. +. +.TP +.B Hb +sets the threshold for breaking the line after formatting a heading. +. +Text after headings at levels above this value are set on the same +output line if possible; +see +.B H +.RB ( 2 ). +. +. +.TP +.B Hc +sets the threshold for centering a heading. +. +Headings at levels above this value use the prevailing alignment +(that is, +they are not centered); +see +.B H +.RB ( 0 ). +. +. +.TP +.B Hi +configures the indentation of text after headings. +. +It does not affect \[lq]run-in\[rq] headings. +. +The following values are recognized; +see +.B H +and +.B P +.RB ( 1 ). +. +. +.IP +.TS +tab(@); +Lb Lb +L Lx. +Value@Effect +0@no indentation +1@indent per the paragraph type +2@indent to align with heading title +.TE +. +. +.TP +.B Hps +sets the heading level threshold for application of preceding vertical +space; +see +.BR H . +. +Headings at levels above the value in register +.B Hps +use the amount of space in register +.BR Hps1 ; +otherwise that in +.BR Hps2 . +. +The value of +.B Hps +should be strictly greater than that of +.B Ej +.RB ( 1 ). +. +. +.TP +.B Hps1 +configures the amount of vertical space preceding a heading above the +.B Hps +threshold; +see +.B H +.RI ( troff +devices: +.BR 0.5v ; +.I nroff +devices: +.BR 1v ). +. +. +.TP +.B Hps2 +configures the amount of vertical space preceding a heading at or below +the +.B Hps +threshold; +see +.B H +.RI ( troff +devices: +.BR 1v ; +.I nroff +devices: +.BR 2v ). +. +. +.TP +.B Hs +sets the heading level threshold for application of succeeding vertical +space. +. +If the heading level is greater than +.BR Hs , +the heading is followed by vertical space in the amount of +.RB register\~ Hss ; +see +.B H +.RB ( 2 ). +. +. +.TP +.B Hss +is multiplied by register +.B Lsp +to produce vertical space after headings above the +threshold in +.RB register\~ Hs ; +see +.B H +.RB ( 1 ). +. +. +.TP +.B Ht +suppresses output of heading level counters above the lowest when the +heading is formatted; +see +.B H +(Boolean-valued; +.BR 0 ). +. +. +. +.TP +.B Hu +sets the heading level used by unnumbered headings; +see +.B HU +.RB ( 2 ). +. +. +.TP +.B Hy +enables automatic hyphenation of words +(Boolean-valued; +.BR 0 ). +. +. +.TP +.B Iso +configures the use of ISO\~8601 date format +if specified +(with any value) +on the command line; +see +.BR ISODATE . +. +The default is determined by localization files. +. +. +.TP +.B L +defines the page length for the document, +and must be set from the command line. +. +A scaling unit should be appended. +. +The default is that of the selected +.I groff +output device. +. +. +.TP +.B Le +.TQ +.B Lf +.TQ +.B Lt +.TQ +.B Lx +configure the report of lists of equation, +figure, +table, +and exhibit captions, +respectively, +after a table of contents; +see +.B TC +(Boolean-valued; +.BR Le :\~ 0 ; +.BR Lf , +.BR Lt , +.BR Lx :\~ 1 ). +. +. +.\" XXX: What is the rationale for this feature? +.TP +.B Letwam +sets the maximum number of input lines permitted in a writer's address; +see +.B WA +and +.B WE +.RB ( 14 ). +. +. +.TP +.B Li +configures the amount of indentation in ens applied to list items; +see +.B LI +.RB ( 6 ). +. +. +.TP +.B Limsp +inserts a space between the prefix and the mark +in automatically numbered lists; +see +.B AL +(Boolean-valued; +.BR 1 ). +. +. +.TP +.B Ls +sets a threshold for placement of vertical space before list items. +. +If the list nesting level is greater than this value, +no such spacing occurs; +see +.B LI +.RB ( 99 ). +. +. +.TP +.B Lsp +configures the base amount of vertical space used for separation +in the document. +. +.I mm +applies this spacing to many contexts, +sometimes with multipliers; +see +.BR DS , +.BR FS , +.BR H , +.BR LI , +and +.B P +.RI ( troff +devices: +.BR 0.5v ; +.I nroff +devices: +.BR 1v ). +. +. +.TP +.B N +configures the header and footer placements used by +.BR PH . +. +The default footer is empty. +. +If \[lq]section-page\[rq] numbering is selected, +the default header becomes empty +and the default footer becomes +.RI \[lq] x - y \[rq], +where +.IR x \~is +is the section number +(the number of the current first-level heading) +.RI and\~ y +the page number within the section. +.\" XXX: section-figure numbering needs more documentation. +. +The following values are recognized; +for finer control, +see +.BR PH , +.BR PF , +.BR EH , +.BR EF , +.BR OH , +and +.BR OF , +and registers +.B Sectf +and +.BR Sectp . +. +Value 5 is a GNU extension +.RB ( 0 ). +. +. +.IP +.TS +tab(@); +Lb Lb +L Lx. +Value@Effect +0@Set header on all pages. +1@Move header to footer on page 1. +2@Omit header on page 1. +3@Use \[lq]section-page\[rq] numbering style on all pages. +4@Omit header on all pages. +5@T{ +Use \[lq]section-page\[rq] and \[lq]section-figure\[rq] \ +numbering style on all pages. +T} +.TE +. +. +.TP +.B Np +causes paragraphs after first-level headings (only) to be numbered +in the format +.IR s . p , +where +.IR s \~is +is the section number +(the number of the current first-level heading) +and +.IR p \~is +the paragraph number, +starting at 1; +see +.B H +and +.B P +(Boolean-valued; +.BR 0 ). +. +. +.TP +.B O +defines the page offset of the document, +and must be set from the command line. +. +A scaling unit should be appended. +. +The default +.RB is\~ \&.75i +on terminal devices. +. +On typesetters, +it is +.B \&.963i +or set to +.B 1i +by the +.I papersize.tmac +package; +see +.MR groff_tmac @MAN5EXT@ . +. +. +.TP +.B Oc +suppresses the appearance of page numbers in the table of contents; +see +.B TC +(Boolean-valued; +.BR 0 ). +. +. +.\" XXX: This really should just be a string, shouldn't it? +.TP +.B Of +selects a separator format within equation, +exhibit, +figure, +and table captions; +see +.BR EC , +.BR EX , +.BR FG , +and +.BR TB . +. +The following values are recognized; +the spaces shown are unpaddable +.RB ( 0 ). +. +. +.IP +.TS +tab(@); +Lb Lb +L Lx. +Value@Effect +0@\[dq]. \[dq] +1@\[dq] \[em] \[dq] +.TE +. +. +.TP +.B P +interpolates the current page number; +it is the same as +.RB register\~ % +except when +\[lq]section-page\[rq] numbering is enabled. +. +. +.TP +.B Pi +configures the amount of indentation in ens applied to the first line of +a paragraph; +see +.B P +.RB ( 5 ). +. +. +.TP +.B Pgps +causes the type size and vertical spacing set by +.B S +to apply to headers and footers, +overriding the +.B HP +string. +. +If not set, +.B S +calls affect headers and footers only when followed by +.BR PH , +.BR PF , +.BR OH , +.BR EH , +.BR OF , +or +.B OE +calls +(Boolean-valued; +.BR 1 ). +. +. +.TP +.B Ps +is multiplied by register +.B Lsp +to vertically separate paragraphs; +see +.B P +.RB ( 1 ). +. +. +.TP +.B Pt +determines when a first-line indentation is applied to a paragraph; +see +.B P +.RB ( 0 ). +. +. +.IP +.TS +tab(@); +Lb Lb +L Lx. +Value@Effect +0@never +1@always +2@T{ +always, +except immediately after +.BR H , +.BR DE , +or +.B LE +T} +.TE +. +. +.TP +.B Ref +is used internally to control +.MR mmroff 1 's +two-pass approach to index and reference management; +see +.B INITI +and +.B RS +(Boolean-valued; +.BR 0 ). +. +. +.\" XXX: Why is this not named `Rpej`? +.TP +.B Rpe +configures the default page ejection policy for reference pages; +see +.B RP +.RB ( 0 ). +. +. +.IP +.TS +tab(@); +Lb Lb +L Lx. +Value@Effect +0@Break the page before and after the list of references. +1@Suppress page break after the list. +2@Suppress page break before the list. +3@Suppress page breaks before and after the list. +.TE +. +. +.TP +.B S +defines the type size for the document, +and must be set from the command line. +. +A scaling unit should be appended; +.B p +is typical +.RB ( 10p ). +. +. +.TP +.B Sectf +selects the \[lq]section-figure\[rq] numbering style. +. +Its default +.RB is\~ 0 +unless +.RB register\~ N +is set +.RB to\~ 5 +at the command line +(Boolean-valued). +. +. +.TP +.B Sectp +selects the \[lq]section-page\[rq] numbering style. +. +Its default +.RB is\~ 0 +unless +.RB register\~ N +is set +.RB to\~ 3 +.RB or\~ 5 +at the command line +(Boolean-valued). +. +. +.TP +.B Si +configures the amount of display indentation in ens; +see +.B DS +.RB ( 5 ). +. +. +.TP +.B Tb +is an auto-incrementing table counter; +see +.BR TB . +. +. +.TP +.B V +defines the vertical spacing for the document, +and must be set from the command line. +. +A scaling unit should be appended; +.B p +is typical. +. +The default vertical spacing is 120% of the type size. +. +. +.TP +.B Verbin +configures the amount of indentation for verbatim displays +when indentation is selected; +see +.B \%VERBON +.RB ( 5n ). +. +. +.TP +.B W +defines the \[lq]width\[rq] +of the document +(that is, +the length of an output line with no indentation); +it must be set from the command line. +. +A scaling unit should be appended. +. +The default +.RB is\~ 6i +or assigned by the +.I papersize.tmac +package; +see +.MR groff_tmac @MAN5EXT@ . +. +. +. +.\" ==================================================================== +.SH Internals +.\" ==================================================================== +. +The +.B LT +letter macros call further macros depending on the letter type, +with which they are suffixed. +. +It is therefore possible to define additional letter types, +either in the territory-specific macro file, +or as local additions. +. +.B LT +sets the registers +.B Pt +and +.B Pi +to 0 and\~5, \" XXX: ...but doesn't use Pi for indentation... +respectively. +.\" XXX: and why aren't both of these actions the responsibility of +.\" let@init_type as described below? +. +The following macros must be defined to support a new letter type. +. +. +.TP +.BI let@init_ type +.B LT +calls this macro to initialize any registers and other data needed by +the letter type. +. +. +.TP +.BI let@head_ type +formats the letterhead; +it is called instead of the usual page header macro. +. +Its definition should remove the alias +.B let@header +unless the letterhead is desired on subsequent pages. +. +. +.TP +.BI let@sg_ type\~\c +.IR "name title n is-final\~" [ SG-arg\~ .\|.\|.] +.B SG +calls this macro only for letters; +.B MT +memoranda have their own signature processing. +. +.I name +and +.I title +are specified through +.BR WA / WE . +. +.IR n \~is +the index of the +.IR n th +writer, +and +.I is-final +is true for the last writer to be listed. +. +Further +.B SG +arguments are appended to the signature line. +. +. +.TP +.BI let@fc_ "type closing" +This macro is called by +.BR FC , +and has the formal closing as the argument. +. +. +.P +.B LO +implements letter options. +. +It requires that a string named +.BI Let type +be defined, +where +.I type +is the letter type. +. +.B LO +then assigns its second argument +.RI ( value ) +to the string +.BI let*lo\- type\c +\&. +. +. +.\" ==================================================================== +.\".SH BUGS +.\" ==================================================================== +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.I @MACRODIR@/@TMAC_M_PREFIX@m.tmac +is the +.I groff +implementation of the memorandum macros. +. +. +.TP +.I @MACRODIR@/mm.tmac +is wrapper to load +.IR m.tmac . +. +. +.TP +.I @MACRODIR@/refer\-mm.tmac +implements +.MR @g@refer @MAN1EXT@ +support for +.IR mm . +. +. +.TP +.I @TMAC_MDIR@/ms.cov +implements an +.IR ms -like +cover sheet. +. +. +.TP +.I @TMAC_MDIR@/0.MT +implements memorandum types 0\[en]3 and 6. +. +. +.TP +.I @TMAC_MDIR@/4.MT +implements memorandum type 4. +. +. +.TP +.I @TMAC_MDIR@/5.MT +implements memorandum type 5. +. +. +.TP +.I @TMAC_MDIR@/locale +performs any (further) desired necessary localization; +empty by default. +. +. +.\" ==================================================================== +.SH Authors +.\" ==================================================================== +. +The GNU version of the +.I mm +macro package was written by +.MT jh@\:axis\:.se +J\[:o]rgen H\[:a]gg +.ME +of Lund, Sweden. +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.UR https://tkurtbond\:.github\:.io/\:troff/\:mm\-all\:.pdf +.I MM \- A Macro Package for Generating Documents +.UE , +the DWB\~3.3 +.I mm +manual, +introduces the package but does not document GNU extensions. +. +. +.P +.IR "Groff: The GNU Implementation of troff" , +by Trent A.\& Fisher and Werner Lemberg, +is the primary +.I groff +manual. +. +You can browse it interactively with \[lq]info groff\[rq]. +. +. +.P +.MR groff @MAN1EXT@ , +.MR @g@troff @MAN1EXT@ , +.MR @g@tbl @MAN1EXT@ , +.MR @g@pic @MAN1EXT@ , +.MR @g@eqn @MAN1EXT@ , +.MR @g@refer @MAN1EXT@ , +.MR groff_mmse @MAN7EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_groff_mm_7_man_C] +.do rr *groff_groff_mm_7_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/contrib/mm/groff_mmse.7.man b/contrib/mm/groff_mmse.7.man new file mode 100644 index 0000000..6ba94eb --- /dev/null +++ b/contrib/mm/groff_mmse.7.man @@ -0,0 +1,183 @@ +.TH groff_mmse @MAN7EXT@ "@MDATE@" "groff @VERSION@" +.SH Namn +groff_mmse \- svenska \(rqmemorandum\(rq makro f\(:or GNU +.I roff +. +. +.\" Skrivet av Jörgen Hägg, Lund, Sverige +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1989-2020 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_groff_mmse_7_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Syntax +.\" ==================================================================== +. +.SY "groff \-m@TMAC_M_PREFIX@mse" +.RI [ flaggor\~ .\|.\|.\&] +.RI [ filer\~ .\|.\|.] +. +.SY "groff \-m m@TMAC_M_PREFIX@mse" +.RI [ flaggor\~ .\|.\|.\&] +.RI [ filer\~ .\|.\|.] +.YS +. +. +.\" ==================================================================== +.SH Beskrivning +.\" ==================================================================== +. +.I m@TMAC_M_PREFIX@mse +är en svensk variant av +.IR m@TMAC_M_PREFIX@m . +Alla texter är översatta. +En A4 sida fĺr text som är 13\~cm bred, +3,5\~cm indragning samt är 28,5\~cm hög. +Det finns stöd för brevuppställning enligt svensk standard +för vänster och högerjusterad text. +. +.LP +.B COVER +kan använda +.I se_ms +som argument. +Detta ger ett svenskt försättsblad. +Se +.MR groff_mm @MAN7EXT@ +för övriga detaljer. +. +. +.\" ==================================================================== +.SH Brev +.\" ==================================================================== +. +Tillgängliga brevtyper: +. +.TP +.B ".LT SVV" +Vänsterställd löptext med adressat i position T0 (vänsterställt). +. +.TP +.B ".LT SVH" +Högerställd löptext med adressat i position T4 (passar +fönsterkuvert). +. +.LP +Följande extra LO-variabler används. +. +.TP +.BI ".LO DNAMN\ " namn +Anger dokumentets namn. +. +.TP +.BI ".LO MDAT\ " datum +Mottagarens datum, anges under +.B Ert datum: +.RB ( LetMDAT ). +. +.TP +.BI ".LO BIL\ " sträng +Anger bilaga, nummer eller sträng med +.B Bilaga +.RB ( LetBIL ) +som prefix. +. +.TP +.BI ".LO KOMP\ " text +Anger kompletteringsuppgift. +. +.TP +.BI ".LO DBET\ " beteckning +Anger dokumentbeteckning eller dokumentnummer. +. +.TP +.BI ".LO BET\ " beteckning +Anger beteckning +(ärendebeteckning i form av diarienummer eller liknande). +. +.TP +.BI ".LO SIDOR\ " antal +Anger totala antalet sidor och skrivs ut efter sidnumret inom +parenteser. +. +.LP +Om makrot +.B .TP +är definierat anropas det efter utskrift av brevhuvudet. +Där lägger man lämpligen in postadress och annat som brevfot. +. +. +.\" ==================================================================== +.SH "Skrivet av" +.\" ==================================================================== +. +Jörgen Hägg, Lund, Sweden +. +. +.\" ==================================================================== +.SH Filer +.\" ==================================================================== +. +.TP +.I @MACRODIR@/@TMAC_M_PREFIX@mse.tmac +.TP +.IR @TMAC_MDIR@/se_ * .cov +. +. +.\" ==================================================================== +.SH "Se ocksĺ" +.\" ==================================================================== +. +.MR groff_mm @MAN7EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_groff_mmse_7_man_C] +.do rr *groff_groff_mmse_7_man_C +. +. +.\" Local Variables: +.\" coding: latin-1 +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/contrib/mm/m.tmac b/contrib/mm/m.tmac new file mode 100644 index 0000000..c679a70 --- /dev/null +++ b/contrib/mm/m.tmac @@ -0,0 +1,3734 @@ +.ig + +Copyright (C) 1991-2023 Free Software Foundation, Inc. +mm is written by Jörgen Hägg + +mm 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. + +mm 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 . + +Please submit bug reports using groff's 'BUG-REPORT' file to +http://savannah.gnu.org/bugs/?group=groff. + +Naming convention adapted from groff ms. +Local names module*name +Extern names module@name +Env.var environ:name +Index array!index +.. +.if !\n(.g \ +. ab groff mm macros require groff extensions; aborting +. +.if \n(.C \ +. ab groff mm macros do not work in compatibility mode; aborting +. +.ds @mm m.tmac\" +. +.if (\n[.x]\n[.y] < 123) \{\ +. ds mm-msg \*[@mm]: groff mm macros require groff 1.23 or later,\" +. as mm-msg " but found groff \n[.x].\n[.y]; aborting\" +. ab \*[mm-msg] +.\} +. +.if d PH .nx +. +.mso devtag.tmac +.\" ######## init ####### +.\" create table of contents entry for headings of level <= Cl +.nr Cl 2 +.\" Eject page between LIST OF XXXX if Cp == 0 +.nr Cp 0 +.\" Debugflag +.if !r D .nr D 0 +.\" Eject after floating display is output [0:1] +.nr De 0 +.\" Floating keep output [0;5] +.nr Df 5 +.\" space before and after display if == 1 [0:1] +.nr Ds 1 +.\" eject page before headings of level <= Ej +.nr Ej 0 +.\" Equation label adjust 0=left, 1=right +.nr Eq 0 +.\" Bullet string (for .BL) +.ie n .ds BU \[bu] +.el .ds BU \s-2\[bu]\s0 +.\" Em dash string +.ie n .ds EM " -- +.el .ds EM \[em] +.\" Footnote spacing +.nr Fs 1 +.\" H1-H7 heading counters +.nr H1 0 1 +.nr H2 0 1 +.nr H3 0 1 +.nr H4 0 1 +.nr H5 0 1 +.nr H6 0 1 +.nr H7 0 1 +.nr H8 0 1 +.nr H9 0 1 +.nr H10 0 1 +.nr H11 0 1 +.nr H12 0 1 +.nr H13 0 1 +.nr H14 0 1 +.\" break after headings of level <= Hb +.nr Hb 2 +.\" center headings of level <= Hc +.nr Hc 0 +.\" header format +.ds HF 2 2 2 2 2 2 2 2 2 2 2 2 2 2 +.\" heading temp. indent [0:2] +.\" 0 -> 0 indent, left margin +.\" 1 -> indent to right , like .P 1 +.\" 2 -> indent to line up with text part of preceding heading +.nr Hi 1 +.\" header pointsize +.ds HP 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +.\" put vertical space of \n[Hss] after headings of level <= Hs +.nr Hs 2 +.\" heading numbering type +.\" 0 -> multiple (1.1.1 ...) +.\" 1 -> single +.nr Ht 0 +.\" Unnumbered heading level +.nr Hu 2 +.\" hyphenation in body +.\" 0 -> no hyphenation +.\" 1 -> hyphenation 14 on +.nr Hy 0 +.\" text for toc, selfexplanatory. Look in the new variable section +.ds Lf LIST OF FIGURES +.nr Lf 1 +.ds Lt LIST OF TABLES +.nr Lt 1 +.ds Lx LIST OF EXHIBITS +.nr Lx 1 +.ds Le LIST OF EQUATIONS +.nr Le 0 +.\" List indentation in ens, used by .AL +.nr Li 6 +.\" put vertical space before list items of nesting level <= Ls +.nr Ls 99 \" TODO: use \n[.R]; see Savannah #63587 +.\" Numbering style [0:5] +.if !r N .nr N 0 +.\" numbered paragraphs +.\" 0 == not numbered +.\" 1 == numbered in first level headings. +.nr Np 0 +.\" Format of figure,table,exhibit,equation titles. +.\" 0= ". ", 1=" - " +.nr Of 0 +.\" Table of contents page numbering style +.nr Oc 0 +.\" Page-number, normally same as %. +.nr P 0 +.\" paragraph indentation in ens +.nr Pi 5 +.\" paragraph spacing +.nr Ps 1 +.\" paragraph type +.\" 0 == left-justified +.\" 1 == indented .P +.\" 2 == indented .P except after .H, .DE or .LE. +.nr Pt 0 +.\" Reference title +.ds Rp REFERENCES +.\" Reference page eject status +.nr Rpe 0 +.\" display indentation in ens +.nr Si 5 +.\" +.\" Current state of TOC, empty outside TC, inside +.\" it will be set to co,fg,tb,ec,ex or ap. +.ds Tcst +.\" +.ie t .ds Sm \v'-.4m'\s-3SM\s0\v'.4m'\" +.el \{\ +. ie c \[u2120] .ds Sm \[u2120]\" +. el .ds Sm (SM)\" +.\} +. +.ie t .ds Tm \v'-.4m'\s-3TM\s0\v'.4m'\" +.el \{\ +. ie c \[tm] .ds Tm \[tm]\" +. el .ds Tm (TM)\" +.\} +.\" +.\"--------------------------------------------- +.\" Internal global variables +.\" +.\" This is for cover macro .MT +.\" .ds @country +.\" +.nr @copy_type 0 +.if r C .nr @copy_type \n[C] +.\" >0 if Subject/Date/From should be bold, roman otherwise +.ie n .ds @sdf_font R +.el .ds @sdf_font B +.if \n[@copy_type]=4 \{\ +. ls 2 +. nr Pi 10 +. nr Pt 1 +.\} +.\" +.\" +.if r E \{\ +. ie \n[E] .ds @sdf_font B +. el .ds @sdf_font R +.\} +.\" +.\" Set the type size and vertical spacing. If given on the command +.\" line, these have already been converted to basic units. +.if !r S .nr S 10 +.ie (\n[S] >= 1000) .ps \n[S]z/1000u +.el .ps \n[S] +.nr *vs-default \n[.ps]*120/100 +.if !r V .nr V \n[*vs-default] +.ie (\n[V] >= 1000) .vs \n[V]p/1000u +.el .vs \n[V] +.rm *vs-default +.\" +.nr @ps \n[.ps] +.nr @vs \n[.v] +.if \n[D]>1 .tm @ps=\n[@ps], @vs=\n[@vs] +.if \n[D]>3 .tm INIT: l:\n[.l] p:\n[.p] o:\n[.o] +.\" +.\" page length +.if r L \{\ +. pl \n[L]u +.\} +.nr @pl \n[.p] +.\" +.\" line length +.ie r W \{\ +. ll \n[W]u +.\} +.el .ll 6i +.nr @ll \n[.l] +.nr @cur-ll \n[@ll] +.lt \n[@ll]u +.\" +.\" page offset +.ie r O .po \n[O]u +.el \{\ +. ie n .po .75i +. el .po .963i +.\} +.\" +.nr @po \n[.o] +.\" +.\" non-zero if escape mechanism is turned off. Used by VERBON/OFF +.nr @verbose-flag 0 +.\"--------------------------------------------- +.\" New variables +.\" +.\" Appendix name +.ds App APPENDIX +.\" print appendixheader, 0 == don't +.nr Aph 1 +.\" +.\" Current appendix text +.ds Apptext +.\" Controls the space before and after static displays if defined. +.\" Lsp is used otherwise +.\" .nr Dsp 1v +.\" +.\" Add a dot after level one heading number if >0 +.nr H1dot 1 +.\" +.\" put vertical space of \n[Hps2] before headings of level <= Hps +.nr Hps 1 +.\" +.\" amount of vertical space before headings when level > Hps +.nr Hps1 0.5v +.if n .nr Hps1 1v +.\" +.\" amount of vertical space before headings when level <= Hps +.nr Hps2 1v +.if n .nr Hps2 2v +.\" +.\" Hss is the number of lines (Lsp) after the header. +.nr Hss 1 +.\" +.\" H1txt will be updated by .H and .HU, containing the heading text. +.\" Will also be updated in table of contents & friends +.\" +.ds H1txt +.\" +.\" header text for the index +.ds Index INDEX +.\" command to sort the index +.ds Indcmd sort +.\" +.\" flag for mkindex +.if !r Idxf .nr Idxf 0 +.\" Change these in the national configuration file +.ds Lifg Figure +.ds Litb TABLE +.ds Liex Exhibit +.ds Liec Equation +.ds Licon CONTENTS +.\" Flag for space between mark and prefix 1==space, 0==no space +.\" Can also be controlled by using '.LI mark 2' +.nr Limsp 1 +.\" +.\" Lsp controls the height of an empty line. Normally 0.5v +.\" Normally used for nroff compatibility. +.nr Lsp 0.5v +.if n .nr Lsp 1v +.ds MO1 January +.ds MO2 February +.ds MO3 March +.ds MO4 April +.ds MO5 May +.ds MO6 June +.ds MO7 July +.ds MO8 August +.ds MO9 September +.ds MO10 October +.ds MO11 November +.ds MO12 December +.\" for GETR +.ds Qrf See chapter \\*[Qrfh], page \\*[Qrfp]. +.\" +.\" header- and footer-size will only change to the current +.\" if Pgps is > 0. +.nr Pgps 1 +.\" +.\" section-page if Sectp > 0 +.nr Sectp 0 +.if (\n[N]=3):(\n[N]=5) \{\ +. nr Sectp 1 +. nr Ej 1 +.\} +.\" section-figure if Sectf > 0 +.nr Sectf 0 +.if \n[N]=5 .nr Sectf 1 +.\" +.\" argument to .nm in .VERBON. +.ds Verbnm 1\" +.\" indent for VERBON +.nr Verbin 5n +.\" +.\" Letter section +.\" Formal closing (.FC) +.ds Letfc Yours very truly, +.\" +.\" Approval line +.ds Letapp APPROVED: +.\" Approval date-string +.ds Letdate Date +.\" +.ds LetCN CONFIDENTIAL\" Confidential default +.ds LetSA To Whom It May Concern:\" Salutation default +.ds LetAT ATTENTION:\" Attention string +.ds LetSJ SUBJECT:\" Subject string +.ds LetRN In reference to:\" Reference string +.\" +.\" Copy to (.NS) +.ds Letnsdef 0 +.ds Letns!copy Copy \" space! +.ds Letns!to " to +.ds Letns!0 Copy to +.ds Letns!1 Copy (with att.\&) to +.ds Letns!2 Copy (without att.\&) to +.ds Letns!3 Att. +.ds Letns!4 Atts. +.ds Letns!5 Enc. +.ds Letns!6 Encs. +.ds Letns!7 Under separate cover +.ds Letns!8 Letter to +.ds Letns!9 Memorandum to +.ds Letns!10 Copy (with atts.\&) to +.ds Letns!11 Copy (without atts.\&) to +.ds Letns!12 Abstract Only to +.ds Letns!13 Complete Memorandum to +.ds Letns!14 CC: +.\" +.\" Text printed below the footer. Controlled by @copy_type (C). +.ds Pg_type!0 +.ds Pg_type!1 OFFICIAL FILE COPY +.ds Pg_type!2 DATE FILE COPY +.ds Pg_type!3 D\ R\ A\ F\ T +.ds Pg_type!4 D\ R\ A\ F\ T +.\" Max lines in return address +.nr Letwam 14 +.\"-------------------------- +.\" test for mgm macro. This can be used if the text must test +.\" what macros is used. +.nr .mgm 1 +.\" +.\" Due to security problems with groff I had to rewrite +.\" the reference system. It's not as elegant as before, you +.\" have to run groff with '-z -rRef=1' and put stderr into the filename +.\" for .INITR +.\" +.\" Output references to stderr if non-zero +.ie !r Ref \{\ +. nr Ref 0 +.\} +.el .warn 0 +.\" +.\"--------------------------------------------- +.\" set local variables. +.ie d @country .msoquiet mm/\*[@country]_locale +.el .msoquiet mm/locale +.\"--------------------------------------------- +.\" ####### module init ###### +.\" reset all things +.\" XXX: Resets .cu and .ul but _not_ .ce or .rj. +.de init@reset +.ie \\n[misc@adjust] 'ad +.el 'na +.ie \\n[Hy] 'hy 14 +.el 'nh +'in 0 +'ti 0 +.ps \\n[@ps]u +.vs \\n[@vs]u +.. +.de @warning +.tm \\*[@mm]:\\n[.F]:\\n[.c]: warning: \\$* +.if \\n[D] .backtrace +.. +.\" All errors are fatal. +.de @error +.tm \\*[@mm]:\\n[.F]:\\n[.c]: error: \\$* +.if \\n[D] .backtrace +.ab +.. +. +.de @abort +.tm \\*[@mm]:\\n[.F]:\\n[.c]: internal error: \\$* +.backtrace +.ab +.. +.de misc@toupper +.tr aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ +.br +\\$1 +.tr aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz +.br +.. +.\" ####### module debug ################################# +.de debug +'tm \\$1:\\n[.F]:\\n[c.] ll=\\n[.l] vs=\\n[.v] ps=\\n[.s],\\n[.ps] \ +in=\\n[.i] fi=\\n[.u] .d=\\n[.d] nl=\\n[nl] pg=\\n[%] +.. +.de debug-all +.nr debug*n 1n +.nr debug*m 1m +'tm \\$1:\\n[.F]:\\n[c.] ll=\\n[.l] vs=\\n[.v] ps=\\n[.s] in=\\n[.i]\ + ad=\\n[.j] fi=\\n[.u] pl=\\n[.p] page=\\n[%] .o=\\n[.o] +'tm _______ .d=\\n[.d] .f=\\n[.f] .h=\\n[.h] .k=\\n[.k] .n=\\n[.n]\ + .p=\\n[.p] .t=\\n[.t] .z=\\n[.z] nl=\\n[nl] dn=\\n[dn] n=\\n[debug*n] +.. +.\" ####### module par ################################# +.nr par*indentation-eligible 1 \" indent following P if Pt=2 +.nr par@suppress-indentation 0 +.nr hd*last-pos -1 +.nr hd*last-hsize -1 +.nr par*number 0 1 +.af par*number 01 +.nr par*number2 0 1 +.af par*number2 01 +.nr par*num-count 0 1 +.af par*num-count 01 +.\" reset numbered paragraphs, arg1 = headerlevel +.de par@reset-num +.if \\$1<3 .nr par*num-count 0 +.if (\\$1=1)&(\\n[Np]=1) .nr par*number 0 +.. +.\"------------ +.\" paragraph +.de P +.if \\n[.$] \{\ +. ie !\B'\\$1' \{\ +. @warning \\$0: expected numeric argument, got '\\$1' +. shift +. \} +. el .if (\\$1 > 1) \ +. @warning \\$0: ignoring unsupported paragraph type \ +'\\$1' +.\} +.\" skip P if previous heading +.if \\n[D]>2 \{\ +. tm Paragraph nl=\\n[nl], last=\\n[hd*last-pos] +. tm Paragraph .k=\\n[.k], hsize=\\n[hd*last-hsize] +.\} +.nr par*indentation-eligible 1-\\n[par@suppress-indentation] +.par@doit \\$* +.if \\n[Np] \\n[H1].\\n+[par*number]\ \ \c +.. +.\"------------ +.de nP +.if \\n[D]>2 \{\ +. tm Paragraph nl=\\n[nl], last=\\n[hd*last-pos] +. tm Paragraph .k=\\n[.k], hsize=\\n[hd*last-hsize] +.\} +.\" A first-line indentation is meaningless for a numbered paragraph. +.nr par*indentation-eligible 0 +.par@doit +\\n[H2].\\n+[par*number2]\ \ \c +.. +.\"------------ +.de par@doit +.SP (u;\\n[Ps]*\\n[Lsp]) +.nr par*do-indent 0 +.ie \\n[.$] \{\ +. if \\$1=1 .nr par*do-indent 1 +.\} +.el \{\ +. if \\n[Pt]=1 .nr par*do-indent 1 +. if (\\n[Pt]=2)&\\n[par*indentation-eligible] \ +. nr par*do-indent 1 +.\} +.if \\n[par*do-indent] .ti +\\n[Pi]n +.rr par*do-indent +.nr par@suppress-indentation 0 +.. +.\" ####### module line ####################################### +.de SP +.br +.if !r line*lp\\n[.z] .nr line*lp\\n[.z] 0 +.if !r line*ac\\n[.z] .nr line*ac\\n[.z] 0 +.ie \\n[.$] .nr line*temp (v;\\$1) +.el .nr line*temp 1v +.\" +.ie \\n[line*lp\\n[.z]]=\\n[.d] \{\ +. \" go here if no output since the last .SP +. nr line*output \\n[line*temp]-\\n[line*ac\\n[.z]] +. if \\n[line*output]<0 .nr line*output 0 +. nr line*ac\\n[.z] +\\n[line*output] +.\} +.el \{\ +. nr line*ac\\n[.z] \\n[line*temp] +. nr line*output \\n[line*temp] +. \" no extra space in the beginning of a page +. if (\\n[.d]<0):(\\n[pg*head-mark]=\\n[.d]) .nr line*output 0 +.\} +.if \\n[line*output] .sp \\n[line*output]u +.nr line*lp\\n[.z] \\n[.d] +.. +.\" ######## module misc ############### +.\" XXX: This register value is meaningless. +.\" .ad b +.\" .nr misc@adjust \n[.j] +.\" might be better... +.nr misc@adjust 14 +.de SA +.if \\n[.$] \{\ +. if ((\\$1 < 0) : (\\$1 > 1)) .@error \\$0: invalid argument \ +'\\$1' +.\" XXX: ...then... +.\" .ad l +.\" .nr misc@adjust \\n[.j] +. nr misc@adjust 0\\$1 +.\} +.\" XXX: ...and finally an unconditional. +.\" .ad \\n[.j] +.ie \\n[misc@adjust] 'ad +.el 'na +.. +.\"------------- +.\" switch environment, keep all important settings. +.de misc@ev-keep +.nr misc*ll \\n[.l] +.ds misc*fam \\n[.fam] +.ev \\$1 +.ll \\n[misc*ll]u +.lt \\n[misc*ll]u +.fam \\*[misc*fam] +.. +.\"------------- +.\" .misc@push stackname value +.de misc@push +.ie d misc*st-\\$1 .ds misc*st-\\$1 \\$2 \\*[misc*st-\\$1] +.el .ds misc*st-\\$1 \\$2 +.. +.\"------------- +.\" .misc@pop stackname +.\" value returned in the string misc*pop +.de misc@pop +.misc@pop-set misc*st-\\$1 \\*[misc*st-\\$1] +.. +.\"------------- +.de misc@pop-set +.ds misc*st-name \\$1 +.shift +.if \\n[.$]<1 .@abort stack '\\*[misc*st-name]' empty +.ds misc*pop \\$1 +.shift +.ds \\*[misc*st-name] \\$* +.. +.\"------------- +.\" .misc@pop-nr stackname varname +.de misc@pop-nr +.misc@pop \\$1 +.nr \\$2 0\\*[misc*pop] +.. +.\"------------- +.\" .misc@pop-ds stackname varname +.de misc@pop-ds +.misc@pop \\$1 +.ds \\$2 \\*[misc*pop] +.. +.\"----------- +.\" reset tabs +.de TAB +.ta T 5n +.. +.\"------------- +.\" .PGFORM linelength [ pagelength [ pageoffset [1]]] +.de PGFORM +.\" Break here to avoid problems with new linesetting of the previous line. +.\" Hope this doesn't break anything else :-) +.\" Don't break if arg_4 is a '1'. +.if \\n[D]>2 .tm PGFORM: \\$* +.if ''\\$4' .br +.if \\n[D]>3 .tm PGFORM: IN l:\\n[.l] p:\\n[.p] o:\\n[.o] +.ie !''\\$1' \{\ +. ll \\$1 +. nr @ll \\n[.l] +. nr @cur-ll \\n[@ll] +. lt \\n[@ll]u +.\} +.el \{\ +. ll \\n[@ll]u +. lt \\n[@ll]u +.\} +.\" +.ie !''\\$2' \{\ +. pl \\$2 +. nr @pl \\n[.p] +.\} +.el .pl \\n[@pl]u +.\" +.ie !''\\$3' \{\ +. po \\$3 +. nr @po \\n[.o] +.\} +.el .po \\n[@po]u +.if \\n[D]>3 .tm PGFORM: OUT l:\\n[.l] p:\\n[.p] o:\\n[.o] +.if \\n[D]>2 .tm PGFORM: ll=\\n[@ll], pl=\\n[@pl], po=\\n[@po] +'in 0 +.pg@move-trap +.if \\n[D]>2 \{\ +. tm Traps: +. ptr +.\} +.. +.\"------------- +.\" .MOVE y [[x] linelength] +.\" move to line y, indent to x +.de MOVE +.if !\\n[.$] \{\ +. @warning \\$0: ignoring; no arguments specified +. return +.\} +.if \\n[nl]<0 \c +.\" move to Y-pos +.sp |(v;\\$1) +.\" calc linelength +.ie \\n[.$]>2 .nr pg*i (n;\\$3) +.el \{\ +. ie \\n[.$]>1 .nr pg*i (n;\\n[@ll]u-\\$2) +. el .nr pg*i \\n[@ll]u +.\} +.\" move to X-pos, if any +.if !''\\$2' .po \\$2 +.\" set linelength +.ll \\n[pg*i]u +.. +.\"------------- +.de SM +.if !\\n[.$] \{\ +. @warning \\$0: ignoring; no arguments specified +. return +.\} +.if \\n[.$]=1 \s-1\\$1\s0 +.if \\n[.$]=2 \s-1\\$1\s0\\$2 +.if \\n[.$]=3 \\$1\s-1\\$2\s0\\$3 +.. +.\"------------- +.nr misc*S-ps \n[@ps] +.nr misc*S-vs \n[@vs] +.nr misc*S-ps1 \n[@ps] +.nr misc*S-vs1 \n[@vs] +.ds misc*a +.ds misc*b +.de S +.ie !\\n[.$] \{\ +. ds misc*a P +. ds misc*b P +.\} +.el \{\ +. ie \\n[.$]=1 .ds misc*b D +. el \{\ +. ie \w@\\$2@=0 .ds misc*b C +. el .ds misc*b \\$2 +. \} +. ie \w@\\$1@=0 .ds misc*a C +. el .ds misc*a \\$1 +.\} +.\" +.\" set point size +.if !'\\*[misc*a]'C' \{\ +. ie '\\*[misc*a]'P' .ps \\n[misc*S-ps]u +. el \{\ +. ie '\\*[misc*a]'D' .ps \\n[S] +. el .ps \\*[misc*a] +. if \\n[D]>2 .tm S: .ps \\*[misc*a] +. \} +.\} +.\" +.\" set vertical spacing +.if !'\\*[misc*b]'C' \{\ +. ie '\\*[misc*b]'P' .vs \\n[misc*S-vs]u +. el \{\ +. ie '\\*[misc*b]'D' .vs \\n[.ps]s+2p +. el .vs \\*[misc*b] +. if \\n[D]>2 .tm S: .vs \\*[misc*b] +. \} +.\} +.nr @ps \\n[.ps] +.nr @psu \\n[.ps]s +.nr @vs \\n[.v] +.nr @vsp \\n[.v]u/1p +.nr @res 1i +.\" +.if \\n[D]>1 \{\ +. tmc "S(\\$*): ma:\\*[misc*a], mb:\\*[misc*b] +. tm1 " => ps:\\n[.s]p (\\n[@psu]u), vs:\\n[@vsp]p (\\n[@vs]u) (res:\\n[@res]) +.\} +.nr misc*S-ps \\n[misc*S-ps1] +.nr misc*S-vs \\n[misc*S-vs1] +.nr misc*S-ps1 \\n[@ps] +.nr misc*S-vs1 \\n[@vs] +.pg@move-trap +.. +.\"------------ +.de HC +.ev 0 +.hc \\$1 +.ev +.ev 1 +.hc \\$1 +.ev +.ev 2 +.hc \\$1 +.ev +.. +.\"------------ +.de RD +.di misc*rd +'fl +.rd \\$1\t +.br +.di +.if !''\\$3' \{\ +. di misc*rd2 +. ds \\$3 "\\*[misc*rd] +. br +. di +.\} +.if !''\\$2' .rn misc*rd \\$2 +.rm misc*rd misc*rd2 +.. +.\"------------ +.\" VERBON [flag [type-size [font]]] +.\" flag +.\" bit function +.\" 0 escape character disablement +.\" 1 add an empty line before verbose text +.\" 2 add an empty line after verbose text +.\" 3 number output lines using Verbnm string for .nm args +.\" 4 indent text by amount in register Verbin +.de VERBON +.br +.nr misc*verb 0\\$1 +.if (0\\n[misc*verb]%4)/2 .SP \\n[Lsp]u +.misc@ev-keep misc*verb-ev +.nf +.if (0\\n[misc*verb]%16)/8 .nm \\*[Verbnm] +.ie !'\\$3'' .ft \\$3 +.el .ft CR +.ie 0\\$2 \{\ +. ss \\$2 +. ps \\$2 +. vs \\$2 +.\} +.el .ss 12 +.ta T 8u*\w@n@u +.if (0\\n[misc*verb]%32)/16 .in +\\n[Verbin]u +.if 0\\n[misc*verb]%2 \{\ +. eo +. nr @verbose-flag 1 \" tell pageheader to set ec/eo +.\} +.. +.de VERBOFF +.ec +.br +.if (0\\n[misc*verb]%8)/4 .SP \\n[Lsp]u +.if (0\\n[misc*verb]%16)/8 .nm +.if (0\\n[misc*verb]%32)/16 .in +.ev +.nr @verbose-flag 0 +.. +.\" Wrapper to cancel the side effect of .tag + .br generating +.\" unwanted vertical space. +.de misc@tag +.\" This macro is currently used solely to give information to the +.\" HTML postprocessor. If for PostScript or PDF output macro .H +.\" had been followed by .DS both .H post-space and .DS pre-space +.\" had been output because of this macro. So it is now enabled +.\" only when postprocessor tags are required. +.if '\*[.T]'html' \{\ +.\" retain temporary indentation and horizontal position +.if !(\\n[.in]-\\n[.i]=0) .nr misc*ti \\n[.in] +.nr misc*.k \\n[.k] +.vpt 0 +.DEVTAG-\\$1 \\$2 +.br +.if r misc*ti \{\ +. ti \\n[misc*ti]u +. rr misc*ti +. sp -1 +.\} +.sp -1 +\h'\\n[misc*.k]u'\c +.rr misc*.k +.vpt 1 +.\} +.. +.\" ######## module pict ################# +.nr pict*width 0 +.nr pict*height 0 +.nr pict*mode 0 +.nr pict*ind 0 +.nr pict*id 0 1 +.\" I assume that the number variable pict*id is the same +.\" between two runs. +.de PIC +.br +.nr pict*ind 0 +.nr pict*box 0 +.while \\n[.$]>0 \{\ +. if '-B'\\$1' \{\ +. nr pict*box 1 +. shift +. continue +. \} +. if '-L'\\$1' \{\ +. nr pict*mode 0 +. shift +. continue +. \} +. if '-R'\\$1' \{\ +. nr pict*mode 1 +. shift +. continue +. \} +. if '-I'\\$1' \{\ +. nr pict*ind (m;\\$2) +. nr pict*mode 2 +. shift 2 +. continue +. \} +. if '-C'\\$1' \{\ +. nr pict*mode 3 +. shift +. continue +. \} +. ds pict*f \\$1 +. nr pict*id +1 +. shift +. if \\n[.$]>0 \{\ +. if !\B'\\$1' .@error \\$0: width parameter is not \ +numeric; got '\\$1' +. nr pict*width (i;\\$1) +. shift +. \} +. if \\n[.$]>0 \{\ +. if !\B'\\$1' .@error \\$0: height parameter is not \ +numeric; got '\\$1' +. nr pict*height (i;\\$1) +. shift +. \} +.\} +.\" let mmroff know the filename and id +.if \\n[Ref]>0 \{\ +. tm .\\\\" PIC id \\n[pict*id] +. tm .\\\\" PIC file \\*[pict*f] +.\} +.\" these are defined by mmroff in the second pass +.if d pict*file!\\n[pict*id] \{\ +. ds pict*f \\*[pict*file!\\n[pict*id]] +. nr pict*llx \\n[pict*llx!\\n[pict*id]] +. nr pict*lly \\n[pict*lly!\\n[pict*id]] +. nr pict*urx \\n[pict*urx!\\n[pict*id]] +. nr pict*ury \\n[pict*ury!\\n[pict*id]] +. \" +. nr pict*w (p;\\n[pict*urx]-\\n[pict*llx]) +. if \\n[pict*w]<0 .nr pict*w 0-\\n[pict*w] +. nr pict*h (p;\\n[pict*ury]-\\n[pict*lly]) +. if \\n[pict*h]<0 .nr pict*h 0-\\n[pict*h] +. if \\n[pict*width]>0 \{\ +. nr pict*rs (u;1000*\\n[pict*width]/\\n[pict*w]) +. nr pict*w (u;\\n[pict*w]*\\n[pict*rs]/1000) +. nr pict*h (u;\\n[pict*h]*\\n[pict*rs]/1000) +. \} +. if \\n[pict*height]>0 \{\ +. nr pict*rs (u;1000*\\n[pict*height]/\\n[pict*h]) +. nr pict*h (u;\\n[pict*h]*\\n[pict*rs]/1000) +. \} +. if '0'\\n[pict*mode]' \{\ +. nr pict*in \\n[.i]u +. \} +. if '1'\\n[pict*mode]' \{\ +. nr pict*in (u;\\n[.l]-\\n[.i]-\\n[pict*w]) +. \} +. if '2'\\n[pict*mode]' \{\ +. nr pict*in \\n[pict*ind]u +. \} +. if '3'\\n[pict*mode]' \{\ +. nr pict*in (u;(\\n[.l]-\\n[.i]-\\n[pict*w])/2) +. \} +. ds pict*h " +. if \\n[pict*h]>0 .ds pict*h \\n[pict*h] +. \" +. ne \\n[pict*h]u-1v +. \" +. \" these lines are copied and modified from pspic.tmac. +. \" Originally written by James Clark +. br +. ie \\n[pict*box]>0 \{\ +\v'-1v'\h'\\n[pict*in]u'\ +\Z'\D'p 0 \\n[pict*h]u \\n[pict*w]u 0 0 -\\n[pict*h]u''\ +\v'\\n[pict*h]u'\X'ps: import \\*[pict*f] \ +\\n[pict*llx] \\n[pict*lly] \ +\\n[pict*urx] \\n[pict*ury] \ +\\n[pict*w] \\n[pict*h]' +.\} +. el \{\ +\v'-1v'\h'\\n[pict*in]u'\ +\X'ps: invis'\ +\Z'\D'p 0 \\n[pict*h]u \\n[pict*w]u 0 0 -\\n[pict*h]u''\ +\X'ps: endinvis'\ +\v'\\n[pict*h]u'\X'ps: import \\*[pict*f] \ +\\n[pict*llx] \\n[pict*lly] \ +\\n[pict*urx] \\n[pict*ury] \ +\\n[pict*w] \\n[pict*h]' +. \} +. br +. sp \\n[pict*h]u-1v +.\} +.. +.\" external picture +.\" -L left align +.de EPIC +.nr pict*adj 0 \" centered +.if '\\$1'-L' \{\ +. shift +. nr pict*adj 1 +.\} +.if \\n[.$]<2 \{\ +. @warning \\$0: ignoring; expected width and height arguments +. return +.\} +.\" Permit a document to start with EPIC. +.if \\n[nl]<0 \& +.ie \B'\\$1' .nr pict*w \\$1 +.el .@error \\$0: width parameter is not numeric; got '\\$1' +.ie \B'\\$2' .nr pict*h \\$2 +.el .@error \\$0: height parameter is not numeric; got '\\$2' +.\" XXX: This is kind of lame. It's also not localized. +.ds pict*name External picture\" +.if !''\\$3' .ds pict*name " \\$3\" +.ne \\n[pict*h]u +.sp \\n[pict*h]u-1v +.nr pict*ind 0 +.if !\\n[pict*adj] .nr pict*ind (u;(\\n[.l]-\\n[.i]-\\n[pict*w])/2) +.mk +.in +\\n[pict*ind]u +\D'l \\n[pict*w]u 0'\ +\D'l 0 -\\n[pict*h]u'\ +\D'l -\\n[pict*w]u 0'\ +\D'l 0 \\n[pict*h]u'\ +\v'-(u;\\n[pict*h]/2)'\ +\h'(u;(\\n[pict*w]-\w'\\*[pict*name]'/2))'\\*[pict*name] +.in +.rt +.sp 1v +.. +.\" ######## module acc ################# +.\"----------- +.\" accents. These are copied from mgs, written by James Clark. +.de acc@over-def +.ds \\$1 \Z'\v'(u;\w'x'*0+\En[rst]-\En[.cht])'\ +\h'(u;-\En[skw]+(-\En[.w]-\w'\\$2'/2)+\En[.csk])'\\$2' +.. +.de acc@under-def +.ds \\$1 \Z'\v'\En[.cdp]u'\h'(u;-\En[.w]-\w'\\$2'/2)'\\$2' +.. +.acc@over-def ` \` +.acc@over-def ' \' +.acc@over-def ^ ^ +.acc@over-def ~ ~ +.acc@over-def : \[ad] +.acc@over-def ; \[ad] +.acc@under-def , \[ac] +.\" ######## module uni ################# +.\" unimplemented macros +.de @disable +.ds @end \" empty +.while \\n[.$] \{\ +. rm \\$1 \" in case it's aliased +. de \\$1 @end +. @warning \\$1: ignoring; unavailable after \\*[@cover] +. @end +. shift +.\} +.. +.rm @end +. +.de CS +.@warning \\$0: not implemented except with ".MT 4" +.. +.de OK +.@warning \\$0: not implemented +.. +.de PM +.@warning \\$0: not implemented +.. +.\" ######## module hd ################# +.\" support for usermacro +.nr hd*h1-page 1 \" last page-number for level 1 header. +.nr hd*htype 0 +.ds hd*sect-pg +.ds hd*mark +.ds hd*suf-space +.nr hd*need 0 +.aln ;0 hd*htype +.als }0 hd*mark +.als }2 hd*suf-space +.aln ;3 hd*need +.\"------------- +.\" .hd@split variable index name val1 val2 ... +.de hd@split +.\" TODO: Verify that this isn't reachable due to ordinary user error; +.\" if it is, make it an @error. +.if \\$2>(\\n[.$]-3) .@abort \\$3 must have at least \\$2 values \ +(\\*[\\$3]) +.nr hd*sp-tmp \\$2+3 +.ds \\$1 \\$[\\n[hd*sp-tmp]] +.. +.de HU +.H 0 "\\$1" +.. +.\"------------- +.de H +.if !r hd*cur-bline .nr hd*cur-bline \\n[nl] +.br +.df@print-float 2\" $$$ could be wrong... +.\" terminate all lists +.LC +.init@reset +.nr hd*level 0\\$1 +.nr hd*arg1 0\\$1 +.if !\\n[hd*level] .nr hd*level \\n[Hu] +.\" +.\" clear lower counters +.nr hd*i 1 1 +.while \\n+[hd*i]<15 .if \\n[hd*level]<\\n[hd*i] .nr H\\n[hd*i] 0 1 +.\" +.\" save last text for use in TP +.if \\n[hd*level]=1 .ds H1txt \\$2\\$3 +.\" +.\" This is a little fix to be able to get correct H1 heading number +.\" in page headers. Special attention was needed when other formats are used. +.ie !''\\g[H1]' \{\ +. ds hd*format \\g[H1] +. af H1 0 +. nr H1h \\n[H1] 1 +. af H1 \\*[hd*format] +.\} +.el .nr H1h \\n[H1] 1 +.if \\n[hd*level]=1 .nr H1h +1 +.\" +.\" Break page before headings of level <= Ej. +.if ((\\n[hd*level]<=\\n[Ej])&(\\n[nl]>\\n[hd*cur-bline])) .pg@next-page +.\" +.\" increment current counter +.nr H\\n[hd*level] +1 +.\" +.\" update pagenumber if section-page is used +.if (\\n[hd*level]=1)&(\\n[Sectp]>0) .hd@set-page 1 +.\" +.\" hd*mark is the text written to the left of the header. +.ds hd*mark \\n[H1]. +.\" +.if \\n[hd*level]>1 .as hd*mark \\n[H2] +.\" +.nr hd*i 2 1 +.while \\n+[hd*i]<15 .if \\n[hd*level]>(\\n[hd*i]-1) \ +. as hd*mark .\\n[H\\n[hd*i]] +.if \\n[Ht] .ds hd*mark \\n[H\\n[hd*level]]. +.\" +.\" special case, no dot after level one heading if not H1dot true +.if (\\n[hd*level]=1)&(\\n[H1dot]=0) .ds hd*mark \\n[H1] +.\" +.ds hd@mark-trimmed \\*[hd*mark]\" mark without spaces, for references +.as hd*mark \ \ \" add spaces between heading mark and title +.if !\\n[hd*arg1] .ds hd*mark \" empty; no mark for unnumbered heading +.\" +.if \\n[D]>1 .tm At header \\*[hd*mark] "\\$2" +.nr hd*htype 0 \" hd*htype = check break and space +. \" 0 = run-in, 1 = break only, 2 = space +.if \\n[hd*level]<=\\n[Hb] .nr hd*htype 1 +.if \\n[hd*level]<=\\n[Hs] .nr hd*htype 2 +. \" two spaces if hd*htype == 0 +.ie (\\n[hd*htype]=0)&(\w@\\$2@) .ds hd*suf-space " \" +.el .ds hd*suf-space \" empty +.nr hd*need 2v \" hd*need = header need space +.\"---------- user macro HX ------------ +.\" User exit macro to override numbering. +.\" May change hd*mark (}0), hd*suf-space (}2) and hd*need (;3) +.\" Can also change Hps1/2. +.if d HX .HX \\n[hd*level] \\n[hd*arg1] "\\$2\\$3" +.\"-------------------------------------- +.\" pre-space +.ie \\n[hd*level]<=\\n[Hps] .SP (u;\\n[Hps2]) +.el .SP (u;\\n[Hps1]) +.\" +.par@reset-num \\n[hd*level]\" reset numbered paragraph +.\" start diversion to measure size of header +.di hd*div +\\*[hd*mark]\\$2\\$3\\*[hd*suf-space] +.br +.di +.rm hd*div +.if \\n[hd*htype] .na \" do not adjust heading if not run-in +.if \\n[hd*htype]<2 .nr hd*need +\\n[Lsp]u \" add some extra space +.ne \\n[hd*need]u+\\n[dn]u+.5p-1v \" space needed for a heading +.\" +.\" size and font calculations +.hd@split hd*font \\n[hd*level] HF \\*[HF]\" get font for this level +.ft \\*[hd*font]\" set new font +.hd@split hd*new-ps \\n[hd*level] HP \\*[HP]\" get point size +.ie (\\*[hd*new-ps]=0):(\w@\\*[hd*new-ps]@=0) \{\ +. if \\n[hd*htype] \{\ +. if '\\*[hd*font]'3' \{\ +. ps -1 +. vs -1 +. \} +. if '\\*[hd*font]'B' \{\ +. ps -1 +. vs -1 +. \} +. \} +.\} +.el \{\ +. ps \\*[hd*new-ps] +. vs \\*[hd*new-ps]+2 +.\} +.\" +.\"---------- user macro HY ------------- +.\" user macro to reset indents +.if d HY .HY \\n[hd*level] \\n[hd*arg1] "\\$2\\$3" +.\" HTML: mark beginning of heading +.misc@tag NH \\n[hd*level] +.\"-------------------------------------- +.nr hd*mark-size \w@\\*[hd*mark]@ +.if (\\n[hd*level]<=\\n[Hc])&\\n[hd*htype] .ce\" center if level<=Hc +.\" +.\" finally, output the header +\\*[hd*mark]\&\c +.\" and the rest of the header +.ie \\n[hd*htype] \{\ +\\$2\\$3 +. br +.\} +.el \\$2\\$3\\*[hd*suf-space]\&\c +.ft 1 +.\" restore pointsize and vertical size. +.ps \\n[@ps]u +.vs \\n[@vs]u +.\" +.\" table of contents +.if (\\n[hd*level]<=\\n[Cl])&\w@\\$2@ .toc@entry \\n[hd*level] "\\$2" +.\" set adjust to previous value +.SA +.\" do break or space +.if \\n[hd*htype] .br +.if \\n[hd*htype]>1 .SP (u;\\n[Lsp]*\\n[Hss]) +.ie \\n[hd*htype] \{\ +. \" indent if Hi=1 and Pt=1 +. if (\\n[Hi]=1)&(\\n[Pt]=1) .ti +\\n[Pi]n +. \" indent size of mark if Hi=2 +. if \\n[hd*htype]&(\\n[Hi]>1) .ti +\\n[hd*mark-size]u +. nr par@suppress-indentation 1 +.\} +.\" We're setting a run-in heading; the next paragraph is normal. +.el .nr par@suppress-indentation 0 +.\" +.\" check if it is time to reset footnotes +.if (\\n[hd*level]=1)&\\n[ft*clear-at-header] .nr ft*nr 0 1 +.\" +.\" check if it is time to reset indexes +.if (\\n[hd*level]=1)&\\n[Sectf] \{\ +. nr lix*fg-nr 0 1 +. nr lix*tb-nr 0 1 +. nr lix*ec-nr 0 1 +. nr lix*ex-nr 0 1 +.\} +.\"---------- user macro HZ ---------- +.if d HZ .HZ \\n[hd*level] \\n[hd*arg1] "\\$2\\$3" +.nr hd*last-pos \\n[nl] +.nr hd*last-hsize \\n[.k] +.\" HTML: end of heading +.misc@tag EO-H +.. +.\"-------- +.de HM +.nr hd*i 0 1 +.while \\n+[hd*i]<15 .af H\\n[hd*i] \\$[\\n[hd*i]] 1 +.. +.\"---------------------- +.\" set page-nr, called from header +.\" +.de hd@set-page +.\" +.ie \\n[.$]>0 .nr P \\$1 +.el .nr P +1 +.\" Set section-page-string +.ds hd*sect-pg \\n[H1]-\\n[P] +.if \\n[Sectp]>1 .if '\\n[H1]'0' .ds hd*sect-pg " +.. +.\"########### module pg #################### +.\" set end of text trap +.wh 0 pg@header +.em pg@end-of-text +.\" +.ds pg*header ''- \\n[P] -'' +.ds pg*footer +.if \n[N]=4 .ds pg*header '''' +.if (\n[N]=3):(\n[N]=5) \{\ +. ds pg*header '''' +. ds pg*footer ''\\*[hd*sect-pg]'' +.\} +.ds pg*even-footer +.ds pg*odd-footer +.ds pg*even-header +.ds pg*odd-header +.\" +.nr pg*top-margin 0 +.nr pg*foot-margin 0 +.nr pg*block-size 0 +.nr pg*footer-size 5v\" 1v+footer+even/odd footer+2v +.nr pg*header-size 7v\" 3v+header+even/odd header+2v +.nr pg*extra-footer-size 0 +.nr pg*extra-header-size 0 +.nr ft*note-size 0 +.nr pg*cur-column 0 +.nr pg*cols-per-page 1 +.nr pg*cur-po \n[@po] +.nr pg*head-mark 0 +.\" +.nr pg*ps \n[@ps] +.nr pg*vs \n[@vs] +.\"------------------------- +.\" footer TRAPS: set, enable and disable +.de pg@set-new-trap +.nr pg*foot-trap \\n[@pl]u-(\\n[pg*block-size]u+\\n[ft*note-size]u+\\n[pg*foot-margin]u+\\n[pg*footer-size]u+\\n[pg*extra-footer-size]u) +.\" +.if \\n[D]>2 .tm pg*foot-trap \\n[@pl]u-(\\n[pg*block-size]u+\\n[ft*note-size]u+\\n[pg*foot-margin]u+\\n[pg*footer-size]u+\\n[pg*extra-footer-size]u) = \\n[pg*foot-trap] +.\" +.\" last-pos points to the position of the footer and bottom +.\" block below foot-notes. +.nr pg*last-pos \\n[@pl]u-(\\n[pg*block-size]u+\\n[pg*foot-margin]u+\\n[pg*footer-size]u+\\n[pg*extra-footer-size]u) +.if \\n[D]>2 .tm pg*last-pos \\n[@pl]u-(\\n[pg*block-size]u+\\n[pg*foot-margin]u+\\n[pg*footer-size]u+\\n[pg*extra-footer-size]u) = \\n[pg*last-pos] +.. +.de pg@enable-trap +.\" Disable in HTML mode +.if !'\*[.T]'html' \{\ +.wh \\n[pg*foot-trap]u pg@footer +.if \\n[D]>2 .tm pg@enable-trap .t=\\n[.t] nl=\\n[nl] +.if \\n[D]>2 .ptr +.\} +.. +.de pg@disable-trap +.ch pg@footer +.. +.\" move to new trap (if changed). +.de pg@move-trap +.pg@disable-trap +.pg@set-new-trap +.pg@enable-trap +.. +.de pg@enable-top-trap +.\" set trap for pageheader. +.nr pg*top-enabled 1 +.. +.de pg@disable-top-trap +.\" remove trap for pageheader. +.nr pg*top-enabled 0 +.. +.\" no header on the next page +.de PGNH +.nr pg*top-enabled (-1) +.. +.\" set first trap for pagefooter +.pg@enable-top-trap +.pg@set-new-trap +.pg@enable-trap +.\"------------------------- +.\" stop output and begin on next page. Fix footnotes and all that. +.de pg@next-page +.\".debug next-page +.ne 999i \" activate trap +.\" .pg@footer +.. +.\"------------------------- +.\" support for PX, TP and EOP. +.als }t pg*header +.als }e pg*even-header +.als }o pg*odd-header +.als TPh pg*header +.als TPeh pg*even-header +.als TPoh pg*odd-header +.\" +.als }b pg*footer +.als }f pg*even-footer +.als }p pg*odd-footer +.als EOPf pg*footer +.als EOPef pg*even-footer +.als EOPof pg*odd-footer +.\"------------------------------------------------------------ +.\" HEADER +.de pg@header +.\" Disable in HTML mode +.if !'\*[.T]'html' \{\ +.if \\n[D]>1 .tm Page# \\n[%] (\\n[.F]:\\n[c.]) +. if (u;(\\n[pg*header-size] + \\n[pg*extra-header-size] \ + + \\n[pg*footer-size] + \\n[pg*extra-footer-size] \ + + \\n[.V]) >= \\n[.p]) \{\ +. pl \\n[nl]u +. @error insufficient page length; aborting +. \} +.\} +.\" check if Hy has been changed +.ie \\n[Hy] 'hy 14 +.el 'nh +.if \\n[Idxf] \{\ +.tl '''' +.\} +.\" assign current page-number to P +.hd@set-page +.\" reset spacing +.nr line*lp\\n[.z] 0 +.nr line*ac\\n[.z] 0 +.\" +.\" suppress pageheader if pagenumber == 1 and N == [124] +.if \\n[pg*top-enabled] \{\ +.\" must be fixed!! +.\". pg@disable-top-trap +. if \\n[pg*extra-header-size] 'sp \\n[pg*extra-header-size]u +. if \\n[pg*top-margin] 'sp \\n[pg*top-margin]u +. ev pg*tl-ev +. pg@set-env +. ie d let@header .let@header +. el \{\ +. ie d TP .TP +. el \{\ +' sp 3 +. ds hd*format \\g[P] +. af P 0 +. ie ((\\n[P]=1)&((\\n[N]=1):(\\n[N]=2))) .sp +. el .tl \\*[pg*header] +. af P \\*[hd*format] +. ie o .tl \\*[pg*odd-header] +. el .tl \\*[pg*even-header] +' sp 2 +. \} +. \} +. ev +. \" why no-space?? +. if d PX \{\ +. ns +. PX +. rs +. \} +. \" check for pending footnotes +. ft@check-old +. \" +. \" back to normal text processing +. pg@enable-trap +. \" mark for multicolumn +. nr pg*head-mark \\n[nl]u +. \" reset NCOL pointer at each new page. +. nr pg*last-ncol 0 +. \" set multicolumn +. \" +. pg@set-po +. \" print floating displays +. df@print-float 4 +. tbl@top-hook +. ns +.\} +.if \\n[pg*top-enabled]<0 .nr pg*top-enabled 1 +.nr hd*cur-bline \\n[nl] \" .H needs to know if output has occurred +.\} +.. +.\"--------------------------------------------------------- +.\" FOOTER +.de pg@footer +.ec +.if \\n[D]>2 .tm Footer# \\n[%] (\\n[.F]:\\n[c.]) nl=\\n[nl] +.pg@disable-trap +.\".debug footer +.tbl@bottom-hook +.\" increment pageoffset for MC +.\" move to the exact start of footer. +'sp |\\n[pg*foot-trap]u+1v +.\" +.if \\n[D]>3 .tm FOOTER after .sp, nl=\\n[nl] +.\" print footnotes +.if d ft*div .ft@print +.\" +.pg@inc-po +.if !\\n[pg*cur-column] .pg@print-footer +.\" next column +.pg@set-po +.pg@enable-trap +.if \\n[@verbose-flag] .eo \" to help VERBON/VERBOFF +.. +.\"------------------------- +.de pg@print-footer +.\" jump to the position just below the foot-notes. +'sp |\\n[pg*last-pos]u+1v +.if \\n[D]>3 .tm print-footer nl=\\n[nl] +.\" check if there are any bottom block +.if d pg*block-div .pg@block +.\" +.\" print the footer and eject new page +.ev pg*tl-ev +.pg@set-env +.vpt 0 +.\" user defined end-of-page macro +.ie d EOP .EOP +.el \{\ +. ie o .tl \\*[pg*odd-footer] +. el .tl \\*[pg*even-footer] +. ds hd*format \\g[P] +. af P 0 +. ie (\\n[P]=1)&(\\n[N]=1) .tl \\*[pg*header] +. el .tl \\*[pg*footer] +. af P \\*[hd*format] +. tl ''\\*[Pg_type!\\n[@copy_type]]'' +.\} +.vpt 1 +.ev +.\" be sure that floating displays and footnotes will be +.\" printed at the end of the document. +.ie (\\n[df*fnr]>=\\n[df*o-fnr]):\\n[ft*exist] \{\ +. ev ne +' bp +. ev +.\} +.el 'bp +.. +.\"------------------------- +.\" +.\" Initialize the title environment +.de pg@set-env +'na +'nh +'in 0 +'ti 0 +.ie \\n[Pgps] \{\ +. ps \\n[@ps]u +. vs \\n[@vs]u +.\} +.el \{\ +. ps \\n[pg*ps]u +. vs \\n[pg*vs]u +.\} +.lt \\n[@ll]u +.ll \\n[@ll]u +.. +.\"------------------------- +.de PH +.ds pg*header "\\$1 +.pg@set-new-size +.. +.de PF +.ds pg*footer "\\$1 +.pg@set-new-size +.. +.de OH +.ds pg*odd-header "\\$1 +.pg@set-new-size +.. +.de EH +.ds pg*even-header "\\$1 +.pg@set-new-size +.. +.de OF +.ds pg*odd-footer "\\$1 +.pg@set-new-size +.. +.de EF +.ds pg*even-footer "\\$1 +.pg@set-new-size +.. +.de pg@clear-hd +.ds pg*even-header +.ds pg*odd-header +.ds pg*header +.. +.de pg@clear-ft +.ds pg*even-footer +.ds pg*odd-footer +.ds pg*footer +.. +.de pg@set-new-size +.nr pg*ps \\n[@ps] +.nr pg*vs \\n[@vs] +.pg@move-trap +.. +.\"------------------------- +.\" end of page processing +.de pg@footnotes +.\".debug footnotes +.\" output footnotes. set trap for block +.\" +.. +.\"------------------------- +.\" print bottom block +.de pg@block +.ev pg*block-ev +'nf +'in 0 +.ll 100i +.pg*block-div +.br +.ev +.. +.\"------------------------- +.\" define bottom block +.de BS +.misc@ev-keep pg*block-ev +.init@reset +.br +.di pg*block-div +.. +.\"------------------------- +.de BE +.br +.di +.nr pg*block-size \\n[dn]u +.ev +.pg@move-trap +.. +.\"------------------------- +.\" print out all pending text +.de pg@end-of-text +.if \\n[D]>2 .tm ---------- End of text processing ---------------- +.df@eot-print +.ref@eot-print +.. +.\"------------------------- +.\" set top and bottom margins +.\" -T sets pg*footer-size and pg*header-size instead +.de VM +.ie '\\$1'-T' \{\ +. shift +. if \\n[.$]=0 \{\ +. nr pg*footer-size 5v +. nr pg*header-size 7v +. \} +. if \\n[.$]>0 .nr pg*header-size (v;\\$1) +. if \\n[.$]>1 .nr pg*footer-size (v;\\$2) +.\} +.el \{\ +. if \\n[.$]=0 \{\ +. nr pg*extra-footer-size 0 +. nr pg*extra-header-size 0 +. \} +. if \\n[.$]>0 .nr pg*extra-header-size (v;\\$1) +. if \\n[.$]>1 .nr pg*extra-footer-size (v;\\$2) +. if \\n[D]>2 \{\ +. tm extra top \\n[pg*extra-footer-size] +. tm extra bottom \\n[pg*extra-header-size] +. \} +.\} +.pg@move-trap +.. +.\"--------------------- +.\" multicolumn output. +.de pg@set-po +.if \\n[pg*cols-per-page]>1 \{\ +. ll \\n[pg*column-size]u +.\} +.. +.de pg@inc-po +.if \\n[pg*cols-per-page]>1 \{\ +. ie \\n+[pg*cur-column]>=\\n[pg*cols-per-page] \{\ +. nr pg*cur-column 0 1 +. nr pg*cur-po \\n[@po]u +. po \\n[@po]u +. ll \\n[@ll]u +. \} +. el \{\ +. nr pg*cur-po +(\\n[pg*column-size]u+\\n[pg*column-sep]u) +. po \\n[pg*cur-po]u +' sp |\\n[pg*head-mark]u +. tbl@top-hook +. \} +.\} +.. +.\" An argument disables the page-break. +.de 1C +.if \\n[pg*cols-per-page]<=1 \{\ +. @warning \\$0: multicolumn mode not active +. return +.\} +.br +.nr pg*cols-per-page 1 +.nr pg*column-sep 0 +.nr pg*column-size \\n[@ll] +.nr pg*ncol-i \\n[pg*cur-column]\" temp variable +.nr pg*cur-column 0 1 +.nr pg*cur-po \\n[@po]u +.PGFORM +.ie !'\\$1'1' .SK +.el \{\ +. if d ft*div \{\ +. if \\n[pg*ncol-i]>0 \{\ +. @warning \\$0: returning to single-column \ +layout with suppressed page break and footnote pending; output may be \ +messy +. \} +. \} +. if \\n[pg*last-ncol]>0 \{\ +. sp |\\n[pg*last-ncol]u +. nr pg*last-ncol 0 +. \} +.\} +.. +.de 2C +.if \\n[pg*cols-per-page]>1 .@error \\$0: multicolumn mode already \ +active +.br +.nr pg*head-mark \\n[nl]u +.nr pg*cols-per-page 2 +.nr pg*column-sep \\n[@ll]/15 +.nr pg*column-size (\\n[@ll]u*7)/15 +.nr pg*cur-column 0 1 +.nr pg*cur-po \\n[@po]u +.ll \\n[pg*column-size]u +.\" .lt \\n[pg*column-size]u +.. +.\" MC column-size [ column-separation ] +.de MC +.if \\n[pg*cols-per-page]>1 .@error \\$0: multicolumn mode already \ +active +.br +.nr pg*head-mark \\n[nl]u +.ie ''\\$1' .nr pg*column-size \\n[.l] +.el .nr pg*column-size (n;\\$1) +.ie ''\\$2' .nr pg*column-sep \\n[pg*column-size]/15 +.el .nr pg*column-sep (n;\\$2) +.\" +.\" calculate the number of columns/page +.nr pg*cols-per-page 0 \" temporarily invalid! +.nr pg*i \\n[pg*column-size] +.while \\n[pg*i]<=\\n[.l] \{\ +. nr pg*cols-per-page +1 +. nr pg*i \\n[pg*i]+\\n[pg*column-sep]+\\n[pg*column-size] +.\} +.if \\n[pg*cols-per-page]<0 .@abort \\n[pg*cols-per-page] columns in \ +page +.nr pg*cur-column 0 1 +.nr pg*cur-po \\n[@po]u +.ll \\n[pg*column-size]u +.\" .lt \\n[pg*column-size]u +.. +.\" begin a new column +.de NCOL +.br +.if \\n[nl]>\\n[pg*last-ncol] .nr pg*last-ncol \\n[nl] +.pg@footer +.. +.\" skip pages +.de SK +.br +.bp +.nr pg*i 0 1 +.\" force new page by writing something invisible. +.while \\n+[pg*i]<=(0\\$1) \{\ +\& +. bp +.\} +.. +.\"------------------------------- +.\" MULB width1 space1 width2 space2 width3 space3 ... +.de MULB +.br +.nr pg*i 0 1 +.nr pg*mul-x 0 1 +.nr pg*mul-ind 0 +.nr pg*mul-last 0 +.while \\n[.$] \{\ +. nr pg*mul!\\n+[pg*i] (n;0\\$1) +. nr pg*muls!\\n[pg*i] (n;0\\$2) +. shift 2 +.\} +.nr pg*mul-max-col \\n[pg*i] +.ds pg*mul-fam \\n[.fam] +.nr pg*mul-font \\n[.f] +.ev pg*mul-ev +.ps \\n[@ps]u +.vs \\n[@vs]u +.fam \\*[pg*mul-fam] +.ft \\n[pg*mul-font] +.fi +.hy 6 +.di pg*mul-div +.MULN +.. +.\"----------- +.de MULN +.if \\n[pg*mul-x]>=\\n[pg*mul-max-col] .@abort undefined column width \ +(pg*mul-x=\\n[pg*mul-x >= pg*mul-max-col=\\n[pg*mul-max]) +.br +.if \\n[.d]>\\n[pg*mul-last] .nr pg*mul-last \\n[.d] +.rt +0 +.in \\n[pg*mul-ind]u +.ll (u;\\n[.i]+\\n[pg*mul!\\n+[pg*mul-x]])u +.nr pg*mul-ind +(u;\\n[pg*mul!\\n[pg*mul-x]]+\\n[pg*muls!\\n[pg*mul-x]]) +.. +.\"----------- +.\" MULE +.de MULE +.br +.if \\n[.d]>\\n[pg*mul-last] .nr pg*mul-last \\n[.d] +.di +.ev +.ne \\n[pg*mul-last]u +.nf +.mk +.pg*mul-div +.rt +.sp \\n[pg*mul-last]u +.fi +.. +.\"----------- +.de OP +.br +.ie o .if !\\n[pg*head-mark]=\\n[nl] \{\ +. bp +1 +. bp +1 +.\} +.el .bp +.. +.\"########### module footnotes ################### +.nr ft*note-size 0 +.nr ft*busy 0 +.nr ft*nr 0 1 +.aln :p ft*nr +.nr ft*wide 0 +.nr ft*hyphen 0\" hyphenation value +.nr ft*adjust 1\" >0 if adjust true +.nr ft*indent 1\" >0 if text indent true (not imp. $$$) +.nr ft*just 0\" 0=left justification, 1=right (not imp. $$$) +.nr ft*exist 0\" not zero if there are any footnotes to be printed +.nr ft*clear-at-header 0\" >0 if footnotes should be reset at first level head. +.\" +.ie t .ds F \v'-.4m'\s-3\\n+[ft*nr]\s0\v'.4m' +.el .ds F [\\n+[ft*nr]] +.\" +.\"----------------- +.\" init footnote environment +.de ft@init +.\" indentcontrol not implemented $$$ +.\" label justification not implemented $$$ +'in 0 +'fi +.ie \\n[ft*adjust] 'ad +.el 'na +.ie \\n[ft*hyphen] 'hy 6 +.el 'hy 0 +.ll \\n[@cur-ll]u +.lt \\n[@cur-ll]u +.ps (p;\\n[@ps]u-2) +.vs (p;\\n[@vs]u-1) +.. +.\"----------------- +.\" set footnote format +.\" no support for two column processing (yet). $$$ +.de FD +.if \\n[.$]=0 .@error \\$0: expected 1 or 2 arguments, got \\n[.$] +.ie \\n[.$]=2 .nr ft*clear-at-header 1 +.el .nr ft*clear-at-header 0 +.\" +.if !'\\$1'' \{\ +. ie \\$1>11 .nr ft*format 0 +. el .nr ft*format \\$1 +. \" +. nr ft*hyphen (\\n[ft*format]%2)*6 +. nr ft*format \\n[ft*format]/2 +. \" +. nr ft*adjust 1-(\\n[ft*format]%2) +. nr ft*format \\n[ft*format]/2 +. \" +. nr ft*indent 1-(\\n[ft*format]%2) +. nr ft*format \\n[ft*format]/2 +. \" +. nr ft*just \\n[ft*format]%2 +.\} +.. +.\"--------------- +.\" Footnote and display width control $$$ +.de WC +.nr ft*i 0 1 +.while \\n+[ft*i]<=\\n[.$] \{\ +. ds ft*x \\$[\\n[ft*i]] +. if '\\*[ft*x]'N' \{\ +. nr ft*wide 0 +. nr ft*first-fn 0 +. nr ds*wide 0 +. nr ds*float-break 1 +. \} +. if '\\*[ft*x]'-WF' .nr ft*wide 0 +. if '\\*[ft*x]'WF' .nr ft*wide 1 +. if '\\*[ft*x]'-FF' .nr ft*first-fn 0 +. if '\\*[ft*x]'FF' .nr ft*first-fn 1 +. if '\\*[ft*x]'-WD' \{\ +. nr ds*wide 0 +. if r ft*df-save \{\ +. nr Df \\n[ft*df-save] +. rm ft*df-save +. \} +. \} +. if '\\*[ft*x]'WD' \{\ +. nr ds*wide 1 +. nr ft*df-save \\n[Df] +. nr Df 4 +. \} +. if '\\*[ft*x]'-FB' .nr ds*float-break 0 +. if '\\*[ft*x]'FB' .nr ds*float-break 1 +. if \\n[D]>1 .tm WC WF=\\n[ft*wide] WD=\\n[ds*wide] +.\} +.. +.\"----------------- +.\" begin footnote +.\" Change environment, switch to diversion and print the foot-note mark. +.de FS +.if \\n[ft*busy] .@error \\$0: cannot nest; missing FE? +.nr ft*busy 1 +.ev ft*ev +.ft@init +.if !\\n[ft*wide] .pg@set-po +.di ft*tmp-div +.nr ft*space (u;\\n[Fs]*\\n[Lsp]) +.sp \\n[ft*space]u +.\" print mark +.ie \\n[.$] .ds ft*mark \\$1 +.el .ds ft*mark \\n[ft*nr]. +\\*[ft*mark] +.in +.75c +.sp -1 +.nr ft*exist 1 +.. +.\"----------------- +.\" init footnote diversion +.de ft@init-footnote +.di ft*div +\l'20n' +.br +.di +.nr ft*note-size \\n[dn] +.. +.\"----------------- +.\" end footnote +.\" End the diversion, back to previous environment, and adjust +.\" the trap to the new foot-note size. +.de FE +.nr ft*busy 0 +.br +.di +'in 0 +'nf +.if \\n[@pl]u<\\n[dn]u .@error \\$0: footnote bigger than page area +.if !d ft*div .nr dn +1v +.if \\n[D]>3 .tm FE: foot-trap=\\n[pg*foot-trap] .d=\\n[.d] dn=\\n[dn] +.ie (\\n[pg*foot-trap]u-\\n[.d]u)<\\n[dn]u \{\ +. da ft*next-div +. ft*tmp-div +. br +. di +.\} +.el \{\ +. if !d ft*div .ft@init-footnote +. da ft*div +. ft*tmp-div +. di +. nr ft*note-size +\\n[dn] +.\} +.rm ft*tmp-div +.ev +.pg@move-trap +.. +.\"----------------- +.\" print footnotes, see pg@footer +.de ft@print +.ev ft*print-ev +'nf +'in 0 +.ll 100i +.ft*div +.br +.ev +.rm ft*div +.nr ft*note-size 0 +.pg@move-trap +.. +.\"----------------- +.\" check if any pending footnotes, see pg@header +.de ft@check-old +.if d ft*next-div \{\ +. ev ft*ev +. ft@init +. ft@init-footnote +. nf +. in 0 +. da ft*div +. ft*next-div +. di +. nr ft*note-size +\\n[dn] +. rm ft*next-div +. ev +. nr ft*exist 0 +. pg@move-trap +.\} +.. +.\"########### module display ################### +.nr ds*wide 0\" >0 if wide displays wanted +.nr df*fnr 0 1\" floating display counter +.nr df*o-fnr 1\" floating display counter, already printed +.nr ds*snr 0 1\" static display counter +.nr ds*lvl 0 1\" display level +.nr ds*float-busy 0\" >0 if printing float +.nr df*float 0\" >0 if previous display was floating +.\"-------------------------------------------- +.de DE +.ie \\n[df*float] .df@end \\$@ +.el .ds@end \\$@ +.. +.\"-------------------------------------------- +.\" floating display start +.\" nested DF/DE is not allowed. +.de DF +.if \\n[df*float] .@error \\$0: cannot nest floating keeps; use DS \ +within DF/DE +.ds ds@macro \\$0 +.ds@set-format \\$@ +.\" +.nr df*old-ll \\n[.l] +.nr ds*ftmp \\n[.f] +.misc@ev-keep df*ev +.ft \\n[ds*ftmp] +.\" +.init@reset +.di df*div +'in 0 +.\" +.ds@set-new-ev \\n[df*old-ll] +.SP \\n[Lsp]u +.nr df*float 1 +.. +.\"-------------------------------------------- +.de df@end +.br +.SP \\n[Lsp]u +.di +.nr df*width!\\n+[df*fnr] \\n[dl] +.nr df*height!\\n[df*fnr] \\n[dn] +.nr df*wide!\\n[df*fnr] \\n[ds*wide] +.nr df*format!\\n[df*fnr] \\n[ds*format] +.ev +.if \\n[D]>2 .tm DF:fnr=\\n[df*fnr] w=\\n[dl] h=\\n[dn] wide=\\n[ds*wide] \ + form=\\n[ds*format] +.\" move div to the floating display list +.rn df*div df*fdiv!\\n[df*fnr] +.\" +.nr par@suppress-indentation 1 \" no indentation after displays +.\" print float if queue is empty and the display fits into +.\" the current page +.if ((\\n[df*fnr]>=\\n[df*o-fnr])&(\\n[dn]<\\n[.t])) .df@print-float 1 +.nr df*float 0 +.. +.\"------------- +.\" called by end-of-text +.de df@eot-print +.br +.if \\n[df*o-fnr]<=\\n[df*fnr] \{\ +. if \\n[D]>2 .tm Print remaining displays. +.\" still some floats left, make non-empty environment +. misc@ev-keep ne +. init@reset +\c +. df@print-float 3 +. ev +.\} +.. +.\"--------------- +.\" print according to Df and De. +.\" .df@print-float type +.\" type called from +.\" 1 .DE +.\" 2 end of section +.\" 3 end of document +.\" 4 beginning of new page +.\" +.de df@print-float +.if \\n[Df]>5 .@abort invalid float type: 5 < Df (\\n[Df]) +.if !\\n[ds*float-busy] \{\ +. nr ds*float-busy 1 +.\" at .DE +. if \\n[D]>3 \{\ +. tmc print-float: .t=\\n[.t] +. if r df*height!\\n[df*o-fnr] \ +. tmc , h=\\n[df*height!\\n[df*o-fnr]] +. tm +. \} +. \" Df = 1 or 5 +. if (\\$1=1)&((\\n[Df]=1):(\\n[Df]=5)) \{\ +. if \\n[.t]>\\n[df*height!\\n[df*o-fnr]] \{\ +. \" Print only new displays. +. if \\n[df*o-fnr]=\\n[df*fnr] \{\ +. br +. ds@print-one-float +. \} +. \} +. \} +. \" Df = 3 +. if (\\$1=1)&(\\n[Df]=3) \{\ +. if \\n[.t]>\\n[df*height!\\n[df*o-fnr]] \{\ +. br +. ds@print-one-float +. \} +. \} +.\" print all if Df<2 and end of section +. if (\\$1=2)&(\\n[Sectp]>0)&(\\n[Df]<2) \{\ +. br +. ds@print-all-floats +. \} +.\" print all if end of document. Where should they go instead? +. if \\$1=3 \{\ +. br +. ds@print-all-floats +.\} +.\" new page +. if (\\$1=4)&(\\n[Df]>1) \{\ +. if \\n[Df]=2 .ds@print-one-float +. if \\n[Df]=3 .ds@print-one-float +. if \\n[Df]>3 \{\ +. ie \\n[De] .ds@print-all-floats +. el .ds@print-this-page +. \} +. \} +. nr ds*float-busy 0 +.\} +.. +.\"--------------- +.\" DF out +.\" print a floating diversion +.de ds@output-float +.nr df*old-ll \\n[.l] +.nr df*old-in \\n[.i] +.ev ds*fev +.nf +.nr df*i \\n[df*o-fnr] +.nr df*f \\n[df*format!\\n[df*i]] +.\" +.in \\n[df*old-in]u +.if \\n[df*f]=1 'in +\\n[Si]n +.if \\n[df*f]>=2 'in 0 +.if \\n[df*f]=2 'ce 9999 +.if \\n[df*f]=3 'in (u;(\\n[.l]-\\n[df*width!\\n[df*i]])/2) +.if \\n[df*f]=4 'rj 9999 +.if \\n[df*f]=5 'in (u;\\n[.l]-\\n[df*width!\\n[df*i]]) +.\" +.\" +.df*fdiv!\\n[df*o-fnr] +.\" +.if \\n[df*f]=2 'ce 0 +.if \\n[df*f]=4 'rj 0 +.ev +.rm df*fdiv!\\n[df*i] +.rm df*height!\\n[df*i] +.rm df*format!\\n[df*i] +.if \\n[df*wide!\\n[df*i]] .nr pg*head-mark \\n[nl]u +.nr df*o-fnr +1 +.. +.\"--------------- +.\" print one floating display if there is one. +.de ds@print-one-float +.if \\n[df*o-fnr]<=\\n[df*fnr] \{\ +. if \\n[D]>3 .tm print-one-float: .t=\\n[.t], h=\\n[df*height!\\n[df*o-fnr]] +. if \\n[.t]<\\n[df*height!\\n[df*o-fnr]] .pg@next-page +. ds@output-float +. if \\n[De] .pg@next-page +.\} +.. +.\"--------------- +.\" print all queued floats. +.\" if De>0 do a page eject between the floats. +.de ds@print-all-floats +.while \\n[df*o-fnr]<=\\n[df*fnr] \{\ +. if \\n[D]>3 .tm print-all-floats: .t=\\n[.t], h=\\n[df*height!\\n[df*o-fnr]] +. if \\n[.t]<\\n[df*height!\\n[df*o-fnr]] .pg@next-page +. br +\c +. ds@output-float +. if \\n[De] .pg@next-page +.\} +.. +.\"--------------- +.\" print as many floats as will fit on the current page +.de ds@print-this-page +.while \\n[df*o-fnr]<=\\n[df*fnr] \{\ +. if \\n[D]>3 .tm print-this-page: .t=\\n[.t], h=\\n[df*height!\\n[df*o-fnr]] +. if \\n[.t]<\\n[df*height!\\n[df*o-fnr]] .break +. ds@output-float +.\} +.. +.\"--------------------------------------------------- +.\" get format of the display +.de ds@set-format +.ie \\n[.$] \{\ +. ie r ds*format!\\$1 .nr ds*format \\n[ds*format!\\$1] +. el .@error \\*[ds@macro]: unrecognized format '\\$1' +.\} +.el .nr ds*format 0 +.if \\n[D]>2 .tm set format=\\n[ds*format] +.\" fill or not to fill, that is the... +.nr ds*fill 0 +.if \\n[.$]>1 \{\ +. ie r ds*fill!\\$2 .nr ds*fill \\n[ds*fill!\\$2] +. el .@error \\*[ds@macro]: unrecognized fill style '\\$2' +.\} +.if \\n[D]>2 .tm set fill=\\n[ds*fill] +.nr ds*rindent 0 +.if \\n[.$]>2 .nr ds*rindent \\$3 +.if \\n[D]>2 .tm set indent=\\n[ds*rindent] +.. +.\"----------------------------- +.\" .ds@set-new-ev previous-line-length +.de ds@set-new-ev +.ll \\$1u +.lt \\$1u +.if \\n[ds*rindent] \{\ +. ll -\\n[ds*rindent]n +. lt -\\n[ds*rindent]n +.\} +.if \\n[ds*wide] \{\ +. ll \\n[@ll]u +. lt \\n[@ll]u +.\} +.\" +.ie \\n[ds*fill] 'fi +.el 'nf +.. +.\"-------------------------------------------------------- +.nr ds*format 0\" dummy value for .En/.EQ +.nr ds*format! 0\" no indent +.nr ds*format!0 0\" no indent +.nr ds*format!L 0\" no indent +.nr ds*format!I 1\" indent +.nr ds*format!1 1\" indent +.nr ds*format!C 2\" center each line +.nr ds*format!2 2\" center each line +.nr ds*format!CB 3\" center as block +.nr ds*format!3 3\" center as block +.nr ds*format!R 4\" right justify each line +.nr ds*format!4 4\" right justify each line +.nr ds*format!RB 5\" right justify as block +.nr ds*format!5 5\" right justify as block +.\"--------------- +.nr ds*fill! 0\" no fill +.nr ds*fill!N 0\" no fill +.nr ds*fill!0 0\" no fill +.nr ds*fill!F 1\" fill on +.nr ds*fill!1 1\" fill on +.\"-------------------------------------------- +.\" static display start +.\" nested DS/DE is allowed. No limit on depth. +.de DS +.ds ds@macro \\$0 +.br +.nr ds*lvl +1 +.ds@set-format \\$@ +.\" +.nr ds*old-ll \\n[.l] +.nr ds*old-in \\n[.i] +.misc@push ds-in \\n[ds*old-in] \" Saving indent and line length of +.misc@push ds-ll \\n[ds*old-ll] \" the text outside the display. +.misc@push ds-form \\n[ds*format] +.nr ds*i \\n[.i] +.nr ds*ftmp \\n[.f] +.misc@ev-keep ds*ev!\\n+[ds*snr] +.ft \\n[ds*ftmp] +.\" +.init@reset +.\" indent in a diversion doesn't seem like a good idea. +'in 0 +.di ds*div!\\n[ds*snr] +.\" +.nr ds*div-ll \\n[ds*old-ll] +.if \\n[ds*format]=1 .nr ds*div-ll -\\n[Si]n +.ds@set-new-ev \\n[ds*div-ll] +.nr df*float 0 +.. +.\"-------------------------------------------- +.de ds@end +.\" We hard-code the DE macro name here since this macro is internal but +.\" only DE calls it. We also know we're closing a static keep because +.\" df@end is called otherwise. See `DE`. +.if \\n-[ds*lvl]<0 .@error DE: no corresponding DS +.br +.di +.\" ********** +.nr ds*width \\n[dl] +.nr ds*height \\n[dn] +.misc@pop-nr ds-ll ds*old-ll \" Restore indent and +.misc@pop-nr ds-in ds*old-in \" line length +.misc@pop-nr ds-form ds*format +.\" +.\" ********** +'nf +.\" calculate needed space +.nr ds*need \\n[ds*height] +.nr ds*i \\n[pg*foot-trap]-\\n[pg*header-size]u-\\n[pg*extra-header-size]u +.if (\\n[ds*height]>\\n[ds*i])&(\\n[.t]<(\\n[ds*i]/2)) .nr ds*need \\n[.t]u+1v +.if (\\n[ds*height]<\\n[ds*i])&(\\n[.t]<(\\n[ds*height])) .nr ds*need \\n[.t]u+1v +.\" Eject page if display will fit one page and +.\" there are less than half of the page left. +.if \\n[ds*need] .ne \\n[ds*need]u +.\" +.\" Print static display +.nr ds*i \\n[Lsp] +.if r Dsp .nr ds*i \\n[Dsp] +.\" +.if \\n[Ds] .SP \\n[ds*i]u \" Space before display +.\" check if pending equation label +.eq@check \\n[ds*need] +'in \\n[ds*old-in]u +.if \\n[ds*format]=1 'in \\n[ds*old-in]u+\\n[Si]n +.if \\n[ds*format]>=2 'in 0 +.if \\n[ds*format]=2 'ce 9999 +.if \\n[ds*format]=3 'in (u;(\\n[.l]-\\n[ds*width])/2) +.if \\n[ds*format]=4 'rj 9999 +.if \\n[ds*format]=5 'in (u;\\n[.l]-\\n[ds*width]) +.\" ********** +.\" +.ds*div!\\n[ds*snr] +.if \\n[Ds] .SP \\n[ds*i]u \" Space after display +.\" +.if \\n[ds*format]=2 'ce 0 +.if \\n[ds*format]=4 'rj 0 +.rm ds*div!\\n[ds*snr] +.nr ds*snr -1 +.nr par@suppress-indentation 1 \" no indentation after displays +.ev +.. +.\"########### module list ################### +.\" .LI text-indent mark-indent pad type [mark [LI-space [LB-space] ] ] +.\" +.nr li*tind 0 +.nr li*mind 0 +.nr li*pad 0 +.nr li*type 0 +.ds li*mark 0 +.nr li*li-spc 0 +.nr li*lvl 0 1 +.aln :g li*lvl +.nr li*cur-vpos 0 +.\"-------------------------- +.\" the major list-begin macro. +.\" If type == -1 a 'break' will occur. +.de LB +.if \\n[.$]<4 .@error \\$0: expected at least 4 arguments, got \\n[.$] +.misc@push cind \\n[.i] +.misc@push tind \\n[li*tind] +.misc@push mind \\n[li*mind] +.misc@push pad \\n[li*pad] +.misc@push type \\n[li*type] +.misc@push li-spc \\n[li*li-spc] +.ds li*mark-list!\\n[li*lvl] \\*[li*mark] +.nr li*lvl +1 +.\" +.nr li*tind (n;0\\$1)\" text-indent +.nr li*mind (n;0\\$2)\" mark-indent +.nr li*pad (n;0\\$3)\" pad +.nr li*type 0\\$4\" type +.ds li*mark \\$5\" mark +.ie !'\\$6'' .nr li*li-spc \\$6\" LI-space +.el .nr li*li-spc 1 +.ie !'\\$7'' .nr li*lb-spc \\$7\" LB-space +.el .nr li*lb-spc 0 +.\" init listcounter +.nr li*cnt!\\n[li*lvl] 0 1 +.\" assign format +.af li*cnt!\\n[li*lvl] 1 +.if \\n[li*type] .if !'\\*[li*mark]'' .af li*cnt!\\n[li*lvl] \\*[li*mark] +.\" +.if \\n[li*lb-spc] .SP (u;\\n[li*lb-spc]*\\n[Lsp]) +.in +\\n[li*tind]u +.. +.\"--------------- +.de LI +.if \\n[li*lvl]<1 .@error \\$0: no list active; call AL, BL, BVL, ... \ +first +.if \\n[li*li-spc]&(\\n[li*lvl]<=\\n[Ls]) \ +. SP (u;\\n[li*li-spc]*\\n[Lsp]) +.ne 2v +.\" +.ds li*c-mark \\*[li*mark] +.nr li*cnt!\\n[li*lvl] +1 +.if \\n[li*type]=1 .ds li*c-mark \\n[li*cnt!\\n[li*lvl]]. +.if \\n[li*type]=2 .ds li*c-mark \\n[li*cnt!\\n[li*lvl]]) +.if \\n[li*type]=3 .ds li*c-mark (\\n[li*cnt!\\n[li*lvl]]) +.if \\n[li*type]=4 .ds li*c-mark [\\n[li*cnt!\\n[li*lvl]]] +.if \\n[li*type]=5 .ds li*c-mark <\\n[li*cnt!\\n[li*lvl]]> +.if \\n[li*type]=6 .ds li*c-mark {\\n[li*cnt!\\n[li*lvl]]} +.if \\n[.$]=1 .ds li*c-mark \\$1 +.if \\n[.$]=2 \{\ +. ie (\\$2=2):(\\n[Limsp]=0) .ds li*c-mark \\$1\\*[li*c-mark] +. el .ds li*c-mark \\$1\ \\*[li*c-mark] +.\} +.\" +.\" determine where the text begins +.nr li*text-begin \\n[li*tind]>?\w@\\*[li*c-mark]\ @ +.\" +.\" determine where the mark begin +.ie !\\n[li*pad] .nr li*in \\n[li*mind] +.el .nr li*in \\n[li*text-begin]-\\n[li*pad]-\w@\\*[li*c-mark]@ +.if !\\n[li*in] .nr li*in 0 +.\" +.ti -\\n[li*tind]u +.\" no indentation if hanging indent +.if (\w@\\*[li*c-mark]@=0)&((\\n[.$]=0):(\w@\\$1@=0)) .nr li*text-begin 0 +\Z'\&\h'\\n[li*in]u'\\*[li*c-mark]'\h'\\n[li*text-begin]u'\&\c +.if \\n[li*type]=-1 .br +.. +.\" +.\"------------- +.de li@pop +.nr li*lvl -1 +.misc@pop-nr cind li*tmp +.in \\n[li*tmp]u +.misc@pop-nr tind li*tind +.misc@pop-nr mind li*mind +.misc@pop-nr pad li*pad +.misc@pop-nr type li*type +.misc@pop-nr li-spc li*li-spc +.ds li*mark \\*[li*mark-list!\\n[li*lvl]] +.. +.de LE +.if \\n[li*lvl]<1 .@error \\$0: no list active; call AL, BL, BVL, ... \ +and LI first +.li@pop +.if '\\$1'1' .SP \\n[Lsp]u +.nr par@suppress-indentation 1 \" no indentation after lists +.. +.\"------------- +.\" list status clear. +.\" terminate all lists to level i +.de LC +.nr li*i 0 +.if \\n[.$] \{\ +. ie \B'\\$1' .nr li*i \\$1 +. el .@error \\$0: argument not numeric: '\\n[li*i]' +.\} +.if \\n[li*i]>\\n[li*lvl] .@error \\$0 invalid argument: \\n[li*i] \ +exceeds depth of nested lists (\\n[li*lvl]) +.while \\n[li*lvl]>\\n[li*i] .li@pop +.nr par@suppress-indentation 1 \" no indentation after lists +.. +.\"------------- +.de AL +.if \\n[.$]>3 .@warning \\$0: ignoring excess arguments +.if \\n[D]>2 .tm AL $* +.ie \\n[.$]<=1 .LB \\n[Li] 0 2 1 "\\$1" +.el \{\ +. ie \\n[.$]=2 .LB 0\\$2 0 2 1 "\\$1" +. el \{\ +. ie !'\\$2'' .LB \\$2 0 2 1 "\\$1" 0 1 +. el .LB \\n[Li] 0 2 1 "\\$1" 0 1 +. \} +.\} +.. +.de ML +.if \\n[.$]>3 .@warning \\$0: ignoring excess arguments +.if \\n[D]>2 .tm ML $* +.nr li*ml-width \w@\\$1@u+1n +.if \\n[.$]<2 .LB \\n[li*ml-width]u 0 1 0 "\\$1" +.if \\n[.$]=2 .LB 0\\$2 0 1 0 "\\$1" +.if \\n[.$]=3 \{\ +. ie '\\$2'' .LB \\n[li*ml-width]u 0 1 0 "\\$1" 0 1 +. el .LB \\n[Li] 0 1 0 "\\$1" 0 1 +.\} +.. +.de VL +.if \\n[D]>2 .tm VL $* +.if \\n[.$]>3 .@warning \\$0: ignoring excess arguments +.if \\n[.$]<1 .@error \\$0: expected 1 to 3 arguments, got \\n[.$] +.ie \\n[.$]<3 .LB 0\\$1 0\\$2 0 0 +.el .LB 0\\$1 0\\$2 0 0 \& 0 1 +.. +.de BL +.if \\n[D]>2 .tm BL $* +.if \\n[.$]>2 .@warning \\$0: ignoring excess arguments +.if \\n[.$]<1 .LB \\n[Pi] 0 1 0 \\*[BU] +.if \\n[.$]=1 .LB 0\\$1 0 1 0 \\*[BU] +.if \\n[.$]=2 \{\ +. ie '\\$1'' .LB \\n[Pi] 0 1 0 \\*[BU] 0 1 +. el .LB 0\\$1 0 1 0 \\*[BU] 0 1 +.\} +.. +.de DL +.if \\n[D]>2 .tm DL $* +.if \\n[.$]>2 .@warning \\$0: ignoring excess arguments +.if \\n[.$]<1 .LB \\n[Pi] 0 1 0 \[em] +.if \\n[.$]=1 .LB 0\\$1 0 1 0 \[em] +.if \\n[.$]=2 \{\ +. ie '\\$1'' .LB \\n[Pi] 0 1 0 \[em] 0 1 +. el .LB 0\\$1 0 1 0 \[em] 0 1 +.\} +.. +.de RL +.if \\n[D]>2 .tm RL $* +.if \\n[.$]>2 .@warning \\$0: ignoring excess arguments +.if \\n[.$]<1 .LB 6 0 2 4 +.if \\n[.$]=1 .LB 0\\$1 0 2 4 +.if \\n[.$]=2 \{\ +. ie '\\$1'' .LB 6 0 2 4 1 0 1 +. el .LB 0\\$1 0 2 4 1 0 1 +.\} +.. +.\" Broken Variable List. As .VL but text begin on the next line +.de BVL +.if \\n[D]>2 .tm BVL $* +.if \\n[.$]>3 .@warning \\$0: ignoring excess arguments +.if \\n[.$]<1 .@error \\$0: expected 1 to 3 arguments, got \\n[.$] +.ie \\n[.$]<3 .LB 0\\$1 0\\$2 0 -1 +.el .LB 0\\$1 0\\$2 0 -1 \& 0 1 +.. +.\" ####### module tbl ####################################### +.\" This module is copied from groff_ms and modified for mm. +.\" Yes, it does not resemble the original anymore :-). +.\" Don't know if I missed something important. +.\" Groff_ms is written by James Clark. +.nr tbl*have-header 0 +.nr tbl*header-written 0 +.de TS +.br +.if ''\\n[.z]' .SP +.if '\\$1'H' .di tbl*header-div +.. +.de tbl@top-hook +.if \\n[tbl*have-header] \{\ +. ie \\n[.t]-\\n[tbl*header-ht]-1v .tbl@print-header +. el .sp \\n[.t]u +.\} +.. +.de tbl@bottom-hook +.if \\n[tbl*have-header] \{\ +. nr T. 1 +.\" draw bottom and side lines of boxed tables. +. T# +.\} +.nr tbl*header-written 0 +.. +.de tbl@print-header +.ev tbl*ev +'nf +.tbl*header-div +.ev +.mk #T +.nr tbl*header-written 1 +.. +.de TH +.ie '\\n[.z]'tbl*header-div' \{\ +. nr T. 0 +. T# +. br +. di +. nr tbl*header-ht \\n[dn] +. ne \\n[dn]u+1v +. nr tbl*have-header 1 +. ie '\\$1'N' .if !\\n[tbl*header-written] .tbl@print-header +. el .tbl@print-header +.\} +.el .@error \\$0: .TH without .TS H" +.. +.de TE +.ie '\\n[.z]'tbl*header-div' .@error \\$0: .TS H but no .TH before .TE +.el \{\ +. nr tbl*have-header 0 +.\} +.\" reset tabs +.TAB +.. +.de T& +.. +.\" ####### module pic ####################################### +.de PS +.if !\\n[.$]=2 \{\ +. ds pic*msg \\$0: expected 2 arguments, got \\n[.$]\" +. as pic*msg ; not preprocessed with pic?\" +. @error \\*[pic*msg] +.\} +.br +.SP .5 +.if r ds*format .if !\\n[ds*lvl] .ne (u;\\$1)+1v +.. +.de PY +.init@reset +.. +.de PE +.PY +.SP .5 +.. +.\" ####### module eq ####################################### +.\" +.nr eq*number 0 1 +.ds eq*label +.de EQ +.ds eq*label "\\$1 +.. +.de eq@check +.if !'\\*[eq*label]'' \{\ +. mk +. \" space down to middle of equation +' sp (u;(\\$1-1v)/2) +. ie (\\n[Eq]%2) \{\ +. \" label to the left +\h'|0'\\*[eq*label] +. \} +. el \{\ +. \" label to the right, possibly compensating for +. \" indented display +. ie \\n[ds*format]=1 \ +\h'|\\n[.l]u-\w'\\*[eq*label]'u+\\n[Si]n'\\*[eq*label] +. el \h'|\\n[.l]u-\w'\\*[eq*label]'u'\\*[eq*label] +. \} +. rt +.\} +.ds eq*label +.. +.de EN +.. +.\"########### module toc ################### +.\" table of contents +.nr toc*slevel 1 +.nr toc*spacing \n[Lsp]u +.nr toc*tlevel 2 +.nr toc*tab 0 +.\"----------- +.\" Table of contents with friends (module lix) +.de TC +.br +.\" print any pending displays and references +.df@print-float 3 +.if \\n[ref*flag] .RP 0 1 +.\" +.if \w@\\$1@>0 .nr toc*slevel \\$1 +.if \w@\\$2@>0 .nr toc*spacing (u;\\$2*\\n[Lsp]) +.if \w@\\$3@>0 .nr toc*tlevel \\$3 +.if \w@\\$4@>0 .nr toc*tab \\$4 +.if \\n[pg*cols-per-page]>1 .1C +.ds H1txt \\*[Licon] +.ds Tcst co +.pg@clear-hd +.EF "" +.OF "" +.pg@next-page +.\"------------- +.if d Ci .toc@read-Ci \\*[Ci] +.nf +.in 0 +.ie \\n[Oc] .hd@set-page 1 +.el \{\ +. nr toc*pn 1 1 +. af toc*pn i +. aln ;g toc*pn +. PF "''\\\\\\\\n[toc*pn]''" +. am pg@header +. nr toc*pn +1 +\\.. +.\} +.nr toc*i 4 1 +.while \\n+[toc*i]<10 \{\ +. if !'\\$\\n[toc*i]'' \{\ +. ce +\\$\\n[toc*i] +. br +. \} +.\} +.if \\n[.$]<=4 .if d TX .TX +.ie d TY .if \\n[.$]<=4 .TY +.el \{\ +. ce +\\*[Licon] +. br +. SP 3 +.\} +.if d toc*list .toc*list +.br +.\" print LIST OF XXX +.if d lix*dsfg .lix@print-ds fg FG "\\*[Lf]" \\n[.$] +.if d lix*dstb .lix@print-ds tb TB "\\*[Lt]" \\n[.$] +.if d lix*dsec .lix@print-ds ec EC "\\*[Le]" \\n[.$] +.if d lix*dsex .lix@print-ds ex EX "\\*[Lx]" \\n[.$] +.. +.\"----------- +.\" .toc@read-Ci lev1 lev2 lev3 lev4 ... lev7 +.de toc@read-Ci +.nr toc*i 0 1 +.while \\n+[toc*i]<15 \{\ +. nr toc*hl!\\n[toc*i] \\$[\\n[toc*i]] +.\} +.. +.\"----------- +.de toc@entry +.ie \\n[Sectp] \{\ +. toc@save \\$1 "\\*[hd*mark]" "\\$2" \\*[hd*sect-pg] +.\} +.el .toc@save \\$1 "\\*[hd*mark]" "\\$2" \\n[P] +.. +.als )E toc@entry +.\"----------- +.de toc@save +.\" collect maxsize of mark if string Ci don't exist. +.if !d Ci \{\ +. if !r toc*hl!\\$1 .nr toc*hl!\\$1 0 +. if \\n[toc*hl!\\$1]<=\w@\\$2@ \{\ +. nr toc*hl!\\$1 \w@\\$2@u +. \} +.\} +.am toc*list +.\" .toc@set level headernumber text pagenumber +.toc@set \\$1 "\\$2" "\\$3" \\$4 +\\.. +.. +.\"----------- +.\" level mark text pagenumber +.de toc@set +.if \\$1<=\\n[toc*slevel] .SP \\n[toc*spacing]u +.na +.fi +.nr toc*ind 0 +.nr toc*i 0 1 +.ie d Ci \{\ +. nr toc*ind +\\n[toc*hl!\\$1]u +.\} +.el \{\ +. while \\n+[toc*i]<\\$1 \{\ +. nr toc*ind +\\n[toc*hl!\\n[toc*i]]u +. \} +.\} +.nr toc*text \\n[toc*ind]u+\\n[toc*hl!\\$1]u +.in \\n[toc*text]u +.ti -\\n[toc*hl!\\$1]u +.\" +.\" length of headernumber space +.nr toc*i \\n[toc*hl!\\$1]-\w@\\$2@ +.\" +.ll \\n[@ll]u-\w@\\$4@u-2m +.ne 2v +.\" ragged right --------------------------------- +.ie \\$1>\\n[toc*tlevel] \{\ +\\$2 +. sp -1 +\\$3\ \ \ \\$4 +. br +.\} +.el \{\ +. \" unnumbered heading -------------------- +. ie '\\$2'' \{\ +. in \\n[toc*ind]u +\\$3\h'1m' +. \} +. \" normal heading ------------------------ +. el \{\ +\\$2 +. sp -1 +\\$3\h'1m' +. \} +. ll \\n[@ll]u +. sp -1 +. nr toc*sep (u;\\n[.l]-\\n[.n]-\\n[.i]-\w@\\$4@)-1m +\h'|\\n[.n]u'\l'\\n[toc*sep]u.'\h'1m'\\$4 +.\} +.ll \\n[@ll]u +.. +.\"########################### module lix ############################ +.\" LIST OF figures, tables, exhibits and equations +.nr lix*fg-nr 0 1 +.nr lix*tb-nr 0 1 +.nr lix*ec-nr 0 1 +.nr lix*ex-nr 0 1 +.aln Fg lix*fg-nr +.aln Tb lix*tb-nr +.aln Ec lix*ec-nr +.aln Ex lix*ex-nr +.\"------------ +.de FG +.lix@print-line fg Lf \\n+[lix*fg-nr] "\\$1" "\\$2" "\\$3" "\\$4" +.. +.de TB +.lix@print-line tb Lt \\n+[lix*tb-nr] "\\$1" "\\$2" "\\$3" "\\$4" +.. +.de EC +.lix@print-line ec Le \\n+[lix*ec-nr] "\\$1" "\\$2" "\\$3" "\\$4" +.. +.de EX +.lix@print-line ex Lx \\n+[lix*ex-nr] "\\$1" "\\$2" "\\$3" "\\$4" +.. +.\"------------ +.\" print line with 'figure' in the text +.\" type stringvar number text override flag refname +.de lix@print-line +.ds lix*text "\\$4 +.\" +.ie \\n[Sectf] .ds lix*numb \\n[H1]-\\$3 +.el .ds lix*numb \\$3 +.\" +.ie !\\n[Of] .ds lix*ds-form .\ \ \" +.el .ds lix*ds-form "\ \[em]\ \" +.nr lix*in \\n[.i] +.ds lix*label \\*[Li\\$1]\ \\*[lix*numb]\\*[lix*ds-form] +.if !'\\$5'' \{\ +. if !0\\$6 .ds lix*label \\*[Li\\$1]\ \\$5\\*[lix*numb]\\*[lix*ds-form] +. if 0\\$6=1 .ds lix*label \\*[Li\\$1]\ \\*[lix*numb]\\$5\\*[lix*ds-form] +. if 0\\$6=2 .ds lix*label \\*[Li\\$1]\ \\$5\\*[lix*ds-form] +.\} +.\" print line if not between DS/DE +.ie (\\n[ds*lvl]<1)&(\\n[df*float]=0) \{\ +. lix@print-text "\\*[lix*label]" "\\*[lix*text]" \\$1 \\$2 \\$7 +.\} +.el \{\ +. lix@embedded-text "\\*[lix*label]" "\\*[lix*text]" \\$1 \\$2 \\$7 +.\} +.\" +.. +.\"----------- +.\" label text type stringvar refname +.de lix@print-text +.ie \\n[Sectp] .ds lix*pgnr \\*[hd*sect-pg] +.el .ds lix*pgnr \\n[%] +.SP \\n[Lsp]u +.misc@ev-keep lix +.init@reset +.br +.ie (\w@\\$1\\$2@)>(\\n[.l]-\\n[.i]) \{\ +. in +\w@\\$1@u +. ti 0 +.\} +.el .ce 1 +\f3\\$1\fP\\$2 +.br +.ev +.\" save line for LIST OF XXX, wth is the width of the label +.if !r lix*wth\\$3 .nr lix*wth\\$3 0 +.\" find the maximum width +.if \w@\\*[lix*label]@>\\n[lix*wth\\$3] .nr lix*wth\\$3 \w@\\*[lix*label]@ +.if \\n[\\$4] .lix@ds-save \\$3 \\*[lix*pgnr] "\\*[lix*text]" "\\*[lix*label]" +.\" save reference to the figure +.if !'\\$5'' .SETR \\$5 \\*[lix*numb] +.. +.\" hide printout until diversion is evaluated +.de lix@embedded-text +\!.ie \\\\n[Sectp] .ds lix*pgnr \\\\*[hd*sect-pg] +\!.el .ds lix*pgnr \\\\n[%] +\!.SP \\\\n[Lsp]u +\!.misc@ev-keep lix +\!.ll \\n[.l]u +\!.init@reset +\!.fi +\!.ie (\w@\\$1\\$2@)>(\\\\n[.l]-\\\\n[.i]) \{\ +. in +\w@\\$1@u +\!. ti 0 +\!\f3\\$1\fP\\$2 +\!.\} +\!.el \{\ +. ce 1 +\!\f3\\$1\fP\\$2 +\!.\} +\!.br +\!.ev +.\" save line for LIST OF XXX, wth is the width of the label +\!.if !r lix*wth\\$3 .nr lix*wth\\$3 0 +.\" find the maximum width +\!.if \w@\\*[lix*label]@>\\\\n[lix*wth\\$3] .nr lix*wth\\$3 \w@\\*[lix*label]@ +\!.if \\\\n[\\$4] .lix@ds-save \\$3 \\\\*[lix*pgnr] "\\*[lix*text]" "\\*[lix*label]" +.\" save reference to the figure +\!.if !'\\$5'' .SETR \\$5 \\*[lix*numb] +.. +.\"------------ +.\" print complete list of XXXX +.de lix@print-ds +.\" arg: fg,tb,ec,ex text +.ds H1txt \\$3 +.ds Tcst \\$1 +.if !\\n[Cp] .pg@next-page +.\" print LIST OF XXXX +.\" execute user-defined macros +.if \\$4<=4 .if d TX\\$2 .TX\\$2 +.ie d TY\\$2 .if \\$4<=4 .TY\\$2 +.el \{\ +. ce +\\$3 +. SP 3 +.\} +.in \\n[lix*wth\\$1]u +.fi +.lix*ds\\$1 +.. +.\"------------ +.\" save line of list in macro +.de lix@ds-save +.\" type pagenumber text +.am lix*ds\\$1 +.lix@dsln \\$1 \\$2 "\\$3" "\\$4" \\$5 +\\.. +.. +.\"------------ +.\" print appended macro +.\" lix@dsln type pagenumber text headernumber +.de lix@dsln +.nr lix*i \\n[lix*wth\\$1]-\w@\\$4@ +.ne 4v +.ll \\n[@ll]u-\w@\\$4@u-\w@\\$2@u-2m +.ti -\\n[lix*wth\\$1]u +\\$4 +.sp -1 +\\$3\h'1m' +.sp -1 +.ll +.nr lix*sep (u;\\n[.l]-\\n[.n]-\\n[.i]-\w@\\$2@)-1m +\h'|\\n[.n]u'\l'\\n[lix*sep]u.'\h'1m'\\$2 +.SP \\n[toc*spacing]u +.. +.\"########################### module fnt ############################ +.\" some font macros. +.\"----------- +.de fnt@switch +.ul 0 +.ds fnt*tmp +.nr fnt*prev \\n[.f] +.nr fnt*i 2 1 +.while \\n+[fnt*i]<=\\n[.$] \{\ +. if \\n[fnt*i]>3 .as fnt*tmp \, +. ie (\\n[fnt*i]%2)=1 .as fnt*tmp \\$1\\$[\\n[fnt*i]] +. el .as fnt*tmp \\$2\\$[\\n[fnt*i]] +. if \\n[fnt*i]<\\n[.$] .as fnt*tmp \/ +.\} +\&\\*[fnt*tmp]\f[\\n[fnt*prev]] +.. +.\"----------- +.de B +.ie \\n[.$] .fnt@switch \f3 \f[\\n[.f]] \\$@ +.el .ft 3 +.. +.de I +.ie \\n[.$] .fnt@switch \f2 \f[\\n[.f]] \\$@ +.el .ft 2 +.. +.de R +.ie \\n[.$] .fnt@switch \f1 \f[\\n[.f]] \\$@ +.el .ft 1 +.. +.de IB +.if \\n[.$] .fnt@switch \f2 \f3 \\$@ +.. +.de BI +.if \\n[.$] .fnt@switch \f3 \f2 \\$@ +.. +.de IR +.if \\n[.$] .fnt@switch \f2 \f1 \\$@ +.. +.de RI +.if \\n[.$] .fnt@switch \f1 \f2 \\$@ +.. +.de RB +.if \\n[.$] .fnt@switch \f1 \f3 \\$@ +.. +.de BR +.if \\n[.$] .fnt@switch \f3 \f1 \\$@ +.. +.\"########################### module box ############################ +.\" draw a box around some text. Text will be kept on the same page. +.\" +.nr box*ll 0 +.\" .B1 and .B2 works like .DS +.de B1 +.if \\n[box*ll] .@error \\$0: cannot nest; missing B2? +.nr box*ll \\n[.l] +.nr box*ind \\n[.i] +.nr box*hyp \\n[.hy] +.nr box*wid \\n[.l]-\\n[.i] +.\" +.\" jump to new environment. +.ev box*ev +.di box*div +.ps \\n[@ps]u +.vs \\n[@vs]u +.in 1n +.ll (u;\\n[box*wid]-1n) +.hy \\n[.hy] +.. +.de B2 +.if !\\n[box*ll] .@error \\$0: no corresponding B1 +.br +.di +.nr box*height \\n[dn] +.ne \\n[dn]u+1v +.ll \\n[box*ll]u +.in \\n[box*ind]u +.nr box*y-pos \\n[.d]u +.nf +.box*div +.fi +\v'-1v+.25m'\ +\D'l \\n[box*wid]u 0'\ +\D'l 0 -\\n[box*height]u'\ +\D'l -\\n[box*wid]u 0'\ +\D'l 0 \\n[box*height]u' +.br +.sp -1 +.ev +.sp .20v +.in \\n[box*ind]u +.ll \\n[box*ll]u +.rm box*div +.nr box*ll 0 +.. +.\"########################### module ref ############################ +.mso refer-mm.tmac +.nr ref*nr 0 1 +.aln :R ref*nr +.nr ref*nr-width 5n +.nr ref*flag 0 \" for end-of-text +.ds Rf \v'-.4m'\s-3[\\n+[ref*nr]]\s0\v'.4m' +.\" +.\" start reference +.\"------------ +.de RS +.if !''\\$1' .ds \\$1 \v'-.4m'\s-3[\\n[ref*nr]]\s0\v'.4m' +.nr ref*flag 1 +.am ref*mac +.ref@start-print \\n[ref*nr]. +\\.. +.eo +.am ref*mac RF +.. +.\"------------ +.de RF +.ec +.am ref*mac +.ref@stop-print +\\.. +.. +.\"------------ +.de ref@start-print +.di ref*div +.in \\n[ref*nr-width]u +.ti -(\w@\\$1@u+1n) +\\$1 +.sp -1 +.. +.de ref@stop-print +.br +.di +.ne \\n[dn]u +.ev ref*ev2 +.nf +.ref*div +.ev +.rm ref*div +.if \\n[Ls] .SP \\n[Lsp]u +.. +.\"----------- +.de RP +.if !d ref*mac \{\ +. @warning \\$0: ignoring; no references defined +. return +.\} +.ie !''\\$2' .nr ref*i 0\\$2 +.el .nr ref*i \\n[Rpe] +.if \\n[ref*i]<2 .SK +.SP 2 +.ref@print-refs +.if 0\\$1<1 .nr ref*nr 0 1 +.if ((\\n[ref*i]=0):(\\n[ref*i]=2)) .SK +.. +.\"----------- +.\" called by end-of-text! +.de ref@eot-print +.\".if \\n[ref*flag] \{\ +.if d ref*mac \{\ +. if \\n[D]>2 .tm Print references, called by eot +. nr ref*flag 0 +. br +. misc@ev-keep ne +. init@reset +\c +' bp +. ev +. ref@print-refs +.\} +.. +.\"----------- +.\" prints the references +.de ref@print-refs +.toc@save 1 "" "\\*[Rp]" \\n[%] +.ce +\f2\\*[Rp]\fP +.sp +.nr ref*ll \\n[.l] +.misc@ev-keep ref*ev +.ll \\n[ref*ll]u +.in 0 +.ref*mac +.in +.rm ref*mac +.ev +.nr ref*flag 0 1 +.. +.\"########################### module app ############################ +.\" +.nr app*nr 0 1 +.af app*nr A +.nr app*dnr 0 1 +.nr app*flag 0 +.\"------------ +.\" .APP name text +.\" name == "" -> autonumber +.de APP +.\" .if \\n[.$]<2 .@error "APP: too few arguments" +.app@set-ind "\\$1" +.\" +.ds Tcst ap +.ds Apptxt \\$2 +.\" +.ie \\n[Aph] .app@header \\*[app*ind] "\\$2" +.el .bp +.app@index "\\*[app*ind]" "\\$2" +.. +.\"------------ +.\" .APPSK name pages text +.\" name == "" -> autonumber +.de APPSK +.if \\n[.$]<2 .@error \\$0: expected 2 or 3 arguments, got \\n[.$] +.app@set-ind "\\$1" +.\" +.ds Tcst ap +.ds Apptxt \\$3 +.\" +.ie \\n[Aph] .app@header \\*[app*ind] "\\$3" +.el .bp +.app@index "\\*[app*ind]" "\\$3" +.pn +\\$2 +.. +.\"------------ +.de app@set-ind +.ie \w@\\$1@ .ds app*ind \\$1 +.el \{\ +. if !\\n[app*flag] \{\ +. nr H1 0 1 +. af H1 A +. af H1h A +. nr app*flag 1 +. \} +. ds app*ind \\n+[app*nr] +. nr H1 \\n+[app*dnr] +. nr H1h \\n[app*dnr] +.\} +.\" clear lower counters +.nr app*i 1 1 +.while \\n+[app*i]<15 .nr H\\n[app*i] 0 1 +.. +.\"------------ +.de app@index +.toc@save 1 "" "\\*[App] \\$1: \\$2" \\n[%] +.. +.\"------------ +.\" app@header name text +.de app@header +.bp +.SP (u;\\n[Lsp]*4) +.ce 1 +\s+4\f3\\*[App]\ \\$1\fP\s0 +.SP (u;\\n[Lsp]*2) +.if \w@\\$2@<\\n[.l] .ce 1 +\f3\s+2\\$2\s0\fP +.SP (u;\\n[Lsp]*4) +.. +.als APPX app@header +.\"########################### module cov ############################ +.\" title stored in diversion cov*title +.\" abstract stored in diversion cov*abstract +.\" arg to abstract stored in cov*abs-arg +.\" indent stored in cov*abs-ind +.\" number of authors stored in cov*au +.\" author(s) stored in cov*au!x!y +.\" number of authors' titles stored in cov*at!x +.\" title(s) of author(s) stored in cov*at!x!y +.\" x is the author-index [1-cov*au], y is the argument-index [1-9]. +.\" author(s) firm stored in cov*firm +.\" new date (if .ND exists) is stored in cov*new-date +.\" +.\" +.ds cov*abs-name ABSTRACT +.\" +.nr cov*au 0 +.de TL +.ds @cover \\$0 +.@disable IA IE WA WE LO LT \" can't use with LT and friends +.if \\n[.$]>0 .ds cov*title-charge-case \\$1 +.if \\n[.$]>1 .ds cov*title-file-case \\$2 +.pg@disable-top-trap +.eo +.de cov*title AU +.. +.\"------------------- +.de cov@title-end +.ec +.. +.\"------------------- +.\" .AU [name [initials [loc [dept [ext [room [arg [arg [arg]]]]]]]]] +.de AU +.cov@title-end +.if !\\n[.$] .return \" AU is being used only to end a TL. +.pg@disable-top-trap +.nr cov*au +1 +.nr cov*at!\\n[cov*au] 0 \" no titles for this author yet +.nr cov*i 0 1 +.ds cov*au!\\n[cov*au]!1 +.while \\n[.$]>=\\n+[cov*i] \{\ +. ds cov*au!\\n[cov*au]!\\n[cov*i] "\\$[\\n[cov*i]] +.\} +.if (\\n[.$]>=3)&(\w@\\$3@) \{\ +. if d cov*location-\\$3] \{\ +. ds cov*au!3!\\n[cov*au] \\*[cov*location-\\$3] +. \} +.\} +.. +.\"------------------- +.\" .AT title [...] +.\" Any quantity of titles may be declared. +.\" Must be called directly after the corresponding .AU. +.de AT +.if !\\n[.$] \{\ +. @warning \\$0: ignoring; no arguments specified +. return +.\} +.nr cov*at!\\n[cov*au] \\n[.$] +.nr cov*i 0 1 +.while \\n[.$]>=\\n+[cov*i] \{\ +. ds cov*at!\\n[cov*au]!\\n[cov*i] "\\$[\\n[cov*i]] +.\} +.. +.\"------------------- +.de AF +.cov@title-end +.if !''\\$1' .ds cov*firm \\$1 +.. +.de AST +.ds cov*abs-name "\\$1\" +.. +.de AS +.pg@disable-top-trap +.if d cov*abstract .@error \\$0: only one abstract allowed +.if !''\\n[.z]' .@error \\$0: no diversion allowed (previous .AS?) +.nr cov*abs-arg 0\\$1 +.nr cov*abs-ind (n;0\\$2) +.de cov*abstract AE +.. +.de AE +.. +.\" fixed for 2000, now uses \n[year]. +.de ISODATE +. \" support for ISO-date +. nr cov*mm \\n[mo] +. nr cov*dd \\n[dy] +. af cov*mm 01 +. af cov*dd 01 +. ie '0'\\$1' \{\ +. ds cov*new-date \\*[MO\\n[mo]] \\n[dy], \\n[year] +. \} +. el \{\ +. ds cov*new-date \\n[year]-\\n[cov*mm]-\\n[cov*dd] +. \} +.. +.ISODATE 0 +.als DT cov*new-date +.de ND +.ds cov*new-date \\$1 +.. +.\" switch to ISO-date if register Iso exist: YYYY-MM-DD +.if r Iso .ISODATE 1 +.\"------------------- +.\" Save technical memorandum numbers. +.de TM +.if !\\n[.$] \{\ +. @warning \\$0: ignoring; no arguments specified +. return +.\} +.nr cov*i 0 1 +.while \\n[.$]>=\\n+[cov*i] .ds cov*mt-tm!\\n[cov*i] \\$[\\n[cov*i]] +.nr cov*mt-tm-max \\n[.$] +.. +.\"----------------------- +.\" cover sheet +.\" the file must have the following last lines (somewhere): +.\" .pg@enable-top-trap +.\" .bp 1 +.\" .pg@enable-trap +.ds cov*mt-file!0 0.MT +.ds cov*mt-file!1 0.MT +.ds cov*mt-file!2 0.MT +.ds cov*mt-file!3 0.MT +.ds cov*mt-file!4 4.MT +.ds cov*mt-file!5 5.MT +.ds cov*mt-file!6 0.MT +.\"------------ +.de MT +.ds @cover \\$0 +.@disable COVER IA IE WA WE LO LT +.ie \\n[.$] \{\ +. ie d cov*mt-file!\\$1 .ds cov*mt-type \\$1 +. el .ds cov*mt-type 6 +.\} +.el .ds cov*mt-type 1 +.ds cov*mt-addressee "\\$2 +.ds cov*mt-type-text "\\$1 +.ie d @country .ds cov*str mm/\\*[@country]_ +.el .ds cov*str mm/ +.mso \\*[cov*str]\\*[cov*mt-file!\\*[cov*mt-type]] +.. +.de COVER +.ds @cover \\$0 +.@disable IA IE WA WE LO LT MT +.ie !\\n[.$] .ds cov*cov-type ms +.el .ds cov*cov-type \\$1 +.pg@disable-top-trap +.ie d @country .ds cov*str mm/\\*[@country]_\\*[cov*cov-type].cov +.el .ds cov*str mm/\\*[cov*cov-type].cov +.mso \\*[cov*str] +.. +.\"########################### module qrf ############################ +.\" forward and backward reference thru special files. +.\" +.\" check if stderr-method is wanted +.\" This was needed when I discovered that groff was considered unsafe +.\" and groff -U didn't work. It's a workaround like the original +.\" index method, but not in my view elegant enough. +.\" +.\" init reference system +.de INITR +.ds qrf*file \\$1.qrf +.nr qrf*pass 2 +.if \\n[D]>1 .tm INITR: source \\*[qrf*file] +.ie \\n[Ref] \{\ +. tm .\\\\" Rfilename: \\*[qrf*file] +.\} +.el 'so \\*[qrf*file] +.. +.\"--------------- +.\" set a reference. +.de SETR +.if \\n[.$]<1 .@error \\$0: expected 1 or 2 arguments, got \\n[.$] +.if !r qrf*pass .tm \\$0: no .INITR in this file \" XXX: .@error? +.if \\n[Ref] \{\ +. ds qrf*name qrf*ref-\\$1 +. if \\n[D]>2 .tm SETR: ref \\*[qrf*name]=\\*[hd@mark-trimmed],\\n[%] +. \" heading-number +. ds \\*[qrf*name]-hn \\*[hd@mark-trimmed] +. \" page-number +. ds \\*[qrf*name]-pn \\n[%] +. \" +. if \\n[Ref] \{\ +. tm .ds \\*[qrf*name]-hn \\*[hd@mark-trimmed] +. tm .ds \\*[qrf*name]-pn \\n[%] +. if !'\\$2'' .tm .ds \\*[qrf*name]-xx \\$2 +. \} +.\} +.. +.\"--------------- +.\" get misc-string +.\" If two arg -> set var. arg to misc-string. +.de GETST +.if \\n[.$]<1 .@error \\$0: expected 1 or 2 arguments, got \\n[.$] +.if !r qrf*pass .tm \\$0: no .INITR in this file \" XXX: .@error? +.ds qrf*name qrf*ref-\\$1 +. if d \\*[qrf*name]-xx \{\ +. ie \\n[.$]>1 .ds \\$2 \\*[\\*[qrf*name]-xx] +. el \\*[\\*[qrf*name]-xx]\c +. \} +.\} +.. +.\"--------------- +.\" get header-number +.\" If two arg -> set var. arg to header-number. +.de GETHN +.if \\n[.$]<1 .@error \\$0: expected 1 or 2 arguments, got \\n[.$] +.if !r qrf*pass .tm \\$0: no .INITR in this file \" XXX: .@error? +.ds qrf*name qrf*ref-\\$1 +.if d \\*[qrf*name]-hn \{\ +. ie \\n[.$]>1 .ds \\$2 \\*[\\*[qrf*name]-hn] +. el \\*[\\*[qrf*name]-hn]\c +.\} +.. +.\"--------------- +.\" get page-number +.\" If two arg -> set var. arg to page-number. +.de GETPN +.if \\n[.$]<1 .@error \\$0: expected 1 or 2 arguments, got \\n[.$] +.if !r qrf*pass .tm \\$0: no .INITR in this file \" XXX: .@error? +.ds qrf*name qrf*ref-\\$1 +.if d \\*[qrf*name]-pn \{\ +. ie \\n[.$]>1 .ds \\$2 \\*[\\*[qrf*name]-pn] +. el \\*[\\*[qrf*name]-pn]\c +.\} +.. +.\"---------- +.de GETR +.if \\n[.$]<1 .@error \\$0: expected an argument +.ie !r qrf*pass .tm \\$0: no .INITR in this file" \" XXX: .@error? +.el \{\ +. GETHN \\$1 Qrfh +. GETPN \\$1 Qrfp +\\*[Qrf] +.\} +.. +.\"########################### module ind ############################ +.\"-------------------- +.\" Another type of index system +.\" INITI type filename [macro] +.de INITI +.if \\n[.$]<2 .@error \\$0: expected 2 or 3 arguments, got \\n[.$] +.\" ignore if INITI has already been used +.if d ind*file .@error \\$0: index file name already set +.ds ind*file \\$2.ind +.if \\n[D]>1 .tm INITI: source \\*[ind*file] +.if !d ind*file .@error \\$0: index file name not specified +.ds ind*type \\$1 +.if \\n[Ref] \{\ +. if \\n[.$]>2 .tm .\\\\" Imacro: \\$3 +.\} +.. +.\"--------------- +.de IND +.if !d ind*file .@error \\$0: no active index; call INITI" +.if \\n[D]>1 .tm IND: type=\\*[ind*type] +.ds ind*ref \" empty +.if '\\*[ind*type]'N' .ds ind*ref \\n[%] +.if '\\*[ind*type]'H' .ds ind*ref \\*[hd*mark] +.if '\\*[ind*type]'B' .ds ind*ref \\*[hd*mark]\t\\n[%] +.if '\\*[ind*ref]'' .@abort invalid index type '\\*[ind*type]' +.\" +.ds ind*line \\$1 +.while \\n[.$]>0 \{\ +. shift +. as ind*line \t\\$1 +.\} +.as ind*line \\*[ind*ref] +.if \\n[Ref] .tm .\\\\" IND \\*[ind*line] +.. +.\" print index +.de INDP +.ie \\n[Ref] .tm .\\\\" Index: \\*[ind*file] +.el \{\ +. if !\\n[Cp] .pg@next-page +. \" print INDEX +. \" execute user-defined macros +. if d TXIND .TXIND +. ie d TYIND .TYIND +. el \{\ +. SK +. ce +\\*[Index] +. SP 3 +. 2C +. nf +. \} +' so \\*[ind*file] +. ie d TZIND .TZIND +. el \{\ +. fi +. 1C +. \} +.\} +.rm ind*file +.. +.\"########################### module let ############################ +.\" Letter macros +.\"------------------------ +.\" Formal closing +.de FC +.df@print-float 3 +.ie \\n[.$] .ds let*i \\$1 +.el .ds let*i \\*[Letfc] +.ie d let*type .let@fc_\\*[let*type] "\\*[let*i]" \\$@ +.el .let@mt-closing "\\*[let*i]" \\$@ +.. +.\"------- +.de let@mt-closing +.ne 5v +.in (u;\\n[.l]/2) +.sp +\\$1 +.in +.. +.\"------------------------ +.\" Signature line +.de SG +.ie d let*type .let*lt-sign \\$@ +.el .let*mt-sign \\$@ +.. +.\"------------------------ +.de let*lt-sign +.\" We hard-code the SG macro name here since this macro is internal but +.\" only SG calls it. +.if !d let@sg_\\*[let*type] .@error SG: letter type '\\*[let*type]' \ +undefined +.df@print-float 3 +.nr let*i 0 1 +.nr let*j 0 +.while \\n+[let*i]<=\\n[let*wa-n] \{\ +.if \\n[let*i]=\\n[let*wa-n] .nr let*j 1 +.let@sg_\\*[let*type] "\\*[let*wa-name!\\n[let*i]]" "\\*[let*wa-title!\\n[let*i]]" \\n[let*i] \\n[let*j] \\$@ +.\} +.. +.\"------------------------ +.\" Memorandum signature +.de let*mt-sign +.df@print-float 3 +.ne \\n[cov*au]u*4v +.ie \\n[.$]>1 .nr let*k 1 +.el .nr let*k \\n[cov*au] +.ds let*tmp \" empty +.if d cov*au!\\n[let*k]!3 \{\ +. as let*tmp \\*[cov*au!\\n[let*k]!3]\" +. if d cov*au!\\n[let*k]!4 \ +. as let*tmp -\\*[cov*au!\\n[let*k]!4]-\" +.\} +.nr let*i 0 1 +.while \\n+[let*i]<=\\n[cov*au] \{\ +. if \\n[let*i]>1 .as let*tmp /\" +. if d cov*au!\\n[let*i]!2 .as let*tmp \\*[cov*au!\\n[let*i]!2]\" +.\} +.if !''\\$1' .as let*tmp -\\$1 +.in (u;\\n[.l]/2) +.nf +.nr let*i 0 1 +.while \\n+[let*i]<=\\n[cov*au] \{\ +. ne 3v+\\n[cov*at!\\n[let*i]]v +. SP 3v +. if \\n[let*i]=\\n[let*k] \{\ +\Z'\h'-(u;\\n[.l]/2)'\\*[let*tmp]'\c +. \} +\\*[cov*au!\\n[let*i]!1] +. nr let*j 0 1 +. while \\n+[let*j]<=\\n[cov*at!\\n[let*i]] \{\ +\\*[cov*at!\\n[let*i]!\\n[let*j]] +. \} +.\} +.fi +.in +.. +.\"------------------------ +.\" Approval signature +.de AV +.ne 6v +.nf +.sp +.ie \\n[.$]<2 \\*[Letapp] +.el .sp +.sp 2 +.ie n ______________________________ ______________ +.el \D'l 25m 0'\h'4m'\D'l 12m 0' +\Z'\\$1'\h'29m'\f[\\*[@sdf_font]]\\*[Letdate]\fP +.fi +.. +.\"------------------------ +.\" Letter signature +.de AVL +.ne 6v +.nf +.sp 3 +.ie n ______________________________ +.el \D'l 25m 0' +\Z'\\$1' +.fi +.. +.\"------------------------ +.\" Letter type +.\" let@header is called from the header. It is supposed +.\" to remove the alias itself. +.de LT +.ds @cover LT +.@disable AF AS AE AT AU COVER CS OK TL MT \" same list as LO +.ds let*type BL +.nr Pi 5 +.nr Pt 0 +.if !''\\$1' .ds let*type \\$1 +.if !d let@head_\\*[let*type] .@error \\$0: unknown letter type '\\$1' +.shift +.als let@header let@head_\\*[let*type] +.let@init_\\*[let*type] \\$@ +.if \n[D]>1 .tm Letter type \\*[let*type] +.. +.\"----------- +.\" Blocked letter +.de let@init_BL +.. +.de let@head_BL +.rm let@header +.let@print-head 1 +.. +.de let@sg_BL +.ne 5v +.nf +.in (u;\\n[.l]/2) +.sp 3v +\\$1 +\\$2 +.in +.if \\$4 .sp +.if \w'\\$5'&\\$4 \\$5 +.fi +.. +.als let@fc_BL let@mt-closing +.\"----------- +.\" Semiblocked letter +.de let@init_SB +.nr Pt 1 +.. +.de let@head_SB +.rm let@header +.let@print-head 1 +.. +.als let@sg_SB let@sg_BL +.als let@fc_SB let@mt-closing +.\"----------- +.\" Full-blocked letter +.de let@init_FB +.. +.de let@head_FB +.rm let@header +.let@print-head +.. +.de let@sg_FB +.ne 5v +.nf +.sp 3v +\\$1 +\\$2 +.if \\$4 .sp +.if \w'\\$5'&\\$4 \\$5 +.fi +.. +.de let@fc_FB +.ne 5v +.sp +\\$1 +.. +.\"----------- +.\" Simplified letter +.de let@init_SP +.. +.de let@head_SP +.rm let@header +.let@print-head +.. +.de let@sg_SP +.nf +.if \\$3=1 .sp +.sp +.ie '\\$2'' .misc@toupper "\\$1" +.el .misc@toupper "\\$1, \\$2" +.if \\$4 .sp +.if \w'\\$5'&\\$4 \\$5 +.fi +.. +.de let@fc_SP +.\" Simplified letters have no formal closing, just space before SG. +.sp 2 +.. +.\"-------------------------------------- +.\" Print the letter-head +.de let@print-head +.nf +.sp |11 +.if '1'\\$1' .in (u;\\n[.l]/2) +.\" ---- WA +.ie d let@wa-div .let@wa-div +.el .sp 3 +.\" ---- datum +\\*[cov*new-date] +.sp +.if '1'\\$1' .if !d let*lo-CN .if !d let*lo-RN .sp 2 +.\" ---- Confidential +.if d let*lo-CN \{\ +. ti 0 +. ie !''\\*[let*lo-CN]' \\*[let*lo-CN] +. el \\*[LetCN] +. sp +.\} +.\" ---- Reference +.if d let*lo-RN \{\ +\\*[LetRN] \\*[let*lo-RN] +. sp +.\} +.\" ---- IA +.sp +.in 0 +.nr let*i 0 1 +.while \\n+[let*i]<=\\n[let*ia-n] \{\ +\\*[let*ia-name!\\n[let*i]] +\\*[let*ia-title!\\n[let*i]] +.\} +.if d let@ia-div .let@ia-div +.\" ---- Attention +.if d let*lo-AT \{\ +. sp +\\*[LetAT] \\*[let*lo-AT] +.\} +.\" ---- Salutation +.if !'\\*[let*type]'SP' .if d let*lo-SA \{\ +. sp +. ti 0 +. ie !''\\*[let*lo-SA]' \\*[let*lo-SA] +. el \\*[LetSA] +.\} +.\" ---- Subject +.if d let*lo-SJ \{\ +. ie '\\*[let*type]'SP' \{\ +. sp 2 +. misc@toupper "\\*[let*lo-SJ]" +. sp +. \} +. el \{\ +. sp +. if '\\*[let*type]'SB' .ti +5m +\\*[LetSJ] \f[\\*[@sdf_font]]\\*[let*lo-SJ]\fP +. \} +.\} +.. +.\"------------------- +.\" .IA [name [title]] +.nr let*ia-n 0 1 +.de IA +.if \\n[.$] .ds let*ia-name!\\n+[let*ia-n] \\$1 +.if \\n[.$]>1 .ds let*ia-title!\\n[let*ia-n] \\$2 +.ev let@ev +.init@reset +'nf +.di let@ia-div +.eo +.. +.de IE +.di +.ec +.ev +.. +.\"------------------- +.\" .WA [name [title]] +.nr let*wa-n 0 1 +.de WA +.if \\n[.$] .ds let*wa-name!\\n+[let*wa-n] \\$1 +.if \\n[.$]>1 .ds let*wa-title!\\n[let*wa-n] \\$2 +.ev let@ev +.init@reset +'nf +.di let@wa-div +.it \\n[Letwam] let@wa-drain +.eo +.. +.\"------ +.de let@wa-drain +.it +.di +.di let@wa-junk +.. +.\"------ +.de WE +.it +.ec +.di +.ev +.if d let@wa-junk .rm let@wa-junk +.. +.\"------------------- +.\" Copy to +.de NS +.sp +.ie !''\\$2' .ds let*str \\$1 +.el \{\ +. ie \\n[.$]>0 \{\ +. ie !\w'\\$1' .ds let*str \\*[Letns!\\*[Letnsdef]] +. el \{\ +. ie d Letns!\\$1 .ds let*str \\*[Letns!\\$1] +. el .ds let*str \\*[Letns!copy](\\$1)\\*[Letns!to] +. \} +. \} +. el .ds let*str \\*[Letns!\\*[Letnsdef]] +.\} +.ne 2 +.nf +\\*[let*str] +.. +.de NE +.fi +.. +.\"------------------- +.\" Letter options +.de LO +.ds @cover \\$0 +.@disable AF AS AE AT AU COVER CS OK TL MT \" same list as LT +.if !\\n[.$] \{\ +. @warning \\$0: ignoring; no arguments specified +. return +.\} +.if !d Let\\$1 .@error \\$0: unrecognized option '\\$1' +.ds let*lo-\\$1 \\$2 +.if \n[D]>1 .tm Letter option \\$1 \\$2 +.. +.\"-------------------- +.\" Start with a clean slate +.init@reset +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/contrib/mm/mm.am b/contrib/mm/mm.am new file mode 100644 index 0000000..191dbce --- /dev/null +++ b/contrib/mm/mm.am @@ -0,0 +1,128 @@ +# Copyright 1991-2020 Free Software Foundation, Inc. +# +# This file 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 . +# +# mm.am +# + +mm_srcdir = $(top_srcdir)/contrib/mm +mm_builddir = $(top_builddir)/contrib/mm + +bin_SCRIPTS += mmroff + +man1_MANS += contrib/mm/mmroff.1 +man7_MANS += \ + contrib/mm/groff_mm.7 \ + contrib/mm/groff_mmse.7 + +# Files installed in $(tmacdir)/mm +MMFILES = \ + contrib/mm/mm/0.MT \ + contrib/mm/mm/5.MT \ + contrib/mm/mm/4.MT \ + contrib/mm/mm/ms.cov \ + contrib/mm/mm/se_ms.cov +mmdir = $(tmacdir)/mm +dist_mm_DATA = $(MMFILES) + +# Files installed in $(tmacdir) +tmacmmdir = $(tmacdir) +dist_tmacmm_DATA = contrib/mm/refer-mm.tmac + +MMEXAMPLEFILES=\ + contrib/mm/examples/letter.mm + +mmexampledir=$(exampledir)/mm +dist_mmexample_DATA = $(MMEXAMPLEFILES) + +EXTRA_DIST += \ + contrib/mm/ChangeLog \ + contrib/mm/examples \ + contrib/mm/Makefile.sim \ + contrib/mm/mm \ + contrib/mm/NOTES \ + contrib/mm/README \ + contrib/mm/groff_mm.7.man \ + contrib/mm/groff_mmse.7.man \ + contrib/mm/mmroff.1.man \ + contrib/mm/mmroff.pl + +mm_TESTS = \ + contrib/mm/tests/LT_SP_AU_without_AT_works.sh \ + contrib/mm/tests/LT_SP_multi-word_LO_SJ_works.sh \ + contrib/mm/tests/MT-1-reports-all-TM-numbers.sh \ + contrib/mm/tests/MT_5_includes_AT_in_SG.sh \ + contrib/mm/tests/P-indentation-works.sh \ + contrib/mm/tests/ms_cover_sheet_robust_to_missing_AF.sh \ + contrib/mm/tests/mse_has-sufficient-footnote-space.sh \ + contrib/mm/tests/place-equation-labels-correctly-in-displays.sh \ + contrib/mm/tests/remove-stale-bib-entry-data.sh \ + contrib/mm/tests/short-pages-do-not-overflow-stack.sh +TESTS += $(mm_TESTS) +EXTRA_DIST += \ + $(mm_TESTS) \ + contrib/mm/tests/artifacts/60657.ref + +mmroff: $(mm_srcdir)/mmroff.pl + $(AM_V_GEN)$(SED) \ + -e 's;[@]PERL[@];$(PERL);' \ + -e 's;[@]VERSION[@];$(VERSION);' \ + $(mm_srcdir)/mmroff.pl \ + >$@.tmp \ + && chmod +x $@.tmp \ + && mv $@.tmp $@ + +# special installation rules for m.tmac, mse.tmac, mmse.tmac, mm.tmac +install-data-local: install_mm +install_mm: + -test -d $(DESTDIR)$(tmacdir) || $(mkinstalldirs) $(DESTDIR)$(tmacdir) + -test -d $(DESTDIR)$(mmdir) || $(mkinstalldirs) $(DESTDIR)$(mmdir) + $(RM) $(DESTDIR)$(tmacdir)/tmac.$(tmac_m_prefix)m + $(RM) $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)m.tmac + $(INSTALL_DATA) $(mm_srcdir)/m.tmac \ + $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)m.tmac + $(SED) -e "s;^.mso m.tmac;.mso $(tmac_m_prefix)m.tmac;g" \ + $(mm_srcdir)/mse.tmac > $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)mse.tmac + @$(SED) -e "s;^.mso mse.tmac;.mso $(tmac_m_prefix)mse.tmac;g" \ + $(mm_srcdir)/mmse.tmac > $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)mmse.tmac + @$(SED) -e "s;^.mso m.tmac;.mso $(tmac_m_prefix)m.tmac;g" \ + $(mm_srcdir)/mm.tmac > $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)mm.tmac +uninstall-local: uninstall_mm +uninstall_mm: + if test -d $(DESTDIR)$(mmexampledir); then \ + rmdir $(DESTDIR)$(mmexampledir); \ + fi + $(RM) $(DESTDIR)$(tmacdir)/tmac.$(tmac_m_prefix)m + $(RM) $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)m.tmac + $(RM) $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)mm.tmac + $(RM) $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)mse.tmac + $(RM) $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)mmse.tmac + -rmdir $(DESTDIR)$(tmacdir)/mm + +# Special distribution rule: we copy all .tmac files from contrib/mm +dist-hook: dist_mm +dist_mm: + chmod u+w $(distdir)/contrib/mm/ + for i in $(mm_srcdir)/*.tmac; do \ + cp -f $$i $(distdir)/contrib/mm/; \ + done + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/contrib/mm/mm.tmac b/contrib/mm/mm.tmac new file mode 100644 index 0000000..98e311d --- /dev/null +++ b/contrib/mm/mm.tmac @@ -0,0 +1,4 @@ +.\" -*- nroff -*- +.\" mm.tmac +.\" +.do mso m.tmac diff --git a/contrib/mm/mm/0.MT b/contrib/mm/mm/0.MT new file mode 100644 index 0000000..b06a4b8 --- /dev/null +++ b/contrib/mm/mm/0.MT @@ -0,0 +1,175 @@ +.ig + +Copyright (C) 1991-2020 Free Software Foundation, Inc. +mm is written by Jörgen Hägg + +mm 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. + +mm 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 . + +Please submit bug reports using groff's 'BUG-REPORT' file to +http://savannah.gnu.org/bugs/?group=groff. +.. +. +.\"------------ +.\" Cover sheet. Memorandum type 0-3 and "string". +.\"------------ +.if !r Au .nr Au 1 +.de cov@print-title +.if !d cov*title .@error title not defined; call TL and AU before MT +.MOVE 4.8c 1.5c +.S 8 +subject: +.sp -1.1 +.S +.PGFORM +.ft \\*[@sdf_font] +.ll 9c +.fi +.cov*title +.ft +.ll +.nf +.if d cov*title-charge-case \fBCharge Case \\*[cov*title-charge-case]\fP +.if d cov*title-file-case \fBFile Case \\*[cov*title-file-case]\fP +.fi +.. +.\"------------ +.de cov@print-authors +.\" The following diagnostic might be unreachable. +.if !r cov*au .@error no authors defined; call AU before MT +.MOVE 5.7c 13.3c +.nf +.S 8 +\\$1: +.br +.S +.sp -1 +.in 0.8c +.ft \\*[@sdf_font] +.nr cov*i 0 1 +.while \\n+[cov*i]<=\\n[cov*au] \{\ +. cov@print-au1 \\n[cov*i] 1 +. if \\n[Au] \{\ +. cov@print-au2 \\n[cov*i] 3 4 +. cov@print-au2 \\n[cov*i] 6 5 +. cov@print-au1 \\n[cov*i] 7 +. cov@print-au1 \\n[cov*i] 8 +. cov@print-au1 \\n[cov*i] 9 +. \} +. if \\n[cov*i]<\\n[cov*au] .SP 1 +.\} +.ft +.if r cov*mt-tm-max \{\ +. SP 1 +. nr cov*i 0 1 +. ft \\*[@sdf_font] +TM +. in 1.5c +. sp -1 +. while \\n+[cov*i]<=\\n[cov*mt-tm-max] \\*[cov*mt-tm!\\n[cov*i]] +. in +. ft +.\} +.fi +.PGFORM +.. +.\"------------ +.\" index arg1 +.de cov@print-au1 +.if d cov*au!\\$1!\\$2 \\*[cov*au!\\$1!\\$2] +.. +.\"------------ +.de cov@print-au2 +.\" index arg1 arg2 +.if d cov*au!\\$1!\\$2 \\*[cov*au!\\$1!\\$2] \c +.if \\$3=5 .if d cov*au!\\$1!\\$3 x\c +.if d cov*au!\\$1!\\$3 \\*[cov*au!\\$1!\\$3]\c +.br +.. +.\"------------ +.de cov@print-date +.MOVE 4.8c 13.3c +.S 8 +.nf +\\$1: +.br +.S +.sp -1 +.in 0.8c +\f[\\*[@sdf_font]]\\*[cov*new-date]\fP +.br +.fi +.PGFORM +.. +.\"------------ +.de cov@print-firm +.if d cov*firm \{\ +. MOVE 2.8c 0 17.7c +. S 18 +. rj 1 +\fB\\*[cov*firm]\fP +. S +. PGFORM +.\} +.. +.\"------------ +.de cov@print-abstract +.SP 3 +.if d cov*abstract \{\ +. misc@ev-keep cov*ev +. if \\n[cov*abs-ind]>0 \{\ +. in +\\n[cov*abs-ind]u +. ll -\\n[cov*abs-ind]u +. \} +. ce +\fI\\$1\fP +. SP 1.5 +. fi +. cov*abstract +. br +. ev +.\} +.. +.\"----------------- +.ds cov*mt0-txt!1 MEMORANDUM FOR FILE +.ds cov*mt0-txt!2 PROGRAMMER'S NOTES +.ds cov*mt0-txt!3 ENGINEER'S NOTES +.if d cov*default-firm .if !d cov*firm .ds cov*firm \\*[cov*default-firm] +.\" +.if !d cov*mt-printed \{\ +. cov@print-firm +. cov@print-title subject +. cov@print-date date +. cov@print-authors from +. cov@print-abstract \\*[cov*abs-name] +. SP 3 +. if (\*[cov*mt-type]>=1)&(\*[cov*mt-type]<=3) \{\ +. ce +\fI\*[cov*mt0-txt!\*[cov*mt-type]]\fP +. SP 1.5 +. \} +. if \*[cov*mt-type]=6 \{\ +. ce +\fI\*[cov*mt-type-text]\fP +. SP 1.5 +. \} +. pg@enable-top-trap +. pg@enable-trap +. ds cov*mt-printed +.\} +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/contrib/mm/mm/4.MT b/contrib/mm/mm/4.MT new file mode 100644 index 0000000..1fd31df --- /dev/null +++ b/contrib/mm/mm/4.MT @@ -0,0 +1,110 @@ +.ig + +Copyright (C) 1991-2020 Free Software Foundation, Inc. +mm is written by Jörgen Hägg + +mm 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. + +mm 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 . + +Please submit bug reports using groff's 'BUG-REPORT' file to +http://savannah.gnu.org/bugs/?group=groff. +.. +. +.\"------------ +.\" Cover sheet. Memorandum type 4 +.\"------------ +.de cov@print-title +.if !d cov*title .@error title not defined; call TL and AU before MT +.MOVE 2.8c +.S +2 +.ad c +.fi +.B +.cov*title +.br +.S +.R +.ad b +.. +.\"------------ +.de cov@print-authors +.\" The following diagnostic might be unreachable. +.if !r cov*au .@error no authors defined; call AU before MT +.SP 0.5 +.I +.S +1 +.nr cov*i 0 1 +.while \\n+[cov*i]<=\\n[cov*au] \{\ +.ce +\\*[cov*au!\\n[cov*i]!1] +.br +.\} +.S +.R +.. +.\"------------ +.de cov@print-firm +.if d cov*firm \{\ +. SP 0.5 +. ce +\\*[cov*firm] +.\} +.. +.\"------------ +.de cov@print-abstract +.SP 2 +.if d cov*abstract \{\ +. misc@ev-keep cov*ev +. init@reset +. if \\n[cov*abs-ind]>0 \{\ +. in +\\n[cov*abs-ind]u +. ll -\\n[cov*abs-ind]u +. \} +. ce +\fI\\*[cov*abs-name]\fP +. SP 2 +. fi +. cov*abstract +. br +. ev +.\} +.. +.\"----------------- +.if d cov*default-firm .if !d cov*firm .ds cov*firm \\*[cov*default-firm] +.if !d cov*mt-printed \{\ +. cov@print-title +. cov@print-authors +. cov@print-firm +. if d cov*abstract \{\ +. if !\n[cov*abs-arg] .cov@print-abstract +. \} +. SP 2 +. nr hd*cur-bline \n[nl] +. ds cov*mt-printed +. pg@enable-top-trap +. pg@enable-trap +.\} +.de CS +.pg@disable-top-trap +.SK +.cov@print-title +.cov@print-authors +.cov@print-firm +.cov@print-abstract +.. +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/contrib/mm/mm/5.MT b/contrib/mm/mm/5.MT new file mode 100644 index 0000000..10bf410 --- /dev/null +++ b/contrib/mm/mm/5.MT @@ -0,0 +1,61 @@ +.ig + +Copyright (C) 1991-2020 Free Software Foundation, Inc. +mm is written by Jörgen Hägg + +mm 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. + +mm 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 . + +Please submit bug reports using groff's 'BUG-REPORT' file to +http://savannah.gnu.org/bugs/?group=groff. +.. +. +.\"------------ +.\" Cover sheet. Memorandum type 5 +.\"------------ +.de cov@print-title +.if !d cov*title .@error title not defined; call TL and AU before MT +.B +.ll 9c +.fi +.cov*title +.R +.ll +.nf +.if d cov*title-charge-case \fBCharge Case \\*[cov*title-charge-case]\fP +.if d cov*title-file-case \fBFile Case \\*[cov*title-file-case]\fP +.fi +.. +.\"------------ +.de cov@print-date +.rj 1 +\f[\\*[@sdf_font]]\\*[cov*new-date]\fP +.br +.. +.\"------------ +.if !d cov*mt-printed \{\ +. SP 1.9c +. cov@print-title +. SP 1.2c +. cov@print-date +. SP 3 +. pg@enable-top-trap +. pg@enable-trap +. ds cov*mt-printed +.\} +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/contrib/mm/mm/ms.cov b/contrib/mm/mm/ms.cov new file mode 100644 index 0000000..cea6073 --- /dev/null +++ b/contrib/mm/mm/ms.cov @@ -0,0 +1,121 @@ +.\" -*- nroff -*- +.ig + +Copyright (C) 1991-2020 Free Software Foundation, Inc. +mm is written by Jörgen Hägg + +mm 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. + +mm 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 . + +Please submit bug reports using groff's 'BUG-REPORT' file to +http://savannah.gnu.org/bugs/?group=groff. +.. +. +.\"------------ +.\" Cover sheet. Mostly like ms cover. +.\"------------ +.de cov@print-title +.ie !d cov*title .@error COVEND: no title (TL) defined +.el \{\ +. in 0 +. misc@ev-keep cov*ev +. init@reset +. ad c +. hy 0 +. fi +. B +. cov*title +. br +. ad b +. R +. ev +.\} +.. +.\"------------ +.de cov@print-authors +.ie !\\n[cov*au] .@error COVEND: no authors (AU) defined +.el \{\ +. SP +. nr cov*i 0 1 +. while \\n+[cov*i]<=\\n[cov*au] \{\ +. ds cov*aname \\*[cov*au!\\n[cov*i]!1] +. ce +. nop \fI\\*[cov*aname]\fP +. nr cov*j 0 1 +. while \\n+[cov*j]<=\\n[cov*at!\\n[cov*i]] \{\ +. ds cov*atitle \\*[cov*at!\\n[cov*i]!\\n[cov*j]] +. ce +. nop \s-1\\*[cov*atitle]\s0 +. \} +. rm cov*atitle +. \} +. rm cov*aname +.\} +.. +.\"------------ +.de cov@print-firm +.if d cov*firm \{\ +. SP .5 +. ce +. nop \\*[cov*firm] +.\} +.. +.\"------------ +.de cov@print-abstract +.SP 2 +.if d cov*abstract \{\ +. misc@ev-keep cov*ev +. init@reset +. if \\n[cov*abs-ind]>0 \{\ +. in +\\n[cov*abs-ind]u +. ll -\\n[cov*abs-ind]u +. \} +. ce +\fI\\$1\fP +. SP 1.5 +. fi +. cov*abstract +. br +. ev +.\} +.. +.\"------------ +.de cov@print-date +.SP 2 +\f[\\*[@sdf_font]]\\*[cov*new-date]\fP +.. +.\"----------------- +.de COVEND +.br +.if d cov*default-firm \ +. if !d cov*firm .ds cov*firm \\*[cov*default-firm] +.sp |4.2c +.cov@print-title +.cov@print-authors +.cov@print-firm +.cov@print-abstract "\\*[cov*abs-name]" +.cov@print-date +.pg@enable-top-trap +.bp 1 +.pg@enable-trap +.if r cov*abs-arg .if \\n[cov*abs-arg] \{\ +. cov@print-abstract ABSTRACT +. SP 2 +.\} +.. +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/contrib/mm/mm/se_ms.cov b/contrib/mm/mm/se_ms.cov new file mode 100644 index 0000000..7ee7ec3 --- /dev/null +++ b/contrib/mm/mm/se_ms.cov @@ -0,0 +1,3 @@ +.\" -*- nroff -*- +.mso mm/ms.cov +.nr cur*abstract-ll 11c diff --git a/contrib/mm/mmroff.1.man b/contrib/mm/mmroff.1.man new file mode 100644 index 0000000..7920c70 --- /dev/null +++ b/contrib/mm/mmroff.1.man @@ -0,0 +1,171 @@ +.TH mmroff @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +mmroff \- cross-referencing front end for GNU +.I roff mm +macro package +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 1989-2023 Free Software Foundation, Inc. +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of +.\" this manual under the conditions for verbatim copying, provided that +.\" the entire resulting derived work is distributed under the terms of +.\" a permission notice identical to this one. +.\" +.\" Permission is granted to copy and distribute translations of this +.\" manual into another language, under the above conditions for +.\" modified versions, except that this permission notice may be +.\" included in translations approved by the Free Software Foundation +.\" instead of in the original English. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_mmroff_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY mmroff +.RB [ \-x ] +.IR groff-argument \~.\|.\|. +.YS +. +. +.SY mmroff +.B \-\-help +.YS +. +. +.SY mmroff +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I mmroff +is a simple wrapper for +.IR groff , +used to expand cross references in +.IR m@TMAC_M_PREFIX@m ; +see +.MR groff_mm @MAN7EXT@ . +. +It runs +.I groff +with the +.B \-mm +option twice, +first with +.B \-z +and +.B \-rRef=1 +to populate cross-reference and index files with their corresponding +entries, +and then again to produce the document. +. +It also handles the inclusion of PostScript images with the +.B PIC +macro. +. +Documents that do not use these features of +.I "groff mm" +(the +.BR INITI , +.BR IND , +.BR INDP , +.BR INITR , +.BR SETR , +.BR GETHN , +.BR GETPN , +.BR GETR , +.BR GETST , +and +.B PIC +macros) +do not require +.IR \%mmroff . +. +. +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-\-help +displays +a usage message, +while +.B \-\-version +shows version information; +both exit afterward. +. +. +.TP +.B \-x +Create or update the cross-reference file and exit. +. +. +.\" ==================================================================== +.SH Authors +.\" ==================================================================== +. +.I mmroff +was written by +.MT jh@\:axis\:.se +J\[o ad]rgen H\[a ad]gg +.ME +of Lund, +Sweden. +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.MR groff_mm @MAN7EXT@ , +.MR groff_mmse @MAN7EXT@ , +.MR groff @MAN1EXT@ , +.MR @g@troff @MAN1EXT@ , +.MR @g@tbl @MAN1EXT@ , +.MR @g@pic @MAN1EXT@ , +.MR @g@eqn @MAN1EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_mmroff_1_man_C] +.do rr *groff_mmroff_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/contrib/mm/mmroff.pl b/contrib/mm/mmroff.pl new file mode 100644 index 0000000..af8bf90 --- /dev/null +++ b/contrib/mm/mmroff.pl @@ -0,0 +1,179 @@ +#!@PERL@ +# Copyright (C) 1989-2020 Free Software Foundation, Inc. +# +# This file 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 . + +use strict; +use warnings; + +(my $progname = $0) =~s @.*/@@; + +# runs groff in safe mode, that seems to be the default +# installation now. That means that I have to fix all nice +# features outside groff. Sigh. +# I do agree however that the previous way opened a whole bunch +# of security holes. + +my $no_exec; + +if (grep(/^--help$/, @ARGV)) { + print "usage: mmroff [-x] [groff-option ...] [file ...]\n"; + exit; +} + +if (grep(/^--version$/, @ARGV)) { + print "mmroff (groff) @VERSION@\n"; + exit; +} + +# check for -x and remove it +if (grep(/^-x$/, @ARGV)) { + $no_exec++; + @ARGV = grep(!/^-x$/, @ARGV); +} + +# mmroff should always have -mm, but not twice +@ARGV = grep(!/^-mm$/, @ARGV); +my $check_macro = "groff -rRef=1 -z -mm @ARGV"; +my $run_macro = "groff -mm @ARGV"; + +my (%cur, $rfilename, $max_height, $imacro, $max_width, @out, @indi); +open(MACRO, "$check_macro 2>&1 |") || die "run $check_macro:$!"; +while() { + if (m#^\.\\" Rfilename: (\S+)#) { + # remove all directories just to be more secure + ($rfilename = $1) =~ s#.*/##; + next; + } + if (m#^\.\\" Imacro: (\S+)#) { + # remove all directories just to be more secure + ($imacro = $1) =~ s#.*/##; + next; + } + if (m#^\.\\" Index: (\S+)#) { + # remove all directories just to be more secure + my $f; + ($f = $1) =~ s#.*/##; + &print_index($f, \@indi, $imacro); + @indi = (); + $imacro = ''; + next; + } + my $x; + if (($x) = m#^\.\\" IND (.+)#) { + $x =~ s#\\##g; + my @x = split(/\t/, $x); + grep(s/\s+$//, @x); + push(@indi, join("\t", @x)); + next; + } + if (m#^\.\\" PIC id (\d+)#) { + %cur = ('id', $1); + next; + } + if (m#^\.\\" PIC file (\S+)#) { + &psbb($1); + &ps_calc($1); + next; + } + if (m#^\.\\" PIC (\w+)\s+(\S+)#) { + eval "\$cur{'$1'} = '$2'"; + next; + } + s#\\ \\ $##; + push(@out, $_); +} +close(MACRO); + +sub Die { + print STDERR "$progname: fatal error: @_\n"; + exit 1; +} + +if ($rfilename) { + push(@out, ".nr pict*max-height $max_height\n") if defined $max_height; + push(@out, ".nr pict*max-width $max_width\n") if defined $max_width; + + open(OUT, ">$rfilename") + or &Die("unable to create $rfilename:$!"); + print OUT '.\" references', "\n"; + my $i; + for $i (@out) { + print OUT $i; + } + close(OUT); +} + +exit 0 if $no_exec; +exit system($run_macro); + +sub print_index { + my ($f, $ind, $macro) = @_; + + open(OUT, ">$f") or &Die("unable to create $f:$!"); + my $i; + for $i (sort @$ind) { + if ($macro) { + $i = '.'.$macro.' "'.join('" "', split(/\t/, $i)).'"'; + } + print OUT "$i\n"; + } + close(OUT); +} + +sub ps_calc { + my ($f) = @_; + + my $w = abs($cur{'llx'}-$cur{'urx'}); + my $h = abs($cur{'lly'}-$cur{'ury'}); + $max_width = $w if $w > $max_width; + $max_height = $h if $h > $max_height; + + my $id = $cur{'id'}; + push(@out, ".ds pict*file!$id $f\n"); + push(@out, ".ds pict*id!$f $id\n"); + push(@out, ".nr pict*llx!$id $cur{'llx'}\n"); + push(@out, ".nr pict*lly!$id $cur{'lly'}\n"); + push(@out, ".nr pict*urx!$id $cur{'urx'}\n"); + push(@out, ".nr pict*ury!$id $cur{'ury'}\n"); + push(@out, ".nr pict*w!$id $w\n"); + push(@out, ".nr pict*h!$id $h\n"); +} + + +sub psbb { + my ($f) = @_; + + unless (open(IN, $f)) { + print STDERR "Warning: Postscript file $f:$!"; + next; + } + while() { + if (/^%%BoundingBox:\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/) { + $cur{'llx'} = $1; + $cur{'lly'} = $2; + $cur{'urx'} = $3; + $cur{'ury'} = $4; + } + } + close(IN); +} + + +1; +# Local Variables: +# mode: CPerl +# End: diff --git a/contrib/mm/mmse.tmac b/contrib/mm/mmse.tmac new file mode 100644 index 0000000..3239aa2 --- /dev/null +++ b/contrib/mm/mmse.tmac @@ -0,0 +1,4 @@ +.\" -*- nroff -*- +.\" mmse.tmac +.\" +.do mso mse.tmac diff --git a/contrib/mm/mse.tmac b/contrib/mm/mse.tmac new file mode 100644 index 0000000..8184b14 --- /dev/null +++ b/contrib/mm/mse.tmac @@ -0,0 +1,166 @@ +.ig + +Copyright (C) 1991-2020 Free Software Foundation, Inc. +mm is written by Jörgen Hägg + +mm 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. + +mm 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 . + +Please submit bug reports using groff's 'BUG-REPORT' file to +http://savannah.gnu.org/bugs/?group=groff. +.. +. +.\" +.\" Swedish version of mm +.\" +.\" See m.tmac for version-information. +.ds @country se +. +.mso m.tmac +.\" The two-letter code for Swedish is 'sv', not 'se' (this is Northern Sami) +.mso sv.tmac +. +.ISODATE +. +.\" Page length +.if !r L .nr @pl 28.5c +.\" page width +.if !r W .nr @ll 13c +.\" page offset +.if !r O .nr @po 3.5c +.\" set the above parameters +.ll \n[@ll]u +.po \n[@po]u +.pl \n[@pl]u +. +.nr pg*footer-size 4v\" 1v+footer+even/odd footer+1v +.\"------------------------------------------------ +.\" Dokumentnamn +.ds LetDNAMN +.\" Mottagarens datum +.ds LetMDAT Ert datum: +.\" Bilaga +.ds LetBIL Bilaga \" +.\" Kompletteringsuppgift +.ds LetKOMP +.\" Dokumentbeteckning eller dokumentnummer +.ds LetDBET +.\" Beteckning (ärendebeteckning i form av diarienummer e.d. +.ds LetBET Beteckning: +.\" Mottagarens beteckning. +.ds LetMBET Er beteckning: +.\" Antal sidor +.ds LetSIDOR +.\" Svensk standard med högerställd löptext. --------------------- +.de let@init_SVH +.in 4.57c +.ll 17.57c +.. +.de let@head_SVH +.rm let@header +.let@print_SV H +.. +.de let@sg_SVH +.. +.de let@fc_SVH +.. +.\" Svensk standard med vänsterställd löptext. --------------------- +.de let@init_SVV +.. +.de let@head_SVV +.rm let@header +.let@print_SV V +.. +.de let@sg_SVV +.. +.de let@fc_SVV +.. +.\"-------------------------------- +.de let@print_SV +.nf +.\" pos T0 ----------------------------------- +.in 0 +.sp |3 +.if d let@wa-div .let@wa-div +.\"----- addressat +.if '\\$1'V' .if d let@ia-div \{\ +. sp |10 +. let@ia-div +.\} +.\" pos T4 ----------------------------------- +.in 9.14c +.\"----- kompletteringsuppgift +.if d let*lo-KOMP \{\ +. sp |2 +\\*[let*lo-KOMP] +.\} +.\"----- dokumentnamn +.if d let*lo-DNAMN \{\ +. sp |3 +\\*[let*lo-DNAMN] +.\} +.\"----- datum +.if d cov*new-date \{\ +. sp |5 +Datum: +\\*[cov*new-date] +.\} +.\"----- mottagarens datum +.if d let*lo-MDAT \{\ +. sp |7 +\\*[LetMDAT] +\\*[let*lo-MDAT] +.\} +.\"----- addressat +.if '\\$1'H' .if d let@ia-div \{\ +. sp |10 +. let@ia-div +.\} +.\" pos T6 ----------------------------------- +.in 13.72c +.\"----- mottagarens beteck. +.if d let*lo-MBET \{\ +. sp |7 +\\*[LetMBET] +\\*[let*lo-MBET] +.\} +.\"----- dokumentbeteck. +.if d let*lo-BET \{\ +. sp |3 +\\*[LetBET] +\\*[let*lo-BET] +.\} +.\" pos T7 ----------------------------------- +.in 16c +.\"----- bilaga +.if d let*lo-BIL \{\ +. sp |2 +\\*[LetBIL]\\*[let*lo-BIL] +.\} +.\" +.\"----- sidnummer +.sp |3 +.ie d let*lo-SIDOR \\n[%] (\\*[let*lo-SIDOR]) +.el \\n[%] +.\" +.\" Ta hand om special +.if d TP .TP +.sp |17 +.. +.\" ----------------------------------- +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/contrib/mm/refer-mm.tmac b/contrib/mm/refer-mm.tmac new file mode 100644 index 0000000..800568a --- /dev/null +++ b/contrib/mm/refer-mm.tmac @@ -0,0 +1,109 @@ +.\" refer-mm.tmac +.\" +.\" Refer support for mm macros. +.\" +.\" Copyright (C) 2011-2020 Free Software Foundation, Inc. +.\" Written by Werner Lemberg (wl@gnu.org) +.\" +.\" This file 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 . +.\" +.\" Please send comments to groff@gnu.org. +. +. +.als ref*error @warning +. +.de ref*text-label-start +. FS "\\$1" +.. +.de ref*text-label-end +. FE +.. +. +.de ref*biblio-item-start +. ref@start-print "\\$1" +.. +.de ref*biblio-item-start-nolabel +. ref@start-print \& +.. +.de ref*biblio-item-end +. ref@stop-print +.. +. +.ds ref*refnum-start \" empty +.ds ref*refnum-end .\" +. +.ds [. \v'-.4m'\s-3[\" +.ds .] ]\s0\v'.4m'\" +. +.ds ref*spec!0 Q A T S V N P I C D O +.ds ref*spec!1 Q A T J S V N P I C D O +.ds ref*spec!2 Q A T S V P I C D O +.ds ref*spec!3 Q A T B E S V P I C D O +.ds ref*spec!4 Q A T R G P I C D O +. +.ds ref*spec!A ", " " +.ds ref*spec!B """ " " "in \fI" "" "\fP" +.ds ref*spec!D """ " " "(" ")" +.ds ref*spec!E ", " " "ed.\& " +.ds ref*spec!G """ " " "(" ")" +.ds ref*spec!J ", " " "\fI" "" "\fP" +.ds ref*spec!N """ "(" "" ")" +.ds ref*spec!O ". " " +.ds ref*spec!P ", " " "p.\~" +.ds ref*spec!PP ", " " "pp.\~" +.ds ref*spec!T ", " " "\(lq" "" "\(rq" +.ds ref*spec!T:0 ", " " "\fI" "" "\fP" +.ds ref*spec!T:2 ", " " "\fI" "" "\fP" +.ds ref*spec!V """ " " "\fB" "\fR" +.ds ref*spec!dflt ", " " +. +.\" For the bibliography section, we emulate the .RS/.RF mechanism of mm by +.\" collecting references (enclosed with .]- and .][) in macro 'ref*mac'. +.\" This macro gets expanded while calling the .RP macro. +. +.de ref*][-first-pass +. ec +. am ref*mac +. ds [F "\\*([F\" +. ][ "\\$1" "\\$2" +. ref*reset +\\.. +.. +. +.de ref*biblio-start-hook +. als ref*][-second-pass ][ +. als ][ ref*][-first-pass +. de ref*item-start-hook +. eo +. am ref*mac ][ +\\.. +.. +. +.de ref*biblio-end-hook +. als ][ ref*][-second-pass +. rm ref*item-start-hook +. als ref*print ref*end-print +. RP +. als ref*print ref*normal-print +.. +. +.mso refer.tmac +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/contrib/mm/tests/LT_SP_AU_without_AT_works.sh b/contrib/mm/tests/LT_SP_AU_without_AT_works.sh new file mode 100755 index 0000000..7589966 --- /dev/null +++ b/contrib/mm/tests/LT_SP_AU_without_AT_works.sh @@ -0,0 +1,50 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +# Regression-test Savannah #60373 (3/3). +# +# Ensure that an author name (AU) with no title (AT) isn't rendered with +# a trailing comma. +# +# Thanks to Robert Goulding for the reproducer. + +EXAMPLE='.LT SP +.WA "John Doe" +Nowhere, +USA. +.WE +.IA "Jane Smith" +Somewhere, +UK. +.IE +.LO SJ "Letter of Introduction" +.LO SA "Dear Ms.\& Smith" +.P +This is the text of the letter. +.FC "Yours sincerely," +.SG' + +echo "$EXAMPLE" \ + | "$groff" -Tascii -P-cbou -mm \ + | grep -Eqx '[[:space:]]+JOHN DOE[[:space:]]*' + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/contrib/mm/tests/LT_SP_multi-word_LO_SJ_works.sh b/contrib/mm/tests/LT_SP_multi-word_LO_SJ_works.sh new file mode 100755 index 0000000..98c3fda --- /dev/null +++ b/contrib/mm/tests/LT_SP_multi-word_LO_SJ_works.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +# Regression-test Savannah #60373 (1/3). +# +# Ensure that a multi-word subject line (LO SJ) gets rendered. +# +# Thanks to Robert Goulding for the reproducer. + +EXAMPLE='.LT SP +.WA "John Doe" +Nowhere, +USA. +.WE +.IA "Jane Smith" +Somewhere, +UK. +.IE +.LO SJ "Letter of Introduction" +.LO SA "Dear Ms.\& Smith" +.P +This is the text of the letter. +.FC "Yours sincerely," +.SG' + +echo "$EXAMPLE" \ + | "$groff" -Tascii -P-cbou -mm \ + | grep -Eqx '[[:space:]]+LETTER OF INTRODUCTION[[:space:]]*' + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/contrib/mm/tests/MT-1-reports-all-TM-numbers.sh b/contrib/mm/tests/MT-1-reports-all-TM-numbers.sh new file mode 100755 index 0000000..3224e7c --- /dev/null +++ b/contrib/mm/tests/MT-1-reports-all-TM-numbers.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# +# Copyright (C) 2023 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +fail= + +wail () { + echo ...FAILED >&2 + fail=YES +} + +# Regression-test Savannah #63613. The identifiers of all technical +# memoranda should be formatted. + +input='.TL +My Memo +.AU "Random Hacker" +.TM 23-SKIDOO 24-URTHRU +.MT 1 +This is my memo. +. +There are many like it but this one is mine.' + +output=$(printf "%s\n" "$input" | "$groff" -mm -Tascii -P-cbou) +echo "$output" + +echo "checking that first TM number is present" >&2 +echo "$output" | grep -q "23-SKIDOO" || wail + +echo "checking that second TM number is present" >&2 +echo "$output" | grep -q "24-URTHRU" || wail + +test -z "$fail" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/contrib/mm/tests/MT_5_includes_AT_in_SG.sh b/contrib/mm/tests/MT_5_includes_AT_in_SG.sh new file mode 100755 index 0000000..4f23d53 --- /dev/null +++ b/contrib/mm/tests/MT_5_includes_AT_in_SG.sh @@ -0,0 +1,43 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +# Regression-test Savannah #57034. +# +# Ensure that an author's title (if any) is written in the signature. +# +# Thanks to Ken Mandelberg for the reproducer. + +EXAMPLE='.TL +Inquiry +.AU "John SMITH" +.AT "Director" +.MT 5 +.P +sentence +.FC Sincerely, +.SG' + +echo "$EXAMPLE" \ + | "$groff" -Tascii -P-cbou -mm \ + | grep -Eqx '[[:space:]]+Director[[:space:]]*' + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/contrib/mm/tests/P-indentation-works.sh b/contrib/mm/tests/P-indentation-works.sh new file mode 100755 index 0000000..5be7efd --- /dev/null +++ b/contrib/mm/tests/P-indentation-works.sh @@ -0,0 +1,135 @@ +#!/bin/sh +# +# Copyright (C) 2023 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +fail= + +wail () { + echo ...FAILED >&2 + fail=YES +} + +# Regression-test Savannah #54909. Check other cases as well. + +input='.P +P1 not indented. +.P 0 +P2 not indented. +.P 1 +P3 indented. +.nr Pt 2 +.P +P4 indented. +.H 1 Heading +.P +P5 not indented. +.P +P6 indented. +.H 3 "Run-in heading." +Some text. +.P +P7 indented. +.DS +display +.DE +.P +P8 not indented. +.P +P9 indented. +.BL +.LI +list item +.LE +.P +P10 not indented. +.P +P11 indented.' + +output=$(printf "%s\n" "$input" | "$groff" -mm -Tascii -P-cbou) +echo "$output" + +# P1 not indented. +# +# P2 not indented. +# +# P3 indented. +# +# P4 indented. +# +# +# 1. Heading +# +# P5 not indented. +# +# P6 indented. +# +# 1.0.1 Run-in heading. Some text. +# +# P7 indented. +# +# display +# +# P8 not indented. +# +# P9 indented. +# +# o list item +# +# P10 not indented. +# +# P11 indented. + +echo "checking that initial untyped paragraph not indented" >&2 +echo "$output" | grep -Eqx ' {7}P1 not indented\.' || wail + +echo "checking that initial type 0 paragraph not indented" >&2 +echo "$output" | grep -Eqx ' {7}P2 not indented\.' || wail + +echo "checking that first paragraph after Pt=2 indented" >&2 +echo "$output" | grep -Eqx ' {12}P3 indented\.' || wail + +echo "checking that second paragraph after Pt=2 indented" >&2 +echo "$output" | grep -Eqx ' {12}P4 indented\.' || wail + +echo "checking that first paragraph after heading not indented" >&2 +echo "$output" | grep -Eqx ' {7}P5 not indented\.' || wail + +echo "checking that second paragraph after heading indented" >&2 +echo "$output" | grep -Eqx ' {12}P6 indented\.' || wail + +echo "checking that paragraph after run-in heading indented" >&2 +echo "$output" | grep -Eqx ' {12}P7 indented\.' || wail + +echo "checking that first paragraph after display not indented" >&2 +echo "$output" | grep -Eqx ' {7}P8 not indented\.' || wail + +echo "checking that second paragraph after display indented" >&2 +echo "$output" | grep -Eqx ' {12}P9 indented\.' || wail + +echo "checking that first paragraph after list not indented" >&2 +echo "$output" | grep -Eqx ' {7}P10 not indented\.' || wail + +echo "checking that second paragraph after list indented" >&2 +echo "$output" | grep -Eqx ' {12}P11 indented\.' || wail + +test -z "$fail" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/contrib/mm/tests/artifacts/60657.ref b/contrib/mm/tests/artifacts/60657.ref new file mode 100644 index 0000000..ed7f6f3 --- /dev/null +++ b/contrib/mm/tests/artifacts/60657.ref @@ -0,0 +1,11 @@ +%K 1 +%A First Author +%B First Book +%O Test one + +%K 2 +%A Second Author +%B Second Book + +%K 3 +%A Third Author diff --git a/contrib/mm/tests/ms_cover_sheet_robust_to_missing_AF.sh b/contrib/mm/tests/ms_cover_sheet_robust_to_missing_AF.sh new file mode 100755 index 0000000..66086f8 --- /dev/null +++ b/contrib/mm/tests/ms_cover_sheet_robust_to_missing_AF.sh @@ -0,0 +1,39 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +# Regression-test Savannah #60915. +# +# Ensure that a missing firm definition doesn't disrupt cover sheet +# layout. + +EXAMPLE='.COVER +.ND 2020-07-17 +.TL +The Great American Novel +.AU "Eileen M. Plausible" +.COVEND' + +echo "$EXAMPLE" \ + | "$groff" -Tascii -P-cbou -mm \ + | grep -Fqx ' 2020-07-17' # 7 spaces + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/contrib/mm/tests/mse_has-sufficient-footnote-space.sh b/contrib/mm/tests/mse_has-sufficient-footnote-space.sh new file mode 100755 index 0000000..936d9e5 --- /dev/null +++ b/contrib/mm/tests/mse_has-sufficient-footnote-space.sh @@ -0,0 +1,77 @@ +#!/bin/sh +# +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +# Regression-test Savnnah #63398. + +input='.de M +. nr N \\\\$1-1 +. if \\\\$1 .M \\\\nN +Sed ut perspiciatis, unde omnis iste natus error sit voluptatem +accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab +illo inventore veritatis et quasi architecto beatae vitae dicta sunt, +explicabo.\\\\*F +. FS +footnote text +. FE +.. +.P +.M 16' + +# .de M +# . nr N \\$1-1 +# . if \\$1 .M \\nN +# Sed ut perspiciatis, unde omnis iste natus error sit voluptatem +# accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab +# illo inventore veritatis et quasi architecto beatae vitae dicta sunt, +# explicabo.\\*F +# .FS +# blather +# .FE +# Nemo enim ipsam voluptatem, quia voluptas sit, aspernatur +# aut odit aut fugit, sed quia consequuntur magni dolores eos, qui ratione +# voluptatem sequi nesciunt, neque porro quisquam est, qui dolorem ipsum, +# quia dolor sit amet consectetur adipiscivelit, sed quia non-numquam eius +# modi tempora incidunt, ut labore et dolore magnam aliquam quaerat +# voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam +# corporis suscipitlaboriosam, nisi ut aliquid ex ea commodi consequatur? +# Quis autem vel eum iure reprehenderit, qui inea voluptate velit esse, +# quam nihil molestiae consequatur, vel illum, qui dolorem eum fugiat, quo +# voluptas nulla pariatur? At vero eos et accusamus et iusto odio +# dignissimos ducimus, qui blanditiis praesentium voluptatum deleniti +# atque corrupti, quos dolores et quas molestias excepturi sint, obcaecati +# cupiditate non-provident, similique sunt in culpa, qui officia deserunt +# mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum +# facilis est et expedita distinctio. Nam libero tempore, cum soluta +# nobis est eligendi optio, cumque nihil impedit, quo minus id, quod +# maxime placeat, facere possimus, omnis voluptas assumenda est, omnis +# dolor repellendus. Temporibus autem quibusdam et aut officiis debitis +# aut rerum necessitatibus saepe eveniet, ut et voluptates repudiandae +# sint et molestiae non-recusandae. Itaque earum rerum hic tenetur a +# sapiente delectus, ut aut reiciendis voluptatibus maiores alias +# consequatur aut perferendis doloribus asperiores repellat. +# .. +# .P +# .M 4 + +output=$(echo "$input" | "$groff" -mm -mmse -Tps) + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/contrib/mm/tests/place-equation-labels-correctly-in-displays.sh b/contrib/mm/tests/place-equation-labels-correctly-in-displays.sh new file mode 100755 index 0000000..1970397 --- /dev/null +++ b/contrib/mm/tests/place-equation-labels-correctly-in-displays.sh @@ -0,0 +1,62 @@ +#!/bin/sh +# +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +fail= + +wail () { + echo FAILED >&2 + fail=YES +} + +# Regression-test Savannah #62190. Check left- and center-aligned +# displayed equations as well. + +input='.DS L +.EQ (1) +p = q +.EN +.DE +.DS I +.EQ (2) +w = z +.EN +.DE +.DS C +.EQ (3) +x = y +.EN +.DE' + +output=$(printf "%s\n" "$input" | "$groff" -e -mm -Tascii -P-cbou) + +echo "checking left-aligned displayed equation" >&2 +echo "$output" | grep -Eq 'p=q {54}\(1\)' || wail + +echo "checking indented displayed equation" >&2 +echo "$output" | grep -Eq 'w=z {49}\(2\)' || wail + +echo "checking centered displayed equation" >&2 +echo "$output" | grep -Eq 'x=y {26}\(3\)' || wail + +test -z "$fail" || exit 1 + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/contrib/mm/tests/remove-stale-bib-entry-data.sh b/contrib/mm/tests/remove-stale-bib-entry-data.sh new file mode 100755 index 0000000..5fb68e6 --- /dev/null +++ b/contrib/mm/tests/remove-stale-bib-entry-data.sh @@ -0,0 +1,72 @@ +#!/bin/sh +# +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +fail= + +wail () { + echo FAILED >&2 + fail=YES +} + +# Regression-test Savannah #60657. Ensure data from a bibliographic +# entry don't carry over to the next. + +# Locate directory containing our test artifacts. +artifact_dir= + +for buildroot in . .. ../.. +do + d=$buildroot/contrib/mm/tests/artifacts + if [ -d "$d" ] + then + artifact_dir=$d + break + fi +done + +# If we can't find it, we can't test. +test -z "$artifact_dir" && exit 77 # skip + +input=".R1 +bibliography $artifact_dir/60657.ref +.R2" + +output=$(echo "$input" | "$groff" -R -mm -Tascii -P-cbou) + +echo "checking first entry" +echo "$output" \ + | grep -q "1\. First Author in First Book\. Test one\.$" \ + || wail + +echo "checking second entry" +echo "$output" \ + | grep -q "2\. Second Author in Second Book\.$" \ + || wail + +echo "checking third entry" +echo "$output" \ + | grep -q "3\. Third Author\.$" \ + || wail + +test -z "$fail" || exit 1 + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/contrib/mm/tests/short-pages-do-not-overflow-stack.sh b/contrib/mm/tests/short-pages-do-not-overflow-stack.sh new file mode 100755 index 0000000..4be0e13 --- /dev/null +++ b/contrib/mm/tests/short-pages-do-not-overflow-stack.sh @@ -0,0 +1,59 @@ +#!/bin/sh +# +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file 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 . +# + +groff="${abs_top_builddir:-.}/test-groff" + +fail= + +wail () { + echo FAILED >&2 + fail=YES +} + +# Regression-test Savannah #24048. Pages that are too short to +# accommodate minimal header and footer requirements should not cause +# infinite trap recursion. + +input='.COVER +.TL +Title +.AU "R. Thurston Howell" +.AT "Professor of Agnotology" "Publisher, Posterior Analytics Weekly" +.COVEND +.P +Main matter goes here.' + +echo "checking that sample document fits using default length" >&2 +output=$(printf "%s\n" "$input" \ + | "$groff" -b -mm -Tascii -P-cbou) || wail + +echo "checking that sample document fits using -rL5v" >&2 +output=$(printf "%s\n" "$input" \ + | "$groff" -b -rL5v -mm -Tascii -P-cbou) || wail + +echo "checking that sample document fails gracefully using -rL4v" >&2 +error=$(printf "%s\n" "$input" \ + | "$groff" -b -rL4v -mm -Tascii -P-cbou -z 2>&1) +# Assume that >= 10 lines of stderr must be due to a giant backtrace. +test $(echo "$error" | wc -l) -lt 10 || wail + +test -z "$fail" + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/contrib/mom/BUGS b/contrib/mom/BUGS new file mode 100644 index 0000000..6e7a828 --- /dev/null +++ b/contrib/mom/BUGS @@ -0,0 +1,985 @@ + -*- text -*- + Copyright 2004-2020 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. + +Assume that anything that doesn't work or behaves oddly is a bug. +The documentation should be taken as the authoritative source for +how things ought to be. + +Post to the groff mailing list with bug reports, questions and +suggestions, or contact me directly at: + + peter@schaffter.ca + +If writing me directly, please include the word "groff" or "mom" in +the Subject line or you risk my spam filters nuking your message. + +--Peter Schaffter + +==================================================================== + +Version 2.5_c +============= + +#R_MARGIN not being respected in PAGEWIDTH. +---Fixed--- + +Version 2.5_b +============= +PAGINATE not restoring page numbers after being disabled. +---Fixed--- + +Sentence space not being restored after a terminating REF. +---Fixed--- + +CODE not always correctly restoring point size of text +afterwards. +---Fixed--- + +BLANKPAGE broken when columns are enabled. +---Fixed--- + +Registers #FROM_COVERTITLE and #FROM_DOC_COVERTITLE not being +cleared in macro COLLATE. +---Fixed--- + +DROPCAP not calculating distance to FOOTER trap correctly. +---Fixed--- + +Version 2.5 +=========== + +Page offset not being restored correctly after CENTRE_BLOCK. +---Fixed--- + +LEFT_HANG intermittently causing type to be raised out of position. +---Fixed--- + +$CHAPTER_STRING default not being set in COPYSTYLE. +---Fixed--- + +When using mom bare metal, NEWPAGE depositing a superfluous blank +page unless B_MARGIN has been set explicitly. +---Fixed--- + +Version 2.4-4_e +=============== + +LANDSCAPE arg to PAPER not being appended to $PAPER so PAPER +isn't picking it up when PAPER is called at the top of DEFAULTS. +---Fixed--- + +BLANKPAGE with NULL arg printing incorrect page number when page +numbering is restored. +---Fixed--- + +BLANKPAGE with DIVIDER arg spitting out one too many pages. +---Fixed--- + +Hyphens appearing mid-line in runon footnotes. +---Fixed--- + +Version 2.4-4_b +=============== +SMALLCAPS introducing a small indent equal to a wordspace when +called after PP. +---Fixed--- + +Version 2.4-4_a +=============== +BIBLIOGRAPHY_SPACING not being respected. +---Fixed--- + +Version 2.4-4 +============= +Default PAPER settings overwriting user-entered PAGEWIDTH, +PAGELENGTH, and PAGE. +---Fixed--- + +QUOTE and BLOCKQUOTE indents shifting after page breaks. +---Fixed--- + +Version 2.4-3 +============= +TYPEWRITE: Inline \*[PREV] calling \*[ULX] without explicitly +returning to TYPEWRITER font. +---Fixed--- + +%u field in refer databases not triggering ref*type 0 (Internet +reference). +---Fixed--- + +Idem field of refer databases overwriting first occurrence of author +name. +---Fixed--- + +Captions not fully respecting TYPEWRITE. +---Fixed--- + +COVERTEXT not fully respecting TYPEWRITE. +---Fixed--- + +Changes to font family inside a COVERTEXT block not being reset to +default document family when the block is terminated. +---Fixed--- + +Unwanted linespace before labels above tables. +---Fixed--- + +Label number of AUTOLABEL_TABLES incrementing by 2 instead of 1. +---Fixed--- + +Page number of the page before a bibliography not printing. +---Fixed--- + +Version 2.4-1 +============= +tbl not respecting pre-tbl fill mode. +---Fixed--- + +COVER and DOC_COVER not always capturing pertinent title and +copyright. +---Fixed--- + +Version 2.4 +=========== +BIBLIOGRAPHY output broken. +---Fixed--- + +Version 2.3 +=========== +.PS/.PE not working at start of documents without a preceding .PP. +---Fixed--- + +Output of .PS/.PE not centered correctly (the default). +---Fixed--- + +Version 2.2-a +============= +Omitting postfixed digit from ROMAN/roman args to LIST not +generating warning. +---Fixed--- + +FOOTERS causing infinite loop. +---Fixed--- + +Version 2.2 +=========== +COVERTITLE not picking up style params. +---Fixed--- + +FORCE_RECTO and BLANKPAGES not co-operating. +---Fixed--- + +TOC and LISTS_OF leading not being picked up and/or adjusted +properly. +---Fixed--- + +PDF outline putting first doc ahead of TOC in PDF outline when +TOC is auto-relocated and COVER has the BLANKPAGE arg. +---Fixed--- + +Version 2.1-b +============= +Toggling of pagination broken. +---Fixed--- + +HEADERS_AND_FOOTERS printing footer at top of second page instead of +printing header unless FOOTER_ON_FIRST_PAGE is called. +---Fixed--- + +Version 2.1-a +============= + +Some part-by-part formatting changes to headers not being recognized +when global header options have been invoked. +---Fixed--- + +Version 2.1 +=========== + +UNDERSCORE adding an extra space after underlined text. +---Fixed--- + +bug #44903: 2 column output misplaced +---Fixed--- + +PDF_IMAGE and FLOAT environments conflicting. +---Fixed--- + +DROPCAP picking up color from last call to .gcolor. +---Fixed--- + +PAD not working properly with mom's indent macros. +---Fixed--- + +Margin notes not respecting differing recto-verso margins. +---Fixed--- + +Graphical object macros not clearing fill/no-fill registers and +modes. +---Fixed--- + +LIST ALPHA emitting a number register to output. +---Fixed--- + +HEADER_PLAIN and FOOTER_PLAIN broken. +---Fixed--- + +Version 2.0-c_1 +=============== + +.TS with no H causing FN_OVERFLOW warning when there are footnotes +on same page. +---Fixed--- + +PDF_TARGET "descriptive text" not printing. +---Fixed--- + +Version 2.0-c +============= + +Endnotes page offset wrong if (BLOCK)QUOTE last macro before +ENDNOTES. +---Fixed--- + +Character translation of diacritics from lowercase to caps broken. +---Fixed--- + +Spacing not being restored (.ns/.rs) after a HEADING that falls at +the top of the page. +---Fixed--- + +Version 2.0-b +============= + +When line numbering is enabled, line numbers after QUOTE being reset +to '0'. +---Fixed--- + +When line numbering is enabled for QUOTE and BLOCKQUOTE, style +params for line numbers not being applied. +---Fixed--- + +TOC overprinting footer when it comes immediately after +BIBLIOGRAPHY. +---Fixed--- + +TOC page numbers not printing when positioned at top of page. +---Fixed--- + +TOC page numbers not always incrementing properly. +---Fixed--- + +Version 2.0-a_1 +=============== + +QUOTE_INDENT not being respected in FLOAT. +---Fixed--- + +SMARTQUOTES OFF broken. +---Fixed--- + +DOCHEADER_LEAD being reset to default after first chapter. +---Fixed--- + +Forced floats that fit on the page causing floats on the next page +to be treated as forced. +---Fixed--- + +Forced floats not advancing on the page after output if the float is +forced to the next page, causing running text to overprint. +---Fixed--- + +Text after deferred floats not being shimmed properly. +---Fixed--- + +Tables that span pages overprinting first two lines of table on new +pages. +---Fixed--- + +PDF_IMAGE not respecting .IL, .IR, or .IB. +---Fixed--- + +AUTOLEAD not sticking after .START. +---Fixed--- + +Version 2.0-a +============= + +Footer not printing on first page when HEADERS_AND_FOOTERS enabled. +---Fixed--- + +$AUTHOR string missing. +---Fixed--- + +Version 2.0 +=========== + +tbl macros .TS/.TE not working unless inside a float. +---Fixed--- + +Terminal period after page number(s) in refer items not always +printing. +---Fixed--- + +==================================================================== + +Version 1.6-a +=========== + +Footnotes on last page of columnar docs before a TOC getting printed +at bottom of last column, not current column. +--Fixed--- + +HEADER_RULE OFF turning off headers completely. +---Fixed--- + +FINIS depositing a blank final page when invoked too close to the +bottom margin. +---Fixed--- + +Version 1-6 +=========== + +ENDNOTE_STRING_CAPS not disabling caps when arg given. +---Fixed--- + +Superfluous blank line before paragraphs with paraheads. +---Fixed--- + +Paraheads causing line numbering to overprint two line numbers. +---Fixed--- + +Endless loop when DOC_LEAD_ADJUST is disabled. +---Fixed--- + +In the case where the list doesn't fit the page, -mom inserts +an extra page with one word and a warning about "environment stack +underflow" and then continues on the following page. +--Fixed-- + +PRINTSTYLE TYPEWRITE not respecting TYPEWRITER_FAMILY when DOCTYPE +is LETTER. +---Fixed--- + +Version 1.5-d +============= + +ILX not quitting left indents set within ITEM. +---Fixed---- + +Version 1.5-c +============= + +COVER_COUNTS_PAGES incrementing pagenum by 1 too many. +---Fixed--- + +HEADER/FOOTER_RECTO strings vanishing when the default CAPS option +is turned off. +---Fixed--- + +TQ not removing QUAD arg from cleared tabs. +---Fixed--- + +DROPCAP_OFF trap remaining in effect after dropcap has been +processed. +---Fixed--- + +PARAHEAD_SIZE 0 resulting in 0-sized type! +---Fixed--- + +When DOC_LEAD is called to change document leading in collated docs, +document leading steadily increases by small amounts at each +subsequent call to COLLATE. +---Fixed--- + +(DOC_)COVER requests annihilating families used in various document +elements if those families differ from the document's overall +family. +---Fixed--- + +Covers and doccovers not always respecting null pagenumbering. +--Fixed--- + +Version 1.5-b +============= +Use of \E*[UC] and \E*[LC] inside strings for HDRFTR_RECTO and +HDRFTR_VERSO breaking headers. +---Not fixable. CAPS option added to HDRFTR_RECTO/VERSO to + accommodate situations where capitalized reserved + strings(\*[$TITLE], \*[$AUTHOR], etc) are desired.--- + +COLLATE depositing a blank page if last output line before it falls +at the bottom of running text. +---Fixed--- + +PRINTSTYLE TYPEWRITE not setting $FAMILY or $FONT or $PP_FT, with +consequences for COLLATE. +---Fixed--- + +FOOTNOTE_MARKERS OFF not disabling footnote markers if used before +START. +---Fixed--- + +1st footnotes with overflow vanishing altogether with an +"automatically ending diversion 'FN_OVERFLOW' on exit" warning. +---Fixed--- + +Right hand margin notes vanishing when an RH margin note overflows +to the next output page. +---Fixed (I think)--- + +Doc bug; \*[S] escape incorrectly typed as \*S[] in the +section on mom's inlines. +---Fixed--- + +Paragraphs inside blockquotes not being spaced when .PARA_SPACE is +active. +---Fixed--- + +Version 1.5-a +============= +Indenting of references (collected with .REF) on endnotes pages when +endnote numbers are right-aligned appears to be backwards; the +first line of the reference is indented more than the second. +---Fixed--- + +Version 1.5 +=========== +DROPCAP not printing the dropcap letter at all in PRINTSTYLE +TYPEWRITE, nor when DROPCAP is used (accidentally?) after a valid +"first" paragraph. +---FIXED--- + +DROPCAP going into an infinite loop when groff called with the +-Tascii switch. +---FIXED--- + +SHIFT_LIST, when used anywhere but with a top-level list, is killing +list indents for every list level *returned to* afterward. +---Fixed--- + +TOC page number for heads and subheads that get bumped to next page +(because of .ne) off by 1. +---Fixed--- + +Moving backwards in nested lists not setting the proper indent. +---Fixed--- + +Default linebreak color missing in om.tmac. +---Fixed--- + +Some links in macrolist.html not pointing to html "name" owing to +missing # in link names. +---Fixed--- + +Version 1.4-b +============= +Line lengths and indents not always being respected in LIST. +---Fixed--- + +CAPS OFF, called inline with \*[CAPS OFF] not working. +(Added two new inlines, \*[UC] and \*[LC], to do the job.) +---Fixed--- + +When type is set after START but no docelement tag given, the +expected family ($DOC_FAMILY) and font (R) are not in effect. +---Fixed--- + +When DOCTYPE is CHAPTER and .TITLE is omitted after .COLLATE, the +title vanishes from page headers/footers. +---Fixed--- + +Version 1.4-a +============= +In collated documents, when using a different HEADER_FAMILY, +if BLANKPAGE is given after COLLATE (but before START) all +subsequent text is set in the HEADER_FAMILY face rather than the +standard text face. +---Fixed--- + +Document title identification string missing on endnotes pages when +the endnote marker style is LINE. +---Fixed--- + +Space between endnote items on endnotes output pages not being +inserted. +---Fixed--- + +Version 1.4 +=========== +Invoking .FOOTERS isn't automatically putting pagination in the top +margin. +---Fixed--- + +.PP_FONT after .COLLATE not being respected. +---Fixed--- + +$SAVED_PP_FT not being fed to .FT in .PP after .COLLATE +---Fixed--- + +.CODE OFF not always restoring previous family and font. +---Fixed--- + +.ITEM, when not in a list, should do nothing. +---Fixed--- + +Version 1.3-e_3 +=============== +ENDNOTES is not, by default, printing headers on endnotes pages. +---Fixed--- + +Processing of the "Endnotes" title for the TOC is putting the +page number 1 line too high and not inserting leader. +---Fixed--- + +Collated docs not respecting $PP_FT (it's picking up the font from +the pagenumber font) +---Fixed--- + +Docheader spacing sometimes depositing too much space between +various docheader elements in TYPEWRITE when DOCTYPE is DEFAULT or +NAMED. +---Fixed--- + +When COLUMNS are on, subheads that are deferred to the next +column/page because there isn't enough room for the s/h and one +line of text are causing columns to overprint. +---Fixed--- + +HDRFTR_LEFT printing one line too high when .HEADER_COLOR is used. +---Fixed--- + +DOCTITLE link broken in the docs. +---Fixed--- + +Version 1.3-e_2 +=============== +TOC formatting incorrect when the pound/number sign (#) is used in +head elements. +---Fixed--- + +[Documentation]: The docs erroneously state that TOC control macros +can be entered anywhere in a file prior to invoking TOC (they should +be entered before START). +---Fixed--- + +Page numbers in the bottom margin being printed too low on output +pages preceding an invocation of COLLATE or macros that call it. +---Fixed--- + +A superfluous blank, numbered page is being generated by COLLATE +(and macros that call it, namely TOC and ENDNOTES) when the last +line of output text before it falls on the last valid baseline of +an output page. Same thing happening occasionally with normal +document termination. +---Fixed--- + +SHIFT_LIST not being observed when moving *back* to a shifted list; +the list is reverting to the left margin. +---Fixed--- + +NUMBER_SUBHEADS not working with TYPESET when PARA_SPACE is on. +---Fixed--- + +Version 1.3-e_1 +=============== +Missing #COLLATE register (accidentally wiped out) creating various +problems with .COLLATE (missing headers, leading increasing +slightly each time .COLLATE invoked, etc). +---Fixed--- + +Version 1.3-e +============= +mom failing during groff build while processing +examples/typesetting.mom +---Fixed--- + +Windows user reports COLLATE fails with a bottom margin error +(generated by mom). +---Fixed--- + +Version 1.3-d +============= +Small error in the examples of output in the "Footnotes and +Punctuation" documentation section. +---Fixed---- + +PAD_LIST_DIGITS/SHIFT_LIST broken when the enumerator type is +roman or ROMAN. +---Fixed--- + +COLLATE wiping out _FAMILY settings. +---Fixed--- + +DOC_LEAD_ADJUST OFF not being observed when COLLATE is invoked. +---Fixed--- + +DROPCAP setting the dropcap too high in initial paragraph after a +COLLATE. +---Fixed--- + +Version 1.3-c +============= +Owing to a superfluous "if" in the FONT macro, the "missing font" +routine is being silently ignored. +---Fixed--- + +FOOTNOTE, used in nofill mode, adds a linebreak between the +marker and the text of the footnote. +---Fixed--- + +Version 1.3-b +============= + +ITALIC_MEANS_ITALIC not being respected when DOCTYPE LETTER. +---Fixed--- + +Underlining of italic passages in PRINTSTYLE TYEPWRITE not spanning +pages. +---Fixed--- + +PRINTSTYLE TYPEWRITE depositing extra space on new pages above quotes +that span pages. +---Fixed--- + +MN doesn't accept OFF, QUIT, END, X, etc. +---Fixed--- + +Margin notes that begin flush with the last line of text on a page +are running down the same page, instead of the remainder being +collected and output on the next. +---Fixed--- + +MN sometimes erroneously dropping margin notes near the bottom of +a page, even when they'd fit. (MN-shifted not being removed by +MN-top.) +---Fixed--- + +MN_INIT not accepting "" args for default values. +---Fixed--- + +Documentation for margin notes erroneously states that the first +(optional) argument can be either "ragged" or "symmetric". S/b +"RAGGED" or "SYMMETRIC". +---Fixed--- + +Use of "" to tell MN_INIT to use the default for any specific +argument in the arg list broken. +---Fixed--- + +Paragraphs that begin with a "smart" double quote when the +preceding paragraph has no corresponding close quote (i.e. dialogue +passages containing multiple paragraphs) are starting off with a +close quote. +---Fixed--- + +Version 1.3-a +============= + +First baseline of type isn't going where it's supposed to when the +docheader is turned off. +---Fixed--- + +Version 1.3 +=========== + +Persistent error in html coding of docs ( tag). +---Fixed--- + +Version 1.2-f +============ + +Multiple line subheads near page bottom sometimes printing one line +of subhead at page bottom, and subsequent lines on next page. +---Fixed--- + +Post-quote spacing still wonky when paragraph spacing is turned on. +---Fixed--- (for good would be nice) + +RULE not always resetting quad and quad value. +---Fixed--- + +Version 1.2-e +============= + +Some string definitions in om.tmac had superfluous spaces after +them (e.g. $COVERTITLE). +---Fixed--- + +Spacing under quotes not correct when paragraph spacing is turned +on. +---Fixed--- + + +First word of last line before footnotes is getting chopped. +---Fixed--- + +Version 1.2-d +============= + +HEADER_FAMILY not changing header family. +---Fixed--- + +FAMILY, after COLLATE, not changing the family of all and every +page element or tag. +---Fixed--- + +Heads and subheads at the start of docs are printing one line lower +than they should. +---Fixed--- + +Gaps are appearing at the bottom of pages when there's a linebreak +followed by a subhead. +---Fixed--- + +When LS is invoked after a single text line at the top of a page +containing a T_MARGIN (set with T_MARGIN or PAGE), mom is performing +spacing adjustments as if the first line doesn't exist. +---Fixed--- + +Changes made to ALD and LS in version 1.2-c should not apply when +the document processing macros are used. There is a significant +conflict with the internal use of ALD when the docheader is only +one line long (as, for example, when DOCTYPE is CHAPTER). +---Fixed, pending discovery of further conflicts--- + +Version 1.2-c +============= + +Deferred footnotes not always being output, and groff complains +"ending diversion FN_OVERFLOW on exit." +---Fixed--- + +First .LS call after a top margin has been set (with .T_MARGIN +or .PAGE) causing mom to move off the top margin baseline. Also, +there are conflicts between ALD, LS and T_MARGIN. +---Fixed--- + +DROPCAP not properly restoring a running \*[COND] or \*[EXT] after +COND or EXT are given as arguments to DROPCAP. +---Fixed--- + +Version 1.2 +=========== + +.PAD not co-operating with mom's fontstyles, esp. when a full +family+fontstyle is given to .FT. +---Fixed--- + +.DROPCAP -- ditto the above. +---Fixed--- + +Version 1.1.9 +============= + +Footnote markers not resetting properly on new pages when COLUMNS +is enabled. +---Fixed--- + +When overflowed footnote material is the only footnote material on +the page or in the column, no footnotes are output. +---Fixed--- + +The AUTOLEAD used in FOOTNOTE not being disabled after FOOTNOTES +are output, or after PROCESS_FN_LEFTOVER/PROCESS_FN_IN_DIVER. +---Fixed--- + +COL_NEXT and COL_BREAK, when invoked during the last column on a +page, are overprinting the last column instead of breaking to a new +page when there are footnotes in the column. +---Fixed--- + +BR_AT_LINE_KERN not "break-and-spreading" text when used in +justified copy. +---Fixed--- + +Version 1.1.8 +============= + +BLOCKQUOTE_FAMILY not changing blockquote family. +---Fixed--- + +FOOTNOTE, whether in column mode or not, was using +#FN_COUNT_FOR_COLS for all footnote markers and handling. +---Fixed--- + +Deferred footnotes that occurred on the second to last page of +documents not printing. +---Fixed--- + +Version 1.1.7-a +=============== + +Suite number in DOCTYPE LETTER not printing. +---Fixed--- + +Footer elements not always vertically aligning. +---Fixed--- + +Footer rule gap not always correctly observed. +---Fixed--- + +Page numbering, when at top of page, not always falling on +HDRFTR_MARGIN. +---Fixed--- + +Default page numbering style for COPYSTYLE draft is DIGIT instead +of roman. +---Fixed--- + +Hyphens around page numbering when style is DIGIT, ROMAN or ALPHA +not vertically centered. +---Fixed--- + +EXT arg not working with DROPCAP. +---Fixed--- + +DOC_QUAD not automatically set immediately after START +---Fixed-- + +Tabs behaving erratically during document processing. +---Fixed--- + +Version 1.1.7 +============= + +When DOCHEADER OFF is given, if falls short +of the top margin of running text, is not respected and +bottom margin falls low. +---Fixed--- + + +Version 1.1.6-e +=============== + +The " mark (doublequote), when entered while not in document +processing mode (i.e. just straightforward typesetting), outputs +nothing unless SMARQUOTES is invoked explicitly. +---Fixed--- + +Version 1.1.6-c +=============== + +In document processing mode, docs that use *none* of the +docprocessing tags being ignored. +---Fixed--- + +Version 1.1.6-b +=============== + +String tabs not picking up #L_MARGIN when #L_MARGIN not explicitly +set with L_MARGIN, PAPER or PAGE. +---Fixed--- + +Infinite loop when B_MARGIN is set lower than FOOTER_MARGIN during +doc processing. +---Fixed--- + +Version 1.1.6-a +=============== + +Mom partially broken when run with groff 1.19.1. Don't know yet +what this is, whether bad coding in mom, or a problem with 1.19.1. +Only solution for now: run mom 1.1.6 with groff 1.18. +----Fixed--- + +Top margin of endnotes pages after the first endnotes page when +PRINTSTYLE is TYPEWRITE and endnotes single-spacing is turned on +falling one line too high. +---Fixed--- + +Version 1.1.6 +============= + +DOCHEADER OFF (distance) not being respected. +---Fixed--- + +FINIS killing ENDNOTES page numbering and heads. +---Fixed--- + +Version 1.1.5 +============= + +Draft and revision not appearing in page headers. +---Fixed--- + +\*[RULE] not working properly with indents and justified copy. +---Fixed--- + +Post-epigraph spacing in TYPEWRITE causing some first pages to run too +deep. +---Fixed--- + +Spacing of docheaders in TYPEWRITE not always consistent. +---Fixed--- + +Version 1.1.4 +============= + +Blockquotes that span pages running too deep. +---Fixed--- + +Version 1.1.3 +============= + +Footnotes not outputting on final page of document body when ENDNOTES +is invoked. +---Fixed--- + +Pad not working properly and/or spitting out warnings when fill mode is +on. +---Fixed--- + +Version 1.1.2 +============= + +PAGENUM_STYLE being ignored unless entered after START. +---Fixed--- + +Version 1.1 +=========== + +String tabs not working as advertised when set from within other tabs. +---Fixed--- + +.COLLATE sometimes depositing a header on the first page of a subsequent doc. +---Fixed with workaround BREAK_QUOTE--- + +.UNDERLINE_QUOTES in PRINTSTYLE TYPEWRITE not on by default as advertised. +---Fixed--- + +.TI not cooperating with other indent styles. +---Fixed--- + +.WS and .SS not cooperating. +---Fixed--- + +.RW and .EW not working. +---Fixed--- + +======================================================================== + +KNOWN PROBLEMS +-------------- + +The indent macros from the typesetting macro set may not always +perform well in conjunction with the document processing macros, +especially when documents are set in columns. Mostly, this is the +result of inadequate testing. There are only so many "who'd want to +do this anyway?" scenarios I can think of on my own. + +Epigraphs at the bottoms of page may sometimes run exactly one line +deeper than they should. The alternative (from my point of view) is +to have them run 1 line shorter than they should. The problem stems +from the fact the epigraphs are leaded differently than all other text, +and there's only so much adjusting that can be done with the whitespace +surrounding them to get them to bottom align. Since stylistically, +epigraphs should never appear at the bottom of a page/column without at +least some running text beneath them in order to make sense of the role +they play in page layout, this not likely to be fixed for some time. + diff --git a/contrib/mom/ChangeLog b/contrib/mom/ChangeLog new file mode 100644 index 0000000..82e5dbb --- /dev/null +++ b/contrib/mom/ChangeLog @@ -0,0 +1,1788 @@ +2023-06-15 + + * om.tmac: Enclose all calls to \D't n' in \Z + +2023-03-01 G. Branden Robinson + + [mom]: Generate test script even if we'll skip it. + + * examples/test-mom.sh.in: Check availability of required + pdfinfo(1) and pdfimages(1) commands at test time; skip if they + aren't present. + * mom.am [!HAVE_PDFTOOLS]: Generate the test script even if + these tools aren't available. + +2023-02-18 G. Branden Robinson + + * mom.am (uninstall_mom): Clean more fastidiously; try to remove + the configured `pdfdocdir` in the event it is empty, but do not + fail if it isn't. (It can be a directory shared with other + groff components; we don't know in what order the uninstall + targets will serialize, but the last one run should succeed.) + +2023-02-02 + * om.tmac (UNDERSCORE, UNDERSCORE2): Add PREFIX and SUFFIX + arguments so surrounding punctuation can be protected from + underscoring. + +2023-01-16 + * om.tmac (PRINTSTYLE): Abort with message if nroff is called on + a document using PRINTSTYLE TYPESET. + + Fixes . Thanks to Gene + for the report. + +2022-11-16 + + * om.tmac (PAPER): Adjust #R_MARGIN to work with papersize.tmac. + +2022-10-23 G. Branden Robinson + + * om.tmac (FORCE_RECTO): Use backslash before newline when + starting multi-line conditional block. + +2022-09-02 + + * examples/mom-pdf.mom: Fixes missing parameter to \*[SIZE] at + line 457. + + * om.tmac: Fixes CODE not restoring point size + correctly. The point size was being stored in a number register + instead of a string. + + * BUGS: Updated. + + Fixes . + +2022-08-29 G. Branden Robinson + + * mom.am (MOMPDFMOM): Pass `PDFMOMBIN` '-K utf8', not '-k', in + case 'configure' didn't find uchardet. + + Fixes . Thanks to Bjarni + Ingi Gislason for the report. + +2022-05-31 + + * Make mom emit a warning and abort when tbl(1) data present + without a corresponding -t on the command line. + +2022-05-20 G. Branden Robinson + + * momdoc/appendices.html: Reflect file rename in groff + distribution: the name of the file mapping Adobe Glyph List + names to groff special character identifiers for text (as + opposed to "special") fonts has changed from "textmap" to + "text.map". + +2022-05-20 G. Branden Robinson + + * mom.am (MOMPROCESSEDEXAMPLEFILES): Include "typesetting.pdf" + only if `HAVE_URW_FONTS`, since the document demands them. + +2022-05-20 G. Branden Robinson + + * mom.am: Rename `BUILD_PDFDOC` to `USE_GROPDF`. + +2022-05-01 G. Branden Robinson + + * mom.am ($(MOMPROCESSEDEXAMPLEFILES)): Depend on new name for + devpdf stamp file. + +2022-04-12 Ingo Schwarze + + Delete the harmful, ill-designed, buggy, and essentially + unmaintained and untested --with-doc option of the configure + script. See the NEWS file for more details on the rationale. + + * mom.am: Delete one INSTALL_SHIPPED_HTML and one BUILD_EXAMPLES + conditional and use BUILD_PDFDOC instead of BUILD_PDFEXAMPLES. + +2021-03-29 G. Branden Robinson + + * mom.am: Eliminate `MOM_TFLAG` and `MOM_PFLAG` Make macros; + they were expanded in only one place. + (MOMPDFMOM): Track rename of Make macro `TFLAG` to `MFLAG`. + +2022-03-26 G. Branden Robinson + + * mom.am (MOMPROCESSEDEXAMPLEFILES): Drop dependency on gnu.eps. + No mom document appears to require this file; it came in with + the initial Automake file for mom in commit 4d84d0f1d, 27 + January 2015, and may have been a copy-and-paste error. + +2021-10-21 G. Branden Robinson + + * mom.am (mom_test_template): Pull file name into a new + variable. + (EXTRA_DIST, contrib/mom/examples/tests-mom.sh): Use it. + (contrib/mom/examples/tests-mom.sh): Build more quietly; + prefix rule with `$(AM_V_GEN)`. Also run `chmod` conditionally. + +2021-10-04 + + * version 2.5 release (see NEWS) + + * removed orphaned stubs for abandoned cutaround feature from + om.tmac + +2019-12-26 + + * added PREFIX_CHAPTER argument to HEADING_STYLE + + * added TOC_HEADING; single line, non-pagenumbered insertions into + the TOC + +2019-11-03 + + * templates added for setting up copyright pages + + * updated mom.am to include the templates when building + pdfs in mom/examples + +2018-11-24 + + * version 2.4 release (see NEWS) + +2018-09-05 + + * improved grap support + +2018-03-04 + + * version 2.3 release (see NEWS) + +2018-02-28 Werner LEMBERG + + * mom.am (.mom.pdf): Use $(GROFF_V). + +2017-11-04 G. Branden Robinson + + * mom.am: Drop unnecessary -M flag; build tree has what it needs. + +2017-10-29 Bjarni Ingi Gislason + + * om.tmac-u: Fix typo in register reference. + + Fix bug https://savannah.gnu.org/bugs/?51608. + +2015-08-22 Bernd Warken + + * groff_mom.7.man: Rename `groff_mom.man'. + + * mom.am: Include renaming. + +2015-08-05 Bernd Warken + + * mom.am: Add `Last update'. Setup Emacs mode. + +* Sun Jul 26 2015 + + o Fix to header part-by-part changes. + +* Mon Apr 27 2015 + + o version 2.1-a release (see NEWS) + +* Fri Apr 4 2015 + + o groff_mom.man: Make it work in compatibility mode. + +* Sat Feb 28 2015 + + o Added an ADJUST argument to QUOTE and BLOCKQUOTE to facilitate + optical centering tweaks + +* Sat Feb 21 2015 + + o Expanded scope of _STYLE macros to headers/footers and + page numbers + +* Thu Feb 5 2015 + + o Version 2.1 release (see NEWS) + + o overhaul of control macro handling + + o overhaul of cover and docheader management + + o general code cleanup to remove redundancies and reduce size of + om.tmac + + o changes to example files to demonstrate new features + + o copyrights updated in all files + +* Tue Jan 14 2015 + + o Added a new example in French, mon_premier_doc.mom + + o Added README-fr.txt, a translation in French of the README.txt file + + o Makefile.sub: generation of mon_premier_doc.mom, installation of + README-fr.txt + +* Sun Nov 30 2014 + + o Added auto underscoring, caps, and color to TOC header + (first-page titles) + + o Added vertical page positioning control macros for TOC and + ENDNOTES headers (first-page titles) + +* Tue Nov 25 2014 + + o Tweak so collated, non-chapter docs with the same author + don't require .AUTHOR "" to skip printing author in docheader + +* Wed Oct 29 2014 + + o Makefile.sub: KFLAG to run pdfmom with -k + + o Set utf-8 preconv coding tag in examples/typesetting.mom and + examples/letter.mom + +* Mon Oct 20 2014 + + o Changes to caption/label/source quadding strategy. + +* Wed Sep 03 2014 Bernd Warken + + o all files in contrib/mom source: Copying and Emacs setting. + + o contrib/mom source/ChangeLog: Repair file. The file runs now in + Emacs change-log mode. + +* Tue Aug 12 2014 + + o Makefile.sub (stamp-strip): Set LANG=C LC_ALL=C when calling + `sed'. + + This prevents a build error on OS X. + +* Thu Apr 3 2014 + + o Makefile.sub: Set LC_ALL=C when calling $(PDFMOM). + + Doing so in an UTF-8 locale with $PERL5OPT=-C set avoids warnings + like + + utf8 "\xF5" does not map to Unicode at\ + [.]src/devices/gropdf/gropdf line 1359, line 63. + Malformed UTF-8 character (unexpected end of string)\ + in substitution (s///) at\ + [.]src/devices/gropdf/gropdf line 1315, line 63. + +* Sat Mar 29 2014 + + o Makefile.sub: Handle examples separately, controlled by + $(make{_,_install_,_uninstall_}examples). + +* Wed Mar 26 2014 + + o Added user settable space to PARA_SPACE. + +* Tue Mar 11 2014 + + o Makefile.sub (MAN7): Do not install empty `mom.7' (tiny change). + + A mom(7) manual got briefly added, then promptly removed again in + 9f38f05e58d31eda1affce01d1144760b5f48096 for integration into + groff_mom(7), but it was forgotten to remove it from the list of + manual pages to install. + +* Fri Feb 28 2014 + + o Reworked handling of pdf-images. Preprocessor support expanded + to include eqn and pic. Spacing and placement of tbl output + improved. Fixed floats in columns. Added facilities for captions + and labels for pdf-image, eqn, pic, and tbl. Added auto-generated + "Lists of". + +* Wed Oct 30 2013 + + o Expanded and improved float/tbl handling. + +* Sat Sep 14 2013 + + o .TS/.TE extended to support multi-page tables with headers. + +* Sat Aug 24 2013 + + o Restored reserved.html to toc.html in docs. + +* Tue Aug 20 2013 + + o Integrate mom.7 into the man-page groff_mom.7 + +* Tue Aug 20 2013 + + o New man page mom.7 + +* Sun Aug 11 2013 + + o Updated documentation concerning refer usage + + o Replaced REF_STYLE and REF macros with warnings. + +* Wed Jun 19 2013 + + o groff_mom.man: Fix inappropriate use of .UR/.UE. + +* Fri Jan 4 2012 + + o Makefile.sub (install_data): Create directory for PDF + documentation. This is necesssary in case GhostScript is not + available, and no other PDF files have been created yet. + +* Sun Dec 30 2012 + + o Makefile.sub (install_data): Fix symlink. + Patch from Elias Pipping . + +* Thu Sep 20 2012 + + o Simplify environment handling. + +* Fri Aug 31 2012 + + o Version 2.0 release. Changes documented in version-2.html in + the html documentation. + + o Added new documentation, Producing PDFs with groff and mom. + +* Sat Feb 18 2012 + + o Added choice to have DOCTYPE NAMED underscored or not + when PRINTSTYLE TYPEWRITE + + o Doc fix to DOCTYPE NAMED underlining entry + +* Thu Sep 8 2011 + + o Added register #SUBHEAD, analogous to #HEAD, to fix excessive + spacing between SUBHEADs and SUBSUBHEADs. + +* Sun Feb 20 2011 + + o Added support for sub-subheads from patch supplied by Petr Man. + +* Fri Feb 11 2011 + + o Moved register #UNADJUSTED_DOC_LEAD to top of TRAPS macro. + +* Fri Nov 19 2010 + + o Added utility macro, SINGE_SPACE, for PRINTSTYLE TYPEWRITE + +* Sat Jan 22 2011 + + o groff_mom.man (FILES): Fix directory locations. + +* Sun Oct 3 2010 + + o Complete overhaul of refer macros and documentation + + o Inclusion of Tadziu Hoffman's postscript code for underlining + +* Wed Aug 18 2010 + + o Complete overhaul of documentation + +* Thu Aug 5 2010 + + o Changes to COVER and DOCCOVER for greater flexibility in + placement of elements + + o Improved handling of MISC info on cover pages for greater style + flexibility + + o Added _FAMILY, _FONT, _SIZE and _COLOR control macros for CODE + +* Mon July 6 2009 + + o Added CLOSING_INDENT and SIGNATURE_SPACE to DOCTYPE LETTER + macros. + +* Sun Jun 14 2009 + + o DROPCAP handling changed; uses local vertical motions now + instead of .mk/.rt. + + o Added macro SUPERSCRIPT_RAISE_AMOUNT + + o Added registers and strings to keep track of .RW and .EW and the + amounts passed to them. + +* Sat May 2 2009 + + o Fixed error in docs: COVERS_COUNT_PAGES changed to + COVER_COUNTS_PAGES. Ditto DOC_COVERS_COUNT_PAGES. + +* Fri May 1 2009 + + o Fixed PARAHEAD size so it properly adds the value of + \*[$PH_SIZE_CHANGE] to \n[#DOC_LEAD]. + +* Sat Jan 17 2009 + + o Changed FAMILY, FT and PT_SIZE requests in DO_COVER to groff + primitives (fam, ft and ps respectively). Fixes (DOC_)COVER bug + where (DOC_)COVER was resetting families and fonts of various + document elements (QUOTE, BLOCKQUOTE, etc) to document default. + + o Removed (excessive) cleanup of (doc)cover and docheader strings + and registers from macro CLEANUP. Changes to mom's default style + for these document elements now survive COLLATE. + +* Fri Jan 2 2009 + + o Added possibility of quadding docheader left or right, as well + as center, which remains the default. + +* Wed Dec 31 2008 + + o Default definition of $QUOTE0 and $QUOTE1 in om.tmac changed + from \[dq] to \[lq] and \[rq], respectively. + +* Sun Jan 4 2009 + + o Makefile.sub (CLEANADD): Add om.tmac-s. + +* Tue Dec 30 2008 + + o Doc fixes in toc.html + + o Control of null pagenumbering of covers passed to \n%; formerly + handled by \n[#PAGE_NUM_ADJ] + +* Tue Dec 23 2008 + + o Added a CAPS option to HDRFTR_RECTO and HDRFTR_VERSO to allow + capitalization of reserved strings when designing recto and/or + verso headers. Fixed docs accordingly. + +* Sun Nov 30 2008 + + o Added .nr #DIVER_DEPTH 0 to end of PRINT_PAGE_NUMBER to ensure + that #DIVER_DEPTH=0 + + o Moved string definition of $FONT in macro FT to top of macro. + + o Moved string definition of $FAMILY in macro FAMILY to top of + macro. + + o Changed condition generating #NO_BREAK at top of macro COLLATE + from .if ( \\n[.t] < \\n[.v] ) \{ .nr #NO_BREAK 1 \} to .if ( + (\\n[.t]-1) <= \\n[.v] ) \{ .nr #NO_BREAK 1 \} + + (Bottom-of-page trap is tripped 1 unit below last valid baseline) + (not on it.) + +* Tue Nov 25 2008 + + o Commented out what appears to be a superfluous and destructive + resetting of #VARIABLE_FOOTER_POSITION at line 13347 in FOOTNOTE + macro. For now, fixes the "vanishing first footnote with some + overflow" bug. + +* Mon Oct 6 2008 + + o Added a bit to .PP to accommodate .PP_FONT I when PRINTSTYLE is + TYPEWRITE and ITALIC_MEANS_ITALIC + +* Mon Jun 30 2008 + + o Removed spurious 'sp |\\n[MN-curr-pos]u from MNbottom-right, + prior to re-invoking traps. Hopefully, fixes vanishing RH margin + notes bug. + +* Sun Mar 16 2008 + + o Added missing spaced paras bit in blockquotes. + +* Tue Jan 22 2008 + + o Fixed indent handling of refer items in endnotes. + + o Amendations to refer.html. + + o Removed dead email address from groff_mom.man. + +* Fri Jan 04 2008 + + o groff_mom.man: Replace .URL with .UR/.UE. Replace .MTO with + .MT/.ME. Insert `\:' in URLs where appropriate. Don't include + www.tmac. + +* Wed Sep 12 2007 + + o Fixed an oversight in DROPCAP that meant when DROPCAP needed to + be ignored, the dropcap letter itself was dropped from running + text altogether, instead of printing as a normal part of text. + + o Added an .if n clause to DROPCAP to prevent mom from going into + an infinite loop when groff invoked with the -Tascii switch. + +* Wed Jul 25 2007 + + o Did a couple of doc fixes. + + o Added vpt checks at the top of all the graphical object macros. + Basically, only turn vpt's off and on again if they're already + enabled. + +* Wed Feb 14 2007 + + o Moved .ne requests in HEAD and SUBHEAD to top of respective + macros, fixing bug that was gathering the wrong page number for + head and subhead toc entries. + +* Fri Nov 24 2006 + + o Added a default linebreak color (black) + +* Thu Sep 28 2006 + + o Fixed missing #'s in linknames in macrolist.html. + +* Mon Jul 31 2006 + + o Changed all .LLs in LIST to .ll requests. + + o Added new macro, FINIS_STRING_CAPS, to control capitalization of + the finis string. + + o Amended doc section on page set up to include directions for + telling groff about the physical dimensions of printer sheets. + + o Added new arg to BLANKPAGE: NULL. If given, BLANKPAGE does not + increment the page number when outputting a blank page. + + o Added new control macros, COVERS_COUNT_PAGES and + DOC_COVERS_COUNT_PAGES in case user wants covers counted in the + pagination scheme. + + o Added new final arg to COVER and DOC_COVER: BLANKPAGE. + Instructs COVER or DOC_COVER to print a blank page after the + cover. + + o Added new optional args to CODE: BR, BREAK, SPREAD. CODE can + now be called inline; if called as a macro and the user wants a + break or spread, s/he has to supply one of the args. + + o Added new macro, CODE_FAMILY, to set fixed-width family used by + .CODE + + o Made EDITOR an alias of AUTHOR + + o Added optional arguments, COVER or DOC_COVER, to reference + macros that may be used on covers and doc covers, allowing users + greater flexibility in determining exactly what goes on covers and + doc covers without screwing up the doc header or the default page + headers/footers + + o Added macros to control the weight and placement of all + underscore/underline rules used in typesetting and document + processing + + o Added macros for drawing of rules, boxes and circles (ellipses) + + o Added macro, RULE_WEIGHT, to control weight of rules drawn with + \*[RULE] + + o General doc updates, additions, amendations and corrections + + o Reformatted entirety of documentation to be xhtml clean + + o Added inlines \*[UC] and \*[LC] to handle inline caps; corrected + doc entry stating that you can use \*[CAPS] and \*[CAPS OFF]; + chief reason is to allow inline capitalization in strings passed + to header/footer definitions. + +* Fri Jul 7 2006 + + o Changed inline, \*[RULE], so that it always draws the rule one + linespace beneath the last output line. Formerly, \*[RULE] drew + the rule on the baseline of the current output line. + +* Sun Jul 2 2006 + + o Changed UNDERSCORE and UNDERSCORE2 to use groff's \D'l ' + line drawing function. + + o Changed RULE to use groff's \D'l ' line drawing function. + + o Added RULE_WEIGHT macro, to allow controlling weight of + \*[RULE], expressed in points (including fractional points). + + o Added two new inlines, \*[UC] (all caps) and \*[LC] + (caps/lowercase). These can be used in user-defined header/footer + strings (if \E is used instead of just the backslash by itself) as + well as in normal copy. + +* Sat Jul 1 2006 + + o Added .FAMILY \\*[$DOC_FAMILY] and .FT R to the end of + .DEFAULT_DOCHEADER, .CHAPTER_DOCHEADER and .NAMED_DOCHEADER. + Fixes bug that was causing type which was set after .START when no + docelement tag given to be set in the last family and font used in + the docheader, instead of the expected $DOC_FAMILY and roman font + (R). + +* Fri Jun 30 2006 + + o Updated copyright file + + o Massive documentation cleanup to make docs well-formed xhtml + +* Thu Jun 22 2006 + + o Rewrote portions of TITLE, COVERTITLE, DOCCOVERTITLE, + CHAPTER_TITLE, SUBTITLE and MISC so that when they're called from + .COLLATE, they properly clean out all associated strings and + registers. Fixes the "vanishing $TITLE" bug. + + o Added missing .rm $AUTHORS to .AUTHOR. .as $AUTHORS now always + starts with a clean slate. + +* Wed Jun 14 2006 + + o Added a missing tag to docelement.html. + +* Sat Jun 10 2006 + + o In header and footer routines, changed all .FAMILY calls when + .PRINTSTYLE TYPESET to .fam + + o Fixed DOC_FAMILY so that PARAHEAD_FAMILY and LINENUMBER_FAMILY + are properly set to the new value. + +* Fri Jun 9 2006 + + o Re-worked .QUOTE_INDENT so that users can pass it an absolute + value (by adding a scaling indicator to the arg) instead of just a + value relative to the paragraph indent. Fixes bug (oversight?) + that meant QUOTES and BLOCKQUOTES got no indent at all if the + PP_INDENT was 0. Fixed EPIGRAPH_INDENT similarly. + + o Added missing default ENDNOTE_LINENUMBER_FAMILY and _FONT to + DEFAULTS. + +* Thu Jun 8 2006 + + o Changed distance of the underscores used in docheaders when + PRINTSTYLE is TYPEWRITE from the default 2p to 4p. This is to + leave room for the descenders if the strings are caps/lowercase. + +* Wed Jun 7 2006 + + o Added strings $AUTHOR and $AUTHORS. $AUTHOR = $AUTHOR_1 (i.e. + the first arg passed to .AUTHOR); $AUTHORS = a comma-separated + concatenated string of all the args passed to .AUTHOR. + +* Tue Jun 6 2006 + + o Updated docs. + + o Converted all .ig blocks in om.tmac to comment lines beginning + with \#. This so that the comments will be stripped from om.tmac + during make. The groff sources still contain the commented + version of om.tmac, as do the tarballs posted on mom's homepage. + + o Added new macro, HEADERS_AND_FOOTERS, to allow having both + headers and footers on a page. + + o Fixed whitespace around epigraphs after .DOCTYPE CHAPTER + docheaders. + + o Added test in .PP_FONT for existence of $SAVED_PP_FT; if it's + there, remove it (fixes bug that was causing .PP to ignore + .PP_FONT after .COLLATE). Also fixed .PP so that it properly + passes $PP_FT to .FT if $PP_FT has been re-defined to + $SAVED_PP_FT. + +* Sun Jun 4 2006 + + o Added a note about colorizing underscored text in the docs. + +* Wed May 24 2006 + + o Adjusted the .ne value for heads and subheads (again) + +* Sun May 21 2006 + + o In the documentation, removed the section stating that setting + the family, font, pointsize and colour of line numbers wasn't + possible. + + o Updated documentation entry for TOCs to include instructions for + using psselect. + +* Sat May 20 2006 + + o Added string $PRE_CODE_FAM to CODE; fixes bug that kept CODE OFF + from restoring the previous family_font combo + + o Added a test for existence of register #DEPTH to .ITEM; if it + doesn't exist, ignore ITEM + +* Fri May 19 2006 + + o Updated docs + + o Added macro, CODE + + o DOCTITLE, TITLE, CHAPTER_TITLE, SUBTITLE, COVERTITLE and + DOC_COVERTITLE now accept multiple arguments; each is printed on a + separate line in docheaders and on cover pages. Where the macros + also supply reference information to page headers, endnotes and + tables of contents, the args are concatenated. + +* Thu May 18 2006 + + o Changed default DOCHEADER_LEAD to +0 when there's both the + chapter number and a chapter title in DOCTYPE CHAPTER. + Compensated by adding 1/4 of the leading in effect for docheaders + between them. Applies equally similar situations on covers and + doc covers. + +* Mon May 15 2006 + + o Added missing default ENDNOTES_ALLOWS_HEADERS to DEFAULTS. + + o Added missing temporary change of the pad marker from # to ^ to + the toc title collection routine of .ENDNOTES. + + o Added string $SAVED_PP_FT to start of .COLLATE; string is tested + for in .PP + + o Improved testing for $FONT and $PP_FT in DEFAULTS + + o Trivial changes to docheader spacing for doctypes DEFAULT and + NAMED when PRINTSTYLE is TYPEWRITE. + +* Sun May 14 2006 + + o Call to .ne in HEAD moved higher in macro, and .ne's reduced + each by 1. + + o Handling of "how much space is needed for subheads + 1 line of + text" in SUBHEAD changed to a simple .ne. Fixes bug that was + causing overprinting of columns when s/h was deferred to next + page/column. + + o In macro, PRINT_HDRFTR, removed .EOL from clause .if + \\n[#HDRFTR_COLOR]=1 + +* Sat May 13 2006 + + o Fixed broken link to DOCTITLE in docs. + +* Wed Apr 26 2006 + + o Corrected doc entry that stated TOC control macros can be + entered anywhere in a file prior to invoking TOC (TOC control + macros must come before START). + + o Removed spurious .nop from .ie \\n[#PRE_COLLATE]=1 clause in + FAMILY (fixes bug that was causing page numbers on pages before + COLLATE or TOC to be printed too low). + + o Added a test at top of COLLATE to set register #NO_BREAK to 1 if + the distance to the next trap is less than one linespace; used in + NEWPAGE to determine whether to do a 'br or .br. (fixes BUG that + was causing COLLATE, NEWPAGE, and TOC to spit out a blank page + when the last line of text before them happened to fall on the + last valid baseline of the page). + + o Changed pad marker used to format TOC entries to permit use of + the pound/number sign (#) in head elements. + + o New macro, PREFIX_CHAPTER_NUMBER, to allow users to prepend + chapter numbers to the numbering scheme used in head element + numbering. + + o Added missing periods at the ends of head, subhead, parahead + numbers. + + o CHAPTER, with a numeric argument, can now be used to identify + any document as a "chapter" for the purposes of prefixing the + argument to CHAPTER to the numbering scheme of head elements. + + o Fixed alignment of TOC entries. + + o Removed .rr #DOC_HEADER and replaced with + + .if \\n[#DOC_HEADER]=1 \{ .nr #DOC_HEADER 2 \} + + near the end of START. I.e., #DOC_HEADER becomes "2" if + docheaders were on in the previous document. COLLATE tests for 2 + in order to reset #DOC_HEADER to 1 for use in the user-invoked + START that comes after a COLLATE. + + o Added register, #CHAPTER_CALLED, to CHAPTER; tested for in + PREFIX_CHAPTER_NUMBER to determine whether the argument to CHAPTER + can be used to establish a chapter number for chapter number + prefixes in head element numbering. + +* Mon Apr 17 2006 + + o Fixed bug that was causing shifted lists, when returned to, to + revert to the left margin instead of observing the correct + indent+shift for the list. + + o Added a check in LIST so that if user invokes LIST with RETURN, + mom doesn't get confused by the initial `R' (which she was using + to check if the arg to LIST was ROMAN or roman). + + o Replaced an incorrectly copied code block in SUBHEAD that was + preventing SUBHEAD from processing subheads properly when + PARA_SPACE was on. + +* Wed Mar 15 2006 + + o Added a .SHIM after .sp \\n[#DC_LINES]v in .DROPCAP. Fixes + problem of dropcaps in initial paragraphs after COLLATE being set + slightly too high. + + o Added .rr #DOC_LEAD_ADJUST_OFF to .ie clause of DOC_LEAD_ADJUST + and removed .rr #DOC_LEAD_ADJUST_OFF from DEFAULTS (after TRAPS) + so that document leading adjustment (or lack thereof) is + maintained from doc to doc when COLLATE is being used. + + o Added new register, #PRE_COLLATE. The .FAMILY macro is called + several times during initial COLLATE processing, and contained a + stanza that allowed FAMILY, after a collate, to invoke DOC_FAMILY + if #COLLATE=1. This allowed users to use FAMILY after a COLLATE + but before START in a way consistent with the behaviour described + in the docs (namely, FAMILY before START sets the DOC_FAMILY). + Since that functionality is still needed, #PRE_COLLATE instructs + FAMILY not to reset DOC_FAMILY until COLLATE is complete (i.e. + after the break to a new page). #PRE_COLLATE, if set to 1, is + removed at the end of HEADER. + +* Thu, Mar 2 2006 + + o Added control macros for linenumbering family, font, point size + and color + + o Added a NO_SHIM macro + +* Sun Feb 26 2006 + + o Changed .PRINT "\h'\\n[#LIST_INDENT\\n[#DEPTH]]u' in the "ROMAN + I, padded" and "roman i, padded" clauses of ITEM to .PRINT + "\h'\\n[#HL_INDENT\\n[#DEPTH]]u' to fix bug associated with using + both PAD_LIST_DIGITS LEFT and SHIFT_LIST. + +* Fri Feb 24 2006 + + o Removed superfluous "if" from FONT, line 492 + + o Removed #ADD_BREAK register from FOOTNOTE and ENDNOTE, along + with the routines it invoked + + o Added an optional argument, BREAK, to FOOTNOTE OFF and ENDNOTE + OFF, for correct and flexible handling of punctuation and + continued lines when FOOTNOTE or ENDNOTE are called while nofill + mode is active. + + o Created an alias for .so, INCLUDE. + +* Thu Feb 2 2006 + + o Small fix to handling of underlining of italic text spanning + pages in PRINTSTYLE TYPEWRITE. + +* Thu Jan 12 2006 + + o Reworked changing and setting of traps associated with + outputting left and right margin notes. See BUGS. + +* Sat Jan 7 2006 + + o Bracketed outputting of margin notes diversions with .nf/.fi. + +* Fri Jan 6 2006 + + o Corrected docs MN_INIT so that the optional first arg is + properly given as RAGGED | SYMMETRIC + + o Fixed MN_INIT macro routine that reads MN_INIT args into strings + so that the strings are first "initialized" with the @ character + if the corresponding arg is blank. Since MN-init tests for \A and + \B (correctly, I hope) for each of its args, the @ character + should be safe. + +* Tue May 16 2005 + + o momdoc/appendices.html: Add space in shebang, conforming to + portability recommendation in autoconf docs. + +* Thu May 12 2005 + + o Added margin notes capability + + o Added mom-specific refer support; refer calls can be embedded in + running text, sent to footnotes or endnotes, or collected for + output on a bibliography page; also added mom-specific refer + control macros + + o Added bibliography page capability, with full suite of control + macros + + o Added referencing of footnotes and endnotes by line number + + o Added capability to have footnotes run on when footnotes are + being referenced by line number + + o Added a post footnote space option, in case users want a little + space between their footnotes + + o Added ENDNOTE_MARKER_STYLE, so user can choose between endnotes + identified by a numerical marker in the text, or by line number + + o Added control macros to accommodate differing needs for endnotes + identified by line number + + o Added ENDNOTE_TITLE_SPACE, so user can control starting position + of the endnotes page title + + o Extended LIST so that it accepts lowercase alpha, uppercase + roman numeral and lowercase roman numeral enumerators; also added + a "prefix" argument (which comes *after* the separator argument) + + o Changed RESET_LIST so that it can reset a list to any number, + letter, or roman numeral, instead of just 1, a, A, I and i + + o Change to handling of footnote/endnote markers in text; input + lines before FOOTNOTE still require \c, but input line after + FOOTNOTE OFF must be entered as a literal continuation of the line + before FOOTNOTE, including any required word space or punctuation + (this so users can get the footnote marker in text either before + or after the punctuation without hassle) + + o Added QUOTE_AUTOLEAD and BLOCKQUOTE_AUTOLEAD, so user can have + quotes and blockquotes leaded differently from running text + + o Reworked QUOTE and BLOCKQUOTE to accommodate _AUTOLEAD control; + spacing above and below quotes is equalized *on a per quote basis* + (not completely happy with this, but at least it gives users some + flexibility in designing (block)quotes) + +* Fri Mar 18 2005 + + o Added mom.vim to /examples + +* Thu Jan 20 2005 + + o Added \*[TB+] and \*[B] to give inline functionality of .TN and + .EL, respectively. + + o Added SECTION and SECTION_CHAR as aliases of LINEBREAK and + LINEBREAK_CHAR + + o Added a NOBREAK option to PAD, so when PAD is called, it's + possible to instruct mom not to advance on the page. + +* Wed Jan 19 2005 + + o New macro, ADD_SPACE, so that extra space can be added at the + top of a new page in document processing; the .ns call in HEADER + was making additional space impossible + + o Reworked handling of ALD/SPACE/SP and LS when they're used at + the tops of pages during pure (i.e. non-docprocessing) + typesetting. First lines were still wandering. Should also be + more intuitive: ALD after LS advances the specified distance from + the top baseline; LS after ALD doesn't change the position of the + first baseline (i.e. merely sets the lead for the text that + follows). + +* Tue Dec 14 2004 + + o Fixed a small problem with spacing under quotes when paragraph + spacing is turned on. + +* Fri Dec 10 2004 + + o Put all calls in VFP_CHECK inside their own environment. + Without the .ev call, the trap invoked VFP_CHECK was chopping off + the first word of the last line before footnotes. + +* Dec 6 2004 + + o Small fixes to elvis_syntax.new (dealing with strings, \{\ and + \} + + o Changed + .ie \\n[#START] \{\ + .if \\n[#DOC_HEADER]=0 \{ . \} + .\} + in HEAD to + .ie \\n[#START] \{\ + .if \\n[#DOC_HEADER]=0 \{ .RLD 1v \} + .\} + so that HEADs at the start of docs with no docheaders falls on + the correct baseline. + +* Dec 3 2004 + + o Removed spurious parens from if ( \\n[#TRAP_DISTANCE] < + \\n[#DOC_LEAD]*2 ) in SUBHEAD. + +* Oct 14 2004 + + o Reworked the LL macro so that the argument can take a prepended + + or - sign (i.e. the argument is relative to the current line + length). + +* Oct 13 2004 + + o Added an .if \\n(.n=0 if to the ie clause in LS that controls + how mom responds to initial LS invocation at page top if T_MARGIN + has been set. Now, if there's text on the "top" baseline, LS + behaves as expected when invoked afterwards. + +* Oct 11 2004 + + o Added an ie !r#DOCS clause to the processing of "top baseline" + ALDs. ALD is used extensively (internally) in the document + processing macros, and does not need to check--indeed, should not + check--for top baseline placement prior to execution. + +* Sep 29 2004 + + o Additions to elvis_syntax.new + +* Sep 12 2004 + + o Small fixes to the documentation. + +* Aug 21 2004 + + o Removed superfluous second arguments from strings UP, DOWN, FWD + and BCK + +* Aug 8 2004 + + o Version changed from the 1.1.x series to 1.2. All of the + features I originally wanted mom to have originally have been + implemented, and appear to be stable. + + o Major overhaul to the setting of page traps and the handling of + footnotes, both "normal" footnotes and footnotes that occur inside + QUOTE, BLOCKQUOTE and EPIGRAPH. + + o Addition of font "styles" to om.tmac, plus changes to the FAMILY + and FT macros to manage them. New section in the doc appendices + on adding fonts and managing the new font styles. + + o Mom now uses a "fallback font" whenever there's an invalid call + to FAMILY. + + o RW and EW now affect only the font in effect. A change of + family or font disables them. + + o BR_AT_LINE_KERN now properly does a .brp (spread and break) when + used in justified text. + + o NEWPAGE, which used to be an alias for .bp, has been moved into + its own macro, in order to make it more responsive to some unusual + situations. + + o Some changes to elvis_syn.new, including that the file + extensions recognized by elvis now include both .mom and .tmac. + This makes om.tmac much easier to read. + +* Jul 6 2004 + + o FT and FAM(ILY) reworked to take advantage of if S, if F and + \n[.sty] additions to groff (1.19.2). Warnings are emitted if a + style hasn't been registered, or if a font style doesn't exist in + the current family. Invalid .FAM(ILY) calls now use a "fallback" + font" (although no warning is issued); fallback is user-settable + + o New macro, FALLBACK_FONT. Not only controls the fallback font + for invalid family calls, but also controls whether mom aborts on + invalid .FT calls after issuing a warning. + + o RW/EW now affect only the current font (or font style) + + o BR_AT_LINE_KERN now (properly) does a break-and-spread when text + is justified. + + o Fairly extensive list of .sty's added to om.tmac. Hopefully, + this will make life easier for users wishing to add new fonts + and/or entire new families to their groff site-font/devps + directory. + +* Jun 6 2004 + + o Altered kerning slightly for footnote markers in text. Daggers + and double-daggers were getting a bit jammed + +* Jun 3 2004 + + o Rewrote the routines dealing with _FAMILY, _FONT, _SIZE, _COLOR + and _QUAD. A single macro for each checks for the calling alias + (e.g. TITLE_FAMILY in _FAMILY), and performs the appropriate + action. + + o All "COLOUR" aliases of "COLOR", no matter where, have been + removed. + + o Added cover and doc cover page generation. + + o Added reference macros COVERTITLE, DOC_COVERTITLE, MISC and + COPYRIGHT (for use with covers only) + + o Fixed EL and TN so they don't spring page traps; in nofill modes + the preceding input line must be terminated by \c. + + o Added #T_MARGIN_LEAD_ADJ to DO_B_MARGIN, DO_T_MARGIN and NEWPAGE + to ensure accurate placement of first lines on new pages when + docprocessing is not taking place. + + o Made NEWPAGE it's own macro; formerly just an alias of .bp. + + o Made BREAKQUOTE obsolete; rewrote sections of footnote handling, + including adding support macros to deal with processing of + footnotes that were started inside quotes, blockquotes and + epigraphs. + + o Added a TERMINATE .em to docprocessing (except letters) to + ensure that deferred footnotes print on the last page of a doc. + +* Mar 15 2004 + + o Added color support + + o Adjusted vertical placement of hyphens around page numbering so + that they are better centered on the height of the page number. + + o Re-wrote portions of the document processing macros so that tabs + behave in a consistent and intuitive manner. Tab structures are + now properly preserved from page to page and column to column. + +* Mar 05 2004 + + o Makefile.sub (GROFF_BIN_PATH): Use SH_SEP. + +* Feb 20 2004 + + o Rewrote the macros associated with DOCTYPE LETTER so that the + user can enter DATE, TO and FROM in any order s/he likes. For + backward compatibility, if the older, fixed order (DATE-TO-FROM) + is used, the date goes flush right with two linespaces after it, + while the other fields go flush left with a single linespace + separating them. + + o Fixed handling of DOCHEADER OFF when fell + short of the top margin of running text (the change is actually in + the SHIM macro, which is called by DOCHEADER). + + o Added a selection of iso 639 two-letter language codes as + optional arguments to SMARTQUOTES, so that the use can enter + her/his language code to get language specific quoting styles + + o Changed the way the strings for \*[ST], \*[STX], \*[FU] + and \*[BU] are read. Formerly, they were entered literally. + Now they're entered as an array. + +* Jan 24 2004 + + o Added lists and associated macros. Mom now does (nested) lists. + + o Added German-style lowered double quotes and two styles of + guillemets to SMARTQUOTES. + + o Added macro SIZE, intended to be called inline as \*[SIZE ]. + This is to bring mom's inline size change syntax into line with + her other inlines. + + o Added ESC_CHAR as an alias of .ec + + o Added doc entries for lists. + + o Updated SMARTQUOTES entry in docs. + + o Updated reserved words in docs. + + o Fixed a few more typos in docs. + +* Mon Dec 29 2003 + + o Makefile.sub (GROFF_BIN_PATH): Use $(SEP). + +* Tue Oct 21 2003 + + o Changed \n[#DRAFT] and \n[#REVISION] to strings \*[$DRAFT] and + \*[$REVISION], allowing for the possibility of blank entries that + don't mess up headers/footers with zeros if user doesn't want any + numbers. + + o Extended handling of draft and revision numbers and strings in + headers/footers for increased flexibility. It's possible now to + have just about any combo of DRAFT_STRING, DRAFT, REVISION_STRING + and REVISION, and have them come out in headers/footers as one + intuitively expects/wants. + +* Mon Oct 13 2003 + + o Finally fix change 2003-08-26, based on ideas from Chuck Silvers + . + + o Makefile.sub: Use a stamp file in the `examples' directory. + +* Sun Aug 31 2003 + + o Makefile.sub: Fix last change to make it really work. + +* Tue Aug 26 2003-08-26 + + o Makefile.sub (prepare_make_examples): Make it work with parallel + runs of `make'. Patch from Chuck Silvers . + +* Fri Jul 25 2003 + + o Added a .bp after .if \\n[#START]=1 in FOOTER. Without it, in + document processing mode, documents that use *none* of the + docprocessing tags (yes, there are times when users want to do + this) ignored the footer trap. + +* Fri Jun 6 2003 + + o Changed register #DOCHEADER_LEAD_ADJ to string + $DOCHEADER_LEAD_ADJ. This means that .DOCHEADER_LEAD no longer + requires a unit of measure; points is assumed. + +* Tue Jun 3 2003 + + o Added SHIM macro, which, when invoked, calculates and moves to + the next "valid" baseline in document processing. + + o Corrected handling of DOCHEADER OFF so that the first + line of running text falls on a "valid" baseline when + is given. + +* Wed May 21 2003 + + o DOC_TITLE changed to be used exclusively with DOCTYPE DEFAULT + + o Fixed problem with restoration of previous doc pagenum style + when endnotes use a different pagenum style (set with + ENDNOTES_PAGENUM_STYLE) + + o Fixed handling of headers/footers with respect to endnotes. + Now, when either headers or footers are on, mom picks up the + correct page header/footer on the last page prior to ENDNOTES, + gets the pageheaders correct for endnotes pages *including the + last one*, and picks up correct page headers/footers for the + subsequent docs after COLLATE + +* Sat May 17 2003 + + o Added TOC (finally) and a nearly complete set of associated + control macros + + o Added new control macros to endnotes: + + ENDNOTES_STRING_CAPS - capitalize the endnotes string + ENDNOTES_NO_COLUMNS - allows docs in columns and endnotes not + ENDNOTES_PAGENUM_STYLE - set page numbering style for endnotes + ENDNOTES_FIRST_PAGENUMBER - set first pagenumber for endnotes + ENDNOTES_ALLOWS_HEADERS - page headers on endnotes pages off or on + ENDNOTES_NO_FIRST_PAGENUM - allows non-printing first page number + when page footers are being used instead of headers + ENDNOTES_SINGLE_SPACE - for TYPEWRITE, if doc double-spaced + SUSPEND/RESTORE_PAGINATION - turns page numbering off for endnotes + + o Added an ADJUST option to ENDNOTE_LEAD + + o Added DOC_TITLE (like TITLE, but sets document-wide title for + collated docs) + + o Added HDRFTR_CENTER_PAD, to allow adjustments to placement of + HDRFTR_CENTER_STRING + + o Added BLANKPAGE macro, to output blank pages (silently numbered) + + o Extensive changes to DEFAULTS, START, COLLATE, HEAD, SUBHEAD and + PARAHEAD because of new TOC and extended flexibility of ENDNOTES + page design + + o Fixed DOCHEADER OFF (distance), FINIS + +* Sat Apr 05 2003 + + o Makefile.sub (GROFFBIN): New variable for groff binary path. + (groff_bin_path): Rename to GROFF_BIN_PATH. + (GROFF): Use GROFFBIN and GROFF_BIN_PATH. + + Patch from Maciej W. Rozycki . + +----------------------------------------------------------------------- + +* Sat Feb 22 2003 + + o (Re)-fixed handling of post epigraph spacing after #START for + TYPEWRITE double-spaced. + +------------------------------------------------------------------------ + +* Sun Feb 16 2003 + + o Added James Ramsey's proposed CHAPTER_TITLE macro, along with + his rewritten START macro and his utility macros to make START + easier to read. + + o Expanded handling of CHAPTER_TITLE to encompass TYPEWRITE, as + well as plugging it into the docheaders. Made CHAPTER_TITLE + backwardly compatible so that pre-1.1.5 docs using CHAPTER_STRING + to create a chapter title remain unaffected when groffed with + 1.1.5. + + o Created control macros for CHAPTER_TITLE FAMILY, FONT and SIZE. + Added defaults for handling of CHAPTER title to DEFAULTS. + Documented CHAPTER_TITLE and everything that goes along with it. + + o Fixed broken draft and revision in headers/footers. + + o Fixed \*[RULE] so that it behaves properly with indents and + justified copy. + + o Fixed/tweaked handling of epigraph spacing in TYPEWRITE. + + o Fixed broken spacing of docheaders in TYPEWRITE. + +* Mon Feb 3 2003 + + o Fixed an oversight in CLOSING for DOCTYPE LETTER (closing wasn't + being set flush left) + +* Sun Sep 29 2002 + + o Changed .ne in .HEAD when PRINTSTYLE TYPESET from 5 to 4. With + 5, heads required at least 2 lines of text underneath or they'd be + deferred to the next page, which created too much whitespace at the + end of the page. Heads will now be processed on the same page if + the head plus at least one line of text underneath fits. I figure + it's easier for the user to break to a new page manually if this + behaviour is unsatisfactory than to massage the page to fix the + excess whitespace. + +* Sun Aug 25 2002 + + o Changed .IX to .IQ. The older form still works, but emits a + message advising the user to update to the newer. (The macro in + om.tmac still remains IX; IQ is an alias.) Docs updated to + reflect the change. + +* Tue Aug 20 2002 + + o Added new (better) way to handle inline kerning. \*[BU #] and + \*[FU #] allow passing an argument to the inline string. The + older forms \*[BU#] and \*[FU#] still work, though. + + o Changed handling of inline horizontal and vertical movements. + Horizontal movements are now done with \*[BCK #] and \*[FWD + #]; verticals with \*[UP #] and \*[DOWN #]. The + older forms \*[FP#] and \*[BP#] still work (horizontals), as do + \*[ALD#] and \*[RLD#] (verticals). + +------------------------------------------------------------------------ + +* Mon Aug 19 2002 + + o Fixed ENDNOTES so footnotes output properly when ENDNOTES is + called + + o Added ENDNOTES_HDRFTR_CENTER so that default no-print of header + center string on endnotes page(s) when DOCTYPE is CHAPTER can be + disabled (i.e. header center will be printed). + +* Sat Aug 10 2002 + + o Added .nf to top of PAD, with a test beforehand for current fill + mode. If fill mode was on, it's restored after PAD completes + processing. Updated reserved.html to include number register + #FILL_MODE. + +* Fri Jul 12 2002 + + o More fixes to underlining. + +* Fri Jul 5 2002 + + o Added capability of endnotes and pertinent control macros to + om.tmac. + + o Added document entries pertaining to endnote macros. + + o Incorporated endnote macros into elvis_syntax. + + o Small doc fixes. + + o Tidied up indenting of om.tmac. + + o Fixed handling of underlining of italics in PRINTSTYLE TYPEWRITE + (there was a problem with footnotes getting underlined when they + shouldn't have been). + + o Removed ENDNOTES from TODO + + o Fixed the character translations for UNDERLINE so they work + properly with digraphs. + +* Mon Jul 1 2002 + + o Expanded docprocessing.html entry "Special Note on Chapters". + Tidied up html a bit. + +* Sat Jun 15 2002 + + o Small fix to PAD to make the use of inlines within the pad + string more intuitive. + + o Added \*[RULE] ( = \l'\n(.lu' ) so that full measure rules + (either to full line length or within tabs) are easier to set. + +* Sat Jun 8 2002 + + o Macro .PS renamed to .PT_SIZE. Alias .TS removed. + + o .tr bits in .CAPS rewritten in the form .tr é\[`E]. + + o General cleanup of docs to reflect changes + + o Small changes/additions to elvis_syn + +* Thu Jun 6 2002 + + o In DOCTYPE, in .if '\\$1'LETTER', added .FOOTER_RIGHT_SIZE +0. + Without it, the suite page was printing at the default + FOOTER_RIGHT_SIZE of -.5, which didn't look good. + +* Wed Jun 5 2002 + + o Makefile.sub (TFLAG): Add `$(top_builddir)/tmac'. + +* Tue Jun 4 2002 + + o Makefile.sub (groff_bin_dirs): Fix typo (forgotten `src' + element). + +* Mon Jun 3 2002 + + o Makefile.sub (uninstall_sub): Don't use `momdocdir' but + `htmldocdir'. Add missing backslash. + +* Sat Jun 1 2002 + + o Makefile.in (prepare_make_examples): Test for `penguin.ps', not + `examples/penguin.ps'. + +* Wed May 29 2002 + + o Rewrote portions of PAGENUM_STYLE and COPYSTYLE so that + PAGENUM_STYLE behaves as advertised. + +* Fri May 24 2002 + + o /Makefile.sub (momdocdir): Removed. + (HTMLDOCFILES): Prepend `momdoc/'. + (EXTRAEXAMPLEFILES): Removed. Added entries to... + (EXAMPLEFILES): This. + (.SUFFIXES, .mom.ps): New. + (prepare_make_examples): Updated. + (examples/*.ps): Removed; .mom.ps will handle this. + (install_data): Updated. + +* hu May 23 2002 + + o Applied two small bug fixes to om.tmac (patches 1.1.1a and + 1.1.1b). + + o mom is now part of groff. + + Some renaming to avoid problems with 8+3 filesystems: + + examples/docprocessing_typeset.mom -> examples/typeset.mom + examples/docprocessing_typewrite.mom -> examples/typewrite.mom + examples/typesetting_macros.mom -> examples/macros.mom + examples/penguin_small2_bw.ps -> examples/penguin.ps + + o Removed `INSTALL' and `README' since groff takes care of + installation now. + + o Added Makefile.sub. + + o Added mom.tmac (which simply calls om.tmac). + + o Added groff_mom.man for orthogonality; it simply points to the + HTML documentation. + +* Thu May 16 2002 + + o Added macro DRAFT_WITH_PAGENUMBER so user can have + draft/revision info attached to the pagenumber in COPYSTYLE DRAFT, + instead of having it HEADER center. Always having it HEADER + center was creating problems with long doc titles, esp. with + PRINTSTYLE TYPEWRITE (which is when COPYSTYLE DRAFT is most likely + to be used). Now user has the choice, in these circumstances, + either to reduce HEADER_SIZE, or to displace the draft/revision + info. Also rewrote portions of COPYSTYLE so that if no revision + number is given in the reference macros, "Rev. #" doesn't appear + when COPYSTYLE DRAFT. + +* Fri May 10 2002 + + o Added capability of user-defined, single string recto/verso + headers/footers. + + o Added new entries to docs about the above. Made some additional + small changes to toc.html, rectoverso.html, and headfootpage.html + to supplement the new entries. + + o Small fix to handling of footer separator rule -- was 1 point + too low owing to fuzziness of #CAP_HEIGHT as returned by + SIZESPECS. + + o Added some more useful stuff to elvis_syntax. + +* Sun May 05 2002 + + o Fix to DEFAULTS so that L_MARGIN and R_MARGIN are reprocessed if + DOCTYPE LETTER. R_MARGIN, as set by DOCTYPE LETTER had no + preceding PAGEWIDTH or PAPER from which to get #PAGE_WIDTH for + figuring out line length. + + o Additional fix to DEFAULTS in handling DOCTYPE LETTER so that if + user sets line length prior to START, no reprocessing of R_MARGIN + occurs. This necessitated adding a new number register: + #USER_SET_L_LENGTH + +* Sat May 04 23:48:05 EDT 2002 + + o Added .cflags 4 /\(en -- was driving me nuts that lines wouldn't + break after these characters; I'm assuming others feel the same + way + +* Fri May 03 2002 + + o Made some small fixes to space handling around quotes, mostly to + do with quotes immediately after START and quotes after + (sub)heads. + +* Wed May 01 2002 + + o Fixed a small bug that was causing the first .PP after START to + begin at the top margin of the page regardless of any type that + preceded .PP when docheaders were off. + + o Fixed HEADER so that when HEADERS are off the first line of type + on pages after the first falls properly at the top margin + +* Sat Apr 27 2002 + + o Renamed docprocessing_macros.mom in /examples to + docprocessing_typeset.mom. Added docprocessing_typewrite.mom, as + well as a README file. + + o Fixed UNDERLINE_QUOTES (for PRINTSTYLE TYPEWRITE) so they really + are on by default as the docs say. + + o Changes to doc entry on COLLATE: + + - removed bit about using COLLATE after a cover page (I wrote the + entry *before* I wrote the macro!). Cover pages should be + followed by NEWPAGE, not COLLATE. + + - added caution about mixing PRINTSTYLEs + + - added caution about using DOC_FAMILY to change family of all + document elements after COLLATE + + o Made HEADER_SIZE (and, by extension, FOOTER_SIZE) available to + PRINTSTYLE TYPEWRITE. Changed appropriate doc entries to reflect + this. + +* Wed Apr 24 2002 + + o Small change to DO_QUOTE to correct a problem with quotes and + blockquotes that fall in the middle of paragraphs (i.e. text after + the quote is not a new para). Basically, added a bit that stores + the current para indent, sets para indent to 0, invokes a PP, then + restores the original para indent. + + o Added new macro, BREAK_QUOTE, to deal with the problem of + footnotes in quotes and blockquotes that cross pages or columns. + + Quotes and blockquotes are read into diversions, which means they + get their footnote information from the page/column on which they + were started. If a footnoted quote crosses a page/column, what + sometimes happens is that the footnote itself is output at the + bottom of page/column where the quote started, whereas the text + marker for the footnote appears on the next page/column where the + quote ends. Furthermore, the text marker is the one appropriate + to the previous page. BREAK_QUOTE is a workaround. + + o Added directory /examples to archive. + + o Added typesetting_macros.mom, docprocessing_macros.mom, + elvis_syntax and penguin_small2_bw.ps to /examples. + + o Added BREAK_QUOTE to docs, made some additions to reserved words + list, and corrected a few little doc errors. + +* Mon Apr 22 2002 + + o Added default .L_MARGIN 1i and .R_MARGIN 1i to PAPER, PAGE, and + PAGEWIDTH. L_MARGIN is essential otherwise left indents and tabs + don't have a register #L_MARGIN to work with. The default right + margin is a convenience only. Updated the doc entries for + L_MARGIN and R_MARGIN to reflect the change. + +* Sun Apr 21 2002 + + o Changes to COLLATE: + + - added some "resets" (LL, LS, QUAD) + - added a check for whether pagination is at page top (either + because FOOTERS are on or because PAGENUM_POS was user set). + If pagination is on, and PAGENUM_POS is TOP, it's turned off + for next page (start of next collated document) and restored + for subsequent pages unless PAGENUM_ON_FIRST_PAGE is on, in + which case the page number appears at page top. + + o The macro TRAPS is always invoked at the end of DEFAULTS (which + is called by START). Formerly, TRAPS was only invoked at the + start of a doc, not after COLLATE. Now runs after COLLATE as + well. + + o Distance from $DOC_TYPE in DOCTYPE NAMED "" to start of + running text was one linespace too deep. Fixed (in START). + + o When 1st arg to PAGENUM_POS was user set to TOP, running text + was printing 1 linespace too high, even when PAGINATION was OFF. + Same problem when HEADERS were OFF (i.e. nothing in the header + margin at all). Fixed by removing -\\n[#DOC_LEAD]u from all .sp + |\\n[#T_MARGIN]u calls of .el portion after .ie \\n[#HEADERS_ON]. + + o Added new macro: PAGENUM_ON_FIRST_PAGE. Normally, when FOOTERS + are being used instead of HEADERS, mom doesn't print the page + number at the top of the first page of a doc, or the first page of + collated docs. New macro allows user to get mom to put the page + number on "first" pages if that's desired. Updated docs to + include the macro. + + o More little fixes to docs. + +* Thu Apr 18 2002 + + o Fixed TI (temporary indent) so that it continues to work as + expected, even when called while another type of indent is in + effect. + +* Tue Apr 16 2002 + + o String tabs weren't working as advertised when set from within a + tab. Fixed. Two new registers added: #ST_OFFSET and #IN_TAB. + String tabs now behave properly and intuitively when set within + tabs. + + o Added a note to docs about surrounding \w'...' escape with + double- quotes when it's used as an argument to macros + + o Added a note to docs that SILENT does not deposit a .br + +* Mon Apr 15 2002 + + o Added new macro BR_AT_LINE_KERN if user wants mom to deposit + .br's before .RW and/or .EW. + + o Added 1/4 points to inline escapes \*[ALD] and \*[RLD]. + + o Added 1/4 points to inline escapes \*[FP] and \*[BP] + + o Updated docs to reflect the above changes. + +* Fri Apr 12 2002 + + o Fixed .RW and .EW which weren't working because of a missing \ + in \\n(.f register. Also made it so that .RW and .EW affect all + fonts in positions 1, 2, 3, and 4 at once, hence line kerning now + affects all fonts that appear after it, not just the font that was + current at the time of the macros' invocation. + + o .SS and .WS now working properly. .WS no longer has any effect + on .SS, which remains constant regardless of .WS. Furthermore, + .SS no longer gets its value by adding \*[$SS_VAR] + \n[.ss]. + Instead, it remains constant. Don't know what I was thinking when + I wrote the routine in the first place. + + o Updated and rewrote doc entry pertaining to SS + +* Wed Apr 10 2002 + + o Renamed tmac.om to om.tmac to bring macro file's name into line + with current groff policy + + o Added more standard paper sizes to PAPER. + + o Fixed T_MARGIN, LS, and AUTOLEAD so that if T_MARGIN is set + before LS or AUTOLEAD at the top of a file, the first line of type + falls properly on the baseline set by T_MARGIN. Previously, LS + and AUTOLEAD automatically advanced by the value passed to them + before setting the first line of type, meaning that the first line + of type fell at T_MARGINu+1v instead of T_MARGIN. + + o Updated docs to reflect changes. + + o Removed #TEST_FOR_NUMERIC from list of reserved words. + + o Added "t" and #T_MARGIN_SET to list of reserved words. + +* Sat Apr 6 2002 + + o Added FACTOR arg to AUTOLEAD, so if user wants autolead to be a + factor of point size, instead of being the sum of pointsize + + autolead, s/he has the choice. Incorporated appropriate changes + to PS and LS. + + o Added new register #AUTOLEAD_FACTOR to reserved words. Modified + comments for AUTOLEAD, PS, and LS to reflect changes. Also + corrected an error where #AUTOLEAD_VALUE had mistakenly been + written $AUTOLEAD_VALUE in comments in the macro file, and removed + erroneous | . Updated AUTOLEAD entry in + momdoc/typesetting.html to reflect the changes. + +* Wed Apr 3 2002 + + o Cleaned up html errors in the docs. + + o Added "Next," "Prev" and "Top" links to top and bottom of doc + files. + + o Fixed some typos in the docs. + +________________________________________________________________________ + +##### License + +Copyright 2004-2020 Free Software Foundation, Inc. + +Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. + +##### Editor settings +Local Variables: +coding: latin-1 +fill-column: 72 +mode: change-log +version-control: never +End: +vim:set autoindent textwidth=72: diff --git a/contrib/mom/NEWS b/contrib/mom/NEWS new file mode 100644 index 0000000..d7cf82a --- /dev/null +++ b/contrib/mom/NEWS @@ -0,0 +1,710 @@ + -*- text -*- + Copyright (C) 2004-2020 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. + +Release 2.5 +----------- +Addition of shaded backgrounds, frames, and page colour. + +Releases 2.4 — 2.4-4_e +---------------------- +General bug fix releases, with an overhaul of float, image, and +pre-processor handling to correct inconsistencies in spacing, +indents, labels, and captions. Corrects page numbering issue in +"Lists of..." when pre-processor material is floated and deferred. + +Release 2.3 +----------- +Addition of DOCTYPE SLIDES and associated macros + NEWSLIDE + PAUSE + TRANSITION for slide presentations processed with gropdf. +Fixes and improvements to nested lists (ITEM now takes a spacing +arg), indents (IB), NEWPAGE (aliased as NEWSLIDE). Addition +of CENTER_BLOCK (center blocks of type over whole line length +regardless of indents). Tighten up graphical object macros. +Addition of macros to handle hanging punctuation. .COLOR preferred +to .gcolor in om.tmac. Changes to HEADER to handle printing of both +headers and footers when DOCTYPE SLIDES. + +Release 2.2 +----------- +Addition of flex-spacing (flexible vertical whitespace). Fixes and +improvements to positioning of floats, images, and pre-processor +material. Addition of TARGET (PDF target) argument to floats, +images, and pre-processor material. Improvements to autolabelling. + +Release 2.1-b +------------- +Fix to handling of kern units. Updated copyright info. + +Release 2.1-a +------------- +Expanded labelling facilities to include floats and +quotes/blockquotes. Improvements to TOC handling. + +Release 2.1 +----------- +Expanded support for doc-covers, covers, and docheaders: + - control macros for formatting every element separately (title, + subtitle, author, etc.); formatting options include family, + font, size, color, quad, caps, smallcaps and underscoring + - (DOC_)COVERTEXT for setting blocks of type on cover pages + - (DOC_)COVER_IMAGE for putting full page or small images on cover + pages + +New _STYLE macros that allow grouping of style parameters +for most document elements into a single macro using keyword/value +pairs. + +Smallcaps, with the ability to control size, weight, and width. + +Release 2.0-c +------------- +Mom now has full support for eqn, pic, and tbl, as well as +captioning and labelling of pdf images and preprocessor output. +Lists of Figures, Equations, and Tables can now be autogenerated. +PDF_IMAGE has a new FRAME option. + +Release 2.0-b +------------- +Improved and expanded float and tbl support. + +Release 2.0-a +------------- +FORCE argument added to FLOAT; immediately breaks to a new page +to output the float if it does not fit on current the page. + +Release 2.0 +----------- +Full integration with gropdf. Mom's focus now is on the generation +of PDF output. PDF outlines and PDF links (internal and external) +fully supported. + +New management of nested heading levels via HEADING , +replacing HEAD, SUBHEAD, SUBSUBHEAD and PARAHEAD. + +"NAMED " argument to HEADING creates PDF target at the +heading. + +Use of "oldstyle" headings preserved, allowing the continued use of HEAD, +SUBHEAD, etc. + +PARAHEAD removed; replaced by HEADING PARAHEAD. + +New management of head styling. + +New management of TOC, mostly transparent to user. + +New management of TOC title and entry styling. + +Overhaul of TOC default style; greater flexibility in numbering +entries, improved indenting, improved spacing. + +FLOAT macro added. + +MN_INIT wrapper re-written such that each argument must be preceded +by a flag. + +New perl script, pdfmom, to facilitate generation of PDF output. + +Additional documentation in the form of a PDF manual, which covers +mom/PDF/groff usage. + +==================================================================== + +Release 1.6-a +------------- +Support for sub-subheads added. + +Release 1.6 +----------- +Complete overhaul of refer handling. If you've been using mom and +refer, the changes may affect documents you've already created. +Please read refer.html. + +Improved underlining thanks to Tadziu Hoffman. + +Increased flexibility of PRINTSTYLE TYPEWRITE, which now allows +user to choose the monospace family and point size. + +Release 1.5-e +------------- +Complete overhaul of documentation + +Release 1.5-d +------------- +Control macros added to various miscellaneous docprocessing +functions + +Release 1.5-c +------------- +Bugfix release (see BUGS, Version 1.5-b). + +Release 1.5-b +------------- +Bugfix release (see BUGS, Version 1.5-a). + +Release 1.5-a +------------- +Bugfix release (see BUGS, Version 1.5). + +Release 1.5 +----------- +Macros have been added to facilitate the drawing of common +graphical objects: rules (horizontal and vertical), boxes (solid or +filled) and circles (ellipses; also solid or filled). The +behaviour of \*[RULE] has changed so that it always deposits a +break when it's called, bringing it (somewhat) into line with the +new macro for drawing rules precisely, DRH. Additionally, a new +macro, RULE_WEIGHT, can be used to control the weight of rules +drawn with \*[RULE]. + +Overall, the handling of underscoring and underlining--wherever it +occurs--has been overhauled so that users can control both the +weight and the placement of underscore/underline rules. New +macros have been created to control, for example, +the weight and placement of the rule under a HEAD, or the weight of +a FOOTNOTE separator rule, etc. Anything that can be underscored +or underlined (except the pseudo-underlining of italic passages in +PRINTSTYLE TYPEWRITE) has a "rule" control macro. See the document +sections pertinent to the macro in question. + +The creation and management of covers and doc covers has been +overhauled for greater flexibility, including the ability to +generate differing titles, subtitles, attribution strings, authors, +doctypes, miscellaneous lines and copyright information for the +same document's doc cover and cover (title) pages, without +affecting the default docheader that appears on page one. +Additionally, you can now get mom to output a blank page after a +cover or doc cover, as well as tell her whether to include covers +and doc covers in the pagination scheme. + +The convenience macro, CODE, has been made more convenient. A new +control macro allows setting users' preferred fixed-width fonts. +Additionally, CODE can now be called inline. + +New inline escapes, \*[UC] and \*[LC], have been added to allow +inline capitalization. This is particularly useful when users +want to pass a header/footer left-center-right part one of mom's +"reserved" strings and want the string capitalized (or not) in the +header/footer. + +For more details, see ChangeLog as well as the documentation. + +Release 1.4-b +------------- +It is now possible to pass an absolute value to QUOTE_INDENT, +BLOCKQUOTE_INDENT and EPIGRAPH_INDENT. If an absolute value +is desired, the user simply appends a unit of measure (scaling +indicator) to the argument. If no unit of measure is appended, +the old behaviour is still observed (i.e. the numeric argument +represents the amount by which to multiply the paragraph indent to +arrive at the desired indent value). + +The main macro file, om.tmac, is now stripped of comments when +groff is built from sources. om.tmac in the sources themselves +still contains the comments, as do the tarballs posted on the mom +homepage. + +Release 1.4-a +------------- +Added a new macro, HEADERS_AND_FOOTERS, to allow having both +headers and footers on a page. + +Release 1.4 +----------- +DOCTITLE, TITLE, CHAPTER_TITLE, SUBTITLE, COVERTITLE and +DOC_COVERTITLE now accept multiple arguments; each is printed +on a separate line. + +New macro, CODE, to facilitate setting programming code snippets. + +Release 1.3-e_<#> +----------------- +New macro, PREFIX_CHAPTER_NUMBER, to allow users to prepend chapter +numbers to the numbering scheme used in head element numbering. + +Indented TOC entries now line up better. + +Line numbering now has control macros for family, font, point size +and color. + +A new macro, NO_SHIM, to disable the automatic shimming of +(possibly irregularly linespaced) quotes and blockquotes. + +Release 1.3-d +------------- +Bug fix release (FONT--removed superfluous "if" that was breaking +fallback font logic; FOOTNOTE--no longer adding a linebreak after +footnote marker in footnote text in nofill modes). + +Fixed indent problem with LIST when both PAD_LIST_DIGITS LEFT and +SHIFT_LIST used concurrently. + +Release 1.3-c +------------- +Bug fix release (margin notes, TYPEWRITE--spacing, underlining and +italicizing + +Release 1.3-b +------------- +Bug fix release. SMARTQUOTES has been smartened; miscellaneous +glitches in PRINTSTYLE TYPEWRITE fixed (see BUGS). Primarily +corrects inconsistencies and bugs with the margin notes routines. + +Release 1.3-a +------------- +Bug fixes: First baseline of type wasn't going where it was supposed +to when the docheader was turned off; fixes to errors in html +formatting of docs. + +Release 1.3 +----------- + +Added line numbering capabilities, with controls. + +Footnotes and endnotes can now be referenced by line number. + +Added ability to adjust vertical position of the title that appears +on the first endnotes page. + +Footnotes can run on when being referenced by line number. + +Footnotes now have a post-footnote spacing option, for adding +a little space between footnotes. + +Extended LIST so it accepts alpha, ROMAN and roman enumerators. + +Added margin notes capability. + +Added refer support. + +Added bibliography page support. + +Added QUOTE_AUTOLEAD and BLOCKQUOTE_AUTOLEAD, so user can have +quotes and blockquotes leaded differently from running text. + +Change: the input line immediately after FOOTNOTE OFF must be +entered as a literal continuation of the line prior to FOOTNOTE, +including any initial spaces or punctuation marks. This allows +for hassle-free placing of footnote markers in running text either +before or after punctuation marks. + +Release 1.2-f +------------- + +Added ADD_SPACE, to permit users to insert space at the top of +running text (after the first page) when using the docprocessing +macros. + +Releases 1.2-a and 1.2-b +------------------------ + +My personal email address has changed. 1.2-a and -b have been +updated to reflect that. Additionally, I made some small changes +to the documentation. + +Release 1.2 +----------- + +As of 1.2, the recommended version of groff to use with mom has +been bumped up from groff, 1.18 to groff, 1.19.2. Although mom will +continue to work with groff, 1.18, her handling of .FAM(ILY) and .FT +is now slightly different, therefore users of groff 1.18 may have to +update documents created with mom so that every .FAM(ILY) request is +followed by a .FT request before any text is input, otherwise mom +will set the text after .FAM(ILY) in Courier (until she encounters a +.FT request). People running groff, >= 1.19.2 don't have to worry +about this, but I recommend that, regardless of which version you're +running, you have a look at the document entries for FAMILY and FT +in order to see how mom will be handling .FAMILY and .FT from now +on. + +When used with groff >=1.19.2, mom now emits warnings if a style +hasn't been registered, or if a font style doesn't exist in the +current family. Invalid .FAM(ILY) calls now use a "fallback" font" +(although no warning is issued). The fallback is user-settable. + +Mom's macro file, om.tmac, now sets up a fairly extensive list of +font "styles," thus expanding the range of arguments that can be +passed to .FT (formerly, just R, I, B and BI, unless users had +already rolled their own solution to the problem of extensive type +families containing fonts like condensed, demibold, black, light, etc). +Users are advised to read the documentation sections on FAM(ILY), +FT and FALLBACK_FONT, as well as the new appendix section, "Adding +PostScript fonts to groff", for information on using mom's style +extensions (and how to disable them, should they conflict with a +user's present groff site-font/devps setup). + +A new macro, FALLBACK_FONT, has been added. It controls not only +the fallback font for invalid .FAMILY calls, but also whether mom +aborts on invalid .FT calls after issuing a warning, or continues +processing using the fallback. + +Release 1.1.9 +------------- + +Added the (optional) generation of cover pages and document cover +pages, plus a full suite of control macros for all cover page +elements. + +Added new reference macros that apply to covers: COVERTITLE, +DOC_COVERTITLE, COPYRIGHT and MISC. + +The need for TRAP OFF/TRAP to deal with ELs and TNs that fall at +the bottom page has been obsoleted. However, both EL and TN, when +invoked in any "nofill" mode (LEFT, RIGHT, CENTER, or the L | R | C +arguments to TAB_SET or ST when no QUAD argument is given), must now +have the input line preceding the EL or TN terminated by \c. Fill +modes do not have this requirement, i.e. no \c is required. + +Footnotes that occur inside quotes, blockquotes and epigraphs now +work just like regular footnotes, with no user intervention +required. This obsoletes the macro BREAK_QUOTE. + +Removed all aliases that used the word COLOUR. Users must use +COLOR wherever COLOR is needed. COLOUR, as a replacement/alias, is +no longer supported. + +NEWPAGE, which used to be an alias of .bp, is now its own macro. + +Release 1.1.8 +------------- + +Added text color support. Users can now define or initialize a color, +and afterwards change text color with an inline of the form +\*[], or with the macro .COLOR. In document processing, +the docelement tag control macros have been expanded to include +_COLOR, e.g. .HEAD_COLOR will colorize +heads, PAGENUM_COLOR ]. +This brings mom's inline size change syntax into line with her other +inlines. \*S[] can still be used for the same thing. + +The file elvis_syntax (for elvis prior to 2.2h) is no longer being +maintained. It was getting messy and long in the tooth. The +official elvis syntax file is elvis_syntax.new, which works for +2.2h of elvis (and higher, one hopes). elvis users are encouraged +to update to 2.2h or higher. + +Release 1.1.6-e +--------------- + +Extended handling of draft and revision numbers and strings in +headers/footers for increased flexibility. It's possible now to +have just about any combo of DRAFT_STRING, DRAFT, REVISION_STRING +and REVISION, and have them come out in headers/footers as one +intuitively expects/wants. + +Also added a new set of syntax highlighting rules for the vi clone, +elvis. Version 2-2h-beta of elvis finally made possible the +highlighting of \*[...] inline escapes, whether or not they're +separated from surrounding text by spaces. This is a terrific +improvement in elvis, and makes for greatly improved readability of +mom files. + +Release 1.1.6-b - 1.1.6d +------------------------ + +Trivial changes to documentation and some cleanups of the main +om.tmac file, including: + +Added a .bp after .if \\n[#START]=1 in FOOTER. Without it, +in document processing mode, documents that use *none* of the +docprocessing tags (yes, there are times when users want to do +this) ignored the footer trap. + +Changed register #DOCHEADER_LEAD_ADJ to string +$DOCHEADER_LEAD_ADJ. This means that .DOCHEADER_LEAD no longer +requires a unit of measure; points is assumed. + +Release 1.1.6-b +--------------- + +Added a SHIM macro that calculates and moves to the next "valid" +baseline during document processing (useful if user starts playing +around with spacing/leading on a page and needs to get the leading +back on track). + +Fixed handling of DOCHEADER OFF so that the first line of +running text falls on a "valid" baseline when is given. + +Release 1.1.6-a +--------------- + +Problem with groff 1.19.1 fixed by Werner (.return handled arguments +incorrectly). + +Fixed handling of page numbering style restoration in endnotes, so +that (collated) docs have the correct page numbering style when the +style has been changed for endnotes (with ENDNOTES_PAGENUM_STYLE). + +DOC_TITLE has been made for use exclusively with DOCTYPE DEFAULT. + +Fixed handling of headers/footers with respect to endnotes. Now, +when either headers or footers are on, mom picks up the correct +page header/footer on the last page prior to ENDNOTES, gets the +pageheaders correct for endnotes pages *including the last one*, and +picks up correct page headers/footers for the subsequent docs after +COLLATE. + + +Release 1.1.6 +------------- + +BAD NEWS: mom appears to be crippled in some areas when run with +groff 1.19.1. Pending a solution, mom must be run with groff 1.18 + +***NEW*** + +Added TOC capabilities. + +Extended range of endnotes control macros. See the documentation +on endnotes control macros. + +Added a new DOC_TITLE macro, to deal with collated documents that +have an overall title, while each doc has its own separate doc +title (from TITLE). + + +Release 1.1.5 +------------- + +***NEW*** + +Added James Ramsey's CHAPTER_TITLE macro as well as control macros to +go with it. Thanks James. Also from James came a patch to handle +START differenty which has been incorporated into om.tmac. Thanks +again, James. + +Some bits and pieces of the docs have been tweaked, but nothing +changed. Hopefully, the changes will make parts of the docs easier to +read and navigate. + +***FIXES*** + +o \*[RULE] + +o broken draft and revision in docheaders + +o post-epigraph spacing in TYPEWRITE + +o header spacing in TYPEWRITE + +------------------------------------------------------------------------ + +Release 1.1.4 +------------- + +***SIGNIFICANT CHANGE*** +.IX is now deprecated, although it will continue to work as before. +The new form is .IQ (Indent Quit). Groff will emit a message advising +users to update their docs. + +***NEW*** +Four new inlines to deal with horizontal and vertical movements: + + o \*[FWD n] + o \*[BCK n] + o \*[UP n] + o \*[DOWN n] + +All four require a unit of measure after n. These inlines are similar +to the older \*[FPn], \*[BPn], \*[ALDn] and \*[RLDn], however they're +not restricted to points, and any value can be entered for n (the older +forms -- which still work -- were restricted to 1 - 36). + +***CHANGED*** +Inline kerning can now be accomplished with \*[BU n] and \*[FU n], where +n, after the space, is the desired number of kern units. The older +forms \*[BUn] and \*[FUn] still work, up to 36 units. + +------------------------------------------------------------------------ + +Release 1.1.3c +-------------- + +***NEW*** +A new macro -- ENDNOTES_HDRFTR_CENTER -- added so that mom's default +behaviour of not printing the header center string when DOCTYPE is +CHAPTER can be disabled (i.e. she will print the center string). The +macro is user-called with ENDNOTES_HEADER_CENTER or +ENDNOTES_FOOTER_CENTER. + +***FIXES*** +PAD now works as advertised when fill mode is on. + +ENDNOTES no longer disables printing of footnotes on last page of +document body. + +Release 1.1.3 +------------- + +***SIGNIFICANT CHANGE -- PLEASE TAKE NOTE*** +As of 1.1.3, groff must be >= 1.18. + +***NEW*** +Added endnotes functionality to mom, along with a slew of macros to +control how mom prints endnotes pages. See the html documentation. + +***NEW*** +Added inline \*[RULE], which draws a rule to the full measure of the +current line length ( to be used in place of \h'\n(.lu' ). Weight of the +rule is dependent on the point size of type when \#[RULE] is called. + +***FIXES*** +PAD -- works more intuitively now when the pad string contains inline +escapes for font, point size, etc. + +UNDERLINE -- fixed character translations of digraphs so they get +underlined properly. Also fixed a bug that was causing some footnotes +to get underlined when UNDERLINE was on in the body of the document. + +***UPDATES*** +Html documentation +elvis_syn + +Release 1.1.2a +-------------- + +***SIGNIFICANT CHANGE -- PLEASE TAKE NOTE*** +In order to help mom toward full groffship, the macro .PS has been +renamed to .PT_SIZE, and the alias .TS (for .TAB_SET) has been removed. +.PS and .TS are keywords used by pic and tbl respectively, and the mom +macros of the same name were in conflict. + +Release 1.1.2 +------------- + +***IT'S OFFICIAL!*** +mom is now an official part of the groff. New releases will be +incorporated into the groff package. I'll still be posting each new +release on the mom homepage, so there's no need to download all of the +most recent version of groff just to get a newer mom. :) + +***CHANGES*** +Fixed default footer separator rule adjustment so that it's closer to +the advertised "4 points above the tallest ascender in the footer." + +Added more stuff to the elvis_syn file. Still wouldn't mind someone +contributing some vim/emacs syntax highlighting. + +Added .cflags 4 /\(em to om.tmac. By default, mom now obligingly +breaks after / and \(en. + +***NEW*** +Macro(s): HEADER_RECTO + HEADER_VERSO +With these macros, users can now define single-string recto/verso +headers/footers. HEADER_RECTO (or FOOTER_RECTO) can be used to create +a one-part header/footer (instead of mom's default three-parters) that +appears on every page if RECTO_VERSO is OFF or, if RECTO_VERSO is on, if +no HEADER_VERSO (or FOOTER_VERSO) has been defined. If a HEADER_VERSO +(or FOOTER_VERSO) is defined and RECTO_VERSO is on, _RECTO prints on +even pages and _VERSO on odd pages. + +Added macro DRAFT_WITH_PAGENUMBER so user can have draft/revision +info attached to the pagenumber in COPYSTYLE DRAFT, instead of having +it HEADER center. Always having it HEADER center was creating problems +with long doc titles, esp. with PRINTSTYLE TYPEWRITE (which is when +COPYSTYLE DRAFT is most likely to be used). + +***FIXES*** +No more "can't break line" warnings in DOCTYPE LETTER. + +If no REVISION number is given, Rev. 0 no longer appears HEADER_CENTER +in COPYSTYLE DRAFT + +PAGENUM_STYLE now works as advertised. + +Release 1.1.1 +------------- + +***CHANGES*** +Main macro file renamed to om.tmac, in keeping with current groff +policy. + +Now okay to use groff mailing list for mom-related posts + +***NEW*** +Toggle macro -- BR_AT_LINE_KERN. When on, automatically deposits +a break whenever .RW or .EW are invoked. Very useful when kerning +whole lines of rag copy. + +***NEW*** +Toggle macro -- PAGENUM_ON_FIRST_PAGE. Normally, when FOOTERS are +being used instead of HEADERS, mom doesn't print the page number at +the top of the first page of a doc, or the first page of collated docs. +PAGENUM_ON_FIRST_PAGE allows user to get mom to put the page number on +"first" pages if that's desired. + +***NEW*** +Macro -- BREAK_QUOTE -- to deal with problem of footnoted quotes and +blockquotes that cross a page or column. + +***NEW*** +New argument to AUTOLEAD -- FACTOR. With FACTOR, you can, if you +wish, enter a factor by which AUTOLEAD multiplies the point size when +calculating lead automatically. + +Improvements +------------ + +PAPER now has a much larger selection of common paper sizes. + +\*[ALD], \*[RLD], \*[FP] and \*[BP] now accept increments of quarter +points (expressed as decimal fractions). \*[RLD1.75], for example, +reverses 1-3/4 points up on the line. + +HEADER_SIZE now available to PRINTSTYLE TYPEWRITE. This was necessary +to deal with the problem of excessively long HEADER_LEFT, _CENTER or +_RIGHT strings. + +Fixes +----- + +T_MARGIN -- can be set before or after LS or AUTOLEAD +SS -- remains constant regardless of WS +WS -- no longer affects SS +TI -- now works as expected even when called while another indent + type is in effect +COLLATE -- small fixes + +Broken .RW and .EW fixed. + +String tabs now behave properly when set from within tabs. + +UNDERLINE_QUOTES (for PRINTSTYLE TYPEWRITE) are now, in fact, on by +default as the docs state. diff --git a/contrib/mom/TODO b/contrib/mom/TODO new file mode 100644 index 0000000..d9bb257 --- /dev/null +++ b/contrib/mom/TODO @@ -0,0 +1,10 @@ + -*- txt -*- + Copyright 2004-2020 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. + +- cutarounds +- clickable footnote and endnote markers +- indexing diff --git a/contrib/mom/copyright b/contrib/mom/copyright new file mode 100644 index 0000000..04c09d9 --- /dev/null +++ b/contrib/mom/copyright @@ -0,0 +1,24 @@ +-*- text -*- +AUTHOR +------ +Peter Schaffter (peter@schaffter.ca) +6-331 Mona Ave +Vanier (ON) CANADA +K1L 7A3 + +======================================================================== + +The groff macro file om.tmac and the html documentation pertaining to +it are Copyright (C) 2004-2021 Peter Schaffter. + +om.tmac is issued under the GNU General Public License, a full copy of +which can be had at + + http://www.gnu.org/licenses/gpl.html + +The html documentation pertaining to om.tmac is issued under the GNU +Free Documentation License, a full copy of which can be had at + + http://www.gnu.org/copyleft/fdl.html + +======================================================================== diff --git a/contrib/mom/examples/README-fr.txt b/contrib/mom/examples/README-fr.txt new file mode 100644 index 0000000..5b1b434 --- /dev/null +++ b/contrib/mom/examples/README-fr.txt @@ -0,0 +1,126 @@ +-*- mode: text; coding: utf-8; -*- +Copyright (C) 2014-2020 Free Software Foundation, Inc. + +Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. + +======================================================================== + +Les fichiers dans ce rĂŠpertoire vous permettent de voir mom en pleine +action. + +Si vous avez tĂŠlĂŠchargĂŠ et dĂŠcompressĂŠ une version de mom depuis sa +page d'accueil, vous verrez qu'aucun exemple n'est accompagnĂŠ du +fichier PDF (.pdf) correspondant, comme c'est le cas sur les versions +prĂŠ-compilĂŠes de groff, ou groff compilĂŠ Ă  partir des sources. + +Je n'ai pas inclu les PDF parce que je voulais conserver l'archive mom +aussi petite que possible. Pour gĂŠnĂŠrer les PDF, traitez les fichiers +avec pdfmom(1). + + pdfmom mom-pdf.mom > mom-pdf.pdf + pdfmom sample_docs.mom > sample_docs.pdf + pdfmom slide-demo.mom > slide-demo.pdf + pdfmom -k letter.mom > letter.pdf + pdfmom -k mon_premier_doc.mom > mon_premier_doc.pdf + pdfmom -k typesetting.mom > typesetting.pdf + +Les fichiers +------------ + +Tous les fichiers sont configurĂŠs pour le format lettre US, exceptĂŠs +mom-pdf.mom et mon_premier_doc.mom, qui utilisent le format A4. + +***typesetting.mom** + +Le fichier typesetting.mom montre l'utilisation d'ĂŠlĂŠments de +composition typographique: tabulations, tabulations intĂŠgrĂŠes dans des +chaĂŽnes de caractères, remplissage de lignes, texte sur plusieurs +colonnes et diffĂŠrents styles d'indentation; ainsi que certaines +subtilitĂŠs et rĂŠglages prĂŠcis disponibles via des macros et des +ĂŠchappements en ligne ("inline escape", des commandes insĂŠrĂŠes +directement dans le texte, par opposition aux macros). + +Comme ce fichier montre ĂŠgalement l'utilisation d'une petite image au +milieu d'un texte et que cette image est la mascotte favorite de tout +le monde -- Tux, le fichier PDF de cette image, penguin.pdf, a ĂŠtĂŠ +ajoutĂŠ dans ce rĂŠpertoire. + +***sample_docs.mom*** + +Le fichier sample_docs.mom montre en exemple les trois styles de +documents apportĂŠs par les macros de formattage de document de mom, +ansi que l'utilisation de COLLATE. Il montre ĂŠgalement certaines +fonctionnalitĂŠs PDF de mom dont l'ĂŠcriture d'une ĂŠbauche de nouvelle +ou des liens cliquables dans une table des matières. + +Le dernier exemple dĂŠmontre, par un texte sĂŠparĂŠ en deux colonnes, la +souplesse de mom pour la conception de document. + +Le PRINTSTYLE de ce fichier est TYPESET et vous donne une idĂŠe du +comportement par dĂŠfaut de mom pour la composition typographique de +document. + +Si vous souhaitez voir comment mom traite le mĂŞme fichier quand +PRINTSTYLE est TYPEWRITE (c'est-Ă -dire dactylographiĂŠ, avec espace +double) remplacez .PRINTSTYLE TYPESET par .PRINTSTYLE TYPEWRITE au +dĂŠbut du fichier. + +***letter.mom*** + +Ceci est simplement l'exemple du tutorial de momdocs, prĂŞt Ă  ĂŞtre vu. + +***slide-demo.mom*** + +Le fichier slide-demo.mom montre une prĂŠsentation de diapositives +avec des effets PAUSE et TRANSITION. Le fichier .pdf gĂŠnĂŠrĂŠ avec +pdfmom devrait ĂŞtre ouvert en mode PrĂŠsentation d'un lecteur PDF +(Okular, Evince, Acroread). Notez que pas tous les effets de +transition sont disponibles pour tous les lecteurs PDF. + +***mon_premier_doc.mom*** + +Le fichier mon_premier_doc.mom est un exemple simple en français +montrant l'utilisation d'ĂŠlĂŠments de formattage courants: titres de +section, paragraphes, listes, table des matières et liens PDF +cliquables. Il doit ĂŞtre gĂŠnĂŠrĂŠ avec l'option -k du fait de la +prĂŠsence de caractères accentuĂŠs. + +Un certain nombre de rĂŠglages ont ĂŠgalement ĂŠtĂŠ changĂŠs pour ce +document en français: ATTRIBUTE_STRING est utilisĂŠ pour remplacer +"by" par "par" en tĂŞte de document (lĂ  oĂš le titre et l'auteur sont +affichĂŠs). TOC_HEADER_STRING sert Ă  modifier le titre de la table des +matières en "Table des matières" plutĂ´t que "Table of Content". Enfin, +le paramètre de configuration INDENT_FIRST_PARAS est activĂŠ afin +d'indenter le premier paragraphe de chaque section -- ceci est l'usage +en typographie française. + +***copyright-default.mom/copyright-chapter.mom*** + +Deux fichiers qui montrent la bonne façon d'insĂŠrer une page des +droits d'auteur dans les documents crĂŠĂŠs avec mom. "Default" est +pour DOCTYPE DEFAULT; "chapter" est pour DOCTYPE CHAPTER. + +***mom-pdf.mom*** + +Le manuel "Producing PDFs with mom and groff". + +***mom.vim*** + +Les règles de coloration syntaxique vim sont basĂŠĂŠs sur celles +fournies par Christian V. J. BrĂźssow (cvjb@cvjb.de). Copiez le fichier +mom.vim dans votre rĂŠpertoire ~/.vim/syntax directory; ensuite, +autorisez la coloration syntaxique si ce n'est pas encore le cas: + + :syntax enable +ou + :syntax on + +***elvis_syntax.new*** + +Ceux qui utilisent elvis, le clone de vi, peuvent directement +copier-coller le contenu de ce fichier dans leur elvis.syn. Tous les +fichiers ayant l'extension .mom auront la coloration syntaxique. Les +règles dans elvis_syntax ne sont pas exhaustive, mais aideront +beaucoup Ă  rendre les fichiers mom plus lisibles. diff --git a/contrib/mom/examples/README.txt b/contrib/mom/examples/README.txt new file mode 100644 index 0000000..851a9a2 --- /dev/null +++ b/contrib/mom/examples/README.txt @@ -0,0 +1,119 @@ +-*- mode: text; coding: utf-8; -*- +Copyright (C) 2004-2020 Free Software Foundation, Inc. + +Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. + +======================================================================== + +The files in this directory show mom in action. + +If you have downloaded and untarrred a version of mom from her +homepage, you'll see that none of the example files come with +corresponding PDF (.pdf) files, as they do with pre-compiled +versions of groff, or groff built from source. + +I haven't included the PDF output because I want to keep the mom +archive as lean as possible. To view the PDF output, process the +files with pdfmom(1). + + pdfmom mom-pdf.mom > mom-pdf.pdf + pdfmom sample_docs.mom > sample_docs.pdf + pdfmom slide-demo.mom > slide-demo.pdf + pdfmom -k letter.mom > letter.pdf + pdfmom -k mon_premier_doc.mom > mon_premier_doc.pdf + pdfmom -k typesetting.mom > typesetting.pdf + +The files themselves +-------------------- + +All are set up for US letter papersize except mom-pdf.mom and +mon_premier_doc.mom, which uses A4. + +***typesetting.mom** + +The file, typesetting.mom, demonstrates the use of typesetting tabs, +string tabs, line padding, multi-columns and various indent styles, +as well as some of the refinements and fine-tuning available via +macros and inline escapes. + +Because the file also demonstrates a cutaround using a small picture +of everybody's favourite mascot, Tux, the PDF file, penguin.pdf has +been included in the directory. + +***sample_docs.mom*** + +The file, sample_docs.mom, shows examples of three of the document +styles available with the mom's document processing macros, as well +as demonstrating the use of COLLATE. It also shows off some of +mom's PDF features, including a PDF outline and clickable links in +the printable Table of Contents. + +The last sample, set in 2 columns, demonstrates mom's flexibility +when it comes to designing documents. + +The PRINTSTYLE of this file is TYPESET, to give you an idea of mom's +default behaviour when typesetting a document. + +If you'd like to see how mom handles exactly the same file when the +PRINTSTYLE is TYPEWRITE (ie typewritten, double-spaced), simply +change .PRINTSTYLE TYPESET to .PRINTSTYLE TYPEWRITE near the top of +the file. + +***letter.mom*** + +This is just the tutorial example from the momdocs, ready for +previewing. + +***slide-demo.mom*** + +The file, slide-demo.mom, demonstrates a slide presentation with +PAUSE and TRANSITION effects. The .pdf created by pdfmom should be +opened in Presentation Mode in a PDF reader (e.g. Okular, Evince, +Acroread). Note that not all transition effects are available in +all PDF readers. + +***mon_premier_doc.mom*** + +The file, mon_premier_doc.mom, is a simple example in French showing +the use of common elements: section headings, paragraphs, lists, table +of contents and clickable links. It should be generated with option -k +as there are some accented letters. + +A few settings were also changed for this French document: +ATTRIBUTE_STRING is used to replace "by" by "par" in the document +header (where the title and the author are displayed). +TOC_HEADER_STRING is used to modity the Table of Content title to +"Table des matičres". And finally, INDENT_FIRST_PARAS is used to +indent the first paragraph of a section -- this is the usual +convention in French typesetting. + +***copyright-default.mom/copyright-chapter.mom*** + +These two files demonstrate the correct way to insert a copyright +page into mom documents. "Default" is for DOCTYPE DEFAULT; +"chapter" is for DOCTYPE CHAPTER. + +***mom-pdf.mom*** + +The manual, Producing PDFs with mom and groff. + +***mom.vim*** + +The vim syntax highlighting rules are based on those provided by +Christian V. J. Brüssow (cvjb@cvjb.de). Copy mom.vim file to your +~/.vim/syntax directory; then, if your vim isn't already set up to +do so, enable mom syntax highlighting with + + :syntax enable +or + :syntax on + +***elvis_syntax.new*** + +For those who use the vi clone, elvis, you can paste this file into +your elvis.syn. Provided your mom documents have the extension +.mom, they'll come out with colorized syntax highlighting. The +rules in elvis_syntax aren't exhaustive, but they go a long way to +making mom files more readable. diff --git a/contrib/mom/examples/copyright-chapter.mom b/contrib/mom/examples/copyright-chapter.mom new file mode 100644 index 0000000..261c712 --- /dev/null +++ b/contrib/mom/examples/copyright-chapter.mom @@ -0,0 +1,160 @@ +.\" -*- mode: text; coding: utf-8; -*- +\# +\# Copyright (C) 2019-2020 Free Software Foundation, Inc. +\# +\# Copying and distribution of this file, with or without modification, +\# are permitted in any medium without royalty provided the copyright +\# notice and this notice are preserved. +\# +.ig +***Template for creating a copyright page, DOCTYPE CHAPTER*** +. +Mom documents comprised of chapters using DOCTYPE CHAPTER require +the START macro to begin each chapter, and the COLLATE macro to join +it to the subsequent chapter. +. +A copyright page (also called an edition page), which is not a +chapter, should be treated as a DOCTYPE DEFAULT. The text of +the copyright page is entered after START and joined to the first +chapter (DOCTYPE CHAPTER) with COLLATE. +. +Copyright pages are not identified by a title or heading, however +they require a TITLE in order to be included in PDF viewer outlines +and the Table of Contents. Supplying '.TITLE "Copyright"' +but disabling the DOCHEADER achieves both these requirements. +. +Pagination should also be disabled for the copyright page. Both +docheader and pagination should be re-enabled before the START of +the first chapter. +.. +. +.\" Cover setup +. +.\" By default, mom uses the last TITLE macro before START for the +.\" title that appears on the cover. Since the TITLE is "Copyright," +.\" mom needs to be told explicitly to use a different title. +. +.\" Cover and PDF viewer setup +. +.DOCTITLE "Book Title" +.TITLE DOC_COVER \ + "\*[$DOCTITLE]" \" Title for the cover page +.AUTHOR \ + "Book Author" +.DOC_COVER \ + TITLE AUTHOR +.PDF_TITLE \ + "DOCTYPE CHAPTER with copyright page" \" For PDF viewer titlebar +. +.\" Copyright page setup +. +.PRINTSTYLE TYPESET +.DOCTYPE DEFAULT \" Copyright page is not a chapter. +. +.DOCHEADER off 1i \" Turn off docheader for copyright page. +. \" Begin text 1 inch from page top. +.PAGINATION off \" Disable pagination for copyright page. +. +.TITLE "Copyright" \" Required for the PDF viewer outline; does not +. \" get printed because docheader is disabled. +.NO_TOC_ENTRY \" So copyright page is not included in the TOC +. +.START \" Begin example copyright page +All rights reserved. No part of this publication may be reproduced, +distributed, or transmitted in any form or by any means, including +photocopying, recording, or other electronic or mechanical methods, +without the prior written permission of the publisher, except +in the case of brief quotations embodied in critical reviews +and certain other noncommercial uses permitted by copyright +law. For permission requests, write to the publisher, addressed +“Attention: Permissions Coordinator,” at the address below. +.SP +.LEFT +Copyright \[co]2019 Copyright Holder +.SP +Additional information... +.TOC_AFTER_HERE \" Place TOC after copyright page. +. +.COLLATE +. +.\" Chapter setup +. +.DOCTYPE CHAPTER \" Begin using DOCTYPE CHAPTER. +.TITLE \ + "\*[$DOCTITLE]" \" Needed for page headers. +. \" Only required before first chapter. +.CHAPTER 1 +.CHAPTER_TITLE \ + "Sample Chapter" +.DOCHEADER \" Re-enable docheader. +.PAGINATE \" Re-enable pagination. +.PAGENUMBER 1 +. +.START \" Begin first chapter. +.PP +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed at +ante. Mauris eleifend, quam a vulputate dictum, massa quam dapibus +leo, eget vulputate orci purus ut lorem. In fringilla mi in ligula. +Pellentesque aliquam quam vel dolor. Nunc adipiscing. Sed quam odio, +tempus ac, aliquam molestie, varius ac, tellus. Vestibulum ut nulla +aliquam risus rutrum interdum. Pellentesque lorem. Curabitur sit +amet erat quis risus feugiat viverra. Pellentesque augue justo, +sagittis et, lacinia at, venenatis non, arcu. Nunc nec libero. In +cursus dictum risus. Etiam tristique nisl a nulla. Ut a orci. +Curabitur dolor nunc, egestas at, accumsan at, malesuada nec, magna. +.PP +Nulla facilisi. Nunc volutpat. Vestibulum ante ipsum primis in +faucibus orci luctus et ultrices posuere cubilia Curae; Ut sit +amet orci vel mauris blandit vehicula. Nullam quis enim. Integer +dignissim viverra velit. Curabitur in odio. In hac habitasse platea +dictumst. Ut consequat, tellus eu volutpat varius, justo orci +elementum dolor, sed imperdiet nulla tellus ut diam. Vestibulum +ipsum ante, malesuada quis, tempus ac, placerat sit amet, elit. +.PP +Sed eget turpis a pede tempor malesuada. Vivamus quis mi at leo +pulvinar hendrerit. Cum sociis natoque penatibus et magnis dis +parturient montes, nascetur ridiculus mus. Pellentesque aliquet +lacus vitae pede. Nullam mollis dolor ac nisi. Phasellus sit amet +urna. Praesent pellentesque sapien sed lacus. Donec lacinia odio +in odio. In sit amet elit. Maecenas gravida interdum urna. Integer +pretium, arcu vitae imperdiet facilisis, elit tellus tempor nisi, +vel feugiat ante velit sit amet mauris. Vivamus arcu. Integer +pharetra magna ac lacus. Aliquam vitae sapien in nibh vehicula +auctor. Suspendisse leo mauris, pulvinar sed, tempor et, consequat +ac, lacus. Proin velit. Nulla semper lobortis mauris. Duis urna +erat, ornare et, imperdiet eu, suscipit sit amet, massa. Nulla nulla +nisi, pellentesque at, egestas quis, fringilla eu, diam. +.PP +Donec semper, sem nec tristique tempus, justo neque commodo nisl, +ut gravida sem tellus suscipit nunc. Aliquam erat volutpat. Ut +tincidunt pretium elit. Aliquam pulvinar. Nulla cursus. Suspendisse +potenti. Etiam condimentum hendrerit felis. Duis iaculis aliquam +enim. Donec dignissim augue vitae orci. Curabitur luctus felis a +metus. Cum sociis natoque penatibus et magnis dis parturient montes, +nascetur ridiculus mus. In varius neque at enim. Suspendisse massa +nulla, viverra in, bibendum vitae, tempor quis, lorem. +.PP +Donec dapibus orci sit amet elit. Maecenas rutrum ultrices lectus. +Aliquam suscipit, lacus a iaculis adipiscing, eros orci pellentesque +nisl, non pharetra dolor urna nec dolor. Integer cursus dolor vel +magna. Integer ultrices feugiat sem. Proin nec nibh. Duis eu dui +quis nunc sagittis lobortis. Fusce pharetra, enim ut sodales luctus, +lectus arcu rhoncus purus, in fringilla augue elit vel lacus. In +hac habitasse platea dictumst. Aliquam erat volutpat. Fusce iaculis +elit id tellus. Ut accumsan malesuada turpis. Suspendisse potenti. +Vestibulum lacus augue, lobortis mattis, laoreet in, varius at, +nisi. Nunc gravida. Phasellus faucibus. In hac habitasse platea +dictumst. Integer tempor lacus eget lectus. Praesent fringilla augue +fringilla. +.PP +Pellentesque aliquam quam vel dolor. Nunc adipiscing. Sed quam odio, +tempus ac, aliquam molestie, varius ac, tellus. Vestibulum ut nulla +aliquam risus rutrum interdum. Pellentesque lorem. Curabitur sit +amet erat quis risus feugiat viverra. Pellentesque augue justo, +sagittis et, lacinia at, venenatis non, arcu. Nunc nec libero. In +cursus dictum risus. Etiam tristique nisl a nulla. Ut a orci. +.TOC +.\" Local Variables: +.\" mode: nroff +.\" End: +.\" vim: filetype=groff: diff --git a/contrib/mom/examples/copyright-default.mom b/contrib/mom/examples/copyright-default.mom new file mode 100644 index 0000000..25a428f --- /dev/null +++ b/contrib/mom/examples/copyright-default.mom @@ -0,0 +1,149 @@ +.\" -*- mode: text; coding: utf-8; -*- +\# +\# Copyright (C) 2019-2020 Free Software Foundation, Inc. +\# +\# Copying and distribution of this file, with or without modification, +\# are permitted in any medium without royalty provided the copyright +\# notice and this notice are preserved. +\# +.ig +***Template for created a copyright page, DOCTYPE DEFAULT*** + +Mom documents comprised of titled sections using DOCTYPE DEFAULT +(e.g. a collection of articles or a book of short stories by +different authors) require the START macro to begin each new +section, and the COLLATE macro to join it to the subsequent section. +. +A copyright page (also called an edition page) should be treated +as a titled section. The text of the copyright page is entered +after START and joined to the next major section (i.e. the beginning +of a document's content) with COLLATE. +. +Copyright pages are not identified by a title or heading, however +they require a TITLE in order to be included in PDF viewer outlines +and, if desired, the Table of Contents. Supplying '.TITLE "Copyright"' +but disabling the DOCHEADER achieves both these requirements. +. +Pagination should also be disabled for the copyright page. Both +docheader and pagination should be re-enabled before the START of +the first (titled) section of the document. +.. +. +.\" Cover and PDF viewer setup +. +.\" By default, mom uses the last TITLE macro before START for the +.\" title that appears on the cover. Since the TITLE is "Copyright," +.\" mom needs to be told explicitly to use a different title. +. +.TITLE DOC_COVER \ + "Document Title" +.EDITOR DOC_COVER \ + "Document Editor" +.ATTRIBUTE_STRING DOC_COVER \ + "Edited by" +.DOC_COVER \ + TITLE EDITOR +.PDF_TITLE \ + "DOCTYPE DEFAULT with copyright page" \" For PDF viewer titlebar +. +.\" Copyright page setup +. +.PRINTSTYLE TYPESET +.DOCHEADER off 1i \" Turn off docheader for copyright page. +. \" Begin text 1 inch from page top. +.PAGINATION off \" Disable pagination for copyright page. +. +.TITLE "Copyright" \" Required for PDF viewer outline; does not +. \" get printed because docheader is disabled. +. +.NO_TOC_ENTRY \" So copyright page is not included in the TOC +. +.START \" Begin copyright page +All rights reserved. No part of this publication may be reproduced, +distributed, or transmitted in any form or by any means, including +photocopying, recording, or other electronic or mechanical methods, +without the prior written permission of the publisher, except +in the case of brief quotations embodied in critical reviews +and certain other noncommercial uses permitted by copyright +law. For permission requests, write to the publisher, addressed +“Attention: Permissions Coordinator,” at the address below. +.SP +.LEFT +Copyright \[co]2019 Copyright Holder +.SP +Additional information... +.TOC_AFTER_HERE \" Place TOC after copyright page. +. +.COLLATE +. +.\" Sample article setup +. +.TITLE \ + "Sample article" \" Title of first article +.AUTHOR \ + "Article Author" +.DOCHEADER \" Re-enable docheader. +.PAGINATE \" Re-enable pagination. +.PAGENUMBER 1 +. +.START +.PP +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed at +ante. Mauris eleifend, quam a vulputate dictum, massa quam dapibus +leo, eget vulputate orci purus ut lorem. In fringilla mi in ligula. +Pellentesque aliquam quam vel dolor. Nunc adipiscing. Sed quam odio, +tempus ac, aliquam molestie, varius ac, tellus. Vestibulum ut nulla +aliquam risus rutrum interdum. Pellentesque lorem. Curabitur sit +amet erat quis risus feugiat viverra. Pellentesque augue justo, +sagittis et, lacinia at, venenatis non, arcu. Nunc nec libero. In +cursus dictum risus. Etiam tristique nisl a nulla. Ut a orci. +Curabitur dolor nunc, egestas at, accumsan at, malesuada nec, magna. +.PP +Nulla facilisi. Nunc volutpat. Vestibulum ante ipsum primis in +faucibus orci luctus et ultrices posuere cubilia Curae; Ut sit +amet orci vel mauris blandit vehicula. Nullam quis enim. Integer +dignissim viverra velit. Curabitur in odio. In hac habitasse platea +dictumst. Ut consequat, tellus eu volutpat varius, justo orci +elementum dolor, sed imperdiet nulla tellus ut diam. Vestibulum +ipsum ante, malesuada quis, tempus ac, placerat sit amet, elit. +.PP +Sed eget turpis a pede tempor malesuada. Vivamus quis mi at leo +pulvinar hendrerit. Cum sociis natoque penatibus et magnis dis +parturient montes, nascetur ridiculus mus. Pellentesque aliquet +lacus vitae pede. Nullam mollis dolor ac nisi. Phasellus sit amet +urna. Praesent pellentesque sapien sed lacus. Donec lacinia odio +in odio. In sit amet elit. Maecenas gravida interdum urna. Integer +pretium, arcu vitae imperdiet facilisis, elit tellus tempor nisi, +vel feugiat ante velit sit amet mauris. Vivamus arcu. Integer +pharetra magna ac lacus. Aliquam vitae sapien in nibh vehicula +auctor. Suspendisse leo mauris, pulvinar sed, tempor et, consequat +ac, lacus. Proin velit. Nulla semper lobortis mauris. Duis urna +erat, ornare et, imperdiet eu, suscipit sit amet, massa. Nulla nulla +nisi, pellentesque at, egestas quis, fringilla eu, diam. +.PP +Donec semper, sem nec tristique tempus, justo neque commodo nisl, +ut gravida sem tellus suscipit nunc. Aliquam erat volutpat. Ut +tincidunt pretium elit. Aliquam pulvinar. Nulla cursus. Suspendisse +potenti. Etiam condimentum hendrerit felis. Duis iaculis aliquam +enim. Donec dignissim augue vitae orci. Curabitur luctus felis a +metus. Cum sociis natoque penatibus et magnis dis parturient montes, +nascetur ridiculus mus. In varius neque at enim. Suspendisse massa +nulla, viverra in, bibendum vitae, tempor quis, lorem. +.PP +Donec dapibus orci sit amet elit. Maecenas rutrum ultrices lectus. +Aliquam suscipit, lacus a iaculis adipiscing, eros orci pellentesque +nisl, non pharetra dolor urna nec dolor. Integer cursus dolor vel +magna. Integer ultrices feugiat sem. Proin nec nibh. Duis eu dui +quis nunc sagittis lobortis. Fusce pharetra, enim ut sodales luctus, +lectus arcu rhoncus purus, in fringilla augue elit vel lacus. In +hac habitasse platea dictumst. Aliquam erat volutpat. Fusce iaculis +elit id tellus. Ut accumsan malesuada turpis. Suspendisse potenti. +Vestibulum lacus augue, lobortis mattis, laoreet in, varius at, +nisi. Nunc gravida. Phasellus faucibus. In hac habitasse platea +dictumst. Integer tempor lacus eget lectus. Praesent fringilla augue +fringilla dui. +.TOC +.\" Local Variables: +.\" mode: nroff +.\" End: +.\" vim: filetype=groff: diff --git a/contrib/mom/examples/elvis_syntax b/contrib/mom/examples/elvis_syntax new file mode 100644 index 0000000..b5735bf --- /dev/null +++ b/contrib/mom/examples/elvis_syntax @@ -0,0 +1,96 @@ +" Copyright (C) 2004-2020 Free Software Foundation, Inc. +" +" Copying and distribution of this file, with or without modification, +" are permitted in any medium without royalty provided the copyright +" notice and this notice are preserved. + +#Mom +language mom +extension .mom .tmac + +startword . +color startword normal + +inword _.' +color inword normal + +other initialpunct +mostly normal + +backslash none + +color args like fixed +color braces like char +color brackets like underlined +color chars like emphasized +color decimals like number +color ellipsis normal +color escapes like keyword +color math like cursor +color misc like string +color operators like string +color parens like comment +color reg_string like math +color tmac_escapes like keyword +color single_slash like char + +font args DA DE EN ES FR IT NL NO PT SV +font args DEFAULT CHAPTER NAMED LETTER +font args TYPESET TYPEWRITE +font args FINAL DRAFT +font args BLOCK QUAD +font args LEFT RIGHT CENTER CENTRE JUSTIFY TOP BOTTOM L R C J +font args OFF QUIT END EXIT DONE NO ALL +font args PAGE NUMBER STAR +font args LETTER LEGAL EXECUTIVE LEDGER TABLOID QUARTO FOLIO +font args 10x14 A3 A4 A5 B4 B5 +font args SINGLESPACE +font args FACTOR +font args DASH BULLET ALPHA DIGIT USER +font args RGB CYM CMYK GRAY GREY +font args COND CONDX EXT EXTX SUP SUPX CONDSUP CONDSUPX EXTSUP EXTSUPX +font args BOLDER BOLDERX SLANT SLANTX +font args UP DOWN BCK FWD BU BP FU FP +font args ROM IT BD BDI PREV +font args ST +font args SUSPEND RESUME + +prefix { \{ \{\ +font braces { \{ \{\ +prefix [ ] +font brackets [ ] +prefix \(bu \(co \(ct \(de \(dg \(di \(em \(en \(mu \(pl \(rg \(sc \(sq \(lq \(rq +font chars \(bu \(co \(ct \(de \(dg \(di \(em \(en \(mu \(pl \(rg \(sc \(sq \(lq \(rq +prefix \(14 \(12 \(34 \(+- +font chars \(14 \(12 \(34 \(+- +prefix \fR \fB \fI \fP \f0 \f1 \f2 \f3 +font chars \fR \fB \fI \fP \f0 \f1 \f2 \f3 +prefix .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 +font decimals . .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 +prefix \/ \/. \/? \/! \/, \/; \/: +font escapes \/ \/. \/? \/! \/, \/; \/: +prefix \, \,. \,? \,! \,, \,; \,: +font escapes \, \,. \,? \,! \,, \,; \,: +prefix \~ \0 \: \| \^ \& \% \! +font escapes \~ \0 \: \| \^ \& \% \! +prefix \b \c \C \d \D \e \f \f( \h \l \L \p \r \s \s+ \s- \S \u \v \w +font escapes \b \c \C \d \D \e \f \f( \h \l \L \p \r \s \s+ \s- \S \u \v \w +prefix ... +font ellipsis ... +prefix + - * / = == < > <= >= ? % +font math + - * / = == < > <= >= ? % +prefix | +font misc | +prefix ! : & +font operators ! : & +prefix ( ) +font parens ( ) +prefix # * $ +font reg_string # * $ +prefix \n \* \[ +font single_slash \n \* \[ +prefix \\n \\* \\$ +font tmac_escapes \\n \\* \\$ + +comment \# +comment \" diff --git a/contrib/mom/examples/elvis_syntax.new b/contrib/mom/examples/elvis_syntax.new new file mode 100644 index 0000000..5dadecc --- /dev/null +++ b/contrib/mom/examples/elvis_syntax.new @@ -0,0 +1,116 @@ +" Copyright (C) 2004-2020 Free Software Foundation, Inc. +" +" Copying and distribution of this file, with or without modification, +" are permitted in any medium without royalty provided the copyright +" notice and this notice are preserved. + +" Steve Kirkendall has thoughtfully reworked elvis's syntax +" highlighting so that it now supports nroff constructs like \fBword +" and \(emword, with \fB and \(em being highlighted while "word" is +" not. +" +" There are some other enhancements as well, making it possible +" to have any word beginning with punctuation (i.e. groff +" requests) highlighted. I've decided to take advantage of these +" improvements, which apply to elvis-2.2h onwards, and write a new +" simplified set of syntax highlighting rules for mom. Just plug +" this file at the end of /etc/elvis/elvis.syn to use them. +" +" If you're using an older version of elvis, stick with the +" highlighting rules in the files elvis_syntax. + +#Mom +language mom +extension .mom .tmac + +startword . +color startword normal + +inword _.' +color inword normal + +other initialpunct +mostly normal + +backslash none + +color args like fixed +color braces like char +color brackets like underlined +color chars like emphasized +color decimals normal +color ellipsis normal +color escapes like keyword +color math like cursor +color misc like string +color operators like string +color parens like comment +color reg_string like math +color tmac_escapes like keyword +color single_slash like char + +font args DA DE EN ES FR IT NL NO PT SV +font args DEFAULT CHAPTER NAMED LETTER +font args TYPESET TYPEWRITE +font args FINAL DRAFT +font args BLOCK QUAD +font args LEFT RIGHT CENTER CENTRE JUSTIFY TOP BOTTOM L R C J +font args OFF QUIT END EXIT DONE NO ALL +font args PAGE NUMBER STAR LINE +font args LETTER LEGAL EXECUTIVE LEDGER TABLOID QUARTO FOLIO +font args 10x14 A3 A4 A5 B4 B5 +font args SINGLESPACE +font args FACTOR +font args DASH BULLET ALPHA DIGIT USER ROMAN roman alpha +font args SUSPEND RESUME +font args RGB CYM CMYK GRAY GREY +font args COND CONDX EXT EXTX SUP SUPX CONDSUP CONDSUPX EXTSUP EXTSUPX +font args BOLDER BOLDERX SLANT SLANTX +font args UP DOWN BCK FWD BU BP FU FP FN_MARK EN_MARK +font args ROM IT BD BDI PREV +font args ST +font args COVER DOC_COVER +font args COVERTITLE DOCTITLE TITLE CHAPTER CHAPTER_TITLE CHAPTER+TITLE SUBTITLE +font args AUTHOR DOCTYPE COPYRIGHT MISC +font args NULL BLANKPAGE NOBREAK + +prefix { \{ \} \{\ } +font braces { \{ \} \{\ } +prefix [ ] +font brackets [ ] +prefix \(bu \(co \(ct \(de \(dg \(di \(em \(en \(mu \(pl \(rg \(sc \(sq \(lq \(rq +font chars \(bu \(co \(ct \(de \(dg \(di \(em \(en \(mu \(pl \(rg \(sc \(sq \(lq \(rq +prefix \(14 \(12 \(34 \(+- +font chars \(14 \(12 \(34 \(+- +prefix \fR \fB \fI \fP \f0 \f1 \f2 \f3 +font chars \fR \fB \fI \fP \f0 \f1 \f2 \f3 +prefix .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 +font decimals . .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 +prefix \/ \/. \/? \/! \/, \/; \/: +font escapes \/ \/. \/? \/! \/, \/; \/: +prefix \, \,. \,? \,! \,, \,; \,: +font escapes \, \,. \,? \,! \,, \,; \,: +prefix \~ \0 \: \| \^ \& \% \! +font escapes \~ \0 \: \| \^ \& \% \! +prefix \b \c \C \d \D \e \f \f( \h \l \L \p \r \s \s+ \s- \S \u \v \w +font escapes \b \c \C \d \D \e \f \f( \h \l \L \p \r \s \s+ \s- \S \u \v \w +prefix ... +font ellipsis ... +prefix + - * / = == < > <= >= ? % +font math + - * / = == < > <= >= ? % +prefix | +font misc | +prefix ! : & +font operators ! : & +prefix ( ) +font parens ( ) +prefix # * $ +font reg_string # * $ +prefix \n \* +font single_slash \n \* +prefix \\n \\* \\$ +font tmac_escapes \\n \\* \\$ + +character \]' +comment \# +comment \" diff --git a/contrib/mom/examples/letter.mom b/contrib/mom/examples/letter.mom new file mode 100644 index 0000000..6e1a0c0 --- /dev/null +++ b/contrib/mom/examples/letter.mom @@ -0,0 +1,46 @@ +.\" -*- mode: text; coding: utf-8; -*- +\# +\# Copyright (C) 2004-2020 Free Software Foundation, Inc. +\# +\# Copying and distribution of this file, with or without modification, +\# are permitted in any medium without royalty provided the copyright +\# notice and this notice are preserved. +\# +.AUTHOR "Yannick P. Guique" +.DOCTYPE LETTER +.PRINTSTYLE TYPESET +.START +.DATE +August 25, 2013 +.TO +GUILLAUME BARRIÈRES +Minidoux Corporation +5000 Pannes Drive +Redmond, Virginia +USA +.FROM +Y.P. GUIQUE +022 Umask Road +St-Sauveur-en-dehors-de-la-mappe, QuĂŠbec +CANADA +.GREETING +Dear Mr. Barrières, +.PP +It has come to my attention that you have been lobbying the +US government to prohibit the use of open source software by +endeavouring to outlaw so-called "warranty free" applications. +.PP +I feel it is my duty to inform you that the success of your +operating system with its embedded web browser relies heavily +on open source programs and protocols, most notably TCP/IP. +.PP +Therefore, in the interests of your corporation's fiscal health, +I strongly advise that you withdraw support for any US +legislation that would cripple or render illegal open source +development. +.CLOSING +Sincerely, +.\" Local Variables: +.\" mode: nroff +.\" End: +.\" vim: filetype=groff: diff --git a/contrib/mom/examples/mom-pdf.mom b/contrib/mom/examples/mom-pdf.mom new file mode 100644 index 0000000..15cf6df --- /dev/null +++ b/contrib/mom/examples/mom-pdf.mom @@ -0,0 +1,620 @@ +.\" -*- mode: text; coding: utf-8; -*- +.\" +.\" Copyright (C) 2012-2020 Free Software Foundation, Inc. +.\" +.\" This file is part of mom, which is part of groff, a free software +.\" project. +.\" +.\" You can redistribute it and/or modify it under the terms of the +.\" GNU General Public License as published by the "Free Software + \" Foundation", version\~2. +.\" +.\" The license text is available on the internet at +.\" +.\" +.PAPER A4 +.\" Reference macros (metadata) +.TITLE "Producing PDFs" "with groff and mom" +.PDF_TITLE "\*[$TITLE] +.COPYRIGHT "20\*[BU3]1\*[BU2]5, 20\*[BU3]1\*[BU2]7 Free Software Foundation +.AUTHOR "Deri James" "\*[UP .5p]and" "Peter Schaffter" +.\" Cover author style +.COVER_AUTHOR_STYLE \ + LEAD 15 \ + SPACE -.5v +.\" Docheader author style +.AUTHOR_STYLE \ + LEAD 14 \ + SPACE -.75 +.ATTRIBUTE_STRING "" \" Don't print 'by' +.\" +.PDF_BOOKMARKS_OPEN 2 +.\" Formatting style, margins +.PRINTSTYLE TYPESET +.L_MARGIN 2.5c +.R_MARGIN 2.5c +.B_MARGIN 2.5c +.\" General defaults +.FAM H +.FT R +.PT_SIZE 10.5 +.AUTOLEAD 3 +.PARA_INDENT 0 \" No indent because we're spacing paragraphs. +.COVERTEXT +.SP .5v +.QUAD CENTER +.HY off +.IB 8P +.\" Copyright notice +This file is part of groff. +.SP .5v +Groff is free software. You can redistribute it +and\*[FU3]/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. +.SP .5v +You should have received a copy of the GNU +General Public License along with this program. +If not, see: +.SP .25v +.PDF_LINK_COLOR 0.0 0.3 0.9 +.PDF_WWW_LINK http://www.gnu.org/licenses/ +.IQ CLEAR +.HY +.COVERTEXT end +.\" Cover and page header +.COVER TITLE AUTHOR COPYRIGHT COVERTEXT +.HEADER_LEFT "James, Schaffter" +.\" +.COVER_LEAD +3.5 +.DOCHEADER_LEAD +3.5 +.\" Color for code snippets +.NEWCOLOUR dark-grey RGB #343434 +.\" Make QUOTE look like CODE +.QUOTE_STYLE \ + FAMILY C \ + FONT B \ + SIZE +1.5 \ + COLOR dark-grey \ + INDENT 9p +.\" +.CODE_STYLE \ + FONT B \ + SIZE 115 \ + COLOR dark-grey +.CONDENSE 87 \" Condense percentage used in COD +.\" +.HEADING_STYLE 1 \ + NUMBER \ + FONT B \ + SIZE +1 \ + BASELINE_ADJUST \n[.v]/5 +.HEADING_STYLE 2 \ + NUMBER \ + FONT I \ + SIZE +.25 \ + BASELINE_ADJUST \n[.v]/5 +.\" +.FOOTNOTE_SIZE -1 +.\" Character definitions for program names, opts, etc. +.char \[ghostscript] \*[BD]ghostscript\*[PREV] +.char \[groff] \*[BD]groff\*[PREV] +.char \[gropdf] \*[BD]gropdf\*[PREV] +.char \[grops] \*[BD]grops\*[PREV] +.char \[man] \*[BD]man\*[PREV] +.char \[-mom] \*[BD]\-mom\*[PREV] +.char \[mom] \*[BD]mom\*[PREV] +.char \[-mpdfmark] \*[BD]\-mpdfmark\*[PREV] +.char \[ms] \*[BD]ms\*[PREV] +.char \[pdfmom] \*[BD]pdfmom\*[PREV] +.char \[pdfroff] \*[BD]pdfroff\*[PREV] +.char \[-P-e] \*[BD]\-P\-e\*[PREV] +.char \[-P-p] \*[BD]\-P\-p\*[PREV] +.char \[ps2pdf] \*[BD]ps2pdf\*[PREV] +.char \[psselect] \*[BD]psselect\*[PREV] +.char \[-T] \*[BD]\-T\*[PREV] +.char \[-Tpdf] \*[BD]\-Tpdf\*[PREV] +.char \[-Tps] \*[BD]\-Tps\*[PREV] +.\" Strings for inline code +.ds cod \E*[CODE]\&\E*[COND] +.ds codx \E*[CONDX]\E*[CODE off]\& +.\" Paragraph spacing +.PARA_SPACE .3v +.\" Wrapper around QUOTE +.de COD +. QUOTE +. nop \*[COND]\\$*\*[CONDX] +. QUOTE OFF +.. +.\" Table of contents +.TOC_PADDING 2 +.SPACE_TOC_ITEMS +.AUTO_RELOCATE_TOC +.TOC_ENTRY_STYLE 2 FONT I +.TOC_LEAD 14.5 ADJUST +.TOC_PADDING 1 +.\" +.DOCHEADER_ADVANCE 5c \" Begin docheader this distance down from top of page +.\" +.NO_SHIM \" Use flex spacing +.START +.\" +.SP .5c +.HEADING 1 NAMED intro "Introduction" +.PP +.RW .12 +PDF documents are intended to be "electronic paper,\*[BU6]" and, as +such, take advantage of the digital medium in ways that PostScript +documents do not. Chief amongst these are clickable links that +point to named destinations, either within the documents themselves +.PDF_LINK internal PREFIX ( SUFFIX ) "internal links" +or to remote web pages +.PDF_LINK external PREFIX ( SUFFIX ), "external links" +and the generation of a clickable document outline that appears in +the Contents panel of most PDF viewers. +.PP +.RW .01 +Using \[groff] and \[mom] to produce PDF documents results in the +automatic generation of clickable document outlines (discussed +below, +.PDF_LINK outline SUFFIX ), + +and, if the \*[cod]TOC\*[codx] macro is included in the source file, +entries in the printable table of contents can be clicked on as well +when the document is viewed at the screen (see +.PDF_LINK toc SUFFIX ). + +.RW 0 +.HEADING 1 NAMED generating "Using groff to generate PDF files" +.PP +Groff provides more than one way to generate PDF documents from +files formatted with the \[mom] macros. One is to call \[groff] +directly, either with +.COD "groff [\-Tps] \-mom \-m pdfmark doc.mom | ps2pdf \- doc.pdf +which pipes output from the \[grops] PostScript driver through +\[ps2pdf], or +.COD "groff \-Tpdf \-mom doc.mom > doc.pdf +which uses the native PDF driver, \[gropdf]. Alternatively, one may +call the wrapper +.COD "pdfroff \-mom \-mpdfmark \-\-no-toc doc.mom > doc.pdf +A fourth, preferred method is to use +.PDF_LINK pdfmom SUFFIX , "\[pdfmom]" +which is strongly recommended since it implements the full range +of PDF features available in \[mom]. +.COD "pdfmom doc.mom > doc.pdf +One reason to prefer using the native PDF driver (via \[pdfmom] or +\[-Tpdf]) is that papersizes set within mom source files (see +.PDF_WWW_LINK https://www.schaffter.ca/mom/momdoc/typesetting.html#page-setup-intro SUFFIX ) \ + "paper and page setup macros" +do not require a corresponding \[-P-p] flag on the +command line. +.PP +There are other minor differences between the methods, discussed +.PDF_LINK pdf-diff SUFFIX . "here" +.RW 0 +.HEADING 1 NAMED links "Creating PDF links with mom" +.PP +Often, but not always, links in the body of a PDF document point +to headings elsewhere in the same document. Creating these links +is a simple process. First, identify the places to link to +("destinations"), then link to them from any place in the document. +.HEADING 2 NAMED naming "Creating destination points at headings" +.PP +The first step in creating links to a heading is to give the +heading a unique destination name. With mom, this is done by +adding \*[cod]NAMED\|\*[codx] to the HEADING macro, where +\*[cod]\*[codx] is a unique identifier for the heading. For +example, +.PDF_TARGET intro-ex +.COD "\&.HEADING 1 NAMED intro \[dq]Introduction\[dq]" +would, in addition to printing the head in the body of the document, +identify the introduction by the unique id, "intro"\*[BU6]. This +id, or name, can then be used to create links to the introduction +from any part of the document. +.PP +Furthermore, \*[cod]NAMED\|\*[codx] stores the text of the +heading for use later on when linking to it (see +.PDF_LINK internal SUFFIX ). + +If headings are being numbered, the heading number is prepended. +.HEADING 2 NAMED target "Creating destination points at arbitrary locations" +.PP +Any part of a document can be a link destination, not just headings. +For example, say you create a table that needs to be referred to +from other parts of the document. You'd identify the location of +the table by placing +.COD "\&.PDF_TARGET \[dq]\[dq]" +just above the table in the source file. As with +\*[cod]HEADING\*[codx], \*[cod]\*[codx] is any unique name. +\*[cod]\*[codx] is optional. \*[cod]\*[codx] can now be linked +to from anywhere in the document. +.SP 2.5p +.HEADING 2 NAMED internal "Creating internal links" +.PP +Internal links are clickable text areas that allow you to jump to +named destinations within a document. (See +.PDF_LINK external "here" +for a description of external links.) +.PP +Internal links are created with the macro \*[cod]PDF_LINK\*[codx], +which takes the form +.COD "\&.PDF_LINK [PREFIX ] [SUFFIX ] \ +\[dq]\[dq]" +where \*[cod]\*[codx] is a named destination point elsewhere in +the document (see +.PDF_LINK naming + +and +.PDF_LINK target SUFFIX ). + +.PP +\*[cod]PREFIX\|\*[codx] and \*[cod]SUFFIX\|\*[codx], both or +either of which are optional, are printed around the clickable area +but do not form part of the link itself. +.PP +\*[cod]\*[codx] is the text that should be clickable, +identifiable in the PDF document by the colour assigned to links +(see +.PDF_LINK colour SUFFIX ). + +.PDF_TARGET expando +.PP +If the hotlink text ends in \*[cod]\[dq]*\[dq]\*[codx]\*[BU9], +the asterisk is replaced by the text of the destination +point, assuming it's a heading. If the hotlink text ends in +\*[cod]\[dq]+\[dq]\*[codx]\*[BU9], the replacement text is surrounded +by quotes. +.PP +Using our +.PDF_LINK intro-ex SUFFIX , "HEADING example" +.RW .1 +above, the following invocation of \*[cod]PDF_LINK\*[codx] would +produce a click\%able link to the introduction: +.COD "\&.PDF_LINK intro PREFIX ( SUFFIX ). \[dq]see: +\[dq]" +.RW 0 +In the text, the link would look like this: +.PDF_LINK intro PREFIX ( SUFFIX ). "see: +" +.HEADING 2 NAMED external "Creating external links" +.PP +External links are clickable text areas whose destination is a +URL. Clicking on them causes a browser window to pop up with the +destination address. +.PP +The format of the macro to create external links is similar to the +one for creating internal links: +.COD "\&.PDF_WWW_LINK [PREFIX ] [SUFFIX ] [\[dq]\[dq]]" +\*[cod]\*[codx] is any valid URL, usually a web address; +\*[cod]PREFIX\|\*[codx] and \*[cod]SUFFIX\|\*[codx] have +exactly the same meaning, as does \*[cod]\*[codx], +which furthermore accepts the same expandos, \*[cod]\[dq]+\[dq]\*[codx] and +\*[cod]\[dq]*\[dq]\*[codx]. +.PP +.RW .1 +If no hotlink text is given, then \*[cod]\*[codx] is +used as the text. If hotlink text is given and ends in +\*[cod]\[dq]*\[dq]\*[codx]\*[BU9], the asterisk is replaced by the +URL. If it ends in \*[cod]\[dq]+\[dq]\*[codx]\*[BU9], the URL is +surrounded by quotes. As an example, +.RW 0 +.COD "\&.PDF_WWW_LINK https://www.schaffter.ca/mom/momdoc/toc.html +would open mom's online documentation at +.PDF_WWW_LINK https://www.schaffter.ca/mom/momdoc/toc.html SUFFIX "." +The same, with \*[cod]\[dq]here\[dq]\*[codx] supplied as +hotlink text, lets you click +.PDF_WWW_LINK https://www.schaffter.ca/mom/momdoc/toc.html "here" +instead. +.HEADING 2 NAMED colour "Assigning a colour to links" +.PP +The colour of links is set with +.COD "\&.PDF_LINK_COLOR | | | <#rrggbb> +where \*[cod]\*[codx] or \*[cod]\*[codx] are the names +of colours already initialized with +.PDF_WWW_LINK https://www.schaffter.ca/mom/momdoc/color.html#xcolor "XCOLOR" +or +.PDF_WWW_LINK https://www.schaffter.ca/mom/momdoc/color.html#newcolor SUFFIX . "NEWCOLOR" +If you prefer to define a new colour (using the RGB colour scheme), +enter it either as 3 numbers between +0.0 \*[UP 1p]\[->]\*[DOWN 1p] 1\*[BU4].0 +or as a 6 character hex string. Thus +.SP .5v +\*[FWD 6p]\*[cod].PDF_LINK_COLOR #ff0000\*[codx] +\ \*[SIZE -.5]and\*[SIZE]\ \" +\*[cod].PDF_LINK_COLOR 1.0 0 0\*[codx] +.SP .5v +both lead to mom using +.PDF_LINK_COLOR 1 0 0 +.PDF_LINK colour red +.PDF_LINK_COLOR +links. +.PP +The default colour can be restored by calling +\*[cod]PDF_LINK_COLOR\*[codx] with no parameter. +.FLOAT +.JUSTIFY +.BOX-NOTE 3P +\*[BD]Note:\*[PREV] +The decimal scheme for creating colours must be used if a file is to +be processed with +\[oq]\[groff]\~\[-Tps]\~\[-mpdfmark]\[cq], +\[oq]\[pdfroff]\[cq], or +\[oq]\[pdfmom]\~\[-Tps]\[cq]. +.IBQ +.FLOAT off +.SP .5v +.HEADING 1 NAMED outline "The PDF Outline" +.PP +Most PDF viewers provide a panel that displays a document's outline, +similar to a table of contents. Clicking on an entry navigates +directly to the appropriate place in the document. +.PP +Mom generates PDF outlines the same way she populates +her own table of contents: by intercepting calls to the +\*[cod]HEADING\*[codx] macro, as well as to the various title +and chapter macros used in namimg documents, and allocating each a +hierarchic level. +.PP +Covers, titles/chapters, and the table of contents are all +assigned to level 1\*[BU5]. Subsequent headings are assigned to +n\*[UP 1p]+\*[DOWN 1p]\*[BU4]1, where n is the level given to +\*[cod]HEADING\*[codx]. +.PP +.RW .22 +The PDF outline can sensibly recover from skipped or omitted heading +levels; the printed table of contents cannot. Users are therefore +advised to use headings in logical order, not for typographic +effects. +.RW 0 +.HEADING 2 NAMED open-close "Opening and closing levels +.PP +A level is said to be open if one or more levels beneath it is +visible in the PDF outline. Closed \%levels have at least one level +beneath them that is not visible unless the closed link is clicked. +It is common for only the first two levels to be open so the outline +doesn't look cluttered. +.PP +To establish which levels should be open by default when a document +loads, use +.COD "\&.PDF_BOOKMARKS_OPEN n +where \*[cod]n\*[codx] is a number specifying at which level all +subsequent ones should be closed. +.PP +If, at any point in the document, you specify +.COD "\&.PDF_BOOKMARKS_OPEN NO \e\[dq] or any other text argument +then all subsequent bookmarks will be closed until +\*[cod]PDF_BOOKMARKS_OPEN\*[codx] opens them again. +.HEADING 2 NAMED disabling "Suspending/disabling collection of outline entries +.PP +Suspending the collection of entries for the PDF outline is +accomplished with +.COD "\&.PDF_BOOKMARKS OFF +Mom's default is to collect entries, so if the command is placed at +the start of a document, it \%disables entry collection completely. +Elsewhere, it suspends collection until you re-enable it with +.COD "\&.PDF_BOOKMARKS \e\[dq] i.e. with no parameter +.SP -1 +.HEADING 2 NAMED pdf:title "The PDF window title" +.PP +While not strictly part of the PDF outline, the title of a document +can be displayed as the document viewer's window title. The macro +to accomplish this is +.COD "\&.PDF_TITLE\ \[dq]\[dq] +It can take any text, so the viewer window title need not be the +same as the document's title. +.FLOAT +.JUSTIFY +.BOX-NOTE 4P+8p +\*[BD]Note:\*[PREV] The macro, \*[cod]DOC_TITLE\*[codx], always +invokes \*[cod]PDF_TITLE\*[codx]. If this is not what you want, you +can remove the window title by issuing +.COD ".PDF_TITLE \[dq]\[dq] \e\[dq] ie. with a blank argument +.IBQ +.FLOAT off +\#.SP .5v +.HEADING 1 NAMED toc "Tables of Contents" +.RLD .5v +.HEADING 2 NAMED toc:gen "Generating a Table of Contents +.PP +.RW .1 +To generate a printable Table of Contents for any document, simply +insert the macro, \*[cod]TOC\*[codx], as the last line of the source +file. (Formatting of the printable Table of Contents is discussed in +detail in the +.PDF_WWW_LINK \ +https://www.schaffter.ca/mom/momdoc/tables-of-contents.html#top \ +SUFFIX ). "mom documentation" +When the file is processed and loaded in a viewer, entries in the +Table of Contents will be clickable links. +.RW 0 +.PP +Whichever link colour is active at the end of the document, prior to +\*[cod]TOC\*[codx], will be used for the \%Table of Contents +links. +.HEADING 2 NAMED toc:pos "Positioning the Table of Contents" +.PP +If \[groff]'s PostScript device (\[-Tps]) is used to process a mom +file, the Table of Contents is printed at the end of the document. +When this is not desirable, the PostScript output from \[groff] +must be processed with \[psselect] in order to place the TOC in the +preferred location. +.PP +When using mom and \[groff]'s native pdf device (via \[pdfmom] or +\[groff] \[-Tpdf]), positioning of the Table of Contents can be done +within the source file. +.PP +The command to control the placement of the TOC is +.COD "\&.AUTO_RELOCATE_TOC [] +where the optional \*[cod]\*[codx] can be one of these +keywords: +.LEFT +.IL 2P +.SP .25v +\*[SIZE -.7]TOP\*[FU2]\*[UP .5p]\c +.FOOTNOTE +\*[BD]Note:\*[PREV] Documents without a COVER or DOC_COVER require +the \*[cod]TOP\*[codx] argument. +.FOOTNOTE off +\*[IT]\*[SIZE +.2]\ +(ie. at the very start of the document)\*[SIZE -.2]\*[PREV] +BEFORE_DOCCOVER +AFTER_DOCCOVER +BEFORE_COVER +AFTER_COVER\*[SIZE +.7] +.SP .25v +.ILQ +.JUSTIFY +It is normally not necessary to supply a keyword, since +\*[cod]AUTO_RELOCATE_TOC\*[codx] places the TOC after the DOC_COVER, +if there is one, or the first COVER when no DOC_COVER is present. +In rare instances where it is desirable to place the TOC somewhere +else in the document, there are two low-level commands, +\*[cod].TOC_BEFORE_HERE\*[codx] +\ \*[SIZE -.5]and\*[SIZE]\ \" +\*[cod].TOC_AFTER_HERE\*[codx] +which place the TOC either before or after the current page. +.PP +These last two commands have a small catch: although the TOC will +appear where specified, the \%"Contents" entry in the PDF outline, +which observes a hierarchy of levels, will assign the TOC to +level\~\*[BU4]1\*[BU4], possibly disrupting the visual ordering of +levels in the outline. +.HEADING 1 NAMED simplify "pdfmom: Simplifying PDF output" +.PP +As explained in the section +.PDF_LINK generating SUFFIX , * +.RW .15 +there are two established methods +.RW 0 +for creating PDF files with \[groff]: the original method, ie. +passing the \[-Tps] and \[-mpdfmark] options to \[groff] (or using +\[pdfroff], which does this for you); or the newer \[-Tpdf], which +produces PDF files natively. +.HEADING 2 NAMED fwd:ref "The problem of forward references" +.PP +.EW .2 +Both methods encounter difficulties when dealing with forward +references; that is, when a link \*[IT]\%earlier\/\*[PREV] in a +document refers to a destination \*[IT]later\/\*[PREV] in the +document and the link text terminates +.EW 0 +with one of the expandos, +\*[cod]\[dq]*\[dq]\*[codx] or \*[cod]\[dq]+\[dq]\*[codx] +(explained +.PDF_LINK expando SUFFIX ). "here" +Mom doesn't know what text to put in the expando because it has not +yet been defined. This means that \[groff] must be run multiple +times to find the unknown text. +.PP +.EW .2 +The program \[pdfroff] exists to handle these multiple runs, but it +imposes some limitations on the PDF features available with \[mom]. +.EW 0 +.HEADING 2 NAMED pdfmom "pdfmom" +.PP +\[pdfmom] performs the same function as \[pdfroff], and is the +preferred, trouble-free way to generate PDF documents from a mom +source file. Like \[pdfroff], it is a frontend to \[groff] and +accepts all the same options (see \[man]\~\[groff]). +.PP +.EW .2 +Called as-is, \[pdfmom] accepts all the same options as \[groff], +and requires no additional flags. PDF generation is performed by +\[gropdf], \[groff]'s native PDF driver: +.EW 0 +.COD "pdfmom doc.mom [groff opts] > doc.pdf +If a \[-Tps] option is supplied, \[pdfmom] hands control over to +\[pdfroff], and both \[groff] and \[pdfroff] options may given. +The resulting PDF is produced from PostScript output fed into +\[ghostscript]. +.COD "pdfmom \-Tps [pdfroff opts [groff opts]] doc.mom > doc.pdf +For either invocation, it is not necessary to add \[-mom] or +\[-mpdfmark], as these are implied. +.PP +.RW .04 +If Encapsulated PostScript or plain PostScript images have been +embedded in a document with +.PDF_WWW_LINK https://www.schaffter.ca/mom/momdoc/images.html#pspic SUFFIX , \ + "PSPIC" +the \[-Tps] option must be used. In most other cases, \[pdfmom] +with no \[-T] flag is preferable. +.RW 0 +.HEADING 2 NAMED papersize "Setting papersize within a source file" +.PP +A significant convenience afforded by using \[pdfmom] (or \[groff] +with the \[-Tpdf] flag) is that papersizes or page dimensions set +within mom source files (see +.PDF_WWW_LINK https://www.schaffter.ca/mom/momdoc/typesetting.html#page-setup-intro \ + SUFFIX ) "paper and page setup macros" +do not require a corresponding \[-P-p] option on the +command line. It is even possible to create documents with +unequal-sized pages. +.HEADING 2 NAMED pdf-diff \ +"Differences between pdfmom and pdfroff" +.PP +Several features described in this manual are not available when +the \[-Tps] option is given to \[pdfmom], nor when using \[pdfroff] +or \[groff]\~\[-Tps]\~\[-mpdfmark]: +.SP .25v +.QUAD LEFT +.HYPHENATION off +.IB 16p +.LIST +.ITEM +.PDF_LINK toc:pos "Relocation of the Table of Contents" +is not supported. The TOC appears at the end of the document; +\[psselect] must be used to re-order pages. +.ITEM +If a link crosses a page boundary, it will stop being a clickable +hotspot on subsequent pages. +.ITEM +When establishing whether PDF outline levels are +.PDF_LINK open-close SUFFIX , "open or closed" +only the numerical parameter to \*[cod]PDF_BOOKMARKS_OPEN\*[codx] has +any effect. +.ITEM +.PDF_LINK colour "PDF_LINK_COLOR" +only accepts colour definitions in decimal notation. +.LIST OFF +.IQ +.HEADING 1 \ +"Comparison of \-Tps\*[FU4]/\*[FU2]\-mpdfmark with \-Tpdf\*[FU4]/\*[FU2]\-mom +.SP .25v +.IB +\[-Tps]\*[FU4]/\*[FU2]\[-mpdfmark] +.LIST +.SHIFT_LIST 1P+6p +.ITEM +does not support all the features described here +.ITEM +accepts images and graphics embedded with PSPIC +.LIST OFF +.IQ +.ALD .4v +.IB +\[-Tpdf]\*[FU4]/\*[FU2]\[-mom] +.LIST +.SHIFT_LIST 1P+6p +.ITEM +facilitates embedding fonts directly in the PDF file (if the +\[-P-e] flag is given on the command line) +.ITEM +sets papersize from within the source file, circumventing the need +for the papersize flag (\[-P-p]) on the command line +.ITEM +is not compatible with +.PDF_WWW_LINK \ + https://www.schaffter.ca/mom/momdoc/docprocessing.html#printstyle \ + "PRINTSTYLE TYPEWRITE" +underlining (e.g., of italics) +.ITEM +generally produces larger files; these can be reduced by piping +the output through \[ps2pdf]\*[B] +.sp -1.25v +.BOX OUTLINED black SHADED grey90 WEIGHT 1p INSET 6p +.JUSTIFY +\*[BD]Note:\*[PREV] Owing to a known bug, PDF files piped through +\[ps2pdf] lose some of their metadata, notably the window title set +with \*[cod]PDF_TITLE\*[codx]. +.BOX STOP +.SP -.25v +.LIST OFF +.TOC +.\" Local Variables: +.\" mode: nroff +.\" End: +.\" vim: filetype=groff: diff --git a/contrib/mom/examples/mom.vim b/contrib/mom/examples/mom.vim new file mode 100644 index 0000000..fe8debf --- /dev/null +++ b/contrib/mom/examples/mom.vim @@ -0,0 +1,140 @@ +" Copyright (C) 2012-2020 Free Software Foundation, Inc. +" +" Copying and distribution of this file, with or without modification, +" are permitted in any medium without royalty provided the copyright +" notice and this notice are preserved. + +" Vim syntax file +" Language: mom +" Maintainer: Peter Schaffter (peter@schaffter.ca) +" Last Change: So 06 Mär 2005 17:28:13 CET +" Filenames: *.mom +" URL: http://www.cvjb.de/comp/vim/mom.vim +" Note: Remove or overwrite troff syntax for *.mom-files with filetype/filedetect. +" Version: 0.1 +" +" Mom: Macro set for easy typesetting with troff/nroff/groff. + +" For version 5.x: Clear all syntax items +" For version 6.x: Quit when a syntax file was already loaded +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +" Mom is case sensitive +syn case match + +" Synchronization, I know it is a huge number, but normal texts can be +" _very_ long ;-) +syn sync lines=1000 + +" Characters allowed in keywords +if version >= 600 + setlocal iskeyword=@,#,$,%,48-57,.,@-@,_,\\,{,},192-255 +else + set iskeyword=@,#,$,%,48-57,.,@-@,_,\\,{,},192-255 +endif + +" mom/groff macros and requests (the initial dot or single-quote) +" +" Highlighting carries through to EOL; macro names, requests and +" arguments are contained +syn match startRequest /^\s*\(\.\|'\)\s*.*$/ contains=momMacro,groffCommentLine,groffRequest,momRegister,groffNoLineBreak,momInteger,groffUnit,momString,momSpecialParam,groffDelimiter,groffRegister,groffPreprocessor,groffBraces + +" mom macros +syn region momMacro start=/^\s*\(\.\|'\)\s*\zs[A-Z0-9_(){}\[\]]\+/ end=/\s\+\|$/ + +" mom registers and strings +syn match momRegister /\(\$\|#\)[A-Za-z][_0-9A-Za-z]*/ contains=momRegisterStart + +syn match momRegisterStart /#\|\$/ contained + +" mom comment region +syn region momCommentRegion matchgroup=startRequest start='\<\.\(COMMENT\)\|\(SILENT\)\>' end='\<\.\(COMMENT\s\+OFF\)\|\(SILENT\s\+OFF\)\>' skip='$' + +" groff requests +syn match groffRequest /^\s*\(\.\|'\)\s*\zs[a-z0-9]\+/ + +" groff comment region +syn region groffCommentLine start='\(\\!\)\|\(\\"\)\|\(\\#\)' end='$' contains=momTodo +syn region groffCommentRegion start="^\s*\.\s*ig" matchgroup=startRequest end="^\.\.$" contains=startRequest + +" Preprocessor requests +syn match groffPreprocessor /[^A-Z]\zs\(EQ\s*$\|EN\s*$\|GS\s*$\|GE\s*$\|GF\s*$\|PS\s*$\|PE\s*$\|R1\s*$\|R2\s*$\|TS\s*$\|TE\s*$\|TH\s*$\)/ contained +syn match groffPreprocessor /[^A-Z]\zs\(G1\s*$\|G2\s*$\|IS\s*$\|IE\s*$\|cstart\s*$\|cend\s*$\)/ contained + +" Preprocessor requests for refer +syn match groffPreprocessor /\(\[\s*$\|\]\s*$\)/ contained + +" Quoted strings +syn region momString matchgroup=startRequest start='"\zs' end='"\|$' contains=groffNoLineBreak,groffGreek,groffSpecialChar,momInteger,momFloatEN,momFloatDE,momBracketRegion,momBracketError,momSpecialMove contained + +" Special characters +syn match groffSpecialChar '\\\((\|\[\)[-+A-Za-z0-9*<>=~!\/]\+\]*' + +" Greek symbols +syn match groffGreek '\\(\*[A-Za-z]\+' + +" Hyphenation marks +syn match groffHyphenation '\\%' + +" Masking of line breaks +syn match groffNoLineBreak /\\\s*$/ contains=groffBraces + +" groff number and string register delimiters +syn region groffDelimiter start=/\\*\\\(n+*\|\*\)\((\|\[\)\= 508 || !exists("did_mom_syn_inits") + if version < 508 + let did_mom_syn_inits = 1 + command -nargs=+ HiLink hi link + else + command -nargs=+ HiLink hi def link + endif + +HiLink groffError Error +HiLink groffBraces darkmagenta +HiLink groffCommentLine darkcyan +HiLink groffCommentRegion cyan +HiLink groffDelimiter cyan +HiLink groffGreek cyan +HiLink groffHyphenation cyan +HiLink groffNoLineBreak cyan +HiLink groffOperators white +HiLink groffPreprocessor brown +HiLink groffRegister darkgreen +HiLink groffRequest magenta +HiLink groffSpecialChar darkcyan +HiLink groffUnit brown +HiLink momCommentRegion darkcyan +HiLink momMacro red +HiLink momRegister green +HiLink momRegisterStart magenta +HiLink momSpecialParam red +HiLink momString white +HiLink startRequest yellow + delcommand HiLink +endif + +let b:current_syntax = "mom" + +" vim:ts=8:sw=4:nocindent:smartindent: diff --git a/contrib/mom/examples/mon_premier_doc.mom b/contrib/mom/examples/mon_premier_doc.mom new file mode 100644 index 0000000..3497c06 --- /dev/null +++ b/contrib/mom/examples/mon_premier_doc.mom @@ -0,0 +1,140 @@ +.\" -*- mode: text; coding: utf-8; -*- +\# +\# Copyright (C) 2015-2020 Free Software Foundation, Inc. +\# +\# Copying and distribution of this file, with or without modification, +\# are permitted in any medium without royalty provided the copyright +\# notice and this notice are preserved. +\# +\# A very simple document with basic elements: headings, paragraphs, +\# lists, table of contents and clickable links. +\# +.TITLE "Mon Premier Document" +.AUTHOR "CicĂŠron" +. +.DOCTYPE DEFAULT +.PRINTSTYLE TYPESET +. +.PAPER A4 +.DOC_COVERTITLE "Mon Premier Document" +.DOC_COVER DOC_COVERTITLE AUTHOR +.COVER TITLE +.ATTRIBUTE_STRING "par" +.TOC_HEADER_STRING "Table des matières" +.AUTO_RELOCATE_TOC +.HEADING_STYLE 1 NUMBER +.HEADING_STYLE 2 NUMBER +.NO_SHIM +.START +\# +.HEADING 1 "Les diffĂŠrentes versions" +.PP +Voir ĂŠgalement le chapitre sur +.PDF_LINK evolution "les ĂŠvolutions" +possibles. +.HEADING 2 "La version originale" +.PP +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non +risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, +ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula +massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci +nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl +sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, +consequat in, pretium a, enim. Pellentesque congue. Ut in risus +volutpat libero pharetra tempor. Cras vestibulum bibendum augue. +Praesent egestas leo in pede. Praesent blandit odio eu enim. +Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum +primis in faucibus orci luctus et ultrices posuere cubilia Curae; +Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. +Maecenas adipiscing ante non diam sodales hendrerit. +.PP +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non +risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, +ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula +massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci +nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl +sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, +consequat in, pretium a, enim. Pellentesque congue. Ut in risus +volutpat libero pharetra tempor. Cras vestibulum bibendum augue. +Praesent egestas leo in pede. Praesent blandit odio eu enim. +Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum +primis in faucibus orci luctus et ultrices posuere cubilia Curae; +Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. +Maecenas adipiscing ante non diam sodales hendrerit. +.PP +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non +risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, +ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula +massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci +nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl +sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, +consequat in, pretium a, enim. Pellentesque congue. Ut in risus +volutpat libero pharetra tempor. Cras vestibulum bibendum augue. +Praesent egestas leo in pede. Praesent blandit odio eu enim. +Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum +primis in faucibus orci luctus et ultrices posuere cubilia Curae; +Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. +\# +.HEADING 2 "La version moderne" +.PP +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non +risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, +ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula +massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci +nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl +sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, +consequat in, pretium a, enim. Pellentesque congue. Ut in risus +volutpat libero pharetra tempor. Cras vestibulum bibendum augue. +Praesent egestas leo in pede. Praesent blandit odio eu enim. +Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum +primis in faucibus orci luctus et ultrices posuere cubilia Curae; +Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. +Maecenas adipiscing ante non diam sodales hendrerit. +.PP +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non +risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, +ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula +massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci +nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl +sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, +consequat in, pretium a, enim. Pellentesque congue. Ut in risus +volutpat libero pharetra tempor. Cras vestibulum bibendum augue. +Praesent egestas leo in pede. Praesent blandit odio eu enim. +Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum +primis in faucibus orci luctus et ultrices posuere cubilia Curae; +Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. +Maecenas adipiscing ante non diam sodales hendrerit. +\# +.HEADING 1 NAMED evolution "Les ĂŠvolutions du Lorem" +.PP +Trois axes de progressions sont envisageables: +.LIST +.SHIFT_LIST 3m +.ITEM +Lorem ipsum dolor sit amet. +.ITEM +Consectetur adipiscing elit. +.ITEM +.PDF_TARGET sed_non_risus +Sed non risus. +.LIST OFF +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non +risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, +ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula +massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci +nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl +sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, +consequat in, pretium a, enim. Pellentesque congue. Ut in risus +volutpat libero pharetra tempor. Cras vestibulum bibendum augue. +Praesent egestas leo in pede. Praesent blandit odio eu enim. +Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum +primis in faucibus orci luctus et ultrices posuere cubilia Curae; +Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. +Maecenas adipiscing ante non diam sodales hendrerit. +\# +.TOC_RV_SWITCH +.TOC +.\" Local Variables: +.\" mode: nroff +.\" End: +.\" vim: filetype=groff: diff --git a/contrib/mom/examples/penguin.pdf b/contrib/mom/examples/penguin.pdf new file mode 100644 index 0000000..5e969ea --- /dev/null +++ b/contrib/mom/examples/penguin.pdf @@ -0,0 +1,148 @@ +%PDF-1.4 +1 0 obj +<< +/Pages 2 0 R +/Type /Catalog +>> +endobj +2 0 obj +<< +/Type /Pages +/Kids [ 3 0 R ] +/Count 1 +>> +endobj +3 0 obj +<< +/Type /Page +/Parent 2 0 R +/Resources << +/XObject << /Im0 8 0 R >> +/ProcSet 6 0 R >> +/MediaBox [0 0 81 96] +/CropBox [0 0 81 96] +/Contents 4 0 R +/Thumb 11 0 R +>> +endobj +4 0 obj +<< +/Length 5 0 R +>> +stream +q +81 0 0 96 0 0 cm +/Im0 Do +Q +endstream +endobj +5 0 obj +29 +endobj +6 0 obj +[ /PDF /Text /ImageC ] +endobj +7 0 obj +<< +>> +endobj +8 0 obj +<< +/Type /XObject +/Subtype /Image +/Name /Im0 +/Filter [ /RunLengthDecode ] +/Width 81 +/Height 96 +/ColorSpace 10 0 R +/BitsPerComponent 8 +/SMask 15 0 R +/Length 9 0 R +>> +stream +ő…ě„ţ…Ú„ű…ř„ű…ű†ţ‚ţzţkűeţXűfţmţzţ~ű†›…ţ„ţ…ţ„ţ…ě„ţ…Ń„ő…ţ€ţpţ\ţQřIţGűJţMţPţXţfţv›…ř„ţ…ě„ţ…Ń„ţ†ţ‡ţ„ţwţ]ţPűJţIűJţIřKţHţIţKţNţwţƒ•…ě„ţ…ř„ţ…ŕ„ţ…ţ†ţ…ţnţKţNţKţJďIţHřIţHţJţPţgţ€ţ„ţ‡¤…ţ„ţ…ě„ţ…Ô„ţ…ţ„ţ†ţOţNţHţJűIţJňHűIţQţiţ_ţHţIţXţ{Ą…ţ„ţ…ě„ţ…ׄű…ţţQţGŕJţIţOţqţ”ţŚţ…ţgţJţHţRţ}ţ…ţ†°…ű„ţ…ě„ţ…Ú„ţ…ţ„ţ†ţmţNţKŕJţHţMţrţ™ţ¨ţţxţ[ţJţMţcţƒţ†ł…ř„ţ…ě„ţ…Ú„ţ…ţ†ţţXţHţKÝJţTţvţ–ţ›ţ€ţwţbţJţKţOţsţ…ţ‡ł…ű„ţ…ě„ţ…Ú„ţ…ţ†ţsţJţHţIăJţKţIţSţoţ‚ţ{ţYţWţQţKţMţHţZţƒţ‡ł…ţ„ű…ě„ţ…Ú„ű…ţ_ţGűIăJţIţJţNţ[ţ`ţOţMţKţIţMţJţIţKţtł…ś„ű…ţRţIţHţIţMćJţIţKűJţNţKţNţIţMţKţIţKţJţ]ţ†ţ„­…ě„ţ…Ú„ţ…ţƒţJţKűIţKţIăJţKűJţIţJřKţIţJţIţOţ€Ş…ě„ţ…ׄţvţMűJţHţNţRţMćJţKţOţRţSűMűKřIţMţsţƒ­…ě„ţ…ׄţuţKţGţKţQţYţpţmţPűKűJřKţGţHţIţZţ~ţNţIűKţJţHţIţKţoţ„­…ě„ű…ř„ţ…é„ţ…ţuţMűHţœţŽţ‘ţ[ţsţ`ţMřJţjţ™ţŽţ¸ţžţĂţŸţnţXřKţJţKţNţ\Ş…ř„ţ…ř„ű…ű„ţ…ř„ţ…ň„ţ…ţtţMţGţ_ţĂţÔţÇţŸţZţXţKűJţeţ˘ţşţĂţĚţŇţÚţĘţPţYűKţJţHţIţJţXŞ…ő„ţ…ű„ţ…Ú„ţ…ţsţMţGţƒţÚţéţćţÖţ–ţJţKűJţ—ţĚţěţ÷űůţőţáţlţJűKţIţHűIţPŞ…ě„ţ…Ú„ţ…ţsűMţŞţâţĐţňţţââáţWţIűJţĹţůţýââáţ•ţ˜ţÚűüűţţGűKţJţIűHţOŞ…ě„ţ…é„ţ…ő„ţ…ţtţIţXţŇţ`ţ„ţšţďţűţsţVţMţOţŇţüţîţfţXţœ‘’‘ţ×ţŇţTűKţJţHţIţHţMŞ…ě„ţ…Ú„ţ…ţsţJţ]ţÝţHţ„ţ–ţ´ţüţˆţfţvţxţÓţüţŹţNţJţoţĄ‘’‘ţěţgűKţJűIţHţMţ„š…ł„ţzţKţ\ţÝţOţ\‘’‘ţˆţúţ‚ţZţ]ţjŔÁŔţřţŽţFţMţVţnţ{ţńţhřJřIţKţ„­…ě„ţ…ě„ű…ď„ţSţWţÖţMţNţiţzţŘţyţţ‚ţţ”ţîţţKűJţKţnţďţkţIţJţIţJţIţMţHţ†­…ě„ţ…Ô„ţRţOţÄţWţKţRţ‚ţľţÎţÓţŃţÍţżţÍţ­ţJţMţKţOţžţăţ^řIţJřIŞ…ě„ţ…ő„ţ…ă„ţSţHţnţëţ¨ţ¸ţÍţ×řŘţÜţßţăţáţÝţĐţˇţĐţęţvűHţIţJűIţJţFŞ…ě„ţ…Ô„ţSţFţOţłţˇţĆţÔřŘţŰţŕţćţčţćţĺââáţŢţ×ţÎţ|ţPňIţJţGŞ…ő„ţ…ű„ţ…ď„ţ…é„ţRţGţfţłţÁţÍţŐűŘţÚţÝââáţčţçţćřĺţćţăţÂţhűJűIţJţMţHŞ…ě„ţ…ő„ţ…ă„ţ]ţTţ•ţşţÉţŇűŘţŮţÜţßââáţčţćőĺţÚţżţĚţqţMţKţIţJţMţIţMţ„­…ě„ű…Ú„ţ…ţeţ^ţĽţŔţÍţŐűŘţÚţÝţáţĺţćřĺââáţĘţˇţźţťţbţKţMţJţIűJţNţ~ţ…ţ†ł…ř„ţ…ř„ű…ď„ţ…ű„ţ…ř„ţ…ţgţYţŸţĆţÎţŘţŮţÚţÜţŢţâţćţĺţäţăţŘţşţšţÄţÇţšţ]ţMţKţIţJţGţIţPţlţ„ţ‡ł…ő„ţ…ű„ţ…Ô„ţcţKţoţźţÓţŮűÚţŢţáţäţăţáţÚţžţ°ţżţĹűÇţ™ţQţJţKţţ‡ţXţBţIţYţ„ţ†ł…ě„ţ…Ô„ţbţNţWţ˜ţ˛ţĐţÚţŢţŕţáţŕţÚţśţŚţ˛ţÁţÄţÇţÄţťţ˜ţSűHţvţ¨ţŸţ‚ţRţMţ|ţ†ł…ě„ţ…ţ„ţ…ď„ţ…ő„ţ…ţ†ţgţMţ[ţËţ˛ţĄţ¨ţÁţĚţĆţÂŔÁŔţžţ˝ţťţ´ţšţĘţŇţŘţÎţ‰ţJţKţMţqŠŞŠţŞţ™ţIţNţxł…ě„ű…ű„ţ…ě„ű…ű„ţZţHţiţÍţËţąţŸţŽţżţÁţŔţ˝ţ˛ţ°ţłŔÁŔűÍţĐţÜţÝţşţRţJţKţQţŒţ›ţmDEDţIţZţƒţ‡ś…ď„ű…ć„ţ…ţ†ű…ţvţPţMţ`ţĐţÍţĚţśţĄţ˘ţ§ţŠţŚţ¤ţśţÇűÍţÓţçţ÷ţüţĺţţKţMţJţIţSţMţJţIţOţtţ‡ţ†ź…ě„ţ…é„ţ…ţ„ţ…ţ„ţ…ţƒţWţKţIţ_ţáţŇűÍţČţśűŤţ­ţÇţĚűÍţ×ţéţúűţűüűţËţWňKţJţIţNţ^ţƒţ„ź…ď„ű…ă„ţ…ţƒţ„ţnţNţKţIţ ţěţŘűÎţÍţÎňÍţŇţÝţę÷ř÷őţţűţ…ţPňKţJţIţTţmű‡ż…ě„ţ…ŕ„ţ…ţzţcţXţFţkţćţůţęţŃţÍűÎţÍţÎţÍţĎţŘţäţńţůřţţýţţţýţŐţ\ţKţNţHţKřJţOţ\ţ~ű…ţ„Ĺ…ě„ţ…ŕ„ţ€ţ]ţgţTţQţżţůţţţůţÝďÍţÝţě÷ř÷ţýňţţýţüţůţ•űNűKţIţKţIţJţKţ`ţ„ż…ő„ţ…ţ„ű…ć„ţ…ţ„ţZűJţFţ†ţ÷ţţţüţýţđţŘţĐřÍţ×ţöűüűřţţýřţţýţţţýţŐţQţIţJţKűIţJţIţKţMţsţ…ţ„Ĺ…ő„ţ…ű„ţ…ă„ţmţOţPţMţWţŮţýţţţýţţţý÷ř÷ţëţáţăţëţôřýűţţýďţţřţ|ţGţIţKőIűJţZţ}΅˄ř…ţzűKţIţ^ţŰűüűţýňţţüűüűţýűţňýěţţüţŇűKűJţIřJţIţMţOţeő…ţ„ř…ő„ţ…ţ„ţ…ţ„ţ…ţ„ű…ě„ţ…ř„ű…ţ„ţˆţ†ţ€ţSţJţHţMţţěţűű˙őţţýţüţýűţţýűţţýěţţýţúţčţ_ţMţKőJűKţIţJţKţ„ţ†Ë…ě„ţ…ř„ű…ţ„ţ…ţţ_ţKţJţFţXţ°ţčţúţţţ˙űýűţţýűúţýďţţýűţţýţüţ÷űóţďţxţPěKţIţHţIţjхţ„ű…ě„ţ…ő„ţ…ű„ţfţPţKţJţFţ\ţ´ţŘţóţűţüţţţýţű÷ř÷ţôţđţďţöţúűüűüűţýűüűţúţů÷ř÷ţóţďţéţâţćţëţ™ţYţKţJţKţJţIűJţKţIţJţPţo˅ě„ű…ř„ţ…ţ„ţuűNřJţnţ¸ţĹţŮţěţńűű÷ř÷ţńţéţçţëţěţőýűüűűüűţůţňţčââáţÜűŘţÖţŇţÓţŕţĐţdűJţGţMţIţNţKţJűIţNţOţv΅ě„ţ…ř„ű…ţţ\ţNţHűJţWţ‚ţťţÂţŐţäţďţüţýţţţýţńţę÷ř÷ţüőţţýţůţńţéţÝţÔűŇűŃţŇţĺţĹţVţOţwţ`ţJţIţKűJţIţHţMţ]ţ‚Ń…ő„ň…ű„ű…ţsţOţJűKţJţ]ţţÇţÜţďţůţţţýţüţţţýţňţôřýűüţţűýţţţüţúţíţĺţÜţŐţŇţŃţŘţňŠŞŠţCţhţ‚ţrţXţMţNţIţKűJţOţu݅ř„ţ…ř„ţ…ř„ţ…ř„ţ†ţƒţ]ţKţNţIţYţMţrţžţăţôţüűýţţřý÷ř÷÷ř÷ţüţýţüňýűüţţţýţü÷ř÷ţîţáţ×ţŇţŕţďţKűNţkţ…ţ]ţKţNţKűJţMţdű†×…ő„ţ…ű„ţ…ř„ţ†ţţTţOţHţqţsţQţĄţć÷ř÷ţýţţőýţüţýűüűűüűýţüţýţţőýţţűýţüţýţřţëţÜţÓţéţQţJţNţIţ_ţ†ţSDEDţOţKţJţIţRţ~ţ…ţ†ŕ…ţ„ţ…ě„ţ…ř„ţ†ţjűMţsţ_ţKţ ţüţţţüţýţţňýűüţţţüţţţýţüřýţüűýűţőýţţţýţńţÜţĎţNţHţ`ţnţcţwţkţJţKţJţFţMţQţ‚Ý…ţ„ţ…ě„ţ…ř„ţƒţZţPţYţ‚ţGţHţîřţţüňýţüţýţţřýţüţýűüűýţţţýţţňýţţţýţţűôţkţPţqţŠţƒţgţ€ţSţKţJţKţJţNţvׅű„ţ…ő„ţ…ţ„ţ†ţ…ţwţPţMţ}ţeţGţNţüőýţüűýţţűýűüţýţüţýţüţýţţěýţüűýţţţýţţţüţýţţţŚţWţxţţ†ţeţlţtţMţIţJţIţKţ`ţ„Ú…ě„ţ…ţ„ţ‡ţ„ţdţJţWţ}ţIţJţműüűţýţüţýţüţýţüřýţüţúűüűţüřýţţţüţýţţűýţţűýţüţţţýţüőýţţţŃţbţqţwţiţTţQţ‹ţKţNţIţKţNţTţڅţ„ţ…ň„ř…ţţYţHţoţfţBţOţŠţüćýţűţďňüţýţüţţűýţüőýţüţţűýűţűýţěţYţNţPűKţGţqţIţNţHűIţKţtţ„Ý…ě„ţ…ţ„ţ…ţvţMţKţƒţPţCţdââáţýűüűýţüűýţţţüţ÷ţíűüűţýţţűýţüţýţüőýţüěýűüţýűüűţuţMűJţKţGţ]ţGţNřIţKţcڅě„ű…ţ„ţ`ţKţeţtţKţHţœţúţüţýţüěýţőţńţýţţřýţţţýţüďýűţőýţţřýţ–ţHűKţIţJţPţRűHţIţHţJţRţ‚ă…ţ„ţ…ě„ű…ţyűMţ{ţWţKţQţĐűüűţűýţţţüřýűńţüéýűüőýűüűőýţüűýţţţ˛ţMőKţNţGţHţKţJţIţKţPţ{é…ř„ţ…ř„ţ…ř„ţ…ţ„ţOţNţ\ţsţGţKţ”ţüţýţţţüţţőýţüţýţüţëţďţüţýţţőýţüţţřýţţřýţţřýţüűýţţţÉţJűKţJţHţTţHţFţIţJţHţJţMţgڅő„ű…ţ†ţ€ţJţGţfţoţHţIţšűýűţřýţüţýţţűüţëţďţűűüţýűüűýţüţţűýţüřýţţőýţüűýţŘţMűKţIţMţ`ţIţGţHűIţHţMţbé…ű„ű…ď„ţ†ţ„ţlţKţIţeţsţIţYţ×ţýţüőýűţűýţţűüűţčţîűüűűüţýţţćýűüţýţüţţűýţţűýţÝţSřKţJţmţIţJţIţHűJţIţQ݅ő„ţ…ţ„ţ…ţţRţMţFţiţ{ţKţYţŢţţţüňýţüţýţţţýűüűţçţîűüţýţţűýţüőýţüţýţüřýűüţţţýţüţýţţââáţRűKţMţKţyţIűJţIţHţKţJţPă…ţ„ţ…ě„ţhţMţKţQţrţ€ţIţ^ţçňýţüţţőýţűţçţđţüőýűüţýţţűýţţţüřýţüţýűüţţřýţäţSřKţIţwţIţJřIűJţOڅň„ţ…ţbţOţNţbţ‰ţ‘ţKţnţîţýűţřüűýţüűüűţýţúţčţňűüÝýţüţţţýţüţýţţűýţüţţţĺţTřKţWţrűKűJřIţO݅ď„ţţXţIţHţXţ~ţ˜ţOţ|ţńţýţţřýţüňýţůţčţňţýţüűýűţţýţüţţţýřţřýţţţüűýţüţýţüţţţăţVűKţHţmţXűKţJţHřIţQ݅ű„ţ…ř„ţ‚ţRűJţIţWţ…ţZţ|ţóřýţüűýţüřýţüţúţčţôőýţüćýţüďýţüţţţýţÖţPţHţJţRţ{ţKţNţJţKřJţKţS݅ď„ţţVűIűMţ[ţuţţňţýţüćýţúţčţôţýţüţýţţţýűţňýűüăýţĹţKţPţmţ{ţpţWţsţgţXţPţJţMţJţdă…ţ„ţ…ű„ű…ţ„ţ…ţ„ţ‡ţ˛ţÝţŢţŇţŽţKţcţžţűţýţţřýţüţţřýţúţčţöţüűýţţďýőüţýţüňýűüţřţ|ţiţQţKűJţIţKűJţsţŸţxţWţzţ…ţ†ă…ű„ţ…ţ„ţ†ţ„ţ†ţŤţÍřÝţÖ‘’‘ţPţhţ¸÷ř÷ţüţýţüţţűüţýţüţýţúţçţöţýţüőýţüűýűţéýţüţřţÝţÜţŰţŹţlţIţJţIřKţJţMţpţ‰ţtţZţ~݅ţ„ţ…ű„ţ†ţ…ţšţżţŇőÝţÖţ’ţPţ`ţąţüřýţüőýţřţéţ÷ţýţţűüéýţţřýţüřýţăţŘţäţăţ×ţnţOţJţIřKţJţOţxţqţdţŹţ›ű†ď…ř„ű…ř„ţ…ţ‰ţ˛ţĹţŇňÝţŃţ€ţJţZţîţýţüţýţţţýűüţýţúţçţóţüţýţüřýţüűýţüţýţüřýţüőýţÝţŇţßââáţÇţcţHţMţIřKţJţRţbţQţ‰ţŘââáţ†ţ‡ď…ţ„ţ…ţ„ţ†ű…ţ„ţƒţ‘ţ­ŔÁŔţĚţ×ďÝţĂţgţKţ†ţŢűüűýűţţüűüűţďţńţýţüţţűýűţňýţüţýţüţýţţřýţßţĐţÝţÚţ¸ţdţJţIţJřKűJţFţfţÇţÝţßţ†ţ„ď…ţ„ţƒţŠţžţšţˇţ´ţ˛ţśţÁţÉţÓţÚďÝţŰţ°ţVţQţnţÍţůűýţţţüţýţţţüţűţýţţţýţüűýţüőýţüűýţţűýűüţúţŕţĎţŰţÓţˇţoţJţKţHřKűJţRţ§ţŘţÚţÝţ†ţƒď…ţ†ţŠţŻţŔţÍţËűÇţÉţĎţÔţÚéÝţŐţţGţMţXţŽţöţüűýţţňýţüÝýţüţýţüţíţÜţŇţĎţŘţÎţźţ‹ţXţMţFűHţGţKţYţţËţÖţŘţÚţ‰ţ„ď…ţ†ţœţžţĘţ×ţÖţÓţŇţÖţÚţŰăÝţÄţHţKţJţTţ™ţëţţűýţüřýűţţüőýţüűýţţţýűüţţţýţňţ×ţŇţÎţÍţŐţÍţźŠŞŠţ„ţXţQţOţIţSţtţ›ţŔţÎţÖţŘţŰţˆé…ţŽţĹţŇÔÝűÜţÝţxţHţKţHţCţPţjţËţüűýţüňýţüţýţţőýűüűýţüţćţÓţŇţÉţĆţÔţŃţÇţžţˇţ´ţąţ°ţąţśţżţËţÖţÚřÝţ˝ţŠţ„ţ†ő…ţ„ţŁţÄţŃŃÝţÜţÝţľţXţIţHţMţJţHţeűýřţňýűţűýţţţýţţţüűýţüţćűŇţĹţÁűÔţÍţĆţÂţżţžű˝ţÄţĚţŐňÝţŘţŹě…ţžţÂţÎËÝţÓţţKţFţJűGţIţóőýţţăýţţţýţüţýţţţěţŐţÓŔÁŔţźţÓţŐţŇţÍţČţÇřĆţÎţÓţÚňÝţÚţŇţ ň…ţ„ţţŔţĚţÜËÝţĂţjţJřIţGţŕňýţüţýţüűýţţőýţüűýţţţüţňţŮţŇţťţšţÓţŮţŘţŐţĐţÎűÍţÎţŇţŘţŰďÝţÚţÍţĄţ„ţ…ţ†ű…‘’‘ţ˝ţÉţÜËÝţŘţ¨ţQţHţIţKţIţÚřýţüţýţüţýţţţýţüňýţüţýţüűýţöţÜţÂţšţšţÓţŮţŰţÚţ×ţŐţÓţŇţÔţŘţÚěÝţÜţŮţŐŠŞŠţ‰ţ†ű…ţţťţČţÜÎÝţÜţÝţĐţűJţHţJţđţţřýţüňýţüţýţüűýţüűýţüţýţőţĎţzţ—ţšţÓţÚűÜűŰţŮűÚţŰţÜŕÝţĹţšű…ţŽţşţÇţÜËÝţÜţÝţżţgţRţXţŽřýţüűýűţűýţüřýűţřýţüţýţ×ţpţVţ–ţşţÔţÚţŰĹÝţŘţ´ţ…ţţźţÇţÜËÝűÜţŘŠŞŠţśţăţúňýűüőýţţőýţüűýţúţÍţeţJţYţ›ţšţÔţÚţÜĹÝţŰţŃţƒţ–ţźţÇţŰţÜÎÝţÜűÚţËţłţ÷űüűţüűýţüřýűüéýţüţřţłţWţHţFţ`ţœţšţŐţŰĹÝţÜţŘţÍţ†ţ­ţźţĚÂÝţŘţŮţČţŚţÚűüéýţüňýţóţ^ţKţHţMţIţHţqţšţśţÖţŰËÝţÚţŃţČţľţ‰ţ“ţľţĂţŐţÜĹÝţŘţÔţËţŻţ’űüűţüřýţüřýţüőýţóţÁţnţJţKţJţGţHţIţwţšţľţÖţÜÔÝţÜţÚţÖţÍţÂţĽţ‹ţ„ţĽţźţËţ×ţÜĹÝţŮţŃţÉţľţ•ţœţÚţóţůţüţýţüűýűüűţöţěţĐţ¤ţmţPţGňKţNţ~ţţśţŐţŰÔÝţŇţĚţÂţ˛ţ’ţ…ű†ţłţ˝ţÉţŇűŰţÜţÝţÜŃÝţÚţŇţČţ¸ţŸţKţNţoţ‘ţ¤ţśţźţ°ţŠţţqţ]ţNţKţJűHőKţJţTţƒţŸţśţÔţŰăÝţŰţÚţŰţÚţŇţžţŞ‘’‘ţ†ő…ţ˛ţşţÄţËţŐţ×űŘţŮţŰţÝţÜÚÝţŮţŇţČţśţ ţYţHţIţHűNţJţIţGţFDEDţJţHţKűGţKţJţIűJţHţYţˆţĄţľţÓţŰćÝţŮţÖţÔţŃţÉţżţŒţ„ř…ţ†ű…ţŞţ´ţšţ˝ţČţËţĚţÎţĐţŃţÔţÖţŘţÚţŰűÜěÝţÜţŘţÎţĂţ˛ţţhřIţJÚIűJűIţYţ‰ţ ţ˛ţÎţŘďÝţŰţÚţŐţĐţËţÇţżţŤţ’ţ„ě…ţţ˘ţŠţ­ţ˛ţśţşţ˝ţŔţĂţÄţČţĚţŃţÓţ×ţŮţŰďÝţÚţŇţÇţ¸ţŠţœţlňJţIăJţHţIřJţ\ţ‰ţœţ­ţÉţÓţŮţŰűÜűŰţŮţŇţËţĹţŔţľţœţ†ř„ď…ţ„ţ…ţˆţţžţ˘ţ¨ţŹţŻűłţľţ¸ţżţĂţÇţÍţŇţ×ţŘţÚţŰűÚţŐţËţžţŽţ ţ—ţkţHţJţHţIďKţMňKţHţGţHţJţIţ^ţ†ţ—ţ§ţÂţËţÓţŘţŮţÚţŮţ×ţŇţÇţ˝ţłţŞţŽţ…ţ„ŕ…ţ†ű…ţ‡ţţ—ţţĄűĽţ§ţŤţŻţłţşŔÁŔţĆţĘţÎţŇţÔţĎţÇţ˝ţ˛ţ¤ţ˜ţţ`ţMţQűRţ]ţhćkţjţ_űWţTţQţ_ţƒţ”ţĄţšţĂţĚţĐűŇţŃţĘţĹţˇţŤţœţˆţ„Ú…ď„ű…ű„ţ…ţ‰ţŽţţ”ţ›ţŸţ˘ţŚţŠţŤţŠţŁţœţ•ţ‘ţŒţ…ţwţƒţ…ţ„ř…ď„ě…ű„ţƒţ€ţ‰ţ”ţ¨ţŤţ­ţ°űąţŻţŤţ§ţţ†ű…ű„×…ě„ţ…ţ„ţƒű„ţ…ţ‰ţţ“ţ˜ű™ţ˜ţ•ţ’ţţŠţ‚ţţ…Ý„ć…ţ„ţƒţ‚ţŒţžţ˘ţŁřŚţ¤ţŸţ–ř„Î…ě„ţ…ř„ű†ű…ţ†ţˆţ‰ţţţŽţŒţ‡ţţ€ű…Ý„ć…ţ„ţ…ţţ‚ţţ”ţ—ţšţ™ţ˜ţ•ţŒţ‡ţ„ţ…ţ„Î…ě„ţ…ř„ď…ţƒţ†ţƒű‚ţ„ţƒř…ď„ţ…ň„Ý…ţ„ű‚ţ…ţˆţ†ű…ţ„ţ…ţ„Ô…€ +endstream +endobj +9 0 obj +7826 +endobj +10 0 obj +/DeviceRGB +endobj +11 0 obj +<< +/Filter [ /RunLengthDecode ] +/Width 81 +/Height 96 +/ColorSpace 10 0 R +/BitsPerComponent 8 +/Length 12 0 R +>> +stream +ő…ě„ţ…Ú„ű…ř„ű…ű†ţ‚ţzţkűeţXűfţmţzţ~ű†›…ţ„ţ…ţ„ţ…ě„ţ…Ń„ő…ţ€ţpţ\ţQřIţGűJţMţPţXţfţv›…ř„ţ…ě„ţ…Ń„ţ†ţ‡ţ„ţwţ]ţPűJţIűJţIřKţHţIţKţNţwţƒ•…ě„ţ…ř„ţ…ŕ„ţ…ţ†ţ…ţnţKţNţKţJďIţHřIţHţJţPţgţ€ţ„ţ‡¤…ţ„ţ…ě„ţ…Ô„ţ…ţ„ţ†ţOţNţHţJűIţJňHűIţQţiţ_ţHţIţXţ{Ą…ţ„ţ…ě„ţ…ׄű…ţţQţGŕJţIţOţqţ”ţŚţ…ţgţJţHţRţ}ţ…ţ†°…ű„ţ…ě„ţ…Ú„ţ…ţ„ţ†ţmţNţKŕJţHţMţrţ™ţ¨ţţxţ[ţJţMţcţƒţ†ł…ř„ţ…ě„ţ…Ú„ţ…ţ†ţţXţHţKÝJţTţvţ–ţ›ţ€ţwţbţJţKţOţsţ…ţ‡ł…ű„ţ…ě„ţ…Ú„ţ…ţ†ţsţJţHţIăJţKţIţSţoţ‚ţ{ţYţWţQţKţMţHţZţƒţ‡ł…ţ„ű…ě„ţ…Ú„ű…ţ_ţGűIăJţIţJţNţ[ţ`ţOţMţKţIţMţJţIţKţtł…ś„ű…ţRţIţHţIţMćJţIţKűJţNţKţNţIţMţKţIţKţJţ]ţ†ţ„­…ě„ţ…Ú„ţ…ţƒţJţKűIţKţIăJţKűJţIţJřKţIţJţIţOţ€Ş…ě„ţ…ׄţvţMűJţHţNţRţMćJţKţOţRţSűMűKřIţMţsţƒ­…ě„ţ…ׄţuţKţGţKţQţYţpţmţPűKűJřKţGţHţIţZţ~ţNţIűKţJţHţIţKţoţ„­…ě„ű…ř„ţ…é„ţ…ţuţMűHţœţŽţ‘ţ[ţsţ`ţMřJţjţ™ţŽţ¸ţžţĂţŸţnţXřKţJţKţNţ\Ş…ř„ţ…ř„ű…ű„ţ…ř„ţ…ň„ţ…ţtţMţGţ_ţĂţÔţÇţŸţZţXţKűJţeţ˘ţşţĂţĚţŇţÚţĘţPţYűKţJţHţIţJţXŞ…ő„ţ…ű„ţ…Ú„ţ…ţsţMţGţƒţÚţéţćţÖţ–ţJţKűJţ—ţĚţěţ÷űůţőţáţlţJűKţIţHűIţPŞ…ě„ţ…Ú„ţ…ţsűMţŞţâţĐţňţţââáţWţIűJţĹţůţýââáţ•ţ˜ţÚűüűţţGűKţJţIűHţOŞ…ě„ţ…é„ţ…ő„ţ…ţtţIţXţŇţ`ţ„ţšţďţűţsţVţMţOţŇţüţîţfţXţœ‘’‘ţ×ţŇţTűKţJţHţIţHţMŞ…ě„ţ…Ú„ţ…ţsţJţ]ţÝţHţ„ţ–ţ´ţüţˆţfţvţxţÓţüţŹţNţJţoţĄ‘’‘ţěţgűKţJűIţHţMţ„š…ł„ţzţKţ\ţÝţOţ\‘’‘ţˆţúţ‚ţZţ]ţjŔÁŔţřţŽţFţMţVţnţ{ţńţhřJřIţKţ„­…ě„ţ…ě„ű…ď„ţSţWţÖţMţNţiţzţŘţyţţ‚ţţ”ţîţţKűJţKţnţďţkţIţJţIţJţIţMţHţ†­…ě„ţ…Ô„ţRţOţÄţWţKţRţ‚ţľţÎţÓţŃţÍţżţÍţ­ţJţMţKţOţžţăţ^řIţJřIŞ…ě„ţ…ő„ţ…ă„ţSţHţnţëţ¨ţ¸ţÍţ×řŘţÜţßţăţáţÝţĐţˇţĐţęţvűHţIţJűIţJţFŞ…ě„ţ…Ô„ţSţFţOţłţˇţĆţÔřŘţŰţŕţćţčţćţĺââáţŢţ×ţÎţ|ţPňIţJţGŞ…ő„ţ…ű„ţ…ď„ţ…é„ţRţGţfţłţÁţÍţŐűŘţÚţÝââáţčţçţćřĺţćţăţÂţhűJűIţJţMţHŞ…ě„ţ…ő„ţ…ă„ţ]ţTţ•ţşţÉţŇűŘţŮţÜţßââáţčţćőĺţÚţżţĚţqţMţKţIţJţMţIţMţ„­…ě„ű…Ú„ţ…ţeţ^ţĽţŔţÍţŐűŘţÚţÝţáţĺţćřĺââáţĘţˇţźţťţbţKţMţJţIűJţNţ~ţ…ţ†ł…ř„ţ…ř„ű…ď„ţ…ű„ţ…ř„ţ…ţgţYţŸţĆţÎţŘţŮţÚţÜţŢţâţćţĺţäţăţŘţşţšţÄţÇţšţ]ţMţKţIţJţGţIţPţlţ„ţ‡ł…ő„ţ…ű„ţ…Ô„ţcţKţoţźţÓţŮűÚţŢţáţäţăţáţÚţžţ°ţżţĹűÇţ™ţQţJţKţţ‡ţXţBţIţYţ„ţ†ł…ě„ţ…Ô„ţbţNţWţ˜ţ˛ţĐţÚţŢţŕţáţŕţÚţśţŚţ˛ţÁţÄţÇţÄţťţ˜ţSűHţvţ¨ţŸţ‚ţRţMţ|ţ†ł…ě„ţ…ţ„ţ…ď„ţ…ő„ţ…ţ†ţgţMţ[ţËţ˛ţĄţ¨ţÁţĚţĆţÂŔÁŔţžţ˝ţťţ´ţšţĘţŇţŘţÎţ‰ţJţKţMţqŠŞŠţŞţ™ţIţNţxł…ě„ű…ű„ţ…ě„ű…ű„ţZţHţiţÍţËţąţŸţŽţżţÁţŔţ˝ţ˛ţ°ţłŔÁŔűÍţĐţÜţÝţşţRţJţKţQţŒţ›ţmDEDţIţZţƒţ‡ś…ď„ű…ć„ţ…ţ†ű…ţvţPţMţ`ţĐţÍţĚţśţĄţ˘ţ§ţŠţŚţ¤ţśţÇűÍţÓţçţ÷ţüţĺţţKţMţJţIţSţMţJţIţOţtţ‡ţ†ź…ě„ţ…é„ţ…ţ„ţ…ţ„ţ…ţƒţWţKţIţ_ţáţŇűÍţČţśűŤţ­ţÇţĚűÍţ×ţéţúűţűüűţËţWňKţJţIţNţ^ţƒţ„ź…ď„ű…ă„ţ…ţƒţ„ţnţNţKţIţ ţěţŘűÎţÍţÎňÍţŇţÝţę÷ř÷őţţűţ…ţPňKţJţIţTţmű‡ż…ě„ţ…ŕ„ţ…ţzţcţXţFţkţćţůţęţŃţÍűÎţÍţÎţÍţĎţŘţäţńţůřţţýţţţýţŐţ\ţKţNţHţKřJţOţ\ţ~ű…ţ„Ĺ…ě„ţ…ŕ„ţ€ţ]ţgţTţQţżţůţţţůţÝďÍţÝţě÷ř÷ţýňţţýţüţůţ•űNűKţIţKţIţJţKţ`ţ„ż…ő„ţ…ţ„ű…ć„ţ…ţ„ţZűJţFţ†ţ÷ţţţüţýţđţŘţĐřÍţ×ţöűüűřţţýřţţýţţţýţŐţQţIţJţKűIţJţIţKţMţsţ…ţ„Ĺ…ő„ţ…ű„ţ…ă„ţmţOţPţMţWţŮţýţţţýţţţý÷ř÷ţëţáţăţëţôřýűţţýďţţřţ|ţGţIţKőIűJţZţ}΅˄ř…ţzűKţIţ^ţŰűüűţýňţţüűüűţýűţňýěţţüţŇűKűJţIřJţIţMţOţeő…ţ„ř…ő„ţ…ţ„ţ…ţ„ţ…ţ„ű…ě„ţ…ř„ű…ţ„ţˆţ†ţ€ţSţJţHţMţţěţűű˙őţţýţüţýűţţýűţţýěţţýţúţčţ_ţMţKőJűKţIţJţKţ„ţ†Ë…ě„ţ…ř„ű…ţ„ţ…ţţ_ţKţJţFţXţ°ţčţúţţţ˙űýűţţýűúţýďţţýűţţýţüţ÷űóţďţxţPěKţIţHţIţjхţ„ű…ě„ţ…ő„ţ…ű„ţfţPţKţJţFţ\ţ´ţŘţóţűţüţţţýţű÷ř÷ţôţđţďţöţúűüűüűţýűüűţúţů÷ř÷ţóţďţéţâţćţëţ™ţYţKţJţKţJţIűJţKţIţJţPţo˅ě„ű…ř„ţ…ţ„ţuűNřJţnţ¸ţĹţŮţěţńűű÷ř÷ţńţéţçţëţěţőýűüűűüűţůţňţčââáţÜűŘţÖţŇţÓţŕţĐţdűJţGţMţIţNţKţJűIţNţOţv΅ě„ţ…ř„ű…ţţ\ţNţHűJţWţ‚ţťţÂţŐţäţďţüţýţţţýţńţę÷ř÷ţüőţţýţůţńţéţÝţÔűŇűŃţŇţĺţĹţVţOţwţ`ţJţIţKűJţIţHţMţ]ţ‚Ń…ő„ň…ű„ű…ţsţOţJűKţJţ]ţţÇţÜţďţůţţţýţüţţţýţňţôřýűüţţűýţţţüţúţíţĺţÜţŐţŇţŃţŘţňŠŞŠţCţhţ‚ţrţXţMţNţIţKűJţOţu݅ř„ţ…ř„ţ…ř„ţ…ř„ţ†ţƒţ]ţKţNţIţYţMţrţžţăţôţüűýţţřý÷ř÷÷ř÷ţüţýţüňýűüţţţýţü÷ř÷ţîţáţ×ţŇţŕţďţKűNţkţ…ţ]ţKţNţKűJţMţdű†×…ő„ţ…ű„ţ…ř„ţ†ţţTţOţHţqţsţQţĄţć÷ř÷ţýţţőýţüţýűüűűüűýţüţýţţőýţţűýţüţýţřţëţÜţÓţéţQţJţNţIţ_ţ†ţSDEDţOţKţJţIţRţ~ţ…ţ†ŕ…ţ„ţ…ě„ţ…ř„ţ†ţjűMţsţ_ţKţ ţüţţţüţýţţňýűüţţţüţţţýţüřýţüűýűţőýţţţýţńţÜţĎţNţHţ`ţnţcţwţkţJţKţJţFţMţQţ‚Ý…ţ„ţ…ě„ţ…ř„ţƒţZţPţYţ‚ţGţHţîřţţüňýţüţýţţřýţüţýűüűýţţţýţţňýţţţýţţűôţkţPţqţŠţƒţgţ€ţSţKţJţKţJţNţvׅű„ţ…ő„ţ…ţ„ţ†ţ…ţwţPţMţ}ţeţGţNţüőýţüűýţţűýűüţýţüţýţüţýţţěýţüűýţţţýţţţüţýţţţŚţWţxţţ†ţeţlţtţMţIţJţIţKţ`ţ„Ú…ě„ţ…ţ„ţ‡ţ„ţdţJţWţ}ţIţJţműüűţýţüţýţüţýţüřýţüţúűüűţüřýţţţüţýţţűýţţűýţüţţţýţüőýţţţŃţbţqţwţiţTţQţ‹ţKţNţIţKţNţTţڅţ„ţ…ň„ř…ţţYţHţoţfţBţOţŠţüćýţűţďňüţýţüţţűýţüőýţüţţűýűţűýţěţYţNţPűKţGţqţIţNţHűIţKţtţ„Ý…ě„ţ…ţ„ţ…ţvţMţKţƒţPţCţdââáţýűüűýţüűýţţţüţ÷ţíűüűţýţţűýţüţýţüőýţüěýűüţýűüűţuţMűJţKţGţ]ţGţNřIţKţcڅě„ű…ţ„ţ`ţKţeţtţKţHţœţúţüţýţüěýţőţńţýţţřýţţţýţüďýűţőýţţřýţ–ţHűKţIţJţPţRűHţIţHţJţRţ‚ă…ţ„ţ…ě„ű…ţyűMţ{ţWţKţQţĐűüűţűýţţţüřýűńţüéýűüőýűüűőýţüűýţţţ˛ţMőKţNţGţHţKţJţIţKţPţ{é…ř„ţ…ř„ţ…ř„ţ…ţ„ţOţNţ\ţsţGţKţ”ţüţýţţţüţţőýţüţýţüţëţďţüţýţţőýţüţţřýţţřýţţřýţüűýţţţÉţJűKţJţHţTţHţFţIţJţHţJţMţgڅő„ű…ţ†ţ€ţJţGţfţoţHţIţšűýűţřýţüţýţţűüţëţďţűűüţýűüűýţüţţűýţüřýţţőýţüűýţŘţMűKţIţMţ`ţIţGţHűIţHţMţbé…ű„ű…ď„ţ†ţ„ţlţKţIţeţsţIţYţ×ţýţüőýűţűýţţűüűţčţîűüűűüţýţţćýűüţýţüţţűýţţűýţÝţSřKţJţmţIţJţIţHűJţIţQ݅ő„ţ…ţ„ţ…ţţRţMţFţiţ{ţKţYţŢţţţüňýţüţýţţţýűüűţçţîűüţýţţűýţüőýţüţýţüřýűüţţţýţüţýţţââáţRűKţMţKţyţIűJţIţHţKţJţPă…ţ„ţ…ě„ţhţMţKţQţrţ€ţIţ^ţçňýţüţţőýţűţçţđţüőýűüţýţţűýţţţüřýţüţýűüţţřýţäţSřKţIţwţIţJřIűJţOڅň„ţ…ţbţOţNţbţ‰ţ‘ţKţnţîţýűţřüűýţüűüűţýţúţčţňűüÝýţüţţţýţüţýţţűýţüţţţĺţTřKţWţrűKűJřIţO݅ď„ţţXţIţHţXţ~ţ˜ţOţ|ţńţýţţřýţüňýţůţčţňţýţüűýűţţýţüţţţýřţřýţţţüűýţüţýţüţţţăţVűKţHţmţXűKţJţHřIţQ݅ű„ţ…ř„ţ‚ţRűJţIţWţ…ţZţ|ţóřýţüűýţüřýţüţúţčţôőýţüćýţüďýţüţţţýţÖţPţHţJţRţ{ţKţNţJţKřJţKţS݅ď„ţţVűIűMţ[ţuţţňţýţüćýţúţčţôţýţüţýţţţýűţňýűüăýţĹţKţPţmţ{ţpţWţsţgţXţPţJţMţJţdă…ţ„ţ…ű„ű…ţ„ţ…ţ„ţ‡ţ˛ţÝţŢţŇţŽţKţcţžţűţýţţřýţüţţřýţúţčţöţüűýţţďýőüţýţüňýűüţřţ|ţiţQţKűJţIţKűJţsţŸţxţWţzţ…ţ†ă…ű„ţ…ţ„ţ†ţ„ţ†ţŤţÍřÝţÖ‘’‘ţPţhţ¸÷ř÷ţüţýţüţţűüţýţüţýţúţçţöţýţüőýţüűýűţéýţüţřţÝţÜţŰţŹţlţIţJţIřKţJţMţpţ‰ţtţZţ~݅ţ„ţ…ű„ţ†ţ…ţšţżţŇőÝţÖţ’ţPţ`ţąţüřýţüőýţřţéţ÷ţýţţűüéýţţřýţüřýţăţŘţäţăţ×ţnţOţJţIřKţJţOţxţqţdţŹţ›ű†ď…ř„ű…ř„ţ…ţ‰ţ˛ţĹţŇňÝţŃţ€ţJţZţîţýţüţýţţţýűüţýţúţçţóţüţýţüřýţüűýţüţýţüřýţüőýţÝţŇţßââáţÇţcţHţMţIřKţJţRţbţQţ‰ţŘââáţ†ţ‡ď…ţ„ţ…ţ„ţ†ű…ţ„ţƒţ‘ţ­ŔÁŔţĚţ×ďÝţĂţgţKţ†ţŢűüűýűţţüűüűţďţńţýţüţţűýűţňýţüţýţüţýţţřýţßţĐţÝţÚţ¸ţdţJţIţJřKűJţFţfţÇţÝţßţ†ţ„ď…ţ„ţƒţŠţžţšţˇţ´ţ˛ţśţÁţÉţÓţÚďÝţŰţ°ţVţQţnţÍţůűýţţţüţýţţţüţűţýţţţýţüűýţüőýţüűýţţűýűüţúţŕţĎţŰţÓţˇţoţJţKţHřKűJţRţ§ţŘţÚţÝţ†ţƒď…ţ†ţŠţŻţŔţÍţËűÇţÉţĎţÔţÚéÝţŐţţGţMţXţŽţöţüűýţţňýţüÝýţüţýţüţíţÜţŇţĎţŘţÎţźţ‹ţXţMţFűHţGţKţYţţËţÖţŘţÚţ‰ţ„ď…ţ†ţœţžţĘţ×ţÖţÓţŇţÖţÚţŰăÝţÄţHţKţJţTţ™ţëţţűýţüřýűţţüőýţüűýţţţýűüţţţýţňţ×ţŇţÎţÍţŐţÍţźŠŞŠţ„ţXţQţOţIţSţtţ›ţŔţÎţÖţŘţŰţˆé…ţŽţĹţŇÔÝűÜţÝţxţHţKţHţCţPţjţËţüűýţüňýţüţýţţőýűüűýţüţćţÓţŇţÉţĆţÔţŃţÇţžţˇţ´ţąţ°ţąţśţżţËţÖţÚřÝţ˝ţŠţ„ţ†ő…ţ„ţŁţÄţŃŃÝţÜţÝţľţXţIţHţMţJţHţeűýřţňýűţűýţţţýţţţüűýţüţćűŇţĹţÁűÔţÍţĆţÂţżţžű˝ţÄţĚţŐňÝţŘţŹě…ţžţÂţÎËÝţÓţţKţFţJűGţIţóőýţţăýţţţýţüţýţţţěţŐţÓŔÁŔţźţÓţŐţŇţÍţČţÇřĆţÎţÓţÚňÝţÚţŇţ ň…ţ„ţţŔţĚţÜËÝţĂţjţJřIţGţŕňýţüţýţüűýţţőýţüűýţţţüţňţŮţŇţťţšţÓţŮţŘţŐţĐţÎűÍţÎţŇţŘţŰďÝţÚţÍţĄţ„ţ…ţ†ű…‘’‘ţ˝ţÉţÜËÝţŘţ¨ţQţHţIţKţIţÚřýţüţýţüţýţţţýţüňýţüţýţüűýţöţÜţÂţšţšţÓţŮţŰţÚţ×ţŐţÓţŇţÔţŘţÚěÝţÜţŮţŐŠŞŠţ‰ţ†ű…ţţťţČţÜÎÝţÜţÝţĐţűJţHţJţđţţřýţüňýţüţýţüűýţüűýţüţýţőţĎţzţ—ţšţÓţÚűÜűŰţŮűÚţŰţÜŕÝţĹţšű…ţŽţşţÇţÜËÝţÜţÝţżţgţRţXţŽřýţüűýűţűýţüřýűţřýţüţýţ×ţpţVţ–ţşţÔţÚţŰĹÝţŘţ´ţ…ţţźţÇţÜËÝűÜţŘŠŞŠţśţăţúňýűüőýţţőýţüűýţúţÍţeţJţYţ›ţšţÔţÚţÜĹÝţŰţŃţƒţ–ţźţÇţŰţÜÎÝţÜűÚţËţłţ÷űüűţüűýţüřýűüéýţüţřţłţWţHţFţ`ţœţšţŐţŰĹÝţÜţŘţÍţ†ţ­ţźţĚÂÝţŘţŮţČţŚţÚűüéýţüňýţóţ^ţKţHţMţIţHţqţšţśţÖţŰËÝţÚţŃţČţľţ‰ţ“ţľţĂţŐţÜĹÝţŘţÔţËţŻţ’űüűţüřýţüřýţüőýţóţÁţnţJţKţJţGţHţIţwţšţľţÖţÜÔÝţÜţÚţÖţÍţÂţĽţ‹ţ„ţĽţźţËţ×ţÜĹÝţŮţŃţÉţľţ•ţœţÚţóţůţüţýţüűýűüűţöţěţĐţ¤ţmţPţGňKţNţ~ţţśţŐţŰÔÝţŇţĚţÂţ˛ţ’ţ…ű†ţłţ˝ţÉţŇűŰţÜţÝţÜŃÝţÚţŇţČţ¸ţŸţKţNţoţ‘ţ¤ţśţźţ°ţŠţţqţ]ţNţKţJűHőKţJţTţƒţŸţśţÔţŰăÝţŰţÚţŰţÚţŇţžţŞ‘’‘ţ†ő…ţ˛ţşţÄţËţŐţ×űŘţŮţŰţÝţÜÚÝţŮţŇţČţśţ ţYţHţIţHűNţJţIţGţFDEDţJţHţKűGţKţJţIűJţHţYţˆţĄţľţÓţŰćÝţŮţÖţÔţŃţÉţżţŒţ„ř…ţ†ű…ţŞţ´ţšţ˝ţČţËţĚţÎţĐţŃţÔţÖţŘţÚţŰűÜěÝţÜţŘţÎţĂţ˛ţţhřIţJÚIűJűIţYţ‰ţ ţ˛ţÎţŘďÝţŰţÚţŐţĐţËţÇţżţŤţ’ţ„ě…ţţ˘ţŠţ­ţ˛ţśţşţ˝ţŔţĂţÄţČţĚţŃţÓţ×ţŮţŰďÝţÚţŇţÇţ¸ţŠţœţlňJţIăJţHţIřJţ\ţ‰ţœţ­ţÉţÓţŮţŰűÜűŰţŮţŇţËţĹţŔţľţœţ†ř„ď…ţ„ţ…ţˆţţžţ˘ţ¨ţŹţŻűłţľţ¸ţżţĂţÇţÍţŇţ×ţŘţÚţŰűÚţŐţËţžţŽţ ţ—ţkţHţJţHţIďKţMňKţHţGţHţJţIţ^ţ†ţ—ţ§ţÂţËţÓţŘţŮţÚţŮţ×ţŇţÇţ˝ţłţŞţŽţ…ţ„ŕ…ţ†ű…ţ‡ţţ—ţţĄűĽţ§ţŤţŻţłţşŔÁŔţĆţĘţÎţŇţÔţĎţÇţ˝ţ˛ţ¤ţ˜ţţ`ţMţQűRţ]ţhćkţjţ_űWţTţQţ_ţƒţ”ţĄţšţĂţĚţĐűŇţŃţĘţĹţˇţŤţœţˆţ„Ú…ď„ű…ű„ţ…ţ‰ţŽţţ”ţ›ţŸţ˘ţŚţŠţŤţŠţŁţœţ•ţ‘ţŒţ…ţwţƒţ…ţ„ř…ď„ě…ű„ţƒţ€ţ‰ţ”ţ¨ţŤţ­ţ°űąţŻţŤţ§ţţ†ű…ű„×…ě„ţ…ţ„ţƒű„ţ…ţ‰ţţ“ţ˜ű™ţ˜ţ•ţ’ţţŠţ‚ţţ…Ý„ć…ţ„ţƒţ‚ţŒţžţ˘ţŁřŚţ¤ţŸţ–ř„Î…ě„ţ…ř„ű†ű…ţ†ţˆţ‰ţţţŽţŒţ‡ţţ€ű…Ý„ć…ţ„ţ…ţţ‚ţţ”ţ—ţšţ™ţ˜ţ•ţŒţ‡ţ„ţ…ţ„Î…ě„ţ…ř„ď…ţƒţ†ţƒű‚ţ„ţƒř…ď„ţ…ň„Ý…ţ„ű‚ţ…ţˆţ†ű…ţ„ţ…ţ„Ô…€ +endstream +endobj +12 0 obj +7826 +endobj +13 0 obj +endobj +14 0 obj +7826 +endobj +15 0 obj +<< +/Type /XObject +/Subtype /Image +/Name /Ma0 +/Filter [ /RunLengthDecode ] +/Width 81 +/Height 96 +/ColorSpace /DeviceGray +/BitsPerComponent 8 +/Length 16 0 R +>> +stream +‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙‚˙ä˙€ +endstream +endobj +16 0 obj +125 +endobj +17 0 obj +<< +/Title (penguin.pdf) +/CreationDate (D:20120619194903) +/ModDate (D:20120619194903) +/Producer (ImageMagick 6.6.0-4 2012-04-30 Q16 http://www.imagemagick.org) +>> +endobj +xref +0 18 +0000000000 65535 f +0000000010 00000 n +0000000059 00000 n +0000000118 00000 n +0000000296 00000 n +0000000377 00000 n +0000000395 00000 n +0000000433 00000 n +0000000454 00000 n +0000008478 00000 n +0000008498 00000 n +0000008525 00000 n +0000016495 00000 n +0000016516 00000 n +0000016532 00000 n +0000016553 00000 n +0000016869 00000 n +0000016889 00000 n +trailer +<< +/Size 18 +/Info 17 0 R +/Root 1 0 R +>> +startxref +17067 +%%EOF diff --git a/contrib/mom/examples/penguin.ps b/contrib/mom/examples/penguin.ps new file mode 100644 index 0000000..2728930 --- /dev/null +++ b/contrib/mom/examples/penguin.ps @@ -0,0 +1,461 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: GIMP PostScript file plugin V 1.06 by Peter Kirchgessner +%%Title: /home/peter/Pics/penguin_small2_bw.ps +%%CreationDate: Wed Apr 17 19:49:51 2002 +%%DocumentData: Clean7Bit +%%LanguageLevel: 2 +%%Pages: 1 +%%BoundingBox: 0 0 81 96 +%%EndComments +%%BeginPreview: 90 107 1 107 +% aaaaaaaaabff555555555540 +% 5b6db6db5edbf6b6b6b6b680 +% aaaaaaaab7ff7ad555555540 +% b55555557eddeeaadadadac0 +% 56db6db6dbffdf56ab555540 +% aaaaaaaaffb755dab556ab40 +% 5b555b55f77ed7d556b56d40 +% aab6d56dbfffaaeb6ad5aa80 +% 6d555aabf6edd5daad56ab40 +% aadaab56ffdfaff555aab540 +% 5555b56bddfdff76dab55680 +% b6aaaaaffbbbbbed5556dac0 +% 55b6d6d5bff7f77aab6aaa80 +% aaaaaaaff77f6ffd6d555540 +% 5b555b576defeedaaaadb680 +% aab6d56dfbfd3bfdb56aaac0 +% 55555aab8eda4fb556ab5540 +% b6daab5743f40b7eaad56d80 +% 5555b56f037007fadaad5540 +% aaaaaaab11e0c6ed55b5aa80 +% 5b6d6db731b1a3feaaaab6c0 +% aaab55566963a3badb555540 +% 6d556aaf35d2e37d556daa80 +% aadaadb57959f3f6aaaab6c0 +% 5555aaab3403c37d6dab5540 +% 6daab5571428c3eeaab56a80 +% aab6d6db908007fd5556ad80 +% ad5555574000176edb6ad540 +% 55aaadab920003fd55555a80 +% b56db55b2000136eaaadab40 +% 56aaaaab400047fdb6d55540 +% aad556d7040112df555ab680 +% 6d5b6ab5d00447bb55ab5540 +% aaaaad57402915cf6d556a80 +% adb555ab9a9243a7aab6ad80 +% 5556dab6902485ead5aad540 +% b5aaab57854901d7daad5a80 +% 56b5556d929201bfab55ab40 +% aaab6d57004400fb756ab540 +% 6d6d55af0a1000efeaad5680 +% aaaaaaba0080005ef6d5aac0 +% adb5b6d60220003fdaaab540 +% 5556aabc0000003bfd5b5680 +% b5aab57c0000003f76d56ac0 +% 56b556e80000001beeaaad40 +% aaab6bf80000001f7f5b5580 +% 6d6d55b00000001dfbaab540 +% aaaaaff00000001bdf6d5680 +% 55b5b5b00000000ffbd5aac0 +% b6aaafe40000000f6ff55a80 +% aad6df7000000246fedaab40 +% 555ab6d000000003aff5b540 +% b6aaafe000000013edbaaa80 +% 556b7d8000000001b7f6d6c0 +% aaad5bc000000001fbbd5a80 +% 6db57f0000000000d77aaac0 +% aaaab58000000000edf6d540 +% 5556f7000000000056fead80 +% b6dab600000000006edb5540 +% aaaaee00000000007ffeb680 +% 5555ee000000000076bb5540 +% b6dabc00000000003f7f6a80 +% 5555d800000000003b7756c0 +% aaabfc00000000003f7eda80 +% 6db6b0000000000036f7aac0 +% aaabd800000000003ffeab40 +% ad57b800000000003d6fda80 +% 55b7d8000000000037fdaac0 +% b55eb800000000003edfab40 +% 56afb000000000003bfbb540 +% aaddb000000000003edf5680 +% 6d5bd8000000000035fdaac0 +% aaafe800000000003b5bb540 +% 55ba5000000000006fef5680 +% b6a83800000000005f736ac0 +% aaa00c00000000003dfdad40 +% 55680e00000000003bd65580 +% b6a107000000000077bc5a80 +% 55a013c0000000023ff82b40 +% a80401a0000000005db45540 +% 429021f0000000043ff02d40 +% 900000f80000000096c4aa80 +% a00080be000000082a902d80 +% 004204770000000244401540 +% a200003e8000001411001540 +% 4004105fc000000044444b40 +% 8800001b8000000a00800540 +% 5040411f4000001012000280 +% 80040007c000001440044080 +% 5080040d0000003100100040 +% 800040200000007400400400 +% 51080002000000e804008040 +% 80008440000003f210000080 +% 50000005000007d400080940 +% 0111000080001ef020808280 +% a00008894000ffd480001540 +% 02000000fa57bb680108aa80 +% a0222002bfffffe900012b40 +% 0a4001115ffdedd20824d540 +% d0888004bb6fbfb4008b5a80 +% ad251202bffdfbe921255580 +% b554a05576ab576a045aaa80 +% aaaa950aaaad5aaaa955b6c0 +% 56d56a556d6aaad48556aa80 +% b55b5555aaab6b5ab55aad40 +% 55aaaaaab5b555554aaad580 +% ad556d5b56aaad6b556b5a80 +%%EndPreview +%%BeginProlog +% Use own dictionary to avoid conflicts +5 dict begin +%%EndProlog +%%Page: 1 1 +% Translate for offset +0.000000 0.000000 translate +% Translate to begin of first scanline +0.000000 95.872000 translate +80.640000 -95.872000 scale +% Variable to keep one line of raster data +/scanline 90 1 mul string def +% Image geometry +90 107 8 +% Transformation matrix +[ 90 0 0 107 0 0 ] +{ currentfile scanline readhexstring pop } +image +72727272717171717171717172717171717171717171717172717171727271717171727273736f +675852524e4653535a676b73737272727272727272727272727272727272727272727272727272 +727272727272727272727272 +7172717271717171717171717271717171717171717171717271717171717172727272726d5d4a +4039393939373a3a3c3f4653637172727272727272727272727272727272727272727272727272 +727272727272727272727272 +7171717271717171717171717271717171717171717171717271717171717173747271644b3f3a +3a393a3a3a393b3b3b38393b3d4d64707272727272727272727272727272727272727272727272 +727272727272727272727272 +727272727171717171717171727171717172717171717171727171717171727372705b3b3d3b3a +3939393939393938393939383a3c3f546d71747272727272727272727272727272727272727272 +727272727272727272727272 +727271727171717171717171727171717171717171717171727171717171727173553e3d383a39 +393a383838383838393940564d3f38394668727272727272727272727272727272727272727272 +727272727272727272727272 +71717171717171717171717172717171717171717171717172717171717172715f3d38393b3b39 +3a393939393939393a3c5574807252403742627272727272727272727272727272727272727272 +727272727272727272727272 +727271727171717171717171727171717171717171717171727171717172726c403c373a3a3a3a +3a3a3a3a3a3a3a3a393e5e82958c72543a38416a72737272727272727272727272727272727272 +727272727272727272727272 +727171727171717171717171727171717171717171717171727171717271735a3d383b3a3a3a3a +3a3a3a3a3a3a3a3a383c5f87978e7c65493a3c5070737272727272727272727272727272727272 +727272727272727272727272 +7171717271717171717171717271717171717171717171717271717172736c4638373b3a3a3a3a +3a3a3a3a3a3a3a3a3a436384897d6d644f3a3b3e60727472727272727272727272727272727272 +727272727272727272727272 +727171727171717171717171727171717171717171717171727171717273603a3839393a3a3a3a +3a3a3a3a3a3a3a3b39425c6f68574745403b3c3848707472727272727272727272727272727272 +727272727272727272727272 +7271727271717171717171717271717171717171717171717271717172724d373938393a3a3a3a +3a3a3a3a3a3a3a393a3d494e3e3e3c3b393c3a393b617272727272727272727272727272727272 +727272727272727272727272 +71717171717171717171717171717171717171717171717172717171727241393839393c3a3a3a +3a3a3a3a3a3a3a393b3a3a3d3b3a3d393c3b393b3a4b7374717272727272727272727272727272 +727272727272727272727272 +7272727271717171717171717271717171717171717171717271717172703a3b3937393b393a3a +3a3a3a3a3a3a3a3a3a3b3a3a393d3a3b3b3b393a393e6d74727272727272727272727272727272 +727272727272727272727272 +7272727271717171717171717271717171717171717171717271717171633c3a3a38383d413c3a +3a3a3a3a3a3a3a3a3a3b3e4142393c3c3b3b3939393c6074707272727272727272727272727272 +727272727272727272727272 +7272727271717171717171717271717171717171717171717271717171623b373b3e40475d5a3f +3b3b3a3a393b3b3b373839486b6d3d393b3b3a38393b5c73717272727272727272727272727272 +727272727272727272727272 +7272727271717171717171717271717171717271717171717271717172623b373c3a3d3f425d65 +3f393a3a3d393b3e5b75795a3e6562393b3b3b39393d4f71727272727272727272727272727272 +727272727272727272727272 +7272727271717171717171717272717171717271717171717271717172623c3838538a9e7e4960 +4e3c3a3a3c3a57879ea9b0b68e445b463b3b3b3a3b3d4a72727272727272727272727272727272 +727272727272727272727272 +7272727271717171727171717272717171727171717271717271717172613c374d96b6cabb8e48 +463b3a3a3a5291abb6c0c7d1be7f3f473b3b3a38393a4672727272727272727272727272727272 +727272727272727272727272 +7272727271717171717271717271717171717171717171717271717172603c3770acd1e3dfcc84 +3a3b3a3a3d85c0e7f4f7f7f2d9a4593a3b3b393839393f6b727272727272727272727272727272 +727272727272727272727272 +7272727271717171717171717271717171717171717171717271717172603c3c9aebdbc5eefdda +45393a3a45b8f7fcda8386d1faec8b373b3b3a3938383e6b727272727272727272727272727272 +727272727272727272727272 +7272727271717171717171717271717171717171717172717271717172613946c8db4e7188eaf9 +60443c3e4dc7fbe953468a7fcdfdc7433b3b3a3839383c6a727272727272727272727272727272 +727272727272727272727272 +7272727271717171717171717271717171717171717171717271717172603a4bd59a387184a5fb +755363655bc9fb9c3d3a5c907ffbe7543b3b3a3939383c6a717272727272727272727272727272 +727272727272727272727272 +7171717171717171717171717171717171717171717171717171717171673b4ad5833e4a7f75f8 +6f484b575cb3f67b363c445b68f4ed553a3a3a3939393b6a717272727272727272727272727272 +727272727272727272727272 +7272727272717171717171717271717171717171717272717271717171714245cc953c3d5667ce +666e6f6c6282e97a3b3a3a3b5bf5ea58393a393a393c386a737272727272727272727272727272 +727272727272727272727272 +727272727171717171717171727171717171717171717171727171717171413eb7c4453b416fa6 +c3c9c6c2bcb1c19d3a3c3b3e8cfbdc4c3939393a39393969727272727272727272727272727272 +727272727272727272727272 +727272727171717171717171727171717171727171717171727171717171413a8df18e477da2af +cdcecbbfa6b2cfc289534273ebf9ac3f3939393939383b62727272727272727272727272727272 +727272727272727272727272 +72727272717171717171717172717171717172717171717172717171717142385bdae697a9c1cd +cfcecfd3d4d7dcd9d5c5a8c5e4dc633838393a39393a365b727272727272727272727272727272 +727272727272727272727272 +72727272717171717171717172717171717171717171717172717171717142363e99a4a8b9cacf +cecfd2d8dcdfe2dfdedad6cdc3ac693f39393939393a375b727272727272727272727272727272 +727272727272727272727272 +7272727271717171717271717271717171717171727171717271717171714137538fa4b4c2cbcf +cfd1d5dadee2e1dfdedededfdcdab5553a3a39393a3c3859727272727272727272727272727272 +727272727272727272727272 +7272727271717171717171717271717171717271717171717271717171714b43839facbdc8cfcf +d0d3d7dae2e2dfdedededed1b1c5c05e3c3b393a3c393c4c717272727272727272727272727272 +727272727272727272727272 +727272727171717171717171727271717171717171717171727171717172524c94a0b2c1cbcfcf +d1d5d9dee1dfdedededabea8aebbad4f3b3c3a393a3a3d426b7273727272727272727272727272 +727272727272727272727272 +72727272727171717271717172727171717171717172717172727171717254478ea5b9c3ced0d1 +d3d6dbe0dededddccfabaab7bbbaaa4b3c3b393a37393f3b597174727272727272727272727272 +727272727272727272727272 +727272727171717171727171727171717171717171717171727171717171503b5c84aec9d0d1d1 +d6d9dddcded9d1b0a0b1b8bbbab387403a3b6c7446333938477173727272727272727272727272 +727272727272727272727272 +7272727271717171717171717271727171717171717171717271717171714f3d457986a3c5d1d6 +d8d9d8d1bfa795a2b4b7bab7adac8642383863978e6f413c3c6973727272727272727272727272 +727272727272727272727272 +727272727171717171717171727171717171717171717271727172717272523b4390a58a8e9da8 +aba4a29d9ca5aeb3b2afabb7c4c2bb5d3b3645849b99663a3c4e72727272727272727272727272 +727272727272727272727272 +727272727171717171717171727171727171717171717271727171717273543c49adbfa29097b4 +c0b9b5b3b4b0afada5aabec7cfcac3763a3b3c5e999a8745393d65727272727272727272727272 +727272727272727272727272 +727272727271717171717171727271717172717171717171727172727171483856aac1bfa18e9e +b1b4b2afa9a3a0a4b3c1c1c5d3ded4ac413a3b4079895a38353948707472727272727272727272 +727272727272727272727272 +7272727271727171717171717272727171717171717171717272737272633f3c4ea8c5c1c0a790 +919698959193a7bac2c1c9e1f4fbfbde6c3b3c3a39423c3b3a393e617473727272727272727272 +727272727272727272727272 +7272727271717171717171717271727171717171717172717272717270453b394dc1d9c8c2c2bc +a79b9b9dabbac0c1c2cde3f8fdfdfdfabf453b3b3b3b3b3b3a393d4c7071727272727272727272 +727272727272727272727272 +727272727171717171717172727171717171717171717171727270715b3d3b398ff5e7cec3c3c1 +c3c1c2c2c3c2c2c8d4e4f5fdfdfdfdfdf9723f3b3b3b3b3b3b3a39435a74747272727272727272 +727272727272727272727272 +7272727271717171717171717271717171717171717171717271726750463658e0fbf7e4c6c2c3 +c3c2c3c2c2c4ceddedf7fdfdfdfdfcfdfccb4a3b3d383b3b3a3a3a3e4a6b727271727272727272 +727272727272727272727272 +72727272717171717171717172717271717171717171717172716d4b544340b1f7fcfdf7d5c2c2 +c2c2c2c2c6d5e7f5fcfdfdfdfdfdfdfcfbf7833d3d3b3b3b393b393a3b4e717272717272727272 +727272727272727272727272 +7272727271717171717271727271727171717171717171727371483a3a3673f4fdfcfbfceccfc5 +c2c1c2cde3f3fafdfdfdfcfdfdfdfdfcfdfccb40393a3b3b39393a393b3c607271727272727272 +727272727272727272727272 +727272727171717171727171727171717171717171717171705a3e3f3c45d0fcfdfdfcfdfcf5e6 +d9dce5f1fafcfcfcfdfdfcfdfdfdfdfdfdfdf66937393b3b393939393a3a486a72717272727272 +727272727272727272727272 +7272727271717171717171717271717171717171717171725f3e3a3c3985fbfcfdfcfdfdfdfdf9 +f1f8fcfdfdfcfcfcfcfdfdfdfdfdfdfdfdfdfd933b3a3b3b3a3a3a3a393a3d4a6b717272727272 +727272727272727272727272 +717171717171717171717171717171717171717172727267443b3b394cd2fafcfdfdfdfdfdfdfb +fafcfdfdfdfcfcfcfcfcfdfdfdfdfdfdfdfdfbc73b3b3a3a3a393a3a3a393c3e52727272727271 +727272717171717172717271 +727172727171717171717171727171717172727175736d423a3a383c7de7f9fefefdfdfdfdfdfc +fbfcfdfdfdfcfdfdfcfdfdfdfdfdfdfdfdfcf8e24d3c3b3b3a3a3a3a3b3b393a3b537173727272 +727272727272727272727272 +7272727271717171717171717271727171727271726e4d3b3b3a3646a0e2f8fdfefdfcfcfdfdfc +f8f8fcfdfdfdfdfdfdfdfcfdfdfdfcfbf4f0efeb653f3b3b3b3b3b3b3b3b3938393f5772727272 +727272727272727272727272 +727172727171717171717171727171717171727171533f3b3b3a364aa5cef0f9fbfdfdfcf9f5f1 +ecebf3f8fafbfbfafcfaf8f7f5f5efeae3dbdfe687473b3b3a3b3a393a3a3b393a393f5c727272 +727272727272727272727272 +7272727271717171717171717272717171717271623d3d3a3b3a3a5ba9b8d0e7edf5f9f9f5ede3 +e1e5e7f2fbf9fafaf7eee2dad3d0cececcc8c9d8c5513a3b3a373c393d3b3a3939383d3e637272 +727272727272727272727272 +727272727171717171717171727171717172726e4a3d383a3b3a456fadb5cbddebf8fbfcfdfced +e4f5fbfdfcfdfdfdfcf7ede3d5cecac8c7c6c6c7deb844393e644e3a393b3a3a3939383c4b6f72 +727272727272727272727272 +72727272717171717172727272727271717272603e3a3b3b393a4b7cbbd3ebf7fdfcfcfbfdfcee +f1fcfcfcfcfbfbfdfcfcfdfbf8f2e8ded3cbc7c6ceee993d34556f5f463c3d393b393a3a3e6272 +727272727272727272727272 +717171727171717172717171727171717173704b3b3d39473c3c5fb0dcf1fbfcfcfcfdfcfcfcf5 +f5fbfcfbfdfcfcfcfcfcfbfbfdfcfcfbf5e9d9cdc7d8ea683b3d3d58724b3b3d3b3a3a3a3c5173 +737272727272727272727272 +7272727271717171717271717271717171736e433e385e603e4090dff5fcfdfcfcfbfcfcfbfcfa +fbfbfcfcfcfbfcfdfcfcfcfcfdfcfcfcfbfcf6e6d3c9e3c3403a3d394d7342353e3a3b3a39416b +727372727272727272727272 +727171727171717171717171727171717172673d374a6b3b3d4cd9f8fdfcfcfcfbfdfbfcfbfcfc +fbfcfcfbfcfcfcfcfdfcfcfcfbfcfbfcfcfdfdfaedd4ceeb6c3c3d3d3e51663a3e383b3a393c56 +717472727272727272727272 +727271727171717171717171727171717173573c3c604d3b3c8ffbfdfbfcfdfcfcfcfcfcfcfbfb +fdfbfdfcfdfbfcfcfcfbfcfcfdfbfdfcfcfcfcfdfcedd3dac43d384e5b5064583a3c3b3a363c40 +6f7272727272727272727272 +727271727171717171717171727171717170483f476f373851e9fdfdfdfbfcfcfcfcfcfcfbfcfd +fcfcfcfbfcfcfbfbfcfcfdfcfdfcfcfcfcfcfcfdfcfdf1e6f1583f5e7770546d42393b3a3b3a3d +637272727272727272727272 +7272727271717172717171717271727372643f3c6a52373da0fbfcfcfcfcfbfcfcfcfdfcfcfbfb +fcfbfcfbfbfcfdfcfcfcfcfcfcfcfcfbfcfcfdfcfdfbfcfcfd9545657c735259613d3c393a393b +4e7172727272727272727272 +7272727271717171717171717271727471513a456a393a5ae6fafcfbfcfbfcfbfcfcfcfcfbf8fa +fbfcfcfcfcfdfbfcfdfcfcfdfcfdfcfbfdfcfbfcfcfcfcfcfdc64f5e6456434078433b3d393b3d +436c72727272727272727272 +727272727171727171717171727272726e47385c53333e98fbfbfcfcfcfcfcfcfcfcfcfcf9eafb +fbfbfbfbfcfcfbfdfcfcfbfcfcfcfcfcfbfdfcfcfdfdfcfdfce7473d3f3b3b375e57393d383939 +3b6171727272727272727272 +72727272717171717171717172717272633c3b703f3451dafcfcfbfbfcfcfbfcfcfdfdfbf4e8fa +fcfdfcfcfcfbfcfbfcfcfcfcfbfdfcfcfcfcfcfcfcfbfbfcfcfa623c3a3a3b374b66373d393939 +3b5072727272727272727272 +727272727171717171717171727272714e3b52613b388af8fcfbfcfbfcfcfcfcfcfdfcfcf2edfc +fdfcfcfcfcfdfcfbfcfcfcfcfcfdfcfdfdfcfcfcfcfdfcfbfcfc84383b3b393a3f774138383938 +3a416f727272727272727272 +727271727171717171717171727272663c3c68453b40c5fbfbfbfdfdfcfcfdfbfcfcfcfcededfb +fcfcfcfcfbfcfcfcfcfbfbfcfcfcfcfcfafcfcfcfcfbfcfdfcfda23c3b3b3b3b3d7437383b3a39 +3b3f68727272727272727272 +7272727271717171717171717174714b3a3a6b373b57eefcfcfcfcfbfcfcfbfcfcfbfdfbe9e9fb +fbfcfcfcfbfcfcfbfbfcfcfbfbfcfbfcfcfcfcfcfbfcfcfcfdfcaf3b3b3b3c3a406f37373a3a39 +393d5f727272727272727272 +7171717272717171727171717271623e3d4a60373b82fbfcfcfdfbfdfcfcfcfcfbfcfcfbe6eafb +fcfdfcfcfcfcfcfbfdfcfcfcfdfcfcfcfcfdfcfcfcfbfcfcfcfdbd3a3b3b3a3843633836393a38 +3a3c54727272727272727272 +727272727272717171717272736d463a37535c3839aafcfcfcfdfdfcfcfcfbfcfdfcfbfbe6eaf9 +fbfbfcfbfcfbfcfcfbfdfcfcfbfcfcfcfcfdfcfcfcfcfbfdfcfcce3c3b3b393c4e533937383939 +383c4f727272727272727272 +71717272717171717171717371593d3b3952603947cdfcfbfcfcfcfcfcfdfdfcfcfcfdfae2e9fa +fbfbfcfdfbfcfcfcfcfcfcfcfcfcfcfbfbfcfbfdfcfcfdfafcfcd4423b3b3b3a5a4e393a39383a +3a3940727272727272727272 +7272727271717171717271726c41393c3656683b47d6fdfbfcfcfcfcfcfcfbfcfdfcfcfae1e9fb +fbfcfdfcfcfcfbfcfcfcfcfbfcfcfbfcfcfcfbfbfdfcfbfcfcfdda413b3b3c3b6644393a3a3938 +3b3a3f727272727272727272 +727271727171717171717171553c3b3b405f6d394ce1fcfcfcfcfcfcfbfdfcfcfcfcfcf9e1ecfb +fcfcfcfcfcfbfbfcfdfcfcfdfbfcfcfcfcfbfcfbfbfdfcfdfcfcdd423b3b3b39643f393a393939 +3a3a3e727272727272727272 +7272727271727171717171724f3e363d4f767e3b5be9fcfdfcfdfbfbfbfcfcfbfafcfcf8e2eefb +fbfcfcfcfcfcfcfcfcfcfcfcfcfcfcfbfdfcfbfcfdfcfcfcfbfdde433b3b3b455f3a3b3b3a3a39 +39393e727272727272727272 +72727272717171717171716e46393938466b863e69edfcfdfcfcfcfcfbfcfcfcfcfcfcf7e2eefc +fbfcfcfdfbfdfcfbfdfcfdfdfdfcfcfcfcfdfbfcfcfbfcfcfbfddc443b3b385a463b3b3b3a3839 +393940727272727272727272 +72727272717171727171716f413a3a3a3945724869effcfcfcfcfbfcfcfbfcfcfcfcfbf8e2f1fc +fcfcfcfbfcfcfcfcfcfcfcfcfcfcfcfbfcfcfcfcfcfcfbfcfdfccc3f383a41683b3d3d3a3b3a3a +3a3b42727272727272727272 +72727272727171717171716e443938393c3c49626eeefcfbfcfcfcfcfcfcfcfcfcfcfcf8e2f1fc +fbfcfdfcfcfdfdfcfcfcfcfcfbfcfbfcfcfcfcfcfcfcfcfcfcfcb83b3f5a685d455b6054463f3a +3c3a51727272727272727272 +727272727271717172717171524a728f8d5e424d80e3fbfcfcfbfcfcfdfcfbfcfcfcfcf7e1f2fb +fcfcfcfcfcfcfcfbfcfdfbfcfcfcfcfcfcfcfcfcfcfdfcfcfcfc9c405b503d3b3c3c455368755c +3d3a5a727272727272727272 +72727172717171727271727174a3c9d4d6c87b3b50b0f9fcfcfdfcfcfcfbfdfcfcfcfcf8e2f3fb +fcfcfdfcfcfcfcfcfcfcfbfbfbfcfbfcfbfcfcfcfcfcfbf9fbf66956403b3a3a39393b3a3a608d +654567717273727272727272 +7272727271717172717371739bc1d1d4d4d4cc7f3f55a9f5fbfbfcfbfdfbfbfcfbfbfcf8e1f3fc +fbfcfcfcfbfcfbfcfcfdfdfcfcfcfcfcfcfcfcfcfbf6d5d3d3d29c59393a393b3b3b3b3a3c5d76 +61486b737272727272727272 +727272727171727171737288b1c7d1d4d4d5d4cc803f4ea1f0fbfcfcfcfbfcfcfcfdfcf6e3f4fc +fdfbfbfcfcfcfcfcfcfcfcfcfdfbfcfcfcfbfcfcfcdccfdbdddccd5b3e3a393b3b3b3b3a3e655e +519c89727373727272727272 +7171717272727171717276a3b8c8d2d4d5d4d5d5c66d3a4892e9fcfbfcfdfcfbfbfbfcf8e1effb +fcfbfcfcfcfcfbfcfcfbfcfbfcfcfcfcfbfcfcfcfcd5c7d4d7dabb50383c393b3b3b3b3a414f40 +76cfda8f7374727272727272 +7172717372727271707e9db3c0cdd4d4d5d4d4d5d4b6543b4673d6fbfbfcfcfdfdfcfbfaeaedfc +fbfdfcfcfcfdfdfcfcfcfcfcfbfbfcfbfcfdfcfcfcd7c5d3d4d1a9513a393a3b3b3b3b3a3a3653 +bad5d7b87371727272727272 +7170778c9baaa8a5a3a7b4bdc9d1d4d4d4d4d4d4d5d2a04435405bc1f7fcfcfdfbfcfcfdfbf9fc +fdfcfbfcfcfcfbfcfcfcfcfbfcfcfcfdfcfcfbfbf8d8c4d3d2c9a85c3a3b383b3b3b3b3a3a4196 +cfd1d4c47370727272727272 +73779fb2bcc1bfbbbbbdc4cad1d4d4d4d5d4d4d4d5d4cb7c3d373c469ef3fbfcfcfcfdfcfcfcfc +fcfbfcfcfbfcfcfcfcfcfcfcfcfcfcfcfbfcfbe8d3c7c4d2cec3ae78463c36383836373b477dbf +cccfd1c07671727272727272 +738ab0bec9cdccc9c7ccd1d2d4d4d4d4d4d4d4d4d4d5d5b758383b3a4387e5fdfcfcfcfbfcfcfc +fdfdfbfcfcfcfcfcfbfcfcfdfcfcfbfbfdfceecdc7c3c2cecbc1ae997146403e393d426189b2c3 +cccfd2c27572727272727272 +7193b7c7ced1d2d3d2d3d4d4d4d4d4d4d5d4d4d4d4d3d4cf953d383a353a68d0fbfbfbfbfdfcfc +fbfbfbfdfcfdfcfbfcfcfbfcfcfcfdfcfbfde3c7c8c2bfc9cac4b5a69c8e7d77767e929eacc0ca +d0d3d4d07f72727272727272 +729eb8c8d0d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d5d3d3d5c065383b38343f57bffbfbfcfcfbfc +fcfcfcfcfbfbfcfdfcfcfcfcfbfbfbfcfcfbdfc9c8bdb9c8cac6bbb0a8a5a1a0a1a3a7b1bfccd1 +d4d4d4d3af77717372727272 +7192b7c6d0d4d4d4d4d4d4d4d5d4d4d4d4d4d4d4d4d4d3d4d4a64639383c3a3852c7fcfcfdfdfd +fcfcfcfcfcfcfdfdfcfcfdfcfdfcfbfcfcfbe0c8c8b8b4c6cacac1b9b5b1b0afafb2b7c0cbd4d4 +d4d5d4d2cf9c727272727272 +728cb5c3ced4d4d4d4d4d4d4d5d4d4d4d4d4d4d4d4d4d4d4d4c97d3b363a3737396ef0fcfcfcfc +fdfcfcfcfbfcfcfcfcfcfcfcfdfcfcfbfcfde7cbc9b3aebfc9cbc8c2bcbbb9b9b9bcc3c9d1d5d5 +d5d5d5d3d1c88f7272727272 +718bb2c0cdd3d4d4d4d4d4d5d5d5d4d4d5d4d4d4d5d4d4d4d4d5b6573a3939393742d8fcfcfcfc +fcfbfcfbfcfcfcfdfcfcfcfcfbfbfcfcfdfbeed0c8adaabcc9d0cecbc5c3c2c1c3c5c8ced2d5d5 +d5d5d5d5d4d1c29071727372 +727fafbdccd3d4d4d4d4d4d4d5d4d4d4d4d4d4d4d4d4d4d4d4d4ce974038393b393fd1fcfcfcfb +fcfbfcfdfcfcfbfcfcfcfcfcfbfcfcfbfcfcf3d3b588aabdc9d0d2d1cdcbc9c8caccced1d4d5d5 +d5d5d5d5d4d3d0cb99767372 +727aadbccbd3d4d4d4d4d4d4d5d4d4d4d4d4d4d4d4d4d4d4d5d3d5c57a3a3a383a59ecfdfcfcfc +fbfcfcfcfcfcfcfbfcfbfcfcfbfcfcfcfbfcf2c46785aabdc9d1d3d3d2d2d0d1d1d2d2d3d4d5d5 +d5d5d5d5d5d5d4d4d4b88872 +727bacbacbd3d4d4d4d4d4d4d5d4d4d4d4d4d4d4d4d4d4d4d5d4d3d5b15441467bd7fcfcfcfbfc +fcfdfdfcfcfcfbfcfcfcfdfdfcfcfcfcfbfccd5d4484abbecad1d2d4d4d5d4d5d4d4d4d4d5d5d5 +d5d5d5d5d5d4d5d4d4d5cea5 +727caebac9d3d4d4d4d4d5d5d5d5d4d4d4d4d4d4d4d4d4d4d5d5d3d3ce99a7dcf8fcfcfcfcfcfc +fbfbfcfcfbfcfcfdfcfcfcfcfbfcfcfcf8c2523a4789aabecad1d3d4d5d5d5d5d5d5d5d5d5d5d5 +d5d5d5d5d5d5d5d5d5d5d2c6 +7084aebacbd2d3d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d3d1d1bfa4f4fafbfbfcfcfbfc +fcfcfbfbfcfcfcfcfcfcfcfcfcfbfbf6a44538364e8aaabecbd2d4d4d4d4d4d4d4d4d4d4d4d4d4 +d4d4d4d4d4d4d5d5d4d3cec1 +718eacbbcdd3d3d4d4d4d5d4d5d4d4d4d5d4d4d5d4d4d5d4d5d4d4d3cfceadbdfbfcfbfcfcfcfc +fbfdfdfcfbfdfbfbfcfcfbfbfcfce87f42353834578aa9c0cbd2d5d5d5d5d5d5d5d5d5d5d5d5d5 +d5d5d5d5d5d5d5d4d0c9c19f +739daec0d0d4d4d4d4d4d4d4d5d4d4d4d4d4d4d4d4d4d4d4d5d4d4d4cfd0bc95d1fbfbfbfcfcfc +fcfcfcfcfcfcfbfcfcfcfcfcefa84c3b383c39385e88a7c1ccd2d4d5d5d5d5d5d5d5d5d5d5d5d5 +d5d5d5d5d4d4d4d1c6bca676 +81a6b6cbd2d3d4d4d4d4d4d4d5d4d4d4d4d4d4d4d4d4d4d4d5d4d4d4cfcabf9f80cbfafbfcfcfc +fbfcfcfcfcfbfcfcfcfcf0b45b3c3a3b3a3738396488a6bfccd3d4d5d5d5d5d5d5d5d5d5d5d5d5 +d4d4d4d4d3d1ccc1b5947871 +94aebfcdd2d3d4d4d4d4d4d4d5d4d4d4d4d4d4d4d4d4d4d5d5d4d4d4d0c6bda6835a8ad1eff7fb +fcfbfcfcfbfaf3e7c5935a3f373a3b3b3b3b3b3d6b8ba7becbd2d5d5d5d5d5d5d5d5d5d5d5d4d4 +d5d4d4cec7c0b5a280727373 +a4afbdc8d1d2d2d3d4d3d4d4d5d4d4d4d4d4d4d4d4d4d4d4d5d4d4d4d1c8bca98d693b3d5c7e93 +a7aea0988f7c5e4b3d3b3a38383b3b3b3b3b3a43708ea7bdcad2d5d5d5d5d5d5d5d5d5d5d4d2d1 +d2d1c8bbb09a7f7372727272 +a3abb7bfc8cbcdcecfd0d2d4d3d4d4d4d4d4d4d4d4d4d4d5d5d4d5d4d0c8bca78f75473839383d +3d3a39373836353a383b37373b3a3a393a3a38477590a6bac9d2d4d5d5d5d4d4d4d5d4d4d0ccca +c6bdb1947971727272737272 +9aa5aaafb7bcbfc0c3c5c6cacccfd0d1d2d3d3d4d4d4d4d5d5d4d4d3cec3b6a28b7b553939393a +393939393939393939393939393a393a3a393947768fa3b5c3cfd4d4d4d4d4d4d2d2d1cbc5bfbb +b19b80737172727272727272 +7a91989da0a2a7abafb2b6b7bcc0c4c6c9cdd0d2d4d4d4d4d4d4d4d1c8bba9988a7c593a3a3a3a +3a393a3a3a3a3a3a3a3a3a3a3a3938393a3a3a4a768a9daebdc9d0d2d3d3d2d2d0cdc7bfb8b2a6 +8a7371717171727272727272 +7172757a838c91979c9fa4a4a6a9aeb1b6bac1c7cdcfd1d2d1d1d1cbbfb09e8f857958383a3839 +3b3b3b3b3c3b3b3c3b3b3b3b3b3a3837383a394c738596a5b5bfc9ced0d1d0cdc7bfbbafa49a7b +727172727272727272727272 +727273727272747c858b90949496999b9fa4acb3b9bec3c8cbcac4bbafa393867d734e3c404141 +4b555858585858585858585857554d454543404d7082909daab6c0c5c7c8c6beb8b2a89b8a7571 +727272727272727272727272 +7372727272727171727274797d8185898d90959ba2a6abb0b6b6b0a89c92867e776547656f7372 +707172727272727272727272727174736f6f66656c7e8a959fa6aeb3b4b4b1aaa49d9382727272 +727272727272727272727272 +727271717271717171727271717273767b7d82898e9195989b9b98928a837e7972616470727172 +72727171717171717172727272727272727171706d76828e979b9da0a1a19f9b968d7c73727271 +717272727272727272727272 +72727272717171717171717172717170717172767d81868788878683807c776f6e727271717171 +7171717171717171717272727272727272727271706f79838c9192959595938d84787171717272 +727272727272727272727272 +7272727271717171717171717271717171737372727375767a7c7d7b79746e6d72737271717171 +7171717171717171717272727272727272727271726e6f737c8285888786837974727172717272 +727272727272727272727272 +7272727271717171717171717271717171727272727272707273706f6f71707272727271717171 +71717271717171717172727272727272727272727272716e6f6f72757372727172717172727272 +727272727272727272727272 +showpage +%%Trailer +end +%%EOF diff --git a/contrib/mom/examples/sample_docs.mom b/contrib/mom/examples/sample_docs.mom new file mode 100644 index 0000000..f9b2933 --- /dev/null +++ b/contrib/mom/examples/sample_docs.mom @@ -0,0 +1,713 @@ +.\" -*- mode: text; coding: utf-8; -*- +\# +\# Copyright (C) 2004-2020 +\# +\# Copying and distribution of this file, with or without modification, +\# are permitted in any medium without royalty provided the copyright +\# notice and this notice are preserved. +\# +\# This file contains three greeked documents collated together: +\# +\# i) two pages of a novelist's outline +\# ii) two pages of a chapter using COPYSTYLE DRAFT +\# iii) three pages of an academic paper, set in two columns +\# +\# Mom's defaults are used throughout, except for iii), which +\# demonstrates some of the ways you can design your own documents. +\# +\# Since the text throughout is greeked, and groff doesn't know how +\# to hyphenate all that pseudo-latinate nonsense, I've inserted +\# discretionary hyphens (\%) into a large number of the words. +\# Normally, this isn't necessary. +\# +\# The PRINTSTYLE is TYPESET. If you'd like to see what mom does +\# with the documents when the PRINTSTYLE is TYPEWRITE, change +\# PRINTSTYLE TYPESET, below, to PRINTSTYLE TYPEWRITE and re-run with +\# +\# pdfmom -Tps sample_docs.mom > sample_docs.pdf +\# +\# =================================================================== +\# +\# First, a sample NAMED document--in this case, an outline. +\# A novelist wouldn't normally write an outline with numbered +\# subheads and paraheads. I've turned the feature on merely to +\# demonstrate it. +\# +\# Information for the cover pages +\# +\# Title, subtitle and copyright for the document cover. +\# +.TITLE DOC_COVER \ + "Sample mom documents" +.SUBTITLE DOC_COVER \ + "Three types of mom documents" \ + "assembled and collated" \ + "by mom's author" +.COPYRIGHT DOC_COVER \ + "2015 Peter Schaffter" +\# +\# What appears in the pdf viewer's window title +\# +.PDF_TITLE "Sample mom documents" +\# +\# Reference macros (metadata) for the first section of the collated +\# document. +\# +.TITLE "Lake Attica's Shores" +.SUBTITLE "A Romance Novel" +.AUTHOR "Rosemary Winspeare" +.COPYRIGHT "2015 Alma Podborski" +\# +\# What to put on the cover for the whole document (in mom-speak, +\# the "doc cover"). The title, subtitle, and author are what were +\# given to TITLE DOC_COVER, SUBTITLE DOC_COVER, and COPYRIGHT +\# DOC_COVER. +\# +.DOC_COVER TITLE SUBTITLE COPYRIGHT +\# +\# What to put on the first document's title page (in mom-speak, the +\# "cover"). In this case, we're using the metadata from TITLE, +\# SUBTITLE, AUTHOR and COPYRIGHT, which will also be used to +\# generate the docheader (minus the copyright). +\# +.COVER TITLE AUTHOR DOCTYPE COPYRIGHT +\# +\# Docstyle macros (templates) +\# +.DOCTYPE NAMED "Outline" +.PRINTSTYLE TYPESET +.PAPER LETTER +\# +\# Here we style the covers a bit. +\# +.DOC_COVER_TITLE_STYLE \ + SIZE +8 \ + SMALLCAPS \ + UNDERLINE 1 3p +.DOC_COVER_SUBTITLE_STYLE \ + FONT I \ + SIZE +2 \ + LEAD 18 \ + SPACE .75v +.DOC_COVER_COPYRIGHT_SIZE -.5 +\# +.COVER_TITLE_SIZE +5 +.COVER_ATTRIBUTE_STYLE \ + SIZE +2 \ + SPACE .25v +.COVER_AUTHOR_STYLE \ + SIZE +2 \ + LEAD 18 +.COVER_DOCTYPE_STYLE \ + SIZE +4 \ + UNDERLINE DOUBLE 1 +.COVER_COPYRIGHT_SIZE -.5 +\# +\# Here we style the docheader a bit. +\# +.SUBTITLE_SPACE .25v +.DOCTYPE_UNDERLINE 1 2p +\# +\# Styles for nested heading levels +\# +\# The first two instances of level-1 headings will be paragraph heads +\# so we set the paragraph head style here, then change it when +\# level-1 headings become main heads. +\# +.HEADING_STYLE 1 \ + FONT BI \ + SIZE +.75 +.HEADING_STYLE 2 \ + FONT B \ + SIZE +.5 \ + BASELINE_ADJUST \n[.v]/8 \" ie 1/8 the leading +\# +.AUTO_RELOCATE_TOC \" Move table of contents to the top of the doc +.SPACE_TOC_ITEMS \" Prettify TOC spacing +\# +\# Begin the document +\# +.START +\# +.PP +.HEADING 1 PARAHEAD "A note on the setting" +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam +nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna ali\%quyam erat, +sed diam voluptua. Stet clita kasd gubergren, no sea takimata sanctus est. +At vero eos et accusam et justo duo do\%lo\%re et ea rebum. +.PP +Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum +dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod +tempor invidunt ut labore et do\%lo\%re magna ali\%quyam erat, sed diam +voluptua. +.PP +Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt +ut labore et do\%lo\%re magna ali\%quyam erat, sed diam voluptua. At +vero, eos et accusam et justo duo do\%lo\%res et ea rebum. Consetetur +sadipscing elitr, sed diam nonumy. +.LINEBREAK +.PP +.HEADING 1 PARAHEAD "About historical personnages" +At vero eos et accusam et justo duo do\%lo\%res et ea rebum. Stet clita +kasd gubergren, no sea takimata sanctus est. Tempor invidunt ut +labore et do\%lo\%re magna ali\%quyam erat, sed diam voluptua. +.PP +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam +nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna ali\%quyam erat, +sed diam voluptua. Consetetur sadipscing elitr, sed diam nonumy +eirmod tempor invidunt ut labore et do\%lo\%re magna. Tempor invidunt +ut labore et do\%lo\%re magna ali\%quyam erat, sed diam voluptua. +\# +\# Change level-1 style and add numbering to levels 1 and 2 +\# +.HEADING_STYLE 1 \ + FONT B \ + SIZE +1.5 \ + CAPS \ + UNDERSCORE .5 2p \ + QUAD C \ + NO_SPACE_AFTER \ + BASELINE_ADJUST +0 \ + NUMBER +.HEADING_STYLE 2 NUMBER +\# +.HEADING 1 "Part One" +.HEADING 2 "Chapter 1" +.PP +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, +sed diam nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna +ali\%quyam erat, sed diam voluptua. At vero eos et accusam et +justo duo do\%lo\%res et ea rebum. +.PP +At vero eos et accusam et justo duo do\%lo\%res et ea rebum. Stet clita +kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit +amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor +invidunt ut labore et do\%lo\%re magna ali\%quyam erat, sed diam voluptua. +Stet clita kasd gubergren, no sea takimata sanctus est. +.HEADING 2 "Chapter 2" +.PP +Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum +dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod +tempor invidunt ut labore et do\%lo\%re magna ali\%quyam erat, sed diam +voluptua. At vero eos et accusam et justo duo do\%lo\%res et ea rebum. +.PP +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, +sed diam nonumy eirmod tempor invidunt. Ut labore et do\%lo\%re magna +ali\%quyam erat, sed diam voluptua at vero. +.HEADING 2 "Chapter 3" +.PP +Eos et accusam et justo duo do\%lo\%res et ea rebum. Stet clita kasd +gubergren, no sea takimata sanctus est lorem ipsum dolor sit amet. +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam +nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna ali\%quyam erat, +sed diam voluptua. At vero eos et accusam et justo duo do\%lo\%res et +ea rebum. +.HEADING 1 "Part Two" +.HEADING 2 "Chapter 4" +.PP +Stet clita kasd gubergren, no sea takimata sanctus est +lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur +sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore +et do\%lo\%re magna ali\%quyam erat, sed diam voluptua. +.PP +At vero eos et accusam et justo duo do\%lo\%res et ea rebum. Stet clita +kasd gubergren, no sea takimata sanctus est lorem ipsum dolor sit amet. +.PP +Nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna ali\%quyam erat, +sed diam voluptua. At vero eos et accusam et justo duo do\%lo\%res et +ea rebum. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, +sed diam nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna +ali\%quyam erat, sed diam voluptua. At vero eos et accusam et justo +duo do\%lo\%res et ea rebum. Stet clita kasd gubergren, no sea takimata +sanctus est lorem ipsum dolor sit amet. Consetetur sadipscing elitr, +sed diam nonumy eirmod tempor invidunt. +.HEADING 2 "Chapter 5" +.PP +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed +diam nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna +ali\%quyam erat, sed diam voluptua. At vero eos et accusam et +justo duo do\%lo\%res et ea rebum. Stet clita kasd gubergren, +no sea takimata sanctus est lorem ipsum dolor sit amet. +.PP +Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt +ut labore et do\%lo\%re magna ali\%quyam erat, sed diam voluptua. At vero +eos et accusam et justo duo do\%lo\%res et ea rebum. Stet clita kasd +gubergren, no sea takimata sanctus. +.PP +At vero eos et accusam et justo duo do\%lo\%res et ea rebum. Stet clita +kasd gubergren. Sea takimata sanctus est lorem ipsum dolor +sit amet. Accusam et justo duo do\%lo\%res et ea rebum. Diam +nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna. +.RIGHT +\*[BD]\&...end of sample outline\c +.EL +.COLLATE +\# +\# The '\c /.EL' keeps mom from depositing a line break which, +\# because "...end of sample outline" falls exactly on the last +\# baseline of the page, would spring the page trap that sets a +\# header at the top of the next page. Since the next page is a +\# title page, we don't want that. Normally, this isn't required, +\# although using it routinely before COLLATE is a good habit. +\# +\# Notice, too, the use of "\&" before "..." Whenever an input line +\# begins with either a period, an apostrophe or a space, you must +\# precede it with \&, otherwise the line will disappear, even when, +\# as here, there's an inline escape beforehand. +\# +\# ===================================================================== +\# +\# Next, a document composed of two pages of a chapter, set in DRAFT +\# style, showing the use of the EPIGRAPH BLOCK macro and the QUOTE +\# macro. +\# +\# You'll notice that the starting page number of this "draft" is 1 (in +\# roman numerals). COPYSTYLE DRAFT always numbers the first page of a +\# document 1. +\# +.TITLE "Lake Attica's Shores" +.SUBTITLE "A Romance Novel" +.AUTHOR "Rosemary Winspeare" +.CHAPTER 1 +.CHAPTER_TITLE "The Bonny Blue Yonder" +.DRAFT 1 +.REVISION 2 +.MISC "Draft 1, 2nd revision" +\# +.DOCTYPE CHAPTER +.COPYSTYLE DRAFT +\# +.EPIGRAPH_FONT I \" Epigraphs are normally set in roman +.DRAFT_WITH_PAGENUMBER \" Draft/revision info usually goes in the header +\# +\# Style the title page +\# +.COVER_CHAPTER_SIZE +6 +.COVER_CHAPTER_TITLE_STYLE \ + SIZE +5 \ + SPACE .25v +.COVER_MISC_SIZE -.25 +\# +\# What goes on the title page +\# +.COVER CHAPTER+TITLE MISC +\# +\# Begin the document +\# +.CHAPTER_SIZE +3.5 +.CHAPTER_TITLE_SIZE +5 +.CHAPTER_TITLE_SPACE +3p +.START +.EPIGRAPH BLOCK +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam +nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna ali\%quyam erat, +sed diam voluptua. +.RIGHT +\# +\# If running PRINTSTYLE TYPEWRITE, this adds space before +\# attribution ("Joseph E. Blough") +\# +.if \n[#PRINT_STYLE]=1 .sp +\# +\*[ROM]\[em]Joseph E. Blough +.EPIGRAPH OFF +.PP +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam +nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna ali\%quyam erat, +sed diam voluptua. At vero eos et accusam et justo duo do\%lo\%res et +ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. +At vero eos et accusam et justo duo do\%lo\%res et ea rebum. Lorem ipsum +dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod +tempor invidunt ut labore et do\%lo\%re magna ali\%quyam erat, sed diam +voluptua. At vero eos et accusam et justo duo do\%lo\%res et ea rebum. +Stet clita kasd gubergren, no sea takimata sanctus est. At vero eos +et accusam et justo duo do\%lo\%res et ea rebum. +.PP +Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum +dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod +tempor invidunt. +.PP +"Consetetur sadipscing elitr," dixit ea. +.PP +"Sed diam nonumy eirmod tempor invidunt ut labore," dixit eum. +.PP +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam +nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna ali\%quyam erat, +sed diam voluptua. Consetetur sadipscing elitr, sed diam nonumy +eirmod tempor invidunt ut labore et do\%lo\%re magna. +.PP +"Lorem ipsum dolor sit amet," dixit ea. +.PP +"At vero eos et accusam et justo duo do\%lo\%res et ea rebum. Stet clita +kasd gubergren, no sea takimata sanctus est," dixit eum. "Sed diam +nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna ali\%quyam erat, +sed diam voluptua." +.PP +Consetetur sadipscing elitr, sed diam nonumy eirmod tempor: +.QUOTE +Invidunt ut labore et do\%lo\%re +Magna ali\%quyam erat sed diam +Voluptua stet clita kasd gubergren +No sea takimata sanctus est. +.QUOTE OFF +.PP +Justo duo do\%lo\%res et ea rebum. Stet clita kasd gubergren, no +sea takimata sanctus est. Lorem ipsum dolor sit amet, consetetur +sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore +et do\%lo\%re magna ali\%quyam erat, sed diam voluptua. +.PP +"Stet clita kasd gubergren," dixit ea. +.PP +"No sea takimata sanctus est," dixit eum. +.PP +Nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna. Aliquyam erat +sed diam voluptua. At vero eos et accusam et justo, duo do\%lo\%res et +ea rebum. +.PP +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam +nonumy eirmod tempor invidunt. Ut labore et do\%lo\%re magna ali\%quyam +erat, sed diam voluptua at vero. Stet clita kasd gubergren, no sea +takimata sanctus est. Consetetur sadipscing elitr, sed diam nonumy +eirmod tempor invidunt ut labore et do\%lo\%re magna. +.PP +Invidunt ut labore et do\%lo\%re magna ali\%quyam erat, sed diam voluptua. +At vero eos et accusam et justo duo do\%lo\%res et ea rebum. Stet clita +kasd gubergren, no sea takimata sanctus est. At vero eos et accusam et +justo duo do\%lo\%res et ea rebum. Lorem ipsum dolor sit amet, consetetur +sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore +et do\%lo\%re magna ali\%quyam erat, sed diam voluptua. At vero eos et +accusam et justo duo do\%lo\%res et ea rebum. Stet clita kasd gubergren, +no sea takimata sanctus est. At vero eos et accusam et justo duo +do\%lo\%res et ea rebum. +.RIGHT +\*[BD]\&...end of sample chapter\c +.EL +.COLLATE +\# +\# ===================================================================== +\# +\# Finally, a sample journal article, set in two columns with a +\# 1.5-pica gutter between them. This example also uses QUOTES, +\# BLOCKQUOTES and FOOTNOTES. In addition, it's set RECTO_VERSO, +\# with differing left and right margins that alternate from page to +\# page. (The header also flips from right to left, which you can +\# see on the 2nd and 3rd pages). +\# +\# The primary purpose of this sample is to demonstrate how to +\# create a stylesheet, along with some of the control macros that +\# can be used. +\# +\# Style the title page +\# +.COVER_TITLE_CAPS +.COVER_ATTRIBUTE_SPACE .5v +.COVER_AUTHOR_STYLE \ + SIZE +1.5 \ + LEAD 14 \ + SPACE .25v +.COVER_MISC_STYLE \ + QUAD L \ + SIZE +0 +.COVER_COPYRIGHT_SIZE +0 +\# +\# What goes on the title page +\# +.COVER TITLE AUTHOR COPYRIGHT MISC +\# +.DOCTYPE DEFAULT +.COPYSTYLE FINAL +\# +.TITLE "Control Equals Chaos" +.SUBTITLE "\*[ALD1]The Psychological and Auditory \ +Impact of Serial vs. Aleatoric Music\*[RLD1]" +.AUTHOR "Joe Chang" "and" "Brad Hegel Connors" +.COPYRIGHT "2015 J. Chang, B.H. Connors +.MISC "Submitted June 3, 2015" "\*[IT]Piano Quarterly\*[PREV]" +\# +\# Style the docheader +\# +.TITLE_CAPS +.ATTRIBUTE_SPACE .33 +.AUTHOR_SIZE +1 +.SUBTITLE_SIZE +2 +\# +.L_MARGIN 6P +.R_MARGIN 4P+6p +.PT_SIZE 10 +.AUTOLEAD 1.5 +\# +.RECTO_VERSO +.PAGENUM 1 +\# +.HEADER_LEFT "Chang, Connors" \" Because we have two authors +.HEADER_SIZE +1 +\# +.DOCHEADER_ADVANCE 1.75i +.DOCHEADER_LEAD +2p +\# +\# When PRINTSTYLE is TYPESET, these indents need to be smaller than +\# the default +\# +.if \n[#PRINT_STYLE]=2 \{\ +. PARA_INDENT 1P +. QUOTE_INDENT 2 +. BLOCKQUOTE_INDENT 2 +.\} +\# +\# Style heading 1 +\# +.HEADING_STYLE 1 \ + QUAD L \ + SIZE +0 \ + NO_NUMBER \ + NO_CAPS \ + NO_UNDERSCORE \ + NO_SPACE_AFTER \ + BASELINE_ADJUST \n[.v]/8 \" ie 1/8 of the leading +\# +\# Style the blockquotes +\# +.BLOCKQUOTE_STYLE \ + FAMILY H \ + SIZE -2 \ + AUTOLEAD 2 +\# +.COLUMNS 2 1P+6p \" Set in two columns +\# +\# Being the document +\# +.START +.PP +Lorem ipsum dolor sit amet, consetetur sadipscing elitr. Sed diam +nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna. Ali\%quyam +erat, sed diam voluptua. +.PP +At vero eos et accusam et justo duo do\%lo\%res et ea rebum. Stet clita +kasd gubergren no sea takimata. Sanctus est, lorem ipsum dolor sit +amet. Consetetur sadipscing elitr, sed diam nonumy. Eirmod tempor +invidunt ut labore et do\%lo\%re magna ali\%quyam erat. Sed diam voluptua +at vero eos et accusam et justo. +\# +.BLOCKQUOTE +Stet clita kasd gubergren, no sea takimata sanctus est lorem. +Ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy +eirmod tempor. Invidunt ut labore et do\%lo\%re magna ali\%quyam erat, +sed diam voluptua at vero. Eos et accusam et justo duo do\%lo\%res et +ea rebum stet clita.\c +.FOOTNOTE \" Note the use of \c, above, to keep the word and footnote marker together. +Clita ipsum dolor sit amet, consetetur sadipscing elitr. +.FOOTNOTE OFF +.BLOCKQUOTE OFF +\# +.PP +Duo do\%lo\%res et ea rebum, stet clita kasd gubergren. No sea takimata +sanctus est lorem ipsum dolor sit amet, consetetur sadipscing elitr. +Sed diam nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna +ali\%quyam. Erat sed diam voluptua at. Vero eos et accusam et justo +duo do\%lo\%res et ea rebum stet. Clita kasd gubergren no sea takimata +sanctus est. +.PP +Nonumy eirmod tempor invidunt, ut labore et do\%lo\%re magna ali\%quyam +erat? At vero eos et accusam et justo duo do\%lo\%res et ea. Rebum stet +clita kasd gubergren no sea takimata sanctus. Est lorem ipsum dolor +sit amet. Sadipscing\c +.FOOTNOTE +Sadipscing diam nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna +ali\%quyam erat, sed diam voluptua. +.FOOTNOTE OFF + elitr sed diam nonumy eirmod tempor invidunt. Ut labore et do\%lo\%re +magna ali\%quyam erat, sed diam voluptua. At vero eos et accusam et +justo duo do\%lo\%res et ea rebum. Stet clita kasd gubergren no sea. +\# +.HEADING 1 "Schoenberg \[em]" "The Origins of Serial Pitch Organization" +\# +.PP +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam +nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna ali\%quyam erat, +sed diam voluptua. At vero eos et accusam et justo duo do\%lo\%res et ea +rebum. Stet clita kasd gubergren, no sea takimata sanctus est lorem. +Ipsum dolor sit amet consetetur sadipscing. Elitr, sed diam nonumy, +eirmod tempor invidunt ut labore et do\%lo\%re magna. Ali\%quyam erat sed +diam voluptua, at vero eos. Et accusam et justo duo do\%lo\%res et ea +rebum stet clita kasd gubergren lorem ipsum. Dolor sit amet +consetetur, sadipscing elitr, sed diam. Nonumy eirmod tempor invidunt +ut labore et do\%lo\%re. Magna ali\%quyam erat sed diam voluptua at vero. +Eos et accusam et justo duo do\%lo\%res et ea rebum stet clita kasd. +Gubergren no sea takimata sanctus est. +.PP +Amet consetetur sadipscing elitr sed diam nonumy eirmod. Tempor +invidunt ut labore. Et dolor\%e magna ali\%quyam erat, sed diam voluptua, +at vero. Eos et accusam et justo duo do\%lo\%res et ea rebum. Stet clita +kasd gubergren sed diam voluptua. +.PP +No sea takimata\c +.FOOTNOTE +Takimata sadipscing elitr, sed diam nonumy eirmod tempor invidunt +ut labore et do\%lo\%re magna ali\%quyam erat, sed diam voluptua. +.FOOTNOTE OFF + sanctus est lorem. Ipsum dolor sit amet, consetetur +sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore +et do\%lo\%re magna ali\%quyam erat, sed diam voluptua. At vero eos et +accusam et justo duo do\%lo\%res et ea rebum amet. Consetetur sadipscing +elitr sed diam nonumy eirmod tempor invidunt ut labore, et do\%lo\%re +magna ali\%quyam erat. Sed diam voluptua, at vero, eos et accusam et +justo duo do\%lo\%res et ea rebum qua certiore. +\# +.HEADING 1 "Messiaen to Stockhausen \[em]" "The Quest for Absolute Control" +\# +.PP +Vero eos et accusam et justo duo do\%lo\%res et ea rebum amet: +\# +.QUOTE +Eirmod tempor invidunt +Ut labore et do\%lo\%re magna ali\%quyam erat +Sed diam voluptua +At vero eos et accusam et justo duo do\%lo\%res. +.QUOTE OFF +\# +Lorem ipsum dolor sit amet, consetetur sadipscing elitr +sed diam. Nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna. +Aliquyam erat, sed diam voluptua at vero eos et accusam. Et +justo duo do\%lo\%res et rebum. +.PP +Elitr sed diam nonumy eirmod tempor. Invidunt ut labore et do\%lo\%re +magna ali\%quyam erat sed. Diam voluptua at vero eos et accusam et +justo duo do\%lo\%res et ea rebum. +\# +.BLOCKQUOTE +Sanctus est lorem ipsum dolor sit amet, consetetur sadipscing. Elitr, +sed diam nonumy eirmod tempor, invidunt ut labore et do\%lo\%re magna +ali\%quyam. Erat sed diam voluptua, at vero eos et accusam et justo +rebum amet. Consetetur sadipsc\%ing elitr sed diam nonumy eirmod +sed diam nonumy, eirmod tempor. Invidunt tempor invidunt ut labore.\c +.FOOTNOTE +Labore diam nonumy eirmod tempor, invidunt ut labore et do\%lo\%re +magna ali\%quyam. Erat sed diam voluptua, at vero eos et accusam et +justo. +.FOOTNOTE OFF + Et do\%lo\%re et magna ali\%quyam erat, sed diam voluptua, at vero. +Eos et accusam et justo duo. +.BLOCKQUOTE OFF +\# +.PP +Lorem ipsum dolor sit amet, consetetur sadipscing elitr. Sed diam +nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna. +.PP +Nonumy eirmod tempor invidunt, ut labore et do\%lo\%re magna ali\%quyam +erat? At vero eos et accusam et justo duo do\%lo\%res et ea. Rebum stet +clita kasd gubergren no sea takimata sanctus. Est lorem ipsum dolor +sit amet. Sadipscing elitr sed diam nonumy eirmod tempor invidunt. +Ut labore et do\%lo\%re magna ali\%quyam erat, sed diam voluptua. +At vero eos et accusam et justo duo do\%lo\%res et ea rebum. +Stet clita kasd gubergren no sea. Ali\%quyam erat, sed diam voluptua. +\# +.HEADING 1 "John Cage \[em]" "Leaving It All to Chance" +\# +.PP +Sit amet, consetetur sadipscing elitr, sed diam nonumy. Eirmod tempor +invidunt ut labore et do\%lo\%re magna. Ali\%quyam erat, sed diam +voluptua at vero. Eos et accusam et justo duo dolores et ea rebum. +Stet clita kasd gubergren, no sea taki\%mata sanctus est. +.PP +Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt +ut labore et do\%lo\%re magna ali\%quyam erat, sed diam voluptua. At vero +eos et accusam et justo duo do\%lo\%res et ea rebum. Stet clita kasd +gubergren, no sea takimata sanctus est lorem. Ipsum dolor sit amet, +consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt +ut labore et do\%lo\%re magna ali\%quyam erat, sed diam voluptua. At vero +eos et accusam et justo duo do\%lo\%res et ea rebum. +.PP +Stet clita kasd gubergren. No sea takimata sanctus est lorem ipsum +dolor sit. Amet consetetur sadipscing elitr, sed diam nonumy eirmod +tempor. Invidunt ut labore et do\%lo\%re magna ali\%quyam erat, sed diam +voluptua, at vero. Eos et accusam et justo duo do\%lo\%res et ea rebum. +Stet clita kasd gubergren, no sea takimata. Sanctus est lorem ipsum +dolor sit amet consetetur. Sadipscing elitr sed diam nonumy eirmod +tempor invidunt. Ut labore et do\%lo\%re magna ali\%quyam erat, sed diam +voluptua. At vero eos et accusam et justo duo do\%lo\%res et ea rebum. +\# +.BLOCKQUOTE +.PP +Stet clita kasd gubergren no sea. Takimata sanctus est lorem ipsum +dolor sit amet. Consetetur sadipscing elitr sed diam nonumy eirmod +tempor invidunt ut labore et do\%lo\%re. Magna ali\%quyam\c +.FOOTNOTE +Aliquyam nonumy eirmod tempor invidunt ut labore. +.FOOTNOTE OFF + erat, sed diam +voluptua at vero eos et accusam. Et justo duo do\%lo\%res et ea rebum, +stet clita kasd gubergren, no sea takimata. +.PP +Takimata lorem ipsum dolor sit amet consetetur sadipscing elitr. +Sed diam, nonumy eirmod tempor, invidunt ut labore et do\%lo\%re magna. +Aliquyam erat sed diam voluptua. At vero eos et accusam et +justo.\c +.FOOTNOTE +Justo vero eos et accusam et justo duo. +.FOOTNOTE OFF +.BLOCKQUOTE OFF +\# +.PP +Duo do\%lo\%res et ea rebum, stet clita kasd gubergren, no sea takimata +sanctus. Est lorem ipsum. Dolor sit amet, consetetur sadipscing elitr, +sed diam nonumy. Eirmod tempor invidunt ut labore et do\%lo\%re magna +ali\%quyam erat, sed diam voluptua. At vero eos et accusam. +.PP +Et justo duo do\%lo\%res et ea rebum stet clita kasd. Gubergren +no sea takimata sanctus est. Lorem ipsum dolor sit amet, consetetur +sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore +et dolore magna ali\%quyam erat, sed diam voluptua. At vero eos et +accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, +no sea takimata sanctus est. +\# +.HEADING 1 "Beyond Cage \[em]" "Catching the Midnight Train" +\# +.PP +Lorem ipsum dolor sit amet, consetetur sadipscing elitr. Sed diam +nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna. Ali\%quyam +erat, sed diam voluptua. +.PP +At vero eos et accusam et justo duo do\%lo\%res et ea rebum. Stet clita +kasd gubergren no sea takimata. Sanctus est, lorem ipsum dolor sit +amet. Consetetur sadipscing elitr, sed diam nonumy. Eirmod tempor +invidunt ut labore et do\%lo\%re magna ali\%quyam erat. Sed diam voluptua +at vero eos et accusam et justo. +.PP +Duo do\%lo\%res et ea rebum, stet clita kasd gubergren. No sea takimata +sanctus est lorem ipsum dolor sit amet, consetetur sadipscing elitr. +Sed diam nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna +ali\%quyam. Erat sed diam voluptua at. Vero eos et accusam et justo +duo do\%lo\%res et ea rebum stet. Clita kasd gubergren no sea takimata +sanctus est. +.PP +Nonumy eirmod tempor invidunt, ut labore et do\%lo\%re magna ali\%quyam +erat? At vero eos et accusam et justo duo do\%lo\%res et ea. Rebum stet +clita kasd gubergren no sea takimata sanctus. Est lorem ipsum dolor +amet. Sadipscing\c +.FOOTNOTE +Sadipscing diam nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna +ali\%quyam erat, sed diam voluptua. +.FOOTNOTE OFF + elitr sed diam nonumy eirmod tempor invidunt. Ut labore et do\%lo\%re +magna ali\%quyam erat, sed diam voluptua. At vero eos et accusam et +justo duo do\%lo\%res et ea rebum. Stet clita kasd gubergren no sea +takimata lorem. Ipsum dolor sit amet, consetetur sadipscing elitr. +Sed diam nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna. +Ali\%quyam erat, sed diam voluptua. At vero eos et accusam et justo +duo do\%lo\%res et ea rebum. Stet clita kasd gubergren, no sea +takimata sanctus est. +.PP +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed +diam nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna +ali\%quyam erat, sed diam voluptua. At vero eos et accusam et justo +duo do\%lo\%res et ea rebum. Stet clita kasd gubergren, no sea +takimata sanctus est. +.RIGHT +\*[BD]\&...end of sample article\*[PREV] +.FINIS +.TOC_RV_SWITCH +.TOC +.\" Local Variables: +.\" mode: nroff +.\" End: +.\" vim: filetype=groff: diff --git a/contrib/mom/examples/slide-demo.mom b/contrib/mom/examples/slide-demo.mom new file mode 100644 index 0000000..989ce5a --- /dev/null +++ b/contrib/mom/examples/slide-demo.mom @@ -0,0 +1,438 @@ +.\" -*- mode: text; coding: utf-8; -*- +\# +\# Copyright (C) 2004-2020 Free Software Foundation, Inc. +\# Revised for version 2.5 2021-08. +\# +\# Copying and distribution of this file, with or without modification, +\# are permitted in any medium without royalty provided the copyright +\# notice and this notice are preserved. +\# +.\" Macro for code blocks +.de CODE_BLOCK +. ie \\n[.$] \{\ +. CODE off +. QUOTE off +. CENTER_BLOCK off +. \} +. el \{\ +. CENTER_BLOCK +. QUOTE +. CODE +. \} +.. +.\"---------------------------------------------------------------- +. +.TITLE "Creating slide presentations with gropdf/mom" +.PDF_TITLE "\*[$TITLE]" +. +.DOCTYPE SLIDES \ + ASPECT 16:9 \ + HEADER "Header left" "\*[$TITLE]" "Header right" \ + FOOTER "" "" "\*S[+2]\*[SLIDE#]\*S[-2]" \ + TRANSITION "Box 1 . O" \ + PAUSE "Wipe 1" +. +.PARA_SPACE .75v +.SS +3 +.HYPHENATION off +. +.NEWCOLOR darkred #aa0000 +.NEWCOLOR darkred1 #900000 +.NEWCOLOR blue1 #00007b +.NEWCOLOR blue2 #00006f +.NEWCOLOR code-grey GRAY 0.3 +.XCOLOR cyan4 +.XCOLOR green4 +. +.HEADER_COLOR darkred1 +.HEADER_RULE_COLOR blue1 +.FOOTER_RULE off +. +.COVER_STYLE \ + LEAD +8 \ + COLOR white +.HEADING_STYLE 1 \ + COLOR blue2 +.CODE_STYLE \ + FONT B \ + SIZE 115 \ + COLOR code-grey +.QUOTE_STYLE \ + QUAD LEFT +.CONDENSE 90 +. +.PDF_IMAGE_FRAME "" 1 blue1 +. +.COVERTITLE \ + "Creating slide presentations" \ + "with" \ + "gropdf and mom" +. +.COVER_START_POS 15P +.COVER COVERTITLE +. +.STRING hand \*[darkred]\[rh]\*[black] +. +.\" Make first slide black. +.\" If printing, remove to save ink. +.SLIDE_COLOR black +. +.START +.SLIDE_COLOR off +. +.ADD_SPACE 9p +.IB 8P +. +.HEADING 1 "PDF slides" +.SP .5v +. +.PP +PDF slides are a subset of mom's document processing macros +formatted for presentation mode when viewed in a PDF reader. In +most respects, they behave identically to the default document type +described in mom's html documentation\*[HANG .] +.BR +Differences in the formatting include\*[HANG :] +. +.PAUSE +.LEFT +.LIST +.ITEM .2v +the choice between two aspect ratios, 4:3 or 16:9 +.LIST USER \*[hand] +.ITEM +both fit on A4 or US letter paper sizes when printed +. +.PAUSE +.LIST BACK +.ITEM .2v +type is set centered by default +.LIST USER \*[hand] +.ITEM +this may be changed to left, right, or justified +. +.PAUSE +.LIST BACK +.ITEM .2v +headers and/or footers must be explicitly instantiated +.LIST USER \*[hand] +.ITEM +the left, centre, and right parts must be supplied +by the user +. +.PAUSE +.LIST BACK +.ITEM .2v +slide numbering (pagination) is disabled +.LIST USER \*[hand] +.ITEM +if slide numbering is desired, it must be put in the left, +centre, or right part of a header or footer definition +.QUIT_LISTS +. +.NEWSLIDE +. +.ADD_SPACE 9p +.IB 2P +. +.DOC_QUAD CENTER +. +.HEADING 1 "Pauses and transitions" +.SP .5v +. +.PP +Slides made with mom take advantage of the pause and slide +transition features provided in presentation mode by most +contemporary PDF readers. +.PAUSE +.PP +Pauses and transitions are dynamic and engaging, holding the +viewer's attention while increasing the impact of the content. +.PAUSE +.PP +With pauses, material on a slide can be revealed progressively +with +.BR +a mouse click or by hitting +. +.LIST +.ITEM .5v +Next +.ITEM 2p +PgDown +.ITEM 2p +Spacebar +.LIST off +. +.PAUSE +.PP +The manner in which new material is revealed and new slides +are displayed can be tailored separately for effects like Fade, +Dissolve, Wipe and others, and can be changed on the fly. +. +.NEWSLIDE +. +.PP +Mom slides begin with the macro DOCTYPE SLIDES, where you choose +the aspect ratio and transition effects, and set up headers and +footers\*[HANG .] +.PAUSE +.PP +You may find it convenient to provide a title for the slide +presentation, as the top of the .mom file for these slides +demonstrates\*[HANG :] +. +.SP -1v +.CODE_BLOCK +\*[COND]\&.TITLE "Creating slide presentations with gropdf/mom" +\&.PDF_TITLE "\\*[$TITLE]" +\&.\\" +\&.DOCTYPE SLIDES \\ + ASPECT 16:9 \\ + HEADER "Header left" "\\*[$TITLE]" "Header right" \\ + FOOTER "" "" "\\*S[+2]\\*[SLIDE#]\\*S[-2]" \\ + TRANSITION "Box 1 . O" \\ + PAUSE "Wipe 1"\*[CONDX] +.CODE_BLOCK off +.SP -.5v +. +.PAUSE +.PP +Afterwards, you may make any changes you like to the layout and +style, then enter START. Unlike other mom documents, PRINTSTYLE is +not required\*[HANG .] +. +.NEWSLIDE +. +.ADD_SPACE 9p +.IB -1P+6p +. +.HEADING 1 \ + "The \s[-2]PAUSE\s[0] and \s[-2]NEWSLIDE\s[0] macros" +.SP .5v +. +.PP +Whenever you want a pause before revealing the next material on a +slide, enter the macro PAUSE on a line by itself. If you want a +reveal effect that's different from the current one, you may pass +PAUSE the parameters of the new effect\*[HANG :] +. +.SP -1v +.PAUSE +. +.CODE_BLOCK +\&.PAUSE "Dissolve .4" +.CODE_BLOCK off +. +.PAUSE "Dissolve .4" +Notice that this material dissolves in, whereas before, new material +appeared from left to right. \*[BU6]The new effect stays in force +until you change it again\*[HANG .] +.PAUSE "Wipe 1" +.PP +New slides are introduced with NEWSLIDE. \*[bu6]Transition effects +and parameters may be given to NEWSLIDE\*[HANG :] +.SP -1v +. +.CODE_BLOCK +\&.NEWSLIDE "Blinds .5" +.CODE_BLOCK off +. +.PAUSE +The next slide in this presentation will appear with the Blinds +effect\*[HANG .] +.BR +Consult man gropdf\c +\*[FU2]\*[UP 1p](\*[DOWN 1p]\*[BU2]1\*[UP 1p]\*[BU1])\*[DOWN 1p] +for all the pause/transition effects and their +parameters.\*[BU6]\*[UP 2p]\s[-2]*\s[0] +.SP 4p +.FT I +.PT_SIZE -2 +*Note that not all PDF \*[BU6]viewers support every effect\*[HANG .] +.FT R +.PT_SIZE +2 +. +.NEWSLIDE "Blinds .5" +.SLIDE_COLOR antiquewhite +. +.ADD_SPACE 9p +. +.HEADING 1 "Highlighting items +.SP .5v +.PP +The BOX macro lets you highlight items as they are revealed with +frames and shaded backgrounds\*[HANG .] +.PAUSE "Fade .5" +.BOX SHADED pink INSET 3p +.PP +This item is highlighted with a shaded background\*[HANG .] +.PAUSE +.PP +The highlight moves to each new item as it's revealed\*[HANG .] +.PAUSE +.PP +Highlighting can continue for as many slides as you want\*[HANG .] +.PAUSE +.PP +If there are no pauses on a slide, BOX can be used +.BR +to provide a background for all the items\*[HANG .] +.PAUSE +.PP +The SLIDE_COLOR macro lets you colour +.BR +the whole slide (q.v.)\*[HANG .] +.BOX off +. +.NEWSLIDE "Box 1 . O" +.SLIDE_COLOR off +. +.ADD_SPACE 9p +. +.HEADING 1 "Macros and preprocessors" +.SP .5v +.PP +Slides can make full use of all mom's document processing and +typesetting macros, including preprocessors and image insertion\*[HANG .] +. +.IBX CLEAR +.LS -4 +. +.PAD "\ +\*[FWD 4P+6p]\*[ST1]#\*[ST1X]\ +\*[FWD 2P+6p]\*[ST2]\*[FWD 12P]\\*[ST2X]\ +\*[FWD 3P+9p]\*[ST3]#\*[ST3X]\ +\*[FWD 3P]\*[ST4]#\*[ST4X]\*[FWD 2P]" +. +.ST 1 L +.ST 2 C +.ST 3 C +.ST 4 C +. +.PAUSE "Fade .5" +. +.TAB 1 +.PT_SIZE -1.5 +.CENTER +\*[BD]\*[blue2]\*[DOWN 6p]tbl +.LEFT +.mk +.PT_SIZE -1 +.COLOR blue2 +.TS H BOXED +tab(^) allbox; +c c +n n. +\*[darkred]\s[-.5]\*[DOWN .5p]Year^Mean Temp.\s[0]\*[blue2] +_ +.TH +\*[cyan4]\fB2015^28.3\*[blue2] +\*[cyan4]1998^28.3\*[blue2] +\*[cyan4]1997^28.3\*[blue2] +\*[cyan4]2010^28.1\*[blue2] +\*[cyan4]2002^28.1\*[blue2] +\*[cyan4]2005^28.0\*[blue2] +\*[cyan4]2014^27.9\*[blue2] +\*[cyan4]2009^27.9\*[blue2] +.TE +. +.rt +.PAUSE +. +.TN +.PT_SIZE +1 +\*[FWD 10p]\*[DOWN 6p]pic +.COLOR green4 +.SP 3p +.PS 2 LEFT +A: ellipse wid 0.5 ht 0.5 + arrow color "green4" up 0.2 from A.n + arrow color "green4" up 0.2 right 0.2 from A.ne + arrow color "green4" right 0.2 from A.e + arrow color "green4" down 0.2 right 0.2 from A.se + arrow color "green4" down 0.2 from A.s + arrow color "green4" down 0.2 left 0.2 from A.sw + arrow color "green4" left 0.2 from A.w + arrow color "green4" up 0.2 left 0.2 from A.nw +.PE +. +.rt +.PAUSE +. +.TN +.COLOR blue2 +\*[FWD 1p]\*[DOWN 6p]eqn +.FAMILY T +.PT_SIZE +3 +.LS +.COLOR code-grey +.SP 4P +.EQ +f sub X (x) ^=^ left { + rpile { 0 above 2x above 0 } + ~~lpile { x < 0 above 0 <= x <= 1 above x > 1 } +.EN +. +.rt +.PAUSE +. +.TN +.FAMILY H +.PT_SIZE -3 +.COLOR blue2 +\*[DOWN 6p]pdf image\*[black]\*[PREV] +.SP 2P+6p +.PDF_IMAGE -C penguin.pdf 81p 96p FRAME +.TQ +. +.NEWSLIDE "Box 1 . O" +.ADD_SPACE 5p +.IB 10P +.PT_SIZE +1.5 +. +.HEADING 1 "Printing handouts" +.SP .5v +. +.CODE_STYLE \ + COLOR BLACK \ + SIZE 120 +.PP +Because slides contain pauses, they need a little help on their +way to the printer or they stop printing at the first pause\*[HANG .] +.PAUSE "Wipe 1" +.PP +Setting GROPDF_NOSLIDE=1 before invoking +\[oq]\*[FU4]\*[CODE]\*[COND]pdfmom\*[CONDX]\*[CODE off]\*[FU4]\[cq] +or +\[oq]\*[FU2]\*[CODE]\*[COND]groff\~-Tpdf\*[CONDX]\*[CODE off]\*[FU6]\[cq] +disables the pauses\*[HANG :] +. +.SP -1v +. +.CODE_STYLE \ + COLOR code-grey \ + SIZE 110 +.CODE_BLOCK +\*[COND]GROPDF_NOSLIDE=1 pdfmom slide-file.mom\*[CONDX] +.CODE_BLOCK off +. +.PAUSE +The output may be piped directly to a printer or saved to a file\*[HANG .] +.PAUSE +.PP +See mom's html documentation and the gropdf\c +\*[FU2]\*[UP 1p](\*[DOWN 1p]\*[BU2]1\*[UP 1p]\*[BU1])\*[DOWN 1p] +manpage for complete information concerning slide usage\*[HANG .] +. +.SP 9p +.CENTER_BLOCK +.nr dcl-ind -1 1 +.while \n[dcl-ind]<4 \{\ +. DCL SOLID \n+[dcl-ind]P 9p 9p blue2 +.\} +.CENTER_BLOCK off +.\" Local Variables: +.\" mode: nroff +.\" End: +.\" vim: filetype=groff: diff --git a/contrib/mom/examples/test-mom.sh.in b/contrib/mom/examples/test-mom.sh.in new file mode 100644 index 0000000..ebaba20 --- /dev/null +++ b/contrib/mom/examples/test-mom.sh.in @@ -0,0 +1,92 @@ +#!/bin/sh +# +# Copyright (C) 2018-2020 Free Software Foundation, Inc. +# +# This file 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 . +# + +builddir="@abs_top_builddir@" +have_urw_fonts="@groff_have_urw_fonts@" +examplesdir="$builddir/contrib/mom/examples" +ret=0 +list=" + letter.pdf + mom-pdf.pdf + mon_premier_doc.pdf + sample_docs.pdf + slide-demo.pdf + typesetting.pdf + copyright-chapter.pdf + copyright-default.pdf + " + +if test "$have_urw_fonts" != "yes"; then + echo "No URW fonts, mom examples cannot be correctly generated" + exit 77 +fi + +for cmd in pdfinfo pdfimages +do + if ! command -v $cmd >/dev/null + then + echo "cannot locate '$cmd' command; skipping" >&2 + exit 77 # skip + fi +done + +# $1: pdf file +# $2: expected number of pages +check_number_pages() +{ + echo "Checking number of pages of $1" + n_pages=`pdfinfo $1 | grep Pages | awk '{ print $2}'` + if test "$n_pages" != "$2"; then + echo " Error: expected $2 pages, found $n_pages pages" + ret=255 + fi +} + +# $1 pdf file +check_has_images() +{ + echo "Checking if $1 has images" + n_lines=`pdfimages -list $1 | wc -l ` + if test $n_lines -le 2; then + echo " no images found" + ret=255 + fi +} + +for k in $list; do + if ! test -f $examplesdir/$k; then + echo "File $k not found" + exit 255 + fi +done + +check_number_pages "$examplesdir/letter.pdf" 1 +check_number_pages "$examplesdir/mom-pdf.pdf" 8 +check_number_pages "$examplesdir/mon_premier_doc.pdf" 5 +check_number_pages "$examplesdir/sample_docs.pdf" 12 +check_number_pages "$examplesdir/slide-demo.pdf" 33 +check_number_pages "$examplesdir/typesetting.pdf" 3 +check_number_pages "$examplesdir/copyright-chapter.pdf" 5 +check_number_pages "$examplesdir/copyright-default.pdf" 5 + +check_has_images "$examplesdir/typesetting.pdf" +check_has_images "$examplesdir/slide-demo.pdf" + +exit $ret diff --git a/contrib/mom/examples/typesetting.mom b/contrib/mom/examples/typesetting.mom new file mode 100644 index 0000000..e273611 --- /dev/null +++ b/contrib/mom/examples/typesetting.mom @@ -0,0 +1,707 @@ +.\" -*- mode: text; coding: utf-8; -*- +\# +\# Copyright 2004-2020 Free Software Foundation, Inc. +\# +\# Copying and distribution of this file, with or without modification, +\# are permitted in any medium without royalty provided the copyright +\# notice and this notice are preserved. +\# +\# Most mom users rely on mom's document processing macros to format +\# their work. The doc processing macros take care of all things +\# typographic and are simple, clear and easy to learn. The kind of +\# "by hand" typesetting this file demonstrates is geared towards +\# professional typographers. Bear in mind, though, that the full +\# power of mom's typesetting capabilities can be brought to bear on +\# document processing as well. +\# +\# Basic page setup +\# +.PAGE 8.5i 11i 1i 1i 1i \" Page size, margins +\# +\# Basic type parameters +\# +.FAMILY T \" Times Roman family +.FT B \" Bold font +.PT_SIZE 12 \" Point size +.LS 14 \" Leading (line spacing) +.LEFT \" Set lines flush left, nofill mode +\# +\# Refinements +\# +.HY \" Hyphenate +.KERN \" Automatic pairwise kerning +.LIGATURES \" Automatic ligature generation +.SMARTQUOTES \" Enable smartquotes +.SS 0 \" No extra space between sentences +\# +.SP |1i-1v \" Advance 1 inch from top of paper to first baseline +Example 1\*[BU 2]: +.ALD .25v \" Advance an extra 1/4 linespace +.UNDERSCORE 3.5p "T\*[BU 4]asting notes using padding, string tabs \ +and multi-columns" +\# +.SP \" Add an extra line space +\# +.FAM H \" Helvetica family +.PT_SIZE 10 +.LS 11 \" New leading +\# +\# The following uses a combination of padding, string tabs, and the +\# FWD escape to set up five tabs with 1-pica gutters stretched over +\# the full line length. +\# +.SILENT \" Don't print the next line +.PAD "\*[ST1]VIN#\*[ST1X]\*[FWD 1P]\*[ST2]ROBE#\*[ST2X]\ +\*[FWD 1P]\*[ST3]NEZ#\*[ST3X]\*[FWD 1P]\*[ST4]BOUCHE#\*[ST4X]\ +\*[FWD 1P]\*[ST5]COMMENTAIRES\*[ST5X]" +.SILENT OFF \" Resume normal printing of text +\# +\# Now that the string tabs have been marked off, we "set" them. +\# +.ST 1 L \" First string tab flush left, nofill (line-for-line) mode +.ST 2 L QUAD \" Remaining tabs are flush left/rag right, fill mode +.ST 3 L QUAD +.ST 4 L QUAD +.ST 5 L QUAD +\# +.TAB 1 \" Call first tab +.UNDERSCORE "VIN" +.TN \" Move to next tab and stay on the same baseline +.UNDERSCORE "ROBE" +.TN \" Ibid +.UNDERSCORE "NEZ" +.TN \" Ibid +.UNDERSCORE "BOUCHE" +.TN \" Ibid +.UNDERSCORE "COMMENTAIRES" +.TQ \" Quit tabs +\# +.ALD 6p \" Advance an extra 6 points +.FT R \" Change font to roman (medium) +.MCO \" Turn multi-column mode on +\# +.TAB 1 \" Notice that this tab gets set line-for-line +\*[IT]Peelee Island \" Set italic +\*[PREV]GewĂźrztraminer \" Revert to former font (roman) +2000 +(Canada) +.MCR \" Return to top of column +.TAB 2 \" Call tab 2; in multi-column mode, don't use .TN +Jaune pâle. +.MCR +.TB 3 \" Notice that from here on, we use the alias TB instead of TAB +Frais, fruitĂŠ, ci\%tronnĂŠ, arĂ´mes fortes de lichee et de fruits +tropicaux. +.MCR +.TB 4 +Doux, fruitĂŠ, bien ĂŠquilibrĂŠ avec une bonne aciditĂŠ. +.MCR +.TB 5 +Bon apĂŠro. Servir avec des plats +.RW .1 \" Reduce Whitespace between letters to tighten this line +indiens ou \%chinois. +.RW 0 \" Back to normal spacing between letters +.BR +Excellent rapport qualitĂŠ/prix. +.MCX 8p \" Multi-column mode off; advance an extra 8 points +.MCO \" Re-invoke multi-columns for next wine description +.TB 1 +\*[IT]Carau Pujol +\*[ROM]Tannat +1995 +(Uraguay) +.MCR +.TB 2 +Rubis foncĂŠ, vio\%lacĂŠe, presque opaque. +.MCR +.TB 3 +Belles arĂ´mes de fruits foncĂŠs (prunes, cerises noires, cassis). +Odeurs tertiares de cuir, cèdre, violets, eucalyptus, avec une trace +exotique de Band-Aid*\*[BU 12]. +\# +\# The \*[BU 12], above, pulls the period back so that it falls +\# underneath the asterisk. \*[BP] could have been used instead +\# if you prefer to use points rather than kern units. +\# +.MCR +.TB 4 +Très rond, tannins mĂťres et veloutĂŠs, avec un long finis fruitĂŠ et +doucement alcoolique. +.MCR +.TB 5 +Superbe\|! Une aubaine Ă  ne pas manquer. PrĂŞt Ă  boire maintenant. +.MCX 1v \" Multi-columns off; advance an extra linespace +\# +\# Now, an example of a hanging indent. This is excessively fussy +\# from a typographic standpoint in that it hangs the asterisk outside +\# the current left margin so that the text following it lines up with +\# with the text in the tasting notes. Notice that in order to use a +\# hanging indent, you must first set a left indent. +\# +.FT I \" Change font to italic +.PT_SIZE -.5 \" Reduce point size by 1/2 point +.LS -.5 \" Reduce leading by 1/2 point +.JUSTIFY \" Set text justified +\# +\# Now, move the left margin back by the width of an asterisk plus 2 points... +\# +.L_MARGIN -(\w'*'+2p) +\# +\# ...and set a left indent equal to the width of an asterisk plus 2 points +\# +.IL \w'*'+2p +\# +\# Now, set the hanging indent equal to the left indent, effectively +\# pulling the first line of the following text back to the new left +\# margin. Subsequent output lines will be indented by the .IL +\# amount. Notice that when using the \w inline escape, there's no +\# need to append a unit of measure. +\# +.HI \w'*'+2p +*\*[FWD 1p]The term "Band-Aid" means the slightly sweet, vaguely chemical +smell associated with medical-grade plastics. It is often found in +wines from terroirs in South America. Provided a wine has a sufficient +concentration of fruit +.RW .04 \" Tighten the next line slightly, so "lipstick" doesn't hyphenate. +aromas and complex tertiary characteristics, Band-Aid is a Good Thing. +Otherwise, it smells like cheap lipstick. +.RW 0 \" Reset kerning to 0 +\# +\# Notice, above, that although the values for IL and HI are the width +\# of an asterisk plus 2 points, when setting the first line of text +\# (the one with the asterisk at the beginning), we put only 1 point of +\# space after the *. This is to compensate for the fact that in the +\# italic font, the letter T doesn't align visually with the rest of +\# the text. As already noted, this is an extremely fussy example. :) +\# +.IQ CLEAR \" Cancel and clear stored indent values +.L_MARGIN 1i \" Reset left margin to its original value. +\# +.ALD 2P \" Add 2-picas extra space before next example +\# +.FAM T +.FT B +.PT_SIZE 12 +.LS 14 +\# +Example 2: +.ALD .25v +\# +.COMMENT +In the next line, because the string to be underscored must be +enclosed in double-quotes, you can't use the double-quote character +itself around the word "Massaging". We circumvent this by using the +groff inline escapes \[lq] and \[rq] (leftquote and rightquote). +.COMMENT OFF +\# +.UNDERSCORE 3.5p "\[lq]Massaging\[rq] \*[BCK 1p]a passage of rag right text" +.SP \" Add an extra linespace +\# +.PT_SIZE 12.5 +.LS 14 +.PT_SIZE -1 \" Reduce point size by 1 point +Passage using groff spacing defaults +\# +.ALD .5v \" Add an extra 1/2 line space +\# +.PT_SIZE +1 \" Restore point size +.QUAD LEFT \" Set quad left, fill mode +.IB 3P \" Indent 3 picas from both the left and right margins +.FT R +The thousand injuries of Fortunato I had borne as I best could; +but when he ventured upon insult, I vowed revenge. You, who so well +know the nature of my soul, will not suppose, however, that I gave +utterance to a threat. \*[IT]At length\*[PREV] I would be +avenged; this was a point definitively settled\[em]but the very +definitiveness with which it was resolved, precluded the idea of +risk. I must not only punish, but punish with impunity. A +wrong is unredressed when retribution overtakes its redresser. +It is equally unredressed when the avenger fails to make himself +felt as such to him who has done the wrong. +.ALD 6p +\# +\# The next line is set quad right, nofill mode, 1/2 point smaller +\# than the preceding text (using the \*[SIZE ] inline escape. +\# +.RIGHT +\*[SIZE -.5]\[em]Edgar Allen Poe, \*[IT]The Cask of Amontillado\*[PREV]\*[SIZE +.5] +.SP \" Extra linespace +.IBQ \" Disable "indent both" +\# +\# The passage above, while acceptable in a longer document, exhibits a +\# few typographic flaws. The shape of the right margin rag exhibits +\# a decidedly "rounded" appearance. The word "I" stands alone at the +\# end of the third line. The space between the 1st and 2nd sentences +\# ("...revenge. You...") is too large, owing to the letter "Y" that +\# begins the 2nd sentence. The spacing between "A wrong..." (line 6) +\# is equally too large because of the way "A" and "w" fit together. +\# The em-dash before Edgar isn't vertically centered with the letter "E". +\# And so on. The most important correction below is fixing the rag +\# so that longer and shorter lines alternate. This is accomplished by +\# manually breaking lines and then slightly lengthening and shortening +\# them until a pleasing rag is achieved. The remainder of the little +\# flaws are fixed with inline escapes. +\# +.FT B +.PT_SIZE -1 +.LEFT +The same passage, \*[BU4]"massaged" +\# +.ALD .5v +\# +.FT R +.PT_SIZE +1 +.QUAD LEFT +.HY OFF \" Turn automatic hyphenation off +.BR_AT_LINE_KERN \" Automatically insert a line break (.BR) at each .RW and .EW +.WS +1 \" Increase word space slightly +.IB \" Turn "indent both" back on; values are the same as before +\# +The thousand injuries of Fortunato I had borne as I best could; +but when he ventured upon insult, I \*[BU2]vowed revenge. +\*[BU4]Y\*[BU6]ou, \*[BU4]who so \*[BU2]well know the nature +.EW .2 +of my soul, \*[BU2]will not suppose, however, that I gave utterance +to a threat. \*[IT]At +.EW .2 +length\*[PREV] I would be avenged; this was a point definitively +settled\[em]but the +.EW .2 +v\*[BU1]ery definitiveness with which it was resolved, precluded the +idea of risk. +.EW 0 +I must not only punish, but punish with impunity. A \*[BCK 1p]wrong +is unredressed +.EW .1 +when retribution overtakes its redresser. It is equally unredressed +when the +.RW .1 +avenger fails to make himself felt as such to him \*[BU 2]who has +done the wrong. +.RW 0 \" Restore normal kerning +.WS +0 \" Restore normal wordspacing +.ALD 6p +.PT_SIZE -.5 +.RIGHT +\*[UP 1.5p]\[em]\*[DOWN 1.5p]\*[BCK 1p]Edgar \*[BCK 1p]Allen Poe, \ +\*[IT]The Cask of Amontillado\*[PREV] +.IQ CLEAR \" Cancel and clear stored values of all indents +\# +.NEWPAGE \" Start a new page +.T_MARGIN 1i \" Set top margin to 1i (approx. equivalent to .ALD 1i-1v above) +\# +.FAM T +.FT B +.PT_SIZE 12 +.LS 14 +.LEFT +\# +Example 3: +.ALD .25v +.UNDERSCORE 3.5p "A \*[BU2]recipe for enumerated lists using indents" +.SP .5v \" Add an extra half line space +.ie '\*[.T]'ps' \ +.FAM N \" New Century Schoolbook family +.el .if '\*[.T]'pdf' \ +.FAM U-N +.FT R +.PT_SIZE 11 +.LS 13 +.HY \" Turn hyphenation back on +.JUSTIFY \" Justify text +This example demonstrates the use of left and hanging indents for +simple enumerated lists. Nested lists are possible, as the example +shows; however, the more complex the nesting, the wiser it becomes +to use (string) tabs, as seen in Example 4. +.DBX .5 0 \n[.l]u 2P+9p \" Draw box; \n[.l]u means "the current line length" +.IB 6p \" Indent from both left and right margins +.ALD 14p +\*[BD]Please note: mom\*[PREV] has macros that allow you to set +enumerated lists automatically. These examples merely show hanging +indents and string tabs in use. +\# +.ALD 9p +.JUSTIFY \" Justify text +.IL \w'\0.\0' \" Establish a left indent equal to 2 figure spaces plus a period. +.HI \w'\0.\0' \" Establish a hanging indent equal to the left indent. +.ALD 6p +\# +\# +1.\0This is the first item in the list. N\*[BU2]otice how the first line +"hangs" back from the remaining text, which is otherwise +indented by the width of by two figure-spaces (digit-width +spaces) and a period. +.BR +.HI \" Notice that HI doesn't require an argument once the value's set +.ALD 6p +2.\0This is the second item in the list. As with the above item, +notice the use of the \*[BU8]\\0 escape sequence in the input +text. It's there to ensure that the space after the number/period +combination always remains the same (i.e. doesn't stretch when the +line is justified). That way, the text of each item always lines up +perfectly. +\# +.COMMENT +Now we're going to set a bullet-point list, indented from the text +above by 1 pica. IL arguments are always added to whatever value +is in already effect for IL, hence all we have to do is tell mom to +indent (from the current left indent) 1 pica plus the width of the +bullet character, \[bu]. \*[FWD 3p] puts three points of space after +the bullet so that the bullet and the text are visually separated. +.COMMENT OFF +\# +\# +.IL 1P+\w'\[bu]\*[FWD 3p]' +\# +\# Hanging indents are always relative to the current left indent. +\# The additional 1-pica indent, above, already having been taken +\# care of, we only want to hang the first lines of bullet list +\# items back by the width of the bullet character plus its 3 extra +\# points of space. +\# +.ALD 6p +.HI \w'\[bu]\*[FWD 3p]' +\*[DOWN 1p]\[bu]\*[UP 1p]\*[FWD 3p]This is the first line of a +sublist with bullets. N\*[BU2]otice how the first line (the one +with the bullet) is indented exactly one pica from the text of the +list item above it, while the remaining lines align with the left +indent we set above. +.ALD 6p +.HI +\*[DOWN 1p]\[bu]\*[UP 1p]\*[FWD 3p]This is the second item of the +sublist with bullets. \*[BU4]We could go on indefinitely, but let's +go back to the top level (numbered) list... +\# +\# The easiest way to return to a previous indent value is by +\# subtraction. The argument to IL, above, was 1P+\w'[bu]\*[FWD +\# 3p]', so we just reverse it by putting a minus sign in front. +\# The parentheses are required for groff to evaluate the expression +\# properly. +\# +.IL -(1P+\w'\[bu]\*[FWD 3p]') +.HI \w'\0.\0' \" Reset hanging indent for use with numbered items. +.ALD 6p +3.\0...and here we are. +.IQ CLEAR \" Don't forget to cancel and/or clear indents! +\# +.FAM T +.FT B +.PT_SIZE 12 +.LS 14 +.LEFT +.SP +\# +Example 4: +.ALD .25v +.UNDERSCORE 3.5p "A \*[BU 2]recipe for nested lists using string tabs" +.SP .5v +.ie '\*[.T]'ps' \ +.FAM N +.el .if '\*[.T]'pdf' \ +.FAM U-N +.FT R +.PT_SIZE 11 +.LS 13 +.JUSTIFY +Although setting up string tabs is a bit more complex than setting +up indents, it's \*[BU 3]well worth the effort, especially for +nested lists. +.ALD 6p +\# +.COMMENT +The PAD line, below, sets up two string tabs. The first (ST1) is +exactly the length of two figure spaces and a period. The second +(ST2) is simply "the remainder of the line." +.COMMENT OFF +\# +.SILENT \" Don't print any of this +.PAD "\*[ST1]\0.\0\*[ST1X]\*[ST2]#\*[ST2X]" +.ST 1 L \" String tabs must be "set" after being marked off in a line +.ST 2 J \" ST 1 will be set flush left, nofill; ST 2 will be justified. +.SILENT OFF \" Restore printing +\# +.TB 1 +1.\c +.TN \" Use .TN so text stays on the same baseline +This is the first item in the list. N\*[BU 2]otice how, just as in +Example 3, the first line hangs back from the remaining text, which +is otherwise +indented. +.ALD 6p +.TB 1 +2.\c +.TN +This is the second item in the list. N\*[BU 2]otice that when +setting "lists" with tabs, there's no need to use the \*[BU 8]\\0 +escape sequence after the number/period combination in the input +text. +\# +.COMMENT +Now, set up the indented bullet-point sublist. The PAD line +says: move forward 12 points (1 pica), then mark off a string +tab (ST3) that's the length of the bullet character; move forward +another three points, then make the next string tab (ST4) the +length of remainder of the line. +.COMMENT OFF +\# +.SILENT +.PAD "\*[FWD 12p]\*[ST3]\[bu]\*[ST3X]\*[FWD 3p]\*[ST4]#\*[ST4X]" +.ST 3 L +.ST 4 J +.SILENT OFF +.ALD 6p +.TB 3 +\*[DOWN 1p]\[bu]\*[UP 1p]\c +.TN +This is the first line of a sublist with bullets. N\*[BU2]otice +how the bullets and the text line up exactly the same as in Example +3. +.ALD 6p +.TB 3 +\*[DOWN 1p]\[bu]\*[UP 1p]\c +.TN +This is the second item of the sublist with bullets. For the fun of +it, lets add in an +.SPREAD +en-dashed sub-sublist. +.BR \" We're in fill mode right now, so you must terminate the line with BR +\# +.SILENT +.PAD "\*[FWD 12p]\*[ST5]\[en]\*[ST5X]\*[FWD 4p]\*[ST6]#\*[ST6X]" +.ST 5 L +.ST 6 J +.SILENT OFF +.ALD 6p +.TB 5 +\*[UP .75p]\[en]\*[DOWN .75p]\c +.TN +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam +nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam +erat, sed diam voluptua. +.ALD 6p +.TB 5 +\*[UP .75p]\[en]\*[DOWN .75p]\c +.TN +At \*[BU 3]vero eos et accusam et justo duo dolores et ea rebum. +Stet clita kasd gubergren, no sea takimata sanctus est lorem ipsum +dolor sit amet. +.ALD 6p +.TB 1 +3.\c +.TN +And here we are, back at the top-level numbered list with a minimum +of muss and fuss, +.ALD 6p +.TB 1 +4.\c +.TN +Generally speaking, once you get the hang of string tabs and the +\*[BD]PAD\*[PREV] macro, you'll find setting up complex indenting +structures easier than with the indent macros. +.TQ +\# +.NEWPAGE +.FAM T +.FT B +.PT_SIZE 12 +.LS 14 +.RLD 2p +.LEFT +\# +Example 5: +.ALD .25v +.UNDERSCORE 3.5p "Word spacing" +.ALD 8p +.ie '\*[.T]'ps' \ +.FAM P \" Palatino family +.el .if '\*[.T]'pdf' \ +.FAM U-P +.PT_SIZE 11 +.LS 14 +\# +\# The "label" lines for the following are set in Helvetica +\# bold, one point smaller than the examples themselves. This +\# demonstrates the use of the groff inline escape \f[...] to change +\# both family and font inline. It also shows using the mom inline +\# \*S[...], which is an alternate form of the inline, \*[SIZE ] +\# +\f[HB]\*S[-1]Normal word spacing\*S[+1]\*[PREV] +.FT R +N\*[BU1]o\*[BU1]w \*[BU1]is the time for all good men to come to the aid of the party. +.ALD 4p +\f[HB]\*S[-1]Word spacing adjusted by \*[UP 1p]\*[BU3]+\*[DOWN 1p]\*[BU1]2\*S[+1]\*[PREV] +.FT R +.WS +2 +N\*[BU1]o\*[BU1]w \*[BU1]is the time for all good men to come to the aid of the party. +.WS DEFAULT +.ALD 4p +\f[HB]\*S[-1]Word spacing adjusted by \*[UP 1p]\*[BU3]+\*[DOWN 1p]4\*S[+1]\*[PREV] +.FT R +.WS +4 +N\*[BU1]o\*[BU1]w \*[BU1]is the time for all good men to come to the aid of the party. +.WS DEFAULT +.ALD 4p +\f[HB]\*S[-1]Word spacing adjusted by \*[UP 1p]\*[BU3]+\*[DOWN 1p]6\*S[+1]\*[PREV] +.FT R +.WS +6 +N\*[BU1]o\*[BU1]w \*[BU1]is the time for all good men to come to the aid of the party. +.WS DEFAULT +.SP 1.5v +\# +.FAM T +.FT B +.PT_SIZE 12 +.LS 14 +\# +.LEFT +Example 6: +.ALD .25v +.UNDERSCORE 3.5p "Line kerning" +.ALD 8p +.ie '\*[.T]'ps' \ +.FAM P \" Palatino family +.el .if '\*[.T]'pdf' \ +.FAM U-P +.FT R +.PT_SIZE 11 +.LS 15 +\# +\# Here, we set up some tabs so the examples can go into facing columns. +\# +.TAB_SET 1 0 19.5P L +.TAB_SET 2 19.5P 19.5P L +\# +.MCO \" Turn multi-columns on +.TB 1 +\f[HB]\*S[-1]Unkerned line\*S[+1]\*[PREV] +.FT R +"But this is \*[IT]important!\/"\*[PREV]she exclaimed. +.ALD 4p +\f[HB]\*S[-1]Line "tightened" \[en] .RW .1\*S[+1]\*[PREV] +.RW .1 +"But this is \*[IT]important!\/"\*[PREV]she exclaimed. +.ALD 4p +\# +\# In the next line, notice that because it uses a different family +\# (Helvetica instead of Palatino), the RW macro doesn't affect it. +\# +\f[HB]\*S[-1]Line "tightened" \[en] .RW .2\*S[+1]\*[PREV] +.RW .2 +"But this is \*[IT]important!\/"\*[PREV]she exclaimed. +.ALD 4p +\f[HB]\*S[-1]Line "tightened" \[en] .RW .3\*S[+1]\*[PREV] +.RW .3 +"But this is \*[IT]important!\/"\*[PREV]she exclaimed. +.MCR +.TB 2 +\f[HB]\*S[-1]Unkerned line\*S[+1]\*[PREV] +"But this is \*[IT]important!\/"\*[PREV]she exclaimed. +.ALD 4p +\f[HB]\*S[-1]Line "loosened" \[en] .EW .1\*S[+1]\*[PREV] +.EW .1 +"But this is \*[IT]important!\/"\*[PREV]she exclaimed. +.ALD 4p +\f[HB]\*S[-1]Line "loosened" \[en] .EW .2\*S[+1]\*[PREV] +.EW .2 +"But this is \*[IT]important!\/"\*[PREV]she exclaimed. +.ALD 4p +\f[HB]\*S[-1]Line "loosened" \[en] .EW .3\*S[+1]\*[PREV] +.EW .3 +"But this is \*[IT]important!\/"\*[PREV]she exclaimed. +.MCX 1.5v +.EW 0 +\# +.FAM T +.FT B +.PT_SIZE 12 +.LS 14 +.LEFT +\# +Example 7: +.ALD .25v +.UNDERSCORE 3.5p "Cutaround using left\*[FU 2]/right indents, \ +multi columns and a dropcap" +.SP +\# +.FT R +.PT_SIZE 11 +.LS 12 +.BR_AT_LINE_KERN OFF \" In justified text, it's best to have this OFF +\# +.TAB_SET 1 0 18.5P J +.TAB_SET 2 20.5P 18.5P J +.MCO +.ALD 5P+9p +\# +\# The little picture of tux. +\# +.if '\*[.T]'pdf' .PDF_IMAGE penguin.pdf 81p 96p +.if '\*[.T]'ps' .PSPIC penguin.ps 81p 96p +.MCR +.TAB 1 +.XCOLOR red \" Initialize the X11 color, red +.DROPCAP_COLOR red +.DROPCAP_FONT B +.DROPCAP L 3 COND 80 \" i.e. the letter L dropped 3 lines, condensed to 80% of its normal width +.EW .2 +orem ipsum dolor sit amet, consetetur sa\%dip\%scing elitr, sed diam +nonumy eir\%mod tempor invidunt ut labore et dolore magna aliquyam +erat, sed diam voluptua. +.EW 0 +.TI 1P +At vero eos et accusam et justo duo dolores et ea rebum. Stet clita +kasd gubergren, no sea taki- +.SPREAD \" Force justify preceding line before starting indent +.IR 3.5P +kimata sanctus est lorem ipsum dolor sit amet. Lorem ipsum dolor +sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod +tempor. +.EW .2 +.TI +Invidunt ut labore et dolore magna ali\%qu\%yam erat, sed diam +voluptua. At +.EW 0 +vero eos et accusam et justo duo dolores et ea rebum. +.TI +Stet clita kasd gubergren, no sea ta- +.SPREAD \" Force justify preceding line before quitting indent +.IRQ +kimata sanctus est lorem ipsum dolor sit amet. Lorem ipsum dolor +sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor +in\%vi\%dunt ut labore et dolore magna aliquyam erat. Sed diam +voluptua, at vero eos et accusam et justo duo +.SPREAD +.EW .3 +dolores et ea rebum. Stet clita no kasd guber- +.SPREAD +.MCR +.TB 2 +gren, no sea takimata sanctus est lorem ipsum +.EW 0 +dolor sit amet. Consetetur sadipscing elitr, sed diam nonumy eirmod +tempor invidunt ut labore et dolore. +.TI +Magna aliquyam erat, sed diam voluptua, at vero eos et accusam. Et +justo duo dolores et ea +.SPREAD +.IL 3.5P +rebum, stet clita kasd gubergren. No sea takimata sanctus est, +lorem ipsum dolor sit amet. +.TI +Sit amet, consetetur sadipscing elitr, sed diam. Nonumy eirmod +tempor in\%vi- +.EW .3 +dunt ut labore et dolore magna. Ali- +.EW 0 +quyam erat sed diam voluptua. At vero eos et accusam et justo duo +dolores et ea rebum stet. +.ILQ +.TI +Dolores et ea rebum stet clita kasd gubergren, no sea takimata +sanctus. Sadipscing elitr sed diam, nonumy eirmod tempor, invidunt +ut labore et dolore magna aliquyam erat. Sed diam voluptua, at vero +eos et accusam et justo duo dolores et ea rebum. +.\" Local Variables: +.\" mode: nroff +.\" End: +.\" vim: filetype=groff: diff --git a/contrib/mom/groff_mom.7.man b/contrib/mom/groff_mom.7.man new file mode 100644 index 0000000..3872b8f --- /dev/null +++ b/contrib/mom/groff_mom.7.man @@ -0,0 +1,3427 @@ +.TH groff_mom @MAN7EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +groff_mom \- modern macros for document composition with GNU +.I roff +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 2002-2020 Free Software Foundation, Inc. +.\" +.\" This file is part of mom, which is part of groff, the GNU roff +.\" type-setting system. +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, but +.\" WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +.\" General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see +.\" . +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_groff_mom_7_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.\" Setup +.\" ==================================================================== +. +.hw line-space +. +. +.\" ==================================================================== +.\" .FONT ( [ ...]) +.\" +.\" Print in different fonts: R, I, B, CR, CI, CB +.\" +.de FONT +. if (\\n[.$] = 0) \{\ +. nop \&\f[P]\& +. return +. \} +. ds result \& +. while (\\n[.$] >= 2) \{\ +. as result \,\f[\\$1]\\$2 +. if !"\\$1"P" .as result \f[P]\"" +. shift 2 +. \} +. if (\\n[.$] = 1) .as result \,\f[\\$1] +. nh +. nop \\*[result]\& +. rm result +. hy \\n[HY] +.. +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY groff +.B \-mom +.RI [ option\~ .\|.\|.\&] +.RI [ file\~ .\|.\|.] +. +.SY groff +.B "\-m mom" +.RI [ option\~ .\|.\|.\&] +.RI [ file\~ .\|.\|.] +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I mom +is a macro set for +.IR groff , +designed primarily to prepare documents for PDF and PostScript output. +. +. +.I mom +provides macros in two categories: typesetting +and document processing. +. +The former provide access to +.IR groff 's +typesetting capabilities in ways that are simpler to master than +.IR groff 's +requests and escape sequences. +. +The latter provide highly customizable markup tags that allow the user +to design and output professional-looking documents with a minimum of +typesetting intervention. +. +. +.P +Files processed with +.MR pdfmom @MAN1EXT@ +produce PDF documents. +. +The documents include a PDF outline that appears in the navigation pane +panel of document viewers, +and may contain clickable internal and external links. +. +.P +Normally. +.IR groff 's +native PDF driver, +.MR gropdf @MAN1EXT@ , +is used to generate the output. +. +When +.I pdfmom +is given the +.RB \[lq] "\-T ps" \[rq] +option, +it still produces PDF, +but processing is delegated to +.IR pdfroff , +which uses +.IR groff 's +PostScript driver, +.MR grops @MAN1EXT@ . +. +Not all PDF features are available when +.B \-T ps +is given; +its primary use is to allow processing of files with embedded PostScript +images. +.\" XXX: but we have PDFPIC now...so -Tps is necessary only for people +.\" who want to avoid use of unsafe mode? +. +. +.P +Files processed with +.B groff \-mom +(or +.BR "\-m mom" ) +format for the device specified with the +.B \-T +option. +. +(In this installation, +.B @DEVICE@ +is the default output device.) +. +. +.P +.I mom +comes with her own comprehensive documentation in HTML. +. +A PDF manual, +\[lq]Producing PDFs with +.I groff +and +.IR mom \[rq], +discusses preparation of PDF documents with +.I mom +in detail. +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.I @MACRODIR@/\:mom.tmac +is a wrapper enabling the package to be loaded with +.RB \[lq] "groff \-m mom" \[rq]. +. +. +.TP +.I @MACRODIR@/\:om.tmac +implements the package. +. +. +.TP +.I @HTMLDOCDIR@/\:mom/\:toc.html +is the entry point to the HTML documentation. +. +. +.TP +.I @PDFDOCDIR@/\:mom\-pdf.pdf +is \[lq]Producing PDFs with +.I groff +and +.IR mom \[rq], +by Deri James and Peter Schaffter. +. +. +.TP +.IR @EXAMPLEDIR@/\:mom/\: * .mom +are examples of +.I mom +usage. +. +. +.\" ==================================================================== +.SH Reference +.\" ==================================================================== +. +.\" ==================================================================== +.SS "Escape sequences" +.\" ==================================================================== +. +.TP +.FONT B \[rs]*[ I B ] +begin using an initialized colour inline +. +. +.TP +.FONT B \[rs]*[BCK I " n" B ] +move backward in a line +. +. +.TP +.B \[rs]*[BOLDER] +invoke pseudo bold inline (related to macro +.BR .SETBOLDER ) +. +. +.TP +.B \[rs]*[BOLDERX] +off pseudo bold inline (related to macro +.BR .SETBOLDER ) +. +. +.TP +.FONT B \[rs]*[BU I " n" B ] +move characters pairs closer together inline (related to macro +.BR \%.KERN ) +. +. +.TP +.B \[rs]*[COND] +invoke pseudo condensing inline (related to macro +.BR \%.CONDENSE ) +. +. +.TP +.B \[rs]*[CONDX] +off pseudo condensing inline (related to macro +.BR \%.CONDENSE ) +. +. +.TP +.FONT B \[rs]*[CONDSUP] R .\|.\|. B \[rs]*[CONDSUPX] +pseudo-condensed superscript +. +. +.TP +.FONT B \[rs]*[DOWN I " n" B ] +temporarily move downward in a line +. +. +.TP +.B \[rs]*[EN\-MARK] +mark initial line of a range of line numbers (for use with line +numbered endnotes) +. +. +.TP +.B \[rs]*[EXT] +invoke pseudo extending inline (related to macro +.BR \%.EXTEND ) +. +. +.TP +.B \[rs]*[EXTX] +off pseudo condensing inline (related to macro +.BR \%.EXTEND ) +. +. +.TP +.FONT B \[rs]*[EXTSUP] R .\|.\|. B \[rs]*[EXTSUPX] +pseudo extended superscript +. +. +.TP +.FONT B \[rs]*[FU I " n" B ] +move characters pairs further apart inline (related to macro +.BR \%.KERN ) +. +. +.TP +.FONT B \[rs]*[FWD I " n" B ] +move forward in a line +. +. +.TP +.B \[rs]*[LEADER] +insert leaders at the end of a line +. +. +.TP +.B \[rs]*[RULE] +draw a full measure rule +. +. +.TP +.FONT B \[rs]*[SIZE I " n" B ] +change the point size inline (related to macro +.BR \%.PT_SIZE ) +. +. +.TP +.B \[rs]*[SLANT] +invoke pseudo italic inline (related to macro +.BR \%.SETSLANT ) +. +. +.TP +.B \[rs]*[SLANTX] +off pseudo italic inline (related to macro +.BR \%.SETSLANT ) +. +. +.TP +.FONT B \[rs]*[ST I B ] R .\|.\|. B \[rs]*[ST I B X] +string tabs (mark tab positions inline) +. +. +.TP +.FONT B \[rs]*[SUP] R .\|.\|. B \[rs]*[SUPX] +superscript +. +. +.TP +.B \[rs]*[TB+] +inline escape for +.B .TN +.RI ( "Tab Next" ) +. +. +.TP +.FONT B \[rs]*[UL] R .\|.\|. B \[rs]*[ULX] +invoke underlining inline (fixed width fonts only) +. +. +.TP +.FONT B \[rs]*[UP I " n" B ] +temporarily move upward in a line +. +. +.\" ==================================================================== +.SS Macros +.\" ==================================================================== +. +.TP +.B .AUTOLEAD +set the linespacing relative to the point size +. +. +.TP +.B .B_MARGIN +set a bottom margin +. +. +.TP +.B .BR +break a justified line +. +. +.TP +.B .CENTER +set line-by-line quad centre +. +. +.TP +.B .CONDENSE +set the amount to pseudo condense +. +. +.TP +.B .EL +break a line without advancing on the page +. +. +.TP +.B .EXTEND +set the amount to pseudo extend +. +. +.TP +.B .FALLBACK_FONT +establish a fallback font (for missing fonts) +. +. +.TP +.B .FAM +alias to +.B .FAMILY +. +. +.TP +.BI ".FAMILY " +set the +.I family type +. +. +.TP +.B .FT +set the font style (roman, italic, etc.) +. +. +.TP +.BI ".HI [" " " ] +hanging indent +. +. +.TP +.B .HY +automatic hyphenation on/off +. +. +.TP +.B .HY_SET +set automatic hyphenation parameters +. +. +.TP +.BI ".IB [" " " ] +indent both +. +. +.TP +.B .IBX [ CLEAR ] +exit indent both +. +. +.TP +.BI ".IL [" " " ] +indent left +. +. +.TP +.B .ILX [ CLEAR ] +exit indent left +. +. +.TP +.B .IQ [ CLEAR ] +quit any/all indents +. +. +.TP +.BI ".IR [" " " ] +indent right +. +. +.TP +.B .IRX [ CLEAR ] +exit indent right +. +. +.TP +.B .JUSTIFY +justify text to both margins +. +. +.TP +.B .KERN +automatic character pair kerning on/off +. +. +.TP +.B .L_MARGIN +set a left margin (page offset) +. +. +.TP +.B .LEFT +set line-by-line quad left +. +. +.TP +.B .LL +set a line length +. +. +.TP +.B .LS +set a linespacing (leading) +. +. +.TP +.B .PAGE +set explicit page dimensions and margins +. +. +.TP +.B .PAGEWIDTH +set a custom page width +. +. +.TP +.B .PAGELENGTH +set a custom page length +. +. +.TP +.BI .PAPER " " +set common paper sizes (letter, A4, etc) +. +. +.TP +.B .PT_SIZE +set the point size +. +. +.TP +.B .QUAD +"justify" text left, centre, or right +. +. +.TP +.B .R_MARGIN +set a right margin +. +. +.TP +.B .RIGHT +set line-by-line quad right +. +. +.TP +.B .SETBOLDER +set the amount of emboldening +. +. +.TP +.B .SETSLANT +set the degree of slant +. +. +.TP +.B .SPREAD +force justify a line +. +. +.TP +.B .SS +set the sentence space size +. +. +.TP +.B .T_MARGIN +set a top margin +. +. +.TP +.BI ".TI [" " " ] +temporary left indent +. +. +.TP +.B .WS +set the minimum word space size +. +. +.\" ==================================================================== +.SH "Documentation of details" +.\" ==================================================================== +. +.\" ==================================================================== +.SS "Details of inline escape sequences in alphabetical order" +.\" ==================================================================== +. +.TP +.FONT B \[rs]*[ I B ] +begin using an initialized colour inline +. +. +.TP +.FONT B \[rs]*[BCK I " n" B ] +move backward in a line +. +. +.\" ==================================================================== +.\" BOLDER +.\" ==================================================================== +.TP +.B \[rs]*[BOLDER] +.TQ +.B \[rs]*[BOLDERX] +Emboldening on/off +. +.RS +. +.P +.B \[rs]*[BOLDER] +begins emboldening type. +. +.B \[rs]*[BOLDERX] +turns the feature off. +. +Both are inline escape sequences; +therefore, +they should not appear as separate lines, +but rather be embedded in text lines, like this: +.RS +.EX +.FONT R "Not " B \[rs]*[BOLDER] R everything B \[rs]*[BOLDERX] \ +R " is as it seems." +.EE +.RE +. +.P +Alternatively, if you wanted the whole line emboldened, you should do +.RS +.EX +.FONT B \[rs]*[BOLDER] R "Not everything is as it seems." \ +B \[rs]*[BOLDERX] +.EE +.RE +. +Once +.B \[rs]*[BOLDER] +is invoked, it remains in effect until turned off. +. +.P +Note: If you're using the document processing macros with +.BR "\%.PRINTSTYLE \%TYPEWRITE" , +.I mom +ignores +.B \[rs]*[BOLDER] +requests. +. +.RE +. +. +.\" ==================================================================== +.\" BU +.\" ==================================================================== +.TP +.FONT B \[rs]*[BU I " n" B ] +move characters pairs closer together inline (related to macro +.BR \%.KERN ) +. +. +.\" ==================================================================== +.\" COND +.\" ==================================================================== +.TP +.B \[rs]*[COND] +.TQ +.B \[rs]*[CONDX] +Pseudo-condensing on/off +. +.RS +. +.P +.B \[rs]*[COND] +begins pseudo-condensing type. +. +.B \[rs]*[CONDX] +turns the feature off. +. +Both are inline escape sequences; +therefore, +they should not appear as separate lines, +but rather be embedded in text lines, like this: +.RS +.EX +.FONT B \[rs]*[COND] I "Not everything is as it seems." B \[rs]*[CONDX] +.EE +.RE +.B \%\[rs]*[COND] +remains in effect until you turn it off with +.BR \%\[rs]*[CONDX] . +. +.P +IMPORTANT: You must turn +.B \%\[rs]*[COND] +off before making any changes to the point size of your type, either +via the +.B \%.PT_SIZE +macro or with the +.B \[rs]s +inline escape sequence. +. +If you wish the new point size to be pseudo-condensed, simply reinvoke +.B \%\[rs]*[COND] +afterward. +. +Equally, +.B \%\[rs]*[COND] +must be turned off before changing the condense percentage with +.BR \%.CONDENSE . +. +.P +Note: If you're using the document processing macros with +.BR "\%.PRINTSTYLE \%TYPEWRITE" , +.I mom +ignores +.B \%\[rs]*[COND] +requests. +. +.RE +. +. +.\" ==================================================================== +.\" CONDSUP +.\" ==================================================================== +.TP +.FONT B \[rs]*[CONDSUP] R .\|.\|. B \[rs]*[CONDSUPX] +pseudo-condensed superscript +. +. +.\" ==================================================================== +.\" DOWN +.\" ==================================================================== +.TP +.FONT B \[rs]*[DOWN I " n" B ] +temporarily move downward in a line +. +. +.\" ==================================================================== +.\" EN-MARK +.\" ==================================================================== +.TP +.B \[rs]*[EN\-MARK] +mark initial line of a range of line numbers (for use with line +numbered endnotes) +. +. +.\" ==================================================================== +.\" EXT +.\" ==================================================================== +.TP +.B \[rs]*[EXT] +.TQ +.B \[rs]*[EXTX] +Pseudo-extending on/off +. +.RS +. +.P +.B \[rs]*[EXT] +begins pseudo-extending type. +. +.B \[rs]*[EXTX] +turns the feature off. +. +Both are inline escape sequences; +therefore, +they should not appear as separate lines, +but rather be embedded in text lines, like this: +.RS +.EX +.FONT B \[rs]*[EXT] I "Not everything is as it seems." B \[rs]*[EXTX] +.EE +.RE +.B \[rs]*[EXT] +remains in effect until you turn it off with +.BR \[rs]*[EXTX] . +. +.P +IMPORTANT: You must turn +.B \%\[rs]*[EXT] +off before making any changes to the point size of your type, either +via the +.B \%.PT_SIZE +macro or with the +.B \[rs]s +inline escape sequence. +. +If you wish the new point size to be +.IR \%pseudo-extended , +simply reinvoke +.B \%\[rs]*[EXT] +afterward. +. +Equally, +.B \%\[rs]*[EXT] +must be turned off before changing the extend percentage with +.BR \%.EXTEND . +. +.P +Note: If you are using the document processing macros with +.BR "\%.PRINTSTYLE \%TYPEWRITE" , +.I mom +ignores +.B \%\[rs]*[EXT] +requests. +. +.RE +. +. +.\" ==================================================================== +.\" EXTSUP +.\" ==================================================================== +.TP +.FONT B \[rs]*[EXTSUP] R .\|.\|. B \[rs]*[EXTSUPX] +pseudo extended superscript +. +. +.\" ==================================================================== +.\" FU +.\" ==================================================================== +.TP +.FONT B \[rs]*[FU I " n" B ] +move characters pairs further apart inline (related to macro +.BR .KERN ) +. +. +.\" ==================================================================== +.\" FWD +.\" ==================================================================== +.TP +.FONT B \[rs]*[FWD I " n" B ] +move forward in a line +. +. +.\" ==================================================================== +.\" LEADER +.\" ==================================================================== +.TP +.B \[rs]*[LEADER] +insert leaders at the end of a line +. +. +.\" ==================================================================== +.\" RULE +.\" ==================================================================== +.TP +.B \[rs]*[RULE] +draw a full measure rule +. +. +.\" ==================================================================== +.\" PT_SIZE +.\" ==================================================================== +.TP +.FONT B \[rs]*[SIZE I " n" B ] +change the point size inline (related to macro +.BR \%.PT_SIZE ) +. +. +.\" ==================================================================== +.\" SLANT +.\" ==================================================================== +.TP +.B \[rs]*[SLANT] +.TQ +.B \[rs]*[SLANTX] +Pseudo italic on/off +. +.RS +. +.P +.B \%\[rs]*[SLANT] +begins +.I pseudo-italicizing +.IR type . +. +.B \%\[rs]*[SLANTX] +turns the feature off. +. +Both are inline escape sequences; +therefore, +they should not appear as separate lines, +but rather be embedded in text lines, like this: +.RS +.EX +.FONT R "Not " B \[rs]*[SLANT] R everything B \[rs]*[SLANTX] \ +R " is as it seems." +.EE +.RE +. +.P +Alternatively, if you wanted the whole line +.IR pseudo-italicized , +you'd do +.RS +.EX +.FONT B \[rs]*[SLANT] R "Not everything is as it seems." \ +B \[rs]*[SLANTX] +.EE +.RE +. +.P +Once +.B \[rs]*[SLANT] +is invoked, it remains in effect until turned off. +. +.P +Note: If you're using the document processing macros with +.BR "\%.PRINTSTYLE \%TYPEWRITE" , +.I mom +underlines pseudo-italics by default. +. +To change this behaviour, use the special macro +.BR .SLANT_MEANS_SLANT . +. +.RE +. +. +.\" ==================================================================== +.\" ST +.\" ==================================================================== +.TP +.FONT B \[rs]*[ST I B ] R .\|.\|. B \[rs]*[ST I B X] +Mark positions of string tabs +. +.RS +.P +The +.I quad +direction must be +.B LEFT +or +.B \%JUSTIFY +(see +.B \%.QUAD +and +.BR \%.JUSTIFY ) +or the +.I no-fill mode +set to +.B LEFT +in order for these inlines to function properly. +. +Please see +.IR \%IMPORTANT , +below. +. +.P +String tabs need to be marked off with inline escape sequences before +being set up with the +.B .ST +macro. +. +Any input line may contain string tab markers. +. +.IR , +above, means the numeric identifier of the tab. +. +.P +The following shows a sample input line with string tab markers. +.RS +.EX +.BR \[rs]*[ST1] "De minimus" \[rs]*[ST1X] \c +.RB "non curat" \[rs]*[ST2] lex \[rs]*[ST2X] . +.EE +.RE +. +.P +String +.I tab 1 +begins at the start of the line and ends after the word +.IR \%time . +. +String +.I tab 2 +starts at +.I good +and ends after +.IR men . +. +.I Inline escape sequences +(e.g., +.I font +or +.I point size +.IR changes , +or horizontal movements, including padding) are taken into account +when +.I mom +determines the +.I position +and +.I length +of +.I string +.IR tabs . +. +.P +Up to nineteen string tabs may be marked (not necessarily all on the +same line, of course), and they must be numbered between 1 and 19. +. +.P +Once string tabs have been marked in input lines, they have to be +.I set +with +.BR .ST , +after which they may be called, by number, with +.BR .TAB . +. +.P +Note: Lines with string tabs marked off in them are normal input +lines, i.e.\& they get printed, just like any input line. +. +If you want to set up string tabs without the line printing, use the +.B \%.SILENT +macro. +. +.P +.I IMPORTANT: +Owing to the way +.I groff +processes input lines and turns them into output lines, it is not +possible for +.I mom +to +.I guess +the correct starting position of string tabs marked off in lines that +are centered or set flush right. +. +.P +Equally, she cannot guess the starting position if a line is fully +justified and broken with +.BR \%.SPREAD . +. +.P +In other words, in order to use string tabs, +.B LEFT +must be active, or, if +.B .QUAD LEFT +or +.B \%JUSTIFY +are active, the line on which the +.I string tabs +are marked must be broken +.I manually +with +.B .BR +(but not +.BR \%.SPREAD ). +. +.P +To circumvent this behaviour, I recommend using the +.B PAD +to set up string tabs in centered or flush right lines. +. +Say, for example, you want to use a +.I string tab +to +.I underscore +the text of a centered line with a rule. +. +Rather than this, +.RS +.EX +.B .CENTER +.B \[rs]*[ST1]A line of text\[rs]*[ST1X]\[rs]c +.B .EL +.B .ST 1 +.B .TAB 1 +.B .PT_SIZE 24 +.B .ALD 3p +.B \[rs]*[RULE] +.B .RLD 3p +.B .TQ +.EE +.RE +you should do: +.RS +.EX +\&.QUAD CENTER +\&.PAD "#\[rs]*[ST1]A line of text\[rs]*[ST1X]#" +\&.EL +\&.ST 1 +\&.TAB 1 +\&.PT_SIZE 24 +\&.ALD 3p +\&\[rs]" You can\[aq]t use \[rs]*[UP] or \[rs]*[DOWN] with \[rs]*[RULE]. +\&.RLD 3p +\&.TQ +.EE +.RE +. +.RE +. +. +.\" ==================================================================== +.\" SUP +.\" ==================================================================== +.TP +.FONT B \[rs]*[SUP] R .\|.\|. B \[rs]*[SUPX] +superscript +. +. +.\" ==================================================================== +.\" TB+ +.\" ==================================================================== +.TP +.B \[rs]*[TB+] +Inline escape for +.B .TN +.RI ( "Tab Next" ) +. +. +.\" ==================================================================== +.\" UL +.\" ==================================================================== +.TP +.FONT B \[rs]*[UL] R .\|.\|. B \[rs]*[ULX] +invoke underlining inline (fixed width fonts only) +. +. +.\" ==================================================================== +.\" UP +.\" ==================================================================== +.TP +.FONT B \[rs]*[UP I " n" B ] +temporarily move upward in a line +. +. +.\" ==================================================================== +.SS "Details of macros in alphabetical order" +.\" ==================================================================== +. +.\" ==================================================================== +.\" AUTOLEAD +.\" ==================================================================== +.TP +.B .AUTOLEAD +set the linespacing relative to the point size +. +. +.\" ==================================================================== +.\" Bottom Margin +.\" ==================================================================== +.TP +.BI .B_MARGIN " " +Bottom Margin +. +.RS +. +.P +Requires a unit of measure +. +.P +.B .B_MARGIN +sets a nominal position at the bottom of the page beyond which you +don't want your type to go. +. +When the bottom margin is reached, +.I mom +starts a new page. +. +.B .B_MARGIN requires a unit of measure. +. +Decimal fractions are allowed. +. +To set a nominal bottom margin of 3/4 inch, enter +.RS +.EX +.B .B_MARGIN .75i +.EE +.RE +. +.P +Obviously, if you haven't spaced the type on your pages so that the +last lines fall perfectly at the bottom margin, the margin will vary +from page to page. +. +Usually, but not always, the last line of type that fits on a page +before the bottom margin causes mom to start a new page. +. +.P +Occasionally, owing to a peculiarity in +.IR groff , +an extra line will fall below the nominal bottom margin. +. +If you're using the document processing macros, this is unlikely to +happen; the document processing macros are very hard-nosed about +aligning bottom margins. +. +.P +Note: The meaning of +.B .B_MARGIN +is slightly different when you're using the document processing +macros. +. +.RE +. +. +.\" ==================================================================== +.\" Fallback Font +.\" ==================================================================== +.TP +.BI \%.FALLBACK_FONT " " "[ ABORT | WARN ]" +Fallback Font +. +.RS +. +.P +In the event that you pass an invalid argument to +.B \%.FAMILY +(i.e.\& a non-existent +.IR family ), +.IR mom , +by default, uses the +.IR "fallback font" , +.B Courier Medium Roman +.RB ( CR ), +in order to continue processing your file. +. +.P +If you'd prefer another +.IR "fallback font" , +pass +.B \%.FALLBACK_FONT +the full +.I family+font name +of the +.I font +you'd like. +. +For example, if you'd rather the +.I fallback font +were +.BR "Times Roman Medium Roman" , +.RS +.EX +.B .FALLBACK_FONT TR +.EE +.RE +would do the trick. +. +.P +.B Mom +issues a warning whenever a +.I font style set +with +.B .FT +does not exist, either because you haven't registered the style +or because the +.I font style +does not exist in the current +.I family set +with +.BR .FAMILY . +. +By default, +.B \%mom +then aborts, which allows you to correct the problem. +. +.P +If you'd prefer that +.B \%mom +not abort on non-existent +.IR fonts , +but rather continue processing using a +.IR "fallback font" , +you can pass +.B \%.FALLBACK_FONT +the argument +.BR WARN , +either by itself, or in conjunction with your chosen +.IB "fallback font" . +. +.P +Some examples of invoking +.BR \%.FALLBACK_FONT : +. +.TP +.B .FALLBACK_FONT WARN +.I mom +will issue a warning whenever you try to access a non-existent +.I font +but will continue processing your file with the default +.IR "fallback font" , +.BR "Courier Medium Roman" . +. +. +.TP +.B .FALLBACK_FONT TR WARN +.B \%mom +will issue a warning whenever you try to access a non-existent +.I font +but will continue processing your file with a +.I fallback font +of +.BR "Times Roman Medium Roman" ; +additionally, +.B TR +will be the +.I fallback font +whenever you try to access a +.I family +that does not exist. +. +.TP +.B .FALLBACK_FONT TR ABORT +.B \%mom +will abort whenever you try to access a non-existent +.BR font , +and will use the +.I fallback font +.B TR +whenever you try to access a +.I family +that does not exist. +. +If, for some reason, you want to revert to +.BR ABORT , +just enter +.B \%".FALLBACK_FONT ABORT" +and +.I mom +will once again abort on +.IR "font errors" . +. +.RE +. +. +.\" ==================================================================== +.\" FAM +.\" ==================================================================== +.TP +.BI .FAM " " +Type Family, +alias of +.B .FAMILY +. +. +.\" ==================================================================== +.\" FAMILY +.\" ==================================================================== +.TP +.BI .FAMILY " " +Type Family, +alias of +.B .FAM +. +.RS +. +.P +.B .FAMILY +takes one argument: the name of the +.I family +you want. +. +.I Groff +comes with a small set of basic families, each identified by a 1-, +2- or 3-letter mnemonic. +. +The standard families are: +.RS +.EX +.B "A = Avant Garde" +.B "BM = Bookman" +.B "H = Helvetica" +.B "HN = Helvetica Narrow" +.B "N = New Century Schoolbook" +.B "P = Palatino" +.B "T = Times Roman" +.B "ZCM = Zapf Chancery" +.EE +.RE +. +.P +The argument you pass to +.B .FAMILY +is the identifier at left, above. +. +For example, if you want +.BR Helvetica , +enter +.RS +.EX +.B .FAMILY H +.EE +.RE +. +.P +Note: The font macro +.RB ( .FT ) +lets you specify both the type +.I family +and the desired font with a single macro. +. +While this saves a few +keystrokes, I recommend using +.B .FAMILY for +.IR family , +and +.B .FT for +.IR font , +except where doing so is genuinely inconvenient. +. +.BR ZCM , +for example, +only exists in one style: +.B Italic +.RB ( I ). +. +.P +Therefore, +.RS +.EX +.B .FT ZCMI +.EE +.RE +makes more sense than setting the +.I family +to +.BR ZCM , +then setting the +.I font +to +.IR I . +. +.P +Additional note: If you are running a +.I groff +version prior to +1.19.2, +you must follow all +.B .FAMILY +requests with a +.B .FT +request, +otherwise +.I mom +will set all type up to the next +.B .FT +request in the fallback font. +. +.P +If you are running +.I groff +1.19.2 or later, +when you invoke the +.B .FAMILY +macro, +.I mom +.I remembers +the font style +.BR ( Roman , +.BR Italic , +etc) currently in use (if the font style exists in the new +.IR family ) +and will continue to use the same font style in the new family. +For example: +.RS +.EX +.BI ".FAMILY BM " "\[rs]"" Bookman family" +.BI ".FT I " "\[rs]"" Medium Italic" +.I \[rs]" Bookman Medium Italic +.BI ".FAMILY H " "\[rs]"" Helvetica family" +.I \[rs]" Helvetica Medium Italic +.EE +.RE +. +.P +However, if the font style does not exist in the new family, +.I mom +will set all subsequent type in the fallback font (by default, +.B Courier Medium +.BR Roman ) +until she encounters a +.B .FT +request that's valid for the +.IR family . +. +.P +For example, assuming you don't have the font +.B Medium Condensed Roman +.RI ( mom +extension +.IR CD ) +in the +.I Helvetica +.IR family : +.RS +.EX +.BI ".FAMILY UN " "\[rs]"" Univers family" +.BI ".FT CD " "\[rs]"" Medium Condensed" +.I \[rs]" Univers Medium Condensed +.BI ".FAMILY H " "\[rs]"" Helvetica family" +.I \[rs]" Courier Medium Roman! +.EE +.RE +. +.P +In the above example, you must follow +.B .FAMILY H +with a +.B .FT +request that's valid for +.BR Helvetica . +. +.P +Please see the Appendices, +.I Adding fonts to +.IR groff , +for information on adding fonts and families to +.IR groff , as well as to +see a list of the extensions +.I mom +provides to +.IR groff 's +basic +.BR R , +.BR I , +.BR B , +.B BI +styles. +. +.P +Suggestion: When adding +.I families to +.IR groff , +I recommend following the established standard for the naming families +and fonts. +. +For example, if you add the +.B Garamond +family, name the font files +.RS +.EX +.B GARAMONDR +.B GARAMONDI +.B GARAMONDB +.B GARAMONDBI +.EE +.RE +. +.B GARAMOND then becomes a valid +.I family name +you can pass to +.BR .FAMILY . +. +(You could, of course, shorten +.B GARAMOND +to just +.BR G , +or +.BR GD .) +.BR R , +.BR I , +.BR B , +and +.B BI +after +.B GARAMOND +are the +.IR roman , +.IR italic , +.I bold +and +.I bold-italic +fonts respectively. +. +.RE +. +. +.\" ==================================================================== +.\" FONT +.\" ==================================================================== +.TP +.BI ".FONT R | B | BI | " "" +Alias to +.B .FT +. +. +.\" ==================================================================== +.\" FT +.\" ==================================================================== +.TP +.BI ".FT R | B | BI | " "" +Set font +. +.RS +. +.P +By default, +.I groff +permits +.B .FT +to take one of four possible arguments specifying the desired font: +.RS +.EX +.B R = (Medium) Roman +.B I = (Medium) Italic +.B B = Bold (Roman) +.B BI = Bold Italic +.EE +.RE +. +.P +For example, if your +.I family +is +.BR Helvetica , +entering +.RS +.EX +.B .FT B +.EE +.RE +will give you the +.I Helvetica bold +.IR font . +. +If your +.I family +were +.BR \%Palatino , +you'd get the +.I \%Palatino bold +.IR font . +. +.P +.B Mom +considerably extends the range of arguments you can pass to +.BR .FT , +making it more convenient to add and access fonts of differing weights +and shapes within the same family. +. +.P +Have a look here for a list of the weight/style arguments +.I mom +allows. +. +Be aware, though, that you must have the fonts, correctly installed +and named, in order to use the arguments. +. +(See +.I Adding fonts to groff +for instructions and information.) +. +Please also read the +.I ADDITIONAL NOTE +found in the description of the +.B \%.FAMILY +macro. +. +. +.P +How +.I mom +reacts to an invalid argument to +.B .FT +depends on which version of +.I groff +you're using. +. +If your +.I groff +version is 1.19.2 or later, +.I mom +will issue a warning and, +depending on how you've set up the fallback font, +either continue processing using the fallback font, +or abort +(allowing you to correct the problem). +. +In earlier versions, +.I mom +will silently continue processing, +using either the fallback font or the font that was in effect prior to +the invalid +.B .FT +call. +. +. +.P +.B .FT +will also accept, as an argument, a full +.I family +and +.I font +.IR name . +. +.P +For example, +.RS +.EX +.B .FT HB +.EE +.RE +will set subsequent type in +.I Helvetica +.IR Bold . +. +.P +However, I strongly recommend keeping +.I family +and +.I font +separate except where doing so is genuinely inconvenient. +. +.P +For inline control of +.IR fonts , +see +.I Inline +.IR Escapes , +font control. +. +.RE +. +. +.\" ==================================================================== +.\" Hanging Indent +.\" ==================================================================== +.TP +.BI "\%.HI [" " " ] +Hanging indent \[em] the optional argument requires a unit of measure. +. +.RS +. +.P +A hanging indent looks like this: +.RS +.EX +The thousand injuries of Fortunato I had borne as best I + could, but when he ventured upon insult, I vowed + revenge.\& You who so well know the nature of my soul + will not suppose, however, that I gave utterance to a + threat, at length I would be avenged.\|.\|. +.EE +.RE +. +The first line of text +.I hangs +outside the +.IR "left margin" . +. +.P +In order to use +.IR "hanging indents" , +you must first have a +.I left indent +active (set with either +.B .IL +or +.BR .IB ). +. +.B Mom +will not hang text outside the +.I left margin set +with +.B \%.L_MARGIN +or outside the +.I left margin +of a +.IR \%tab . +. +.P +The first time you invoke +.BR .HI , +you must give it a +.BR measure . +. +If you want the first line of a paragraph to +.IR "hang by" , +say, +.IR "1 pica" , +do +.RS +.EX +.B ".IL 1P" +.B ".HI 1P" +.EE +.RE +. +Subsequent invocations of +.B \%.HI +do not require you to supply a +.IR measure ; +.I mom +keeps track of the last measure you gave it. +. +.P +Generally speaking, you should invoke +.B .HI +immediately prior to the line you want hung (i.e.\& without any +intervening control lines). +. +And because +.I hanging indents +affect only one line, there's no need to turn them off. +. +.P +.I IMPORTANT: +Unlike +.BR IL , +.B IR +and +.BR IB , +measures given to +.B .HI +are NOT additive. +. +Each time you pass a measure to +.BR .HI , +the measure is treated literally. +. +.B +.I Recipe: +A numbered list using +.I hanging indents +. +.P +.I Note: +.I mom +has macros for setting lists. +. +This recipe exists to demonstrate the use of +.I hanging indents +only. +.RS +.EX +\&.PAGE 8.5i 11i 1i 1i 1i 1i +\&.FAMILY T +\&.FT R +\&.PT_SIZE 12 +\&.LS 14 +\&.JUSTIFY +\&.KERN +\&.SS 0 +\&.IL \[rs]w\[aq]\[rs]0\[rs]0.\[aq] +\&.HI \[rs]w\[aq]\[rs]0\[rs]0.\[aq] +1.\[rs]0The most important point to be considered is whether +the answer to the meaning of Life, the Universe, and +Everything really is 42.\& We have no one\[aq]s word on the +subject except Mr.\& Adams\[aq]s. +\&.HI +2.\[rs]0If the answer to the meaning of Life, the Universe, +and Everything is indeed 42, what impact does this have on +the politics of representation?\& 42 is, after all not a +prime number.\& Are we to infer that prime numbers don\[aq]t +deserve equal rights and equal access in the universe? +\&.HI +3.\[rs]0If 42 is deemed non-exclusionary, how do we present +it as the answer and, at the same time, forestall debate +on its exclusionary implications? +.EE +.RE +. +.P +First, we invoke a left indent with a measure equal to the width of 2 +figures spaces plus a period (using the \[rs]w inline escape). +. +At this point, the left indent is active; text afterward would +normally be indented. +. +However, we invoke a hanging indent of exactly the same width, which +hangs the first line (and first line only!\&) to the left of the indent +by the same distance (in this case, that means \[lq]out to the left +margin\[rq]). +. +Because we begin the first line with a number, a period, and a figure +space, the actual text +.RI ( "The most important point.\|.\|.\&" ) +starts at exactly the same spot as the indented lines that follow. +. +.P +Notice that subsequent invocations of +.B .HI +don't require a +.I measure +to be given. +. +.P +Paste the example above into a file and preview it with +.RS +.EX +.B pdfmom filename.mom | ps2pdf \- filename.pdf +.EE +.RE +to see hanging indents in action. +. +.RE +. +. +.\" ==================================================================== +.\" IB - INDENT BOTH +.\" ==================================================================== +.TP +.BI "\%.IB [" " " ] +Indent both \[em] the optional argument requires a unit of measure +. +.RS +. +.P +.B .IB +allows you to set or invoke a left and a right indent at the same time. +. +.P +At its first invocation, you must supply a measure for both indents; +at subsequent invocations when you wish to supply a measure, both must +be given again. +. +As with +.B .IL +and +.BR .IR , +the measures are added to the values previously passed to the +macro. +. +Hence, if you wish to change just one of the values, you must give an +argument of zero to the other. +. +.P +.I A word of advice: +If you need to manipulate left and right indents separately, use a +combination of +.B .IL +and +.B .IR +instead of +.BR .IB . +. +You'll save yourself a lot of grief. +. +.P +A +.I minus sign +may be prepended to the arguments to subtract from their current +values. +. +The \[rs]w inline escape may be used to specify text-dependent +measures, in which case no unit of measure is required. +. +For example, +.RS +.EX +.B .IB \[rs]w\[aq]margarine\[aq] \[rs]w\[aq]jello\[aq] +.EE +.RE +left indents text by the width of the word +.I margarine +and right indents by the width of +.IR jello . +. +.P +Like +.B .IL +and +.BR .IR , +.B .IB +with no argument indents by its last active values. +. +See the brief explanation of how mom handles indents for more details. +. +.P +.I Note: +Calling a +.I tab +(with +.BR ".TAB " ) +automatically cancels any active indents. +. +.P +.I Additional note: +Invoking +.B .IB +automatically turns off +.B .IL +and +.BR .IR . +. +.RE +. +. +.\" ==================================================================== +.\" IL - INDENT LEFT +.\" ==================================================================== +.TP +.BI "\%.IL [" " " ] +Indent left \[em] the optional argument requires a unit of measure +. +.RS +. +.P +.B .IL +indents text from the left margin of the page, or if you're in a +.IR tab , +from the left edge of the +.IR tab . +. +Once +.I IL +is on, the +.I left indent +is applied uniformly to every subsequent line of text, even if you +change the line length. +. +.P +The first time you invoke +.BR .IL , +you must give it a measure. +. +Subsequent invocations with a measure add to the previous measure. +. +A minus sign may be prepended to the argument to subtract from the +current measure. +. +The +.B \[rs]w +inline escape may be used to specify a text-dependent measure, in +which case no unit of measure is required. +. +For example, +.RS +.EX +.B .IL \[rs]w\[aq]margarine\[aq] +.EE +.RE +indents text by the width of the word +.IR margarine . +. +.P +With no argument, +.B .IL +indents by its last active value. +. +See the brief explanation of how +.I mom +handles indents for more details. +. +.P +.I Note: +Calling a +.I tab +(with +.BR ".TAB " ) +automatically cancels any active indents. +. +.P +.I Additional note: +Invoking +.B .IL +automatically turns off +.BR IB . +. +.RE +. +. +.\" ==================================================================== +.\" IQ - quit any/all indents +.\" ==================================================================== +.TP +.BI "\%.IQ [" " " ] +IQ \[em] quit any/all indents +. +.RS +. +.P +.I IMPORTANT NOTE: +The original macro for quitting all indents was +.BR .IX . +. +This usage has been deprecated in favour of +.BR IQ . +. +.B .IX +will continue to behave as before, but +.I mom +will issue a warning to +.I stderr +indicating that you should update your documents. +. +.P +As a consequence of this change, +.BR .ILX , +.B .IRX +and +.B .IBX +may now also be invoked as +.BR .ILQ , +.B .IRQ +and +.BR .IBQ . +. +Both forms are acceptable. +. +.P +Without an argument, the macros to quit indents merely restore your +original margins and line length. +. +The measures stored in the indent macros themselves are saved so you +can call them again without having to supply a measure. +. +.P +If you pass these macros the optional argument +.BR CLEAR , +they not only restore your original left margin and line length, but +also clear any values associated with a particular indent style. +. +The next time you need an indent of the same style, you have to supply +a measure again. +. +.P +.BR ".IQ CLEAR" , +as you'd suspect, quits and clears the values for all indent +styles at once. +. +.RE +. +. +.\" ==================================================================== +.\" IR - INDENT RIGHT +.\" ==================================================================== +.TP +.BI "\%.IR [" " " ] +Indent right \[em] the optional argument requires a unit of measure +. +.RS +. +.P +.B .IR +indents text from the +.I right margin +of the page, or if you're in a +.IR tab , +from the end of the +.IR tab . +. +.P +The first time you invoke +.BR .IR , +you must give it a measure. +. +Subsequent invocations with a measure add to the previous indent +measure. +. +A +.I minus sign +may be prepended to the argument to subtract from the current indent +measure. +. +The \[rs]w inline escape may be used to specify a text-dependent +measure, in which case no +.I unit of measure +is required. +. +For example, +.RS +.EX +.B .IR \[rs]w\[aq]jello\[aq] +.EE +.RE +indents text by the width of the word +.IR jello . +. +.P +With no argument, +.B .IR +indents by its last active value. +. +See the brief explanation of how +.I mom +handles indents for more details. +. +.P +.I Note: +Calling a +.I tab +(with +.BR "\%.TAB " ) +automatically cancels any active indents. +. +.P +.I Additional note: +Invoking +.B .IR +automatically turns off +.BR IB . +. +.RE +. +. +.\" ==================================================================== +.\" Left Margin +.\" ==================================================================== +.TP +.BI .L_MARGIN " " +Left Margin +. +.RS +. +.P +L_MARGIN establishes the distance from the left edge of the printer +sheet at which you want your type to start. +. +It may be used any time, +and remains in effect until you enter a new value. +. +.P +Left indents and tabs are calculated from the value you pass to +.BR .L_MARGIN , +hence it's always a good idea to invoke it before starting any serious +typesetting. +. +A unit of measure is required. +. +Decimal fractions are allowed. +. +Therefore, +to set the left margin at 3 picas (1/2 inch), +you'd enter either +.RS +.EX +.B .L_MARGIN 3P +.EE +.RE +or +.RS +.EX +.B .L_MARGIN .5i +.EE +.RE +. +.P +If you use the macros +.BR .PAGE , +.B .PAGEWIDTH +or +.B .PAPER +without invoking +.B .L_MARGIN +(either before or afterward), +.I mom +automatically sets +.B .L_MARGIN +to +.IR "1 inch" . +. +.P +Note: +.B .L_MARGIN +behaves in a special way when you're using the document processing +macros. +. +.RE +. +. +.\" ==================================================================== +.\" MCO - BEGIN MULTI-COLUMN SETTING +.\" ==================================================================== +.TP +.B .MCO +Begin multi-column setting. +. +.RS +.P +.B .MCO +.RI ( "Multi-Column On" ) +is the +.I macro +you use to begin +.IR "multi-column setting" . +. +It marks the current baseline as the top of your columns, for use +later with +.BR .MCR . +. +See the introduction to columns for an explanation of +.I multi-columns +and some sample input. +. +.P +.I Note: +Do not confuse +.B .MCO +with the +.B .COLUMNS +macro in the document processing macros. +. +.RE +. +. +.\" ==================================================================== +.\" MCR - RETURN TO TOP OF COLUMN +.\" ==================================================================== +.TP +.B \%.MCR +Once you've turned +.I multi-columns +on (with +.BR \%.MCO ), +.BR .MCR , +at any time, +returns you to the +.IR "top of your columns" . \" XXX: Are italics truly required here? +. +. +.\" ==================================================================== +.\" MCX - EXIT MULTI-COLUMNS +.\" ==================================================================== +.TP +.BI "\%.MCX [ " "" " ]" +Optional argument requires a unit of measure. +. +.RS +. +.P +Exit multi-columns. +. +.P +.B .MCX +takes you out of any +.I tab +you were in (by silently invoking +.BR .TQ ) +and advances to the bottom of the longest column. +. +.P +Without an argument, +.B .MCX +advances +.I 1 linespace +below the longest column. +. +.P +Linespace, in this instance, is the leading in effect at the moment +.B .MCX +is invoked. +. +.P +If you pass the +.I +argument to +.BR .MCX , +it advances +.I 1 linespace +below the longest column (see above) +.I PLUS +the distance specified by the argument. +. +The argument requires a unit of measure; therefore, to advance an +extra 6 points below where +.B \%.MCX +would normally place you, you'd enter +.RS +.EX +.B .MCX 6p +.EE +.RE +. +.P +.I Note: +If you wish to advance a precise distance below the baseline of the +longest column, use +.B .MCX +with an argument of +.B 0 +(zero; no +.I unit of measure +required) in conjunction with the +.B \%.ALD +macro, like this: +.RS +.EX +.B .MCX 0 +.B .ALD 24p +.EE +.RE +. +The above advances to precisely +.I 24 points +below the baseline of the longest column. +. +.RE +. +. +.\" ==================================================================== +.\" Start a new Page +.\" ==================================================================== +.TP +.B .NEWPAGE +. +.RS +. +.P +Whenever you want to start a new page, use +.BR .NEWPAGE , +by itself with no argument. +. +.B Mom +will finish up processing the current page and move you to the top of +a new one (subject to the top margin set with +.BR .T_MARGIN ). +. +.RE +. +. +.\" ==================================================================== +.\" Page +.\" ==================================================================== +.TP +.BI ".PAGE " " [ " " [ " " [ " " [ " \ + " [ " " ] ] ] ] ]" +. +.RS +. +.P +All arguments require a unit of measure +. +.P +.I IMPORTANT: +If you're using the document processing macros, +.B .PAGE +must come after +.BR .START . +. +Otherwise, it should go at the top of a document, prior to any text. +. +And remember, when you're using the document processing macros, top +margin and bottom margin mean something slightly different than when +you're using just the typesetting macros (see Top and bottom margins +in document processing). +. +.P +.B .PAGE +lets you establish paper dimensions and page margins with a single +macro. +. +The only required argument is page width. +. +The rest are +optional, but they must appear in order and you can't skip over +any. +. +.IR , +.IR , +.I +and +.I +refer to the left, right, top and bottom margins respectively. +. +.P +Assuming your page dimensions are 11 inches by 17 inches, and that's +all you want to set, enter +.RS +.EX +.B .PAGE 11i 17i +.EE +.RE +. +If you want to set the left margin as well, say, at 1 inch, +.B PAGE +would look like this: +.RS +.EX +.B .PAGE 11i 17i 1i +.EE +.RE +. +.P +Now suppose you also want to set the top margin, +say, +at 1\(en1/2 inches. +. +.I +comes after +.I +in the optional arguments, but you can't skip over any arguments, +therefore to set the top margin, you must also give a right margin. +. +The +.B .PAGE +macro would look like this: +.RS +.EX +.tr -\- +\&.PAGE 11i 17i 1i 1i 1.5i + | | +required right---+ +---top margin + margin +.tr -- +.EE +.RE +. +.P +Clearly, +.B .PAGE +is best used when you want a convenient way to tell +.I mom +just the dimensions of your printer sheet (width and length), or when +you want to tell her everything about the page (dimensions and all the +margins), for example +.RS +.EX +.B .PAGE 8.5i 11i 45p 45p 45p 45p +.EE +.RE +. +This sets up an 8\(12 by 11 inch page with margins of 45 points +(5/8-inch) all around. +. +.P +Additionally, if you invoke +.B .PAGE +with a top margin argument, any macros you invoke after +.B .PAGE +will almost certainly move the baseline of the first line of text down +by one linespace. +. +To compensate, do +.RS +.EX +.B .RLD 1v +.EE +.RE +immediately before entering any text, or, if it's feasible, make +.B .PAGE +the last macro you invoke prior to entering text. +. +.P +Please read the +.I Important note +on page dimensions and papersize for information on ensuring +.I groff +respects your +.B .PAGE +dimensions and margins. +. +.RE +. +. +.\" ==================================================================== +.\" Page Length +.\" ==================================================================== +.TP +.BI .PAGELENGTH " " +tells +.I mom +how long your printer sheet is. +. +It works just like +.BR .PAGEWIDTH . +. +.RS +. +.P +Therefore, to tell +.I mom +your printer sheet is 11 inches long, you enter +.RS +.EX +.B .PAGELENGTH 11i +.EE +.RE +. +Please read the important note on page dimensions and papersize for +information on ensuring +.I groff +respects your +.IR PAGELENGTH . +. +.RE +. +. +.\" ==================================================================== +.\" Page Width +.\" ==================================================================== +.TP +.BI .PAGEWIDTH " " +. +.RS +. +.P +The argument to +.B .PAGEWIDTH +is the width of your printer sheet. +. +.P +.B .PAGEWIDTH +requires a unit of measure. +. +Decimal fractions are allowed. +. +Hence, to tell +.I mom +that the width of your printer sheet is 8\(12 inches, you enter +.RS +.EX +\&.PAGEWIDTH 8.5i +.EE +.RE +. +.P +Please read the Important note on page dimensions and papersize for +information on ensuring +.I groff +respects your +.IR PAGEWIDTH . +. +.RE +. +. +.\" ==================================================================== +.\" Paper +.\" ==================================================================== +.TP +.BI .PAPER " " +provides a convenient way to set the page dimensions for some common +printer sheet sizes. +. +The argument +.I +can be one of: +.BR LETTER , +.BR LEGAL , +.BR STATEMENT , +.BR TABLOID , +.BR LEDGER , +.BR FOLIO , +.BR QUARTO , +.BR EXECUTIVE , +.BR 10x14 , +.BR A3 , +.BR A4 , +.BR A5 , +.BR B4 , +.BR B5 . +. +. +.TP +.B .PRINTSTYLE +. +. +.\" ==================================================================== +.\" PT_SIZE - POINT SIZE OF TYPE +.\" ==================================================================== +.TP +.BI .PT_SIZE " " +Point size of type, does not require a +.IR "unit of measure" . +. +.RS +. +.P +.B \%.PT_SIZE +.RI ( "Point Size" ) +takes one argument: the +.I size of type +in +.IR points . +. +Unlike most other macros that establish the +.I size +or +.I measure +of something, +.B \%.PT_SIZE +does not require that you supply a +.I unit of measure +since it's a near universal convention that +.I type size +is measured in +.IR points . +. +Therefore, to change the +.I type size +to, say, +.IR "11 points" , +enter +.RS +.EX +.B .PT_SIZE 11 +.EE +.RE +. +.I Point sizes +may be +.I fractional +(e.g., +.I 10.25 +or +.IR 12.5 ). +. +.P +You can prepend a +.I plus +or a +.I minus sign +to the argument to +.BR \%.PT_SIZE , +in which case the +.I point size +will be changed by +.I + +or +.I \- +the original value. +. +For example, +if the +.I point size +is +.IR 12 , +and you want +.IR 14 , +you can do +.RS +.EX +.B .PT_SIZE +2 +.EE +.RE +then later reset it to +.I 12 +with +.RS +.EX +.B .PT_SIZE \-2 +.EE +.RE +. +The +.I size of type +can also be changed inline. +. +.P +.I Note: +It is unfortunate that the +.B \%pic +preprocessor has already taken the name, PS, and thus +.IR mom 's +macro for setting +.I point sizes +can't use it. +. +However, if you aren't using +.BR pic , +you might want to alias +.B \%.PT_SIZE +as +.BR .PS , +since there'd be no conflict. +. +For example +.RS +.EX +.B .ALIAS PS PT_SIZE +.EE +.RE +would allow you to set +.I point sizes +with +.BR .PS . +. +.RE +. +. +.\" ==================================================================== +.\" Right Margin +.\" ==================================================================== +.TP +.BI .R_MARGIN " " +Right Margin +. +.RS +. +.P +Requires a unit of measure. +. +.P +IMPORTANT: +.BR .R_MARGIN , +if used, must come after +.BR .PAPER , +.BR .PAGEWIDTH , +.BR .L_MARGIN , +and/or +.B .PAGE +(if a right margin isn't given to PAGE). +. +The reason is that +.B .R_MARGIN +calculates line length from the overall page dimensions and the left +margin. +. +.P +Obviously, it can't make the calculation if it doesn't know the page +width and the left margin. +. +.P +.B .R_MARGIN +establishes the amount of space you want between the end of typeset +lines and the right hand edge of the printer sheet. +. +In other words, it sets the line length. +.B .R_MARGIN +requires a unit of measure. +. +Decimal fractions are allowed. +. +.P +The line length macro (LL) can be used in place of +.BR .R_MARGIN . +. +In either case, the last one invoked sets the line length. +. +The choice of which to use is up to you. +. +In some instances, you may find it easier to think of a section of +type as having a right margin. +. +In others, giving a line length may make more sense. +. +.P +For example, if you're setting a page of type you know should have +6-pica margins left and right, it makes sense to enter a left and +right margin, like this: +.RS +.EX +.B .L_MARGIN 6P +.B .R_MARGIN 6P +.EE +.RE +. +.P +That way, you don't have to worry about calculating the line +length. +. +On the other hand, if you know the line length for a patch of type +should be 17 picas and 3 points, entering the line length with LL is +much easier than calculating the right margin, e.g., +.RS +.EX +.B .LL 17P+3p +.EE +.RE +. +.P +If you use the macros +.BR .PAGE , +.B .PAGEWIDTH +or +.B PAPER +without invoking +.B .R_MARGIN +afterward, +.I mom +automatically sets +.B .R_MARGIN +to +.IR "1 inch" . +. +If you set a line length after these macros (with +.BR .LL ), +the line length calculated by +.B .R_MARGIN +is, of course, overridden. +. +.P +Note: +.B .R_MARGIN +behaves in a special way when you're using the document processing +macros. +. +.RE +. +. +.\" ==================================================================== +.\" ST - Set String Tabs +.\" ==================================================================== +.TP +.FONT B .ST I " " B "L | R | C | J [ QUAD ]" +. +.RS +.P +After +.I string tabs +have been marked off on an input line (see +.BR \[rs]*[ST].\|.\|.\&\[rs]*[STX] ), +you need to +.I set +them by giving them a direction and, optionally, the +.B \%QUAD +argument. +. +.P +In this respect, +.B .ST +is like +.B \%.TAB_SET +except that you don't have to give +.B .ST +an indent or a line length (that's already taken care of, inline, +by +.BR \[rs]*[ST].\|.\|.\&\[rs]*[STX] ). +. +.P +If you want string +.I tab 1 +to be +.BR \%left , +enter +.RS +.EX +.B .ST 1 L +.EE +.RE +. +If you want it to be +.I \%left +and +.IR \%filled , +enter +.RS +.EX +.B .ST 1 L \%QUAD +.EE +.RE +. +If you want it to be justified, enter +.RS +.EX +.B .ST 1 J +.EE +.RE +. +.RE +. +. +.\" ==================================================================== +.\" TAB - Call Tabs +.\" ==================================================================== +.TP +.BI \%.TAB " " +After +.I tabs +have been defined (either with +.B \%.TAB_SET +or +.BR .ST ), +.B \%.TAB +moves to whatever +.I tab number +you pass it as an argument. +. +.RS +. +.P +For example, +.RS +.EX +.B \%.TAB 3 +.EE +.RE +moves you to +.IR "\%tab 3" . +. +.P +Note: +.B \%.TAB +breaks the line preceding it and advances 1 linespace. +. +Hence, +.RS +.EX +.B .TAB 1 +.B A line of text in tab 1. +.B .TAB 2 +.B A line of text in tab 2. +.EE +.RE +produces, on output +.RS +.EX +.B "A line of text in tab 1." +.B " A line of text in tab 2." +.EE +.RE +. +. +.P +If you want the tabs to line up, +use +.B .TN +(\[lq]Tab Next\[rq]) +or, +more conveniently, +the inline escape sequence +.BR \[rs]*[TB+] : +.RS +.EX +.BR .TAB \~1 +A line of text in tab 1.\[rs]*[TB+] +A line of text in tab 2. +.EE +.RE +which produces +.RS +.EX +.B "A line of text in tab 1.\& A line of text in tab 2." +.EE +.RE +. +. +.P +If the text in your tabs runs to several lines, and you want the first +lines of each tab to align, you must use the multi-column macros. +. +.P +.I Additional note: +Any indents in effect prior to calling a tab are automatically turned +off by +.BR TAB . +. +If you were happily zipping down the page with a left indent of +.I 2 picas +turned on, and you call a +.I tab +whose indent from the left margin is +.IR "6 picas" , +your new distance from the +.I left margin +will be +.IR "6 picas" , +not +I 6 picas plus the 2 pica +indent. +. +.P +.I \%Tabs +are not by nature columnar, which is to say that if the text inside a +.I tab +runs to several lines, calling another +.I tab +does not automatically move to the baseline of the first line in the +.IR "previous tab" . +. +To demonstrate: +.RS +.EX +TAB 1 +Carrots +Potatoes +Broccoli +\&.TAB 2 +$1.99/5 lbs +$0.25/lb +$0.99/bunch +.EE +.RE +produces, on output +.RS +.EX +Carrots +Potatoes +Broccoli + $1.99/5 lbs + $0.25/lb + $0.99/bunch +.EE +.RE +. +.RE +. +.\" ==================================================================== +.\" TB - Call Tabs Alias +.\" ==================================================================== +.TP +.BI .TB " " +Alias to +.B .TAB +. +. +.\" ==================================================================== +.\" TI - TEMPORARY (LEFT) INDENT +.\" ==================================================================== +.TP +.BI "\%.TI [" " " ] +Temporary left indent \[em] the optional argument requires a +.I unit of measure +. +.RS +. +.P +A temporary indent is one that applies only to the first line of text +that comes after it. +. +Its chief use is indenting the first line of paragraphs. +.RB ( Mom's +.B .PP +macro, for example, uses a +.IR "temporary indent" .) +. +.P +The first time you invoke +.BR .TI , +you must give it a measure. +. +If you want to +.I indent +the first line of a paragraph by, say, 2 ems, do +.RS +.EX +.B .TI 2m +.EE +.RE +. +.P +Subsequent invocations of +.B .TI +do not require you to supply a measure; +.I mom +keeps track of the last measure you gave it. +. +.P +Because +.I temporary indents +are temporary, there's no need to turn them off. +. +.P +.I IMPORTANT: +Unlike +.BR .IL , +.B .IR +and +.BR IB , +measures given to +.B .TI +are NOT additive. +. +In the following example, the second +.B \%".TI 2P" +is exactly +.IR "2 picas" . +.RS +.EX +.B .TI 1P +.B The beginning of a paragraph.\|.\|.\& +.B .TI 2P +.B The beginning of another paragraph.\|.\|.\& +.EE +.RE +. +.RE +. +. +. +.\" ==================================================================== +.\" TN - Tab Next +.\" ==================================================================== +.TP +.B .TN +Tab Next +. +.RS +.P +Inline escape +.B \[rs]*[TB+] +. +.P +.B TN +moves over to the +.I next tab +in numeric sequence +.RI ( "tab n+1" ) +without advancing on the page. +. +See the +.I NOTE +in the description of the +.B \%.TAB +macro for an example of how +.B TN +works. +. +.P +In +.I \%tabs +that aren't given the +.B QUAD +argument when they're set up with +.B \%.TAB_SET +or +.BR ST , +you must terminate the line preceding +.B .TN +with the +.B \[rs]c +inline escape sequence. +. +Conversely, if you did give a +.B QUAD +argument to +.B \%.TAB_SET +or +.BR ST , +the +.B \[rs]c must not be used. +. +.P +If you find remembering whether to put in the +.B \[rs]c +bothersome, you may prefer to use the inline escape alternative +to +.BR .TN , +.BR \[rs]*[TB+] , +which works consistently regardless of the fill mode. +. +.P +.I Note: +You must put text in the input line immediately after +.BR .TN . +. +Stacking of +.BR .TN 's +is not allowed. +. +In other words, you cannot do +.RS +.EX +\&.TAB 1 +Some text\[rs]c +\&.TN +Some more text\[rs]c +\&.TN +\&.TN +Yet more text +.EE +.RE +. +The above example, assuming +.I tabs +numbered from +.I 1 +to +.IR 4 , +should be entered +.RS +.EX +\&.TAB 1 +Some text\[rs]c +\&.TN +Some more text\[rs]c +\&.TN +\[rs]&\[rs]c +\&.TN +Yet more text +.EE +.RE +. +\[rs]& is a zero-width, non-printing character that +.I groff +recognizes as valid input, hence meets the requirement for input text +following +.BR .TN . +. +.RE +. +. +.\" ==================================================================== +.\" Tab Quit +.\" ==================================================================== +.TP +.B .TQ +.B TQ +takes you out of whatever +.I tab +you were in, advances +.IR "1 linespace" , +and restores the +.IR "left margin" , +.IR "line length" , +.I quad direction +and +.I fill mode +that were in effect prior to invoking any +.IR tabs . +. +. +.\" ==================================================================== +.\" Top Margin +.\" ==================================================================== +.TP +.BI .T_MARGIN " " +Top margin +. +.RS +. +.P +Requires a unit of measure +. +.P +.B .T_MARGIN +establishes the distance from the top of the printer sheet at which +you want your type to start. +. +It requires a unit of measure, and decimal fractions are allowed. +. +To set a top margin of 2\(12 centimetres, you'd enter +.RS +.EX +.B .T_MARGIN 2.5c +.EE +.RE +. +.B .T_MARGIN +calculates the vertical position of the first line of type on a page +by treating the top edge of the printer sheet as a baseline. +Therefore, +.RS +.EX +.B .T_MARGIN 1.5i +.EE +.RE +puts the baseline of the first line of type 1\(12 inches beneath the +top of the page. +. +.P +Note: +.B .T_MARGIN +means something slightly different when you're using the document +processing macros. +. +See Top and bottom margins in document processing for an explanation. +. +.P +IMPORTANT: +.B .T_MARGIN +does two things: it establishes the top margin for pages that come +after it and it moves to that position on the current page. +. +Therefore, +.B .T_MARGIN +should only be used at the top of a file (prior to entering text) or +after NEWPAGE, like this: +.RS +.EX +.B .NEWPAGE +.B .T_MARGIN 6P +.I +.EE +.RE +. +.RE +. +. +.\" ==================================================================== +.SH Authors +.\" ==================================================================== +. +.I mom +was written by +.MT peter@\:schaffter\:.ca +Peter Schaffter +.ME . +. +PDF support was provided by +.MT deri@\:chuzzlewit\:.myzen\:.co\:.uk +Deri James +.ME . +. +This manual page was written by Bernd Warken. +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.TP +.I @HTMLDOCDIR@/\:mom/\:toc\:.html +entry point to the HTML documentation +. +. +.TP +.UR http://\:www\:.schaffter\:.ca/\:mom/\:momdoc/\:toc\:.html +.UE +HTML documentation online +. +. +.TP +.UR http://\:www\:.schaffter\:.ca/\:mom/ +.UE +the +.I mom +macros homepage +. +. +.P +.IR "Groff: The GNU Implementation of troff" , +by Trent A.\& Fisher and Werner Lemberg, +is the primary +.I groff +manual. +. +You can browse it interactively with \[lq]info groff\[rq]. +. +. +.P +.MR pdfmom @MAN1EXT@ , +.MR groff @MAN1EXT@ , +.MR @g@troff @MAN1EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_groff_mom_7_man_C] +.do rr *groff_groff_mom_7_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/contrib/mom/mom.am b/contrib/mom/mom.am new file mode 100644 index 0000000..3bbbc9a --- /dev/null +++ b/contrib/mom/mom.am @@ -0,0 +1,182 @@ +# Copyright (C) 2002-2020 Free Software Foundation, Inc. +# Written by Werner Lemberg +# Automake migration by Bertrand Garrigues +# +# +# This file 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 . + +mom_srcdir = $(top_srcdir)/contrib/mom + +# pdfmom command used to generate .pdf +# +# Use '-K utf8', not '-k', in case 'configure' didn't find uchardet. +MOMPDFMOM = \ + GROFF_COMMAND_PREFIX= \ + GROFF_BIN_PATH="$(GROFF_BIN_PATH)" \ + PDFMOM_BIN_PATH="$(top_builddir)" \ + $(PDFMOMBIN) $(FFLAG) $(MFLAG) -M$(mom_srcdir) -K utf8 -p -e -t + +man7_MANS += contrib/mom/groff_mom.7 + +# Files installed in $(tmacdir). +# MOMNORMALFILES are located in the source tree. +MOMNORMALFILES = \ + contrib/mom/mom.tmac \ + contrib/mom/om.tmac +momtmacdir = $(tmacdir) +dist_momtmac_DATA = $(MOMNORMALFILES) + +# Files installed in htmldocdir/mom +MOMHTMLDOCFILES=\ + contrib/mom/momdoc/stylesheet.css \ + contrib/mom/momdoc/appendices.html \ + contrib/mom/momdoc/color.html \ + contrib/mom/momdoc/cover.html \ + contrib/mom/momdoc/definitions.html \ + contrib/mom/momdoc/docelement.html \ + contrib/mom/momdoc/docprocessing.html \ + contrib/mom/momdoc/goodies.html \ + contrib/mom/momdoc/graphical.html \ + contrib/mom/momdoc/headfootpage.html \ + contrib/mom/momdoc/images.html \ + contrib/mom/momdoc/inlines.html \ + contrib/mom/momdoc/intro.html \ + contrib/mom/momdoc/letters.html \ + contrib/mom/momdoc/macrolist.html \ + contrib/mom/momdoc/rectoverso.html \ + contrib/mom/momdoc/refer.html \ + contrib/mom/momdoc/reserved.html \ + contrib/mom/momdoc/tables-of-contents.html \ + contrib/mom/momdoc/toc.html \ + contrib/mom/momdoc/typesetting.html \ + contrib/mom/momdoc/using.html \ + contrib/mom/momdoc/version-2.html +momhtmldir = $(htmldocdir)/mom +momhtml_DATA = $(MOMHTMLDOCFILES) + +# Files installed in $(examplesdir)/mom. MOMEXAMPLEFILES are located +# in the source tree, while MOMPROCESSEDEXAMPLEFILES are generated in +# the build tree. +MOMEXAMPLEFILES=\ + contrib/mom/examples/letter.mom \ + contrib/mom/examples/mom-pdf.mom \ + contrib/mom/examples/mon_premier_doc.mom \ + contrib/mom/examples/sample_docs.mom \ + contrib/mom/examples/typesetting.mom \ + contrib/mom/examples/README.txt \ + contrib/mom/examples/README-fr.txt \ + contrib/mom/examples/elvis_syntax \ + contrib/mom/examples/elvis_syntax.new \ + contrib/mom/examples/penguin.ps \ + contrib/mom/examples/penguin.pdf \ + contrib/mom/examples/mom.vim \ + contrib/mom/examples/slide-demo.mom \ + contrib/mom/examples/copyright-default.mom \ + contrib/mom/examples/copyright-chapter.mom +momexampledir = $(exampledir)/mom +dist_momexample_DATA = $(MOMEXAMPLEFILES) + +if USE_GROPDF +MOMPROCESSEDEXAMPLEFILES = \ + contrib/mom/examples/letter.pdf \ + contrib/mom/examples/mom-pdf.pdf \ + contrib/mom/examples/mon_premier_doc.pdf \ + contrib/mom/examples/sample_docs.pdf \ + contrib/mom/examples/slide-demo.pdf \ + contrib/mom/examples/copyright-default.pdf \ + contrib/mom/examples/copyright-chapter.pdf +if HAVE_URW_FONTS +MOMPROCESSEDEXAMPLEFILES += contrib/mom/examples/typesetting.pdf +endif +momprocessedexampledir = $(exampledir)/mom +nodist_momprocessedexample_DATA = $(MOMPROCESSEDEXAMPLEFILES) +endif + +mom_test_template = contrib/mom/examples/test-mom.sh.in + +# Small test suite on mom examples +mom_TESTS = contrib/mom/examples/tests-mom.sh +TESTS += $(mom_TESTS) +contrib/mom/examples/tests-mom.sh: \ + $(top_builddir)/config.status \ + $(MOMPROCESSEDEXAMPLEFILES) \ + $(top_srcdir)/$(mom_test_template) + $(AM_V_GEN)sed \ + -e "s|[@]abs_top_builddir[@]|$(abs_top_builddir)|g" \ + -e "s|[@]groff_have_urw_fonts[@]|$(groff_have_urw_fonts)|g" \ + $(top_srcdir)/$(mom_test_template) > $@ \ + && chmod +x $@ +MOSTLYCLEANFILES += $(mom_TESTS) +EXTRA_DIST += $(mom_test_template) + +# For this list of files we add a symlink from $(exampledir)/mom to $(pdfdocdir) +PDFDOCFILE = mom-pdf.pdf + +EXTRA_DIST += $(MOMHTMLDOCFILES) $(MOMEXAMPLEFILES) \ + contrib/mom/BUGS \ + contrib/mom/ChangeLog \ + contrib/mom/NEWS \ + contrib/mom/TODO \ + contrib/mom/copyright \ + contrib/mom/groff_mom.7.man + +MOSTLYCLEANFILES += \ + $(MOMPROCESSEDEXAMPLEFILES) \ + penguin.ps \ + penguin.pdf + +# rule to generate .pdf files from .mom files +SUFFIXES += .mom .pdf +.mom.pdf: + $(GROFF_V)$(MKDIR_P) `dirname $@` \ + && LC_ALL=C $(MOMPDFMOM) $< >$@ + +$(MOMPROCESSEDEXAMPLEFILES): $(MOMNORMALFILES) \ + groff troff gropdf pdfmom penguin.ps penguin.pdf font/devpdf/stamp + +penguin.ps: + $(AM_V_at)cp $(mom_srcdir)/examples/penguin.ps $@ +penguin.pdf: + $(AM_V_at)cp $(mom_srcdir)/examples/penguin.pdf $@ + +install-data-hook: install_mom +install_mom: +if USE_GROPDF + for f in $(PDFDOCFILE); do \ + $(RM) $(DESTDIR)$(pdfdocdir)/$$f; \ + ln -s $(exampledir)/mom/$$f $(DESTDIR)$(pdfdocdir)/$$f; \ + done +endif + +uninstall_groffdirs: uninstall_mom +uninstall_mom: + for f in $(PDFDOCFILE); do \ + $(RM) $(DESTDIR)$(pdfdocdir)/$$f; \ + done + -rmdir $(DESTDIR)$(pdfdocdir) + if test -d $(DESTDIR)$(exampledir)/mom; then \ + rmdir $(DESTDIR)$(exampledir)/mom; \ + fi + if test -d $(DESTDIR)$(htmldocdir)/mom; then \ + rmdir $(DESTDIR)$(htmldocdir)/mom; \ + fi + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/contrib/mom/mom.tmac b/contrib/mom/mom.tmac new file mode 100644 index 0000000..7a6494b --- /dev/null +++ b/contrib/mom/mom.tmac @@ -0,0 +1,3 @@ +.\" -*- nroff -*- mom.tmac +.\" +.do mso om.tmac diff --git a/contrib/mom/momdoc/appendices.html b/contrib/mom/momdoc/appendices.html new file mode 100644 index 0000000..964a2ab --- /dev/null +++ b/contrib/mom/momdoc/appendices.html @@ -0,0 +1,901 @@ + + + + + + + + + Mom -- Appendices + + + + + + + +
+ + + + + + +
Back to Table of Contents
+ +

Appendices

+ + + +

+ +

Adding fonts to groff

+ +
+

+<prefix>, in this section, refers +to the directory in which groff is installed, typically +
+ + /usr/share/groff/ + +(for distro-specific, pre-compiled groff packages) or +
+ + /usr/local/share/groff/ + +(if you’ve built groff from source). +

+ +

+<version> refers to the groff version number, which +can be found, if necessary, by typing +
+ + groff -v + +at the command line. +

+
+ +

+Groff comes with a small library of +families +(see the +FAMILY +macro for a list). The families have four +fonts +associated with them. These fonts are a combination of +weight +and +shape: +
+ + R (Roman, usually Medium weight), + I (Italic, usually Medium weight), + B (Bold, usually Roman shape) and + BI (Bold Italic) + +If you work with mom a lot, sooner or later you’ll find that these +families and their associated fonts aren’t sufficient. You’ll +want to supplement them, either with more fonts for the families +already provided—Damn! I need Helvetica Bold Condensed +Italic—or with entire new families. +

+ +

Extending groff families / adding new families and fonts

+ +

The traditional approach

+ +

+The traditional approach to extending groff families has been +to create new families for non-default weights and shapes (e.g. +Light, which is a +weight, +or Condensed, which is a +shape), +then to associate them with groff’s predefined R, +I, B and BI font styles. An example of this +can be seen in the groff PostScript font library itself, which is +found in +
+ + <prefix>/<version>/font/devps/ + +There’s one “family” for Helvetica (HR, +HI, HB, HBI) and another for Helvetica Narrow +(HNR, HNI, HNB, HNBI). +

+ +

+The difficulty with this approach is that typographers tend to +think of families as referring to the entire set of font weights +and shapes associated with a family name. For example, when +a typesetter says “the Helvetica family”, s/he is +including the weights Helvetica Thin, Helvetica Light, Helvetica +Regular, Helvetica Bold, Helvetica Heavy, etc, and all their +associated shapes (Roman, Italic, Condensed, Narrow, Extended, +Outline, etc). +

+ +

+Thus, intuitively, when a typesetter gives mom a +.FAMILY H directive, s/he reasonably expects that +any subsequent .FT directive will access the desired font +from the Helvetica family—without the need to state explicitly +both family and font to .FT, as it is explained one can +do in the +FAMILY +and +FT +sections of these documents. +

+ +

+If one had, say, Helvetica Light Roman and Helvetica Light Italic +as well as Helvetica Light Condensed Roman and Helvetica Light +Condensed Italic, the established groff approach would require two +“partial” families, HL (for Helvetica Light) +and HLCD (for Helvetica Light Condensed), with R and +I fonts for both: +
+ + HLR + HLI + HLCDR + HLCDI + +Accessing these family/font combos routinely +throughout a document would then require changing the family +(with .FAMILY) and selecting the desired font +(with .FT R or .FT I), or +passing .FT the lengthy family+fontname (.e.g. +.FT HLCDI). +

+ +

The simpler way with mom

+ +

+Fortunately, groff provides a mechanism whereby it’s possible +to extend the basic R, I, B, and BI fonts +(“styles” in groff-speak) so that one can, in fact, +create extensive type families, and access all the fonts in them +with .ft (groff) or .FT (mom). +

+ +

+Mom uses this mechanism to offer, in addition to groff’s +default font styles, the following: +

+ +
+
+ +UL = Ultra Light +ULI = Ultra Light Italic +ULCD = Ultra Light Condensed +ULCDI = Ultra Light Condensed Italic +ULEX = Ultra Light Extended +ULEXI = Ultra Light Extended Italic + +XL = Extra Light +XLI = Extra Light Italic +XLCD = Extra Light Condensed +XLCDI = Extra Light Condensed Italic +XLEX = Extra Light Extended +XLEXI = Extra Light Extended Italic + +TH = Thin +THI = Thin Italic +THCD = Thin Condensed +THCDI = Thin Condensed Italic +THEX = Thin Extended +THEXI = Thin Extended Italic + +L = Light Roman +LI = Light Italic +LCD = Light Condensed +LCDI = Light Condensed Italic +LEX = Light Extended +LEXI = Light Extended Italic + +BK = Book Roman +BKI = Book Italic +BKCD = Book Condensed +BKCDI = Book Condensed Italic +BKEX = Book Extended +BKEXI = Book Extended Italic + +CD = Medium Condensed +CDI = Medium Condensed Italic +EX = Medium Extended +EXI = Medium Extended Italic + +DB = DemiBold Roman +DBI = DemiBold Italic +DBCD = DemiBold Condensed +DBCDI = DemiBold Condensed Italic +DBEX = DemiBold Extended +DBEXI = DemiBold Extended Italic + +SB = SemiBold Roman +SBI = SemiBold Italic +SBCD = SemiBold Condensed +SBCDI = SemiBold Condensed Italic +SBEX = SemiBold Extended +SBEXI = SemiBold Extended Italic + +
+ +BCD = Bold Condensed +BCDI = Bold Condensed Italic +BEX = Bold Extended +BEXI = Bold Extended Italic +BO = Bold Outline + +XB = Extra Bold +XBI = Extra Bold Italic +XBCD = Extra Bold Condensed +XBCDI = Extra Bold Condensed Italic +XBEX = Extra Bold Extended +XBEXI = Extra Bold Extended Italic + +UB = Ultra Bold +UBI = Ultra Bold Italic +UBCD = Ultra Bold Condensed +UBCDI = Ultra Bold Condensed Italic +UBEX = Ultra Bold Extended +UBEXI = Ultra Bold Extended Italic + +HV = Heavy +HVI = Heavy Italic +HVCD = Heavy Condensed +HVCDI = Heavy Condensed Italic +HVEX = Heavy Extended +HVEXI = Heavy Extended Italic + +BL = Black +BLI = Black Italic +BLCD = Black Condensed +BLCDI = Black Condensed Italic +BLEX = Black Extended +BLEXI = Black Extended Italic +BLO = Black Outline + +XBL = Extra Black +XBLI = Extra Black Italic +XBLCD = Extra Black +XBLCDI = Extra Black +XBLEX = Extra Black Italic +XBLEXI = Extra Black Italic + +UBL = Ultra Black +UBLI = Ultra Black Italic +UBLCD = Ultra Black Condensed +UBLCDI = Ultra Black Condensed Italic +UBLEX = Ultra Black Extended +UBLEXI = Ultra Black Extended Italic + +SC = Small Caps Roman +SCI = Small Caps Italic +SCDB = Small Caps Demibold +SCDBI = Small Caps Demibold Italic +SCSB = Small Caps Semibold +SCSBI = Small Caps Semibold Italic + +
+ +

+Thus, with mom, if you’ve installed some extra +Helvetica fonts and named them according to the convention +<F><S> (where <F> means +family and <S> means font style), once having +entered +
+ + .FAMILY H + +you can access any of the extra Helvetica fonts simply by passing +the correct argument to +FT +from the list, above. For example, if you were working in Medium +Roman (.FT R) and you needed Medium Condensed Italic +for a while (assuming it’s installed), you’d just type +
+ + .FT CDI + +to access the Medium Condensed Italic font from the Helvetica +family. +

+ +

+Mom’s list of font styles doesn’t pretend to be +exhaustive. The extension names are arbitrary and can be used in a +flexible manner. For example, if you create a family that has a +Demibold font (DB) but no Bold font (B), you might +find it more convenient to give the Demibold font the extension +“B”. +

+ +

+You may, at needs, want to add to mom’s list of font styles. +You can do this by editing the file, om.tmac (typical location: +<prefix>/<version>/tmac/om.tmac). Near the +top, you’ll see lines of the form +
+ + .sty \n[.fp] XL \" Extra Light + .sty \n[.fp] L \" Light Roman + .sty \n[.fp] LI \" Light Italic + .sty \n[.fp] LCD \" Light Condensed Roman + +Simply add your new font style by imitating what you see, above, +and plugging in your new font style (having, of course, +added the font to groff, correctly named); see +Step-by-step instructions). +

+ +

+For example, if you already have some fonts from the Univers family +installed and have called the family Univers, you might decide at +some point to add the Bold Outline font (UniversBO). In which +case, you’d add +
+ + .sty \n[.fp] BO \" Bold Outline + +to the .sty \n[.fp]  <font style> list +in om.tmac. +

+ +
+

+Note: +Mom’s font extensions are not “user-space” +controllable via a macro. If you’ve been using groff for +a long time, and have already rolled your own solution to adding +families and fonts to groff, you may find that mom’s font +extensions conflict with your own scheme. Should that be the case, +comment out the .sty \n[.fp] <font style> +lines found near the top of the om.tmac file. +

+
+ +
+

+Important: +Be careful that any styles you add do not conflict with +family names that already exist. “C”, +for example, conflicts with the Courier family (CR, +CI, CB, CI). Were you to create a font +style “C”, thinking that .FT C +would give you access to font style once you’d given a +.FAMILY directive, you’d get a nasty surprise: +your type would come out in Courier Roman! +

+
+ +

+ +

Step-by-step instructions

+ + + + +

+There are a number of ways to approach making fonts available +to groff. These instructions aren’t meant to cover all +possibilities, merely one. +

+ +

+GNU/Linux distributions being what they are, directory locations +may differ and the presence of some executable can’t be +guaranteed. I run a Debian-based system. The instructions reflect +that. Users of other distros may have to interpret them according +to the way their distro operates. +

+ +

What you need before you start

+ +
    +
  • groff, version 1.18 or higher
    + (Debian package: groff) +
  • +
  • ghostscript
    + (Debian package: ghostscript or ghostscript-x) +
  • +
  • fontforge
    + (Debian package: fontforge) +
  • +
+ +

Initial preparation (you only need do this once)

+ +
    +
  1. + Locate the groff directory, + site-font. The exact location is + difficult to predict, owing to differences between distros and + whether you’re using a pre-packaged groff or have built + it from source. Some typical locations are: +
    + + /usr/share/groff/ + /usr/local/share/groff/ + /etc/groff/ + + If you can’t find the site-font directory, locate + groff’s site-tmac directory, and, as root, + create site-font in the same directory. Eg, if you find + site-tmac in /usr/share/groff/, create site-font in + /usr/share/groff/ +
    + + sudo mkdir site-font + +
  2. +
  3. + Create two files, generate-t42.pe and generate-pfa.pe, + as you see them below. Place them in a convenient and + easily-remembered location, like your home directory. +
    + generate-t42.pe + +
    + +# generate-t42.pe + +Open($1); +Generate($fontname + ".pfa"); +Generate($fontname + ".t42"); + +
    +
    + generate-pfa.pe +
    + +# generate-pfa.pe + +Open($1); +Generate($fontname + ".pfa"); + +
    +
  4. +
+ +

Step 1: Acquire the font

+ +

+The two most commonly available types of fonts are PostScript Type1 +(extension .pfb) and TrueType (extension .ttf). Either can be made +available to groff. There are many websites holding collections of +both. +

+ +

Step 2: Prepare to convert the font to the correct format

+ +

+Change into the directory holding the new font. +

+ +

+For convenience in the next step, make a symbolic link to +the file 'textmap': +
+ + ln -s <prefix>/<version>/font/devps/generate/textmap . + +See +here +for an explanation of <prefix> +and <version>. +

+ +

+In addition, unless you’re installing fonts from your home +directory, make links to the files 'generate-t42.pe' and +'generate-pfa.pe'. +
+ + ln -s $HOME/generate-t42.pe . + ln -s $HOME/generate-pfa.pe . + +

+ +

Step 3: Convert the font and put it in the right place

+ +

+TrueType fonts (.ttf) need to be converted to .t42. Type 1 fonts +(.pfa, .pfb) need to be converted to .pfa. +

+ +

 • Converting TTF Fonts

+ +

+For .ttf fonts, run +
+ + fontforge -script generate-t42.pe <file>.ttf + +This will create three new files with the extensions .t42, .pfa, and +.afm. Next, run +
+ + afmtodit <afm file> textmap <groff font> + +This will create a groff font with the name you give. (See +here +for advice on naming groff fonts.) +

+ +

+Move the .t42 and groff font files to +<prefix>/site-font/devps/. +

+ +

+If you’re running a recent version of groff that includes +the native pdf device (gropdf), move the .pfa file to <prefix>/site-font/devpdf/. If not, you +may safely remove it. You may also safely remove the .afm file. +

+ +

 • Converting Type1 Fonts

+ +

+For .pfb fonts, run +
+ + fontforge -script generate-pfa.pe <file>.pfb + +This will create two new files with the extensions .pfa, and .afm. +Next, run +
+ + afmtodit <afm file> textmap <groff font> + +Move the .pfa and groff font files to +<prefix>/<site-font>/devps/. +(See +here +for advice on naming groff fonts.) +

+ +

+If you’re running a recent version of groff that includes the +native pdf device (gropdf), link the .pfa and groff font files, now +in <prefix>/<site-font>/devps/, +to the <prefix>/site-font/devpdf +directory. +

+ +

+Start by changing into the +<prefix>/site-font/devpdf/ +directory, then: +
+ + ln -s <prefix>/<site-font>/devps/<file>.pfa . + ln -s <prefix>/<site-font>/devps/<groff font> . + +You may safely remove the .afm file. +

+ +

Step 4: Update the download file

+ +

 • Get the internal font name

+ +

+Inspect your new groff font file. Near the top, you will see a line +of the form +
+ + internalname <name> + +Usually, the internal name is helpfully descriptive, e.g. +
+ + internalname Optima-Bold + +Make a note of the internal name. +

+ +

 • Add the font to the download file

+ +

+If a file called ‘download’ is not already present in +<prefix>/site-font/devps/, +copy over the one found in +<prefix>/<version>/font/devps/. +

+ +

+The download file maps the internal names used by groff to the +actual fonts. To add your new font to the download file, append a +line containing the internal name, followed by a tab (make sure your +text editor is inserting the tab character, not spaces), followed by +the .t42 or .pfa font to which the internal name refers. +

+ +

+For example, if the internal name is Optima-Bold and the font is a +.pfa file called Optima-Bold.pfa, your updated download file will +contain +
+ + Optima-Bold<tab>Optima-Bold.pfa + +

+ +

 • Updating the gropdf download file

+ +

+If you’re running a recent version of groff that includes +the native pdf device (gropdf), you must update the +<prefix>/site-font/devpdf/download +file as well. If it does not exist, create it. +

+ +
+

+Note: +Start with a blank ‘download’ file. Do not copy +over the ‘download’ file from +<prefix>/<version>/font/devpdf/. +

+
+ +

+The instructions for registering fonts in the +<prefix>/site-font/devpdf/ download +file are identical to those for PostScript fonts (see above), but +with one important difference: the lines must all begin with a tab +character. Thus, using our Optima example, your +<prefix>/site-font/devpdf/download +file download line for the same font is +
+ + <tab>Optima-Bold<tab>Optima-Bold.pfa + +

+ +

Naming groff fonts

+ +

+For convenience when using mom, and to keep your font collection +organized, choose meaningful groff font names following the scheme +<Family><FONT>, where Family is something +like Optima or Univers or Clarendon, and FONT is either +
+ +R  (roman/regular) +
+I  (italic) +
+B  (bold) +
+BI (bold italic) +
+or one of the 1–5 character fontstyles listed +here. +Thus, for the fonts Optima Light Italic and Optima Extra Black, your font names would be +
+ + OptimaLI + OptimaXBL + +This scheme allows you to enter .FAMILY Optima to make +Optima the current family, and .FT LI or .FT XBL +when you need the fonts Light Italic or Extra Black. +

+ +

+Groff font names are, in fact, arbitrary; you can call your fonts +anything you like, provided the +internal name +in the +download file +matches the internal name found in the groff font file. When +calling a font that does not follow the recommended naming convention, +you must pass the full font name to .FT whenever you wish +to use it. +

+ +

+For example, the font, Goudy Stout, isn’t really part of the +Goudy family, and while "stout" describes it, Stout is not a +recognized font style. Therefore, its groff name could simply be +GoudyStout, and whenever you needed it, you could call it with +.FT GoudyStout. +

+ +

Automate the whole process – the install-font script

+ +

+A bash script to make the entire process of installing fonts a +painless no-brainer has been posted online at +https://www.schaffter.ca/mom/bin/install-font.sh. +Be sure to make the script executable +(chmod 755 install-font) +after you download it, then type ./install-font.sh -H for +usage. +

+ +

+ + + +

Some reflections on mom

+ +

+If, as Eric Raymond asserts, open source begins with a programmer +scratching a personal itch, then mom can truly be called open +source. +

+ +

+Mom had her origins in a library of groff routines I wrote over +the years to handle various aspects of typesetting and document +processing that weren’t adequately covered by ms, me, mm, and +friends. Typically, I’d use the library to cobble together +macro sets for new challenges as they came my way. +

+ +

+As a writer living in a perpetual state of penury, all the computers +I’ve ever owned have been hand-me-downs—several +generations out-of-date and resource challenged. Disk space has +always been an issue, as has processor speed and available RAM. One +of the reasons I run GNU/Linux rather than the offering from Redmond +is that it has helped enormously to get the most out of my poor +little boxes. +

+ +

+In Linux-land (all Unix variants, in fact), the choice of +typesetting systems basically comes down to groff or TeX. Both are +wonderful—monumental achievements if you ask me—and both +have their own particular strengths. However, for people in my +financial position (and there are millions of us around the globe, +in both developed and developing countries), TeX and groff have one +big difference: size. TeX is huge. Even its most ardent supporters +agree it suffers from bloat, on top of being complex and unwieldy to +manage. Groff is tiny by comparison, occupying minimal disk space +and having only a small memory footprint while at the same time +being flexible and powerful, typographically speaking. Back in the +Jurassic Period, I ran it successfully on a 386 with 8 megs of RAM +and a 250 meg hard disk. +

+ +

+However, groff has always had a liability: it’s incredibly geeky. +Owing to its very long history, it—and its power users +—seem to have remained stuck in a time warp. The canonical macro packages +still look as they did back in those decades when memory was exorbitantly +expensive and every byte mattered. +

+ +

+For some time now, groff users and macro writers have had the option +to use “long” names for macros (i.e. longer than two +letters, the original limit), yet have mostly chosen not to. With +long names, it’s possible to create macro sets that are +humanly readable and easy to interpret, encouraging development and +evolution. What’s more, the macros themselves need not be +terse, intimidating, and easily forgotten 1- or 2-letter commands +inserted in the body of a document. They can be sensible and +helpful to everyone, groff newbies and old hands alike. +

+ +

+Mom’s macro file, om.tmac, uses long names, aliases, and a +host of other groff goodies that have become part of the whole groff +picture. The function of nearly every macro, number register and +string can be inferred simply from its name. The file is heavily +commented. A consistent, if idiosyncratic, indenting style is used +as well, significantly improving readability. Anyone wanting to +futz around with mom’s macros should be able to do so with a +minimum of head scratching. +

+ +

+ + + +

Contact the author

+ +

+If you have any questions or comments about mom, suggestions to +make, criticisms to offer, or bugs to report, use the groff mailing +list (subscription information available +here) +or contact me, Peter Schaffter, directly at the following +address: +
+ + peter@schaffter.ca + +Please include the word “mom” or “groff” in +the Subject line of any message sent to my personal address or you +risk the wrath of my implacable spam filters. +

+ +

+If you want to visit mom’s website, you’ll find a link +to it at +
+ + https://www.schaffter.ca + +The site contains links to some of my fiction, all of which was +typeset with mom and groff. +

+ +

+ + + + + + + +
Back to Table of ContentsTop
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/color.html b/contrib/mom/momdoc/color.html new file mode 100644 index 0000000..f53b5c0 --- /dev/null +++ b/contrib/mom/momdoc/color.html @@ -0,0 +1,505 @@ + + + + + + + + + Mom -- Colour + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: Graphical objects
+ +

Coloured text

+ + + +

+ +

Introduction

+ +

+Mom’s support for coloured text is straightforward. You begin +by telling mom about the colours you want with +NEWCOLOR +or +XCOLOR. +Afterwards, any time you want text to be coloured, you either colour +it with an +inline escape +that contains the colour name (e.g. \*[red] +or \*[blue]) or invoke the macro +COLOR +with the name of the colour you want. +

+ +

+For example, say you want to have the name “Jack” in the +sentence “All work and no play makes Jack a dull boy” +appear in yellow. You’d begin by telling mom about the colour, +yellow. There are two ways of doing this; see +NEWCOLOR +and +XCOLOR +for a full explanation of the difference between the two. +

+ +

+If you use XCOLOR, you’d enter this: +
+ + .XCOLOR yellow + +If you use NEWCOLOR, you might enter: +
+ + .NEWCOLOR yellow RGB #FFFF00 + +

+ +

+After defining or initializing the colour yellow you’d +colourise the name, Jack, either with an inline escape +
+ + All work and no play makes \*[yellow]Jack\*[black] a dull boy. + +or with the +COLOR +macro +
+ + All work and no play makes + .COLOR yellow + Jack + .COLOR black + a dull boy. + +Notice, in both examples, that a) you have to set the colour back +to black after “Jack,” and b) you don’t have to +define or initialize the colour, black. Mom predefines it for you. +

+ +

+For information on using colour during +document processing, +see +Colour support in document processing. +

+ +
+

+Note: +Mom’s colour support is for text only. She doesn’t +support “fill” (or “background”) colour for +solid, enclosed graphical objects (polygons, ellipses) drawn with +groff’s \D +inline escapes, +although you may give a colour as one of the arguments to +mom’s “box” and “circle” macros, +DBX +and +DCL +when the first argument to these macros is SOLID. +

+
+ +
+

+Experts: +If you’re accustomed to using groff’s +.defcolor to define colours, and groff’s inline +\m[<colorname>] to call them, you may continue to +do so without confusing mom. +

+
+ +
+

Coloured text macros

+ + +
+ +

+ + + +
+

Creating (initializing) a colour with NEWCOLOR

+
+ +
+Macro: NEWCOLOR <colour name> [<colour scheme>] <colour components> +
+ +

+NEWCOLOR lets you create a colour, rather like an artist mixing +paint on a palette. The colour isn’t used immediately; +NEWCOLOR merely tells mom how to mix the colour when you need it. +If you haven’t invoked .NEWCOLOR (or +.XCOLOR), +mom doesn’t have a clue what you mean when you reference a +colour (with +COLOR +or +\*[<colour name>]). +

+ +

+The first argument to NEWCOLOR is a name for your colour. It +can be anything you like—provided it’s just one word +long—and can be caps, lower case, or any combination of the +two. +

+ +

+The second argument, which is entirely optional, is the +“colour scheme” you want mom to use when mixing the +colour. Valid arguments are +
+ + RGB (3 components: red green blue) + CYM (3 components: cyan yellow magenta) + CMYK (4 components: cyan magenta yellow black) + GRAY (1 component) + +If you omit the second argument, mom assumes you +want RGB. +

+ +

+The final argument is the components of your colour. This can be +hexadecimal string starting with a pound sign (#) (for +colour values in the 0-255 range) or two pound signs (##) +(for colour values in the 0-65535 range), or it can be a series of +decimal digits, separated by spaces, one digit per component, with +the argument enclosed in double quotes. (If this is all gibberish +to you, see +Tips for newbies.) +

+ +

+Thus, to tell mom about a colour named “YELLOW”, you +could enter one of the following: +
+ + .NEWCOLOR YELLOW #FFFF00 \"or ##FFFFFFFF0000 or "1 1 0" + .NEWCOLOR YELLOW RGB #FFFF00 \"or ##FFFFFFFF0000 or "1 1 0" + .NEWCOLOR YELLOW CMY #0000FF \"or ##0000FFFF0000 or "0 0 1" + .NEWCOLOR YELLOW CMYK #0000FF00 \"or ##00000000FFFF0000 or "0 0 1 0" + +After you’ve told mom about a colour, you can then get her to +set text in that colour either with the +inline escape, +\*[<colourname>], +or the macro +COLOR. +(See the +example, +above.) +

+ +
+

+Note: +The colourname you give to NEWCOLOR may be used with groff’s +\m[<colourname>] inline escape (the \m +escape is used to set text and rule colours). Thus, assuming +a colourname “blueblack” set with NEWCOLOR, +\*[blueblack] and \m[blueblack] +are equivalent. Furthermore, the colourname can be given as an +argument to groff’s +primitive +request, .gcolor (which does the same thing as +\m[<colourname>]). +

+ +

+Equally, the colourname may be used with +\M[<colourname>] and .fcolor, which set +the “fill” colour for solid graphical objects. +

+
+ +
+

+Tips for newbies: +Colour manipulation can be tremendously confusing if you don’t +have a background in graphic arts or computing. My advice, if colour +intimidates you, is to stick to using mom’s default RGB colour +scheme, and to fire up a colour chooser that gives you the RGB values +you want for the colour you select. Plug those values into the +components argument to NEWCOLOR, and you’ll get the colour +you want. Both the KDE and gnome desktops have colour selectors +that provide you with the shorter RGB hexadecimal string. If +you’re not running KDE or gnome, the X utility, xcolorsel, +provides you with a similar functionality, although it only provides +RGB values for 256 pre-defined colours. If you use xcolorsel, be +sure to click the button “Display format” and select +“8 bit truncated rgb”. +

+ +

+Alternatively, you can use mom’s simpler +XCOLOR +macro to initialize one of the 256 pre-defined X colours by +supplying the name of the colour as an argument. +

+
+ + + +
+

Initializing a colour with XCOLOR

+
+ +
+Macro: XCOLOR <X colourname> [<alias>] +
+ +

+<X colourname> must be all one word, all lower case. +
+(See +Finding X colour names +for how to get a list of valid colour names.) +

+ +

+XCOLOR is similar to NEWCOLOR in that it tells mom to initialize a +colour, but it’s easier to use. All you have to do is pass +it, as an argument, the valid name of one of the 256 pre-defined +X colours. The name must be all one word, and, breaking with mom +policy, it must be entered in lower case. +

+ +

+For example, if you want to initialize the X colour, coral, all you +have to do is enter +
+ + .XCOLOR coral + +Afterwards +
+ + .COLOR coral + + +will colourise subsequent text coral until you instruct mom to +return to black, or some other pre-defined, initialized colour. +(The +inline escape +\*[coral] will equally colourise text coral +after you’ve initialized the colour with XCOLOR.) +

+ +

+The downside of XCOLOR is that you can’t create custom +colours. This restriction, however, is mitigated by the fact that +for many users, 256 colours is more than enough to play around with. +

+ +

+While some X colours have fanciful names (peachpuff, papayawhip, +thistle, snow), many are self-explanatory and self-descriptive +in ordinary colour terms. “blue” is pure (rgb) +blue, “green” is pure (rgb) green, and so on. +Furthermore, for many X colours, there exist four variants, each +representing increasingly darker shades of the same colour. +For example, “blue1” is a relatively bright blue; +“blue2”, “blue3” and “blue4” are +increasingly darker shades. For that reason, you may find XCOLOR is +a better choice than NEWCOLOR when it comes to initializing common +colours. +

+ +

+The whimsical nature of X colour names sometimes makes for names +that are long to type in, e.g. “mediumspringgreen”. The +optional second argument to XCOLOR allows you to come up with more +convenient name by which to reference the colour. For example, you +could enter +
+ + .XCOLOR mediumspringgreen mygreen + +or + + .XCOLOR mediumspringgreen MYGREEN + +so that whenever you want text mediumspringgreen-ed, you can use +either .COLOR mygreen (or .COLOR MYGREEN) +or the inline escape +\*[mygreen] (or \*[MYGREEN].) +

+ +

Finding X colour names

+ +

+There are two ways of finding the names of the pre-defined X +colours. One is to consult the file, rgb.txt, included with all +X11 installations. The location of the file on a Debian GNU/Linux +distribution is typically /etc/X11/rgb.txt. Other distributions and +other X installations may have the file in another location. The +file lists the colour names, but doesn’t show you what the +colours actually look like. +

+ +

+A better way to get the colour names, as well as to see what the +colours look like, is to fire up a colour chooser (like xcolorsel) +that both lists the colour names and shows a swatch of the colour +as well. +

+ +

+Whichever method you use to find X colour names, remember that the +names, passed as arguments to XCOLOR, must be all one word, all in +lower case. +

+ +
+

+Note: +Both the colourname and the alias you give to XCOLOR may be +used with groff’s \m[<colourname>] +inline escape (the \m escape is used to set +text and rule colours). Thus, assuming an X-colourname +“mediumspringgreen” set with +XCOLOR, and an alias, “mygreen”, +\*[mediumspringgreen], +\m[mediumspringgreen], +\*[mygreen] and +\m[mygreen] are all equivalent. +Furthermore, both the colourname and the alias can be given as an +argument to groff’s +primitive +request, .gcolor (which does the same thing as +\m[<colourname>]). +

+ +

+The colourname initialized with XCOLOR but not the +alias may also be used with groff’s inline escape, +\M[<colorname>], and the corresponding primitive, +.fcolor, both of which set the “fill” colour +for solid graphical objects. If you need a colour initialized with +XCOLOR for \M or .fcolor, you MUST give the +full colourname; the alias won’t work. +

+
+ + + +
+

Invoking a colour

+
+ +
+Macro: COLOR <colourname> +
+ +

+Inline: \*[<colourname>] +

+ +

+Once you’ve told mom about a colour (via +NEWCOLOR +or +XCOLOR, +you use either the macro COLOR or the +inline escape, +\*[<colourname>], to cause mom to set +subsequent text in that colour. See the +example, +above, which shows both in action. +

+ +
+

+Note: +You can use the \*[<colourname>] +inline escape in any +document processing +macro that takes a +string argument. +However, you must remember to reset the colour at the end of the +argument (typically with \*[black]) unless +you want all subsequent invocations of that particular macro to be +colourised. +

+ +

+Furthermore, if you use +\*[<colourname>] in the string +argument passed to +HEADING <n> +and you’ve requested that the heading level be numbered, the +numbers themselves will not be colourised, only the text you pass to +the macro. If you wish the numbers to be colourised along with the +text, you must explicitly tell mom with +HEADING_STYLE <n>. +

+ +

+For colourising underscored text, see +Colourising underscored text +in the notes at the end of +UNDERSCORE. +

+
+ +

+ + + + + + + + +
Back to Table of ContentsTopNext: Graphical objects
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/cover.html b/contrib/mom/momdoc/cover.html new file mode 100644 index 0000000..7efee1f --- /dev/null +++ b/contrib/mom/momdoc/cover.html @@ -0,0 +1,851 @@ + + + + + + + + + Mom -- Document processing, creating cover pages + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: Tables of contents
+ +

Creating cover pages

+ + + +

+ +

Introduction to cover pages

+ +

+Though identical in treatment, mom provides two kinds of cover +pages: document cover pages (”doc covers”) and section +cover pages (“covers”). Section cover pages are +analogous to title pages. +

+ +

+A doc cover is what you’d most likely use at the start of a +collated document, where you might want the name of the complete +document, the author(s) and the copyright line to appear. Another +place you might use a doc cover is for a novel, where you want the +title of the novel, not the chapter title or chapter number, as the +first cover page. +

+ +

+A cover is what you’d use for pages that separate sections +of a collated document, i.e. title pages. A cover page (but not a +doc cover) in a collated document could, for example, simply read: +”PART 1”. +

+ +

+In non-collated documents (say, an essay) you can use either a cover +or doc cover to generate the cover sheet. +

+ +

+In addition, nothing prevents you from generating both a doc cover +and a cover for every document in a collated document. Or you can +selectively disable the automatic generation of either doc covers or +covers in a collated document on-the-fly. +

+ +
+

+Important note: +Automatic generation of covers or doc covers after the first one(s) +only takes place if you are working with collated documents. Mom +provides no mechanism for saying ”print a section cover +here even though I’m still working on the same (non-collated) +document.” +

+
+ +

Description of cover pages

+ +

+By default, mom typesets covers and doc covers identically to +docheaders +(see +How to change the look of docheaders +for a description of what a docheader looks like). The only +differences are +

+
    +
  • the position on the page where the information is output
  • +
  • the (optional) addition of copyright and miscellaneous information
  • +
  • there’s no running text underneath, although you can add text + to a cover or doc cover (for example, an Abstract) with + COVERTEXT +
  • +
+ +

+You tell mom what you want to appear on cover pages through the +arguments you pass to +DOC_COVER +and/or +COVER. +Provided you have already given mom the appropriate reference macros +(e.g. +TITLE +or +AUTHOR), +she will output covers and doc covers identically to how she +would output docheaders containing the same information. +

+ +

+By default, mom starts covers and doc covers one-third of the way +down the page. This can be changed through the use of the control +macros DOC_COVER_START_POS / COVER_START_POS (or DOC_COVER_ADVANCE / +COVER_ADVANCE). +

+ +

+If you request copyright information (and have already given mom the +reference macro +COPYRIGHT) +she sets it, by default, in a smaller +point size +in the bottom right hand corner of the cover or doc cover. The +position, as well as all of the standard typesetting parameters, can be +altered via control macros. +

+ +

+Similarly, if you request miscellaneous information (and have +already given mom the reference macro +MISC) +she sets it, by default, in a smaller point size in the bottom left +hand corner of the cover or doc cover. As with the copyright, the +position and type specs can be altered via control macros. +

+ +

Headers/footers/pagination

+ +

+Mom does not set any +headers +or +footers +on cover pages. Neither does she set any page numbers. From +the point of view of pagination, covers and doc covers are by +default considered ”null” pages. If you wish them to +be included in the pagination scheme (even though no page numbers +appear), you must tell mom that’s what you want by invoking +
+ + .DOC_COVER_COUNTS_PAGES + +or +
+ + .COVER_COUNTS_PAGES + +

+ +

Designing your own cover pages

+ +

+Finally, if you want to design your own cover page(s), you can +typeset them by hand inside a +COVERTEXT +block using mom’s typesetting macros to format the text. +

+ +

Persistence of data and formatting

+ +

+Doc-cover and cover data—that is to say, the strings passed to +reference macros that appear on doc cover and cover +pages—does not persist after +START, +however the formatting of the various parts (TITLE, AUTHOR, +COPYRIGHT, etc.) does. +

+ + + + + +
+

DOC_COVER and COVER

+
+ +
+Macro: DOC_COVER (see argument list, below) +
+ +
+Macro: COVER (see argument list, below) +
+ +

+DOC_COVER and COVER behave identically. The reason mom provides +two macros for cover page generation is so that you can have two +different kinds of covers with different information on each. +

+ +

+Imagine, for a moment, you’ve written a document comprised of +three sections. When you +COLLATE +the document for output, you could use DOC_COVER to generate a cover +page that contained the name of the entire document, your (the +author’s) name, and perhaps the copyright date. Subsequently, +you could use COVER, after each .COLLATE but before each +.START, +to generate a cover page (title page, cover sheet) containing +just the name of the section, for example, “Part 1”. +

+ +

+The arguments to DOC_COVER and COVER tell mom +what you’d like on cover pages. You may give as many or as +few arguments as you need, in any order. A very common setup would +be: +
+ + .COVER TITLE AUTHOR COPYRIGHT + +

+ +

The argument list

+ +

+The arguments to COVER and DOC_COVER tell mom +what you want on the cover page: +
+ + TITLE | DOCTITLE | DOC_COVERTITLE | COVERTITLE + CHAPTER | CHAPTER_TITLE | CHAPTER+TITLE + SUBTITLE + AUTHOR + DOCTYPE + DOC_COVERTEXT | COVERTEXT + DOC_COVER_IMAGE | COVER_IMAGE + COPYRIGHT + MISC + PDF_OUTLINE_LABEL "<label>" + BLANKPAGE + +

+ +

What the arguments mean

+ +
+
TITLE
+
– the string(s) you gave to + TITLE +
+
DOCTITLE
+
– the string(s) you gave to + DOCTITLE +
+
DOC_COVERTITLE / COVERTITLE
+
– the string(s) you gave to + DOC_COVERTITLE + or + COVERTITLE +
+
CHAPTER, CHAPTER_TITLE, CHAPTER+TITLE
+
– see below, + How the CHAPTER argument and friends work +
+
SUBTITLE
+
– the string(s) you gave to + SUBTITLE +
+
AUTHOR
+
– the string(s) you gave to + AUTHOR +
+
DOCTYPE
+
– the string you gave to + DOCTYPE NAMED +
+
DOC_COVERTEXT / COVERTEXT
+
– the block of type you entered for + DOC_COVERTEXT + or + COVERTEXT +
+
DOC_COVER_IMAGE / COVER_IMAGE
+
– the image file you gave to + DOC_COVER_IMAGE + or + COVER_IMAGE +
+
COPYRIGHT
+
– the string you gave to + COPYRIGHT +
+
MISC
+
– the string(s) you gave to + MISC +
+
PDF_OUTLINE_LABEL <label>
+
+ + By default, mom identifies doc covers in the outline panel of PDF + viewers with the prepended label, “Cover:”, and covers + with the label “Title Page:”. If you would like + to change the label, give the PDF_OUTLINE_LABEL + argument to DOC_COVER or COVER along with the new label, in + quotation marks, as in this example: +
+   .COVER TITLE AUTHOR COPYRIGHT PDF_LABEL "Cover Sheet: " +
+
+
BLANKPAGE
+
+ + If the final argument to DOC_COVER or COVER is BLANKPAGE, + mom will insert a blank page after the doc cover or cover. This is + particularly useful if you intend to print your document two-sided, + since, in two-sided printing, there may be instances where you do + not want text on the reverse side of cover or title pages + + + If you enable + DOC_COVERS_COUNT_PAGES + and/or + COVERS_COUNT_PAGES, + the blank page will be taken into account in the pagination + scheme, though no page number appears on it. Otherwise, blank + pages are invisible to mom’s pagination. + +
+
+ +

+Please note that in all cases, if you have passed +a reference macro one of the optional arguments +DOC_COVER or COVER (e.g. +.TITLE DOC_COVER "Title"), mom will print the +appropriate string on the appropriate cover page. Thus, +
+ + .TITLE DOC_COVER "Collected Essays" + .TITLE COVER "1985-2015" + .TITLE "Neo-liberalism: Who Did They Think They Were Fooling?" + .DOC_COVER TITLE + .COVER TITLE + +will print “Collected Essays” on the doc cover page, +“1985-2015” on the cover page, and, assuming the +docheader hasn’t been disabled, “Neo-liberalism: Who +Did They Think They Were Fooling?” as the title in the +docheader. +

+ +

+Note that +
+ + .DOC_COVERTITLE "Collected Essays" + .COVERTITLE "1985-2015" + .TITLE "Neo-liberalism: Who Did They Think They Were Fooling?" + .DOC_COVER DOC_COVERTITLE + .COVER COVERTITLE + +could be used to accomplish the same thing. +

+ +
How the CHAPTER argument and friends work
+ +

+• CHAPTER +
+The CHAPTER argument will print the +CHAPTER_STRING +concatenated with the chapter number you gave to +CHAPTER. +For example, assuming a vanilla setup for your chapter: +
+ + .CHAPTER 1 + .CHAPTER_TITLE "The Bonny Blue Yonder" + .COVER CHAPTER \" (or .DOC_COVER CHAPTER) + +will print (and only print) +
+ + Chapter 1 + +

+ +

+• CHAPTER_TITLE +
+The CHAPTER_TITLE argument will print the chapter title +you gave to +CHAPTER_TITLE. +For example, assuming a vanilla setup for your chapter: +
+ + .CHAPTER 1 + .CHAPTER_TITLE "The Bonny Blue Yonder" + .COVER CHAPTER_TITLE \"(or .DOC_COVER CHAPTER_TITLE) + +will print (and only print) +
+ + The Bonny Blue Yonder + +

+ +

+• CHAPTER+TITLE +
+The CHAPTER+TITLE argument will print both the +concatenated chapter string+number and the chapter title. For +example, assuming a vanilla setup for your chapter: +
+ + .CHAPTER 1 + .CHAPTER_TITLE "The Bonny Blue Yonder" + .COVER CHAPTER+TITLE \"(or .DOC_COVER CHAPTER+TITLE) + +will print +
+ + Chapter 1 + The Bonny Blue Yonder + +

+ +
+

DOC_COVERTEXT and COVERTEXT

+
+ +
+Macro: DOC_COVERTEXT [START <starting position>] <toggle> +
+
+Macro: COVERTEXT [START <starting position>] <toggle> +
+ +

+• Must come after +PRINTSTYLE +

+ +

+DOC_COVERTEXT and COVERTEXT allow you to add +text to doc covers and covers in addition to, or instead of, what is +generated by mom from the arguments you give to +DOC_COVER +and +COVER. +

+ +

+Invoke .DOC_COVERTEXT or .COVERTEXT on a line +by itself, follow it with the text and formatting you desire, and +terminate the text block with .DOC_COVERTEXT OFF or +COVERTEXT OFF (or QUIT, END, DONE, etc.). +

+ +

+By default, cover text is set over the full line length of the +document, using the style parameters of +running text. +Therefore, as noted, these macros must come after PRINTSTYLE +and any global style changes (margins, family, size, leading, +etc.). Formatting within a cover text block must be done +“manually” with mom’s typesetting macros; +PP +is the only allowed document element tag. +

+ +

Placement

+ +

+If you do not instruct mom to put anything on doc cover or cover +pages except DOC_COVERTEXT or COVERTEXT, the +cover text will begin at the document’s top margin. +Equally, if only COPYRIGHT and/or MISC are +to go on the pages, cover text begins at the top margin. In all +other cases, cover text begins below the last element on the page +(excluding COPYRIGHT or MISC), separated by a blank line. +

+ +

+If you wish to change the starting position of the text, you must +use +SP +or +ALD +to move it further down the page. Alternatively, you may use the +optional START argument to give a precise location for the text to +begin. +

+ +

+DOC_COVERTEXT and COVERTEXT are particularly +useful for putting abstracts on cover pages, as technical reports +often require. +

+ +

+Here’s a simple recipe for setting an abstract: +
+ + .COVERTEXT + .FT BI + .PT_SIZE 14 + .LS 14 + .CENTER + Abstract + .SP .5v + .FT R + .PT_SIZE 12 + .IB 6P + .JUSTIFY + Text of Abstract... + .COVERTEXT OFF + +Assuming you have told mom to put the title and author on the +cover page, the abstract will appear beneath the author with a +14-point bold-italic title, centered, with the text of the abstract +medium-roman and justified, indented 6 picas from both margins. +

+ +
+

DOC_COVER_IMAGE and COVER_IMAGE

+
+ +
+Macro: DOC_COVER_IMAGE <image> <width> <height> [ -L | -C | -R | -I <indent> <Y-pos> [ <X-pos> ] ] +
+ +
+Macro: COVER_IMAGE <image> <width> <height> [ -L | -C | -R | -I <indent> <Y-pos> [ <X-pos> ] ] +
+ +

+There are times you need a full page image on a cover, for example +the jacket of a book. Equally, there are times when you need a small +image on the cover, perhaps a company logo. +

+ +

+DOC_COVER_IMAGE and COVER_IMAGE take the same arguments +as PDF_IMAGE, and in the same order. Consult +PDF_IMAGE +for a description. +

+ +

+Two additional arguments allow you to place images using x-y +coordinates. Please note that if you use x-y coordinates for +positioning, Y-pos comes before X-pos in the order of +arguments. +

+ +

+Like PDF_IMAGE, the image file must be in PDF format. Mom +apologizes, but PostScript images are not supported for inclusion on +covers. See +Image conversion and file processing +for instructions on converting various image types to PDF, and +here +for instructions on obtaining image dimensions. +

+ +

Positioning of doc cover and cover images

+ +

+With no arguments other than <file name>, +<width>, and <height>, +DOC_COVER_IMAGE and COVER_IMAGE place images flush with the top +left corner of the printer sheet. This allows placing full-page +background images on covers. For example, assuming a US-letter page +size, +
+ + .DOC_COVER_IMAGE image.pdf 612p 792p + .DOC_COVER TITLE AUTHOR DOC_COVER_IMAGE + +will fill the doc cover page with “image.pdf” and set +the title and author in their usual locations. +

+ +

+For smaller images, the horizontal position is established +with one of the -L, -C, -R, or +-I <indent> arguments, just like +PDF_IMAGE. +You may instead use the X-pos argument, provided that it +is preceded by a Y-pos argument. The values given to +-I, Y-pos and X-pos must have a +unit of measure +appended to them. +

+ +

+Vertical positioning of smaller images requires the Y-pos +argument (which is why it precedes X-pos in the order of +arguments) otherwise the image will be flush with the top edge of +the printer sheet +

+ +

+The positioning of images does not effect the placement of type on +doc cover and cover pages. +

+ +
+

+Tip: +The combination of +COVERTEXT +and COVER_IMAGE make it possible to design covers entirely to your +own specifications. +

+
+ +
+

Enabling/disabling automatic generation of cover pages

+
+ +
+Macro: COVERS <toggle> +
+ +
+Macro: DOC_COVERS <toggle> +
+ +

+By default, if you give mom a +COVER +or +DOC_COVER +directive, she will print the cover or doc cover. In a document +that contains sections, articles or chapters formerly treated as +”one-off’s” but now being +collated, +such behaviour may not be desirable. +

+ +

+Mom lets you selectively enable or disable the generation of covers +and/or doc covers with the toggle macros, COVERS and DOC_COVERS. +Because they’re toggle macros, simply invoking them by +themselves enables automatic cover or doc cover generation, while +invoking them with any argument at all (OFF, QUIT, X, +etc) disables cover or doc cover generation.

+ +
+

+Note: +You must place these macros prior to any instance of +START. +Since they’re ”on” by default, there’s no +need to use them if you want covers. However, if you don’t, +especially in the kind of scenario described above, the best place +to put them (most likely with an OFF, NO, X, etc. argument), +is immediately after the first invocation of START. By doing so, +you ensure they meet the requirement of preceding all subsequent +instances of START. +

+
+ +

+ +

Control macros for doc covers and covers

+ +

+The default typographic appearance of the items on a doc cover or +cover is identical to that of the items in a +docheader. +(See +Docheader description +for a description of the defaults.) +

+ +

+COPYRIGHT +and +MISC, +which do not appear in docheaders, have the following default +characteristics: +

+
    +
  • the COPYRIGHT line is set flush with the document’s right + and bottom margins, 2 + point sizes + smaller than the size of + running text +
  • +
  • MISC lines are set flush with the document’s left and bottom + margins, in the same family, font and point size as the + copyright line. +
  • +
+ +

+The defaults for the entirety of doc covers and covers, and all the +elements thereon, can be changed with control macros whose defaults +and arguments are identical to the corresponding +Control macros for docheaders +(q.v.) The only difference is the name by which you invoke them. Wherever +DOCHEADER is used for overall changes, replace it +with DOC_COVER or COVER. For part-by-part +changes, prepend DOC_COVER_ or COVER_ to the +part/parameter. +

+ +

+Thus, to change the overall family, color, leading, quad, and +starting position of a doc cover, you’d do +
+ + .DOC_COVER_FAMILY H + .DOC_COVER_COLOR blue + .DOC_COVER_LEAD +2 + .DOC_COVER_QUAD L + .DOC_COVER_ADVANCE 3i \" or .DOC_COVER_START_POS 3i + +To change the style parameters for selected parts of a cover, you +might do something like this: +
+ + .COVER_TITLE_FONT B + .COVER_TITLE_SIZE +4 + .COVER_SUBTITLE_FONT I + .COVER_AUTHOR_FONT R + .COVER_AUTHOR_SPACE_BEFORE 6p + .COVER_DOCTYPE_COLOR red + .COVER_MISC_SIZE -1 + .COVER_MISC_LEAD 12 + .COVER_COPYRIGHT_SIZE -2 + .COVER_COPYRIGHT_QUAD L + .COVER_MISC_QUAD R + +Note in the above example that _COPYRIGHT_QUAD and _MISC_QUAD set +both the horizontal position on the page and the quad direction, +either L (or LEFT) or R (or RIGHT), and have no corresponding +docheader control macro. +

+ +
+

+Tip: +As with the docheader control macros, DOC_COVER_ and +COVER_ part/parameter style changes may be +grouped, +for example +
+ + .DOC_COVER_TITLE_STYLE \ + FAMILY A \ + FONT B \ + SIZE +4 \ + CAPS + +

+
+ + + + + + + + +
Back to Table of ContentsTopNext: Tables of contents
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/definitions.html b/contrib/mom/momdoc/definitions.html new file mode 100644 index 0000000..b85a089 --- /dev/null +++ b/contrib/mom/momdoc/definitions.html @@ -0,0 +1,995 @@ + + + + + + + + + Mom -- Definitions and Terms + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: Using mom
+ +

Definitions of terms used in this manual

+ +

+I use a number of typesetting-specific and groff-specific terms +throughout this documentation, as well as a few terms that apply +to mom herself. To make life easier, I’ll explain +them here. Refer back to this section should you encounter a word +or concept you’re not familiar with. +

+ +

+ + + + + + + +

Typesetting terms

+
+
Ascender
+
+ The portion of a letter that extends above the bowl. For + example, the letters a, c, and e have no ascenders. The letters + b, d, and h do. +
+ +
Baseline
+
+ The imaginary line on which the bottoms of capital letters and + the bowls of lower case letters rest. +
+ +
Ballot box
+
+ An unfilled square, usually + cap-height + in size, typically placed beside items in a checklist. +
+ +
Bullet
+
+ A small, filled circle typically found beside items or points in + a list. +
+ +
Cap-height
+
+ The height of the tallest capital letter in a given + font + at the current + point size. +
+ +
Descender
+
+ The portion of a letter that extends beneath the + baseline + (j, q, y are letters with descenders). +
+ +
Discretionary hyphen
+
+ A symbol inserted between two syllables of a word that indicates + to a typesetting program the valid hyphenation points in the + word. Normally, if hyphenation is turned on, groff knows where + to hyphenate words. However, hyphenation being what it is + (in English, at any rate), groff doesn’t always get it right. + Discretionary hyphens make sure it does. In the event that the + word doesn’t need to be hyphenated at all, groff leaves them + alone. In groff, the discretionary hyphen is entered with + \% (i.e. a backslash followed by the percent sign). +
+ +
Drop cap
+
+ A large, usually upper-case letter that introduces the first + paragraph of a document or section thereof. The top of the + drop cap usually lines up with the top of the first line of the + paragraph, and typically “drops” several lines lower. + Text adjacent to the drop cap is indented to the right of the + letter until the bottom of the drop cap is reached, at which + point text reverts to the left margin. +
+ +
Em/en
+
+ An em is a relative measurement equal to the width of the + letter M at a given + point size + in a given + font. + Since most Ms are designed square, an em is usually (but + sometimes erroneously) considered to be the same size as the + current point size (i.e., if the point size of the type is 12, + one em equals 12 points). An en is equal to the width of a + letter N (historically 2/3 of an em, although groff treats an en + as 1/2 of an em). Typically, ems and ens are used to measure + indents, or to define the length of dashes (long hyphens). +
+ +
Family
+
+ The collective name by which a collection of + fonts + are known, e.g. Helvetica, Times Roman, Garamond. +
+ +
Figure space/Digit space
+
+ A + fixed width space + that has the width of one digit. Used for aligning numerals in, + say, columns or numbered lists. In groff, the figure space is + entered with \0 (i.e. a backslash followed by a zero) +
+ +
Fixed-width font
+
+ A family or font in which every character occupies exactly the + same amount of horizontal space on the line. Courier is the + best-known, if not the most elegant, fixed-width font. +
+ +
Fixed width space
+
+ Equal to + word space, + but does not expand or contract when text is + justified. + In groff, fixed width space is entered with + \<space> (i.e. a backslash followed by a space) +
+ +
Font
+
+ The specific + weight + and + shape + of type within a + family, + e.g. light, medium, bold (which are weights), and roman, italic, + condensed (which are shapes). By default, groff knows of four + fonts within its default set of families: R (medium roman), I + (medium italic), B (bold roman) and BI (bold italic). + Mom considerably extends this very basic list. +
+ +
Force justify
+
+ Sometimes, in + justified + text, a line needs to be broken short of the right margin. + Force justifying means telling a typesetting program (like + groff) that you want the line broken early AND that you want the + line’s word spacing stretched to force the line flush with the + right margin. +
+ +
Gutter
+
+ The vertical whitespace separating columns of type. +
+ +
Justify/justification
+
+ Lines of type are justified when they’re flush at both the left + and right margins. Justification is the act of making both + margins flush. Some people use the terms "left justified" and + "right justified" to mean type where only the left (or right) + margins align. I don’t. See + quad. +
+ +
Kerning
+
+ Moving pairs of letters closer together to remove excess + whitespace between them. In the days before phototypesetting, + type was set from small, rectangular blocks of wood or metal, + each block having exactly one letter. Because the edge of + each block determined the edge of each letter, certain letter + combinations (TA, for example) didn’t fit together well and had + to be mortised by hand to bring them visually closer. Modern + typesetting systems usually take care of kerning automatically, + but they’re far from perfect. Professional typesetters still + devote a lot of time to fitting letters and punctuation together + properly. +
+ +
Kern Units
+
+ A relative distance, which, by default, is equal to 1/36 of the + current + point size. + Used between individual letters for + kerning. + Different typesetting systems use different values (1/54 is + popular), and sometimes call kern units by a different name. + It is possible to change the default size of the kern unit with the + KERN_UNIT + macro. +
+ +
Lead/leading
+
+ The distance from the + baseline + of one line of type to the line of type immediately beneath + it. Pronounced "ledding." Also called line spacing. Usually + measured in + points. + +

+ In case you’re interested... In previous centuries, + lines of type were separated by thin strips of—you guessed + it—lead. Lines of type that had no lead between them were said + to be “set solid.” Once you began separating them with + strips of lead, they were said to be “leaded”, and the + spacing was expressed in terms of the number of + points + of lead. For this reason, “leading” and “line + spacing” aren’t, historically speaking, synonymous. + If type was set 10 on 12, for example, the leading was 2 + points, not 12. Nowadays, however, the two terms are used + interchangeably to mean the distance from baseline to baseline. +

+ +
+ +
Leaders
+
+ Single characters used to fill lines, usually to their end. So + called because they “lead” the eye from one element + of the page to another. For example, in the following (brief) + Table of Contents, the periods (dots) are leaders. + + + Foreword............... 2 + Chapter 1.............. 5 + Chapter 2.............. 38 + Chapter 3.............. 60 + +
+ +
Ligature
+
+ Ligatures are letters joined together to form a single + character. The commonest are fi, fl, ff, ffi and ffl. Others + are ae and oe. Occasionally, one sees an st ligature, but this + is archaic and quite rare. +
+ +
Picas/Points
+
+ There are twelve points in a pica, and six picas in an inch + (hence 72 points to the inch). In the same way that gem-dealers + have always used their own system of measurement for weight + (carats), typographers have always used their own system of + measurement for type. +
+ +
Point Size
+
+ The nominal size of type, measured in + points + from the bottom of the longest + descender + to the top of the highest + ascender. + In reality, type is always fractionally smaller than its point + size. +
+ +
Quad
+
+ When only one margin of type is flush, lines of type are quadded + in the direction of the flush margin. Therefore, quad left + means the left margin is flush, the right isn’t. Quad right + means the right margin is flush, the left isn’t. Quad centre + means neither the left nor the right margin is flush; rather, + lines of type are quadded on both sides so that type appears + centred on the page. +
+ +
Rag
+
+ Describes a margin that isn’t flush. Rag right means the right + margin isn’t flush. Rag left means the left margin isn’t flush. + The expression "flush left/rag right" is sometimes used to + describe type that is + quadded + left. +
+ +
Shape
+
+ The degree of slant and/or the width of characters. + (Technically speaking, this is not a proper typesetting term; + however, it may help clarify some concepts presented in these + documents.) + +

+ Some typical shapes are: +

+ +
    +
  • Roman, which has no slant, and has letterforms of + average width
  • +
  • Italic, which is slanted, and has letterforms + of average width
  • +
  • Condensed, which has no slant, but has + letterforms narrower than the average represented by Roman
  • +
  • Condensed Italic, which is slanted, with letterforms narrower + than average
  • +
+ +

+ The term + font, + as it is used in these documents, refers to a combination of + weight + and shape. +

+ +
+ +
Solid/set solid
+
+ When no + lead + is added between lines of type (i.e., the + point size + and linespacing are the same), the lines are said to be “set + solid.” +
+ +
Track kerning/Line kerning
+
+ Sometimes, it’s advantageous to increase or decrease the amount + of space between every letter in a line by an equal (usually + small) amount, in order to fit more (or fewer) characters on the + line. The correct term is letter spacing, but track kerning and + line kerning (and sometimes, just "kerning") have come to mean + the same thing. +
+ +
Unbreakable space
+
+ Equal to + word space, + however words separated by an unbreakable space will always be + kept together on the same line. Expands and contracts like word + space. Useful for proper names, which one should, whenever + possible, avoid splitting onto two lines. In groff, unbreakable + space is entered with \~ (i.e. a backslash followed by a + tilde) +
+ +
Weight
+
+ The thickness of the strokes of letterforms. Medium and Book + have average thicknesses and are the weights used for most + of the text in books, magazines, newspapers, etc. Light has + strokes slightly thinner than Medium or Book, but is still + acceptable for most text. Semibold, Bold, Heavy and Black all + have strokes of increasing thickness, making them suitable for + headings and the like. +
+ +
Word space
+
+ The amount of whitespace between words. When text is + justified, + word space expands or contracts to make the margins flush. +
+ +
x-height
+
+ The height of a lower case letter x in a given font at a given + point size. Generally used to mean the average height of the + bowl of lower case letters. +
+
+ +

Groff terms

+ +
+
Alias
+
+ A + macro + invoked by a name different from its “official” + name. For example, the official name of the macro to change + family + is FAMILY. Its alias is FAM. + Aliases may be created for any macro (via the + ALIAS + macro) provided the alias uses a name not already taken by the + mom macros or one of the groff + primitives. + For a complete list of words or names you must not use, see the + list of reserved words. +
+ +
Arguments
+
+ Parameters or information needed by a + macro + to do its job. For example, in the macro + + + .PT_SIZE 12 + + + 12 is the argument. In the macro + + + .QUAD LEFT + + + LEFT is the argument. Arguments are separated from + macros by spaces. Some macros require several arguments; each + is separated by a space. +
+ +
Comment Lines
+
+ Input lines + introduced with the comment character \# (i.e. a + backslash followed by the pound sign). When processing output, + groff silently ignores everything on a line that begins with the + comment character. +
+ +
Control Lines
+
+ Instructions to groff that appear on a line by themselves, which + means that “control lines” are either + macros + or groff + primitives. + Control lines begin with a period or, occasionally, an apostrophe. +
+ +
Filled lines/fill mode
+
+ Automatic + justification + or + quadding. + In fill mode, the ends of lines as they appear in your text + editor are ignored. Instead, words from adjoining + input lines + are added one at a time to the output line until no more words + fit. Then, depending whether text is to be + justified + or + quadded + (left, right, or centre), and depending on whether automatic + hyphenation is turned on, groff attempts to hyphenate the last + word, or, barring that, spreads and breaks the line (when + justification is turned on) or breaks and quads the line (when + quadding is turned on). + +

+ Nofill mode (non-filled text) means that groff respects the ends + of lines exactly as they appear in your text editor. +

+ +
+ +
Inline escapes
+
+ Instructions issued to groff that appear as part of an + input line + (as opposed to + macros, + which must appear on a line by themselves). Inline escapes are + always introduced by the backslash character. For example, + + + A line of text with the word T\*[BU 2]oronto in it + + + contains the inline escape \*[BU 2] (which means + “move the letter ‘o’ 2 + kern units + closer to the letter ‘T’”). + +

+ Mom’s inline escapes always take the form + \*[<ESCAPE>], where ESCAPE is + composed of capital letters, sometimes followed immediately by a + digit, sometimes followed by a space and a + numeric argument. + Groff’s escapes begin with the backslash + character but typically have no star and are in lower case. For + example, the mom escapes to move forward 6 + points on a line are either + + + \*[FP6]  or  \*[FWD 6p] + + + while the groff escape for the same thing is + + + \h’6p’ + +

+ +
+ +
Input line
+
+ A line of text as it appears in your text editor. +
+ +
Macros
+
+ Instructions embedded in a document that determine how groff + processes the text for output. mom’s macros + always begin with a period, on a line by themselves, and must + be typed in capital letters. Typically, macros contain complex + commands issued to groff—behind the scenes—via + groff + primitives. +
+ +
Machine units
+
+ A machine unit is 1/1000 of a + point + when the groff device is ps. (“ps” means + “PostScript”—the default device for + which groff prepares output, and the device for which + mom was originally designed.) +
+ +
Numeric argument
+
+ An + argument + that has the form of a digit. Numeric arguments can be built + out of arithmetic expressions using +, -, *, and / for plus, + minus, times, and divided-by respectively. If a numeric + argument requires a + unit of measure, + a unit of measure must be appended to every digit in + the argument. For example: + + + .ALD 1i-1v + + +
+

+ IMPORTANT: groff does not + respect the order of operations, but rather evaluates + arithmetic expressions from left to right. Parentheses must + be used to circumvent this peculiarity. Not to worry, though. + The likelihood of more than just the occasional plus or minus + sign when using mom’s macros is slim. +

+
+
+ +
Output line
+
+ A line of text as it appears in output copy. +
+ +
Pre-processor
+
+ Pre-processors are used by groff to generate tables + (tbl), diagrams (pic), graphs + (grap), and equations (eqn). + These pre-processors are fully supported by mom. In addition, + the “refer” pre-processor is used to generate + bibliographies and lists of cited works. The PDF_IMAGE macro, + which allows insertion of graphics into a document, is not + strictly a pre-processor but behaves similarly to tbl, pic, and + eqn. +
+ +
Primitives
+
+ The lowercase instructions, introduced with a period, that groff + uses as its native command language, and out of which macros + are built. The majority of groff’s primitive requests are two + letters long. +
+ +
String Argument
+
+ Technically, any + argument + that is not numeric. In this documentation, string argument + means an argument that requires the user to input text. For + example, in the + macro + + + .TITLE "My Pulitzer Novel" + + + "My Pulitzer Novel" is a string argument. + +

+ Because string arguments must be enclosed by double-quotes, you + can’t use double-quotes as part of the string argument. If you + need double-quotes to be part of a string argument, use the + inline escapes + \(lq and \(rq (leftquote and + rightquote respectively) in place of the double-quote character + ("). +

+ +
+ +
Unit of measure
+
+ The single letter after a + numeric argument + that tells mom what measurement scale the + argument should use. Common valid units are: + + + i (inches) + p (points) + P (Picas) + c (centimetres) + m (ems) + n (ens) + u (machine units) + v (the current leading [line space]) + + +

+ Units of measure must come immediately after the numeric + argument (i.e. with no space between the argument and the unit + of measure), like this: + + + .ALD 2v + .LL 39P + .IL 1i + + + The above example advances 2 line spaces and sets the line + length to 39 picas with a left indent of 1 inch. +

+ +
+

+ IMPORTANT: + Most mom macros that set the size or measure of something must + be given a unit of measure since most of the macros do not have + default units of measure. There are a couple of exceptions, + the most notable of which are PT_SIZE and + LS. Both use + points + as the default unit of measure, which means you don’t have to + append “p” to their argument. +

+
+ +

+ You can enter decimal values for any unit of measure. Different + units may be combined by adding them together (e.g. 1.5i+2m, + which gives a measure of 1-1/2 inches plus 2 ems). +

+ +
+

+ Note: + a pica is composed of 12 points, therefore 12.5 picas is 12 + picas and 6 points, not 12 picas and 5 points. If you want 12 + picas and 5 points, you have to enter the measure as 12P+5p. +

+
+ +
+ +
Zero-width character
+
+ The + inline escape + that allows you to print a literal period, apostrophe and, if + output lines + are + filled, + a space that falls at the beginning of an + input line. + It looks like this: + + + \& (i.e. a backslash followed by an ampersand) + + + Normally, groff interprets a period (or an apostrophe) at the + beginning of an input line as meaning that what follows is a + control line. + In fill modes, groff treats a space at the beginning of an input + line as meaning “start a new line and put a space at the + beginning of it.” If you want groff to interpret periods + and apostrophes at the beginning of input lines literally (i.e. + to print them), or spaces at the beginning of input lines as just + garden variety word spaces, you must start the line with the + zero-width character. +
+
+ +

Mom terms

+
+
Baseline grid
+
+ Virtual guide lines spaced according to the + leading + established for running text. Adherence to the grid ensures that + text fills the page completely to the bottom margin. Uncorrected + deviations from the grid result in bottom margins that fall short. +
+ +
Control macro
+
+ Macros used in + document processing + to control/alter the appearance of document elements (e.g. + headings, quotes, footnotes, + headers, + etc.). +
+ +
Document header/docheader
+
+ Document information (title, subtitle, author, etc) output at + the top of page one. +
+ +
Epigraph
+
+ A short, usually cited passage that appears at the beginning of + a chapter, story, or other document. +
+ +
Float
+
+ A float is material intended to be kept together as a block. + Floated material that fits on a page in position is output on that + page. Floats that do not fit in position are deferred to the top + of the next page. +
+ + +
+ Document information (frequently author and title) output in + the bottom margin of pages after page one. Not to be + confused with footnotes, which are considered part of + running text. +
+ + +
+ The title used to identify a section of a document. Headings + are hierarchic, corresponding to the notion of head, subhead, + subsubhead, etc. +
+ + +
+ Document information (frequently author and title) output in the + top margin of pages after page one. + +
+

+ Note: In terms of content and style, + headers and + footers + are the same; they differ only in their placement on the page. + In most places in this documentation, references to the content + or style of headers applies equally to footers. +

+
+ +
+ +
Linebreak/author linebreak
+
+ A gap in the vertical flow of + running text, + frequently set off by typographic symbols such as asterisks or + daggers. Used to indicate a shift in the content of a document + (e.g. a scene change in a short story). Also commonly called a + scene break or a section break. +
+ +
Paragraph head
+
+ A heading joined to the body of a paragraph. +
+ + +
+ A portion of text that, when clicked on in a PDF viewer, + navigates to a bookmarked location in a document, generally but not + exclusively a heading. PDF links are usually coloured to make + them stand out from the surrounding text. +
+ +
PDF outline
+
+ The hierarchically-arranged navigation outline provided by most PDF + viewers (e.g. Okular, Evince), typically in a panel to the left of + the document window, and usually labelled “Contents”. +
+ +
Quote
+
+ A quote, to mom, is a line-for-line setting + of quoted material (e.g. poetry, song lyrics, or a snippet of + programming code). You don’t have to use + BR + with quotes. +
+ +
Running text
+
+ In a document formatted with mom, running + text means text that forms the body of the document, including + elements such as headings. + Docheaders, + headers, + footers + and page numbers are not part of running text. +
+ +
Toggle
+
+ A macro or tag that, when invoked without an argument, begins + something or turns a feature on, and, when invoked with ANY + argument, ends something or turns a feature off. See + Example 3 + of the section + How to read macro arguments. +
+
+ +

+ + + + + + + + +
Back to Table of ContentsTopNext: Using mom
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/docelement.html b/contrib/mom/momdoc/docelement.html new file mode 100644 index 0000000..43f79d4 --- /dev/null +++ b/contrib/mom/momdoc/docelement.html @@ -0,0 +1,6639 @@ + + + + + + + + + Mom -- Document processing, element tags + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: Graphics, floats, preprocessor support
+ +

The document element tags

+ + + +

+ +

Document element tags table of contents

+ + + +

+ +

Introduction to the document element tags

+ +

+Once you’ve completed the setup for a document (see +Setting up a mom document), +formatting it is a snap. Simply invoke the appropriate tag for +each document element as you need it. The tags are macros that +tell mom: “This is a paragraph; this is a heading; this is a +footnote,” and so on. +

+ +

+Generally, for each tag, there are +control macros +for the tag’s family, font and point size. Where appropriate, +there are macros to control leading, indents, quad and special +features as well. +Mom has tasteful defaults for all the tags, hence you only use the +control macros when you want to change the way she does things. +This is usually done prior to +START, +but can, in fact, be done at any time in the course of a document. +Any change to a tag’s style affects all subsequent invocations +of the tag. +

+ +

Control macros – changing the tag defaults

+ +

+The control macros for document processing tags let you design the +look of all the parts of your documents—should you wish. At +a bare minimum, all tags have macros to change mom’s defaults +for family, font, point size and colour. Where appropriate, there +are macros to control leading, indents and quad as well. +

+ +

+In addition, many tags have special macros to control features that +are pertinent to those tags alone. Have a look at the section +dealing with any particular tag to find out what macros control the +tag, and what mom’s defaults for the tag are. +

+ +

+The control macros may be used at any time during the course of a +document (i.e. before or after +START). +The changes you make alter all subsequent invocations of the +affected tag until you make another change, either by passing new +arguments to the tag’s control macro, or toggling a particular +feature of the tag on or off. +

+ +

+And don’t forget: the +typesetting macros +can be used at any time, including inside +toggle +tags (affecting only that particular invocation of the tag). +Equally, +inline escapes +can be used in tags that take +string arguments. +

+ +
+

+Tip: +Get familiar with mom at her default settings before exploring the +control macros. Put her through her paces. See how she behaves. +Get to know what she feels like and how she looks, both in your +text editor and on the printed page. Then, if you don’t like +something, use this documentation to find the precise macro you need +to change it. There are tons of control macros. Reading up on them +and trying to remember them all might lead you to think that mom is +complex and unwieldy, which is not only untrue, but would offend her +mightily. +

+
+ +
+

+Important: +The family, font, point size, colour and leading control macros have +no effect in +PRINTSTYLE TYPEWRITE, +except where noted throughout this documentation. +

+ +

+Please also note that the defaults listed with the control macros +apply only to +PRINTSTYLE TYPESET +unless a default for TYPEWRITE is also given. +

+
+ +

Arguments to the control macros

+ +

Family and font

+ +

+The arguments to the control macros that end in _FAMILY or _FONT are +the same as for +FAMILY +and +FT. +

+ +

Point size

+ +

+Control macros that end in _SIZE always take +the form +<n> or -<n> where +<n> is the number of +points +larger (+) or smaller (-) than the point size of paragraphs +you want the document element to be. For example, to set +blockquotes 2 points smaller than the type in paragraphs, do +
+ + .BLOCKQUOTE_SIZE -2 + +There’s no need for a +unit of measure +with the _SIZE control macros; points is assumed. +

+ +

Colour

+ +

+Control macros that end in _COLOR take as their argument a colour +name pre-defined (or “initialized”) with +NEWCOLOR +or +XCOLOR. +For example, if you want your +author linebreaks +to be red, once you’ve defined or initialized the colour, red, +
+ + .LINEBREAK_COLOR red + +will turn them red. +

+ +

Lead / linespacing

+ +

+Control macros that end in _AUTOLEAD take the same argument as +AUTOLEAD, +viz. a digit that represents the number of points to add to +the tag’s point size to arrive at its +leading. +For example, to set footnotes +solid, do +
+ + .FOOTNOTE_AUTOLEAD 0 + +To set footnotes with a 1-point lead (i.e. with the line spacing +one point greater than the footnote’s point size), do +
+ + .FOOTNOTE_AUTOLEAD 1 + +

+ +
+

+Note: +_AUTOLEAD control macros do not have a FACTOR argument. +

+
+ + +

Indents

+ +

+Except for +PARA_INDENT, +the argument to control macros that end in _INDENT can take +either a single numeral (whole numbers only, no decimal fractions) +without a +unit of measure +appended to it, or a digit (including decimal fractions) with +a unit of measure appended. +

+ +

+A digit without a unit of measure appended represents by +how much you want your paragraph first-line indents (set with +PARA_INDENT) multiplied to achieve the correct indent for a +particular tag. For example, +
+ + .PARA_INDENT 2m + .BLOCKQUOTE_INDENT 2 + +means that blockquotes will be indented from the left and right +margins by twice the size of the paragraph indent, or 4 +ems. +

+ +

+A digit with a unit of measure appended defines an absolute +indent, relative to nothing. In the following, blockquotes will be +indented by 3 +picas +and 6 +points, +regardless of the paragraph indent. +
+ + .PARA_INDENT 2m + .BLOCKQUOTE_INDENT 3P+6p + +

+ +

Quad / justification style

+ +

+Control macros that end in _QUAD take the same arguments as +QUAD. +

+ +

Underscore style, rule weight

+ +

+If mom gives the option to underscore a document element, the weight +of the underline and its distance from the +baseline +are controlled by macros that end in _UNDERSCORE or _UNDERLINE, the +two being synonymous. These macros take the following arguments: +
+ + DOUBLE - double underscore + <weight> - the underscore weight (in points, no unit of measure required + <distance> - distance from baseline (unit of measure required) + <rule gap> - distance between double underscore rules (unit of measure required) + +DOUBLE by itself will double-underscore the element. The +remaining arguments must be entered in the order given. You may not +skip over any of them, which means that if you only wish to change +<rule gap>, you must still enter a +<weight> and <distance> argument. +

+ +

+Page elements that are separated from +running text +by a rule (i.e. page headers, page footers, and footnotes) are +controlled by macros that end in _RULE_WEIGHT. +

+ +

+The weight argument to _UNDERSCORE macros is the same as the +argument to +RULE_WEIGHT, +as is the argument to _RULE_WEIGHT macros. +

+ +

Grouping control macros

+ +

+As of version 2.1, it is possible to group control macros for a +particular tag into a single <element>_STYLE macro. +For example, rather than setting the family, size, and indent of +BLOCKQUOTES +with +
+ + .BLOCKQUOTE_FAMILY H + .BLOCKQUOTE_SIZE -2 + .BLOCKQUOTE_INDENT 4P + +you can enter the same style parameter changes with +
+ + .BLOCKQUOTE_STYLE \ + FAMILY H \ + SIZE -2 \ + INDENT 4P + +<element>_STYLE macros use +“keyword/value” pairs (FAMILY is a keyword, +H is a value), and may be entered entirely on one line, +or, as the example shows, broken into several readable lines using +the backslash. The macro itself and all but the last keyword/value +pair require the backslash when this style is used. +

+ +

+Not all the control macros for a particular tag may be available +with an <element>_STYLE macro. Generally speaking, +though, if a tag has control macros for +

+ + + + + + + + + + + + + + + + + + +
FAMILYLEADINDENTSMALLCAPS
FONTAUTOLEADCOLORUNDERSCORE or UNDERLINE
SIZEQUADCAPS
+

+those parameters may be used within an +<element>_STYLE macro. +

+ +
+

+Note: +If you need to reverse the sense of CAPS, +SMALLCAPS or UNDERSCORE/UNDERLINE, which +do not take a value after the keyword, use NO_CAPS, +NO_SMALLCAPS, and NO_UNDERSCORE/NO_UNDERLINE. +

+
+ +

+ + + +

Epigraphs

+ + + +

+Epigraphs +colour, flavour, or comment on the document they precede. +Typically, they are centred at the top of a document’s first page +(underneath the title) and set in a smaller point size than that of +paragraph text. +

+ +

+By default, mom sets epigraphs centred and +unfilled; +this lets you input them on a line for line basis. This behaviour +can be changed to accommodate +filled +epigraph “blocks.” +

+ + + +
+

EPIGRAPH

+
+ +
+Macro: EPIGRAPH <toggle> | [ BLOCK ] +
+ +

+EPIGRAPH is a toggle, used like this: +
+ + .EPIGRAPH + <text of epigraph> + .EPIGRAPH OFF + +OFF, above, could be anything—say, Q or +X—since any argument other than BLOCK +turns it off. +

+ +

+If given the argument, BLOCK, EPIGRAPH sets epigraphs +filled, +justified or quadded in the same direction as paragraphs, indented +equally from both the left and right margins. +

+ +

+If a block-style epigraph runs to more than one paragraph (unlikely, +but conceivable), you must introduce every paragraph—including +the first—with the +PP +tag. +

+ +
+

+Note: +EPIGRAPH should only be used at the top of a document (i.e. just +after +START) +or after headings. The latter is not especially recommended, but it +does work. In all other places where you want quotes or cited text, +use +QUOTE +or +BLOCKQUOTE. +

+
+ +
+

+Tips on vertical spacing around epigraphs: +If you wish to change the vertical position of an epigraph with +SPACE, +ALD, or +RLD, +do so before invoking .EPIGRAPH, like this: +
+ + .SP -6p + .EPIGRAPH + A notable quote. + .EPIGRAPH OFF + +If you’re setting a document in +columns +and you’d like to add or subtract space after the +epigraph, which is centred over the top of both columns, the place +to do it is inside the epigraph, like this: +
+ + .EPIGRAPH + A notable quote. + .SP 1v + .EPIGRAPH OFF + +If you were to add the .SP 1v outside the epigraph, the +space would be added to the top of the leftmost column only, +resulting in unbalanced columns. +

+
+ +
+

EPIGRAPH control macros and defaults

+ +

+See +Arguments to the control macros. +
+The following EPIGRAPH control macros may also be +grouped +using EPIGRAPH_STYLE. +

+ + +.EPIGRAPH_FAMILY default = prevailing document family; default is Times Roman +.EPIGRAPH_FONT default = roman +.EPIGRAPH_SIZE default = -1.5 (points) +.EPIGRAPH_COLOR default = black +.EPIGRAPH_AUTOLEAD default = 2 points +(The next two apply to “block” style epigraphs only) +.EPIGRAPH_INDENT* (see Note on EPIGRAPH_INDENT, below) + +*Indent here refers to the indent from both the left and right margins + that centres block style epigraphs on the page. + +
+ +
+

Note on EPIGRAPH_INDENT

+ +

+If you pass EPIGRAPH_INDENT an integer with no unit of measure +appended, the integer represents the amount by which to multiply +PARA_INDENT to arrive at an indent for block style epigraphs. If +you append a unit of measure to the argument, the indent will be +precisely the amount specified. +

+ +

+Please also note that if your PARA_INDENT is 0 (i.e. +no indenting of the first line of paragraphs), you must set an +EPIGRAPH_INDENT yourself, with a unit of measure appended to the +argument. Mom has no default for EPIGRAPH_INDENT if paragraph first +lines are not being indented. +

+ +

+The default value for EPIGRAPH_INDENT is 3 (for +PRINTSTYLE TYPESET) +and 2 (for +PRINTSTYLE TYPEWRITE). +

+
+ +

+ + + +

Paragraphs

+ + + +

+The paragraph macro is the one you use most often. Consequently, +it’s one of most powerful, yet simplest to use—just the +letters PP. No arguments, nothing. Just .PP on a line +by itself any time, in any document element, tells mom you want to +start a new paragraph. The spacing and indent appropriate to where +you are in your document are taken care of automatically. +

+ +

+By default, mom does not indent the first paragraph of a document, +nor paragraphs that fall immediately after headings. The first +paragraphs of blockquotes and block-style epigraphs are also not +indented. This behaviour can be changed with the control macro +INDENT_FIRST_PARAS. +

+ +

+Mom does not deposit a blank line between paragraphs. If you want +her to do so, use the control macro +PARA_SPACE. +(I don’t recommend using this macro with +PRINTSTYLE TYPEWRITE.) +

+ +

+Note that mom does not provide widow or orphan control for +paragraphs (i.e., even if only one line of a paragraph fits at the +bottom of a page, she will set it on that page). The reason for +this is that writers of fiction often have single-line paragraphs +(e.g. in dialogue). Groff’s simplistic orphan control will +break these one-liners—if they fall at the bottom of the +page—to a new page, which is not what you want. +

+ + + +
+

PP

+
+ +
+Macro: PP +
+

+.PP (on a line by itself, of course) tells mom to start a +new paragraph. See +above +for more details. In addition to regular text paragraphs, you can +use PP in +epigraphs, +blockquotes, +endnotes +and +footnotes. +

+ +
+

PP control macros and defaults

+ +

+The PP macro being so important, and representing, as it were, the +basis of everything that goes on in a document, its control is +managed in a manner somewhat different from other document element +tags. As a result, the control macros for PP may not be +grouped +within a _STYLE macro. +

+ +
    +
  1. Family control
  2. +
  3. Font control
  4. +
  5. Paragraph colour
  6. +
  7. Leading/linespacing control
  8. +
  9. Justification/quad control
  10. +
  11. First-line indent control
  12. +
  13. Initial paragraphs indent control
  14. +
  15. Inter-paragraph spacing
  16. +
+
+ +

1. Family control

+ +

+The paragraph +family +is set with +FAMILY +prior to +START, +or +DOC_FAMILY +afterwards. Please note that both globally affect the family of +every element in the document. +

+ +

+If you wish to change the family for regular text paragraphs only, +invoke .FAMILY immediately after .PP in every +paragraph whose family you wish to differ from the prevailing +document family. Alternatively, set the family and font for +paragraphs with PP_FONT, giving it a complete family+font name, e.g. +
+ + PP_FONT TI + +which would make the font used in paragraphs Times Roman Italic. +

+ +

+Mom’s default paragraph (and document) family is Times Roman. +

+ +
+

+Note: +Neither FAMILY nor DOC_FAMILY has any effect when the PRINTSTYLE is +TYPEWRITE. +

+
+ +

2. Font control

+ +

+To change the +font +used in regular text paragraphs, use PP_FONT, which takes the same +argument as +FT. +PP_FONT may be used before or after +START. +Only regular text paragraphs are affected; paragraphs in +epigraphs, +blockquotes, +endnotes, +and +footnotes +remain at their default setting (medium roman) unless you change +them with the appropriate control macros. +

+ +

+Mom’s default paragraph font is medium roman. +

+ +
+

+Note: +PP_FONT has no effect when the PRINTSTYLE is TYPEWRITE. +If you wish to set whole typewritten paragraphs in italic, invoke +.FT I immediately after .PP. Depending +on which of +UNDERLINE_ITALIC +or +ITALIC_MEANS_ITALIC +is currently enabled, the paragraph will be set underlined or in +italic. Neither persists past the end of the paragraph. +

+
+ +

3. Paragraph colour

+ +

+Mom has no special control macro for colourising paragraphs. If you +wish a colourised paragraph, you must use the macro +COLOR +or the +inline escape, +\*[<colourname>], +after .PP. The colour must be one pre-defined (or +“initialized”) with +NEWCOLOR +or +XCOLOR. +

+ +

+Please note that unless you change the colour back to it’s +default (usually black) at the end of the paragraph, all subsequent +paragraphs will be set in the new colour, although most other +elements of your document will continue to be set in the default +colour (usually black). +

+ +

+For example, assuming you have defined the colour, blue, +
+ + .PP + .COLOR blue + <first paragraph> + .HEADING 1 "Monty Python" + .HEADING 2 "The Origins of Spam" + .PP + <second paragraph> + +the first paragraph will be blue, the head and subhead will be in +the document’s default colour (usually black), and the second +paragraph will be in blue. +

+ +

4. Leading

+ +

+The paragraph +leading +is set with +LS +prior to +START, +or +DOC_LEAD +afterwards. Please note that either method globally affects the +leading and spacing of every document element (except +headers +and +footers). +

+ +

+If you wish to change the leading of regular text paragraphs only, +invoke .LS immediately after .PP in any +paragraph whose leading you wish to change. +

+ +
+

+Warning: +Changing a paragraph’s leading will almost certainly screw up +mom’s ability to balance the bottom margin of pages. Should +you absolutely require a change to a paragraph’s leading and +need to get mom back on track leading-wise afterwards, use the +SHIM +or +FLEX +macro, depending on which +vertical whitespace management +strategy you are using. +

+
+ +

+Mom’s default paragraph leading (document leading) +is 16 points, adjusted to fill the page. +

+ +

5. Justification / quad

+ +

+The justification/quad-direction of regular text paragraphs (i.e. +justified, +or +filled +and +quadded +left/right/centre) is set with +JUSTIFY +or +QUAD +prior to +START, +and with +DOC_QUAD +afterwards. +

+ +

+Please note that either method of setting the paragraph +justification/quad-direction also affects +epigraphs, +footnotes, +and +endnotes, +but not +blockquotes +(whose default is quad left unless you change it with +BLOCKQUOTE_QUAD). +The justification/quad-direction of epigraphs and footnotes may be +changed with their own control macros. +

+ +

+If you wish to change the justification/quad-direction of individual +paragraphs, invoke +.JUSTIFY +or +.QUAD +on the line immediately after .PP. Only the paragraph +in question gets justified or quadded differently; subsequent +paragraphs remain unaffected. +

+ +

+Mom’s default justification/quad-direction for paragraphs +when the +PRINTSTYLE +is TYPESET is justified; for PRINTSTYLE +TYPEWRITE, the default is quad left. +

+ +

6. First-line indent

+ +

+The first-line indent of paragraphs is controlled by PARA_INDENT, +which takes one argument: the size of the indent. PARA_INDENT may be +used before or after +START. +A +unit of measure +is required; fractional sizes are allowed. Thus, to set the +paragraph indent to 4-1/2 +ems, do +
+ + .PARA_INDENT 4.5m + +In addition to establishing the basic first line-indent of +paragraphs, PARA_INDENT also affects +epigraphs, +quotes +and +blockquotes, +whose overall indenting from the left and (where applicable) +right margins is relative to PARA_INDENT if +the _INDENT control macro for these tags has +no +unit of measure +appended to it. Furthermore, the first-line indent of paragraphs +within these document elements (as well as footnotes) is also +relative to PARA_INDENT (always 1/2 of PARA_INDENT), hence they are +also affected. +

+ +

+Mom’s default PARA_INDENT is 2 ems for +PRINTSTYLE +TYPESET and 3 picas (1/2 inch) for +PRINTSTYLE +TYPEWRITE. +

+ +

7. Indenting initial paragraphs

+ +

+By default, mom does not indent the first paragraph of a document, +nor the first paragraph after a heading or +linebreak, +nor the first paragraphs of +epigraphs, +blockquotes, +endnotes +or +footnotes +that run to more than one paragraph. +

+ +

+If you wish to have first paragraphs indented, invoke the macro +INDENT_FIRST_PARAS without an argument, either before or after +START. +INDENT_FIRST_PARAS is a toggle macro, therefore passing it any +argument (OFF, QUIT, Q, +X...) cancels its effect, meaning that first paragraphs +will once again not be indented. +

+ +

8. Inter-paragraph spacing

+ +

+By default, mom does not insert a blank line between +paragraphs. If you would like her to do so, invoke the macro +PARA_SPACE without an argument, either before or after +START. +PARA_SPACE is a toggle macro, therefore passing it any argument +(OFF, QUIT, Q, X...) +cancels its effect, meaning that paragraphs will once again not be +separated by a blank line. +

+ +

+If you would like to space paragraphs by less than a full linespace, +invoke PARA_SPACE with the amount of space you want as a numeric +argument. A +unit of measure +is required. For example, to space paragraphs by one-quarter +linespace + + .PARA_SPACE .25v + +is how you’d do it, or, if you want six points between +paragraphs + + .PARA_SPACE 6p + +

+ +

+If +flex-spacing +is enabled, additional flexible vertical whitespace can be inserted +between spaced paragraphs with the +FLEX +macro. +

+ +

+PARA_SPACE is not recommended for use with PRINTSTYLE TYPEWRITE +unless you give PRINTSTYLE the SINGLESPACE option. +

+ +
+

+Note: +If PARA_SPACE is on, mom spaces only those paragraphs that come +after an initial paragraph. Initial paragraphs are those that come +immediately after the +docheader +(i.e. the start of a document), +epigraphs, +headings, +and +linebreaks. +(The first paragraph after these document elements requires no +blank line to separate it from other paragraphs.) +

+ +

+Sometimes, you can be fairly deep into a document before using PP +for the first time, and when you do, because mom is still waiting +for that initial paragraph, she doesn’t space it with a blank +line, even though you expect her to. The simple workaround for this +is to invoke .PP twice (in succession) at the point you +expect the blank line to appear. +

+
+ +

+ + + +

Headings

+ + + +

+Heads, subheads, and deeper levels of section headings are +handled by a single macro, HEADING, to which you pass an argument +stating the desired level. +.HEADING 1 "<text>", +for example, would be a main head; +.HEADING 2 "<text>" +would be a subhead; etc. +

+ +

+In addition to printing headings in the body of your document, +HEADING collects the heading as an entry for the Table of Contents, +if the document is to have one, and the +PDF outline. +With the NAMED argument, it furthermore acts as a +bookmark for +PDF links. +

+ +

+Headings can also be numbered on a per-heading-level basis, +hierarchically and concatenatively, e.g. +
+ + 1. + 1.1 + 1.2 + 1.2.1 + 2. + 2.1 + 2.2 + 2.2.1 + +By default, a blank line precedes headings, regardless of the level. +Mom initially sets up a very basic style for nine levels of heading, +of which you can have an infinite number, although as has been said, +if you need more than four levels of heading, you should consider +re-organising your material. The pared-down style of mom’s +defaults is intentional; it is expected that you will design +headings to your own specifications with the +control macro, +HEADING_STYLE. +

+ +

+It is very good practice, and strongly recommended, that you respect +the hierarchy of headings, using level-1 for main heads, level-2 for +subheads, level-3 for subsubheads, etc. The ease of designing and +re-designing the style for each level, plus mom’s very basic +defaults, are meant, in part, to prevent the whimsical misuse of +a particular heading level just because its style appeals to you. +

+ + + +
+

HEADING

+
+ +
+Macro: HEADING <level> [ +PARAHEAD ] [ NAMED <pdf-id> ] "<heading text>" +
+ +

+The first argument to HEADING is the level. Level 1 is +analogous to a main head; level 2 is analogous to a subhead; level 3 +is analogous to a subsubhead; etc. +

+ +

+The second (optional) argument, PARAHEAD, instructs mom +that the heading should be treated as a +paragraph head. +If HEADING is being used to create a parahead, it must come after +PP, +not before. +

+ +

+The indent applied to a parahead is the same as what would be +expected from a paragraph without the parahead (see +Indenting initial paragraphs). +If you wish that a paragraph introduced by a parahead not be +indented, use +PARA_INDENT +to set the paragraph indent to zero, then reset the indent for +subsequent paragraphs. +

+ +

+The optional third argument, NAMED <id>, gives +the heading a unique, non-printing identifier that allows it to be +referenced from anywhere in the final PDF document with the PDF_LINK +macro, provided the mom file is processed with +pdfmom. +PDF_LINK usage is explained in the manual, +Producing PDFs with groff and mom. +

+ +

+The final argument is the text of the heading, surrounded by double +quotes. Long headings that are likely to exceed the current +line length should be broken into chunks, each surrounded by +double-quotes, like this: +
+ + .HEADING 1 "A needlessly long but instructive" "first level heading" + +

+ +
+

+Note: +If a heading falls near the bottom of an output page and mom is +unable to fit the heading plus at least one line of text underneath +it, she will set the head at the top of the next page. +

+
+ +
+

Spacing of headings

+ +

+As described above, mom inserts a blank line before each heading. +If the leading of your document never changes, and you introduce no +additional space into the text—as, for example, between +paragraphs—this will result in perfectly equal whitespace before +each heading. +

+ +

+If, however, you disrupt the regular placement of text on +mom’s +baseline grid, +HEADING adds extra whitespace to the blank line according to the +vertical whitespace management +strategy in effect. This, along with a similar strategy for +whitespace around quotes, blockquotes, and +floated +and +pre-processor material +is what allows mom to balance the bottom +margins of pages effectively. +

+ +

+It occasionally happens that the extra whitespace becomes +noticeable. This typically occurs when the amount of whitespace +adjustment approaches the value of the current leading. The result +looks like two blank lines instead of one. When this happens, a +simple but effective fix is to reduce the space before the heading +by backing up one line, either with +
+ + .SPACE -1v + +or +
+ + .RLD -1v + +This results in slightly less whitespace than normal, but the +difference is usually not apparent. Alternatively, you may pass the +NO_SHIM or NO_FLEX argument to +HEADING_STYLE +to prevent shimming or flex-spacing of any particular heading level +either globally or selectively. If shimming/flex-spacing is +disabled selectively with +
+ + .HEADING_STYLE <n> NO_SHIM | NO_FLEX + +it can be re-enabled for the heading level with +
+ + .HEADING_STYLE <n> SHIM | FLEX + +

+
+ +
+

HEADING control and defaults

+ +
+

+By default, mom pre-initializes nine levels of headings to use +the bold font of the prevailing document family, with a baseline +adjustment of 1/10 of the current +leading. +In addition, level-1 headings are 3 points larger than running text, +level-2 headings 2 points larger, and level 3-headings 1 point +larger. The remaining 6 levels are the same size as running text. +A single blank line precedes all levels of heading. +

+ +

The HEADING_STYLE macro

+ +

+Styling heads is accomplished with a single macro +
+ + .HEADING_STYLE <level> + +where <level> is the numeric heading level to which +the style applies. +

+ +

+HEADING_STYLE takes any or all of the following arguments, +which may be given in any order: +
+ + FAMILY <family> \ + FONT <font> \ + SIZE <+|-size> \ + QUAD <direction> \ + COLOR <colour> \ + UNDERSCORE <weight> <gap> | NO_UNDERSCORE \ + UNDERSCORE2 <weight> <gap1> <gap2> | NO_UNDERSCORE2 \ + CAPS | NO_CAPS \ + SMALLCAPS | NO_SMALLCAPS \ + BASELINE_ADJUST <amount to raise heading from the baseline> \ + NEEDS <lines of text required beneath the heading> \ + PREFIX_CHAPTER [<n>] \ + SPACE_AFTER | NO_SPACE_AFTER \ + NUMBER | NO_NUMBER \ + NO_SHIM | SHIM \ + NO_FLEX | FLEX + +

+ +

+You may enter your entire argument list on a single line, or, if it +is very long, break it into shorter lines with the +“line-continued” backslash (\), as shown +above. +

+ +

+The arguments to FAMILY, FONT, +SIZE, QUAD, and +COLOR are the same as +those you’d give to the +control macros +ending in _FAMILY, _FONT, _SIZE, _QUAD, or _COLOR. See +Arguments to the control macros. +

+ +

+UNDERSCORE and UNDERSCORE2 require that a +weight for the underscore be given, in points (decimal fractions +allowed), but without the unit of measure p appended. +They also require that the underscore’s distance from the +baseline be supplied; in the case of UNDERSCORE2, an additional gap +argument representing the distance between the two underscores must +be provided. +

+ +

+The CAPS argument capitalizes the text of a heading +level in the body of a document but not in the Table of +Contents, where capitalization of entries is controlled by +TOC_ENTRY_STYLE <n>. +

+ +

+BASELINE_ADJUST allows you to raise a heading slightly +above the baseline on which it would otherwise sit. For aesthetic +reasons, it is often desirable to introduce a small amount of space +between a heading and the text following it. Since headings are +preceded by a blank line, it is preferable to move the heading +upward than to lower the text following it. The argument to +BASELINE_ADJUST is the amount by which to raise the heading. It +requires no + or - sign, and must have a +unit of measure +appended to it. +

+ +

+NEEDS lets you reserve the number of lines of text +required beneath a heading, including fractions thereof (e.g. +“1.5” for one line of text plus half a linespace). +If a heading falls near the bottom margin and there isn’t +sufficient room for both the heading and the reserved space, mom +will break to a new page for the heading. A +unit of measure +should not be appended to the argument. +Note: If you have +DROPCAPs +after headings, you must increase the value of NEEDS +to match the number of dropcap lines. +

+ +

+PREFIX_CHAPTER instructs mom to prefix the current +chapter number to numbered headings. If mom is unable to determine +a chapter number, she will ask for one. +

+ +

+Note that using PREFIX_CHAPTER with an explicit chapter +number will also set the chapter number for subsequent +automatically-generated image and pre-processor labels +as well. +

+ +

+SPACE_AFTER inserts a blank line equal to the current +leading after a HEADING. +If you’d like a full linespace after a heading level, use +SPACE_AFTER. If you’d like additional space before +a heading level, you must introduce it yourself with +SPACE +or +ALD. +

+ +

+NUMBER and NO_NUMBER allow you to determine +whether mom prepends a hierarchic numbering scheme to a heading +level in the body of a document. Numbering of Table of Contents +entries is controlled separately with +TOC_ENTRY_NUMBERS. +Mom also has a special macro to toggle whether to prefix a chapter +number to numbered headings and Table of Contents entries, +PREFIX_CHAPTER_NUMBER. +

+ +

+SHIM is not necessary if shimming is enabled +globally, which it is by default; it exists to re-enable +shimming for the heading level if you have previously passed +HEADING_STYLE <n> a NO_SHIM +argument. The FLEX and NO_FLEX arguments work +the same way if flex-spacing is enabled. +

+ +

+The argument list is long, so you may want to break it into +several lines by using the backslash character (\). +Here’s an example of how you might style a level 1 heading: +
+ + .HEADING_STYLE 1 \ + FONT B \ + QUAD C \ + UNDERSCORE .5 2p \ + BASELINE_ADJUST 3p \ + NUMBER + +This creates a level-1 heading style that’s bold, centred, +underscored and numbered, raised by 3 points from the baseline. +

+
+
+ + + +
+

Prefixing chapter numbers

+
+ +
+Macro: PREFIX_CHAPTER_NUMBER <none> | <chapter number as digit> | <anything> +
+ +

+If, in addition to numbering heads, you want mom to prepend the +chapter number, invoke .PREFIX_CHAPTER_NUMBER. +

+ +

+When you invoke .PREFIX_CHAPTER_NUMBER without an +argument, mom checks to see whether the argument you passed to CHAPTER (if it’s been +called) is a digit. If it isn’t (say you’ve numbered your +chapter “One” instead of “1”), mom will +abort with a request that you pass PREFIX_CHAPTER_NUMBER a digit +representing the chapter number. +

+ +

+After you invoke .PREFIX_CHAPTER_NUMBER, mom will prepend +the chapter number to all headings you have requested be numbered +with +.HEADING_STYLE <n> NUMBER. +Thus, assuming chapter number twelve (12): +
+ + 1. LEVEL 1 HEADING + 1.1. Level 2 heading + +would become +
+ + 12.1. LEVEL 1 HEADING + 12.1.1. Level 2 heading + +

+ +
+

+Note: +If a chapter number is given to PREFIX_CHAPTER_NUMBER, automatically +generated labels with a prepended chapter number are also affected. +

+
+ +

+In collated documents, mom automatically increments the digit used +by PREFIX_CHAPTER_NUMBER by one (current chapter digit + 1) every +time you invoke +.COLLATE, +even if you’ve (temporarily) turned off the prefixing +of chapter numbers. Thus, even if you number your chapters +“One”, “Two”, “Three” instead of +“1”, “2”, “3”, mom will Do The +Right Thing with respect to numbering head (and label) elements +in all collated chapters following the first invocation of +PREFIX_CHAPTER_NUMBER (assuming, of course, that the collated +chapters are in incrementing order; if not, you must put +
+ + .PREFIX_CHAPTER_NUMBER <chapter number> + +somewhere after the invocation of COLLATE and before the first +numbered head element of each collated document). +

+ +

+PREFIX_CHAPTER_NUMBER can be disabled by passing it any argument +other than a digit (e.g. (OFF, QUIT, Q, +X...), although, as noted above, mom will keep, +and—in the case of collated documents—increment the +chapter number, allowing you to turn prefixing of chapter numbers to +numbered head elements off and on according to your needs or whims. +

+ +
+

+Note: +Because PREFIX_CHAPTER_NUMBER takes an (optional) digit representing +the chapter number, it’s use need not be restricted to +DOCTYPE CHAPTER. +You can use it with any document type. Furthermore, even if +your doctype isn’t CHAPTER, you can identify +the document as a chapter for the purposes of numbering head +elements by invoking the macro +.CHAPTER +with a +numeric argument +in your document setup. +

+
+

+ + + +

Oldstyle headings

+ + + +

+In versions of mom prior to 2.0, headings were entered by their +commonly used names, viz. HEAD, SUBHEAD, and SUBSUBHEAD. The +new +HEADING +scheme allows for greater flexibility, and permits seamless +integration with PDF output. +

+ +

+Documents created with pre-2.0 versions may still use the oldstyle +heading names, as may new documents, however there are some +differences in their behaviour. +

+ +

+Whenever mom encounters an oldstyle heading, she loads the default +style formerly associated with the oldstyle name. See below for a +description of the default styles in the sections +HEAD (now HEADING 1), +SUBHEAD (now HEADING 2), +and +SUBSUBHEAD (now HEADING 3). +Mom also emits a message to stderr alerting you to what she’s +doing. +

+ +

+The control macros formerly associated with oldstyle headings are no +longer present in mom’s macro file, which means that if you +made changes to mom’s default for those headings, you must +recreate the changes with the +HEADING_STYLE +macro. The entire style need not be recreated, only those +parameters that differed from mom’s defaults. Thus, if your +HEADs were set flush left, instead of the oldstyle default, centred, +but otherwise kept mom’s settings, you need only do +
+ + .HEADING_STYLE 1 QUAD L + +

+ +
+

+Important: +The macro PARAHEAD is no longer available. You must create paragraph +heads using the +HEADING +macro. Mom will abort with an informational message whenever she +encounters PARAHEAD. Assuming a heading level of 3 for your +paraheads, the former defaults for PARAHEAD can be set up like this: +
+ + .HEADING STYLE 3 FONT BI SIZE -.25 \" For PRINTSTYLE TYPESET + .HEADING STYLE 3 FONT I SIZE +0 \" For PRINTSTYLE TYPEWRITE + +Equally, the macro NUMBER_PARAHEADS is no longer available. You +must enable numbering of the correct level for paraheads with +HEADING_STYLE. Again assuming a heading level of 3 for paraheads, +it’s simply done: +
+ + .HEADING_STYLE 3 NUMBER + +

+ +

Correct usage of paraheads

+ +

+It is tempting to choose an arbitrary heading level for paraheads, +since they are sometimes needed out-of-sequence; for example, +immediately after a main head (level-1) in a document that +subsequently requires subheads (level-2). In such a circumstance, +choosing level-3 for all your paraheads might seem to make sense, +but in fact doesn’t, since it disrupts the hierarchy of +both the Table of Contents (if your document has one) and the PDF +outline. +

+ +

+Correct use of the PARAHEAD option to HEADING under such +circumstances requires always assigning PARAHEAD to +the next logical level in the heading hierarchy. For example, if +there are no headings before the parahead, it should be assigned to +level-1. If subsequently there is a main head to be followed by +more paraheads, the main head should be level-1, and the paraheads +level-2. This will almost certainly require assigning new style +parameters to level-1 (with +HEADING_STYLE) +and to the level now being used for paraheads. The following +example demonstrates. +
+ + .HEADING_STYLE 1 FONT BI SIZE +.25 \" parahead style, level-1 + .PP + .HEADING 1 PARAHEAD <parahead> + <paragraph text> + .PP + .HEADING 1 PARAHEAD <parahead> + <paragraph text> + \# main head style, level-1 + .HEADING_STYLE 1 FONT B SIZE +3 QUAD CENTER UNDERSCORE .5 2p + .HEADING_STYLE 2 FONT BI SIZE +.25 \" parahead style, level-2 + .HEADING 1 <main head> + .PP + <paragraph text> + .PP + .HEADING 2 PARAHEAD <parahead> + <paragraph text> + +

+
+ + + +
+

OLDSTYLE HEADINGS

+
+ +
+Macro: OLDSTYLE_HEADINGS +
+ +

+OLDSTYLE_HEADINGS requires no argument. It instructs mom to set the +first three levels of heading to the parameters of her old defaults +for HEAD, SUBHEAD, and SUBSUBHEAD. Use of OLDSTYLE_HEADINGS will +also prevent mom from generating the message she issues the first +time she encounters HEAD, SUBHEAD, and SUBSUBHEAD. +

+ + + + + +

+When invoked for the first time, with or without +OLDSTYLE_HEADINGS, +HEAD sets the parameters for level-1 headings to mom’s old +HEAD defaults, then prints the head as a level-1 heading. +The NAMED <id> optional argument is explained in +the description of +HEADING. +

+ +

+If, prior to invoking HEAD, you have given any parameters to level-1 +heads with +HEADING STYLE, +they will be preserved; any you give afterwards will be respected. +

+ +

+The former style defaults for HEAD were: +
+ + FAMILY = prevailing document family + FONT = bold (TYPESET); roman (TYPEWRITE) + SIZE = +1 (TYPESET); +0 (TYPEWRITE) + QUAD = C + UNDERSCORE .5 2p + CAPS + +

+ +
+

+Note: +The macro NUMBER_HEADS from pre-2.0 versions of mom, can still be +used, though it is now a wrapper for +
+ + .HEADING_STYLE 1 NUMBER + +Mom will alert you to this on stderr. +

+
+ + + +
+Macro: SUBHEAD [ NAMED <id> ] "<text of head>" "<another line>"... +
+ +

+When invoked for the first time, with or without +OLDSTYLE_HEADINGS, +SUBHEAD sets the parameters for level-2 headings to mom’s old +SUBHEAD defaults, then prints the subhead as a level-2 heading. +The NAMED <id> optional argument is explained in +the description of +HEADING. +

+ +

+The former style defaults for SUBHEAD were: +
+ + FAMILY = prevailing document family + FONT = bold (TYPESET); italic, i.e. underlined (TYPEWRITE) + SIZE = +.5 (TYPESET); +0 (TYPEWRITE) + QUAD = L + BASELINE_ADJUST = 1/8 the current leading + +

+ +
+

+Note: +The macro NUMBER_SUBHEADS from pre-2.0 versions of mom, can still be +used, though it is now a wrapper for +
+ + .HEADING_STYLE 2 NUMBER + +Mom will alert you to this on stderr. +

+
+ + + +
+Macro: SUBSUBHEAD [ NAMED <id> ] "<text of head>" "<another line>"... + +
+ +

+When invoked for the first time, with or without +OLDSTYLE_HEADINGS, +SUBSUBHEAD sets the parameters for level-3 headings to mom’s old +SUBSUBHEAD defaults, then prints the subsubhead as a level-3 heading. +The NAMED <id> optional argument is explained in +the description of +HEADING. +

+ +

+The former style defaults for SUBSUBHEAD were: +
+ + FAMILY = prevailing document family + FONT = italic (TYPESET); roman (TYPEWRITE) + SIZE = +.5 (TYPESET); +0 (TYPEWRITE) + QUAD = L + BASELINE_ADJUST = 1/8 the current leading + +

+ +
+

+Note: +The macro NUMBER_SUBSUBHEADS from pre-2.0 versions of mom, can still be +used, though it is now a wrapper for +
+ + .HEADING_STYLE 3 NUMBER + +Mom will alert you to this on stderr. +

+
+ +

+ + + +

Linebreaks (section breaks)

+ + + +

+Linebreaks (“author linebreaks”, “section +breaks”) are gaps in the vertical flow of running text that +indicate a shift in content (e.g. a scene change in story). They +are frequently set off by typographic symbols, sometimes whimsical +in nature. +

+ + + +
+

LINEBREAK

+
+ +
+Macro: LINEBREAK +
+

+Alias: SECTION +

+ +

+LINEBREAK takes no arguments. Simply invoke it (on a line by +itself, of course) whenever you want to insert an author linebreak. +

+ +
+

LINEBREAK control macros and defaults

+ +

+By default, mom marks +author linebreaks +with three centred asterisks (stars) in the prevailing colour of the +document (by default, black). You can alter this with the control +macros +

+
    +
  1. LINEBREAK_CHAR
  2. +
  3. LINEBREAK_COLOR
  4. +
+
+ +

1. Linebreak character

+
+Macro: LINEBREAK_CHAR [ <character> ] [ <iterations> [ <vertical adjustment> ] ] +
+ +

+Alias: SECTION_CHAR +

+

+• The third optional argument requires a +unit of measure. +

+ +

+LINEBREAK_CHAR determines what mom prints when LINEBREAK is invoked. +It takes 3 optional arguments: the character you want deposited at +the line break, the number of times you want the character repeated, +and a vertical adjustment factor. +

+ +

+The first argument is any valid groff character (e.g. * +[an asterisk], \[dg] [a dagger], \f[ZD]\N'141'\fP +[an arbitrary character from Zapf Dingbats], \l'4P' [a +4-pica long rule]). Mom sets the character centred on the current +line length. (See man groff_char for a list of all +valid groff characters.) +

+ +

+The second argument is the number of times to repeat the character. +

+ +

+The third argument is a +|-value by which to raise (-) or lower (+) +the character in order to make it appear visually centred between +sections of text. This lets you make vertical adjustments to +characters that don’t sit on the +baseline +(such as asterisks). The argument must be preceded by a plus or +minus sign, and must include a unit of measure. +

+ +

+If you enter LINEBREAK_CHAR with no arguments, sections of +text will be separated by two blank lines when you invoke +.LINEBREAK. +

+ +

+Mom’s default for LINEBREAK_CHAR is +
+ + .LINEBREAK_CHAR * 3 -3p + +i.e. three asterisks, raised 3 points from their normal vertical +position (for +PRINTSTYLE TYPESET; +the vertical adjustment is -2 points for +PRINTSTYLE TYPEWRITE). +

+ +

2. Linebreak colour

+ +
+Macro: LINEBREAK_COLOR <colourname> +
+

+Alias: SECTION_COLOR +

+ +

+To change the colour of the linebreak character(s), simply invoke +.LINEBREAK_COLOR with the name of a colour pre-defined +(or “initialized”) with +NEWCOLOR +or +XCOLOR. + +

+ +

+ + + +

Quotes (line for line, poetry or code)

+ + + +

+Quotes +are always set in +nofill mode, +flush left. This permits entering quotes on a line for line basis +in your text editor and have them come out the same way on output +copy. (See +Blockquotes +for how quotes, in the present sense, differ from longer passages of +cited text.) +

+ +

+Since mom originally came into being to serve the needs of creative +writers (i.e. novelists, short story writers, etc.—not +to cast aspersions on the creativity of mathematicians and +programmers), she sets quotes in italics +(PRINTSTYLE TYPESET) +or underlined +(PRINTSTYLE TYPEWRITE), +indented from the left margin. Obviously, she’s thinking +“quotes from poetry or song lyrics”, but with the +QUOTE control macros +you can change her defaults so QUOTE serves other needs, e.g. +entering verbatim snippets of programming code, command-line +instructions, and so on. (See the +CODE +for a convenience macro to assist in including code snippets in +documents.) +

+ +

QUOTE spacing

+ +

+Besides indenting quotes, mom further sets them off from +running text +with a small amount of vertical whitespace top and bottom. In +PRINTSTYLE TYPEWRITE, +this is always one full linespace. In +PRINTSTYLE TYPESET, +it’s 1/2 of the prevailing +leading +if the quote fits fully on the page (i.e. with running text above +and below it), otherwise it’s a full linespace either above +or below as is necessary to balance the page to the bottom margin. +This behaviour can be changed with the control macro +ALWAYS_FULLSPACE_QUOTES. +

+ +
+

Notes on quote spacing

+ +

+If your quote (or blockquote) leading differs from the document +leading, mom attempts to observe the same rules for vertical +whitespace outlined above; however, she will also insert a small, +flexible amount of extra whitespace +(shim or flex-spacing) +around the quotes to make sure the whitespace is equal, top and +bottom. When shimming is enabled, this may result in multiple +quotes or blockquotes on the same page being spaced slightly +differently. +

+ +

Disable shimming/flex-spacing of quotes and blockquotes

+ +

+If you don’t want the behaviour +described above (i.e., you don’t want mom putting additional shim +or flex-spacing around quotes and +blockquotes), put .NO_SHIM or/and .NO_FLEX +in the style sheet section of your document (i.e. after PRINTSTYLE +but before START), which will disable shimming or/and flex-spacing +globally for all tags, or disable shimming/flex-spacing +on a per-instance basis prior to .QUOTE or +.BLOCKQUOTE, re-enabling it after the terminating +.QUOTE OFF or .BLOCKQUOTE OFF with +.NO_SHIM OFF or .NO_FLEX OFF. +

+ +
+ +

Keeping QUOTEs and BLOCKQUOTEs together as a block

+ +

+The text of quotes and blockquotes is output immediately, and may therefore +start on one page and finish on the next. If you wish to keep the +text together as a block, deferred to the following page if the +block doesn’t all fit on one page, wrap +(BLOCK)QUOTE...(BLOCK)QUOTE OFF +inside a +float. +If you further wish to force a page break before the floated quote +or blockquote (leaving whitespace at the bottom of the page, pass +FLOAT +the FORCE argument. + + .FLOAT FORCE + .QUOTE + Fly me to the moon + And let me play among the stars + Let me see what life is like + On Jupiter and Mars + .QUOTE END + .FLOAT OFF + +

+ +

Labelling/captioning quotes and blockquotes

+ +

+Quotes and blockquotes may be labelled and/or captioned identically to +floats +with the macros +LABEL +and +CAPTION +(see +Labelling and captioning floats). +

+ + + +
+

QUOTE

+
+ +
+Macro: QUOTE [ ADJUST +|-<space> ] | <anything> +
+

+• The argument to ADJUST requires a +unit of measure +

+ +

+QUOTE is a toggle macro. To begin a section of quoted text, invoke +it with no argument, then type in your quote. When you’re +finished, invoke .QUOTE with any argument (e.g. OFF, +END, X, Q...) to turn it off. Example: +
+ + .QUOTE + Nymphomaniacal Jill + Used a dynamite stick for a thrill + They found her vagina + In North Carolina + And bits of her tits in Brazil. + .QUOTE END + +Mom does her best to equalize whitespace around quotes and make +sure the line following it falls on a valid baseline. On occasion, +you may need to tweak the quote placement slightly, which is done +by passing ADJUST to QUOTE with a plus or minus value. +The quote will be lowered (+) or raised (-) +within the space allotted for it by the given amount. For +example, to lower a quote slightly within the space allotted for it, +you’d do +
+ + .QUOTE ADJUST +3p + There was a soprano named Golda + Whose lovers grew colda and colda + For during love-making + She'd sing the earth-shaking + Love theme from Tristan und Isolde. + .QUOTE off + +

+ + + +

1. Family/font/size/colour/indent

+ +
+

+See +Arguments to the control macros. +
+The following QUOTE control macros may also be +grouped +using QUOTE_STYLE. If you do so, QUOTE_LEFT, QUOTE_CENTER, +and QUOTE_RIGHT must be entered as: +
+   QUAD LEFT
+   QUAD CENTER
+   QUAD RIGHT +

+ + +.QUOTE_FAMILY default = prevailing document family; default is Times Roman +.QUOTE_FONT default = italic; underlined in TYPEWRITE +.QUOTE_SIZE default = +0 (i.e. same size as paragraph text) +.QUOTE_AUTOLEAD default = none; leading of quotes is the same as paragraphs +.QUOTE_COLOR default = black +.QUOTE_INDENT (see below, "Quote indent") +.QUOTE_LEFT -+ Quad direction of quote. +.QUOTE_CENTER | LEFT observes QUOTE_INDENT; +.QUOTE_RIGHT -+ CENTER and RIGHT do not + +
+ +

Quote indent

+ +

+QUOTE_INDENT takes one of two kinds of argument: an integer +representing the amount by which to multiply the argument passed to +.PARA_INDENT +(by default, 2 +ems +for TYPESET, 3 +picas +for TYPEWRITE) to arrive at the quote indent, or a distance with a +unit of measure +appended. +

+ +

+Be careful when using QUOTE. If a quote is set flush left (the +default), the QUOTE_INDENT applies only to the left margin. Because +quote lines are output as-is (see +no-fill mode), +they do not respect line length and may extend beyond a document's +right margin. Similarly, if a quote is being set flush right, the +indent applies only to the right margin; long lines may extend into +the left margin. Centered quotes are never indented, so long lines +may extend beyond both the left and right margins. +

+ +

+The default value for QUOTE_INDENT is 3 (for +PRINTSTYLE TYPESET) +and 1 (for +PRINTSTYLE TYPEWRITE). +

+ +
+

+Note: +If your PARA_INDENT is 0 (i.e. no indenting of the first line of +paragraphs), you must set a QUOTE_INDENT yourself, with a +unit of measure appended to the argument. Mom has no default for +QUOTE_INDENT if paragraph first lines are not being indented. +

+
+ +

2. Spacing above and below quotes (typeset only)

+ +

+If you’d like mom always to put a full linespace above and +below quotes, invoke +
+ + .ALWAYS_FULLSPACE_QUOTES + +with no argument. If you wish to restore mom’s +default behaviour regarding the spacing of quotes (see +Quote spacing), +invoke the macro with any argument (OFF, QUIT, +END, X...) +

+ +
+

+Note: +This macro also sets mom’s spacing policy for +blockquotes. +

+
+ +

3. Underlining quotes (typewrite only)

+ +

+By default in +PRINTSTYLE TYPEWRITE, +mom underlines quotes. If you’d rather she didn’t, +invoke .UNDERLINE_QUOTES with any argument +(OFF, QUIT, END, X...) +to disable the feature. Invoke it without an argument to restore +mom’s default underlining of quotes. +

+ +

+If you not only wish that mom not underline quotes, but also that +she set them in italic, you must follow each instance of QUOTE with +the typesetting macro +FT I. +Furthermore, since mom underlines all instances of italics by +default in PRINTSTYLE TYPEWRITE, you must also make sure that +ITALIC_MEANS_ITALIC is enabled (see +PRINTSTYLE TYPEWRITE control macros). +

+ +

+ + + +

Blockquotes (cited material)

+ + + +

+Blockquotes +are used to cite passages from another author’s work. So that +they stand out well from +running text, +mom indents them from both the left and right margins and sets them +in a different point size +(PRINTSTYLE TYPESET +only). +Output lines +are +filled, +and, by default, +quadded +left. +

+ +

+Besides indenting blockquotes, mom further sets them off from +running text with a small amount of vertical whitespace top and +bottom. (See +Quote spacing +for a complete explanation of how this is managed, and how +to control it.) +

+ +

+Additional information concerning blockquotes, floats, and labelling +blockquotes can be found in the sections +Keeping quotes and blockquotes together as a block, +and +Labelling/captioning quotes and blockquotes. +

+ + + +
+

BLOCKQUOTE

+
+ +
+Macro: BLOCKQUOTE [ ADJUST +|-<space> ] | <anything> +
+ +

+Aliases: CITE, CITATION +

+ +

+• The argument to ADJUST requires a +unit of measure +

+ +

+BLOCKQUOTE is a toggle macro. To begin a cited passage, invoke +the tag with no argument, then type in your blockquote. When +you’re finished, invoke .BLOCKQUOTE with any +argument (e.g. OFF, END, X, Q...) to turn it off. +Example: +
+ + .BLOCKQUOTE + Redefining the role of the United States from enablers to keep + the peace to enablers to keep the peace from peacekeepers is + going to be an assignment. + .RIGHT + \[em]George W. Bush + .BLOCKQUOTE END + +If the cited passage runs to more than one paragraph, you must +introduce each paragraph—including the first—with +.PP. +

+ +

+Mom does her best to equalize whitespace around blockquotes and make +sure the line following it falls on a valid baseline. On occasion, +you may need to tweak the blockquote placement slightly, which is +done by passing ADJUST to BLOCKQUOTE with a plus or minus +value. The blockquote will be lowered (+) or raised +(-) within the space allotted for it by the given +amount. For example, to raise a blockquote slightly within the +space allotted for it, you’d do +
+ + .BLOCKQUOTE ADJUST -3p + True! - nervous - very, very dreadfully nervous I had been and + am; but why will you say that I am mad? The disease had sharpened + my senses - not destroyed - not dulled them. + .RIGHT + \[em]Edgar Allen Poe, The Tell-Tale Heart + .QUOTE off + +

+ +
+

+Note: +The aliases CITE and CITATION may be used in place of the BLOCKQUOTE +tag, as well as in any of the control macros that begin or end with +BLOCKQUOTE_. +

+
+ +
+

BLOCKQUOTE control macros and defaults

+ +
    +
  1. Family/font/size/leading/colour/quad/indent
  2. +
  3. Spacing above and below (typeset only)
  4. +
+
+ +

1. Family/font/size/colour/quad/indent

+ +
+

+See +Arguments to the control macros. +
+The following BLOCKQUOTE control macros may also be +grouped +using BLOCKQUOTE_STYLE. +

+ +.BLOCKQUOTE_FAMILY default = prevailing document family; default is Times Roman +.BLOCKQUOTE_FONT default = roman +.BLOCKQUOTE_SIZE default = -1 (point) +.BLOCKQUOTE_AUTOLEAD default = none; leading of blockquotes is the same as paragraphs +.BLOCKQUOTE_COLOR default = black +.BLOCKQUOTE_QUAD default = left +.BLOCKQUOTE_INDENT (see below) + +
+ +

Blockquote indent

+ +

+BLOCKQUOTE_INDENT takes one of two kinds of argument: an +integer representing the amount by which to multiply the argument +passed to +PARA_INDENT +(by default, 2 +ems +for TYPESET, 3 +picas +for TYPEWRITE) to arrive at the blockquote indent, or a distance with a +unit of measure +appended. Both result in blockquotes being indented equally from +the left and right margins. +

+ +

+The default value for BLOCKQUOTE_INDENT is 3 (for +PRINTSTYLE TYPESET) +and 1 (for +PRINTSTYLE TYPEWRITE). +

+ +
+

+Note: +If your PARA_INDENT is 0 (i.e. no indenting of the first line of +paragraphs), you must set a BLOCKQUOTE_INDENT yourself, with +a unit of measure appended to the argument. Mom has no default for +BLOCKQUOTE_INDENT if paragraph first lines are not being indented. +

+
+ + + +

2. Spacing above and below blockquotes (typeset only)

+ +

+If you’d like mom always to put a full linespace above and +below blockquotes, invoke +
+ + .ALWAYS_FULLSPACE_QUOTES + +with no argument. If you wish to restore mom’s default +behaviour regarding the spacing of blockquotes (see +Quote spacing), +invoke the macro with any argument (OFF, QUIT, +END, X...). +

+ +
+

+Note: +This macro also sets mom’s spacing policy for +quotes. +

+
+ +

+ + + +

Inserting code into a document

+ + + +

+CODE is a convenience macro that facilitates entering code blocks +into documents. Its use is not restricted to documents created +using mom’s document processing macros; it can be used for +“manually” typeset documents as well. +

+ +
+

CODE

+
+ +
+Macro: CODE [BR | BREAK | SPREAD] <anything> +
+ +

+Inline escape: \*[CODE] +

+ +

+When you invoke the macro CODE or insert +\*[CODE] into running text, mom switches to +a +fixed-width font +(Courier, by default) and turns +SMARTQUOTES +off. +

+ +

+If your code includes the backslash character, which is +groff’s escape character, you will have to change the +escape character temporarily to something else with the macro +ESC_CHAR. +Mom has no way of knowing what special characters you’re going +to use in code snippets, therefore she cannot automatically replace +the escape character with something else. +

+ +

+The correct order for changing the escape character inside +CODE is + + .CODE + .ESC_CHAR character + <code> + .ESC_CHAR \ + .CODE OFF + +Be aware that changing the escape character prevents subsequent +macros, which require that the backslash be the escape character, +from functioning correctly. Therefore, do not introduce any macros +into your CODE block without first restoring the escape character to +its default. +

+ +

+Alternatively, you can enter the backslash character as +\e or \\ (two backslashes), which tells groff +to print a literal backslash. +

+ +
+

+Note: +.CODE does not cause a line break when +you’re in a +fill mode +(i.e. +JUSTIFY +or +QUAD +LEFT, CENTER, or RIGHT). +If you want CODE to deposit a break, invoke .CODE with +the argument BR (or BREAK). If, in addition +to having mom break the line before .CODE, you want her +to +force justify +it as well, invoke .CODE with the argument, +SPREAD. If, in addition to breaking the line before CODE +you want a break afterwards, you must supply it manually with +BR +unless what follows immediately is a macro that automatically causes +a break (e.g. +PP). +

+ +

+In all likelihood, if you want the situation described above (i.e. a +break before and after CODE), what you probably want is to use +QUOTE +in conjunction with CODE, like this: +
+ + .QUOTE + .CODE + $ echo "Hello, world" | sed -e 's/Hello,/Goodbye, cruel/' + .QUOTE OFF + +QUOTE takes care of breaking both the text and the code, as well as +indenting the code and offsetting it from +running text +with vertical whitespace. Notice that .CODE, above, has +no corresponding .CODE OFF. .CODE inside a QUOTE +does not require a terminating .CODE OFF, which risks +introducing unwanted vertical whitespace. +

+
+ +

+Passing any argument other than BR, BREAK or +SPREAD to CODE (e.g. OFF, QUIT, +END, X, etc) turns CODE off and returns the +family, font, and smartquotes back to their former state. +

+ +

Using \*[CODE] inline

+ +

+\*[CODE] invokes .CODE, allowing you to +bracket code snippets inline. It does not accept the BR, +BREAK, or SPREAD arguments. It is most useful +for short snippets, as in the following example. +
+ + \*[CODE]apropos\*[CODE X] and \*[CODE]man -k\*[CODE X] are identical. + +

+ +

+\*[CODE] does not permit changing the escape +character, so \e or a doubled backslash must be used. +Furthermore, if your code starts with a period, you must enter it as +“\&.”. +
+ + Registers are created with the \*[CODE]\&.nr\*[CODE X] request. + +

+ +

CODE and punctuation

+ +

+.CODE OFF automatically inserts a word space into +running text. If your CODE block is to be followed by punctuation +with the parameters of +running text, +you must terminate the block with “\c” and +enter the punctuation at the beginning of the next input line. If +the punctuation mark is a period or an apostrophe, you must precede +it with +“\&”. +
+ + ...for example, + .CODE + echo "Hello, world" | sed -e 's/Hello,/Goodbye, cruel/'\c + .CODE OFF + \&. As this demonstrates... + +Use of \*[CODE] inline does not require +the \c, however periods and apostrophes after +\*[CODE X] still need to be introduced +with \&, as in this example: +
+ + ...append the unit of measure \*[CODE]p\*[CODE OFF]\&. New sentence... + +

+ + +
+

CODE control macros and defaults

+ +
    +
  1. Family/Font/Colour
  2. +
  3. Size
  4. +
+
+ +

1. Family/font/colour

+ +
+

+See +Arguments to the control macros. +
+The following CODE control macros may also be +grouped +using CODE_STYLE. +

+ +.CODE_FAMILY default = Courier +.CODE_FONT default = roman; see Note +.CODE_COLOR default = black + +Note: Unlike other control macros, CODE_FONT sets the code font for both +PRINTSTYLE TYPESET and PRINTSTYLE TYPEWRITE. + +
+ +

2. Size

+ +

+CODE_SIZE works a little differently from the other _SIZE macros +(see Arguments to the control +macros). The argument you pass it is a percentage of the +prevailing document point size. It does not require a prepended +plus (+) or minus (-) sign, nor an appended +percent sign (%). Thus, if you want the point size of your CODE font to be +90% of the prevailing document point size, you enter: +
+ + .CODE_SIZE 90 + +Fixed-width fonts have notoriously whimsical +x-heights, +meaning that they frequently look bigger (or, in some cases, +smaller) than the type surrounding them, even if they’re +technically the same point size. CODE_SIZE lets you choose a +percentage of the prevailing point size for your fixed-width +CODE font so it doesn’t look gangly or minuscule in relation +to the type around it. All invocations of .CODE or +\*[CODE] will use this size, so that if you +decide to change the prevailing point size of your document, the +CODE font will be scaled proportionally. +

+ +

+ + + +

Nested lists

+ + + +

+Lists are points or items of interest or importance that are +separated from +running text +by enumerators. Some typical enumerators are +en-dashes, +bullets, +digits and letters. +

+ +

+Setting lists with mom is easy. First, you initialize a list with +the LIST macro. Then, for every item in the list, you invoke +the macro .ITEM followed by the text of the item. +When a list is finished, you exit the list with +.LIST OFF (or QUIT, END, +BACK, etc.) +

+ +

+By default mom starts each list with the enumerator flush with the +left margin of running text that comes before it, like this: +
+ + My daily schedule needs organising. I can’t + seem to get everything done I want. + o an hour’s worth of exercise + o time to prepare at least one healthy + meal per day + o reading time + o work on mom + o writing + - changes from publisher + - current novel + o a couple of hours at the piano + +In other words, mom does not, by default, indent entire lists. +Indenting a list is controlled by the macro +SHIFT_LIST. +(This is a design decision; there are too many instances where a +default indent is not desirable.) Equally, mom does not add any +extra space above or below lists. +

+ +

+Lists can be nested (as in the example above). In other words, +you can set lists within lists, each with an enumerator (and +possibly, indent) of your choosing. In nested lists, each +invocation of .LIST OFF (you may prefer to use +.LIST BACK) takes you back to the previous depth +(or level) of list, with that list’s enumerator and indent +intact. The final .LIST OFF exits lists completely +and returns you to the left margin of running text. +

+ +

+If +QUAD CENTER +is in effect when LIST is invoked, the list is set quad left but +centred on the page as a block, based on the longest line of list +text. Equally, if QUAD RIGHT in in effect, the list is +set flush left but quadded right as a block. If you want a centred +or right-quadded list in an otherwise left-quadded or justified +document, simply invoke .QUAD <direction> +before the list and reset the quad afterwards. Do not use +CENTER +or +RIGHT. +

+ +
+

+Note: +Mom centres lists over the entire line length, disregarding +IB +if it is in effect. If there are lines in the list that exceed +the margins of IB, they must be broken manually with +.BR if you wish to keep them within the indented margins. +

+
+ +

+Finally, lists can be used in documents created with either the +document processing macros +or just the +typesetting macros. +

+ + + +
+

LIST

+
+ +
+Macro: LIST [ BULLET | DASH | DIGIT | ALPHA | alpha | ROMAN<n> | roman<n> | USER <user-defined enumerator> | PLAIN | VARIABLE <character>] [ <separator> ] [ <prefix> ] [ <anything> ] +
+ +

+Invoked by itself (i.e. with no argument), LIST +initializes a list with bullets as the default enumerator. +Afterwards, each block of input text preceded by +.ITEM, +on a line by itself, is treated as a list item. +

+ +
+

+Note: +Every time you invoke .LIST to start a list (as opposed to +exiting one), +you must supply an enumerator (and optionally, a separator) for the +list, unless you want mom’s default enumerator, which is a +bullet. Within nested lists, mom stores the enumerator, separator +and indent for any list you return backwards to (i.e. with +.LIST OFF), but does not store any information for lists +you move forward to. +

+
+ +

+There are a lot of arguments (be sure to side-scroll through them +all, above), so I’ll discuss them one at a time here. +

+

The first argument – enumerator style

+ +

+The optional arguments BULLET, DASH, +DIGIT (for Arabic numerals), ALPHA (for +uppercase letters), alpha (for lowercase letters), +ROMAN<n> (for uppercase roman numerals), +roman<n> (for lowercase roman numerals) tell +mom what kind of enumerator to use for a given list. +

+ +

+The arguments, ROMAN<n> and +roman<n>, are special. You must append to them +a digit (arabic, e.g. "1" or "9" or "17") saying how many items a +particular roman-numeraled LIST is going to have. Mom requires this +information in order to align roman numerals sensibly, and will +abort—with a message — if you don’t provide it. +(For setting roman numeral and digit lists with the enumerators +aligned flush right—the default is flush left—see +PAD_LIST_DIGITS.) +

+ +

+A roman-numeraled list containing, say, five items, would be set +up like this: +
+ + .LIST roman5 producing i) Item 1. + .ITEM ii) Item 2. + Item 1. iii) Item 3. + .ITEM iv) Item 4. + Item 2. v) Item 5. + .ITEM + Item 3 + .ITEM + Item 4 + .ITEM + Item 5 + +

+ +

+The argument VARIABLE <character> lets +you choose different enumerators for the items in a list. +<character> is the widest enumerator to +be used. Thus, if you have a list enumerated by both bullets +and em-dashes, you’d set it up with +
+ + .LIST VARIABLE \[em] + +and select the enumerator you want with +
+ + .ITEM \[em] + +or +
+ + .ITEM \[bu] + +If your enumerator contains spaces, you must enclose the +<character> argument in both LIST and ITEM in +double-quotes, e.g. +
+ + .LIST VARIABLE "\*[UP 1p]\[bu]\*[DOWN 1p]" + .ITEM "\*[UP 1p]\[bu]\*[DOWN 1p]" + +

+ +

+The argument USER lets you make up your own enumerator, +and must be followed by a second argument: what you’d like the +enumerator to look like. For example, if you want a list enumerated +with =>, +
+ + .LIST USER => + .ITEM + A list item + + +will produce +
+ + => A list item + +Some useful special groff characters you might want to pass to +USER are: + + \[sq] - square box + \[rh] - pointing hand + \[->] - right arrow + \[rA] - right double arrow + \[OK] - checkmark + +The size and vertical positioning of special characters may be +adjusted with +inline escapes +in the argument passed to USER. For example, to raise the position +of \[sq] slightly, you might do + + .LIST USER "\*[UP .25p]\[sq]\*[DOWN .25p]" + or + .LIST USER \v'-.25p'\[sq]\v'.25p' + +

+ +

+The argument PLAIN initializes a list with no enumerator. +

+ +
+

+Note: +If the argument to USER contains spaces, you must enclose +the argument in double quotes. +

+
+ +

The second argument – separator style

+ +

+If you choose DIGIT, ALPHA, alpha, +ROMAN<n>, or roman<n>, you may +enter the optional argument, separator, to say what kind +of separator you want after the enumerator. The separator can be +anything you like. The default for DIGIT is a period +(dot), like this: +
+ + 1. A list item + +The default separator for ALPHA, alpha, +ROMAN<n> and roman<n> is a right +parenthesis, like this: +
+ + a) An alpha-ed list item + b) A second alpha-ed list item + +If you’d prefer, say, digits with right-parenthesis separators +instead of the default period, you’d do +
+ + .LIST DIGIT ) + .ITEM + A numbered list item + +which would produce +
+ + 1) A numbered list item + +

+ +
+

+Note: +BULLET, DASH and USER do not take a +separator. +

+
+ +

The third argument – prefix style

+ +

+Additionally, you may give a prefix (i.e. a character +that comes before the enumerator) when your +enumerator style for a particular list is DIGIT, +ALPHA, alpha, ROMAN<n> or +roman<n>. In the arguments to LIST, the prefix +comes after the separator, which is counter-intuitive, +so please be careful. +

+ +

+A prefix can be anything you like. Most likely, you’ll want +some kind of open-bracket, such as a left parenthesis. If, for +example, you want a DIGIT list with the numbers enclosed +in parentheses, you’d enter +
+ + .LIST DIGIT ) ( + .ITEM + The first item on the list. + .ITEM + The second item on the list. + +which would produce +
+ + (1) The first item on the list. + (2) The second item on the list. + +

+ +
+

+Note: +BULLET, DASH and +USER do not take a prefix. +

+
+ +

Exiting lists – LIST OFF / BACK or QUIT_LISTS

+ +

+Any single argument to LIST other than +BULLET, DASH, DIGIT, +ALPHA, alpha, ROMAN<n>, +roman<n> or USER (e.g. +LIST OFF or LIST BACK) takes you out +of the current list. +

+ +

+If you are at the first list-level (or list-depth), mom returns you +to the left margin of running text. Any indents that were in effect +prior to setting the list are fully restored. +

+ +

+If you are in a nested list, mom moves you back one list-level +(i.e., does not take you out of the list structure) and restores the +enumerator, separator and indent appropriate to that level. +

+ +

+Each invocation of .LIST should thus be matched by +a corresponding .LIST OFF in order to fully exit +lists. For example, +
+ + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, + sed diam nonumy eirmod tempor invidunt ut labore. + o List item in level 1 + o List item in level 1 + - List item in level 2 + - List item in level 2 + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, + sed diam nonumy eirmod tempor invidunt ut labore. + +is created like this: +
+ + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, + sed diam nonumy eirmod tempor invidunt ut labore. + .LIST BULLET + .ITEM + List item in level 1 + .ITEM + List item in level 1 + .LIST DASH + .ITEM + List item in level 2 + .ITEM + List item in level 2 + .LIST OFF \" Turn level 2 list off + .LIST OFF \" Turn level 1 list off + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, + sed diam nonumy eirmod tempor invidunt ut labore. + +Alternatively, you may use the single-purpose macro +.QUIT_LISTS, to get yourself out of a list structure. In +the example above, the two .LIST OFF lines could be +replaced with a single .QUIT_LISTS. +

+ +
+

ITEM

+
+ +
+Macro: ITEM [<enumerator>] [<space>] +
+

+• The argument to <space> requires a +unit of measure +

+ +

+After you’ve initialized a list with +LIST, +precede each item you want in the list with .ITEM. Mom +takes care of everything else with respect to setting the item +appropriate to the list you’re in. +

+ +

+If you’ve chosen the VARIABLE argument when +invoking LIST, ITEM must be followed by an enumerator character. +

+ +

+If you give ITEM a space argument, either by itself or after a +variable enumerator character, the item will be spaced by the amount +of the argument. +

+ +

+In document processing, it is valid to have list items that contain +multiple paragraphs. Simply issue a +.PP +request for each paragraph following the first item. +I.e., don’t do this: +
+ + .ITEM + .PP + Some text... + .PP + A second paragraph of text + +but rather +
+ + .ITEM + Some text... + .PP + A second paragraph of text + +

+ +
+

LIST control macros and defaults

+ +

+LIST control macros may not be +grouped. +

+ +
    +
  1. Indenting lists (SHIFT_LIST)
  2. +
  3. Resetting an initialized list’s enumerator (RESET_LIST)
  4. +
  5. Padding digit enumerators (PAD_LIST_DIGITS)
  6. +
+
+ +

1. Indenting lists – SHIFT_LIST

+ +

+If you want a list to be indented to the right of running text, or +indented to the right of a current list, use the macro SHIFT_LIST +immediately after +LIST. +SHIFT_LIST takes just one argument: the amount by which you want the +list shifted to the right. The argument requires a +unit of measure. +

+ +

+SHIFT_LIST applies only to the list you just initialized with LIST. +It does not carry over from one invocation of LIST to the next. +However, the indent remains in effect when you return to a list +level in a nested list. +

+ +

+For example, if you want a 2-level list, with each list indented to +the right by 18 +points, +
+ + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, + sed diam nonumy eirmod tempor invidunt ut labore. + .LIST \" List 1 + .SHIFT_LIST 18p \" Indent 18 points right of running text + .ITEM + List 1 item + .ITEM + List 1 item + .LIST DASH \" List 2 + .SHIFT_LIST 18p \" Indent 18 points right of list 1 + .ITEM + List 2 item + .ITEM + List 2 item + .LIST OFF \" Move back to list 1 + .ITEM + List 1 item + .ITEM + List 1 item + .LIST OFF \" Exit lists + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, + sed diam nonumy eirmod tempor invidunt ut labore. + +produces (approximately) +
+ + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, + sed diam nonumy eirmod tempor invidunt ut labore. + • List 1 item + • List 1 item + - List 2 item + - List 2 item + • List 1 item + • List 1 item + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, + sed diam nonumy eirmod tempor invidunt ut labore. + +

+ +

2. Resetting an initialized list’s enumerator – RESET_LIST

+ +

+In nested lists, if your choice of enumerator for a given level +of list is DIGIT, ALPHA, alpha, +ROMAN or roman, you may sometimes want to +reset the list’s enumerator when you return to that list. +Consider the following: +
+ + Things to do religiously each and every day: + • take care of the dog + a) walk every day + b) brush once a week + - trim around the eyes every fourth brushing + - don’t forget to check nails + • feed the cat + d) soft food on Mon., Wed. and Fri. + e) dry food on Tues., Thurs. and Sat. + f) canned tuna on Sunday + +

+ +

+The alpha-enumerated items under “Feed the cat” +would be normally a), b), c), but we want d), e), f). The +solution is to reset the second .LIST alpha’s +enumerator—before the first .ITEM—with +the macro RESET_LIST. +

+ +

+With no argument, .RESET_LIST resets an incrementing +enumerator to 1, A, a, I or i depending on the style of enumerator. +If you pass .RESET_LIST a +numeric argument, +it represents the starting position for an incrementing enumerator. In +the example above, .RESET_LIST 4 starts the second +alpha-ed list at d). +

+ +

3. Padding digit enumerators – PAD_LIST_DIGITS

+ +
Arabic digits
+ +

+When your choice of enumerators is DIGIT and the number of items +in the list exceeds nine (9), you have to make a design decision: +should mom leave room for the extra numeral in two-numeral digits to +the right or the left of the single-numeral digits? +

+ +

+If you want the extra space to the right, invoke the macro +.PAD_LIST_DIGITS (with no argument), after +.LIST and before .ITEM. This will produce +something like +
+ + 8. List item + 9. List item + 10. List item + +If you want the extra space to the left, invoke +.PAD_LIST_DIGITS with the single argument, +LEFT, which will produce +
+ + 8. List item + 9. List item + 10. List item + +

+ +

+Of course, if the number of items in the list is less than ten +(10), there’s no need for PAD_LIST_DIGITS. +

+ +
Roman numerals
+ +

+By default, mom sets roman numerals in lists flush left. The +<n> argument appended to ROMAN<n> +or roman<n> allows her to calculate how much space +to put after each numeral in order to ensure that the text of items +lines up properly. +

+ +

+If you’d like the roman numerals to line +up flush right (i.e. be padded "left"), simply +invoke .PAD_LIST_DIGITS LEFT after +.LIST ROMAN<n> or +.LIST roman<n> and before .ITEM. +

+ +

+ + + +

Line numbering – prepend numbers to output lines

+ + + +

+When you turn line-numbering on, mom, by default +

+
    +
  • numbers every line of paragraph text; line-numbering is + suspended for all other document processing tags (like + docheaders, epigraphs, headings, quotes, etc.) and special + pages (covers, endotes, bibliographies, etc.); be aware, + though, that if you turn + docheaders + off (with + DOCHEADER OFF) + and create your own docheader, mom + will line-number your custom docheader, so turn + line numbering on afterwards +
  • +
  • doesn’t touch your line length; line numbers are hung + outside your current left margin (as set with + L_MARGIN, + PAGE + or + DOC_LEFT_MARGIN), + regardless of any indents that may be active +
  • +
  • separates line numbers from running text by two + figure spaces. +
  • +
+ +

+Mom expects that +QUOTEs +and +BLOCKQUOTEs +will not be line-numbered, however control macros are provided to +enable line numbering for either. +See +Line numbering control macros for quotes and blockquotes. +

+ + + +
+

NUMBER_LINES

+
+ +
+Macro: NUMBER_LINES <start number> [ <which lines to number> [ <gutter> ] ] +
+ +
+Macro: NUMBER_LINES <anything> | RESUME +
+ +

+NUMBER_LINES does what it says: prints line numbers, to the left of +output lines +of paragraph text. One of the chief reasons for wanting numbered +lines is in order to identify footnotes or endnotes by line number +instead of by a marker in the text. (See +Footnotes by linenumber +for instructions on line-numbered footnotes, and +ENDNOTE_MARKER_STYLE LINE +for instructions on line-numbered endnotes.) +

+ +
+

+Note: +Do not use NUMBER_LINES inside +QUOTE +or +BLOCKQUOTE. +By default, mom expects that quotes and blockquotes will not be +line numbered. If you wish to enable line numbering for them, you +must invoke +NUMBER_QUOTE_LINES +or +NUMBER_BLOCKQUOTE_LINES. +

+
+ + +

+The first time you invoke +NUMBER_LINES +you must, at a minimum, tell it what line number you want the +next +output line +to have. The optional arguments <which lines to number> +and <gutter> allow you to state which lines should +be numbered (e.g. every five or every ten lines), and the gutter to +place between line numbers and +running text. +

+ +

+For example, if you want mom to number output lines using her defaults, + + .NUMBER_LINES 1 + +will prepend the number, 1, to the next output line and number all +subsequent output lines sequentially. +

+ +

+If you want only every five lines numbered, pass mom the optional +<which lines to number> argument, like this: + + .NUMBER_LINES 1 5 + +

+ +
+

+GOTCHA! +The argument to <which lines to number> instructs +mom to number only those lines that are multiples of the argument. +Hence, in the above example, line number 1 will +not be numbered, since 1 is not a multiple of +5. +

+ +

+If you want line number 1 to be numbered, you have +to invoke .NUMBER_LINES 1 1 before the +first output line you want numbered, then study your output +copy and determine where best to insert the following in your +input text: +
+ + .NUMBER_LINES \n[ln] 5 + +(The escape \n[ln] ensures that NUMBER_LINES +automatically supplies the correct value for the first argument, +<start number>.) +

+ +

+Following this recipe, line number 1 will be numbered; +subsequently, only line numbers that are multiples of 5 will be +numbered. A little experimentation may be required to determine the +best place for it in your input text. +

+
+ +

+The optional argument, <gutter>, tells mom how much +space to put between the line numbers and the running text. +<gutter> does not require (or even accept) a +unit of measure. +The argument you pass to it is the number of +figure spaces +you want between line numbers and running text. +Mom’s default gutter is two figure spaces. If +you’d like a wider gutter, say, four figures spaces, you’d do +
+ + .NUMBER_LINES 1 1 4 + | + +-- Notice you *must* supply a value + for the 2nd argument in order to supply + a value for the 3rd. + +

+ +
+

+Note: +When giving a value for <gutter>, you cannot skip +the <which lines to number> argument. Either fill +in the desired value, or use two double-quotes ( "" ) to +have mom use the value formerly in effect. +

+
+ +

Off/suspend, resume

+ +

+After initializing line numbering, you can suspend it, with the +option to resume, using +
+ + .NUMBER_LINES OFF + +(or END, QUIT, X, etc). +

+ +

To resume line numbering: +
+ + .NUMBER_LINES RESUME + +When you resume, the line number will be the next in sequence +from where you left off. If that is not what you want—say +you want to reset the line number to 1—re-invoke +.NUMBER_LINES with whatever arguments are needed for the +desired result. +

+ +
+

+Additional notes: +

+
    +
  1. In document processing, you may invoke + .NUMBER_LINES either before or after + .START. Mom doesn’t care. +
  2. +
  3. If you’re collating documents with + COLLATE, + you should re-invoke, at a minimum, + .NUMBER_LINES 1 for each collated + document, in order to ensure that each begins with the + number 1 prepended to the first line. +
  4. +
  5. Occasionally, you may want to + change the current gutter between line numbers and running + text without knowing what the next output line number should + be. Since NUMBER_LINES requires this number as its first + argument, in such instances, pass NUMBER_LINES as its first + argument the escape + \n[ln]. +
    + For example, if you were numbering every 5 lines with a + gutter of 2 (figure spaces) and you needed to change the + gutter to 4 (figures spaces), +
    + + .NUMBER_LINES \n[ln] 5 4 + + would do the trick. +
    +
  6. +
  7. If you’re using + margin notes + in a document, be sure to set the gutter for margin notes wide + enough to allow room for the line numbers. +
  8. +
  9. Mom (groff, actually), only numbers + lines to the left of running text. For aesthetic + reason, therefore, the use of line numbering when setting a + document in columns is discouraged. However, should you wish + to number lines when setting in columns, make sure the + gutter(s) + between columns is wide enough to leave room for the numbers. +
  10. +
+
+ + + +

1. Family/font/size/colour

+ +
+

+See +Arguments to the control macros. +
+The following NUMBER_LINES control macros may also be +grouped +using LINENUMBER_STYLE. +

+ +.LINENUMBER_FAMILY default = prevailing family or document family; default is Times Roman +.LINENUMBER_FONT default = prevailing font +.LINENUMBER_SIZE default = +0 +.LINENUMBER_COLOR default = black + +
+ +

2. Reset line numbering after COLLATE

+ +

+After +COLLATE, +line numbering continues from where it left off. If you would like +each chapter or major document section to begin its line numbering +at “1”, invoke + + .NUMBER_LINES_PER_SECTION + +after +.NUMBER_LINES. +

+ +

3. Line numbering control macros for QUOTE and BLOCKQUOTE

+ +
• Including QUOTEs and BLOCKQUOTEs in the line numbering scheme
+ +

+If you’d like mom to number lines in a +QUOTE +or +BLOCKQUOTE +as part of the same order and sequence as paragraph text, +invoke + + .NUMBER_QUOTE_LINES + +or + + .NUMBER_BLOCKQUOTE_LINES + +either before or after NUMBER_LINES. Both behave identically with +respect to the affected macro (i.e. QUOTE or BLOCKQUOTE). +

+ +
• Selectively enabling line numbering for QUOTEs and BLOCKQUOTEs
+ +

+If you’d like to enable line numbering selectively for quotes +and blockquotes only, invoke .NUMBER_QUOTE_LINES +or .NUMBER_BLOCKQUOTE_LINES first, followed by +.NUMBER_LINES <n>, where <n> +is the first line number of the quote or blockquote. Afterwards, +enter your QUOTE or BLOCKQUOTE. When the quote or blockquote +is finished (i.e. after .QUOTE OFF or +.BLOCKQUOTE OFF), turn line numbering off. Each +subsequent quote or blockquote you want line numbered requires +only .NUMBER_LINES <n> (with a corresponding +.NUMBER_LINES OFF) until you turn NUMBER_QUOTE_LINES or +NUMBER_BLOCKQUOTE_LINES off. +

+ +

+Here’s a recipe where the first line number of quotes starts +repeatedly at “1”. + + <running text> + .NUMBER_QUOTE_LINES + .NUMBER_LINES 1 + .QUOTE + <text of quote> + .QUOTE OFF + .NUMBER_LINES OFF + <further running text> + .NUMBER_LINES 1 + .QUOTE + <text of quote> + .QUOTE OFF + .NUMBER_LINES OFF + <further running text> + +

+ +
• Changing the line number gutter for QUOTEs and BLOCKQUOTEs
+ +

+Owing to groff’s restriction on accepting only the figure +space as the line number +gutter’s +unit of measure, it is not possible for line numbers in quotes +or blockquotes to hang outside a document’s overall left +margin and be reliably flush with the line numbers of paragraph +text. Consequently, line numbers in quotes or blockquotes hang +to the left of the quote, separated by the currently active +gutter for NUMBER_LINES. +

+ +

+If you’d like to change the line number gutter for quotes +or blockquotes, invoke .NUMBER_QUOTE_LINES or +.NUMBER_BLOCKQUOTE_LINES with a digit representing the +number of +figure spaces +you’d like between the line numbers and the quoted text, like this: +
+ + .NUMBER_QUOTE_LINES 3 + +With the above, line numbers in quotes (and only quotes) will have +a gutter of 3 figure spaces. +

+ +
• Silently increment line numbers during QUOTE and BLOCKQUOTE
+ +

+If you’ve asked mom not to line number quotes or blockquotes, +but would like line numbering to continue while they’re +being output (as opposed to mom’s default behaviour of +suspending incrementing of line numbers during the output of +quotes and blockquotes), invoke + + .NUMBER_QUOTE_LINES SILENT + +or + + .NUMBER_BLOCKQUOTE_LINES SILENT + +With these, mom continues to increment line numbers while quotes +or blockquotes are being output, but the line numbers won’t +appear in the output copy. +

+ +

+Once having turned NUMBER_QUOTE_LINES or NUMBER_BLOCKQUOTE_LINES on, +you may disable them with + + .NUMBER_QUOTE_LINES OFF + +or + + .NUMBER_BLOCKQUOTE_LINES OFF + +

+ +

+ + + +

Footnotes

+ + + +

+For something so complex behind the scenes, footnotes are easy to use. +You just type, for example, +
+ + ...the doctrines of Identity as urged by Schelling\c + .FOOTNOTE + <footnote about who the hell is Schelling> + .FOOTNOTE OFF + were generally the points of discussion presenting the most + of beauty to the imaginative Morella. + +and be done with it. +(Note the obligatory use of the \c +inline escape, +required whenever your +FOOTNOTE_MARKER_STYLE +is either STAR [star/dagger footnotes] or +NUMBER [superscript numbers].) +

+ +

+After you invoke .FOOTNOTE, mom takes care of everything: +putting footnote markers in the body of the document, keeping track +of how many footnotes are on the page, identifying the footnotes +themselves appropriately, balancing them properly with the bottom +margin, deferring footnotes that don’t fit on the page... +Even if you’re using +COLUMNS, +mom knows what to do, and Does The Right Thing. +

+ +
+

+Note: +See +refer.html +for information on using footnotes with the refer +bibliographic database. +

+
+ +

Footnote behaviour

+ +

+Footnotes can be sly little beasts. If you’re writing a +document that’s footnote-heavy, you might want to read the +following. +

+ +

+By default, mom marks footnotes with alternating stars (asterisks), +daggers, and double-daggers. The first footnote gets a star, the +second a dagger, the third a double-dagger, the fourth two stars, +the fifth two daggers, etc. If you prefer numbered footnotes, rest +assured mom is happy to oblige. +

+ +

+A small amount of vertical whitespace and a short horizontal rule +separate footnotes from the document body. When +shimming +is enabled, the amount of whitespace +may vary slightly from page to page depending on the number of lines +in the footnotes. Mom tries for a nice balance between too little +whitespace and too much, but when push comes to shove, she’ll +usually opt for ample over cramped. The last lines of footnotes are +always flush with the document’s bottom margin. +

+ +

+When +flex-spacing +is enabled, the distance between the last line of text and the +first footnote is always the same. +

+ +

+If mom sees that a portion of a footnote cannot be fit on its page, +she carries that portion over to the next page. If an entire +footnote can’t be fit on its page (i.e., FOOTNOTE has been +called too close to the bottom), she defers the footnote to the next +page, but sets it with the appropriate marker from the previous +page. +

+ +

+When footnotes occur within cited text, for example a +QUOTE +or a +BLOCKQUOTE, +mom will usually opt for deferring the footnote over to the next +page if it allows her to complete the cited text on one page. +

+ +

+In the unfortunate happenstance that a deferred footnote is the +only footnote on its page (i.e., it’s marked in the document +body with a star) and the page it’s deferred to has its own +footnotes, mom separates the deferred footnote from the page’s +proper footnote(s) with a blank line. This avoids the confusion +that might result from readers seeing two footnote entries on +the same page identified by a single star (or the number 1 if +you’ve requested numbered footnotes that begin at 1 on every +page). The blank line makes it clear that the first footnote entry +belongs to the previous page. +

+ +

+In the circumstance where a deferred footnote is not the only one +on its page, and is consequently marked by something other than +a single star, there’s no confusion and mom doesn’t +bother with the blank line. (By convention, the first footnote on +a page is always marked with a single star, so if readers see, say, +a dagger or double-dagger marking the first footnote entry, +they’ll know the entry belongs to the previous page). +

+ +

+Very exceptionally, two footnotes may have to be deferred (e.g., one +occurs on the second to last line of a page, and another on the last +line). In such a circumstance, mom does not add +a blank after the second deferred footnote. If you’d like a blank +line separating both deferred footnotes from any footnotes proper to +the page the deferred ones were moved to, add the space manually by +putting a +.SPACE +command at the end of the footnote text, before +.FOOTNOTE OFF (or OFF, QUIT, +END, X, etc). +

+ +

+Obviously, deferred footnotes aren’t an issue if you request +numbered footnotes that increase incrementally throughout the whole +document—yet another convenience mom has thought of. +

+ +

+While mom’s handling of footnotes is sophisticated, +and tries to take nearly every imaginable situation under which they +might occur into account, some situations are simply impossible from +a typographic standpoint. For example, if you have a +HEAD +near the bottom of a page and the page has some footnotes on it, mom +may simply not have room to set any text under the head (normally, +she insists on having room for at least one line of text beneath +a head). In such an instance, mom will either set the head, with +nothing under it but footnotes, or transfer the head to the next +page. Either way, you’ll have a gaping hole at the bottom +of the page. It’s a sort of typographic Catch-22, and can +only be resolved by you, the writer or formatter of the document, +adjusting the type on the offending page so as to circumvent the +problem. +

+ +

Footnote markers and punctuation in the running text

+ +
    +
  1. “Fill” modes – JUSTIFY, or QUAD LEFT | CENTER | RIGHT
  2. +
  3. “No-fill” modes – LEFT, CENTER, RIGHT
  4. +
+ +

1. “Fill” modes – JUSTIFY, or QUAD LEFT | CENTER | RIGHT

+ +

+In +fill +modes, the correct way to enter the line after +.FOOTNOTE OFF is to input it as if it’s +literally a continuation of the input line you were entering before +you invoked .FOOTNOTE. Therefore, if necessary, the +input line may have to begin with space(s) or a punctuation mark, as +in the two following examples. +

+ +
+
Example 1
+ +A line of text,\c +.FOOTNOTE +A footnote line. +.FOOTNOTE OFF + broken up with a comma. +^ +(last line begins with a literal space) + +
+ +
+
Example 2
+ +A line of text\c +.FOOTNOTE +A footnote line. +.FOOTNOTE OFF +, broken up with a comma. +^ +(last line begins with a comma and a space) + +
+ +

+Example 1 produces, on output +
+ + A line of text,* broken up with a comma. + +Example 2 produces +
+ + A line of text*, broken up with a comma. + +Care must be taken, though, if the punctuation mark that begins the +line after .FOOTNOTE OFF is a period (dot). You +must begin such lines with \&., like +this: +
+ + ...end of sentence\c + .FOOTNOTE + A footnote line. + .FOOTNOTE OFF + \&. A new sentence... + +If you omit the \&., the line will vanish! +

+ +
+

+Note: +The document element tags, +EPIGRAPH +and +BLOCKQUOTE, +imply a fill mode, therefore these instructions also apply when you +insert a footnote into epigraphs or blockquotes. +

+
+ +

2. “No-fill” modes – LEFT, CENTER, RIGHT

+ +

+In +no-fill +modes, you must decide a) whether text on the input line +after .FOOTNOTE OFF is to be joined to the +output line before .FOOTNOTE was invoked, or b) +whether you want the output text to begin on a new line. +

+ +

+In the first instance, simply follow the instructions, +above, +for fill modes. +

+ +

+In the second instance, you must explicitly tell mom that +you want input text after .FOOTNOTE OFF to +begin on a new output line. This is accomplished by passing +.FOOTNOTE OFF (or OFF, QUIT, +END, X, etc) an additional argument: +BREAK or BR. +

+ +

+Study the two examples below to understand the difference. +

+ +
+
Example 1
+ +.LEFT +A line of text\c +.FOOTNOTE +A footnote line +.FOOTNOTE OFF +that carries on after the footnote. + +
+ +
+
Example 2
+ +.LEFT +A line of text\c +.FOOTNOTE +A footnote line +.FOOTNOTE OFF BREAK +that doesn’t carry on after the footnote. + +
+ +

+Example 1, on output, produces +
+ + A line of text* that carries on after the footnote. + +whereas Example 2 produces + + A line of text* + that doesn’t carry on after the footnote. + +The distinction becomes particularly important if you like to see +punctuation marks come after footnote markers. In no-fill +modes, that’s accomplished like this: +
+ + .LEFT + A line of text\c + .FOOTNOTE + A footnote line + .FOOTNOTE OFF + , + broken up with a comma. + +The output of the above looks like this: +
+ + A line of text*, + broken up with a comma. + +

+ +
+

+Note: +The document element tag, +QUOTE, +implies a no-fill mode, therefore these instructions also apply when +you insert footnotes into quotes. +

+
+ + + +
+

FOOTNOTE

+
+ +
+Tag: FOOTNOTE <toggle> [ BREAK | BR ] [ INDENT LEFT | RIGHT | BOTH <indent value> ] +
+ +

+• <indent value> requires a unit of measure +
+See HYPER-IMPORTANT NOTE. +

+ +

+FOOTNOTE is a toggle macro, therefore invoking it on a line by +itself allows you to enter a footnote in the body of a document. +Invoking it with any argument other than INDENT (i.e. +OFF, QUIT, END, X...) +tells mom you’re finished. +

+ +

+Footnotes are the only element of +running text +that are not affected by the typesetting +indent macros. +In the unlikely event that you want a page’s footnotes to +line up with a running indent, invoke .FOOTNOTE with +the INDENT argument and pass it an indent direction and +indent value. L, R, and B may be used in place +of LEFT, RIGHT, and BOTH. FOOTNOTE must be +invoked with INDENT for every footnote you want indented; +mom does not save any footnote indent information from invocation to +invocation. +

+ +
+

+Note: +If a footnote runs to more than one paragraph, do not begin +the footnote with the +PP +tag. Use .PP only to introduce subsequent paragraphs. +

+
+ +
+

+HYPER-IMPORTANT NOTE: +The final word on the +input line +that comes immediately before FOOTNOTE must terminate with a +\c +inline escape if your +FOOTNOTE_MARKER_STYLE +is either STAR or NUMBER. See the +footnote example +above. +

+ +

+Additionally, in +fill +modes +(JUSTIFY +or +QUAD), +the line after a .FOOTNOTE OFF should be +entered as if there were no interruption in the input text, i.e., +the line should begin with a literal space or punctuation mark (see +explanation and examples +here). +

+ +

+In +no-fill +modes, the optional argument BREAK or BR may +be used after the OFF (or OFF, +QUIT, END, X, etc) argument to +instruct mom not to join the next input line to the previous output. +See +here +for a more complete explanation, with examples. +

+ +

+Do not use the \c inline escape if your +FOOTNOTE_MARKER_STYLE is LINE, or if you have disabled +footnote markers with +.FOOTNOTE_MARKERS OFF. +In these instances, the line after .FOOTNOTE OFF +should be entered normally. +

+
+ +
+

FOOTNOTE control macros and defaults

+ +
    +
  1. Family/font/size/colour/lead/quad
  2. +
  3. Footnote markers – on or off
  4. +
  5. Footnote marker style – star+dagger or numbered +
  6. +
  7. Footnotes by line number +
  8. +
  9. Reset footnote number – set footnote marker number to 1
  10. +
  11. Inter-footnote spacing
  12. +
  13. Footnote rule – on or off
  14. +
  15. Footnote rule length – length of footnote separator rule
  16. +
  17. Footnote rule weight – weight of footnote separator rule
  18. +
  19. Adjust vertical position of footnote separator rule
  20. +
+
+ +

1. Family/font/size/colour/lead/quad

+ +
+

+See +Arguments to the control macros. +
+The following FOOTNOTE control macros may also be +grouped +using FOOTNOTE_STYLE. +

+ +.FOOTNOTE_FAMILY default = prevailing document family; default is Times Roman +.FOOTNOTE_FONT default = roman +.FOOTNOTE_SIZE default = -2 (points) +.FOOTNOTE_COLOR default = black +.FOOTNOTE_AUTOLEAD default = 2 points (typeset); single-spaced (typewrite) +.FOOTNOTE_QUAD default = same as paragraphs + +
+ +

2. Footnote markers – FOOTNOTE_MARKERS

+ +

+If you don’t want footnote markers in either the body of +the document or beside footnote entries themselves, toggle them +off with .FOOTNOTE_MARKERS OFF (or OFF, +QUIT, END, X...). This means, +of course, that you’ll have to roll your own. If you want +them back on, invoke .FOOTNOTE_MARKERS with no argument. +Footnote markers are on by default. +

+ +

+If FOOTNOTE_MARKERS are disabled, do not use the \c +inline escape to terminate the line before .FOOTNOTE. +

+ +

3. Footnote marker style – FOOTNOTE_MARKER_STYLE

+ +

+Mom gives you two choices of footnote marker style: star+dagger (see +footnote behaviour +above), or numbered. +

+ +

+.FOOTNOTE_MARKER_STYLE STAR gives you star+dagger (the +default). There is a limit of 10 footnotes per page with this +style. +

+ +

+.FOOTNOTE_MARKER_STYLE NUMBER gives you superscript +numbers, both in the document body and in the footnote entries +themselves. By default, footnote numbers increase incrementally +(prev. footnote number + 1) throughout the whole document. You +can ask mom to start each page’s footnote numbers at 1 with +.RESET_FOOTNOTE_NUMBER +(see below.) +

+ +

+If your +PRINTSTYLE +is TYPEWRITE and you would prefer that the footnotes +themselves not use superscript numbers, you may pass +.FOOTNOTE_MARKER_STYLE NUMBER an additional argument: +NO_SUPERSCRIPT. While the marker in the text will still +be superscript, the footnotes themselves will be identified with +normal-sized, base aligned numbers, surrounded by parentheses. +

+ +
Left padding of footnote numbers
+ +

+When footnote numbering is enabled, in order to ensure that the +left margin of footnote text aligns regardless of the footnote +number, you sometimes have to pad the footnote numbers. This will +be the case any time the footnote numbers change from 9 to 10 on +the same page, or from 99 to 100. Consider this scenario: +
+ + 9 Footnote text + 10 Footnote text + 11 Footnote text + +As you can see, the left margins of the footnotes are not aligned. +

+ +

+In order to correct this, use the macro +.FOOTNOTE_NUMBER_PLACEHOLDERS, which takes a single +argument: the number of placeholders in the longer digit. For +example, placed at an appropriate point in your input file, +.FOOTNOTE_NUMBER_PLACEHOLDERS 2 causes the above +example to come out like this: +
+ + 9 Footnote text + 10 Footnote text + 11 Footnote text + +Given the impossibility of knowing in advance when the number of +placeholders required for footnote numbers will change, you must +study your output file to determine where to insert this +macro into your input file. +

+ +

+Obviously, mom does not provide a default for +.FOOTNOTE_NUMBER_PLACEHOLDERS. +

+ +
+

+Note: +.FOOTNOTE_NUMBER_PLACEHOLDERS affects both superscript +footnote numbers, and, in +PRINTSTYLE TYPEWRITE, +the normal, base-aligned numbers surrounded by parentheses that you +get with +.FOOTNOTE_MARKER_STYLE NUMBER NO_SUPERSCRIPT. +

+
+ +

4. Footnotes by line number – FOOTNOTE_MARKER_STYLE LINE

+ +

+FOOTNOTE_MARKER_STYLE with the argument, LINE lets you +have footnotes which are identified by line number, rather than by a +marker in the text. (Note that +NUMBER_LINES +must be enabled in order to use this marker style.) +

+ +

+With FOOTNOTE_MARKER_STYLE LINE, mom will identify +footnotes either by single line numbers, or line ranges. If +what you want is a single line number, you need only invoke +.FOOTNOTE, without the terminating \c, +at the appropriate place in running text. Input lines after the +footnote has been terminated (e.g. with +.FOOTNOTE OFF) are entered normally. +

+ +

+If you want a range of line numbers (e.g. [5-11] ), +insert, directly into the first line of the range you want, the +inline escape, +\*[FN_MARK]. For the terminating line +number of the range, you need only invoke .FOOTNOTE +(again, without the terminating \c); mom is smart enough +to figure out that where .FOOTNOTE was invoked represents +the terminating line number. +

+ +

+Range-numbered footnotes are always output on the page +where .FOOTNOTE was invoked, not the page where +\*[FN_MARK] appears (subject, of course, to +the rules for footnotes that fall too close to the bottom of a page, +as outlined +here). +

+ +

+The behaviour of line-numbered footnotes can be controlled with the +macros: +
+FOOTNOTE_LINENUMBER_BRACKETS +
+FOOTNOTE_LINENUMBER_SEPARATOR +
+FOOTNOTES_RUN_ON +

+ +
+
• FOOTNOTE_LINENUMBER_BRACKETS
+ +

+Mom, by default, surrounds footnote line numbers with square +brackets. The style of the brackets may be changed with the macro +
+ + .FOOTNOTE_LINENUMBER_BRACKETS + +which takes one of three possible arguments: PARENS +(round brackets), SQUARE (the default) or +BRACES (curly braces). If you prefer a shortform, the +arguments, (, [ or { may be used +instead. +

+ +

Thus, for example, either +
+ + .FOOTNOTE_LINENUMBER_BRACKETS PARENS + +or +
+ + .FOOTNOTE_LINENUMBER_BRACKETS ( + +will surround footnote line numbers with round brackets. +

+ +
• FOOTNOTE_LINENUMBER_SEPARATOR
+ +

+If you don’t want the numbers enclosed in brackets, you +may tell mom to use a “separator” instead. A common +separator would be the colon, but it can be anything you like. +The macro to do this is +
+ + .FOOTNOTE_LINENUMBER_SEPARATOR + +which takes, as its single argument, the separator you want. For +safety and consistency’s sake, always enclose the argument in +double-quotes. The separator can be composed of any valid groff +character, or any combination of characters. +

+ +

+A word of caution: when using a separator, mom doesn’t +insert any space after the separator. Hence, if you want space +(you probably do), you must make the space part of the argument you +pass to FOOTNOTE_LINENUMBER_SEPARATOR. For example, to get a colon +separator with a space after it, you’d do +
+ + .FOOTNOTE_LINENUMBER_SEPARATOR ": " + +

+ +
• FOOTNOTES_RUN_ON
+ +

+Finally, if your footnote marker style is LINE, you may +instruct mom to do “run-on style” footnotes. Run-on +footnotes do not treat footnotes as discrete entities, i.e. each +beginning on a new line. Rather, each footnote is separated from +the footnote before it by horizontal space in the running line, so +that the footnotes on any given page form a continuous block, like +lines in a paragraph. +

+ +

+The macro to get mom to run footnotes on is +
+ + .FOOTNOTES_RUN_ON + +Invoked by itself, it turns the feature on. Invoked with any other +argument (OFF, NO, etc.), it turns the feature off. +It is generally not a good idea to turn the feature on and off +during the course of a single document. If you do, mom will issue +a warning if there’s going to be a problem. However, it is +always perfectly safe to enable/disable the feature after +COLLATE. +

+
+ +

5. Reset footnote number – RESET_FOOTNOTE_NUMBER

+ +

+.RESET_FOOTNOTE_NUMBER, by itself, resets footnote +numbering so that the next footnote you enter is numbered 1. +

+ +

+.RESET_FOOTNOTE_NUMBER PAGE tells mom to start every +page’s footnote numbering at 1. +

+ +

6. Inter-footnote spacing – FOOTNOTE_SPACING

+ +

+If you’d like some space between footnotes, you can +have mom put it in for you by invoking .FOOTNOTE_SPACING +with an argument representing the amount of extra space you’d +like. The argument to FOOTNOTE_SPACING requires a +unit of measure. +

+ +

+In the following example, footnotes will be separated from each +other by 3 +points. +
+ + .FOOTNOTE_SPACING 3p + +

+ +
+

+Note: +If you’re using footnotes for references generated from the +refer database (see +refer.html), +correct MLA style requires a full linespace between footnotes, which +you can accomplish with .FOOTNOTE_SPACING 1v. +

+
+ +

7. Footnote rule – FOOTNOTE_RULE

+ +

+If you don’t want a footnote separator rule, toggle it +off with .FOOTNOTE_RULE OFF (or END, +QUIT, X...). Toggle it back on by invoking +.FOOTNOTE_RULE with no argument. The default is to print +the rule. +

+ +

8. Footnote rule length – FOOTNOTE_RULE_LENGTH

+ +

+If you want to change the length of the footnote separator rule, +invoke .FOOTNOTE_RULE_LENGTH with a length, like this, +
+ + .FOOTNOTE_RULE_LENGTH 1i + + +which sets the length to 1 inch. Note that a +unit of measure +is required. The default is 4 +picas +for both +PRINTSTYLEs. +

+ +

9. Footnote rule weight – FOOTNOTE_RULE_WEIGHT

+ +

+If you want to change the weight (“thickness”) of the +footnote separator rule, invoke .FOOTNOTE_RULE_WEIGHT +with the desired weight. The weight is measured in +points; +however, do not append the +unit of measure, +p, to the argument. +

+ +

+Mom’s default footnote rule weight is 1/2 point. If +you’d like a 1-point rule instead,
+ + .FOOTNOTE_RULE_WEIGHT 1 + +is how you’d get it. +

+ +

10. Adjust vertical position of footnote separator rule – FOOTNOTE_RULE_ADJ

+ +

+The footnote separator rule is a rule whose bottom edge falls +on the +baseline +(at the footnote +leading) +one line above the first line of a page’s footnotes. By default, +mom raises the rule 3 +points +from the baseline so that the separator and the footnotes don’t +look jammed together. If you’d prefer a different vertical +adjustment, invoke .FOOTNOTE_RULE_ADJ with the +amount you’d like. For example +
+ + .FOOTNOTE_RULE_ADJ 4.25p + +raises the rule by 4-1/4 points. Note that you can only raise +the rule, not lower it. A +unit of measure +is required. +

+ +
+

+Note: +If your document +leading +is 2 +points +or less (e.g your +point size +is 10 and your linespacing is 10, 11, or 12), lowering mom’s +default footnote rule adjustment will almost certainly give you +nicer looking results than leaving the adjustment at the default. +Furthermore, you can invoke .FOOTNOTE_RULE_ADJ on any +page in which footnotes appear, or in any column, so that the +placement of the footnote rule can be changed on-the-fly, should you +wish. +

+
+ +

+ + + +

Endnotes

+ + + +

+Embedding endnotes into mom documents is accomplished the same way +as embedding +footnotes. +The example below is identical to the one shown in the +introduction to footnotes, +except that .FOOTNOTE has been replaced with +.ENDNOTE. +

+ +
+
Example
+ + ...the doctrines of Identity as urged by Schelling\c + .ENDNOTE + <endnote about who the hell is Schelling> + .ENDNOTE OFF + were generally the points of discussion presenting the most + of beauty to the imaginative Morella. + +
+ +

+As with footnotes, note the obligatory use of the \c +inline escape +when your +ENDNOTE_MARKER_STYLE +is NUMBER or SUPERSCRIPT (both of which mark +endnotes references in +running text +with superscript numbers). When the marker style is +LINE, you must not use the \c +escape. +

+ +

+Endnotes differ from footnotes in two ways (other than the fact that +endnotes come at the end of a document whereas footnotes appear in +the body of the document): +

+ +
    +
  1. When your ENDNOTE_MARKER_STYLE is NUMBER or + SUPERSCRIPT, endnotes are always numbered + incrementally, starting at “1”. +
  2. +
  3. Endnotes must be output explicitly; mom does not output + them for you. In + collated + documents, this allows you to choose whether you want the + endnotes to appear at the end of each chapter or article in a + document, or grouped together at the very end of the document. +
  4. +
+ +

+Within endnotes, you may use the document element tags +PP, +QUOTE +and +BLOCKQUOTE. +This provides the flexibility to create endnotes that run to several +paragraphs, as well as to embed cited text within endnotes. +

+ +

+Should you wish to change the appearance of quotes or blockquotes +that appear within endnotes, you may do so with the +quote control macros +or +blockquote control macros. +However, you must make the changes within each endnote, +prior to invoking .QUOTE or .BLOCKQUOTE, +and undo them prior to terminating the endnote (i.e. before +.ENDNOTE OFF), otherwise the changes will affect +subsequent quotes and blockquotes that appear in the document body +as well. +

+ +
+

+Note: +See +refer.html +for information on using endnotes with the refer +bibliographic database. +

+
+ +

Endnotes behaviour

+ +

+When you output endnotes (with +.ENDNOTES), +mom finishes processing the last page of your document, then breaks +to a new page for printing the endnotes. If the document type is +CHAPTER, +the centre part of the +header +(or footer), which, by default, contains a chapter number or title, +is removed. +

+ +

+By default, mom starts the endnotes page with a bold, centred head, +“ENDNOTES”. Subsequently, for each section in a +collated +document (e.g. chapters in a book), she identifies the section in bold +type, flush left and underscored, followed by one-half linespace. +Endnotes pertaining to the section are output underneath, identified +by superscript numbers. The text of the endnotes themselves is +indented to the right of the numbers. +

+ +
+

+Note: +The one-half linespace between section identifiers and the endnotes +themselves, plus the need to group identifiers and endnotes sensibly, +means that mom cannot guarantee perfectly aligned bottom margins. +This is an unavoidable consequence of the structure of endnotes. +

+
+ +

+Of course, all the defaults, as well as the overall style of the +endnotes pages, can be changed with the +endnote control macros. +The attentive will notice that endnotes have an awful lot of control +macros. This is because endnotes are like a mini-document unto +themselves, and therefore need not be bound by the style parameters +of the body of the document. +

+ +

Endnotes and columnar documents

+ +

+If your document is set in columns (see +COLUMNS), +mom gives you the option to have endnotes appear in either +the column format or set to the full page width. See +ENDNOTES_NO_COLUMNS. +

+ + + +
+

ENDNOTE

+
+ +
+Macro: ENDNOTE <toggle> [ BREAK | BR ] +
+

+See HYPER-IMPORTANT NOTE +

+ +

+ENDNOTE is a toggle macro, therefore invoking it on a line by itself +allows you to enter an endnote in the body of a document. Invoking +it with any other argument (i.e. OFF, QUIT, +END, X...) tells mom that you’ve +finished the endnote. +

+ +
+

+Note: +If an endnote runs to more than one paragraph, do not begin +the endnote with the +PP +tag. Use PP only to introduce subsequent paragraphs. +

+
+ +
+

+HYPER-IMPORTANT NOTE: +If your +ENDNOTE_MARKER_STYLE +is NUMBER or SUPERSCRIPT (mom’s +default is NUMBER unless you have +ENDNOTE_REFS +enabled, in which case it’s SUPERSCRIPT), the final word on the +input line +that comes immediately before .ENDNOTE must terminate +with a +\c +inline escape. See the +endnote example +above. +

+ +

+Additionally, in +fill +modes +(JUSTIFY +or +QUAD, +the line after .ENDNOTE OFF should be +entered as if there were no interruption in the input text, i.e., +the line should begin with a literal space or punctuation mark (see +explanation and examples for footnotes, which apply equally to +endnotes, +here). +

+ +

+In +no-fill +modes, the optional argument BREAK or BR may +be used after the OFF (or OFF, +QUIT, END, X, etc) argument to +instruct mom not to join the next input line to the previous output. +See +here +for a more complete explanation. The examples are for +.FOOTNOTE, but apply equally to .ENDNOTE. +

+ +

+If your ENDNOTE_MARKER_STYLE is LINE, do not use the \c +escape, and enter the line after .ENDNOTE OFF normally, +ie at your text editor’s left margin. +

+
+ + + +
+

ENDNOTES

+
+ +
+Macro: ENDNOTES +
+ +

+Unlike footnotes, which mom automatically outputs at the bottom +of pages, endnotes must be explicitly output by you, the +user. ENDNOTES, by itself (i.e. without any argument), is the macro +to do this. +

+ +

+Typically, you’ll use ENDNOTES at the end of a document. If +it’s a single (i.e. not collated) document, mom will print +the endnotes pertaining to it. If it’s a collated document, +mom will print all the endnotes contained within all sections of +the document (typically chapters), appropriately identified and +numbered. +

+ +

+Should you wish to output the endnotes for each section of a +collated document at the ends of the sections (instead of at the +very end of the document), simply invoke .ENDNOTES +immediately prior to +COLLATE. +Mom will print the endnotes, identified and numbered appropriately, +on a separate page prior to starting the next section of the +document. Each subsequent invocation of .ENDNOTES +outputs only those endnotes that mom collected after the previous +invocation. +

+ +
+

ENDNOTES control macros and defaults

+ +
+

+Important: +Endnotes control macros must always be invoked prior to the first +instance of +.ENDNOTE. +

+ +

+When you embed endnotes in the body of a document, mom collects +and processes them for later outputting (when you invoke +.ENDNOTES). +By the time you do invoke .ENDNOTES, it’s much too late to +change your mind about how you want them to look. +

+ +

+My advice? If you’re planning to change the default +appearance of endnotes pages, set them up prior to +START. +

+
+ +
    +
  1. General endnotes style control +
  2. +
  3. Pagination of endnotes +
  4. +
  5. Header/footer control +
  6. +
  7. Endnotes header (first-page title) control +
  8. +
  9. Endnotes document-identification string control +
  10. +
  11. Endnotes referencing style +
  12. +
+
+ +

1. General endnotes page style control

+ +
• Base family/font/quad
+ +
+

+See +Arguments to the control macros. +
+The following ENDNOTE control macros may also be +grouped +using ENDNOTE_STYLE. +

+ +.ENDNOTE_FAMILY default = prevailing document family; default is Times Roman +.ENDNOTE_FONT default = roman +.ENDNOTE_QUAD* default = justified + +*Note: ENDNOTE_QUAD must be set to either L (LEFT) or J (JUSTIFIED); + R (RIGHT) and C (CENTER) will not work. + +
+ + + +
• Base point size
+ +
+Macro: ENDNOTE_PT_SIZE <base type size of endnotes> +
+ +

+Unlike most other control macros that deal with size of document +elements, ENDNOTE_PT_SIZE takes as its argument an absolute value, +relative to nothing. Therefore, the argument represents the size of +endnote type in +points, +unless you append an alternative +unit of measure. +For example, +
+ + .ENDNOTE_PT_SIZE 12 + +sets the base point size of type on the endnotes page to 12 +points, whereas +
+ + .ENDNOTE_PT_SIZE .6i + +sets the base point size of type on the endnotes page to 1/6 of an +inch. +

+ +

+The type size set with ENDNOTE_PT_SIZE is the size of type used for +the text of the endnotes, and forms the basis from which the point +size of other endnote page elements is calculated. +

+ +

+The default for +PRINTSTYLE TYPESET +is 12.5 points (the same default size used in the body of the +document). +

+ + + +
• Leading
+ +
+Macro: ENDNOTE_LEAD <base leading of endnotes> [ ADJUST ] +
+ +

+• Does not require a unit of measure; points is assumed +

+ +

+Unlike most other control macros that deal with leading of document +elements, ENDNOTE_LEAD takes as its argument an absolute value, +relative to nothing. Therefore, the argument represents the +leading +of endnotes in +points +unless you append an alternative +unit of measure. +For example, +
+ + .ENDNOTE_LEAD 14 + +sets the base leading of type on the endnotes page to 14 +points, whereas +
+ + .ENDNOTE_LEAD .5i + +sets the base leading of type on the endnotes page to 1/2 inch. +

+ +

+If you want the leading of endnotes adjusted to fill the page, pass +ENDNOTE_LEAD the optional argument +ADJUST. (See +DOC_LEAD_ADJUST +for an explanation of leading adjustment.) +

+ +

+The default for +PRINTSTYLE TYPESET +is the prevailing document leading (16 by default), adjusted. +

+ +
+

+Note: +Even if you give mom a .DOC_LEAD_ADJUST OFF command, she +will still, by default, adjust endnote leading. You must +enter .ENDNOTE_LEAD <lead> with no +ADJUST argument to disable this default behaviour. +

+
+ + + +
• Spacing between endnotes
+ +
+Macro: ENDNOTE_SPACING <space to insert between endnotes> +
+

+• Requires a unit of measure +

+ +

+If you’d like some whitespace between endnotes, just invoke +ENDNOTE_SPACING with the amount of space you want, e.g. +
+ + .ENDNOTE_SPACING 6p + +which inserts 6 points of lead between endnotes. Be aware, though, +that inserting space between endnotes means that the bottoms of +endnotes pages will most likely not align. +

+ +

+Mom’s default is not to insert any whitespace between endnotes. +

+ + + +
• Singlespace endnotes (TYPEWRITE only)
+ +
+Macro: SINGLESPACE_ENDNOTES <toggle> +
+ +

+If your +PRINTSTYLE +is TYPEWRITE and you use TYPEWRITE’s default +double-spacing, endnotes are double-spaced. If your document is +single-spaced, endnotes are single-spaced. +

+ +

+If, for some reason, you’d prefer that endnotes be +single-spaced in an otherwise double-spaced document (including +double-spaced +collated +documents), invoke +
+ + .SINGLESPACE_ENDNOTES + +with no argument. And if, god help you, you want to change endnote +single-spacing back to double-spacing for different spacing of +endnotes output at the ends of separate documents in a collated +document, invoke .SINGLESPACE_ENDNOTES with any argument +(OFF, QUIT, END, X...). +

+ + + +
• Paragraph indenting
+ +
+Macro: ENDNOTE_PARA_INDENT <amount to indent first line of paragraphs in endnotes> +
+ +

+• Requires a unit of measure +

+ +

+ENDNOTE_PARA_INDENT works exactly the same way as +PARA_INDENT, +except that the indent given is the amount by which to indent the +first lines of endnote paragraphs, not document body paragraphs. +

+ +

+The default is 1.5 +ems +for +PRINTSTYLE TYPESET; +1/2 inch for +PRINTSTYLE TYPEWRITE. +

+ +
+

+Note: +The first line of the first paragraph of endnotes (the one attached +immediately to the identifying endnote number) is never indented. +Only subsequent paragraphs are affected by ENDNOTE_PARA_INDENT. +

+
+ + + +
• Inter-paragraph spacing
+ +
+Macro: ENDNOTE_PARA_SPACE <toggle> +
+ +

+ENDNOTE_PARA_SPACE works exactly the same way as +PARA_SPACE, +except that it inserts a blank line between endnote paragraphs, not +document body paragraphs. +

+ +

+The default is not to insert a blank line between paragraphs in +endnotes. +

+ + + +
• Turning off column mode during endnotes output
+ +
+Macro: ENDNOTES_NO_COLUMNS <toggle> +
+ +

+By default, if your document is set in +columns, +mom sets the endnotes in columns, too. However, if your document +is set in columns and you’d like the endnotes not to be, +just invoke .ENDNOTES_NO_COLUMNS with no argument. +The endnotes pages will be set to the full page measure of your +document. +

+ +

+If you output endnotes at the end of each document in a +collated +document set in columns, column mode will automatically be +reinstated for each document, even with ENDNOTES_NO_COLUMNS turned +on. In such circumstances, you must re-enable ENDNOTES_NO_COLUMNS +for each separate collated document. +

+ +

2. Pagination of endnotes

+ + + +
• Page numbering style
+ +
+Macro: ENDNOTES_PAGENUM_STYLE DIGIT | ROMAN | roman | ALPHA | alpha +
+ +

+Use this macro to set the page numbering style of endnotes pages. +The arguments are identical to those for +PAGENUM_STYLE. +The default is digit. You may want to change it to, say, +alpha, which you would do with +
+ + .ENDNOTES_PAGENUM_STYLE alpha + +

+ + + +
• Setting the first page number of endnotes
+ +
+Macro: ENDNOTES_FIRST_PAGENUMBER <page # that appears on page 1 of endnotes> +
+ +

+Use this macro with caution. If all endnotes for several +collated +documents are to be output at once, i.e. not at the end of each +separate doc, ENDNOTES_FIRST_PAGENUMBER tells mom what page number +to put on the first page of the endnotes. +

+ +

+However, if you set ENDNOTES_FIRST_PAGENUMBER in collated documents +in which the endnotes are output after each section (chapter, +article, etc), you have to reset every section’s first page +number after +COLLATE +and before +START +with +PAGENUMBER. +

+ + + +
• Omitting a page number on the first page of endnotes
+ +
+Macro: ENDNOTES_NO_FIRST_PAGENUM <toggle> +
+ +

+This macro is for use only if +FOOTERS +are on. It tells +ENDNOTES +not to print a page number on the first endnotes page. Mom’s +default is to print the page number. +

+ + + +
• Suspending pagination during endnotes output
+ +
+Macro: SUSPEND_PAGINATION +
+ +
+Macro: RESTORE_PAGINATION +
+ +

+SUSPEND_PAGINATION doesn’t take an argument. Invoked +immediately prior to +ENDNOTES, +it turns off endnotes pages pagination. Mom continues, however to +increment page numbers silently. +

+ +

+To restore normal document pagination after endnotes, invoke +.RESTORE_PAGINATION (again, with no argument) immediately +after .ENDNOTES. +

+ +

3. Header/footer control

+ +
• Modifying what goes in the endnotes header/footer
+ +

+If you wish to modify what appears in the header/footer that appears +on endnotes page(s), make the changes before you invoke +.ENDNOTES, +not afterwards. +

+ +

+Except in the case of +DOCTYPE CHAPTER, +mom prints the same header or footer used throughout the document +on the endnotes page(s). Chapters get treated differently in that, +by default, mom does not print the header/footer centre string +(normally the chapter number or chapter title.) In most cases, this +is what you want. However, should you not want mom to remove +the centre string from the endnotes page(s) headers/footers, invoke +.ENDNOTES_HEADER_CENTER +with no argument. +

+ +

+An important change you may want to make is to put the word +“Endnotes” in the header/footer centre position. To do +so, invoke +
+ + .HEADER_CENTER "Endnotes" + +or + + .FOOTER_CENTER "Endnotes" + +prior to invoking .ENDNOTES. +

+ +
+

+Note: +If your +DOCTYPE +is CHAPTER, you must also invoke +ENDNOTES_HEADER_CENTER +for the ENDNOTES_HEADER_CENTER to appear. +

+
+ +
• Header/footer centre string when doctype is CHAPTER
+ +
+Macro: ENDNOTES_HEADER_CENTER toggle +
+ +

+If your +DOCTYPE +is CHAPTER and you want mom to include a centre +string in the headers/footers that appear on endnotes +pages, invoke .ENDNOTES_HEADER_CENTER (or +.ENDNOTES_FOOTER_CENTER) with no argument. Mom’s +default is not to print the centre string. +

+ +

+If, for some reason, having enabled the header/footer centre string +on endnotes pages, you wish to disable it, invoke the same macro +with any argument (OFF, QUIT, END, +X...).

+ +
• Allow headers on endnotes pages
+ +
+Macro: ENDNOTES_ALLOWS_HEADERS <none> | ALL +
+ +

+By default, if HEADERS are on, mom prints page headers on all +endnotes pages except the first. If you don’t want her to +print headers on endnotes pages, do +
+ + .ENDNOTES_ALLOWS_HEADERS OFF + +If you want headers on every page including the first, do +
+ + .ENDNOTES_ALLOWS_HEADERS ALL + +

+ +
+

+Note: +If FOOTERS are on, mom prints footers on every endnotes page. +This is a style convention. In mom, there is no such beast as +ENDNOTES_ALLOWS_FOOTERS OFF. +

+
+ +

4. Endnotes header (first-page title) control

+ + + +
• Header (first-page title) string
+ +
+Macro: ENDNOTES_HEADER_STRING "<title to print at the top of endnotes>" +
+ +

+Alias: ENDNOTE_STRING (for compatibility with older documents) +

+ +

+By default, mom prints the word “ENDNOTES” as a head +at the top of the first page of endnotes. If you want her to +print something else, invoke .ENDNOTES_HEADER_STRING +with the endnotes-page head you want, surrounded by double-quotes. +If you don’t want a head at the top of the first +endnotes-page, invoke .ENDNOTES_HEADER_STRING +with a blank argument (either two double-quotes side by +side—""—or no argument at all). +

+ + + +
• Header (first-page title) control macros and defaults
+ +
+

+See +Arguments to the control macros. +
+The following ENDNOTES_HEADER control macros may also be +grouped +using ENDNOTES_HEADER_STYLE. +

+ +

+Please note that “_HEADER_”, here, refers to the title +that appears at the top of the first endnotes page, not to the page +headers of subsequent endnotes pages. + +.ENDNOTES_HEADER_FAMILY default = prevailing document family +.ENDNOTES_HEADER_FONT default = bold +.ENDNOTES_HEADER_SIZE* default = +1 +.ENDNOTES_HEADER_QUAD default = centred +.ENDNOTES_HEADER_COLOR default = black + +*Relative to the size of the endnotes text (set with ENDNOTE_PT_SIZE) + +

+
+ +

+Note: For compatibility with older documents, these macros are aliased +as .ENDNOTE_STRING_<SPEC>, e.g. .ENDNOTE_STRING_FAMILY. +

+ + + +
• Header (first-page title) placement
+ +
+Macro: ENDNOTES_HEADER_V_POS <distance from top of page> +
+ +

+• Argument requires a unit of measure +

+ +

+Alias: ENDNOTE_STRING_ADVANCE (for compatibility with older documents) +

+ +

+By default, mom places the title (the docheader, as it were) of +endnotes pages (typically "ENDNOTES") on the same +baseline +that is used for the start of +running text. +If you’d prefer another location, higher or lower on the page +(thereby also raising or lowering the starting position of the +endnotes themselves), invoke .ENDNOTES_HEADER_V_POS with +an argument stating the distance from the top edge of the page at +which you’d like the title placed. +

+ +

+The argument requires a unit of measure, so if you’d like the title +to appear 1-1/2 inches from the top edge of the page, you’d tell +mom about it like this: +
+ + .ENDNOTES_HEADER_V_POS 1.5i + +

+ + + +
• Header (first-page title) underscoring
+ +
+Macro: ENDNOTES_HEADER_UNDERSCORE [DOUBLE] [<underscore weight> [<underscore gap> [<distance between double rules]]] | <none> | <anything> +
+ +

+Alias: ENDNOTES_HEADER_UNDERLINE. +(For compatibility with older documents, also +aliased as ENDNOTE_STRING_UNDERSCORE and +ENDNOTE_STRING_UNDERLINE.) +

+ +

+• The argument +<underscore weight> +must not have the +unit of measure, +p, +appended to it; all other arguments require a unit of measure +

+ +

+Invoked without an argument, .ENDNOTES_HEADER_UNDERSCORE +will place a single rule underneath the endnotes page title. Invoked +with the argument, DOUBLE, ENDNOTES_HEADER_UNDERSCORE will +double-underscore the title. Invoked with any other non-numeric +argument, (e.g. OFF, NO, X, etc.) the macro disables +underscoring of the title. +

+ +

+In addition, you can use ENDNOTES_HEADER_UNDERSCORE to control the +weight of the underscore rule(s), the gap between the title and the +underscore, and, in the case of double-underscores, the distance +between the two rules. +

+ +

+Some examples: +
+ + .ENDNOTES_HEADER_UNDERSCORE 1 + - turn underscoring on; set the rule weight to 1 point + + .ENDNOTES_HEADER_UNDERSCORE 1 3p + - turn underscoring on; set the rule weight to 1 point; set + the gap between the title and the underscore to 3 points + + .ENDNOTES_HEADER_UNDERSCORE DOUBLE .75 3p + - turn double-underscoring on; set the rule weight to 3/4 of + a point; set the gap between the title and the upper + underscore to 3 points; leave the gap between the upper + and the lower underscore at the default + + .ENDNOTES_HEADER_UNDERSCORE DOUBLE 1.5 1.5p 1.5p + - turn double-underscoring on; set the rule weight to 1-1/2 + points; set the gap between the title and the upper + underscore to 1-1/2 points; set the gap between the upper + and the lower underscore to 1-1/2 points + +Note, from the above, that in all instances, underscoring (single +or double) is enabled whenever ENDNOTES_HEADER_UNDERSCORE is used in +this way. +

+ +

+By default, mom double-underscores the title if your +PRINTSTYLE +is TYPEWRITE. +

+ + + +
• Header (first-page title) capitalization
+ +
+Macro: ENDNOTES_HEADER_CAPS toggle +
+ +

+Alias: ENDNOTE_STRING_CAPS (for compatibility with older documents) +

+ +

+Invoked by itself, .ENDNOTES_HEADER_CAPS will +automatically capitalize the endnotes-page title. Invoked with any +other argument, the macro disables automatic capitalization of the +title. +

+ +

+If you’re generating a table of contents, you may want the +endnotes pages title to be in caps, but the toc entry in caps/lower +case. If the argument to +ENDNOTES_HEADER_STRING +is in caps/lower case and ENDNOTES_HEADER_CAPS is on, this is exactly +what will happen. +

+ +

+Mom’s default is to capitalize the endnotes pages title string. +

+ + + +

5. Endnotes document-identification title control

+ +
• Document-identification title string(s)
+ +
+Macro: ENDNOTE_TITLE "<title to identify a document in endnotes>" +
+ +

+By default, mom identifies the document(s) to which endnotes belong +by the document title(s) given to the +TITLE +macro. If you’d like her to identify the document(s) another +way, simply invoke .ENDNOTE_TITLE prior to +START +with the identifying title you want, surrounded by double-quotes. +

+ +

+If you don’t want any identifying title, invoke +.ENDNOTE_TITLE with a blank argument, either two +double-quotes side by side ("") or no argument +at all. This is particularly useful if you have a single (i.e. +non-collated) document and find having the document’s title +included in the endnotes redundant. +

+ + + +
• Document-identification string control macros and defaults
+ +
+

+See +Arguments to the control macros. +
+The following ENDNOTE_TITLE_STYLE control macros may also be +grouped +using ENDNOTE_TITLE_STYLE_STYLE. +

+ +.ENDNOTE_TITLE_FAMILY default = prevailing document family; default is Times Roman +.ENDNOTE_TITLE_FONT default = bold +.ENDNOTE_TITLE_SIZE* default = 0 +.ENDNOTE_TITLE_COLOR default = black +.ENDNOTE_TITLE_QUAD default = left +.ENDNOTE_TITLE_CAPS +.ENDNOTE_TITLE_SMALLCAPS +.ENDNOTE_TITLE_UNDERSCORE default = single underscore + +*Relative to the size of the endnotes text (set with ENDNOTE_PT_SIZE) + +
+ + + +

6. Endnotes referencing style

+ +
• Endnote marker style
+ +
+Macro: ENDNOTE_MARKER_STYLE LINE | NUMBER | SUPERSCRIPT +
+ +

+• Argument: LINE +By default, mom places superscript numbers in +running text +to identify endnotes. However, if you have +linenumbering +turned on, you may instruct mom not to put superscript numbers in +the running text, but rather to reference endnotes by line number. +The command to do this is +
+ + .ENDNOTE_MARKER_STYLE LINE + +With ENDNOTE_MARKER_STYLE LINE, mom will identify +endnotes either by single line numbers or by line ranges. If +what you want is a single line number, you need only invoke +.ENDNOTE at the appropriate place in running +text without the terminating \c. Input lines +after the endnote has been terminated (e.g. with .ENDNOTE +OFF) must begin at the left margin. +

+ +

+(Should you wish to revert to mom’s default behaviour of +placing a superscript number in the text to identify an endnote, +you can invoke .ENDNOTE_MARKER_STYLE with the argument, +NUMBER. It is not advisable to switch marker styles +within a single document, for aesthetic reasons, but there is +nothing to prevent you from doing so.) +

+ +

+If you want a range of line numbers (e.g. [5-11] ), +insert, directly into the first line of the range you want, the +inline escape, +\*[EN-MARK]. For the terminating line +number of the range, you need only invoke .ENDNOTE +(again, without the terminating \c). Mom is smart enough +to figure out that where .ENDNOTE is invoked represents +the terminating line number. +

+ +
+

+Note: +By default, mom reserves a fixed amount of space, equal to 8 +placeholders, for the linenumbers of linenumbered endnotes. Within +that space, the numbers are flush right with each other. The +reserved space is enough to print a range of linenumbers of the form +[nnnn-nnnn], but may be more than you need. +

+ +

+The goal with linenumbered endnotes is to ensure that the longest +linenumber or range of lines is flush with the left margin of the +page. Adjusting the reserved space is done with the macro +ENDNOTE_NUMBERS_ALIGN, +and the rules for getting it right are simple. +

+ +

+If your document runs to less than 100 lines, invoke +
+ + .ENDNOTE_NUMBERS_ALIGN RIGHT 0 + +If your document has between 100 and 999 lines +
+ + .ENDNOTE_NUMBERS_ALIGN RIGHT 1 + +If your document has between 1000 and 9999 lines +
+ + .ENDNOTE_NUMBERS_ALIGN RIGHT 2 + +etc. +

+
+ +

+• Argument: NUMBER +With the argument NUMBER, mom places superscript numbers +in running text, but identifies endnotes in the endnotes section +of your document with normal-sized, base-aligned numbers. +

+ +

+• Argument: SUPERSCRIPT +With the argument SUPERSCRIPT, mom places superscript +numbers in running text, and identifies endnotes in the endnotes +section of your document with superscript numbers as well. This is +mom’s default. +

+ +
+

+Note: +By default, mom reserves a fixed amount of space, equal to 2 +placeholders, for the superscript numbers identifying endnotes in +the endnotes section of your document. Within that space, the +numbers are flush right with each other. +

+ +

+If you need less space (the total number of endnotes is less than 10) or +more (the total number of endnotes is greater than 99), use the +macro +ENDNOTE_NUMBERS_ALIGN, +to set the desired amount of reserved space, e.g. +
+ + .ENDNOTE_NUMBERS_ALIGN RIGHT 1 + +or +
+ + .ENDNOTE_NUMBERS_ALIGN RIGHT 3 + +

+
+ +
• Spacing between line-numbered endnotes and the endnote text
+ +
+Macro: ENDNOTE_LINENUMBER_GAP <size of gap> +
+ +

+• Requires a unit of measure +

+ +

+When your +ENDNOTE_MARKER_STYLE +is LINE, mom, by default, inserts a space equal to +1/2-en +between the linenumber and the text of an endnote. For aesthetic +reasons, you may want to change the size of the gap, which is done +with the macro ENDNOTE_LINENUMBER_GAP. +

+ +

+ENDNOTE_LINENUMBER_GAP takes as its single argument the size +of the gap. The argument requires a +unit of measure, +so, for example, to change the gap to 2 +picas, +you’d do +
+ + .ENDNOTE_LINENUMBER_GAP 2P + +

+ +
• Brackets around endnote line numbers
+ +
+Macro: ENDNOTE_LINENUMBER_BRACKETS PARENS | SQUARE | BRACES | ( | [ | { +
+ +

+By default, mom puts endnote line numbers inside square brackets. +The style of the brackets may be changed with the macro +ENDNOTE_LINENUMBER_BRACKETS, which takes one of three possible +arguments: PARENS (“round” brackets), +SQUARE (the default) or BRACES (curly braces). +If you prefer a shortform, the arguments, (, [ +or { may be used instead. +

+ +
• Separator after endnote line numbers instead of brackets
+ +
+Macro: ENDNOTE_LINENUMBER_SEPARATOR <character> +
+ +

+If you don’t want the numbers enclosed in brackets, you may tell +mom to use a separator instead. A common +separator would be the colon, but it can be anything you like. +

+ +

+ENDNOTE_LINENUMBER_SEPARATOR takes as its single argument the +separator you want. (If the argument contains spaces, don’t +forget to enclose the argument in double-quotes.) The separator +can be composed of any valid groff character, or any combination of +characters. For example, to get a colon separator after the line +number in line-numbered endnotes, you’d do +
+ + .ENDNOTE_LINENUMBER_SEPARATOR : + +

+ +
• Endnote numbering style control
+ +
+

+See +Arguments to the control macros. +

+ +

+Please note that the control macros for endnote numbering affect only +the numbers that appear on the endnotes pages themselves, not the +endnote numbers that appear in the body of a document. +

+ +Numbered endnotes +.ENDNOTE_NUMBER_FAMILY default = prevailing document family; default Times Roman +.ENDNOTE_NUMBER_FONT default = bold +.ENDNOTE_NUMBER_SIZE* default = 0 +Linenumbered endnotes +.ENDNOTE_LINENUMBER_FAMILY default = prevailing document family; default Times Roman +.ENDNOTE_LINENUMBER_FONT default = bold +.ENDNOTE_LINENUMBER_SIZE* default = 0 + +*Relative to the size of the endnotes text (set with ENDNOTE_PT_SIZE) + +
+ +
• Endnote numbering alignment
+ +

+By default, when your +ENDNOTE_MARKER_STYLE +is NUMBER, mom hangs the numbers on endnotes pages, +aligned right to two placeholders, producing this: +
+ + 9. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, + sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. + + 10. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, + sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. + +If you wish to change either the alignment or the number of +placeholders, the macro to use is ENDNOTE_NUMBERS_ALIGN. +

+ + + +
+Macro: ENDNOTE_NUMBERS_ALIGN LEFT | RIGHT <number of placeholders> +
+ +

+ENDNOTE_NUMBERS_ALIGN determines how endnote numbers are aligned. If you invoke +
+ + .ENDNOTE_NUMBERS_ALIGN RIGHT 2 + +the periods (dots) after the numbers will align, like this + + 9. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, + sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. + + 10. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, + sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. + +If you invoke + + .ENDNOTE_NUMBERS_ALIGN LEFT 2 + +the first digits of the numbers will line up flush left, like this + + 9. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, + sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. + + 10. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, + sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. + +The argument <number of placeholders> represents +the maximum size of the numbers, expressed as the number of +digits in the largest number. Numbers in the range 0-9 require +1 placeholder; in the range 10-99, 2 placeholders; in the range +100-999 3 placeholders, and so on. +

+ +

+Therefore, if you have fewer than ten endnotes, +
+ + .ENDNOTE_NUMBERS_ALIGN RIGHT 1 + +would ensure proper right alignment of endnote numbers. +

+ +

+Mom’s default for endnote number alignment is to align the +numbers right to two placeholders. +

+ +
+

+Note: +ENDNOTE_NUMBERS_ALIGN can also be used to establish the alignment +and number of placeholders when your +ENDNOTE_MARKER_STYLE +is SUPERSCRIPT. Furthermore, it can be used to establish +the number of placeholders to reserve when your ENDNOTE_MARKER_STYLE +is LINE, even though, in such an instance, the numbers +themselves are always aligned right. See +here +for examples. +

+
+ +

+ + + +

Margin notes

+ + + +

+Margin notes are short annotations that appear in either the left +or right margin of a document. Sometimes they comment on the text. +Sometimes they assist in following the “flow” of a +document by summarizing the subject of a portion of text. Sometimes +they’re comments to yourself in a draft copy. +

+ +

+The margin notes macros and routines in om.tmac (mom) are +“mommified” versions of the margin notes macros and +routines written by Werner Lemberg and patched by Gaius Mulley. +

+ +

Margin notes behaviour

+ +

+First things first: before you enter your first margin note, you +must “initialize” margin notes with +MN_INIT. +MN_INIT sets up the style parameters for margin notes, including +things like +font, +family +and +leading. +MN_INIT may be called before or after +START. +

+ +

+After initializing margin notes, you create margin notes with the +MN +macro. Based on the argument you pass MN, your margin note will go +in either the left or the right margin. +

+ +

+Margin notes are tricky from a typographic standpoint with respect +to vertical placement. Since the leading of margin notes may differ +from that of +running text, +it’s impossible for mom to guess whether to align +the first lines of margin notes with a document +baseline, +whether to align the last lines of margin notes with a document +baseline, or whether to centre them, vertically, so that neither +first nor last line aligns with anything! +

+ +

+Given this difficulty, mom always aligns the first line of any +margin note with a document baseline. If you want a different +behaviour, you must adjust the position(s) of margin notes yourself, +on a note by note basis. (See +Adjusting the vertical position of margin notes.) +

+ +

+Generally speaking, mom tries to place margin notes at the point +where you invoke +MN. +However, in the event that a margin note runs deep, she may not be +able to place a subsequent margin note exactly where you want. In +such an instance, mom will “shift” the margin note down +on the page, placing it one (margin note) linespace beneath the +previous margin note (plus whatever vertical space is required to +get the first line to line up with a baseline of running text). A +warning will be issued, letting you know this has happened, and +where. +

+ +

+Sometimes, if a margin note has to be shifted down, there simply +isn’t enough room to start the margin note on the page on +which .MN is invoked. In that case, mom ignores the +margin note entirely and issues a warning, letting you know what +she’s done, and where.

+ +

+In the event that a margin note, successfully begun on a page, runs +past your bottom margin (or the last line before footnotes begin), +the margin note will “flow” onto the next page. If +it is a “left” margin note, it will continue in the +left margin. If it is a “right” margin note, it will +continue in the right margin. +

+ +

+If your document is being set in two columns, mom will sensibly and +automatically set all margin notes pertaining to the left column in +the left margin, and all margin notes pertaining to the right column +in the right margin, regardless of the “direction” +argument you give the MN tag. If you try to use MN in documents of +more than two columns, mom will ignore all margin notes, and issue +a warning for each. +

+ +

Adjusting the vertical position of margin notes

+ +

+When the +leading +of margin notes differs from the leading used throughout a document, +you may want to adjust the vertical position of individual margin +notes. This is most often going to be the case with margin notes +that end near the bottom of the page, where you want the last line +of the margin note to line up with the last line of text on the +page. +

+ +

+Adjustments to the vertical position of margin notes must be done +inside the margin note (i.e. after .MN), at the top, +before entering text. The commands to use are +\!.ALD +(to lower the margin note) and +\!.RLD +(to raise it). + +The \! must precede the macros, or they +won’t have any effect. +

+ + + +
+

MN_INIT

+
+ +
+Macro: MN_INIT <arguments> (see list) +
+ +

Argument list:

+ + +RAGGED | SYMMETRIC +<L_WIDTH> <value> +<R_WIDTH> <value> +<GUTTER> <value> +<FONTSTYLE> <value> +<SIZE> <value> +<LEAD> <value> +<COLOR> <value> +<HY> <value> + + +

+Before you enter your first margin note, you must initialize +the style parameters associated with margin notes using MN_INIT. +If you forget to do so, mom will issue a warning and abort. +

+ +

+The arguments may be entered in any order, and since the list is +long, use of the backslash character ( \ ) to put each on +a separate line is recommended, e.g. +
+ + .MN_INIT \ + SYMMETRIC \ + L_WIDTH 4P \ + SIZE 8 \ + LEAD 9 \ + HY 14 + +All arguments are optional, but since mom requires you to run +MN_INIT before entering margin notes, you should, at a minimum, set +the RAGGED or SYMMETRIC parameter. +You will almost certainly want to set L_WIDTH, R_WIDTH, +SIZE and LEAD as well. +

+ +

RAGGED | SYMMETRIC

+ +

+If the argument RAGGED is given, both left and +right margin notes will be flush left. If the argument +SYMMETRIC is given, left margin notes will be set flush +right, and right margin notes flush left. The effect +is something like this: +
+ + A left This is a meaningless batch A right + margin note of text whose sole purpose is margin note + with just to demonstrate how the sym- with just + a few words metric argument to MN sets left a few words + in it. and right margin notes. in it. + +

+ +

+If the argument is omitted, both left and right margin notes will +be set justified. (Justified is usually not a good idea, since the +narrow measure of margin notes makes pleasing justification a near +impossibility.) +

+ +

L_WIDTH <value>

+ +

+The width of left margin notes. A +unit of measure +must be appended directly onto the argument. The default is to set +left margin notes right out to the edge of the page, which is almost +certainly not what you want, so you should give a value for this +argument if using left margin notes. +

+ +

R_WIDTH <value>

+ +

+The width of right margin notes. A +unit of measure +must be appended directly onto the argument. The default is to +set right margin notes right out to the edge of the page, which is +almost certainly not what you want, so you should give a value for +this argument if using right margin notes. +

+ +

GUTTER <value>

+ +

+The +gutter +between margin notes and +running text. +A +unit of measure +must be appended directly onto the argument. The gutter applies to +both left and right margin notes. The default is 1 +em. +

+ +

FONTSTYLE <value>

+ +

+The family+font for margin notes. Yes, that’s right: the +family plus font combo. For example, if you want Times +Roman Medium, the argument must be TR. If you want Palatino +Medium Italic, the argument must be PI. The default is the same +family+font combo used for a document’s paragraph text. +

+ +

SIZE <value>

+ +

+The point size of type for margin notes. There is no need to append a +unit of measure +to the argument; +points +is assumed (although there’s nothing preventing you from +appending an alternative unit of measure directly to the argument). +The default is for margin notes to use the same point size of type +as is used in document paragraphs. +

+ +

LEAD <value>

+ +

+The +leading +of margin notes. <LEAD> takes +points +as its unit of measure, so don’t tack a unit of measure onto +the end of the argument. The default lead is the same as paragraph +text (i.e. the document’s base leading). +

+ +

COLOR <value>

+ +

+The colour of margin notes. The colour must be pre-initialized +with +NEWCOLOR +or +XCOLOR. +The default is black. +

+ +

HY <value>

+ +

+<value> is a digit telling groff how you want margin +notes hyphenated. +
+ + 0 = do not hyphenate + 1 = hyphenate without restrictions + 2 = do not hyphenate the last word on the page + 4 = do not hyphenate the last two characters of a word + 8 = do not hyphenate the first two characters of a word + +The values can be added together, so, for example, if you want +neither the first two nor the last two characters of words +hyphenated, the hyphenation-flag would be 12. The default value is +14 (i.e. 2+4+8). +

+ + + +
+

MN

+
+ +
+Macro: MN LEFT | RIGHT +
+ +

+Once you’ve initialized margin notes with +.MN_INIT, +you can enter margin notes any time you like with .MN. +An argument of LEFT will set a left margin note. An +argument of RIGHT will set a right margin note. +

+ +

+Any argument, such as OFF (or OFF, +QUIT, END, X, etc) exits the +current margin note. +

+ +

+ + + + + +

Document termination string

+ + + +

+The use of FINIS is optional. If you invoke it at the end of a +document (before +.ENDNOTES, +.BIBLIOGRAPHY +or +.TOC) +mom deposits the word, END, centred after a blank line, +beneath the last line of the document. END is enclosed +between +em-dashes, +like this: +
+ + ...and they all lived happily ever after. + + — END — + +If there is insufficient room for FINIS on the last page of a +document, mom will alert you on stderr. +

+ +

+If you’re writing in a language other than English, you can +change what mom prints for END with the control macro +FINIS_STRING. +

+ +
+

FINIS

+
+ +
+Macro: FINIS +
+ +

+The use of FINIS is optional, but if you use it, it should be the +last macro you invoke in a document before +.ENDNOTES, +.BIBLIOGRAPHY +or +.TOC. +See +above +for a description of how FINIS behaves. +

+ +
+

+Note: +If you don’t use FINIS, and you don’t want +footers +(if they’re on) or a page number at the bottom of the last +page of a document, you have to turn them off manually, as the last +two lines of your document file, like this: +
+ + .FOOTERS OFF + .PAGINATE OFF + +

+
+ + + +

Finis control macros

+ +

+Since FINIS is only used once in a document, it has few control +macros. It is expected that you will make changes to style +parameters such as family, font, and size with +inline escapes +in the FINIS string itself (see below). +

+ +

Changing the FINIS string

+ +

+By default, FINIS prints the word, END, between +em-dashes. +If you’d like mom to print something else between the dashes, +use the FINIS_STRING macro (anywhere in the document prior to +FINIS). +

+ +

+For example, if your document’s in French, you’d do +
+ + .FINIS_STRING "FIN" + +Double-quotes must enclose the macro’s argument. +

+ +
+

+Note: +If you pass FINIS_STRING a blank string, +
+ + .FINIS_STRING "" + +mom will still print the em-dashes when you invoke +.FINIS. This, in effect, produces a short, centred +horizontal rule that terminates the document. (In +PRINTSTYLE TYPEWRITE, +it’s a short, dashed line composed of four hyphens.) +

+
+ + + +

Automatic capitalization of the FINIS string

+ +

+By default, mom sets the string you pass to FINIS all-caps. +If you’d prefer that she not do so, but rather respect +the FINIS string exactly as you enter it, invoke the macro +.FINIS_STRING_CAPS with the OFF argument, like +this: +
+ + .FINIS_STRING_CAPS OFF + +OFF, above, could be anything, e.g. NO or +X. +

+ + + +

Changing the FINIS colour

+ +

+Invoking the control macro .FINIS_COLOR with a +pre-defined (or “initialized”) colour changes the colour +of both the FINIS string and the em-dashes that surround it. If you +use the +inline escape, +\*[<colourname>], +in the argument passed to FINIS, only the text will be in the +new colour; the em-dashes will be in the default document colour +(usually black). +

+ + + +

Removing the dashes around FINIS

+ +

+If you don’t want the dashes around the FINIS string, you can +remove them with +
+ + .FINIS_NO_DASHES + +

+ +

+ + + + + + + + +
Back to Table of ContentsTopNext: Graphics, floats, and preprocessor support
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/docprocessing.html b/contrib/mom/momdoc/docprocessing.html new file mode 100644 index 0000000..4d09553 --- /dev/null +++ b/contrib/mom/momdoc/docprocessing.html @@ -0,0 +1,4420 @@ + + + + + + + + + Mom -- Document Processing, Introduction and Setup + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: The document element tags
+ +

Document processing with mom

+ +

Table of contents

+ +
+ + +
+ +


+ + + +

Introduction to document processing

+ +

+Document processing with mom uses markup tags to identify document elements +such as headings, paragraphs, blockquotes, and so on. The tags are, of course, +macros, but with sensible, readable names that make them easy +to grasp and easy to remember. (And don’t forget: if you +don’t like the “official” name of a tag — +too long, cumbersome to type in, not “intuitive” enough +— you can change it with the +ALIAS +macro.) +

+ +

+In addition to the tags themselves, mom has an extensive array of +macros that control how they look and behave. +

+ +

+Setting up a mom doc is a simple, four-part procedure. You +begin by entering metadata about the document itself (title, +subtitle, author, etc.). Next, you tell mom what kind of document +you’re creating (e.g. a chapter, letter, abstract, etc...) and +what kind of output you want (typeset, typewritten, draft-style, +etc) — essentially, templates. Thirdly, you make as many +or as few changes to the templates as you wish; in other words, +create a style sheet. Lastly, you invoke the +START +macro. VoilĂ ! You’re ready to write. +

+ + + +

Document defaults

+ +

+As is to be expected, mom has defaults for everything. If you want +to know a particular default, read about it in the description of +the pertinent tag. +

+ +

+I fear the following may not be adequately covered elsewhere in the +documentation, so just in case: +

+
    +
  • the paper size is 8.5x11 inches
  • +
  • the left and right margins are 1-inch
  • +
  • the top and bottom margins for document text are plus/minus + visually 1-inch +
  • +
  • pages are numbered; the number appears centred, at the + bottom, surrounded by hyphens (e.g. -6- ) +
  • +
  • the first page of a document begins with a + document header +
  • +
  • subsequent pages have + page headers + with a rule underneath +
  • +
+ + + +

Vertical whitespace management

+ + + + +

+Mom takes evenly-aligned bottom margins in +running text +very seriously. Only under a very few, exceptional circumstances +will she allow a bottom margin to “hang” (i.e. to fall +short). +

+ +

+Mom offers two modes of operation for ensuring flush bottom margins: +shimming and flex-spacing. Shimming means that mom nudges the +next line after a significant break in running text back onto the +baseline grid +(e.g. after the insertion of a graphic). Flex-spacing means that any +vertical whitespace remaining between the end of running text and +the bottom margin is distributed equally at logical points on the +page. +

+ +

+Mom uses the +leading +of running text (the “document leading”) that’s in effect +at the start of running text on each page +to establish the grid and space document elements such as heads or +blockquotes so that they adhere to it. (Prior to invoking +START, +the document leading is set with the +typesetting macro +LS, +afterwards with the +document control macro +DOC_LEAD.) +

+ +

+What this means is that documents whose paragraphs are not separated +by whitespace and which do not contain graphics or +pre-processor material +will fill the page completely to the bottom margin. +However, if your paragraphs are spaced, or if there are any leading +changes on a page, or if graphics or pre-processor material are +inserted, it’s very likely the bottom margins will hang +unless shimming or flex-spacing is enabled. +

+ +

Shimming vs. flex-spacing

+ +

+Shimming is mom’s default mode of operation. She applies it +automatically before headings, around quotes and blockquotes, and +beneath +floats +and +pre-processor material. +In addition, the +SHIM +macro can be inserted into a document at any point to make sure +the text following falls on the baseline grid. +

+ +

+This mode of operation works well in documents whose paragraphs are +not spaced. Deviations from the baseline grid, usually +caused by floats or pre-processor material, are corrected +immediately. If the shimming results in slightly unbalanced +whitespace around them, it can easily be remedied by passing the +ADJUST argument to the appropriate macro. +

+ +

+If you do not want mom shimming automatically, +NO_SHIM +turns shimming off globally and suppresses the SHIM macro. If you +want to disable shimming only for a particular float or +pre-processor, the NO_SHIM argument may be given to the +appropriate macro. +

+ +

+Flex-spacing kicks in automatically whenever you turn shimming +off. In other words, if you want a document flex-spaced, +.NO_SHIM is how you achieve it. If, in addition to not +shimming, you don’t want mom flex-spacing either, +NO_FLEX +lets you disable it, too. +

+ +

+Flex-spacing differs from shimming in that mom doesn’t +correct deviations from the baseline grid. Rather, she distributes +whitespace left at the bottom of the page equally in appropriate +places. Like shimming, flex-spacing is automatically applied +before heads, after floats and pre-processor material, and around +quotes and blockquotes. Like shimming, flex-spacing can be +disabled for individual floats or pre-processor material with the +NO_FLEX flag. +

+ +

+In addition, you can use the +FLEX +macro to insert flex-spacing yourself into the document, which you +will almost certainly want to do if your paragraphs are spaced. +This is because paragraphs are not flex-spaced. Typographically, +the ideal for spaced paragraphs is that the space between them +remain constant. Paradoxically, the only way to achieve flush +bottom margins, or to correct excessive flex-spacing before a +heading, is by adding flex-space between the paragraphs. This +requires human judgment, and mom does not presume to decide for you. +

+ +

+Shimming and flex-spacing are mutually exclusive. If the one is +active, the other isn’t unless you have disabled both. This means +that you cannot use the FLEX macro when shimming is enabled, or the +SHIM macro when flex-spacing is enabled. Mom will issue a warning +if you do. +

+ +

+The choice of whether to use shimming or flex-spacing depends on +whether or not your paragraphs are spaced. In a document with +indented, non-spaced paragraphs, shimming and flex-spacing produce +nearly the same result, with shimming winning by an aesthetic hair. +In documents with spaced paragraphs, flex-spacing is the only way to +achieve flush bottom margins. +

+ + + +
+

SHIM

+
+ +
+Macro: SHIM +
+ +

+When shimming is enabled, which it is by default, the SHIM macro +allows you to nudge the line following it back onto the baseline +grid. In documents with non-spaced paragraphs, this prevents +the bottom margins from hanging. +

+ +

+Mom herself automatically applies shimming +

+
    +
  • before headings
  • +
  • around quotes and blockquotes
  • +
  • after PDF images, tables, pic diagrams, equations, and floats
  • +
+ +

+You may sometimes find the amount of space generated by +SHIM looks too big, whether inserted manually into a +document or as a result of automatic shimming. +The situation occurs when the amount of shimming applied +comes close to the leading currently in effect, making it seem as if +there’s one linespace too much whitespace. +

+ +

+The solution is simply to add .SPACE -1v or +.RLD 1v to the document immediately after +.SHIM. (Both .SPACE -1v and +.RLD 1v back up by one linespace.) +

+ +
+

NO_SHIM

+
+ +
+Macro: NO_SHIM <none> | <anything> +
+ +

+NO_SHIM, without an argument, disables automatic shimming, +suppresses the SHIM macro, and enables flex-spacing. +

+ +

+NO_SHIM with any argument (e.g. OFF, QUIT, +END, X, etc) re-enables shimming if it has +been disabled and disables flex-spacing. +

+ + + +
+

FLEX

+
+ +
+Macro: FLEX [ FORCE ] +
+ +

+When flex-spacing is enabled, the FLEX macro inserts flexible +vertical whitespace into a document. The amount of flex-space is +determined from any extra whitespace at the bottom of a page divided +by the number of flex points on the same page. +

+ +

+If flex-spacing is enabled, mom herself automatically applies +flex-spacing +

+
    +
  • before headings
  • +
  • around quotes and blockquotes
  • +
  • after PDF images, tables, pic diagrams, equations, and floats
  • +
+ +

+Near the bottom of some pages, you may find that +floated +or +pre-processor material, +including images, or a single line of text afterwards, is not flush +with the bottom margin. This is a result of mom flex-spacing +after such material but not before. The solution to is +insert .FLEX immediately beforehand. +

+ +

+There are some instances where mom inhibits flex-spacing, notably +after outputting floated material deferred from one page to the +next. Introducing FLEX by itself in these instances—say, +before a head or paragraph—will not have any effect; you must +pass FLEX the FORCE argument. +

+ +
+

+Important note on flex-spacing policy:
+Mom disables flex-spacing on +

+
    +
  • the last page or column of a document, before the Table of Contents, + Endnotes, Bibliography, and/or any “Lists of...” +
  • +
  • the page preceding a + COLLATE +
  • +
  • the page preceding a + NEWPAGE + or + BLANKPAGE +
  • +
  • the column preceding a + COL_NEXT + or + COL_BREAK +
  • +
+ +

+If this is not what you want, insert +.NO_FLEX OFF +before the first flex-space point on the affected page or in the +affected column. +

+ +

+Flex-spacing is also disabled for any page or column where +insufficient room at or near the bottom causes a +HEADING +or +table +to be moved to the top of the next page. These situations cannot +be harmonized with flex-spacing except by adjusting your layout +to prevent them. You may try re-enabling flex-spacing for the +page (.NO_FLEX OFF) and manually inserting +flex-spaces at appropriate points, but the original whitespace is +usually large enough that re-distributing it merely changes +one layout gaffe into another. +

+ +

+Very occasionally you may notice that a document element (spaced +paragraph, floated material, pre-processor material, or a PDF image) +near the bottom of page has also caused mom to disable flex-spacing +for that page. This occurs when the document element following it +is a +spaced paragraph. +

+ +

+It is typographically acceptable for there to be space between +insertions in running text (e.g. an image) and the bottom margin when +the next page begins with a paragraph. If you’d like to +nudge the insertion a little closer to the bottom margin—not +all the way; that isn’t possible without pushing it to the +next page and disrupting subsequent flex-spacing—insert a +small amount of space beforehand with +SP. +Do not, in these cases, use the ADJUST +argument (for example to +PDF_IMAGE.) +

+ +

+In the case of a spaced paragraph itself near the bottom of the page +causing a break, re-enabling flex-spacing +(.NO_FLEX OFF) at an appropriate place in your input +file will resolve the issue, provided there is at least one +flex-point on the page. If not, add one or more. +

+
+ +
+

NO_FLEX

+
+ +
+Macro: NO_FLEX <none> | <anything> +
+ +

+NO_FLEX, without an argument, disables automatic flex-spacing +and suppresses the FLEX macro. If, in addition to NO_FLEX, NO_SHIM +has also been given, your document will be neither flex-spaced nor +shimmed. +

+ +

+NO_FLEX with any argument (e.g. OFF, QUIT, +END, X, etc) re-enables flex-spacing if it has +been disabled. +

+ +

+ + + +

Preliminary document setup

+ +
+

Tutorial – Setting up a mom document

+ +

+There are four parts to setting up a mom doc (three, actually, +with one optional). Before we proceed, though, be reassured that +something as simple as +
+ + .TITLE "By the Shores of Lake Attica" + .AUTHOR "Rosemary Winspeare" + .PRINTSTYLE TYPESET + .START + +produces a beautifully typeset 8.5x11 document, with a +docheader +at the top of page 1, +page headers +with the title and author on subsequent pages, and page numbers at +the bottom of each page. In the course of the document, headings, +citations, quotes, epigraphs, and so on, all come out looking neat, +trim, and professional. +

+ +

+For the purposes of this tutorial, we’re going to set up +a short story—My Pulitzer Winner—by Joe Blow. +Thankfully, we don’t have to look at story itself, just the +setup. Joe wants the document +

+
    +
  • to be draft 7, revision 39;
  • +
  • to use the DEFAULT template;
  • +
  • to print as draft-style output (instead of final-copy output);
  • +
  • to be typeset, in Helvetica, 12 on 14, + rag-right; +
  • +
  • to have footers + instead of + headers; +
  • +
  • to use a single asterisk for + author linebreaks. +
  • +
+ +

+Joe Blow has no taste in typography. His draft won’t look +pretty, but this is, after all, a tutorial; we’re after +examples, not beauty. +

+ +

Step 1

+ +

+The first step in setting up any document is giving mom some +reference information (metadata). The reference macros are: +

+
+
    +
  • TITLE
  • +
  • SUBTITLE
  • +
  • AUTHOR
  • +
  • CHAPTER – chapter number
  • +
  • CHAPTER_TITLE
  • +
  • DRAFT – draft number
  • +
  • REVISION – revision number
  • +
+
+
+
    +
  • COPYRIGHT – only used on cover pages
  • +
  • MISC – only used on cover pages
  • +
  • DOCTITLE
  • +
  • COVERTITLE
  • +
  • DOC_COVERTITLE
  • +
  • PDF_TITLE
  • +
+
+ +

+You can use as many or as few as you wish, although at a minimum, +you’ll probably fill in TITLE (unless the document’s a +letter) and AUTHOR. Order doesn’t matter. You can separate +the +arguments +from the macros by any number of spaces. The following are what +you’d need to start Joe Blow’s story. +
+ + .TITLE "My Pulitzer Winner" + .AUTHOR "Joe Blow" + .DRAFT 7 + .REVISION 39 + +

+ +

Step 2

+ +

+Once you’ve given mom the reference information she needs, you +tell her how you want your document formatted. What kind of +document is it? Should it be typeset or typewritten? Is this a +final copy (for the world to see) or just a draft? Mom calls +the macros that answer these questions “the docstyle +macros”, and they’re essentially templates. +

+
    +
  • PRINTSTYLE—typeset or typewritten
  • +
  • DOCTYPE—the type of document (default, chapter, user-defined, letter, slide)
  • +
  • COPYSTYLE—draft or final copy
  • +
+ +

+Mom has defaults for DOCTYPE and COPYSTYLE; if they’re what +you want, you don’t need to include them. However, +PRINTSTYLE has no default and must be present in every formatted +document. If you omit it, mom won’t process the document +AND she’ll complain (both to stderr and as a single printed +sheet with a warning). Moms—they can be so annoying +sometimes. <sigh> +

+ +

+Adding to what we already have, the next bit of setup for Joe +Blow’s story looks like this: +
+ + .TITLE "My Pulitzer Winner" + .AUTHOR "Joe Blow" + .DRAFT 7 + .REVISION 39 + \# + .DOCTYPE DEFAULT \"Superfluous; mom uses DOCTYPE DEFAULT by default + .PRINTSTYLE TYPESET + .COPYSTYLE DRAFT + +Notice the use of the +comment line +( \# ), a handy way to keep groups of macros visually +separated for easy reading in a text editor. +

+ +

Step 3

+ +

+This step—completely optional—is where you, the user, +take charge. Mom has reasonable defaults for every document element +and tag, but who’s ever satisfied with defaults? Use any of +the +typesetting macros +here to change mom’s document defaults (paper size, margins, +family, point size, line space, rag, etc), or any of the document +processing +control macros. +This is the stylesheet section of a document, and +must come after the +PRINTSTYLE +directive. Failure to observe this condition will result in +PRINTSTYLE overriding your changes. +

+ +

+Joe Blow wants his story printed in Helvetica, 12 on 14, rag right, +with +page footers +instead of +page headers +and a single asterisk for the +linebreak +character. None of these requirements conforms to mom’s +defaults for the chosen PRINTSTYLE (TYPESET), so we change them +here. The setup for Joe Blow’s story now looks like this: +
+ + .TITLE "My Pulitzer Winner" + .AUTHOR "Joe Blow" + .DRAFT 7 + .REVISION 39 + \# + .DOCTYPE DEFAULT + .PRINTSTYLE TYPESET + .COPYSTYLE DRAFT + \# + .FAMILY H + .PT_SIZE 12 + .LS 14 + .QUAD LEFT \"ie rag right + .FOOTERS + .LINEBREAK_CHAR * + +

+ +

Step 4

+ +

+The final step in setting up a document is telling mom to start +document processing. It’s a no-brainer, just the single +macro START. Other than PRINTSTYLE, it’s the only macro +required for document processing. +

+ +

+Here’s the complete setup for My Pulitzer Winner: +
+ + .TITLE "My Pulitzer Winner" + .AUTHOR "Joe Blow" + .DRAFT 7 + .REVISION 39 + \# + .DOCTYPE DEFAULT + .PRINTSTYLE TYPESET + .COPYSTYLE DRAFT + \# + .FAMILY H + .PT_SIZE 12 + .LS 14 + .QUAD LEFT \"ie rag right + .FOOTERS + .LINEBREAK_CHAR * + \# + .START + +As pointed out earlier, Joe Blow is no typographer. Given that all he +needs is a printed draft of his work, a simpler setup would have been: +
+ + .TITLE "My Pulitzer Winner" + .AUTHOR "Joe Blow" + .DRAFT 7 + .REVISION 39 + \# + .PRINTSTYLE TYPEWRITE + .COPYSTYLE DRAFT + \# + .START + +.PRINTSTYLE TYPEWRITE, above, means that Joe’s +work will come out “typewritten, double-spaced”, +making the blue-pencilling he (or someone else) is sure to do much +easier (which is why many publishers and agents still insist on +typewritten, double-spaced copy). +

+ +

+When J. Blow stops re-writing and decides to print off a final, +typeset copy of his work for the world to see, he need only make two +changes to the (simplified) setup: +
+ + .TITLE "My Pulitzer Winner" + .AUTHOR "Joe Blow" + .DRAFT 7 + .REVISION 39 + \# + .PRINTSTYLE TYPESET \"first change + .COPYSTYLE FINAL \"second change + \# + .START + +In the above, .DRAFT 7, .REVISION 39, and +.COPYSTYLE FINAL are actually superfluous. The draft +and revision numbers aren’t used when COPYSTYLE is FINAL, +and COPYSTYLE FINAL is mom’s default unless you tell +her otherwise. +

+ +

+But... to judge from the number of drafts already, +J. Blow may very well decide his “final” version still +isn’t up to snuff. Hence, he might as well leave in the +superfluous macros. That way, when draft 7, rev. 62 becomes draft +8, rev. 1, he’ll be ready to tackle his Pulitzer winner again. +

+
+ +

+ + + +

The reference macros (metadata)

+ +

+The reference macros give mom the metadata she needs to generate +docheaders, +page headers, +and +covers. +They must go at the top of any file that uses mom’s document +processing macros. +

+ +
+

Reference macros

+ + +
+ + + +
+

TITLE

+
+ +
+Macro: TITLE [COVER | DOC_COVER] "<title string>" ["<2nd line>" ["<3rd line>" ... ] ] +
+

+• Arguments must be enclosed in double-quotes +

+ +

+The title string can be caps or caps/lower-case; it’s up to you. In +PRINTSTYLE TYPESET, +the title will appear in the +docheader +exactly as you typed it. However, mom converts the title to all +caps in +page headers +unless you turn that feature off (see +HEADER_<POSITION>_CAPS). +In +PRINTSTYLE TYPEWRITE, +the title always gets converted to caps. +

+ +

+TITLE accepts multiple arguments, each surrounded by double-quotes. +Each argument is printed on a separate line, permitting you to +create multi-line titles in your docheaders. +

+ +
+

+Note: +If your DOCTYPE is CHAPTER, TITLE +should be the title of the opus, not “CHAPTER whatever”. +

+
+ +

+If the optional argument, COVER or DOC_COVER, +is given to TITLE, the remaining string arguments represent the +title that will appear on cover or document cover pages (see the +Introduction to cover pages +for a description of the difference between “document +covers” and “covers”). Thus, it is possible +to have differing titles appear on the document cover, the cover +(“title”) page, and in the document header. For +example, +
+ + .TITLE DOC_COVER "Collected Essays" + .TITLE COVER "The Meming of Meaning" + .TITLE "LOL Cat Corruption" + .AUTHOR "D. Rawkins" + .DOC_COVER TITLE AUTHOR + .COVER TITLE + .START + +creates a document cover with “Collected Essays” and the +author, a cover page with “The Meming of Meaning”, +and a docheader title, “LOL Cat Corruption” at the top +of the essay. +

+ +

+Alternatively, you can use the macros +DOC_COVERTITLE +and +COVERTITLE +to accomplish the same thing. +

+ +

Table of Contents exceptions

+

+Except for standalone documents (i.e. non-collated documents such +as essays), the TITLE string appears as an entry in the Table of +Contents. If you would like a document section not to appear in the +Table of Contents (e.g. the copyright page), invoke the macro +.NO_TOC_ENTRY after .TITLE. +

+ + + + +
+

DOCUMENT TITLE

+
+ +
+Macro: DOCTITLE "<overall document title>" ["<2nd line>" ["<3rd line>" ... ] ] +
+

+• Arguments must be enclosed in double-quotes +

+ +
+

+Note: +This macro should be used only if your DOCTYPE is DEFAULT (which is +mom’s default). If your DOCTYPE is CHAPTER, use +TITLE +to set the overall document title for cover pages, document cover +pages, and page headers or footers. +

+
+ +

+When you’re creating a single document, say, an essay or a +short story, you have no need of this macro. +TITLE +takes care of all your title needs. +

+ +

+However if you’re +collating +a bunch of documents together, say, to print out a report containing +many articles with different titles, or a book of short stories with +different authors, you need DOCTITLE. +

+ +

+DOCTITLE tells mom the title of the complete document (as opposed to +the title of each article or entitled section), and appears +

+ +
    +
  1. as the window title in PDF viewers (e.g. Okular or Evince)
  2. +
  3. in the initial rightmost position of page headers in the document
  4. +
+ +

+Moreover, DOCTITLE does not appear in the +PDF outline, +as its presence in window title would make it redundant. +

+ +

+The doctitle string can be caps or caps/lower-case; it’s up to +you. In +PRINTSTYLE TYPESET, +by default, the doctitle in +page headers +is all in caps, unless you turn that feature off (see +HEADER_<POSITION>_CAPS). +In +PRINTSTYLE TYPEWRITE, +the doctitle always gets converted to caps. +

+ +

+DOCTITLE accepts multiple arguments, each surrounded +by double-quotes. Each argument is printed on a separate line, +permitting you to create multi-line document titles for use on +Covers +and/or +Doc covers. +

+ + + +
+

SUBTITLE

+
+ +
+Macro: SUBTITLE [COVER | DOC_COVER] "<subtitle>" ["<2nd line>" ["<3rd line>" ... ] ] +
+

+• String arguments must be enclosed in double-quotes +

+ +

+The subtitle string can be caps or caps/lower-case. I recommend +caps/lower case. +

+ +

+SUBTITLE accepts multiple arguments, each surrounded +by double-quotes. Each argument is printed on a separate line, +permitting you to create multi-line subtitles. +

+ +

+If the optional argument, COVER or DOC_COVER, +is given to SUBTITLE, the remaining string +arguments represent the subtitle that will appear on cover or +document cover pages (see the +Introduction to cover pages +for a description of the difference between “document +covers” and “covers”). Thus, it is possible to have +differing subtitles appear on the document cover, the cover +(“title”) page, and in the document header. An extreme +example would be: +
+ + .SUBTITLE "The Docheader Subtitle" + .SUBTITLE DOC_COVER "The Document Cover Subtitle" + .SUBTITLE COVER "The Cover Subtitle" + +The first invocation of .SUBTITLE establishes the +subtitle that appears in the docheader at the top of the first page +of a document. The second invocation establishes the subtitle that +appears on the document cover; the third establishes the subtitle +that appears on the cover (“title”) page. +

+ +

+If you don’t require differing subtitles for doc cover and cover +pages, .SUBTITLE, without the optional first argument, is +sufficient, provided you give the word, SUBTITLE, as an +argument to the macro +DOC_COVER +or +COVER +

+ + + +
+

AUTHOR

+
+ +
+Macro: AUTHOR [COVER | DOC_COVER] "<author>" [ "<author2>" ["<author3>" ... ] ] +
+ +

+Alias: EDITOR +

+

+• String arguments must be enclosed in double-quotes +

+ +

+Each author string can hold as many names as you like, e.g. +
+ + .AUTHOR "Joe Blow" + +or +
+ + .AUTHOR "Joe Blow, Jane Doe" "John Hancock" + +Mom prints each string that’s enclosed in double-quotes on a +separate line in the +docheader, +however only the first string appears in +page headers. +If you want mom to put something else in the author part of page +headers (say, just the last names of a document’s two +authors), redefine the appropriate part of the header (see +header/footer control). +

+ +

+The strings can be caps or caps/lower-case. I recommend caps/lower +case. +

+ +

+If the optional argument, COVER or DOC_COVER, +is given to AUTHOR, the remaining string arguments represent the +author(s) that will appear on cover or document cover pages (see the +Introduction to cover pages +for a description of the difference between “document +covers” and “covers”). Thus, it is possible +to have differing authors on the document cover, the cover +(“title”) page, in the document first-page header and +subsequent page headers/footers. An example might be: +
+ + .AUTHOR "Joe Blow" + .EDITOR DOC_COVER "John Smith" "and" "Jane Doe" \" EDITOR is an alias for AUTHOR + .AUTHOR COVER "Joe Blow" "(assisted by Jane Doe)" + +The first invocation of .AUTHOR establishes the author +that appears in the docheader at the top of the first page of +a document and in subsequent page headers/footers. The second +invocation establishes the authors (editors, in this instance) that +appear on the document cover; the third establishes the author(s) +that appear(s) on the cover (“title”) page. +

+ +

+If you don’t require differing authors for doc cover and cover +pages, .AUTHOR, without the optional first argument, is +sufficient, provided you give the word, AUTHOR as an +argument to the macro +DOC_COVER +or +COVER +

+ + + +
+

CHAPTER

+
+ +
+Macro: CHAPTER <chapter number> +
+ +

+The chapter number can be in any form you like—a digit, a roman +numeral, a word. If you choose +DOCTYPE CHAPTER, +mom prints whatever argument you pass CHAPTER beside the word, +“Chapter”, as a single line +docheader. +She also puts the same thing in the middle of +page headers. +

+ +

+Please note that if your argument to CHAPTER runs to more than one +word, you must enclose the argument in double-quotes. +

+ +

+If you’re not using DOCTYPE CHAPTER, the macro can +be used to identify any document as a chapter for the purpose of +prepending a chapter number to numbered head elements, provided +you pass it a +numeric argument. +See +PREFIX_CHAPTER_NUMBER. +

+ + + +

Chapter string

+ +

+If you’re not writing in English, you can ask mom to use the +word for “chapter” in your own language by telling her +what it is with the CHAPTER_STRING macro, like this: +
+ + .CHAPTER_STRING "ChapĂŽtre" + +

+ +

+If you would like a blank chapter string, i.e., you’d like the +chapter number to appear without “Chapter” beforehand, +enter .CHAPTER_STRING "\&". +

+ + + +
+

CHAPTER_TITLE

+
+ +
+Macro: CHAPTER_TITLE "<chapter title>" ["<2nd line>" ["<3rd line>" ... ] ] +
+

+• Arguments must be enclosed in double-quotes +

+ +

+If, either in addition to or instead of “Chapter +<n>” appearing at the top of chapters, you want your +chapter to have a title, use CHAPTER_TITLE, with your title enclosed +in double-quotes, like this: +
+ + .CHAPTER_TITLE "The DMCA Nazis" + +

+ +

+CHAPTER_TITLE accepts multiple arguments, each surrounded by +double-quotes. Each argument is printed on a separate line, +permitting you to create multi-line chapter titles in your +docheaders. +

+ +

+If you’ve used +CHAPTER +to give the chapter a number, both “Chapter <n>” +and the chapter title will appear at the top of the chapter, like +this: +
+ + Chapter 1 + The DMCA Nazis + +In such a case, by default, only the chapter’s title will appear in +the +page headers, +not “Chapter <n>”. +

+ +

+If you omit CHAPTER when setting up your reference macros, only the +title will appear, both at the top of page one and in subsequent +page headers. +

+ +

+The style of the chapter title can be altered by +control macros, +e.g. CHAPTER_TITLE_FAMILY, CHAPTER_TITLE_FONT, etc. The default +family, font and point size are Times Roman, Bold Italic, 4 points +larger than +running text. +

+ + + +
+

DRAFT

+
+ +
+Macro: DRAFT <draft number> +
+ +

+DRAFT only gets used with +COPYSTYLE DRAFT. +If the COPYSTYLE is FINAL (the default), mom ignores DRAFT. DRAFT +accepts both alphabetic and numeric arguments, hence it’s +possible to do either +
+ + .DRAFT 2 + or + .DRAFT Two + +

+ +

+Mom prints the argument to .DRAFT (i.e. the draft number) +beside the word “Draft” in the middle part of +page headers. +

+ +
+

+A small word of caution: +If your argument to .DRAFT is more than one word long, +you must enclose the argument in double-quotes. +

+
+ +

+You may, if you wish, invoke .DRAFT without an +argument, in which case, no draft number will be printed beside +“Draft” in headers or footers. +

+ + + +

The draft string

+ +

+If you’re not writing in English, you can ask mom +to use the word for “draft” in your own language by +telling her what it is with the DRAFT_STRING macro, +like this: +
+ + .DRAFT_STRING "Jet" + +

+ +

+Equally, DRAFT_STRING can be used to roll your own solution to +something other than the word “Draft.” For example, you +might want “Trial run alpha-three” to appear in the +headers of a draft version. You’d accomplish this by doing +
+ + .DRAFT alpha-three + .DRAFT_STRING "Trial run" + +

+ +

+If you wanted only “Trial run” to appear, entering +.DRAFT without an argument as well as +.DRAFT_STRING "Trial run" is how you’d do it. +

+ +
+

+Note: +If you define both a blank .DRAFT and a blank +.DRAFT_STRING, mom skips the draft field in headers +entirely. If this is what you want, this is also the only way +to do it. Simply omitting invocations of .DRAFT and +.DRAFT_STRING will result in mom using her default, which +is to print “Draft <number>”. +

+
+ + + +
+

REVISION

+
+ +
+Macro: REVISION <revision number> +
+ +

+REVISION only gets used with +COPYSTYLE DRAFT. +If the COPYSTYLE is FINAL (the default), mom ignores the REVISION +macro. REVISION accepts both alphabetic and numeric arguments, hence +it’s possible to do either +
+ + .REVISION 2 + +or + + .REVISION Two + +

+ +

+Mom prints the revision number beside the shortform +“Rev.” in the middle part of +page headers. +

+ +
+

+A small word of caution: +If your argument to .REVISION is more than one word long, +you must enclose the argument in double-quotes. +

+
+ +

+You may, if you wish, invoke .REVISION without an +argument, in which case, no revision number will be printed beside +“Rev.” in headers or footers. +

+ + + +

The revision string

+ +

+If you’re not writing in English, you can ask mom +to use the word for “revision,” or a shortform +thereof, in your own language by telling her what it is with the +REVISION_STRING macro, like this: +
+ + .REVISION_STRING "RĂŠv." + +

+ +

+Additionally, you may sometimes want to make use of mom’s +COPYSTYLE DRAFT +but not actually require any draft information. For example, +you might like mom to indicate only the revision number of +your document. The way to do that is to define an empty +.DRAFT and .DRAFT_STRING in addition to +.REVISION, like this: +
+ + .DRAFT + .DRAFT_STRING + .REVISION 2 + +

+ +

+Equally, if you want to roll your own solution to what revision +information appears in headers, you could do something like this: +
+ + .DRAFT + .DRAFT_STRING + .REVISION "two-twenty-two" + .REVISION_STRING "Revision" + +

+ +

+The above, naturally, has no draft information. If you want to roll +your own .DRAFT and/or .DRAFT_STRING as well, +simply supply arguments to either or both. +

+ + + +
+ +
+ +
+Macro: COPYRIGHT [COVER | DOC_COVER] "<copyright info>" +
+ +

+• Argument must be enclosed in double-quotes +

+ +

+The required argument to COPYRIGHT is only used on cover or doc cover +pages, and then only if the argument COPYRIGHT is passed to +COVER +or +DOC_COVER. +Do not include the copyright symbol in the argument passed to +COPYRIGHT; mom puts it in for you. +

+ +

+The optional argument, COVER or DOC_COVER, +should only be used if you have both a doc cover and a cover and want +differing copyright information on each (see the +Introduction to cover pages +for a description of the difference between “document +covers” and “covers”). Thus, it is possible to +have differing copyright information on the document cover and on +the cover (“title”) page. An example might be: +
+ + .COPYRIGHT DOC_COVER "2010 John Smith and Jane Doe" + .COPYRIGHT COVER "2008 Joe Blow" + +The first invocation of .COPYRIGHT establishes the +copyright information that appears on the document cover; the second +establishes the copyright information that appears on the cover +(“title”) page. +

+ +

+If you don’t require differing copyright information for +doc cover and cover pages, .COPYRIGHT, without the +optional first argument, is sufficient, provided you give the word, +COPYRIGHT, as an argument to the macro +DOC_COVER +or +COVER +

+ +

+Style parameters for the copyright line may be +entered as individual macros or +grouped, +e.g. +
+ + .COPYRIGHT_FAMILY H + .COPYRIGHT_FONT R + .COPYRIGHT_SIZE -2 + +or +
+ + .COPYRIGHT_STYLE \ + FAMILY H \ + FONT R \ + SIZE -2 + +The vertical position of the copyright line may be raised (-) or +lowered (+) with the macro COPYRIGHT_V_ADJUST. For example, to +raise the copyright line by 3 +points, you’d do +
+ + .COPYRIGHT_V_ADJUST -3p + +Alternatively, the COPYRIGHT_STYLE macro may be used with the +argument V_ADJUST: + + .COPYRIGHT_STYLE \ + FAMILY H \ + FONT R \ + SIZE -2 \ + V_ADJUST -3p + +

+ + + +
+

MISC

+
+ +
+Macro: MISC [COVER | DOC_COVER] "<argument 1>" ["<argument 2>" "<argument 3>" ...] +
+ +

+• String arguments must be enclosed in double-quotes +

+ +

+The argument(s) passed to MISC are only used on cover or doc cover +pages, and then only if the argument MISC is passed to +COVER +or +DOC_COVER. +MISC can contain any information you like. Each argument appears on +a separate line at the bottom of the cover or doc cover page. +

+ +

+For example, if you’re submitting an essay where the prof has +requested that you include the course number, his name and the date, +you could do +
+ + .MISC "Music History 101" "Professor Hasbeen" "Dec. 24, 2010" + +and the information would appear on the essay’s cover page. +

+ +

+If the optional argument, COVER or DOC_COVER, +is given to MISC, the string arguments represent the miscellaneous +information that will appear on cover or document cover pages (see +the +Introduction to cover pages +for a description of the difference between “document +covers” and “covers”). Thus, it is possible to +have differing miscellaneous information on the document cover and +on the cover (“title”) page. An example might be: +
+ + .MISC DOC_COVER "Music History 101" "Professor Hasbeen" + .MISC COVER "Spring Term Paper" + +

+ +

+The first invocation of .MISC establishes the +miscellaneous information that appears on the document cover; the +second establishes the miscellaneous information that appears on the +cover (“title”) page. +

+ +

+If you don’t require differing miscellaneous information +for doc cover and cover pages, .MISC, without the +optional first argument, is sufficient, provided you give the word +“MISC” as an argument to the macro +DOC_COVER +or +COVER +

+ + + +
+

COVERTITLE & DOC_COVERTITLE

+
+ +
+Macro: COVERTITLE "<user defined cover page title>" ["<2nd line>" ["<3rd line>" ... ] ] +
+

+• Arguments must be enclosed in double-quotes +

+ +
+Macro: DOC_COVERTITLE "<user defined document cover page title>" ["<2nd line>" ["<3rd line>" ... ] ] +
+

+• Arguments must be enclosed in double-quotes +

+ +

+The arguments passed to COVERTITLE or DOC_COVERTITLE are only +used on cover or doc cover pages, and then only if the argument +COVERTITLE or DOC_COVERTITLE is explicitly +passed to +COVER +or +DOC_COVER. +

+ +

+COVERTITLE and DOC_COVERTITLE accept multiple arguments, each +surrounded by double-quotes. Each argument is printed on a separate +line, permitting you to create multi-line titles on your cover +and/or doc cover pages. +

+ +

+You only require COVERTITLE or DOC_COVERTITLE if they differ from +TITLE. Note that +TITLE +itself has two optional arguments that accomplish the same thing. +

+ +
+

PDF Title

+
+ +
+Macro: PDF_TITLE "<pdf viewer window title>" +
+

+• Argument must be enclosed in double-quotes +

+ +

+Except for +DOCTITLE, +mom does not, by default, provide PDF viewers with a document title. +You may set one, if you like, with PDF_TITLE. +

+ +
+

TOC heading

+
+ +
+Macro: TOC_HEADING "<single line TOC heading>" +
+

+• Argument must be enclosed in double-quotes +

+ +

+Mom generates tables of contents automatically (see +TOC). +You may sometimes want to insert a line of text into the table of +contents without it referring to a page number, for example to +identify a “Part I” and a “Part II.” +

+ +

+Placed before any instance of +START, +TOC_HEADING inserts its text into the table of contents with a +modest amount of whitespace around it to distinguish it easily +from table of contents entries. +

+ +

+The appearance of the heading may be controlled with +the macro +TOC_HEADING_STYLE. +

+ +
+Macro: TOC_HEADING_STYLE "<arguments>" +
+ +

+TOC_HEADING_STYLE controls the look of TOC headings. It is a +“grouping” +style macro with multiple arguments. It is recommended that +you use the backslash character to separate them into individual +lines rather than entering a single, very long line. +

+ +

+TOC_HEADING_STYLE accepts as many or as few arguments as you need: + + FAMILY <family> \ + FONT <font> \ + SIZE <+|-n> \ + COLOR <colorname>* \ + QUAD L | C | R \ + SPACE_ABOVE <n>** \ + SPACE_BENEATH <n>** + +  * COLOR must be pre-initialized with +NEWCOLOR +or +XCOLOR. +
+** SPACE_ABOVE and SPACE_BENEATH require a +unit of measure +to be appended to their numeric argument. +

+ +

+For example, if you want your TOC headings to be bold, slightly +larger than the rest of the table of contents, centred, and with +one linespace beforehand, + + FONT B \ + SIZE +.5 \ + QUAD C \ + SPACE_ABOVE 1v + +

+ +

+ See +Arguments to the control macros +for further information about the arguments. Note that +SPACE_ABOVE and SPACE_BENEATH are unique to +TOC_HEADING_STYLE. + +

+ +

+ + + +

The docstyle macros

+ +

+The docstyle macros tell mom what type of document you’re +writing, whether you want the output typeset or “typewritten, +double-spaced”, and whether you want a draft copy (with draft +and revision information in the headers) or a final copy. +

+ +
+

Docstyle macros

+ +
+ + + +
+

DOCTYPE

+
+ +
+Macro: DOCTYPE DEFAULT | CHAPTER | NAMED "<name>" | LETTER | SLIDES +
+ +

+The arguments DEFAULT, CHAPTER and +NAMED tell mom what to put in the +docheader +and +page headers. +LETTER and SLIDES tells her you want to write +a letter or create slides. +

+ +

+Mom’s default DOCTYPE is DEFAULT. If that’s +what you want, you don’t have to give a DOCTYPE command. +

+ +

+DEFAULT prints a +docheader +containing the title, subtitle and author information given to the +reference macros, +and page headers with the author and title. (See +Default specs for headers +for how mom outputs each part of the page header.) +

+ +

+CHAPTER prints “Chapter <n>” in place +of a +docheader +(<n> is what you gave to the +reference macro, +CHAPTER). +If you give the chapter a title with +CHAPTER_TITLE, +mom prints “Chapter <n>” and the +title underneath. If you omit the +CHAPTER +reference macro but supply a +CHAPTER_TITLE, +mom prints only the chapter title. +

+ +

+The page headers in DOCTYPE CHAPTER contain the author, +the title of the book (which you gave with +TITLE), +and “Chapter <n>” (or the chapter title). See +Default Specs for Headers +for mom’s default type parameters for each part of +the page header. +

+ +

+NAMED takes an additional argument: a name for this +particular kind of document (e.g. outline, synopsis, abstract, +memorandum), enclosed in double-quotes. NAMED is +identical to DEFAULT except that mom prints the argument +to NAMED beneath the +docheader, +as well as in page headers. +(See +Default specs for headers +for how mom outputs each part of the page header.) +

+ +
+

+Note: version 2.1 change +
+DOCTYPE NAMED "string" no longer accepts a colour +argument after "string". Setting the colour +of the string is now done with DOCTYPE_COLOR +<color>. Default underscoring of +"string" in the docheader and on covers +has been removed. Use DOCTYPE_UNDERSCORE, +DOC_COVER_DOCTYPE_UNDERSCORE and/or +COVER_DOCTYPE_UNDERSCORE to re-enable it. All three take +the same arguments listed in the +Underscore style, rule weight +section of +Arguments to the control macros. +

+
+ +

+LETTER tells mom you’re writing a letter. See the +section +Writing Letters +for instructions on using mom to format letters. +

+ +

Slides

+ +

+PDF slides are a special kind of mom document, formatted for viewing +in a PDF reader’s presentation mode. In most respects, they +behave identically to the other document types. Key differences +are: +

+
    +
  • headers, footers, and pagination are disabled by default
  • +
  • type is set +QUAD CENTER +by default
  • +
  • +flex-spacing +and +shimming +are disabled by default; shimming may +be re-enabled (with NO_SHIM OFF), but not flex-spacing
  • +
  • there’s no need for +PRINTSTYLE
  • +
+ +

+DOCTYPE SLIDES takes up to five optional arguments, which come +immediately after SLIDES. They may be entered in any order. +
+ + DOCTYPE SLIDES \ + ASPECT 4:3 | 16:9 \ + HEADER "left" "centre" "right" \ + FOOTER "left" "centre" "right" \ + TRANSITION "<slide transition effect>" (mode + parameters) \ + PAUSE "<text reveal effect>" (mode + parameters) + +For convenience, you many want to enter each argument on a single +line as shown above; all but the last must be terminated by a +backslash. +

+ +
Aspect
+ +

+Slides can be formatted for one of two aspect ratios common to +monitors and screens: 4:3 and 16:9. The default is 16:9. + + 4:3 16:9 + media size: 11" x 8.25" media size: 11" x 8.1875" + left/right margins: 36 points left/right margins: 36 points + top margin: 90 points top margin: 80 points + bottom margin: 84 points bottom margin: 72 points + base text size: 16 points base text size: 14 points + autoleading: 6 points, adjusted autoleading: 4 points, adjusted + (header/footer size: -3 points) (header/footer size: -2 points) + +Note that both media sizes fit on either A4 or US LETTER papersizes. +

+ +
Headers, footers, and pagination
+ +

+If you want a header, footer, or both for your slides, pass SLIDES +the HEADER and/or FOOTER argument(s). Both +take three additional +string arguments, +which must be enclosed in double-quotes, defining the left, centre, +and right parts of the header/footer. Any parts you want left blank +should be entered as two double-quotes. For example, + + HEADER "" "My slide presentation" "" + +will result in a header with only the centre part. +

+ +

+Normal pagination is disabled for slides. If you want your slides +numbered, the slide number must be given to one of the header/footer +parts with the +inline escape +
+\*[SLIDE#]. For example: + + HEADER "" "My slide presentation" "" \ + FOOTER "" "" "\*[SLIDE#]" + +will give you a centred header with numbering at the bottom right of +the slide. +

+ +

+The overall family, size, and colour of headers may be set with +HEADER_FAMILY, HEADER_SIZE, and HEADER_COLOR. If you request +FOOTERS, you may use the FOOTER_ equivalent of these macros. +If you request both headers and footers, use one or the other but +not both. For example, in a header/footer situation, HEADER_FAMILY +would determine the family for both headers and footers, but if you +attempted to do this + + .HEADER_FAMILY T + .FOOTER_FAMILY H + +FOOTER_FAMILY would take precedence, and your header family would be +“H”. +

+ +

+All other formatting of individual header/footer parts must be +entered as inline escapes inside the double-quotes. If you want, +say, your headers to be red but your footer page numbering to be +black and two points larger, this is how you’d do it: + + .HEADER_COLOR red + .DOCTYPE SLIDES \ + HEADER "" "My slide presentation" "" \ + FOOTER "" "" "\*[black]\*S[+2]\*[SLIDE#]\*S[-2]" + +

+ +
+

+Note: +Do not use mom’s +\*[SIZE ±n] +inline escape to change point size in the strings +passed to HEADER or FOOTER. Prefer either mom’s +\*S[±n] or groff’s +\s[±n]. +

+
+ +
Transition
+ +

+“Transition” refers to how new slides appear during a +presentation. The official PDF specification lists a number of modes, +each with a choice of configurable parameters. Modes include Box, +Blinds, Wipe, Fade, and several others. Parameters include things +like duration, dimension, and direction. There are a total of +twelve modes; for each one there are from one to six configurable +parameters. Consult man gropdf(1) for a complete listing +of modes and parameters. +

+ +

+If you pass SLIDES the TRANSITION argument, you must +at a minimum follow it with a mode. Afterwards, you may give as +many or as few parameters as you wish. Parameters are, in order, + + 1. duration + 2. dimension + 3. motion + 4. direction + 5. scale + 6. bool + +You don’t have to fill them all out. If you only need the +first three, that’s all you need to input. If you need the +first and third, enter the second as a period (dot), which is used +any time you want to leave a parameter at its current default or +when it isn’t applicable. For example, if you want a Box +transition that lasts 1 second, filling the screen from the centre +outwards, you’d enter + + TRANSITION "Box 1 . O" + +because Box does not take a “dimension” parameter but it +does take a motion parameter. +

+ +

+Notice that the entire string (mode+parameters) must be enclosed in +double-quotes. +

+ +
+

+Note: +Not all PDF viewers support all modes. Any that are not supported +are replaced by the “R” mode, which simply replaces one +slide with the next unless the PDF viewer has a different default +transition mode. +

+
+ +
Pause
+ +

+A “pause” occurs when material on a slide is halted (see +PAUSE), +awaiting a mouse click, PgDown, Next, or the spacebar to reveal +subsequent material. All the same modes and parameters as +TRANSITION may be used. The manner of entering them is +is identical, including that the entire mode+parameter string must +be enclosed in double-quotes. +

+ +
+

SLIDE MACROS

+
+ +
+Macro: NEWSLIDE ["<transition mode and parameters>"] +
+ +

+Unless you want material from one slide to flow onto the next, you +need to tell mom when to start a new slide with the macro NEWSLIDE. +Without any arguments, the new slide will appear with the default +TRANSITION you gave to DOCTYPE SLIDES. +

+ +

+If you would like a different transition, you may pass NEWSLIDE a +new mode and associated parameters, following the same rules as the +TRANSITION argument to DOCTYPE. Note that the new effect becomes +the default. If you wish to return to the original transition, you +must give it explicitly to the appropriate NEWSLIDE. +

+ +
+Macro: PAUSE ["<pause mode and parameters>"] +
+ +

+Pauses in slides are accomplished by entering the macro PAUSE at +desired locations in your input file. Subsequent material will be +revealed using the pause mode given to DOCTYPE SLIDES. +

+ +

+If you would like a different mode, you may pass PAUSE a +new mode and associated parameters, following the same rules as the +PAUSE argument to DOCTYPE. +

+ +
+Macro: TRANSITION ["<transition mode and parameters>"] +
+ +

+If for some reason you have material that flows from one slide to +the next and you want the next slide to have a transition +different from the current one, you can tell mom about the new +transition with the macro TRANSITION anywhere prior to the break to +the next slide. +

+ +

Printing slides

+ +

+If you want to print slides as handouts, you have to tell +pdfmom or gropdf, otherwise printing will +stop at the first pause. Simply precede pdfmom or +gropdf with GROPDF_NOSLIDE=1, like this: +
+ + GROPDF_NOSLIDE=1 pdfmom <options> slidefile.mom > slidefile.pdf + + +

+ + + +
+

PRINTSTYLE

+
+ +
+Macro: PRINTSTYLE TYPESET | TYPEWRITE [ SINGLESPACE ] +
+ +

+• Required for document processing, except in the case of +slides +
+Must come before any changes to default document style +

+ +

+PRINTSTYLE tells mom whether to typeset a document, or to print it +out “typewritten, doubled-spaced”. +

+ +
+

+Important: +This macro may not be omitted. In order for document +processing to take place, mom requires a PRINTSTYLE. If you +don’t give one, mom will warn you on stderr and print a single +page with a nasty message. +

+ +

+Just as important: +PRINTSTYLE must precede any and all page and style +parameters associated with a document with the exception of +PAPER, which should be placed at the top of your file. +PRINTSTYLE sets up complete templates that include default margins, +family, fonts, point sizes, and so on. Therefore, changes to any +aspect of document style must come afterwards. For example, +
+ + .PAPER A4 + .LS 14 + .QUAD LEFT + .PRINTSTYLE TYPESET + +will not change mom’s default document leading to 14 points, +nor the default justification style (fully justified) to left +justified, whereas +
+ + .PAPER A4 + .PRINTSTYLE TYPESET + .LS 14 + .QUAD LEFT + +will. +

+ +
+ +

+TYPESET, as the argument implies, typesets +documents (by default in Times Roman; see +TYPESET defaults). +You have full access to all the +typesetting macros +as well as the +style control macros +of document processing. +

+ +

+With TYPEWRITE, mom does her best to reproduce the look +and feel of typewritten, double-spaced copy (see +TYPEWRITE defaults). +Control macros +and +typesetting macros +that alter family, font, point size, and +leading +are (mostly) ignored. An important exception is +HEADER_SIZE +(and, by extension, FOOTER_SIZE), which allows you to reduce the +point size of headers/footers should they become too crowded. Most +of mom’s inlines affecting the appearance of type are also +ignored +(\*S[<size>] +is an exception; there may be a few others). +

+ +

+In short, TYPEWRITE never produces effects +other than those available on a typewriter. Don’t be fooled +by how brainless this sounds; mom is remarkably sophisticated when +it comes to conveying the typographic sense of a document within the +confines of TYPEWRITE. +

+ +

+The primary uses of TYPEWRITE are: outputting hard +copy drafts of your work (for editing) and producing documents +for submission to publishers and agents who (wisely) insist on +typewritten, double-spaced copy. To get a nicely typeset version of +work that’s in the submission phase of its life (say, to show +fellow writers for critiquing), simply change TYPEWRITE +to TYPESET and print out a copy. +

+ +

+If, for some reason, you would prefer the output of +TYPEWRITE single-spaced, pass PRINTSTYLE +TYPEWRITE the optional argument, SINGLESPACE. +

+ +
+

PRINTSTYLE TYPESET defaults

+ + Family = Times Roman + Point size = 12.5 + Paragraph leading = 16 points, adjusted + Fill mode = justified + Hyphenation = enabled + max. lines = 2 + margin = 36 points + interword adjustment = 1 point + Kerning = enabled + Ligatures = enabled + Smartquotes = enabled + Word space = groff default + Sentence space = 0 + +
+ +
+

PRINTSTYLE TYPEWRITE defaults

+ + Family = Courier + Italics = underlined + Point size = 12 + Paragraph leading = 24 points, adjusted; 12 points for SINGLESPACE + Fill mode = left + Hyphenation = disabled + Kerning = disabled + Ligatures = disabled + Smartquotes = disabled + Word space = groff default + Sentence space = groff default + Columns = ignored + +
+ +
+

PRINTSTYLE TYPEWRITE control macros

+ +

Family

+ +

+If you’d prefer a monospace +family +for PRINTSTYLE TYPEWRITE other than mom’s +default, Courier, you can change it with +.TYPEWRITER_FAMILY <family> (or +.TYPEWRITER_FAM). Since groff ships with only the +Courier family, you will have to install any other monospace family +yourself. See +Adding fonts to +groff. +

+ +

Point size

+ +

+If you’d like a smaller or larger point size for +PRINTSTYLE TYPEWRITE (mom’s default is 12-point), +you can change it with +.TYPEWRITER_SIZE <size>. There’s no need to +add a +unit of measure +to the <size> argument; points is assumed. Be +aware, however, that regardless of point size, mom’s +leading/linespacing for TYPEWRITE is fixed at 24-point +for double-spaced, and 12-point for single-spaced. +

+ +

Underlining of italics

+ +

+In PRINTSTYLE TYPEWRITE, mom, by default, underlines +anything that looks like italics. This includes the +\*[SLANT] +inline escape +for pseudo-italics. (See +UNDERLINE +for a note on how to process TYPEWRITE files that underline +italics.) +

+ +

+If you’d prefer that mom were less bloody-minded +about pretending to be a typewriter (i.e., you’d like italics and +pseudo-italics to come out as italics), use the control macros +
+ + .ITALIC_MEANS_ITALIC + +and + + .SLANT_MEANS_SLANT + +Neither requires an argument. +

+ +

+Although it’s unlikely, should you wish to reverse +the sense of these macros in the midst of a document, +.UNDERLINE_ITALIC and .UNDERLINE_SLANT restore +underlining of italics and pseudo-italics. +

+ +

+Additionally, by default, mom underlines +quotes +(but not +blockquotes) +in PRINTSTYLE TYPEWRITE. If you don’t like this +behaviour, turn it off with +
+ + .UNDERLINE_QUOTES OFF + +

+ +

+To turn underlining of quotes back on, use UNDERLINE_QUOTES without +an argument. +

+ +

+While most of the +control macros +have no effect on PRINTSTYLE TYPEWRITE, there +is an important exception: +HEADER_SIZE +(and by extension, FOOTER_SIZE). This is +particularly useful for reducing the point size of +headers/footers should they become crowded (quite likely to +happen if the title of your document is long and your +COPYSTYLE +is DRAFT). +

+ +

+Finally, note that colour is disabled for TYPEWRITE. If +you would like it enabled, for example so PDF links are colourised, +invoke the groff +primitive +'.color' after PRINTSTYLE. +

+ +
+ + + +
+

COPYSTYLE

+
+ +
+Macro: COPYSTYLE DRAFT | FINAL +
+ +

+Mom’s default COPYSTYLE is FINAL, so you +don’t have to use this macro unless you want to. +

+ +

+COPYSTYLE DRAFT exhibits the following behaviour: +

+
    +
  1. Documents start on page 1, whether or not you + request a different starting page number with + PAGENUMBER. +
  2. +
  3. Page numbers are set in lower case roman numerals.
  4. +
  5. The draft number supplied by + DRAFT + and a revision number, if supplied with + REVISION + (see + reference macros), + appear in the centre part of + page headers + (or footers, depending on which you’ve selected) along with + any other information that normally appears there. +
  6. +
+ +
+

+Important: +If you define your own centre part for page headers with +HEADER_CENTER, +no draft and/or revision number will appear there. If you want +draft and revision information in this circumstance, use +DRAFT_WITH_PAGENUMBER. +

+
+ +

+COPYSTYLE FINAL differs from DRAFT in that: +

+
    +
  1. It respects the starting page number you give the document.
  2. +
  3. Page numbers are set in normal (Arabic) digits.
  4. +
  5. No draft or revision number appears in the page headers.
  6. +
+ +
+

+Note: +The centre part of page headers can get crowded, especially with +DOCTYPE CHAPTER +and +DOCTYPE NAMED, +when the COPYSTYLE is DRAFT. Three mechanisms are +available to overcome this problem. One is to reduce the overall +size of headers (with +HEADER_SIZE). +Another, which only works with +PRINTSTYLE TYPESET, +is to reduce the size of the header’s centre part only (with +HEADER_CENTER_SIZE). +And finally, you can elect to have the draft/revision information +attached to page numbers instead of having it appear in the centre +of page headers (see +DRAFT_WITH_PAGENUMBER). +

+
+ +

+ + + +

Initiate document processing

+ +

+In order to use mom’s document element macros (tags), you have +to tell her you want them. The macro to do this is +START. +

+ +

+START collects the information you gave mom in the setup section at +the top of your file (see +Tutorial – Setting up a mom document), +merges it with her defaults, sets up headers and page numbering, +and prepares mom to process your document using the document +element tags. No document processing takes place until you invoke +.START. +

+ + + +
+

START

+
+ +
+Macro: START +
+

+• Required for document processing +

+ +

+START takes no arguments. It simply instructs mom to begin document +processing. If you don’t want document processing (i.e., you +only want the +typesetting macros), +don’t use START. +

+ +

+At a barest minimum before START, you must enter a +PRINTSTYLE +command. +

+ +

+ + + +

Establishing typestyle and formatting parameters before START

+ +

+In the third (optional) part of setting up a document (the +stylesheet; see +Tutorial – Setting up a mom document), +you can use the +typesetting macros +to change mom’s document-wide defaults for margins, +line length, family, base point size, +leading, +and justification style. +

+ +

+Two additional style concerns have to be addressed here (i.e. in +macros before +START): +changes to the +docheader, +and whether you want you want the document’s nominal leading +adjusted to fill pages fully to the bottom margin. +

+ +
+

Type & formatting parameters before START

+ +
+ +

Behaviour of the typesetting macros before START

+ +

+From time to time (or maybe frequently), you’ll want the +overall look of a document to differ from mom’s defaults. +Perhaps you’d like her to use a different +family, +or a different overall +leading, +or have different left and/or right page margins. +

+ +

+To accomplish such alterations, use the appropriate +typesetting macros +(listed below) after +PRINTSTYLE +and before +START. +

+ +

+More than one user has, quite understandably, not fully grasped the +significance of the preceding sentence. The part they’ve missed is +after PRINTSTYLE. +

+ +

+Changes to any aspect of the default look and/or formatting of a mom +document must come after PRINTSTYLE. For example, it might seem +natural to set up page margins at the very top of a document with +
+ + .L_MARGIN 1i + .R_MARGIN 1.5i + +However, when you invoke .PRINTSTYLE, those margins +will be overridden. The correct place to set margins—and +all other changes to the look of a document—is after +PRINTSTYLE. +

+ +
+

+Important: +Do not use the macros listed in +Changing document-wide typesetting parameters after START +prior to START; they are exclusively for use afterwards. +

+
+ +
+

Meanings

+

+When used before START, the +typesetting macros, +below have the following meanings: +
+ + L_MARGIN Left margin of pages, including headers/footers + R_MARGIN Right margin of pages, including headers/footers + T_MARGIN The point at which running text (i.e. not + headers/footers or page numbers) starts on each + page + B_MARGIN* The point at which running text (i.e. not + (see note) headers/footers or page numbers) ends on each page + + PAGE If you use PAGE, its final four arguments have the + same meaning as L_ R_ T_ and B_MARGIN (above). + + LL The line length for everything on the page; + equivalent to setting the right margin with + R_MARGIN + FAMILY The family of all type in the document + PT_SIZE The point size of type in paragraphs; mom uses + this to calculate automatic point size changes + (e.g. for heads, footnotes, quotes, headers, etc) + LS/AUTOLEAD** The leading used in paragraphs; all leading and + spacing of running text is calculated from this + + QUAD/JUSTIFY Affects paragraphs only + LEFT*** No effect + RIGHT*** No effect + CENTER*** No effect + +------ + *See FOOTER MARGIN AND BOTTOM MARGIN for an important warning + **See DOC_LEAD_ADJUST +***See Special note + +

+
+ +

+Other macros that deal with type style, or refinements thereof +(KERN, +LIGATURES, +HY, +WS, +SS, +etc.), behave normally. It is not recommended that you set up tabs +or indents prior to START. +

+ +

+If you want to change any of the basic parameters (above) +after START and have them affect a document globally (as if +you’d entered them before START), you must use the macros +listed in +Changing document-wide typesetting parameters after START. +

+ +

Special note on LEFT, RIGHT and CENTER prior to START

+ +

+In a word, these three macros have no effect on document processing +when invoked prior to START. +

+ +

+All mom’s document element tags +(PP, +HEADING, +BLOCKQUOTE, +FOOTNOTE, +etc.) except +QUOTE +set a +fill mode +as soon as they’re invoked. If you wish to turn fill mode off +for the duration of any tag (with +LEFT, RIGHT or CENTER) +you must do so immediately after invoking the tag. Furthermore, +the change affects only the current invocation of the tag. +Subsequent invocations of the same tag for which you want the same +change require that you invoke .LEFT, .RIGHT +or .CENTER immediately after every invocation of the tag. +

+ + + +

Including (sourcing) style sheets and files

+ +

+If you routinely make the same changes to mom’s defaults in +order to create similar documents in a similar style—in other +words, you need a template— you can create stylesheet files +and include, or “source”, them into your mom documents +with the macro .INCLUDE. The right place for such style +sheets is after +PRINTSTYLE +and before +START. +

+ +

+Say, for example, in a particular kind of document, you always +want main heads set in Helvetica Bold Italic, flush left, with +no underscore. You’d create a file, let’s call it +head-template, in which you’d place the pertinent +HEADIING control macros. +
+ + .HEADING_STYLE 1 \ + FAMILY H \ + FONT BI \ + QUAD L \ + NO_UNDERSCORE + +Then, in the preliminary document set-up section of your main file, +you’d include the style sheet, or template, like this: +
+ + .TITLE "Sample Document + .AUTHOR "Joe Blow + .PRINTSTYLE TYPESET + \# + .INCLUDE head-template + \# + .START + + +The blank comment lines ( \# ) aren’t required, but +they do make your file(s) easier to read. +

+ +

+If the file to be included is in the same directory as the file +you’re working, you simply enter the filename after +.INCLUDE. If the file’s in another directory, you must +provide a full path name to it. For example, if you’re working in +a directory called /home/joe/stories and your +stylesheet is in /home/joe/stylesheets, the above +example would have to look like this: +
+ + .TITLE "Sample Document + .AUTHOR "Joe Blow + .PRINTSTYLE TYPESET + \# + .INCLUDE /home/joe/stylesheets/head-template + \# + .START + +

+ +

+INCLUDE is not restricted to style sheets or templates. You can +include any file at any point into a document, provided the file +contains only text and valid groff or mom formatting commands. +Neither is INCLUDE restricted to use with mom’s document +processing macros. You can use it in plain typeset documents as +well. +

+ +
+

+Note: +INCLUDE is an alias for the groff request .so. If the +sourced file contains material that requires pre-processing (e.g. +a table made with tbl(1) or non-English characters), use +.so rather than INCLUDE and invoke pdfmom thus: +
+ + soelim file.mom | pdfmom [flags] > file.pdf + +soelim only looks for lines that begin with .so, +which furthermore must not have any space between the period and +the “s”. +

+
+ + + +

Initializing colours

+ +

+Although it doesn’t really matter where you define/initialize +colours for use in document processing (see +NEWCOLOR +and +XCOLOR +in the section +Coloured text), +I recommend doing so before you begin document processing with +START. +

+ +

+The macro +COLOR +and the +inline escape, +\*[<colorname>] +can be used at any time during document processing for occasional +colour effects. However, consistent and reliable colourising of +various document elements (the docheader, heads, linebreaks, +footnotes, pagenumbers, and so on) must be managed through the use +of the +document element control macros. +

+ +

+Please note that colour is disabled if your +PRINTSTYLE +is TYPEWRITE. If you would like it enabled, for example +so PDF links are colourised, invoke the groff +primitive +'.color' after PRINTSTYLE. +

+ +
+

+Note: +If you plan to have mom generate a +table of contents, +do not embed colour +inline escapes +(\*[<colourname>]) +in the +string arguments +given to any of the +reference macros, +nor in the string arguments given to +HEADING. +Use, rather, the +control macros +mom provides to automatically colourise these elements. +

+
+ + + +
+

Adjust linespacing to fill pages and align bottom margins

+
+ +
+Macro: DOC_LEAD_ADJUST toggle +
+ +

+• Must come after +LS +or +AUTOLEAD +and before +START +

+ +

+DOC_LEAD_ADJUST is a special macro to adjust document +leading +so that bottom margins fall precisely where you expect. +

+ +

+When you invoke .DOC_LEAD_ADJUST, mom takes the number +of lines that fit on the page at your requested leading, then +incrementally adds +machine units +to the leading until the maximum number of lines at the new leading +that fit on the page coincides perfectly with the bottom margin of +running text. +

+ +

+In most instances, the difference between the requested lead and +the adjusted lead is unnoticeable, and since in almost all cases +adjusted leading is what you want, it’s mom’s default +and you don’t have to invoke it explicitly. +

+ +

+However, should you not want adjusted document leading, you must +turn it off manually, like this: +
+ + .DOC_LEAD_ADJUST OFF + +

+ +

+If you set the document leading prior to START with +LS +or +AUTOLEAD, +.DOC_LEAD_ADJUST OFF must come afterwards, like +this: +
+ + .LS 12 + .DOC_LEAD_ADJUST OFF + +In this scenario, the maximum number of lines that fit on a page at +a +leading +of 12 +points +determine where mom ends a page. The effect will be that last lines +usually fall (slightly) short of the “official” bottom +margin. +

+ +

+In +PRINTSTYLE TYPEWRITE, +the leading is always adjusted and can’t be turned off. +

+ +
+

+Note: +DOC_LEAD_ADJUST, if used, must be invoked after +LS +or +AUTOLEAD +and before +START. +

+ +

+Additional note: +Even if you disable DOC_LEAD_ADJUST, mom will still adjust the +leading of endnotes pages and toc pages. See +ENDNOTE_LEAD +and +TOC_LEAD +for an explanation of how to disable this default behaviour. +

+
+ + + +
+

Managing the docheader

+
+ +
+Macro: DOCHEADER <toggle> [ distance to advance from top of page ] [ NO_SHIM ] +
+ +

+• Must come before +START; distance requires a unit of measure +

+ +

+By default, mom prints a +docheader +on the first page of any document (see +below +for a description of the docheader). If you don’t want a docheader, +turn it off with +
+ + .DOCHEADER OFF + +DOCHEADER is a toggle macro, so the argument doesn’t +have to be OFF; it can be anything you like. +

+ +

+If you turn the docheader off, mom, by default, starts +the running text of your document on the same top +baseline +as all subsequent pages. If you’d like her to start at a different +vertical position, give her the distance you’d like as a second +argument. +
+ + .DOCHEADER OFF 1.5i + +This starts the document 1.5 inches from the top of the page plus +whatever spacing adjustment mom has to make in order to ensure that +the first baseline of running text falls on a “valid” +baseline (i.e., one that ensures that the bottom margin of the first +page falls where it should). The distance is measured from the top +edge of the paper to the +baseline +of the first line of type. +

+ +

+With .DOCHEADER OFF, it is possible to create your own +custom docheaders (after +START) +using mom’s typesetting macros. It is recommended that if you +do create a custom docheader, you make +.SHIM +the last macro before the first item of your document (for +example, .PP or .HEADING 1. +

+ +
+

+Note: +You may have tried DOCHEAHER OFF with a distance argument +and discovered that mom will not budge the starting position of the document +from her chosen default location. This is byproduct of +shimming, +which mom always applies before the first line of running text after +the docheader, regardless of which +vertical whitespace management +strategy is in effect. If you encounter the problem, pass +DOCHEADER OFF <distance> +the additional final argument, NO_SHIM. +

+
+ + + +

Docheader control: How to change the look of docheaders

+ +

+In +PRINTSTYLE TYPEWRITE, +the look of docheaders is carved in stone. In +PRINTSTYLE TYPESET, +however, you can make a lot of changes. Macros that alter +docheaders must come before +START. +

+ +

Docheader description

+ +

+A typeset docheader has the following characteristics: +

+
+ + TITLE bold, 3.5 points larger than running text (not necessarily caps) + Subtitle medium, same size as running text + by medium italic, same size as running text + Author(s) medium italic, same size as running text + +(Document type) bold italic, 3 points larger than running text + +
+ +

+Or, if the +DOCTYPE +is CHAPTER, +

+
+ + Chapter <n> bold, 4 points larger than running text +Chapter Title bold italic, 4 points larger than running text + +
+ +

+The +family +is the prevailing family of the whole document. Title, subtitle, +author, and document type are what you supply with the +reference macros. +Any you leave out will not appear; mom will compensate: +

+ +
+

+Note: +If your DOCTYPE is CHAPTER and you have both “Chapter +<n>” and a “Chapter Title” (as above), mom +inserts a small amount of whitespace between them, equal to +one-quarter of the +leading +in effect. If this doesn’t suit you, you can remove or alter +the space with +CHAPTER_TITLE_SPACE_BEFORE. +

+
+ +
+

Docheader control

+ +

+With the docheader control macros, you can change the family, +colour, leading, and quad direction of the entire docheader. You can +also set the style parameters for each part individually. Style +parameters include family, font, size, colour, lead, space before, +caps, smallcaps, and underscoring. +

+ + +
+ +

1. Changes to the whole docheader

+ +
Change the starting position of the docheader
+ +

+By default, a docheader starts on the same +baseline +as +running text. +If you’d like it to start somewhere else, use the macro +DOCHEADER_ADVANCE and give it the distance you want (measured from +the top edge of the paper to the first baseline of the docheader), +like this: +
+ + .DOCHEADER_ADVANCE 4P + +A +unit of measure +is required. +

+ +
+

+Note: +If +HEADERS +are OFF, mom’s normal top margin for +running text +(7.5 +picas) +changes to 6 picas (visually approx. 1 inch). Since the first +baseline of the docheader falls on the same baseline as the first +line of running text (on pages after page 1), you might find the +docheaders a bit high when headers are off. Use DOCHEADER_ADVANCE +to place them where you want. +

+
+ +
Change the quad direction of the docheader
+ +

+By default, mom centres the docheader. If you’d prefer to +have your docheaders set flush left or right, or need to restore +the default centering, invoke .DOCHEADER_QUAD with the +quad direction you want, either LEFT (or L), +RIGHT (or R) or CENTER (or +C). +

+ +
Change the family of the entire docheader
+ +

+By default, mom sets the docheader in the same +family used for +running text. +If you’d prefer to have your docheaders set in a different +family, invoke .DOCHEADER_FAMILY with the family you +want. The argument to DOCHEADER_FAMILY is the same as for +FAMILY. +

+ +

+For example, mom’s default family for running text is Times +Roman. If you’d like to keep that default, but have the +docheaders set entirely in Helvetica, +
+ + .DOCHEADER_FAMILY H + +is how you’d do it. +

+ +

+Please note that if you use DOCHEADER_FAMILY, you can still alter +the family of individual parts of the docheader. +

+ +
Change the colour of the entire docheader
+ +

+The default colour for docheaders is black, as you’d expect. +If you wish to change it, use +.DOCHEADER_COLOR <colour>, where + <colour> is a colour pre-initialized with +XCOLOR +or +NEWCOLOR. +

+ +
Change the leading of the entire docheader
+ +

+By default, mom uses the leading in effect for +running text +for docheaders. If you want to increase or +decrease the overall docheader leading, use +.DOCHEADER_LEAD +|-<amount>, where +<amount> is the number of +points +by which to make the adjustment. +

+ +

2. Part by part changes

+ +

+Whenever you want to change the style parameters for any part of +the docheader, simply join the name of the part to the parameter +you wish to change using an underscore, then supply any necessary +arguments. The subtitle double-underlined? No problem. +
+ + .SUBTITLE_UNDERSCORE DOUBLE + +Author in red? +
+ + .AUTHOR_COLOR red + +Title in smallcaps? + + .TITLE_SMALLCAPS + +

+ +
+

+Note: +Use ATTRIBUTE as the part name for the attribution string +(“by”) that precedes the author, and DOCTYPE +as the name for the string passed to DOCTYPE NAMED "string". +

+
+ +
List of parameters with arguments
+ +
+
_FAMILY
+
+ Takes the same argument as FAMILY. +
+
_FONT
+
+ Takes the same argument as FT. +
+
_SIZE
+
+ Takes a + or - value relative to the size of + running text. +
+
_COLOR
+
+ Takes the same argument as COLOR. + Colours should be pre-initialized with + XCOLOR + or + NEWCOLOR. +
+
_LEAD
+
+ Takes an absolute leading value, i.e. not relative to the + overall leading of the docheader. The leading applies to + multiple lines of type within the same docheader part, e.g. + several authors or a long title that must be split over two + lines. No + unit of measure + is required; + points + is assumed. +
+
_SPACE
+
+ Takes a numeric value with a + unit of measure + appended to it. The value may be negative. This allows you + to adjust the whitespace before a docheader part, for example + if you want more whitespace between the title and the author. + + Note that TITLE does not have a _SPACE + parameter; use + DOCHEADER_ADVANCE + to move the title further down on the page. + +
+
_CAPS
+
+ Capitalizes the entire docheader part. No argument is + required. +
+
_NO_CAPS
+
+ Only used if you need to reverse the sense of _CAPS, as + can sometimes happen when + collating + documents that have differing docheader style requirements. +
+
_SMALLCAPS
+
+ Set the entire docheader part in smallcaps. No argument is + required. +
+
_NO_SMALLCAPS
+
+ Only used if you need to reverse the sense of + _SMALLCAPS, as can sometimes happen when + collating + documents that have differing docheader style requirements. +
+
_UNDERSCORE
+
+ With no argument, underscores the docheader part. With a + single, possibly decimal numeric argument, sets the weight of + the underscore. A second numeric argument to which a + unit of measure + is appended (most likely p) sets the distance + between the baseline and the underscore. + + If the argument DOUBLE is given, double underscores + the docheader part. With a single, possibly decimal numeric + argument afterwards, sets the weight of the underscore rules. + A third numeric argument to which a + unit of measure + is appended (most likely p) sets the distance + between the baseline and the first underscore rule. A fourth + numeric argument to which a unit of measure is appended sets + the distance between the two underscore rules. + + + You may give _UNDERLINE as the parameter instead of + _UNDERSCORE if you prefer. + +
+
NO_UNDERSCORE
+
+ Only used if you need to reverse the sense of + _UNDERSCORE, as can sometimes happen when + collating + documents that have differing docheader style requirements. +
+
+ +
Grouping part/parameter changes
+ +

+If you want to change several parameters for a particular docheader +part, you may group the changes together in a single macro by +joining the name of the part to STYLE with an underscore, +for example TITLE_STYLE or AUTHOR_STYLE. +The following demonstrates: + + .CHAPTER_TITLE_STYLE \ + FAMILY T \ + SIZE +4 \ + UNDERSCORE 2 \ + SMALLCAPS + +Notice the use of the backslash character, which is required after +the macro name and all parameters except the last. Grouping reduces +clutter and the finger fatigue caused by entering + + .CHAPTER_TITLE_FAMILY T + .CHAPTER_TITLE_SIZE +4 + .CHAPTER_TITLE_UNDERSCORE 2 + .CHAPTER_TITLE_SMALLCAPS + +

+ +

3. Changing or removing the attribution string (“by”)

+ +

+If you’re not writing in English, you can change what mom +prints where “by” appears in docheaders. For example, +
+ + .ATTRIBUTE_STRING "par" + +changes “by” to “par”. ATTRIBUTE_STRING +can also be used, for example, to make the attribution read +“Edited by”. +

+ +

+If you don’t want an attribution string at all, simply pass +ATTRIBUTE_STRING an empty argument, like this: +
+ + .ATTRIBUTE_STRING "" + +Mom will deposit a blank line where the attribution string normally +appears. +

+ +

+If the optional argument COVER or DOC_COVER +is given to ATTRIBUTE_STRING, the string argument represents the +attribution string that will appear on cover or document cover pages +(see the +Introduction to cover pages +for a description of the difference between “document +covers” and “covers”). Thus, it is possible to +have different attribution strings on the document cover page, the +cover (“title”) page, and in the first-page docheader. +An extreme example would be: +
+ + .ATTRIBUTE_STRING "" + .ATTRIBUTE_STRING DOC_COVER "Edited by" + .ATTRIBUTE_STRING COVER "by" + +The first invocation of .ATTRIBUTE_STRING establishes a +blank attribution string that will be incorporated in the first-page +docheader. The second will print “Edited by” on the +document cover; the third will print “by” on the cover +(“title”) page. +

+ +

+If you don’t require differing attribute strings for +doc cover pages, cover pages, or the first-page docheader, +.ATTRIBUTE_STRING, without either of the optional first +arguments, is sufficient. +

+ +

+ + + +

Setting documents in columns

+ +

+Setting documents in columns is easy with mom. All you have to do +is say how many columns you want and how much space you want +between them (the +gutters). +That’s it. Mom takes care of everything else, from soup to +nuts. +

+ +

Some words of advice

+ +

+If you want your type to achieve a pleasing +justification +or +rag +in columns, reduce the point size of type (and probably the +leading +as well). Mom’s default document point size is 12.5, which +works well across her default 39 +pica +full page line length, but with even just two columns on a page, the +default point size is awkward to work with. +

+ +

+Furthermore, you’ll absolutely need to reduce the indents for +epigraphs, +quotes, +and +blockquotes +(and probably the +paragraph first-line indent +as well). +

+ + + +
+

COLUMNS

+
+ +
+Macro: COLUMNS <number of columns> <width of gutters> +
+ +

+• Should be the last macro before START +
+ +The second argument requires a unit of measure +

+ +

+COLUMNS takes two arguments: the number of columns you want on +document pages, and the width of the +gutter +between them. For example, to set up a page with two columns +separated by an 18 point gutter, you’d do +
+ + .COLUMNS 2 18p + +Nothing to it, really. However, as noted above, COLUMNS should +always be the last document setup macro prior to +START. +

+ +
+

+Note: +Mom ignores columns completely when the +PRINTSTYLE +is TYPEWRITE. The notion of typewriter-style +output in columns is just too ghastly for her to bear. +

+
+ +

Marking the first page column start position

+ +

+If you insert or remove space after the docheader, i.e. immediately after +START +in your input file, mom needs to know where your first column begins +in order to align subsequent columns on the first page. +

+ +
+Macro: COL_MARK +
+ +

+COL_MARK tells mom where the first column after the +docheader begins, in order for the top of subsequent columns on the +first page to be aligned. Note that if you do not manually add +or remove space after the docheader, there is no need to invoke +COL_MARK. +

+ +
+

+Note: +If you do add or subtract space after the docheader, e.g. with +ALD +or +SP, +and your +unit of measure +is something other than a multiple of “v”, be +sure to follow the spacing command with +SHIM +before entering .COL_MARK unless shimming has been +disabled with +NO_SHIM. +If your document is being flex-spaced, do not use +FLEX. +Rather, disable flex-spacing temporarily with +
+ + .NO_FLEX + .NO_SHIM off + .SHIM + .COL_MARK + +and re-enable it afterwards with + + .NO_SHIM + .NO_FLEX off + +

+
+ +

Using tabs when COLUMNS are enabled

+ +

+Mom’s tabs (both +typesetting tabs +and +string tabs) +behave as you’d expect during document processing, even +when COLUMNS are enabled. Tab structures set up during document +processing carry over from page to page and column to column. +

+ + + +

Breaking columns manually

+ +

+Mom takes care of breaking columns when they reach the bottom +margin of a page. However, there may be times you want to break +the columns yourself. There are two macros for breaking columns +manually: COL_NEXT and COL_BREAK. +

+ +
+Macro: COL_NEXT +
+ +

+.COL_NEXT breaks the line just before it, +quads +it left (assuming the type is justified or quad left), and moves over +to the top of the next column. If the column happens to be the last +(rightmost) one on the page, mom starts a new page +at the “column 1” position. This is the macro to use when +you want to start a new column after the end of a paragraph. +

+ +
+Macro: COL_BREAK +
+ +

+.COL_BREAK is almost the same as .COL_NEXT, +except that instead of breaking and quadding the line preceding it, +mom breaks and spreads it (see +SPREAD). +Use this macro whenever you need to start a new column in the middle +of a paragraph. +

+ +
+

+Warning: +If you need COL_BREAK in the middle of a blockquote or (god help +you) an epigraph, you must do the following in order for COL_BREAK +to work: +
+ + .SPREAD + \!.COL_BREAK + +

+
+ +

+ + + + + + +

Changing basic type and formatting parameters after START

+ + + +

+ +

Behaviour of the typesetting macros during document processing

+ +

+During document processing, most of the +typesetting macros +affect type in the document globally. For example, if you turn +kerning off, pairwise kerning is disabled not only in paragraphs, +but also in headers, footers, quotes, and so on. +

+ +

+Typesetting macros that alter margins and line lengths affect +running text +globally (or at least try to), but leave headers/footers and +footnotes alone. (To indent footnotes, see the full explanation of +the +FOOTNOTE +macro.) +

+ +

+Mom’s tabs (both +typesetting tabs +and +string tabs) +behave as expected in running text during document processing. Tab +structures that do not exceed the line length of running text are +preserved sensibly from page to page, and, if +COLUMNS +are enabled, from column to column. +

+ +

+Some typesetting macros, however, when used during document +processing, behave in special ways. These are the macros that deal +with the basic parameters of type style: horizontal and vertical +margins, line length, +family, +font, +point size, +leading, +and +quad. +

+ +

+Mom assumes that any changes to these parameters stem from a +temporary need to set type in a style different from that provided +by mom’s +document element tags. +In other words, you need to do a bit of creative typesetting in the +middle of a document. +

+ +

+The following lists those typesetting macros whose behaviour during +document processing requires some explanation. +(Please refer to +Top and bottom margins in document processing +for information on how mom interprets +T_MARGIN +and +B_MARGIN +in document processing. Additionally, see +ADD_SPACE +if you encounter the problem of trying to get mom to put space at +the tops of pages after the first.) +

+ +
+ + MACRO EFFECT DURING DOCUMENT PROCESSING + ----- --------------------------------- + + L_MARGIN •The left margin of all running text + assumes the new value. + + •The line length remains unaltered. + + •The header and footer left margin + remain at the current document default. + + (You won’t use this often by itself. Most + likely, you’ll use it in combination with + R_MARGIN or LL.) + + R_MARGIN •The right margin of all running text + assumes the new value. In other words, + the line length is altered. + + •The header and footer right margin + remain at the current document default. + + LL •The line length of all running text + is set to the new value. + + •The header and footer line length remain + at the current document default. + + FAMILY •Changes family for the duration of the + current tag only. As soon as another document + element tag is invoked, the family reverts to + the current default for the new tag. + + FT •Changes font for the duration of the + current tag only. As soon as another document + element tag is entered, the font reverts + to the current default for the new tag. + + N.B. — \*[SLANT] and \*[BOLDER] affect + paragraph text, and remain in effect for all + paragraphs until turned off. If you want to + use them in a macro that takes a string + argument, include the escape in the string. + \*[COND] and \*[EXT] behave similarly. + + PT_SIZE •Changes point size for the duration of the + current tag only. As soon as another document + element tag is entered, the point size reverts + to the current document default for the new + tag. + + LS •Changes line space for the duration of the + current tag only. As soon as another document + element tag is entered, the line space reverts + to the current document default for the new + tag. + + Using LS to temporarily change leading within + a document will almost certainly result in a + bottom margin that doesn’t align with the + bottom margin of subsequent pages. You’ll + need to use the SHIM or FLEX macro to get mom back + on track when you’re ready to return to the + document’s default leading. + + AUTOLEAD •Invoked before START, sets the overall document + leading as a function of the overall document + point size (i.e. the point size used in paragraphs); + subsequently disabled after START, except for calls + to DOC_PT_SIZE + + •DOC_LEAD before DOC_PT_SIZE cancels the AUTOLEAD + set before START + + •Invoked after START, remains in effect for all + subsequent point size changes made with PT_SIZE, + but does not affect the leading of the document + element tags (e.g. HEADING, PP, QUOTE...), or calls + to DOC_PT_SIZE + + QUAD •Changes quad for the duration of the + current tag only. As soon as another document + element tag is entered, the quad reverts to + the current document default for the new + tag. + + N.B. — Line-for-line quadding macros + (LEFT, CENTER, RIGHT) are also temporary, + overridden by the QUAD value of any subsequent + document element tag. + +
+ +

Top and bottom margins in document processing

+ +

+Normally, mom establishes the top and bottom +margins of +running text +in documents from the values of HEADER_MARGIN + +HEADER_GAP and FOOTER_MARGIN + FOOTER_GAP +respectively. However, if you invoke +T_MARGIN +or +B_MARGIN +either before or after +START, +they set the top and bottom margins of running text irrespective of +HEADER_GAP and FOOTER_GAP. +

+ +

+Put another way, in document processing, T_MARGIN +and B_MARGIN set the top and bottom margins of +running text, but have no effect on the placement of +headers, +footers, +or page numbers. +

+ + + +

Inserting space at the top of a new page

+ +

+Occasionally, you may want to insert space before the start of +running text +on pages after the first. +

+ +

+You might have tried using +ALD +or +SPACE +and found it did nothing. This is because mom normally inhibits +any extra space before the start of running text on pages after the +first. +

+ +

+If you need the space, you must use the macro ADD_SPACE in +conjunction with +NEWPAGE. +

+ + + +
+

ADD_SPACE/RESTORE_SPACE

+
+ +
+Macro: ADD_SPACE <amount of space> +
+Macro: RESTORE_SPACE +
+ +

+• Requires a unit of measure +

+ +

+If your +DOCTYPE +is DEFAULT, CHAPTER, NAMED, or LETTER, ADD_SPACE takes as its +single argument the distance you want mom to advance from the normal +baseline position at the top of any page after the first (i.e. +the one on which the docheader is normally printed). A +unit of measure is +required. +

+ +

+For example, say you wanted to insert 2 inches of space before the +start of +running text +on a page other than the first. You’d accomplish it with +
+ + .NEWPAGE + .ADD_SPACE 2i + +which would terminate your current page, break to a new page, print +the header (assuming headers are on) and insert 2 inches of space +before the start of running text. +

+ +

+Since adding space in this way is almost sure to disrupt mom’s +ability to guarantee perfectly flush bottom margins, I highly +recommend using the +SHIM +or +FLEX +macro immediately after ADD_SPACE, which will add the space plus +whatever correction is required by the +vertical whitespace management +strategy in effect. +

+ +

+If your +DOCTYPE +is SLIDES, ADD_SPACE may be used on any slide including the +first to introduce additional white space at the top. +

+ +

RESTORE_SPACE

+ +

+You may sometimes find that mom refuses to respect +SP, +ALD/RLD, +SHIM, +or +FLEX +after the first element (line of text, floated material) output +at the top of a page. Should this happen, insert the macro +RESTORE_SPACE before issuing the spacing command. +

+ + + +

Changing document-wide typesetting parameters after START

+ +

+In the normal course of things, you establish the basic type style +parameters of a document prior to invoking +START, +using the +typesetting macros +(L_MARGIN, FAMILY, PT_SIZE, LS, etc). After START, you must +use the following macros if you wish to make global changes to the +basic type style parameters, for example changing the overall leading or +the justification style. +

+ +
+

+Important: +Because these macros globally update the chosen parameter, they +should only be used immediately prior to +COLLATE +or, if an occasional effect is desired, +NEWPAGE. +DOC_PT_SIZE, +for example, updates the point size of every page element, including +headers, footers, page numbers, and so on, which is almost certainly +not what you want in the middle of a page. +

+
+ +
+

Post-START global style change macros

+ +
+ + + +
+

DOC_LEFT_MARGIN

+
+ +
+Macro: DOC_LEFT_MARGIN <left margin> +
+ +

+• Requires a unit of measure +

+ +

Arguments and behaviour

+ +
    +
  • the argument is the same as for + L_MARGIN +
  • +
  • changes all left margins, including headers, footers, and page + numbers to the new value +
  • +
  • any document elements that use a left indent calculate + the indent from the new value +
  • +
  • the line length remains the same (i.e., the right margin + shifts when you change the left margin) +
  • +
+ + + +
+

DOC_RIGHT_MARGIN

+
+ +
+Macro: DOC_RIGHT_MARGIN <right margin> +
+ +

+• Requires a unit of measure +

+ +

Arguments and behaviour

+ +
    +
  • the argument is the same as for + R_MARGIN +
  • +
  • changes all right margins, including headers, footers, and + page numbers to the new value; +
  • +
  • any document elements that use a right indent calculate + the indent from the new value +
  • +
+ + + +
+

DOC_LINE_LENGTH

+
+ +
+Macro: DOC_LINE_LENGTH <length> +
+ +

+• Requires a unit of measure +

+ +

Arguments and behaviour

+ +
    +
  • the argument is the same as for + LL +
  • +
  • exactly equivalent to changing the right margin with + DOC_RIGHT_MARGIN (see + above); +
  • +
+ + + +
+

DOC_FAMILY

+
+ +
+Macro: DOC_FAMILY <family> +
+ +

Arguments and behaviour

+ + + + + +
+

DOC_PT_SIZE

+
+ +
+Macro: DOC_PT_SIZE <point size> +
+ +

+• Does not require a unit of measure; points is assumed +

+ +

Arguments and behaviour

+ +
    +
  • the argument is the same as for + PT_SIZE, + and refers to the point size of type in paragraphs +
  • +
  • all automatic point size changes (heads, quotes, + footnotes, headers, etc.) are affected by the new size; + anything you do not want affected must be reset to + its former value (see the Control Macros section of + the pertinent document element for instructions on + how to do this) +
  • +
  • if + AUTOLEAD + was invoked before START; the value of AUTOLEAD will be used + to update the leading of all document element tags except + FOOTNOTE and EPIGRAPH +
  • +
+ + + +
+

DOC_LEAD

+
+ +
+Macro: DOC_LEAD <points> [ ADJUST ] +
+ +

+• Does not require a unit of measure; points is assumed +

+ +

Arguments and behaviour

+ +
    +
  • the argument is the same as for + LS, + and refers to the + leading + of paragraphs +
  • +
  • because paragraphs will have a new leading, the leading and + spacing of most running text is influenced by the new value +
  • +
  • epigraphs and footnotes remain unaffected; + if you wish to change their leading, use + EPIGRAPH_AUTOLEAD + and + FOOTNOTE_AUTOLEAD. +
  • +
  • the optional argument ADJUST performs + leading adjustment as explained in + DOC_LEAD_ADJUST +
  • +
  • if + AUTOLEAD + was invoked before START; the value of that AUTOLEAD will be + cancelled +
  • +
+ +
+

+Note: +Even if you don’t pass DOC_LEAD the optional argument +ADJUST, mom will still adjust the leading of endnotes +pages and toc pages. See +ENDNOTE_LEAD +and +TOC_LEAD +for an explanation of how to disable this default behaviour. +

+
+ + + +
+

DOC_QUAD

+
+ +
+Macro: DOC_QUAD L | R | C | J +
+ +

Arguments and behaviour

+ +
    +
  • the arguments are the same as for + QUAD +
  • +
  • affects paragraphs, epigraphs and footnotes; does not + affect blockquotes +
  • +
+ +

Terminating a document

+ +

+You need do nothing special to terminate a document. When groff +finishes processing the last +input line +of a file, the page is ejected, subject to whatever routines are +needed to complete it (e.g. printing footnotes or adding the page +number). +

+ +

+It happens sometimes, however, that a last line of +running text, +falling on or very near the bottom of the page, tricks groff into +breaking to a new page before terminating. The result is a blank +page at the end of the formatted document. +

+ +

+The situation is rare, generally occurring only when some additional +macro is required after the input text, e.g. to exit a +list +or terminate a +quote. +To prevent it from ever happening, I recommend getting into the habit +of following the final input line of all your mom files with +.EL. +Depending on the +fill mode +in effect, you may also have to append the “join line” +escape, +\c, to the final line.

+ +

+Thus, for normal text at the end of a paragraph, which is in fill +mode, +
+ + and they all lived happily ever after. + .EL + +or for ending a +LIST +(also in fill mode) + + .ITEM + peaches, pears, plums + .EL + .LIST OFF + +whereas, at the end of a +QUOTE +(which is in nofill mode), + + Shall be lifted\[em]nevermore!\c + .EL + .QUOTE OFF + +Notice that the .EL comes after the last line of input +text, not any macros following. +

+ +
+

+Note: +\*[B] +cannot be used as a replacement for .EL when terminating +a document. +

+
+ + + + + + + + +
Back to Table of ContentsTopNext: The document element tags
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/goodies.html b/contrib/mom/momdoc/goodies.html new file mode 100644 index 0000000..7c39e14 --- /dev/null +++ b/contrib/mom/momdoc/goodies.html @@ -0,0 +1,1785 @@ + + + + + + + + + Mom -- Goodies + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: Inline escapes
+ +

Goodies

+ +

+The macros in this section are a collection of useful (and sometimes +nearly indispensable) routines to simplify typesetting. +

+ +
+
+ +
+
+ +
+
+ +

+ + + +
+

Rename macros

+
+ +
+Macro: ALIAS <new name> <old name> +
+ +

+The ALIAS macro may well be your best friend. With it, you can +change the name of a macro to anything you like (provided the new +name is not already being used by mom). +

+ +

+Groff has always been a bit intimidating for new users because +its standard macro packages use very terse macro names. Mom +doesn’t like people to feel intimidated; she wants them +to feel welcome. Consequently, she tries for easy-to-grasp, +self-explanatory macro names. However, mom knows that people have +their own ways of thinking, their own preferences, their own habits. +Some of her macro names may not suit you; they might be too long, +or aren’t what you automatically think of when you want to +do a particular thing, or might conflict with habits you’ve +developed over the years. +

+ +

+If you don’t like one of mom’s macro names, say, +PAGEWIDTH, change it, like this: +
+ + .ALIAS PW PAGEWIDTH + | | + new--+ +--official + name name + +The first argument to ALIAS is the new name you want for a macro. +The second is the “official” name by which the macro is +normally invoked. After ALIAS, either can be used. +

+ +
+

+Tip: +A particularly good candidate for ALIAS is the macro +PT_SIZE. +A more natural name for it would simply be PS, but PS conflicts +with the eqn equation preprocessor and thus mom uses the +longer form. However, if you’re not using eqn, you can +happily rename PT_SIZE to +PS: +
+ + .ALIAS PS PT_SIZE + +

+
+ +
+

+Note: +If you use ALIAS a lot, and always for the same things, consider +creating an aliases file of the form +
+ + .ALIAS <new name> <old name> + .ALIAS <new name> <old name> + .ALIAS <new name> <old name> + ...etc + +Put the file someplace convenient and source it (include it) at the +beginning of your documents with the +INCLUDE +macro. Assuming that you’ve created an aliases file called +mom-aliases in your home directory under a directory called +Mom, you’d source it by placing +
+ + .INCLUDE /home/<username>/Mom/mom-aliases + +at the top of your documents. +

+ +

+If you share documents that make use of an alias file, remember that +other people don’t have the file. Paste the whole thing at +the top of your documents, please. +

+
+ +
+

+Experts: +ALIAS is an alias of .als. You can use either, or mix +’n’ match with impunity. +

+
+ + +
+

Hide input lines from output

+
+ +
+ Macro: SILENT toggle +
+ +

+Alias: COMMENT +

+ +

+Sometimes, you want to “hide” +input lines +from final output. This is most likely to be the case when setting +up string tabs (see the +quickie tutorial on string tabs +for an example), but there are other places where you might want +input lines to be invisible as well. Any place you don’t want +input lines to appear in the output, use the SILENT macro. +

+ +

+SILENT is a toggle. Invoking it without an argument turns it on; +any argument turns it off. E.g., +
+ + .SILENT + A line of text + .SILENT OFF + +The line “A line of text” will not appear in the +output copy. +

+ +

+SILENT is aliased as COMMENT. If you want to insert non-printing +comments into your documents, you may prefer this. +

+ +
+

+Tip: +SILENT does not automatically break an +input line +(see +BR) +when you’re in one of the +fill modes +(JUSTIFY +or +QUAD L | R | C | J). +The same applies to tabs +(typesetting +or +string) +to which you’ve passed the J or QUAD argument. You must +insert .BR yourself, or risk a portion of your text +disappearing into a black hole. +

+
+ + + +
+

Suspend / re-invoke traps

+
+ +
+Macro: TRAP toggle +
+ +

+Traps are vertical positions on the output page at which +you or mom have instructed groff to start doing something +automatically. Commonly, this is near the bottom of the page, where +behind-the-scenes processing is needed in order for one page to +finish and another to start. +

+ +

+Sometimes, traps get sprung when you don’t want them. If this +happens, surround just the offending macros and input lines with +
+ + .TRAP OFF + ... + .TRAP + +TRAP is a toggle, therefore any argument turns it off (i.e., suspends +the trap), and no argument turns it (back) on. +

+ + + +
+

Convert typewriter doublequotes to proper doublequotes

+
+ +
+Macro: SMARTQUOTES [<off>] [ ,, | >> | << ] +
+ +or + +
+Macro: SMARTQUOTES DA | DE | ES | FR | IT | NL | NO | PT | SV +
+ +

+If you invoke SMARTQUOTES without an argument, mom converts all +instances of the inch-mark, ("), also called +a doublequote, into the appropriate instances of true Anglo-American +open-and close-doublequotes. (See +Internationalization +for how to get SMARTQUOTES to behave correctly for non-English +quoting styles.) +

+ +

+Typographically, there is a difference between the inch-mark and +quotation marks—a big difference. Sadly, typewriters and computer +keyboards supply only one: the inch-mark. While using inches for +doublequotes is, and always has been, acceptable in typewriter-style +copy, it has never been, and, God willing, never will be acceptable in +typeset copy. Failure to turn inches into quotes is the first thing +a professional typesetter notices in documents prepared by amateurs. +And you don’t want to look like an amateur, do you? +

+ +

Internationalization

+

+If you invoke SMARTQUOTES with one of the optional arguments +(,, or >> +or <<) you can use +" (i.e. the inch-mark/doublequotes key) +as “cheap” open-and close-quotes when inputting text in +a language other than English, and have mom convert them, on output, +into the chosen open-and close-quote style. +

+ +

+,, opens quotes with “lowered +doublequotes” and closes them with “raised +doublequotes”, as in this ascii approximation: +
+ + ,,Hilfe !`` + + +>> opens quotes with guillemets +pointing to the right, and closes them with guillemets pointing to +the left, as in this ascii approximation: +
+ + >>ZurĂźck !<< + +<< opens quotes with guillemets +pointing to the left, and closes them with guillemets pointing to +the right, as in this ascii approximation: +
+ + <<Mais monsieur! Je ne suis pas ce genre de fille!>> + +Please note: the above arguments to SMARTQUOTES are literal +ASCII characters. ,, is two commas; +<< is two less-than signs; +>> is two greater-than signs. +

+ +

+Alternatively, you can pass SMARTQUOTES the two-letter, ISO 639 +abbreviation for the language you’re writing in, and mom will +output the correct quotes. +
+ + .SMARTQUOTES DA = Danish >>text<< + .SMARTQUOTES DE = German ,,text`` + .SMARTQUOTES ES = Spanish ``text´´ + .SMARTQUOTES FR = French << text >> + .SMARTQUOTES IT = Italian << text >> + .SMARTQUOTES NL = Dutch ´´text´´ + .SMARTQUOTES NO = Norwegian <<text>> + .SMARTQUOTES PT = Portuguese <<text>> + .SMARTQUOTES SV = Swedish >>text>> + +

+ +

+Turn SMARTQUOTES off by passing it any argument not in the argument +list (e.g. OFF, QUIT, X, etc) +

+ +

+If you’re using the +document processing macros +with +PRINTSTYLE TYPESET, +smartquotes are on by default (in the Anglo-American style); with +PRINTSTYLE TYPEWRITE, +it’s off by default (and should probably stay that way). +

+ +

+Finally, if you’re fussy about the kerning of quote marks in +relation to the text they surround, or have special quoting needs, +you have to enter quote marks by hand using groff’s native +inline escapes +for special characters (see man groff-char +for a complete list of special characters). Entering quote marks +this way allows you to use mom’s +inline kerning escapes +to fine-tune the look of quotes. +

+ +
+

+Note: +SMARTQUOTES does not work on single quotes, which most people +input with the apostrophe (found at the right-hand end of the +“home row” on a QWERTY keyboard). Groff will interpret +all instances of the apostrophe as an apostrophe, making the symbol +useless as an open-single-quote. For open single quotes, input +the backtick character typically found under the tilde on most +keyboards. Here’s an example of correct input copy with +single quotes: +
+ + "But she said, `I don’t want to!'" + +

+ +

+Additional note: +Whether or not you have SMARTQUOTES turned on, get into the habit of +entering the foot-and inch-marks, when you need them, with the +inline escapes +\*[FOOT] and +\*[INCH], instead of +' and ". +

+
+ + + +
+

Convert to upper case

+
+ +
+Macro: CAPS toggle +
+ +

+CAPS converts all lower case letters to upper case. +Primarily, it’s a support macro used by the +document processing macros, +but you may find it helpful on occasion. CAPS is a toggle, therefore +no argument turns it on, any argument (OFF, +QUIT, X, etc) turns it off. +
+ + .CAPS + All work and no play makes Jack a dull boy. + .CAPS OFF + + +produces, on output +
+ + ALL WORK AND NO PLAY MAKES JACK A DULL BOY. + +If you wish to capitalise a section of type inline, use the +inline escapes, +\*[UC]...\*[LC] +like this: +
+ + All work \*[UC]and\*[LC] no play makes Jack a dull boy. + + +The above produces, on output +
+ + All work AND no play makes Jack a dull boy. + +

+ +
+

+Note: +\*[LC] must come after a terminating period. +
+ + \*[UC]All work and no play makes Jack a dull boy.\*[LC] + +not + + \*[UC]All work and no play makes Jack a dull boy\*[LC]. + +Conversely, an initial period must come before +\*[UC], or be preceded by \&, like this: +
+ + .\*[UC]start\*[LC] is used to begin document processing. + +or + + \*[UC]\&.start\*[LC] is used to begin document processing. + +Upon output, either will produce +
+ + START is used to begin document processing. + +

+
+ + + +
+

User-defined strings

+
+ +
+Macro: STRING <name> <what you want in the string> +
+ +

+You may find sometimes that you have to type out portions of text +repeatedly. If you’d like not to wear out your fingers, you can +define a string that, whenever you call it by name, outputs whatever +you put into it. +

+ +

+For example, say you’re creating a document that repeatedly uses +the phrase “the Montreal/Windsor corridor”. Instead +of typing all that out every time, you could define a string, like +this: +
+ + .STRING mw the Montreal/Windsor corridor + +Once a string is defined, you can call it any time with the +inline escape +\*[<name>]. Using the example +string above +
+ + The schedule for trains along \*[mw]: + +produces, on output +
+ + The schedule for trains along the Montreal/Windsor corridor: + +

+ +
+

+Note: +Be very careful not to put any spaces at the ends of strings +you’re defining, unless you want them. Everything after +the name argument you pass to STRING goes into the string, +including trailing spaces. It’s a good idea to get into the +habit of using groff’s native commenting mechanism, \", immediately following any string definition +in order to avoid spaces you can’t see, like this +
+ + .STRING mw the Montreal/Windsor corridor\" + +

+
+ +
+

+Experts: +STRING is an alias for ds. You can use either, or mix +’n’ match with impunity. +

+
+ + + +
+

Change the escape character

+
+ +
+Macro: ESC_CHAR <new character> | <anything> +
+ +

+Groff’s and mom’s default escape character is +the backslash. Sometimes, you may want to include a literal +backslash in your document. There are two ways to accomplish +this. One is simply to double the backslash character (\\), which is convenient if you don’t have +a lot of backslashes to input. If you need to input a whole batch +of backslashes (say, when including code snippets in your document), +you can use ESC_CHAR to make the change permanent (until you decide +to restore the escape character to its default, the backslash). +

+ +

+ESC_CHAR with a single character argument changes the escape +character to whatever the argument is. ESC_CHAR with no argument +restores the escape character to the backslash. +

+ +
+

+Important: +Changing the escape character prevents macros, which require that +the backslash be the escape character, from functioning correctly. +Do not introduce any subsequent macros without first restoring the +escape character to its default. +

+
+ +
+

+Experts: +ESC_CHAR is an alias of .ec. Mix ’n’ match +the two with impunity. +

+
+ + + +
+

Get cap-height, x-height and descender depth of a font

+
+ +
+Macro: SIZESPECS +
+ +

+Whenever you need to get the +cap-height, +x-height +or +descender +depth of type at the current point size, invoke .SIZESPECS, which takes no argument. +The dimensions are stored in the string registers +\*[$CAP_HEIGHT], +\*[$X_HEIGHT], +and +\*[$DESCENDER], respectively, in +machine units +to which the +unit of measure, +u, is already appended. +

+ +

+Thus, if you wanted to advance 2 inches from your current position +on the page plus the cap-height of the current point size of type +
+ + .PT_SIZE <n> + .SIZESPECS + .ALD 2i+\*[$CAP_HEIGHT] + +would do the trick. +

+ + + +
+

Single underscore

+
+ +
+Macro: UNDERSCORE [ <distance below baseline> ] [ PREFIX <prefix> ] [ SUFFIX <suffix> ] "<string>" +
+ +

+• <distance below baseline> requires a unit of measure +

+ +

+By default, UNDERSCORE places an underscore 2 points beneath the +required +string argument. +The string must be enclosed in double-quotes, like this: +
+ + .UNDERSCORE "Unmonitored monopolies breed high prices and poor products" + +If you wish to change the distance of the rule from the baseline, +use the optional argument +<distance below baseline> +(with a unit of measure). +
+ + .UNDERSCORE 3p "Unmonitored monopolies breed high prices and poor products" + +The above places the upper edge of the underscore 3 points below the +baseline. +

+ +
+

+Tip: +UNDERSCORE can also be used for strikethrough effects by supplying a +negative value to the distance argument. +

+
+ +

+PREFIX and SUFFIX allow you to add +non-underscored punctuation (or other glyphs) to the beginning +and/or end of the underscored string. If the argument to either +PREFIX or SUFFIX contains spaces, surround the +argument with double-quotes. For example, the following underscores +the text string but not the surrounding punctuation. +
+ + .UNDERSCORE PREFIX ( SUFFIX .) "Unmonitored monopolies breed high prices and poor products" + +

+ +
+

+Note: +UNDERSCORE does not work across line breaks in output copy, which is +to say that you can’t underscore a multi-line passage simply +by putting the text of the whole thing in the string you pass to +UNDERSCORE. If you need to underscore several lines of type, use +UNDERLINE. +

+
+ +
+

+Additional note: +In +nofill modes, +UNDERSCORE causes a break before and after, meaning the underscored +word or phrase will appear as a separate line in your output. If +you wish to embed an underscored word or phrase into non-filled +text, temporarily change to the corresponding fill mode with +QUAD +and insert breaks manually with +BR +as appropriate, reverting to the original nofill mode afterwards. +

+
+ +

Controlling the weight of underscores

+

+The weight (thickness) of underscores may be controlled with the +macro UNDERSCORE_WEIGHT. Thus, if you want underscores with a +weight of 1-1/2 points, you’d invoke: +
+ + .UNDERSCORE_WEIGHT 1.5 + +prior to invoking .UNDERSCORE. Every +subsequent instance of .UNDERSCORE will use +this weight. +

+ +

+Mom’s default underscore weight is 1/2 point. +

+ +
+

+Note: +UNDERSCORE_WEIGHT also sets the weight of +double underscores. +

+
+ +

Colourising underscored text

+

+If you want underscored text to be in a different colour from the +text around it, use the +COLOR +macro rather than the +inline escape for changing colour. +In other words, assuming your prevailing text colour is black and +you want underscored text in red +
+ + .COLOR red + .UNDERSCORE "text to underscore" + .COLOR black + +rather than +
+ + .UNDERSCORE "\*[red]text to underscore\*[black]" + +The latter will render the text in red but the underscore in black. +You can, of course, use this to create rainbow effects if that's +what you want, e.g. text in red, underscore in blue, and prevailing +type in black: +
+ + .UNDERSCORE "\*[red]text to underscore\*[blue]" + .COLOR black + +

+ + + +
+

Double underscore

+
+ +
+Macro: UNDERSCORE2 [ <distance below baseline> [ <distance between rules> ] [ PREFIX <prefix> ] [ SUFFIX <suffix> ] "<string>" +
+ +

+• <distance below baseline> +and +<distance between rules> +require a unit of measure +

+ +

+By default, UNDERSCORE2 places a double underscore 2 points beneath +the required +string argument. +The string must be enclosed in double-quotes, like this: +
+ + .UNDERSCORE2 "Unmonitored monopolies breed high prices and poor products" + +The default distance between the two rules is 2 points, measured +from the bottom edge of the upper rule to the top edge of the lower +one. +

+ +

+If you wish to change the distance of the double underscore from the +baseline, +use the optional argument +<distance below baseline> +(with a unit of measure), e.g. +
+ + .UNDERSCORE2 3p "Unmonitored monopolies breed high prices and poor products" + +which places the upper edge of the first rule of the double +underscore 3 points below the baseline. +

+ +

+If you wish to change the distance between the two rules as well, +use the second optional argument +<distance between rules> +(with a unit of measure). The distance between the two rules +is measured from the bottom edge of the upper rule to the top +edge of the lower one. Be aware that you must give a value for +<distance below baseline> if you want to +use <distance between rules>. +

+ +

+PREFIX and SUFFIX allow you to add +non-underscored punctuation (or other glyphs) to the beginning +and/or end of the double-underscored string. If the argument to +either PREFIX or SUFFIX contains spaces, +surround the argument with double-quotes. For example, the +following double-underscores the text string but not the surrounding +punctuation. +
+ + .UNDERSCORE2 PREFIX ( SUFFIX .) "Unmonitored monopolies breed high prices and poor products" + +The weight (thickness) of double underscores may be controlled with +the macro +UNDERSCORE_WEIGHT +(q.v). +

+ +

+See +here +for advice on colourising double-underscored text. +

+ +
+

+Note: +In +nofill modes, +UNDERSCORE2 causes a break before and after, meaning the double-underscored +word or phrase will appear as a separate line in your output. If +you wish to embed a double-underscored word or phrase into non-filled +text, temporarily change to the corresponding fill mode with +QUAD +and insert breaks manually with +BR +as appropriate, reverting to the original nofill mode afterwards. +

+
+ + +
+

Underline

+
+ +
+Macro: UNDERLINE toggle +
+ +

+The distinction between underscoring and underlining is that +underscoring is suitable for occasional effects (a word here, +a phrase there), whereas underlining underlines whole passages +of type. Furthermore, you cannot colourise underlining. +There’s a special macro, +UNDERLINE_SPECS, +to control the weight and distance from the baseline of the +underline. +

+ +

+Lastly, files that use UNDERLINE must be processed with +
+ + pdfmom -Tps filename.mom | ps2pdf - filename.pdf + +since groff’s pdf driver does not recognize UNDERLINE. +

+ +

+Note that +PRINTSTYLE TYPEWRITE +uses UNDERLINE to underline italics +and pseudo-italics (SLANT) +by default. The default may be changed (see +Underlining of italics) +but if it's what you want, you must process your document as shown +above. +

+ +

+UNDERLINE is a toggle macro, therefore you invoke it by itself (i.e. +with no argument) to initiate underlining, and with any argument +(OFF, QUIT, END, X, etc) +to turn it off. +

+ +
+

+Note: +Underlining may also be turned on and off +inline +with the escapes +\*[UL]...\*[ULX]. +

+ +

+Additional note: +In document processing, neither .UNDERLINE nor +\*[UL] persist past the current document element tag. +For example, if you turn underlining on in a paragraph +(.PP), +your next paragraph will not be underlined. +

+
+ +

UNDERLINE_SPECS

+ +

+The weight of underlining and the distance from the baseline is +set with +
+ + .UNDERLINE_SPECS <weight> <distance> + +The <weight> argument can be expressed in any +unit of measure +you like, but points is the most usual. Mom’s default is 1/2 point +(.5p). The same holds for the <distance> argument; +mom’s default is 1-1/4 points (1.25p). +

+ + + +

INLINE ESCAPE FOR UNDERLINING

+ +

+The macro pair, +.UNDERLINE / +.UNDERLINE OFF, and the inline escapes, +\*[UL] / \*[ULX], are +functionally identical, hence, in +fill +modes +
+ + Which should I heed? + .UNDERLINE + Just do it + .UNDERLINE OFF + or + .UNDERLINE + just say no? + .UNDERLINE OFF + +produces the same result as +
+ + Which should I heed? \*[UL]Just do it\*[ULX] or \*[UL]just say no?\*[ULX] + +In either case, this is a misuse of UNDERLINE. +UNDERSCORE +is preferable. +

+ + + +
+

Insert equalized whitespace into lines

+
+ +
+Macro: PAD "<string with pad markers inserted>" [ NOBREAK ] +
+ +

+With PAD, you can insert proportional amounts of whitespace into a +line. The optional NOBREAK +argument tells mom not to advance on the page after the PAD macro +has been invoked. +

+ +

+PAD calculates the difference between the length of text on the line +and the distance remaining to its end, then inserts the difference +(as whitespace) at the place(s) you specify. +

+ +

+Take, for example, the following relatively common typesetting +situation, found at the bottom of legal agreements: +
+ + Date Signature | + +

+ +

+The person signing the agreement is supposed to fill in the date +as well as a signature. Space needs to be left for both, but the +exact amount is neither known, nor important. All that matters is +that there be a little space after Date, and rather more space after +Signature. (In the above, | represents the +end of the line at the prevailing line length.) +

+ +

+The +pad marker +(see below) is # (the pound or number sign +on your keyboard) and can be used multiple times in a line. With +that in mind, here’s how you’d input the Date/Signature line +(assuming a length of 30 picas): +
+ + .LL 30P + .PAD "Date#Signature###" + +

+ +

+When the line is output, the space remaining on the line, after +"Date" and "Signature" have been taken into +account, is split into four (because there are four # signs). One +quarter of the space is inserted between Date and Signature, the +remainder is inserted after Signature. +

+ +
+

Example of PAD usage

+

+One rarely wants merely to insert space in a line; one usually wants +to fill it with something, hence PAD is particularly useful in +conjunction with +string tabs. +The following uses the Date/Signature example, above, but adds +rules into the whitespace through the use of string tabs and +mom’s +inline escape +\*[RULE]. +
+ + .LL 30P + .PAD "Date \*[ST1]#\*[ST1X] Signature \*[ST2]###\*[ST2X]" NOBREAK + .ST 1 J + .ST 2 J + .TAB 1 + \*[RULE] + .TN + \*[RULE] + .TQ + +

+ +

+Here’s what the example does: +

+
    +
  1. Pads the Date/Signature line with a shorter space for Date + (#) and a longer space for Signature + (###), encloses the padded space with string tabs + markers, and outputs the line without advancing on the page. +
  2. +
  3. Sets the quad for the two string tabs (in this instance, justified). +
  4. +
  5. Calls the first string tab and draws a rule to its full + length. +
  6. +
  7. Calls the second tab with + TN + (which moves to tab 2 and stays on the same baseline) + then draws a rule to the full length of string tab 2. +
  8. +
+ +

+Often, when setting up string tabs this way, you don’t want the +padded line to print immediately. To accomplish this, use +SILENT. +See the +quickie tutorial on string tabs +for an example. +

+
+ +
+

+Note: +Because the pound sign +(#) is used as the pad marker, you +can’t use it as a literal part of the pad string. If you need +the sign to appear in the text of a padded line, change the pad +marker with +PAD_MARKER. +Also, be aware that # as a pad marker +only applies within the PAD macro; at all other times it prints +literally, just as you’d expect. +

+ +

+Another important consideration when using PAD is that because the +string must be enclosed in double-quotes, you can’t use the +double-quote (") as part of the string. The +way to circumvent this is to use the groff +inline escapes +\(lq and \(rq +(leftquote and rightquote respectively) whenever double-quotes are +required in the string passed to PAD. +

+
+ + + +
+

Change/set the marker used with PAD

+
+ +
+Macro: PAD_MARKER "<character to use as the pad marker> +
+ +

+If you need to change mom’s default pad marker (#), either because you want a literal # in +the padded line, or simply because you want to use another character +instead, use PAD_MARKER, whose argument is the new pad marker +character you want. +
+ + .PAD_MARKER @ + +changes the pad marker to @. +

+ +

+Once you’ve changed the pad marker, the new marker remains in effect +for every instance of +PAD +until you change it again (say, back to the pound sign). +

+ + + +
+

Inline escape to add leaders to a line

+
+ +
+Inline: \*[LEADER] +
+ +

+Whenever you want to fill a line or tab with +leaders, +use the +inline escape +\*[LEADER]. The remainder of the line or +tab will be filled with the leader character. Mom’s default +leader character is a period (dot), but you can change it to any +character you like with +LEADER_CHARACTER. +

+ +
+

+Note: +\*[LEADER] fills lines or tabs right to +their end. You cannot insert leaders into a line or tab and have +text following the leader on the same line or in the same tab. +Should you wish to achieve such an effect typographically, create +tabs for each element of the line and fill them appropriately with +the text and leaders you need. +String tabs +are perfect for this. An example follows. +
+ + .LL 30P + .PAD "Date\*[ST1]#\*[ST1X] Signature\*[ST2]###\*[ST2X]" NOBREAK + .EL + .ST 1 J + .ST 2 J + .TAB 1 + \*[LEADER] + .TN + \*[LEADER] + .TQ + +

+ +

+The PAD line sets the words Date and Signature, and marks string +tabs around the pad space inserted in the line. The string tabs are +then "set", called, and filled with leaders. The result +looks like this: +
+ + Date.............Signature..................................... + +

+
+ + + +
+

Change/set the leader character

+
+ +
+Macro: LEADER_CHARACTER <character> +
+ +

+LEADER_CHARACTER takes one argument: a single character you would +like to be used for +leaders. +(See +\*[LEADER] +for an explanation of how to fill lines with leaders.) +

+ +

+For example, to change the leader character from mom’s +default (a period) to the underscore character, enter +
+ + .LEADER_CHARACTER _ + +

+ +
+

+Tip: +A particularly useful function of LEADER_CHARACTER is that it can be +used to increase the spacing of mom’s default leaders. This is +done by assigning to LEADER_CHARACTER both the period (dot) and a +space. The technique requires a little low-level groffing: +
+ + .char \[leader] . \" + .LEADER_CHARACTER \[leader] + +The .char +primitive +allows you to define a character called leader, to which +you assign a period and a space. The \", which, in +groff, is used to add non-printing comments to a line, is not +strictly necessary. Its presence here lets you see that +there’s a space after the period. +

+
+ + + +
+

Drop caps

+
+ +
+Macro: DROPCAP <dropcap letter> <number of lines to drop> [ COND <percentage> | EXT <percentage> ] +
+ +

+The first two arguments to DROPCAP are the letter you want to be the +drop cap +and the number of lines you want it to drop. By default, mom uses +the current family and font for the drop cap. +

+ +

+The optional argument (COND or EXT) indicates +that you want the drop cap condensed (narrower) or extended (wider). +If you use COND or EXT, you must +follow the argument with the percentage of the letter’s normal +width you want it condensed or extended. No percent sign +(%) is required. +

+ +

+Mom will do her very best to get the drop cap to line up with the +first line of text indented beside it, then set the correct number +of indented lines, and restore your left margin when the number of +drop cap lines has been reached. +

+ +

+Beginning a paragraph with a drop cap “T” looks like this: +
+ + .DROPCAP T 3 COND 90 + he thousand injuries of Fortunato I had borne as best I + could, but when he ventured upon insult, I vowed revenge. + You who so well know the nature of my soul will not suppose, + however, that I gave utterance to a threat... + +

+ +

+The drop cap, slightly condensed but in the current family and font, +will be three lines tall, with whatever text fills those three +lines indented to the right of the letter. The remainder of the +paragraph’s text will revert to the left margin. +

+ +
+

+Note: +When using the +document processing macro +PP, +DROPCAP only works +

+
    +
  • with initial paragraphs (i.e. at the start of the document, + or after + HEADING),
  • +
  • when .DROPCAP comes immediately after .PP,
  • +
  • the + PRINTSTYLE + is TYPESET.
  • +
+

+If these conditions aren’t met, DROPCAP is silently ignored. +

+ +

+Additional note: +If you have dropcaps after +HEADINGs, +you must increase the NEEDS argument to +HEADING_STYLE +to match the number of dropcap lines. For example, assuming +dropcaps that are three lines tall: +
+ + .HEADING_STYLE 1 NEEDS 3 + +

+
+ +
+

+Warning: +DROPCAP puts a bit of a strain on resource-challenged systems. If +you have such a system and use drop caps extensively in a document, +be prepared for a wait while mom does her thing. +

+
+ +

Support macros for DROPCAP

+

+Drop caps are the bane of most typesetters’ existence. +It’s very difficult to get the size of the drop cap right +for the number of drop lines, especially if the drop cap is in a +different family from the prevailing family of running text. Not +only that, but there’s the gutter around the drop cap to take +into account, plus the fact that the letter may be too wide or too +narrow to look anything but odd or misplaced. +

+ +

+Mom solves the last of these problems with the COND and +EXT arguments. The rest she solves with macros that +change the default behaviour of DROPCAP, namely +

+ + +

+These macros must, of course, come before you invoke DROPCAP. +

+ +

• DROPCAP_FAMILY

+

+Set the drop cap family by giving DROPCAP_FAMILY the name of the +family you want, e.g. +
+ + .DROPCAP_FAMILY H + +which will set the family to Helvetica for the drop cap only. +

+ +

• DROPCAP_FONT

+

+Set the drop cap font by giving DROPCAP_FONT the name of the font +you want, e.g. +
+ + .DROPCAP_FONT I + +which will set the font to italic for the drop cap only. +

+ +

• DROPCAP_ADJUST

+

+If the size mom calculates for the drop cap isn’t precisely +what you want, you can increase or decrease it with DROPCAP_ADJUST, +like this: e.g. +
+ + .DROPCAP_ADJUST +1 + +or +
+ + .DROPCAP_ADJUST -.75 + +

+ +

+DROPCAP_ADJUST only understands +points, +therefore do not append any +unit of measure +to the argument. And always be sure to prepend the plus or +minus sign, depending on whether you want the drop cap larger or +smaller. +

+ +

• DROPCAP_COLOR

+

+If you’d like your drop cap colourized, simply invoke +.DROPCAP_COLOR <color> with the name of a +colour you’ve already created (“initialized”) with +NEWCOLOR +or +XCOLOR. +Only the drop cap will be colourized; all other text will remain at +the current colour default (usually black). +

+ +

• DROPCAP_GUTTER

+

+By default, mom puts three points of space between the drop cap +and the text indented beside it. If you want another value, use +DROPCAP_GUTTER (with a unit of measure), like this: +
+ + .DROPCAP_GUTTER 6p + +

+ + + +
+

Superscript

+
+ +
+Inlines: \*[SUP]...\*[SUPX] +
+ +

+Superscripts are accomplished +inline. +Whenever you need one, typically for numerals, all you need +to do is surround the superscript with the inlines above. +\*[SUP] begins superscripting; +\*[SUPX] turns it off. +

+ +

+If your running type is +pseudo-condensed +or +pseudo-extended +and you want your superscripts to be equivalently pseudo-condensed +or -extended, use +
+\*[CONDSUP]...\*[CONDSUPX] or +\*[EXTSUP]...\*[EXTSUPX]. +

+ +

+The superscript inlines are primarily used by the +document processing macros +for automatic generation of numbered footnotes. However, you may +find them useful for other purposes. +

+ +
+

+Note: +Mom does a pretty fine job of making superscripts look good in any +font and at any size. If you’re fussy, though (and I am), +about precise vertical placement, kerning, weight, size, and so on, +you may want to roll your own solution. +

+
+ +

SUPERSCRIPT RAISE AMOUNT

+

+By default, mom raises superscripts 1/3 of an +em +above the baseline. If you’re not happy with this default, +you can change it by invoking SUPERSCRIPT_RAISE_AMOUNT with the +amount you want them raised. A +unit of measure +must be appended directly to the amount. Thus, if you want +superscripts raised by 3 +points +instead of 1/3 em, you’d do +
+ + .SUPERSCRIPT_RAISE_AMOUNT 3p + +and all subsequent superscripts would be raised by 3 points. +

+ + + +
+

Centre blocks of type

+
+ +
+Macro: CENTER_BLOCK <toggle> +
+ +

+Blocks of type sometimes need to be centred on the page with their quad +direction (left, centre, right) left intact. The +document processing macros +QUOTE +and +BLOCKQUOTE +take care of this automatically, but there are other situations +where you may want to centre blocks of type. An example might be +left-quadded +nested lists. +

+ +

+Whenever you want to centre a block of type on the page, surround it +with .CENTER_BLOCK/.CENTER_BLOCK OFF (or QUIT, +X, etc). +

+ +
+

Hanging characters

+
+
+
+Macro: LEFT_HANG <character> [ <gutter> ] +
+

+• left-hung characters +

+ +
+Inline: \*[HANG <character>] +
+

+• right-hung characters +

+ +

+Hung characters, frequently punctuation, fall outside the left or +right margin. Their purpose is usually to fine-tune justification. +Consider the following: +

+ + + + + + + + +
+“Play the man, Master Ridley; we +shall this day light such a candle, +by God's grace, in England, as I +trust shall never be put out.” + +   + +“ +
+
+
+
+
+Play the man, Master Ridley; we +shall this day light such a candle, +by God's grace, in England, as I +trust shall never be put out.”
+ +

+In the right hand example, the opening double-quote hangs outside +the left margin, creating a uniform left margin for the text. +

+ +

Left hung characters

+ +

+LEFT_HANG hangs its first argument, the character to be hung, to +the left of the left margin. The optional second argument lets you +specify an amount of space to insert between the hung character and +the text. +

+ +

+Input text after LEFT_HANG must begin with the character to be hung +PLUS a +horizontal motion +corresponding to <gutter> if one was given. +If the hung character is a left double-quote, \[lq] +must be used as the argument to LEFT_HANG and the usual keyboard +double-quote (") entered as the input text so as not to +confuse +SMARTQUOTES +The following example demonstrates: +
+ + .LEFT_HANG \[lq] 1p + "\*[FWD 1p]This line will have its opening double-quote + plus one point of space hung outside the left margin." + +

+ +

+Note that what follows LEFT_HANG must be an input line and therefore +it cannot be used to left-hang a +HEADING +character. +

+ +
+

+Important: +Versions of mom lower than 2.5_a that included LEFT_HANG required +that the character and its gutter be entered as a single, +concatenated argument, using horizontal motions to establish the +gutter +(e.g. +FWD, +BCK). +Documents created with versions prior to 2.5_a may have to be +updated. +

+
+ +

Right hung characters

+ +

+The \*[HANG c] inline escape hangs its argument outside +the right margin of justified or quad right copy. The argument may +be a single character, or a single character preceded by a +horizontal motion, effectively establishing a gutter between the +right margin and the hung character: +
+ + This line will have its closing period hung outside + the right margin with a one point gutter\*[HANG \*[FWD 1p].] + +If the hung character is a right double-quote, "\[rq]" +must be used as the argument (that is, the \[rq] +character surrounded by double-quotes). The double-quotes are +required for all special characters of the form +\[name]. +Horizontal motion, if any, must fall inside the double-quotes: +
+ + ...and they all lived happily ever after.\*[HANG "\*[FWD 1p]\[rq]"] + +

+ +

+If the hung character is a hyphen, +\*[HANG -] +must come at the end of an +input line. +This restriction does not apply to other characters, which may come +anywhere in an input line provided that, on output, the line breaks +at the point you introduced the hung character. +

+ +

+For the exceptionally fussy, \*[HANG] may also be used to +improve visual centring; when text is centred, \*[HANG c] +hangs the character to the right of the centred line instead of the +margin. +

+ +

+ + + + + + + + +
Back to Table of ContentsTopNext: Inline escapes
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/graphical.html b/contrib/mom/momdoc/graphical.html new file mode 100644 index 0000000..0f373b7 --- /dev/null +++ b/contrib/mom/momdoc/graphical.html @@ -0,0 +1,689 @@ + + + + + + + + + Mom -- Graphical Objects + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: Document processing
+ +

Graphical objects

+ + + +

+ +

Introduction to graphical objects

+ +

+Groff has a number of +inline escapes +for drawing rules, polygons, ellipses and splines. All begin with +\D (presumably for “Draw”) and are documented +in the groff info manual: +
+ + info groff \D + +The escapes allow you to draw just about any simple graphical object +you can think of, but owing to their syntax they’re not always easy +to read, which can make tweaking them difficult. Additionally, +while they perform in a consistent manner, they don’t +always perform in an expected manner. +

+ +

+Experience shows that the most common graphical elements typesetters +need are rules (horizontal and vertical), boxes, and circles (or +ellipses). For this reason, mom provides macros +to draw these objects in an easy-to-understand way; the results are +predictable, and mom’s syntax makes fixes or tweaks +painless. +

+ +

+For example, if you want to draw a 2-inch square outline box at the left +margin using groff’s \D escapes, it looks like this: +
+ + back up + by + weight + +-------+ + | | + \D't 500'\h'-500u'\D'p 2i 0 0 2i -2i 0 0 -2i' + | | | | + +-------+ +------------------------+ + set rule draw box, 1 line at a time + weight + + +Obviously, this isn’t very efficient for something as simple as a +box. +

+ +

+Here’s the same box, drawn with mom’s box drawing +macro +DBX: +
+ + left margin indent--+ +--box width + | | + .DBX .5 0 2i 2i + | | + rule weight--+ +--box depth + (in points) + +

+ +

+Mom’s graphical object macros allow—in fact, +require—giving the rule weight (“thickness”) for +the object (or saying that you want it filled), an indent from the +left margin where the object begins, the dimensions of the object, +and optionally a colour for the object. +

+ +

+There are no defaults for the arguments to mom’s graphical +object macros, which means you must supply the arguments every time +you invoke them. +

+ +
+

+Note: +As stated above, mom only provides macros for commonly-used +graphical objects (rules, boxes, circles). More complex objects +(polygons, non-straight lines, splines) must be drawn using +groff’s \D escapes. +

+
+ +

Graphical object behaviour

+ +

+Mom’s graphical object macros all behave in the following, +carved-in-stone ways: +

+
    +
  1. Objects are drawn from the + baseline + down, including horizontal rules.
  2. +
  3. Objects begin precisely at the left indent supplied as + an argument to the macro.
  4. +
  5. Objects are drawn from left to right.
  6. +
  7. Enclosed objects (boxes, circles) are drawn from the + perimeter inward.
  8. +
  9. Objects return to their horizontal/vertical point of origin.
  10. +
+ +

+The consistency means that once you’ve mastered the very +simple order of arguments that applies to invoking graphical +object macros, you can draw objects with full confidence that you +know exactly where they’re placed and how much room they +occupy. Furthermore, because all return to their point of origin, +you’ll know exactly where you are on the page. +

+ +

Order of arguments

+ +

+The order of arguments to the graphical object macros is the same +for every macro: +

+
    +
  • the rule weight +
      +
    • the single word SOLID may be used in place + of weight if you want boxes or circles filled
    • +
  • +
  • the indent from the current left margin at which to begin + the object +
  • +
  • the width of the object if applicable
  • +
  • the depth of the object if applicable
  • +
  • the colour of the object (optional)
  • +
+ +
+

Graphical objects macros

+ +
    +
  • DRH + – horizontal rules
  • +
  • DRV + – vertical rules
  • +
  • DBX + – box
  • +
  • DCL + – circles or ellipses
  • +
+
+ + + +
+

Drawing horizontal rules

+
+ +
+Macro: DRH <none> | <weight> <indent> <width> [<colour>] +
+ +

+•  +the argument to <weight> is in +points, +but do not append the +unit of measure, +p +
+•  +<indent> +and +<width> +require a unit of measure +
+•  +arithmetic expressions to +<indent> +and +<width> +must be surrounded by parentheses +

+ +

+If all you want is to draw a rule from your current left +margin to your current right margin (in other words, a "full +measure" rule), you may invoke .DRH without any +arguments. +

+
+

+Note: +DRH is the only graphical object macro that may be invoked +without arguments. The weight (“thickness”) of +the rule is determined by the argument you last gave the +macro +RULE_WEIGHT. +DRH, used this way, is exactly equivalent to entering the +inline escape +\*[RULE]. +

+
+ +

+To draw horizontal rules of a specified width, you must, at +a minimum, supply DRH with the arguments weight, +indent (measured from the current left margin) and +width. +

+ +

+Optionally, you may give a color argument. The colour +may be either one defined with +NEWCOLOR, +or a named X-color initialized with +XCOLOR, +or an X-color alias (again, initialized with XCOLOR). +

+ +

+Say, for example, you want to draw a 1-1/4 point horizontal rule +that starts 2 picas from the current left margin and runs for 3 +inches. To do so, you’d invoke .DRH like this: +
+ + weight width + | | + .DRH 1.25 2P 3i + | + indent + +(Note that the rule weight argument, which is expressed in points, +must not have the unit of measure p appended to it.) +

+ +

+If, in addition, you want the rule blue: +
+ + .DRH 1.25 2P 3i blue + +

+ +

How mom handles the positioning of horizontal rules

+ +

+Horizontal rules are drawn from left to right, and from the baseline +down. “From the baseline down” means that if you request +a rule with a weight of four points, the four points of rule fall +entirely below the baseline. +

+ +

+Furthermore, after the rule is drawn, mom returns you to the current +left margin, at the same vertical position on the page as when DRH +was invoked. In other words, DRH causes no movement on the page, +either horizontal or vertical. +

+ + + +
+

Drawing vertical rules

+
+ +
+Macro: DRV <weight> <indent> <depth> [<colour>] +
+ +

+•  +the argument to <weight> is in +points, +but do not append the +unit of measure, +p +
+•  +<indent> +and +<depth> +require a unit of measure +
+•  +arithmetic expressions to +<indent> +and +<depth> +must be surrounded by parentheses +

+ +

+To draw vertical rules of a specified depth, you must, at +a minimum, supply DRV with the arguments weight, +indent (measured from the current left margin) and +depth. +

+ +

+Optionally, you may give a color argument. The colour +may be either one defined with +NEWCOLOR, +or a named X-color initialized with +XCOLOR, +or an X-color alias (again, initialized with XCOLOR). +

+ +

+Say, for example, you want to draw a 3/4-point vertical rule that +starts 19-1/2 picas from the current left margin and has a depth of +6 centimetres. To do so, you’d invoke .DRV like +this: +
+ + weight depth + | | + .DRV .75 19P+6p 6c + | + indent + +(Note that the rule weight argument, which is expressed in points, +must not have the unit of measure p appended to it.) +

+ +

+If, in addition, you want the rule red: +
+ + .DRV .75 19P+6p 6c red + +

+ +

How mom handles the positioning of vertical rules

+ +

+Vertical rules are drawn from the baseline down, and from left to +right. "Left to right" means that if you request a rule +with a weight of four points, the four points of rule fall entirely +to the right of the indent given to DRV. +

+ +

+Furthermore, after the rule is drawn, mom returns you to the current +left margin, at the same vertical position on the page as when DRV +was invoked. In other words, DRV causes no movement on the page, +either horizontal or vertical. +

+ + + +
+

Drawing boxes

+
+ +
+Macro: DBX <weight>|SOLID <indent> <width>|FULL_MEASURE <depth> [<color>] +
+ +

+•  +the argument to <weight> is in +points, +but do not append the +unit of measure +p +
+• <indent>, +<width>, +and +<depth> +require a unit of measure +
+•  +arithmetic expressions to +<indent>, +<width>, +and +<depth> +must be enclosed in parentheses. +

+ +

+To draw boxes you must, at a minimum, supply DBX with the arguments +weight or SOLID, indent, +width or FULL_MEASURE, and depth. +

+ +

+weight is the rule weight of outlined boxes, given in +points but without the +unit of measure +p appended. +

+ +

+If SOLID is given as the first argument, the box is +filled rather than outlined and no weight argument should +be supplied. +

+ +

+indent is measured from the current left margin. If +FULL_MEASURE is given, indent should be set to +“0”. +

+ +

+width is the width of the box with a +unit of measure +appended, caclculated from indent argument. +

+ +

+If FULL_MEASURE is given instead of width, +it circumvents having to calculate the width when left and/or right +indents are in effect; mom draws the box from the current left +margin to the current right margin. When no indents are in effect, +FULL_MEASURE or \n[.l]u—the groff +way of saying “the current line length”—have the +same effect. +

+ +

+Optionally, you may give a color argument. The colour +may be either one defined with +NEWCOLOR, +or a named X-color initialized with +XCOLOR, +or an X-color alias (again, initialized with XCOLOR). +

+ +

+Say, for example, you want to draw a 1/2 point outline box that +starts one inch from the current left margin and has the dimensions +12 picas x 6 picas. To do so, you’d invoke .DBX +like this: +
+ + indent depth + | | + .DBX .5 1i 12P 6P + | | + weight width + +(Note that the box weight argument, which is expressed in points, +must not have the unit of measure p appended to it.) +

+ +

+If you want the same box, but solid (“filled”) rather +than drawn as an outline: +
+ + .DBX SOLID 1i 12P 6P + +Additionally, if you want the box green: +
+ + .DBX .5 1i 12P 6P green + +or + + .DBX SOLID 1i 12P 6P green + +

+ +

How mom handles the positioning of boxes

+ +

+Boxes are drawn from the baseline down, from left to right, and +from the perimeter inward. “From the perimeter +inward” means that if you request a box weight of six points, +the 6-point rules used to draw the outline of the box fall entirely +within the dimensions of the box. +

+ +

+Furthermore, after the box is drawn, mom returns you to the current +left margin, at the same vertical position on the page as when DBX +was invoked. In other words, DBX causes no movement on the page, +either horizontal or vertical. +

+ + + +
+

Drawing circles (ellipses)

+
+ +
+Macro: DCL <weight>|SOLID <indent> <width>|FULL_MEASURE <depth> [<color>] +
+ +

+•  +the argument to <weight> is in +points, +but do not append the +unit of measure +p +
+• <indent>, +<width>, +and +<depth> +require a unit of measure +
+•  +arithmetic expressions to +<indent>, +<width>, +and +<depth> +must be enclosed in parentheses. +

+ +

+To draw circles you must, at a minimum, supply DCL with the arguments +weight or SOLID, indent, +width or FULL_MEASURE, and depth. +

+ +

+weight is the rule weight of outlined circles, given in +points but without the unit of measure +unit of measure +p appended. +

+ +

+If SOLID is given as the first argument, the circle is +filled rather than outlined and no weight argument should +be supplied. +

+ +

+indent is measured from the current left margin. If +FULL_MEASURE is given, indent should be set to +“0”. +

+ +

+width is the width of the circle with a +unit of measure +appended, caclculated from indent argument. +

+ +

+If FULL_MEASURE is given instead of width, +it circumvents having to calculate the width when left and/or right +indents are in effect; mom draws the circle from the current left +margin to the current right margin. When no indents are in effect, +FULL_MEASURE or \n[.l]u—the groff +way of saying “the current line length”—have the +same effect. +

+ +

+Optionally, you may give a color argument. The colour +may be either one defined with +NEWCOLOR, +or a named X-color initialized with +XCOLOR, +or an X-color alias (again, initialized with XCOLOR). +

+ +

+Say, for example, you want to draw a 1/2 point outline circle that +starts one inch from the current left margin and has the dimensions +12 picas x 6 picas. To do so, you’d invoke .DCL +like this: +
+ + indent depth + | | + .DCL .5 1i 12P 6P + | | + weight width + +(Note that the circle weight argument, which is expressed in points, +must not have the unit of measure p appended to it.) +

+ +

+If you want the same circle, but solid (“filled”) rather +than drawn as an outline: +
+ + .DCL SOLID 1i 12P 6P + +Additionally, if you want the circle green: +
+ + .DCL .5 1i 12P 6P green + +or + + .DCL SOLID 1i 12P 6P green + +

+ + +

How mom handles the positioning of circles (ellipses)

+ +

+Circles (ellipses) are drawn from the baseline down, from left +to right, and from the perimeter inward. “From the +perimeter inward” means that if you request a circle weight of +six points, the 6-point rule used to draw the outline of the circle +or ellipse falls entirely within the dimensions of the +circle or ellipse. +

+ +

+Furthermore, after the circle is drawn, mom returns you to the +current left margin, at the same vertical position on the page as +when DCL was invoked. In other words, DCL causes no movement on the +page, either horizontal or vertical. +

+ +

+ + + + + + + + +
Back to Table of ContentsTopNext: Document processing
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/headfootpage.html b/contrib/mom/momdoc/headfootpage.html new file mode 100644 index 0000000..1c11ab1 --- /dev/null +++ b/contrib/mom/momdoc/headfootpage.html @@ -0,0 +1,2341 @@ + + + + + + + + + Mom -- Document processing, page headers/footers and pagination + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: Recto/verso printing, collating
+ +

Page headers/footers, pagination

+ + + +

+ +

Table of contents

+ +

Managing page headers and footers

+ +

Control macros for headers/footers

+ +

User-defined, single string recto/verso headers/footers

+ +

Headers and footers on the same page

+

Pagination

+ +

Inserting blank pages into a document

+ +

+ +

Managing page headers and footers

+ +
+

+Note: +Because headers and footers are virtually identical, this +documentation addresses itself only to headers. In all cases, +unless otherwise noted, descriptions of headers describe footers as +well. +

+ +

+Furthermore, any +control macro +that begins with HEADER_ may be used to control footers, simply by +replacing HEADER_ with FOOTER_. +

+
+ +

+Headers +and +footers, +as defined in the section +Mom’s Document Processing Terms, +are those parts of a document that contain information about the document +itself which appear in the margins either above or below +running text. +They are, in all respects but two, identical. The differences are: +

+
    +
  1. headers appear in the margin above running text while + footers appear in the margin beneath running text; +
  2. +
  3. the (optional) rule that separates headers from running + text appears below the header while + the (optional) rule that separates footers from running + text appears above the footer. +
  4. +
+ +
+

+Note: +While the single page number that mom generates in either the top +or bottom margin above or below running text is technically a kind +of header/footer, mom and this documentation treat it as a separate +page element. +

+
+ +
+

+Author’s note: +Left to their own devices (i.e. if you’re happy with the way +mom does things by default), headers are something you never have to +worry about. You can skip reading this section entirely. But if +you want to change them, be advised that headers have more macros to +control their appearance than any other document element. The text +of this documentation becomes correspondingly dense at this point. +

+
+ +

General description of headers/footers

+ +

+Headers comprise three distinct parts: a left part, a centre part, +and a right part. Each part contains text (a “string”) +that identifies some aspect of the document as a whole. +

+ +

+The left part (“header-left”) lines up with the +document’s left margin. The centre part (“header +centre”) is centred on the document’s line length. +The right part (“header-right”) lines up with the +document’s right margin. Not all parts need contain a string, +and if you don’t want headers at all, you can turn them off +completely. +

+ +
+

+Note to groff experts: +Although mom’s headers resemble the three-part titles +generated by .tl, they’re in no way related to it, +nor based upon it. .tl is not used at all in mom. +

+
+ +

+Normally, mom fills headers with strings appropriate to the document +type selected by +DOCTYPE, +with the author left, the document title right, and chapter or +document type information in the centre. You can, however, supply +whatever strings you like—including page numbers—to go +in any part of headers. What’s more, you can set the family, +font, size, colour and capitalization style (caps, caps/lower-case, +or smallcaps) for each header part individually. +

+ +

+By default, mom prints a horizontal rule beneath headers to separate +them visually from running text. In the case of footers, the rule +is above. You can increase or decrease the space between the header +and the rule if you like (with +HEADER_RULE_GAP), +or remove it completely. +

+ +

Default specs for headers/footers

+ +

+Mom makes small type adjustments to each part of the header (left, +centre, right) to achieve an aesthetically pleasing result. The +defaults are listed below. (The strings mom puts by default in each +part are explained in +DOCTYPE.) +

+ +
+

+Note: Except for capitalization (all caps or caps/lower-case), +these defaults apply only to +PRINTSTYLE TYPESET. +

+ +TYPE SPEC HEADER LEFT HEADER CENTER HEADER RIGHT +--------- ----------- ------------- ------------ +Family document default document default document default +Font roman italic roman +Colour (black) (black) (black) +All caps no no yes +Size* -.5 (points) -.5 (points) -2 (points) + (-2 if all caps) (-2 if all caps) (-.5 if not all caps) + +*Relative to the point size of running text + +
+ +

+You can, of course, change any of the defaults using the appropriate +control macros. And should you wish to design headers from the +ground up, mom has a special macro +HEADER_PLAIN +that removes all type adjustments to headers. The +type specs for running text are used instead, providing a simple +reference point for any alterations you want to make to the family, +font, size, and capitalization style of any header part. +

+ +

Vertical placement and spacing of headers/footers

+ +

+As explained in the section, +Typesetting macros during document processing, +the top and bottom margins of a mom document are the vertical start +and end positions of +running text, +not the vertical positions of headers or footers, which, by definition, +appear in the margins above (or below) running text. +

+ +

+The vertical placement of headers is controlled by the macro +HEADER_MARGIN, +which establishes the +baseline +position of headers relative to the top edge of the page. The +header rule, whose position is relative to the header itself, is +controlled by a separate macro. +

+ +

+FOOTER_MARGIN is the counterpart to HEADER_MARGIN, and establishes +the baseline position of footers relative to the bottom edge of the +page. +

+ +

+The distance between headers and the start +of running text can be controlled with the macro +HEADER_GAP, +effectively making HEADER_MARGIN + HEADER_GAP the top margin of +running text unless you give mom a literal top margin (with +T_MARGIN) +or +PAGE, +in which case she ignores HEADER_GAP and begins the running text at +whatever top margin you give. +

+ +

+FOOTER_GAP and +B_MARGIN +work similarly, except they determine where running text ends +on the page. (See +Important – footer margin and bottom margins +for a warning about possible conflicts between the footer margin and +the bottom margin.) +

+ +

+Confused? Mom apologizes. It’s really quite simple. By +default, mom sets headers 4-1/2 +picas +down from the top of the page and begins the running text 3 picas +(the HEADER_GAP) beneath that, which means the effective top margin +of the running text is 7-1/2 picas (visually approx. 1 +inch). However, if you give mom a literal top margin (with +T_MARGIN), +she ignores the HEADER_GAP and starts the running text at whatever +top margin you give. +

+ +

+Footers are treated similarly. Mom sets footers 3 picas up from the +bottom of the page, and interrupts the processing of running text 3 +picas (the FOOTER_GAP) above that (again, visually approx. 1 inch). +However, if you give mom a literal bottom margin (with +B_MARGIN), +she ignores the FOOTER_GAP and interrupts the processing of running +text at whatever bottom margin you give. +

+ +

+If mom is paginating your document (she does, by default, at the +bottom of each page), the vertical spacing and placement of page +numbers, whether at the top or the bottom of the page, is managed +exactly as if the page numbers were headers (or footers), and are +controlled by the same macros. See +Pagination control. +

+ +

+ + + +

Managing headers/footers

+ +

+The following are the basic macros for turning +headers +or +footers +on or off. They should be invoked prior to +START. +

+ +

+By default, mom prints page headers. If you turn +them off, she will begin the +running text +on each page with a default top margin of 6 +picas +unless you have requested a different top margin (with +T_MARGIN) +prior to +START. +

+ +
+

+Note: +HEADERS +and +FOOTERS +are mutually exclusive. If headers are on, footers (but not +bottom-of-page numbering) are automatically turned off. Equally, +if footers are on, headers (but not top-of-page numbering) are +automatically turned off. Thus, if you’d prefer footers in a +document, you need only invoke +.FOOTERS; +there’s no need to turn headers off first. +

+
+ +

+If you need both headers and footers, there’s a special macro +HEADERS_AND_FOOTERS +that allows you to set it up. +

+ + + + + +
+

Headers

+
+ +
+Macro: HEADERS toggle +
+ +

+Page headers +are on by default. If you don’t want them, turn them off by +invoking .HEADERS with any argument (OFF, +QUIT, END, X...), e.g. +
+ + .HEADERS OFF + +

+ +

+NOTE: HEADERS automatically +disables +footers +but not the page numbers that normally appear at the bottom of the +page. If you want both headers and footers, you must use the macro +HEADERS_AND_FOOTERS. +

+ +

+ADDITIONAL NOTE: If HEADERS are OFF, mom’s normal top +margin for +running text +(7.5 +picas) +changes to 6 picas (visually approx. 1 inch). This does NOT apply +to the situation where footers have been explicitly turned on +(with +FOOTERS). +Explicitly invoking footers moves page numbering to the +top of the page, where its placement and spacing are the same as +for headers (i.e. the top margin of running text remains 7.5 +picas.) +

+ + + +
+

Footers

+
+ +
+Macro: FOOTERS toggle +
+ +

+Page footers +are off by default. If you want them instead of +headers, +turn them on by invoking +.FOOTERS without an argument, e.g. +
+ + .FOOTERS + +FOOTERS automatically disables headers, and +mom shifts the placement of page numbers from their +normal position at page bottom to the top of the page. +

+ +

+NOTE: If you want both headers and footers, you must use the +macro +HEADERS_AND_FOOTERS. +

+ +

+NOTE: By default, when footers are on, +mom does not print a page number on the first +page of a document, nor on first pages after +COLLATE. +If you don’t want this behaviour, you can change it with +PAGENUM_ON_FIRST_PAGE. +

+ + + +
+ +
+ +
+Macro: FOOTER_ON_FIRST_PAGE toggle +
+ +

+If you invoke +.FOOTERS, +mom, by default, does not print a footer on the +first page of the document. (The +docheader +on page 1 makes it redundant.) However, should you wish a footer on +page 1, invoke .FOOTER_ON_FIRST_PAGE without any argument. +

+ +

+ +

Control macros for headers/footers

+ +

+Virtually every part of headers (and footers; see the note on how +“headers” means “footers” +in the +Introduction +to headers/footers) can be designed to your own specifications. +

+ +
+

Header/footer control macros and defaults

+ +
    +
  1. Header/footer strings +
  2. +
  3. Header/footer style +
  4. +
  5. Header/footer vertical placement and spacing +
  6. +
  7. Header/footer separator rule +
  8. +
+
+ + + +

1. Header/footer strings

+ +
+”Macro: HEADER_LEFT “<text of header-left> | # +
+ +
+”Macro: HEADER_CENTER “<text of header-centre> | # +
+ +
+”Macro: HEADER_RIGHT “<text of header-right> | # +
+ +

+To change the text (the “string”) of the left, centre, +or right part of headers, invoke the appropriate macro, above, +with the string you want. For example, mom, by default, prints +the document’s author in the header-left position. If your +document has, say, two authors, and you want both their names to +appear header-left, change HEADER_LEFT like this: +
+ + .HEADER_LEFT "R. Stallman, E. Raymond" + +

+ +

+Because the arguments to HEADER_LEFT, _CENTER, +and _RIGHT are +string arguments, +they must be enclosed in double-quotes. +

+ +
+

+Note: +Replace HEADER_, above, with FOOTER_ to change the strings in +footers. +

+
+ +

Padding the header/footer centre string

+ +
+Macro: HEADER_CENTER_PAD LEFT | RIGHT <amount of space by which to pad centre string left or right> +
+ +

+• Requires a unit of measure +

+ +

+By default, mom centres the header-centre string on the line length +in effect for page headers. +

+ +

+In some cases, notably when the header-left or header-right +strings are particularly long, the effect isn’t pretty. The +offendingly long header-left or right crowds, or even overprints, +the header-centre. That’s where HEADER_CENTER_PAD comes +in. With a bit of experimentation (yes, you have to preview the +document), you can use HEADER_CENTER_PAD to move the header-centre +string left or right until it looks acceptably centred between the +two other strings. +

+ +

+For example, say your document is an outline for a novel called +By the Shores of Lake Attica. You’ve told mom you want +
+ + .DOCTYPE NAMED "Outline" + +but when you preview your work, you see that “Outline”, +in the centre of the page header, is uncomfortably close to the +title, which is to the right. By invoking +
+ + .HEADER_CENTER_PAD RIGHT 3P + +you can scoot the word "Outline" over three +picas +to the left (because the padding is added onto the right of the +string) so that your head looks nicely spaced out. Invoking +.HEADER_CENTER_PAD with the LEFT argument puts +the padding on the left side of the string so that it scoots +right. +

+ +

+Most reassuring of all is that if you use HEADER_CENTER_PAD +conjunction with +RECTO_VERSO, +mom will pad the centre string appropriately left OR right, +depending on which page you’re on, without you having to tell +her to do so. +

+ +

Using mom’s reserved strings in header/footer definitions

+ +

+As pointed out in the +Author’s note +in the introduction to headers/footers, headers and footers are +something you don’t normally have to worry much about. Mom +usually knows what to do. +

+ +

+However, situations do arise where you need to manipulate what goes +in the header/footer strings, setting and resetting them as you go +along. +

+ +

+A case where you might want to do this would be if you want to +output endnotes at the end of each document in a series of +collated +documents, and you want the word "Endnotes" to go in the header +centre position of the endnotes, but want, say, the +TITLE +to go back into the centre position for the next output document. +

+ +

+In scenarios like the above, mom has a number of reserved strings +you can plug into the HEADER_LEFT, _CENTER and _RIGHT macros. They +are: +
+ + \E*[$TITLE] —the current argument passed to .TITLE + \E*[$DOCTITLE] —the current argument passed to .DOCTITLE + \E*[$DOC_TYPE] —the NAMED argument passed to .DOCTYPE + \E*[$AUTHOR] —the current first argument passed to .AUTHOR + \E*[$AUTHOR_1...9] —the current arguments passed to .AUTHOR + \E*[$AUTHORS] —a comma-separated concatenated string + of all the current arguments passed to .AUTHOR + (i.e. a list of authors) + \E*[$CHAPTER_STRING] —the current argument passed to .CHAPTER_STRING, + if invoked, otherwise, "Chapter" + \E*[$CHAPTER] —the current argument (typically a number) passed + to .CHAPTER + \E*[$CHAPTER_TITLE] —the current argument passed to .CHAPTER_TITLE + +Returning to the scenario above, first, you’d define a centre +string for the endnotes page: +
+ + .HEADER_CENTER "Endnotes" + +Then, you’d output the endnotes: +
+ + .ENDNOTES + +Then, you’d prepare mom for the next document: +
+ + .COLLATE + .TITLE "New Doc Title" + .AUTHOR "Josephine Blough" + +Then, you’d redefine the header-centre string using the +reserved string \*[$TITLE], like this: +
+ + .HEADER_CENTER "\E*[$TITLE]" + +And last, you’d do: +
+ + .START + +VoilĂ ! Any argument you pass to +TITLE +from here on in (say, for subsequent documents) is back in the +header-centre position. Here’s the whole routine again: +
+ + .HEADER_CENTER "Endnotes" + .ENDNOTES + .COLLATE + .TITLE "New Doc Title" + .AUTHOR "Josephine Blough" + .HEADER_CENTER "\E*[$TITLE]" + .START + +

+ +

+If need be, you can concatenate the strings, as in the following +example. +
+ + .HEADER_CENTER "\E*[$CHAPTER_STRING] \E*[$CHAPTER]" + +which, assuming a .CHAPTER_STRING of +"Chapter" and a .CHAPTER of +"2", would put “Chapter 2” in the +header-centre position. +

+ +

Replacing header-left, -centre or -right with the page number

+ +

+If you would like to have the current page number appear in the +header-left, -centre, or -right position instead of a text string, +invoke the appropriate macro, above, with the single argument +# (the “number” or “pound” sign). +Do not surround the pound size with double-quotes, as you would +normally do if the argument to .HEADER_CENTER were a +string. For example, +
+ + .HEADER_CENTER # + +(notice, no double-quotes) will print the current page number in the +centre part of headers. +

+ +

Including the page number in header-left, -CENTER or -right

+ +

+If you would like to include the current page number in the +string you pass to HEADER_LEFT, _CENTER, or _RIGHT, (as +opposed to replacing the string with the page number), use the +special +inline escape +\*[PAGE#] in the string argument. +

+ +

+For example, say you have a document that’s ten pages long, +and you want header-right to say “page <whichever> of +10”, invoke .HEADER_RIGHT as follows: +
+ + .HEADER_RIGHT "page \*[PAGE#] of 10" + +The header-right of page two will read “page 2 of 10”, +the header-right of page three will read “page 3 of 10”, +and so on. +

+ + + +

2. Header/footer style

+ +
Global changes
+ +

+The following macros allow you to make changes that affect all parts +of the header at once. +

+ + + +
+Macro: HEADER_PLAIN +
+ +

+By default, mom makes adjustments to the font, size, and +capitalization style of each part of headers to achieve an +aesthetically pleasing look. Should you wish to design your own +headers from the ground up without worrying how changes to the +various elements of header style interact with mom’s defaults, +invoke .HEADER_PLAIN by itself, with no argument. Mom +will disable her default behaviour for headers, and reset all +elements of header style to the same family, font, point size and +colour as she uses in paragraphs. +

+ +

+Replace HEADER_, above, with FOOTER_ to disable mom’s default +behaviour for the various elements of footer style. +

+ +
+Macro: HEADER_FAMILY <family> +
+ +

+By default, mom uses the default document family for headers. If +you would like her to use another +family +in headers, invoke .HEADER_FAMILY with the identifier +for the family you want. The argument is the same as for the +typesetting macro +FAMILY. +

+ +

+Replace HEADER_, above, with FOOTER_ to change the footer family. +

+ +
+Macro: HEADER_SIZE <+|-number of points> +
+

+• Argument is relative to the point size of type in paragraphs. +See +Arguments to the control macros +for an explanation of how control macros ending in +_SIZE work. +

+ +

+By default, mom makes small adjustments to the size of each part +of a header to achieve an aesthetically pleasing result. If +you’d like her to continue to do so, but would like the +overall appearance of headers to be a little smaller or a little +larger, invoke .HEADER_SIZE with + or - the number of points (fractions allowed) +by which you want her to in/decrease the size of headers. For +example, +
+ + .HEADER_SIZE +.75 + +increases the size of every part of a header by 3/4 of a point while +respecting mom’s own little size changes. +

+ +

+Replace HEADER_, above, with FOOTER_ to change the footer size. +

+ +
+

+Note: +Normally, macros that control headers have no effect on +PRINTSTYLE TYPEWRITE. +HEADER_SIZE is an exception. While all parts of a header in +PRINTSTYLE TYPEWRITE are always the same size, you +can use HEADER_SIZE with PRINTSTYLE TYPEWRITE to +reduce the header’s overall point size. You’ll most +likely require this when the +COPYSTYLE +is DRAFT, since portions of the header may overprint if, +say, the title of your document is very long. +

+
+ +
+Macro: HEADER_COLOR <colorname> +
+ +

+If you want your headers in a colour different from the document +default (usually black), invoke .HEADER_COLOR with the +name of a colour pre-defined (or “initialized”) with +NEWCOLOR +or +XCOLOR. +

+ +

+HEADER_COLOR will set all the parts of the header +plus the header rule in the colour you give it as an argument. If +you wish finer control over colour in headers, you can use +HEADER_<POSITION>_COLOR +to colourize each part of the header separately, as well as +HEADER_RULE_COLOR +to change the colour of the header rule. +

+ +

+Replace HEADER_, above, with FOOTER_ to colourize footers. +

+ +

3. Part by part changes

+ +

+When using the following control ”macros, replace +“<POSITION> by LEFT, CENTER, or RIGHT as +appropriate. +

+ + + +
+Macro: HEADER_<POSITION>_FAMILY <family> +
+ +

+Use HEADER_<POSITION>_FAMILY to change the +family +of any part of headers. See +Arguments to the control macros +for an explanation of how control macros ending in _FAMILY work. +

+ +

+Replace HEADER_, above, with FOOTER_ to change a footer part’s family. +

+ +
+Macro: HEADER_<POSITION>_FONT <font> +
+ +

+Use HEADER_<POSITION>_FONT to change the +font +of any part of headers. See +Arguments to the control macros +for an explanation of how control macros ending in _FONT work. +

+ +

+Replace HEADER_, above, with FOOTER_ to change a footer part’s font. +

+ +
+Macro: HEADER_<POSITION>_SIZE <+|-number of points> +
+ +

+Use HEADER_<POSITION>_SIZE to change the size of any part of +headers (relative to the point size of type in paragraphs). See +Arguments to the control macros +for an explanation of how control macros ending in _SIZE work. +

+ +

+Replace HEADER_, above, with FOOTER_ to change a footer part’s size. +

+ +
+Macro: HEADER_<POSITION>_CAPS toggle +
+ +

+HEADER_<POSITION>_CAPS is a +toggle macro. +If you want any part of headers to be set in all caps, regardless of +the capitalization of that part’s string as given to the +reference macros +or as defined by you with the +header string control macros, +simply invoke this macro (using the appropriate position) with no +argument. If you wish to turn capitalization off (say, for the +header-right string that mom capitalizes by default), invoke the +macro with any argument (e.g. OFF, QUIT, +END, X...). +

+ +

+Replace HEADER_, above, with FOOTER_ to change a footer part’s +capitalization style. +

+ +
+Macro: HEADER_<POSITION>_SMALLCAPS toggle +
+ +

+HEADER_<POSITION>_SMALLCAPS is a +toggle macro. +If you want any part of headers to be set in smallcaps, simply +invoke this macro (using the appropriate position) with no argument. +If you wish to turn the smallcaps off, invoke the macro with any +argument (e.g. OFF, QUIT, END, +X...). +

+ +

+Replace HEADER,_ above, with FOOTER_ to invoke smallcaps for footer +parts. +

+ +
+Macro: HEADER_<POSITION>_COLOR <colorname> +
+ +

+HEADER_<POSITION>_COLOR allows you to set a colour for each of +the three possible parts of a page header separately. For example, +say you want the right part of the header (by default, the document +title) in red, this is how you’d get it: +
+ + .HEADER_RIGHT_COLOR red + +The other parts of the header will be in the default header colour +(usually black, but that can be changed with +HEADER_COLOR). +

+ +

+Remember that you have to define (or “initialize”) a +colour with +NEWCOLOR +or +XCOLOR +before you can use the colour. +

+ +

+If you create a +user-defined header +with +HEADER_RECTO +or +HEADER_VERSO, +and you want various elements within the header to be colourized, +embed the colours in the string passed to HEADER_RECTO or +HEADER_VERSO with the +\*[<colorname>] +inline escape. +

+ +

+Replace HEADER_, above, with FOOTER_ to set the colours for the +various elements of footers. +

+ +
Grouping style parameters for the individual header parts
+ +

+Instead of using control macros for the style parameters +of an individual header part, the parameters may be +grouped +by invoking HEADER_<POSITION>_STYLE with a list of +keyword/value pairs. Acceptable keywords are +FAMILY FONT SIZE COLOR CAPS and SMALLCAPS. +Keyword/value pairs may appear on the same line as the macro, or +separated into several lines using the backslash character +(\). If you use the latter style, all but the final +parameter must be terminated with the backslash. +

+ +

+Thus, to set the header-left part in Helvetica bold, red, 1 point larger +than +running text +and all caps, you could do either +
+ + .HEADER_LEFT_STYLE FAMILY H FONT B SIZE +1 COLOR red CAPS + +or +
+ + .HEADER_LEFT_STYLE \ + FAMILY H \ + FONT B \ + SIZE +1 \ + COLOR red \ + CAPS + +If you need to reverse the sense of CAPS +or SMALLCAPS, use NO_CAPS or +NO_SMALLCAPS. +

+ + + +

3. Header/footer vertical placement and spacing

+ +

+See +Vertical placement and spacing of headers/footers +for an explanation of how mom deals with +headers, footers, and top/bottom page margins. +

+ + + + + +
+Macro: HEADER_MARGIN <distance to baseline of header> +
+ +

+• Requires a unit of measure +

+ +

+Use HEADER_MARGIN to set the distance from the top edge of the page to the +baseline +of type in headers. A unit of measure is required, and decimal +fractions are allowed. +

+ +

+Mom’s default header margin is 4-1/2 +picas, +but if you want a different margin, say, 1/2-inch, do +
+ + .HEADER_MARGIN .5i + +If your document uses +footers, +replace HEADER_, above, with FOOTER_. The argument to FOOTER_MARGIN +is the distance from the bottom edge of the page to the baseline of +type in footers. Mom’s default footer margin is 3 +picas. +

+ +

Header/footer margins and page numbering

+ +

+Mom uses HEADER_MARGIN and FOOTER_MARGIN to establish the baseline +position of page numbers in addition to the baseline position of +headers and footers proper. +

+ +

+By default, page numbers appear at the bottom of the page, therefore +if you want the default position (bottom), but want to change the +baseline placement, use FOOTER_MARGIN. Conversely, if page numbers +are at the top of the page, either because you turned +FOOTERS +on or because you instructed mom to put them there with +PAGENUM_POS, +you’d use HEADER_MARGIN to change their baseline placement. +

+ + + + + +
+Macro: HEADER_GAP <distance from header to start of running text> +
+ +

+• Requires a unit of measure +

+ +

+Use HEADER_GAP to set the distance from the +baseline +of type in headers to the start of +running text. +A unit of measure is required, and decimal fractions are allowed. +

+ +

+As explained in +Vertical placement and spacing of headers/footers, +HEADER_MARGIN + HEADER_GAP determine the default vertical starting +position of running text on the page unless you have given mom your +own top margin (with +T_MARGIN). +If you give a top margin, mom ignores HEADER_GAP; running text +starts at your stated top margin. +

+ +

+Mom’s default header gap is 3 +picas, +but if you want a different gap, say, 2 centimetres, do +
+ + .HEADER_GAP 2c + +If your document uses +footers, +replace HEADER_, above, with FOOTER_. The argument to FOOTER_GAP +is the distance from the baseline of type in footers to the last +baseline of running text on the page. +

+ +

+As explained in +Vertical placement and spacing of headers/footers, +FOOTER_MARGIN + FOOTER_GAP determine the default vertical end +position of running text on the page unless you have given mom a +bottom margin (with +B_MARGIN). +If you give a bottom margin, mom ignores FOOTER_GAP; running text +ends at your stated bottom margin, subject to the restriction outlined +here. +

+ +

+Mom’s default footer gap is 3 +picas. +

+ +
+

+Note: +Mom uses HEADER_GAP and FOOTER_GAP to establish the start and end +baseline positions of running text with respect to both headers and +footers AND page numbers. If you wish to change the gap between the +last line of running text and a bottom page number, use FOOTER_GAP. +If page numbers are at the top of the page, change the gap between +the number and the first line of running text with HEADER_GAP. +

+
+ +
+

+Additional note: +HEADER_GAP and FOOTER_GAP may only be used once, at the start of a +document. In +collated documents, +this means that HEADER_GAP or FOOTER_GAP cannot be used to change +the gaps once they have been set. The same applies to the Table of +Contents, Endnotes, Bibliographies, and Lists of... . +

+ +

+In the event that you need to change the header or footer gap after +the start of a document, you must do so with +T_MARGIN +or +B_MARGIN, +which raise or lower the top and bottom margins of +running text +but do not affect the placement headers and footers. +(See +here +for a demonstration.) +

+
+ + + +

4. Header/footer separator rule

+ +

+The header/footer separator rule is a modest horizontal rule, +set slightly below the header (or above the footer), that runs +the length of the +header +and helps separate it visually from +running text. If +you don’t want the rule, you can turn it off. If you want it, +but at a different vertical position relative to the header (or +footer), you can alter its placement. +

+ +
+ +
+ + + +
+Macro: HEADER_RULE toggle +
+ +

+By default, mom prints a header separator rule underneath headers +(or above footers). If you don’t want the rule, turn it off by +invoking .HEADER_RULE with any argument (OFF, +QUIT, END, X...), e.g. +
+ + .HEADER_RULE OFF + +To turn the rule (back) on, invoke .HEADER_RULE +without any argument. +

+ +
+

+Note: +Replace HEADER_, above, with FOOTER_ to enable/disable the printing +of the footer separator rule. (Most likely, if you’re using +FOOTERS, +you’ll want it off.) +

+
+ + + +
+Macro: HEADER_RULE_WEIGHT <weight in points> +
+ +

+• Argument must NOT have a unit of measure appended +

+ +

+HEADER_RULE_WEIGHT controls the weight (“thickness”) of +the header rule. Like +RULE_WEIGHT, +it takes a single argument: the weight of the header rule expressed +in +points +but without the unit of measure, p, appended. The +argument to HEADER_RULE_WEIGHT must be greater than 0 and less than +100; decimal fractions are allowed. +

+ +

+Say, for example, you want a really strong header separator rule. +
+ + .HEADER_RULE_WEIGHT 4 + +which sets the separator rule weight to 4 points, is how you’d do +it. +

+ +

+Mom’s default header rule weight is 1/2 point. +

+ +
+

+Note: +Replace HEADER_, above, with FOOTER_ to set the weight of the footer +separator rule. +

+
+ + + +
+Macro: HEADER_RULE_GAP <distance of rule beneath header> +
+ +

+• Requires a unit of measure +

+ +

+HEADER_RULE_GAP is the distance from the +baseline +of type in headers to the top edge of the rule underneath. (If +FOOTER_RULE_GAP, the gap is the distance from the top of the highest +ascender +to the bottom edge of the rule.) A unit of measure is required, and +decimal fractions are allowed. Please note that HEADER_RULE_GAP has +no effect on +HEADER_GAP +(i.e., HEADER_RULE_GAP is NOT added to HEADER_GAP when mom calculates +the space between headers and the start of +running text). +

+ +

+By default, the header rule gap is 4 +points. +If you’d like to change it to, say, 1/4 +em, do +
+ + .HEADER_RULE_GAP .25m + +

+ +
+

+Note: +Replace HEADER_, above, with FOOTER_ if you’re using +footers +and want to change the separator rule gap. In footers, the gap is +measured from the top of the tallest +ascender +in the footer. +

+ +

+Additional note: +When using +FOOTER_RECTO +and +FOOTER_VERSO, +make sure that the default size for footers +(FOOTER_SIZE) +is set to the largest size of type that will be used in the footer +or mom may not get the rule gap right. Inline changes to the size +of type in FOOTER_RECTO and FOOTER_VERSO should always be negative +(smaller) than the default. +

+
+ + + +
+Macro: HEADER_RULE_COLOR <colorname> +
+ +

+If you wish to change the colour of the header rule, invoke +.HEADER_RULE_COLOR with the name of a colour pre-defined +(or “initialized”) with +NEWCOLOR +or +XCOLOR. +

+ +

+HEADER_RULE_COLOR overrides the colour set with +HDRFTR_COLOR, +so it’s possible to have the heads entirely in, say, blue (set +with HEADER_COLOR), and the header rule in, say, red. +

+ +
+

+Note: +Replace HEADER_, above, with FOOTER_ to change the colour of the +footer rule. +

+
+ +

+ + + +

User-defined, single string recto/verso headers/footers

+ +

+Sometimes, you’ll find you can’t get mom’s +handling of 3-part headers or footers to do exactly what you want in +the order you want. This is most likely happen when you want the +information contained in the headers/footers split over two pages, +as is often the case with recto/verso documents. +

+ +

+Say, for example, you want recto page headers to contain a +document’s author, centred, and verso page headers to contain +the document’s title, also centred, like this: +
+ + +------------------------+ +------------------------+ + | Author | | Title | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + +------------------------+ +------------------------+ + +With mom’s standard 3-part headers, this isn’t possible, +even when +RECTO_VERSO +is enabled. RECTO_VERSO switches the left and right parts of +headers on alternate pages, but the centre part remains unchanged. +

+ +

+Any time you need distinctly different headers on alternate pages, +mom has macros that let you manually design and determine what goes +into headers on recto pages, and what goes into headers on verso +pages. The macros are +HEADER_RECTO +and +HEADER_VERSO. +Both allow you to state whether the header is flush left, centred, +or flush right, and both take a single +string argument +with which, by combining text and +inline escapes, +you can make the headers come out just about any way you want. Use +of the \*[PAGE#] escape is permitted in the +string argument (see +Including the page number in header-left, -centre or -right), +and, as an added bonus, mom provides a special mechanism whereby +it’s possible to +pad +the string as well. The padding mechanism lets you create headers +that contain left, centre and right parts like mom’s defaults +but entirely of your own design. +

+ + + + + +
+Macro: HEADER_RECTO LEFT | CENTER | RIGHT [ CAPS ] "<header recto string>" +
+ +
+Macro: HEADER_VERSO LEFT | CENTER | RIGHT [ CAPS ] "<header verso string>" +
+ +
+ +

+User-defined single string headers/footers (no recto/verso) +
+HEADER_RECTO may be used to create user-defined, single string +headers (or footers, with FOOTER_RECTO), even when recto/verso is +not enabled (with +RECTO_VERSO). +In such cases, the header/footer you create is the one used on +every page, making HEADER_RECTO your “I need to design my own +headers from scratch” solution. +

+
+ +

+HEADER_RECTO and HEADER_VERSO behave identically, hence all +references to HEADER_RECTO in this section also refer to +HEADER_VERSO. Furthermore, FOOTER_ can be used instead of HEADER_ +to set up recto/verso footers. +

+ +

+The first argument to HEADER_RECTO is the direction in which you +want the header +quadded. +L, C, and R may be used in place of +LEFT, CENTER, and RIGHT. +

+ +

+The second argument (optional) tells mom to capitalize the text of +the header. Please note: Do not use +\*[UC]...\*[LC] +inside the string passed to HEADER_RECTO. +

+ +

+The final argument is a string, surrounded by double-quotes, +containing what you want in the header. HEADER_RECTO disables +mom’s normal 3-part headers, therefore anything you want in +the headers must be entered by hand in the string, including colours +(via the +inline escape +\*[<colorname>]). +

+ +

+By default, HEADER_RECTO is set at the same size, and in the same +family and font, as paragraph text. The control macros +HEADER_FAMILY +and +HEADER_SIZE +may be used to change the default family and size. Changes to the +font(s) within the string must be accomplished with the +inline escapes +\*[ROM], +\*[IT], +\*[BD], +\*[BDI], +and \*[PREV] (see +Changing fonts). +Additional refinements to the style of the header-recto string, +including horizontal spacing and/or positioning, can also be made +with inline escapes. +

+ +

+To include the current page number in the string, use the +\*[PAGE#] +inline escape. +

+ +

Padding the header-recto/header-verso string

+ +

+You can “pad” the header-recto string, a convenience +you’ll appreciate in circumstances such as the following. +
+ + VERSO RECTO + +------------------------+ +------------------------+ + | Author Page# | | Page# Title | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + +------------------------+ +------------------------+ + +

+ +

+There are two steps to padding the string argument passed to HEADER_RECTO +(if you’re unsure what padding is, see +Insert space into lines). +

+
    +
  1. Begin and end the string (inside the double-quotes) with the caret character (^).
  2. +
  3. Enter the pound sign (#) at any point in the string where you want an equalized amount of whitespace inserted.
  4. +
+ +

+The situation depicted above is accomplished like this: +
+ + .HEADER_RECTO LEFT "^\*[PAGE#]#\E*[$TITLE]^" + .HEADER_VERSO LEFT "^\E*[$AUTHOR]#\*[PAGE#]^" + +Notice that the quad argument, LEFT, is used in both +cases. When padding a header, it doesn’t matter which +quad argument you use, although you must be sure to supply +one. Also note that mom does not interpret the # in +\*[PAGE#] as a padding marker (i.e. as a +place to insert whitespace). +

+ +
+

+Important: +The +PAD_MARKER +macro, which changes the default pad marker (#) used by +PAD, +has no effect on the pad marker used in the HEADER_RECTO string. If +you absolutely must have a literal pound sign in your HEADER_RECTO +string, use the escape sequence for the pound sign +( \[sh] ) where you want the pound sign to go. +

+
+ + + +

Headers and footers on the same page

+ +

+Normally, mom prints either a header or a footer, but not both, depending on whether +HEADERS +or +FOOTERS +is enabled. (Page numbering, whether in the top margin +or the bottom, is not considered a header or a footer.) +Should you need both headers and footers on the same page, the +single macro HEADERS_AND_FOOTERS is the way to set it up. +

+ +
+Macro: HEADERS_AND_FOOTERS (see Invocation) +
+ +

+Invocation: +
+ + .HEADERS_AND_FOOTERS \ + <L | C | R> "<header-recto string>" \ + <L | C | R> "<footer-recto string>" \ + <L | C | R> "<header-verso string>" \ + <L | C | R> "<footer-verso string>" + +or + + .HEADERS_AND_FOOTERS <anything> + +

+ +

+Unlike the macros, +HEADERS +and +FOOTERS, +which are +toggle +macros, HEADERS_AND_FOOTERS requires that you supply the information +you want in the headers and footers yourself. Mom does no automatic +generation of things like the title and the author in headers and +footers when you’re using HEADERS_AND_FOOTERS. Furthermore, +style changes—family, font, pointsize, colour, capitalization, +etc —are entirely your responsibility and must be made with +inline escapes +in the arguments passed to “<recto +”header string>“, <recto footer +string>“, etc. By default, mom sets the headers and +footers created with HEADERS_AND_FOOTERS in the same family, font, +point size, capitalization style and colour as +running text. +

+ +

+The manner of entering what you want is identical to the way you +input +single string headers and footers. +I suggest reading up on them, as well as looking at the entries, +HEADER_RECTO +and +Using mom’s reserved strings in header/footer definitions. +

+ +

+The same +padding mechanism +used in HEADER_RECTO and HEADER_VERSO is available in the +string arguments +passed to HEADERS_AND_FOOTERS, allowing you to simulate two- and +three-part headers and footers. +

+ +

+L | C | R in the arguments to HEADERS_AND_FOOTERS refers +to whether you want the specific header or footer part on the left, +in the middle, or on the right. (You can also use the longer forms, +LEFT, CENTER and RIGHT.) The +string you give afterwards is whatever text you want, including +mom’s +reserved strings, +and whatever +inline escapes +you need to change things like family and font, pointsize, colour, +etc. as you go along. +

+ +

+Note the backslashes in the invocation, above. Every set of +arguments given this way to HEADERS_AND_FOOTERS except the +last requires a backslash after it. The use of backslashes +isn’t required if you want to put the entire argument list on +the same (very long!) line as the macro itself; I recommend sticking +to the style shown above to keep things manageable. +

+ +

+If you want to disable having both headers and footers on the same +page, invoke .HEADERS_AND_FOOTERS with any argument +you want (e.g. OFF, QUIT, END, +X...). Mom will restore her default behaviour of setting +automatically generated page headers, with the page number, +centered, at the bottom of the page. If you would prefer footers +instead of headers after turning HEADERS_AND_FOOTERS off, invoke +.FOOTERS +afterwards. +

+ +

Examples of HEADERS_AND_FOOTERS usage

+ +
+
Example 1: Header and footer the same on every page
+ +.HEADERS_AND_FOOTERS \ +-----------------------+ +C "\E*[$TITLE]" \ | Title | +L "^\E*[$AUTHOR]#\*[PAGE#]^" | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + | Author Pg. # | + +-----------------------+ + + +

+\E*[$TITLE] and +\E*[$AUTHOR] will print the strings you pass +to +TITLE +and +AUTHOR; +\*[PAGE#] is how you include the page number +in a header or footer string. (For a list of special strings you +can use in headers and footers, see +here.) +

+ +

+You don’t have to use these special strings. You can type +in anything you like. I’ve only used them here to show that +they’re available. +

+
+ +
+
Example 2: Different headers and footers on recto/verso pages
+ +.HEADERS_AND_FOOTERS \ +C "BOOK TITLE" \ +L "^\*[PAGE#]#\E*[$AUTHOR]^" \ +C "Story Title" \ +L "^\E*[$AUTHOR]#\*[PAGE#]^" + + +-----------------------+ +------------------------+ + | BOOK TITLE | | Story Title | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | Pg. # Author | | Author Pg.# | + +-----------------------+ +------------------------+ + +
+ +

+ + + +

Pagination

+ +

+By default, mom paginates documents. Page numbers +appear in the bottom margin of the page, centred between two hyphens. +As with all elements of mom’s document processing, +most aspects of pagination style can be altered to suit your taste +with control macros. +

+ + +
+

Pagination macros

+ +
+ + + +
+Macro: PAGINATE toggle +
+ +

+Alias: PAGINATION +

+ +

+By default, mom paginates documents (in the bottom margin). If +you’d prefer she not paginate, turn pagination off by +invoking .PAGINATE with any argument (OFF, +NO, QUIT, END, X...), +e.g. +
+ + .PAGINATE NO + +To (re)start pagination, invoke .PAGINATE without any +argument. +

+ + + +
+Macro: PAGENUMBER <number> +
+ +

+As is to be expected, pagination of documents begins at page 1. If +you’d prefer that mom begin with a different number on the +first page of a document, invoke .PAGENUMBER with the +number you want. +

+ +

+PAGENUMBER need not be used only to give mom a "first page" number. +It can be used at any time to tell mom what number you want a page +to have. Subsequent page numbers will, of course, be incremented by +1 from that number. +

+ + + +
+Macro: PAGENUM_STYLE DIGIT | ROMAN | roman | ALPHA | alpha +
+ +

+PAGENUM_STYLE lets you tell mom what kind of page numbering you +want. +
+ + DIGIT Arabic digits (1, 2, 3...) + ROMAN upper case roman numerals (I, II, III...) + roman lower case roman numerals (i, ii, iii...) + ALPHA upper case letters (A, B, C...) + alpha lower case letters (a, b, c...) + +

+ + + +
+Macro: PAGENUM_ON_FIRST_PAGE toggle +
+ +

+This macro applies only if you’ve enabled +FOOTERS. +If FOOTERS are on, mom automatically places page numbers at the tops +of pages except on the first page of a document (or on first pages +after +COLLATE). +If you’d like the page number to appear on “first” pages +when footers are on, invoke +
+ + .PAGENUM_ON_FIRST_PAGE + +with no argument. Any other argument turns the feature off +(OFF, QUIT, END, X, +etc). +

+ +

+As with most of the +control macros, +PAGENUM_ON_FIRST_PAGE can be invoked at any time, meaning that if +you don’t want a page number on the very first page of a +document, but do want one on pages that appear after COLLATE, omit +it before the first +START +of the document, then invoke it either just before or after your +first COLLATE. +

+ + + +
+Macro: DRAFT_WITH_PAGENUMBER +
+ +

+Sometimes, in +COPYSTYLE DRAFT, +the CENTER part of page headers gets overcrowded because of +the draft and revision information that go there by default. +DRAFT_WITH_PAGENUMBER is one way to fix the problem. +

+ +

+Invoked without an argument, .DRAFT_WITH_PAGENUMBER +removes draft/revision information from the page headers and +attaches it instead to the document’s page numbering, in the +form +
+ + Draft #, Rev. # / <pagenumber> + +If you have not supplied mom with a draft number (with +DRAFT) +DRAFT_WITH_PAGENUMBER will assume “Draft 1“, and will +print it before the page number. +

+ +

+See the note in +COPYSTYLE DRAFT + +for other ways of dealing with crowded page headers when formatting +draft-style copy. +

+ + + +
+Macro: PAGENUMBER_STRING "<text of page number string>" +
+ +

+If you want page numbering to contain text in addition to the page +number itself, use PAGENUMBER_STRING. +

+ +

+The most common use for PAGENUMBER_STRING is to include the total +number of pages along with the page number, for example +“Page 1 of 10, Page 2 of 10...” To accomplish this, +you’d enter +
+ + .PAGENUMBER_STRING "Page \*[PAGE#] of 10" + +Notice that the page number is entered symbolically with the +inline escape +\*[PAGE#], +while the total number of pages must be entered explicitly after the +document is complete and the total number of pages known. +

+ + + + + +

1. Page number family/font/size/colour

+ +
+

+See +Arguments to the control macros. +
+The following control macros may also be +grouped +using PAGENUMBER_STYLE.* +

+ +.PAGENUM_FAMILY default = prevailing document family +.PAGENUM_FONT default = roman +.PAGENUM_SIZE default = +0 (i.e. same size as paragraph text) +.PAGENUM_COLOR default = black + +
+ +

+*Note: Do not confuse PAGENUMBER_STYLE with +PAGENUM_STYLE. +

+ +

2. Page number position

+ +
+Macro: PAGENUM_POS [ TOP | BOTTOM ]  [ LEFT | CENTER | RIGHT ] +
+ +

+Use PAGENUM_POS to change the default position of automatic page +numbering. PAGENUM_POS requires two arguments: a vertical +position (TOP or BOTTOM) and a horizontal +position (LEFT or CENTER or RIGHT). +

+ +

+For example, if you turn both +headers +and +footers +off (with .HEADERS OFF and +.FOOTERS OFF) and you want mom to number your pages +at the top right position, enter +
+ + .PAGENUM_POS TOP RIGHT + +

+ +
+

+Note: +HEADERS must be OFF for PAGENUM_POS TOP to work. +

+
+ +

3. Enclose page numbers with hyphens (on or off)

+ +
+Macro: PAGENUM_HYPHENS toggle +
+ +

+By default, mom encloses page numbers between hyphens. If you +don’t want this behaviour, invoke the macro PAGENUM_HYPHENS +with any argument (OFF, QUIT, END, +X, etc), like this: +
+ + .PAGENUM_HYPHENS OFF + +If, for some reason, you want to turn page number hyphens back +on, invoke the macro without an argument. +

+ + + +

Inserting blank pages into a document

+ +
+Macro: BLANKPAGE <# of blank pages to insert> [DIVIDER [NULL]] +
+ +

+This one does exactly what you’d expect—inserts a blank +page (or pages) into a document. Unless you give the optional argument, +NULL, mom silently increments the page number of every +blank page and keeps track of +recto/verso +stuff, but otherwise does nothing. This is useful for forcing new +sections of a document onto recto pages, but may have other +applications as well. +

+ +

+The required argument to BLANK_PAGE is the number of blank pages to +insert. The argument is not optional, hence even if you only want +one blank page, you have to tell mom: +
+ + .BLANKPAGE 1 + +The optional argument DIVIDER must be given if +you’re inserting a blank page before the start of major +document sections (chapters, endnotes, bibliographies, +or tables of contents–provided the table of contents is not being +autorelocated). +Without the DIVIDER argument, mom simply +inserts the blank pages and prepares the next page to receive +running text. +

+ +

+NULL, which is also optional, allows you to output the +specified number of pages without mom incrementing the page number +for each blank page. She will, however, continue to keep track +of which pages are recto/verso if recto/verso printing has been +enabled. +

+ +
+

+Note: +Do not use BLANKPAGE before TOC if the table of contents is being +autorelocated. +

+
+ +

+ + + + + + + + +
Back to Table of ContentsTopNext: Recto/verso printing, collating
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/images.html b/contrib/mom/momdoc/images.html new file mode 100644 index 0000000..dc1837f --- /dev/null +++ b/contrib/mom/momdoc/images.html @@ -0,0 +1,3515 @@ + + + + + + + + + Mom -- Graphics, floats, and preprocessor support + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: Page headers/footers, pagination
+ +

Graphics, floats, and preprocessor support

+ +
+ +
+ +

+ +

Inserting images and graphics

+ +

+In order to include images in mom documents, the images must be in +either PDF (.pdf) or EPS (.eps) format. Each format requires its own +macro, but both take the same arguments, and in the same order. +

+ +

+Please note that there are differences in the way the files +containing PDF and EPS images must be processed, hence documents may +not contain a mix. +

+ +

Image conversion and file processing

+ +

+When your image files are not in PDF or EPS format—jpgs, +for example—you must convert them before including them in +a mom document. Any utility for converting images may used. The +ImageMagick suite of programmes, present on most GNU/Linux +systems, contains convert, which is simple and effective. +

+ +

PDF

+ +

+Assuming a jpg image, conversion to PDF is done like this: +
+ + convert <image>.jpg <image>.pdf + +Any image type supported by convert may be converted this +way. +

+ +

+Mom files containing PDF images must be processed using +groff’s pdf driver. Use of +pdfmom +is strongly recommended, which natively invokes the pdf driver. +
+ + pdfmom doc.mom > doc.pdf + +

+ +

EPS

+ +

+Assuming a jpg image, conversion to EPS is done like this: +
+ + convert <image>.jpg <image>.eps + +Any image type supported by convert may be converted this +way. There have been reports of trouble with PostScript level 2 +images, so don’t save your images in this format. +

+ +

+Mom files containing EPS images must be processed using +groff’s postscript driver. Use of +pdfmom, +which can be told to use the postscript driver, is strongly +recommended. +
+ + pdfmom -Tps doc.mom > doc.pdf + +

+ + + +
+

PDF_IMAGE

+
+ +
+Macro: PDF_IMAGE \ +
+[ -L | -C | -R | -I <indent> ] \ +
+<pdf image file> <width> <height> [ SCALE <factor> ] \ +
+[ ADJUST +|-<vertical adjustment> ] [ NO_SHIM ] [ NO_FLEX ] \ +
+[ FRAME ] \ +
+[ CAPTION "<caption>" ] [ SHORT_CAPTION "<short caption>" ] \ +
+[ LABEL "<label>" ] [ TARGET "<name>" ]
+
+

+•  +<indent>, +<width>, +<height> +and + +<vertical adjustment> +require a +unit of measure +

+ +
+

+Note: +Mom files with embedded PDF images must be processed with +pdfmom doc.mom > doc.pdf. Arguments may be broken +into several lines using the “line-continued” backslash +(\), as shown above. +

+
+ +

+Unlike +PSPIC, +which it resembles, PDF_IMAGE requires that the pdf image’s +dimensions (the bounding box, +see below) +be supplied each time it’s called. +

+ +

+The first optional argument tells mom how to align the image +horizontally, with -L, -C, and -R +standing for left, centre and right respectively. If you need more +precise placement, the -I argument allows you to give an +indent from the left margin. Thus, to indent a PDF image 6 +picas +from the left margin +
+ + .PDF_IMAGE -I 6P <remaining arguments> + +If you omit the first argument, the image will be centred. +

+ +

+<pdf image> must be in PDF format, with a .pdf +extension. If it is not, mom will abort with a message. See +here +for instructions on converting image formats to PDF. +

+ +

+<width> and <height> are the +dimensions of the image’s bounding box. The most reliable way +of getting the bounding box is with the utility, pdfinfo: +
+ + pdfinfo <image.pdf> | grep "Page *size" + +This will spit out a line that looks like this: +
+ + Page size: width x height pts + +pts means +points, +therefore the unit of measure appended to <width> +and <height> must be p. +

+ +

+The remaining arguments are optional and may be entered in any +order, although it’s best to put CAPTION, +SHORT_CAPTION, and LABEL last. +

+ +
SCALE
+ +

+SCALE allows you to scale the image by +<factor>. The factor is a percentage of the +image’s original dimensions, thus SCALE 50 +scales the image to 50 percent of its original size. No percent +sign or unit of measure should be appended. +

+ +
ADJUST
+ +

+ADJUST lets you raise (-) or lower +(+) the image +within the space allotted for it +by the amount you specify. This is useful for achieving good +optical centering between surrounding blocks of type. A unit of +measure is required. +

+ +
+

+Tip: +You may sometimes find that a PDF_IMAGE at the bottom of a page +doesn’t sit flush on the bottom margin, however attempts to lower it +by adding space beforehand result in it being deferred to the next +page. +

+ +

+The solution is to introduce negative space before the image +so that it displays on the page, then lower it to the bottom margin +with PDF_IMAGE’s ADJUST argument. +

+
+ +
NO_SHIM
+ +

+NO_SHIM instructs mom not to apply +shimming +after an image, which she will do automatically when shimming is +enabled, which it is by default. Shimming ensures that running text +after the image falls properly on the page’s +baseline grid, +but can result in slightly unequal spacing above and below +(correctable with the ADJUST argument). +NO_SHIM is useful when you have several images on the +page and there are visible differences in the spacing beneath them +as a result of shimming. To ensure a flush bottom margin, the last +image on the page should be shimmed, i.e. should not be given the +NO_SHIM argument. +

+ +
NO_FLEX
+ +

+NO_FLEX instructs mom not to apply +flex-spacing +after an image, which she will do automatically when flex-spacing is +enabled. NO_FLEX is useful when you have several images +on the page and you want to distribute excess vertical +whitespace on the page amongst other flex-spacing points on the +page. If there are no others, the final image should be +flex-spaced, i.e. not given the NO_FLEX argument. +

+ +
FRAME
+ +

+FRAME instructs mom to put a frame around the image. +Parameters for the frame are set with +PDF_IMAGE_FRAME. +

+ +
CAPTION
+ +

+CAPTION allows you to give the image a caption. By +default, the caption appears above the image, but may be attached to +the label that appears beneath the image. See +CAPTION_AFTER_LABEL +in +Captions and labels. +The text of the caption must be surrounded by double-quotes. +

+ +
SHORT_CAPTION
+ +

+SHORT_CAPTION allows you to trim long captions for +inclusion in the List of Figures. The text you supply, surrounded +by double-quotes, is what will appear in the List. +

+ +
LABEL
+ +

+LABEL, if given, appears beneath the image. The text you +supply, surrounded by double-quotes, is how the image is labelled +in both the document proper and the List of Figures. Mom provides +an auto-labelling facility for images (see +AUTOLABEL), +which, if enabled, overrides the LABEL argument. +

+ +
TARGET
+ +

+TARGET followed by a unique name surrounded by +double-quotes creates a PDF target for the image so that it may be +linked to from other places in the file (with PDF_LINK; see +Producing PDFs with groff and mom). +

+ +

+Please note: The following functionality is available +only with groff 1.22.4 or later. +

+ +

+When +autolabelling +is enabled and the document is processed with +pdfmom, +the target name can be used to generate the target’s label +number in running text if it is entered as a groff string, i.e. of the +form \*[name]. For example, if you create +a target named “foo” for a pdf image whose autolabel +number would be 3, entering +
+ + See + .PDF_LINK foo "Figure \*[foo]" + +anywhere in running text would result in a pdf link that reads +“Figure 3”. If chapter numbers are being prefixed to +labels, the same string in, say, chapter 5 would produce the pdf +link “Figure 5.3”. +

+ +
+

+Note: Version 2.0-c change +
+Mom now treats all pdf images identically to +floats, +which is to say that if an image doesn’t fit on the output +page, she will defer it to the top of the next page while continuing +to process +running text. +ADJUST is ignored whenever an image is the first to be +deferred, except when moving from column to column on the same page, +when the image may need to be optically adjusted. Subsequent images +that do not fit, if any, are output in order immediately after the +first. +

+ +

+Prior to 2.0-c, it was recommended that images be wrapped inside +FLOAT, +but this is now no longer required, and should, in fact, be avoided. +

+
+ + + +
+

PDF_IMAGE_FRAME

+
+ +
+Macro: PDF_IMAGE_FRAME <inset amount> <rule weight> <color> +
+

+• <inset amount> +requires a +unit of measure; +conversely, +<rule weight> +must not have a unit of measure appended +

+ +

+PDF_IMAGE_FRAME establishes the parameters for subsequent invocations of +PDF_IMAGE +when the FRAME argument is given. Arguments must appear +in order, and any you wish left at the current value should be +entered as two adjacent double-quotes. So, for example, +
+ + .PDF_IMAGE_FRAME "" "" blue + +leaves the inset value and rule weight at their current value and +changes the frame colour to blue. +

+ +

+Frames are drawn outside the image at +its requested dimensions inclusive of scaling. Colours must be +pre-initialized with +XCOLOR +or +NEWCOLOR. +

+ +

+The default inset is 6 points, the default rule +weight is .5 (points), and the default colour is black. +

+ + + +
+

PSPIC

+
+ +
+Macro: PSPIC [ -L | -R | -I <n> ] <file> [ width [ height ] ] +
+ +

+PSPIC is not actually part of mom, but rather a macro included with +every groff installation. man groff_tmac contains the +documentation for PSPIC, but I’ll repeat it here with a few +modifications for clarity. +

+ +
+

From groff_tmac

+

+<file> is the name of the file containing the +image; width and height give the desired +width and height of the image as you wish it to appear within the +document. The width and height arguments may have +units of measure +attached; the default unit of measure is i. PSPIC will +scale the graphic uniformly in the x and y directions so that +it is no more than width wide and height +high. By default, the graphic will be horizontally centred. The +-L and -R options cause the graphic to be +left-aligned and right-aligned, respectively. The -I +option causes the graphic to be indented by <n>; +the default unit of measure is m +(ems). +

+
+ +

+It is not necessary to pass PSPIC the <width> +and <height> arguments unless you are scaling +the image, in which case you will most likely need the original +dimensions of the EPS image’s bounding box. These can be +found with +
+ + gs -q -dBATCH -dNOPAUSE -sDEVICE=bbox <image file>.pdf 2>&1 \ + | grep "%%BoundingBox" | cut -d " " -f4,5 + +The two digits returned are in +points, +therefore the +unit of measure +p must be appended to them. +

+ +

+Because PSPIC lacks the ADJUST option offered by +PDF_IMAGE +a certain amount of manual tweaking of the vertical placement of the +image will probably be required, typically by using the +ALD +and +RLD +macros. Wrapping the image in a +float +and using FLOAT’s ADJUST option can also be used to +correct optical centering. +

+ +

+Additionally, non-floated EPS images +will almost certainly disrupt the baseline placement of +running text. +In order to get mom back on track after inserting a non-floated +.PSPIC image, insert the +SHIM +or +FLEX +macro afterwards, depending on the +vertical whitespace management +strategy in effect, so that the bottom margin of running text falls +where it should. +

+ +

+Remember that mom files with embedded EPS images must be processed +with +
+ + pdfmom -Tps doc.mom > doc.pdf + +

+ +
+

+Please note: +PSPIC does not support +autolabelling, +labels, captions, or inclusion in the List of Figures. If you wish +this functionality, +convert your images to pdf +and use +PDF_IMAGE +instead, then process the file with +pdfmom +(without the -Tps option). +

+
+

+ +

Introduction to floats

+ +

+Non-textual insertions in a document (tables, for example) sometimes +do not fit on the output page of a PDF or PostScript document at +the place they’re inserted in the input file. It’s +necessary, therefore, to defer them to the next page while carrying +on with +running text. +

+ +

+Whenever you need this functionality, mom provides the FLOAT macro. +

+ +

+Floats are usually used for images and graphics, but can contain +anything you like, including text. Whatever’s in the +float will be kept together as a block, output immediately if +there’s room, or deferred to the top of the next output page +when there isn’t; running text continues to the bottom of the +previous page without interruption. +

+ +

+In the case of a float that doesn’t fit being followed by +one that does, both are deferred and output one after the other. +Note that this represents a change from versions 2.1-b_1 and earlier +where the second float was output in position and the first was +deferred. +

+ +

+A key distinction between a float and a +QUOTE +or +BLOCKQUOTE +is that while a float keeps everything together and defers output if +necessary, quotes and blockquotes are output immediately, and may +start on one page and finish on the next. +

+ +

+Floats always begin in +no-fill mode. +Text entered immediately after FLOAT will be set line-for-line +unless a +JUSTIFY +or +QUAD L|R|C +precedes it. Alternatively, any macro that sets a quad direction +may be used, e.g. +PP. +

+ +

+Floats always deposit a break before they begin, which means the +line beforehand will not be +filled. +Floats, therefore, cannot be inserted in the middle of a paragraph +without studying the output file and determining where to break or +spread +the line before the float. Furthermore, if you want a float between +paragraphs, the float should come before .PP, like this: +
+ + .FLOAT + ... + .FLOAT OFF + .PP + +not +
+ + .PP + .FLOAT + ... + .FLOAT OFF + +

+ +

+Floats begin on the baseline immediately below the running text +preceding them. No additional whitespace surrounds them, above or +below. Running text below a float is, however, +shimmed +or +flex-spaced, +depending on the +vertical whitespace management +strategy in effect. This behaviour can be disabled for individual +floats with NO_SHIM or NO_FLEX. +

+ +

+If you’d like more space around a float, you must add it +manually, for example with +ALD +or +SPACE. +

+ + + +
+

FLOAT

+
+ +
+Macro: FLOAT <arguments> | <anything> +
+Arguments: +
+[ ADJUST +|-<amount> ] \ +
+[ FORCE ] \ +
+[ SPAN ] \ +
+[ INDENT <value> ] \ +
+[ CENTER ] \ +
+[ RIGHT ] \ +
+[ NO_SHIM] \ +
+[ NO_FLEX ] \ +
+[ TARGET "<name>" ]
+
+
+ +
+

+Note: +FLOAT is intended for use with the document processing macros only. +

+
+ +
+

+Note: +As a general rule, avoid consecutive floats that have no intervening +running text. +Rather, wrap all the material into a single float. +

+
+ +
+

+Note: +Deferred floats are output with the left indent that was in effect +when they were input. If you do not want this behaviour, disable +the indent prior to inputting the float and re-enable it afterward. +

+
+ +
+

+Note: +Mom treats pic pre-processor directives and pdf images as +floats so it is not necessary to wrap them inside FLOAT unless +additional material is included in what is floated. +

+
+ +

+To begin a float, simply invoke .FLOAT and follow it with +whatever you want the float to contain. When you’re done, +invoke .FLOAT OFF (or OFF, +QUIT, END, X, etc). +

+ +
ADJUST
+ +

+The optional ADJUST argument tells mom to raise +(+) or lower (-) the float within +the space allotted to it by the specified amount. +<amount> must have a +unit of measure +appended. ADJUST gives you precise control over +the vertical centering of floats, allowing you to compensate for +unequal spacing that may result from the automatic +shimming +or +flex-spacing +floats. +

+ +

+ADJUST is ignored for the first float deferred to +a following page but respected for subsequent deferred floats +output immediately afterwards. +

+ +
FORCE
+ +

+The FORCE argument instructs mom to output the float +exactly where it occurs in the input file. With FORCE, +mom immediately breaks to a new page to output the float if it does +not fit on the current page. While this is somewhat contrary to the +notion of floats (i.e. that running text should continue to fill the +page), there are circumstances where it may be desirable. +

+ +

+If you need to force a page break after completion of a float that +has been deferred to a subsequent page, insert \!.bp +immediately before terminating the float. +

+ +
SPAN
+ +

+The SPAN argument tells mom that a float, if deferred, +may carry onto multiple pages. Please note that SPAN may +not be used for floats containing a boxed table; mom will abort with +a warning should this occur. Unboxed tables, on the other hand, are +acceptable within floats that are given the SPAN argument. +

+ +
INDENT
+ +

+INDENT allows you to indent a float from the left margin +by a specified value. The value must have a +(unit of measure +appended to it. +

+ +
CENTER
+ +

+CENTER instructs mom to center a float if it is not +already centered by default. +

+ +
RIGHT
+ +

+RIGHT instructs mom to place a float at the right of the +page; the longest line in the float will be flush with the +page’s right margin. +

+ +
NO_SHIM
+ +

+NO_SHIM instructs mom not to apply +shimming +after a float, which she will do automatically when shimming is +enabled, which it is by default. Shimming ensures that running text +after the float falls properly on the page’s +baseline grid, +but can result in slightly unequal spacing above and below +(correctable with the ADJUST argument). +NO_SHIM is useful when you have several floats on the +page and there are visible differences in the spacing beneath them +as a result of shimming. To ensure a flush bottom margin, the last +float on the page should be shimmed, i.e. should not be given the +NO_SHIM argument. +

+ +
NO_FLEX
+ +

+NO_FLEX instructs mom not to apply +flex-spacing +after a float, which she will do automatically when flex-spacing is +enabled. NO_FLEX is useful when you have several floats +on the page and you want to distribute excess vertical +whitespace on the page amongst other flex-spacing points on the +page. If there are no others, the final float should be +flex-spaced, i.e. not given the NO_FLEX argument. +

+ +
TARGET
+ +

+TARGET followed by a unique name surrounded by +double-quotes creates a PDF target for the float so that it may be +linked to from other places in the file (with PDF_LINK; see +Producing PDFs with groff and mom). +

+ +

+Floats cannot be autolabelled, so unlike pdf images and +pre-processor material, the target name cannot be used as a string +to generate the target’s label number in running text. Label +numbers for floats must be entered explicitly running text, however +they may be entered symbolically in the argument to +LABEL. +See +Reserved variables for +labels. +

+ + +
+

+Note: +Floats use +no-fill mode, +with each input line beginning at the left margin. If this is not +what you want, you must specify the preferred horizontal alignment +within the float (e.g. +CENTER +or +RIGHT). +

+ +

+Furthermore, if you want text +filled, +you must specify +.QUAD L|R|C +or +.JUSTIFY—again, +within the float. +

+
+ +

Labelling and captioning floats

+ +

+Labelling and captioning of tables (tbl), equations +(eq), diagrams (pic) and pdf images +(PDF_IMAGE) +are handled by the macros that initiate them, regardless of whether +they’re wrapped inside a float. However, since a float may +contain any valid input, it is sometimes necessary to add a label +and/or caption to the float itself. +

+ +
+

+Important: +Always use the native labelling/captioning facilities for +preprocessor output and pdf images rather than labelling the +containing float, if any. +

+
+ +

+The macros to label and caption floats are +LABEL +and +CAPTION. +If a label or caption is to appear above the float, the appropriate +macro is entered immediately after +FLOAT. +If a label or caption is to appear beneath the float, the appropriate +macro is entered immediately before ending the float with +FLOAT OFF. +

+ +

+If a label and caption are to be joined, the LABEL macro is +used to enter both by passing the CAPTION argument to +LABEL. +

+ +

+It is impossible for mom to know the contents of a float, so +floats cannot be autolabelled. Each label must be entered +explicitly. Mom does, however, provide a way to enter both +chapter numbers and incrementing label numbers +symbolically, +easing the burden of keeping the numbering scheme intact as +labelled floats are added to or subtracted from a document. +

+ +
+

+Tip: +QUOTE +and +BLOCKQUOTE +may also be labelled and captioned using LABEL and +CAPTION. +

+
+ +

Spacing

+ +

+If a float has a caption at the top, the caption is whitespaced +1/4 linespace from running text and the float itself begins +an additional 1/4 linespace below the caption. If the float has +no corresponding label at the bottom, the float observes the +bottom-spacing rules for all floats, namely that no extra space is +added other than +shimming +or +flex-spacing, +depending on the +vertical whitespace management +in effect. +

+ +

+If a float has a label at the bottom but no caption at the top, the +float begins exactly where started, i.e. with no extra whitespace +between running text and the float. The label (and attached +caption, if any) are whitespaced 1/4 linespace below the float, +with an additional 1/4 linespace underneath plus shimming or +flex-spacing. +

+ +

+Labelled/captioned quotes and blockquotes inside floats treat the +labels/captions as part of the quote so the spacing above and +below the whole float block is what you’d expect from quotes +normally, while the spacing between the label/caption and the quote +is 1/4 linespace. +

+ +
+

LABEL

+
+ +
+Macro: LABEL +"<label>" [ CAPTION "<caption>" ] [ SHORT_CAPTION ] \ +
+[ TO_LIST FIGURES | TABLES | EQUATIONS ]
+
+ +

+The placement of a float’s label depends on where you put it +inside the float. +

+ +

+If you want a label at the top, put LABEL immediately +underneath +FLOAT +and follow it with the text of the label surrounded by double-quotes: +
+ + .FLOAT + .LABEL "Fig. 1" + +If you want a label at the bottom, put LABEL immediately +before ending the float: +
+ + .FLOAT + <contents of float> + .LABEL "Fig. 1" + .FLOAT OFF + +

+ +

Reserved variables for labels

+ +

+Mom reserves strings you may use when entering +label text after the LABEL argument. +\*[chapter] holds the current chapter +or major section number. \*[fig-label], +\*[tbl-label], and +\*[eqn-label] increment the label number of +the appropriate label type by one, and are initially set to zero +after each invocation of +START +when the +DOCTYPE +is CHAPTER. Thus, in every chapter requiring numbered +float labels, you can enter +
+ + .LABEL "Fig. \*[chapter].\*[fig-label]. TO_LIST FIGURES + +which, assuming the third autolabelled float of Chapter 2, will +produce Fig. 2.3. +

+ +

+If your DOCTYPE is DEFAULT or NAMED, +you must reset \*[<type>-label] after +each +COLLATE +by entering +
+ + .AUTOLABEL_<list type> + +before .START. +

+ +

+If +autolabelling +is enabled, e.g. .AUTOLABEL_IMAGES (List +of Figures) or .AUTOLABEL_PIC (also List of Figures), +the prefix is stripped from the label when it appears in +the List. Thus, if you have invoked .AUTOLABEL_PIC, +
+ + .LABEL "Fig. 1.1." + CAPTION "Caption for label \ + TO_LIST FIGURES + +or +
+ + .LABEL "Fig. \*[chapter].\*[label]." \ + CAPTION "Caption for label \ + TO_LIST FIGURES + +will appear in the List of Figures as “1.1.  Caption for +label”. +

+ +

CAPTION

+ +

+If you’d like a caption attached to the label, pass +LABEL the optional argument CAPTION followed +by the text of the caption as a single string surrounded by +double-quotes: +
+ + .FLOAT + <contents of float> + .LABEL "Fig. 1" CAPTION "Caption for Fig. 1" + .FLOAT OFF + +Note that the +CAPTION +macro by itself permits entering several strings, each output on +a line by itself, whereas the CAPTION argument to +LABEL accepts only a single string. +

+ +

SHORT_CAPTION

+ +

+If your caption runs long and you’re including the +float in a “List of ...”, (see +TO_LIST, below) +SHORT_CAPTION tells +mom how you’d like the caption to appear in the List. +

+ +

TO_LIST

+ +

+The optional argument TO_LIST tells mom to add the +float’s label and attached caption, if present, to the specified +list, +which may be one of FIGURES, TABLES, or +EQUATIONS. +

+ +

+If, for some reason, you want only the caption appended to the List, +give \& as the first argument to LABEL, followed by +CAPTION “caption”: +
+ + .LABEL \& \ + CAPTION "caption" + +

+ +
+

+Tip: +TO_LIST can be used to handle situations where labelled +floats need to go to a uniquely named “List of ...”. +

+ +

+Suppose, for example, your document contains figures (e.g. +pic output or pdf-images) and tables, and you need a +“List of Examples” for floats labelled “Example +n.n”. By changing the default title string for +LIST_OF_EQUATIONS +to “List of Examples”, you may include the float in your +List of Examples with +
+ + .TO_FIGURES EQUATIONS + +

+
+ +
+

CAPTION

+
+ +
+Macro: CAPTION +"<caption>" \ +
+[ "<additional line>" [ "<additional line>"... ] ] \ +
+[ TO_LIST FIGURES | TABLES | EQUATIONS ]
+
+ +

+The placement of a float’s caption depends on where you put it +inside the float. +

+ +

+If you want a caption at the top, put CAPTION immediately +underneath +FLOAT +and follow it with the text of the caption surrounded by double-quotes: +
+ + .FLOAT + .CAPTION "Caption at top of float" + +CAPTION can take multiple string arguments, allowing for +captions that run to several lines. There is a caveat: the strings +are not automatically broken into individual lines. You must +provide strings that include literal breaks or spaces: +
+ + .FLOAT + .CAPTION "Caption" ".BR" "at top" ".BR" "of float" + +or, easier to read: +
+ + .FLOAT + .CAPTION "Caption" \ + ".BR" \ + "at top" \ + ".BR" \ + "of float" + +If you want a caption at the bottom, put CAPTION immediately +before ending the float: +
+ + .FLOAT + <contents of float> + .CAPTION "Caption at bottom of float" + .FLOAT OFF + +

+ +
+

+Note: +If you want a caption attached to a label, do not use +CAPTION by itself. Rather, invoke +.LABEL +with the CAPTION argument. +

+
+ +

+ +

Preprocessor support

+ +

+Mom offers full support for the eqn (equations), pic +(diagrams), grap (graphs), tbl (tables) and +refer (bibliographies/citations) preprocessors, including +captions, labelling, autolabelling, and inclusion in the Lists of +Equations, Figures, and Tables. +

+ +

+Other than refer, which is discussed at length in the Bibliographies and references section, it is +beyond the scope of this documentation to cover full preprocessor +usage. Consult the manpages eqn(1), pic(1), +grap(1) and tbl(1) for instructions. +

+ +
+

+Version 2.0-c changes +
+Preprocessor support has been revised and expanded as of version 2.0-c. +Please read the following sections thoroughly and update any +documents created with versions prior to 2.0-c as necessary. +

+
+ +

tbl support

+ +

+Mom documents can include tables generated with the groff +preprocessor tbl. If you are unfamiliar with tbl, I +recommend downloading a copy of +Tbl - A Program to Format Tables, +which, in addition to providing a thorough introduction, contains +some fine examples. If you use tbl, you must pass groff or +pdfmom the -t flag when you process the file. +

+ +

+Tables formatted with tbl begin with the macro +.TS (Table Start) and end with +.TE (Table End). Depending on where you +want your tables output in a document, you may need to wrap +your tbl code inside a +float, +or pass the H argument to .TS. +

+ +

+If you put tbl code inside a float, the table will be +output immediately if it fits on the page, or deferred to the top +of the next page if it doesn’t. If you prefer a table to +begin where you say and span over to the next page, or if you know +for certain a boxed table will run to multiple pages, simply pass the +H argument to .TS, along with a corresponding +TH +and do not wrap the table inside a float. +

+ +
+

+Note: +If you create a boxed table that will span several pages, do not +wrap the table inside a float. Boxed, multipage tables and FLOAT +should be considered mutually exclusive. This restriction is +imposed by the tbl preprocessor itself, not groff or +mom. Unboxed tables that span several pages, however, are +acceptable within FLOAT. +

+
+ +

tbl placement in mom docs

+ +

+If you use .TS without the H argument (and +therefore no .TH), tables that fit on the page are output +in position. If there is not enough room to output the table, +tbl will abort with message instructing you to use +.TS H/.TH. Given that .TS without H +may sometimes fail, it is advisable to begin all tbl blocks +with .TS H. +

+ +

+If you give .TS the H argument (with a +corresponding .TH), tables will be output in position and +span as many pages as necessary to complete output. A table header +will be printed at the top of each page’s table output. In the +event that there is not enough room to print the table header and +at least one row of table data near the bottom of a page, mom will +break to a new page before beginning table output, leaving a gap +in +running text. +

+ +

+Boxed tables inside +floats +are output in position if they fit on the page. If not, they are +deferred to the top of the next page without a break in running +text. Boxed tables within floats may not, however, span multiple +pages; mom will abort with a message should a boxed table in a float +run longer than the page. +

+ +

+Unboxed tables inside floats may span multiple pages provided the +SPAN argument has been given to +FLOAT. +

+ +
+

+Note: +The vertical spacing around unfloated tables may appear slightly +unequal, especially if there are several tables on the page. This +is a result of the +shimming +or +flex-spacing +that mom applies automatically after each table, depending on which +vertical whitespace management +is in effect. You may +disable shimming or flex-spacing with +NO_SHIM +or +NO_FLEX, +or by passing the NO_SHIM or NO_FLEX argument +to .TS. In either case, you will still likely want to +adjust the spacing around with table with the ADJUST +argument to .TS. Tables inside floats should be adjusted +with the ADJUST argument to +FLOAT, +not the ADJUST argument to .TS. +

+
+ +
+

.TS / .TH / .TE

+
+ +
+Macro: TS +
+Arguments: +
+  [ H ] +
+  [ BOXED ] +
+  [ CENTER ] +
+  [ NEEDS ] +
+  [ ADJUST +|-<vertical adjustment>]
+ +(unit of measure +required) + +
+  [ NO_SHIM ] +
+  [ NO_FLEX ] +
+  [ CAPTION "<caption>" ] +
+  [ SHORT_CAPTION "<short caption>" ] +
+  [ LABEL "<label>" ] +
+  [ TARGET "<name>" ] +
+
+Macro: TH (optional, only if .TS H) +
+Macro: TE [ SOURCE "<text of table source>" ] +
+ +

+Tables to be formatted with tbl begin with the macro +.TS and end with .TE. Global tbl +options (“flags”), formatting, and data (per +tbl(1)) come between the two macros. +
+ + .TS + <tbl options, formatting, and data> + .TE + +Tables may be wrapped inside a +float, +in which case, the entire table will be output on the current page +if it fits, or deferred to the next page if it doesn’t. +
+ + .FLOAT + .TS + <tbl options, formatting, and data> + .TE + .FLOAT OFF + +

+ +
+

The .TS macro

+
+ +
+

+Note: Version 2.0-c change +
+2.0-c introduces revisions to the handling of labels and/or +captions, which, along with NO_SHIM, must now be given +as arguments to .TS rather than .TE, as was +the case formerly. Please read this section carefully if you have +documents containing tables as they may need to be updated. +

+
+ +
+

+IMPORTANT: +All arguments to TS must appear on the same line as +.TS. Do not attempt to break them up with the +“line-continued” backslash. You may want to set your +text editor to “wrap” mode in order to see all your +arguments. This annoyance stems from the preprocessor mechanism +itself, not groff or mom. +

+
+ +

+The TS macro must be invoked before entering a tbl +block. You may give as many or as few of its arguments as required, +in any order, although it is advisable to put CAPTION, +SHORT_CAPTION, and/or LABEL last. +

+ +
H
+ +

+With the H argument, a table will span as many pages as +necessary, with or without a running header. The placement of the +corresponding +.TH, +which is required whenever the H argument is given, +determines what, if anything, goes in the header. Compare the +following: + + .TS H .TS H + c s s c s s + c s s c s s + c c c c c c + n n n. n n n. + Percent Increase .TH + 2002-2012 Percent Increase + .TH 2002-2012 + <tbl data> <tbl data> + .TE .TE + +The first example will create a table that spans multiple +pages if necessary, with a running header (“Percent +Increase / 2002-2012”) for that table appearing at +the top of each page until the table ends. The second example, +equally, may run to several pages, but without the running header. +See +TH +for an explanation of .TH placement. +

+ +
+

+Tip: +Generally speaking, it’s a good idea to get into the habit +of using .TS H all the time, since there are no +circumstances under which it fails, whereas .TS without +H will fail on tables that exceed the page length. +

+
+ +
BOXED
+ +

+If a table is to be boxed (i.e., tbl is given the flags +'box' or 'allbox') you must pass the argument +BOXED to .TS, as in this example: +
+ + .TS BOXED + allbox; + c s s + c c c + n n n. + <tbl data> + .TE + +

+ +
CENTER
+ +

+If a table is to be centered on the page, (i.e., tbl is +given the 'center' flag), you must pass the argument +CENTER to .TS, as in this example, which +creates a (possibly) multipage boxed table, centered on the page, +with a running header. + + .TS H BOXED CENTER + allbox center; + c s s + c s s + c c c + n n n. + Percent Increase + 2002-2012 + .TH + <tbl data> + .TE + +

+ +
NEEDS
+ +

+If a table is not inside a float and you pass .TS the +H argument (which you should; see the tip +here), +mom begins output immediately where the table occurs in the +input file if there is enough room on the output page for the +table header plus at least one row of table data. If there +isn’t enough room, mom breaks to a new page before beginning +the table, leaving a gap in +running text +at the bottom of the previous page. If, for aesthetic reasons, +you would prefer that mom require more than one row of table data +beneath the header near the bottom of a page, you may increase the +number with the NEEDS argument, followed by the desired +number of rows. +

+ +
ADJUST
+ +

+ADJUST lets you raise (-) or lower +(+) the table +within the space allotted for it +by the amount you specify. This is useful for achieving good +optical centering between surrounding blocks of type. A unit of +measure is required. +

+ +
NO_SHIM
+ +

+NO_SHIM instructs mom not to apply +shimming +after a table, which she will do automatically when shimming is +enabled, which it is by default. Shimming ensures that running text +after the table falls properly on the page’s +baseline grid, +but can result in slightly unequal spacing above and below +(correctable with the ADJUST argument). +NO_SHIM is useful when you have several tables on the +page and there are visible differences in the spacing beneath them +as a result of shimming. To ensure a flush bottom margin, the last +table on the page should be shimmed, i.e. should not be given the +NO_SHIM argument. +

+ +
NO_FLEX
+ +

+NO_FLEX instructs mom not to apply +flex-spacing +after a table, which she will do automatically when flex-spacing is +enabled. NO_FLEX is useful when you have several tables +on the page and you want to distribute excess vertical +whitespace on the page amongst other flex-spacing points on the +page. If there are no others, the final table should be +flex-spaced, i.e. not given the NO_FLEX argument. +

+ +
CAPTION
+ +

+CAPTION allows you to give the table a caption. By +default, the caption appears above the table, but may be attached to +the label that appears beneath the table. See +CAPTION_AFTER_LABEL +in +Captions and labels. +The text of the caption must be surrounded by double-quotes. +

+ +

+Please note that if your table has a caption, you must invoke +TS with the H flag, which also entails the use +of +TH. +

+ +
SHORT_CAPTION
+ +

+SHORT_CAPTION allows you to trim long captions for +inclusion in the List of Tables. The text you supply, surrounded +by double-quotes, is what will appear in the List. +

+ +
LABEL
+ +

+LABEL, if given, appears beneath the table. The text you +supply, surrounded by double-quotes, is how the table is labelled +in both the document proper and the List of Tables. Mom provides +an auto-labelling facility for tables (see +AUTOLABEL), +which, if enabled, overrides the LABEL argument. +

+ +
TARGET
+ +

+TARGET followed by a unique name surrounded by +double-quotes creates a PDF target for the table so that it may be +linked to from other places in the file (with PDF_LINK; see +Producing PDFs with groff and mom). +

+ +

+Please note: The following functionality is available +only with groff 1.22.4 or later. +

+ +

+When +autolabelling +is enabled and the document is processed with +pdfmom, +the target name can be used to generate the target’s label +number in running text if it is entered as a groff string, i.e. of +the form \*[name]. For example, if you +create a target called “foo” for a table whose autolabel +number would be 3, entering +
+ + See + .PDF_LINK foo "Table \*[foo]" + +anywhere in running text would result in a pdf link that reads +“Table 3”. If chapter numbers are being prefixed to +labels, the same string in, say, chapter 5 would produce the pdf +link “Table 5.3”. +

+ +
+

The .TH macro

+
+ +

+The TH macro (Table Header), which is required +when you begin a table with .TS H, allows you to +determine what goes in a table’s running header if it spans +multiple pages. Placing .TH under the first row of +tbl data makes the first row the header. If placed under +the second row, the first and second rows form the header, and so +on. +

+ +

+As there are sometimes reasons to run .TS H when +you don’t, in fact, want a running header (e.g. when +your table has a caption), you can suppress it by placing +.TH immediately underneath your tbl formatting +specifications, the last line of which always ends with a period +(see tbl(1)). +

+ +

+See the +H +argument to .TS for examples demonstrating .TH +placement. +

+ +
+

The .TE macro

+
+ +

+tbl blocks must be terminated with .TE, +which, as of version 2.0-c, takes a single, optional argument, +SOURCE. (Formerly, TE took a label/caption +argument along with arguments controlling placement.) The argument +is followed by the text of the table’s source, surrounded by +double-quotes. The SOURCE argument may only be used if +MLA +(Modern Language Association) style is enabled. +

+ +

+ +

pic support

+ +

+Mom documents can include diagrams generated with the groff +preprocessor pic. If you are unfamiliar with pic, I +recommend downloading a copy of +Making Pictures with GNU PIC +which provides a thorough introduction and contains many examples. +If you use pic, you must pass groff or pdfmom the -p +flag when you process the file. + +

+ +

+Diagrams created with pic begin with the macro +.PS (Pic Start) and end with +.PE (Pic End). Everything between them is +interpreted by the preprocessor as pic instructions. Please note: +Making Pictures with GNU PIC says that .PF can +also be used to terminate a pic diagram, but this is not supported +by mom. +

+ +

+Pic diagrams are always centered. Note that this represents a +change from version 2.0-b of mom, where centering diagrams required +passing -mpic to groff or +pdfmom +on the command line. +

+ +

+In addition, mom treats pic diagrams identically to +floats, +which is to say that if a diagram doesn’t fit on the output +page, she will defer it to the top of the next page while continuing +to process +running text. +ADJUST is ignored whenever a diagram is deferred, except +when moving from column to column on the same page, when the diagram +may need to be optically adjusted. Subsequent diagrams that do not +fit, if any, are output in order immediately after the first. +

+ +

+Lastly, if your diagrams contain text, you may set all the type +parameters for the text (family, font, size, leading) separately +from the pic block with the macro +PIC_TEXT_STYLE. +If you need to change the type parameters within the block +on-the-fly, you must use pic’s native facilities for +doing so. +

+ +
+

.PS / .PE

+
+ +
+Macro: PS + +
+Arguments: [ <width> <height> ] + +
+  [ LEFT ]
+
+  [ ADJUST +|-<vertical adjustment>]
+ +(unit of measure +required) + +
+  [ NO_SHIM ] +
+  [ NO_FLEX ] +
+  [ CAPTION "<caption>" ] +
+  [ SHORT_CAPTION "<short caption>" ] +
+  [ LABEL "<label>" ] +
+  [ TARGET "<name>" ] +
+
+Macro: PE (no arguments; ends +the pic block) +
+ +
+

+IMPORTANT: +All arguments to PS must appear on the same line as +.PS. Do not attempt to break them up with the +“line-continued” backslash. You may want to set your +text editor to “wrap” mode in order to see all your +arguments. This annoyance stems from the preprocessor mechanism +itself, not groff or mom. +

+
+ +
'width' and 'height'
+ +

+The width and height arguments to +.PS are idiosyncratic owing to the preprocessor itself. +Both are optional and both expect a value in inches, so neither +argument should have a +(unit of measure +appended. +

+ +

+If the width argument is supplied, the diagram, but +not any text it contains, is scaled to the given width. If a +literal width argument of 0 (zero) is given and a +height argument is supplied, the diagram, but not any +text it contains, will be scaled to the requested height. In the +case of two non-zero arguments being given, only the height scaling +is applied. +

+ +
LEFT
+ +

+By default, pic diagrams are centred on the page. If you would +prefer them to be flush left, pass PS the LEFT +argument. +

+
ADJUST
+ +

+ADJUST lets you raise (-) or lower +(+) a diagram +within the space allotted for it +by the amount you specify. This is useful for achieving good +optical centering between surrounding blocks of type. A unit of +measure is required. +

+ +
NO_SHIM
+ +

+NO_SHIM instructs mom not to apply +shimming +after a pic diagram, which she will do automatically when +shimming is enabled, which it is by default. Shimming ensures that +running text after the diagram falls properly on the page’s +baseline grid, +but can result in slightly unequal spacing above and below +(correctable with the ADJUST argument). +NO_SHIM is useful when you have several diagrams on the +page and there are visible differences in the spacing beneath them +as a result of shimming. To ensure a flush bottom margin, the last +diagram on the page should be shimmed, i.e. should not be given the +NO_SHIM argument. +

+ +
NO_FLEX
+ +

+NO_FLEX instructs mom not to apply +flex-spacing +after a pic diagram, which she will do automatically when +flex-spacing is enabled. NO_FLEX is useful when you +have several diagrams on the page and you want to distribute excess +vertical whitespace on the page amongst other flex-spacing points +on the page. If there are no others, the final diagram should be +flex-spaced, i.e. not given the NO_FLEX argument. +

+ +
CAPTION
+ +

+CAPTION allows you to give the diagram a caption. By +default, the caption appears above the diagram, but may be attached to +the label that appears beneath it. See +CAPTION_AFTER_LABEL +in +Captions and labels. +The text of the caption must be surrounded by double-quotes. +

+ +
SHORT_CAPTION
+ +

+SHORT_CAPTION allows you to trim long captions for +inclusion in the List of Figures. The text you supply, surrounded +by double-quotes, is what will appear in the List. +

+ +
LABEL
+ +

+LABEL, if given, appears beneath the diagram. The text you +supply, surrounded by double-quotes, is how the diagram is labelled +in both the document proper and the List of Figures. Mom provides +an auto-labelling facility for diagrams (see +AUTOLABEL), +which, if enabled, overrides the LABEL argument. +

+ +
TARGET
+ +

+TARGET followed by a unique name surrounded by +double-quotes creates a PDF target for the diagram so that it may be +linked to from other places in the file (with PDF_LINK; see +Producing PDFs with groff and mom). +

+ +

+Please note: The following functionality is available +only with groff 1.22.4 or later. +

+ +

+When +autolabelling +is enabled and the document is processed with +pdfmom, +the target name can be used to generate the target’s label +number in running text if it is entered as a groff string, i.e. of +the form \*[name]. For example, if you +create a target called “foo” for a diagram whose +autolabel number would be 3, entering +
+ + See + .PDF_LINK foo "Figure \*[foo]" + +anywhere in running text would result in a pdf link that reads +“Figure 3”. If chapter numbers are being prefixed to +labels, the same string in, say, chapter 5 would produce the pdf +link “Figure 5.3”. +

+ + + +
+

PIC_TEXT_STYLE

+
+ +
+Macro: PIC_TEXT_STYLE \ +
+ +  [ FAMILY ] "<family>" \ +
+  [ FONT ] "<font>" \ +
+  [ SIZE ] "+|-<size>" \ +
+  [ AUTOLEAD ] "<value>" +
+
+ +

+Diagrams drawn with pic may contain text, and groff +inline escapes +may be used to alter the text parameters. A problem that arises +from so doing is that, in many cases, it clutters up the pic +code unnecessarily. +

+ +

+PIC_TEXT_STYLE lets you establish the type parameters for text +inside a pic block all at once in cases where so doing +improves the readability of your mom source files. +

+ +

+The arguments to PIC_TEXT_STYLE behave identically to the arguments +to other control macros, explained +here. +They may be given in any order, and you may use as many or as few as +you like. +

+ +
+

+Note: +Text within pic diagrams does not scale when you provide a +scaling argument to .PS. This is a limitation of the +preprocessor itself, not groff or mom. +

+
+ +

+ +

grap support

+ +

+Grap is a pic preprocessor for creating graphs. Grap +usage is covered in the grap(1) manpage. Its mom +implementation is the same as for pic except that instead of +enclosing directives between +.PS / .PE, +they are enclosed between .G1/.G2. If you use grap, +you must pass groff or pdfmom the -G flag when you process +the file. + +

+ +

+.G1 takes all the same arguments as +PS +with one exception: the argument GRAP must always be given to +.G1. So, for example, a skeleton grap block raised 2 points +and with a caption would be entered: +
+ + .G1 GRAP ADJUST +2p CAPTION "Graph caption" + <grap directives> + .G2 + + +

+ +

+ +

eqn support

+ +

+Support for eqn is provided via extensions to the standard +.EQ/.EN macros. eqn usage itself is beyond +the scope of this documentation, but is covered in the manpage +eqn(1). You can also download a copy of Ted +Harding’s + +A Guide to Typesetting Mathematics Using GNU eqn +, +which contains useful examples. If you use eqn, you must give groff or +pdfmom the -e flag. + +

+ +
+

.EQ / .EN

+
+ +
+Macro: EQ +
+Arguments: +
+  [ -L | -C | -I <indent> ]
+ +(unit of measure +required) + +
+  [ ADJUST +|-<vertical adjustment>]
+ +(unit of measure +required) + +
+  [ NO_SHIM ] +
+  [ NO_FLEX ] +
+  [ CAPTION "<caption>" ] +
+  [ LABEL "<label>" ] +
+  [ SHIFT_LABEL +|-<vertical adjustment> ] +
+  [ SHORT_CAPTION "<short caption>" ] +
+  [ TARGET "<name>" ] +
+  [ CONTINUED | CONT | ... ]
+
+ +
+

+Note: Version 2.0-c change +
+2.0-c introduces revisions to EQ, including the addition +of a dash (-) to the positioning arguments +(-L, -C, and -I) and the removal of a +default value for -I. Other changes include passing all +options to .EQ (including the label) such that +.EN takes only a single, optional argument saying whether +the equation is to be continued at the next invocation of +.EQ. Please read this section carefully if you have +documents containing equations as they may need to be updated. +

+
+ +
+

+IMPORTANT: +All arguments to EQ must appear on the same line as +.EQ. Do not attempt to break them up with the +“line-continued” backslash. You may want to set your +text editor to “wrap” mode in order to see all your +arguments. This annoyance stems from the preprocessor mechanism +itself, not groff or mom. +

+
+ +
+

The .EQ macro

+
+ +

+Equations to be set with eqn begin with .EQ, +followed by eqn code. Equations are centered by default, +but may be set flush left or indented from the left margin +if -L or -I are passed as arguments to +.EQ. +

+ +
ADJUST
+ +

+ADJUST lets you raise (-) or lower +(+) an equation +within the space allotted for it +by the amount you specify. This is useful for achieving good +optical centering between surrounding blocks of type. A unit of +measure is required. +

+ +
NO_SHIM
+ +

+NO_SHIM instructs mom not to apply +shimming +after an equation, which she will do automatically when shimming is +enabled, which it is by default. Shimming ensures that running text +after the equation falls properly on the page’s +baseline grid, +but can result in slightly unequal spacing above and +below (correctable with the ADJUST argument). +NO_SHIM is useful when you have several equations on the +page and there are visible differences in the spacing beneath them +as a result of shimming. To ensure a flush bottom margin, the last +equation on the page should be shimmed, i.e. should not be given the +NO_SHIM argument. +

+ +
NO_FLEX
+ +

+NO_FLEX instructs mom not to apply +flex-spacing +after an equation, which she will do automatically when flex-spacing +is enabled. NO_FLEX is useful when you have several +equations on the page and you want to distribute excess vertical +whitespace on the page amongst other flex-spacing points on +the page. If there are no others, the final equation should be +flex-spaced, i.e. not given the NO_FLEX argument. +

+ +
CAPTION
+ +

+CAPTION allows you to give the equation a caption. +Equation captions always appear beneath the equation. +

+ +
SHORT_CAPTION
+ +

+SHORT_CAPTION allows you to trim long captions for +inclusion in the List of Equations. The text you supply, surrounded +by double-quotes, is what will appear in the List. +

+ +
LABEL
+ +

+LABEL, if given, appears on the same baseline as the last line of the +equation, flush with the left or right margin, depending on the +equation’s horizontal position. The text you supply, surrounded by +double-quotes, is how +the equation is labelled in both the document proper and the List of +Equations. Mom provides an auto-labelling facility for equations (see +AUTOLABEL), +which, if enabled, overrides the LABEL argument. +

+ +
SHIFT_LABEL
+ +

+SHIFT_LABEL allows you to raise (-) or lower +(+) the equation label. It’s primary use is to +center equation labels vertically on the equation rather than flush +with the last line. Assuming a three-line equation, +.EQ SHIFT_LABEL -1v would raise the label by +one line, thus centering it vertically on the equation. +

+ +
TARGET
+ +

+TARGET followed by a unique name surrounded by +double-quotes creates a PDF target for the equation so that it may +be linked to from other places in the file (with PDF_LINK; see +Producing PDFs with groff and mom). +

+ +

+Please note: The following functionality is available +only with groff 1.22.4 or later. +

+ +

+When +autolabelling +is enabled and the document is processed with +pdfmom, +the target name can be used to generate the target’s label +number in running text if it is entered as a groff string, i.e. of +the form \*[name]. For example, if you +create a target called “foo” for an equation whose +autolabel number would be 3, entering +
+ + See + .PDF_LINK foo "Equation \*[foo]" + +anywhere in running text would result in a pdf link that reads +“Equation 3”. If chapter numbers are being prefixed to +labels, the same string in, say, chapter 5 would produce the pdf +link “Equation 5.3”. +

+ + +
+

The .EN macro

+
+ +

+A block of eqn code is terminated with .EN. +

+ +

+If an equation needs to span multiple lines, possibly aligned +with eqn’s 'mark' and 'lineup' +directives, separate invocations of .EQ/.EN +are required for each line, and the optional argument, +CONTINUED (or CONT, or ... [three +dots, an ellipsis]), must be passed to .EN. +

+ +

+If -L or -I is given to the first +.EQ of a multi-line equation, they remain in effect +until an .EN without the CONTINUED argument +is reached. +

+ +

+Mom does not treat equations as floats, therefore it is possible to +begin an equation on one page and terminate it on the next. If you +wish to keep all lines of an equation together, you must wrap the +equation, including all invocations of .EQ/.EN, inside +a +float. +

+ +

+ +

refer support

+ +

+refer support is covered in the section +Bibliographies and references. +

+ +

+ +

Captions and labels

+ + + +

+Mom includes facilities for adding captions and labels to figures, +tables, equations, and pdf images, including auto-labelling. If +Lists of Figures, Tables, and Equations are desired, captions (if +any) and labels (if any) are collected and output in the Lists with +the appropriate page number. +

+ +

+The distinction between a caption and a label is that labels are +identifiers, e.g. “Fig. 1” or “Table 3”, +while captions are descriptive or informative. For most types of +writing, it is usual to provide both. +

+ +

+By default, mom sets captions above figures (i.e. pic output and +pdf images) and tables. This behaviour may be modified with the +macro +CAPTION_AFTER_LABEL. +Equations always have their captions set underneath. All aspects of +the text style for captions may be set with the macro +CAPTIONS. +

+ +

+Labels for tables are set underneath the table unless the +MLA +macro has been invoked, in which case the label and caption appear +above the table, per MLA style, and the source for the table, if +any, appears underneath. Labels for figures are set underneath. +Equation labels, by default, are set on the same baseline as the +last line of the equation. Like captions, all aspects of text style +for labels may be established with a single macro +LABELS. +Furthermore, mom can autolabel figures, tables, and equations, with +or without a prefixed chapter number. +

+ +
+

Autolabel

+
+ +
+Macro: AUTOLABEL_EQUATIONS +
+Macro: AUTOLABEL_IMAGES +
+Macro: AUTOLABEL_PIC +
+Macro: AUTOLABEL_TABLES +
+Arguments: +
+[ PREFIX "<string>"] [ SUFFIX "<string>"] [ PREFIX_CHAPTER [ <n> ] ] +
+
+ +

+AUTOLABEL_<type> takes care of labelling <type> by +identifying each with a separate, incrementing numeric scheme, which +is also collected for output in Lists of Figures, Equations, and +Tables. +

+ +

+Autolabelling may be disabled on-the-fly by giving any argument +other than PREFIX, SUFFIX, or +PREFIX_CHAPTER to the appropriate macro. For example, +
+ + .AUTOLABEL_IMAGES NO + +would disable autolabelling of images. +

+ +

Prefixes and suffixes

+ +

+By default, when AUTOLABEL is enabled, the label numbers are +prefixed, and, in the case of equations, suffixed, with strings such +that they appear for tables as “Table <n>”, for +pic diagrams and pdf images as “Fig. <n>”, +and for equations as “Eq. (<n>)”. +

+ +

+You can use PREFIX <"string"> to change what +comes before the automatic numbering. For example, if you are +including musical excerpts in your document, MLA style requires that +they be labelled “Ex. <n>”. Since musical +excerpts are likely to be scanned images (in pdf format, don’t +forget), you have to change the prefix string for pdf images: +
+ + .AUTOLABEL_IMAGES \ + PREFIX "Ex. " \ + SUFFIX "" + +If you need a suffix after the automatic numbering, use +SUFFIX <"string">, like this: +
+ + .AUTOLABEL_IMAGES \ + PREFIX "(Fig. " \ + SUFFIX ")" + +Note from the above that both arguments, PREFIX and +SUFFIX, are required should you want either. Two +adjacent double-quotes leaves the string blank. +

+ +
+

+Note: +In automatically formatted +“Lists of ...”, +label number prefixes are stripped when autolabelling is enabled. +

+
+ +

Prefixing chapter numbers

+ +

+If you would like mom to prefix chapter numbers to the label, +pass AUTOLABEL_<type> the argument +PREFIX_CHAPTER. +

+ +

+If for some reason you need to specify the chapter number, +you may do so by passing the number as an argument to +PREFIX_CHAPTER. Subsequent chapters or major sections +will increment by one as expected. +

+ +
+

+Note: +For the purposes of labelling, mom treats +DOCTYPE DEFAULT +as if it were DOCTYPE CHAPTER, hence, with +PREFIX_CHAPTER, each collated DEFAULT +doctype’s prefixed “chapter” number is +incremented and the label number itself reset to “1”. +If you do not supply the PREFIX_CHAPTER argument, the +label number is not reset automatically. To reset it, invoke +.AUTOLABEL_<type> after each +COLLATE. +

+
+ +
+Macro: SET_AUTOLABEL FIG | TBL | PIC | EQN <n> +
+ +

+You may sometimes need to set or reset the autolabel number for a +particular type of pre-processor or for PDF images. This is likely +to occur if you are using +FLOAT +in conjunction with the TO_LIST argument. +

+ +

+For example, if your document has Figures (PDF images, pic diagrams) +and you want your tables to be labelled as Figures as well, you have +to wrap the tables inside a float and label the float manually as +“Fig. n”, sending it to the List of Figures with +TO_LIST FIGURES. +

+ +

+Mom does not autolabel floats or assign them automatically +to a list, so she doesn’t know you’ve interrupted the +auto-incrementing label numbers. Use SET_AUTOLABEL get her back on +track. The number you give as an argument after telling her which +kind of label number to set is the one you want to appear next. +
+ + .SET_AUTOLABEL FIG 6 + +means the next autolabelled Figure will be “Fig. 6.” +

+ +
+

Captions after labels

+
+ +
+Macro: CAPTION_AFTER_LABEL IMG | PIC | TBL | ALL [ <anything> ] +
+ +

+By default, mom sets captions above figures (pic output +and pdf images) and tables; labels are always underneath. +

+ +

+.CAPTION_AFTER_LABEL, with one of the required arguments, +instructs mom to attach captions directly to the appropriate +labels, beginning on the same line. Any argument after the first +disables this behaviour, restoring caption placement to mom’s +default. For example, +
+ + .CAPTION_AFTER_LABEL ALL + +would enable captions after labels globally, while a subsequent +
+ + .CAPTION_AFTER_LABEL IMG OFF + +would disable captions after labels for pdf images only. +OFF can be anything you like (X, +NO, etc). +

+ +

+If +MLA +is enabled, there’s no need to invoke +CAPTION_AFTER_LABEL as this is implied. +

+ +
+

+Note: +A separate invocation of .CAPTION_AFTER_LABEL is required +for each one of the required first arguments. You cannot, for +example, do +
+ + .CAPTION_AFTER_LABEL IMG TBL + +Rather, you must do +
+ + .CAPTION_AFTER_LABEL IMG + .CAPTION_AFTER_LABEL TBL + +

+
+ +
+

MLA-style captioning and labelling

+
+ +
+Macro: MLA [ <anything> ] +
+ +

+Modern Language Association style dictates that captions should +always go after labels. Furthermore, labels and captions for tables +should go above the tables, with the source for the table, if +any, underneath. +

+ +

+Invoking .MLA by itself takes care of these details. If +you need to disable MLA-style captioning and labelling mid-document, +.MLA OFF does the trick. OFF can be +anything you like (X, NO, etc). +

+ +
+

Style parameters for captions, labels and sources

+
+ +
+Macro: CAPTIONS EQN | IMG | PIC | TBL | FLOATING | ALL +
+Macro: LABELS EQN | IMG | PIC | TBL | FLOATING | ALL +
+Macro: SOURCES TBL +
+Style arguments: +
+  FAMILY <family> \ +
+  FONT <font> \ +
+  SIZE +|-<size> \ +
+  AUTOLEAD <value> \ +
+  COLOR <color> \ +
+  QUAD LEFT | CENTER | RIGHT [ ON_LL ] \ +
+  INDENT <indent> \ +
+  ADJUST +|-<vertical adjustment> +
+
+ +
+

+Note: +Arguments may be broken into several lines using the +“line-continued” backslash (\), as shown above. +

+
+ +
+

+Additional note: +Mom’s default style for labels, captions, and sources is +the same as the style used for running text, with two exceptions: +labels are set in bold, except for eqn which is roman medium, and +the autolead value for all three is “2”, effectively +tightening the lead. Furthermore, they are quadded left (except +eqn, which is quadded right.) +

+
+ +

+With the exception of ADJUST and QUAD (which +requires a bit of explanation), the style arguments to CAPTIONS, +LABELS, and SOURCES (which is only available +for tables) behave identically to the +arguments to control macros. +

+ +

+The first, required argument after CAPTIONS, +LABELS, or SOURCES indicates the preprocessor +type for which you are setting the parameters. (For convenience +PDF_IMAGE—argument IMG—is here treated as a +preprocessor.) FLOATING sets the style for the macros +CAPTION +and +LABEL, +which are used to label floats, quotes, and blockquotes. +

+ +

+An argument of ALL sets a unified style for all +preprocessors, floats, quotes, and blockquotes. If the +ALL argument is given, arguments to subsequent +invocations of CAPTIONS, LABELS, or +SOURCES overwrite only the explicitly named style +parameters. +

+ +

QUAD — quadding of labels, captions, and sources

+ +
• pic, tbl, pdf images
+ +

+By default, figures (pic output and pdf images) and tables +have their captions and labels set quad left. Sources (for +tables) are also set quad left. Equations have their labels +set quad right, and their captions centered. +

+ +

+Regardless of the quad direction, captions, labels and sources +are set on the width of the figure, table, or pdf image +unless you pass the optional ON_LL argument to +QUAD <direction>, in which case +the prevailing document line length is used instead. +

+ +
• eqn
+ +

+Equations behave differently. By default, equation labels are +set flush right with the page’s right margin regardless of +equation positioning, which is, again by default, centered. If the +equation is positioned left, the label will appear at the right +margin regardless of the direction you give to QUAD. If +the equation is indented with the +-I <indent> option, a quad +direction of LEFT is observed, but may overprint the last +line of the equation. +

+ +

+Note that there is no CENTER option for equation labels, +and that captions are always quadded over the prevailing document +line length. +

+ +
• quotes and blockquotes
+ +

+Floating labels attached to QUOTEs are quadded on the +prevailing document line length, and require the INDENT +argument if you want to align them with the left and/or right edges +the quote. +

+ +

+Floating labels attached to BLOCKQUOTEs are always quadded on +the indent and line length of the blockquote. +

+ +
• floats
+ +

+Floating labels and captions attached to FLOATs are always +quadded over the prevailing document line length, and require the +INDENT argument if you want to align them with the left +and/or right edges of the float’s contents. +

+ +

INDENT

+ +

+The INDENT argument may only be used if the label +or caption type is FLOATING, and only applies to +FLOATs and QUOTEs, not BLOCKQUOTEs. +

+ +

+It is not possible for mom to know the width of a float before +setting a label or caption attached to a float. She therefore sets +it on the prevailing document line length. While this isn’t +much of an issue when the label or caption quad is CENTER, +you may want to adjust the horizontal positioning when the quad is +LEFT or RIGHT. +

+ +

+INDENT, with a numeric value to which a +unit of measure +is appended, allows you to indent a floating label or caption so +it lines up with the left edge of a FLOAT or QUOTE. +INDENT RIGHT (with a value) allows you to shorten the +line length to the appropriate width. If you need both a left and +right indent, invoke LABELS or CAPTIONS twice, +one instance containing INDENT <indent> and +the other INDENT RIGHT <indent>. +

+ +

ADJUST

+ +

+The ADJUST argument allows you to add(+) or +subtract (-) vertical space between labels and captions +and the output to which they are attached. The argument requires a +unit of measure. +For example, if you find that table labels are a bit too close to +the table itself, +
+ + .LABELS TBL ADJUST +3p + +would put three extra points of space between the bottoms of tables +and the labels that appear beneath them. +

+ +

Lists of Figures, Tables, and Equations

+ +

+Besides a +Table of Contents, +mom can generate Lists of Figures, Tables, and Equations. Labels +and captions are collected and concatenated, and output in lists +with the appropriate page number, just like a Table of Contents. +Including such lists in a document is as simple as adding whichever +you need of +
+ + .LIST_OF_FIGURES + .LIST_OF_EQUATIONS + .LIST_OF_TABLES + +to the end of your input file. +

+ +

+Also like the Table of Contents, entries in the Lists’ output +are clickable PDF links when a document is viewed at the screen. +

+ +

Placement of Lists

+ +

+Lists normally appear after the Table of Contents, and continue +the page numbering scheme used for it. By default, the Table of +Contents begins on roman-numeral page “i”. +

+ +

+If you are using mom’s +AUTO_RELOCATE_TOC +feature, you have two options for placement of the Lists within the +document. If you want the Lists shifted to the top of the document +along with the Table of Contents, invoke the Lists macros after +.TOC. +If you prefer to have the Lists at the end of the document, invoke +the Lists macros before .TOC. +

+ +

+Lists shifted with the Table of Contents do not appear in the Table +of Contents itself, but do appear as clickable links in the PDF +outline typically available in the left panel of most PDF viewers. +Lists that are not shifted with the Table of Contents appear in both +the Table of Contents itself and the PDF outline. +

+ +
+

Macros to generate Lists

+
+ +
+Macro: LIST_OF_EQUATIONS +
+Macro: LIST_OF_FIGURES +
+Macro: LIST_OF_TABLES +
+Arguments: +
+  [ TITLE_STRING "<string>" ] [ START_PAGENUM <page number> ] +
+
+ +

+The first optional argument to the LIST_OF_<type> +macros allows you to change the title that appears at the top of the +page. This is useful not only for internationalization, or to meet +the requirements of various style guides, but is also useful +for, say, documents containing musical examples, which, per +MLA-style, should be labelled “Example ” or +“Ex. ”. When it comes time to output the List of +Figures (to which musical examples, usually scanned pdf images, belong), +
+ + LIST_OF_FIGURES TITLE_STRING "List of Examples" + +ensures that the title of the List is correct. +

+ +

+The second optional argument allows you to give a starting page +number for a list in cases where mom’s pagination scheme does +not provide the List with the starting page number you want. +

+

Formatting and style parameters for Lists

+ +

+Like the Table of Contents, nearly every aspect of Lists can be +designed independently of a document’s overall style. By +default, Lists follow the formatting and style parameters of the +Table of Contents, both mom’s defaults and any changes you may +have made to the Table of Contents. +

+ +

+If you wish to make changes to any aspect of Lists formatting +or styling, the macro LISTS_STYLE provides all the +tools necessary. It is unlikely that you’ll want the +formatting of the various list types to differ one from the other, +so LISTS_STYLE applies to all Lists. In the event that +you do need to change some aspect of the formatting for different +list types, simply invoke LISTS_STYLE immediately prior +to each list whose formatting needs to be changed. +

+ +
+

Lists style

+
+ +
+Macro: LISTS_STYLE +
+Arguments: +
+  FAMILY <family> \ +
+  FONT <font> \ +
+  PT_SIZE <size> \ +
+  LEAD <leading> \ +
+  TITLE_FAMILY <family> \ +
+  TITLE_FONT <font> \ +
+  TITLE_SIZE +|-<size> \ +
+  TITLE_QUAD LEFT | CENTER | RIGHT \ +
+  TOC_HEADER_UNDERSCORE default = none +
+  TITLE_COLOR <color> \ +
+  PN_FAMILY <family> \ +
+  PN_FONT <font> \ +
+  PN_SIZE +|-<size> \ +
+  EQN_PN_PADDING <placeholders> \ +
+  FIG_PN_PADDING <placeholders> \ +
+  TBL_PN_PADDING <placeholders> \ +
+  PAGENUM_STYLE DIGIT | ROMAN | roman | ALPHA | alpha \ +
+  NO_PAGINATION +
+
+ +
+

+Note: +Arguments may be broken into several lines using the +“line-continued” backslash (\), as shown above. +

+
+ +

+FAMILY is the family for the entirety of Lists pages. +

+ +

+FONT is the font for the entirety of Lists pages. +

+ +

+PT_SIZE is the base point size for the entirety of Lists +pages. +

+ +

+LEAD is the base leading for the entirety of Lists pages. +

+ +

+TITLE_FAMILY is the family for the Lists titles if you +want it different from the family otherwise used for the Lists +pages. +

+ +

+TITLE_FONT is the font for the Lists titles if you want +it different from the font otherwise used for the Lists pages. +

+ +

+TITLE_SIZE tells mom by how much to increase +(+) or decrease (-) the point size of the +titles relative to the overall point size of Lists pages. +

+ +

+TITLE_QUAD tells mom how to position the title +horizontally. +

+ +

+TITLE_COLOR sets the colour for the titles. The colour +must be pre-initialized with +NEWCOLOR +or +XCOLOR. +

+ +

+PN_FAMILY sets the family for entry pagenumbers. +

+ +

+PN_FONT sets the font for entry pagenumbers. +

+ +

+PN_SIZE tells mom by how much to increase (+) +or decrease (-) the point size of entry pagenumbers +relative to the overall point size of Lists pages. +

+ +

+EQN_PN_PADDING, FIG_PN_PADDING, and +TBL_PN_PADDING tells mom how many placeholders to reserve +for the entry pagenumbers in their respective Lists. If, for example, +a document with both tables and figures runs to over a hundred +pages, but there are no tables after page 99, +
+ + LISTS_STYLE FIG_PN_PADDING 3 + LISTS_STYLE TBL_PN_PADDING 2 + +would prevent an unneeded, reserved placeholder from putting too +much space between the leader and the entry pagenumber in the List of +Tables. +

+ +

+The padding in effect, unless you change it, is whatever was set for +the Tables of Contents; mom’s default is “3”. +

+ +

+PAGENUM_STYLE tells mom which pagination format to use +for the page numbers of the Lists pages themselves. By default, +since Lists observe what is in effect for the Table of Contents, the +pagination format is “roman”. Please note that the +starting page number for any of the Lists is given as an argument to +the +LISTS_0F_<type> +macro. +

+ +

+NO_PAGINATION disables pagination of Lists pages. +

+ +

Shaded backgrounds and frames (boxes)

+ +

+Mom lets you add shaded backgrounds and frames to text and other +material. For convenience, she calls backgrounds and frames +“boxes.” Entire passages may be boxed, or individual +document elements like headings, quotes, or pre-processor output. +Furthermore, boxes may be nested. +

+ +

+Boxes start on the baseline where the boxed material would have +started were it not for the box, subject to minor aesthetic +corrections mom takes the liberty of making. +

+ +

+Boxes extend from the current left margin to the current right +margin, respecting any active left and/or right indents. There are +two exceptions, +EPIGRAPH BLOCK +and +BLOCKQUOTE, +which are discussed +here. +

+ +

+After a box is started, active left and right indents are +cleared. The box’s inset determines the new left and right +margins. Indents set inside a box are relative to the inset. +When a box is stopped, formerly active left and right indents +are restored. +

+ +

+Frames are drawn from the perimeter inward. The inset is +relative to the inner edge of the frame. +

+ +

+If a box (including the bottom inset) can complete on a page, it +does, even if there is no further room for type. This may, on +occasion, result in slight deviations from normal bottom margin +alignment. +

+ +

+Boxes span pages whenever the boxed material continues on the next +page. Spanning boxes extend fully to the bottom margin of the page +on which they begin, leaving a slightly larger inset at the bottom +than around the other sides. +

+ +

+When there is not enough room to set at least one line of type +inside a box, mom defers starting the box until the next page, +leaving a gap. +

+ +

+Boxed material is not +shimmed +or +flexed. +If either was active prior to the box, it is restored when the box +ends and mom automatically shims or flexes whatever comes next. +

+ +
+

+NOTE: +Shaded backgrounds and frames are not available when your +PRINTSTYLE +is TYPEWRITE or when +COLUMNS are enabled. +

+
+ +
+

BOX

+
+ +
+Macro: BOX [ <arguments> ] | <anything> +
+Arguments: +
+[ SHADED <color> | OUTLINED <colour> ] \ +
+[ INSET <dist> ] \ +
+[ WEIGHT <wt> ] \ +
+[ ADJUST +|-<amount> ] \ +
+[ EQN | PIC | GRAP | IMG ] +
+
+ +

+Without arguments, BOX begins a shaded grey background. +The material inside is inset by one +pica. +Any other type of box requires at a minimum either +SHADED or OUTLINED. In the case of boxes +that are to contain pdf images or pre-processor material for +eqn, +pic, +or +grap, +IMG, EQN, PIC, or GRAP +must also be given. Note that +tbl +does not have this requirement. +

+ +

+BOX is a +toggle macro, +so any argument other than one in the list completes the box +(QUIT, END, X, etc). +

+ +

+Boxes should be started inside toggle macros like +QUOTE +or +FLOAT +just after the macro is called, and terminated just before toggling +the macro off (unless you wish the box to enclose further material). +

+ +

+Non-toggle macros like +HEADING +or +PP +require that the box be started beforehand. Boxed pre-processor +material must be fully enclosed by BOX / BOX OFF, as +in this recipe for a one-off boxed pic diagram: + +.BOX +.PS +<pic commands> +.PE +.BOX OFF + +Arguments to BOX are not sticky. Each time you invoke BOX, you +must invoke it with arguments unless you want mom’s default grey +background. If all or several boxes in a document require the same +arguments, create a macro at the top of the input file that calls +BOX with the arguments you want, e.g. + +  .de PINK_BOX +  .BOX \ +    SHADED pink \ +    OUTLINED darkred \ +    WEIGHT 1p \ +    INSET 9p +  .. + +.PINK_BOX may then be used instead of .BOX any +time you want a box with those arguments. +

+ +

SHADED | OUTLINED

+ +

+SHADED or OUTLINED are required. Both may +be given, resulting in a shaded background with a frame, and both +require a colour, e.g. + +  .BOX SHADED blue OUTLINED black + +The colour may be +

+ +
    +
  • an xcolor name
  • +
  • a colour initialized with + NEWCOLOR + or + XCOLOR +
  • +
  • an RGB hexadecimal string beginning with (e.g. #FF0000)
  • +
+ +

+Note that without SHADED, the above would simply draw a +black frame. +

+ +

WEIGHT

+ +

+Mom’s default weight for OUTLINED is 1/2 +point. +If you’d like to change it, give WEIGHT the desired +value with a unit of measure appended, typically points, e.g. + +  .BOX OUTLINED black WEIGHT 1p + +

+ +

INSET

+ +

+Mom’s default inset for boxes is one +pica +on all sides. If you’d like a larger or smaller inset, give +INSET the distance you want with a unit of measure +appended, e.g. + +  .BOX SHADED pink INSET 2m + +

+ +

ADJUST

+ +

+If you are not happy with the starting position of a box, you can +change it by giving ADJUST the distance you want it +raised (-) or lowered (+) with a unit of measure appended. For +example, to lower a box three points, + +  .BOX OUTLINED black ADJUST +3p + +To raise it, + +  .BOX OUTLINED black ADJUST -3p + +

+ +

PIC / GRAP / EQN / IMG

+ +

+The PIC argument must be given to BOX if the box contains +any +pic +diagrams. Likewise, graphs made with +grap, +equations made with +eqn, +and +pdf images +require a corresponding GRAP, EQN, or +IMG argument. +

+ +

+If you’re boxing a single diagram, graph, or pdf image, wrap +it in a float, like this: + +  .FLOAT +  .BOX PIC <other parameters> +  .PS +  <pic input> +  .PE +  .BOX OFF +  .FLOAT OFF + +Notice that in the case of pdf images, pic, and grap, this +represents a change from the norm, where the use of FLOAT may be +destructive and is discouraged. +

+ +

Additional notes on BOX usage and behaviour

+ +

QUOTE, BLOCKQUOTE, EPIGRAPH, FLOAT

+ +

+QUOTE, +BLOCKQUOTE, +EPIGRAPH, +and +FLOAT +require that boxes be started after they are +invoked and stopped just before they are toggled off: + +  .QUOTE +  .BOX <parameters> +  Text of quote +  .BOX OFF +  .QUOTE OFF + +

+ +

CODE

+ +

+If you’re boxing +CODE +that’s wrapped inside +QUOTE, +as described +here, +set the quote indent to “0” with + +  .QUOTE_STYLE INDENT 0 + +so that the box’s leftmost inset is respected. +

+ +

+Here’s a recipe for setting boxed code with an 18-point inset: + +  .QUOTE_STYLE INDENT 0 +  .QUOTE +  .CODE +  .BOX INSET 18p +  Hello, world. +  .BOX OFF +  .QUOTE OFF + +Note that CODE, wrapped inside QUOTE, does not require a corresponding CODE OFF. +

+ +

Description of boxed BLOCKQUOTES and EPIGRAPH BLOCKS

+ +

+When you box a BLOCKQUOTE, or an EPIGRAPH with the BLOCK +argument, the box is centred on the page and is only as wide as the +blockquote or epigraph plus the box’s inset. +

+ +

+QUOTE and EPIGRAPH (without the BLOCK argument), on the +other hand, set the box fully to the left and right margins. +

+ +

Leftover box syndrome

+ +

+Boxed quotes and blockquotes sometimes exhibit leftover box +syndrome, where the page after a fully terminated boxed quote or +blockquote begins with an empty bit of box. Equally, you may +sometimes see the lower edge of a quote’s or +blockquote’s box falling slightly below the page’s +bottom margin. +

+ +

+The solution in both situations is to use the ADJUST +argument to raise or lower the box’s starting position. +Leftover box syndrome is usually fixed by raising the box slightly. +When the box runs too deep, lowering it is generally recommended, +although this will result in a widowed line at the top of the next +page. In either case, some experimentation is necessary. +

+ +

SLIDES

+ +

+On a slide with no pauses, boxes behave as they do in printed +documents. +

+ +

+When a slide contains pauses, only the material up to the first +pause is boxed. As subsequent material is revealed, the box changes +location, moving down to surround each new item. This behaviour +persists until the box is stopped, making it useful for highlighting +material as it is revealed. +

+ +

Footnotes

+ +

+You don’t have to worry about boxes encroaching on footnotes. +Mom makes sure they don’t. +

+ +

Page colour

+ +

+Mom lets you change the page (“paper”) colour +from white to anything you like. While this has limited application +in printed documents, it can be effective in +slide presentations. +

+ +
+

PAGE_COLOR

+
+ +
+Macro: PAGE_COLOR <color> | OFF | off +
+

+Aliased as PAGE_COLOUR, SLIDE_COLOR, +and SLIDE_COLOUR. +

+ +

+When you invoke PAGE_COLOR with a color argument, the +current and subsequent pages turn the colour you request. If +more than one instance of PAGE_COLOR appears before a page break, +including PAGE_COLOR OFF, only the last applies. +

+ +
+

+Note: +Unlike other +toggle macros, +PAGE_COLOR requires the use of OFF or off +to terminate it rather than an arbitrary string (OFF, +QUIT, END, X, etc). +

+
+ +

+ + + + + + + + +
Back to Table of ContentsTopNext: Page headers/footers, pagination
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/inlines.html b/contrib/mom/momdoc/inlines.html new file mode 100644 index 0000000..8613161 --- /dev/null +++ b/contrib/mom/momdoc/inlines.html @@ -0,0 +1,1112 @@ + + + + + + + + Mom -- Inline escapes + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: Coloured text
+ +

Inline escapes

+ + + +

+ +

Introduction

+

+Inline escapes, as described in the +groff terms +section of this manual, are typesetting commands that appear in text +input lines, +as opposed to macros and other +control lines +that must appear on lines by themselves. +

+ +

+Aside from altering type parameters within a line, inlines also tell +groff about special characters—em-dashes, bullets, +figure/digit-width spaces, +and so on. It is beyond the scope of this manual to provide +a complete list of groff’s inline functions and special +characters. I recommend having a look at the +canonical reference materials +should you need more information than is contained herein. +

+ +

+In groff, the escape character is the backslash (\). +Groff interprets everything following the backslash as instructions, +not literal text, until the escape sequence is complete. Should +you need the actual backslash character as part of a line of text, +simply enter it twice (\\). Groff understands that this +means “please print a backslash character.” +

+ +

+You can also use \e to print a literal backslash, or use +ESC_CHAR to change the escape +character to something other than the backslash, which lets you +use a single backslash as a literal backslash. +

+ +

+Groff has a number of ways of recognizing what constitutes a +complete escape sequence. This is both a boon and a curse; some +escape sequences have no terminating delimiter and consequently +become difficult to distinguish from real input text. Others +require the use of an opening parenthesis with no corresponding +closing parenthesis. Still others need to be enclosed in square +brackets. +

+ +

+Mom recognizes that certain escapes get used more often than others. +For these, she has a consistent input style that takes the form +\*[...], which makes them stand out well +from the text of your documents. These escapes are the ones listed +under +Mom’s personal inline escapes. +

+ +

+Despite mom’s best intentions, there are still +a number of typesetting functions that can only be accomplished +with groff’s native inline escapes. I’ve listed the +ones that strike me as essential, but there are many others. If you +want to know what they are, please read the +canonical reference materials +pertaining to groff. +

+ +
+

+Helpful bit of information: +Inline escapes can be used in +document processing macros +that take +string arguments. +

+
+ + + +

+ + + +

Mom’s personal inline escapes

+ +

Changing fonts

+ +

+Mom provides five escapes for changing fonts inline: +
+ + \*[ROM] Change to the medium roman font + \*[IT] Change to the medium italic font + \*[BD] Change to the bold roman font + \*[BDI] Change to the bold italic font + \*[PREV] Revert to the previous font (once only)* + +

+ +
+

+*Note: +\*[PREV] does not operate "stack +style". It returns to the previous font once only, and +afterwards has no effect. In other words, in the case of +\*[PREV]\*[PREV], only the first +\*[PREV] is respected; the second one is silently +ignored. +

+
+ +

+These escapes are provided for merely for convenience, legibility, +and consistency when typesetting with mom. For more complete and +flexible inline font control, please see +font control with \f. +

+ +
+

Notes concerning document processing

+

+If you’re using the +document processing macros, +inline font changes remain in effect only for the duration of the +current document element tag. +

+ +

+Additionally, if you’re designing your own +HEADERS or FOOTERS +and want to use mom’s inline escapes for changing fonts as +part of the left, centre and/or right strings, or in the strings +for +recto +and/or +verso +HEADERS or FOOTERS, or in the strings passed to +HEADERS_AND_FOOTERS, +you must enter the inlines beginning with \E* +rather than just \*, e.g. +\E*[BD]. You may, in such cases, prefer to +use the simpler groff inline escape +\f. +

+
+ + + +

Changing point size

+

+Mom has two inline escapes for changing point size: +
+ + \*[SIZE <size>] + +and +
+ + \*S[<size>] + +where “size” is the new size you want. You can use +either; they behave exactly the same way. For example, to change +the point size of type inline to 12 points, you could enter either +
+ + \*[SIZE 12] + +or +
+ + \*S[12] + +Entering either \*[SIZE] or +\*S[] with no argument reverts to the former +point size. +

+ +

+The advantage of the first form is that it’s easy to remember, +and follows mom’s usual inline syntax. The advantage of the +second is that it’s more concise. +

+ +

+Notice that in both cases, the new size does not require a +unit of measure; +points +is assumed. However, a unit of measure may be appended to the size +if that’s what you wish. Fractional sizes are, of course, +allowed. +

+ +

+The size given to \*[SIZE <size>] +or \*S[<size>] may be expressed in +plus or minus terms, which can be very useful. In the following +examples, the word “mom” will be output 2 points larger +than the point size of the rest of the line. +
+ + While she isn't perfect, \*S[+2]mom\*S[-2] isn't half bad. + While she isn't perfect, \*[SIZE +2]mom\*[SIZE -2] isn't half bad. + +Please note that inline size changes do not update the leading if +AUTOLEAD +is enabled. +

+ +
+

NOTE CONCERNING DOCUMENT PROCESSING

+

+If you’re using the +document processing macros +and wish to design your own +HEADERS or FOOTERS +using mom’s inline escape for changing point size as part of +the left, centre and/or right strings, or in the strings for +recto +and/or +verso +HEADERS or FOOTERS, or in the strings passed to +HEADERS_AND_FOOTERS, +you must use the form \*S[<n>] +and enter the inline beginning with \E*, like this: +\E*S[<+|-><n>]. +

+ +

+Additional note: +If you’re accustomed to groff’s usual way of handling +inline size requests (\sN, \sÂąN, \s(NN, \sÂą(NN, \s[NNN], +\sÂą[NNN]), feel free to continue with your old habits. Mom +doesn’t care. +

+
+ + + +

Capitalise a section of type

+

+If you need to capitalise a region of type inline, +bracket the region of type with the inline escapes, +\*[UC] (Upper Case) and +\*[LC] (Lower Case), like this: +
+ + All work \*[UC]and\*[LC] no play makes Jack a dull boy. + +The above produces, on output +
+ + All work AND no play makes Jack a dull boy. + +

+ +
+

+Note: +\*[UC] and \*[LC] must not be used inside the +string arguments +passed to the +HEADER_<POSITION> +macro. Instead, use the control macro +HEADER_<POSITION>_CAPS. +For +HEADER_RECTO +(or _VERSO) or +FOOTER_RECTO +(or _VERSO), supply the CAPS option to the appropriate +macro. +

+
+ + + +

Pairwise kerning

+

+Pairwise kerning means moving specific letter pairs closer +together or further apart (see +Typesetting terms, kerning +for more details). +

+ +

+Mom permits inline pairwise kerning through the use of the inline +escapes +
+ + \*[BU <n>] Closes the space between letters (Back Units). + \*[FU <n>] Opens the space between letters (Forward Units). + +<n> is the number of +kern units +by which to close or open the space between letters. +

+ +

+For example, +
+ + THE HUMAN COST OF COMMODIF\*[FU 1]YING FRESH W\*[BU 4]A\*[BU 5]TER + +moves the letter Y in “COMMODIFYING” one kern unit away +from the letter F, and the letter A in “WATER” four +kern units closer to the letter W. Additionally, the letter T in +“WATER” is moved five kern units closer to the letter A. +

+ +

+For backward compatibility, the forms +
+ + \*[BU1]...\*[BU36] Move backward 1...36 kern units + \*[FU1]...\*[FU36] Move forward 1...36 kern units + +also exist (i.e. with no space before the number of kern units desired, +up to a limit of 36). +

+ +

+The default size of a kern unit is 1/36 of the current point size; +this may be changed by invoking the macro .KERN_UNIT +with the desired value, which represents a fraction of the current +point size. For example, to change the kern unit to 1/54 of the +current point size, +
+ + .KERN_UNIT 54 + +To restore the kern unit to its default, invoke +.KERN_UNIT with an argument of DEFAULT. +

+ + +
+

Notes concerning document processing

+

+If you’re using the +document processing macros +and wish to design your own +HEADERS or FOOTERS +using mom’s inline escapes for kerning as part of the left, +centre and/or right strings, or in the strings for +recto +and/or +verso +HEADERS or FOOTERS, or in the strings passed to +HEADERS_AND_FOOTERS, +you must use the forms +\E*[BU<n>] and +\E*[FU<n>] (i.e. with no space), +and enter the inline beginning with \E* +rather than just \*, e.g. +\E*[BU4]. +

+ +

+Additional note: +Using the BU or FU escapes between characters +pairs that are already automatically kerned (see +KERN) +disables the automatic kerning and uses the value you give to +BU or FU instead. +

+
+ + + +

Horizontal inline movement

+

+Sometimes, you may need to insert a specified amount of white +space into an +output line, +or—occasionally—back up to a previous position on an +output +line in order to create special typographic effects. +

+ +

+Mom’s inline escapes for these horizontal movements are +
+ + \*[BCK <n unit>]  Move backward inline the specified number of + units of measure; decimal fractions are allowed. + +and + + \*[FWD <n unit>]  Move forward inline the specified number of + units of measure; decimal fractions are allowed. + +

+ +

+For example, +
+ + 1.\*[FWD 12p]The Free Trade Play-Offs: WalMart 100, Mexico 0 + +puts 12 points of space between 1. and +The. +

+ +
+

+Note: +For backward compatibility, the forms +
+ + \*[BP.25]...\*[BP12.75] Move backward .25...12.75 points + \*[FP.25]...\*[FP12.75] Move forward .25...12.75 points + +also exist (i.e. with no space before the digit and points being +the unit of measure, hence no unit of measure required). Both +accept quarter points, so it’s possible to do, +for example, \*[FP.5] or +\*[BP1.25] up to a limit of 12.75 points. +

+
+ +
+

Note concerning document processing

+

+If you’re using the +document processing macros +and wish to design your own +HEADERS or FOOTERS +using mom’s inline escapes for horizontal movements as part of +the left, centre and/or right strings, or in the strings for +recto +and/or +verso +HEADERS or FOOTERS, or in the strings passed to +HEADERS_AND_FOOTERS, +you must use the forms +\E*[BP<n>] and +\E*[FP<n>] (i.e. with no space), +and enter the inline beginning with \E* +rather than just \*, e.g. +\E*[BP.75]. You may, in such cases, prefer +to use the native groff inline escape +\h. +

+
+ + + +

Vertical inline movement

+

+If you need to move portions of type up or down on a line, mom +provides the following inline escapes: +
+ + \*[DOWN <n unit>] Move down inline the specified number of + units of measure + + \*[UP <n unit>] Move up inline the specified number of + units of measure + +For example, +
+ + Tel: 905\*[UP 1p]-\*[DOWN 1p]4072 + +moves the hyphen in the telephone number up by 1 point, then +moves back down by the same amount. +

+ +
+

+Note: +\*[UP] and +\*[DOWN] +do not work in conjunction with the inline escape, +\*[RULE]. +

+ +

+Additional note: +For backward compatibility, the following are also available: +
+ + \*[ALD.25]...\*[ALD12.75] Advance lead .25...12.75 points (move downward) + \*[RLD.25]...\*[RLD12.75] Reverse lead .25...12.75 points (move upward) + +

+ +

+Both \*[ALD] and +\*[RLD] work in points, hence you +mustn’t use a unit of measure. +

+
+ +
+

Note concerning document processing

+

+If you’re using the +document processing macros +and wish to design your own +HEADERS or FOOTERS +using mom’s inline escapes for vertical movements as part of +the left, centre and/or right strings, or in the strings for +recto +and/or +verso +HEADERS or FOOTERS, or in the strings passed to +HEADERS_AND_FOOTERS, +you must use the forms +\E*[ALD<n>] and +\E*[RLD<n>] (i.e. with no space), and enter the +inline beginning with \E* rather than just +\*, +e.g. \E*[ALD.5]. +You may, in such cases, prefer to use the native groff inline +escape +\v. + +

+
+ + + +

Terminate a line without advancing on the page

+

+Sometimes, you want mom to break a line but not advance on the page. +This can be accomplished with the macro +EL +or with the escape \*[B]. Simply attach +\*[B] to the end of any input line. Using +the example given in the document entry for EL, you’d use +\*[B] like this: +
+ + .LEFT + .LS 12.5 + A line of text.\*[B] + .ALD 24p + The next line of text. + + +\*[B] works reliably regardless of the current +fill mode. +

+ + + +

Call the next sequential tab without advancing on the page

+

+Sometimes, you want mom to move to the next tab in sequence (e.g. +from TAB 1 to TAB 2, or TAB 8 to TAB 9) without mom advancing on the +page. (See the NOTE +here +if you’re not clear how mom manages tabs and linebreaks.) To +do so, simply attach the escape \*[TB+] to +the end of the input line in previous tab, like this: +
+ + .TAB 1 + Some text\*[TB+] \" In tab 1 + Some more text \" In tab 2, same baseline. + + +\*[TB+] works reliably regardless of the +current +fill mode. +

+ + + +

Full measure rules

+

+I find I often need rules drawn to the full measure of the +current line or tab length. The official way to do this is +\l'\n[.l]u', which is annoying to type, +and doesn’t mean a whole heck of a lot if you’re new +to groff. The inline, \*[RULE], is a +simple replacement for \l'\n[.l]u'. Use it +whenever you need a rule drawn to the full measure of the current +line or tab length, for example: +
+ + .LL 6P + \*[RULE] + + +The above draws a rule the full measure of the 6-pica line length. +For another way to draw full measure rules, see the macro +DRH. +

+ +

+\*[RULE] must appear on an +input line +by itself, and always causes a break when entered after a normal +input line of text. It does not, however, deposit a break when used +immediately after a macro. +

+ +

+The weight of the rule drawn with \*[RULE] +is controlled with the macro +RULE_WEIGHT. +Mom’s default is 1/2 point. +

+ +
+

+Note: +\*[RULE] draws the rule to the full measure, +hence it cannot be used to fill the remainder of a partial line with +a rule in this way: +
+ + Signature__________________________________________ + +If you wish to accomplish this effect, you have to use +\*[RULE] in conjunction with the +PAD +macro and +string tabs. +(See the +example +provided with PAD.) + +

+ +

+Please also note that the inline escapes +\*[UP] +and +\*[DOWN] +cannot be used in conjunction with \*[RULE]. +

+ +

+This doesn’t work: +
+ + \*[DOWN 2p]\*[RULE]\*[UP 2p] + +whereas this does: +
+ + .ALD 2p + \*[RULE] + .RLD 2p + +

+ +

+See groff’s +Horizontal line drawing function +for more information on drawing horizontal rules. +

+
+ + + +
+Macro: RULE_WEIGHT <weight in points> +
+ +

+• Must not have a +unit of measure +appended. +
+  Argument must be greater than 0 and less than 100; decimal +fractions are allowed. +

+ +

+RULE_WEIGHT allows you to tell mom how heavy (in other words, how +“thick”) you want the rules drawn with the inline +escape, +\*[RULE]. +It takes a single argument: the weight of the rule in +points +but without the +unit of measure +p attached. Thus, to set the weight of rules +drawn with \*[RULE] to 1-1/4 points, +you’d do +
+ + .RULE_WEIGHT 1.25 + +

+ +

+RULE_WEIGHT also sets the weight of rules drawn +with +.DRH +when DRH is not given any arguments. +

+ +

+ + + +

Commonly-used groff inline escapes

+ +

Font control (\f)

+ +

+Groff’s basic mechanism for inline font control is the escape +\f[<font>]. +
+ + \f[R] Change to the medium roman font (equivalent to mom's \*[ROM]) + \f[I] Change to the medium italic font (equivalent to mom's \*[IT]) + \f[B] Change to the bold roman font (equivalent to mom's \*[BD]) + \f[BI] Change to the bold italic font (equivalent to mom's \*[BDI]) + \f[P] Revert to the previous font (equivalent to mom's \*[PREV]) + +

+ +

+\f[<font>] can be used with any valid +font style +registered with groff. (See +here +for a list of pre-registered font styles provided by mom). +

+ +

+\f[<family><font>] can also take a complete valid +family+font name combo. This is especially useful should you +need to change both family and font inline. For example, if your +prevailing family and font are Times Roman and you want a few words +in Courier Bold Italic, you could do this: +
+ + .FAM T + .FT R + The command \f[CBI]ls -l\f[P] gives a "long" directory listing. + +The Unix command ls -l will appear in Courier Bold Italic +in a line that is otherwise in Times Roman. +

+ + + +

Inline horizontal motions (\h)

+ +

+Whenever you need to move forward or backward on a line, use the +inline +
+ + \h'<distance>' + +In order to avoid unpleasant surprises, always append a +unit of measure +to <distance>. For example, +
+ + \h'1.25i' + +moves you 1.25 inches to the right (forward) of the horizontal +position on the current +output line. +

+ +
+

+Note: +\h'<distance>' is exactly equivalent to a +\*[FWD n<unit>]. +

+
+ +

+To move backwards by the same amount, do +
+ + \h'-1.25i' + +

+ +
+

+Note: +\h'-<distance>' is exactly equivalent to +\*[BCK n<unit>]. +

+
+ + + +

Inline vertical motions (\v)

+ +

+If you need to raise or lower type on a line (say, for sub- or +superscripts, or any other special effect), use +
+ + \v'<distance>' + +In order to avoid unpleasant surprises, always append a +unit of measure +to <distance>. For example, +
+ + \v'.6m' + +moves you (approx.) 2/3 of an +em +downward on the current +output line. +

+ +
+

+Note: +\v'<distance>' is exactly equivalent to +\*[DOWN n<unit>]. +

+
+ +

+To move upward an equivalent amount, do +
+ + \v'-.6m' + +

+ +
+

+Note: +\v'<-distance>' is exactly equivalent to +\*[UP n<unit>]. +

+
+ +
+

+Important: +The vertical motion of \v only affects type on the +current +output line. +When groff breaks the output line, the effect of +\v is cancelled; the baseline of the next output line +is where it would be if you hadn’t used \v. +

+
+ +
+

+Tip: +When using \v for occasional effects in a line, +don’t forget to reverse it when you’ve done what you +want to do. Otherwise, the remaining type will be set too high (if +you used \v with the minus sign) or too low (if you used +\v without the minus sign). +

+
+ + + +

String width function (\w)

+ +

+In the context of mom, the string width inline +\w'<string>' primarily serves to let you establish the +horizontal measure of something (e.g. indents) based on the length +of a bit of text. For example, if you want a left indent the length +of the word “Examples:” plus a space, you can set it with +the \w inline escape: +
+ + .IL "\w'Examples: '" + +

+ +
+

+Note: +Whenever you pass \w'string' +to a macro that normally requires a +unit of measure, +do NOT add a unit of measure to the +\w'string' argument. +

+ +

+Furthermore, if the \w is used in place of a +numeric argument +to a macro and string is composed of several words +separated by spaces, you must surround the whole escape with double +quotes, as in the example above. +

+
+ + + +

Horizontal line drawing function (\l)

+ +

+The \l'distance' inline allows you to draw a horizontal +rule of the specified distance. You must supply a +unit of measure. +Therefore, to set a 3-pica rule into a line of text, you’d do +
+ + A line of text with a superfluous \l'3P' 3-pica rule in it. + +\l'3P', above, not only draws the rule, but advances 3 +picas horizontally as well, just as you’d expect. +

+ +

+For an easy way of drawing rules to the full measure of the current +line or tab length, see +Full measure rules. +

+ +

+The weight (thickness) of rules varies according to the point +size in effect when you invoke \l, but you can’t fix +the weight with any real precision. A point size of 12 produces +a tastefully moderate rule weight of between one-half and one +point (depending on your printer). +

+ +
+

+Note: +Besides \l, groff provides a number of more +sophisticated “drawing” escapes. It is well beyond +the scope of this documentation to demonstrate their usage; see +
+ + info groff \\D + +for directions concerning their use. The drawing escapes can be a +bit unwieldy, so mom provides “user-friendly” macros for +the +graphical objects +most commonly encountered in typesetting: horizontal and vertical +rules, boxes, and circles (ellipses). +

+ +

+Additionally, groff comes with two “preprocessors” that +let you create ruled tables and vector diagrams (line drawings): +tbl and pic. The documentation for tbl can be +downloaded from +
+ http://cm.bell-labs.com/cm/cs/doc/76/tbl.ps.gz +
+and pic from +
+ http://www.kohala.com/start/troff/gpic.raymond.ps +
+Both are powerful tools, but they can be nasty to learn—at +first, anyway. You may prefer to use a vector drawing program +to create diagrams and tables; inserting the results into a +document is easy enough with +PDF_IMAGE +or +PSPIC. +

+
+ + + +

Special characters and symbols

+

+Here follows a short list of commonly-used special characters +available via inline escapes. If you’re not sure of the +meaning of some of these characters, consult the +Definitions of Terms. +

+ +

+For a complete list of special characters and glyphs (i.e. just +about anything you’d ever want to appear on the printed +page, including mathematical symbols, accented characters, unusual +ligatures and letters unique to various European languages), consult +man groff_char. +

+ + + CHARACTER ESCAPE SEQUENCE + --------- --------------- + Comment line \# or .\" + Fixed-width space \<space> + Unbreakable space \~ + Digit-width (figure) space \0 + Zero-width character \& + Discretionary hyphen \% + Backslash \\ or \e + Plus/minus (arithmetic) \[+-] + Subtract (arithmetic) \[mi] + Multiply (arithmetic) \[mu] + Divide (arithmetic) \[di] + Em-dash \[em] + En-dash \[en] + Left double-quote \[lq] + Right double-quote \[rq] + Open (left) single-quote \[oq] + Close (right) single-quote \[cq] + Bullet \[bu] + Ballot box \[sq] + One-quarter \[14] + One-half \[12] + Three-quarters \[34] + Degree sign \[de] + Dagger \[dg] + Foot mark \[fm] + Cent sign \[ct] + Registered trademark \[rg] + Copyright \[co] + Section symbol \[se] + +
+ +

+ + + + + + + + +
Back to Table of ContentsTopNext: Coloured text
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/intro.html b/contrib/mom/momdoc/intro.html new file mode 100644 index 0000000..3e25631 --- /dev/null +++ b/contrib/mom/momdoc/intro.html @@ -0,0 +1,487 @@ + + + + + + + + + What is mom? + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: Definitions
+ +

What is mom?

+ + + +

+ +

Who is mom meant for?

+ +

+Mom (“my own macros”, “my other macros”, +“maximum overdrive macros”...) is a macro set for groff, +designed to format documents in Portable Document Format (.pdf) and +PostScript (.ps). She’s aimed at three kinds of users: +

+ +
    +
  1. Typesetters who suspect groff might be the right + tool for the job but who are frustrated, + intimidated, or puzzled by groff’s terse, + not-always-typographically-intuitive + primitives; +
  2. +
  3. Writers who need to format their work easily, with a + minimum of clutter; +
  4. +
  5. Newcomers to groff, typesetting, or document processing + who need a well-documented macro set to get them started. +
  6. +
+ +

+Mom is actually two macro packages in one: a very complete set +of typesetting macros, and an equally thorough set of document +formatting macros. The typesetting macros afford fine-grained +control over all visible aspects of page layout and design (margins, +fonts, sizes, kerning, etc), while the document formatting macros +focus on the logical structure of a document (titles, headings, +paragraphs, lists, etc) and call on groff to render logical +structure into pleasing type. +

+ +

Typesetting with mom

+ +

+Mom’s typesetting macros control the basic parameters +of type: margins, line lengths, type family, font, point size, +linespacing, and so on. In addition, they allow you to move +around on the page horizontally and vertically, and to set up +tabs, indents, and columns. Finally, they let you adjust such +typographic details as justification style, letter spacing, word +spacing, hyphenation, and kerning. +

+ +

+The typesetting macros also provide the means to create horizontal +and vertical rules, rectangles (boxes, frames), and ellipses +(circles). +

+ +

+In terms of typographic control, the typesetting macros provide +access to groff’s primitives in a way that’s consistent, +sensible, and easy to use. With them, you can create individual +pages designed from the ground up. Provided you have not signalled +to mom that you want document processing (via the +START +macro; see below), every typesetting macro is a literal command +that remains in effect until you modify it or turn it off. This +means that if you want to create flyers, surveys, tabulated forms, +curricula vitae and so on, you may do so in the good old-fashioned +way: one step at a time with complete control over every element on +the page. +

+ +

+Years of experience have convinced me that no program can ever +replace the human eye and human input when it comes to high quality +typesetting. Words and punctuation on the printed page are too +variable, too fluid, to be rendered flawlessly by any algorithm, +no matter how clever. +

+ +

+Mom, therefore, does not try to guess solutions for issues like +hanging punctuation, or left-margin adjustments for troublesome +letters like T, V and W. Rather, she provides tools that allow +knowledgeable typesetters to handle these typographic challenges in +ways that are easier and more intuitive than manipulating groff at +the primitive level. +

+ +

Document processing with mom

+ +

+Mom’s document processing macros let you format documents +without having to worry about the typographic details. In this +respect, mom is similar to other groff macro packages, as well as +to html and LaTeX. Where mom differs is in the degree of control +you have over the look and placement of the various elements of a +document. For example, if you’d like your headings underlined, +or in caps, or centred rather than flush left, you can make the +changes easily and have them apply to the whole document. Temporary +and one-off changes are easy, too. +

+ +

+Mom has some features other macro sets don’t provide. For +example, you can switch between draft-style and final-copy output. +If you regularly make submissions to publishers and editors who +insist on "typewritten, double-spaced," there’s a special +macro— +PRINTSTYLE TYPEWRITE— +that changes typeset documents into ones that would make an +old-school typing teacher proud. Footnotes, endnotes, tables of +contents, multiple columns, nested lists, recto/verso printing and +user designable headers and footers are also part of the fun. +

+ +

Mom’s philosophy

+ +

+Formatting documents should be easy, from soup to nuts. Writers +need to focus on what they’re writing, not on how it looks. +From the moment you fire up an editor to the moment you add +"FINIS" to your opus, nothing should interfere with the flow of +your words. The commands needed to format your work should be +easy to remember, comprehensible, and stand out well from the +text. There shouldn’t be too much clutter. Your documents +should be as readable inside a text editor as they are on the +printed page. +

+ +

+Unfortunately, in computerland, “easy,” +“comprehensible,” and “readable” often +mean “you’re stuck with what you get.” No +document formatting system can give you exactly what you want all +the time, every time. Documents always need to be tweaked, either +to satisfy a typographic whim or to clarify some aspect of their +content. +

+ +

+Groff has traditionally solved the problem of formatting vs. +tweaking by requiring users of the common macro packages (mm, ms, +me and their offspring) to resort to groff +primitives +and +inline escapes +for their special typesetting needs. Not to put too fine a point +on it, groff primitives tend toward the abstruse, and most inline +escapes are about as readable as an encrypted password. This does +not make for happy-camper writers, who either find themselves stuck +with a formatting style they don’t like, or are forced to +learn groff from the ground up—a daunting task, to say the +least. +

+ +

+Mom aims to make creating documents a simple matter, but with no +corresponding loss of user control. The document processing macros +provide an initial set of reasonable defaults, but anything that +is not to your liking can be changed. In combination with the +typesetting macros, you have all the tools you need to massage +passages and tweak pages until they look utterly professional. +

+ +

+One rarely hears the term “user interface” in +conjunction with document processing. Since formatting takes +place inside a text editor, little thought is given to the +look and feel of the formatting commands. Mom attempts to +rectify this by providing users with a consistent, readable +“coding” style. Most of the macros (especially in +the document processing set) have humanly-readable names. Not +only does this speed up learning the macros, it makes the sense +of what’s going on in a document easier to decipher, +typographically and structurally. +

+ +

+Mom does not try to be all things to all people. In contrast to +the normal groff philosophy, she does not try to produce output +that looks good no matter where it’s displayed. She’s +designed for primarily for PDF or PostScript output, although +with +PRINTSTYLE TYPEWRITE +she produces acceptable terminal copy. No attempt is made to be +compatible with older versions of troff. +

+ +

+One special feature in mom’s design is the attention she pays +to aligning the bottom margins of every page. Nothing screams +shoddy in typeset documents louder than bottom margins that +wander, or, in typesetter jargon, “hang.” There are, +of course, situations where whitespace at the bottom of a page +may be unavoidable (for example, you wouldn’t want a head +to appear at the bottom of the page without some text underneath +it), but in all cases where hanging bottom margins can be avoided, +mom does avoid them, by clever adjustments to leading (“line +spacing”) and the spacing between different elements on the +page. +

+ +

A note on mom’s documentation

+ +

+Writing documentation is tough, no doubt about it. One is never +quite sure of the user’s level of expertise. Is s/he new to +the application, new to its underlying protocols and programs, new +to the operating system? At some point, one has to decide for whom +the documentation is intended. Making the wrong choice can mean the +difference between a program that gets used and a program that gets +tossed. +

+ +

+Mom’s documentation assumes users know their way around +their own operating system (basic file management, how to use +the command line, how to use a text editor, etc). I run GNU/Linux, +and while the documentation may exhibit a GNU/Linux bias, mom +and groff can, in fact, be run on other platforms. +

+ +

+The documentation further assumes users at least know what groff +is, even if they don’t know much about it. Lastly, +it assumes that everyone—groff newbies and experts +alike—learns faster from a few well-placed examples than +from manpage-style reference docs. What mom’s documentation +doesn’t assume is that you know everything—not about +groff, not about typesetting, not about document processing. Even +experts have odd lacunae in their knowledge base. Therefore, +whenever I suspect that a term or procedure will cause head +scratching, I offer an explanation. And when explanations +aren’t enough, I offer examples. +

+ +

Canonical reference materials

+ +

+The canonical reference materials for groff are +cstr54 (a downloadable PostScript copy of which +is available +here) +and the troff and groff_diff +manpages. The most complete and up-to-date source of information is +the groff info pages, available by typing info groff at +the command line (assuming you have the TeXinfo standalone browser +installed on your system, which is standard for most GNU/Linux +distributions). And for inputting special characters, see man +groff_char. +

+ +

+I’ve tried to avoid reiterating the information contained +in these documents; however, in a few places, this has proved +impossible. But be forewarned: I have no qualms about +sidestepping excruciating completeness concerning groff usage; +I’m more interested in getting mom users up and running. +Mea culpa. +

+ +

+Groff has ancillary programmes (pre-processors) for generating +tables (tbl), diagrams (pic), and +equations (eqn), which may be used in conjunction +with mom. The manuals describing their usage are found at: +
+ +  tbl http://www.kohala.com/start/troff/v7man/tbl/tbl.ps +
+  pic http://www.kohala.com/start/troff/gpic.raymond.ps +
+  eqn http://www.kohala.com/start/troff/v7man/eqn/eqn2e.ps +
+

+ +
+

+Note: Mom’s macro file (om.tmac) is heavily +commented. Each macro is preceded by a description of its +arguments, function and usage, which may give you information in +addition to what’s contained in this documentation. +

+
+ +

+ +

How to read macro arguments

+ +

+The concise descriptions of macros in this documentation typically +look like this: +

+ +
+Macro: MACRO_NAME arguments +
+ +

+arguments lists the macro’s +arguments using conventions that should be familiar to anyone who +has ever read a manpage. Briefly: +

+ +
    +
  1. Macro arguments are separated from each other by spaces.
  2. +
  3. If an argument is surrounded by chevrons + (< >), it’s a description + of the argument, not the argument itself. +
  4. +
  5. If an argument begins with or is surrounded by double-quotes, the + double quotes must be included in the argument. +
  6. +
  7. If the user has a choice between several arguments, each of the + choices is separated by the pipe character + (|), which means “or.” +
  8. +
  9. Arguments that are optional are surrounded by square brackets.
  10. +
  11. <off> or <anything> in an argument + list means that any argument other than those in the argument + list turns the macro off. +
  12. +
+ +

Toggle macros

+ +

+Some macros don’t require an argument. They simply start +something. When you need to turn them off, the same macro with +any argument will do the trick. That’s right: any +argument (in caps, lowercase, or a mixture thereof). This permits +choosing whatever works for you: OFF, end, +Quit, Q, X, and so on. +

+ +

+Since these macros toggle things on and off, the argument list +simply reads toggle. +

+ +
+

Examples

+ +
Example 1: An argument requiring double-quotes
+ +
+Macro: TITLE "<title of document>" +
+ +

+The required argument to TITLE is the title of your document. +Since it’s surrounded by double-quotes, you must include +them in the argument, like this: +
+ + .TITLE "My Pulitzer Novel" + +

+ +
Example 2: A macro with required and optional arguments
+ +
+Macro: TAB_SET <tab number> <indent> <length> [ L | R | C | J [ QUAD ] ]  +
+ +

+The first required argument is a number that identifies the tab +(say, "3"). The second required argument is an indent from the +left margin (say, 6 picas). The third required argument is the +length of the tab (say, 3 picas). Therefore, at a minimum, when +using this macro, you would enter: +
+ + .TAB_SET 3 6P 3P + +The remaining two arguments are optional. The first is a +single letter, either L, R, C or +J. The second, which is itself +optional after L, R, C or +J, is the word QUAD. +Therefore, depending on what additional information you wish to +pass to the macro, you could enter: +
+ + .TAB_SET 3 6P 3P L + +or +
+ + .TAB_SET 3 6P 3P L QUAD + +

+ +
Example 3: A sample toggle macro:
+ +
+Macro: QUOTE toggle +
+ +

+QUOTE begins a section of quoted text +in a document and doesn’t require an argument. When the +quote’s finished, you have to tell mom it’s done. + + .QUOTE + So runs my dream, but what am I? + An infant crying in the night + An infant crying for the light + And with no language but a cry. + .QUOTE OFF + +

+ +

+ Alternatively, you could have turned the quote off with + END, or X, or something else. +

+
+ + + + + + + + +
Back to Table of ContentsTopNext: Definitions
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/letters.html b/contrib/mom/momdoc/letters.html new file mode 100644 index 0000000..3021eb2 --- /dev/null +++ b/contrib/mom/momdoc/letters.html @@ -0,0 +1,577 @@ + + + + + + + + + Mom -- Writing letters + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: Quick reference guide
+ +

Writing letters

+ + + +

+ +

Introduction

+ +

+Mom’s simple but effective letter-writing macros are a subset +of the +document processing macros, +designed to ease the creation of correspondence. +

+ +

+Because the letter macros are a subset of the document processing +macros, you can use +control macros +to design correspondence to your own specifications. However, +mom makes no pretence of providing complete design flexibility in +the matter of letters, which are, after all, simple communicative +documents whose only real style requirements are that they be neat +and professional-looking. +

+ +
+

Tutorial – writing letters

+ +

+Mom letters begin, like all mom-processed documents, with +reference macros +(in this case, +AUTHOR), +a +DOCTYPE +(LETTER, obviously), the essential +PRINTSTYLE +macro, and +START, +like this: +
+ + .AUTHOR "Yannick P. Guique" + .DOCTYPE LETTER + .PRINTSTYLE TYPESET + .START + +PRINTSTYLE, above, could also be TYPEWRITE. Mom has no +objection to creating letters that look like they were typed on an +Underwood by a shapely secretary with 1940s gams. +

+ +

+Please note that if you choose PRINTSTYLE TYPEWRITE, +there’s no need to give the SINGLESPACE option, as +this is the unalterable default for letters. +

+ +

+After the START macro, you enter headers pertinent to your letter: +the date, the addressee (in business correspondence, typically both +name and address), the addresser (that’s you; in business +correspondence, typically both name and address), and a greeting +(in full, e.g. “Dear Mr. Smith,” or “Dear +Mr. Smith:”). +

+ +

+The macros for entering the headers are simple (they’re not even +toggles): +
+ + .DATE + .TO + .FROM + .GREETING + +You may enter them in any order you like, except for GREETING, which +must come last. Mom ignores any headers you omit and spaces the +letter’s opening according to what you do include. See +Default for letters +to find out how mom formats the headers. +

+ +

+Once you’ve filled in what you need to get a letter started, +simply type the letter, introducing each and every paragraph, +including the first, with the +PP +macro. +

+ +

+At the end of the letter, should you wish a closing (“Yours +truly,” “Sincerely,” “Hugs and +kisses”), invoke the macro .CLOSING on a line +by itself, and follow it with the text of the closing. N.B. +Don’t put your name here; mom supplies it automatically from +AUTHOR), +with enough space to leave room for your signature. If you omit the +closing, mom simply adds your name (from AUTHOR), again with enough +space for your signature. +

+ +

+Assuming our tutorial letter is for business correspondence, +here’s what the complete letter looks like. +
+ + .AUTHOR "Yannick P. Guique" + .DOCTYPE LETTER + .PRINTSTYLE TYPESET + .START + .DATE + August 25, 2010 + .TO + GUILLAUME BARRIÈRES + Minidoux Corporation + 5000 Pannes Drive + Redmond, Virginia + .FROM + Y.P. GUIQUE + 022 Umask Road + St-Sauveur-en-dehors-de-la-mappe, QuĂŠbec + .GREETING + Dear Mr. Barrières, + .PP + It has come to my attention that you have once again been + lobbying the US government to prohibit the use of open source + software by endeavouring to outlaw so-called "warranty + free" applications. + .PP + I feel it is my duty to inform you that the success of your + operating system relies heavily on open source programs and + protocols, notably TCP/IP. + .PP + Therefore, in the interests of your corporation’s fiscal health, + I strongly advise that you withdraw support for any US + legislation that would cripple or render illegal open source + development. + .CLOSING + Sincerely, + +This produces a letter with headers that follow the North American +standard for business correspondence. If you’d prefer another style +of correspondence, for example, British, you’d set up the same +letter like this: +
+ + .AUTHOR "Yannick P. Guique" + .DOCTYPE LETTER + .PRINTSTYLE TYPESET + .START + .FROM + .RIGHT + Y.P. GUIQUE + 022 Umask Road + St-Sauveur-en-dehors-de-la-mappe, QuÊbec + .TO + GUILLAUME BARRIÈRES + Minidoux Corporation + 5000 Pannes Drive + Redmond, Virginia + .DATE + .RIGHT + August 25, 2004 + .GREETING + Dear Mr. Barrières, + +Notice the use of .RIGHT after .FROM and +.DATE in this example, used to change the default quad +for these macros. +

+
+ +

Default letter style

+ +

+In letters, if the order of header macros is +

+
    +
  1. .DATE
  2. +
  3. .TO  (the addressee)
  4. +
  5. .FROM  (the addresser)
  6. +
  7. .GREETING  (“Dear Whoever,” “To Whom It May Concern,” etc.)
  8. +
+

+mom sets +

+
    +
  • the date flush right, page right, at the top of page one, + with a gap of two linespaces underneath +
  • +
  • the addressee (.TO) in a block flush left, page + left, with a gap of one linespace underneath +
  • +
  • the addresser (.FROM) in a block flush left, page + left, with a gap of one linespace underneath +
  • +
  • the greeting flush left, with a gap of one linespace + underneath +
  • +
+

+which is the standard for North American business correspondence. +

+ +

+If you switch the order of .DATE, .TO and/or +.FROM, mom sets all the headers +flush left, with a gap of one linespace underneath each. (The +default left quad of any header can be changed by invoking the +.RIGHT macro, on a line by itself, immediately before +inputting the text of the header.) +

+ +

+Following the headers, mom sets +

+
    +
  • the body of the letter justified
  • +
  • in multi-page letters: +
      +
    • a footer indicating there’s a next page (of the form .../#)
    • +
    • the page number at the top of every page after page one
    • +
  • +
  • the closing/signature lines flush left, indented halfway across the page
  • +
+ +

+Other important style defaults are listed below, and may be changed +via the +typesetting macros +or the document processing +control macros +prior to +START. +Assume that any style parameter not listed below is the same as for +any document processed with +PRINTSTYLE TYPESET +or +PRINTSTYLE TYPEWRITE. +

+ +
+ + PARAMETER PRINTSTYLE TYPESET PRINTSTYLE TYPEWRITE + + Paper size 8.5 x 11 inches 8.5 x 11 inches + Left/right margins 1.125 inches 1.125 inches + Header margin 3.5 picas 3.5 picas + (for page numbers) + Header gap 3 picas 3 picas + (for page numbers) + Family Times Roman Courier + Font roman roman + Point size 12 12 + Line space 13.5 12 (i.e. singlespaced) + Paragraph indent 3 ems 3 picas + Spaced paragraphs yes no + Footers* yes yes + Footer margin 3 picas 3 picas + Footer gap 3 picas 3 picas + Page numbers top, centred top, centred + + *Footers contain a "next page" number of the form .../# + +
+ +

+ + +
+

The letter macros

+

+All letter macros must come after +START, +except NO_SUITE, which must come after +PRINTSTYLE +and before +START. +

+ + +
+ + + +
+Macro: DATE +
+ +

+Invoke .DATE on a line by itself, with the date +underneath, like this: +
+ + .DATE + October 31, 2012 + +If you wish to change the default quad direction for the date, +enter .LEFT or .RIGHT, on a line by itself, +immediately after .DATE. +

+ +

+If you wish to insert additional space between the date and any +letter header that comes after it, do so after inputting the date, +not at the top of the next header macro, like this: +
+ + .DATE + October 31, 2012 + .SPACE \"Or, more simply, .SP + +If you wish to remove the default space, +
+ + .SPACE -1v \"Or, more simply, .SP -1v + +will do the trick. +

+ + + +
+Macro: TO +
+ +

+Invoke .TO on a line by itself, with the name and address +of the addressee underneath, like this: +
+ + .TO + JOHN SMITH + 10 Roberts Crescent + Bramladesh, Ont. + +If you wish to change the default quad direction for the address, +enter .LEFT or .RIGHT, on a line by itself, +immediately after .TO. +

+ +

+If you wish to insert additional space between the address and +any letter header that comes after it, do so after inputting the +address, not at the top of the next header macro, like this: +
+ + .TO + JOHN SMITH + 10 Roberts Crescent + Bramladesh, Ont. + .SPACE \"Or, more simply, .SP + +If you wish to remove the default space, +
+ + .SPACE -1v \"Or, more simply, .SP -1v + +will do the trick. +

+ + + +
+Macro: FROM +
+ +

+Invoke .FROM on a line by itself, with the name and +address of the addresser underneath, like this: +
+ + .FROM + JOE BLOW + 15 Brunette Road + Ste-Vieille-Andouille, QuĂŠbec + +If you wish to change the default quad direction for the address, +enter .LEFT or .RIGHT, on a line by itself, +immediately after .FROM. +

+ +

+If you wish to insert additional space between the address and +any letter header that comes after it, do so after inputting the +address, not at the top of the next header macro, like this: +
+ + .FROM + JOE BLOW + 15 Brunette Road + Ste-Vieille-Andouille, QuĂŠbec + .SPACE \"Or, more simply, .SP + +If you wish to remove the default space, +
+ + .SPACE -1v \"Or, more simply, .SP -1v + +will do the trick. +

+ + + +
+Macro: GREETING +
+ +

+Invoke .GREETING on a line by itself, with the full +salutation you want for the letter underneath, like this: +
+ + .GREETING + Dear Mr. Smith, + +

+ + + +
+Macro: CLOSING +
+ +

+Invoke .CLOSING on a line by itself after the body of +the letter, with the closing you’d like (e.g. “Yours +truly,”) underneath, like this: +
+ + .CLOSING + Yours truly, + +

+ +
+

+CLOSING control macros and defaults +
+Two macros control the behaviour of .CLOSING: +

+
    +
  • CLOSING_INDENT
  • +
  • SIGNATURE_SPACE
  • +
+ +

+The first, CLOSING_INDENT, indicates the distance from the left +margin you’d like to have your closing indented. It takes a +single +numeric argument +and must have a +unit of measure +appended to it, unless you want an indent of 0 (zero). Mom’s +default is one half the width of the letter’s line length +(i.e. halfway across the page). If you wanted, instead, an indent of +6 +picas, +you’d do it like this: +
+ + .CLOSING_INDENT 6P + +Or, if you wanted to have no indent at all: +
+ + .CLOSING_INDENT 0 + +

+ +

+The second, SIGNATURE_SPACE, controls how much room to leave for the +signature. It takes a single +numeric argument +and must have a +unit of measure +appended to it. Mom’s default is 3 line spaces, but if you +wanted to change that to, say, 2 line spaces, you’d do: +
+ + .SIGNATURE_SPACE 2v + +

+
+ + + +
+Macro: NO_SUITE +
+ +

+If you don’t want mom to print a “next page” +number at the bottom of multi-page letters, invoke +.NO_SUITE, on a line by itself, prior to +START. +

+ +

+ + + + + + + + +
Back to Table of ContentsTopNext: Quick reference guide
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/macrolist.html b/contrib/mom/momdoc/macrolist.html new file mode 100644 index 0000000..81ebd7c --- /dev/null +++ b/contrib/mom/momdoc/macrolist.html @@ -0,0 +1,1529 @@ + + + + + + + + + Mom -- Quick reference guide + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: Appendices
+ +

Quick reference guide

+ +

+Once you know your way around mom, you may find this guide +preferable to using the Table of Contents. It lists mom’s +major user-space macros. The links point to references found +elsewhere in the documentation. +

+ + + +

Quick reference guide

+ +
TYPESETTING MACROS
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
++++ Paper size, margins, line length
PAPER-- set common paper sizes (letter, A4, etc)
PAGEWIDTH-- set a custom page width
PAGELENGTH-- set a custom page length
PAGE-- set explicit page dimensions and margins
T_MARGIN-- set a top margin
B_MARGIN-- set a bottom margin
L_MARGIN-- set a left margin (page offset)
R_MARGIN-- set a right margin
LL-- set a line length
+ + + + + + + + + + + + + + + + + + +
++++ Family, font, point size
FAMILY-- set the family of type
FT-- set the font style (roman, italic, etc)
FALLBACK_FONT-- establish a fallback font (for missing fonts)
PT_SIZE-- set the point size
\*[SIZE n]-- change the point size inline
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
++++ Font modifications
Pseudo italic
SETSLANT-- set the degree of slant
\*[SLANT]-- invoke pseudo italic inline
\*[SLANTX]-- turn off pseudo italic inline
Pseudo bold
SETBOLDER-- set the amount of emboldening
\*[BOLDER]-- invoke pseudo bold inline
\*[BOLDERX]-- turn off pseudo bold inline
Pseudo condensed
CONDENSE-- set the amount to pseudo condense
\*[COND]-- invoke pseudo condensing inline
\*[CONDX]-- turn off pseudo condensing inline
Pseudo extended
EXTEND-- set the amount to pseudo extend
\*[EXT]-- invoke pseudo extending inline
\*[EXTX]-- turn off pseudo condensing inline
+ + + + + + + + + + + +
++++ Linespacing (leading)
LS-- set the linespacing (leading)
AUTOLEAD-- set the linespacing relative to the point size
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
++++ Justification, quad, line-by-line setting, breaking lines
JUSTIFY-- justify text to both margins
QUAD-- "justify" text left, centre, or right
LEFT-- set line-by-line quad left
CENTER-- set line-by-line quad centre
RIGHT-- set line-by-line quad right
BR-- break a justified line
SPREAD-- force justify a line
EL-- break a line without advancing on the page
+ + + + + + + + + + + +
++++ Hyphenation
HY-- automatic hyphenation on/off
HY_SET-- set automatic hyphenation parameters
+ + + + + + + + + + + +
++++ Word and sentence spacing
WS-- set the minimum word space size
SS-- set the sentence space size
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
++++ Kerning, ligatures, smartquotes
KERN-- automatic character pair kerning on/off
\*[BU n]-- move characters pairs closer together inline
\*[FU n]-- move character pairs further apart inline
RW-- uniformly tighten space between characters
EW-- uniformly loosen space between characters
BR_AT_LINE_KERN-- break previous line when RW or EW is invoked
LIGATURES-- automatic generation of ligatures on/off
SMARTQUOTES-- smartquoting on/off
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
++++ Horizontal and vertical movements, columnar setting
ALD-- move downards on the page
RLD-- move upwards on the page
SPACE-- insert space between lines on a page
\*[DOWN n]-- temporarily move downwards in a line
\*[UP n]-- temporarily move upwards in a line
\*[FWD n]-- move forward in a line
\*[BCK n]-- move backwards in a line
MCO-- multiple columns on
MCR-- recto vertical position of column start
MCX-- multiple columns off, advance past longest column
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
++++ Indents
IL-- set and turn on a left indent
IR-- set and turn on a right indent
IB-- set and turn on indents both left and right
IQ-- quit (exit) all indents
TI-- set and turn on a temporary (one line) indent
HI-- set and turn on a hanging indent
ILX-- left indents off
IRX-- right indents off
IBX-- both left and right indents off
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
++++ Tabs
TAB_SET-- set up a typesetting tab
TAB <n>-- call tab <n>
TQ-- quit (exit) tabs
\*[ST<n>]...-- string tabs (mark tab positions inline)
\*[ST<n>X]
TN-- move to tab<n+1> without advancing on the page
ST-- set quad/fill for string tabs
+ + + + + + + + + + + + + + + + + + + + +
++++ Underscoring, underlining
UNDERSCORE-- underscore
UNDERSCORE2-- double underscore
UNDERLINE-- underline (fixed width fonts only)
\*[UL]...-- invoke underlining inline (fixed width fonts only)
\*[ULX]
+ + + + + + + + + + + + + + + + + +
++++ Superscipts
\*[SUP]...\*[SUPX]-- superscript
\*[CONDSUP]...\*[CONDSUPX]-- pseudo-condensed superscript
\*[EXTSUP]...\*[EXTSUPX]-- pseudo extended supercript
SUPERSCRIPT_RAISE_AMOUNT-- vertical offset of superscripts
+ + + + + + + + + + + + + + + + + + + + +
++++ Nested lists
LIST-- begin a list
ITEM-- begin an item in a list
SHIFT_LIST-- change the indent of a list
RESET_LIST-- clear and reset a list’s enumerator
PAD_LIST_DIGITS-- reserve space for digits
+ + + + + + + + + + + + + + + + + +
++++ Colour
NEWCOLOR-- initialize (define) a colour
COLOR-- begin using an initialized colour
XCOLOR-- initialize a "named" X colour
\*[<colorname>]-- begin using an initialized colour inline
+ + + + + + + + + + + + + + + + + + + + + + + +
++++ Dropcaps
DROPCAP-- set a dropcap
DROPCAP_FAMILY-- set a dropcap’s family
DROPCAP_FONT-- set a dropcap’s font style
DROPCAP_COLOR-- set a dropcap’s colour
DROPCAP_ADJUST-- adjust size of a dropcap
DROPCAP_GUTTER-- adjust space between a dropcap and regular text
+ + + + + + + + + + + +
++++ Smallcaps
SMALLCAPS
SMALLCAPS_STYLE
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+++ Utilities
ALIAS-- give a macro a new name
CAPS-- set type all caps
COMMENT-- silently embed comments in a document
ESC_CHAR-- change the default escape character
\*[LEADER]-- insert leaders at the end of a line
LEADER_CHARACTER-- change the character used for leaders
NEWPAGE-- break to a new page
NEWSLIDE-- break to a new slide
PAUSE-- pause slide presentation
TRANSITION-- transition effect for slides
PAD-- insert equalized whitespace into a line
PAD_MARKER-- change the pad marker
\*[RULE]-- draw a full measure rule
SIZESPECS-- cap-height, x-height, descender depth
SILENT-- output processing off or on
TRAP-- enable or disable page position traps
LEFT_HANG / \*[HANG]-- hanging punctuation
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
++++ Graphical objects and images
DRH-- draw a horizontal rule
DRV-- draw a vertical rule
DBX-- draw a box
DCL-- draw a circle (ellipse)
RULE_WEIGHT-- set weight of rules drawn with \*[RULE]
PDF_IMAGE-- insert a PDF image
PSPIC-- insert a PostScript image
+ +
DOCUMENT PROCESSING MACROS
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
++++ Reference macros
TITLE-- document title
DOCTITLE-- document title (if different from TITLE)
ENDNOTE_TITLE-- document/chapter id string for endnotes
CHAPTER-- chapter number
CHAPTER_TITLE-- chapter title
CHAPTER_STRING-- what to use in place of “Chapter”
SUBTITLE-- document subtitle
AUTHOR-- document author(s)
DOC_COVERTITLE-- document title cover
COVERTITLE-- section cover title
COPYRIGHT-- copyright
MISC-- miscellaneous cover information
DRAFT-- document’s draft number
DRAFT_STRING-- what to use in place of “Draft”
REVISION-- document’s revision number
REVISION_STRING-- what to use in place of “Revision”
PDF_TITLE-- PDF viewer window title
TOC_HEADING-- non-pagenumbered line inserted into the TOC
+ + + + + + + + + + + + + + + + + +
++++ General document formatting directives
DOCTYPE-- general document type
DOCTYPE SLIDES-- create slide presentation
COPYSTYLE-- draft or final copy
PRINTSTYLE-- typeset or “typewritten”
+ + + + + + + + + + + + + + + + + +
++++ Line numbering
NUMBER_LINES-- automatic line numbering on/off
NUMBER_QUOTE_LINES-- numbering of QUOTE lines on/off
NUMBER_BLOCKQUOTE_LINES-- numbering of BLOCKQUOTE lines on/off
Control macros
+ + + + + + + + + + + + + + +
++++ Set documents in columns
COLUMNS
COL_NEXT
COL_BREAK
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+++ TYPEWRITE control macros
TYPEWRITER_FAMILYalternative to Courier
TYPEWRITER_SIZEpoint size of typewriter font
UNDERLINE_ITALIC-- underlining of italics on
UNDERLINE_QUOTES-- underlining of QUOTEs on/off
ITALIC_MEANS_ITALIC-- use real italics (not underlining)
UNDERLINE_SLANT-- underlining of pseudo-italics on
SLANT_MEANS_SLANT-- use pseudo italics (not underlining)
+ + + + + + + + +
++++ Initiate document processing
START-- begin document processing
+ + + + + + + + + + + +
++++ Epigraphs
EPIGRAPH-- set an epigraph underneath the docheader
Control macros-- change default style of epigraphs
+ + + + + + + + + + + + + + + + + +
++++ Headings
HEADING-- hierarchical headings
Control macros-- style heading levels
 HEADING_STYLE-- set style parameters for heading levels
 PREFIX_CHAPTER_NUMBER-- add chapter number to heading numbering
+ + + + + + + + + + + + + + + + + + + + + + + +
++++ Paragraphs
PP-- set a paragraph
Control macros-- managing paragraph style concerns
 PP_FONT-- globally change font of regular paragraphs
 PARA_INDENT-- set the paragraph first-line indent
 INDENT_FIRST_PARAS-- indenting of paragraph first-lines on/off
 PARA_SPACE-- linespace between paragraphs on/off
+ + + + + + + + + + + + + + +
++++ Quotes (line for line verbatim quotes)
QUOTE-- set quoted text line for line
Control macros-- change default style of quotes
 ALWAYS_FULLSPACE_QUOTES-- control vertical space around quotes
+ + + + + + + + + + + + + + +
++++ Blockquotes (cited passages of text)
BLOCKQUOTE-- set passages of cited text
Control macros-- change default blockquote style
 ALWAYS_FULLSPACE_BLOCKQUOTES-- control vertical spacing
+ + + + + + + + +
++++ Floats
FLOAT-- keep blocks of input together, output on next page +
+   if necessary
+ + + + + + + + + + + + + + +
++++ Images and graphics
PDF_IMAGE-- inserting pdf images
 PDF_IMAGE_FRAME-- set parameters for pdf image frames
PSPIC-- inserting PostScript images
+ + + + + + + + + + + + +
++++ Shaded backgrounds, frames, page colour
BOX -- shaded backgrounds and frames
PAGE_COLOR
+ + + + + + + + + + +
++++ eqn support
EQ-- begin an eqn block
EN-- end an eqn block
+ + + + + + + + + + + + + + +
++++ pic support
PS-- begin a pic block
PE-- end a pic block
PIC_TEXT_STYLE-- set style for pic text
+ + + + + + + + + + + +
++++ grap support
G1-- begin a grap block
G2-- end a grap block
+ + + + + + + + + + + + + + +
++++ tbl support
TS-- begin a tbl block
TH-- running table header (after TS H)
TE-- end tbl block
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
++++ Captions and labels
AUTOLABEL-- auto-label figures, tables, equations
SET_AUTOLABEL-- set or reset autolabel numbers
CAPTION_AFTER_LABEL-- place captions after labels
MLA-- MLA-style labelling and captioning
CAPTION-- add a caption to a float or (block)quote
LABEL-- add a label to a float or (block)quote
CAPTIONS-- set style for captions
LABELS-- set style for labels
SOURCES-- set style for sources (tbl only)
+ + + + + + + + + + + + + + + + + +
++++ Lists of Figures, Tables, and Equations
LIST_OF_FIGURES-- generate a List of Figures
LIST_OF_TABLES-- generate a List of Tables
LIST_OF_EQUATIONS-- generate a List of Equations
LISTS_STYLE-- set style parameters for Lists
+ + + + + + + + + + + + + + + + + +
++++ Code snippets
CODE-- set a code snippet
Control macros-- change default style of code snippets
 General-- family, font, and colour
 CODE_SIZE-- code size as a percentage of prevailing text
+ + + + + + + + + + + + + + + + + +
++++ Author linebreaks (section breaks)
LINEBREAK-- insert an author linebreak (section break)
Control macros-- change default style of linebreaks
 LINEBREAK_CHAR-- character to use for author linebreaks
 LINEBREAK_COLOR-- colour of author linebreak character
+ + + + + + + + + + + + + + + + + + + + +
++++ Document termination string
FINIS-- insert a document termination string
Control macros-- change default style finis string
 FINIS_STRING-- set the document termination string
 FINIS_STRING_CAPS-- capitalization of termination string
 FINIS_COLOR-- set the document termination string colour
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
++++ Footnotes
FOOTNOTE-- set a footnote
Control macros-- change default style of footnotes
 FOOTNOTE_MARKERS-- footnote markers on/off
 FOOTNOTE_MARKER_STYLE-- type of footnote marker to use
 RESET_FOOTNOTE_NUMBER-- reset footnote numbering
 FOOTNOTE_RULE-- footnote separator rule on/off
 FOOTNOTE_RULE_ADJ-- adjust position of footnote rule
 FOOTNOTE_RULE_LENGTH-- adjust length of footnote rule
 FOOTNOTES_RUN_ON-- instruct footnotes to be continuous
+ + + + + + + + + + + + + + + + + + +
++++ Endnotes
ENDNOTE-- set an endnote
\*[EN-MARK]-- mark initial line of a range of line numbers
+   (for use with line numbered endnotes)
ENDNOTES-- output endnotes
Control macros
+ + + + + + + + + + + + + + + + + + + + +
General style control
Pagination
Header/footer control
Title control
Document/section identification control
Identification style
+ + + + + + + + + + + +
++++ Margin notes
MN_INIT-- initialize margin notes
MN-- set a margin note
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
++++ Bibliographic references
REF-- begin a reference
FOOTNOTE_REFS-- place references in footnotes
ENDNOTE_REFS-- place references in endnotes
REF( / REF)-- put parentheses around embedded references
REF[ / REF]-- put square brackets around embedded references
REF{ / REF}-- put curly braces around embedded references
BIBLIOGRAPHY-- output a bibliography
Control macros
+ + + + + + + + + + + + + + +
BIBLIOGRAPHY_TYPE -- "plain" or enumerated list
General style control
Header/footer control
Main head control
+ + + + + + + + + + + + + + + + + +
++++ Tables of contents
TOC-- output a table of contents
NO_TOC_ENTRY-- omit a document section from the TOC
TOC_HEADING-- insert a heading into the TOC
Control macros
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
General style control
Page numbering
Header string control
Entries and reference page numbers style control
TOC_TITLE_STYLE
TOC_ENTRY_STYLE
TOC_HEADING_STYLE
Additional table of contents control macros
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
++++ Letter (correspondence) macros
DATE-- letter’s date
FROM-- letter’s addresser
TO-- letter’s addressee
GREETING-- letter’s salutation
CLOSING-- letter’s closing salutation
CLOSING_INDENT-- indentation of the closing salutation
SIGNATURE_SPACE-- room to leave for the signature
NO_SUITE-- printing of "next page number" off or on
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
++++ Changing global print style parameters after START
DOC_LEFT_MARGIN-- left margin of everything on the page
DOC_RIGHT_MARGIN-- right margin of everything on the page
DOC_LINE_LENGTH-- document’s base line length
DOC_FAMILY-- document’s base family
DOC_PT_SIZE-- document’s base point size
DOC_LEAD-- document’s base lead
DOC_QUAD-- document’s base quad directions
+ + + + + + + + + + + +
++++ Managing a document’s first-page header
DOCHEADER-- document first-page header on/off
Control macros-- change default style of docheader elements
+ + + + + + + + + + + + + + + + + +
++++ Managing page headers and footers
HEADERS-- page headers on/off
FOOTERS-- page footers on/off
HEADERS_AND_FOOTERS-- enable generation of both headers and
+   footers
Control macros
+ + + + + + + + + + + + + + + + + + + + +
Strings-- left-right-center strings
Style-- change defaults for headers and/or footers
Global-- global style changes
Part-by-part-- part-by-part style changes
Vertical placement-- adjust position of headers and/or footers
Separator rule-- manage the header/footer separator rule
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
++++ Recto/verso page headers and footers
RECTO_VERSO-- recto/verso headers and/or footers on/off
FORCE_RECTO-- insert blank pages so chapters start recto
SWITCH_HEADERS-- switch recto or verso header
SWITCH_FOOTERS-- switch recto or verso footer
HEADER_RECTO-- string that constitutes a recto header
HEADER_VERSO-- string that constitutes a verso header
FOOTER_RECTO-- string that constitutes a recto footer
FOOTER_VERSO-- string that constitutes a recto footer
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
++++ Pagination
PAGINATE-- pagination on/off
Control macros-- change default style for pagination
 PAGENUMBER-- user-defined (starting) page number
 PAGENUM_STYLE-- digits, roman numerals, etc
 PAGENUMBER_STRING-- user-defined page numbering string
 PAGENUM_ON_FIRST_PAGE-- when page numbering is at page top
 DRAFT_WITH_PAGENUMBER-- attach draft/revision to page number
+ + + + + + + + + + + +
++++ Vertical whitespace management
SHIM-- align to the baseline grid
FLEX-- insert flexible whitespace
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
++++ Document and section cover (title) pages
DOC_COVER-- information to include in a document cover
COVER-- information to include in a section cover
DOC_COVERS-- printing of document covers on/off
COVERS-- printing of section covers on/off
DOC_COVERTEXT-- user-added text for document covers
COVERTEXT-- user-added text for section covers
DOC_COVER_IMAGE-- add images to document covers
COVER_IMAGE-- add images to document covers
Control macros-- change style defaults for covers
+ + + + + + + + + + + + + + + + + + + + + + + +
+++ Utilities
ADD_SPACE-- add space to the top of a page
RESTORE_SPACE-- restore spacing at the top of a page
BLANKPAGE-- output one or more blank pages
DOC_LEAD_ADJUST-- adjust leading to fill pages
COLLATE-- join documents (chapters/sections)
CENTER_BLOCK-- centre blocks of type
+ +

+ + + + + + + + +
Back to Table of ContentsTopNext: Appendices
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/rectoverso.html b/contrib/mom/momdoc/rectoverso.html new file mode 100644 index 0000000..92cf80f --- /dev/null +++ b/contrib/mom/momdoc/rectoverso.html @@ -0,0 +1,350 @@ + + + + + + + + + Mom -- Recto/verso printing, collating + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: Cover pages
+ +

Recto/verso printing, collating

+ + + +

+ +

Introduction to recto/verso printing

+ +

+Recto/verso printing allows you to set up a mom document in such +a way that it can be printed on both sides of a printer sheet and +subsequently bound. +

+ +

+With recto/verso, mom automatically takes control of the following +aspects of alternating page layout: +

+
    +
  • switching left and right margins (if they’re not equal)
  • +
  • switching the left and right parts of the default 3-part + headers + or + footers + (see the + General description of headers) +
  • +
  • switching + HEADER_RECTO + and + HEADER_VERSO + if user-defined, single string recto/verso headers + or footers are used in place of the default 3-part + headers or footers +
  • +
  • switching the page number position (if page numbers are not centred)
  • +
+
+ +
+

Recto/verso macros

+ +
+ + + +
+Macro: RECTO_VERSO +
+ +

+If you want mom to set up alternating pages for recto/verso +printing, simply invoke RECTO_VERSO, with no argument, anywhere in +your document (most likely before +START). +

+ +
+

+Note: +Recto/verso always switches the left and right parts of +headers +or +footers +on odd/even pages. However, it only switches the left and right +margins if the margins aren’t equal. Consequently, it is +your responsibility to set the appropriate differing left and right +margins with +L_MARGIN +and +R_MARGIN +(prior to +START) +or with +DOC_LEFT_MARGIN +and +DOC_RIGHT_MARGIN +(before or after START). +

+ +

+Equally, recto/verso only switches the page number position if page +numbers aren’t centred, which means you have to set the page +number position with +PAGENUM_POS +(before or after START). +

+
+ + + +
+Macro: FORCE_RECTO +
+ +

+It is a common convention with two-sided printing to ensure that +cover pages, title pages, and chapters or major sections of a document +always begin on the recto side of a page. This sometimes +necessitates inserting a blank page before the start of a new +chapter or major section. +

+ +

+If you would like mom to take care of this for you automatically, +simply invoke FORCE_RECTO before the first +START +of the document. +

+ + + +
+Macro: SWITCH_HEADERS +
+ +

+SWITCH_HEADERS switches the location of the header left string +(by default, the author) and the header right string (by default, +the document title). If you don’t like mom’s default +placement of author and title, use SWITCH_HEADERS to reverse it. +

+ +

+SWITCH_HEADERS can also be useful in conjunction with +RECTO_VERSO. +The assumption of RECTO_VERSO is that the first page of a document +(i.e. recto/odd) represents the norm for header-left and header-right, +meaning that the second (and all subsequent verso/even) pages of the +document will reverse the order of header-left and header-right. +

+ +

+If mom’s behaviour in this matter is not what you want, simply +invoke SWITCH_HEADERS on the first page of your recto/verso document +to reverse her default treatment of header parts. The remainder of +your document (with respect to headers) will come out as you want. +

+ +

+ + + +

Introduction to collating

+ +

+Many people wisely keep chapters of a long work in separate +files, previewing or printing them as needed during the draft +phase. However, when it comes to the final version, mom requires +a single, collated file in order to keep track of page numbering +and recto/verso administration, generating tables of contents and +endnotes, ensuring that +docheaders +get printed correctly, and a host of other details. +

+ +

+The COLLATE macro, which can be used with any +DOCTYPE +except LETTER, lets you glue mom-formatted input files +together. You need only concatenate chapters into a single file +(most likely with cat(1)), and put +.COLLATE at the end of each concatenated chapter. +Assuming all the files begin with the required +reference macros +(metadata), style parameters, and +START, +each chapter will begin on a fresh page and behave as expected. +

+ +

+Even if you work with monolithic, multi-chapter files, every +chapter and its associated metadata plus .START +still needs to be preceded by .COLLATE. +

+ +
+

+Note: +COLLATE assumes you are collating documents/files with similar +type-style parameters hence there’s no need for PRINTSTYLE +to appear after COLLATE, although if you’re collating +documents that were created as separate files, chances are the +PRINTSTYLE’s already there. +

+
+ +
+

+Two words of caution: +

+
    +
  1. Do not collate documents of differing + PRINTSTYLES (i.e., don’t try to + collate a TYPESET document and TYPEWRITE + document). +
  2. +
  3. Use .DOC_FAMILY instead of + .FAMILY if, for some reason, you want to + change the family of all the document elements after + .COLLATE. .FAMILY, by itself, will + change the family of paragraph text only. +
  4. +
+
+ + + +
+

collate

+
+ +
+Macro: COLLATE +
+ +

+The most basic (and most likely) collating situation looks like +this: +
+ + .COLLATE + .CHAPTER 17 + .START + +A slightly more complex version of the same thing, for chapters +that require their own titles, looks like this: +
+ + .COLLATE + .CHAPTER_TITLE "Geek Fatigue: Symptoms and Causes" + .START + +

+ +
+

+Tip: +If the last line of text before .COLLATE +falls too close to the bottom margin, or if the line is followed +by a macro likely to cause a linebreak (e.g. .LIST OFF or +.IQ), mom may output a superfluous blank page before +the start of the following document. +

+ +

+In order to avoid this, insert +.EL +after the last line of text, before .COLLATE and/or any +concluding macros. For example, +
+ + some concluding text.\c + .EL + .COLLATE + +or +
+ + some concluding text.\c + .EL + .LIST OFF + .COLLATE + +

+
+ +
+

+Note: +See the +two words of caution, +above. +

+
+ +

+ + + + + + + + +
Back to Table of ContentsTopNext: Cover pages
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/refer.html b/contrib/mom/momdoc/refer.html new file mode 100644 index 0000000..5f11814 --- /dev/null +++ b/contrib/mom/momdoc/refer.html @@ -0,0 +1,2129 @@ + + + + + + + + + Mom -- Document processing, bibliographies and references + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: Writing letters
+ +

Bibliographies and references

+ +
+ +
+ +

+ +

Introduction to bibliographies and references

+ +

+Mom provides the ability to format and generate bibliographies, as +well as footnote or endnote references, in MLA (Modern Language +Association) style. She accomplishes this by working in conjunction +with a special groff program called refer. +

+ +

+Refer requires first that you create a database of works +that will be cited in your documents. Once that’s done, special +macros let you briefly key in references to entries in the database +and have mom format them with respect to order, punctuation and +italicization in footnotes, endnotes, or a full bibliography. +

+ +

+Refer has been around for a long time. It’s +powerful and has many, many features. Unfortunately, the manpage +(man refer), while complete and accurate, is +dense and not a good introduction. (It’s a classic manpage +Catch-22: the manpage is useful only after you know how to use the +program.) +

+ +

+In order to get mom users up and running with refer, +this section of mom’s documentation focuses exclusively, in a +recipe-like manner, on what you need to know to use refer +satisfactorily in conjunction with mom. The instructions are not to +be taken as a manual on full refer usage. +

+ +

+If you’re already a refer user, the information +herein will be useful for adapting your current refer +usage to mom’s way of doing things. If you’ve never +used refer, the information is essential, and, in many +cases, may be all you need. +

+ +

+I encourage anyone interested in what MLA style looks +like—and, by extension, how your bibliographies and references +will look after mom formats them—to check out +
+ + http://www.aresearchguide.com/12biblio.html + +or any other website or reference book on MLA style. +

+ +

+ +
+

Tutorial on refer usage with mom

+
    +
  1. Create a refer database +
  2. +
  3. Insert a refer block +
  4. +
  5. Tell mom where you want your references (if footnotes or endnotes)
  6. +
  7. Accessing references in the database
  8. +
  9. Entering footnote/endnote references
  10. +
  11. Parenthetical insertions
  12. +
  13. Generating a bibliography from parenthetical insertions
  14. +
  15. Generating a comprehensive bibliography
  16. +
  17. Invoking groff with mom and refer
  18. +
+ +

1. Create a refer database

+ +

+The first step in using refer with mom is creating a +database. The database is a text file containing entries for the +works you will be citing. You may set up separate databases for +individual documents, or create a large database that can be +accessed by many documents. +

+ +

+Entries (“records” in refer-speak) in the database +are separated from each other by a single, blank line. The records +themselves are composed of single lines (“fields”) with +no blank lines between them. Each field begins with a percent +sign and a single letter (the "field identifier") +e.g. %A or %T. The letter identifies +what part of a bibliographic entry the field refers to: Author, +Title, Publisher, Date, etc. After the field identifier comes +a single space, followed by the information appropriate to +field. +

+ + + +

+Here’s an example database containing two records so you can +visualize what the above paragraph says. +

+ +
Example refer database
+
+ +%A Terry Pratchett +%A Neil Gaiman +%T Good Omens +%C London +%I Gollancz +%D 1990 + +%A Peter Schaffter +%T The Schumann Proof +%C Toronto +%I RendezVous Press +%D 2004 + +
+ +

+The order in which you enter fields doesn’t matter. +Refer will re-arrange them for you. +

+ +

2. Insert a refer block

+ +

+Having set up your database, you now need to put some +refer-specific commands in your mom file. +

+ +

+Refer commands are introduced by a single line +containing .R1, and concluded with a single line +containing .R2. What goes between the .R1 +and .R2 lines is called a “refer block”. +Refer commands in a refer block should be entered one per +line, in lowercase letters, with no initial period (dot). +The actual commands depend on whether you want your references +

+
    +
  • in footnotes/endnotes
  • +
  • parenthetically inserted (in abbreviated form) into running text, +referring to a works-cited list (bibliography)
  • +
  • to generate a comprehensive bibliography (a reading list)
  • +
+ +
Refer block for footnotes/endnotes
+ +

+If you want footnote or endnote references, place this block at +the top of your mom file. +

+ +
+
+ +.R1 +no-label-in-text +no-label-in-reference +join-authors " and " ", " ", and " +database <full path to database> +.R2 + +
+
+

+<full path to the database> +means the full path including the filename, e.g. +/home/user/refer/my-database-file. +

+ +
Refer block for parenthetical insertions into running text
+ +

+If you want short, parenthetical insertions into running text, +referring to works cited in a bibliography, place this block at +the top of your mom file. +

+ +
+
+ +.R1 +label "(A.n|Q)" +bracket-label " (" ")" ", " +join-authors ", and " ", " ", and " +move-punctuation +reverse A1 +sort A1Q1T1B1E1 +database <full path to database> +.R2 + +
+
+

+<full path to the database> +means the full path including the filename, e.g. +/home/user/refer/my-database-file. +

+ +
Refer block for comprehensive bibliographies
+ +

+If you want to output an entire refer database, or +generate a comprehensive bibliography (a reading list) from a +database, place this block at the bottom of your mom file, +either prior to or immediately after invoking +BIBLIOGRAPHY. +

+ +
+
+ +.R1 +no-label-in-text +no-label-in-reference +join-authors ", and " ", " ", and " +sort A1Q1T1B1E1 +reverse A1 +database <full path to database> +.R2 + +
+
+ +

+<full path to the database> +means the full path including the filename, e.g. +/home/user/refer/my-database. +

+ +

3. Tell mom where you want your references

+ +

+If you want references in footnotes, issue the instruction +
+ + .FOOTNOTE_REFS + +anywhere before the first citation in your file. Footnote markers +will be inserted into the text, and the bibliographic information +for the citation will appear as a footnote. +

+ +

+If you want references in endnotes, issue the instruction +
+ + .ENDNOTE_REFS + +anywhere before the first citation in your file. Endnote markers +will be inserted into the text, and the bibliographic information +for the citation will appear as an endnote entry. +

+ +

+Note that if you want references parenthetically inserted +into running text, referring to entries in a works-cited list +(bibliography) that mom and refer assemble +automatically, no special instructions are required. See +Generating a bibliography from parenthetical insertions +for how to output the collected references. +

+ +

+For outputting an entire refer database, or +generating a comprehensive reading list from a database, see the +macro +BIBLIOGRAPHY. +

+ +

4. Accessing references in the database

+ +

+References are accessed by putting keywords from the desired database +record between two special refer commands: +
+ + .[ + +and +
+ + .] + +Keywords are any word, or set of words, that identify a database +record unambiguously. Thus, if you have only one database record for +the author Ray Bradbury, +
+ + .[ + bradbury + .] + +is sufficient. However, if your database contains several records +for books by Bradbury, say, Fahrenheit 451 and The +Martian Chronicles, +“bradbury 451” and +“bradbury martian” would identify the two records unambiguously. +

+ +

+A special database field identifier, %K, lets you create +unique keywords for database records to help clear up any ambiguity. +

+ +

+Notice that you don’t have to worry about capitalization when +entering keywords. +

+ +

5. Entering footnote/endnote references

+ +

+Depending on which you have issued, a +.FOOTNOTE_REFS +or an +.ENDNOTE_REFS +command, entering references is done like this: +
+ + .REF + .[ + keyword(s) + .] + .REF + +If FOOTNOTE_REFS is in effect, the reference between the first +and second .REF will be treated as a footnote. If +ENDNOTE_REFS, it will be treated as an endnote. Endnote references +must be explicitly output with +ENDNOTES +at the end of your file, before +TOC. +

+ +
+

+Important: +REF behaves identically to +FOOTNOTE +and +ENDNOTE +with respect to the use of the \c inline escape. Please +read the +HYPER IMPORTANT NOTE +found in the document entry for FOOTNOTE (which also applies to +ENDNOTE). +

+
+ +

6. Parenthetical insertions

+ +

+See +Inserting parenthetical references into +text. +

+ +

7. Generating a bibliography from parenthetical insertions

+ +

+To generate a bibliography from works cited by parenthetical +insertions in the text, put this at the end of your document, before +.TOC. +
+ + .BIBLIOGRAPHY + .[ + $LIST$ + .] + .BIBLIOGRAPHY OFF + +

+ +

8. Generating a comprehensive bibliography

+ +

+You can also generate a comprehensive bibliography, which is to say a +bibliography containing more works than are actually cited (a +“reading list”), by placing references between +.BIBLIOGRAPHY +and +.BIBLIOGRAPHY OFF. +Once you have input the desired references, insert +
+ + .[ + $LIST$ + .] + +and follow it with .BIBLIOGRAPHY OFF. Study the +example below if you’re having trouble visualizing this. +

+ +
Example bibliography
+
+ +.BIBLIOGRAPHY +.R1 +no-label-in-text +no-label-in-reference +join-authors ", and " ", " ", and " +sort A1Q1T1B1E1 +reverse A1 +database <full path to database> +.R2 +.[ +bradbury +.] +.[ +pratchett +.] +.[ +$LIST$ +.] +.BIBLIOGRAPHY OFF + +
+ +

+Alternatively, you can output an entire database as a +bibliography. Do the following at the end of your document, before +.TOC. +
+ + .BIBLIOGRAPHY + .R1 + no-label-in-text + no-label-in-reference + join-authors ", and " ", " ", and " + sort A1Q1T1B1E1 + reverse A1 + bibliography <full path to database> + .R2 + .BIBLIOGRAPHY OFF + +

+ +

9. Invoking groff with mom and refer

+ +

+So, now you’ve got a document formatted properly to use +references processed with refer, what do you do to output +the document? +

+ +

+It’s simple. Pass the -R flag to pdfmom or groff, +like this: +
+ + pdfmom -R <filename> ... + +

+
+ +

+ +

MLA (Modern Language Association) style

+ +

Types of references (endnote, footnote, or embedded in text)

+ +

+MLA allows for three types of references, or referencing styles: +

+
    +
  • short, parenthetical references in the text, linked to a + works-cited list (bibliography) at the end of the document
  • +
  • footnote references
  • +
  • endnote references
  • +
+ +

+There are significant differences between the way footnote/endnote +references should be formatted, and the formatting style of +bibliographies. One example is that footnote/endnote references +should have their first lines indented, whereas bibliographic +references should have their second lines indented. Fortunately, +with mom, there’s no need to concern yourself with the differences; +they’re taken care of automatically. +

+ +

+In terms of inserting references into your documents, +footnote/endnote references are input in a manner similar to +entering any other kind of +footnote +or +endnote. +Parenthetical references, however, need to be handled differently. +See the next section. +

+ +

Inserting parenthetical references into the text

+ +

+MLA style prefers restricting the information in parenthetical +references to the barest minimum needed to identify works +in the works-cited list (the bibliography). Typically, a +parenthetical insertion is just the author’s last name +followed by the page number of the cited work (if only one work by +that author is cited), or by the author, a shortened title of the +work, and the page number (if more than one work is cited). +

+ +

+This necessitates a slightly fiddly way of entering parenthetical +references, though not by any means difficult or hard to make sense +of. +

+ +

+The refer block suggested +here +for parenthetical references prints only the author’s +last name from the database record identified by your keywords +(the label command), surrounded by parentheses (the +bracket-label command). Therefore, assuming you are +citing Ray Bradbury’s The Martian Chronicles, and it is +the only work by Bradbury mentioned in the text, +
+ + ...end of sentence. + .[ + martian chronicles + .] + A new sentence... + +will insert “...end of sentence (Bradbury). A new sentence...” into the text. +The Martian Chronicles will be added +to the works-cited list generated at the end of the document if it +is not already present as the result of an earlier reference. +

+ +

+If you need a page number to identify where in The Martian +Chronicles to find a specific quote +
+ + "...aluminum roaches and iron crickets." + .[ + [ martian chronicles + .] 168) + A new sentence... + +results in “...aluminum roaches and iron crickets.” (Bradbury 168) A new sentence...” +(which is excruciatingly correct MLA style). The +“[” before martian chronicles tells +refer to print the opening parenthesis; any text immediately +following the “.]”, including spaces, +replaces the closing parenthesis. (Notice that you have to +add the closing parenthesis yourself after the page number.) +

+ +

+If your document cites more than one work by Bradbury and you need +a title and page number in addition to the author’s name in +the inline reference, +
+ + "...aluminum roaches and iron crickets." + .[ + [ bradbury martian + .], \fIChronicles\fP 168) + A new sentence... + +will produce ““...aluminum roaches and iron crickets.” (Bradbury, Chronicles 168) A new sentence...”. +

+ +
+

The ‘label’ and ‘bracket-label’ commands

+ +

+The label and bracket-label commands in +the refer block allow you to customize what information goes +into parenthetical references, and how they should be formatted. +label dictates which fields from the database record +to print and how to punctuate them. bracket-label +controls the bracketing style. Users are encouraged to consult +man refer for usage. +

+ +

+Here’s an example of how to set up APA-style references, which +require the author and date of publication, optionally with a page +number or range of pages. +
+ + .R1 + label "(A.n|Q) ', ' D.y" + bracket-label " (" ")" ", " + join-authors ", and " ", " ", and " + move-punctuation + reverse A1 + sort A1Q1T1B1E1 + database /home/peter/Groff-mom/Testing/Refer/refer-database + .R2 + +Assuming a reference to a work by Ursula Leguin published in 1980 +
+ + .[ + leguin + .] + +produces + +(Leguin, 1980) +. +If a page number is also required +
+ + .[ + [ leguin + .], p. 73) + +produces +(Leguin, 1980, p. 73). +

+
+ +

+ +

The refer database

+ +

Introduction

+ +

+The heart and soul of refer is the bibliographic +database. Knowing how to create records (i.e. the entries for works +cited in a document) is largely a question matching data (author, +title, publisher, etc) with the correct field identifier. For +example, if you’re citing from a scholarly journal, you need to know +that %J is the field identifier for journal names and +%N is the field identifier for the journal number. Use +the +Quick list of field identifiers +as your guide. +

+ +

The rules

+ +

+Entering the data correctly is also important. Fortunately, there +are very few rules, and those there are make sense. In a nutshell: +

+
    +
  • enter the data in each field in natural order; author John Smith is + “John Smith”, editor Jane Doe is “Jane Doe”
  • +
  • capitalize all proper nouns and words in titles as you expect + to see them; otherwise, use lowercase
  • +
  • use no terminating punctuation unless required; typically, + required punctuation is the period after a shortform + (“ed.” or “eds.”, “Jr.”, + etc) or a question mark or exclamation mark at the end of a + title
  • +
  • if part of a field needs to be set off in single-quotes, use + \[oq] and \[cq] (openquote, closequote) rather than the + single-quote (or apostrophe) character on your keyboard
  • +
  • if part of a field needs to be forced into italics, use the + escapes \*[IT] and + \*[PREV]; if the italicized portion + concludes the field, omit \*[PREV]
  • +
  • if you require characters with accents, ligatures or special + symbols, use groff’s “named” glyphs (e.g. + \['e] for ĂŠ); a full list can be found in + man groff_char
  • +
+ +

Quick guide to field identifiers (click on any that are links for more information)

+ +
+ +%A author – records may contain multiple authors, + one per line +%Q non-human author – corporate author, e.g. National Geographic; + may also be used for exceptional reference types +%m multiple authors – whenever "et al." is desirable +%i idem – multiple works by the same author +%p post-author – post-author information (e.g. appendix, + foreword, letter) +%T title – primary title (of a book) or the + title of an article (within a scholarly + journal or a magazine) +%B book title – when %T contains the title of an article; +%q force quote – force a title into double-quotes +%t reprint title – if different from a work's original title +%b main author – when citing a preface, foreword, + introduction, or afterword, the author of + the complete original work +%E editor – records may contain multiple editors, + one per line +%l translator – if more than one translator, all the + names +%r translator – if tr. and ed. are one in the same + and editor +%M magazine or – when %T contains the title of an article + newspaper +%J journal – when %T contains the title of an article +%e edition – number or name of an edition + (e.g. Second, 2nd, Collector's, etc.) +%S series – series name of books or journals +%V volume – volume number (of books) +%N journal number – journal or magazine number +%R report number – technical report number +%G gov’t. – government ordering number +%O other – information for which there is no appropriate + field letter +%C city – city of publication +%I publisher – publisher +%D date – publication date +%d original + publication date – if different from date of publication +%P page(s) – page number or range +%n annotation – annotation to the reference +%s site name – for internet references, the website name +%c content – for internet references, the source of + the material (e.g. Web or Email); for websites, + the content, if unclear +%o organization – for internet sites, the organization, group + or sponsor of the site +%a access date – for internet sites, the date of access +%u URL – for internet sites, the full URL +%K keywords – words that help clear up ambiguities in + the database + +
+ +

Field identifiers: specifics, usage and examples

+ +

%A – author field

+ +

+For multiple authors, enter each in a separate %A +field in the order in which they should appear. If the author on +the title page is the editor (say, a book of short stories edited by +Ray Bradbury), add , ed. to the end of the +%A field, like this: +
+ + %A Ray Bradbury, ed. + +Do not use the %E field in these instances. If the work +has several such editors, enter each in a separate %A +field, as for multiple authors, and add , eds. to the +last one, like this: +
+ + %A Jane Dearborne + %A Bill Parsons, eds. + +

+ +

%Q – exceptional entries

+ +

+Sometimes, a work has no author or title information, for example a +book review in a newspaper. In such cases, use %Q, like +this: +
+ + %Q Rev. of \*[IT]Mean Streets Omnibus\*[PREV], ed. Raymond Hammett + %M Times Literary Supplement + %D 7 July 1972 + +

+ +

%m – multiple authors (et al.)

+ +

+Whenever it’s desirable to abbreviate a list of authors with +“et al.” enter it in the %m field, like this: +
+ + %A Paul Lauter + %A Doug Scofield + %m et al. + +

+ +

%i – idem

+ +

+Whenever there are several works by the same author, fill out the +%A field with the author’s name and follow it with the +%i idem, like this: +
+ + %A Jonathon Schmidt + %i idem + +Per MLA style, the author’s name will be replaced by a long dash. +

+ +

+If it’s necessary to state the role the author served (say, +editor or translator), fill out the %i field with the +information minus idem, like this: +
+ + %A Ray Bradbury + %i ed. + %T Timeless Stories for Today and Tomorrow + +

+ +

%p – post-author information

+ +

+When citing from a preface, foreword, introduction, afterword, +or appendix, MLA requires that the information come between the +author’s name and the work’s title, like this: +
+ + %A Martin Packham, Jr. + %p appendix + %T Why the West was Won + +Do not capitalize the first word in the %p field unless +it is a proper noun. +

+ +

%q – force title into double-quotes

+ +

+Occasionally, you may not be able to use %T for the +title because doing so will cause it to come out in italics when +double-quotes are called for. An example of this is when citing +from a dissertation. Use %q to get around the problem, +like this: +
+ + %A Carol Sakala + %q Maternity Care Policy in the United States + %O diss., Boston U, 1993 + +

+ +

%E – editor

+ +

+Use this only if the author and the editor are not one in the same, +e.g. +
+ + %A Geoffrey Chaucer + %T The Works of Geoffrey Chaucer + %E F. W. Robinson + +

+ +

%l – translator

+ +

+If there is more than one translator, enter all the names, with +appropriate conjunctions and punctuation, like this: +
+ + %A Feodor Dostoevsky + %T Crime and Punishment + %l Jessie Coulson, Marjorie Benton, and George Bigian + +

+ +

%O – other

+ +

+Occasionally, MLA requires additional information after the title +but before the publication data (city/publisher/date), for instance, +the number of volumes in a series, or the fact that the work cited +is a dissertation. Here are two examples: +
+ + %A Arthur M. Schlesinger + %T History of U.S. Political Parties + %O 4 vols. + %C New York + %I Chelsea + %D 1973 + + %A Carol Sakala + %q Maternity Care Policy in the United States + %O diss., Boston U, 1993 + +Do not capitalize the first word of the %O field unless +it is a proper noun. +

+ +

+Generally, consider %O a catch-all for information that +does not match the criterion of any existing field identifier. +

+ +

%C – city

+ +

+Normally, %C takes the name of the city of publication, +and that’s all. In the case of a republished book, if new material +has been added, put such information in the %C +field, like this: +
+ + %A Theodore Dreiser + %T Sister Carrie + %d 1900 + %C Introd. E. L. Doctorow, New York + +

+ +

%d – original date of publication

+ +

+Normally, all that is required in the %d field is the +original date of publication. However, if supplementary original +publication data is desired, include it in the field, like this: +
+ + %A Kazuo Ishiguro + %T The Remains of the Day + %d London: Faber, 1989 + %C New York + %I Knopf + %D 1990 + +

+ +

%K – keywords

+ +

+Refer hates ambiguity, and complains when encountering +it. Ambiguities result from the duplication of any word in more +than one database record when that word is used to identify a +reference in your input file. Use %K to create unique +keywords found nowhere else in the database. +

+ +

+Imagine, for example, that your database contains records for +Ray Bradbury’s The Illustrated Man, another record for +The Illustrated Bradbury and a third for Bradbury, +Illustrated. %K can be used to clear up any +ambiguities by assigning a unique word to each record, for example +%K ill-man for the first, %K ill-brad for the +second, and %K brad-ill for the third. +

+ +

%P – pages

+ +

+When citing page numbers, which is often the case with footnotes +and endnotes, it is not necessary to put the numbers in the database +records. The %P field can be added underneath the +keyword(s) in the .[ / .] entries in your +input file, allowing you to recycle database records. For example, +
+ + %A Frye + %T Anatomy + %K frye-anat + +could be your short record for Northrop Frye’s The Anatomy of +Criticism. Any time you wanted to cite a particular page or +range of pages from that work in a footnote or endnote, you can +put +
+ + .REF + .[ + frye-anat + %P 67-8 + .] + .REF + +in your input file, and have it show up with the correct page(s). +

+ +

%n – annotations

+ +

+Annotations come at the very end of references. Capitalize all +words that require it, including, for bibliographic references (but not +for footnotes/endnotes) the first. +

+ +

+ +
+

The bibliography and reference macros

+ +
+ + + +
+

Begin/end a reference that goes in a footnote or endnote

+
+ +
+Macro: REF +
+ +

+The macro REF tells mom that what follows is +refer-specific, a keyword-identified reference to a +refer database record. Depending on whether you’ve issued +a +.FOOTNOTE_REFS +or +.ENDNOTE_REFS +instruction, the reference will be formatted and placed in a +footnote, or collected for output in the endnotes. Parenthetical +insertion of references into the text do not require +.REF (see +Inserting parenthetical references into the text.) +

+ +

+Before you use REF, you must create a refer block +containing refer commands (see +Required refer commands +in the tutorial, above). +

+ +

+REF usage always looks like this: +
+ + .REF + .[ + keyword(s) + .] + .REF + +Notice that REF “brackets” the refer instructions, +and never takes an argument. +

+ +

+What REF really is is a convenience. One could, for example, put a +reference in a footnote by doing +
+ + .FOOTNOTE + .[ + keyword(s) + .] + .FOOTNOTE OFF + +However, if you have a lot of references going into footnotes (or +endnotes), it’s much shorter to type .REF/.REF +than .FOOTNOTE/.FOOTNOTE OFF. It also helps you +distinguish—visually, in your input file—between +footnotes (or endnotes) which are references, and footnotes (or +endnotes) which are explanatory, or expand on the text. +

+ +
+

+Note: +If you’re using REF to put references in footnotes and your +footnotes need to be indented, you may (indeed, should) pass REF the +same arguments used to indent footnotes. See +FOOTNOTE. +

+ +

+Additional note: +REF behaves identically to +FOOTNOTE +or +ENDNOTE, +so please read the HYPER IMPORTANT NOTE found in the document entry +for +FOOTNOTE +and/or +ENDNOTE +for instructions on correct entry of text preceding and following REF. +

+
+ + + + +
+

Instruct mom to put references in footnotes

+
+ +
+Macro: FOOTNOTE_REFS +
+ +

+FOOTNOTE_REFS is an instruction to +REF, +saying, “put all subsequent references bracketed by the REF +macro into footnotes.” You invoke it by itself, with no +argument. +

+ +

+When FOOTNOTE_REFS is in effect, regular footnotes, (i.e. +those introduced with .FOOTNOTE and terminated with +.FOOTNOTE OFF) continue to behave normally. +

+ +

+You may switch between FOOTNOTE_REFS and +ENDNOTE_REFS +at any time. +

+ +

+By default, FOOTNOTE_REFS sets the +FOOTNOTE_MARKER_STYLE +to NUMBER (i.e. superscript numbers). You may change +change that if you wish by invoking FOOTNOTE_MARKER_STYLE, with the +argument you want, after FOOTNOTE_REFS. +

+ +

+If you have a lot of footnote references, and are identifying +footnotes by line number rather than by markers in the text, you may +want to enable +FOOTNOTES_RUN_ON +in conjunctions with FOOTNOTE_REFS. +

+ + + +
+

Instruct mom to put references in endnotes

+
+ +
+Macro: ENDNOTE_REFS +
+ +

+ENDNOTE_REFS is an instruction to +REF, +saying, “add all subsequent references bracketed by the REF +macro to endnotes.” You invoke it by itself, with no argument. +

+ +

+When ENDNOTE_REFS is in effect, mom continues to format regular +endnotes, (i.e. those introduced with .ENDNOTE and +terminated with .ENDNOTE OFF) in the normal way. +

+ +

+You may switch between ENDNOTE_REFS and +FOOTNOTE_REFS +at any time. +

+ + + +
+

Manage indenting of references, per MLA standards

+
+ +
+Macro: INDENT_REFS FOOTNOTE | ENDNOTE | BIBLIO <indent> +
+ +

+• <indent> requires a unit of measure +

+ +

+MLA-style requires that footnote or endnote references should +have their first lines indented, whereas bibliographic references +should have their second and subsequent lines indented. Thus, if +you invoke INDENT_REFS with a first argument of FOOTNOTE +or ENDNOTE, the value you give to +<indent> sets the indent of the first line for +those types of references; if you invoke it with BIBLIO, +the value you give <indent> sets the indent of +second and subsequent lines in bibliographies. +

+ +

+By default, the indent for all three types of references is 1/2-inch +for +PRINTSTYLE TYPEWRITE +and 2 +ems +for +PRINTSTYLE TYPESET. +

+ +

+If you’d like to change the indent for footnote, endnote or +bibliography references, just invoke .INDENT_REFS with +a first argument saying which one you want the indent changed for, and +a second argument saying what you’d like the indent to be. +For example, if you want the second-line indent of references on a +bibliography page to be 3 +picas, +
+ + .INDENT_REFS BIBLIO 3P + +is how you’d set it up. +

+ +
+

+Tip: +If you are identifying endnotes by line number +(ENDNOTE_MARKER_STYLE LINE) +and have instructed mom to put references bracketed by +.REF +into endnotes (with +ENDNOTE_REFS), +you will almost certainly want to adjust the second-line indent for +references in endnotes, owing to the way mom formats line-numbered +endnotes. Study the output of such documents to see whether an +indent adjustment is required. +

+ +

+The same advice applies to references in endnotes when you have enabled +
+ + .ENDNOTE_NUMBERS_ALIGN_LEFT + +in favour of mom’s default, which is to align them right. +Study the output to determine what size of second-line indent works +best. +

+ +

+(Frankly, endnote references formatted in MLA-style combined with +left-aligned endnote numbers is a no-win situation, and so is best +avoided. Wherever you set the indent, you’ll end up with the +endnote numbers appearing to hang into the left margin, so you might +as well have them hang, as is the case with +.ENDNOTE_NUMBERS_ALIGN_RIGHT.  – Ed.) +

+
+ + + +
+

Enable/disable hyphenation of references

+
+ +
+Macro: HYPHENATE_REFS <toggle> +
+ +

+If you have hyphenation turned on for a document (see +HY), +and in most cases you probably do, mom will hyphenate references +bracketed by the +REF +macro. Since references typically contain quite a lot of proper +names, which shouldn’t be hyphenated, you may want to disable +hyphenation for references. +

+ +

+HYPHENATE_REFS is a toggle macro; invoking it by itself will turn +automatic hyphenation of REF-bracketed references on (the default). +Invoking it with any other argument (OFF, NO, +X, etc.) will disable automatic hyphenation for +references bracketed by REF. +

+ +

+An alternative to turning reference hyphenation off is to prepend +to selected proper names in your refer database +the groff +discretionary hyphen +character, \%. (See +here +in the tutorial for an example.) +

+ +
+

+Note: +References embedded in the body of a document are considered part of +running text, +and are hyphenated (or not) according to whether hyphenation is +turned on or off for running text. Therefore, if you want to +disable hyphenation for such references, you must do so temporarily, +with +HY, +like this: +
+ + .HY OFF + .[ + keyword(s) + .] + .HY + +Alternatively, sprinkle your database fields liberally with +\%. +

+
+ + + +
+

Begin a bibliography

+
+ +
+Macro: BIBLIOGRAPHY toggle +
+ +

+To append a bibliography to your document, whether of references +inserted parenthetically into text or a comprehensive reading list +derived from a large refer database, all you need +do is invoke .BIBLIOGRAPHY. .BIBLIOGRAPHY +breaks to a new page, prints the title (BIBLIOGRAPHY by default, but +that can be changed), and awaits refer instructions. How +to create bibliographies is covered in the tutorial section, +Generating a bibliography from parenthetical insertions +and +Generating a comprehensive bibliography. +When all the required data has been entered, type +
+ + .BIBLIOGRAPHY OFF + +to complete the bibliography. +

+ +

+See the +Bibliography control macros and defaults +for macros to tweak, design and control the appearance of +bibliography pages. +

+ + + +
+

Plain, or numbered list bibliography

+
+ +
+Macro: BIBLIOGRAPHY_TYPE PLAIN | LIST [ <list separator> ] [ <list prefix> ] +
+ +

+Mom offers two styles of bibliography output: plain, or numbered +list style. With the argument, PLAIN, bibliography entries are output +with no enumerators. With the argument, LIST, each entry is numbered. +

+ +

+The two optional arguments, <list separator> +and <list prefix> have the same meaning as the +equivalent arguments to +LIST +(i.e. <separator> and <prefix>). +

+ +

+You may enter the BIBLIOGRAPHY_TYPE either before or after +.BIBLIOGRAPHY. It must, however, always come before +any refer commands. See +Generating a bibliography from parenthetical insertions +and +Generating a comprehensive bibliography. +

+ +

+Mom’s default BIBLIOGRAPHY_TYPE is PLAIN. +

+ + + + + +

1. General bibliography page style control

+ +
• Base family/font/quad
+ +
+

+See +Arguments to the control macros. +

+ +.BIBLIOGRAPHY_FAMILY default = prevailing document family; default is Times Roman +.BIBLIOGRAPHY_FONT default = roman +.BIBLIOGRAPHY_QUAD* default = justified + +*Note: BIBLIOGRAPHY_QUAD must be set to either L (LEFT) or J (JUSTIFIED); + R (RIGHT) and C (CENTER) will not work. + +
+ + + +
• Base point size
+ +
+Macro: BIBLIOGRAPHY_PT_SIZE <base type size of bibliography> +
+ +

+Unlike most other control macros that deal with size of document +elements, BIBLIOGRAPHY_PT_SIZE takes as its argument an absolute +value, relative to nothing. Therefore, the argument represents the +size of bibliography type in +points, +unless you append an alternative +unit of measure. +For example, +
+ + .BIBLIOGRAPHY_PT_SIZE 12 + +sets the base point size of type on the bibliography page to 12 +points, whereas +
+ + .BIBLIOGRAPHY_PT_SIZE .6i + +sets the base point size of type on the bibliography page to 1/6 of an +inch. +

+ +

+The type size set with BIBLIOGRAPHY_PT_SIZE is the size of type used +for the text of the bibliographies, and forms the basis from which +the point size of other bibliography page elements is calculated. +

+ +

+The default for +PRINTSTYLE TYPESET +is 12.5 points (the same default size used in the body of the +document). +

+ + + +
• Leading
+ +
+Macro: BIBLIOGRAPHY_LEAD <base leading of bibliographies> [ ADJUST ] +
+ +

+• Does not require a unit of measure; points is assumed +

+ +

+Unlike most other control macros that deal with leading of document +elements, BIBLIOGRAPHY_LEAD takes as its argument an absolute value, +relative to nothing. Therefore, the argument represents the +leading +of bibliographies in +points +unless you append an alternative +unit of measure. +For example, +
+ + .BIBLIOGRAPHY_LEAD 14 + +sets the base leading of type on the bibliography page to 14 +points, whereas +
+ + .BIBLIOGRAPHY_LEAD .5i + +sets the base leading of type on the bibliography page to 1/2 inch. +

+ +

+If you want the leading of bibliographies adjusted to fill the page, +pass BIBLIOGRAPHY_LEAD the optional argument, +ADJUST. (See +DOC_LEAD_ADJUST +for an explanation of leading adjustment.) +

+ +

+The default for +PRINTSTYLE TYPESET +is the prevailing document lead (16 by default), adjusted. +

+ +
+

+Note: +Even if you give mom a .DOC_LEAD_ADJUST OFF command, +she will still, by default, adjust bibliography leading. You +must enter BIBLIOGRAPHY_LEAD <lead> +with no ADJUST argument to disable this default +behaviour. +

+
+ + + +
• Adjust the space between bibliography entries
+ +
+Macro: BIBLIOGRAPHY_SPACING <amount of space> +
+ +

+• Requires a unit of measure +

+ +

+By default, mom inserts no space between bibliography entries. +If you’d prefer she add some, instruct her to do so with +BIBLIOGRAPHY_SPACING. Say, for example, you want a half a linespace +between entries, +
+ + .BIBLIOGRAPHY_SPACING .5v + +would do the trick. +

+ +
+

+Note: +As with endnotes pages, inserting space between bibliography entries +will most likely result in hanging bottom margins. +

+
+ + + +
• Singlespace bibliography (TYPEWRITE only)
+ +
+Macro: SINGLESPACE_BIBLIOGRAPHY <toggle> +
+ +

+If your +PRINTSTYLE +is TYPEWRITE and you use TYPEWRITE’s default +double-spacing, bibliographies are double-spaced. If your document +is single-spaced, bibliographies are single-spaced. +

+ +

+If, for some reason, you’d prefer that bibliographies be +single-spaced in an otherwise double-spaced document (including +double-spaced +collated +documents), invoke .SINGLESPACE_BIBLIOGRAPHY with no +argument. +

+ + + +
• Turning off column mode during bibliography output
+ +
+Macro: BIBLIOGRAPHY_NO_COLUMNS <toggle> +
+ +

+By default, if your document is set in +columns, +mom sets the bibliographies in columns, too. However, if your +document is set in columns and you’d like the bibliographies +not to be, just invoke .BIBLIOGRAPHY_NO_COLUMNS with +no argument. The bibliography pages will be set to the full page +measure of your document. +

+ +

+If you output bibliographies at the end of each document in a +collated +document set in columns, column mode will automatically be +reinstated for each document, even with BIBLIOGRAPHY_NO_COLUMNS +turned on. In such circumstances, you must re-enable +BIBLIOGRAPHY_NO_COLUMNS for each separate collated document. +

+ +

2. Pagination of bibliographies

+ + + +
• Page numbering style
+ +
+Macro: BIBLIOGRAPHY_PAGENUM_STYLE DIGIT | ROMAN | roman | ALPHA | alpha +
+ +

+Use this macro to set the page numbering style of bibliography +pages. The arguments are identical to those for +PAGENUM_STYLE. +The default is digit. You may want to change it to, say, +alpha, which you would do with +
+ + .BIBLIOGRAPHY_PAGENUM_STYLE alpha + +

+ + + +
• Setting the first page number of bibliographies
+ +
+Macro: BIBILOGRAPHY_FIRST_PAGENUMBER <page # that appears on page 1 of bibliographies> +
+ +

+Use this macro with caution. If the bibliography for a +collated +document is to be output at the document’s end, +BIBLIOGRAPHY_FIRST_PAGENUMBER tells mom what page number to put on +the first page of the bibliography. +

+ +

+However, if you’re outputting a bibliography at the end of each +section (chapter, article, etc) of a collated document, +you have to reset every section’s first page number after +COLLATE +and before +START. +

+ + + +
• Omitting a page number on the first page of bibliographies
+ +
+Macro: BIBLIOGRAPHY_NO_FIRST_PAGENUM <toggle> +
+ +

+This macro is for use only if +FOOTERS +are on. It tells +BIBLIOGRAPHY +not to print a page number on the first bibliography page. +Mom’s default is to print the page number. +

+ + + +
• Suspending pagination during bibliography output
+ +
+Macro: SUSPEND_PAGINATION +
+ +
+Macro: RESTORE_PAGINATION +
+ +

+SUSPEND_PAGINATION doesn’t take an argument. Invoked +immediately prior to +BIBLIOGRAPHY, +it turns off pagination for the duration of the bibliography. Mom +continues, however to increment page numbers silently. +

+ +

+To restore normal document pagination after bibliographies, invoke +.RESTORE_PAGINATION (again, with no argument) immediately +after you’ve finished with your bibliography. +

+ +

3. Header/footer control

+ +
• Modifying what goes in the bibliography header/footer
+ +

+If you wish to modify what appears in the header/footer that appears +on bibliography pages, make the changes before you invoke +.BIBLIOGRAPHY, +not afterwards. +

+ +

+Except in the case of +DOCTYPE CHAPTER, +mom prints the same header or footer used throughout the document +on bibliography pages. Chapters get treated differently in that, +by default, mom does not print the header/footer centre string +(normally the chapter number or chapter title.) In most cases, this +is what you want. However, should you not want mom to remove the +centre string from the bibliography pages’ headers/footers, or +you would like her to add one in cases where there hasn’t been +one before (e.g. DOCTYPE DEFAULT) invoke +.BIBLIOGRAPHY_HEADER_CENTER +with no argument. +

+ +

+An important change you may want to make is to put the word +“Bibliography” in the header/footer centre position. To +do so, invoke +
+ + .BIBLIOGRAPHY_HEADER_CENTER + .HEADER_CENTER "Bibliography" + +or + + .BIBLIOGRAPHY_FOOTER_CENTER + .FOOTER_CENTER "Bibliography" + +prior to invoking .BIBLIOGRAPHY. +

+ +
+

+Important: +Unless you have a running centre string in your headers or footers, you must invoke + + .BIBLIOGRAPHY_HEADER_CENTER + +or + + .BIBLIOGRAPHY_FOOTER_CENTER + +in order for the centre string to appear, as demonstrated above. +

+
+ +
• Header/footer centre string when doctype is CHAPTER
+ +
+Macro: BIBLIOGRAPHY_HEADER_CENTER toggle +
+ +

+If your +DOCTYPE +is CHAPTER and you want mom to include a centre +string in the headers/footers that appear on bibliography +pages, or if you do not have a running header/footer +centre string in the body of the document, invoke +.BIBLIOGRAPHY_HEADER_CENTER (or +.BIBLIOGRAPHY_FOOTER_CENTER) with no argument before +defining the centre string . Mom’s default is NOT to print the +centre string. +

+ +

+If, for some reason, having enabled the header/footer centre string +on bibliography pages, you wish to disable it, invoke the same macro +with any argument (OFF, QUIT, Q, +X...). +

+ +
• Allow headers on bibliography pages
+ +
+Macro: BIBLIOGRAPHY_ALLOWS_HEADERS <none> | ALL +
+ +

+By default, if HEADERS are on, mom prints page headers on all +bibliography pages except the first. If you don’t want her to +print headers on bibliography pages, do +
+ + .BIBLIOGRAPHY_ALLOWS_HEADERS OFF + +If you want headers on every page including the first, do +
+ + .BIBLIOGRAPHY_ALLOWS_HEADERS ALL + +

+ +
+

+Note: +If FOOTERS are on, mom prints footers on every bibliography page. +This is a style convention. In mom, there is no such beast as +BIBLIOGRAPHY_ALLOWS_FOOTERS OFF. +

+
+ +

4. Bibliography first-page title control

+ + + +
• Title string
+ +
+Macro: BIBLIOGRAPHY_STRING "<title to print at the top of bibliography pages>" +
+

+Alias: BIBLIOGRAPHY_HEADER +

+ +

+By default, mom prints the word “BIBLIOGRAPHY” as a title +at the top of the first page of a bibliography. If you want her to +print something else, invoke .BIBLIOGRAPHY_STRING with +the title you want, surrounded by double-quotes. +

+ +

+If you don’t want a title at the top of the first bibliography +page, invoke .BIBLIOGRAPHY_STRING with a blank argument +(either two double-quotes side by +side—""—or no argument at all). +

+ + + +
• Title string control macros and defaults
+ +
+

+See +Arguments to the control macros. +

+ +.BIBLIOGRAPHY_STRING_FAMILY default = prevailing document family; default is Times Roman +.BIBLIOGRAPHY_STRING_FONT default = bold +.BIBLIOGRAPHY_STRING_SIZE* default = +1 +.BIBLIOGRAPHY_STRING_QUAD default = centred + +*Relative to the size of the bibliography text (set with BIBLIOGRAPHY_PT_SIZE) + +
+ + + +
• Title string placement
+ +
+Macro: BIBLIOGRAPHY_STRING_ADVANCE <distance from top of page> +
+ +

+• Argument requires a unit of measure +

+ +

+By default, mom places the title (the docheader, as it were) of +bibliographies (typically "BIBLIOGRAPHY") on the same +baseline +that is used for the start of +running text. +If you’d prefer another location, higher or lower on the page +(thereby also raising or lowering the starting position of the +bibliography itself), invoke .BIBLIOGRAPHY_STRING_ADVANCE +with an argument stating the distance from the top edge of the page +at which you’d like the title placed. +

+ +

+The argument requires a unit of measure, so if you’d like the title +to appear 1-1/2 inches from the top edge of the page, you’d tell +mom about it like this: +
+ + .BIBLIOGRAPHY_STRING_ADVANCE 1.5i + +

+ + + +
• Title string underscoring
+ +
+Macro: BIBLIOGRAPHY_STRING_UNDERSCORE [DOUBLE] [<underline weight> [<underline gap> [<distance between double rules]]] | <none> | <anything> +
+ +

+Alias: BIBLIOGRAPHY_STRING_UNDERLINE +

+ +

+• The argument +<underscore weight> +must not have the +unit of measure, +p, appended to it +

+ +

+Invoked without an argument, +.BIBLIOGRAPHY_STRING_UNDERSCORE will place a single rule +underneath the bibliography’s first-page title. Invoked with the +argument, DOUBLE, BIBLIOGRAPHY_STRING_UNDERSCORE will +double-underscore the title. Invoked with any other non-numeric +argument, (e.g. OFF, NO, X, etc.) +the macro disables underlining of the title. +

+ +

+In addition, you can use BIBLIOGRAPHY_STRING_UNDERSCORE to control +the weight of the underscore rule(s), the gap between the title and +the underscore, and, in the case of double-underscores, the distance +between the two rules. +

+ +

+Some examples: +
+ + .BIBLIOGRAPHY_STRING_UNDERLINE 1 + - turn underlining on; set the rule weight to 1 point + + .BIBLIOGRAPHY_STRING_UNDERLINE 1 3p + - turn underlining on; set the rule weight to 1 point; set + the gap between the string and the underline to 3 points + + .BIBLIOGRAPHY_STRING_UNDERLINE DOUBLE .75 3p + - turn double-underlining on; set the rule weight to 3/4 of + a point; set the gap between the string and the upper + underline to 3 points; leave the gap between the upper + and the lower underline at the default + + .BIBLIOGRAPHY_STRING_UNDERLINE DOUBLE 1.5 1.5p 1.5p + - turn double-underlining on; set the rule weight to 1-1/2 + points; set the gap between the string and the upper + underline to 1-1/2 points; set the gap between the upper + and the lower underline to 1-1/2 points + +Note, from the above, that in all instances, underscoring (single or +double) is enabled whenever BIBLIOGRAPHY_STRING_UNDERSCORE is used +in this way. +

+ +

+By default, mom double-underscores the title if your +PRINTSTYLE +is TYPEWRITE. +

+ + + +
• Title string capitalization
+ +
+Macro: BIBLIOGRAPHY_STRING_CAPS toggle +
+ +

+Invoked by itself, .BIBLIOGRAPHY_STRING_CAPS will +automatically capitalize the bibliography first-page title. Invoked +with any other argument, the macro disables automatic capitalization +of the title. +

+ +

+If you’re generating a table of contents, you may want the +bibliography first-page title to be in caps, but the toc entry in +caps/lower case. If the argument to +BIBLIOGRAPHY_STRING +is in caps/lower case and BIBLIOGRAPHY_STRING_CAPS is +on, this is exactly what will happen. +

+ +

+Mom’s default is to capitalize the bibliography first-page +title. +

+ +

+ + + + + + + + +
Back to Table of ContentsTopNext: Writing letters
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/reserved.html b/contrib/mom/momdoc/reserved.html new file mode 100644 index 0000000..4cdab3b --- /dev/null +++ b/contrib/mom/momdoc/reserved.html @@ -0,0 +1,2736 @@ + + + + + + + + + Mom -- Reserved words (macros, strings, registers) + + + + + + + +
+ + + + + + +
Back to Table of Contents
+ +

List of reserved words (macros, strings, registers)

+ +

+The following is a list of reserved words used by mom. Before +changing the name of any macro or document element tag with +ALIAS, +I strongly recommend doing a search of this page for your proposed +new name. If you find it in the left hand column, choose something +else instead. +

+ +

+Anyone interested in hacking/patching mom’s macro file +(om.tmac) will also find this list useful since it lists most of +the macros, strings, diversions, aliases, and number registers +mom uses, along with brief descriptions of their functions. +

+ +

+The list is not exhaustive. PDF-related macros, strings, registers, +and diversions, as well as those associated with preprocessor +support and “Lists of” are not included. +

+ +

+ + +TYPESETTING ++++MACROS+++ +*Page layout + PAGELENGTH Page width + PAGE Page width/length; left, right, top, bottom margins + PAGEWIDTH Page width + PAPER Letter, legal, or A4 + B_MARGIN Space to leave at page bottom + L_MARGIN Page offset + R_MARGIN Line length as a function of + pagewidth minus pageoffset minus rightmargin + T_MARGIN Advance lead from page top + +*Page control + DO_B_MARGIN Margin at bottom of page; trap-invoked + DO_T_MARGIN Margin at top of page; trap-invoked + +*Style + COLOR Change color of text to predefined value + CONDENSE Set percentage of pseudo-condense (alias of + CONDENSE_OR_EXTEND) + EXTEND Set percentage of pseudo-extend (alias of + CONDENSE_OR_EXTEND) + FAMILY Family + FT Font + FALLBACK_FONT Font to use whenever FAMILY or FT errors occur + LL Line length + LS Leading (.vs) + NEWCOLOR Define a text color + PT_SIZE Point size + SETBOLDER Set degree of emboldening (pseudo-bold) in units + SETSLANT Set degree of pseudo-italic + XCOLOR Initialize a color from rgb.txt + +*Autolead + AUTOLEAD Always lead n points more than .PT_SIZE + +*Quad, fill, justification + JUSTIFY Justified text + QUAD Filled text, left, right, or centre + +*Quad, no-fill + CENTER Line-for-line, non-filled text, centre + LEFT Line-for-line, non-filled text, left + RIGHT Line-for-line, non-filled text, right + +*Hyphenation + HY Turn hyphenation on/off, or set LINES, MARGIN, SPACE + HY_SET Set LINES, MARGIN, SPACE in a single command + +*Advanced style + KERN Turn automatic kerning on or off + LIGATURES Turn ligatures on or off + SS Sentence space control + WS Word space control + +*Line breaks + BR Alias of br + EL Breaks line but doesn't advance + SPACE Alias of sp + SPREAD Alias of brp + +*Vertical motions + ALD Advance lead + RLD Reverse lead + +*Indents + HI Indent hang + IB Indent both + IBX Indent both off + IL Indent left + ILX Indent left off + IQ Indents off + IR Indent right + IRX Indent right off + IX Indents off -- deprecated + TI Indent temporary + +*Tabs + ST String tab + TAB_SET Tab Set + TN Tab Next + TQ Tab Quit + +*Columnar tabs + MCO Turn on multi-column mode + MCR Return to top of column + MCX Turn off multi-column mode + +*Underscore + UNDERSCORE Underscores words or phrases + UNDERSCORE2 Double underscores words or phrases + +*Underline + UNDERLINE Underlines whole passages (Courier only) + +*Smart Quotes + SMARTQUOTES Turns smart quotes on or off + +*Graphical objects + RULE_WEIGHT Weight of rules drawn with \*[RULE] + DBX Draw box + DCL Draw circle (ellipse) + DRH Draw horizontal rule + DRV Draw vertical rule + +*Misc + Support + BR_AT_LINE_KERN Deposit a break before RW and WE + CAPS Convert u/lc to UC + COMMENT Don't print lines till COMMENT OFF (alias of SILENT) + DROPCAP_ADJUST Points (poss. fractional) to add/subtract + from drop caps + DROPCAP Create drop cap + DROPCAP_FAMILY Drop cap family + DROPCAP_FONT Drop cap font + DROPCAP_GUTTER Drop cap gutter + DROPCAP_OFF Support only; restores .in if there was one + ESC_CHAR Alias for .ec + EW Extra white -- loosen overall line kern + (character spacing) + LEADER_CHARACTER Sets leader character + PAD Insert padding spaces at marked places + PADMARKER Sets character to use instead of # in PAD + PRINT Simply prints args passed to it; keeps my code + indented nicely + RW Reduce white -- tighten overall line kern + (character spacing) + SILENT Don't print lines till SILENT OFF + SIZESPECS Get cap-height, x-height and descender depth for + current point size + SUPERSCRIPT_RAISE_AMOUNT Change default vertical displacement of superscripts + TRAP Turn traps off or on + ++++DIVERSIONS+++ + + NO_FLASH Diverts output of SILENT or COMMENT so they don't print + NULL Diverts SIZESPECS in PRINT_HDRFTR so it doesn't screw up + FOOTER and FOOTNOTE processing when FOOTERS are on + PAD_STRING Diverts $PAD_STRING for processing + TYPESIZE Diverts SIZESPECS routine so it doesn't print + ++++NUMBER REGISTERS+++ + + #ABORT_FT_ERRORS Abort on FT errors? (boolean) + #ALD ALD value + #ARGS_TO_LIST Tells LIST whether LIST was invoked with a valid + arg; controls LIST OFF processing + #ARGS_TO_SQ Tells SMARTQUOTES whether it was invoked with a + valid arg; controls SMARTQUOTES OFF + processing + #AUTOLEAD_FACTOR Using FACTOR arg to AUTOLEAD? (boolean) + #AUTO_LEAD Using autolead? (boolean) + #AUTOLEAD_VALUE Auto leading value + #BL_INDENT Value of left indent when IB + #B_MARGIN Bottom margin + #B_MARGIN_SET Has a bottom margin been set with B_MARGIN? (boolean) + #BOLDER_UNITS Number of units to embolden type + #BR_AT_LINE_KERN Break when EW/RW are invoked? (boolean) + #BR_INDENT Value of right indent when IB + #BX_SOLID Draw box filled? (boolean) + c column mark + #CAPS_ON Is CAPS enabled? (boolean) + #CL_SOLID Draw circle filled? (boolean) + #CODE_FAM Use different family from Courier for CODE? (boolean) + #CODE_FT Use different font from roman for CODE? (boolean) + #CONDENSE Are we in pseudo-condense mode? (boolean) + #CONDENSE_WAS_ON For restoring \*[COND] in DROPCAP + #COND_WIDTH Width of pseudo-condensed type + (pointsize x $COND_PERCENT) + #CURRENT_HY \\n[.hy] when ref*normal-print called + #CURRENT_L_LENGTH Current line length at first invocation of LIST; + like #ORIG_L_LENGTH + #CURRENT_TAB Current tab number + #DC_COLOR Colorize dropcap? (boolean) + #DC_GUT Width of dropcap gutter + #DC_HEIGHT Dropcap height + #DC_LINES Number of lines for dropcap + #DEGREES # of degrees slant for pseudo-italic + #ENUMERATOR<n> Number register enumerator for depth <n> in lists + #EW Is EW in effect? (boolean) + #EXT_WIDTH Width of pseudo-extended type + (pointsize x $EXT_PERCENT) + #EXTEND Are we in pseudo-extend mode? (boolean) + #EXTEND_WAS_ON For restoring \*[EXT] in DROPCAP + #FILL_MODE Which fill mode are we in? ( \n[.j] ) + #FILLED Are we in a fill mode? (boolean) + #H_INDENT Value of left indent when IH + #HL_INDENT<n> Hanging indent for LIST depth <n> + #HL_INDENT Value of the hang when IH + #HY_SET Did we manually set hyphenation parameters? + (boolean) + #HYPHEN_ADJ Amount by which to raise hyphens surrounding page + numbers + #HYPHENATE Hyphenation on? (boolean) + #IN_ITEM Are we in a list item? (boolean) + #IN_ITEM_L_INDENT Value passed to IL if #IN_ITEM=1 + #IN_TAB Are we in a tab? (boolean) + Set in macro TAB; used in ST to determine + whether to add #ST_OFFSET to #ST<n>_OFFSET + #INDENT_ACTIVE Indicates whether an indent is active (boolean) + #INDENT_BOTH_ACTIVE Toggle + #INDENT_LEFT_ACTIVE Toggle + #INDENT_RIGHT_ACTIVE Toggle + #INDENT_STYLE_BOTH Indicates IB when #INDENT_ACTIVE=1 (boolean) + #INDENT_STYLE_HANG Indicates IH when #INDENT_ACTIVE=1 (boolean) + #INDENT_STYLE_LEFT Indicates IL when #INDENT_ACTIVE=1 (boolean) + #INDENT_STYLE_RIGHT Indicates IR when #INDENT_ACTIVE=1 (boolean) + #INDENT_STYLE_TEMP Indicates IT when #INDENT_ACTIVE=1 (boolean) + #IGNORE_COLUMNS Don't set document in columns (boolean) + #IN_DIVER Are we in a diversion? (boolean) + #IX_WARN Toggles to 1 the first time IX is user-invoked + #JUSTIFY In EW/RW, when BR_AT_LINE_KERN, whether to + break or break-spread preceding line (boolean) + #KERN Kern on? (boolean) + #KERN_UNIT Size of kern units (1/36 of current point size) + #KERN_WAS_ON Indicates kerning was on; used in list ITEMs (boolean) + #LAST_TAB Last tab number set in multi-columns + #LAST_FN_COUNT_FOR_COLS #FN_COUNT_FOR_COLS at top of HEADER + #LEAD Leading (alias) + #LIGATURES Ligatures on? (boolean) + #LIST_INDENT<n> Left indent of list <n> + #L_INDENT Value of left indent + #L_LENGTH Line length + #L_MARGIN Page offset if set with LMARGIN; + if .po used, \n[.o] returns page offset + #LOOP In EPIGRAPH, #LOOP=1 if a while loop executes; + otherwise 0. Elsewhere, an arbitrary incrementing + register used to read in strings + #MCX_ALD Amount to advance past end of longest column + #NEWPAGE Was NEWPAGE just invoked? (boolean) + #NEXT_DEPTH_BACK Next list level back in lists + #NEXT_TAB Current tab number + 1 (used in TN) + #NEXT_TAB Next tab in an n+1 sequence + #NOFILL Are we in a nofill mode? (boolean) + #NOFILL_MODE Nofill mode + #OLD_LEAD Lead in effect prior to changing it with .vs + in .LS or .AUTOLEAD + #OPEN_CLOSE Manipulates character " to print `` or '' + #ORIGINAL_L_LENGTH Used in LIST for IB processing; holds \n[.l] + p Output line horiz position at end of + $PAD_STRING + #PAD_COUNT Number of times # was included in arg to PAD + #PAD_LIST_DIGITS Pad list digits to the left? (boolean) + #PAD_SPACE Size of padding space + #PAGE_LENGTH Page length (alias) + #PAGE_WIDTH Page width + #PP_ACTIVE Are we in the context of a para? (boolean) + #PRINT_FOOTER_ON_PAGE_1 (boolean) + #PSEUDO_FILL Signals that LEFT, RIGHT or CENTER is + in effect (booleand off, i.e. to 0, when + QUAD <arg> or JUSTIFY is called) + #PT_SIZE Point size (fractional) in units (alias) + #Q_AT_TOP Does a quote start at the top of a new page? + (boolean) + #QUAD In autoquad mode? (boolean) + #QUIT Tells LIST whether to exit lists completely + (boolean) + #REMOVE Used in LIST OFF cleanup + #RESTORE_FILL Used to restore \[.u] state if temporarily changed + #RESTORE_LEAD Lead value in effect prior to AUTOLEAD + #RESTORE_LINE_LENGTH Restores actual line length in RULE + #RESTORE_LN_NUMBER Start linenumbering again with stored + #NEXT_LN? (boolean) + #RESTORE_PT_SIZE Stores current point size (in units) prior + to underscore + #R_INDENT Value of right indent + #R_MARGIN Right margin + #RESTORE_PREV_INDENT Tells LIST OFF what kind of indent was active + prior to first invocation of LIST + #RESTORE_TRAP Did we have to disable traps? Used in + graphical object macros (boolean) + #RESTORE_SQ Instructs SMARTQUOTES to restore smartquotes if + SMARTQUOTES invoked without an arg + #RLD RLD value + #RULE_WEIGHT Weight given to RULE_WEIGHT + #RULE_WEIGHT_ADJ RULE_WEIGHT/2 + #RW Is RW in effect? (boolean) + #SHIFT_LIST<n> Value to add to #LIST_INDENT<n> for shifted lists + #SILENT Is silent on? (boolean) + #SIZE_FOR_PAD Used to ensure that the size in effect prior + to PAD is restored at the start of every + iteration of $PAD_STRING + #SLANT_ON Is SLANT on? (boolean) + #SPACE_TO_END Whitespace at end of string passed to PAD + #SQ_WAS_ON Instructs CODE OFF to restore smartquotes if they + were on prior to CODE + #ST<n>_LENGTH Length of ST<n>; calculated during ST <n> + #ST<n>_MARK Page offset of autotab <n> at ST<n>X + #ST_NUM Incrementing counter for autotab identification + #ST<n>_OFFSET Offset (from current tab) to add to #ST<n>_OFFSET + when calculating string indents set from within + tabs + #ST<n>_OFFSET Indent of autotab <n> (page offset) + #STORED_L_INDENT Current left indent at first invocation of LIST + #STORED_R_INDENT Current right indent at first invocation of LIST + #STORED_BL_INDENT Current "both, left" indent at first invocation + of LIST + #STORED_BR_INDENT Current "both, right" indent at first invocation + of LIST + #STORED_HL_INDENT Current hanging indent at first invocation + of LIST + #STORED_T_INDENT Current temporary indent at first invocation + of LIST + #STR_LENGTH Holds string length derived from .length request + tbl Are we in a tbl? (boolean) + #T_INDENT Value of temporary indent + #T_MARGIN Top margin + #TAB_ACTIVE Are we in a tab? (boolean) + #TAB_NUMBER Tab number given to TAB_SET + #TAB_LENGTH Tab length given to TAB_SET + #TAB_OFFSET Tab indent given to TAB_SET + #TEXT_WIDTH Width of string to underscore + #TN Was TN (or \*[T+] called? (boolean) + #TOP Set to 1 in T_MARGIN, DO_T_MARGIN and ALD; tells + the first LS or AUTOLEAD on a page to maintain + the baseline position prior to the LS call + #TOP_BASELINE_ADJ Amount by which to adjust the baseline position + of the first line on the page if an LS or AUTOLEAD + request differs from the lead current at the end of + the previous page + #TOTAL_LISTS Total number of lists in a nest + #UNDERSCORE_WEIGHT Weight of underscores + #UNDERSCORE_WEIGHT_ADJ UNDERSCORE_WEIGHT/2 + #USER_SET_L_LENGTH Did user invoke LL? (boolean) + #USER_SET_TITLE_ITEM Did user invoke TOC_TITLE_ENTRY? + #WEIGHT Weight given to #RULE_WEIGHT + #WEIGHT_ADJ RULE_WEIGHT/2 + u Horiz position of start of underscore + ++++STRINGS+++ + + $ARG String holding substrings derived from .substring + request + $COND_PERCENT Percentage by which to pseudo-condense type + $COLOR_SCHEME Color scheme used in NEWCOLOR + $<colorname>_FILL XCOLOR "alias" with _FILL attached; used to determine if + the alias exists when the alias is passed to DBX SOLID + or DCL SOLID + $CURRENT_QUAD Restores current quad value in RULE + $CURRENT_TAB Current tab number + $DC_ADJUST +|- # of points to subtract from dropcap + $DC_FAM Drop cap family + $DC_FT Drop cap font + $DROPCAP The dropcap letter + $ENUMERATOR<n> String enumerator for depth <n> in lists + $ENUMERATOR_TYPE<n> Type of enumerator used in LIST<n> + $EW Value passed to EW + $EXT_PERCENT Percentage by which to pseudo-extend type + $FAMILY Family + $FAMILY_FOR_PAD Used to ensure that the family in effect prior + to PAD is restored at the start of every + iteration of $PAD_STRING + $FONT Font + $FONT_FOR_PAD Used to ensure that the font in effect prior + to PAD is restored at the start of every + iteration of $PAD_STRING + $PAD_MARKER Character to mark off padding in PAD + $PAD_STRING Arg passed to PAD + $PREFIX<n> Prefix for enumerator of LIST<n> + $QUAD_VALUE Quad value (left, right, centre, justify) + $QUOTE0 Open quotation marks + $QUOTE1 Close quotation marks + $RESTORE_COND Restores the pseudo-condense value in effect + prior to DROPCAP + $RESTORE_EXT Restores the pseudo-extend value in effect + prior to DROPCAP + $RESTORE_FAM Used to restore the family in effect + prior to DROPCAP + $RESTORE_FT Used to restore the font/fontstyle in effect + prior to DROPCAP + $RESTORE_PT_SIZE Used to restore the point size of normal + running text after a dropcap + $RESTORE_QUAD_VALUE Quad value for use in restoring L, R, C, J + (after tabs) + $RESTORE_SQ The smartquoting string last passed to SMARTQUOTES + $RULE_GAP Distance between underscore rules + $RW Value passed to RW + $SAVED_STYLE Current style, if there is one (used in FAMILY) + $SAVED_UNDERSCORE_GAP Temporarily holds string in $UNDERSCORE_GAP + $SEPARATOR<n> Separator for depth <n> in lists + $SS_VAR Holds + or - sentence space value + $ST<n>_FILL Always QUAD if QUAD passed to ST <n> + ST\n[#LOOP] Used to initialize string tab markers (1-19) + ST\n[#LOOP]X Used to initialize string tab markers (1-19) + $ST<n>_QUAD_DIR Quad direction supplied to ST for <n> + $SUP_LOWER Vertical displacement amount of superscripts + $SUP_RAISE Vertical displacement amount of superscripts + $SUP_RAISE_AMOUNT Argument passed to SUPERSCRIPT_RAISE_AMOUNT + $TAB_NUMBER Argument passed to TAB macro to call TAB# macro + created in TAB_SET + $UNDERSCORE_GAP Distance between text and underscore rule + $WS_CONSTANT 12; used to hold groff default wordspace + $WS Holds WS value; concatenation of WS_CONSTANT and + WS_VAR + $WS_VAR + or - value to add to $WS_CONSTANT + BLACK Pre-defined black color + black Pre-defined black color + WHITE Pre-defined white color + white Pre-defined white color + ++++ALIASES+++ + + ALIAS als + ALIASN aln + BR br + CENTRE CENTER + COLOUR COLOR + COMMENT SILENT + CONDENSE CONDENSE_OR_EXTEND + EXTEND CONDENSE_OR_EXTEND + FAM FAMILY + FT FONT + HYPHENATE HY + HYPHENATION HY + INCLUDE so + LIG LIGATURES + LL LINE_LENGTH + MAC de + NEW_PAGE bp + NEWCOLOUR NEWCOLOR + NEWPAGE NEW_PAGE + PAGELENGTH PAGE_LENGTH + PAGE_LENGTH pl + PAGEWIDTH PAGE_WIDTH + SPREAD brp + SP sp + STRING ds + TABSET TAB_SET + TB TAB + TI IT + UNDERSCORE_2 UNDERSCORE2 + XCOLOUR XCOLOR + ++++ALIASES FOR NUMBER REGISTERS+++ + + #DIVER_DEPTH dn -- diversion depth + #DIVER_WIDTH dl -- diversion width + #INDENT .i -- value of current indent + #LEAD .v -- line space (.vs, not .ls) + #L_LENGTH .l -- line length + #NUM_ARGS .$ -- number of arguments passed to a macro + #PAGE_LENGTH .p -- page length + #PT_SIZE .ps -- current point size (fractional) in units + #TRAP_DISTANCE .t -- distance to next trap + ++++INLINE ESCAPES+++ + + ALD<n> Move down inline by <n> (between .25 and 12.75) + B Inline equivalent to .EL + BCK Inline backward horizontal movement + BD Bold font + BDI Bold italic font + BLACK Color + black color + BOLDER Pseudo-bold on + BOLDERX Pseudo-bold off + BP Back points (horizontal movement) + BP<n> Back points by <n> (between .25 and 12.75) + BU Back units (inline pairwise kerning) + BU<n> Back units by <n> (between 1 and 36) + COND Pseudo-condense type + COND_FOR_SUP Pseudo-condense string for use with superscripts + (called with CONDSUP) + COND_FOR_SUP Pseudo-extend string for use with superscripts (called + with EXTSUP) + CONDSUP Pseudo-condensed superscript (using value set with + CONDENSE) + CONDSUPX Pseudo-condensed superscript off + CONDX Pseudo-condense off + DOWN Inline downward vertical movement + EN-MARK Inline escape to indicate the beginning of a + range of lines used to identify an endnote + EXT Pseudo-extend type + EXTX Pseudo-extend off + EXTSUP Pseudo-extended superscript + EXTSUPX Pseudo-extended superscript off + FN-MARK Inline escape to indicate the beginning of a + range of lines used to identify a footnote + FP<n> Forward points by <n> (between .25 and 12.75) + FP Forward points (horizontal movement) + FU Forward units (inline pairwise kerning) + FU<n> Forward units by <n> (between 1 and 36) + FWD Inline forward horizontal movement + PREV Return to previous font in effect + RLD<n> Move up, inline, by <n> (between .25 and 12.75) + ROM Roman (medium) font + S Same \s + SLANT Slant (pseudo-italic on + SLANTX Slant off + ST<n> String tab end marker + ST<n> String tab start marker + SUP Superscript + SUPX Superscript off + TB+ Move to next tab number (n+1) without advancing on the page + UP Inline upward vertical movement + WHITE Color + white Color + ++++SPECIAL CHARACTERS+++ + + FOOT The foot character \(fm + INCH The inch character \(fm\(fm + LEADER Deposit leader to end of current LL or TAB + RULE Draw a rule to the full measure of the current line or + tab length +DOCUMENT PROCESSING ++++MACROS+++ +*Document info (reference macros) + AUTHOR Author + CHAPTER Chapter number + CHAPTER_TITLE Chapter title + COPYRIGHT Copyright info (covers only) + DOCTITLE Overall doc title (for collated docs) + DRAFT Draft number + MISC Misc info (covers only) + REVISION Revision number + SUBTITLE Doc subtitle + TITLE Doc title + +*Covers + COVER What goes on cover + COVERS Whether covers get printed (boolean) + COVER_ADVANCE Set vertical start position of cover material + COVER_LEAD Overall leading of covers + COVERTITLE User-defined cover title string + DOC_COVER What goes on doc cover + DOC_COVERS Whether doc covers get printed + DOC_COVER_ADVANCE Set vertical start position of doc cover material + DOC_COVER_LEAD Overall leading of doc covers + DOC_COVERTITLE User-defined doc cover title string + +*Document style + COPYSTYLE Output style (DRAFT or FINAL) + DEFAULTS In START, sets defaults + DOCTYPE Kind of doc (DEFAULT, CHAPTER, NAMED, LETTER) + PAGENUMBER Page number that appears on 1st page of doc + PAPER Paper size (LETTER, LEGAL, A4) + PRINTSTYLE Print style (TYPEWRITE or TYPESET) + NUMBER_LINES Number output lines in the left margin + +*Document tags and macros + ADD_SPACE Special macro to add space to the top of a pages after + page 1; must be preceded by NEWPAGE + BIBLIOGRAPHY Begin a bibliography page + BIBLIOGRAPHY_TYPE LIST or PLAIN + BLOCKQUOTE Block-indented, quoted text + COL_BREAK Breaks and spreads line before invocation; moves to + next column on page or 1st col of next page. An + alias of COL_NEXT. + COL_NEXT Moves to next column on page or 1st col of next page + ENDNOTE Endnote + ENDNOTE_REFS Send REFs to endnotes + ENDNOTES Output endnotes + EPIGRAPH Epigraph before 1st para + EQ/EN eqn block + FINIS Prints --END-- + FLOAT Keep material together as a block; defer output + to following page if not enough room to print + FOOTNOTE Collects footnotes in text for printing at bottom + of page + FOOTNOTE_REFS Send REFs to footnotes + HEAD Section title (main heads) + HYPHENATE_REFS Turn on/off hyphenation of REF references + ITEM Begin a list item + LINEBREAK Break between narrative sections + LIST Initialize a list + MN Margin note + MN_INIT Initialize parameters for margin notes + NUMBER_LINES Number text lines + NUMBER_BLOCKQUOTE_LINES Number blockquote lines + NUMBER_QUOTE_LINES Number quote lines + PAD_LIST_DIGITS Leave space for two-numeral digit enumerators + in a list + PARAHEAD Paragraph head + PP Paragraph + QUOTE Poetic or line for line quotes + REF Wrapper around FOOTNOTE or ENDNOTE, depending + on FOOTNOTE_REFS or ENDNOTE_REFS + REF( Begin embedded reference, parens + REF) End embedded reference, parens + REF[ Begin embedded reference, square brackets + REF] End embedded reference, square brackets + REF{ Begin embedded reference, braces + REF} End embedded reference, braces + REF_INDENT Amount of 2nd line indent of references for + footnote, endnote or bibliography refs + RESET_LIST Reset digit or alpha list enumerator + SHIFT_LIST Move a list over to the right + START Sets doc defaults and prints info collected + with doc info macros + SUBHEAD Subheads + SUBSUBHEAD Subsubheads + TH Running tbl header + TS/TE Begin/end a tbl block + +*Headers/footers + DO_FOOTER Prints footer (after footnote processing, if any) + FOOTER_ON_FIRST_PAGE Print footer on first page? (boolean) + FOOTER Trap-invoked footer macro + HEADER Trap-invoked header macro + PAGINATE Turns page numbering on or off (doc default=on) + PAGINATE_TOC Turns pagination of toc on or off (default=on) + RECTO_VERSO Enables switch HEADER_LEFT and HEADER_RIGHT on + alternate pages + +*Control macros +-General- + ALWAYS_FULLSPACE_QUOTES Fullspace quotes instead of default + 1/2 spacing them. + ATTRIBUTE_STRING What to print before author (default is "by") + CHAPTER_STRING What to print whenever the word "chapter" + is required + COLUMNS Print in columns + DOC_FAMILY Overall doc family + DOCHEADER Print doc header? + DOCHEADER_ADVANCE Start position of docheader (relative to top + of page) + DOCHEADER_LEAD +|- value applied to #DOC_LEAD to in/decrease + leading of doc header + DOC_LEAD_ADJUST Adjust #DOC_LEAD to fill page to #B_MARGIN + DOC_LEAD Overall doc leading + DOC_LEFT_MARGIN Doc left margin + DOC_LINE_LENGTH Doc line length + DOC_PT_SIZE Overall doc point size + DOC_RIGHT_MARGIN Doc right margin + DOC_TITLE Overall doc title that gets printed in + headers/footers (mostly for use with collated + docs where each doc is an article with a + different title + DRAFT_STRING What to print whenever the word "draft" is + required + DRAFT_WITH_PAGENUMBER Attach draft/revision info to page number + (instead of putting it HEADER centre) + REVISION_STRING What to print whenever the word "revision" + is required + +-Covers- + COVER_ADVANCE Vertical place on page to start outputting + cover material + COVER_LEAD Lead in/decrease for cover pages + COVERS_COUNT_PAGES Whether to include cover pages in pagination scheme + DOC_COVER_ADVANCE Vertical place on page to start outputting + doc cover material + DOC_COVER_LEAD Lead in/decrease for doc cover pages + DOC_COVERS_COUNT_PAGES Whether to include doc cover pages in pagination + scheme + +-Epigraphs and finis- + EPIGRAPH_AUTOLEAD Autolead value for epigraphs + EPIGRAPH_INDENT Value by which to multiply PP_INDENT for + block epigraphs + FINIS_STRING What to print when FINIS is invoked + FINIS_STRING_CAPS Whether to capitalize the finis string + +-eqn- + EQ_INDENT Indent value if 'EQ I' + +-Footnotes- + FOOTNOTE_AUTOLEAD Autolead to use in footnotes + FOOTNOTE_LINENUMBER_BRACKETS Brackets for footnote linenumbers + FOOTNOTE_LINENUMBER_SEPARATOR Separator for footnote linenumbers + FOOTNOTE_MARKERS Turns footnote markers on or off + FOOTNOTE_MARKER_STYLE STAR or NUMBER; default=STAR + FOOTNOTE_RULE_ADJ # of points to raise footnote rule from its + baseline + FOOTNOTE_RULE_LENGTH Length of footnote separator rule + FOOTNOTE_RULE Turns printing of fn separator rule on or off; + default is on + FOOTNOTE_SPACING Post footnote item spacing + FOOTNOTES_RUN_ON Run footnotes on (line numbering mode only) + RESET_FOOTNOTE_NUMBER Reset fn# to 1, or, if arg PAGE, reset + automatically to 1 on every page + RUNON_WARNING Utility macro; warns if FOOTNOTES_RUN_ON + was called when fn marker style is STAR or + NUMBER + +-Endnotes- + ENDNOTE_LEAD Leading for endnotes page + ENDNOTE_LINENUMBER_BRACKETS Brackets around line numbers identifying + endnotes and text + ENDNOTE_LINENUMBER_GAP Amount of space to leave between line + ENDNOTE_LINENUMBER_SEPARATOR Separator between line numbers identifying + endnotes and the endnote item text + endnotes and text + ENDNOTE_MARKER_STYLE NUMBER or LINE + ENDNOTE_NUMBERS_ALIGN_RIGHT Hang endnote numbers and align right + ENDNOTE_NUMBERS_ALIGN_LEFT Don't hang endnote numbers and align left + ENDNOTE_PARA_INDENT First line indent of paras in multi-para + endnotes + ENDNOTE_PARA_SPACE Whether to space paras in multi-para endnotes + ENDNOTE_PT_SIZE Base point size for endnotes page + FOOTNOTE_SPACING Post endnotenote item spacing + ENDNOTE_STRING Endnotes page head + ENDNOTE_STRING_ADVANCE Distance of title string "ENDNOTES" from top + edge of page + ENDNOTE_STRING_CAPS Capitalize the endnotes string + ENDNOTE_STRING_UNDERLINE Underscoring of endnotes page head + ENDNOTE_TITLE Endnotes identifying title + ENDNOTE_TITLE_SPACE Distance from top of page to endnotest title + ENDNOTE_TITLE_UNDERLINE Underscoring of endnotes identifying title + ENDNOTES_ALLOWS_HEADERS Page headers on endnotes pages? (boolean) + ENDNOTES_FIRST_PAGENUMBER Page number to appear on page 1 of endnotes + pages + ENDNOTES_HDRFTR_CENTER Print header/footer centre string on endnotes + pages? + ENDNOTES_HEADER_CENTER Print header centre string on endnotes pages? + ENDNOTES_FOOTER_CENTER Print footer centre string on endnotes pages? + ENDNOTES_NO_COLUMNS Turn columnar mode off for endnotes pages + ENDNOTES_NO_FIRST_PAGENUM Don't print a pagenumber on page 1 of + endnotes. + ENDNOTES_PAGENUM_STYLE Set numbering style for endnotes pages page + numbers + SINGLESPACE_ENDNOTES Single space TYPEWRITE endnotes + +-Bibliographies- + BIBLIOGRAPHY_ALLOWS_HEADERS Allow headers on bib pages + BIBLIOGRAPHY_FIRST_PAGENUMBER Starting page number for bibliographies + BIBLIOGRAPHY_HDRFTR_CENTER Header/footer center string for bib pages + BIBLIOGRAPHY_LEAD Base lead of bib pages + BIBLIOGRAPHY_NO_COLUMNS De-columnize bibliographies + BIBLIOGRAPHY_NO_FIRST_PAGENUM Don't print a page number on the first + page of bibliographies + BIBLIOGRAPHY_PAGENUM_STYLE Format for bib pages page numbering + BIBLIOGRAPHY_PT_SIZE Base point size for bib pages + BIBLIOGRAPHY_SPACING Post bib entry space + BIBLIOGRAPHY_STRING String for bib title + BIBLIOGRAPHY_STRING_ADVANCE Distance of title string "BIBLIOGRAPHY" from + top edge of page + BIBLIOGRAPHY_STRING_CAPS Capitalize bib title string + BIBLIOGRAPHY_STRING_UNDERLINE Underscore bib title string + SINGLESPACE_BIBLIOGRAPHY Singlespace bibs if PRINTSTYLE TYPEWRITE + +-Headers and footers- + FOOTER_COLOR Footer color + FOOTER_GAP Distance between running text and footer + FOOTER_MARGIN Distance from footer to bottom of page + FOOTERS Turns footers on or off + HDRFTR_CENTER String to go in centre part of header/footer; + default doctype + HDRFTR_CENTER_CAPS Centre part of header/footer in caps? (boolean) + HDRFTR_CENTER_PAD Pad hdrftr CENTER left or right by specified + amount + HDRFTR_GAP Distance from header/footer to running text + HDRFTR_LEFT_CAPS Left part of header/footer in caps? (boolean) + HDRFTR_LEFT String to go in left part of header/footer; + default is AUTHOR_1 + HDRFTR_LEFT The header/footer left string + HDRFTR_MARGIN Distance from top of page to header + HDRFTR_PLAIN Header/footer fam/ft/ps all same as running + text + HDRFTR_RECTO User-defined, single string recto + header/footer + HDRFTR_RIGHT_CAPS Right part of header/footer in caps? (boolean) + HDRFTR_RIGHT The header/footer right string + HDRFTR_RULE_GAP Space between header/footer and header/footer + rule + HDRFTR_RULE_INTERNAL Prints the header/footer rule + HDRFTR_RULE Turns header/footer rule on or off + When invoked internally, prints the rule. + HDRFTR_VERSO User-defined, single string verso + header/footer + HEADERS Turns headers on or off + HEADER_GAP Space between header and running text + HEADER_MARGIN Space from top of page to header + HEADERS_AND_FOOTERS Enables and permits the creation of + headers and footers that appear on the + same page + SWITCH_HDRFTR Switch HDRFTR_LEFT and HDRFTR_RIGHT + +-Page numbering- + PAGENUM_HYPHENS Turns on/off hyphens surrounding page numbers + PAGENUM_ON_FIRST_PAGE Print page number on first page when footers + are on (boolean) + PAGENUM_POS Controls placement of page numbers; + default=bottom/centred + PAGENUM_SIZE How much to in/decrease point size of page + numbers + PAGENUM_STYLE Page # in roman, Arabic, or alphabetic + RESTORE_PAGINATION Restore pagination after outputting non- + paginated endnotes. + SUSPEND_PAGINATION Suspend pagination prior to outputting + endnotes + +-Heads- + HEAD_CAPS Print section titles in caps? (boolean) + HEAD_SPACE Give HEADs 2 line-spaces before. If OFF, + only 1. Default is on. + HEAD_UNDERLINE Underline section titles? (boolean) + NUMBER_HEADS Print head numbers + RESET_HEAD_NUMBER Reset head number + HEAD_BASELINE_ADJUST Amount to raise head above baseline + +-Subheads- + NUMBER_SUBHEADS Print subhead numbers + RESET_SUBHEAD_NUMBER Reset subhead number + SUBHEAD_BASELINE_ADJUST Amount to raise subhead above baseline + +-Subsubheads- + NUMBER_SUBSUBHEADS Print subhead numbers + RESET_SUBSUBHEAD_NUMBER Reset subhead number + SUBSUBHEAD_BASELINE_ADJUST Amount to raise subhead above baseline + +-Para heads- + NUMBER_PARAHEADS Print parahead numbers + PARAHEAD_INDENT How much to indent paraheads + RESET_PARAHEAD_NUMBER Reset parahead number + + PREFIX_CH_NUM_WARNING Macro to abort PREFIX_CHAPTER_NUMBER + with a warning if the arg to CHAPTER isn't + a digit, and user hasn't supplied a digit + to PREFIX_CHAPTER_NUMBER + PREFIX_CHAPTER_NUMBER Prefix the chapter number to numbered + heads, subheads and paraheads +-Paragraphs- + INDENT_FIRST_PARAS Indent 1st paras? (doc default=not indented) + PARA_INDENT Size of para indent + PARA_SPACE Put a line space before paras + PP_FONT Overall doc font + +-Quotes- + Q_FITS Utility macro for DO_QUOTE + Q_NOFIT Utility macro for DO_QUOTE + QUOTE_AUTOLEAD Leading of (block)quotes + +-Line/section breaks- + LINEBREAK_CHAR Linebreak character, iterations and positioning + +-Printstyle TYPEWRITE- + ITALIC_MEANS_ITALIC For TYPEWRITE; render .FT I in italic. + SLANT_MEANS_SLANT In TYPEWRITE, render \*[SLANT] as slant + UNDERLINE_ITALIC In TYPEWRITE, render .FT I as underlined + UNDERLINE_QUOTES In TYPEWRITE, underline quotes? (boolean) + UNDERLINE_SLANT In TYPEWRITE, render \*[SLANT] as underlined + +-Table of contents- + TOC_APPENDS_AUTHORS Appends author(s) to toc doc title entries + TOC_LEAD Leading of toc pages + TOC_PADDING Number of placeholders for toc entries page + numbers + TOC_HEAD_INDENT Indent of toc head entries + TOC_HEADER_STRING TOC header string (default=Contents) + TOC_PAGENUM_STYLE Page numbering style (hdrftr nums) of + toc pages + TOC_RV_SWITCH Switch L/R margins of toc pages + TOC_PARAHEAD_INDENT Indent of toc parahead entries + TOC_SUBHEAD_INDENT Indent of toc subhead entries + TOC_TITLE_ENTRY User supplied toc doc title entry + TOC_TITLE_INDENT Indent of toc doc title entries + +*Aliases for header/footer control macros + HEADER_SIZE HDRFTR_SIZE + HEADER_RIGHT_PS HDRFTR_RIGHT_SIZE + HEADER_RIGHT_SIZE HDRFTR_RIGHT_SIZE + HEADER_RIGHT_FAM HDRFTR_RIGHT_FAMILY + HEADER_RIGHT_FAMILY HDRFTR_RIGHT_FAMILY + HEADER_RIGHT_FONT HDRFTR_RIGHT_FONT + HEADER_RIGHT_FT HDRFTR_RIGHT_FONT + HEADER_LEFT_PS HDRFTR_LEFT_SIZE + HEADER_LEFT_SIZE HDRFTR_LEFT_SIZE + HEADER_LEFT_FAM HDRFTR_LEFT_FAMILY + HEADER_LEFT_FAMILY HDRFTR_LEFT_FAMILY + HEADER_LEFT_FONT HDRFTR_LEFT_FONT + HEADER_LEFT_FT HDRFTR_LEFT_FONT + HEADER_CENTRE_PS HDRFTR_CENTER_SIZE + HEADER_CENTRE_SIZE HDRFTR_CENTER_SIZE + HEADER_FAM HDRFTR_FAMILY + HEADER_FAMILY HDRFTR_FAMILY + HEADER_CENTRE_FAM HDRFTR_CENTER_FAMILY + HEADER_CENTRE_FAMILY HDRFTR_CENTER_FAMILY + HEADER_CENTRE_FONT HDRFTR_CENTER_FONT + HEADER_CENTRE_FT HDRFTR_CENTER_FONT + HEADER_CENTER_PS HDRFTR_CENTER_SIZE + HEADER_CENTER_SIZE HDRFTR_CENTER_SIZE + HEADER_CENTER_FAM HDRFTR_CENTER_FAMILY + HEADER_CENTER_FAMILY HDRFTR_CENTER_FAMILY + HEADER_CENTER_FONT HDRFTR_CENTER_FONT + HEADER_CENTER_FT HDRFTR_CENTER_FONT + FOOTER_SIZE HDRFTR_SIZE + FOOTER_RIGHT_PS HDRFTR_RIGHT_SIZE + FOOTER_RIGHT_SIZE HDRFTR_RIGHT_SIZE + FOOTER_RIGHT_FAM HDRFTR_RIGHT_FAMILY + FOOTER_RIGHT_FAMILY HDRFTR_RIGHT_FAMILY + FOOTER_RIGHT_FONT HDRFTR_RIGHT_FONT + FOOTER_RIGHT_FT HDRFTR_RIGHT_FONT + FOOTER_LEFT_PS HDRFTR_LEFT_SIZE + FOOTER_LEFT_SIZE HDRFTR_LEFT_SIZE + FOOTER_LEFT_FAM HDRFTR_LEFT_FAMILY + FOOTER_LEFT_FAMILY HDRFTR_LEFT_FAMILY + FOOTER_LEFT_FONT HDRFTR_LEFT_FONT + FOOTER_LEFT_FT HDRFTR_LEFT_FONT + FOOTER_CENTRE_PS HDRFTR_CENTER_SIZE + FOOTER_CENTRE_SIZE HDRFTR_CENTER_SIZE + FOOTER_FAM HDRFTR_FAMILY + FOOTER_FAMILY HDRFTR_FAMILY + FOOTER_CENTRE_FAM HDRFTR_CENTER_FAMILY + FOOTER_CENTRE_FAMILY HDRFTR_CENTER_FAMILY + FOOTER_CENTRE_FT HDRFTR_CENTER_FONT + FOOTER_CENTER_PS HDRFTR_CENTER_SIZE + FOOTER_CENTER_SIZE HDRFTR_CENTER_SIZE + FOOTER_CENTER_FAM HDRFTR_CENTER_FAMILY + FOOTER_CENTER_FAMILY HDRFTR_CENTER_FAMILY + FOOTER_CENTER_FONT HDRFTR_CENTER_FONT + FOOTER_CENTER_FT HDRFTR_CENTER_FONT + ++++LETTER MACROS+++ + + CLOSING Closing (i.e. Yours truly,) + CLOSING_INDENT Left indent of CLOSING + DATE Date for letters + FROM Addresser's name and address + GREETING Full salutation (e.g. Dear John Smith,) + NO_SUITE Remove suite page numbers from bottom of letter pages + SIGNATURE_SPACE Amount of room to leave for signature + TO Addressee's name and address + ALL_DONE .em (the "end macro") for letters + ++++SUPPORT+++ + + CHECK_INDENT Applies indents to doc elements inside ev's + (head, subhead, etc) + CLEANUP_DEFAULTS Removes selected rregisters and strings + from DEFAULTS after START + DO_COVER Formats and outputs covers + DO_DOC_COVER Formats and outputs doc covers + D0_QUOTE Outputs quotes with space adjustments before + and after + DIVER_FN_1_PRE -+ + DIVER_FN_2_PRE | Manage footnotes called inside diversions + | QUOTE, BLOCKQUOTE and EPIGRAPH + DIVER_FN_2_POST -+ + DIVERT_FN_LEFTOVER Diverts excess fn stored in FN_OVERFLOW into + FOOTNOTE + DIVERT_FN_OVERFLOW Diverts excess fn stored in FN_OVERFLOW when + FN_DEFER into FOOTNOTE + DO_EPIGRAPH Outputs epigraphs with space adjustments before + and after + FN_OVERFLOW_TRAP Fixed at B_MARGIN; if footnotes run longer than + B_MARGIN, diverts excess into FN_OVERFLOW + GET_ROMAN_INDENT Figures out amount of space to reserve + for roman numerals in lists + HDRFTR_RULE Prints rule under header or over footer + MN_OVERFLOW_TRAP Trap-invoked macro to collect margin note + overflows + NO_SHIM Disable SHIM + PRINT_FOOTNOTE_RULE An alias of PRINT_FOOTNOTE; prints footnote + separator rule + PRINT_HDRFTR Prints header/footer (trap invoked) + PRINT_PAGE_NUMBER Invoked in HEADER or FOOTER + PRINT_USERDEF_HDRFTR Prints user defined, single string recto/verso + header/footer + PROCESS_SHIM Calculates #SHIM when \n[.d] is lower on the + page than #T_MARGIN + PROCESS_FN_IN_DIVER Processes footnotes gathered in a diversion (called + at page/column breaks) + REMOVE_INDENT Removes indents set with CHECK_INDENT + Q_FITS Handles spacing of quotes when quote fits on the page + Q_NOFIT Handles spacing of quotes when quote does not fit on + the page + QUIT_LISTS Exit lists cleanly and completely + SET_LIST_INDENT Restore indent of a prev. level of list + SHIM Advance to next "valid" baseline + TBL*CLEANUP Remove selected registers and strings created + by TS/TH/TE + TBL*GET_QUAD Establish quad of tbl caption + tbl*float-warning If tbl in a float exceeds page limits + tbl*print-header Administrivia for printing tbl headers + tbl@top-hook Trap-invoked (HEADER); prints running tbl header + and moves FOOTER/FN_OVERFLOW_TRAP_POS traps + to accommodate tbl + TERMINATE .em that ensures deferred footnotes get output + on final pages + TRAPS Sets hdrftr traps; optionally adjusts #DOC_LEAD + to fill page to #B_MARGIN + TYPEWRITER Sets family (C), font (R) and point size (12) + for PRINTSTYLE TYPEWRITE + VFP_CHECK Trap-sprung macro, 1 valid baseline higher than + where FOOTER will be sprung; checks whether + there is, in fact, just enough room for + another line of running text to be added to + the page without jamming footnotes too close + to running text. + ++++DIVERSIONS+++ + + B_QUOTE Block (indented) quote text + CLOSING_TEXT Closing (i.e. Yours truly,) + EPI_TEXT Epigraph text + END_NOTES Endnotes text + FLOAT*DIV Float content + FN_IN_DIVER Footnotes gathered from inside a diversion + FN_OVERFLOW Excess footnotes when B_MARGIN is reached + FOOTNOTES Text of footnotes + GREETING Full salutation (e.g. Dear John Smith,) + LETTERHEAD<n> Date, addresser, addressee or greeting; + <n> is from 1 to 4, supplied by #FIELD + P_QUOTE Line for line (poetic) quote text + RUNON_FOOTNOTES Special diversion for run-on footnotes + RUNON_FN_IN_DIVER Special diversion for run-on footnotes inside + (block)quotes + tbl*header-div Running tbl header + TOC_ENTRIES TOC entries + ++++NUMBER REGISTERS+++ + + #ADJ_BIB_LEAD Adjust BIB_LEAD? (boolean) + #ADJ_DOC_LEAD Adjust DOC_LEAD? (boolean) + #ADJ_EN_LEAD Adjust EN_LEAD? (boolean) + #ADJ_TOC_LEAD Adjust TOC_LEAD? (boolean) + #ADVANCE_FROM_TOP Distance from page top to start of + running text if no docheader + #ARG_NUM Keeps track of number of args passed to a + macro + #ARGS_TO_LIST Was LIST passed some args? (boolean) + #ATTRIBUTE_COLOR Colorize attribute string? (boolean) + #AUTHOR_<n> Strings passed to AUTHOR + #AUTHOR_COLOR Colorize author(s)? (boolean) + #AUTHOR_COVER_NUM Incrementing register used in defining + $AUTHOR_COVER_<n> strings + #AUTHOR_DOCCOVER_NUM Incrementing register used in defining + $AUTHOR_COVER_<n> strings + #AUTHOR_NUM Keeps track of user-defined string + AUTHOR_<n> in AUTHOR + #AUTHORS Equals final value of AUTHOR_NUM; + used for authors in doc header + #BASELINE_MARK In PP, the vertical position on the page + (when paragraph spacing is on) after a + quote or blockquote has been output and + the post-quote space has been added. + #BMARG Position of unvarying bottom margin + during doc processing; required for + collecting footnotes inside diversions + #BIB_ALLOWS_HEADERS Put headers on bib pages? (boolean) + #BIB_ALLOWS_HEADERS_ALL Put headers on all bib pages? (boolean) + #BIB_FIRST_PAGE Tells PRINT_PAGE_NUMBER about bibliography + first page number + #BIB_FIRST_PN Starting pagenumber for bibliographies + #BIB_HDRFTR_CENTER Put a center string in bib page headers? + (boolean) + #BIB_LEAD Bibliography lead, expressed in points + #BIB_LIST Output bibs in list style? (boolean) + #BIB_NO_COLS De-columnize bibliographies? (boolean) + #BIB_NO_FIRST_PN Put a page number on the first page of + bibliographies? (boolean) + #BIB_SINGLESPACE Single-space TYPEWRITE bibliographies? (boolean) + #BIB_SPACE Post item space for bibliography pages + #BIB_STRING_ADVANCE Vertical position of "BIBLIOGRAPHY" string + (relative to the top edge of the page) + #BIB_STRING_CAPS Capitalize bib title? (boolean) + #BIB_STRING_UNDERLINE Underscore bib title? 0=no; 1=yes; 2=double + #BIB_STRING_UNDERLINE_WEIGHT Underline weight in units + #BIB_STRING_UNDERLINE_WEIGHT_ADJ Underline weight/2 + #BIB_PS Base point size for bibliography pages expressed + in points + #BIBLIOGRAPHY Are we doing a bib page? (boolean) + #BQ_AUTOLEAD Register created by BLOCKQUOTE_AUTOLEAD + #BQ_LEAD Leading of blockquotes + #BQUOTE_COLOR Colorize blockquotes? (boolean) + #BQUOTE_LN Number blockquotes? (boolean) + #CAP_HEIGHT_ADJUST Tallest cap height of strings LEFT, CENTER, + and RIGHT in footers; used to place rule + over footer + #CAPS_WAS_ON In HDRFTR, to re-enable running text CAPS + (boolean) + #CENTER_CAP_HEIGHT Cap height of CENTER string in + headers/footers + #CH_NUM The chapter number obtained by + PREFIX_CHAPTER_NUMBER + #CHAPTER_CALLED Has CHAPTER been invoked? (boolean); used + by PREFIX_CHAPTER_NUMBER to see whether + to try to get the chapter number from + the arg passed to CHAPTER + #CHAPTER_TITLE_NUM Incrementing register used to define strings + $CHAPTER_TITLE_<n> + #CHAPTER_TITLE_COLOR Colorize chapter title? (boolean) + #CLOSING Is there a closing (for letters)? (boolean) + #CODE_COLOR Colorize CODE? (boolean) + #CODE_SIZE_ADJ Percentage by which to scale CODE font + #COL_L_LENGTH Line length of columns + #COL_<n>_L_MARGIN Left margin of column <n> + #COL_NEXT Was COL_NEXT invoked? (boolean; used in + FOOTER) + #COL_NUM Incrementing counter of num of columns; + for use with #COL_<n>_L_MARGIN + #COL_TOTAL #COL_L_LENGTH + #GUTTER; used to calculate + #COL_<n>_L_MARGIN + #COLLATE Are we performing a COLLATE? (boolean) + #COLLATED_DOC If 1, instructs TOC that this is a collated + doc + #COLUMNS Are columns turned on? (boolean) + #COLUMNS_WERE_ON Stores columnar state prior to outputting + endnotes in no-columns mode + #COPY_STYLE 1=draft, 2=final + #COUNTERS_RESET Tells FOOTNOTE if fn counters have + been reset because of footnotes gathered + inside a diversion + #COVER Print a COVER? (boolean) + #COVER_ATTRIBUTE_COLOR Colorize cover attribution string? (boolean) + #COVER_AUTHOR Put AUTHOR(s) on COVER? (boolean) + #COVER_AUTHOR_COLOR Colorize cover author(s)? (boolean) + #COVER_BLANKPAGE Output blankpage after COVER? (boolean) + #COVER_COLOR Colorize COVER? (boolean) + #COVER_COPYRIGHT Put copyright on COVER? (boolean) + #COVER_COPYRIGHT_COLOR Colorize cover copyright line? (boolean) + #COVER_DOCTYPE Put doctype on COVER? (boolean) + #COVER_DOCTYPE_COLOR Colorize cover doctype? (boolean) + #COVER_END Are we ending a COVER? (boolean) + #COVER_LEAD Cover leading + #COVER_MISC Put misc on COVER? (boolean) + #COVER_MISC_COLOR Colorize cover misc line? (boolean) + #COVER_RULE_WEIGHT Doctype underline weight on COVER + #COVER_RULE_WEIGHT_ADJ COVER_RULE_WEIGHT/2 + #COVER_START_POS Vertical starting pos of cover material + #COVER_SUBTITLE Put subtitle on COVER? (boolean) + #COVER_TITLE Put title on COVER? (boolean) + #COVER_TITLE_NUM Number of cover title items + #COVER_TITLE_COLOR Colorize cover title? (boolean) + #COVER_SUBTITLE_COLOR Colorize cover subtitle? (boolean) + #COVER_UNDERLINE Underline doctype on COVER? (boolean) + #COVER_UNDERLINE_WEIGHT Doctype underline weight on COVER + #COVER_UNDERLINE_WEIGHT_ADJ COVER_UNDERLINE_WEIGHT/2 + #CURRENT_V_POS \n[.d] ; used in SHIM + #COVERS Print covers? (boolean) + #COVERS_COUNT Include COVER in pagination scheme? (boolean) + #COVERS_OFF Don't print COVERs (boolean) + #DATE_FIRST Was .DATE invoked as first letter + header after .START? (boolean) + dc "mark" register for document columns + DD Vert. space before and after eqn blocks + defer / new-defer Appended to FLOAT*DIV: if float deferred + #DEFER_BIB_SPACING Tells DEFAULTS to do BIBLIOGRAPHY_SPACING + if it was called before START + #DEFER_PAGINATION Tells COLLATE to restore pagination (from + RESTORE_PAGINATION + #DEFER_SPACE_ADDED Was space added between two "first" footnotes that + appear on the same page? (boolean) + #DELAY_SHIM Instructs DO_QUOTE to delay SHIM when quote + falls at the top of a page + #DEPTH LIST depth + #DEPTH_1 Doc header depth with lead adjustment + (#DOCHEADER_LINES * #DOCHEADER_LEAD) + #DEPTH_2 Doc header depth without lead adjustment + (#DOCHEADER_LINES * #DOC_LEAD) + #DEPTH_TO_B_MARGIN Page length minus #B_MARGIN + D-float Depth of float containing/ending with + DRH, DRV, DBX, or DCL + DI eqn indent if EQ I + #DIVER_FN Register that tells FOOTNOTE whether to + "move" or "defer" a footnote collected + inside a diversion + #DIVERSIONS_HY_MARGIN A reasonable value for .hym applied to + QUOTE, BLOCKQUOTE and EPIGRAPH to + avoid excessive hyphenation if these are + set quad left + #DIVERTED Set to 1 in DIVERT_FN_OVERFLOW; reset + subsequently in FOOTNOTES when called by + PROCESS_FN_LEFTOVER to 2 or 3 for use by + FOOTER to decide whether to in/decrease + #FN_DEPTH when outputting footnotes + #DOC_COVER Are we doing a DOC_COVER? (boolean) + #DOC_COVER_AUTHOR Put AUTHOR(s) on DOC_COVER? (boolean) + #DOCCOVER_BLANKPAGE Output blank page after DOC_COVER? (boolean) + #DOC_COVER_CHAPTER_TITLE_COLOR Colorize CHAPTER_TITLE on DOC_COVER? (boolean) + #DOC_COVER_COPYRIGHT Put copyright on DOC_COVER? (boolean) + #DOC_COVER_DOCTYPE Put doctype on DOC_COVER? (boolean) + #DOCCOVER_END Are we finishing a DOC_COVER? (boolean) + #DOC_COVER_LEAD Doc cover leading + #DOC_COVER_MISC Put misc on DOC_COVER? (boolean) + #DOC_COVER_START_POS Vertical starting pos of doc cover material + #DOC_COVER_COLOR Colorize cover? (boolean) + #DOC_COVER_START_POS Vertical starting pos of cover material + #DOC_COVER_TITLE_COLOR Colorize doc cover title? (boolean) + #DOC_COVER_SUBTITLE_COLOR Colorize doc cover subtitle? (boolean) + #DOC_COVER_ATTRIBUTE_COLOR Colorize doc cover attribution string? (boolean) + #DOC_COVER_AUTHOR_COLOR Colorize doc cover author(s)? (boolean) + #DOC_COVER_DOCTYPE_COLOR Colorize doc cover doctype? (boolean) + #DOC_COVER_COPYRIGHT_COLOR Colorize doc cover copyright line? (boolean) + #DOC_COVER_MISC_COLOR Colorize doc cover misc line? (boolean) + #DOC_COVER_SUBTITLE Put subtitle on DOC_COVER? (boolean) + #DOC_COVER_TITLE Put title on DOC_COVER? (boolean) + #DOC_COVER_TITLE_NUM Number of doc cover title items + #DOC_COVERS Print doc covers? (boolean) + #DOC_COVERS_OFF Don't print DOC_COVERs (boolean) + #DOCCOVER_RULE_WEIGHT Doctype underline weight on DOC_COVER + #DOCCOVER_RULE_WEIGHT_ADJ DOCCOVER_RULE_WEIGHT/2 + #DOCCOVER_UNDERLINE Underline doctype on DOC_COVER? (boolean) + #DOCCOVER_UNDERLINE_WEIGHT Doctype underline weight on DOC_COVER + #DOCCOVER_UNDERLINE_WEIGHT_ADJ DOCCOVER_UNDERLINE_WEIGHT/2 + #DOCCOVERS_COUNT Include DOC_COVER in pagination scheme? (boolean) + #DOC_HEADER Whether to print a doc header (boolean) + #DOC_LEAD_ADJ Incrementing value (in units) added to + #DOC_LEAD to fill page to #B_MARGIN + #DOC_LEAD Leading used in body + #DOC_L_LENGTH Global L_LENGTH + #DOC_L_MARGIN Global L_MARGIN + #DOC_LR_MARGIN_TMP In HEADER, if RECTO_VERSO=1, temporarily + holds DOC_L_MARGIN during page margin switch + #DOC_PT_SIZE Point size used for body text + #DOC_R_MARGIN Global R_MARGIN + #DOC_TYPE 1=default, 2=chapter, 3=named, 4=letter + #DOCHEADER_ADVANCE Distance from top-of-page to baseline of + docheader + #DOCHEADER_COLOR Colorize docheader? (boolean) + #DOCHEADER_DEPTH Depth of docheader + #DOCHEADER_LEAD Lead of doc header + (#DOC_LEAD + #DOCHEADER_LEAD_ADJ) + #DOC_LEAD_ADJUST_OFF Don't adjust DOC_LEAD (boolean) + #DOCS Always 1 after START + #DOCTITLE_NUM Number of doctitle items + #DOCTYPE_COLOR Colorize doctype? (boolean) + #DOCTYPE_RULE_WEIGHT Doctype underline weight + #DOCTYPE_RULE_WEIGHT_ADJ DOCTYPE_RULE_WEIGHT/2 + #DOCTYPE_UNDERLINE Underline doctype? (boolean) + #DOCTYPE_UNDERLINE_WEIGHT Weight of doctype underline + #DOCTYPE_UNDERLINE_WEIGHT_ADJ DOCTYPE_UNDERLINE_WEIGHT/2 + #DOING_COVER Tells PRINT_AUTHORS that it's printing + the authors for a cover or doc cover + #DONE_ONCE Keeps track of how many times footnotes + have been collected inside the same diversion + #DONT_RULE_ME Rule this (apparent) first footnote? (boolean) + #DIVER_LN_OFF Turn linenumbering off in (block)quotes? + (boolean) + #DRAFT_WITH_PAGENUM Are we attaching draft/revision info to page + number? (boolean) + #EM_ADJUST Amount to raise \(em at END + #EN_ALLOWS_HEADERS Put page headers on endnotes pages? (boolean) + #EN_ALLOWS_HEADERS_ALL Put page headers on all endnotes pages? + (boolean) + #EN_BQ_AUTOLEAD Register created by EN_BLOCKQUOTE_AUTOLEAD + #EN_BQ_LEAD Leading of blockquotes on endnotes pages + #EN_FIGURE_SPACE Width of \0, for use with formatting endnotes + #EN_FIRST_PAGE Tells PRINT_PAGE_NUMBER about endnotes + first page number + #EN_FIRST_PN Page number that appears on page 1 of + endnotes pages. + #EN_HDRFTR_CENTER Should we print centre string of + headers/footers on endnotes pages? (boolean) + #EN_LEAD Lead of endnotes + #EN_LN_BRACKETS Are we using brackets for line-numbered + endnotes (boolean) + #EN_LN_SEP Are we using a separator for line-numbered + endnotes (boolean) + #EN_MARK \n[ln] when \*[EN-MARK] is called + #EN_MARK_2 \n[ln] when ENDNOTE is called + #EN_MARKER_STYLE 1=NUMBER; 2=LINE + #EN_NO_COLS Do not set endnotes in columns? (boolean) + #EN_NO_FIRST_PN Put pagenumber on 1st page of endnotes? + (boolean) + #EN_NUMBER Number of current endnote + #EN_NUMBER_PLACEHOLDERS Number of placeholders to reserve for endnotes + numbers + #EN_NUMBERS_ALIGN_RIGHT Hang and align endnote numbers right? + (boolean) + #EN_NUMBERS_ALIGN_LEFT Align endnote numbers with left margin? + (boolean) + #EN_NUMBERS_PLACEHOLDERS Number of placeholders when endnote numbers + hang and align right + #EN_NUMBER_L_LENGTH Line length for endnote numbers when they're + right aligned + #EN_PP_INDENT First line indent of paras in multi-para + endnotes + #EN_PP_SPACE Space multi-paras in endnotes? (boolean) + #EN_PS ps of endnotes + #EN_Q_AUTOLEAD Register created by EN_QUOTE_AUTOLEAD + #EN_Q_LEAD Leading of quotes on endnotes pages + #EN_REF Put REFs in endnotes? (boolean) + #EN_SINGLESPACE Single space endnotes pages? (boolean) + #EN_STRING_ADVANCE Vertical position of "ENDNOTES" string (relative to + the top edge of the page) + #EN_STRING_CAPS Should ENDNOTES capitalize the endnotes + string? (boolean) + #EN_STRING_UNDERLINE Underscore endnotes page head? (boolean) + #EN_STRING_UNDERLINE_WEIGHT Weight of endnotes page title underscore + #EN_STRING_UNDERLINE_WEIGHT_ADJ EN_STRING_UNDERLINE_WEIGHT_ADJ/2 + #EN_TEXT_INDENT Page offset for text of endnotes when + numbers right align + #EN_TITLE_UNDERLINE Underscore endnotes document identifier? + (boolean) + #EN_TITLE_UNDERLINE_WEIGHT Weight of endnotes document identification + underscore + #EN_TITLE_UNDERLINE_WEIGHT_ADJ #EN_STRING_UNDERLINE_WEIGHT_ADJ/2 + #END_QUOTE For PP=0 indenting; did we just end a quote? + (boolean) + #ENDNOTE Are we in an endnote? (boolean) + #ENDNOTE_REFS Are REFs going to endnotes? (boolean) + #ENDNOTES Are we in an endnote (for FOOTERs; boolean) + #EPI_ACTIVE Are we in an epigraph? (boolean) + #EPI_AUTOLEAD Autolead value for epigraphs + #EPI_COLOR Colorize epigraphs? (boolean) + #EPI_DEPTH Depth of epigraph from first baseline to + last + #EPI_FITS Does epigraph fit on page/column? (boolean) + #EPIGRAPH Did we have an epigraph? (boolean) + #EPI_LEAD_DIFF Difference between #DOC_LEAD and #EPI_LEAD + #EPI_LEAD Leading of epigraph; set by AUTOLEAD + #EPI_LINES_EVEN Even # of lines at end of epi crossing page in + TYPEWRITE (d-spaced)? + #EPI_LINES Number of lines in the epigraph + #EPI_LINES_TO_END Number of epigraph lines remaining after + footer trap is sprung + #EPI_LINES_TO_TRAP Number of epigraph lines till footer trap is + sprung + #EPI_L_LENGTH Epigraph line length + #EPI_OFFSET Left margin of epigraphs + #EPI_OFFSET_VALUE Epigraph indent as a function of page offset + #EPI_ON Are we in an epigraph? (boolean) + #EPI_WHITESPACE Space after epigraph to compensate for + epigraph leading + #FIELD Incrementing register tacked onto LETTERHEAD + #FINIS Was FINIS invoked? (boolean) + #FINIS_STRING_CAPS Capitalize finis string? (boolean) + #FINIS_COLOR Colorize FINIS? (boolean) + #FIRST_DOC_TITLE_PN Page number of 1st (collated) doc (for TOC) + #FIRST_DOC_TOC_PN_PADDING Padding for 1st page number of 1st (collated) doc + (for TOC) + float*after-shim / \n[nl]; tests if SHIM has stayed on the same + float*before-shim baseline + float-span Float can run to multiple pages? (boolean) + float*with-tbl Float contains a tbl block + #FN_AUTOLEAD Autolead value of footnotes + #FN_BL_INDENT Left indent of INDENT BOTH in footnotes + #FN_BR_INDENT Right indent of INDENT BOTH in footnotes + #FN_COUNT Which fn marker to print; also to + tell mom to reserve space for and print + the rule above footnotes + #FN_COUNT_AT_FOOTER The FN_COUNT after FOOTNOTES has been + output in FOOTER + #FN_COUNT_FOR_COLS Holds a separate footnote count for columns + (so they don't reset to 0 1 until page break) + #FN_DEFER Defer footnote to next page/column? (boolean) + If 0, don't defer. + #FN_DEFER_SPACE Whether to deposit space before + footnote 1 because there's a deferred + footnote on the page + #FN_DEPTH Depth of footnote diversion(s) + #FN_FOR_EPI Signals to epigraph that a footnote is being + processed + #FN_GAP When there are footnotes on a page, the + difference between where FOOTER will be + sprung and the next valid baseline. + Used in VFP_CHECK. + #FN_LEAD Lead in footnotes after FN_AUTOLEAD is + applied + #FN_L_INDENT Left indent of INDENT LEFT in footnotes + #FN_LINES Number of lines in fn; used to calculate + fn depth + #FN_LN_BRACKETS Are footnote linenumber brackets being used? + (boolean) + #FN_LN_SEP Is a footnote linenumber separator being used? + (boolean) + #FN_MARK \n[ln] when \*[FN-MARK] is called + #FN_MARK_2 \n[nl] when FOOTNOTE is called + #FN_MARKER_STYLE 1=STAR; 2=NUMBER + #FN_MARKERS Print footnote markers? (boolean) + #FN_NUMBER The footnote number attached to running text + (and fns) when numbers instead of + star/dagger is being used for footnootes + numbers + #FN_OVERFLOW_DEPTH Depth of leftover from footnote processing + #FN_OVERFLOW_TRAP_POS The register that sets the position of + trap FN_OVERFLOW_TRAP. + #FN_R_INDENT Right indent of INDENT RIGHT in footnotes + #FN_REF Put REFs in footnotes? (boolean) + #FN_RULE Print fn rule? (boolean) + #FN_RULE_ADJ # of points to raise footnote separator from + its baseline + #FN_RULE_LENGTH Length of footnote separator rule + #FN_RULE_WEIGHT Weight of the footnote separator rule + #FN_RULE_WEIGHT_ADJ FN_RULE_WEIGHT/2 + #FN_WAS_DEFERED Tells HEADER about a deferred footnote + #FOOTER_DIFF In TRAPS, the difference between the + original #B_MARGIN and #VISUAL_B_MARGIN + #FOOTER_GAP Amount of space between end of text and + page # + #FOOTER_MARGIN Amount of space between page # and bottom + of page + #FOOTER_POS Position of footer trap (required for + collecting footnotes inside a diversion) + #FOOTER_RULE Print footer rule? (boolean) + #FOOTER_RULE_GAP Gap between footer and separator rule above + #FOOTER_RULE_WEIGHT Weight of footer rule + #FOOTER_RULE_WEIGHT_ADJ #FOOTER_RULE_WEIGHT/2 + #FOOTERS_ON Are we using footers? (boolean) + #FOOTERS_WERE_ON Were footers on? - used in FINIS and BLANKPAGE + (boolean) + #FOOTNOTE_COLOR Colorize footnotes? (boolean) + #FORCE Force float? (boolean) + #FROM_BIB_STRING Tells UNDERSCORE it's underscoring $BIB_STRING + #FROM_COVER Tells UNDERSCORE it's underscoring on a cover + #FROM_DOC_COVER Tells UNDERSCORE it's underscoring on a doccover + #FROM_DOCTYPE Tells UNDERSCORE it's underscoring the doctype + #FROM_EN_STRING Tells UNDERSCORE it's underscoring $EN_STRING + #FROM_EN_TITLE Tells UNDERSCORE it's underscoring $EN_TITLE + #FROM_HEAD Tells UNDERSCORE it's underscoring a head + #FROM_DIVERT_FN Signals to FOOTNOTE, when run from + within DIVERT_FN_LEFTOVER, to set + #SPACE_REMAINING to the total area + allowable for running text + #FROM_FOOTER In col to col footnote processing, tells + FOOTNOTE that FOOTNOTES was output from + FOOTER. + #FROM_HEADER In col to col footnote processing, tells + FOOTNOTE that FOOTNOTES was output from + HEADER. + #FULLSPACE_QUOTES Should we fullspace quotes? (boolean) + #GET_DC_HEIGHT Used in routine to get the correct point size for + dropcaps + #GET_DEPTH Signals to FOOTNOTE that it should + measure the depth of current footnotes + plus the most recently added one, except + where the footnote is to be deferred to + the next page or column + #GUTTER Width of gutter between columns + #H_BASELINE_ADJ Vertical spacing adjustment for heads (default=0) + #HDRFTR_BOTH Are we setting both headers and footers? (boolean) + #HDRFTR_CENTER_CAPS CENTER part of header/footer in caps? + (boolean; default=off) + #HDRFTR_CENTER_COLOR Colorize header/footer center? (boolean) + #HDRFTR_COLOR Colorize headers/footers? (boolean) + #HDRFTR_CTR_PAD_LEFT Amount of hdrftr CENTER padding on the left + #HDRFTR_CTR_PAD_RIGHT Amount of hdrftr CENTER padding on the right + #HDRFTR_CTR_PAD_TMP Temp storage of left hdrftr CENTER padding + (for recto/verso switch) + #HDRFTR_HEIGHT Cap height of $HDRFTR_RECTO/$HDRFTR_VERSO + strings + #HDRFTR_LEFT_CAPS Left part of header/footer in caps? + (boolean; default=off) + #HDRFTR_LEFT_COLOR Colorize header/footer left? (boolean) + #HDRFTR_PT_SIZE Initial point size of headers/footers + #HDRFTR_RECTO_CAPS Header/footer recto caps? (boolean) + #HDRFTR_RIGHT_CAPS Right part of header/footer in caps? + (boolean; default=on) + #HDRFTR_RIGHT_COLOR Colorize header/footer right? (boolean) + #HDRFTR_RULE Print head/footer rule? (boolean) + #HDRFTR_RULE_COLOR Colorize header/footer rule? (boolean) + #HDRFTR_RULE_GAP Space between header/footer and + header/footer rule + #HDRFTR_RULE_WEIGHT Weight of header/footer rule + #HDRFTR_RULE_WEIGHT_ADJ HDRFTR_RULE_WEIGHT/2 + #HDRFTR_TMP_CAPS_SWITCH Temporarily holds HDRFTR_LEFT_CAPS value if + #SWITCH_HDRFTR=1 + #HDRFTR_VERSO_CAPS Header/footer verso caps? (boolean) + #HEAD 1=main/section head 2=subhead + #HEAD_CAPS Print section titles in caps? (boolean) + #HEAD_COLOR Colorize heads? (boolean) + #HEADER_GAP Distance from header to running text + #HEAD_NUM Head number + #HEAD_SPACE 2 line spaces before heads? (boolean) + #HEAD_UNDERLINE Underline heads? (boolean) + #HEAD_UNDERLINE_WEIGHT Head underline weight + #HEAD_UNDERLINE_WEIGHT_ADJ HEAD_UNDERLINE_WEIGHT/2 + #HEADER_MARGIN Distance from top of page to header + #HEADER_RULE Print header rule? (boolean) + #HEADER_RULE_GAP Gap between header and header rule + #HEADER_RULE_WEIGHT Header rule weight + #HEADER_RULE_WEIGHT_ADJ HEADER_RULE_WEIGHT/2 + #HEADERS_ON Headers on? (boolean) + #HEADER_STATE Saves header state in COLLATE for use in + START after COLLATE + #HEADERS_WERE_ON Were headers on? - used in BLANKPAGE (boolean) + #HF_OFF Has HEADERS_AND_FOOTERS been turned off? (boolean) + #HORIZ_MARK Horizontal + #HOW_MANY Number of blank pages to output + #IGNORE Should we ignore this macro? Set to 1 in + TYPEWRITE. + #IN_BIB_LIST Tells ITEM we're doing a bibliography in + list style + #INDENT_FIRST_PARAS Indent first paras? (boolean) + #INDENT_FIRSTS Tells footnotes to leave INDENT_FIRST_PARAS + alone if it's on for running text. + #ITALIC_MEANS_ITALIC For TYPEWRITE. (boolean) + #ITEM Counter for removing _1, _2, _3... strings + in TITLE, CHAPTER_TITLE, etc. + #L_LENGTH_FOR_EPI Stores line length at top of doc for use + with EPIGRAPH when columns are on + #L_MARGIN_DIFF Difference between DOC_L_MARGIN and + L_MARGIN + #LB_CHAR_ITERATIONS Number of linebreak character iterations + #LEFT_CAP_HEIGHT Cap height of left string in headers/footers + #VALID_BASELINE Calculates vert. position of next valid + baseline in SHIM + #LETTER_STYLE 1=BUSINESS 2=PERSONAL + #LINEBREAK Did we have a linebreak? (boolean) + #LINEBREAK_COLOR Colorize linebreak? (boolean) + #LINENUMBER_COLOR Colorize linenumbers? (boolean) + #LINENUMBERS Holds various states of line-numbering when + line numbering is enabled + #LINES_PER_PAGE # of lines (at DOC_LEAD) that fit on + page after #B_MARGIN is set + #LN Test 1st arg to NUMBER_LINES for digit or string + MN-active Are we doing a margin note? (boolean) + MN-curr Current margin note + MN-div-<n>-depth Depth of margin note <n> + MN-hy Hyphenation flag of margin notes + #MNinit Have margin notes been initialized? (boolean) + #MNinit_DEFERRED Did we have to defer a margin note? (boolean) + MN-last-pos Baseline of previous margin note + MN-lead-adj Difference between the current DOC_LEAD and the + leading used in margin notes + MN-left Number of current left margin note + MN-left-start Horizontal start position of left margin note + MN-left-width Width of left margin note + MN-right Number of current right margin note + MN-right-start Horizontal start position of right margin note + MN-right-width Width of right margin note + MN-sep Gutter between margin notes and running text + MN-shifted Did we have to shift a margin note down? + (boolean) + MN-size Point size of margin notes + MN-spacing Leading of margin notes + #MISC_<n> Used to print "next" misc lines in DO_COVER + #MISC_COVER_NUM Number of cover misc items + #MISC_DOCCOVER_NUM Number od doc cover misc items + #MISC_NUM Number of MISC items + #MISCS =#MISC_NUM in DO_COVER + #MN_OVERFLOW_LEFT If 1, left margin note text overflows + #MN_OVERFLOW_RIGHT If 1, right margin note text overflows + #n%_AT_PAGENUM_SET Page # from n% when PAGENUMBER invoked + #NEEDS_SPACE Instruct FOOTNOTE, when called by + PROCESS_FN_IN_DIVER, that if the footnote + had to be deferred, the VFP must be + raised by 1v (set in DIVER_FN_2_PRE) + #NEITHER Should we print no covers? (boolean) + #NEXT_AUTHOR Supplies correct digit to AUTHOR_<n> + when printing authors in doc header + #NEXT_LN Next linenumber when \n[ln] has to be stored + because linenumbering suspended + #NEXT_MISC Incrementing counter for misc lines in + DO_COVER + #NEXT_SUBTITLE Incrementing register used to print subtitles + #no-repeat-MN-left Don't repeat left margin note (boolean) + #no-repeat-MN-right Don't repeat right margin note (boolean) + #NO_BACK_UP Instructs FN_OVERFLOW_TRAP not to + subtract 1 line of footnote lead from + FN_OVERFLOW in a PREV_FN_DEFERRED + situation. + #NO_BREAK Set to 1 in COLLATE if last line of + text before COLLATE falls at the bottom + of the page; instructs NEWPAGE to use + 'br instead of .br + #NO_COLUMNS Don't print document in columns (boolean) + #NO_FN_MARKER Don't print footnote markers (boolean) + #NO_SHIM Should SHIM shim? (boolean) + #NO_SPACE When para spacing is active, instructs + PP not to add space after a quote or blockquote + #NO_TRAP_RESET Should we reset page traps? (boolean) + #NOT_YET_ADJUSTED Line on which a footnote was called has not yet + been adjusted by groff (boolean) + #NUM_AUTHORS # of authors mod 2 to test if odd or even + # of authors + #NUM_MISCS Number of args passed to MISC + #NUM_MISCS_COVER Number of args passed to MISC COVER + #NUM_MISCS_DOCCOVER Number of args passed to MISC DOC_COVER + #NUMBER_HEAD Are heads numbered? (boolean) + #NUMBER_PH Are paraheads numbered? (boolean) + #NUMBER_SH Are subheads numbered? (boolean) + #NUMBER_SSH Are subsubheads numbered? (boolean) + #NUM_COLS Number of columns per page + #NUMBERED If set to 1, lets PARAHEAD know that + main-, sub-, and subsubhead numbers have already been + prefixed to the parahead string + #NUM_FIELDS Incrementing register used to match + #TOTAL_FIELDS + #OK_PROCESS_LEAD Initial processing of TOC and endnote + leading is deferred until OK_PROCESS_LEAD=1 + #ORIGINAL_B_MARGIN The value for #B_MARGIN as set by the + macro B_MARGIN + #ORIG_DOC_LEAD DOC_LEAD before endnotes, bibliographies, tocs + #ORIG_L_LENGTH \\n[.l] before starting LISTs + #ORIGINAL_DOC_LEAD The lead for PRINT_STYLE 1 as set in + PRINTSTYLE; required so that PRINT_STYLE 1 + footnotes have an unadjusted lead of + 12 points + #OVERFLOW Signals to FOOTNOTE that some of the + footnote text won't fit on the page + #OVERFLOW_LEFT Does left margin note overflow? (boolean) + #OVERFLOW_RIGHT Does right margin note overflow? (boolean) + #P Page number for margin notes + #PAD_LIST_DIGITS<n> Pad LIST digits for LIST <n>? (boolean) + #PAGE_NUM_ADJ What to add to n% to get #PAGENUMBER + #PAGE_NUM_H_POS 1=left 2=CENTER 3=right; default=2 + #PAGE_NUM_COLOR Colorize pagenumbers? (boolean) + #PAGE_NUM_HYPHENS Print hyphens surrounding page numbers? + (boolean) + #PAGE_NUM_HYPHENS_SET Did user set (or unset) hyphens around page + numbers? (boolean) + #PAGE_NUM_POS_SET Did user set page number position? (boolean) + #PAGE_NUM_SET Test if PAGE_1_NUM was used to set 1st page + number + #PAGE_NUM_V_POS 1=top 2=bottom; default=2 + #PAGE_NUMS Print page numbers? (boolean) + #PAGE_POS Exact position on page during a diversion + (required for collecting footnotes inside + a diversion) + #PAGE_TOP \n[nl] after HEADER completes itself + #PAGENUM_STYLE_SET Did we set pagenumber style? (boolean) + #PAGENUMBER The page number + #PAGES Number of blank pages to output + #PAGINATE Are we paginating? (boolean) + #PAGINATE_TOC Is toc pagination on? (boolean) + #PAGINATE_WAS_ON Keeps track of pagination state while + outputting blank pages + #PAGINATION_STATE Saves pagination state in COLLATE for use in + START after a COLLATE + #PAGINATION_WAS_ON Was pagination on? - used in FINIS (boolean) + #PH_COLOR Colorize paraheads? (boolean) + #PH_INDENT Size of parahead indent + #PH_NUM Parahead number + #PP 0 at first para; auto-increments + #PP_AT_PAGE_BREAK # of last (incl. partial) para on page + #PP_INDENT How much to indent paras + #PP_SPACE Put space before paras? (boolean) + #PP_SPACE_SUSPEND Suspend para spacing for blockquotes and + epigraphs + #PP_STYLE_PREV In footnotes, stores PP style in effect + prior to invoking FOOTNOTE + #PP_STYLE Regular para=1; quote or epi para=2 + #PRE_COLLATE Set to 1 in COLLATE; prevents FAMILY + from clobbering a user-set DOC_FAMILY + #PREFIX_CH_NUM Prefix the chapter number to numbered + heads, subheads and/or paraheads? (boolean) + #PREV_FN_DEFERRED Was previous footnote deferred? (boolean) + #PRINT_PAGENUM_ON_PAGE_1 Should we print the page number on first + page of doc when footers are on? (boolean) + #PRINT_STYLE Typewrite=1, typeset=2 + #PT_SIZE_IN_UNITS Stored value of \n[.ps] from last time + PT_SIZE was called + #Q_AUTOLEAD Register created by QUOTE_AUTOLEAD + #Q_DEPTH Depth of quote + #Q_FITS Does this quote fit on one page/column? + (boolean) + #Q_LEAD Leading of quotes + #Q_LEAD_DIFF Difference between leading of running text + and the leading used in quotes/blockquotes + #Q_LEAD_REAL Leading of quotes and blockquotes saved at the + ends of their respective diversions + #Q_L_LENGTH Line length of quotes + #Q_OFFSET Page offset for quotes + #Q_OFFSET_VALUE Factor by which to multiply PP_INDENT to + offset quotes + #Q_PARTIAL_DEPTH The amount of a quote/blockquote that fits at + the bottom of a page when a quote/blockquote + spans pages + #Q_PP In PP, stores para # in QUOTE. Removed in + ENDQUOTE. + #Q_SPACE_ADJ The flexible amount of whitespace to add before + and after a quote/blockquote + #Q_TOP Vertical place on page that a quote starts + #QUOTE 1=PQUOTE, 2=BQUOTE + #QUOTE_COLOR Colorize quotes (poetic)? (boolean) + #QUOTE_LN Linenumber quotes? (boolean) + #RECTO_VERSO Switch HEADER_LEFT and HEADER_RIGHT on + alternate pages? (boolean) + ref*suppress-period Suppress period at end of ref field? (boolean) + ref*type Kind of reference we're building + #REF Was REF called? (boolean) + #REF_HY Hyphenate REFs? (boolean) + #REF_WARNING Have we issued a ref warning? (boolean) + #REPEAT Number of times to repeat linebreak + character + #RERUN_TRAPS Should we invoke TRAPS? (boolean) + #RESERVED_SPACE Just enough room to put 1 more line of + footnotes on the page + #RESET_EN_PP Holds value of register #EN_PP_INDENT + #RESET_EN_PP_INDENT Holds value of register #EN_PP_INDENT + #RESET_FN_COUNTERS 1 = "moved" footnote collected in a diversion + 2 = "deferred" fn collected in a diversion + #RESET_FN_NUMBER Should fn# start at 1 on every page? + (boolean) + #RESET_L_LENGTH Stores current line length when necessary + #RESET_PARA_SPACE Holds current value of boolean register + #PP_SPACE + #RESET_PP_INDENT Stores value of PP_INDENT when needed + #RESET_QUOTE_SPACING Stores value of boolean register + #FULLSPACE_QUOTES (used in endnotes) + #RESTORE_ADJ_DOC_LEAD Stores value of #ADJ_DOC_LEAD whenever needed + #RESTORE_B_MARGIN Stores #B_MARGIN whenever needed + #RESTORE_DOC_LEAD Stores value of current doc lead (used in + endnotes) + #RESTORE_HY Restore hyphenation after .][? (boolean) + #RESTORE_INDENT Store \n[.i] whenever needed + #RESTORE_L_LENGTH Stores \n[.l] whenever needed + #RESTORE_LN_NUM Should we restore line numbering? (boolean) + #RESTORE_OFFSET Page offset at moment footer trap is sprung; + not currently used + #RESTORE_UNDERLINE Instructs CODE OFF to restore underlining of + italics (TYPEWRITE) if underlining was + formerly on + #RIGHT_CAP_HEIGHT Cap height of right string in + headers/footers + #RULED Tells FOOTNOTE if a rule (or space has been + put above the first footnote on the page + #RUNON_FN_IN_DIVER If #LN=1, if we're in a (block)quote, instructs + FOOTNOTE to unformat diversion RUNON_FN_IN_DIVER + #RUNON_FOOTNOTES If #LN=1, instructs FOOTNOTE to unformat + diversion RUNON_FOOTNOTES + #RUN_ON Are we using run-on footnotes? (boolean) + #SAVED_DIVER_FN_COUNT In the case of a footnote inside a + diversion that should be treated as a + "normal" footnote, FOOTNOTE needs to + distinguish between a "normal" deferred + footnote (always the 1st footnote on the + page) and one that only looks as if + it should be deferred, when, in fact, + it's an overflow; this register lets + FOOTNOTE know whether the diversion + footnote is, in fact, the first on the + page. + #SAVED_DOC_LEAD Stored value of #DOC_LEAD (used in DEFAULTS after + a COLLATE) + #SAVED_FN_COUNT #FN_COUNT+1 prior to +#FN_COUNT; used + in FOOTNOTES while gathering fns inside + diversions + #SAVED_FN_COUNT_FOR_COLS #FN_COUNT_FOR_COLS+1 prior to + +#FN_COUNT_FOR_COLS; used in FOOTNOTES + while gathering fns inside diversions + #SAVED_FN_DEPTH_1 Footnote depth prior to adding footnote + diversion depth to FN_DEPTH; used when + footnote text will overflow + #SAVED_FN_DEPTH_2 Footnote depth after to adding footnote + diversion depth to FN_DEPTH; used when + footnote text will overflow + #SAVED_FN_NUMBER Stores current FN_NUMBER whenever needed + #SAVED_FOOTER_POS Position of FOOTER in DO_QUOTE (hack) + #SAVED_LEAD In FOOTER and DO_FOOTER, stores the + lead in effect prior to outputting + FOOTNOTES or performing either + PROCESS_FN_LEFTOVER or + PROCESS_FN_IN_DIVERSION; both the + diversion FOOTNOTES and the two macros + have, for PRINT_STYLE 2, an AUTOLEAD + call, which requires that an LS be + performed with the #SAVED_LEAD in + order to remove register #AUTO_LEAD or + #AUTO_LEAD_FACTOR. + #SAVED_UNDERSCORE_WEIGHT Stores underscore weight whenever needed + #SAVED_UNDERSCORE_WEIGHT_ADJ SAVED_UNDERSCORE_WEIGHT/2 + #SAVED_VFP Store variable footer position whenever needed + #SAVED_WEIGHT Stores weight given to RULE_WEIGHT whenever needed + #SAVED_WEIGHT_ADJ SAVED_UNDERSCORE_WEIGHT/2 + #SEP_TYPE Set to 1 if LIST separator is ( or [ or { + #SH_COLOR Colorize subheads? (boolean) + #SH_BASELINE_ADJ #DOC_LEAD/8 (TYPESET) or /5 (TYPEWRITE) + (used for subhead vertical spacing) + #SH_NUM Subhead number + #SHIM Amount of lead required to advance to + next valid baseline + #SILENT_BQUOTE_LN "Silently" linenumber blockquotes? (boolean) + #SILENT_QUOTE_LN "Silently" linenumber quotes? (boolean) + #SINGLE_SPACE Is TYPEWRITE in single space mode? (boolean) + #SKIP ENTRY If one, don't print the first entry (the + document title) in the TOC of uncollated docs. + #SKIP_FOOTER If 1, instructs DO_FOOTER to do nothing + if B_MARGIN falls below FOOTER_MARGIN + #SLANT_MEANS_SLANT For TYPEWRITE. (boolean) + #SLANT_WAS_ON Keeps track of SLANT when it needs to go off + for a while + #SPACE_REMAINING Space remaining to footer trap; used to + decide whether or not to defer a footnote + #SPACE_TO_FOOTER Distance to FOOTER trap; used to calculate + available space when FOOTNOTE is called inside + a diversion + #SR_ADJ_FACTOR An adjustment factor that compensates + for the fact that #SPACE_REMAINING + sometimes reports a fractionally larger + space than is actually available for + footnote text. + #SSH_BASELINE_ADJ #DOC_LEAD/8 (TYPESET) or /5 (TYPEWRITE) + (used for subsubhead vertical spacing) + #START If 1, signals completion of START + #START_FOR_FOOTERS Toggle set in START; signals to + PRINT_HDRFTR that START has been invoked, + allowing PRINT_HDRFTR to decide whether or + not to print a footer on page 1 + #START_FOR_MNinit If 1, defer processing MN_INIT until #START + #STORED_PP_INDENT Temporarily holds value of #PP_INDENT + #SUBHEAD Was subhead the last macro invoked? (boolean) + Controls vert. space between SUBHEAD and + SUBSUBHEAD + #SUBTITLE_COLOR Colorize subtitle? (boolean) + #SUBTITLE_COVER_NUM Incrementing register used to define strings + $SUBTITLE_COVER_<n> + #SUBTITLE_DOCCOVER_NUM Incrementing register used to define strings + $SUBTITLE_DOCCOVER_<n> + #SUBTITLE_NUM Incrementing register used to define strings + $SUBTITLE_<n> + #SUBTITLES Holds number of subtitle items + #SUITE Current page number (for letters) + #SUP_PT_SIZE Point size of superscript + #SUSPEND_PAGINATION Suspend pagination prior to endnotes? + #SWITCH_HDRFTR Switch HDRFTR_LEFT and HDRFTR_RIGHT? + (boolean) + tbl*boxed tbl has box or allbox (boolean) + tbl*center-label-on-table Is tbl caption centered? (boolean) + tbl*have-header tbl has a running header (boolean) + tbl*header-ht Depth of tbl*header-div + tbl*left-label-on-table Is tbl caption quad left? (boolean) + tbl*move-fn-overflow-trap Whether to move FN_OVERFLOW_TRAP_POS + to accommodate tbl + tbl*move-fn-overflow Amount by which to change + FN_OVERFLOW_TRAP_POS to accommodate tbl + tbl*move-footer Amount by which to change FOOTER trap + to accommodate tbl + tbl*move-footer-trap Whether to move FOOTER trap to accommodate + tbl + tbl*no-shim Whether to SHIM tbl (boolean) + tbl*right-label-on-table Is tbl caption quad right? (boolean) + #T_MARGIN_LEAD_ADJ \n[.v]-12000; ensures critically accurate + placement of first lines on pages when + doc processing is not being used and + a T_MARGIN has been set + #TAB_OFFSET# "#" at the end is from $CURRENT_TAB + #TERMINATE Has TERMINATE been called? (boolean) + #TITLE_COLOR Colorize title? (boolean) + #TITLE_NUM Number of title items + #TOC_AUTHORS Whether to append author(s) to toc doc + title entries (boolean) + #TOC_ENTRY_PN Current page number when a toc entry is + collected + #TOC_FIRST_PAGE If 1, tells PRINT_PAGE_NUMBER that this + is the first page of the toc + #TOC_LEAD Leading of toc pages + #TOC_PN_PADDING Max. # of placeholders for toc entries + page numbers + #TOC_PS Point size of toc pages + #TOC_RV_SWITCH Switch L/R margins of toc pages + #TOC_HEAD_INDENT Indent of toc head entries + #TOC_HEAD_SIZE_CHANGE ps in/decrease of toc head entries + #TOC_PH_INDENT Indent of toc parahead entries + #TOC_PH_SIZE_CHANGE ps in/decrease of toc parahead entries + #TOC_SH_INDENT Indent of toc subhead entries + #TOC_SH_SIZE_CHANGE ps in/decrease of toc subhead entries + #TOC_TITLE_INDENT Indent of toc doc title entries + #TOC_TITLE_SIZE_CHANGE ps in/decrease of toc doc title entries + @TOP Controls .ns at page top; + trap-invoked (FOOTER); mostly trap-removed + (RR_@TOP) + #TOTAL_FIELDS Total number of letter header fields + #TRAP \n[.t]-1 (used in DO_QUOTE) + #TW Width of tbl block + #UNADJUSTED_DOC_LEAD Argument passed to DOC_LEAD prior to + adjusting (set in TRAPS) + #UNDERLINE_ITALIC For TYPEWRITE. (boolean) + #UNDERLINE_ON Was UNDERLINE called? (boolean) + #UNDERLINE_QUOTES Was UNDERLINE_QUOTES called? (boolean) + #UNDERLINE_QUOTE Underline pquotes? (boolean) + #UNDERLINE_SLANT For TYPEWRITE. (boolean) + #UNDERLINE_WAS_ON Was underlining on prior to the + invocation of current macro? (boolean) + #UNDERLINE_WAS_ON_FN As above, but for footnotes only + #USER_DEF_HDRFTR_CENTER Has user defined hdrftr center? (boolean) + #USER_DEF_HDRFTR_LEFT Has user defined hdrftr left? (boolean) + #USER_DEF_HDRFTR_RIGHT Has user defined hdrftr right? (boolean) + #USER_DEF_HEADER_CENTER User defined CENTER title? (boolean); + used in COPYSTYLE + #USER_DEF_HEADER_LEFT User defined CENTER title? (boolean); + used in COPYSTYLE + #USER_DEF_HEADER_RIGHT User defined CENTER title? (boolean) + used in COPYSTYLE + #USERDEF_HDRFTR User defined single string recto/verso + header/footer? (boolean) + #USERDEF_HDRFTR_RECTO_QUAD 1=left, 2=CENTER, 3=right + #USERDEF_HDRFTR_VERSO_QUAD 1=left, 2=CENTER, 3=right + #VARIABLE_FOOTER_POS Wandering trap position for processing + footnotes and footers; pos depends on number of + footnotes + #VISUAL_B_MARGIN Set in TRAPS, what \n[nl] would report + on the last line of running text before + FOOTER is sprung. + #VFP_DIFF #FN_DEPTH minus #SAVED_FN_DEPTH; the + number of footnote lines that will fit + on the page when there will be over, and + therefore the amount by which to raise + the VFP for footnotes with overflow after + the 1st footnote. + y Vertical position stored with mk in hdrftrs. + ++++STRINGS+++ + + $1ST_LETTER First letter of first arg to LIST + $ADJUST_BIB_LEAD 2nd arg to BIBLIOGRAPHY_LEAD; if not blank + adjust bib leading + $ADJUST_EN_LEAD 2nd arg to ENDNOTE_LEAD; if not blank adjust + endnote leading + $ADJUST_TOC_LEAD 2nd arg to TOC_LEAD; if not blank adjust + toc leading + $ATTRIBUTE_COLOR Attribution string color + $ATTRIBUTE_STRING Attribution string in doc header + $ATTRIBUTE_STRING_COVER Attribution string on cover + $ATTRIBUTE_STRING_DOCCOVER Attribution string on doc cover + $AUTHOR_<n> Document author(s) + $AUTHOR The author, or the first argument + passed to .AUTHOR ($AUTHOR_1) + $AUTHOR_COLOR Author color + $AUTHOR_COVER_<n> Author(s) on cover + $AUTHOR_DOCCOVER_<n> Author(s) on doc cover + $AUTHOR_FAM Family to use for author in doc header + $AUTHOR_FT Font to use for author in doc header + $AUTHOR_SIZE_CHANGE ps in/decrease of author in doc header + $AUTHOR_PT_SIZE Absolute ps of authors + $AUTHORS Comma-separated concatenated + string of all args passed to .AUTHOR + $BIB_FAM Bibliography page family + $BIB_FT Bibliography page font + $BIB_LEAD Base leading for bibliographies + $BIB_LIST_SEPARATOR Separator between enumerator and text + when outputting bibliographies in + LIST style + $BIB_LIST_PREFIX Prefix before enumerator when outputting + bibliographies in LIST style + $BIB_PN_STYLE Format of bibliography page numbers + $BIB_QUAD + $BIB_SPACE Post entry space for bibliographies + $BIB_STRING Bibliography title string + $BIB_STRING_FAM Bib title family + $BIB_STRING_FT Bib title font + $BIB_STRING_QUAD Bib title quad + $BIB_STRING_RULE_GAP Distance between the underscores when + BIB_STRING (bib first-page header) is + double-underlined + $BIB_STRING_SIZE_CHANGE Bib title size (+ or -) + $BIB_STRING_UNDERLINE_GAP Distance between BIB_STRING text and (first) + underline rule + $BQ_LN_GUTTER Gutter between line numbers and bquotes in + bquotes + $BQUOTE_COLOR Blockquote color + $BQUOTE_FAM Family to use for blockquotes + $BQUOTE_FT Font to use for blockquotes + $BQUOTE_QUAD Quad value for blockquotes + $BQUOTE_SIZE_CHANGE ps in/decrease of blockquotes + $BX_COLOR Box color + $BX_DEPTH Box depth + $BX_INDENT Box left margin starting position + $BX_WEIGHT Box rule weight + $BX_WIDTH Box width + $CENTER_TITLE What to put in the middle of header + title + $CH_NUM Chapter number (as a string) + $CHAPTER The chapter number + $CHAPTER_STRING What to print whenever the word + "chapter" is required + $CHAPTER_TITLE Concatenated args passed to CHAPTER_TITLE + $CHAPTER_TITLE_<n> Chapter title items + $CHAPTER_TITLE_FAM Family of chapter title + $CHAPTER_TITLE_FT Font of chapter title + $CHAPTER_TITLE_SIZE_CHANGE ps in/decrease of chapter title + $CHAPTER_TITLE_PT_SIZE Absolute ps of chapter title + $CHAPTER_TITLE_COLOR Color of chapter title + $CL_COLOR Circle (ellipse) color + $CL_DEPTH Circle (ellipse) depth + $CL_INDENT Circle (ellipse) left margin starting + position + $CL_WEIGHT Circle (ellipse) rule weight + $CL_WIDTH Circle (ellipse) width + $CLOSE_INDENT Argument passed to CLOSING_INDENT + $CODE_FAM Family to use with CODE + $CODE_FT Font to use with CODE + $CODE_COLOR Color of CODE + $COLOR_SCHEME Color scheme arg passed to NEWCOLOR + $COPY_STYLE DRAFT or FINAL + $COPYRIGHT Copyright info + $COPYRIGHT_COVER Copyright info for cover + $COPYRIGHT_DOCCOVER Copyright info for doc cover + $COPYRIGHT_FAM Copyright line family + $COPYRIGHT_FT Copyright line font + $COPYRIGHT_PT_SIZE Base string to which $COPYRIGHT_SIZE_CHANGE + is appended + $COPYRIGHT_SIZE_CHANGE Copyright line size + $COPYRIGHT_COLOR Copyright line color + $COPYRIGHT_QUAD Copyright line quad direction + $COVER_ATTRIBUTE_COLOR Cover attribution string color + $COVER_AUTHOR_COLOR Cover author(s) color + $COVER_AUTHOR_FAM Cover author(s) family + $COVER_AUTHOR_FT Cover author(s) font + $COVER_AUTHOR_PT_SIZE Author point size on cover + $COVER_AUTHOR_SIZE_CHANGE Cover author(s) size + $COVER_CHAPTER_TITLE_COLOR Color of chapter title on cover + $COVER_CHAPTER_TITLE_PT_SIZE Size of chapter title on cover + $COVER_COLOR Overall cover color + $COVER_COPYRIGHT_PT_SIZE Size of copyright info on cover + $COVER_DOCTYPE_PT_SIZE Size of doctype on cover + $COVER_FAM Overall cover family + $COVER_LEAD_ADJ String appended to DOC_LEAD to arrive at + base leading of covers + $COVER_SUBTITLE_PT_SIZE Size of subtitle on cover + $COVER_TITLE_PT_SIZE Size of title on cover + $COVER_TITLE User-defined cover title string + $COVER_TITLE_<n> Cover title items + $COVER_TITLE_FAM Cover title family + $COVER_TITLE_FT Cover title font + $COVER_TITLE_SIZE_CHANGE Cover title size + $COVER_TITLE_COLOR Cover title color + $COVER_UNDERLINE_GAP Distance between baseline of the doctype + on covers and the underline + $COVER_SUBTITLE_FAM Cover subtitle family + $COVER_SUBTITLE_FT Cover subtitle font + $COVER_SUBTITLE_SIZE_CHANGE Cover subtitle size + $COVER_SUBTITLE_COLOR Cover subtitle color + $COVER_DOCTYPE_FAM Cover doctype family + $COVER_DOCTYPE_FT Cover doctype font + $COVER_DOCTYPE_SIZE_CHANGE Cover doctype size + $COVER_DOCTYPE_COLOR Cover doctype color + $COVER_COPYRIGHT_FAM Cover copyright family + $COVER_COPYRIGHT_FT Cover copyright font + $COVER_COPYRIGHT_SIZE_CHANGE Cover copyright size + $COVER_COPYRIGHT_COLOR Cover copyright color + $COVER_MISC_FAM Cover misc family + $COVER_MISC_FT Cover misc font + $COVER_MISC_SIZE_CHANGE Cover misc size + $COVER_MISC_COLOR Cover misc color + $CURRENT_EV \n[.ev] at REF_BRACKETS_START + $DC_COLOR Dropcap color + $DOC_COVER_ATTRIBUTE_COLOR Doc cover attribution string color + $DOC_COVER_AUTHOR_COLOR Doc cover author(s) color + $DOC_COVER_AUTHOR_FAM Doc cover author(s) family + $DOC_COVER_AUTHOR_FT Doc cover author(s) font + $DOC_COVER_AUTHOR_PT_SIZE Size of author on doc cover + $DOC_COVER_AUTHOR_SIZE_CHANGE Doc cover author(s) size + $DOC_COVER_CHAPTER_TITLE_COLOR Color of chapter title on doc cover + $DOC_COVER_CHAPTER_TITLE_PT_SIZE Size of chapter title on doc cover + $DOC_COVER_COLOR Overall doc cover color + $DOC_COVER_COPYRIGHT_COLOR Doc cover copyright color + $DOC_COVER_COPYRIGHT_FAM Doc cover copyright family + $DOC_COVER_COPYRIGHT_FT Doc cover copyright font + $DOC_COVER_COPYRIGHT_PT_SIZE Size of copyright info on doc cover + $DOC_COVER_COPYRIGHT_SIZE_CHANGE Doc cover copyright size + $DOC_COVER_DOCTYPE_COLOR Doc cover doctype color + $DOC_COVER_DOCTYPE_FAM Doc cover doctype family + $DOC_COVER_DOCTYPE_FT Doc cover doctype font + $DOC_COVER_DOCTYPE_PT_SIZE Size of doctype on doc cover + $DOC_COVER_DOCTYPE_SIZE_CHANGE Doc cover doctype size + $DOC_COVER_MISC_COLOR Doc cover misc color + $DOC_COVER_MISC_FAM Doc cover misc family + $DOC_COVER_MISC_FT Doc cover misc font + $DOC_COVER_MISC_SIZE_CHANGE Doc cover misc size + $DOC_COVER_FAM Overall doc cover family + $DOC_COVER_LEAD_ADJ String appended to DOC_LEAD to arrive at base + leading of doc covers + $DOC_COVER_SUBTITLE_FAM Doc cover subtitle family + $DOC_COVER_SUBTITLE_FT Doc cover subtitle font + $DOC_COVER_SUBTITLE_PT_SIZE Size of subtitle on doc cover + $DOC_COVER_SUBTITLE_SIZE_CHANGE Doc cover subtitle size + $DOC_COVER_SUBTITLE_COLOR Doc cover subtitle color + $DOC_COVER_TITLE User-defined doc cover title string + $DOC_COVER_TITLE_<n> Doc cover title items + $DOC_COVER_TITLE_COLOR Doc cover title color + $DOC_COVER_TITLE_FAM Doc cover title family + $DOC_COVER_TITLE_FT Doc cover title font + $DOC_COVER_TITLE_PT_SIZE Size of title on doc cover + $DOC_COVER_TITLE_SIZE_CHANGE Doc cover title size + $DOC_FAM Predominant font family used in the + document + $DOC_QUAD Quad used for body text (justified or + left) + $DOC_TITLE Concatenated args passed to DOCTITLE + $DOC_TITLE_<n> DOCTITLE items + $DOC_TYPE Document type (default, chapter, named, + letter) + $DOCCOVER_UNDERLINE_GAP Distance between baseline of doctype and the + underline on covers + $DOCHEADER_COLOR Color of docheader + $DOCHEADER_FAM Family used for all parts of the docheader + $DOCHEADER_QUAD Quad direction (LRC) of docheader + $DOCHEADER_LEAD_ADJ +|- value applied to #DOC_LEAD to + in/decrease leading of doc header + $DOCTYPE_COLOR Color of DOCTYPE string in doc header + $DOCTYPE_FAM Family to use for DOCTYPE string in + doc header + $DOCTYPE_FT Font to use for DOCTYPE string in + doc header + $DOCTYPE_SIZE_CHANGE ps in/decrease of DOCTYPE string in + doc header + $DOCTYPE_PT_SIZE Absolute ps of DOCTYPE + $DOCTYPE_UNDERLINE_GAP Distance between baseline of DOCTYPE and the + underline in doc header + $DRAFT The draft number (string valued) + $DRAFT_STRING What to print whenever the word "draft" + is required + EN_MARK Inline, gets #EN_MARK (\(ln) + $EN_CLOSE_BRACKET Close bracket for line-number enumerated + endnotes + $EN_FAMILY Family for endnotes + $EN_FT Font for endnotes + $EN_LEAD Leading of endnotes pages + $EN_LINENUMBER String to print for line-number enumerators + in line-numbered endnotes + $EN_LN_FAM Family for line-numbers in line-number + identified endnotes + $EN_LN_FT Font for line-numbers in line-number + identified endnotes + $EN_LN_GAP Gap to leave in initial endnote lines + between line-number identifies and text + $EN_LN_SEP User-defined separator to use between line + number(s) and endnotes when endnotes are + identified by line number + $EN_LN_SIZE_CHANGE Size change (+ or -) for line-numbers in + line-number identified endnotes + $EN_OPEN_BRACKET Open bracket for line-number enumerated + endnotes + $EN_PN_STYLE Pagenumbering style for endnotes pages + $EN_QUAD Quad for endnotes + $EN_STRING Endnotes page head + $EN_STRING_FAM Endnotes page head family + $EN_STRING_FT Endnotes page head font + $EN_STRING_QUAD Endnotes page head quad direction + $EN_STRING_RULE_GAP Distance between rules when EN_STRING is + double-underlined + $EN_STRING_UNDERLINE_GAP Distance between baseline of EN_STRING and + underline rule + $EN_STRING_SIZE_CHANGE Endnotes page head size + $EN_TITLE Endnote document identifier + $EN_TITLE_FAM Endnote document identifier family + $EN_TITLE_FT Endnote document identifier font + $EN_TITLE_QUAD Endnote document identifier quad + direction + $EN_TITLE_SIZE_CHANGE Endnote document identifier size + $EN_TITLE_UNDERLINE_GAP Distance between baseline of EN_TITLE and + underline rule + $EN_NUMBER_FAM Endnote numbering family + $EN_NUMBER_FT Endnote numbering font + $EN_NUMBER_SIZE_CHANGE Endnote numbering size + $EPI_AUTOLEAD Autolead value (decimals ok) of + epigraphs + $EPI_COLOR Color of epigraphs + $EPI_FAM Family to use in epigraphs + $EPI_FT Font to use in epigraphs + $EPI_OFFSET_VALUE Arg passed to EPIGRAPH_INDENT if the + arg has a unit of measure appended to it + $EPI_QUAD Quad in block-style epigraphs + (justified or left) + $EPI_SIZE_CHANGE ps in/decrease of epigraphs + $EVAL_BIB_SPACE Temporary string to find out if the + arg to BIBLIOGRAPHY_SPACING ended in "v" + $EVAL_EI_ARG Temporary string to find out whether + the arg to EPIGRAPH_INDENT ended with + a unit of measure + $EVAL_QI_ARG Temporary string to find out whether + the arg to QUOTE_INDENT ended with + a unit of measure + eval*[B Used to get substring of \*([B + eval*[S Used to get substring of \*([S + eval*[s Used to get substring of \*([s + $FINIS_COLOR Color of FINIS string + $FINIS_STRING What to print when FINIS macro is + invoked + float-adj:bottom A + or - sign + float-adj:top A + or - sign + float*type Used with tbl; 'boxed' or 'table' + FN_MARK Inline, gets #FN_MARK ( \n[ln] ) + $FN_CLOSE_BRACKET Close bracket for line-number identified + footnotes + $FN_FAM Family used in footnotes + $FN_FT Font used in footnotes + $FN_LINENUMBER String to print before footnotes when + line-numbering enabled for footnotes + $FN_LN_SEP Separator after line-number identified + footnotes + $FN_OPEN_BRACKET Open bracket for line-number identified + footnotes + $FN_QUAD Quad used in footnotes + $FN_SIZE_CHANGE ps in/decrease of footnotes + $FN_SPACE Post footnote space + $FOOTNOTE_COLOR Footnote color + $FTR_RECTO_QUAD Quad direction of footer recto + $FTR_RECTO_STRING String for footer recto + $FTR_VERSO_QUAD Quad direction of footer verso + $FTR_VERSO_STRING String for footer verso + $HDR_RECTO_QUAD Quad of header recto + $HDR_RECTO_STRING String for header recto + $HDR_VERSO_QUAD Quad of header verso + $HDR_VERSO_STRING String for header verso + +**Note: "header", in the descriptions below, means either headers or footers + $HDRFTR_CENTER What to put in CENTER part of headers; + default doctype + $HDRFTR_CENTER_COLOR Color of CENTER part of headers + $HDRFTR_CENTER_FAM Family of CENTER part of headers + $HDRFTR_CENTER_FT Font of centre part of headers + $HDRFTR_CENTER_NEW HDRFTR_CENTER after the start of TOC; + defined in HDRFTR_CENTER if + HDRFTR_CENTER is called as + FOOTER_CENTER + $HDRFTR_CENTER_OLD HDRFTR_CENTER just prior to start of + TOC; defined in HDRFTR_CENTER if + HDRFTR_CENTER is called as + FOOTER_CENTER + $HDRFTR_CENTER_SIZE_CHANGE ps in/decrease of centre title in + headers + $HDRFTR_COLOR Color of headers/footers + $HDRFTR_FAM Family to use in headers + $HDRFTR_LEFT_COLOR Color of LEFT part of headers + $HDRFTR_LEFT_FAM Family of left part of headers + $HDRFTR_LEFT_FT Font of left part of headers + $HDRFTR_LEFT_SIZE_CHANGE ps in/decrease of author in headers + $HDRFTR_LEFT What to put in left part of headers; + default author + $HDRFTR_RIGHT_COLOR Color of RIGHT part of headers + $HDRFTR_RIGHT_FAM Family of right part of headers + $HDRFTR_RIGHT_FT Font of right part of headers + $HDRFTR_RIGHT_SIZE_CHANGE ps in/decrease of right part of + headers + $HDRFTR_RIGHT What to put in right part of headers; + default title + $HDRFTR_RULE_COLOR Color of header rule + $HDRFTR_SIZE_CHANGE ps in/decrease of headers + $HDRFTR_TMP_SIZE_CHANGE_SWITCH Temporarily holds + HDRFTR_LEFT_SIZE_CHANGE if + #SWITCH_HDRFTRS=1 + $HDRFTR_TMP_SWITCH Temporarily holds HDRFTR_LEFT if + #SWITCH_HDRFTRS=1 + $HDRFTR_TMP_COLOR_SWITCH Temporarily holds HDRFTR_LEFT_COLOR if + #SWITCH_HDRFTRS=1 + $HEAD_COLOR Head color + $HEAD_FAM Family to use for section titles + $HEAD_FT Font to use for section titles + $HEAD_QUAD Quad value of section titles + $HEAD_SIZE_CHANGE ps in/decrease of section titles + $HEAD_UNDERLINE_GAP Distance between a head and the underline + $HYPHEN Vertically adjusted hyphen used around page + numbers + $LHS Holds digits on the left side of the decimal + in weight arg passed to RULE_WEIGHT + $LINEBREAK_CHAR Character that marks line breaks + $LINEBREAK_CHAR_V_ADJ +|- amount by which to raise/lower + linebreak character + $LAST_CHAR Temporary string used to discover whether + user has remembered to put a digit after + ROMAN or roman in arg to LIST + $LINEBREAK_COLOR Linebreak color + $LIST_ARG_1 The first arg to LIST (minus digits if + ROMAN or roman + $LN_COLOR Linenumber color + $LN_FAMILY Linenumber family + $LN_FONT Linenumber font + $LN_GUTTER Gutter to leave between line numbers + and text + $LN_INC 2nd arg to NUMBER_LINES as a string + $LN_NUM 1st arg to NUMBER_LINES as a string + $LN_SIZE_CHANGE ps in/decrease of linenumbers + $MISC_<n> Position of args pass to MISC + $MISC_COLOR Misc color + $MISC_COVER_<n> Misc items for cover + $MISC_DOCCOVER_<n> Misc items for doc cover + $MISC_QUAD Misc quad direction + $MN-arg<n> Sequentially numbered args passed to MNinit + MN-color Color of margin note + MN-curr Number of current margin note + MN-dir Left or right margin note + MN-font Font of margin note + MN-left-ad Fill mode of margin note + PAGE# For use in hdrftr strings where page # + is needed; \*[PAGE] + $PAGENUM_COLOR Page number color + $PAGENUM_STYLE String passed to PAGENUM_STYLE + $PAGE_NUM_FAM Family of page numbers + $PAGE_NUM_FT Font of page numbers + $PAGE_NUM_SIZE_CHANGE ps in/decrease of page numbers + $PAPER Paper size (LETTER, A4, LEGAL); + default=LETTER + $PH_COLOR Parahead color + $PH_FAM Parahead family + $PH_FT Parahead font + $PH_SIZE_CHANGE ps in/decrease of paraheads + $PH_SPACE Amount of horizontal space between a parahead + and the start of paragraph text + $PP_FT Font used in paragraphs + $RESTORE_PAGENUM_STYLE Hold previous page numbering style + $ROMAN_WIDTH<n> The digit(s) appended by user to ROMAN or + roman when LIST is invoked + $Q_LN_GUTTER Gutter between linenumbers and quotes + in quotes + $Q_OFFSET_VALUE Arg passed to QUOTE_INDENT if the + arg has a unit of measure appended to it + $QUOTE_COLOR Quote (poetic) color + $QUOTE_FAM Family to use for pquotes + $QUOTE_FT Font to use for pquotes + $QUOTE_SIZE_CHANGE ps in/decrease of pquotes + ref*post-punct Final punctuation mark of references + ref*spec!<n> Holds fields required by differing reference + types + ref*string The data passed to a reference + $REF_BIB_INDENT 2nd line indent value for references in + bibliographies + $REF_EN_INDENT 2nd line indent value for references in + endnotes + $REF_FN_INDENT 2nd line indent value for references in + footnotes + $REF_STYLE MLA bibliography-style or footnote/endnote + style; used in ref*add-<x> + $RESTORE_SS_VAR Saves \*[$SS_VAR] for use with ref*build + #REVISION The revision number (string valued) + $REVISION_STRING What to print whenever the word + "revision" is required + $RHS Holds digits on the right side of the decimal + in weight arg passed to RULE_WEIGHT + $RL_COLOR Rule color (DRH/DRV) + $RL_DEPTH Rule depth (DRH/DRV) + $RL_INDENT Left start position of rule (DRH/DRV) + $RL_LENGTH Rule length (DRH/DRV) + $RL_WEIGHT Rule weight (DRH/DRV) + $SAVED_COPYRIGHT Temporarily holds string in $COPYRIGHT + $SAVED_RULE_GAP Temporarily holds string in $RULE_GAP + $SAVED_DOC_FAM Document family in effect before COLLATE + $SAVED_PP_FT $PP_FT in effect at start of + .COLLATE; tested for and removed + in .PP + $SH_FAM Family to use in subheads + $SH_FT Font to use in subheads + $SH_SIZE_CHANGE ps in/decrease of subheads + $SH_COLOR Subhead color + $SIG_SPACE Arg passed to macro, SIGNATURE_SPACE + $SUBTITLE Concatenated args passed to SUBTITLE + $SUBTITLE_<n> Subtitle items for doc header + $SUBTITLE_COLOR Color of subtitle + $SUBTITLE_COVER_<n> Subtitle items for cover + $SUBTITLE_DOCCOVER_<n> Subtitle items for doc cover + $SUBTITLE_FAM Family to use for subtitle in doc + header + $SUBTITLE_FT Font to use for subtitle in doc header + $SUBTITLE_SIZE_CHANGE ps in/decrease of subtitle + $SUBTITLE_PT_SIZE Absolute ps of subtitle + $SUITE The #SUITE number register + tbl*center 'C' if set + tbl*label Text of tbl caption + tbl*needs # of rows of tbl data required to print + tbl near bottom of page + tbl*user-add-space User-added space before a tbl caption + $TITLE Concatenated args pass to TITLE + $TITLE_<n> Title items + $TITLE_COLOR Color of title + $TITLE_FAM Family to use for title in doc header + $TITLE_FT Font to use for title in doc header + $TITLE_PT_SIZE Absolute point size of title in docheader + $TITLE_SIZE_CHANGE ps in/decrease of title in doc header + $TOC_AUTHORS What to print after toc doc title entry + if #TOC_AUTHORS=1 + $TOC_FAM Family to use on toc pages + $TOC_HEAD_FAM Family of toc head entries + $TOC_HEAD_FT Font of toc head entries + $TOC_HEAD_ITEM A head as collected for TOC_ENTRIES + $TOC_HEADER_FAM Family to use for "Contents" + $TOC_HEADER_FT Font to use for "Contents" + $TOC_HEADER_QUAD Quad direction of "Contents" + $TOC_HEADER_SIZE ps in/decrease of "Contents"**** + $TOC_HEADER_STRING Header string of first toc page + $TOC_LEAD Leading of toc pages + $TOC_PH_ITEM Toc parahead entry + $TOC_PN Sets up toc leaders + entry pn + (typeset) + $TOC_PN_FAM Family for toc entries page numbers + $TOC_PN_FT Font for toc entries page numbers + $TOC_PN_SIZE_CHANGE ps in/decrease of toc entries page + numbers + $TOC_PN_STYLE Page-numbering style of toc pages + $TOC_PN_TYPEWRITE Sets up toc leaders + entry pn + (typewrite) + $TOC_PH_FAM Family of toc parahead entries + $TOC_PH_FT Font of toc parahead entries + $TOC_PARAHEAD_ITEM A parahead collected for TOC_ENTRIES + $TOC_SH_FAM Family of toc subhead entries + $TOC_SH_FT Font of toc subhead entries + $TOC_SH_ITEM A subhead collected for TOC_ENTRIES + $TOC_TITLE_FAM Family of toc doc title entries + $TOC_TITLE_FT Font of toc doc title entries + $TOC_TITLE_ITEM Toc document title item + $USER_SET_TITLE_ITEM User defined toc doc title entry as + set by TOC_TITLE_ENTRY + $UR_PAGINATION_STYLE Pagination style prior to endnotes + $USERDEF_HDRFTR_RECTO User defined header/footer recto string + $USERDEF_HDRFTR_VERSO User defined header/footer verso string + ++++PREPROCESSOR KEYWORDS+++ + + (eqn) EQ EN (grn) GS GE GF (pic) PS PE (refer) R1 R2 [ ] + + (tbl) TS TE TH (grap) G1 G2 (ideal) IS IE (chem) cstart cend + ++++ALIASES+++ + + +Please note: +Prior to version 1.1.9, all macros that included the word COLOR had +aliases that used COLOUR instead. This convenience has now been +removed, in an effort to reduce the size of the om.tmac file. + +Furthermore, if you want the convenience, you’ll have to edit the +om.tmac file. Simply aliasing, say, HEAD_COLOR as HEAD_COLOUR will +not work, owing to significant changes in the handling of +docelement control macros that end in _COLOR. + + ++++These aliases are for convenience, and header/footer management+++ + + BIBLIOGRAPHY_STRING_UNDERSCORE BIBLIOGRAPHY_STRING_UNDERLINE + CITATION BLOCKQUOTE + CITE BLOCKQUOTE + COL_BREAK COL_NEXT + DOC_FAM DOC_FAMILY + DOC_L_LENGTH DOC_LINE_LENGTH + DOC_L_LENGTH DOC_LINE_LENGTH + DOC_L_MARGIN DOC_LEFT_MARGIN + DOC_L_MARGIN DOC_LEFT_MARGIN + DOC_LS DOC_LEAD + DOC_PS DOC_PT_SIZE + DOC_R_MARGIN DOC_RIGHT_MARGIN + DOC_R_MARGIN DOC_RIGHT_MARGIN + ENDNOTE_STRING_UNDERSCORE ENDNOTE_STRING_UNDERLINE + ENDNOTE_TITLE_UNDERSCORE ENDNOTE_TITLE_UNDERLINE + FOOTER_CENTER_CAPS HDRFTR_CENTER_CAPS + FOOTER_CENTER HDRFTR_CENTER + FOOTER_CENTRE_CAPS HDRFTR_CENTER_CAPS + FOOTER_CENTRE HDRFTR_CENTER + FOOTER_LEFT_CAPS HDRFTR_LEFT_CAPS + FOOTER_LEFT HDRFTR_LEFT + FOOTER_PLAIN HDRFTR_PLAIN + FOOTER_RECTO HDRFTR_RECTO + FOOTER_RIGHT_CAPS HDRFTR_RIGHT_CAPS + FOOTER_RIGHT HDRFTR_RIGHT + FOOTER_RULE_GAP HDRFTR_RULE_GAP + FOOTER_RULE HDRFTR_RULE + FOOTER_VERSO HDRFTR_VERSO + HDRFTR_RULE_INTERNAL HDRFTR_RULE + HEADER_CENTER_CAPS HDRFTR_CENTER_CAPS + HEADER_CENTER HDRFTR_CENTER + HEADER_CENTRE_CAPS HDRFTR_CENTER_CAPS + HEADER_CENTRE HDRFTR_CENTER + HEADER_LEFT_CAPS HDRFTR_LEFT_CAPS + HEADER_LEFT HDRFTR_LEFT + HEADER_PLAIN HDRFTR_PLAIN + HEADER_RECTO HDRFTR_RECTO + HEADER_RIGHT_CAPS HDRFTR_RIGHT_CAPS + HEADER_RIGHT HDRFTR_RIGHT + HEADER_RULE_GAP HDRFTR_RULE_GAP + HEADER_RULE HDRFTR_RULE + HEADER_VERSO HDRFTR_VERSO + PAGENUM PAGENUMBER + PAGINATION PAGINATE + PP_FT PP_FONT + PRINT_FOOTNOTE_RULE FOOTNOTE_RULE + SWITCH_FOOTERS SWITCH_HDRFTR + SWITCH_HEADERS SWITCH_HDRFTR + TOC_LS TOC_LEAD + TOC_PS TOC_PT_SIZE + ++++These aliases are used for docelement type-style control+++ + + AUTHOR_FAMILY _FAMILY + AUTHOR_FONT _FONT + AUTHOR_SIZE _SIZE + BIBLIOGRAPHY_FAMILY _FAMILY + BIBLIOGRAPHY_FONT _FONT + BIBLIOGRAPHY_FOOTER_CENTER BIBLIOGRAPHY_HDRFTR_CENTER + BIBLIOGRAPHY_FOOTER_CENTRE BIBLIOGRAPHY_HDRFTR_CENTRE + BIBLIOGRAPHY_HEADER_CENTER BIBLIOGRAPHY_HDRFTR_CENTER + BIBLIOGRAPHY_HEADER_CENTRE BIBLIOGRAPHY_HDRFTR_CENTRE + BIBLIOGRAPHY_QUAD _QUAD + BIBLIOGRAPHY_STRING_FAMILY _FAMILY + BIBLIOGRAPHY_STRING_FONT _FONT + BIBLIOGRAPHY_STRING_QUAD _QUAD + BIBLIOGRAPHY_STRING_SIZE _SIZE + BLOCKQUOTE_AUTOLEAD Q_AUTOLEAD + BLOCKQUOTE_AUTOLEAD QUOTE_AUTOLEAD + BLOCKQUOTE_COLOR _COLOR + BLOCKQUOTE_FAMILY _FAMILY + BLOCKQUOTE_FONT _FONT + BLOCKQUOTE_QUAD _QUAD + BLOCKQUOTE_SIZE _SIZE + CHAPTER_TITLE_COLOR _COLOR + CHAPTER_TITLE_FAMILY _FAMILY + CHAPTER_TITLE_FONT _FONT + CHAPTER_TITLE_SIZE _SIZE + COVER_ATTRIBUTE_COLOR _COLOR + COVER_AUTHOR_COLOR _COLOR + COVER_AUTHOR_FAMILY _FAMILY + COVER_AUTHOR_FONT _FONT + COVER_AUTHOR_SIZE _SIZE + COVER_COLOR _COLOR + COVER_COPYRIGHT_COLOR _COLOR + COVER_COPYRIGHT_FAMILY _FAMILY + COVER_COPYRIGHT_FONT _FONT + COVER_COPYRIGHT_QUAD _QUAD + COVER_COPYRIGHT_SIZE _SIZE + COVER_DOCTYPE_COLOR _COLOR + COVER_DOCTYPE_FAMILY _FAMILY + COVER_DOCTYPE_FONT _FONT + COVER_DOCTYPE_SIZE _SIZE + COVER_FAMILY _FAMILY + COVER_MISC_COLOR _COLOR + COVER_MISC_QUAD _QUAD + COVER_SUBTITLE_COLOR _COLOR + COVER_SUBTITLE_FAMILY _FAMILY + COVER_SUBTITLE_FONT _FONT + COVER_SUBTITLE_SIZE _SIZE + COVER_TITLE_COLOR _COLOR + COVER_TITLE_FAMILY _FAMILY + COVER_TITLE_FONT _FONT + COVER_TITLE_SIZE _SIZE + DOC_COVER_ATTRIBUTE_COLOR _COLOR + DOC_COVER_AUTHOR_COLOR _COLOR + DOC_COVER_AUTHOR_FAMILY _FAMILY + DOC_COVER_AUTHOR_FONT _FONT + DOC_COVER_AUTHOR_SIZE _SIZE + DOC_COVER_COLOR _COLOR + DOC_COVER_COPYRIGHT_COLOR _COLOR + DOC_COVER_COPYRIGHT_FAMILY _FAMILY + DOC_COVER_COPYRIGHT_FONT _FONT + DOC_COVER_COPYRIGHT_QUAD _QUAD + DOC_COVER_COPYRIGHT_SIZE _SIZE + DOC_COVER_DOCTYPE_COLOR _COLOR + DOC_COVER_DOCTYPE_FAMILY _FAMILY + DOC_COVER_DOCTYPE_FONT _FONT + DOC_COVER_DOCTYPE_SIZE _SIZE + DOC_COVER_FAMILY _FAMILY + DOC_COVER_MISC_COLOR _COLOR + DOC_COVER_MISC_QUAD _QUAD + DOC_COVER_SUBTITLE_COLOR _COLOR + DOC_COVER_SUBTITLE_FAMILY _FAMILY + DOC_COVER_SUBTITLE_FONT _FONT + DOC_COVER_SUBTITLE_SIZE _SIZE + DOC_COVER_TITLE_COLOR _COLOR + DOC_COVER_TITLE_FAMILY _FAMILY + DOC_COVER_TITLE_FONT _FONT + DOC_COVER_TITLE_SIZE _SIZE + DOCHEADER_COLOR _COLOR + DOCHEADER_FAMILY _FAMILY + DOCHEADER_QUAD _QUAD + DOC_QUAD _QUAD + DOCTYPE_FAMILY _FAMILY + DOCTYPE_FONT _FONT + DOCTYPE_SIZE _SIZE + ENDNOTE_BLOCKQUOTE_AUTOLEAD Q_AUTOLEAD + ENDNOTE_BLOCKQUOTE_AUTOLEAD QUOTE_AUTOLEAD + ENDNOTE_FAMILY _FAMILY + ENDNOTE_FONT _FONT + ENDNOTE_LINENUMBER_FAMILY _FAMILY + ENDNOTE_LINENUMBER_FONT _FONT + ENDNOTE_LINENUMBER_SIZE _SIZE + ENDNOTE_NUMBER_FAMILY _FAMILY + ENDNOTE_NUMBER_FONT _FONT + ENDNOTE_NUMBER_SIZE _SIZE + ENDNOTE_QUAD _QUAD + ENDNOTE_QUOTE_AUTLOEAD Q_AUTOLEAD + ENDNOTE_QUOTE_AUTOLEAD QUOTE_AUTOLEAD + ENDNOTE_STRING_FAMILY _FAMILY + ENDNOTE_STRING_FONT _FONT + ENDNOTE_STRING_QUAD _QUAD + ENDNOTE_STRING_SIZE _SIZE + ENDNOTE_TITLE_FAMILY _FAMILY + ENDNOTE_TITLE_FONT _FONT + ENDNOTE_TITLE_QUAD _QUAD + ENDNOTE_TITLE_SIZE _SIZE + EPIGRAPH_COLOR _COLOR + EPIGRAPH_FAMILY _FAMILY + EPIGRAPH_FONT _FONT + EPIGRAPH_QUAD _QUAD + EPIGRAPH_SIZE _SIZE + FINIS_COLOR _COLOR + FOOTNOTE_COLOR _COLOR + FOOTNOTE_FAMILY _FAMILY + FOOTNOTE_FONT _FONT + FOOTNOTE_QUAD _QUAD + FOOTNOTE_SIZE _SIZE + HDRFTR_CENTER_FAMILY _FAMILY + HDRFTR_CENTER_FONT _FONT + HDRFTR_CENTER_SIZE _SIZE + HDRFTR_COLOR _COLOR + HDRFTR_FAMILY _FAMILY + HDRFTR_LEFT_FAMILY _FAMILY + HDRFTR_LEFT_FONT _FONT + HDRFTR_LEFT_SIZE _SIZE + HDRFTR_RIGHT_FAMILY _FAMILY + HDRFTR_RIGHT_FONT _FONT + HDRFTR_RIGHT_SIZE _SIZE + HDRFTR_RULE_COLOR _COLOR + HDRFTR_SIZE _SIZE + HEAD_COLOR _COLOR + HEAD_FAMILY _FAMILY + HEAD_FONT _FONT + HEAD_QUAD _QUAD + HEAD_SIZE _SIZE + LINEBREAK_COLOR _COLOR + LINENUMBER_FAMILY _COLOR + LINENUMBER_FONT _COLOR + LINENUMBER_SIZE _COLOR + LINENUMBER_COLOR _COLOR + MISC_COLOR _COLOR + MISC_QUAD _QUAD + PAGENUM_COLOR _COLOR + PAGENUM_FAMILY _FAMILY + PAGENUM_FONT _FONT + PARAHEAD_COLOR _COLOR + PARAHEAD_FAMILY _FAMILY + PARAHEAD_FONT _FONT + PARAHEAD_SIZE _SIZE + QUOTE_COLOR _COLOR + QUOTE_FAMILY _FAMILY + QUOTE_FONT _FONT + QUOTE_INDENT _INDENT + QUOTE_SIZE _SIZE + REF_INDENT INDENT_REFS + REF) REF_BRACKETS_END + REF] REF_BRACKETS_END + REF} REF_BRACKETS_END + REF( REF_BRACKETS_START + REF[ REF_BRACKETS_START + REF{ REF_BRACKETS_START + SUBHEAD_COLOR _COLOR + SUBHEAD_FAMILY _FAMILY + SUBHEAD_FONT _FONT + SUBHEAD_SIZE _SIZE + SUBTITLE_COLOR _COLOR + SUBTITLE_FAMILY _FAMILY + SUBTITLE_FONT _FONT + SUBTITLE_SIZE _SIZE + TITLE_COLOR _COLOR + TITLE_FAMILY _FAMILY + TITLE_FONT _FONT + TITLE_SIZE _SIZE + TOC_FAM _FAMILY + TOC_FAMILY _FAMILY + TOC_HEADER_FAMILY _FAMILY + TOC_HEADER_FONT _FONT + TOC_HEADER_QUAD _QUAD + TOC_HEADER_SIZE _SIZE + TOC_HEAD_FAMILY _FAMILY + TOC_HEAD_FONT _FONT + TOC_HEAD_SIZE _SIZE + TOC_PARAHEAD_FAMILY _FAMILY + TOC_PARAHEAD_FONT _FONT + TOC_PARAHEAD_SIZE _SIZE + TOC_PN_FAMILY _FAMILY + TOC_PN_FONT _FONT + TOC_PN_SIZE _SIZE + TOC_PT_SIZE _SIZE + TOC_SUBHEAD_FAMILY _FAMILY + TOC_SUBHEAD_FONT _FONT + TOC_SUBHEAD_SIZE _SIZE + TOC_TITLE_FAMILY _FAMILY + TOC_TITLE_FONT _FONT + TOC_TITLE_SIZE _SIZE + ++++These aliases are used to control underlining/underscoring weights+++ + + UNDERSCORE_WEIGHT RULE_WEIGHT + HEAD_UNDERLINE_WEIGHT RULE_WEIGHT + HEADER_RULE_WEIGHT RULE_WEIGHT + FOOTER_RULE_WEIGHT RULE_WEIGHT + FOOTNOTE_RULE_WEIGHT RULE_WEIGHT + COVER_UNDERLINE_WEIGHT RULE_WEIGHT + DOC_COVER_UNDERLINE_WEIGHT RULE_WEIGHT + ENDNOTE_STRING UNDERLINE_WEIGHT RULE_WEIGHT + ENDNOTE_TITLE UNDERLINE_WEIGHT RULE_WEIGHT + BIBLIOGRAPHY_STRING UNDERLINE_WEIGHT RULE_WEIGHT + + +

+ + + + + + + +
Back to Table of ContentsTop
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/stylesheet.css b/contrib/mom/momdoc/stylesheet.css new file mode 100644 index 0000000..9d9efa3 --- /dev/null +++ b/contrib/mom/momdoc/stylesheet.css @@ -0,0 +1,691 @@ +/* Copyright (C) 2004-2020 Free Software Foundation, Inc. */ +/* This file is part of mom, which is part of groff, a free software */ +/* project. */ + +/* You can redistribute it and/or modify it under the terms of the */ +/* "GNU General Public License" as published by the "Free Software */ +/* Foundation", version 2. + +/* The license text is available in the internet at */ +/* */ + +/* stylesheet for the mom macros documentation */ + +a:link { color: blue; text-decoration: none; } +a:hover { color: red; text-decoration: underline; } +a:visited { color: purple; text-decoration: none; } +a:visited:hover { color: purple; text-decoration: underline; } +a.header-link:visited { color: #6e70cc ; } +a.header-link:visited:hover { color: #6e70cc ; } + +a:link.quick { text-decoration: underline; } +.version /* version number for top of toc.html */ +{ + font-size: 90% ; + text-align: center ; +} + +.page /* Page setup: page color, size and border */ +{ + width: 67% ; + position: relative ; + top: 12px ; + bottom: 12px ; + margin: auto ; + padding: 12px ; + border: solid 1px #ceac8d ; + color: #302419 ; + background-color: #ffffeb ; + font: 1em/1.5em arial,sans-serif ; + font-variant-ligatures: none; +} + +.nobr /* Make a class property */ +{ + white-space: nowrap ; + hyphens: none ; +} + +/* Heads */ + +h1.docs +{ + font-family: arial,sans-serif ; + font-size: 125% ; + text-align: center ; + color: #002b56 ; + background-color: #e2f1ff ; + outline: solid 1px #99cccc ; + padding: 6px ; +} +h2.docs +{ + margin-bottom: -.25em ; + font-size: 105% ; + color: #000056 ; +} +h2.macro-group /* ie "Page setup" or "Indents" or "Multi-columns" */ +{ + margin-top: 1em ; + font-size: 120% ; + color: #000056 ; + background-color: #dfccad ; + padding: 6px ; +} +h3.docs +{ + margin-bottom: -.5em ; + font-size: 95% ; + color: #000056 ; + text-transform: uppercase ; +} +h3.appendices +{ + font-size: 100% ; + text-transform: none ; +} +h3.notes +{ + display: inline-block ; + margin-top: .5em ; +} +h3.control +{ + padding-top: .5em ; + font-size: 100% ; + text-transform: none ; +} +h3.numbered +{ + font-size: 100% ; + margin-bottom: -.5em ; +} +h3.macro-id +{ + font-size: 105% ; + color: #000056 ; + text-transform: uppercase ; + margin-top: 3px ; + margin-bottom: 0px ; +} +h4.docs +{ + font-size: 95% ; + margin-bottom: -.5em ; + color: #000056 ; +} +h4.doc-param-macros +{ + margin-top: -.5em ; +} +h4.arg-list +{ + margin-top: -.5em ; +} +h4.fields +{ + color: #302419 ; +} +h5.docs +{ + margin-bottom: -.5em ; + font-size: 95% ; + color: #000056 ; + text-transform: uppercase ; +} +ul.doc-param-macros +{ + margin-top: .75em ; + margin-left: -.5em ; +} +.control-macros-header +{ + display: inline-block ; + margin-bottom: -.25em ; + padding: 2px 6px 0 6px ; + outline: 1px solid #000058 ; + font-size: 100% ; + background-color: #e2f1ff ; +} +.control-macro +{ + font-size: 100% ; + margin-bottom: -.75em ; + color: #2f2f71 ; +} +.macro-id-overline +{ + display: inline-block ; + border-top: solid 2px #8d8775 ; + margin-bottom: .5em ; +} + +/* Paragraphs */ + +p.no-indent +{ + text-indent: 0px ; +} +p.requires +{ + font-family: arial,sans-serif ; + font-style: italic ; + text-indent: 0px ; + margin-top: .25em ; +} +p.alias +{ + font-family: arial,sans-serif ; + font-style: normal ; + text-indent: 0px ; + margin-top: .25em ; +} + +/* Horizontal rules */ + +hr /* horizontal rules need a border to be colorized) */ +{ + border: solid 1px #8d8775 ; +} +div.rule-short /* for section breaks; top/bottom margins set manually */ +{ + display: block ; + width: 25% ; + margin: auto; + clear: both ; +} +div.rule-medium /* underneath mini-tocs; top/bottom margins set manually */ +{ + display: block ; + width: 40% ; + margin: auto; + clear: both ; +} +div.rule-long /* precedes nav bar at bottom of page */ +{ + display: block ; + width: 90% ; + margin: auto; +} + +/* Boxed text */ + +.box-macro-args /* Macro name+args */ +{ + display: block ; + border: solid 1px #302419 ; + padding-top: 5px ; + padding-bottom: 3px ; + padding-left: 15px ; + padding-right: 15px ; + background-color: #ffffff ; + white-space: nowrap ; + overflow: auto ; +} +.box-code +{ + display: block ; + width: 100% ; + border: solid 1px #302419 ; + padding-top: 5px ; + padding-bottom: 18px ; + padding-left: 15px ; + padding-right: 15px ; + color: #6f614a ; + background-color: #ffffff ; + white-space: nowrap ; +} +.box-tip +{ + outline: solid 1px #ceac8d ; + padding-left: 15px ; + padding-right: 15px ; + text-align: justify ; + background-color: #f9f9d9 ; + margin-bottom: 1.5em ; + } +.box-example-layout +{ + outline: solid 1px #ceac8d ; + padding-left: 15px ; + padding-right: 15px ; + text-align: justify ; + background-color: #f9f9d9 ; + margin-bottom: 2.5em ; + } +.box-notes +{ + outline: solid 1px #ceac8d ; + padding-left: 15px ; + padding-right: 15px ; + text-align: justify ; + background-color: #f9f9d9 ; + margin-bottom: 1.5em ; + } +.box-important +{ + outline: solid 1px #ce7a65 ; + padding-left: 15px ; + padding-right: 15px ; + text-align: justify ; + background-color: #f9f9d9 ; + margin-bottom: 1.5em ; +} +p.tip +{ + padding-top: 9px ; + padding-bottom: 9px ; + text-indent: 0px ; +} +p.tip-top +{ + padding-top: 9px ; + text-indent: 0px ; +} +p.tip-bottom +{ + padding-bottom: 9px ; + text-indent: 0px ; +} + +/* Pre-formatted code */ + +span.pre /* pre-formatted multi-line blocks; indent must be exactly 2 spaces */ +{ + display: block ; + position: relative ; + top: -1em ; + margin-bottom: -1.5em ; + font-family: "Lucida Console",monospace ; + font-weight: bolder ; + font-size: 95% ; + white-space: pre ; + overflow: auto ; +} +span.defaults +{ + margin-left: 6px ; + padding-bottom: 1em ; + font-size: 95% ; +} +span.pre-in-pp +{ + display: block ; + position: relative ; + top: -1em ; + margin-bottom: -.5em ; + font-family: "Lucida Console",monospace ; + font-weight: bolder ; + font-size: 95% ; + white-space: pre ; + overflow: auto ; +} +span.important +{ + font-family: arial,sans-serif ; + font-weight: bolder ; + color: #8b0000 ; +} +span.note +{ + font-family: arial,sans-serif ; + font-weight: bolder ; + color: #443526 ; +} +span.additional-note +{ + font-family: arial,sans-serif ; + font-weight: bolder ; + font-style: italic ; + color: #443526 ; +} +span.tip +{ + font-family: arial,sans-serif ; + font-weight: bolder ; + color: #443526 ; +} +span.experts +{ + font-family: arial,sans-serif ; + font-weight: bolder ; + color: #443526 ; +} +/* Mini-tocs (usually at top of page) */ + +/* 1-column, centered mini-toc */ +ul.mini-toc-centered +{ + text-align: center ; + list-style-type: none ; + margin-left: -40px ; +} + +/* 2-column mini-toc column defs*/ +.mini-toc-col-1 +{ + float: left ; + width: 49% ; + margin-left: -10px ; +} +.mini-toc-col-2 +{ + float: left ; + width: 51% ; + clear: right ; +} + +/* 3-column mini-toc column defs */ +.col-1-definitions +{ + float: left ; + width: 32% ; + height: 55em ; + padding-bottom: 9px; + background-color: #ded4bd ; + margin-right: 2% ; +} +.col-2-definitions +{ + float: left ; + width: 32% ; + height: 55em ; + padding-bottom: 9px; + background-color: #ded4bd ; + margin-right: 2% ; +} +.col-3-definitions +{ + float: left ; + width: 32% ; + height: 55em ; + padding-bottom: 9px; + background-color: #ded4bd ; + margin-bottom: 24px ; +} + +/* List styles */ + +ul.toc +{ + margin-top: .5em ; +} +ul.no-enumerator +{ + list-style-type: none ; +} +.list-head +{ + font-family: arial,sans-serif ; + font-weight: bolder ; + font-size: 110% ; + color: #000056 ; +} +.list-head-goodies +{ + font-family: arial,sans-serif ; + font-weight: normal ; + font-size: 110% ; + color: #000056 ; +} +.no-anchor +{ + color: #302419 ; + font-weight: bold ; +} +.text-color +{ + color: #302419 ; +} +li.item +{ + font-family: arial,sans-serif ; + font-weight: normal ; + font-size: 100% ; + margin-left: -10px ; + list-style-type: disc ; +} +.mini-toc +{ + margin-top: -1em ; + font-size: 90% ; +} +.sublist +{ + margin-left: -1em ; + font-size: 90% ; + color: #302419 ; + list-style-type: disc ; +} +.sub +{ + list-style-type: circle ; +} +.normal +{ + font-style: normal ; + font-size: 100% ; +} +.normal-smaller +{ + font-weight: normal ; + color: #302419 ; + font-size: 90% ; +} +.normal-sub-sub +{ + font-weight: normal ; + color: #302419 ; + font-size: 90% ; +} + +/* Macro lists / defaults */ + +div.macro-list-container +{ + background-color: #ded4bd ; + margin-bottom: 1.5em ; +} +h3.macro-list +{ + font-size: 100% ; + color: #000056 ; + text-transform: uppercase ; + padding: 9px ; +} +ul.macro-list +{ + margin-left: -21px ; + padding-right: 12px ; + list-style-type: none ; + font-family: arial,sans-serif ; + margin-top: -1.25em ; + padding-bottom: 6px ; +} +ol.macro-list +{ + font-family: arial,sans-serif ; + margin-top: -1.25em ; + padding-bottom: 6px ; +} + +.defaults-container +{ + background-color: #e3d2b1 ; + border: 1px solid #3f2c00 ; + margin-bottom: 2.5em ; +} +h3.defaults +{ + font-size: 100% ; + color: #000056 ; + text-transform: uppercase ; + padding: 9px ; +} +p.defaults +{ + margin-top: .25em ; + margin-left: 6px ; + margin-right: 12px ; + margin-bottom: 0 ; +} +#toc-title, #toc-head, #toc-subhead, #toc-parahead +{ + display: block ; + margin-top: -1em ; + margin-bottom: -1em ; +} + +/* Bottom of page spacer */ + +div.bottom-spacer +{ + display: block ; + height: 24px ; +} + +/* General markup */ + +kbd +{ + font-family: "Lucida Console",monospace ; + font-weight: bold ; + font-size: 98% ; +} +kbd.macro-args +{ + margin-right: .5em ; + color: #6f614a ; + white-space: nowrap ; + overflow: auto ; +} + +/* tocs */ + +h1.toc +{ + font-family: arial,sans-serif ; + font-size: 175% ; + text-align: center ; + color: #002b56 ; + background-color: #e2f1ff ; + outline: solid 1px #99cccc ; + padding: 6px ; +} +h2.toc +{ + font-size: 120% ; + color: #000056 ; +} +h3.toc +{ + margin-top: -.5em ; + margin-bottom: -.5em ; + font-size: 100% ; + color: #6e70cc ; +} +.highlight +{ + font-weight: bold ; +} +.fourth-level +{ + margin-left: -1.25em ; + list-style-type: none ; +} +ul.toc-docproc +{ + margin-left: -1em ; +} +.toc-docproc-header +{ + margin-top: -.5em ; + text-transform: uppercase ; +} +a.header-link +{ + color: #6e70cc ; + font-size: 95% ; +} + +/* Examples */ + +.examples-container +{ + border: solid 1px #917963 ; + background-color: #f9f9d9 ; + padding-left: 24px ; + padding-right: 24px ; + padding-top: 3px ; + padding-bottom: 3px ; +} + +.examples +{ + font-weight: bolder ; + font-size: 98% ; + color: #524b3f ; + margin-top: 12px ; + margin-bottom: 3px ; +} + +/* definitions.html */ + +table.definitions /* mini-toc is set up as a table */ +{ + margin-top: 12px ; + text-align: left ; + margin-left: 12px ; +} +th.definitions +{ + padding-bottom: 6px ; + font-size: 120% ; + color: #000056 ; +} +dt /* definition terms in italic*/ +{ + font-style: italic ; +} +dt.no-italic +{ + font-style: normal ; +} + +/* Tables */ +table.quick-ref +{ + margin-top: .25em ; +} +table.quick-ref, th.quick-ref +{ + padding-bottom: .25em ; + font-family: "Lucida Console",monospace ; + font-weight: bold ; + text-align: left ; +} + +td +{ + padding: 0 ; + padding-left: .5em ; +} + +/* Misc */ + +span.book-title +{ + font-style: italic ; +} + +dt.params +{ + font-style: normal ; + font-weight: bold ; +} + +dd.cover-args +{ + margin-bottom: .25em; + margin-left: 1.25em ; +} diff --git a/contrib/mom/momdoc/tables-of-contents.html b/contrib/mom/momdoc/tables-of-contents.html new file mode 100644 index 0000000..1f9affb --- /dev/null +++ b/contrib/mom/momdoc/tables-of-contents.html @@ -0,0 +1,1224 @@ + + + + + + + + + Mom -- Document processing, tables of contents + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: Bibliographies and references
+ +

Tables of contents

+ + + +

+ +

Introduction to tables of contents

+ +

+Want a table of contents for your document? Easy. Just enter +
+ + .TOC + +as the very last macro of your input file. Mom will have picked +up all document titles (in +collated +documents) and headings, as well as the endnotes section and +bibliography, if they exist, and assigned them the appropriate page +number. Talk about a no-brainer! +

+ +

+That said, tables of contents have even more control macros than +endnotes. As always, the reason for so many control macros is so +that if you want to change just about any aspect of the table of +contents’ typographic appearance, you can. +

+ +

Tables of contents appearance and behaviour

+ +

+When you output a table of contents (with +.TOC), +mom finishes processing the last page of your document then breaks +to a new page for printing the table of contents. +

+ +

+Mom follows standard typesetting conventions for tables of contents. +To this end, if +HEADERS +are enabled for the document, the first page of the table of +contents has no page header, but does have a first page number +(roman numeral), always “i”, in the bottom margin. If +FOOTERS +are enabled for the document, the first page has neither a footer, +nor a page number in the top margin. (If you absolutely must have +a page footer on the first page of the table of contents, simply +invoke +.FOOTER_ON_FIRST_PAGE +immediately before .TOC.) Subsequent table of contents +pages have both page headers or footers and a page number. +

+ +

+Entries in a table of contents are hierarchically indented, as you +would expect, and if headings are numbered in the body of the document, +you can instruct mom to number them in the table of contents as +well (see +TOC_ENTRY_NUMBERS). +

+ +

+Tables of contents are never set in columns, regardless of whether +the rest of the document is. Lastly, if +recto/verso +printing is enabled, the table of contents respects it. This +sometimes leads to tables of contents that begin with the wrong +margins, but the margins can be corrected either by outputting a +BLANKPAGE +or by using the control macro +TOC_RV_SWITCH. +

+ +

+The overall table of contents +family, +point size +and +lead +can be altered with +control macros, +as can the family, +font, +point size and indent of each level of entry. Furthermore, the page +numbering style can be changed, as can the amount of visual space +reserved for entry page numbers. +

+ +

PDF output

+ +

+When files containing a table of contents are processed with +pdfmom, +entries in the table of contents are clickable links when the +document is viewed at the screen. The colour of the links is the +last .PDF_LINK_COLOR in effect, so if you wish another +colour, it should be set just before issuing .TOC. +

+ +

+When preparing files for printing, coloured links in both the table +of contents and elsewhere in the document may not be desirable. +You can disable the colour by passing +pdfmom +the -c option, like this:
+ + pdfmom -c doc.mom > doc.pdf + +

+ +

Positioning the Table of Contents

+ +

+Because a table of contents can’t be generated until the +end of a document (hence the last macro in the file), it is also +the last page of the document. While this is desirable for some +language conventions—French, for example—it is not +desirable for others. +

+ +

Automatic PDF relocation of the Table of Contents

+ +

+When +pdfmom +is used to process files with a table of contents, the macro +.AUTO_RELOCATE_TOC can be used to reposition the table +of contents to the top of the output document, with the presence +of a cover and/or title page sensibly taken into account. Full +AUTO_RELOCATE_TOC usage is described in the manual, +Producing PDFs with groff and mom. +

+ +

+In order to take advantage of automatic table of contents +repositioning, you must use +pdfmom +with groff’s native PDF driver (i.e. without the +-Tps flag). Files that need to be processed with +the -Tps flag require you to reposition the table +of contents yourself with psselect, described +below. +

+ +
+

+Note: +AUTO_RELOCATE_TOC must come before +START. +

+
+ +

Using psselect to relocate the Table of Contents in PostScript documents

+ +

+To change the location of the table of contents in files +processed with pdfmom -Tps, you have two choices: +rearrange the pages by hand (okay for one or two hard copies), +or use the psselect programme provided by the +psutils suite of tools (which you may have to +install as a package from your distribution if it is not already on +your system). +

+ +

+The procedure for using psselect to put the +table of contents near the beginning of a document begins by +you determining how many pages it contains. You can do this by +previewing the document with the document viewer of your choice +(gv, Okular, Evince, etc). +

+ +

+Once you know the number of pages in the table of contents, you use +psselect to place them where you want. +

+ +

+Say, for example, the table of contents runs to just one page. The +command to place a one-page table of contents at the start of a +document is: +
+ + psselect -p _1,1-_2 + +The -p option instructs psselect that what +follows is a comma-separated list of the order in which you want +pages of a document rearranged. The underscore character means +"counting backwards from the end of the document". Thus, the above +says: "Put the last page first (i.e. the table of contents), followed +by all pages from the original first page up to the second to last +(i.e. the last page before the table of contents)." +

+ +

+If your table of contents runs to two pages, the option to +psselect would look like this: +
+ + psselect -p _1-_2,1-_3 + +If your table of contents runs to two pages and you have a cover +page, the command would look like this: +
+ + psselect -p 1,_1-_2,2-_3 + +

+ +
+

+Note: +psselect outputs to stdout, so you have to redirect the +output to a new file. +
+ + psselect -p <page list> <file>.ps > <new-file>.ps + +

+
+ + + +
+

The TOC macro

+
+ +
+Macro: TOC [ INCLUDE_TITLE ] +
+ +

+If you want a table of contents, just place .TOC at the +very end of your document. Mom takes care of the rest. +

+ +

+The optional argument, INCLUDE_TITLE, is needed only +if your document is standalone, i.e. is not collated, for example +an essay. By default, mom does not include the title (and page +number) of standalone documents in the Table of Contents since it +is largely redundant. If you would like her to include the title, +invoke .TOC with INCLUDE_TITLE. +

+ +
+

+Note: +If the last line of text in a document, before .TOC, +falls too close to the bottom margin, or if the line is followed +by a macro likely to cause a linebreak (e.g. .LIST OFF or +.IQ), mom may output a superfluous blank page before the +Table of Contents. +

+ +

+In order to avoid this, insert +.EL +after the last line of text, before .TOC and/or any +concluding macros. For example, +
+ + some concluding text. + .EL + .TOC + +or +
+ + some concluding text. + .EL + .LIST OFF + .TOC + +

+
+ +
+

TOC heading

+
+ +
+Macro: TOC_HEADING "<single line TOC heading>" +
+

+• Argument must be enclosed in double-quotes +

+ +

+You may sometimes want to insert a line of text into the table of +contents without it referring to a page number, for example to +identify a “Part I” and a “Part II”. +

+ +

+Placed before any instance of the +START +macro, TOC_HEADING inserts its text into the table of contents +before the next section title or heading. A modest amount of +whitespace is introduced above and beneath to distinguish it easily +from table of contents entries. +

+ +

+The appearance of the heading may be controlled with +the macro +TOC_HEADING_STYLE. +

+ + +

+ +

Control macros for tables of contents

+ +

+Aside from allowing you to set the style of table of contents +entries on a per-level basis, the control macros let you design +the table of contents as if they were a complete document unto +themselves (overall family, headers/footers, pagination, etc). +

+ + + +

1. General tables of contents style control

+ + + +
+Macro: TOC_FAMILY <family> +
+ +

+TOC_FAMILY establishes the default family for every page element in +a table of contents, including the table of contents’ header +string (by default, “Contents”) and the page +number in the top or bottom margin. The default is the prevailing +document family. +

+ +

+All page elements in the table of contents also have their own +_FAMILY control macros, which can be used on a case-by-case basis to +override the default family set with TOC_FAMILY. +

+ + + +
+Macro: TOC_PT_SIZE <base type size of the toc> +
+ +

+• Does not require a unit of measure; points is assumed +

+ +

+Unlike most other control macros that deal with size of document +elements, TOC_PT_SIZE takes as its argument an absolute value, +relative to nothing. (Compare this with the +_SIZE +control macros.) The argument represents the base point size +of tables of contents from which the size of all other table of +contents elements are calculated. +

+ +

+The default for +PRINTSTYLE TYPESET +is 12.5 points (the same default size used in the body of the +document). +

+ + + +
+Macro: TOC_LEAD <leading of the toc> [ ADJUST ] +
+ +

+• Does not require a unit of measure; points is assumed +

+ +

+Unlike most other control macros that deal with leading of document +elements, TOC_LEAD takes as its argument an absolute value, relative +to nothing. Therefore, the argument represents the +leading +of tables of contents in +points +unless you append an alternative +unit of measure. +For example, +
+ + .TOC_LEAD 14 + +sets the base leading of tables of contents to 14 points, whereas +
+ + .TOC_LEAD .5i + +sets the base leading of tables of contents to 1/2 inch. +

+ +

+If you want the leading of tables of contents adjusted to fill the +page, pass TOC_LEAD the optional argument ADJUST. (See +DOC_LEAD_ADJUST +for an explanation of leading adjustment.) +

+ +

+The default for +PRINTSTYLE TYPESET +is the prevailing document lead (16 by default), adjusted. +

+ +
+

+Note: +Even if you give mom a .DOC_LEAD_ADJUST OFF command, +she will still, by default, adjust the leading of the table of +contents. You must enter +TOC_LEAD <lead> with no ADJUST +argument to disable this default behaviour. +

+ +

+Additional note: +Tables of contents are always double-spaced in +PRINTSTYLE TYPEWRITE, +regardless of whether the body of the document is single-spaced. +

+
+ +

2. Page numbering

+ +

+The pagination style of tables of contents is controlled by the same +macros that control +document page numbering, +except +PAGENUM +(tables of contents always start on page 1). The defaults are the +same as for the rest of the document, with the exception that tables +of contents, by default, have roman numeral page numbers. +

+ +

+Therefore, if you wish to change some aspect of table of contents +pagination style, use the +document pagination control macros +immediately prior to .TOC. +

+ +

+A special macro, +TOC_PAGENUM_STYLE, +controls the style of table of contents pagination (i.e. the actual +table of contents pages’ numbers, not the page number +references of entries). +

+ + + +
+Macro: PAGINATE_TOC <toggle> +
+ +

+By default, mom paginates tables of contents. If you’d like +her not to, do +
+ + .PAGINATE_TOC OFF + +(or NO, X, etc). +

+ +
+

+Note: +Simply invoking +.PAGINATION OFF +or +.PAGINATE OFF +disables table of contents pagination for the first +page of the table of contents only. You must use +.PAGINATE_TOC OFF to disable table of contents +pagination completely, even if pagination is turned off elsewhere in +your document. +

+
+ + + +
+Macro: TOC_PAGENUM_STYLE <DIGIT | ROMAN | roman | ALPHA | alpha> +
+

+See +PAGENUM_STYLE +for an explanation of the arguments. +

+ +

+By default, mom uses roman numerals to number table of contents +pages. Use TOC_PAGENUM_STYLE if you’d prefer something else. +For example, to have standard digits instead of roman numerals, do +the following: +
+ + .TOC_PAGENUM_STYLE DIGIT + +

+ +

3. Header string and style

+ +

+The table of contents header string is the title that appears at the top of the +table of contents. By default, it’s “Contents”.

+ +
+Macro: TOC_HEADER_STRING <string> +
+ +

+If you’d like the title of the table of contents to read +something other than “Contents”, do, for +example +
+ + .TOC_HEADER_STRING "Table of Contents" + +

+ +
Header string vertical placement
+ +
+Macro: TOC_HEADER_V_POS <distance from top of page> +
+

+• Requires a unit of measure +

+ +

+Normally, the TOC header string falls at the same vertical position +as the +docheader. +If you’d like it to fall at a different position, say 2 inches, use +
+ + .TOC_HEADER_V_POS 2i + +

+ +
Header string control macros and defaults
+ +
+

+See +Arguments to the control macros. +
+The following TOC_HEADER control macros may also be +grouped +using TOC_HEADER_STYLE. +

+ +.TOC_HEADER_FAMILY default = prevailing doc family +.TOC_HEADER_FONT default = bold +.TOC_HEADER_SIZE default = +4 +.TOC_HEADER_QUAD default = left +.TOC_HEADER_COLOR default = black +.TOC_HEADER_CAPS default = no +.TOC_HEADER_SMALLCAPS default = no +.TOC_HEADER_UNDERSCORE default = none + +
+ +

4. Entries and reference page numbers style

+ +

+“Entries” refers to the hierarchical arrangement of +section titles (in +collated +documents) and headings as they appear in the table of contents: + + Section title + Head level 1 + Head level 2 + Head level 3 + ... + +The style for title entries (e.g. chapter numbers or titles) and +heading levels is controlled by +TOC_TITLE_STYLE +and +TOC_ENTRY_STYLE +respectively. +

+ +

+“Reference page numbers” means the page numbers +associated with entries. Macros to control their style take the +form .TOC_PN_<SPEC>, and the defaults are listed +here. +

+ +
+

+See +Arguments to the control macros. + + +.TOC_PN_FAMILY default = prevailing doc family +.TOC_PN_FONT default = roman +.TOC_PN_SIZE default = 0 + +

+
+ + + +
+Macro: TOC_TITLE_STYLE <see below for args> +
+ +

+TOC_TITLE_STYLE allows you to set all the style parameters for +title entries in the tables of contents with one macro. The +number of arguments can run long, so you may want to break them into +several lines with the backslash character (\). The +arguments are: +
+ + FAMILY <family> + FONT <font> + SIZE +|-<n> + COLOR <color> + INDENT <amount> + CAPS | NO_CAPS + +The arguments may be entered in any order. +

+ +

+The family, font, size, and color arguments behave identically +to the individual control macros that govern other tags, therefore see +Arguments to the control macros +for usage. Their defaults are the same as for paragraphs in +running text. +

+ +

+INDENT lets you indent title entries by the amount specified, and +requires a +unit of measure. +The default is zero. +

+ +

+CAPS instructs mom to capitalize title entries. +Capitalization may be enabled or disabled on a per-entry-level +basis. +

+ +

+As an example, if you want title entries bold, slightly larger than other +entries and capitalized, you could do either +
+ + .TOC_TITLE_ENTRY FONT B SIZE +.5 CAPS + +or +
+ + .TOC_TITLE_ENTRY \ + FONT B \ + SIZE +.5 \ + CAPS + +

+ + + +
+Macro: TOC_ENTRY_STYLE <level> <see below for remaining args> +
+ +

+TOC_ENTRY_STYLE allows you to set individually all the style +parameters for any level of entry (beneath titles) in the tables +of contents. The number of arguments can run long, so you may +want to break them into several lines with the backslash character +(\). +

+ +

+<level> corresponds to a +HEADING +level assigned in the body of the document. The remaining arguments +are as follows. +
+ + FAMILY <family> + FONT <font> + SIZE +|-<n> + COLOR <color> + INDENT <amount> + CAPS | NO_CAPS + +The arguments may be entered in any order. +

+ +

+The family, font, size, and color arguments behave identically +to the individual control macros that govern other tags, therefore see +Arguments to the control macros +for usage. Their defaults are the same as for paragraphs in +running text. +

+ +

+INDENT lets you indent entries by the amount specified, and +requires a +unit of measure. +Mom sensibly indents and aligns all levels of entry. If you change +the indent for any level, all levels beneath it are still indented +according to mom’s normal arrangement, but with the indent +assigned to level taken into account. When you use +INDENT, the indent is measured from the left edge of +the text of the previous level, including numbering, if any. +

+ +

+CAPS instructs mom to capitalize title entries. +Capitalization may be enabled or disabled on a per-title basis. +

+ +

+As an example, if you want a particular entry level, say +“2”, to be in Helvetica, italics, and slightly larger +than other entries, you could do either +
+ + .TOC_ENTRY_STYLE 2 FAMILY H FONT I SIZE +.25 + +or +
+ + .TOC_ENTRY_STYLE 2 \ + FAMILY H + FONT I \ + SIZE +.25 + +

+ + + +
+Macro: TOC_PREFIX_CHAPTER_NUMBER <none> <anything> +
+

+Alias: TOC_PREFIX_SECTION_NUMBER +

+ +

+By default, mom does not prefix a chapter number to chapters or +section titles in the table of contents. If you would like her to +do so, invoke .TOC_PREFIX_CHAPTER_NUMBER without an +argument before +START. +

+ +

+You may subsequently disable the prefixing of chapter numbers +by supplying the macro with any argument (OFF, +QUIT, Q, X...) prior to the +.START that comes after +.COLLATE. +

+ +

+This macro is useful you want chapters numbered in the table of +contents but the chapters themselves are identified by title only. +It can be used with both +DOCTYPE CHAPTER +and +DOCTYPE DEFAULT. +The alias TOC_PREFIX_SECTION_NUMBER may be preferable +in the latter case. +

+ + + +
+Macro: PAD_TOC_CHAPTER_NUMBERS <number of chapters> +
+

+Alias: PAD_TOC_SECTION_NUMBERS +

+ + +

+If the number of chapters or major sections +(DOCTYPE DEFAULT) +exceeds 9, you can have mom pad the numbers so the rightmost +numerals of the chapter numbers align. Simply invoke +PAD_TOC_CHAPTER_NUMBERS with the number of chapters in +the document. +

+ +

+Without padding: +
+ + 9. Chapter Title.....................100 + 10. Chapter Title....................123 + +With padding: +
+ + 9. Chapter Title....................100 + 10. Chapter Title....................123 + +

+ + + +
+Macro: TOC_ENTRY_NUMBERS <FULL> <TRUNCATE> <NONE> +
+ +

+If numbering is enabled for any level of +HEADING, +mom, by default, includes the numbering in that level’s +entries in table of contents. If you would prefer that +numbering not be included in the table of contents, +issue .TOC_ENTRY_NUMBERS NONE. If +you’d like to include numbering, but not the full, +concatenated numbering used in the body of the document, issue +.TOC_ENTRY_NUMBERS TRUNCATE. +

+ +

+Assuming numbering is enabled for HEADINGs 1, 2, and 3, +.TOC_ENTRY_NUMBERS FULL (mom’s default), would +result in +
+ + 1. Level-1 entry + 1.1. Level-2 entry + 1.1.1. Level-3 entry + 2. Level-1 entry + 2.1. Level-2 entry + 2.1.1. Level-3 entry + +whereas .TOC_ENTRY_NUMBERS TRUNCATE would produce +
+ + 1. Level-1 entry + 1. Level-2 entry + 1. Level-3 entry + 2. Level-1 entry + 1. Level-2 entry + 1. Level-3 entry + +and .TOC_ENTRY_NUMBERS NONE would remove numbering +completely. +
+ + Level-1 entry + Level-2 entry + Level-3 entry + Level-1 entry + Level-2 entry + Level-3 entry + +

+ +
+

+Note: +.TOC_ENTRY_NUMBERS TRUNCATE removes the numbering +associated with table of contents chapter or section titles +when +PREFIX_CHAPTER_NUMBER +is enabled. To enable the numbering of chapter or section titles +in this circumstance, use +TOC_PREFIX_CHAPTER_NUMBER. +

+
+ +

5. Additional table of contents control macros

+ +

+The following five macros allow you to +

+ + + + +
+Macro: TOC_APPENDS_AUTHOR <none> | "<name(s) of authors>" +
+ +

+In certain kinds of collated documents, different authors are +responsible for the articles or stories contained within them. In +such documents, you may wish to have the author or authors appended +to the table of contents’ title entry for each story or +article. +

+ +

+If you invoke .TOC_APPENDS_AUTHOR without an +argument, mom appends the first argument you passed to +AUTHOR +to table of contents title entries, separated by a front-slash. +

+ +

+If you invoke .TOC_APPENDS_AUTHOR with an argument +(surrounded by double-quotes), mom will append it to the table of +contents title entries instead. This is useful if you have multiple +authors you wish to identify by last name only. For example, if +three authors—Joe Blough, Jane Doe, and John Deere—are +responsible for a single article +
+ + .TOC_APPENDS_AUTHOR "Blough et al." + +would be a good way to identify them in the table of contents. +

+ + + +
+Macro: TOC_TITLE_ENTRY "<alternate wording for a title entry in the toc>" +
+ +

+In +collated +documents, the title of each chapter appears in the table of +contents. It may sometimes happen that you don’t want the +title as it appears in the table of contents to be the same as what +appears in the +docheader. +You might, for example, want to shorten it. Or, in the case of +chapters where the docheader contains both a chapter number and a +chapter title, like this +
+ + Chapter 6 + Burning Bush — Maybe God Was Right + +you might want only the chapter title, not the chapter number, to +show up in the table of contents. (By default, .TOC +generates both.) +

+ +

+If you want to change the wording of a title entry in the table of +contents, simply invoke +
+ + .TOC_TITLE_ENTRY + +with the desired wording, enclosed in double-quotes. Using the +example, above, +
+ + .CHAPTER 6 + .CHAPTER_TITLE "Burning Bush — Maybe God Was Right" + .TOC_TITLE_ENTRY "Burning Bush" + .DOCTYPE CHAPTER + + +would identify chapter 6 in the table of contents simply as +“Burning Bush”. +

+ + + +
+Macro: SPACE_TOC_ITEMS +
+ +

+If you’d like mom to add a small amount of space between table +of contents entry levels, use .SPACE_TOC_ITEMS. Mom will +visually group entry levels in a way that’s pleasing to the +eye. The only catch to this macro is that the bottom margins of +table of contents pages may not align perfectly. +

+ +

+Please note that +SPACE_TOC_ITEMS is only available with +PRINTSTYLE TYPESET. +

+ + + + +
+Macro: TOC_PADDING <number of placeholders to allow for page number listings> +
+ +

+By default, mom allows room for 3 digits in the page number +references of table of contents entries. If you’d like some +other number of placeholders, say 2 (if your document runs to less +than 100 pages), do +
+ + .TOC_PADDING 2 + +

+ + + +
+Macro: TOC_RV_SWITCH +
+ +

+TOC_RV_SWITCH doesn’t take an argument. It simply instructs +mom to switch the left and right margins of the first table of +contents page in +recto/verso +documents should the table of contents happen to begin on an even +page when you want an odd, or vice versa. +

+ +

+The same result can be accomplished by outputting a +BLANKPAGE. +

+ +

6. I still need more!

+ +

+If there is some aspect of Table of Contents formatting for which +no TOC control macros are provided, mom has a special +toggle macro +to help out: TOC_PAGE_SETTINGS. +

+ +

+TOC_PAGE_SETTINGS allows you to enter extra formatting changes for +the Table of Contents as if it were simply another collated section +or chapter of a document. Because it’s a toggle macro, +invoking it by itself begins collecting your formatting directives, +and invoking it with any argument (OFF, QUIT, +END...) stops the collection. +

+ +

+TOC_PAGE_SETTINGS is special in that the formatting commands +contained within it must be preceded by \! (that’s +backslash-exclamation point). +

+ +

+For example, say you want to redesign the default page headers for +the Tables of Contents so that it only contains the document title +on the left and “Contents” in italics on the right, and +furthermore adjust the footer margin and footer gap, this is how +you’d do it: +
+ + .TOC_PAGE_SETTINGS + \!.HEADER_RECTO L "^\E*[$TITLE]#\*[IT]Contents\*[PREV]^" + \!.FOOTER_MARGIN 3P + \!.B_MARGIN 6P+3p + .TOC_PAGE_SETTINGS END + +(For an explanation of why the example uses .B_MARGIN to +set/change the footer gap, see +here.) +

+ +

+TOC_PAGE_SETTINGS can be put in the stylesheet section of a document +(i.e. after +PRINTSTYLE +and before +START) +or invoked just before +TOC. +

+ +

+ + + + + + + + +
Back to Table of ContentsTopNext: Bibliographies and references
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/toc.html b/contrib/mom/momdoc/toc.html new file mode 100644 index 0000000..6273751 --- /dev/null +++ b/contrib/mom/momdoc/toc.html @@ -0,0 +1,476 @@ + + + + + + + + + Mom, version 2.5_d -- Table of Contents + + + + + + + +
+ +
+ mom, version 2.5_d +
+ +

Table of Contents

+ +

+ The table of contents is large. To ease navigation, + click on any link in the +
+ Quick Table of Contents +
+ which will take you to the corresponding entry in the +
+ Detailed Table of Contents. +
+ If you’ve been using mom for a while, you may prefer the +
+ Quick Reference Guide, +
+ which gives a convenient, categorized list of mom’s + user-space macros with links to corresponding entries in the + documentation. +

+ +

+ + + +

Quick Table of Contents

+ + + + + +

+ + + +

Detailed Table of Contents

+ +
+

VERSION 2.0 NOTES

+ + + +

1. WHAT IS MOM?

+ + + +

2. DEFINITIONS OF TERMS USED IN THIS MANUAL

+ + + +

3. USING MOM

+ + + + + +

4. TYPESETTING WITH MOM

+ + + + + +

5. DOCUMENT PROCESSING WITH MOM

+ +

6. QUICK REFERENCE GUIDE

+

7. APPENDICES

+ +
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/typesetting.html b/contrib/mom/momdoc/typesetting.html new file mode 100644 index 0000000..51d199e --- /dev/null +++ b/contrib/mom/momdoc/typesetting.html @@ -0,0 +1,4988 @@ + + + + + + + + + Mom -- Typesetting Macros + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: Goodies
+ +

The typesetting macros

+ + + +

+ +

Introduction

+ +

+Mom’s typesetting macros provide access to groff’s +typesetting capabilities. Aside from controlling basic type +parameters (family, font, line length, point size, leading), +mom’s macros fine-tune wordspacing, letterspacing, kerning, +hyphenation, and so on. In addition, mom has true typesetting tabs, +string tabs, multiple indent styles, line padding, and a batch of +other goodies. +

+ +

+In some cases, mom’s typesetting macros merely imitate groff +primitives. In others, they approach typesetting concerns in +conceptually new ways (for groff, at least). This should present +no problem for newcomers to groff who are learning mom. Old groff +hands should be careful. Just because it looks like a duck and +walks like a duck does not, in this instance, mean that it is a +duck. When using mom, stay away from groff primitives if mom +provides a macro that accomplishes the same thing. +

+ +

+Mom’s typesetting macros can be used as a standalone package, +independent of the +document processing macros. +With them, you can typeset on-the-fly. Book covers, your best +friend’s rĂŠsumĂŠ, a poster for a lost dog—none of these +requires structured document processing (page headers, paragraphs, +headings, footnotes, etc). What they do demand is precise control over +every element on the page. The typesetting macros give you that +control. +

+ +

+ + + +

Paper and page setup: paper size & page margins

+ +

+The page setup macros establish the physical dimensions of your page +and the margins you want it to have. The +PAPER +macro provides a shortcut for setting the page to the correct +dimensions for a number of common paper sizes. The +PAGE +macro provides a convenient way of setting the page dimensions and +some or all of the page margins with a single macro. +

+ +
+

Important note on page dimensions and papersize

+ +

+When mom files are processed with +pdfmom, +which is recommended (see +Producing PDFs with groff and mom), +page dimensions are automatically passed to groff, and you +don’t have to worry about them. +

+ +

+Mom documents processed directly with groff, or with +pdfroff, or with pdfmom ‑Tps, require +that the papersize be given on the command line as well if the +papersize is different from the default on your system. You can +verify—or change—the default papersize by inspecting the +files +
+ + <path to groff>/font/devps/DESC + +and +
+ + <path to groff>/font/devpdf/DESC + +(See man papersize for list of valid papersize +names, as well as for instructions on how to enter a non-standard +size.) +

+ +

+If you occasionally need to print on sheets that do not +conform to your default papersize, you must, in addition +to setting the page dimensions in your mom file, pass the +-P-p<papersize> option to groff, +pdfroff, or pdfmom -Tps. +

+ +

+For example, suppose your routine papersize is “letter”, +and you need to print something on a legal-sized sheet. After +telling mom about the legal-size sheet (with either +PAGELENGTH +and +PAGEWIDTH +or +PAPER, +or +PAGE), +you must include -P-p<papersize> on whichever +command line you use, e.g. +
+ + pdfmom -Tps -mom -P-plegal + +Remember, though, that +pdfmom, +with no -Tps option, is smart enough to know the +papersize from the dimensions provided in your mom file. +

+ +

+Consult man groff, man grops and man +groff_font for additional information concerning papersizes, +as well as information on printing in “landscape” +orientation. +

+
+ +
+

Paper and page setup macros

+ + +
+ + + +
+

Page width

+
+ +
+Macro: PAGEWIDTH <width of printer sheet> +
+

+• Requires a unit of measure +

+ +

+The argument to PAGEWIDTH is the width of your printer sheet. +PAGEWIDTH requires a unit of measure. Decimal fractions are +allowed. Hence, to tell mom that the width of your printer sheet is +8-1/2 inches, you enter +
+ + .PAGEWIDTH 8.5i + +Please read the +Important note on page dimensions and papersize +for information on ensuring groff respects your PAGEWIDTH. +

+ + + +
+

Page length

+
+ +
+Macro: PAGELENGTH <length of printer sheet> +
+

+• Requires a unit of measure +

+ +

+PAGELENGTH tells mom how long your printer sheet is. It works just +like PAGEWIDTH. Therefore, to tell mom your printer sheet is 11 +inches long, you enter +
+ + .PAGELENGTH 11i + +Please read the +Important note on page dimensions and papersize +for information on ensuring groff respects your PAGELENGTH. +

+ + + +
+

Paper

+
+ +
+Macro: PAPER <paper type> [ LANDSCAPE ] +
+ +

+PAPER provides a convenient way to set the dimensions for some +common printer sheet sizes. <paper type> can +be one of: +
+ + LETTER EXECUTIVE + LEGAL 10x14 + STATEMENT A3 + TABLOID A4 + LEDGER A5 + FOLIO B4 + QUARTO B5 + +Say, for example, you have A4-sized sheets in your printer. It’s +shorter (and easier) to enter +
+ + .PAPER A4 + +than to remember the correct dimensions and enter +
+ + .PAGEWIDTH 595p + .PAGELENGTH 842p + +If you’d like landscape orientation for your paper type, +pass PAPER the LANDSCAPE argument. +

+ +

+Please read the +Important note on page dimensions and papersize +for information on ensuring groff respects your PAPER size. +

+ +
+

+Important: If you need PAPER, +it should always be placed at the very top of your file. +

+
+ + + +
+

Left margin

+
+ +
+Macro: L_MARGIN <left margin> +
+

+• Requires a unit of measure +

+ +

+L_MARGIN establishes the distance from the left edge of the printer +sheet at which you want your type to start. +Left indents +and +tabs +are calculated from the value you pass to L_MARGIN. +If you use the macros +PAGEWIDTH +or +PAPER +without setting L_MARGIN, mom automatically sets the left margin to +1 inch. +

+ +

+A unit of measure is required and decimal fractions are allowed. +Therefore, to set the left margin at 3 picas (1/2 inch), you’d +enter either +
+ + .L_MARGIN 3P + +or + + .L_MARGIN .5i + +

+ +
+

+Note: L_MARGIN behaves in a special way +when you’re using the +document processing macros. +See +Typesetting macros during document processing +for an explanation. +

+
+ + + +
+

Right margin

+
+ +
+Macro: R_MARGIN <right margin> +
+

+• Requires a unit of measure +

+ +
+

+IMPORTANT: R_MARGIN, if used, must +come after +PAPER, +PAGEWIDTH, +L_MARGIN +and/or +PAGE +(if a right margin isn’t given to PAGE). The reason is that +R_MARGIN calculates line length from the overall page dimensions and +the left margin. Mom can’t make the calculation if +she doesn’t know the page width and the left margin. +

+
+ +

+R_MARGIN establishes the amount of space you want between the end +of typeset lines and the right hand edge of the printer sheet. In +other words, it sets the line length. R_MARGIN requires a unit of +measure. Decimal fractions are allowed. +

+ +

+The line length macro +(LL) +can be used in place of R_MARGIN. In either case, the last one +invoked sets the line length. The choice of which to use is up +to you. In some instances, you may find it easier to think of a +section of type as having a right margin. In others, giving a line +length may make more sense. +

+ +

+For example, if you’re setting a page of type you know should +have 6-pica margins left and right, it makes sense to enter a left +and right margin, like this: +
+ + .L_MARGIN 6P + .R_MARGIN 6P + +That way, you don’t have to worry about calculating the line +length. On the other hand, if you know the line length for a patch +of type should be 17 picas and 3 points, entering the line length +with LL is much easier than calculating the right margin, e.g. +
+ + .LL 17P+3p + +If you use the macros +PAGE, +PAGEWIDTH +or +PAPER +without invoking .R_MARGIN afterwards, mom automatically +sets R_MARGIN to 1 inch. If you set a line length after these +macros (with +LL), +the line length calculated by R_MARGIN is, of course, overridden. +

+ +
+

+Note: R_MARGIN behaves in a special way when you’re +using the +document processing macros. +See +Typesetting macros during document processing +for an explanation. +

+
+ + + +
+

Top margin

+
+ +
+Macro: T_MARGIN <top margin> +
+

+• Requires a unit of measure +

+ +

+T_MARGIN establishes the distance from the top of the printer +sheet at which you want your type to start. It requires a unit of +measure, and decimal fractions are allowed. To set a top margin of +2-1/2 centimetres, you’d enter +
+ + .T_MARGIN 2.5c + +T_MARGIN calculates the vertical position of the first line of type +on a page by treating the top edge of the printer sheet as a +baseline. Therefore, +
+ + .T_MARGIN 1.5i + +puts the baseline of the first line of type 1-1/2 inches beneath the +top of the page. +

+ +
+

+Note: T_MARGIN means something slightly +different when you’re using the +document processing macros. +See +Top and bottom margins in document processing +for an explanation. +

+
+ +
+

+IMPORTANT: T_MARGIN does two +things: it establishes the top margin for pages that come after +it and it moves to that position on the current page. +Therefore, T_MARGIN should only be used at the top of a file (prior +to entering text) or after +NEWPAGE, +like this: +
+ + .NEWPAGE + .T_MARGIN 6P + <text> + +

+
+ + + +
+

Bottom margin

+
+ +
+Macro: B_MARGIN <bottom margin> +
+

+• Requires a unit of measure +

+ +

+B_MARGIN sets a nominal position at the bottom of the page beyond +which you don’t want your type to go. When the bottom margin +is reached, mom starts a new page. B_MARGIN requires a unit of +measure. Decimal fractions are allowed. To set a nominal bottom +margin of 3/4 inch, enter +
+ + .B_MARGIN .75i + +Obviously, if you haven’t spaced the type on your pages so +that the last lines fall perfectly at the bottom margin, the margin +will vary from page to page. Usually, but not always, the last line +of type that fits on a page before the bottom margin causes mom to +start a new page. +

+ +

+Occasionally, owing to a peculiarity in groff, an extra line will +fall below the nominal bottom margin. If you’re using the +document processing macros, +this is unlikely to happen; the document processing macros are very +hard-nosed about aligning bottom margins. +

+ +
+

+Note: The meaning of B_MARGIN is slightly +different when you’re using the document processing macros. +See +Top and bottom margins in document processing +for an explanation. +

+
+ + + +
+

Page

+
+ +
+Macro: PAGE <width> [ <length> [ <lm> [ <rm> [ <tm> [ <bm> ] ] ] ] ] +
+

+• All arguments require a unit of measure +

+ +
+

+IMPORTANT: If you’re using the +document processing macros, +PAGE must come after +PRINTSTYLE. +Otherwise, it should go at the top of a document, prior to any +text. And remember, when you’re using the document processing +macros, top margin and bottom margin mean something slightly +different than when you’re using just the typesetting macros +(see +Top and bottom margins in document processing). +

+
+ +

+PAGE lets you establish paper dimensions and page margins with a +single macro. The only required argument is page width. The rest +are optional, but they must appear in order and you can’t +skip over any. <lm>, <rm>, <tm>, and +<bm> refer to the left, right, top and bottom +margins respectively. +

+ +

+Assuming your page dimensions are 11 inches by 17 inches, and +that’s all you want to set, enter +
+ + .PAGE 11i 17i + +If you want to set the left margin as well, say, at 1 inch, PAGE +would look like this: +
+ + .PAGE 11i 17i 1i + +Now suppose you also want to set the top margin, say, at 1-1/2 +inches. <tm> comes after <rm> in the optional arguments, +but you can’t skip over any arguments, therefore to set the +top margin, you must also give a right margin. The PAGE macro would +look like this: +
+ + .PAGE 11i 17i 1i 1i 1.5i + | | + required right---+ +---top margin + margin + +Clearly, PAGE is best used when you want a convenient way to tell +mom just the dimensions of your printer sheet (width and length), or +when you want to tell her everything about the page (dimensions and +all the margins), for example +
+ + .PAGE 8.5i 11i 45p 45p 45p 45p + +This sets up an 8-1/2 by 11 inch page with margins of 45 points +(5/8-inch) all around. +

+ +

+Additionally, if you are not using the +document processing macros +and invoke PAGE with a top margin argument, any macro you invoke +after PAGE will likely move the +baseline +of the first line of text down by one linespace. To compensate, do +
+ + .RLD 1v + +immediately before entering any text. +

+ +

+Please read the +Important note on page dimensions and papersize +for information on ensuring groff respects your PAGE dimensions and +margins. +

+ + + +
+

Start a new page

+
+ +
+Macro: NEWPAGE +
+ +

+Whenever you want to start a new page, use NEWPAGE, by itself with +no argument. Mom will finish up processing the current page and move +you to the top of a new one (subject to the top margin set with +T_MARGIN). +

+ +

+ + + +

Basic typesetting parameters

+ +

+The basic typesetting parameter macros deal with fundamental +requirements for setting type: family, font, point size, leading, +and line length. +

+ +

+If you’re using the typesetting macros only, the arguments +passed to the basic parameter macros remain in effect until +you change them. The document processing macros handle things +differently. See +Typesetting macros during document processing +for an explanation. +

+ +
+

Basic parameter macros

+
    +
  • FAMILY – type family
  • +
  • FT – font
  • +
  • FALLBACK_FONT – for invalid fonts
  • +
  • PT_SIZE – point size of type
  • +
  • LS – line spacing/leading
  • +
  • AUTOLEAD – automatic line spacing
  • +
  • LL – line length
  • +
+
+ + + +
+

Type family

+
+ +
+Macro: FAMILY <family> +
+

+Alias: FAM +

+ +

+FAMILY takes one argument: the name of the +family +you want. Groff comes with a small set of basic families, each +identified by a 1-, 2-or 3-letter mnemonic. The standard families +are: +
+ + A = Avant Garde + BM = Bookman + H = Helvetica + HN = Helvetica Narrow + N = New Century Schoolbook + P = Palatino + T = Times Roman + ZCM = Zapf Chancery + +The argument you pass to FAMILY is the identifier at left, above. +For example, if you want Helvetica, enter +
+ + .FAMILY H + +

+ +
+

+Note: The font macro +(FT) +lets you specify both the type family and the desired font with +a single macro. While this saves a few keystrokes, I recommend +using FAMILY for family, and FT for font, except where doing +so is genuinely inconvenient. ZCM, for example, +only exists in one style: Italic (I). Therefore, +.FT ZCMI makes more sense than setting the family to +ZCM, then setting the font to I. +

+ +

+Furthermore, if you need to access a character from groff's Zapf +Dingbats font directly, use .FT ZD or the +inline escape +\f[ZD]. Commonly-used dingbats are +available without changing to the ZD font by using groff's +pre-defined character escapes, e.g. \[rh] for a pointing +right hand; see man groff_char for a complete list. +Dingbats that have not been pre-defined must be accessed with the +\N escape. For example, \f[ZD]\N'37' prints +the (undefined) telephone dingbat. +

+ +

+Additional note: +If you are running a version of groff lower than 1.19.2, you must +follow all FAMILY requests with a FT request, otherwise mom will set +all type up to the next FT request in the +fallback font. +

+
+ +

+If you are running a version of groff greater than or +equal to 1.19.2, when you invoke the FAMILY macro, mom +“remembers” the font style (Roman, Italic, etc) +currently in use (if the font style exists in the new family) and +will continue to use the same font style in the new family. For +example: +
+ + .FAMILY BM \" Bookman family + .FT I \" Medium Italic + <some text> \" Bookman Medium Italic + .FAMILY H \" Helvetica family + <more text> \" Helvetica Medium Italic + +However, if the font style does not exist in the new family, mom +will set all subsequent type in the +fallback font +(by default, Courier Medium Roman) until she encounters a +FT +request that’s valid for the family. For example, assuming +you don’t have the font “Medium Condensed Roman” +(mom extension “CD”) in the Helvetica family: +
+ + .FAMILY UN \" Univers family + .FT CD \" Medium Condensed + <some text> \" Univers Medium Condensed + .FAMILY H \" Helvetica family + <more text> \" Courier Medium Roman! + +In the above example, you must follow +.FAMILY H with a FT request +that’s valid for Helvetica. +

+ +

+Please see the Appendices, +Adding fonts to groff, +for information on adding fonts and families to groff, as well as +to see a list of the extensions mom provides to groff’s basic +R, I, B, BI styles. +

+ +
+

+Suggestion: When adding +families to groff, I recommend following the established standard +for the naming families and fonts. For example, if you add the +Garamond family, name the font files +
+ + GARAMONDR + GARAMONDI + GARAMONDB + GARAMONDBI + +GARAMOND then becomes a valid family name you can pass to FAMILY. +(You could, of course, shorten GARAMOND to just G, or GD.) R, +I, B, and BI after GARAMOND are the roman, +italic, bold and bold-italic fonts respectively. +

+
+ + + +
+

FT

+
+ +
+Macro: FT R | I | B | BI | <any other valid font style> +
+

+Alias: FONT +

+ +

+By default, groff permits FT to take one of four possible arguments +specifying the desired font: +
+ + R = (Medium) Roman + I = (Medium) Italic + B = Bold (Roman) + BI = Bold Italic + +For example, if your +family +is Helvetica, entering +
+ + .FT B + +will give you the Helvetica bold +font. +If your family were Palatino, you’d get the Palatino bold +font. +

+ +

+Mom considerably extends the range of arguments you can pass to FT, +making it more convenient to add and access fonts of differing +weights +and +shapes +within the same family. Have a look +here +for a list of the weight/style arguments mom allows. Be aware, +though, that you must have the fonts, correctly installed and named, +in order to use the arguments. (See +Adding fonts to groff +for instructions and information.) Please also read the +Additional note +found in the description of the FAMILY macro. +

+ +

+How mom reacts to an invalid argument to FT depends on which version +of groff you’re using. If your groff version is greater than +or equal to 1.19.2, mom will issue a warning and, depending on how +you’ve set up the +fallback font, +either continue processing using the fallback font, or abort +(allowing you to correct the problem). If your groff version is +less than 1.19.2, mom will silently continue processing, using +either the fallback font or the font that was in effect prior to the +invalid FT call. +

+ +

+FT will also accept, as an argument, a full family+font name. For +example, +
+ + .FT HB + +will set subsequent type in Helvetica Bold. However, I strongly +recommend keeping family and font separate except where doing so is +genuinely inconvenient. +

+ +

+For inline control of fonts, see +Inline Escapes, font control. +

+ + + + +
+

Fallback font

+
+ +
+Macro: FALLBACK_FONT <fallback font> [ ABORT | WARN ] +
+ +

+In the event that you pass an invalid argument to +.FAMILY +(i.e. a non-existent family), mom, by default, uses the fallback +font, Courier Medium Roman (CR), in order to continue processing +your file. +

+ +

+If you’d prefer another fallback font, pass FALLBACK_FONT the +full family+font name of the font you’d like. For example, if +you’d rather the fallback font were Times Roman Medium Roman, +
+ + .FALLBACK_FONT TR + +would do the trick. +

+ +

+Mom issues a warning whenever a font style set with +FT +does not exist, either because you haven’t registered the +style (see +here +for instructions on registering styles), or because the font style +does not exist in the current family set with +FAMILY. +By default, mom then aborts, which allows you to correct the +problem. +

+ +

+If you’d prefer that mom not abort on non-existent fonts, +but rather continue processing using a fallback font, you can pass +FALLBACK_FONT the argument WARN, either by itself, or in +conjunction with your chosen fallback font. +

+ +

+Some examples of invoking FALLBACK_FONT: +

+ +
    +
  • +.FALLBACK_FONT WARN +
    +mom will issue a warning whenever you try to access a non-existent +font but will continue processing your file with the default +fallback font, Courier Medium Roman. +
    +
  • +
  • +.FALLBACK_FONT TR WARN +
    +mom will issue a warning whenever you try to access a non-existent +font but will continue processing your file with a fallback font of +Times Roman Medium Roman; additionally, “TR” will be +the fallback font whenever you try to access a family that does not +exist. +
  • +
  • +.FALLBACK_FONT TR ABORT +
    +mom will abort whenever you try to access a non-existent font, and +will use the fallback font “TR” whenever you try to +access a family that does not exist. +
  • +
+ +

+If, for some reason, you want to revert to ABORT, just enter +.FALLBACK_FONT ABORT and mom will once again abort +on font errors. +

+ + + +
+

Point size of type

+
+ +
+Macro: PT_SIZE <size of type in points> +
+

+• Does not require a unit of measure +

+ +

+PT_SIZE (Point Size) takes one argument: the size of type in points. +Unlike most other macros that establish the size or measure of +something, PT_SIZE does not require that you supply a unit of +measure since it’s a near universal convention that type size +is measured in points. Therefore, to change the type size to, say, +11 points, enter +
+ + .PT_SIZE 11 + +Point sizes may be fractional (e.g. 10.25 or 12.5). +

+ +

+If you invoke PT_SIZE without an argument, it reverts to its former +value. For example, if your point size is 10 and you change it to +12 with .PT_SIZE 12, entering .PT_SIZE +(i.e. without an argument) resets the point size to 10. +

+ +

+You can prepend a plus or a minus sign to the argument to PT_SIZE, +in which case the point size will be changed by + or - the original +value. For example, if the point size is 12, and you want 14, you +can do +
+ + .PT_SIZE +2 + +then later reset it to 12 with + + .PT_SIZE -2 + +or, more simply, just + + .PT_SIZE + +The size of type can also be changed inline. See +Inline Escapes, changing point size. +

+ +
+

+Note: It is unfortunate that the +pic preprocessor has already taken the name, +PS, and thus mom’s macro for setting point +sizes can’t use it. However, if you aren’t using +pic, you might want to +alias +PT_SIZE as PS, since there’d be no conflict. For example +
+ + .ALIAS PS PT_SIZE + +would allow you to set point sizes with .PS. +

+
+ + + +
+

Line spacing / leading

+
+ +
+Macro: LS <distance between lines> +
+

+• Does not require a unit of measure +

+ +

+LS (Line Space) takes one argument: the distance you want, typically +in points, from baseline to baseline of type. The argument may be +fractional (e.g. 12.25 or 14.5). Like PT_SIZE, LS does not require +a unit of measure, since +leading +is most often given in points. Therefore, to set the linespace to +14 points, you would enter +
+ + .LS 14 + +However, if you wish, you may specify a unit of measure by appending +it directly to the argument passed to LS. For example, if you want +a linespace of 1/4 of an inch, enter +
+ + .LS .25i + +You can prepend a plus or a minus sign to the argument to LS, in +which case the line spacing will be changed by + or - the original +value. For example, if the line spacing is 14 points, and you want +17 points, you can do +
+ + .LS +3 + +then later reset it to 14 points with +
+ + .LS -3 + +

+ +
+

+Experts: LS should not be confused with +the groff primitive .ls. LS acts like +.vs. mom does not provide a macro analogous to +.ls. +

+
+ + + +
+

Automatic line spacing

+
+ +
+Macro: AUTOLEAD <amount of automatic leading> [FACTOR] +
+

+• Does not require a unit of measure +
+(Please see +here +for information on using +AUTOLEAD during document +processing.) +

+ +

+Without the FACTOR argument, AUTOLEAD calculates the +linespace for you by adding its argument to the current point size +of type. All subsequent +PT_SIZE +requests automatically update the linespacing by the autolead amount. +

+ +

+Used in this way, AUTOLEAD does not require a unit of measure; +points is assumed. However, you may use an alternate unit of +measure by appending it to the argument. The argument may be a +decimal fraction (e.g. .5 or 2.75). +

+ +

+As an example, if your current point size of type is 12, entering +
+ + .AUTOLEAD 2 + +changes the linespace to 14 points, regardless any linespacing +already in effect. From here on, every change to the size of type +(with PT_SIZE, not +inline) +changes the linespace as well. If you decrease the type size to 9 +points, the leading decreases to 11 points. If you increase the +type size to 16 points, the leading increases to 18 points. +

+ +

+Automatic updating of the linespacing continues until you enter a +“manual” line space value with +LS. +

+ +
+

+Experts: Please note that the groff +primitives, +.vs and .ps, are unaffected by, and have no +effect, on AUTOLEAD. +

+
+ +

+If you give AUTOLEAD the optional FACTOR argument, AUTOLEAD +calculates the line space as a factor of the +numeric argument +you gave AUTOLEAD. For example, if your point size is 12, +
+ + .AUTOLEAD 1.125 FACTOR + +sets the leading at 13.5 points. If you change the point size to +14, the leading automatically changes to 15.75 (14 x 1.125). +

+ +
+

+Note: There’s no need to prepend a +plus sign +(+) +to AUTOLEAD’s argument, although you may do so if you wish. +

+
+ + + +
+

Line length

+
+ +
+Macro: LL <line length> +
+

+• Requires a unit of measure +

+ +

+LL (Line Length) takes one argument: the distance from the left +margin of the page to the maximum allowable point on the right at +which groff should place type. The line length, in other words, as +the macro suggests. +

+ +

+LL requires a unit of measure. Therefore, to set the line length to +39 picas, you would enter +
+ + .LL 39P + +As with other macros that require a unit of measure, the argument to +LL may be fractional. For example, +
+ + .LL 4.5i + +sets the line length to 4-1/2 inches. +

+ +

+Additionally, you may express a new line length relative to the +current line length by prepending a plus or minus sign to the +argument. Thus, if you wanted to increase the line length by 3 +points, you could +do +
+ + .LL +3p + +This is especially handy when you want to “hang” +punctuation outside the right margin since you can pass +groff’s +\w +escape as the argument to LL, like this: +
+ + .LL +\w'.'u + +The above example increases the current line length by the width of +a period. Notice that you must append the +unit of measure, +u, to the escape since LL requires a unit of measure. +

+ +
+

+Note: The right margin macro +(R_MARGIN) +can also be used to set line length. +

+
+ +

+ + + +

Justification and quadding/breaking and joining lines

+ +

+The justification and quadding macros deal with how type aligns +along the left and right margins. In a nutshell, type either aligns +at the left margin, at the right margin, at both margins, or at +neither margin (centred). +

+ +

+These macros also determine whether or not +input lines +are joined and +filled +during output. +

+ +

+Additionally, macros that deal with how to break +output lines +are covered in this section, as is the +inline escape +for joining input lines. +

+ +

+You may encounter some words here that are unfamiliar. Refer to +Typesetting terms +and +Groff terms +for an explanation. +

+ +
+

Justification and quadding/breaking and joining lines macros

+
    +
  • Fill modes +
      +
    • JUSTIFY – set lines justified
    • +
    • QUAD – set filled lines flush left, right or centred
    • +
  • +
  • Nofill modes +
      +
    • LEFT – set non-filled lines flush left
    • +
    • RIGHT – set non-filled lines flush right
    • +
    • CENTER – set non-filled lines centred
    • +
  • +
  • Breaking lines +
      +
    • BR – manually break an output line
    • +
    • EL – break a line without advancing to the next output line
    • +
    • SPACE – break a line and add space before the next output line
    • +
    • SPREAD – break and force-justify an output line
    • +
  • +
  • Joining input lines in nofill mode +
      +
    • \c inline escape
    • +
  • +
+
+ + + +
+

Justify lines

+
+ +
+Macro: JUSTIFY +
+ +

+(See +fill mode +for a definition of the difference between “fill” and +“no-fill” modes.) +

+ +

+JUSTIFY doesn’t take an argument. +Input lines +after JUSTIFY are +filled +and +justified +upon output. +

+ +

+To break lines and prevent them from being filled and justified, use +the +BR +macro. +

+ + + +
+

Quad lines left, right, or centre

+
+ +
+Macro: QUAD L | LEFT | R | RIGHT | C | CENTER | J | JUSTIFY +
+ +

+Alias: FILL +

+ +

(See +fill mode +for a definition of the difference between “fill” and +“no-fill” modes.) +

+ +

+QUAD takes one argument: the direction in which lines should be +quadded. +Input lines +after QUAD are +filled +upon output. +

+ +

+If L or LEFT, type is set flush along the left +margin. +

+ +

+If R or RIGHT, type is set flush along the +right margin. +

+ +

+If C or CENTER type is set centred on the +current line length. +

+ +

+J and JUSTIFY justify text, and are +included as a convenience only. Obviously, if text is +justified, it isn’t quadded. .QUAD J and +.QUAD JUSTIFY have exactly the same effect as +JUSTIFY. +

+ +

+To break lines and prevent them from being filled, use the +BR +macro. +

+ + + +
+

Set lines flush left, right or centered in no-fill mode

+
+ +
+Macro: LEFT +
+Macro: RIGHT +
+Macro: CENTER  (alias CENTRE) +
+ +

+(See +no-fill mode +for a definition of the difference between “fill” and +“no-fill” modes.) +

+ +

+LEFT, RIGHT, and CENTER let you enter text on a line for line basis +without having to use the +BR +macro after each line. Consider the following: +
+ + .QUAD LEFT + So runs my dream, but what am I? + .BR + An infant crying in the night + .BR + An infant crying for the light + .BR + And with no language but a cry. + .BR + +Because text after .QUAD LEFT is +filled, +you have to use the +BR +macro to prevent the lines from running together. Not only is this +annoying to type, it’s awkward to read in a text editor. Much +better to do +
+ + .LEFT + So runs my dream, but what am I? + An infant crying in the night + An infant crying for the light + And with no language but a cry. + +

+ +
+

+IMPORTANT: Because LEFT, +RIGHT, and CENTER are nofill modes, groff does not always respect the +current line length. +Input lines +that run long may exceed it, or get broken in undesirable ways. +Therefore, when using these three macros, you should preview your +work to ensure that all lines fit as expected. +

+
+ + + +
+

Manually break lines

+
+ +
+Macro: BR +
+ +

+When using +JUSTIFY +or +QUAD, +BR tells mom about partial lines that you want broken (as opposed to +filled). +Any partial +output line +that immediately precedes BR will be +quadded +in the direction of the current quad, or set flush left if text is +justified. +

+ +

+Most of the time, you won’t need the BR macro. In fill modes, +mom tries to be sensible about where breaks are needed. If the +nature of a macro is such that under most circumstances you’d +expect a break, mom puts it in herself. Equally, in macros where a +break isn’t normally desirable, no break occurs. This means +text files don’t get cluttered with annoying BR’s. +

+ +
+

+Note: Lines of text in +nofill mode +never require a BR. Furthermore, in nofill mode, ALL macros cause a +break. If a break is not desired, use the +\c +inline escape. +

+ +

+Experts: BR is an alias for +.br. You can use either, or mix +’n’ match with impunity. +

+
+ + + +
+

Manually break a line without advancing on the page

+
+ +
+Macro: EL +
+ +

+In nofill modes + +(LEFT, +RIGHT, +CENTER) + +you must terminate the line input preceding +EL +with the + +\c inline escape. + +

+ +

+Suggestion: If you find remembering whether to put in the +\c +bothersome, you may prefer to use the +inline escape +alternative to EL, +\*[B], +which works consistently regardless of the fill mode. +EL does not work after the +PAD +macro. See +.PAD NOBREAK +for the way around this. +

+ +

+EL (“End Line”) +is conceptually equivalent to the notion of a carriage return with +no linefeed. Its function is simple: it breaks a line without +advancing on the page. As an example of where you might use it, +imagine that you’re working from marked-up copy. The markup +indicates 24 points of space between two given lines, but the +prevailing line spacing is 12.5 points. You may find it more +convenient to break the first line with EL and instruct mom to +advance 24 points to the next line instead of calculating the lead +that needs to be added to 12.5 to get 24. To demonstrate: +
+ + .LEFT + .LS 12.5 + A line of text.\c + .EL + .ALD 24p + The next line of text. + +may be more intuitive than +
+ + .LEFT + .LS 12.5 + A line of text. + .ALD 11.5p + The next line of text. + +The first example has the further advantage that should you wish to +change the prevailing line space but keep the 24 points lead, you +don’t have to recalculate the extra space. +

+ +

+ALD in the above examples stands for +“Advance +LeaD”, +which is covered in the section +Vertical movements. +

+ + + +
+

Break lines and add space between

+
+ +
+Macro: SPACE [<space to add between lines>] +
+

+Alias: SP +

+ +

+SPACE breaks a line, just like +BR, +then adds space after the line. With no argument, it adds an extra +line space. If you pass it a numeric argument without supplying a +unit of measure, +it advances that number of extra line spaces. For example: +
+ + .SPACE + +breaks the line then adds an extra linespace, whereas +
+ + .SPACE 2 + +breaks the line and adds two extra linespaces. +

+ +

+If you supply a unit of measure, SPACE breaks the line and advances +the specified vertical distance, as in +
+ + .SPACE 6p + +which breaks the line and advances six points further. +

+ +
+

+Tip: SPACE and +ALD +can be used interchangeably (.SPACE 6p and +.ALD 6p are equivalent). However, ALD without an +argument does nothing, whereas SPACE without an argument adds an +extra line space. I recommend using SPACE when you want an extra +line space (or multiple thereof), and ALD whenever you want some +other value of space after a line. +

+ +

+Experts: SPACE is an alias of +.sp. You can use either, or mix ’n’ match +with impunity. Because SPACE aliases .sp, it may be used +with groff’s absolute position modifier +“|” (the pipe +character) to move to a specified vertical location on the page. +Consult + + info groff “Manipulating Spacing” + +or, more simply, + + info groff sp. + +

+
+ + + +
+

Break and force justify (spread) lines

+
+ +
+Macro: SPREAD +
+ +

+Sometimes, you need to break a line of +justified +text and have it come out fully justified, not +quadded +left the way it would be with the +BR +macro. An example of where you’d do this would be when you +want to prevent a word at the end of a line from being hyphenated +(say, a proper name). SPREAD is the macro that lets you break the +line and have it came out fully justified. +

+ +
+

+Experts: SPREAD is an alias for +.brp You can use either, or mix ’n’ match +with impunity. +

+
+ + + +
+

Join input lines

+
+ +
+Inline: \c +
+ +

+Sometimes, especially when in one of the +nofill modes, +a macro will cause a break where you don’t want one. In order +to prevent this from happening (in other words, to join +input lines +together, forming one +output line), +use the groff +inline escape +\c at the end of each input line to be +joined to another, like this: +
+ + .LEFT + .FAMILY T + .FT R + Some lines of text to be \c + .FAMILY H + .FT B + joined \c + .FAMILY T + .FT R + together. + +Upon output, the lines will be joined together to read +
+ + Some lines of text to be joined together. + +with the word “joined” in Helvetica bold. Note the +spaces before \c. Without them, the last three words of +the output line would read +
+ + bejoinedtogether + +Please also note that had the example been in one of the +fill modes, +there’d have been no need for the \c. +

+ +
+

+Addendum: The example, above, is designed to demonstrate the +use of \c. An easier and more intuitive way +to accomplish the family/font change in the example would be with +the groff +inline escape, +\f, +like this: +
+ + Some lines of text to be \f[HB]joined\*[PREV] together. + +

+
+ +

+ + + +

Typographic refinements

+ +

+The macros in this section help you tweak groff’s behaviour, +ensuring that your documents look typographically professional. +

+ +
+

Typographic refinements macros

+ +
    +
  • Word and sentence spacing +
      +
    • WS – word spacing
    • +
    • SS – sentence space
    • +
  • +
  • Letter spacing (track kerning) +
  • +
  • Hyphenation +
      +
    • HY – turn auto hyphenation on/off, or set specific hyphenation parameters
    • +
    • HY_SET – set all hyphenation parameters
    • +
  • +
  • Automatic kerning and ligatures +
      +
    • KERN – turn automatic pairwise kerning on or off
    • +
    • LIGATURES – turn automatic generation of ligatures on or off
    • +
  • +
+
+ + + +
+

Word spacing

+
+ +
+Macro: WS <+|-wordspace> | DEFAULT +
+ +

+WS (Word Space) increases or decreases the amount of space between +words. In +nofill modes, +or if +QUAD +is in effect, the space between words is fixed. Therefore, if you +change the word spacing with WS, the change applies uniformly to the +space between every word on every line. However, when text is +justified, +the space between words varies from line to line (in order to +justify the text). Consequently, the change you make with WS +represents the minimum (and ideal) space groff will try to put +between words before deciding whether to hyphenate a final word or +to stretch the word spacing. +

+ +

+Word space is relative to point size. Generally, in/decreasing the +word space by a value of 1 or 2 produces a difference that in many +cases is scarcely visible. In/decreasing by a value between 3 and 5 +produces a subtle but noticeable difference. In/decreasing by a +value greater than 6 is almost always apparent. You should preview +your work to assess the effect of WS. +

+ +

+WS takes as its argument a whole number preceded by a plus or minus +sign. Therefore, to decrease the word space slightly, you might +enter +
+ + .WS -2 + +To increase it by a noticeable amount, you might enter +
+ + .WS +6 + +You can reset the word spacing to its previous value by switching +the plus or minus sign, like this: +
+ + .WS +2 + A line of text + .WS -2 + +The .WS -2 undoes the effect of +.WS +2. You can also reset WS to its groff default +by entering +
+ + .WS DEFAULT + +This can be particularly useful if you’ve been playing around +with plus and minus values, and can’t remember by how much to +in/decrease the word space to get it back to normal. +

+ + + +
+

Sentence space

+
+ +
+Macro: SS <+sentence space> | 0 | DEFAULT +
+ +

+SS (Sentence Space) tells groff how to treat double spaces it +encounters between sentences in +input lines. +If you use SS, input sentences with two spaces after them and +input sentences that fall at the end of input lines all receive a +normal word space plus an additional amount of space whose size is +determined by the + value passed as an argument to SS. Thus, +
+ + .SS +2 + +means that input sentences with two spaces after them receive a +normal word space PLUS the +2 value passed to SS. +

+ +

+Like +WS, +increasing the sentence space by a value of 1 or 2 produces a +difference that in many cases is scarcely visible. Increasing by a +value of 5 or so produces a subtle but noticeable difference (i.e., +the space between double-spaced input sentences will be slightly +but visibly greater than the space between words). Increasing by a +value greater than 10 is always apparent. You should preview your +work to assess the effect of SS. +

+ +

+There’s an additional argument you can pass SS: the number +zero (without the plus sign). It’s the argument you’ll +use most often. Typeset copy should never have two spaces between +sentences, and the "zero" argument tells groff to give the extra +spaces no space at all (effectively removing them). Therefore, if +you double-space your sentences (as you should when writing in a +text editor), get in the habit of putting +
+ + .SS 0 + +at the top of your files. +

+ +

+If you do use SS for something other than ensuring that you +don’t get unwanted sentence spaces in output copy, you can set +or reset the sentence space to the groff default (the same width +as a word space, i.e., double-spaced input sentences will appear +double-spaced on output as well) with +
+ + .SS DEFAULT + +If you’re using the +document processing macros +and your +PRINTSTYLE +is TYPEWRITE, .SS DEFAULT is the +default, because you do want double spaces between sentences in copy +that imitates the look of a typewritten document. +

+ +
+

+IMPORTANT: SS with an argument other +than 0 (zero) should only be used if you’re of +the old (and wise) school of typists that puts two spaces between +sentences. If you ignore this advice and use SS when you habitually +put only one space between sentences, you risk producing output +where the space between sentences is not equal. +

+
+ + + +
+

Automatic hyphenation control

+
+ +
+Macro: HY LINES <max. number of consecutive hyphenated lines> +
+Macro: HY MARGIN <size of hyphenation margin> +
+Macro: HY SPACE <extra interword spacing to prevent hyphenation> +
+Macro: HY DEFAULT +
+Macro: HY toggle +
+

+Aliases: HYPHENATE, HYPHENATION +

+ +

+HY, as you can see, can be invoked with a number of arguments. In +all cases, the aliases HYPHENATE or HYPHENATION can be used in place +of HY. To aid in understanding the various arguments you can pass +to HY, I’ve broken them down into separate sections. +

+ +

1.  HY

+ +

+HY by itself (i.e. with no argument) simply turns automatic +hyphenation on. Any argument other than LINES, MARGIN, SPACE, or +DEFAULT, turns automatic hyphenation off. For example, as explained +in +How to read macro arguments, +you could turn HY off by entering +
+ + .HY OFF + +or + + .HY X + +or + + .HY END + +A subsequent call to HY restores hyphenation with the parameters for +LINES, MARGIN, or SPACE that were formerly in effect (see below). +

+ +

+HY observes the following default hyphenation rules: +

+
    +
  • Last lines (i.e. ones that will spring a trap—typically + the last line on a page) will not be hyphenated. +
  • +
  • The first and last two characters of a word are never + split off. +
  • +
+ +

2.  HY LINES

+ +

+HY LINES sets the maximum number of consecutive hyphenated lines +that will appear in output copy. 2 is a very good choice, and +you’d set it with +
+ + .HY LINES 2 + +By default, when you turn automatic hyphenation on, there is no +limit to the number of consecutive hyphenated lines. +

+ +
+

+Note: +Discretionary hyphens +count when groff is figuring out how many lines to hyphenate; +explicit hyphens (i.e. the actual hyphen character) do not. +

+
+ +

3.  HY MARGIN

+ +

+HY MARGIN sets the amount of room allowed at the end of a line +before hyphenation is tripped (e.g., if there’s only 6 points +left at the end of a line, groff won’t try to hyphenate the +next word). HY MARGIN only applies if you’re using +QUAD, +and is really only useful if you’re using QUAD LEFT. +

+ +

+As an example, if you don’t want groff to hyphenate words +when there’s only 18 points of space left at the end of a +left-quadded line, you’d enter +
+ + .HY MARGIN 18p + +

+ +
+

+Note: The numeric argument after HY +MARGIN requires a +unit of measure. +

+
+ +

4.  HY SPACE

+ +

+HY SPACE sets an amount of extra interword space that groff will +try to put between words on a line in order to prevent +hyphenation. HY SPACE applies only to +justified lines. +Generally speaking, you’ll want this value to be quite small, +since too big a value will result in lines with gaping holes between +the words. A reasonable value might be half a point, or one point, +which you’d set with +
+ + .HY SPACE .5p + +or + + .HY SPACE 1p + +

+ +
+

+Note: The numeric argument after HY SPACE +requires a +unit of measure. +

+
+ +

5.  HY DEFAULT

+ +

+HY DEFAULT resets automatic hyphenation to its default behaviour, +cancelling any changes made with HY LINES, HY +MARGIN, and/or HY SPACE. +

+ +
+

Thoughts on hyphenation in general

+ +

+Hyphenation is a necessary evil. If it can be avoided, it +should be. If it can’t be, it should occur infrequently. +That’s the reason for the number of parameters you can set +with HY. +

+ +

+Furthermore, hyphenation in +rag +copy requires a great deal of attention. At best, it should be +avoided completely by individually adjusting the number of words +on consecutive lines to achieve a pleasing, natural-looking rag. +Since such adjustments are often too fussy for document processing, +I recommend playing around with HY MARGIN a bit if your copy looks +hyphen-heavy. +

+
+ + + +
+

Set hyphenation parameters all at once

+
+ +
+Macro: HY_SET <lines> [ <margin> [ <space> ] ] +
+ +

+Alias: HYSET +

+ +

+HY_SET lets you set the parameters for hyphenation +with a single macro. <lines>, +<margin>, and +<space> correspond to the numeric +values required by LINES, +MARGIN, and SPACE as described +above. +

+ +

+To set just the maximum number of consecutive hyphenated lines, +you’d enter +
+ + .HY_SET 2 + +If you wanted the same number of maximum consecutive hyphenated +lines and a hyphenation margin for use with +rag +copy, +
+ + .HY_SET 2 36p + +would set the hyphenation margin to 36 points. +

+ +

+If you wanted the same number of maximum consecutive hyphenated +lines and a hyphenation space of 2 points for use with +justified +copy, +
+ + .HYSET 2 0 2p + +is how you’d do it. +

+ + + +
+

Reduce whitespace

+
+ +
+Macro: RW <amount of whitespace reduction between letters> +
+ +

+RW (Reduce Whitespace) +and its corresponding macro +EW (Expand Whitespace), +allow you to tighten (or loosen) +output lines +by uniformly reducing or expanding the space between characters. +This is particularly useful when you want to squeeze or stretch +lines on a narrow measure. +

+ +

+The value passed to RW may be a whole number or a decimal fraction. +Since a value of 1 produces a noticeable reduction in the space +between letters at text sizes, you’ll most likely use small +decimal values when tightening lines. For example, +
+ + .RW .1 + +or + + .RW .2 + +may be just enough to squeeze an extra character or two on a line +without the change in letter spacing being obvious. I highly +recommend previewing your work to assess the effect of RW. +

+ +
+

+Note: By default, RW does not deposit a +break +when it’s invoked if you’re in one of the +fill +modes (i.e. +QUAD +L, R, C, J, or +JUSTIFY). +If you want +RW to break at the ends of the previous +input lines +while you’re in a fill mode, tell mom +that’s what you want by invoking +.BR_AT_LINE_KERN. +

+
+ +
+

+IMPORTANT: +RW (and its complement, EW, see below) only affects the current +font, and remains in effect for that font every time it’s +called, hence it must be reset to zero to cancel its effect +(.RW 0). +

+
+ + + +
+

Expand whitespace

+
+ +
+Macro: EW <amount of whitespace expansion between letters> +
+ +

+EW (Expand Whitespace) +expands the amount of whitespace between letters, effectively +“loosening” lines of type. +

+ +

+The value passed to EW may be a whole number or a decimal fraction. +Since a value of 1 produces a noticeable expansion in the space +between letters at text sizes, you’ll most likely use small +decimal values when loosening lines. For example, +
+ + .EW .1 + +or + + .EW .2 + +may be just enough to open up a line without the change in letter +spacing being obvious. I highly recommend previewing your work to +assess the effect of EW. +

+ +
+

+Note: By default, EW does not deposit a +break +when it’s invoked if you’re in one of the +fill +modes (i.e. +QUAD +L, R, C, J, or +JUSTIFY). +If you want +EW to break at the ends of the previous +input lines +while you’re in a fill mode, tell mom that’s what you +want by invoking the +.BR_AT_LINE_KERN +toggle macro. +

+
+ +
+

+IMPORTANT: +EW (and its complement, RW, see above) only affects the current +font, and remains in effect for that font every time it’s +called, hence it must be reset to zero to cancel its effect +(.RW 0). +

+
+ + + +
+

Break before line kerning

+
+ +
+Macro: BR_AT_LINE_KERN toggle +
+ +

+By default, in +fill +modes (i.e. +QUAD +L, R, C, J, or +JUSTIFY) +mom does not break +input lines +when you invoke +RW +or +EW. +If you’d like her to break input lines prior to RW or EW, +invoke .BR_AT_INPUT_LINE without any argument. To +disable the breaks, invoke .BR_AT_INPUT_LINE with any +argument (OFF, QUIT, END, +X...), like this +
+ + .BR_AT_LINE_KERN OFF + +or + + .BR_AT_LINE_KERN X + +With QUAD L, R, or C, mom simply breaks the line. With QUAD J (or +just JUSTIFY, which is the same thing), she breaks and +force justifies +the line prior to .EW or .RW. +

+ + + +
+

Automatic kerning

+
+ +
+Macro: KERN toggle +
+ +

+By itself (i.e. with no argument), KERN turns automatic pairwise +kerning +on. With any argument (e.g. OFF, Q, +X), pairwise kerning is turned off. +

+ +

+Kerning of individual character pairs can be controlled with the two +inline escapes +
+\*[BU <n>] and +\*[FU <n>]. See +Inline Escapes, kerning. +

+ + + +
+

Automatic ligature generation

+
+ +
+Macro: LIGATURES toggle +
+

+Alias: LIG +

+ +

+Provided your current font has +ligatures, +LIGATURES, by itself, turns on automatic generation of ligatures. +When automatic ligature generation is on, simply typing the letters +of a ligature combination will produce the correct ligature upon +output. For example, if you type the word “finally”, +the fi combination will be output as an fi ligature. Generally +speaking, ligatures are A Good Thing, hence mom has them on by +default. +

+ +

+LIGATURES with any argument turns automatic ligature generation off. +

+ +
+

+Note: Not all fonts support ligatures. +

+
+ +

+ + + +

Type modifications (pseudo font styles)

+ +

+It sometimes happens that a +family +doesn’t contain all the fonts you need. You might, for +example, be missing an italic font, or a bold font. Or you might +not be able to get your hands on the condensed version. That’s +where these macros and inline escapes come in. With them, you +can fake the fonts you’re missing. A word of caution, +though: “faked” fonts are just that—faked. You +should only use them as a last resort, and then only sparingly. A +word or two or a line or two in a faked font will pass unnoticed; +large patches of type in a faked font look typographically cheap. +

+ +
+

Type modifications macros

+ +
    +
  • Pseudo italic +
      +
    • SETSLANT – degree of pseudo-italicizing
    • +
    • \*[SLANT] – inline escape for pseudo-italicizing type
    • +
  • +
  • Pseudo bold +
  • +
  • Pseudo condensed +
      +
    • CONDENSE – percentage for pseudo-condensed type
    • +
    • \*[COND] – inline escape for pseudo-condensed type
    • +
  • +
  • Pseudo extended +
      +
    • EXTEND – percentage for pseudo-extended type
    • +
    • \*[EXT] – inline escape for pseudo-extending
    • +
  • +
  • Smallcaps +
  • +
+
+ + + +
+

Set degree of slant for pseudo-italicizing

+
+ +
+Macro: SETSLANT <degrees to slant type> | RESET +
+ +

+Pseudo-italicizing of type is accomplished by slanting a roman font +a certain number of degrees to the right. SETSLANT lets you fix the +number of degrees. Mom’s default is 15, which produces an +acceptable approximation of an italic font. If you want another +value—say, 13 degrees—you’d set it by entering +
+ + .SETSLANT 13 + +If you change the degree of slant and later want to set it back to +the mom default, do +
+ + .SETSLANT RESET + +

+ +
+

+Note: By itself, SETSLANT will not start +pseudo-italicizing type; it merely tells mom what degree of slant +you want. To start pseudo-italicizing, use the +inline escape +\*[SLANT]. +

+
+ + + +
+

Pseudo italic on/off

+
+ +
+Inline: \*[SLANT] +
+Inline: \*[SLANTX] +
+ +

+\*[SLANT] begins pseudo-italicizing. \*[SLANTX] turns +the feature off. Both are inline +escapes, +therefore they should not appear as separate lines, but rather be +embedded in text lines, like this: +
+ + Not \*[SLANT]everything\*[SLANTX] is as it seems. + +Alternatively, if you wanted the whole line pseudo-italicized, +you’d do +
+ + \*[SLANT]Not everything is as it seems.\*[SLANTX] + +Once \*[SLANT] is invoked, it remains in +effect until turned off. +

+ +
+

+Note: If you’re using the +document processing macros +with +PRINTSTYLE TYPEWRITE, +mom underlines pseudo-italics by default. To change this behaviour, +use the special macro +SLANT_MEANS_SLANT. +

+
+ + + +
+

Set amount of emboldening

+
+ +
+Macro: SETBOLDER <amount of emboldening, in machine units> | RESET +
+ +

+Emboldening of type is accomplished by printing characters twice; +the second printing is slightly offset from the first, effectively +“thickening” the character. SETBOLDER lets you set the +number of +machine units +for the offset. Mom’s default is 700 units, which produces an +acceptable approximation of a bold font. If you want another +value—say, 500 units—you’d set it by entering +
+ + .SETBOLDER 500 + +If you change the emboldening offset and later want to set it back +to the mom default, do +
+ + .SETBOLDER RESET + +

+ +
+

+Note: By itself, SETBOLDER will not start +emboldening type; it merely tells mom what you want the emboldening +offset to be. To start emboldening, use the +inline escape +\*[BOLDER]. +

+
+ + + +
+

Emboldening on/off

+
+ +
+Inline: \*[BOLDER] +
+Inline: \*[BOLDERX] +
+ +

+\*[BOLDER] begins emboldening type. +\*[BOLDERX] turns the +feature off. Both are +inline escapes, +therefore they should not appear as separate lines, but rather be +embedded in text lines, like this: +
+ + Not \*[BOLDER]everything\*[BOLDERX] is as it seems. + +Alternatively, if you wanted the whole line emboldened, +you’d do +
+ + \*[BOLDER]Not everything is as it seems.\*[BOLDERX] + +Once \*[BOLDER] is invoked, it remains in +effect until turned off. +

+ +
+

+Note: If you’re using the +document processing macros +with +PRINTSTYLE TYPEWRITE, +mom ignores \*[BOLDER] requests. +

+
+ + + +
+

Set percentage for pseudo-condensed type

+
+ +
+Macro: CONDENSE <pseudo-condense percentage> +
+ +

+Pseudo-condensing of type is accomplished by reducing the width of +characters at a given point size without reducing their height, +effectively narrowing them so they look like condensed type. +CONDENSE tells mom what percentage of the normal character width you +want the characters to be condensed. +

+ +

+Mom has no default value for CONDENSE, therefore you must set it +before using the +inline escape +\*[COND]. +80 percent of the normal character width is a good value, and +you’d set it like this: +
+ + .CONDENSE 80 + +

+ +
+

+Note: By itself, CONDENSE will not start +pseudo-condensing type; it merely tells mom what percentage of the +normal character width you want characters to be condensed. To +start pseudo-condensing, use the +inline escape +\*[COND]. +

+ +

+Additional note: Make sure that +pseudo-condensing is off (with +\*[CONDX]) +before making any changes to the pseudo-condense percentage +with CONDENSE. +

+
+ + + +
+

Pseudo-condensing on/off

+
+ +
+Inline: \*[COND] +
+Inline: \*[CONDX] +
+ +

+\*[COND] begins pseudo-condensing type. +\*[CONDX] turns the feature off. Both are +inline escapes, +therefore they should not appear as separate lines, but rather be +embedded in text lines, like this: +
+ + \*[COND]Not everything is as it seems.\*[CONDX] + +\*[COND] remains in effect until you turn it +off with \*[CONDX]. +

+ +
+

+IMPORTANT: You must turn +\*[COND] off before making any changes to +the point size of your type, either via the +PT_SIZE +macro or with the \s inline escape. If you wish +the new point size to be pseudo-condensed, simply re-invoke +\*[COND] afterwards. Equally, +\*[COND] must be turned off before changing +the condense percentage with +.CONDENSE. +

+
+ +
+

+Note: If you’re using the +document processing macros +with +PRINTSTYLE TYPEWRITE, +mom ignores \*[COND] requests. +

+
+ + + +
+

Set percentage for pseudo-extended type

+
+ +
+Macro: EXTEND <pseudo-extend percentage> +
+ +

+Pseudo-extending of type is accomplished by increasing the width of +characters at a given point size without increasing their height, +effectively widening them so they look like extended type. EXTEND +tells mom what percentage of the normal character width you want the +characters to be extended. +

+ +

+Mom has no default value for EXTEND, therefore you must set it +before using the +inline escape +\*[EXT]. 120% of +the normal character width is a good value, and you’d set it +like this: +
+ + .EXTEND 120 + +

+ +
+

+Note: By itself, EXTEND will not start +pseudo-extending type; it merely tells mom what percentage of the +normal character width you want characters to be extended. To start +pseudo-extending, use the +inline escape +\*[EXT]. +

+ +

+Additional note: Make sure that +pseudo-extending is off (with +\*[EXTX]) +before making any changes to the pseudo-extend percentage +with EXTEND. +

+
+ + + +
+

Pseudo-extending on/off

+
+ +
+Inline: \*[EXT] +
+Inline: \*[EXTX] +
+ +

+\*[EXT] begins pseudo-extending type. +\*[EXTX] turns the feature off. Both are +inline escapes, +therefore they should not appear as separate lines, but rather be +embedded in text lines, like this: +
+ + \*[EXT]Not everything is as it seems.\*[EXTX] + +\*[EXT] remains in effect until you turn it off with +\*[EXTX]. +

+IMPORTANT: You must turn +\*[EXT] off before making any changes to the +point size of your type, either via the +PT_SIZE +macro or with the \s inline escape. If you wish +the new point size to be pseudo-extended, simply re-invoke +\*[EXT] afterwards. Equally, +\*[EXT] must be turned off before changing +the extend percentage with +EXTEND. +

+
+
+

+Note: If you’re using the +document processing macros +with +PRINTSTYLE TYPEWRITE, +mom ignores \*[EXT] requests. +

+
+ + + +
+

Smallcaps

+
+ +
+Macro: SMALLCAPS <toggle> +
+ +

+To begin setting type in pseudo-smallcaps, simply invoke +.SMALLCAPS. When you no longer want them, invoke +SMALLCAPS OFF (or END, STOP, +DONE, etc). If you are currently in a +no-fill mode, +(i.e. +LEFT, +CENTER, +or +RIGHT) +and you want the smallcaps to continue on the same line, +append a \c to the line, like this +
+ + A line of type\c + .SMALLCAPS + with a few words in smallcaps. + .SMALLCAPS OFF + +The line preceding .SMALLCAPS OFF should also have a +\c appended to it if you wish it to continue unbroken. +

+ +
+

+Note: +SMALLCAPS does not have an inline equivalent to + +\*[UC] / \*[LC] +. +Furthermore, if you’re using the +document processing macros +with +PRINTSTYLE TYPEWRITE, +mom ignores SMALLCAPS. +

+ +

+Additionally, be aware that no automatic +kerning +takes place while pseudo-smallcaps are in effect. +

+
+ +
+

Set size, weight, and width of smallcaps

+
+ +
+Macro: SMALLCAPS_STYLE SIZE <percentage> WEIGHT_ADJ <percentage> EXTEND <percentage> +
+ +

+True smallcaps are not a font effect, but, like designer cuts of +bold, condensed, and extended, actual fonts provided with some +families. It is highly recommended that you acquire real smallcaps +fonts rather than relying on mom’s pseudo version. +

+ +

+To achieve a reasonable facsimile of designer-cut smallcaps fonts, +mom needs to know the percentage of regular caps at a given point +size by which to reduce the small caps. To make adjustments for +the difference in weight and width of the smaller caps, she also +needs to know by how much to embolden (“fatten”) the +smallcaps, and by how much to increase their width. +

+ +

+All three arguments to SMALLCAPS_STYLE reflect a +percentage of the point size in effect when +SMALLCAPS +is invoked. Mom’s defaults for pseudo-smallcaps are: +
+ + SIZE = 74% + WEIGHT_ADJ = .3% + EXTEND = 5% + +To change any or all of the defaults, you might enter +
+ + .SMALLCAPS_STYLE SIZE 80 WEIGHT_ADJ .25 EXTEND 3 + +or, more readably, +
+ + .SMALLCAPS_STYLE + SIZE 80 \ + WEIGHT_ADJ .25 \ + EXTEND 3 + +Note that you do not have to give SMALLCAPS_STYLE all three +arguments, and that the arguments may be entered in any order. Any +arguments you omit will remain at their former value. +

+ +

+ + + +

Vertical movements

+ +The two macros in this section allow you to move down or up on the +page relative to the current +baseline. + +
+

Vertical movements macros

+
    +
  • ALD – Advance Lead
  • +
  • RLD – Reverse Lead
  • +
  • (see also SPACE)
  • +
+
+ + + +
+

Advance Lead (move downward)

+
+ +
+Macro: ALD <distance to move downward> +
+

+• Requires a unit of measure +

+ +

+ALD takes one argument: the distance to move downward on the page +relative to the current vertical position. +

+ +

+ALD causes a line break, which means the argument is added to the +current +leading. +For example, if your current leading is 12 points, a line of type +after .ALD 6p will be 18 points distant from the previous +line. +

+ +

+If you wish to advance the argument's distance from the +current baseline, it should be preceded by +EL. +For example, +
+ + .LEFT + .LS 12 + First line. + Second line.\c + .EL + .ALD 15p + Third line. + +would place the third line exactly 15 points beneath the second. +

+ +

+ALD requires a unit of measure. Decimal fractions are allowed, and +values may be combined. Therefore, to move down on the page by 1/4 +of an inch, you could enter either +
+ + .ALD .25i + +or +
+ + .ALD 1P+6p + +As the mnemonic +(Advance LeaD) +suggests, you’ll most often use ALD with +points +of lead. +

+ +
+

+Note: if you want to use ALD at the top +of a page (i.e. to advance to the starting position of type on a +page), combine the value you want with -1v (minus one +line space), like this: +
+ + .ALD 1i-1v + +At the top of a page, this will advance one inch from the top edge +of the paper. Without the -1v, the same command would advance one +inch from the top of the page plus the distance of one line space. +

+
+ + + +
+

Reverse Lead (move upward)

+
+ +
+Macro: RLD <distance to move upward> +
+

+• Requires a unit of measure +

+ +

+RLD takes one argument: the distance to move upward on the page +relative to the current vertical position. +

+ +

+RLD causes a line break, which means the argument is subtracted from +the current +leading. +For example, if your current leading is 12 points, a line of type +after .RLD 6p will be 6 points distant from the previous +line. +

+ +

+If you wish to move upward from the current baseline by the +argument's distance, RLD should be preceded by +EL. +For example, +
+ + .LEFT + .LS 18 + First line. + Second line.\c + .EL + .RLD 3p + Third line. + +would raise the third line by 3 points relative to the baseline of +the second line. Put another way, if the .RLD in the +example were 18p, the third line would fall on the same baseline as +the second. +

+ +

+RLD requires a unit of measure. Decimal fractions are allowed, and +values may be combined. Therefore, to move up on the page by 1/4 of +an inch, you could enter either +
+ + .RLD .25i + +or + + .RLD 1P+6p + +As the mnemonic +(Reverse LeaD) +suggests, you’ll most often use RLD with +points +of lead. +

+ +

+ + + +

Tabs

+ +

+Mom provides two different kinds of tab setup: typesetting tabs +and string tabs. Neither one has anything to do with the tab key +on your keyboard, and both are utterly divorced from groff’s +notion of tabs. I recommend reading this section carefully in order +to understand how mom handles tabs. +

+ +
+

+Note: see the section +Typesetting macros during document processing +for reassuring information on the use of tabs during +document processing. +

+
+ +

Typesetting tabs

+ +

+Typesetting tabs are defined by both an indent from the left margin +and a line length. This is quite different from typewriter-style +tab stops (the groff norm) that only define the left indent. In +conjunction with the +multi-column macros, +typesetting tabs significantly facilitate tabular and columnar work. +

+ +

+Typesetting tabs are created with the +TAB_SET +macro. TAB_SET identifies the tab (by number), establishes its left +indent and line length, and optionally sets a quad direction and +fill mode. After tabs have been created with TAB_SET, they can be +called at any time with the +TAB +macro. +

+ +
+

Quickie tutorial on typesetting tabs

+ +

+Say you want to set up three tabs to produce an employee evaluation +that looks something like this: +

+ +
+ +CRITERION EVALUATION COMMENTS + +Service Good Many clients specifically request + support from Joe by name. + +Punctuality Satisfactory Tends to arrive after 8:00am, but + often works through lunch hour. + +Team spirit Needs work Persistently gives higher priority + to helping clients than respecting + organizational hierarchy. + +
+ +

+You want the first tab, CRITERION, +

+
    +
  • to begin at the left margin of the page – i.e. no indent
  • +
  • to have a line length of 5 picas
  • +
  • to be set flush left
  • +
+ +

+Tabs must be numbered, and each has to be set up with a separate +TAB_SET +line. Therefore, to set up tab 1, you enter +
+ + .TAB_SET 1 0 5P L + | | | | + tab #--+ | | +--direction + | | + indent--+ +--length + +You want the second tab, EVALUATION, +

+
    +
  • to begin 8 picas from the left margin
  • +
  • to have a length of 9 picas
  • +
  • to be set centered
  • +
+ +

+You set it up like this: +
+ + .TAB_SET 2 8P 9P C + | | | | + tab #--+ | | +--direction + | | + indent--+ +--length + +You want the third tab, COMMENTS, +

+
    +
  • to begin 19 picas from the left margin
  • +
  • to have a length of 17 picas
  • +
  • to be set flush left, filled
  • +
+ +

+The setup looks like this: +
+ + .TAB_SET 3 19P 17P L QUAD + | | | | | + | | | | +--fill output lines + | | | | + tab #--+ | | +--direction + | | + indent--+ +--length + +Once the tabs are set up, you can call them in one of two ways: +

+
    +
  • with .TAB (passing the tab + number as an argument), which breaks the current line, + advances one linespace and calls the tab.
  • +
  • with .TN (Tab Next), which keeps + you on the current line and moves over to the next + tab in sequence (i.e. from 1 to 2, 2 to 3, etc.), or, more + conveniently, with the + \*[TB+] + inline escape
  • +
+ +

+To exit from tabs and restore your original left margin, line +length, quad direction and fill mode, use +.TQ +(Tab Quit). +

+ +

+Here’s how the input for our sample employee evaluation looks +(with some introductory parameters): +

+ +
Code:
+
+ +.PAGE 8.5i 11i 1i 1i 1i +.FAMILY T +.FT R +.PT_SIZE 14 +.LS 16 +.QUAD LEFT +.KERN +.HY OFF +.SS 0 +.TAB_SET 1 0 5P L +.TAB_SET 2 8P 9P C +.TAB_SET 3 19P 17P L QUAD +.TAB 1 +CRITERION\*[TB+] +EVALUATION\*[TB+] +COMMENTS +.SP +.TAB 1 +Service\*[TB+] +Good\*[TB+] +Many clients specifically request support from Joe by name. +.SP +.TAB 1 +Punctuality\*[TB+] +Satisfactory\*[TB+] +Tends to arrive after 8:00am, but often works through lunch hour. +.SP +.TAB 1 +Team spirit\*[TB+] +Needs work\*[TB+] +Persistently gives higher priority to helping clients +than respecting organizational hierarchy. +.TQ + +
+ +

+Try setting this up and processing it with +
+ + pdfmom filename.mom > filename.pdf + +then previewing the .pdf file. Notice how .TN +simply moves over to the next tab, while the combination +.SP/.TAB 1 breaks the line, advances by one extra +linespace, and calls the first tab. +

+ +

+Notice, too, how the QUAD argument passed to tab 3 means +you don’t have to worry about the length of +input lines; +mom +fills +the tab and sets the type flush left. +

+
+ +

String tabs (autotabs)

+ +

+String tabs let you mark off tab positions with +inline escapes +embedded in +input lines. +Left indents and line lengths are calculated from the beginning and +end positions of the marks. This is especially useful when tab +indents and lengths need to be determined from the text that goes in +each tab. +

+ +

+Setting up string tabs is a two-step procedure. First, you enter an +input line in which you mark off where you want tabs to begin and +end. (This is often best done in conjunction with the +SILENT +macro.) +

+ +

+Next, you invoke the +ST +macro for every string tab you defined, and optionally pass quad and +fill information to it. That done, string tabs are called with the +TAB +macro, just like typesetting tabs. +

+ +

+In combination with the +PAD +macro and the groff inline escape +\h +(move horizontally across the page) or mom’s +\*[FWD <distance>] +(move forward) inline, string tabs provide tremendous flexibility in +setting up complex tab structures. +

+ +
+

Quickie tutorial on string tabs

+

+Say you want to set up tabs for the +employee evaluation form +used as an example in the +typesetting tabs tutorial. +This time, though, you want to play around with the point size of +type, so you can’t know exactly how long the tabs will be or +where they should start. All you know is +

+
    +
  • CRITERION is the longest line in tab 1
  • +
  • EVALUATION is the longest line in tab 2
  • +
  • tab 3 should extend to the current right margin
  • +
  • you want a 1 pica gutter between each tab
  • +
+ +

+This is an ideal job for string tabs. +

+ +

+The first thing you need for string tabs is an +input line +with tab positions marked on it. Tabs are marked with the +inline escapes +\*[ST<n>] +and +\*[ST<n>X], +where <n> +is the number you want the tab to have. (In this example, we +enclose the input line with the +SILENT +macro so the line doesn’t print. We also use the +PAD +macro to permit defining tab 3 as simply “the amount of space +remaining on the input line.”) +

+ +

+The setup looks like this: +

+ +
Code:
+ +
+ +.SILENT +.PAD "\*[ST1]CRITERION\*[ST1X]\*[FWD 12p]\*[ST2]EVALUATION\*[ST2X]\*[FWD 12p]\*[ST3]#\*[ST3X]" +.SILENT OFF + +
+ +

+The long line after .PAD looks scary, but +it isn’t really. Here’s what it means when broken down +into its component parts: +

+
    +
  • The longest line in tab 1 is “CRITERION”, so we + enclose CRITERION with begin/end markers for string tab 1: +
    + + \*[ST1]CRITERION\*[ST1X] + +
  • +
  • We want a 1 pica (12 points) gutter between tab 1 and 2, + so we insert 12 points of space with \*[FWD 12p]: +
    + + \*[FWD 12p] + +
  • +
  • The longest line in tab 2 is “EVALUATION”, so + we enclose EVALUATION with begin/end markers for string + tab 2: + + \*[ST2]EVALUATION\*[ST2X] + +
  • +
  • We want 1 pica (12 points) between tab 2 and 3, so we + insert it with: +
    + + \*[FWD 12p] + +
  • +
  • We want tab 3 to be as long as whatever space remains on + the current line length, so we enclose the + pad marker + (#) with begin/end markers for string tab 3: + + \*[ST3]#\*[ST3X] + +
  • +
+ +

+The tabs are now defined, but they require +quad direction +and +fill +information. For each string tab defined above, enter a separate +.ST +line, like this: +
+ + .ST 1 L + .ST 2 L + .ST 3 L QUAD + | | | + | | +--fill output lines + | | +tab #--+ +--direction + +From here on in, you call the tabs with +.TAB, +.TN, +or +\*[TB+] +just like typesetting tabs (see +typesetting tabs tutorial). +

+ +

+Here’s the complete setup and entry for the sample employee +evaluation form utilizing string tabs. +

+ +
Code:
+
+ +.PAGE 8.5i 11i 1i 1i 1i +.FAMILY T +.FT R +.PT_SIZE 14 +.LS 16 +.QUAD LEFT +.KERN +.HY OFF +.SS 0 +.SILENT +.PAD "\*[ST1]CRITERION\*[ST1X]\*[FWD 12p]\*[ST2]EVALUATION\*[ST2X]\*[FWD 12p]\*[ST3]#\*[ST3X]" +.SILENT OFF +.ST 1 L +.ST 2 L +.ST 3 L QUAD +.TAB 1 +CRITERION\*[TB+] +EVALUATION\*[TB+] +COMMENTS +.SP +.TAB 1 +Service\*[TB+] +Good\*[TB+] +Many clients specifically request support from Joe by name. +.SP +.TAB 1 +Punctuality\*[TB+] +Satisfactory\*[TB+] +Tends to arrive after 8:00am, but often works through lunch hour. +.SP +.TAB 1 +Team spirit\*[TB+] +Needs work\*[TB+] +Persistently gives higher priority to helping clients +than respecting organizational hierarchy. +.TQ + +
+ +

+Try setting this up and processing it with +
+ + pdfmom filename.mom > filename.pdf + +and previewing the .pdf file. +

+ +

+Now, change the point size of the above sample to 12 and preview it +again. You’ll see that the tab structure remains identical +(tab 1=CRITERION, tab 2=EVALUATION, tab 3=space remaining, and the +gutter between tabs is still 1 pica), while the position and length +of the tabs have altered because of the new point size. +

+ +

+Now try increasing the gutters to 2 picas +(\*[FWD 24p] or +\*[FWD 2P] instead of +\*[FWD 12p]). Preview the file again, +and notice how the tab structure remains the same, but the gutters +are wider. +

+
+ +
+

Tabs macros

+ +
    +
  • TAB_SET – create typesetting tabs
  • +
  • \*[ST]...\*[STX] – inline escapes for marking String Tabs
  • +
  • ST – set String Tabs
  • +
  • TAB – call tabs
  • +
  • TN – Tab Next; call next tab in sequence
  • +
  • \*[TB+] – inline escape to call next tab in sequence
  • +
  • TQ – Tab Quit
  • +
+ +
+ + + +
+

Set up typesetting tabs

+
+ +
+Macro: TAB_SET <tab number> <indent> <length> L | R | C | J [ QUAD ] +
+

+• <indent> and <length> require a unit of measure +

+ +

+TAB_SET creates typesetting tabs that later can be called with +.TAB. +Typesetting tabs are numbered, and defined by an indent, a length, +and a quad direction, hence TAB_SET has four required arguments: +

+
    +
  • a tab number
  • +
  • an indent (measured from the left margin of the page, + or, if you’re already in a tab, from the left margin of the tab)
  • +
  • a length
  • +
  • a direction
  • +
+ +

+To set up a centred tab 6 picas long and 9 points from the left +margin, you’d enter +
+ + .TAB_SET 1 9p 6P C + +The tab number in the above (”1”) is simply an +identifier. It could have been 4, or 17, or 296. There’s no +need to set up tabs in numerical sequence. +

+ +

+By default, tabs are in +nofill +mode, meaning you can enter text in tabs on a line-for-line basis +without having to use the +BR +macro. If you want a tab to be +filled, +pass the optional argument QUAD, +which will make the tab behave as if you’d entered +.QUAD L | R | C. +

+ +

+For +justified +tabs, simply pass the argument J (without the QUAD argument), like +this: +
+ + .TAB 1 9p 6P J + +Once tabs are set, they can be called at any time with the +TAB <n> +macro, where <n> is the number of the desired tab. +

+ +

+You can set up any number of typesetting tabs. However, be aware +that +string tabs +are also called with TAB <n>, so be careful that you +don’t set up a typesetting tab numbered, say, 4, when you +already have a string tab numbered 4. Every tab, typesetting or +string, must have a unique numeric identifier. +

+ +
+

+Note: If you use TAB_SET while +you’re currently inside a tab, the indent argument is the +distance from the tab’s left margin, not the left margin of +the page. Therefore, you should exit tabs (with +.TQ) +before creating new tabs (unless, of course, you want to set up a +tab structure within the confines of an existing tab). +

+
+ +
+

+IMPORTANT: Turn all indents off (see +Indents) +before setting up tabs with TAB_SET, or mom may get confused. +

+
+ + + +
+

Mark positions of string tabs

+
+ +
+Inlines: \*[ST<number>]...\*[ST<number>X] +
+ +

+The quad +direction must be +LEFT +or +JUSTIFY +(see +QUAD +and +JUSTIFY) +or the +no-fill mode +set to +LEFT +in order for these inlines to function properly. Please see +IMPORTANT, +below. +

+ +

+String tabs need to be marked off with +inline escapes +before being set up with the +ST +macro. Any input line may contain string tab markers. <number>, above, means the numeric +identifier of the tab. The following shows a sample input line with +string tab markers. +
+ + \*[ST1]Now is the time\*[ST1X] for all \*[ST2]good men\*ST2X] to come to the aid of the party. + +String tab 1 begins at the start of the line and ends after the word +“time”. String tab 2 starts at “good” and +ends after “men”. Inline escapes (e.g. font or point +size changes, or horizontal movements, including +padding) +are taken into account when mom determines the position and length +of string tabs. +

+ +

+Up to nineteen string tabs may be marked (not necessarily all on the +same line, of course), and they must be numbered between 1 and 19. +

+ +

+Once string tabs have been marked in input lines, they have to be +“set” with +.ST, +after which they may be called, by number, with +.TAB. +

+ +
+

+Note: Lines with string tabs marked off +in them are normal input lines, i.e., they get printed, just like +any input line. If you want to set up string tabs without the line +printing, use the +SILENT +macro. +

+
+ +
+

+IMPORTANT: +Owing to the way groff processes +input lines +and turns them into +output lines, +it is not possible for mom to “guess” the correct +starting position of string tabs marked off in lines that are +centered or set flush right. +

+ +

+Equally, she cannot guess the starting position if a line is fully +justified and broken with +SPREAD. +

+ +

+In other words, in order to use string tabs, +LEFT +must be active, or, if +QUAD LEFT +or +JUSTIFY +are active, the line on which the string tabs are marked must be +broken “manually” with +.BR +(but not +.SPREAD). +

+ +

+To circumvent this behaviour, I recommend using the +PAD +to set up string tabs in centered or flush right lines. Say, for +example, you want to use a string tab to underscore the text of a +centered line with a rule. Rather than this, +
+ + .CENTER + \*[ST1]A line of text\*[ST1X]\c + .EL + .ST 1 + .TAB 1 + .PT_SIZE 24 + .ALD 3p + \*[RULE] + .RLD 3p + .TQ + +you should do: +
+ + .QUAD CENTER + .PAD "#\*[ST1]A line of text\*[ST1X]#" + .EL + .ST 1 + .TAB 1 + .PT_SIZE 24 + .ALD 3p + \*[RULE] \" Note that you can’t use \*[UP ] or \*[DOWN] with \*[RULE] + .RLD 3p + .TQ + +

+
+ + + +
+

Set string tabs

+
+ +
+Macro: ST <tab number> L | R | C | J [ QUAD ] +
+ +

+After string tabs have been marked off on an input line (see +\*[ST]...\*[STX]), +you need to “set” them by giving them a direction and, +optionally, the QUAD argument. In this respect, ST is +like +TAB_SET +except that you don’t have to give ST an indent or a +line length (that’s already taken care of, inline, by +\*[ST]...\*[STX]). If you want string tab 1 +to be left, enter +
+ + .ST 1 L + +If you want it to be left and +filled, enter +
+ + .ST 1 L QUAD + +If you want it to be justified, enter +
+ + .ST 1 J + +See the +Quickie tutorial on string tabs +for a full explanation of setting up string tabs. +

+ + + +
+

Call tabs

+
+ +
+Macro: TAB <tab number> +
+

+Alias: TB +

+ +

+After tabs have been defined (either with +TAB_SET +or +ST), +TAB moves to whatever tab number you pass it as an argument. For +example, +
+ + .TAB 3 + +moves you to tab 3. +

+ +
+

+Note: TAB breaks the line preceding it and +advances 1 linespace. Hence, +
+ + .TAB 1 + A line of text in tab 1. + .TAB 2 + A line of text in tab 2. + +produces, on output +
+ + A line of text in tab 1. + A line of text in tab 2. + +If you want the tabs to line up, use +TN +(Tab Next) +or, more conveniently, the inline escape +\*[TB+]: +
+ + .TAB 1 + A line of text in tab 1.\*[TB+] + A line of text in tab 2. + +which produces +
+ + A line of text in tab 1. A line of text in tab 2. + +If the text in your tabs runs to several lines, and you want the +first lines of each tab to align, you must use the +multi-column macros. +

+ +

+Additional note: Any indents +in effect prior to calling a tab are automatically turned off by +TAB. If you were happily zipping down the page with a left indent +of 2 picas turned on, and you call a tab whose indent from the left +margin is 6 picas, your new distance from the left margin will be 6 +picas, not 6 picas plus the 2 pica indent. +

+
+ + + +
+

Tab Next

+
+ +
+Macro: TN +
Inline escape: \*[TB+] +
+ +

+TN moves over to the next tab in numeric sequence (tab n+1) without +advancing on the page. See the +NOTE +in the description of the TAB macro for an example of how TN works. +

+ +

+In tabs that aren’t given the QUAD +argument when they’re set up with +TAB SET +or +ST, +you must terminate the line preceding .TN +with the \c inline escape. Conversely, +if you did give a QUAD argument to TAB_SET or ST, the +\c must not be used. +

+ +

+If you find remembering whether to put in the +\c bothersome, you may prefer to use the +inline escape +alternative to +.TN, +\*[TB+], +which works consistently regardless of the fill mode. +

+ +
+

+Note: You must put text in the +input line +immediately after TN. Stacking of TN’s is not +allowed. In other words, you cannot do +
+ + .TAB 1 + Some text\c + .TN + Some more text\c + .TN + .TN + Yet more text + +The above example, assuming tabs numbered from 1 to 4, should be entered +
+ + .TAB 1 + Some text\c + .TN + Some more text\c + .TN + \&\c + .TN + Yet more text + + +\& is a zero-width, non-printing character that groff +recognizes as valid input, hence meets the requirement for input +text following .TN. +

+
+ + + +
+

Tab Quit

+
+ +
+Macro: TQ +
+ +

+TQ takes you out of whatever tab you were in, advances 1 linespace, +and restores the left margin, line length, quad direction and +fill mode +that were in effect prior to invoking any tabs. +

+ +

+ + + +

Multiple columns

+ +

+Tabs are not by nature columnar, which is to say that if the text +inside a tab runs to several lines, calling another tab does not +automatically move to the +baseline +of the first line in the previous tab. To demonstrate: +
+ + .TAB 1 + Carrots + Potatoes + Broccoli + .TAB 2 + $1.99/5 lbs + $0.25/lb + $0.99/bunch + +produces, on output +
+ + Carrots + Potatoes + Broccoli + $1.99/5 lbs + $0.25/lb + $0.99/bunch + +The multi-column macros allow you to set tabs in columnar fashion, +rather than line by line. When you invoke multi-column mode (with +.MCO – +Multi-Column On), +mom saves the position of the current baseline. +.MCR +(Multi-Column Return) +at any point while multi-columns are on returns you to the saved +position. Exiting multi-columns +(.MCX – +Multi-Column eXit) +quits the current tab (if you’re in one) and moves you to the +bottom of the longest column. (Note that you do not have to use +multi-columns in conjunction with tabs.) +

+ +

+Using our example above, but setting it in multi-column mode, +
+ + .MCO + .TAB 1 + Carrots + Potatoes + Broccoli + .MCR + .TAB 2 + $1.99/5 lbs + $0.25/lb + $0.99/bunch + .MCX + +produces +
+ + Carrots $1.99/5 lbs + Potatoes $0.25/lb + Broccoli $0.99/bunch + +

+ +
+

+Note: Do not confuse MCO with +the +COLUMNS +macro in the +document processing macros. +

+
+ +
+

+Additional Note: +Do not use multi-columns with +DOCTYPE SLIDES +because MCX uses the lowest line on the page to determine column +depth. Owing to the fact that both headers and footers are printed +prior to slides receiving text, MCX will always go to the +footer position. If you need functionality similar to MCO/MCX, use +the groff requests .mk and .rt. See +info groff mk. +

+
+ +
+

Multi-columns macros

+ +
    +
  • MCO – begin multi-column setting
  • +
  • MCR – return to top of column
  • +
  • MCX – exit multi-columns
  • +
+
+ + + +
+

Begin multi-column setting

+
+ +
+ Macro: MCO +
+ +

+MCO (Multi-Column On) is the macro you use to begin multi-column +setting. It marks the current +baseline +as the top of your columns, for use later with +MCR. +See the +introduction to columns +for an explanation of multi-columns and some sample +input. +

+ +
+

+Note: Do not confuse MCO with +the +COLUMNS +macro in the +document processing macros. +

+
+ + + +
+

Return to top of column

+
+ +
+Macro: MCR +
+ +

+Once you’ve turned multi-columns on (with +.MCO), +.MCR, at any time, returns you to the top of +your columns. +

+ + + +
+

Exit multi-columns

+
+ +
+Macro: MCX [ <distance to advance below longest column> ] +
+

+• Optional argument requires a unit of measure +

+ +

+MCX takes you out of any tab you were in (by silently invoking +.TQ) +and advances to the bottom of the longest column. +

+ +

+Without an argument, MCX advances 1 linespace below the longest +column. Linespace, in this instance, is the +leading +in effect at the moment MCX is invoked. +

+ +

+If you pass the <distance> argument to MCX, it +advances 1 linespace below the longest column (see above) PLUS the +distance specified by the argument. The argument requires a unit +of measure; therefore, to advance an extra 6 points below where MCX +would normally place you, you’d enter +
+ + .MCX 6p + +

+ +
+

+Note: If you wish to advance a precise +distance below the +baseline +of the longest column, use MCX with an argument of 0 (zero; no unit +of measure required) in conjunction with the +ALD +macro, like this: +
+ + .MCX 0 + .ALD 24p + +

+
+ +

+The above advances to precisely 24 points below the baseline +of the longest column. +

+ +

+ + + +

Indents

+ +

+With mom’s indents, you can indent from the left, the right, +or both margins. In addition, mom provides temporary left indents +(i.e., only one line is indented, as at the start of a paragraph) +and “hanging” left indents (the reverse of a temporary +indent; the first line isn’t indented, subsequent lines are). +

+ +

How mom handles indents

+ +

+Mom provides five kinds of indents: left, right, both, temporary, +and hanging. Each is invoked by its own name: +

+
    +
  • IL – Indent Left
  • +
  • IR – Indent Right
  • +
  • IB – Indent Both
  • +
  • HI – Hanging Indent
  • +
  • TI – Temporary Indent
  • +
+ +

+In addition, there are four macros to control exiting from +indents: +

+
    +
  • IQ – quit all active indents
  • +
  • ILX – exit indent style left
  • +
  • IRX – exit indent style right
  • +
  • IBX – exit indent style both
  • +
+ +

+This section deals exclusively with IL, IR, and IB. For an +explanation of hanging and temporary indents—how they work and +how to use them—see +Hanging indents +and +Temporary indents. +

+ +

+The first time you invoke any of mom’s indents, you must +supply a measure. For example, +
+ + .IL 2P + +indents text 2 picas from the left margin (or current tab indent). +

+ +

+When you want to exit the above indent, use either +
+ + .IQ + +or + + .ILX + +The next time you want the same indent, invoke it without the +argument, like this: +
+ + .IL + +As you can see, once you’ve supplied a measure to an indent +macro, mom stores the value, obviating the need to repeat it on +subsequent invocations. And mom doesn’t just store the +measure—she hangs on to it tenaciously. Arguments passed to +IL, IR, and IB are additive. Consider the following: +
+ + .LL 20P + .IR 2P \"Indent right by 2 picas + A first block of text... + ... + ... + .IQ \"Turn indent off + A second block of text... + ... + ... + .IR 2P \"Indent right by an additional 2 picas (i.e. 4 picas) + A third block of text... + ... + ... + +The first block of text is right indented by 2 picas (i.e. the line +length is shortened by 2 picas to 18 picas). The second block of +text, after IQ, is, as you’d expect, set to the full measure. +The third block of text—the one to pay attention to—is +not right indented by 2 picas, but rather by 4 picas. Mom adds +the value of arguments to IL, IR, and IB to whatever value is already +in effect. +

+ +

+If you wanted the third block of text in the example above to be +right indented by just 2 picas (the original measure given to IR), +you would enter .IR without an argument. +

+ +

+Because indent arguments are additive, putting a minus sign in front +of the argument can be used to subtract from the current value. +In the following example, the first line is indented 18 points, +the second is indented 36 points (18 + 18), and the third is again +indented 18 points (36 - 18). +
+ + .IL 18p \"Indent left by 18 points = 18 points + Now is the time + .IL 18p \"Indent left by 18 points more = 36 points + for all good men to come + .IL -18p \"Indent left by 18 points less = 18 points + to the aid of the party. + +Sometimes, you may want to clear out the stored indent +values—let mom start indenting with a clean slate, as it +were. Giving the optional argument CLEAR to any of the +“indent quit” macros resets them to zero. +

+
    +
  • IQ CLEAR – quit and clear all indents
  • +
  • ILX CLEAR – quit and clear indent style left
  • +
  • IRX CLEAR – quit and clear indent style right
  • +
  • IBX CLEAR – quit and clear indent style both
  • +
+ +

+Indent styles may be combined and manipulated separately. You +could, for example, have a left indent of 4 picas and a right indent +of 6 picas and control each separately, as in the following example. +
+ + .IL 4P \"Indent left 4 picas + .IR 6P \"Indent right 6 picas + Some text + .IRX \"Turn off the right indent only + More text \"Text is still indented 4 picas left + +If, at .IRX, you wanted the text afterwards to have no +indents (either left or right), you would enter .IQ, +which exits all indent styles at once. +

+ +

+A word of advice: Indents are best used only when you have a +compelling reason not to change the current left margin or line +length. In many instances where indents might seem expedient, +it’s better to use tabs, or actually change the left margin +or the line length. Mom’s indenting macros are flexible and +powerful, but easy to get tangled up in. +

+ +
+

+Note: see the section +Typesetting macros during document processing +for information and advice on using indents with the +document processing macros. +

+
+ +
+

Indents macros

+ + +
+ + + +
+

Indent left

+
+ +
+Macro: IL [ <measure> ] +
+

+• The optional argument requires a unit of measure +

+ +

+IL indents text from the left margin of the page, or if you’re +in a tab, from the left edge of the tab. Once IL is on, the left +indent is applied uniformly to every subsequent line of text, even +if you change the line length. +

+ +

+The first time you invoke .IL, you must give it a +measure. Subsequent invocations with a measure add to the previous +measure. A minus sign may be prepended to the argument to subtract +from the current measure. The +\w +inline escape +may be used to specify a text-dependent measure, in which case no +unit of measure is required. For example, +
+ + .IL \w'margarine' + +indents text by the width of the word “margarine”. +

+ +

+With no argument, IL after an ILX indents by its last active value. See the +explanation of how mom handles indents +for more details. +

+ +
+

+Note: Calling a tab (with +.TAB <n>) +automatically cancels any active indents. +

+ +

+Additional note: Invoking IL +automatically turns off IB. +

+
+ + + +
+

Indent right

+
+ +
+Macro: IR [ <measure> ] +
+

+• The optional argument requires a unit of measure +

+ +

+IR indents text from the right margin of the page, or if +you’re in a tab, from the end of the tab. +

+ +

+The first time you invoke .IR, you must give it a +measure. Subsequent invocations with a measure add to the previous +indent measure. A minus sign may be prepended to the argument to +subtract from the current indent measure. The +\w +inline escape +may be used to specify a text-dependent measure, in which case no +unit of measure is required. For example,
+ + .IR \w'jello' + +indents text by the width of the word “jello”. +

+ +

+With no argument, IR after an IRX indents by its last active value. See the +explanation of how mom handles indents +for more details. +

+ +
+

+Note: Calling a tab (with +.TAB <n>) +automatically cancels any active indents. +

+ +

+Additional note: Invoking IR +automatically turns off IB. +

+
+ + + +
+

Indent both

+
+ +
+Macro: IB [ <indent-1> <indent-2> ] +
+

+• The optional arguments require a unit of measure +

+ +

+IB allows you to set or invoke a left and a right indent at the same +time. +

+ +

+If you supply only an indent-1 argument, the argument is +the amount to indent from both the left and right margins. If you +give both indent-1 and indent-2, the first is +the indent from the left margin and the second is the indent from +the right margin. +

+ +

+As with IL and IR, the measures are added to the values previously +passed to the macro. Hence, if you wish to change just one of the +values, you must give an argument of zero to the other. (A word of +advice: If you need to manipulate left and right indents separately, +use a combination of IL and IR instead of IB. You’ll save +yourself a lot of grief.) +

+ +

+A minus sign may be prepended to the arguments to subtract from +their current values. The +\w +inline escape +may be used to specify text-dependent measures, in which case no +unit of measure is required. For example, +
+ + .IB \w’margarine’ \w'jello' + +left indents text by the width of the word “margarine” +and right indents by the width of “jello”. +

+ +

+Like IL and IR, IB with no argument after an IBX indents by its +last active values. See the +explanation of how mom handles indents +for more details. +

+ +
+

+Note: Calling a tab (with +.TAB <n>) +automatically cancels any active indents. +

+ +

+Additional note: Invoking IB +automatically turns off IL and IR. +

+
+ + + +
+

Temporary (left) indent

+
+ +
+Macro: TI [ <measure> ] +
+

+• The optional argument requires a unit of measure +

+ +

+A temporary indent is one that applies only to the first line of +text that comes after it. Its chief use is indenting the first line +of paragraphs. (Mom’s +PP +macro, for example, uses a temporary indent.) +

+ +

+The first time you invoke .TI, you must give +it a measure. If you want to indent the first line of a paragraph +by, say, 2 +ems, +do +
+ + .TI 2m + +Subsequent invocations of TI do not require you to supply a measure; +mom keeps track of the last measure you gave it. +

+ +

+Because temporary indents are temporary, there’s no need to +turn them off. +

+ +
+

+IMPORTANT: Unlike IL, IR, and IB, +measures given to TI are not additive. In the following +example, the second .TI 2P is exactly 2 picas. +
+ + .TI 1P + The beginning of a paragraph... + .TI 2P + The beginning of another paragraph... + +

+
+ + + +
+

Hanging indent

+
+ +
+Macro: HI [ <measure> ] +
+

+• The optional argument requires a unit of measure +

+ +

+A hanging indent looks like this: +
+ + The thousand injuries of Fortunato I had borne as best I + could, but when he ventured upon insult, I vowed + revenge. You who so well know the nature of my soul + will not suppose, however, that I gave utterance to a + threat, at length I would be avenged... + +The first line of text “hangs” outside the left margin. +

+ +

+In order to use hanging indents, you must first have a left indent +active (set with either +.IL +or +.IB). +Mom will not hang text outside the left margin set with +.L_MARGIN +or outside the left margin of a tab. +

+ +

+The first time you invoke .HI, you must give +it a measure. If you want the first line of a paragraph to hang by, +say, 1 pica, do +
+ + .IL 1P + .HI 1P + +Subsequent invocations of HI do not require you to supply a measure; +mom keeps track of the last measure you gave it. +

+ +

+Generally speaking, you should invoke HI immediately prior to the +line you want hung (i.e. without any intervening +control lines). +And because hanging indents affect only one line, there’s no +need to turn them off. +

+ +
+

+IMPORTANT: Unlike IL, IR, and IB, +measures given to HI are NOT additive. Each time you pass a measure +to HI, the measure is treated literally. +

+
+ +

Recipe: A numbered list using hanging indents

+ +
+

+Note: mom has macros for setting lists (see +Nested lists). +This recipe exists to demonstrate the use of hanging indents only. +

+
+ +

+ + .PAGE 8.5i 11i 1i 1i 1i 1i + .FAMILY T + .FT R + .PT_SIZE 12 + .LS 14 + .JUSTIFY + .KERN + .SS 0 + .IL \w'\0\0.' + .HI \w'\0\0.' + 1.\0The most important point to be considered is whether the + answer to the meaning of Life, the Universe, and Everything + really is 42. We have no-one’s word on the subject except + Mr. Adams’. + .HI + 2.\0If the answer to the meaning of Life, the Universe, + and Everything is indeed 42, what impact does this have on + the politics of representation? 42 is, after all not a + prime number. Are we to infer that prime numbers don’t + deserve equal rights and equal access in the universe? + .HI + 3.\0If 42 is deemed non-exclusionary, how do we present it + as the answer and, at the same time, forestall debate on its + exclusionary implications? + +First, we invoke a left indent with a measure equal to the width of +2 +figures spaces +plus a period (using the +\w +inline escape). At this point, the left indent is active; text +afterwards would normally be indented. However, we invoke a +hanging indent of exactly the same width, which hangs the first +line (and first line only!) to the left of the indent by the +same distance (in this case, that means “out to the left +margin”). Because we begin the first line with a number, +a period, and a figure space, the actual text (“The most +important point...”) starts at exactly the same spot as the +indented lines that follow. +

+ +

+Notice that subsequent invocations of .HI don’t +require a measure to be given. +

+ +

+Paste the example above into a file and preview it with +
+ + pdfmom filename.mom > filename.pdf + +to see hanging indents in action. +

+ + + +
+

Quitting indents

+
+ +
+Macro: IQ [ CLEAR ] (quit any/all indents — see IMPORTANT NOTE) +
+
+ +Macro: ILX [ CLEAR ] (exit Indent Left) +
+ +Macro: IRX [ CLEAR ] (exit Indent Right) +
+ +Macro: IBX [ CLEAR ] (exit Indent Both) + +
+

+IMPORTANT NOTE: The original macro +for quitting all indents was IX. This usage has been deprecated in +favour of IQ. IX will continue to behave as before, but mom will +issue a warning to stderr indicating that you should update your +documents. +

+ +

+As a consequence of this change, ILX, IRX and IBX may now also be +invoked as ILQ, IRQ and IBQ. Both forms are acceptable. +

+
+ +

+Without an argument, the macros to quit indents merely restore your +original margins and line length. The measures stored in the indent +macros themselves are saved so you can call them again without +having to supply a measure. +

+ +

+If you pass these macros the optional argument CLEAR, +they not only restore your original left margin and line length, but +also clear any values associated with a particular indent style. +The next time you need an indent of the same style, you have to +supply a measure again. +

+ +

+.IQ CLEAR, as you’d suspect, +quits and clears the values for all indent styles at once. +

+ +

+ + + + + + + + +
Back to Table of ContentsTopNext: Goodies
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/using.html b/contrib/mom/momdoc/using.html new file mode 100644 index 0000000..c93e385 --- /dev/null +++ b/contrib/mom/momdoc/using.html @@ -0,0 +1,319 @@ + + + + + + + + + Using mom + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: The typesetting macros
+ +

Using mom

+ + + +

+ +

Introduction

+ +

+As explained in the section +What is mom?, +mom can be used in two ways: for straightforward typesetting or for +document processing. The difference between the two is that in +straightforward typesetting, every macro is a literal instruction +that determines precisely how text following it will look. Document +processing, on the other hand, uses markup tags (e.g. .PP +for paragraphs, .HEADING for different levels of heads, +.FOOTNOTE for footnotes, etc.) that perform typesetting +operations automatically. +

+ +

+You tell mom that you want to use the document processing macros +with the +START +macro. After START, mom determines the appearance of +text following the markup tags automatically, although you, the +user, can easily change how the tags are interpreted. +

+ +

How to input mom’s macros

+ +

+Regardless of whether you’re preparing a term paper or making a +flyer for your lost dog, the following apply. +

+ +
    +
  1. + You need a good text editor for inputting mom files. +
    + + I cannot recommend highly enough that you use an editor that + lets you write syntax highlighting rules for mom’s + macros and + inline escapes. + Simply colourizing macros and inlines to half-intensity can be + enough to make text stand out clearly from formatting commands. + Mom herself comes with a complete set of syntax highlighting + rules for the vim editor. A number of freely available editors + come with groff syntax highlighting rules, which are sufficient + for mom files, though not as colourful or complete as the vim + rules that ship with mom. + +
  2. +
  3. + Macros begin with a period (dot) at the left margin of your text + editor’s screen, and must be entered in upper case (capital) + letters. +
  4. +
  5. + Macro + arguments + are separated from the macro itself by spaces. Multiple + arguments to the same macro are separated from each + other by spaces. Any number of spaces may be used. +
  6. +
  7. + Arguments to a macro must appear on the same line as the + macro. +
    + + If the argument list is very long, you may use the + backslash character (\) to break the line visually. + From groff’s point of view, the backslash and newline are + invisible. Thus, for example, + + .HEADING_STYLE 1 FAMILY Garamond FONT B SIZE +2 + + and + + .HEADING_STYLE 1 \ + FAMILY Garamond \ + FONT B \ + SIZE +2 + + + are exactly equivalent. +
  8. +
  9. + Any argument (except a + string argument) + that is not a digit must be entered in upper case + (capital) letters. +
  10. +
  11. + Any argument that requires a plus or minus sign must + have the plus or minus sign prepended to the argument + with no intervening space (e.g. +2). +
  12. +
  13. + Any argument that requires a + unit of measure + must have the unit appended directly to the argument, with no + intervening space (e.g. .5i). +
  14. +
  15. + String arguments, + in the sense of this manual, must be surrounded by double-quotes + (e.g. "text"). Multiple + string arguments are separated from each other by spaces (with + each argument surrounded by double-quotes). +
    + + If a string argument becomes + uncomfortably long, you may break it into two or more lines + with the backslash character. + + .SUBTITLE "An In-Depth Consideration of the \ + Implications of Forty-Two as the Answer to Life, \ + The Universe, and Everything" + + +
  16. +
+ +
+

+Tip: +It’s important that your documents be easy to read and +understand in a text editor. One way to achieve this is to group +macros that serve a similar purpose together, and separate them from +other groups of macros with a comment line. In groff, that’s +done with \# (backslash-pound) or .\" +(period-backslash-doublequote) on a line by itself. Either +instructs groff to ignore the remainder of the line, which may or +may not contain text. Consider the following, which is a template +for starting the chapter of a book. +
+ + \# Reference/meta-data + .TITLE "My Pulitzer Novel" + .AUTHOR "Joe Blow" + .CHAPTER 1 + \# Template + .DOCTYPE CHAPTER + .PRINTSTYLE TYPESET + \# Type style + .FAM P + .PT_SIZE 10 + .LS 12 + \# + .START + +You may also, if you wish, add a comment to the end of a line with +\" (no period), like this: +
+ + .FAMILY P \" Maybe Garamond instead? + +

+
+ +

Processing and viewing documents

+ +

+The most basic command-line usage for processing a file formatted +with the mom macros is +
+ + groff -mom filename.mom > filename.ps + +which processes the .mom file and dumps the output into a +viewable/printable PostScript file. +

+ +

Mom and PDF

+ +

+Adobe’s Portable Document Format (PDF) has largely supplanted +PostScript, of which it is a subset, as the standard for typeset +documents. While printed versions of documents in either format +will be identical, PDF documents, when viewed at the screen, may +also contain clickable links and a number of other special features. +

+ +

+As of version 2.0, mom supports full PDF integration. The creation +and processing of mom files into PostScript documents remains +unchanged from 1.x, but the expected and recommended format of final +documents is now PDF. +

+ +

+The manual, +Producing PDFs with groff and mom, +explains and demonstrates the PDF-specific macros that are available +in mom, as well as the use of pdfmom, the +recommended way to process mom files. +

+ +

pdfmom

+ +

+Groff provides more than one way to generate PDF documents, +but when processing files formatted with the mom macros, +pdfmom is the recommended and most robust way to do +it: +
+ + pdfmom filename.mom > filename.pdf + +pdfmom is a wrapper around groff, and accepts all +groff’s command-line options as listed in the groff manpage. +Full usage is explained in the manual, +Producing PDFs with groff and mom. +

+ +

+PDF links in a document, including linked entries in the +Table of Contents, are identified by colour. When printing +documents with links, you will most likely not want the link +text coloured. The groff option, -c, disables colour +throughout a document; thus, when preparing a document for printing, +you should use: +
+ + pdfmom -c filename.mom > filename.pdf + +pdfmom tends to produce large files. You may +reduce their size by piping them through ps2pdf: +
+ + pdfmom -c filename.mom | ps2pdf - filename.pdf + +Be aware, though, that files piped through ps2pdf will lose some pdf +metadata, notably the document window title set with PDF_TITLE. +

+ +

Automatic previewing of documents

+ +

+Most PDF viewers have a “Watch File” option, which +automatically updates a displayed document whenever there’s +a change. This is useful when preparing documents that require +judgment calls. I recommend creating a keymapping in your +text editor that both saves the mom file and processes it with +pdfmom. The displayed PDF then automatically +reflects whatever changes you save to the mom file. +

+ +

+ + + + + + + + +
Back to Table of ContentsTopNext: The typesetting macros
+ +
+ +

+ + + diff --git a/contrib/mom/momdoc/version-2.html b/contrib/mom/momdoc/version-2.html new file mode 100644 index 0000000..bd1cb8d --- /dev/null +++ b/contrib/mom/momdoc/version-2.html @@ -0,0 +1,424 @@ + + + + + + + + + Mom -- Version 2.0 notes + + + + + + + +
+ + + + + + + +
Back to Table of ContentsNext: Introduction to mom
+ +

Version 2.0 notes

+ + + +

+ +

1. Prefatory comments

+ +

+Version 2.0 comes about as a result of Deri James’ +contribution of gropdf to groff, +and his subsequent work integrating the device with +mom. +

+ +

+Whereas the 1.x releases were oriented toward PostScript output, +2.0 focuses on PDF output, a bias reflected throughout this +documentation. Users are strongly encouraged to process their files +with +pdfmom, +a wrapper around groff -Tpdf, in order to take +full advantage of all PDF has to offer. +

+ +

+While portions of mom have been rewritten, and new features +introduced, 2.0 is backwardly compatible with 1.x releases. Changes +are either transparent, or accompanied by notifications on stderr. +

+ +

+The implementation of nested heads has been completely rethought, +as has the manner of styling of them. There are no limits on +how deep the nesting can go. The 1.x macros HEAD, +SUBHEAD, and SUBSUBHEAD may still be used, but +must be re-designed with the new HEADING_STYLE macro +if their 1.x defaults are not desired. +

+ +

+In conjunction with the changes to nested heads, Table of Contents +generation has also been rethought. Greater flexibility in the +inclusion of toc entry numbering been added. Like nested heads, +there’s a new macro TOC_ENTRY_STYLE that permits +styling of each level in the toc hierarchy separately. The default +overall layout has also been significantly improved, achieving a +level of typographical elegance formerly lacking. Best of all, the +Table of Contents can now be repositioned to the correct spot at the +top of a document from within the mom source file. +

+ +

+When mom files are processed with pdfmom, a PDF +outline for the Contents panel of PDF viewers is automatically +generated. In addition, entries in the Table of Contents +are clickable links when a document is viewed at the screen. +pdfmom also permits setting a document’s +papersize within the source file without the corresponding need for +-P-p<papersize> on the command line. +

+ +

+Lastly, while not strictly part of mom, a bash script, +install-font.sh, has been posted at the +mom site. +The script significantly eases the installation of new +groff families and fonts, with conversion to .pfa +and .t42 being performed by fontforge. +

+ +

2. Differences between v2.0 and v1.x

+ +

2.1. PDF support

+ +

+PDF support has been added, with features including the automatic +generation of PDF outlines, embedding of images in PDF format (via +the +PDF_IMAGE +macro) and PDF linking (internal and external). +

+ +

2.1.1. Producing PDFs with groff and mom

+ +

+A manual in PDF format, +Producing PDFs with groff and mom, +has been added to the documentation. The file, +mom-pdf.pdf can be found in +
+ + /usr/local/share/doc/groff-<version>/pdf/ + +or +
+ + /usr/share/doc/groff-base/pdf/ + +or at +
+ + http://www.schaffter.ca/mom/momdoc/mom-pdf.pdf + +PDF usage, and all associated macros except +PDF_IMAGE, +are fully explained in the manual, which should be considered an +integral part of the present documentation. In addition, the mom +source file for the manual can be found in +
+ + /usr/local/share/doc/groff-<version>/examples/mom + +or +
+ + /usr/share/doc/groff-base/examples/mom/ + +and provides an excellent demonstration of mom usage. +

+ +

2.1.2. PDF_IMAGE

+ +

+A new macro for embedding PDF images has been added, +PDF_IMAGE. +

+ +

+PDF_IMAGE functions similarly to PSPIC and accepts the same +arguments. Differences in implementation are that PDF_IMAGE +requires the image dimensions (the bounding box) to be supplied. +Instructions for getting the bounding box are included in the +documentation entry for PDF_IMAGE. Two additional options, +SCALE and ADJUST, allow scaling of the image +and optical centering. +

+ +

2.2. Covers

+ +

+Arguments to +COVER +and +DOC_COVER +may now be given in any order. +

+ +

2.3. Headings

+ +

+The 1.x macros HEAD, SUBHEAD, SUBSUBHEAD, are now deprecated and +have been replaced by the single macro +HEADING <n>, +where <n> is the heading level. The deprecated +macros may still be used, and conform in style to their original +defaults; they are, however, wrappers around HEADING levels 1 +– 3. Both the wrappers and HEADING itself can take a +NAMED <id> argument, specifying a PDF link +destination. +

+ +

+Styling of headings is managed by the single macro HEADING_STYLE <n> where +<n> conforms to a heading level. The control +macros for HEAD, SUBHEAD and SUBSUBHEAD have been removed. Users +wishing to style the wrappers must use HEADING_STYLE. +

+ +

+PARAHEAD is no longer valid. Paragraph heads in 2.0 are created +by passing the PARAHEAD argument to HEADING. Mom +will abort with an informational message whenever she encounters +.PARAHEAD. +

+ +

2.4. Margin notes

+ +

+The macro for setting margin note parameters, +MN_INIT, +has been re-written such that each parameter now has the form +<PARAMETER> <value>. This differs +from 1.x where parameters were entered without a preceding +<PARAMETER> flag. Parameters may be entered in any +order. Any that are skipped are set to default values. Documents +created with 1.x will have to have their MN_INIT updated +accordingly. +

+ +

2.5. Floats

+ +

+A +FLOAT +macro has been added, which functions similarly to the ms +macros’ .KF/.KE, i.e., the contents of the float are +output immediately if there’s room on the page, otherwise +normal text processing continues and the contents are output at the +top of the next page. An ADJUST argument to FLOAT allows +for optical centering. +

+ +

2.6. Tables of contents

+ +

+The default look of the Table of Contents has been overhauled to +produce a more typographically pleasing result. All control macros +for TOC title and entry styles have been removed, replaced by +TOC_TITLE_STYLE +and +TOC_ENTRY_STYLE <n> +where <n> corresponds to a heading level. Both +macros permit setting any or all of the style parameters for TOC +titles (i.e. chapters or major sections/divisions of a collated +document) and TOC entries (nested heading levels) at once. +Documents created with 1.x that contain TOCs will need to have their +TOC style updated if the new defaults are unsatisfactory. +

+ +

+Two new TOC control macros have been added, +SPACE_TOC_ITEMS +and +AUTO_RELOCATE_TOC. +SPACE_TOC_ITEMS groups TOC entry levels and separates them with a +discrete amount of whitespace. This leads to improved legibility, +and is highly recommended even though it is not mom’s +default. AUTO_RELOCATE_TOC intelligently repositions the Table +of Contents to the top of a document when the mom source file is +processed with +pdfmom. +

+ +

3. Version 2.1 changes

+

Version 2.1 adds these features:

    +
  • expansion of cover, docheader, page header, and heading + control macros to permit caps, smallcaps, color, and + underscoring
  • +
  • the ability to style every element appearing in docheaders and + automatically-generated cover/title pages separately
  • +
  • macros to place images on cover/title pages
  • +
  • a new macro COVERTEXT that allows adding text (e.g. an + Abstract) to automatically-generated cover/title pages or to + create cover/title pages entirely by hand
  • +
  • separate indent control macros for QUOTES and BLOCKQUOTES
  • +
  • pseudo-smallcaps, including a control macro to choose the + size, weight, and width of the small caps
  • +
  • new <element>_STYLE macros that allow setting + parameters for <element> with a single macro using + keyword/value pairs
  • +
+ +

+The following changes have been made: +

+ +
    +
  • MISC_AUTOLEAD (including COVER_MISC_AUTOLEAD and + DOC_COVER_MISC_AUTOLEAD) has been replaced in favour of MISC_LEAD, + which takes an absolute leading value rather than one derived + from the point size.
  • +
  • COVER_UNDERLINE and DOC_COVER_UNDERLINE have been + removed in favour of COVER_DOCTYPE_UNDERLINE and + DOC_COVER_DOCTYPE_UNDERLINE.
  • +
  • DOCTYPE NAMED <string> no longer accepts a + color argument; setting the colour for + <string> is accomplished with DOCTYPE_COLOR + <color>. In addition, the string now has a + complete set of control macros.
  • +
  • Default underscoring of the DOCTYPE NAMED string has been + removed, both in the docheader and on cover/title pages.
  • +
  • No cover/title page data persists, however formatting for the + elements on them does.
  • +
+ +

4. Version 2.2 changes

+ +

+Version 2.2 adds these features: +

+
    +
  • flex-spacing, an alternative to mom’s default shimming + policy; flex-spacing balances vertical whitespace on the page by + distributing any excess equally at sensible points so that running + text always fills the page to the bottom margin (see + + vertical whitespace management) +
  • +
  • improvements to auto-labelling, such that it is now possible + to link symbolically to auto-labelled preprocessor material and + PDF images (note that you must be running groff 1.22.4 or higher + for this feature) +
  • +
+ +

5. Version 2.5 changes

+ +

+Version 2.5 adds shaded backgrounds and frames that span pages +appropriately when necessary, and a macro to set page or slide +background colour. +

+ +

6. pdfmom

+ +

+Deri James has provided pdfmom, a wrapper around +groff that processes mom source files with all the PDF bells and +whistles. Its use is highly recommended. Usage is explained in the +manual, + + Producing PDFs with groff and mom +. +A significant convenience of pdfmom is that it can, with the +-Tps flag, be used to pass processing over to Keith +Marshall’s pdfroff. This is useful when +processing files that contain PostScript images embedded with +PSPIC. +pdfmom, without the flag, uses groff’s PDF device +(gropdf), which only recognizes PDF images that +have been embedded with +PDF_IMAGE. +

+ +

7. install-font.sh

+ +

+A bash script, install-font.sh, has been posted at the +mom site. +There’s nothing mom-specific about the script, and it is not +an official part of groff. +

+ +

+Installing groff fonts is a multi-step procedure, which, while not +difficult, can be a nuisance. install-font.sh takes +care of all the details, including converting fonts to formats +acceptable to grops and gropdf, +creating and installing the groff fonts in the appropriate +directories, updating the download files, and installing the +original fonts in a system-wide directory, if desired. +

+ +

+ + + + + + + + +
Back to Table of ContentsTopNext: Introduction to mom
+ +
+ +

+ + + diff --git a/contrib/mom/om.tmac b/contrib/mom/om.tmac new file mode 100644 index 0000000..adb7508 --- /dev/null +++ b/contrib/mom/om.tmac @@ -0,0 +1,24571 @@ +.ig +Mom -- a typesetting/document-processing macro set for groff. + +Copyright (C) 2002-2020 Free Software Foundation, Inc. + Written by Peter Schaffter + PDF integration contributed by Deri James + +This file 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 . + +Version 2.5_d +------------- +Antoine de St-ExupĂŠry asserted that elegance in engineering is +achieved not when there is nothing left to add, but when there is +nothing left to take away. + +By those standards, mom is a Rube Goldberg contraption. She was +created over the years while groff, and my understanding of it, +changed and evolved. However, I'm a firm believer in "if it ain't +broke, don't fix it." Version 2.0 removed some of the redundancies +and cruft, but mom still needs some nip and tuck. + +"" in the description of arguments that can be passed +to a macro means that any argument turns the feature off. + +Thanks to everyone who has contributed suggestions and patches, +and to those whose GPL'd work has been plundered. Special thanks +to Werner Lemberg (margin notes), Tadziu Hoffman (underlining), +Deri James (pdf integration), Robin Haberkorn (tbl integration, eqn +extensions, and float management). +.. +\# +\# ==================================================================== +\# +.if \n(.C \ +. ab [mom]: The groff mom macros do not work in compatibility mode. +\# Check that GNU troff is being run +.if !\n[.g]=1 \ +. ab [mom]: The mom macros require that you be running GNU troff. +\# Check which version of groff is being run +.if (\n[.x]\n[.y] < 118) \ +. ab [mom]: You need GNU troff version 1.18 or higher to run this version of mom. +\# Mom version +.ds version 2.5_d +.if dVERSION \{\ +. ab [mom]: Version \*[version] +.\} +\# Groff revision +.ds short_revision \n[.Y] +.substring short_revision 0 0 +\# +\# Add supplementary styles +.sty \n[.fp] UL \" Ultra Light +.sty \n[.fp] ULI \" Ultra Light Italic +.sty \n[.fp] ULCD \" Ultra Light Condensed +.sty \n[.fp] ULCDI \" Ultra Light Condensed Italic +.sty \n[.fp] ULEX \" Ultra Light Extended +.sty \n[.fp] ULEXI \" Ultra Light Extended Italic +\# +.sty \n[.fp] XL \" Extra Light +.sty \n[.fp] XLI \" Extra Light Italic +.sty \n[.fp] XLCD \" Extra Light Condensed +.sty \n[.fp] XLCDI \" Extra Light Condensed Italic +.sty \n[.fp] XLEX \" Extra Light Extended +.sty \n[.fp] XLEXI \" Extra Light Extended Italic +\# +.sty \n[.fp] TH \" Thin +.sty \n[.fp] THI \" Thin Italic +.sty \n[.fp] THCD \" Thin Condensed +.sty \n[.fp] THCDI \" Thin Condensed Italic +.sty \n[.fp] THEX \" Thin Extended +.sty \n[.fp] THEXI \" Thin Extended Italic +\# +.sty \n[.fp] L \" Light Roman +.sty \n[.fp] LI \" Light Italic +.sty \n[.fp] LCD \" Light Condensed +.sty \n[.fp] LCDI \" Light Condensed Italic +.sty \n[.fp] LEX \" Light Extended +.sty \n[.fp] LEXI \" Light Extended Italic +\# +.sty \n[.fp] BK \" Book Roman +.sty \n[.fp] BKI \" Book Italic +.sty \n[.fp] BKCD \" Book Condensed +.sty \n[.fp] BKCDI \" Book Condensed Italic +.sty \n[.fp] BKEX \" Book Extended +.sty \n[.fp] BKEXI \" Book Extended Italic +\# +.sty \n[.fp] CD \" Medium Condensed +.sty \n[.fp] CDI \" Medium Condensed Italic +.sty \n[.fp] EX \" Medium Extended +.sty \n[.fp] EXI \" Medium Extended Italic +\# +.sty \n[.fp] DB \" DemiBold Roman +.sty \n[.fp] DBI \" DemiBold Italic +.sty \n[.fp] DBCD \" DemiBold Condensed +.sty \n[.fp] DBCDI \" DemiBold Condensed Italic +.sty \n[.fp] DBEX \" DemiBold Extended +.sty \n[.fp] DBEXI \" DemiBold Extended Italic +\# +.sty \n[.fp] SB \" SemiBold Roman +.sty \n[.fp] SBI \" SemiBold Italic +.sty \n[.fp] SBCD \" SemiBold Condensed +.sty \n[.fp] SBCDI \" SemiBold Condensed Italic +.sty \n[.fp] SBEX \" SemiBold Extended +.sty \n[.fp] SBEXI \" SemiBold Extended Italic +\# +.sty \n[.fp] BCD \" Bold Condensed +.sty \n[.fp] BCDI \" Bold Condensed Italic +.sty \n[.fp] BEX \" Bold Extended +.sty \n[.fp] BEXI \" Bold Extended Italic +.sty \n[.fp] BO \" Bold Outline +\# +.sty \n[.fp] XB \" Extra Bold +.sty \n[.fp] XBI \" Extra Bold Italic +.sty \n[.fp] XBCD \" Extra Bold Condensed +.sty \n[.fp] XBCDI \" Extra Bold Condensed Italic +.sty \n[.fp] XBEX \" Extra Bold Extended +.sty \n[.fp] XBEXI \" Extra Bold Extended Italic +\# +.sty \n[.fp] UB \" Ultra Bold +.sty \n[.fp] UBI \" Ultra Bold Italic +.sty \n[.fp] UBCD \" Ultra Bold Condensed +.sty \n[.fp] UBCDI \" Ultra Bold Condensed Italic +.sty \n[.fp] UBEX \" Ultra Bold Extended +.sty \n[.fp] UBEXI \" Ultra Bold Extended Italic +\# +.sty \n[.fp] HV \" Heavy +.sty \n[.fp] HVI \" Heavy Italic +.sty \n[.fp] HVCD \" Heavy Condensed +.sty \n[.fp] HVCDI \" Heavy Condensed Italic +.sty \n[.fp] HVEX \" Heavy Extended +.sty \n[.fp] HVEXI \" Heavy Extended Italic +\# +.sty \n[.fp] BL \" Black +.sty \n[.fp] BLI \" Black Italic +.sty \n[.fp] BLCD \" Black Condensed +.sty \n[.fp] BLCDI \" Black Condensed Italic +.sty \n[.fp] BLEX \" Black Extended +.sty \n[.fp] BLEXI \" Black Extended Italic +.sty \n[.fp] BLO \" Black Outline +\# +.sty \n[.fp] XBL \" Extra Black +.sty \n[.fp] XBLI \" Extra Black Italic +.sty \n[.fp] XBLCD \" Extra Black +.sty \n[.fp] XBLCDI \" Extra Black +.sty \n[.fp] XBLEX \" Extra Black Italic +.sty \n[.fp] XBLEXI \" Extra Black Italic +\# +.sty \n[.fp] UBL \" Ultra Black +.sty \n[.fp] UBLI \" Ultra Black Italic +.sty \n[.fp] UBLCD \" Ultra Black Condensed +.sty \n[.fp] UBLCDI \" Ultra Black Condensed Italic +.sty \n[.fp] UBLEX \" Ultra Black Extended +.sty \n[.fp] UBLEXI \" Ultra Black Extended Italic +\# +.sty \n[.fp] SC \" Small Caps Roman +.sty \n[.fp] SCI \" Small Caps Italic +.sty \n[.fp] SCDB \" Small Caps Demibold +.sty \n[.fp] SCDBI \" Small Caps Demibold Italic +.sty \n[.fp] SCSB \" Small Caps Semibold +.sty \n[.fp] SCSBI \" Small Caps Semibold Italic +\# +\# Instruct grops to use square linecaps and joins. +\# This instruction is also executed in DO_B_MARGIN, NEWPAGE, and HEADER +\# +.if !n \X'ps: exec 0 setlinejoin'\X'ps: exec 0 setlinecap' +\# +\# The following PostScript, provided by Tadziu Hoffmann, permits +\# no-fail underlining +\# +.de ul*ps +ps: def +grops begin +/decornone { grops begin /X { } def /Y { } def /y2 -1 def end } def +/decorline { grops begin u neg /uld exch def u /ulw exch def + /X { currentpoint /y0 exch def /x0 exch def } def + /Y { currentpoint /y1 exch def /x1 exch def + drawline /x2 x1 def /y2 y1 def } def end } def +/drawline { gsave ulw setlinewidth 0 setlinecap x1 y1 uld sub moveto + y2 y0 eq { x2 y2 } { x0 y0 } ifelse uld sub lineto stroke + grestore } def +decornone +/uld 0 def +/ulw 0 def +/A { X show Y } def +/B { 0 SC 3 -1 roll X widthshow Y } def +/C { 0 exch X ashow Y } def +/D { 0 exch 0 SC 5 2 roll X awidthshow Y } def +/E { 0 rmoveto X show Y } def +/F { 0 rmoveto 0 SC 3 -1 roll X widthshow Y } def +/G { 0 rmoveto 0 exch X ashow Y } def +/H { 0 rmoveto 0 exch 0 SC 5 2 roll X awidthshow Y } def +/I { 0 exch rmoveto X show Y } def +/J { 0 exch rmoveto 0 SC 3 -1 roll X widthshow Y } def +/K { 0 exch rmoveto 0 exch X ashow Y } def +/L { 0 exch rmoveto 0 exch 0 SC 5 2 roll X awidthshow Y } def +/M { rmoveto X show Y } def +/N { rmoveto 0 SC 3 -1 roll X widthshow Y } def +/O { rmoveto 0 exch X ashow Y } def +/P { rmoveto 0 exch 0 SC 5 2 roll X awidthshow Y } def +/Q { moveto X show Y } def +/R { moveto 0 SC 3 -1 roll X widthshow Y } def +/S { moveto 0 exch X ashow Y } def +/T { moveto 0 exch 0 SC 5 2 roll X awidthshow Y } def +end +.. +\# +.if !n \Y[ul*ps] +.if n .color 0 +.nr TOC.RELOCATE 0 \" TOC.RELOCATE is off by default +.ds PDFHREF.TEXTCOL.DEFAULT 0.0 0.3 0.9 +.nr PDFHREF.VIEW.LEADING.C 3i +.nr PDFHREF.VIEW.LEADING.T 1i +.nr PDFHREF.VIEW.LEADING 0 +.nr PDFHREF.VIEW.LEADING.H \n[PDFHREF.VIEW.LEADING] +\# +\# ==================================================================== +\# +\# TYPESETTING MACROS, STRINGS, AND ALIASES +\# ======================================== +\# +\# +++ALIASES+++ +\# +\# Alias .als as ALIAS, and .aln (number registers) as ALIASN +\# +.als ALIAS als +.als ALIASN aln +\# +\# ALIASES FOR GROFF REQUESTS +\# -------------------------- +\# +.ALIAS MAC de +.ALIAS BR br +.ALIAS SPREAD brp +.ALIAS ESC_CHAR ec +.ALIAS STRING ds +.ALIAS INCLUDE so +\# +\# ALIASES FOR NUMBER REGISTERS +\# ---------------------------- +\# +.ALIASN #PT_SIZE .ps \"fractional point size in units +.ALIASN #DIVER_DEPTH dn \"diversion depth +.ALIASN #DIVER_WIDTH dl \"diversion width +.ALIASN #TRAP_DISTANCE .t \"distance to next trap +.ALIASN #LEAD .v \"line space +.ALIASN #PAGE_LENGTH .p \"page length +.ALIASN #NUM_ARGS .$ \"number of arguments passed to a macro +.ALIASN #INDENT .i \"value of current indent +\# +\# ==================================================================== +\# +\# MISCELLANEOUS +\# ============= +.nr #L_MARGIN \n[.o] \" Tabs, etc require #L_MARGIN +.cflags 4 /\[en] \" So slash and en-dashes get broken +\# +\# 'END' is used throughout as the 2nd arg to 'MAC' (alias of .de) +\# Defining it as a macro here prevents groff from complaining +\# that 'END' isn't defined. +\# +.de END +.. +\# +\# ==================================================================== +\# +\# +++PAGE LAYOUT+++ +\# +\# Macros that control the physical layout of the page: paper size +\# and margins. +\# +\# PAGE WIDTH +\# ---------- +\# *Argument: +\# +\# *Function: +\# Stores user supplied page width in register #PAGE_WIDTH. +\# *Notes: +\# #PAGE_WIDTH is used to establish the default LL (and right margin). +\# Requires unit of measure. +\# +.MAC PAGEWIDTH END +. br +. nr #PAGE_WIDTH \\$1 +. if !r#L_MARGIN .L_MARGIN \\n[.o] +. if !r#R_MARGIN .R_MARGIN 1i +. if '\\*[.T]'pdf' \X'papersize=\\n[#PAGE_WIDTH]z,\\n[#PAGE_LENGTH]z'\c +.END +\# +\# L_MARGIN +\# -------- +\# *Argument: +\# +\# *Function: +\# Stores user supplied page offset in register #L_MARGIN. +\# Sets .po to user supplied offset. +\# *Notes: +\# Requires unit of measure. +\# +.MAC L_MARGIN END +. br +. nr #L_MARGIN (\\$1) +. po \\n[#L_MARGIN]u +.END +\# +\# R_MARGIN +\# -------- +\# *Argument: +\# +\# *Function: +\# Stores user supplied right margin in register #R_MARGIN. +\# *Notes: +\# This is a pseudo-margin. Right margin is actually a function of +\# line length. The macro calculates line length from the page offset +\# and the value plugged into #R_MARGIN. +\# +\# N.B. -- PAGEWIDTH and L_MARGIN have to be defined before R_MARGIN. +\# +\# Requires unit of measure. +\# +.MAC R_MARGIN END +. br +. nr #R_MARGIN (\\$1) +. ll \\n[#PAGE_WIDTH]u-\\n[#L_MARGIN]u-\\n[#R_MARGIN]u +. ta \\n[.l]u +. nr #L_LENGTH \\n[.l] +.END +\# +\# T_MARGIN +\# -------- +\# *Argument: +\# +\# *Function: +\# Stores the user supplied top margin in register #T_MARGIN. +\# Advances user supplied depth from the top of the page. +\# *Notes: +\# Requires unit of measure. +\# +.MAC T_MARGIN END +. nr #T_MARGIN (\\$1) +. if !\\n[#DOCS] .sp |\\n[#T_MARGIN]u-1v +. wh 0i DO_T_MARGIN +.END +\# +\# B_MARGIN +\# -------- +\# *Argument: +\# +\# *Function: +\# Stores the user supplied bottom margin in register #B_MARGIN. +\# *Notes: +\# Requires unit of measure. +\# +.MAC B_MARGIN END +. br +. nr #B_MARGIN (\\$1) +. nr #ORIGINAL_B_MARGIN \\n[#B_MARGIN] +. nr #B_MARGIN_SET 1 +. wh -\\n[#B_MARGIN]u DO_B_MARGIN +.END +\# +\# PAGE +\# ---- +\# *Arguments: +\# [pagelength [leftmargin [rightmargin [topmargin [bottommargin]]]]] +\# *Function: +\# Page set-up. Collects arguments and passes them to the appropriate +\# macros. +\# *Notes: +\# All arguments after pagewidth are optional, but must appear +\# in the order given above. (User can fill in as much or as +\# little as desired.) +\# +\# All arguments require a unit of measure. +\# +.MAC PAGE END +. br +. PAGEWIDTH \\$1 +. PAGELENGTH \\$2 +. ie '\\$3'' .L_MARGIN \\n[.o] +. el .L_MARGIN \\$3 +. ie '\\$4'' .R_MARGIN 1i +. el .R_MARGIN \\$4 +. if !'\\$5'' .T_MARGIN \\$5 +. if !'\\$6'' .B_MARGIN \\$6 +.END +\# +\# gropdf: pass pagelength to postprocessor; no need for -P-p +\# +.MAC PAGELENGTH END +. pl \\$* +. if '\\*[.T]'pdf' \X'papersize=\\n[#PAGE_WIDTH]z,\\n[#PAGE_LENGTH]z'\c +.END +\# +\# ===================================================================== +\# +\# +++PAGE CONTROL+++ +\# +\# Generic macros for breaking pages. +\# +\# DO_T_MARGIN +\# ----------- +\# *Argument: +\# +\# *Function: +\# Plants the top margin at the top of each page. +\# *Notes: +\# The trap is set in .T_MARGIN or .PAGE +\# +.MAC DO_T_MARGIN END +. ev T_MARGIN +. sp |\\n[#T_MARGIN]u-1v +. ev +.END +\# +\# DO_B_MARGIN +\# ----------- +\# *Argument: +\# +\# *Function: +\# Plants the bottom margin at the bottom of each page. +\# *Notes: +\# The trap is set in .B_MARGIN or .PAGE. +\# +.MAC DO_B_MARGIN END +. nr #T_MARGIN_LEAD_ADJ \\n[#LEAD]-12000 +. ev B_MARGIN +. if !n .nop \X'ps: exec 0 setlinejoin'\X'ps: exec 0 setlinecap' +. ie \\n[#DOCS] \ +. if !\\n[#NEWPAGE] .bp +. el .bp +. ev +.END +\# +\# NEWPAGE +\# ------- +\# *Argument: +\# +\# *Function: +\# Breaks to a new page. +\# *Notes: +\# If a B_MARGIN has been set, processes that, otherwise, just +\# breaks to a new page. +\# +.MAC NEWPAGE END +. br +. if \\n[#DOC_TYPE]=5 \{\ +. if \\n[#NUM_ARGS]>0 \ +. pdftransition PAGE \\$1 +. \} +. if !\\n[defer] \{\ +. nr #NEWPAGE 1 +. rr tbl*no-print-header +. \} +. ie !\\n[#DOCS]=1 \ +. if \\n[#B_MARGIN_SET]=1 .DO_B_MARGIN +. el \{\ +. if (\\n[#COLUMNS]=1):(\\n[#COLUMNS]=2) .nr #COL_NUM \\n[#NUM_COLS] +. if !\\n[#FN_DEPTH] \{\ +. ch FN_OVERFLOW_TRAP +. nr #RESET_FN_OVERFLOW_TRAP 1 +. \} +. \} +. if dPDF.EXPORT \ +. if \\n[#FLEX_ACTIVE] \ +. if !\\n[#NO_FLEX] \ +. tm .ds pre-newpage-\\n% \\n%@\\n[#COL_NUM] +. ie \\n[#DOCS]=1 \{\ +. if (\\n[@TOP]=0):(\\n[#END_COVER]=1) .bp +. rr #END_COVER +. if \\n[#RESET_FN_OVERFLOW_TRAP] \{\ +. wh -\\n[#FN_OVERFLOW_TRAP_POS]u FN_OVERFLOW_TRAP +. rr #RESET_FN_OVERFLOW_TRAP_POS +. \} +. \} +. el .if !\\n[#B_MARGIN_SET]=1 .bp +.END +\# +.ALIAS NEWSLIDE NEWPAGE +\# +\# ===================================================================== +\# +\# +++GENERAL STYLE MACROS+++ +\# +\# LINE LENGTH +\# ----------- +\# *Argument: +\# +\# *Function: +\# Stores user supplied line length in register #L_LENGTH. +\# Sets .ll to #L_LENGTHu +\# *Notes: +\# Requires unit of measure. +\# +.MAC LL END +. nr #USER_SET_L_LENGTH 1 +. ll \\$1 +. nr #L_LENGTH \\n[.l] +. ta \\n[.l]u +.END +\# +\# +++FAMILY AND FONT+++ +\# +\# FALLBACK FONT +\# ------------- +\# *Argument: +\# [ ABORT | WARN ] | ABORT | WARN +\# *Function: +\# Sets register #ABORT_FT_ERRORS to 1, or defines a fallback font +\# called "dummy" at font position 0. +\# *Notes: +\# Calls to non-existent families cause mom to continue processing +\# files using the fallback font until a valid family is entered. +\# +\# Calls to non-existent fonts generate warnings. If ABORT is passed +\# to FALLBACK_FONT, mom stops processing files after the warning. +\# Otherwise, she continues to process files using the fallback font +\# after the warning is issued. The default fallback font is CR; the +\# default for font warnings is to abort. +\# +.MAC FALLBACK_FONT END +. if \\n[#NUM_ARGS]=1 \{\ +. if '\\$1'ABORT' .nr #ABORT_FT_ERRORS 1 +. if '\\$1'WARN' \ +. if r #ABORT_FT_ERRORS .nr #ABORT_FT_ERRORS 0 +. if !'\\$1'ABORT' \ +. if !'\\$1'WARN' .fp 0 dummy \\$1 +. \} +. if \\n[#NUM_ARGS]=2 \{\ +. fp 0 dummy \\$1 +. if '\\$2'ABORT' .nr #ABORT_FT_ERRORS 1 +. if '\\$2'WARN' .nr #ABORT_FT_ERRORS 0 +. \} +.END +\# +.FALLBACK_FONT CR ABORT +\# +\# FAMILY +\# ------ +\# *Argument: +\# +\# *Function: +\# Stores user supplied font family in string $FAMILY. Sets .fam +\# to $FAMILY. +\# +.MAC FAMILY END +. if '\\n[.ev]'COVER_TEXT' .ds $SAVED_DOC_FAM \\n[.fam] +. if \\n[#COLLATE] .rm $SAVED_DOC_FAM +. ds $FAMILY \\$1 +. if \\n[#PRINT_STYLE]=1 \{\ +. fam \\*[$TYPEWRITER_FAM] +. return +. \} +. if \\n[#IGNORE] \{\ +. fam \\*[$TYPEWRITER_FAM] +. return +. \} +. if (\\n[.x]\\n[.y]\\*[short_revision] >= 1192) .ds $SAVED_STYLE \\n[.sty] +. ft 0 +. fam \\*[$FAMILY] +. if (\\n[.x]\\n[.y]\\*[short_revision] >= 1192) \{\ +. ft \\*[$SAVED_STYLE] +. if !F\\n[.fn] .ft 0 +. \} +. ie \\n[#PRE_COLLATE]=1 . +. el \{\ +. if \\n[#COLLATE]=1 \ +. if !r#START .ds $DOC_FAM \\*[$FAMILY] +. \} +.END +\# +\# FONT +\# ---- +\# *Argument: +\# R | I | B | BI | +\# *Function: +\# Stores user supplied font in $FONT and sets .ft to $FONT. +\# +.MAC FT END +. ds $FONT \\$1 +. if \\n[#PRINT_STYLE]=1 \{\ +. ie '\\$1'I' \{\ +. if \\n[#UNDERLINE_ITALIC]=1 \{\ +. UNDERLINE +. return +. \} +. if \\n[#ITALIC_MEANS_ITALIC]=1 \{\ +. ds $FONT \\$1 +. ft \\*[$FONT] +. return +. \} +. \} +. el .UNDERLINE OFF +. return +. \} +. ft 0 +. ft \\*[$FONT] +. if (\\n[.x]\\n[.y]\\*[short_revision] >= 1192) \{\ +. if '\\n[.sty]'' \{\ +. if !F\\n[.fn] \{\ +. if !S\\*[$FONT] \{\ +. tm1 "[mom]: Font style "\\*[$FONT]" at line \\n[.c] has not been registered. +. ie \\n[#ABORT_FT_ERRORS]=0 \ +. tm1 " Continuing to process using fallback font. +. el .ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. if \\n[.f]=0 \{\ +. tm1 "[mom]: Either font style "\\*[$FONT]" at line \\n[.c] does not exist in family "\\n[.fam]", +. tm1 " or family "\\n[.fam]" has not been installed. +. ie \\n[#ABORT_FT_ERRORS]=0 \ +. tm1 " Continuing to process using fallback font. +. el .ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. \} +. \} +. \} +.END +\# +\# POINT SIZE +\# ---------- +\# *Arguments: +\# +\# *Function: +\# Sets point size to user supplied value in scaled points. +\# If #AUTO_LEAD is on, resets lead accordingly. +\# *Notes: +\# Must NOT use a unit of measure. +\# +.MAC PT_SIZE END +. if \\n[#PRINT_STYLE]=1 .return +. if \\n[#IGNORE] .return +. ps \\$1 +. nr #PT_SIZE_IN_UNITS \\n[.ps] +. ie '\\$0'DOC_PT_SIZE' \{\ +. if !\\n[#DOCS] .DOC_MACRO_ERROR \\$0 +. br +. nr #NEW_DOC_PT_SIZE \\n[.ps] +. if \\n[#DOC_AUTOLEAD] \{\ +. ie !\\n[#DOC_AUTOLEAD_FACTOR] .nr #AUTOLEADING \\n[#DOC_AUTOLEAD] +. el .nr #AUTOLEADING \\n[.ps]*\\n[#DOC_AUTOLEAD]/1000-\\n[.ps] +. nr #DOC_LEAD \\n[.ps]+\\n[#AUTOLEADING] +. nr #RESET_TRAPS 1 +. \} +. \} +. el \{\ +. if \\n[#AUTO_LEAD] \{\ +. nr #SAVED_VS \\n[.v] +. vs \\n[.ps]u+\\n[#AUTOLEADING]u +. \} +. \} +. if \\n[pdfbx-running]=1 \{\ +. nr #VS_DIFF \\n[#SAVED_VS]-\\n[.v] +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u+\\n[#VS_DIFF]u +. \} +.END +\# +\# SIZE (inline) +\# ------------- +\# *Arguments: +\# +\# *Function: +\# Sets point size to user supplied value in scaled points. +\# Intended to be called inline with \*[SIZE ] +\# *Notes: +\# Can be used with a unit of measure or not. +\# +.MAC SIZE END +\c +.ps \\$1 +.END +\# +\# LEADING +\# ------- +\# *Argument: +\# +\# *Function: +\# Turns off #AUTOLEAD if it's on. +\# Sets .vs to user supplied value. +\# *Notes: +\# Does not require unit of measure. LS automatically turns off AUTOLEAD. +\# +.MAC LS END +. br +. if \\n[#PRINT_STYLE]=1 .return +. if \\n[#IGNORE] .return +. if \\n[#AUTO_LEAD] \{\ +. rr #AUTO_LEAD +. rr #AUTOLEAD_VALUE +. rr #AUTOLEADING +. \} +. nr #SAVED_VS \\n[.v] +. vs \\$1 +. if \\n[pdfbx-running]=1 \{\ +. nr #VS_DIFF \\n[#SAVED_VS]-\\n[.v] +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u+\\n[#VS_DIFF]u +. \} +. if !\\n[#START] \ +. if \\n[.t]<\\n[.v] 'bp +.END +\# +\# AUTOLEAD +\# -------- +\# *Argument: +\# [FACTOR] +\# *Function: +\# Stores user supplied auto-lead value in register #AUTOLEAD_VALUE. +\# Adds #AUT0LEAD_VALUE to #PT_SIZE when invoked to set leading. +\# All subsequent PT_SIZE requests reset the leading in the same way until +\# AUTOLEAD is turned off. +\# *Notes: +\# With the optional FACTOR argument, the current point size is +\# multiplied by #AUTOLEAD_VALUE/1000 instead of the two being added +\# together. +\# +.MAC AUTOLEAD END +. if \\n[#PRINT_STYLE]=1 .return +. if \\n[#IGNORE] .return +. nr #AUTO_LEAD 1 \" autolead on or off +. nr #AUTOLEAD_VALUE (p;\\$1) \" arg x 1000 +. ie '\\$2'FACTOR' \{\ +. if !\\n[#DOCS] .nr #DOC_AUTOLEAD_FACTOR \\n[#AUTOLEAD_VALUE] \" save for DOC_PT_SIZE +. nr #AUTOLEADING \\n[.ps]*\\n[#AUTOLEAD_VALUE]/1000-\\n[.ps] +. \} +. el .nr #AUTOLEADING \\n[#AUTOLEAD_VALUE] +. vs \\n[.ps]u+\\n[#AUTOLEADING]u +.END +\# +\# STRINGS FOR INLINE CONTROL OF GENERAL TYPE STYLE +\# ------------------------------------------------ +.ds ROM \Ef[R] +.ds IT \Ef[I] +.ds BD \Ef[B] +.ds BDI \Ef[BI] +.ds PREV \Ef[] +.ds S \Es +\# +\# ===================================================================== +\# +\# +++KERNING+++ +\# +\# AUTOMATIC PAIRWISE KERNING +\# -------------------------- +\# *Arguments: +\# | +\# *Function: +\# Turns automatic pairwise kerning on or off. +\# +.MAC KERN END +. ie '\\$1'' \{\ +. kern +. nr #KERN 1 +. \} +. el \{\ +. kern 0 +. nr #KERN 0 +. \} +.END +\# +\# INLINE KERNING AND HORIZONTAL MOVEMENT +\# -------------------------------------- +\# +\# Inline kerning provides a simple way to adjust the amount of +\# space between any two letters. It's predicated on a unit of +\# measure "U", which, by default, is 1/36 of the current point +\# size as returned by \n[.ps]; e.g., if the current point size is +\# 18, \n[.ps] returns 18000u, therefore U=500u. Since U remains +\# proportional relative to the current point size, the amount of +\# kerning between two letters as expressed in Us remains visually +\# similar regardless of changes in point size. +\# +\# The default value for U may be changed or reset with the +\# KERN_UNIT macro. +\# +.MAC KERN_UNIT END +. ie '\\$1'DEFAULT' .ds $KERN_UNIT 36 +. el .ds $KERN_UNIT \\$1 +.END +\# +.ds $KERN_UNIT 36 +.ds BU \h'-(\En[.ps]u/\E*[$KERN_UNIT]u*\\$1u)' +.ds FU \h'(\En[.ps]u/\E*[$KERN_UNIT]u*\\$1u)' +\# +\# Initialize strings for pre-1.1.3c-style BU and FU +\# +.nr #LOOP 0 1 +.while \n+[#LOOP]<37 \{\ +. ds BU\n[#LOOP] \h'-(\En[.ps]u/\E*[$KERN_UNIT]u*\n[#LOOP]u)' +. ds FU\n[#LOOP] \h'(\En[.ps]u/\E*[$KERN_UNIT]u*\n[#LOOP]u)' +.\} +\# +\# Horizontal movements +\# -------------------- +\# BP1...12.75 and FP1...12.75 move backwards or forwards inline by the +\# specified number of points. +\# +.ds BCK \h'-\\$1' +.ds FWD \h'\\$1' +\# +.ds BP.25 \h'-.25' +.ds BP.5 \h'-.5' +.ds BP.75 \h'-.75' +.ds BP1 \h'-1p' +.ds BP1.25 \h'-1.25p' +.ds BP1.5 \h'-1.5p' +.ds BP1.75 \h'-1.75p' +.ds BP2 \h'-2p' +.ds BP2.25 \h'-2.25p' +.ds BP2.5 \h'-2.5p' +.ds BP2.75 \h'-2.75p' +.ds BP3 \h'-3p' +.ds BP3.25 \h'-3.25p' +.ds BP3.5 \h'-3.5p' +.ds BP3.75 \h'-3.75p' +.ds BP4 \h'-4p' +.ds BP4.25 \h'-4.25p' +.ds BP4.5 \h'-4.5p' +.ds BP4.75 \h'-4.75p' +.ds BP5 \h'-5p' +.ds BP5.25 \h'-5.25p' +.ds BP5.5 \h'-5.5p' +.ds BP5.75 \h'-5.75p' +.ds BP6 \h'-6p' +.ds BP6.25 \h'-6.25p' +.ds BP6.5 \h'-6.5p' +.ds BP6.75 \h'-6.75p' +.ds BP7 \h'-7p' +.ds BP7.25 \h'-7.25p' +.ds BP7.5 \h'-7.5p' +.ds BP7.75 \h'-7.75p' +.ds BP8 \h'-8p' +.ds BP8.25 \h'-8.25p' +.ds BP8.5 \h'-8.5p' +.ds BP8.75 \h'-8.75p' +.ds BP9 \h'-9p' +.ds BP9.25 \h'-9.25p' +.ds BP9.5 \h'-9.5p' +.ds BP9.75 \h'-9.75p' +.ds BP10 \h'-10p' +.ds BP10.25 \h'-10.25p' +.ds BP10.5 \h'-10.5p' +.ds BP10.75 \h'-10.75p' +.ds BP11 \h'-11p' +.ds BP11.25 \h'-11.25p' +.ds BP11.5 \h'-11.5p' +.ds BP11.75 \h'-11.75p' +.ds BP12 \h'-12p' +.ds BP12.25 \h'-12.25p' +.ds BP12.5 \h'-12.5p' +.ds BP12.75 \h'-12.75p' +\# +.ds FP.25 \h'.25' +.ds FP.5 \h'.5' +.ds FP.75 \h'.75' +.ds FP1 \h'1p' +.ds FP1.25 \h'1.25p' +.ds FP1.5 \h'1.5p' +.ds FP1.75 \h'1.75p' +.ds FP2 \h'2p' +.ds FP2.25 \h'2.25p' +.ds FP2.5 \h'2.5p' +.ds FP2.75 \h'2.75p' +.ds FP3 \h'3p' +.ds FP3.25 \h'3.25p' +.ds FP3.5 \h'3.5p' +.ds FP3.75 \h'3.75p' +.ds FP4 \h'4p' +.ds FP4.25 \h'4.25p' +.ds FP4.5 \h'4.5p' +.ds FP4.75 \h'4.75p' +.ds FP5 \h'5p' +.ds FP5.25 \h'5.25p' +.ds FP5.5 \h'5.5p' +.ds FP5.75 \h'5.75p' +.ds FP6 \h'6p' +.ds FP6.25 \h'6.25p' +.ds FP6.5 \h'6.5p' +.ds FP6.75 \h'6.75p' +.ds FP7 \h'7p' +.ds FP7.25 \h'7.25p' +.ds FP7.5 \h'7.5p' +.ds FP7.75 \h'7.75p' +.ds FP8 \h'8p' +.ds FP8.25 \h'8.25p' +.ds FP8.5 \h'8.5p' +.ds FP8.75 \h'8.75p' +.ds FP9 \h'9p' +.ds FP9.25 \h'9.25p' +.ds FP9.5 \h'9.5p' +.ds FP9.75 \h'9.75p' +.ds FP10 \h'10p' +.ds FP10.25 \h'10.25p' +.ds FP10.5 \h'10.5p' +.ds FP10.75 \h'10.75p' +.ds FP11 \h'11p' +.ds FP11.25 \h'11.25p' +.ds FP11.5 \h'11.5p' +.ds FP11.75 \h'11.75p' +.ds FP12 \h'12p' +.ds FP12.25 \h'12.25p' +.ds FP12.5 \h'12.5p' +.ds FP12.75 \h'12.75p' +\# +\# WHOLE LINE (TRACK) KERNING +\# -------------------------- +\# *Argument: +\# +\# *Function: +\# Invokes .tkf (track kerning) for the current font with +\# 1 as both the upper and lower point size limits, so that +\# the value entered by the user applies regardless of point +\# size. RW ("Reduce Whitespace") reduces the amount of space +\# between all characters by an equal amount. EW ("Extra +\# Whitespace") increases the amount of space. +\# *Notes: +\# Decimal values are acceptable. +\# +\# A value of 1 will produce an unacceptably tight or loose line +\# at most text point sizes; therefore, effective use of RW and +\# EW is in the fractional range below 1. +\# +\# \n[.f] holds the current font number, which is acceptable to .tkf. +\# +\# RW and EW must be reset to 0 to cancel their effect on subsequent +\# output lines. +\# +.MAC RW END +. if \\n[#BR_AT_LINE_KERN] \{\ +. ie \\n[#JUSTIFY]=1 .brp +. el .br +. \} +. rr #EW +. rm $EW +. nr #RW 1 +. ds $RW \\$1 +. tkf \\n[.f] 1 -\\$1 1 -\\$1 +.END +\# +.MAC EW END +. if \\n[#BR_AT_LINE_KERN] \{\ +. ie \\n[#JUSTIFY]=1 .brp +. el .br +. \} +. rr #RW +. rm $RW +. nr #EW 1 +. ds $EW \\$1 +. tkf \\n[.f] 1 \\$1 1 \\$1 +.END +\# +\# BREAK AT LINE KERN +\# ------------------ +\# *Arguments: +\# toggle +\# *Function: +\# Enables/disables .br's before .RW and .EW +\# *Notes: +\# Mostly, users will want .br's before any kind of line kerning, but +\# there may be cases where they don't. BR_AT_LINE_KERN is off by +\# default and must be invoked explicitly. +\# +.MAC BR_AT_LINE_KERN END +. ie '\\$1'' .nr #BR_AT_LINE_KERN 1 +. el .rr #BR_AT_LINE_KERN +.END +\# +\# ===================================================================== +\# +\# +++HYPHENATION+++ +\# +\# AUTO HYPHENATION +\# ---------------- +\# *Arguments: +\# | | DEFAULT +\# or +\# LINES | MARGIN | SPACE +\# *Function: +\# Turns auto hyphenation on or off, resets the hyphenation style +\# to default, or permits the setting of various hyphenation +\# parameters. +\# *Notes: +\# HY, by itself, defaults to .hy 14, i.e. no hyphens after the +\# first two or before the last two characters of a word, and no +\# hyphenation of the last line prior to a trap (e.g., at the +\# bottom of a page). +\# +\# HY DEFAULT resets the hyphenation style to .hy 14 (see +\# above) if that behaviour is desired after changes have been +\# made to LINES, MARGIN, or SPACE. +\# +\# HY LINES sets the number of allowable consecutive hyphenated lines. +\# +\# HY MARGIN sets the amount of space (ipPcm) allowed at the end +\# of a line in QUAD mode before hyphenation is tripped (e.g. if there's +\# only 6 points left, groff won't try to hyphenate the next word). +\# +\# HY SPACE sets the amount of extra interword space (ipPcm) that can +\# be added in JUSTIFY mode to prevent a line from being hyphenated. +\# +.MAC HY END +. ie '\\$1'' \{\ +. hy 14 +. if \\n[#LINES] .hlm \\n[#LINES] +. if \\n[#MARGIN] .hym \\n[#MARGIN]] +. if \\n[#SPACE] .hys \\n[#SPACE] +. nr #HYPHENATE 1 +. \} +. el \{\ +. if !'\\$1'LINES' \{\ +. nh +. nr #HYPHENATE 0 +. \} +. if !'\\$1'MARGIN' \{\ +. nh +. nr #HYPHENATE 0 +. \} +. if !'\\$1'SPACE' \{\ +. nh +. nr #HYPHENATE 0 +. \} +. if !'\\$1'DEFAULT' \{\ +. nh +. nr #HYPHENATE 0 +. \} +. if '\\$1'LINES' \{\ +. hlm \\$2 +. nr #HY_LINES \\$2 +. \} +. if '\\$1'MARGIN' \{\ +. hym \\$2 +. nr #HY_MARGIN \\$2 +. \} +. if '\\$1'SPACE' \{\ +. hys \\$2 +. nr #HY_SPACE \\$2 +. \} +. if '\\$1'DEFAULT' \{\ +. hlm -1 +. hym 0 +. hys 0 +. rr #HY_LINES +. rr #HY_SPACE +. rr #HY_MARGIN +. \} +. \} +.END +\# +\# HYPHENATION PARAMETERS +\# ---------------------- +\# *Arguments: +\# <# of lines> | | +\# *Function: +\# Allows user to specify .HY LINES, MARGIN, and SPACE with a single command. +\# +.MAC HY_SET END +. nr #HY_SET 1 +. hlm \\$1 +. hym \\$2 +. hys \\$3 +.END +\# +\# ===================================================================== +\# +\# +++VERTICAL SPACING+++ +\# +\# ADVANCE LEAD +\# ------------ +\# *Argument: +\# +\# *Function: +\# Creates or modifies register #ALD. Adds user supplied lead +\# below current baseline. +\# *Notes: +\# Requires a unit of measure. +\# +.MAC ALD END +. if '\\$0'ALD' \{\ +. nr #ALD (u;\\$1) +. sp \\n[#ALD]u +. \} +. if '\\$0'ADD_SPACE' \{\ +. vpt 0 +. nr #ALD \\$1 +. rs +. nop \& +. br +. sp |\\n[#T_MARGIN]u-1v+\\n[#ALD]u +. rr @TOP +. nr #SPACE_ADDED 1 +. vpt +. \} +. if '\\$0'SPACE' .sp \\$1 +. if '\\$0'SP' .sp \\$1 +.END +\# +\# REVERSE LEAD +\# ------------ +\# *Argument: +\# +\# *Function: +\# Creates or modifies register #RLD. Reverses user supplied +\# lead above current baseline. +\# *Notes: +\# Requires a unit of measure. +\# +.MAC RLD END +. br +. nr #RLD (u;\\$1) +. sp -\\n[#RLD]u +.END +\# +\# ALD/RLD STRINGS +\# --------------- +\# The strings \*[ALD.25]...\*[ALD12.75] and their corresponding +\# \*[RLD] forms have been left in for backward compatibility with +\# documents created using mom-1.1.3c or earlier. The preferred methods +\# of advancing and reversing on the page inline are \*[UP ] +\# and \*[DOWN ]. +\# +.ds DOWN \v'\\$1' +.ds UP \v'-\\$1' +\# +.ds ALD.25 \v'.25p' +.ds ALD.5 \v'.5p' +.ds ALD.75 \v'.75p' +.ds ALD1 \v'1p' +.ds ALD1.25 \v'1.25p' +.ds ALD1.5 \v'1.5p' +.ds ALD1.75 \v'1.75p' +.ds ALD2 \v'2p' +.ds ALD2.25 \v'2.25p' +.ds ALD2.5 \v'2.5p' +.ds ALD2.75 \v'2.75p' +.ds ALD3 \v'3p' +.ds ALD3.25 \v'3.25p' +.ds ALD3.5 \v'3.5p' +.ds ALD3.75 \v'3.75p' +.ds ALD4 \v'4p' +.ds ALD4.25 \v'4.25p' +.ds ALD4.5 \v'4.5p' +.ds ALD4.75 \v'4.75p' +.ds ALD5 \v'5p' +.ds ALD5.25 \v'5.25p' +.ds ALD5.5 \v'5.5p' +.ds ALD5.75 \v'5.75p' +.ds ALD6 \v'6p' +.ds ALD6.25 \v'6.25p' +.ds ALD6.5 \v'6.5p' +.ds ALD6.75 \v'6.75p' +.ds ALD7 \v'7p' +.ds ALD7.25 \v'7.25p' +.ds ALD7.5 \v'7.5p' +.ds ALD7.75 \v'7.75p' +.ds ALD8 \v'8p' +.ds ALD8.25 \v'8.25p' +.ds ALD8.5 \v'8.5p' +.ds ALD8.75 \v'8.75p' +.ds ALD9 \v'9p' +.ds ALD9.25 \v'9.25p' +.ds ALD9.5 \v'9.5p' +.ds ALD9.75 \v'9.75p' +.ds ALD10 \v'10p' +.ds ALD10.25 \v'10.25p' +.ds ALD10.5 \v'10.5p' +.ds ALD10.75 \v'10.75p' +.ds ALD11 \v'11p' +.ds ALD11.25 \v'11.25p' +.ds ALD11.5 \v'11.5p' +.ds ALD11.75 \v'11.75p' +.ds ALD12 \v'12p' +.ds ALD12.25 \v'12.5p' +.ds ALD12.5 \v'12.5p' +.ds ALD12.75 \v'12.75p' +\# +.ds RLD.25 \v'-.25p' +.ds RLD.5 \v'-.5p' +.ds RLD.75 \v'-.75p' +.ds RLD1 \v'-1p' +.ds RLD1.25 \v'-1.25p' +.ds RLD1.5 \v'-1.5p' +.ds RLD1.75 \v'-1.75p' +.ds RLD2 \v'-2p' +.ds RLD2.25 \v'-2.25p' +.ds RLD2.5 \v'-2.5p' +.ds RLD2.75 \v'-2.75p' +.ds RLD3 \v'-3p' +.ds RLD3.25 \v'-3.25p' +.ds RLD3.5 \v'-3.5p' +.ds RLD3.75 \v'-3.75p' +.ds RLD4 \v'-4p' +.ds RLD4.25 \v'-4.25p' +.ds RLD4.5 \v'-4.5p' +.ds RLD4.75 \v'-4.75p' +.ds RLD5 \v'-5p' +.ds RLD5.25 \v'-5.25p' +.ds RLD5.5 \v'-5.5p' +.ds RLD5.75 \v'-5.75p' +.ds RLD6 \v'-6p' +.ds RLD6.25 \v'-6.25p' +.ds RLD6.5 \v'-6.5p' +.ds RLD6.75 \v'-6.75p' +.ds RLD7 \v'-7p' +.ds RLD7.25 \v'-7.25p' +.ds RLD7.5 \v'-7.5p' +.ds RLD7.75 \v'-7.75p' +.ds RLD8 \v'-8p' +.ds RLD8.25 \v'-8.25p' +.ds RLD8.5 \v'-8.5p' +.ds RLD8.75 \v'-8.75p' +.ds RLD9 \v'-9p' +.ds RLD9.25 \v'-9.25p' +.ds RLD9.5 \v'-9.5p' +.ds RLD9.75 \v'-9.75p' +.ds RLD10 \v'-10p' +.ds RLD10.25 \v'-10.25p' +.ds RLD10.5 \v'-10.5p' +.ds RLD10.75 \v'-10.75p' +.ds RLD11 \v'-11p' +.ds RLD11.25 \v'-11.25p' +.ds RLD11.5 \v'-11.5p' +.ds RLD11.75 \v'-11.75p' +.ds RLD12 \v'-12p' +.ds RLD12.25 \v'-12.5p' +.ds RLD12.5 \v'-12.5p' +.ds RLD12.75 \v'-12.75p' +\# +\# ===================================================================== +\# +\# +++REFINEMENTS+++ +\# +\# AUTOMATIC LIGATURES +\# ------------------- +\# *Arguments: +\# | +\# *Function: +\# Turns automatic ligature generation on or off. +\# *Notes: +\# Ligatures may be supplied manually with \[fi], \[fl], etc. +\# +.MAC LIGATURES END +. ie '\\$1'' \{\ +. lg +. nr #LIGATURES 1 +. \} +. el \{\ +. lg 0 +. nr #LIGATURES 0 +. \} +.END +\# +\# SMARTQUOTES +\# ----------- +\# *Arguments: +\# [ ,, ] | [ << ] | [ >> ] | +\# or +\# [ DA | DE | EN | ES | FR | IT | NL | NO | PT | SV ] | +\# *Function: +\# Turns smartquotes on (optionally with a quoting style from the +\# argument list, or off). +\# If no quoting style is given, then EN (English) is used by default. +\# If no quoting style is given and smart quotes have been turned off +\# previously, the old quoting style will be restored. +\# *Notes: +\# The " character is read outside the macro when mom is +\# processed. The strings for open/close ($QUOTE) are then +\# defined in the macro. +\# +.char " \\*[$QUOTE\\n[#OPEN_CLOSE]]\R'#OPEN_CLOSE (1-\\n[#OPEN_CLOSE])' +.nr #SQ_ON 0 +\# +.MAC SMARTQUOTES END +.\" First " will be translated to $QUOTE0 +. nr #OPEN_CLOSE 0 +. if '\\$1'' \{\ +. if !'\\*[$RESTORE_SQ]'' \{\ +. SMARTQUOTES \\*[$RESTORE_SQ] +. return +. \} +.\" Default smart quotes (English) +. ds $QUOTE0 \[lq] +. ds $QUOTE1 \[rq] +. ds $RESTORE_SQ EN +. nr #SQ_ON 1 +. return +. \} +. if '\\$1',,' \{\ +. ds $QUOTE0 \[Bq] +. ds $QUOTE1 \[lq] +. ds $RESTORE_SQ \\$1 +. nr #SQ_ON 1 +. return +. \} +. if '\\$1'<<' \{\ +. ds $QUOTE0 \[Fo] +. ds $QUOTE1 \[Fc] +. ds $RESTORE_SQ \\$1 +. nr #SQ_ON 1 +. return +. \} +. if '\\$1'>>' \{\ +. ds $QUOTE0 \[Fc] +. ds $QUOTE1 \[Fo] +. ds $RESTORE_SQ \\$1 +. nr #SQ_ON 1 +. return +. \} +. if '\\$1'DA' \{\ +. ds $QUOTE0 \[Fc] +. ds $QUOTE1 \[Fo] +. ds $RESTORE_SQ \\$1 +. nr #SQ_ON 1 +. return +. \} +. if '\\$1'DE' \{\ +. ds $QUOTE0 \[Bq] +. ds $QUOTE1 \[lq] +. ds $RESTORE_SQ \\$1 +. nr #SQ_ON 1 +. return +. \} +. if '\\$1'EN' \{\ +. ds $QUOTE0 \[lq] +. ds $QUOTE1 \[rq] +. ds $RESTORE_SQ \\$1 +. nr #SQ_ON 1 +. return +. \} +. if '\\$1'ES' \{\ +. ds $QUOTE0 \[lq] +. ds $QUOTE1 \[rq] +. ds $RESTORE_SQ \\$1 +. nr #SQ_ON 1 +. return +. \} +. if '\\$1'FR' \{\ +. ds $QUOTE0 \[Fo]\| +. ds $QUOTE1 \|\[Fc] +. ds $RESTORE_SQ \\$1 +. nr #SQ_ON 1 +. return +. \} +. if '\\$1'IT' \{\ +. ds $QUOTE0 \[Fo]\| +. ds $QUOTE1 \|\[Fc] +. ds $RESTORE_SQ \\$1 +. nr #SQ_ON 1 +. return +. \} +. if '\\$1'NL' \{\ +. ds $QUOTE0 \[rq] +. ds $QUOTE1 \[rq] +. ds $RESTORE_SQ \\$1 +. nr #SQ_ON 1 +. return +. \} +. if '\\$1'NO' \{\ +. ds $QUOTE0 \[Fo] +. ds $QUOTE1 \[Fc] +. ds $RESTORE_SQ \\$1 +. nr #SQ_ON 1 +. return +. \} +. if '\\$1'PT' \{\ +. ds $QUOTE0 \[Fo] +. ds $QUOTE1 \[Fc] +. ds $RESTORE_SQ \\$1 +. nr #SQ_ON 1 +. return +. \} +. if '\\$1'SV' \{\ +. ds $QUOTE0 \[Fc] +. ds $QUOTE1 \[Fc] +. ds $RESTORE_SQ \\$1 +. nr #SQ_ON 1 +. return +. \} +.\" None of the above -> turn smartquotes off +. ds $QUOTE0 \[dq] +. ds $QUOTE1 \[dq] +. nr #SQ_ON 0 +.END +\# +.ds $QUOTE0 \[lq] +.ds $QUOTE1 \[rq] +\# +\# Strings for foot and inch marks +\# +.ds FOOT \[fm] +.ds INCH \[fm]\[fm] +\# +\# ===================================================================== +\# +\# +++LINE BREAKS+++ +\# +\# NO-SPACE BREAK +\# -------------- +\# *Argument: +\# +\# *Function: +\# Breaks a line without advancing. +\# *Notes: +\# EL is the mnemonic used on older, dedicated typesetting machines +\# to indicate "process the line, without advancing the galley +\# medium." It stands for End Line. +\# +\# The \c inline must be appended to the end of input lines when in +\# nofill mode; in fill modes, the \c inline must not be used. +\# +.MAC EL END +. TRAP OFF +. if \\n[#PSEUDO_FILL]=1 \& +. br +. sp -1v +. TRAP +.END +\# +\# An inline escape to accomplish the same thing. +\# Preferable, since it works with filled and non-filled copy and +\# doesn't require the user to remember whether to use (or not use) +\# \c. +\# +.ds B \h'|0'\R'#NO_ADVANCE 1'\c +\# +\# ===================================================================== +\# +\# +++FILLING/QUADDING/JUSTIFYING+++ +\# +\# JUSTIFY +\# ------- +\# *Argument: +\# +\# *Function: +\# Turns fill on and sets .ad to b. +\# *Notes: +\# Justifies text left and right. +\# +.MAC JUSTIFY END +\#. if r pdfbx-top 'sp -1 +. if \\n[#TAB_ACTIVE]=0 \{\ +. nr #QUAD 1 +. ds $RESTORE_QUAD_VALUE \\*[$QUAD_VALUE] +. \} +' ce 0 +. QUAD J +. if \\n[#PRINT_STYLE]=1 .QUAD L +. nr #PSEUDO_FILL 0 +.END +\# +\# QUAD +\# ---- +\# *Arguments: +\# L | LEFT | R | RIGHT | C | CENTER/CENTRE +\# *Function: +\# Turns fill on and sets .ad to l, r, or c. +\# *Notes: +\# Terminology is a problem here. Some people call quad left +\# left justified, flush left, or flush left/rag right (and the +\# reverse for quad right). Quad center is sometimes called rag +\# both. For our purposes, all "quad" modes mean that groff fill +\# mode is enabled. +\# +.MAC QUAD END +. if r pdfbx-top \{\ +' sp -1 +. rr pdfbx-top +. \} +.\" The QUAD in PP adds an unwanted linespace after a HEADING at the +.\" top of a pdf box because of this .br, so HEADING assigns the +.\" tmp register "bx-top\n[stack]" to inhibit it. +. ie !r pdfbx-top\\n[stack] .br +. el .rr pdfbx-top\\n[stack] +. if \\n[#COVERTEXT_PP] \ +. ds $RESTORE_DOC_QUAD \\*[$QUAD_VALUE] +. ds $QUAD_VALUE \\$1 +. substring $QUAD_VALUE 0 0 +. if \\n[#TAB_ACTIVE]=0 \{\ +. nr #QUAD 1 +. ds $RESTORE_QUAD_VALUE \\*[$QUAD_VALUE] +. \} +' ce 0 +' fi +. if '\\*[$QUAD_VALUE]'L' \{\ +. nr #JUSTIFY 0 +. ad l +. \} +. if '\\*[$QUAD_VALUE]'R' \{\ +. nr #JUSTIFY 0 +. ad r +. \} +. if '\\*[$QUAD_VALUE]'C' \{\ +. nr #JUSTIFY 0 +. ad c +. \} +. if '\\*[$QUAD_VALUE]'J' \{\ +. nr #JUSTIFY 1 +. ad b +. \} +. nr #PSEUDO_FILL 0 +.END +\# +\# LEFT, RIGHT, AND CENTER +\# ----------------------- +\# The purpose of these macros is to allow the user to enter lines +\# of text that will be quadded LRC without having to stick .BR +\# or .br between lines. For the sake of consistency, all three +\# appear to behave similarly (from the point of view of the user), +\# although the underlying primitives don't. For this reason, LEFT, +\# RIGHT, and CENTER must be followed by .QUAD [L R C J] or .JUSTIFY +\# to restore text to fill mode. +\# +\# LEFT +\# ---- +\# *Argument: +\# +\# *Function: +\# Turns fill mode off. Allows user to quad lines left without +\# requiring the .BR or .br macro. +\# *Notes: +\# LEFT simply turns fill off. Lines that exceed the current LL +\# will not be broken. Note that this behaviour differs from the +\# RIGHT and CENTER macros. +\# +.MAC LEFT END +. if \\n[#TAB_ACTIVE]=0 \{\ +. rr #QUAD +. ds $RESTORE_QUAD_VALUE LEFT +. \} +. ce 0 +. nf +. nr #PSEUDO_FILL 1 +.\" Fix for a little conflict with DOCTYPE LETTER +. if '\\n[.z]'LETTERHEAD1' .rr #DATE_FIRST +.END +\# +\# RIGHT +\# ----- +\# *Argument: +\# +\# *Function: +\# Turns fill on. Allows user to quad lines right without +\# requiring the .BR or .br macro. +\# *Notes: +\# Lines that exceed the current LL will be broken, with the excess +\# text quadded right. +\# +.MAC RIGHT END +. if \\n[#TAB_ACTIVE]=0 \{\ +. rr #QUAD +. ds $RESTORE_QUAD_VALUE RIGHT +. \} +. nf +. rj 100000 +. nr #PSEUDO_FILL 1 +.END +\# +\# CENTER +\# ------ +\# *Argument: +\# +\# *Function: +\# Turns fill off. Allows user to center lines without +\# requiring the .BR or .br macro. +\# *Notes: +\# Lines that exceed the current LL will be broken, with the excess +\# text centered. +\# +.MAC CENTER END +. if \\n[#TAB_ACTIVE]=0 \{\ +. rr #QUAD +. ds $RESTORE_QUAD_VALUE CENTER +. \} +. nf +. ce 100000 +. nr #PSEUDO_FILL 1 +.END +\# +\# CENTER BLOCKS OF TYPE +\# --------------------- +\# *Arguments: +\# | +\# *Function: +\# Allows users to centre blocks of type on the page without +\# altering their quad. +\# +.MAC CENTER_BLOCK END +. br +. ie !\\n[.$] .di CENTER*BLOCK +. el \{\ +. di +. in \\n[.l]u-\\n[dl]u/2u +. if \\n[.u] .nr #FILLED 1 +. nf +. CENTER*BLOCK +. if \\n[#FILLED] .fi +. rr #FILLED +. in +. \} +.END +\# +.ALIAS CENTRE_BLOCK CENTER_BLOCK +\# +\# ===================================================================== +\# +\# +++TABS+++ +\# +\# There are two different kinds of tabs: typesetting tabs and +\# string tabs. +\# +\# Typesetting tabs are set with TAB_SET, which requires a tab number, +\# an indent (offset) from the left margin and a length (optionally +\# with a quad direction and an instruction to fill lines). After tabs +\# are set with TAB_SET, they are called with .TAB n, where "n" +\# corresponds to the number passed to TAB_SET as a valid tab number. +\# +\# String tabs allow the user to mark off tab positions inline. Tab +\# indents and lengths are calculated from the beginning and end +\# positions of the marks. Up to 19 string tabs may be created, +\# numbered 1-19. Once created, they are called with .TAB n, +\# just like typesetting tabs. +\# +\# Setting up string tabs is a two-step procedure. First, the user +\# enters an input line in which s/he wants to mark off string tabs. +\# The beginning of a tab is marked with \*[STn], where "n" is +\# the desired number of the tab. The end of the tab is marked +\# with \*[STnX]. All ST's must have a matching STX. String tabs +\# may be nested. +\# +\# Next, the user invokes .ST n for every string tab defined, and +\# optionally passes quad information to it. That done, string tabs +\# can be called just like typesetting tabs. +\# +\# Strings for string tab inlines +\# ------------------------------ +\# Initialize string tab markers numbered 1 to 19. +\# +.nr #LOOP 0 1 +.while \n+[#LOOP]<20 \{\ +. ds ST\n[#LOOP] \Ek[#ST\n[#LOOP]_OFFSET] +.\} +\# +.nr #LOOP 0 1 +.while \n+[#LOOP]<20 \{\ +. ds ST\n[#LOOP]X \Ek[#ST\n[#LOOP]_MARK] +.\} +.rr #LOOP +\# +\# These are reserved ST numbers for internal use +.ds ST100 \Ek[#ST100_OFFSET] +.ds ST100X \Ek[#ST100_MARK] +.ds ST101 \Ek[#ST101_OFFSET] +.ds ST101X \Ek[#ST101_MARK] +.ds ST102 \Ek[#ST102_OFFSET] +.ds ST102X \Ek[#ST102_MARK] +.ds ST103 \Ek[#ST103_OFFSET] +.ds ST103X \Ek[#ST103_MARK] +\# +\# QUAD AND SET STRING TABS +\# ------------------------ +\# *Arguments: +\# L | R | C | J [QUAD] +\# *Function: +\# Creates strings $ST<#>_QUAD_DIR and $ST<#>_FILL, then sets up a +\# tab based on the collected information. +\# *Notes: +\# Like TAB_SET, ST invoked without a quad direction will default to LEFT. +\# If lines should be filled and quadded, use the optional argument QUAD. +\# N.B. -- indents *must* be turned off before setting string tabs +\# inside .PAD +\# +.MAC ST END +. ds $ST\\$1_QUAD_DIR \\$2 +. if \\n[#NUM_ARGS]=3 .ds $ST\\$1_FILL QUAD +. nr #ST\\$1_LENGTH \\n[#ST\\$1_MARK]-\\n[#ST\\$1_OFFSET] +. ie \\n[#IN_TAB] \ +. TAB_SET \\$1 \\n[#ST\\$1_OFFSET]u+\\n[#ST_OFFSET]u \ + \\n[#ST\\$1_LENGTH]u \\*[$ST\\$1_QUAD_DIR] \\*[$ST\\$1_FILL] +. el \ +. TAB_SET \\$1 \\n[#ST\\$1_OFFSET]u \\n[#ST\\$1_LENGTH]u \ + \\*[$ST\\$1_QUAD_DIR] \\*[$ST\\$1_FILL] +.END +\# +\# TAB SET +\# ------- +\# *Arguments: +\# ident(ipPcm) length(ipPcm) [L | R | C | J [QUAD]] +\# *Function: +\# Creates macros TABn and TAB n, where "n" is any arbitrary number. +\# TABn is a typesetting tab (i.e. a tab defined as an indent +\# from the page left offset plus a line length.) +\# *Notes: +\# n = arbitrary digit to identify the tab +\# indent = indent from left margin; unit of measure required +\# length = length of tab (unit of measure required; can be +\# \w''u--if more than one word in string, surround +\# with double quotes "\w''" +\# LRCJ = quad for tab (left, right, center, justified) +\# If option QUAD afterwards is not given, quad is line for line +\# (no fill mode), meaning that there's no need for .BR or .br +\# between lines. +\# QUAD = fill tab (so it behaves as if .QUAD LRC or .JUSTIFY +\# had been given). +\# +\# N.B. -- indents *must* be turned off before setting tabs +\# +\# Tabs are not columnar in behaviour. .TN and \*[TB+] permit +\# bottom-line to bottom-line tab movement. +\# +\# When resetting tabs, .TQ must be invoked before .TAB_SET. +\# +\# Indents are turned off automatically whenever a new tab is called +\# with TAB . +\# +\# Generally, it's a good idea to make sure all indents are off +\# before setting tabs. +\# +.MAC TAB_SET END +. br +. nr #TAB_NUMBER \\$1 +. ds $CURRENT_TAB \\n[#TAB_NUMBER] +. nr #TAB_OFFSET (\\$2) +. nr #TAB_LENGTH (\\$3) +. MAC TAB\\n[#TAB_NUMBER] +. if !\\\\n[#TB+]=1 .br +. if \\\\n[#TB+]=1 \{\ +. EL +. vpt 0 +. rr #TB+ +. \} +. in 0 +. nr #TAB_ACTIVE 1 +. nr #CURRENT_TAB \\n[#TAB_NUMBER] +. ds $CURRENT_TAB \\*[$CURRENT_TAB] +. nr #TAB_OFFSET\\*[$CURRENT_TAB] \\n[#TAB_OFFSET] +. nr #ST_OFFSET \\n[#TAB_OFFSET] +. ie !'\\\\n[.z]'' \ +\!. po \\\\\\\\n[#L_MARGIN]u+\\\\n[#TAB_OFFSET\\\\*[$CURRENT_TAB]]u +. el \ +. po \\\\n[#L_MARGIN]u+\\\\n[#TAB_OFFSET\\\\*[$CURRENT_TAB]]u +. ll \\n[#TAB_LENGTH]u +. ta \En[.l]u +. ie '\\$5'QUAD' \{\ +. if '\\$4'L' .QUAD L +. if '\\$4'R' .QUAD R +. if '\\$4'C' .QUAD C +. if '\\$4'J' .JUSTIFY +. \} +. el \{\ +. if '\\$4'' .LEFT +. if '\\$4'L' .LEFT +. if '\\$4'R' .RIGHT +. if '\\$4'C' .CENTER +. if '\\$4'J' .JUSTIFY +. \} +. if \\\\n[#TN]=1 \{\ +. TRAP +. rr #TN +. \} +.. +. rr #TAB_ACTIVE +.END +\# +\# TAB +\# --- +\# *Arguments: +\# +\# *Function: +\# Moves to tab number passed as an argument. +\# +.MAC TAB END +. ds $TAB_NUMBER \\$1 +. TAB\\*[$TAB_NUMBER] +. nr #IN_TAB 1 +.END +\# +\# TAB NEXT +\# -------- +\# *Argument: +\# +\# *Function: +\# Automatically moves to TAB on the same line as the last +\# line of the previous tab. +\# *Notes: +\# The \c inline must be appended to the end of input lines when in +\# nofill mode; in fill modes, the \c inline must not be used. +\# +.MAC TN END +. nr #TN 1 +. vpt 0 +. sp -1v +. nr #NEXT_TAB \\n[#CURRENT_TAB]+1 +. TAB\\n[#NEXT_TAB] +. vpt +.END +\# +\# An inline escape to accomplish the same thing. Preferable, since +\# it works with filled and non-filled copy and doesn't require the +\# user to remember to use (or not use) the \c. +\# +.ds TB+ \ +"\c\R'#TB+ 1'\R'#TN 1'\R'#NEXT_TAB \\n[#CURRENT_TAB]+1'\\*[TAB\\n[#NEXT_TAB]]\c +\# +\# TAB QUIT +\# -------- +\# *Argument: +\# +\# *Function: +\# Sets #TAB_ACTIVE to "0" (off). +\# Resets left margin to value in effect prior to tabs. +\# Resets line length to value in effect prior to tabs. +\# Checks #QUAD to see if we were in flush or quad mode +\# prior to tabs (0=off, 1=on). +\# Resets QUAD [ L|R|C ], LEFT, RIGHT, CENTER, or JUSTIFY +\# in effect prior to tabs. +\# *Notes: +\# TQ must precede setting new tabs to get the tabs' indents +\# measured from page left. Otherwise, the tabs' indents are +\# measured from the left margin of the currently active tab. +\# +.MAC TQ END +. br +. rr #TAB_ACTIVE +. rr #IN_TAB +. nr #LOOP 0 1 +. while \\n+[#LOOP]<20 \{\ +. rm $ST\\n[#LOOP]_FILL +. \} +. rr #LOOP +. ie !'\\n[.z]'' \{\ +\!. po \\n[#L_MARGIN]u +\!. ll \\n[#L_LENGTH]u +. \} +. el \{\ +. po \\n[#L_MARGIN]u +. ll \\n[#L_LENGTH]u +. \} +. ll \\n[#L_LENGTH]u +. ta \\n[.l]u +. ie \\n[#QUAD] \{\ +. ie '\\*[$RESTORE_QUAD_VALUE]'J' .JUSTIFY +. el .QUAD \\*[$RESTORE_QUAD_VALUE] +. \} +. el \{\ +. if '\\*[$RESTORE_QUAD_VALUE]'LEFT' .LEFT +. if '\\*[$RESTORE_QUAD_VALUE]'RIGHT' .RIGHT +. if '\\*[$RESTORE_QUAD_VALUE]'CENTER' .CENTER +. \} +.END +\# +\# ==================================================================== +\# +\# COLOR HANDLING +\# ============== +\# +\# COLOR +\# ----- +\# *Arguments: +\# +\# *Function: +\# Allows the inline escape for setting color to be called +\# as a macro. +\# +.MAC COLOR END +. ie \\n[.u]=1 \{\ +\c +\\*[\\$1]\c +. \} +. el \\*[\\$1] +.END +\# +\# NEWCOLOR +\# -------- +\# *Arguments: +\# [] +\# *Function: +\# Based on .defcolor, allows users to name and define colors using +\# one of the four color schemes rgb, cmy, cmyk and grey. The new +\# color is then defined as a string so that it can be called inline +\# with \*[COLORNAME] or with .COLOR. +\# *Notes: +\# With only two args, the default color scheme is rgb. +\# +\# It is highly recommended that users define new colors as +\# all-cap strings, to differentiate them from x colors, which must +\# be in lower case. +\# +.MAC NEWCOLOR END +. if \\n[#NUM_ARGS]=2 .defcolor \\$1 rgb \\$2 +. if \\n[#NUM_ARGS]=3 \{\ +. if '\\$2'RGB' .ds $COLOR_SCHEME rgb +. if '\\$2'CYM' .ds $COLOR_SCHEME cym +. if '\\$2'CMYK' .ds $COLOR_SCHEME cmyk +. if '\\$2'GRAY' .ds $COLOR_SCHEME gray +. if '\\$2'GREY' .ds $COLOR_SCHEME gray +. defcolor \\$1 \\*[$COLOR_SCHEME] \\$3 +. \} +. ds \\$1 \\m[\\$1] +.END +\# +\# XCOLOR +\# ------ +\# *Arguments: +\# [] +\# *Function: +\# Defines a string of x color name (i.e. a predefined x +\# color). If is given, creates a string of +\# that references the x color name of the first argument. +\# *Notes: +\# The color name must be a valid color name from rgb.txt, and +\# must be given entirely in lower case, all one word. +\# +.MAC XCOLOR END +. ds \\$1 \m[\\$1] +. if \\n[#NUM_ARGS]=2 \{\ +. ds \\$2 \m[\\$1] +. ds $\\$2_FILL \\$1 +. ds COLAL_\\$2 \\$1 +. \} +.END +\# +\# Pre-define xcolors black and white +\# +.ds black \m[black] +.ds BLACK \m[black] +.ds white \m[white] +.ds WHITE \m[white] +.ds default black +\# +\# ===================================================================== +\# +\# +++MISCELLANEOUS USEFUL MACROS AND STRINGS+++ +\# +.nr _w 500 +.nr _d 1250 +\# +\# These string are used for creating aliases within loops that set +\# style for doc-cover, cover, and docheader items. They're defined +\# here because underscoring needs them. +\# +.ds TITLE_TYPE_1 ATTRIBUTE +.ds TITLE_TYPE_2 AUTHOR +.ds TITLE_TYPE_3 CHAPTER +.ds TITLE_TYPE_4 CHAPTER_TITLE +.ds TITLE_TYPE_5 COVERTITLE +.ds TITLE_TYPE_6 DOCTITLE +.ds TITLE_TYPE_7 DOCTYPE +.ds TITLE_TYPE_8 DOC_COVERTITLE +.ds TITLE_TYPE_9 SUBTITLE +.ds TITLE_TYPE_10 TITLE +.ds TITLE_TYPE_11 MISC +.ds TITLE_TYPE_12 COPYRIGHT +.ds TITLE_TYPE_13 DOC_COVER_TITLE +.ds TITLE_TYPE_14 COVER_TITLE +\# +\# UNDERLINE +\# --------- +\# *Arguments: +\# | +\# *Function: +\# Simulates typewriter-style underlining of italic passages. +\# *Notes: +\# Defaults for rule weight and distance from baseline are below. +\# UNDERLINE_SPECS lets user change them +\# +.MAC UNDERLINE_SPECS END +. ie \B'\\$1' .nr _w (u;\\$1) +. el \{\ +. ie '\\$1'DEFAULT' .nr _w 500 +. el \{\ +. nr _w 500 +. tm1 "[mom]: The first argument to \\$0 must be a numeric +. tm1 " argument with a unit of measure appended, or DEFAULT. +. tm1 " Setting underline weight to DEFAULT. +. \} +. \} +. shift +. ie \B'\\$1' .nr _d (u;\\$1) +. el \{\ +. ie '\\$1'DEFAULT' .nr _d 1250 +. el \{\ +. nr _d 1250 +. tm1 "[mom]: The second argument to \\$0 must be a numeric +. tm1 " argument with a unit of measure appended, or DEFAULT. +. tm1 " Setting underline distance from baseline to DEFAULT. +. \} +. \} +.END +\# +.MAC UNDERLINE END +. ds $SAVED_SS_VAR \\*[$SS_VAR] +. ie '\\$1'' \{\ +. nr #UNDERLINE_ON 1 +. ss \\n[.ss] 0 +. ie !n .nop \X'ps: exec \\n[_w] \\n[_d] decorline'\c +. el .cu 1000 +. \} +. el \{\ +. nr #UNDERLINE_ON 0 +. if !'\\*[$SAVED_SS_VAR]'' .SS \\*[$SAVED_SS_VAR] +. ie !n .nop \X'ps: exec decornone'\c +. el .cu 0 +. \} +.END +\# +\# UL/ULX +\# ------ +\# *Arguments: +\# +\# *Function: +\# Simulates typewriter-style underlining of italic passages. +\# *Notes: +\# Intended to be called with inline escapes \*[UL] (underline +\# on) and \*[ULX] (underline off). +\# +.MAC UL END +\c +. ds $SAVED_SS_VAR \\*[$SS_VAR] +. ss \\n[.ss] 0 +. ie !'\\n[.z]'' \{\ +\c +. ie !n \{\ +. if !\\n[.k]=0 \?\h'-\w'\\n[.ss]'u'\? +\?\R'#UNDERLINE_ON 1'\X'ps: exec \\n[_w] \\n[_d] decorline'\?\c +. \} +. el \{\ +\?\R'#UNDERLINE_ON 1'\?\c +. cu 1000 +. \} +. \} +. el \{\ +. ie !n \{\ +. nr #UNDERLINE_ON 1 +. nop \X'ps: exec \\n[_w] \\n[_d] decorline'\c +. \} +. el \{\ +\R'#UNDERLINE_ON 1'\c +. cu 1000 +. \} +. \} +.END +\# +.MAC ULX END +\c +. SS \\*[$SAVED_SS_VAR] +. rm $SAVED_SS_VAR +. ie !'\\n[.z]'' \{\ +\c +. ie !n \{\ +\?\R'#UNDERLINE_ON 0'\X'ps: exec decornone'\?\c +. \} +. el \{\ +\?\R'#UNDERLINE_ON 0'\?\c +. cu 0 +. \} +. \} +. el \{\ +. ie !n \{\ +. nr #UNDERLINE_ON 0 +. nop \X'ps: exec decornone'\c +. \} +. el \{\ +. nr #UNDERLINE_ON 0 +. cu 0 +. \} +. \} +.END +\# +\# UNDERSCORE +\# ---------- +\# *Arguments: +\# [] "text" +\# *Function: +\# Places an underscore 2 points under the string if no lead given, +\# otherwise places underscore under string by user specified amount. +\# *Notes: +\# When using this macro, the string to be underscored must begin +\# with double-quotes ("), regardless of whether it's the sole +\# argument or the second. +\# E.g.: +\# .UNDERSCORE "Text to be underscored +\# or +\# .UNDERSCORE 2p "Text to be underscored +\# +\# UNDERSCORE does not work across line breaks. Each line of text +\# must be entered separately. If the UNDERSCORE begins in the +\# middle of a line and crosses over a break, the portion before +\# the break and the portion afterwards must be entered +\# separately. +\# +.MAC UNDERSCORE END +. nr #SAVED_UNDERSCORE_WEIGHT \\n[#UNDERSCORE_WEIGHT] +. nr #SAVED_UNDERSCORE_WEIGHT_ADJ \\n[#UNDERSCORE_WEIGHT_ADJ] +. ds $SAVED_UNDERSCORE_GAP \\*[$UNDERSCORE_GAP] +. if \\n[#NUM_ARGS]>=2 \{\ +. if \B'\\$1' \{\ +. ds $UNDERSCORE_GAP \\$1 +. shift +. \} +. if '\\$1'PREFIX' \{\ +. ds $PREFIX \\$2 +. shift 2 +. \} +. if '\\$1'SUFFIX' \{\ +. ds $SUFFIX \\$2 +. shift 2 +. \} +. \} +. if !'\\*[$TITLE_TYPE]'' \{\ +. nr #UNDERSCORE_WEIGHT \\n[#\\*[$TITLE_TYPE]_UNDERLINE_WEIGHT] +. nr #UNDERSCORE_WEIGHT_ADJ \\n[#\\*[$TITLE_TYPE]_UNDERLINE_WEIGHT_ADJ] +. ds $UNDERSCORE_GAP \\*[$\\*[$TITLE_TYPE]_UNDERLINE_GAP] +. \} +. nr #TEXT_WIDTH \w'\\$1' +. ie \\n[.u]=1 \{\ +\\*[$PREFIX]\Z'\\$1'\ +\Z'\D't \\n[#UNDERSCORE_WEIGHT]''\ +\v'\\*[$UNDERSCORE_GAP]+\\n[#UNDERSCORE_WEIGHT_ADJ]u'\ +\D'l \\n[#TEXT_WIDTH]u 0'\ +\Z'\D't \\n[#RULE_WEIGHT]''\ +\v'-(\\*[$UNDERSCORE_GAP]+\\n[#UNDERSCORE_WEIGHT_ADJ]u)'\\*[$SUFFIX]\c +. nop +. \} +. el \{\ +\\*[$PREFIX]\Z'\\$1'\ +\Z'\D't \\n[#UNDERSCORE_WEIGHT]''\ +\v'\\*[$UNDERSCORE_GAP]+\\n[#UNDERSCORE_WEIGHT_ADJ]u'\ +\D'l \\n[#TEXT_WIDTH]u 0'\ +\Z'\D't \\n[#RULE_WEIGHT]''\ +\v'-(\\*[$UNDERSCORE_GAP]+\\n[#UNDERSCORE_WEIGHT_ADJ]u)'\\*[$SUFFIX] +. \} +. nr #UNDERSCORE_WEIGHT \\n[#SAVED_UNDERSCORE_WEIGHT] +. nr #UNDERSCORE_WEIGHT_ADJ \\n[#SAVED_UNDERSCORE_WEIGHT_ADJ] +. ds $UNDERSCORE_GAP \\*[$SAVED_UNDERSCORE_GAP] +. rr #SAVED_UNDERSCORE_WEIGHT +. rr #SAVED_UNDERSCORE_WEIGHT_ADJ +. rm $SAVED_UNDERSCORE_GAP +. rm $PREFIX +. rm $SUFFIX +. rm $TITLE_TYPE +.END +\# +\# DOUBLE UNDERSCORE +\# ----------------- +\# *Arguments: +\# [points below baseline] [points distance between rules] "text" +\# *Function: +\# Same as UNDERSCORE, except it produces a double underscore. The default +\# distance between the rules is 2 points. +\# *Notes: +\# The same double-quote requirement as UNDERSCORE. +\# +.MAC UNDERSCORE2 END +. nr #SAVED_UNDERSCORE_WEIGHT \\n[#UNDERSCORE_WEIGHT] +. nr #SAVED_UNDERSCORE_WEIGHT_ADJ \\n[#UNDERSCORE_WEIGHT_ADJ] +. ds $SAVED_UNDERSCORE_GAP \\*[$UNDERSCORE_GAP] +. ds $SAVED_RULE_GAP \\*[$RULE_GAP] +. if \\n[#NUM_ARGS]>=2 \{\ +. if \B'\\$1' \{\ +. ds $UNDERSCORE_GAP \\$1 +. shift +. \} +. if \B'\\$1' \{\ +. ds $RULE_GAP \\$1 +. shift +. \} +. if '\\$1'PREFIX' \{\ +. ds $PREFIX \\$2 +. shift 2 +. \} +. if '\\$1'SUFFIX' \{\ +. ds $SUFFIX \\$2 +. shift 2 +. \} +. if \\n[#NUM_ARGS]=3 \{\ +. ds $UNDERSCORE_GAP \\$1 +. ds $RULE_GAP \\$2 +. shift 2 +. \} +. if !'\\*[$TITLE_TYPE]'' \{\ +. nr #UNDERSCORE_WEIGHT \\n[#\\*[$TITLE_TYPE]_UNDERLINE_WEIGHT] +. nr #UNDERSCORE_WEIGHT_ADJ \\n[#\\*[$TITLE_TYPE]_UNDERLINE_WEIGHT_ADJ] +. ds $UNDERSCORE_GAP \\*[$\\*[$TITLE_TYPE]_UNDERLINE_GAP] +. ds $RULE_GAP \\*[$\\*[$TITLE_TYPE]_RULE_GAP] +. \} +. nr #TEXT_WIDTH \w'\\$1' +. ie \\n[.u]=1 \{\ +\\*[$PREFIX]\Z'\\$1'\ +\Z'\D't \\n[#UNDERSCORE_WEIGHT]''\ +\v'\\*[$UNDERSCORE_GAP]+\\n[#UNDERSCORE_WEIGHT_ADJ]u'\ +\Z'\D'l \\n[#TEXT_WIDTH]u 0''\ +\v'\\*[$RULE_GAP]+\\n[#UNDERSCORE_WEIGHT]u'\ +\D'l \\n[#TEXT_WIDTH]u 0'\ +\Z'\D't \\n[#RULE_WEIGHT]''\ +\v'-(\\*[$UNDERSCORE_GAP]+\\*[$RULE_GAP])-(\\n[#UNDERSCORE_WEIGHT]u*2u)'\\*[$SUFFIX]\c +. \} +. el \{\ +\\*[$PREFIX]\Z'\\$1'\ +\Z'\D't \\n[#UNDERSCORE_WEIGHT]''\ +\v'\\*[$UNDERSCORE_GAP]+\\n[#UNDERSCORE_WEIGHT_ADJ]u'\ +\Z'\D'l \\n[#TEXT_WIDTH]u 0''\ +\v'\\*[$RULE_GAP]+\\n[#UNDERSCORE_WEIGHT]u'\ +\D'l \\n[#TEXT_WIDTH]u 0'\ +\Z'\D't \\n[#RULE_WEIGHT]''\ +\v'-(\\*[$UNDERSCORE_GAP]+\\*[$RULE_GAP])-(\\n[#UNDERSCORE_WEIGHT]u*2u)'\\*[$SUFFIX] +. \} +. nr #UNDERSCORE_WEIGHT \\n[#SAVED_UNDERSCORE_WEIGHT] +. nr #UNDERSCORE_WEIGHT_ADJ \\n[#SAVED_UNDERSCORE_WEIGHT_ADJ] +. ds $UNDERSCORE_GAP \\*[$SAVED_UNDERSCORE_GAP] +. rr #SAVED_UNDERSCORE_WEIGHT +. rr #SAVED_UNDERSCORE_WEIGHT_ADJ +. rm $PREFIX +. rm $SUFFIX +. rm $SAVED_UNDERSCORE_GAP +. rm $SAVED_RULE_GAP +. rm $TITLE_TYPE +.END +\# +\# Default underscoring underline and rule gaps +\# +.ds $BIB_STRING_RULE_GAP 2p +.ds $BIB_STRING_UNDERLINE_GAP 2p +.ds $EN_STRING_RULE_GAP 2p +.ds $EN_STRING_UNDERLINE_GAP 2p +.ds $EN_TITLE_UNDERLINE_GAP 2p +.ds $RULE_GAP 2p +.ds $TOC_HEADER_RULE_GAP 2p +.ds $TOC_HEADER_UNDERLINE_GAP 2p +.ds $UNDERSCORE_GAP 2p +\# +.nr #LOOP 0 1 +.while \n+[#LOOP]<=14 \{\ +. ds $\*[TITLE_TYPE_\n[#LOOP]]_RULE_GAP 2p +. ds $COVER_\*[TITLE_TYPE_\n[#LOOP]]_RULE_GAP 2p +. ds $DOC_COVER_\*[TITLE_TYPE_\n[#LOOP]]_RULE_GAP 2p +. ds $\*[TITLE_TYPE_\n[#LOOP]]_UNDERLINE_GAP 2p +. ds $COVER_\*[TITLE_TYPE_\n[#LOOP]]_UNDERLINE_GAP 2p +. ds $DOC_COVER_\*[TITLE_TYPE_\n[#LOOP]]_UNDERLINE_GAP 2p +.\} +\# +\# SUPERSCRIPT +\# ----------- +\# *Function: +\# Prints everything after inline invocation as superscript. +\# *Notes: +\# \*[SUP] and \*[SUPX] turn superscript on and off respectively. +\# If running type is pseudo-condensed/expanded, invoke the superscript +\# strings as \*[CONDSUP] or \*[EXTSUP] and turn off with \*[CONDSUPX] +\# and \*[EXTSUPX] respectively. +\# +\# Default raise/lower amount +.ds $SUP_RAISE \v'-.3m' +.ds $SUP_LOWER \v'.3m' +\# +\# SUPERSCRIPT RAISE +\# ----------------- +\# *Argument: +\# +\# *Function: +\# Defines strings $SUP_RAISE and $SUP_LOWER for use with \*[SUP], +\# \*[CONDSUP] and \*[EXTSUP]. +\# +.MAC SUPERSCRIPT_RAISE_AMOUNT END +. ds $SUP_RAISE_AMOUNT \\$1 +. ds $SUP_RAISE \v'-\\*[$SUP_RAISE_AMOUNT]' +. ds $SUP_LOWER \v'\\*[$SUP_RAISE_AMOUNT]' +.END +\# +.ds SUP \ +\R'#PT_SIZE_IN_UNITS \En[.ps]'\ +\R'#SUP_PT_SIZE \En[#PT_SIZE_IN_UNITS]u*6u/10u'\ +\s[\En[#PT_SIZE_IN_UNITS]u]\E*[$SUP_RAISE]\s[\En[#SUP_PT_SIZE]u] +\# +.ds SUPX \s[\En[#PT_SIZE_IN_UNITS]u]\E*[$SUP_LOWER] +\# +.ds CONDSUP \ +\R'#PT_SIZE_IN_UNITS \En[.ps]'\ +\R'#SUP_PT_SIZE \En[#PT_SIZE_IN_UNITS]u*6u/10u'\ +\s[\En[#PT_SIZE_IN_UNITS]u]\E*[$SUP_RAISE]\s[\En[#SUP_PT_SIZE]u]\E*[COND_FOR_SUP] +\# +.ds CONDSUPX \s[\En[#PT_SIZE_IN_UNITS]u]\E*[$SUP_LOWER]\E*[COND] +\# +.ds EXTSUP \ +\R'#PT_SIZE_IN_UNITS \En[.ps]'\ +\R'#SUP_PT_SIZE \En[#PT_SIZE_IN_UNITS]u*6u/10u'\ +\s[\En[#PT_SIZE_IN_UNITS]u]\E*[$SUP_RAISE]\s[\En[#SUP_PT_SIZE]u]\E*[EXT_FOR_SUP] +\# +.ds EXTSUPX \s[\En[#PT_SIZE_IN_UNITS]u]\E*[$SUP_LOWER]\E*[EXT] +\# +\# SLANT +\# ----- +\# +\# SETSLANT +\# -------- +\# *Arguments: +\# | RESET +\# *Function: +\# Modifies register #DEGREES for use with \*[SLANT], or resets +\# it to the default. Defines string \*[SLANTX] +\# *Notes: +\# \*[SLANT] permits pseudo-italicizing of a font in cases where +\# no italic font exists in a particular family. +\# +\# Default # of degrees is 15. +\# +\# Do not use unit of measure with arg to SETSLANT. +\# +\# It may be necessary to adjust the spacing on either side of +\# [SLANT] and [SLANTX]. +\# +\# In docs, SLANT carries over from para to para. +\# +.nr #DEGREES 15 +.ds SLANT \ER'#SLANT_ON 1'\ES'\En[#DEGREES]' +.ds SLANTX \ER'#SLANT_ON 0'\ES'0' +\# +.MAC SETSLANT END +. ie '\\$1'RESET' \{\ +. nr #DEGREES 15 +. if \\n[#PRINT_STYLE]=1 \ +. if \\n[#UNDERLINE_SLANT] .return +. ds SLANT \ER'#SLANT_ON 1'\ES'\En[#DEGREES]' +. \} +. el \{\ +. nr #DEGREES \\$1 +. if \\n[#PRINT_STYLE]=1 \ +. if \\n[#UNDERLINE_SLANT] .return +. ds SLANT \ER'#SLANT_ON 1'\ES'\En[#DEGREES]' +. \} +. ds SLANTX \ER'#SLANT_ON 0'\ES'0' +.END +\# +\# BOLDER +\# ------ +\# +\# SETBOLDER +\# --------- +\# *Arguments: +\# | RESET +\# *Function: +\# Modifies register #BOLDER_UNITS for use with \*[BOLDER], or resets +\# it to the default 700 units. +\# *Notes: +\# \*[BOLDER] allows pseudo-emboldening of a font where no bold +\# font exists in a particular family. +\# +\# Default for SETBOLDER is 700 units. Do not use unit of measure +\# with arg to SETBOLDER. +\# +.nr #BOLDER_UNITS 700 +\# +.MAC SETBOLDER END +. if \\n[#IGNORE]=1 .return +. ie '\\$1'RESET' .nr #BOLDER_UNITS 700 +. el .nr #BOLDER_UNITS \\$1 +.END +\# +.MAC BOLDER END +\c +.bd \\n[.f] \\n[#BOLDER_UNITS] +.END +\# +.MAC BOLDERX END +\c +.bd \\n[.f] +.END +\# +\# +++CONDENSE/EXTEND+++ +\# +\# CONDENSE/EXTEND +\# --------------- +\# *Arguments: +\# +\# *Function: +\# Stores current point size in z's in #PT_SIZE_IN_UNITS, figures out +\# new point size (for character width) from arg, and defines string +\# COND or EXT, which set the type size to the new character width, +\# and sets the height of type to the value stored in CURRENT_PT_SIZE +\# *Notes: +\# CONDENSE_OR_EXTEND is invoked from the aliases +\# CONDENSE and EXTEND. CONDENSE implies <100, EXTEND +\# implies >100. Do not use a percent sign in the argument. +\# +\# There is no default setting for CONDENSE or EXTEND. +\# 80 is a good approximation of condensed type, 120 is okay +\# for extended. +\# +\# The value set by CONDENSE or EXTEND applies to all +\# subsequent \*[COND] or \*[EXT] escapes until a new value is set. +\# +\# \*[COND] or \*[EXT] must be turned off before all changes of point +\# size, and reinvoked afterwards (if so desired). This refers to +\# changes of point size via control lines AND via inlines. +\# +.MAC CONDENSE_OR_EXTEND END +. if '\\$0'CONDENSE' \{\ +. ds $COND_PERCENT \\$1 +. if \\n[#PRINT_STYLE]=1 \{\ +. rm $COND_PERCENT +. ds $COND_PERCENT 100 +. \} +. ds COND \ +\R'#PT_SIZE_IN_UNITS \En[.ps]'\ +\R'#CONDENSE 1'\ +\R'#COND_WIDTH (\En[#PT_SIZE_IN_UNITS]u*\E*[$COND_PERCENT]u)/100'\ +\Es[\En[#COND_WIDTH]u]\EH'\En[#PT_SIZE_IN_UNITS]u' +. ds COND_FOR_SUP \ +\R'#COND_WIDTH (\En[#SUP_PT_SIZE]u*\E*[$COND_PERCENT]u)/100'\ +\Es[\En[#COND_WIDTH]u]\H'\En[#SUP_PT_SIZE]u' +. \} +. if '\\$0'EXTEND' \{\ +. ds $EXT_PERCENT \\$1 +. if \\n[#PRINT_STYLE]=1 \{\ +. rm $EXT_PERCENT +. ds $EXT_PERCENT 100 +. \} +. ds EXT \ +\R'#PT_SIZE_IN_UNITS \En[.ps]'\ +\R'#EXTEND 1'\ +\R'#EXT_WIDTH (\En[#PT_SIZE_IN_UNITS]u*\E*[$EXT_PERCENT]u)/100'\ +\Es[\En[#EXT_WIDTH]u]\EH'\En[#PT_SIZE_IN_UNITS]u' +. ds EXT_FOR_SUP \ +\R'#EXT_WIDTH (\En[#SUP_PT_SIZE]u*\E*[$EXT_PERCENT]u)/100'\ +\Es[\En[#EXT_WIDTH]u]\H'\En[#EXT_PT_SIZE]u' +. \} +.END +\# +.ds CONDX \ +\ER'#CONDENSE 0'\Es[0]\R'#PT_SIZE_IN_UNITS \En[.ps]'\H'\En[#PT_SIZE_IN_UNITS]u' +.ds EXTX \ +\ER'#EXTEND 0'\Es[0]\R'#PT_SIZE_IN_UNITS \En[.ps]'\H'\En[#PT_SIZE_IN_UNITS]u' +\# +\# +++PAD LINES+++ (insert space) +\# +\# PAD MARKER +\# ---------- +\# *Arguments: +\# +\# *Function: +\# Defines string $PAD_MARKER, used in PAD +\# *Notes: +\# $PAD_MARKER is normally # (the pound sign). +\# +.MAC PAD_MARKER END +. ds $PAD_MARKER \\$1 +.END +\# +\# PAD +\# --- +\# *Arguments: +\# "" +\# "" +\# *Function: +\# Defines and redefines padding character (default=pound sign +\# unless padding character has been set with PAD_MARKER) +\# several times so that when the string is output at the end +\# of the macro, every # has been converted to an equal-sized +\# amount of padding (blank space) on a line. +\# *Notes: +\# String tabs may be marked off during PAD. +\# +.MAC PAD END +. if \\n[.u]=1 .nr fill 1 +. nf +. if !d$PAD_MARKER .ds $PAD_MARKER # +. char \\*[$PAD_MARKER] \R'#PAD_COUNT \En[#PAD_COUNT]+1' +. ds $FAMILY_FOR_PAD \\n[.fam] +.\" .if !n .fp \\n[.fp] \\n[.sty] +. ds $FONT_FOR_PAD \\n[.sty] +. nr #SIZE_FOR_PAD \\n[.ps] +. ds $PAD_STRING \\$1 +. as $PAD_STRING \Ekp +. di PAD_STRING +. fam \\*[$FAMILY_FOR_PAD] +\f[\\*[$FONT_FOR_PAD]]\s[\\n[#SIZE_FOR_PAD]u]\\*[$PAD_STRING] +. br +. di +. if \\n[#INDENT_ACTIVE] \{\ +. if \\n[#INDENT_LEFT_ACTIVE] .ll -\\n[#L_INDENT]u +. if \\n[#INDENT_RIGHT_ACTIVE] .ll -\\n[#R_INDENT]u +. if \\n[#INDENT_BOTH_ACTIVE] .ll -\\n[#BR_INDENT]u +. \} +. char \\*[$PAD_MARKER] \ +\R'#SPACE_TO_END \En[.l]-\En[p]'\R'#PAD_SPACE \En[#SPACE_TO_END]/\En[#PAD_COUNT]' +. di PAD_STRING +. fam \\*[$FAMILY_FOR_PAD] +\f[\\*[$FONT_FOR_PAD]]\s[\\n[#SIZE_FOR_PAD]u]\\*[$PAD_STRING] +. br +. di +. if \\n[#INDENT_ACTIVE] \ +. if (\\n[#INDENT_LEFT_ACTIVE]=1):(\\n[#INDENT_BOTH_ACTIVE]) .ll +. char \\*[$PAD_MARKER] \h'\En[#PAD_SPACE]u' +. if \\n[#SILENT] .SILENT +. fam \\*[$FAMILY_FOR_PAD] +\f[\\*[$FONT_FOR_PAD]]\s[\\n[#SIZE_FOR_PAD]u] +. ie '\\$2'' .nop \\*[$PAD_STRING] +. el \{\ +. ie !'\\$2'NOBREAK' .pdfhref L -D "\\$2" -E -- \&\\*[$PAD_STRING] +. el .nop \\*[$PAD_STRING] +. \} +. if \\n[#SILENT] .SILENT OFF +. br +. if \\n[fill] \{\ +. fi +. rr fill +. \} +. rr #PAD_COUNT +. rr #SPACE_TO_END +. rr #PAD_SPACE +. rm $PAD_STRING +. rm PAD_STRING +. rchar \\*[$PAD_MARKER] +. if '\\$2'NOBREAK' \{\ +. TRAP OFF +. EOL +. TRAP +. \} +.END +\# +\# +++LEADERS+++ +\# +\# The leader mechanism is primitive, but it works. Basically, every +\# macro in this set that includes a line length also sets a single +\# groff tab stop at the right hand end of the line. That way, +\# whenever Ctrl-A is invoked (always at the end of an input line), +\# leader of the correct length gets deposited. Ctrl-A is accessed by +\# the string LEADER (i.e. inline, as \*[LEADER]). Leaders within tabs +\# get their length from the tab line length. +\# +\# SET LEADER CHARACTER +\# -------------------- +\# *Arguments: +\# +\# *Function: +\# Set leader character. +\# +.MAC LEADER_CHARACTER END +. lc \\$1 +.END +\# +.ds LEADER  +\# +\# +++DROP CAPS+++ +\# +\# DROP CAP FAMILY +\# --------------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies string $DC_FAM. +\# +.MAC DROPCAP_FAMILY END +. ds $DC_FAM \\$1 +.END +\# +\# DROP CAP FONT +\# ------------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies string $DC_FT. +\# +.MAC DROPCAP_FONT END +. ds $DC_FT \\$1 +.END +\# +\# DROPCAP COLOR +\# ------------- +\# *Arguments: +\# +\# *Function: +\# Defines string $DC_COLOR to argument. +\# *Notes: +\# User must define an XCOLOR or NEWCOLOR before using +\# DC_COLOR. +\# +.MAC DROPCAP_COLOR END +. if \\n[#PRINT_STYLE]=1 .return +. nr #DC_COLOR 1 +. ds $DC_COLOR \\$1 +.END +\# +\# DROP CAP GUTTER +\# --------------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies register #DC_GUT. +\# *Notes: +\# Requires unit of measure. Default is 3p. +\# +.MAC DROPCAP_GUTTER END +. nr #DC_GUT (\\$1) +.END +\# +\# DROP CAP ADJUST +\# --------------- +\# *Argument: +\# <+|- # of points to in/decrease point size of drop cap letter> +\# *Function: +\# Creates or modifies string $DC_ADJUST. +\# *Notes: +\# Despite its best efforts, DROPCAP doesn't always get the point +\# size of the drop cap critically perfect. DROPCAP_ADJUST lets +\# the user add or subtract points (or fractions of points) to +\# get the size right. +\# +\# Requires the + or - sign. +\# +.MAC DROPCAP_ADJUST END +. ds $DC_ADJUST \\$1 +.END +\# +\# DROP CAP +\# -------- +\# *Arguments: +\# <# of lines> [COND <% to condense> | EXT <% to extend>] +\# *Function: +\# Calculates point size of dropcap based on # of lines passed as +\# arg 2. Sets indent for text based on dropcap width+gutter. +\# Advances and prints dropcap; reverses and prints indented text +\# to bottom of dropcap, then resets indent to left margin (plus +\# any indent that was in effect prior to invoking DROPCAP). +\# *Notes: +\# Drop caps when using the doc processing macro PP only work with +\# initial paragraphs (i.e. at doc start, or after heads), only when +\# DROPCAPS comes immediately after PP, and only when the PRINTSTYLE +\# is TYPESET. If these conditions aren't met, DROPCAPS is silently +\# ignored. +\# +\# The COND or EXT argument are processed separately from all +\# other COND or EXT inlines or macros, hence passing COND or +\# EXT has no effect on running type. +\# +.MAC DROPCAP END +. if \\n[#IGNORE]=1 \{\ +. PRINT \\$1\c +. return +. \} +. br +. if n \{\ +. PRINT \\$1\c +. return +. \} +. if \\n[#DOCS] \{\ +. if \\n[#PRINT_STYLE]=1 \{\ +. PRINT \\$1\c +. return +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. sp -1 +. if \\n[#PP_STYLE]=2 \{\ +. PRINT \\$1\c +. return +. \} +. if \\n[#PP]>1 \{\ +. if \\n[#PP_INDENT] .ti \\n[#PP_INDENT]u +. PRINT \\$1\c +. return +. \} +. ti 0 +. \} +. \} +. ds $DROPCAP \\$1 +. nr #DC_LINES \\$2-1 +. if \\n[#CONDENSE]=1 \{\ +. ds $RESTORE_COND \\*[$COND_PERCENT] +\\*[CONDX] +. nr #CONDENSE_WAS_ON 1 +. \} +. if \\n[#EXTEND]=1 \{\ +. ds $RESTORE_EXT \\*[$EXT_PERCENT] +\\*[EXTX] +. nr #EXTEND_WAS_ON 1 +. \} +. if '\\$3'COND' .CONDENSE \\$4 +. if '\\$3'EXT' .EXTEND \\$4 +. if !r#DC_GUT .nr #DC_GUT 3p +. ie \\n[#DOCS] .ds $RESTORE_FAM \\*[$DOC_FAM] +. el .ds $RESTORE_FAM \\n[.fam] +. ie \\n[#DOCS] .ds $RESTORE_FT \\*[$PP_FT] +. el .ds $RESTORE_FT \\*[$FONT] +. nr #RESTORE_PT_SIZE \\n[#PT_SIZE] +. nr #RESTORE_INDENT \\n[.i] +. SIZESPECS +. nr #DC_HEIGHT \\n[#DC_LINES]*\\n[#LEAD]+\\n[#CAP_HEIGHT] +. ie !d$DC_FAM .FAM \\n[.fam] +. el .FAM \\*[$DC_FAM] +. ie !d$DC_FT .FT \\*[$FONT] +. el .FT \\*[$DC_FT] +. while \\n[#GET_DC_HEIGHT]<\\n[#DC_HEIGHT] \{\ +. ps \\n[#PT_SIZE]u+100u +. SIZESPECS +. nr #GET_DC_HEIGHT \\n[#CAP_HEIGHT] +. \} +. if d$DC_ADJUST .ps \\*[$DC_ADJUST]p +. nr #DC_LINES +1 +. if (\\n[#DC_LINES]v-1v)>(\\n[.t]-1) \{\ +. nr pgnum \\n%+\\n[#PAGE_NUM_ADJ] 1 +. if \\n[#COLUMNS]=1 .ds col-num ", column \\n[#COL_NUM] +. tm1 \ +"[mom]: Dropcap at line \\n[.c] does not fit on page \\n[pgnum]\\*[col-num]. +. tm1 \ +" Shifting paragraph to next page or column. +. ie \\n[#COLUMNS] .COL_NEXT +. el .NEWPAGE +. \} +. ie \\n[#DC_COLOR]=1 \{\ +. ie !'\\$3'' \{\ +. ie '\\$3'COND' \ +. PRINT \ +\\*[DOWN \\n[#DC_LINES]v]\ +\m[\\*[$DC_COLOR]]\\*[COND]\\*[$DROPCAP]\\*[CONDX]\m[]\\*[UP \\n[#DC_LINES]v] +. el \ +. PRINT \ +\\*[DOWN \\n[#DC_LINES]v]\ +\m[\\*[$DC_COLOR]]\\*[EXT]\\*[$DROPCAP]\\*[EXTX]\m[]\\*[UP \\n[#DC_LINES]v] +. \} +. el .PRINT \ +\\*[DOWN \\n[#DC_LINES]v]\ +\m[\\*[$DC_COLOR]]\\*[$DROPCAP]\m[]\\*[UP \\n[#DC_LINES]v] +. \} +. el \{\ +. ie !'\\$3'' \{\ +. ie '\\$3'COND' \ +. PRINT \ +\\*[DOWN \\n[#DC_LINES]v]\ +\\*[COND]\\*[$DROPCAP]\\*[CONDX]\\*[UP \\n[#DC_LINES]v] +. el \ +. PRINT \ +\\*[DOWN \\n[#DC_LINES]v]\ +\\*[EXT]\\*[$DROPCAP]\\*[EXTX]\\*[UP \\n[#DC_LINES]v] +. \} +. el .PRINT \ +\\*[DOWN \\n[#DC_LINES]v]\ +\\*[$DROPCAP]\\*[UP \\n[#DC_LINES]v] +. \} +. if '\\$3'COND' \E*[COND] +. if '\\$3'EXT' \E*[EXT] +. ie \\n[.i] \{\ +. vs 0 +. br +. in +\w'\\*[$DROPCAP]'u+\\n[#DC_GUT]u +. vs +. \} +. el \{\ +. vs 0 +. br +. in \w'\\*[$DROPCAP]'u+\\n[#DC_GUT]u +. vs +. \} +. if '\\$3'COND' \E*[CONDX]\c +. if '\\$3'EXT' \E*[EXTX]\c +. FAM \\*[$RESTORE_FAM] +. FT \\*[$RESTORE_FT] +. ps \\n[#RESTORE_PT_SIZE]u +. if \\n[#CONDENSE_WAS_ON] \{\ +. CONDENSE \\*[$RESTORE_COND] +\\*[COND]\c +. \} +. if \\n[#EXTEND_WAS_ON] \{\ +. EXTEND \\*[$RESTORE_EXT] +\\*[EXT]\c +. \} +. ie \\n[.u] .wh \\n[.d]u+\\n[#DC_HEIGHT]u-1v DROPCAP_OFF +. el .wh \\n[.d]u+\\n[#DC_HEIGHT]u DROPCAP_OFF +. rr #CONDENSE_WAS_ON +. rr #EXTEND_WAS_ON +. rm $DROPCAP +. rr #DC_LINES +. rm $RESTORE_COND +. rm $RESTORE_EXT +. rm $RESTORE_FAM +. rm $RESTORE_FT +. rr #RESTORE_PT_SIZE +. rr #RESTORE_INDENT +. rr #DC_HEIGHT +. rr #GET_DC_HEIGHT +. rr x +.END +\# +.MAC DROPCAP_OFF END +' in \\n[#RESTORE_INDENT]u +. ch DROPCAP_OFF +.END +\# +\# ===================================================================== +\# +\# +++GRAPHICAL OBJECTS+++ +\# +\# Set params for graphical objects. +\# +.MAC GRAPHICAL_OBJ END +. rr #FILLED +. rr #FILL_MODE +. rr #NOFILL +. rr #NOFILL_MODE +. if \\n[.vpt]=1 \{\ +. vpt 0 +. nr #RESTORE_TRAP 1 +. \} +. ie !\\n[#NO_ADVANCE]=1 .br +. el \{\ +. sp -1v +. rr #NO_ADVANCE +. \} +. ie \\n[.u]=1 \{\ +. nr #FILLED 1 +. nr #FILL_MODE \\n[.j] +. \} +. el \{\ +. nr #NOFILL 1 +. if \\n[.ce]>0 .nr #NOFILL_MODE 3 +. if \\n[.rj]>0 .nr #NOFILL_MODE 5 +. ce 0 +. rj 0 +. \} +. nf +.END +\# +\# HORIZONTAL RULE - DRH +\# --------------------- +\# *Arguments: +\# | [ ] +\# *Function: +\# With no arg, draws a full measure rule. With args, draws +\# described horizontal rule. +\# *Notes: +\# Rules are drawn left-to-right, from the baseline down, and +\# return to their point of origin. If no arg given (full measure +\# rule), the rule weight is the one set by RULE_WEIGHT. +\# +.MAC DRH END +. GRAPHICAL_OBJ +. ds $RL_WEIGHT \\$1 +. ds $RL_INDENT \\$2 +. ds $RL_LENGTH \\$3 +. ie !'\\$4'' .ds $RL_COLOR \\$4 +. el \{\ +. ie '\\n[.m]'' .ds $RL_COLOR \\*[default] +. el .ds $RL_COLOR \\n[.m] +. \} +. nr #SAVED_WEIGHT \\n[#RULE_WEIGHT] +. nr #SAVED_WEIGHT_ADJ \\n[#RULE_WEIGHT_ADJ] +. di NULL +. if \\n[#NUM_ARGS]>=1 .RULE_WEIGHT \\*[$RL_WEIGHT] +. di +. COLOR \\*[$RL_COLOR] +. ie \\n[#NUM_ARGS]=0 \{\ +. ie \\n[#INDENT_ACTIVE] \{\ +. nr #RESTORE_L_LENGTH \\n[.l] +. if \\n[#INDENT_BOTH_ACTIVE] .ll \\n[.l]u-\\n[#BL_INDENT]u +. if \\n[#INDENT_LEFT_ACTIVE] .ll \\n[.l]u-\\n[#L_INDENT]u +\Z'\D't \\n[#RULE_WEIGHT]''\ +\h'\\*[$RL_INDENT]+\\n[#RULE_WEIGHT_ADJ]u'\ +\v'\\n[#RULE_WEIGHT_ADJ]u'\ +\D'l \En[.l]u 0'\v'-\\n[#RULE_WEIGHT_ADJ]u'\ +\v'-\\n[#RULE_WEIGHT_ADJ]u'\ +\Z'\D't \\n[#SAVED_RULE_WEIGHT]'' +. ll \\n[#RESTORE_L_LENGTH]u +. rr #RESTORE_L_LENGTH +. \} +. el \{\ +\Z'\D't \\n[#RULE_WEIGHT]''\ +\h'\\*[$RL_INDENT]+\\n[#RULE_WEIGHT_ADJ]u'\ +\v'\\n[#RULE_WEIGHT_ADJ]u'\ +\D'l \En[.l]u 0'\v'-\\n[#RULE_WEIGHT_ADJ]u'\ +\v'-\\n[#RULE_WEIGHT_ADJ]u'\ +\Z'\D't \\n[#SAVED_RULE_WEIGHT]'' +. \} +. \} +. el \{\ +\Z'\D't \\n[#RULE_WEIGHT]''\ +\h'\\*[$RL_INDENT]+\\n[#RULE_WEIGHT_ADJ]u'\ +\v'\\n[#RULE_WEIGHT_ADJ]u'\ +\D'l \\*[$RL_LENGTH] 0'\ +\v'-\\n[#RULE_WEIGHT_ADJ]u'\ +\Z'\D't \\n[#SAVED_RULE_WEIGHT]'' +. rr #RESTORE_L_LENGTH +. \} +. if \\n[#FILLED]=1 \{\ +. if \\n[#FILL_MODE]=0 .QUAD LEFT +. if \\n[#FILL_MODE]=1 .JUSTIFY +. if \\n[#FILL_MODE]=3 .QUAD CENTER +. if \\n[#FILL_MODE]=5 .QUAD RIGHT +. rr #FILLED +. \} +. sp -1v +. if \\n[#NOFILL]=1 \{\ +. if \\n[#NOFILL_MODE]=3 .CENTER +. if \\n[#NOFILL_MODE]=5 .RIGHT +. \} +. gcolor +. nr #RULE_WEIGHT \\n[#SAVED_WEIGHT] +. nr #RULE_WEIGHT_ADJ \\n[#SAVED_WEIGHT_ADJ] +. rr #SAVED_WEIGHT +. rr #SAVED_WEIGHT_ADJ +. if \\n[#RESTORE_TRAP]=1 \{\ +. vpt +. rr #RESTORE_TRAP +. \} +. if '\\n[.z]'FLOAT*DIV' \ +. if !(\\n[.d]+\\n[#WEIGHT])<\\n[D-float] .nr D-float \\n[.d]+\\n[#WEIGHT] +.END +\# +\# RULE +\# ---- +\# *Argument: +\# +\# *Function: +\# Draws a rule the length of the current measure. +\# *Notes: +\# A convenience macro. DRH with no argument does the same thing. +\# Kept in for backward compatibility. +\# +.MAC RULE END +. if \\n[.u]=1 \{\ +. nr fill 1 +. ds $CURRENT_QUAD \\*[$QUAD_VALUE] +. nf +. \} +. ie \\n[#INDENT_ACTIVE] \{\ +. if \\n[#INDENT_BOTH_ACTIVE] .ll \\n[.l]u-\\n[#BL_INDENT]u +. if \\n[#INDENT_LEFT_ACTIVE] .ll \\n[.l]u-\\n[#L_INDENT]u +. PRINT \ +\Z'\D't \\n[#RULE_WEIGHT]''\ +\v'\\n[#RULE_WEIGHT_ADJ]u'\ +\h'\\n[#RULE_WEIGHT_ADJ]u'\ +\D'l \En[.l]u 0'\v'-\\n[#RULE_WEIGHT_ADJ]u'\h'|0'\c +. ll +. rr #RESTORE_L_LENGTH +. \} +. el \{\ +. PRINT \ +\Z'\D't \\n[#RULE_WEIGHT]''\ +\v'\\n[#RULE_WEIGHT_ADJ]u'\ +\h'\\n[#RULE_WEIGHT_ADJ]u'\ +\D'l \En[.l]u 0'\v'-\\n[#RULE_WEIGHT_ADJ]u'\h'|0'\c +. \} +. if \\n[fill] \{\ +. fi +. rr fill +. QUAD \\*[$CURRENT_QUAD] +. rm $CURRENT_QUAD +. \} +. EOL +.END +\# +\# VERTICAL RULE - DRV +\# ------------------- +\# *Arguments: +\# [ ] +\# *Function: +\# Draws described vertical rule. +\# *Notes: +\# Rules are drawn left-to-right, from the baseline down, and +\# return to their point of origin. +.MAC DRV END +. GRAPHICAL_OBJ +. ds $RL_WEIGHT \\$1 +. ds $RL_INDENT \\$2 +. ds $RL_DEPTH \\$3 +. ie !'\\$4'' \ +. ds $RL_COLOR \\$4 +. el \{\ +. ie '\\n[.m]'' .ds $RL_COLOR \\*[default] +. el .ds $RL_COLOR \\n[.m] +. \} +. nr #SAVED_WEIGHT \\n[#RULE_WEIGHT] +. nr #SAVED_WEIGHT_ADJ \\n[#RULE_WEIGHT_ADJ] +. RULE_WEIGHT \\*[$RL_WEIGHT] +. COLOR \\*[$RL_COLOR] +\Z'\D't \\n[#RULE_WEIGHT]''\ +\h'\\*[$RL_INDENT]+\\n[#RULE_WEIGHT]u+\\n[#RULE_WEIGHT_ADJ]u'\ +\D'l 0 \\*[$RL_DEPTH]'\ +\D't \\n[#SAVED_RULE_WEIGHT]' +. if \\n[#FILLED]=1 \{\ +. if \\n[#FILL_MODE]=0 .QUAD LEFT +. if \\n[#FILL_MODE]=1 .JUSTIFY +. if \\n[#FILL_MODE]=3 .QUAD CENTER +. if \\n[#FILL_MODE]=5 .QUAD RIGHT +. rr #FILLED +. \} +. sp -1v +. if \\n[#NOFILL]=1 \{\ +. if \\n[#NOFILL_MODE]=3 .CENTER +. if \\n[#NOFILL_MODE]=5 .RIGHT +. \} +. gcolor +. nr #RULE_WEIGHT \\n[#SAVED_WEIGHT] +. nr #RULE_WEIGHT_ADJ \\n[#SAVED_WEIGHT_ADJ] +. if \\n[#RESTORE_TRAP]=1 \{\ +. vpt +. rr #RESTORE_TRAP +. \} +. if '\\n[.z]'FLOAT*DIV' \ +. if !(\\n[.d]+\\*[$RL_DEPTH])<\\n[D-float] .nr D-float \\n[.d]+\\*[$RL_DEPTH] +.END +\# +\# BOXES - DBX +\# ----------- +\# *Arguments: +\# |SOLID |FULL_MEASURE [ ] +\# *Function: +\# Draws described box. +\# *Notes: +\# Boxes are drawn left-to-right, from the baseline down, and +\# return to their point of origin. Box rules are drawn from the +\# perimeter inwards. +\# +.MAC DBX END +. GRAPHICAL_OBJ +. ie '\\$1'SOLID' .nr #BX_SOLID 1 +. el .ds $BX_WEIGHT \\$1 +. ds $BX_INDENT \\$2 +. ie '\\$3'FULL_MEASURE' \{\ +. ie (\\n[#INDENT_LEFT_ACTIVE]+\\n[#INDENT_RIGHT_ACTIVE]+\\n[#INDENT_BOTH_ACTIVE])=0 \{\ +. nr #WIDTH \\n[.l] +. ds $BX_WIDTH \\n[#WIDTH]u +. \} +. el \{\ +. if \\n[#INDENT_LEFT_ACTIVE] \{\ +. nr #WIDTH \\n[.l]-\\n[#L_INDENT] +. ds $BX_WIDTH \\n[#WIDTH]u +. \} +. if \\n[#INDENT_RIGHT_ACTIVE] \{\ +. nr #WIDTH \\n[.l] +. ds $BX_WIDTH \\n[#WIDTH]u +. \} +. if \\n[#INDENT_BOTH_ACTIVE] \{\ +. nr #WIDTH \\n[.l]-(\\n[#BL_INDENT]) +. ds $BX_WIDTH \\n[#WIDTH]u +. \} +. \} +. \} +. el .ds $BX_WIDTH \\$3 +. ds $BX_DEPTH \\$4 +. ie !'\\$5'' \{\ +. ie d$\\$5_FILL .ds $BX_COLOR \\*[$\\$5_FILL] +. el .ds $BX_COLOR \\$5 +. \} +. el \{\ +. ie '\\n[.m]'' .ds $BX_COLOR \\*[default] +. el .ds $BX_COLOR \\n[.m] +. \} +. nr #SAVED_WEIGHT \\n[#RULE_WEIGHT] +. nr #SAVED_WEIGHT_ADJ \\n[#WEIGHT_ADJ] +. if !'\\$1'SOLID' .RULE_WEIGHT \\*[$BX_WEIGHT] +. ds $BX_INDENT \\*[$BX_INDENT]-\\n[#WEIGHT_ADJ]u +. ie \\n[#BX_SOLID]=1 \{\ +. fcolor \\*[$BX_COLOR] +\h'\\*[$BX_INDENT]+\\n[#BOX_WEIGHT_ADJ]u+\\n[#RULE_WEIGHT]u'\ +\D'P \\*[$BX_WIDTH] 0 0 \\*[$BX_DEPTH] -\\*[$BX_WIDTH] 0 0 -\\*[$BX_DEPTH]' +. fcolor +. rr #BX_SOLID +. \} +. el \{\ +. COLOR \\*[$BX_COLOR] +\Z'\D't \\n[#RULE_WEIGHT]''\ +\h'\\*[$BX_INDENT]+\\n[#RULE_WEIGHT]u+\\n[#RULE_WEIGHT_ADJ]u'\ +\v'\\n[#WEIGHT_ADJ]u'\ +\D'p \\*[$BX_WIDTH]-\\n[#RULE_WEIGHT]u 0 0 \\*[$BX_DEPTH]-\\n[#RULE_WEIGHT]u -\\*[$BX_WIDTH]+\\n[#RULE_WEIGHT]u 0 0 -\\*[$BX_DEPTH]+\\n[#RULE_WEIGHT]u'\ +\v'-\\n[#WEIGHT_ADJ]u'\ +\Z'\D't \\n[#SAVED_RULE_WEIGHT]'' +. gcolor +. \} +. sp -1v +. if \\n[#FILLED]=1 \{\ +. if \\n[#FILL_MODE]=0 .QUAD LEFT +. if \\n[#FILL_MODE]=1 .JUSTIFY +. if \\n[#FILL_MODE]=3 .QUAD CENTER +. if \\n[#FILL_MODE]=5 .QUAD RIGHT +. \} +. if \\n[#NOFILL]=1 \{\ +. if \\n[#NOFILL_MODE]=3 .CENTER +. if \\n[#NOFILL_MODE]=5 .RIGHT +. \} +. nr #RULE_WEIGHT \\n[#SAVED_WEIGHT] +. nr #WEIGHT_ADJ \\n[#SAVED_WEIGHT_ADJ] +. rr #SAVED_WEIGHT +. rr #SAVED_WEIGHT_ADJ +. if \\n[#RESTORE_TRAP]=1 \{\ +. vpt +. rr #RESTORE_TRAP +. \} +. if '\\n[.z]'FLOAT*DIV' \ +. if !(\\n[.d]+\\*[$BX_DEPTH])<\\n[D-float] .nr D-float \\n[.d]+\\*[$BX_DEPTH] +.END +\# +\# ELLIPSES - DCL +\# -------------- +\# *Arguments: +\# |SOLID |FULL_MEASURE [ ] +\# *Function: +\# Draws described ellipses. +\# *Notes: +\# Ellipses (circles) are drawn left-to-right, from the baseline +\# down, and return to their point of origin. Ellipse rules are +\# drawn from the perimeter inwards. +\# +.MAC DCL END +. GRAPHICAL_OBJ +. ie '\\$1'SOLID' .nr #CL_SOLID 1 +. el .ds $CL_WEIGHT \\$1 +. ds $CL_INDENT \\$2 +. ds $CL_WIDTH \\$3 +. ie '\\$3'FULL_MEASURE' \{\ +. ie (\\n[#INDENT_LEFT_ACTIVE]+\\n[#INDENT_RIGHT_ACTIVE]+\\n[#INDENT_BOTH_ACTIVE])=0 \ +. nr #WIDTH \\n[.l] +. ds $CL_WIDTH \\n[#WIDTH]u +. el \{\ +. if \\n[#INDENT_LEFT_ACTIVE] \{\ +. nr #WIDTH \\n[.l]-\\n[#L_INDENT] +. ds $CL_WIDTH \\n[#WIDTH]u +. \} +. if \\n[#INDENT_RIGHT_ACTIVE] \{\ +. nr #WIDTH \\n[.l] +. ds $CL_WIDTH \\n[#WIDTH]u +. \} +. if \\n[#INDENT_BOTH_ACTIVE] \{\ +. nr #WIDTH \\n[.l]-(\\n[#BL_INDENT]) +. ds $CL_WIDTH \\n[#WIDTH]u +. \} +. \} +. \} +. el .ds $CL_WIDTH \\$3 +. ds $CL_DEPTH \\$4 +. ie !'\\$5'' \{\ +. ie d$\\$5_FILL .ds $CL_COLOR \\*[$\\$5_FILL] +. el .ds $CL_COLOR \\$5 +. \} +. el \{\ +. ie '\\n[.m]'' .ds $CL_COLOR \\*[default] +. el .ds $CL_COLOR \\n[.m] +. \} +. nr #SAVED_WEIGHT \\n[#RULE_WEIGHT] +. nr #SAVED_WEIGHT_ADJ \\n[#WEIGHT_ADJ] +. if !'\\$1'SOLID' .RULE_WEIGHT \\*[$CL_WEIGHT] +. ds $CL_INDENT \\*[$CL_INDENT]-\\n[#WEIGHT_ADJ]u +. ie \\n[#CL_SOLID]=1 \{\ +. fcolor \\*[$CL_COLOR] +\h'\\*[$CL_INDENT]+\\n[#RULE_WEIGHT]u'\ +\v'\\*[$CL_DEPTH]/2u'\ +\D'E \\*[$CL_WIDTH]-\\n[#RULE_WEIGHT]u \\*[$CL_DEPTH]-\\n[#RULE_WEIGHT]u'\ +\v'-\\*[$CL_DEPTH]/2u' +. fcolor +. rr #CL_SOLID +. \} +. el \{\ +. COLOR \\*[$CL_COLOR] +\Z'\D't \\n[#RULE_WEIGHT]''\ +\h'\\*[$CL_INDENT]+\\n[#RULE_WEIGHT]u+\\n[#RULE_WEIGHT_ADJ]u'\ +\v'\\*[$CL_DEPTH]/2u'\ +\D'e \\*[$CL_WIDTH]-\\n[#RULE_WEIGHT]u \\*[$CL_DEPTH]-\\n[#RULE_WEIGHT]u'\ +\v'-(\\*[$CL_DEPTH]/2u)'\ +\Z'\D't \\n[#SAVED_RULE_WEIGHT]'' +. gcolor +. \} +. sp -1v +. if \\n[#FILLED]=1 \{\ +. if \\n[#FILL_MODE]=0 .QUAD LEFT +. if \\n[#FILL_MODE]=1 .JUSTIFY +. if \\n[#FILL_MODE]=3 .QUAD CENTER +. if \\n[#FILL_MODE]=5 .QUAD RIGHT +. rr #FILLED +. \} +. if \\n[#NOFILL]=1 \{\ +. if \\n[#NOFILL_MODE]=3 .CENTER +. if \\n[#NOFILL_MODE]=5 .RIGHT +. \} +. nr #RULE_WEIGHT \\n[#SAVED_WEIGHT] +. nr #WEIGHT_ADJ \\n[#SAVED_WEIGHT_ADJ] +. rr #SAVED_WEIGHT +. rr #SAVED_WEIGHT_ADJ +. if \\n[#RESTORE_TRAP]=1 \{\ +. vpt +. rr #RESTORE_TRAP +. \} +. if '\\n[.z]'FLOAT*DIV' \ +. if !(\\n[.d]+\\*[$CL_DEPTH])<\\n[D-float] .nr D-float \\n[.d]+\\*[$CL_DEPTH] +.END +\# +\# RULE WEIGHT +\# ----------- +\# *Argument: +\# +\# *Function: +\# Sets \D't ' to the correct number of machine units for the +\# argument given in points. +\# *Notes: +\# Decimal fractions are allowed. Rule weight must be < 100. +\# +.MAC RULE_WEIGHT END +. di NULL \" Diverted so there's no problem with breaks, spacing, etc. +. ds $ARG \\$1 +. substring $ARG -1 +. if !\B'\\*[$ARG]' \{\ +. tm1 "[mom]: The argument to \\$0 must not have a unit of measure appended. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. length #STR_LENGTH \\$1 +. ds $ARG \\$1 +. substring $ARG 0 0 +. ie '\\*[$ARG]'.' \{\ +. ds $ARG \\$1 +. substring $ARG 1 \\n[#STR_LENGTH]-1 +. nr #WEIGHT \\*[$ARG]*100 +. if (\\n[#WEIGHT]>=1000) \{\ +. while (\\n[#WEIGHT]>=1000) \{\ +. nr #WEIGHT \\n[#WEIGHT]/10 +. \} +. \} +. \} +. el \{\ +. ds $ARG \\$1 +. length #ARG_LENGTH \\*[$ARG] +. if \\n[#ARG_LENGTH]>1 .substring $ARG 1 1 +. ie '\\*[$ARG]'.' \{\ +. ds $LHS \\$1 +. substring $LHS 0 0 +. ds $RHS \\$1 +. substring $RHS 2 +. nr #WEIGHT \\*[$LHS]\\*[$RHS]*100 +. if (\\n[#WEIGHT]>=10000) \{\ +. while (\\n[#WEIGHT]>=10000) \{\ +. nr #WEIGHT \\n[#WEIGHT]/10 +. \} +. \} +. \} +. el \{\ +. ie \\n[#STR_LENGTH]<=2 .nr #WEIGHT \\$1*1000 +. el \{\ +. ds $ARG \\$1 +. substring $ARG 2 2 +. ie !'\\*[$ARG]'.' \{\ +. tm1 "[mom]: Invalid argument given to macro \\$0 at line \\n[.c]. +. tm1 " Rule weight must be < 100 points. +. tm1 " Falling back to default weight .5 points. +. nr #WEIGHT 500 +. \} +. el \{\ +. ds $LHS \\$1 +. substring $LHS 0 1 +. ds $RHS \\$1 +. substring $RHS 3 +. nr #WEIGHT \\*[$LHS]\\*[$RHS]*1000 +. if (\\n[#WEIGHT]>=100000) \{\ +. while (\\n[#WEIGHT]>=100000) \{\ +. nr #WEIGHT \\n[#WEIGHT]/10 +. \} +. \} +. \} +. \} +. \} +. \} +. nr #WEIGHT_ADJ \\n[#WEIGHT]/2 +. if '\\$0'BIBLIOGRAPHY_STRING_UNDERLINE_WEIGHT' \ +. ds $TITLE_TYPE BIB_STRING_ +. if '\\$0'ENDNOTE_TITLE_UNDERLINE_WEIGHT' \ +. ds $TITLE_TYPE EN_TITLE_ +. if '\\$0'EN_HEADER_UNDERLINE_WEIGHT' \ +. ds $TITLE_TYPE EN_STRING_ +. if !'\\*[$TITLE_TYPE]'BIB_STRING' \ +. if !'\\*[$TITLE_TYPE]'EN_TITLE' \ +. if !'\\*[$TITLE_TYPE]'EN_STRING' \ +. ds _TYPE \\$0 +. length type-len _TYPE +. if \\n[type-len]>17 \{\ +. substring _TYPE 0 -17 +. ds $TITLE_TYPE \\*[_TYPE] +. \} +. if !'\\*[$TITLE_TYPE]'' \{\ +. nr #\\*[$TITLE_TYPE]UNDERLINE_WEIGHT \\n[#WEIGHT] +. nr #\\*[$TITLE_TYPE]UNDERLINE_WEIGHT_ADJ \\n[#WEIGHT_ADJ] +. \} +. if '\\$0'RULE_WEIGHT' \{\ +. nr #RULE_WEIGHT \\n[#WEIGHT] +. nr #RULE_WEIGHT_ADJ \\n[#WEIGHT_ADJ] +. \} +. if '\\$0'UNDERSCORE_WEIGHT' \{\ +. nr #UNDERSCORE_WEIGHT \\n[#WEIGHT] +. nr #UNDERSCORE_WEIGHT_ADJ \\n[#WEIGHT_ADJ] +. \} +. if '\\$0'FOOTER_RULE_WEIGHT' \{\ +. nr #FOOTER_RULE_WEIGHT \\n[#WEIGHT] +. nr #FOOTER_RULE_WEIGHT_ADJ \\n[#WEIGHT_ADJ] +. \} +. if '\\$0'FOOTNOTE_RULE_WEIGHT' \{\ +. nr #FN_RULE_WEIGHT \\n[#WEIGHT] +. nr #FN_RULE_WEIGHT_ADJ \\n[#WEIGHT_ADJ] +. \} +. if '\\$0'HEADER_RULE_WEIGHT' \{\ +. nr #HEADER_RULE_WEIGHT \\n[#WEIGHT] +. nr #HEADER_RULE_WEIGHT_ADJ \\n[#WEIGHT_ADJ] +. \} +. di +.END +\# +\# Aliases for RULE_WEIGHT +\# +.ALIAS BIB_STRING_UNDERLINE_WEIGHT RULE_WEIGHT +.ALIAS DOCTYPE_UNDERLINE_WEIGHT RULE_WEIGHT +.ALIAS EN_STRING_UNDERLINE_WEIGHT RULE_WEIGHT +.ALIAS EN_TITLE_UNDERLINE_WEIGHT RULE_WEIGHT +.ALIAS FN_RULE_WEIGHT RULE_WEIGHT +.ALIAS FOOTER_RULE_WEIGHT RULE_WEIGHT +.ALIAS FOOTNOTE_RULE_WEIGHT RULE_WEIGHT +.ALIAS HEADER_RULE_WEIGHT RULE_WEIGHT +.ALIAS RULE_WEIGHT RULE_WEIGHT +.ALIAS TOC_HEADER_UNDERLINE_WEIGHT RULE_WEIGHT +.ALIAS UNDERSCORE_WEIGHT RULE_WEIGHT +\# +\# Default rule weights +\# +.nr #BIB_STRING_UNDERLINE_WEIGHT 500 +.nr #DOCTYPE_UNDERLINE_WEIGHT 500 +.nr #EN_STRING_UNDERLINE_WEIGHT 500 +.nr #EN_TITLE_UNDERLINE_WEIGHT 500 +.nr #FN_RULE_WEIGHT 500 +.nr #FOOTER_RULE_WEIGHT 500 +.nr #HEADER_RULE_WEIGHT 500 +.nr #RULE_WEIGHT 500 +.nr #TOC_HEADER_UNDERLINE_WEIGHT 500 +.nr #UNDERSCORE_WEIGHT 500 +\# +.nr #BIB_STRING_UNDERLINE_WEIGHT_ADJ \n[#BIB_STRING_UNDERLINE_WEIGHT]/2 +.nr #DOCTYPE_UNDERLINE_WEIGHT_ADJ \n[#DOCTYPE_UNDERLINE_WEIGHT]/2 +.nr #EN_STRING_UNDERLINE_WEIGHT_ADJ \n[#EN_STRING_UNDERLINE_WEIGHT]/2 +.nr #EN_TITLE_UNDERLINE_WEIGHT_ADJ \n[#EN_TITLE_UNDERLINE_WEIGHT]/2 +.nr #FN_RULE_WEIGHT_ADJ \n[#FN_RULE_WEIGHT]/2 +.nr #FOOTER_RULE_WEIGHT_ADJ \n[#FOOTER_RULE_WEIGHT]/2 +.nr #HEADER_RULE_WEIGHT_ADJ \n[#HEADER_RULE_WEIGHT]/2 +.nr #RULE_WEIGHT_ADJ \n[#RULE_WEIGHT]/2 +.nr #TOC_HEADER_UNDERLINE_WEIGHT_ADJ \n[#TOC_HEADER_UNDERLINE_WEIGHT]/2 +.nr #UNDERSCORE_WEIGHT_ADJ \n[#UNDERSCORE_WEIGHT]/2 +\# +\# Read in remaining aliases and default rule weights +\# +.nr #LOOP 0 1 +.while \n+[#LOOP]<=14 \{\ +. ALIAS \*[TITLE_TYPE_\n[#LOOP]]_UNDERLINE_WEIGHT RULE_WEIGHT +. ALIAS COVER_\*[TITLE_TYPE_\n[#LOOP]]_UNDERLINE_WEIGHT RULE_WEIGHT +. ALIAS DOC_COVER_\*[TITLE_TYPE_\n[#LOOP]]_UNDERLINE_WEIGHT RULE_WEIGHT +. nr #\*[TITLE_TYPE_\n[#LOOP]]_UNDERLINE_WEIGHT 500 +. nr #COVER_\*[TITLE_TYPE_\n[#LOOP]]_UNDERLINE_WEIGHT 500 +. nr #DOC_COVER_\*[TITLE_TYPE_\n[#LOOP]]_UNDERLINE_WEIGHT 500 +. nr #\*[TITLE_TYPE_\n[#LOOP]]_UNDERLINE_WEIGHT_ADJ \ + \n[#\*[TITLE_TYPE_\n[#LOOP]]_UNDERLINE_WEIGHT]/2 +. nr #COVER_\*[TITLE_TYPE_\n[#LOOP]]_UNDERLINE_WEIGHT_ADJ \ + \n[#COVER_\*[TITLE_TYPE_\n[#LOOP]]_UNDERLINE_WEIGHT]/2 +. nr #DOC_COVER_\*[TITLE_TYPE_\n[#LOOP]]_UNDERLINE_WEIGHT_ADJ \ + \n[#DOC_COVER_\*[TITLE_TYPE_\n[#LOOP]]_UNDERLINE_WEIGHT]/2 +.\} +\# +\# Set default rule weight +\# +.di NULL +\D't 500' +.di +\# +\# ===================================================================== +\# +\# +++WORD AND SENTENCE SPACING+++ +\# +\# WORD SPACE CONTROL +\# ------------------ +\# *Argument: +\# <+|->wordspace | DEFAULT +\# *Function: +\# Increases or decreases interword space by user supplied amount. +\# If DEFAULT, value is set to 12 (groff default). +\# *Notes: +\# $WS_CONSTANT is the groff default word space. +\# $WS_VAR is the user supplied amount by which to in/decrease word space. +\# $WS is a concatenation of WS_CONSTANT and WS_VAR. +\# +\# \n[.sss] holds the current sentence space value. +\# +.MAC WS END +. ds $WS_CURR \\n[.ss] +. ds $WS_VAR \\$1 +. ie '\\$1'DEFAULT' .ss 12 \\n[.sss] +. el \{\ +. ds $WS (\\*[$WS_CURR]+\\*[$WS_VAR]) +. ie \\n[.sss]=12 .ss \\*[$WS] 12 +. el \{\ +. ss \\*[$WS] (\\*[$WS]+\\*[$SS_VAR]) +. SS \\*[$SS_VAR] +. \} +. \} +.END +\# +\# SENTENCE SPACE CONTROL +\# ---------------------- +\# *Argument: +\# <+-sentencespace> | 0 | DEFAULT +\# *Function: +\# Increases or decreases sentence space by user supplied amount. +\# If 0, sentence spaces are ignored. If DEFAULT, value is +\# set to 12 (groff default). +\# *Notes: +\# Because the user supplied value requires a literal + or - sign, +\# the macro argument is stored in a string. +\# +\# Sentence space applies only to input where sentences are separated +\# by two spaces (and/or, in fill mode [FLUSH L|R|C or JUSTIFY], an EOL). +\# Changing .SS when sentences are separated by only one space has +\# no effect on the space between sentences. +\# +\# \n[.ss] holds the current wordspace value. +\# \n[.sss] holds the current sentence space value. +\# +.MAC SS END +. ds $SS_VAR \\$1 +. ie '\\$1'0' .ss \\n[.ss] 0 +. el \{\ +. ie '\\$1'DEFAULT' .ss \\n[.ss] +. el .ss \\n[.ss] \\*[$SS_VAR] +. \} +.END +\# +\# ===================================================================== +\# +\# INDENTS +\# ------- +\# +\# +++INDENT LEFT+++ +\# +.MAC IL END +. if \\n[#INDENT_STYLE_BOTH] .IBX +. nr #INDENT_STYLE_LEFT 1 +. nr #INDENT_ACTIVE 1 +. nr #INDENT_LEFT_ACTIVE 1 +. ie '\\$1'' \{\ +. br +. in \\n[#L_INDENT]u +. ta \\n[.l]u-\\n[#L_INDENT]u +. if \\n[#IN_ITEM] .nr #IN_ITEM_L_INDENT 0 +. \} +. el \{\ +. br +. nr #L_INDENT +(u;\\$1) +. in \\n[#L_INDENT]u +. ta \\n[.l]u-\\n[#L_INDENT]u +. if \\n[#IN_ITEM] .nr #IN_ITEM_L_INDENT +(u;\\$1) +. \} +.END +\# +\# +++INDENT RIGHT+++ +\# +.MAC IR END +. if \\n[#INDENT_STYLE_BOTH] .IBX +. nr #INDENT_STYLE_RIGHT 1 +. nr #INDENT_ACTIVE 1 +. nr #INDENT_RIGHT_ACTIVE 1 +. ie '\\$1'' \{\ +. br +. ie \\n[#TAB_ACTIVE] \{\ +. ll \\n[.l]u-\\n[#R_INDENT]u +. ta \\n[.l]u-\\n[#L_INDENT]u +. \} +. el \{\ +. ll \\n[.l]u-\\n[#R_INDENT]u +. ta \\n[.l]u-\\n[#L_INDENT]u +. \} +. \} +. el \{\ +. br +. nr #R_INDENT (u;\\$1) +. ie \\n[#TAB_ACTIVE] \{\ +. ll \\n[.l]u-\\n[#R_INDENT]u +. ta \\n[.l]u-\\n[#L_INDENT]u +. \} +. el \{\ +. ll \\n[.l]u-\\n[#R_INDENT]u +. ta \\n[.l]u-\\n[#L_INDENT]u +. \} +. \} +.END +\# +\# +++INDENT BOTH+++ +\# +.MAC IB END +. br +. if \\n[#INDENT_STYLE_LEFT] .ILX +. if \\n[#INDENT_STYLE_RIGHT] .IRX +. nr #INDENT_STYLE_BOTH 1 +. nr #INDENT_ACTIVE 1 +. nr #INDENT_BOTH_ACTIVE 1 +. ie '\\$1'' \{\ +. ie \\n[#DOCS] \ +. ll \\n[#DOC_L_LENGTH]u-\\n[#BR_INDENT]u +. el .ll \\n[.l]u-\\n[#BR_INDENT]u +. in \\n[#BL_INDENT]u +. ta \\n[.l]u +. \} +. el \{\ +. nr #BL_INDENT (\\n[#INDENT]+\\$1) +. ie \\n[#NUM_ARGS]=2 .nr #BR_INDENT +(\\$2) +. el .nr #BR_INDENT \\n[#BL_INDENT] +. if '\\n[.z]'' .ll +. ll \\n[.l]u-\\n[#BR_INDENT]u +. in \\n[#BL_INDENT]u +. ta \\n[.l]u-\\n[#BR_INDENT]u +. \} +.END +\# +\# +++TEMPORARY INDENT+++ +\# +.MAC TI END +. br +. ie '\\$1'' \{\ +. ti \\n[#T_INDENT]u +. if \\n[#INDENT_LEFT_ACTIVE] .ti \\n[#T_INDENT]u+\\n[#L_INDENT]u +. if \\n[#INDENT_BOTH_ACTIVE] .ti \\n[#T_INDENT]u+\\n[#BL_INDENT]u +. \} +. el \{\ +. nr #T_INDENT (\\$1) +. ti \\n[#T_INDENT]u +. \} +.END +\# +\# +++HANGING INDENT+++ +\# +.MAC HI END +. ie '\\$1'' .ti -\\n[#HL_INDENT]u +. el \{\ +. nr #HL_INDENT (\\$1) +. ti -\\n[#HL_INDENT]u +. \} +.END +\# +\# +++INDENTS OFF+++ +\# +.MAC ILX END +. ie \\n[#IN_ITEM] .nr #L_INDENT -\\n[#IN_ITEM_L_INDENT] +. el \{\ +. br +. ie \\n[pdfbx-running]=1 \ +. ie !r pdfbx-clear \{\ +. in \\*[wt\\n[stack]]+\\*[gap\\n[stack]]u+\\n[#IL_ACTIVE]u +. el .in \\*[wt\\n[stack]]+\\*[gap\\n[stack]]u +. \} +. el .in 0 +. rr #INDENT_LEFT_ACTIVE +. nr #L_INDENT_ILX \\n[#L_INDENT] +. \} +. if '\\$1'CLEAR' \{\ +. if \\n[pdfbx-running]=1 \ +. if !r pdfbx-clear \ +. in \\*[wt\\n[stack]]+\\*[gap\\n[stack]]u +. rr #L_INDENT +. rr #INDENT_STYLE_LEFT +. rr #L_INDENT_ILX +. rr #INDENT_ACTIVE +. \} +.END +\# +.MAC IRX END +. br +. rr #INDENT_RIGHT_ACTIVE +. ie \\n[#TAB_ACTIVE] .TAB\\n[#CURRENT_TAB] +. el \{\ +. ie \\n[#COLUMNS] \{\ +. ll \\n[#COL_L_LENGTH]u +. ta \\n[.l]u +. \} +. el \{\ +. ie \\n[pdfbx-running]=1 \{\ +. if !r pdfbx-clear \ +. ll \\n[pdfbx-ll]u +. \} +. el .ll \\n[#DOC_L_LENGTH]u +. ta \\n[.l]u +. \} +. \} +. if '\\$1'CLEAR' \{\ +. if \\n[pdfbx-running]=1 \{\ +. if !r pdfbx-clear \ +. ll \\n[#L_LENGTH]u-(\\*[wt\\n[stack]]+\\*[gap\\n[stack]]u) +. \} +. rr #R_INDENT +. rr #INDENT_STYLE_RIGHT +. \} +.END +\# +.MAC IBX END +. br +. in 0 +. rr #INDENT_ACTIVE +. rr #INDENT_BOTH_ACTIVE +. ie \\n[#TAB_ACTIVE] .TAB\\n[#CURRENT_TAB] +. el \{\ +. ie \\n[#COLUMNS] \{\ +. ll \\n[#COL_L_LENGTH]u +. ta \\n[.l]u +. \} +. el \{\ +. ll \\n[#L_LENGTH]u +. ta \\n[.l]u +. \} +. \} +. if '\\$1'CLEAR' \{\ +. rr #BL_INDENT +. rr #BR_INDENT +. rr #INDENT_STYLE_BOTH +. \} +.END +\# +.MAC IX END +. if '\\$0'IX' \{\ +. if !\\n[#IX_WARN] \{\ +. tm1 "[mom]: Use of .IX is deprecated. Use .IQ instead. +. tm1 " .IX will continue to behave as before, but to +. tm1 " avoid this message, please update your document. +. nr #IX_WARN 1 +. \} +. \} +. br +. in 0 +. rr #INDENT_LEFT_ACTIVE +. rr #INDENT_RIGHT_ACTIVE +. rr #INDENT_BOTH_ACTIVE +. rr #INDENT_ACTIVE +. if \\n[#INDENT_STYLE_RIGHT] \{\ +. ie \\n[#TAB_ACTIVE] .TAB\\n[#CURRENT_TAB] +. el \{\ +. ie \\n[#COLUMNS] \{\ +. ll \\n[#COL_L_LENGTH]u +. ta \\n[.l]u +. \} +. el \{\ +. ll \\n[#L_LENGTH]u +. ta \\n[.l]u +. \} +. \} +. \} +. if \\n[#INDENT_STYLE_BOTH] \{\ +. ie \\n[#TAB_ACTIVE] .TAB\\n[#CURRENT_TAB] +. el \{\ +. ie \\n[#COLUMNS] \{\ +. ll \\n[#COL_L_LENGTH]u +. ta \\n[.l]u +. \} +. el \{\ +. ll \\n[#L_LENGTH]u +. ta \\n[.l]u +. \} +. \} +. \} +. if '\\$1'CLEAR' \{\ +. if \\n[#INDENT_STYLE_RIGHT] \{\ +. ie \\n[#TAB_ACTIVE] .TAB\\n[#CURRENT_TAB] +. el \{\ +. ie \\n[#COLUMNS] \{\ +. ll \\n[#COL_L_LENGTH]u +. ta \\n[.l]u +. \} +. el \{\ +. ll \\n[#L_LENGTH]u +. ta \\n[.l]u +. \} +. \} +. \} +. if \\n[#INDENT_STYLE_BOTH] \{\ +. ie \\n[#TAB_ACTIVE] .TAB\\n[#CURRENT_TAB] +. el \{\ +. ie \\n[#COLUMNS] \{\ +. ll \\n[#COL_L_LENGTH]u +. ta \\n[.l]u +. \} +. el \{\ +. ll \\n[#L_LENGTH]u +. ta \\n[.l]u +. \} +. \} +. \} +. rr #L_INDENT +. rr #R_INDENT +. rr #BL_INDENT +. rr #BR_INDENT +. rr #T_INDENT +. rr #H_INDENT +. rr #INDENT_STYLE_LEFT +. rr #INDENT_STYLE_RIGHT +. rr #INDENT_STYLE_BOTH +. \} +.END +\# +\# ===================================================================== +\# +\# +++HANGING CHARACTERS+++ +\# +\# LEFT_HANG hangs its argument to the left of the left margin. +\# If enclosed in double-quotes, the argument may contain local +\# horizontal motions. Input text after LEFT_HANG must begin +\# by repeating the text of the argument including horizontal +\# motions. If the hung character is a left double-quote, +\# \[lq] must be used in the argument and the usual keyboard +\# double-quote (") used for the input text (so as not to confuse +\# SMARTQUOTES). +\# +\# HANG is called inline with \*[HANG ]. Hangs its +\# single-character argument, typically a punctuation mark, to the +\# right of the right margin in justified copy. Unlike LEFT_HANG, +\# does not require repeating the character as part of input text. +\# +\# Except for hung hyphens, HANG may be used mid-line in input +\# text. Hung hyphens must come at the end of input lines. If +\# the hung character is a right double-quote, "\[rq]" must be +\# used as the argument (that is, the rq character surrounded by +\# double-quotes). The double-quotes are required for all special +\# characters that have the form \[c]. +\# +.MAC LEFT_HANG END +. nr hang-char-width \w'\\$1' +. ds hang-char-gutter \\$2 +. ie '\\*[hang-char-gutter]'' \ +. nr hang-char \\n[hang-char-width] +. el \ +. nr hang-char \\n[hang-char-width]+\\*[hang-char-gutter] +\h'-\\n[hang-char]u'\c +.END +\# +.MAC HANG END +\c +.if '\\$1'\[rq]' .nr #OPEN_CLOSE 0 +\c +\&\\$1\c +\h'-\w'\\$1'u'\c +.END +\# +\# ===================================================================== +\# +\# +++MULTIPLE COLUMNS+++ +\# +\# MULTIPLE COLUMNS ON +\# ------------------- +\# *Arguments: +\# +\# *Function: +\# Marks the top of a column set +\# +.MAC MCO END +. mk c +.END +\# +\# MULTIPLE COLUMN RETURN +\# ---------------------- +\# *Arguments: +\# +\# *Function: +\# Returns to the top of a column set +\# +.MAC MCR END +. vpt 0 +. sp |\\n[c]u +. vpt +.END +\# +\# MULTIPLE COLUMNS OFF +\# -------------------- +\# *Arguments: +\# | +\# *Function: +\# Advances to the end of a column set +\# *Notes: +\# With no argument, advances to the next baseline (at the current +\# leading value) beneath the longest column. With an argument +\# (which requires a unit of measure), advances arg distance +\# beneath the baseline of the deepest column. If the argument +\# is zero, advances to the baseline of the deepest column. +\# +.MAC MCX END +. vpt 0 +. ie '\\$1'' \{\ +. if '\\n[.z]'FLOAT*DIV' \!.TQ +. TQ +. sp |\\n[.h]u +. \} +. el \{\ +. nr #MCX_ALD (\\$1) +. TQ +. ie \\n[#MCX_ALD]=0 .sp |\\n[.h]u-1v +. el .sp |\\n[.h]u+\\n[#MCX_ALD]u +. rr #MCX_ALD +. \} +. vpt +.END +\# +\# ===================================================================== +\# +\# +++TYPESETTING SUPPORT MACROS+++ +\# +\# TRAP +\# ---- +\# *Arguments: +\# toggle +\# *Function: +\# Enables/disables traps. +\# *Notes: +\# EL and TN don't function as advertised on the last line before +\# a trap (when they break the preceding line, they spring the +\# trap, and groff won't back up to the line preceding the trap). +\# TRAP is a kludge to get EL and TN work properly on last lines. +\# The user simply encloses the offending lines in TRAP OFF/TRAP. +\# +.MAC TRAP END +. ie '\\$1'' .vpt +. el .vpt 0 +.END +\# +\# SILENT +\# ------ +\# *Arguments: +\# | +\# *Function: +\# Diverts text so that it doesn't print, or turns the function off. +\# *Notes: +\# Useful for setting up autotabs where you don't want the line with +\# the tab marks to print. +\# +\# Also aliased as COMMENT, in case user wants to input a batch of +\# text that doesn't print. +\# +.MAC SILENT END +. nr #SILENT 1 +. if \\n[#QUAD] .br +. ie '\\$1'' .di NO_FLASH +. el \{\ +. br +. di +. rm NO_FLASH +. rr #SILENT +. \} +.END +\# +\# PRINT +\# ----- +\# *Function: +\# Prints anything. A macro that helps keep my code nicely indented. +\# +.MAC PRINT END +. nop \\$* +.END +\# +\# Numbered strings for while loop in SMALLCAPS. +\# +.ds $c1 a +.ds $c2 b +.ds $c3 c +.ds $c4 d +.ds $c5 e +.ds $c6 f +.ds $c7 g +.ds $c8 h +.ds $c9 i +.ds $c10 j +.ds $c11 k +.ds $c12 l +.ds $c13 m +.ds $c14 n +.ds $c15 o +.ds $c16 p +.ds $c17 q +.ds $c18 r +.ds $c19 s +.ds $c20 t +.ds $c21 u +.ds $c22 v +.ds $c23 w +.ds $c24 x +.ds $c25 y +.ds $c26 z +.ds $c27 \[`a] +.ds $c28 \[^a] +.ds $c29 \['a] +.ds $c30 \[:a] +.ds $c31 \[oa] +.ds $c32 \[~a] +.ds $c33 \[ae] +.ds $c34 \[`e] +.ds $c35 \[^e] +.ds $c36 \['e] +.ds $c37 \[:e] +.ds $c38 \[`i] +.ds $c39 \[^i] +.ds $c40 \['i] +.ds $c41 \[:i] +.ds $c42 \[`o] +.ds $c43 \[^o] +.ds $c44 \['o] +.ds $c45 \[:o] +.ds $c46 \[~o] +.ds $c47 \[/o] +.ds $c48 \[`u] +.ds $c49 \[^u] +.ds $c50 \['u] +.ds $c51 \[:u] +.ds $c52 \[,c] +.ds $c53 \[Sd] +.ds $c54 \[~n] +.ds $c55 \[Sd] +.ds $c56 \[Tp] +.ds $c57 \['y] +.ds $c58 \[:y] +\# +.ds $C1 A +.ds $C2 B +.ds $C3 C +.ds $C4 D +.ds $C5 E +.ds $C6 F +.ds $C7 G +.ds $C8 H +.ds $C9 I +.ds $C10 J +.ds $C11 K +.ds $C12 L +.ds $C13 M +.ds $C14 N +.ds $C15 O +.ds $C16 P +.ds $C17 Q +.ds $C18 R +.ds $C19 S +.ds $C20 T +.ds $C21 U +.ds $C22 V +.ds $C23 W +.ds $C24 X +.ds $C25 Y +.ds $C26 Z +.ds $C27 \[`A] +.ds $C28 \[^A] +.ds $C29 \['A] +.ds $C30 \[:A] +.ds $C31 \[oA] +.ds $C32 \[~A] +.ds $C33 \[AE] +.ds $C34 \[`E] +.ds $C35 \[^E] +.ds $C36 \['E] +.ds $C37 \[:E] +.ds $C38 \[`I] +.ds $C39 \[^I] +.ds $C40 \['I] +.ds $C41 \[:I] +.ds $C42 \[`O] +.ds $C43 \[^O] +.ds $C44 \['O] +.ds $C45 \[:O] +.ds $C46 \[~O] +.ds $C47 \[/O] +.ds $C48 \[`U] +.ds $C49 \[^U] +.ds $C50 \['U] +.ds $C51 \[:U] +.ds $C52 \[,C] +.ds $C53 \[-D] +.ds $C54 \[~N] +.ds $C55 \[-D] +.ds $C56 \[TP] +.ds $C57 \['Y] +.ds $C58 \[:Y] +\# +\# CAPS +\# ---- +\# *Arguments: +\# | +\# *Function: +\# Converts text to caps, or, if OFF, reverts to normal caps/lc. +\# *Notes: +\# For inline control of capitalization style, use \*[UC] and +\# \*[LC]. +\# +.MAC CAPS END +. ie '\\$1'' \{\ +. LC_TO_CAPS +. nr #CAPS_ON 1 +. \} +. el \{\ +. CAPS_TO_LC +. rr #CAPS_ON +. \} +.END +\# +.MAC UC END +\c +. LC_TO_CAPS +. nr #CAPS_ON 1 +.END +\# +.MAC LC END +\c +. CAPS_TO_LC +. rr #CAPS_ON +.END +\# +\# Perform lowercase conversion to caps or revert to lowercase +\# +.MAC CONVERT_CASE END +. if '\\$0'LC_TO_CAPS' \{\ +. nr #LOOP 0 1 +. while \\n+[#LOOP]<=58 \{\ +. tr \\*[$c\\n[#LOOP]]\\*[$C\\n[#LOOP]] +. \} +. \} +. if '\\$0'CAPS_TO_LC' \{\ +. nr #LOOP 0 1 +. while \\n+[#LOOP]<=58 \{\ +. tr \\*[$c\\n[#LOOP]]\\*[$c\\n[#LOOP]] +. \} +. \} +.END +. +.ALIAS LC_TO_CAPS CONVERT_CASE +.ALIAS CAPS_TO_LC CONVERT_CASE +. +\# +\# SMALLCAPS +\# --------- +\# *Arguments: +\# | +\# *Function: +\# Converts text to smallcaps, or, if , reverts to normal +\# caps/lc. +\# *Notes: +\# SMALLCAPS has no inline escape eqiv. to \*[UC]. +\# +.MAC SMALLCAPS END +. if \\n[#PRINT_STYLE]=2 \{\ +. if !\\n[.u] \ +. if \\n[.int] .nop \& \c +. nr sc*size \\n[.ps]*\\n[sc*factor]/1000 +. if \\n[sc*wt-adj] .nr sc*wt-adj-factor \\n[sc*size]*\\n[sc*wt-adj]/1000 +. if \\n[sc*extend] .nr sc*extend-factor \\n[sc*size]*\\n[sc*extend]/1000 +. ie '\\$1'' \{\ +. nr #SMALLCAPS_ON 1 +. nr #LOOP 0 1 +. while \\n+[#LOOP]<=58 \{\ +. char \\*[$c\\n[#LOOP]] \ +\Z'\s[\\n[sc*size]u+\\n[sc*extend-factor]u]\H'-\\n[sc*extend-factor]u'\ +\\*[$C\\n[#LOOP]]'\ +\h'\\n[sc*wt-adj-factor]u'\\*[$C\\n[#LOOP]]\s[0] +. \} +. \} +. el \{\ +. nr #LOOP 0 1 +. while \\n+[#LOOP]<=58 \{\ +. rchar \\*[$c\\n[#LOOP]] +. \} +. rr sc*wt-adj-factor +. rr sc*extend-factor +. rr #SMALLCAPS_ON +. \} +. \} +.END +\# +\# SMALLCAPS_SIZE +\# -------------- +\# *Arguments: +\# [ +\# *Function: +\# Sets registers 'sc*factor', 'sc*wt-adj', and sc*extend. +\# *Notes: +\# Weight adjustment pseudo-emboldens small caps to visually match the +\# weight of the larger real caps. +\# +\# Both sc*factor (size) and sc*wt-adj (weight adjustment) args are +\# expressed as percentages of type size. +\# +.MAC SMALLCAPS_STYLE END +. nr #LOOP 0 1 +. while \\n+[#LOOP]<=\\n[#NUM_ARGS] \{\ +. if '\\$1'SIZE' \{\ +. shift +. nr sc*factor (z;\\$1)/100 +. shift +. \} +. if '\\$1'WEIGHT_ADJ' \{\ +. shift +. nr sc*wt-adj (z;\\$1)/100 +. shift +. \} +. if '\\$1'EXTEND' \{\ +. shift +. nr sc*extend (z;\\$1)/100 +. shift +. \} +. \} +. if \\n[sc*wt-adj]=0 .rr sc*wt-adj +. if \\n[sc*extend]=0 .rr sc*extend +.END +. +.SMALLCAPS_STYLE \ +SIZE 74 \ +WEIGHT_ADJ .3 \ +EXTEND 5 +\# +\# SIZESPECS +\# --------- +\# Argument: +\# +\# Function: +\# Gets cap-height, x-height, and descender depth of the +\# current font at the current point size. +\# *Notes: +\# The routine is diverted so it remains invisible to output. +\# +.MAC SIZESPECS END +. if !'\\n[.z]'' \ +. if \\n[dn] .nr saved-dn \\n[dn] +. di TYPESIZE +E\R'#CAP_HEIGHT \\n[.cht]' +e\R'#X_HEIGHT \\n[.cht]' +y\R'#DESCENDER \\n[.cdp]' +. br +. ds $CAP_HEIGHT \\n[#CAP_HEIGHT]u +. ds $X_HEIGHT \\n[#X_HEIGHT]u +. ds $DESCENDER \\n[#DESCENDER]u +. di +. if !'\\n[.z]'' \ +. nr dn \\n[saved-dn] +.END +\# +\# ===================================================================== +\# +\# +++TYPESETTING ALIASES+++ +\# +.ALIAS ADD_SPACE ALD +.ALIAS CENTRE CENTER +.ALIAS COLOUR COLOR +.ALIAS COMMENT SILENT +.ALIAS CONDENSE CONDENSE_OR_EXTEND +.ALIAS EXTEND CONDENSE_OR_EXTEND +.ALIAS FAM FAMILY +.ALIAS FONT FT +.ALIAS HYPHENATE HY +.ALIAS HYPHENATION HY +.ALIAS HYSET HY_SET +.ALIAS IBQ IBX +.ALIAS ILQ ILX +.ALIAS IQ IX +.ALIAS IRQ IRX +.ALIAS LIG LIGATURES +.ALIAS NEWCOLOUR NEWCOLOR +.ALIAS PADMARKER PAD_MARKER +.ALIAS SP ALD +.ALIAS SPACE ALD +.ALIAS TABSET TAB_SET +.ALIAS TB TAB +.ALIAS UNDERSCORE_2 UNDERSCORE2 +.ALIAS XCOLOUR XCOLOR +\# +\# ==================================================================== +\# +\# DOCUMENT PROCESSING MACROS, STRINGS AND ALIASES +\# =============================================== +\# +\# DOC_MACRO_ERROR +\# --------------- +\# *Arguments: +\# None. +\# *Function: +\# Warning message if DOC_ called before START. +\# +.MAC DOC_MACRO_ERROR END +. if '\\$1'DOC_L_MARGIN' .ds $REPLACEMENT L_MARGIN +. if '\\$1'DOC_R_MARGIN' .ds $REPLACEMENT R_MARGIN +. if '\\$1'DOC_LINE_LENGTH' .ds $REPLACEMENT LL +. if '\\$1'DOC_FAMILY' .ds $REPLACEMENT "FAMILY or FAM +. if '\\$1'DOC_PT_SIZE' .ds $REPLACEMENT PT_SIZE +. if '\\$1'DOC_LEAD' .ds $REPLACEMENT LS +. if '\\$1'DOC_QUAD' .ds $REPLACEMENT QUAD +. tm1 "[mom]: \\$1 at line \\n[.c] of '\\n[.F]' should not be used before START. +. tm1 " Use \\*[$REPLACEMENT] instead. +. ab [mom]: Aborting. +.END +\# +\# +++PAGE DIMENSIONS+++ +\# +\# PAPER SIZE +\# ---------- +\# *Arguments: +\# LETTER | LEGAL | STATEMENT | TABLOID | LEDGER | FOLIO | QUARTO | 10x14 | EXECUTIVE | A3 | A4 | A5 | B4 | B5 +\# *Function: +\# Sets up dimensions for different paper sizes. +\# *Notes: +\# LANDSCAPE may be given after papersize arg. +\# +.MAC PAPER END +. vs 0 +. ds $PAPER \\$1 +. if '\\*[$PAPER]'LETTER' \{\ +. PAGEWIDTH 8.5i +. PAGELENGTH 11i +. \} +. if '\\*[$PAPER]'LEGAL' \{\ +. PAGEWIDTH 8.5i +. PAGELENGTH 14i +. \} +. if '\\*[$PAPER]'STATEMENT' \{\ +. PAGEWIDTH 5.5i +. PAGELENGTH 8.5i +. \} +. if '\\*[$PAPER]'TABLOID' \{\ +. PAGEWIDTH 11i +. PAGELENGTH 17i +. \} +. if '\\*[$PAPER]'LEDGER' \{\ +. PAGEWIDTH 17i +. PAGELENGTH 11i +. \} +. if '\\*[$PAPER]'FOLIO' \{\ +. PAGEWIDTH 8.5i +. PAGELENGTH 13i +. \} +. if '\\*[$PAPER]'QUARTO' \{\ +. PAGEWIDTH 610p +. PAGELENGTH 780p +. \} +. if '\\*[$PAPER]'10x14' \{\ +. PAGEWIDTH 10i +. PAGELENGTH 14i +. \} +. if '\\*[$PAPER]'EXECUTIVE' \{\ +. PAGEWIDTH 7.25i +. PAGELENGTH 10.5i +. \} +. if '\\*[$PAPER]'A3' \{\ +. PAGEWIDTH 842p +. PAGELENGTH 1190p +. \} +. if '\\*[$PAPER]'A4' \{\ +. PAGEWIDTH 595p +. PAGELENGTH 842p +. \} +. if '\\*[$PAPER]'A5' \{\ +. PAGEWIDTH 421p +. PAGELENGTH 595p +. \} +. if '\\*[$PAPER]'B4' \{\ +. PAGEWIDTH 709p +. PAGELENGTH 1002p +. \} +. if '\\*[$PAPER]'B5' \{\ +. PAGEWIDTH 501p +. PAGELENGTH 709p +. \} +. if '\\$2'LANDSCAPE' \{\ +. nr #PAGE_WIDTH_TMP \\n[#PAGE_WIDTH] +. PAGEWIDTH \\n[#PAGE_LENGTH]u +. PAGELENGTH \\n[#PAGE_WIDTH_TMP]u +. as $PAPER " LANDSCAPE\" +. \} +. if !r#L_MARGIN .L_MARGIN \\n[.o] +. if !r#R_MARGIN .R_MARGIN \\n[#PAGE_WIDTH]u-\\n[#L_MARGIN]u-1i +. if '\\*[.T]'pdf' .br +. vs +.END +\# +\# ==================================================================== +\# +\# +++PRINTSTYLE -- TYPEWRITE OR TYPESET+++ +\# +\# PRINTSTYLE +\# ---------- +\# *Arguments: +\# TYPESET | TYPEWRITE [SINGLESPACE] +\# *Function: +\# Sets type specs for typewriter-style or typeset output. +\# *Notes: +\# Number registers: TYPEWRITE=1, TYPESET=2. +\# +.MAC PRINTSTYLE END +. if n \{\ +. if '\\$1'TYPESET' \{\ +. pl 1 +. ab [mom]: Terminal output requires PRINTSTYLE TYPEWRITE. Aborting. +. \} +. \} +. if !\\n[#COLLATE]=1 \{\ +. if !d$PAPER \{\ +. PAGELENGTH 11i +. PAGEWIDTH 8.5i +. \} +. if '\\$1'TYPEWRITE' \{\ +. nr #PRINT_STYLE 1 +. if !\\n[#DOC_TYPE]=4 \{\ +. L_MARGIN 6P +. R_MARGIN 6P +. \} +. ds $TYPEWRITER_FAM C +. ds $TYPEWRITER_PS 12 +. TYPEWRITER +. color 0 +. ie '\\$2'SINGLESPACE' \{\ +. nr #SINGLE_SPACE 1 +. vs 12 +. ie \\n[#DOC_TYPE]=4 .nr #FOOTER_ADJ \\n[.v] +. el .nr #FOOTER_ADJ \\n[.v] +. nr #ORIGINAL_DOC_LEAD \\n[.v] +. \} +. el \{\ +. if !\\n[#DOC_TYPE]=4 \{\ +. vs 24 +. nr #FOOTER_ADJ \\n[.v]/2 +. nr #ORIGINAL_DOC_LEAD \\n[.v] +. \} +. \} +. QUAD L +. HY OFF +. SMARTQUOTES OFF +. if !\\n[#PP_INDENT] .nr #PP_INDENT 3P +. HDRFTR_RIGHT_CAPS +. nr #BOLDER_UNITS 0 +. nr #CONDENSE 0 +. nr #EXTEND 0 +. if !\\n[#ITALIC_MEANS_ITALIC] \{\ +. rm IT +. rm PREV +. UNDERLINE_ITALIC +. \} +. rm BD +. rm BDI +. if !\\n[#SLANT_MEANS_SLANT] .UNDERLINE_SLANT +. if !\\n[#UNDERLINE_QUOTES] .UNDERLINE_QUOTES +. nr #IGNORE_COLUMNS 1 +. nr #RULE_WEIGHT 500 +. char \[em] -- +. tr `' +. tr \[lq]" +. tr \[rq]" +. \} +. if '\\$1'TYPESET' \{\ +. nr #PRINT_STYLE 2 +. if !\\n[#DOC_TYPE]=5 \{\ +. if !\\n[#DOC_TYPE]=4 \{\ +. L_MARGIN 6P +. R_MARGIN 6P +. \} +. \} +. FAMILY T +. FT R +. if !\\n[#DOC_TYPE]=4 .ps 12.5 +. if !\\n[#DOC_TYPE]=4 .vs 16 +.\" In DEFAULTS, TRAPS is run with this leading, so we need a register to +.\" hold it for use with the .sp in FOOTER +. nr #FOOTER_ADJ 12000 +. JUSTIFY +. HY +. HY_SET 2 36p 1p +. KERN +. LIG +. SS 0 +. SMARTQUOTES +. if !\\n[#PP_INDENT] \{\ +. in 2m \"Set indent +. nr #PP_INDENT \\n[.i] \"Read into #PP_INDENT +. in 0 \"Remove indent +. \} +. HDRFTR_RIGHT_CAPS +. rr #IGNORE_COLUMNS +. \} +.\" Set up default style for nine levels of headings +. nr #HD_LEVEL 0 1 \" loop step +. nr #LOOP 9 \" loop count +. while \\n+[#HD_LEVEL]<=\\n[#LOOP] \{\ +. HEADING_STYLE \\n[#HD_LEVEL] \ + FONT B \ + SIZE +0 \ + QUAD L \ + NEEDS 1 \ + COLOR black +.\" Set up default style for nine levels of TOC headings +. TOC_ENTRY_STYLE \\n[#HD_LEVEL] \ + FONT R \ + SIZE +0 \ + COLOR black +. \} +.\" Set up decreasing sizes for headings levels 1 - 3, starting at +3 +. nr #HD_LEVEL 0 1 \" loop step +. nr #LOOP 3 \" loop count +. nr #HD_SIZE 4 1 +. while \\n+[#HD_LEVEL]<=\\n[#LOOP] \{\ +. nr #HD_SIZE_CHANGE \\n-[#HD_SIZE] +. ds $HEAD_\\n[#HD_LEVEL]_SIZE +\\n[#HD_SIZE_CHANGE] +. \} +.\" Set up TOC title style +. TOC_TITLE_STYLE FONT R SIZE +0 INDENT 0 +.\" Set up captions, labels, sources +. LABELS ALL FONT B AUTOLEAD 2 +. LABELS EQN FONT R QUAD RIGHT +. CAPTIONS ALL AUTOLEAD 2 +. CAPTIONS EQN QUAD CENTER +. SOURCES TBL AUTOLEAD 2 +. \} +.END +\# +\# Set limited parameters to TYPEWRITE. +\# +.MAC TYPEWRITER_FAMILY END +. ds $TYPEWRITER_FAM \\$1 +.END +\# +.ALIAS TYPEWRITER_FAM TYPEWRITER_FAMILY +\# +.MAC TYPEWRITER_SIZE END +. ds $TYPEWRITER_PS \\$1 +.END +\# +.MAC TYPEWRITER END +. fam \\*[$TYPEWRITER_FAM] +. ft R +. ps \\*[$TYPEWRITER_PS] +.END +\# +\# ITALIC MEANS ITALIC +\# ------------------- +\# *Argument: +\# +\# *Function: +\# Instructs TYPEWRITE to treat italics as italics, whether +\# invoked via control lines or inline. +\# *Notes: +\# ITALIC_MEANS_ITALIC and UNDERLINE_ITALIC are mutually exclusive, +\# hence invoking the one automatically turns off the other. +\# +.MAC ITALIC_MEANS_ITALIC END +. if \\n[#PRINT_STYLE]=1 \{\ +. nr #ITALIC_MEANS_ITALIC 1 +. rr #UNDERLINE_ITALIC +. rm ROM +. rm IT +. rm PREV +. ds ROM \Ef[R] +. ds IT \Ef[I] +. ds PREV \Ef[] +. \} +.END +\# +\# UNDERLINE ITALIC +\# ---------------- +\# *Argument: +\# +\# *Function: +\# Instructs TYPEWRITE to underline italics, whether invoked +\# via control lines or inline. +\# *Notes: +\# UNDERLINE_ITALIC and ITALIC_MEANS_ITALIC are mutually exclusive, +\# hence invoking the one automatically turns off the other. +\# +\# UNDERLINE_ITALIC is the default for TYPEWRITE. +\# +.MAC UNDERLINE_ITALIC END +. if \\n[#PRINT_STYLE]=1 \{\ +. nr #UNDERLINE_ITALIC 1 +. rr #ITALIC_MEANS_ITALIC +. rm ROM +. rm IT +. rm PREV +. ds ROM \E*[ULX] +. ds IT \E*[UL] +. ds PREV \f[P]\E*[ULX] +. \} +.END +\# +\# UNDERLINE SLANT +\# --------------- +\# *Arguments: +\# | +\# *Function: +\# Instructs TYPEWRITE to underline occurrences of \*[SLANT], or +\# turns feature off. +\# *Notes: +\# Users may want \*[SLANT] to mean slant in TYPEWRITE, although +\# most of the time, \*[SLANT] most likely means the user wanted +\# italic but didn't have it, ergo the need to tell TYPEWRITE to +\# treat \*[SLANT] as italic (i.e. underlined). +\# +\# UNDERLINE_SLANT and SLANT_MEANS_SLANT are mutually exclusive, +\# hence invoking the one automatically turns off the other. +\# +\# UNDERLINE_SLANT is the default for TYPEWRITE. +\# +.MAC UNDERLINE_SLANT END +. if \\n[#PRINT_STYLE]=1 \{\ +. rr #SLANT_MEANS_SLANT +. nr #UNDERLINE_SLANT 1 +. rm SLANT +. rm SLANTX +. ds SLANT \ER'#SLANT_ON 1'\E*[UL] +. ds SLANTX \ER'#SLANT_ON 0'\E*[ULX] +. \} +.END +\# +.MAC SLANT_MEANS_SLANT END +. if \\n[#PRINT_STYLE]=1 \{\ +. rr #UNDERLINE_SLANT +. nr #SLANT_MEANS_SLANT 1 +. rm SLANT +. rm SLANTX +. ds SLANT \ER'#SLANT_ON 1'\ES'\En[#DEGREES]' +. ds SLANTX \ER'#SLANT_ON 0'\ES'0' +. \} +.END +\# +.MAC IGNORE_COLUMNS END +. if \\n[#PRINT_STYLE]=1 .nr #NO_COLUMNS 1 +.END +\# +\# ==================================================================== +\# +\# +++COPY STYLE -- DRAFT OR FINAL+++ +\# +\# COPY STYLE +\# ---------- +\# *Arguments: +\# DRAFT | FINAL +\# *Function: +\# Sets registers that are used to determine what to put +\# in the default header, and how to number pages. +\# *Notes: +\# DOCTYPE must come before COPYSTYLE. +\# +.MAC COPYSTYLE END +. ds $COPY_STYLE \\$1 +. if '\\*[$COPY_STYLE]'DRAFT' \{\ +. nr #COPY_STYLE 1 +. if !d$DRAFT .DRAFT 1 +. \} +. if '\\*[$COPY_STYLE]'FINAL' .nr #COPY_STYLE 2 +. if '\\*[$CHAPTER_STRING]'' .CHAPTER_STRING "Chapter" +. if '\\*[$DRAFT_STRING]'' .DRAFT_STRING "Draft" +. if '\\*[$REVISION_STRING]'' .REVISION_STRING "Rev." +.\" Default +. if \\n[#DOC_TYPE]=1 \{\ +. ie \\n[#COPY_STYLE]=1 \{\ +. ie \\n[#PAGENUM_STYLE_SET] .PAGENUM_STYLE \\*[$PAGENUM_STYLE] +. el .PAGENUM_STYLE roman +. if \\n[#USER_DEF_HDRFTR_CENTER]=0 \{\ +. ie \\n[#DRAFT_WITH_PAGENUM] .ds $HDRFTR_CENTER +. el \{\ +. ie '\\*[$REVISION]'' \{\ +. ds $HDRFTR_CENTER \ + \\*[$DRAFT_STRING]\\*[$DRAFT] +. \} +. el \{\ +. ds $HDRFTR_CENTER \ + \\*[$DRAFT_STRING]\\*[$DRAFT], \ + \\*[$REVISION_STRING] \\*[$REVISION] +. \} +. \} +. \} +. \} +. el \{\ +. ie \\n[#PAGENUM_STYLE_SET] .PAGENUM_STYLE \\*[$PAGENUM_STYLE] +. el .PAGENUM_STYLE DIGIT +. if \\n[#DRAFT_WITH_PAGENUM] .rr #DRAFT_WITH_PAGENUM +. if \\n[#USER_DEF_HDRFTR_CENTER]=0 \{\ +. ds $HDRFTR_CENTER +. rr #USER_DEF_HDRFTR_CENTER +. \} +. \} +. \} +.\" Chapter +. if \\n[#DOC_TYPE]=2 \{\ +.\" Copystyle DRAFT +. ie \\n[#COPY_STYLE]=1 \{\ +. ie \\n[#PAGENUM_STYLE_SET] \ +. PAGENUM_STYLE \\*[$PAGENUM_STYLE] +. el \ +. PAGENUM_STYLE roman +. if \\n[#USER_DEF_HDRFTR_CENTER]=0 \{\ +. ie \\n[#DRAFT_WITH_PAGENUM] \{\ +. ie '\\*[$CHAPTER]'' \{\ +. ie !'\\*[$CHAPTER_TITLE_1]'' \ +. ds $HDRFTR_CENTER \\*[$CHAPTER_TITLE] +. el .ds $HDRFTR_CENTER \\*[$CHAPTER_STRING] +. \} +. el \{\ +. ie !'\\*[$CHAPTER_TITLE_1]'' \ +. ds $HDRFTR_CENTER \\*[$CHAPTER_TITLE] +. el .ds $HDRFTR_CENTER \\*[$CHAPTER_STRING] \\*[$CHAPTER] +. \} +. \} +. el \{\ +. ie '\\*[$REVISION]'' \{\ +. ie '\\*[$CHAPTER]'' \{\ +. ie !'\\*[$CHAPTER_TITLE_1]'' \{\ +. ie '\\*[$DRAFT]'' \ +. ds $HDRFTR_CENTER \\*[$CHAPTER_TITLE] +. el \{\ +. ds $HDRFTR_CENTER \ + \\*[$CHAPTER_TITLE], \ + \\*[$DRAFT_STRING]\\*[$DRAFT] +. \} +. \} +. el \{\ +. ie '\\*[$DRAFT]'' \{\ +. ds $HDRFTR_CENTER \ + \\*[$CHAPTER_STRING] +. \} +. el \{\ +. ds $HDRFTR_CENTER \ + \\*[$CHAPTER_STRING], \ + \\*[$DRAFT_STRING]\\*[$DRAFT] +. \} +. \} +. \} +. el \{\ +. ie !'\\*[$CHAPTER_TITLE_1]'' \{\ +. ie '\\*[$DRAFT]'' \ +. ds $HDRFTR_CENTER \\*[$CHAPTER_TITLE] +. el \{\ +. ds $HDRFTR_CENTER \ + \\*[$CHAPTER_TITLE_1], \ + \\*[$DRAFT_STRING]\\*[$DRAFT] +. \} +. \} +. el \{\ +. ie '\\*[$DRAFT]'' \{\ +. ds $HDRFTR_CENTER \ + \\*[$CHAPTER_STRING] \\*[$CHAPTER] +. \} +. el \{\ +. ds $HDRFTR_CENTER \ + \\*[$CHAPTER_STRING] \\*[$CHAPTER], \ + \\*[$DRAFT_STRING]\\*[$DRAFT] +. \} +. \} +. \} +. \} +. el \{\ +. ie '\\*[$CHAPTER]'' \{\ +. ie !'\\*[$CHAPTER_TITLE_1]'' \{\ +. ie '\\*[$DRAFT]'' \{\ +. ds $HDRFTR_CENTER \ + \\*[$CHAPTER_TITLE], \ + \\*[$REVISION_STRING] \\*[$REVISION] +. \} +. el \{\ +. ds $HDRFTR_CENTER \ + \\*[$CHAPTER_TITLE], \ + \\*[$DRAFT_STRING]\\*[$DRAFT], \ + \\*[$REVISION_STRING] \\*[$REVISION] +. \} +. \} +. el \{\ +. ie '\\*[$DRAFT]'' \{\ +. ds $HDRFTR_CENTER \ + \\*[$CHAPTER_STRING], \ + \\*[$REVISION_STRING] \\*[$REVISION] +. \} +. el \{\ +. ds $HDRFTR_CENTER \ + \\*[$CHAPTER_STRING], \ + \\*[$DRAFT_STRING]\\*[$DRAFT], \ + \\*[$REVISION_STRING] \\*[$REVISION] +. \} +. \} +. \} +. el \{\ +. ie !'\\*[$CHAPTER_TITLE_1]'' \{\ +. ie '\\*[$DRAFT]'' \{\ +. ds $HDRFTR_CENTER \ + \\*[$CHAPTER_TITLE], \ + \\*[$REVISION_STRING] \\*[$REVISION] +. \} +. el \{\ +. ds $HDRFTR_CENTER \ + \\*[$CHAPTER_TITLE], \ + \\*[$DRAFT_STRING]\\*[$DRAFT], \ + \\*[$REVISION_STRING] \\*[$REVISION] +. \} +. \} +. el \{\ +. ie '\\*[$DRAFT]'' \{\ +. ds $HDRFTR_CENTER \ + \\*[$CHAPTER_STRING] \\*[$CHAPTER], \ + \\*[$REVISION_STRING] \\*[$REVISION] +. \} +. el \{\ +. ds $HDRFTR_CENTER \ + \\*[$CHAPTER_STRING] \\*[$CHAPTER], \ + \\*[$DRAFT_STRING]\\*[$DRAFT], \ + \\*[$REVISION_STRING] \\*[$REVISION] +. \} +. \} +. \} +. \} +. \} +. \} +. \} +.\" Copystyle FINAL +. el \{\ +. if \\n[#DRAFT_WITH_PAGENUM] .rr #DRAFT_WITH_PAGENUM +. if \\n[#USER_DEF_HDRFTR_CENTER]=0 \{\ +. ie \\n[#PAGENUM_STYLE_SET] \ +. PAGENUM_STYLE \\*[$PAGENUM_STYLE] +. el .PAGENUM_STYLE DIGIT +. ie '\\*[$CHAPTER]'' \{\ +. ie !'\\*[$CHAPTER_TITLE_1]'' \ +. ds $HDRFTR_CENTER \\*[$CHAPTER_TITLE] +. el \ +. ds $HDRFTR_CENTER \\*[$CHAPTER_STRING] +. \} +. el \{\ +. ie !'\\*[$CHAPTER_TITLE_1]'' \ +. ds $HDRFTR_CENTER \\*[$CHAPTER_TITLE] +. el \ +. ds $HDRFTR_CENTER \\*[$CHAPTER_STRING] \\*[$CHAPTER] +. \} +. \} +. \} +. \} +.\" Named +. if \\n[#DOC_TYPE]=3 \{\ +. ie \\n[#COPY_STYLE]=1 \{\ +. ie \\n[#PAGENUM_STYLE_SET] .PAGENUM_STYLE \\*[$PAGENUM_STYLE] +. el .PAGENUM_STYLE roman +. ie \\n[#DRAFT_WITH_PAGENUM] \ +. ds $HDRFTR_CENTER \\*[$DOC_TYPE] +. el \{\ +. if \\n[#USER_DEF_HDRFTR_CENTER]=0 \{\ +. ie '\\*[$REVISION]'' \{\ +. ie '\\*[$DRAFT]'' \ +. ds $HDRFTR_CENTER \\*[$DOC_TYPE] +. el \{\ +. ds $HDRFTR_CENTER \ + \\*[$DOC_TYPE], \ + \\*[$DRAFT_STRING]\\*[$DRAFT] +. \} +. \} +. el \{\ +. ie '\\*[$DRAFT]'' \{\ +. ds $HDRFTR_CENTER \ + \\*[$DOC_TYPE], \ + \\*[$REVISION_STRING] \\*[$REVISION] +. \} +. el \{\ +. ds $HDRFTR_CENTER \ + \\*[$DOC_TYPE], \ + \\*[$DRAFT_STRING]\\*[$DRAFT], \ + \\*[$REVISION_STRING] \\*[$REVISION] +. \} +. \} +. \} +. \} +. \} +. el \{\ +. if \\n[#DRAFT_WITH_PAGENUM] .rr #DRAFT_WITH_PAGENUM +. if \\n[#USER_DEF_HDRFTR_CENTER]=0 \{\ +. ie \\n[#PAGENUM_STYLE_SET] .PAGENUM_STYLE \\*[$PAGENUM_STYLE] +. el .PAGENUM_STYLE DIGIT +. ds $HDRFTR_CENTER \\*[$DOC_TYPE] +. \} +. \} +. \} +.END +\# +\# ==================================================================== +\# +\# +++COLLECT DOC INFO (reference macros, metadata)+++ +\# +\# *Arguments: +\# various string/register arguments +\# *Function: +\# Set strings and registers for covers, docheaders, page headers. +\# +.MAC DOCTITLE END +. rr #DOCTITLE_NUM +. nr #DOCTITLE_NUM 0 1 +. while \\n[#NUM_ARGS]>\\n[#DOCTITLE_NUM] \{\ +. ds $DOCTITLE_\\n+[#DOCTITLE_NUM] \\$\\n[#DOCTITLE_NUM] +. \} +. ds $DOCTITLE \\$* +. PDF_TITLE \\*[$DOCTITLE] +.END +\# +.MAC TITLE END \"Document title +. if '\\$1'DOC_COVER' \{\ +. shift +. DOC_COVERTITLE \\$@ +. return +. \} +. if '\\$1'COVER' \{\ +. shift +. COVERTITLE \\$@ +. return +. \} +. ie \\n[#NUM_ARGS]=0 \{\ +. if \\n[#TITLE_NUM] \{\ +. nr #ITEM 0 1 +. while \\n[#TITLE_NUM]>\\n[#ITEM] \{\ +. rm $TITLE_\\n+[#ITEM] +. \} +. rr #TITLE_NUM +. \} +. \} +. el \{\ +. nr #TITLE_NUM 0 1 +. while \\n[#NUM_ARGS]>\\n[#TITLE_NUM] \{\ +. ds $TITLE_\\n+[#TITLE_NUM] \\$\\n[#TITLE_NUM] +. \} +. ds $TITLE \\$* +. \} +.END +\# +.MAC SUBTITLE END \"Document sub-title +. ie \\n[#NUM_ARGS]=0 \{\ +. if \\n[#DOC_COVER_SUBTITLE_NUM] \ +. ds COVER_ DOC_COVER_ +. if \\n[#COVER_SUBTITLE_NUM] \ +. ds COVER_ COVER_ +. if \\n[#\\*[COVER_]SUBTITLE_NUM] \{\ +. nr #ITEM 0 1 +. while \\n[#\\*[COVER_]SUBTITLE_NUM]>\\n[#ITEM] \{\ +. rm $\\*[COVER_]SUBTITLE_\\n+[#ITEM] +. \} +. rr #\\*[COVER_]SUBTITLE_NUM +. rm $SUBTITLE +. \} +. \} +. el \{\ +. if '\\$1'DOC_COVER' \{\ +. ds COVER_ DOC_COVER_ +. shift +. \} +. if '\\$1'COVER' \{\ +. ds COVER_ COVER_ +. shift +. \} +. nr #\\*[COVER_]SUBTITLE_NUM 0 1 +. while \\n[#NUM_ARGS]>\\n[#\\*[COVER_]SUBTITLE_NUM] \{\ +. ds $\\*[COVER_]SUBTITLE_\\n+[#\\*[COVER_]SUBTITLE_NUM] \ +\\$\\n[#\\*[COVER_]SUBTITLE_NUM] +. \} +. rm COVER_ +. ds $SUBTITLE \\$* +. \} +.END +\# +.MAC CHAPTER END \"If document is a chapter, the chapter number +. nr #CHAPTER_CALLED 1 +. ds $CHAPTER \\$1 +. if \B'\\*[$CHAPTER]' .nr #CH_NUM \\*[$CHAPTER] +. if !r #CH_NUM .nr #CH_NUM 1 +.END +. +.MAC CHAPTER_NUMBER END +. nr #CH_NUM \\$1 +.END +\# +.MAC CHAPTER_TITLE END \" This defines what comes after Chapter # +. ie \\n[#NUM_ARGS]=0 \{\ +. if \\n[#CHAPTER_TITLE_NUM] \{\ +. nr #ITEM 0 1 +. while \\n[#CHAPTER_TITLE_NUM]>\\n[#ITEM] \{\ +. rm $CHAPTER_TITLE_\\n+[#ITEM] +. \} +. rr #CHAPTER_TITLE_NUM +. rm $CHAPTER_TITLE +. \} +. \} +. el \{\ +. rr #CHAPTER_TITLE_NUM +. nr #CHAPTER_TITLE_NUM 0 1 +. while \\n[#NUM_ARGS]>\\n[#CHAPTER_TITLE_NUM] \{\ +. ds $CHAPTER_TITLE_\\n+[#CHAPTER_TITLE_NUM] \ +\\$\\n[#CHAPTER_TITLE_NUM] +. \} +. ds $CHAPTER_TITLE \\$* +. \} +.END +\# +.MAC DRAFT END \"Draft number +. ie '\\$1'' .ds $DRAFT +. el .ds $DRAFT " \\$1 +.END +\# +.MAC REVISION END \"Revision number +. ds $REVISION \\$1 +.END +\# +.MAC DRAFT_WITH_PAGENUMBER END \"Attach draft/revision strings to page number +. nr #DRAFT_WITH_PAGENUM 1 +.END +\# +.MAC AUTHOR END \"Author. Enclose all args fully in double quotes. +. rr #NO_PRINT_AUTHOR +. if '\\$1'DOC_COVER' \{\ +. ds COVER_ DOC_COVER_ +. shift +. \} +. if '\\$1'COVER' \{\ +. ds COVER_ COVER_ +. shift +. \} +. nr #\\*[COVER_]AUTHOR_NUM 0 1 +. while \\n[#NUM_ARGS]>\\n[#\\*[COVER_]AUTHOR_NUM] \{\ +. ds $\\*[COVER_]AUTHOR_\\n+[#\\*[COVER_]AUTHOR_NUM] \ +\\$\\n[#\\*[COVER_]AUTHOR_NUM] +. if !'\\*[$\\*[COVER_]AUTHOR_\\n[#\\*[COVER_]AUTHOR_NUM]]'' \ +. as $AUTHORS \ +"\\*[$\\*[COVER_]AUTHOR_\\n[#\\*[COVER_]AUTHOR_NUM]], \" +. \} +. ds $AUTHOR \\*[$AUTHOR_1] +. substring $AUTHORS 0 -2 +. ds PDF_AUTHORS \\*[$AUTHORS] +. pdfmomclean PDF_AUTHORS +. nop \!x X ps:exec [/Author (\\*[PDF_AUTHORS]) /DOCINFO pdfmark +.END +. +.ALIAS EDITOR AUTHOR +\# +.MAC COPYRIGHT END \"For use on cover pages only +. ie \\n[#NUM_ARGS]=1 \ +. ds $COVER_COPYRIGHT \[co]\\$1 +. el \{\ +. if '\\$1'COVER' .ds $COVER_COPYRIGHT \[co]\\$2 +. if '\\$1'DOC_COVER' .ds $DOC_COVER_COPYRIGHT \[co]\\$2 +. \} +.END +\# +.MAC COPYRIGHT_V_ADJUST END +. ds $COPYRIGHT_V_ADJ \\$1 +.END +\# +.MAC MISC END \"Doc cover and cover pages only; enclose all args in double quotes +. rm COVER_ +. ie \\n[#NUM_ARGS]=0 \{\ +. if \\n[#DOC_COVER_MISC_LINES] \ +. ds COVER_ DOC_COVER_ +. if \\n[#COVER_MISC_LINES] \ +. ds COVER_ COVER_ +. if \\n[#\\*[COVER_]MISC_LINES] \{\ +. nr #LINE 0 1 +. while \\n[#\\*[COVER_]MISC_LINES]>\\n[#LINE] \{\ +. rm $\\*[COVER_]MISC_\\n+[#LINE] +. \} +. rr #\\*[COVER_]MISC_LINES +. \} +. \} +. el \{\ +. if '\\$1'DOC_COVER' \{\ +. ds COVER_ DOC_COVER_ +. shift +. \} +. if '\\$1'COVER' \{\ +. ds COVER_ COVER_ +. shift +. \} +. nr #\\*[COVER_]MISC_LINE 0 1 +. while \\n[#NUM_ARGS]>\\n[#\\*[COVER_]MISC_LINE] \{\ +. ds $\\*[COVER_]MISC_\\n+[#\\*[COVER_]MISC_LINE] \ +\\$[\\n[#\\*[COVER_]MISC_LINE]] +. \} +. nr #\\*[COVER_]MISC_LINES \\n[#NUM_ARGS] +. rm COVER_ +. \} +.END +\# +\# Page number that appears on page one. +.MAC PAGENUMBER END +. nr #n%_AT_PAGENUM_SET \\n% +. nr #PAGE_NUM_ADJ \\$1-\\n[#n%_AT_PAGENUM_SET] +. rr #n%_AT_PAGENUM_SET +. nr #PAGE_NUM_SET 1 +.END +\# +\# Replacement string for pagenumber. +.MAC PAGENUMBER_STRING END +. ds $PAGENUM_STRING \\$1 +.END +\# +\# ==================================================================== +\# +\# +++TYPE OF DOCUMENT+++ +\# +\# DOCUMENT TYPE +\# ------------- +\# *Argument: +\# DEFAULT | CHAPTER | NAMED " | LETTER +\# *Function: +\# Creates strings and sets registers for document types. +\# *Notes: +\# Number registers: DEFAULT=1, CHAPTER=2, NAMED=3, LETTER=4, +\# SLIDES=5 +\# +.MAC DOCTYPE END +. if '\\$1'DEFAULT' .nr #DOC_TYPE 1 +. if '\\$1'CHAPTER' .nr #DOC_TYPE 2 +. if '\\$1'NAMED' \{\ +. rr #NO_PRINT_DOCTYPE +. ds $DOC_TYPE \\$2 +. nr #DOC_TYPE 3 +. \} +. if '\\$1'LETTER' \{\ +. nr #DOC_TYPE 4 +. L_MARGIN 1.125i +. R_MARGIN 1.125i +. ps 12 +. vs 13.5 +. nr #FOOTER_ADJ \\n[.v] +. DOCHEADER OFF +. PARA_INDENT 3m +. INDENT_FIRST_PARAS +. PARA_SPACE +. ds $SUITE \En[#SUITE] +. HEADER_MARGIN 3P+6p +. HEADER_GAP 3P +. FOOTERS +. FOOTER_RULE OFF +. FOOTER_LEFT "" +. FOOTER_CENTER "" +. FOOTER_RIGHT_SIZE +0 +. FOOTER_RIGHT "\&.../\E*[$SUITE] +. FOOTER_ON_FIRST_PAGE +. em ALL_DONE +. \} +. if '\\$1'SLIDES' \{\ +. shift +. nr #DOC_TYPE 5 +. PRINTSTYLE TYPESET +. FAMILY H +. QUAD CENTER +. QUOTE_STYLE QUAD CENTER +. BLOCKQUOTE_STYLE \ + QUAD J \ + INDENT \\n[.l]u/5u +. PARA_INDENT 0 +. NO_SHIM +. NO_FLEX +. HEADING_STYLE 1 \ + SIZE +8 \ + QUAD CENTER +. HEADING_STYLE 2 \ + SIZE +4 \ + QUAD CENTER +. HEADING_STYLE 3 \ + SIZE +2 \ + QUAD CENTER +. DOCHEADER off +. PAGINATION off +. PAGENUM_HYPHENS off +. HEADERS off +. FOOTERS off +. HEADERS_PLAIN +. FOOTERS_PLAIN +. nr loop-count 0 1 +. nr loop-counter \\n[#NUM_ARGS] +.\" Default 16:9 setup if no ASPECT +. PAGE 11i 6.1875i 36p 36p 80p 72p +. PT_SIZE 14 +. AUTOLEAD 4 +. HEADER_SIZE -2 +. while \\n+[loop-count]<=\\n[loop-counter] \{\ +. if '\\$1'ASPECT' \{\ +. if '\\$2'4:3' \{\ +. PAGE 11i 8.25i 36p 36p 90p 84p +. PT_SIZE 16 +. AUTOLEAD 6 +. HEADER_SIZE -3 +. \} +. if '\\$2'16:9' \{\ +. PAGE 11i 6.1875i 36p 36p 80p 72p +. PT_SIZE 14 +. AUTOLEAD 4 +. HEADER_SIZE -2 +. \} +. shift 2 +. \} +. if '\\$1'HEADER' \{\ +. shift 1 +. nr #SLIDE_HEADERS 1 +. ds $SLIDE_HDR_L \\$1 +. ds $SLIDE_HDR_C \\$2 +. ds $SLIDE_HDR_R \\$3 +. HEADER_MARGIN 45p +. shift 3 +. \} +. if '\\$1'FOOTER' \{\ +. shift 1 +. nr #SLIDE_FOOTERS 1 +. ds $SLIDE_FTR_L \\$1 +. ds $SLIDE_FTR_C \\$2 +. ds $SLIDE_FTR_R \\$3 +. shift 3 +. \} +. if '\\$1'TRANSITION' \{\ +. shift 1 +. ds $TRANS_TYPE \\$1 +. shift 1 +. \} +. if '\\$1'PAUSE' \{\ +. shift 1 +. ds $PAUSE_TYPE \\$1 +. shift 1 +. \} +. \} +. if d $TRANS_TYPE \ +. pdftransition PAGE \\*[$TRANS_TYPE] +. if d $PAUSE_TYPE \ +. pdftransition BLOCK \\*[$PAUSE_TYPE] +. \} +. ie \\n[#SLIDE_HEADERS]+\\n[#SLIDE_FOOTERS]=2 \{\ +. HEADERS_AND_FOOTERS L "^\\*[$SLIDE_HDR_L]#\\*[$SLIDE_HDR_C]#\\*[$SLIDE_HDR_R]^" \ + L "^\\*[$SLIDE_FTR_L]#\\*[$SLIDE_FTR_C]#\\*[$SLIDE_FTR_R]^" +. \} +. el \{\ +. if \\n[#SLIDE_HEADERS] \{\ +. HEADERS +. HEADER_RECTO L "^\\*[$SLIDE_HDR_L]#\\*[$SLIDE_HDR_C]#\\*[$SLIDE_HDR_R]^" \ +. \} +. if \\n[#SLIDE_FOOTERS] \{\ +. FOOTERS +. FOOTER_RECTO L "^\\*[$SLIDE_FTR_L]#\\*[$SLIDE_FTR_C]#\\*[$SLIDE_FTR_R]^" +. \} +. \} +.END +\# +\# +++LETTER MACROS+++ +\# +\# First, create a register to hold incrementing numbers to be +\# appended to LETTERHEAD. +\# +.nr #FIELD 0 1 +\# +\# DATE +\# ---- +\# *Arguments: +\# +\# *Function: +\# Stores date (entered on the line after .DATE) in diversion +\# LETTERHEAD +\# +.MAC DATE END +. if !'\\n[.z]'' .di +. di LETTERHEAD\\n+[#FIELD] +. ie \\n[#FIELD]=1 \{\ +. nr #DATE_FIRST 1 +. RIGHT +. \} +. el .LEFT +.END +\# +\# TO +\# -- +\# *Arguments: +\# +\# *Function: +\# Stores addressee address (entered on the line after .TO) in +\# diversion LETTERHEAD +\# +.MAC TO END +. if !'\\n[.z]'' .di +. di LETTERHEAD\\n+[#FIELD] +. LEFT +.END +\# +\# FROM +\# ---- +\# *Arguments: +\# +\# *Function: +\# Stores addresser address (entered on the line after .FROM) in +\# diversion LETTERHEAD +\# +.MAC FROM END +. if !'\\n[.z]'' .di +. di LETTERHEAD\\n+[#FIELD] +. LEFT +.END +\# +\# GREETING +\# -------- +\# *Arguments: +\# +\# *Function: +\# Stores greeting (entered on the line after .GREETING) in +\# diversion LETTERHEAD +\# +.MAC GREETING END +. if !'\\n[.z]'' .di +. di LETTERHEAD\\n+[#FIELD] +. LEFT +.END +\# +\# CLOSING +\# ------- +\# *Arguments: +\# +\# *Function: +\# Stores greeting in diversion CLOSING. +\# +.MAC CLOSING END +. if '\\*[$SIG_SPACE]'' .ds $SIG_SPACE 3v +. ie ( (2v+\\*[$SIG_SPACE]) > \\n[.t] ) \{\ +. ie !\\n[@TOP] \{\ +. ch HEADER +. ch FOOTER +. br +. tm1 "[mom]: Insufficient room for \\$0 and signature line. +. ab [mom]: Terminating '\\n[.F]' before closing. +. \} +. el .sp +. \} +. el .br +. nr #CLOSING 1 +. di CLOSING_TEXT +.END +\# +\# CLOSING INDENT +\# -------------- +\# *Argument: +\# +\# *Function: +\# Defines string $CLOSE_INDENT for use in macro, ALL_DONE. +\# +.MAC CLOSING_INDENT END +. ds $CLOSE_INDENT \\$1 +.END +\# +\# SIGNATURE_SPACE +\# --------------- +\# *Argument: +\# +\# *Function: +\# Defines string $SIG_SPACE for use in macro, ALL_DONE. +\# +.MAC SIGNATURE_SPACE END +. ds $SIG_SPACE \\$1 +.END +\# +\# NO SUITE +\# -------- +\# *Arguments: +\# +\# *Function: +\# Redefines $FOOTER_RIGHT to blank so that a suite number doesn't +\# appear at the bottom of letter pages. +\# +.MAC NO_SUITE END +. FOOTER_RIGHT "" +.END +\# +\# ==================================================================== +\# +\# +++DEFAULTS FOR DOCUMENT PROCESSING+++ +\# +\# TYPE-STYLE CONTROL MACROS +\# ------------------------- +\# The control macros for family, font, size, color and quad are +\# here grouped together. Each (e.g., _FAMILY) uses the calling alias +\# to determine the document element to which the style parameter +\# applies. Defaults for all these guys are set in DEFAULTS, and +\# listed in the "Control Macros" section of the documentation +\# pertinent to the element whose style is to be changed. +\# +.MAC _FAMILY END +. ds PARAM FAM +. ds ELEMENT \\$0 +. if '\\$0'COPYRIGHT_FAMILY' \ +. ds ELEMENT COVER_COPYRIGHT_FAMILY +. ds FROM_ALIAS \\$0 +. substring ELEMENT 0 -4 \" Strip 'ILY' from FAMILY +. ASSIGN_ELEMENT \\$1 +.END +\# +.MAC _FONT END +. ds PARAM FT +. ds ELEMENT \\$0 +. ds FROM_ALIAS \\$0 +. if '\\$0'COPYRIGHT_FONT' \ +. ds ELEMENT COVER_COPYRIGHT_FONT +. substring ELEMENT 0 -5 +. ds ELEMENT \\*[ELEMENT]FT \" ELEMENT is now \\$0_FT +. ASSIGN_ELEMENT \\$1 +.END +\# +.MAC _SIZE END +. ds PARAM SIZE_CHANGE +. ds ELEMENT \\$0_CHANGE +. if '\\$0'CODE_SIZE' \{\ +. ds PARAM SIZE_ADJ +. ds ELEMENT \\$0_ADJ +. \} +. if '\\$0'COPYRIGHT_SIZE' \ +. ds ELEMENT COVER_COPYRIGHT_SIZE_CHANGE +. ds FROM_ALIAS \\$0 +. ASSIGN_ELEMENT \\$1 +.END +\# +.MAC _COLOR END +. if \\n[#PRINT_STYLE]=1 .return +. ds PARAM COLOR +. ds ELEMENT \\$0 +. if '\\$0'COPYRIGHT_COLOR' \ +. ds ELEMENT COVER_COPYRIGHT_COLOR +. ds FROM_ALIAS \\$0 +. ASSIGN_ELEMENT \\$1 +.END +\# +.MAC _CAPS END +. ds CAPS_TYPE \\$0 +. substring CAPS_TYPE 0 7 +. ds CALLED_AS \\$0 +. substring CALLED_AS -7 +. ie '\\*[CALLED_AS]'NO_CAPS' \{\ +. ie '\\*[CAPS_TYPE]'BIBLIOGR' \{\ +. if '\\$0'BIBLIOGRAPHY_HEADER_NO_CAPS' .rr #BIB_STRING_CAPS +. if '\\$0'BIBLIOGRAPHY_STRING_NO_CAPS' .rr #BIB_STRING_CAPS +. \} +. el \{\ +. ie '\\*[CAPS_TYPE]'ENDNOTES' \{\ +. if '\\$0'ENDNOTES_HEADER_NO_CAPS' .rr #EN_STRING_CAPS +. if '\\$0'ENDNOTES_STRING_NO_CAPS' .rr #EN_STRING_CAPS +. \} +. el \{\ +. ie '\\$0'TOC_HEADER_NO_CAPS' .rr #TOC_STRING_CAPS +. el \{\ +. ds REGISTER_TYPE \\$0 +. substring REGISTER_TYPE 0 -8 +. as REGISTER_TYPE CAPS +. rr #\\*[REGISTER_TYPE] +. \} +. \} +. \} +. \} +. el \{\ +. ie '\\*[CAPS_TYPE]'BIBLIOGR' \{\ +. if '\\$0'BIBLIOGRAPHY_HEADER_CAPS' .nr #BIB_STRING_CAPS 1 +. if '\\$0'BIBLIOGRAPHY_STRING_CAPS' .nr #BIB_STRING_CAPS 1 +. \} +. el .nr #\\$0 1 +. \} +.END +. +.ALIAS _NO_CAPS _CAPS +\# +.MAC _SMALLCAPS END +. ds SMALLCAPS_TYPE \\$0 +. substring SMALLCAPS_TYPE 0 7 +. ds CALLED_AS \\$0 +. substring CALLED_AS -12 +. ie '\\*[CALLED_AS]'NO_SMALLCAPS' \{\ +. ie '\\*[SMALLCAPS_TYPE]'BIBLIOGR' \{\ +. if '\\$0'BIBLIOGRAPHY_HEADER_NO_SMALLCAPS' .rr #BIB_STRING_SMALLCAPS +. if '\\$0'BIBLIOGRAPHY_STRING_NO_SMALLCAPS' .rr #BIB_STRING_SMALLCAPS +. \} +. el \{\ +. ie '\\*[SMALLCAPS_TYPE]'ENDNOTES' \{\ +. if '\\$0'ENDNOTES_HEADER_NO_SMALLCAPS' .rr #EN_STRING_SMALLCAPS +. if '\\$0'ENDNOTES_STRING_NO_SMALLCAPS' .rr #EN_STRING_SMALLCAPS +. \} +. el \{\ +. ie '\\$0'TOC_HEADER_NO_SMALLCAPS' .rr #TOC_STRING_SMALLCAPS +. el \{\ +. ds REGISTER_TYPE \\$0 +. substring REGISTER_TYPE 0 -13 +. as REGISTER_TYPE SMALLCAPS +. rr #\\*[REGISTER_TYPE] +. \} +. \} +. \} +. \} +. el \{\ +. ie '\\*[SMALLCAPS_TYPE]'BIBLIOGR' \{\ +. if '\\$0'BIBLIOGRAPHY_HEADER_SMALLCAPS' .nr #BIB_STRING_SMALLCAPS 1 +. if '\\$0'BIBLIOGRAPHY_STRING_SMALLCAPS' .nr #BIB_STRING_SMALLCAPS 1 +. \} +. el .nr #\\$0 1 +. \} +.END +. +.ALIAS _NO_SMALLCAPS _SMALLCAPS +\# +.MAC _QUAD END +. if '\\$0'BIBLIOGRAPHY_QUAD' \{\ +. if '\\$1'R' .QUAD-ERROR \\$0 +. if '\\$1'C' .QUAD-ERROR \\$0 +. \} +. if '\\$0'ENDNOTE_QUAD' \{\ +. if '\\$1'R' .QUAD-ERROR \\$0 +. if '\\$1'C' .QUAD-ERROR \\$0 +. \} +. if '\\$0'DOC_QUAD' \ +. if !\\n[#DOCS] .DOC_MACRO_ERROR \\$0 +. ds PARAM QUAD +. ds ELEMENT \\$0 +. if '\\$0'COPYRIGHT_QUAD' \ +. ds ELEMENT COVER_COPYRIGHT_QUAD +. ds FROM_ALIAS \\$0 +. ASSIGN_ELEMENT \\$1 +.END +\# +\# Special handling for QUOTE quadding +\# +.MAC QUOTE_QUAD END +. ds $Q_QUAD \\$0 +. substring $Q_QUAD 6 +.END +. +.ALIAS QUOTE_LEFT QUOTE_QUAD +.ALIAS QUOTE_CENTER QUOTE_QUAD +.ALIAS QUOTE_RIGHT QUOTE_QUAD +\# +.MAC QUAD-ERROR END +. tm1 "[mom]: \\$1 at line \\n[.c] of '\\n[.F]' must be set to either L or J. +. ab [mom]: Aborting. +.END +\# +.MAC ASSIGN_ELEMENT END +. rm $\\*[ELEMENT] \" Clear this first +.\" HDRFTR__ need special handling. +. ds hdrftr \\*[FROM_ALIAS] +. substring hdrftr 0 5 +. if '\\*[hdrftr]'HDRFTR' \{\ +. ds hdrftr-pos-element \\*[ELEMENT] +.\" See if ELEMENT is of the form HDRFTR__ +. substring hdrftr-pos-element 0 7 +. substring hdrftr-pos-element -1 +. if !'\\*[ELEMENT]'HDRFTR_COLOR' \{\ +. if '\\*[hdrftr-pos-element]'L' .nr hdrftr-pos-element 1 +. if '\\*[hdrftr-pos-element]'C' .nr hdrftr-pos-element 1 +. if '\\*[hdrftr-pos-element]'R' .nr hdrftr-pos-element 1 +. \} +. \} +. if !\\n[hdrftr-pos-element] \{\ +. ds c1-c5 \\*[ELEMENT] +. substring c1-c5 0 4 \" Grab first five letters of the alias +. \} +.\" If none of the following, convert the substring of the +.\" calling alias, ie \*[ELEMENT], into the parameter string, e.g., +.\" $TITLE_FAM, assign arg, and set register. +. if !'\\*[c1-c5]'BIBLI' \ +. if !'\\*[c1-c5]'BLOCK' \ +. if !'\\*[c1-c5]'CITAT' \ +. if !'\\*[c1-c5]'ENDNO' \ +. if !'\\*[c1-c5]'EPIGR' \ +. if !'\\*[c1-c5]'FOOTN' \ +. if !'\\*[c1-c5]'HDRFT' \ +. if !'\\*[c1-c5]'LINEN' \ +. if !'\\*[c1-c5]'PAGEN' \{\ +. ie '\\*[ELEMENT]'CODE_SIZE_ADJ' .nr #\\*[ELEMENT] \\$1 +. el \{\ +. ds $\\*[ELEMENT] \\$1 +. nr #\\*[ELEMENT] 1 +. \} +. \} +. if '\\*[$\\*[ELEMENT]]'' \{\ +. if '\\*[c1-c5]'BIBLI' .ASSIGN_PARAM BIB \\$1 +. if '\\*[c1-c5]'BLOCK' .ASSIGN_PARAM BQUOTE_ \\$1 +. if '\\*[c1-c5]'CITAT' .ASSIGN_PARAM BQUOTE_ \\$1 +. if '\\*[c1-c5]'ENDNO' .ASSIGN_PARAM EN \\$1 +. if '\\*[c1-c5]'EPIGR' .ASSIGN_PARAM EPI_ \\$1 +. if '\\*[c1-c5]'FOOTN' .ASSIGN_PARAM FN_ \\$1 +. if '\\*[c1-c5]'HDRFT' .ASSIGN_PARAM HDRFTR_ \\$1 +. if '\\*[c1-c5]'LINEN' .ASSIGN_PARAM LN_ \\$1 +. if '\\*[c1-c5]'PAGEN' .ASSIGN_PARAM PAGE_NUM_ \\$1 +. \} +. if \\n[hdrftr-pos-element] \{\ +. if '\\*[hdrftr-pos-element]'L' .ds hdrftr-pos-element LEFT +. if '\\*[hdrftr-pos-element]'C' .ds hdrftr-pos-element CENTER +. if '\\*[hdrftr-pos-element]'R' .ds hdrftr-pos-element RIGHT +. if '\\*[ELEMENT]'HDRFTR_\\*[hdrftr-pos-element]_FAM' \ +. ds $HDRFTR_\\*[hdrftr-pos-element]_FAM \\$1 +. \} +. rr hdrftr-pos-element +. rm hdrftr-pos-element +.END +\# +.MAC ASSIGN_PARAM END +. if '\\*[PARAM]'FAM' .nr substr-index -7 +. if '\\*[PARAM]'FT' .nr substr-index -5 +. if '\\*[PARAM]'SIZE_CHANGE' .nr substr-index -5 +. if '\\*[PARAM]'COLOR' .nr substr-index -6 +. if '\\*[PARAM]'QUAD' .nr substr-index -5 +. if '\\$1'BIB' \{\ +. ds ELEMENT \\*[FROM_ALIAS] +. substring ELEMENT 12 \\n[substr-index] +. if '\\*[ELEMENT]'_HEADER_' \ +. ds ELEMENT _STRING_ +. \} +. if '\\$1'BQUOTE_' .rm ELEMENT +. if '\\$1'EN' \{\ +. ds ELEMENT \\*[FROM_ALIAS] +. substring ELEMENT 7 \\n[substr-index] +. if '\\*[ELEMENT]'S_HEADER_' \ +. ds ELEMENT _STRING_ +. if '\\*[ELEMENT]'_LINENUMBER_' \ +. ds ELEMENT _LN_ +. \} +. if '\\$1'EPI_' .rm ELEMENT +. if '\\$1'FN_' .rm ELEMENT +. if '\\$1'HDRFTR_' \{\ +. if '\\*[ELEMENT]'HDRFTR_FAM' \{\ +. nr #HDRFTR 1 +. ds $HDRFTR_FAM \\$2 +. ds $HDRFTR_LEFT_FAM \\$2 +. ds $HDRFTR_CENTER_FAM \\$2 +. ds $HDRFTR_RIGHT_FAM \\$2 +. \} +. if '\\*[ELEMENT]'HDRFTR_COLOR' \{\ +. nr #HDRFTR 1 +. nr #HDRFTR_COLOR 1 +. ds $HDRFTR_COLOR \\$2 +. \} +. if '\\*[ELEMENT]'HDRFTR_SIZE_CHANGE' \{\ +. nr #HDRFTR 1 +. ds $HDRFTR_SIZE_CHANGE \\$2 +. \} +. if '\\*[PARAM]'SIZE_CHANGE' \{\ +. nr #HDRFTR 1 +. if '\\*[hdrftr-pos-element]'L' \ +. ds $HDRFTR_LEFT_SIZE_CHANGE \\$2 +. if '\\*[hdrftr-pos-element]'C' \ +. ds $HDRFTR_CENTER_SIZE_CHANGE \\$2 +. if '\\*[hdrftr-pos-element]'R' \ +. ds $HDRFTR_RIGHT_SIZE_CHANGE \\$2 +. \} +. if !r #HDRFTR \{\ +. substring ELEMENT 7 \\n[substr-index] +. if '\\*[ELEMENT]'_LEFT' .ds ELEMENT _STRING_ +. \} +. \} +. if '\\$1'LN_' .rm ELEMENT +. if '\\$1'PAGE_NUM_' .rm ELEMENT +. if !r #HDRFTR \{\ +. ds $\\$1\\*[ELEMENT]\\*[PARAM] \\$2 +. nr #\\$1\\*[ELEMENT]\\*[PARAM] 1 +. \} +. rr #HDRFTR +. rm hdrftr-pos-element +. rr substr-index +. rm FROM_ALIAS +. rm ELEMENT +.END +\# +.MAC TITLE_LEAD END +. ds $TYPE \\$0 +. substring $TYPE 0 2 +. if '\\*[$TYPE]'DOC' .nr DOC_ 1 +. ds $TYPE \\$0 +. ie '\\*[$TYPE]'MISC_LEAD' .ds $TYPE COVER_MISC +. el .substring $TYPE -6 0 +. ds $\\*[$TYPE]_LEAD \\$1 +. nr #\\*[$TYPE]_LEAD 1 +. rm $TYPE +.END +\# +\# The _STYLE macro, called by various aliases, allows grouping +\# style parameters for most document elements in a single macro +\# using 'KEYWORD value' pairs. +\# +.MAC _STYLE END +. SILENT \" Some of the invoked macros cause unwanted breaks +. ds $STYLE_TYPE \\$0 +. substring $STYLE_TYPE 0 -7 +. ds $HDR_FTR \\*[$STYLE_TYPE] +. length #HDR_FTR_STRING $HDR_FTR +. if \\n[#HDR_FTR_STRING]<=5 .substring $HDR_FTR 0 5 \" HEADER or FOOTER +. if '\\*[$HDR_FTR]'HEADER' .ds $HDR_FTR HEADER +. if '\\*[$HDR_FTR]'FOOTER' .ds $HDR_FTR FOOTER +. ds $POS \\$0 +. substring $POS 7 7 +. if '\\*[$POS]'L' .ds $POS LEFT +. if '\\*[$POS]'C' .ds $POS CENTER +. if '\\*[$POS]'R' .ds $POS RIGHT +. if '\\*[$STYLE_TYPE]'\\*[$HDR_FTR]_\\*[$POS]' \{\ +. ds $\\*[$HDR_FTR]_\\*[$POS] \\*[$HDR_FTR]_\\*[$POS] +. ds $STYLE_TYPE HDRFTR_\\*[$POS] +. \} +. if '\\*[$STYLE_TYPE]'ENDNOTES_HEADER' \ +. ds $BIB-EN-TOC EN_STRING +. if '\\*[$STYLE_TYPE]'ENDNOTE_STRING' \ +. ds $BIB-EN-TOC EN_STRING +. if '\\*[$STYLE_TYPE]'BIBLIOGRAPHY_HEADER' \ +. ds $BIB-EN-TOC BIB_STRING +. if '\\*[$STYLE_TYPE]'BIBLIOGRAPHY_STRING' \ +. ds $BIB-EN-TOC BIB_STRING +. if '\\*[$STYLE_TYPE]'TOC_HEADER' \ +. ds $BIB-EN-TOC TOC_STRING +. if '\\*[$STYLE_TYPE]'PAGENUMBER' \ +. ds $STYLE_TYPE PAGENUM +. nr #LOOP 0 1 +. nr #STYLE_PARAMS \\n[#NUM_ARGS] +. while \\n+[#LOOP]<=\\n[#STYLE_PARAMS] \{\ +. if '\\$1'FAMILY' \{\ +. shift +. \\*[$STYLE_TYPE]_FAMILY \\$1 +. shift +. \} +. if '\\$1'FONT' \{\ +. shift +. \\*[$STYLE_TYPE]_FONT \\$1 +. shift +. \} +. if '\\$1'SIZE' \{\ +. shift +. \\*[$STYLE_TYPE]_SIZE \\$1 +. shift +. \} +. if '\\$1'COLOR' \{\ +. shift +. \\*[$STYLE_TYPE]_COLOR \\$1 +. shift +. \} +. if '\\$1'CAPS' \{\ +. if \\n[#\\*[$STYLE_TYPE]_SMALLCAPS] \{\ +. tm1 \ +"[mom]: '\\*[$STYLE_TYPE]_STYLE' contains CAPS and SMALLCAPS. \ +CAPS takes precedence. +. rr #\\*[$STYLE_TYPE]_SMALLCAPS +. \} +. \\*[$STYLE_TYPE]_CAPS +. if d $\\*[$HDR_FTR]_LEFT .HEADER_LEFT_CAPS +. if d $\\*[$HDR_FTR]_CENTER .HEADER_CENTER_CAPS +. if d $\\*[$HDR_FTR]_CENTRE .HEADER_CENTER_CAPS +. if d $\\*[$HDR_FTR]_RIGHT .HEADER_RIGHT_CAPS +. shift +. \} +. if '\\$1'NO_CAPS' \{\ +. nr #\\*[$STYLE_TYPE]_CAPS 0 +. if !'\\*[$BIB-EN-TOC]'' \ +. rr #\\*[$BIB-EN-TOC]_CAPS +. shift +. \} +. if '\\$1'SMALLCAPS' \{\ +. if \\n[#\\*[$STYLE_TYPE]_CAPS] \{\ +. tm1 \ +"[mom]: '\\*[$STYLE_TYPE]_STYLE' contains CAPS and SMALLCAPS. \ +SMALLCAPS takes precedence. +. rr #\\*[$STYLE_TYPE]_CAPS +. \} +. \\*[$STYLE_TYPE]_SMALLCAPS +. shift +. \} +. if '\\$1'NO_SMALLCAPS' \{\ +. rr #\\*[$STYLE_TYPE]_SMALLCAPS +. if !'\\*[$BIB-EN-TOC]'' \ +. rr #\\*[$BIB-EN-TOC]_SMALLCAPS +. shift +. \} +. if '\\$1'LEAD' \{\ +. shift +. \\*[$STYLE_TYPE]_LEAD \\$1 +. shift +. \} +. if '\\$1'AUTOLEAD' \{\ +. shift +. \\*[$STYLE_TYPE]_AUTOLEAD \\$1 +. shift +. \} +. if '\\$1'SPACE' \{\ +. shift +. \\*[$STYLE_TYPE]_SPACE \\$1 +. shift +. \} +. if '\\$1'QUAD' \{\ +. shift +. ie '\\*[$STYLE_TYPE]'QUOTE' \{\ +. ds $QUAD_TYPE \\$1 +. substring $QUAD_TYPE 0 0 +. if '\\*[$QUAD_TYPE]'L' .QUOTE_LEFT +. if '\\*[$QUAD_TYPE]'C' .QUOTE_CENTER +. if '\\*[$QUAD_TYPE]'R' .QUOTE_RIGHT +. \} +. el .\\*[$STYLE_TYPE]_QUAD \\$1 +. shift +. \} +. if '\\$1'INDENT' \{\ +. shift +. \\*[$STYLE_TYPE]_INDENT \\$1 +. shift +. \} +.\" UNDERLINE and UNDERSCORE are identical but we can't use : or & +.\" in string comparisons. +. if '\\$1'UNDERLINE' \{\ +. shift +. if '\\$1'DOUBLE' \{\ +. as ul-args \\$1 \" +. shift +. \} +. nr #COUNT 0 1 +. while \\n+[#COUNT]<=3 \{\ +. if \B'\\$1' \{\ +. as ul-args \\$1 \" +. shift +. \} +. \} +. \\*[$STYLE_TYPE]_UNDERSCORE \\*[ul-args] +. \} +. if '\\$1'UNDERSCORE' \{\ +. shift +. if '\\$1'DOUBLE' \{\ +. as ul-args \\$1 \" +. shift +. \} +. nr #COUNT 0 1 +. while \\n+[#COUNT]<=3 \{\ +. if \B'\\$1' \{\ +. as ul-args \\$1 \" +. shift +. \} +. \} +. \\*[$STYLE_TYPE]_UNDERSCORE \\*[ul-args] +. \} +. if '\\$1'NO_UNDERSCORE' \{\ +. rr #\\*[$STYLE_TYPE]_UNDERLINE +. if !'\\*[$BIB-EN-TOC]'' \ +. rr #\\*[$BIB-EN-TOC]_UNDERLINE +. shift +. \} +. if '\\$1'NO_UNDERLINE' \{\ +. rr #\\*[$STYLE_TYPE]_UNDERLINE +. if !'\\*[$BIB-EN-TOC]'' \ +. rr #\\*[$BIB-EN-TOC]_UNDERLINE +. shift +. \} +. if '\\$1'V_ADJUST' \{\ +. shift +. COPYRIGHT_V_ADJUST \\$1 +. shift +. \} +. \} +. rm $STYLE_TYPE +. rm $HDR_FTR +. rm $POS +. rm $HEADER_LEFT +. rm $HEADER_CENTER +. rm $HEADER_RIGHT +. rm $BIB-EN-TOC +. rm ul-args +. SILENT off +.END +. +.ds STYLE_TYPE_1 ATTRIBUTE +.ds STYLE_TYPE_2 AUTHOR +.ds STYLE_TYPE_3 BIBLIOGRAPHY_HEADER +.ds STYLE_TYPE_4 BIBLIOGRAPHY_STRING +.ds STYLE_TYPE_5 BLOCKQUOTE +.ds STYLE_TYPE_6 CHAPTER +.ds STYLE_TYPE_7 CHAPTER_TITLE +.ds STYLE_TYPE_8 CODE +.ds STYLE_TYPE_9 COPYRIGHT +.ds STYLE_TYPE_10 COVER +.ds STYLE_TYPE_11 COVERTITLE +.ds STYLE_TYPE_12 DOC_COVERTITLE +.ds STYLE_TYPE_13 DOCHEADER +.ds STYLE_TYPE_14 DOCTITLE +.ds STYLE_TYPE_15 DOCTYPE +.ds STYLE_TYPE_16 ENDNOTE_TITLE +.ds STYLE_TYPE_17 ENDNOTES_HEADER +.ds STYLE_TYPE_18 ENDNOTE_STRING +.ds STYLE_TYPE_19 EPIGRAPH +.ds STYLE_TYPE_20 FINIS +.ds STYLE_TYPE_21 FOOTER_LEFT +.ds STYLE_TYPE_22 FOOTER_CENTER +.ds STYLE_TYPE_23 FOOTER_CENTRE +.ds STYLE_TYPE_24 FOOTER_RIGHT +.ds STYLE_TYPE_25 FOOTNOTE +.ds STYLE_TYPE_26 HEADER_LEFT +.ds STYLE_TYPE_27 HEADER_CENTER +.ds STYLE_TYPE_28 HEADER_CENTRE +.ds STYLE_TYPE_29 HEADER_RIGHT +.ds STYLE_TYPE_30 LEAD +.ds STYLE_TYPE_31 LINENUMBER +.ds STYLE_TYPE_32 MISC +.ds STYLE_TYPE_33 QUOTE +.ds STYLE_TYPE_34 PAGENUMBER +.ds STYLE_TYPE_35 SUBTITLE +.ds STYLE_TYPE_36 TITLE +.ds STYLE_TYPE_37 TOC_HEADER +. +.nr #LOOP 0 1 +.while \n+[#LOOP]<=37 \{\ +. ALIAS \*[STYLE_TYPE_\n[#LOOP]]_STYLE _STYLE +. ALIAS COVER_\*[STYLE_TYPE_\n[#LOOP]]_STYLE _STYLE +. ALIAS DOC_COVER_\*[STYLE_TYPE_\n[#LOOP]]_STYLE _STYLE +.\} +\# +\# UNDERLINE CONTROL +\# ----------------- +\# *Arguments: +\# [ DOUBLE ] [ [] ] | | +\# *Function: +\# Toggles underlining of the element indicated by the calling alias +\# on or off. Uses #_UNDERLINE_WEIGHT to set the weight, +\# and defines string $_UNDERLINE_GAP. +\# +.MAC _UNDERLINE END +. ds $GET_TITLE_TYPE \\$0 +. substring $GET_TITLE_TYPE -2 +. ie '\\*[$GET_TITLE_TYPE]'NE' \{\ +.\" Called as _UNDERLINE +. ds $GET_TITLE_TYPE \\$0 +. substring $GET_TITLE_TYPE 0 -10 +. ds $TITLE_TYPE \\*[$GET_TITLE_TYPE] +. \} +. el \{\ +.\" Called as _UNDERSCORE +. ds $GET_TITLE_TYPE \\$0 +. substring $GET_TITLE_TYPE 0 -11 +. ds $TITLE_TYPE \\*[$GET_TITLE_TYPE] +. \} +. ds $GET_TITLE_TYPE \\$0 +. substring $GET_TITLE_TYPE 0 2 +. if '\\*[$GET_TITLE_TYPE]'BIB' .ds $TITLE_TYPE BIB_STRING_ +. if '\\*[$GET_TITLE_TYPE]'SUB' .ds $TITLE_TYPE SUBTITLE_ +. ds $GET_TITLE_TYPE \\$0 +. substring $GET_TITLE_TYPE 0 7 +. if '\\*[$GET_TITLE_TYPE]'ENDNOTES' .ds $TITLE_TYPE EN_STRING_ +. ds $GET_TITLE_TYPE \\$0 +. substring $GET_TITLE_TYPE 0 10 +. if '\\*[$GET_TITLE_TYPE]'ENDNOTE_STR' .ds $TITLE_TYPE EN_STRING_ +. if '\\*[$GET_TITLE_TYPE]'ENDNOTE_TIT' .ds $TITLE_TYPE EN_TITLE_ +. ie '\\$1'' .nr #\\*[$TITLE_TYPE]UNDERLINE 1 +. el \{\ +. ie \\n[#NUM_ARGS]=1 \{\ +. ie \B'\\$1' \{\ +. if !\\n[#PRINT_STYLE]=1 \{\ +. \\*[$TITLE_TYPE]UNDERLINE_WEIGHT \\$1 +. nr #\\*[$TITLE_TYPE]UNDERLINE 1 +. \} +. \} +. el \{\ +. ie '\\$1'DOUBLE' .nr #\\*[$TITLE_TYPE]UNDERLINE 2 +. el .nr #\\*[$TITLE_TYPE]UNDERLINE 0 +. \} +. \} +. el \{\ +. if !\\n[#PRINT_STYLE]=1 \{\ +. nr #\\*[$TITLE_TYPE]UNDERLINE 1 +. if '\\$1'DOUBLE' \{\ +. nr #\\*[$TITLE_TYPE]UNDERLINE 2 +. shift +. \} +. \\*[$TITLE_TYPE]UNDERLINE_WEIGHT \\$1 +. if !'\\$2'' \ +. ds $\\*[$TITLE_TYPE]UNDERLINE_GAP \\$2 +. if !'\\$3'' \ +. ds $\\*[$TITLE_TYPE]RULE_GAP \\$3 +. \} +. \} +. \} +. rm $TITLE_TYPE +.END +. +.ALIAS ENDNOTE_STRING_UNDERLINE _UNDERLINE +.ALIAS ENDNOTE_STRING_UNDERSCORE _UNDERLINE +\# +\# DEFAULTS +\# -------- +\# *Arguments: +\# +\# *Function: +\# Sets up defaults if no values are entered prior to START. +\# *Notes: +\# The defaults for $CHAPTER_STRING, $DRAFT_STRING, and +\# $REVISION_STRING are in the COPYSTYLE macro. +\# +.MAC DEFAULTS END +. if !\\n[#DOC_TYPE]=5 \{\ +. ie !d $PAPER \{\ +. PAGEWIDTH \\n[#PAGE_WIDTH]u +. PAGELENGTH \\n[.p]u +. \} +. el .PAPER \\*[$PAPER] +. \} +. if !\\n[#DOC_TYPE] .DOCTYPE DEFAULT +. if !r #CH_NUM .nr #CH_NUM 1 +. ie \\n[#PAGENUM_STYLE_SET] .PAGENUM_STYLE \\*[$PAGENUM_STYLE] +. el \ +. if !\\n[#COPY_STYLE]=1 .PAGENUM_STYLE DIGIT +. if !\\n[#COPY_STYLE] .COPYSTYLE FINAL +. if \\n[#DRAFT_WITH_PAGENUM] .COPYSTYLE \\*[$COPY_STYLE] +. if \\n[#DOC_TYPE]=4 \{\ +. if !\\n[#USER_SET_L_LENGTH] \{\ +. R_MARGIN \\n[#R_MARGIN]u +. rr #USER_SET_L_LENGTH +. \} +. if \\n[#PRINT_STYLE]=1 .PRINTSTYLE TYPEWRITE SINGLESPACE +. \} +. if \\n[#COPY_STYLE]=1 \{\ +. COPYSTYLE DRAFT +. PAGENUMBER 1 +. \} +. if !r #DOC_HEADER .DOCHEADER +. if !r #HEADERS_ON .HEADERS +. if !r #PAGINATE .PAGINATE +. if !r #HEADER_MARGIN .HEADER_MARGIN 4P+6p +. if !r #HEADER_GAP .HEADER_GAP 3P +. if \\n[#FOOTERS_ON] \{\ +. HEADERS OFF +. ie \\n[#PAGINATE] \ +. if \\n[#PAGE_NUM_POS_SET]=0 .PAGENUM_POS TOP CENTER +. el \ +. if !\\n[#T_MARGIN] .T_MARGIN 6P +. \} +. if !\\n[#HEADERS_ON] \{\ +. if !\\n[#FOOTERS_ON] \{\ +. ie \\n[#PAGE_NUM_V_POS]=1 \{\ +. HEADER_MARGIN \\n[#HEADER_MARGIN] +. HEADER_GAP \\n[#HEADER_GAP] +. \} +. el .if !r #T_MARGIN .T_MARGIN 6P +. \} +. \} +. if !r #T_MARGIN \ +. T_MARGIN \\n[#HEADER_MARGIN]+\\n[#HEADER_GAP] +. if !r #DOCHEADER_ADVANCE \ +. nr #DOCHEADER_ADVANCE \\n[#T_MARGIN] +. if !r #FOOTER_MARGIN .FOOTER_MARGIN 3P +. if !r #FOOTER_GAP .FOOTER_GAP 3P +. if !r #B_MARGIN \ +. B_MARGIN \\n[#FOOTER_MARGIN]u+\\n[#FOOTER_GAP]u +. if !\\n[#HEADER_RULE_GAP] .HEADER_RULE_GAP 4p +. if !\\n[#FOOTER_RULE_GAP] .FOOTER_RULE_GAP 4p +. if !r #HDRFTR_RULE .HDRFTR_RULE +. if !r #PAGE_NUM_SET .PAGENUMBER 1 +.\" Read in number registers and strings for type parameters +. nr #DOC_L_MARGIN \\n[#L_MARGIN] +. nr #DOC_L_LENGTH \\n[#L_LENGTH] +. nr #DOC_R_MARGIN \\n[#PAGE_WIDTH]-(\\n[#DOC_L_MARGIN]+\\n[#L_LENGTH]) +. ie !'\\*[$SAVED_DOC_FAM]'' \{\ +. ds $DOC_FAM \\*[$SAVED_DOC_FAM] +. rm $SAVED_DOC_FAM +. \} +. el .ds $DOC_FAM \\*[$FAMILY] +. ie !r #DOC_PT_SIZE .nr #DOC_PT_SIZE \\n[#PT_SIZE] +. el \ +. if !\\n[#DOC_PT_SIZE]=\\n[#PT_SIZE] \ +. nr #DOC_PT_SIZE \\n[#PT_SIZE] +. if \\n[#TOC] .nr #DOC_PT_SIZE \\n[#TOC_PS] +. if \\n[#ENDNOTES] .nr #DOC_PT_SIZE \\n[#EN_PS] +. if \\n[#BIBLIOGRAPHY] .nr #DOC_PT_SIZE \\n[#BIB_PS] +. if \ +(\\n[#TOC]=0)&\ +(\\n[#LIST_OF_FIGURES]=0)&\ +(\\n[#LIST_OF_TABLES]=0)&\ +(\\n[#LIST_OF_EQUATIONS]=0) \ +. nr #DOC_LEAD \\n[.v] +. nr #DOC@LEAD \\n[#DOC_LEAD] +. if \\n[#AUTO_LEAD] .nr #DOC_AUTOLEAD \\n[#AUTOLEAD_VALUE] +.\" #SAVED_DOC_LEAD is set in COLLATE +. if \\n[#SAVED_DOC_LEAD] \{\ +. if \ +(\\n[#TOC]=0)&\ +(\\n[#LIST_OF_FIGURES]=0)&\ +(\\n[#LIST_OF_TABLES]=0)&\ +(\\n[#LIST_OF_EQUATIONS]=0) \{\ +. ie !\\n[#DOC_LEAD]=\\n[#SAVED_DOC_LEAD] .nr #RERUN_TRAPS 1 +. el .nr #SKIP_TRAPS 1 +. \} +. \} +. ie \\n[#ADJ_DOC_LEAD]=1 . +. el \ +. if !\\n[#DOC_LEAD_ADJUST_OFF] .DOC_LEAD_ADJUST +. ie d$RESTORE_DOC_QUAD \{\ +. ds $DOC_QUAD \\*[$RESTORE_DOC_QUAD] +. rm $RESTORE_DOC_QUAD +. \} +. el .ds $DOC_QUAD \\*[$QUAD_VALUE] +. if '\\*[$FONT]'' .FT R +. if '\\*[$PP_FT]'' .ds $PP_FT \\*[$FONT] +. FT \\*[$PP_FT] +.\" Counters +. nr #PP 0 +. nr #FN_NUMBER 0 1 +. nr #EN_NUMBER 0 1 +. nr #FN_COUNT_FOR_COLS 0 1 +. nr #DONE_ONCE 0 1 +.\" Enable shimming if user hasn't turned it off +. if \\n[#NO_SHIM]=2 \{\ +. rr #NO_SHIM +. nr #NO_FLEX 1 +. \} +.\" General style defaults for both PRINTSTYLEs +. nr #PP_STYLE 1 +. PARA_INDENT \\n[#PP_INDENT]u +. if !d $HDRFTR_FAM .ds $HDRFTR_FAM \\*[$DOC_FAM] +. if !d $HDRFTR_SIZE_CHANGE .HDRFTR_SIZE +0 +. if !d $PAGE_NUM_FAM .PAGENUM_FAMILY \\*[$DOC_FAM] +. if !d $PAGE_NUM_FT .PAGENUM_FONT R +. if !d $PAGE_NUM_SIZE_CHANGE .PAGENUM_SIZE +0 +. if !r #PAGE_NUM_POS_SET .PAGENUM_POS BOTTOM CENTER +. ie \\n[#PAGE_NUM_HYPHENS_SET] \{\ +. if \\n[#PAGE_NUM_HYPHENS]=0 .PAGENUM_HYPHENS OFF +. if \\n[#PAGE_NUM_HYPHENS]=1 .PAGENUM_HYPHENS +. \} +. el \ +. if !d$PAGENUM_STRING .PAGENUM_HYPHENS +. if !d $FN_FAM .FOOTNOTE_FAMILY \\*[$DOC_FAM] +. if !d $FN_FT .FOOTNOTE_FONT R +. if !d $FN_QUAD .FOOTNOTE_QUAD \\*[$DOC_QUAD] +. if !r #FN_RULE .FOOTNOTE_RULE +. if !r #FN_MARKERS .FOOTNOTE_MARKERS +. if \\n[#FN_MARKERS]=1 \{\ +. if \\n[#FN_REF]=1 \ +. if !\\n[#FN_MARKER_STYLE] .FOOTNOTE_MARKER_STYLE NUMBER +. if !\\n[#FN_MARKER_STYLE] .FOOTNOTE_MARKER_STYLE STAR +. \} +. if !r #EN_MARKER_STYLE .ENDNOTE_MARKER_STYLE SUPERSCRIPT +. if !d $EN_PN_STYLE .ENDNOTES_PAGENUM_STYLE digit +. if !d $EN_FAM .ENDNOTE_FAMILY \\*[$DOC_FAM] +. if !d $EN_FT .ENDNOTE_FONT R +. if !d $EN_QUAD \{\ +. ds quad-check \\*[$DOC_QUAD] +. substring quad-check 0 0 +. if '\\*[$DOC_QUAD]'C' .nr quad-check 1 +. if '\\*[$DOC_QUAD]'R' .nr quad-check 1 +. ie \\n[quad-check] .ENDNOTE_QUAD J +. el .ENDNOTE_QUAD \\*[$DOC_QUAD] +. rr quad-check +. \} +. if !d $EN_STRING .ENDNOTES_HEADER_STRING "Endnotes" +. if !d $EN_STRING_FAM .ENDNOTES_HEADER_FAMILY \\*[$EN_FAM] +. if !d $EN_STRING_QUAD .ENDNOTES_HEADER_QUAD CENTER +. if !d $EN_TITLE \{\ +. ie \\n[#DOC_TYPE]=2 \{\ +. ie !'\\*[$CHAPTER_TITLE_1]'' \{\ +. ie '\\*[$CHAPTER]'' .ENDNOTE_TITLE "\\*[$CHAPTER_TITLE]" +. el .ENDNOTE_TITLE \ +"\\*[$CHAPTER_STRING] \\*[$CHAPTER]: \\*[$CHAPTER_TITLE]" +. \} +. el \{\ +. ie '\\*[$CHAPTER]'' .ENDNOTE_TITLE "\\*[$CHAPTER_STRING]" +. el .ENDNOTE_TITLE "\\*[$CHAPTER_STRING] \\*[$CHAPTER]" +. \} +. \} +. el .ENDNOTE_TITLE "\\*[$TITLE]" +. \} +. if !d $EN_TITLE_FAM .ENDNOTE_TITLE_FAMILY \\*[$EN_FAM] +. if !d $EN_TITLE_QUAD .ENDNOTE_TITLE_QUAD LEFT +. if !d $EN_NUMBER_FAM .ENDNOTE_NUMBER_FAMILY \\*[$EN_FAM] +. if !d $EN_LN_FAM .ENDNOTE_LINENUMBER_FAMILY \\*[$EN_FAM] +. if !r #EN_NUMBERS_ALIGN_LEFT \{\ +. if !r #EN_NUMBERS_ALIGN_RIGHT \{\ +. ie !\\n[#EN_MARKER_STYLE]=2 .ENDNOTE_NUMBERS_ALIGN RIGHT 2 +. el .ENDNOTE_NUMBERS_ALIGN RIGHT 4 +. \} +. \} +. if !r #EN_LN_GAP .ENDNOTE_LINENUMBER_GAP 1m +. if !r #EN_ALLOWS_HEADERS .ENDNOTES_ALLOWS_HEADERS +. if !d $BIB_PN_STYLE .BIBLIOGRAPHY_PAGENUM_STYLE digit +. if !d $BIB_FAM .BIBLIOGRAPHY_FAMILY \\*[$DOC_FAM] +. if !d $BIB_FT .BIBLIOGRAPHY_FONT R +. if !d $BIB_QUAD \{\ +. ds quad-check \\*[$DOC_QUAD] +. substring quad-check 0 0 +. if '\\*[$DOC_QUAD]'C' .nr quad-check 1 +. if '\\*[$DOC_QUAD]'R' .nr quad-check 1 +. ie \\n[quad-check] .BIBLIOGRAPHY_QUAD J +. el .BIBLIOGRAPHY_QUAD \\*[$DOC_QUAD] +. rr quad-check +. \} +. if !d $BIB_STRING .BIBLIOGRAPHY_STRING "Bibliography" +. if !d $BIB_STRING_FAM .BIBLIOGRAPHY_STRING_FAMILY \\*[$BIB_FAM] +. if !d $BIB_STRING_QUAD .BIBLIOGRAPHY_STRING_QUAD CENTER +. if !d $TOC_HEADER_STRING .TOC_HEADER_STRING "Contents" +. if !d $TOC_HEADER_QUAD .TOC_HEADER_QUAD LEFT +. if !d $TOC_PN_STYLE .TOC_PAGENUM_STYLE roman +. if !r #TOC_PN_PADDING .TOC_PADDING 3 +.\" Line numbering +. if !r #LN_GUTTER .nr #LN_GUTTER 2 +. if !r #Q_LN_GUTTER .nr #Q_LN_GUTTER 2 +. if !r #BQ_LN_GUTTER .nr #BQ_LN_GUTTER 2 +. if !d $LN_FAM .ds $LN_FAM \\*[$DOC_FAM] +. if !d $LN_FT .ds $LN_FT R +. if !d $LN_SIZE_CHANGE .ds $LN_SIZE_CHANGE +0 +. if !d $LN_COLOR .ds $LN_COLOR black +.\" PDF link colour +. if !\\n[PDFHREF_COLOR_SET] .PDF_LINK_COLOR 0.0 0.3 0.9 +.\" PDF frame +. if !d pdf-img:frame-weight .ds pdf-img:frame-weight .5 +. if !d pdf-img:frame-color .ds pdf-img:frame-color black +.\" Captions, labels, sources +.\" All at default doc specs except leading, which is autolead 2 +. nr label-type-counter 0 1 +. while \\n+[label-type-counter]<=5 \{\ +. if \\n[label-type-counter]=1 .ds label-type eqn +. if \\n[label-type-counter]=2 .ds label-type pdf-img +. if \\n[label-type-counter]=3 .ds label-type pic +. if \\n[label-type-counter]=4 .ds label-type tbl +. if \\n[label-type-counter]=5 .ds label-type floating +. nr spec-type-counter 0 1 +. while \\n+[spec-type-counter]<=3 \{\ +. if \\n[spec-type-counter]=1 .ds spec-type label +. if \\n[spec-type-counter]=2 .ds spec-type caption +. if \\n[spec-type-counter]=3 .ds spec-type source +. set-defaults +. set-inline-specs +. \} +. rm label-type +. rm spec-type +. \} +.\" String defaults for both PRINTSTYLEs +. ie \\n[#DOC_TYPE]=1 \{\ +. ie '\\*[$DOCTITLE]'' \{\ +. if \\n[#USER_DEF_HDRFTR_LEFT]=0 .ds $HDRFTR_LEFT \\*[$AUTHOR_1] +. if \\n[#USER_DEF_HDRFTR_RIGHT]=0 .ds $HDRFTR_RIGHT \\*[$TITLE] +. \} +. el \{\ +. if \\n[#COPY_STYLE]=1 .DRAFT_WITH_PAGENUMBER +. if \\n[#USER_DEF_HDRFTR_LEFT]=0 .ds $HDRFTR_LEFT \\*[$AUTHOR_1] +. if \\n[#USER_DEF_HDRFTR_CENTER]=0 .ds $HDRFTR_CENTER \\*[$TITLE] +. if \\n[#USER_DEF_HDRFTR_RIGHT]=0 .ds $HDRFTR_RIGHT \\*[$DOCTITLE] +. \} +. \} +. el \{\ +. if \\n[#USER_DEF_HDRFTR_LEFT]=0 .ds $HDRFTR_LEFT \\*[$AUTHOR_1] +. if \\n[#USER_DEF_HDRFTR_RIGHT]=0 .ds $HDRFTR_RIGHT \\*[$TITLE] +. \} +. if !d $ATTRIBUTE_STRING .ds $ATTRIBUTE_STRING by +. if !d $FINIS_STRING .FINIS_STRING "End" +. if !r #FINIS_STRING_CAPS .nr #FINIS_STRING_CAPS 1 +.\" Covers +. if !r #DOC_COVERS_OFF .nr #DOC_COVERS 1 +. if !r #COVERS_OFF .nr #COVERS 1 +. if !d $COVER_COPYRIGHT_QUAD .COVER_COPYRIGHT_QUAD R +. if !d $COVER_MISC_QUAD .COVER_MISC_QUAD L +. if !d $MISC_QUAD .MISC_QUAD L +. if !d $DOC_COVER_COPYRIGHT_QUAD .DOC_COVER_COPYRIGHT_QUAD R +. if !d $DOC_COVER_MISC_QUAD .DOC_COVER_MISC_QUAD L +.\" Defaults for printstyle TYPEWRITE +. if \\n[#PRINT_STYLE]=1 \{\ +. TYPEWRITER +. SS DEFAULT +. if \\n[#UNDERLINE_QUOTES]=1 .UNDERLINE_QUOTES +. if \\n[#UNDERLINE_QUOTES]=0 .UNDERLINE_QUOTES OFF +. if !\\n[#HDRFTR_PLAIN] \{\ +. if !r #HDRFTR_RIGHT_CAPS .nr #HDRFTR_RIGHT_CAPS 1 +. if \\n[#HDRFTR_RIGHT_CAPS]=0 \ +. if !d $HDRFTR_RIGHT_SIZE_CHANGE .HDRFTR_RIGHT_SIZE +0 +. \} +.\" +Doctype underlining (if NAMED) +. if !r #DOCTYPE_UNDERLINE .nr #DOCTYPE_UNDERLINE 1 +.\" +Quotes and blockquotes +. if !r #Q_OFFSET_VALUE \ +. if '\\*[$Q_OFFSET_VALUE]'' \ +. QUOTE_INDENT \\n[#PP_INDENT]u+(\\n[#PP_INDENT]u/2u) +. if !d $Q_QUAD .QUOTE_LEFT +. if !d $BQUOTE_QUAD .BLOCKQUOTE_QUAD LEFT +. if !r #BQ_OFFSET_VALUE \ +. if '\\*[$BQ_OFFSET_VALUE]'' \ +. BLOCKQUOTE_INDENT \\n[#PP_INDENT]u+(\\n[#PP_INDENT]u/2u) +.\" +Epigraphs +. if !r #EPI_OFFSET_VALUE \ +. if '\\*[$EPI_OFFSET_VALUE]'' .EPIGRAPH_INDENT 2 +.\" +Linebreaks +. if !d $LINEBREAK_CHAR .LINEBREAK_CHAR * 3 2p +.\" +Footnotes +. if !d $FN_SIZE_CHANGE .FOOTNOTE_SIZE +0 +. if !r #FN_RULE_LENGTH .FOOTNOTE_RULE_LENGTH 2i +.\" +Endnotes +. if !r #EN_PP_INDENT .ENDNOTE_PARA_INDENT \\n[#PP_INDENT] +. if !r #EN_STRING_CAPS .ENDNOTES_HEADER_CAPS +. if !r #EN_STRING_UNDERLINE .nr #EN_STRING_UNDERLINE 2 +.\" +Footnotes +. if !r #FN_RULE_ADJ .FOOTNOTE_RULE_ADJ 6p +.\" +Slant stuff +. if !r #SLANT_MEANS_SLANT \{\ +. ie \\n[#UNDERLINE_SLANT]=1 .UNDERLINE_SLANT +. el .UNDERLINE_SLANT OFF +. \} +.\" +Bibliography +. if !r #BIB_STRING_UNDERLINE .nr #BIB_STRING_UNDERLINE 2 +. if !r #BIB_STRING_CAPS .BIBLIOGRAPHY_STRING_CAPS +. \} +.\" Defaults for printstyle TYPESET +. if \\n[#PRINT_STYLE]=2 \{\ +. if !d $DOCHEADER_LEAD_ADJ .DOCHEADER_LEAD +0 +.\" +Cover +. if !d $COVER_LEAD_ADJ .COVER_LEAD +0 +. if !d $COVER_FAM .COVER_FAMILY \\*[$DOC_FAM] +.\" (title) +. if !d $COVER_TITLE_FAM \{\ +. ie !d $COVER_FAM .COVER_TITLE_FAMILY \\*[$DOC_FAM] +. el .COVER_TITLE_FAMILY \\*[$COVER_FAM] +. \} +. if !d $COVER_TITLE_FT .COVER_TITLE_FONT B +. if !d $COVER_TITLE_SIZE_CHANGE .COVER_TITLE_SIZE +3.5 +.\" (doctitle) +. if !d $COVER_DOCTITLE_FAM \{\ +. ie !d $DOC_COVER_FAM .COVER_DOCTITLE_FAMILY \\*[$DOC_FAM] +. el .COVER_DOCTITLE_FAMILY \\*[$COVER_FAM] +. \} +. if !d $COVER_DOCTITLE_FT .COVER_DOCTITLE_FONT B +. if !d $COVER_DOCTITLE_SIZE_CHANGE .COVER_DOCTITLE_SIZE +3.5 +.\" (covertitle) +. if !d $COVER_COVERTITLE_FAM \{\ +. ie !d $COVER_FAM .COVER_COVERTITLE_FAMILY \\*[$DOC_FAM] +. el .COVER_COVERTITLE_FAMILY \\*[$COVER_FAM] +. \} +. if !d $COVER_COVERTITLE_FT .COVER_COVERTITLE_FONT B +. if !d $COVER_COVERTITLE_SIZE_CHANGE .COVER_COVERTITLE_SIZE +3.5 +.\" (doc_covertitle) +. if !d $COVER_DOC_COVERTITLE_FAM \{\ +. ie !d $COVER_FAM .COVER_DOC_COVERTITLE_FAMILY \\*[$DOC_FAM] +. el .COVER_DOC_COVERTITLE_FAMILY \\*[$COVER_FAM] +. \} +. if !d $COVER_DOC_COVERTITLE_FT .COVER_DOC_COVERTITLE_FONT B +. if !d $COVER_DOC_COVERTITLE_SIZE_CHANGE .COVER_DOC_COVERTITLE_SIZE +3.5 +.\" (chapter) +. if !d $COVER_CHAPTER_FAM \{\ +. ie !d $COVER_FAM .COVER_CHAPTER_FAMILY \\*[$DOC_FAM] +. el .COVER_CHAPTER_FAMILY \\*[$COVER_FAM] +. \} +. if !d $COVER_CHAPTER_FT .COVER_CHAPTER_FONT B +. if !d $COVER_CHAPTER_SIZE_CHANGE .COVER_CHAPTER_SIZE +3.5 +.\" (chapter title) +. if !d $COVER_CHAPTER_TITLE_FAM \{\ +. ie !d $COVER_FAM .COVER_CHAPTER_TITLE_FAMILY \\*[$DOC_FAM] +. el .COVER_CHAPTER_TITLE_FAMILY \\*[$COVER_FAM] +. \} +. if !d $COVER_CHAPTER_TITLE_FT .COVER_CHAPTER_TITLE_FONT BI +. if !d $COVER_CHAPTER_TITLE_SIZE_CHANGE .COVER_CHAPTER_TITLE_SIZE +4 +.\" (subtitle) +. if !d $COVER_SUBTITLE_FAM \{\ +. ie !d $COVER_FAM .COVER_SUBTITLE_FAMILY \\*[$DOC_FAM] +. el .COVER_SUBTITLE_FAMILY \\*[$COVER_FAM] +. \} +. if !d $COVER_SUBTITLE_FT .COVER_SUBTITLE_FONT R +. if !d $COVER_SUBTITLE_SIZE_CHANGE .COVER_SUBTITLE_SIZE +0 +.\" (attribution and author[s]) +. if !d $COVER_ATTRIBUTE_FAM \{\ +. ie !d $COVER_FAM .COVER_ATTRIBUTE_FAMILY \\*[$DOC_FAM] +. el .COVER_ATTRIBUTE_FAMILY \\*[$COVER_FAM] +. \} +. if !d $COVER_ATTRIBUTE_FT .COVER_ATTRIBUTE_FONT I +. if !d $COVER_ATTRIBUTE_SIZE_CHANGE .COVER_ATTRIBUTE_SIZE +0 +. if !d $COVER_AUTHOR_FAM \{\ +. ie !d $COVER_FAM .COVER_AUTHOR_FAMILY \\*[$DOC_FAM] +. el .COVER_AUTHOR_FAMILY \\*[$COVER_FAM] +. \} +. if !d $COVER_AUTHOR_FT .COVER_AUTHOR_FONT I +. if !d $COVER_AUTHOR_SIZE_CHANGE .COVER_AUTHOR_SIZE +0 +.\" (doctype if "named") +. if !d $COVER_DOCTYPE_FAM \{\ +. ie !d $COVER_FAM .COVER_DOCTYPE_FAMILY \\*[$DOC_FAM] +. el .COVER_DOCTYPE_FAMILY \\*[$COVER_FAM] +. \} +. if !d $COVER_DOCTYPE_FT .COVER_DOCTYPE_FONT BI +. if !d $COVER_DOCTYPE_SIZE_CHANGE .COVER_DOCTYPE_SIZE +3 +.\" (copyright) +. if !d $COVER_COPYRIGHT_FAM \{\ +. ie !d $COVER_FAM .COVER_COPYRIGHT_FAMILY \\*[$DOC_FAM] +. el .COVER_COPYRIGHT_FAMILY \\*[$COVER_FAM] +. \} +. if !d $COVER_COPYRIGHT_FT .COVER_COPYRIGHT_FONT R +. if !d $COVER_COPYRIGHT_SIZE_CHANGE .COVER_COPYRIGHT_SIZE -2 +.\" (misc) +. if !d $COVER_MISC_FAM .COVER_MISC_FAMILY \\*[$DOC_FAM] +. if !d $COVER_MISC_FT .COVER_MISC_FONT R +. if !d $COVER_MISC_SIZE_CHANGE .COVER_MISC_SIZE -2 +. if !r #COVER_MISC_LEAD .COVER_MISC_LEAD 14.5 +.\" +Doc cover +. if !d $DOC_COVER_LEAD_ADJ .DOC_COVER_LEAD +0 +. if !d $DOC_COVER_FAM .DOC_COVER_FAMILY \\*[$DOC_FAM] +.\" (title) +. if !d $DOC_COVER_TITLE_FAM \{\ +. ie !d $DOC_COVER_FAM .DOC_COVER_TITLE_FAMILY \\*[$DOC_FAM] +. el .DOC_COVER_TITLE_FAMILY \\*[$DOC_COVER_FAM] +. \} +. if !d $DOC_COVER_TITLE_FT .DOC_COVER_TITLE_FONT B +. if !d $DOC_COVER_TITLE_SIZE_CHANGE .DOC_COVER_TITLE_SIZE +3.5 +.\" (doctitle) +. if !d $DOC_COVER_DOCTITLE_FAM \{\ +. ie !d $DOC_COVER_FAM .DOC_COVER_DOCTITLE_FAMILY \\*[$DOC_FAM] +. el .DOC_COVER_DOCTITLE_FAMILY \\*[$DOC_COVER_FAM] +. \} +. if !d $DOC_COVER_DOCTITLE_FT .DOC_COVER_DOCTITLE_FONT B +. if !d $DOC_COVER_DOCTITLE_SIZE_CHANGE .DOC_COVER_DOCTITLE_SIZE +3.5 +.\" (covertitle) +. if !d $DOC_COVER_COVERTITLE_FAM \{\ +. ie !d $COVER_FAM .DOC_COVER_COVERTITLE_FAMILY \\*[$DOC_FAM] +. el .DOC_COVER_COVERTITLE_FAMILY \\*[$COVER_FAM] +. \} +. if !d $DOC_COVER_COVERTITLE_FT .DOC_COVER_COVERTITLE_FONT B +. if !d $DOC_COVER_COVERTITLE_SIZE_CHANGE .DOC_COVER_COVERTITLE_SIZE +3.5 +.\" (doc_covertitle) +. if !d $DOC_COVER_DOC_COVERTITLE_FAM \{\ +. ie !d $COVER_FAM .DOC_COVER_DOC_COVERTITLE_FAMILY \\*[$DOC_FAM] +. el .DOC_COVER_DOC_COVERTITLE_FAMILY \\*[$COVER_FAM] +. \} +. if !d $DOC_COVER_DOC_COVERTITLE_FT .DOC_COVER_DOC_COVERTITLE_FONT B +. if !d $DOC_COVER_DOC_COVERTITLE_SIZE_CHANGE .DOC_COVER_DOC_COVERTITLE_SIZE +3.5 +.\" (chapter) +. if !d $DOC_COVER_CHAPTER_FAM \{\ +. ie !d $DOC_COVER_FAM .DOC_COVER_CHAPTER_FAMILY \\*[$DOC_FAM] +. el .DOC_COVER_CHAPTER_FAMILY \\*[$DOC_COVER_FAM] +. \} +. if !d $DOC_COVER_CHAPTER_FT .DOC_COVER_CHAPTER_FONT B +. if !d $DOC_COVER_CHAPTER_SIZE_CHANGE .DOC_COVER_CHAPTER_SIZE +3.5 +.\" (chapter title) +. if !d $DOC_COVER_CHAPTER_TITLE_FAM \{\ +. ie !d $DOC_COVER_FAM .DOC_COVER_CHAPTER_TITLE_FAMILY \\*[$DOC_FAM] +. el .DOC_COVER_CHAPTER_TITLE_FAMILY \\*[$DOC_COVER_FAM] +. \} +. if !d $DOC_COVER_CHAPTER_TITLE_FT .DOC_COVER_CHAPTER_TITLE_FONT BI +. if !d $DOC_COVER_CHAPTER_TITLE_SIZE_CHANGE .DOC_COVER_CHAPTER_TITLE_SIZE +4 +.\" (subtitle) +. if !d $DOC_COVER_SUBTITLE_FAM \{\ +. ie !d $DOC_COVER_FAM .DOC_COVER_SUBTITLE_FAMILY \\*[$DOC_FAM] +. el .DOC_COVER_SUBTITLE_FAMILY \\*[$DOC_COVER_FAM] +. \} +. if !d $DOC_COVER_SUBTITLE_FT .DOC_COVER_SUBTITLE_FONT R +. if !d $DOC_COVER_SUBTITLE_SIZE_CHANGE .DOC_COVER_SUBTITLE_SIZE +0 +.\" (attribution and author[s]) +. if !d $DOC_COVER_ATTRIBUTE_FAM \{\ +. ie !d $DOC_COVER_FAM .DOC_COVER_ATTRIBUTE_FAMILY \\*[$DOC_FAM] +. el .DOC_COVER_ATTRIBUTE_FAMILY \\*[$DOC_COVER_FAM] +. \} +. if !d $DOC_COVER_ATTRIBUTE_FT .DOC_COVER_ATTRIBUTE_FONT I +. if !d $DOC_COVER_ATTRIBUTE_SIZE_CHANGE .DOC_COVER_ATTRIBUTE_SIZE +0 +. if !d $DOC_COVER_AUTHOR_FAM \{\ +. ie !d $DOC_COVER_FAM .DOC_COVER_AUTHOR_FAMILY \\*[$DOC_FAM] +. el .DOC_COVER_AUTHOR_FAMILY \\*[$DOC_COVER_FAM] +. \} +. if !d $DOC_COVER_AUTHOR_FT .DOC_COVER_AUTHOR_FONT I +. if !d $DOC_COVER_AUTHOR_SIZE_CHANGE .DOC_COVER_AUTHOR_SIZE +0 +.\" (doctype if "named") +. if !d $DOC_COVER_DOCTYPE_FAM \{\ +. ie !d $DOC_COVER_FAM .DOC_COVER_DOCTYPE_FAMILY \\*[$DOC_FAM] +. el .DOC_COVER_DOCTYPE_FAMILY \\*[$DOC_COVER_FAM] +. \} +. if !d $DOC_COVER_DOCTYPE_FT .DOC_COVER_DOCTYPE_FONT BI +. if !d $DOC_COVER_DOCTYPE_SIZE_CHANGE .DOC_COVER_DOCTYPE_SIZE +3 +.\" (copyright) +. if !d $DOC_COVER_COPYRIGHT_FAM \{\ +. ie !d $DOC_COVER_FAM .DOC_COVER_COPYRIGHT_FAMILY \\*[$DOC_FAM] +. el .DOC_COVER_COPYRIGHT_FAMILY \\*[$DOC_COVER_FAM] +. \} +. if !d $DOC_COVER_COPYRIGHT_FT .DOC_COVER_COPYRIGHT_FONT R +. if !d $DOC_COVER_COPYRIGHT_SIZE_CHANGE .DOC_COVER_COPYRIGHT_SIZE -2 +.\" (misc) +. if !d $DOC_COVER_MISC_FAM .DOC_COVER_MISC_FAMILY \\*[$DOC_FAM] +. if !d $DOC_COVER_MISC_FT .DOC_COVER_MISC_FONT R +. if !d $DOC_COVER_MISC_SIZE_CHANGE .DOC_COVER_MISC_SIZE -2 +. if !r #DOC_COVER_MISC_LEAD .DOC_COVER_MISC_LEAD 14.5 +.\" +Docheader +. if !d $DOCHEADER_FAM .DOCHEADER_FAMILY \\*[$DOC_FAM] +. if !d $TITLE_FAM \{\ +. ie !d $DOCHEADER_FAM .TITLE_FAMILY \\*[$DOC_FAM] +. el .TITLE_FAMILY \\*[$DOCHEADER_FAM] +. \} +. if !d $TITLE_FT .TITLE_FONT B +.\" Title size change +. if !d $TITLE_SIZE_CHANGE \{\ +. ie \\n[#DOC_TYPE]=2 .TITLE_SIZE +4 +. el .TITLE_SIZE +3.5 +. \} +. if !d $CHAPTER_FAM \{\ +. ie !d $DOCHEADER_FAM .CHAPTER_FAMILY \\*[$DOC_FAM] +. el .CHAPTER_FAMILY \\*[$DOCHEADER_FAM] +. \} +. if !d $CHAPTER_FT .CHAPTER_FONT B +. if !d $CHAPTER_SIZE_CHANGE .CHAPTER_SIZE +4 +. if !d $CHAPTER_TITLE_FAM \{\ +. ie !d $DOCHEADER_FAM .CHAPTER_TITLE_FAMILY \\*[$DOC_FAM] +. el .CHAPTER_TITLE_FAMILY \\*[$DOCHEADER_FAM] +. \} +. if !d $CHAPTER_TITLE_FT .CHAPTER_TITLE_FONT BI +. if !d $CHAPTER_TITLE_SIZE_CHANGE .CHAPTER_TITLE_SIZE +4 +. if !d $SUBTITLE_FAM \{\ +. ie !d $DOCHEADER_FAM .SUBTITLE_FAMILY \\*[$DOC_FAM] +. el .SUBTITLE_FAMILY \\*[$DOCHEADER_FAM] +. \} +. if !d $SUBTITLE_FT .SUBTITLE_FONT R +. if !d $SUBTITLE_SIZE_CHANGE .SUBTITLE_SIZE +0 +. if !d $ATTRIBUTE_FAM \{\ +. ie !d $DOCHEADER_FAM .ATTRIBUTE_FAMILY \\*[$DOC_FAM] +. el .ATTRIBUTE_FAMILY \\*[$DOCHEADER_FAM] +. \} +. if !d $ATTRIBUTE_FT .ATTRIBUTE_FONT I +. if !d $ATTRIBUTE_SIZE_CHANGE .ATTRIBUTE_SIZE +0 +. if !d $AUTHOR_FAM \{\ +. ie !d $DOCHEADER_FAM .AUTHOR_FAMILY \\*[$DOC_FAM] +. el .AUTHOR_FAMILY \\*[$DOCHEADER_FAM] +. \} +. if !d $AUTHOR_FT .AUTHOR_FONT I +. if !d $AUTHOR_SIZE_CHANGE .AUTHOR_SIZE +0 +. if !d $DOCTYPE_FAM \{\ +. ie !d $DOCHEADER_FAM .DOCTYPE_FAMILY \\*[$DOC_FAM] +. el .DOCTYPE_FAMILY \\*[$DOCHEADER_FAM] +. \} +. if !d $DOCTYPE_FT .DOCTYPE_FONT BI +. if !d $DOCTYPE_SIZE_CHANGE .DOCTYPE_SIZE +3 +.\" +Headers and footers +. if !\\n[#HDRFTR_PLAIN] \{\ +. if !d $HDRFTR_LEFT_FAM \ +. HDRFTR_LEFT_FAMILY \\*[$DOC_FAM] +. if !d $HDRFTR_LEFT_FT \ +. HDRFTR_LEFT_FONT R +. if \\n[#HDRFTR_LEFT_CAPS] \ +. if !d $HDRFTR_LEFT_SIZE_CHANGE \ +. HDRFTR_LEFT_SIZE -2 +. if !d $HDRFTR_LEFT_SIZE_CHANGE \ +. HDRFTR_LEFT_SIZE -.5 +. if !d $HDRFTR_CENTER_FAM \ +. HDRFTR_CENTER_FAMILY \\*[$DOC_FAM] +. if !d $HDRFTR_CENTER_FT .HDRFTR_CENTER_FONT I +. if \\n[#HDRFTR_CENTER_CAPS] \ +. if !d $HDRFTR_CENTER_SIZE_CHANGE \ +. HDRFTR_CENTER_SIZE -2 +. if !d $HDRFTR_CENTER_SIZE_CHANGE \ +. HDRFTR_CENTER_SIZE -.5 +. if !d $HDRFTR_RIGHT_FAM \ +. HDRFTR_RIGHT_FAMILY \\*[$DOC_FAM] +. if !d $HDRFTR_RIGHT_FT .HDRFTR_RIGHT_FONT R +. ie !r #HDRFTR_RIGHT_CAPS \{\ +. nr #HDRFTR_RIGHT_CAPS 1 +. if !d $HDRFTR_RIGHT_SIZE_CHANGE \ +. HDRFTR_RIGHT_SIZE -2 +. \} +. el \{\ +. if \\n[#HDRFTR_RIGHT_CAPS]=0 \ +. if !d $HDRFTR_RIGHT_SIZE_CHANGE \ +. HDRFTR_RIGHT_SIZE -.5 +. \} +. ie !\\n[#HDRFTR_RIGHT_SMALLCAPS] \{\ +. if \\n[#HDRFTR_RIGHT_CAPS] \ +. if !d $HDRFTR_RIGHT_SIZE_CHANGE \ +. HDRFTR_RIGHT_SIZE -2 +. \} +. el \{\ +. nr #SKIP_CAPS_SMALLCAPS_WARNING 1 +. if \\n[#HDRFTR_RIGHT_CAPS] .HDRFTR_RIGHT_CAPS OFF +. \} +. if !d $HDRFTR_RIGHT_SIZE_CHANGE .HDRFTR_RIGHT_SIZE -.5 +. \} +.\" +Quotes +. if !d $QUOTE_FAM .QUOTE_FAMILY \\*[$DOC_FAM] +. if !d $QUOTE_FT .QUOTE_FONT I +. if !d $QUOTE_SIZE_CHANGE .QUOTE_SIZE +0 +. if !r #Q_OFFSET_VALUE \ +. if '\\*[$Q_OFFSET_VALUE]'' .QUOTE_INDENT 3 +. if !d $Q_QUAD .QUOTE_LEFT +.\" +Blockquotes +.\" Note: the leading for quotes and blockquotes is set after .DEFAULTS in START +. if !d $BQUOTE_FAM .BLOCKQUOTE_FAMILY \\*[$DOC_FAM] +. if !d $BQUOTE_FT .BLOCKQUOTE_FONT R +. if !d $BQUOTE_SIZE_CHANGE .BLOCKQUOTE_SIZE -1 +. if !d $BQUOTE_QUAD .BLOCKQUOTE_QUAD LEFT +. if !r #BQ_OFFSET_VALUE \ +. if '\\*[$BQ_OFFSET_VALUE]'' .BLOCKQUOTE_INDENT 3 +.\" +Epigraphs +. if !d $EPI_FAM .EPIGRAPH_FAMILY \\*[$DOC_FAM] +. if !d $EPI_FT .EPIGRAPH_FONT R +. if !d $EPI_SIZE_CHANGE .EPIGRAPH_SIZE -1.5 +. if !r #EPI_AUTOLEAD .EPIGRAPH_AUTOLEAD 2 +. if !d $EPI_QUAD .EPIGRAPH_QUAD \\*[$DOC_QUAD] +. if !r #EPI_OFFSET_VALUE \ +. if '\\*[$EPI_OFFSET_VALUE]'' .EPIGRAPH_INDENT 3 +.\" +Linebreaks +. if !d $LINEBREAK_CHAR .LINEBREAK_CHAR * 3 3p +. if !d $LINEBREAK_COLOR .LINEBREAK_COLOR black +.\" +Footnotes +. if !r #FN_RULE_LENGTH .FOOTNOTE_RULE_LENGTH 4P +. if !r #FN_RULE_ADJ .FOOTNOTE_RULE_ADJ 3p +. if !d $FN_SIZE_CHANGE .FOOTNOTE_SIZE -2 +. if !r #FN_AUTOLEAD .FOOTNOTE_AUTOLEAD 2 +.\" +Endnotes +. if !r #EN_PS .ENDNOTE_PT_SIZE (\\n[#DOC_PT_SIZE]u) +. if !d $EN_STRING_FT .ENDNOTES_HEADER_FONT B +. if !d $EN_STRING_SIZE_CHANGE .ENDNOTES_HEADER_SIZE +3.5 +. if !d $EN_TITLE_FT .ENDNOTE_TITLE_FONT B +. if !d $EN_TITLE_SIZE_CHANGE .ENDNOTE_TITLE_SIZE +0 +. if !d $EN_NUMBER_FT .ENDNOTE_NUMBER_FONT B +. if !d $EN_LN_FT .ENDNOTE_LINENUMBER_FONT R +. if !d $EN_NUMBER_SIZE_CHANGE .ENDNOTE_NUMBER_SIZE +0 +. if !d $EN_LN_SIZE_CHANGE .ENDNOTE_LINENUMBER_SIZE +0 +. if !r #EN_PP_INDENT .ENDNOTE_PARA_INDENT 1.5m +. if !d $EN_SPACE .ENDNOTE_SPACING 0 +.\" +Bibliography +. if !r #BIB_LIST .BIBLIOGRAPHY_TYPE PLAIN +. if !r #BIB_PS .BIBLIOGRAPHY_PT_SIZE (\\n[#DOC_PT_SIZE]u) +. if !d $BIB_STRING_FT .BIBLIOGRAPHY_STRING_FONT B +. if !d $BIB_STRING_SIZE_CHANGE .BIBLIOGRAPHY_STRING_SIZE +3.5 +.\" +Table of contents +. if !d $TOC_FAM .TOC_FAMILY \\*[$DOC_FAM] +. if !r #TOC_PS .TOC_PT_SIZE (\\n[#DOC_PT_SIZE]u) +. if '\\*[$TOC_LEAD]'' .TOC_LEAD \\n[#DOC@LEAD]u ADJUST +. if !d $TOC_HEADER_FAM .TOC_HEADER_FAMILY \\*[$TOC_FAM] +. if !d $TOC_HEADER_SIZE_CHANGE .TOC_HEADER_SIZE +3.5 +. if !d $TOC_HEADER_FT .TOC_HEADER_FONT B +. if !d $TOC_PN_FAM .TOC_PN_FAMILY \\*[$TOC_FAM] +. if !d $TOC_PN_FT .TOC_PN_FONT R +. if !d $TOC_PN_SIZE_CHANGE .TOC_PN_SIZE +0 +. if !d $TOC_TITLE_FAM .TOC_TITLE_FAMILY \\*[$TOC_FAM] +. \} +.\" +Refer support +. if !r #EN_REF .nr #FN_REF 1 +. if !d $REF_FN_INDENT \{\ +. if \\n[#PRINT_STYLE]=1 .INDENT_REFS FOOTNOTE .5i +. if \\n[#PRINT_STYLE]=2 .INDENT_REFS FOOTNOTE 2m +. \} +. if !d $REF_EN_INDENT \{\ +. if \\n[#PRINT_STYLE]=1 .INDENT_REFS ENDNOTE .5i +. if \\n[#PRINT_STYLE]=2 .INDENT_REFS ENDNOTE 2m +. \} +. if !d $REF_BIB_INDENT \{\ +. if \\n[#PRINT_STYLE]=1 .INDENT_REFS BIBLIO .5i +. if \\n[#PRINT_STYLE]=2 .INDENT_REFS BIBLIO 2m +. \} +.\" Define strings for idem entries +. if \\n[#PRINT_STYLE]=1 .char \[idem] \[hy]\[hy]\[hy] +. if \\n[#PRINT_STYLE]=2 .char \[idem] \v'-.3m'\l'3m'\v'.3m' +.\" Adjust doc leading for PRINTSTYLE TYPESET +. if \\n[#PRINT_STYLE]=2 \ +. if \\n[#ADJ_DOC_LEAD]=1 .DOC_LEAD_ADJUST +.\" This diversion is to get a value for #FN_AUTOLEAD +. di NULL +. if \\n[#AUTO_LEAD] \{\ +. nr #RESTORE_AUTO_LEAD 1 +. nr #SAVED_AUTOLEAD_VALUE \\n[#AUTOLEAD_VALUE] +. \} +. ev NULL +. if \\n[#PRINT_STYLE]=1 \{\ +. ps \\*[$TYPEWRITER_PS] +. ie \\n[#SINGLE_SPACE]=1 .vs \\n[#ORIGINAL_DOC_LEAD]u +. el .vs \\n[#ORIGINAL_DOC_LEAD]u/2u +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. ps \\n[#DOC_PT_SIZE]u\\*[$FN_SIZE_CHANGE] +. vs \\n[.ps]u+\\n[#FN_AUTOLEAD]u +. \} +. nr #FN_LEAD \\n[#LEAD] +. ev +. di +. if \\n[#RESTORE_AUTO_LEAD] \{\ +. nr #AUTO_LEAD 1 +. nr #AUTOLEAD_VALUE \\n[#SAVED_AUTOLEAD_VALUE] +. \} +. if !\\n[#SKIP_TRAPS] .TRAPS +. rr #SKIP_TRAPS +. if \\n[#REMOVE_ADJ] .DOC_LEAD \\n[#DOC_LEAD]u-\\n[#DOC_LEAD_ADJ]u +. if (\\n[#FOOTER_MARGIN]+\\n[.v]>=\\n[#B_MARGIN]) \{\ +. tm1 "[mom]: Your chosen bottom margin for running text is too close to the footer margin. +. tm1 " No footers or bottom-of-page page numbers will be printed. +. tm1 " Please reset B_MARGIN or FOOTER_MARGIN to allow enough space. +. tm1 " If no footers or bottom-of-page page numbers are required, +. tm1 " invoke .FOOTER_MARGIN 0 before .START +. nr #SKIP_FOOTER 1 +. \} +.\" Endnote, bibliography and toc leading +. nr #OK_PROCESS_LEAD 1 +. nr #RESTORE_DOC_LEAD \\n[.v] +. nr #RESTORE_B_MARGIN \\n[#B_MARGIN] +. if \\n[#PRINT_STYLE]=1 \{\ +. ie \\n[#SINGLE_SPACE] \{\ +. ENDNOTE_LEAD 12 ADJUST +. BIBLIOGRAPHY_LEAD 12 ADJUST +. \} +. el \{\ +. ie \\n[#EN_SINGLESPACE] .ENDNOTE_LEAD 12 ADJUST +. el .ENDNOTE_LEAD 24 ADJUST +. ie \\n[#BIB_SINGLESPACE] .BIBLIOGRAPHY_LEAD 12 ADJUST +. el .BIBLIOGRAPHY_LEAD 24 ADJUST +. \} +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. ie !d $EN_LEAD .ENDNOTE_LEAD \\n[#UNADJUSTED_DOC_LEAD]u ADJUST +. el .ENDNOTE_LEAD \\*[$EN_LEAD] \\*[$ADJUST_EN_LEAD] +. ie !d $BIB_LEAD .BIBLIOGRAPHY_LEAD \\n[#UNADJUSTED_DOC_LEAD]u ADJUST +. el .BIBLIOGRAPHY_LEAD \\*[$BIB_LEAD] \\*[$ADJUST_BIB_LEAD] +. ie !d $TOC_LEAD .TOC_LEAD \\n[#UNADJUSTED_DOC_LEAD]u \\*[$ADJUST_TOC_LEAD] +. el .TOC_LEAD \\*[$TOC_LEAD] \\*[$ADJUST_TOC_LEAD] +. \} +. ie !d $BIB_SPACE .BIBLIOGRAPHY_SPACING 0 +. el \{\ +. if \\n[#DEFER_BIB_SPACING]=1 \{\ +. BIBLIOGRAPHY_SPACING \\*[$BIB_SPACE] +. rr #DEFER_BIB_SPACING +. \} +. \} +. nr #DOC_LEAD \\n[#RESTORE_DOC_LEAD]u +. nr #B_MARGIN \\n[#RESTORE_B_MARGIN] +. vs \\n[#DOC_LEAD]u +. if !\\n[#PRINT_STYLE]=1 \{\ +. if \\n[#RERUN_TRAPS] \{\ +. TRAPS +. rr #RERUN_TRAPS +. \} +. \} +.\" Set default heading and toc-entry family if not done already +. nr #HD_LEVEL 0 1 \" loop step +. nr #LOOP 9 \" loop count +. while \\n+[#HD_LEVEL]<=\\n[#LOOP] \{\ +. if '\\*[$HEAD_\\n[#HD_LEVEL]_FAM]'' \ +. ds $HEAD_\\n[#HD_LEVEL]_FAM \\*[$DOC_FAM] +. if '\\*[$HEAD_\\n[#HD_LEVEL]_BASELINE_ADJ]'' \ +. ds $HEAD_\\n[#HD_LEVEL]_BASELINE_ADJ \\n[.v]/10 +. if '\\*[$TOC_HEAD_\\n[#HD_LEVEL]_FAM]'' \ +. ds $TOC_HEAD_\\n[#HD_LEVEL]_FAM \\*[$TOC_FAM] +. \} +. if '\\*[$TOC_TITLE_FAM]'' .TOC_TITLE_FAMILY \\*[$DOC_FAM] +.\" TOC heading (single, non-pagenumbered line insertion) +. if !d $TOC_HEADING_FAM .ds $TOC_HEADING_FAM \\*[$DOC_FAM] +. if !d $TOC_HEADING_FT .ds $TOC_HEADING_FT R +. if !d $TOC_HEADING_SIZE .ds $TOC_HEADING_SIZE +0 +. if !d $TOC_HEADING_COLOR .ds $TOC_HEADING_COLOR black +. if !d $TOC_HEADING_QUAD .ds $TOC_HEADING_QUAD L +. if !d $SPACE_ABOVE .ds $SPACE_ABOVE .75v +. if !d $SPACE_BENEATH .ds $SPACE_BENEATH .25v +.\" Re-run MNinit to capture strings and registers set in DEFAULTS. +. if !'\\*[$MN-arg1]'' \{\ +. MNinit \ +\\*[$MN-arg1] \\*[$MN-arg2] \ +\\*[$MN-arg3] \\*[$MN-arg4] \ +\\*[$MN-arg5] \\*[$MN-arg6] \ +\\*[$MN-arg7] \\*[$MN-arg8] \ +\\*[$MN-arg9] +. \} +. if \\n[#PRINT_STYLE]=1 .nr #IGNORE 1 +. if \\n[#AUTO_LEAD] \{\ +. rr #AUTO_LEAD +. rr #AUTOLEAD_VALUE +. \} +.END +\# +\# ================================================================= +\# +\# Macros and aliases needed for doccover, cover, and docheader in +\# START. +\# +.MAC DOC_HEADER_QUAD END +. if '\\$0'DOC_HEADER_QUAD' .ds $CALLING_MACRO DOCHEADER +. if '\\$0'COVER_H_POS' .ds $CALLING_MACRO COVER +. if '\\$0'DOC_COVER_H_POS' .ds $CALLING_MACRO DOC_COVER +. ie !'\\*[$\\*[$CALLING_MACRO]_QUAD]'' \{\ +. substring $\\*[$CALLING_MACRO]_QUAD 0 0 +. if '\\*[$\\*[$CALLING_MACRO]_QUAD]'L' .LEFT +. if '\\*[$\\*[$CALLING_MACRO]_QUAD]'C' .CENTER +. if '\\*[$\\*[$CALLING_MACRO]_QUAD]'C' .RIGHT +. \} +. el .CENTER +.END +. +.ALIAS COVER_H_POS DOC_HEADER_QUAD +.ALIAS DOC_COVER_H_POS DOC_HEADER_QUAD +\# +.MAC DO_TITLE_OR_AUTHOR END +. ie '\\$0'DO_AUTHORS' .ds $TTL_AUTH AUTHOR +. el .ds $TTL_AUTH TITLE +. if '\\*[$\\*[$PRFX]\\*[$TTL_AUTH]_1]'' \{\ +. if !'\\*[$\\*[$PRFX]DOC\\*[$TTL_AUTH]_1]'' \ +. ds $\\*[$PRFX]\\*[$TTL_AUTH]_1 "\&" +. if !'\\*[$AUTHOR_1]'' .rm $PRFX +. \} +. if !'\\*[$\\*[$PRFX]\\*[$TTL_AUTH]_1]'' \{\ +. if '\\$0'DO_SUBTITLE' \{\ +. if '\\*[$PRFX]'\\*[DOC_]COVER_SUB' \{\ +. ds $PRFX SUB +. nr #\\*[DOC_]COVER_SUB 1 +. \} +. \} +. if !\\n[#PRINT_STYLE]=1 \{\ +. if (\\n[#COVER]=1):(\\n[#DOC_COVER]=1) \ +. if !'\\*[$PRFX]'SUB' \ +. rn $PRFX $PRFX_SAVED +. fam \\*[$\\*[$COVER_TYPE]\\*[$PRFX]\\*[$TTL_AUTH]_FAM] +. ft \\*[$\\*[$COVER_TYPE]\\*[$PRFX]\\*[$TTL_AUTH]_FT] +. ps \ +\\n[#DOC_PT_SIZE]u\\*[$\\*[$COVER_TYPE]\\*[$PRFX]\\*[$TTL_AUTH]_SIZE_CHANGE] +. if '\\*[$COVER_TYPE]'' .vs \\n[#DOCHEADER_LEAD]u +. if !'\\*[$\\*[$COVER_TYPE]\\*[$PRFX]\\*[$TTL_AUTH]_LEAD]'' \{\ +. vs \\*[$\\*[$COVER_TYPE]\\*[$PRFX]\\*[$TTL_AUTH]_LEAD] +. if \\n[#DOCHEADER] .sp |\\n[#T_MARGIN]u-1v +. \} +. if \\n[#CHAPTER+TITLE]=1 .ALD \\n[.v]u/4u \" A little space before the chapter title +. if \\n[#\\*[$COVER_TYPE]\\*[$PRFX]\\*[$TTL_AUTH]_COLOR]=1 \ +. COLOR \\*[$\\*[$COVER_TYPE]\\*[$PRFX]\\*[$TTL_AUTH]_COLOR] +. if \\n[#\\*[$COVER_TYPE]\\*[$PRFX]\\*[$TTL_AUTH]_CAPS]=1 .CAPS +. if \\n[#\\*[$COVER_TYPE]\\*[$PRFX]\\*[$TTL_AUTH]_SMALLCAPS]=1 .SMALLCAPS +. if (\\n[#COVER]=1):(\\n[#DOC_COVER]=1) \ +. rn $PRFX_SAVED $PRFX +. if \\n[#\\*[DOC_]COVER_TITLE]=2 \ +. ds $PRFX DOC +. \} +. if \\n[#\\*[DOC_]COVER_SUB] \{\ +. rr #\\*[DOC_]COVER_SUB +. ds $PRFX \\*[DOC_]COVER_SUB +. ds $SAVED_COVER_TYPE \\*[$COVER_TYPE] +. rm $COVER_TYPE +. \} +. nr #ARG_NUM 0 1 +. while \\n[#\\*[$PRFX]\\*[$TTL_AUTH]_NUM]>=\\n+[#ARG_NUM] \{\ +. ie \\n[#\\*[$COVER_TYPE]\\*[$PRFX]\\*[$TTL_AUTH]_UNDERLINE] \{\ +. ds $TITLE_TYPE \\*[$COVER_TYPE]\\*[$PRFX]\\*[$TTL_AUTH] +. ie \\n[#\\*[$COVER_TYPE]\\*[$PRFX]\\*[$TTL_AUTH]_UNDERLINE]=2 \{\ +. ie !\\n[#PRINT_STYLE]=1 \ +. UNDERSCORE2 \\*[$\\*[$PRFX]\\*[$TTL_AUTH]_UNDERLINE_GAP] \ +\\*[$\\*[$PRFX]\\*[$TTL_AUTH]_RULE_GAP] \ +"\\*[$\\*[$PRFX]\\*[$TTL_AUTH]_\\n[#ARG_NUM]] +. el .UNDERSCORE "\\*[$\\*[$PRFX]\\*[$TTL_AUTH]_\\n[#ARG_NUM]] +. \} +. el \{\ +. ie !\\n[#PRINT_STYLE]=1 \ +. UNDERSCORE "\\*[$\\*[$PRFX]\\*[$TTL_AUTH]_\\n[#ARG_NUM]] +. el .PRINT "\\*[$\\*[$PRFX]\\*[$TTL_AUTH]_\\n[#ARG_NUM]] +. \} +. \} +. el \{\ +. PRINT "\\*[$\\*[$PRFX]\\*[$TTL_AUTH]_\\n[#ARG_NUM]] +. \} +. if \\n[#ARG_NUM]>1 .as PDF_BM " \" +. as PDF_BM \\*[$\\*[$PRFX]\\*[$TTL_AUTH]_\\n[#ARG_NUM]] +. \} +. rm $TITLE_TYPE +. if \\n[#PRINT_STYLE]=2 .vs +. if \\n[#\\*[$COVER_TYPE]\\*[$PRFX]\\*[$TTL_AUTH]_COLOR]=1 \ +. gcolor +. SMALLCAPS off +. CAPS off +. \} +. if !'\\*[$SAVED_COVER_TYPE]'' \{\ +. ds $COVER_TYPE \\*[$SAVED_COVER_TYPE] +. rm $SAVED_COVER_TYPE +. \} +.END +. +.ALIAS DO_TITLE DO_TITLE_OR_AUTHOR +.ALIAS DO_SUBTITLE DO_TITLE_OR_AUTHOR +.ALIAS DO_AUTHORS DO_TITLE_OR_AUTHOR +\# +.MAC DO_CHAPTER END +. fam \\*[$\\*[DOC_]COVER_CHAPTER_FAM] +. ft \\*[$\\*[DOC_]COVER_CHAPTER_FT] +. ps \\n[#DOC_PT_SIZE]u\\*[$\\*[DOC_]COVER_CHAPTER_SIZE_CHANGE] +. if \\n[#\\*[DOC_]COVER_CHAPTER_COLOR]=1 \ +. COLOR \\*[$\\*[DOC_]COVER_CHAPTER_COLOR] +. if \\n[#\\*[DOC_]COVER_CHAPTER_CAPS]=1 .CAPS +. if \\n[#\\*[DOC_]COVER_CHAPTER_SMALLCAPS]=1 .SMALLCAPS +. ie \\n[#\\*[DOC_]COVER_CHAPTER_UNDERLINE] \{\ +. ds $TITLE_TYPE \\*[$COVER_TYPE]CHAPTER +. ie \\n[#\\*[DOC_]COVER_CHAPTER_UNDERLINE]=2 \ +. UNDERSCORE2 \\*[$\\*[DOC_]COVER_CHAPTER_UNDERLINE_GAP] \ +\\*[$\\*[DOC_]COVER_CHAPTER_RULE_GAP] "\\*[$CHAPTER_STRING] \\*[$CHAPTER]" +. el .UNDERSCORE "\\*[$CHAPTER_STRING] \\*[$CHAPTER]" +. \} +. el .PRINT "\\*[$CHAPTER_STRING] \\*[$CHAPTER]" +. gcolor +. SMALLCAPS off +. CAPS off +.END +. +.ALIAS DO_TITLE DO_TITLE_OR_AUTHOR +.ALIAS DO_SUBTITLE DO_TITLE_OR_AUTHOR +.ALIAS DO_AUTHORS DO_TITLE_OR_AUTHOR +\# +.MAC DO_CHAPTER END +. fam \\*[$\\*[DOC_]COVER_CHAPTER_FAM] +. ft \\*[$\\*[DOC_]COVER_CHAPTER_FT] +. ps \\n[#DOC_PT_SIZE]u\\*[$\\*[DOC_]COVER_CHAPTER_SIZE_CHANGE] +. if \\n[#\\*[DOC_]COVER_CHAPTER_COLOR]=1 \ +. COLOR \\*[$\\*[DOC_]COVER_CHAPTER_COLOR] +. if \\n[#\\*[DOC_]COVER_CHAPTER_CAPS]=1 .CAPS +. if \\n[#\\*[DOC_]COVER_CHAPTER_SMALLCAPS]=1 .SMALLCAPS +. ie \\n[#\\*[DOC_]COVER_CHAPTER_UNDERLINE] \{\ +. ds $TITLE_TYPE \\*[$COVER_TYPE]CHAPTER +. ie \\n[#\\*[DOC_]COVER_CHAPTER_UNDERLINE]=2 \ +. UNDERSCORE2 \\*[$\\*[DOC_]COVER_CHAPTER_UNDERLINE_GAP] \ +\\*[$\\*[DOC_]COVER_CHAPTER_RULE_GAP] "\\*[$CHAPTER_STRING] \\*[$CHAPTER]" +. el .UNDERSCORE "\\*[$CHAPTER_STRING] \\*[$CHAPTER]" +. \} +. el .PRINT "\\*[$CHAPTER_STRING] \\*[$CHAPTER]" +. gcolor +. SMALLCAPS off +. CAPS off +.END +\# +\# Spacing adjustments for (doc)cover and docheader elements +\# +.MAC _SPACE END +. ds $\\$0R \\$1 +.END +. +.ds SPACER_TYPE_1 SUBTITLE +.ds SPACER_TYPE_2 ATTRIBUTE +.ds SPACER_TYPE_3 AUTHOR +.ds SPACER_TYPE_4 CHAPTER_TITLE +.ds SPACER_TYPE_5 DOCTYPE +. +.nr #LOOP 0 1 +.while \n+[#LOOP]<=5 \{\ +. ALIAS \*[SPACER_TYPE_\n[#LOOP]]_SPACE _SPACE +. ALIAS COVER_\*[SPACER_TYPE_\n[#LOOP]]_SPACE _SPACE +. ALIAS DOC_COVER_\*[SPACER_TYPE_\n[#LOOP]]_SPACE _SPACE +.\} +\# +.MAC DEFAULT_DOCHEADER END +. nr #DOCHEADER 1 +. DOC_HEADER_QUAD +. vs \\n[#DOCHEADER_LEAD]u +. if \\n[#PRINT_STYLE]=2 \ +. if \\n[#DOCHEADER_COLOR]=1 \ +. COLOR \\*[$DOCHEADER_COLOR] +. DO_TITLE +. rr #DOCHEADER +. if !'\\*[$SUBTITLE_1]'' \{\ +. ds $PRFX SUB +. if !'\\*[$SUBTITLE_SPACER]'' .sp \\*[$SUBTITLE_SPACER] +. if \\n[#PRINT_STYLE]=2 \ +. if \\n[#DOCHEADER_COLOR]=1 \ +. COLOR \\*[$DOCHEADER_COLOR] +. DO_SUBTITLE +. rm $PRFX +. \} +. if !\\n[#NO_PRINT_AUTHOR] \{\ +. if !'\\*[$AUTHOR_1]'' \{\ +. ie \\n[#PRINT_STYLE]=1 \{\ +. TYPEWRITER +. ie \\n[#SINGLE_SPACE]=1 .vs \\n[#DOC_LEAD]u +. el .vs \\n[#DOC_LEAD]u/2u +. sp +. \} +. el .vs \\n[#DOC_LEAD]u\\*[$DOCHEADER_LEAD_ADJ] +. if d$ATTRIBUTE_STRING \{\ +. FAMILY \\*[$ATTRIBUTE_FAM] +. FT \\*[$ATTRIBUTE_FT] +. ps \ +\\n[#DOC_PT_SIZE]u\\*[$ATTRIBUTE_SIZE_CHANGE] +. if \\n[#DOCHEADER_COLOR]=1 \ +. COLOR \\*[$DOCHEADER_COLOR] +. if \\n[#ATTRIBUTE_COLOR]=1 \ +. COLOR \\*[$ATTRIBUTE_COLOR] +. if \\n[#ATTRIBUTE_CAPS]=1 .CAPS +. if !'\\*[$ATTRIBUTE_SPACER]'' \ +. sp \\*[$ATTRIBUTE_SPACER] +. ie \\n[#ATTRIBUTE_UNDERLINE] \{\ +. ds $TITLE_TYPE ATTRIBUTE +. ie \\n[#ATTRIBUTE_UNDERLINE]=2 \ +. UNDERSCORE2 \\*[$ATTRIBUTE_UNDERLINE_GAP] \ +\\*[$ATTRIBUTE_RULE_GAP] "\\*[$ATTRIBUTE_STRING]" +. el .UNDERSCORE "\\*[$ATTRIBUTE_STRING]" +. \} +. el .PRINT "\\*[$ATTRIBUTE_STRING]" +. if \\n[#ATTRIBUTE_COLOR]=1 .gcolor +. CAPS off +. \} +. if !'\\*[$AUTHOR_SPACER]'' .sp \\*[$AUTHOR_SPACER] +. if \\n[#DOCHEADER_COLOR]=1 \ +. COLOR \\*[$DOCHEADER_COLOR] +. DO_AUTHORS +. \} +. \} +. FAMILY \\*[$DOC_FAM] +. FT R +.END +\# +.MAC DEFAULT_DOCHEADER_TYPEWRITE END +. CENTER +. TYPEWRITER +. if !\\n[#SINGLE_SPACE] \{\ +. vs \\n[#DOC_LEAD]u/2u +. sp |\\n[#T_MARGIN]u-1v +. \} +. if !'\\*[$TITLE_1]'' \{\ +. ie \\n[#SINGLE_SPACE] \ +. vs \\n[#DOC_LEAD]u+(\\n[#DOC_LEAD]u/4u) +. el .vs (\\n[#DOC_LEAD]u/2u)+(\\n[#DOC_LEAD]u/4u) +. CAPS +. DO_TITLE +. CAPS OFF +. vs +. \} +. if !'\\*[$SUBTITLE]'' \{\ +. ds $PRFX SUB +. sp +. DO_SUBTITLE +. rm $PRFX +. \} +. if !\\n[#NO_PRINT_AUTHOR] \{\ +. if !'\\*[$AUTHOR_1]'' \{\ +. sp +. if d$ATTRIBUTE_STRING .PRINT "\\*[$ATTRIBUTE_STRING] +. sp +. DO_AUTHORS +. \} +. \} +.END +\# +.MAC CHAPTER_DOCHEADER END +. DOC_HEADER_QUAD +. FAMILY \\*[$CHAPTER_FAM] +. FT \\*[$CHAPTER_FT] +. ps \\n[#DOC_PT_SIZE]u\\*[$CHAPTER_SIZE_CHANGE] +. vs \\n[#DOCHEADER_LEAD]u +.\" Chapter title only +. ie '\\*[$CHAPTER]'' \{\ +. if \\n[#PRINT_STYLE]=2 \ +. if \\n[#DOCHEADER_COLOR]=1 \ +. COLOR \\*[$DOCHEADER_COLOR] +. if !'\\*[$CHAPTER_TITLE_1]'' \{\ +. ds $PRFX CHAPTER_ +. nr #DOCHEADER 1 +. DO_TITLE +. rr #DOCHEADER +. rm $PRFX +. \} +. \} +.\" Chapter string, possibly with a chapter title +. el \{\ +. if \\n[#PRINT_STYLE]=2 \{\ +. if \\n[#DOCHEADER_COLOR]=1 \ +. COLOR \\*[$DOCHEADER_COLOR] +. if \\n[#CHAPTER_COLOR]=1 \ +. COLOR \\*[$CHAPTER_COLOR] +. \} +. if \\n[#CHAPTER_CAPS]=1 .CAPS +. ie \\n[#CHAPTER_UNDERLINE] \{\ +. ds $TITLE_TYPE CHAPTER +. ie \\n[#CHAPTER_UNDERLINE]=2 \ +. UNDERSCORE2 \\*[$CHAPTER_UNDERLINE_GAP] \ +\\*[$CHAPTER_RULE_GAP] "\\*[$CHAPTER_STRING] \\*[$CHAPTER]" +. el .UNDERSCORE "\\*[$CHAPTER_STRING] \\*[$CHAPTER]" +. \} +. el .PRINT "\\*[$CHAPTER_STRING] \\*[$CHAPTER]" +. rm $TITLE_TYPE +. if \\n[#PRINT_STYLE]=2 \ +. if \\n[#CHAPTER_COLOR]=1 .gcolor +. CAPS off +. if !'\\*[$CHAPTER_TITLE_1]'' \{\ +. ds $PRFX CHAPTER_ +. if \\n[#PRINT_STYLE]=2 \{\ +. nr #CHAPTER+TITLE 1 +. if \\n[#DOCHEADER_COLOR]=1 \ +. COLOR \\*[$DOCHEADER_COLOR] +. \} +. if !'\\*[$CHAPTER_TITLE_SPACER]'' \ +. sp \\*[$CHAPTER_TITLE_SPACER] +. DO_TITLE +. rm $PRFX +. rr #CHAPTER+TITLE +. \} +. \} +. FAMILY \\*[$DOC_FAM] +. FT R +.END +\# +.MAC CHAPTER_DOCHEADER_TYPEWRITE END +. CENTER +. TYPEWRITER +. if !\\n[#SINGLE_SPACE] \{\ +. vs \\n[#DOC_LEAD]u/2u +. sp |\\n[#T_MARGIN]u-1v +. \} +. ie '\\*[$CHAPTER]'' \{\ +. CAPS +. ie !'\\*[$CHAPTER_TITLE]'' \{\ +. vs \\n[.v]u+(\\n[.v]u/3u) +. nr #ARG_NUM 0 1 +. while \\n[#CHAPTER_TITLE_NUM]>=\\n+[#ARG_NUM] \{\ +. UNDERSCORE 3p "\\*[$CHAPTER_TITLE_\\n[#ARG_NUM]]" +. \} +. vs +. \} +. el \{\ +. CAPS +. UNDERSCORE 3p "\\*[$CHAPTER_STRING]" +. \} +. CAPS OFF +. RLD 1v +. \} +. el \{\ +. CAPS +. UNDERSCORE 3p "\\*[$CHAPTER_STRING] \\*[$CHAPTER] +. CAPS OFF +. if !'\\*[$CHAPTER_TITLE]'' \{\ +. sp +. nr #ARG_NUM 0 1 +. while \\n[#CHAPTER_TITLE_NUM]>=\\n+[#ARG_NUM] \{\ +. PRINT "\\*[$CHAPTER_TITLE_\\n[#ARG_NUM]] +. \} +. \} +. sp -1 +. \} +. vs \\n[#DOC_LEAD]u +. if \\n[#SINGLE_SPACE] .sp 2 +.END +\# +.MAC NAMED_DOCHEADER END +. DEFAULT_DOCHEADER +. if !\\n[#NO_PRINT_DOCTYPE] \{\ +. FAMILY \\*[$DOCTYPE_FAM] +. FT \\*[$DOCTYPE_FT] +. ps \\n[#DOC_PT_SIZE]u\\*[$DOCTYPE_SIZE_CHANGE] +. vs \\n[#DOCHEADER_LEAD]u +. ALD \\n[#DOCHEADER_LEAD]u +. if \\n[#DOCHEADER_COLOR]=1 \ +. COLOR \\*[$DOCHEADER_COLOR] +. if \\n[#DOCTYPE_COLOR]=1 \ +. COLOR \\*[$DOCTYPE_COLOR] +. if \\n[#DOCTYPE_CAPS]=1 .CAPS +. if !'\\*[$DOCTYPE_SPACER]'' .sp \\*[$DOCTYPE_SPACER] +. ie \\n[#DOCTYPE_UNDERLINE] \{\ +. ds $TITLE_TYPE DOCTYPE +. ie \\n[#DOCTYPE_UNDERLINE]=2 \ +. UNDERSCORE2 \\*[$DOCTYPE_UNDERLINE_GAP] \ +\\*[$DOCTYPE_RULE_GAP] "\\*[$DOC_TYPE] +. el .UNDERSCORE "\\*[$DOC_TYPE] +. \} +. el .PRINT "\\*[$DOC_TYPE] +. gcolor +. CAPS off +. \} +. FAMILY \\*[$DOC_FAM] +. FT R +.END +\# +\# COVER PAGE +\# ---------- +\# *Arguments: +\# TITLE | DOCTITLE | CHAPTER | CHAPTER_TITLE | CHAPTER+TITLE | COVERTITLE \ +\# [ SUBTITLE AUTHOR DOCTYPE COPYRIGHT MISC BLANKPAGE PDF_OUTLINE_LABEL ] +\# *Function: +\# Toggles the number register for each cover page element +\# passed as an argument. +\# *Notes: +\# TITLE, DOCTITLE, CHAPTER, CHAPTER_TITLE or CHAPTER+TITLE must +\# be supplied. After that, users may enter as many or as few of +\# the arguments as they like. BLANKPAGE inserts a blank page +\# after the cover. +\# +\# If called as DOC_COVER, performs the same operations, but +\# applies everything to a doc cover. +\# +.MAC COVER END +. rm DOC_ +. ie '\\$0'DOC_COVER' \{\ +. nr #DOC_COVER 1 +. ds DOC_ DOC_ +. \} +. el .nr #COVER 1 +. if \\n[#NUM_ARGS]=1 \{\ +. if '\\$1'\\*[DOC_]COVERTEXT' \ +. nr #\\*[DOC_]COVERTEXT_ONLY 1 +. \} +. if \\n[#NUM_ARGS]=3 \{\ +. if '\\$1'\\*[DOC_]COVERTEXT' \ +. if '\\$2'PDF_OUTLINE_LABEL' \ +. nr #\\*[DOC_]COVERTEXT_ONLY 1 +. if '\\$1'PDF_OUTLINE_LABEL' \ +. if '\\$2'\\*[DOC_]COVERTEXT' \ +. nr #\\*[DOC_]COVERTEXT_ONLY 1 +. \} +. nr #ARG_NUM 0 1 +. nr #COVER_ITEM \\n[#NUM_ARGS] \"loop count +. while \\n+[#ARG_NUM]<=\\n[#COVER_ITEM] \{\ +. if '\\$1'DOCTITLE' \{\ +. nr #\\*[DOC_]COVER_TITLE 2 +. shift +. \} +. if '\\$1'TITLE' \{\ +. nr #\\*[DOC_]COVER_TITLE 1 +. if \\n[#FROM_\\*[DOC_]COVERTITLE] \{\ +. nr #\\*[DOC_]COVER_TITLE 7 +. rr #FROM_\\*[DOC_]COVERTITLE +. \} +. shift +. \} +. if '\\$1'CHAPTER' \{\ +. nr #\\*[DOC_]COVER_TITLE 3 +. shift +. \} +. if '\\$1'CHAPTER_TITLE' \{\ +. nr #\\*[DOC_]COVER_TITLE 4 +. shift +. \} +. if '\\$1'CHAPTER+TITLE' \{\ +. nr #\\*[DOC_]COVER_TITLE 5 +. shift +. \} +. if '\\$1'COVERTITLE' \{\ +. nr #COVERTITLE 1 +. nr #\\*[DOC_]COVER_TITLE 6 +. shift +. \} +. if '\\$1'DOC_COVERTITLE' \{\ +. nr #DOC_COVERTITLE 1 +. nr #\\*[DOC_]COVER_TITLE 7 +. shift +. \} +. if '\\$1'SUBTITLE' \{\ +. nr #\\*[DOC_]COVER_SUBTITLE 1 +. shift +. \} +. if '\\$1'AUTHOR' \{\ +. nr #\\*[DOC_]COVER_AUTHOR 1 +. shift +. \} +. if '\\$1'EDITOR' \{\ +. nr #\\*[DOC_]COVER_AUTHOR 1 +. shift +. \} +. if '\\$1'DOCTYPE' \{\ +. nr #\\*[DOC_]COVER_DOCTYPE 1 +. shift +. \} +. if '\\$1'COPYRIGHT' \{\ +. nr #\\*[DOC_]COVER_COPYRIGHT 1 +. shift +. \} +. if '\\$1'MISC' \{\ +. nr #\\*[DOC_]COVER_MISC 1 +. shift +. \} +. if '\\$1'\\*[DOC_]COVERTEXT' \{\ +. nr #\\*[DOC_]COVERTEXT 1 +. shift +. \} +. if '\\$1'\\*[DOC_]COVER_IMAGE' \{\ +. nr #\\*[DOC_]COVER_IMAGE 1 +. shift +. \} +. if '\\$1'PDF_OUTLINE_LABEL' \{\ +. shift +. ds $PDF_\\*[DOC_]COVER_LABEL \\$1 +. shift +. \} +. if '\\$1'BLANKPAGE' \{\ +. nr #\\*[DOC_]COVER_BLANKPAGE 1 +. shift +. \} +. \} +. if '\\$0'DOC_COVER' .rm DOC_ +.END +\# +\# COVER TITLE +\# ----------- +\# *Arguments: +\# +\# *Function: +\# Stores cover title in string(s) for output on cover pages. +\# +.MAC COVERTITLE END +. rm DOC_ +. if '\\$0'DOC_COVERTITLE' \ +. ds DOC_ DOC_ +. nr #FROM_\\*[DOC_]COVERTITLE 1 +. ie \\n[#NUM_ARGS]=0 \{\ +. nr argc 0 1 +. while \\n+[argc]<=3 \{\ +. if \\n[#\\*[DOC_]COVER_TITLE_NUM] \{\ +. nr #ITEM 0 1 +. while \\n[#\\*[DOC_]COVERTITLE_NUM]>\\n[#ITEM] \{\ +. rm $\\*[DOC_]COVERTITLE_\\n+[#ITEM] +. \} +. rr #\\*[DOC_]COVERTITLE_NUM +. rm $\\*[DOC_]COVERTITLE +. \} +. \} +. \} +. el \{\ +. nr #\\*[DOC_]COVERTITLE_NUM 0 1 +. while \\n[#NUM_ARGS]>\\n[#\\*[DOC_]COVERTITLE_NUM] \{\ +. ds \ +$\\*[DOC_]COVERTITLE_\\n+[#\\*[DOC_]COVERTITLE_NUM] \\$\\n[#\\*[DOC_]COVERTITLE_NUM] +. nr #\\*[DOC_]COVERTITLE_NUM \\n[#\\*[DOC_]COVERTITLE_NUM] +. \} +. ds $\\*[DOC_]COVERTITLE \\$* +. \} +.END +\# +.MAC COVER_ATTRIBUTE_STRING END +. if '\\$0'DOC_COVER_ATTRIBUTE_STRING' \ +. ds DOC_ DOC_ +. ds $\\*[DOC_]COVER_ATTRIBUTE_STRING \\$1 +. rm DOC_ +.END +. +.ALIAS DOC_COVER_ATTRIBUTE_STRING COVER_ATTRIBUTE_STRING +\# +\# COVER TEXT +\# ---------- +\# *Arguments: +\# [ START ] | +\# *Function: +\# With no arg, begins a diversion holding the cover text for +\# output on the cover page. With START , sets a vertical +\# starting position relative to the top edge of the page. With +\# any other arg, ends the diversion. +\# *Notes: +\# Aliased as DOC_COVERTEXT. +\# +\# If no other items assigned to cover pages, starts 1/3 of the +\# way down the cover page unless START pos is given, otherwise +\# starts underneath the last of title, subtitle, author(s) or +\# doctype, preceded by a blank line. +\# +\# Does not persist. +\# +.MAC COVERTEXT END +. rm DOC_ +. if '\\$0'DOC_COVERTEXT' .ds DOC_ DOC_ +. if '\\$1'START' \{\ +. shift +. nr #\\*[DOC_]COVERTEXT_START_POS (u;\\$1) +. shift +. \} +. ie '\\$1'' \{\ +. nr #COVERTEXT_PP 1 +. di \\*[DOC_]COVER_TEXT +. ev COVER_TEXT +. evc 0 +\!. if \\\\n[#\\*[DOC_]COVERTEXT_ONLY] \ +. sp |\\\\n[#T_MARGIN]u-\\\\n[#DOC_LEAD]u +\!. ie !\\n[#\\*[DOC_]COVERTEXT_START_POS] \{\ +\!. sp |\\n[.p]u/3u-1v +\!. \} +\!. el \{\ +\!. vs 0 +\!. sp |0i +\!. vs \\\\n[#DOC_LEAD]u+\\\\*[$\\*[DOC_]COVER_LEAD_ADJ] +\!. sp |\\n[#\\*[DOC_]COVERTEXT_START_POS]u-1 +\!. \} +\!. vpt +. \} +. el \{\ +. br +\!. vpt 0 +. ev +. di +. rm $FONT +. rr #COVERTEXT_PP +. IQ CLEAR +. \} +. rm DOC_ +.END +. +.ALIAS DOC_COVERTEXT COVERTEXT +\# +\# COVER IMAGE +\# ----------- +\#*Arguments: +\# [ -L|-C|-R|-I Y-pos [ X-pos ] ] +\#*Function: +\# Places an image on doccovers and covers. +\#*Notes: +\# Aliased as DOC_COVER_IMAGE. +\# +\# and are required. With no further args, images +\# are set at 0,0 by default so that full page images fill the entire +\# printer sheet. +\# +\# Positioning args are the same as PDF_IMAGE. -L, -R, -C and -I +\# observe the left and right margins. +\# +\# Y-pos is required for all but full page images; without it, images +\# are flush with the top of the page. X-pos is only needed if the +\# user prefers to give absolute X,Y positioning. +\# +\# Note that Y-pos comes before X-pos in the args. +\# +.MAC COVER_IMAGE END +. if '\\$0'DOC_COVER_IMAGE' .ds DOC_ DOC_ +. ds \\*[DOC_]COVER_IMG_FILE \\$1 +. nr \\*[DOC_]COVER_IMG_W (z;\\$2) +. nr \\*[DOC_]COVER_IMG_H (z;\\$3) +. if !'\\$4'' \{\ +. ie !\B'\\$4' \{\ +. if '\\$4'-L' .nr \\*[DOC_]COVER_IMG_IND \ + \\n[#L_MARGIN]u +. if '\\$4'-C' .nr \\*[DOC_]COVER_IMG_IND \ + \\n[#PAGE_WIDTH]u-\\n[\\*[DOC_]COVER_IMG_W]u/2 +. if '\\$4'-R' .nr \\*[DOC_]COVER_IMG_IND \ + \\n[#L_MARGIN]+\\n[.l]u-\\n[\\*[DOC_]COVER_IMG_W]u +. if '\\$4'-I' \{\ +. nr \\*[DOC_]COVER_IMG_IND \\n[#L_MARGIN]+\\$5 +. if !'\\$6'' .nr \\*[DOC_]COVER_IMG_Y (u;\\$6) +. shift \\n[#NUM_ARGS] +. \} +. if \B'\\$5' .nr \\*[DOC_]COVER_IMG_Y (u;\\$5) +. \} +. el \{\ +. nr \\*[DOC_]COVER_IMG_Y (u;\\$4) +. if \B'\\$5' .nr \\*[DOC_]COVER_IMG_X (u;\\$5) +. \} +. \} +. rm DOC_ +.END +. +.ALIAS DOC_COVER_IMAGE COVER_IMAGE +\# +.MAC DO_COVER_IMAGE END +. ll \\n[#PAGE_WIDTH]u +. po 0 +. vs 0 +. sp |0i +. if \\n[\\*[DOC_]COVER_IMG_Y] .sp \\n[\\*[DOC_]COVER_IMG_Y]u +. if \\n[\\*[DOC_]COVER_IMG_X] .in \\n[\\*[DOC_]COVER_IMG_X]u +. if \\n[\\*[DOC_]COVER_IMG_IND] .in \\n[\\*[DOC_]COVER_IMG_IND]u +. if \\n[.u]=1 .nf +. nop \X'pdf: pdfpic \\*[\\*[DOC_]COVER_IMG_FILE] -L \ +\\n[\\*[DOC_]COVER_IMG_W]z \\n[\\*[DOC_]COVER_IMG_H]z' +. in +. vs +. po +. ll +.END +. +.ALIAS DO_DOC_COVER_IMAGE DO_COVER_IMAGE +\# +\# COVER PAGE LEADING +\# ------------------ +\# *Arguments: +\# <+|- amount by which to in/decrease leading of cover/doc cover> +\# *Function: +\# Stores user supplied lead in/decrease in string $COVER_LEAD_ADJ +\# or $DOC_COVER_LEAD_ADJ, depending on whether the macro was called +\# with an alias (DOC_COVER_LEAD). +\# *Notes: +\# A unit of measure must be supplied. Decimal fractions OK. +\# Default is +0, i.e. same as DOC_LEAD. +\# +.MAC COVER_LEAD END +. ie '\\$0'DOC_COVER_LEAD' .ds $DOC_COVER_LEAD_ADJ \\$1 +. el .ds $COVER_LEAD_ADJ \\$1 +.END +\# +\# MISC_AUTOLEAD functionality has been removed. Leading for MISCs +\# is now entered as an absolute value. The macro emits a warning. +\# +.MAC MISC_AUTOLEAD END +. ds replacement \\$0 +. substring replacement 0 -9 +. ds replacement \\*[replacement]LEAD +. ds cover-type \\$0 +. substring cover-type 0 2 +. ie '\\*[cover-type]'COV' .ds cover-type cover +. el .ds cover-type doc-cover +. tm1 "[mom]: \\$0 at line \\n[.c] of '\\n[.F]' is no longer valid. +. tm1 " Leading of \\*[cover-type] MISC items is now set with \\*[replacement], which +. tm1 " takes an absolute leading value. Please update your document. +. ab [mom]: Aborting. +.END +. +.ALIAS DOC_COVER_MISC_AUTOLEAD MISC_AUTOLEAD +.ALIAS COVER_MISC_AUTOLEAD MISC_AUTOLEAD +\# +\# COVER PAGE START POSITION +\# ------------------------- +\# *Arguments: +\# +\# *Function: +\# Stores user supplied lead in/decrease in #COVER_START_POS +\# or #DOC_COVER_START_POS, depending on whether the macro was +\# called by an alias (DOC_COVER_ADVANCE). +\# *Notes: +\# A unit of measure must be supplied. Decimal fractions OK. +\# If user doesn't invoke this macro, the default starting +\# position for both covers and doc covers is 1/3 of the way +\# down the page (setup in DO_COVER). +\# +.MAC COVER_ADVANCE END +. ds COVER_TYPE \\$0 +. substring COVER_TYPE 0 2 +. ie 'COVER_TYPE'DOC' .nr #DOC_COVER_START_POS (\\$1) +. el .nr #COVER_START_POS (\\$1) +.END +. +.ALIAS DOC_COVER_ADVANCE COVER_ADVANCE +.ALIAS DOC_COVER_START_POS COVER_ADVANCE +.ALIAS COVER_ADVANCE COVER_ADVANCE +.ALIAS COVER_START_POS COVER_ADVANCE +\# +\# COVERS - WHETHER TO PRINT +\# ------------------------- +\# *Arguments: +\# | +\# *Function: +\# Creates or removes registers #COVERS and #COVERS_OFF, checked for +\# in DEFAULTS (in START) prior to printing +\# +.MAC COVERS END +. ie '\\$0'DOC_COVERS' \{\ +. ie '\\$1'' \{\ +. rr #DOC_COVERS_OFF +. nr #DOC_COVERS 1 +. \} +. el \{\ +. rr #DOC_COVERS +. nr #DOC_COVERS_OFF 1 +. \} +. \} +. el \{\ +. ie '\\$1'' \{\ +. rr #COVERS_OFF +. nr #COVERS 1 +. \} +. el \{\ +. rr #COVERS +. nr #COVERS_OFF 1 +. \} +. \} +.END +\# +\# COVER_COUNTS_PAGES +\# ------------------ +\# *Arguments: +\# | +\# *Function: +\# Creates or removes registers #COVERS_COUNT or #DOCCOVERS_COUNT, +\# used in END_COVER to determine whether to increment the page +\# number silently when doc covers or covers are output. +\# +.MAC COVER_COUNTS_PAGES END +. if '\\$0'DOC_COVER_COUNTS_PAGES' \{\ +. ie '\\$1'' .nr #DOCCOVERS_COUNT 1 +. el .rr #DOCCOVERS_COUNT +. return +. \} +. if '\\$0'COVER_COUNTS_PAGES' \{\ +. ie '\\$1'' .nr #COVERS_COUNT 1 +. el .rr #COVERS_COUNT +. return +. \} +.END +\# +.MAC DO_COVER END +. nr #DOING_COVER 1 +. ev COVER +. evc 0 +. vpt 0 +. if \\n[#PAGINATE]=1 \{\ +. nr #PAGINATION_WAS_ON 1 +. rr #PAGINATE +. \} +. if \\n[#HEADERS_ON]=1 \{\ +. nr #HEADERS_WERE_ON 1 +. HEADERS OFF +. \} +. if \\n[#FOOTERS_ON]=1 \{\ +. nr #FOOTERS_WERE_ON 1 +. FOOTERS OFF +. \} +. if \\n[#COLUMNS]=1 \{\ +. nr #COLUMNS_WERE_ON 1 +. rr #COLUMNS +. \} +. ds PDF_BM +. ie '\\$0'DO_DOC_COVER' \{\ +. ds DOC_ DOC_ +. nr #DOC_COVER_DONE 1 +. if '\\*[$PDF_DOC_COVER_LABEL]'' \ +. ds $PDF_DOC_COVER_LABEL Cover: +. \} +. el \ +. if '\\*[$PDF_COVER_LABEL]'' \ +. ds $PDF_COVER_LABEL Title Page: +. ds $COVER_TYPE \\*[DOC_]COVER_ +. if !r#\\*[DOC_]COVER_START_POS \ +. nr #\\*[DOC_]COVER_START_POS \\n[#PAGE_LENGTH]/3 +. if \\n[#PRINT_STYLE]=1 \ +. if !\\n[#SINGLE_SPACE]=1 .vs \\n[#DOC_LEAD]u/2u +. if \\n[#PRINT_STYLE]=2 \{\ +. vs \\n[#DOC_LEAD]u\\*[$\\*[DOC_]COVER_LEAD_ADJ] +. nr #\\*[DOC_]COVER_LEAD \\n[.v] +. \} +. if \\n[.ns] .rs +. if '\\$0'DO_COVER' \{\ +. if \\n[TOC.RELOCATE]==5 \ +. if !rTOC_BH .TOC_BEFORE_HERE +. \} +. if '\\$0'DO_DOC_COVER' \{\ +. if \\n[TOC.RELOCATE]==3 \ +. if !rTOC_BH .TOC_BEFORE_HERE +. \} +. RV_HARD_SET_MARGINS +.\" Cover image +. if \\n[#\\*[DOC_]COVER_IMAGE]=1 \{\ +. DO_\\*[DOC_]COVER_IMAGE +. rr #\\*[DOC_]COVER_IMAGE +. \} +.\" Start cover +. sp |\\n[#\\*[DOC_]COVER_START_POS]u-1v +. if !\\n[#PRINT_STYLE]=1 \ +. if \\n[#\\*[DOC_]COVER_COLOR]=1 \ +. COLOR \\*[$\\*[DOC_]COVER_COLOR] +. \\*[DOC_]COVER_H_POS +. if (\\n[#\\*[DOC_]COVER_TITLE]=1):(\\n[#\\*[DOC_]COVER_TITLE]=2) .ds DOC DOC +. fam \\*[$\\*[DOC_]COVER_\\*[DOC]TITLE_FAM] +. ft \\*[$\\*[DOC_]COVER_\\*[DOC]TITLE_FT] +. ps \\*[$\\*[DOC_]COVER_\\*[DOC]TITLE_SIZE_CHANGE] +. ie \\n[#PRINT_STYLE]=1 .TYPEWRITER +. el .vs \\n[#\\*[DOC_]COVER_LEAD]u +. nr PDFHREF.VIEW.LEADING \\n[PDFHREF.VIEW.LEADING.C] +.\" Title and/or doctitle +. if (\\n[#\\*[DOC_]COVER_TITLE]=1):(\\n[#\\*[DOC_]COVER_TITLE]=2) \{\ +. ie \\n[#PRINT_STYLE]=1 \{\ +. vs \\n[.v]u*2u +. sp -1.5 +. CAPS +. nr #ARG_NUM 0 1 +. while \\n[#TITLE_NUM]>=\\n+[#ARG_NUM] \{\ +. UNDERSCORE "\\*[$TITLE_\\n[#ARG_NUM]]" +. if \\n[#ARG_NUM]>1 .as PDF_BM " \" +. as PDF_BM \\*[$TITLE_\\n[#ARG_NUM]] +. \} +. CAPS OFF +. vs +. \} +. el \{\ +. DO_TITLE +. rm $PRFX +. \} +. PDF_BOOKMARK 1 \\*[$PDF_\\*[DOC_]COVER_LABEL] \\*[PDF_BM] +. \} +.\" Chapter +. if \\n[#\\*[DOC_]COVER_TITLE]=3 \{\ +. ie \\n[#PRINT_STYLE]=1 \{\ +. CAPS +. UNDERSCORE "\\*[$CHAPTER_STRING] \\*[$CHAPTER] +. CAPS OFF +. \} +. el .DO_CHAPTER +. PDF_BOOKMARK 1 \ +\\*[$PDF_\\*[DOC_]COVER_LABEL] \\*[$CHAPTER_STRING] \\*[$CHAPTER] +. if \\n[#\\*[DOC_]COVER_CHAPTER_CAPS]=1 .CAPS off +. \} +.\" Chapter title +. if \\n[#\\*[DOC_]COVER_TITLE]=4 \{\ +. ie \\n[#PRINT_STYLE]=1 \{\ +. CAPS +. nr #ARG_NUM 0 1 +. vs \\n[.v]u*2u +. sp -1.5 +. while \\n[#CHAPTER_TITLE_NUM]>=\\n[#ARG_NUM] \{\ +. UNDERSCORE "\\*[$CHAPTER_TITLE_\\n+[#ARG_NUM]]" +. if \\n[#ARG_NUM]>1 .as PDF_BM " \" +. as PDF_BM \\*[$CHAPTER_TITLE_\\n[#ARG_NUM]] +. \} +. CAPS OFF +. vs +. \} +. el \{\ +. ds $PRFX CHAPTER_ +. DO_TITLE +. rm $PRFX +. \} +. PDF_BOOKMARK 1 \\*[$PDF_\\*[DOC_]COVER_LABEL] \\*[PDF_BM] +. \} +.\" Chapter + chapter title +. if \\n[#\\*[DOC_]COVER_TITLE]=5 \{\ +. ie \\n[#PRINT_STYLE]=1 \{\ +. CAPS +. UNDERSCORE "\\*[$CHAPTER_STRING] \\*[$CHAPTER] +. CAPS OFF +. \} +. el .DO_CHAPTER +. if !'\\*[$CHAPTER_TITLE_1]'' \{\ +. ie \\n[#PRINT_STYLE]=1 \{\ +. ie \\n[#SINGLE_SPACE]=0 .vs \\n[#DOC_LEAD]u/2u +. el .vs \\n[#DOC_LEAD]u +. sp +. nr #ARG_NUM 0 1 +. while \\n[#CHAPTER_TITLE_NUM]>=\\n+[#ARG_NUM] \{\ +. PRINT "\\*[$CHAPTER_TITLE_\\n[#ARG_NUM]]" +. if \\n[#ARG_NUM]>1 .as PDF_BM " \" +. as PDF_BM \\*[$CHAPTER_TITLE_\\n[#ARG_NUM]] +. \} +. if \\n[#SINGLE_SPACE]=0 .vs \\n[#DOC_LEAD]u +. \} +. el \{\ +. ds $PRFX CHAPTER_ +. if \\n[#PRINT_STYLE]=2 .nr #CHAPTER+TITLE 1 +. if !'\\*[$\\*[DOC_]COVER_CHAPTER_TITLE_SPACER]'' \ +. sp \\*[$\\*[DOC_]COVER_CHAPTER_TITLE_SPACER] +. DO_TITLE +. rr #CHAPTER+TITLE +. rm $PRFX +. \} +. \} +. PDF_BOOKMARK 1 \\*[$PDF_\\*[DOC_]COVER_LABEL] \\*[PDF_BM] +. \} +.\" (Doc)covertitle +.\" Titles to (doc)covers that are entered with +.\" .TITLE DOC_COVER title +.\" and included in (DOC)COVER with TITLE get treated as +.\" (DOC_)COVERTITLEs, so we define the appropriate strings and +.\" registers from their (DOC_)COVER_TITLE equivalents. +.\" +. if (\\n[#\\*[DOC_]COVER_TITLE]=6):(\\n[#\\*[DOC_]COVER_TITLE]=7) \{\ +. ds $\\*[DOC_]COVER_\\*[DOC_]COVERTITLE_FAM \ +\\*[$\\*[DOC_]COVER_TITLE_FAM] +. ds $\\*[DOC_]COVER_\\*[DOC_]COVERTITLE_FT \ +\\*[$\\*[DOC_]COVER_TITLE_FT] +. ds $\\*[DOC_]COVER_\\*[DOC_]COVERTITLE_COLOR \ +\\*[$\\*[DOC_]COVER_TITLE_COLOR] +. nr #\\*[DOC_]COVER_\\*[DOC_]COVERTITLE_COLOR \ +\\n[#\\*[DOC_]COVER_TITLE_COLOR] +. nr #\\*[DOC_]COVER_\\*[DOC_]COVERTITLE_CAPS \ +\\n[#\\*[DOC_]COVER_TITLE_CAPS] +. nr #\\*[DOC_]COVER_\\*[DOC_]COVERTITLE_SMALLCAPS \ +\\n[#\\*[DOC_]COVER_TITLE_SMALLCAPS] +. ds $\\*[DOC_]COVER_\\*[DOC_]COVERTITLE_LEAD \ +\\*[$\\*[DOC_]COVER_TITLE_LEAD] +. ds $\\*[DOC_]COVER_\\*[DOC_]COVERTITLE_SIZE_CHANGE \ +\\*[$\\*[DOC_]COVER_TITLE_SIZE_CHANGE] +. nr #\\*[DOC_]COVER_\\*[DOC_]COVERTITLE_UNDERLINE \ +\\n[#\\*[DOC_]COVER_TITLE_UNDERLINE] +. nr #\\*[DOC_]COVER_\\*[DOC_]COVERTITLE_UNDERLINE_WEIGHT \ +\\n[#\\*[DOC_]COVER_TITLE_UNDERLINE_WEIGHT] +. nr #\\*[DOC_]COVER_\\*[DOC_]COVERTITLE_UNDERLINE_WEIGHT_ADJ \ +\\n[#\\*[DOC_]COVER_TITLE_UNDERLINE_WEIGHT_ADJ] +. ds $\\*[DOC_]COVER_\\*[DOC_]COVERTITLE_UNDERLINE_GAP \ +\\*[$\\*[DOC_]COVER_TITLE_UNDERLINE_GAP] +. ds $\\*[DOC_]COVER_\\*[DOC_]COVERTITLE_RULE_GAP \ +\\*[$\\*[DOC_]COVER_TITLE_RULE_GAP] +. ie \\n[#PRINT_STYLE]=1 \{\ +. CAPS +. vs \\n[.v]u*2u +. nr #ARG_NUM 0 1 +. while \\n[#\\*[DOC_]COVERTITLE_NUM]>=\\n+[#ARG_NUM] \{\ +. UNDERSCORE "\\*[$\\*[DOC_]COVERTITLE_\\n[#ARG_NUM]]" +. if \\n[#ARG_NUM]>1 .as PDF_BM " \" +. as PDF_BM \\*[$\\*[DOC_]COVERTITLE_\\n[#ARG_NUM]] +. \} +. vs +. CAPS OFF +. \} +. el \{\ +. ds $PRFX \\*[DOC_]COVER +. DO_TITLE +. rm $PRFX +. \} +. PDF_BOOKMARK 1 \\*[$PDF_\\*[DOC_]COVER_LABEL] \\*[PDF_BM] +. \} +. ie !'\\*[DOC_]'' \{\ +. if !\\n[#DOC_COVER_TITLE] \ +. if '\\*[$PDF_\\*[DOC_]COVER_LABEL]'' \ +. PDF_BOOKMARK 1 Cover page +. \} +. el \{\ +. if !\\n[#COVER_TITLE] \ +. if '\\*[$PDF_\\*[DOC_]COVER_LABEL]'' \ +. PDF_BOOKMARK 1 Title page +. \} +. rr #\\*[DOC_]COVER_TITLE +.\" Subtitle +. if \\n[#\\*[DOC_]COVER_SUBTITLE]=1 \{\ +. ie \\n[#PRINT_STYLE]=1 \{\ +. if !'\\*[$\\*[DOC_]COVER_SUBTITLE_1]'' \ +. ds $PRFX \\*[DOC_]COVER_ +. sp 2 +. nr #ARG_NUM 0 1 +. while \\n[#\\*[$PRFX]SUBTITLE_NUM]>=\\n+[#ARG_NUM] \{\ +. PRINT "\\*[$\\*[$PRFX]SUBTITLE_\\n[#ARG_NUM]]" +. \} +. rm $PRFX +. \} +. el \{\ +. ie !'\\*[$\\*[DOC_]COVER_SUBTITLE_1]'' .ds $PRFX \\*[DOC_]COVER_SUB +. el .ds $PRFX SUB +. if !'\\*[$\\*[DOC_]COVER_SUBTITLE_SPACER]'' \ +. sp \\*[$\\*[DOC_]COVER_SUBTITLE_SPACER] +. DO_SUBTITLE +. rm $PRFX +. \} +. \} +. if \\n[#PRINT_STYLE]=1 \ +. if !r#\\*[DOC_]COVER_SUBTITLE .sp +.\" Author (plus attribution) +. if \\n[#\\*[DOC_]COVER_AUTHOR]=1 \{\ +. ie \\n[#PRINT_STYLE]=1 \ +. sp +. el \{\ +. ie !'\\*[$\\*[DOC_]COVER_AUTHOR_LEAD]'' \ +. vs \\*[$\\*[DOC_]COVER_AUTHOR_LEAD] +. el .vs \\n[#\\*[DOC_]COVER_LEAD]u +. \} +. if '\\*[$\\*[DOC_]COVER_ATTRIBUTE_STRING]'' \ +. ds $\\*[DOC_]COVER_ATTRIBUTE_STRING \ + \\*[$ATTRIBUTE_STRING] +. ie !\\n[#PRINT_STYLE]=1 \{\ +. fam \\*[$\\*[DOC_]COVER_ATTRIBUTE_FAM] +. ft \\*[$\\*[DOC_]COVER_ATTRIBUTE_FT] +. ps \ +\\n[#DOC_PT_SIZE]u\\*[$\\*[DOC_]COVER_ATTRIBUTE_SIZE_CHANGE] +. if \\n[#\\*[DOC_]COVER_ATTRIBUTE_COLOR]=1 \ +. COLOR \\*[$\\*[DOC_]COVER_ATTRIBUTE_COLOR] +. if \\n[#\\*[DOC_]COVER_ATTRIBUTE_CAPS]=1 .CAPS +. if \\n[#\\*[DOC_]COVER_ATTRIBUTE_SMALLCAPS]=1 .SMALLCAPS +. if !'\\*[$\\*[DOC_]COVER_ATTRIBUTE_SPACER]'' \ +. sp \\*[$\\*[DOC_]COVER_ATTRIBUTE_SPACER] +. ie \\n[#\\*[DOC_]COVER_ATTRIBUTE_UNDERLINE] \{\ +. ds $TITLE_TYPE \\*[DOC_]COVER_ATTRIBUTE +. ie \\n[#\\*[DOC_]COVER_ATTRIBUTE_UNDERLINE]=2 \ +. UNDERSCORE2 \\*[$\\*[DOC_]COVER_ATTRIBUTE_UNDERLINE_GAP] \ +\\*[$\\*[DOC_]COVER_ATTRIBUTE_RULE_GAP] "\\*[$\\*[DOC_]COVER_ATTRIBUTE_STRING]" +. el .UNDERSCORE \\*[$\\*[DOC_]COVER_ATTRIBUTE_STRING] +. \} +. el .PRINT "\\*[$\\*[DOC_]COVER_ATTRIBUTE_STRING]" +. SMALLCAPS off +. CAPS off +. if \\n[#\\*[DOC_]COVER_ATTRIBUTE_COLOR]=1 \ +. gcolor +. \} +. el \ +. PRINT "\\*[$\\*[DOC_]COVER_ATTRIBUTE_STRING]" +. ie \\n[#PRINT_STYLE]=1 .sp +. el \{\ +. if !'\\*[$\\*[DOC_]COVER_AUTHOR_SPACER]'' \ +. sp \\*[$\\*[DOC_]COVER_AUTHOR_SPACER] +. \} +. if '\\$0'DO_COVER' \ +. ds $PRFX COVER_ +. if '\\$0'DO_DOC_COVER' \ +. ds $PRFX DOC_COVER_ +. DO_AUTHORS +. rm $PRFX +. \} +.\" Named doctype string +. if \\n[#DOC_TYPE]=3 \{\ +. if \\n[#\\*[DOC_]COVER_DOCTYPE]=1 \{\ +. ie \\n[#PRINT_STYLE]=1 \{\ +. TYPEWRITER +. sp 1.5 +. UNDERSCORE2 3p 2p "\\*[$DOC_TYPE] +. \} +. el \{\ +. fam \\*[$\\*[DOC_]COVER_DOCTYPE_FAM] +. ft \\*[$\\*[DOC_]COVER_DOCTYPE_FT] +. ps \ +\\n[#DOC_PT_SIZE]u\\*[$\\*[DOC_]COVER_DOCTYPE_SIZE_CHANGE] +. if \\n[#\\*[DOC_]COVER_DOCTYPE_COLOR]=1 \ +. COLOR \\*[$\\*[DOC_]COVER_DOCTYPE_COLOR] +. sp +. if \\n[#\\*[DOC_]COVER_DOCTYPE_CAPS]=1 .CAPS +. if \\n[#\\*[DOC_]COVER_DOCTYPE_SMALLCAPS]=1 .SMALLCAPS +. if !'\\*[$\\*[DOC_]COVER_DOCTYPE_SPACER]'' \ +. sp \\*[$\\*[DOC_]COVER_DOCTYPE_SPACER] +. ie \\n[#\\*[DOC_]COVER_DOCTYPE_UNDERLINE] \{\ +. ds $TITLE_TYPE \\*[DOC_]COVER_DOCTYPE +. ie \\n[#\\*[DOC_]COVER_DOCTYPE_UNDERLINE]=2 \ +. UNDERSCORE2 \\*[$\\*[DOC_]COVER_DOCTYPE_UNDERLINE_GAP] \ +\\*[$\\*[DOC_]COVER_DOCTYPE_RULE_GAP] "\\*[$DOC_TYPE]" +. el .UNDERSCORE "\\*[$DOC_TYPE]" +. \} +. el .PRINT "\\*[$DOC_TYPE]" +. SMALLCAPS off +. CAPS off +. if \\n[#\\*[DOC_]COVER_DOCTYPE_COLOR]=1 \ +. gcolor +. \} +. \} +. \} +.\" Covertext +. if \\n[#\\*[DOC_]COVERTEXT]=1 \{\ +. nr #DOING_COVERTEXT 1 +. if !\\n[#\\*[DOC_]COVERTEXT_START_POS] .sp +. if \\n[#\\*[DOC_]COVERTEXT]=1 \{\ +. ev \\*[DOC_]COVERTEXT +. nf +. \\*[DOC_]COVER_TEXT +. ev +. \} +. if \\n[#\\*[DOC_]COVERTEXT_ONLY] \ +. PDF_BOOKMARK 1 \\*[$PDF_\\*[DOC_]COVER_LABEL] \\*[PDF_BM] +. rr #\\*[DOC_]COVERTEXT +. rm \\*[DOC_]COVER_TEXT +. rr #DOING_COVERTEXT +. rr #\\*[DOC_]COVERTEXT_START_POS +. \} +. sp |\\n[#VISUAL_B_MARGIN]u +.\" Copyright +. ie \\n[#PRINT_STYLE]=1 \ +. if !\\n[#SINGLE_SPACE] .sp +. el \{\ +. fam \\*[$\\*[DOC_]COVER_COPYRIGHT_FAM] +. ft \\*[$\\*[DOC_]COVER_COPYRIGHT_FT] +. ps \\n[#DOC_PT_SIZE]u\\*[$\\*[DOC_]COVER_COPYRIGHT_SIZE_CHANGE] +. nr #COPYRIGHT_V_POS \\n[#DOC_LEAD]-\\n[.v] +. sp \\n[#COPYRIGHT_V_POS]u +. rr #COPYRIGHT_V_POS +. \} +. if \\n[#\\*[DOC_]COVER_COPYRIGHT]=1 \{\ +. if '\\*[$\\*[DOC_]COVER_COPYRIGHT]'' \ +. ds $\\*[DOC_]COVER_COPYRIGHT \\*[$COVER_COPYRIGHT] +. QUAD \\*[$\\*[DOC_]COVER_COPYRIGHT_QUAD] +. if \\n[#\\*[DOC_]COVER_COPYRIGHT_COLOR]=1 \ +. COLOR \\*[$\\*[DOC_]COVER_COPYRIGHT_COLOR] +. ie !'\\*[$COPYRIGHT_V_ADJ]'' \ +. PRINT \v'\\*[$COPYRIGHT_V_ADJ]'\\*[$\\*[DOC_]COVER_COPYRIGHT] +. el \ +. PRINT \\*[$\\*[DOC_]COVER_COPYRIGHT] +. if \\n[#\\*[DOC_]COVER_COPYRIGHT_COLOR]=1 \ +. gcolor +. \} +. sp |\\n[#VISUAL_B_MARGIN]u +.\" Misc +. if \\n[#\\*[DOC_]COVER_MISC]=1 \{\ +. if \\n[#PRINT_STYLE]=2 \{\ +. fam \\*[$\\*[DOC_]COVER_MISC_FAM] +. ft \\*[$\\*[DOC_]COVER_MISC_FT] +. ps \\n[#DOC_PT_SIZE]u\\*[$\\*[DOC_]COVER_MISC_SIZE_CHANGE] +. vs \\*[$\\*[DOC_]COVER_MISC_LEAD] +. if \\n[#\\*[DOC_]COVER_MISC_COLOR]=1 \ +. COLOR \\*[$\\*[DOC_]COVER_MISC_COLOR] +. \} +. ie !'\\*[$\\*[DOC_]COVER_MISC_1]'' \{\ +. QUAD \\*[$\\*[DOC_]COVER_MISC_QUAD] +. da MISC_DIV +. nr #NEXT_MISC 0 1 +. while \\n[#\\*[DOC_]COVER_MISC_LINES]>=\\n+[#NEXT_MISC] \{\ +. nop \\*[$\\*[DOC_]COVER_MISC_\\n[#NEXT_MISC]] +. br +. \} +. da +. \} +. el \{\ +. QUAD \\*[$MISC_QUAD] +. da MISC_DIV +. nr #NEXT_MISC 0 1 +. while \\n[#MISC_LINES]>=\\n+[#NEXT_MISC] \{\ +. nop \\*[$MISC_\\n[#NEXT_MISC]] +. br +. \} +. da +. \} +. nr #MISC_V_ADJ \\n[#DOC_LEAD]-\\n[.v] +. sp \\n[#MISC_V_ADJ]u +. sp -\\n[dn]u+1 +. nf +. MISC_DIV +. if \\n[#MISC_COLOR]=1 .gcolor +. if \\n[#\\*[DOC_]COVER_MISC_COLOR]=1 .gcolor +. rm MISC_DIV +. rr #MISC_DEPTH +. \} +. if \\n[TOC.RELOCATE]==1 \{\ +. if !\\n[#COVER_BLANKPAGE] \ +. if !rTOC_BH .TOC_AFTER_HERE +. \} +. if '\\$0'DO_COVER' \{\ +. if \\n[TOC.RELOCATE]==6 \ +. if !rTOC_BH .TOC_AFTER_HERE +. \} +. if '\\$0'DO_DOC_COVER' \{\ +. if \\n[TOC.RELOCATE]==4 \ +. if !rTOC_BH .TOC_AFTER_HERE +. \} +. END_COVER +.END +\# +\# Macro to terminate (doc)cover processing +\# +.MAC END_COVER END +. EOL +. vpt +. rr #\\*[DOC_]COVERTEXT_ONLY +. rr #\\*[DOC_]COVER_TITLE +. rr #\\*[DOC_]COVERTITLE +. rr #\\*[DOC_]COVER_SUBTITLE +. rr #\\*[DOC_]COVER_AUTHOR +. rr #\\*[DOC_]COVER_DOCTYPE +. rr #\\*[DOC_]COVER_COPYRIGHT +. rr #\\*[DOC_]COVER_MISC +. rr #\\*[DOC_]COVERTEXT +. rr #\\*[DOC_]COVER_IMAGE +. rr #\\*[DOC_]COVER_BLANKPAGE +. rm $PDF_\\*[DOC_]COVER_LABEL +. rr #\\*[DOC_]COVER +. if '\\*[$COVER_TYPE]'DOC_COVER_' .ds DOC DOC +. rm $COVER_TYPE +. if \\n[#DOC_TYPE]=5 .nr #SKIP 1 +. nr #END_COVER 1 +. NEWPAGE +. rr #NEWPAGE +. rr #SKIP +. if \\n[#PAGINATION_WAS_ON]=1 .nr % +1 +. ie \\n[#\\*[DOC_]COVER_BLANKPAGE]=1 \{\ +. if \\n[TOC.RELOCATE] \ +. if !\\n[#TOC_BH] .TOC_AFTER_HERE +.\" Without the empty PDF_BOOKMARK, (doc)cover BLANKPAGE causes +.\" the PDF outline to place the first doc or chapter before the TOC, +.\" even though PDF output is correct. +. PDF_BOOKMARK 1 +. nop \& +. bp +. rr #\\*[DOC_]COVER_BLANKPAGE +. if !\\n[#\\*[DOC]COVERS_COUNT]=1 .nr % -2 +. rm DOC_ +. \} +. el \ +. if !\\n[#\\*[DOC]COVERS_COUNT]=1 .nr #PAGE_NUM_ADJ -1 +. if !'\\n[.ev]'0' .ev +. if \\n[#PAGINATION_WAS_ON] \{\ +. rr #PAGINATION_WAS_ON +. PAGINATE +. PAGENUMBER \\n%+\\n[#PAGE_NUM_ADJ]-1 +. \} +. if \\n[#HEADERS_WERE_ON] \{\ +. rr #HEADERS_WERE_ON +. HEADERS +. \} +. if \\n[#FOOTERS_WERE_ON] \{\ +. rr #FOOTERS_WERE_ON +. FOOTERS +. \} +. if \\n[#COLUMNS_WERE_ON]=1 \{\ +. rr #COLUMNS_WERE_ON 1 +. nr #COLUMNS 1 +. \} +. rr #DOING_COVER +. if \\n[.ns] .nop \& +. if \\n[#RECTO_VERSO] .nr #RV_POST_COVER 1 +. rm DOC_ +.END +\# +\# +++START THE DOCUMENT+++ +\# +\# THE START MACRO +\# --------------- +\# *Arguments: +\# +\# *Function: +\# Macro to start document processing. Reads in default document +\# style parameters and any parameters the user has changed before +\# issuing START. Using the information gathered in the opening +\# macros, prints appropriate title (or chapter #), subtitle, +\# author and document type (if appropriate). +\# *Notes: +\# The .PRINT \& (zero-width character) is required to get the +\# subsequent .sp request to work as advertised. +\# +\# The overall document line length, family, and point-size +\# are stored in #DOC_L_LENGTH, $DOC_FAM, and #DOC_PT_SIZE for +\# use in the HEADER and FOOTER macros. +\# +.MAC START END +. nr #DOCS 1 +. if \\n[TOC.RELOCATE]==2 \ +. if !\\n[TOC_BH] .TOC_BEFORE_HERE +. if !n .nop \X'ps: exec 0 setlinejoin'\X'ps: exec 0 setlinecap' +. if !\\n[#PRINT_STYLE] \{\ +. PRINTSTYLE TYPEWRITE +. PRINT \& +. po 6P +. ll 39P +. ta \\n[.l]u +. sp |1i-1v +. CENTER +. PRINT "You neglected to enter a PRINTSTYLE." +. ab [mom]: PRINTSTYLE missing. Aborting '\\n[.F]'. +. \} +. if \\n[#LINENUMBERS]=1 \{\ +. nm +. NUMBER_LINES OFF +. nr #LINENUMBERS 2 +. \} +. if \\n[#COLLATE] \{\ +. COPYSTYLE \\*[$COPY_STYLE] +. nr #HEADERS_ON \\n[#HEADER_STATE] +. if \\n[#PAGE_NUM_V_POS]=1 .nr #PAGINATE \\n[#PAGINATION_STATE] +. PRINT \& +. if !'\\*[$RESTORE_PAGENUM_STYLE]'' \{\ +. PAGENUM_STYLE \\*[$RESTORE_PAGENUM_STYLE] +. rm $RESTORE_PAGENUM_STYLE +. \} +. if \\n[#PAGINATE_WAS_ON] \{\ +. PAGINATE +. rr #PAGINATE_WAS_ON +. \} +. \} +. DEFAULTS +. nr #PAGE_TOP \\n[#T_MARGIN]u-\\n[#DOC_LEAD]u +. rr #RESET_TRAPS +. if !r#EN_Q_AUTOLEAD .nr #EN_Q_LEAD \\n[#EN_LEAD] +. if !r#EN_BQ_AUTOLEAD .nr #EN_BQ_LEAD \\n[#EN_LEAD] +.\" TOC/recto-verso stuff +. nr @L_MARGIN \\n[#DOC_L_MARGIN] +. nr @R_MARGIN \\n[#DOC_R_MARGIN] +.\" Covers and doc covers +. if \\n[#DOC_COVERS]=1 \{\ +. if \\n[#DOC_COVER]=1 .DO_DOC_COVER +. \} +. if \\n[#COVERS]=1 \{\ +. if \\n[#COVER]=1 .DO_COVER +. \} +. nr PDFHREF.VIEW.LEADING \\n[PDFHREF.VIEW.LEADING.T] +. if !\\n[#TOC] .RV_HARD_SET_MARGINS +. if \\n[#COLUMNS] .COLUMNS \\n[#NUM_COLS] \\n[#GUTTER]u +. sp |\\n[#DOCHEADER_ADVANCE]u-\\n[#DOC_LEAD]u +.\" Collect TITLE for TOC. +. if !\\n[#TOC]=1 \{\ +. nr #TOC_ENTRY_PN \\n%+\\n[#PAGE_NUM_ADJ] +. af #TOC_ENTRY_PN \\g[#PAGENUMBER] +. ie \\n[#USER_SET_TITLE_ITEM] \{\ +. ds $TOC_TITLE_ITEM \\*[$USER_SET_TITLE_ITEM] +. rr #USER_SET_TITLE_ITEM +. rm $USER_SET_TITLE_ITEM +. \} +. el \{\ +. ie \\n[#DOC_TYPE]=2 \{\ +. ie '\\*[$CHAPTER_TITLE]'' \ +. ds $TOC_TITLE_ITEM \\*[$CHAPTER_STRING] \\*[$CHAPTER] +. el \{\ +. ie '\\*[$CHAPTER]'' \ +. ds $TOC_TITLE_ITEM \\*[$CHAPTER_TITLE] +. el \ +. ds $TOC_TITLE_ITEM \ +\\*[$CHAPTER_STRING] \\*[$CHAPTER]: \\*[$CHAPTER_TITLE] +. \} +. \} +. el \ +. ds $TOC_TITLE_ITEM \\*[$TITLE] +. \} +. if \\n[#TOC_AUTHORS]=1 \{\ +. ie '\\*[$TOC_AUTHORS]'' \ +. as $TOC_TITLE_ITEM / \\*[$AUTHOR_1] +. el \{\ +. as $TOC_TITLE_ITEM / \\*[$TOC_AUTHORS] +. rm $TOC_AUTHORS +. \} +. \} +. as $TOC_TITLE_ITEM \| +. if \\n[#PREFIX_CH_NUM] \ +. ds $TOC_CH_NUM \ + \\n[#CH_NUM].\[toc-hd-num-spacer] +. if \\n[#TOC_PREFIX_CH_NUM] \{\ +. rn $TOC_TITLE_ITEM $TOC_TITLE_ITEM_OLD +. ds $TOC_CH_NUM \ + \\n[#CH_NUM].\[toc-hd-num-spacer] +. if (\\n[#PAD_TOC_CH_NUM]=2)&(\\n[#CH_NUM]<10) \ +. ds $TOC_CH_NUM \h'\w'\0'u'\\*[$TOC_CH_NUM] +. if \\n[#PAD_TOC_CH_NUM]=3 \{\ +. if \\n[#CH_NUM]<10 \ +. ds $TOC_CH_NUM \h'\w'\0'u*2u'\\*[$TOC_CH_NUM] +. if (\\n[#CH_NUM]>=10)&(\\n[#CH_NUM]<100) \ +. ds $TOC_CH_NUM \h'\w'\0'u'\\*[$TOC_CH_NUM] +. \} +. if \\n[#PAD_TOC_CH_NUM]=4 \{\ +. if \\n[#CH_NUM]<10 \ +. ds $TOC_CH_NUM \h'\w'\0'u*3u'\\*[$TOC_CH_NUM] +. if (\\n[#CH_NUM]>=10)&(\\n[#CH_NUM]<100) \ +. ds $TOC_CH_NUM \h'\w'\0'u*2u'\\*[$TOC_CH_NUM] +. if (\\n[#CH_NUM]>=100)&(\\n[#CH_NUM]<1000) \ +. ds $TOC_CH_NUM \h'\w'\0'u'\\*[$TOC_CH_NUM] +. \} +. ds $TOC_TITLE_ITEM \\*[$TOC_CH_NUM]\\*[$TOC_TITLE_ITEM_OLD] +. rm $TOC_TITLE_ITEM_OLD +. \} +. \} +. if !'\\*[$TOC_HEADING]'' \{\ +. HEADING_TO_TOC +. rm $TOC_HEADING +. \} +. if !\\n[#TOC] \{\ +. if !'\\*[$TOC_TITLE_ITEM]'' \{\ +. PDF_BOOKMARK 1 \\*[$TOC_TITLE_ITEM] +. if !r #NO_TOC_ENTRY .TITLE_TO_TOC +. if r #NO_TOC_ENTRY .rr #NO_TOC_ENTRY +. \} +. \} +. if !\\n[#TOC] .nr #POST_TOP 1 +.\" End TITLE collection +. if \\n[#PRINT_PAGENUM_ON_PAGE_1] \{\ +. if \\n[#PAGE_NUM_V_POS]=1 \{\ +. br +. sp |\\n[#HEADER_MARGIN]u +. PRINT_PAGE_NUMBER +. \} +. \} +. rr #COLLATE +. rr #PAGINATION_STATE +.\" End collate stuff +. if \\n[#DOC_TYPE]=5 \{\ +. rr @TOP +. ch RR_@TOP +. \} +. sp |\\n[#DOCHEADER_ADVANCE]u-\\n[#DOC_LEAD]u +. ie \\n[#DOC_HEADER]=0 \{\ +. if \\n[.ns] .rs +. if \\n[#DOC_TYPE]=4 \ +. if !'\\n[.z]'' .di +. nr #STORED_PP_INDENT \\n[#PP_INDENT] +. PARA_INDENT 0 +. PP +. PARA_INDENT \\n[#STORED_PP_INDENT]u +. rr #STORED_PP_INDENT +. ie r #ADVANCE_FROM_TOP \{\ +. br +. sp |\\n[#ADVANCE_FROM_TOP]u-1v +. if \\n[#ADJ_DOC_LEAD]=1 \ +. if !\\n[#DOCHEADER_NO_SHIM] .SHIM_1 +. \} +. el \{\ +. br +. sp |\\n[#T_MARGIN]u-1v +. \} +. if \\n[#COLUMNS] \{\ +. mk dc +. nr #COL_NUM 0 1 +. po \\n[#COL_\\n+[#COL_NUM]_L_MARGIN]u +. nr #L_MARGIN \\n[.o] +. ll \\n[#COL_L_LENGTH]u +. \} +. nr #PP 0 +. \} +. el \{\ +. if \\n[#AUTO_LEAD] .nr #RESTORE_AUTO_LEAD 1 +. nr #CURRENT_LEAD \\n[.v] +. if \\n[#PRINT_STYLE]=2 .vs \\n[#DOC_LEAD]u\\*[$DOCHEADER_LEAD_ADJ] +. nr #DOCHEADER_LEAD_DIFF \\n[#CURRENT_LEAD]-\\n[.v] +. sp +\\n[#DOCHEADER_LEAD_DIFF]u +. if \\n[#RESTORE_AUTO_LEAD] \{\ +. nr #AUTO_LEAD 1 +. nr #AUTOLEAD_VALUE \\n[#SAVED_AUTOLEAD_VALUE] +. \} +. nr #DOCHEADER_LEAD \\n[.v] +. vpt 0 +.\" Default doctype +. if \\n[#DOC_TYPE]=1 \{\ +. if \\n[.ns] \{\ +. rs +. nop \& +. sp -1 +. \} +. ev DOCHEADER +. evc 0 +. L_MARGIN \\n[#DOC_L_MARGIN]u +. LL \\n[#DOC_L_LENGTH]u +. ta \\n[.l]u +. if \\n[#PRINT_STYLE]=1 .DEFAULT_DOCHEADER_TYPEWRITE +. if \\n[#PRINT_STYLE]=2 .DEFAULT_DOCHEADER +. ev +. \} +.\" Chapter doctype +. if \\n[#DOC_TYPE]=2 \{\ +. if \\n[.ns] .rs +. ev DOCHEADER +. evc 0 +. if \\n[#DOCHEADER_COLOR]=1 \ +. COLOR \\*[$DOCHEADER_COLOR] +. L_MARGIN \\n[#DOC_L_MARGIN]u +. LL \\n[#DOC_L_LENGTH]u +. ta \\n[.l]u +. if \\n[#PRINT_STYLE]=1 .CHAPTER_DOCHEADER_TYPEWRITE +. if \\n[#PRINT_STYLE]=2 .CHAPTER_DOCHEADER +. ev +. \} +.\" Named +. if \\n[#DOC_TYPE]=3 \{\ +. if \\n[.ns] \{\ +. rs +. nop \& +. sp -1 +. \} +. ev DOCHEADER +. evc 0 +. if \\n[#DOCHEADER_COLOR]=1 \ +. COLOR \\*[$DOCHEADER_COLOR] +. L_MARGIN \\n[#DOC_L_MARGIN]u +. LL \\n[#DOC_L_LENGTH]u +. ta \\n[.l]u +. if \\n[#PRINT_STYLE]=1 \{\ +. DEFAULT_DOCHEADER_TYPEWRITE +. if !\\n[#NO_PRINT_DOCTYPE] \{\ +. sp +. UNDERSCORE2 3p 2p "\\*[$DOC_TYPE]" +. \} +. \} +. if \\n[#PRINT_STYLE]=2 .NAMED_DOCHEADER +. ev +. \} +. if !\\n[#DOC_TYPE]=4 \{\ +. if \\n[#PRINT_STYLE]=1 .sp +. if \\n[#PRINT_STYLE]=2 .sp \\n[#DOC_LEAD]u*2u +. if \\n[#COLUMNS] \{\ +. nr #COL_NUM 0 1 +. nr #L_LENGTH_FOR_EPI \\n[#L_LENGTH] +. ie \\n[#RV_POST_COVER] \{\ +. nr #COL_\\n+[#COL_NUM]_L_MARGIN \\n[#DOC_L_MARGIN] +. po \\n[#COL_\\n[#COL_NUM]_L_MARGIN]u +. nr #L_MARGIN \\n[.o] +. rr #RV_POST_COVER +. \} +. el \{\ +. po \\n[#COL_\\n+[#COL_NUM]_L_MARGIN]u +. nr #L_MARGIN \\n[.o] +. \} +. LL \\n[#COL_L_LENGTH]u +. ta \\n[.l]u +. \} +. \} +. nr #NO_PRINT_AUTHOR 1 +. nr #NO_PRINT_DOCTYPE 1 +. \} +. vs \\n[#DOC_LEAD]u +. if \\n[#PRINT_STYLE]=1 \ +. if \\n[#SINGLE_SPACE]=1 .sp +. if \\n[#ADJ_DOC_LEAD]=1 \ +. if \\n[#ADVANCE_FROM_TOP]=0 \ +. if \\n[#DOC_HEADER]=1 \ +. if !\\n[#DOCHEADER_NO_SHIM] .SHIM_1 +. if \\n[#COLUMNS] .mk dc +. FAMILY \\*[$DOC_FAM] +. QUAD \\*[$DOC_QUAD] +. CLEANUP_DEFAULTS +. nr #START_FOR_FOOTERS 1 +. if !\\n[#DOC_TYPE]=4 .em TERMINATE +. if \\n[#LINENUMBERS]=2 \{\ +. ie \\n[#PER_SECTION] .NUMBER_LINES 1 +. el .NUMBER_LINES RESUME +. nr #LINENUMBERS 1 +. \} +. if \\n[#RUN_ON]=1 \{\ +. if \\n[#FN_MARKER_STYLE]=1 .RUNON_WARNING +. if \\n[#FN_MARKER_STYLE]=2 .RUNON_WARNING +. \} +. nr PDFHREF.VIEW.LEADING \\n[PDFHREF.VIEW.LEADING.H] +. vpt +. if !r flex .nr flex 1 +. nr flex-spaces 0 +.\" If one-page, don't flex. +. if !dPDF.EXPORT \{\ +. if \\n[#FLEX_ACTIVE] \{\ +. if !\\n[#NO_FLEX] \{\ +. if d pre-toc-\\n%@\\n[#COL_NUM] \ +. nr #NO_FLEX 1 +. if d pre-list-\\n%@\\n[#COL_NUM] \ +. nr #NO_FLEX 1 +. if d page-\\n%@\\n[#COL_NUM] \ +. nr #NO_FLEX 1 +. if '\\*[last-page]'\\n%@\\n[#COL_NUM]' \ +. nr #NO_FLEX 1 +. \} +. \} +. \} +. if \\n[#DOC_TYPE]=5 \{\ +. if \\n[#HDRFTR_BOTH] \ +. HEADER_RECTO \\*[$HDR_RECTO_QUAD] "\\*[$HDR_RECTO_STRING]" +. if \\n[#SLIDE_HEADERS] .HEADER +. if \\n[#HDRFTR_BOTH] \ +. FOOTER_RECTO \\*[$FTR_RECTO_QUAD] "\\*[$FTR_RECTO_STRING]" +. if \\n[#SLIDE_FOOTERS] \ +. PRINT_FOOTER +. sp |\\n[#T_MARGIN]u-\\n[#DOC_LEAD]u +. vpt +. \} +.END +\# +.MAC RR_ADVANCE_FROM_TOP END +. rr #ADVANCE_FROM_TOP +. ch RR_ADVANCE_FROM_TOP +.END +\# +.MAC CLEANUP_DEFAULTS END +. nr #START 1 +. if \\n[#DOC_HEADER]=1 .nr #DOC_HEADER 2 +. rm $TOC_TITLE_ITEM +. rr #MISC_NUM +. rr #MISCS +. rr #NEXT_AUTHOR +. rr #NEXT_MISC +. wh \\n[nl]u+1u RR_ADVANCE_FROM_TOP +. rr #DOCHEADER_NO_SHIM +.END +\# +\# ==================================================================== +\# +\# +++MACROS TO CHANGE SOME DEFAULTS+++ +\# +\# DOCUMENT HEADER +\# --------------- +\# *Argument: +\# | [distance to advance from top of page] [NO_SHIM] +\# *Function: +\# Turns printing of document header on or off. If a second +\# numeric argument with units of measure is given, advances that +\# distance from the top of the page without printing the document +\# header. +\# *Notes: +\# Default is on. If the 1st argument is (which turns +\# document headers off), the optional 2nd argument may be given +\# (with a unit of measure). +\# +.MAC DOCHEADER END +. if \\n[#NUM_ARGS]=0 .nr #DOC_HEADER 1 +. if \\n[#NUM_ARGS]=1 \{\ +. ie '\\$1'NO_SHIM' .nr #DOCHEADER_NO_SHIM 1 +. el .nr #DOC_HEADER 0 +. \} +. if \\n[#NUM_ARGS]>1 \{\ +. nr #DOC_HEADER 0 +. if \B'\\$2' .nr #ADVANCE_FROM_TOP \\$2 +. if '\\$3'NO_SHIM' .nr #DOCHEADER_NO_SHIM 1 +. \} +.END +\# +\# DOCUMENT HEADER LEADING +\# ----------------------- +\# *Arguments: +\# <+|- amount by which to in/decrease leading of doc header> +\# *Function: +\# Stores user supplied lead in/decrease in string $DOCHEADER_LEAD_ADJ. +\# *Notes: +\# A unit of measure must be supplied. Decimal fractions OK. +\# Default is +0, i.e. same as DOC_LEAD. +\# +.MAC DOCHEADER_LEAD END +. ds $DOCHEADER_LEAD_ADJ \\$1 +.END +\# +\# DOCHEADER ADVANCE +\# ----------------- +\# *Arguments: +\# +\# *Function: +\# Creates register #DOCHEADER_ADVANCE, used in START. +\# *Notes: +\# Unit of measure required. +\# Default is same as T_MARGIN. +\# +.MAC DOCHEADER_ADVANCE END +. nr #DOCHEADER_ADVANCE \\$1 +.END +\# +\# DOCUMENT LEFT MARGIN +\# -------------------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies register #DOC_L_MARGIN. +\# *Notes: +\# Affects everything on the page. +\# +.MAC DOC_LEFT_MARGIN END +. if !\\n[#DOCS] .DOC_MACRO_ERROR \\$0 +. br +. nr #DOC_L_MARGIN (\\$1) +. L_MARGIN \\n[#DOC_L_MARGIN]u +.END +\# +\# DOCUMENT RIGHT MARGIN +\# --------------------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies register #DOC_R_MARGIN. +\# *Notes: +\# Affects everything on the page. +\# +.MAC DOC_RIGHT_MARGIN END +. br +. nr #DOC_R_MARGIN (\\$1) +. R_MARGIN \\n[#DOC_R_MARGIN] +. nr #DOC_L_LENGTH \\n[#L_LENGTH] +.END +\# +\# DOCUMENT LINE LENGTH +\# -------------------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies register #DOC_L_LENGTH. +\# *Notes: +\# Affects everything on the page. +\# +.MAC DOC_LINE_LENGTH END +. if !\\n[DOCS] .DOC_MACRO_ERROR \\$0 +. br +. nr #DOC_L_LENGTH (\\$1) +. LL \\n[#DOC_L_LENGTH]u +. ta \\n[.l]u +.END +\# +\# DOCUMENT FAMILY +\# --------------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies string $DOC_FAM. +\# *Notes: +\# Affects everything except headers and footers. +\# +.MAC DOC_FAMILY END +. if !\\n[DOCS] .DOC_MACRO_ERROR \\$0 +. br +. ds $DOC_FAM \\$1 +. ds $FAMILY \\*[$DOC_FAM] +. AUTHOR_FAMILY \\*[$DOC_FAM] +. BLOCKQUOTE_FAMILY \\*[$DOC_FAM] +. DOCHEADER_FAMILY \\*[$DOC_FAM] +. DOCTYPE_FAMILY \\*[$DOC_FAM] +. EPIGRAPH_FAMILY \\*[$DOC_FAM] +. FOOTNOTE_FAMILY \\*[$DOC_FAM] +. HDRFTR_FAMILY \\*[$DOC_FAM] +. LINENUMBER_FAMILY \\*[$DOC_FAM] +. QUOTE_FAMILY \\*[$DOC_FAM] +. SUBTITLE_FAMILY \\*[$DOC_FAM] +. TITLE_FAMILY \\*[$DOC_FAM] +.END +\# +\# DOCUMENT POINT SIZE +\# ------------------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies register #DOC_PT_SIZE. +\# *Notes: +\# DOC_PT_SIZE is the basis for calculating all type sizes in +\# a document. Ignored if PRINTSTYLE TYPEWRITE. +\# +.ALIAS DOC_PT_SIZE PT_SIZE +\# +\# DOCUMENT LEAD +\# ------------- +\# *Argument: +\# [ADJUST] +\# *Function: +\# Creates or modifies register #DOC_LEAD. If the optional +\# ADJUST argument is given, adjusts leading so that the last +\# line of text falls exactly on #B_MARGIN. +\# *Notes: +\# DOC_LEAD is the basis for calculating all leading changes in +\# a document. Default for TYPESET is 16; 24 for TYPEWRITE. +\# +\# Because the visible bottom or footer margin of a page depends +\# on the overall document lead supplied by the register #DOC_LEAD, +\# DOC_LEAD, in the body of a document, should always be associated +\# with the start of a new page (in other words, just before or +\# just after a manual NEWPAGE). Ignored if PRINTSTYLE TYPEWRITE. +\# +.MAC DOC_LEAD END +. if \\n[#IGNORE] .return +. if !\\n[#DOCS] .DOC_MACRO_ERROR \\$0 +. br +. if '\\$0'DOC_LEAD' \{\ +. vs \\$1 +. rr #DOC_AUTOLEAD +. rr #DOC_AUTOLEAD_FACTOR +. nr #DOC_LEAD \\n[.v] +. \} +. nr #RESET_TRAPS 1 +. if !\\n[#ADJ_DOC_LEAD] .nr #REMOVE_ADJ 1 +. if !'\\$0'DOC_LEAD' \{\ +. if '\\$0'EN_LEAD' .nr #DOC_LEAD \\n[#EN_LEAD] +. if '\\$0'BIB_LEAD' .nr #DOC_LEAD \\n[#BIB_LEAD] +. if '\\$0'TOC_LEAD' .nr #DOC_LEAD \\n[#TOC_LEAD] +. if '\\$2'ADJUST' .TRAPS +. rr #RESET_TRAPS +. \} +.END +\# +\# ADJUST DOCUMENT LEAD +\# -------------------- +\# *Arguments: +\# | +\# *Function: +\# Adjusts document lead so that the last line of text falls exactly +\# on #B_MARGIN. +\# +.MAC DOC_LEAD_ADJUST END +. ie '\\$1'' \{\ +. nr #ADJ_DOC_LEAD 1 +. rr #DOC_LEAD_ADJUST_OFF +. \} +. el \{\ +. nr #ADJ_DOC_LEAD 0 +. nr #DOC_LEAD_ADJUST_OFF 1 +. \} +.END +\# +\# SHIM +\# ---- +\# *Argument: +\# None +\# *Function: +\# Advances to the next valid baseline. +\# *Notes: +\# If a user plays around with spacing in a doc (say, with ALD), +\# it isn't easy to get mom back on track so she can achieve +\# perfectly flush bottom margins. Any time SHIM is used, it +\# ensures that the next output line falls on a valid baseline. +\# +\# First, a little convenience macro +\# +.MAC PROCESS_SHIM END +. if !\\n[nl]=\\n[#VALID_BASELINE] \{\ +. while \\n+[#VALID_BASELINE]<\\n[#CURRENT_V_POS] . +. nr #SHIM \\n[#VALID_BASELINE]-\\n[#CURRENT_V_POS] +. \} +.END +\# +\# And a macro to disable SHIM +\# +.MAC NO_SHIM END +. ie '\\$1'' \{\ +. nr #NO_SHIM 1 +. nr #FLEX_ACTIVE 1 +. \} +. el \{\ +. rr #NO_SHIM +. rr #SHIM +. rr #FLEX_ACTIVE +. \} +.END +\# +.nr #NO_SHIM 2 \" Restored to 1 in DEFAULTS. +\# +.MAC SHIM END +. if \\n[#NO_SHIM] \ +. if !'\\$0'SHIM_1' .return +. if !\\n[#NO_FLEX] \{\ +. if !'\\$0'SHIM_1' \{\ +. tm1 "[mom]: \ +SHIM, line \\n[.c], is incompatible with flex-spacing, which is enabled. +. tm1 " \ +Flex-spacing must be disabled with NO_FLEX before using SHIM. +. ab [mom]: Aborting '\\n[.F]', line \\n[.c]. +. \} +. \} +. nr #VALID_BASELINE \\n[#T_MARGIN]-\\n[#DOC_LEAD] \\n[#DOC_LEAD] +. if !r#CURRENT_V_POS .nr #CURRENT_V_POS \\n[.d] +. ie \\n[#ADVANCE_FROM_TOP] \{\ +. ie \\n[#CURRENT_V_POS]<(\\n[#T_MARGIN]-1v) \{\ +. while \\n-[#VALID_BASELINE]>\\n[#CURRENT_V_POS] . +. nr #VALID_BASELINE +\\n[#DOC_LEAD] +. nr #SHIM \\n[#VALID_BASELINE]-\\n[#CURRENT_V_POS] +. \} +. el .PROCESS_SHIM +. \} +. el .PROCESS_SHIM +. nr #SHIM_MAX \\n[#DOC_LEAD]*10/15 +. if !\\n[#CALCULATE_ONLY] \{\ +. if !\\n[defer-count] \ +. if \\n[#SHIM]>\\n[#SHIM_MAX] .sp -1 +' sp \\n[#SHIM]u +. \} +. rr #CURRENT_V_POS +.END +\# +.ALIAS SHIM_1 SHIM +\# +\# ==================================================================== +\# +\# +++FLEX SPACING+++ +\# +\# INSERT FLEX SPACE +\# ----------------- +\# *Arguments: +\# FORCE +\# *Function: +\# Inserts flexible whitespace ("flex-space"). +\# *Notes: +\# FORCE restores flex-spacing if an .ns is preventing it. +\# Useful in conjunction with deferred floated material that +\# plants an .ns after outputting the last deferred float. +\# +.MAC FLEX END +. if !\\n[#NO_SHIM] \{\ +. if \\n[#NO_FLEX] \{\ +. tm1 "[mom]: \ +FLEX, line \\n[.c], is incompatible with shimming, which is presently enabled. +. tm1 " \ +Shimming must be disabled with NO_SHIM before using FLEX. +. ab [mom]: Aborting '\\n[.F]', line \\n[.c]. +. \} +. \} +. if '\\$1'FORCE' \{\ +. nr flex:force 1 +. return +. \} +. if !\\n[#NO_FLEX] \{\ +. if !\\n[.ns] \{\ +. if !\\n[.t]<=\\n[.v] \{\ +. nr flex-spaces +1 +. if dflex-space:\\n[flex]@\\n[#COL_NUM] \{\ +. sp \\*[flex-space:\\n[flex]@\\n[#COL_NUM]] +. \} +. \} +. \} +. \} +.END +\# +.MAC NO_FLEX END +. rr flexed +. ie '\\$1'' \{\ +. nr #NO_FLEX 1 +. if \\n[#FLEX_ACTIVE] .rr #FLEX_ACTIVE +. \} +. el \ +. if !\\n[#DOC_TYPE]=5 .rr #NO_FLEX +.END +\# +\# CALCULATE FLEX SPACES +\# --------------------- +\# *Function: +\# Derives flex-space size by dividing the space remaining before +\# FOOTER by the number of times FLEX was used on the page/col. +\# *Notes: +\# .h is reliable for determining space remaining, but can't be used +\# for columns because it can't be zeroed from one col to the +\# next. Workaround is to use nl for columns and compensate for +\# .br's, .sp's, and .ne's. Here be dragons. +\# +.MAC CALCULATE_FLEX END +. nr flex:target-pos \\n[.p]+\\n[#VARIABLE_FOOTER_POS]-1 +. nr flex:current-pos \\n[.h]-\\n[.v] +. if \\n[#COLUMNS] \{\ +. ie \\n[.trunc] \ +. nr flex:current-pos \\n[nl]-\\n[.v]-(\\n[.trunc]-1) +. el .nr flex:current-pos \\n[nl]-\\n[.v] +. if '\\n[.ev]'tbl*end' \{\ +. nr flex:current-pos \\n[nl]-(\\n[.trunc]-1) +. if \\n[tbl*boxed] .nr flex:current-pos -.65v +. \} +. ie \\n[nl-from-heading] \{\ +. nr flex:current-pos \\n[nl-from-heading]-\\n[.v] +. rr nl-from-heading +. \} +. el \{\ +. if !\\n[.pe] \{\ +. if \\n[nl]=(\\n[.p]+(\\n[#VARIABLE_FOOTER_POS]-1)) \ +. nr flex-spaces -1 +. \} +. \} +. \} +. nr flex:space-remaining \ + \\n[flex:target-pos]-\\n[flex:current-pos] +. if \\n[flex-spaces] \{\ +. nr flex-space:\\n[flex]@\\n[#COL_NUM] \ + \\n[flex:space-remaining]/\\n[flex-spaces] +. if dPDF.EXPORT \{\ +. tm .ds flex-space:\\n[flex]@\\n[#COL_NUM] \ + \\n[flex-space:\\n[flex]@\\n[#COL_NUM]]u +.\" For debugging: catch edge-cases that result in negative +.\" flex-spacing and don't apply flex to the page/column. +. if \\n[flex-space:\\n[flex]@\\n[#COL_NUM]]<0 \{\ +. tm .ds flex-space:\\n[flex]@\\n[#COL_NUM] 0 +. tm .ds Negative flex space \\n%@\\n[#COL_NUM] (\\n[flex-space:\\n[flex]@\\n[#COL_NUM]]) +. \} +. \} +. \} +.END +\# +\# ==================================================================== +\# +\# +++INTERNATIONALIZATION+++ +\# +\# ATTRIBUTE STRING +\# ---------------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies string $ATTRIBUTE_STRING. +\# *Notes: +\# Default is "by". A blank string ("") may be used if no +\# attribution is desired. Blank line results. +\# +.MAC ATTRIBUTE_STRING END +. if !'\\$1'DOC_COVER' \ +. if !'\\$1'COVER' .nr #NEITHER 1 +. if !'\\$1'COVER' \ +. if !'\\$1'DOC_COVER' .nr #NEITHER 1 +. if '\\$1'DOC_COVER' \{\ +. ds $DOC_COVER_ATTRIBUTE_STRING \\$2 +. if '\\*[$DOC_COVER_ATTRIBUTE_STRING]'' \ +. ds $DOC_COVER_ATTRIBUTE_STRING \& +. \} +. if '\\$1'COVER' \{\ +. ds $COVER_ATTRIBUTE_STRING \\$2 +. if '\\*[$COVER_ATTRIBUTE_STRING]'' \ +. ds $COVER_ATTRIBUTE_STRING \& +. \} +. if \\n[#NEITHER]=1 \{\ +. ds $ATTRIBUTE_STRING \\$1 +. rr #NEITHER +. \} +.END +\# +\# CHAPTER STRING +\# -------------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies string $CHAPTER_STRING. +\# *Notes: +\# Default is "chapter". +\# +.MAC CHAPTER_STRING END +. ds $CHAPTER_STRING \\$1 +.END +\# +\# DRAFT STRING +\# ------------ +\# *Argument: +\# +\# *Function: +\# Creates or modifies string $DRAFT_STRING. +\# *Notes: +\# Default is "draft". +\# +.MAC DRAFT_STRING END +. ds $DRAFT_STRING \\$1 +.END +\# +\# REVISION STRING +\# --------------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies string $REVISION_STRING. +\# *Notes: +\# Default is "revision". +\# +.MAC REVISION_STRING END +. ds $REVISION_STRING \\$1 +.END +\# +\# FINIS STRING +\# ------------ +\# *Argument: +\# +\# *Function: +\# Creates or modifies string $FINIS_STRING. +\# *Notes: +\# Default is "END". +\# +.MAC FINIS_STRING END +. ds $FINIS_STRING \\$1 +.END +\# +\# ==================================================================== +\# +\# +++RECTO/VERSO+++ +\# +\# RECTO_VERSO +\# ----------- +\# *Arguments: +\# | +\# *Function: +\# Switches HDRFTR_LEFT and HDRFTR_RIGHT on alternate pages. Also +\# switches page numbers left and right if either is chosen rather +\# than the default centered page numbers. Switches left and right +\# margins if differing values have been entered. +\# *Notes: +\# Default is OFF. +\# +.MAC RECTO_VERSO END +. ie '\\$1'' .nr #RECTO_VERSO 1 +. el .nr #RECTO_VERSO 0 +.END +\# +\# FORCE RECTO +\# ----------- +\# *Function: +\# Forces doccover and cover pages to recto +\# +.MAC FORCE_RECTO END +. ie '\\$1'' \{\ +. nr #FORCE_RECTO 1 +. nr #DOC_COVER_BLANKPAGE 1 +. nr #COVER_BLANKPAGE 1 +. \} +. el \{\ +. rr #FORCE_RECTO +. rr #DOC_COVER_BLANKPAGE +. rr #COVER_BLANKPAGE +. \} +.END +\# +.MAC RV_HARD_SET_MARGINS END +. DOC_LEFT_MARGIN \\n[@L_MARGIN]u +. DOC_RIGHT_MARGIN \\n[@R_MARGIN]u +. po \\n[#DOC_L_MARGIN]u +. LL \\n[#DOC_L_LENGTH]u +.END +\# +\# ==================================================================== +\# +\# +++EPIGRAPHS+++ +\# +\# EPIGRAPH INDENT +\# --------------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies register #EPI_OFFSET_VALUE. +\# *Notes: +\# Default is 2 for TYPEWRITE, 3 for TYPESET. +\# +.MAC EPIGRAPH_INDENT END +. rr #EPI_OFFSET_VALUE +. rm $EPI_OFFSET_VALUE +. ds $EVAL_EI_ARG \\$1 +. substring $EVAL_EI_ARG -1 +. ie \B'\\*[$EVAL_EI_ARG]' .nr #EPI_OFFSET_VALUE \\$1 +. el .ds $EPI_OFFSET_VALUE \\$1 +. rm $EVAL_EI_ARG +.END +\# +\# EPIGRAPH AUTOLEAD +\# ----------------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies register #EPI_AUTOLEAD. +\# *Notes: +\# Default is 2 (for TYPESET; TYPEWRITE doesn't require this). +\# +.MAC EPIGRAPH_AUTOLEAD END +. nr #EPI_AUTOLEAD (p;\\$1) +.END +\# +\# EPIGRAPH +\# -------- +\# *Arguments: +\# BLOCK | +\# *Function: +\# Places an epigraph before the document's text, after the +\# document header, or after a HEAD. +\# *Notes: +\# #EPIGRAPH 1 = centered; 2 = block +\# +\# By default, epigraphs are centered, allowing the user +\# to input them on a line per line basis. To change this +\# behaviour, the user can supply the argument BLOCK, which +\# will produce indented, filled text similar to BLOCKQUOTE. +\# +\# If a block epigraph contains more than one para, ALL paras of +\# the epigraph must be preceded by PP. Otherwise, PP is optional. +\# +.MAC EPIGRAPH END +. nr #PP_STYLE 2 +. nr #Q_PP 0 +. if \\n[#LINENUMBERS]=1 \{\ +. NUMBER_LINES OFF +. nr #LINENUMBERS 2 +. \} +. if \\n[#START] \{\ +. if \\n[#PRINT_STYLE]=1 \ +. if \\n[#AUTHOR_LINES]=1 .sp \\n[#DOC_LEAD]u +. \} +. ie '\\$1'' \{\ +. nr #EPIGRAPH 1 +. ev EPIGRAPH +. nr #IN_DIVER 1 +. ll \\n[#L_LENGTH]u +. ta \\n[.l]u +. CHECK_INDENT +. if \\n[#COLUMNS] \{\ +. ie \\n[#START] \{\ +. ll \\n[#DOC_L_LENGTH]u +. ta \\n[.l]u +. \} +. el \{\ +. ll \\n[#COL_L_LENGTH]u +. ta \\n[.l]u +. \} +. \} +. CENTER +. if \\n[#PRINT_STYLE]=1 \{\ +. fam \\*[$TYPEWRITER_FAM] +. ft R +. if '\\*[$EPI_FT]'I' .FT I +. ps \\*[$TYPEWRITER_PS] +. ie \\n[#SINGLE_SPACE] .vs \\n[#DOC_LEAD]u +. el .vs \\n[#DOC_LEAD]u/2u +. nr #EPI_LEAD \\n[#LEAD] +. nr #EPI_LEAD_DIFF \\n[#DOC_LEAD]-\\n[#EPI_LEAD] +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. FAMILY \\*[$EPI_FAM] +. FT \\*[$EPI_FT] +. ps \\n[#DOC_PT_SIZE]u\\*[$EPI_SIZE_CHANGE] +. if \\n[#EPI_COLOR]=1 \{\ +. nf +\m[\\*[$EPI_COLOR]] +. EOL +. \} +. vs \\n[.ps]u+\\n[#EPI_AUTOLEAD]u +. nr #EPI_LEAD \\n[#LEAD] +. nr #EPI_LEAD_DIFF \\n[#DOC_LEAD]-\\n[#EPI_LEAD] +. \} +. di EPI_TEXT +. nr #DIVERSIONS_HY_MARGIN (p;\\n[.ps]u*2.75)/1000 +. HY_SET 1 \\n[#DIVERSIONS_HY_MARGIN]u (\\n[#PT_SIZE]u/1000u/8u)p +. hy 14 +. nr #EPI_ACTIVE 1 +. \} +. el \{\ +. ie '\\$1'BLOCK' \{\ +. nr #EPIGRAPH 2 +. ev EPIGRAPH +. evc 0 +. ie \\n[#START] \{\ +. ie \\n[#COLUMNS] \{\ +. ie r#EPI_OFFSET_VALUE \ +. ll \ +\\n[#L_LENGTH_FOR_EPI]u-(\\n[#PP_INDENT]u*(\\n[#EPI_OFFSET_VALUE]u*2u)) +. el \ +. ll \ +\\n[#L_LENGTH_FOR_EPI]u-(\\*[$EPI_OFFSET_VALUE]u*2u) +. ta \\n[.l]u +. \} +. el \{\ +. ie r#EPI_OFFSET_VALUE \ +. ll \ +\\n[#L_LENGTH]u-(\\n[#PP_INDENT]u*(\\n[#EPI_OFFSET_VALUE]u*2u)) +. el \ +. ll \\n[#L_LENGTH]u-(\\*[$EPI_OFFSET_VALUE]*2u) +. ta \\n[.l]u +. \} +. \} +. el \{\ +. ie r#EPI_OFFSET_VALUE \ +. ll \ +\\n[#L_LENGTH]u-(\\n[#PP_INDENT]u*(\\n[#EPI_OFFSET_VALUE]u*2u)) +. el \ +. ll \\n[#L_LENGTH]u-(\\*[$EPI_OFFSET_VALUE]*2u) +. ta \\n[.l]u +. if \\n[#COLUMNS] \{\ +. ie r#EPI_OFFSET_VALUE \ +. ll \ +\\n[#COL_L_LENGTH]u-(\\n[#PP_INDENT]u*(\\n[#EPI_OFFSET_VALUE]u*2u)) +. el \ +. ll \\n[#COL_L_LENGTH]u-(\\*[$EPI_OFFSET_VALUE]*2u) +. ta \\n[.l]u +. \} +. CHECK_INDENT +. \} +. if \\n[#PRINT_STYLE]=1 \{\ +. fam \\*[$TYPEWRITER_FAM] +. ft R +. if '\\*[$EPI_FT]'I' .FT I +. ps \\*[$TYPEWRITER_PS] +. ie \\n[#SINGLE_SPACE] .vs \\n[#DOC_LEAD]u +. el .vs \\n[#DOC_LEAD]u/2u +. QUAD LEFT +. HY OFF +. nr #EPI_LEAD \\n[#LEAD] +. nr #EPI_LEAD_DIFF \\n[#DOC_LEAD]-\\n[#EPI_LEAD] +. di EPI_TEXT +. nr #EPI_ACTIVE 1 +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. FAMILY \\*[$EPI_FAM] +. FT \\*[$EPI_FT] +. ps \\n[#DOC_PT_SIZE]u\\*[$EPI_SIZE_CHANGE] +. if \\n[#EPI_COLOR]=1 \{\ +. nf +\m[\\*[$EPI_COLOR]] +. EOL +. \} +. vs \\n[.ps]u+\\n[#EPI_AUTOLEAD]u +. QUAD \\*[$EPI_QUAD] +. nr #DIVERSIONS_HY_MARGIN (p;\\n[.ps]u*2.75)/1000 +. HY_SET 1 \\n[#DIVERSIONS_HY_MARGIN]u (\\n[#PT_SIZE]u/1000u/8u)p +. hy 14 +. nr #EPI_LEAD \\n[#LEAD] +. nr #EPI_LEAD_DIFF \\n[#DOC_LEAD]-\\n[#EPI_LEAD] +. di EPI_TEXT +. nr #EPI_ACTIVE 1 +. \} +. \} +. el .DO_EPIGRAPH +. \} +.END +\# +\# DO EPIGRAPH +\# ----------- +\# *Arguments: +\# +\# *Function: +\# Ends diversion started in EPIGRAPH. Makes spacing +\# adjustments to compensate for the difference between epigraph +\# leading and overall document leading, so that the bottom of +\# the pages remain flush. +\# *Notes: +\# In addition to its usual place at the beginning of a +\# document, EPIGRAPH may also be used after HEAD. +\# +.MAC DO_EPIGRAPH END +. br +. di +. rr #IN_DIVER +. if \\n[#RESET_FN_COUNTERS]=2 \{\ +. if !\\n[#FN_COUNT]=1 \{\ +. if ((\\n[#PAGE_LENGTH]+\\n[#VARIABLE_FOOTER_POS])+\\n[#DIVER_DEPTH])>(\\n[#PAGE_LENGTH]+\\n[#VARIABLE_FOOTER_POS]) \{\ +. DIVER_FN_2_POST +. rr #RESET_FN_COUNTERS +. \} +. \} +. \} +. nr #SAVED_FN_NUMBER \\n[#FN_NUMBER] +. nr #DONE_ONCE 0 1 +. REMOVE_INDENT +. ev +. nr #EPI_DEPTH \\n[#DIVER_DEPTH]-\\n[#EPI_LEAD] +. nr #EPI_LINES \\n[#EPI_DEPTH]/\\n[#EPI_LEAD] +. ie \\n[#START] \{\ +. if !\\n[#NO_SHIM] .RLD \\n[#SHIM]u +. nr #EPI_WHITESPACE (\\n[#DOC_LEAD]*\\n[#EPI_LINES])-\\n[#EPI_DEPTH] +. while \\n[#EPI_WHITESPACE]>\\n[#DOC_LEAD] \{\ +. nr #EPI_WHITESPACE -\\n[#DOC_LEAD] +. \} +. if \\n[#PRINT_STYLE]=1 \ +. if !\\n[#SINGLE_SPACE]=1 .ALD \\n[#DOC_LEAD]u +. if \\n[#PRINT_STYLE]=2 \{\ +. ie !\\n[#DOC_TYPE]=2 .RLD \\n[#DOC_LEAD]u +. el \{\ +. ie '\\*[$CHAPTER_TITLE]'' .RLD \\n[#DOC_LEAD]u +. el .if '\\*[$CHAPTER]'' .RLD \\n[#DOC_LEAD]u +. \} +. if \\n[#EPI_WHITESPACE]<\\n[#DOC_LEAD] \ +. ALD \\n[#EPI_LEAD_DIFF]u+(\\n[#EPI_WHITESPACE]u/2u) +. if \\n[#EPI_WHITESPACE]>\\n[#DOC_LEAD] \ +. ALD \ +\\n[#EPI_LEAD_DIFF]u+(\\n[#EPI_WHITESPACE]u/2u)-\\n[#DOC_LEAD]u +. \} +. \} +. el \{\ +. ie \\n[#EPI_DEPTH]<\\n[#TRAP_DISTANCE] \{\ +. nr #EPI_FITS 1 +. nr #EPI_WHITESPACE (\\n[#DOC_LEAD]*\\n[#EPI_LINES])-\\n[#EPI_DEPTH] +. while \\n[#EPI_WHITESPACE]>\\n[#DOC_LEAD] \{\ +. nr #EPI_WHITESPACE -\\n[#DOC_LEAD] +. \} +. ie \\n[#PRINT_STYLE]=1 \ +. ALD \\n[#DOC_LEAD]u/2u +. el \{\ +. if \\n[#EPI_WHITESPACE]<\\n[#DOC_LEAD] \ +. ALD \ +\\n[#EPI_LEAD_DIFF]u+(\\n[#EPI_WHITESPACE]u/2u) +. if \\n[#EPI_WHITESPACE]>\\n[#DOC_LEAD] \ +. ALD \ +\\n[#EPI_LEAD_DIFF]u+(\\n[#EPI_WHITESPACE]u/2u)-\\n[#DOC_LEAD]u +. \} +. if \\n[#DIVER_FN]=2 .rr #DIVER_FN +. \} +. el \{\ +. nr #EPI_LINES_TO_TRAP 0 1 +. while \\n[#EPI_LEAD]*\\n+[#EPI_LINES_TO_TRAP]<\\n[#TRAP_DISTANCE] \{\ +. nr #LOOP 1 +. \} +. nr #EPI_LINES_TO_TRAP -1 +. nr #EPI_WHITESPACE \ +(\\n[#EPI_LINES_TO_TRAP]*\\n[#DOC_LEAD])-(\\n[#EPI_LINES_TO_TRAP]*\\n[#EPI_LEAD]) +. while \\n[#EPI_WHITESPACE]>\\n[#DOC_LEAD] \{\ +. nr #EPI_WHITESPACE -\\n[#DOC_LEAD] +. \} +. if \\n[#EPI_WHITESPACE]<\\n[#DOC_LEAD] \ +. ALD \\n[#EPI_WHITESPACE]u +. if \\n[#EPI_WHITESPACE]>\\n[#DOC_LEAD] \ +. ALD \\n[#EPI_WHITESPACE]u-\\n[#DOC_LEAD]u +. \} +. \} +. SET_EPI_OFFSET +. nf +. EPI_TEXT +. br +. ie \\n[#START] \{\ +. if \\n[#PRINT_STYLE]=1 .SHIM_1 +. if \\n[#PRINT_STYLE]=2 \{\ +. if \\n[#EPI_WHITESPACE]<\\n[#DOC_LEAD] \ +. ALD \\n[#EPI_WHITESPACE]u/2u +. if \\n[#EPI_WHITESPACE]>\\n[#DOC_LEAD] \ +. ALD (\\n[#EPI_WHITESPACE]u/2u)-\\n[#DOC_LEAD]u +. SHIM +. \} +. \} +. el \{\ +. rr #EPI_ACTIVE +. ie \\n[#EPI_FITS] \{\ +. ie \\n[#FN_FOR_EPI] \{\ +. nr #EPI_LINES_TO_END 1 +. nr #EPI_WHITESPACE \ +(\\n[#EPI_LINES_TO_END]*\\n[#DOC_LEAD])-(\\n[#EPI_LINES_TO_END]*\\n[#EPI_LEAD]) +. while \\n[#EPI_WHITESPACE]>\\n[#DOC_LEAD] \{\ +. nr #EPI_WHITESPACE -\\n[#DOC_LEAD] +. \} +. ALD \\n[#EPI_WHITESPACE]u-(\\n[#DOC_LEAD]u-\\n[#EPI_LEAD]u) +. \} +. el \{\ +. ie \\n[#PRINT_STYLE]=1 \ +. SHIM_1 +. el \{\ +. if \\n[#EPI_WHITESPACE]<\\n[#DOC_LEAD] \ +. ALD \\n[#EPI_WHITESPACE]u/2u +. if \\n[#EPI_WHITESPACE]>\\n[#DOC_LEAD] \ +. ALD (\\n[#EPI_WHITESPACE]u/2u)-\\n[#DOC_LEAD]u +. \} +. \} +. SHIM +. \} +. el \{\ +. nr #EPI_LINES_TO_END \\n[#EPI_LINES]-\\n[#EPI_LINES_TO_TRAP] +. if \\n[#LOOP] .nr #EPI_LINES_TO_END +1 +. rr #LOOP +. nr #EPI_WHITESPACE \ +(\\n[#EPI_LINES_TO_END]*\\n[#DOC_LEAD])-(\\n[#EPI_LINES_TO_END]*\\n[#EPI_LEAD]) +. while \\n[#EPI_WHITESPACE]>\\n[#DOC_LEAD] \{\ +. nr #EPI_WHITESPACE -\\n[#DOC_LEAD] +. \} +. ALD \\n[#EPI_WHITESPACE]u-(\\n[#DOC_LEAD]u-\\n[#EPI_LEAD]u) +. if \\n[#PRINT_STYLE]=1 \{\ +. if !\\n[#SINGLE_SPACE] \{\ +. nr #EPI_LINES_EVEN \\n[#EPI_LINES_TO_END]%2 +. ie \\n[#EPI_LINES_EVEN] .ALD .5v +. el .RLD .5v +. rr #EPI_LINES_EVEN +. \} +. \} +. \} +. \} +. nr #PP_STYLE 1 +. rr #EPI_FITS +. ALD \\n[#DOC_LEAD]u +. QUAD \\*[$DOC_QUAD] +. po \\n[#L_MARGIN]u +. if \\n[#COLUMNS] \{\ +. po \\n[#COL_\\n[#COL_NUM]_L_MARGIN]u +. nr #L_MARGIN \\n[.o] +. \} +. if \\n[#START] \{\ +. if \\n[#COLUMNS] \{\ +. po \\n[#COL_\\n[#COL_NUM]_L_MARGIN]u +. nr #L_MARGIN \\n[.o] +. mk dc +. \} +. \} +. if \\n[#LINENUMBERS]=2 \{\ +. NUMBER_LINES RESUME +. nr #LINENUMBERS 1 +. \} +.END +\# +.MAC SET_EPI_OFFSET END +. if \\n[#EPIGRAPH]=1 \{\ +. po \\n[#L_MARGIN]u +. if \\n[#COLUMNS] \{\ +. po \\n[#COL_\\n[#COL_NUM]_L_MARGIN]u +. nr #L_MARGIN \\n[.o] +. \} +. \} +. if \\n[#EPIGRAPH]=2 \{\ +. ie !\\n[#EPI_OFFSET_VALUE]=0 \ +. nr #EPI_OFFSET \ +\\n[#L_MARGIN]+(\\n[#PP_INDENT]*\\n[#EPI_OFFSET_VALUE]) +. el \ +. if !'\\*[$EPI_OFFSET_VALUE]'' \ +. nr #EPI_OFFSET \\n[#L_MARGIN]+\\*[$EPI_OFFSET_VALUE] +. if \\n[#COLUMNS] \{\ +. ie !\\n[#EPI_OFFSET_VALUE]=0 \ +. nr #EPI_OFFSET \ +\\n[#COL_\\n[#COL_NUM]_L_MARGIN]+(\\n[#PP_INDENT]*\\n[#EPI_OFFSET_VALUE]) +. el \ +. if !'\\*[$EPI_OFFSET_VALUE]'' \ +. nr #EPI_OFFSET \ +\\n[#COL_\\n[#COL_NUM]_L_MARGIN]+\\*[$EPI_OFFSET_VALUE] +. \} +. if !'\\$0'GET_EPI_OFFSET' \ +. if !\\n[#EPI_OFFSET]=0 .po \\n[#EPI_OFFSET]u +. \} +.END +. +.ALIAS GET_EPI_OFFSET SET_EPI_OFFSET +\# +\# ==================================================================== +\# +\# +++FINIS MACRO+++ +\# +\# FINIS +\# ----- +\# *Arguments: +\# +\# *Function: +\# Deposits --END-- at the end of a document. +\# +.MAC FINIS END +. if !\\n[@TOP] \{\ +. if \\n[.t]<=2v \{\ +. tm1 "[mom]: '\\n[.F]': Insufficient room to print \\$0 on last page. +. return +. \} +. \} +. br +. ev FINIS +. evc 0 +. if \\n[#TAB_ACTIVE] .TQ +. if \\n[#INDENT_ACTIVE] .IQ CLEAR +. nr #EM_ADJUST (1m/8) +. if \\n[#COLUMNS] \{\ +. po \\n[#COL_\\n[#COL_NUM]_L_MARGIN]u +. nr #L_MARGIN \\n[.o] +. \} +. ALD \\n[#DOC_LEAD]u +. CENTER +. if \\n[#FINIS_STRING_CAPS]=1 .CAPS +. if \\n[#PRINT_STYLE]=1 \{\ +. ie !\\n[#FINIS_NO_DASHES] .PRINT "--\\*[$FINIS_STRING]-- +. el .PRINT "\\*[$FINIS_STRING] +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. if \\n[#FINIS_COLOR]=1 .COLOR \\*[$FINIS_COLOR] +. ie !\\n[#FINIS_NO_DASHES] .ds $FINIS_DASH \ +\v'-\\n[#EM_ADJUST]u'\[em]\v'+\\n[#EM_ADJUST]u' +. el .rm $FINIS_DASH +. PRINT \ +\\*[$FINIS_DASH]\\*[$FINIS_STRING]\\*[$FINIS_DASH]\c +. \} +. EL +. if \\n[#FINIS_COLOR]=1 .gcolor +. if \\n[#FINIS_STRING_CAPS]=1 .CAPS OFF +. ev +. pdfsync +.END +\# +.MAC FINIS_STRING_CAPS END +. ie '\\$1'' .nr #FINIS_STRING_CAPS 1 +. el .nr #FINIS_STRING_CAPS 0 +.END +. +.ALIAS FINIS_CAPS FINIS_STRING_CAPS +\# +.MAC FINIS_NO_DASHES END +. nr #FINIS_NO_DASHES 1 +.END +\# +\# ==================================================================== +\# +\# +++HEADERS/FOOTERS+++ +\# +\# Define a string so that the current page number can be incorporated +\# into the strings for hdrftr left, right, and center. NOTE: This is +\# not the same thing as using the shortform # in hdrftr strings. +\# +.ds PAGE# \En[#PAGENUMBER] +.ALIAS SLIDE# PAGE# +\# +.MAC RESTORE_SPACE END +. if !\\n[#START] .vpt 0 +. if \\n[@TOP] \{\ +. ch RR_@TOP +. rr @TOP +. \} +. if \\n[#NEWPAGE] .rr #NEWPAGE +. if \\n[.u]=1 .nr #FILLED 1 +. nf +. rs +. nop \& +. sp -1 +. if \\n[#FILLED] \{\ +. fi +. rr #FILLED +. \} +. if !\\n[#START] .vpt +.END +\# +\# HDRFTR RULE GAP +\# --------------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies register #HDRFTR_RULE_GAP to hold amount +\# of space between header/footer and header/footer rule. +\# *Notes: +\# Default is 4p. +\# +.MAC HDRFTR_RULE_GAP END +. nr #HDRFTR_RULE_GAP (\\$1) +. if '\\$0'HEADER_RULE_GAP' \ +. nr #HEADER_RULE_GAP \\n[#HDRFTR_RULE_GAP] +. if '\\$0'FOOTER_RULE_GAP' \ +. nr #FOOTER_RULE_GAP \\n[#HDRFTR_RULE_GAP] +.END +\# +\# HDRFTR LEFT +\# ----------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies string $HDRFTR_LEFT. +\# Creates register #USER_DEF_HDRFTR_LEFT, which, if 1, +\# overrides the $HDRFTR_LEFT string created by default +\# in DEFAULTS. +\# *Notes: +\# Especially useful if doc has more than one author, and a list +\# of authors by last name is desired in header/footers. +\# Default is author. +\# +\# If the argument is the # character, simply prints the current +\# page number. +\# +\# If the user wants to incorporate the page number into the string, +\# \*[PAGE#] must be used. For example, if the user wants to put +\# an ellipsis before the page number in the string, s/he should use +\# ...\*[PAGE#], not ...# +\# +.MAC HDRFTR_LEFT END +. nr #USER_DEF_HDRFTR_LEFT 1 +. ds $HDRFTR_LEFT \\$1 +.END +\# +\# HDRFTR CAPS AND SMALLCAPS +\# ------------------------------------ +\# *Argument: +\# | +\# *Function: +\# Turns capitalisation of $HDRFTR_ on or off. +\# *Notes: +\# Default for RIGHT (ie AUTHOR) is on. +\# +.MAC CAPS_SMALLCAPS_WARNING END +. tm1 "[mom]: At line \\n[.c], both CAPS and SMALLCAPS have been enabled for HEADER_\\$1. +. tm1 " CAPS takes precedence. +.END +. +.MAC _HDRFTR_CAPS END +. ds $HDR_FTR \\$0 +. substring $HDR_FTR 0 5 \" HEADER or FOOTER +. ds POSITION \\$0 +. substring POSITION 7 7 +. if '\\*[POSITION]'L' .ds POSITION LEFT +. if '\\*[POSITION]'C' .ds POSITION CENTER +. if '\\*[POSITION]'R' .ds POSITION RIGHT +. if \\n[#HDRFTR_\\*[POSITION]_SMALLCAPS]=1 \ +. CAPS_SMALLCAPS_WARNING \\*[POSITION] +. ie '\\$1'' .nr #HDRFTR_\\*[POSITION]_CAPS 1 +. el \{\ +. nr #HDRFTR_\\*[POSITION]_CAPS 0 +. ds $HDRFTR_\\*[POSITION]_SIZE_CHANGE +0 +. \} +.END +. +.MAC _HDRFTR_SMALLCAPS END +. ds $HDR_FTR \\$0 +. substring $HDR_FTR 0 5 \" HEADER or FOOTER +. ds POSITION \\$0 +. substring POSITION 7 7 +. if '\\*[POSITION]'L' .ds POSITION LEFT +. if '\\*[POSITION]'C' .ds POSITION CENTER +. if '\\*[POSITION]'R' .ds POSITION RIGHT +. if \\n[#HDRFTR_\\*[POSITION]_CAPS]=1 \ +. CAPS_SMALLCAPS_WARNING \\*[POSITION] +. ie '\\$1'' .nr #HDRFTR_\\*[POSITION]_SMALLCAPS 1 +. el \ +. nr #HDRFTR_\\*[POSITION]_SMALLCAPS 0 +.END +\# +\# HDRFTR CENTER +\# ------------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies string $HDRFTR_CENTER. +\# Creates register #USER_DEF_HDRFTR_CENTER, which, if 1, +\# overrides the $HDRFTR_CENTER string created by default +\# in COPYSTYLE. +\# *Notes: +\# Default is document type if DOCTYPE NAMED, Chapter # if DOCTYPE +\# CHAPTER, draft and revision number if COPYSTYLE DRAFT. +\# +\# If the argument is the # character, simply prints the current +\# page number. +\# +\# If the user wants to incorporate the page number into the string, +\# \*[PAGE#] must be used. For example, if the user wants to put +\# an ellipsis before the page number in the string, s/he should use +\# ...\*[PAGE#], not ...# +\# +.MAC HDRFTR_CENTER END +. nr #USER_DEF_HDRFTR_CENTER 1 +. if '\\$0'HEADER_CENTER' \{\ +. ds $HDRFTR_CENTER_OLD \\*[$HDRFTR_CENTER] +. ds $HDRFTR_CENTER_NEW \\$1 +. \} +. if '\\$0'FOOTER_CENTRE' \{\ +. ds $HDRFTR_CENTER_OLD \\*[$HDRFTR_CENTER] +. ds $HDRFTR_CENTER_NEW \\$1 +. \} +. ie '\\$1'TOC' .ds $TOC_HDRFTR_CENTER \\$2 +. el .ds $HDRFTR_CENTER \\$1 +.END +\# +\# HDRFTR CENTER CAPS AND SMALLCAPS +\# -------------------------------- +\# *Argument: +\# | +\# *Function: +\# Turns capitalisation of $HDRFTR_CENTER (typically, doctype of +\# the document) on or off. +\# *Notes: +\# Default is on. +\# +.MAC HDRFTR_CENTER_SMALLCAPS END +. if \\n[#HDRFTR_CENTER_SMALLCAPS]=1 \ +. CAPS_SMALLCAPS_WARNING CENTER +. ie '\\$1'' .nr #HDRFTR_CENTER_SMALLCAPS 1 +. el \ +. nr #HDRFTR_CENTER_SMALLCAPS 0 +.END +\# +\# HDRFTR CENTER PADDING +\# --------------------- +\# *Argument: +\# LEFT | RIGHT +\# *Function: +\# Creates or modifies registers #HDRFTR_CTR_PAD_LEFT or +\# #HDRFTR_CTR_PAD_RIGHT. +\# *Notes: +\# By default, the HDRFTR_CENTER string is centered on the doc +\# line length. Long titles or long author names can screw up +\# visual centering, or create overprints. This macro allows the +\# user to pad the center string by the specified amount of space +\# to fix these problems. +\# +\# A unit of measure is required. +\# +.MAC HDRFTR_CENTER_PAD END +. if '\\$1'LEFT' .nr #HDRFTR_CTR_PAD_LEFT (\\$2) +. if '\\$1'RIGHT' .nr #HDRFTR_CTR_PAD_RIGHT (\\$2) +.END +\# +\# SWITCH HDRFTR CENTER PADDING SIDE (support macro) +\# ------------------------------------------------- +\# *Argument: +\# +\# *Function: +\# Switches the padding side of hdrftr center padding. +\# *Notes: +\# Required to keep spacing around hdrftr string constant +\# in recto/verso documents. +\# +.MAC SWITCH_HDRFTR_CENTER_PAD END +. nr #HDRFTR_CTR_PAD_TMP \\n[#HDRFTR_CTR_PAD_LEFT] +. HDRFTR_CENTER_PAD LEFT \\n[#HDRFTR_CTR_PAD_RIGHT]u +. HDRFTR_CENTER_PAD RIGHT \\n[#HDRFTR_CTR_PAD_TMP]u +.END +\# +\# HDRFTR RIGHT +\# ------------ +\# *Argument: +\# +\# *Function: +\# Creates or modifies string $HDRFTR_RIGHT. +\# Creates register #USER_DEF_HDRFTR_RIGHT, which, if 1, +\# overrides the $HDRFTR_RIGHT string created by default +\# in DEFAULTS. +\# *Notes: +\# Default is document title. +\# +\# If the argument is the # character, simply prints the current +\# page number. +\# +\# If the user wants to incorporate the page number into the string, +\# \*[PAGE#] must be used. For example, if the user wants to put +\# an ellipsis before the page number in the string, s/he should use +\# ...\*[PAGE#], not ...# +\# +.MAC HDRFTR_RIGHT END +. nr #USER_DEF_HDRFTR_RIGHT 1 +. ds $HDRFTR_RIGHT \\$1 +.END +\# +\# HDRFTR RIGHT CAPS AND SMALLCAPS +\# ------------------------------- +\# *Argument: +\# | +\# *Function: +\# Turns capitalisation of $HDRFTR_RIGHT (typically, the title of +\# the document) on or off. +\# *Notes: +\# Default is on. +\# +.MAC HDRFTR_RIGHT_SMALLCAPS END +. if \\n[#HDRFTR_RIGHT_SMALLCAPS]=1 \ +. CAPS_SMALLCAPS_WARNING RIGHT +. ie '\\$1'' .nr #HDRFTR_RIGHT_SMALLCAPS 1 +. el \ +. nr #HDRFTR_RIGHT_SMALLCAPS 0 +.END +\# +\# HDRFTR RULE +\# ----------- +\# *Arguments: +\# | +\# *Function: +\# If invoked via the alias HDRFTR_RULE_INTERNAL in HDRFTR, prints a rule +\# under the header/over the footer. Otherwise, turns HDRFTR_RULE +\# on or off. +\# +.MAC HDRFTR_RULE END +. if r #HEADERS_ON \ +. if \\n[#HEADERS_ON]=1 .nr #HDRFTR_RULE_GAP \\n[#HEADER_RULE_GAP] +. if r #FOOTERS_ON \ +. if \\n[#FOOTERS_ON]=1 .nr #HDRFTR_RULE_GAP \\n[#FOOTER_RULE_GAP] +. if '\\$0'HDRFTR_RULE_INTERNAL' \{\ +. ie \\n[#USERDEF_HDRFTR] \{\ +. nr #CAP_HEIGHT_ADJUST \\n[#HDRFTR_HEIGHT] +. if \\n[#HEADERS_ON] \{\ +. rt \\n[y]u +. ALD \\n[#HDRFTR_RULE_GAP]u +. nr #HDRFTR_RULE_WEIGHT \\n[#HEADER_RULE_WEIGHT] +. nr #HDRFTR_RULE_WEIGHT_ADJ \\n[#HEADER_RULE_WEIGHT_ADJ] +. \} +. if \\n[#FOOTERS_ON] \{\ +. rt \\n[y]u +. RLD \ +\\n[#HDRFTR_RULE_GAP]u+\\n[#CAP_HEIGHT_ADJUST]u+\\n[#FOOTER_RULE_WEIGHT]u +. nr #HDRFTR_RULE_WEIGHT \\n[#FOOTER_RULE_WEIGHT] +. nr #HDRFTR_RULE_WEIGHT_ADJ \\n[#FOOTER_RULE_WEIGHT_ADJ] +. \} +. ie \\n[#HDRFTR_RULE_COLOR]=1 \{\ +\m[\\*[$HDRFTR_RULE_COLOR]]\ +\D't \\n[#HDRFTR_RULE_WEIGHT]u'\ +\h'|0'\ +\v'+\\n[#HDRFTR_RULE_WEIGHT_ADJ]u'\ +\D'l \\n[#DOC_L_LENGTH]u 0'\ +\D't \\n[#RULE_WEIGHT]u'\ +\h'-\\n[#RULE_WEIGHT]u'\ +\m[] +. \} +. el \{\ +\D't \\n[#HDRFTR_RULE_WEIGHT]u'\ +\h'|0'\ +\v'+\\n[#HDRFTR_RULE_WEIGHT_ADJ]u'\ +\D'l \\n[#DOC_L_LENGTH]u 0'\ +\D't \\n[#RULE_WEIGHT]u'\ +\h'-\\n[#RULE_WEIGHT]u' +. \} +. br +. \} +. el \{\ +. if \\n[#PRINT_STYLE]=1 .nr #CAP_HEIGHT_ADJUST \\n[#CAP_HEIGHT] +. if \\n[#PRINT_STYLE]=2 \{\ +. ie \\n[#LEFT_CAP_HEIGHT]>\\n[#CENTER_CAP_HEIGHT] \ +. nr #CAP_HEIGHT_ADJUST \\n[#LEFT_CAP_HEIGHT] +. el .nr #CAP_HEIGHT_ADJUST \\n[#CENTER_CAP_HEIGHT] +. ie \\n[#CAP_HEIGHT_ADJUST]>\\n[#RIGHT_CAP_HEIGHT] \ +. nr #CAP_HEIGHT_ADJUST \\n[#CAP_HEIGHT_ADJUST] +. el .nr #CAP_HEIGHT_ADJUST \\n[#RIGHT_CAP_HEIGHT] +. \} +. if \\n[#HEADERS_ON] \{\ +. rt \\n[y]u +. ALD \\n[#HDRFTR_RULE_GAP]u +. nr #HDRFTR_RULE_WEIGHT \\n[#HEADER_RULE_WEIGHT] +. nr #HDRFTR_RULE_WEIGHT_ADJ \\n[#HEADER_RULE_WEIGHT_ADJ] +. \} +. if \\n[#FOOTERS_ON] \{\ +. rt \\n[y]u +. RLD \ +\\n[#HDRFTR_RULE_GAP]u+\\n[#CAP_HEIGHT_ADJUST]u+\\n[#FOOTER_RULE_WEIGHT]u +. nr #HDRFTR_RULE_WEIGHT \\n[#FOOTER_RULE_WEIGHT] +. nr #HDRFTR_RULE_WEIGHT_ADJ \\n[#FOOTER_RULE_WEIGHT_ADJ] +. \} +. ie \\n[#HDRFTR_RULE_COLOR]=1 \{\ +\m[\\*[$HDRFTR_RULE_COLOR]]\ +\D't \\n[#HDRFTR_RULE_WEIGHT]u'\ +\h'|0'\ +\v'+\\n[#HDRFTR_RULE_WEIGHT_ADJ]u'\ +\D'l \\n[#DOC_L_LENGTH]u 0'\ +\D't \\n[#RULE_WEIGHT]u'\ +\h'-\\n[#RULE_WEIGHT]u'\ +\m[] +. \} +. el \{\ +\D't \\n[#HDRFTR_RULE_WEIGHT]u'\ +\h'|0'\ +\v'+\\n[#HDRFTR_RULE_WEIGHT_ADJ]u'\ +\D'l \\n[#DOC_L_LENGTH]u 0'\ +\D't \\n[#RULE_WEIGHT]u'\ +\h'-\\n[#RULE_WEIGHT]u' +. \} +. br +. \} +. \} +. if '\\$0'HEADER_RULE' \{\ +. ie '\\$1'' \{\ +. nr #HEADER_RULE 1 +. nr #HDRFTR_RULE 1 +. \} +. el \{\ +. nr #HEADER_RULE 0 +. nr #HDRFTR_RULE 0 +. \} +. \} +. if '\\$0'FOOTER_RULE' \{\ +. ie '\\$1'' \{\ +. nr #FOOTER_RULE 1 +. nr #HDRFTR_RULE 1 +. \} +. el \{\ +. nr #FOOTER_RULE 0 +. nr #HDRFTR_RULE 0 +. \} +. \} +. if '\\$0'HDRFTR_RULE' \{\ +. ie '\\$1'' .nr #HDRFTR_RULE 1 +. el .nr #HDRFTR_RULE 0 +. \} +.END +. +.ALIAS HDRFTR_RULE_INTERNAL HDRFTR_RULE +\# +\# HDRFTR PLAIN +\# ------------ +\# *Arguments: +\# +\# *Function: +\# Sets the family, font, and point size of all strings in +\# header/footers to the same family and point size as running +\# text. Font for the header/footer becomes roman throughout. +\# +.MAC HDRFTR_PLAIN END +. nr #HDRFTR_PLAIN 1 +. rm $HDRFTR_FAMILY +. rm #HDRFTR_PT_SIZE +. rm $HDRFTR_COLOR +. rm $HDRFTR_LEFT_FAMILY +. rm $HDRFTR_LEFT_FONT +. rm $HDRFTR_LEFT_SIZE_CHANGE +. rr #HDRFTR_LEFT_CAPS +. rr #HDRFTR_LEFT_SMALLCAPS +. rr #HDRFTR_LEFT_COLOR +. rm $HDRFTR_CENTER_FAMILY +. rm $HDRFTR_CENTER_FONT +. rm $HDRFTR_CENTER_SIZE_CHANGE +. rr #HDRFTR_CENTER_CAPS +. rr #HDRFTR_CENTER_SMALLCAPS +. rr #HDRFTR_CENTER_COLOR +. rm $HDRFTR_RIGHT_FAMILY +. rm $HDRFTR_RIGHT_FONT +. rm $HDRFTR_RIGHT_SIZE_CHANGE +. rr #HDRFTR_RIGHT_CAPS +. rr #HDRFTR_RIGHT_SMALLCAPS +. rr #HDRFTR_RIGHT_COLOR +.END +\# +\# SWITCH HDRFTR +\# ------------- +\# *Arguments: +\# | +\# *Function: +\# Creates or modifies register #SWITCH_HDRFTR, used to switch +\# default location of HDRFTR_LEFT and HDRFTR_RIGHT. +\# *Notes: +\# Default is OFF. +\# +\# Typically, the author string appears at the left of header/footers, +\# and the title string appears at the right. This switches the +\# location of the two. Useful in conjunction with RECTO_VERSO to tweak +\# switches on alternate pages to come out as the user wishes. The +\# assumption of RECTO_VERSO is that the first page of the document +\# (recto) is odd, and even though it has no header/footer, if it did +\# have one, it would print as AUTHOR...CENTER...TITLE (or whatever +\# strings the user has supplied for HDRFTR_LEFT/RIGHT), meaning that +\# the next page, which does have a header/footer, will come out as +\# TITLE...CENTER...AUTHOR (or whatever strings the user has supplied +\# for HDRFTR_LEFT/RIGHT). SWITCH_HDRFTRS allows the user to get the +\# desired string in the desired place on the desired recto/verso page. +\# +.MAC SWITCH_HDRFTR END +. ie '\\$1'' .nr #SWITCH_HDRFTR 1 +. el .nr #SWITCH_HDRFTR 0 +.END +\# +\# USER DEFINED HDRFTR RECTO +\# ------------------------- +\# *Arguments: +\# L | LEFT | C | CENTER | CENTER | R | RIGHT +\# *Function: +\# Toggles #USERDEF_HDRFTR on, stores quad as #USERDEF_HDRFTR_RECTO_QUAD, +\# stores string in $USERDEF_HDRFTR_RECTO. +\# *Notes: +\# For use when users don't want 3-part headers/footers, but rather +\# want to design their own headers/footers and need different +\# headers/footers on recto and verso pages. Using just +\# HEADER_RECTO or FOOTER_RECTO, even when recto/verso is not on, +\# allows users to design their own headers/footers for doc pages. +\# +.MAC HDRFTR_RECTO END +. nr #USERDEF_HDRFTR 1 +. ds $QUAD_TYPE \\$1 +. substring $QUAD_TYPE 0 0 +. if '\\*[$QUAD_TYPE]'L' .nr #USERDEF_HDRFTR_RECTO_QUAD 1 +. if '\\*[$QUAD_TYPE]'C' .nr #USERDEF_HDRFTR_RECTO_QUAD 2 +. if '\\*[$QUAD_TYPE]'R' .nr #USERDEF_HDRFTR_RECTO_QUAD 3 +. shift +. ie '\\$1'CAPS' \{\ +. nr #HDRFTR_RECTO_CAPS 1 +. ds $USERDEF_HDRFTR_RECTO \\$2 +. \} +. el .ds $USERDEF_HDRFTR_RECTO \\$1 +.END +\# +\# USER DEFINED HDRFTR VERSO +\# ------------------------- +\# *Arguments: +\# L | LEFT | C | CENTER | CENTER | R | RIGHT +\# *Function: +\# Toggles #USERDEF_HDRFTR on, stores quad as #USERDEF_HDRFTR_VERSO_QUAD, +\# stores string in $USERDEF_HDRFTR_VERSO. +\# *Notes: +\# For use when users don't want 3-part headers/footers, but rather +\# want to design their own headers/footers and need different +\# headers/footers on recto and verso pages. +\# +.MAC HDRFTR_VERSO END +. nr #USERDEF_HDRFTR 1 +. ds $QUAD_TYPE \\$1 +. if !'\\*[$QUAD_TYPE]'' .substring $QUAD_TYPE 0 0 +. if '\\*[$QUAD_TYPE]'L' .nr #USERDEF_HDRFTR_VERSO_QUAD 1 +. if '\\*[$QUAD_TYPE]'C' .nr #USERDEF_HDRFTR_VERSO_QUAD 2 +. if '\\*[$QUAD_TYPE]'R' .nr #USERDEF_HDRFTR_VERSO_QUAD 3 +. shift +. ie '\\$1'CAPS' \{\ +. nr #HDRFTR_VERSO_CAPS 1 +. ds $USERDEF_HDRFTR_VERSO \\$2 +. \} +. el .ds $USERDEF_HDRFTR_VERSO \\$1 +.END +\# +\# PRINT FOOTER ON FIRST PAGE +\# -------------------------- +\# *Arguments: +\# | +\# *Function: +\# Toggles register #PRINT_FOOTER_ON_PAGE_1 +\# *Notes: +\# Lets user choose whether to print footer on first +\# page of doc. +\# +.MAC FOOTER_ON_FIRST_PAGE END +. ie '\\$1'' .nr #PRINT_FOOTER_ON_PAGE_1 1 +. el .rr #PRINT_FOOTER_ON_PAGE_1 +.END +\# +\# PRINT PAGE NUMBER ON FIRST PAGE +\# ------------------------------- +\# *Arguments: +\# | +\# *Function: +\# Toggles register #PRINT_PAGENUM_ON_PAGE_1 +\# *Notes: +\# Lets user choose whether to print page number on first +\# page of doc and after collate when footers are on or page numbering +\# has been user set at top of page. +\# +.MAC PAGENUM_ON_FIRST_PAGE END +. ie '\\$1'' .nr #PRINT_PAGENUM_ON_PAGE_1 1 +. el .rr #PRINT_PAGENUM_ON_PAGE_1 +.END +\# +\# PRINT HEADER/FOOTER +\# ------------------- +\# *Arguments: +\# +\# *Function: +\# Based on defaults or values entered by user, prints a +\# three-part title at either the top or the bottom of the page. +\# *Notes: +\# Called from within either HEADER or FOOTER. +\# +.MAC PRINT_HDRFTR END +. if \\n[#DOC_TYPE]=4 .nr #SUITE \En[.pn] +. if \\n[#FOOTERS_ON] \{\ +. if \\n[#START_FOR_FOOTERS] \{\ +. rr #START_FOR_FOOTERS +. if \\n[#DOC_TYPE]=5 \{\ +. if !\\n[#HDRFTR_BOTH] .PRINT_USERDEF_HDRFTR +. return +. \} +. if !\\n[#PRINT_FOOTER_ON_PAGE_1] \{\ +. ie !\\n[#HDRFTR_BOTH] .return +. el \{\ +. rr #FOOTERS_ON +. if !\\n[#COLLATE] .nr #HEADERS_ON 1 +. ie \\n[#HEADER_RULE]=1 .HEADER_RULE +. el .HEADER_RULE OFF +. ie \\n[#HDRFTR_BOTH] .HEADER_VERSO \\*[$HDR_VERSO_QUAD] "\\*[$HDR_VERSO_STRING]" +. el .HEADER_RECTO \\*[$HDR_RECTO_QUAD] "\\*[$HDR_RECTO_STRING]" +. return +. \} +. \} +. \} +. \} +. if \\n[#USERDEF_HDRFTR] \{\ +. PRINT_USERDEF_HDRFTR +. return +. \} +. if \\n[#SWITCH_HDRFTR] \{\ +. ds $HDRFTR_TMP_SWITCH \\*[$HDRFTR_LEFT] +. ds $HDRFTR_LEFT \\*[$HDRFTR_RIGHT] +. ds $HDRFTR_RIGHT \\*[$HDRFTR_TMP_SWITCH] +. ds $HDRFTR_TMP_SIZE_CHANGE_SWITCH \\*[$HDRFTR_LEFT_SIZE_CHANGE] +. ds $HDRFTR_LEFT_SIZE_CHANGE \\*[$HDRFTR_RIGHT_SIZE_CHANGE] +. ds $HDRFTR_RIGHT_SIZE_CHANGE \\*[$HDRFTR_TMP_SIZE_CHANGE_SWITCH] +. nr #HDRFTR_TMP_CAPS_SWITCH \\n[#HDRFTR_LEFT_CAPS] +. nr #HDRFTR_LEFT_CAPS \\n[#HDRFTR_RIGHT_CAPS] +. nr #HDRFTR_TMP_SMALLCAPS_SWITCH \\n[#HDRFTR_LEFT_SMALLCAPS] +. nr #HDRFTR_LEFT_SMALLCAPS \\n[#HDRFTR_RIGHT_SMALLCAPS] +. nr #HDRFTR_RIGHT_CAPS \\n[#HDRFTR_TMP_CAPS_SWITCH] +. ds $HDRFTR_TMP_COLOR_SWITCH \\*[$HDRFTR_LEFT_COLOR] +. ds $HDRFTR_LEFT_COLOR \\*[$HDRFTR_RIGHT_COLOR] +. ds $HDRFTR_RIGHT_COLOR \\*[$HDRFTR_TMP_COLOR_SWITCH] +. rr #HDRFTR_TMP_CAPS_SWITCH +. rm $HDRFTR_TMP_SWITCH +. rm $HDRFTR_TMP_SIZE_CHANGE_SWITCH +. rm $HDRFTR_TMP_COLOR_SWITCH +. nr #SWITCH_HDRFTR 0 +. \} +. nr #PAGENUMBER \\n%+\\n[#PAGE_NUM_ADJ] +. if \\n[#ENDNOTES] .PAGENUM_STYLE \\*[$EN_PN_STYLE] +. if \\n[#PRINT_STYLE]=1 \{\ +. if \\n[#FOOTERS_ON] \{\ +. di NULL +. SIZESPECS +. nr #LEFT_CAP_HEIGHT \\n[#CAP_HEIGHT] +. di +. \} +. if o .RIGHT +. if e .LEFT +. if \\n[#RECTO_VERSO]=0 .LEFT +. if \\n[#HDRFTR_LEFT_CAPS] .CAPS +. ie '\\*[$HDRFTR_LEFT]'#' .PRINT \\n[#PAGENUMBER] +. el \{\ +. ie !'\\*[$HDRFTR_LEFT]'' .PRINT \\*[$HDRFTR_LEFT] +. el .PRINT \& +. \} +. if \\n[#HDRFTR_LEFT_CAPS] .CAPS OFF +. CENTER +. if \\n[#HDRFTR_CENTER_CAPS] .CAPS +. rt \\n[y]u +. ie '\\*[$HDRFTR_CENTER]'#' .PRINT \ +\h'\\n[#HDRFTR_CTR_PAD_LEFT]u'\\n[#PAGENUMBER]\h'\\n[#HDRFTR_CTR_PAD_RIGHT]u' +. el \{\ +. ie !'\\*[$HDRFTR_CENTER]'' .PRINT \ +\h'\\n[#HDRFTR_CTR_PAD_LEFT]u'\\*[$HDRFTR_CENTER]\h'\\n[#HDRFTR_CTR_PAD_RIGHT]u' +. el .PRINT \& +. \} +. if \\n[#HDRFTR_CENTER_CAPS] .CAPS OFF +. if o .LEFT +. if e .RIGHT +. if \\n[#RECTO_VERSO]=0 .RIGHT +. if \\n[#HDRFTR_RIGHT_CAPS] .CAPS +. rt \\n[y]u +. ie '\\*[$HDRFTR_RIGHT]'#' .PRINT \\n[#PAGENUMBER] +. el \{\ +. ie !'\\*[$HDRFTR_RIGHT]'' .PRINT \\*[$HDRFTR_RIGHT] +. el .PRINT \& +. \} +. if \\n[#HDRFTR_RIGHT_CAPS] .CAPS OFF +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. if \\n[#HDRFTR_COLOR]=1 \{\ +. nf +\m[\\*[$HDRFTR_COLOR]] +. \} +. fam \\*[$HDRFTR_LEFT_FAM] +. ft \\*[$HDRFTR_LEFT_FT] +. ps \\n[#HDRFTR_PT_SIZE]u\\*[$HDRFTR_LEFT_SIZE_CHANGE] +. if \\n[#FOOTERS_ON] \{\ +. di NULL +. SIZESPECS +. nr #LEFT_CAP_HEIGHT \\n[#CAP_HEIGHT] +. di +. \} +. if o .LEFT +. if e .RIGHT +. if \\n[#RECTO_VERSO]=0 .LEFT +. if \\n[#HDRFTR_LEFT_SMALLCAPS] .SMALLCAPS +. if \\n[#HDRFTR_LEFT_CAPS] .CAPS +. ie '\\*[$HDRFTR_LEFT]'#' \{\ +. ie \\n[#HDRFTR_LEFT_COLOR]=1 \ +. PRINT \m[\\*[$HDRFTR_LEFT_COLOR]]\\n[#PAGENUMBER]\m[] +. el \ +. PRINT \\n[#PAGENUMBER] +. \} +. el \{\ +. ie !'\\*[$HDRFTR_LEFT]'' \{\ +. ie \\n[#HDRFTR_LEFT_COLOR]=1 \ +. PRINT \m[\\*[$HDRFTR_LEFT_COLOR]]\\*[$HDRFTR_LEFT]\m[] +. el \ +. PRINT \\*[$HDRFTR_LEFT] +. \} +. el .nop \& +. \} +. if \\n[#HDRFTR_LEFT_CAPS] .CAPS OFF +. if \\n[#HDRFTR_LEFT_SMALLCAPS] .SMALLCAPS OFF +. fam \\*[$HDRFTR_CENTER_FAM] +. ft \\*[$HDRFTR_CENTER_FT] +. ps \\n[#HDRFTR_PT_SIZE]u\\*[$HDRFTR_CENTER_SIZE_CHANGE] +. if \\n[#FOOTERS_ON] \{\ +. di NULL +. SIZESPECS +. nr #CENTER_CAP_HEIGHT \\n[#CAP_HEIGHT] +. di +. \} +. CENTER +. if \\n[#HDRFTR_CENTER_SMALLCAPS] .SMALLCAPS +. if \\n[#HDRFTR_CENTER_CAPS] .CAPS +. rt \\n[y]u +. ie '\\*[$HDRFTR_CENTER]'#' \{\ +. ie \\n[#HDRFTR_CENTER_COLOR]=1 .PRINT \ +\h'\\n[#HDRFTR_CTR_PAD_LEFT]u'\m[\\*[$HDRFTR_CENTER_COLOR]]\ +\\n[#PAGENUMBER]\h'\\n[#HDRFTR_CTR_PAD_RIGHT]u'\m[] +. el .PRINT \ +\h'\\n[#HDRFTR_CTR_PAD_LEFT]u'\\n[#PAGENUMBER]\h'\\n[#HDRFTR_CTR_PAD_RIGHT]u' +. \} +. el \{\ +. ie !'\\*[$HDRFTR_CENTER]'' \{\ +. ie \\n[#HDRFTR_CENTER_COLOR]=1 .PRINT \ +\h'\\n[#HDRFTR_CTR_PAD_LEFT]u'\m[\\*[$HDRFTR_CENTER_COLOR]]\ +\\*[$HDRFTR_CENTER]\h'\\n[#HDRFTR_CTR_PAD_RIGHT]u'\m[] +. el .PRINT \ +\h'\\n[#HDRFTR_CTR_PAD_LEFT]u'\\*[$HDRFTR_CENTER]\h'\\n[#HDRFTR_CTR_PAD_RIGHT]u' +. \} +. el .PRINT \& +. \} +. if \\n[#HDRFTR_CENTER_CAPS] .CAPS OFF +. if \\n[#HDRFTR_CENTER_SMALLCAPS] .SMALLCAPS OFF +. fam \\*[$HDRFTR_RIGHT_FAM] +. ft \\*[$HDRFTR_RIGHT_FT] +. ps \\n[#HDRFTR_PT_SIZE]u\\*[$HDRFTR_RIGHT_SIZE_CHANGE] +. if \\n[#FOOTERS_ON] \{\ +. di NULL +. SIZESPECS +. nr #RIGHT_CAP_HEIGHT \\n[#CAP_HEIGHT] +. di +. \} +. if o .RIGHT +. if e .LEFT +. if \\n[#RECTO_VERSO]=0 .RIGHT +. if \\n[#HDRFTR_RIGHT_SMALLCAPS] .SMALLCAPS +. if \\n[#HDRFTR_RIGHT_CAPS] .CAPS +. rt \\n[y]u +. ie '\\*[$HDRFTR_RIGHT]'#' \{\ +. ie \\n[#HDRFTR_RIGHT_COLOR]=1 \ +. PRINT \m[\\*[$HDRFTR_RIGHT_COLOR]]\\n[#PAGENUMBER]\m[] +. el \ +. PRINT \\n[#PAGENUMBER] +. \} +. el \{\ +. ie !'\\*[$HDRFTR_RIGHT]'' \{\ +. ie \\n[#HDRFTR_RIGHT_COLOR]=1 \ +. PRINT \m[\\*[$HDRFTR_RIGHT_COLOR]]\\*[$HDRFTR_RIGHT]\m[] +. el \ +. PRINT \\*[$HDRFTR_RIGHT] +. \} +. el .PRINT \& +. \} +. if \\n[#HDRFTR_RIGHT_CAPS] .CAPS OFF +. if \\n[#HDRFTR_RIGHT_SMALLCAPS] .SMALLCAPS OFF +. \} +. if \\n[#HDRFTR_RULE] .HDRFTR_RULE_INTERNAL +. br +.END +\# +\# PRINT USER DEFINED HEADER/FOOTER +\# -------------------------------- +\# *Arguments: +\# +\# *Function: +\# Based on defaults or values entered by user, prints a single part +\# (i.e. not 3-part) title at either the top or the bottom of the page. +\# *Notes: +\# Called from within PRINT_HDRFTR. +\# +.MAC PRINT_USERDEF_HDRFTR END +. nr #PAGENUMBER \\n%+\\n[#PAGE_NUM_ADJ] +. fc ^ # +. if \\n[#PRINT_STYLE]=2 \{\ +. fam \\*[$HDRFTR_FAM] +. ft R +. ps \\n[#HDRFTR_PT_SIZE]u +. if \\n[#HDRFTR_COLOR]=1 \{\ +. nf +. COLOR \\*[$HDRFTR_COLOR] +. \} +. \} +. ie \\n[#RECTO_VERSO] \{\ +. if o \{\ +. if \\n[#USERDEF_HDRFTR_RECTO_QUAD]=1 .LEFT +. if \\n[#USERDEF_HDRFTR_RECTO_QUAD]=2 .CENTER +. if \\n[#USERDEF_HDRFTR_RECTO_QUAD]=3 .RIGHT +. if \\n[#HDRFTR_RECTO_CAPS]=1 .CAPS +. if '\\n[.ev]'FOOTER' .vs 0 +. PRINT \\*[$USERDEF_HDRFTR_RECTO] +. if '\\n[.ev]'FOOTER' .vs +. if \\n[#HDRFTR_RECTO_CAPS]=1 .CAPS OFF +. EOL +. if \\n[#FOOTERS_ON] \{\ +. di NULL +. SIZESPECS +. nr #HDRFTR_HEIGHT \\n[#CAP_HEIGHT] +. di +. \} +. \} +. if e \{\ +. ie !'\\*[$USERDEF_HDRFTR_VERSO]'' \{\ +. if \\n[#USERDEF_HDRFTR_VERSO_QUAD]=1 .LEFT +. if \\n[#USERDEF_HDRFTR_VERSO_QUAD]=2 .CENTER +. if \\n[#USERDEF_HDRFTR_VERSO_QUAD]=3 .RIGHT +. if \\n[#HDRFTR_VERSO_CAPS]=1 .CAPS +. if '\\n[.ev]'FOOTER' .vs 0 +. PRINT \\*[$USERDEF_HDRFTR_VERSO] +. if '\\n[.ev]'FOOTER' .vs +. if \\n[#HDRFTR_VERSO_CAPS]=1 .CAPS OFF +. EOL +. if \\n[#FOOTERS_ON] \{\ +. di NULL +. SIZESPECS +. nr #HDRFTR_HEIGHT \\n[#CAP_HEIGHT] +. di +. \} +. \} +. el \{\ +. if \\n[#USERDEF_HDRFTR_RECTO_QUAD]=1 .LEFT +. if \\n[#USERDEF_HDRFTR_RECTO_QUAD]=2 .CENTER +. if \\n[#USERDEF_HDRFTR_RECTO_QUAD]=3 .RIGHT +. if \\n[#HDRFTR_RECTO_CAPS]=1 .CAPS +. if '\\n[.ev]'FOOTER' .vs 0 +. PRINT \\*[$USERDEF_HDRFTR_RECTO] +. if '\\n[.ev]'FOOTER' .vs +. if \\n[#HDRFTR_RECTO_CAPS]=1 .CAPS OFF +. EOL +. if \\n[#FOOTERS_ON] \{\ +. di NULL +. SIZESPECS +. nr #HDRFTR_HEIGHT \\n[#CAP_HEIGHT] +. di +. \} +. \} +. \} +. \} +. el \{\ +. if \\n[#USERDEF_HDRFTR_RECTO_QUAD]=1 .LEFT +. if \\n[#USERDEF_HDRFTR_RECTO_QUAD]=2 .CENTER +. if \\n[#USERDEF_HDRFTR_RECTO_QUAD]=3 .RIGHT +. if \\n[#HDRFTR_RECTO_CAPS]=1 .CAPS +. if '\\n[.ev]'FOOTER' .vs 0 +. if !r #SKIP .PRINT \\*[$USERDEF_HDRFTR_RECTO] +. if '\\n[.ev]'FOOTER' .vs +. if \\n[#HDRFTR_RECTO_CAPS]=1 .CAPS OFF +. EOL +. if \\n[#FOOTERS_ON] \{\ +. di NULL +. SIZESPECS +. nr #HDRFTR_HEIGHT \\n[#CAP_HEIGHT] +. di +. \} +. \} +. fc +. if \\n[#PRINT_STYLE]=2 \{\ +. ie \\n[#HDRFTR_COLOR]=1 \m[\\*[$HDRFTR_COLOR]] +. el \m[black] +. \} +. if \\n[#HDRFTR_RULE] \ +. HDRFTR_RULE_INTERNAL +.END +\# +\# +++HEADERS+++ +\# +\# HEADERS (off or on) +\# ------------------- +\# *Arguments: +\# | +\# *Function: +\# Turns headers at the top of the page off or on. +\# *Notes: +\# Default is on. +\# +.MAC HEADERS END +. ie '\\$1'' .nr #HEADERS_ON 1 +. el .nr #HEADERS_ON 0 +.END +\# +\# HEADER MARGIN +\# ------------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies register #HEADER_MARGIN to hold amount +\# of space between top of page and header. +\# *Notes: +\# Requires unit of measure. Default is 4P+6p, measured top-of-page +\# to baseline. +\# +.MAC HEADER_MARGIN END +. nr #HEADER_MARGIN (\\$1) +.END +\# +\# HEADER GAP +\# ---------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies register #HEADER_GAP to hold amount +\# of space between header and running text. +\# *Notes: +\# Default is 1P+6p. +\# +.MAC HEADER_GAP END +. nr #HEADER_GAP (\\$1) +.END +\# +\# HEADER +\# ------ +\# *Arguments: +\# +\# *Function: +\# Resets margin notes, processes footnote and margin note +\# leftover, takes care of recto-verso, prepares for columns after +\# first, determines whether to flex-space the page,,outputs +\# deferred floats, and does some tbl magic. If headers are +\# enabled, prints header appropriate to DOC_TYPE, PRINTSTYLE, and +\# COPYSTYLE. +\# +.MAC HEADER END +. vpt 0 +. if \\n[#DOC_TYPE]=5 \{\ +. if \\n[#SLIDE_FOOTERS] \{\ +. PRINT_FOOTER +. if \\n[#HDRFTR_BOTH] \ +. HEADER_RECTO \\*[$HDR_RECTO_QUAD] "\\*[$HDR_RECTO_STRING]" +. \} +. \} +. nr flex-spaces 0 +. nr flex +1 +. if \\n[#NEW_DOC_PT_SIZE] .nr #DOC_PT_SIZE \\n[#NEW_DOC_PT_SIZE] +. rr #NEW_DOC_PT_SIZE +. if \\n[#RESET_TRAPS] \{\ +. TRAPS +. if \\n[#REMOVE_ADJ] .nr #DOC_LEAD -\\n[#DOC_LEAD_ADJ] +. \} +. rr #REMOVE_ADJ +. rr #RESET_TRAPS +. MNtop +. rr #FROM_FOOTER +. nr #FROM_HEADER 1 +. nr #LAST_FN_COUNT_FOR_COLS \\n[#FN_COUNT_FOR_COLS] +. if \\n[#FN_DEPTH] .PROCESS_FN_LEFTOVER +. rr #RULED +. if \\n[#RESET_FN_NUMBER] .nr #FN_NUMBER 0 1 +. if !\\n[#DIVERTED] .rr #PREV_FN_DEFERRED +. po \\n[#DOC_L_MARGIN]u +. if \\n[#RECTO_VERSO] \{\ +. if !\\n[#TOC_RV_SWITCH]=2 \{\ +. nr #DOC_LR_MARGIN_TMP \\n[#DOC_L_MARGIN] +. DOC_LEFT_MARGIN \\n[#DOC_R_MARGIN]u +. if \\n[#CROPS] .DOC_LEFT_MARGIN \\n[#DOC_R_MARGIN]u+\\n[cropmarks]u +. DOC_RIGHT_MARGIN \\n[#DOC_LR_MARGIN_TMP]u +. if \\n[#CROPS] .DOC_RIGHT_MARGIN \\n[#DOC_LR_MARGIN_TMP]u-\\n[cropmarks]u +. SWITCH_HDRFTR_CENTER_PAD +. \} +. \} +. ev HEADER +. if \\n[#PAGE_NUM_V_POS]=1 .vs 0 +. sp |\\n[#HEADER_MARGIN]u-1v +. mk y +. ll \\n[#DOC_L_LENGTH]u +. ta \\n[.l]u +. if \\n[#PRINT_STYLE]=1 \{\ +. fam \\*[$TYPEWRITER_FAM] +. ft R +. ps \\*[$TYPEWRITER_PS]\\*[$HDRFTR_SIZE_CHANGE] +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. fam \\*[$HDRFTR_FAM] +. ft R +. ps \\n[#DOC_PT_SIZE]u\\*[$HDRFTR_SIZE_CHANGE] +. \} +. nr #HDRFTR_PT_SIZE \\n[#PT_SIZE] +. if \\n[#CAPS_ON] \{\ +. nr #CAPS_WAS_ON 1 +. CAPS OFF +. \} +. if \\n[#PRINT_STYLE]=1 \{\ +. if \\n[#ENDNOTES]=1 \{\ +.\" Single-spaced endnotes have a different lead +. if \\n[#EN_SINGLESPACE] \{\ +. nr #RESTORE_DOC_LEAD \\n[#DOC_LEAD] +. nr #DOC_LEAD \\n[#EN_LEAD]u +. \} +. \} +. \} +. if !n .nop \X'ps: exec 0 setlinejoin'\X'ps: exec 0 setlinecap' +. sp -1v +. if \\n[#DOC_TYPE]=5 \{\ +. if \\n[#SLIDE_HEADERS] \{\ +. HEADERS +. if \\n[#SLIDE_FOOTERS] \{\ +. FOOTERS off +.\" So rule prints after header on first page +. if !r #SKIP_RULE \{\ +. sp +. if \\n[#HEADER_RULE] .HEADER_RULE +. nr #SKIP_RULE 1 +. \} +. \} +. \} +. \} +. ie \\n[#HEADERS_ON] .PRINT_HDRFTR +. el \{\ +. if \\n[#PAGE_NUM_V_POS]=1 \ +. if \\n[#PAGINATE] .PRINT_PAGE_NUMBER +. \} +. sp |\\n[#T_MARGIN]u-\\n[#DOC_LEAD]u +. if \\n[#PRINT_STYLE]=1 \{\ +. if \\n[#ENDNOTES]=1 \{\ +. if \\n[#EN_SINGLESPACE] \{\ +. nr #DOC_LEAD \\n[#RESTORE_DOC_LEAD]u +. rr #RESTORE_DOC_LEAD +. \} +. \} +. \} +. nr #PAGE_TOP \\n[nl] +. ev +.\" PDF boxes +. if \\n[pdfbx-running]=1 \{\ +. if !\\n[pdfbx-div-start] \{\ +. ps \\n[#SIZE_AT_FOOTER]u +. SIZESPECS +. ds pdfbx-cap-adj \\*[$CAP_HEIGHT] +. ps +. sp |\\n[t]u-\\n[#LEAD_AT_FOOTER]u +. sp (\\*[wt\\n[stack]]/2u)+\\*[pdfbx-cap-adj]+\\*[gap\\n[stack]]u +. ch FOOTER \\n[#VFP\\n[stack]]u +. \} +. \} +. po \\n[#L_MARGIN]u +. if \\n[#RECTO_VERSO] .nr #L_MARGIN +\\n[#L_MARGIN_DIFF] +. if \\n[#CAPS_WAS_ON] \{\ +. CAPS +. rr #CAPS_WAS_ON +. \} +. if \\n[#TAB_ACTIVE] .TAB \\n[#CURRENT_TAB] +. if \\n[#QUOTE] \{\ +. ie \\n[#TAB_ACTIVE] .TAB \\n[#CURRENT_TAB] +. el \{\ +. ie r #\\*[BQ]_OFFSET_VALUE .nr #\\*[BQ]_OFFSET \ +\\n[#L_MARGIN]+(\\n[#PP_INDENT]*\\n[#\\*[BQ]_OFFSET_VALUE]) +. el .nr #\\*[BQ]_OFFSET \\n[#L_MARGIN]+\\*[$\\*[BQ]_OFFSET_VALUE] +. ie \\n[#QUOTE]=1 \{\ +. if !'\\*[$Q_QUAD]'CENTER' \ +. if !'\\*[$Q_QUAD]'RIGHT' \ +. po \\n[#Q_OFFSET]u +. \} +. el .po \\n[#\\*[BQ]_OFFSET]u +. \} +. if !\\n[pdfbx-running]=0 \{\ +. if \\n[#PRINT_STYLE]=2 .sp \\n[#Q_LEAD_DIFF]u +. \} +. \} +. if \\n[#IN_LIST] \ +. po +\\n[#LIST_OFFSET_VALUE]u +. if \\n[#RESET_FN_COUNTERS]=1 \{\ +. rr #RESET_FN_COUNTERS +. PROCESS_FN_IN_DIVER +. nr #FN_COUNT \\n[#SAVED_FN_COUNT] 1 +. if \\n[#COLUMNS]=1 .nr #FN_COUNT_FOR_COLS \\n[#SAVED_FN_COUNT_FOR_COLS] 1 +. ie \\n[#RESET_FN_NUMBER]=1 .nr #FN_NUMBER \\n[#SAVED_FN_NUMBER] 1 +. el .nr #FN_NUMBER \\n[#FN_NUMBER] 1 +. rm FN_IN_DIVER +. if dRUNON_FN_IN_DIVER .rm RUNON_FN_IN_DIVER +. \} +. if \\n[#EPIGRAPH] \{\ +. ie \\n[#TAB_ACTIVE] .TAB \\n[#CURRENT_TAB] +. el \{\ +. ie r#EPI_OFFSET_VALUE \ +. nr #EPI_OFFSET \ +\\n[#L_MARGIN]+(\\n[#PP_INDENT]*\\n[#EPI_OFFSET_VALUE]) +. el \ +. nr #EPI_OFFSET \\n[#L_MARGIN]+\\*[$EPI_OFFSET_VALUE] +. po \\n[#EPI_OFFSET]u +. \} +. \} +. ie \\n[#EPIGRAPH] \{\ +. ie !\\n[#EPI_ACTIVE] \{\ +. ns +. rr #EPI_ACTIVE +. \} +. el \{\ +. ie \\n[#EPI_FITS] .ns +. el .sp \\n[#DOC_LEAD]u-\\n[#EPI_LEAD]u +. \} +. \} +. el .ns +. if \\n[#COLUMNS] \{\ +. nr #FN_COUNT_FOR_COLS 0 1 +. nr #L_MARGIN \\n[#DOC_L_MARGIN] +. if \\n[#RECTO_VERSO] .COLUMNS \\n[#NUM_COLS] \\n[#GUTTER]u +. nr #COL_NUM 0 1 +. mk dc +. po \\n[#COL_\\n+[#COL_NUM]_L_MARGIN]u +. nr #L_MARGIN \\n[.o] +. if \\n[#TAB_ACTIVE] .TAB \\n[#CURRENT_TAB] +. ll \\n[#COL_L_LENGTH]u +. ta \\n[.l]u +. if \\n[#QUOTE] \{\ +. ie \\n[#\\*[BQ]_OFFSET_VALUE] \ +. po +(\\n[#PP_INDENT]u*\\n[#\\*[BQ]_OFFSET_VALUE]u) +. el \ +. po +\\*[$\\*[BQ]_OFFSET_VALUE] +. \} +. if \\n[#EPIGRAPH] \{\ +. if \\n[#EPI_ACTIVE] \{\ +. ie \\n[#EPI_FITS] . +. el .nr dc -\\n[#EPI_LEAD_DIFF] +. \} +. ie r#EPI_OFFSET_VALUE \{\ +. po \ +\\n[#COL_\\n[#COL_NUM]_L_MARGIN]u+(\\n[#PP_INDENT]u*\\n[#EPI_OFFSET_VALUE]u) +. \} +. el .po \\n[#COL_\\n[#COL_NUM]_L_MARGIN]u+\\*[$EPI_OFFSET_VALUE] +. \} +. \} +. rr #FROM_HEADER +. rr #DEFER_SPACE_ADDED +. if !\\n[#FN_DEPTH] .if r #DIVERTED .rr #DIVERTED +. if \\n[#MN_OVERFLOW_LEFT]=1 \{\ +. MN LEFT +. nf +. MN_OVERFLOW_LEFT +. MN +. \} +. if \\n[#MN_OVERFLOW_RIGHT]=1 \{\ +. MN RIGHT +. nf +. MN_OVERFLOW_RIGHT +. MN +. \} +. rm MN_OVERFLOW_LEFT +. rr #MN_OVERFLOW_LEFT +. rr #no-repeat-MN-left +. rm MN_OVERFLOW_RIGHT +. rr #MN_OVERFLOW_RIGHT +. rr #no-repeat-MN-right +. if \\n[#PRE_COLLATE]=1 .rr #PRE_COLLATE +. if \\n[#UNDERLINE_WAS_ON]=1 \{\ +. vs 0 +. ie !n \ +. nop \R'#UNDERLINE_ON 1'\X'ps: exec \\n[_w] \\n[_d] decorline' +. el .cu 1000 +. br +. ns +. rr #UNDERLINE_WAS_ON +. \} +. if \\n[#RESTORE_PAGINATION] \{\ +. PAGINATE +. rr #RESTORE_PAGINATION +. \} +. ch RR_@TOP +. ie \\n[tbl*have-header] .rr @TOP +. el .wh \\n[nl]u+1u RR_@TOP +. if \\n[#FLEX_ACTIVE] \{\ +. if \\n[#RESTORE_FLEX] \{\ +. rr #NO_FLEX +. rr #RESTORE_FLEX +. \} +. if \\n[#RESTORE_COL_FLEX] \{\ +. rr #NO_FLEX +. rr #RESTORE_COL_FLEX +. \} +. \} +.\" Don't flex the last page/col, or the page/col before a COLLATE, +.\" NEWPAGE, COL_NEXT, or BLANKPAGE. +. if !dPDF.EXPORT \{\ +. if \\n[#FLEX_ACTIVE] \ +. if !\\n[#NO_FLEX] \ +. nr #RESTORE_FLEX 1 +. if '\\*[last-page]'\\n%@\\n[#COL_NUM]' \ +. if !\\n[#NO_FLEX] .nr #NO_FLEX 1 +. if '\\*[pre-collate-\\n%]'\\n%@\\n[#COL_NUM]' \ +. if !\\n[#NO_FLEX] .nr #NO_FLEX 1 +. if '\\*[pre-newpage-\\n%]'\\n%@\\n[#COL_NUM]' \ +. if !\\n[#NO_FLEX] .nr #NO_FLEX 1 +. if d page-\\n%@\\n[#COL_NUM] .nr #NO_FLEX 1 +. \} +. ie \\n[defer] .PROCESS_FLOATS +. el \{\ +.\" These two sets of conditions only occur if the .br in .TS causes +.\" a page break. +. if !\\n[doing-tbl] \{\ +. if (\\n[tbl*have-caption]=1)&(\\n[tbl*caption-after-label]=0) \{\ +. RESTORE_SPACE +. if !\\n[span] \{\ +. ie \\n[#MLA] .sp \\n[tbl*label-lead-diff]u +. el .sp \\n[tbl*caption-lead-diff]u +. \} +. \} +. \} +. \} +.\" So tables without TH that don't fit don't overprint first row +.\" at top of page +. ie \\n[tbl*no-header] \{\ +. rs +. nop \& +. vpt +. rr \\n[tbl*no-header] +. SHIM_1 +. \} +. el .vpt +. if \\n[span] \{\ +. ev FLOAT +. if \\n[#INDENT_LEFT_ACTIVE] .in \\n[#L_INDENT]u/2u +. nf +. RESTORE_SPACE +. if !\\n[tbl*no-top-hook] \ +. if \\n[tbl*have-header:1] .tbl*print-header +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u +. ch FN_OVERFLOW_TRAP -\\n[#FN_OVERFLOW_TRAP_POS]u +. \} +. if !\\n[begin-tbl] \ +. if !r tbl*no-top-hook .tbl@top-hook +. rr tbl*no-top-hook +. if r flex:force .rr flex:force +. rr ref*last +. if !\\n[float*defer] .ev 0 +. if (\\n[pdfbx-running]=1):(\\n[#DOC_TYPE]=5) \{\ +. rr @TOP +. ch RR_@TOP +. \} +. if \\n[pdfbx-running]=1 \ +. ch FOOTER \\n[#VFP\\n[stack]]u +.END +\# +\# ==================================================================== +\# +\# +++FOOTERS+++ +\# +\# FOOTERS (off or on) +\# ------------------- +\# *Arguments: +\# | +\# *Function: +\# Turns footers at the bottom of the page off or on. +\# *Notes: +\# Default is off. If on, page numbers automatically go at +\# the top, centered, unless pagination has been turned off, +\# or the pagenumber position has been changed to left or right. +\# +.MAC FOOTERS END +. ie '\\$1'' \{\ +. rr #HEADERS_ON +. nr #FOOTERS_ON 1 +. PAGENUM_POS TOP CENTER +. \} +. el .nr #FOOTERS_ON 0 +.END +\# +\# FOOTER MARGIN +\# ------------- +\# *Argument: +\#
+\# *Function: +\# Creates or modifies register #FOOTER_MARGIN which holds the +\# amount of space to leave between the page number and the bottom +\# of the page. +\# *Notes: +\# Unit of measure required. Default is 3P. +\# +.MAC FOOTER_MARGIN END +. ie \\n%>0 .nr #FOOTER_MARGIN (\\$1) +. el . +.END +\# +\# FOOTER GAP +\# ---------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies register #FOOTER_GAP which holds the +\# amount of space to leave between running text and the page number. +\# *Notes: +\# Requires unit of measure. Default is 3P. Measured baseline to +\# baseline. +\# +.MAC FOOTER_GAP END +. ie \\n%>0 .nr #FOOTER_GAP (\\$1) +. el . +.END +\# +\# FOOTER +\# ------ +\# *Arguments: +\# +\# *Function: +\# Gathers strings for flex-spacing, processes margin notes and +\# footnotes, prepares for move to next column or page. Places +\# footer at bottom of page if #FOOTERS=1, otherwise places page +\# number at bottom of page (if #PAGINATE=1). Page numbers are +\# in arabic or roman according to COPYSTYLE. DRAFT starts the +\# document at page 1 regardless of PAGENUMBER. FINAL respects +\# PAGENUMBER. +\# +.MAC FOOTER END +. if r #START .rr #START +. if \\n[pdfbx-running] \{\ +. if \\n[#FN_COUNT] \{\ +. nr pdfbx-fn-trap \\n[nl]+\\*[wt\\n[stack]]+\\*[gap\\n[stack]] +. nop \!x X pdf: background footnote \\n[pdfbx-fn-trap]z +. rr pdfbx-fn-trap +. \} +. \} +. CALCULATE_FLEX +. if \\n[#DOING_COVERTEXT] \{\ +. tm1 "[mom]: COVERTEXT exceeds cover page depth. +. ab [mom]: Aborting '\\n[.F]'. +. \} +. vpt 0 +. rr #LB_4_HD +. rr #QUOTE_4_HD +. nr #LEAD_AT_FOOTER \\n[.v] +. nr #SIZE_AT_FOOTER \\n[.ps] +. if !r pg-trans .nr pg-trans 0 1 +. ev PAGE_TRANSITION\\n+[pg-trans] +. pdfmarksuspend +. ie !n .nop \X'ps: exec decornone' +. el .cu 0 +. br +. if \\n[#UNDERLINE_ON]=1 .nr #UNDERLINE_WAS_ON 1 +. if \\n[MN-left]>0 \{\ +. if !\\n[#no-repeat-MN-left]=1 \{\ +. MNbottom-left +. nr #no-repeat-MN-left 1 +. \} +. if '\\n[.z]'MN_OVERFLOW_LEFT' \{\ +. di +. nr #MN_OVERFLOW_LEFT 1 +. rr #OVERFLOW_LEFT +. \} +. \} +. if \\n[MN-right]>0 \{\ +. if !\\n[#no-repeat-MN-right]=1 .MNbottom-right +. if '\\n[.z]'MN_OVERFLOW_RIGHT' \{\ +. di +. nr #MN_OVERFLOW_RIGHT 1 +. rr #OVERFLOW_RIGHT +. \} +. \} +\# Table bottom hook, draws the table borders in +\# multipage boxed tables. +. tbl@bottom-hook +. ch MN_OVERFLOW_TRAP +. nr #L_MARGIN_DIFF \\n[#L_MARGIN]-\\n[#DOC_L_MARGIN] +. if !\\n[#FN_DEFER] \{\ +. nr #DIVER_DEPTH 0 +. if \\n[#FN_DEPTH] \{\ +. if \\n[#DIVERTED]=3 .nr #FN_DEPTH +\\n[#VFP_DIFF] +. vpt 0 +. sp \ +|\\n[#PAGE_LENGTH]u-(\\n[#B_MARGIN]u+\\n[#FN_DEPTH]u-\\n[#DOC_LEAD]u) +. vpt +. po \\n[#DOC_L_MARGIN]u +. if \\n[#COLUMNS] \{\ +. po \\n[#COL_\\n[#COL_NUM]_L_MARGIN]u +. nr #L_MARGIN \\n[.o] +. nr #FROM_FOOTER 1 +. \} +. nf +. ch FN_OVERFLOW_TRAP -\\n[#FN_OVERFLOW_TRAP_POS]u +. FOOTNOTES +. rm FOOTNOTES +. if d RUNON_FOOTNOTES .rm RUNON_FOOTNOTES +. if \\n[#PRINT_STYLE]=1 .vs \\n[#LEAD_AT_FOOTER]u +. if \\n[#PRINT_STYLE]=2 .vs \\n[#LEAD_AT_FOOTER]u +. if '\\n[.z]'FN_OVERFLOW' \{\ +. di +. nr #FN_OVERFLOW_DEPTH \\n[#DIVER_DEPTH] +. \} +. nr #FN_COUNT_AT_FOOTER \\n[#FN_COUNT] +. nr #FN_COUNT 0 +. if \\n[#COL_NEXT] \{\ +. ie !\\n[#COL_NUM]=\\n[#NUM_COLS] .nr #COL_NUM \\n-[#COL_NUM] +. el .nr #COL_NUM \\n[#NUM_COLS] 1 +. \} +. \} +. rr #DIVERTED +. \} +. nr @TOP 1 +. ie \\n[#COLUMNS]=1 \{\ +. ie (\\n[#COL_NUM]=\\n[#NUM_COLS]):(\\n[#NEWPAGE]=1) \{\ +. rr #NEWPAGE +. DO_FOOTER +. \} +. el \{\ +. ie (\\n[#ENDNOTES]=1):(\\n[#BIBLIOGRAPHY]=1) \{\ +. if \\n[#ENDNOTES] .sp |\\n[ec]u-\\n[#EN_LEAD]u +. if \\n[#BIBLIOGRAPHY] .sp |\\n[bc]u-\\n[#BIB_LEAD]u +. \} +. el \{\ +. vs \\n[#LEAD_AT_FOOTER]u +. rt \\n[dc]u +. nr flex-spaces 0 +. \} +. if d page-\\n%@\\n[#COL_NUM] \{\ +. rr #NO_FLEX +. rr #RESTORE_COL_FLEX +. \} +. po \\n[#COL_\\n+[#COL_NUM]_L_MARGIN]u +. if !dPDF.EXPORT \{\ +. if \\n[#FLEX_ACTIVE] \{\ +. if !\\n[#NO_FLEX] \{\ +. if '\\*[last-page]'\\n%@\\n[#COL_NUM]' \ +. nr #NO_FLEX 1 +. if '\\*[pre-collate]'\\n%@\\n[#COL_NUM]' \ +. nr #NO_FLEX 1 +. if '\\*[pre-newpage-\\n%]'\\n%@\\n[#COL_NUM]' \{\ +. nr #NO_FLEX 1 +. nr #RESTORE_FLEX 1 +. \} +. if d page-\\n%@\\n[#COL_NUM] \{\ +. nr #NO_FLEX 1 +. nr #RESTORE_COL_FLEX 1 +. \} +. \} +. \} +. \} +. nr #L_MARGIN \\n[.o] +. if \\n[#FN_DEPTH] .PROCESS_FN_LEFTOVER +. vs \\n[#LEAD_AT_FOOTER]u +. if \\n[#PREV_FN_DEFERRED] .nr #PREV_FN_DEFERRED 2 +. rr #RULED +. if !\\n[#EPIGRAPH] .rr #COL_NEXT +. if !\\n[#QUOTE] .rr #COL_NEXT +. if \\n[#RESET_FN_COUNTERS]=1 \{\ +. rr #RESET_FN_COUNTERS +. PROCESS_FN_IN_DIVER +. LS \\n[#LEAD_AT_FOOTER]u +. nr #FN_COUNT \\n[#FN_COUNT] 1 +. nr #FN_COUNT_FOR_COLS \\n[#FN_COUNT_FOR_COLS] 1 +. rm FN_IN_DIVER +. if dRUNON_FN_IN_DIVER .rm RUNON_FN_IN_DIVER +. \} +. rr #DEFER_SPACE_ADDED +. if \\n[#TAB_ACTIVE] .TAB \\n[#CURRENT_TAB] +. if \\n[#QUOTE] \{\ +. ie \\n[#TAB_ACTIVE] .TAB \\n[#CURRENT_TAB] +. el \{\ +. ie \\n[#Q_OFFSET_VALUE] \ +. nr #Q_OFFSET \ +\\n[#L_MARGIN]+(\\n[#PP_INDENT]*\\n[#Q_OFFSET_VALUE]) +. el \ +. nr #Q_OFFSET \\n[#L_MARGIN]+\\*[$Q_OFFSET_VALUE] +. if \\n[#COLUMNS] \{\ +. ie \\n[#Q_OFFSET_VALUE] .nr #Q_OFFSET \ +\\n[#COL_\\n[#COL_NUM]_L_MARGIN]+(\\n[#PP_INDENT]*\\n[#Q_OFFSET_VALUE]) +. el .nr #Q_OFFSET \ +\\n[#COL_\\n[#COL_NUM]_L_MARGIN]+\\*[$Q_OFFSET_VALUE] +. \} +. po \\n[#Q_OFFSET]u +. \} +. \} +. if \\n[#EPIGRAPH] \{\ +. ie \\n[#TAB_ACTIVE] .TAB \\n[#CURRENT_TAB] +. el \{\ +. ie r#EPI_OFFSET_VALUE .nr #EPI_OFFSET \ +\\n[#L_MARGIN]+(\\n[#PP_INDENT]*\\n[#EPI_OFFSET_VALUE]) +. el .nr #EPI_OFFSET \ +\\n[#L_MARGIN]+\\*[$EPI_OFFSET_VALUE] +. if \\n[#COLUMNS] \{\ +. ie r#EPI_OFFSET_VALUE .nr #EPI_OFFSET \ +\\n[#COL_\\n[#COL_NUM]_L_MARGIN]+(\\n[#PP_INDENT]*\\n[#EPI_OFFSET_VALUE]) +. el .nr #EPI_OFFSET \ +\\n[#COL_\\n[#COL_NUM]_L_MARGIN]+\\*[$EPI_OFFSET_VALUE] +. \} +. po \\n[#EPI_OFFSET]u +. \} +. \} +. ie \\n[tbl*interrupted] \{\ +. tbl*print-header +. rr tbl*interrupted +. \} +. el .if !r tbl*no-top-hook .tbl@top-hook +. rr tbl*no-top-hook +. ie \\n[#EPIGRAPH] \{\ +. ie !\\n[#EPI_ACTIVE] \{\ +. ns +. rr #EPI_ACTIVE +. \} +. el \{\ +. sp |\\n[dc]u+(\\n[#DOC_LEAD]u-\\n[#EPI_LEAD]u) +. rr #EPI_ACTIVE +. \} +. \} +. el .ns +. ev +. \} +. ns +. rr #DIVERTED +. ch RR_@TOP +. wh \\n[nl]u+1u RR_@TOP +. if \\n[tbl*have-header] .tbl@bottom-hook +. if \\n[defer] .PROCESS_FLOATS +. ie \\n[tbl*no-header] \{\ +. rs +. nop \& +. vpt +. rr \\n[tbl*no-header] +. SHIM_1 +. \} +. el .vpt +. if '\\n[.ev]'caption' .rs +. if \\n[tbl*interrupted] .tbl*print-header +. rr tbl*interrupted +. \} +. el .DO_FOOTER +. pdfmarkrestart +.END +\# +\# PROCESS FOOTER +\# -------------- +\# *Arguments: +\# +\# *Function: +\# Prints footer (page number, or 3-part footer). +\# Resets CAPS and UNDERLINE if they were on. +\# +.MAC DO_FOOTER END +.\" Kill pdfbackground if BoxStop causes a page break +. if r pdfbxstop \{\ +. pdfbackground off +. rr pdfbx-running +. \} +.\" Part of workaround for refer spitting out a blank page if the +.\" last reference falls on the bottom line. +. if \\n[num*refs] \{\ +. if \\n[ref*num]=\\n[num*refs] \{\ +. rr num*refs +. nr ref*last 1 +. \} +. \} +. ie !\\n[#DOC_TYPE]=5 .PRINT_FOOTER +. el .vpt +. if !\\n[ref*last] \{\ +. ie \\n[defer]>0 \{\ +\c +' bp +. \} +. el 'bp +. \} +.END +\# +.MAC PRINT_FOOTER END +. if r #SAVED_FOOTER_POS .ch FOOTER \\n[#SAVED_FOOTER_POS]u +. rr #SAVED_FOOTER_POS +. vpt 0 +. sp -1 +. ev FOOTER +. ie n \ +. sp |\\n[#PAGE_LENGTH]u-\\n[#FOOTER_MARGIN]u +. el \ +. sp |\\n[#PAGE_LENGTH]u-\\n[#FOOTER_MARGIN]u-\\n[#FOOTER_ADJ]u +. mk y +. UNDERLINE OFF +. po \\n[#DOC_L_MARGIN]u +. ll \\n[#DOC_L_LENGTH]u +. ta \\n[.l]u +. if \\n[#PRINT_STYLE]=1 .TYPEWRITER +. if \\n[#PRINT_STYLE]=2 \{\ +. fam \\*[$HDRFTR_FAM] +. ft R +. ps \\n[#DOC_PT_SIZE]u\\*[$HDRFTR_SIZE_CHANGE] +. \} +. nr #HDRFTR_PT_SIZE \\n[#PT_SIZE] +. if \\n[#CAPS_ON] \{\ +. nr #CAPS_WAS_ON 1 +. CAPS OFF +. \} +. ie \\n[#FOOTERS_ON] \{\ +. if !\\n[#SKIP_FOOTER]>0 .PRINT_HDRFTR +. if \\n[#HDRFTR_BOTH] \ +. HEADER_RECTO \\*[$HDR_RECTO_QUAD] "\\*[$HDR_RECTO_STRING]" +. if \\n[#DOC_TYPE]=5 .FOOTERS +. \} +. el \{\ +. if \\n[#PAGINATE] \{\ +. if \\n[#PAGE_NUM_V_POS]=2 \ +. if !\\n[#SKIP_FOOTER]>0 .PRINT_PAGE_NUMBER +. \} +. \} +. rr #SKIP_FOOTER +. if \\n[#CAPS_WAS_ON] \{\ +. CAPS +. rr #CAPS_WAS_ON +. \} +. ev +. vpt +.END +\# +\# ==================================================================== +\# +\# +++HEADERS AND FOOTERS+++ +\# +\# HEADERS_AND_FOOTERS +\# ------------------- +\# *Arguments: +\# HEADER_RECTO_QUAD \ +\# HEADER_RECTO_STRING \ +\# FOOTER_RECTO_QUAD \ +\# FOOTER_RECTO_STRING \ +\# HEADER_VERSO_QUAD \ +\# HEADER_VERSO_STRING \ +\# FOOTER_VERSO_QUAD \ +\# FOOTER_VERSO_STRING +\# | +\# *Function: +\# Allows having both headers and footers. Sets register +\# #HDRFTR_BOTH to 1; collects HEADER/FOOTER_RECTO/VERSO +\# information; appends FOOTER_RECTO and FOOTER_VERSO to +\# START and turns off pagination; appends to macros +\# PRINT_USERDEF_HDRFTR and HEADER the necessary number +\# register manipulations and redefinitions of the +\# HEADER/FOOTER_RECTO/VERSO strings so that both +\# headers and footers get printed, with the appropriate +\# strings for each +\# *Notes: +\# Works in conjunction with HDRFTR_RECTO and HDRFTR_VERSO (qqv.), +\# ergo all style changes must be done inline in the strings +\# passed as arguments. +\# +.MAC HEADERS_AND_FOOTERS END +. ie \\n[#NUM_ARGS]>1 \{\ +. nr #HDRFTR_BOTH 1 +. nr #FOOTERS_ON 1 +. if !r#HEADER_RULE .nr #HEADER_RULE 1 +. if !r#FOOTER_RULE .nr #FOOTER_RULE 1 +. ds $HDR_RECTO_QUAD \\$1 +. ds $HDR_RECTO_STRING \\$2 +. ds $FTR_RECTO_QUAD \\$3 +. ds $FTR_RECTO_STRING \\$4 +. ds $HDR_VERSO_QUAD \\$5 +. ds $HDR_VERSO_STRING \\$6 +. ds $FTR_VERSO_QUAD \\$7 +. ds $FTR_VERSO_STRING \\$8 +.am START DONE +. if \\\\n[#HDRFTR_BOTH]=1 \{\ +. FOOTER_RECTO \\\\*[$FTR_RECTO_QUAD] "\\\\*[$FTR_RECTO_STRING]" +. FOOTER_VERSO \\\\*[$FTR_VERSO_QUAD] "\\\\*[$FTR_VERSO_STRING]" +. if \\\\n[#HEADER_RULE]=1 .HEADER_RULE +. ie \\\\n[#FOOTER_RULE]=1 .FOOTER_RULE +. el .FOOTER_RULE OFF +. if r #PAGINATE .rr #PAGINATE +. if r #PAGE_NUM_V_POS .rr #PAGE_NUM_V_POS +. \} +.DONE +.am PRINT_USERDEF_HDRFTR DONE +. if \\\\n[#HDRFTR_BOTH]=1 \{\ +. if \\n[#FOOTERS_ON]=1 \{\ +. if !\\\\n[#COLLATE]=1 \{\ +. HEADER_RECTO \\*[$HDR_RECTO_QUAD] "\\*[$HDR_RECTO_STRING]" +. HEADER_VERSO \\*[$HDR_VERSO_QUAD] "\\*[$HDR_VERSO_STRING]" +. rr #FOOTERS_ON +. nr #HEADERS_ON 1 +. ie \\\\n[#HEADER_RULE]=1 .HEADER_RULE +. el .HEADER_RULE OFF +. \} +. \} +. if \\n[#HEADERS_ON]=1 \{\ +. FOOTER_RECTO \\*[$FTR_RECTO_QUAD] "\\*[$FTR_RECTO_STRING]" +. FOOTER_VERSO \\*[$FTR_VERSO_QUAD] "\\*[$FTR_VERSO_STRING]" +. \} +. \} +.DONE +.am HEADER DONE +. if \\\\n[#HDRFTR_BOTH]=1 \{\ +. if r #START_FOR_FOOTERS .rr #START_FOR_FOOTERS +. rr #HEADERS_ON +. nr #FOOTERS_ON 1 +. FOOTER_RECTO \\*[$FTR_RECTO_QUAD] "\\*[$FTR_RECTO_STRING]" +. FOOTER_VERSO \\*[$FTR_VERSO_QUAD] "\\*[$FTR_VERSO_STRING]" +. ie \\\\n[#FOOTER_RULE]=1 .FOOTER_RULE +. el .FOOTER_RULE OFF +. \} +.DONE +. \} +. el \{\ +. rr #HDRFTR_BOTH +. rr #USERDEF_HDRFTR +. rm $USERDEF_HDRFTR_RECTO +. rm $USERDEF_HDRFTR_VERSO +. FOOTERS OFF +. HEADERS +. if \\n[#COLLATE]=1 \{\ +. nr #HEADER_STATE 1 +. nr #PAGINATION_STATE 1 +. \} +. PAGINATE +. PAGENUM_POS BOTTOM CENTER +. nr #HF_OFF 1 +. \} +.END +\# +\# ==================================================================== +\# +\# +++HEADINGS+++ +\# +.char \[hd-num-spacer] \0 +.char \[parahead-spacer] \~\~ +.char \[toc-hd-num-spacer] \h'\w'\[en]'u' +.ds toc-word-space \ \" ie an unbreakable space +\# +\# HEADING +\# ------- +\# *Arguments: +\# [PARAHEAD] [NAMED ] +\# *Function: +\# Assigns a heading level to the heading text and prints heading +\# in the style set up for that level. If PARAHEAD given, the +\# heading is attached to the body of the paragraph. If NAMED +\# given, creates a target for pdf links. Collects the heading +\# for the TOC and sets TOC indenting appropriate for the level. +\# *Notes: +\# If PARAHEAD given, HEADING must come after PP. +\# +.MAC HEADING END +. ie !r pdfbx-top \{\ +' br +. if \\n[@TOP] .br +. \} +. el \{\ +. if r pdfbx-running .nr pdfbx-top 1 +. \} +. if !\B'\\$1' \{\ +. tm1 "[mom]: The first argument to \\$0 must be a numeric heading level. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. if r #QUOTE .rr #QUOTE +. if r #END_QUOTE .rr #END_QUOTE +. if r #EPIGRAPH .rr #EPIGRAPH +. vs \\n[#DOC_LEAD]u +. if \\$1<\\n[#LEVEL] \ +. nr #ACTIVE_LEVELS \\n[#LEVEL] \" loop count for resetting numbering registers +. nr #LAST_LEVEL \\n[#LEVEL] \" used during TOC collection, if SPACE_TOC_ITEMS +. nr #LEVEL \\$1 \" resets #LEVEL to arg +. shift +. nr #ARG_NUM 0 1 +. while \\n+[#ARG_NUM]<=2 \{\ +. if '\\$1'NAMED' \{\ +. ds PDF_NM "\\$1 \\$2 +. shift 2 \" \\$1 is now heading text +. \} +. if '\\$1'PARAHEAD' \{\ +. nr #PARAHEAD 1 +. shift \" \\$1 is now NAMED, if we have it; otherwise heading text +. \} +. \} +.\" Spacing +. if \\n[#Q_LEAD_DIFF_CHECK] .sp -1 +. if \\n[.t]<\\n[.v] .nr nl-from-heading \\n[nl] +. ie !\\n[#PARAHEAD] \{\ +. if !\\n[@TOP] \{\ +. nr #HEAD 1 +. ie !\\n[#START] \{\ +. nr #HEADING_NEEDS \\n[#NUM_ARGS]v+\\*[$HEAD_\\n[#LEVEL]_NEEDS]v+1v +. if \\n[#HEAD_\\n[#LEVEL]_SPACE_AFTER] .nr #HEADING_NEEDS +1v +. if \\n[.t]<\\n[#HEADING_NEEDS] .sp \\n[.t]u +. vpt 0 +. if !r pdfbx-top \ +. if !\\n[#SPACE_ADDED] .if !\\n[#LINEBREAK] .sp +. \} +. el \{\ +. ie !\\n[#PP] \{\ +. rr #START +. RESTORE_SPACE +. if !\\n[#SPACE_ADDED] \ +. if !\\n[#COLUMNS] .sp +. \} +. el .sp +. \} +. if \\n[#EPIGRAPH] \ +. if \\n[#SINGLE_SPACE] .sp +. \} +. if \\n[#PP_SPACE] \ +. if \\n[#QUOTE_4_HD] .sp .5v +. ie !\\n[#SPACE_ADDED] \{\ +. if !\\n[.ns] \{\ +. ie !\\n[#NO_SHIM] \ +. if !\\n[#HEAD_\\n[#LEVEL]_NO_SHIM] \ +. if !r pdfbx-top .SHIM +. el \{\ +. if !\\n[#NO_FLEX] \ +. if !\\n[#HEAD_\\n[#LEVEL]_NO_FLEX] \ +. if !r pdfbx-top .FLEX +. \} +. \} +. \} +. el .rr #SPACE_ADDED +. vpt +. \} +. el \{\ +. if \\n[#NUM_ARGS]>1 \{\ +. tm1 "[mom]: Error at line \\n[.c], \\$0. +. tm1 " PARAHEAD may not be given more than 1 line of text. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. vpt 0 +. if !(\\n[#PRINT_STYLE]=1)&(\\n[#SINGLE_SPACE]=1) .sp -1v +. if \\n[#QUOTE_4_HD] \{\ +. sp -1v +. if \\n[#PP_SPACE] \{\ +. sp .5v +. SHIM +. \} +. \} +. if (\\n[#QUOTE_4_HD]=0)&(\\n[#LB_4_HD]=0)&(\\n[#START]=0) \ +. if !\\n[#LB_4_PARAHEAD] .sp -1v +. \} +. ev HEADING +. evc 0 +.\" Style +. if \\n[#PRINT_STYLE]=2 \{\ +. fam \\*[$HEAD_\\n[#LEVEL]_FAM] +. ft \\*[$HEAD_\\n[#LEVEL]_FT] +. ps \\n[#DOC_PT_SIZE]u\\*[$HEAD_\\n[#LEVEL]_SIZE] +. if r pdfbx-top \{\ +. SIZESPECS +. ie \\n[#PP]=0 \{\ +. rt +. ds pdfbx-cap-adj \\*[$CAP_HEIGHT] +. sp (\\*[wt\\n[stack]]/2u)+\\*[pdfbx-cap-adj]+\\*[gap\\n[stack]]u +. \} +. el \{\ +. nr pdfbx-cap-adj \\*[$CAP_HEIGHT]-\\*[pdfbx-cap-adj] +. sp \\n[pdfbx-cap-adj]u +. \} +. \} +. nf +. \} +.\" Numbering +. ds $TOC_HD_NUM_PREV \\*[$TOC_HD_NUM] +. rm $TOC_HD_NUM +. rm $PDF_HD_NUM +. ie \\n[#NUMBER_HEAD_\\n[#LEVEL]] \{\ +. if \\n[#PREFIX_CH_NUM] .ds $HD_NUM \\n[#CH_NUM]. +. nr #HEAD_\\n[#LEVEL]_NUM +1 \" incremented manually here; still auto-increments +.\" Reset numbering registers for headings beneath current level +. nr @LEVEL \\n[#LEVEL] 1 \" loop step +. nr #LOOP \\n[#ACTIVE_LEVELS] \" loop count +. while \\n+[@LEVEL]<=\\n[#LOOP] \ +. if \\n[#HEAD_\\n[@LEVEL]_NUM] \ +. nr #HEAD_\\n[@LEVEL]_NUM 0 1 +.\" Build numbering strings for body and toc +. nr @LEVEL 0 1 \" loop step +. nr #LOOP \\n[#LEVEL] \" loop count +. while \\n+[@LEVEL]<=\\n[#LOOP] \ +. if \\n[#HEAD_\\n[@LEVEL]_NUM] \ +. as $HD_NUM \\n[#HEAD_\\n[@LEVEL]_NUM]. +. ie \\n[#TRUNC_TOC_HD_NUM] \ +. ds $TOC_HD_NUM \\n[#HEAD_\\n[#LEVEL]_NUM]. +. el .ds $TOC_HD_NUM \\*[$HD_NUM] +. if \\n[#LEVEL]=1 \ +. ds $TOC_HD_NUM_PREV \\*[$TOC_HD_NUM] +. if \\n[#TOC_NO_HD_NUM] .rm $TOC_HD_NUM +. if !\\n[#HEAD_\\n[#LEVEL]_NUM]] .rm $TOC_HD_NUM +. as $HD_NUM \[hd-num-spacer] +. ds $PDF_HD_NUM \\*[$TOC_HD_NUM] +. if !'\\*[$TOC_HD_NUM]'' .as $TOC_HD_NUM \[toc-hd-num-spacer] +. if !'\\*[$PDF_HD_NUM]'' .as $PDF_HD_NUM " " +. \} +. el .nr @LEVEL \\n[#LEVEL] 1 +.\" TOC collection and formatting +. nr #TOC_ENTRY_PN \\n%+\\n[#PAGE_NUM_ADJ] +. af #TOC_ENTRY_PN \\g[#PAGENUMBER] +. nr #ARG_NUM 0 1 +. while \\n[#ARG_NUM]<\\n[#NUM_ARGS] \{\ +. as $TOC_HEAD_\\n[#LEVEL]_ITEM "\\$[\\n+[#ARG_NUM]] +. if \\n[#NUM_ARGS]>\\n[#ARG_NUM] \ +. as $TOC_HEAD_\\n[#LEVEL]_ITEM "\\*[toc-word-space] +. \} +. PDF_BOOKMARK \ + \\*[PDF_NM] \\n[#LEVEL]+1 \ + \\*[$PDF_HD_NUM] \\*[$TOC_HEAD_\\n[#LEVEL]_ITEM] +. rm PDF_NM +. rm $PDF_HD_NUM +. ev TOC_EV +. ie \\n[#PRINT_STYLE]=1 \{\ +. fam \\*[$TYPEWRITER_FAM] +. ft R +. ps \\*[$TYPEWRITER_PS] +. \} +. el \{\ +. FAMILY \\*[$TOC_HEAD_\\n[#LEVEL]_FAM] +. FT \\*[$TOC_HEAD_\\n[#LEVEL]_FT] +. ps \\n[#TOC_PS]u\\*[$TOC_HEAD_\\n[#LEVEL]_SIZE] +. \} +.\" Indents for TOC heading levels. +.\" First, numbered heads. @LEVEL here is #LEVEL+1 +. ie \\n[#NUMBER_HEAD_\\n[#LEVEL]] \{\ +. ie !\\n[#TOC_NO_HD_NUM] \{\ +. ie \\n[#TRUNC_TOC_HD_NUM] \{\ +. if !\\n[#TOC_HEAD_\\n[@LEVEL]_INDENT_SET] \{\ +. ie !\\n[#FROM_STYLE_\\n[@LEVEL]] \{\ +. ie !\\n[#NUMBER_HEAD_\\n[@LEVEL]] \ +. nr #TOC_HEAD_\\n[@LEVEL]_INDENT \ +\\n[#TOC_HEAD_\\n-[@LEVEL]_INDENT]+\ +\w'\\*[$TOC_HD_NUM]'+\ +1.5m +. el \ +. nr #TOC_HEAD_\\n[@LEVEL]_INDENT \ +\\n[#TOC_HEAD_\\n-[@LEVEL]_INDENT]+\ +\w'\\*[$TOC_HD_NUM]' +. \} +. el \ +. nr #TOC_HEAD_\\n[@LEVEL]_INDENT \ + \\n[#TOC_HEAD_\\n-[@LEVEL]_INDENT] +. \} +. \} +. el \{\ +. if !\\n[#TOC_HEAD_\\n[@LEVEL]_INDENT_SET] \{\ +. ie !\\n[#FROM_STYLE_\\n[@LEVEL]] \{\ +. ie \\n[#NUMBER_HEAD_\\n-[@LEVEL]] \{\ +. ie !\\n[#NUMBER_HEAD_\\n+[@LEVEL]] \ +. nr #TOC_HEAD_\\n[@LEVEL]_INDENT \ +\\n[#TOC_HEAD_\\n-[@LEVEL]_INDENT]+\ +\w'\\*[$TOC_HD_NUM_PREV]'+\ +1.5m +. el \{\ +.\" Get the number of digits in the chapter number +. ds ch-num-width \\n[#CH_NUM] +. length ch-num-width \\*[ch-num-width] +. nr ch-num-width -1 +. nr num-ch-digits \w'\0'*\\n[ch-num-width] +. nr #TOC_HEAD_\\n[@LEVEL]_INDENT \ +\\n[#TOC_HEAD_\\n-[@LEVEL]_INDENT]+\ +\\n[num-ch-digits]+\ +\w'.\[toc-hd-num-spacer]' +. \} +. \} +. el \ +. nr #TOC_HEAD_\\n[@LEVEL]_INDENT \ +\\n[#TOC_HEAD_\\n-[@LEVEL]_INDENT]+\ +\w'\\n[#TOC_HD_NUM].' +. ie \\n[#LEVEL]=1 \ +. nr #TOC_HEAD_\\n+[@LEVEL]_INDENT +\w'\0' +. el \{\ +. if !\\n[#NUMBER_HEAD_\\n[@LEVEL]] \{\ +. nr @LEVEL \\n+[@LEVEL] 1 +. nr #TOC_HEAD_\\n+[@LEVEL]_INDENT +\w'\0' +. \} +. \} +. \} +. el \ +. nr #TOC_HEAD_\\n[@LEVEL]_INDENT \ +\\n[#TOC_HEAD_\\n-[@LEVEL]_INDENT]+\ +\\n[#TOC_HEAD_\\n+[@LEVEL]_INDENT] +. \} +. if \\n[#LEVEL]=1 \{\ +. if \\n[#NUMBER_HEAD_\\n[@LEVEL]] \{\ +. if \\n[#PREFIX_CH_NUM] \ +. nr #TOC_HEAD_\\n[@LEVEL]_INDENT \ +\w'\\*[$TOC_HD_NUM]' +. \} +. \} +. \} +. \} +. el \{\ +. ie !\\n[#FROM_STYLE_\\n[@LEVEL]] \{\ +. if !\\n[#TOC_HEAD_\\n[@LEVEL]_INDENT_SET] \ +. nr #TOC_HEAD_\\n[@LEVEL]_INDENT \ + \\n[#TOC_HEAD_\\n-[@LEVEL]_INDENT]+1.5m +. \} +. el \{\ +. if !\\n[#TOC_HEAD_\\n[@LEVEL]_INDENT_SET] \ +. nr #TOC_HEAD_\\n[@LEVEL]_INDENT \ +\\n[#TOC_HEAD_\\n-[@LEVEL]_INDENT]+\ +\\n[#TOC_HEAD_\\n+[@LEVEL]_INDENT] +. \} +. \} +. \} +.\" Non-numbered heads +. el \{\ +. nr @LEVEL \\n[#LEVEL] 1 +.\" increments @LEVEL even if false +. ie \\n[#FROM_STYLE_\\n+[@LEVEL]] \{\ +. if !\\n[#TOC_HEAD_\\n[@LEVEL]_INDENT_SET] \{\ +. nr #TOC_HEAD_\\n[@LEVEL]_INDENT \ +\\n[#TOC_HEAD_\\n[#LEVEL]_INDENT]+\ +\\n[#TOC_HEAD_\\n[@LEVEL]_INDENT] +. if !\\n[#LEVEL]=\\n[#LAST_LEVEL] \{\ +. if \\n[#NUMBER_HEAD_\\n[@LEVEL]] \ +. nr #TOC_HEAD_\\n[#LEVEL]_INDENT \ +\\n[#TOC_HEAD_\\n[@LEVEL]_INDENT]+\ +\w'\\*[$TOC_HD_NUM_PREV]' +. \} +. \} +. \} +. el \{\ +. nr #TOC_HEAD_\\n[@LEVEL]_INDENT \ + \\n[#TOC_HEAD_\\n-[@LEVEL]_INDENT]+1.5m +. if \\n[#LEVEL]=1 \{\ +. if !\\n[#FROM_STYLE_1] \ +. nr #TOC_HEAD_1_INDENT 0 +. \} +. \} +. \} +. nr #TOC_HEAD_\\n[@LEVEL]_INDENT_SET 1 +. HD_TO_TOC +. rm $TOC_HEAD_\\n[#LEVEL]_ITEM +.\" Print heading +. if !\\n[#PARAHEAD] .\\*[$HEAD_\\n[#LEVEL]_QUAD] +. if \\n[#CAPS_ON] \{\ +. CAPS OFF +. nr #CAPS_RESTORE 1 +. \} +. if \\n[#HEAD_\\n[#LEVEL]_CAPS] \{\ +. CAPS +. nr #CAPS_OFF 1 +. \} +. if \\n[#SMALLCAPS_ON] \{\ +. SMALLCAPS OFF +. nr #SMALLCAPS_RESTORE 1 +. \} +. if \\n[#HEAD_\\n[#LEVEL]_SMALLCAPS] \{\ +. SMALLCAPS +. nr #SMALLCAPS_OFF 1 +. \} +. if !'\\*[$HEAD_\\n[#LEVEL]_COLOR]'' \ +. COLOR \\*[$HEAD_\\n[#LEVEL]_COLOR] +. nop \X'ps: exec decornone'\c +. if r pdfbx-top \{\ +. ds $RESTORE_ADJ \\*[$HEAD_\\n[#LEVEL]_BASELINE_ADJ] +. ds $HEAD_\\n[#LEVEL]_BASELINE_ADJ 0 +. \} +. nr #ARG_NUM 0 1 +. while \\n+[#ARG_NUM]<=\\n[#NUM_ARGS] \{\ +. if \\n[#PARAHEAD] \ +. nr #PP_TEXT_OFFSET \ + \w'\\*[$HD_NUM]\\$[\\n[#ARG_NUM]]'+\w'\[parahead-spacer]' +. if (\\n[#HEAD_\\n[#LEVEL]_UNDERSCORE]=0)&(\\n[#HEAD_\\n[#LEVEL]_UNDERSCORE2]=0) \{\ +. ie \\n[#HD_NUM_INDENT] \{\ +. if !'\\*[$HEAD_\\n[#LEVEL]_QUAD]'CENTER' \ +. ti \\n[#HD_NUM_INDENT]u +. PRINT \ +"\v'-\\*[$HEAD_\\n[#LEVEL]_BASELINE_ADJ]'\\$[\\n[#ARG_NUM]] +. br +. \} +. el \{\ +. ie !\\n[#PARAHEAD] \{\ +. PRINT \ +"\v'-\\*[$HEAD_\\n[#LEVEL]_BASELINE_ADJ]'\\*[$HD_NUM]\\$[\\n[#ARG_NUM]] +. br +. \} +. el \{\ +. if (\\n[#PP]>0):(\\n[#INDENT_FIRST_PARAS]) \{\ +. if !\\n[#LB_4_PARAHEAD] \{\ +. if !\\n[#START] \{\ +. if \\n[#PP_ACTIVE] \{\ +. ie \\n[#PP]=1 .br +. el \{\ +. nr #PP_TEXT_OFFSET +\\n[#PP_INDENT] +. ie !\\n[pdfbx-running] .ti \\n[#PP_INDENT]u +. el .ti \\n[#PP_INDENT]u+\\*[wt\\n[stack]]+\\*[gap\\n[stack]]u +. \} +. \} +. \} +. \} +. \} +. ie \\n[#PRINT_STYLE]=1 \ +. PRINT "\\*[UL]\\*[$HD_NUM]\\$[\\n[#ARG_NUM]]\\*[ULX] +. el .PRINT "\\*[$HD_NUM]\\$[\\n[#ARG_NUM]] +. rr #LB_4_PARAHEAD +. sp -1v +. \} +. \} +. \} +. if \\n[#HEAD_\\n[#LEVEL]_UNDERSCORE] \{\ +. nr #SAVED_UL_WEIGHT \\n[#UNDERSCORE_WEIGHT] +. UNDERSCORE_WEIGHT \\*[$HEAD_\\n[#LEVEL]_UL_WEIGHT] +. ie \\n[#HD_NUM_INDENT] \{\ +. if !'\\*[$HEAD_\\n[#LEVEL]_QUAD]'CENTER' \ +. ti \\n[#HD_NUM_INDENT]u +. UNDERSCORE \\*[$HEAD_\\n[#LEVEL]_UL_GAP] \ + "\v'-\\*[$HEAD_\\n[#LEVEL]_BASELINE_ADJ]'\\$[\\n[#ARG_NUM]] +. br +. \} +. el \{\ +. ie !\\n[#PARAHEAD] \{\ +. UNDERSCORE \\*[$HEAD_\\n[#LEVEL]_UL_GAP] \ +"\v'-\\*[$HEAD_\\n[#LEVEL]_BASELINE_ADJ]'\\*[$HD_NUM]\\$[\\n[#ARG_NUM]] +. br +. \} +. el \{\ +. if (\\n[#PP]>0):(\\n[#INDENT_FIRST_PARAS]) \{\ +. if !\\n[#LB_4_HD] \{\ +. if !\\n[#START] \{\ +. if \\n[#PP_ACTIVE] \{\ +. nr #PP_TEXT_OFFSET +\\n[#PP_INDENT] +. if (\\n[#PRINT_STYLE]=1)&(\\n[#SINGLE_SPACE]=1) .sp -1v +. ti \\n[#PP_INDENT]u +. \} +. \} +. \} +. \} +. UNDERSCORE \\*[$HEAD_\\n[#LEVEL]_UL_GAP] \ + "\\*[$HD_NUM]\\$[\\n[#ARG_NUM]] +. sp -1v +. \} +. \} +. nr #UNDERSCORE_WEIGHT \\n[#SAVED_UL_WEIGHT] +. \} +. if \\n[#HEAD_\\n[#LEVEL]_UNDERSCORE2] \{\ +. nr #SAVED_UL2_WEIGHT \\n[#UNDERSCORE_WEIGHT] +. UNDERSCORE_WEIGHT \\*[$HEAD_\\n[#LEVEL]_UL2_WEIGHT] +. ie \\n[#HD_NUM_INDENT] \{\ +. if !'\\*[$HEAD_\\n[#LEVEL]_QUAD]'CENTER' \ +. ti \\n[#HD_NUM_INDENT]u +. UNDERSCORE2 \\*[$HEAD_\\n[#LEVEL]_UL2_GAP_1] \ + \\*[$HEAD_\\n[#LEVEL]_UL2_GAP_2] \ + "\v'-\\*[$HEAD_\\n[#LEVEL]_BASELINE_ADJ]'\\$[\\n[#ARG_NUM]] +. br +. \} +. el \{\ +. ie !\\n[#PARAHEAD] \{\ +. UNDERSCORE2 \\*[$HEAD_\\n[#LEVEL]_UL2_GAP_1] \ + \\*[$HEAD_\\n[#LEVEL]_UL2_GAP_2] \ +"\v'-\\*[$HEAD_\\n[#LEVEL]_BASELINE_ADJ]'\\*[$HD_NUM]\\$[\\n[#ARG_NUM]] +. br +. \} +. el \{\ +. if (\\n[#PP]>0):(\\n[#INDENT_FIRST_PARAS]) \{\ +. if !\\n[#LB_4_HD] \{\ +. if !\\n[#START] \{\ +. if \\n[#PP_ACTIVE] \{\ +. nr #PP_TEXT_OFFSET +\\n[#PP_INDENT] +. if (\\n[#PRINT_STYLE]=1)&(\\n[#SINGLE_SPACE]=1) \ +. sp -1v +. ti \\n[#PP_INDENT]u +. \} +. \} +. \} +. \} +. UNDERSCORE2 \\*[$HEAD_\\n[#LEVEL]_UL2_GAP_1] \ +\\*[$HEAD_\\n[#LEVEL]_UL2_GAP_2] "\\*[$HD_NUM]\\$[\\n[#ARG_NUM]] +. sp -1v +. \} +. \} +. nr #UNDERSCORE_WEIGHT \\n[#SAVED_UL2_WEIGHT] +. \} +. if !\\n[#HD_NUM_INDENT] .nr #HD_NUM_INDENT \w'\\*[$HD_NUM]' +. \} +. if r pdfbx-top \{\ +. ds $HEAD_\\n[#LEVEL]_BASELINE_ADJ \\*[$RESTORE_ADJ] +. if !\\n[#PARAHEAD] .sp \\*[$HEAD_\\n[#LEVEL]_BASELINE_ADJ] +. \} +. if !\\n[#PARAHEAD] \ +. if \\n[#HEAD_\\n[#LEVEL]_SPACE_AFTER] .sp +. if \\n[#CAPS_OFF] \{\ +. CAPS OFF +. rr #CAPS_OFF +. \} +. if \\n[#CAPS_RESTORE] \{\ +. CAPS +. rr #CAPS_RESTORE +. \} +. if \\n[#SMALLCAPS_OFF] \{\ +. SMALLCAPS OFF +. rr #SMALLCAPS_OFF +. \} +. if \\n[#SMALLCAPS_RESTORE] \{\ +. SMALLCAPS +. rr #SMALLCAPS_RESTORE +. \} +. ev +. rm $HD_NUM +. rr #HD_NUM_INDENT +. if \\n[@TOP] \{\ +. ch RR_@TOP +. rr @TOP +. rs +. nop \& +. sp -1 +. \} +. if \\n[#PARAHEAD] \{\ +. ie !\\n[pdfbx-running] .ti \\n[#PP_TEXT_OFFSET]u +. el .ti \\n[#PP_TEXT_OFFSET]u+\\*[wt\\n[stack]]+\\*[gap\\n[stack]]u +. \} +. if !\\n[#PARAHEAD] .nr #PP 0 +. rr #PARAHEAD +. if \\n[#LB_4_HD] .rr #LB_4_HD +. if \\n[#QUOTE_4_HD] .rr #QUOTE_4_HD +. vpt +. rr nl-from-heading +. if r pdfbx-top \{\ +. rr pdfbx-top +. nr pdfbx-top\\n[stack] 1 +. \} +.END +\# +\# HEADING_STYLE +\# ------------- +\# *Arguments: +\# +\# FAMILY +\# FONT +\# SIZE <+|-n> +\# COLOR +\# CAPS | NO_CAPS +\#---when called as HEADING_STYLE, these are also available--- +\# QUAD +\# NUMBER | NO_NUMBER +\# SPACE_AFTER | NO_SPACE_AFTER +\# UNDERSCORE | UNDERSCORE2 +\# NO_UNDERSCORE | NO_UNDERSCORE2 +\# BASELINE_ADJUST +\#---when called as TOC_ENTRY_STYLE this is also available--- +\# INDENT +\# *Function: +\# Sets up complete style parameters for HEADING . If +\# invoked as TOC_ENTRY_STYLE, sets up parameters for the +\# corresponding TOC entry at . +\# *Notes: +\# Arguments may be given in any order. Any not given retain +\# their current values. Defaults for an initial 9 levels of +\# heading are set up in PRINTSTYLE. +\# +\# NUMBER indicates that hierarchic numbering of should be +\# prepended to heading text. If invoked as TOC_ENTRY_STYLE, +\# prepend numbering to TOC entries at (only works if +\# NUMBER is given to the corresponding HEADING ). +\# +\# INDENT refers to the indent for in the TOC. It is +\# measured from the left offset of the entry level above it +\# (including numbering, if present). TOC entry levels beneath +\# will have their indents adjusted accordingly. +\# +.MAC HEADING_STYLE END +. if !'\\$0'TOC_HEADING_STYLE' \{\ +. if !\B'\\$1' \{\ +. tm1 "[mom]: The first argument to \\$0 must be a numeric heading level. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. nr #LEVEL \\$1 +. if \\n[#FROM_OLDSTYLE] .nr #LEVEL_\\n[#LEVEL]_SET 1 +. shift +.\" Prepend TOC_ to style strings if called as TOC_ENTRY_STYLE +. \} +. if '\\$0'TOC_ENTRY_STYLE' .ds $TOC TOC_ +. nr #ARG_NUM 0 1 +. nr #ATTRIB \\n[#NUM_ARGS] +. while \\n+[#ARG_NUM]<=\\n[#ATTRIB] \{\ +. if '\\$1'UNDERSCORE' \{\ +. nr #HEAD_\\n[#LEVEL]_UNDERSCORE 1 +. shift +. if '\\$1'' \{\ +. tm1 "[mom]: The UNDERSCORE argument to \\$0 requires a rule weight. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. ds $HEAD_\\n[#LEVEL]_UL_WEIGHT \\$1 +. shift +. if '\\$1'' \{\ +. tm1 "[mom]: The UNDERSCORE argument to \\$0 requires a rule gap. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. ds $HEAD_\\n[#LEVEL]_UL_GAP \\$1 +. shift +. \} +. if '\\$1'NO_UNDERSCORE' \{\ +. rr #HEAD_\\n[#LEVEL]_UNDERSCORE +. shift +. \} +. if '\\$1'UNDERSCORE2' \{\ +. nr #HEAD_\\n[#LEVEL]_UNDERSCORE2 1 +. shift +. if '\\$1'' \{\ +. tm1 "[mom]: The UNDERSCORE2 argument to \\$0 requires a rule weight. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. ds $HEAD_\\n[#LEVEL]_UL2_WEIGHT \\$1 +. shift +. if '\\$1'' \{\ +. tm1 "[mom]: The UNDERSCORE2 argument to \\$0 requires a rule gap. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. ds $HEAD_\\n[#LEVEL]_UL2_GAP_1 \\$1 +. shift +. if '\\$1'' \{\ +. tm1 "[mom]: The UNDERSCORE2 argument to \\$0 requires an inter-rule gap. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. ds $HEAD_\\n[#LEVEL]_UL2_GAP_2 \\$1 +. shift +. \} +. if '\\$1'NO_UNDERSCORE2' \{\ +. rr #HEAD_\\n[#LEVEL]_UNDERSCORE2 +. shift +. \} +. if '\\$1'SPACE_ABOVE' \{\ +. shift +. ds $SPACE_ABOVE \\$1 +. shift +. \} +. if '\\$1'SPACE_BENEATH' \{\ +. shift +. ds $SPACE_BENEATH \\$1 +. shift +. \} +. if '\\$1'SPACE_AFTER' \{\ +. nr #HEAD_\\n[#LEVEL]_SPACE_AFTER 1 +. shift +. \} +. if '\\$1'NO_SPACE_AFTER' \{\ +. rr #HEAD_\\n[#LEVEL]_SPACE_AFTER +. shift +. \} +. if '\\$1'FAMILY' \{\ +. shift +. ds $\\*[$TOC]HEAD_\\n[#LEVEL]_FAM \\$1 +. if '\\$0'TOC_HEADING_STYLE' .ds $TOC_HEADING_FAM \\$1 +. shift +. \} +. if '\\$1'FONT' \{\ +. shift +. ds $\\*[$TOC]HEAD_\\n[#LEVEL]_FT \\$1 +. if '\\$0'TOC_HEADING_STYLE' .ds $TOC_HEADING_FT \\$1 +. shift +. \} +. if '\\$1'SIZE' \{\ +. shift +. ds $\\*[$TOC]HEAD_\\n[#LEVEL]_SIZE \\$1 +. if '\\$0'TOC_HEADING_STYLE' .ds $TOC_HEADING_SIZE \\$1 +. shift +. \} +. if '\\$1'QUAD' \{\ +. shift +. ds $QUAD_TYPE \\$1 +. substring $QUAD_TYPE 0 0 +. ie !'\\$0'TOC_HEADING_STYLE' \{\ +. if '\\*[$QUAD_TYPE]'L' .ds $HEAD_\\n[#LEVEL]_QUAD LEFT +. if '\\*[$QUAD_TYPE]'C' .ds $HEAD_\\n[#LEVEL]_QUAD CENTER +. if '\\*[$QUAD_TYPE]'R' .ds $HEAD_\\n[#LEVEL]_QUAD RIGHT +. \} +. el \{\ +. if '\\*[$QUAD_TYPE]'L' .ds $TOC_HEADING_QUAD LEFT +. if '\\*[$QUAD_TYPE]'C' .ds $TOC_HEADING_QUAD CENTER +. if '\\*[$QUAD_TYPE]'R' .ds $TOC_HEADING_QUAD RIGHT +. \} +. shift +. \} +. if '\\$1'COLOR' \{\ +. shift +. ds $\\*[$TOC]HEAD_\\n[#LEVEL]_COLOR \\$1 +. if '\\$0'TOC_HEADING_STYLE' .ds $TOC_HEADING_COLOR \\$1 +. shift +. \} +. if '\\$1'BASELINE_ADJUST' \{\ +. shift +. ds $HEAD_\\n[#LEVEL]_BASELINE_ADJ \\$1 +. shift +. \} +. if '\\$1'CAPS' \{\ +. nr #\\*[$TOC]HEAD_\\n[#LEVEL]_CAPS 1 +. shift +. \} +. if '\\$1'NO_CAPS' \{\ +. rr #HEAD_\\n[#LEVEL]_CAPS +. shift +. \} +. if '\\$1'SMALLCAPS' \{\ +. nr #\\*[$TOC]HEAD_\\n[#LEVEL]_SMALLCAPS 1 +. shift +. \} +. if '\\$1'NO_SMALLCAPS' \{\ +. rr #HEAD_\\n[#LEVEL]_SMALLCAPS +. shift +. \} +. if '\\$1'NUMBER' \{\ +. nr #NUMBER_HEAD_\\n[#LEVEL] 1 +. nr #HEAD_\\n[#LEVEL]_NUM 0 1 +. shift +. \} +. if '\\$1'NO_NUMBER' \{\ +. rr #NUMBER_HEAD_\\n[#LEVEL] +. shift +. \} +. if '\\$1'PREFIX_CHAPTER' \{\ +. shift +. ie \B'\\$1' \{\ +. PREFIX_CHAPTER_NUMBER \\$1 +. \} +. el .PREFIX_CHAPTER_NUMBER +. \} +. if '\\$1'INDENT' \{\ +. shift +. nr #TOC_HEAD_\\n[#LEVEL]_INDENT \\$1 +. nr #FROM_STYLE_\\n[#LEVEL] 1 +. shift +. \} +. if '\\$1'NEEDS' \{\ +. shift +. ds $HEAD_\\n[#LEVEL]_NEEDS \\$1 +. shift +. \} +. if '\\$1'SHIM' \{\ +. rr #HEAD_\\n[#LEVEL]_NO_SHIM +. shift +. \} +. if '\\$1'NO_SHIM' \{\ +. nr #HEAD_\\n[#LEVEL]_NO_SHIM 1 +. shift +. \} +. if '\\$1'FLEX' \{\ +. rr #HEAD_\\n[#LEVEL]_NO_FLEX +. shift +. \} +. if '\\$1'NO_FLEX' \{\ +. nr #HEAD_\\n[#LEVEL]_NO_FLEX 1 +. shift +. \} +. \} +. rr #LEVEL +. if d$TOC .rm $TOC +.END +. +.ALIAS TOC_ENTRY_STYLE HEADING_STYLE +.ALIAS TOC_HEADING_STYLE HEADING_STYLE +\# +\# OLDSTYLE HEADINGS +\# ----------------- +\# *Arguments: +\# None. +\# *Function: +\# Called from HEAD, SUBHEAD, and SUBSUBHEAD, sets style +\# parameters for HEADINGs 1-3 to former mom defaults for those macros. +\# Any styles already assigned to those levels are retained. +\# +\# Called by user with no argument, allows use of old style HEAD, +\# SUBHEAD, and SUBSUBHEAD without generating the deprecated msg. +\# *Notes: +\# For backward compatibility, and to ease the transition to +\# the HEADING scheme for heads. +\# +\# Paraheads must be set with .HEADING PARAHEAD; attempts +\# to call PARAHEAD abort with an instructive message. +\# +.MAC OLDSTYLE_HEADINGS END +. if '\\$1'' .nr #SKIP_MSG 1 +. nr #FROM_OLDSTYLE 1 \" Used in HEADING +. if \\n[#PRINT_STYLE]=1 \{\ +. if !\\n[#LEVEL_1_SET] \{\ +. HEADING_STYLE 1 \ + FONT R \ + SIZE +0 \ + QUAD C \ + CAPS \ + UNDERSCORE .5 2p \ + BASELINE_ADJUST 0 \ + SPACE_AFTER +. nr #OLDSTYLE_HD 1 +. return +. \} +. if !\\n[#LEVEL_2_SET] \{\ +. HEADING_STYLE 2 \ + FONT R \ + SIZE +0 \ + UNDERSCORE .5 2p \ + BASELINE_ADJUST \\n[.v]/8 +. nr #OLDSTYLE_SH 1 +. return +. \} +. if !\\n[#LEVEL_3_SET] \{\ +. HEADING_STYLE 3 \ + FONT R \ + SIZE +0 \ + BASELINE_ADJUST \\n[.v]/8 +. nr #OLDSTYLE_SSH 1 +. return +. \} +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. if !\\n[#LEVEL_1_SET] \{\ +. HEADING_STYLE 1 \ + FAMILY \E*[$DOC_FAM] \ + FONT B \ + SIZE +1 \ + QUAD C \ + CAPS \ + UNDERSCORE .5 2p \ + BASELINE_ADJUST 0 \ + SPACE_AFTER +. nr #OLDSTYLE_HD 1 +. return +. \} +. if !\\n[#LEVEL_2_SET] \{\ +. HEADING_STYLE 2 \ + FAMILY \E*[$DOC_FAM] \ + FONT B \ + SIZE +.5 \ + BASELINE_ADJUST \\n[.v]/8 +. nr #OLDSTYLE_SH 1 +. return +. \} +. if !\\n[#LEVEL_3_SET] \{\ +. HEADING_STYLE 3 \ + FAMILY \E*[$DOC_FAM] \ + FONT I \ + SIZE +.5 \ + BASELINE_ADJUST \\n[.v]/8 +. nr #OLDSTYLE_SSH 1 +. return +. \} +. \} +. rr #FROM_OLDSTYLE +.END +\# +\# "Deprecated" message +\# +.MAC DEPRECATED END +. if !\\n[#SKIP_MSG] \{\ +. tm1 "[mom]: Macro '\\$1' at line \\n[.c] is deprecated. +. tm1 " Invoking HEADING \\$2 instead and assigning style defaults +. tm1 " from former \\$1 as described in the documentation. +. tm1 " If another style is desired, use HEADING_STYLE \\$2 to +. tm1 " create it (see docs). +. tm1 " Further warnings will not be emitted for \\$1. +. tm1 " To avoid this message when using the deprecated HEAD, +. tm1 " SUBHEAD, and SUBSUBHEAD macros, add '.OLDSTYLE_HEADINGS' +. tm1 " after PRINTSTYLE before START. +. rm $MACRO +. \} +.END +\# +\# Wrappers around old-style headings. +\# +.MAC HEAD END +. if !\\n[#OLDSTYLE_HD] \{\ +. DEPRECATED HEAD 1 +. OLDSTYLE_HEADINGS HEAD +. \} +. HEADING 1 \\$@ +.END +\# +.MAC SUBHEAD END +. if !\\n[#OLDSTYLE_SH] \{\ +. DEPRECATED SUBHEAD 2 +. OLDSTYLE_HEADINGS SUBHEAD +. \} +. HEADING 2 \\$@ +.END +\# +.MAC SUBSUBHEAD END +. if !\\n[#OLDSTYLE_SSH] \{\ +. DEPRECATED SUBSUBHEAD 3 +. OLDSTYLE_HEADINGS SUBSUBHEAD +. \} +. HEADING 3 \\$@ +.END +\# +.MAC PARAHEAD END +. tm1 "[mom]: \\$0 is no longer a valid macro. +. tm1 " Use 'HEADING PARAHEAD ' instead. +. tm1 " You will probably want to invoke HEADING_STYLE to set +. tm1 " the type parameters for the parahead. See docs. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +.END +\# +\# Wrapper macro for oldstyle NUMBER_HEADS, NUMBER_SUBHEADS... +\# +.MAC HEADING_NUMBERS END +. if '\\$0'NUMBER_PARAHEADS' \{\ +. tm1 "[mom]: \\$0 is no longer a valid macro. +. tm1 " Use 'HEADING_STYLE NUMBER' instead. See docs. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. return +. \} +. if '\\$0'NUMBER_HEADS' .nr level 1 +. if '\\$0'NUMBER_SUBHEADS' .nr level 2 +. if '\\$0'NUMBER_SUBSUBHEADS' .nr level 3 +. ds mom "[mom]:\" +. ie '\\$1'' .ds $PARAM NUMBER +. el \{\ +. ds $PARAM NO_NUMBER +. ds $SWITCH " \\$1 +. \} +. HEADING_STYLE \\n[level] \\*[$PARAM] +. if (\\n[#OLDSTYLE_HD]=1):(\\n[#OLDSTYLE_SH]=1):(\\n[#OLDSTYLE_SSH]=1) \{\ +. tm1 "\\*[mom] OLDSTYLE_HEADINGS detected. +. ds mom " \" +. \} +. tm1 "\\*[mom] Setting HEADING_STYLE \\n[level] to '\\*[$PARAM]' at '\\$0\\*[$SWITCH]', line \\n[.c]. +. rm $PARAM +. rm $SWITCH +.END +. +.ALIAS NUMBER_HEADS HEADING_NUMBERS +.ALIAS NUMBER_SUBHEADS HEADING_NUMBERS +.ALIAS NUMBER_SUBSUBHEADS HEADING_NUMBERS +.ALIAS NUMBER_PARAHEADS HEADING_NUMBERS +\# +\# PREFIX CHAPTER NUMBERS TO HEADINGS/TOC ENTRIES +\# ---------------------------------------------- +\# *Arguments: +\# | | +\# *Function: +\# Toggles register #PREFIX_CH_NUM. Uses $CHAPTER to set #CH_NUM +\# if $CHAPTER is a digit; if given, sets #CH_NUM +\# to arg. +\# *Notes: +\# Default is OFF. +\# +.MAC PREFIX_CHAPTER_NUMBER END +. if \\n[#NUM_ARGS]=0 \{\ +. if !'\\*[$CHAPTER]'' \{\ +. if !\B'\\*[$CHAPTER]' \{\ +. tm1 "[mom]: \\$0 at line \\n[.c] cannot determine a chapter number. +. tm1 " Enter the current chapter number as a digit after PREFIX_CHAPTER. +. ab [mom]: Aborting '\\n[.F]', line \\n[.c]. +. \} +. \} +. \} +. ie '\\$1'' .nr #PREFIX_CH_NUM 1 +. el \{\ +. ie \B'\\$1' \{\ +. nr #PREFIX_CH_NUM 1 +. nr #CH_NUM \\$1 +. \} +. el .rr #PREFIX_CH_NUM +. \} +.END +\# +\# ==================================================================== +\# +\# +++LINE BREAKS+++ +\# +\# LINEBREAK CHARACTER +\# ------------------- +\# *Arguments: +\# [character] [iterations] [vertical adjustment] +\# *Function: +\# Allows user to specify a line break character and the number +\# of times to repeat it horizontally. +\# *Notes: +\# Without an argument, LINEBREAK_CHAR will deposit a blank line. +\# +\# Vertical adjustment requires a unit of measure (most likely +\# "p"), and has to be preceded by +|- +\# +.MAC LINEBREAK_CHAR END +. nr #REPEAT 1 +. ds $LINEBREAK_CHAR \\$1 +. if !'\\$2'' .nr #LB_CHAR_ITERATIONS \\$2 +. if !'\\$3'' .ds $LINEBREAK_CHAR_V_ADJ \\$3 +. if '\\*[$LINEBREAK_CHAR_V_ADJ]'' .ds $LINEBREAK_CHAR_V_ADJ +0 +. if \\n[#LB_CHAR_ITERATIONS] \{\ +. while (\\n[#LB_CHAR_ITERATIONS]>\\n[#REPEAT]) \{\ +. as $LINEBREAK_CHAR "\\ \\$1 +. nr #REPEAT \\n[#REPEAT]+1 +. \} +. \} +. rr #REPEAT +. rr #LB_CHAR_ITERATIONS +.END +\# +\# LINE BREAK +\# ---------- +\# *Arguments: +\# +\# *Function: +\# Deposits line break character. +\# *Notes: +\# If $LINEBREAK_CHAR is blank, simply advances 2 line spaces. +\# +.MAC LINEBREAK END +. if r #Q_AT_TOP .rr #Q_AT_TOP +. if \\n[@TOP] .RESTORE_SPACE +. ie '\\*[$LINEBREAK_CHAR]'' \{\ +. br +. nop \& +. sp +. \} +. el \{\ +. ie \\n[#END_QUOTE] . +. el .sp +. ev LINEBREAK +. evc 0 +. CENTER +. PRINT \ +\m[\\*[$LINEBREAK_COLOR]]\v'\\*[$LINEBREAK_CHAR_V_ADJ]'\ +\\*[$LINEBREAK_CHAR]\m[] +. sp +. ev +. QUAD \\*[$DOC_QUAD] +. \} +. nr #LINEBREAK 1 +. if r #QUOTE .rr #QUOTE +. if r #END_QUOTE .rr #END_QUOTE +. nr #PP 0 +. nr #LB_4_HD 1 +. nr #LB_4_PARAHEAD 1 +.END +\# +\# ==================================================================== +\# +\# +++PARAGRAPHS+++ +\# +\# PARAGRAPH FONT +\# -------------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies string $PP_FT. +\# *Notes: +\# Affects all paragraphs. +\# +.MAC PP_FONT END +. if \\n[#PRINT_STYLE]=1 \{\ +. ie \\n[#ITALIC_MEANS_ITALIC] .nop +. el .return +. \} +. if \\n[#COLLATE]=1 \ +. if !'\\*[$SAVED_PP_FT]'' .rm $SAVED_PP_FT +. ds $PP_FT \\$1 +. FT \\*[$PP_FT] +.END +\# +\# PARAGRAPH INDENT +\# ---------------- +\# *Argument: +\# +\# *Function: +\# Allows user to change the default para indent. The change will +\# affect the indent of QUOTEs and BLOCKQUOTEs as well. +\# *Notes: +\# Default for printstyle TYPEWRITE is 1/2-inch. Default for +\# printstyle TYPESET is 2 ems. The defaults are set in +\# PRINTSTYLE, not DEFAULTS. +\# +.MAC PARA_INDENT END +. ie \B'\\$1' \{\ +. nr #PP_INDENT (\\$1) +. nr #SAVED_PP_INDENT \\n[#PP_INDENT] +. \} +. el \{\ +. ie '\\$1'' \{\ +. nr #PP_INDENT \\n[#SAVED_PP_INDENT] +. rr #SAVED_PP_INDENT +. \} +. el \{\ +. nr #SAVED_PP_INDENT \\n[#PP_INDENT] +. rr #PP_INDENT +. \} +. \} +.END +\# +\# INDENT FIRST PARAGRAPHS +\# ----------------------- +\# *Arguments: +\# | +\# *Function: +\# By default, the first para of a document, as well as the first +\# paras of blockquotes and block-style epigraphs are not indented. +\# When invoked, this macro will indent all paras. +\# *Notes: +\# Default is OFF. +\# +.MAC INDENT_FIRST_PARAS END +. ie '\\$1'' .nr #INDENT_FIRST_PARAS 1 +. el .rr #INDENT_FIRST_PARAS +.END +\# +\# INTER-PARAGRAPH SPACING +\# ----------------------- +\# *Arguments: +\# | +\# *Function: +\# Adds a line space between paragraphs in body text. Block quotes +\# are unaffected. +\# *Notes: +\# Default is OFF. PARA_SPACE is not recommended for use with +\# PRINTSTYLE TYPEWRITE without SINGLESPACE. +\# +.MAC PARA_SPACE END +. ie '\\$1'' \ +. nr #PP_SPACE 1 +. el \{\ +. ie \B'\\$1' \{\ +. nr #PP_SPACE 1 +. ds $PP_SPACE_AMOUNT \\$1 +. \} +. el .rr #PP_SPACE +. \} +.END +\# +\# PARAGRAPH +\# --------- +\# *Arguments: +\# +\# *Function: +\# Figures out what to do with paragraphs under differing conditions. +\# *Notes: +\# Note the use of transparent line break (\!.br) to get +\# PP to work within blockquotes and epigraphs. +\# +\# PP_STYLE 1 = regular paras; 2 = blockquotes, epigraphs +\# +.MAC PP END +. if \\n[#COVERTEXT_PP] \{\ +. ie \\n[#INDENT_ACTIVE] .ti \\n[#INDENT]u+\\n[#PP_INDENT]u +. el .ti \\n[#PP_INDENT]u +. return +. \} +. if \\n[#PP]>0 .br +. if \\n[#DOC_TYPE]=4 \{\ +. if !'\\n[.z]'' .di +. nr #TOTAL_FIELDS \\n[#FIELD] +. nr #FIELD 0 1 +. nr #NUM_FIELDS 0 1 +. if \\n[#TOTAL_FIELDS]>0 \{\ +. while \\n+[#NUM_FIELDS]<=\\n[#TOTAL_FIELDS] \{\ +. nf +. LETTERHEAD\\n+[#FIELD] +. QUAD \\*[$DOC_QUAD] +. ALD \\n[#DOC_LEAD]u +. if \\n[#DATE_FIRST]=1 .ALD \\n[#DOC_LEAD]u +. rr #DATE_FIRST +. rm LETTERHEAD\\n[#FIELD] +. \} +. rr #FIELD +. rr #NUM_FIELDS +. rr #TOTAL_FIELDS +. \} +. \} +. rr #PP_ACTIVE +. if r #Q_AT_TOP .rr #Q_AT_TOP +. if \\n[#PP_STYLE]=1 \{\ +. if \\n[#ENDNOTE] \{\ +. nr #RESET_PARA_SPACE \\n[#PP_SPACE] +. ie \\n[#EN_PP_SPACE] .PARA_SPACE +. el .PARA_SPACE OFF +. \} +. if !\\n[#ENDNOTE] .po \\n[#L_MARGIN]u +. if \\n[#COLUMNS] \{\ +. if !\\n[#ENDNOTE] \{\ +. po \\n[#COL_\\n[#COL_NUM]_L_MARGIN]u +. nr #L_MARGIN \\n[.o] +. \} +. \} +. if \\n[#TAB_ACTIVE] .TAB \\n[#CURRENT_TAB] +. ie \\n[#PRINT_STYLE]=1 \{\ +. TYPEWRITER +. ie \\n[#ENDNOTE] .vs \\n[#EN_LEAD]u +. el .vs \\n[#DOC_LEAD]u +. QUAD \\*[$DOC_QUAD] +. if \\n[#SLANT_ON] \ +. if \\n[#UNDERLINE_SLANT] .UNDERLINE +. if '\\*[$PP_FT]'I' \ +. if \\n[#ITALIC_MEANS_ITALIC] .FT I +. \} +. el \{\ +. ie \\n[#ENDNOTE] \{\ +. FAMILY \\*[$EN_FAM] +. FT \\*[$EN_FT] +. ps \\n[#EN_PS]u +. vs \\n[#EN_LEAD]u +. QUAD \\*[$EN_QUAD] +. \} +. el \{\ +. FAMILY \\*[$DOC_FAM] +. if !'\\*[$SAVED_PP_FT]'' \{\ +. ds $PP_FT \\*[$SAVED_PP_FT] +. rm $SAVED_PP_FT +. \} +. FT \\*[$PP_FT] +. ps \\n[#DOC_PT_SIZE]u +. vs \\n[#DOC_LEAD]u +. QUAD \\*[$DOC_QUAD] +. \} +. \} +. ie \\n[#PP]=0 \{\ +. if \\n[#INDENT_FIRST_PARAS] \{\ +. ie \\n[#INDENT_ACTIVE] .ti \\n[#INDENT]u+\\n[#PP_INDENT]u +. el .ti \\n[#PP_INDENT]u +. if '\\n[.z]'END_NOTES' \ +. ti \\n[#EN_PP_INDENT]u+\\n[#EN_TEXT_INDENT]u +. \} +. if r #END_QUOTE \{\ +. if \\n[#END_QUOTE] \{\ +. if !\\n[#LINEBREAK] \{\ +. ie \\n[#INDENT_ACTIVE] .ti \\n[#INDENT]u+\\n[#PP_INDENT]u +. el .ti \\n[#PP_INDENT]u +. if '\\n[.z]'END_NOTES' \ +. ti \\n[#EN_PP_INDENT]u+\\n[#EN_TEXT_INDENT]u +. \} +. \} +. \} +. \} +. el \{\ +. if \\n[#PP_SPACE] \{\ +. ie \\n[#END_QUOTE] \{\ +. ie !'\\*[$PP_SPACE_AMOUNT]'' .sp \\*[$PP_SPACE_AMOUNT] +. el .sp +. rr #END_QUOTE +. nr #NO_SPACE 1 +. nr #BASELINE_MARK \\n[nl] +. \} +. el \{\ +. if \\n[#NO_SPACE]=1 .rr #NO_SPACE +. if \\n[post-float] \{\ +. if (\\n[.t]-1)<\\*[$PP_SPACE_AMOUNT] \{\ +. ie \\n[#COLS] .COL_NEXT +. el .NEWPAGE +. \} +. rr post-float +. \} +. if !\\n[nl]=\\n[#BASELINE_MARK] \{\ +. ie !'\\*[$PP_SPACE_AMOUNT]'' .sp \\*[$PP_SPACE_AMOUNT] +. el .sp +. rr #BASELINE_MARK +. \} +. \} +. \} +. if \\n[restore-pp-space] \{\ +. rr restore-pp-space +. PARA_SPACE +. \} +. ie \\n[#INDENT_ACTIVE] .ti \\n[#INDENT]u+\\n[#PP_INDENT]u +. el .ti \\n[#PP_INDENT]u +. if '\\n[.z]'END_NOTES' \ +. ti \\n[#EN_PP_INDENT]u+\\n[#EN_TEXT_INDENT]u +. \} +. if r #START .rr #START +. if r #QUOTE .rr #QUOTE +. if r #END_QUOTE .rr #END_QUOTE +. if r #HEAD .rr #HEAD +. if r #SUBHEAD .rr #SUBHEAD +. if r #EPIGRAPH .rr #EPIGRAPH +. if r #Q_FITS .rr #Q_FITS +. if r #LINEBREAK .rr #LINEBREAK +. if \\n[#ENDNOTE] \{\ +. ie \\n[#RESET_PARA_SPACE] .PARA_SPACE +. el .PARA_SPACE OFF +. \} +. if \\n[#CONDENSE] \{\ +\E*[COND]\c +. \} +. if \\n[#EXTEND]=1 \{\ +\E*[EXT]\c +. \} +. nr #PP +1 +. \} +. if \\n[#PP_STYLE]=2 \{\ +\!. br +. ie \\n[#Q_PP]=0 \{\ +. if \\n[#INDENT_FIRST_PARAS] \ +. ti \\n[#PP_INDENT]u/2u +. if \\n[#ENDNOTE] \{\ +. ie \\n[#INDENT_FIRSTS] .ti \\n[#PP_INDENT]u/2u +. el .ti 0 +. \} +. \} +. el \{\ +. ti \\n[#PP_INDENT]u/2u +. if \\n[#PP_SPACE]=1 \{\ +. ie !'\\*[$PP_SPACE_AMOUNT]'' .ALD \\*[$PP_SPACE_AMOUNT] +. el .sp +. \} +. \} +. if \\n[#CONDENSE] \{\ +\E*[COND]\c +. \} +. if \\n[#EXTEND]=1 \{\ +\E*[EXT]\c +. \} +. nr #Q_PP +1 +. \} +.\" This takes care of multi-paragraph dialogue, where each para +.\" is introduced by an open quote whereas the previous para has +.\" no close quote. +. if \\n[#OPEN_CLOSE]=1 .nr #OPEN_CLOSE 0 +. nr #PP_ACTIVE 1 +. UNDERLINE OFF +. if r #QUOTE_4_HD .rr #QUOTE_4_HD +. if r #LB_4_HD .rr #LB_4_HD +.END +\# +\# ==================================================================== +\# +\# +++QUOTES+++ +\# +\# ---Line for line quotes, e.g. poetry or code snippets--- +\# +\# UNDERLINE QUOTES +\# ---------------- +\# *Arguments: +\# | +\# *Function: +\# Creates or modifies register #UNDERLINE_QUOTES (toggle). +\# If on, line for line quotes are underlined when printstyle +\# is TYPEWRITE. +\# *Notes: +\# Default is ON for printstyle TYPEWRITE. +\# +.MAC UNDERLINE_QUOTES END +. ie '\\$1'' .nr #UNDERLINE_QUOTES 1 +. el .rr #UNDERLINE_QUOTES +.END +\# +\# QUOTE INDENT +\# ------------ +\# *Argument: +\# | +\# *Function: +\# Creates or modifies register #Q_OFFSET_VALUE or string +\# $Q_OFFSET_VALUE. +\# *Notes: +\# If just an integer given, value by which to multiply PARA_INDENT +\# to get quote indent. If integer with a unit of measure appended, +\# absolute value of quote indent. +\# +\# Default is 3 for typeset; 2 for typewrite. +\# +.MAC QUOTE_INDENT END +. if '\\$0'BLOCKQUOTE_INDENT' .ds BQ BQ +. if '\\$0'QUOTE_INDENT' .ds BQ Q +. rr #\\*[BQ]_OFFSET_VALUE +. rm $\\*[BQ]_OFFSET_VALUE +. ds $EVAL_QI_ARG \\$1 +. substring $EVAL_QI_ARG -1 +. ie \B'\\*[$EVAL_QI_ARG]' .nr #\\*[BQ]_OFFSET_VALUE \\$1 +. el .ds $\\*[BQ]_OFFSET_VALUE \\$1 +. rm BQ +.END +. +.ALIAS BLOCKQUOTE_INDENT QUOTE_INDENT +\# +\# QUOTE_AUTOLEAD +\# -------------- +\# *Arguments: +\# +\# *Function: +\# Sets autolead for quotes and/or blockquotes. +\# +.MAC QUOTE_AUTOLEAD END +. rr #\\$0_DEFAULT +. if '\\$0'QUOTE_AUTOLEAD' .nr #Q_AUTOLEAD (p;\\$1) +. if '\\$0'BLOCKQUOTE_AUTOLEAD' .nr #BQ_AUTOLEAD (p;\\$1) +. if '\\$0'ENDNOTE_QUOTE_AUTOLEAD' .nr #EN_Q_AUTOLEAD (p;\\$1) +. if '\\$0'ENDNOTE_BLOCKQUOTE_AUTOLEAD' .nr #EN_BQ_AUTOLEAD (p;\\$1) +.END +. +.ALIAS BLOCKQUOTE_AUTOLEAD QUOTE_AUTOLEAD +.ALIAS ENDNOTE_QUOTE_AUTOLEAD QUOTE_AUTOLEAD +.ALIAS ENDNOTE_BLOCKQUOTE_AUTOLEAD QUOTE_AUTOLEAD +\# +\# ALWAYS FULLSPACE QUOTES +\# ----------------------- +\# *Arguments: +\# | +\# *Function: +\# Toggles register #FULLSPACE_QUOTES. +\# *Notes: +\# If user doesn't like the default 1/2 line space above and below +\# quotes, s/he can turn it off here. Has no effect in TYPEWRITE. +\# +.MAC ALWAYS_FULLSPACE_QUOTES END +. if '\\$1'' .nr #FULLSPACE_QUOTES 1 +. el .rr #FULLSPACE_QUOTES +.END +\# +\# QUOTE +\# ----- +\# *Arguments: +\# | +\# *Function: +\# Indents quoted text on a line for line basis, or turns QUOTE off. +\# *Notes: +\# Owing to the need to bottom align TYPESET pages, quoted text gets +\# diverted so its depth can be measured (in DO_QUOTE) for determining +\# how much space to put before and after. +\# +.MAC QUOTE END +. ie \\n[@TOP] \ +. br +. el 'br +. if \\n[#PP]>0 .rr #START +. if '\\n[.z]'FLOAT*DIV' .nr Q-float 1 +. if \\n[#LINENUMBERS]=1 \{\ +. nr #LINENUMBERS 2 +. nr #NEXT_LN \\n[ln] +. nm +. \} +. if '\\$1'ADJUST' \{\ +. ds $Q_SPACE_ADJUST \\$2 +. shift 2 +. \} +. ie '\\$1'' \{\ +. ev QUOTE +. evc 0 +. if \\n[.i] .in 0 +. if \\n[#LINENUMBERS]=2 \ +. if \\n[#SILENT_QUOTE_LN]=1 .nm \\n[#NEXT_LN] 1000 -4 +. nr #IN_DIVER 1 +. nr #QUOTE 1 +. di P_QUOTE +. if '\\*[$Q_QUAD]'RIGHT' \{\ +. ie !'\\*[$Q_OFFSET_VALUE]'' .ll \\n[#L_LENGTH]u-\\*[$Q_OFFSET_VALUE] +. el .ll \\n[#L_LENGTH]u-(\\n[#PP_INDENT]u*\\n[#Q_OFFSET_VALUE]u) +. \} +. ta \\n[.l]u +. if \\n[#COLUMNS] \{\ +. ie \\n[#Q_OFFSET_VALUE] \ +. ll \\n[#COL_L_LENGTH]u-(\\n[#PP_INDENT]u*\\n[#Q_OFFSET_VALUE]u) +. el .ll \\n[#COL_L_LENGTH]u-\\*[$Q_OFFSET_VALUE] +. ta \\n[.l]u +. \} +. if \\n[#PRINT_STYLE]=1 \{\ +. TYPEWRITER +. vs \\n[#DOC_LEAD]u +. LEFT +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. FAMILY \\*[$QUOTE_FAM] +. FT \\*[$QUOTE_FT] +. ps \\n[#DOC_PT_SIZE]u\\*[$QUOTE_SIZE_CHANGE] +. ie !r #Q_AUTOLEAD .vs \\n[#DOC_LEAD]u +. el \{\ +. vs \\n[.ps]u+\\n[#Q_AUTOLEAD]u +. nr #Q_LEAD \\n[.v] +. \} +. if \\n[#ENDNOTE] \{\ +. ps \\n[#EN_PS]u\\*[$QUOTE_SIZE_CHANGE] +. ie !r #EN_Q_AUTOLEAD .vs \\n[#EN_Q_LEAD]u +. el \{\ +. vs \\n[.ps]u+\\n[#EN_Q_AUTOLEAD]u +. nr #EN_Q_LEAD \\n[.v] +. \} +. \} +. nr #Q_LEAD_REAL \\n[.v] +. if \\n[#QUOTE_COLOR]=1 \{\ +. nf +. COLOR \\*[$QUOTE_COLOR] +. \} +. \\*[$Q_QUAD] +. \} +. if \\n[#LINENUMBERS]=2 \{\ +. ie \\n[#QUOTE_LN]=1 \{\ +. if '\\n[#Q_LN_GUTTER]'' .nr #Q_LN_GUTTER \\n[#LN_GUTTER] +. LN_PARAMS +. nm \\n[ln] "" \\n[#Q_LN_GUTTER] -3-\\n[#Q_LN_GUTTER] +. RESTORE_PARAMS +. \} +. el \ +. if !\\n[#SILENT_QUOTE_LN] .NUMBER_LINES OFF +. \} +. nr #Q_TOP \\n[nl] +. if \\n[#PRINT_STYLE]=1 \ +. if \\n[#UNDERLINE_QUOTES] .FT I +. \} +. el .DO_QUOTE +.END +\# +\# CODE +\# ---- +\# *Arguments: +\# [ BR | BREAK | SPREAD ] +\# or +\# [ BR | BREAK | SPREAD ] +\# *Function: +\# Takes care of administrivia associated with setting code snippets. +\# +.MAC CODE END +\c +. if '\\$1'BR' \{\ +. ie '\\n[.z]'FLOAT*DIV' 'br +. el .br +. shift +. \} +. if '\\$1'BREAK' \{\ +. ie '\\n[.z]'FLOAT*DIV' 'br +. el .br +. shift +. \} +. if '\\$1'SPREAD' \{\ +. ie '\\n[.z]'FLOAT*DIV' 'brp +. el .brp +. shift +. \} +. ie '\\$1'' \{\ +. ds $RESTORE_FAM \\n[.fam] +. ds $RESTORE_FT \\n[.sty] +. ie \\n[#PRINT_STYLE]=1 \{\ +. CODE_FAMILY C +. ie \\n[#CODE_FT]=1 .ft \\*[$CODE_FT] +. el \{\ +. CODE_FONT R +. ft R +. char ' \[aq] +. \} +. if \\n[#UNDERLINE_QUOTES]=1 \{\ +. nr #RESTORE_UNDERLINE 1 +. UNDERLINE_QUOTES OFF +. FT \\*[$CODE_FT] +. char ' \[aq] +. \} +. \} +. el \{\ +. ie \\n[#CODE_FAM]=1 .fam \\*[$CODE_FAM] +. el \{\ +. CODE_FAMILY C +. fam \\*[$CODE_FAM] +. \} +. ie \\n[#CODE_FT]=1 .ft \\*[$CODE_FT] +. el \{\ +. CODE_FONT R +. ft \\*[$CODE_FT] +. \} +. if \\n[#CODE_COLOR]=1 .COLOR \\*[$CODE_COLOR] +. char ' \[aq] +. if !\\n[#CODE_SIZE_ADJ]=0 \{\ +. ds $RESTORE_SIZE \\n[.s] +. ps \\n[#PT_SIZE]u*\\n[#CODE_SIZE_ADJ]u/100u +. \} +. if \\n[#SQ_ON] \{\ +. nr #SQ_WAS_ON 1 +. SMARTQUOTES OFF +. \} +. \} +. \} +. el \{\ +. fam \\*[$RESTORE_FAM] +. ft \\*[$RESTORE_FT] +. if !\\n[#CODE_SIZE_ADJ]=0 .ps \\*[$RESTORE_SIZE] +. rm $RESTORE_FAM +. rm $RESTORE_FT +. rm $RESTORE_SIZE +. if \\n[#PRINT_STYLE]=2 .char ' \[cq] +. if !'\\n[.z]'' \ +. if \\n[#LINENUMBERS] .nn +. if \\n[#CODE_COLOR]=1 .gcolor +. if \\n[#RESTORE_UNDERLINE]=1 \{\ +. rr #RESTORE_UNDERLINE +. UNDERLINE_QUOTES +. \} +. if \\n[#SQ_WAS_ON]=1 \{\ +. rr #SQ_WAS_ON +. SMARTQUOTES +. \} +. if \\n[#QUOTE] .sp -1 +. if \\n[pdfbx-end] .if !\\n[#QUOTE] .sp -1 +. \} +.END +\# +\# ---Blockquotes--- +\# +\# BLOCKQUOTE +\# ---------- +\# *Arguments: +\# | +\# *Function: +\# Indents quoted text in fill mode and shortens line length +\# equivalently, or turns BLOCKQUOTE off. +\# *Notes: +\# Owing to the need to bottom align TYPESET pages, quoted text gets +\# diverted so its depth can be measured (in DO_QUOTE) for determining +\# how much space to put before and after. +\# +\# .PP after blockquote is optional if there's only one para, +\# but required if there's more than one. +\# +.MAC BLOCKQUOTE END +. ie \\n[@TOP] \ +. br +. el 'br +. if \\n[#PP]>0 .rr #START +. if '\\n[.z]'FLOAT*DIV' .nr Q-float 1 +. if \\n[#LINENUMBERS]=1 \{\ +. nr #LINENUMBERS 2 +. nr #NEXT_LN \\n[ln] +. nm +. \} +. if '\\$1'ADJUST' \{\ +. ds $BQ_SPACE_ADJUST \\$2 +. shift 2 +. \} +. ie '\\$1'' \{\ +. ev BLOCKQUOTE +. evc 0 +. if \\n[.i] .in 0 +. if \\n[#LINENUMBERS]=2 \ +. if \\n[#SILENT_BQUOTE_LN]=1 .nm \\n[#NEXT_LN] 1000 -4 +. nr #IN_DIVER 1 +. nr #QUOTE 2 +. nr #PP_STYLE 2 +. nr #Q_PP 0 +. di B_QUOTE +. ie !'\\*[$BQ_OFFSET_VALUE]'' .ll \\n[#L_LENGTH]u-(\\*[$BQ_OFFSET_VALUE]*2u) +. el .ll \\n[#L_LENGTH]u-(\\n[#PP_INDENT]u*(\\n[#BQ_OFFSET_VALUE]u*2u)) +. if \\n[#ENDNOTE] \{\ +. if \\n[#EN_NUMBERS_ALIGN_RIGHT] \{\ +. ie r#BQ_OFFSET_VALUE \ +. ll \ +\\n[#RESET_L_LENGTH]u-\\n[#EN_TEXT_INDENT]u-(\\n[#EN_PP_INDENT]u*(\\n[#BQ_OFFSET_VALUE]u*2u)) +. el \ +. ll \ +\\n[#RESET_L_LENGTH]u-\\n[#EN_TEXT_INDENT]u-(\\*[$BQ_OFFSET_VALUE]*2u) +. \} +. if \\n[#EN_NUMBERS_ALIGN_LEFT] \{\ +. ie r#BQ_OFFSET_VALUE \ +. ll \\n[#L_LENGTH]u-(\\n[#EN_PP_INDENT]u*(\\n[#BQ_OFFSET_VALUE]u*2u)) +. el \ +. ll \\n[#L_LENGTH]u-(\\*[$BQ_OFFSET_VALUE]u*2u) +. \} +. \} +. ta \\n[.l]u +. CHECK_INDENT +. if \\n[#COLUMNS] \{\ +. ie r#BQ_OFFSET_VALUE \ +. ll \ +\\n[#COL_L_LENGTH]u-(\\n[#PP_INDENT]u*(\\n[#BQ_OFFSET_VALUE]u*2u)) +. el \ +. ll \\n[#COL_L_LENGTH]u-(\\*[$BQ_OFFSET_VALUE]*2u) +. if \\n[#ENDNOTE] \{\ +. if \\n[#EN_NUMBERS_ALIGN_RIGHT] \{\ +. ie r#BQ_OFFSET_VALUE \ +. ll \ +\\n[#RESET_L_LENGTH]u-\\n[#EN_TEXT_INDENT]u-(\\n[#EN_PP_INDENT]u*(\\n[#BQ_OFFSET_VALUE]u*2u)) +. el \ +. ll \ +\\n[#RESET_L_LENGTH]u-\\n[#EN_TEXT_INDENT]u-(\\*[$BQ_OFFSET_VALUE]*2u) +. \} +. if \\n[#EN_NUMBERS_ALIGN_LEFT] \{\ +. ie r#BQ_OFFSET_VALUE \ +. ll \ +\\n[#COL_L_LENGTH]u-(\\n[#EN_PP_INDENT]u*(\\n[#BQ_OFFSET_VALUE]u*2u)) +. el \ +. ll \\n[#COL_L_LENGTH]u-(\\*[$BQ_OFFSET_VALUE]*2u) +. \} +. \} +. ta \\n[.l]u +. \} +. if \\n[#PRINT_STYLE]=1 \{\ +. TYPEWRITER +. vs \\n[#DOC_LEAD]u +. QUAD LEFT +. HY OFF +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. FAMILY \\*[$BQUOTE_FAM] +. FT \\*[$BQUOTE_FT] +. ps \\n[#DOC_PT_SIZE]u\\*[$BQUOTE_SIZE_CHANGE] +. ie !r #BQ_AUTOLEAD .vs \\n[#DOC_LEAD]u +. el \{\ +. vs \\n[.ps]u+\\n[#BQ_AUTOLEAD]u +. nr #BQ_LEAD \\n[.v] +. \} +. if \\n[#ENDNOTE] \{\ +. ps \\n[#EN_PS]u\\*[$BQUOTE_SIZE_CHANGE] +. ie !r#EN_BQ_AUTOLEAD .vs \\n[#EN_BQ_LEAD]u +. el \{\ +. vs \\n[.ps]u+\\n[#EN_BQ_AUTOLEAD]u +. nr #EN_BQ_LEAD \\n[.v] +. \} +. \} +. nr #BQ_LEAD_REAL \\n[.v] +. if \\n[#BQUOTE_COLOR]=1 \{\ +. nf +. COLOR \\*[$BQUOTE_COLOR] +. \} +. QUAD \\*[$BQUOTE_QUAD] +. nr #DIVERSIONS_HY_MARGIN (p;\\n[.ps]u*2.75)/1000 +. HY_SET 1 \\n[#DIVERSIONS_HY_MARGIN]u (\\n[#PT_SIZE]u/1000u/8u)p +. hy 14 +. \} +. if \\n[#LINENUMBERS]=2 \{\ +. ie \\n[#BQUOTE_LN]=1 \{\ +. if '\\n[#BQ_LN_GUTTER]'' .nr #BQ_LN_GUTTER \\n[#LN_GUTTER] +. LN_PARAMS +. nm \\n[ln] "" \\n[#BQ_LN_GUTTER] -3-\\n[#BQ_LN_GUTTER] +. RESTORE_PARAMS +. \} +. el \ +. if !\\n[#SILENT_BQUOTE_LN] .NUMBER_LINES OFF +. \} +. nr #Q_TOP \\n[nl] +. if \\n[#INDENT_FIRST_PARAS] \{\ +. ie !\\n[#ENDNOTE] \{\ +. if \\n[#PRINT_STYLE]=1 .ti \\n[#PP_INDENT]u/2u +. if \\n[#PRINT_STYLE]=2 .ti \\n[#PP_INDENT]u/2u +. \} +. el \{\ +. if \\n[#INDENT_FIRSTS]=1 \{\ +. if \\n[#PRINT_STYLE]=1 .ti \\n[#EN_PP_INDENT]u/2u +. if \\n[#PRINT_STYLE]=2 .ti \\n[#EN_PP_INDENT]u/2u +. \} +. \} +. \} +. \} +. el .DO_BLOCKQUOTE +.END +\# +\# DO QUOTE +\# -------- +\# *Arguments: +\# +\# *Function: +\# Ends the diversion P_QUOTE or B_QUOTE. Spaces them according to +\# PRINTSTYLE, whether there's inter-paragraph spacing, and page +\# position. TYPEWRITE treats spacing the same way in all circumstance +\# (viz. an extra line space). TYPESET puts in only half +\# line spaces if the entire quote plus 1 line of body under the quote +\# fits on the page; otherwise it puts in a full extra blank +\# line. (This is to ensure the page remains bottom aligned). +\# +.MAC DO_QUOTE END +. br +. if \\n[#DIVER_LN_OFF] \{\ +\!. NUMBER_LINES OFF +. rr #DIVER_LN_OFF +. \} +. nr #Q_DEPTH \\n[.d] +. di +. if '\\$0'DO_BLOCKQUOTE' .ds BQ BQ +. if '\\$0'DO_QUOTE' .ds BQ Q +. rr #IN_DIVER +. if \\n[#RESET_FN_COUNTERS]=2 \{\ +. if !\\n[#FN_COUNT]=1 \{\ +. if ((\\n[#PAGE_LENGTH]+\\n[#VARIABLE_FOOTER_POS])+\\n[#DIVER_DEPTH])>(\\n[#PAGE_LENGTH]+\\n[#VARIABLE_FOOTER_POS]) \{\ +. DIVER_FN_2_POST +. rr #RESET_FN_COUNTERS +. \} +. \} +. \} +. nr #SAVED_FN_NUMBER \\n[#FN_NUMBER] +. nr #DONE_ONCE 0 1 +. REMOVE_INDENT +. ev +. nr #Q_LEAD_DIFF \\n[#LEAD]-\\n[#\\*[BQ]_LEAD_REAL] +. nr q-lead-diff \\n[#Q_LEAD_DIFF] +. if !\\n[pdfbx-running] \{\ +. if !'\\n[.z]'FLOAT*DIV' \{\ +. br +. nr #CALCULATE_ONLY 1 +. nr #CURRENT_V_POS \\n[nl]+\\n[#Q_DEPTH] +. SHIM +. rr #CALCULATE_ONLY +. nr #Q_SPACE_EQ (\\n[#SHIM]/2) +. nr #TRAP \\n[.t]-1 +. \} +. \} +. if \\n[#ENDNOTE] \{\ +. nr #RESET_QUOTE_SPACING \\n[#FULLSPACE_QUOTES] +. ALWAYS_FULLSPACE_QUOTES +. \} +. if \\n[#PRINT_STYLE]=1 \{\ +. if \\n[#START]=1 . +. if \\n[#START]=0 \ +. if !\\n[#LINEBREAK] .ALD \\n[#DOC_LEAD]u +. if \\n[#HEAD] \ +. if \\n[#HEAD]=1 .RLD \\n[#DOC_LEAD]u +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. ie \\n[#PP_SPACE] \{\ +. ie \\n[#HEAD] . +. el \{\ +. ie \\n[#START] . +. el \{\ +. ie \\n[#FULLSPACE_QUOTES] .ALD \\n[#DOC_LEAD]u +. el .ALD \\n[#DOC_LEAD]u/2u +. \} +. \} +. \} +. el \{\ +. if !\\n[nl]=\\n[#PAGE_TOP] \{\ +. ie \\n[#Q_DEPTH]<(\\n[#TRAP_DISTANCE]-1) \{\ +. ie ((\\n[#TRAP_DISTANCE]-1)-\\n[#Q_DEPTH])<\\n[#DOC_LEAD] \ +. Q_NOFIT +. el \{\ +. ie (\\n[#TRAP_DISTANCE]-\\n[#DOC_LEAD])<\\n[#DOC_LEAD] \ +. Q_NOFIT +. el \{\ +. ie (\\n[#Q_DEPTH]+\\n[.v])=(\\n[#TRAP_DISTANCE]-1) \ +. Q_NOFIT +. el .Q_FITS +. \} +. \} +. \} +. el .Q_NOFIT +. \} +. \} +. if \\n[#LINEBREAK] \{\ +. vpt 0 +. ie !\\n[@TOP] .sp -\\n[#DOC_LEAD]u +. el \{\ +. nop +. sp |\\n[#T_MARGIN]u-\\n[#BQ_LEAD]u +. \} +. vpt +. \} +. \} +. ie !'\\*[$\\*[BQ]_OFFSET_VALUE]'' \ +. nr #\\*[BQ]_OFFSET \\n[#L_MARGIN]+(\\*[$\\*[BQ]_OFFSET_VALUE]) +. el \ +. nr #\\*[BQ]_OFFSET \ +\\n[#L_MARGIN]+(\\n[#PP_INDENT]*\\n[#\\*[BQ]_OFFSET_VALUE]) +. if \\n[#COLUMNS] \{\ +. ie r#\\*[BQ]_OFFSET_VALUE \ +. nr #\\*[BQ]_OFFSET \ +\\n[#COL_\\n[#COL_NUM]_L_MARGIN]+(\\n[#PP_INDENT]*\\n[#\\*[BQ]_OFFSET_VALUE]) +. el .nr #\\*[BQ]_OFFSET \ +\\n[#COL_\\n[#COL_NUM]_L_MARGIN]+\\*[$\\*[BQ]_OFFSET_VALUE] +. \} +. if !\\n[#ENDNOTE] \{\ +. ie '\\*[BQ]'Q' \{\ +. if '\\*[$Q_QUAD]'LEFT' \{\ +. po \\n[#Q_OFFSET]u +. if '\\n[.z]'FLOAT*DIV' \!.po \\n[#Q_OFFSET]u +. \} +. \} +. el \{\ +. po \\n[#\\*[BQ]_OFFSET]u +. if '\\n[.z]'FLOAT*DIV' \!.po \\n[#\\*[BQ]_OFFSET]u +. \} +. \} +. if \\n[#ENDNOTE] \{\ +. ie \\n[#\\*[BQ]_OFFSET_VALUE] \ +. in +\\n[#EN_PP_INDENT]u*\\n[#\\*[BQ]_OFFSET_VALUE]u +. el .in +\\*[$\\*[BQ]_OFFSET_VALUE] +. \} +. ie \\n[#START]=1 \ +. RLD 0-\\n[#Q_LEAD_DIFF]u +. el \{\ +. if \\n[#PRINT_STYLE]=2 \{\ +. ie !\\n[pdfbx-post-q] \{\ +. ie !\\n[#NO_SHIM] \ +. sp \\n[#Q_SPACE_EQ]u+(\\n[#Q_LEAD_DIFF]u/2u) +. el .if !\\n[#NO_FLEX] .FLEX +. \} +. el .sp -.5 +. \} +. \} +. if \\n[#QUOTE]=1 \{\ +. if !'\\*[$Q_SPACE_ADJUST]'' .sp +\\*[$Q_SPACE_ADJUST] +. nf +. P_QUOTE +. if !'\\*[$Q_SPACE_ADJUST]'' \{\ +. sp -\\*[$Q_SPACE_ADJUST] +. rm $Q_SPACE_ADJUST +. \} +. \} +. if \\n[#QUOTE]=2 \{\ +. if !'\\*[$BQ_SPACE_ADJUST]'' .sp +\\*[$BQ_SPACE_ADJUST] +. nf +. B_QUOTE +. if !'\\*[$BQ_SPACE_ADJUST]'' \{\ +. sp -\\*[$BQ_SPACE_ADJUST] +. rm $BQ_SPACE_ADJUST +. \} +. \} +. if !\\n[#START] .rr #QUOTE +. rr delay-ev-pop +. if !'\\n[.z]'FLOAT*DIV' \{\ +. if \\n[#PRINT_STYLE]=1 \{\ +. if !\\n[.v]=\\n[#DOC_LEAD] \{\ +. if !r pdfbx-post-q \{\ +. ie !\\n[#NO_SHIM] .SHIM +. el \ +. if !\\n[#NO_FLEX] .FLEX +. \} +. \} +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. ie \\n[#START] \{\ +. ie \\n[#PP_SPACE] . +. el \{\ +. sp \\n[#DOC_LEAD]u/2u +. if !r pdfbx-post-q \{\ +. ie !\\n[#NO_SHIM] .SHIM +. el \ +. if !\\n[#NO_FLEX] .FLEX +. \} +. \} +. \} +. el \{\ +. ie \\n[#HEAD]=1 \{\ +. sp \\n[#DOC_LEAD]u +. if !r pdfbx-post-q \{\ +. ie !\\n[#NO_SHIM] .SHIM +. el \ +. if !\\n[#NO_FLEX] .FLEX +. \} +. \} +. el \{\ +. ie \\n[#FULLSPACE_QUOTES] \{\ +. ie \\n[#ENDNOTE] .ALD \\n[#EN_LEAD]u +. el .if !'\\n[.z]'FLOAT*DIV' .ALD \\n[#DOC_LEAD]u +. \} +. el \ +. if !'\\n[.z]'FLOAT*DIV' .ALD \\n[#DOC_LEAD]u/2u +. ie \\n[#Q_FITS] \{\ +. ie (\\n[#Q_TOP]=\\n[#PAGE_TOP]):(\\n[@TOP]=1) \{\ +. if \\n[has-label] .sp \\n[#DOC_LEAD]u/2u +. if !'\\n[.z]'FLOAT*DIV' \{\ +. nr #Q_AT_TOP 1 +. nr #DELAY_SHIM 1 +. \} +. \} +. el \{\ +. ie !\\n[#NO_SHIM] .SHIM +. el .if !\\n[#NO_FLEX] .FLEX +. \} +. \} +. el \{\ +. ie r pdfbx-post-q \{\ +. if \\n[.t]>1v \{\ +. ie !\\n[#NO_SHIM] .SHIM +. el \ +. if !\\n[#NO_FLEX] .FLEX +. \} +. \} +. el \{\ +. ie !\\n[#NO_SHIM] .SHIM +. el \ +. if !\\n[#NO_FLEX] .FLEX +. \} +.\" Make sure that Q_LEAD_DIFF is not added to the first line of +.\" normal text at the top of any page following output of a quote +.\" whose last line falls on B_MARGIN of the previous page. +. if \\n[#Q_LEAD_DIFF] \{\ +. if \\n[nl]=(\\n[#T_MARGIN]-\\n[#DOC_LEAD]+\\n[#Q_LEAD_DIFF]) \{\ +. PRINT \& +. br +. sp -1v-\\n[#Q_LEAD_DIFF]u +. nr #Q_LEAD_DIFF_CHECK 1 +. \} +. \} +. \} +. \} +. \} +. \} +. \} +. if \\n[#RESTORE_NO_SHIM] .nr #NO_SHIM 1 +. rr #Q_SPACE_EQ +. if \\n[#LINENUMBERS]=2 \{\ +. nr #LINENUMBERS 1 +. if !\\n[#ENDNOTE] \{\ +. ie \\n[#RESTORE_LN_NUM]=1 \{\ +. LN_PARAMS +. nm \\n[#NEXT_LN] +. RESTORE_PARAMS +. \} +. el \{\ +. LN_PARAMS +. nm +0 +. RESTORE_PARAMS +. \} +. \} +. \} +. if \\n[#ENDNOTE] \ +. nr #FULLSPACE_QUOTES \\n[#RESET_QUOTE_SPACING] +. if r #HEAD .rr #HEAD +. if r #EPIGRAPH .rr #EPIGRAPH +. rr #Q_PP +. rr #LINEBREAK +. nr #PP_STYLE 1 +. nr #END_QUOTE 1 +. if !\\n[#ENDNOTE] \ +. po \\n[#L_MARGIN]u +. if \\n[#ENDNOTE] .in \\n[#EN_TEXT_INDENT]u +. if \\n[#COLUMNS] \{\ +. if !\\n[#ENDNOTE] \{\ +. po \\n[#COL_\\n[#COL_NUM]_L_MARGIN]u +. nr #L_MARGIN \\n[.o] +. \} +. if \\n[#ENDNOTE] .in \\n[#EN_TEXT_INDENT]u +. \} +. ie !\\n[#ENDNOTE] .QUAD \\*[$DOC_QUAD] +. el .QUAD \\*[EN_QUAD] +. if r #DELAY_SHIM \{\ +. ie !\\n[#NO_SHIM] .SHIM +. el \ +. if !\\n[#NO_FLEX] .FLEX +. rr #DELAY_SHIM +. \} +. if \\n[#PRINT_STYLE]=1 \ +. if \\n[#UNDERLINE_QUOTES] .FT R +. nr #QUOTE_4_HD 1 +. rr #\\*[BQ]_LEAD_REAL +. rm BQ +. if \\n[#DOC_TYPE]=5 .NO_SHIM +. if '\\n[.z]'FLOAT*DIV' \!.po \\n[#L_MARGIN]u +.END +. +.ALIAS DO_BLOCKQUOTE DO_QUOTE +\# +\# Utility macros for DO_QUOTE +\# --------------------------- +\# +.MAC Q_FITS END +. nr #Q_FITS 1 +. ie \\n[#HEAD]=1 .ALD \\n[#Q_LEAD_DIFF]u +. el \{\ +. ie \\n[#START] . +. el \{\ +. ie \\n[#FULLSPACE_QUOTES] \{\ +. ie \\n[#ENDNOTE] .ALD \\n[#EN_LEAD]u+\\n[#Q_LEAD_DIFF]u +. el .ALD \\n[#DOC_LEAD]u+\\n[#Q_LEAD_DIFF]u +. \} +. el \{\ +.\" This seems to be the only way to get the baseline of quotes that +.\" start at the top of the page to fall on the first line of the +.\" grid (ie. on the first valid baseline of the page). +. ie \\n[#Q_TOP]=\\n[#PAGE_TOP] \{\ +. if \\n[#QUOTE]=1 .ds $QUOTE_TYPE Q +. if \\n[#QUOTE]=2 .ds $QUOTE_TYPE B +. rn \\*[$QUOTE_TYPE]_QUOTE Q_TEMP +. di \\*[$QUOTE_TYPE]_QUOTE +. nf +. if \\n[#QUOTE]=1 .vs \\n[#Q_LEAD]u +. if \\n[#QUOTE]=2 .vs \\n[#BQ_LEAD]u +. PRINT \& +. sp -1v+\\n[#Q_LEAD_DIFF]u +. Q_TEMP +. di +. rm Q_TEMP +. sp \\n[#DOC_LEAD]u/2u +. \} +. el \ +. sp \\n[#DOC_LEAD]u/2u +. \} +. \} +. if \\n[#DIVER_FN]=2 .rr #DIVER_FN +. if !\\n[#NO_FLEX] .FLEX +. \} +. rm $QUOTE_TYPE +.END +\# +.MAC Q_NOFIT END +. rr #Q_FITS +. if \\n[#QUOTE]=1 \{\ +. ds $QUOTE_TYPE Q +. ds quote-type quote +. \} +. if \\n[#QUOTE]=2 \{\ +. ds $QUOTE_TYPE B +. ds quote-type blockquote +. \} +. if \\n[has-caption] \{\ +. if !\\n[@TOP] \ +. if !\\n[nl]=\\n[#PAGE_TOP] \ +. if (\\n[.t]-1)<\ +\\n[#DOC_LEAD]+(\\n[#DOC_LEAD]/4)\ ++\\n[#\\*[QUOTE_TYPE]_LEAD] \{\ +. tm1 "[mom]: Insufficient room for caption and at least one line of \\*[quote-type] +. tm1 " on page \\n[%] (line \\n[.c]). Moving quote to next page or column. +. ie \\n[#COLUMNS] .COL_NEXT +. el .NEWPAGE +. \} +. \} +. ie r#HEAD \ +. if \\n[#HEAD]=1 . +. el \{\ +. if \\n[#Q_DEPTH]=0 \ +. if \\n[.ns] .rs +. ie \\n[#FULLSPACE_QUOTES] \{\ +. ie \\n[#ENDNOTE] .sp \\n[#EN_LEAD]u+\\n[#Q_LEAD_DIFF]u +. el .sp \\n[#DOC_LEAD]u+\\n[#Q_LEAD_DIFF]u +. \} +. el \{\ +. sp .5 +. if \\n[@TOP] .rs +. \} +. ie \\n[#Q_LEAD_REAL] \ +. nr #Q_PARTIAL_DEPTH 0 \\n[#Q_LEAD_REAL] +. el .nr #Q_PARTIAL_DEPTH 0 \\n[#BQ_LEAD_REAL] +. while \\n+[#Q_PARTIAL_DEPTH]<(\\n[#TRAP_DISTANCE]-1) \{\ +. +. \} +. if !\\n[#Q_LEAD_REAL]=\\n[#DOC_LEAD] \{\ +. ie \\n[#Q_LEAD_REAL] \ +. nr #Q_PARTIAL_DEPTH -\\n[#Q_LEAD_REAL] +. el .nr #Q_PARTIAL_DEPTH -\\n[#BQ_LEAD_REAL] +. \} +. nr #Q_SPACE_EQ \ +(\\n[#TRAP_DISTANCE]-1)-\\n[#Q_PARTIAL_DEPTH]+(\\n[#Q_LEAD_DIFF]u/2u) +. if \\n[#FN_COUNT]>0 .nr #Q_SPACE_EQ (\\n[#Q_SPACE_EQ] / 2u) +.\" Hack to deal with the fact that even though the above routine +.\" makes the bottom line of the quote fall exactly on the bottom +.\" margin when traps are disabled, it refuses to do so when traps +.\" are on. The difference by which it's off is #Q_LEAD_DIFF +.\" (the +\\n[#Q_LEAD_DIFF] at the end of the line, above). Hack +.\" solution: temporarily lower the FOOTER trap position. +. if !\\n[pdfbx-running] \{\ +. if !\\n[#Q_DEPTH]=0 \{\ +. nr #SAVED_FOOTER_POS \\n[#VARIABLE_FOOTER_POS] +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u+.25v +. \} +. \} +.\} +.END +\# +\# ==================================================================== +\# +\# +++PAGINATION+++ +\# +\# PAGINATE +\# -------- +\# *Arguments: +\# | +\# *Function: +\# Turns page numbering off or on during document processing. +\# *Notes: +\# Default is on. +\# +.MAC PAGINATE END +. ie '\\$1'' \{\ +. nr #PAGINATE 1 +. if \\n[#SAVED_V_POS] \{\ +. nr #PAGE_NUM_V_POS \\n[#SAVED_V_POS] +. rr #SAVED_V_POS +. \} +. \} +. el \{\ +. nr #PAGINATE 0 +. nr #SAVED_V_POS \\n[#PAGE_NUM_V_POS] +. rr #PAGE_NUM_V_POS +. \} +. if \\n[#HF_OFF]=1 \{\ +. rr #PAGINATION_STATE +. rr #HF_OFF +. \} +.END +\# +\# SUSPEND PAGINATION (before ENDNOTES) +\# ------------------ +\# *Argument: +\# +\# *Function: +\# Creates register #SUSPEND_PAGINATION +\# *Notes: +\# Useful only to suspend pagination before outputting endnotes. +\# +.MAC SUSPEND_PAGINATION END +. nr #SUSPEND_PAGINATION 1 +.END +\# +\# RESTORE PAGINATION (after ENDNOTES) +\# ------------------ +\# *Argument: +\# +\# *Function: +\# Removes register #SUSPEND_PAGINATION. Creates register +\# #DEFER_PAGINATION +\# *Notes: +\# Useful only to restore pagination after outputting endnotes. +\# +.MAC RESTORE_PAGINATION END +. rr #SUSPEND_PAGINATION +. if \\n[#PAGE_NUM_V_POS]=1 .PAGINATE +. if \\n[#PAGE_NUM_V_POS]=2 .nr #DEFER_PAGINATION 1 +.END +\# +\# PAGE NUMBER FORMAT +\# ------------------ +\# *Arguments: +\# DIGIT | ROMAN | roman | ALPHA | alpha +\# *Function: +\# Assigns user entered format to #PAGENUMBER. +\# +.MAC PAGENUM_STYLE END +. nr #PAGENUM_STYLE_SET 1 +. if '\\$1'DIGIT' \{\ +. ds $PAGENUM_STYLE \\$1 +. af #PAGENUMBER 1 +. \} +. if '\\$1'ROMAN' \{\ +. ds $PAGENUM_STYLE \\$1 +. af #PAGENUMBER I +. \} +. if '\\$1'roman' \{\ +. ds $PAGENUM_STYLE \\$1 +. af #PAGENUMBER i +. \} +. if '\\$1'ALPHA' \{\ +. ds $PAGENUM_STYLE \\$1 +. af #PAGENUMBER A +. \} +. if '\\$1'alpha' \{\ +. ds $PAGENUM_STYLE \\$1 +. af #PAGENUMBER a +. \} +.END +\# +\# HYPHENS AROUND PAGE NUMBERS +\# --------------------------- +\# *Arguments: +\# | +\# *Function: +\# Creates or modifies register #PAGE_NUM_HYPHENS. +\# Used to dis/enable hyphens on either side of page numbers. +\# *Notes: +\# Default is on. +\# +.MAC PAGENUM_HYPHENS END +. nr #PAGE_NUM_HYPHENS_SET 1 +. ie '\\$1'' .nr #PAGE_NUM_HYPHENS 1 +. el .rr #PAGE_NUM_HYPHENS +.END +\# +\# PAGENUMBER POSITION +\# ------------------- +\# *Arguments: +\# TOP | BOTTOM LEFT | CENTER | RIGHT +\# *Function: +\# Creates or modifies various PAGE_NUM_H | V_POS registers. +\# Used to position page numbers. +\# *Notes: +\# Default is center/bottom. +\# +.MAC PAGENUM_POS END +. nr #PAGE_NUM_POS_SET 1 +. if '\\$1'TOP' .nr #PAGE_NUM_V_POS 1 +. if '\\$1'BOTTOM' .nr #PAGE_NUM_V_POS 2 +. if '\\$2'LEFT' .nr #PAGE_NUM_H_POS 1 +. if '\\$2'CENTER' .nr #PAGE_NUM_H_POS 2 +. if '\\$2'CENTRE' .nr #PAGE_NUM_H_POS 2 +. if '\\$2'RIGHT' .nr #PAGE_NUM_H_POS 3 +.END +\# +.MAC PN_WITH_HYPHENS END +. nr #HYPHEN_ADJ \\n[#CAP_HEIGHT]/12 +. ds $HYPHEN \v'-\En[#HYPHEN_ADJ]u'-\v'\En[#HYPHEN_ADJ]u' +. ds $PN_FOR_KN \\n[#PAGENUMBER] +.\" Check for initial or terminal 1's or 7's, and apply a little kerning +. substring $PN_FOR_KN 0 0 \" 1st digit +. if '\\*[$PN_FOR_KN]'1' .ds $PRE_HY_KN \*[BU3] +. if '\\*[$PN_FOR_KN]'7' .ds $PRE_HY_KN \*[BU3] +. ds $PN_FOR_KN \\n[#PAGENUMBER] +. substring $PN_FOR_KN -1 -1 \" last digit +. if '\\*[$PN_FOR_KN]'1' .ds $POST_HY_KN \*[BU3] +. if '\\*[$PN_FOR_KN]'7' .ds $POST_HY_KN \*[BU3] +. PRINT \ +\m[\\*[$PAGE_NUM_COLOR]]\ +\\*[$HYPHEN]\|\\*[$PRE_HY_KN]\\n[#PAGENUMBER]\\*[$POST_HY_KN]\|\\*[$HYPHEN] +. br +. rm $PRE_HY_KERN +. rm $POST_HY_KERN +.END +\# +\# PRINT PAGE NUMBER +\# ----------------- +\# *Arguments: +\# +\# *Function: +\# Prints page number if PAGINATE=1. +\# +.MAC PRINT_PAGE_NUMBER END +. ev PAGENUMBER +. nf +. po \\n[#DOC_L_MARGIN]u +. ll \\n[#DOC_L_LENGTH]u +. ta \\n[.l]u +. fam \\*[$PAGE_NUM_FAM] +. ft \\*[$PAGE_NUM_FT] +. ps \\n[#DOC_PT_SIZE]u\\*[$PAGE_NUM_SIZE_CHANGE] +. if \\n[#PRINT_STYLE]=1 .TYPEWRITER +. if \\n[#PAGE_NUM_V_POS]=1 .vs 0 +. if o \{\ +. ie \\n[#PAGE_NUM_H_POS]=1 .LEFT +. el .RIGHT +. \} +. if e \{\ +. ie \\n[#PAGE_NUM_H_POS]=1 .RIGHT +. el .LEFT +. \} +. if \\n[#PAGE_NUM_H_POS]=2 .CENTER +. if \\n[#RECTO_VERSO]=0 \{\ +. if \\n[#PAGE_NUM_H_POS]=1 .LEFT +. if \\n[#PAGE_NUM_H_POS]=2 .CENTER +. if \\n[#PAGE_NUM_H_POS]=3 .RIGHT +. \} +. nr #PAGENUMBER \\n%+\\n[#PAGE_NUM_ADJ] +. if \\n[#EN_FIRST_PAGE] \{\ +. if \\n[#EN_FIRST_PN] .PAGENUMBER \\n[#EN_FIRST_PN] +. rr #EN_FIRST_PAGE +. \} +. if \\n[#BIB_FIRST_PAGE] \{\ +. if \\n[#BIB_FIRST_PN] .PAGENUMBER \\n[#BIB_FIRST_PN] +. rr #BIB_FIRST_PAGE +. \} +. ie \\n[#DRAFT_WITH_PAGENUM] \{\ +. ie '\\*[$REVISION]'' \ +. PRINT "\\*[$DRAFT_STRING]\\*[$DRAFT] / \\n[#PAGENUMBER]" +. el \{\ +. ie '\\*[$DRAFT]'' \ +. PRINT "\\*[$REVISION_STRING] \\*[$REVISION] / \\n[#PAGENUMBER]" +. el \ +. PRINT \ +"\\*[$DRAFT_STRING]\\*[$DRAFT], \\*[$REVISION_STRING] \\*[$REVISION] / \ +\\n[#PAGENUMBER]" +. \} +. \} +. el \{\ +. ie \\n[#PAGE_NUM_HYPHENS] \{\ +. if '\\*[$PAGENUM_STYLE]'DIGIT' \{\ +. di NULL +1\\R'#CAP_HEIGHT \\n[.cht]' +. di +. PN_WITH_HYPHENS +. \} +. if '\\*[$PAGENUM_STYLE]'ROMAN' \{\ +. di NULL +I\\R'#CAP_HEIGHT \\n[.cht]' +. di +. PN_WITH_HYPHENS +. \} +. if '\\*[$PAGENUM_STYLE]'ALPHA' \{\ +. di NULL +E\\R'#CAP_HEIGHT \\n[.cht]' +. di +. PN_WITH_HYPHENS +. \} +. if '\\*[$PAGENUM_STYLE]'roman' \ +. PRINT \m[\\*[$PAGE_NUM_COLOR]]-\|\\n[#PAGENUMBER]\|- +. if '\\*[$PAGENUM_STYLE]'alpha' \ +. PRINT \m[\\*[$PAGE_NUM_COLOR]]-\|\\n[#PAGENUMBER]\|- +. \} +. el \{\ +. ie !d$PAGENUM_STRING .PRINT \m[\\*[$PAGE_NUM_COLOR]]\\n[#PAGENUMBER] +. el .PRINT \m[\\*[$PAGE_NUM_COLOR]]\\*[$PAGENUM_STRING] +. \} +. \} +. ev +. nr #DIVER_DEPTH 0 +.END +\# +\# ==================================================================== +\# +\# +++FOOTNOTES+++ +\# +\# Mom's footnote handling is baroque, to say the least. There are +\# redundancies in a number of the macros involved, as well as some +\# registers that probably don't get used anymore. The baggage is left +\# in in case some new footnote oddity/challenge gets thrown at her. +\# +\# The macros are heavily commented. +\# +\# FOOTNOTE AUTOLEAD +\# ----------------- +\# *Arguments: +\# +\# *Function: +\# Creates or modifies register #FN_AUTOLEAD. +\# *Notes: +\# Default is #DOC_LEAD/2 for TYPEWRITE; 2 for TYPESET +\# +.MAC FOOTNOTE_AUTOLEAD END +. nr #FN_AUTOLEAD (p;\\$1) +.END +\# +\# FOOTNOTE MARKERS +\# ---------------- +\# *Arguments: +\# | +\# *Function: +\# Turns generation of footnote markers on or off. +\# *Notes: +\# Default is on. +\# +.MAC FOOTNOTE_MARKERS END +. ie '\\$1'' .nr #FN_MARKERS 1 +. el .nr #FN_MARKERS 0 +.END +\# +\# FOOTNOTE MARKER STYLE +\# --------------------- +\# *Arguments: +\# STAR | NUMBER | LINE +\# *Function: +\# Sets register #FN_MARKER_STYLE, used in FOOTNOTE to determine +\# the style of footnote markers. +\# *Notes: +\# 1=STAR; 2=NUMBER; 3=LINE. LINE means "use output line numbers". +\# Default is STAR. +\# +.MAC FOOTNOTE_MARKER_STYLE END +. if '\\$1'STAR' \{\ +. if \\n[#FN_MARKER_STYLE]=3 \{\ +. if !\\n[#NEWPAGE]=1 \{\ +. tm1 "[mom]: Your current FOOTNOTE_MARKER STYLE is LINE. +. tm1 " You cannot change footnote marker style without +. tm1 " first breaking to a new page with NEWPAGE. +. tm1 " Ignoring request FOOTNOTE_MARKER_STYLE STAR at line \\n[.c]. +. return +. \} +. \} +. if \\n[#RUN_ON]=1 \{\ +. tm1 "[mom]: FOOTNOTE_MARKER_STYLE STAR at line \\n[.c] is incompatible +. tm1 " with RUN_ON footnotes. Ignoring request. +. return +. \} +. nr #FN_MARKER_STYLE 1 +. if \\n[#NEWPAGE]=1 .rr #NEWPAGE +. FOOTNOTE_MARKERS +. \} +. if '\\$1'NUMBER' \{\ +. if \\n[#FN_MARKER_STYLE]=3 \{\ +. if !\\n[#NEWPAGE]=1 \{\ +. tm1 "[mom]: Your current FOOTNOTE_MARKER STYLE is NUMBER. +. tm1 " You cannot change footnote marker style without +. tm1 " first breaking to a new page with NEWPAGE. +. tm1 " Ignoring request FOOTNOTE_MARKER_STYLE NUMBER at line \\n[.c]. +. return +. \} +. \} +. if \\n[#RUN_ON]=1 \{\ +. tm1 "[mom]: FOOTNOTE_MARKER_STYLE NUMBER at line \\n[.c] is incompatible +. tm1 " with RUN_ON footnotes. Ignoring request. +. return +. \} +. nr #FN_MARKER_STYLE 2 +. shift +. if '\\$1'NO_SUPERSCRIPT' .nr #NO_SUPERSCRIPT 1 +. if \\n[#NEWPAGE]=1 .rr #NEWPAGE +. FOOTNOTE_MARKERS +. \} +. if '\\$1'LINE' \{\ +. nr #FN_MARKER_STYLE 3 +. FOOTNOTE_MARKERS OFF +. if !\\n[#FN_LN_SEP] \ +. if !\\n[#FN_LN_BRACKETS] .FOOTNOTE_LINENUMBER_BRACKETS SQUARE +. \} +.END +\# +\# FOOTNOTE NUMBER PLACEHOLDERS +\# ---------------------------- +\# *Argument: +\# +\# *Function: +\# Sets register #FN_NUMBER_PLACEHOLDERS, used to establish whether to +\# right pad a footnote number (in the footnote itself, not body copy). +\# *Notes: +\# No default is set for this; user must determine if, and where, it's +\# required +\# +.MAC FOOTNOTE_NUMBER_PLACEHOLDERS END +. nr #FN_NUMBER_PLACEHOLDERS \\$1 +.END +\# +\# FOOTNOTE LINENUMBER MARK +\# ------------------------ +\# *Function: +\# This string, when called inline, stores the current output line +\# number in register #FN_MARK for use with FOOTNOTE. +\# +.ds FN_MARK \R'#FN_MARK \En[ln]' +\# +\# FOOTNOTE LINENUMBER SEPARATOR +\# ----------------------------- +\# *Argument: +\# +\# *Function: +\# Stores user-defined separator (for use then +\# FOOTNOTE_MARKER_STYLE is LINE) in string $FN_LN_SEP. The +\# separator is intended to be used when the user wishes a +\# separator, rather than the choice of brackets offered by +\# FOOTNOTE_LINENUMBER_BRACKETS. +\# +.MAC FOOTNOTE_LINENUMBER_SEPARATOR END +. rr #FN_LN_BRACKETS +. nr #FN_LN_SEP 1 +. ds $FN_LN_SEP "\\$1 +.END +\# +\# FOOTNOTE LINENUMBER BRACKETS +\# ---------------------------- +\# *Argument: +\# PARENS | SQUARE | BRACES or ( | [ | { +\# *Function: +\# Sets register #FN_LN_BRACKETS to 1, and creates strings +\# $FN_OPEN_BRACKET and $FN_CLOSE_BRACKET according to the given +\# argument. +\# +.MAC FOOTNOTE_LINENUMBER_BRACKETS END +. rr #FN_LN_SEP +. nr #FN_LN_BRACKETS 1 +. if '\\$1'PARENS' \{\ +. ds $FN_OPEN_BRACKET ( +. ds $FN_CLOSE_BRACKET ) +. \} +. if '\\$1'(' \{\ +. ds $FN_OPEN_BRACKET ( +. ds $FN_CLOSE_BRACKET ) +. \} +. if '\\$1'SQUARE' \{\ +. ds $FN_OPEN_BRACKET [ +. ds $FN_CLOSE_BRACKET ] +. \} +. if '\\$1'[' \{\ +. ds $FN_OPEN_BRACKET [ +. ds $FN_CLOSE_BRACKET ] +. \} +. if '\\$1'BRACES' \{\ +. ds $FN_OPEN_BRACKET { +. ds $FN_CLOSE_BRACKET } +. \} +. if '\\$1'{' \{\ +. ds $FN_OPEN_BRACKET { +. ds $FN_CLOSE_BRACKET } +. \} +.END +\# +\# RESET FOOTNOTE NUMBER +\# --------------------- +\# *Arguments: +\# | PAGE +\# *Function: +\# Resets register #FN_NUMBER to 1. If argument is PAGE, creates +\# toggle #RESET_FN_NUMBER which is checked in HEADER. If 1, +\# numbered footnotes on every page start at 1. +\# +.MAC RESET_FOOTNOTE_NUMBER END +. ie '\\$1'' .nr #FN_NUMBER 0 1 +. el .nr #RESET_FN_NUMBER 1 +.END +\# +\# FOOTNOTE RULE LENGTH +\# -------------------- +\# *Arguments: +\# +\# *Function: +\# Creates or modifies registers #FN_RULE_LENGTH. +\# *Notes: +\# Requires unit of measure (iPpcm). +\# Default is 4P for both PRINTSTYLEs. +\# +.MAC FOOTNOTE_RULE_LENGTH END +. nr #FN_RULE_LENGTH (\\$1) +.END +\# +\# FOOTNOTE_RULE_ADJ +\# ----------------- +\# *Arguments: +\# +\# *Function: +\# Creates or modifies register #FN_RULE_ADJ. +\# *Notes: +\# Default is 3p for both TYPESTYLES. +\# +\# Requires unit of measure. +\# +.MAC FOOTNOTE_RULE_ADJ END +. nr #FN_RULE_ADJ (\\$1) +.END +\# +\# FOOTNOTE RULE +\# ------------- +\# *Arguments: +\# | +\# *Function: +\# Turns printing of footnote separator rule on or off. If invoked as +\# PRINT_FOOTNOTE_RULE, prints footnote separator rule. +\# *Notes: +\# Default is on. +\# +\# Invoked in FOOTNOTE (as PRINT_FOOTNOTE_RULE) as 1st line of a footnote +\# if the footnote number (#FN_COUNT) is 1. +\# +.MAC FOOTNOTE_RULE END +. ie '\\$0'PRINT_FOOTNOTE_RULE' \{\ +. if \\n[#FN_RULE]=0 .RLD 1v +. RLD 1v +. LEFT +\v'-\\n[#FN_RULE_ADJ]u-\\n[#FN_RULE_WEIGHT_ADJ]u'\ +\D't \\n[#FN_RULE_WEIGHT]'\ +\h'-\\n[#FN_RULE_WEIGHT]u'\ +\D'l \\n[#FN_RULE_LENGTH]u 0'\ +\v'+\\n[#FN_RULE_ADJ]u+\\n[#FN_RULE_WEIGHT_ADJ]u' +\!. ps \\n[#DOC_PT_SIZE]u\\*$[FN_SIZE_CHANGE] +. QUAD \\*[$FN_QUAD] +. \} +. el \{\ +. ie '\\$1'' .nr #FN_RULE 1 +. el .nr #FN_RULE 0 +. \} +.END +\# +\# FOOTNOTE SPACING +\# ---------------- +\# *Arguments: +\# | +\# *Function: +\# Enables printing of post footnote spacing. +\# *Notes: +\# Default is no space. +\# +.MAC FOOTNOTE_SPACING END +. ie \B'\\$1' .ds $FN_SPACE \\$1 +. el .rm $FN_SPACE +.END +\# +\# FOOTNOTE FIRST LINE INDENT +\# -------------------------- +\# *Arguments: +\# +\# *Function: +\# Indents first line of footnotes. +\# *Notes: +\# Default is no indent. +\# +.MAC FOOTNOTE_INDENT END +. nr #FN_INDENT \\$1 +.END +\# +\# RUN ON FOOTNOTES +\# ---------------- +\# *Arguments: +\# | +\# *Function: +\# Toggles run-on footnotes on or off. +\# +.MAC FOOTNOTES_RUN_ON END +. ie '\\$1'' \{\ +. if \\n[#FN_COUNT]>0 \{\ +. tm1 "[mom]: Switching to run-on footnotes at line \\n[.c] will cause +. tm1 " you to loose footnotes already formatted for this page. +. tm1 " Ignoring request FOOTNOTES_RUN_ON. +. rr #RUN_ON +. return +. \} +. nr #RUN_ON 1 +. if \\n[#FN_MARKER_STYLE]=1 .RUNON_WARNING +. if \\n[#FN_MARKER_STYLE]=2 .RUNON_WARNING +. \} +. el \{\ +. if \\n[#FN_COUNT]>0 \{\ +. if \\n[#RUN_ON]=1 \{\ +. tm1 "[mom]: Switching off run-on footnotes at line \\n[.c] will cause +. tm1 " you to loose footnotes already formatted for this page. +. tm1 " Ignoring request FOOTNOTES_RUN_ON \\$1. +. return +. \} +. \} +. rr #RUN_ON +. \} +.END +\# +.MAC RUNON_WARNING END +. if \\n[#FN_MARKER_STYLE]=1 \{\ +. tm1 "[mom]: The footnote marker style active at line \\n[.c] is STAR, +. tm1 " which is incompatible with run-on footnotes. Please change +. tm1 " the footnote marker style to LINE. Continuing to process, +. tm1 " but ignoring request FOOTNOTES_RUN_ON. +. rr #RUN_ON +. \} +. if \\n[#FN_MARKER_STYLE]=2 \{\ +. tm1 "[mom]: The footnote marker style active at line \\n[.c] is NUMBER, +. tm1 " which is incompatible with run-on footnotes. Please change +. tm1 " the footnote marker style to LINE. Continuing to process, +. tm1 " but ignoring request FOOTNOTES_RUN_ON. +. rr #RUN_ON +. \} +.END +\# +\# FOOTNOTE +\# -------- +\# *Arguments: +\# | INDENT L|LEFT|R|RIGHT|B|BOTH | +\# *Function: +\# Begins collecting and diverting footnote text if no argument +\# given. Otherwise, ends diversion FOOTNOTES, measures footnote +\# depth, and sets footnote trap. +\# *Notes: +\# The input line preceding a footnote call MUST terminate with \c +\# or the footnote marker will be spaced away from the word it +\# should be joined to. +\# +\# If FOOTNOTE is invoked with INDENT, the footnote will +\# be indented. An indent style and an indent value must be given. +\# Subsequent footnotes will NOT be indented; INDENT must be given +\# for each footnote the user wants indented. +\# +.MAC FOOTNOTE END +. ie '\\$1'' \{\ +. if \\n[#UNDERLINE_ON] \{\ +. UNDERLINE OFF +. nr #UNDERLINE_WAS_ON_FN 1 +. \} +. if \\n[#FN_MARKER_STYLE]=3 \{\ +. if !\\n[#LINENUMBERS] \{\ +. tm1 "[mom]: Line numbering must be enabled with NUMBER_LINES when +. tm1 " FOOTNOTE_MARKER_STYLE is LINE. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. if \\n[#FN_MARK]=0 .nr #FN_MARK \\n[ln] +. nr #FN_MARK_2 \\n[ln] +. if '\\n[.z]'P_QUOTE' \{\ +. nr #FN_MARK -1 +. nr #FN_MARK_2 -1 +. \} +. if \\n[#IN_DIVER]=1 \{\ +. if '\\n[.z]'P_QUOTE' \{\ +. if !\\n[#QUOTE_LN]=1 \{\ +. if !\\n[#SILENT_QUOTE_LN]=1 \{\ +. tm1 "[mom]: You have requested a line-numbered footnote inside a +. tm1 " QUOTE at line \\n[.c], but line-numbering has not been enabled +. tm1 " for QUOTES. Printing footnote with label "0". +. rr #FN_MARK +. rr #FN_MARK_2 +. \} +. \} +. \} +. if '\\n[.z]'B_QUOTE' \{\ +. if !\\n[#BQUOTE_LN]=1 \{\ +. if !\\n[#SILENT_BQUOTE_LN]=1 \{\ +. tm1 "[mom]: You have requested a line-numbered footnote inside a +. tm1 " BLOCKQUOTE at line \\n[.c], but line-numbering has not been enabled +. tm1 " for BLOCKQUOTES. Printing footnote with label "0". +. rr #FN_MARK +. rr #FN_MARK_2 +. \} +. \} +. \} +. \} +. \} +.\" Begin processing footnotes that occur inside QUOTE, BLOCKQUOTE +.\" or EPIGRAPH. +. if \\n[#IN_DIVER]=1 \{\ +. nr #PAGE_POS \\n[nl]+\\n[.d]+\\n[#DOC_LEAD] +. nr #FOOTER_POS \\n[#PAGE_LENGTH]+(\\n[#VARIABLE_FOOTER_POS]-1) +. nr #SPACE_TO_FOOTER \\n[#FOOTER_POS]-\\n[#PAGE_POS] +.\" Are we on a "defer" line? If so, defer the text of the footnote. +. ie \\n[#SPACE_TO_FOOTER]<=\\n[#DOC_LEAD] \ +. nr #DIVER_FN 2 \" treat like a normal deferred footnote +. el \ +. nr #DIVER_FN 2 \" treat like a normal footnote +. if \\n[#PAGE_POS]>\\n[#FOOTER_POS] \ +. nr #DIVER_FN 1 \" move this footnote +.\" Test for situation where, because a final line of QUOTE, BLOCKQUOTE +.\" or EPIGRAPH isn't yet adjusted at this point, the last word on the +.\" line may *seem* to belong to the final line of the page, but will, +.\" in fact, become the first word of the subsequent page. In such +.\" circumstances, we want the footnote to be treated as a "moved" +.\" diversion footnote. +. if \\n[.k]>\\n[.l] .nr #DIVER_FN 1 +. if r #DIVER_FN \{\ +. if !\\n[#DIVER_FN]=2 .\\n+[#DONE_ONCE] +.\" A footnote inside a diversion will become the 1st footnote on the +.\" following page/column. +. if \\n[#DIVER_FN]=1 .DIVER_FN_1_PRE +.\" A footnote inside a diversion that should be treated like a +.\" normal footnote (including defers.) +. if \\n[#DIVER_FN]=2 .DIVER_FN_2_PRE +. \} +. nr #SAVED_FN_COUNT \\n[#FN_COUNT]+1 +. nr #SAVED_FN_COUNT_FOR_COLS \\n[#FN_COUNT_FOR_COLS]+1 +. \} +.\" End processing footnotes that occur inside QUOTE, BLOCKQUOTE or +.\" EPIGRAPH. +.\" +.\" Test for situation where, because a final line of running text +.\" isn't yet adjusted at this point, the last word on the line may +.\" *seem* to belong to the final line of the page, but will, in +.\" fact, become the first word of the subsequent page. In such +.\" circumstances, we want the footnote marker in running text to +.\" be the correct one for the 1st footnote on the page. +. if \\n[.k]>\\n[.l] \{\ +. if (\\n[nl]+\\n[#DOC_LEAD])>(\\n[#PAGE_LENGTH]+\\n[#VARIABLE_FOOTER_POS]) \{\ +. ie \\n[#COLUMNS]=1 \{\ +. if \\n[#COL_NUM]=\\n[#NUM_COLS] \{\ +. if \\n[#FN_MARKER_STYLE]=1 .nr #FN_COUNT_FOR_COLS 0 1 +. if \\n[#FN_MARKER_STYLE]=2 \{\ +. if \\n[#RESET_FN_NUMBER] \{\ +. nr #FN_NUMBER 0 1 +. nr #NOT_YET_ADJUSTED 1 +. \} +. \} +. \} +. \} +. el \{\ +. if \\n[#FN_MARKER_STYLE]=1 .nr #FN_COUNT 0 1 +. if \\n[#FN_MARKER_STYLE]=2 \{\ +. if \\n[#RESET_FN_NUMBER] \{\ +. nr #FN_NUMBER 0 1 +. nr #NOT_YET_ADJUSTED 1 +. \} +. \} +. \} +. \} +. \} +. if \\n[#FN_MARKERS] \{\ +.\" Housekeeping +. if \\n[#CONDENSE] \*[CONDX]\c +. if \\n[#EXTEND] \*[EXTX]\c +.\" Add footnote markers to running text... +. if !\\n[#NO_FN_MARKER] \{\ +.\" ...but not if TERMINATE has not been called +. if !r#TERMINATE \{\ +.\" Marker style star/dagger/double-dagger +. if \\n[#FN_MARKER_STYLE]=1 \{\ +.\" Columnar docs either move col to col, or last col to next page. +.\" They require their own special FN_COUNT because regular FN_COUNT +.\" is used to figure out things like whether or not to put a rule +.\" above footnotes (in addition to keeping track of the footnote +.\" count in non-columnar docs). +. ie \\n[#COLUMNS]=1 \{\ +. if \\n[#FN_COUNT_FOR_COLS]=0 .PRINT \*[BU2]*\c +. if \\n[#FN_COUNT_FOR_COLS]=1 .PRINT \*[BU1]\[dg]\c +. if \\n[#FN_COUNT_FOR_COLS]=2 .PRINT \[dd]\c +. if \\n[#FN_COUNT_FOR_COLS]=3 .PRINT \*[BU2]**\c +. if \\n[#FN_COUNT_FOR_COLS]=4 .PRINT \*[BU1]\[dg]\[dg]\c +. if \\n[#FN_COUNT_FOR_COLS]=5 .PRINT \[dd]\[dd]\c +. if \\n[#FN_COUNT_FOR_COLS]=6 .PRINT \*[BU2]***\c +. if \\n[#FN_COUNT_FOR_COLS]=7 .PRINT \*[BU1]\[dg]\[dg]\[dg]\c +. if \\n[#FN_COUNT_FOR_COLS]=8 .PRINT \[dd]\[dd]\[dd]\c +. if \\n[#FN_COUNT_FOR_COLS]=9 .PRINT \*[BU2]****\c +. \} +. el \{\ +. if \\n[#FN_COUNT]=0 .PRINT \*[BU2]*\c +. if \\n[#FN_COUNT]=1 .PRINT \*[BU1]\[dg]\c +. if \\n[#FN_COUNT]=2 .PRINT \[dd]\c +. if \\n[#FN_COUNT]=3 .PRINT \*[BU2]**\c +. if \\n[#FN_COUNT]=4 .PRINT \*[BU1]\[dg]\[dg]\c +. if \\n[#FN_COUNT]=5 .PRINT \[dd]\[dd]\c +. if \\n[#FN_COUNT]=6 .PRINT \*[BU2]***\c +. if \\n[#FN_COUNT]=7 .PRINT \*[BU1]\[dg]\[dg]\[dg]\c +. if \\n[#FN_COUNT]=8 .PRINT \[dd]\[dd]\[dd]\c +. if \\n[#FN_COUNT]=9 .PRINT \*[BU2]****\c +. \} +. \} +.\" Marker style superscript numbers +. if \\n[#FN_MARKER_STYLE]=2 \{\ +. if \\n[#PRINT_STYLE]=1 \ +. PRINT \ +"\s-2\v'-\\n[#DOC_LEAD]u/5u'\\n+[#FN_NUMBER]\v'+\\n[#DOC_LEAD]u/5u'\s+2\c" +. if \\n[#PRINT_STYLE]=2 \ +. PRINT \ +"\*[SUP]\\n+[#FN_NUMBER]\*[SUPX]\c" +. \} +. \} +. \} +. \} +.\" More housekeeping +.\" +.\" #SPACE_REMAINING is the space left between where we are +.\" on the page and the bottom margin. It's used to determine whether +.\" or not the footnote will overflow, and how many lines of +.\" footnotes will fit on the page if some have to overflow. +. ie \\n[#DIVER_FN]=2 \ +. nr #SPACE_REMAINING (\\n[#PAGE_LENGTH]-\\n[#B_MARGIN])-(\\n[#PAGE_POS]) +. el \ +. nr #SPACE_REMAINING (\\n[#PAGE_LENGTH]-\\n[#B_MARGIN])-\\n[nl] +. if \\n[#FROM_DIVERT_FN]=1 \{\ +. nr #SPACE_REMAINING \\n[#PAGE_LENGTH]-\\n[#B_MARGIN] +. rr #FROM_DIVERT_FN +. \} +. nr #PP_STYLE_PREV \\n[#PP_STYLE] +. nr #PP_STYLE 2 +. if \\n[#INDENT_FIRST_PARAS] .nr #INDENT_FIRSTS 1 +. INDENT_FIRST_PARAS +.\" Prepare FOOTNOTE to receive footnote text. +. if \\n[.hy] .nr #RESTORE_HY_PARAMS \\n[.hy] +. ev FOOTNOTES +. ll \\n[#DOC_L_LENGTH]u +. ta \\n[.l]u +. if \\n[#COLUMNS]=1 \{\ +. ll \\n[#COL_L_LENGTH]u +. ta \\n[.l]u +. \} +. if \\n[#FN_R_INDENT] \{\ +. ll -\\n[#FN_R_INDENT]u +. ta \\n[.l]u +. \} +. if \\n[#FN_BR_INDENT] \{\ +. ll -\\n[#FN_BR_INDENT]u +. ta \\n[.l]u +. \} +. FAMILY \\*[$FN_FAM] +. FT \\*[$FN_FT] +. ps \\n[#DOC_PT_SIZE]u\\*[$FN_SIZE_CHANGE] +. vs \\n[.ps]u+\\n[#FN_AUTOLEAD]u +. QUAD \\*[$FN_QUAD] +. if \\n[#PRINT_STYLE]=1 \{\ +. TYPEWRITER +. ie \\n[#SINGLE_SPACE] .vs \\n[#ORIGINAL_DOC_LEAD]u +. el .vs \\n[#ORIGINAL_DOC_LEAD]u/2u +. QUAD LEFT +. HY OFF +. \} +. nr #FN_LEAD \\n[#LEAD] +.\" Begin diversion FOOTNOTES or FN_IN_DIVER +. ie r#COUNTERS_RESET \{\ +. ie \\n[#DONE_ONCE]=1 \{\ +. ie \\n[#RUN_ON] \{\ +. di RUNON_FN_IN_DIVER +. nr #RUNON_FN_IN_DIVER 1 +. \} +. el .di FN_IN_DIVER +. \} +. el \{\ +. ie \\n[#RUN_ON] \{\ +. da RUNON_FN_IN_DIVER +. nr #RUNON_FN_IN_DIVER 1 +. \} +. el .da FN_IN_DIVER +. \} +. \\n+[#DONE_ONCE] +. \} +. el \{\ +. ie \\n[#RUN_ON] \{\ +. nh +. da RUNON_FOOTNOTES +. nr #RUNON_FOOTNOTES 1 +. \} +. el .da FOOTNOTES +. \} +. if \\n[#FOOTNOTE_COLOR]=1 \{\ +. TRAP OFF +. nf +\m[\\*[$FOOTNOTE_COLOR]] +. EOL +. fi +. TRAP +. \} +. if \\n[#EPIGRAPH] .nr #FN_FOR_EPI 1 +.\" When a deferred footnote is also the 1st footnote on the page, +.\" and when the page it's output on also has footnotes, some +.\" whitespace is needed between the deferred footnote and the +.\" first footnote belonging to the output page so that there's +.\" no confusion when two stars (or two number 1s) appear in +.\" footnotes... +. if \\n[#FN_DEFER_SPACE] \{\ +.\" ...but only add the extra space if TERMINATE has not been called +. if !r#TERMINATE \{\ +.\" ...and not if defer space has already been added +. if !\\n[#DEFER_SPACE_ADDED] \{\ +.\" ...and not if the footnote count the last time we checked for +.\" a defer situation inside a diversion is greater than 1. +. if !\\n[#SAVED_DIVER_FN_COUNT]>1 \{\ +. if \\n[#FN_MARKER_STYLE]=1 .ALD 1v +. if \\n[#RESET_FN_NUMBER] .ALD 1v +. nr #DEFER_SPACE_ADDED 1 +. \} +. \} +. \} +. rr #FN_DEFER_SPACE +. rr #SAVED_DIVER_FN_COUNT +. \} +. if \\n[#DIVERTED]=3 \{\ +. if \\n[#FN_COUNT]>0 \{\ +\!. RLD 1v +. \} +. \} +.\" Add footnote rule (or, if no rule, some whitespace). +.\" N.B.- this line increments #FN_COUNT each and every time FOOTNOTE +.\" is run. +. if \\n+[#FN_COUNT]=1 \{\ +.\" If a footnote is called in a diversion, and the footnote has to +.\" be moved, don't put in the rule now (it's taken care of when +.\" FN_IN_DIVER is output into FOOTNOTE in PROCESS_FN_IN_DIVER). +. if !\\n[#DONT_RULE_ME]=1 \{\ +. if !\\n[#FN_DEPTH] \{\ +. if \\n[#PRINT_STYLE]=1 \ +. if !\\n[#RUN_ON] .sp \\n[#DOC_LEAD]u +. ie \\n[#FN_RULE]=1 \{\ +. if !\\n[#RUN_ON] \{\ +. if \\n[#SINGLE_SPACE] .sp \\n[#DOC_LEAD]u +. PRINT_FOOTNOTE_RULE +. if !'\\*[$FN_SPACE]'' .sp -\\*[$FN_SPACE] +. \} +. \} +. el .sp +. nr #RULED 1 +. \} +. \} +. \} +. rr #DONT_RULE_ME +. ds $RESTORE_SS_VAR \\*[$SS_VAR] +. SS 0 +.\" Add footnote markers to footnote text... +. ie \\n[#FN_MARKERS] \{\ +. if !'\\*[$FN_SPACE]'' \ +. if \\n[#FN_COUNT]>0 .ALD \\*[$FN_SPACE] +. if !\\n[#NO_FN_MARKER] \{\ +.\" ...but not if TERMINATE has been called. +. if !r#TERMINATE \{\ +. if \\n[#REF]=1 \{\ +. nr #REF_FN_INDENT (u;\\*[$REF_FN_INDENT]) +. ti \\n[#REF_FN_INDENT]u +. \} +. if \\n[#FN_MARKER_STYLE]=1 \{\ +. ie \\n[#COLUMNS]=1 \{\ +. \\n+[#FN_COUNT_FOR_COLS] +. if \\n[#FN_COUNT_FOR_COLS]=1 .PRINT \h'0+\\n[#FN_INDENT]u'*\c +. if \\n[#FN_COUNT_FOR_COLS]=2 .PRINT \h'0+\\n[#FN_INDENT]u'\[dg]\c +. if \\n[#FN_COUNT_FOR_COLS]=3 .PRINT \h'0+\\n[#FN_INDENT]u'\[dd]\c +. if \\n[#FN_COUNT_FOR_COLS]=4 .PRINT \h'0+\\n[#FN_INDENT]u'**\c +. if \\n[#FN_COUNT_FOR_COLS]=5 .PRINT \h'0+\\n[#FN_INDENT]u'\[dg]\[dg]\c +. if \\n[#FN_COUNT_FOR_COLS]=6 .PRINT \h'0+\\n[#FN_INDENT]u'\[dd]\[dd]\c +. if \\n[#FN_COUNT_FOR_COLS]=7 .PRINT \h'0+\\n[#FN_INDENT]u'***\c +. if \\n[#FN_COUNT_FOR_COLS]=8 .PRINT \h'0+\\n[#FN_INDENT]u'\[dg]\[dg]\[dg]\c +. if \\n[#FN_COUNT_FOR_COLS]=9 .PRINT \h'0+\\n[#FN_INDENT]u'\[dd]\[dd]\[dd]\c +. if \\n[#FN_COUNT_FOR_COLS]=10 .PRINT \h'0+\\n[#FN_INDENT]u'****\c +. \} +. el \{\ +. if \\n[#FN_COUNT]=1 .PRINT \h'0+\\n[#FN_INDENT]u'*\c +. if \\n[#FN_COUNT]=2 .PRINT \h'0+\\n[#FN_INDENT]u'\[dg]\c +. if \\n[#FN_COUNT]=3 .PRINT \h'0+\\n[#FN_INDENT]u'\[dd]\c +. if \\n[#FN_COUNT]=4 .PRINT \h'0+\\n[#FN_INDENT]u'**\c +. if \\n[#FN_COUNT]=5 .PRINT \h'0+\\n[#FN_INDENT]u'\[dg]\[dg]\c +. if \\n[#FN_COUNT]=6 .PRINT \h'0+\\n[#FN_INDENT]u'\[dd]\[dd]\c +. if \\n[#FN_COUNT]=7 .PRINT \h'0+\\n[#FN_INDENT]u'***\c +. if \\n[#FN_COUNT]=8 .PRINT \h'0+\\n[#FN_INDENT]u'\[dg]\[dg]\[dg]\c +. if \\n[#FN_COUNT]=9 .PRINT \h'0+\\n[#FN_INDENT]u'\[dd]\[dd]\[dd]\c +. if \\n[#FN_COUNT]=10 .PRINT \h'0+\\n[#FN_INDENT]u'****\c +. \} +. \} +. if \\n[#FN_MARKER_STYLE]=2 \{\ +. ds $FN_NUMBER \\n[#FN_NUMBER] +. length #FN_NUMBER_LENGTH \\*[$FN_NUMBER] +. if \\n[#COLUMNS]=1 \ +. \\n+[#FN_COUNT_FOR_COLS] +. if \\n[#NOT_YET_ADJUSTED]=1 \{\ +. nr #FN_NUMBER 1 1 +. rr #NOT_YET_ADJUSTED +. \} +. if \\n[#PRINT_STYLE]=1 \{\ +. ie \\n[#NO_SUPERSCRIPT] \{\ +. ie \\n[#FN_NUMBER_LENGTH]<\\n[#FN_NUMBER_PLACEHOLDERS] \ +. PRINT "\h'0+\\n[#FN_INDENT]u'\0(\\n[#FN_NUMBER])\|\c" +. el \ +. PRINT "\h'0+\\n[#FN_INDENT]u'(\\n[#FN_NUMBER])\|\c" +. \} +. el \{\ +. ie \\n[#FN_NUMBER_LENGTH]<\\n[#FN_NUMBER_PLACEHOLDERS] \ +. PRINT \ +"\h'0+\\n[#FN_INDENT]u'\s-2\v'-\\n[.v]u/5u'\0\\n[#FN_NUMBER]\|\v'+\\n[.v]u/5u'\s+2\|\c" +. el \ +. PRINT \ +"\h'0+\\n[#FN_INDENT]u'\s-2\v'-\\n[.v]u/5u'\\n[#FN_NUMBER]\|\v'+\\n[.v]u/5u'\s+2\|\c" +. \} +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. ie \\n[#FN_NUMBER_LENGTH]<\\n[#FN_NUMBER_PLACEHOLDERS] \ +. PRINT "\h'0+\\n[#FN_INDENT]u'\*[SUP]\0\\n[#FN_NUMBER]\*[SUPX]\*[FU 3]\c" +. el \ +. PRINT "\h'0+\\n[#FN_INDENT]u'\*[SUP]\\n[#FN_NUMBER]\*[SUPX]\*[FU 3]\c" +. \} +. \} +. \} +. \} +. \} +. el \{\ +.\" Line-numbered footnotes handling +. if \\n[#FN_MARKER_STYLE]=3 \{\ +. if \\n[#FN_SPACE]>0 \{\ +. if !\\n[#RUN_ON]=1 \ +. if \\n[#FN_COUNT]>0 .ALD \\n[#FN_SPACE]u +. \} +. if \\n[#REF]=1 \{\ +. if !\\n[#RUN_ON]=1 \{\ +\!. ti +\\n[#REF_FN_INDENT]uu +. \} +. \} +. ie \\n[#FN_LN_BRACKETS]=1 \{\ +. ds $FN_LINENUMBER \h'0+\\n[#FN_INDENT]u'\v'-.085m'\\*[$FN_OPEN_BRACKET]\v'.085m' +. ie \\n[#FN_MARK_2]=\\n[#FN_MARK] \ +. as $FN_LINENUMBER \ +\\n[#FN_MARK]\v'-.085m'\\*[$FN_CLOSE_BRACKET]\v'.085m'\h'.25m' +. el \ +. as $FN_LINENUMBER \ +\\n[#FN_MARK]\v'-.1m'-\v'.1m'\\n[#FN_MARK_2]\v'-.085m'\ +\\*[$FN_CLOSE_BRACKET]\v'.085m'\h'.25m' +. \} +. el \{\ +. ie \\n[#FN_MARK_2]=\\n[#FN_MARK] \ +. ds $FN_LINENUMBER \\n[#FN_MARK]\\*[$FN_LN_SEP] +. el \ +. ds $FN_LINENUMBER \ +\h'0+\\n[#FN_INDENT]u'\\n[#FN_MARK]\v'-.1m'-\v'.1m'\\n[#FN_MARK_2]\\*[$FN_LN_SEP] +. \} +. \} +. if !\\n[#NO_FN_MARKER] \ +. PRINT \\*[$FN_LINENUMBER]\c +. rm $FN_LINENUMBER +. nr #FN_MARK 0 +. \} +. \} +. el \{\ +.\" If INDENT arg is passed to FOOTNOTE, calculate the indent... +. ie '\\$1'INDENT' \{\ +. ev FOOTNOTES +. if '\\$2'L' .in (\\$3) +. if '\\$2'LEFT' .in (\\$3) +. if '\\$2'R' .nr #FN_R_INDENT (\\$3) +. if '\\$2'RIGHT' .nr #FN_R_INDENT (\\$3) +. if '\\$2'B' \{\ +. nr #FN_BL_INDENT (\\$3) +. ie '\\$4'' .nr #FN_BR_INDENT \\n[#FN_BL_INDENT] +. el .nr #FN_BR_INDENT (\\$4) +. in \\n[#FN_BL_INDENT]u +. \} +. if '\\$2'BOTH' \{\ +. nr #FN_BL_INDENT (\\$3) +. ie '\\$4'' .nr #FN_BR_INDENT \\n[#FN_BL_INDENT] +. el .nr #FN_BR_INDENT (\\$4) +. in \\n[#FN_BL_INDENT]u +. \} +. ev +.\" ...then re-run FOOTNOTE without an argument. +. FOOTNOTE +. \} +. el \{\ +. br +.\" Add "defer space" if the previously diverted footnote was the +.\" 1st footnote proper to its page (i.e. it looks like a deferred +.\" footnote but it's really an overflow). +. if \\n[#DIVERTED] \{\ +. if \\n[#PREV_FN_DEFERRED]=1 \{\ +. if \\n[#FN_MARKER_STYLE]=1 .ALD \\n[#FN_LEAD]u +. if \\n[#RESET_FN_NUMBER] .ALD \\n[#FN_LEAD]u +. nr #PREV_FN_DEFERRED 2 +. \} +. \} +. if \\n[#REF]=1 \{\ +\!. in +. \} +.\" Terminate FOOTNOTES or FN_IN_DIVER diversion +. di +. HY_SET 1 \\n[#DIVERSIONS_HY_MARGIN]u (\\n[#PT_SIZE]u/1000u/8u)p +. if \\n[#RESTORE_HY_PARAMS] .hy \\n[#RESTORE_HY_PARAMS] +.\" More housekeeping +.\" Turn off indent possibly set by FOOTNOTE INDENT +. in 0 +. ev +. if \\n[#UNDERLINE_WAS_ON_FN] \{\ +. UNDERLINE +. rr #UNDERLINE_WAS_ON_FN +. \} +.\" Restore sentence spacing +. if \\n[#PRINT_STYLE]=2 \{\ +. if d $RESTORE_SS_VAR .SS \\*[$RESTORE_SS_VAR] +. rm $RESTORE_SS_VAR +. \} +. rr #FN_R_INDENT +. rr #FN_BR_INDENT +. nr #PP_STYLE \\n[#PP_STYLE_PREV] +. if !\\n[#INDENT_FIRSTS] .INDENT_FIRST_PARAS OFF +. rr #INDENT_FIRSTS +.\" Calculate footnote depth, but not if #COUNTERS_RESET (created in +.\" DIVER_FN_1_PRE) to instruct FOOTNOTES to skip this step for now +.\" (it's taken care of when FN_IN_DIVER is output into FOOTNOTES in +.\" PROCESS_FN_IN_DIVER). +. ie r#COUNTERS_RESET .rr #COUNTERS_RESET +. el \{\ +. nr #GET_DEPTH 1 +.\" If the footnote is the 1st on the page and it falls too close +.\" to the bottom margin, defer the footnote text to the next page... +. if (\\n[#SPACE_REMAINING]-1)<=(\\n[.v]) \{\ +.\" ...but not if PROCESS_FN_LEFTOVER has set #PREV_FN_DEFERRED to 1 +. if !\\n[#PREV_FN_DEFERRED]=1 \{\ +. nr #FN_DEFER 1 +. nr #FN_DEPTH +\\n[#DIVER_DEPTH] +. rr #GET_DEPTH +.\" This is required so that the defer space clause can distinguish +.\" a real #FN_COUNT=1 from one generated if FOOTNOTE is run inside +.\" QUOTE, BLOCKQUOTE or EPIGRAPH +. if \\n[#DIVER_FN]=2 \{\ +. nr #SAVED_DIVER_FN_COUNT \\n[#FN_COUNT] +. rr #DIVER_FN +. \} +. \} +. \} +.\" Calculate the footnote depth. +. if \\n[#GET_DEPTH]=1 \{\ +.\" Save the previous footnote depth (for use when there will be +.\" some overflowed footnote text). +. nr #SAVED_FN_DEPTH_1 \\n[#FN_DEPTH] +.\" Add the depth of the current footnote to any already existent +.\" footnotes. +. nr #FN_DEPTH +\\n[#DIVER_DEPTH] +.\" Special handling for run-on footnotes +. if \\n[#RUN_ON]=1 \{\ +. if \\n[#RUNON_FOOTNOTES] .unformat RUNON_FOOTNOTES +. if \\n[#RUNON_FN_IN_DIVER] .unformat RUNON_FN_IN_DIVER +. ev FOOTNOTES +.\" Recreate FOOTNOTES with rule followed by text of unformatted +.\" run-on footnotes. +. di FOOTNOTES +. ie \\n[#FN_RULE]=0 .RLD 1v +. el \{\ +\v'-\\n[#FN_RULE_ADJ]u-\\n[#FN_RULE_WEIGHT_ADJ]u'\ +\D't \\n[#FN_RULE_WEIGHT]'\ +\h'-\\n[#FN_RULE_WEIGHT]u'\ +\D'l \\n[#FN_RULE_LENGTH]u 0'\ +\v'+\\n[#FN_RULE_ADJ]u+\\n[#FN_RULE_WEIGHT_ADJ]u' +. \} +. br +. if \\n[#RUNON_FOOTNOTES] \{\ +. RUNON_FOOTNOTES +. rr #RUNON_FOOTNOTES +. \} +. if \\n[#RUNON_FN_IN_DIVER] \{\ +. RUNON_FN_IN_DIVER +. rr #RUNON_FN_IN_DIVER +. \} +. br +. di +. ev +. nr #FN_DEPTH \\n[#DIVER_DEPTH] +. nr #SAVED_VFP 0+\\n[#VARIABLE_FOOTER_POS] +. nr #VARIABLE_FOOTER_POS 0-\\n[#B_MARGIN]u +. \} +.\" Save the new depth +. nr #SAVED_FN_DEPTH_2 \\n[#FN_DEPTH] +.\" Signal that defer space should be added when PROCESS_FN_LEFTOVER +.\" processes deferred footnotes. +. if \\n[#FN_DEFER] \{\ +. if \\n[#FN_COUNT]=2 \{\ +. ie \\n[#COLUMNS] \{\ +. if !\\n[#FROM_FOOTER] \{\ +. if \\n[#FN_DEFER]=1 .nr #FN_DEFER_SPACE 1 +. if \\n[#FN_COUNT_FOR_COLS]>=1 .rr #FN_DEFER_SPACE +. if \\n[#FROM_HEADER] .nr #FN_DEFER_SPACE 1 +. \} +. \} +. el .nr #FN_DEFER_SPACE 1 +. \} +. rr #FN_DEFER +. \} +.\" If the depth of the whole footnote won't fit in the space +.\" between where we are on the page and the bottom margin, calculate +.\" how much of it will fit. +. if \\n[#FN_DEPTH]>\\n[#SPACE_REMAINING] \{\ +. nr #FN_LINES 0 1 +. while (\\n+[#FN_LINES]*\\n[#FN_LEAD])<\\n[#SPACE_REMAINING] \{\ +. nr #FN_DEPTH (\\n[#FN_LINES]*\\n[#FN_LEAD]) +. \} +. nr #VFP_DIFF \\n[#FN_DEPTH]-\\n[#SAVED_FN_DEPTH_1] +. nr #OVERFLOW 1 +.\" Very occasionally, #VFP_DIFF, on a 1st footnote that isn't to +.\" be deferred, comes up with a depth equal to exactly 1 line +.\" of footnotes, i.e. enough room to print the rule and nothing +.\" else. The following tests for such a condition, and rather than +.\" attempting to treat the footnote as an overflow, it tells mom to +.\" treat it as a special kind of deferred footnote (#FN_DEFER 2). +. if \\n[#SAVED_FN_DEPTH_1]=0 \{\ +. if \\n[#FN_DEPTH]=\\n[#FN_LEAD] \{\ +. nr #FN_DEFER 2 +. nr #FN_DEPTH \\n[#SAVED_FN_DEPTH_2] +. rr #OVERFLOW +. \} +. \} +. \} +.\" Calculate VFP based on whether the footnote overflows, or is to +.\" be treated normally. +. ie \\n[#OVERFLOW]=1 \{\ +. if \\n[#RUN_ON] \{\ +. rr #VARIABLE_FOOTER_POS +. nr #VARIABLE_FOOTER_POS \\n[#SAVED_VFP] +. \} +. ie \\n[#FN_COUNT]=1 \{\ +. ie \\n[#RULED]=1 \{\ +. ie \\n[#COLUMNS]=1 \{\ +. ie \\n[#COL_NUM]=\\n[#NUM_COLS] \{\ +. ie \\n[#FROM_FOOTER] \{\ +. ie \\n[#FN_COUNT_FOR_COLS]>1 \{\ +. nr #FN_DEPTH -\\n[#FN_DEPTH] +. if \\n[#DIVERTED]=1 .nr #DIVERTED 3 +. if !\\n[#PREV_FN_DEFERRED]=1 \ +. nr #FN_DEPTH -\\n[#VFP_DIFF] +. \} +. el \{\ +. nr #VARIABLE_FOOTER_POS -\\n[#FN_DEPTH] +. if \\n[#DIVERTED]=1 .nr #DIVERTED 3 +. \} +. \} +. el .nr #VARIABLE_FOOTER_POS -(\\n[#FN_DEPTH]) +. \} +. el .nr #VARIABLE_FOOTER_POS -(\\n[#FN_DEPTH]) +. \} +. el .nr #VARIABLE_FOOTER_POS -(\\n[#FN_DEPTH]) +. \} +. el \{\ +. nr #VARIABLE_FOOTER_POS -\\n[#VFP_DIFF] +. if \\n[#DIVERTED]=1 .nr #DIVERTED 3 +. if !\\n[#PREV_FN_DEFERRED]=1 \{\ +. ie \\n[#COLUMNS]=1 \ +. if !\\n[#FROM_FOOTER] . +. el .nr #FN_DEPTH -\\n[#VFP_DIFF] +. \} +. if \\n[#DIVERTED]=3 \{\ +. if !\\n[#PREV_FN_DEFERRED] \{\ +. if !\\n[#FROM_FOOTER] \{\ +. if \\n[#FN_COUNT]=1 \{\ +. if !\\n[#VFP_DIFF] \{\ +. if \\n[#FN_MARKER_STYLE]=1 \{\ +. da FOOTNOTES +\!. ALD \\n[#FN_LEAD]u +. di +. \} +. if \\n[#RESET_FN_NUMBER] \{\ +. da FOOTNOTES +\!. ALD \\n[#FN_LEAD]u +. di +. \} +. \} +. \} +. \} +. \} +. \} +. \} +. nr #FN_DEPTH \\n[#SAVED_FN_DEPTH_1]+\\n[#VFP_DIFF] +. \} +. el \{\ +. nr #VARIABLE_FOOTER_POS -\\n[#VFP_DIFF] +. nr #FN_DEPTH \\n[#SAVED_FN_DEPTH_1]+\\n[#VFP_DIFF] +. \} +. rr #OVERFLOW +. rr #RULED +. \} +. el \{\ +. nr #VARIABLE_FOOTER_POS -\\n[#DIVER_DEPTH] +. if \\n[#PREV_FN_DEFERRED]=1 \{\ +. if \\n[#DIVERTED] \{\ +. if !\\n[#FN_DEPTH]=\\n[#SAVED_FN_DEPTH_1] \{\ +. nr #FN_DEPTH +\\n[#FN_LEAD] +. nr #VARIABLE_FOOTER_POS -\\n[#FN_LEAD] +. rr #PREV_FN_DEFERRED +. \} +. \} +. \} +. if \\n[#FN_COUNT]>1 \{\ +. nr #NO_BACK_UP 1 +. rr #DIVERTED +. rr #RULED +. \} +. \} +. \} +. \} +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u +.\" If we have a footnote whose text has to be deferred to the next +.\" page, reset the FOOTER trap to its original location. +. if \\n[#FN_DEFER] \{\ +. nr #VARIABLE_FOOTER_POS 0-\\n[#B_MARGIN]u +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u +. \} +. \} +. nr #NO_FN_MARKER 0 +. \} +. if \\n[#NUM_ARGS]=2 \{\ +. if '\\$2'BREAK' .BR +. if '\\$2'BR' .BR +. \} +.END +\# +\# Utility macros to manage footnotes that occur inside diversions +\# --------------------------------------------------------------- +\# +\# There are some redundancies here; they're left in in case unforeseen +\# footnote situations crop up in the future that might require +\# manipulation of them. +\# +\# 1. Pre-footnote processing for footnotes in diversions +\# +\# a) A footnote inside a diversion will be moved entirely (marker +\# in running text and text of footnote) to the next page/column. +\# +.MAC DIVER_FN_1_PRE END +. nr #RESET_FN_COUNTERS 1 +. nr #COUNTERS_RESET 1 +. if \\n[#DONE_ONCE]=1 \{\ +. if \\n[#FN_DEFER] \{\ +. if \\n[#SAVED_DIVER_FN_COUNT]=1 \{\ +. ie \\n[#COLUMNS]=1 \ +. if \\n[#COL_NUM]=\\n[#NUM_COLS] .nr #FN_DEFER_SPACE 1 +. el .nr #FN_DEFER_SPACE 1 +. \} +. \} +. if \\n[#FN_MARKER_STYLE]=1 \{\ +. if \\n[#FN_COUNT]>0 .nr #FN_COUNT 0 1 +. if \\n[#COLUMNS]=1 \ +. if \\n[#COL_NUM]=\\n[#NUM_COLS] .nr #FN_COUNT_FOR_COLS 0 1 +. \} +. if \\n[#FN_MARKER_STYLE]=2 \{\ +. if \\n[#RESET_FN_NUMBER]=1 \{\ +. ie \\n[#COLUMNS]=1 \ +. if \\n[#COL_NUM]=\\n[#NUM_COLS] .nr #FN_NUMBER 0 1 +. el .nr #FN_NUMBER 0 1 +. \} +. \} +. \} +.END +\# +\# b) Treat as a normal footnote, including defers. +\# +.MAC DIVER_FN_2_PRE END +. nr #RESET_FN_COUNTERS 2 +.END +\# +\# 2. Post-footnote processing for footnotes in diversions +\# +\# Even when a footnote inside a diversion is treated as +\# "normal," some manipulation of registers is required. The +\# macro is called in DO_QUOTE (i.e. at the termination of +\# quotes and blockquotes) and in DO_EPIGRAPH. +\# +.MAC DIVER_FN_2_POST END +. if \\n[#DONE_ONCE]=1 \{\ +. if \\n[#FN_MARKER_STYLE]=1 \{\ +. if \\n[#FN_COUNT]=0 .nr #DONT_RULE_ME 1 +. if \\n[#FN_COUNT]>0 .nr #FN_COUNT 0 1 +. if \\n[#COLUMNS]=1 \{\ +. if \\n[#COL_NUM]=\\n[#NUM_COLS] .nr #FN_COUNT_FOR_COLS 0 1 +. if !\\n[#COL_NUM]=\\n[#NUM_COLS] . +. \} +. \} +. if \\n[#FN_MARKER_STYLE]=2 \{\ +. if \\n[#FN_COUNT]=0 .nr #DONT_RULE_ME 1 +. if \\n[#FN_COUNT]>0 .nr #FN_COUNT 0 1 +. if \\n[#RESET_FN_NUMBER]=1 \{\ +. ie \\n[#COLUMNS]=1 \ +. if \\n[#COL_NUM]=\\n[#NUM_COLS] .nr #FN_NUMBER 0 1 +. el .nr #FN_NUMBER 0 1 +. \} +. \} +. \} +.END +\# +\# The main macros that handle footnote processing. +\# ----------------------------------------------- +\# +\# FN_OVERFLOW_TRAP starts off "underneath" FOOTER, but is revealed +\# as #VARIABLE_FOOTER_POSITION changes the position of FOOTER. +\# FN_OVERFLOW_TRAP simply starts diversion FN_OVERFLOW to "catch" +\# the overflow. The diversion is ended in FOOTER, immediately after +\# FOOTER outputs the diversion, FOOTNOTES, before PROCESS_FN_LEFTOVER +\# is run (either in HEADER, or in FOOTER if moving col to col). +\# +.MAC FN_OVERFLOW_TRAP END +. if \\n[#FN_COUNT] \{\ +. di FN_OVERFLOW +. ie !\\n[#NO_BACK_UP]=1 \{\ +. if \\n[#PREV_FN_DEFERRED] \{\ +. ie \\n[#COLUMNS]=1 \{\ +. if \\n[#FROM_FOOTER] \{\ +. if \\n[#PREV_FN_DEFERRED] \{\ +. if !\\n[#COL_NUM]=\\n[#NUM_COLS] \ +. rr #PREV_FN_DEFERRED +. \} +. \} +. if !\\n[#FROM_FOOTER] \{\ +. if !\\n[#COL_NUM]=\\n[#NUM_COLS] \{\ +. if !\\n[#LAST_FN_COUNT_FOR_COLS]>1 \{\ +\!. RLD \\n[#FN_LEAD]u +. \} +. \} +. \} +. \} +. el \{\ +\!. RLD \\n[#FN_LEAD]u +. \} +. \} +. \} +. el \{\ +. rr #NO_BACK_UP +. rr #PREV_FN_DEFERRED +. \} +. \} +.\" When #FROM_DIVERT_FN is 1, it signals to FOOTNOTE, when run from +.\" within DIVERT_FN_LEFTOVER, to set #SPACE_REMAINING to the total +.\" area allowable for running text. +. nr #FROM_DIVERT_FN 1 +.END +\# +\# PROCESS_FN_LEFTOVER is called at the top of HEADER, and in +\# FOOTER if we're moving from one column to the next (i.e. after +\# outputting FOOTNOTES). It checks for whether we have a "deferred +\# footnote" situation, and resets counters and number registers +\# accordingly. Lastly, if we have some footnote overflow, it calls +\# DIVERT_FN_LEFTOVER. +\# +.MAC PROCESS_FN_LEFTOVER END +. if \\n[#PREV_FN_DEFERRED]=2 \ +. if \\n[#FN_COUNT_AT_FOOTER]>1 .rr #PREV_FN_DEFERRED +. ie !\\n[#FN_DEFER] \{\ +. nr #FN_COUNT 0 1 +. nr #FN_DEPTH 0 +. nr #VARIABLE_FOOTER_POS 0-\\n[#B_MARGIN] +. \} +. el \{\ +. if \\n[#FN_DEFER]=1 .nr #VARIABLE_FOOTER_POS 0-\\n[#B_MARGIN] +. if \\n[#FN_DEFER]=2 \{\ +. nr #FN_DEPTH 0 +. nr #VARIABLE_FOOTER_POS 0-\\n[#B_MARGIN] +. \} +. \} +. nr #SPACE_REMAINING 0 +. ch FOOTER -\\n[#B_MARGIN]u +. if \\n[#FN_DEFER] \{\ +. nr #NO_FN_MARKER 1 +. rn FOOTNOTES DEFERRED-FOOTNOTE +. nr #FN_DEPTH 0 +. FOOTNOTE +. nf +. DEFERRED-FOOTNOTE +. FOOTNOTE OFF +. ie \\n[#COLUMNS]=1 \{\ +. if \\n[#COL_NUM]=\\n[#NUM_COLS] \{\ +. if !\\n[#FROM_FOOTER] \ +. if \\n[#FN_COUNT_FOR_COLS]=1 .nr #PREV_FN_DEFERRED 1 +. \} +. \} +. el .nr #PREV_FN_DEFERRED 1 +. \} +. if !\\n[#FN_DEFER] \ +. if \\n[#FN_OVERFLOW_DEPTH] .DIVERT_FN_LEFTOVER +. ie \\n[#COLUMNS]=1 \{\ +. if \\n[#COL_NUM]>1 \ +. if \\n[#COL_NUM]=\\n[#NUM_COLS] .nr #FN_COUNT 0 1 +. \} +. el .nr #FN_COUNT 0 1 +. if \\n[#DIVER_FN]=2 .rr #DIVER_FN +. rr #FROM_DIVERT_FN +.END +\# +\# DIVERT_FN_LEFTOVER is called in PROCESS_FN_LEFTOVER (at +\# the top of HEADER, and in FOOTER if we're moving from one column +\# to the next). +\# +.MAC DIVERT_FN_LEFTOVER END +. nr #NO_FN_MARKER 1 +. nr #DIVERTED 1 +. FOOTNOTE +. nf +. FN_OVERFLOW +. FOOTNOTE OFF +. if \\n[#PREV_FN_DEFERRED] \{\ +. nr #FN_DEPTH -\\n[#FN_LEAD] +. nr #VARIABLE_FOOTER_POS +\\n[#FN_LEAD] +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u +. if \\n[#PREV_FN_DEFERRED]=2 \{\ +. nr #PREV_FN_DEFERRED 1 +. rr #DIVERTED +. \} +. \} +. rr #FN_OVERFLOW_DEPTH +.END +\# +\# This is a special macro to deal with footnotes that are set inside +\# diversions (QUOTE, BLOCKQUOTE and EPIGRAPH). It's called in HEADER +\# (and in FOOTER, if we're moving from column to column), and comes +\# after PROCESS_FOOTNOTE_LEFTOVER in those two macros. +\# +.MAC PROCESS_FN_IN_DIVER END +. nr #SPACE_REMAINING 0 +. ch FOOTER -\\n[#B_MARGIN]u +. nr #NO_FN_MARKER 1 +. if !\\n[#RESET_FN_COUNTERS]=2 .rr #RESET_FN_COUNTERS +. FOOTNOTE +. if \\n[#FN_OVERFLOW_DEPTH] .nf +. ie dRUNON_FN_IN_DIVER \{\ +. RUNON_FN_IN_DIVER +. rm RUNON_FN_IN_DIVER +. \} +. el \{\ +. nf +. FN_IN_DIVER +. \} +. FOOTNOTE OFF +. rr #DIVER_FN +.END +\# +\# ==================================================================== +\# +\# +++ENDNOTES+++ +\# +\# When endnotes are output, the spacing between the notes is always +\# 1 extra linespace. This can have bottom margin consequences. If +\# this doesn't bother you, don't worry about it. If it does bother +\# you, and you want to adjust the spacing between any two endnotes (as +\# they're output), make the spacing adjustments (.ALD/.RLD) at the +\# *end* of endnotes (i.e. just before .ENDNOTE OFF), not at the top. +\# +\# Endnotes must be output manually with .ENDNOTES. This allows user +\# the flexibility to output endnotes at the end of each collated +\# document, or to output them at the end of the entire document. +\# +\# Control macros +\# -------------- +\# +\# ENDNOTE POINT SIZE +\# ------------------ +\# *Argument: +\# +\# *Function: +\# Creates or modifies register #EN_PS. +\# *Notes: +\# Default is same as running text in body of document. +\# +\# This size control macro differs from other size control macros +\# in that it sets an absolute point size, not a relative one. This +\# is because a) endnotes always appear separate from the body of +\# a document and therefore don't need to be relative to the body +\# of the document, and b) there are quite a few elements of the +\# endnotes page(s) that need to be relative to the base point size +\# of that page. If the base endnote point size were relative to +\# the body of the document (i.e. a _SIZE macro taking a +|- value) +\# getting the rest of the endnote elements sized properly could +\# become very confusing. +\# +.MAC ENDNOTE_PT_SIZE END +. nr #EN_PS (p;\\$1) +.END +\# +\# ENDNOTE SPACING +\# ---------------- +\# *Arguments: +\# | +\# *Function: +\# Enables space between endnotes items. +\# *Notes: +\# Default is no space. +\# +.MAC ENDNOTE_SPACING END +. ie \B'\\$1' .ds $EN_SPACE \\$1 +. el .rm $EN_SPACE +.END +\# +\# ENDNOTES_HDRFTR_CENTER +\# ---------------------- +\# *Argument: +\# toggle +\# *Function: +\# Creates or removes toggle register #EN_HDRFTR_CENTER, used to +\# determine whether mom should print a/the hdrftr center string +\# on the endnotes page. Primarily to enable/disable printing of the +\# chapter name in hdrftrs when DOCTYPE CHAPTER. +\# *Notes: +\# Default is OFF +\# +.MAC ENDNOTES_HDRFTR_CENTER END +. ie '\\$1'' .nr #EN_HDRFTR_CENTER 1 +. el .rr #EN_HDRFTR_CENTER +.END +\# +\# ENDNOTE STRING +\# -------------- +\# *Argument: +\# +\# *Function: +\# Creates or modifies string $EN_STRING. +\# *Notes: +\# Default is "Endnotes" +\# +.MAC ENDNOTES_HEADER_STRING END +. ds $EN_STRING \\$1 +.END +. +.ALIAS ENDNOTE_STRING ENDNOTES_HEADER_STRING +\# +\# ENDNOTE STRING START POSITION +\# ---------------------------- +\# *Argument: +\# <distance from page top> +\# *Function: +\# Creates or modifies register #EN_STRING_V_POS +\# +.MAC ENDNOTES_HEADER_V_POS END +. nr #EN_STRING_V_POS (\\$1) +.END +. +.ALIAS ENDNOTE_STRING_ADVANCE ENDNOTES_HEADER_V_POS +.ALIAS ENDNOTE_STRING_V_POS ENDNOTES_HEADER_V_POS +.ALIAS ENDNOTES_HEADER_V_POS ENDNOTES_HEADER_V_POS +\# +\# ENDNOTE HEADER CAPS and SMALLCAPS +\# --------------------------------- +\# *Arguments: +\# <none> | <anything> +\# *Function: +\# Turns capitalization or smallcaps style of the endnotes pages +\# title string "Endnotes" on or off. +\# *Notes: +\# Users may want the endnotes pages title string to be in +\# caps, but the toc entry for endnotes in lower case. If the +\# argument to ENDNOTES_HEADER_STRING is in lower case and +\# ENDNOTES_HEADER_CAPS is turned on, this is exactly what will +\# happen. Ditto for smallcaps. +\# +\# Default for CAPS is on. +\# +.MAC ENDNOTES_HEADER_CAPS END +. ie '\\$1'' .nr #EN_STRING_CAPS 1 +. el .nr #EN_STRING_CAPS 0 +.END +. +.ALIAS ENDNOTE_STRING_CAPS ENDNOTES_HEADER_CAPS +. +.MAC ENDNOTES_HEADER_SMALLCAPS END +. ie '\\$1'' .nr #EN_STRING_SMALLCAPS 1 +. el .nr #EN_STRING_SMALLCAPS 0 +.END +. +.ALIAS ENDNOTE_STRING_SMALLCAPS ENDNOTES_HEADER_SMALLCAPS +\# +\# ENDNOTE TITLE +\# ------------- +\# *Argument: +\# <string that appears before the first endnote pertaining to any document> +\# *Function: +\# Creates string $EN_TITLE. +\# *Notes: +\# Default is the document title, or, if doc is a chapter, "Chapter #" +\# +.MAC ENDNOTE_TITLE END +. ds $EN_TITLE \\$1 +.END +\# +\# ENDNOTE MARKER STYLE +\# -------------------- +\# *Arguments: +\# NUMBER | LINE | SUPERSCRIPT +\# *Function: +\# Sets register #EN_MARKER_STYLE, used in ENDNOTE to determine +\# the style of endnote markers (labels). +\# *Notes: +\# 1=NUMBER; 2=LINE. LINE means "use output line numbers". +\# Default is NUMBER. +\# +.MAC ENDNOTE_MARKER_STYLE END +. if '\\$1'NUMBER' .nr #EN_MARKER_STYLE 1 +. if '\\$1'LINE' \{\ +. nr #EN_MARKER_STYLE 2 +. if !\\n[#EN_LN_SEP] \ +. if !\\n[#EN_LN_BRACKETS] .ENDNOTE_LINENUMBER_BRACKETS SQUARE +. \} +. if '\\$1'SUPERSCRIPT' .nr #EN_MARKER_STYLE 3 +.END +\# +\# ENDNOTE LINENUMBER MARK +\# ----------------------- +\# *Function: +\# This string, when called inline, stores the current output line +\# number in register #EN_MARK for use with ENDNOTE. +\# +.ds EN_MARK \R'#EN_MARK \En[ln]' +\# +\# ENDNOTE LINENUMBER SEPARATOR +\# ---------------------------- +\# *Argument: +\# <user-defined separator> +\# *Function: +\# Stores user-defined separator (for use then +\# ENDNOTE_MARKER_STYLE is LINE) in string $EN_LN_SEP. The +\# separator is intended to be used when the user wishes a +\# separator, rather than the choice of brackets offered by +\# ENDNOTE_LINENUMBER_BRACKETS. +\# +.MAC ENDNOTE_LINENUMBER_SEPARATOR END +. rr #EN_LN_BRACKETS +. nr #EN_LN_SEP 1 +. ds $EN_LN_SEP "\\$1 +.END +\# +\# ENDNOTE LINENUMBER BRACKETS +\# --------------------------- +\# *Argument: +\# PARENS | SQUARE | BRACES or ( | [ | { +\# *Function: +\# Sets register #EN_LN_BRACKETS to 1, and creates strings +\# $EN_OPEN_BRACKET and $EN_CLOSE_BRACKET according to the given argument. +\# +.MAC ENDNOTE_LINENUMBER_BRACKETS END +. rr #EN_LN_SEP +. nr #EN_LN_BRACKETS 1 +. if '\\$1'PARENS' \{\ +. ds $EN_OPEN_BRACKET ( +. ds $EN_CLOSE_BRACKET ) +. \} +. if '\\$1'(' \{\ +. ds $EN_OPEN_BRACKET ( +. ds $EN_CLOSE_BRACKET ) +. \} +. if '\\$1'SQUARE' \{\ +. ds $EN_OPEN_BRACKET [ +. ds $EN_CLOSE_BRACKET ] +. \} +. if '\\$1'[' \{\ +. ds $EN_OPEN_BRACKET [ +. ds $EN_CLOSE_BRACKET ] +. \} +. if '\\$1'BRACES' \{\ +. ds $EN_OPEN_BRACKET { +. ds $EN_CLOSE_BRACKET } +. \} +. if '\\$1'{' \{\ +. ds $EN_OPEN_BRACKET { +. ds $EN_CLOSE_BRACKET } +. \} +.END +\# +\# ENDNOTE LINENUMBER GAP +\# ---------------------- +\# *Argument: +\# <space between line-number labels and endnotes text> +\# *Function: +\# Defines string $EN_LN_GAP, used during printing of line-number +\# labels in ENDNOTE. +\# +.MAC ENDNOTE_LINENUMBER_GAP END +. nr #EN_LN_GAP (u;\\$1) +.END +\# +\# ENDNOTE NUMBERS ALIGNMENT +\# ------------------------- +\# *Argument: +\# LEFT | RIGHT <max. number of digit placeholders that will appear in endnotes> +\# *Function: +\# Creates registers for _LEFT or _RIGHT; creates register +\# #EN_NUMBER_PLACEHOLDERS. +\# *Notes: +\# Default is for endnote numbers to be right aligned to 2 placeholders. +\# +.MAC ENDNOTE_NUMBERS_ALIGN END +. if '\\$1'LEFT' \{\ +. rr #EN_NUMBERS_ALIGN_RIGHT +. nr #EN_NUMBERS_ALIGN_LEFT 1 +. \} +. if '\\$1'RIGHT' \{\ +. rr #EN_NUMBERS_ALIGN_LEFT +. nr #EN_NUMBERS_ALIGN_RIGHT 1 +. \} +. nr #EN_NUMBER_PLACEHOLDERS \\$2 +.END +\# +\# ENDNOTE PARAGRAPH INDENT +\# ------------------------ +\# *Argument: +\# <first line indent of paras subsequent to 1st in endnotes> +\# *Function: +\# Creates register #EN_PP_INDENT for use in .PP. +\# *Notes: +\# Requires a unit of measure. +\# +\# Default is 1.5m for TYPESET; same indent as PARA_INDENT for TYPEWRITE. +\# +.MAC ENDNOTE_PARA_INDENT END +. nr #EN_PP_INDENT (\\$1) +.END +\# +\# TURN OFF COLUMN MODE FOR ENDNOTES +\# --------------------------------- +\# *Argument: +\# <none> | <anything> +\# *Function: +\# Creates or removes register #EN_NO_COLS +\# *Notes: +\# Allows user to tell mom not to set endnotes in columnar +\# documents in columns. Default is to set endnotes in columns. +\# +.MAC ENDNOTES_NO_COLUMNS END +. ie '\\$1'' .nr #EN_NO_COLS 1 +. el .rr #EN_NO_COLS +.END +\# +\# NO FIRST PAGE NUMBER ON ENDNOTES FIRST PAGE +\# ------------------------------------------- +\# *Argument: +\# <none> | <anything> +\# *Function: +\# Creates or removes register #EN_NO_FIRST_PN +\# *Notes: +\# For use if FOOTERS are on. Tells ENDNOTES not to put a page +\# number on the first endnotes page. Some users may want this. +\# Default is to print a page number at the top of the first +\# endnotes page when footers are on. +\# +.MAC ENDNOTES_NO_FIRST_PAGENUM END +. ie '\\$1'' .nr #EN_NO_FIRST_PN 1 +. el .rr #EN_NO_FIRST_PN +.END +\# +\# PAGE HEADERS ON ENDNOTES PAGES +\# ------------------------------ +\# *Argument: +\# <none> | ALL +\# *Function: +\# Creates or removes register #EN_ALLOWS_HEADERS or +\# #EN_ALLOWS_HEADERS_ALL +\# *Notes: +\# Whether ENDNOTES puts a page header at the top of endnotes +\# pages if page headers are used throughout the document. +\# Default is to insert the page headers, but not on the first +\# page. If the optional argument ALL is given, ENDNOTES puts a +\# page header on the first page as well. +\# +.MAC ENDNOTES_ALLOWS_HEADERS END +. ie '\\$1'' .nr #EN_ALLOWS_HEADERS 1 +. el \{\ +. ie '\\$1'ALL' \{\ +. nr #EN_ALLOWS_HEADERS 1 +. nr #EN_ALLOWS_HEADERS_ALL 1 +. \} +. el \{\ +. nr #EN_ALLOWS_HEADERS 0 +. nr #EN_ALLOWS_HEADERS_ALL 0 +. \} +. \} +.END +\# +\# ENDNOTES PAGES PAGE NUMBERING STYLE +\# ----------------------------------- +\# *Argument: +\# DIGIT | ROMAN | roman | ALPHA | alpha +\# *Function: +\# Creates or modifies $EN_PN_STYLE. +\# *Notes: +\# Allows user to define what style should be used for endnotes +\# pages page numbering. Arguments are the same as for +\# PAGENUM_STYLE. +\# +\# Default is DIGIT. +\# +.MAC ENDNOTES_PAGENUM_STYLE END +. ds $EN_PN_STYLE \\$1 +.END +\# +\# FIRST PAGE NUMBER FOR ENDNOTES +\# ------------------------------ +\# *Argument: +\# <page number that appears on page 1 of endnotes pages> +\# *Function: +\# Creates or modifies string $EN_FIRST_PN +\# *Notes: +\# To be used with caution, only if all endnotes +\# are to be output at once, i.e. not at the end of the separate +\# docs of a collated doc +\# +.MAC ENDNOTES_FIRST_PAGENUMBER END +. nr #EN_FIRST_PN \\$1 +.END +\# +\# SINGLESPACE ENDNOTES +\# -------------------- +\# *Argument: +\# <none> | <anything> +\# *Function: +\# Sets lead of endnotes pages in TYPEWRITE to 12 points, +\# adjusted. +\# *Notes: +\# Default is to double-space endnotes pages. +\# +.MAC SINGLESPACE_ENDNOTES END +. if \\n[#PRINT_STYLE]=1 \{\ +. ie \\n[#SINGLE_SPACE] \{\ +. nr #EN_SINGLESPACE 1 +. rr #IGNORE +. if \\n[#OK_PROCESS_LEAD] \{\ +. ENDNOTE_LEAD 12 ADJUST +. nr #IGNORE 1 +. \} +. \} +. el \{\ +. ie '\\$1'' \{\ +. nr #EN_SINGLESPACE 1 +. rr #IGNORE +. if \\n[#OK_PROCESS_LEAD] \{\ +. ENDNOTE_LEAD 12 ADJUST +. nr #IGNORE 1 +. \} +. \} +. el \{\ +. rr #EN_SINGLESPACE +. rr #IGNORE +. if \\n[#OK_PROCESS_LEAD] \{\ +. ENDNOTE_LEAD 24 ADJUST +. nr #IGNORE 1 +. \} +. \} +. \} +. \} +.END +\# +\# ENDNOTE PARAGRAPH SPACE +\# ----------------------- +\# *Argument: +\# toggle +\# *Function: +\# Creates toggle register #EN_PP_SPACE for use in .PP. +\# *Notes: +\# Like PARA_SPACE. Default is not to space endnote paras. +\# +.MAC ENDNOTE_PARA_SPACE END +. ie '\\$1'' .nr #EN_PP_SPACE 1 +. el .rr #EN_PP_SPACE +.END +\# +\# ENDNOTE +\# ------- +\# *Argument: +\# toggle +\# *Function: +\# Places superscript endnote number in text, then collects and +\# processes endnote in diversion END_NOTES. +\# *Notes: +\# \c must be appended to the word immediately preceding .ENDNOTE +\# when ENDNOTE_MARKER_STYLE is NUMBER. +\# +.MAC ENDNOTE END +. ie '\\$1'' \{\ +. nr #ENDNOTE 1 +. ie !\\n[#EN_MARKER_STYLE]=2 \{\ +. if \\n[#CONDENSE] .nop \*[CONDX]\c +. if \\n[#EXTEND] .nop \*[EXTX]\c +. if \\n[#UNDERLINE_ON] \{\ +. nr #UNDERLINE_WAS_ON 1 +. UNDERLINE OFF +. \} +. if \\n[#PRINT_STYLE]=1 \{\ +. if \\n[#SLANT_ON] \{\ +. nr #SLANT_WAS_ON 1 +. nop \*[SLANTX]\c +. \} +.\" Vertical raise amount here is more than when the same string is printed in +.\" the endnotes so bottom of number aligns with top of bowl. +. PRINT \ +"\s-2\v'-\\n[#DOC_LEAD]u/5u'\\n+[#EN_NUMBER]\v'+\\n[#DOC_LEAD]u/5u'\s+2\c" +. \} +. if \\n[#PRINT_STYLE]=2 .PRINT \*[SUP]\\n+[#EN_NUMBER]\*[SUPX]\c +. \} +. el \{\ +. ie r#EN_NUMBER .nr #EN_NUMBER \\n[#EN_NUMBER]+1 +. el .nr #EN_NUMBER 1 1 +. if !\\n[#LINENUMBERS] \{\ +. tm1 "[mom]: Line numbering must be enabled with NUMBER_LINES when +. tm1 " ENDNOTE_MARKER_STYLE is LINE. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. if \\n[#EN_MARK]=0 .nr #EN_MARK \\n[ln] +. nr #EN_MARK_2 \\n[ln] +. if '\\n[.z]'P_QUOTE' \{\ +. nr #EN_MARK -1 +. nr #EN_MARK_2 -1 +. \} +. \} +. nr #PP_STYLE_PREV \\n[#PP_STYLE] +. nr #PP_STYLE 1 +. if \\n[#INDENT_FIRST_PARAS] .nr #INDENT_FIRSTS 1 +. INDENT_FIRST_PARAS +. ev EN +. da END_NOTES +. LL \\n[#DOC_L_LENGTH]u +. ta \\n[.l]u +. if \\n[#COLUMNS] \{\ +. ie \\n[#EN_NO_COLS] .LL \\n[#DOC_L_LENGTH]u +. el .LL \\n[#COL_L_LENGTH]u +. ta \\n[.l]u +. \} +\!. if \\\\n[.vpt]=0 .vpt +\!. ne 3 +. vs \\n[#EN_LEAD]u +.\" Print identifying doc title (e.g., Chapter n) +. if \\n[#EN_NUMBER]=1 \{\ +. if \\n[#PRINT_STYLE]=1 .TYPEWRITER +. if \\n[#PRINT_STYLE]=2 \{\ +. FAMILY \\*[$EN_TITLE_FAM] +. FT \\*[$EN_TITLE_FT] +. ps \\n[#EN_PS]u\\*[$EN_TITLE_SIZE_CHANGE] +. if \\n[#EN_TITLE_COLOR] .COLOR \\*[$EN_TITLE_COLOR] +. if \\n[#ENDNOTE_TITLE_SMALLCAPS] .SMALLCAPS +. if \\n[#ENDNOTE_TITLE_CAPS] .CAPS +. \} +. ie \\n[#SINGLE_SPACE]=1 .sp 2 +. el .sp +. if !'\\*[$EN_TITLE]'' \{\ +. substring $EN_TITLE_QUAD 0 0 +. if '\\*[$EN_TITLE_QUAD]'L' .LEFT +. if '\\*[$EN_TITLE_QUAD]'C' .CENTER +. if '\\*[$EN_TITLE_QUAD]'R' .RIGHT +\!. vpt 0 +. sp -.25v +. ie \\n[#EN_TITLE_UNDERLINE] \ +. UNDERSCORE "\\*[$EN_TITLE]" +. el \{\ +. ie \\n[#PRINT_STYLE]=1 \ +. UNDERSCORE "\\*[$EN_TITLE]" +. el .PRINT "\\*[$EN_TITLE]" +. \} +. sp .25v +\!. vpt +. \} +. if \\n[#EN_TITLE_COLOR] .gcolor +. if \\n[#ENDNOTE_TITLE_SMALLCAPS] .SMALLCAPS OFF +. if \\n[#ENDNOTE_TITLE_CAPS] .CAPS OFF +. \} +.\" Get indent from endnotes point size; convert string to reg in +.\" case indent string is, e.g., m or n +. ps \\n[#EN_PS]u +. nr #REF_EN_INDENT (u;\\*[$REF_EN_INDENT]) +. if \\n[#PRINT_STYLE]=1 \{\ +. TYPEWRITER +. if \\n[#EN_NUMBER]=1 \{\ +. ie \\n[#SINGLE_SPACE]=1 .sp +. el .sp .25 +. \} +. if \\n[#EN_MARKER_STYLE]=3 .ps -2 +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. if \\n[#EN_MARKER_STYLE]=1 \{\ +. FAMILY \\*[$EN_NUMBER_FAM] +. FT \\*[$EN_NUMBER_FT] +. ps \\n[#EN_PS]u\\*[$EN_NUMBER_SIZE_CHANGE] +. \} +. if \\n[#EN_MARKER_STYLE]=2 \{\ +. FAMILY \\*[$EN_LN_FAM] +. FT \\*[$EN_LN_FT] +. ps \\n[#EN_PS]u\\*[$EN_LN_SIZE_CHANGE] +. \} +. if \\n[#EN_MARKER_STYLE]=3 \{\ +. FAMILY \\*[$EN_NUMBER_FAM] +. FT \\*[$EN_NUMBER_FT] +. ps \\n[#PT_SIZE_IN_UNITS]u*6u/10u +. \} +. \} +.\" Build string for line-numbered endnotes +. if \\n[#EN_MARKER_STYLE]=2 \{\ +. ie \\n[#EN_LN_BRACKETS]=1 \{\ +. ds $EN_LINENUMBER \v'-.085m'\\*[$EN_OPEN_BRACKET]\v'.085m' +. ie \\n[#EN_MARK_2]=\\n[#EN_MARK] .as $EN_LINENUMBER \ +\\n[#EN_MARK]\v'-.085m'\\*[$EN_CLOSE_BRACKET]\v'.085m'\" +. el .as $EN_LINENUMBER \ +\\n[#EN_MARK]\v'-.1m'-\v'.1m'\\n[#EN_MARK_2]\v'-.085m'\ +\\*[$EN_CLOSE_BRACKET]\v'.085m'\" +. \} +. el \{\ +. ie \\n[#EN_MARK_2]=\\n[#EN_MARK] \ +. ds $EN_LINENUMBER \ +\\n[#EN_MARK]\\*[$EN_LN_SEP] +. el \ +. ds $EN_LINENUMBER \ +\\n[#EN_MARK]\v'-.1m'-\v'.1m'\\n[#EN_MARK_2]\\*[$EN_LN_SEP] +. \} +. nr #EN_MARK 0 +. \} +. vpt 0 +. ie \\n[#EN_NUMBERS_ALIGN_RIGHT] .RIGHT +. el .LEFT +. if \\n[#EN_MARKER_STYLE]=1 \ +. nr #EN_NUMBER_L_LENGTH \w'\0'*\\n[#EN_NUMBER_PLACEHOLDERS]+\w'.' +. if \\n[#EN_MARKER_STYLE]=2 \{\ +. ie \\n[#EN_LN_BRACKETS]=1 .nr #EN_NUMBER_L_LENGTH \ +(\w'\0'*(\\n[#EN_NUMBER_PLACEHOLDERS]*2))+\w'-[]' +. el .nr #EN_NUMBER_L_LENGTH \ +(\w'\0'*(\\n[#EN_NUMBER_PLACEHOLDERS]*2))+\w'-\\*[$EN_LN_SEP]' +. RIGHT +. \} +. if \\n[#EN_MARKER_STYLE]=3 \{\ +. nr #EN_NUMBER_L_LENGTH \ +\w'\0'*\\n[#EN_NUMBER_PLACEHOLDERS]+.15m +. RIGHT +. \} +. ie \\n[#REF]=1 \ +. ll \\n[#EN_NUMBER_L_LENGTH]u+\\n[#REF_EN_INDENT]u +. el .ll \\n[#EN_NUMBER_L_LENGTH]u +. if \\n[#EN_MARKER_STYLE]=1 \{\ +. if \\n[#REF]=1 .ti \\n[#REF_EN_INDENT]u +. nop \En[#EN_NUMBER]. +. \} +. if \\n[#EN_MARKER_STYLE]=2 \{\ +. nop \\*[$EN_LINENUMBER] +. rm $EN_LINENUMBER +. \} +. if \\n[#EN_MARKER_STYLE]=3 \{\ +\!. vpt 0 +. ps \" Reset ps changed to get width of s-script numbers +. ie \\n[#PRINT_STYLE]=1 \{\ +.\" Vertical raise amount here is less than when the same string is printed in +.\" the body of the text because number precedes a cap. +. nop \ +\s-2\v'-\\n[#DOC_LEAD]u/7u'\\n[#EN_NUMBER]\|\v'+\\n[#DOC_LEAD]u/7u'\s+2 +. \} +. el .nop \E*[SUP]\\n[#EN_NUMBER]\E*[SUPX]\h'.15m' +. \} +. EOL +. ll +\!. vpt +. nr #EN_FIGURE_SPACE \w'\0' +. if \\n[#EN_MARKER_STYLE]=1 \{\ +. ie \\n[#REF]=1 .ti \ +\\n[#EN_NUMBER_L_LENGTH]u+\\n[#REF_EN_INDENT]u+\\n[#EN_FIGURE_SPACE]u +. el .in \ +\\n[#EN_NUMBER_L_LENGTH]u+\\n[#EN_FIGURE_SPACE]u +. \} +. if \\n[#EN_MARKER_STYLE]=2 \{\ +. ie \\n[#REF]=1 .ti \ +\\n[#EN_NUMBER_L_LENGTH]u+\\n[#REF_EN_INDENT]u+\\n[#EN_LN_GAP]u +. el .ti \ +\\n[#EN_NUMBER_L_LENGTH]u+\\n[#EN_LN_GAP]u +. \} +. if \\n[#EN_MARKER_STYLE]=3 \{\ +. ie \\n[#REF]=1 .ti \ +\\n[#EN_NUMBER_L_LENGTH]u+\\n[#REF_EN_INDENT]u+\w'\|'u +. el .in \ +\\n[#EN_NUMBER_L_LENGTH]u +. \} +. nr #EN_TEXT_INDENT \\n[.i] +. QUAD \\*[$EN_QUAD] +. vpt +. if \\n[#PRINT_STYLE]=1 .TYPEWRITER +. if \\n[#PRINT_STYLE]=2 \{\ +. FAMILY \\*[$EN_FAM] +. FT \\*[$EN_FT] +. ps \\n[#EN_PS]u +. \} +. \} +. el \{\ +\!. ie \\n[#EN_NUMBER]=\\\\n[#LAST_EN] .vpt 0 +\!. el .br +. if \\n[#PRINT_STYLE]=2 .sp \\*[$EN_SPACE] +. in 0 +. if \\n[#EN_MARKER_STYLE]=2 \{\ +\!. in 0 +. \} +. da +.\" Restore sentence spacing +. if \\n[#PRINT_STYLE]=2 \{\ +. if d$RESTORE_SS_VAR .SS \\*[$RESTORE_SS_VAR] +. rm $RESTORE_SS_VAR +. \} +. ev +.\" Restore lead -- need +. nr #PP_STYLE \\n[#PP_STYLE_PREV] +. if !\\n[#INDENT_FIRSTS] .INDENT_FIRST_PARAS OFF +. rr #INDENT_FIRSTS +. rr #ENDNOTE +. if \\n[#UNDERLINE_WAS_ON] \{\ +. rr #UNDERLINE_WAS_ON +. UNDERLINE +. \} +. if \\n[#SLANT_WAS_ON] \{\ +. rr #SLANT_WAS_ON +\*[SLANT]\c +. \} +. \} +. if \\n[#NUM_ARGS]=2 \{\ +. if '\\$2'BREAK' .BR +. if '\\$2'BR' .BR +. \} +.END +\# +\# Endnotes (user space macro) +\# --------------------------- +\# +\# ENDNOTES +\# -------- +\# *Arguments: +\# none +\# *Function: +\# Sets new document leading from #EN_LEAD, breaks to a new page, +\# sets up an endnotes page based on registers and strings associated +\# with endnotes, then outputs diversion END_NOTES. +\# +.MAC ENDNOTES END +. if \\n[defer] .NEWPAGE +. nr #LAST_EN \\n[#EN_NUMBER] +. nr #ENDNOTES 1 +. nr #EN_FIRST_PAGE 1 +. SETUP_ENDNOTES +. if !\\n[#PRINT_STYLE]=1 .chop END_NOTES +. nf +. END_NOTES +. rm END_NOTES +. ps \\n[#DOC_PT_SIZE]u +. if \\n[#PRINT_STYLE]=1 .vs \\n[#DOC_LEAD]u +. if \\n[#PRINT_STYLE]=2 \{\ +. ie \\n[#ADJ_EN_LEAD] \ +. nr #DOC_LEAD \\n[#RESTORE_DOC_LEAD] +. el .DOC_LEAD \\n[#RESTORE_DOC_LEAD]u +. rr #RESTORE_DOC_LEAD +. \} +. if \\n[#COLUMNS_WERE_ON] .nr #COLUMNS 1 +. if \\n[#HEADER_STATE]=1 .HEADERS +. if \\n[#LINENUMBERS]=2 \{\ +. NUMBER_LINES RESUME +. nr #LINENUMBERS 1 +. \} +. rr #ENDNOTES +.END +\# +\# Macros common to endnotes, bibliography, and toc +\# ------------------------------------------------ +\# +.MAC SETUP_BIB_EN END +. if '\\$0'SETUP_BIBLIOGRAPHY' .ds EN-OR-BIB BIB +. if '\\$0'SETUP_ENDNOTES' .ds EN-OR-BIB EN +. nr #HEADER_STATE \\n[#HEADERS_ON] +. ds $RESTORE_PAGENUM_STYLE \\*[$PAGENUM_STYLE] +. if \\n[#LINENUMBERS]=1 \{\ +. NUMBER_LINES OFF +. nr #LINENUMBERS 2 +. \} +. if \\n[#HEADERS_ON]=1 \ +. if !\\n[#\\*[EN-OR-BIB]_ALLOWS_HEADERS_ALL] .HEADERS OFF +. if \\n[#HEADER_STATE]=1 \{\ +. ie \\n[#\\*[EN-OR-BIB]_HDRFTR_CENTER]=1 . +. el .rm $HDRFTR_CENTER +. \} +. ie !\\n[#SUSPEND_PAGINATION] \{\ +. if \\n[#PAGINATE]=1 \{\ +. if \\n[#PAGE_NUM_V_POS]=1 \{\ +. PAGENUM_STYLE \\*[$\\*[EN-OR-BIB]_PN_STYLE] +. if \\n[#\\*[EN-OR-BIB]_FIRST_PN] .PAGENUMBER \\n[#\\*[EN-OR-BIB]_FIRST_PN]-1 +. if r #\\*[EN-OR-BIB]_NO_FIRST_PN .nr #PAGINATE 0 +. \} +. \} +. \} +. el \{\ +. ie \\n[#PAGE_NUM_V_POS]=2 .nr #PAGINATE 1 +. el .nr #PAGINATE 0 +. \} +. if \\n[#FOOTERS_ON]=1 \{\ +. if !'\\*[$HDRFTR_CENTER_OLD]'' \ +. ds $HDRFTR_CENTER \\*[$HDRFTR_CENTER_OLD] +. \} +. NEWPAGE +. if \\n[#FOOTERS_ON]=1 \{\ +. ds $HDRFTR_CENTER \\*[$HDRFTR_CENTER_NEW] +. rm $HDRFTR_CENTER_OLD +. rm $HDRFTR_CENTER_NEW +. \} +. ie !\\n[#SUSPEND_PAGINATION] \{\ +. if \\n[#PAGE_NUM_V_POS]=1 \{\ +. if r #\\*[EN-OR-BIB]_NO_FIRST_PN \ +. if \\n[#PAGINATION_STATE]=1 .nr #PAGINATE 1 +. \} +. \} +. el \ +. if \\n[#PAGE_NUM_V_POS]=2 .nr #PAGINATE 0 +. rr #PAGINATION_STATE +. PAGENUM_STYLE \\*[$\\*[EN-OR-BIB]_PN_STYLE] +. if \\n[#\\*[EN-OR-BIB]_FIRST_PN] .PAGENUMBER \\n[#\\*[EN-OR-BIB]_FIRST_PN] +. if \\n[#HEADER_STATE]=1 \ +. if \\n[#\\*[EN-OR-BIB]_ALLOWS_HEADERS] .HEADERS +.\" Collect endnotes title string for TOC +. nr #TOC_ENTRY_PN \\n%+\\n[#PAGE_NUM_ADJ] +. af #TOC_ENTRY_PN \\g[#PAGENUMBER] +. ds $TOC_TITLE_ITEM \\*[$\\*[EN-OR-BIB]_STRING]\| +. PDF_BOOKMARK 1 \\*[$\\*[EN-OR-BIB]_STRING] +. TITLE_TO_TOC +.\" End collection of endnotes title string for TOC +.\" Process endnotes +. if \\n[#PRINT_STYLE]=1 .vs \\n[#\\*[EN-OR-BIB]_LEAD]u +. if \\n[#PRINT_STYLE]=2 \{\ +. if \\n[#\\*[EN-OR-BIB]_NO_COLS] \{\ +. if \\n[#COLUMNS] .nr #COLUMNS_WERE_ON 1 +. nr #COLUMNS 0 +. \} +. nr #RESTORE_DOC_LEAD \\n[#DOC_LEAD] +. ie \\n[#ADJ_\\*[EN-OR-BIB]_LEAD] .nr #DOC_LEAD \\n[#\\*[EN-OR-BIB]_LEAD] +. el .DOC_LEAD \\n[#\\*[EN-OR-BIB]_LEAD]u +. \} +. vpt 0 +. RESTORE_SPACE +. ie r#\\*[EN-OR-BIB]_STRING_V_POS .sp |\\n[#\\*[EN-OR-BIB]_STRING_V_POS]u-1v +. el .sp |\\n[#T_MARGIN]u-\\n[#\\*[EN-OR-BIB]_LEAD]u +. vpt +. mk ec +. if \\n[#SLANT_ON] \{\ +\*[SLANTX]\c +. \} +. sp +. if !'\\*[$\\*[EN-OR-BIB]_STRING]'' \{\ +. if \\n[#PRINT_STYLE]=1 \{\ +. TYPEWRITER +. vs \\n[#\\*[EN-OR-BIB]_LEAD]u +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. LL \\n[#DOC_L_LENGTH]u +. ta \\n[.l]u +. if \\n[#COLUMNS] \{\ +. ie \\n[#\\*[EN-OR-BIB]_NO_COLS] .LL \\n[#DOC_L_LENGTH]u +. el .LL \\n[#COL_L_LENGTH]u +. ta \\n[.l]u +. \} +. FAMILY \\*[$\\*[EN-OR-BIB]_STRING_FAM] +. FT \\*[$\\*[EN-OR-BIB]_STRING_FT] +. ps \\n[#\\*[EN-OR-BIB]_PS]u\\*[$\\*[EN-OR-BIB]_STRING_SIZE_CHANGE] +. vs \\n[#\\*[EN-OR-BIB]_LEAD]u +. \} +. substring $\\*[EN-OR-BIB]_STRING_QUAD 0 0 +. if '\\*[$\\*[EN-OR-BIB]_STRING_QUAD]'L' .LEFT +. if '\\*[$\\*[EN-OR-BIB]_STRING_QUAD]'C' .CENTER +. if '\\*[$\\*[EN-OR-BIB]_STRING_QUAD]'R' .RIGHT +. EOL +. if \\n[#\\*[EN-OR-BIB]_STRING_COLOR]=1 .COLOR \\*[$\\*[EN-OR-BIB]_STRING_COLOR] +. if \\n[#\\*[EN-OR-BIB]_STRING_CAPS] .CAPS +. if \\n[#\\*[EN-OR-BIB]_STRING_SMALLCAPS] .SMALLCAPS +. ie \\n[#\\*[EN-OR-BIB]_STRING_UNDERLINE] \{\ +. if \\n[#PRINT_STYLE]=2 .ds $TITLE_TYPE \\*[EN-OR-BIB]_STRING +. ie \\n[#PRINT_STYLE]=1 \ +. UNDERSCORE2 3p 2p "\\*[$\\*[EN-OR-BIB]_STRING]" +. el \{\ +. ie \\n[#\\*[EN-OR-BIB]_STRING_UNDERLINE]=2 \ +. UNDERSCORE2 \\*[$\\*[EN-OR-BIB]_UNDERLINE_GAP] \\*[$\\*[EN-OR-BIB]_RULE_GAP] "\\*[$\\*[EN-OR-BIB]_STRING]" +. el .UNDERSCORE "\\*[$\\*[EN-OR-BIB]_STRING]" +. \} +. \} +. el .PRINT "\\*[$\\*[EN-OR-BIB]_STRING] +. \} +. SMALLCAPS OFF +. if \\n[#\\*[EN-OR-BIB]_STRING_COLOR]=1 .gcolor +. CAPS OFF +. FAMILY \\*[$\\*[EN-OR-BIB]_FAMILY] +. FT \\*[$\\*[EN-OR-BIB]_FT] +. ps -\\*[$\\*[EN-OR-BIB]_STRING_SIZE_CHANGE] +. ie \\n[#PRINT_STYLE]=1 \{\ +. ie \\n[#SINGLE_SPACE]=1 .sp +. el \{\ +. ie \\n[#\\*[EN-OR-BIB]_SINGLESPACE]=1 .sp +. el . +. \} +. \} +. el \{\ +. ie '\\*[EN-OR-BIB]'BIB' .sp 2 +. el .sp +. \} +. SHIM +. QUAD \\*[$\\*[EN-OR-BIB]_QUAD] +.END +. +.ALIAS SETUP_BIBLIOGRAPHY SETUP_BIB_EN +.ALIAS SETUP_ENDNOTES SETUP_BIB_EN +\# +\# ENDNOTES, BIBLIOGRAPHY and TOC LEADING +\# -------------------------------------- +\# *Argument: +\# <leading> [ ADJUST ] +\# *Function: +\# Depending on the name by which it's called, creates or modifies +\# register #<type>_LEAD, where <type> is BIB, EN, or TOC. Creates or removes +\# register #ADJ_<type>_LEAD. Stores arguments in strings if BIB, +\# EN, or TOC leading are set before START. +\# *Notes: +\# Default is same as doc lead for TYPESET, adjusted; 24 for TYPEWRITE. +\# +.MAC _LEAD END +. if '\\$0'BIBLIOGRAPHY_LEAD' .ds $SECTION BIB +. if '\\$0'ENDNOTE_LEAD' .ds $SECTION EN +. if '\\$0'TOC_LEAD' .ds $SECTION TOC +. rr #ADJ_\\*[$SECTION]_LEAD +. ds $\\*[$SECTION]_LEAD \\$1 +. rm $ADJUST_\\*[$SECTION]_LEAD +. if '\\$2'ADJUST' \{\ +. nr #ADJ_\\*[$SECTION]_LEAD 1 +. ds $ADJUST_\\*[$SECTION]_LEAD ADJUST +. \} +. if !\\n[#OK_PROCESS_LEAD] .return +. nr #\\*[$SECTION]_LEAD (p;\\$1) +.END +. +.ALIAS BIBLIOGRAPHY_LEAD _LEAD +.ALIAS ENDNOTE_LEAD _LEAD +.ALIAS TOC_LEAD _LEAD +\# +\# ==================================================================== +\# +\# +++BIBLIOGRAPHY+++ +\# +\# Mom treats bibliographies and endnotes very similarly. The chief +\# difference is that endnotes are collected and formatted inside a +\# diversion, while bibliographies are built "by hand." ENDNOTES sets +\# up the endnotes page and outputs the formatted diversion. +\# BIBLIOGRAPHY sets up the bibliography page, then awaits refer +\# commands. +\# +\# All of the bibliography control macros have their exact +\# counterparts in the endnotes control macros. See, therefore, +\# Arguments, Functions, and Notes in the Endnotes section. +\# +\# Bibliography control macros +\# +.MAC BIBLIOGRAPHY_PT_SIZE END +. nr #BIB_PS (p;\\$1) +.END +\# +.MAC BIBLIOGRAPHY_HDRFTR_CENTER END +. ie '\\$1'' .nr #BIB_HDRFTR_CENTER 1 +. el .rr #BIB_HDRFTR_CENTER +.END +\# +.MAC BIBLIOGRAPHY_STRING END +. ds $BIB_STRING \\$1 +.END +\# +.MAC BIBLIOGRAPHY_STRING_ADVANCE END +. nr #BIB_STRING_V_POS (u;\\$1) +.END +\# +.MAC BIBLIOGRAPHY_STRING_V_POS END +. nr #BIB_STRING_V_POS (u;\\$1) +.END +. +.ALIAS BIBLIOGRAPHY_HEADER_V_POS BIBLIOGRAPHY_STRING_V_POS +\# +.MAC BIBLIOGRAPHY_NO_COLUMNS END +. ie '\\$1'' .nr #BIB_NO_COLS 1 +. el .rr #BIB_NO_COLS +.END +\# +.MAC BIBLIOGRAPHY_NO_FIRST_PAGENUM END +. ie '\\$1'' .nr #BIB_NO_FIRST_PN 1 +. el .rr #BIB_NO_FIRST_PN +.END +\# +.MAC BIBLIOGRAPHY_ALLOWS_HEADERS END +. ie '\\$1'' .nr #BIB_ALLOWS_HEADERS 1 +. el \{\ +. ie '\\$1'ALL' \{\ +. nr #BIB_ALLOWS_HEADERS 1 +. nr #BIB_ALLOWS_HEADERS_ALL 1 +. \} +. el \{\ +. rr #BIB_ALLOWS_HEADERS +. rr #BIB_ALLOWS_HEADERS_ALL +. \} +. \} +.END +\# +.MAC BIBLIOGRAPHY_PAGENUM_STYLE END +. ds $BIB_PN_STYLE \\$1 +.END +\# +.MAC BIBLIOGRAPHY_FIRST_PAGENUMBER END +. nr #BIB_FIRST_PN \\$1 +.END +\# +.MAC SINGLESPACE_BIBLIOGRAPHY END +. if \\n[#PRINT_STYLE]=1 \{\ +. ie \\n[#SINGLE_SPACE] \{\ +. nr #BIB_SINGLESPACE 1 +. rr #IGNORE +. if \\n[#OK_PROCESS_LEAD] \{\ +. BIBLIOGRAPHY_LEAD 12 ADJUST +. nr #IGNORE 1 +. \} +. \} +. el \{\ +. ie '\\$1'' \{\ +. nr #BIB_SINGLESPACE 1 +. rr #IGNORE +. if \\n[#OK_PROCESS_LEAD] \{\ +. BIBLIOGRAPHY_LEAD 12 ADJUST +. nr #IGNORE 1 +. \} +. \} +. el \{\ +. rr #BIB_SINGLESPACE +. rr #IGNORE +. if \\n[#OK_PROCESS_LEAD] \{\ +. BIBLIOGRAPHY_LEAD 24 ADJUST +. nr #IGNORE 1 +. \} +. \} +. \} +. \} +.END +\# +\# Style for outputting collected bibliographic references +\# ------------------------------------------------------- +\# *Argument: +\# LIST | PLAIN [ <list separator> ] [ <list prefix> ] +\# *Function: +\# Sets #BIB_LIST to 1 for numbered list style, 0 for plain output +\# *Notes: +\# Technically, user is supposed to enter PLAIN if s/he wants an +\# unnumbered bibliography, but the el clause says "any arg but +\# LIST means unnumbered." Effectively, any arg but LIST produces +\# a "plain" bibliographic list. +\# +\# The 2nd and 3rd args have the same options as the 2nd and 3rd +\# args to LIST. +\# +.MAC BIBLIOGRAPHY_TYPE END +. ie '\\$1'LIST' \{\ +. nr #BIB_LIST 1 +. ie '\\$2'' \ +. if '\\*[$BIB_LIST_SEPARATOR]'' .ds $BIB_LIST_SEPARATOR . +. el .ds $BIB_LIST_SEPARATOR \\$2 +. ie '\\$3'' .ds $BIB_LIST_PREFIX +. el .ds $BIB_LIST_PREFIX \\$3 +. \} +. el .nr #BIB_LIST 0 +.END +\# +\# Spacing between items in bibliographies +\# --------------------------------------- +\# *Argument: +\# <amount of space> +\# *Function: +\# Gets value for $BIB_SPACE. +\# *Notes: +\# Requires a unit of measure. +\# +.MAC BIBLIOGRAPHY_SPACING END +. ds $BIB_SPACE \\$1 +.END +\# +\# Bibliography (user space macro) +\# ------------------------------- +\# *Function: +\# Sets up a new page, with title, ready to accept the output +\# of refer's $LIST$ or .R1 bibliography .R2 +\# *Notes: +\# Bibliography pages are set up almost identically to endnotes pages. +\# +.MAC BIBLIOGRAPHY END +. if \\n[defer] .NEWPAGE +. ie '\\$1'' \{\ +. rr #FN_REF +. rr #EN_REF +. nr #BIBLIOGRAPHY 1 +. nr #BIB_FIRST_PAGE 1 +\#. nr #SKIP_FOOTER +1 +. SETUP_BIBLIOGRAPHY +\#. nr #SKIP_FOOTER -1 +. if \\n[#PRINT_STYLE]=1 \{\ +. ie \\n[#SINGLE_SPACE]=1 .vs \\n[#BIB_LEAD]u +. el \{\ +. ie \\n[#BIB_SINGLESPACE]=1 .vs \\n[#BIB_LEAD]u +. el .vs \\n[#BIB_LEAD]u +. \} +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. ie \\n[#ADJ_BIB_LEAD] \ +. nr #DOC_LEAD \\n[#RESTORE_DOC_LEAD] +. el .DOC_LEAD \\n[#RESTORE_DOC_LEAD]u +. rr #RESTORE_DOC_LEAD +. \} +. if \\n[#COLUMNS_WERE_ON] .nr #COLUMNS 1 +. if \\n[#HEADER_STATE]=1 .HEADERS +. if \\n[#LINENUMBERS]=2 \{\ +. NUMBER_LINES RESUME +. nr #LINENUMBERS 1 +. \} +. di BIB +. \} +. el \{\ +. br +. di +.\" Part of workaround for refer spitting out a blank page if the +.\" last ref falls on the bottom line. +. nr num*refs \\n[ref*num*first-pass] +. nf +. chop BIB +. BIB +. \} +. rr #BIBLIOGRAPHY +.END +\# +\# ==================================================================== +\# +\# +++TABLE OF CONTENTS+++ +\# +\# Strings to allocate space for leaders and entry page numbers +\# +.ds $TOC_PN \\*[ST102]\F[\\*[$TOC_PN_FAM]]\f[\\*[$TOC_PN_FT]]\ +\s[\\n[#TOC_PS]u]^\\*[ST102X]\\*[ST103]\s[\\*[$TOC_PN_SIZE_CHANGE]]\ +\h'.2n'\h'\w'0'u*\\n[#TOC_PN_PADDING]u'\\*[ST103X] +\# +.ds $TOC_PN_TYPEWRITE \\*[ST102]^\\*[ST102X]\\*[ST103]\ +\h'\w'0'u*\\n[#TOC_PN_PADDING]u'\\*[ST103X] +\# +\# Macro to remove titles from the TOC. +\# Primarily to remove the copyright page from the TOC. +\# +.MAC NO_TOC_ENTRY END +. nr #NO_TOC_ENTRY 1 +.END +\# +\# USER-INSERTED HEADING IN TOC +\# ---------------------------- +\# *Arguments: +\# <text> +\# *Function: +\# Inserts a single line of non-pagenumbered text into the TOC. +\# +.MAC TOC_HEADING END +. ds $TOC_HEADING \\$1 +.END +\# +\# TOC collector +\# +.MAC TO_TOC END +. if !'\\n[.ev]'TOC_EV' .ev TOC_EV +. nr #TOC_CH_NUM_INDENT \w'\\*[$TOC_CH_NUM]' +. da TOC_ENTRIES +\!. ie \\\\n[#SKIP_ENTRY]=1 \{\ +. rr #SKIP_ENTRY +\!. \} +\!. el \{\ +. TQ +. ie \\n[#PRINT_STYLE]=1 \{\ +\!. fam \\*[$TYPEWRITER_FAM] +\!. ft R +\!. ps \\*[$TYPEWRITER_PS] +. ds _TYPEWRITE _TYPEWRITE +. \} +. el \{\ +. ie '\\$0'HD_TO_TOC' \{\ +\!. ps \\n[#TOC_PS]u\\*[$TOC_HEAD_\\n[#LEVEL]_SIZE] +. \} +. el \{\ +\!. FAMILY \\*[$TOC_TITLE_FAM] +\!. FT \\*[$TOC_TITLE_FT] +\!. ps \\n[#TOC_PS]u\\*[$TOC_TITLE_SIZE] +. \} +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. rm _TYPEWRITE +. if \\n[#SPACE_TOC_ITEMS] \{\ +. if \\n[#POST_TOP]=1 \{\ +. ie !\\n[#LEVEL]=\\n[#LAST_LEVEL] \{\ +. ie \\n[#LEVEL]>\\n[#LAST_LEVEL] \!.sp .2v +. el \!.sp .4v +. \} +. el \{\ +. if \\n[#COLLATED_DOC] \ +. if '\\$0'TITLE_TO_TOC' \!.sp .4v +. \} +. \} +. \} +. \} +\!. vpt 0 +\!. PAD_MARKER ^ +. if !'\\$0'HD_TO_TOC' \{\ +\!. if \\n[#TOC_TITLE_CAPS]=1 .CAPS +. \} +. if '\\$0'HD_TO_TOC' \{\ +. nr #POST_TOP 1 +\!. if \\n[#TOC_HEAD_\\n[#LEVEL]_CAPS]=1 .CAPS +. \} +. ie '\\$0'HD_TO_TOC' \{\ +. if \\n[#PRINT_STYLE]=1 \{\ +. ds $TOC_HEAD_\\n[#LEVEL]_FAM] \\*[$TYPEWRITER_FAM] +. ds $TOC_HEAD_\\n[#LEVEL]_FT] R +. \} +\!. PAD \ +"\f[\\*[$TOC_HEAD_\\n[#LEVEL]_FAM]\ +\\*[$TOC_HEAD_\\n[#LEVEL]_FT]]\ +\h'\\\\n[#TOC_INDENT_ADJ]u'\h'\\n[#TOC_HEAD_\\n[#LEVEL]_INDENT]u'\ +\\*[$TOC_HD_NUM]\\*[$TOC_HEAD_\\n[#LEVEL]_ITEM]\\*[$TOC_PN\\*[_TYPEWRITE]]" \ +"\\*[PDFBOOKMARK.NAME]" +. \} +. el \{\ +. ie '\\$0'HEADING_TO_TOC' \{\ +. if \\n[#PRINT_STYLE]=1 \{\ +. ds $TOC_TITLE_FAM \\*[$TYPEWRITER_FAM] +. ds $TOC_TITLE_FT R +. \} +. if !'\\*[$TOC_HEADING_QUAD]'' \{\ +. substring $TOC_HEADING_QUAD 0 0 +. if '\\*[$TOC_HEADING_QUAD]'L' \!.LEFT +. if '\\*[$TOC_HEADING_QUAD]'C' \!.CENTER +. if '\\*[$TOC_HEADING_QUAD]'R' \!.RIGHT +. \} +\!. vpt +\!. ne \\*[$SPACE_ABOVE]+\\*[$SPACE_BENEATH]+2v +\!. vpt 0 +. if \\n[#PRINT_STYLE]=2 \ +. if \\n[#POST_TOP] \!.sp \\*[$SPACE_ABOVE] +. ie \\n[#PRINT_STYLE]=1 \!.nop \\*[$TOC_HEADING] +. el \{\ +\!. nop \ +\f[\\*[$TOC_HEADING_FAM]\\*[$TOC_HEADING_FT]]\ +\s[\\*[$TOC_HEADING_SIZE]]\ +\m[\\*[$TOC_HEADING_COLOR]]\ +\\*[$TOC_HEADING]\ +\m[]\s[0]\f[P] +. \} +. if \\n[#PRINT_STYLE]=2 \{\ +. ie \\n[#SPACE_TOC_ITEMS] \ +. if \\n[#POST_TOP]=0 \!.sp \\*[$SPACE_BENEATH] +. el \!.sp \\*[$SPACE_BENEATH] +. \} +\!. vpt +. da +. ev +. return +. \} +. el \{\ +\!. PAD \ +"\f[\\*[$TOC_TITLE_FAM]\\*[$TOC_TITLE_FT]]\ +\h'\\n[#TOC_TITLE_INDENT]u'\\*[$TOC_TITLE_ITEM]\\*[$TOC_PN\\*[_TYPEWRITE]]" \ +"\\*[PDFBOOKMARK.NAME]" +. \} +. \} +. ie '\\$0'HD_TO_TOC' \ +\!. if \\n[#TOC_HEAD_\\n[#LEVEL]_CAPS]=1 .CAPS OFF +. el \ +\!. if \\n[#TOC_TITLE_CAPS]=1 .CAPS OFF +\!. PAD_MARKER # +\!. EOL +\!. ST 102 L +\!. ST 103 R QUAD +. if \\n[#PRINT_STYLE]=2 \{\ +\!. FAMILY \\*[$TOC_PN_FAM] +\!. FT \\*[$TOC_PN_FT] +\!. ps \\n[#TOC_PS]u +. \} +\!. TAB 102 +\!. PRINT \fR\\*[LEADER]\f[] +\!. TN +. if \\n[#PRINT_STYLE]=2 \{\ +\!. ps \\*[$TOC_PN_SIZE_CHANGE] +. \} +\!. PRINT \\n[#TOC_ENTRY_PN] +\!. \} +. da +. ev +.END +. +.ALIAS HD_TO_TOC TO_TOC +.ALIAS TITLE_TO_TOC TO_TOC +.ALIAS HEADING_TO_TOC TO_TOC +\# +\# Control macros for toc +\# ---------------------- +\# +\# TOC TITLE STYLE +\# --------------- +\# *Arguments: +\# FAMILY <family> +\# FONT <font> +\# SIZE <+|-n> +\# COLOR <color> +\# CAPS +\# INDENT +\# *Function: +\# Assigns complete style parameters to TITLEs (doc titles, +\# chapter titles, etc) in the TOC. +\# *Notes: +\# TITLEs are not headings, therefore they require their own style +\# macro. Otherwise, the same as TOC_ENTRY_STYLE. +\# +.MAC TOC_TITLE_STYLE END +. nr #ARG_NUM 0 1 +. nr #ATTRIB \\n[#NUM_ARGS] +. while \\n+[#ARG_NUM]<=\\n[#ATTRIB] \{\ +. if '\\$1'FAMILY' \{\ +. shift +. ds $TOC_TITLE_FAM \\$1 +. shift +. \} +. if '\\$1'FONT' \{\ +. shift +. ds $TOC_TITLE_FT \\$1 +. shift +. \} +. if '\\$1'SIZE' \{\ +. shift +. ds $TOC_TITLE_SIZE \\$1 +. shift +. \} +. if '\\$1'CAPS' \{\ +. nr #TOC_TITLE_CAPS 1 +. shift +. \} +. if '\\$1'NO_CAPS' \{\ +. rr #TOC_TITLE_CAPS +. shift +. \} +. if '\\$1'SMALLCAPS' \{\ +. nr #TOC_TITLE_SMALLCAPS 1 +. shift +. \} +. if '\\$1'NO_SMALLCAPS' \{\ +. rr #TOC_TITLE_SMALLCAPS +. shift +. \} +. if '\\$1'INDENT' \{\ +. shift +. nr #TOC_TITLE_INDENT \\$1 +. shift +. \} +. \} +.END +\# +\# TOC HEADER STRING +\# ----------------- +\# *Argument: +\# <string for "doc header" of first toc page> +\# *Function: +\# Creates or modifies string $TOC_HEADER_STRING +\# *Notes: +\# Default is "Contents". +\# +.MAC TOC_HEADER_STRING END +. ds $TOC_HEADER_STRING \\$1 +.END +\# +\# TOC HEADER CAPS and SMALLCAPS +\# ----------------------------- +\# *Arguments: +\# <none> | <anything> +\# *Function: +\# Turns capitalization or smallcaps style of the toc title string +\# on or off. +\# *Notes: +\# Users may want the toc title string to be in +\# caps, but the page header to be in lower case. If the +\# argument to TOC_HEADER_STRING is in lower case and +\# TOC_HEADER_CAPS is turned on, this is exactly what will +\# happen. Ditto for SMALLCAPS. +\# +.MAC TOC_HEADER_CAPS END +. ie '\\$1'' .nr #TOC_STRING_CAPS 1 +. el .nr #TOC_STRING_CAPS 0 +.END +. +.MAC TOC_HEADER_SMALLCAPS END +. ie '\\$1'' .nr #TOC_STRING_SMALLCAPS 1 +. el .nr #TOC_STRING_SMALLCAPS 0 +.END +. +\# +\# TOC VERTICAL PLACEMENT +\# ---------------------- +\# *Argument: +\# <distance from page top> +\# *Function: +\# Creates register #TOC_HEADER_V_POS. +\# *Notes: +\# Default is same as normal docheader position. +\# +.MAC TOC_HEADER_V_POS END +. nr #TOC_HEADER_V_POS (u;\\$1) +.END +\# +\# +\# TOC POINT SIZE +\# -------------- +\# *Argument: +\# <base point size for toc pages> +\# *Function: +\# Creates or modifies register #TOC_PS. +\# *Notes: +\# This size control macro differs from other size control macros +\# in that it sets an absolute point size, not a relative one. +\# See notes for ENDNOTE_PT_SIZE for explanation. +\# +\# No unit of measure required (points assumed). Default is 12.5 +\# for TYPESET. +\# +.MAC TOC_PT_SIZE END +. nr #TOC_PS (p;\\$1) +.END +\# +\# TOC ENTRIES PAGE NUMBERS PADDING +\# -------------------------------- +\# *Argument: +\# <number of placeholders for toc entries page numbers> +\# *Function: +\# Creates or modifies register #TOC_PN_PADDING. +\# *Notes: +\# "Placeholders" is the maximum number of digits in a page +\# number numeral. +\# +\# Default is 3. +\# +.MAC TOC_PADDING END +. nr #TOC_PN_PADDING \\$1 +.END +\# +\# PAGINATE TOC +\# ------------ +\# *Argument: +\# <none> | <anything> +\# *Function: +\# Creates or removes register #PAGINATE_TOC. +\# *Notes: +\# Default is to paginate toc. +\# +.MAC PAGINATE_TOC END +. ie '\\$1'' .nr #PAGINATE_TOC 1 +. el .nr #PAGINATE_TOC 0 +.END +\# +.MAC TOC_FIRST_PAGENUM END +. nr #TOC_START_PAGENUM \\$1 +.END +\# +\# TOC PAGES PAGE-NUMBERING STYLE +\# ------------------------------ +\# *Argument: +\# DIGIT | ROMAN | roman | ALPHA | alpha +\# *Function: +\# Creates or modifies string $TOC_PN_STYLE +\# *Notes: +\# Page numbering style for page numbers that appear in the +\# headers/footers of toc pages. See notes for PAGENUM_STYLE. +\# +\# Default is roman. +\# +.MAC TOC_PAGENUM_STYLE END +. ds $TOC_PN_STYLE \\$1 +.END +\# +\# TOC RECTO_VERSO SWITCH +\# ---------------------- +\# *Argument: +\# <none> | <anything> +\# *Function: +\# Creates or removes register #TOC_RV_SWITCH +\# *Notes: +\# Allows switching of L/R margins if a doc is recto/verso and +\# the first toc page happens to fall the wrong way +\# +.MAC TOC_RV_SWITCH END +. ie '\\$1'' .nr #TOC_RV_SWITCH 1 +. el .rr #TOC_RV_SWITCH +.END +\# +\# TOC ENTRY SPACING +\# ----------------- +\# *Arguments: +\# <none> | <anything> +\# *Function: +\# Toggles whether a small amount of space is inserted between TOC +\# entries for greater legibility. +\# +.MAC SPACE_TOC_ITEMS END +. ie !'\\$1'' .rr #SPACE_TOC_ITEMS +. el .nr #SPACE_TOC_ITEMS 1 +.END +\# +\# NUMBERING OF TOC CHAPTER/SECTION ENTRIES +\# ---------------------------------------- +\# *Arguments: +\# <none> | <anything> +\# *Function: +\# Determines whether chapter numbers are prefixed to title +\# entries in the TOC (title here means chapter/chapter-title +\# or, if the doctype is DEFAULT or NAMED, the section title. +\# *Notes: +\# Aliased as TOC_PREFIX_SECTION_NUMBER. +\# +.MAC TOC_PREFIX_CHAPTER_NUMBER END +. ie '\\$1'' .nr #TOC_PREFIX_CH_NUM 1 +. el .rr #TOC_PREFIX_CH_NUM +.END +. +.ALIAS TOC_PREFIX_SECTION_NUMBER TOC_PREFIX_CHAPTER_NUMBER +\# +\# PADDING OF TOC CHAPTER/SECTION NUMBERS +\# -------------------------------------- +\# *Arguments: +\# <amount of padding> | <anything> +\# *Function: +\# Insert figure spaces before toc chapter numbers so they +\# right align. +\# *Notes: +\# Aliased as PAD_TOC_SECTION_NUMBERS. +\# +.MAC PAD_TOC_CHAPTER_NUMBERS END +. ie !'\\$1'' .nr #PAD_TOC_CH_NUM \\$1 +. el .rr #PAD_TOC_CH_NUM +.END +. +.ALIAS PAD_TOC_SECTION_NUMBERS PAD_TOC_CHAPTER_NUMBERS +\# +\# NUMBERING OF TOC HEAD ENTRIES +\# ----------------------------- +\# *Arguments: +\# FULL | TRUNCATE | NONE +\# *Function: +\# Determines how, or whether, to prepend heading numbers to TOC +\# entries. +\# *Notes: +\# FULL means the complete numbering string (default). +\# +\# TRUNCATE means prepend a single digit sufficient to identify +\# an entry's place in the numbering scheme with reference to the +\# level above it. Thus, if a HEADING 1 is the second HEADING 1 +\# and therefore numbered "2.", a HEADING 2 beneath it (in the TOC) +\# will have only "1." prepended to the entry; TOC indenting makes it +\# evident under which level the HEADING 2 belongs. +\# +\# Note that TRUNCATE also removes chapter numbers, if +\# PREFIX_CHAPTER_NUMBER is on. +\# +.MAC TOC_ENTRY_NUMBERS END +. if '\\$1'TRUNCATE' .nr #TRUNC_TOC_HD_NUM 1 +. if '\\$1'FULL' .nr #TRUNC_TOC_HD_NUM 0 +. if '\\$1'NONE' .nr #TOC_NO_HD_NUM 1 +.END +\# +\# User defined TITLE entry string +\# +.MAC TOC_TITLE_ENTRY END +. nr #USER_SET_TITLE_ITEM 1 +. ds $USER_SET_TITLE_ITEM \\$1 +.END +\# +\# APPEND AUTHOR(S) TO TOC DOC TITLE ENTRIES +\# ----------------------------------------- +\# *Argument: +\# <none> | <name(s) of author(s) as they should appear in toc doc title entries> +\# *Function: +\# Creates register #TOC_AUTHORS (to tell TOC to append authors +\# to toc doc title entries). Optionally creates string +\# $TOC_AUTHORS. +\# *Notes: +\# Normally, TOC does not append the author(s) to a toc doc title +\# entry. This special macro instructs TOC to do so. +\# +\# If user has multiple authors for each doc when collating, +\# TOC_APPENDS_AUTHOR "<string>" must be inserted somewhere between +\# COLLATE and START in each doc. Otherwise, mom prints only the +\# first author given to AUTHOR. +\# +.MAC TOC_APPENDS_AUTHOR END +. nr #TOC_AUTHORS 1 +. if !'\\$1'' .ds $TOC_AUTHORS \\$1 +.END +\# +\# TABLE OF CONTENTS PAGE SETUP +\# ---------------------------- +\# *Arguments: +\# <none> | <anything> +\# *Function: +\# Some changes to the TOC layout (e.g. margins and page headers) +\# are not covered by the TOC and endnotes control macros. This +\# macro permits access to any and all page setup macros not so +\# covered. +\# *Notes +\# Wraps a diversion that ends when the macro is invoked with an +\# argument. The contained formatting macros must be preceded by +\# '\!'. The diversion is output before START in TOC. +\# +.MAC TOC_PAGE_SETTINGS END +. nr #TOC_PAGE_PARAMS 1 +. ie '\\$1'' \ +. di TOC_PAGE_PARAMS +. el .di +.END +\# +\# TABLE OF CONTENTS +\# ----------------- +\# *Arguments: +\# none +\# *Function: +\# Takes care of the administrivia of setting up the TOC as if +\# it's a collated doc, then outputs the formatted TOC_ENTRIES +\# diversion. +\# +.MAC TOC END +. ie (\\n[@TOP]=0)&(\\n[.t]<=\\n[.v]) \ +' br \" When last line of text is on or near b-margin. +. el .br \" All other cases +. if dPDF.EXPORT \ +. if \\n[#FLEX_ACTIVE] \ +. if !\\n[#NO_FLEX] \ +. tm .ds pre-toc-\\n%@\\n[#COL_NUM] 1 +. if \\n[#TOC_RV_SWITCH]=1 .nr #TOC_RV_SWITCH 2 +. char \[leader] " . +. LEADER_CHARACTER \[leader] +. if !\\n[#TOC_HEAD_1_INDENT] \ +. nr #TOC_INDENT_ADJ 1.5m +. if \\n[#TOC_PREFIX_CH_NUM] \ +. nr #TOC_INDENT_ADJ \\n[#TOC_CH_NUM_INDENT] +. if !\\n[#DOC_TYPE]=2 \{\ +. if !'\\$1'INCLUDE_TITLE' \{\ +. if r #LEVEL .nr #SKIP_ENTRY 1 +. nr #TOC_INDENT_ADJ 0 +. \} +. \} +. nr #TOC 1 +. nr TOC.RELOCATE 0 +. if \\n[#LINENUMBERS]=1 \{\ +. NUMBER_LINES OFF +. nr #LINENUMBERS 2 +. \} +. if !r #PAGINATE_TOC .PAGINATE_TOC +. nr #TOC_FIRST_PAGE 1 +. if \\n[#FINIS] \{\ +. if \\n[#FOOTERS_WERE_ON] \ +. FOOTERS \" Have to turn FOOTERS on for next bit to work, so we can't skip this step +. \} +. if \\n[#FOOTERS_ON]=1 \{\ +. if !'\\*[$HDRFTR_CENTER_OLD]'' \ +. ds $HDRFTR_CENTER \\*[$HDRFTR_CENTER_OLD] +. ie \\n[#PAGINATE_TOC]=1 .PAGINATE +. el .PAGINATION OFF +. \} +. if \\n[#FOOTERS_WERE_ON] .FOOTERS OFF \" But have to turn FOOTERS off again so they don't print when FINIS was called +. rr #COLUMNS +. COLLATE +. if \\n[#PRINT_STYLE]=1 \{\ +. rr #IGNORE +. if \\n[#SINGLE_SPACE] .DOC_LEAD 24 +. DOC_LEAD_ADJUST +. TRAPS +. nr #IGNORE 1 +. \} +. if \\n[#FINIS] \{\ +. if \\n[#FOOTERS_WERE_ON] .FOOTERS \" Finally, turn footers on if they were on +. rr #FOOTERS_WERE_ON +. if \\n[#PAGINATION_WAS_ON] \{\ +. nr #PAGINATE 1 +. rr #PAGINATION_WAS_ON +. \} +. rr #FINIS +. \} +. ie \\n[#PAGINATE_TOC]=1 .PAGINATE +. el .PAGINATION OFF +. ds $HDRFTR_CENTER \\*[$HDRFTR_CENTER_NEW] +. rm $HDRFTR_CENTER_OLD +. rm $HDRFTR_CENTER_NEW +. rr #COLLATED_DOC +. if !r #TOC_START_PAGENUM .nr #TOC_START_PAGENUM 1 +. PAGENUMBER \\n[#TOC_START_PAGENUM] +. if \\n[#LINENUMBERS]=2 .nr #LINENUMBERS 3 +. L_MARGIN \\n[#DOC_L_MARGIN]u +. LL \\n[#DOC_L_LENGTH]u +. HEADER_CENTER "\\*[$TOC_HEADER_STRING] +. if \\n[#SLANT_ON] .nop \\*[SLANTX] +. PAGENUM_STYLE \\*[$TOC_PN_STYLE] +. PAGENUM_FAMILY \\*[$TOC_PN_FAM] +. if r #TOC_PAGE_PARAMS .TOC_PAGE_PARAMS +. ie \\n[#ADJ_TOC_LEAD] \{\ +. DOC_LEAD \\*[$TOC_LEAD] ADJUST +. TRAPS +. \} +. el .DOC_LEAD \\*[$TOC_LEAD] +. ie \\n[#TOC_HEADER_V_POS] \ +. DOCHEADER OFF \\n[#TOC_HEADER_V_POS]u-\\n[#DOC_LEAD]u +. el .DOCHEADER OFF \\n[#T_MARGIN]u-\\n[#DOC_LEAD]u +. if (\\n[#PRINT_STYLE]=1)&(\\n[#SINGLE_SPACE]=1) \ +. DOCHEADER OFF \\n[#T_MARGIN]u-(\\n[#DOC_LEAD]u*2u) +. START +. PDF_BOOKMARK 1 \\*[$TOC_HEADER_STRING] +. if \\n[#PRINT_STYLE]=1 .TYPEWRITER +. if \\n[#PRINT_STYLE]=2 \{\ +. FAMILY \\*[$TOC_HEADER_FAM] +. FT \\*[$TOC_HEADER_FT] +. ps \\n[#TOC_PS]u\\*[$TOC_HEADER_SIZE_CHANGE] +. if \\n[#TOC_HEADER_COLOR]=1 \ +. COLOR \\*[$TOC_HEADER_COLOR] +. \} +. QUAD \\*[$TOC_HEADER_QUAD] +. if \\n[#TOC_STRING_CAPS] .CAPS +. if \\n[#TOC_STRING_SMALLCAPS] .SMALLCAPS +. if \\n[#PRINT_STYLE]=1 \ +. UNDERSCORE 3p "\\*[$TOC_HEADER_STRING]" +. if \\n[#PRINT_STYLE]=2 \{\ +. ie \\n[#TOC_HEADER_UNDERLINE] \{\ +. ds $TITLE_TYPE TOC_HEADER +. ie \\n[#TOC_HEADER_UNDERLINE]=2 \ +. UNDERSCORE2 \\*[$TOC_UNDERLINE_GAP] \\*[$TOC_RULE_GAP] "\\*[$TOC_HEADER_STRING]" +. el .UNDERSCORE "\\*[$TOC_HEADER_STRING]" +. \} +. el .PRINT \\*[$TOC_HEADER_STRING] +. \} +. SMALLCAPS OFF +. CAPS OFF +. if \\n[#TOC_HEADER_COLOR]=1 .gcolor +. br +. sp +. SHIM_1 +. nf +. TOC_ENTRIES +. if \\n[#LINENUMBERS]=3 \{\ +. NUMBER_LINES RESUME +. nr #LINENUMBERS 1 +. nn 1 +. \} +. rr #TOC +. rr #TOC_RV_SWITCH +. pdfsync +.END +\# +\# ==================================================================== +\# +\# +++COLUMNS+++ +\# +\# COLUMNS +\# ------- +\# *Arguments: +\# <number of columns> <width of gutters> +\# *Function: +\# Creates registers associated with setting docs in columns. +\# Calculates column line lengths and offsets +\# *Notes: +\# COLUMNS, if used, s/b the last macro invoked before START. +\# +.MAC COLUMNS END +. if \\n[#IGNORE_COLUMNS]=1 .return +. nr #COLUMNS 1 +. nr #NUM_COLS \\$1 +. nr #GUTTER (\\$2) +. nr #COL_L_LENGTH \\n[#L_LENGTH]-(\\n[#GUTTER]*(\\n[#NUM_COLS]-1))/\\n[#NUM_COLS] +. nr #COL_TOTAL 0 \\n[#COL_L_LENGTH]+\\n[#GUTTER] +. nr #COL_NUM 0 1 +. while !\\n[#COL_NUM]=\\n[#NUM_COLS] \{\ +. nr #COL_\\n+[#COL_NUM]_L_MARGIN \\n[#L_MARGIN]+\\n[#COL_TOTAL] +. nr #COL_TOTAL \\n+[#COL_TOTAL] +. \} +. if \\n[#NUM_COLS]=1 \ +. if !\\n[#COLLATE]=1 .MN_INIT +. rr #COL_TOTAL +. rr #COL_NUM +.END +\# +\# MARK COL V-POSITION AFTER DOCHEADER +\# ----------------------------------- +\# *Arguments: +\# none +\# *Function: +\# Sets 1st page dc register. +\# *Notes: +\# Only required if manual spacing, positive or negative, precedes +\# start of columns on first page of doc. +\# +.MAC COL_MARK END +. mk dc +.END +\# +\# NEXT COLUMN +\# ----------- +\# *Arguments: +\# <none> +\# *Function: +\# Breaks current column and moves to next column. +\# If current column is the last on the page, breaks +\# to a new page. +\# +.MAC COL_NEXT END +. if \\n[#COLUMNS] \{\ +. nr #COL_NEXT 1 +. vpt 0 +. if !'\\$1'internal' \ +. if dPDF.EXPORT \ +. if \\n[#FLEX_ACTIVE] \ +. if !\\n[#NO_FLEX] \ +. if \\n[#COL_NUM]>1 \ +. tm .ds page-\\n%@\\n[#COL_NUM] 1 +. ie '\\$0'COL_NEXT' .br +. el \{\ +. brp +. RLD 1v +. \} +. vpt +. ie \\n[#COL_NUM]=\\n[#NUM_COLS] .NEWPAGE +. el .FOOTER +. \} +.END +\# +\# ==================================================================== +\# +\# +++LISTS+++ +\# +\# LIST +\# ---- +\# *Arguments: +\# [ BULLET | DASH | DIGIT | alpha | ALPHA | roman | ROMAN | USER ] \ +\# [ <separator> | NONE ] [ <prefix> ] [ <anything> ] +\# *Function: +\# Stores indent information in effect prior to invocation and +\# initializes a list with the supplied enumerator (and separator). +\# *Notes: +\# Default enumerator is a bullet. +\# +\# Enumerator *must* be supplied for every list that's to the +\# right of another list, every time, unless the default bullet is +\# desired. +\# +\# <anything> moves back one list level intuitively, or exits lists +\# completely if the level in which it's invoked is the first. +\# +.MAC LIST END +. br +. if r pdfbx-top 'sp -1 +. ds $1ST_LETTER \\$1 +. if !'\\*[$1ST_LETTER]'' .substring $1ST_LETTER 0 0 +. if '\\*[$1ST_LETTER]'r' .ds $1ST_LETTER R +. ie '\\*[$1ST_LETTER]'R' \{\ +. if r #ROMAN_LIST .rr #ROMAN_LIST +. if '\\$1'ROMAN' .nr #ROMAN_LIST 1 +. if '\\$1'roman' .nr #ROMAN_LIST 1 +. ds $LAST_CHAR \\$1 +. substring $LAST_CHAR -1 +. if !\B'\\*[$LAST_CHAR]' \{\ +. if !r #ROMAN_LIST \{\ +. LIST OFF +. return +. \} +. tm1 "[mom]: You must append a number to the '\\$1' argument to \\$0. +. tm1 " The number should be the total number of items in this list. +. tm1 " See the documentation. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. ds $ROMAN_WIDTH \\$1 +. substring $ROMAN_WIDTH 1 +. while !\B'\\*[$ROMAN_WIDTH]' \{\ +. substring $ROMAN_WIDTH 1 +. \} +. length #ROMAN_LENGTH \\*[$ROMAN_WIDTH] +. ds $LIST_ARG_1 \\$1 +. substring $LIST_ARG_1 0 -(\\n[#ROMAN_LENGTH]+1) +. \} +. el .ds $LIST_ARG_1 \\$1 +. if !r#DEPTH \{\ +. if \\n[#INDENT_ACTIVE] \{\ +. nr #STORED_HL_INDENT \\n[#HL_INDENT] +. nr #STORED_T_INDENT \\n[#T_INDENT] +. if \\n[#INDENT_STYLE_LEFT] \ +. nr #STORED_L_INDENT \\n[#L_INDENT] +. if \\n[#INDENT_STYLE_RIGHT] \ +. nr #STORED_R_INDENT \\n[#R_INDENT] +. if \\n[#INDENT_STYLE_BOTH] \{\ +. nr #STORED_BL_INDENT \\n[#BL_INDENT] +. nr #STORED_BR_INDENT \\n[#BR_INDENT] +. \} +. \} +. nr #CURRENT_L_LENGTH \\n[.l] +. nr #DEPTH 0 1 +. if \\n[#INDENT_ACTIVE]=1 \{\ +. if \\n[#INDENT_LEFT_ACTIVE]=1 \ +. nr #RESTORE_PREV_INDENT 1 +. if \\n[#INDENT_BOTH_ACTIVE]=1 \{\ +. ie \\n[#DOC_TYPE]=5 .IBX CLEAR +. el .IBX +. nr #ORIG_L_LENGTH \\n[.l] +. IB +. nr #RESTORE_PREV_INDENT 2 +. \} +. if \\n[#INDENT_RIGHT_ACTIVE]=1 \{\ +. ie \\n[#DOC_TYPE]=5 .IRX CLEAR +. el .IRX +. nr #ORIG_L_LENGTH \\n[.l] +. IR +. nr #RESTORE_PREV_INDENT 3 +. if \\n[#INDENT_LEFT_ACTIVE]=1 \ +. nr #RESTORE_PREV_INDENT 4 +. \} +. \} +. \} +. ds pre-list-quad \\*[$QUAD_VALUE] +. substring pre-list-quad 0 0 +. if '\\*[pre-list-quad]'C' \{\ +. if !'\\n[.z]'LIST*DIV' \{\ +. nr #PRE_LIST_QUAD \\n[.j] +. nr #LIST_CENTER 1 +. if !'\\n[.z]'LIST*DIV' .di LIST*DIV +\!. nr #IN_LIST 1 +. ad l +. \} +. \} +. if '\\*[pre-list-quad]'R' \{\ +. if !'\\n[.z]'LIST*DIV' \{\ +. nr #PRE_LIST_QUAD \\n[.j] +. nr #LIST_RIGHT 1 +. if !'\\n[.z]'LIST*DIV' .di LIST*DIV +\!. nr #IN_LIST 1 +. ad l +. \} +. \} +. ie \\n[#NUM_ARGS]=0 \{\ +. nr #ARGS_TO_LIST 1 \" So default behaves as if LIST BULLET +. ds $ENUMERATOR\\n+[#DEPTH] \[bu] +. ds $ENUMERATOR_TYPE\\n[#DEPTH] other +. ds $SEPARATOR +. ds $PREFIX +. ds $SEPARATOR\\n[#DEPTH] +. ds $PREFIX\\n[#DEPTH] +. \} +. el \{\ +. rr #ARGS_TO_LIST \" Clear this before processing arg 1. +. if '\\*[$LIST_ARG_1]'DASH' \{\ +. nr #ARGS_TO_LIST 1 +. ds $ENUMERATOR\\n+[#DEPTH] \[en] +. ds $ENUMERATOR_TYPE\\n[#DEPTH] other +. ds $SEPARATOR\\n[#DEPTH] +. ds $PREFIX\\n[#DEPTH] +. \} +. if '\\*[$LIST_ARG_1]'BULLET' \{\ +. nr #ARGS_TO_LIST 1 +. ds $ENUMERATOR\\n+[#DEPTH] \[bu] +. ds $ENUMERATOR_TYPE\\n[#DEPTH] other +. ds $SEPARATOR\\n[#DEPTH] +. ds $PREFIX\\n[#DEPTH] +. \} +. if '\\*[$LIST_ARG_1]'DIGIT' \{\ +. nr #ARGS_TO_LIST 1 +. nr #ENUMERATOR\\n+[#DEPTH] 0 1 +. ds $ENUMERATOR_TYPE\\n[#DEPTH] register +. ds $SEPARATOR\\n[#DEPTH] . +. ds $PREFIX\\n[#DEPTH] +. if \\n[#NUM_ARGS]>=2 \{\ +. ie '\\$2'NONE' .ds $SEPARATOR\\n[#DEPTH] +. el .ds $SEPARATOR\\n[#DEPTH] \\$2 +. if \\n[#NUM_ARGS]=3 .ds $PREFIX\\n[#DEPTH] \\$3 +. \} +. \} +. if '\\*[$LIST_ARG_1]'alpha' \{\ +. nr #ARGS_TO_LIST 1 +. nr #ENUMERATOR\\n+[#DEPTH] 0 1 +. af #ENUMERATOR\\n[#DEPTH] a +. ds $ENUMERATOR_TYPE\\n[#DEPTH] register +. ds $SEPARATOR\\n[#DEPTH] ) +. ds $PREFIX\\n[#DEPTH] +. if \\n[#NUM_ARGS]>=2 \{\ +. ie '\\$2'NONE' .ds $SEPARATOR\\n[#DEPTH] +. el .ds $SEPARATOR\\n[#DEPTH] \\$2 +. if \\n[#NUM_ARGS]=3 .ds $PREFIX\\n[#DEPTH] \\$3 +. \} +. \} +. if '\\*[$LIST_ARG_1]'ALPHA' \{\ +. nr #ARGS_TO_LIST 1 +. nr #ENUMERATOR\\n+[#DEPTH] 0 1 +. af #ENUMERATOR\\n[#DEPTH] A +. ds $ENUMERATOR_TYPE\\n[#DEPTH] register +. ds $SEPARATOR\\n[#DEPTH] ) +. ds $PREFIX\\n[#DEPTH] +. if \\n[#NUM_ARGS]>=2 \{\ +. ie '\\$2'NONE' .ds $SEPARATOR\\n[#DEPTH] +. el .ds $SEPARATOR\\n[#DEPTH] \\$2 +. if \\n[#NUM_ARGS]=3 \ +. ds $PREFIX\\n[#DEPTH] \\$3 +. \} +. \} +. if '\\*[$1ST_LETTER]'R' \{\ +. nr #ARGS_TO_LIST 1 +. nr #ENUMERATOR\\n+[#DEPTH] 0 1 +. if '\\*[$LIST_ARG_1]'roman' .af #ENUMERATOR\\n[#DEPTH] i +. if '\\*[$LIST_ARG_1]'ROMAN' .af #ENUMERATOR\\n[#DEPTH] I +. ds $ENUMERATOR_TYPE\\n[#DEPTH] roman +. ds $SEPARATOR\\n[#DEPTH] ) +. ds $PREFIX\\n[#DEPTH] +. if \\n[#NUM_ARGS]>=2 \{\ +. ie '\\$2'NONE' .ds $SEPARATOR\\n[#DEPTH] +. el .ds $SEPARATOR\\n[#DEPTH] \\$2 +. if \\n[#NUM_ARGS]=3 .ds $PREFIX\\n[#DEPTH] \\$3 +. \} +. \} +. if '\\*[$LIST_ARG_1]'USER' \{\ +. nr #ARGS_TO_LIST 1 +. ds $ENUMERATOR\\n+[#DEPTH] \\$2 +. ds $ENUMERATOR_TYPE\\n[#DEPTH] other +. ds $SEPARATOR\\n[#DEPTH] +. ds $PREFIX\\n[#DEPTH] +. \} +. if '\\*[$LIST_ARG_1]'VARIABLE' \{\ +. if \\n[#NUM_ARGS]<2 \{\ +. tm1 "[mom]: You must follow the \\$1 argument to \\$0 with the widest +. tm1 " enumerator to be used. See the documentation. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. nr #ARGS_TO_LIST 1 +. ds $ENUMERATOR\\n+[#DEPTH] +. ds $ENUMERATOR_TYPE\\n[#DEPTH] variable +. ds $ENUMERATOR_WIDTH\\n[#DEPTH] \w'\\$2\ ' +. ds $SEPARATOR\\n[#DEPTH] +. ds $PREFIX\\n[#DEPTH] +. \} +. if '\\*[$LIST_ARG_1]'PLAIN' \{\ +. nr #ARGS_TO_LIST 1 +. ds $ENUMERATOR\\n+[#DEPTH] +. ds $ENUMERATOR_TYPE\\n[#DEPTH] plain +. ds $SEPARATOR\\n[#DEPTH] +. ds $PREFIX\\n[#DEPTH] +. \} +. if \\n[#NUM_ARGS]=1 \{\ +. if !r#ARGS_TO_LIST \{\ +. ie \\n[#DEPTH]=1 \{\ +. ie \\n[#NEXT_DEPTH_BACK]=0 \{\ +. SET_LIST_INDENT +. if \\n[#QUIT]=1 \{\ +. QUIT_LISTS +. return +. \} +. return +. \} +. el \{\ +. QUIT_LISTS +. return +. \} +. \} +. el \{\ +. SET_LIST_INDENT +. return +. \} +. \} +. \} +. \} +. nr #TOTAL_LISTS \\n[#DEPTH] +. if '\\*[$ENUMERATOR_TYPE\\n[#DEPTH]]'register' \{\ +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]m\\*[$SEPARATOR\\n[#DEPTH]]\ ' +. if '\\*[$LIST_ARG_1]'ALPHA' .nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]M\\*[$SEPARATOR\\n[#DEPTH]]\ ' +. \} +. if '\\*[$ENUMERATOR_TYPE\\n[#DEPTH]]'roman' \ +. GET_ROMAN_INDENT +. if '\\*[$ENUMERATOR_TYPE\\n[#DEPTH]]'other' \ +. nr #LIST_INDENT\\n[#DEPTH] \w'\\*[$ENUMERATOR\\n[#DEPTH]]\ ' +. if '\\*[$ENUMERATOR_TYPE\\n[#DEPTH]]'variable' \ +. nr #LIST_INDENT\\n[#DEPTH] \\*[$ENUMERATOR_WIDTH\\n[#DEPTH]] +. ll \\n[#CURRENT_L_LENGTH]u +. ie \\n[#DEPTH]=1 \{\ +. ie \\n[#INDENT_ACTIVE]=1 \{\ +. if \\n[#INDENT_STYLE_LEFT]=1 \{\ +. if \\n[#L_INDENT_ILX] \{\ +. rr #L_INDENT +. rr #L_INDENT_ILX +. \} +. nr #L_INDENT \\n[#L_INDENT]+\\n[#LIST_INDENT\\n[#DEPTH]] +. nr #HL_INDENT\\n[#DEPTH] \\n[#LIST_INDENT\\n[#DEPTH]] +. nr #LIST_INDENT\\n[#DEPTH] \\n[#L_INDENT] +. \} +. if \\n[#INDENT_BOTH_ACTIVE]=1 \{\ +. nr #L_INDENT \\n[#BL_INDENT]+\\n[#LIST_INDENT\\n[#DEPTH]] +. nr #HL_INDENT\\n[#DEPTH] \\n[#LIST_INDENT\\n[#DEPTH]] +. nr #LIST_INDENT\\n[#DEPTH] \\n[#L_INDENT] +. \} +. if \\n[#INDENT_RIGHT_ACTIVE]=1 \{\ +. ie \\n[#INDENT_LEFT_ACTIVE]=1 \{\ +. \" Don't do anything; we already have a left indent +. \} +. el \{\ +. nr #L_INDENT +\\n[#LIST_INDENT\\n[#DEPTH]] +. nr #HL_INDENT\\n[#DEPTH] \\n[#LIST_INDENT\\n[#DEPTH]] +. \} +. \} +. \} +. el \{\ +. nr #L_INDENT +\\n[#LIST_INDENT\\n[#DEPTH]] +. nr #HL_INDENT\\n[#DEPTH] \\n[#LIST_INDENT\\n[#DEPTH]] +. \} +. \} +. el \{\ +. nr #L_INDENT +\\n[#LIST_INDENT\\n[#DEPTH]] +. nr #HL_INDENT\\n[#DEPTH] \\n[#LIST_INDENT\\n[#DEPTH]] +. \} +.END +\# +\# ITEM +\# ---- +\# *Arguments: +\# <none> | <space before item> +\# *Function: +\# Prints enumerator for a given list depth and prepares mom to +\# receive the text of an item. +\# +.MAC ITEM END +. ie \\n[#NUM_ARGS]=2 .sp \\$2 +. el \ +. if \B'\\$1' .sp \\$1 +. if '\\*[$ENUMERATOR_TYPE\\n[#DEPTH]]'plain' .nop +. if !r#DEPTH .return +. if \\n[#LINENUMBERS]=1 \{\ +. NUMBER_LINES OFF +. nr #LINENUMBERS 2 +. \} +. if \\n[#KERN]=1 \{\ +. nr #KERN_WAS_ON 1 +. KERN OFF +. \} +. rr #IN_ITEM +. IL +. nr #IN_ITEM 1 +. ll \\n[#CURRENT_L_LENGTH]u \" Set ll again because IL turns IB off. +. ie !'\\n[.z]'' \!.TRAP OFF +. el .TRAP OFF +. HI \\n[#HL_INDENT\\n[#DEPTH]]u +. if '\\*[$SEPARATOR\\n[#DEPTH]]')' .nr #SEP_TYPE 1 +. if '\\*[$SEPARATOR\\n[#DEPTH]]']' .nr #SEP_TYPE 1 +. if '\\*[$SEPARATOR\\n[#DEPTH]]'}' .nr #SEP_TYPE 1 +. ie \\n[#IN_BIB_LIST]=1 \{\ +. ie \\n[#ENUMERATOR\\n[#DEPTH]]<9 \{\ +. ie \\n[#SEP_TYPE]=1 .PRINT \ +\v'-.085m'\\*[$PREFIX\\n[#DEPTH]]\v'.085m'\ +\\n+[#ENUMERATOR\\n[#DEPTH]]\v'-.085m'\\*[$SEPARATOR\\n[#DEPTH]]\v'.085m' +. el .PRINT \ +\\*[$PREFIX\\n[#DEPTH]]\\n+[#ENUMERATOR\\n[#DEPTH]]\\*[$SEPARATOR\\n[#DEPTH]] +. \} +. el \{\ +. ie \\n[#SEP_TYPE]=1 .PRINT \ +\h'-\w'\0'u'\v'-.085m'\\*[$PREFIX\\n[#DEPTH]]\v'.085m'\ +\\n+[#ENUMERATOR\\n[#DEPTH]]\v'-.085m'\\*[$SEPARATOR\\n[#DEPTH]]\v'.085m' +. el .PRINT \ +\h'-\w'\0'u'\ +\\*[$PREFIX\\n[#DEPTH]]\\n+[#ENUMERATOR\\n[#DEPTH]]\\*[$SEPARATOR\\n[#DEPTH]] +. \} +. \} +. el \{\ +. ie '\\*[$ENUMERATOR_TYPE\\n[#DEPTH]]'register' \{\ +.\" DIGIT +. ie '\\g[#ENUMERATOR\\n[#DEPTH]]'0' \{\ +. ie \\n[#PAD_LIST_DIGITS\\n[#DEPTH]]=1 \{\ +. ie \\n[#ENUMERATOR\\n[#DEPTH]]<9 \{\ +. ie \\n[#SEP_TYPE]=1 .PRINT \ +\0\v'-.085m'\\*[$PREFIX\\n[#DEPTH]]\v'.085m'\\n+[#ENUMERATOR\\n[#DEPTH]]\ +\v'-.085m'\\*[$SEPARATOR\\n[#DEPTH]]\v'.085m' +. el .PRINT \ +\0\\*[$PREFIX\\n[#DEPTH]]\\n+[#ENUMERATOR\\n[#DEPTH]]\\*[$SEPARATOR\\n[#DEPTH]] +. \} +. el \{\ +. ie \\n[#SEP_TYPE]=1 .PRINT \ +\v'-.085m'\\*[$PREFIX\\n[#DEPTH]]\v'.085m'\\n+[#ENUMERATOR\\n[#DEPTH]]\ +\v'-.085m'\\*[$SEPARATOR\\n[#DEPTH]]\v'.085m' +. el .PRINT \ +\\*[$PREFIX\\n[#DEPTH]]\\n+[#ENUMERATOR\\n[#DEPTH]]\\*[$SEPARATOR\\n[#DEPTH]] +. \} +. \} +. el \{\ +. ie \\n[#SEP_TYPE]=1 .PRINT \ +\v'-.085m'\\*[$PREFIX\\n[#DEPTH]]\v'.085m'\\n+[#ENUMERATOR\\n[#DEPTH]]\ +\v'-.085m'\\*[$SEPARATOR\\n[#DEPTH]]\v'.085m' +. el .PRINT \ +\\*[$PREFIX\\n[#DEPTH]]\\n+[#ENUMERATOR\\n[#DEPTH]]\\*[$SEPARATOR\\n[#DEPTH]] +. \} +. \} +. el \{\ +.\" ALPHA +. ie '\\g[#ENUMERATOR\\n[#DEPTH]]'A' \{\ +. ie \\n[#SEP_TYPE]=1 .PRINT \ +\v'-.085m'\\*[$PREFIX\\n[#DEPTH]]\v'.085m'\\n+[#ENUMERATOR\\n[#DEPTH]]\ +\v'-.085m'\\*[$SEPARATOR\\n[#DEPTH]]\v'.085m' +. el .PRINT \ +\\*[$PREFIX\\n[#DEPTH]]\\n+[#ENUMERATOR\\n[#DEPTH]]\\*[$SEPARATOR\\n[#DEPTH]] +. \} +.\" alpha +. el .PRINT \ +\\*[$PREFIX\\n[#DEPTH]]\\n+[#ENUMERATOR\\n[#DEPTH]]\\*[$SEPARATOR\\n[#DEPTH]] +. \} +. \} +. if '\\*[$ENUMERATOR_TYPE\\n[#DEPTH]]'roman' \{\ +. ie \\n[#PAD_LIST_DIGITS\\n[#DEPTH]]=1 \{\ +.\" ROMAN I, padded +. ie '\\g[#ENUMERATOR\\n[#DEPTH]]'I' \{\ +. ie \\n[#SEP_TYPE]=1 .PRINT \ +\h'\\n[#HL_INDENT\\n[#DEPTH]]u'\h'-\w'\\*[$PREFIX\\n[#DEPTH]]\ +\\n+[#ENUMERATOR\\n[#DEPTH]]\\*[$SEPARATOR\\n[#DEPTH]]\0'u'\ +\v'-.085m'\\*[$PREFIX\\n[#DEPTH]]\v'.085m'\\n[#ENUMERATOR\\n[#DEPTH]]\ +\v'-.085m'\\*[$SEPARATOR\\n[#DEPTH]]\v'.085m' +. el .PRINT \ +\h'\\n[#HL_INDENT\\n[#DEPTH]]u'\h'-\w'\\*[$PREFIX\\n[#DEPTH]]\ +\\n+[#ENUMERATOR\\n[#DEPTH]]\\*[$SEPARATOR\\n[#DEPTH]]\ +\0'u'\\*[$PREFIX\\n[#DEPTH]]\\n[#ENUMERATOR\\n[#DEPTH]]\ +\\*[$SEPARATOR\\n[#DEPTH]] +. \} +.\" roman i, padded +. el .PRINT \ +\h'\\n[#HL_INDENT\\n[#DEPTH]]u'\h'-\w'\\*[$PREFIX\\n[#DEPTH]]\ +\\n+[#ENUMERATOR\\n[#DEPTH]]\\*[$SEPARATOR\\n[#DEPTH]]\0'u'\ +\\*[$PREFIX\\n[#DEPTH]]\\n[#ENUMERATOR\\n[#DEPTH]]\\*[$SEPARATOR\\n[#DEPTH]] +. \} +.\" No pad +. el \{\ +.\" ROMAN I, no pad +. ie '\\g[#ENUMERATOR\\n[#DEPTH]]'I' \{\ +. ie \\n[#SEP_TYPE]=1 .PRINT \ +\v'-.085m'\\*[$PREFIX\\n[#DEPTH]]\v'.085m'\\n+[#ENUMERATOR\\n[#DEPTH]]\ +\v'-.085m'\\*[$SEPARATOR\\n[#DEPTH]]\v'.085m' +. el .PRINT \ +\\*[$PREFIX\\n[#DEPTH]]\\n+[#ENUMERATOR\\n[#DEPTH]]\\*[$SEPARATOR\\n[#DEPTH]] +. \} +.\" roman i, no pad +. el .PRINT \ +\\*[$PREFIX\\n[#DEPTH]]\\n+[#ENUMERATOR\\n[#DEPTH]]\\*[$SEPARATOR\\n[#DEPTH]] +. \} +. \} +. if '\\*[$ENUMERATOR_TYPE\\n[#DEPTH]]'other' \ +. PRINT \\*[$ENUMERATOR\\n[#DEPTH]]\\*[$SEPARATOR\\n[#DEPTH]] +. if '\\*[$ENUMERATOR_TYPE\\n[#DEPTH]]'variable' \ +. PRINT \\$1 +. \} +. rr #SEP_TYPE +. EOL +. if \\n[#REF]=1 \{\ +. IL +\\n[#REF_BIB_INDENT]u +. ti \\n[#L_INDENT]u-\\n[#REF_BIB_INDENT]u +. \} +. ie !'\\n[.z]'' \!.TRAP +. el .TRAP +. if \\n[#KERN_WAS_ON]=1 \{\ +. KERN +. rr #KERN_WAS_ON +. \} +. if \\n[#LINENUMBERS]=2 \{\ +. NUMBER_LINES RESUME +. nr #LINENUMBERS 1 +. \} +.END +\# +\# A utility macro that determines the space to reserve for +\# roman numeral enumerated lists. Limit is 20 roman numerals +\# per list. If this isn't enough, the user can add to the +\# macro. +\# +.MAC GET_ROMAN_INDENT END +. if '\\*[$LIST_ARG_1]'roman' \{\ +. if '\\*[$ROMAN_WIDTH]'1' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 1 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]i\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'2' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 2 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]ii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'3' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 3 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]iii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'4' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 4 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]iii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'5' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 5 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]iii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'6' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 6 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]iii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'7' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 7 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]vii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'8' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 8 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]viii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'9' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 9 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]viii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'10' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 10 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]viii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'11' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 11 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]viii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'12' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 12 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]viii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'13' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 13 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]xiii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'14' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 14 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]xiii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'15' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 15 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]xiii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'16' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 16 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]xiii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'17' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 17 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]xvii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'18' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 18 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]xviii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'19' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 19 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]xviii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'20' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 20 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]xviii\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. \} +. if '\\*[$LIST_ARG_1]'ROMAN' \{\ +. if '\\*[$ROMAN_WIDTH]'1' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 1 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]I\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'2' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 2 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]II\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'3' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 3 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]III\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'4' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 4 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]IV\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'5' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 5 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]IV\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'6' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 6 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]IV\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'7' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 7 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]VII\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'8' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 8 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]VIII\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'9' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 9 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]VIII\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'10' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 10 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]VIII\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'11' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 11 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]VIII\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'12' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 12 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]VIII\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'13' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 13 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]XIII\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'14' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 14 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]XIV\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'15' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 15 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]XIV\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'16' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 16 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]XIV\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'17' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 17 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]XVII\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'18' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 18 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]XVIII\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'19' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 19 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]XVIII\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. if '\\*[$ROMAN_WIDTH]'20' \{\ +. ds $ROMAN_WIDTH\\n[#DEPTH] 20 +. nr #LIST_INDENT\\n[#DEPTH] \ +\w'\\*[$PREFIX\\n[#DEPTH]]XVIII\\*[$SEPARATOR\\n[#DEPTH]]\0' +. \} +. \} +.END +\# +\# SHIFT LIST +\# ---------- +\# *Arguments: +\# <amount by which to indent a list to the right> +\# *Function: +\# Adds the value of the arg to the current list's indent. +\# *Notes: +\# Requires a unit of measure. +\# +.MAC SHIFT_LIST END +. nr #SHIFT_LIST\\n[#DEPTH] (\\$1) +. nr #L_INDENT +\\n[#SHIFT_LIST\\n[#DEPTH]] +.END +\# +\# PAD LIST DIGITS +\# --------------- +\# *Arguments: +\# [ LEFT ] +\# *Function: +\# Adds a figure space to a list's hanging and left indent. If +\# LEFT is given, sets reg. #PAD_LIST_DIGITS to 1 for use in ITEM. +\# +.MAC PAD_LIST_DIGITS END +. if '\\g[#ENUMERATOR\\n[#DEPTH]]'0' \{\ +. nr #LIST_INDENT\\n[#DEPTH] +\\w'\\0' +. nr #L_INDENT \\n[#LIST_INDENT\\n[#DEPTH]]+\\n[#LIST_INDENT\\n-[#DEPTH]] +. nr #HL_INDENT\\n+[#DEPTH] +\\w'\\n[#ENUMERATOR\\n[#DEPTH]]' +. if '\\$1'LEFT' .nr #PAD_LIST_DIGITS\\n[#DEPTH] 1 +. \} +. if '\\g[#ENUMERATOR\\n[#DEPTH]]'i' \ +. if '\\$1'LEFT' .nr #PAD_LIST_DIGITS\\n[#DEPTH] 1 +. if '\\g[#ENUMERATOR\\n[#DEPTH]]'I' \ +. if '\\$1'LEFT' .nr #PAD_LIST_DIGITS\\n[#DEPTH] 1 +.END +\# +\# RESET LIST +\# ---------- +\# *Arguments: +\# none +\# *Function: +\# Resets register enumerators to 1, a, i... +\# +.MAC RESET_LIST END +. ie '\\$1'' .nr #ENUMERATOR\\n[#DEPTH] 0 1 +. el .nr #ENUMERATOR\\n[#DEPTH] \\$1-1 1 +.END +\# +\# QUIT LISTS +\# ---------- +\# *Arguments: +\# none +\# *Function: +\# Exits lists cleanly and restores any indents that were in +\# effect prior to LIST. +\# +.MAC QUIT_LISTS END +. br +. if '\\n[.z]'LIST*DIV' \{\ +\!. rr #IN_LIST +. di +. \} +. IQ CLEAR +. nr #HL_INDENT \\n[#STORED_HL_INDENT] +. nr #T_INDENT \\n[#STORED_T_INDENT] +. nr #L_INDENT \\n[#STORED_L_INDENT] +. nr #R_INDENT \\n[#STORED_R_INDENT] +. nr #BL_INDENT \\n[#STORED_BL_INDENT] +. nr #BR_INDENT \\n[#STORED_BR_INDENT] +. rr #STORED_HL_INDENT +. if \\n[#LIST_CENTER] \ +. nr #LIST_OFFSET_VALUE \\n[.l]-\\n[dl]/2 +. if \\n[#LIST_RIGHT] \{\ +. nr #LIST_OFFSET_VALUE \\n[.l]-\\n[dl] +. if r pdfbx-running \ +. nr #LIST_OFFSET_VALUE \ +\\n[.l]-\\n[dl]-\\*[gap\\n[stack]]-(\\*[wt\\n[stack]]/2) +. \} +. po +\\n[#LIST_OFFSET_VALUE]u +. if \\n[.u] .nr #FILLED 1 +. nf +. if dLIST*DIV \{\ +. LIST*DIV +. rm LIST*DIV +. \} +. if \\n[#FILLED] .fi +. if !\\n[#PRE_LIST_QUAD]=\\n[.j] .ad \\n[#PRE_LIST_QUAD] +. rr #FILLED +. po +. rr #PRE_LIST_QUAD +. if \\n[#RESTORE_PREV_INDENT]=1 \ +. IL +. if \\n[#RESTORE_PREV_INDENT]=2 \{\ +. ll \\n[#ORIG_L_LENGTH]u +. IB +. \} +. if \\n[#RESTORE_PREV_INDENT]=3 \{\ +. ll \\n[#ORIG_L_LENGTH]u +. IR +. \} +. if \\n[#RESTORE_PREV_INDENT]=4 \{\ +. nr #R_INDENT \\n[#STORED_R_INDENT] +. nr #L_INDENT \\n[#STORED_L_INDENT] +. ll \\n[#ORIG_L_LENGTH]u +. IR +. IL +. \} +.\" Clean up after exiting last depth of list +. nr #REMOVE 0 1 +. while \\n+[#REMOVE]<=\\n[#TOTAL_LISTS] \{\ +. rr #LIST_INDENT\\n[#REMOVE] +. rr #ENUMERATOR\\n[#REMOVE] +. rm $ENUMERATOR\\n[#REMOVE] +. rm $SEPARATOR\\n[#REMOVE] +. rm $ENUMERATOR_TYPE\\n[#REMOVE] +. rr #PAD_LIST_DIGITS\\n[#REMOVE] +. rr #SHIFT_LIST\\n[#REMOVE] +. \} +. rr #STORED_L_INDENT +. rr #STORED_BL_INDENT +. rr #STORED_BR_INDENT +. rr #STORED_R_INDENT +. rr #STORED_R_INDENT +. rr #REMOVE +. rr #TOTAL_LISTS +. rr #QUIT +. rr #DEPTH +. rr #NEXT_DEPTH_BACK +. rr #RESTORE_PREV_INDENT +. rr #ORIG_L_LENGTH +. rr #CURRENT_L_LENGTH +. rr #IN_ITEM +. rr #IN_ITEM_L_INDENT +.END +\# +\# SET LIST INDENT +\# --------------- +\# *Arguments: +\# none +\# *Function: +\# Restores indent of prev. list in nested lists. Also sets the +\# #QUIT register if an invocation of LIST OFF applies to the first +\# level of list. +\# +.MAC SET_LIST_INDENT END +. nr #NEXT_DEPTH_BACK \\n[#DEPTH]-1 +. if \\n[#NEXT_DEPTH_BACK]=0 \{\ +. nr #QUIT 1 +. if \\n[#INDENT_ACTIVE]=1 \{\ +. if \\n[#INDENT_STYLE_BOTH]=1 \{\ +. ie \\n[#DOCS] \ +. ll \\n[#DOC_L_LENGTH]u-\\n[#STORED_BR_INDENT]u +. el \ +. ll \\n[#L_LENGTH]u-\\n[#STORED_BR_INDENT]u +. in \\n[#BL_INDENT]u +. \} +. if \\n[#INDENT_STYLE_LEFT] \{\ +. in \\n[#STORED_L_INDENT]u +. \} +. if \\n[#INDENT_STYLE_RIGHT] \{\ +. ie \\n[#DOCS] \ +. ll \\n[#DOC_L_LENGTH]u-\\n[#STORED_R_INDENT]u +. el \ +. ll \\n[#L_LENGTH]u-\\n[#STORED_R_INDENT]u +. \} +. \} +. return +. \} +. nr #L_INDENT -\\n[#LIST_INDENT\\n[#DEPTH]]+\\n[#SHIFT_LIST\\n[#DEPTH]] +. nr #HL_INDENT \\n[#HL_INDENT\\n-[#DEPTH]] +.END +\# +\# ==================================================================== +\# +\# +++DOCUMENT PROCESSING MISC AND SUPPORT MACROS+++ +\# +\# COLLATE +\# ------- +\# *Arguments: +\# <none> +\# *Function: +\# Turns headers off (if on) and saves header state, sets register +\# #COLLATE to 1 (toggle), and breaks to a new page. +\# *Notes: +\# COLLATE exists primarily to allow putting multiple chapters in +\# a single file, although it can be used for any document type. After +\# COLLATE, any of the macros that normally precede START may be +\# used, and should behave as expected. +\# +\# N.B.--the START macro must be used after every COLLATE +\# +.MAC COLLATE END +. if dPDF.EXPORT .tm .ds pre-collate-\\n% \\n%@\\n[#COL_NUM] +. if \\n[defer] \{\ +. nr #BLANKPAGE_AFTER_DEFER 1 +. bp +. \} +. nr #HEADER_STATE \\n[#HEADERS_ON] +. if (\\n[defer]=0)&(\\n[float*defer]=0) .HEADERS OFF +. if \\n[#LINENUMBERS] \{\ +. NUMBER_LINES off +. nr #LINENUMBERS 2 +. \} +. if \\n[#BLANKPAGE] \{\ +. if \\n[nl]=\\n[#PAGE_TOP] \{\ +. nr #NO_NEWPAGE 1 +. RESTORE_SPACE +. \} +. rr #BLANKPAGE +. \} +. if \\n[defer] \ +. DO_FOOTER +. EOL +. ds $SAVED_DOC_FAM \\*[$DOC_FAM] +. ds $SAVED_PP_FT \\*[$PP_FT] +. nr #COLLATE 1 +. nr #PRE_COLLATE 1 +. nr #POST_TOP 1 +. nr #HEAD_1_NUM 0 1 +. if !\\n[#LISTS] \{\ +. if \\n[eqn*label-with-chapter]=1 .nr eqn*label-num 0 1 +. if \\n[float*label-with-chapter]=1 .nr fig*label-num 0 1 +. if \\n[pdf-img*label-with-chapter]=1 .nr fig*label-num 0 1 +. if \\n[pic*label-with-chapter]=1 .nr fig*label-num 0 1 +. if \\n[tbl*label-with-chapter]=1 .nr tbl*label-num 0 1 +. \} +. if \\n[#DOC_HEADER]=2 .nr #DOC_HEADER 1 +. if \\n[#PAGE_NUM_V_POS]=1 \{\ +. nr #PAGINATION_STATE \\n[#PAGINATE] +. PAGINATION OFF +. \} +. IQ CLEAR +. TQ +. LL \\n[#DOC_L_LENGTH]u +. PT_SIZE \\n[#DOC_PT_SIZE]u +. QUAD \\*[$DOC_QUAD] +. nr #SAVED_DOC_LEAD \\n[#DOC_LEAD] +. nr #COLLATED_DOC 1 +. vs \\n[#DOC_LEAD]u +\*[SLANTX] +\*[CONDX] +\*[EXTX] +. if \\n[#TOC] \{\ +. if \\n[TOC_BH]=1 .pdfswitchtopage before MOM:TOC +. if \\n[TOC_BH]=2 .pdfswitchtopage after MOM:TOC +. \} +. if !\\n[#NO_NEWPAGE] .NEWPAGE +. if !\\n[#TOC] \{\ +. if \\n[#FORCE_RECTO] \{\ +. ds $PN_FORMAT_CURR \\g[#PAGENUMBER] +. af #PAGENUMBER 1 +. if \\n[#PAGENUMBER]%2=1 .nr #ODD_PAGENUM 1 +. af #PAGENUMBER \\*[$PN_FORMAT_CURR] +. if \\n[#ODD_PAGENUM] .BLANKPAGE 1 DIVIDER +. rr #ODD_PAGENUM +. rr #BLANKPAGE_AFTER_DEFER +. \} +. \} +. rr #NO_NEWPAGE +. ch RR_@TOP +. rr @TOP +. if \\n[.ns] \{\ +. rs +. nop \& +. \} +. if '\\n[.ev]'PAGE_TRANSITION\\n[pg-trans]' .ev +. if \\n[#DEFER_PAGINATION] .PAGINATE +. if !'\\*[$RESTORE_PAGENUM_STYLE]'' \{\ +. PAGENUM_STYLE \\*[$RESTORE_PAGENUM_STYLE] +. rm $RESTORE_PAGENUM_STYLE +. \} +. if \\n[#CH_NUM] \ +. if \\n[#TOC]=0 .nr #CH_NUM +1 +. rm $EN_TITLE +. COVERTITLE +. DOC_COVERTITLE +. TITLE +. CHAPTER +. CHAPTER_TITLE +. SUBTITLE +. MISC +. rr #COVER_TITLE +. rr #DOC_COVER_TITLE +. rr #FROM_COVERTITLE +. rr #FROM_DOC_COVERTITLE +. rr #MISC +. rr #COVER_MISC +. rr #DOC_COVER_MISC +. rr #COPYRIGHT +. rr #COVER_COPYRIGHT +. rr #DOC_COVER_COPYRIGHT +. rr #COVER_AUTHOR +. rr #DOC_COVER_AUTHOR +. rm COVER_TEXT +. rm DOC_COVER_TEXT +. rm $COPYRIGHT +. rm $COVER_COPYRIGHT +. rm $DOC_COVER_COPYRIGHT +. rr #END_QUOTE +. rr #PAGENUM_STYLE_SET +. rr #DOC_COVER +. rr #COVER +. rr #LAST_LEVEL +. rr #LEVEL +. if \\n[#RESTORE_PN_V_POS] \{\ +. nr #PAGE_NUM_V_POS \\n[#RESTORE_PN_V_POS] +. rr #RESTORE_PN_V_POS +. \} +. nr #LOOP 0 1 +. while \\n+[#LOOP]<=\\n[@LEVEL] \ +. rr #TOC_HEAD_\\n[#LOOP]_INDENT_SET +. if \\n[#FLEX_ACTIVE] .rr #NO_FLEX +.END +\# +\# NUMBER_LINES +\# ------------ +\# *Arguments: +\# <starting line number> [ <increment> [ <gutter> ] ] +\# or +\# <anything> | RESUME +\# *Function: +\# Begin, suspend/turn off, or resume numbering of output lines. +\# +.MAC NUMBER_LINES END +. if '\\n[.z]'EPI_TEXT' .return +. if '\\$1'' \{\ +. tm1 "[mom]: NUMBER_LINES at line \\n[.c] has no argument. +. tm1 " You have forgotten to give a starting line number or 'RESUME'. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. if !\\n[#LINENUMBERS]=2 .nr #LINENUMBERS 1 +.\" Test whether the first arg is a digit. +. if \B'\\$1' \{\ +. if \\n[#QUOTE] \{\ +. if \\n[#QUOTE]=1 .ds macro QUOTE +. if \\n[#QUOTE]=2 .ds macro BLOCKQUOTE +. tm1 "[mom]: \\$0 at line \\n[.c] may not be used inside \\*[macro]. +. tm1 " Please set NUMBER_LINES before \\*[macro], followed by +. tm1 " NUMBER_\\*[macro]_LINES. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. nr #LN \\$1 +. ds $LN_NUM \\$1 +. if !'\\n[.z]'' .nr #RESTORE_LN_NUM 1 +. ie '\\$2'' \ +. if '\\*[$LN_INC]'' .ds $LN_INC 1 +. el .ds $LN_INC \\$2 +. ie '\\$3'' \ +. if !\\n[#LN_GUTTER] .nr #LN_GUTTER 2 +. el .nr #LN_GUTTER \\$3 +. \} +. ie !\\n[#LN] \{\ +.\" In other words, the first arg was not a digit. +. rr #LN +. ie '\\$1'RESUME' \{\ +. LN_PARAMS +. nm \\*[$LN_NUM] +. RESTORE_PARAMS +. \} +. el \{\ +. nm +.\" Register ln is still set and may confuse preprocessors like tbl. +.\" Still, resuming line numbering must be possible, so save ln in +.\" $LN_NUM +. ds $LN_NUM \\n[ln] +. if !\\n[#QUOTE] .nr ln 0 +. if !\\n[#LINENUMBERS]=2 .rr #LINENUMBERS +. \} +. \} +. el \{\ +. LN_PARAMS +. nm \\*[$LN_NUM] \\*[$LN_INC] \\n[#LN_GUTTER] -3-\\n[#LN_GUTTER] +. RESTORE_PARAMS +. if !'\\n[.z]'' .nr #DIVER_LN_OFF 1 +. \} +. rr #LN +.END +\# +\# LINENUMBER STYLE PARAMETERS +\# --------------------------- +\# *Arguments: +\# none +\# *Function: +\# LN_PARAMS sets parameters for line numbers. +\# RESTORE_PARAMS restores them after internal calls to .nm +\# *Notes: +\# It's not documented, but groff's linenumbering is processed +\# in a unique environment reserved for the numbers, such that +\# whatever style params were in effect prior to the invocation +\# of .nm remain in effect for the numbers even if the running +\# text has different params. Eg, If you set .gcolor to 'purple' +\# before .nm then set it back to what it was, the numbers will be +\# purple while the text remains at the default color. +\# +.MAC LN_PARAMS END +. ie d$LN_FAM .fam \\*[$LN_FAM] +. el .fam \\n[.fam] +. ie d$LN_FT .ft \\*[$LN_FT] +. el .ft \\n[.sty] +. ie d$LN_SIZE_CHANGE .ps \\*[$LN_SIZE_CHANGE] +. el .ps \\n[.s] +. ie d$LN_COLOR .COLOR \\*[$LN_COLOR] +. el .gcolor \\n[.m] +.END +\# +.MAC RESTORE_PARAMS END +. fam +. ft +. ps +. gcolor +.END +\# +\# Whether, at COLLATE, to reset line number to 1. +\# +\# NUMBER LINES PER SECTION +\# ------------------------ +\# *Argument: +\# none +\# *Function: +\# Sets register that determines whether, at COLLATE, to reset +\# line number to 1. +\# *Notes: +\# The default is to continue the line numbering from where it +\# left off. +\# +.MAC NUMBER_LINES_PER_SECTION END +. nr #PER_SECTION 1 +.END +\# +\# NUMBER QUOTE AND BLOCKQUOTE LINES AS PART OF RUNNING TEXT +\# --------------------------------------------------------- +\# *Argument: +\# <gutter> | <anything> +\# *Function: +\# Sets #(B)QUOTE_LN to 1 if no argument, or a single numeric +\# argument, is given; otherwise, turns (BLOCK)QUOTE linenumbering +\# off. +\# *Notes: +\# #(B)QUOTE is checked for in QUOTE and BLOCKQUOTE. +\# The single numeric argument allows establishing a different gutter from +\# the one used for line numbers in running text. +\# +.MAC NUMBER_QUOTE_LINES END +. ie \\n[#NUM_ARGS]=0 .nr #QUOTE_LN 1 +. el \{\ +. ie \B'\\$1' \{\ +. nr #QUOTE_LN 1 +. nr #Q_LN_GUTTER \\$1 +. \} +. el \{\ +. ie '\\$1'SILENT' .nr #SILENT_QUOTE_LN 1 +. el \{\ +. rr #QUOTE_LN +. rr #SILENT_QUOTE_LN +. \} +. \} +. \} +.END +\# +.MAC NUMBER_BLOCKQUOTE_LINES END +. ie \\n[#NUM_ARGS]=0 .nr #BQUOTE_LN 1 +. el \{\ +. ie \B'\\$1' \{\ +. nr #BQUOTE_LN 1 +. nr #BQ_LN_GUTTER \\$1 +. \} +. el \{\ +. ie '\\$1'SILENT' .nr #SILENT_BQUOTE_LN 1 +. el \{\ +. rr #BQUOTE_LN +. rr #SILENT_BQUOTE_LN +. \} +. \} +. \} +.END +\# +\# OUTPUT BLANK PAGES +\# ------------------ +\# *Argument: +\# <number of blank pages to output> [ DIVIDER [ NULL ] ] +\# *Function: +\# Outputs blank pages. +\# *Notes: +\# If recto/verso, each page is recto/verso, even if there's +\# nothing on it. +\# +\# The 1st argument to BLANKPAGE is non-optional. DIVIDER is for +\# blank pages before endnotes, bibliographies, tocs, new chapters. +\# +.MAC BLANKPAGE END +. nr #BLANKPAGE 1 +. nr #HOW_MANY \\$1 +. shift +. nr #PAGES 0 1 +. if \\n[#LINENUMBERS] \{\ +. nr #LINENUMBERS_WERE_ON 1 +. NUMBER_LINES OFF +. \} +. while \\n+[#PAGES]<=\\n[#HOW_MANY] \{\ +. if \\n[#HEADERS_ON]=1 \{\ +. nr #HEADERS_WERE_ON 1 +. HEADERS OFF +. \} +. if \\n[#PAGE_NUM_V_POS]=1 \{\ +. if \\n[#PAGINATE]=1 .nr #PAGINATE_WAS_ON 1 +. nr #RESTORE_PN_V_POS \\n[#PAGE_NUM_V_POS] +. PAGINATION OFF +. \} +. if \\n[#COLUMNS]=1 .nr #COLUMNS +1 +. NEWPAGE \" Break to blank page +. nop \& +. br +. if \\n[#FOOTERS_ON]=1 \{\ +. nr #FOOTERS_WERE_ON 1 +. FOOTERS OFF +. \} +. if \\n[#PAGE_NUM_V_POS]=2 \{\ +. if \\n[#PAGINATE]=1 .nr #PAGINATE_WAS_ON 1 +. nr #RESTORE_PN_V_POS \\n[#PAGE_NUM_V_POS] +. PAGINATION OFF +. \} +. if !'\\$1'DIVIDER' .if \\n[#HEADERS_WERE_ON] .HEADERS +. \} +. if \\n[#COLUMNS]=2 .nr #COLUMNS -1 +. NEWPAGE \" Break to text page +. ie '\\$1'DIVIDER' \{\ +. if \\n[#BLANKPAGE_AFTER_DEFER] .bp +. if \\n[#FOOTERS_WERE_ON] .FOOTERS +. if \\n[#RESTORE_PN_V_POS] \{\ +. if \\n[#PAGINATE_WAS_ON] .PAGINATE +. nr #PAGE_NUM_V_POS \\n[#RESTORE_PN_V_POS] +. \} +. if \\n[#HEADERS_WERE_ON] .HEADERS +. shift +. if '\\$1'NULL' .nr #PAGE_NUM_ADJ -\\n[#HOW_MANY] +. \} +. el \{\ +. if '\\$1'' \{\ +. if \\n[#FOOTERS_WERE_ON] .FOOTERS +. if \\n[#RESTORE_PN_V_POS] \{\ +. if \\n[#PAGINATE_WAS_ON] .PAGINATE +. nr #PAGE_NUM_V_POS \\n[#RESTORE_PN_V_POS] +. \} +. \} +. if '\\$1'NULL' \{\ +. if \\n[#FOOTERS_WERE_ON] .FOOTERS +. if \\n[#RESTORE_PN_V_POS]=2 \ +. nr #PAGE_NUM_V_POS \\n[#RESTORE_PN_V_POS] +. if \\n[#PAGE_NUM_V_POS]=2 \ +. if \\n[#PAGINATE_WAS_ON] .PAGINATE +. nr #PAGE_NUM_ADJ -\\n[#HOW_MANY] +. \} +. \} +. if \\n[#PAGINATE]=1 \ +. if \\n[#RESTORE_PN_V_POS]=1 \{\ +. RESTORE_SPACE +. sp |\\n[#HEADER_MARGIN]u +. PRINT_PAGE_NUMBER +. \} +. if \\n[#LINENUMBERS_WERE_ON] .NUMBER_LINES RESUME +. rr #HOW_MANY +. rr #HEADERS_WERE_ON +. rr #FOOTERS_WERE_ON +. rr #PAGINATE_WAS_ON +. rr #RESTORE_PN_V_POS +.END +\# +\# FLOATS +\# ------ +\# +.am PSPIC \" Need to do this for PSPIC inside a float +. vpt 0 +\h'(\\n[ps-offset]u + \\n[ps-deswid]u)' +. sp -1 +. vpt +.. +\# +.MAC PROCESS_FLOATS END +. if \\n[#TAB_ACTIVE] \{\ +. nr #RESTORE_TAB 1 +. TQ +. \} +. if !\\n[tbl*no-top-hook] .tbl@top-hook +. rr tbl*no-top-hook +. sp |\\n[#T_MARGIN]u-\\n[#DOC_LEAD]u +. if r pdfbx-defer \{\ +. nr lead-diff \\n[#LEAD_AT_FOOTER]-\\n[.v] +. sp |\\n[t]u-\\n[.v]u+\\n[lead-diff]u +. rr pdfbx-defer +. \} +. nr defer-count \\n[defer] +. nr #TMP_PAGE_OFFSET \\n[.o] +. po \\n[#L_MARGIN]u +. ev protect +. evc FLOAT +. nf +. RESTORE_SPACE +. if '\\*[float*type:\\n[defer]]'boxed-tbl:\\n[defer]' \{\ +. ch RR_@TOP +.\" Get depth of the first deferred float when there's more than one. +. if (\\n[.t] >= 1)&(\\n[float-depth:\\n[defer]] > (\\n[.t]+\\n[#DOC_LEAD])) \ +. tbl*float-warning +. if \\n[#MLA] .sp \\n[tbl*label-lead-diff]u +. if (\\n[tbl*have-caption:\\n[defer]]=1)&(\\n[tbl*caption-after-label]=0) \ +. sp \\n[tbl*caption-lead-diff]u +. if \\n[tbl*caption-after-label] \ +. sp |\\n[#T_MARGIN]u-\\n[#DOC_LEAD]u +. \} +. if \\n[float*pic:1] \{\ +. if (\\n[pic*have-caption]=1)&(\\n[pic*caption-after-label]=0) \{\ +. ie \\n[#COLUMNS] \ +. sp |\\n[dc]u+\\n[pic*caption-lead-diff]u +. el .sp |\\n[#T_MARGIN]u-\\n[#DOC_LEAD]u+\\n[pic*caption-lead-diff]u +. \} +. rr pic*caption-lead-diff +. rr pic*top-lead-diff +. rr float*pic +. \} +. if \\n[float*img:1] \{\ +. ie \\n[#COLUMNS] \ +. sp |\\n[dc]u +. el \ +. sp |\\n[#T_MARGIN]u-\\n[#DOC_LEAD]u +. if \\n[pdf-img:frame] \{\ +. sp -(\\*[pdf-img:frame-weight]p*2u) +. rr pdf-img:frame +. \} +. \} +. if \\n[defers] .rr defers +. nr loop-count 0 1 +. nr new-defer 0 1 +. while \\n+[loop-count]<=\\n[defer-count] \{\ +. nr tbl*no-top-hook 1 +. rnn defer float*defer \" So '.if \n[defer]' is skipped during float output +. vpt +. ch RR_@TOP +. rr @TOP +. if \\n[pdf-img*have-caption] \ +. if !\\n[pdf-img*caption-after-label] .sp -.5v +. rr pdf-img*have-caption +. rr pic*have-caption +. if '\\*[float*type:\\n[loop-count]]'table:\\n[loop-count]' \{\ +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u +. ch FN_OVERFLOW_TRAP -\\n[#FN_OVERFLOW_TRAP_POS]u +. \} +. ie !\\n[float-span:\\n[loop-count]] \{\ +. ie ((\\n[float-depth:\\n[loop-count]]-\\n[.v])>\\n[.t]):(\\n[D-float:\\n[loop-count]]>\\n[.t]):(\\n[defers]=1) \{\ +.\" Insufficient space, defer to next page +. nr defers 1 +. rn FLOAT*DIV:\\n[loop-count] NEW*FLOAT*DIV:\\n+[new-defer] +. rnn float-depth:\\n[loop-count] new-float-depth:\\n[new-defer] +. rnn D-float:\\n[loop-count] new-D-float:\\n[new-defer] +. \} +. el \{\ +. output-float +. ie !r pdfboxed \{\ +. ie (\\n[.t]-2)<(\\n[#DOC_LEAD]u/2) .SHIM_1 +. el .sp .5 +. \} +. el .rr pdfboxed +. \} +. \} +. el \{\ +. rr tbl*no-top-hook +. if \\n[float-span:\\n[loop-count]] \ +. rn tbl*header-div:\\n[loop-count] tbl*header-div:span +. ie !r pdfboxed \{\ +. output-float +. sp .5 +. \} +. el .rr pdfboxed +. \} +. if !\\n[loop-count]=\\n[defer-count] .rr flexed +. rr float-span:\\n[loop-count] +. rr float*tbl:\\n[loop-count] +. rr tbl*have-caption:\\n[loop-count] +. rr float*tbl*center:\\n[loop-count] +. rr tbl*have-header:\\n[loop-count] +. rm float*div:\\n[loop-count] +. rr float-depth:\\n[loop-count] +. rm tbl*header-div:\\n[loop-count] +. rm float*type:\\n[loop-count] +. \} +. if !\\n[float*defer]=1 \{\ +. if !(\\n[loop-count]-1)=1 \{\ +. if !\\n[.t]=1 .sp -.5 +. \} +. \} +. if !\\n[@no-shim] \ +. if !\\n[q-float] \ +. if !\\n[#NO_SHIM] .SHIM +.\" FLOAT arrays are empty now +.\" Rename new arrays (FLOATs deferred to next page) to proper names +. rr float*defer +. rnn new-defer defer +. nr loop-count 0 1 +. while \\n+[loop-count]<=\\n[defer] \{\ +. rn NEW*FLOAT*DIV:\\n[loop-count] FLOAT*DIV:\\n[loop-count] +. rnn new-float-depth:\\n[loop-count] float-depth:\\n[loop-count] +. rnn new-D-float:\\n[loop-count] D-float:\\n[loop-count] +. \} +. if !\\n[#TMP_PAGE_OFFSET]=\\n[.o] .po \\n[#TMP_PAGE_OFFSET]u +. rr #TMP_PAGE_OFFSET +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u +. ch FN_OVERFLOW_TRAP -\\n[#FN_OVERFLOW_TRAP_POS]u +. if \\n[float-depth:1]>\\n[.t] .bp +. ie !\\n[#NO_SHIM] .SHIM +. el \{\ +. if !\\n[#NO_FLEX] \ +. if !\\n[flexed] .FLEX +. \} +. if !\\n[#NO_SHIM] \ +. if \\n[#SHIM]>(\\n[#DOC_LEAD]-(\\n[#DOC_LEAD]/4)) \ +' sp -\\n[#DOC_LEAD]u +. ie !\\n[flex:force] .ns +. el \{\ +. rr flex:force +. if !\\n[#NO_FLEX] .FLEX +. \} +. nr tbl*have-header 0 +. rr tbl*have-caption +. rr loop-count +. rr defer-count +. rr float*before-shim +. rr float*after-shim +. rm float-adj +. rr check-indent +. if \\n[#NEWPAGE] \{\ +. vpt +' bp +. rr #NEWPAGE +. \} +. rr float*img +. rr float*eqn +. rr float*tbl +. rr float*pic +. if \\n[#RESTORE_TAB] \{\ +. TAB \\n[#CURRENT_TAB] +. rr #RESTORE_TAB +. \} +.END +\# +.MAC output-float END +. if \\n[float*img] \{\ +. if \\n[loop-count]=1 .nr no-top-space:1 1 +. \} +. vpt 0 +. if \\n[.ns] \{\ +. rs +. nop \& +. sp -1 +. \} +. if \\n[no-top-space:1] \{\ +. ie !\\n[#COLUMNS] \{\ +. sp |\\n[#T_MARGIN]u-\\n[#DOC_LEAD]u +. ns +. \} +. el .sp |\\n[dc]u +. if \\n[float*tbl:1] \{\ +. if !\\n[no-top-space:1] .RESTORE_SPACE +. ie \\n[tbl*caption-top-lead-diff] \{\ +. sp \\n[tbl*caption-top-lead-diff]u +. rr tbl*caption-top-lead-diff +. \} +. el \{\ +. if '\\*[float*type:1]'boxed-tbl:1' \{\ +. ie (\\n[tbl*have-caption]=1)&(\\n[tbl*caption-after-label]=0) .sp .3n +. el .sp (\\n[#DOC_LEAD]u/2u)+.3n +. \} +. \} +. rr float*tbl:1 +. \} +. if \\n[float*img:1] \{\ +. RESTORE_SPACE +. if \\n[pdf-img*caption-top-lead-diff] \{\ +. sp \\n[pdf-img*caption-top-lead-diff]u +. rr pdf-img*caption-top-lead-diff +. \} +. \} +. \} +. if \\n[float*pic] \{\ +. nr pic*top-space-adj \\n[#DOC_LEAD]-\\n[pic@text-lead] +. if (\\n[pic*have-caption]=0):(\\n[pic*caption-after-label]=1) \ +. sp \\n[pic*top-space-adj]u +. if \\n[#COLUMNS] \ +. if !'\\*[pic*space-adj:\\n[loop-count]]'' \ +. sp \\*[pic*space-adj:\\n[loop-count]] +. \} +. nf +. if \\n[q-float] \ +. if !\\n[has-caption] .sp \\n[#Q_LEAD_DIFF]u +. if \\n[Q-float]=2 .sp |\\n[t]u-.5v +. ns +. vpt +. if \\n[check-indent] \{\ +. if \\n[#INDENT_LEFT_ACTIVE] \{\ +. in \\n[#L_INDENT]u/2u +. \} +. \} +. rr no-top-space:1 +. if \\n[loop-count]>1 \{\ +. if !'\\*[float-adj:\\n[loop-count]]'' \{\ +. rs +. sp \\*[float-adj:\\n[loop-count]] +. ns +. nr restore-v-pos 1 +. \} +. \} +. nr check-indent 1 +. FLOAT*DIV:\\n[loop-count] +. if \\n[no-top-space:1] \ +. RESTORE_SPACE +. if \\n[restore-v-pos] \{\ +. sp -\\*[float-adj:\\n[loop-count]] +. rm float-adj:\\n[loop-count] +. rr restore-v-pos +. \} +. if r float*img:1 \{\ +. sp .5 +. rr float*img:1 +. \} +. if r Q-float:1 \{\ +. if !\\n[#FULLSPACE_QUOTES] .sp -.5 +. rr Q-float:1 +. \} +. if \\n[#COLUMNS] \ +. if !'\\*[pic*space-adj:\\n[loop-count]]'' \ +. sp -\\*[pic*space-adj:\\n[loop-count]] +. rm pic*space-adj:\\n[loop-count] +. if \\n[D-float:1] .rr D-float:1 +. rr D-float +. rr @no-shim +. rr q-float +. rm B_QUOTE +. rm P_QUOTE +.END +\# +\# FLOAT +\# ----- +\# *Arguments: +\# [ ADJUST +|-<amount> ] [ FORCE] [ SPAN] [ NO_SHIM] | [ NO_FLEX ] [ TARGET ] | <anything> +\# *Function: +\# Captures input in a diversion, which is output immediately if +\# there's room on the page; otherwise outputs diversion at top of +\# next page. +\# *Notes: +\# ADJUST allows for raising or lowering the contents of +\# the diversion within the space allotted. FORCE breaks to +\# a new page immediately. +\# +\# +.MAC FLOAT END +. nr ll-pre-float \\n[.l] +. if \\n[#NUM_ARGS]>0 \{\ +. nr loop-count 0 1 +. nr loop-counter \\n[#NUM_ARGS] +. while \\n+[loop-count]<=\\n[loop-counter] \{\ +. if '\\$1'FORCE' \{\ +. nr #FORCE 1 +. shift +. \} +. if '\\$1'SPAN' \{\ +. nr float-span 1 +. shift +. \} +. if '\\$1'ADJUST' \{\ +. shift +. ds float-adj \\$1 +. shift +. \} +. if '\\$1'CENTER' \{\ +. nr center-float 1 +. shift +. \} +. if '\\$1'CENTRE' \{\ +. nr center-float 1 +. shift +. \} +. if '\\$1'INDENT' \{\ +. shift +. nr indent-float \\$1 +. shift +. \} +. if '\\$1'RIGHT' \{\ +. nr right-float 1 +. shift +. \} +. if '\\$1'NO_SHIM' \{\ +. nr @no-shim 1 +. shift +. \} +. if '\\$1'NO_FLEX' \{\ +. nr @no-flex 1 +. shift 1 +. \} +. if '\\$1'TARGET' \{\ +. shift +. ds float*target "\\$1 +. shift 1 +. \} +. \} +. \} +. ie \\n[float*started] .rr float*started +. el \{\ +. while !'\\$1'' .shift 1 +. nr float*started 1 +. \} +. ie '\\$1'' \{\ +.\" Harmonize floats treated as defers and floats proper to the top +.\" of the next page between passes when flex is enabled. +.\" +.\" Without this, floats near the bottom of the page may be deferred +.\" on the first pass, but when flex-spacing moves the line just +.\" before the float to the bottom of the page, the upcoming .br +.\" causes the float to be proper to the next page instead of +.\" deferred to it. +. nr floatnum +1 +. ie !\\n[#NO_FLEX] \{\ +.\" Only on 2nd pass +. if !dPDF.EXPORT \{\ +. ie d float\\n[floatnum]:no-defer .br +. el \{\ +.\" .v in the following is arbitrary. Groff rounds down decimal +.\" fractions so flex-spacing may be slightly short. Since there +.\" are no conditions under which a .t-1 (bottom margin) < .v +.\" on the 1st pass doesn't cause a float to be deferred, all floats +.\" on the second pass that meet the condition are also, correctly, +.\" deferred. +. if (\\n[.t]-1)<\\n[.v] \ +. if !\\n[@TOP] .nr no-break 1 +. \} +. \} +.\" Only on 1st pass +. ie !\\n[no-break] \{\ +. ds pre-float:page@col \\n%@\\n[#COL_NUM] +. br +. ds post-float:page@col \\n%@\\n[#COL_NUM] +. if dPDF.EXPORT \{\ +. if !'\\*[pre-float:page@col]'\\*[post-float:page@col]' \ +. tm .ds float\\n[floatnum]:no-defer 1 +. \} +. \} +. el .rr no-break +. \} +. el .br +. if \\n[nl]=\\n[#PAGE_TOP] \ +. RESTORE_SPACE +. ds ev-pre-float \\n[.ev] +. ev FLOAT +. evc \\*[ev-pre-float] +. if \\n[.u] .nr fill-pre-float 1 \" Needed for tbl +. di FLOAT*DIV +. if !'\\*[float*target]'' .PDF_TARGET "\\*[float*target] +. rm float*target +. nf +. \} +. el \{\ +. br +.\" So @no-shim persists if float output with output-float +. if r @no-shim .nr float*no-shim 1 +. if \\n[float-span] \{\ +. nr span 1 +\!. rr span +. \} +\!. rm tbl*header-div:span +\!. nr tbl*no-print-header 1 +. di +. if \\n[float-span] \{\ +. nr dn-save \\n[dn] +. da FLOAT*DIV +\!. rr float-span +. da +. nr dn \\n[dn-save] +. rr dn-save +. \} +. ie \\n[float*tbl] \ +. if !\\n[tbl*have-header] .ev 0 +. el .ev 0 +. if \\n[tbl*boxed] \{\ +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u+\\n[#DOC_LEAD]u +. ch FN_OVERFLOW_TRAP -\\n[#FN_OVERFLOW_TRAP_POS]u+\\n[#DOC_LEAD]u +. ie !\\n[#MLA] \{\ +. ie (\\n[tbl@label]=1):(\\n[tbl@source]=1):(\\n[tbl*autolabel]=1) .nr dn -.65v +. el .nr dn +.65v +. rr tbl@label +. rr tbl@source +. \} +. el .if !\\n[tbl@source] .nr dn -1.65v +. \} +.\" Defer float +. if (\\n[dn]>\\n[.t]):(\\n[D-float]>\\n[.t]):(\\n[defer]>0) \{\ +. if !\\n[float-span] \{\ +. if (\\n[dn]+(\\n[.v]*2)>(\\n[.p]-\\n[#TOP_MARGIN]-\\n[#DOC_LEAD]-\\n[#B_MARGIN])) \{\ +. tm1 "[mom]: Floated element exceeds page depth. +. ab [mom]: Aborting '\\n[.F]' at line \\n[.c]. +. \} +. \} +.\" Save depth of diversion here. The .da zeroes it. +. nr dn-save \\n[dn] +. if \\n[#FLEX_ACTIVE] \{\ +. if !\\n[@no-flex] \{\ +. da FLOAT*DIV +\!. FLEX +\!. nr flexed 1 +. da +. \} +. \} +. nr dn \\n[dn-save] +. rr dn-save +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u +. ch FN_OVERFLOW_TRAP -\\n[#FN_OVERFLOW_TRAP_POS]u +. ev 0 +. ie \\n[@TOP] \{\ +. br +. if \\n[tbl*boxed] .rs +. rr tbl*boxed +. \} +. el \{\ +. if !\\n[defer] .nr defer 0 1 +. rn FLOAT*DIV FLOAT*DIV:\\n+[defer] +. if !'\\*[float-adj]'' \ +. rn float-adj float-adj:\\n[defer] +. if \\n[float-span] \ +. if !\\n[tbl*boxed] .rnn float-span float-span:\\n[defer] +. if \\n[float*tbl] \{\ +. if \\n[defer]>0 \{\ +. nr no-top-space:\\n[defer] 1 +. nr float*tbl:\\n[defer] 1 +. if \\n[tbl*have-caption] \ +. nr tbl*have-caption:\\n[defer] 1 +. \} +. ie \\n[tbl*boxed] \ +. ds float*type:\\n[defer] boxed-tbl:\\n[defer] +. el .ds float*type:\\n[defer] table:\\n[defer] +. if \\n[tbl*center] .nr float*tbl-center:\\n[defer] 1 +. if \\n[tbl*have-header] .rnn tbl*have-header tbl*have-header:\\n[defer] +. rn tbl*header-div tbl*header-div:\\n[defer] +. rr tbl*center +. \} +. if \\n[float*eqn] \{\ +. if \\n[defer]=1 .nr no-top-space:\\n[defer] 1 +. ds float*type:\\n[defer] eqn +. \} +. if \\n[float*pic] \{\ +. ds float*type:\\n[defer] pic +. nr float*pic:\\n[defer] 1 +. rn pic*space-adj pic*space-adj:\\n[defer] +. \} +. if \\n[float*img] \{\ +. ds float*type:\\n[defer] img +. nr float*img:\\n[defer] 1 +. nr no-top-space:\\n[defer] 1 +. \} +. if \\n[D-float] .nr D-float:\\n[defer] \\n[D-float] +. if \\n[Q-float] .nr Q-float:\\n[defer] \\n[#Q-float] +. nr float-depth:\\n[defer] \\n[dn] +. if \\n[#FORCE] \{\ +. ie \\n[#COLUMNS] .COL_NEXT +. el .NEWPAGE +. rr #FORCE +. \} +. if \\n[tbl*boxed] .rr tbl*boxed +. if \\n[table] .rr table +. br +. return \" output div after header +. \} +. \} +. nr dn-save \\n[dn] +. if \\n[#FLEX_ACTIVE] \{\ +. if !\\n[@no-flex] \{\ +. da FLOAT*DIV +\!. FLEX +\!. nr flexed 1 +. da +. \} +. \} +. nr dn \\n[dn-save] +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u +. ch FN_OVERFLOW_TRAP -\\n[#FN_OVERFLOW_TRAP_POS]u +. vpt 0 +. if !'\\*[float-adj]'' .sp \\*[float-adj] +. if \\n[.u] .nr fill 1 +. if \\n[@TOP] \{\ +. nr no-adjust 1 +. rr @TOP +. \} +. if \\n[float*tbl] \{\ +. if (\\n[#MLA]=1)&(\\n[tbl@source]=0) \ +. chop FLOAT*DIV +. if \\n[nl]=\\n[#PAGE_TOP] \{\ +. ie (\\n[tbl*have-caption]=1)&(\\n[tbl*caption-after-label]=0) \{\ +. ie !\\n[#MLA] .sp \\n[tbl*caption-lead-diff]u +. el .ch RR_@TOP +. \} +. el \{\ +. ev protect +. evc FLOAT +. nf +. rs +. ie \\n[tbl*boxed] .sp |\\n[#PAGE_TOP]u+.3n +. el .sp |\\n[#PAGE_TOP]u-.25v +. \} +. \} +. \} +. if \\n[float*img] \ +. if \\n[pdf-img:frame] \ +. sp -(\\*[pdf-img:frame-weight]p*2u) +. if !'\\n[.ev]'protect' \{\ +. ev protect +. evc FLOAT +' nf +. \} +. if \\n[float*tbl] \{\ +. if \\n[tbl*boxed] \ +. if \\n[tbl*center] \ +. if \\n[#L_INDENT] \ +. in -\\n[#L_INDENT]u/2u +. \} +. if \\n[center-float] \ +. in (\\n[.l]u-\\n[dl]u)/2u +. if \\n[indent-float] \ +. in \\n[indent-float]u +. if \\n[right-float] \ +. in \\n[.l]u-\\n[dl]u +. FLOAT*DIV +. if (\\n[center-float]>0):(\\n[indent-float]>0):(\\n[right-float]>0) \ +. in +. ev +. if \\n[float*tbl] \{\ +. rr tbl*no-print-header +. ie \\n[tbl*boxed] \{\ +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u +. ch FN_OVERFLOW_TRAP -\\n[#FN_OVERFLOW_TRAP_POS]u +. ie \\n[nl]>(\\n[.p]+\\n[#VARIABLE_FOOTER_POS]) \{\ +. ie \\n[#COLUMNS] .COL_NEXT +. el .NEWPAGE +. \} +. el \{\ +. if \\n[dn-save]=\\n[bx-tbl-depth] .sp .35v +. rr dn-save +. if !\\n[tbl*plain-boxed] \{\ +. if !\\n[tbl*autolabel] \{\ +. if !\\n[#MLA] \{\ +. if \\n[tbl@label]=1 .sp .5 +. \} +. \} +. \} +. rr tbl*boxed +. rr bx-tbl-depth +. \} +. \} +. el \{\ +. if !'\\*[tbl*label]'' \ +. if \\n[tbl*autolabel]=0 .sp .5 +. \} +. rr float*tbl +. rr tbl*center +. rm tbl*header-div +. rr tbl*have-caption +. rr tbl*have-label +. rr tbl*have-source +. rm tbl*caption +. rm tbl*label +. rm tbl*source +. \} +. if \\n[float*img] \ +. if (\\n[.t]-1)>(\\n[#DOC_LEAD]u/2u) .sp .5 +. if \\n[D-float] \{\ +. ie \\n[dn]=0 .sp \\n[D-float]u+\\n[#DOC_LEAD]u +. el \ +. if \\n[dn]<\\n[D-float] \ +. sp \\n[D-float]u+\\n[#DOC_LEAD]u-\\n[dn]u +.\" Flex won't grab .h of D-floats without a dummy text line. +. vpt 0 +. nop \& +. sp -1 +. vpt 1 +. \} +. if \\n[fill] \{\ +. fi +. rr fill +. \} +. rm FLOAT*DIV +. if !'\\*[float-adj]'' \ +. if !\\n[no-adjust] .sp -\\*[float-adj] +. vpt +. if \\n[Q-float] \{\ +. sp .5 +. rr Q-float +. \} +. if !\\n[#NO_SHIM] \ +. if !\\n[@no-shim] .SHIM +. rm float-adj +. rm no-adjust +. rr center-float +. rr indent-float +. rr right-float +. rr D-float +. rr @no-shim +. rr @no-flex +. rr #FORCE +. rm P_QUOTE +. rm B_QUOTE +. if \\n[float*img] .rr float*img +. if \\n[float*pic] .rr float*pic +. if \\n[float*eqn] .rr float*eqn +. rr float*target +. rm float*target +. if \\n[#NO_SHIM] \ +. if !\\n[#NO_FLEX] .nr post-float 1 +. ev \\*[ev-pre-float] +. rr fill-pre-float +. rm ev-pre-float +. \} +.END +\# +\# SET TRAPS FOR HEADERS/FOOTERS/FOOTNOTES +\# --------------------------------------- +\# *Arguments: +\# <none> +\# *Function: +\# Sets header/footer/footnotes/etc... traps. +\# +\# TRAPS calculates the number of lines that actually fit on a +\# page based on #B_MARGIN and resets page bottom trap to coincide +\# with the depth of that number of lines, or, if #ADJ_DOC_LEAD=1, +\# adjusts #DOC_LEAD so that the last line of text on a page falls +\# exactly on #B_MARGIN. +\# +.MAC RR_@TOP END \" Trap-invoked after first line of text on a new page +. rr @TOP +. if \\n[.ns] \{\ +. vpt 0 +. rs +. if \\n[.u] .nr fill 1 +. nf +. nop \& +. sp -1 +. if \\n[fill] .fi +. if r #NEWPAGE .rr #NEWPAGE +. \} +. if \\n[.vpt]=0 .vpt +.END +\# +.MAC TRAPS END +. if !\\n[#UNADJUSTED_DOC_LEAD] .nr #UNADJUSTED_DOC_LEAD \\n[#DOC@LEAD] +.\" Remove all header/footer traps +. if !\\n[#NO_TRAP_RESET] \{\ +. ch DO_T_MARGIN +. ch DO_B_MARGIN +. ch HEADER +. ch FOOTER +. ch FN_OVERFLOW_TRAP +.\" Plant header trap +. wh 0 HEADER +. \} +.\" Adjust lead so last line of text falls on B_MARGIN +. nr #LINES_PER_PAGE 0 1 +. nr #DOC_LEAD_ADJ 0 1 +. nr #DEPTH_TO_B_MARGIN \\n[#PAGE_LENGTH]-\\n[#ORIGINAL_B_MARGIN]-\\n[#DOC_LEAD] +.\" Get the number of unadjusted lines that fit on the page; always a +.\" bit short of the bottom margin +. while \\n[#T_MARGIN]+(\\n[#DOC_LEAD]*\\n+[#LINES_PER_PAGE])<\\n[#DEPTH_TO_B_MARGIN] \{\ +. +. \} +. nr #LINES_PER_PAGE -1 +.\" Add machine units, 1 at a time, increasing the leading until the +.\" new leading fills the page properly +. while \\n[#T_MARGIN]+(\\n[#DOC_LEAD]+\\n+[#DOC_LEAD_ADJ]*\\n[#LINES_PER_PAGE])<=\\n[#DEPTH_TO_B_MARGIN] \{\ +. +. \} +. DOC_LEAD \\n[#DOC_LEAD]u+\\n[#DOC_LEAD_ADJ]u +.\" The "visual" bottom margin is what \n[nl] would report on the +.\" last line before the FOOTER trap is sprung +. nr #VISUAL_B_MARGIN \\n[#T_MARGIN]+(\\n[#LINES_PER_PAGE]*\\n[#DOC_LEAD]) +.\" Get the difference between #B_MARGIN and #VISUAL_B_MARGIN +. nr #FOOTER_DIFF (\\n[#PAGE_LENGTH]-\\n[#B_MARGIN])-\\n[#VISUAL_B_MARGIN] +.\" Set #B_MARGIN to 1 machine unit lower on the page than #VISUAL_B_MARGIN +. nr #B_MARGIN \\n[#B_MARGIN]+(\\n[#FOOTER_DIFF]-1) +.\" Set the FN_OVERFLOW_TRAP position +. nr #FN_OVERFLOW_TRAP_POS \\n[#B_MARGIN]-\\n[#FN_LEAD] +. if \\n[#PRINT_STYLE]=1 .nr #FN_OVERFLOW_TRAP_POS \\n[#ORIGINAL_B_MARGIN]u +.\" Set footer and footnote overflow traps +. if !\\n[#NO_TRAP_RESET] \{\ +. nr #FN_COUNT 0 1 +. nr #SPACE_REMAINING 0 +. nr #FN_DEPTH 0 +. nr #VARIABLE_FOOTER_POS 0-\\n[#B_MARGIN]u +. wh \\n[.p]u FOOTER +. wh -(\\n[#FN_OVERFLOW_TRAP_POS]u) FN_OVERFLOW_TRAP +. ch FOOTER -\\n[#B_MARGIN]u +. \} +.END +\# +\# CHECK INDENT +\# ------------ +\# *Arguments: +\# <none> +\# *Function: +\# Adds left, right, or both indent values to document elements +\# like heads and subheads that are processed in environments. +\# +.MAC CHECK_INDENT END +. if \\n[#INDENT_LEFT_ACTIVE] \{\ +. in \\n[#L_INDENT]u +. if \\n[#QUOTE] \{\ +. in -\\n[#L_INDENT]u \"Because we added an indent in 2nd line of macro +. ll -\\n[#L_INDENT]u +. ta \\n[.l]u +. \} +. if \\n[#EPIGRAPH] \{\ +. in -\\n[#L_INDENT]u +. ll -\\n[#L_INDENT]u +. ta \\n[.l]u +. \} +. \} +. if \\n[#INDENT_RIGHT_ACTIVE] \{\ +. ll -\\n[#R_INDENT]u +. ta \\n[.l]u +. \} +. if \\n[#INDENT_BOTH_ACTIVE] \{\ +. in \\n[#BL_INDENT]u +. ll -\\n[#BR_INDENT]u +. ta \\n[.l]u +. if \\n[#QUOTE] \{\ +. in -\\n[#BL_INDENT]u +. ie \\n[#BR_INDENT]=\\n[#BL_INDENT] \{\ +. ll -\\n[#BR_INDENT]u +. ta \\n[.l]u +. \} +. el \{\ +. ll -(\\n[#BR_INDENT]u/2u) +. ta \\n[.l]u +. \} +. \} +. if \\n[#EPIGRAPH] \{\ +. in -\\n[#BL_INDENT]u +. ie \\n[#BR_INDENT]=\\n[#BL_INDENT] \{\ +. ll -\\n[#BR_INDENT]u +. ta \\n[.l]u +. \} +. el \{\ +. ll -(\\n[#BR_INDENT]u/2u) +. ta \\n[.l]u +. \} +. \} +. \} +.END +\# +\# REMOVE INDENT +\# ------------- +\# *Arguments: +\# <none> +\# *Function: +\# Removes left, right, or both indent values from document elements +\# like heads and subheads that are processed in environments. +\# +.MAC REMOVE_INDENT END +. in 0 +. ll \\n[#L_LENGTH]u +. ta \\n[.l]u +.END +\# +\# This .em (for all DOC_TYPEs, except 4 [LETTER]) ensures that +\# deferred footnotes and floats that happen on the 2nd to last page +\# get output, and the last page/col isn't flexed. +\# +.MAC TERMINATE END +. if dPDF.EXPORT .tm .ds last-page \\n%@\\n[#COL_NUM] +. ie \\n[#FN_DEPTH] \{\ +. ie \\n[#FN_DEFER] \{\ +. br +. nr #TERMINATE 1 +. FOOTNOTE +. nf +. FOOTNOTE OFF +. \} +. el \{\ +. br +. ch FN_OVERFLOW_TRAP +. FOOTER +. \} +. \} +. el \{\ +. br +. ch FN_OVERFLOW_TRAP +. FOOTER +. \} +. if \\n[defer] \ +' bp +.END +\# +\# END MACRO FOR LETTERS +\# --------------------- +\# *Arguments: +\# none +\# *Function: +\# The .em macro executed at the end of letters. Turns footers +\# and pagination off, terminates and outputs diversion CLOSING +\# (indented with the author's name underneath). +\# +.MAC ALL_DONE END +. ch FOOTER +. ch HEADER +. br +. if \\n[#DOC_TYPE]=4 \{\ +. if !'\\n[.z]'' \{\ +. br +. ALD \\*[$SIG_SPACE] +. di +. \} +. IQ CLEAR +. TQ +. LEFT +. ie !'\\*[$CLOSE_INDENT]'' .IL \\*[$CLOSE_INDENT] +. el .IL \\n[#DOC_L_LENGTH]u/2u +. sp +. if \\n[#CLOSING] \{\ +. CLOSING_TEXT +. br +. \} +. PRINT \\*[$AUTHOR_1] +. \} +.END +\# +\# Set up a default papersize of US letter +\# +.PAGEWIDTH 8.5i +.PAGELENGTH 11i +\# +\# ==================================================================== +\# +\# +++DOCUMENT PROCESSING ALIASES+++ +\# +\# Create aliases to make life easier for users: synonyms, short forms +\# and alternate spellings. +\# +.ALIAS CITATION BLOCKQUOTE +.ALIAS CITE BLOCKQUOTE +.ALIAS DOC_R_MARGIN DOC_RIGHT_MARGIN +.ALIAS DOC_L_MARGIN DOC_LEFT_MARGIN +.ALIAS DOC_L_LENGTH DOC_LINE_LENGTH +.ALIAS DOC_RMARGIN DOC_RIGHT_MARGIN +.ALIAS DOC_LMARGIN DOC_LEFT_MARGIN +.ALIAS DOC_LLENGTH DOC_LINE_LENGTH +.ALIAS DOC_FAM DOC_FAMILY +.ALIAS DOC_LS DOC_LEAD +.ALIAS DOC_PS DOC_PT_SIZE +.ALIAS FILL QUAD +.ALIAS PAGENUM PAGENUMBER +.ALIAS PAGINATION PAGINATE +.ALIAS PP_FT PP_FONT +.ALIAS TOC_PS TOC_PT_SIZE +\# +\# HEADER and FOOTER macros +\# ------------------------ +\# Because the type-style of headers and footers are managed +\# identically, and the type-style macros (_<type parameter>) all +\# require the correct name of the calling macro, it's necessary +\# to create HEADER_ and FOOTER_ macros here that are basically +\# aliases with an argument. +\# +.MAC FOOTER_CENTER_COLOR END +. HDRFTR_CENTER_COLOR \\$1 +.END +\# +.MAC FOOTER_CENTER_COLOUR END +. HDRFTR_CENTER_COLOR \\$1 +.END +\# +.MAC FOOTER_CENTER_FAM END +. HDRFTR_CENTER_FAMILY \\$1 +.END +\# +.MAC FOOTER_CENTER_FAMILY END +. HDRFTR_CENTER_FAMILY \\$1 +.END +\# +.MAC FOOTER_CENTER_FONT END +. HDRFTR_CENTER_FONT \\$1 +.END +\# +.MAC FOOTER_CENTER_FT END +. HDRFTR_CENTER_FONT \\$1 +.END +\# +.MAC FOOTER_CENTER_PS END +. HDRFTR_CENTER_SIZE \\$1 +.END +\# +.MAC FOOTER_CENTER_SIZE END +. HDRFTR_CENTER_SIZE \\$1 +.END +\# +.MAC FOOTER_CENTRE_CAPS END +. HDRFTR_CENTER_CAPS \\$1 +.END +\# +.MAC FOOTER_CENTRE_COLOR END +. HDRFTR_CENTER_COLOR \\$1 +.END +\# +.MAC FOOTER_CENTRE_COLOUR END +. HDRFTR_CENTER_COLOR \\$1 +.END +\# +.MAC FOOTER_CENTRE_FAM END +. HDRFTR_CENTER_FAMILY \\$1 +.END +\# +.MAC FOOTER_CENTRE_FAMILY END +. HDRFTR_CENTER_FAMILY \\$1 +.END +\# +.MAC FOOTER_CENTRE_FONT END +. HDRFTR_CENTER_FONT \\$1 +.END +\# +.MAC FOOTER_CENTRE_FT END +. HDRFTR_CENTER_FONT \\$1 +.END +\# +.MAC FOOTER_CENTRE_PS END +. HDRFTR_CENTER_SIZE \\$1 +.END +\# +.MAC FOOTER_CENTRE_SIZE END +. HDRFTR_CENTER_SIZE \\$1 +.END +\# +.MAC FOOTER_COLOR END +. HDRFTR_COLOR \\$1 +.END +\# +.MAC FOOTER_COLOUR END +. HDRFTR_COLOR \\$1 +.END +\# +.MAC FOOTER_FAM END +. HDRFTR_FAMILY \\$1 +.END +\# +.MAC FOOTER_FAMILY END +. HDRFTR_FAMILY \\$1 +.END +\# +.MAC FOOTER_LEFT_COLOR END +. HDRFTR_LEFT_COLOR \\$1 +.END +\# +.MAC FOOTER_LEFT_COLOUR END +. HDRFTR_LEFT_COLOR \\$1 +.END +\# +.MAC FOOTER_LEFT_FAM END +. HDRFTR_LEFT_FAMILY \\$1 +.END +\# +.MAC FOOTER_LEFT_FAMILY END +. HDRFTR_LEFT_FAMILY \\$1 +.END +\# +.MAC FOOTER_LEFT_FONT END +. HDRFTR_LEFT_FONT \\$1 +.END +\# +.MAC FOOTER_LEFT_FT END +. HDRFTR_LEFT_FONT \\$1 +.END +\# +.MAC FOOTER_LEFT_PS END +. HDRFTR_LEFT_SIZE \\$1 +.END +\# +.MAC FOOTER_LEFT_SIZE END +. HDRFTR_LEFT_SIZE \\$1 +.END +\# +.MAC FOOTER_RIGHT_COLOR END +. HDRFTR_RIGHT_COLOR \\$1 +.END +\# +.MAC FOOTER_RIGHT_COLOUR END +. HDRFTR_RIGHT_COLOR \\$1 +.END +\# +.MAC FOOTER_RIGHT_FAM END +. HDRFTR_RIGHT_FAMILY \\$1 +.END +\# +.MAC FOOTER_RIGHT_FAMILY END +. HDRFTR_RIGHT_FAMILY \\$1 +.END +\# +.MAC FOOTER_RIGHT_FONT END +. HDRFTR_RIGHT_FONT \\$1 +.END +\# +.MAC FOOTER_RIGHT_FT END +. HDRFTR_RIGHT_FONT \\$1 +.END +\# +.MAC FOOTER_RIGHT_PS END +. HDRFTR_RIGHT_SIZE \\$1 +.END +\# +.MAC FOOTER_RIGHT_SIZE END +. HDRFTR_RIGHT_SIZE \\$1 +.END +\# +.MAC FOOTER_RULE_COLOR END +. HDRFTR_RULE_COLOR \\$1 +.END +\# +.MAC FOOTER_SIZE END +. HDRFTR_SIZE \\$1 +.END +\# +.MAC HEADER_CENTER_COLOR END +. HDRFTR_CENTER_COLOR \\$1 +.END +\# +.MAC HEADER_CENTER_COLOUR END +. HDRFTR_CENTER_COLOR \\$1 +.END +\# +.MAC HEADER_CENTER_FAM END +. HDRFTR_CENTER_FAMILY \\$1 +.END +\# +.MAC HEADER_CENTER_FAMILY END +. HDRFTR_CENTER_FAMILY \\$1 +.END +\# +.MAC HEADER_CENTER_FONT END +. HDRFTR_CENTER_FONT \\$1 +.END +\# +.MAC HEADER_CENTER_FT END +. HDRFTR_CENTER_FONT \\$1 +.END +\# +.MAC HEADER_CENTER_PS END +. HDRFTR_CENTER_SIZE \\$1 +.END +\# +.MAC HEADER_CENTER_SIZE END +. HDRFTR_CENTER_SIZE \\$1 +.END +\# +.MAC HEADER_CENTRE_COLOR END +. HDRFTR_CENTER_COLOR \\$1 +.END +\# +.MAC HEADER_CENTRE_COLOUR END +. HDRFTR_CENTER_COLOR \\$1 +.END +\# +.MAC HEADER_CENTRE_FAM END +. HDRFTR_CENTER_FAMILY \\$1 +.END +\# +.MAC HEADER_CENTRE_FAMILY END +. HDRFTR_CENTER_FAMILY \\$1 +.END +\# +.MAC HEADER_CENTRE_FONT END +. HDRFTR_CENTER_FONT \\$1 +.END +\# +.MAC HEADER_CENTRE_FT END +. HDRFTR_CENTER_FONT \\$1 +.END +\# +.MAC HEADER_CENTRE_PS END +. HDRFTR_CENTER_SIZE \\$1 +.END +\# +.MAC HEADER_CENTRE_SIZE END +. HDRFTR_CENTER_SIZE \\$1 +.END +\# +.MAC HEADER_COLOR END +. HDRFTR_COLOR \\$1 +.END +\# +.MAC HEADER_COLOUR END +. HDRFTR_COLOR \\$1 +.END +\# +.MAC HEADER_FAM END +. HDRFTR_FAMILY \\$1 +.END +\# +.MAC HEADER_FAMILY END +. HDRFTR_FAMILY \\$1 +.END +\# +.MAC HEADER_LEFT_COLOR END +. HDRFTR_LEFT_COLOR \\$1 +.END +\# +.MAC HEADER_LEFT_COLOUR END +. HDRFTR_LEFT_COLOR \\$1 +.END +\# +.MAC HEADER_LEFT_FAM END +. HDRFTR_LEFT_FAMILY \\$1 +.END +\# +.MAC HEADER_LEFT_FAMILY END +. HDRFTR_LEFT_FAMILY \\$1 +.END +\# +.MAC HEADER_LEFT_FONT END +. HDRFTR_LEFT_FONT \\$1 +.END +\# +.MAC HEADER_LEFT_FT END +. HDRFTR_LEFT_FONT \\$1 +.END +\# +.MAC HEADER_LEFT_PS END +. HDRFTR_LEFT_SIZE \\$1 +.END +\# +.MAC HEADER_LEFT_SIZE END +. HDRFTR_LEFT_SIZE \\$1 +.END +\# +.MAC HEADER_RIGHT_COLOR END +. HDRFTR_RIGHT_COLOR \\$1 +.END +\# +.MAC HEADER_RIGHT_COLOUR END +. HDRFTR_RIGHT_COLOR \\$1 +.END +\# +.MAC HEADER_RIGHT_FAM END +. HDRFTR_RIGHT_FAMILY \\$1 +.END +\# +.MAC HEADER_RIGHT_FAMILY END +. HDRFTR_RIGHT_FAMILY \\$1 +.END +\# +.MAC HEADER_RIGHT_FONT END +. HDRFTR_RIGHT_FONT \\$1 +.END +\# +.MAC HEADER_RIGHT_FT END +. HDRFTR_RIGHT_FONT \\$1 +.END +\# +.MAC HEADER_RIGHT_PS END +. HDRFTR_RIGHT_SIZE \\$1 +.END +\# +.MAC HEADER_RIGHT_SIZE END +. HDRFTR_RIGHT_SIZE \\$1 +.END +\# +.MAC HEADER_RULE_COLOR END +. HDRFTR_RULE_COLOR \\$1 +.END +\# +.MAC HEADER_SIZE END +. HDRFTR_SIZE \\$1 +.END +\# +\# Aliases for other HEADER and FOOTER macros. +\# +.ALIAS BIBLIOGRAPHY_FOOTER_CENTER BIBLIOGRAPHY_HDRFTR_CENTER +.ALIAS BIBLIOGRAPHY_FOOTER_CENTRE BIBLIOGRAPHY_HDRFTR_CENTER +.ALIAS BIBLIOGRAPHY_HEADER_CENTER BIBLIOGRAPHY_HDRFTR_CENTER +.ALIAS BIBLIOGRAPHY_HEADER_CENTRE BIBLIOGRAPHY_HDRFTR_CENTER +. +.ALIAS ENDNOTES_FOOTER_CENTER ENDNOTES_HDRFTR_CENTER +.ALIAS ENDNOTES_FOOTER_CENTRE ENDNOTES_HDRFTR_CENTER +.ALIAS ENDNOTES_HEADER_CENTER ENDNOTES_HDRFTR_CENTER +.ALIAS ENDNOTES_HEADER_CENTRE ENDNOTES_HDRFTR_CENTER +. +.ALIAS FOOTER_CENTER HDRFTR_CENTER +.ALIAS TOC_PAGEFOOTER_CENTER HDRFTR_CENTER +.ALIAS TOC_PAGEFOOTER_CENTRE HDRFTR_CENTER +.ALIAS FOOTER_CENTER_CAPS _HDRFTR_CAPS +.ALIAS FOOTER_CENTER_PAD HDRFTR_CENTER_PAD +.ALIAS FOOTER_CENTER_SMALLCAPS _HDRFTR_SMALLCAPS +.ALIAS FOOTER_CENTRE HDRFTR_CENTER +.ALIAS FOOTER_CENTRE_CAPS _HDRFTR_CAPS +.ALIAS FOOTER_CENTRE_PAD HDRFTR_CENTER_PAD +.ALIAS FOOTER_CENTRE_SMALLCAPS _HDRFTR_SMALLCAPS +.ALIAS FOOTER_LEFT HDRFTR_LEFT +.ALIAS FOOTER_LEFT_CAPS _HDRFTR_CAPS +.ALIAS FOOTER_LEFT_SMALLCAPS _HDRFTR_SMALLCAPS +.ALIAS FOOTER_PLAIN HDRFTR_PLAIN +.ALIAS FOOTER_RECTO HDRFTR_RECTO +.ALIAS FOOTER_RIGHT HDRFTR_RIGHT +.ALIAS FOOTER_RIGHT_CAPS _HDRFTR_CAPS +.ALIAS FOOTER_RIGHT_SMALLCAPS _HDRFTR_SMALLCAPS +.ALIAS FOOTER_RULE HDRFTR_RULE +.ALIAS FOOTER_RULE_GAP HDRFTR_RULE_GAP +.ALIAS FOOTER_VERSO HDRFTR_VERSO +. +.ALIAS HEADER_CENTER HDRFTR_CENTER +.ALIAS TOC_PAGEHEADER_CENTER HDRFTR_CENTER +.ALIAS TOC_PAGEHEADER_CENTRE HDRFTR_CENTER +.ALIAS HEADER_CENTER_CAPS _HDRFTR_CAPS +.ALIAS HEADER_CENTER_PAD HDRFTR_CENTER_PAD +.ALIAS HEADER_CENTER_SMALLCAPS _HDRFTR_SMALLCAPS +.ALIAS HEADER_CENTRE HDRFTR_CENTER +.ALIAS HEADER_CENTRE_CAPS _HDRFTR_CAPS +.ALIAS HEADER_CENTRE_PAD HDRFTR_CENTER_PAD +.ALIAS HEADER_CENTRE_SMALLCAPS _HDRFTR_SMALLCAPS +.ALIAS HEADER_LEFT HDRFTR_LEFT +.ALIAS HEADER_LEFT_CAPS _HDRFTR_CAPS +.ALIAS HEADER_LEFT_SMALLCAPS _HDRFTR_SMALLCAPS +.ALIAS HEADER_PLAIN HDRFTR_PLAIN +.ALIAS HEADER_RECTO HDRFTR_RECTO +.ALIAS HEADER_RIGHT HDRFTR_RIGHT +.ALIAS HEADER_RIGHT_CAPS _HDRFTR_CAPS +.ALIAS HEADER_RIGHT_SMALLCAPS _HDRFTR_SMALLCAPS +.ALIAS HEADER_RULE HDRFTR_RULE +.ALIAS HEADER_RULE_GAP HDRFTR_RULE_GAP +.ALIAS HEADER_VERSO HDRFTR_VERSO +. +.ALIAS SWITCH_FOOTERS SWITCH_HDRFTR +.ALIAS SWITCH_HEADERS SWITCH_HDRFTR +\# +\# Create type-style aliases for tags, titles, and page elements +\# +\# These are used for creating aliases with while loops +\# +.ds ELEMENT_TYPE_1 BIBLIOGRAPHY_STRING +.ds ELEMENT_TYPE_2 BIBLIOGRAPHY_HEADER +.ds ELEMENT_TYPE_3 BLOCKQUOTE +.ds ELEMENT_TYPE_4 CITATION +.ds ELEMENT_TYPE_5 CITE +.ds ELEMENT_TYPE_6 ENDNOTES_HEADER +.ds ELEMENT_TYPE_7 ENDNOTE_STRING +.ds ELEMENT_TYPE_8 EPIGRAPH +.ds ELEMENT_TYPE_9 HDRFTR_CENTER +.ds ELEMENT_TYPE_10 HDRFTR_LEFT +.ds ELEMENT_TYPE_11 HDRFTR_RIGHT +.ds ELEMENT_TYPE_12 LINENUMBER +.ds ELEMENT_TYPE_13 PAGENUM +.ds ELEMENT_TYPE_14 QUOTE +.ds ELEMENT_TYPE_15 TOC_HEADER +.ds ELEMENT_TYPE_16 CODE +.ds ELEMENT_TYPE_17 FINIS +.ds ELEMENT_TYPE_18 COPYRIGHT +\# +\# Create aliases for _FAMILY +.ALIAS BIBLIOGRAPHY_FAMILY _FAMILY +.ALIAS COVER_FAMILY _FAMILY +.ALIAS DOCHEADER_FAMILY _FAMILY +.ALIAS DOC_COVER_FAMILY _FAMILY +.ALIAS ENDNOTE_FAMILY _FAMILY +.ALIAS ENDNOTE_LINENUMBER_FAMILY _FAMILY +.ALIAS ENDNOTE_NUMBER_FAMILY _FAMILY +.ALIAS ENDNOTE_STRING_FAMILY _FAMILY +.ALIAS ENDNOTE_TITLE_FAMILY _FAMILY +.ALIAS FOOTNOTE_FAMILY _FAMILY +.ALIAS HDRFTR_FAMILY _FAMILY +.ALIAS PAGENUMBER_FAMILY _FAMILY +.ALIAS TOC_FAMILY _FAMILY +.ALIAS TOC_PAGENUMBER_FAMILY _FAMILY +.ALIAS TOC_PN_FAMILY _FAMILY +.ALIAS TOC_TITLE_FAMILY _FAMILY +\# +.nr #LOOP 0 1 +.while \n+[#LOOP]<=18 \{\ +. ALIAS \*[ELEMENT_TYPE_\n[#LOOP]]_FAMILY _FAMILY +.\} +\# Covers, docheader +.nr #LOOP 0 1 +.while \n+[#LOOP]<=12 \{\ +. ALIAS \*[TITLE_TYPE_\n[#LOOP]]_FAMILY _FAMILY +. ALIAS COVER_\*[TITLE_TYPE_\n[#LOOP]]_FAMILY _FAMILY +. ALIAS DOC_COVER_\*[TITLE_TYPE_\n[#LOOP]]_FAMILY _FAMILY +.\} +\# +\# Create aliases for _FONT +.ALIAS BIBLIOGRAPHY_FONT _FONT +.ALIAS ENDNOTE_FONT _FONT +.ALIAS ENDNOTE_LINENUMBER_FONT _FONT +.ALIAS ENDNOTE_NUMBER_FONT _FONT +.ALIAS ENDNOTE_TITLE_FONT _FONT +.ALIAS FOOTNOTE_FONT _FONT +.ALIAS TOC_PN_FONT _FONT +\# +.nr #LOOP 0 1 +.while \n+[#LOOP]<=18 \{\ +. ALIAS \*[ELEMENT_TYPE_\n[#LOOP]]_FONT _FONT +.\} +\# Covers, docheader +.nr #LOOP 0 1 +.while \n+[#LOOP]<=12 \{\ +. ALIAS \*[TITLE_TYPE_\n[#LOOP]]_FONT _FONT +. ALIAS COVER_\*[TITLE_TYPE_\n[#LOOP]]_FONT _FONT +. ALIAS DOC_COVER_\*[TITLE_TYPE_\n[#LOOP]]_FONT _FONT +.\} +\# +\# Create aliases for _SIZE +.ALIAS ENDNOTE_LINENUMBER_SIZE _SIZE +.ALIAS ENDNOTE_NUMBER_SIZE _SIZE +.ALIAS ENDNOTE_TITLE_SIZE _SIZE +.ALIAS FOOTNOTE_SIZE _SIZE +.ALIAS HDRFTR_SIZE _SIZE +.ALIAS TOC_PN_SIZE _SIZE +\# +.nr #LOOP 0 1 +.while \n+[#LOOP]<=18 \{\ +. ALIAS \*[ELEMENT_TYPE_\n[#LOOP]]_SIZE _SIZE +.\} +\# Covers, docheader +.nr #LOOP 0 1 +.while \n+[#LOOP]<=12 \{\ +. ALIAS \*[TITLE_TYPE_\n[#LOOP]]_SIZE _SIZE +. ALIAS COVER_\*[TITLE_TYPE_\n[#LOOP]]_SIZE _SIZE +. ALIAS DOC_COVER_\*[TITLE_TYPE_\n[#LOOP]]_SIZE _SIZE +.\} +\# +\# Create aliases for TITLE_LEAD +.nr #LOOP 0 1 +.while \n+[#LOOP]<=12 \{\ +. ALIAS \*[TITLE_TYPE_\n[#LOOP]]_LEAD TITLE_LEAD +. ALIAS COVER_\*[TITLE_TYPE_\n[#LOOP]]_LEAD TITLE_LEAD +. ALIAS DOC_COVER_\*[TITLE_TYPE_\n[#LOOP]]_LEAD TITLE_LEAD +.\} +\# +\# Create aliases for _UNDERLINE +.ALIAS BIBLIOGRAPHY_HEADER_UNDERLINE _UNDERLINE +.ALIAS BIBLIOGRAPHY_HEADER_UNDERSCORE _UNDERLINE +.ALIAS BIBLIOGRAPHY_STRING_UNDERLINE _UNDERLINE +.ALIAS BIBLIOGRAPHY_STRING_UNDERSCORE _UNDERLINE +.ALIAS BIB_STRING_UNDERLINE _UNDERLINE +.ALIAS ENDNOTES_HEADER_UNDERLINE _UNDERLINE +.ALIAS ENDNOTES_HEADER_UNDERSCORE _UNDERLINE +.ALIAS ENDNOTES_STRING_UNDERLINE _UNDERLINE +.ALIAS ENDNOTES_STRING_UNDERSCORE _UNDERLINE +.ALIAS ENDNOTE_TITLE_UNDERLINE _UNDERLINE +.ALIAS ENDNOTE_TITLE_UNDERSCORE _UNDERLINE +.ALIAS EN_STRING_UNDERLINE _UNDERLINE +.ALIAS EN_STRING_UNDERSCORE _UNDERLINE +.ALIAS TOC_HEADER_UNDERLINE _UNDERLINE +.ALIAS TOC_HEADER_UNDERSCORE _UNDERLINE +\# +.nr #LOOP 0 1 +.while \n+[#LOOP]<=12 \{\ +. ALIAS \*[TITLE_TYPE_\n[#LOOP]]_UNDERLINE _UNDERLINE +. ALIAS \*[TITLE_TYPE_\n[#LOOP]]_UNDERSCORE _UNDERLINE +. ALIAS COVER_\*[TITLE_TYPE_\n[#LOOP]]_UNDERLINE _UNDERLINE +. ALIAS COVER_\*[TITLE_TYPE_\n[#LOOP]]_UNDERSCORE _UNDERLINE +. ALIAS DOC_COVER_\*[TITLE_TYPE_\n[#LOOP]]_UNDERLINE _UNDERLINE +. ALIAS DOC_COVER_\*[TITLE_TYPE_\n[#LOOP]]_UNDERSCORE _UNDERLINE +.\} +\# +\# Create aliases for _COLOR +.ALIAS BIBLIOGRAPHY_HEADER_COLOR _COLOR +.ALIAS COVER_COLOR _COLOR +.ALIAS DOCHEADER_COLOR _COLOR +.ALIAS ENDNOTE_TITLE_COLOR _COLOR +.ALIAS FINIS_COLOR _COLOR +.ALIAS FOOTNOTE_COLOR _COLOR +.ALIAS HDRFTR_COLOR _COLOR +.ALIAS HDRFTR_RULE_COLOR _COLOR +.ALIAS LINEBREAK_COLOR _COLOR +.ALIAS SECTION_COLOR _COLOR +\# +.nr #LOOP 0 1 +.while \n+[#LOOP]<=18 \{\ +. ALIAS \*[ELEMENT_TYPE_\n[#LOOP]]_COLOR _COLOR +.\} +\# Covers, docheader +.nr #LOOP 0 1 +.while \n+[#LOOP]<=12 \{\ +. ALIAS \*[TITLE_TYPE_\n[#LOOP]]_COLOR _COLOR +. ALIAS COVER_\*[TITLE_TYPE_\n[#LOOP]]_COLOR _COLOR +. ALIAS DOC_COVER_\*[TITLE_TYPE_\n[#LOOP]]_COLOR _COLOR +.\} +\# +\# Create aliases for _CAPS +.ALIAS BIBLIOGRAPHY_HEADER_CAPS _CAPS +.ALIAS BIBLIOGRAPHY_STRING_CAPS _CAPS +.ALIAS ENDNOTE_TITLE_CAPS _CAPS +\# +.nr #LOOP 0 1 +.while \n+[#LOOP]<=12 \{\ +. ALIAS \*[TITLE_TYPE_\n[#LOOP]]_CAPS _CAPS +. ALIAS COVER_\*[TITLE_TYPE_\n[#LOOP]]_CAPS _CAPS +. ALIAS DOC_COVER_\*[TITLE_TYPE_\n[#LOOP]]_CAPS _CAPS +.\} +\# +\# Create aliases for _SMALLCAPS +.ALIAS BIBLIOGRAPHY_HEADER_SMALLCAPS _SMALLCAPS +.ALIAS BIBLIOGRAPHY_STRING_SMALLCAPS _SMALLCAPS +.ALIAS ENDNOTE_TITLE_SMALLCAPS _SMALLCAPS +.ALIAS HDRFTR_CENTER_SMALLCAPS _SMALLCAPS +.ALIAS HDRFTR_LEFT_SMALLCAPS _SMALLCAPS +.ALIAS HDRFTR_RIGHT_SMALLCAPS _SMALLCAPS +\# +.nr #LOOP 0 1 +.while \n+[#LOOP]<=12 \{\ +. ALIAS \*[TITLE_TYPE_\n[#LOOP]]_SMALLCAPS _SMALLCAPS +. ALIAS COVER_\*[TITLE_TYPE_\n[#LOOP]]_SMALLCAPS _SMALLCAPS +. ALIAS DOC_COVER_\*[TITLE_TYPE_\n[#LOOP]]_SMALLCAPS _SMALLCAPS +.\} +\# +\# Create aliases for _QUAD +.ALIAS BIBLIOGRAPHY_HEADER_QUAD _QUAD +.ALIAS BIBLIOGRAPHY_QUAD _QUAD +.ALIAS BIBLIOGRAPHY_STRING_QUAD _QUAD +.ALIAS BLOCKQUOTE_QUAD _QUAD +.ALIAS COPYRIGHT_QUAD _QUAD +.ALIAS COVER_COPYRIGHT_QUAD _QUAD +.ALIAS COVER_MISC_QUAD _QUAD +.ALIAS COVER_QUAD _QUAD +.ALIAS DOCHEADER_QUAD _QUAD +.ALIAS DOC_COVER_COPYRIGHT_QUAD _QUAD +.ALIAS DOC_COVER_MISC_QUAD _QUAD +.ALIAS DOC_COVER_QUAD _QUAD +.ALIAS DOC_QUAD _QUAD +.ALIAS ENDNOTES_HEADER_QUAD _QUAD +.ALIAS ENDNOTE_QUAD _QUAD +.ALIAS ENDNOTE_STRING_QUAD _QUAD +.ALIAS ENDNOTE_TITLE_QUAD _QUAD +.ALIAS EPIGRAPH_QUAD _QUAD +.ALIAS FOOTNOTE_QUAD _QUAD +.ALIAS MISC_QUAD _QUAD +.ALIAS TOC_HEADER_QUAD _QUAD +\# +\# Support aliases +\# +.ALIAS COL_BREAK COL_NEXT +.ALIAS DOC_COVER COVER +.ALIAS DOC_COVERS COVERS +.ALIAS DOC_COVERTITLE COVERTITLE +.ALIAS DOC_COVER_COUNTS_PAGES COVER_COUNTS_PAGES +.ALIAS DOC_COVER_LEAD COVER_LEAD +.ALIAS DOC_DOC_COVERTITLE COVERTITLE +.ALIAS DO_DOC_COVER DO_COVER +.ALIAS PRINT_FOOTNOTE_RULE FOOTNOTE_RULE +\# +\# Miscellaneous aliases +.ALIAS SECTION LINEBREAK +.ALIAS SECTION_CHAR LINEBREAK_CHAR +\# +\# Miscellaneous macros to take care of backward compatibility +\# ----------------------------------------------------------- +\# +\# As of 1.1.9, EL and TN got changed to make TRAP...TRAP OFF +\# unnecessary for users. However, I used both macros extensively +\# throughout this file (in conjunction with TRAP...TRAP OFF). +\# EOL is the old EL; used only in om.tmac. +\# +.MAC EOL END +. if \\n[.vpt] \{\ +. vpt 0 +. nr #RESTORE_TRAP 1 +. \} +. br +. sp -1v +. if \\n[#RESTORE_TRAP] \{\ +. vpt +. rr #RESTORE_TRAP +. \} +.END +\# +\# PREPROCESSOR SUPPORT +\# ==================== +\# +\# Utility macros--label and caption styles, lists collector, lists +\# generator. +\# +.nr lists*target 0 1 +. +.MAC get-label-type END +. if \\n[all]=1 .ds label-type eqn +. if \\n[all]=2 .ds label-type pdf-img +. if \\n[all]=3 .ds label-type pic +. if \\n[all]=4 .ds label-type tbl +. if \\n[all]=5 .ds label-type floating +.END +\# +.MAC set-defaults END +. if '\\*[\\*[label-type]*\\*[spec-type]-family]'' \ +. ds \\*[label-type]*\\*[spec-type]-family \\*[$DOC_FAM]\" +. if '\\*[\\*[label-type]*\\*[spec-type]-font]'' \ +. ds \\*[label-type]*\\*[spec-type]-font R\" +. if '\\*[\\*[label-type]*\\*[spec-type]-size-change]'' \ +. ds \\*[label-type]*\\*[spec-type]-size-change +0\" +. if !r \\*[label-type]*\\*[spec-type]-autolead \ +. nr \\*[label-type]*\\*[spec-type]-autolead 2 +. if '\\*[\\*[label-type]*\\*[spec-type]-space]'' \ +. ds \\*[label-type]*\\*[spec-type]-space +0\" +. if '\\*[\\*[label-type]*\\*[spec-type]-color]'' \ +. ds \\*[label-type]*\\*[spec-type]-color black\" +. if '\\*[\\*[label-type]*\\*[spec-type]-quad]'' \{\ +. ie '\\*[label-type]'eqn' \{\ +. if '\\*[spec-type]'caption' \ +. ds \\*[label-type]*\\*[spec-type]-quad C\" +. \} +. el .ds \\*[label-type]*\\*[spec-type]-quad L\" +. \} +. if '\\n[\\*[label-type]*\\*[spec-type]-quad-on-ll]'' \ +. nr \\*[label-type]*\\*[spec-type]-quad-on-ll 1 +. if '\\*[spec-type]'caption' \ +. nr default-left 1 +.END +\# +.MAC set-inline-specs END +. ds \\*[label-type]*\\*[spec-type]-specs \ +\f[\\*[\\*[label-type]*\\*[spec-type]-family]\\*[\\*[label-type]*\\*[spec-type]-font]]\ +\s[\\*[\\*[label-type]*\\*[spec-type]-size-change]]\ +\m[\\*[\\*[label-type]*\\*[spec-type]-color]] +.END +\# +\# Line lengths, indents, and quads for captions and labels. +\# Aliased for eqn, pic, pdf-image, and tbl. +\# +.MAC SET_QUAD END +. ds label-type \\$0 +. substring label-type 0 2 +. if '\\*[label-type]'PDF' .ds label-type pdf-img +. if '\\*[label-type]'TBL' .ds label-type tbl +. if '\\*[label-type]'PIC' .ds label-type pic +. if '\\*[label-type]'EQN' .ds label-type eqn +. ds spec-type \\$0 +. substring spec-type -6 -10 +. if '\\*[spec-type]'PTION' .ds spec-type caption +. if '\\*[spec-type]'LABEL' .ds spec-type label +. if '\\*[spec-type]'OURCE' .ds spec-type source +. QUAD \\$1 +. ds \\*[label-type]*\\*[spec-type]-quad \\$1 +. substring \\*[label-type]*\\*[spec-type]-quad 0 0 +. if '\\*[label-type]'pdf-img' \{\ +. if '\\*[\\*[label-type]*\\*[spec-type]-quad]'L' \{\ +. if !\\n[pdf-img*\\*[spec-type]-quad-on-ll] \{\ +. ie !'\\*[pdf-img:pos]'-R' \ +. ll \\n[pdf-img:ind]u+\\n[pdf-img:width]u+\\n[pdf-img:frame-inset]u +. el .ll -\\n[ind-pre-img]u +. if '\\*[pdf-img:pos]'-C' \ +. in \\n[pdf-img:ind]u-\\n[pdf-img:frame-inset]u +. if '\\*[pdf-img:pos]'-R' \ +. in \\n[.l]u-(\\n[pdf-img:width]u+(\\n[pdf-img:frame-inset]u*2u)) +. if '\\*[pdf-img:pos]'-I' \ +. in \\n[pdf-img:ind]u +. \} +. \} +. if '\\*[\\*[label-type]*\\*[spec-type]-quad]'C' \{\ +. if !\\n[pdf-img*\\*[spec-type]-quad-on-ll] \{\ +. if '\\*[pdf-img:pos]'-L' \ +. ll \\n[pdf-img:width]u+(\\n[pdf-img:frame-inset]u*2u) +. if '\\*[pdf-img:pos]'-C' \{\ +. ll (\\n[ll-pre-img]u-\\n[pdf-img:width]u/2u+(\\n[pdf-img:frame-inset]u))+\\n[pdf-img:width]u +. in \\n[.l]u-(\\n[pdf-img:width]u+(\\n[pdf-img:frame-inset]u*2u)) +. \} +. if '\\*[pdf-img:pos]'-R' \{\ +. ll -\\n[ind-pre-img]u +. in \\n[.l]u-(\\n[pdf-img:width]u+(\\n[pdf-img:frame-inset]u*2u)) +. \} +. if '\\*[pdf-img:pos]'-I' \{\ +. ll \\n[pdf-img:ind]u+\\n[pdf-img:width]u+(\\n[pdf-img:frame-inset]u*2u) +. in \\n[pdf-img:ind]u +. \} +. \} +. \} +. if '\\*[\\*[label-type]*\\*[spec-type]-quad]'R' \{\ +. if !\\n[pdf-img*\\*[spec-type]-quad-on-ll] \{\ +. if '\\*[pdf-img:pos]'-L' \ +. ll \\n[pdf-img:width]u+(\\n[pdf-img:frame-inset]u*2u] +. if '\\*[pdf-img:pos]'-C' \{\ +. ll (\\n[.l]u-\\n[ind-pre-img]u-\\n[pdf-img:width]u/2u)+\\n[pdf-img:width]u+\\n[pdf-img:frame-inset]u +. in \\n[pdf-img:ind]u +. \} +. if '\\*[pdf-img:pos]'-R' \{\ +. ll -\\n[ind-pre-img]u +. in \\n[.l]u-\\n[pdf-img:width]u +. \} +. if '\\*[pdf-img:pos]'-I' \{\ +. ll \\n[pdf-img:ind]u+\\n[pdf-img:width]u+(\\n[pdf-img:frame-inset]u*2u) +. in \\n[pdf-img:ind]u +. \} +. \} +. \} +. \} +. if '\\*[label-type]'pic' \{\ +. if !\\n[pic*\\*[spec-type]-quad-on-ll] \{\ +. ie \\n[pic*left] .ll \\n[pic*div-width]u +. el \{\ +. ll \\n[pic*div-width]u +. in (\\n[ll-pre-float]u-\\n[pic*div-width]u)/2u +. \} +. \} +. \} +. if '\\*[label-type]'tbl' \{\ +. if !\\n[tbl*\\*[spec-type]-quad-on-ll] \{\ +. ie \\n[tbl*center] \{\ +. ie '\\*[spec-type]'label' \{\ +.\" Differentiate between a tbl label and a float label +. ie !'\\*[ev-current]'FLOAT' \{\ +. ll \\n[ll-pre-tbl]u-\\n[TW]u/2u+\\n[TW]u +. if \\n[tbl*have-header] \ +. in (\\n[ll-pre-tbl]u-\\n[.i]u)-\\n[TW]u/2u+\\n[.i]u +. \} +. el \{\ +. in \\n[ll-pre-tbl]u+\\n[.i]u-\\n[TW]u/2u +. ll \\n[.l]u-\\n[.i]u +. \} +. \} +. el \{\ +. if '\\*[spec-type]'source' \{\ +. ie \\n[float*tbl] \{\ +. ll \\n[TW]u +\!. in \\n[ll-pre-tbl]u-\\n[TW]u/2u+\\n[tmp-ind]u +. \} +. el \{\ +. ll \\n[TW]u+\\n[ind-pre-tbl]u +. ie \\n[ind-pre-tbl] \ +\!. in \\n[ll-pre-tbl]u-\\n[TW]u/2u +. el \ +\!. in \\n[ll-pre-tbl]u-\\n[TW]u/2u+\\n[tmp-ind]u +. \} +\!. ti -\\n[tmp-ind]u +. \} +. if '\\*[spec-type]'caption' \{\ +. ll \\n[ll-pre-tbl]u+\\n[.i]u-\\n[TW]u/2u+\\n[TW]u +. in \\n[ll-pre-tbl]u+\\n[.i]u-\\n[TW]u/2u +. \} +. \} +. \} +. el \{\ +. ll \\n[TW]u+\\n[.i]u +.\" Check the effect of setting a source in non-MLA mode. +. if '\\*[spec-type]'source' \{\ +. if \\n[#MLA] \{\ +. ie \\n[float*tbl] \{\ +\!. ll \\n[TW]u+\\n[ind-pre-tbl]u +\!. in \\n[tmp-ind]u+\\n[ind-pre-tbl]u +\!. ti -\\n[tmp-ind]u +. \} +. el \{\ +. ll \\n[TW]u+\\n[ind-pre-tbl]u +\!. in \\n[tmp-ind]u +\!. ti -\\n[tmp-ind]u +. \} +. \} +. \} +. \} +. \} +. \} +.END +\# +.ALIAS TBL*SET_CAPTION_QUAD SET_QUAD +.ALIAS TBL*SET_LABEL_QUAD SET_QUAD +.ALIAS TBL*SET_SOURCE_QUAD SET_QUAD +.ALIAS PDF_IMG*SET_CAPTION_QUAD SET_QUAD +.ALIAS PDF_IMG*SET_LABEL_QUAD SET_QUAD +.ALIAS PIC*SET_CAPTION_QUAD SET_QUAD +.ALIAS PIC*SET_LABEL_QUAD SET_QUAD +\# +.MAC style END +. ds label-type \\$0 +. substring label-type 0 2 +. if '\\*[label-type]'img' .ds label-type pdf-img +. if '\\*[label-type]'tbl' .ds label-type tbl +. if '\\*[label-type]'pic' .ds label-type pic +. ds spec-type \\$0 +. substring spec-type 4 6 +. if '\\*[spec-type]'cap' .ds spec-type caption +. if '\\*[spec-type]'lab' .ds spec-type label +. if '\\*[spec-type]'sou' .ds spec-type source +. ie \\n[#PRINT_STYLE]=1 .TYPEWRITER +. el \{\ +' fam \\*[\\*[label-type]*\\*[spec-type]-family] +' ft \\*[\\*[label-type]*\\*[spec-type]-font] +' ps \\n[#DOC_PT_SIZE]u\\*[\\*[label-type]*\\*[spec-type]-size-change] +. \m[\\*[\\*[label-type]*\\*[spec-type]-color]] +. \} +.END +\# +.ALIAS tbl*caption-style style +.ALIAS tbl*label-style style +.ALIAS tbl*source-style style +.ALIAS img*caption-style style +.ALIAS img*label-style style +.ALIAS img*source-style style +.ALIAS pic*caption-style style +.ALIAS pic*label-style style +.ALIAS pic*source-style style +\# +\# User style macros +\# +\# TYPE SPECS FOR LABELS, CAPTIONS, AND SOURCES +\# -------------------------------------------- +\# Aliased as CAPTIONS and LABELS for eqn, pic, tbl, and pdf images. +\# *Arguments: +\# EQN | IMG | PIC | TBL | FLOATING \ +\# Remaining arguments are optional +\# FAMILY fam \ +\# FONT sty \ +\# SIZE +|-size \ +\# QUAD LEFT | CENTRE | RIGHT [ ON_LL ] \ +\# COLOR color \ +\# AUTOLEAD n \ +\# ADJUST +|-n +\# *Function: +\# Sets type specs for captions, labels, and sources according to +\# calling alias name +\# *Notes: +\# SIZE is relative to running text. +\# QUAD optional arg says quad on full line length rather than +\# pdf-img or pre-processor output. +\# +.MAC CAPTION_LABEL_SPECS END +. if '\\$0'CAPTIONS' .ds spec-type caption +. if '\\$0'LABELS' .ds spec-type label +. if '\\$0'SOURCES' .ds spec-type source +. ds $LABEL-TYPE \\$1 +. if '\\$1'EQN' .ds label-type eqn +. if '\\$1'FLOATING' .ds label-type floating +. if '\\$1'IMG' .ds label-type pdf-img +. if '\\$1'PIC' .ds label-type pic +. if '\\$1'TBL' .ds label-type tbl +. if '\\$1'ALL' .nr all 1 +. shift +. nr loop-counter \\n[#NUM_ARGS] +. nr loop-count 0 1 +. while \\n+[loop-count]<=\\n[loop-counter] \{\ +. if '\\$1'FAMILY' \{\ +. shift +. ie r all \{\ +. nr all 0 1 +. while \\n+[all]<=5 \{\ +. get-label-type +. ds \\*[label-type]*\\*[spec-type]-family \\$1 +. \} +. \} +. el .ds \\*[label-type]*\\*[spec-type]-family \\$1 +. if \\n[#PRINT_STYLE]=1 \ +. ds \\*[label-type]*\\*[spec-type]-family \\*[$TYPEWRITER_FAM] +. shift +. \} +. if '\\$1'FONT' \{\ +. shift +. ie r all \{\ +. nr all 0 1 +. while \\n+[all]<=5 \{\ +. get-label-type +. ds \\*[label-type]*\\*[spec-type]-font \\$1 +. \} +. \} +. el .ds \\*[label-type]*\\*[spec-type]-font \\$1 +. if \\n[#PRINT_STYLE]=1 \ +. ds \\*[label-type]*\\*[spec-type]-font R +. shift +. \} +. if '\\$1'SIZE' \{\ +. shift +. ie r all \{\ +. nr all 0 1 +. while \\n+[all]<=5 \{\ +. get-label-type +. ds \\*[label-type]*\\*[spec-type]-size-change \\$1 +. \} +. \} +. el .ds \\*[label-type]*\\*[spec-type]-size-change \\$1 +. if \\n[#PRINT_STYLE]=1 \ +. ds \\*[label-type]*\\*[spec-type]-size-change +0 +. shift +. \} +. if '\\$1'AUTOLEAD' \{\ +. shift +. ie r all \{\ +. nr all 0 1 +. while \\n+[all]<=5 \{\ +. get-label-type +. nr \\*[label-type]*\\*[spec-type]-autolead (p;\\$1) +. \} +. \} +. el .nr \\*[label-type]*\\*[spec-type]-autolead (p;\\$1) +. shift +. \} +. if '\\$1'QUAD' \{\ +. shift +. ie r all \{\ +. nr all 0 1 +. while \\n+[all]<=5 \{\ +. get-label-type +. ds \\*[label-type]*\\*[spec-type]-quad \\$1 +. substring \\*[label-type]*\\*[spec-type]-quad 0 0 +. if '\\$2'ON_LL' \ +. nr \\*[label-type]*\\*[spec-type]-quad-on-ll 1 +. \} +. \} +. el \{\ +. ds \\*[label-type]*\\*[spec-type]-quad \\$1 +. substring \\*[label-type]*\\*[spec-type]-quad 0 0 +. if \\n[\\*[label-type]*\\*[spec-type]-quad-on-ll] \ +. rr \\*[label-type]*\\*[spec-type]-quad-on-ll +. if '\\$2'ON_LL' \ +. nr \\*[label-type]*\\*[spec-type]-quad-on-ll 1 +. \} +. ie '\\$2'ON_LL' .shift 2 +. el .shift +. \} +. if '\\$1'COLOR' \{\ +. shift +. ie r all \{\ +. nr all 0 1 +. while \\n+[all]<=5 \{\ +. get-label-type +. ds \\*[label-type]*\\*[spec-type]-color \\$1 +. \} +. \} +. el .ds \\*[label-type]*\\*[spec-type]-color \\$1 +. if \\n[#PRINT_STYLE]=1 \ +. ds \\*[label-type]*\\*[spec-type]-color black +. shift +. \} +. if '\\$1'ADJUST' \{\ +. shift +. ie r all \{\ +. nr all 0 1 +. while \\n+[all]<=5 \{\ +. get-label-type +. ds \\*[label-type]*\\*[spec-type]-space \\$1 +. \} +. \} +. el .ds \\*[label-type]*\\*[spec-type]-space \\$1 +. if \\n[#PRINT_STYLE]=1 \ +. ds \\*[label-type]*\\*[spec-type]-space +0 +. shift +. \} +. if '\\$1'INDENT' \{\ +. shift +. ie '\\*[label-type]'floating' \{\ +. ie \B'\\$1' \{\ +. nr \\*[label-type]*\\*[spec-type]-indent-l \\$1 +. shift +. \} +. el \{\ +. ie '\\$1'RIGHT' \{\ +. shift +. nr \\*[label-type]*\\*[spec-type]-indent-r \\$1 +. shift +. \} +. el \{\ +. tm1 \ +"[mom]: Missing value for INDENT in macro '\\$0' at line \\n[.c]. +. ab \ +[mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. \} +. \} +. el \{\ +. shift +. if !\\n[#SKIP_INDENT_WARNING] \{\ +. tm1 \ +"[mom]: '\\$0 \\*[$LABEL-TYPE]' at line \\n[.c] does not take an indent. +. tm1 \ +" No indent(s) will be applied. +. nr #SKIP_INDENT_WARNING 1 +. \} +. if '\\$1'INDENT' .shift +. if '\\$1'RIGHT' .shift +. if \B'\\$1' .shift +. \} +. \} +. \} +. ie r all \{\ +. nr all 0 1 +. while \\n+[all]<=5 \{\ +. get-label-type +. set-defaults +. set-inline-specs +. \} +. \} +. el \{\ +. set-defaults +. set-inline-specs +. \} +. ds revert-specs \f[]\s[0]\m[] +. rr #SKIP_INDENT_WARNING +. rr all +.END +. +.ALIAS CAPTIONS CAPTION_LABEL_SPECS +.ALIAS LABELS CAPTION_LABEL_SPECS +.ALIAS SOURCES CAPTION_LABEL_SPECS +\# +\# LABELS and CAPTIONS (floats and [block]quotes) +\# ---------------------------------------------- +\# *Arguments: +\# <text of label or caption> [ CAPTION <text of caption> ] \ +\# [ TO_LIST FIGURES | EQUATIONS | TABLES ] +\# *Function: +\# Add label/caption to float, quotes, and blockquotes +\# *Notes: +\# Aliased as CAPTION. If called as CAPTION, prints all +\# double-quoted text strings including ".br" or ".sp"; +\# may come at top or bottom of labelled object, or both. +\# If called as LABEL, optional arg CAPTION attaches caption +\# text to the label; may only come at bottom of object and +\# can only take one double-quoted text string. +\# +\# These strings allow users to create labels of the form +\# 'Fig. \*[chapter].\*[fig-label]', e.g. 'Fig. 1.1' +\# +.ds chapter \\n[#CH_NUM] +.ds fig-label \\n+[fig*label-num] +.ds tbl-label \\n+[tbl*label-num] +.ds eqn-label \\n+[eqn*label-num] +\# +\# +.MAC LABEL END +. br +. if \\n[.ns] \{\ +. vpt 0 +. rs +. nop \& +. sp -1 +. vpt +. \} +. if r chop-space .sp -1 +. rr chop-space +. if \\n[#QUOTE] .nr q-float 1 +. if '\\$0'CAPTION' \{\ +. ds labelcap caption +. ds $FLOATING_CAPTION \\$* +. \} +. if '\\$0'LABEL' \{\ +. ds labelcap label +. ds $FLOATING_LABEL \\$1 +. shift +. nr loop-counter 0 1 +. nr loop-count \\n[#NUM_ARGS] +. while \\n+[loop-counter]<=\\n[loop-count] \{\ +. if '\\$1'CAPTION' \{\ +. nr with-caption 1 +. ds $FLOATING_CAPTION \\$2 +. shift 2 +. \} +. if '\\$1'SHORT_CAPTION' \{\ +. ds $LIST_CAPTION \\$2 +. shift 2 +. \} +. if '\\$1'TO_LIST' \{\ +. nr to-list 1 +. if '\\$2'FIGURES' .ds $LIST_OF FIGURES +. if '\\$2'EQUATIONS' .ds $LIST_OF EQUATIONS +. if '\\$2'TABLES' .ds $LIST_OF TABLES +. shift 2 +. \} +. \} +. \} +. if \\n[D-float] \ +. if \\n[.d]>\\n[D-float] \ +. sp \\n[.d]u-\\n[D-float]u +. rr has-\\*[labelcap] +. nr has-\\*[labelcap] 1 +. rr @bottom +. if !\\n[.d]=0 .nr @bottom 1 +. ds ev-current \\n[.ev] +. ev floating*labelcap +. evc \\*[ev-current] +. ps \\n[#DOC_PT_SIZE]u +. if \\n[floating*\\*[labelcap]-indent-l] \ +. in \\n[floating*\\*[labelcap]-indent-l]u +. if \\n[floating*\\*[labelcap]-indent-r] \ +. ll -\\n[floating*\\*[labelcap]-indent-r]u +. ds $QUAD_PREV \\*[$QUAD_VALUE] +. QUAD \\*[floating*\\*[labelcap]-quad] +.\" 1/4 space before both captions and labels +\!. if \\\\n[nl]=\\\\n[#PAGE_TOP] .nr deferred-float 1 +. if !\\n[deferred-float] \{\ +. ie !\\n[@bottom] \{\ +. ie '\\n[.z]'' \ +. sp \\n[#DOC_LEAD]u/4u +. el \ +. if '\\n[.z]'FLOAT*DIV' .sp \\n[#DOC_LEAD]u/4u +. \} +. el \{\ +. sp \\n[#DOC_LEAD]u/4u +. rr @bottom +. \} +. \} +\!. if \\\\n[deferred-float] \{\ +. if !\\n[#QUOTE] .sp -(\\n[#DOC_LEAD]u/4u) +\!. \} +. nr floating*\\*[labelcap]-lead-diff \\n[.v] +. vs \\n[.ps]u+\\n[floating*\\*[labelcap]-autolead]u +. nr floating*\\*[labelcap]-lead-diff \ + \\n[floating*\\*[labelcap]-lead-diff]-\\n[.v] +. if !\\n[deferred-float] \ +. RESTORE_SPACE +. ie '\\*[labelcap]'label' \{\ +. if \\n[to-list] \{\ +.\" Strip prefix from label if list-type is being autolabelled +.\" Becomes $LIST_LABEL +. if '\\*[$LIST_OF]'FIGURES' \ +. if r fig*label-num .STRIP_PRFX_SFFX "\\*[$FLOATING_LABEL]" +. if '\\*[$LIST_OF]'TABLES' \ +. if r tbl*label-num .STRIP_PRFX_SFFX "\\*[$FLOATING_LABEL]" +. if '\\*[$LIST_OF]'EQUATIONS' \ +. if r eqn*label-num .STRIP_PRFX_SFFX "\\*[$FLOATING_LABEL]" +. \} +. ds $FLOATING_LABEL \ +\F[\\\\*[floating*label-family]]\ +\f[\\\\*[floating*label-font]]\ +\s[\\\\*[floating*label-size-change]]\ +\m[\\\\*[floating*label-color]]\ +\\*[$FLOATING_LABEL] +. \} +. el \{\ +. if !\\n[deferred-float] \ +. sp \\n[floating*caption-lead-diff]u +. if !'\\*[floating*caption-space]'' \ +. sp \\*[floating*caption-space] +. while !'\\$1'' \{\ +. nop \ +\F[\\*[floating*caption-family]]\ +\f[\\*[floating*caption-font]]\ +\s[\\*[floating*caption-size-change]]\ +\m[\\*[floating*caption-color]]\ +\\$1 +. if \\n[.u]=1 .br +. shift +. \} +. if !'\\*[floating*caption-space]'' \ +. sp -\\*[floating*caption-space] +. \} +. if \\n[with-caption] \{\ +. nr width-label \w'\\*[$FLOATING_LABEL]' +. if !\\n[width-label]=0 \ +. as $FLOATING_LABEL \0 +. as $FLOATING_LABEL \ +\F[\\\\*[floating*caption-family]]\ +\f[\\\\*[floating*caption-font]]\ +\s[\\\\*[floating*caption-size-change]]\ +\m[\\\\*[floating*caption-color]]\ +\\*[$FLOATING_CAPTION] +. if '\\*[$LIST_CAPTION]'' \ +. ds $LIST_CAPTION \\*[$FLOATING_CAPTION] +. \} +. if !'\\*[$FLOATING_LABEL]'' \{\ +. sp \\n[floating*label-lead-diff]u +. if !'\\*[floating*label-space]'' \ +. sp \\*[floating*label-space] +. nop \\*[$FLOATING_LABEL] +. if \\n[.u]=1 .br +. if !'\\*[floating*label-space]'' \ +. sp -\\*[floating*label-space] +. \} +.\" 1/4 space after captions and labels +. ie !\\n[@bottom] \ +. sp \\n[#DOC_LEAD]u/4u +. el \{\ +. if '\\n[.z]'FLOAT*DIV' \{\ +. sp \\n[#DOC_LEAD]u/4u +\!. if \\\\n[deferred-float] \ +. sp -(\\n[#DOC_LEAD]u/4u) +. \} +. \} +\!. rr deferred-float +. ll +. vs +. QUAD \\*[$QUAD_PREV] +. in +. ev +. if \\n[to-list] \{\ +. nr loop-counter 0 1 +. nr loop-count 2 +. ds labelcap label +. while \\n+[loop-counter]<=\\n[loop-count] \{\ +. ds \\*[labelcap]-family \\*[floating*\\*[labelcap]-family] +. ds \\*[labelcap]-font \\*[floating*\\*[labelcap]-font] +. ds \\*[labelcap]-size-change \\*[floating*\\*[labelcap]-size-change] +. ds \\*[labelcap]-color \\*[floating*\\*[labelcap]-color] +. ie '\\*[$LISTS_FAM]'' \ +. ds floating*\\*[labelcap]-family \\*[$DOC_FAM] +. el \ +. ds floating*\\*[labelcap]-family \\*[$LISTS_FAM] +. if '\\*[$LISTS_FT]'' \ +. ds floating*\\*[labelcap]-font R +. ds floating*\\*[labelcap]-size-change +0 +. ds floating*\\*[labelcap]-color pdf:href.colour +. ds labelcap caption +. \} +. ie '\\*[$LIST_LABEL]'' .TO_\\*[$LIST_OF] "\\*[$FLOATING_LABEL] +. el .TO_\\*[$LIST_OF] "\\*[$LIST_LABEL]" "\\*[$LIST_CAPTION] +. rr to-list +. nr loop-counter 0 1 +. nr loop-count 2 +. ds labelcap label +. while \\n+[loop-counter]<=\\n[loop-count] \{\ +. ds floating*\\*[labelcap]-family \\*[\\*[labelcap]-family] +. ds floating*\\*[labelcap]-font \\*[\\*[labelcap]-font] +. ds floating*\\*[labelcap]-size-change \\*[\\*[labelcap]-size-change] +. ds floating*\\*[labelcap]-color \\*[\\*[labelcap]-color] +. ds labelcap caption +. \} +. \} +. rr with-caption +. rm $FLOATING_CAPTION +. rm $FLOATING_LABEL +. rm $LIST_LABEL +. rm $LIST_CAPTION +.END +. +.ALIAS CAPTION LABEL +. +.MAC STRIP_PRFX_SFFX END +.\" Strip suffix from label string +. ds suffix \\$1 +. substring suffix -1 +.\" If suffix is '.' ',' ':' or ')', remove it. +. if '\\*[suffix]'.' .nr strip-suffix 1 +. if '\\*[suffix]',' .nr strip-suffix 1 +. if '\\*[suffix]':' .nr strip-suffix 1 +. if '\\*[suffix]')' .nr strip-suffix 1 +. if \\n[strip-suffix] \{\ +. ds $LIST_LABEL \\$1 +. substring $LIST_LABEL 0 -2 +. \} +. rr strip-suffix +. if '\\*[$LIST_LABEL]'' .ds $LIST_LABEL \\$1 +.\" Remove prefix (e.g. "Fig. ") by looping through $LIST_LABEL +.\" until a digit is encountered +. nr loop-counter 100 \" arbitrary +. nr loop-count 0 1 +. while \\n+[loop-count]<=\\n[loop-counter] \{\ +. substring $LIST_LABEL 1 +. if \B'\\*[$LIST_LABEL]' .break +. \} +. substring $LIST_LABEL 1 +.END +\# +\# CAPTION_AFTER_LABEL +\# ------------------- +\# *Arguments: +\# <none> | <anything> +\# *Function: +\# Sets register indicating non-MLA captions should come after labels. +\# +.MAC CAPTION_AFTER_LABEL END +. if '\\$1'IMG' .ds type pdf-img +. if '\\$1'PIC' .ds type pic +. if '\\$1'TBL' .ds type tbl +. if !\\n[#MLA] \{\ +. nr \\*[type]*caption-after-label 1 +. if '\\$1'ALL' \{\ +. nr pdf-img*caption-after-label 1 +. nr tbl*caption-after-label 1 +. nr pic*caption-after-label 1 +. \} +. if !'\\$2'' \{\ +. ie !'\\$1'ALL' .rr \\*[type]*caption-after-label +. el \{\ +. rr pdf-img*caption-after-label +. rr tbl*caption-after-label +. rr pic*caption-after-label +. \} +. \} +. \} +.END +\# +\# AUTOLABELLING +\# ------------- +\# *Argument: +\# [ PREFIX <prefix> SUFFIX <suffix> ] | <anything> +\# *Function: +\# Turns label autonumbering on of off; optionally lets user set +\# prefix and suffix for labels. +\# *Notes: +\# Aliased for images (pdf), tbl, pic, and eqn. +\# +.MAC AUTOLABEL END +. if '\\$0'AUTOLABEL_EQUATIONS' .ds label-type eqn +. if '\\$0'AUTOLABEL_TABLES' .ds label-type tbl +. if '\\$0'AUTOLABEL_PIC' \{\ +. ds label-type pic +. nr fig*autolabel 1 +. \} +. if '\\$0'AUTOLABEL_IMAGES' \{\ +. ds label-type pdf-img +. nr fig*autolabel 1 +. \} +. if !'\\$1'' \{\ +. ds \\*[label-type]-label-args \\$1 +. substring \\*[label-type]-label-args -1 -3 +. \} +. if '\\*[\\*[label-type]-label-args]'FIX' .nr \\*[label-type]-label-args 1 +. if '\\*[\\*[label-type]-label-args]'TER' .nr \\*[label-type]-label-args 1 +. if !\\n[\\*[label-type]*label-num] \ +. nr \\*[label-type]*label-num 0 1 +. if '\\*[label-type]'pdf-img' \ +. if !\\n[fig*label-num] .nr fig*label-num 0 1 +. if '\\*[label-type]'pic' \ +. if !\\n[pic*label-num] .nr fig*label-num 0 1 +. nr \\*[label-type]*autolabel 1 +. nr loop-counter 0 1 +. nr loop-count \\n[#NUM_ARGS] +. while \\n+[loop-counter]<=\\n[loop-count] \{\ +. if '\\$1'PREFIX' \{\ +. ds \\*[label-type]*label-prfx \\$2 +. nr \\*[label-type]*label-prfx-set 1 +. shift 2 +. \} +. if '\\$1'SUFFIX' \{\ +. ds \\*[label-type]*label-sffx \\$2 +. nr \\*[label-type]*label-sffx-set 1 +. shift 2 +. \} +. if '\\$1'PREFIX_CHAPTER' \{\ +. if \\n[fig*autolabel] .nr fig*label-with-chapter 1 +. nr \\*[label-type]*label-with-chapter 1 +. shift 1 +. if \B'\\$1' \{\ +. nr #CH_NUM \\$1 +. shift +. \} +. \} +. \} +. if '\\*[\\*[label-type]*label-prfx]'' \{\ +. if '\\*[label-type]'eqn' \ +. if !\\n[\\*[label-type]*label-prfx-set] \ +. ds \\*[label-type]*label-prfx (\" +. if '\\*[label-type]'pic' \ +. if !\\n[\\*[label-type]*label-prfx-set] \ +. ds \\*[label-type]*label-prfx Fig. \" +. if '\\*[label-type]'pdf-img' \ +. if !\\n[\\*[label-type]*label-prfx-set] \ +. ds \\*[label-type]*label-prfx Fig. \" +. if '\\*[label-type]'tbl' \ +. if !\\n[\\*[label-type]*label-prfx-set] \ +. ds \\*[label-type]*label-prfx Table \" +. \} +. if '\\*[\\*[label-type]*label-sffx]'' \{\ +. if '\\*[label-type]'eqn' \ +. if !\\n[\\*[label-type]*label-sffx-set] \ +. ds \\*[label-type]*label-sffx )\" +. if '\\*[label-type]'pic' \ +. if !\\n[\\*[label-type]*label-sffx-set] \ +. ds \\*[label-type]*label-sffx .\" +. if '\\*[label-type]'pdf-img' \ +. if !\\n[\\*[label-type]*label-sffx-set] \ +. ds \\*[label-type]*label-sffx .\" +. if '\\*[label-type]'tbl' \ +. if !\\n[\\*[label-type]*label-sffx-set] \ +. ds \\*[label-type]*label-sffx .\" +. \} +. if \\n[\\*[label-type]-label-args]>0 \{\ +. if \\n[\\*[label-type]*label-prfx-set]+\\n[\\*[label-type]*label-sffx-set]=1 \{\ +. ie (\\n[\\*[label-type]*label-prfx-set]=1)&(\\n[\\*[label-type]*label-sffx-set]=0) \ +. ds missing-arg SUFFIX +. el .ds missing-arg PREFIX +. tm1 "[mom]: You must supply a \\*[missing-arg] argument to \\$0. +. tm1 " If you wish the \\*[missing-arg] to be blank, use \\*[missing-arg] "". +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. \} +. if \\n[#NUM_ARGS]=1 \{\ +. rr fig*autolabel +. rr \\*[label-type]*autolabel +. rr \\*[label-type]*label-prfx-set +. rr \\*[label-type]*label-sffx-set +. \} +. rr \\*[label-type]-label-args +.END +\# +.ALIAS AUTOLABEL_EQUATIONS AUTOLABEL +.ALIAS AUTOLABEL_IMAGES AUTOLABEL +.ALIAS AUTOLABEL_PIC AUTOLABEL +.ALIAS AUTOLABEL_TABLES AUTOLABEL +\# +\# SET AUTOLABEL NUMBER +\# -------------------- +\# *Argument: +\# FIG | TBL | PIC | EQN <n> +\# *Function: +\# Sets the autolabel number for the corresponding label type. +\# *Notes: +\# Used to set autolabel number when manual labelling of floats +\# (in conjunction with TO_LIST) disrupts auto-incrementing. +\# +.MAC SET_AUTOLABEL END +. rm labelnum-type +. if '\\$1'FIG' .ds labelnum-type fig +. if '\\$1'TBL' .ds labelnum-type tbl +. if '\\$1'PIC' .ds labelnum-type pic +. if '\\$1'EQN' .ds labelnum-type eqn +. nr labelnum \\$2-1 +. nr \\*[labelnum-type]*label-num \\n[labelnum] 1 +.END +\# +\# MLA STYLE +\# --------- +\# *Argument: +\# <none> | <anything> +\# *Function: +\# Sets or removes register #MLA. +\# *Notes: +\# MLA formatting differs from other styles wrt caption and +\# label placement. +\# +.MAC MLA END +. ie '\\$1'' \{\ +. nr #MLA 1 +. nr pdf-img*caption-after-label 1 +. nr pic*caption-after-label 1 +. rr tbl*caption-after-label +. \} +. el \ +. rr #MLA +.END +\# +.MAC mla@error END +. tm1 "[mom]: MLA style enabled, but \\$1 has no corresponding \\$2. +. ab [mom]: Aborting '\\$3' at \\$4, line \\$5. +.END +\# +\# LISTS_OF +\# -------- +\# *Aliases: +\# LIST_OF_EQUATIONS +\# LIST_OF_FIGURES +\# LIST_OF_TABLES +\# *Arguments: +\# [ TITLE_STRING <string> ] [ START_PAGENUM <pagenumber> ] +\# *Function: +\# Generates lists-of based on calling alias. +\# *Notes: +\# Called at end of file. +\# If after TOC, and TOC is being auto-relocated, lists are also +\# relocated. If called before, lists are output at end of file. +\# +.MAC LISTS_OF END +. EOL +. ds $LIST_TYPE \\$0 +. nr #LISTS 1 +. substring $LIST_TYPE -1 -4 +. if '\\*[$LIST_TYPE]'URES' \{\ +. ds $LIST_TYPE FIGURES +. ds list-type fig +. ds label-type fig +. ds \\*[$LIST_TYPE]_TITLE_STRING "List of Figures +. \} +. if '\\*[$LIST_TYPE]'BLES' \{\ +. ds $LIST_TYPE TABLES +. ds list-type tbl +. ds label-type tbl +. ds \\*[$LIST_TYPE]_TITLE_STRING "List of Tables +. \} +. if '\\*[$LIST_TYPE]'IONS' \{\ +. ds $LIST_TYPE EQUATIONS +. ds list-type eqn +. ds label-type eqn +. ds \\*[$LIST_TYPE]_TITLE_STRING "List of Equations +. \} +. nr #LIST_OF_\\*[$LIST_TYPE] 1 +. nr loop-count 0 1 +. nr loop-counter \\n[#NUM_ARGS] +. while \\n+[loop-count]<=\\n[loop-counter] \{\ +. if '\\$1'TITLE_STRING' \{\ +. ds \\*[$LIST_TYPE]_TITLE_STRING \\$2 +. shift 2 +. \} +. if '\\$1'START_PAGENUM' \{\ +. nr #\\*[$LIST_TYPE]_START_PAGENUM \\$2 +. shift 2 +. \} +. \} +. if dPDF.EXPORT \ +. if \\n[#FLEX_ACTIVE] \ +. if !\\n[#NO_FLEX] \ +. tm .ds pre-list-\\n%@\\n[#COL_NUM] 1 +. char \[leader] " . +. LEADER_CHARACTER \[leader] +. if \\n[#LINENUMBERS]=1 \{\ +. NUMBER_LINES OFF +. nr #LINENUMBERS 2 +. \} +. if \\n[#FINIS] \{\ +. if \\n[#FOOTERS_WERE_ON] \ +. FOOTERS +. \} +. if \\n[#FOOTERS_ON]=1 \{\ +. if !'\\*[$HDRFTR_CENTER_OLD]'' .ds $HDRFTR_CENTER \\*[$HDRFTR_CENTER_OLD] +. ie \\n[#LISTS_NO_PAGENUM]=1 .PAGINATION OFF +. el .PAGINATE +. \} +. if \\n[#FOOTERS_WERE_ON] \ +. if !\\n[#FINIS] .FOOTERS OFF +. rr #COLUMNS +. COLLATE +. if \\n[#PRINT_STYLE]=1 \{\ +. if \\n[#SINGLE_SPACE] .LS 24 +. DOC_LEAD_ADJUST +. \} +. if \\n[#FINIS] \{\ +. if \\n[#FOOTERS_WERE_ON] .FOOTERS +. rr #FOOTERS_WERE_ON +. if \\n[#PAGINATION_WAS_ON] \{\ +. nr #PAGINATE 1 +. rr #PAGINATION_WAS_ON +. \} +. rr #FINIS +. \} +. ds $HDRFTR_CENTER \\*[$HDRFTR_CENTER_NEW] +. rm $HDRFTR_CENTER_OLD +. rm $HDRFTR_CENTER_NEW +. rr #COLLATED_DOC +. DOCTYPE DEFAULT +. DOCHEADER +. rr #DOCHEADER_ADVANCE +. TITLE "\\*[\\*[$LIST_TYPE]_TITLE_STRING] +. AUTHOR "" +. L_MARGIN \\n[#DOC_L_MARGIN]u +. LL \\n[#DOC_L_LENGTH]u +. if '\\*[$LISTS_FAM]'' \ +. ds $LISTS_FAM \\*[$TOC_FAM] +. if '\\*[$LISTS_FT]'' \ +. ds $LISTS_FT \\*[$TOC_TITLE_FT] +. if !\\n[#LISTS_PS] \ +. nr #LISTS_PS \\n[#TOC_PS] +. ps \\n[#LISTS_PS]u +. if !\\n[#LISTS_LEAD] \ +. nr #LISTS_LEAD \\n[#TOC_LEAD] +. if \\n[#PRINT_STYLE]=2 \{\ +. ie \\n[#LISTS_LEAD_ADJUST]=1 \{\ +. nr #DOC_LEAD \\n[#LISTS_LEAD] +. DOC_LEAD_ADJUST +. TRAPS +. \} +. el \{\ +. nr #DOC_LEAD \\n[#LISTS_LEAD] +. DOC_LEAD_ADJUST OFF +. \} +. \} +. ie !'\\*[$LISTS_TITLE_QUAD]'' \ +. DOCHEADER_QUAD \\*[$LISTS_TITLE_QUAD] +. el .DOCHEADER_QUAD \\*[$TOC_HEADER_QUAD] +. if !'\\*[$LISTS_TITLE_FAM]'' \ +. TITLE_FAMILY \\*[$LISTS_TITLE_FAM] +. if !'\\*[$LISTS_TITLE_FT]'' \ +. TITLE_FONT \\*[$LISTS_TITLE_FT] +. if !'\\*[$LISTS_TITLE_SIZE]'' \ +. TITLE_SIZE \\*[$LISTS_TITLE_SIZE] +. if !'\\*[$LISTS_TITLE_COLOR]'' \ +. TITLE_COLOR \\*[$LISTS_TITLE_COLOR] +. if \\n[#LISTS_TITLE_CAPS] \ +. TITLE_CAPS +. if \\n[#LISTS_TITLE_SMALLCAPS] \ +. TITLE_SMALLCAPS +. if \\n[#LISTS_TITLE_UNDERSCORE] \{\ +. TITLE_UNDERSCORE \ +\\*[DOUBLE] \ +\\*[$LISTS_OF_UL_WT] \ +\\*[$LISTS_OF_UL_GAP] \ +\\*[$LISTS_OF_RULE_GAP] +. \} +. if '\\*[$LISTS_PN_FAM]'' \ +. ds $LISTS_PN_FAM \\*[$TOC_PN_FAM] +. if '\\*[$LISTS_PN_FT]'' \ +. ds $LISTS_PN_FT \\*[$TOC_PN_FT] +. if '\\*[$LISTS_PN_SIZE_CHANGE]'' \ +. ds $LISTS_PN_SIZE_CHANGE \\*[$TOC_PN_SIZE_CHANGE] +. if !\\n[#EQN_PN_PADDING] \ +. nr #EQN_PN_PADDING \\n[#TOC_PN_PADDING] +. if !\\n[#FIG_PN_PADDING] \ +. nr #FIG_PN_PADDING \\n[#TOC_PN_PADDING] +. if !\\n[#TBL_PN_PADDING] \ +. nr #TBL_PN_PADDING \\n[#TOC_PN_PADDING] +. ie '\\*[$LISTS_PAGENUM_STYLE]'' \ +. PAGENUM_STYLE \\*[$TOC_PAGENUM_STYLE] +. el \ +. PAGENUM_STYLE \\*[$LISTS_PAGENUM_STYLE] +. if r #\\*[$LIST_TYPE]_START_PAGENUM \ +. PAGENUMBER \\n[#\\*[$LIST_TYPE]_START_PAGENUM] +. if r #LISTS_NO_PAGENUM .PAGINATION off +. HEADER_LEFT "\\*[$HDRFTR_LEFT] +. HEADER_RIGHT "\\*[$HDRFTR_RIGHT] +. HEADER_CENTER "\\*[\\*[$LIST_TYPE]_TITLE_STRING] +. if \\n[#LINENUMBERS]=2 .nr #LINENUMBERS 3 +.\" Get num placeholders for ch. num and label num. +. if \\n[\\*[list-type]*autolabel] \{\ +. if \\n[\\*[label-type]*label-with-chapter] \{\ +. if \\n[#CH_NUM]<1000 .nr chapno-width 3 +. if \\n[#CH_NUM]<100 .nr chapno-width 2 +. if \\n[#CH_NUM]<10 .nr chapno-width 1 +. \} +. if \\n[\\*[list-type]*label-num]<1000 .nr label-width 3 +. if \\n[\\*[list-type]*label-num]<100 .nr label-width 2 +. if \\n[\\*[list-type]*label-num]<10 .nr label-width 1 +.\" Calculate width of label-num tab +. nr label-width \\n[\\*[list-type]*label-width] +. \} +. if \\n[#SLANT_ON] .nop \\*[SLANTX] +. if \\n[#COLUMNS]=1 .nr #COLUMNS 0 +. START +. if \\n[#PRINT_STYLE]=2 .sp -1 +. if '\\*[$LIST_TYPE]'FIGURES' .LIST_OF_FIG +. if '\\*[$LIST_TYPE]'TABLES' .LIST_OF_TBL +. if '\\*[$LIST_TYPE]'EQUATIONS' .LIST_OF_EQN +. if \\n[#LINENUMBERS]=3 \{\ +. NUMBER_LINES RESUME +. nr #LINENUMBERS 1 +. nn 1 +. \} +. rr #LISTS +. pdfsync +.END +.\" +.ALIAS LIST_OF_EQUATIONS LISTS_OF +.ALIAS LIST_OF_FIGURES LISTS_OF +.ALIAS LIST_OF_TABLES LISTS_OF +\# +\# LISTS-OF STYLE +\# -------------- +\# *Arguments: +\# FAMILY fam \ +\# FONT sty \ +\# PT_SIZE size \ +\# LEAD leading [ADJUST] \ +\# TITLE_FAMILY fam \ +\# TITLE_FONT sty \ +\# TITLE_SIZE +|-size \ +\# TITLE_QUAD LEFT | CENTER | RIGHT \ +\# TITLE_COLOR color \ +\# TITLE_CAPS \ +\# TITLE_NO_CAPS \ +\# TITLE_SMALLCAPS \ +\# TITLE_NO_SMALLCAPS \ +\# TITLE_UNDERSCORE [ DOUBLE] <wt> <gap> (dbl-rule-gap) \ +\# NO_PAGINATION \ +\# PAGENUM_STYLE format \ +\# PN_FAMILY fam \ +\# PN_FONT sty \ +\# PN_SIZE +|-size \ +\# PN_PADDING n +\# *Function: +\# Allows setting of all style parameters for lists-of. +\# *Notes: +\# Assumption is that lists-of will all have the same style. +\# TOC style is used if LISTS_STYLE is omitted. +\# +.MAC LISTS_STYLE END +. nr loop-count 0 1 +. nr loop-counter \\n[#NUM_ARGS] +. while \\n+[loop-count]<=\\n[loop-counter] \{\ +. if '\\$1'FAMILY' \{\ +. ds $LISTS_FAM \\$2 +. shift 2 +. \} +. if '\\$1'FONT' \{\ +. ds $LISTS_FT \\$2 +. shift 2 +. \} +. if '\\$1'TITLE_FAMILY' \{\ +. ds $LISTS_TITLE_FAM \\$2 +. shift 2 +. \} +. if '\\$1'TITLE_FONT' \{\ +. ds $LISTS_TITLE_FT \\$2 +. shift 2 +. \} +. if '\\$1'TITLE_SIZE' \{\ +. ds $LISTS_TITLE_SIZE \\$2 +. shift 2 +. \} +. if '\\$1'TITLE_QUAD' \{\ +. ds $LISTS_TITLE_QUAD \\$2 +. shift 2 +. \} +. if '\\$1'TITLE_COLOR' \{\ +. ds $LISTS_TITLE_COLOR \\$2 +. shift 2 +. \} +. if '\\$1'TITLE_CAPS' \{\ +. nr #LISTS_TITLE_CAPS 1 +. shift 1 +. \} +. if '\\$1'TITLE_NO_CAPS' \{\ +. rr #LISTS_TITLE_CAPS +. shift 1 +. \} +. if '\\$1'TITLE_SMALLCAPS' \{\ +. nr #LISTS_TITLE_SMALLCAPS 1 +. shift 1 +. \} +. if '\\$1'TITLE_NO_SMALLCAPS' \{\ +. rr #LISTS_TITLE_NO_SMALLCAPS +. shift 1 +. \} +.\" UNDERSCORE and UNDERLINE are identical, but we can't evaluate +.\" the results of two string comparisons. +. if '\\$1'TITLE_UNDERSCORE' \{\ +. nr #LISTS_TITLE_UNDERSCORE 1 +. shift +. ie '\\$1'DOUBLE' \{\ +. ds DOUBLE DOUBLE +. shift +. if \B'\\$1' \{\ +. ds $LISTS_OF_UL_WT \\$1 +. shift +. \} +. if \B'\\$1' \{\ +. ds $LISTS_OF_UL_GAP \\$1 +. shift +. \} +. if \B'\\$1' \{\ +. ds $LISTS_OF_RULE_GAP \\$1 +. shift +. \} +. \} +. el \{\ +. if \B'\\$1' \{\ +. ds $LISTS_OF_UL_WT \\$1 +. shift +. \} +. if \B'\\$1' \{\ +. ds $LISTS_OF_UL_GAP \\$1 +. shift +. \} +. \} +. \} +. if '\\$1'TITLE_UNDERLINE' \{\ +. nr #LISTS_TITLE_UNDERSCORE 1 +. shift +. ie '\\$1'DOUBLE' \{\ +. ds DOUBLE DOUBLE +. shift +. if \B'\\$1' \{\ +. ds $LISTS_OF_UL_WT \\$1 +. shift +. \} +. if \B'\\$1' \{\ +. ds $LISTS_OF_UL_GAP \\$1 +. shift +. \} +. if \B'\\$1' \{\ +. ds $LISTS_OF_RULE_GAP \\$1 +. shift +. \} +. \} +. el \{\ +. if \B'\\$1' \{\ +. ds $LISTS_OF_UL_WT \\$1 +. shift +. \} +. if \B'\\$1' \{\ +. ds $LISTS_OF_UL_GAP \\$1 +. shift +. \} +. \} +. \} +. if '\\$1'TITLE_NO_UNDERSCORE' \{\ +. rr #LISTS_TITLE_UNDERSCORE 1 +. rm DOUBLE +. rm $LISTS_OF_UL_WT +. rm $LISTS_OF_UL_GAP +. rm $LISTS_OF_RULE_GAP +. shift +. \} +. if '\\$1'TITLE_NO_UNDERLINE' \{\ +. rr #LISTS_TITLE_UNDERSCORE 1 +. rm DOUBLE +. rm $LISTS_OF_UL_WT +. rm $LISTS_OF_UL_GAP +. rm $LISTS_OF_RULE_GAP +. shift +. \} +. if '\\$1'PT_SIZE' \{\ +. nr #LISTS_PS (p;\\$2) +. shift 2 +. \} +. if '\\$1'LEAD' \{\ +. nr #LISTS_LEAD (p;\\$2) +. ie !'\\$3'ADJUST' \{\ +. nr #LISTS_LEAD_ADJUST 0 +. shift 2 +. \} +. el \{\ +. nr #LISTS_LEAD_ADJUST 1 +. shift 3 +. \} +. \} +. if '\\$1'NO_PAGINATION' \{\ +. nr #LISTS_NO_PAGENUM 1 +. shift 1 +. \} +. if '\\$1'PAGENUM_STYLE' \{\ +. ds $LISTS_PAGENUM_STYLE \\$2 +. shift 2 +. \} +. if '\\$1'PN_FAMILY' \{\ +. ds $LISTS_PN_FAM \\$2 +. shift 2 +. \} +. if '\\$1'PN_FONT' \{\ +. ds $LISTS_PN_FT \\$2 +. shift 2 +. \} +. if '\\$1'PN_SIZE' \{\ +. ds $LISTS_PN_SIZE_CHANGE \\$2 +. shift 2 +. \} +. if '\\$1'EQN_PN_PADDING' \{\ +. nr #EQN_PN_PADDING \\$2 +. shift 2 +. \} +. if '\\$1'FIG_PN_PADDING' \{\ +. nr #FIG_PN_PADDING \\$2 +. shift 2 +. \} +. if '\\$1'TBL_PN_PADDING' \{\ +. nr #TBL_PN_PADDING \\$2 +. shift 2 +. \} +. \} +.END +\# +\# Lists-of collector +\# Strings to allocate space for leaders and entry page numbers +\# +.ds $LISTS_PN \\*[ST102]\F[\\*[$LISTS_PN_FAM]]\f[\\*[$LISTS_PN_FT]]\ +\s[\\n[#LISTS_PS]u]^\\*[ST102X]\\*[ST103]\s[\\\\*[$LISTS_PN_SIZE_CHANGE]]\ +\h'.5m'\h'\w'0'u*\\\\n[#LISTS_PN_PADDING]u'\\*[ST103X] +\# +.ds $LISTS_PN_TYPEWRITE \\*[ST102]^\\*[ST102X]\\*[ST103]\|\ +\h'\w'\0'u*\\\\n[#LISTS_PN_PADDING]u'\\*[ST103X] +\# +.MAC LISTS_COLLECTOR END +. nr #LISTS_ENTRY_PN \\n%+\\n[#PAGE_NUM_ADJ] +. if \\n[#KERN] .nr #RESTORE_KERN 1 +. KERN OFF +. if '\\$0'TO_EQUATIONS' \{\ +. ds list-type eqn +. ds label-type eqn +. da LIST_OF_EQN +\!. nr #LISTS_PN_PADDING \\\\n[#EQN_PN_PADDING] +. \} +. if '\\$0'TO_FIGURES' \{\ +. ds list-type fig +. ds label-type fig +. if (\\n[pdf-img*have-label]=1):(\\n[pdf-img*autolabel]=1):\ +(\\n[pic*autolabel]=1):(\\n[pic*have-label]=1) \{\ +. nr \\*[label-type]*have-label 1 +. if !'\\*[pdf-img*label]'' .rn pdf-img*label \\*[label-type]*label +. if !'\\*[pic*label]'' .rn pic*label \\*[label-type]*label +. \} +. da LIST_OF_FIG +\!. nr #LISTS_PN_PADDING \\\\n[#FIG_PN_PADDING] +. \} +. if '\\$0'TO_TABLES' \{\ +. ds list-type tbl +. ds label-type tbl +. da LIST_OF_TBL +\!. nr #LISTS_PN_PADDING \\\\n[#TBL_PN_PADDING] +. \} +. br +. ie \\n[#PRINT_STYLE]=1 \{\ +\!. fam \\*[$TYPEWRITER_FAM] +\!. ft R +\!. ps \\*[$TYPEWRITER_PS] +. ds _TYPEWRITE _TYPEWRITE +. \} +. el \{\ +\!. FAMILY \\\\*[$LISTS_FAM] +\!. FONT \\\\*[$LISTS_FT] +\!. ps \\\\n[#LISTS_PS]u +. \} +. if \\n[#PRINT_STYLE]=2 .rm _TYPEWRITE +\!. PAD_MARKER ^ +\!. vpt 0 +. ie !\\n[\\*[label-type]*autolabel] \{\ +.\" If there is a label... +. if !'\\*[\\*[label-type]*label]'' \ +\!. PAD \ +"\\*[ST100]\h'\w'\\*[\\*[label-type]*label]'u'\\*[ST100X]\0\\*[ST101]\h'\w'\\$2'u'\\*[ST101X]\\\\*[$LISTS_PN\\*[_TYPEWRITE]]" \ +"\*[PDFBOOKMARK.NAME]" +.\" If there is no label... +. if '\\*[\\*[label-type]*label]'' \ +\!. PAD \ +"\\*[ST100]\\*[ST100X]\\*[ST101]\h'\w'\\$1'u'\0\\*[ST101X]\\\\*[$LISTS_PN\\*[_TYPEWRITE]]" \ +"\*[PDFBOOKMARK.NAME]" +. \} +.\" If autolabelling... +. el \ +\!. PAD \ +"\\*[ST100]\h'\\\\n[label-width]u'\\*[ST100X]\ \ \ \\*[ST101]\h'\w'\\$2'u'\\*[ST101X]\\\\*[$LISTS_PN\\*[_TYPEWRITE]]" \ +"\*[PDFBOOKMARK.NAME]" +\!. PAD_MARKER # +\!. EOL +. ie !\\n[\\*[label-type]*autolabel] \ +\!. ST 100 L +. el \ +\!. ST 100 R +\!. ST 101 L +\!. ST 102 L +\!. ST 103 R +. if \\n[#PRINT_STYLE]=2 \{\ +\!. FAMILY \\\\*[$LISTS_FAM] +\!. FT \\\\*[$LISTS_FT] +\!. ps \\\\n[#LISTS_PS]u +. \} +\!. TAB 100 +\!. PDF_LINK \\*[list-type]:\\n[lists*target] "\\$1" +\!. TN +\!. vpt 0 +\!. PDF_LINK \\*[list-type]:\\n[lists*target] "\\$2" +\!. TN +\!. vpt 0 +\!. PRINT \fR\\*[LEADER]\f[] +\!. TN +. if \\n[#PRINT_STYLE]=2 \{\ +\!. FAMILY \\\\*[$LISTS_PN_FAM] +\!. FT \\\\*[$LISTS_PN_FT] +\!. ps \\\\*[$LISTS_PN_SIZE_CHANGE] +. \} +\!. PRINT \\n[#LISTS_ENTRY_PN] +\!. TQ +\!. vpt +. da +. if \\n[#RESTORE_KERN] .KERN +.END +. +.ALIAS TO_EQUATIONS LISTS_COLLECTOR +.ALIAS TO_FIGURES LISTS_COLLECTOR +.ALIAS TO_TABLES LISTS_COLLECTOR +\# +\# ***tbl*** +\# +\# Support for multipage tables with headers borrowed from ms and +\# mommified by Robin Haberkorn <robin.haberkorn@googlemail.com> +\# with extensions by Peter Schaffter. +\# +.nr tbl*have-header 0 +.ds T& +\# +.MAC TS END +. if \\n[.t]<\\n[#DOC_LEAD] .nr begin-tbl 1 +. br +. rr tbl*pdfbx +. if r pdfbx-top \{\ +. rt +. sp (\\*[wt\\n[stack]]/2u)+\\*[gap\\n[stack]]u +. \} +. rr begin-tbl +. rm tbl*caption +. rm tbl*label +. rr tbl*have-caption +. rr tbl*have-label +. rr tbl*have-header +. rr float*tbl +. rr tbl*boxed +. nr ind-pre-tbl \\n[.i] +. nr ll-pre-tbl \\n[.l] +. nr lead-pre-tbl \\n[.v] +. nr tbl*needs 1 +. nr doing-tbl 1 +. nf +. if '\\n[.z]'FLOAT*DIV' .nr float*tbl 1 +. if !'\\n[.z]'FLOAT*DIV' \{\ +. if \\n[.t]=1 \{\ +. if (\\n[@TOP]=0)&(\\n[#START]=0) \{\ +. ie \\n[#COLUMNS] .COL_NEXT internal +. el .NEWPAGE +. \} +. \} +. \} +. nr loop-count 0 1 +. nr loop-counter \\n[#NUM_ARGS] +. ie \\n[#NUM_ARGS]=1 \{\ +. if '\\$1'H' \{\ +. nr tbl*have-header 1 +. nr tbl*plain 1 +. \} +. \} +. el \{\ +. while \\n+[loop-count]<=\\n[loop-counter] \{\ +. if '\\$1'H' \{\ +. nr tbl*have-header 1 +. shift +. \} +. if '\\$1'BOXED' \{\ +. nr tbl*boxed 1 +. shift +. \} +. if '\\$1'CENTER' \{\ +. if \\n[#INDENT_BOTH_ACTIVE] \{\ +. IBX +. nr #RESTORE_INDENT_BOTH 1 +. \} +. nr tbl*center 1 +. shift +. \} +. if '\\$1'CENTRE' \{\ +. if \\n[#INDENT_BOTH_ACTIVE] \{\ +. IBX +. nr #RESTORE_INDENT_BOTH 1 +. \} +. nr tbl*center 1 +. shift +. \} +. if '\\$1'NEEDS' \{\ +. nr tbl*needs \\$2 +. shift 2 +. \} +. if '\\$1'NO_SHIM' \{\ +. nr tbl*no-shim 1 +. shift +. \} +. if '\\$1'NO_FLEX' \{\ +. nr tbl*no-flex 1 +. shift +. \} +. if '\\$1'ADJUST' \{\ +. ds tbl*space-adj \\$2 +. shift 2 +. \} +. if '\\$1'CAPTION' \{\ +. nr tbl*have-caption 1 +. ds tbl*caption \\$2 +. shift 2 +. \} +. if '\\$1'SHORT_CAPTION' \{\ +. ds tbl*caption-short \\$2 +. shift 2 +. \} +. if '\\$1'LABEL' \{\ +. nr tbl*have-label 1 +. ds tbl*label \\$2 +. shift 2 +. \} +. if '\\$1'TARGET' \{\ +. ds target "\\$2 +. PDF_TARGET "\\*[target] +. shift 2 +. \} +. \} +. \} +. if (\\n[tbl*have-caption]=0):(\\n[tbl*caption-after-label]=1) \{\ +. rr pdfbx-top +. if \\n[tbl*boxed] .sp -1p +. \} +. if \\n[tbl*have-header] .nr tbl*needs +1 +. if (\\n[tbl*have-label]=1):(\\n[tbl*autolabel]=1) \ +. ds label-type tbl +. if (\\n[tbl*have-caption]=1)&(\\n[tbl*have-header]=0) \ +. tbl*caption-warning +. if \\n[tbl*boxed] \{\ +. if (\\n[tbl*have-label]=0)&(\\n[tbl*have-caption]=0)&\ +(\\n[tbl*autolabel]=0)&(\\n[tbl*have-source]=0) \ +. nr tbl*plain-boxed 1 +. \} +. if !\\n[tbl*have-header] .nr tbl*no-header 1 +. ds tbl*label-sffx-tmp \\*[tbl*label-sffx] +. if !'\\*[tbl*label-sffx-tmp]'' .substring tbl*label-sffx-tmp -1 +. if '\\*[tbl*label-sffx-tmp]'.' \ +. if (\\n[tbl*caption-after-label]=0):(\\n[#MLA]=1) .chop tbl*label-sffx +. if \\n[tbl*caption-after-label] \{\ +. if !'\\*[tbl*label-sffx]'' \ +. if '\\*[tbl*caption]'' .chop tbl*label-sffx +. \} +. if !'\\*[tbl*caption-short]'' .ds short -short +. if \\n[tbl*autolabel] \{\ +. if \\n[tbl*label-with-chapter] \ +. ds chapno \\n[#CH_NUM]. +. ds tbl*label \ +\\*[tbl*label-prfx]\\*[chapno]\\n+[tbl*label-num]\\*[tbl*label-sffx]\" +. nr tbl*label-width \w'\\*[tbl*label]' +. \} +. ie \\n[@TOP] \{\ +. if !'\\n[.z]'FLOAT*DIV' \{\ +. RESTORE_SPACE +. nr @TOP 1 +. if \\n[#COLUMNS] \ +. if !'\\*[tbl*space-adj]'' \ +. sp \\*[tbl*space-adj]-1v +. if \\n[tbl*boxed] .nr tbl*boxed 2 +. vpt +. \} +. \} +. el \ +. if !'\\*[tbl*space-adj]'' .sp \\*[tbl*space-adj]u +. if !\\n[#MLA] \{\ +. if (\\n[tbl*have-caption]=0):(\\n[tbl*caption-after-label]=1) \{\ +. ie !'\\n[.z]'FLOAT*DIV' \{\ +. ie !\\n[tbl*boxed]=2 \{\ +. if \\n[tbl*have-header] .nr tbl*restore-header 1 +. if !\\n[@TOP] .sp .5v +. if \\n[tbl*boxed] .sp .25v +. if \\n[tbl*restore-header]=1 .nr tbl*have-header 1 +. \} +. el \{\ +. if !\\n[tbl*boxed] .ns +. sp .25v +. \} +. \} +. el .sp .5v +. \} +. \} +. if \\n[nl]=\\n[#PAGE_TOP] .ns +. if '\\n[.z]'FLOAT*DIV' \{\ +. ie \\n[defer]>0 .sp .5v +. el .sp .25v +. \} +. if \\n[@TOP] .rr @TOP +. ds ev-current \\n[.ev] +. if (\\n[nl]=\\n[#PAGE_TOP]):(\\n[nl]=\\n[dc]) \ +. nr tbl*caption-lead-diff-adj 1 +. if \\n[#MLA] \ +. if \\n[tbl*have-label]+\\n[tbl*have-caption]=0 \ +. sp .5v +. if \\n[tbl*boxed]=2 \{\ +. if \\n[#MLA]=0 \ +. if (\\n[tbl*caption-after-label]=1):(\\n[tbl*have-caption]=0) \ +. sp 1n +. \} +. fi +. if \\n[tbl*have-header] \{\ +. di tbl*header-div +. ev table-header +. evc \\*[ev-current] +. if !\\n[float-span] \{\ +. ie '\\*[ev-current]'FLOAT' \{\ +. ie !\\n[tbl*center] \ +. in 0 +. el \{\ +. in 0 +\!. in 0 +. \} +. \} +. el \!.in 0 +. \} +. \} +.END +\# +.MAC TH END +. ie '\\n[.z]'tbl*header-div' \{\ +. nr T. 0 +. T# +. di +. ev +. if \\n[#PDF_BOOKMARKS] \{\ +. ie !'\\n[.z]'' \{\ +. if (\\n[float*img]=0)&(\\n[float*pic]=0)&(\\n[float*eqn]=0) \{\ +\!. PDF_TARGET tbl:\\\\n+[lists*target] +. ie !'\\*[tbl*label]'' \ +\!. TO_TABLES "\\*[tbl*label]" "\\*[tbl*caption\\*[short]]" +. el \ +\!. TO_TABLES "\\*[tbl*caption\\*[short]]" +. \} +. \} +. el \{\ +. if '\\n[.z]'' .PDF_TARGET tbl:\\n+[lists*target] +. ie !'\\*[tbl*label]'' \ +. TO_TABLES "\\*[tbl*label]" "\\*[tbl*caption\\*[short]]" +. el \ +. TO_TABLES "\\*[tbl*caption\\*[short]]" +. \} +. \} +. if \\n[#MLA] .if !\\n[tbl*have-caption] \ +. mla@error label caption \\n[.F] \\$0 \\n[.c] +. if !'\\n[.z]'FLOAT*DIV' \{\ +. ie !\\n[tbl*boxed] \{\ +. nr th*needs (u;\\n[dn]+\\n[tbl*needs]v) +. if \\n[th*needs]>\\n[.t] \{\ +. if dPDF.EXPORT \ +. if \\n[#FLEX_ACTIVE] \ +. if !\\n[#NO_FLEX] \ +. tm .ds pre-newpage-\\n% \\n%@\\n[#COL_NUM] +. ne \\n[dn]u+\\n[tbl*needs]v +. nr tbl@needs 1 +. \} +. \} +. el \{\ +. nr th*needs (u;\\n[dn]+.3n+\\n[tbl*needs]v) +. if \\n[th*needs]>\\n[.t] \{\ +. if \\n[#COLUMNS] \ +. if !\\n[#COL_NUM]=\\n[#NUM_COLS] \ +. nr tbl*no-top-hook 1 +. nr tbl*no-print-header 1 +. if dPDF.EXPORT \ +. if \\n[#FLEX_ACTIVE] \ +. if !\\n[#NO_FLEX] \ +. tm .ds pre-newpage-\\n% \\n%@\\n[#COL_NUM] +. ne \\n[dn]u+\\n[tbl*needs]v +. nr tbl@needs 1 +. \} +. \} +. \} +. ie (\\n[dn]-\\n[.v])>\\n[.t] \{\ +. if !\\n[@TOP] .@error ridiculously long table header +. if \\n[tbl@needs] \{\ +. if \\n[tbl*boxed] \{\ +. RESTORE_SPACE +. sp -1n +. \} +. rr tbl@needs +. \} +. if \\n[tbl*have-caption] .TBL*CAPTION +. \} +. el \{\ +. nr tbl*header-ht \\n[dn] +. if \\n[tbl@needs] \{\ +. if \\n[tbl*boxed] \{\ +. RESTORE_SPACE +. if !\\n[#MLA] \{\ +. if (\\n[tbl*have-caption]=0):(\\n[tbl*caption-after-label]=1) \ +. nop \& +. sp -1n +. \} +. \} +. rr tbl@needs +. \} +. if (\\n[tbl*have-caption]=1)&(\\n[tbl*caption-after-label]=0) \{\ +. TBL*CAPTION +. vs +. \} +. tbl*print-header +. \} +. \} +. el \{\ +. if \\n[tbl*have-caption] \{\ +. TBL*CAPTION +. nr skip-th-warning 1 +. \} +. if !\\n[skip-th-warning] .@error .TH without .TS H +. rr skip-th-warning +. \} +.\" When centering a boxed table inside a float, .T# won't place +.\" vertical rules in the correct horizontal position unless .ll is +.\" given a nominal value (can be anything) and an indent is set +.\" manually. +. if '\\n[.z]'FLOAT*DIV' \{\ +. if \\n[tbl*center] \{\ +. nr float*ll \\n[.l] +. ll 0 +. in \\n[float*ll]u-\\n[TW]u/2u +. \} +. \} +.END +\# +.MAC TE END +. if !r TW \{\ +. tm1 "[mom]: '\\n[.F]' contains tbl(1) data but '-t' flag is missing from +. tm1 " the command line. +. ab Aborting. +. \} +. ev tbl*end \" Needed because of .ad changes +. evc \\*[ev-current] +. nh +. nf +. rr tbl*no-header +. if !'\\$1'' \{\ +. if '\\$1'SOURCE' \{\ +. ie !\\n[#MLA] \{\ +. tm1 "[mom]: \\$1 argument to \\$0 at line \\n[.c], but MLA style not enabled. +. tm1 " Ignoring \\$1, but continuing to process. +. \} +. el \{\ +. nr tbl*have-source 1 +. shift +. \} +. \} +. \} +. if (\\n[#MLA]=1)&(\\n[tbl*have-source]=0) .tbl*source-warning +. if !'\\n[.z]'FLOAT*DIV' \{\ +. if \\n[.t]<(\\n[.v]/2u) \{\ +. ie (\\n[tbl*have-label]=1):\ +(\\n[tbl*caption-after-label]=1):\ +(\\n[tbl*have-source]=1):\ +(\\n[tbl*autolabel]=1) \{\ +. rm tbl*header-div +. nr tbl*no-top-hook 1 +. ie \\n[tbl*autolabel] \ +. if \\n[#MLA] \ +. if !\\n[tbl*have-source] . +. el \{\ +. nr pgnum \\n%+\\n[#PAGE_NUM_ADJ] +. if \\n[#COLUMNS]=1 .ds col-num ", column \\n[#COL_NUM] +. tm1 "[mom]: '\\n[.F]', macro \\$0, line \\n[.c]: +. tm1 " Insufficient room for label, caption, and/or source after +. tm1 " table on page \\n[pgnum]\\*[col-num]. Omitting, but continuing to process table. +. \} +. nr tbl*skip-source 1 +. nr tbl*skip-label 1 +. rr tbl*have-caption +. ie \\n[#COLUMNS] \ +. COL_NEXT internal +. el .NEWPAGE +. \} +. el \{\ +.\" Don't print tbl-header at top of next page or column if tbl +.\" finishes without room for further input at bottom of page +. rm tbl*header-div +. nr tbl*no-print-header 1 +. nr tbl*no-top-hook 1 +. ie \\n[#COLUMNS] \ +. COL_NEXT internal +. el .NEWPAGE +. \} +. \} +. \} +. if !\\n[#MLA] \{\ +. if (\\n[tbl*have-label]=1):(\\n[tbl*autolabel]=1):(\\n[tbl*caption-after-label]=1) \{\ +. ev label +. if '\\*[ev-current]'FLOAT' .evc 0 +. ie \\n[#PRINT_STYLE]=1 .TYPEWRITER +. el \{\ +. tbl*label-style +. vs \\n[.ps]u+\\n[tbl*label-autolead]u +. \} +. SIZESPECS +. if \\n[tbl*label-with-chapter] \ +. ds chapno \\n[#CH_NUM]. +. TBL*SET_LABEL_QUAD \\*[tbl*label-quad] +. di tbl*label-div +. ie \\n[tbl*boxed] .sp \\n[#CAP_HEIGHT]u +. el .sp \\n[#DOC_LEAD]u/4u +. if (\\n[tbl*have-label]=1):(\\n[tbl*autolabel]=1) \{\ +. if !'\\*[tbl*label-space]'' .sp \\*[tbl*label-space] +. ie \\n[tbl*autolabel] \{\ +. ie !\\n[tbl*caption-after-label] .nop \ +\\*[tbl*label] +. el \{\ +. nop \ +\\*[tbl*label]\| +. tbl*caption-style +. vs \\n[.ps]u+\\n[tbl*caption-autolead]u +. ds tbl*caption-old \\*[tbl*caption] +. ds tbl*caption " \\*[tbl*caption] +. nop \\*[tbl*caption] +. ds tbl*caption \\*[tbl*caption-old] +. \} +. \} +. el \{\ +. ie !\\n[tbl*caption-after-label] .nop \\*[tbl*label] +. el \{\ +. nop \\*[tbl*label]\ \|\c +. tbl*caption-style +. vs \\n[.ps]u+\\n[tbl*caption-autolead]u +. ds tbl*caption " \\*[tbl*caption] +. nop \\*[tbl*caption] +. \} +. \} +. \} +. br +. di +. in 0 +. ev +. nr pgnum \\n%+\\n[#PAGE_NUM_ADJ] +. ie !'\\n[.z]'FLOAT*DIV' \{\ +. rr tbl*have-header +. rr tbl*have-caption +. ie (\\n[dn]-\\n[.v])>\\n[.t] \{\ +. if \\n[#COLUMNS]=1 .ds col-num ", column \\n[#COL_NUM] +. tm1 "[mom]: '\\n[.F]', macro \\$0, line \\n[.c]: +. tm1 " Insufficient room for label, caption, and/or source after +. tm1 " table on page \\n[pgnum]\\*[col-num]. Omitting, but continuing to process. +. ie \\n[#COLUMNS] \ +. COL_NEXT internal +. el .NEWPAGE +. if d tbl*header-div .rm tbl*header-div +. rr tbl*caption-top-lead-diff +. nr tbl*skip-source 1 +. nr tbl*skip-label 1 +. \} +. el .print-label +. \} +. el .print-label +. \} +. \} +. if \\n[tbl*autolabel] \{\ +. ds tbl*label \\*[chapno]\\n[tbl*label-num] +. if dLABEL.REFS \ +. tm .ds \\*[target] \\*[chapno]\\n[tbl*label-num] +. rm target +. \} +. if !\\n[tbl*skip-source] \{\ +. if \\n[tbl*have-source] \{\ +. ds tbl*source \\$1 +. SIZESPECS +. ev source +. evc \\*[ev-current] +. nf +. nh +. ie \\n[#PRINT_STYLE]=1 \{\ +. TYPEWRITER +. sp +. \} +. el \{\ +. tbl*source-style +. vs \\n[.ps]u+\\n[tbl*source-autolead]u +. \} +. di tbl*source-div +. TBL*SET_SOURCE_QUAD \\*[tbl*source-quad] +. if (\\n[tbl*have-label]=0)&(\\n[#MLA]=0) \ +. if !\\n[tbl*autolabel] .sp \\n[#CAP_HEIGHT]u +. if \\n[#MLA] \ +. sp \\n[#CAP_HEIGHT]u +. if !'\\*[tbl*source-space]'' .sp \\*[tbl*source-space] +. nop \\*[tbl*source] +. br +. di +. nf +. tbl*source-div +. ev +. \} +. \} +. if '\\n[.z]'FLOAT*DIV' .nr bx-tbl-depth \\n[.d]-1v +. if '\\n[.z]'tbl*header-div' \{\ +. @error .TS with 'H' flag but no corresponding .TH +. ab Aborting. +. \} +. ev +. if !\\n[tbl*plain] \{\ +. ie \\n[tbl*plain-boxed] \{\ +. ie \\n[#MLA] .if !\\n[tbl*have-source] .sp .6v +. el .sp +. \} +. el \{\ +. if !\\n[tbl*have-source] \{\ +. if (\\n[tbl*have-label]=0)&\ +(\\n[tbl*caption-after-label]=0)&(\\n[tbl*autolabel]=0) \ +. sp 1v +. if (\\n[tbl*have-label]=1):(\\n[tbl*autolabel]=1) \ +. sp .5v +. \} +. if '\\n[.z]'FLOAT*DIV' .nr chop-space 1 +. \} +. \} +. ll \\n[ll-pre-tbl]u +. if (\\n[nl]=\\n[dc]):(\\n[nl]=\\n[#PAGE_TOP]) .ns +. if !'\\*[tbl*space-adj]'' .sp -\\*[tbl*space-adj]u +. if \\n[#MLA] \ +. sp .5v +. if !r pdfbx-running \{\ +. ie !\\n[tbl*no-shim] \{\ +. ie !\\n[#NO_SHIM] \ +. if !'\\n[.z]'FLOAT*DIV' .SHIM +. el \ +. if !\\n[tbl*no-flex] \ +. if !\\n[#NO_FLEX] \ +. if !'\\n[.z]'FLOAT*DIV' .FLEX +. \} +. el \ +. if !\\n[tbl*no-flex] \ +. if !\\n[#NO_FLEX] \ +. if !'\\n[.z]'FLOAT*DIV' .FLEX +. \} +. ie \\n[tbl*boxed] \{\ +. nr tbl*pdfbx 2 +. if \\n[tbl*have-label] .nr tbl*pdfbx 3 +. \} +. el .nr tbl*pdfbx 1 +. TBL*CLEANUP +. it 2 rr-tbl*pdfbx +.END +\# +\# Utility macros for tbl +\# +.MAC TBL*CAPTION END +. ev caption +. evc \\*[ev-current] +. vs \\n[.ps]u+\\n[tbl*caption-autolead]u +. nr caption-lead \\n[.v] +. nr tbl*caption-lead-diff \\n[lead-pre-tbl]-\\n[.v] +. nr tbl*caption-top-lead-diff \\n[tbl*caption-lead-diff] +. ie !\\n[#MLA] \{\ +. if \\n[tbl*have-caption] \{\ +.\" Get rid of these guys when you're sure you don't need them. +\#. if !'\\n[.z]'FLOAT*DIV' \{\ +. if !\\n[tbl*caption-after-label] \{\ +. ie (\\n[nl]=\\n[#PAGE_TOP]):(\\n[nl]=\\n[dc]) \{\ +. RESTORE_SPACE +. ie \\n[#COLUMNS] .sp |\\n[dc]u +. el .sp |\\n[#T_MARGIN]u-\\n[#DOC_LEAD]u +. sp \\n[tbl*caption-lead-diff]u +. \} +. el \{\ +. if \\n[.ns] .if !(\\n[nl]=\\n[#PAGE_TOP]) .rs +. if !\\n[pdfbx-top] .sp \\n[#DOC_LEAD]u/2u +. \} +. if \\n[pdfbx-top] \{\ +. ps \\*[tbl*caption-size-change] +. SIZESPECS +. ps +. nr pdfbx-top 1 \" SIZESPECS trips rr-pdfbx-top +. rt +. sp \\*[gap\\n[stack]]u+\\*[wt\\n[stack]]\ ++\\n[tbl*caption-top-lead-diff]u+\\*[$CAP_HEIGHT]+.5p +. \} +. \} +\#. \} +. nh +. \} +. \} +. el \{\ +. if !\\n[tbl*autolabel] \{\ +. ie !\\n[tbl*have-label] \ +. mla@error caption label \\n[.F] \\$0 \\n[.c] +. el .ev label +. \} +. \} +. ie \\n[#PRINT_STYLE]=1 .nr tmp-ind 2m +. el .nr tmp-ind 1.25m +. ie \\n[#PRINT_STYLE]=1 .TYPEWRITER +. el \{\ +. if !\\n[#MLA] \{\ +. tbl*caption-style +. nr lead-current \\n[.v] +. \} +. \} +. ie !\\n[#MLA] \{\ +. ie !\\n[tbl*caption-after-label] \{\ +. di tbl*caption-div +. ie \\n[tbl*center] \!.in -\\n[ind-pre-tbl]u +. el \!.in 0 +. TBL*SET_CAPTION_QUAD \\*[tbl*caption-quad] +. nop \\*[tbl*caption] +. br +. di +. evc 0 +. if !'\\n[.z]'FLOAT*DIV' \{\ +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u+\\n[#DOC_LEAD]u +. ch FN_OVERFLOW_TRAP -\\n[#FN_OVERFLOW_TRAP_POS]u+\\n[#DOC_LEAD]u +. nr caption-needs 2 +. ie \\n[tbl*boxed] .nr tbl*lead \\n[.v]+3n +. el .nr tbl*lead \\n[.v] +. if \ +(\\n[dn]+(\\n[tbl*lead]*(\\n[tbl*needs]+1)))>=\\n[.t] \{\ +. nr pgnum \\n%+\\n[#PAGE_NUM_ADJ] +. if \\n[#COLUMNS]=1 .ds col-num ", column \\n[#COL_NUM] +. tm1 \ +"[mom]: Table with caption at line \\n[.c] \ +does not fit on page \\n[pgnum]\\*[col-num]. +. tm1 \ +" Shifting table to next page or column. +. ie (\\n[#COLUMNS]=1)&(\\n[#COL_NUM]=\\n[#NUM_COLS]) \{\ +. rr tbl*no-header +. NEWPAGE +. \} +. el \{\ +. nr tbl*no-top-hook -1 +. sp \\n[.t]u +. ie \\n[#COLUMNS] \ +. sp |\\n[dc]u+\\n[tbl*caption-lead-diff]u +. el .sp |\\n[#PAGE_TOP]u+\\n[tbl*caption-lead-diff]u +. \} +. \} +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u +. ch FN_OVERFLOW_TRAP -\\n[#FN_OVERFLOW_TRAP_POS]u +. \} +. if \\n[.u] .nr fill 1 +. nf +. if \\n[.ns] .RESTORE_SPACE +. tbl*caption-div +. if \\n[#PRINT_STYLE]=1 .sp .5v +. if !'\\*[tbl*caption-space]'' \ +. sp \\*[tbl*caption-space] +. if \\n[tbl*caption-lead-diff-adj] \{\ +. sp -\\n[tbl*caption-lead-diff]u +. rr tbl*caption-lead-diff-adj +. \} +. if \\n[fill-pre-float] .fi +. \} +. el \{\ +. if (\\n[tbl*have-label]=0) \{\ +. if !\\n[tbl*autolabel] \{\ +. tm1 "[mom]: CAPTION_AFTER_LABEL enabled, but no label given +. tm1 " for table at line \\n[.c]. +. tm1 " Skipping caption but continuing to process. +. \} +. \} +. \} +. \} +. el \{\ +. if (\\n[tbl*have-label]=1):(\\n[tbl*autolabel]=1) \{\ +. ie !\\n[tbl*have-caption] \ +. mla@error label caption \\n[.F] \\$0 \\n[.c] +. el \{\ +. ie !'\\n[.z]'FLOAT*DIV' \{\ +. ie (\\n[nl]=\\n[#PAGE_TOP]):(\\n[nl]=\\n[dc]) \{\ +. ie !\\n[#COLUMNS] \ +. sp |\\n[#PAGE_TOP]u+\\n[tbl*caption-lead-diff]u +. el .sp |\\n[dc]u+\\n[tbl*caption-lead-diff]u +. \} +. el .sp .5v +. \} +. el .sp .5v +. \} +. ev label +. evc \\*[ev-current] +. nh +. ie \\n[#PRINT_STYLE]=1 .TYPEWRITER +. el \{\ +. tbl*label-style +. vs \\n[.ps]u+\\n[tbl*label-autolead]u +. nr tbl*label-lead-diff \\n[lead-pre-tbl]-\\n[.v] +. \} +. if \\n[tbl*label-with-chapter] \ +. ds chapno \\n[#CH_NUM]. +. if r pdfbx-top \ +. if \\n[#MLA] .nr pdfbx-mla-tbl-top 1 +. TBL*SET_LABEL_QUAD \\*[tbl*label-quad] +. if \\n[pdfbx-mla-tbl-top] \{\ +. sp +. sp \\n[tbl*label-lead-diff]u +. rr pdfbx-mla-tbl-top +. \} +. di tbl*mla-label-caption +\!. in 0 +. ie \\n[tbl*autolabel] \{\ +. ds label \ +\\*[tbl*label-prfx]\\*[chapno]\\n[tbl*label-num]\\*[tbl*label-sffx]\" +. nop \\*[label] +. nr tbl*label-width \w'\\*[label]' +. rr label +. \} +. el \{\ +. if !'\\*[tbl*label]'' \{\ +. nop \\*[tbl*label] +. nr tbl*label-width \w'\\*[tbl*label]' +. \} +. \} +. if \\n[tbl*autolabel] \ +. ds tbl*label \\*[chapno]\\n[tbl*label-num] +. br +. di +. \} +. da tbl*mla-label-caption +. ie \\n[#PRINT_STYLE]=1 .TYPEWRITER +. el .tbl*caption-style +. if '\\*[tbl*caption-quad]'L' \{\ +. EOL +. ie \\n[float*tbl] \{\ +. ie \\n[tbl*center] \ +. ll \\n[ll-pre-tbl]u-\\n[TW]u/2u+\\n[TW]u-\\n[tmp-ind]u +. el \ +. ll \\n[TW]u+\\n[.i]u-\\n[tmp-ind]u +\!. in \\n[tmp-ind]u +. ti -\\n[tmp-ind]u +. \} +. el \{\ +. ie \\n[tbl*center] \{\ +. if '\\*[tbl*label-quad]'L' \{\ +. ll \\n[ll-pre-tbl]u-\\n[TW]u/2u+\\n[TW]u +\!. in \\n[tmp-ind]u +. \} +. \} +. el \ +. in \\n[tmp-ind]u+\\n[ind-pre-tbl]u +. \} +. ti -\\n[tmp-ind]u +. \} +. nop \\*[tbl*caption] +. br +\!. in +. da +. if !'\\n[.z]'FLOAT*DIV' \{\ +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u+\\n[#DOC_LEAD]u +. ch FN_OVERFLOW_TRAP -\\n[#FN_OVERFLOW_TRAP_POS]u+\\n[#DOC_LEAD]u +. ie \\n[#MLA] .nr caption-needs 3 +. el .nr caption-needs 2 +. if \ +(\\n[dn]+(\\n[#DOC_LEAD]*\\n[tbl*needs])+(\\n[caption-needs]*\\n[caption-lead]))>\\n[.t] \{\ +. nr pgnum \\n%+\\n[#PAGE_NUM_ADJ] +. if \\n[#COLUMNS] .ds col-num ", column \\n[#COL_NUM] +. tm1 \ +"[mom]: Table with caption at line \\n[.c] \ +does not fit on page \\n[pgnum]\\*[col-num]. +. tm1 \ +" Shifting table to next column or page. +. ie (\\n[#COLUMNS]=1)&(\\n[#COL_NUM]=\\n[#NUM_COLS]) \{\ +. rr tbl*no-header +. if \\n[defer] .nr skip-th-warning 1 +. NEWPAGE +. \} +. el \{\ +. nr tbl*no-top-hook 1 +. sp \\n[.t]u +. if (\\n[tbl*caption-after-label]=1):(\\n[tbl*plain]=1) \ +. sp 1n-.3n +. \} +. \} +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u +. ch FN_OVERFLOW_TRAP -\\n[#FN_OVERFLOW_TRAP_POS]u +. \} +. nf +. if (\\n[nl]=\\n[#PAGE_TOP]):(\\n[nl]=\\n[dc]) \ +. nr tbl*label-lead-diff-adj 1 +. ie (\\n[.t]>1)&(\\n[@TOP]=0) \{\ +. if !\\n[#NO_FLEX] \{\ +. NO_FLEX +. nr #RESTORE_FLEX 1 +. \} +. if \\n[.ns] .rs +. sp \\n[tbl*label-lead-diff]u +. \} +. el \{\ +. if \\n[.t]=1 .sp \\n[.t]u +. ie \\n[#COL_NUM]>1 \ +. ie (\\n[nl]=\\n[#PAGE_TOP]):(\\n[nl]=\\n[dc]) \ +. sp |\\n[dc]u+\\n[tbl*label-lead-diff]u +. el .sp .5v +. \} +. tbl*mla-label-caption +. \} +. ie \\n[#PRINT_STYLE]=1 .sp .5v +. el .sp .5n +. if \\n[tbl*label-lead-diff-adj] \{\ +. sp -\\n[tbl*label-lead-diff]u +. rr tbl*label-lead-diff-adj +. \} +. br +. if !'\\*[tbl*caption-space]'' .sp \\*[tbl*caption-space] +. ie \\n[float*tbl] .ev FLOAT +. el .ev \\*[ev-current] +.END +\# +.MAC TBL*CLEANUP END +. if !'\\n[.z]'FLOAT*DIV' \{\ +. rm tbl*header-div +. rm short +. rm tbl*caption +. rm tbl*caption-short +. rm tbl*label +. rr tbl*center +. rr tbl*caption-top-lead-diff +. rr tbl*have-header +. rr tbl*no-print-header +. rr tbl*have-caption +. rr tbl*have-label +. rr tbl*plain-boxed +. rr tbl*boxed +. \} +. rr doing-tbl +. rm tbl*space-adj +. rr tbl*skip-label +. rr tbl*skip-source +. rr tbl*label-warning +. rr tbl*no-shim +. rr tbl*no-flex +. rr tbl*plain +. rr tbl*caption-top-lead-diff +. rnn tbl*have-label tbl@label +. rnn tbl*have-source tbl@source +. if '\\*[tbl*label-sffx-tmp]'.' .ds tbl*label-sffx . +. if \\n[#RESTORE_INDENT_BOTH] \{\ +. IB +. rr #RESTORE_INDENT_BOTH +. \} +. if \\n[#RESTORE_INDENT_LEFT] \{\ +. IL +. rr #RESTORE_INDENT_LEFT +. \} +. if \\n[#RESTORE_FLEX] \{\ +. NO_FLEX off +. rr #RESTORE_FLEX +. \} +.END +\# +.MAC print-label END +. if \\n[.u] .nr fill 1 +. nf +. if \\n[tbl*center] \{\ +. if '\\n[.z]'' \{\ +. ll \\n[.l]u-\\n[TW]u/2u+\\n[TW]u +. if \\n[ind-pre-tbl] \ +. in \\n[ind-pre-tbl]u-(\\n[ind-pre-tbl]u/2u) +. \} +. \} +. if !\\n[tbl*skip-label] \ +. tbl*label-div +. if \\n[tbl*center] \{\ +. if '\\n[.z]'' \{\ +. ll +. in 0 +. \} +. \} +. if \\n[fill] .fi +. rr fill +.END +\# +.MAC tbl@top-hook END +. if (\\n[tbl*have-header:1]=1):(\\n[tbl*have-header]=1) \{\ +. if !r tbl*no-print-header \{\ +. nf +. rr @TOP +. ch RR_@TOP +. ev top-hook +. evc 0 +. rs +. nop \& +. ie !\\n[tbl*boxed] .sp -1 +. el .sp -1n +. tbl*print-header +. ev +. \} +. \} +.END +\# +.MAC tbl*print-header END +. if \\n[.u]=1 \{\ +. nf +. nr fill 1 +. \} +. if \\n[#COL_NUM]>1 \ +. if !\\n[tbl*have-caption] \ +. if (\\n[@TOP]=1):(\\n[nl]=\\n[dc]) \ +. sp .3n +. if \\n[tbl*center] \!.in \\n[ind-pre-tbl]u/2u +. ie d tbl*header-div:span .tbl*header-div:span +. el .tbl*header-div +. if '\\n[.z]'FLOAT*DIV' \ +. if \\n[tbl*center] .ce 1000 +. mk #T +.END +\# +.MAC tbl@bottom-hook END +. rr #DIVERTED +. rr @TOP +. ch RR_@TOP +.END +\# +.MAC tbl*float-warning END +. tm1 "[mom]: Table in FLOAT, output page \\n[#PAGENUMBER], exceeds page vertical limits. +. tm1 " Multipage boxed tables cannot be contained within floats. +. ab [mom]: Aborting '\\n[.F]', approx. line \\n[.c]. +.END +\# +.MAC tbl*caption-warning END +. tm1 "[mom]: TS at line \\n[.c] has CAPTION but no H argument. +. tm1 " CAPTION requires H with a corresponding .TH. +. ab [mom]: Aborting '\\n[.F]'. +.END +\# +.MAC tbl*source-warning END +. tm1 "[mom]: MLA enabled, but TE at line \\n[.c] has no SOURCE. +. tm1 " MLA style for tables requires that a source be cited. +. ab [mom]: Aborting '\\n[.F]'. +.END +\# +.MAC ds@need END \" Move vertically until there is enough space for \$1 +. if '\\n(.z'' \{\ +. while \\n[.t]<=(\\$1)&(\\n[nl]>\\n[#PAGE_TOP]) \{\ +. rs +' sp \\n[.t]u +. \} +. \} +.END +\# +\# ***eqn*** +\# +\# EQ/EN macros borrowed from ms, mommified by Robin Haberkorn +\# <robin.haberkorn@googlemail.com>, expanded by Peter Schaffter. +\# +\# EQ [ -L | -C | -I <indent> ] [label] +\# EN [ CONT | CONTINUED | ... ] +\# +\# Equations are centered by default, but can be left-justified +\# (EQ -L), explicitly centered, or indented (EQ -I). +\# +\# Each eqn block for multi-line equations aligned with 'mark' and +\# 'lineup' should be terminated by passing 'CONT' or 'CONTINUED' +\# or '...' to EN. +\# +\# Note that geqn mark and lineup work correctly in centered equations. +\# +.MAC EQ END +. if \\n[eqn*copy-in]=1 \{\ +. if !\\n[eqn-linenum] .nr eqn-linenum \\n[.c] +. if !\\n[pgnum] .nr pgnum \\n%+\\n[#PAGE_NUM_ADJ] +. br +. if \\n[.u] .nr fill 1 +. rr float*eqn +. if '\\n[.z]'FLOAT*DIV' .nr float*eqn 1 +. nr eqn*restore-adj \\n[.j] +. na +. if !\\n[continued] \{\ +. PDF_TARGET eqn:\\n+[lists*target] +. rr eqn*type +. nr loop-counter \\n[#NUM_ARGS] +. nr loop-count 0 1 +. while \\n+[loop-count]<=\\n[loop-counter] \{\ +. if '\\$1'-L' \{\ +. nr eqn*left 1 +. nr eqn*type 1 +. shift +. \} +. if '\\$1'-I' \{\ +. nr eqn*ind 1 +. nr eqn*type 2 +. shift +. ds DI \\$1 +. ds DI@cont \\*[DI] +. shift +. \} +. if '\\$1'-C' \{\ +. nr eqn*center 1 +. nr eqn*type 3 +. shift +. \} +. if '\\$1'ADJUST' \{\ +. ds eqn*space-adj \\$2 +. shift 2 +. \} +. if '\\$1'LABEL' \{\ +. ds eqn*label \\$2 +. shift 2 +. \} +. if '\\$1'SHIFT_LABEL' \{\ +. ds eqn*shift-label \\$2 +. shift 2 +. \} +. if '\\$1'CAPTION' \{\ +. ds eqn*caption \\$2 +. shift 2 +. \} +. if '\\$1'SHORT_CAPTION' \{\ +. ds eqn*caption-short \\$2 +. shift 2 +. \} +. if '\\$1'TARGET' \{\ +. ds target "\\$2 +. PDF_TARGET "\\*[target] +. shift 2 +. \} +. if '\\$1'NO_SHIM' \{\ +. nr @no-shim 1 +. shift 1 +. \} +. if '\\$1'NO_FLEX' \{\ +. nr eqn*no-flex +. shift +. \} +. \} +. \} +. if (\\n[eqn*have-label]=1):(\\n[eqn*autolabel]=1) \ +. ds label-type eqn +. if '\\*[eqn*shift-label]'' .ds eqn*shift-label 0 +. if !\\n[eqn*type] \{\ +. nr eqn*center 1 +. nr eqn*type 3 +. shift +. \} +. if !'\\*[eqn*caption]'' \{\ +. if '\\*[caption-quad]'L' \{\ +. if \\n[default-left] .ds caption-quad R +. rr default-left +. \} +. \} +. if !\\n[continued] \{\ +. if !'\\*[eqn*caption-short]'' .ds short -short +. if \\n[eqn*autolabel] \{\ +. if \\n[eqn*label-with-chapter] \ +. ds chapno \\n[#CH_NUM]. +. ds eqn*label \\*[chapno]\\n+[eqn*label-num] +. nr eqn*label-width \w'\\*[eqn*label]' +. if dLABEL.REFS \ +. tm .ds \\*[target] \\*[chapno]\\n[eqn*label-num] +. rm target +. nr eqn*label-num -1 +. \} +. ie !'\\n[.z]'' \{\ +. if (\\n[float*img]=0)&(\\n[float*pic]=0)&(\\n[float*tbl]=0) \{\ +\!. PDF_TARGET eqn:\\\\n+[lists*target] +. ie !'\\*[eqn*label]'' \ +\!. TO_EQUATIONS "\\*[eqn*label]" "\\*[eqn*caption\\*[short]]" +. el \ +\!. TO_EQUATIONS "\\*[eqn*caption\\*[short]]" +. \} +. \} +. el \{\ +. PDF_TARGET eqn:\\n+[lists*target] +. ie !'\\*[eqn*label]'' \ +. TO_EQUATIONS "\\*[eqn*label]" "\\*[eqn*caption\\*[short]]" +. el \ +. TO_EQUATIONS "\\*[eqn*caption\\*[short]]" +. \} +. \} +. if \\n[continued] \{\ +. rm continued +. rr continued +. \} +. if \\n[eqn@left*cont] .nr eqn*type 1 +. if \\n[eqn@ind*cont] \{\ +. nr eqn*type 2 +. ds DI \\*[DI@cont] +. \} +. \} +. if \\n[eqn@center*cont] .nr eqn*type 3 +. ev EQN +. evc 0 +. di eqn*div +. in 0 +. nf +.END +\# +.MAC EN END +. if !'\\n[.z]'eqn*div' \{\ +. @error mismatched EN +. return +. \} +. br +. di +. ev +. if !'\\*[eqn*label]'' .nr eqn*have-label 1 +. if !'\\*[eqn*caption]'' .nr eqn*have-caption 1 +. if !'\\$1'' \{\ +. ie '\\$1'...' .ds continued CONT +. el .ds continued \\$1 +. substring continued 0 3 +. ie '\\*[continued]'CONT' \{\ +. nr continued 1 +. rm continued +. if \\n[eqn*ind] .nr eqn@ind*cont 1 +. if \\n[eqn*left] .nr eqn@left*cont 1 +. if \\n[eqn*center] .nr eqn@center*cont 1 +. \} +. el \{\ +. tm1 "[mom]: Invalid argument \\$1 to \\$0. +. tm1 " Must be 'CONTINUED', 'CONT', or '...' +. ab [mom]: Aborting '\\n[.F]' at line \\n[.c]. +. \} +. \} +. if \\n[dl]:\\n[eqn*have-label] \{\ +. ds eqn*tabs \\n[.tabs] +. ie \\n[dl] \{\ +. if !'\\n[.z]'FLOAT*DIV' \{\ +. ie \\n[eqn*have-caption] .ne \\n[dn]u-\\n[.V] +. el .ne \\n[dn]u-1v-\\n[.V] +. \} +. chop eqn*div +. if '\\*[DD]'' \{\ +. ds DD .5v +. if !\\n[@TOP] \{\ +. ie r pdfbx-top \{\ +. SIZESPECS +. rt +. sp (\\*[wt\\n[stack]]/2u)+\\*[gap\\n[stack]]u+\\*[$CAP_HEIGHT] +. \} +. el .sp \\*[DD] +. if !'\\*[eqn*space-adj]'' .sp \\*[eqn*space-adj]u +. \} +. \} +. ie \\n[eqn*type]=1 \{\ +. ta (u;\\n[.l]-\\n[.i])R +. ie \\n[continued] .nop \\*[eqn*div] +. el \{\ +. ie \\n[eqn*autolabel] \ +.nop \ +\\*[eqn*div]\ +\\*[eqn*label-specs]\ +\t\v'+\\*[eqn*shift-label]'\ +\\*[eqn*label-prfx]\\*[chapno]\\n+[eqn*label-num]\\*[eqn*label-sffx]\ +\v'-\\*[eqn*shift-label]'\ +\\*[revert-specs] +. el \ +.nop \ +\\*[eqn*div]\ +\\*[eqn*label-specs]\ +\t\v'+\\*[eqn*shift-label]'\ +\\*[eqn*label]\ +\v'-\\*[eqn*shift-label]'\ +\\*[revert-specs] +. \} +. if !\\n[continued] \{\ +. if \\n[eqn*have-caption] \ +. ADD_CAPTION +. \} +. \} +. el \{\ +. ie \\n[eqn*type]=2 \{\ +. ie '\\*[eqn*label-quad]'L' \{\ +. ta \\*[DI] +. ie \\n[continued] .nop \t\\*[eqn*div] +. el \{\ +. ie \\n[eqn*autolabel] \ +.nop \ +\\*[eqn*label-specs]\ +\v'+\\*[eqn*shift-label]'\ +\\*[eqn*label-prfx]\\*[chapno]\\n+[eqn*label-num]\\*[eqn*label-sffx]\ +\v'-\\*[eqn*shift-label]'\ +\t\\*[eqn*div]\ +\\*[revert-specs] +. el \ +.nop \ +\\*[eqn*label-specs]\ +\v'+\\*[eqn*shift-label]'\ +\\*[eqn*label]\ +\v'-\\*[eqn*shift-label]'\ +\\*[revert-specs]\ +\t\\*[eqn*div] +. \} +. \} +. el \{\ +. ta \\*[DI] (u;\\n[.l]-\\n[.i])R +. ie \\n[continued] .nop \t\\*[eqn*div] +. el \{\ +. ie \\n[eqn*autolabel] \ +.nop \ +\t\\*[eqn*div]\ +\\*[eqn*label-specs]\ +\t\v'+\\*[eqn*shift-label]'\ +\\*[eqn*label-prfx]\\*[chapno]\\n+[eqn*label-num]\\*[eqn*label-sffx]\ +\v'-\\*[eqn*shift-label]'\ +\\*[revert-specs] +. el \ +.nop \ +\t\\*[eqn*div]\ +\\*[eqn*label-specs]\ +\t\v'+\\*[eqn*shift-label]'\ +\\*[eqn*label]\ +\v'-\\*[eqn*shift-label]'\ +\\*[revert-specs] +. \} +. \} +. if !\\n[continued] \{\ +. if \\n[eqn*have-caption] \ +. ADD_CAPTION +. \} +. \} +. el \{\ +. ie '\\*[eqn*label-quad]'L' \{\ +. ta (u;\\n[.l]-\\n[.i]/2)C +. ie \\n[continued] .nop \t\\*[eqn*div] +. el \{\ +. ie \\n[eqn*autolabel] \ +.nop \ +\\*[eqn*label-specs]\ +\v'+\\*[eqn*shift-label]'\ +\\*[eqn*label-prfx]\\*[chapno]\\n+[eqn*label-num]\\*[eqn*label-sffx]\ +\v'-\\*[eqn*shift-label]'\ +\t\\*[eqn*div]\ +\\*[revert-specs] +. el \ +.nop \ +\\*[eqn*label-specs]\ +\v'+\\*[eqn*shift-label]'\ +\\*[eqn*label]\ +\v'-\\*[eqn*shift-label]'\ +\\*[revert-specs]\ +\t\\*[eqn*div] +. \} +. \} +. el \{\ +. ta (u;\\n[.l]-\\n[.i]/2)C (u;\\n[.l]-\\n[.i])R +. ie \\n[continued] .nop \t\\*[eqn*div] +. el \{\ +. ie \\n[eqn*autolabel] \ +.nop \ +\t\\*[eqn*div]\ +\\*[eqn*label-specs]\ +\t\v'+\\*[eqn*shift-label]'\ +\\*[eqn*label-prfx]\\*[chapno]\\n+[eqn*label-num]\\*[eqn*label-sffx]\ +\v'-\\*[eqn*shift-label]'\ +\\*[revert-specs] +. el \ +.nop \ +\t\\*[eqn*div]\ +\\*[eqn*label-specs]\ +\t\v'+\\*[eqn*shift-label]'\ +\\*[eqn*label]\ +\v'-\\*[eqn*shift-label]'\ +\\*[revert-specs] +. \} +. \} +. if !\\n[continued] \{\ +. if \\n[eqn*have-caption] \ +. ADD_CAPTION +. \} +. \} +. \} +. \} +. el \{\ +. ta (u;\\n[.l]-\\n[.i])R +.nop \ +\\*[eqn*label-specs]\ +\t\v'+\\*[eqn*shift-label]'\ +\t\\*[eqn*label]\ +\v'-\\*[eqn*shift-label]'\ +\\*[revert-specs] +. \} +. ta \\*[eqn*tabs] +.\" if continuing (ie is a multi-line equation), don't space and SHIM +. if !\\n[continued] \{\ +. br +. if !\\n[@TOP] \{\ +. if !\\n[.t]<(\\*[DD]+1) \{\ +. sp \\*[DD] +. ie !\\n[eqn*have-caption] \{\ +. sp .25v +. if \\n[pdfbx-running] .nr eqn*pdfbx 1 +. \} +. el .if \\n[pdfbx-running] .nr eqn*pdfbx 2 +. \} +. \} +. if !'\\*[eqn*space-adj]'' .sp -\\*[eqn*space-adj]u +. ie !\\n[eqn*no-shim] \{\ +. ie !\\n[#NO_SHIM] \ +. if !'\\n[.z]'FLOAT*DIV' .SHIM +. el \ +. if !\\n[eqn*no-flex] \ +. if !\\n[#NO_FLEX] \ +. if !'\\n[.z]'FLOAT*DIV' .FLEX +. \} +. el \ +. if !\\n[eqn*no-flex] \ +. if !\\n[#NO_FLEX] \ +. if !'\\n[.z]'FLOAT*DIV' .FLEX +. rm DD +. rm eqn*caption +. rm eqn*caption-short +. rm eqn*label +. rm short +. rr eqn*copy-in +. \} +. rm DI@cont +. rr eqn*center +. rr eqn@center*cont +. rr eqn*have-label +. rr eqn*have-caption +. rr eqn*ind +. rr eqn@ind*cont +. rr eqn*left +. rr eqn@left*cont +. \} +. nr eqn*copy-in 1 +. ad \\n[eqn*restore-adj] +. if \\n[fill] .fi +. rr fill +.END +\# +.MAC ADD_CAPTION END +. ie \\n[.t]<\\n[.v] \{\ +. if !'\\n[.z]'FLOAT*DIV' \{\ +. if \\n[#COLUMNS]=1 .ds col-num ", column \\n[#COL_NUM] +. tm1 "[mom]: '\\n[.F]', macro EQ, line \\n[eqn-linenum]: +. tm1 " Insufficient room for equation caption on page \\n[pgnum]\\*[col-num]. +. tm1 " Skipping caption but continuing to process. +. if !\\n[@TOP] \{\ +. ie \\n[#COLUMNS] \ +. COL_NEXT internal +. el .NEWPAGE +. \} +. rr eqn-linenum +. rr pgnum +. \} +. \} +. el \{\ +. if \\n[#PRINT_STYLE]=2 \{\ +. ps \\*[eqn*caption-size-change] +. nr lead-curr \\n[.v] +. sp .5v +. vs \\n[.ps]u+\\n[eqn*caption-autolead]u +. nr eqn*caption-lead-diff \\n[lead-curr]-\\n[.v] +. sp \\n[eqn*caption-lead-diff]u +. ps +. if !'\\*[eqn*caption-space]'' \ +. sp \\*[eqn*caption-space] +. \} +. if '\\*[eqn*caption-quad]'L' \{\ +. fi +. ad l +. nop \ +\\*[eqn*caption-specs]\ +\\*[eqn*caption]\ +\\*[revert-specs] +. nf +. \} +. if '\\*[eqn*caption-quad]'C' \{\ +. fi +. ad c +. nop \ +\\*[eqn*caption-specs]\ +\\*[eqn*caption]\ +\\*[revert-specs] +. nf +. \} +. if '\\*[eqn*caption-quad]'R' \{\ +. fi +. ad r +. nop \ +\\*[eqn*caption-specs]\ +\\*[eqn*caption]\ +\\*[revert-specs] +. nf +. \} +. if !'\\*[eqn*caption-space]'' \ +. sp -\\*[eqn*caption-space] +. vs +. \} +.END +\# +\# ***pic*** +\# +.MAC have-adjust END +. nr #ARGS 0 1 +. nr #COUNT \\n[#NUM_ARGS] +. while \\n+[#ARGS]<=\\n[#COUNT] \{\ +. if '\\$1'ADJUST' \{\ +. ds pic*space-adj \\$2 +. break +. \} +. shift +. \} +.END +\# +\# User settable text style for pic +\# +\# PIC_TEXT_STYLE +\# -------------- +\# *Argument: +\# <offset from page left> +\# *Function: +\# Stores user supplied page offset in register #L_MARGIN. +\# Sets .po to user supplied offset. +\# *Notes: +\# Requires unit of measure. +\# +.MAC PIC_TEXT_STYLE END +. nr #ARGS 0 1 +. nr #COUNT \\n[#NUM_ARGS] +. while \\n+[#ARGS]<=\\n[#COUNT] \{\ +. if '\\$1'FAMILY' \{\ +. shift +. ds pic*text-family \\$1 +. shift +. \} +. if '\\$1'FONT' \{\ +. shift +. ds pic*text-font \\$1 +. shift +. \} +. if '\\$1'SIZE' \{\ +. shift +. ds pic*text-size-change \\$1 +. shift +. \} +. if '\\$1'AUTOLEAD' \{\ +. shift +. nr pic*text-autolead \\$1 +. shift +. \} +. \} +.END +\# +\# Main macros +\# +.MAC PS END +. if \\n[pdfbx-running] \{\ +. ie !r pdfbx-top .nr pic*pdfbx 2 +. el .nr pic*pdfbx 1 +. \} +. if !\\n[#PP] .nop +. br +. have-adjust \\$@ \" Adjusting is handled by FLOAT +. if !'\\n[.z]'FLOAT*DIV' \ +. FLOAT ADJUST \\*[pic*space-adj] +. PDF_TARGET fig:\\n+[lists*target] +. ds ev-current \\n[.ev] +. rr float*pic +. rr pic*have-label +. rr grap +. nr float*pic 1 +. nr ind-pre-pic \\n[.i] +. nr lead-pre-pic \\n[.v] +. if \\n[#MLA] \ +. if !\\n[pdfbx-running] .sp .5v +. in 0 +. ev PIC +. evc \\n[ev-current] +. nf +. ie \\n[#NUM_ARGS]<2 .@error bad arguments to PS (not preprocessed with pic?) +. el \{\ +. if \B'\\$1' \{\ +. ie !\B'\\$2' .ds pic*scale-width \\$1 +. el .ds pic*scale-width \\$2 +. \} +. \} +.\" This is a bit confusing. pic is decorated with 2 args (width +.\" and height), which are read during pre-processing but have to be +.\" ignored when parsing args during main processing. We shift pic's +.\" args out of the way, then pop them off the arg stack because +.\" they're not needed during macro processing. +. while \B'\\$1' .shift +. nr loop-counter \\n[#NUM_ARGS] +. nr loop-count 0 1 +. while \\n+[loop-count]<=\\n[loop-counter] \{\ +. if '\\$1'LEFT' \{\ +. nr pic*left 1 +. shift 1 +. \} +. if '\\$1'CAPTION' \{\ +. nr pic*have-caption 1 +. ds pic*caption \\$2 +. shift 2 +. \} +. if '\\$1'SHORT_CAPTION' \{\ +. ds pic*caption-short \\$2 +. shift 2 +. \} +. if '\\$1'LABEL' \{\ +. nr pic*have-label 1 +. ds pic*label \\$2 +. shift 2 +. \} +. if '\\$1'TARGET' \{\ +. ds target "\\$2 +. PDF_TARGET "\\*[target] +. shift 2 +. \} +. if '\\$1'NO_SHIM' \{\ +. nr @no-shim 1 +. shift 1 +. \} +. if '\\$1'NO_FLEX' \{\ +. nr @no-flex 1 +. shift 1 +. \} +. if '\\$1'GRAP' \{\ +. nr grap 1 +. shift 1 +. \} +. \} +. if (\\n[pic*have-label]=1):(\\n[pic*autolabel]=1) \ +. ds label-type pic +. ds pic*label-sffx-tmp \\*[pic*label-sffx] +. if !'\\*[pic*label-sffx-tmp]'' \ +. substring pic*label-sffx-tmp -1 +. if '\\*[pic*label-sffx-tmp]'.' \ +. if \\n[pic*caption-after-label]=0 .chop pic*label-sffx +. if \\n[#MLA] \{\ +. if (\\n[pic*have-label]=1):(\\n[pic*autolabel]=1) \{\ +. if !\\n[pic*have-caption] \ +. mla@error label caption \\n[.F] \\$0 \\n[.c] +. \} +. if \\n[pic*have-caption] \{\ +. if !\\n[pic*have-label] \{\ +. if !\\n[pic*autolabel] \ +. mla@error caption label \\n[.F] \\$0 \\n[.c] +. \} +. \} +. \} +. if !'\\*[pic*text-family]'' \ +. fam \\*[pic*text-family] +. if !'\\*[pic*text-font]'' \ +. ft \\*[pic*text-font] +. if !'\\*[pic*text-size-change]'' \ +. ps \\n[#DOC_PT_SIZE]u\\*[pic*text-size-change] +. nr lead-current \\n[.v] +. ie \\n[pic*text-autolead] \ +. vs \\n[.ps]u+(\\n[pic*text-autolead]u*1000u) +. el .vs \\n[.ps]u +. nr pic@text-lead \\n[.v] +. nr pic@text-size \\n[.ps] +. if !'\\*[pic*text-color]'' .COLOR \\*[pic*text-color] +. if \\n[@TOP] \{\ +. RESTORE_SPACE +. nr pic*top-lead-adj 1 +. \} +. nr pic*top-lead-diff \\n[lead-pre-pic]u-\\n[.v]u +. if (\\n[pic*have-caption]=0):(\\n[pic*caption-after-label]=1) \{\ +. ie \\n[pic*top-lead-adj] \{\ +. sp \\n[pic*top-lead-diff]u +. rr pic*top-lead-adj +. \} +. el .if (\\n[pic*caption-after-label]=0):(\\n[#MLA]=0) \ +. sp \\n[lead-pre-pic]u/2u +. \} +. if \\n[pic*label-with-chapter] \ +. ds chapno \\n[#CH_NUM]. +. if \\n[pic*autolabel] \ +. ds pic*label \\*[pic*label-prfx]\\*[chapno]\\n+[fig*label-num]\\*[pic*label-sffx] +. nr fig*label-width \w'\\*[pic*label]' +. if !'\\*[pic*caption-short]'' .ds short -short +. if \\n[#PDF_BOOKMARKS] \{\ +. ie !'\\*[pic*label]'' \ +\!. TO_FIGURES "\\*[pic*label]" "\\*[pic*caption\\*[short]]" +. el \ +\!. TO_FIGURES "\\*[pic*caption\\*[short]]" +. \} +. di pic*div +.END +\# +.MAC PE END +. di +. nr pic*div-width \\n[dl] +. if \\n[@TOP] \ +. RESTORE_SPACE +. if !\\n[nl]=\\n[#PAGE_TOP] .sp \\n[lead-pre-pic]u/2u +. if (\\n[pic*have-caption]=1)&(\\n[pic*caption-after-label]=0) \{\ +. ev caption +. evc \\*[ev-current] +. nh +. ie \\n[#PRINT_STYLE]=1 .TYPEWRITER +. el \{\ +. if \\n[.u] \{\ +. nr fill 1 +. nf +. \} +. pic*caption-style +. if \\n[fill] .fi +. rr fill +. nr lead-current \\n[.v] +. vs \\n[.ps]u+\\n[pic*caption-autolead]u +. nr pic*caption-lead-diff \\n[lead-current]-\\n[.v] +. in \\n[ind-pre-pic]u +. \} +. PIC*SET_CAPTION_QUAD \\*[pic*caption-quad] +. if \\n[@TOP] .RESTORE_SPACE +\!. in -\\n[ind-pre-pic]u +. sp \\n[pic*caption-lead-diff]u +\!. if \\\\n[.ns] .rs +. if \\n[pic*pdfbx]=1 \{\ +. SIZESPECS +. if \\n[PIC]=1 \!.rt +. if \\n[PIC]=2 .rt +. sp \\n[pic*caption-lead-diff]u +. sp \\*[wt\\n[stack]]+\\*[gap\\n[stack]]u+\\*[$CAP_HEIGHT] +. nr pic*pdfbx 2 +. \} +. nop \\*[pic*caption] +. if \\n[#PRINT_STYLE]=1 .sp .5 +. if !'\\*[pic*caption-space]'' \ +. sp \\*[pic*caption-space]-\\n[pic*text-autolead]p +. br +. ev +. \} +. if \\n[pic*pdfbx]=1 \{\ +. if (\\n[pic*have-caption]=0):(\\n[pic*caption-after-label]=1) \{\ +. if \\n[PIC]=1 \!.rt +. if \\n[PIC]=2 .rt +. sp \\n[#DOC_LEAD]u/2u +. sp \\*[wt\\n[stack]]+\\*[gap\\n[stack]]u +.\" Correct for wandering top of pic +. sp -\\n[pic*text-autolead]p +. \} +. \} +. if !\\n[pic*left] \ +. in (\\n[ll-pre-float]u-\\n[pic*div-width]u)/2u +. if \\n[grap] \ +\!. sp -2 +. if (\\n[grap]=1)&(\\n[pic*caption-after-label]=1) \ +\!. sp -2 +. if \\n[pdfbx-running] \{\ +. if \\n[pdfbx-top] \{\ +. ie !\\n[pic*left] \!.in -\\*[gap\\n[stack]]u*2u +. el .in -\\*[wt\\n[stack]] +. \} +. \} +. if (\\n[pic*pdfbx]=0):(\\n[pic*pdfbx]=2) \ +. if (\\n[pic*have-caption]=0)&(\\n[pic*caption-after-label]=0) \ +\!. sp -.5-\\n[pic*text-autolead]p +. pic*div +. br +. if (\\n[pic*have-label]=1):(\\n[pic*autolabel]=1):(\\n[pic*caption-after-label]=1) \{\ +. nr lead-pre-label \\n[.v] +. ev label +. evc \\*[ev-current] +. ie \\n[#PRINT_STYLE]=1 .TYPEWRITER +. el \{\ +. pic*label-style +. nr lead-current \\n[.v] +. vs \\n[.ps]u+\\n[pic*label-autolead]u +. in \\n[ind-pre-pic]u +. sp \\n[lead-current]u-\\n[.v]u +. \} +. PIC*SET_LABEL_QUAD \\*[pic*label-quad] +\!. in -\\n[ind-pre-pic]u +. if !'\\*[pic*label-space]'' .sp \\*[pic*label-space] +. if \\n[#PRINT_STYLE]=1 .sp .5v +. if \\n[#PRINT_STYLE]=2 \{\ +. SIZESPECS +. if !\\n[pic*pdfbx] \{\ +. ie !\\n[grap] .sp -1 +. el .sp -1.5 +. \} +. sp \\*[$CAP_HEIGHT]+.5 +. if \\n[grap] .if !\\n[pic*have-label] .sp -.5 +. \} +. ie \\n[pic*autolabel] \ +. nop \ +\\*[pic*label-prfx]\\*[chapno]\\n[fig*label-num]\\*[pic*label-sffx]\| +. el \ +. if !'\\*[pic*label]'' .nop \\*[pic*label] +. if dLABEL.REFS \{\ +. if \\n[pic*autolabel] \ +. tm .ds \\*[target] \\*[chapno]\\n[fig*label-num] +. if \\n[pic*have-label] \ +. tm .ds \\*[target] \\*[pic*label] +. \} +. rm target +. fam +. ft +. ps +. gcolor +. ie !\\n[pic*caption-after-label] .br +. el \{\ +. if !'\\*[pic*caption]'' .nop \ +\\*[pic*caption-specs]\\*[pic*caption]\\*[revert-specs] +. br +. \} +. ev +. in 0 +. \} +. if \\n[pic*pdfbx] .nr pic*pdfbx 2 +. ev +. if !\\n[pdfbx-running] \ +. sp .5 +. if \\n[pic*pdfbx]=2 .if !\\n[grap] .sp .5 +. ie \\n[pdfbx-running] \ +. if \\n[PIC]=1 .FLOAT off +. el .FLOAT off +. it 1 rr-pic*pdfbx +. in \\n[ind-pre-pic]u +. if !\\n[defer] .rr pic*have-caption +. rm pic*left +. rm short +. rr float*pic +. if '\\*[pic*label-sffx-tmp]'.' .ds pic*label-sffx . +. if \\n[pdfbx-running]=0 .rr pdfbx-running +. if r pdfbx-top .rr pdfbx-top +. if '\\*[pic*label-sffx-tmp]'.' .ds pic*label-sffx . +.END +\# +\# ***refer*** +\# +\# Footnote references +\# ------------------- +\# *Function: +\# Instruct REF to put references in footnotes. +\# +.MAC FOOTNOTE_REFS END +. ie !'\\$1'' .rr #FN_REF +. el \{\ +. if r #EN_REF .rr #EN_REF +. nr #FN_REF 1 +. \} +.END +\# +\# Endnote references +\# ------------------ +\# *Function: +\# Instruct REF to collect references for endnotes output. +\# +.MAC ENDNOTE_REFS END +. ie !'\\$1'' .rr #EN_REF +. el \{\ +. if r #FN_REF .rr #FN_REF +. nr #EN_REF 1 +. if !r#EN_MARKER_STYLE .ENDNOTE_MARKER_STYLE SUPERSCRIPT +. \} +.END +\# +\# Prepare mom for a reference +\# --------------------------- +\# *Argument: +\# <none> | INDENT L|LEFT|R|RIGHT|B|BOTH <indent value> +\# *Function: +\# Calls FOOTNOTE or ENDNOTE, depending on whether #REF_FN or +\# #REF_EN is set to 1. +\# *Notes: +\# For convenience, REF is a toggle. +\# +\# REF optionally takes the same arguments as FOOTNOTE, allowing +\# users to indent references that go in footnotes when footnote +\# indenting is required. FOOTNOTE_REFS must be on for this. +\# +.MAC REF END +. ie \\n[#FN_REF]+\\n[#EN_REF]=0 \{\ +. if !\\n[#REF_WARNING]=1 \{\ +. tm1 "[mom]: Before REF at line \\n[.c], neither FOOTNOTE_REFS nor ENDNOTE_REFS +. tm1 " has been selected. If "sort" and "accumulate" are in your refer +. tm1 " commands, references will be collected for later output with $LIST$. +. tm1 " Otherwise, they will disappear. +. nr #REF_WARNING 1 +. \} +. \} +. el \{\ +. ie \\n[#REF]=1 \{\ +. if \\n[#FN_REF]=1 .FOOTNOTE OFF +. if \\n[#EN_REF]=1 .ENDNOTE OFF +. rr #REF +. \} +. el \{\ +. rr #REF_WARNING +. nr #REF 1 +. if \\n[#FN_REF]=1 .FOOTNOTE \\$1 \\$2 \\$3 +. if \\n[#EN_REF]=1 .ENDNOTE +. \} +. \} +.END +\# +\# Embedded references in text (with brackets) +\# ------------------------------------------- +\# +.MAC REF_BRACKETS_NOTICE END +. tm1 "[mom]: \\$1 has been removed from mom. See the mom documentation 'refer.html' +. tm1 " for instructions on parenthetical insertions of references into text. +. ie '\\$1'REF_STYLE' .tm1 " Continuing to process '\\n[.F]' from line \\n[.c]. +. el .ab [mom]: Aborting '\\n[.F]' at \\$1, line \\n[.c]. +.END +\# +.MAC REF_BRACKETS_START END +. REF_BRACKETS_NOTICE \\$0 +.END +\# +.MAC REF_BRACKETS_END END +. REF_BRACKETS_NOTICE \\$0 +.END +\# +\# These four pairs of aliases used to allow users to embed +\# references in text and have them surrounded by (), [], {} or <>. +\# bracket-label should be used in the refer block instead. +\# +.ALIAS REF( REF_BRACKETS_START +.ALIAS REF) REF_BRACKETS_END +\# +.ALIAS REF[ REF_BRACKETS_START +.ALIAS REF] REF_BRACKETS_END +\# +.ALIAS REF{ REF_BRACKETS_START +.ALIAS REF} REF_BRACKETS_END +\# +.ALIAS REF< REF_BRACKETS_START +.ALIAS REF> REF_BRACKETS_END +\# +\# Refer indenting +\# --------------- +\# *Argument: +\# FOOTNOTE | ENDNOTE | BIBLIO <indent for 2nd and subsequent lines of discrete reference entries> +\# *Function: +\# Sets registers #REF_FN_INDENT, #REF_EN_INDENT or #REF_BIB_INDENT. +\# *Notes: +\# Indent value requires a unit of measure. If refs are going +\# into footnotes or endnotes, first lines get indented; if going +\# into a bibliography, second lines get indented +\# +.MAC INDENT_REFS END +. if '\\$1'FOOTNOTE' .ds $REF_FN_INDENT \\$2 +. if '\\$1'ENDNOTE' .ds $REF_EN_INDENT \\$2 +. if '\\$1'BIBLIO' .ds $REF_BIB_INDENT \\$2 +.END +\# +.ALIAS REF_INDENT INDENT_REFS +\# +\# Hyphenation of references +\# ------------------------- +\# *Argument: +\# <none> | <anything> +\# *Function: +\# Sets register #REF_HY +\# +.MAC HYPHENATE_REFS END +. ie '\\$1'' .nr #REF_HY 1 +. el \ +. if r #REF_HY .rr #REF_HY +.END +\# +\# The remainder of the definitions in this section are modified +\# versions of the definitions found in the refer module of s.tmac. +\# +.de @error +.tm [mom]: '\\n[.F]', line \\n[.c]: \\$* +.. +\# +\# Underlining unavoidably turns off sentence spacing. +\# +.de ref*restore-ss +\c +.SS \\*[$SAVED_SS_VAR] +.if '\\n[.z]'END_NOTES' \{\ +\c +\E*[PREV]\c +.\} +.. +\# The following strings define the order of entries for different +\# types of references. Each letter in the string refers to a database +\# field (A for author, T1/T2 for article and book titles, etc). +\# +.de ref*specs +.if \\n[#PRINT_STYLE]=1 \{\ +. char ' \[aq] +. char \[oq] \[aq] +.\} +.\" Internet site - type 0 +.ds ref*spec!0 i Q A m p T2 s o D c a u n +.\" Journal article - type 1 +.ds ref*spec!1 i Q A m p T2 q O J V S N D P n +.\" Book - type 2 +.ds ref*spec!2 i Q A m p T1 q b d l r E S e V O C I D P t n +.\" Article within book - type 3 +.ds ref*spec!3 i Q A m p T2 B b d l r E S e V O C I D P t n +.\" Tech report - type 4 +.ds ref*spec!4 i Q A m p T1 R G O C I D P n +.\" Magazine or newspaper article - type 5 +.ds ref*spec!5 i Q A m p T2 O M V S N D P n +.. +\# +\# Refer's "1st" macro. Since it is possible to define database +\# fields using any single letter, we remove all possible string +\# definitions of the form [X and [x. Also, reset ref*spec!<n> +\# strings to their defaults. +\# +.de ]- +.ref*specs +.rm [A [B [C [D [E [F [G [H [I [J [K [L [M \ + [N [O [P [Q [R [S [T [U [V [W [X [Y [Z \ + [a [b [c [d [e [f [g [h [i [j [k [l [m \ + [n [o [p [q [r [s [t [u [v [w [x [y [z +.if r [e .rr [e \" [e persists if %e field is last +.rr ref*type +.rm ref*string +.. +\# +\# Refer's "2nd" macro; builds up a reference with ref*build, and +\# prints it with ref*print. +\# +.de ][ +.nr ref*type \\$1 +.if \\n[ref*type]=0 \{\ +. ie d [C \{\ +. if !d [I \{\ +. nr pre-1900 1 \" If pre-1900, MLA allows excluding publisher +. nr ref*type 2 +. \} +. \} +. el .nr ref*type 2 +. if d [q .nr ref*type 2 +.\} +.if d [u .nr ref*type 0 \" If %u exists, always treat as Internet ref +.if \\n[ref*type]=3 \{\ +. if !'\\*([R'' \{\ +. nr ref*type 4 +. ds ref*spec!4 i Q A m p T2 B R O C I D P n +. \} +. if !'\\*([G'' \{\ +. nr ref*type 4 +. ds ref*spec!4 i A m p T2 B G O C I D P O n +. \} +.\} +.if r [T \{\ +. als [T1 [T +. als [T2 [T +.\} +.ie d ref*spec!\\n[ref*type] .ref*build \\*[ref*spec!\\n[ref*type]] +.el \{\ +. @error unknown reference type '\\n[ref*type]' +. ref*build \\*[ref*spec!0] +.\} +.if !\\n[.hy]=0 \{\ +.nr #RESTORE_HY \\n[.hy] +.if !r#REF_HY .nh +.\} +.ref*print +.if !\\n[#RESTORE_HY]=0 .hy \\n[#RESTORE_HY] +.rr #RESTORE_HY +.rm ref*string +.rm [F [T1 [T2 +.. +\# +\# Refer's "3rd" macros, which set up and terminate the output +\# of collected references +\# +.de ]< +.rm author \" If not, persists over multiple 'bibliography' commands +.als ref*print ref*end-print +.nr #REF 1 +.if \\n[#BIB_LIST]=1 \{\ +. nr #IN_BIB_LIST 1 +. LIST DIGIT \\*[$BIB_LIST_SEPARATOR] \\*[$BIB_LIST_PREFIX] +.\} +.. +\# +.de ]> +.LIST OFF +.rr #REF +.rr #IN_BIB_LIST +.als ref*print ref*normal-print +.. +\# +\# Output +\# ------ +\# +\# Output normal, non-collected refs +\# +.de ref*normal-print +.nr #CURRENT_HY \\n[.hy] +\\*[ref*string] +.. +\# +\# Output collected refs +\# +.de ref*end-print +.\" 10 is arbitrary +.nn 10 +.nr #REF_BIB_INDENT (u;\\*[$REF_BIB_INDENT]) +.ie \\n[#BIB_LIST]=0 \{\ +. in +\\n[#REF_BIB_INDENT]u +. ti -\\n[#REF_BIB_INDENT]u +.\} +.el .ITEM +.\" Part of workaround for refer spitting out a blank page if the +.\" last ref falls on the bottom line. +\\*[ref*string]\R'ref*num*first-pass +1'\?\R'ref*num +1'\? +.sp \\*[$BIB_SPACE] +.ie \\n[#BIB_LIST]=0 .in +.el .IL -\\n[#REF_BIB_INDENT]u +.nn 0 +.. +\# +.als ref*print ref*normal-print +\# +\# Build up the ref*string +\# +\# Correct MLA "typewritten" style (printstyle TYPEWRITE) demands +\# two spaces after each period. The spaces are hardwired into the +\# string definitions (ref*add-<x>), so we have to make sure that there +\# aren't two spaces when the printstyle is TYPESET. Since I find that +\# references look a bit crowded with 0 sentence space, I've bumped it +\# up to +8. User's sentence spacing is reset in FOOTNOTES and ENDNOTES. +\# +.de ref*build +.if \\n[#PRINT_STYLE]=2 \ +. if (\\n[#FN_REF]+\\n[#EN_REF])>0 .SS +8 +.rm ref*string +.while \\n[.$] \{\ +. if d [\\$1 \{\ +. ie d ref*add-\\$1 .ref*add-\\$1 +. el .ref*add-dflt \\$1 +. \} +. shift +.\} +.\" now add a final period +.ie d ref*string \{\ +. if !\\n[ref*suppress-period] .as ref*string . +. if d ref*post-punct \{\ +. as ref*string "\\*[ref*post-punct] +. rm ref*post-punct +. \} +.\} +.el .ds ref*string +.. +\# +\# The following macros determine how entries are formatted WRT +\# punctuation, type style, additional strings, etc. +\# +\# o First argument is the database field letter. +\# o Second argument is the punctuation character to use to separate this +\# field from the previous field. +\# o Third argument is a string with which to prefix this field. +\# o Fourth argument is a string with which to postfix this field. +\# o Fifth argument is a string to add after the punctuation character +\# supplied by the next field. +\# +\# %A Author(s) +.de ref*add-A +.ds eval*[A \\*([A +.substring eval*[A -1 +.if !\\n[skip-[A] \{\ +. if '\\*[eval*[A]'.' \ +. if !\\n[#FN_REF]+\\n[#EN_REF] .chop [A +.\" Per MLA, footnotes and endnotes should not use idem, therefore +.\" if %i contains other than idem (e.g., ed., trans.), transpose it +.\" to after author's name +. ie \\n[#FN_REF]+\\n[#EN_REF]=1 \{\ +. ie !'\\*[idem]'' .ref*field A "" "" "? \\*[idem]" +. el .ref*field A +. rm idem +. el .ref*field A +. \} +.\} +.if \\n([A .nr ref*suppress-period 1 +.rr skip-[A +.. +\# %i Idem. +\# +\# In bibliographies, per MLA, replace %A with long dash after +\# first entry with author's name; if %i field contains other than +\# the word 'idem', appends it to the dash. +\# In foot/endnotes, idem is ignored; MLA requires full name for +\# each foot/endnote entry. +\# +.de ref*add-i +.\" Is a foot/endnote. +.ie \\n[#FN_REF]+\\n[#EN_REF]=1 \{\ +. ie '\\*([i'idem' .rm [i +. el .ds idem \\*([i +.\} +.el \{\ +. rr skip-[A +.\" %i is idem +. ie '\\*([i'idem' \{\ +.\" If [A (%A) is the same as the last [A, captured in 'author'. +. if '\\*([A'\\*[author]' \{\ +. rm [i +. ref*field i "" \[idem] "" " " +. nr skip-[A 1 +. \} +. ds author \\*([A +. \} +.\" %i is not 'idem'; attach to long dash +. el \{\ +. ds eval*[i \\*([i +. substring eval*[i -1 +. if '\\*[eval*[i]'.' \{\ +. chop [i +. ds idem \\*([i +. \} +. rm [i +. rm [A +. ref*field i "" \[idem] ", \\*[idem]" " " +. \} +.\} +.. +\# %m Multiple authors (et al.) +.de ref*add-m +.if !\\n[#FN_REF]+\\n[#EN_REF] \{\ +. ds eval*[m \\*([m +. substring eval*[m -1 +. if '\\*[eval*[m]'.' .chop [m +.\} +.ref*field m , +.. +\# %p Post-author string (e.g., Preface, Foreword, etc) +.de ref*add-p +.\" Convert first letter to uppercase, per MLA, if BIBLIO +.if !\\n[#FN_REF]+\\n[#EN_REF] \{\ +. ds initial*cap \\*([p +. substring initial*cap 0 0 +. ds [p*string \\*([p +. substring [p*string 1 +. ds [p \E*[UC]\\*[initial*cap]\E*[LC]\\*[[p*string] +.\} +.ie \\n[#FN_REF]+\\n[#EN_REF] .ref*field p , +.el .ref*field p . " " +.. +\# %Q Author(s) when author is not a person +.de ref*add-Q +.ie \\n[#FN_REF]+\\n[#EN_REF] .ref*field Q +.el .ref*field Q +.. +\# %T Title (generic) +.de ref*add-T1 +.ie \\n[#FN_REF]+\\n[#EN_REF] .ref*field T , \E*[IT] \E*[ref*restore-ss] +.el \{\ +. ie !'\\*([A'' .ref*field T . " \E*[IT]" \E*[ref*restore-ss] +. el \{\ +. ie !'\\*([Q'' .ref*field T . " \E*[IT]" \E*[ref*restore-ss] +. el .ref*field T . \E*[IT] \E*[ref*restore-ss] +. \} +.\} +.if \\n([T .nr ref*suppress-period \\n([T +.. +\# %T Title of a chapter or article +.de ref*add-T2 +.ie \\n[#FN_REF]+\\n[#EN_REF] \ +. ref*field T , \[lq] "" \[rq] +.el \{\ +. ie '\\*([A'' \{\ +. ref*field T . \[lq] "" \[rq] +. if !'\\*([Q''.ref*field T . " \[lq]" "" \[rq] +. \} +. el .ref*field T . " \[lq]" "" \[rq] +.\} +.if \\n([T .nr ref*suppress-period \\n([T +.. +\# %B Book title (when citing an article from a book) +.de ref*add-B +.ie \\n[#FN_REF]+\\n[#EN_REF] \{\ +. ie \\n([T .ref*field B "" \E*[IT] \E*[ref*restore-ss] +. el .ref*field B , \E*[IT] \E*[ref*restore-ss] +.\} +.el \{\ +. ie \\n([T .ref*field B "" ".\E*[IT]" \E*[ref*restore-ss] +. el .ref*field B . " \E*[IT]" \E*[ref*restore-ss] +.\} +\# refer doesn't set reg [T to 1 for these book titles, so we do it here +.ds eval*[B \\*([B +.substring eval*[B -1 +.rr [T +.if '\\*[eval*[B]'!' .nr [T 1 +.if '\\*[eval*[B]'?' .nr [T 1 +.rm eval*[B +.. +\# %q Titles that must go in quotes (e.g. an unpublished dissertation) +.de ref*add-q +.ie \\n[#FN_REF]+\\n[#EN_REF] .ref*field q , \[lq] "" \[rq] +.el \{\ +. ie !'\\*([A'' .ref*field q . " \[lq]" "" \[rq] +. el \{\ +. ie !'\\*([Q'' .ref*field q . " \[lq]" "" \[rq] +. el .ref*field q . \[lq] "" \[rq] +. \} +.\} +.. +\# %R Report number for technical reports +.de ref*add-R +.ref*field R . " " +.. +\# %J Journal name +.de ref*add-J +.ie \\n[#FN_REF]+\\n[#EN_REF] \{\ +. ie \\n([T .ref*field J "" "\E*[IT]" \E*[ref*restore-ss] +. el .ref*field J , "\E*[IT]" \E*[ref*restore-ss] +.\} +.el \{\ +. ie \\n([T .ref*field J "" " \E*[IT]" \E*[ref*restore-ss] +. el .ref*field J . " \E*[IT]" \E*[ref*restore-ss] +.\} +.. +\# %M Magazine or newspaper name +.de ref*add-M +.ie \\n[#FN_REF]+\\n[#EN_REF] \{\ +. ie \\n([T .ref*field M "" "\E*[IT]" \E*[ref*restore-ss] +. el .ref*field M , "\E*[IT]" \E*[ref*restore-ss] +.\} +.el \{\ +. ie \\n([T .ref*field M "" " \E*[IT]" \E*[ref*restore-ss] +. el .ref*field M . " \E*[IT]" \E*[ref*restore-ss] +.\} +.. +\# %E Editor(s) +.de ref*add-E +.ds eval*[E \\*([E +.substring eval*[E -1 +.if '\\*[eval*[E]'.' \{\ +. if !\\n[#FN_REF]+\\n[#EN_REF] .chop [E +. rm eval*[E +.\} +.\" Workaround for join-authors also joining editors. MLA style +.\" requires a comma after first editor only if there are more than +.\" two, whereas join-authors always puts a comma after the first if +.\" there's more than one. +.rm eval*[E +.nr position 1 1 +.nr counter 1 1 +.while !'\\*[eval*[E]',' \{\ +. ds eval*[E \\*([E +. substring eval*[E \\n+[position] \\n[position] +. if \\n+[counter]>30 .break \" 30 is arbitrary +.\} +.\" Check for " and" +.if '\\*[eval*[E]',' \{\ +. ds eval*[E \\*([E +. nr and-check \\n[position]+4 +. substring eval*[E \\n+[position] \\n[and-check] +.\} +.if '\\*[eval*[E]' and' \{\ +. nr counter 1 1 +. nr start-range -1 1 +. nr end-range 3 1 +. while !'\\*[eval*[E]', and' \{\ +. ds eval*[E \\*([E +. substring eval*[E \\n+[start-range] \\n+[end-range] +. if \\n+[counter]>50 .break \" just in case; 50 is arbitrary +. \} +. if '\\*[eval*[E]', and' \{\ +. length len*[E \\*([E +. nr rhs \\n[len*[E]-\\n[start-range] +. ds lhs \\*([E +. ds rhs \\*([E +. substring lhs 0 \\n[start-range]-1 +. substring rhs -(\\n[rhs]-1) +. ds [E \\*[lhs]\\*[rhs] +. \} +. rm lhs +. rm rhs +. rr and-check +. rr counter +. rr start-range +. rr end-range +. rr len*[E +.\} +.\" End workaround +.ie !\\n[ref*type]=0 \{\ +. ie \\n([E>0 \{\ +. ie \\n[#FN_REF]+\\n[#EN_REF] \{\ +. ie \\n([T .ref*field E "" "ed. " +. el .ref*field E , "ed. " +. \} +. el \{\ +. ie \\n([T .ref*field E "" " Eds. " +. el .ref*field E . " Eds. " +. \} +. \} +. el \{\ +. ie \\n[#FN_REF]+\\n[#EN_REF] \{\ +. ie \\n([T .ref*field E "" "ed. " +. el .ref*field E , "ed. " +. \} +. el \{\ +. ie \\n([T .ref*field E "" " Ed. " +. el .ref*field E . " Ed. " +. \} +. \} +.\} +.el \{\ +. ie \\n([T .ref*field E "" " " +. el .ref*field E . " " +.\} +.rr [T +.rr [E +.. +\# %e Edition +.de ref*add-e +.ie \\n([T .ref*field e "" "" " ed." +.el \{\ +. ie \\n[#FN_REF]+\\n[#EN_REF] .ref*field e , "" " ed." +. el .ref*field e . " " " ed." +.\} +.nr ref*suppress-period 1 +.nr [e 1 +.rr [T +.. +\# %V Volume (of a journal, or series of books); for journals, %N may be preferable +.de ref*add-V +.if \\n[ref*type]=1 \ +. ref*field V +.if \\n[ref*type]=2 \{\ +. ie \\n[#FN_REF]+\\n[#EN_REF] .ref*field V , "vol. " +. el \{\ +. ie \\n([T .ref*field V "" " Vol. " +. el .ref*field V . " Vol. " +. \} +.\} +.if \\n[ref*type]=3 \{\ +. ie \\n([T .ref*field V "" " " +. el .ref*field V . " " +.\} +.rr [T +.. +\# %N Journal number +.de ref*add-N +.ref*field N +.. +\# %S Series (books or journals) +.de ref*add-S +.if \\n[ref*type]=1 \ +. ref*field S +.if \\n[ref*type]=2 \{\ +. ie \\n[#FN_REF]+\\n[#EN_REF] \{\ +. ie \\n([T .ref*field S +. el .ref*field S , +. \} +. el \{\ +. ie \\n([T .ref*field S "" " " +. el .ref*field S . " " +. \} +.\} +.if \\n[ref*type]=3 \{\ +. ie \\n([T .ref*field S "" " " +. el .ref*field S . " " +.\} +.rr [T +\# refer doesn't set reg [T to 1 for series titles, so we do it here +.ds eval*[S \\*([S +.substring eval*[S -1 +.if '\\*[eval*[S]'!' .nr [T 1 +.if '\\*[eval*[S]'?' .nr [T 1 +.rm eval*[S +.. +\# %C City +.de ref*add-C +.ie \\n[#FN_REF]+\\n[#EN_REF] \{\ +. ie r [d \{\ +. ref*field C +. rr [d +. \} +. el \ +. ref*field C "" \*[FU 2]( +. if \\n([T .nr ref*suppress-period \\n([T +.\} +.el \{\ +. ie \\n([T .ref*field C "" " " +. el \{\ +. ie r [e .ref*field C "" " " +. el .ref*field C . " " +. \} +.\} +.rr [T +.rr [e +.. +\# %I Publisher (I stands for Issuer) +.de ref*add-I +.ie \\n[#FN_REF]+\\n[#EN_REF] \{\ +. ie !'\\*([C'' .ref*field I : +. el .ref*field I "" ( +.\} +.el \{\ +. ie !'\\*([C'' .ref*field I : +. el \{\ +. ie \\n([T .ref*field I "" " " +. el .ref*field I . " " +. \} +.\} +.rr [T +.. +\# %D Date of publication +.de ref*add-D +.if \\n[ref*type]=0 \{\ +. ie \\n[#FN_REF]+\\n[#EN_REF] .ref*field D , +. el .ref*field D . " " +.\} +.if \\n[ref*type]=1 \ +. ref*field D "" "(" ")" +.if \\n[ref*type]=2 \{\ +. ie \\n[#FN_REF]+\\n[#EN_REF] .ref*field D , "" ) +. el .ref*field D , +.\} +.if \\n[ref*type]=3 \{\ +. ie !'\\*([C'' \{\ +. ie \\n[#FN_REF]+\\n[#EN_REF] .ref*field D , "" ) +. el .ref*field D , +. \} +. el \{\ +. if '\\*([I'' \{\ +. ds eval*[D \\*([D +. substring eval*[D 0 -4 +. ie '\\*[eval*[D]'1' .ds kern \*[BU3] +. el .ds kern \*[BU2] +. ie \\n[#PRINT_STYLE]=2 \ +. if \\n[#FN_REF]+\\n[#EN_REF] .ref*field D "" (\\*[kern] ) +. el .ref*field D +. \} +. rm eval*[D +. rm kern +. \} +.\} +.if \\n[ref*type]=4 .ref*field D , +.if \\n[ref*type]=5 .ref*field D +.ds eval*[D \\*([D +.substring eval*[D -1 +.if '\\*[eval*[D]'.' .nr ref*suppress-period 1 +.. +\# %P Page number(s) +.de ref*add-P +.if \\n[ref*type]=5 .nr ref*type 1 +.ie \\n[#FN_REF]+\\n[#EN_REF] \{\ +. ie \\n[ref*type]=1 .ref*field P : "" . +. el .ref*field P "" "\|" +. if \\n[ref*type]=1 .nr ref*suppress-period 1 +.\} +.el \{\ +. ie \\n[ref*type]=1 .ref*field P \|: +. el \{\ +. ie d [n .ref*field P . \| . +. el .ref*field P . " " +. \} +.\} +.. +\# %G Gov't. ordering number +.de ref*add-G +.ie \\n[#FN_REF]+\\n[#EN_REF] ref*field G , +.el .ref*field G . " " +.. +\# %O Other (info that goes after %T [or %B] but is hard to categorize; e.g., a dissertation) +.de ref*add-O +.ds eval*[O \\*([O +.substring eval*[O -1 +.if '\\*[eval*[O]'.' .nr [O 1 +.ds initial*cap \\*([O +.substring initial*cap 0 0 +.ds [O*string \\*([O +.substring [O*string 1 +.if !\\n[#FN_REF]+\\n[#EN_REF] \ +. ds [O \E*[UC]\\*[initial*cap]\E*[LC]\\*[[O*string] +.ie \\n[#FN_REF]+\\n[#EN_REF] .ref*field O , +.el \{\ +. if \\n([O=1 .chop [O +. ie r [e .ref*field O "" " " +. el \{\ +. ie !d [A .ref*field O +. el .ref*field O . " " +. \} +.\} +.rr [O +.rr [e +.. +\# %n Annotations (after ref) +.de ref*add-n +.ds eval*[n \\*([n +.substring eval*[n -1 +.if '\\*[eval*[n]'.' .chop [n +.if '\\*[eval*[n]'?' .nr [n 1 +.if '\\*[eval*[n]'!' .nr [n 1 +.ie \\n[#FN_REF]+\\n[#EN_REF] .ref*field n , +.el \{\ +. ie !'\\*([P'' .ref*field n "" " " +. el .ref*field n . " " +.\} +.if r [n .nr ref*suppress-period 1 +.rr [n +.. +\# +.de ref*add-dflt +.ref*field \\$1 , +.. +\# +\# Book reprints +\# ------------- +\# %d date of publication (the original date of publication) +.de ref*add-d +.ie \\n[#FN_REF]+\\n[#EN_REF] \{\ +. ref*field d "" ( ; +. nr [d 1 +.\} +.el \{\ +. ie \\n([T .ref*field d "" " " +. el .ref*field d . " " +.\} +.rr [T +.. +\# %b main author when citing from a preface, introduction, foreword +\# or afterword +.de ref*add-b +.ie \\n[#FN_REF]+\\n[#EN_REF] \{\ +. ie \\n([T .ref*field b "" "by" +. el .ref*field b , "by " +.\} +.el \{\ +. ie \\n([T .ref*field b "" " By " +. el .ref*field b . " By " +.\} +.rr [T +.. +\# %t title, if different from original title (the T field, which s/b +\# the original title) +.de ref*add-t +.ie \\n[#FN_REF]+\\n[#EN_REF] .ref*field t , "rpt. of \E*[IT] " \E*[ref*restore-ss] +.el \{\ +. ie \\n([T .ref*field t "" " Rpt. of \E*[IT] " \E*[ref*restore-ss] +. el .ref*field t . " Rpt. of \E*[IT] " \E*[ref*restore-ss] +.\} +.rr [T +.. +\# +\# Translated works +\# ---------------- +\# %l Trans(l)ator +.de ref*add-l +.ie \\n[#FN_REF]+\\n[#EN_REF] \{\ +. ie \\n([T .ref*field l "" "trans. " +. el .ref*field l , "trans. " +.\} +.el \{\ +. ie \\n([T .ref*field l "" " Trans. " +. el .ref*field l . " Trans. " +.\} +.rr [T +.. +\# %r Translato(r) and edito(r) +.de ref*add-r +.ie \\n[#FN_REF]+\\n[#EN_REF] .ref*field r , "trans. and ed. " +.el \{\ +. ie \\n([T .ref*field r "" " Trans. and ed. " +. el .ref*field r . " Trans. and ed. " +.\} +.rr [T +.. +\# +\# Internet +\# -------- +\# %s Site name +.de ref*add-s +.ie \\n[#FN_REF]+\\n[#EN_REF] .ref*field s , \E*[IT] \E*[ref*restore-ss] +.el \{\ +.ie \\n([s .ref*field s "" ".\E*[IT]" \E*[ref*restore-ss] +.el .ref*field s . " \E*[IT]" \E*[ref*restore-ss] +.\} +.\" refer doesn't set reg [T to 1 for these titles, so we do it here +.if !\\n[#FN_REF]+\\n[#EN_REF] \{\ +. ds eval*[s \\*([s +. substring eval*[s -1 +. rr [T +. if '\\*[eval*[s]'.' .nr [T 1 +. if '\\*[eval*[s]'!' .nr [T 1 +. if '\\*[eval*[s]'?' .nr [T 1 +. rm eval*[s +.\} +.. +\# %c content of site (ie. Web, Online posting, etc) +.de ref*add-c +.ie \\n[#FN_REF]+\\n[#EN_REF] .ref*field c , +.el \{\ +. ie \\n([T .ref*field c "" " " +. el .ref*field c . " " +.\} +.rr [T +.. +\# %o organization, group or sponsor of site +.de ref*add-o +.ie \\n[#FN_REF]+\\n[#EN_REF] .ref*field o , +.el \{\ +. ie \\n([T .ref*field o "" " " +. el .ref*field o . " " +.\} +.rr [T +.. +\# %a access date, i.e. the date you read it +.de ref*add-a +.ie \\n[#FN_REF]+\\n[#EN_REF] .ref*field a , +.el \{\ +. ie \\n([T .ref*field a "" " " +. el .ref*field a . " " +.\} +.rr [T +.. +\# %u URL +.de ref*add-u +.ref*field u "" < > +.rr [T +.. +.de ref*add-z +.ref*field z +.. +\# +\# Build up reference string from ref*add-<x> macros. +\# +\# First, a string to ensure next field's font is reset to roman +\# (TYPESET) or non-underlined (TYPEWRITE) +\# +.ie !n .ds ref*roman \f[R]\X'ps: exec decornone'\?\R'#UNDERLINE_ON 0'\? +.el .ds ref*roman \f[R]\?\R'#UNDERLINE_ON 0'\? +\# +.de ref*field +.if d ref*string \{\ +. ie d ref*post-punct \{\ +. as ref*string "\\$2\\*[ref*post-punct] \" +. rm ref*post-punct +. \} +. el .as ref*string "\\$2 \" +.\} +.as ref*string "\\$3\\*([\\$1\\$4\E*[ref*roman] +.if \\n[.$]>4 .ds ref*post-punct "\\$5\E*[ref*roman] +.nr ref*suppress-period 0 +.. +\# +\# MARGIN NOTES +\# ------------ +\# +\# Wrapper for MNinit. +\# +.MAC MN_INIT END +. if \B'\\$2' \{\ +. tm1 "[mom]: 1.x-style \\$0 detected, but you are using v2.x. +. tm1 " v2.x requires flags before arguments to \\$0. +. tm1 " Please read docelement.html#mn-init and update your file. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. nr #ARGS 0 1 +. nr #COUNT 9 +. while \\n+[#ARGS]<=\\n[#COUNT] \ +. ds $MN-arg\\n[#ARGS] @ +. nr #FLAG 0 1 +. nr #COUNT \\n[#NUM_ARGS] +. while \\n+[#FLAG]<=\\n[#COUNT] \{\ +. if '\\$1'RAGGED' \{\ +. ds $MN-arg1 \\$1 +. shift +. \} +. if '\\$1'SYMMETRIC' \{\ +. ds $MN-arg1 \\$1 +. shift +. \} +. if '\\$1'L_WIDTH' \{\ +. shift +. ds $MN-arg2 \\$1 +. shift +. \} +. if '\\$1'R_WIDTH' \{\ +. shift +. ds $MN-arg3 \\$1 +. shift +. \} +. if '\\$1'GUTTER' \{\ +. shift +. ds $MN-arg4 \\$1 +. shift +. \} +. if '\\$1'FONTSTYLE' \{\ +. shift +. ds $MN-arg5 \\$1 +. shift +. \} +. if '\\$1'SIZE' \{\ +. shift +. ds $MN-arg6 \\$1 +. shift +. \} +. if '\\$1'LEAD' \{\ +. shift +. ds $MN-arg7 \\$1 +. shift +. \} +. if '\\$1'COLOR' \{\ +. shift +. ds $MN-arg8 \\$1 +. shift +. \} +. if '\\$1'HY' \{\ +. shift +. ds $MN-arg9 \\$1 +. shift +. \} +. \} +. if '\\*[$MN-arg5]'@' .ds $MN-arg5 \E*[$DOC_FAM]R +. MNinit \ +\\*[$MN-arg1] \\*[$MN-arg2] \ +\\*[$MN-arg3] \\*[$MN-arg4] \ +\\*[$MN-arg5] \\*[$MN-arg6] \ +\\*[$MN-arg7] \\*[$MN-arg8] \ +\\*[$MN-arg9] +.END +\# +.MAC MN_OVERFLOW_TRAP END +. if \\n[#OVERFLOW_LEFT]=1 \{\ +. nr #no-repeat-MN-left 1 +. di MN_OVERFLOW_LEFT +. \} +. if \\n[#OVERFLOW_RIGHT]=1 \{\ +. nr #no-repeat-MN-right 1 +. di MN_OVERFLOW_RIGHT +. \} +. rr #OVERFLOW_LEFT +. rr #OVERFLOW_RIGHT +.END +\# +\# The remainder of the margin notes macros and routines are adapted +\# from Werner Lemberg's MN.tmac. +\# +\# MNinit +\# ------ +\# Usage: +\# MNinit [ragged|symmetric] \ +\# left-width right-width separation \ +\# font fontsize vertical-spacing \ +\# color hyphenation-flags +\# +\# Initialize margin notes. Empty arguments (denoted with "") set +\# default values. If the first argument is the string 'ragged', +\# left and right margin notes are printed ragged-right. If it is +\# 'symmetric', left margin notes are printed ragged-left and right +\# margin notes ragged-right. If omitted, margin notes are left +\# and right adjusted. +\# +.de MNinit +. nr #MNinit 1 +. ds MN-left-ad b\" +. ds MN-right-ad b\" +. if '\\$1'@' .shift +. if '\\$1'RAGGED' \{\ +. ds MN-left-ad l\" +. ds MN-right-ad l\" +. shift +. \} +. if '\\$1'SYMMETRIC' \{\ +. ds MN-left-ad r\" +. ds MN-right-ad l\" +. shift +. \} +. ie \B'\\$3' .nr MN-sep (n;\\$3) +. el .nr MN-sep 1m +. if ((\\n[.o] - \\n[MN-sep]) < 1n) \ +. ab MN: Left margin too small (<1n) for requested margin notes separation. +. ie \B'\\$1' \{\ +. nr MN-left-width (n;\\$1) +. nr MN-left-start (\\n[.o] - \\n[MN-sep] - \\n[MN-left-width]) +. \} +. el \{\ +. nr MN-left-width (\\n[.o] - \\n[MN-sep]) +. nr MN-left-start 0 +. \} +. if (\\n[MN-left-start] < 0) \ +. ab MN: Left margin too small for requested margin notes settings. +. if (\\n[MN-left-width] < 1n) \ +. ab MN: Left margin notes width too small (<1n). +. ie \B'\\$2' \{\ +. nr MN-right-width (n;\\$2) +. nr MN-right-start (\\n[.o] + \\n[.l] + \\n[MN-sep]) +. if \\n[#COLUMNS]=1 \{\ +. if !\\n[#NUM_COLS]=1 \ +. nr MN-right-start (\\n[#COL_2_L_MARGIN] + \\n[#COL_L_LENGTH] + \\n[MN-sep]) +. \} +. \} +. el \{\ +. nr MN-right-width \\n[MN-left-width] +. nr MN-right-start (\\n[.o] + \\n[.l] + \\n[MN-sep]) +. if \\n[#COLUMNS]=1 \{\ +. if !\\n[#NUM_COLS]=1 \ +. nr MN-right-start (\\n[#COL_2_L_MARGIN] + \\n[#COL_L_LENGTH] + \\n[MN-sep]) +. \} +. \} +. ie \A'\\$4' \{\ +. ds MN-font \\$4\" +. if \\n[#PRINT_STYLE]=1 .ds MN-font CR +. \} +. el \{\ +. ds MN-font \\*[$PP_FT] +. if \\n[#PRINT_STYLE]=1 .ds MN-font CR +. \} +. ie \B'\\$5' \{\ +. ps \\$5 +. nr MN-size \\n[.ps] +. ps +. if \\n[#PRINT_STYLE]=1 \{\ +. ps \\*[$TYPEWRITER_PS] +. nr MN-size \\n[.ps] +. ps +. \} +. \} +. el \ +. nr MN-size \\n[#DOC_PT_SIZE] +. ie \B'\\$6' \{\ +' vs \\$6 +. nr MN-spacing \\n[.v] +' vs +. if \\n[#PRINT_STYLE]=1 \ +. nr MN-spacing \\n[#DOC_LEAD] +. \} +. el .nr MN-spacing \\n[#DOC_LEAD] +. ie \A'\\$7' \ +. if !\\n[#PRINT_STYLE]=1 .ds MN-color \\$7\" +. el \ +. if !\\n[#PRINT_STYLE]=1 .ds MN-color +. ie \B'\\$8' .nr MN-hy \\$8 +. el .nr MN-hy \\n[.hy] +. ev MNbottom-left-env +. if \A'\\*[MN-font]' .ft \\*[MN-font] +. if \\n[MN-size] .ps \\n[MN-size]u +. if \\n[MN-spacing] .vs \\n[MN-spacing]u +. ll \\n[MN-left-width]u +. ad \\*[MN-left-ad] +. hy \\n[MN-hy] +' in 0 +. nop \m[\\*[MN-color]]\c +. ev +. ev MNbottom-right-env +. if \A'\\*[MN-font]' .ft \\*[MN-font] +. if \\n[MN-size] .ps \\n[MN-size]u +. if \\n[MN-spacing] .vs \\n[MN-spacing]u +. ll \\n[MN-right-width]u +. ad \\*[MN-right-ad] +. hy \\n[MN-hy] +' in 0 +. nop \m[\\*[MN-color]]\c +. ev +. nr MN-active 0 +.. +\# MN +\# -- +\# Usage: +\# +\# MN LEFT|RIGHT +\# margin note text +\# MN +\# +\# With a parameter, start a margin note, otherwise end a margin note. +\# If the parameter is the string 'left', define a left margin note, +\# otherwise define a right margin note. +\# +.de MN +. ds MN-dir \\$1 +. if !'\\$1'LEFT' \{\ +. if !'\\$1'RIGHT' \{\ +. MN_QUIT +. return +. \} +. \} +. if \\n[#COLUMNS]=1 \{\ +. if \\n[#NUM_COLS]>2 \{\ +. tm [mom]: Macro MN: More than two columns. Ignoring margin notes. +. return +. \} +. if !\\n[#NUM_COLS]=1 \{\ +. ie \\n[#COL_NUM]=1 .ds MN-dir LEFT +. el .ds MN-dir RIGHT +. \} +. \} +. if !\\n[#MNinit]=1 \{\ +. tm1 "[mom]: Macro MN: You must set parameters with MN_INIT before using MN. +. ab [mom]: Aborting '\\n[.F]' at MN, line \\n[.c]. +. \} +. ie !'\\$1'' \{\ +. if \\n[MN-active] \{\ +. tm [mom]: Macro MN: Can't handle nested margin notes, line \\n[.c]. +. return +. \} +. nr MN-active 1 +. ev MN-env +. ie '\\*[MN-dir]'LEFT' \{\ +. nr MN-left +1 +. ds MN-curr l-\\n[MN-left]\" +. evc MNbottom-left-env +. \} +. el \{\ +. nr MN-right +1 +. ds MN-curr r-\\n[MN-right]\" +. evc MNbottom-right-env +. \} +. mk MN-mk-\\*[MN-curr] +. di MN-div-\\*[MN-curr] +. \} +. el .MN_QUIT +.. +\# +\# MN_QUIT +\# ------- +\# Utility macro to handle .MN OFF | QUIT | X etc +\# +.de MN_QUIT +. if \\n[MN-active] \{\ +. br +. di +. nr MN-div-\\*[MN-curr]-depth \\n[dn] +. ev +. \} +. nr MN-active 0 +.. +\# +\# MNtop +\# ----- +\# Resets these registers (called in HEADER) +.de MNtop +. nr MN-left 0 +. nr MN-right 0 +. nr MN-active 0 +. rr MN-shifted +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u +.. +\# +\# MNbottom +\# -------- +\# Executed in FOOTER. +\# +.de MNbottom +. if '\\$0'MNbottom-left' \{\ +. ds MN-pos left +. ds l-r l +. ds Left-Right Left +. \} +. if '\\$0'MNbottom-right' \{\ +. ds MN-pos right +. ds l-r r +. ds Left-Right Right +. \} +. nr MN-curr 0 +. nr MN-last-pos 0 +. nr MN-lead-adj \\n[#DOC_LEAD]-\\n[MN-spacing] +. vpt 0 +. if \\n[MN-active] \{\ +. di +. tm [mom]: Macro MN: Margin note finished by new page. Ignored. +. \} +. if \\n[#RECTO_VERSO] \{\ +. if e \{\ +. if '\\*[MN-pos]'right' \ +. nr MN-\\*[MN-pos]-start (\\n[.o]+\\n[.l]+\\n[MN-sep]) +. if '\\*[MN-pos]'left' \ +. nr MN-\\*[MN-pos]-start (\\n[.o]-\\n[MN-sep]-\\n[MN-left-width]) +. \} +. \} +. po \\n[MN-\\*[MN-pos]-start]u +. ev MNbottom-\\*[MN-pos]-env +. nr #P \\n%+\\n[#PAGE_NUM_ADJ] +. while (\\n[MN-curr] < \\n[MN-\\*[MN-pos]]) \{\ +. nr MN-curr +1 +. ie (\\n[MN-last-pos] < \\n[MN-mk-\\*[l-r]-\\n[MN-curr]]) \ +. sp |\\n[MN-mk-\\*[l-r]-\\n[MN-curr]]u+\\n[MN-lead-adj]u +. el \{\ +. nr MN-shifted 1 +. sp 1v +. SHIM +. if \\n[#SHIM]>\\n[MN-spacing] .sp -(1v+\\n[MN-lead-adj]u) +. tm [mom]: Macro MN: Warning: \\*[Left-Right] margin note #\\n[MN-curr] on page \\n[#P] shifted down. +. \} +.\" If last margin note doesn't fit +. if ( (\\n[nl]+\\n[MN-div-\\*[l-r]-\\n[MN-curr]-depth]) > (\\n[.p]+\\n[#VARIABLE_FOOTER_POS]-1) ) \{\ +. if \\n[MN-shifted]=1 \{\ +. sp -(1v+\\n[#SHIM]u) +. rm MN-div-\\*[l-r]-\\n[MN-curr] +. tm1 "[mom]: \ +No room to start \\*[MN-pos] margin note #\\n[MN-curr] on page \\n[#P]. +. tm1 " Ignoring margin note. +. rr MN-shifted +. \} +. nr #no-repeat-MN-\\*[MN-pos] 1 +. if '\\*[MN-pos]'left' .nr #OVERFLOW_LEFT 1 +. if '\\*[MN-pos]'right' .nr #OVERFLOW_RIGHT 1 +. ie \\n[#FN_COUNT]=0 \{\ +. ch FOOTER \\n[.p]u +. wh \\n[#VARIABLE_FOOTER_POS]u+\\n[MN-lead-adj]u+1u MN_OVERFLOW_TRAP +. \} +. el \ +. wh \\n[.p]u+\\n[#VARIABLE_FOOTER_POS]u-1u MN_OVERFLOW_TRAP +. vpt +. \} +. nf +. MN-div-\\*[l-r]-\\n[MN-curr] +. fi +. br +. nr MN-last-pos \\n[nl] +. \} +. ev +. po +. if !\\n[#no-repeat-MN-\\*[MN-pos]]=1 .vpt +.. +. +.ALIAS MNbottom-right MNbottom +.ALIAS MNbottom-left MNbottom +\# +\# PDF SUPPORT +\# =========== +\# +\# Initial setup +\# +.nr CURRENT_LEVEL 0 +.nr VIRTUAL_LEVEL 0 +.nr #PDF_BOOKMARKS 1 +.nr #PDF_BOOKMARKS_OPEN 1 +.pdfview /PageMode /UseOutlines +\# +\# TOC_BEFORE_HERE +\# --------------- +\# +\# Call this and the TOC will be placed preceding this page +\# +.MAC TOC_BEFORE_HERE END +. nr TOC_BH 1 +. pdfpagename MOM:TOC +.END +\# +\# TOC_AFTER_HERE +\# --------------- +\# +\# Call this and the TOC will be placed after this page +\# +.MAC TOC_AFTER_HERE END +. nr TOC_BH 2 +. pdfpagename MOM:TOC +.END +\# +\# PDF_LINK_COLOR +\# ----------------- +\# +\# Arguments:- +\# <name defined by previous call to XCOLOR or NEWCOLOR> or +\# <red> <green> <blue> all 0.0 -> 1.0 +\# Notes +\# Should be called before START but can also be called at any time to change colour +\# The colour assigned at the end of the document is used for all links in the TOC +\# +.MAC PDF_LINK_COLOR END +. ie \\n[.$]==3 \{\ +. ds PDFHREF.COLOUR \\$* +. if !(\B'\\$1' & \B'\\$2' & \B'\\$3') \{\ +. tm1 "[mom]: All three arguments to \\$0 at line \\n[.c] must be decimal. +. tm1 " Continuing to process using default link color. +. ds PDFHREF.COLOUR 0.0 0.3 0.9 +. \} +. defcolor pdf:href.colour rgb \\*[PDFHREF.COLOUR] +. ds PDFHREF.TEXT.COLOUR pdf:href.colour +. \} +. el \{\ +. ie \\n[.$]==0 \{\ +. if dPDFHREF.TEXTCOL.DEFAULT \ +. PDF_LINK_COLOR \\*[PDFHREF.TEXTCOL.DEFAULT] +. \} +. el \{\ +. ds ARG_1 \\$1 +. substring ARG_1 0 0 +. ie '\\*[ARG_1]'#' \{\ +. defcolor pdf:href.colour rgb \\$1 +. ds PDFHREF.TEXT.COLOUR pdf:href.colour +. \} +. el \{\ +. ie dCOLAL_\\$1 .ds PDFHREF.TEXT.COLOUR \\*[COLAL_\\$1] +. el .ds PDFHREF.TEXT.COLOUR \\$1 +. \} +. \} +. \} +. if !\\n[PDFHREF_COLOR_SET]=1 \ +. nr PDFHREF_COLOR_SET 1 +.END +\# +.ALIAS PDF_LINK_COLOUR PDF_LINK_COLOR +\# +\# AUTO_RELOCATE_TOC +\# ----------------- +\# +\# Call before START to have TOC automatically relocated to after the +\# DOC COVER (if there is one) or the COVER if there isn't +\# +.MAC AUTO_RELOCATE_TOC END +. if '\\$1'' .nr TOC.RELOCATE 1 +. if '\\$1'TOP' .nr TOC.RELOCATE 2 +. if '\\$1'BEFORE_DOCCOVER' .nr TOC.RELOCATE 3 \" Same as TOP unless no DOCCOVER +. if '\\$1'AFTER_DOCCOVER' .nr TOC.RELOCATE 4 +. if '\\$1'BEFORE_COVER' .nr TOC.RELOCATE 5 +. if '\\$1'AFTER_COVER' .nr TOC.RELOCATE 6 +.END +\# +.ALIAS AUTO_TOC_RELOCATE AUTO_RELOCATE_TOC +\# +\# PDF_BOOKMARK +\# ------------ +\# *Argument: +\# Hierarchy Level +\# Bookmark Text +\# *Function: +\# Creates a bookmark using the given text +\# The level controls the hierarchy of the bookmarks +\# *Notes +\# Bookmarks can be turned off (will not be added to document outline) by calling +\# "PDF_BOOKMARKS NO" and turned on with "PDF_BOOKMARKS". +\# +\# Bookmarks can be open or closed by calling PDF_BOOKMARKS_OPEN +\# +.MAC PDF_BOOKMARK END +. if \\n[#PDF_BOOKMARKS] \{\ +. ie '\\$1'NAMED' \{\ +. ds PDF_NM -T \\$2 +. ds PDF_NM2 \\$2 +. shift 2 +. \} +. el .ds PDF_NM +. nr LEVEL_REQ \\$1 +. shift +. ie \\n[LEVEL_REQ]>\\n[VIRTUAL_LEVEL] \{\ +. nr VIRTUAL_LEVEL \\n[LEVEL_REQ] +. nr LEVEL_REQ \\n[CURRENT_LEVEL]+1 +. \} +. el \{\ +. ie \\n[LEVEL_REQ]<\\n[VIRTUAL_LEVEL] \{\ +. nr VIRTUAL_DIFF \\n[VIRTUAL_LEVEL]-\\n[LEVEL_REQ] +. nr VIRTUAL_LEVEL \\n[LEVEL_REQ] +. nr LEVEL_REQ (\\n[CURRENT_LEVEL]-\\n[VIRTUAL_DIFF])>?1 +. \} +. el .nr LEVEL_REQ \\n[CURRENT_LEVEL] +. \} +. ds PDF_TX \\$* +. pdfmomclean PDF_TX +. nr PDF_LEV (\\n[LEVEL_REQ]*\\n[#PDF_BOOKMARKS_OPEN]) +. ie '\\*[.T]'ps' \{\ +. if !'\\*[PDF_NM]'' \{\ +. pdfhref M -N \\*[PDF_NM2] -- \\*[PDF_TX] +. if !dpdf:href.map .tm gropdf-info:href \\*[PDF_NM2] \\*[PDF_TX] +. \} +. pdfbookmark \\n[PDF_LEV] \\*[PDF_TX] +. \} +. el .pdfbookmark \\*[PDF_NM] \\n[PDF_LEV] \\$* +. nr CURRENT_LEVEL \\n[LEVEL_REQ] +. rr LEVEL_REQ +. rr PDF_LEV +. rr VIRTUAL_DIFF +. rm PDF_NM +. \} +.END +\# +\# PDF_TITLE +\# --------- +\# *Argument: +\# Title Text +\# *Function +\# Set the PDF title (this is often used by PDF readers to title the main window) +\# +.MAC PDF_TITLE END +. ds pdftitle \\$* +. pdfmomclean pdftitle +. nop \!x X ps:exec [/Title (\\*[pdftitle]) /DOCINFO pdfmark +.END +\# +\# PDF_BOOKMARKS +\# ------------- +\# *Argument: +\# <nothing> | <anything> +\# *Function: +\# With no parameter turns on outline bookmarks +\# With any parameter turns off outline bookmarks +\# +.MAC PDF_BOOKMARKS END +. ie '\\$1'' .nr #PDF_BOOKMARKS 1 +. el .nr #PDF_BOOKMARKS 0 +.END +\# +\# PDF_BOOKMARKS_OPEN +\# ------------------ +\# *Argument: +\# <number> | <nothing> | <text> +\# *Function: +\# If arg is numeric all Bookmark levels > arg are closed +\# If arg is empty all bookmarks are open +\# If arg is any text then any following bookmarks are closed +\# +.MAC PDF_BOOKMARKS_OPEN END +. ie \B'\\$1' \{\ +. nr PDFOUTLINE.FOLDLEVEL \\$1 +. nr #PDF_BOOKMARKS_OPEN 1 +. \} +. el .if '\\*[.T]'pdf' \{\ +. nr PDFOUTLINE.FOLDLEVEL 10000 +. ie '\\$1'' .nr #PDF_BOOKMARKS_OPEN 1 +. el .nr #PDF_BOOKMARKS_OPEN 0-1 +. \} +.END +\# +\# PDF_LINK +\# -------- +\# *Arguments: +\# $1 = named link +\# [PREFIX text] : text to prefix link +\# [SUFFIX text] : text after link +\# text +\# *Notes +\# Text is output as a hotspot link to named destination. +\# If text has final '*' it is replaced with the text associated with the link +\# +.MAC PDF_LINK END +. ds PDF_NM \\$1 +. shift +. ie '\\$1'PREFIX' \{\ +. ds PDF_PRE -P "\&\\$2" +. shift 2 +. \} +. el .ds PDF_PRE +. ie '\\$1'SUFFIX' \{\ +. ds PDF_POST -A "\\$2" +. shift 2 +. \} +. el .ds PDF_POST +. ds PDF_AST_Q +. ds PDF_TXT \&\\$1 +. ds PDF_AST \\*[PDF_TXT] +. substring PDF_AST -1 -1 +. if '\\*[PDF_AST]'+' \{\ +. ds PDF_AST * +. ds PDF_AST_Q "" +. \} +. if '\\*[PDF_AST]'*' \{\ +. chop PDF_TXT +. ie '\\*[.T]'pdf' \{\ +. ie d pdf:look(\\*[PDF_NM]) \ +. as PDF_TXT \&\\*[PDF_AST_Q]\\*[pdf:look(\\*[PDF_NM])]\\*[PDF_AST_Q] +. el \{\ +. as PDF_TXT Unknown +. if !rPDF_UNKNOWN .tm \ +\\n[.F]:\\n[.c]: forward reference detected (please run using 'pdfmom') +. nr PDF_UNKNOWN 1 +. \} +. \} +. el \{\ +. ie d pdf:href(\\*[PDF_NM]).info \ +. as PDF_TXT \&\\*[PDF_AST_Q]\\*[pdf:href(\\*[PDF_NM]).info]\\*[PDF_AST_Q] +. el .as PDF_TXT Unknown +. \} +. \} +. pdfhref L \\*[PDF_PRE] \\*[PDF_POST] -D \\*[PDF_NM] -- \\*[PDF_TXT] +. rm PDF_NM +. rm PDF_PRE +. rm PDF_POST +. rm PDF_TXT +. rm PDF_AST +. rm PDF_AST_Q +.END +\# +.MAC PDF_WWW_LINK END +. ds PDF_NM \\$1 +. shift +. ie '\\$1'PREFIX' \{\ +. ds PDF_PRE -P "\\$2" +. shift 2 +. \} +. el .ds PDF_PRE +. ie '\\$1'SUFFIX' \{\ +. ds PDF_POST -A "\\$2" +. shift 2 +. \} +. el .ds PDF_POST +. ds PDF_AST_Q +. ds PDF_TXT \\$1 +. ie !'\\*[PDF_TXT]'' \{\ +. ds PDF_AST \\*[PDF_TXT] +. substring PDF_AST -1 -1 +. if '\\*[PDF_AST]'+' \{\ +. ds PDF_AST * +. ds PDF_AST_Q "" +. \} +. if '\\*[PDF_AST]'*' \{\ +. chop PDF_TXT +. as PDF_TXT \&\\*[PDF_AST_Q]\\*[PDF_NM]\\*[PDF_AST_Q] +. \} +. \} +. el .ds PDF_TXT \\*[PDF_NM] +. pdfhref W -D "\\*[PDF_NM]" \\*[PDF_PRE] \\*[PDF_POST] -- \\*[PDF_TXT] +. rm PDF_NM +. rm PDF_PRE +. rm PDF_POST +. rm PDF_TXT +. rm PDF_AST PDF_AST_Q +.END +\# +.MAC PDF_TARGET END +. ds ARG_1 \\$1 +. shift +. ie '\\$*'' .pdfhref M -N \\*[ARG_1] -- \\$* +. el .pdfhref M -N \\*[ARG_1] -E -- \\$* +. if '\\*[.T]'ps' .if !dpdf:href.map .tm gropdf-info:href \\*[ARG_1] \\$* +.END +\# +\# PDF_IMAGE +\# --------- +\# *Arguments: +\# [ -L -| -R | -C | -I <indent> ] \ +\# <image file> <width> <height> \ +\# [ SCALE <factor> ] [ ADJUST +|-<vertical shift> ] [ TARGET <pdf target> ] \ +\# [ NO_SHIM ] [ NO_FLEX ] +\# *Function: +\# Allows embedding of PDF images with the same arguments as PSPIC +\# plus SCALE and ADJUST options. +\# *Notes: +\# <image file> <width> <height> are required. +\# +.MAC PDF_IMAGE END +. br +. if !'\\n[.z]'FLOAT*DIV' \{\ +. nr pdf-img:float 1 +. FLOAT +. \} +. PDF_TARGET fig:\\n+[lists*target] +. nr float*img 1 +. ds ev-current \\n[.ev] +. ev IMG +. evc \\*[ev-current] +. if \\n[#HYPHENATE] .nh +. nr ind-pre-img \\n[.i] +. nr ll-pre-img \\n[.l] +. in 0 +. ds pos:tmp \\$1 +. substring pos:tmp 0 0 +. ie !'\\*[pos:tmp]'-' .ds pdf-img:pos -C +. el \{\ +. ds pdf-img:pos \\$1 +. shift +. \} +. if '\\*[pdf-img:pos]'-I' \{\ +. nr pdf-img:ind \\$1 +. shift +. \} +. ds pdf-img:file \\$1 +. ds pdf-img@file \\$1 +. substring pdf-img@file -1 -3 +. if !'\\*[pdf-img@file]'pdf' \{\ +. tm1 "[mom]: Image file '\\*[pdf-img:file]' at line \\n[.c] not found, or not a PDF image. +. ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. +. \} +. nr pdf-img:width \\$2 +. nr pdf-img:depth \\$3 +. shift 3 +. nr loop-counter \\n[#NUM_ARGS] +. nr loop-count 0 1 +. while \\n+[loop-count]<=\\n[loop-counter] \{\ +. if '\\$1'SCALE' \{\ +. shift +. nr pdf-img:scale \\$1 +. shift +. nr pdf-img:width \\n[pdf-img:width]*\\n[pdf-img:scale]/100 +. nr pdf-img:depth \\n[pdf-img:depth]*\\n[pdf-img:scale]/100 +. \} +. if '\\$1'ADJUST' \{\ +. shift +. ds pdf-img:adj \\$1 +. shift +. \} +. if '\\$1'FRAME' \{\ +. nr pdf-img:frame 1 +. if !r pdf-img:frame-inset .nr pdf-img:frame-inset 6p +. shift +. \} +. if '\\$1'CAPTION' \{\ +. nr pdf-img*have-caption 1 +. ds pdf-img*caption \\$2 +. shift 2 +. \} +. if '\\$1'SHORT_CAPTION' \{\ +. ds pdf-img*caption-short \\$2 +. shift 2 +. \} +. if '\\$1'LABEL' \{\ +. nr pdf-img*have-label 1 +. ds pdf-img*label \\$2 +. ds label-type pdf-img +. shift 2 +. \} +. if '\\$1'TARGET' \{\ +. ds target "\\$2 +. PDF_TARGET "\\*[target] +. shift 2 +. \} +. if '\\$1'NO_SHIM' \{\ +. if !'\\n[.z]'FLOAT*DIV' .nr pdf-img*no-shim 1 +. nr @no-shim 1 +. shift 1 +. \} +. if '\\$1'NO_FLEX' \{\ +. nr pdf-img*no-flex 1 +. nr @no-flex 1 +. shift 1 +. \} +. \} +. if (\\n[pdf-img*have-label]=1):(\\n[pdf-img*autolabel]=1) \ +. ds label-type pdf-img +. if !'\\*[pdf-img*label-sffx]'' \{\ +. ds pdf-img*label-sffx-tmp \\*[pdf-img*label-sffx] +. substring pdf-img*label-sffx-tmp -1 +. if '\\*[pdf-img*label-sffx-tmp]'.' \ +. if \\n[pdf-img*caption-after-label]=0 .chop pdf-img*label-sffx +. \} +. if '\\*[pdf-img:pos]'-C' \ +. nr pdf-img:ind (\\n[.ll]-\\n[ind-pre-img]-\\n[pdf-img:width])/2 +. if '\\*[pdf-img:pos]'-R' \ +. nr pdf-img:ind \\n[.ll]-\\n[pdf-img:width]-\\n[ind-pre-img] +. if \\n[pdf-img*label-with-chapter] \ +. ds chapno \\n[#CH_NUM]. +. if \\n[pdf-img*autolabel] \{\ +. ds pdf-img*label \\*[pdf-img*label-prfx]\\*[chapno]\\n+[fig*label-num]\\*[pdf-img*label-sffx] +. nr fig*label-width \w'\\*[pdf-img*label]' +. nr fig*label-num -1 +. \} +. if !'\\*[pdf-img*caption-short]'' .ds short -short +. if \\n[#PDF_BOOKMARKS] \{\ +. ie (\\n[pdf-img*have-label]=1):(\\n[pdf-img*autolabel]=1) \{\ +\!. TO_FIGURES "\\*[pdf-img*label]" "\\*[pdf-img*caption\\*[short]]" +. \} +. el \{\ +\!. if !'\\*[pdf-img*caption\\*[short]]'' \ +\!. TO_FIGURES "\\*[pdf-img*caption\\*[short]]" +. \} +. \} +. if r IMG \{\ +. if \\n[pdfbx-top] \ +. rt +. sp (\\*[wt\\n[stack]]/2u)+\\*[gap\\n[stack]]u +. nr img*pdfbx 1 +. \} +. di PDF*IMAGE +. if \\n[@TOP] \{\ +. ch RR_@TOP +. rs +. nop \& +. sp -1v +. \} +. if \\n[pdf-img*have-caption] \{\ +. if !\\n[pdf-img*autolabel] \{\ +. if !\\n[pdf-img*have-label] \{\ +. if \\n[#MLA] \ +. mla@error caption label \\n[.F] \\$0 \\n[.c] +. \} +. \} +. if !\\n[pdf-img*caption-after-label] \{\ +. if !r pdfbx-top \ +. if !\\n[@TOP] \!.sp .5v +. nr lead-pre-caption \\n[.v] +. ev caption +. evc IMG +. ie \\n[#PRINT_STYLE]=1 .TYPEWRITER +. el \{\ +. img*caption-style +. vs \\n[.ps]u+\\n[pdf-img*caption-autolead]u +. \} +. if r pdfbx-top .nr restore-pdfbx-top 1 +. PDF_IMG*SET_CAPTION_QUAD \\*[pdf-img*caption-quad] +. if r restore-pdfbx-top \{\ +. nr pdfbx-top 1 +. rr restore-pdfbx-top +. \} +. nr pdf-img*caption-top-lead-diff \\n[lead-pre-caption]-\\n[.v] +. if r pdfbx-top \{\ +. SIZESPECS +. rt +. sp \\n[pdf-img*caption-top-lead-diff]u +. sp (\\*[wt\\n[stack]])+\\*[gap\\n[stack]]u+\\*[$CAP_HEIGHT] +. rr pdfbx-top +. \} +. if \\n[pdfbx-running] \{\ +. in -(\\*[wt\\n[stack]])+\\*[gap\\n[stack]]u +. ll -(\\*[wt\\n[stack]])+\\*[gap\\n[stack]]u +. \} +. nop \\*[pdf-img*caption] +. if r pdfbx-running \{\ +. in +. ll +. \} +. br +. if !'\\*[pdf-img*caption-space]'' .sp \\*[pdf-img*caption-space] +. ev +. in 0 +. sp -.5v +. \} +. \} +. nf +. if \\n[pdf-img:frame] \{\ +. nr frame-width \\n[pdf-img:width]+(\\n[pdf-img:frame-inset]*2) +. nr frame-depth \\n[pdf-img:depth]+(\\n[pdf-img:frame-inset]*2) +. if '\\*[pdf-img:pos]'-L' \{\ +. nr pdf-img:ind \\n[pdf-img:frame-inset] +. nr pdf-img:dbx-ind 0 +. \} +. if '\\*[pdf-img:pos]'-C' \{\ +. nr pdf-img:dbx-ind \ +\\n[.ll]-\\n[ind-pre-img]-\\n[pdf-img:width]/2-\\n[pdf-img:frame-inset] +. \} +. if '\\*[pdf-img:pos]'-R' \{\ +. nr pdf-img:ind -\\n[pdf-img:frame-inset] +. nr pdf-img:dbx-ind \ +\\n[.l]u-(\\n[pdf-img:width]u+(\\n[pdf-img:frame-inset]u*2u)+\\n[ind-pre-img]u) +. \} +. if '\\*[pdf-img:pos]'-I' \{\ +. nr pdf-img:ind +\\n[pdf-img:frame-inset] +. nr pdf-img:dbx-ind \\n[pdf-img:ind]-\\n[pdf-img:frame-inset] +. \} +. DBX \\*[pdf-img:frame-weight] \ + \\n[pdf-img:dbx-ind]u \ + \\n[frame-width]u \ + \\n[frame-depth]u \ + \\*[pdf-img:frame-color] +. sp \\n[pdf-img:frame-inset]u +. nr pdf-img:ind -\\n[pdf-img:frame-inset] +. \} +. ti \\n[pdf-img:ind]u+\\n[pdf-img:frame-inset]u +. nop \X'pdf: pdfpic \\*[pdf-img:file] -L \\n[pdf-img:width]z \\n[pdf-img:depth]z' +. if r pdfbx-top .rr pdfbx-top +. if '\\*[pdf-img:pos]'-C' .nr pdf-img:ind +\\n[pdf-img:frame-inset] +. sp \\n[pdf-img:depth]u +. if \\n[pdf-img:frame] .sp \\n[pdf-img:frame-inset]u +. if (\\n[pdf-img*have-label]=1):(\\n[pdf-img*autolabel]=1):(\\n[pdf-img*caption-after-label]=1) \{\ +. if \\n[#MLA] \{\ +. if (\\n[pdf-img*have-label]=1):(\\n[pdf-img*autolabel]=1) \{\ +. if !\\n[pdf-img*have-caption] \ +. mla@error label caption \\n[.F] \\$0 \\n[.c] +. \} +. \} +. nr lead-pre-label \\n[.v] +. ev label +. evc IMG +. ie \\n[#PRINT_STYLE]=1 .TYPEWRITER +. el \{\ +. img*label-style +. vs \\n[.ps]u+\\n[pdf-img*label-autolead]u +. \} +. if \\n[pdf-img*label-with-chapter] \ +. ds chapno \\n[#CH_NUM]. +. PDF_IMG*SET_LABEL_QUAD \\*[pdf-img*label-quad] +. SIZESPECS +. nr pdf-img*label-lead-diff \\n[lead-pre-label]-\\n[.v] +. sp -.5+\\*[$CAP_HEIGHT]+\\n[pdf-img*label-lead-diff]u +. if !'\\*[pdf-img*label-space]'' .sp \\*[pdf-img*label-space] +. if \\n[pdfbx-running] \{\ +. in -(\\*[wt\\n[stack]])+\\*[gap\\n[stack]]u +. ll -(\\*[wt\\n[stack]])+\\*[gap\\n[stack]]u +. \} +. ie \\n[pdf-img*autolabel] \{\ +. nop \ +\\*[pdf-img*label-prfx]\\*[chapno]\\n+[fig*label-num]\\*[pdf-img*label-sffx]\| +. ds pdf-img*label \\*[chapno]\\n[fig*label-num] +. if dLABEL.REFS \ +. tm .ds \\*[target] \\*[chapno]\\n[fig*label-num] +. rm target +. \} +. el .if !'\\*[pdf-img*label]'' .nop \\*[pdf-img*label] +. fam +. ft +. ps +. if r pdfbx-running \{\ +. in +. ll +. \} +. gcolor +. if !'\\*[pdf-img*caption]'' \{\ +. if \\n[pdf-img*caption-after-label] \{\ +. ds pdf-img*caption-old \\*[pdf-img*caption] +. ds pdf-img*caption " \\*[pdf-img*caption] +. nop \\*[pdf-img*caption-specs]\\*[pdf-img*caption]\\*[revert-specs] +. ds pdf-img*caption \\*[pdf-img*caption-old] +. \} +. \} +. br +. ev +. in 0 +. \} +\!. in +. di +. nf +. vpt 0 +. if !'\\*[pdf-img:adj]'' \{\ +. if \\n[@TOP] \ +. if \\n[#COLUMNS]>1 \ +\!. rs +\!. sp \\*[pdf-img:adj] +. \} +. PDF*IMAGE +. if !'\\*[pdf-img:adj]'' \ +. if !\\n[@TOP] \!.sp -\\*[pdf-img:adj] +. vpt +. ev +. if \\n[pdf-img:float] \{\ +. FLOAT off +. nr dl \\n[pdf-img:width] +. \} +. if \\n[img*pdfbx] \{\ +. sp .5 +. nr img*pdfbx 2 +. \} +. if !\\n[pdf-img:float] \{\ +. ie !\\n[#NO_SHIM] \ +. if !\\n[pdf-img*no-shim] .SHIM +. el \ +. if !\\n[#NO_FLEX] \ +. if !\\n[pdf-img*no-flex] .FLEX +. \} +. PDF_IMAGE_CLEAN +.END +\# +\# PDF_IMAGE_FRAME +\# --------------- +\# *Arguments: +\# [ <inset> ] [ <rule weight> ] [ <color> ] +\# *Function: +\# Sets parameters for pdf image frames. +\# *Notes: +\# Defaults are '6p' '.5' 'black'. Arguments to be left at default +\# must be entered as "". +\# +.MAC PDF_IMAGE_FRAME END +. ie !'\\$1''\{\ +. ds frame-arg \\$1 +. substring frame-arg -1 +. ie \B'\\*[frame-arg]' \{\ +. tm1 "[mom]: \\$0 inset argument at line \\n[.c] +. tm1 " of '\\n[.F]' requires a unit of measure. +. tm1 " Default 6 point inset will be used instead. +. \} +. el \{\ +. nr pdf-img:frame-inset \\$1 +. shift +. \} +. \} +. el .shift +. ie !'\\$1'' \{\ +. ds frame-arg \\$1 +. substring frame-arg -1 +. ie \B'\\*[frame-arg]' \{\ +. ds pdf-img:frame-weight \\$1 +. shift +. \} +. el \{\ +. ds frame-arg \\$1 +. substring frame-arg -1 +. length arg-len \\*[frame-arg] +. if \\n[arg-len]=1 \{\ +. tm1 "[mom]: \\$0 rule weight argument at line \\n[.c] +. tm1 " of '\\n[.F]' must not have a unit of measure appended. +. tm1 " Default .5 rule weight will be used instead. +. shift +. \} +. \} +. \} +. el .shift +. if !'\\$1'' \{\ +. ie m \\$1 .ds pdf-img:frame-color \\$1 +. el \{\ +. tm1 "[mom]: \\$0 color argument '\\$1' at line \\n[.c] +. tm1 " of '\\n[.F]' is not a valid color. +. tm1 " Default black will be used instead. +. \} +. \} +.END +\# +.MAC PDF_IMAGE_CLEAN END +. rm PDF*IMAGE +. rm pdf-img:adj +. rm pdf-img*caption +. rm pdf-img*caption-short +. rm pdf-img:file +. rm pdf-img*label +. rm pdf-img:pos +. rm short +. rr ind-pre-img +. rr pdf-img:depth +. rr pdf-img:float +. if !\\n[pdf-img:frame] \ +. rr pdf-img:frame +. rr pdf-img:ind +. rr pdf-img:no-shim +. rr pdf-img:no-flex +. rr pdf-img:scale +. if !\\n[defer] \ +. rr pdf-img*have-caption +. rr pdf-img:frame-inset +. rr pdf-img:width +. if '\\*[pdf-img*label-sffx-tmp]'.' .ds pdf-img*label-sffx . +. it 1 rr-img*pdfbx +.END +\# +.de pdfmomclean +. ie '\\n[.z]'' \{\ +. ds pdfcleaned \\$* +. ev pdfcln +. tr \[em]- +. nf +. box pdf:clean +. nop \\*[\\*[pdfcleaned]] +. fl +. box +. chop pdf:clean +. asciify pdf:clean +. ev +. ds \\*[pdfcleaned] "\\*[pdf:clean] +. rm pdf:clean +. tr \[em]\[em] +. \} +. el .nop \!.pdfmomclean \\$@ +.. +\# +.MAC PAUSE END +. nr pdfbx-inhibit-space 1 +. if \\n[pdfbx-running] \{\ +. nr pdfbx-pause 1 +. rr pdfbx-inhibit-space +. BoxStop +. \} +. vpt 0 +. br +. vpt +. ie !'\\n[.z]'' \{\ +\!. pdfpause +\!. pdftransition BLOCK \\$1 +. \} +. el \{\ +. pdfpause +. pdftransition BLOCK \\$1 +. \} +. if \\n[pdfbx-pause] \{\ +. BoxStart \\*[pdfbx-args] +. rr pdfbx-pause +. rr pdfbx-inhibit-space +. \} +.END +\# +.MAC TRANSITION END +. ie !'\\n[.z]'' \ +\!. pdftransition PAGE \\$1 +. el .pdftransition PAGE \\$1 +.END +\# +\# Shaded backgrounds and frames (pdf boxes), page colour +\# +\# BOX +\# --- +\# *Arguments: +\# SHADED <color> | OUTLINED <color> \ +\# [ WEIGHT <wt> ] [ INSET <dist> ] \ +\# [ ADJUST +|-<amount> ] \ +\# [ EQN | PIC | GRAP | IMG ] +\# *Function: +\# Calls BoxStart with the supplied arguments or stops a running +\# box. +\# *Notes: +\# If OUTLINED given but no WEIGHT, the default weight is .5p. +\# Otherwise, args have no defaults. +\# +.MAC BOX END +. nr #FROM_BOX 1 +. ie \\n[#NUM_ARGS]=0 \ +. BoxStart SHADED grey85 INSET 1P +. el \{\ +. ie \\n[#NUM_ARGS]=1 .BoxStop +. el .BoxStart \\$* +. \} +. rr #FROM_BOX +.END +\# +\# PAGE COLOUR +\# ----------- +\# *Arguments: +\# <color> | OFF | off +\# *Function: +\# Sets pagefill to <color> or stops pagefill. +\# *Notes: +\# OFF|off is required instead of the usual <anything>. +\# +.MAC PAGE_COLOR END +. ie !'\\$1'OFF' \{\ +. ie !'\\$1'off' \{\ +. fcolor \\$1 +. device pdf: background pagefill +. \} +. el .device pdf: background off +. \} +. el .device pdf: background off +.END +\# +.ALIAS PAGE_COLOUR PAGE_COLOR +.ALIAS SLIDE_COLOR PAGE_COLOR +.ALIAS SLIDE_COLOUR PAGE_COLOR +\# +\# Begin or end a box; called from BoxStart +\# +.de pdfbackground +. device pdf: background \\$* +. if '\\$1'off' \{\ +. ie (\\n[stack]-1)=0 \{\ +. if \\n[.t]>(1.6v+(\\*[wt\\n[stack]]/2u)) \ +. sp \\*[wt\\n[stack]]/2u +. \} +. el \{\ +. nr pdfbx-container \\n[stack]-1 +. if \\n[.t]>=((\\*[wt\\n[stack]]/2u)+(\\*[gap\\n[pdfbx-container]])+(\\*[wt\\n[pdfbx-container]])) \ +. sp \\*[wt\\n[stack]]/2u +. \} +. \} +.. +\# +\# Input trap macros +\# +.de rr-pdfbx-top +. rr pdfbx-top +.. +\# +.de rr-pdfbx-end +. rr pdfbx-end +.. +\# +.de rr-pdfbxstop +. rr pdfbxstop +.. +\# +.de rr-pic*pdfbx +. rr pic*pdfbx +.. +\# +.de rr-tbl*pdfbx +. rr tbl*pdfbx +.. +\# +.de rr-img*pdfbx +. rr img*pdfbx +.. +\# +.de rr-pdfbx-post-q +. rr pdfbx-post-q +.. +\# +.de rr-pdfbx-div-start +. rr pdfbx-div-start +.. +\# +\# Heavy lifting macros called from BOX. +\# +.de BoxStart +. ds pdfbx-args \\$* +. if \\n[pdfbx-inhibit-space] .sp -1 +. rr pdfbx-inhibit-space +. if \\n[#PP_SPACE] \{\ +. nr restore-pp-space 1 +. PARA_SPACE off +. \} +. if \\n[#PRINT_STYLE]=1 \{\ +. tm1 "[mom]: PRINTSTYLE TYPEWRITE does not permit shaded backgrounds and frames. +. tm1 " Continuing to process without backgrounds or frames. +. return +. \} +. if \\n[#COLUMNS] \{\ +. tm1 "[mom]: Shaded backgrounds and frames are not available when COLUMNS are enabled. +. tm1 " Continuing to process without backgrounds or frames. +. return +. \} +. if \\n[Q-float]=1 .nr Q-float 2 +. if !'\\n[.z]'' \{\ +. nr pdfbx-div-start 1 +\!. it 1 rr-pdfbx-div-start +. \} +. if !\\n[#NO_SHIM] \{\ +. NO_SHIM +. nr pdfbx-restore-shim 1 +. \} +. if !\\n[#NO_FLEX] \{\ +. NO_FLEX +. nr pdfbx-restore-flex 1 +. \} +. if (\\n[#NO_SHIM]=0)&(\\n[#NO_FLEX]=1) .nr pdfbx-restore-shim 1 +. if (\\n[#NO_SHIM]=1)&(\\n[#NO_FLEX]=0) .nr pdfbx-restore-flex 1 +. rr shad +. rr outl +. rm wt +. rm pdfbx-adj +. nr pdfbx-running 1 +. nr pdfbx-top 1 +. nr stack +1 +. nr pdfbx-prev \\n[stack]-1 +. ds type " " +. ie r #FROM_BOX .ds calling-macro BOX +. el .ds calling-macro \\$0 +. while \\n[.$] \{\ +. if !'\\$1'SHADED' \ +. if !'\\$1'OUTLINED' \ +. if !'\\$1'WEIGHT' \ +. if !'\\$1'INSET' \ +. if !'\\$1'PIC' \ +. if !'\\$1'GRAP' \ +. if !'\\$1'EQN' \ +. if !'\\$1'IMG' \ +. if !'\\$1'ADJUST' \{\ +. tm [mom]: Invalid argument '\\$1' to \\*[calling-macro], line \\n[.c]. +. shift 1 +. \} +. if '\\$1'SHADED' \{\ +. nop \\M[\\$2]\c +. nr shad 1 +. chop type +. as type "fill" +. shift 2 +. \} +. if '\\$1'OUTLINED' \{\ +. nop \\m[\\$2]\c +. nr outl 1 +. chop type +. as type "box" +. shift 2 +. \} +. if '\\$1'WEIGHT' \{\ +. ds wt \\$2 +. shift 2 +. \} +. if '\\$1'INSET' \{\ +. nr gap \\$2 +. shift 2 +. \} +. if '\\$1'ADJUST' \{\ +. ds pdfbx-adj \\$2 +. shift 2 +. \} +. if '\\$1'PIC' \{\ +. ie '\\n[.z]'FLOAT*DIV' .nr PIC 2 +. el .nr PIC 1 +. shift 1 +. \} +. if '\\$1'GRAP' \{\ +. ie '\\n[.z]'FLOAT*DIV' .nr PIC 2 +. el .nr PIC 1 +. shift 1 +. \} +. if '\\$1'EQN' \{\ +. nr EQN 1 +. shift 1 +. \} +. if '\\$1'IMG' \{\ +. nr IMG 1 +. shift 1 +. \} +. \} +. if '\\*[type]' ' .ds type "fill " +. chop type +. if !r gap .nr gap 1P +. ie \\n[outl] \ +. if '\\*[wt]'' .ds wt .5p +. el .ds wt 0 +. if d pdfbx-adj .sp \\*[pdfbx-adj] +. if \\n[@TOP] \{\ +. RESTORE_SPACE +. sp -1 +. nr @TOP 1 +. \} +. nr pdfbxstop 1 \" Stop box in footer if .br causes a page break +. br +. if \\n[Q-float]=2 .sp -.5 +. rr pdfbxstop +. fl +. SIZESPECS +. ds pdfbx-cap-adj \\*[$CAP_HEIGHT] +.\" Top spacing +. if \\n[#EPIGRAPH]+\\n[#QUOTE]=0 \ +. if \\n[#START] .sp -2 +. if \\n[#EPIGRAPH] \{\ +. ie \\n[#START] \!.sp -2 +. el \!.sp -1.5 +. \} +. if \\n[#QUOTE] \{\ +. if !\\n[@TOP] \!.sp -.5-\\*[pdfbx-cap-adj] +. if \\n[#START] \!.sp .5+\\*[wt] +. rr @TOP +. \} +. if '\\n[.z]'FLOAT*DIV' \{\ +. if !\\n[#START] \!.sp -1 +. nr no-top-space:1 1 +. nr pdfboxed 1 +. \} +. if \\n[stack]=1 \{\ +. if \\n[#INDENT_LEFT_ACTIVE] .nr #IL_ACTIVE \\n[#L_INDENT] +. if \\n[#INDENT_RIGHT_ACTIVE] .nr #IR_ACTIVE \\n[#R_INDENT] +. if \\n[#INDENT_BOTH_ACTIVE] \{\ +. nr #IBL_ACTIVE \\n[#BL_INDENT] +. nr #IBR_ACTIVE \\n[#BR_INDENT] +. \} +. if \\n[#IN_ITEM] \ +. if \\n[#BR_INDENT] .nr #IBR_ACTIVE \\n[#BR_INDENT] +. \} +.\" Set l +. nr pdfbx-l \\n[#L_MARGIN] +. if \\n[#EPIGRAPH]=2 \{\ +. GET_EPI_OFFSET +. nr pdfbx-l \\n[#EPI_OFFSET] +. \} +. if \\n[#QUOTE]=2 \{\ +. ie \\n[#BQ_OFFSET_VALUE] \ +. nr pdfbx-l \\n[#L_MARGIN]+(\\n[#PP_INDENT]*\\n[#BQ_OFFSET_VALUE]) +. el \ +. nr pdfbx-l \\n[#L_MARGIN]+(\\*[$BQ_OFFSET_VALUE]) +. \} +. ie \\n[stack]=1 \ +. nr l \\n[pdfbx-l]+(\\*[wt]/2)+\\n[#IL_ACTIVE]+\\n[#IBL_ACTIVE] +. el .nr l +(\\*[wt\\n[pdfbx-prev]]/2)+\\*[gap\\n[pdfbx-prev]]+(\\*[wt]/2) +.\" Set r +. nr r \\n[pdfbx-l]+\\n[.l]-(\\*[wt]/2u) +. if \\n[#QUOTE]=1 .nr r \\n[pdfbx-l]+\\n[#L_LENGTH]-(\\*[wt]/2) +. if \\n[#IR_ACTIVE] .nr r \\n[pdfbx-l]+\\n[#L_LENGTH]-\\n[#IR_ACTIVE]-(\\*[wt]/2) +. if \\n[#IBR_ACTIVE] .nr r \\n[pdfbx-l]+\\n[#L_LENGTH]-\\n[#IBR_ACTIVE]-(\\*[wt]/2) +.\" Set t +. ie \\n[stack]=1 .nr t \\n[#T_MARGIN]+(\\*[wt]/2) +. el .nr t +(\\*[wt\\n[pdfbx-prev]]/2)+\\*[gap\\n[pdfbx-prev]]+(\\*[wt]/2) +.\" Set b +. nr b \\n[.p]+\\n[#VARIABLE_FOOTER_POS]-(\\*[wt]/2)+\\n[#DOC_LEAD]u +.\" Clear indents +. if \\n[stack]=1 \{\ +. nr pdfbx-clear 1 +. ILX CLEAR +. IRX CLEAR +. if !\\n[#QUOTE]=2 \ +. if !\\n[#EPIGRAPH]=2 \ +. IBX CLEAR +. if \\n[#IR_ACTIVE] .nr pdfbx-pre-ll \\n[#L_LENGTH] +. rr pdfbx-clear +. \} +.\" See if box fits +.\" PIC and IMG are in floats, which take care of fit/defer. +. if (\\n[PIC]=0)&(\\n[IMG]=0) \{\ +. if '\\n[.z]'' \{\ +. nr pdfbx-min \ + (\\*[wt]*2)+\\*[pdfbx-cap-adj]+(\\n[gap]*2) +. if r EQN .nr pdfbx-min +1v +. if \\n[.t]<\\n[pdfbx-min] \{\ +. rr pdfbx-running +. bp +. nr pdfbx-running 1 +. RESTORE_SPACE +. \} +. \} +. \} +.\" FOOTER trap +. if !r #VFP0 .nr #VFP0 \\n[#VARIABLE_FOOTER_POS] +. nr #VFP\\n[stack] 0\\n[#VFP\\n[pdfbx-prev]]-\\*[wt]-\\n[gap] +. nr #VARIABLE_FOOTER_POS 0\\n[#VFP\\n[stack]] +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u +. mk +. sp \\*[wt]/2u +. +. pdfbackground \\*[type] \\n[l]z \\n[t]z \\n[r]z \\n[b]z \\*[wt] +. +.\" Always start at wt+gap +. ie \\n[#IL_ACTIVE]:\\n[#IBL_ACTIVE] \ +. IL \\n[gap]u+\\*[wt]+\\n[#IL_ACTIVE]u+\\n[#IBL_ACTIVE]u +. el .IL \\n[gap]u+\\*[wt] +. ie \\n[#IR_ACTIVE]:\\n[#IBR_ACTIVE] \ +. IR \\n[gap]u+\\*[wt]+\\n[#IR_ACTIVE]u+\\n[#IBR_ACTIVE]u +. el .IR \\n[gap]u+\\*[wt] +. nr pdfbx-ll \\n[.l] +. rt +. sp \\*[wt]+\\*[pdfbx-cap-adj]+\\n[gap]u +. if (\\n[shad]=1) .nop \\M[]\c +. if (\\n[outl]=1) .nop \\m[]\c +. ds gap\\n[stack] \\n[gap] +. ds wt\\n[stack] \\*[wt] +. rm wt type +. it 2 rr-pdfbx-top +.. +\# +.de BoxStop +. if \\n[#PRINT_STYLE]=1 .return +. if \\n[#COLUMNS]=1 .return +. if \\n[#QUOTE]=1 .nr pdfboxed 1 +. if \\n[pdfbx-end]=\\n[nl] \{\ +. ie !'\\n[.z]'FLOAT*DIV' .nr pdfbxstop-consec 1 +. el \ +\!. if '\\n[.z]'FLOAT*DIV' .nr pdfbxstop-consec 1 +. rr pdfbx-end +. \} +. nr pdfbxstop 1 \" Stop box in footer if EOL causes a page break +. if !'\\n[.z]'' \!.nr pdfbxstop 1 +. EOL +. rr pdfbxstop +. if (\\n[.ns]+\\n[@TOP])>0 .RESTORE_SPACE +. nr pdfbx-prev \\n[stack]-1 +. nr #VARIABLE_FOOTER_POS 0\\n[#VFP\\n[pdfbx-prev]] +. if \\n[stack]=1 \{\ +. if !\\n[#FN_COUNT] .nr #VARIABLE_FOOTER_POS 0-\\n[#B_MARGIN] +. \} +. ch FOOTER \\n[#VARIABLE_FOOTER_POS]u +. if !'\\n[.z]'' \!.ch FOOTER \\n[#VARIABLE_FOOTER_POS]u +. ie !r pdfbxstop-consec \{\ +. sp \\*[gap\\n[stack]]u+(\\*[wt\\n[stack]]/2u) +. if r tbl*pdfbx \{\ +. if \\n[tbl*pdfbx]=1 .sp -.6 +. if \\n[tbl*pdfbx]=2 .sp -.6-1p +. if \\n[tbl*pdfbx]=3 .sp -.6+1.5p +. \} +. if r eqn*pdfbx \{\ +. if \\n[eqn*pdfbx]=1 .sp -.75 +. if \\n[eqn*pdfbx]=2 .sp -.5 +. rr eqn*pdfbx +. \} +. \} +. el \{\ +. sp +. if r pdfbx-post-space .sp -\\n[pdfbx-post-space]u +. rr pdfbx-post-space +. sp (\\*[wt\\n[stack]]/2u)+\\*[gap\\n[stack]]u +. if \\n[.t]<(\\*[wt\\n[stack]]+\\*[gap\\n[stack]]) \{\ +. nr pdfbx-container \\n[stack]+1 +. sp \\*[wt\\n[pdfbx-container]]/2u +. \} +. \} +. if \\n[pic*pdfbx]=2 \ +. sp -.5 +. if \\n[grap] \ +. if \\n[pic*have-label] \ +. sp .5 +. if \\n[img*pdfbx]=2 \ +. sp -.5 +. +. pdfbackground off +. +. EOL +. if \\n[.t]<1v \{\ +. nr pdfbxstop 1 \" Stop box in footer if .br causes a page break +. br +. \} +. if \\n[pdfbx-pause] .sp -2 +. if \\n[pic*pdfbx] \ +. if \\n[pic*have-label] .sp .5 +. IL -(\\*[gap\\n[stack]]u+\\*[wt\\n[stack]]) +. IR -(\\*[gap\\n[stack]]u+\\*[wt\\n[stack]]) +.\" Bottom spacing +.\" If the .sp or .br in the ie/el clause causes a break, tell +.\" HEADER to skip the PDF boxes stanza. +. nr pdfbxstop 1 +. if !'\\n[.z]'' \!.nr pdfbxstop 1 +. if '\\n[.z]'FLOAT*DIV' .if \\n[float*tbl] .sp -.5 +. ie \\n[.t]>1v \{\ +. nr pdfbx-post-space 1.6v +. if \\n[#EPIGRAPH] \ +. nr pdfbx-post-space .6v +. \} +. el .br +. rr pdfbxstop +. if '\\n[.z]'FLOAT*DIV' \!.rr pdfbxstop +. sp \\n[pdfbx-post-space]u +. if \\n[pic*pdfbx] \ +. sp -.5 +. if \\n[img*pdfbx] \ +. sp -.5 +. if \\n[#QUOTE] .sp -.5+(\\*[wt\\n[stack]]/2u) +. nr pdfbx-end \\n[nl] +. it 2 rr-pdfbx-end +. rr pdfbxstop-consec +. ie '\\n[.z]'' .rr pdfbx-running +. el \{\ +\!. rr pdfbx-running +\!. nr pdfbx-defer 1 +. \} +. ie '\\n[.z]'' .nr stack \\n[stack]-1 +. el \{\ +\!.nr stack-for-float \\n[stack] +\!.nr stack \\n[stack]-1 +. \} +. if \\n[pic*pdfbx] .rr pic*pdfbx +. if \\n[tbl*pdfbx] .rr tbl*pdfbx +. if \\n[img*pdfbx] .rr img*pdfbx +. if \\n[stack]=0 \{\ +. ILX CLEAR +. IRX CLEAR +. IBX CLEAR +. if \\n[#IL_ACTIVE] \{\ +. nr #L_INDENT \\n[#IL_ACTIVE] +. IL +. rr #IL_ACTIVE +. \} +. if \\n[#IR_ACTIVE] \{\ +. nr #R_INDENT \\n[#IR_ACTIVE] +. ll \\n[pdfbx-pre-ll]u +. IR +. rr pdfbx-pre-ll +. rr #IR_ACTIVE +. \} +. if \\n[#IBR_ACTIVE] \{\ +. ll \\n[pdfbx-pre-ll]u +. IB \\n[#IBL_ACTIVE]u \\n[#IBR_ACTIVE]u +. rr pdfbx-pre-ll +. rr #IBR_ACTIVE +. rr #IBL_ACTIVE +. \} +. if r PIC \{\ +. rr pic*pdfbx +. rr PIC +. \} +. if r EQN \{\ +. rr eqn*pdfbx +. rr EQN +. \} +. if r IMG \{\ +. rr img*pdfbx +. rr IMG +. \} +. \} +. if '\\n[.z]'P_QUOTE' \{\ +. nr pdfbx-post-q 1 +. it 2 rr-pdfbx-post-q +. \} +. if d pdfbx-adj .rm pdfbx-adj +. if \\n[restore-pp-space] \{\ +. rr restore-pp-space +. PARA_SPACE +. \} +. if \\n[pdfbx-restore-shim] \{\ +. NO_SHIM off +. rr pdfbx-restore-shim +. \} +. if \\n[pdfbx-restore-flex] \{\ +. NO_FLEX off +. rr pdfbx-restore-flex +. \} +. ie '\\n[.z]'' \{\ +. if \\n[stack]=0 \{\ +. rr #VFP0 +. if !\\n[#NO_SHIM] .SHIM +. if !\\n[#NO_FLEX] .FLEX +. \} +. \} +. el \{\ +\!. if (\\\\n[stack]=0) \{\ +. rr #VFP0 +. if !r #EPIGRAPH \!.SHIM +. \} +. \} +.. +\# +\# Local Variables: +\# mode: nroff +\# End: +\# vim: filetype=groff: diff --git a/contrib/pdfmark/ChangeLog b/contrib/pdfmark/ChangeLog new file mode 100644 index 0000000..1c5a18f --- /dev/null +++ b/contrib/pdfmark/ChangeLog @@ -0,0 +1,683 @@ +2023-02-18 G. Branden Robinson <g.branden.robinson@gmail.com> + + * pdfmark.am (uninstall-pdfmark-hook): Simplify uninstallation. + Try to remove the configured `pdfdocdir` in the event it is + empty, but do not fail if it isn't. (It can be a directory + shared with other groff components; we don't know in what order + the uninstall targets will serialize, but the last one run + should succeed.) + +2022-09-20 G. Branden Robinson <g.branden.robinson@gmail.com> + + * sanitize.tmac: Move comment to where escape sequences are + recognized. Problem arose in commit 058b63ce3d, 2021-09-04. + + troff:.../contrib/pdfmark/sanitize.tmac:162: warning: macro '\"' + not defined + +2022-05-20 G. Branden Robinson <g.branden.robinson@gmail.com> + + * pdfmark.am: Rename `BUILD_PDFDOC` to `USE_GROPDF`. + +2022-03-30 G. Branden Robinson <g.branden.robinson@gmail.com> + + * pdfmark.am: Eliminate `PDFMARK_TFLAG` and `PDFMARK_PFLAG` Make + macros; they were expanded in only one place. + (PDFROFF): Track rename of Make macro `TFLAG` to `MFLAG`. + +2022-03-30 G. Branden Robinson <g.branden.robinson@gmail.com> + + * cover.ms: Die horribly if `PSPIC` call fails. + +2022-03-26 G. Branden Robinson <g.branden.robinson@gmail.com> + + * pdfmark.am (PDFDOCFILES): Replace hard-coded "gnu.eps" + file name with expansion of `DOC_GNU_EPS`. + (contrib/pdfmark/pdfmark.pdf): Pass `-I` option to pdfroff(1) to + enable location of "gnu.eps" file. + +2021-10-24 Keith Marshall <keith.d.marshall@ntlworld.com> + + Adapt to accommodate global XH and XN implementations. + + cf. <https://savannah.gnu.org/bugs/?58946#comment13> + + * spdf.tmac (XH-INIT, XN-INIT, XH-UPDATE-TOC): Delete definitions; + the defaults, provided by s.tmac, are now sufficient. + (XH-REPLACEMENT, XN-REPLACEMENT): Define these, rather than... + (XH, XN): ...these, respectively. + +2021-10-02 Keith Marshall <keith.d.marshall@ntlworld.com> + + Make a minor layout adjustment. + + * pdfmark.ms (Section 2.4.3): Add a vertical space reservation, to + avoid a widow line at the end of the paragraph explaining use of... + (PDFHREF.Y): ...this computed register, in the definition of... + (PDFBOOKMARK.VIEW): ...this. + +2021-10-02 Keith Marshall <keith.d.marshall@ntlworld.com> + + Clarify references to use of the -Tpdf option. + + * pdfmark.ms (Section 2, Section 3.1): Add footnotes, indicating that + only "-Tps" and "-Tpdf" output formats are supported, and that "-Tpdf" + may avoid a separate step, to convert from PostScript to PDF. + +2021-10-02 Keith Marshall <keith.d.marshall@ntlworld.com> + + Work around misplacement of link "hot-spots" in footnotes. + + * pdfmark.ms (pdfhref-nobreak): New document-local macro; used instead + of "pdfhref", this forces paragraph adjustment before placement of any + unbreakable link text, for which line-wrap may be required. Currently + observed only within footnotes, without adjustment, the "hot-spot" for + the link may be placed 1v above its associated text. + +2021-10-02 Keith Marshall <keith.d.marshall@ntlworld.com> + + Link footnote reference marks to footnote text. + + * pdfmark.ms (FP): Redefine locally; replace s.tmac default. + (FF): Do not redefine; our FP replacement macro does not use it. + [d FS-MARK] (FS-MARK): Redefine locally; map it to... + (pdf:fn.mark): ...this locally defined macro. + [!d FS-MARK] (@FS): Rename s.tmac implementation as... + (pdf:fn.record): ...this, then redefine @FS itself, to call... + (pdf:fn.mark, pdf:fn.record): ...these, in respective order. + (groff-1.19.1, GhostScript-8.14): Update footnote reference syntax. + (Ghostscript-8.14, MSYS): Emulate sentence space after footnote mark. + (*): Replace s.tmac string definition; make it equivalent to "\c", + after renaming its original implementation as... + (pdf:fn.index): ...this; synchronize references with changes to... + (pdf:fn.index.count): ...this new locally defined register; it is + auto-incremented by one, as each footnote is placed. + +2021-10-01 Keith Marshall <keith.d.marshall@ntlworld.com> + + Incorporate user-defined TOC leader style. + + * pdfmark.ms: Make some comment tidy-up adjustments. + (TC-LEADER, TC-MARGIN): Define them, to take advantage of new + s.tmac features; cf. <https://savannah.gnu.org/bugs/?61157>. + +2021-09-18 Keith Marshall <keith.d.marshall@ntlworld.com> + + Factor a further unnecessary macro out of spdf.tmac + + * spdf.tmac (XR): Remove it; relocate it to... + * pdfmark.ms (XR): ...here. + +2021-09-13 Keith Marshall <keith.d.marshall@ntlworld.com> + + Add comments to annotate locally-defined font change macros. + + * pdfmark.ms (EM): Annotate this locally-defined emphasis macro... + (CWB, CWI, CWBI): ...these constant width font interpolation macros... + (=): ...and this locally-defined IP tag variant string. + +2021-09-13 Keith Marshall <keith.d.marshall@ntlworld.com> + + Update defunct internet URL references. + + * pdfmark.ms (pdfmark-manual): Adobe moved the document (again); + update the document reference macro, to follow the URL relocation. + (www.mingw.org): The MinGW Project has relinquished this domain; + update the URL reference, to follow web-site relocation to... + (mingw.osdn.io): ...here. + +2021-09-13 Keith Marshall <keith.d.marshall@ntlworld.com> + + Factor document-specific bloat out of spdf.tmac + + * spdf.tmac: Reorganize; add many comments. + (XN): Retained, but reimplemented, to serve as... + (XH, XN): ...both of these; add callback hooks for... + (XH-INIT, XN-INIT, XH-UPDATE-TOC): ...these; provide no-op stubs; + factor out TOC collection code, delegating to XH-UPDATE-TOC. + (opt*XN-N, opt*XN-S, opt*XN-X): Rename internal macros to... + (de spdf:XH-N, de spdf:XH-S, de spdf:XH-X): ...these, respectively. + (AN, @AN, IE, IS, LU, NN, PXREF, SAME-PAGE, XM): Delete; we do not + require these; if users do, they should define their own. + (pdf@toc): Delete internal macro; fold body into... + (TC): ...this. + + * pdfmark.ms (XH-UPDATE-TOC): Implement callback; it is based on... + (XN): ...original implementation of this, factored out of spdf.tmac, + but with significant simplification, to remove unnecessary code. + (XNVS1, XNVS2, XNVS3): Tighten vertical spacing. + +2021-09-04 Keith Marshall <keith.d.marshall@ntlworld.com> + + Reduce potential for user-space exposure of "ms" internals. + + * spdf.tmac (@NH): Append to s.tmac macro; assign... + (spdf:nh*hl): ...this new internal register; alias it to... + (.NH): ...this new public name, hence making it track... + (nh*hl): ...this s.tmac internal numeric register. + (XN): Use \n[.NH] instead of \n[nh*hl]. + +2021-09-03 Keith Marshall <keith.d.marshall@ntlworld.com> + + Sanitize text for use in PDF document outlines. + + * sanitize.tmac: New file; it implements... + (sanitize): ...this new macro; interprets its first argument as a + string name, and copies its remaining arguments to the named string, + discarding specific embedded troff escape sequences; currently... + (\F): ...only this is identified as "specifically discardable". + + * pdfmark.am (TMACFILES): Add sanitize.tmac + + * spdf.tmac (mso): Include sanitize.tmac + (xn*ref, xn*argc): Rename all occurrences... + (spdf:refname, spdf:argc): ...to these, respectively. + (XN): Stop inserting $* directly into PDF outlines; instead, use... + (spdf:bm.text): ...this new string; this is locally defined by... + (spdf:bm.define): ...this new macro; passed the original $* from + XN, this itself, is locally defined as a redirectable alias for... + (spdf:bm.basic): ...this new local macro; it simply copies $*, + passed from XN, to the string named by its first argument, (which is + always spdf:bm.text), so reproducing previous behaviour. + (opt*XN-S): New macro; defined for internal use only, it adds a "-S" + option to XN, such that, when specified, it temporarily redirects... + (spdf:bm.define): ...this macro mapping alias to... + (sanitize): ...this. + + * pdfmark.ms (XN): Add "-S" option for all headings which include... + (\F[C]...\F[]): ...this escape sequence. + +2021-08-21 Keith Marshall <keith.d.marshall@ntlworld.com> + + Define, and use registered trade mark strings. + + * pdfmark.ms (Adobe, Acrobat, Distiller, PostScript, Microsoft): + Define as strings. Each expands to its own name, followed by the + registered trademark symbol, as a superscript, and optional trailing + punctuation, below the superscript. Use each as required. + +2021-08-21 Keith Marshall <keith.d.marshall@ntlworld.com> + + Prefer "-ize" to "-ise" where etymology permits. + + * pdfmark.ms: For all verbs, and their derivative nouns, for which + British English allows either "-ise" or "-ize" as ending, prefer the + "-ize" form of verb, and "-ization" form of noun, throughout. + +2021-08-20 Keith Marshall <keith.d.marshall@ntlworld.com> + + Correct a spelling error. + + * pdfmark.ms (Section 2.5.3.1): Fix typo: s/exanple/example/. + +2021-08-20 Keith Marshall <keith.d.marshall@ntlworld.com> + + Space out section headings in pdfmark.ms source. + + * pdfmark.ms (.NH): Precede each instance by one null request, to + improve readability. + +2021-08-18 Keith Marshall <keith.d.marshall@ntlworld.com> + + Refine pdfroff "missing ghostscript" diagnostic. + + * pdfroff.sh [$GS = ":"]: Fix typo: s/connot/cannot/; refine text. + +2020-12-25 G. Branden Robinson <g.branden.robinson@gmail.com> + + * pdfmark.am (PDFROFF): Call pdfroff without + `--keep-temporary-files` option. Temporary directories are + created with mktemp(1) and files with an embedded process + identifier, which frustrates reproducible builds. + + See <https://savannah.gnu.org/bugs/?57218>. + +2018-02-28 Werner LEMBERG <wl@gnu.org> + + * pdfmark.am (pdfmark.pdf): Use $(GROFF_V). + +2018-02-28 Werner LEMBERG <wl@gnu.org> + + * pdfmark.am (pdfroff): Use $(AM_V_GEN) to silence file generation. + +2015-08-22 Bernd Warken <groff-bernd.warken-72@web.de> + + * pdfroff.1.man: Rename `pdfroff.man'. + + * pdfmark.am: Add `Last update'. Setup Emacs mode. + +2015-08-05 Bernd Warken <groff-bernd.warken-72@web.de> + + * pdfmark.am: Add `Last update'. Setup Emacs mode. + +2015-04-03 Werner LEMBERG <wl@gnu.org> + + * pdfroff.man: Make it work in compatibility mode. + +2014-10-14 Keith Marshall <keith.d.marshall@ntlworld.com> + + Deduce "--no-toc-relocation" from input stream (revisited). + + * pdfroff.sh (WRKFILE): Correct malformed sed expression. + + * spdf.tmac (TC): Prefer value of pdfroff's PHASE register to defined + state of pdf:href.map, when choosing to emit control record to... + (toc_relocation): ...enable this. + +2014-10-13 Keith Marshall <keith.d.marshall@ntlworld.com> + + Deduce "--no-toc-relocation" from input stream. + + * pdfroff.sh (WRKFILE): Scan it for "pdfroff-option:set" records; + apply settings; check for equivalent of "--no-toc-relocation" option. + + * spdf.tmac (TC): Emit "pdfroff-option:set toc-relocation=enabled". + +2014-10-12 Keith Marshall <keith.d.marshall@ntlworld.com> + + Avoid spurious user visible control messages on stderr. + + * pdfroff.sh (REFCOPY): Ensure that at least one pdfhref mark of type + 'Z' will remain in the reference map, after all references have been + resolved; this is required, to suppress writing of reference control + records to stderr during the final PDF output processing phase. + +2014-09-04 Bernd Warken <groff-bernd.warken-72@web.de> + + * all pdfmark source files: Copying (remove last updates and + replace years with package years) and Emacs setup. + +2014-03-30 Steffen Nurpmeso <sdaoden@yandex.com> + + * Makefile.sub: Put straight error-prevention prefixes for `rm'. + +2014-03-29 Steffen Nurpmeso <sdaoden@yandex.com> + + * Makefile.sub: Handle examples separately, controlled by + $(make{_,_install_,_uninstall_}examples). + +2013-01-28 Deri James <deri@chuzzlewit.myzen.co.uk> + + * pdfmark.tmac (pdfmark, pdf:composed): Use `\!' instead of `\X'. + + With the old pdfmark there are gaps between two of the lines, but + with the new version they disappear. The use of `.br' and `.in 0' + is arbitrary any request which causes an implicit break could be + used. Two breaks together only produce one line break, but if there + is an intervening `\X' then the second break finds the line buffer + not empty and generates another line break. + + Using `\!' does alter the position of the pdfmark lines in the + intermediate file sent to grops (the pdfmark lines are output + immediately rather than being serialised through the output line + processing), but this has no effect since the contents of the + pdfmark line stay the same. It is the contents which determine + where bookmarks jump to not the position of the record in the input + stream to grops. + + I initially used `.output', but hit a snag if a pdfbookmark occurs + before the document starts to output (message saying to insert an + explicit `.br'), this is quite likely for things like `.pdfinfo + /Author' which occur at the top of the document. So I'm using the + `\!' escape. + +2012-09-20 Werner LEMBERG <wl@gnu.org> + + Simplify enviroment handling. + + Suggested by Ivan Shmakov <oneingray@gmail.com>. + + * Makefile.sub (PDFROFF): Don't use export. + +2011-12-26 Mike Frysinger <vapier@gentoo.org> + + Fix parallel build race failure. + + Sometimes building in parallel will fail in the pdfmark directory: + + make[2]: Entering directory '.../contrib/pdfmark' + rm -f pdfroff + rm -f pdfmark.pdf + sed -f ... ./pdfroff.sh >pdfroff + ...; ./pdfroff ... pdfmark.ms >pdfmark.pdf + /bin/sh: ./pdfroff: Permission denied + chmod +x pdfroff + make[2]: *** [pdfmark.pdf] Error 126 + + This is because the generated pdf files use the local generated + pdfroff helper script, but they don't depend directly upon it, so + make tries to create the two in parallel and randomly falls over. + + * Makefile.sub: Have all the .pdf files explicitly depend on the + `pdfroff' helper script. + +2010-12-23 Keith Marshall <keith.d.marshall@ntlworld.com> + + Update copyright notices; pdfmark.tmac bug-fix. + + * pdfmark.tmac: Update copyright notices. + (pdf*href.mark.resolve): Avoid premature removal, by aliasing to... + (pdf*href.mark.begin): ...this, rather than renaming. + + * pdfroff.sh, pdfroff.man: Update copyright notices. + +2010-12-14 Keith Marshall <keith.d.marshall@ntlworld.com> + + Clean up handling of temporary files directory. + + * .cvsignore (pdfroff-*): Ignore sub-directories matching this. + * Makefile.sub (MOSTLCLEANDIRADD): Schedule them for removal. + +2010-12-02 Keith Marshall <keith.d.marshall@ntlworld.com> + + Address potential temporary file security vulnerabilities. + + * pdfroff.sh (GROFF_TMPDIR): Use mktemp(1) to assign it, if possible; + fall back to ${TMPDIR}, ${TMP} or ${TEMP} if unsuccessful. + * pdfroff.man: Document it. + +2009-08-16 Colin Watson <cjwatson@debian.org> + + Make pdfroff's GhostScript invocation safer. + + * pdfroff.sh (PDFROFF_POSTPROCESSOR_COMMAND): Add `-dSAFER' option. + * pdfroff.man: Document it. + +2008-12-28 Keith Marshall <keith.d.marshall@ntlworld.com> + + Avoid phantom line wrapping in pdfhref hot-spots. + + * pdfmark.tmac (pdf*href.mark.end): Emit hot-spot end markers within + scope of `\Z', to prevent possible output line length overflow which + may occur only in the layout computation passes, but not in the final + output pass. Problem observed and identified by Nick Stoughton; it + causes some hot-spots to be displaced from their proper locations. + +2007-04-11 Keith Marshall <keith.d.marshall@ntlworld.com> + + Avoid stray newlines in folded pdfmark literal content. + + * pdfmark.tmac (pdf*pdfmark.dispatch.wrapped): New string; define it + when accumulating long literal content; make it undefined otherwise. + (PDFMARK.FOLDWIDTH, PDFMARK.FOLDWIDTH.MAX): Reserve space for two + extra characters, to accommodate a space and an escaped newline, + while accumulating literal content, in case folding is required. + (pdf*pdfmark.dispatch) [pdf*pdfmark.dispatch.wrapped]: Add them. + +2007-04-11 Keith Marshall <keith.d.marshall@ntlworld.com> + + * pdfmark.tmac (pdfbookmark): Don't evaluate within diversions; defer + placement until diversion is copied out at top level. + +2007-02-06 Eric S. Raymond <esr@snark.thyrsus.com> + + * pdfroff.man: Update .UR/.UE and .MT/.ME to latest changes in + an-ext.tmac. + +2007-01-30 Werner LEMBERG <wl@gnu.org> + + * pdfroff.man: Updated. + +2007-01-21 Werner LEMBERG <wl@gnu.org> + + * pdfroff.man: Revised, based on a patch from Eric Raymond. It now + uses the new macros from an-ext.tmac. This is the first of a series + of man patches which Eric has contributed. + +2006-07-30 Keith Marshall <keith.d.marshall@ntlworld.com> + + * pdfroff.sh (PDFROFF_KILL_NULL_PAGES): Require `%%BeginPageSetup' on + PostScript output line immediately following `%%Page:'. + +2006-07-29 Keith Marshall <keith.d.marshall@ntlworld.com> + + * pdfroff.sh (PDFROFF_KILL_NULL_PAGES): Require `sed' to match a more + explicit regular expression, for detection of redundant pages. + +2006-07-14 Keith Marshall <keith.d.marshall@ntlworld.com> + + * pdfroff.sh (PDFWRITE): Local shell variable replaced... + (PDFROFF_POSTPROCESSOR_COMMAND): by this new environment variable... + (GROFF_GHOSTSCRIPT_INTERPRETER): with this bound to it. + (PDFROFF_COLLATE, PDFROFF_KILL_NULL_PAGES): New environment variables. + (--no-kill-null-pages): New command line option; implement it, and... + (--help): Add description for it. + + * pdfroff.man (PDFROFF_POSTPROCESSOR_COMMAND): Document it. + (PDFROFF_COLLATE, PDFROFF_KILL_NULL_PAGES): Document them. + (--no-kill-null-pages): Document it. + +2006-07-14 Zvezdan Petkovic <zpetkovic@acm.org> + + * pdfroff.sh (--emit-ps): New command line option; implement it. + (--help): Add description for it. + + * pdfroff.man (--emit-ps): Document it. + +2006-06-11 Werner LEMBERG <wl@gnu.org> + + * pdfroff.man: Add `.ig' block after NAME section to make mandb + happy. + +2006-03-31 Keith Marshall <keith.d.marshall@ntlworld.com> + + Split `pdfmark' output as required, to avoid excessively long + `ps:exec' intermediate output records. + + * pdfmark.tmac (pdfmark): Macro extended to deploy ... + (pdf*pdfmark.limit): New macro; use it to define ... + (PDFMARK.FOLDWIDTH, PDFMARK.FOLDWIDTH.MAX): New registers. + (pdf*compose.first, pdf*compose.next, pdf*compose.literal): New + macros; each will be aliased as required to ... + (pdf*compose): ... this, to dynamically construct ... + (pdf:composed.line, pdf:composed.literal): ... these new strings. + (pdf:compose.test): New dynamically constructed string; use it to + detect parenthesised literals in pdfmark content, so folding can be + avoided within them, subject to honouring of `PDFMARK.FOLDWIDTH'. + (pdf*length.increment): New macro; it triggers output folding when ... + (pdf:length): ... this new register exceeds `PDFMARK.FOLDWIDTH.MAX'. + (pdf*pdfmark.post.first, pdf*pdfmark.post.next): New macros; each will + be aliased as required to ... + (pdf*pdfmark.post): ... this, and invoked by ... + (pdf*pdfmark.dispatch): ... this new macro; use it to define ... + (pdf:composed): ... this dynamically constructed macro; use ... + (pdf*end): ... this new macro to terminate it. + +2006-03-09 Keith Marshall <keith.d.marshall@ntlworld.com> + + Incorporate portability recommendations by Ralf Wildenhues + <ralf.wildenhues@gmx.de> + + * pdfroff.sh: Avoid unsafe quoting in variable substitutions of + the form "${VAR+"set"}"; remove outer quotes everywhere; prefix + with `x' on each side of comparisons. + ($NULLCMD): Define when `$ZSH_VERSION' is set, i.e. when host + has `/bin/sh -> zsh'; also... + (emulate sh): Invoke, for this case. + + Enhancement/bug fix requested by Werner LEMBERG <wl@gnu.org> + + * pdfroff.sh (--help): Direct output to `stdout', not `stderr'. + (--keep-temporary-files): New option; implement it. + + * pdfroff.man (OPTIONS): Document `--keep-temporary-files' option. + (FILES): Note names and purpose of files it affects. + + * Makefile.sub (PDFROFF): Add `--keep-temporary-files' option; + retain them in `GROFF_TMPDIR=.'. + (CLEANADD): Include temporary files matching `pdf[0-9]*'. + +2006-03-08 Werner LEMBERG <wl@gnu.org> + + * pdfmark.ms: Update URL for Adobe Reference Manual. + +2006-02-26 Claudio Fontana <claudio@gnu.org> + + * Makefile.sub: Add DESTDIR to install and uninstall targets + to support staged installations. + +2006-02-25 Werner LEMBERG <wl@gnu.org> + + * pdfmark.ms: Correct typo; reported by Thomas Klausner. + +2006-02-24 Werner LEMBERG <wl@gnu.org> + + * pdfmark.ms, pdfroff.sh: Replace legal/illegal with valid/invalid. + +2005-06-22 Keith Marshall <keith.d.marshall@ntlworld.com> + + pdfroff.sh portability enhancement. + + * pdfroff.sh (ARGLIST): Variable removed. + (GROFF_STYLE): Use it for all groff invocations. + (INPUT_FILES): Pass to all groff invocations, instead of ARGLIST. + (CS_MACRO, CE_MACRO): Initialize independently. + (CS_FILTER): Simplify quoting; it used to confuse some shells. + (Source): CVS keyword removed; replaced by... + (RCSfile, Revision): these. + +2005-06-17 Keith Marshall <keith.d.marshall@ntlworld.com> + + * pdfroff.sh (MATCH): Correct quoting. + (Source): Add terminating `$' on CVS keyword. + +2005-06-17 Zvezdan Petkovic <zpetkovic@acm.org> + + * Makefile.sub: (RM): Define as `rm -f', for `make' programs + which don't predefine it. + +2005-06-16 Bernd Warken <groff-bernd.warken-72@web.de> + + * pdfroff.sh (NULLDEV): Correct misspelled instance of NULDEV. + +2005-05-28 Werner LEMBERG <wl@gnu.org> + + * Makefile.sub (.ms.pdf): Use `--stylesheet', not `--style'. + +2005-05-26 Werner LEMBERG <wl@gnu.org> + + * Makefile.sub, pdfmark.tmac, pdfroff.sh, spdf.tmac: Update postal + address for Free Software Foundation. + +2005-05-17 Keith Marshall <keith.d.marshall@ntlworld.com> + + Improve portability of `pdfroff' shell script. + + * pdfroff.sh: Add space in shebang, conforming to portability + guidelines in `autoconf' docs. + (searchpath): New shell function; use it instead of `type' command + to locate prerequisite helper programs. + + * pdfroff.man: Document influence of `OSTYPE' and `PATH_SEPARATOR' + environment variables. + + * Makefile.sub (pdfroff): Make it depend on SH_DEPS_SED_SCRIPT, + from arch/misc/shdeps.sh; use it to customize PATH_SEPARATOR + initialization code for `searchpath' function in pdfroff.sh. + +2005-05-16 Keith Marshall <keith.d.marshall@ntlworld.com> + + Interim documentation update. + + * pdfmark.ms (GROFF-WEBSITE): New string; use it in references and + examples. + (Section 2.5): Add definitions of D and Z operators, for use with + pdfhref macro. + (Section 2.5.4): Complete description of pdfhref macro usage for + `Linking to Internet Resources'; provide examples. + +2005-05-14 Nick Stoughton <nick@usenix.org> + + * pdfmark.tmac (LB): Renamed to ... + (PDFLB): This to avoid conflicts with mm's LB macro. + +2005-05-02 Keith Marshall <keith.d.marshall@ntlworld.com> + + Handle parsing anomalies in Cygwin's `ash', and similar, shells. + + * pdfroff.sh ($CAT, $GREP, $SED, $GROFF, $DIFF): Avoid interpreting + misdirected error messages, which `type' sends to `stdout' in some + shells, as a successful program file match. + + ($AWK, $GS): Likewise; also ensure that multiple choice match + prototypes are eval'ed as such, in case token splitting occurs + before variable expansion. + +2005-04-24 Keith Marshall <keith.d.marshall@ntlworld.com> + + Add support for folded outlines in PDF documents. + + * pdfmark.tmac (PDFOUTLINE.FOLDLEVEL): New register. + (pdf:bm.emit): Use it. + + * pdfmark.ms: Document it. + +2005-03-25 Werner LEMBERG <wl@gnu.org> + + * Makefile.in: Removed. + +2005-03-24 Werner LEMBERG <wl@gnu.org> + + * Makefile: Renamed to... + * Makefile.in: This. + +2005-03-22 Keith Marshall <keith.d.marshall@ntlworld.com> + + * pdfroff.sh: Eliminate invalid program reference to $AWK, when + invoked with `--no-reference-dictionary' option. + +2005-03-02 Keith Marshall <keith.d.marshall@ntlworld.com> + + * contrib/pdfmark/Makefile.sub (install_data): Use $(INSTALL_SCRIPT) + to install `pdfroff'. + * contrib/pdfmark/pdfroff.man (opte): New macro. + Use it to remove spurious equal signs from SYNOPSIS. + +2005-02-28 Keith Marshall <keith.d.marshall@ntlworld.com> + + Provide `pdfroff' shell script, and manpage to document it; + runs multiple groff passes, to format PDF documents. + + * pdfroff.sh: New shell script template; + * pdfroff.man: New man page to document it. + + Integrate `pdfmark' into normal groff build system; + install macro `pdfmark' packages, build and install `pdfroff', + and PDF format documentation. + + * Makefile.sub: Rewritten. + * pdfmark.tmac: Modified. + (pdfhref): New macro operators, `D' and `Z'. + (pdf*href-D, pdf*href-Z): New macros: implement them. + (pdf*href.mark.resolve, pdf*href.mark.emit, pdf*href.mark.flush): + Modified macro algorithm, to eliminate inconsistencies between + `grohtml' representations of `opminy' from differing groff versions. + (pdf*href.mark, pdf*href.mark.release, pdf*href.mark.close): + deleted (redundant macros). + (PDFHREF.LEADING): Default value changed (was 2.5p; now -1.0p). + Global comment updates. + + * TODO: Updated. + +2004-12-10 Werner LEMBERG <wl@gnu.org> + + * TODO: Updated. + +2004-12-08 Keith Marshall <keith.d.marshall@ntlworld.com> + + First import of pdfmark files. + +________________________________________________________________________ + +Copyright (C) 2004-2020 Free Software Foundation, Inc. + +Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. + +Local Variables: +fill-column: 72 +mode: change-log +version-control: never +End: +vim:set autoindent textwidth=72: diff --git a/contrib/pdfmark/PROBLEMS b/contrib/pdfmark/PROBLEMS new file mode 100644 index 0000000..d31be4a --- /dev/null +++ b/contrib/pdfmark/PROBLEMS @@ -0,0 +1,32 @@ + -*- text -*- + Copyright (C) 2004-2020 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. + +Known PROBLEMS in pdfmark.tmac +============================== + +Bounding boxes for link hot-spots which straddle a page break +are not computed correctly. + +*** Resolved: 06-Dec-2004 (KDM): pdfmark.tmac.patch-20041206 *** + +-------- + +Documents including a large number of cross references may fail, +with an 'input stack limit exceeded' error. + +*** Resolved: 27-Sep-2004 (KDM): pdfmark.tmac.patch-20040927 *** + +-------- + +Links placed in diversions, such as footnotes or floating keeps, +resolve to the wrong destinations; (mapping order becomes confused +between links in diversion, and links in running text following +the diversion). + +-------- + +Annotations placed by .pdfnote cannot exceed about 200 chars. diff --git a/contrib/pdfmark/README b/contrib/pdfmark/README new file mode 100644 index 0000000..7440ffd --- /dev/null +++ b/contrib/pdfmark/README @@ -0,0 +1,57 @@ + -*- text -*- + Copyright (C) 2004-2020 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. + +README for pdfmark.tmac +======================= + +Copyright (C) 2004, 2009 Free Software Foundation Inc. +Contributed by Keith Marshall (keith.d.marshall@ntlworld.com) + +This is free software. See file COPYING, for copying permissions, +and warranty disclaimer. + +This is a preview release of a proposed pdfmark.tmac macro package, +for use with GNU troff (groff). It is not yet complete, and should +be considered as an alpha release; there are a few problems to be +resolved (see file PROBLEMS). + +Partial documentation is provided, in groff-ms format. To convert +this to PDF format, you will require a working groff installation, +a working ghostscript installation, with the gs command in your PATH, +and a GNU-compatible make. The tarball should be unpacked in the +top directory of your groff source tree, then: + + cd <groff-current>/contrib/pdfmark + make pdfmark + +where <groff-current> is the top directory of your current groff +source tree. + +Included in this package, are: + + pdfmark.tmac -- the core pdfmark macro set + spdf.tmac -- a rudimentary set of bindings for ms macros + pdfmark.ms -- preliminary documentation + cover.ms -- a template for the documentation cover sheet + gnu.eps -- the groff logo, copied from the groff distribution + Makefile -- makefile, for formatting the documentation + README -- this file + PROBLEMS -- a list of known problems + TODO -- a list of planned features, not yet implemented + +To make the pdfmark macros generally usable, copy pdfmark.tmac to the +'site-tmac' directory appropriate to your groff installation; (ms users +may also wish to copy spdf.tmac). The macros may then be accessed, by +including the '-mpdfmark' option on the groff command line; (for ms +users, '-mspdf' is equivalent to '-ms -mpdfmark', with some extra +macros 'thrown in'). + +Comments, and bug reports are welcomed. Please post to the groff +mailing list, groff@gnu.org; (you must be subscribed to this list to +post mails). To subscribe, visit + + http://lists.gnu.org/mailman/listinfo/groff diff --git a/contrib/pdfmark/TODO b/contrib/pdfmark/TODO new file mode 100644 index 0000000..219b60e --- /dev/null +++ b/contrib/pdfmark/TODO @@ -0,0 +1,60 @@ + -*- text -*- + Copyright 2004-2020 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. + +TODO items for pdfmark.tmac +=========================== + +Add copyright information to PDF documentation. + +-------- + +Add acknowledgements and trade mark ownership notifications +to PDF documentation. + +-------- + +Provide documentation in man page and texinfo formats. + +-------- + +Add comments in spdf.tmac, to clarify its operation. +Also add commentary in pdfmark.tmac, to clarify operation of +recent changes. + +-------- + +Make Makefile generic, so 'configure' can resolve target +system dependencies. + +* Comment added 2005-02-26 by Keith Marshall <keith.d.marshall@ntlworld.com> + +If this refers to contrib/pdfmark/Makefile, then it is addressed by the new +'pdfroff' script; the original Makefile may be considered redundant. Local +system dependencies are resolved by 'configure', and applied to 'pdfroff', +when it is generated from 'pdfroff.sh'. + +-------- + +Improve Makefile.sub, to integrate pdfmark.tmac installation +into a regular groff build. Add it to groff's Makefile.in. + +* Comment added 2005-02-26 by Keith Marshall <keith.d.marshall@ntlworld.com> + +Completed. + +-------- + +Provide a 'pdfmark' script (or call it 'groff2pdf'?) which +actually converts a groff input file to pdf, and which +takes care of the necessary intermediate steps to handle +PDF marks. + +* Comment added 2005-02-26 by Keith Marshall <keith.d.marshall@ntlworld.com> + +This facility now provided by 'pdfroff' script; documented in 'pdfroff.man'. +Man page still requires an additional section, to describe use of 'stylesheet' +feature. Script also requires documentation in PDF and texinfo formats. diff --git a/contrib/pdfmark/cover.ms b/contrib/pdfmark/cover.ms new file mode 100644 index 0000000..b647a29 --- /dev/null +++ b/contrib/pdfmark/cover.ms @@ -0,0 +1,70 @@ +.\" Copyright (C) 2004-2020 Free Software Foundation, Inc. +.\" +.\" Copying and distribution of this file, with or without modification, +.\" are permitted in any medium without royalty provided the copyright +.\" notice and this notice are preserved. +.\" +.am pspic*error-hook +. ab \\n[.F]:\\n[.c]: fatal error: PSPIC failed to include '\\$1' +.. +.de CS +.if !rCO .nr CO 0 +.if !rTL .nr TL 0 +.\".nr PO*SAVED \\n[PO] +.nr LL*SAVED \\n[LL] +.nr HM*SAVED \\n[HM] +.nr HM 0 +.nr PO (2.1c+\\n[CO]u) +.nr LL 17.1c +\& +.nr PS*SAVED \\n[PS] +.nr VS*SAVED \\n[VS] +.nr PS 24 +.nr VS 30 +.CD +.fam T +.sp |(5.9c+\\n[TL]u) +.als AU au@first +.. +.de au@first +.sp 1.5v +.als AU au@next +.AU \\$@ +.. +.de au@next +.DE +.nr PS 18 +.nr VS 18 +.CD +.sp 0.5v +\\$* +.. +.de AI +\H'-4z'\\$*\H'0' +.. +.de CE +.DE +.sp |17.5c +.PSPIC gnu.eps +.nr PS 19 +.CD +.fam H +.tkf HR 10z 2p 20z 4p +\H'-4z'A GNU MANUAL\H'0' +.DE +.\".nr PO \\n[PO*SAVED] +.nr LL \\n[LL*SAVED] +.nr PS \\n[PS*SAVED] +.nr VS \\n[VS*SAVED] +.nr HM \\n[HM*SAVED] +.\".rr PO*SAVED +.rr LL*SAVED +.rr PS*SAVED +.rr VS*SAVED +.rr HM*SAVED +.fam +.. +.\" Local Variables: +.\" mode: nroff +.\" End: +.\" vim: filetype=groff: diff --git a/contrib/pdfmark/pdfmark.am b/contrib/pdfmark/pdfmark.am new file mode 100644 index 0000000..15eec8c --- /dev/null +++ b/contrib/pdfmark/pdfmark.am @@ -0,0 +1,99 @@ +# Copyright (C) 2005-2021 Free Software Foundation, Inc. +# Written by Keith Marshall (keith.d.marshall@ntlworld.com) +# Automake migration by Bertrand Garrigues +# +# This file 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/>. + +pdfmark_srcdir = $(top_srcdir)/contrib/pdfmark +pdfmark_builddir = $(top_builddir)/contrib/pdfmark + +man1_MANS += contrib/pdfmark/pdfroff.1 + +bin_SCRIPTS += pdfroff + +# Files installed in $(tmacdir) +TMACFILES = \ + contrib/pdfmark/pdfmark.tmac \ + contrib/pdfmark/sanitize.tmac \ + contrib/pdfmark/spdf.tmac +pdfmarktmacdir = $(tmacdir) +dist_pdfmarktmac_DATA = $(TMACFILES) + +# Files installed in $(pdfdocdir) +PDFDOCFILES = \ + contrib/pdfmark/pdfmark.pdf +if USE_PDFROFF +pdfmarkpdfdocdir = $(pdfdocdir) +nodist_pdfmarkpdfdoc_DATA = $(PDFDOCFILES) +MOSTLYCLEANFILES += $(PDFDOCFILES) +else +EXTRA_DIST += $(PDFDOCFILES) +endif + +EXTRA_DIST += \ + contrib/pdfmark/cover.ms \ + contrib/pdfmark/pdfmark.ms \ + contrib/pdfmark/ChangeLog \ + contrib/pdfmark/README \ + contrib/pdfmark/PROBLEMS \ + contrib/pdfmark/TODO \ + contrib/pdfmark/pdfroff.1.man \ + contrib/pdfmark/pdfroff.sh + +PDFROFF=\ + GROFF_TMPDIR=. \ + GROFF_COMMAND_PREFIX= \ + GROFF_BIN_DIR="$(GROFF_BIN_DIR)" \ + GROFF_BIN_PATH="$(GROFF_BIN_PATH)" \ + ./pdfroff \ + $(FFLAG) $(MFLAG) -dpaper=$(PAGE) -P-p$(PAGE) -M$(pdfmark_srcdir) + +contrib/pdfmark/pdfmark.pdf: contrib/pdfmark/pdfmark.ms + $(GROFF_V)$(MKDIR_P) `dirname $@` \ + && $(PDFROFF) -I $(doc_builddir) -I $(doc_srcdir) -mspdf \ + --stylesheet=$(pdfmark_srcdir)/cover.ms \ + $(top_srcdir)/contrib/pdfmark/pdfmark.ms >$@ + +# The pdf files use the local script to generate. +$(PDFDOCFILES): pdfroff groff troff gropdf +$(PDFDOCFILES): $(dist_devpsfont_DATA) $(nodist_devpsfont_DATA) \ + $(DOC_GNU_EPS) + +pdfroff: contrib/pdfmark/pdfroff.sh $(SH_DEPS_SED_SCRIPT) + $(AM_V_GEN)sed -f $(SH_DEPS_SED_SCRIPT) \ + -e "s|[@]VERSION[@]|$(VERSION)|" \ + -e "s|[@]GROFF_AWK_INTERPRETERS[@]|$(ALT_AWK_PROGS)|" \ + -e "s|[@]GROFF_GHOSTSCRIPT_INTERPRETERS[@]|$(ALT_GHOSTSCRIPT_PROGS)|" \ + -e "s|[@]GROFF_BIN_DIR[@]|$(bindir)|" $(pdfmark_srcdir)/pdfroff.sh \ + >$@ \ + && chmod +x $@ + +mostlyclean-local: mostlyclean_pdfmark +mostlyclean_pdfmark: + rm -rf $(top_builddir)/pdfroff-* + +uninstall_groffdirs: uninstall-pdfmark-hook +uninstall-pdfmark-hook: +if USE_PDFROFF + -rmdir $(DESTDIR)$(pdfmarkpdfdocdir) +endif + + +# Local Variables: +# mode: makefile-automake +# fill-column: 72 +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/contrib/pdfmark/pdfmark.ms b/contrib/pdfmark/pdfmark.ms new file mode 100644 index 0000000..0d7d28c --- /dev/null +++ b/contrib/pdfmark/pdfmark.ms @@ -0,0 +1,2831 @@ +.ig +pdfmark.ms + +This file is part of groff, the GNU roff type-setting system. + +Copyright (C) 2004-2021 Free Software Foundation, Inc. +written by Keith Marshall <keith.d.marshall@ntlworld.com> + +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 or +any later version published by the Free Software Foundation; with no +Invariant Sections, with no Front-Cover Texts, and with no Back-Cover +Texts. + +A copy of the Free Documentation License is included as a file called +FDL in the main directory of the groff source package. +.. +. +.CS +Portable Document Format +Publishing with GNU Troff +.AU Keith Marshall +.AI <keith.d.marshall@ntlworld.com> +.CE +. +.\" Specify the Internet address for the groff web site. +.\" +.ds GROFF-WEBSITE http://www.gnu.org/software/groff +. +.\" Set the PDF default document view attribute, to ensure that the document +.\" outline is visible, each time the document is opened in Acrobat Reader. +.\" +.pdfview /PageMode /UseOutlines +.\" +.\" Initialize the outline view to show only three heading levels, +.\" with additional subordinate level headings folded. +.\" +.nr PDFOUTLINE.FOLDLEVEL 3 +. +.\" Add document identification meta-data +.\" +.pdfinfo /Title Portable Document Format Publishing with GNU Troff +.pdfinfo /Author Keith Marshall +.pdfinfo /Subject Tips and Techniques for Exploiting PDF Features with GNU Troff +.pdfinfo /Keywords groff troff PDF pdfmark +. +.\" Set the default cross reference format to indicate section numbers, +.\" rather than page numbers, when we insert a reference pointer. +.\" +.ds PDFHREF.INFO section \\*[SN-NO-DOT] \\$* +. +.\" Define a macro, to print reference links WITHOUT the usual "see" prefix. +.\" +.de XR-NO-PREFIX +.rn PDFHREF.PREFIX xx +.ds PDFHREF.PREFIX +.XR \\$@ +.rn xx PDFHREF.PREFIX +.. +. +.\" Define a string, to insert a Registered Trade Mark symbol as +.\" a superscript... +.\" +.ds rg \*{\(rg\*} +.\" +.\" ...and use it to define strings, representing frequently used +.\" registered trade marks. +.\" +.ds Adobe "Adobe\Z'\\$1'\*(rg\" +.ds Acrobat "Acrobat\Z'\\$1'\*(rg\" +.ds Distiller "Distiller\Z'\\$1'\*(rg\" +.ds PostScript "PostScript\Z'\\$1'\*(rg\" +.\" +.ds Microsoft "Microsoft\Z'\\$1'\*(rg\" +. +.\" Establish the page layout. +.\" +.nr PO 2.5c +.nr LL 17.0c +.nr LT 17.0c +.nr DI 5n +.nr HY 0 +. +.\" Within the table of contents, the width of the right-hand margin, +.\" in which space is reserved for the display of page numbers, and the +.\" appearance of the leaders which precede it, are controlled by:- +.\" +.char \[TC-LEADER] \h'0.8n'. +.nr TC-MARGIN \w'00000' +. +.\" Generate headers in larger point sizes, for NH levels < 4, +.\" with point size increasing by 1.5p, for each lesser NH level. +.\" +.nr GROWPS 4 +.nr PSINCR 1.5p +. +. +.\" Implement an interface with the FS macro (from s.tmac) to facilitate +.\" placement of footnote reference marks, with each serving as an active +.\" pdfhref link to the associated footnote itself. +.\" +.de pdf:fn.mark nr +.\" Macro to replace original duty performed by "\**"; must be invoked +.\" at point of footnote mark placement, e.g. by FS, BEFORE recording of +.\" the associated text within the footnote diversion is commenced. +.\" +.ie \\n[.$] \{\ +. pdfhref L -D pdf:fn\\$1 -- \\$2 +. pdfhref M -N pdf:fn\\$1r +. \} +.\" +.\" s.tmac does not publicly expose its auto-incrementing footnote index; +.\" to avoid a dependency on an undocumented internal feature, we create +.\" our own counter, while keeping the internal index synchronized, by +.\" interpolating a renamed "\**", each time we increment our counter. +.\" +.el .\\$0 \\n+[pdf:fn.index.count] \\*[pdf:fn.index] +.nr pdf:fn.index.count 0 1 +.rn * pdf:fn.index +.ds * \c +. +.\" For versions of s.tmac which support the FS-MARK callback hook, it +.\" is sufficient for us to answer the callback request. +.\" +.\" FIXME: in time, we may be able to unconditionally assume that this +.\" callback hook will be supported... +.\" +.ie d FS-MARK .als FS-MARK pdf:fn.mark +.el \{\ +.\" ...but in the interim, we may need to redefine s.tmac's FS macro, +.\" (actually the @FS internal macro, rather than FS itself), to gain +.\" an effect equivalent to taking control of FS-MARK, to achieve the +.\" placement of a footnote mark as an active pdfhref link. +.\" +.rn @FS pdf:fn.record +.de @FS +.pdf:fn.mark +.pdf:fn.record +.. +.\} +.\" Override s.tmac's (undocumented) footnote output hook; this emulates +.\" the default output style for \n[FF] == 3 footnotes, with the footnote +.\" number formatted as a pdfhref link back to the position at which the +.\" footnote marker appears, within the document text. +.\" +.de FP +.LP +.nr pdf:fn.tag.width (u;2*\\n[FI]) +.ds pdf:fn.tag \s'-1.5p'\\$1.\s'+1.5p' +.pdfhref M -N pdf:fn\\$1 +.in +\\n[pdf:fn.tag.width]u +.ti -\\n[pdf:fn.tag.width]u +.nr pdf:fn.tag.width -\\w'\\*[pdf:fn.tag]'u +.pdfhref L -D pdf:fn\\$1r -A \\h'\\n[pdf:fn.tag.width]u'\c -- \\*[pdf:fn.tag] +.. +.de pdfhref-nobreak +.\" FIXME: I've only noticed this anomaly when planting pdfhref links +.\" within footnotes; if the start of the link text is placed near the +.\" line length limit, and all of it is moved to the start of the next +.\" line, the "hot-spot" region is computed to be one line higher than +.\" it should be; ending the preceding input line with "\c", and then +.\" invoking pdfhref via this wrapper, works around this issue. +.\" +.ie \\n[.l]-\\n[.i]-\\n[.k]-\\w'\\$\\n[.$]' \& +.el \p +.pdfhref \\$* +.. +. +.\" Define a local macro to facilitate choice of style for emphasis; +.\" by default, make it equivalent to the ms standard "I" macro. +.\" +.de EM +.\".I "\s'+0.3'\\$1\s0" "\\$2" "\\$3" +.I \\$@ +.. +.\" Also, define variations on the ms standard "CW" macro, to add +.\" bold, italic, and both styles to constant width text; note that +.\" each of these accept two additional arguments, in comparison to +.\" standard "CW", such that \$1 specifies the text which is to be +.\" styled, \$2 and \$3 specify inner after/before bracketting, to +.\" set as regular "CW" text, while \$4 and \$5 become equivalent +.\" to \$2 and \$3 of standard "CW", acting as outer bracketting. +.\" +.de CWB +\\$5\fC\\$3\fP\f(CB\\$1\fP\fC\\$2\fP\\$4 +.. +.de CWI +\\$5\fC\\$3\fP\f(CI\\$1\fP\fC\\$2\fP\\$4 +.. +.de CWBI +\\$5\fC\\$3\fP\f[CBI]\\$1\fP\fC\\$2\fP\\$4 +.. +.\" Finally, augment this group with a variant string, which may be +.\" used to set constant width tags on "IP" paragraphs, with \$1 set +.\" as if by "CWB", followed by an optional suffix set as if by "CWBI", +.\" and with the suffix bracketted by \$3 after and \$4 before, each +.\" set in the regular "CW" style. +.\" +.ds = \f(CB\\$1\f(CR\\$4\f[CBI]\\$2\f(CR\\$3 +. +.\" Additionally, add a cross-reference convenience macro, emulating +.\" the style of the "ms" font change macros... +.\" +.\" .XR <dest-name> [<affixed> [<prefix>]] +.\" +.\" ...such that, when invoked with one, two, or three arguments, this +.\" expands to the equivalent of: +.\" +.\" .pdfhref L -D <dest-name> [-A <affixed> [-P <prefix>]] +.\" +.\" to place a pdfhref reference link, to a named destination, within +.\" the same document, using the reference text which is predefined in +.\" the reference dictionary entry associated with the destination. +.\" +.de XR +.if \\n(.$ \{\ +. if \\n[OPMODE] \{\ +. ds xr!argv -D "\\$1" +. if \\n(.$>1 .as xr!argv " -A "\\$2" +. if \\n(.$>2 .as xr!argv " -P "\\$3" +. pdfhref L \\*[xr!argv] +. rm xr!argv +. \} +. \} +.. +. +.NH 1 +.\" Conventionally, in "ms", NH precedes text which is to be set as a +.\" numbered section heading, but it makes no provision for automatic +.\" reference to that heading in a table of contents, or (in the case +.\" of PDF document production) in a document outline. Both of these +.\" limitations may be mitigated, by using the XN macro, (provided by +.\" spdf.tmac), which sets its arguments, both as text to be included +.\" in the section heading, as printed, and as an assocated document +.\" outline reference; it will also make this same text available to +.\" the user-specified callback macro, XH-UPDATE-TOC, whereby it may +.\" be used, e.g. to construct a table of contents entry. +.\" +.\" Within the table of contents, structural layout will be achieved, +.\" under the direction of the following spacing control constants: +.\" +.ds XNVS1 0.50v \" leading for top level +.ds XNVS2 0.15v \" leading at nesting level increment +.ds XNVS3 0.30v \" leading following nested group +.\" +.\" Note that one TOC related callback hook is shared by both XH and +.\" XN; its is called XH-UPDATE-TOC, regardless of whether called by +.\" XH or by XN; when called by XN, it is invoked with arguments: +.\" +.\" .XH-UPDATE-TOC <outline-level> <section-number> <text> ... +.\" +.de XH-UPDATE-TOC +.\" This implementation of XH-UPDATE-TOC utilizes the rudimentary ms +.\" mechanism for formatting a table of contents, using XS and XE to +.\" bracket individual entries. +. XS +. \" A local register, tc*hl, is used to track the outline level +. \" of each TOC entry, as it is added; it is not defined, until +. \" the first entry is recorded... +. \" +. if r tc*hl \{\ +. \" ...after which, we use it to establish indentation, +. \" to reflect changes in outline level. +. \" +. ie \\$1>1 \{\ +. \" When at any outline level greater than one, +. \" any level increment will be offset by XNVS2 +. \" units of vertical space... +. \" +. ie \\$1>\\n[tc*hl] .sp \\*[XNVS2] +. +. \" ...whereas any decrement will be offset by +. \" XNVS3 units. +. \" +. el .if \\n[tc*hl]>\\$1 .sp \\*[XNVS3] +. \} +. +. \" ...but every top-level entry, after the first, is +. \" offset by XNVS1 units. +. \" +. el .sp \\*[XNVS1] +. \} +. +. \" \$1 becomes the effective outline level for the current table +. \" of contents entry, but we must ensure that it is one or more. +. \" +. ie \\$1 .nr tc*hl \\$1 +. el .nr tc*hl 1 +. +. \" The current outline level determines the indentation at which +. \" we place the section number reference... +. \" +. nop \h'\\n[tc*hl]-1m'\\$2\c +. +. \" ...after which we discard \$1 and \$2, allowing us to append +. \" all remaining arguments, ensuring that there is at least 0.5n +. \" of following space, before the first leader dot. +. \" +. shift 2 +. nop \h'1.5n'\\$*\h'0.5n' +. XE +.. +.XN Introduction +.\" +.\" If using an old s.tmac, without the SN-NO-DOT extension, ensure +.\" that we get SOMETHING in section number references. +.\" +.if !d SN-NO-DOT .als SN-NO-DOT SN +.LP +It might appear that it is a fairly simple matter to +produce documents in \*[Adobe]\~\(lqPortable\~Document\~Format\(rq, +commonly known as PDF, using +.CW groff ) GNU\~Troff\~( +as the document formatter. +Indeed, +.CW groff 's +default output format is the native \*[Adobe]\~\*[PostScript] format, +which PDF producers such as \*[Adobe] \*[Acrobat] \*[Distiller ,] +or GhostScript, expect as their input format. +Thus, the PDF production process would seem to entail simply +formatting the document source with +.CW groff , +to produce a \*[PostScript] version of the document, +which can subsequently be processed by \*[Acrobat] \*[Distiller] +or GhostScript, to generate the final PDF document. +.LP +For many PDF production requirements, +the production cycle described above may be sufficient. +However, this is a limited PDF production method, +in which the resultant PDF document represents no more than +an on screen image of the printed form of the document, if +.CW groff 's +\*[PostScript] output were printed directly. +.LP +The Portable Document Format provides a number of features, +which significantly enhance the experience of reading a document on screen, +but which are of little or no value to a document which is merely printed. +It +.EM is +possible to exploit these PDF features, which are described in the \*[Adobe] +.de pdfmark-manual pdfmark-manual +.\" This is an example of a resource reference specified by URI ... +.\" We may need to refer often to the Adobe pdfmark Reference Manual, +.\" so we create the internet link definition using a macro, to make +.\" it reusable. +.\" +.\" Note also, that we protect the description of the reference by +.\" preceding it with "--", to avoid "invalid character in name" type +.\" error messages from groff (caused by the use of "\~"). +.\" +.pdfhref W -D https://www.adobe.com/go/acrobatsdk_pdfmark \ + -P \(lq -A \(rq\\$1 -- pdfmark\~Reference\~Manual +.pdfmark-manual , +with some refinement of the simple PDF production method, provided +appropriate \(lqfeature implementing\(rq instructions can be embedded into +.CW groff 's +\*[PostScript] rendering of the document. +This, of course, implies that the original document source, which +.CW groff +will process to generate the \*[PostScript] description of the document, +must include appropriate markup to exploit the desired PDF features. +It is this preparation of the +.CW groff +document source to exploit a number of these features, +which provides the principal focus of this document. +.LP +The markup techniques to be described have been utilized in the production of +the PDF version of this document itself. +This has been formatted using +.CW groff 's +.CW ms +macro package; +thus, usage examples may be found in the document source file, +.CW \n(.F , +to which comments have been added, +to help identify appropriate markup examples for implementing PDF features, +such as:\(en +.QS +.IP \(bu +Selecting a default document view, which defines how the document will appear +when opened in the reader application; for example, when this document is +opened in \*[Acrobat]\~Reader, it should display the top of the cover sheet, +in the document view pane, while a document outline should appear to the left, +in the \(lqBookmarks\(rq pane. +.IP \(bu +Adding document identification \(lqmeta\(hydata\(rq, +which can be accessed, in \*[Acrobat]\~Reader, +by inspecting the \(lqFile\^/\^Document\~Properties\^/\^Summary\(rq. +.IP \(bu +Creating a document outline, which will be displayed in the \(lqBookmarks\(rq +pane of \*[Acrobat]\~Reader, such that readers may quickly navigate to any +section of the document, simply by clicking on the associated heading +in the outline view. +.IP \(bu +Embedding active links in the body of the document, such that readers may +quickly navigate to related material at another location within the same +document, or in another PDF document, or even to a related Internet resource, +specified by its URI. +.IP \(bu +Adding annotations, in the form of \(lqsticky notes\(rq, at strategic +points within the PDF document. +.QE +.LP +All of the techniques described have been tested on +.EM both +GNU/Linux, and on \*[Microsoft] Windows\(tm2000 operating platforms, using +.CW groff +.CW 1.19.1 ,\** +.FS +Later versions should, and some earlier versions may, be equally suitable. +See\c +.pdfhref-nobreak W \*[GROFF-WEBSITE] +for information and availability of the latest version. +.FE +in association with +.CW AFPL +.CW GhostScript +.CW 8.14 .\** +.FS +Again, other versions may be suitable. +See\c +.pdfhref-nobreak W http://ghostscript.com +for information and availability. +.FE +\& +Other tools employed, which should be readily available on +.EM any +Unix\(tm +or GNU/Linux system, are +.CW sed , +.CW awk +and +.CW make , +together with an appropriate text editor, for creating and marking up the +.CW groff +input files. +These additional utilities are not provided, as standard, +on the \*[Microsoft] Windows\(tm platform, +but several third party implementations are available. +Some worth considering include the MKS\*(rg\~Toolkit,\** +.FS +A commercial offering; see\c +.pdfhref-nobreak W http://mkssoftware.com/products/tk/default.asp +for information. +.FE +Cygwin,\** +.FS +A +.EM free +but comprehensive +.SM +POSIX +.LG +emulation environment and +Unix\(tm +toolkit for \%32\(hybit \*[Microsoft] Windows\(tm platforms; see\c +.pdfhref-nobreak W http://cygwin.com +for information and download. +.FE +or MSYS.\** +.FS +Another free, but minimal suite of common +Unix\(tm +tools for \%32\(hybit \*[Microsoft] Windows\(tm, available for download from\c +.pdfhref-nobreak W -A ; https://mingw.osdn.io +it +.EM does +include those tools listed above, +and is the package which was actually used when performing the Windows\(tm2000 +platform tests referred to in the text. +.FE +\& +This list is by no means exhaustive, and should in no way be construed as an +endorsement of any of these packages, nor to imply that other similar packages, +which may be available, are in any way inferior to them. +.bp +. +.NH 1 +.\" We may wish a section heading to represent a named destination, +.\" so that we can create a linked reference to it, from some other +.\" part of the PDF document, (or even from another PDF document). +.\" +.\" Here we use the "-N" option of the "XN" macro, to create a named +.\" PDF link destination, at the location of the heading. Notice that +.\" we also use the "--" marker to separate the heading text from the +.\" preceding option specification; it is not strictly necessary in +.\" this case, but it does help to set off the heading text from the +.\" option specification. +.\" +.XN -N pdf-features -- Exploiting PDF Document Features +.LP +To establish a consistent framework for adding PDF features, a +.CW groff +macro package, named +.CW pdfmark.tmac , +has been provided. +Thus, to incorporate PDF features in a document, +the appropriate macro calls, as described below, may be placed in the +.CW groff +document source, which should then be processed with a +.CW groff +command of the form\** +.FS +.pdfhref M pdf-features-fn +.nr pdf-features-fn \n[fn*text-num] +Note that, +if any +.CW -T \^\c +.CWI dev +option is specified, +it should be either +.CW -T \^\c +.CW ps , +or +.CW -T \^\c +.CW pdf ; +any other explicit choice is unlikely to be compatible with +.CW -m \|\|\c +.CW pdfmark , +and will have an unpredictable +(possibly erroneous) +effect on the output. +If no +.CW -T \^\c +.CWI dev +option is specified, +(in which case +.CW -T \^\c +.CW ps +is implicitly assumed), +or if +.CW -T \^\c +.CW ps +is explicitly specified, +then the output will be produced in \*[PostScript] format, +and will require conversion to PDF, +(e.g. by using GhostScript tools); +explicit specification of +.CW -T \^\c +.CW pdf +will result in direct output in PDF format, +thus obviating the need for conversion. +.FE +.QP +.fam C +groff [-Tps\h'0.2p'|\h'0.2p'-Tpdf] [-m\F[]\|\|\FC\c +.I name ] +-m\F[]\|\|\FC\c +.B pdfmark +.I options \F[]\|\|\FC\c [- +.I file \F[]\|\|\FC\c "...] " +\&... +.LP +It may be noted that the +.CW pdfmark +macros have no dependencies on, and no known conflicts with, +any other +.CW groff +macro package; thus, users are free to use any other macro package, +of their choice, to format their documents, while also using the +.CW pdfmark +macros to add PDF features. +. +.NH 2 +.XN -S -N pdfmark-operator -- The \F[C]pdfmark\F[] Operator +.LP +All PDF features are implemented by embedding instances of the +.B \F[C]pdfmark\F[] +operator, as described in the \*[Adobe] +.pdfmark-manual , +into +.CW groff 's +\*[PostScript] output stream. +To facilitate the use of this operator, the +.CW pdfmark +macro package defines the primitive +.CW pdfmark +macro; it simply emits its argument list, +as arguments to a +.CW pdfmark +operator, in the \*[PostScript] output stream. +.LP +.pdfhref M -N pdfmark-example +To illustrate the use of the +.CW pdfmark +macro, the following is a much simplified example of how a bookmark +may be added to a PDF document outline +.QP +.CW ".pdfmark \e" +.RS 4 +.nf +.fam C +/Count 2 \e +/Title (An Example of a Bookmark with Two Children) \e +/View [/FitH \en[PDFPAGE.Y]] \e +/OUT +.RE +.LP +In general, users should rarely need to use the +.CW pdfmark +macro directly. +In particular, the above example is too simple for general use; it +.EM will +create a bookmark, but it does +.EM not +address the issues of setting the proper value for the +.CW /Count +key, nor of computing the +.CW PDFPAGE.Y +value used in the +.CW /View +key. The +.CW pdfmark +macro package includes a more robust mechanism for creating bookmarks, +.\" +.\" Here is an example of how a local reference may be planted, +.\" using the automatic formatting feature of the "pdfhref" macro. +.\" +.\" This is a forward reference to the named destination "add-outline", +.\" which is defined below, using the "XN" wrapper macro, from the +.\" "spdf.tmac" macro package. The automatically formatted reference +.\" will be enclosed in parentheses, as specified by the use of +.\" "-P" and "-A" options. +.\" +.pdfhref L -P ( -A ), -D add-outline +.\" +which addresses these issues automatically. +Nevertheless, the +.CW pdfmark +macro may be useful to users wishing to implement more advanced PDF features, +than those currently supported directly by the +.CW pdfmark +macro package. +. +.NH 2 +.XN -N docview -- Selecting an Initial Document View +.LP +By default, +when a PDF document is opened, +the first page will be displayed, +at the default magnification set for the reader, +and outline and thumbnail views will be hidden. +When using a PDF reader, +such as \*[Acrobat]\~Reader, +which supports the +.CW /DOCVIEW +class of the +.CW pdfmark +operator, +these default initial view settings may be overridden, +using the +.CW pdfview +macro. +For example +.QP +.CW ".pdfview /PageMode /UseOutlines" +.LP +will cause \*[Acrobat]\~Reader to open the document outline view, +to the left of the normal page view, +while +.QP +.CW ".pdfview /PageMode /UseThumbs" +.LP +will open the thumbnail view instead. +.LP +Note that the two +.CW /PageMode +examples, above, are mutually exclusive \(em it is not possible to have +.EM both +outline and thumbnail views open simultaneously. +However, it +.EM is +permitted to add +.CW /Page +and +.CW /View +keys, to force the document to open at a page other than the first, +or to change the magnification at which the document is initially displayed; +see the +.pdfmark-manual +for more information. +.LP +It should be noted that the view controlling meta\(hydata, defined by the +.CW pdfview +macro, is not written immediately to the \*[PostScript] output stream, +but is stored in an internal meta\(hydata \(lqcache\(rq, +(simply implemented as a +.CW groff +diversion). +This \(lqcached\(lq meta\(hydata must be written out later, by invoking the +.CW pdfsync +macro, +.\" +.\" Here is another example of how we may introduce a forward reference. +.\" This time we are using the shorter notation afforded by the "XR" macro +.\" provided by "spdf.tmac"; this example is equivalent to the native +.\" "pdfmark.tmac" form +.\" .pdfhref L -D pdfsync -P ( -A ). +.\" +.XR pdfsync ). ( +. +.NH 2 +.XN -N docinfo -- Adding Document Identification Meta-Data +.LP +In addition to the +.CW /DOCVIEW +class of meta\(hydata described above, +.XR docview ), ( +we may also wish to include document identification meta\(hydata, +which belongs to the PDF +.CW /DOCINFO +class. +.LP +To do this, we use the +.CW pdfinfo +macro. +As an example of how it is used, +the identification meta\(hydata attached to this document +was specified using a macro sequence similar to:\(en +.DS I +.CW +\&.pdfinfo /Title PDF Document Publishing with GNU Troff +\&.pdfinfo /Author Keith Marshall +\&.pdfinfo /Subject How to Exploit PDF Features with GNU Troff +\&.pdfinfo /Keywords groff troff PDF pdfmark +.DE +Notice that the +.CW pdfinfo +macro is repeated, once for each +.CW /DOCINFO +record to be placed in the document. +In each case, the first argument is the name of the applicable +.CW /DOCINFO +key, which +.EM must +be named with an initial solidus character; +all additional arguments are collected together, +to define the value to be associated with the specified key. +.LP +As is the case with the +.CW pdfview +macro, +.XR docview ), ( +the +.CW /DOCINFO +records specified with the +.CW pdfinfo +macro are not immediately written to the \*[PostScript] output stream; +they are stored in the same meta\(hydata cache as +.CW /DOCVIEW +specifications, until this cache is explicitly flushed, +by invoking the +.CW pdfsync +macro, +.XR pdfsync ). ( +. +.NH 2 +.XN -N add-outline -- Creating a Document Outline +.LP +A PDF document outline comprises a table of references, +to \(lqbookmarked\(rq locations within the document. +When the document is viewed in an \(lqoutline\~aware\(rq PDF document reader, +such as \*[Adobe] \*[Acrobat] Reader, +this table of \(lqbookmarks\(rq may be displayed in a document outline pane, +or \(lqBookmarks\(rq pane, to the left of the main document view. +Individual references in the outline view may then be selected, +by clicking with the mouse, +to jump directly to the associated marked location in the document view. +.LP +The document outline may be considered as a collection of \(lqhypertext\(rq +references to \(lqbookmarked\(rq locations within the document. +The +.CW pdfmark +macro package provides a single generalized macro, +.CW pdfhref , +for creating and linking to \(lqhypertext\(rq reference marks. +This macro will be described more comprehensively in a later section, +.XR pdfhref ); ( +the description here is restricted to its use for defining document outline entries. +. +.NH 3 +.XN -N basic-outline -- A Basic Document Outline +.LP +In its most basic form, the document outline comprises a structured list of headings, +each associated with a marked location, or \(lqbookmark\(rq, in the document text, +and a specification for how that marked location should be displayed, +when this bookmark is selected. +.LP +To create a PDF bookmark, the +.CW pdfhref +macro is used, +at the point in the document where the bookmark is to be placed, +in the form +.QP +.fam C +.B ".pdfhref O" +.I level > < +.I "descriptive text ..." +.LP +in which the reference class +.CWB O \& \& \(rq \(lq +stipulates that this is an outline reference. +.LP +Alternatively, for those users who may prefer to think of a document outline +simply as a collection of bookmarks, the +.CW pdfbookmark +macro is also provided \(em indeed, +.CW pdfhref +invokes it, when processing the +.CWB O \& \& \(rq \(lq +reference class operator. +It may be invoked directly, in the form +.QP +.fam C +.B .pdfbookmark +.I level > < +.I "descriptive text ..." +.LP +Irrespective of which of the above macro forms is employed, the +.CWI level > < +argument is required. +It is a numeric argument, defining the nesting level of the \(lqbookmark\(rq +in the outline hierarchy, with one being the topmost level. +Its function may be considered analagous to the +.EM "heading level" +of the document's section headings, +for example, as specified with the +.CW NH +macro, if using the +.CW ms +macros to format the document. +.LP +All further arguments, following the +.CWI level > < +argument, are collected together, to specify the heading text which will appear +in the document's outline view. +Thus, the outline entry for this section of this document, +which has a level three heading, +might be specified as +.QP +.CW +\&.pdfhref O 3 \*(SN A Basic Document Outline +.LP +or, in the alternative form using the +.CW pdfbookmark +macro, as +.QP +.CW +\&.pdfbookmark 3 \*(SN A Basic Document Outline +. +.NH 3 +.XN Hierarchical Structure in a Document Outline +.LP +When a document outline is created, using the +.CW pdfhref +macro as described in +.\" +.\" Here is an example of how we can temporarily modify the format of +.\" a reference link, in this case to indicate only the section number +.\" of the link target, in the form "section #", (or, if we define +.\" "SECREF.BEGIN" before the call, its content followed by the +.\" section number). +.\" +.\" We first define a macro, which will get the reference data from +.\" pdfhref, as arguments, and will return the formatted output, as we +.\" require it, the string "PDFHREF.TEXT". +.\" +.de SECREF +.while \\n(.$ \{\ +. ie '\\$1'section' \{\ +. if !dSECREF.BEGIN .ds SECREF.BEGIN \\$1 +. ds PDFHREF.TEXT \\*[SECREF.BEGIN]\~\\$2 +. rm SECREF.BEGIN +. shift \\n(.$ +. \} +. el .shift +. \} +.. +.\" We now tell "pdfhref" to use our formatting macro, in place of +.\" its builtin default formatter, before we specify the reference. +.\" +.pdfhref F SECREF +.pdfhref L -A , -D basic-outline +.\" +.\" At this point, we would normally revert the "pdfhref" formatter +.\" to use its default, built in macro. However, in this particular +.\" case, we want to use our custom format one more time, before we +.\" revert it, so we will omit the reversion step this time. +.\" +and any entry is added at a nesting level greater than one, +then a hierarchical structure is automatically defined for the outline. +However, as was noted in the simplified +.pdfhref L -D pdfmark-example -- example +in +.pdfhref L -A , -D pdfmark-operator +.\" +.\" And now, we revert to default "pdfhref" formatting behaviour, +.\" by completing the call we delayed above. +.\" +.pdfhref F +.\" +the data required by the +.CW pdfmark +operator to create the outline entry may not be fully defined, +when the outline reference is defined in the +.CW groff +document source. +Specifically, when the outline entry is created, its +.CW /Count +key must be assigned a value equal to the number of its subordinate entries, +at the next inner level of the outline hierarchy; +typically however, +these subordinate entries will be defined +.EM later +in the document source, and the appropriate +.CW /Count +value will be unknown, when defining the parent entry. +.LP +To resolve this paradox, the +.CW pdfhref +macro creates the outline entry in two distinct phases \(em +a destination marker is placed in the \*[PostScript] output stream immediately, +when the outline reference is defined, +but the actual outline entry is stored in an internal \(lqoutline cache\(rq, +until its subordinate hierarchy has been fully defined; +it can then be inserted in the output stream, with its +.CW /Count +value correctly assigned. +Effectively, to ensure integrity of the document outline structure, +this means that each top level outline entry, and +.EM all +of its subordinates, are retained in the cache, until the +.EM next +top level entry is defined. +.LP +One potential problem, which arises from the use of the \(lqoutline cache\(rq, +is that, at the end of any document formatting run, the last top level outline entry, +and any subordinates defined after it, will remain in the cache, and will +.EM not +be automatically written to the output stream. +To avoid this problem, the user should follow the guidelines given in +.\" +.\" Here is a more conventional example of how to temporarily change +.\" to the format used to display reference links. We will again use +.\" the "SECREF" format, which we defined above, but on this occasion +.\" we will immediately revert to the default format, after the link +.\" has been placed. +.\" +.pdfhref F SECREF +.pdfhref L -D pdfsync -A , +.pdfhref F +.\" +to synchronize the output state with the cache state, +.XR pdfsync ), ( +at the end of the +.CW groff +formatting run. +. +.NH 3 +.XN -N outline-view -- Associating a Document View with an Outline Reference +.LP +Each \(lqbookmark\(rq entry, in a PDF document outline, +is associated with a specific document view. +When the reader selects any outline entry, +the document view changes to display the document context +associated with that entry. +.LP +The document view specification, +to be associated with any document outline entry, +is established at the time when the outline entry is created. +However, rather than requiring that each individual use of the +.CW pdhref +macro, to create an outline entry, +should include its own view specification, +the actual specification assigned to each entry is derived from +a generalized specification defined in the string +.CW PDFBOOKMARK.VIEW , +together with the setting of the numeric register +.CW PDFHREF.VIEW.LEADING , +which determine the effective view specification as follows:\(en +.QS +.IP \*[= PDFBOOKMARK.VIEW] +Establishes the magnification at which the document will be viewed, +at the location of the \(lqbookmark\(rq; by default, it is defined by +.RS +.QP +.CW ".ds PDFBOOKMARK.VIEW /FitH \e\en[PDFPAGE.Y] u" +.RE +.IP +which displays the associated document view, +with the \(lqbookmark\(rq location positioned at the top of the display window, +and with the magnification set to fit the page width to the width of the window. +.IP \*[= PDFHREF.VIEW.LEADING] +Specifies additional spacing, +to be placed between the top of the display window +and the actual location of the \(lqbookmark\(rq on the displayed page view. +By default, it is set as +.RS +.QP +.CW ".nr PDFHREF.VIEW.LEADING 5.0p" +.RE +.IP +Note that +.CW PDFHREF.VIEW.LEADING +does not represent true \(lqleading\(rq, in the typographical sense, +since any preceding text, set in the specified display space, +will be visible at the top of the document viewing window, +when the reference is selected. +.IP +Also note that the specification of +.CW PDFHREF.VIEW.LEADING +is shared by +.EM all +reference views defined by the +.CW pdfhref +macro; whereas +.CW PDFBOOKMARK.VIEW +is applied exclusively to outline references, +there is no independent +.CW PDFBOOKMARK.VIEW.LEADING +specification. +.QE +.LP +If desired, the view specification may be changed, by redefining the string +.CW PDFBOOKMARK.VIEW , +and possibly also the numeric register +.CW PDFHREF.VIEW.LEADING . +Any alternative definition for +.CW PDFBOOKMARK.VIEW +.EM must +be specified in terms of valid view specification parameters, +as described in the \*[Adobe] +.pdfmark-manual . +.LP +Note the use of the register +.CW PDFPAGE.Y , +in the default definition of +.CW PDFBOOKMARK.VIEW +above. +This register is computed by +.CW pdfhref , +when creating an outline entry; +it specifies the vertical position of the \(lqbookmark\(rq, +in basic +.CW groff +units, relative to the +.EM bottom +edge of the document page on which it is defined, +and is followed, in the +.CW PDFBOOKMARK.VIEW +definition, by the +.CW grops +.CW u \(rq \(lq +operator, to convert it to \*[PostScript] units on output. +It may be used in any redefined specification for +.CW PDFBOOKMARK.VIEW , +(or in the analogous definition of +.CW PDFHREF.VIEW , +described in +'ne 2v +.XR-NO-PREFIX pdfhref-view ), +but +.EM not +in any other context, +since its value is undefined outside the scope of the +.CW pdfhref +macro. +.LP +Since +.CW PDFPAGE.Y +is computed relative to the +.EM bottom +of the PDF output page, +it is important to ensure that the page length specified to +.CW troff +correctly matches the size of the logical PDF page. +This is most effectively ensured, +by providing +.EM identical +page size specifications to +.CW groff , +.CW grops +and to the \*[PostScript] to PDF converter employed, +and avoiding any page length changes within the document source. +.LP +Also note that +.CW PDFPAGE.Y +is the only automatically computed \(lqbookmark\(rq location parameter; +if the user redefines +.CW PDFBOOKMARK.VIEW , +and the modified view specification requires any other positional parameters, +then the user +.EM must +ensure that these are computed +.EM before +invoking the +.CW pdfhref +macro. +. +.NH 3 +.XN -N outline-folding -- Folding the Outline to Conceal Less Significant Headings +.LP +When a document incorporates many subheadings, +at deeply nested levels, +it may be desirable to \(lqfold\(rq the outline +such that only the major heading levels are initially visible, +yet making the inferior subheadings accessible, +by allowing the reader to expand the view of any heading branch on demand. +.LP +The +.CW pdfmark +macros support this capability, +through the setting of the +.CW PDFOUTLINE.FOLDLEVEL +register. +This register should be set to the number of heading levels +which it is desired to show in expanded form, in the +.EM initial +document outline display; +all subheadings at deeper levels will still be added to the outline, +but will not become visible until the outline branch containing them is expanded. +'ne 5 +For example, the setting used in this document: +.QS +.LD +.fam C +\&.\e" Initialize the outline view to show only three heading levels, +\&.\e" with additional subordinate level headings folded. +\&.\e" +\&.nr PDFOUTLINE.FOLDLEVEL 3 +.DE +.QE +.LP +results in only the first three levels of headings being displayed +in the document outline, +.EM until +the reader chooses to expand the view, +and so reveal the lower level headings in any outline branch. +.LP +The initial default setting of +.CW PDFOUTLINE.FOLDLEVEL , +if the document author does not choose to change it, +is 10,000. +This is orders of magnitude greater than the maximum heading level +which is likely to be used in any document; +thus the default behaviour will be to show document outlines fully expanded, +to display all headings defined, +at all levels within each document. +.LP +The setting of +.CW PDFOUTLINE.FOLDLEVEL +may be changed at any time; +however, the effect of each such change may be difficult to predict, +since it is applied not only to outline entries which are defined +.EM after +the setting is changed, +but also to any entries which remain in the outline cache, +.EM at +this time. +Therefore, it is recommended that +.CW PDFOUTLINE.FOLDLEVEL +should be set +.EM once , +at the start of each document; +if it +.EM is +deemed necessary to change it at any other time, +the outline cache should be flushed, +.XR pdfsync ), ( +.EM immediately +before the change, +which should immediately preceed a level one heading. +. +.NH 3 +.XN -N multipart-outline -- Outlines for Multipart Documents +.LP +When a document outline is created, using the +.CW pdfhref +macro, each reference mark is automatically assigned a name, +composed of a fixed stem followed by a serially generated numeric qualifier. +This ensures that, for each single part document, every outline reference +has a uniquely named destination. +.LP +As the overall size of the PDF document increases, +it may become convenient to divide it into smaller, +individually formatted \*[PostScript] components, +which are then assembled, in the appropriate order, +to create a composite PDF document. +While this strategy may simplify the overall process of creating and +editing larger documents, it does introduce a problem in creating +an overall document outline, +since each individual \*[PostScript] component will be assigned +duplicated sequences of \(lqbookmark\(rq names, +with each name ultimately referring to multiple locations in the composite document. +To avoid such reference naming conflicts, the +.CW pdfhref +macro allows the user to specify a \(lqtag\(rq, +which is appended to the automatically generated \(lqbookmark\(rq name; +this may be used as a discriminating mark, to distinguish otherwise +similarly named destinations, in different sections of the composite document. +.LP +To create a \(lqtagged\(rq document outline, +the syntax for invocation of the +.CW pdfhref +macro is modified, by the inclusion of an optional \(lqtag\(rq specification, +.EM before +the nesting level argument, i.e. +.QP +.fam C +.B ".pdfhref O" +.B -T \& [ +.I tag >] < +.I level > < +.I "descriptive text ..." +.LP +The optional +.CWI tag > < +argument may be composed of any characters of the user's choice; +however, its initial character +.EM "must not" +be any decimal digit, and ideally it should be kept short +\(em one or two characters at most. +.LP +By employing a different tag in each section, +the user can ensure that \(lqbookmark\(rq names remain unique, +throughout all the sections of a composite document. +For example, when using the +.CW spdf.tmac +macro package, which adds +.CW pdfmark +capabilities to the standard +.CW ms +package, +.XR using-spdf ), ( +the table of contents is collected into a separate \*[PostScript] section +from the main body of the document. +In the \(lqbody\(rq section, the document outline is \(lquntagged\(rq, +but in the \(lqTable\~of\~Contents\(rq section, a modified version of the +.CW TC +macro adds an outline entry for the start of the \(lqTable\~of\~Contents\(rq, +invoking the +.CW pdfhref +macro as +.QP +.CW ".pdfhref O -T T 1 \e\e*[TOC]" +.LP +to tag the associated outline destination name with the single character suffix, +.CW T \(rq. \(lq +Alternatively, as in the case of the basic outline, +.XR basic-outline ), ( +this may equally well be specified as +.QP +.CW ".pdfbookmark -T T 1 \e\e*[TOC]" +. +.NH 3 +.XN Delegation of the Outline Definition +.LP +Since the most common use of a document outline +is to provide a quick method of navigating through a document, +using active \(lqhypertext\(rq links to chapter and section headings, +it may be convenient to delegate the responsibility of creating the outline +to a higher level macro, which is itself used to +define and format the section headings. +This approach has been adopted in the +.CW spdf.tmac +package, to be described later, +.XR using-spdf ). ( +.LP +When such an approach is adopted, +the user will rarely, if ever, invoke the +.CW pdfhref +macro directly, to create a document outline. +For example, the structure and content of the outline for this document +has been exclusively defined, using a combination of the +.CW NH +macro, from the +.CW ms +package, to establish the structure, and the +.CW XN +macro from +.CW spdf.tmac , +to define the content. +In this case, +the responsibility for invoking the +.CW pdfhref +macro, to create the document outline, +is delegated to the +.CW XN +macro. +. +.NH 2 +.XN -N pdfhref -- Adding Reference Marks and Links +.LP +.pdfhref F SECREF +.ds SECREF.BEGIN Section +.pdfhref L -D add-outline +.pdfhref F +has shown how the +.CW pdfhref +macro may be used to create a PDF document outline. +While this is undoubtedly a powerful capability, +it is by no means the only trick in the repertoire of this versatile macro. +.LP +The macro name, +.CW pdfhref , +which is a contraction of \(lqPDF HyperText Reference\(rq, +indicates that the general purpose of this macro is to define +.EM any +type of dynamic reference mark, within a PDF document. +Its generalized usage syntax takes the form +.QP +.fam C +.B .pdfhref +.BI class > < +.I "-options ...\&" ] [ +[--] +.I "descriptive text ...\&" ] [ +.LP +where +.CW <\f(CIclass\fP> +represents a required single character argument, +which defines the specific reference operation to be performed, +and may be selected from:\(en +.QS +.IP \*[= O] +Add an entry to the document outline. +This operation has been described earlier, +.XR add-outline ). ( +.IP \*[= M] +Place a \(lqnamed destination\(rq reference mark at the current output position, +in the current PDF document, +.XR mark-dest ). ( +.IP \*[= D] +Specify the content of a PDF document reference dictionary entry; +typically, such entries are generated automatically, +by transformation of the intermediate output resulting from the use of +.CW pdfhref +.CWB M \& \& \(rq, \(lq +with the +.CWB -X \& \& \(rq \(lq +modifier, +.XR create-map ); ( +however, it is also possible to specify such entries manually, +.XR user-format ). ( +.IP \*[= L] +Insert an active link to a named destination, +.XR link-named ), ( +at the current output position in the current PDF document, +such that when the reader clicks on the link text, +the document view changes to show the location of the named destination. +.IP \*[= W] +Insert an active link to a \(lqweb\(rq resource, +.XR add-weblink ), ( +at the current output position in the current PDF document. +This is effectively the same as using the +.CWB L \& \& \(rq \(lq +operator to establish a link to a named destination in another PDF document, +.XR link-extern ), ( +except that in this case, the destination is specified by a +\(lquniform resource identifier\(rq, or +.CW URI ; +this may represent any Internet or local resource +which can be specified in this manner. +.IP \*[= F] +Specify a user defined macro, to be called by +.CW pdfhref , +when formatting the text in the active region of a link, +.XR set-format ). ( +.IP \*[= Z] +Define the absolute position on the physical PDF output page, +where the \(lqhot\(hyspot\(rq associated with an active link is to be placed. +Invoked in pairs, marking the starting and ending PDF page co\(hyordinates +for each link \(lqhot\(hyspot\(rq, this operator is rarely, if ever, +specified directly by the user; +rather, appropriate +.CW pdfhref +.CWB Z \& \& \(rq \(lq +specifications are inserted automatically into the document reference map +during the PDF document formatting process, +.XR create-map ). ( +.IP \*[= I] +Initialize support for +.CW pdfhref +features. +The current +.CW pdfhref +implementation provides only one such feature which requires initialization +\(em a helper macro which must be attached to a user supplied page trap handler, +in order to support mapping of reference \(lqhot\(hyspots\(rq +which extend through a page transition; +.XR page-trap ). ( +.QE +. +.NH 3 +.XN -S -- Optional Features of the \F[C]pdfhref\F[] Macro +.LP +The behaviour of a number of the +.CW pdfhref +macro operations can be modified, +by including +.EM "option specifiers" \(rq \(lq +after the operation specifying argument, +but +.EM before +any other arguments normally associated with the operation. +In +.EM all +cases, an option is specified by an +.EM "option flag" \(rq, \(lq +comprising an initial hyphen, +followed by one or two option identifying characters. +Additionally, +.EM some +options require +.EM "exactly one" +option argument; +for these options, the argument +.EM must +be specified, and it +.EM must +be separated from the preceding option flag by one or more +.EM spaces , +(tabs +.EM "must not" +be used). +It may be noted that this paradigm for specifying options +is reminiscent of most +Unix\(tm +shells; however, in the case of the +.CW pdfhref +macro, omission of the space separating an option flag from its argument is +.EM never +permitted. +.LP +A list of +.EM all +general purpose options supported by the +.CW pdfhref +macro is given below. +Note that not all options are supported for all +.CW pdfhref +operations; the operations affected by each option are noted in the list. +For +.EM most +operations, if an unsupported option is specified, +it will be silently ignored; however, this behaviour should +not be relied upon. +.LP +The general purpose options, supported by the +.CW pdfhref +macro, are:\(en +.QS +.IP \*[= -N\0 name > <] +Allows the +.CWI name > < +associated with a PDF reference destination +to be defined independently from the following text, +which describes the reference. +This option affects only the +.CWB M \& \& \(rq \(lq +operation of the +.CW pdfhref +macro, +.XR mark-dest ). ( +.IP \*[= -E] +Also used exclusively with the +.CWB M \& \& \(rq \(lq +operator, the +.CWB -E +option causes any specified +.CWI descriptive \& \& \~\c +.CWI text +arguments, +.XR mark-dest ), ( +to be copied, or +.EM echoed , +in the body text of the document, +at the point where the reference mark is defined; +(without the +.CWB -E +option, such +.CWI descriptive \& \& \~\c +.CWI text +will appear +.EM only +at points where links to the reference mark are placed, +and where the standard reference display format, +.XR set-format ), ( +is used). +.IP \*[= -D\0 dest > <] +Specifies the +.CW URI , +or the destination name associated with a PDF active link, +independently of the following text, +which describes the link and demarcates the link \(lqhot\(hyspot\(rq. +This option affects the behaviour of the +.CW pdfhref +macro's +.CWB L \& \& \(rq \(lq +and +.CWB W \& \& \(rq \(lq +operations. +.IP +When used with the +.CWB L \& \& \(rq \(lq +operator, the +.CWI dest > < +argument must specify a PDF \(lqnamed destination\(rq, +as defined using +.CW pdfhref +with the +.CWB M \& \& \(rq \(lq +operator. +.IP +When used with the +.CWB W \& \& \(rq \(lq +operator, +.CWI dest > < +must specify a link destination in the form of a +\(lquniform resource identifier\(rq, or +.CW URI , +.XR add-weblink ). ( +.IP \*[= -F\0 file > <] +When used with the +.CWB L \& \& \(rq \(lq +.CW pdfhref +operator, +.CWI file > < +specifies an external PDF file in which the named destination +for the link reference is defined. +This option +.EM must +be specified with the +.CWB L \& \& \(rq \(lq +operator, +to create a link to a destination in a different PDF document; +when the +.CWB L \& \& \(rq \(lq +operator is used +.EM without +this option, the link destination is assumed to be defined +within the same document. +.IP \*[= -P\0 \(dqprefix\(hytext\(dq > <] +Specifies +.CWI \(dqprefix\(hytext\(dq > < +to be attached to the +.EM start +of the text describing an active PDF document link, +with no intervening space, but without itself being included in the +active area of the link \(lqhot\(hyspot\(rq; +it is effective with the +.CWB L \& \& \(rq \(lq +and +.CWB W \& \& \(rq \(lq +.CW pdfhref +operators. +.IP +Typically, this option would be used to insert punctuation before +the link \(lqhot\(hyspot\(rq. +Thus, there is little reason for the inclusion of spaces in +.CWI \(dqprefix\(hytext\(dq > < ; +however, if such space is required, then the enclosing double quotes +.EM must +be specified, as indicated. +.IP \*[= -A\0 \(dqaffixed\(hytext\(dq > <] +Specifies +.CWI \(dqaffixed\(hytext\(dq > < +to be attached to the +.EM end +of the text describing an active PDF document link, +with no intervening space, but without itself being included in the +active area of the link \(lqhot\(hyspot\(rq; +it is effective with the +.CWB L \& \& \(rq \(lq +and +.CWB W \& \& \(rq \(lq +.CW pdfhref +operators. +.IP +Typically, this option would be used to insert punctuation after +the link \(lqhot\(hyspot\(rq. +Thus, there is little reason for the inclusion of spaces in +.CWI \(dqaffixed\(hytext\(dq > < ; +however, if such space is required, then the enclosing double quotes +.EM must +be specified, as indicated. +.IP \*[= -T\0 tag > <] +When specified with the +.CWB O \& \& \(rq \(lq +operator, +.CWI tag > < +is appended to the \(lqbookmark\(rq name assigned to the generated outline entry. +This option is +.EM required , +to distinguish between the series of \(lqbookmark\(rq names generated in +individual passes of the +.CW groff +formatter, when the final PDF document is to be assembled +from a number of separately formatted components; +.XR multipart-outline ). ( +.IP \*[= -X] +This +.CW pdfhref +option is used with either the +.CWB M \& \& \(rq \(lq +operator, or with the +.CWB L \& \& \(rq \(lq +operator. +.IP +When used with the +.CWB M \& \& \(rq \(lq +operator, +.XR mark-dest ), ( +it ensures that a cross reference record for the marked destination +will be included in the document reference map, +.XR export-map ). ( +.IP +When used with the +.CWB L \& \& \(rq \(lq +operator, +.XR link-named ), ( +it causes the reference to be displayed in the standard cross reference format, +.XR set-format ), ( +but substituting the +.CWI descriptive \& \& \~\c +.CWI text +specified in the +.CW pdfhref \& \(lq +.CW L \(rq +argument list, +for the description specified in the document reference map. +.IP \*[= --] +Marks the end of the option specifiers. +This may be used with all +.CW pdfhref +operations which accept options, to prevent +.CW pdfhref +from interpreting any following arguments as option specifiers, +even if they would otherwise be interpreted as such. +It is also useful when the argument list to +.CW pdfhref +contains special characters \(em any special character, +which is not valid in a +.CW groff +macro name, will cause a parsing error, if +.CW pdfhref +attempts to match it as a possible option flag; +using the +.CW -- \(rq \(lq +flag prevents this, so suppressing the +.CW groff +warning message, which would otherwise ensue. +.IP +Using this flag after +.EM all +sequences of macro options is recommended, +even when it is not strictly necessary, +if only for the entirely cosmetic benefit of visually separating +the main argument list from the sequence of preceding options. +.QE +.LP +In addition to the +.CW pdfhref +options listed above, a supplementary set of two character options are defined. +These supplementary options, listed below, are intended for use with the +.CWB L \& \& \(rq \(lq +operator, in conjunction with the +.CWB -F \& \& \~\c +.CWBI file > < +option, to specify alternate file names, +in formats compatible with the file naming conventions +of alternate operating systems; +they will be silently ignored, if used in any other context. +.LP +The supported alternate file name options, +which are ignored if the +.CWB -F \& \& \~\c +.CWBI file > < +option is not specified, are:\(en +.QS +.IP \*[= -DF\0 dos\(hyfile > <] +Specifies the name of the file in which a link destination is defined, +using the file naming semantics of the +.CW MS\(hyDOS \*(rg +operating system. +When the PDF document is read on a machine +where the operating system uses the +.CW MS\(hyDOS \*(rg +file system, then +.CWI dos\(hyfile > < +is used as the name of the file containing the reference destination, +overriding the +.CWI file > < +argument specified with the +.CWB -F +option. +.IP \*[= -MF\0 mac\(hyfile > <] +Specifies the name of the file in which a link destination is defined, +using the file naming semantics of the +.CW Apple \*(rg +.CW Macintosh \*(rg +operating system. +When the PDF document is read on a machine +where the operating system uses the +.CW Macintosh \*(rg +file system, then +.CWI mac\(hyfile > < +is used as the name of the file containing the reference destination, +overriding the +.CWI file > < +argument specified with the +.CWB -F +option. +.IP \*[= -UF\0 unix\(hyfile > <] +Specifies the name of the file in which a link destination is defined, +using the file naming semantics of the +.CW Unix \(tm +operating system. +When the PDF document is read on a machine +where the operating system uses +.CW POSIX +file naming semantics, then +.CWI unix\(hyfile > < +is used as the name of the file containing the reference destination, +overriding the +.CWI file > < +argument specified with the +.CWB -F +option. +.IP \*[= -WF\0 win\(hyfile > <] +Specifies the name of the file in which a link destination is defined, +using the file naming semantics of the +.CW MS\(hyWindows \*(rg +32\(hybit operating system. +When the PDF document is read on a machine +where the operating system uses any of the +.CW MS\(hyWindows \*(rg +file systems, with long file name support, then +.CWI win\(hyfile > < +is used as the name of the file containing the reference destination, +overriding the +.CWI file > < +argument specified with the +.CWB -F +option. +.QE +. +.NH 3 +.XN -N mark-dest -- Marking a Reference Destination +.LP +The +.CW pdfhref +macro may be used to create active links to any Internet resource, +specified by its +.CW URI , +or to any \(lqnamed destination\(rq, +either within the same document, or in another PDF document. +Although the PDF specification allows link destinations to be defined +in terms of a page number, and an associated view specification, +this style of reference is not currently supported by the +.CW pdfhref +macro, because it is not possible to adequately bind the specification +for the destination with the intended reference context. +.LP +References to Internet resources are interpreted in accordance with the +.CW W3C +standard for defining a +.CW URI ; +hence the only prerequisite, for creating a link to any Internet resource, +is that the +.CW URI +be properly specified, when declaring the reference; +.XR add-weblink ). ( +In the case of references to \(lqnamed destinations\(rq in PDF documents, +however, it is necessary to provide a mechanism for creating such +\(lqnamed destinations\(rq. +This may be accomplished, by invoking the +.CW pdfhref +macro in the form +.QP +.fam C +.B ".pdfhref M" +.B -N \& [ +.I name >] < +.B -X ] [ +.B -E ] [ +.I "descriptive text ...\&" ] [ +.LP +This creates a \(lqnamed destination\(rq reference mark, with its name specified by +.CWI name > < , +or, if the +.CWB -N +option is not specified, by the first word of +.CWI descriptive \& \& \~\c +.CWI text \& \& ; +(note that this imposes the restriction that, +if the +.CWB -N +option is omitted, then +.EM "at least" +one word of +.CWI descriptive \& \& \~\c +.CWI text +.EM must +be specified). +Additionally, a reference view will be automatically defined, +and associated with the reference mark, +.XR pdfhref-view ), ( +.\" and, if any +.\" .CWI descriptive +.\" .CWI text +.\" is specified, or the +and, if the +.CWB -X +option is specified, and no document cross reference map has been imported, +.XR import-map ), ( +then a cross reference mapping record, +.XR export-map ), ( +will be written to the +.CW stdout +stream; +this may be captured, and subsequently used to generate a cross reference map +for the document, +.XR create-map ). ( +.LP +When a \(lqnamed destination\(rq reference mark is created, using the +.CW pdfhref +macro's +.CWB M \& \& \(rq \(lq +operator, there is normally no visible effect in the formatted document; any +.CWI descriptive \& \& \~\c +.CWI text +which is specified will simply be stored in the cross reference map, +for use when a link to the reference mark is created. +This default behaviour may be changed, by specifying the +.CWB -E +option, which causes any specified +.CWI descriptive \& \& \~\c +.CWI text +to be \(lqechoed\(rq in the document text, +at the point where the reference mark is placed, +in addition to its inclusion in the cross reference map. +. +.NH 4 +.XN -N export-map -- Mapping a Destination for Cross Referencing +.LP +Effective cross referencing of +.EM any +document formatted by +.CW groff +requires multiple pass formatting. +Details of how this multiple pass formatting may be accomplished, +when working with the +.CW pdfmark +macros, will be discussed later, +.XR do-xref ); ( +at this stage, the discussion will be restricted to the initial preparation, +which is required at the time when the cross reference destinations are defined. +.LP +The first stage, in the process of cross referencing a document, +is the generation of a cross reference map. +Again, the details of +.EM how +the cross reference map is generated will be discussed in +.pdfhref F SECREF L -D do-xref -A ; +.pdfhref F +however, it is important to recognize that +.EM what +content is included in the cross reference map is established +when the reference destination is defined \(em it is derived +from the reference data exported on the +.CW stderr +stream by the +.CW pdfhref +macro, when it is invoked with the +.CWB M \& \& \(rq \(lq +operator, and is controlled by whatever definition of the string +.CW PDFHREF.INFO +is in effect, when the +.CW pdfhref +macro is invoked. +.LP +The initial default setting of +.CW PDFHREF.INFO +is +.QP +.CW ".ds PDFHREF.INFO page \e\en% \e\e$*" +.LP +which ensures that the cross reference map will contain +at least a page number reference, supplemented by any +.CWI descriptive \& \& \~\c +.CWI text +which is specified for the reference mark, as defined by the +.CW pdfhref +macro, with its +.CWB M \& \& \(rq \(lq +operator; this may be redefined by the user, +to export additional cross reference information, +or to modify the default format for cross reference links, +.XR set-format ). ( +. +.NH 4 +.XN -N pdfhref-view -- Associating a Document View with a Reference Mark +.LP +In the same manner as each document outline reference, defined by the +.CW pdfhref +macro with the +.CWB O \& \& \(rq \(lq +operator, +.XR add-outline ), ( +has a specific document view associated with it, +each reference destination marked by +.CW pdfhref +with the +.CWB M \& \& \(rq \(lq +operator, requires an associated document view specification. +.LP +The mechanism whereby a document view is associated with a reference mark +is entirely analogous to that employed for outline references, +.XR outline-view ), ( +except that the +.CW PDFHREF.VIEW +string specification is used, in place of the +.CW PDFBOOKMARK.VIEW +specification. +Thus, the reference view is defined in terms of:\(en +.QS +.IP \*[= PDFHREF.VIEW] +A string, +establishing the position of the reference mark within the viewing window, +and the magnification at which the document will be viewed, +at the location of the marked reference destination; +by default, it is defined by +.RS +.QP +.CW ".ds PDFHREF.VIEW /FitH \e\en[PDFPAGE.Y] u" +.RE +.IP +which displays the reference destination at the top of the viewing window, +with the magnification set to fit the page width to the width of the window. +.IP \*[= PDFHREF.VIEW.LEADING] +A numeric register, +specifying additional spacing, to be placed between the top of the display +window and the actual position at which the location of the reference +destination appears within the window. +This register is shared with the view specification for outline references, +and thus has the same default initial setting, +.RS +.QP +.CW ".nr PDFHREF.VIEW.LEADING 5.0p" +.RE +.IP +as in the case of outline reference views. +.IP +Again, notice that +.CW PDFHREF.VIEW.LEADING +does not represent true typographic \(lqleading\(rq, +since any preceding text, set in the specified display space, +will be visible at the top of the viewing window, +when the reference is selected. +.QE +.LP +Just as the view associated with outline references may be changed, +by redefining +.CW PDFBOOKMARK.VIEW , +so the view associated with marked reference destinations may be changed, +by redefining +.CW PDFHREF.VIEW , +and, if desired, +.CW PDFHREF.VIEW.LEADING ; +such changes will become effective for all reference destinations marked +.EM after +these definitions are changed. +(Notice that, since the specification of +.CW PDFHREF.VIEW.LEADING +is shared by both outline reference views and marked reference views, +if it is changed, then the views for +.EM both +reference types are changed accordingly). +.LP +It may again be noted, that the +.CW PDFPAGE.Y +register is used in the definition of +.CW PDFHREF.VIEW , +just as it is in the definition of +.CW PDFBOOKMARK.VIEW ; +all comments in +.pdfhref F SECREF L -D outline-view +.pdfhref F +relating to its use, and indeed to page position computations in general, +apply equally to marked reference views and to outline reference views. +. +.NH 3 +.XN -N link-named -- Linking to a Marked Reference Destination +.LP +Any named destination, such as those marked by the +.CW pdfhref +macro, using it's +.CWB M \& \& \(rq \(lq +operator, may be referred to from any point in +.EM any +PDF document, using an +.EM "active link" ; +such active links are created by again using the +.CW pdfhref +macro, but in this case, with the +.CWB L \& \& \(rq \(lq +operator. +This operator provides support for two distinct cases, +depending on whether the reference destination is defined in +the same document as the link, +.XR link-intern ), ( +or is defined as a named destination in a different PDF document, +.XR link-extern ). ( +. +.NH 4 +.XN -N link-intern -- References within a Single PDF Document +.LP +The general syntactic form for invoking the +.CW pdfhref +macro, +when creating a link to a named destination within the same PDF document is +.QP +.fam C +.B .pdfhref +.B L +.B -D \& [ +.BI dest-name >] < +.B -P \& [ +.BI prefix-text >] < +.B -A \& [ +.BI affixed-text >] < +\e +.br +\0\0\0 +.B -X ] [ +.B -- ] [ +.I "descriptive text ...\&" ] [ +.LP +where +.CWI dest-name > < +specifies the name of the link destination, +as specified using the +.CW pdfhref +.CWB M \& \& \(rq \(lq +operation; (it may be defined either earlier in the document, +to create a backward reference, or later, to create a forward reference). +.\" +.\" Here's a example of how to add an iconic annotation. +.\" +.\".pdfnote -T "Internal Cross References" \ +.\" This description is rather terse, and could benefit from \ +.\" the inclusion of an example. +.LP +If any +.CWI descriptive \& \& \~\c +.CWI text +arguments are specified, then they will be inserted into the +.CW groff +output stream, to define the text appearing in the \(lqhot\(hyspot\(rq +region of the link; +this will be printed in the link colour specified by the string, +.CW PDFHREF.TEXT.COLOUR , +which is described in +.XR-NO-PREFIX set-colour . +If the +.CWB -X +option is also specified, then the +.CWI descriptive \& \& \~\c +.CWI text +will be augmented, by prefacing it with page and section number indicators, +in accordance with the reference formatting rules which are in effect, +.XR set-format ); ( +such indicators will be included within the active link region, +and will also be printed in the link colour. +.LP +Note that +.EM either +the +.CWB -D \& \& \~\c +.CWBI dest\(hyname > < +option, +.EM or +the +.CWI descriptive \& \& \~\c +.CWI text +arguments, +.EM "but not both" , +may be omitted. +If the +.CWB -D \& \& \~\c +.CWBI dest\(hyname > < +option is omitted, then the first word of +.CWI descriptive \& \& \~\c +.CWI text \& \& , +i.e.\~all text up to but not including the first space, +will be interpreted as the +.CWBI dest\(hyname > < +for the link; this text will also appear in the running text of the document, +within the active region of the link. +Alternatively, if the +.CWB -D \& \& \~\c +.CWBI dest\(hyname > < +option +.EM is +specified, and +.CWI descriptive \& \& \~\c +.CWI text +is not, +then the running text which defines the reference, +and its active region, +will be derived from the reference description which is specified +when the named destination is marked, +.XR mark-dest ), ( +and will be formatted according to the reference formatting rules +which are in effect, when the reference is placed, +.XR set-format ); ( +in this case, it is not necessary to specify the +.CWB -X +option to activate automatic formatting of the reference \(em it is implied, +by the omission of all +.CWI descriptive \& \& \~\c +.CWI text +arguments. +.LP +The +.CWB -P \& \& \~\c +.CWBI prefix\(hytext > < +and +.CWB -A \& \& \~\c +.CWBI affixed\(hytext > < +options may be used to specify additional text +which will be placed before and after the linked text respectively, +with no intervening space. +Such prefixed and affixed text will be printed in the normal text colour, +and will not be included within the active region of the link. +This feature is mostly useful for creating parenthetical references, +or for placing punctuation adjacent to, +but not included within, +the text which defines the active region of the link. +.LP +The operation of the +.CW pdfhref +macro, when used with its +.CWB L \& \& \(rq \(lq +operator to place a link to a named PDF destination, +may best be illustrated by an example. +However, since the appearance of the link will be influenced by +factors established when the named destination is marked, +.XR mark-dest ), ( +and also by the formatting rules in effect when the link is placed, +the presentation of a suitable example will be deferred, +until the formatting mechanism has been explained, +.XR set-format ). ( +. +.NH 4 +.XN -N link-extern -- References to Destinations in Other PDF Documents +.LP +The +.CW pdfhref +macro's +.CWB L \& \& \(rq \(lq +operator is not restricted to creating reference links +within a single PDF document. +When the link destination is defined in a different document, +then the syntactic form for invoking +.CW pdfhref +is modified, by the addition of options to specify the +name and location of the PDF file in which the destination is defined. +Thus, the extended +.CW pdfhref +syntactic form becomes +.QP +.fam C +.B .pdfhref +.B L +.B -F +.BI file > < +.B -D \& [ +.BI dest-name >] < +\e +.br +\0\0\0 +.B -DF \& [ +.BI dos-file >] < +.B -MF \& [ +.BI mac-file >] < +.B -UF \& [ +.BI unix-file >] < +\e +.br +\0\0\0 +.B -WF \& [ +.BI win-file >] < +.B -P \& [ +.BI prefix-text >] < +.B -A \& [ +.BI affixed-text >] < +\e +.br +\0\0\0 +.B -X ] [ +.B -- ] [ +.I "descriptive text ...\&" ] [ +.LP +where the +.CWB -F \& \& \~\c +.CWBI file > < +option serves +.EM two +purposes: it both indicates to the +.CW pdfhref +macro that the specified reference destination +is defined in an external PDF file, +and it also specifies the normal path name, +which is to be used to locate this file, +when a user selects the reference. +.LP +In addition to the +.CWB -F \& \& \~\c +.CWBI file > < +option, which +.EM must +be specified when referring to a destination in an external PDF file, +the +.CWB -DF \& \& \~\c +.CWBI dos\(hyfile > < , +.CWB -MF \& \& \~\c +.CWBI mac\(hyfile > < , +.CWB -UF \& \& \~\c +.CWBI unix\(hyfile > < +and +.CWB -WF \& \& \~\c +.CWBI win\(hyfile > < +options may be used to specify the location of the file +containing the reference destination, +in a variety of operating system dependent formats. +These options assign their arguments to the +.CW /DosFile , +.CW /MacFile , +.CW /UnixFile +and +.CW /WinFile +keys of the generated +.CW pdfmark +respectively; thus when any of these options are specified, +.EM "in addition to" +the +.CWB -F \& \& \~\c +.CWBI file > < +option, and the document is read on the appropriate operating systems, +then the path names specified by +.CWBI dos\(hyfile > < , +.CWBI mac\(hyfile > < , +.CWBI unix\(hyfile > < +and +.CWBI win\(hyfile > < +will be searched, +.EM instead +of the path name specified by +.CWBI file > < , +for each of the +.CW MS\(hyDOS \*(rg, +.CW Apple \*(rg +.CW Macintosh \*(rg, +.CW Unix \(tm +and +.CW MS\(hyWindows \*(rg +operating systems, respectively; see the +.pdfmark-manual , +for further details. +.LP +Other than the use of these additional options, +which specify that the reference destination is in an external PDF file, +the behaviour of the +.CW pdfhref +.CWB L \& \& \(rq \(lq +operator, with the +.CWB -F \& \& \~\c +.CWBI file > < +option, remains identical to its behaviour +.EM without +this option, +.XR link-intern ), ( +with respect to the interpretation of other options, +the handling of the +.CWI descriptive \& \& \~\c +.CWI text +arguments, and the formatting of the displayed reference. +.LP +Once again, since the appearance of the reference is determined by +factors specified in the document reference map, +and also by the formatting rules in effect when the reference is placed, +the presentation of an example of the placing of +a reference to an external destination will be deferred, +until the formatting mechanism has been explained, +.XR set-format ). ( +. +.NH 3 +.XN -N add-weblink -- Linking to Internet Resources +.LP +In addition to supporting the creation of cross references +to named destinations in PDF documents, the +.CW pdfhref +macro also has the capability to create active links to Internet resources, +or indeed to +.EM any +resource which may be specified by a Uniform Resource Identifier, +(which is usually abbreviated to the acronym \(lqURI\(rq, +and sometimes also referred to as a Uniform Resource Locator, +or \(lqURL\(rq). +.LP +Since the mechanism for creating a link to a URI differs somewhat +from that for creating PDF references, the +.CW pdfhref +macro is invoked with the +.CWB W \& \& \(rq \(lq +(for \(lqweb\(hylink\(rq) operator, rather than the +.CWB L \& \& \(rq \(lq +operator; nevertheless, the invocation syntax is similar, having the form +.QP +.fam C +.B .pdfhref +.B W +.B -D \& [ +.BI URI >] < +.B -P \& [ +.BI prefix-text >] < +.B -A \& [ +.BI affixed-text >] < +\e +.br +\0\0\0 +.B -- ] [ +.I "descriptive text ...\&" +.LP +where the optional +.CWB -D +.CWBI URI > < +modifier specifies the address for the target Internet resource, +in any appropriate +.EM "Uniform Resource Identifier" +format, while the +.CWI descriptive +.CWI text +argument specifies the text which is to appear in the \(lqhot\(hyspot\(rq +region, and the +.CWB -P +.CWBI prefix\(hytext > < +and +.CWB -A +.CWBI affixed\(hytext > < +options have the same effect as in the case of local document links, +.XR link-intern ). ( +.LP +Notice that it is not mandatory to include the +.CWB -D +.CWBI URI > < +in the link specification; if it +.EM is +specified, then it is not necessary for the URI to appear, +in the running text of the document \(em the +.CWI descriptive +.CWI text +argument exactly defines the text +which will appear within the \(lqhot\(hyspot\(rq region, +and this need not include the URI. +However, if the +.CWB -D \& \& \~\c +.CWBI URI > < +specification is omitted, then the +.CWI descriptive +.CWI text +argument +.EM must +be an +.EM exact +representation of the URI, which +.EM will , +therefore, appear as the entire content of the \(lqhot\(hyspot\(rq. +For example, we could introduce a reference to +.pdfhref W -D \*[GROFF-WEBSITE] -A , the groff web site +in which the actual URI is concealed, by using mark up such as:\(en +.DS I +.CW +For example, we could introduce a reference to +\&.pdfhref W -D \*[GROFF-WEBSITE] -A , the groff web site +in which the actual URI is concealed, +.DE +Alternatively, +to refer the reader to the groff web site, +making it obvious that the appropriate URI is +.pdfhref W -A , \*[GROFF-WEBSITE] +the requisite mark up might be:\(en +.DS I +.CW +to refer the reader to the groff web site, +making it obvious that the appropriate URI is +\&.pdfhref W -A , \*[GROFF-WEBSITE] +the requisite mark up might be:\e(en +.DE +. +.NH 3 +.XN -N set-format -- Establishing a Format for References +.LP +There are two principal aspects to be addressed, +when defining the format to be used when displaying references. +Firstly, it is desirable to provide a visual cue, +to indicate that the text describing the reference is imbued +with special properties \(em it is dynamically linked to the reference +destination \(em and secondly, the textual content should +describe where the link leads, and ideally, +it should also describe the content of the reference destination. +.LP +The visual cue, +that a text region defines a dynamically linked reference, +is most commonly provided by printing the text within the active +region in a distinctive colour. +This technique will be employed automatically by the +.CW pdfhref +macro \(em +.XR set-colour +\(em unless the user specifically chooses to adopt, and implement, +some alternative strategy. +. +.NH 4 +.XN -N set-colour -- Using Colour to Demarcate Link Regions +.LP +Typically, when a PDF document contains +.EM active +references to other locations, either within the same document, +or even in other documents, or on the World Wide Web, +it is usually desirable to make the regions +where these active links are placed stand out from the surrounding text. +. +.NH 4 +.XN -N user-format -- Specifying Reference Text Explicitly +. +.NH 4 +.XN -N auto-format -- Using Automatically Formatted Reference Text +. +.NH 4 +.XN -N custom-format -- Customizing Automatically Formatted Reference Text +.LP +It is incumbent on the user, +if employing automatic formatting of the displayed reference, +.XR set-format ), ( +to ensure that an appropriate reference definition +is created for the reference destination, +and is included in the reference map for the document +in which the reference will appear; +thus, it may be easiest to +.EM always +use manual formatting for external references. +. +.NH 3 +.XN Problematic Links +.LP +Irrespective of whether a +.CW pdfhref +reference is placed using the +.CWB L \& \& \(rq \(lq +operator, or the +.CWB W \& \& \(rq \(lq +operator, there may be occasions when the resulting link +does function as expected. +A number of scenarios, which are known to be troublesome, +are described below. +. +.NH 4 +.XN -N page-trap -- Links with a Page Transition in the Active Region +.LP +When a link is placed near the bottom of a page, +it is possible that its active region, or \(lqhot\(hyspot\(rq, +may extend on to the next page. +In this situation, a page trap macro is required +to intercept the page transition, and to restart the mapping of +the \(lqhot\(hyspot\(rq boundary on the new page. +.LP +The +.CW pdfmark +macro package includes a suitable page trap macro, to satisfy this requirement. +However, to avoid pre\(hyempting any other requirement the user may have for +a page transition trap, this is +.EM not +installed as an active page trap, +unless explicitly requested by the user. +.LP +To enable proper handling of page transitions, +which occur within the active regions of reference links, +the user should:\(en +.QS +.nr ITEM 0 1 +.IP \n+[ITEM]. +Define a page transition macro, to provide whatever features may be required, +when a page transition occurs \(em e.g.\& printing footnotes, +adding page footers and headers, etc. +This macro should end by setting the output position at the correct +vertical page offset, where the printing of running text is to restart, +following the page transition. +.IP \n+[ITEM]. +Plant a trap to invoke this macro, at the appropriate vertical position +marking the end of normal running text on each page. +.KS +.IP \n+[ITEM]. +Initialize the +.CW pdfhref +hook into this page transition trap, by invoking +.RS +.IP +.fam C +.B "pdfhref I -PT" +.BI macro-name > < +.LP +where +.CWBI macro-name > < +is the name of the user supplied page trap macro, +to ensure that +.CW pdfhref +will correctly restart mapping of active link regions, +at the start of each new page. +.KE +.RE +.QE +.LP +It may be observed that this initialization of the +.CW pdfhref +page transition hook is, typically, required only once +.EM before +document formatting begins. +Users of document formatting macro packages may reasonably expect that +this initialization should be performed by the macro package itself. +Thus, writers of such macro packages which include +.CW pdfmark +bindings, should provide appropriate initialization, +so relieving the end user of this responsibility. +The following example, abstracted from the sample +.CW ms +binding package, +.CW spdf.tmac , +illustrates how this may be accomplished:\(en +.DS I +.CW +\&.\e" groff "ms" provides the "pg@bottom" macro, which has already +\&.\e" been installed as a page transition trap. To ensure proper +\&.\e" mapping of "pdfhref" links which overflow the bottom of any +\&.\e" page, we need to install the "pdfhref" page transition hook, +\&.\e" as an addendum to this macro. +\&. +\&.pdfhref I -PT pg@bottom +.DE +. +.NH 2 +.XN -N add-note -- Annotating a PDF Document using Pop-Up Notes +. +.NH 2 +.XN -S -N pdfsync -- Synchronizing Output and \F[C]pdfmark\F[] Contexts +.LP +It has been noted previously, that the +.CW pdfview +macro, +.XR docview ), ( +the +.CW pdfinfo +macro, +.XR docinfo ), ( +and the +.CW pdfhref +macro, when used to create a document outline, +.XR add-outline ), ( +do not immediately write their +.CW pdfmark +output to the \*[PostScript] data stream; +instead, they cache their output, in a +.CW groff +diversion, in the case of the +.CW pdfview +and +.CW pdfinfo +macros, or in an ordered collection of strings and numeric registers, +in the case of the document outline, +until a more appropriate time for copying it out. +In the case of +.CW pdfview +and +.CW pdfinfo +\(lqmeta\(hydata\(rq, +this \(lqmore appropriate time\(rq is explicitly chosen by the user; +in the case of document outline data, +.EM some +cached data may be implicitly written out as the document outline is compiled, +but there will +.EM always +be some remaining data, which must be explicitly flushed out, before the +.CW groff +formatting process is allowed to complete. +.LP +To allow the user to choose when cached +.CW pdfmark +data is to be flushed to the output stream, the +.CW pdfmark +macro package provides the +.CW pdfsync +macro, (to synchronize the cache and output states). +In its simplest form, it is invoked without arguments, i.e. +.QP +.fam C +.B .pdfsync +.LP +This form of invocation ensures that +.EM both +the \(lqmeta\(hydata cache\(rq, containing +.CW pdfview +and +.CW pdfinfo +data, +.EM and +the \(lqoutline cache\(rq, +containing any previously uncommitted document outline data, +are flushed; ideally, this should be included in a +.CW groff +\(lqend macro\(rq, to ensure that +.EM both +caches are flushed, before +.CW groff +terminates. +.LP +Occasionally, +it may be desirable to flush either the \(lqmeta\(hydata cache\(rq, +without affecting the \(lqoutline cache\(rq, or vice\(hyversa, +at a user specified time, prior to reaching the end of the document. +This may be accomplished, by invoking the +.CW pdfsync +macro with an argument, i.e. +.QP +.fam C +.B ".pdfsync M" +.LP +to flush only the \(lqmeta\(hydata cache\(rq, or +.QP +.fam C +.B ".pdfsync O" +.LP +to flush only the \(lqoutline cache\(rq. +.LP +The \(lqmeta\(hydata cache\(rq can normally be safely flushed +in this manner, at any time +.EM after +output of the first page has started; +(it may cause formatting problems, +most notably the appearance of unwanted white space, if flushed earlier, +or indeed, if flushed immediately after a page transition, +but before the output of the content on the new page has commenced). +Caution is required, however, when explicitly flushing the +\(lqoutline cache\(rq, since if the outline is to be +subsequently extended, then the first outline entry after flushing +.EM must +be specified at level 1. +Nevertheless, such explicit flushing may occasionally be necessary; +for example, the +.CW TC +macro in the +.CW spdf.tmac +package, +.XR using-spdf ), ( +invokes +.CW ".pdfsync\ O" \(rq \(lq +to ensure that the outline for the \(lqbody\(rq section of the document +is terminated, +.EM before +it commences the formatting of the table of contents section. +.bp +. +.NH 1 +.XN -N pdf-layout -- PDF Document Layout +.LP +The +.CW pdfmark +macros described in the preceding section, +.XR pdf-features ), ( +provide no inherent document formatting capability of their own. +However, +they may be used in conjunction with any other +.CW groff +macro package of the user's choice, +to add such capability. +.LP +In preparing this document, the standard +.CW ms +macro package, supplied as a component of the GNU Troff distribution, +has been employed. +To facilitate the use of the +.CW pdfmark +macros with the +.CW ms +macros, +a binding macro package, +.CW spdf.tmac , +has been created. +The use of this binding macro package is described in the following section, +.XR using-spdf ); ( +it may also serve as an example to users of other standard +.CW groff +macro packages, +as to how the +.CW pdfmark +macros may be employed with their chosen primary macro package. +. +.NH 2 +.XN -S -N using-spdf -- Using \F[C]pdfmark\F[] Macros with the \F[C]ms\F[] Macro Package +.LP +The use of the binding macro package, +.CW spdf.tmac , +allows for the use of the +.CW pdfmark +macros in conjunction with the +.CW ms +macros, +simply by issuing a +.CW groff +command of the form\** +.FS +Once again, +.pdfhref L -D pdf-features-fn -- as noted in footnote\*{\n[pdf-features-fn]\*} +to +.XR-NO-PREFIX pdf-features , +do not specify any +.CW -T \^\c +.CWI dev +option, +other than +.CW -T \^\c +.CW ps , +or +.CW -T \^\c +.CW pdf ; +specify +.CW -T \^\c +.CW pdf , +if you wish to avoid the conversion of \*[PostScript] output to PDF, +which will be required if you specify +.CW -T \^\c +.CW ps , +or if you omit the +.CW -T \^\c +.CWI dev +option entirely. +.FE +.QP +.fam C +groff [-Tps\h'0.2p'|\h'0.2p'-Tpdf] [-m\F[]\|\|\FC\c +.B spdf +.I options \F[]\|\|\FC\c [- +.I file \F[]\|\|\FC\c "...] " +\&... +.LP +When using the +.CW spdf.tmac +package, the +.CW groff +input files may be marked up using any of the standard +.CW ms +macros to specify document formatting, +while PDF features may be added, +using any of the +.CW pdfmark +macros described previously, +.XR pdf-features ). ( +Additionally, +.CW spdf.tmac +defines a number of convenient extensions to the +.CW ms +macro set, to better accomodate the use of PDF features within the +.CW ms +formatting framework, +and to address a number of +.CW ms +document layout issues, +which require special handling when producing PDF documents. +These additional macros, +and the issues they are intended to address, +are described below. +. +.NH 3 +.XN -S -- \F[C]ms\F[] Section Headings in PDF Documents +.LP +Traditionally, +.CW ms +provides the +.CW NH +and +.CW SH +macros, to specify section headings. +However, +there is no standard mechanism for generating a +table of contents entry based on the text of the section heading; +neither is there any recognized standard method for establishing a +cross reference link to the section. +.LP +To address this +.CW ms +limitation, +.CW spdf.tmac +defines the +.CW XN +macro, +.XR xn-macro ), ( +to be used in conjunction with the +.CW NH +macro. +. +.NH 4 +.XN -S -N xn-macro -- The \F[C]XN\F[] Macro +.bp +. +.NH 1 +.XN The PDF Publishing Process +. +.NH 2 +.XN -N do-xref -- Resolving Cross References +. +.NH 3 +.XN -N create-map -- Creating a Document Reference Map +. +.NH 3 +.XN -N import-map -- Deploying a Document Reference Map +.TC +.\" Local Variables: +.\" mode: nroff +.\" End: +.\" vim: filetype=groff: diff --git a/contrib/pdfmark/pdfmark.tmac b/contrib/pdfmark/pdfmark.tmac new file mode 100644 index 0000000..5f664f2 --- /dev/null +++ b/contrib/pdfmark/pdfmark.tmac @@ -0,0 +1,1953 @@ +.ig + +pdfmark.tmac + +Copyright (C) 2004-2020 Free Software Foundation, Inc. + Written by Keith Marshall (keith.d.marshall@ntlworld.com) + +This file 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/>. + +Author's Note +============= + +While I have written this macro package from scratch, much of my +inspiration has come from discussion on the groff mailing list +(mailto:groff@gnu.org). I am particularly indebted to: + + Kees Zeelenberg, for an earlier macro package he posted, + a study of which helped me to get started. + + Carlos J. G. Duarte and Werner Lemberg, whose discussion + on computation of the bounding boxes for link "hot-spots" + forms the basis of such computations in this package. +.. +.if !\n(.g .ab These pdfmark macros require groff. +.\" +.\" Check if we have already been loaded -- do not reload +.if d pdfmark .nx +.\" +.\" ====================================================================== +.\" Module PDFMARK: Insert Arbitrary PDFMARK Code in the Postscript Stream +.\" ====================================================================== +.\" +.\" PDFMARK output may be disabled, by zeroing the PDFOPMODE register, +.\" ( which mimics a more generic OPMODE, if it is defined ). +.\" +.if rOPMODE .aln PDFOPMODE OPMODE +.\" +.\" but if OPMODE wasn't defined, +.\" then make the default PDFMARK mode ENABLED. +.\" +.if !rPDFOPMODE .nr PDFOPMODE 1 +.\" +.\" PDFMARK output must be constrained to a maximum line length limit, +.\" for strict compliance with the Postscript DSC. This limit is defined +.\" in register "PDFMARK.FOLDWIDTH.MAX". This is user definable, up to a +.\" ceiling value of 255, which is also its default value; this limit +.\" is enforced for each PDFMARK, by macro "pdf*pdfmark.limit". +.\" +.de pdf*pdfmark.limit +.\" ---------------------------------------------------------------- +.\" Usage: +.\" .pdf*pdfmark.limit REGISTER-NAME DEFAULT-MAXIMUM-VALUE +.\" ---------------------------------------------------------------- +.\" +.\" If a register named REGISTER-NAME has not been defined, then +.\" define it now, with default value = DEFAULT-MAXIMUM-VALUE. +.\" +.if !r\\$1 .nr \\$1 \\$2 +.\" +.\" But when it has already been defined, ensure that its value does +.\" not exceed DEFAULT-MAXIMUM-VALUE; if value does exceed this ceiling, +.\" then redefine it, to enforce the limit. +.\" +.if (\\n[\\$1] > \\$2) .nr \\$1 \\$2 +.. +.\" The "pdfmark" macro is responsible for emitting the appropriate +.\" Postscript code. +.\" +.de pdfmark +.\" ---------------------------------------------------------------- +.\" Usage: +.\" .pdfmark text of pdfmark instruction +.\" Macro supplies the required opening "[" and closing "pdfmark" +.\" operator; DO NOT include them in the instruction text! +.\" ---------------------------------------------------------------- +.\" +.if \\n[PDFOPMODE] \{\ +.\" +.\" Strict DSC compliance forbids emission of ps:exec lines which +.\" exceed 255 characters in length. We will allow the user to specify +.\" an alternative lesser limit ... +.\" +. pdf*pdfmark.limit PDFMARK.FOLDWIDTH.MAX 255 +.\" +.\" ... and we will also support a second lesser limit, which will be +.\" applied to literal text parenthetically embedded within the PDFMARK. +.\" +. pdf*pdfmark.limit PDFMARK.FOLDWIDTH \\n[PDFMARK.FOLDWIDTH.MAX] +.\" +.\" We will push out the entire PDFMARK in one chunk, provided it fits +.\" within this limit. +.\" +. length pdf:length "[\\$* pdfmark\" +. ie !(\\n[pdf:length] > \\n[PDFMARK.FOLDWIDTH]) \{\ +. \" +. \" This PDFMARK is suitable for single chunk output ... +. \" +. nop \!x X ps:exec [\\$* pdfmark +. \} +. el \{\ +. \" ... but, when the limit would be violated, then we must +. \" recompose the specified PDFMARK, spreading it over as many +. \" continuation lines as are necessary. +. \" +. als pdf*compose pdf*compose.first +. while \\n(.$ \{\ +. pdf*compose \\$1 +. shift +. \} +. \" +. \" Complete the PDFMARK recomposition, by appending a +. \" "pdfmark" operator, and push it out to the intermediate +. \" output stream, (excluding its final line break). +. \" +. pdf*compose pdfmark +. pdf*pdfmark.dispatch +. \" +. \" And clean up when done. +. \" +. rm pdf*compose pdf*pdfmark.post +. rm pdf:compose.test pdf:composed.literal +. \} +. rr pdf:length +. \} +.. +.\" When a PDFMARK exceeds the specified output record length limit, +.\" then we decompose it, subsequently using the dynamically overloaded +.\" macro, "pdf*compose", to reassemble it into as many continuation +.\" records as it may require. +.\" +.\" Each call to "pdf*compose" uses macro "pdf*length.increment" to +.\" keep track of the current output record length, so ensuring that +.\" the active maximum length limit is not violated. +.\" +.de pdf*length.increment +.\" ---------------------------------------------------------------- +.\" Usage: +.\" .pdf*length.increment NEXT-ADDITION +.\" ---------------------------------------------------------------- +.\" +.ie d pdf:composed.line \ +. length pdf:length "\\*[pdf:composed.line] \\$*\" +.el .length pdf:length "\\$*\" +.. +.\" The first call to "pdf*compose" for each PDFMARK is directed +.\" to "pdf*compose.first"; this initialises the local strings +.\" and macros used to compose the eventual PDFMARK output. +.\" +.de pdf*compose.first +.\" ---------------------------------------------------------------- +.\" Usage: +.\" .als pdf*compose pdf*compose.first +.\" . pdf*compose TOKEN +.\" ---------------------------------------------------------------- +.\" +.\" Ensure that the output record accumulator will be initialised +.\" on posting of the first composed PDFMARK record. +.\" +.als pdf*pdfmark.post pdf*pdfmark.post.first +.\" +.\" The first token passed to "pdf*compose" should not be a +.\" literal, but be prepared to handle one, just in case. +.\" +.ds pdf:compose.test \\$1 +.substring pdf:compose.test 0 0 +.ie '('\\*[pdf:compose.test]' \{\ +.\" +.\" We found a literal, even though we didn't expect it; +.\" if it's a single element literal, we can just handle it +.\" as if it is a regular token anyway. +.\" +. ds pdf:compose.test "\\$\\n(.$\" +. substring pdf:compose.test -1 +. if !')'\\*[pdf:compose.test]' \{\ +. \" +. \" But when it is the first of a literal sequence, +. \" then we need to set up "pdf*compose" to handle it. +. \" +. ds pdf:composed.literal "[\\$*\" +. als pdf*compose pdf*compose.literal +. \} +. \} +.el .ds pdf:compose.test ) +.if ')'\\*[pdf:compose.test]' \{\ +.\" +.\" In the normal case, we start each new PDFMARK with a +.\" regular token; save it as the first in the composed output +.\" line sequence, and set up "pdf*compose" to collect +.\" the rest of the sequence. +.\" +. ds pdf:composed.line "[\\$*\" +. als pdf*compose pdf*compose.next +. \} +.. +.\" Subsequent calls to "pdf*compose", while collecting +.\" regular tokens, are then directed to "pdf*compose.next". +.\" +.de pdf*compose.next +.\" ---------------------------------------------------------------- +.\" Usage: +.\" .als pdf*compose pdf*compose.next +.\" . pdf*compose TOKEN +.\" ---------------------------------------------------------------- +.\" +.\" This first checks to ensure that the supplied token really is +.\" a regular token, and not the first element in a literal. +.\" +.ds pdf:compose.test \\$1 +.substring pdf:compose.test 0 0 +.ie '('\\*[pdf:compose.test]' \{\ +.\" +.\" The supplied token represents the first element of a literal, +.\" but it may be a single element literal, which we simply handle +.\" as a regular token anyway. +.\" +. ds pdf:compose.test "\\$\\n(.$\" +. substring pdf:compose.test -1 +. if !')'\\*[pdf:compose.test]' \{\ +. \" +. \" The supplied token is the first of a sequence of elements +. \" which collectively define a literal, so start collecting a +. \" composite literal token, and change the "pdf*compose" +. \" state, to collect and append the remaining elements. +. \" +. ds pdf:composed.literal "\\$*\" +. als pdf*compose pdf*compose.literal +. \} +. \} +.el .ds pdf:compose.test ) +.if ')'\\*[pdf:compose.test]' \{\ +.\" +.\" The supplied token IS a regular token; add it, but ensure that +.\" the active maximum record length limit is honoured. +.\" +. pdf*length.increment "\\$*\" +. ie (\\n[pdf:length] > \\n[PDFMARK.FOLDWIDTH.MAX]) \{\ +. \" +. \" Adding this token would cause the current PDFMARK record, in +. \" groff's intermediate output file, to overflow the active record +. \" length limit, so post the current record and start another. +. \" +. pdf*pdfmark.dispatch +. ds pdf:composed.line "\\$*\" +. \} +. el \{\ +. \" +. \" This token will fit in the current PDFMARK record, without +. \" violating the active length limit, so simply add it. +. \" +. ie d pdf:composed.line .as pdf:composed.line " \\$*\" +. el .ds pdf:composed.line "\\$*\" +. \} +. \} +.. +.\" While assembling a multiple token literal sequence into a single +.\" literal token, successive calls to "pdf*compose" are directed +.\" to "pdf*compose.literal". +.\" +.de pdf*compose.literal +.\" ---------------------------------------------------------------- +.\" Usage: +.\" .als pdf*compose pdf*compose.literal +.\" . pdf*compose TOKEN +.\" ---------------------------------------------------------------- +.\" +.\" First, check to ensure that the current token can be appended to +.\" the accumulated literal, without extending it beyond the maximum +.\" allowed literal token length. +.\" +.length pdf:length "\\*[pdf:composed.literal] \\$*\" +.ie (\\n[pdf:length] > (\\n[PDFMARK.FOLDWIDTH] - 2)) \{\ +.\" +.\" If it has grown too long, then it must be folded across two +.\" physical PDFMARK output records, so check if we can accommodate +.\" the portion collected so far within the current output record. +.\" +. pdf*length.increment "\\*[pdf:composed.literal]\" +. if (\\n[pdf:length] > (\\n[PDFMARK.FOLDWIDTH.MAX] - 2)) \{\ +. \" +. \" The current output record CAN'T accommodate the currently +. \" composed portion of the literal, so flush out the current +. \" record, to make way for the accumulated literal, and mark +. \" the dispatch mode as "wrapped", for the fragments of the +. \" folded literal string, which are to follow. +. \" +. pdf*pdfmark.dispatch +. ds pdf*pdfmark.dispatch.wrapped +. \} +. ie d pdf:composed.line \{\ +. \" +. \" If we DIDN'T need to flush the current output record, +. \" then we can simply append the accumulated literal to it... +. \" +. as pdf:composed.line " \\*[pdf:composed.literal]\" +. \} +. el \{\ +. \" +. \" otherwise, when the current record has been flushed, or is +. \" empty, then we promote the accumulated literal, to make it +. \" the next output record... +. \" +. rn pdf:composed.literal pdf:composed.line +. \} +.\" +.\" Now, to complete the fold, flush out any accumulated partial +.\" output record, and continue accumulating the literal, starting +.\" with the current token. +.\" +. pdf*pdfmark.dispatch +. ds pdf:composed.literal "\\$*\" +. \} +.el \{\ +.\" +.\" Alternatively, when we HAVEN'T identified a need to fold the +.\" current output record, then we simply append the current token +.\" to the accumulated literal token buffer string. +.\" +. as pdf:composed.literal " \\$*\" +. \} +.\" +.\" Having ensured that we have sufficient space, in which to +.\" append the current token to the currently accumulated literal, +.\" we check its rightmost character, to see if is the closing +.\" parenthesis, which completes the literal. +.\" +.ds pdf:compose.test \\$\\n(.$ +.substring pdf:compose.test -1 +.if ')'\\*[pdf:compose.test]' \{\ +.\" +.\" The literal has been completely collected, so we may now append +.\" it to the current output record, as a single literal token, but +.\" subject to the constraint that it must not extend the output +.\" record beyond the maximum permitted length. +.\" +. pdf*length.increment "\\*[pdf:composed.literal]\" +. ie (\\n[pdf:length] > \\n[PDFMARK.FOLDWIDTH.MAX]) \{\ +. \" +. \" So, when the literal cannot be accommodated within the maximum +. \" length constraint, then we flush the current record, and start +. \" a new one, with the literal token as its first entry. +. \" +. pdf*pdfmark.dispatch +. rn pdf:composed.literal pdf:composed.line +. \} +. el \{\ +. \" +. \" When the literal CAN be accommodated within the maximum length +. \" constraint, then ... +. \" +. ie d pdf:composed.line \{\ +. \" +. \" When an output record has already been instantiated, we +. \" append the literal token to it, and discard the accumulator +. \" string, which is no longer required. +. \" +. as pdf:composed.line " \\*[pdf:composed.literal]\" +. rm pdf:composed.literal +. \} +. el \{\ +. \" +. \" But when no output record yet exists, then we simply +. \" reassign the accumulated literal token, to instantiate a +. \" new output record. +. \" +. rn pdf:composed.literal pdf:composed.line +. \} +. \} +.\" +.\" Finally, since we have completed the accumulation of the literal, we +.\" revert to the "unwrapped" mode of operation for "pdf*pdfmark.dispatch", +.\" and restore the normal "pdf*compose" action, for collection of the next +.\" token (if any). +.\" +. rm pdf*pdfmark.dispatch.wrapped +. als pdf*compose pdf*compose.next +. \} +.. +.\" While composing a multiple record PDFMARK, each composed record +.\" must be added to the collection, whenever the partially composed +.\" output record has been filled; this is handled when necessary, +.\" by calling the "pdf*pdfmark.dispatch" macro. +.\" +.de pdf*pdfmark.dispatch +.\" ---------------------------------------------------------------- +.\" Usage: +.\" .pdf*pdfmark.dispatch +.\" ---------------------------------------------------------------- +.\" +.if d pdf:composed.line \{\ +.\" +.\" This is simply a wrapper around the overloaded "pdf*pdfmark.post" +.\" macro, ensuring that an output record has actually been collected +.\" before attempting to post it; it then cleans up after posting, to +.\" ensure that each collected record is posted only once. +.\" +. if d pdf*pdfmark.dispatch.wrapped \{\ +. \" +. \" When dispatching an excessively long literal string, which +. \" must be wrapped over multiple records, this mode is active +. \" for all but the closing record; we must escape the newline +. \" at the end of each such unclosed literal record. +. \" +. as pdf:composed.line " \\\\\\\\\" +. \} +. pdf*pdfmark.post +. rm pdf:composed.line +. \} +.. +.\" For each PDFMARK, the first call of "pdf*pdfmark.post" is directed +.\" to the "pdf*pdfmark.post.first" macro; this initialises the state +.\" of the "pdf:composed" macro, for assembly of a new PDFMARK. +.\" +.de pdf*pdfmark.post.first +. nop \!x X ps:exec \\*[pdf:composed.line] +.\" +.\" Subsequent calls to "pdf*pdfmark.post" are redirected to the +.\" alternative "pdf*pdfmark.post.next" macro, which simply appends +.\" additional PDFMARK records to the "pdf:composed" macro. +.\" +.als pdf*pdfmark.post pdf*pdfmark.post.next +.. +.de pdf*pdfmark.post.next +. nop \!+\\*[pdf:composed.line] +.. +.\" "pdf*end" is a dummy macro. It is required to mark the end +.\" of each individual fragment which is added to "pdf:composed"; +.\" other than this, it does nothing. +.\" +.de pdf*end +.. +.\" +.\" Some supporting macros defer actual pdfmark output until an +.\" appropriate time for it to be written; the "pdfsync" macro +.\" provides a mechanism for flushing such deferred output; +.\" it should be called from an end macro, and at any other time +.\" when it may be deemed necessary to flush pdfmark context. +.\" +.de pdfsync +.\" ---------------------------------------------------------------- +.\" Usage: +.\" .pdfsync buffer ... +.\" Arguments indicate which "buffer(s)" to flush: +.\" O -> bookmark (outline) cache +.\" M -> document metadata diversion +.\" If no argument, flush ALL buffers +.\" ---------------------------------------------------------------- +.\" +.ie \\n(.$ \{\ +. while \\n(.$ \{\ +. if '\\$1'O' .pdf:bm.sync 1 +. if '\\$1'M' \{\ +. if dpdf:metadata .pdf:metadata +. rm pdf:metadata +. \} +. shift +. \} +. \} +.el .pdfsync O M +.. +.\" +.\" some helper functions ... +.\" +.\" "pdf:warn" and "pdf:error" write diagnostic messages to stderr +.\" +.de pdf:warn +.\" ---------------------------------------------------------- +.\" Usage: +.\" .pdf:warn text of message +.\" ---------------------------------------------------------- +.\" +.tm \\n(.F:\\n(.c: macro warning: \\$* +.. +.de pdf:error +.\" ---------------------------------------------------------- +.\" Usage: +.\" .pdf:error text of message +.\" ---------------------------------------------------------- +.\" +.tm \\n(.F:\\n(.c: macro error: \\$* +.. +.\" "pdf:pop", assisted by "pdf*pop", allows us to retrieve register, +.\" or string values, from a string masquerading as a data queue, +.\" or as a stack. +.\" +.de pdf:pop +.\" ---------------------------------------------------------------- +.\" Usage: +.\" .pdf:pop <type> <to-name> <from-name> +.\" $1 = nr for numeric register, ds for string +.\" $2 = name of register or string to be assigned +.\" $3 = name of string, from which data is to be retrieved +.\" ---------------------------------------------------------------- +.\" +.pdf*pop \\$* \\*[\\$3] +.. +.de pdf*pop +.ds pdf:stack \\$3 +.\\$1 \\$2 \\$4 +.shift 4 +.ie \\n(.$ .ds \\*[pdf:stack] \\$* +.el .rm \\*[pdf:stack] +.rm pdf:stack +.. +.\" +.\" +.\" =========================================================== +.\" Module PDFINFO: Insert MetaData Entries into a PDF Document +.\" =========================================================== +.\" +.\" N.B. +.\" Output from the macros in this module is deferred, until +.\" subsequent invocation of .pdfsync, or .pdfexit +.\" +.\" ."pdfinfo" provides a general purpose form of metadata entry ... +.\" it allows arbitrary text to be associated with any specified +.\" metadata field name. +.\" +.de pdfinfo +.\" ------------------------------------------------------------------- +.\" Usage: +.\" .pdfinfo /FieldName field content ... +.\" Examples: +.\" .pdfinfo /Title A PDF Document +.\" .pdfinfo /Author Keith Marshall +.\" ------------------------------------------------------------------- +.\" +.ds pdf:meta.field \\$1 +.shift +.da pdf:metadata +\!.pdfmark \\*[pdf:meta.field] (\\$*) /DOCINFO +.di +.rm pdf:meta.field +.. +.\" +.\" Macro "pdfview" defines a special form of metadata entry ... +.\" it uses the /DOCVIEW pdfmark, to specify the initial (default) view, +.\" when the document is opened. +.\" +.de pdfview +.\" ------------------------------------------------------------------- +.\" Usage: +.\" .pdfview view parameters ... +.\" Examples: +.\" .pdfview /PageMode /UseOutlines +.\" .pdfview /Page 2 /View [/FitH \n(.p u] +.\" ------------------------------------------------------------------- +.\" +.da pdf:metadata +\!.pdfmark \\$* /DOCVIEW +.di +.. +.\" +.\" +.\" ===================================================================== +.\" Module PDFNOTE: Insert "Sticky Note" Style Comments in a PDF Document +.\" ===================================================================== +.\" +.\" "PDFNOTE.WIDTH" and "PDFNOTE.HEIGHT" set the preferred size for +.\" display of the "sticky note" pane, when opened. Acrobat Reader +.\" seems not to honour these -- perhaps GhostScript doesn't encode +.\" them correctly! Anyway, let's set some suitable default values, +.\" in case the user has a set up which does work as advertised. +.\" +.nr PDFNOTE.WIDTH 3.5i +.nr PDFNOTE.HEIGHT 2.0i +.\" +.\" "pdf:bbox" defines the expression used to set the size and location +.\" of the bounding rectangle for display of notes and link "hot-spots". +.\" This is defined, such that a note is placed at troff's current text +.\" position on the current page, with its displayed image size defined +.\" by the "PDFNOTE.WIDTH" and "PDFNOTE.HEIGHT" registers, while the +.\" bounds for a link "hot-spot" are matched to the text region which +.\" defines the "hot-spot". +.\" +.ds pdf:bbox \\n[pdf:llx] u \\n[pdf:lly] u \\n[pdf:urx] u \\n[pdf:ury] u +.\" +.\" Getting line breaks into the text of a PDFNOTE is tricky -- we need +.\" to get a "\n" into the Postscript stream, but three levels of "\" are +.\" swallowed, when we invoke "pdfnote". The following definition of "PDFLB", +.\" (for LineBreak), is rather ugly, but does allow us to use +.\" +.\" .pdfnote Some text.\*[PDFLB]Some more text, on a new line. +.\" +.ds PDFLB \\\\\\\\\\\\\\\\n +.\" +.de pdfnote +.\" ---------------------------------------------------------------------- +.\" Usage: +.\" .pdfnote [-T "Text for Title"] Text of note ... +.\" ---------------------------------------------------------------------- +.\" +.if \\n[PDFOPMODE] \{\ +.\" +.\" First, compute the bounding rectangle, +.\" for this PDFNOTE instance +.\" +. mk pdf:ury +. nr pdf:llx \\n(.k+\\n(.o+\\n[.in] +. nr pdf:lly \\n[pdf:ury]-\\n[PDFNOTE.HEIGHT] +. nr pdf:urx \\n[pdf:llx]+\\n[PDFNOTE.WIDTH] +. ds pdf:note.instance /Rect [\\*[pdf:bbox]] +.\" +.\" Parse any specified (recognisable) PDFNOTE options +.\" +. while dpdf:note\\$1 \{\ +. pdf:note\\$1 \\$@ +. shift \\n[pdf:note.argc] +. \} +.\" +.\" Emit the note, and clean up +.\" +. pdfmark \\*[pdf:note.instance] /Contents (\\$*) /ANN +. rm pdf:note.instance +. rr pdf:note.argc +. \} +.. +.de pdf:note-T +.nr pdf:note.argc 2 +.as pdf:note.instance " /Title (\\$2) +.. +.\" +.\" +.\" ===================================================================== +.\" Module PDFBOOKMARK: Add an Outline Reference in the PDF Bookmark Pane +.\" ===================================================================== +.\" +.\" "PDFBOOKMARK.VIEW" controls how the document will be displayed, +.\" when the user selects a bookmark. This default setting will fit +.\" the page width to the viewing window, with the bookmarked entry +.\" located at the top of the viewable area. +.\" +.ds PDFBOOKMARK.VIEW /FitH \\n[PDFPAGE.Y] u +.\" +.\" "PDFOUTLINE.FOLDLEVEL" controls how the document outline will be +.\" displayed. It is a number, defining the maximum heading level +.\" which will be visible, without outline expansion by the user, in +.\" the initial view of the document outline. Assuming that no sane +.\" document will ever extend to 10,000 levels of nested headings, +.\" this initial default value causes outlines to be fully expanded. +.\" +.nr PDFOUTLINE.FOLDLEVEL 10000 +.\" +.\" The actual job of creating an outline reference +.\" is performed by the "pdfbookmark" macro. +.\" +.de pdfbookmark +.\" ------------------------------------------------------------------ +.\" Usage: +.\" .pdfbookmark [-T tag] level "Text of Outline Entry" +.\" +.\" $1 = nesting level for bookmark (1 is top level) +.\" $2 = text for bookmark, (in PDF viewer bookmarks list) +.\" $3 = suffix for PDF internal bookmark name (optional) +.\" ------------------------------------------------------------------ +.\" +.ie '\\n(.z'' \{\ +.\" +.\" When we are at the top diversion level, i.e. actually emitting text +.\" to the output device stream, then we compute the location of, and +.\" plant this bookmark immediately. +.\" +. if \\n[PDFOPMODE] \{\ +. \" +. \" Make the bookmark name "untagged" by default, +. \" then parse any specified options, to set a "tag", if required +. \" +. ds pdf:href-T +. while dpdf:href.opt\\$1 \{\ +. pdf:href.opt\\$1 \\$@ +. shift \\n[pdf:href.argc] +. \} +. rr pdf:href.argc +. \" +. \" If we found "--" to mark the end of the options, discard it +. \" +. if '\\$1'--' .shift +. \" +. \" Synchronise the bookmark cache +. \" to the requested bookmark nesting level +. \" +. pdf:bm.sync \\$1 +. shift +. \" +. \" Increment the bookmark serialisation index +. \" in order to generate a uniquely serialised bookmark name, +. \" ( which we return in the string "PDFBOOKMARK.NAME" ), +. \" and insert this bookmark into the cache +. \" +. pdf:href.sety +. nr pdf:bm.nr +1 +. ds PDFBOOKMARK.NAME pdf:bm\\n[pdf:bm.nr]\\*[pdf:href-T] +. ds pdf:bm\\n[pdf:bm.nr] /Dest /\\*[PDFBOOKMARK.NAME] +. pdfmark \\*[pdf:bm\\n[pdf:bm.nr]] /View [\\*[PDFBOOKMARK.VIEW]] /DEST +. as pdf:bm\\n[pdf:bm.nr] " /Title (\\$*) +. pdf:href.options.clear +. rr PDFPAGE.Y +. \} +. \} +.el \{\ +.\" +.\" But when we are collecting a diversion which will be written out later, +.\" then we must defer bookmark placement, until we emit the diversion. +.\" (don't rely on $0 == pdfbookmark here; it may be a volatile alias). +.\" +. nop \!.pdfbookmark \\$@ +. \} +.. +.\" +.\" Macro "pdf:bm.sync" is called for each bookmark created, +.\" to establish a cache entry at the appropriate nesting level. +.\" It will flush ALL previous cache content, when called to +.\" add a new bookmark at level 1, or if simply called at +.\" level 1, without adding any bookmark. +.\" +.de pdf:bm.sync +.\" ------------------------------------------------------------------ +.\" Usage: +.\" .pdf:bm.sync level +.\" $1 = nesting level of current bookmark, or 1 to flush cache +.\" ------------------------------------------------------------------ +.\" +.\" First validate the bookmark nesting level +.\" adjusting it if required +.\" +.if \\$1>\\n[pdf:bm.nl] .nr pdf:bm.nl +1 +.ie \\$1>\\n[pdf:bm.nl] \{\ +. pdf:warn adjusted level \\$1 bookmark; should be <= \\n[pdf:bm.nl] +. \} +.el .nr pdf:bm.nl \\$1 +.if \\n[pdf:bm.nl]<1 \{\ +. pdf:warn bad arg (\\$1) in \\$0 \\$1; \\$0 1 forced +. nr pdf:bm.nl 1 +. \} +.\" +.\" If reverting from a higher to a lower nesting level, +.\" cyclicly adjust cache counts for each pending higher level +.\" +.if \\n[pdf:bm.lc]>=\\n[pdf:bm.nl] \{\ +. nr pdf:bm.lc +1 +. if !rpdf:bm.c\\n[pdf:bm.lc].c .nr pdf:bm.c\\n[pdf:bm.lc].c 0 +. while \\n[pdf:bm.lc]>\\n[pdf:bm.nl] \{\ +. as pdf:bm.c\\n[pdf:bm.lc] " \\n[pdf:bm.c\\n[pdf:bm.lc].c] +. rr pdf:bm.c\\n[pdf:bm.lc].c +. nr pdf:bm.lc -1 +. \} +. \} +.\" +.\" Update the cache level, +.\" flushing when we are at level 1 +.\" +.nr pdf:bm.lc \\n[pdf:bm.nl] +.ie \\n[pdf:bm.nl]=1 \{\ +. while \\n[pdf:bm.ic]<\\n[pdf:bm.nr] .pdf:bm.emit 0 +. rr pdf:bm.rc +. \} +.el .nr pdf:bm.c\\n[pdf:bm.nl].c +1 +.. +.\" Macro "pdf:bm.emit" is called, when the cache is at level 1. +.\" This flushes ALL pending bookmarks from the cache, i.e. the +.\" preceding level 1 bookmark, and any nested dependents, +.\" which it may have. +.\" +.de pdf:bm.emit +.\" ------------------------------------------------------------------ +.\" Usage: +.\" .pdf:bm.emit flag +.\" $1 = reference counting flag, used to control recursion +.\" ------------------------------------------------------------------ +.\" +.\" First check for nested dependents, +.\" and append the "dependent count" to the bookmark, as required. +.\" +.nr pdf:bm.ic +1 +.nr pdf:bm.lc +1 +.pdf:pop nr pdf:bm.rc pdf:bm.c\\n[pdf:bm.lc] +.if \\n[pdf:bm.rc] \{\ +. ds pdf:bm.fold +. if \\n[pdf:bm.lc]>\\n[PDFOUTLINE.FOLDLEVEL] .ds pdf:bm.fold - +. as pdf:bm\\n[pdf:bm.ic] " /Count \\*[pdf:bm.fold]\\n[pdf:bm.rc] +. rm pdf:bm.fold +. \} +.pdfmark \\*[pdf:bm\\n[pdf:bm.ic]] /OUT +.rm pdf:bm\\n[pdf:bm.ic] +.\" +.\" For ALL dependents, if any, +.\" recursively flush out any higher level dependents, +.\" which they themselves may have +.\" +.while \\n[pdf:bm.rc] \{\ +. nr pdf:bm.rc -1 +. pdf:bm.emit \\n[pdf:bm.rc] +. \} +.\" +.\" Finally, +.\" unwind the recursive call stack, until we return to the top level. +.\" +.nr pdf:bm.rc \\$1 +.nr pdf:bm.lc -1 +.. +.nr pdf:bm.nr 0 +.nr pdf:bm.nl 1 +.nr pdf:bm.lc 0 +.nr pdf:bm.ic 0 +.\" +.\" +.\" ============================================================= +.\" Module PDFHREF: Create Hypertext References in a PDF Document +.\" ============================================================= +.\" +.\" "PDFHREF.VIEW" controls how the document will be displayed, +.\" when the user follows a link to a named reference. +.\" +.ds PDFHREF.VIEW /FitH \\n[PDFPAGE.Y] u +.\" +.\" This default setting will fit the page width to the viewing +.\" window, with the bookmarked entry located close to the top +.\" of the viewable area. "PDFHREF.VIEW.LEADING" controls the +.\" actual distance below the top of the viewing window, where +.\" the reference will be positioned; 5 points is a reasonable +.\" default offset. +.\" +.nr PDFHREF.VIEW.LEADING 5.0p +.\" +.\" Yuk!!! +.\" PDF view co-ordinates are mapped from the bottom left corner, +.\" of the page, whereas page printing co-ordinates are mapped +.\" conventionally, from top left. +.\" +.\" Macro "pdf:href.sety" transforms the vertical position of the +.\" last printed baseline, from the printing co-ordinate domain to +.\" the PDF view domain. +.\" +.de pdf:href.sety +.\" ---------------------------------------------------------------- +.\" Usage: +.\" .pdf:href.sety +.\" ---------------------------------------------------------------- +.\" +.\" This computation yields the vertical view co-ordinate +.\" in groff's basic units; don't forget to append grops' "u" +.\" conversion operator, when writing the pdfmark! +.\" +.nr PDFPAGE.Y \\n(.p-\\n(nl+\\n[PDFHREF.VIEW.LEADING] +.. +.\" When we create a link "hot-spot" ... +.\" "PDFHREF.LEADING" sets the distance above the top of the glyph +.\" bounding boxes, in each line of link text, over which the link +.\" hot-spot will extend, while "PDFHREF.HEIGHT" sets the hot-spot +.\" height, PER LINE of text occupied by the reference. +.\" +.\" Since most fonts specify some leading space within the bounding +.\" boxes of their glyphs, a better appearance may be achieved when +.\" NEGATIVE leading is specified for link hot-spots; indeed, when +.\" the default 10pt Times font is used, -1.0 point seems to be a +.\" reasonable default value for "PDFHREF.LEADING" -- it may be +.\" changed, if desired. +.\" +.\" "PDFHREF.HEIGHT" is initially set as one vertical spacing unit; +.\" note that it is defined as a string, so it will adapt to changes +.\" in the vertical spacing. Changing it is NOT RECOMMENDED. +.\" +.nr PDFHREF.LEADING -1.0p +.ds PDFHREF.HEIGHT 1.0v +.\" +.\" PDF readers generally place a rectangular border around link +.\" "hot-spots". Within text, this looks rather ugly, so we set +.\" "PDFHREF.BORDER" to suppress it -- the three zeroes represent +.\" the border parameters in the "/Border [0 0 0]" PDFMARK string, +.\" and may be changed to any valid form, as defined in Adobe's +.\" PDFMARK Reference Manual. +.\" +.ds PDFHREF.BORDER 0 0 0 +.\" +.\" "PDFHREF.COLOUR" (note British spelling) defines the colour to +.\" be used for display of link "hot-spots". This will apply both +.\" to borders, if used, and, by default to text; however, actual +.\" text colour is set by "PDFHREF.TEXT.COLOUR", which may be reset +.\" independently of "PDFHREF.COLOUR", to achieve contrasting text +.\" and border colours. +.\" +.\" "PDFHREF.COLOUR" must be set to a sequence of three values, +.\" each in the range 0.0 .. 1.0, representing the red, green, and +.\" blue components of the colour specification in the RGB colour +.\" domain, which is shared by "groff" and the PDF readers. +.\" +.ds PDFHREF.COLOUR 0.35 0.00 0.60 +.defcolor pdf:href.colour rgb \*[PDFHREF.COLOUR] +.\" +.\" "PDFHREF.TEXT.COLOUR", on the other hand, is simply defined +.\" using any "groff" colour name -- this default maps it to the +.\" same colour value as "PDFHREF.COLOUR". +.\" +.ds PDFHREF.TEXT.COLOUR pdf:href.colour +.\" +.\" Accommodate users who prefer the American spelling, COLOR, to +.\" the British spelling, COLOUR. +.\" +.als PDFHREF.COLOR PDFHREF.COLOUR +.als PDFHREF.TEXT.COLOR PDFHREF.TEXT.COLOUR +.\" +.\" All PDF "Hypertext" reference capabilities are accessed +.\" through the "pdfhref" macro +.\" +.de pdfhref +.\" ----------------------------------------------------------------- +.\" Usage: +.\" .pdfhref <subcommand [options ...] [parameters ...]> ... +.\" ----------------------------------------------------------------- +.\" +.if \\n[PDFOPMODE] \{\ +.\" +.\" Loop over all subcommands specified in the argument list +.\" +. while \\n(.$ \{\ +. \" +. \" Initially, assume each subcommand will complete successfully +. \" +. nr pdf:href.ok 1 +. \" +. \" Initialise -E and -X flags in the OFF state +. \" +. nr pdf:href-E 0 +. nr pdf:href-X 0 +. \" +. \" Handle the case where subcommand is specified as "-class", +. \" setting up appropriate macro aliases for subcommand handlers. +. \" +. if dpdf*href\\$1 .als pdf*href pdf*href\\$1 +. if dpdf*href\\$1.link .als pdf*href.link pdf*href\\$1.link +. if dpdf*href\\$1.file .als pdf*href.file pdf*href\\$1.file +. \" +. \" Repeat macro alias setup +. \" for the case where the subcommand is specified as "class", +. \" (without a leading hyphen) +. \" +. if dpdf*href-\\$1 .als pdf*href pdf*href-\\$1 +. if dpdf*href-\\$1.link .als pdf*href.link pdf*href-\\$1.link +. if dpdf*href-\\$1.file .als pdf*href.file pdf*href-\\$1.file +. \" +. \" Process one subcommand ... +. \" +. ie dpdf*href \{\ +. \" +. \" Subcommand "class" is recognised ... +. \" discard the "class" code from the argument list, +. \" set the initial argument count to swallow all arguments, +. \" and invoke the selected subcommand handler. +. \" +. shift +. nr pdf:argc \\n(.$ +. pdf*href \\$@ +. \" +. \" When done, +. \" discard all arguments actually consumed by the handler, +. \" before proceeding to the next subcommand (if any). +. \" +. shift \\n[pdf:argc] +. \} +. el \{\ +. \" +. \" Subcommand "class" is not recognised ... +. \" issue a warning, and discard the entire argument list, +. \" so aborting this "pdfhref" invocation +. \" +. pdf:warn \\$0: undefined reference class '\\$1' ignored +. shift \\n(.$ +. \} +. \" +. \" Clean up temporary reference data, +. \" to ensure it doesn't propagate to any future reference +. \" +. rm pdf*href pdf:href.link pdf:href.files +. rr pdf:href-E pdf:href-X +. pdf:href.options.clear +. \} +. rr pdf:href.ok +. \} +.. +.\" +.\" Macros "pdf:href.flag" and "pdf:href.option" +.\" provide a generic mechanism for switching on flag type options, +.\" and for decoding options with arguments, respectively +.\" +.de pdf:href.flag +.\" ---------------------------------------------------------------------- +.\" ---------------------------------------------------------------------- +.nr pdf:href\\$1 1 +.nr pdf:href.argc 1 +.. +.de pdf:href.option +.\" ---------------------------------------------------------------------- +.\" ---------------------------------------------------------------------- +.ds pdf:href\\$1 \\$2 +.nr pdf:href.argc 2 +.. +.\" +.\" Valid PDFHREF options are simply declared +.\" by aliasing option handlers to "pdf:href.option", +.\" or to "pdf:href.flag", as appropriate +.\" +.als pdf:href.opt-A pdf:href.option \" affixed text +.als pdf:href.opt-D pdf:href.option \" destination name +.als pdf:href.opt-E pdf:href.flag \" echo link descriptor +.als pdf:href.opt-F pdf:href.option \" remote file specifier +.als pdf:href.opt-N pdf:href.option \" reference name +.als pdf:href.opt-P pdf:href.option \" prefixed text +.als pdf:href.opt-T pdf:href.option \" bookmark "tag" +.als pdf:href.opt-X pdf:href.flag \" cross reference +.\" +.\" For references to another document file +.\" we also need to support OS dependent file name specifiers +.\" +.als pdf:href.opt-DF pdf:href.option \" /DOSFile specifier +.als pdf:href.opt-MF pdf:href.option \" /MacFile specifier +.als pdf:href.opt-UF pdf:href.option \" /UnixFile specifier +.als pdf:href.opt-WF pdf:href.option \" /WinFile specifier +.\" +.\" Macro "pdf:href.options.clear" ensures that ALL option +.\" argument strings are deleted, after "pdfhref" has completed +.\" all processing which depends on them +.\" +.de pdf:href.options.clear +.\" ----------------------------------------------------------------- +.\" Usage: +.\" .pdf:href.options.clear [option ...] +.\" ----------------------------------------------------------------- +.\" +.\" When an option list is specified ... +.\" +.ie \\n(.$ \{\ +. \" +. \" then loop through the list, +. \" deleting each specified option argument string in turn +. \" +. while \\n(.$ \{\ +. if dpdf:href-\\$1 .rm pdf:href-\\$1 +. shift +. \} +. \} +.\" +.\" ... but when no list is specified, +.\" then recurse, to clear all known option argument strings +.\" +.el .pdf:href.options.clear A D F N P T DF MF UF WF +.. +.\" +.\" "PDFHREF.INFO" establishes the content of the cross reference +.\" data record, which is exported via the "stderr" stream, when a +.\" cross reference anchor is created using a "pdfhref" macro request +.\" of the form +.\" +.\" .pdfhref M -N name -X text ... +.\" +.\" .ds PDFHREF.INFO \\*[PDFHREF.NAME] reference data ... +.\" +.ds PDFHREF.INFO page \\n% \\$* +.\" +.\" Macro "pdf*href-M" is the handler invoked by "pdfhref", when +.\" called with the "M" reference class specifier, to create a +.\" named cross reference mark, and to emit a cross reference +.\" data record, as specified by "PDFHREF.INFO". +.\" +.de pdf*href-M +.\" ----------------------------------------------------------------- +.\" Usage: +.\" .pdfhref M [-X] [-N name | -D name] [-E] descriptive text ... +.\" ----------------------------------------------------------------- +.\" +.\" Initially, declare the -D and -N string options as empty, +.\" so we avoid warning messages when we try to use them, and find +.\" that they are undefined. +.\" +.ds pdf:href-D +.ds pdf:href-N +.\" +.\" Parse, interpret, and strip any specified options from the +.\" argument list. (Note that only options with a declared handler +.\" will be processed; there is no provision for detecting invalid +.\" options -- anything which is not recognised is assumed to start +.\" the "descriptive text" component of the argument list). +.\" +.while dpdf:href.opt\\$1 \{\ +. pdf:href.opt\\$1 \\$@ +. shift \\n[pdf:href.argc] +. \} +.\" +.\" If we found "--", to mark the end of the options, +.\" then we should discard it. +.\" +.if '\\$1'--' .shift +.\" +.\" All PDF reference markers MUST be named. The name may have been +.\" supplied using the "-N Name" option, (or the "-D Name" option); +.\" if not, deduce it from the first "word" in the "descriptive text", +.\" if any, and set the marker -- if we still can't identify the name +.\" for the destination, then this marker will not be created. +.\" +.pdf*href.set \\*[pdf:href-N] \\*[pdf:href-D] \\$1 +.\" +.\" If we specified a cross reference, with the "-X" option, and the +.\" reference mark has been successfully created, then we now need to +.\" write the cross reference info to the STDERR stream +.\" +.if \\n[pdf:href-X] .pdf*href.export \\*[PDFHREF.INFO] +.\" +.\" Irrespective of whether this marker is created, or not, +.\" the descriptive text will be copied to the groff output stream, +.\" provided the "-E" option was specified +.\" +.if \\n[pdf:href-E] \&\\$* +.. +.\" +.de pdf*href.set +.\" ---------------------------------------------------------------------- +.\" ---------------------------------------------------------------------- +.pdf*href.map.init +.ie \\n(.$ \{\ +. \" +. \" a marker name has been supplied ... +. \" if we are formatting for immediate output, +. \" emit PDFMARK code to establish the associated view +. \" +. ie '\\n(.z'' \{\ +. pdf:href.sety +. pdfmark /Dest /\\$1 /View [\\*[PDFHREF.VIEW]] /DEST +. ds PDFHREF.NAME \\$1 +. rr PDFPAGE.Y +. \} +. \" +. \" but, when formatting a diversion ... +. \" delay output of the PDFMARK code, until the diversion +. \" is eventually written out +. \" +. el \!.\\$0 \\$@ +. \" +. \" check if we also need to emit cross reference data +. \" (caller will do this if "pdf:href-X" is set, but it is +. \" not necessary, when "pdf:href.map" already exists) +. \" +. if dpdf:href.map .nr pdf:href-X 0 +. \} +.el \{\ +. \" marker is unnamed ... +. \" issue error message; do not emit reference data +. \" +. pdf:warn pdfhref destination marker must be named +. nr pdf:href-X 0 +. \} +.. +.de pdf*href.export +.\" +.\" Called ONLY by "pdf*href-M", +.\" this macro ensures that the emission of exported reference data +.\" is synchronised with the placement of the reference mark, +.\" especially when the mark is defined within a diversion. +.\" +.ie '\\n(.z'' .tm gropdf-info:href \\*[PDFHREF.NAME] \\$* +.el \!.\\$0 \\$@ +.. +.\" +.\" Macro "pdf*href-D" is invoked when "pdfhref" is called +.\" with the "D" reference class specifier; it provides a +.\" standardised mechanism for interpreting reference data +.\" exported by the "M" reference class, and may be used +.\" to directly define external reference data, without the +.\" use of "M" reference class designators in the source +.\" document. +.\" +.de pdf*href-D +.ds pdf:href-N +.\" +.\" Parse, interpret, and strip any specified options from the +.\" argument list. (Note that only options with a declared handler +.\" will be processed; there is no provision for detecting invalid +.\" options -- anything which is not recognised is assumed to start +.\" the "descriptive text" component of the argument list). +.\" +.while dpdf:href.opt\\$1 \{\ +. pdf:href.opt\\$1 \\$@ +. shift \\n[pdf:href.argc] +. \} +.\" +.\" If we found "--", to mark the end of the options, +.\" then we should discard it. +.\" +.if '\\$1'--' .shift +.\" +.ie '\\*[pdf:href-N]'' \{\ +. pdf:warn pdfhref defined reference requires a name +. \} +.el \{\ +. ds pdf:href(\\*[pdf:href-N]).info \\$* +. \} +.. +.\" +.\" Macro "pdf*href-F" is invoked when "pdfhref" is called +.\" with the "F" reference class specifier; it allows the user +.\" to provide an alternative interpreter macro, which will be +.\" called when a "PDFHREF.INFO" record is retrieved to define +.\" the text of a cross reference link "hot spot". +.\" +.de pdf*href-F +.\" ---------------------------------------------------------------- +.\" Usage: +.\" .pdfhref F [macro-name] +.\" ---------------------------------------------------------------- +.\" +.\" Set macro specified by "macro-name" as the format interpreter +.\" for parsing "PDFHREF.INFO" records; if "macro-name" is omitted, +.\" or is specified as the reserved name "default", then use the +.\" default format parser, "pdf*href.format", defined below. +.\" +.if '\\$1'default' .shift \\n(.$ +.ie \\n(.$ .als pdf*href.format \\$1 +.el .als pdf*href.format pdf*href.default +.nr pdf:argc 1 +.. +.\" The default reference formatting macro is defined below. +.\" It parses the "PDFHREF.INFO" record specific to each reference, +.\" recognising the keywords "file", "page" and "section", when they +.\" appear in initial key/value pairs, replacing the key/value pair +.\" with "PDFHREF.FILEREF", "PDFHREF.PAGEREF" or "PDFHREF.SECTREF" +.\" respectively; any additional data in the "PDFHREF.INFO" record +.\" is enclosed in typographic double quotes, and the parsed record +.\" is appended to "PDFHREF.PREFIX", to be returned as the formatted +.\" reference text. +.\" +.\" Default definitions for the reference strings "PDFHREF.PREFIX", +.\" "PDFHREF.FILEREF", "PDFHREF.PAGEREF" and "PDFHREF.SECTREF" are +.\" provided, in the English language. Users may substitute any +.\" desired alternative definitions, for example, when formatting +.\" documents in other languages. In each case, "\\$1" may be used +.\" in the substitution, to represent the "value" component of the +.\" respective key/value pair specified in the "PDFHREF.INFO" record. +.\" +.ds PDFHREF.PREFIX see +.ds PDFHREF.PAGEREF page \\$1, +.ds PDFHREF.SECTREF section \\$1, +.ds PDFHREF.FILEREF \\$1 +.\" +.de pdf*href.format +.\" ----------------------------------------------------------------- +.\" Usage: (to be called ONLY by "pdfhref") +.\" .pdf*href.format cross reference data ... +.\" ----------------------------------------------------------------- +.\" +.\" This macro is responsible for defining the strings "PDFHREF.TEXT" +.\" and "PDFHREF.DESC", which are used by the "pdfhref" macro, as the +.\" basis for generating the text content of a link "hot spot"; (any +.\" user specified alternate formatter MUST do likewise). +.\" +.\" Note that "PDFHREF.TEXT" defines the overall format for the "link +.\" text", while "PDFHREF.DESC" is the descriptive component thereof. +.\" +.\" This default implementation, subject to user customisation of the +.\" "internationalisation" strings defined above, formats "hot spots" +.\" of the style +.\" +.\" see page N, section S, "descriptive text ..." +.\" +.ds PDFHREF.TEXT \\*[PDFHREF.PREFIX] +.while d\\$0.\\$1 \{\ +. \\$0.\\$1 "\\$2" +. shift 2 +. \} +.\" +.\" Retrieve the descriptive text from the cross reference data, +.\" ONLY IF no overriding description has been set by the calling +.\" "pdfhref" macro invocation. +.\" +.if \\n(.$ .if !dPDFHREF.DESC .ds PDFHREF.DESC \\$* +.\" +.\" Augment "PDFHREF.TEXT" so the descriptive text will be included +.\" in the text of the formatted reference +.\" +.if dPDFHREF.DESC .as PDFHREF.TEXT " \(lq\\\\*[PDFHREF.DESC]\(rq +.\" +.\" Finally, suppress any leading spaces, +.\" which may have been included in the PDFHREF.TEXT definition. +.\" +.ds PDFHREF.TEXT \\*[PDFHREF.TEXT] +.. +.de pdf*href.format.file +.\" ---------------------------------------------------------------------- +.\" Include a file identifier in a formatted reference. +.\" This is invoked ONLY by "pdf*href.format", and ONLY IF the +.\" reference data includes an initial file identifier tuple. +.\" ---------------------------------------------------------------------- +.\" +.as PDFHREF.TEXT " \\*[PDFHREF.FILEREF] +.. +.de pdf*href.format.page +.\" ---------------------------------------------------------------------- +.\" Include a page number in a formatted reference. +.\" This is invoked ONLY by "pdf*href.format", and ONLY IF the +.\" reference data includes an initial page number tuple. +.\" ---------------------------------------------------------------------- +.\" +.as PDFHREF.TEXT " \\*[PDFHREF.PAGEREF] +.. +.de pdf*href.format.section +.\" ---------------------------------------------------------------------- +.\" Include a section number in a formatted reference. +.\" This is invoked ONLY by "pdf*href.format", and ONLY IF the +.\" reference data includes an initial section number tuple. +.\" ---------------------------------------------------------------------- +.\" +.as PDFHREF.TEXT " \\*[PDFHREF.SECTREF] +.. +.\" +.\" Make "pdf*href.format" the default cross reference formatter +.\" +.als pdf*href.default pdf*href.format +.\" +.\" +.\" Macro "pdf*href" provides a generic mechanism for placing link +.\" "hot-spots" in a PDF document. ALL "pdfhref" class macros which +.\" create "hot-spots" are aliased to this macro; each must also have +.\" an appropriately aliased definition for "pdf*href.template". +.\" +.de pdf*href +.\" ------------------------------------------------------------------ +.\" Usage: +.\" .pdf*href class [options ...] [link text ...] +.\" ------------------------------------------------------------------ +.\" +.\" First, we initialise an empty string, which will be affixed to +.\" the end of the "link text". (This is needed to cancel the effect +.\" of a "\c" escape, which is placed at the end of the "link text" +.\" to support the "-A" option -- any text supplied by the user, when +.\" the "-A" option is specified, will replace this empty string). +.\" +.ds pdf:href-A +.\" +.\" Now we interpret, and remove any specified options from the +.\" argument list. (Note that only options with a declared handler +.\" will be processed; there is no provision for detecting invalid +.\" options -- anything which is not recognised is assumed to start +.\" the "link text" component of the argument list). +.\" +.while dpdf:href.opt\\$1 \{\ +. pdf:href.opt\\$1 \\$@ +. shift \\n[pdf:href.argc] +. \} +.\" +.\" If we found "--", to mark the end of the options, then we should +.\" discard it. +.\" +.if '\\$1'--' .shift +.\" +.\" All PDF link classes REQUIRE a named destination. This may have +.\" been supplied using the "-D Name" option, but, if not, deduce it +.\" from the first "word" in the "link text", if any -- if we still +.\" can't identify the destination, then set "pdf:href.ok" to zero, +.\" so this link will not be created. +.\" +.if !dpdf:href-D .pdf:href.option -D \\$1 +.if '\\*[pdf:href-D]'' \{\ +. pdf:error pdfhref has no destination +. nr pdf:href.ok 0 +. \} +.\" +.\" Some PDF link classes support a "/File (FilePathName)" argument. +.\" +.if dpdf*href.file \{\ +. \" +. \" When this is supported, it may be specified by supplying +. \" the "-F FileName" option, which is captured in "pdf:href-F". +. \" +. if dpdf:href-F \{\ +. \" +. \" the /File key is present, so set up the link specification +. \" to establish the reference to the specified file +. \" +. als pdf*href.link pdf*href.file +. ds pdf:href.files /File (\\*[pdf:href-F]) +. \" +. \" in addition to the /File key, +. \" there may also be platform dependent alternate file names +. \" +. if dpdf:href-DF .as pdf:href.files " /DOSFile (\\*[pdf:href-DF]) +. if dpdf:href-MF .as pdf:href.files " /MacFile (\\*[pdf:href-MF]) +. if dpdf:href-UF .as pdf:href.files " /UnixFile (\\*[pdf:href-UF]) +. if dpdf:href-WF .as pdf:href.files " /WinFile (\\*[pdf:href-WF]) +. \} +. \" In some cases, the "/File" key is REQUIRED. +. \" We will know it is missing, if "pdf*href.link" is not defined. +. \" +. if !dpdf*href.link \{\ +. \" +. \" When a REQUIRED "/File" key specification is not supplied, +. \" then complain, and set "pdf:href.ok" to abort the creation +. \" of the current reference. +. \" +. pdf:error pdfhref: required -F specification omitted +. nr pdf:href.ok 0 +. \} +. \" Now, we have no further use for "pdf*href.file". +. \" +. rm pdf*href.file +. \} +.\" +.\" Now, initialise a string, defining the PDFMARK code sequence +.\" to create the reference, using the appropriate type indicators. +.\" +.ds pdf:href.link /Subtype /Link \\*[pdf*href.link] +.\" +.\" And now, we have no further use for "pdf*href.link". +.\" +.rm pdf*href.link +.\" +.\" If the user specified any "link prefix" text, (using the "-P text" +.\" option), then emit it BEFORE processing the "link text" itself. +.\" +.if dpdf:href-P \&\\*[pdf:href-P]\c +.ie \\n[pdf:href.ok] \{\ +. \" +. \" This link is VALID (so far as we can determine) ... +. \" Modify the "link text" argument specification, as required, +. \" to include any pre-formatted cross reference information +. \" +. ie \\n(.$ \{\ +. \" +. \" One or more "link text" argument(s) are present, +. \" so, set the link description from the argument(s) ... +. \" +. ds PDFHREF.DESC \\\\$* +. ie \\n[pdf:href-X] \{\ +. \" +. \" ... and, when the "-X" flag is set, +. \" also include formatted location information, +. \" derived from the cross reference record. +. \" +. pdf*href.format \\*[pdf:href(\\*[pdf:href-D]).info] +. \} +. el \{\ +. \" ... but, when the "-X" flag is NOT set, +. \" use only the argument(s) as the entire content +. \" of the "link text" +. \" +. rn PDFHREF.DESC PDFHREF.TEXT +. \} +. \} +. el \{\ +. \" No "link text" arguments are present, +. \" so, format the cross reference record to define +. \" the content of the "link text". +. \" +. pdf*href.format \\*[pdf:href(\\*[pdf:href-D]).info] +. \} +. \" Apply border and colour specifications to the PDFMARK string +. \" definition, as required. +. \" +. if dPDFHREF.BORDER .as pdf:href.link " /Border [\\*[PDFHREF.BORDER]] +. if dPDFHREF.COLOUR .as pdf:href.link " /Color [\\*[PDFHREF.COLOUR]] +. \" +. \" Emit the "link text", in its appropriate colour, marking the +. \" limits of its bounding box(es), as the before and after output +. \" text positions. +. \" +. pdf*href.mark.begin "\\*[pdf:href.link]" +. if dPDFHREF.COLOUR .defcolor pdf:href.colour rgb \\*[PDFHREF.COLOUR] +. nop \&\m[\\*[PDFHREF.TEXT.COLOUR]]\\*[PDFHREF.TEXT]\m[]\c +. pdf*href.mark.end +. \" +. \" Clean up the temporary registers and strings, used to +. \" compute the "hot-spot" bounds, and format the reference, +. \" +. rm PDFHREF.DESC PDFHREF.TEXT +. \} +.\" +.\" But when we identify an INVALID link ... +.\" We simply emit the "link text", with no colour change, no border, +.\" and no associated "hot-spot". +.\" +.el \&\\$*\c +.\" +.\" And then, if the user specified any affixed text, (using the +.\" "-A text" option), we tack it on at the end. +.\" +.nop \&\\*[pdf:href-A] +.. +.de pdf*href.map.init +.\" ---------------------------------------------------------------------- +.\" ---------------------------------------------------------------------- +.\" +.if dpdf:href.map-1 \{\ +. \" +. \" We have a reference map, but we haven't started to parse it yet. +. \" This must be the first map reference in pass 2, so we need to +. \" "kick-start" the parsing process, by loading the first indexed +. \" sub-map into the global map. +. \" +. rn pdf:href.map-1 pdf:href.map +. als pdf:href.map.internal pdf:href.map +. nr pdf:href.map.index 1 1 +. \} +.als pdf*href.map.init pdf*href.mark.idle +.. +.\" +.\" "pdf*href-Z" is used to add link co-ordinate entries to the +.\" "pdf:href.map". Primarily, it is used by the "pdfroff" formatter, +.\" to pass link co-ordinate data from one "groff" formatting pass to +.\" the next, and is not generally useful to the end user. +.\" +.de pdf*href-Z +.\" ---------------------------------------------------------------------- +.\" Usage: +.\" .pdfhref Z page-index x-displacement y-displacement +.\" Where: +.\" page-index is the reference mark's page number +.\" x-displacement is its offset from the left edge of the page +.\" y-displacement is its offset from the top edge of the page +.\" ( both displacement values are expressed in basic groff units, ) +.\" ( and measured perpendicular to their respective page edges. ) +.\" ---------------------------------------------------------------------- +.\" +.ie \\n(.$=3 .ds pdf:href.map-\\n+[pdf*href-Z.index] \\$* +.el .pdf:error pdfhref Z operator expects exactly three arguments +.. +.\" Initialise the auto-incrementing "pdf*href-Z.index" register, +.\" to ensure that sub-map numbering starts at 1. +.\" +.nr pdf*href-Z.index 0 1 +.\" +.de pdf*href.map.read +.\" ---------------------------------------------------------------------- +.\" Usage: (internal use only): +.\" .pdf*href.map.read co-ordinate name list ... +.\" ---------------------------------------------------------------------- +.\" +.\" Reads values from "pdf:href.map" to each named register, in turn +.\" Reading to "null" discards the corresponding value in "pdf:href.map" +.\" +.while \\n(.$ \{\ +. \" +. \" Loop over all registers named in the argument list, +. \" assigning values from "pdf:href.map" to each in turn. +. \" +. pdf:pop nr pdf:\\$1 pdf:href.map.internal +. if !dpdf:href.map.internal \{\ +. \" +. \" We ran out of map references in the current sub-map, +. \" so move on to the next indexed sub-map, if any. +. \" +. if dpdf:href.map-\\n+[pdf:href.map.index] \{\ +. rn pdf:href.map-\\n[pdf:href.map.index] pdf:href.map +. als pdf:href.map.internal pdf:href.map +. \} +. \} +. \" +. \" Proceed to the next named co-ordinate, (if any), specified +. \" in the argument list. +. \" +. shift +. \} +.\" +.\" Discard any assignments to a register named "null" +.\" +.rr pdf:null +.. +.de pdf*href.mark.begin +.\" ---------------------------------------------------------------------- +.\" ---------------------------------------------------------------------- +.pdf*href.map.init +.ie dpdf:href.map \{\ +. \" +. \" Once we have established a document reference map, +. \" then this, and all subsequent calls to "pdf*href.mark.begin", +. \" may be redirected to the reference mark resolver, and the +. \" "pdf*href.mark.end" macro has nothing further to do. +. \" +. pdf*href.mark.resolve \\$@ +. als pdf*href.mark.begin pdf*href.mark.resolve +. als pdf*href.mark.end pdf*href.mark.idle +. \} +.el \{\ +. \" Since we don't yet have a document reference map, the +. \" reference mark resolver will not work, in this pass of the +. \" formatter; this, and all subsequent calls to "pdf*href.mark.begin", +. \" may be redirected to "pdf*href.mark.end", which is responsible +. \" for emitting the reference mark data to be incorporated into +. \" the reference map in a subsequent formatting pass. +. \" +. pdf*href.mark.end +. als pdf*href.mark.begin pdf*href.mark.end +. \} +.. +.de pdf*href.mark.resolve +.\" ---------------------------------------------------------------------- +.\" ---------------------------------------------------------------------- +.ie '\\n(.z'' \{\ +. ds pdf:href.link \\$1 +. nr pdf:urx \\n(.o+\\n(.l +. pdf*href.map.read spg llx ury epg urx.end lly.end +. ie \\n[pdf:spg]=\\n[pdf:epg] \{\ +. \" +. \" This link is entirely contained on a single page ... +. \" emit the text, which defines the content of the link region, +. \" then make it active. +. \" +. pdf*href.mark.emit 1 \\n[pdf:urx.end] +. if \\n[pdf:lly]<\\n[pdf:lly.end] \{\ +. \" +. \" This link spans multiple output lines; we must save its +. \" original end co-ordinates, then define a new intermediate +. \" end point, to create a PDFMARK "hot-spot" extending from +. \" the start of the link to the end if its first line. +. \" +. nr pdf:ury +1v +. nr pdf:llx \\n(.o+\\n[.in] +. nr pdf:lly \\n[pdf:lly.end]-\\*[PDFHREF.HEIGHT] +. if \\n[pdf:ury]<\\n[pdf:lly] \{\ +. nr pdf:lly +\\*[PDFHREF.HEIGHT]-1v +. pdf*href.mark.emit 2 +. nr pdf:ury \\n[pdf:lly.end]-\\*[PDFHREF.HEIGHT] +. \} +. pdf*href.mark.emit 0 \\n[pdf:urx.end] +. \} +. pdf*href.mark.flush +. \} +. el \{\ +. \" This link is split across a page break, so ... +. \" We must mark the "hot-spot" region on the current page, +. \" BEFORE we emit the link text, as we will have moved off +. \" this page, by the time the text has been output. +. \" +. \" First step: define the region from the start of the link, +. \" to the end of its first line. +. \" +. pdf*href.mark.emit 1 \\n[pdf:urx] +. \" +. \" All additional regions MUST align with the left margin. +. \" +. nr pdf:llx \\n(.o+\\n[.in] +. \" +. \" If the current page can accommodate more than the current line, +. \" then it will include a second active region for this link; this +. \" will extend from just below the current line to the end of page +. \" trap, if any, or the bottom of the page otherwise, and occupy +. \" the full width of the page, between the margins. +. \" +. nr pdf:ury +1v +. pdf*href.mark.emit 3 +. \" +. \" We now need a page transition trap, to map the active link +. \" region(s), which overflow on to the following page(s); (the +. \" handler for this trap MUST have been previously installed). +. \" +. ie dpdf*href.mark.hook \{\ +. \" +. \" The page transition trap handler has been installed, +. \" so we may activate both it, and also the appropriate +. \" termination handler, to deactivate it when done. +. \" +. als pdf*href.mark.hook pdf*href.mark.trap +. \" +. \" Now we set up "pdf:epg" to count the number of page breaks +. \" which this link will span, and emit the link text, leaving +. \" the page trap macro to map active regions on intervening +. \" pages, which are included in the link. +. \" +. nr pdf:epg -\\n[pdf:spg] 1 +. \} +. el \{\ +. \" There was no handler initialised for the page trap, +. \" so we are unable to map the active regions for this link; +. \" we may discard the remaining map data for this link, +. \" and issue a diagnostic. +. \" +. pdf:error pdfhref: link dissociated at page break (trap not initialised) +. if dPDFHREF.BROKEN.COLOR \{\ +. \" +. \" The user may opt to have such broken links highlighted. +. \" We use "PDFHREF.BROKEN.COLOUR" to specify this requirement, +. \" but the user may prefer the American spelling, so we will +. \" handle both as equivalent. +. \" +. als PDFHREF.BROKEN.COLOUR PDFHREF.BROKEN.COLOR +. \} +. if dPDFHREF.BROKEN.COLOUR \{\ +. if dPDFHREF.COLOUR .als PDFHREF.COLOUR PDFHREF.BROKEN.COLOUR +. \} +. \} +. \} +. \} +.el \!.\\$0 \\$@ +.. +.\" +.\" Macro "pdf*href.mark.emit" is called only by "pdf*href". It is +.\" responsible for emitting the PDFMARK code, to establish the +.\" "hot-spot" region associated with a document or resource link. +.\" +.de pdf*href.mark.emit +.\" ---------------------------------------------------------------------- +.\" Usage: +.\" .pdf*href.mark.emit <action> [<end-urx>] +.\" <action> == 0 --> normal operation -- link height = 1 line +.\" <action> == 1 --> start of link -- add leading above text +.\" <action> == 2 --> overtall link -- set intermediate baseline +.\" <action> == 3 --> split link -- break at bottom of page +.\" ---------------------------------------------------------------------- +.\" +.if \\$1=1 \{\ +. \" +. \" Initialising a new link region ... +. \" Some different versions of "groff" disagree about the vertical +. \" displacement of "opminy", as emitted by "\O1|\h'-\w"|"u'\O2\c", +. \" relative to the current text baseline. Therefore, recompute +. \" the link displacement, independently of "opminy". +. \" +. mk pdf:ury.base +. while \\n[pdf:ury.base]<\\n[pdf:ury] .nr pdf:ury.base +1v +. nr pdf:ury.base -1m+\\n[PDFHREF.LEADING] +. \" +. \" adjust the end-point vertical displacement by the same offset, +. \" and then relocate the link starting point to its new displacement, +. \" as established by this base line relative computation. +. \" +. nr pdf:lly.end +\\n[pdf:ury.base]-\\n[pdf:ury]+\\*[PDFHREF.HEIGHT] +. rnn pdf:ury.base pdf:ury +. \} +.if \\$1<2 \{\ +. \" +. \" Link segment fits on a single line ... +. \" Set its height and end-point horizontal displacement accordingly. +. \" +. nr pdf:lly \\n[pdf:ury]+\\*[PDFHREF.HEIGHT] +. if \\n[pdf:lly]>=\\n[pdf:lly.end] .nr pdf:urx \\$2 +. \} +.ie \\$1=3 \{\ +. \" +. \" Link segment extends beyond the next page break ... +. \" Recompute truncated height, to just fit portion on current page, +. \" recursing to emit it, and leaving page trap mechanism to place +. \" continuation region(s) on following page(s). +. \" +. nr pdf:lly (\\n[.t]u-\\n[.V]u)/1v +. if \\n[pdf:lly]>0 \{\ +. nr pdf:lly \\n[pdf:ury]+\\n[pdf:lly]v-1v+\\*[PDFHREF.HEIGHT] +. pdf*href.mark.emit 2 +. \} +. \} +.el \{\ +. \" Link region size and placement has been fully specified ... +. \" Emit it. +. \" +. pdfmark \\*[pdf:href.link] /Rect [\\*[pdf:bbox]] /ANN +. \} +.. +.\" +.\" When "pdf*href" emits a link for which the "hot-spot" spans a +.\" page break, then we need to provide a "hook" in to the page break +.\" trap, so we can map the "hot-spot" regions which are to be placed +.\" on either side of the page break. +.\" +.\" Macro "pdf*href.mark.idle" is a dummy macro, which provide this +.\" "hook" for normal page breaks, where there is no link "hot-spot" +.\" crossing the break. +.\" +.de pdf*href.mark.idle +.\" ---------------------------------------------------------------------- +.\" Usage: +.\" Called only as an internal hook, by a page trap macro. +.\" Expects no arguments, and does nothing. +.\" ---------------------------------------------------------------------- +.. +.\" +.\" Macro "pdf*href.mark.trap" is the active "hook", which is substituted +.\" for "pdf*href,mark.idle" at those page breaks which are crossed by +.\" a link "hot-spot". +.\" +.de pdf*href.mark.trap +.\" ---------------------------------------------------------------------- +.\" Usage: +.\" Called only as an internal hook, by a page trap macro. +.\" Expects no arguments. Maps residual link "hot-spot" regions, +.\" which spill beyond any page break. Not to be invoked directly +.\" by the user, nor by any user supplied macro. +.\" ---------------------------------------------------------------------- +.\" +.mk pdf:ury +.nr pdf:ury +1v-1m-\\n[PDFHREF.LEADING] +.ie \\n-[pdf:epg] \{\ +. \" +. \" The link "hot-spot" extends across more than one page break, +. \" so, for each page which is completely contained within the +. \" extent of the link, simply mark the entire text area on the +. \" page as a "hot-spot". +. \" +. pdf*href.mark.emit 3 +. \} +.el \{\ +. \" The link "hot-spot" ends on the page which immediately follows +. \" the current page transition, so we may now finalise this link. +. \" +. nr pdf:lly \\n[pdf:ury]+\\*[PDFHREF.HEIGHT] +. if \\n[pdf:lly.end]>\\n[pdf:lly] \{\ +. \" +. \" The "hot-spot" extends beyond the first line of text, +. \" on its final page; compute and emit "hot-spot" region to cover +. \" the full with of the text area, including all but the last +. \" line of the link text. +. \" +. while \\n[pdf:lly.end]>\\n[pdf:lly] .nr pdf:lly +1v +. nr pdf:lly -1v +. pdf*href.mark.emit 2 +. \" +. \" Now, adjust the vertical "hot-spot" mapping reference, +. \" to identify the correct position for the last line of +. \" text, over which the "hot-spot" extends. +. \" +. nr pdf:ury \\n[pdf:lly.end]-\\*[PDFHREF.HEIGHT] +. \} +. \" +. \" We now have exactly one final line of text, over which we must +. \" emit a "hot-spot" region; map it, terminate page trap processing +. \" for this "hot-spot", and clean up the "hot-spot" mapping context. +. \" +. pdf*href.mark.emit 0 \\n[pdf:urx.end] +. als pdf*href.mark.hook pdf*href.mark.idle +. pdf*href.mark.flush +. \} +.. +.de pdf*href.mark.flush +.\" ---------------------------------------------------------------------- +.\" ---------------------------------------------------------------------- +.rr pdf:spg pdf:epg +.rr pdf:llx pdf:lly pdf:urx pdf:ury +.if dPDFHREF.COLOR .als PDFHREF.COLOUR PDFHREF.COLOR +.rr pdf:urx.end pdf:lly.end +.. +.de pdf*href.mark.end +.\" ---------------------------------------------------------------------- +.\" ---------------------------------------------------------------------- +\O1\Z'|'\O2\c +.. +.\" Macro "pdf*href-I" is used for one time initialisation of special +.\" "pdfhref" features; (currently, only the above page trap hook is +.\" supported, but it is implemented with one level of indirection, to +.\" accommodate possible future expansion). +. +.de pdf*href-I +.\" ---------------------------------------------------------------------- +.\" Usage: +.\" .pdfhref I -<option> <optarg> [-<option> <optarg>] ... +.\" ---------------------------------------------------------------------- +.\" +.\" Loop over all arguments, in pairs ... +. +.while \\n(.$ \{\ +. \" +. \" handing them off to their respective initialisers, +. \" when suitable initialisers exist, or complaining otherwise. +. \" +. ie dpdf*href\\$1.init .pdf*href\\$1.init \\$2 +. el .pdf*error pdfhref:init: unknown feature '\\$1' +. shift 2 +. \} +.. +.\" Before we can use the page break "hook", we need to initialise it +.\" as an addendum to a regular page break trap. To ensure that we don't +.\" compromise the user's page trap setup, we leave the onus for this +.\" initialisation with the user, but we provide the "pdf*href-PT.init" +.\" macro, (invoked by ".pdfhref I -PT <macro-name>"), to implement a +.\" suitable initialisation action. +. +.de pdf*href-PT.init +.\" ---------------------------------------------------------------------- +.\" Usage: +.\" .pdfhref I -PT <macro-name> +.\" <macro-name> == name of user's page break trap macro +.\" ---------------------------------------------------------------------- +.\" +.\" Initially, map the page break hook to its default, do nothing helper. +. +.als pdf*href.mark.hook pdf*href.mark.idle +.ie !\\n(.$ \{\ +. \" +. \" Don't have enough arguments to specify a page trap macro name, +. \" so simply plant "pdf*href.mark.hook" as a top of page trap. +. \" +. wh 0 pdf*href.mark.hook +. \} +.el \{\ +. \" Page trap macro name is specified in "\\$1" ... +. \" +. ie d\\$1 \{\ +. \" +. \" When this page trap macro already exists, then we simply +. \" append a call to "pdf*href.mark.hook" to it. +. \" +. am \\$1 pdf*href.mark.idle +. pdf*href.mark.hook +. pdf*href.mark.idle +. \} +. el \{\ +. \" However, when the specified page trap macro does not yet +. \" exist, then we create it, and plant it as a top of page +. \" trap. +. \" +. de \\$1 pdf*href.mark.idle +. pdf*href.mark.hook +. pdf*href.mark.idle +. wh 0 \\$1 +. \} +. \} +.. +. +.\" "pdf*href-L" is the generic handler for creating references to +.\" named destinations in PDF documents. It supports both local +.\" references, to locations within the same document, through its +.\" "pdf*href-L.link" attribute, and also references to locations +.\" in any other PDF document, through "pdf*href-L.file". +.\" +.als pdf*href-L pdf*href +.ds pdf*href-L.link /Dest /\\\\*[pdf:href-D] +.ds pdf*href-L.file /Action /GoToR \\\\*[pdf:href.files] \\*[pdf*href-L.link] +.\" +.\" "pdf*href-O" is the "official" handler for creating PDF +.\" document outlines. It is simply an alias to "pdfbookmark", +.\" which may also be invoked directly, if preferred. Neither +.\" a "pdf*href-O.link" nor a "pdf*href-O.file" attribute is +.\" required. +.\" +.als pdf*href-O pdfbookmark +.\" +.\" "pdf*href-W" is the generic handler for creating references to +.\" web resources, (or any resource specified by a uniform resource +.\" identifier). Such resource links are fully specified by the +.\" "pdf*href-W.link" attribute. +.\" +.als pdf*href-W pdf*href +.ds pdf*href-W.link /Action << /Subtype /URI /URI (\\\\*[pdf:href-D]) >> +.\" +.\" Local Variables: +.\" mode: nroff +.\" End: +.\" vim: filetype=groff: +.\" pdfmark.tmac: end of file diff --git a/contrib/pdfmark/pdfroff.1.man b/contrib/pdfmark/pdfroff.1.man new file mode 100644 index 0000000..029a1f4 --- /dev/null +++ b/contrib/pdfmark/pdfroff.1.man @@ -0,0 +1,981 @@ +.TH pdfroff @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +pdfroff \- construct files in Portable Document Format using +.I groff +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (C) 2005-2020 Free Software Foundation, Inc. +.\" +.\" This file is part of groff, the GNU roff type-setting system. +.\" +.\" Permission is granted to copy, distribute and/or modify this +.\" document under the terms of the GNU Free Documentation License, +.\" Version 1.3 or any later version published by the Free Software +.\" Foundation; with no Invariant Sections, with no Front-Cover Texts, +.\" and with no Back-Cover Texts. +.\" +.\" A copy of the Free Documentation License is included as a file +.\" called FDL in the main directory of the groff source package. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_pdfroff_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY pdfroff +.RI [ groff-option ] +.RB [ \-\-emit\-ps ] +.RB [ \-\-no\-toc\-relocation ] +.RB [ \-\-no\-kill\-null\-pages ] +.RB [ \-\-stylesheet=\c +.IR name ] +.RB [ \-\-no\-pdf\-output ] +.RB [ \-\-pdf\-output=\c +.IR name ] +.RB [ \-\-no\-reference\-dictionary ] +.RB [ \-\-reference\-dictionary=\c +.IR name ] +.RB [ \-\-report\-progress ] +.RB [ \-\-keep\-temporary\-files ] +.RI [ file\~ .\|.\|.] +.YS +. +. +.SY pdfroff +.B \-h +. +.SY pdfroff +.B \-\-help +.YS +. +. +.SY pdfroff +.B \-v +.RI [ groff-option +\&.\|.\|.\&] +. +.SY pdfroff +.B \-\-version +.RI [ groff-option +\&.\|.\|.\&] +.YS +. +. +.P +.I groff-option +is any short option supported by +.MR groff @MAN1EXT@ +except for +.BR \-h , +.BR \-T , +and +.BR \-v ; +see section \[lq]Usage\[rq] below. +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I pdfroff +is a wrapper program for the GNU text processing system, +.IR groff . +. +It transparently handles the mechanics of multiple pass +.I groff +processing, +when applied to suitably marked up +.I groff +source files, +such that tables of contents and body text are formatted separately, +and are subsequently combined in the correct order, +for final publication as a single PDF document. +. +A further optional \[lq]style sheet\[rq] capability is provided; +this allows for the definition of content which is required to precede +the table of contents, +in the published document. +. +. +.P +For each invocation of +.IR pdfroff , +the ultimate +.I groff +output stream is post-processed by the Ghostscript +.MR gs 1 +interpreter to produce a finished PDF document. +. +. +.P +.I pdfroff +makes no assumptions about, +and imposes no restrictions on, +the use of any +.I groff +macro packages which the user may choose to employ, +in order to achieve a desired document format; +however, +it +.I does +include specific built in support for the +.I \%pdfmark +macro package, +should the user choose to employ it. +. +Specifically, +if the +.I pdfhref +macro, +defined in the +.I \%pdfmark.tmac +package, +is used to define public reference marks, +or dynamic links to such reference marks, +then +.I pdfroff +performs as many preformatting +.I groff +passes as required, +up to a maximum limit of +.IR four , +in order to compile a document reference dictionary, +to resolve +references, +and to expand the dynamically defined content of links. +. +. +.\" ==================================================================== +.SH Usage +.\" ==================================================================== +. +The command line is parsed in accordance with normal GNU conventions, +but with one exception\(emwhen specifying any short form option +(i.e., +a single character option introduced by a single hyphen), +and if that option expects an argument, +then it +.I must +be specified independently +(i.e., +it may +.I not +be appended to any group of other single character short form options). +. +. +.P +Long form option names +(i.e., +those introduced by a double hyphen) +may +be abbreviated to their minimum length unambiguous initial substring. +. +. +.P +Otherwise, +.I pdfroff +usage closely mirrors that of +.I groff +itself. +. +Indeed, +with the exception of the +.BR \-h , +.BR \-v , +and +.BI \-T \ dev +short form options, +and all long form options, +which are parsed +internally by +.IR pdfroff , +all options and file name arguments specified on the command line are +passed on to +.IR groff , +to control the formatting of the PDF document. +. +Consequently, +.I pdfroff +accepts all options and arguments, +as specified in +.MR groff @MAN1EXT@ , +which may also be considered as the definitive reference for all +standard +.I pdfroff +options and argument usage. +. +. +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.I pdfroff +accepts all of the short form options +(i.e., +those introduced by a +single hyphen), +which are available with +.I groff +itself. +. +In most cases, +these are simply passed transparently to +.IR groff ; +the following, +however, +are handled specially by +.IR pdfroff . +. +. +.TP +.B \-h +Same as +.BR \-\-help ; +see below. +. +. +.TP +.B \-i +Process standard input, +after all other specified input files. +. +This is passed transparently to +.IR groff , +but, +if grouped with other options, +it +.I must +be the first in the group. +. +Hiding it within a group breaks standard input processing, +in the multiple-pass +.I groff +processing context of +.IR pdfroff . +. +. +.TP +.BI \-T \ dev +Only +.B \-T\ ps +is supported by +.IR pdfroff . +. +Attempting to specify any other device causes +.I pdfroff +to abort. +. +. +.TP +.B \-v +Same as +.BR \-\-version ; +see below. +. +. +.P +See +.MR groff @MAN1EXT@ +for a description of all other short form options, +which are +transparently passed through +.I pdfroff +to +.IR groff . +. +. +.P +All long form options +(i.e., +those introduced by a double hyphen) +are interpreted locally by +.IR pdfroff ; +they are +.I not +passed on to +.IR groff , +unless otherwise stated below. +. +. +.TP +.B \-\-help +Causes +.I pdfroff +to display a summary of the its usage syntax, +and supported options, +and then exit. +. +. +.TP +.B \-\-emit\-ps +Suppresses the final output conversion step, +causing +.I pdfroff +to emit PostScript output instead of PDF. +. +This may be useful to capture intermediate PostScript output when using +a specialised postprocessor, +such as +.I gpresent +for example, +in place of the default Ghostscript PDF writer. +. +. +.TP +.B \-\-keep\-temporary\-files +Suppresses the deletion of temporary files, +which normally occurs +after +.I pdfroff +has completed PDF document formatting; +this may be useful when debugging formatting problems. +. +. +.IP +See section \[lq]Files\[rq] below for a description of the temporary +files used by +.IR pdfroff . +. +. +.TP +.B \-\-no\-pdf\-output +May be used with the +.BI \%\-\-reference\-dictionary= name +option +(described below) +to eliminate the overhead of PDF formatting when running +.I pdfroff +to create a reference dictionary for use in a different document. +. +. +.TP +.B \-\-no\-reference\-dictionary +May be used to eliminate the overhead of creating a reference +dictionary, +when it is known that the target PDF document contains no public +references, +created by the +.B pdfhref +macro. +. +. +.TP +.B \-\-no\-toc\-relocation +May be used to eliminate the extra +.I groff +processing pass, +which is required to generate a table of contents, +and relocate it to the start of the PDF document, +when processing any document which lacks an automatically +generated table of contents. +. +. +.TP +.B \-\-no\-kill\-null\-pages +While preparing for simulation of the manual collation step, +which is traditionally required to relocate a +.I "table of contents" +to the start of a document, +.I pdfroff +accumulates a number of empty page descriptions +into the intermediate PostScript output stream. +. +During the final collation step, +these empty pages are normally discarded from the finished document; +this option forces +.I pdfroff +to leave them in place. +. +. +.TP +.BI \-\-pdf\-output= name +Specifies the name to be used for the resultant PDF document; +if unspecified, +the PDF output is written to standard output. +. +A future version of +.I pdfroff +may use this option, +to encode the document name in a generated reference dictionary. +. +. +.TP +.BI \-\-reference\-dictionary= name +Specifies the name to be used for the generated reference dictionary +file; +if unspecified, +the reference dictionary is created in a temporary file, +which is deleted when +.I pdfroff +completes processing of the current document. +. +This option +.I must +be specified, +if it is desired to save the reference dictionary, +for use in references placed in other PDF documents. +. +. +.TP +.B \-\-report\-progress +Causes +.I pdfroff +to display an informational message on standard error, +at the start of each +.I groff +processing pass. +. +. +.TP +.BI \-\-stylesheet= name +Specifies the name of an +.IR "input file" , +to be used as a style sheet for formatting of content, +which is to be placed +.I before +the table of contents, +in the formatted PDF document. +. +. +.TP +.B \-\-version +Causes +.I pdfroff +to display a version identification message. +. +The entire command line is then passed transparently to +.IR groff , +in a +.I one +pass operation +.IR only , +in order to display the associated +.I groff +version information, +before exiting. +. +. +.\" ==================================================================== +.SH Environment +.\" ==================================================================== +. +The following environment variables may be set, +and exported, +to modify the behaviour of +.IR pdfroff . +. +. +.TP +.I PDFROFF_COLLATE +Specifies the program to be used +for collation of the finished PDF document. +. +. +.IP +This collation step may be required to move +.I tables of contents +to the start of the finished PDF document, +when formatting with traditional macro packages, +which print them at the end. +. +However, +users should not normally need to specify +.IR \%PDFROFF_COLLATE , +(and indeed, +are not encouraged to do so). +. +If unspecified, +.I pdfroff +uses +.MR sed @MAN1EXT@ +by default, +which normally suffices. +. +. +.IP +If +.I \%PDFROFF_COLLATE +.I is +specified, +then it must act as a filter, +accepting a list of file name arguments, +and write its output to the standard output stream, +whence it is piped to the +.IR \%PDFROFF_POSTPROCESSOR_COMMAND , +to produce the finished PDF output. +. +. +.IP +When specifying +.IR \%PDFROFF_COLLATE , +it is normally necessary to also specify +.IR \%PDFROFF_KILL_NULL_PAGES . +. +. +.IP +.I \%PDFROFF_COLLATE +is ignored, +if +.I pdfroff +is invoked with the +.B \%\-\-no\-kill\-null\-pages +option. +. +. +.TP +.I PDFROFF_KILL_NULL_PAGES +Specifies options to be passed to the +.I \%PDFROFF_COLLATE +program. +. +. +.IP +It should not normally be necessary to specify +.IR \%PDFROFF_KILL_NULL_PAGES . +. +The internal default is a +.MR sed @MAN1EXT@ +script, +which is intended to remove completely blank pages +from the collated output stream, +and which should be appropriate in most applications of +.IR pdfroff . +. +However, +if any alternative to +.MR sed @MAN1EXT@ +is specified for +.IR \%PDFROFF_COLLATE , +then it is likely that a corresponding alternative specification for +.I \%PDFROFF_KILL_NULL_PAGES +is required. +. +. +.IP +As in the case of +.IR \%PDFROFF_COLLATE , +.I \%PDFROFF_KILL_NULL_PAGES +is ignored, +if +.I pdfroff +is invoked with the +.B \%\-\-no\-kill\-null\-pages +option. +. +. +.TP +.I PDFROFF_POSTPROCESSOR_COMMAND +Specifies the command to be used for the final document conversion +from PostScript intermediate output to PDF. +. +It must behave as a filter, +writing its output to the standard output stream, +and must accept an arbitrary number of +.I files .\|.\|.\& +arguments, +with the special case of +.RB \[lq] \- \[rq] +representing the standard input stream. +. +. +.IP +If unspecified, +.I \%PDFROFF_POSTPROCESSOR_COMMAND +defaults to +. +.RS 12n +.EX +gs \-dBATCH \-dQUIET \-dNOPAUSE \-dSAFER \-sDEVICE=pdfwrite \e + \-sOutputFile=\- +.EE +.RE +. +. +.TP +.I GROFF_TMPDIR +Identifies the directory in which +.I pdfroff +should create temporary files. +. +If +.I \%GROFF_TMPDIR +is +.I not +specified, +then the variables +.IR TMPDIR , +.I TMP +and +.I TEMP +are considered in turn as possible temporary file repositories. +. +If none of these are set, +then temporary files are created +in the current directory. +. +. +.TP +.I GROFF_GHOSTSCRIPT_INTERPRETER +Specifies the program to be invoked when +.I pdfroff +converts +.I groff +PostScript output to PDF. +. +If +.I \%PDFROFF_POSTPROCESSOR_COMMAND +is specified, +then the command name it specifies is +.I implicitly +assigned to +.IR \%GROFF_GHOSTSCRIPT_INTERPRETER , +overriding any explicit setting specified in the environment. +. +If +.I \%GROFF_GHOSTSCRIPT_INTERPRETER +is not specified, +then +.I pdfroff +searches the process +.IR PATH , +looking for a program with any of the well known names +for the Ghostscript interpreter; +if no Ghostscript interpreter can be found, +.I pdfroff +aborts. +. +. +.TP +.I GROFF_AWK_INTERPRETER +Specifies the program to be invoked when +.I pdfroff +is extracting reference dictionary entries from a +.I groff +intermediate message stream. +. +If +.I \%GROFF_AWK_INTERPRETER +is not specified, +then +.I pdfroff +searches the process +.IR PATH , +looking for any of the preferred programs, +.IR gawk , +.IR mawk , +.IR nawk , +and +.IR awk , +in that order; +if none of these are found, +.I pdfroff +issues a warning message, +and continue processing; +however, +in this case, +no reference dictionary is created. +. +. +.TP +.I OSTYPE +Typically defined automatically by the operating system, +.I \%OSTYPE +is used on Microsoft Win32/MS-DOS platforms +.IR only , +to infer the default +.I \%PATH_SEPARATOR +character, +which is used when parsing the process +.I PATH +to search for external helper programs. +. +. +.TP +.I PATH_SEPARATOR +If set, +.I \%PATH_SEPARATOR +overrides the default separator character, +(\[oq]:\[cq] on POSIX/Unix systems, +inferred from +.I \%OSTYPE +on Microsoft Win32/MS-DOS), +which is used when parsing the process +.I PATH +to search for external helper programs. +. +. +.TP +.I SHOW_PROGRESS +If this is set to a non-empty value, +then +.I pdfroff +always behaves as if the +.B \%\-\-report\-progress +option is specified on the command line. +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +Input and output files for +.I pdfroff +may be named according to any convention of the user's choice. +. +Typically, +input files may be named according to the choice of the principal +normatting macro package, +e.g., +.RI file .ms +might be an input file for formatting using the +.I ms +macros +.RI ( s.tmac ); +normally, +the final output file should be named +.RI file .pdf . +. +. +.P +Temporary files created by +.I pdfroff +are placed in the file system hierarchy, +in or below the directory specified by environment variables +(see section \[lq]Environment\[rq] above). +. +If +.MR mktemp @MAN1EXT@ +is available, +it is invoked to create a private subdirectory of +the nominated temporary files directory, +(with subdirectory name derived from the template +.IR pdfroff\-XXXXXXXXXX ); +if this subdirectory is successfully created, +the temporary files will be placed within it, +otherwise they will be placed directly in the directory +nominated in the environment. +. +. +.P +All temporary files themselves +are named according to the convention +.IR pdf $$ . *, +where +.I $$ +is the standard shell variable representing the process identifier of +the +.I pdfroff +process itself, +and +.I * +represents any of the extensions used by +.I pdfroff +to identify the following temporary and intermediate files. +. +. +.TP +.IR pdf $$ .tmp +A scratch pad file, +used to capture reference data emitted by +.IR groff , +during the +.I reference dictionary +compilation phase. +. +. +.TP +.IR pdf $$ .ref +The +.IR "reference dictionary" , +as compiled in the last but one pass of the +.I reference dictionary +compilation phase; +(at the start of the first pass, +this file is created empty; +in successive passes, +it contains the +.I reference dictionary +entries, +as collected in the preceding pass). +. +. +.IP +If the +.BR \%\-\-reference\-dictionary =\c +.I name +option is specified, +this intermediate file becomes permanent, +and is named +.IR name , +rather than +.IR pdf $$ .ref . +. +. +.TP +.IR pdf $$ .cmp +Used to collect +.I reference dictionary +entries during the active pass of the +.I reference dictionary +compilation phase. +. +At the end of any pass, +when the content of +.IR pdf $$ .cmp +compares as identical to +.IR pdf $$ .ref , +(or the corresponding file named by the +.BR \%\-\-reference\-dictionary =\c +.I name +option), +then +.I reference dictionary +compilation is terminated, +and the +.I document reference map +is appended to this intermediate file, +for inclusion in the final formatting passes. +. +. +.TP +.IR pdf $$ .tc +An intermediate +.I PostScript +file, +in which \[lq]Table of Contents\[rq] entries are collected, +to facilitate relocation before the body text, +on ultimate output to the +.I Ghostscript +postprocessor. +. +. +.TP +.IR pdf $$ .ps +An intermediate +.I PostScript +file, +in which the body text is collected prior to ultimate output to the +.I Ghostscript +postprocessor, +in the proper sequence, +.I after +.IR pdf $$ .tc . +. +. +.\" ==================================================================== +.SH Authors +.\" ==================================================================== +. +.I pdfroff +was written by +.MT keith\:.d\:.marshall@\:ntlworld\:.com +Keith Marshall +.ME , +who maintains it at +.UR https://\:osdn\:.net/\:users/\:keith/\:pf/\:\%groff-pdfmark/\ +\:wiki/\:\%FrontPage +his +.I groff-pdfmark +OSDN site +.UE . +. +.IR groff 's +version may be withdrawn in a future release. +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.IR "Groff: The GNU Implementation of troff" , +by Trent A.\& Fisher and Werner Lemberg, +is the primary +.I groff +manual. +. +You can browse it interactively with \[lq]info groff\[rq]. +. +. +.P +Since +.I pdfroff +provides a superset of all +.I groff +capabilities, +the above manual, +or its terser reference page, +.MR groff @MAN7EXT@ +may also be considered definitive references to all +.I standard +capabilities of +.IR pdfroff , +with this document providing the reference to +.IR pdfroff 's +extended features. +. +. +.P +While +.I pdfroff +imposes neither any restriction on, +nor any requirement for, +the use of any specific +.I groff +macro package, +a number of supplied macro packages, +and in particular those associated with the package +.IR \%pdfmark.tmac , +are best suited for use with +.I pdfroff +as the preferred formatter. +. +. +.TP +.I @PDFDOCDIR@/\:\%pdfmark.pdf +\[lq]Portable Document Format Publishing with GNU +.IR Troff \[rq], +by Keith Marshall, +offers detailed documentation on the use of these packages. +. +This file, +together with its source, +.IR \%pdfmark.ms , +is part of the +.I groff +distribution. +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_pdfroff_1_man_C] +.do rr *groff_pdfroff_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/contrib/pdfmark/pdfroff.sh b/contrib/pdfmark/pdfroff.sh new file mode 100644 index 0000000..f34c841 --- /dev/null +++ b/contrib/pdfmark/pdfroff.sh @@ -0,0 +1,682 @@ +#! /bin/sh +# ------------------------------------------------------------------------------ +# +# Function: Format PDF Output from groff Markup +# +# Copyright (C) 2005-2021 Free Software Foundation, Inc. +# Written by Keith Marshall (keith.d.marshall@ntlworld.com) +# +# This file 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/>. +# +# ------------------------------------------------------------------------------ +# +# Set up an identifier for the NULL device. +# In most cases "/dev/null" will be correct, but some shells on +# MS-DOS/MS-Windows systems may require us to use "NUL". +# + NULLDEV="/dev/null" + test -c $NULLDEV || NULLDEV="NUL" +# +# Set up the command name to use in diagnostic messages. +# (We can't assume we have 'basename', so use the full path if required. +# Also use the 'exec 2>...' workaround for a bug in Cygwin's 'ash'). +# + CMD=`exec 2>$NULLDEV; basename $0` || CMD=$0 +# +# To ensure that prerequisite helper programs are available, and are +# executable, a [fairly] portable method of detecting such programs is +# provided by function 'searchpath'. +# + searchpath(){ + # + # Usage: searchpath progname path + # + IFS=${PATH_SEPARATOR-":"} prog=':' + for dir in $2 + do + for ext in '' '.exe' + # + # try 'progname' with all well known extensions + # (e.g. Win32 may require 'progname.exe') + # + do + try="$dir/$1$ext" + test -f "$try" && test -x "$try" && prog="$try" && break + done + test "$prog" = ":" || break + done + echo "$prog" + } +# @PATH_SEARCH_SETUP@ +# +# If the system maps '/bin/sh' to some 'zsh' implementation, +# then we may need this hack, adapted from autoconf code. +# + test x${ZSH_VERSION+"set"} = x"set" && NULLCMD=":" \ + && (emulate sh) >$NULLDEV 2>&1 && emulate sh +# +# We need both 'grep' and 'sed' programs, to parse script options, +# and we also need 'cat', to display help and some error messages, +# so ensure they are all installed, before we continue. +# + CAT=`searchpath cat "$PATH"` + GREP=`searchpath grep "$PATH"` + SED=`searchpath sed "$PATH"` +# +# Another fundamental requirement is the 'groff' program itself; +# we MUST use a 'groff' program located in 'GROFF_BIN_DIR', if this +# is specified; if not, we will search 'GROFF_BIN_PATH', only falling +# back to a 'PATH' search, if neither of these is specified. +# + if test -n "$GROFF_BIN_DIR" + then + GPATH=GROFF_BIN_DIR + GROFF=`searchpath groff "$GROFF_BIN_DIR"` +# + elif test -n "$GROFF_BIN_PATH" + then + GPATH=GROFF_BIN_PATH + GROFF=`searchpath groff "$GROFF_BIN_PATH"` +# + else + GPATH=PATH + GROFF=`searchpath groff "$PATH"` + fi +# +# If one or more of these is missing, diagnose and bail out. +# + NO='' NOPROG="$CMD: installation problem: cannot find program" + test "$CAT" = ":" && echo >&2 "$NOPROG 'cat' in PATH" && NO="$NO 'cat'" + test "$GREP" = ":" && echo >&2 "$NOPROG 'grep' in PATH" && NO="$NO 'grep'" + test "$GROFF" = ":" && echo >&2 "$NOPROG 'groff' in $GPATH" && NO="$NO 'groff'" + test "$SED" = ":" && echo >&2 "$NOPROG 'sed' in PATH" && NO="$NO 'sed'" + if test -n "$NO" + then + set $NO + test $# -gt 1 && NO="s" IS="are" || NO='' IS="is" + while test $# -gt 0 + do + test $# -gt 2 && NO="$NO $1," + test $# -eq 2 && NO="$NO $1 and" && shift + test $# -lt 2 && NO="$NO $1" + shift + done + $CAT >&2 <<-ETX + + *** FATAL INSTALLATION ERROR *** + + The program$NO $IS required by '$CMD', + but cannot be found; '$CMD' is unable to continue. + + ETX + exit 1 + fi +# +# Identify the postprocessor command, for writing PDF output. +# (May be forced, by defining PDFROFF_POSTPROCESSOR_COMMAND in the environment; +# if this is not set, leave blank to use the built in default). +# + if test -n "${PDFROFF_POSTPROCESSOR_COMMAND}" + then + GROFF_GHOSTSCRIPT_INTERPRETER=`set command ${PDFROFF_POSTPROCESSOR_COMMAND}; + echo $2` + fi +# +# Set up temporary/intermediate file locations, with traps to +# clean them up on exit. Note that, for greater portability, we +# prefer to refer to events by number, rather than by symbolic +# names; thus, the EXIT event is trapped as event zero. +# + export TMPDIR GROFF_TMPDIR + TMPDIR=${GROFF_TMPDIR=${TMPDIR-${TMP-${TEMP-"."}}}} + if GROFF_TMPDIR=`exec 2>${NULLDEV}; mktemp -dt pdfroff-XXXXXXXXXX` + then + # + # We successfully created a private temporary directory, + # so to clean up, we may simply purge it. + # + trap "rm -rf ${GROFF_TMPDIR}" 0 + # + else + # + # Creation of a private temporary directory was unsuccessful; + # fall back to user nominated directory, (using current directory + # as default), and schedule removal of only the temporary files. + # + GROFF_TMPDIR=${TMPDIR} + trap "rm -f ${GROFF_TMPDIR}/pdf$$.*" 0 + fi + # + # In the case of abnormal termination events, we force an exit + # (with status code '1'), leaving the normal exit trap to clean + # up the temporary files, as above. Note that we again prefer + # to refer to events by number, rather than by symbolic names; + # here we trap SIGHUP, SIGINT, SIGQUIT, SIGPIPE and SIGTERM. + # + trap "exit 1" 1 2 3 13 15 +# + WRKFILE=${GROFF_TMPDIR}/pdf$$.tmp +# + REFCOPY=${GROFF_TMPDIR}/pdf$$.cmp + REFFILE=${GROFF_TMPDIR}/pdf$$.ref +# + CS_DATA="" + TC_DATA=${GROFF_TMPDIR}/pdf$$.tc + BD_DATA=${GROFF_TMPDIR}/pdf$$.ps +# +# Initialise 'groff' format control settings, +# to discriminate table of contents and document body formatting passes. +# + TOC_FORMAT="-rPHASE=1" + BODY_FORMAT="-rPHASE=2" +# + LONGOPTS=" + help reference-dictionary no-reference-dictionary + stylesheet pdf-output no-pdf-output + version report-progress no-toc-relocation + emit-ps keep-temporary-files no-kill-null-pages + " +# Parse the command line, to identify 'pdfroff' specific options. +# Collect all other parameters into new argument and file lists, +# to be passed on to 'groff', enforcing the '-Tps' option. +# + DIFF="" STREAM="" INPUT_FILES="" + SHOW_VERSION="" GROFF_STYLE="$GROFF -Tps" + while test $# -gt 0 + do + case "$1" in +# +# Long options must be processed locally ... +# + --*) +# +# First identify, matching any abbreviation to its full form. +# + MATCH="" OPTNAME=`IFS==; set dummy $1; echo $2` + for OPT in $LONGOPTS + do + MATCH="$MATCH"`echo --$OPT | $GREP "^$OPTNAME"` + done +# +# For options in the form --option=value +# capture any specified value into $OPTARG. +# + OPTARG=`echo $1 | $SED -n s?"^${OPTNAME}="??p` +# +# Perform case specific processing for matched option ... +# + case "$MATCH" in + + --help) + $CAT <<-ETX + Usage: $CMD [-option ...] [--long-option ...] [file ...] + + Options: + -h + --help + Display this usage summary, and exit. + + -v + --version + Display a version identification message and exit. + + --report-progress + Enable console messages, indicating the progress of the + PDF document formatting process. + + --emit-ps + Emit PostScript output instead of PDF; this may be useful + when the ultimate PDF output is to be generated by a more + specialised postprocessor, (e.g. gpresent), rather than + the default GhostScript PDF writer. + + --pdf-output=name + Write the PDF, (or PostScript), output stream to file + 'name'; if this option is unspecified, standard output + is used for PDF, (or PostScript), output. + + --no-pdf-output + Suppress the generation of PDF, (or PostScript), output + entirely; use this with the --reference-dictionary option, + if processing a document stream to produce only a + reference dictionary. + + --no-reference-dictionary + Suppress the generation of a '$CMD' reference dictionary + for the PDF document. Normally '$CMD' will create a + reference dictionary, at the start of document processing; + this option can accelerate processing, if it is known in + advance, that no reference dictionary is required. + + --reference-dictionary=name + Save the document reference dictionary in file 'name'. + If 'name' already exists, when processing commences, it + will be used as the base case, from which the updated + dictionary will be derived. If this option is not used, + then the reference dictionary, created during the normal + execution of '$CMD', will be deleted on completion of + document processing. + + --stylesheet=name + Use the file 'name' as a 'groff' style sheet, to control + the appearance of the document's front cover section. If + this option is not specified, then no special formatting + is applied, to create a front cover section. + + --no-toc-relocation + Suppress the multiple pass 'groff' processing, which is + normally required to position the table of contents at the + start of a PDF document. + + --no-kill-null-pages + Suppress the 'null page' elimination filter, which is used + to remove the excess blank pages produced by the collation + algorithm used for 'toc-relocation'. + + --keep-temporary-files + Suppress the normal clean up of temporary files, which is + scheduled when 'pdfroff' completes. + + ETX + exit 0 + ;; + + --version) + GROFF_STYLE="$GROFF_STYLE \"$1\"" + SHOW_VERSION="GNU pdfroff (groff) version @VERSION@" + ;; + + --report-progress) + SHOW_PROGRESS=echo + ;; + + --keep-temporary-files) + trap "" 0 + ;; + + --emit-ps) + PDFROFF_POSTPROCESSOR_COMMAND="$CAT" + ;; + + --pdf-output) + PDF_OUTPUT="$OPTARG" + ;; + + --no-pdf-output) + PDF_OUTPUT="$NULLDEV" + ;; + + --reference-dictionary) + REFFILE="$OPTARG" + ;; + + --no-reference-dictionary) + AWK=":" DIFF=":" REFFILE="$NULLDEV" REFCOPY="$NULLDEV" + ;; + + --stylesheet) + STYLESHEET="$OPTARG" CS_DATA=${GROFF_TMPDIR}/pdf$$.cs + ;; + + --no-toc-relocation) + TC_DATA="" TOC_FORMAT="" BODY_FORMAT="" + ;; + + --no-kill-null-pages) + PDFROFF_COLLATE="$CAT" PDFROFF_KILL_NULL_PAGES="" + ;; +# +# any other non-null match must have matched more than one defined case, +# so report the ambiguity, and bail out. +# + --*) + echo >&2 "$CMD: ambiguous abbreviation in option '$1'" + exit 1 + ;; +# +# while no match at all simply represents an undefined case. +# + *) + echo >&2 "$CMD: unknown option '$1'" + exit 1 + ;; + esac + ;; +# +# A solitary hyphen, as an argument, means "stream STDIN through groff", +# while the "-i" option means "append STDIN stream to specified input files", +# so set up a mechanism to achieve this, for ALL 'groff' passes. +# + - | -i*) + STREAM="$CAT ${GROFF_TMPDIR}/pdf$$.in |" + test "$1" = "-" && INPUT_FILES="$INPUT_FILES $1" \ + || GROFF_STYLE="$GROFF_STYLE $1" + ;; +# +# Those standard options which expect an argument, but are specified with +# an intervening space, between flag and argument, must be reparsed, so we +# can trap invalid use of '-T dev', or missing input files. +# + -[dfFILmMnoPrTwW]) + OPTNAME="$1" + shift; set reparse "$OPTNAME$@" + ;; +# +# Among standard options, '-Tdev' is treated as a special case. +# '-Tps' is automatically enforced, so if specified, is silently ignored. +# + -Tps) ;; +# +# No other '-Tdev' option is permitted. +# + -T*) echo >&2 "$CMD: option '$1' is incompatible with PDF output" + exit 1 + ;; +# +# '-h' and '-v' options redirect to their equivalent long forms ... +# + -h*) set redirect --help + ;; +# + -v*) shift; set redirect --version "$@" + ;; +# +# All other standard options are simply passed through to 'groff', +# with no validation beforehand. +# + -*) GROFF_STYLE="$GROFF_STYLE \"$1\"" + ;; +# +# All non-option arguments are considered as possible input file names, +# and are passed on to 'groff', unaltered. +# + *) INPUT_FILES="$INPUT_FILES \"$1\"" + ;; + esac + shift + done +# +# If the '-v' or '--version' option was specified, +# then we simply emulate the behaviour of 'groff', with this option, +# and quit. +# + if test -n "$SHOW_VERSION" + then + echo >&2 "$SHOW_VERSION" + echo >&2; eval $GROFF_STYLE $INPUT_FILES + exit $? + fi +# +# Establish how to invoke 'echo', suppressing the terminating newline. +# (Adapted from 'autoconf' code, as found in 'configure' scripts). +# + case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,*-n*) n='' c='' ;; + *c*) n='-n' c='' ;; + *) n='' c='\c' ;; + esac +# +# If STDIN is specified among the input files, +# or if no input files are specified, then we need to capture STDIN, +# so we can replay it into each 'groff' processing pass. +# + test -z "$INPUT_FILES" && STREAM="$CAT ${GROFF_TMPDIR}/pdf$$.in |" + test -n "$STREAM" && $CAT > ${GROFF_TMPDIR}/pdf$$.in +# +# Unless reference resolution is explicitly suppressed, +# we initiate it by touching the cross reference dictionary file, +# and initialise the comparator, to kickstart the reference resolver loop. +# + SAY=":" + if test -z "$DIFF" + then + >> $REFFILE + echo kickstart > $REFCOPY + test x${SHOW_PROGRESS+"set"} = x"set" && SAY=echo +# +# In order to correctly resolve 'pdfmark' references, +# we need to have both the 'awk' and 'diff' programs available. +# + NO='' + if test -n "$GROFF_AWK_INTERPRETER" + then + AWK="$GROFF_AWK_INTERPRETER" + test -f "$AWK" && test -x "$AWK" || AWK=":" + else + for prog in @GROFF_AWK_INTERPRETERS@ + do + AWK=`searchpath $prog "$PATH"` + test "$AWK" = ":" || break + done + fi + DIFF=`searchpath diff "$PATH"` + test "$AWK" = ":" && echo >&2 "$NOPROG 'awk' in PATH" && NO="$NO 'awk'" + test "$DIFF" = ":" && echo >&2 "$NOPROG 'diff' in PATH" && NO="$NO 'diff'" + if test -n "$NO" + then + set $NO + SAY=":" AWK=":" DIFF=":" + test $# -gt 1 && NO="s $1 and $2 are" || NO=" $1 is" + $CAT >&2 <<-ETX + + *** WARNING *** + + The program$NO required, but cannot be found; + consequently, '$CMD' is unable to resolve 'pdfmark' references. + + Document processing will continue, but no 'pdfmark' reference dictionary + will be compiled; if any 'pdfmark' reference appears in the resulting PDF + document, the formatting may not be correct. + + ETX + fi + fi +# +# Run the multi-pass 'pdfmark' reference resolver loop ... +# + $SAY >&2 $n Resolving references ..$c + until $DIFF $REFCOPY $REFFILE 1>$NULLDEV 2>&1 + do +# +# until all references are resolved, to yield consistent values +# in each of two consecutive passes, or until it seems that no consistent +# resolution is achievable. +# + $SAY >&2 $n .$c + PASS_INDICATOR="${PASS_INDICATOR}." + if test "$PASS_INDICATOR" = "...." + then +# +# More than three passes required indicates a probable inconsistency +# in the source document; diagnose, and bail out. +# + $SAY >&2 " failed" + $CAT >&2 <<-ETX + $CMD: unable to resolve references consistently after three passes + $CMD: the source document may exhibit instability about the reference(s) ... + ETX +# +# Report the unresolved references, as a diff between the two pass files, +# preferring 'unified' or 'context' diffs, when available +# + DIFFOPT='' + $DIFF -c0 $NULLDEV $NULLDEV 1>$NULLDEV 2>&1 && DIFFOPT='-c0' + $DIFF -u0 $NULLDEV $NULLDEV 1>$NULLDEV 2>&1 && DIFFOPT='-u0' + $DIFF >&2 $DIFFOPT $REFCOPY $REFFILE + exit 1 + fi +# +# Replace the comparison file copy from any previous pass, +# with the most recently updated copy of the reference dictionary. +# (Some versions of 'mv' may not support overwriting of an existing file, +# so remove the old comparison file first). +# + rm -f $REFCOPY + mv $REFFILE $REFCOPY +# +# Run 'groff' and 'awk', to identify reference marks in the document source, +# filtering them into the reference dictionary; discard incomplete 'groff' output +# at this stage. +# + eval $STREAM $GROFF_STYLE -Z 1>$NULLDEV 2>$WRKFILE $REFCOPY $INPUT_FILES + $AWK '/^gropdf-info:href/ {$1 = ".pdfhref D -N"; print}' $WRKFILE > $REFFILE + done + $SAY >&2 " done" +# +# To get to here ... +# We MUST have resolved all 'pdfmark' references, such that the content of the +# updated reference dictionary file EXACTLY matches the last saved copy. +# +# If PDF output has been suppressed, then there is nothing more to do. +# + test "$PDF_OUTPUT" = "$NULLDEV" && exit 0 +# +# We are now ready to start preparing the intermediate PostScript files, +# from which the PDF output will be compiled -- but before proceeding further ... +# let's make sure we have a GhostScript interpreter to convert them! +# + if test -n "$GROFF_GHOSTSCRIPT_INTERPRETER" + then + GS="$GROFF_GHOSTSCRIPT_INTERPRETER" + test -f "$GS" && test -x "$GS" || GS=":" + else + for prog in @GROFF_GHOSTSCRIPT_INTERPRETERS@ + do + GS=`searchpath $prog "$PATH"` + test "$GS" = ":" || break + done + fi +# +# If we could not find a GhostScript interpreter, then we can do no more. +# + if test "$GS" = ":" + then + echo >&2 "$CMD: installation problem: cannot find GhostScript interpreter" + $CAT >&2 <<-ETX + + *** FATAL INSTALLATION ERROR *** + + '$CMD' requires a GhostScript interpreter to convert PostScript to PDF. + You do not appear to have one installed; thus, '$CMD' cannot continue. + + ETX + exit 1 + fi +# +# We now extend the local copy of the reference dictionary file, +# to create a full 'pdfmark' reference map for the document ... +# + $AWK '/^grohtml-info/ {print ".pdfhref Z", $2, $3, $4}' $WRKFILE >> $REFCOPY +# +# ... appending a dummy map reference, to ensure that at least +# one such is always present; (this is required, to suppress any +# further intermediate output to stderr during the "press-ready" +# runs of groff, for PDF output file production). +# + echo ".pdfhref Z 0 0 0" >> $REFCOPY +# +# Evaluate any processing options which may have been specified +# as a result of parsing the document source ... +# + eval `$SED -n '/^ *pdfroff-option:set */s///p' $WRKFILE` +# +# ... (which is currently supported to enable "toc-relocation", +# only when the document actually relies on it, and if it is not +# explicitly disabled from the command line) ... +# + if test x${toc_relocation-"auto"} != xenabled + then +# +# ... thus we reproduce the effect of the "--no-toc-relocation" +# option, when no enabling request is detected in the document +# control stream. +# + TC_DATA="" TOC_FORMAT="" BODY_FORMAT="" + fi +# +# Re-enable progress reporting, if necessary ... +# (Missing 'awk' or 'diff' may have disabled it, to avoid display +# of spurious messages associated with reference resolution). +# + test x${SHOW_PROGRESS+"set"} = x"set" && SAY=echo +# +# If a document cover style sheet is specified ... +# then we run a special formatting pass, to create a cover section file. +# + if test -n "$STYLESHEET" + then + DOT='^\.[ ]*' + CS_MACRO=${CS_MACRO-"CS"} CE_MACRO=${CE_MACRO-"CE"} + $SAY >&2 $n "Formatting document ... front cover section ..$c" + CS_FILTER="$STREAM $SED -n '/${DOT}${CS_MACRO}/,/${DOT}${CE_MACRO}/p'" + eval $CS_FILTER $INPUT_FILES | eval $GROFF_STYLE $STYLESHEET - > $CS_DATA + $SAY >&2 ". done" + fi +# +# If table of contents relocation is to be performed (it is, by default), +# then we run an extra 'groff' pass, to format a TOC intermediate file. +# + if test -n "$TC_DATA" + then + $SAY >&2 $n "Formatting document ... table of contents ..$c" + eval $STREAM $GROFF_STYLE $TOC_FORMAT $REFCOPY $INPUT_FILES > $TC_DATA + $SAY >&2 ". done" + fi +# +# In all cases, a final 'groff' pass is required, to format the document body. +# + $SAY >&2 $n "Formatting document ... body section ..$c" + eval $STREAM $GROFF_STYLE $BODY_FORMAT $REFCOPY $INPUT_FILES > $BD_DATA + $SAY >&2 ". done" +# +# Finally ... +# Invoke GhostScript as a PDF writer, to bind all of the generated +# PostScript intermediate files into a single PDF output file. +# + $SAY >&2 $n "Writing PDF output ..$c" + if test -z "$PDFROFF_POSTPROCESSOR_COMMAND" + then + PDFROFF_POSTPROCESSOR_COMMAND="$GS -dQUIET -dBATCH -dNOPAUSE -dSAFER + -sDEVICE=pdfwrite -sOutputFile="${PDF_OUTPUT-"-"} + + elif test -n "$PDF_OUTPUT" + then + exec > $PDF_OUTPUT + fi +# +# (This 'sed' script is a hack, to eliminate redundant blank pages). +# + ${PDFROFF_COLLATE-"$SED"} ${PDFROFF_KILL_NULL_PAGES-' + /%%Page:/{ + N + /%%BeginPageSetup/b again + } + b + :again + /%%EndPageSetup/b finish + /%%Page:/{ + N + b again + } + b + :finish + N + /^%%Page:.*\n0 Cg EP$/d + '} $TC_DATA $BD_DATA | $PDFROFF_POSTPROCESSOR_COMMAND $CS_DATA - + $SAY >&2 ". done" +# +# ------------------------------------------------------------------------------ +# $RCSfile$ $Revision$: end of file diff --git a/contrib/pdfmark/sanitize.tmac b/contrib/pdfmark/sanitize.tmac new file mode 100644 index 0000000..49feaa9 --- /dev/null +++ b/contrib/pdfmark/sanitize.tmac @@ -0,0 +1,170 @@ +.ig + +sanitize.tmac + +Copyright (C) 2021 Free Software Foundation, Inc. + Written by Keith Marshall (keith.d.marshall@ntlworld.com) + +This file 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/>. + +.. +.eo +.de sanitize +.\" Usage: .sanitize name text ... +.\" +.\" Remove designated formatting escape sequences from "text ..."; return +.\" the sanitized text in a string register, identified by "name". +.\" +.\" Begin by initializing the named result as an empty string, bind it to +.\" an internal reference name, and discard the "name" argument, to leave +.\" only the text which is to be sanitized, as residual arguments. +.\" +. ds \$1 +. als sanitize:result \$1 +. shift +. +.\" Initialize a working string register, which we will cyclically reduce +.\" until it becomes empty, after starting with all of the text passed as +.\" the residual arguments, and establish its initial length. +.\" +. ds sanitize:residual "\$*\" +. length sanitize:residual.length "\$*\" +. +.\" Begin the cyclic reduction loop... +.\" +. while \n[sanitize:residual.length] \{\ +. \" +. \" ...assuming, at the start of each cycle, that the next character +. \" will not be skipped, and that it will be moved from the residual, +. \" to the result, as the character-by-character scan proceeds. +. \" +. nr sanitize:skip.count 0 +. sanitize:scan.execute +. +. \" For each character scanned, we need to check if it matches the +. \" normal escape character; the check is most readily performed, if +. \" an alternative escape character is introduced, and when a match +. \" is found, we prepare to skip an escape sequence. +. \" +. ec ! +. if '!*[sanitize:scan.char]'\' .nr sanitize:skip.count 1 +. ec +. ie \n[sanitize:skip.count] \{\ +. \" +. \" When a possible escape sequence has been detected, we back it +. \" up, (in case it isn't recognized, and we need to reinstate its +. \" content into the result string), then scan ahead to check for +. \" an identifiable escape sequence... +. \" +. rn sanitize:scan.char sanitize:hold +. sanitize:scan.execute +. ie d sanitize:esc-\*[sanitize:scan.char] \ +. \" +. \" ...which we delegate to its appropriate handler, to skip... +. \" +. sanitize:esc-\*[sanitize:scan.char] +. +. \" ...but, in the case of an unrecognized escape sequence, we copy +. \" its backed-up content, followed by the character retrieved from +. \" the current scan cycle, to the result string. +. \" +. el .as sanitize:result "\*[sanitize:hold]\*[sanitize:scan.char]\" +. \} +. +. \" When the current scan cycle has retrieved a character, which isn't +. \" part of any possible escape sequence, we simply copy that character +. \" to the result string. +. \" +. el .as sanitize:result "\*[sanitize:scan.char]\" +. \} +. +.\" Clean up the register space, by deleting all of the string registers, +.\" and numeric registers, which are designated as temporary, for private +.\" use within this macro only. +.\" +. rm sanitize:hold sanitize:scan.char sanitize:residual sanitize:result +. rr sanitize:residual.length sanitize:skip.count +.. +.de sanitize:scan.execute +.\" Usage (internal): .sanitize:scan.execute +.\" +.\" Perform a single-character reduction of sanitize:residual, by copying +.\" its initial character to sanitize:scan.char, and then deleting it from +.\" sanitize:residual itself. (Note that we use arithmetic decrementation +.\" of sanitize:residual.length, rather than repeating the length request +.\" on sanitize:residual, because reduction WILL fail when there is only +.\" one character remaining). +.\" +. nr sanitize:residual.length -1 +. ds sanitize:scan.char "\*[sanitize:residual]\" +. substring sanitize:scan.char 0 0 +. substring sanitize:residual 1 +.. +.de sanitize:skip-( +.\" Usage (internal): .sanitize:skip-( +.\" +.\" For any identified escape sequence, with a two-character property name, +.\" simply skip over the next two characters in the residual string. +.\" +. nr sanitize:residual.length -2 +. substring sanitize:residual 2 +.. +.de sanitize:skip-[ +.\" Usage (internal): .sanitize:skip-[ +.\" +.\" For any identified escape sequence, with an arbitrary-length property +.\" name, skip following characters in the residual string, until we find +.\" a terminal "]" character, or we exhaust the residual. +.\" +. while \n[sanitize:skip.count] \{\ +. sanitize:scan.execute +. ie \n[sanitize:residual.length] \{\ +. \" We haven't yet exhausted the residual; if we find a nested "[" +. \" character, increment the nesting level, otherwise decrement it +. \" for each "]"; it will become zero at the terminal "]". +. \" +. ie '\*[sanitize:scan.char]'[' .nr sanitize:skip.count +1 +. el .if '\*[sanitize:scan.char]']' .nr sanitize:skip.count -1 +. \} +. \" Stop unconditionally, if we do exhaust the residual. +. \" +. el .nr sanitize:skip.count 0 +. \} +.. +.de sanitize:esc-generic +.\" Usage: .sanitize:esc-X +.\" +.\" (X represents any legitimate single-character escape sequence id). +.\" +.\" Handler for skipping "\X" sequences, in text which is to be sanitized; +.\" this will automatically detect sequences conforming to any of the forms +.\" "\Xc", "\X(cc", or "\X[...]", and will handle each appropriately. The +.\" implementation is generic, and may be aliased to handle any specific +.\" escape sequences, which exhibit similar semantics. +.\" +. sanitize:scan.execute +. if d sanitize:skip-\*[sanitize:scan.char] \ +. sanitize:skip-\*[sanitize:scan.char] +.. +.ec +.\" Map the generic handler to specific escape sequences, as required. +.\" +.als sanitize:esc-F sanitize:esc-generic +.\" Local Variables: +.\" mode: nroff +.\" End: +.\" vim: filetype=groff: +.\" sanitize.tmac: end of file diff --git a/contrib/pdfmark/spdf.tmac b/contrib/pdfmark/spdf.tmac new file mode 100644 index 0000000..130d8bd --- /dev/null +++ b/contrib/pdfmark/spdf.tmac @@ -0,0 +1,328 @@ +.ig + +spdf.tmac + +Binding macros for use of "-m pdfmark" in conjunction with "-ms". + + +Copyright (C) 2004-2021 Free Software Foundation, Inc. + Written by Keith Marshall (keith.d.marshall@ntlworld.com) + +This file 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/>. + +.. +.\" Bindings +.\" ======== +.\" +.\" Generic output mode control flag; pdfmark.tmac will bind this to +.\" its own internal PDFOPMODE flag. +.\" +.if !r OPMODE .nr OPMODE 1 +.\" +.mso s.tmac +.mso sanitize.tmac +.mso pdfmark.tmac +. +.\" Establish a handler to clean up output context, at end of document. +.\" +.de pdf@exit em +. if \\n[OPMODE] .pdfsync +. pg@end-text +.em pdf@exit +. +. +.\" Omitted Sections +.\" ================ +.\" +.\" Define section markers, for special document sections, +.\" which are to be omitted from regular document processing. +.\" +.\" .OMIT <name1> <name2> +.\" +.\" Defines a pair of macros, <name1> and <name2>, such that execution +.\" of .<name1> marks the start of a block of troff input which should +.\" be ignored; this block ends, on execution of .<name2> +.\" +.de OMIT OMIT +. de \\$1 +. omit@begin \\$1 \\$2 +. . +. de \\$2 +. omit@end \\$1 \\$2 +. . +.\" Definition of the OMIT macro itself, ends when it is first used, +.\" to identify an omitted section marker macro pair. +.\" +.OMIT CS CE \" front cover text, processed independently +.OMIT MS ME \" menu definitions, for info documents only +. +.\" Actual omission is initiated by recording the name of the block +.\" start macro, followed by injection of an "ig" request... +.\" +.de omit@begin +. ds omit@section \\$1 +\. ig \\$2 +.. +.\" ...and terminates with verification that the end macro matches +.\" the start macro, and removal of the start macro record; (error +.\" reporting uses the "@error" macro, from s.tmac). +.\" +.de omit@end +. if !'\\*[omit@section]'\\$1' .@error \\$2 without \\$1 +. rm omit@section +.. +. +.\" Document Outlines, and Section Headings +.\" ======================================= +.\" +.\" .XH [-N <name>] [-S] [-X] <outline-level> <heading-text> ... +.\" .XN [-N <name>] [-S] [-X] <heading-text> ... +.\" +.\" Use after SH, and XN <n> respectively, to define text to be set +.\" within the section heading, as a PDF document ouline entry, and +.\" optionally, as a table of contents entry. +.\" +.\" Options: +.\" -N <name> Assigns <name> as a pdfhref destination, +.\" and associates it with the heading. +.\" +.\" -S Strip troff font-change escapes from the +.\" text copied to the document outline. +.\" +.\" -X Force pdfhref destination assignment; if +.\" -N <name> is unspecified, use first word +.\" of <heading-text> as <name>. +.\" +.\" Arguments: +.\" <outline-level> The nesting level of the heading, within +.\" the document outline, and TOC. Required +.\" for XH; inferred from NH <n>, for XN. +.\" +.\" <heading-text> Text (required) to appear within each of +.\" the section heading, document outline, +.\" and (optionally) TOC. +.\" +.\" Hooks: +.\" XH-INIT User-defined macro, called on entry to XH; +.\" used to specify initialization state which +.\" may be needed after using SH; e.g. specify +.\" a PDFHREF.INFO state without incorporation +.\" of any "section" references. +.\" +.\" XN-INIT User-defined macro, called on entry to XN; +.\" used to specify initialization state which +.\" may be needed after using NH; e.g. specify +.\" a PDFHREF.INFO state which may incorporate +.\" "section" references. +.\" +.\" XH-UPDATE-TOC User-defined macro, called by both XH, and +.\" XN; (there is no XN-UPDATE-TOC). Must be +.\" defined, if a TOC entry is to be generated +.\" by either XH, or XN; the format of such a +.\" TOC entry is determined by the definition +.\" of this macro. +.\" +.\" Our replacements for both XH, and XN macros share a common entry +.\" point; we map both to their respective replacement hooks, so that +.\" we may continue to take advantage of setup logic in s.tmac. When +.\" these are eventually invoked, they will have been renamed so that +.\" they replace XH, and XH respectively. +.\" +.de XH-REPLACEMENT als +.als XN-REPLACEMENT XH-REPLACEMENT +.\" FIXME: within s.tmac, the heading level established by the most +.\" recent prior invocation of the NH macro is tracked by the "nh*hl" +.\" private register; perhaps s.tmac could expose this more publicly, +.\" as by this ostensibly read-only alias, since we need it to keep +.\" PDF document outlines in synchronization with NH level... +.\" +.\" .aln .NH nh*hl +.\" +.\" ...but maybe a local "belt and braces" approach is better anyway, +.\" to insulate "nh*hl" from possible abuse of our ".NH" register, by +.\" any users who may be determined to shoot themselves in the foot! +.\" +.ie r nh*hl .nr spdf:nh*hl \n[nh*hl] +.el .nr spdf:nh*hl 0 +.am @NH +. nr spdf:nh*hl \\n[nh*hl] +.. +.aln .NH spdf:nh*hl +. +.\" The common entry point for both XH, and XN, handles initialization, +.\" and interpretation of any specified options, before handing over to +.\" one of two distinct formatting helper macros, which are specific to +.\" the XH, and XN implementations respectively. +.\" +.am XH-REPLACEMENT \" thus serving as implementation for both XH and XN +.\" +.\" The user is expected to furnish the XH-INIT, XH-UPDATE-TOC, and +.\" XN-INIT handlers. (Note that the XH-UPDATE-TOC hook serves both +.\" XH and XN; there is no separate XN-UPDATE-TOC). A suitable stub +.\" for each is provided by s.tmac; we have no need to replace them. +.\" +. \\$0-INIT +. rm spdf:refname +. als spdf:bm.define spdf:bm.basic +. while d spdf:XH\\$1 \{\ +. spdf:XH\\$1 \\$* +. shift \\n[spdf:argc] +. \} +. rr spdf:argc +. if '\\$1'--' .shift +. spdf:\\$0.format \\$@ +.. +.\" Interpret the "-N <name>" option... +.\" +.de spdf:XH-N +. ds spdf:refname \\$2 +. nr spdf:argc 2 +.. +.\" ...the "-X" option, and... +.\" +.de spdf:XH-X +. if !d spdf:refname .ds spdf:refname \\\\$1 +. nr spdf:argc 1 +.. +.\" ...the "-S" option. +.\" +.de spdf:XH-S +. als spdf:bm.define sanitize +. nr spdf:argc 1 +.. +.\" By default, when the "-S" option is not specified, the text +.\" incorporated into the PDF document outline will be a simple +.\" verbatim copy of the arguments. +.\" +.de spdf:bm.basic +. shift \" ignore \$1; it should always be "spdf:bm.text" +. ds spdf:bm.text "\\$*\" +.. +.\" After initialization, and interpretation of options, the XH +.\" and XN implementations diverge, into this helper macro, which +.\" is specific to the XH implementation... +.\" +.de spdf:XH.format +. XH-UPDATE-TOC \\$@ +. ds spdf:bm.argv \\$1 +. shift \" finalization doesn't want the outline level in \$1 +. spdf:XH.finalize \\$@ +.. +.\" ...and this, which is specific to XN... +.\" +.de spdf:XN.format +. ds spdf:bm.argv \\n[.NH] \\*[SN] +. XH-UPDATE-TOC \\n[.NH] \\*[SN] \\$@ +. spdf:XH.finalize \\$@ +.. +.\" ...before ultimately converging back into this finalization +.\" macro, which is once again common to both XH and XN. +.\" +.de spdf:XH.finalize +. spdf:bm.define spdf:bm.text "\\$*" +. if d spdf:refname .pdfhref M -X -N \\*[spdf:refname] -- \\$@ +. pdfhref O \\*[spdf:bm.argv] \\*[spdf:bm.text] +. rm spdf:refname spdf:bm.argv spdf:bm.text +. nop \\$* +.. +. +.\" Cross-Reference Marshalling +.\" =========================== +.\" +.\" s.tmac provides the "pg@bottom" macro, which has already +.\" been installed as a page transition trap. To ensure proper +.\" mapping of "pdfhref" links which overflow the bottom of any +.\" page, we need to install the "pdfhref" page transition hook, +.\" as an addendum to this macro. +. +.pdfhref I -PT pg@bottom +. +. +.\" Phased Output Control +.\" ===================== +.\" +.\" Segregate output of table of contents, and document body text, +.\" into two distinct output phases, to facilitate assembly of the +.\" aggregate document in the correct order, particularly when the +.\" TOC is generated at the end, by the default "ms" mechanism. +.\" +.nr PDF-TOC-ONLY 1 +.nr PDF-BODY-TEXT 2 +.\" +.\" .OP [<output-phase>] +.\" +.\" If the user-specified PHASE numeric register has been defined, +.\" and its value matches the <output-phase> argument value, (or if +.\" no <output-phase> argument is specified), then set the OPMODE +.\" control flag to one, and activate groff's "pen-down" mode. +.\" +.\" Otherwise, if <output-phase> is specified, but does NOT match +.\" PHASE, set OPMODE to zero, and select "pen-up" mode. +.\" +.\" Alternatively, if PHASE has not been defined, unconditionally +.\" set OPMODE to one, and leave groff's pen state unchanged. +.\" +.de OP +.ie r PHASE \{\ +. ie \\n(.$ \{\ +. nr op:request 0 +. while \\n(.$ \{\ +. if \\$1=\\n[PHASE] .nr op:request 1 +. shift +. \} +. \} +. el .nr op:request 1 +. if !\\n[op:request]=\\n[OPMODE] \{\ +. nr OPMODE \\n[op:request] +. nop \O[\\n[OPMODE]]\c +. \} +. \} +.el .nr OPMODE 1 +.. +. +.\" Table of Contents Generation +.\" ============================ +.\" +.\" .TC [no] +.\" +.\" Replaces (and emulates) the TC macro, from s.tmac, to ensure +.\" that the pdfmark document outline cache is flushed, before TOC +.\" generation commences, that an outline reference is added for the +.\" TOC itself, and that pdfroff TOC relocation mode is enabled, for +.\" the TOC output phase of document production. +.\" +.de TC +. pdfsync O +. P1 +. OP \n[PDF-TOC-ONLY] +. pg@begin 1 i +. if !\\n[PHASE] .tm pdfroff-option:set toc_relocation=enabled +. if \\n[OPMODE] \{\ +. pdfhref O -T T 1 "\\*[TOC]" +. pdfsync O +. \} +. PX \\$1 +.. +. +.\" Initialize the default output state, for production of "body-text". +.\" +.OP \n[PDF-BODY-TEXT] +. +.\" Local Variables: +.\" mode: nroff +.\" End: +.\" vim: filetype=groff: +.\" spdf.tmac: end of file diff --git a/contrib/pic2graph/pic2graph.1.man b/contrib/pic2graph/pic2graph.1.man new file mode 100644 index 0000000..f3c1c1e --- /dev/null +++ b/contrib/pic2graph/pic2graph.1.man @@ -0,0 +1,234 @@ +.TH pic2graph @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +pic2graph \- convert a +.I pic +diagram into a cropped image +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" This documentation is released to the public domain. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_pic2graph_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY pic2graph +.RB [ \-unsafe ] +.RB [ \-format\~\c +.IR output-format ] +.RB [ \-eqn\~\c +.IR delimiters ] +.RI [ convert-argument \~.\|.\|.] +.YS +. +. +.SY pic2graph +.B \-\-help +.YS +. +. +.SY pic2graph +.B \-v +. +.SY pic2graph +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I pic2graph +reads a +.MR @g@pic @MAN1EXT@ +program from the standard input and writes an image file, +by default in Portable Network Graphics (PNG) format, +to the standard output. +. +It furthermore translates +.MR @g@eqn @MAN1EXT@ +constructs, so it can be used for generating images of mathematical +formulae. +. +. +.PP +The input PIC code should +.I not +be wrapped with the +.B .PS +and +.BR .PE / .PF +macros that normally guard it within +.MR groff @MAN1EXT@ +documents. +. +. +.\" FIXME: How old? This text hasn't been touched since 2008 at latest. +.\" Older versions of +.\" .I \%convert +.\" will produce a black-on-white graphic; newer ones may produce a +.\" black-on-transparent graphic. +. +.PP +Arguments not recognized by +.I pic2graph +are passed to the ImageMagick or GraphicsMagick program +.MR convert 1 . +. +. +By specifying these, you can give your image a border, +.\" Transparent backgrounds are the default in 2018. +.\" force the background transparent, +set the image's pixel density, +or perform other useful transformations. +. +. +.PP +The output image is clipped using +.IR \%convert 's +.B \-trim +option to the smallest possible bounding box that contains all the black +pixels. +. +. +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-\-help +displays a usage message, +while +.B \-v +and +.B \-\-version +show version information; +all exit afterward. +. +.TP +.BI \-eqn\~ delimiters +Use +.I delimiters +as the opening and closing +characters that delimit +.I @g@eqn +directives; +the default is \(lq$$\(rq. +. +The option argument +.I delimiters +should be a two-character string, +but an empty string (\(dq\(dq) is accepted as a directive to disable +.I @g@eqn +processing. +. +. +.TP +.BI \-format\~ output-format +Write the image in +.IR output-format , +which must be understood by +.IR \%convert ; +the default is PNG. +. +. +.TP +.B \-unsafe +Run +.I groff +in +.I unsafe +mode, enabling the PIC command +.B sh +to execute arbitrary Unix shell commands. +. +The +.I groff +default is to forbid this. +. +. +.\" ==================================================================== +.SH Environment +.\" ==================================================================== +. +.TP +.I \%GROFF_TMPDIR +.TQ +.I \%TMPDIR +.TQ +.I TMP +.TQ +.I TEMP +These environment variables are searched in the given order to determine +the directory where temporary files will be created. +. +If none are set, +.I /tmp +is used. +. +. +.\" ==================================================================== +.SH Authors +.\" ==================================================================== +. +.I pic2graph +was written by +.MT esr@\:thyrsus\:.com +Eric S.\& Raymond +.ME , +based on a recipe by W.\& Richard Stevens. +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +W.\& Richard Stevens, +.UR http://\:www\:.kohala\:.com/\:start/\:troff/\:pic2html\:.html +.I Turning PIC into HTML +.UE +. +. +.PP +.MR eqn2graph @MAN1EXT@ , +.MR grap2graph @MAN1EXT@ , +.MR @g@pic @MAN1EXT@ , +.MR @g@eqn @MAN1EXT@ , +.MR groff @MAN1EXT@ , +.MR convert 1 +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_pic2graph_1_man_C] +.do rr *groff_pic2graph_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/contrib/pic2graph/pic2graph.am b/contrib/pic2graph/pic2graph.am new file mode 100644 index 0000000..9788270 --- /dev/null +++ b/contrib/pic2graph/pic2graph.am @@ -0,0 +1,40 @@ +# Copyright (C) 2001-2020 Free Software Foundation, Inc. +# +# This file 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/>. +# +# pic2graph.am +# + +pic2graph_srcdir = $(top_srcdir)/contrib/pic2graph +man1_MANS += contrib/pic2graph/pic2graph.1 +bin_SCRIPTS += pic2graph +EXTRA_DIST += \ + contrib/pic2graph/pic2graph.sh \ + contrib/pic2graph/pic2graph.1.man + +pic2graph: $(pic2graph_srcdir)/pic2graph.sh + $(AM_V_GEN)sed -e "s|[@]g[@]|$(g)|g" \ + -e "s|[@]VERSION[@]|$(VERSION)|" \ + -e $(SH_SCRIPT_SED_CMD) $(pic2graph_srcdir)/pic2graph.sh \ + >$@ \ + && chmod +x $@ + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/contrib/pic2graph/pic2graph.sh b/contrib/pic2graph/pic2graph.sh new file mode 100644 index 0000000..b229914 --- /dev/null +++ b/contrib/pic2graph/pic2graph.sh @@ -0,0 +1,122 @@ +#! /bin/sh +# +# pic2graph -- compile PIC image descriptions to bitmap images +# +# by Eric S. Raymond <esr@thyrsus.com>, July 2002 + +# In Unixland, the magic is in knowing what to string together... +# +# Take a pic/eqn diagram on stdin, emit cropped bitmap on stdout. +# The pic markup should *not* be wrapped in .PS/.PE, this script will do that. +# An -unsafe option on the command line enables gpic/groff "unsafe" mode. +# A -format FOO option changes the image output format to any format +# supported by convert(1). An -eqn option changes the eqn delimiters. +# All other options are passed to convert(1). The default format in PNG. +# +# Requires the groff suite and the ImageMagick tools. Both are open source. +# This code is released to the public domain. +# +# Here are the assumptions behind the option processing: +# +# 1. Only the -U option of gpic(1) is relevant. -C doesn't matter because +# we're generating our own .PS/.PE, -[ntcz] are irrelevant because we're +# generating Postscript. +# +# 2. Ditto for groff(1), though it's a longer and more tedious demonstration. +# +# 3. Many options of convert(1) are potentially relevant (especially +# -density, -interlace, -transparency, -border, and -comment). +# +# Thus, we pass -U to gpic and groff, and everything else to convert(1). +# +# We don't have complete option coverage on eqn because this is primarily +# intended as a pic translator; we can live with eqn defaults. +# +groffpic_opts="" +convert_opts="" +convert_trim_arg="-trim" +format="png" +eqndelim='$$' + +while [ "$1" ] +do + case $1 in + -unsafe) + groffpic_opts="-U";; + -format) + format=$2 + shift;; + -eqn) + eqndelim=$2 + shift;; + -v | --version) + echo "GNU pic2graph (groff) version @VERSION@" + exit 0;; + --help) + echo "usage: pic2graph [ option ...] < in > out" + exit 0;; + *) + convert_opts="$convert_opts $1";; + esac + shift +done + +if [ "$eqndelim" ] +then + eqndelim="delim $eqndelim" +fi + +# create temporary directory +tmp= +for d in "$GROFF_TMPDIR" "$TMPDIR" "$TMP" "$TEMP" /tmp +do + test -n "$d" && break +done + +if ! test -d "$d" +then + echo "$0: error: temporary directory \"$d\" does not exist or is" \ + "not a directory" >&2 + exit 1 +fi + +if ! tmp=`(umask 077 && mktemp -d -q "$d/pic2graph-XXXXXX") 2> /dev/null` +then + # mktemp failed--not installed or is a version that doesn't support those + # flags? Fall back to older method which uses more predictable naming. + # + # $RANDOM is a Bashism. The fallback of $PPID is not good pseudorandomness, + # but is supported by the stripped-down dash shell, for instance. + tmp="$d/pic2graph$$-${RANDOM:-$PPID}" + (umask 077 && mkdir "$tmp") 2> /dev/null +fi + +if ! test -d "$tmp" +then + echo "$0: error: cannot create temporary directory \"$tmp\"" >&2 + exit 1 +fi + +# See if the installed version of convert(1) is new enough to support the -trim +# option. Versions that didn't were described as "old" as early as 2008. +is_convert_recent=`convert -help | grep -e -trim` +if test -z "$is_convert_recent" +then + echo "$0: warning: falling back to old '-crop 0x0' trim method" >&2 + convert_trim_arg="-crop 0x0" +fi + +trap 'exit_status=$?; rm -rf "$tmp" && exit $exit_status' EXIT INT TERM + +# Here goes: +# 1. Wrap the input in dummy .PS/PE macros (and add possibly null .EQ/.EN) +# 2. Process through eqn and pic to emit troff markup. +# 3. Process through groff to emit Postscript. +# 4. Use convert(1) to crop the PostScript and turn it into a bitmap. +(echo ".EQ"; echo $eqndelim; echo ".EN"; echo ".PS"; cat; echo ".PE") | \ + groff -e -p $groffpic_opts -Tps -P-pletter > "$tmp"/pic2graph.ps \ + && convert $convert_trim_arg $convert_opts "$tmp"/pic2graph.ps \ + "$tmp"/pic2graph.$format \ + && cat "$tmp"/pic2graph.$format + +# End diff --git a/contrib/rfc1345/COPYRIGHT b/contrib/rfc1345/COPYRIGHT new file mode 100644 index 0000000..9f3b859 --- /dev/null +++ b/contrib/rfc1345/COPYRIGHT @@ -0,0 +1,23 @@ +Copyright (c) 2021 Dorai Sitaram + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice (including +the next paragraph) shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/contrib/rfc1345/groff_rfc1345.7.man b/contrib/rfc1345/groff_rfc1345.7.man new file mode 100644 index 0000000..c04cad9 --- /dev/null +++ b/contrib/rfc1345/groff_rfc1345.7.man @@ -0,0 +1,265 @@ +.TH groff_rfc1345 @MAN7EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +groff_rfc1345 \- special character names from RFC 1345 and Vim digraphs +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright (c) 2021 Dorai Sitaram +.\" +.\" Permission is hereby granted, free of charge, to any person +.\" obtaining a copy of this software and associated documentation files +.\" (the "Software"), to deal in the Software without restriction, +.\" including without limitation the rights to use, copy, modify, merge, +.\" publish, distribute, sublicense, and/or sell copies of the Software, +.\" and to permit persons to whom the Software is furnished to do so, +.\" subject to the following conditions: +.\" +.\" The above copyright notice and this permission notice (including the +.\" next paragraph) shall be included in all copies or substantial +.\" portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +.\" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +.\" BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +.\" ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +.\" CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +.\" SOFTWARE. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_groff_rfc1345_7_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +The file +.I rfc1345.tmac +defines special character escape sequences for +.MR groff @MAN7EXT@ +based on the glyph mnemonics specified in RFC 1345 and the digraph table +of the text editor Vim. +. +Each escape sequence translates to a Unicode code point, +and will render correctly if the underlying font is a Unicode font that +covers the code point. +. +. +.PP +For example, +.RB \[lq] \[rs][Rx] \[rq] +is the \[lq]recipe\[rq] or \[lq]prescription take\[rq] symbol, +and maps to the code point U+211E. +. +.I groff +lets you write it as +.RB \[lq] \[rs][u211E] \[rq], +but +.RB \[lq] \[rs][Rx] \[rq] +is more mnemonic. +. +. +.PP +For a list of the glyph names provided, +please see the file +.IR rfc1345.tmac , +which contains definitions of the form +. +.RS +.EX +\&.char \[rs][Rx] \[rs][u211E] \[rs]" PRESCRIPTION TAKE +.EE +.RE +. +where +.BR .char 's +first argument defines a +.I groff +special character escape sequence with a mnemonic glyph name, +its second argument is a special character escape sequence based on the +code point, +and the comment describes the glyph defined. +. +. +.PP +The RFC 1345 glyph names cover a wide range of Unicode code points, +including +supplemental Latin, +Greek, +Cyrillic, +Hebrew, +Arabic, +Hiragana, +Katakana, +and Bopomofo letters, +punctuation, +math notation, +currency +symbols, +industrial and entertainment icons, +and box-drawing symbols. +. +. +.PP +The Vim digraph table is practically a subset of RFC 1345 +(being limited to two-character mnemonics), +but, +as a newer implementation, +adds four mnemonics not specified in the RFC +(the horizontal ellipsis, +the Euro sign, +and two mappings for the rouble sign). +. +These have also been added to +.IR rfc1345.tmac . +. +. +.PP +.I rfc1345.tmac +contains a total of 1,696 glyph names. +. +It is not an +error to load +.I rfc1345.tmac +if your font does not have all the glyphs, +as long as it contains the glyphs that you actually use in your +document. +. +. +.PP +The RFC 1345 mnemonics are not identical in every case to the mappings +for special character glyph names that are built in to +.IR groff ; +for example, +.RB \[lq] \[rs][<<] \[rq] +means the \[lq]much less than\[rq] sign (U+226A) when +.I rfc1345.tmac +is not loaded and this special character is not otherwise defined by a +document or macro package. +. +.I rfc1345.tmac +redefines +.RB \[lq] \[rs][<<] \[rq] +to the \[lq]left-pointing double angle quotation mark\[rq] (U+00AB). +. +See +.MR groff_char @MAN7EXT@ +for the full list of predefined special character escape sequences. +. +. +.\" ==================================================================== +.SS Usage +.\" ==================================================================== +. +Load the +.I rfc1345.tmac +file. +. +This can be done by either adding +.RB \[lq] ".mso rfc1345.tmac" \[rq] +to your document before the first use of any of the glyph names the +macro file defines, +or by using the +.MR @g@troff @MAN1EXT@ +option +.RB \[lq] "\-m rfc1345" \[rq] +from the shell. +. +. +.\" ==================================================================== +.SS Bugs +.\" ==================================================================== +. +As the +.I groff +Texinfo manual notes, +\[lq][o]nly the current font is checked for ligatures and kerns; +neither special fonts nor entities defined with the +.B char +request +(and its siblings) +are taken into account.\[rq] +. +Many of the characters defined in +.I rfc1345.tmac +are accented Latin letters, +and will be affected by this deficiency, +.UR https://\:savannah\:.gnu\:.org/\:bugs/\:?59932 +producing subpar typography +.UE . +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.I @MACRODIR@/\:rfc1345\:.tmac +implements the character mappings. +. +. +.\" ==================================================================== +.SH Authors +.\" ==================================================================== +. +.I rfc1345\:.tmac +was contributed by +.MT ds26gte@\:yahoo\:.com +Dorai Sitaram +.ME . +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.UR https://\:tools\:.ietf\:.org/\:html/\:rfc1345 +RFC 1345 +.UE , +by Keld Simonsen, +June 1992. +. +. +.PP +The Vim digraph table can be listed using the +.MR vim 1 +command +.RB \[lq] ":help \%digraph\-table" \[rq]. +. +. +.PP +.MR groff_char @MAN7EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_groff_rfc1345_7_man_C] +.do rr *groff_groff_rfc1345_7_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/contrib/rfc1345/rfc1345.am b/contrib/rfc1345/rfc1345.am new file mode 100644 index 0000000..7a23424 --- /dev/null +++ b/contrib/rfc1345/rfc1345.am @@ -0,0 +1,41 @@ +# Copyright 2021 Free Software Foundation, Inc. +# +# This file 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/>. + +rfc1345_srcdir = $(top_srcdir)/contrib/rfc1345 +rfc1345_builddir = $(top_builddir)/contrib/rfc1345 + +man7_MANS += contrib/rfc1345/groff_rfc1345.7 + +# files installed in $(tmacdir) +rfc1345tmacdir = $(tmacdir) +dist_rfc1345tmac_DATA = contrib/rfc1345/rfc1345.tmac + +rfc1345_TESTS= \ + contrib/rfc1345/tests/rfc1345-smoke-test.sh +TESTS += $(rfc1345_TESTS) +EXTRA_DIST += $(rfc1345_TESTS) + +EXTRA_DIST += \ + contrib/rfc1345/groff_rfc1345.7.man \ + contrib/rfc1345/COPYRIGHT + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/contrib/rfc1345/rfc1345.tmac b/contrib/rfc1345/rfc1345.tmac new file mode 100644 index 0000000..5041e78 --- /dev/null +++ b/contrib/rfc1345/rfc1345.tmac @@ -0,0 +1,1705 @@ +.ig +rfc1345.tmac + +Adds glyph names formed from +- the mnemonics specified in + RFC 1345, https://www.rfc-editor.org/rfc/rfc1345.txt, + Keld Simonsen, June 1992; and +- the digraphs ,. Eu =R =P from Vim's digraph table. +.. +.char \[!I] \[u00A1] \" INVERTED EXCLAMATION MARK +.char \[Ct] \[u00A2] \" CENT SIGN +.char \[Pd] \[u00A3] \" POUND SIGN +.char \[Cu] \[u00A4] \" CURRENCY SIGN +.char \[Ye] \[u00A5] \" YEN SIGN +.char \[BB] \[u00A6] \" BROKEN BAR +.char \[SE] \[u00A7] \" SECTION SIGN +.char \[':] \[u00A8] \" DIAERESIS +.char \[Co] \[u00A9] \" COPYRIGHT SIGN +.char \[-a] \[u00AA] \" FEMININE ORDINAL INDICATOR +.char \[<<] \[u00AB] \" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +.char \[NO] \[u00AC] \" NOT SIGN +.char \[--] \[u00AD] \" SOFT HYPHEN +.char \[Rg] \[u00AE] \" REGISTERED SIGN +.char \['m] \[u00AF] \" MACRON +.char \[DG] \[u00B0] \" DEGREE SIGN +.char \[+-] \[u00B1] \" PLUS-MINUS SIGN +.char \[2S] \[u00B2] \" SUPERSCRIPT TWO +.char \[3S] \[u00B3] \" SUPERSCRIPT THREE +.char \[''] \[u00B4] \" ACUTE ACCENT +.char \[My] \[u00B5] \" MICRO SIGN +.char \[PI] \[u00B6] \" PILCROW SIGN +.char \[.M] \[u00B7] \" MIDDLE DOT +.char \[',] \[u00B8] \" CEDILLA +.char \[1S] \[u00B9] \" SUPERSCRIPT ONE +.char \[-o] \[u00BA] \" MASCULINE ORDINAL INDICATOR +.char \[>>] \[u00BB] \" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +.char \[14] \[u00BC] \" VULGAR FRACTION ONE QUARTER +.char \[12] \[u00BD] \" VULGAR FRACTION ONE HALF +.char \[34] \[u00BE] \" VULGAR FRACTION THREE QUARTERS +.char \[?I] \[u00BF] \" INVERTED QUESTION MARK +.char \[A!] \[u00C0] \" LATIN CAPITAL LETTER A WITH GRAVE +.char \[A'] \[u00C1] \" LATIN CAPITAL LETTER A WITH ACUTE +.char \[A>] \[u00C2] \" LATIN CAPITAL LETTER A WITH CIRCUMFLEX +.char \[A?] \[u00C3] \" LATIN CAPITAL LETTER A WITH TILDE +.char \[A:] \[u00C4] \" LATIN CAPITAL LETTER A WITH DIAERESIS +.char \[AA] \[u00C5] \" LATIN CAPITAL LETTER A WITH RING ABOVE +.char \[AE] \[u00C6] \" LATIN CAPITAL LETTER AE +.char \[C,] \[u00C7] \" LATIN CAPITAL LETTER C WITH CEDILLA +.char \[E!] \[u00C8] \" LATIN CAPITAL LETTER E WITH GRAVE +.char \[E'] \[u00C9] \" LATIN CAPITAL LETTER E WITH ACUTE +.char \[E>] \[u00CA] \" LATIN CAPITAL LETTER E WITH CIRCUMFLEX +.char \[E:] \[u00CB] \" LATIN CAPITAL LETTER E WITH DIAERESIS +.char \[I!] \[u00CC] \" LATIN CAPITAL LETTER I WITH GRAVE +.char \[I'] \[u00CD] \" LATIN CAPITAL LETTER I WITH ACUTE +.char \[I>] \[u00CE] \" LATIN CAPITAL LETTER I WITH CIRCUMFLEX +.char \[I:] \[u00CF] \" LATIN CAPITAL LETTER I WITH DIAERESIS +.char \[D-] \[u00D0] \" LATIN CAPITAL LETTER ETH (Icelandic) +.char \[N?] \[u00D1] \" LATIN CAPITAL LETTER N WITH TILDE +.char \[O!] \[u00D2] \" LATIN CAPITAL LETTER O WITH GRAVE +.char \[O'] \[u00D3] \" LATIN CAPITAL LETTER O WITH ACUTE +.char \[O>] \[u00D4] \" LATIN CAPITAL LETTER O WITH CIRCUMFLEX +.char \[O?] \[u00D5] \" LATIN CAPITAL LETTER O WITH TILDE +.char \[O:] \[u00D6] \" LATIN CAPITAL LETTER O WITH DIAERESIS +.char \[*X] \[u00D7] \" MULTIPLICATION SIGN +.char \[O/] \[u00D8] \" LATIN CAPITAL LETTER O WITH STROKE +.char \[U!] \[u00D9] \" LATIN CAPITAL LETTER U WITH GRAVE +.char \[U'] \[u00DA] \" LATIN CAPITAL LETTER U WITH ACUTE +.char \[U>] \[u00DB] \" LATIN CAPITAL LETTER U WITH CIRCUMFLEX +.char \[U:] \[u00DC] \" LATIN CAPITAL LETTER U WITH DIAERESIS +.char \[Y'] \[u00DD] \" LATIN CAPITAL LETTER Y WITH ACUTE +.char \[TH] \[u00DE] \" LATIN CAPITAL LETTER THORN (Icelandic) +.char \[ss] \[u00DF] \" LATIN SMALL LETTER SHARP S (German) +.char \[a!] \[u00E0] \" LATIN SMALL LETTER A WITH GRAVE +.char \[a'] \[u00E1] \" LATIN SMALL LETTER A WITH ACUTE +.char \[a>] \[u00E2] \" LATIN SMALL LETTER A WITH CIRCUMFLEX +.char \[a?] \[u00E3] \" LATIN SMALL LETTER A WITH TILDE +.char \[a:] \[u00E4] \" LATIN SMALL LETTER A WITH DIAERESIS +.char \[aa] \[u00E5] \" LATIN SMALL LETTER A WITH RING ABOVE +.char \[ae] \[u00E6] \" LATIN SMALL LETTER AE +.char \[c,] \[u00E7] \" LATIN SMALL LETTER C WITH CEDILLA +.char \[e!] \[u00E8] \" LATIN SMALL LETTER E WITH GRAVE +.char \[e'] \[u00E9] \" LATIN SMALL LETTER E WITH ACUTE +.char \[e>] \[u00EA] \" LATIN SMALL LETTER E WITH CIRCUMFLEX +.char \[e:] \[u00EB] \" LATIN SMALL LETTER E WITH DIAERESIS +.char \[i!] \[u00EC] \" LATIN SMALL LETTER I WITH GRAVE +.char \[i'] \[u00ED] \" LATIN SMALL LETTER I WITH ACUTE +.char \[i>] \[u00EE] \" LATIN SMALL LETTER I WITH CIRCUMFLEX +.char \[i:] \[u00EF] \" LATIN SMALL LETTER I WITH DIAERESIS +.char \[d-] \[u00F0] \" LATIN SMALL LETTER ETH (Icelandic) +.char \[n?] \[u00F1] \" LATIN SMALL LETTER N WITH TILDE +.char \[o!] \[u00F2] \" LATIN SMALL LETTER O WITH GRAVE +.char \[o'] \[u00F3] \" LATIN SMALL LETTER O WITH ACUTE +.char \[o>] \[u00F4] \" LATIN SMALL LETTER O WITH CIRCUMFLEX +.char \[o?] \[u00F5] \" LATIN SMALL LETTER O WITH TILDE +.char \[o:] \[u00F6] \" LATIN SMALL LETTER O WITH DIAERESIS +.char \[-:] \[u00F7] \" DIVISION SIGN +.char \[o/] \[u00F8] \" LATIN SMALL LETTER O WITH STROKE +.char \[u!] \[u00F9] \" LATIN SMALL LETTER U WITH GRAVE +.char \[u'] \[u00FA] \" LATIN SMALL LETTER U WITH ACUTE +.char \[u>] \[u00FB] \" LATIN SMALL LETTER U WITH CIRCUMFLEX +.char \[u:] \[u00FC] \" LATIN SMALL LETTER U WITH DIAERESIS +.char \[y'] \[u00FD] \" LATIN SMALL LETTER Y WITH ACUTE +.char \[th] \[u00FE] \" LATIN SMALL LETTER THORN (Icelandic) +.char \[y:] \[u00FF] \" LATIN SMALL LETTER Y WITH DIAERESIS +.char \[A-] \[u0100] \" LATIN CAPITAL LETTER A WITH MACRON +.char \[a-] \[u0101] \" LATIN SMALL LETTER A WITH MACRON +.char \[A(] \[u0102] \" LATIN CAPITAL LETTER A WITH BREVE +.char \[a(] \[u0103] \" LATIN SMALL LETTER A WITH BREVE +.char \[A;] \[u0104] \" LATIN CAPITAL LETTER A WITH OGONEK +.char \[a;] \[u0105] \" LATIN SMALL LETTER A WITH OGONEK +.char \[C'] \[u0106] \" LATIN CAPITAL LETTER C WITH ACUTE +.char \[c'] \[u0107] \" LATIN SMALL LETTER C WITH ACUTE +.char \[C>] \[u0108] \" LATIN CAPITAL LETTER C WITH CIRCUMFLEX +.char \[c>] \[u0109] \" LATIN SMALL LETTER C WITH CIRCUMFLEX +.char \[C.] \[u010A] \" LATIN CAPITAL LETTER C WITH DOT ABOVE +.char \[c.] \[u010B] \" LATIN SMALL LETTER C WITH DOT ABOVE +.char \[C<] \[u010C] \" LATIN CAPITAL LETTER C WITH CARON +.char \[c<] \[u010D] \" LATIN SMALL LETTER C WITH CARON +.char \[D<] \[u010E] \" LATIN CAPITAL LETTER D WITH CARON +.char \[d<] \[u010F] \" LATIN SMALL LETTER D WITH CARON +.char \[D/] \[u0110] \" LATIN CAPITAL LETTER D WITH STROKE +.char \[d/] \[u0111] \" LATIN SMALL LETTER D WITH STROKE +.char \[E-] \[u0112] \" LATIN CAPITAL LETTER E WITH MACRON +.char \[e-] \[u0113] \" LATIN SMALL LETTER E WITH MACRON +.char \[E(] \[u0114] \" LATIN CAPITAL LETTER E WITH BREVE +.char \[e(] \[u0115] \" LATIN SMALL LETTER E WITH BREVE +.char \[E.] \[u0116] \" LATIN CAPITAL LETTER E WITH DOT ABOVE +.char \[e.] \[u0117] \" LATIN SMALL LETTER E WITH DOT ABOVE +.char \[E;] \[u0118] \" LATIN CAPITAL LETTER E WITH OGONEK +.char \[e;] \[u0119] \" LATIN SMALL LETTER E WITH OGONEK +.char \[E<] \[u011A] \" LATIN CAPITAL LETTER E WITH CARON +.char \[e<] \[u011B] \" LATIN SMALL LETTER E WITH CARON +.char \[G>] \[u011C] \" LATIN CAPITAL LETTER G WITH CIRCUMFLEX +.char \[g>] \[u011D] \" LATIN SMALL LETTER G WITH CIRCUMFLEX +.char \[G(] \[u011E] \" LATIN CAPITAL LETTER G WITH BREVE +.char \[g(] \[u011F] \" LATIN SMALL LETTER G WITH BREVE +.char \[G.] \[u0120] \" LATIN CAPITAL LETTER G WITH DOT ABOVE +.char \[g.] \[u0121] \" LATIN SMALL LETTER G WITH DOT ABOVE +.char \[G,] \[u0122] \" LATIN CAPITAL LETTER G WITH CEDILLA +.char \[g,] \[u0123] \" LATIN SMALL LETTER G WITH CEDILLA +.char \[H>] \[u0124] \" LATIN CAPITAL LETTER H WITH CIRCUMFLEX +.char \[h>] \[u0125] \" LATIN SMALL LETTER H WITH CIRCUMFLEX +.char \[H/] \[u0126] \" LATIN CAPITAL LETTER H WITH STROKE +.char \[h/] \[u0127] \" LATIN SMALL LETTER H WITH STROKE +.char \[I?] \[u0128] \" LATIN CAPITAL LETTER I WITH TILDE +.char \[i?] \[u0129] \" LATIN SMALL LETTER I WITH TILDE +.char \[I-] \[u012A] \" LATIN CAPITAL LETTER I WITH MACRON +.char \[i-] \[u012B] \" LATIN SMALL LETTER I WITH MACRON +.char \[I(] \[u012C] \" LATIN CAPITAL LETTER I WITH BREVE +.char \[i(] \[u012D] \" LATIN SMALL LETTER I WITH BREVE +.char \[I;] \[u012E] \" LATIN CAPITAL LETTER I WITH OGONEK +.char \[i;] \[u012F] \" LATIN SMALL LETTER I WITH OGONEK +.char \[I.] \[u0130] \" LATIN CAPITAL LETTER I WITH DOT ABOVE +.char \[i.] \[u0131] \" LATIN SMALL LETTER I DOTLESS +.char \[IJ] \[u0132] \" LATIN CAPITAL LIGATURE IJ +.char \[ij] \[u0133] \" LATIN SMALL LIGATURE IJ +.char \[J>] \[u0134] \" LATIN CAPITAL LETTER J WITH CIRCUMFLEX +.char \[j>] \[u0135] \" LATIN SMALL LETTER J WITH CIRCUMFLEX +.char \[K,] \[u0136] \" LATIN CAPITAL LETTER K WITH CEDILLA +.char \[k,] \[u0137] \" LATIN SMALL LETTER K WITH CEDILLA +.char \[kk] \[u0138] \" LATIN SMALL LETTER KRA (Greenlandic) +.char \[L'] \[u0139] \" LATIN CAPITAL LETTER L WITH ACUTE +.char \[l'] \[u013A] \" LATIN SMALL LETTER L WITH ACUTE +.char \[L,] \[u013B] \" LATIN CAPITAL LETTER L WITH CEDILLA +.char \[l,] \[u013C] \" LATIN SMALL LETTER L WITH CEDILLA +.char \[L<] \[u013D] \" LATIN CAPITAL LETTER L WITH CARON +.char \[l<] \[u013E] \" LATIN SMALL LETTER L WITH CARON +.char \[L.] \[u013F] \" LATIN CAPITAL LETTER L WITH MIDDLE DOT +.char \[l.] \[u0140] \" LATIN SMALL LETTER L WITH MIDDLE DOT +.char \[L/] \[u0141] \" LATIN CAPITAL LETTER L WITH STROKE +.char \[l/] \[u0142] \" LATIN SMALL LETTER L WITH STROKE +.char \[N'] \[u0143] \" LATIN CAPITAL LETTER N WITH ACUTE +.char \[n'] \[u0144] \" LATIN SMALL LETTER N WITH ACUTE +.char \[N,] \[u0145] \" LATIN CAPITAL LETTER N WITH CEDILLA +.char \[n,] \[u0146] \" LATIN SMALL LETTER N WITH CEDILLA +.char \[N<] \[u0147] \" LATIN CAPITAL LETTER N WITH CARON +.char \[n<] \[u0148] \" LATIN SMALL LETTER N WITH CARON +.char \['n] \[u0149] \" LATIN SMALL LETTER N PRECEDED BY APOSTROPHE +.char \[NG] \[u014A] \" LATIN CAPITAL LETTER ENG (Lappish) +.char \[ng] \[u014B] \" LATIN SMALL LETTER ENG (Lappish) +.char \[O-] \[u014C] \" LATIN CAPITAL LETTER O WITH MACRON +.char \[o-] \[u014D] \" LATIN SMALL LETTER O WITH MACRON +.char \[O(] \[u014E] \" LATIN CAPITAL LETTER O WITH BREVE +.char \[o(] \[u014F] \" LATIN SMALL LETTER O WITH BREVE +.char \[O"] \[u0150] \" LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +.char \[o"] \[u0151] \" LATIN SMALL LETTER O WITH DOUBLE ACUTE +.char \[OE] \[u0152] \" LATIN CAPITAL LIGATURE OE +.char \[oe] \[u0153] \" LATIN SMALL LIGATURE OE +.char \[R'] \[u0154] \" LATIN CAPITAL LETTER R WITH ACUTE +.char \[r'] \[u0155] \" LATIN SMALL LETTER R WITH ACUTE +.char \[R,] \[u0156] \" LATIN CAPITAL LETTER R WITH CEDILLA +.char \[r,] \[u0157] \" LATIN SMALL LETTER R WITH CEDILLA +.char \[R<] \[u0158] \" LATIN CAPITAL LETTER R WITH CARON +.char \[r<] \[u0159] \" LATIN SMALL LETTER R WITH CARON +.char \[S'] \[u015A] \" LATIN CAPITAL LETTER S WITH ACUTE +.char \[s'] \[u015B] \" LATIN SMALL LETTER S WITH ACUTE +.char \[S>] \[u015C] \" LATIN CAPITAL LETTER S WITH CIRCUMFLEX +.char \[s>] \[u015D] \" LATIN SMALL LETTER S WITH CIRCUMFLEX +.char \[S,] \[u015E] \" LATIN CAPITAL LETTER S WITH CEDILLA +.char \[s,] \[u015F] \" LATIN SMALL LETTER S WITH CEDILLA +.char \[S<] \[u0160] \" LATIN CAPITAL LETTER S WITH CARON +.char \[s<] \[u0161] \" LATIN SMALL LETTER S WITH CARON +.char \[T,] \[u0162] \" LATIN CAPITAL LETTER T WITH CEDILLA +.char \[t,] \[u0163] \" LATIN SMALL LETTER T WITH CEDILLA +.char \[T<] \[u0164] \" LATIN CAPITAL LETTER T WITH CARON +.char \[t<] \[u0165] \" LATIN SMALL LETTER T WITH CARON +.char \[T/] \[u0166] \" LATIN CAPITAL LETTER T WITH STROKE +.char \[t/] \[u0167] \" LATIN SMALL LETTER T WITH STROKE +.char \[U?] \[u0168] \" LATIN CAPITAL LETTER U WITH TILDE +.char \[u?] \[u0169] \" LATIN SMALL LETTER U WITH TILDE +.char \[U-] \[u016A] \" LATIN CAPITAL LETTER U WITH MACRON +.char \[u-] \[u016B] \" LATIN SMALL LETTER U WITH MACRON +.char \[U(] \[u016C] \" LATIN CAPITAL LETTER U WITH BREVE +.char \[u(] \[u016D] \" LATIN SMALL LETTER U WITH BREVE +.char \[U0] \[u016E] \" LATIN CAPITAL LETTER U WITH RING ABOVE +.char \[u0] \[u016F] \" LATIN SMALL LETTER U WITH RING ABOVE +.char \[U"] \[u0170] \" LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +.char \[u"] \[u0171] \" LATIN SMALL LETTER U WITH DOUBLE ACUTE +.char \[U;] \[u0172] \" LATIN CAPITAL LETTER U WITH OGONEK +.char \[u;] \[u0173] \" LATIN SMALL LETTER U WITH OGONEK +.char \[W>] \[u0174] \" LATIN CAPITAL LETTER W WITH CIRCUMFLEX +.char \[w>] \[u0175] \" LATIN SMALL LETTER W WITH CIRCUMFLEX +.char \[Y>] \[u0176] \" LATIN CAPITAL LETTER Y WITH CIRCUMFLEX +.char \[y>] \[u0177] \" LATIN SMALL LETTER Y WITH CIRCUMFLEX +.char \[Y:] \[u0178] \" LATIN CAPITAL LETTER Y WITH DIAERESIS +.char \[Z'] \[u0179] \" LATIN CAPITAL LETTER Z WITH ACUTE +.char \[z'] \[u017A] \" LATIN SMALL LETTER Z WITH ACUTE +.char \[Z.] \[u017B] \" LATIN CAPITAL LETTER Z WITH DOT ABOVE +.char \[z.] \[u017C] \" LATIN SMALL LETTER Z WITH DOT ABOVE +.char \[Z<] \[u017D] \" LATIN CAPITAL LETTER Z WITH CARON +.char \[z<] \[u017E] \" LATIN SMALL LETTER Z WITH CARON +.char \[O9] \[u01A0] \" LATIN CAPITAL LETTER O WITH HORN +.char \[o9] \[u01A1] \" LATIN SMALL LETTER O WITH HORN +.char \[OI] \[u01A2] \" LATIN CAPITAL LETTER OI +.char \[oi] \[u01A3] \" LATIN SMALL LETTER OI +.char \[yr] \[u01A6] \" LATIN LETTER YR +.char \[U9] \[u01AF] \" LATIN CAPITAL LETTER U WITH HORN +.char \[u9] \[u01B0] \" LATIN SMALL LETTER U WITH HORN +.char \[Z/] \[u01B5] \" LATIN CAPITAL LETTER Z WITH STROKE +.char \[z/] \[u01B6] \" LATIN SMALL LETTER Z WITH STROKE +.char \[ED] \[u01B7] \" LATIN CAPITAL LETTER EZH +.char \[A<] \[u01CD] \" LATIN CAPITAL LETTER A WITH CARON +.char \[a<] \[u01CE] \" LATIN SMALL LETTER A WITH CARON +.char \[I<] \[u01CF] \" LATIN CAPITAL LETTER I WITH CARON +.char \[i<] \[u01D0] \" LATIN SMALL LETTER I WITH CARON +.char \[O<] \[u01D1] \" LATIN CAPITAL LETTER O WITH CARON +.char \[o<] \[u01D2] \" LATIN SMALL LETTER O WITH CARON +.char \[U<] \[u01D3] \" LATIN CAPITAL LETTER U WITH CARON +.char \[u<] \[u01D4] \" LATIN SMALL LETTER U WITH CARON +.char \[U:-] \[u01D5] \" LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON +.char \[u:-] \[u01D6] \" LATIN SMALL LETTER U WITH DIAERESIS AND MACRON +.char \[U:'] \[u01D7] \" LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE +.char \[u:'] \[u01D8] \" LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE +.char \[U:<] \[u01D9] \" LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON +.char \[u:<] \[u01DA] \" LATIN SMALL LETTER U WITH DIAERESIS AND CARON +.char \[U:!] \[u01DB] \" LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE +.char \[u:!] \[u01DC] \" LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE +.char \[A1] \[u01DE] \" LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON +.char \[a1] \[u01DF] \" LATIN SMALL LETTER A WITH DIAERESIS AND MACRON +.char \[A7] \[u01E0] \" LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON +.char \[a7] \[u01E1] \" LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON +.char \[A3] \[u01E2] \" LATIN CAPITAL LETTER AE WITH MACRON +.char \[a3] \[u01E3] \" LATIN SMALL LETTER AE WITH MACRON +.char \[G/] \[u01E4] \" LATIN CAPITAL LETTER G WITH STROKE +.char \[g/] \[u01E5] \" LATIN SMALL LETTER G WITH STROKE +.char \[G<] \[u01E6] \" LATIN CAPITAL LETTER G WITH CARON +.char \[g<] \[u01E7] \" LATIN SMALL LETTER G WITH CARON +.char \[K<] \[u01E8] \" LATIN CAPITAL LETTER K WITH CARON +.char \[k<] \[u01E9] \" LATIN SMALL LETTER K WITH CARON +.char \[O;] \[u01EA] \" LATIN CAPITAL LETTER O WITH OGONEK +.char \[o;] \[u01EB] \" LATIN SMALL LETTER O WITH OGONEK +.char \[O1] \[u01EC] \" LATIN CAPITAL LETTER O WITH OGONEK AND MACRON +.char \[o1] \[u01ED] \" LATIN SMALL LETTER O WITH OGONEK AND MACRON +.char \[EZ] \[u01EE] \" LATIN CAPITAL LETTER EZH WITH CARON +.char \[ez] \[u01EF] \" LATIN SMALL LETTER EZH WITH CARON +.char \[j<] \[u01F0] \" LATIN SMALL LETTER J WITH CARON +.char \[G'] \[u01F4] \" LATIN CAPITAL LETTER G WITH ACUTE +.char \[g'] \[u01F5] \" LATIN SMALL LETTER G WITH ACUTE +.char \[AA'] \[u01FA] \" LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE +.char \[aa'] \[u01FB] \" LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE +.char \[AE'] \[u01FC] \" LATIN CAPITAL LETTER AE WITH ACUTE +.char \[ae'] \[u01FD] \" LATIN SMALL LETTER AE WITH ACUTE +.char \[O/'] \[u01FE] \" LATIN CAPITAL LETTER O WITH STROKE AND ACUTE +.char \[o/'] \[u01FF] \" LATIN SMALL LETTER O WITH STROKE AND ACUTE +.char \[;S] \[u02BF] \" MODIFIER LETTER LEFT HALF RING +.char \['<] \[u02C7] \" CARON +.char \['(] \[u02D8] \" BREVE +.char \['.] \[u02D9] \" DOT ABOVE +.char \['0] \[u02DA] \" RING ABOVE +.char \[';] \[u02DB] \" OGONEK +.char \['"] \[u02DD] \" DOUBLE ACUTE ACCENT +.char \[A%] \[u0386] \" GREEK CAPITAL LETTER ALPHA WITH ACUTE +.char \[E%] \[u0388] \" GREEK CAPITAL LETTER EPSILON WITH ACUTE +.char \[Y%] \[u0389] \" GREEK CAPITAL LETTER ETA WITH ACUTE +.char \[I%] \[u038A] \" GREEK CAPITAL LETTER IOTA WITH ACUTE +.char \[O%] \[u038C] \" GREEK CAPITAL LETTER OMICRON WITH ACUTE +.char \[U%] \[u038E] \" GREEK CAPITAL LETTER UPSILON WITH ACUTE +.char \[W%] \[u038F] \" GREEK CAPITAL LETTER OMEGA WITH ACUTE +.char \[i3] \[u0390] \" GREEK SMALL LETTER IOTA WITH ACUTE AND DIAERESIS +.char \[A*] \[u0391] \" GREEK CAPITAL LETTER ALPHA +.char \[B*] \[u0392] \" GREEK CAPITAL LETTER BETA +.char \[G*] \[u0393] \" GREEK CAPITAL LETTER GAMMA +.char \[D*] \[u0394] \" GREEK CAPITAL LETTER DELTA +.char \[E*] \[u0395] \" GREEK CAPITAL LETTER EPSILON +.char \[Z*] \[u0396] \" GREEK CAPITAL LETTER ZETA +.char \[Y*] \[u0397] \" GREEK CAPITAL LETTER ETA +.char \[H*] \[u0398] \" GREEK CAPITAL LETTER THETA +.char \[I*] \[u0399] \" GREEK CAPITAL LETTER IOTA +.char \[K*] \[u039A] \" GREEK CAPITAL LETTER KAPPA +.char \[L*] \[u039B] \" GREEK CAPITAL LETTER LAMDA +.char \[M*] \[u039C] \" GREEK CAPITAL LETTER MU +.char \[N*] \[u039D] \" GREEK CAPITAL LETTER NU +.char \[C*] \[u039E] \" GREEK CAPITAL LETTER XI +.char \[O*] \[u039F] \" GREEK CAPITAL LETTER OMICRON +.char \[P*] \[u03A0] \" GREEK CAPITAL LETTER PI +.char \[R*] \[u03A1] \" GREEK CAPITAL LETTER RHO +.char \[S*] \[u03A3] \" GREEK CAPITAL LETTER SIGMA +.char \[T*] \[u03A4] \" GREEK CAPITAL LETTER TAU +.char \[U*] \[u03A5] \" GREEK CAPITAL LETTER UPSILON +.char \[F*] \[u03A6] \" GREEK CAPITAL LETTER PHI +.char \[X*] \[u03A7] \" GREEK CAPITAL LETTER CHI +.char \[Q*] \[u03A8] \" GREEK CAPITAL LETTER PSI +.char \[W*] \[u03A9] \" GREEK CAPITAL LETTER OMEGA +.char \[J*] \[u03AA] \" GREEK CAPITAL LETTER IOTA WITH DIAERESIS +.char \[V*] \[u03AB] \" GREEK CAPITAL LETTER UPSILON WITH DIAERESIS +.char \[a%] \[u03AC] \" GREEK SMALL LETTER ALPHA WITH ACUTE +.char \[e%] \[u03AD] \" GREEK SMALL LETTER EPSILON WITH ACUTE +.char \[y%] \[u03AE] \" GREEK SMALL LETTER ETA WITH ACUTE +.char \[i%] \[u03AF] \" GREEK SMALL LETTER IOTA WITH ACUTE +.char \[u3] \[u03B0] \" GREEK SMALL LETTER UPSILON WITH ACUTE AND DIAERESIS +.char \[a*] \[u03B1] \" GREEK SMALL LETTER ALPHA +.char \[b*] \[u03B2] \" GREEK SMALL LETTER BETA +.char \[g*] \[u03B3] \" GREEK SMALL LETTER GAMMA +.char \[d*] \[u03B4] \" GREEK SMALL LETTER DELTA +.char \[e*] \[u03B5] \" GREEK SMALL LETTER EPSILON +.char \[z*] \[u03B6] \" GREEK SMALL LETTER ZETA +.char \[y*] \[u03B7] \" GREEK SMALL LETTER ETA +.char \[h*] \[u03B8] \" GREEK SMALL LETTER THETA +.char \[i*] \[u03B9] \" GREEK SMALL LETTER IOTA +.char \[k*] \[u03BA] \" GREEK SMALL LETTER KAPPA +.char \[l*] \[u03BB] \" GREEK SMALL LETTER LAMDA +.char \[m*] \[u03BC] \" GREEK SMALL LETTER MU +.char \[n*] \[u03BD] \" GREEK SMALL LETTER NU +.char \[c*] \[u03BE] \" GREEK SMALL LETTER XI +.char \[o*] \[u03BF] \" GREEK SMALL LETTER OMICRON +.char \[p*] \[u03C0] \" GREEK SMALL LETTER PI +.char \[r*] \[u03C1] \" GREEK SMALL LETTER RHO +.char \[*s] \[u03C2] \" GREEK SMALL LETTER FINAL SIGMA +.char \[s*] \[u03C3] \" GREEK SMALL LETTER SIGMA +.char \[t*] \[u03C4] \" GREEK SMALL LETTER TAU +.char \[u*] \[u03C5] \" GREEK SMALL LETTER UPSILON +.char \[f*] \[u03C6] \" GREEK SMALL LETTER PHI +.char \[x*] \[u03C7] \" GREEK SMALL LETTER CHI +.char \[q*] \[u03C8] \" GREEK SMALL LETTER PSI +.char \[w*] \[u03C9] \" GREEK SMALL LETTER OMEGA +.char \[j*] \[u03CA] \" GREEK SMALL LETTER IOTA WITH DIAERESIS +.char \[v*] \[u03CB] \" GREEK SMALL LETTER UPSILON WITH DIAERESIS +.char \[o%] \[u03CC] \" GREEK SMALL LETTER OMICRON WITH ACUTE +.char \[u%] \[u03CD] \" GREEK SMALL LETTER UPSILON WITH ACUTE +.char \[w%] \[u03CE] \" GREEK SMALL LETTER OMEGA WITH ACUTE +.char \['G] \[u03D8] \" GREEK NUMERAL SIGN +.char \[,G] \[u03D9] \" GREEK LOWER NUMERAL SIGN +.char \[T3] \[u03DA] \" GREEK CAPITAL LETTER STIGMA +.char \[t3] \[u03DB] \" GREEK SMALL LETTER STIGMA +.char \[M3] \[u03DC] \" GREEK CAPITAL LETTER DIGAMMA +.char \[m3] \[u03DD] \" GREEK SMALL LETTER DIGAMMA +.char \[K3] \[u03DE] \" GREEK CAPITAL LETTER KOPPA +.char \[k3] \[u03DF] \" GREEK SMALL LETTER KOPPA +.char \[P3] \[u03E0] \" GREEK CAPITAL LETTER SAMPI +.char \[p3] \[u03E1] \" GREEK SMALL LETTER SAMPI +.char \['%] \[u03F4] \" ACUTE ACCENT AND DIAERESIS (Tonos and Dialytika) +.char \[j3] \[u03F5] \" GREEK IOTA BELOW +.char \[IO] \[u0401] \" CYRILLIC CAPITAL LETTER IO +.char \[D%] \[u0402] \" CYRILLIC CAPITAL LETTER DJE (Serbocroatian) +.char \[G%] \[u0403] \" CYRILLIC CAPITAL LETTER GJE (Macedonian) +.char \[IE] \[u0404] \" CYRILLIC CAPITAL LETTER UKRAINIAN IE +.char \[DS] \[u0405] \" CYRILLIC CAPITAL LETTER DZE (Macedonian) +.char \[II] \[u0406] \" CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +.char \[YI] \[u0407] \" CYRILLIC CAPITAL LETTER YI (Ukrainian) +.char \[J%] \[u0408] \" CYRILLIC CAPITAL LETTER JE +.char \[LJ] \[u0409] \" CYRILLIC CAPITAL LETTER LJE +.char \[NJ] \[u040A] \" CYRILLIC CAPITAL LETTER NJE +.char \[Ts] \[u040B] \" CYRILLIC CAPITAL LETTER TSHE (Serbocroatian) +.char \[KJ] \[u040C] \" CYRILLIC CAPITAL LETTER KJE (Macedonian) +.char \[V%] \[u040E] \" CYRILLIC CAPITAL LETTER SHORT U (Byelorussian) +.char \[DZ] \[u040F] \" CYRILLIC CAPITAL LETTER DZHE +.char \[A=] \[u0410] \" CYRILLIC CAPITAL LETTER A +.char \[B=] \[u0411] \" CYRILLIC CAPITAL LETTER BE +.char \[V=] \[u0412] \" CYRILLIC CAPITAL LETTER VE +.char \[G=] \[u0413] \" CYRILLIC CAPITAL LETTER GHE +.char \[D=] \[u0414] \" CYRILLIC CAPITAL LETTER DE +.char \[E=] \[u0415] \" CYRILLIC CAPITAL LETTER IE +.char \[Z%] \[u0416] \" CYRILLIC CAPITAL LETTER ZHE +.char \[Z=] \[u0417] \" CYRILLIC CAPITAL LETTER ZE +.char \[I=] \[u0418] \" CYRILLIC CAPITAL LETTER I +.char \[J=] \[u0419] \" CYRILLIC CAPITAL LETTER SHORT I +.char \[K=] \[u041A] \" CYRILLIC CAPITAL LETTER KA +.char \[L=] \[u041B] \" CYRILLIC CAPITAL LETTER EL +.char \[M=] \[u041C] \" CYRILLIC CAPITAL LETTER EM +.char \[N=] \[u041D] \" CYRILLIC CAPITAL LETTER EN +.char \[O=] \[u041E] \" CYRILLIC CAPITAL LETTER O +.char \[P=] \[u041F] \" CYRILLIC CAPITAL LETTER PE +.char \[R=] \[u0420] \" CYRILLIC CAPITAL LETTER ER +.char \[S=] \[u0421] \" CYRILLIC CAPITAL LETTER ES +.char \[T=] \[u0422] \" CYRILLIC CAPITAL LETTER TE +.char \[U=] \[u0423] \" CYRILLIC CAPITAL LETTER U +.char \[F=] \[u0424] \" CYRILLIC CAPITAL LETTER EF +.char \[H=] \[u0425] \" CYRILLIC CAPITAL LETTER HA +.char \[C=] \[u0426] \" CYRILLIC CAPITAL LETTER TSE +.char \[C%] \[u0427] \" CYRILLIC CAPITAL LETTER CHE +.char \[S%] \[u0428] \" CYRILLIC CAPITAL LETTER SHA +.char \[Sc] \[u0429] \" CYRILLIC CAPITAL LETTER SHCHA +.char \[="] \[u042A] \" CYRILLIC CAPITAL LETTER HARD SIGN +.char \[Y=] \[u042B] \" CYRILLIC CAPITAL LETTER YERU +.char \[%"] \[u042C] \" CYRILLIC CAPITAL LETTER SOFT SIGN +.char \[JE] \[u042D] \" CYRILLIC CAPITAL LETTER E +.char \[JU] \[u042E] \" CYRILLIC CAPITAL LETTER YU +.char \[JA] \[u042F] \" CYRILLIC CAPITAL LETTER YA +.char \[a=] \[u0430] \" CYRILLIC SMALL LETTER A +.char \[b=] \[u0431] \" CYRILLIC SMALL LETTER BE +.char \[v=] \[u0432] \" CYRILLIC SMALL LETTER VE +.char \[g=] \[u0433] \" CYRILLIC SMALL LETTER GHE +.char \[d=] \[u0434] \" CYRILLIC SMALL LETTER DE +.char \[e=] \[u0435] \" CYRILLIC SMALL LETTER IE +.char \[z%] \[u0436] \" CYRILLIC SMALL LETTER ZHE +.char \[z=] \[u0437] \" CYRILLIC SMALL LETTER ZE +.char \[i=] \[u0438] \" CYRILLIC SMALL LETTER I +.char \[j=] \[u0439] \" CYRILLIC SMALL LETTER SHORT I +.char \[k=] \[u043A] \" CYRILLIC SMALL LETTER KA +.char \[l=] \[u043B] \" CYRILLIC SMALL LETTER EL +.char \[m=] \[u043C] \" CYRILLIC SMALL LETTER EM +.char \[n=] \[u043D] \" CYRILLIC SMALL LETTER EN +.char \[o=] \[u043E] \" CYRILLIC SMALL LETTER O +.char \[p=] \[u043F] \" CYRILLIC SMALL LETTER PE +.char \[r=] \[u0440] \" CYRILLIC SMALL LETTER ER +.char \[s=] \[u0441] \" CYRILLIC SMALL LETTER ES +.char \[t=] \[u0442] \" CYRILLIC SMALL LETTER TE +.char \[u=] \[u0443] \" CYRILLIC SMALL LETTER U +.char \[f=] \[u0444] \" CYRILLIC SMALL LETTER EF +.char \[h=] \[u0445] \" CYRILLIC SMALL LETTER HA +.char \[c=] \[u0446] \" CYRILLIC SMALL LETTER TSE +.char \[c%] \[u0447] \" CYRILLIC SMALL LETTER CHE +.char \[s%] \[u0448] \" CYRILLIC SMALL LETTER SHA +.char \[sc] \[u0449] \" CYRILLIC SMALL LETTER SHCHA +.char \[='] \[u044A] \" CYRILLIC SMALL LETTER HARD SIGN +.char \[y=] \[u044B] \" CYRILLIC SMALL LETTER YERU +.char \[%'] \[u044C] \" CYRILLIC SMALL LETTER SOFT SIGN +.char \[je] \[u044D] \" CYRILLIC SMALL LETTER E +.char \[ju] \[u044E] \" CYRILLIC SMALL LETTER YU +.char \[ja] \[u044F] \" CYRILLIC SMALL LETTER YA +.char \[io] \[u0451] \" CYRILLIC SMALL LETTER IO +.char \[d%] \[u0452] \" CYRILLIC SMALL LETTER DJE (Serbocroatian) +.char \[g%] \[u0453] \" CYRILLIC SMALL LETTER GJE (Macedonian) +.char \[ie] \[u0454] \" CYRILLIC SMALL LETTER UKRAINIAN IE +.char \[ds] \[u0455] \" CYRILLIC SMALL LETTER DZE (Macedonian) +.char \[ii] \[u0456] \" CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I +.char \[yi] \[u0457] \" CYRILLIC SMALL LETTER YI (Ukrainian) +.char \[j%] \[u0458] \" CYRILLIC SMALL LETTER JE +.char \[lj] \[u0459] \" CYRILLIC SMALL LETTER LJE +.char \[nj] \[u045A] \" CYRILLIC SMALL LETTER NJE +.char \[ts] \[u045B] \" CYRILLIC SMALL LETTER TSHE (Serbocroatian) +.char \[kj] \[u045C] \" CYRILLIC SMALL LETTER KJE (Macedonian) +.char \[v%] \[u045E] \" CYRILLIC SMALL LETTER SHORT U (Byelorussian) +.char \[dz] \[u045F] \" CYRILLIC SMALL LETTER DZHE +.char \[Y3] \[u0462] \" CYRILLIC CAPITAL LETTER YAT +.char \[y3] \[u0463] \" CYRILLIC SMALL LETTER YAT +.char \[O3] \[u046A] \" CYRILLIC CAPITAL LETTER BIG YUS +.char \[o3] \[u046B] \" CYRILLIC SMALL LETTER BIG YUS +.char \[F3] \[u0472] \" CYRILLIC CAPITAL LETTER FITA +.char \[f3] \[u0473] \" CYRILLIC SMALL LETTER FITA +.char \[V3] \[u0474] \" CYRILLIC CAPITAL LETTER IZHITSA +.char \[v3] \[u0475] \" CYRILLIC SMALL LETTER IZHITSA +.char \[C3] \[u0480] \" CYRILLIC CAPITAL LETTER KOPPA +.char \[c3] \[u0481] \" CYRILLIC SMALL LETTER KOPPA +.char \[G3] \[u0490] \" CYRILLIC CAPITAL LETTER GHE WITH UPTURN +.char \[g3] \[u0491] \" CYRILLIC SMALL LETTER GHE WITH UPTURN +.char \[A+] \[u05D0] \" HEBREW LETTER ALEF +.char \[B+] \[u05D1] \" HEBREW LETTER BET +.char \[G+] \[u05D2] \" HEBREW LETTER GIMEL +.char \[D+] \[u05D3] \" HEBREW LETTER DALET +.char \[H+] \[u05D4] \" HEBREW LETTER HE +.char \[W+] \[u05D5] \" HEBREW LETTER VAV +.char \[Z+] \[u05D6] \" HEBREW LETTER ZAYIN +.char \[X+] \[u05D7] \" HEBREW LETTER HET +.char \[Tj] \[u05D8] \" HEBREW LETTER TET +.char \[J+] \[u05D9] \" HEBREW LETTER YOD +.char \[K%] \[u05DA] \" HEBREW LETTER FINAL KAF +.char \[K+] \[u05DB] \" HEBREW LETTER KAF +.char \[L+] \[u05DC] \" HEBREW LETTER LAMED +.char \[M%] \[u05DD] \" HEBREW LETTER FINAL MEM +.char \[M+] \[u05DE] \" HEBREW LETTER MEM +.char \[N%] \[u05DF] \" HEBREW LETTER FINAL NUN +.char \[N+] \[u05E0] \" HEBREW LETTER NUN +.char \[S+] \[u05E1] \" HEBREW LETTER SAMEKH +.char \[E+] \[u05E2] \" HEBREW LETTER AYIN +.char \[P%] \[u05E3] \" HEBREW LETTER FINAL PE +.char \[P+] \[u05E4] \" HEBREW LETTER PE +.char \[Zj] \[u05E5] \" HEBREW LETTER FINAL TSADI +.char \[ZJ] \[u05E6] \" HEBREW LETTER TSADI +.char \[Q+] \[u05E7] \" HEBREW LETTER QOF +.char \[R+] \[u05E8] \" HEBREW LETTER RESH +.char \[Sh] \[u05E9] \" HEBREW LETTER SHIN +.char \[T+] \[u05EA] \" HEBREW LETTER TAV +.char \[,+] \[u060C] \" ARABIC COMMA +.char \[;+] \[u061B] \" ARABIC SEMICOLON +.char \[?+] \[u061F] \" ARABIC QUESTION MARK +.char \[H'] \[u0621] \" ARABIC LETTER HAMZA +.char \[aM] \[u0622] \" ARABIC LETTER ALEF WITH MADDA ABOVE +.char \[aH] \[u0623] \" ARABIC LETTER ALEF WITH HAMZA ABOVE +.char \[wH] \[u0624] \" ARABIC LETTER WAW WITH HAMZA ABOVE +.char \[ah] \[u0625] \" ARABIC LETTER ALEF WITH HAMZA BELOW +.char \[yH] \[u0626] \" ARABIC LETTER YEH WITH HAMZA ABOVE +.char \[a+] \[u0627] \" ARABIC LETTER ALEF +.char \[b+] \[u0628] \" ARABIC LETTER BEH +.char \[tm] \[u0629] \" ARABIC LETTER TEH MARBUTA +.char \[t+] \[u062A] \" ARABIC LETTER TEH +.char \[tk] \[u062B] \" ARABIC LETTER THEH +.char \[g+] \[u062C] \" ARABIC LETTER JEEM +.char \[hk] \[u062D] \" ARABIC LETTER HAH +.char \[x+] \[u062E] \" ARABIC LETTER KHAH +.char \[d+] \[u062F] \" ARABIC LETTER DAL +.char \[dk] \[u0630] \" ARABIC LETTER THAL +.char \[r+] \[u0631] \" ARABIC LETTER REH +.char \[z+] \[u0632] \" ARABIC LETTER ZAIN +.char \[s+] \[u0633] \" ARABIC LETTER SEEN +.char \[sn] \[u0634] \" ARABIC LETTER SHEEN +.char \[c+] \[u0635] \" ARABIC LETTER SAD +.char \[dd] \[u0636] \" ARABIC LETTER DAD +.char \[tj] \[u0637] \" ARABIC LETTER TAH +.char \[zH] \[u0638] \" ARABIC LETTER ZAH +.char \[e+] \[u0639] \" ARABIC LETTER AIN +.char \[i+] \[u063A] \" ARABIC LETTER GHAIN +.char \[++] \[u0640] \" ARABIC TATWEEL +.char \[f+] \[u0641] \" ARABIC LETTER FEH +.char \[q+] \[u0642] \" ARABIC LETTER QAF +.char \[k+] \[u0643] \" ARABIC LETTER KAF +.char \[l+] \[u0644] \" ARABIC LETTER LAM +.char \[m+] \[u0645] \" ARABIC LETTER MEEM +.char \[n+] \[u0646] \" ARABIC LETTER NOON +.char \[h+] \[u0647] \" ARABIC LETTER HEH +.char \[w+] \[u0648] \" ARABIC LETTER WAW +.char \[j+] \[u0649] \" ARABIC LETTER ALEF MAKSURA +.char \[y+] \[u064A] \" ARABIC LETTER YEH +.char \[:+] \[u064B] \" ARABIC FATHATAN +.char \["+] \[u064C] \" ARABIC DAMMATAN +.char \[=+] \[u064D] \" ARABIC KASRATAN +.char \[/+] \[u064E] \" ARABIC FATHA +.char \['+] \[u064F] \" ARABIC DAMMA +.char \[1+] \[u0650] \" ARABIC KASRA +.char \[3+] \[u0651] \" ARABIC SHADDA +.char \[0+] \[u0652] \" ARABIC SUKUN +.char \[aS] \[u0670] \" SUPERSCRIPT ARABIC LETTER ALEF +.char \[p+] \[u067E] \" ARABIC LETTER PEH +.char \[v+] \[u06A4] \" ARABIC LETTER VEH +.char \[gf] \[u06AF] \" ARABIC LETTER GAF +.char \[0a] \[u06F0] \" EASTERN ARABIC-INDIC DIGIT ZERO +.char \[1a] \[u06F1] \" EASTERN ARABIC-INDIC DIGIT ONE +.char \[2a] \[u06F2] \" EASTERN ARABIC-INDIC DIGIT TWO +.char \[3a] \[u06F3] \" EASTERN ARABIC-INDIC DIGIT THREE +.char \[4a] \[u06F4] \" EASTERN ARABIC-INDIC DIGIT FOUR +.char \[5a] \[u06F5] \" EASTERN ARABIC-INDIC DIGIT FIVE +.char \[6a] \[u06F6] \" EASTERN ARABIC-INDIC DIGIT SIX +.char \[7a] \[u06F7] \" EASTERN ARABIC-INDIC DIGIT SEVEN +.char \[8a] \[u06F8] \" EASTERN ARABIC-INDIC DIGIT EIGHT +.char \[9a] \[u06F9] \" EASTERN ARABIC-INDIC DIGIT NINE +.char \[A-0] \[u1E00] \" LATIN CAPITAL LETTER A WITH RING BELOW +.char \[a-0] \[u1E01] \" LATIN SMALL LETTER A WITH RING BELOW +.char \[B.] \[u1E02] \" LATIN CAPITAL LETTER B WITH DOT ABOVE +.char \[b.] \[u1E03] \" LATIN SMALL LETTER B WITH DOT ABOVE +.char \[B-.] \[u1E04] \" LATIN CAPITAL LETTER B WITH DOT BELOW +.char \[b-.] \[u1E05] \" LATIN SMALL LETTER B WITH DOT BELOW +.char \[B_] \[u1E06] \" LATIN CAPITAL LETTER B WITH LINE BELOW +.char \[b_] \[u1E07] \" LATIN SMALL LETTER B WITH LINE BELOW +.char \[C,'] \[u1E08] \" LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE +.char \[c,'] \[u1E09] \" LATIN SMALL LETTER C WITH CEDILLA AND ACUTE +.char \[D.] \[u1E0A] \" LATIN CAPITAL LETTER D WITH DOT ABOVE +.char \[d.] \[u1E0B] \" LATIN SMALL LETTER D WITH DOT ABOVE +.char \[D-.] \[u1E0C] \" LATIN CAPITAL LETTER D WITH DOT BELOW +.char \[d-.] \[u1E0D] \" LATIN SMALL LETTER D WITH DOT BELOW +.char \[D_] \[u1E0E] \" LATIN CAPITAL LETTER D WITH LINE BELOW +.char \[d_] \[u1E0F] \" LATIN SMALL LETTER D WITH LINE BELOW +.char \[D,] \[u1E10] \" LATIN CAPITAL LETTER D WITH CEDILLA +.char \[d,] \[u1E11] \" LATIN SMALL LETTER D WITH CEDILLA +.char \[D->] \[u1E12] \" LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW +.char \[d->] \[u1E13] \" LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW +.char \[E-!] \[u1E14] \" LATIN CAPITAL LETTER E WITH MACRON AND GRAVE +.char \[e-!] \[u1E15] \" LATIN SMALL LETTER E WITH MACRON AND GRAVE +.char \[E-'] \[u1E16] \" LATIN CAPITAL LETTER E WITH MACRON AND ACUTE +.char \[e-'] \[u1E17] \" LATIN SMALL LETTER E WITH MACRON AND ACUTE +.char \[E->] \[u1E18] \" LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW +.char \[e->] \[u1E19] \" LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW +.char \[E-?] \[u1E1A] \" LATIN CAPITAL LETTER E WITH TILDE BELOW +.char \[e-?] \[u1E1B] \" LATIN SMALL LETTER E WITH TILDE BELOW +.char \[E,(] \[u1E1C] \" LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE +.char \[e,(] \[u1E1D] \" LATIN SMALL LETTER E WITH CEDILLA AND BREVE +.char \[F.] \[u1E1E] \" LATIN CAPITAL LETTER F WITH DOT ABOVE +.char \[f.] \[u1E1F] \" LATIN SMALL LETTER F WITH DOT ABOVE +.char \[G-] \[u1E20] \" LATIN CAPITAL LETTER G WITH MACRON +.char \[g-] \[u1E21] \" LATIN SMALL LETTER G WITH MACRON +.char \[H.] \[u1E22] \" LATIN CAPITAL LETTER H WITH DOT ABOVE +.char \[h.] \[u1E23] \" LATIN SMALL LETTER H WITH DOT ABOVE +.char \[H-.] \[u1E24] \" LATIN CAPITAL LETTER H WITH DOT BELOW +.char \[h-.] \[u1E25] \" LATIN SMALL LETTER H WITH DOT BELOW +.char \[H:] \[u1E26] \" LATIN CAPITAL LETTER H WITH DIAERESIS +.char \[h:] \[u1E27] \" LATIN SMALL LETTER H WITH DIAERESIS +.char \[H,] \[u1E28] \" LATIN CAPITAL LETTER H WITH CEDILLA +.char \[h,] \[u1E29] \" LATIN SMALL LETTER H WITH CEDILLA +.char \[H-(] \[u1E2A] \" LATIN CAPITAL LETTER H WITH BREVE BELOW +.char \[h-(] \[u1E2B] \" LATIN SMALL LETTER H WITH BREVE BELOW +.char \[I-?] \[u1E2C] \" LATIN CAPITAL LETTER I WITH TILDE BELOW +.char \[i-?] \[u1E2D] \" LATIN SMALL LETTER I WITH TILDE BELOW +.char \[I:'] \[u1E2E] \" LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE +.char \[i:'] \[u1E2F] \" LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE +.char \[K'] \[u1E30] \" LATIN CAPITAL LETTER K WITH ACUTE +.char \[k'] \[u1E31] \" LATIN SMALL LETTER K WITH ACUTE +.char \[K-.] \[u1E32] \" LATIN CAPITAL LETTER K WITH DOT BELOW +.char \[k-.] \[u1E33] \" LATIN SMALL LETTER K WITH DOT BELOW +.char \[K_] \[u1E34] \" LATIN CAPITAL LETTER K WITH LINE BELOW +.char \[k_] \[u1E35] \" LATIN SMALL LETTER K WITH LINE BELOW +.char \[L-.] \[u1E36] \" LATIN CAPITAL LETTER L WITH DOT BELOW +.char \[l-.] \[u1E37] \" LATIN SMALL LETTER L WITH DOT BELOW +.char \[L--.] \[u1E38] \" LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON +.char \[l--.] \[u1E39] \" LATIN SMALL LETTER L WITH DOT BELOW AND MACRON +.char \[L_] \[u1E3A] \" LATIN CAPITAL LETTER L WITH LINE BELOW +.char \[l_] \[u1E3B] \" LATIN SMALL LETTER L WITH LINE BELOW +.char \[L->] \[u1E3C] \" LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW +.char \[l->] \[u1E3D] \" LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW +.char \[M'] \[u1E3E] \" LATIN CAPITAL LETTER M WITH ACUTE +.char \[m'] \[u1E3F] \" LATIN SMALL LETTER M WITH ACUTE +.char \[M.] \[u1E40] \" LATIN CAPITAL LETTER M WITH DOT ABOVE +.char \[m.] \[u1E41] \" LATIN SMALL LETTER M WITH DOT ABOVE +.char \[M-.] \[u1E42] \" LATIN CAPITAL LETTER M WITH DOT BELOW +.char \[m-.] \[u1E43] \" LATIN SMALL LETTER M WITH DOT BELOW +.char \[N.] \[u1E44] \" LATIN CAPITAL LETTER N WITH DOT ABOVE +.char \[n.] \[u1E45] \" LATIN SMALL LETTER N WITH DOT ABOVE +.char \[N-.] \[u1E46] \" LATIN CAPITAL LETTER N WITH DOT BELOW +.char \[n-.] \[u1E47] \" LATIN SMALL LETTER N WITH DOT BELOW +.char \[N_] \[u1E48] \" LATIN CAPITAL LETTER N WITH LINE BELOW +.char \[n_] \[u1E49] \" LATIN SMALL LETTER N WITH LINE BELOW +.char \[N->] \[u1E4A] \" LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW +.char \[N->] \[u1E4B] \" LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW +.char \[O?'] \[u1E4C] \" LATIN CAPITAL LETTER O WITH TILDE AND ACUTE +.char \[o?'] \[u1E4D] \" LATIN SMALL LETTER O WITH TILDE AND ACUTE +.char \[O?:] \[u1E4E] \" LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS +.char \[o?:] \[u1E4F] \" LATIN SMALL LETTER O WITH TILDE AND DIAERESIS +.char \[O-!] \[u1E50] \" LATIN CAPITAL LETTER O WITH MACRON AND GRAVE +.char \[o-!] \[u1E51] \" LATIN SMALL LETTER O WITH MACRON AND GRAVE +.char \[O-'] \[u1E52] \" LATIN CAPITAL LETTER O WITH MACRON AND ACUTE +.char \[o-'] \[u1E53] \" LATIN SMALL LETTER O WITH MACRON AND ACUTE +.char \[P'] \[u1E54] \" LATIN CAPITAL LETTER P WITH ACUTE +.char \[p'] \[u1E55] \" LATIN SMALL LETTER P WITH ACUTE +.char \[P.] \[u1E56] \" LATIN CAPITAL LETTER P WITH DOT ABOVE +.char \[p.] \[u1E57] \" LATIN SMALL LETTER P WITH DOT ABOVE +.char \[R.] \[u1E58] \" LATIN CAPITAL LETTER R WITH DOT ABOVE +.char \[r.] \[u1E59] \" LATIN SMALL LETTER R WITH DOT ABOVE +.char \[R-.] \[u1E5A] \" LATIN CAPITAL LETTER R WITH DOT BELOW +.char \[r-.] \[u1E5B] \" LATIN SMALL LETTER R WITH DOT BELOW +.char \[R--.] \[u1E5C] \" LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON +.char \[r--.] \[u1E5D] \" LATIN SMALL LETTER R WITH DOT BELOW AND MACRON +.char \[R_] \[u1E5E] \" LATIN CAPITAL LETTER R WITH LINE BELOW +.char \[r_] \[u1E5F] \" LATIN SMALL LETTER R WITH LINE BELOW +.char \[S.] \[u1E60] \" LATIN CAPITAL LETTER S WITH DOT ABOVE +.char \[s.] \[u1E61] \" LATIN SMALL LETTER S WITH DOT ABOVE +.char \[S-.] \[u1E62] \" LATIN CAPITAL LETTER S WITH DOT BELOW +.char \[s-.] \[u1E63] \" LATIN SMALL LETTER S WITH DOT BELOW +.char \[S'.] \[u1E64] \" LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE +.char \[s'.] \[u1E65] \" LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE +.char \[S<.] \[u1E66] \" LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE +.char \[s<.] \[u1E67] \" LATIN SMALL LETTER S WITH CARON AND DOT ABOVE +.char \[S.-.] \[u1E68] \" LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE +.char \[S.-.] \[u1E69] \" LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE +.char \[T.] \[u1E6A] \" LATIN CAPITAL LETTER T WITH DOT ABOVE +.char \[t.] \[u1E6B] \" LATIN SMALL LETTER T WITH DOT ABOVE +.char \[T-.] \[u1E6C] \" LATIN CAPITAL LETTER T WITH DOT BELOW +.char \[t-.] \[u1E6D] \" LATIN SMALL LETTER T WITH DOT BELOW +.char \[T_] \[u1E6E] \" LATIN CAPITAL LETTER T WITH LINE BELOW +.char \[t_] \[u1E6F] \" LATIN SMALL LETTER T WITH LINE BELOW +.char \[T->] \[u1E70] \" LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW +.char \[t->] \[u1E71] \" LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW +.char \[U--:] \[u1E72] \" LATIN CAPITAL LETTER U WITH DIAERESIS BELOW +.char \[u--:] \[u1E73] \" LATIN SMALL LETTER U WITH DIAERESIS BELOW +.char \[U-?] \[u1E74] \" LATIN CAPITAL LETTER U WITH TILDE BELOW +.char \[u-?] \[u1E75] \" LATIN SMALL LETTER U WITH TILDE BELOW +.char \[U->] \[u1E76] \" LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW +.char \[u->] \[u1E77] \" LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW +.char \[U?'] \[u1E78] \" LATIN CAPITAL LETTER U WITH TILDE AND ACUTE +.char \[u?'] \[u1E79] \" LATIN SMALL LETTER U WITH TILDE AND ACUTE +.char \[U-:] \[u1E7A] \" LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS +.char \[u-:] \[u1E7B] \" LATIN SMALL LETTER U WITH MACRON AND DIAERESIS +.char \[V?] \[u1E7C] \" LATIN CAPITAL LETTER V WITH TILDE +.char \[v?] \[u1E7D] \" LATIN SMALL LETTER V WITH TILDE +.char \[V-.] \[u1E7E] \" LATIN CAPITAL LETTER V WITH DOT BELOW +.char \[v-.] \[u1E7F] \" LATIN SMALL LETTER V WITH DOT BELOW +.char \[W!] \[u1E80] \" LATIN CAPITAL LETTER W WITH GRAVE +.char \[w!] \[u1E81] \" LATIN SMALL LETTER W WITH GRAVE +.char \[W'] \[u1E82] \" LATIN CAPITAL LETTER W WITH ACUTE +.char \[w'] \[u1E83] \" LATIN SMALL LETTER W WITH ACUTE +.char \[W:] \[u1E84] \" LATIN CAPITAL LETTER W WITH DIAERESIS +.char \[w:] \[u1E85] \" LATIN SMALL LETTER W WITH DIAERESIS +.char \[W.] \[u1E86] \" LATIN CAPITAL LETTER W WITH DOT ABOVE +.char \[w.] \[u1E87] \" LATIN SMALL LETTER W WITH DOT ABOVE +.char \[W-.] \[u1E88] \" LATIN CAPITAL LETTER W WITH DOT BELOW +.char \[w-.] \[u1E89] \" LATIN SMALL LETTER W WITH DOT BELOW +.char \[X.] \[u1E8A] \" LATIN CAPITAL LETTER X WITH DOT ABOVE +.char \[x.] \[u1E8B] \" LATIN SMALL LETTER X WITH DOT ABOVE +.char \[X:] \[u1E8C] \" LATIN CAPITAL LETTER X WITH DIAERESIS +.char \[x:] \[u1E8D] \" LATIN SMALL LETTER X WITH DIAERESIS +.char \[Y.] \[u1E8E] \" LATIN CAPITAL LETTER Y WITH DOT ABOVE +.char \[y.] \[u1E8F] \" LATIN SMALL LETTER Y WITH DOT ABOVE +.char \[Z>] \[u1E90] \" LATIN CAPITAL LETTER Z WITH CIRCUMFLEX +.char \[z>] \[u1E91] \" LATIN SMALL LETTER Z WITH CIRCUMFLEX +.char \[Z-.] \[u1E92] \" LATIN CAPITAL LETTER Z WITH DOT BELOW +.char \[z-.] \[u1E93] \" LATIN SMALL LETTER Z WITH DOT BELOW +.char \[Z_] \[u1E94] \" LATIN CAPITAL LETTER Z WITH LINE BELOW +.char \[z_] \[u1E95] \" LATIN SMALL LETTER Z WITH LINE BELOW +.char \[h_] \[u1E96] \" LATIN SMALL LETTER H WITH LINE BELOW +.char \[t:] \[u1E97] \" LATIN SMALL LETTER T WITH DIAERESIS +.char \[w0] \[u1E98] \" LATIN SMALL LETTER W WITH RING ABOVE +.char \[y0] \[u1E99] \" LATIN SMALL LETTER Y WITH RING ABOVE +.char \[A-.] \[u1EA0] \" LATIN CAPITAL LETTER A WITH DOT BELOW +.char \[a-.] \[u1EA1] \" LATIN SMALL LETTER A WITH DOT BELOW +.char \[A2] \[u1EA2] \" LATIN CAPITAL LETTER A WITH HOOK ABOVE +.char \[a2] \[u1EA3] \" LATIN SMALL LETTER A WITH HOOK ABOVE +.char \[A>'] \[u1EA4] \" LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE +.char \[a>'] \[u1EA5] \" LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE +.char \[A>!] \[u1EA6] \" LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE +.char \[a>!] \[u1EA7] \" LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE +.char \[A>2] \[u1EA8] \" LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE +.char \[a>2] \[u1EA9] \" LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE +.char \[A>?] \[u1EAA] \" LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE +.char \[a>?] \[u1EAB] \" LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE +.char \[A>-.] \[u1EAC] \" LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW +.char \[a>-.] \[u1EAD] \" LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW +.char \[A('] \[u1EAE] \" LATIN CAPITAL LETTER A WITH BREVE AND ACUTE +.char \[a('] \[u1EAF] \" LATIN SMALL LETTER A WITH BREVE AND ACUTE +.char \[A(!] \[u1EB0] \" LATIN CAPITAL LETTER A WITH BREVE AND GRAVE +.char \[a(!] \[u1EB1] \" LATIN SMALL LETTER A WITH BREVE AND GRAVE +.char \[A(2] \[u1EB2] \" LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE +.char \[a(2] \[u1EB3] \" LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE +.char \[A(?] \[u1EB4] \" LATIN CAPITAL LETTER A WITH BREVE AND TILDE +.char \[a(?] \[u1EB5] \" LATIN SMALL LETTER A WITH BREVE AND TILDE +.char \[A(-.] \[u1EB6] \" LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW +.char \[a(-.] \[u1EB7] \" LATIN SMALL LETTER A WITH BREVE AND DOT BELOW +.char \[E-.] \[u1EB8] \" LATIN CAPITAL LETTER E WITH DOT BELOW +.char \[e-.] \[u1EB9] \" LATIN SMALL LETTER E WITH DOT BELOW +.char \[E2] \[u1EBA] \" LATIN CAPITAL LETTER E WITH HOOK ABOVE +.char \[e2] \[u1EBB] \" LATIN SMALL LETTER E WITH HOOK ABOVE +.char \[E?] \[u1EBC] \" LATIN CAPITAL LETTER E WITH TILDE +.char \[e?] \[u1EBD] \" LATIN SMALL LETTER E WITH TILDE +.char \[E>'] \[u1EBE] \" LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE +.char \[e>'] \[u1EBF] \" LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE +.char \[E>!] \[u1EC0] \" LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE +.char \[e>!] \[u1EC1] \" LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE +.char \[E>2] \[u1EC2] \" LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE +.char \[e>2] \[u1EC3] \" LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE +.char \[E>?] \[u1EC4] \" LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE +.char \[e>?] \[u1EC5] \" LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE +.char \[E>-.] \[u1EC6] \" LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW +.char \[e>-.] \[u1EC7] \" LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW +.char \[I2] \[u1EC8] \" LATIN CAPITAL LETTER I WITH HOOK ABOVE +.char \[i2] \[u1EC9] \" LATIN SMALL LETTER I WITH HOOK ABOVE +.char \[I-.] \[u1ECA] \" LATIN CAPITAL LETTER I WITH DOT BELOW +.char \[i-.] \[u1ECB] \" LATIN SMALL LETTER I WITH DOT BELOW +.char \[O-.] \[u1ECC] \" LATIN CAPITAL LETTER O WITH DOT BELOW +.char \[o-.] \[u1ECD] \" LATIN SMALL LETTER O WITH DOT BELOW +.char \[O2] \[u1ECE] \" LATIN CAPITAL LETTER O WITH HOOK ABOVE +.char \[o2] \[u1ECF] \" LATIN SMALL LETTER O WITH HOOK ABOVE +.char \[O>'] \[u1ED0] \" LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE +.char \[o>'] \[u1ED1] \" LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE +.char \[O>!] \[u1ED2] \" LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE +.char \[o>!] \[u1ED3] \" LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE +.char \[O>2] \[u1ED4] \" LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE +.char \[o>2] \[u1ED5] \" LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE +.char \[O>?] \[u1ED6] \" LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE +.char \[o>?] \[u1ED7] \" LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE +.char \[O>-.] \[u1ED8] \" LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW +.char \[o>-.] \[u1ED9] \" LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW +.char \[O9'] \[u1EDA] \" LATIN CAPITAL LETTER O WITH HORN AND ACUTE +.char \[o9'] \[u1EDB] \" LATIN SMALL LETTER O WITH HORN AND ACUTE +.char \[O9!] \[u1EDC] \" LATIN CAPITAL LETTER O WITH HORN AND GRAVE +.char \[o9!] \[u1EDD] \" LATIN SMALL LETTER O WITH HORN AND GRAVE +.char \[O92] \[u1EDE] \" LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE +.char \[o92] \[u1EDF] \" LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE +.char \[O9?] \[u1EE0] \" LATIN CAPITAL LETTER O WITH HORN AND TILDE +.char \[o9?] \[u1EE1] \" LATIN SMALL LETTER O WITH HORN AND TILDE +.char \[O9-.] \[u1EE2] \" LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW +.char \[o9-.] \[u1EE3] \" LATIN SMALL LETTER O WITH HORN AND DOT BELOW +.char \[U-.] \[u1EE4] \" LATIN CAPITAL LETTER U WITH DOT BELOW +.char \[u-.] \[u1EE5] \" LATIN SMALL LETTER U WITH DOT BELOW +.char \[U2] \[u1EE6] \" LATIN CAPITAL LETTER U WITH HOOK ABOVE +.char \[u2] \[u1EE7] \" LATIN SMALL LETTER U WITH HOOK ABOVE +.char \[U9'] \[u1EE8] \" LATIN CAPITAL LETTER U WITH HORN AND ACUTE +.char \[u9'] \[u1EE9] \" LATIN SMALL LETTER U WITH HORN AND ACUTE +.char \[U9!] \[u1EEA] \" LATIN CAPITAL LETTER U WITH HORN AND GRAVE +.char \[u9!] \[u1EEB] \" LATIN SMALL LETTER U WITH HORN AND GRAVE +.char \[U92] \[u1EEC] \" LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE +.char \[u92] \[u1EED] \" LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE +.char \[U9?] \[u1EEE] \" LATIN CAPITAL LETTER U WITH HORN AND TILDE +.char \[u9?] \[u1EEF] \" LATIN SMALL LETTER U WITH HORN AND TILDE +.char \[U9-.] \[u1EF0] \" LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW +.char \[u9-.] \[u1EF1] \" LATIN SMALL LETTER U WITH HORN AND DOT BELOW +.char \[Y!] \[u1EF2] \" LATIN CAPITAL LETTER Y WITH GRAVE +.char \[y!] \[u1EF3] \" LATIN SMALL LETTER Y WITH GRAVE +.char \[Y-.] \[u1EF4] \" LATIN CAPITAL LETTER Y WITH DOT BELOW +.char \[y-.] \[u1EF5] \" LATIN SMALL LETTER Y WITH DOT BELOW +.char \[Y2] \[u1EF6] \" LATIN CAPITAL LETTER Y WITH HOOK ABOVE +.char \[y2] \[u1EF7] \" LATIN SMALL LETTER Y WITH HOOK ABOVE +.char \[Y?] \[u1EF8] \" LATIN CAPITAL LETTER Y WITH TILDE +.char \[y?] \[u1EF9] \" LATIN SMALL LETTER Y WITH TILDE +.char \[;'] \[u1F00] \" GREEK DASIA AND ACUTE ACCENT +.char \[,'] \[u1F01] \" GREEK PSILI AND ACUTE ACCENT +.char \[;!] \[u1F02] \" GREEK DASIA AND VARIA +.char \[,!] \[u1F03] \" GREEK PSILI AND VARIA +.char \[?;] \[u1F04] \" GREEK DASIA AND PERISPOMENI +.char \[?,] \[u1F05] \" GREEK PSILI AND PERISPOMENI +.char \[!:] \[u1F06] \" GREEK DIAERESIS AND VARIA +.char \[?:] \[u1F07] \" GREEK DIAERESIS AND PERISPOMENI +.char \[1N] \[u2002] \" EN SPACE +.char \[1M] \[u2003] \" EM SPACE +.char \[3M] \[u2004] \" THREE-PER-EM SPACE +.char \[4M] \[u2005] \" FOUR-PER-EM SPACE +.char \[6M] \[u2006] \" SIX-PER-EM SPACE +.char \[1T] \[u2009] \" THIN SPACE +.char \[1H] \[u200A] \" HAIR SPACE +.char \[-1] \[u2010] \" HYPHEN +.char \[-N] \[u2013] \" EN DASH +.char \[-M] \[u2014] \" EM DASH +.char \[-3] \[u2015] \" HORIZONTAL BAR +.char \[!2] \[u2016] \" DOUBLE VERTICAL LINE +.char \[=2] \[u2017] \" DOUBLE LOW LINE +.char \['6] \[u2018] \" LEFT SINGLE QUOTATION MARK +.char \['9] \[u2019] \" RIGHT SINGLE QUOTATION MARK +.char \[.9] \[u201A] \" SINGLE LOW-9 QUOTATION MARK +.char \[9'] \[u201B] \" SINGLE HIGH-REVERSED-9 QUOTATION MARK +.char \["6] \[u201C] \" LEFT DOUBLE QUOTATION MARK +.char \["9] \[u201D] \" RIGHT DOUBLE QUOTATION MARK +.char \[:9] \[u201E] \" DOUBLE LOW-9 QUOTATION MARK +.char \[9"] \[u201F] \" DOUBLE HIGH-REVERSED-9 QUOTATION MARK +.char \[/-] \[u2020] \" DAGGER +.char \[/=] \[u2021] \" DOUBLE DAGGER +.char \[..] \[u2025] \" TWO DOT LEADER +.char \[,.] \[u2026] \" HORIZONTAL ELLIPSIS (Vim) +.char \[%0] \[u2030] \" PER MILLE SIGN +.char \[1'] \[u2032] \" PRIME +.char \[2'] \[u2033] \" DOUBLE PRIME +.char \[3'] \[u2034] \" TRIPLE PRIME +.char \[1"] \[u2035] \" REVERSED PRIME +.char \[2"] \[u2036] \" REVERSED DOUBLE PRIME +.char \[3"] \[u2037] \" REVERSED TRIPLE PRIME +.char \[Ca] \[u2038] \" CARET +.char \[<1] \[u2039] \" SINGLE LEFT-POINTING ANGLE QUOTATION MARK +.char \[>1] \[u203A] \" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +.char \[:X] \[u203B] \" REFERENCE MARK +.char \[!*2] \[u203C] \" DOUBLE EXCLAMATION MARK +.char \['-] \[u203E] \" OVERLINE +.char \[/f] \[u2044] \" FRACTION SLASH +.char \[0S] \[u2070] \" SUPERSCRIPT DIGIT ZERO +.char \[4S] \[u2074] \" SUPERSCRIPT DIGIT FOUR +.char \[5S] \[u2075] \" SUPERSCRIPT DIGIT FIVE +.char \[6S] \[u2076] \" SUPERSCRIPT DIGIT SIX +.char \[7S] \[u2077] \" SUPERSCRIPT DIGIT SEVEN +.char \[8S] \[u2078] \" SUPERSCRIPT DIGIT EIGHT +.char \[9S] \[u2079] \" SUPERSCRIPT DIGIT NINE +.char \[+S] \[u207A] \" SUPERSCRIPT PLUS SIGN +.char \[-S] \[u207B] \" SUPERSCRIPT MINUS +.char \[=S] \[u207C] \" SUPERSCRIPT EQUALS SIGN +.char \[(S] \[u207D] \" SUPERSCRIPT LEFT PARENTHESIS +.char \[)S] \[u207E] \" SUPERSCRIPT RIGHT PARENTHESIS +.char \[nS] \[u207F] \" SUPERSCRIPT LATIN SMALL LETTER N +.char \[0s] \[u2080] \" SUBSCRIPT DIGIT ZERO +.char \[1s] \[u2081] \" SUBSCRIPT DIGIT ONE +.char \[2s] \[u2082] \" SUBSCRIPT DIGIT TWO +.char \[3s] \[u2083] \" SUBSCRIPT DIGIT THREE +.char \[4s] \[u2084] \" SUBSCRIPT DIGIT FOUR +.char \[5s] \[u2085] \" SUBSCRIPT DIGIT FIVE +.char \[6s] \[u2086] \" SUBSCRIPT DIGIT SIX +.char \[7s] \[u2087] \" SUBSCRIPT DIGIT SEVEN +.char \[8s] \[u2088] \" SUBSCRIPT DIGIT EIGHT +.char \[9s] \[u2089] \" SUBSCRIPT DIGIT NINE +.char \[+s] \[u208A] \" SUBSCRIPT PLUS SIGN +.char \[-s] \[u208B] \" SUBSCRIPT MINUS +.char \[=s] \[u208C] \" SUBSCRIPT EQUALS SIGN +.char \[(s] \[u208D] \" SUBSCRIPT LEFT PARENTHESIS +.char \[)s] \[u208E] \" SUBSCRIPT RIGHT PARENTHESIS +.char \[Li] \[u20A4] \" LIRA SIGN +.char \[Pt] \[u20A7] \" PESETA SIGN +.char \[W=] \[u20A9] \" WON SIGN +.char \[Eu] \[u20AC] \" EURO SIGN (Vim) +.char \[=R] \[u20BD] \" ROUBLE SIGN (Vim) +.char \[=P] \[u20BD] \" ROUBLE SIGN (Vim) +.char \[oC] \[u2103] \" DEGREE CENTIGRADE +.char \[co] \[u2105] \" CARE OF +.char \[oF] \[u2109] \" DEGREE FAHRENHEIT +.char \[N0] \[u2116] \" NUMERO SIGN +.char \[PO] \[u2117] \" SOUND RECORDING COPYRIGHT +.char \[Rx] \[u211E] \" PRESCRIPTION TAKE +.char \[SM] \[u2120] \" SERVICE MARK +.char \[TM] \[u2122] \" TRADE MARK SIGN +.char \[Om] \[u2126] \" OHM SIGN +.char \[AO] \[u212B] \" ANGSTROEM SIGN +.char \[13] \[u2153] \" VULGAR FRACTION ONE THIRD +.char \[23] \[u2154] \" VULGAR FRACTION TWO THIRDS +.char \[15] \[u2155] \" VULGAR FRACTION ONE FIFTH +.char \[25] \[u2156] \" VULGAR FRACTION TWO FIFTHS +.char \[35] \[u2157] \" VULGAR FRACTION THREE FIFTHS +.char \[45] \[u2158] \" VULGAR FRACTION FOUR FIFTHS +.char \[16] \[u2159] \" VULGAR FRACTION ONE SIXTH +.char \[56] \[u215A] \" VULGAR FRACTION FIVE SIXTHS +.char \[18] \[u215B] \" VULGAR FRACTION ONE EIGHTH +.char \[38] \[u215C] \" VULGAR FRACTION THREE EIGHTHS +.char \[58] \[u215D] \" VULGAR FRACTION FIVE EIGHTHS +.char \[78] \[u215E] \" VULGAR FRACTION SEVEN EIGHTHS +.char \[1R] \[u2160] \" ROMAN NUMERAL ONE +.char \[2R] \[u2161] \" ROMAN NUMERAL TWO +.char \[3R] \[u2162] \" ROMAN NUMERAL THREE +.char \[4R] \[u2163] \" ROMAN NUMERAL FOUR +.char \[5R] \[u2164] \" ROMAN NUMERAL FIVE +.char \[6R] \[u2165] \" ROMAN NUMERAL SIX +.char \[7R] \[u2166] \" ROMAN NUMERAL SEVEN +.char \[8R] \[u2167] \" ROMAN NUMERAL EIGHT +.char \[9R] \[u2168] \" ROMAN NUMERAL NINE +.char \[aR] \[u2169] \" ROMAN NUMERAL TEN +.char \[bR] \[u216A] \" ROMAN NUMERAL ELEVEN +.char \[cR] \[u216B] \" ROMAN NUMERAL TWELVE +.char \[50R] \[u216C] \" ROMAN NUMERAL FIFTY +.char \[100R] \[u216D] \" ROMAN NUMERAL ONE HUNDRED +.char \[500R] \[u216E] \" ROMAN NUMERAL FIVE HUNDRED +.char \[1000R] \[u216F] \" ROMAN NUMERAL ONE THOUSAND +.char \[1r] \[u2170] \" SMALL ROMAN NUMERAL ONE +.char \[2r] \[u2171] \" SMALL ROMAN NUMERAL TWO +.char \[3r] \[u2172] \" SMALL ROMAN NUMERAL THREE +.char \[4r] \[u2173] \" SMALL ROMAN NUMERAL FOUR +.char \[5r] \[u2174] \" SMALL ROMAN NUMERAL FIVE +.char \[6r] \[u2175] \" SMALL ROMAN NUMERAL SIX +.char \[7r] \[u2176] \" SMALL ROMAN NUMERAL SEVEN +.char \[8r] \[u2177] \" SMALL ROMAN NUMERAL EIGHT +.char \[9r] \[u2178] \" SMALL ROMAN NUMERAL NINE +.char \[ar] \[u2179] \" SMALL ROMAN NUMERAL TEN +.char \[br] \[u217A] \" SMALL ROMAN NUMERAL ELEVEN +.char \[cr] \[u217B] \" SMALL ROMAN NUMERAL TWELVE +.char \[50r] \[u217C] \" SMALL ROMAN NUMERAL FIFTY +.char \[100r] \[u217D] \" SMALL ROMAN NUMERAL ONE HUNDRED +.char \[500r] \[u217E] \" SMALL ROMAN NUMERAL FIVE HUNDRED +.char \[1000r] \[u217F] \" SMALL ROMAN NUMERAL ONE THOUSAND +.char \[1000RCD] \[u2180] \" ROMAN NUMERAL ONE THOUSAND C D +.char \[5000R] \[u2181] \" ROMAN NUMERAL FIVE THOUSAND +.char \[10000R] \[u2182] \" ROMAN NUMERAL TEN THOUSAND +.char \[<-] \[u2190] \" LEFTWARDS ARROW +.char \[-!] \[u2191] \" UPWARDS ARROW +.char \[->] \[u2192] \" RIGHTWARDS ARROW +.char \[-v] \[u2193] \" DOWNWARDS ARROW +.char \[<>] \[u2194] \" LEFT RIGHT ARROW +.char \[UD] \[u2195] \" UP DOWN ARROW +.char \[<!!] \[u2196] \" NORTH WEST ARROW +.char \[//>] \[u2197] \" NORTH EAST ARROW +.char \[!!>] \[u2198] \" SOUTH EAST ARROW +.char \[<//] \[u2199] \" SOUTH WEST ARROW +.char \[<=] \[u21D0] \" LEFTWARDS DOUBLE ARROW +.char \[=>] \[u21D2] \" RIGHTWARDS DOUBLE ARROW +.char \[==] \[u21D4] \" LEFT RIGHT DOUBLE ARROW +.char \[FA] \[u2200] \" FOR ALL +.char \[dP] \[u2202] \" PARTIAL DIFFERENTIAL +.char \[TE] \[u2203] \" THERE EXISTS +.char \[/0] \[u2205] \" EMPTY SET +.char \[DE] \[u2206] \" INCREMENT +.char \[NB] \[u2207] \" NABLA +.char \[(-] \[u2208] \" ELEMENT OF +.char \[-)] \[u220B] \" CONTAINS AS MEMBER +.char \[*P] \[u220F] \" N-ARY PRODUCT +.char \[+Z] \[u2211] \" N-ARY SUMMATION +.char \[-2] \[u2212] \" MINUS SIGN +.char \[-+] \[u2213] \" MINUS-OR-PLUS SIGN +.char \[*-] \[u2217] \" ASTERISK OPERATOR +.char \[Ob] \[u2218] \" RING OPERATOR +.char \[Sb] \[u2219] \" BULLET OPERATOR +.char \[RT] \[u221A] \" SQUARE ROOT +.char \[0(] \[u221D] \" PROPORTIONAL TO +.char \[00] \[u221E] \" INFINITY +.char \[-L] \[u221F] \" RIGHT ANGLE +.char \[-V] \[u2220] \" ANGLE +.char \[PP] \[u2225] \" PARALLEL TO +.char \[AN] \[u2227] \" LOGICAL AND +.char \[OR] \[u2228] \" LOGICAL OR +.char \[(U] \[u2229] \" INTERSECTION +.char \[)U] \[u222A] \" UNION +.char \[In] \[u222B] \" INTEGRAL +.char \[DI] \[u222C] \" DOUBLE INTEGRAL +.char \[Io] \[u222E] \" CONTOUR INTEGRAL +.char \[.:] \[u2234] \" THEREFORE +.char \[:.] \[u2235] \" BECAUSE +.char \[:R] \[u2236] \" RATIO +.char \[::] \[u2237] \" PROPORTION +.char \[?1] \[u223C] \" TILDE OPERATOR +.char \[CG] \[u223E] \" INVERTED LAZY S +.char \[?-] \[u2243] \" ASYMPTOTICALLY EQUAL TO +.char \[?=] \[u2245] \" APPROXIMATELY EQUAL TO +.char \[?2] \[u2248] \" ALMOST EQUAL TO +.char \[=?] \[u224C] \" ALL EQUAL TO +.char \[HI] \[u2253] \" IMAGE OF OR APPROXIMATELY EQUAL TO +.char \[!=] \[u2260] \" NOT EQUAL TO +.char \[=3] \[u2261] \" IDENTICAL TO +.char \[=<] \[u2264] \" LESS-THAN OR EQUAL TO +.char \[>=] \[u2265] \" GREATER-THAN OR EQUAL TO +.char \[<*] \[u226A] \" MUCH LESS-THAN +.char \[*>] \[u226B] \" MUCH GREATER-THAN +.char \[!<] \[u226E] \" NOT LESS-THAN +.char \[!>] \[u226F] \" NOT GREATER-THAN +.char \[(C] \[u2282] \" SUBSET OF +.char \[)C] \[u2283] \" SUPERSET OF +.char \[(_] \[u2286] \" SUBSET OF OR EQUAL TO +.char \[)_] \[u2287] \" SUPERSET OF OR EQUAL TO +.char \[0.] \[u2299] \" CIRCLED DOT OPERATOR +.char \[02] \[u229A] \" CIRCLED RING OPERATOR +.char \[-T] \[u22A5] \" UP TACK +.char \[.P] \[u22C5] \" DOT OPERATOR +.char \[:3] \[u22EE] \" VERTICAL ELLIPSIS +.char \[.3] \[u22EF] \" MIDLINE HORIZONTAL ELLIPSIS +.char \[Eh] \[u2302] \" HOUSE +.char \[<7] \[u2308] \" LEFT CEILING +.char \[>7] \[u2309] \" RIGHT CEILING +.char \[7<] \[u230A] \" LEFT FLOOR +.char \[7>] \[u230B] \" RIGHT FLOOR +.char \[NI] \[u2310] \" REVERSED NOT SIGN +.char \[(A] \[u2312] \" ARC +.char \[TR] \[u2315] \" TELEPHONE RECORDER +.char \[Iu] \[u2320] \" TOP HALF INTEGRAL +.char \[Il] \[u2321] \" BOTTOM HALF INTEGRAL +.char \[</] \[u2329] \" LEFT-POINTING ANGLE BRACKET +.char \[/>] \[u232A] \" RIGHT-POINTING ANGLE BRACKET +.char \[Vs] \[u2423] \" OPEN BOX +.char \[1h] \[u2440] \" OCR HOOK +.char \[3h] \[u2441] \" OCR CHAIR +.char \[2h] \[u2442] \" OCR FORK +.char \[4h] \[u2443] \" OCR INVERTED FORK +.char \[1j] \[u2446] \" OCR BRANCH BANK IDENTIFICATION +.char \[2j] \[u2447] \" OCR AMOUNT OF CHECK +.char \[3j] \[u2448] \" OCR DASH +.char \[4j] \[u2449] \" OCR CUSTOMER ACCOUNT NUMBER +.char \[1-o] \[u2460] \" CIRCLED DIGIT ONE +.char \[2-o] \[u2461] \" CIRCLED DIGIT TWO +.char \[3-o] \[u2462] \" CIRCLED DIGIT THREE +.char \[4-o] \[u2463] \" CIRCLED DIGIT FOUR +.char \[5-o] \[u2464] \" CIRCLED DIGIT FIVE +.char \[6-o] \[u2465] \" CIRCLED DIGIT SIX +.char \[7-o] \[u2466] \" CIRCLED DIGIT SEVEN +.char \[8-o] \[u2467] \" CIRCLED DIGIT EIGHT +.char \[9-o] \[u2468] \" CIRCLED DIGIT NINE +.char \[10-o] \[u2469] \" CIRCLED NUMBER TEN +.char \[11-o] \[u246A] \" CIRCLED NUMBER ELEVEN +.char \[12-o] \[u246B] \" CIRCLED NUMBER TWELVE +.char \[13-o] \[u246C] \" CIRCLED NUMBER THIRTEEN +.char \[14-o] \[u246D] \" CIRCLED NUMBER FOURTEEN +.char \[15-o] \[u246E] \" CIRCLED NUMBER FIFTEEN +.char \[16-o] \[u246F] \" CIRCLED NUMBER SIXTEEN +.char \[17-o] \[u2470] \" CIRCLED NUMBER SEVENTEEN +.char \[18-o] \[u2471] \" CIRCLED NUMBER EIGHTEEN +.char \[19-o] \[u2472] \" CIRCLED NUMBER NINETEEN +.char \[20-o] \[u2473] \" CIRCLED NUMBER TWENTY +.char \[(1)] \[u2474] \" PARENTHESIZED DIGIT ONE +.char \[(2)] \[u2475] \" PARENTHESIZED DIGIT TWO +.char \[(3)] \[u2476] \" PARENTHESIZED DIGIT THREE +.char \[(4)] \[u2477] \" PARENTHESIZED DIGIT FOUR +.char \[(5)] \[u2478] \" PARENTHESIZED DIGIT FIVE +.char \[(6)] \[u2479] \" PARENTHESIZED DIGIT SIX +.char \[(7)] \[u247A] \" PARENTHESIZED DIGIT SEVEN +.char \[(8)] \[u247B] \" PARENTHESIZED DIGIT EIGHT +.char \[(9)] \[u247C] \" PARENTHESIZED DIGIT NINE +.char \[(10)] \[u247D] \" PARENTHESIZED NUMBER TEN +.char \[(11)] \[u247E] \" PARENTHESIZED NUMBER ELEVEN +.char \[(12)] \[u247F] \" PARENTHESIZED NUMBER TWELVE +.char \[(13)] \[u2480] \" PARENTHESIZED NUMBER THIRTEEN +.char \[(14)] \[u2481] \" PARENTHESIZED NUMBER FOURTEEN +.char \[(15)] \[u2482] \" PARENTHESIZED NUMBER FIFTEEN +.char \[(16)] \[u2483] \" PARENTHESIZED NUMBER SIXTEEN +.char \[(17)] \[u2484] \" PARENTHESIZED NUMBER SEVENTEEN +.char \[(18)] \[u2485] \" PARENTHESIZED NUMBER EIGHTEEN +.char \[(19)] \[u2486] \" PARENTHESIZED NUMBER NINETEEN +.char \[(20)] \[u2487] \" PARENTHESIZED NUMBER TWENTY +.char \[1.] \[u2488] \" DIGIT ONE FULL STOP +.char \[2.] \[u2489] \" DIGIT TWO FULL STOP +.char \[3.] \[u248A] \" DIGIT THREE FULL STOP +.char \[4.] \[u248B] \" DIGIT FOUR FULL STOP +.char \[5.] \[u248C] \" DIGIT FIVE FULL STOP +.char \[6.] \[u248D] \" DIGIT SIX FULL STOP +.char \[7.] \[u248E] \" DIGIT SEVEN FULL STOP +.char \[8.] \[u248F] \" DIGIT EIGHT FULL STOP +.char \[9.] \[u2490] \" DIGIT NINE FULL STOP +.char \[10.] \[u2491] \" NUMBER TEN FULL STOP +.char \[11.] \[u2492] \" NUMBER ELEVEN FULL STOP +.char \[12.] \[u2493] \" NUMBER TWELVE FULL STOP +.char \[13.] \[u2494] \" NUMBER THIRTEEN FULL STOP +.char \[14.] \[u2495] \" NUMBER FOURTEEN FULL STOP +.char \[15.] \[u2496] \" NUMBER FIFTEEN FULL STOP +.char \[16.] \[u2497] \" NUMBER SIXTEEN FULL STOP +.char \[17.] \[u2498] \" NUMBER SEVENTEEN FULL STOP +.char \[18.] \[u2499] \" NUMBER EIGHTEEN FULL STOP +.char \[19.] \[u249A] \" NUMBER NINETEEN FULL STOP +.char \[20.] \[u249B] \" NUMBER TWENTY FULL STOP +.char \[(a)] \[u249C] \" PARENTHESIZED LATIN SMALL LETTER A +.char \[(b)] \[u249D] \" PARENTHESIZED LATIN SMALL LETTER B +.char \[(c)] \[u249E] \" PARENTHESIZED LATIN SMALL LETTER C +.char \[(d)] \[u249F] \" PARENTHESIZED LATIN SMALL LETTER D +.char \[(e)] \[u24A0] \" PARENTHESIZED LATIN SMALL LETTER E +.char \[(f)] \[u24A1] \" PARENTHESIZED LATIN SMALL LETTER F +.char \[(g)] \[u24A2] \" PARENTHESIZED LATIN SMALL LETTER G +.char \[(h)] \[u24A3] \" PARENTHESIZED LATIN SMALL LETTER H +.char \[(i)] \[u24A4] \" PARENTHESIZED LATIN SMALL LETTER I +.char \[(j)] \[u24A5] \" PARENTHESIZED LATIN SMALL LETTER J +.char \[(k)] \[u24A6] \" PARENTHESIZED LATIN SMALL LETTER K +.char \[(l)] \[u24A7] \" PARENTHESIZED LATIN SMALL LETTER L +.char \[(m)] \[u24A8] \" PARENTHESIZED LATIN SMALL LETTER M +.char \[(n)] \[u24A9] \" PARENTHESIZED LATIN SMALL LETTER N +.char \[(o)] \[u24AA] \" PARENTHESIZED LATIN SMALL LETTER O +.char \[(p)] \[u24AB] \" PARENTHESIZED LATIN SMALL LETTER P +.char \[(q)] \[u24AC] \" PARENTHESIZED LATIN SMALL LETTER Q +.char \[(r)] \[u24AD] \" PARENTHESIZED LATIN SMALL LETTER R +.char \[(s)] \[u24AE] \" PARENTHESIZED LATIN SMALL LETTER S +.char \[(t)] \[u24AF] \" PARENTHESIZED LATIN SMALL LETTER T +.char \[(u)] \[u24B0] \" PARENTHESIZED LATIN SMALL LETTER U +.char \[(v)] \[u24B1] \" PARENTHESIZED LATIN SMALL LETTER V +.char \[(w)] \[u24B2] \" PARENTHESIZED LATIN SMALL LETTER W +.char \[(x)] \[u24B3] \" PARENTHESIZED LATIN SMALL LETTER X +.char \[(y)] \[u24B4] \" PARENTHESIZED LATIN SMALL LETTER Y +.char \[(z)] \[u24B5] \" PARENTHESIZED LATIN SMALL LETTER Z +.char \[A-o] \[u24B6] \" CIRCLED LATIN CAPITAL LETTER A +.char \[B-o] \[u24B7] \" CIRCLED LATIN CAPITAL LETTER B +.char \[C-o] \[u24B8] \" CIRCLED LATIN CAPITAL LETTER C +.char \[D-o] \[u24B9] \" CIRCLED LATIN CAPITAL LETTER D +.char \[E-o] \[u24BA] \" CIRCLED LATIN CAPITAL LETTER E +.char \[F-o] \[u24BB] \" CIRCLED LATIN CAPITAL LETTER F +.char \[G-o] \[u24BC] \" CIRCLED LATIN CAPITAL LETTER G +.char \[H-o] \[u24BD] \" CIRCLED LATIN CAPITAL LETTER H +.char \[I-o] \[u24BE] \" CIRCLED LATIN CAPITAL LETTER I +.char \[J-o] \[u24BF] \" CIRCLED LATIN CAPITAL LETTER J +.char \[K-o] \[u24C0] \" CIRCLED LATIN CAPITAL LETTER K +.char \[L-o] \[u24C1] \" CIRCLED LATIN CAPITAL LETTER L +.char \[M-o] \[u24C2] \" CIRCLED LATIN CAPITAL LETTER M +.char \[N-o] \[u24C3] \" CIRCLED LATIN CAPITAL LETTER N +.char \[O-o] \[u24C4] \" CIRCLED LATIN CAPITAL LETTER O +.char \[P-o] \[u24C5] \" CIRCLED LATIN CAPITAL LETTER P +.char \[Q-o] \[u24C6] \" CIRCLED LATIN CAPITAL LETTER Q +.char \[R-o] \[u24C7] \" CIRCLED LATIN CAPITAL LETTER R +.char \[S-o] \[u24C8] \" CIRCLED LATIN CAPITAL LETTER S +.char \[T-o] \[u24C9] \" CIRCLED LATIN CAPITAL LETTER T +.char \[U-o] \[u24CA] \" CIRCLED LATIN CAPITAL LETTER U +.char \[V-o] \[u24CB] \" CIRCLED LATIN CAPITAL LETTER V +.char \[W-o] \[u24CC] \" CIRCLED LATIN CAPITAL LETTER W +.char \[X-o] \[u24CD] \" CIRCLED LATIN CAPITAL LETTER X +.char \[Y-o] \[u24CE] \" CIRCLED LATIN CAPITAL LETTER Y +.char \[Z-o] \[u24CF] \" CIRCLED LATIN CAPITAL LETTER Z +.char \[a-o] \[u24D0] \" CIRCLED LATIN SMALL LETTER A +.char \[b-o] \[u24D1] \" CIRCLED LATIN SMALL LETTER B +.char \[c-o] \[u24D2] \" CIRCLED LATIN SMALL LETTER C +.char \[d-o] \[u24D3] \" CIRCLED LATIN SMALL LETTER D +.char \[e-o] \[u24D4] \" CIRCLED LATIN SMALL LETTER E +.char \[f-o] \[u24D5] \" CIRCLED LATIN SMALL LETTER F +.char \[g-o] \[u24D6] \" CIRCLED LATIN SMALL LETTER G +.char \[h-o] \[u24D7] \" CIRCLED LATIN SMALL LETTER H +.char \[i-o] \[u24D8] \" CIRCLED LATIN SMALL LETTER I +.char \[j-o] \[u24D9] \" CIRCLED LATIN SMALL LETTER J +.char \[k-o] \[u24DA] \" CIRCLED LATIN SMALL LETTER K +.char \[l-o] \[u24DB] \" CIRCLED LATIN SMALL LETTER L +.char \[m-o] \[u24DC] \" CIRCLED LATIN SMALL LETTER M +.char \[n-o] \[u24DD] \" CIRCLED LATIN SMALL LETTER N +.char \[o-o] \[u24DE] \" CIRCLED LATIN SMALL LETTER O +.char \[p-o] \[u24DF] \" CIRCLED LATIN SMALL LETTER P +.char \[q-o] \[u24E0] \" CIRCLED LATIN SMALL LETTER Q +.char \[r-o] \[u24E1] \" CIRCLED LATIN SMALL LETTER R +.char \[s-o] \[u24E2] \" CIRCLED LATIN SMALL LETTER S +.char \[t-o] \[u24E3] \" CIRCLED LATIN SMALL LETTER T +.char \[u-o] \[u24E4] \" CIRCLED LATIN SMALL LETTER U +.char \[v-o] \[u24E5] \" CIRCLED LATIN SMALL LETTER V +.char \[w-o] \[u24E6] \" CIRCLED LATIN SMALL LETTER W +.char \[x-o] \[u24E7] \" CIRCLED LATIN SMALL LETTER X +.char \[y-o] \[u24E8] \" CIRCLED LATIN SMALL LETTER Y +.char \[z-o] \[u24E9] \" CIRCLED LATIN SMALL LETTER Z +.char \[0-o] \[u24EA] \" CIRCLED DIGIT ZERO +.char \[hh] \[u2500] \" BOX DRAWINGS LIGHT HORIZONTAL +.char \[HH] \[u2501] \" BOX DRAWINGS HEAVY HORIZONTAL +.char \[vv] \[u2502] \" BOX DRAWINGS LIGHT VERTICAL +.char \[VV] \[u2503] \" BOX DRAWINGS HEAVY VERTICAL +.char \[3-] \[u2504] \" BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL +.char \[3_] \[u2505] \" BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL +.char \[3!] \[u2506] \" BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL +.char \[3/] \[u2507] \" BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL +.char \[4-] \[u2508] \" BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL +.char \[4_] \[u2509] \" BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL +.char \[4!] \[u250A] \" BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL +.char \[4/] \[u250B] \" BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL +.char \[dr] \[u250C] \" BOX DRAWINGS LIGHT DOWN AND RIGHT +.char \[dR] \[u250D] \" BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY +.char \[Dr] \[u250E] \" BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT +.char \[DR] \[u250F] \" BOX DRAWINGS HEAVY DOWN AND RIGHT +.char \[dl] \[u2510] \" BOX DRAWINGS LIGHT DOWN AND LEFT +.char \[dL] \[u2511] \" BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY +.char \[Dl] \[u2512] \" BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT +.char \[LD] \[u2513] \" BOX DRAWINGS HEAVY DOWN AND LEFT +.char \[ur] \[u2514] \" BOX DRAWINGS LIGHT UP AND RIGHT +.char \[uR] \[u2515] \" BOX DRAWINGS UP LIGHT AND RIGHT HEAVY +.char \[Ur] \[u2516] \" BOX DRAWINGS UP HEAVY AND RIGHT LIGHT +.char \[UR] \[u2517] \" BOX DRAWINGS HEAVY UP AND RIGHT +.char \[ul] \[u2518] \" BOX DRAWINGS LIGHT UP AND LEFT +.char \[uL] \[u2519] \" BOX DRAWINGS UP LIGHT AND LEFT HEAVY +.char \[Ul] \[u251A] \" BOX DRAWINGS UP HEAVY AND LEFT LIGHT +.char \[UL] \[u251B] \" BOX DRAWINGS HEAVY UP AND LEFT +.char \[vr] \[u251C] \" BOX DRAWINGS LIGHT VERTICAL AND RIGHT +.char \[vR] \[u251D] \" BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY +.char \[Udr] \[u251E] \" BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT +.char \[uDr] \[u251F] \" BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT +.char \[Vr] \[u2520] \" BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT +.char \[UdR] \[u2521] \" BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY +.char \[uDR] \[u2522] \" BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY +.char \[VR] \[u2523] \" BOX DRAWINGS HEAVY VERTICAL AND RIGHT +.char \[vl] \[u2524] \" BOX DRAWINGS LIGHT VERTICAL AND LEFT +.char \[vL] \[u2525] \" BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY +.char \[Udl] \[u2526] \" BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT +.char \[uDl] \[u2527] \" BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT +.char \[Vl] \[u2528] \" BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT +.char \[UdL] \[u2529] \" BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY +.char \[uDL] \[u252A] \" BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY +.char \[VL] \[u252B] \" BOX DRAWINGS HEAVY VERTICAL AND LEFT +.char \[dh] \[u252C] \" BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +.char \[dLr] \[u252D] \" BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT +.char \[dlR] \[u252E] \" BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT +.char \[dH] \[u252F] \" BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY +.char \[Dh] \[u2530] \" BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT +.char \[DLr] \[u2531] \" BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY +.char \[DlR] \[u2532] \" BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY +.char \[DH] \[u2533] \" BOX DRAWINGS HEAVY DOWN AND HORIZONTAL +.char \[uh] \[u2534] \" BOX DRAWINGS LIGHT UP AND HORIZONTAL +.char \[uLr] \[u2535] \" BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT +.char \[ulR] \[u2536] \" BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT +.char \[uH] \[u2537] \" BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY +.char \[Uh] \[u2538] \" BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT +.char \[ULr] \[u2539] \" BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY +.char \[UlR] \[u253A] \" BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY +.char \[UH] \[u253B] \" BOX DRAWINGS HEAVY UP AND HORIZONTAL +.char \[vh] \[u253C] \" BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +.char \[vLr] \[u253D] \" BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT +.char \[vlR] \[u253E] \" BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT +.char \[vH] \[u253F] \" BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY +.char \[Udh] \[u2540] \" BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT +.char \[uDh] \[u2541] \" BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT +.char \[Vh] \[u2542] \" BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT +.char \[UdLr] \[u2543] \" BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT +.char \[UdlR] \[u2544] \" BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT +.char \[uDLr] \[u2545] \" BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT +.char \[uDlR] \[u2546] \" BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT +.char \[UdH] \[u2547] \" BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY +.char \[uDH] \[u2548] \" BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY +.char \[VLr] \[u2549] \" BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY +.char \[VlR] \[u254A] \" BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY +.char \[VH] \[u254B] \" BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL +.char \[FD] \[u2571] \" BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT +.char \[BD] \[u2572] \" BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT +.char \[TB] \[u2580] \" UPPER HALF BLOCK +.char \[LB] \[u2584] \" LOWER HALF BLOCK +.char \[FB] \[u2588] \" FULL BLOCK +.char \[lB] \[u258C] \" LEFT HALF BLOCK +.char \[RB] \[u2590] \" RIGHT HALF BLOCK +.char \[.S] \[u2591] \" LIGHT SHADE +.char \[:S] \[u2592] \" MEDIUM SHADE +.char \[?S] \[u2593] \" DARK SHADE +.char \[fS] \[u25A0] \" BLACK SQUARE +.char \[OS] \[u25A1] \" WHITE SQUARE +.char \[RO] \[u25A2] \" WHITE SQUARE WITH ROUNDED CORNERS +.char \[Rr] \[u25A3] \" WHITE SQUARE CONTAINING BLACK SMALL SQUARE +.char \[RF] \[u25A4] \" SQUARE WITH HORIZONTAL FILL +.char \[RY] \[u25A5] \" SQUARE WITH VERTICAL FILL +.char \[RH] \[u25A6] \" SQUARE WITH ORTHOGONAL CROSSHATCH FILL +.char \[RZ] \[u25A7] \" SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL +.char \[RK] \[u25A8] \" SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL +.char \[RX] \[u25A9] \" SQUARE WITH DIAGONAL CROSSHATCH FILL +.char \[sB] \[u25AA] \" BLACK SMALL SQUARE +.char \[SR] \[u25AC] \" BLACK RECTANGLE +.char \[Or] \[u25AD] \" WHITE RECTANGLE +.char \[UT] \[u25B2] \" BLACK UP-POINTING TRIANGLE +.char \[uT] \[u25B3] \" WHITE UP-POINTING TRIANGLE +.char \[PR] \[u25B6] \" BLACK RIGHT-POINTING TRIANGLE +.char \[Tr] \[u25B7] \" WHITE RIGHT-POINTING TRIANGLE +.char \[Dt] \[u25BC] \" BLACK DOWN-POINTING TRIANGLE +.char \[dT] \[u25BD] \" WHITE DOWN-POINTING TRIANGLE +.char \[PL] \[u25C0] \" BLACK LEFT-POINTING TRIANGLE +.char \[Tl] \[u25C1] \" WHITE LEFT-POINTING TRIANGLE +.char \[Db] \[u25C6] \" BLACK DIAMOND +.char \[Dw] \[u25C7] \" WHITE DIAMOND +.char \[LZ] \[u25CA] \" LOZENGE +.char \[0m] \[u25CB] \" WHITE CIRCLE +.char \[0o] \[u25CE] \" BULLSEYE +.char \[0M] \[u25CF] \" BLACK CIRCLE +.char \[0L] \[u25D0] \" CIRCLE WITH LEFT HALF BLACK +.char \[0R] \[u25D1] \" CIRCLE WITH RIGHT HALF BLACK +.char \[Sn] \[u25D8] \" INVERSE BULLET +.char \[Ic] \[u25D9] \" INVERSE WHITE CIRCLE +.char \[Fd] \[u25E2] \" BLACK LOWER RIGHT TRIANGLE +.char \[Bd] \[u25E3] \" BLACK LOWER LEFT TRIANGLE +.char \[*2] \[u2605] \" BLACK STAR +.char \[*1] \[u2606] \" WHITE STAR +.char \[TEL] \[u260E] \" BLACK TELEPHONE +.char \[tel] \[u260F] \" WHITE TELEPHONE +.char \[<H] \[u261C] \" WHITE LEFT POINTING INDEX +.char \[>H] \[u261E] \" WHITE RIGHT POINTING INDEX +.char \[0u] \[u263A] \" WHITE SMILING FACE +.char \[0U] \[u263B] \" BLACK SMILING FACE +.char \[SU] \[u263C] \" WHITE SUN WITH RAYS +.char \[Fm] \[u2640] \" FEMALE SIGN +.char \[Ml] \[u2642] \" MALE SIGN +.char \[cS] \[u2660] \" BLACK SPADE SUIT +.char \[cH] \[u2661] \" WHITE HEART SUIT +.char \[cD] \[u2662] \" WHITE DIAMOND SUIT +.char \[cC] \[u2663] \" BLACK CLUB SUIT +.char \[cS-] \[u2664] \" WHITE SPADE SUIT +.char \[cH-] \[u2665] \" BLACK HEART SUIT +.char \[cD-] \[u2666] \" BLACK DIAMOND SUIT +.char \[cC-] \[u2667] \" WHITE CLUB SUIT +.char \[Md] \[u2669] \" QUARTER NOTE +.char \[M8] \[u266A] \" EIGHTH NOTE +.char \[M2] \[u266B] \" BARRED EIGHTH NOTES +.char \[M16] \[u266C] \" BARRED SIXTEENTH NOTES +.char \[Mb] \[u266D] \" MUSIC FLAT SIGN +.char \[Mx] \[u266E] \" MUSIC NATURAL SIGN +.char \[MX] \[u266F] \" MUSIC SHARP SIGN +.char \[OK] \[u2713] \" CHECK MARK +.char \[XX] \[u2717] \" BALLOT X +.char \[-X] \[u2720] \" MALTESE CROSS +.char \[IS] \[u3000] \" IDEOGRAPHIC SPACE +.char \[,_] \[u3001] \" IDEOGRAPHIC COMMA +.char \[._] \[u3002] \" IDEOGRAPHIC PERIOD +.char \[+"] \[u3003] \" DITTO MARK +.char \[+_] \[u3004] \" IDEOGRAPHIC DITTO MARK +.char \[*_] \[u3005] \" IDEOGRAPHIC ITERATION MARK +.char \[;_] \[u3006] \" IDEOGRAPHIC CLOSING MARK +.char \[0_] \[u3007] \" IDEOGRAPHIC NUMBER ZERO +.char \[<+] \[u300A] \" LEFT DOUBLE ANGLE BRACKET +.char \[>+] \[u300B] \" RIGHT DOUBLE ANGLE BRACKET +.char \[<'] \[u300C] \" LEFT CORNER BRACKET +.char \[>'] \[u300D] \" RIGHT CORNER BRACKET +.char \[<"] \[u300E] \" LEFT WHITE CORNER BRACKET +.char \[>"] \[u300F] \" RIGHT WHITE CORNER BRACKET +.char \[("] \[u3010] \" LEFT BLACK LENTICULAR BRACKET +.char \[)"] \[u3011] \" RIGHT BLACK LENTICULAR BRACKET +.char \[=T] \[u3012] \" POSTAL MARK +.char \[=_] \[u3013] \" GETA MARK +.char \[('] \[u3014] \" LEFT TORTOISE SHELL BRACKET +.char \[)'] \[u3015] \" RIGHT TORTOISE SHELL BRACKET +.char \[(I] \[u3016] \" LEFT WHITE LENTICULAR BRACKET +.char \[)I] \[u3017] \" RIGHT WHITE LENTICULAR BRACKET +.char \[-?] \[u301C] \" WAVE DASH +.char \[=T:)] \[u3020] \" POSTAL MARK FACE +.char \[A5] \[u3041] \" HIRAGANA LETTER SMALL A +.char \[a5] \[u3042] \" HIRAGANA LETTER A +.char \[I5] \[u3043] \" HIRAGANA LETTER SMALL I +.char \[i5] \[u3044] \" HIRAGANA LETTER I +.char \[U5] \[u3045] \" HIRAGANA LETTER SMALL U +.char \[u5] \[u3046] \" HIRAGANA LETTER U +.char \[E5] \[u3047] \" HIRAGANA LETTER SMALL E +.char \[e5] \[u3048] \" HIRAGANA LETTER E +.char \[O5] \[u3049] \" HIRAGANA LETTER SMALL O +.char \[o5] \[u304A] \" HIRAGANA LETTER O +.char \[ka] \[u304B] \" HIRAGANA LETTER KA +.char \[ga] \[u304C] \" HIRAGANA LETTER GA +.char \[ki] \[u304D] \" HIRAGANA LETTER KI +.char \[gi] \[u304E] \" HIRAGANA LETTER GI +.char \[ku] \[u304F] \" HIRAGANA LETTER KU +.char \[gu] \[u3050] \" HIRAGANA LETTER GU +.char \[ke] \[u3051] \" HIRAGANA LETTER KE +.char \[ge] \[u3052] \" HIRAGANA LETTER GE +.char \[ko] \[u3053] \" HIRAGANA LETTER KO +.char \[go] \[u3054] \" HIRAGANA LETTER GO +.char \[sa] \[u3055] \" HIRAGANA LETTER SA +.char \[za] \[u3056] \" HIRAGANA LETTER ZA +.char \[si] \[u3057] \" HIRAGANA LETTER SI +.char \[zi] \[u3058] \" HIRAGANA LETTER ZI +.char \[su] \[u3059] \" HIRAGANA LETTER SU +.char \[zu] \[u305A] \" HIRAGANA LETTER ZU +.char \[se] \[u305B] \" HIRAGANA LETTER SE +.char \[ze] \[u305C] \" HIRAGANA LETTER ZE +.char \[so] \[u305D] \" HIRAGANA LETTER SO +.char \[zo] \[u305E] \" HIRAGANA LETTER ZO +.char \[ta] \[u305F] \" HIRAGANA LETTER TA +.char \[da] \[u3060] \" HIRAGANA LETTER DA +.char \[ti] \[u3061] \" HIRAGANA LETTER TI +.char \[di] \[u3062] \" HIRAGANA LETTER DI +.char \[tU] \[u3063] \" HIRAGANA LETTER SMALL TU +.char \[tu] \[u3064] \" HIRAGANA LETTER TU +.char \[du] \[u3065] \" HIRAGANA LETTER DU +.char \[te] \[u3066] \" HIRAGANA LETTER TE +.char \[de] \[u3067] \" HIRAGANA LETTER DE +.char \[to] \[u3068] \" HIRAGANA LETTER TO +.char \[do] \[u3069] \" HIRAGANA LETTER DO +.char \[na] \[u306A] \" HIRAGANA LETTER NA +.char \[ni] \[u306B] \" HIRAGANA LETTER NI +.char \[nu] \[u306C] \" HIRAGANA LETTER NU +.char \[ne] \[u306D] \" HIRAGANA LETTER NE +.char \[no] \[u306E] \" HIRAGANA LETTER NO +.char \[ha] \[u306F] \" HIRAGANA LETTER HA +.char \[ba] \[u3070] \" HIRAGANA LETTER BA +.char \[pa] \[u3071] \" HIRAGANA LETTER PA +.char \[hi] \[u3072] \" HIRAGANA LETTER HI +.char \[bi] \[u3073] \" HIRAGANA LETTER BI +.char \[pi] \[u3074] \" HIRAGANA LETTER PI +.char \[hu] \[u3075] \" HIRAGANA LETTER HU +.char \[bu] \[u3076] \" HIRAGANA LETTER BU +.char \[pu] \[u3077] \" HIRAGANA LETTER PU +.char \[he] \[u3078] \" HIRAGANA LETTER HE +.char \[be] \[u3079] \" HIRAGANA LETTER BE +.char \[pe] \[u307A] \" HIRAGANA LETTER PE +.char \[ho] \[u307B] \" HIRAGANA LETTER HO +.char \[bo] \[u307C] \" HIRAGANA LETTER BO +.char \[po] \[u307D] \" HIRAGANA LETTER PO +.char \[ma] \[u307E] \" HIRAGANA LETTER MA +.char \[mi] \[u307F] \" HIRAGANA LETTER MI +.char \[mu] \[u3080] \" HIRAGANA LETTER MU +.char \[me] \[u3081] \" HIRAGANA LETTER ME +.char \[mo] \[u3082] \" HIRAGANA LETTER MO +.char \[yA] \[u3083] \" HIRAGANA LETTER SMALL YA +.char \[ya] \[u3084] \" HIRAGANA LETTER YA +.char \[yU] \[u3085] \" HIRAGANA LETTER SMALL YU +.char \[yu] \[u3086] \" HIRAGANA LETTER YU +.char \[yO] \[u3087] \" HIRAGANA LETTER SMALL YO +.char \[yo] \[u3088] \" HIRAGANA LETTER YO +.char \[ra] \[u3089] \" HIRAGANA LETTER RA +.char \[ri] \[u308A] \" HIRAGANA LETTER RI +.char \[ru] \[u308B] \" HIRAGANA LETTER RU +.char \[re] \[u308C] \" HIRAGANA LETTER RE +.char \[ro] \[u308D] \" HIRAGANA LETTER RO +.char \[wA] \[u308E] \" HIRAGANA LETTER SMALL WA +.char \[wa] \[u308F] \" HIRAGANA LETTER WA +.char \[wi] \[u3090] \" HIRAGANA LETTER WI +.char \[we] \[u3091] \" HIRAGANA LETTER WE +.char \[wo] \[u3092] \" HIRAGANA LETTER WO +.char \[n5] \[u3093] \" HIRAGANA LETTER N +.char \[vu] \[u3094] \" HIRAGANA LETTER VU +.char \["5] \[u309B] \" KATAKANA-HIRAGANA VOICED SOUND MARK +.char \[05] \[u309C] \" KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK +.char \[*5] \[u309D] \" HIRAGANA ITERATION MARK +.char \[+5] \[u309E] \" HIRAGANA VOICED ITERATION MARK +.char \[a6] \[u30A1] \" KATAKANA LETTER SMALL A +.char \[A6] \[u30A2] \" KATAKANA LETTER A +.char \[i6] \[u30A3] \" KATAKANA LETTER SMALL I +.char \[I6] \[u30A4] \" KATAKANA LETTER I +.char \[u6] \[u30A5] \" KATAKANA LETTER SMALL U +.char \[U6] \[u30A6] \" KATAKANA LETTER U +.char \[e6] \[u30A7] \" KATAKANA LETTER SMALL E +.char \[E6] \[u30A8] \" KATAKANA LETTER E +.char \[o6] \[u30A9] \" KATAKANA LETTER SMALL O +.char \[O6] \[u30AA] \" KATAKANA LETTER O +.char \[Ka] \[u30AB] \" KATAKANA LETTER KA +.char \[Ga] \[u30AC] \" KATAKANA LETTER GA +.char \[Ki] \[u30AD] \" KATAKANA LETTER KI +.char \[Gi] \[u30AE] \" KATAKANA LETTER GI +.char \[Ku] \[u30AF] \" KATAKANA LETTER KU +.char \[Gu] \[u30B0] \" KATAKANA LETTER GU +.char \[Ke] \[u30B1] \" KATAKANA LETTER KE +.char \[Ge] \[u30B2] \" KATAKANA LETTER GE +.char \[Ko] \[u30B3] \" KATAKANA LETTER KO +.char \[Go] \[u30B4] \" KATAKANA LETTER GO +.char \[Sa] \[u30B5] \" KATAKANA LETTER SA +.char \[Za] \[u30B6] \" KATAKANA LETTER ZA +.char \[Si] \[u30B7] \" KATAKANA LETTER SI +.char \[Zi] \[u30B8] \" KATAKANA LETTER ZI +.char \[Su] \[u30B9] \" KATAKANA LETTER SU +.char \[Zu] \[u30BA] \" KATAKANA LETTER ZU +.char \[Se] \[u30BB] \" KATAKANA LETTER SE +.char \[Ze] \[u30BC] \" KATAKANA LETTER ZE +.char \[So] \[u30BD] \" KATAKANA LETTER SO +.char \[Zo] \[u30BE] \" KATAKANA LETTER ZO +.char \[Ta] \[u30BF] \" KATAKANA LETTER TA +.char \[Da] \[u30C0] \" KATAKANA LETTER DA +.char \[Ti] \[u30C1] \" KATAKANA LETTER TI +.char \[Di] \[u30C2] \" KATAKANA LETTER DI +.char \[TU] \[u30C3] \" KATAKANA LETTER SMALL TU +.char \[Tu] \[u30C4] \" KATAKANA LETTER TU +.char \[Du] \[u30C5] \" KATAKANA LETTER DU +.char \[Te] \[u30C6] \" KATAKANA LETTER TE +.char \[De] \[u30C7] \" KATAKANA LETTER DE +.char \[To] \[u30C8] \" KATAKANA LETTER TO +.char \[Do] \[u30C9] \" KATAKANA LETTER DO +.char \[Na] \[u30CA] \" KATAKANA LETTER NA +.char \[Ni] \[u30CB] \" KATAKANA LETTER NI +.char \[Nu] \[u30CC] \" KATAKANA LETTER NU +.char \[Ne] \[u30CD] \" KATAKANA LETTER NE +.char \[No] \[u30CE] \" KATAKANA LETTER NO +.char \[Ha] \[u30CF] \" KATAKANA LETTER HA +.char \[Ba] \[u30D0] \" KATAKANA LETTER BA +.char \[Pa] \[u30D1] \" KATAKANA LETTER PA +.char \[Hi] \[u30D2] \" KATAKANA LETTER HI +.char \[Bi] \[u30D3] \" KATAKANA LETTER BI +.char \[Pi] \[u30D4] \" KATAKANA LETTER PI +.char \[Hu] \[u30D5] \" KATAKANA LETTER HU +.char \[Bu] \[u30D6] \" KATAKANA LETTER BU +.char \[Pu] \[u30D7] \" KATAKANA LETTER PU +.char \[He] \[u30D8] \" KATAKANA LETTER HE +.char \[Be] \[u30D9] \" KATAKANA LETTER BE +.char \[Pe] \[u30DA] \" KATAKANA LETTER PE +.char \[Ho] \[u30DB] \" KATAKANA LETTER HO +.char \[Bo] \[u30DC] \" KATAKANA LETTER BO +.char \[Po] \[u30DD] \" KATAKANA LETTER PO +.char \[Ma] \[u30DE] \" KATAKANA LETTER MA +.char \[Mi] \[u30DF] \" KATAKANA LETTER MI +.char \[Mu] \[u30E0] \" KATAKANA LETTER MU +.char \[Me] \[u30E1] \" KATAKANA LETTER ME +.char \[Mo] \[u30E2] \" KATAKANA LETTER MO +.char \[YA] \[u30E3] \" KATAKANA LETTER SMALL YA +.char \[Ya] \[u30E4] \" KATAKANA LETTER YA +.char \[YU] \[u30E5] \" KATAKANA LETTER SMALL YU +.char \[Yu] \[u30E6] \" KATAKANA LETTER YU +.char \[YO] \[u30E7] \" KATAKANA LETTER SMALL YO +.char \[Yo] \[u30E8] \" KATAKANA LETTER YO +.char \[Ra] \[u30E9] \" KATAKANA LETTER RA +.char \[Ri] \[u30EA] \" KATAKANA LETTER RI +.char \[Ru] \[u30EB] \" KATAKANA LETTER RU +.char \[Re] \[u30EC] \" KATAKANA LETTER RE +.char \[Ro] \[u30ED] \" KATAKANA LETTER RO +.char \[WA] \[u30EE] \" KATAKANA LETTER SMALL WA +.char \[Wa] \[u30EF] \" KATAKANA LETTER WA +.char \[Wi] \[u30F0] \" KATAKANA LETTER WI +.char \[We] \[u30F1] \" KATAKANA LETTER WE +.char \[Wo] \[u30F2] \" KATAKANA LETTER WO +.char \[N6] \[u30F3] \" KATAKANA LETTER N +.char \[Vu] \[u30F4] \" KATAKANA LETTER VU +.char \[KA] \[u30F5] \" KATAKANA LETTER SMALL KA +.char \[KE] \[u30F6] \" KATAKANA LETTER SMALL KE +.char \[Va] \[u30F7] \" KATAKANA LETTER VA +.char \[Vi] \[u30F8] \" KATAKANA LETTER VI +.char \[Ve] \[u30F9] \" KATAKANA LETTER VE +.char \[Vo] \[u30FA] \" KATAKANA LETTER VO +.char \[.6] \[u30FB] \" KATAKANA MIDDLE DOT +.char \[-6] \[u30FC] \" KATAKANA-HIRAGANA PROLONGED SOUND MARK +.char \[*6] \[u30FD] \" KATAKANA ITERATION MARK +.char \[+6] \[u30FE] \" KATAKANA VOICED ITERATION MARK +.char \[b4] \[u3105] \" BOPOMOFO LETTER B +.char \[p4] \[u3106] \" BOPOMOFO LETTER P +.char \[m4] \[u3107] \" BOPOMOFO LETTER M +.char \[f4] \[u3108] \" BOPOMOFO LETTER F +.char \[d4] \[u3109] \" BOPOMOFO LETTER D +.char \[t4] \[u310A] \" BOPOMOFO LETTER T +.char \[n4] \[u310B] \" BOPOMOFO LETTER N +.char \[l4] \[u310C] \" BOPOMOFO LETTER L +.char \[g4] \[u310D] \" BOPOMOFO LETTER G +.char \[k4] \[u310E] \" BOPOMOFO LETTER K +.char \[h4] \[u310F] \" BOPOMOFO LETTER H +.char \[j4] \[u3110] \" BOPOMOFO LETTER J +.char \[q4] \[u3111] \" BOPOMOFO LETTER Q +.char \[x4] \[u3112] \" BOPOMOFO LETTER X +.char \[zh] \[u3113] \" BOPOMOFO LETTER ZH +.char \[ch] \[u3114] \" BOPOMOFO LETTER CH +.char \[sh] \[u3115] \" BOPOMOFO LETTER SH +.char \[r4] \[u3116] \" BOPOMOFO LETTER R +.char \[z4] \[u3117] \" BOPOMOFO LETTER Z +.char \[c4] \[u3118] \" BOPOMOFO LETTER C +.char \[s4] \[u3119] \" BOPOMOFO LETTER S +.char \[a4] \[u311A] \" BOPOMOFO LETTER A +.char \[o4] \[u311B] \" BOPOMOFO LETTER O +.char \[e4] \[u311C] \" BOPOMOFO LETTER E +.char \[eh4] \[u311D] \" BOPOMOFO LETTER EH +.char \[ai] \[u311E] \" BOPOMOFO LETTER AI +.char \[ei] \[u311F] \" BOPOMOFO LETTER EI +.char \[au] \[u3120] \" BOPOMOFO LETTER AU +.char \[ou] \[u3121] \" BOPOMOFO LETTER OU +.char \[an] \[u3122] \" BOPOMOFO LETTER AN +.char \[en] \[u3123] \" BOPOMOFO LETTER EN +.char \[aN] \[u3124] \" BOPOMOFO LETTER ANG +.char \[eN] \[u3125] \" BOPOMOFO LETTER ENG +.char \[er] \[u3126] \" BOPOMOFO LETTER ER +.char \[i4] \[u3127] \" BOPOMOFO LETTER I +.char \[u4] \[u3128] \" BOPOMOFO LETTER U +.char \[iu] \[u3129] \" BOPOMOFO LETTER IU +.char \[v4] \[u312A] \" BOPOMOFO LETTER V +.char \[nG] \[u312B] \" BOPOMOFO LETTER NG +.char \[gn] \[u312C] \" BOPOMOFO LETTER GN +.char \[(JU)] \[u321C] \" PARENTHESIZED HANGUL JU +.char \[1c] \[u3220] \" PARENTHESIZED IDEOGRAPH ONE +.char \[2c] \[u3221] \" PARENTHESIZED IDEOGRAPH TWO +.char \[3c] \[u3222] \" PARENTHESIZED IDEOGRAPH THREE +.char \[4c] \[u3223] \" PARENTHESIZED IDEOGRAPH FOUR +.char \[5c] \[u3224] \" PARENTHESIZED IDEOGRAPH FIVE +.char \[6c] \[u3225] \" PARENTHESIZED IDEOGRAPH SIX +.char \[7c] \[u3226] \" PARENTHESIZED IDEOGRAPH SEVEN +.char \[8c] \[u3227] \" PARENTHESIZED IDEOGRAPH EIGHT +.char \[9c] \[u3228] \" PARENTHESIZED IDEOGRAPH NINE +.char \[10c] \[u3229] \" PARENTHESIZED IDEOGRAPH TEN +.char \[KSC] \[u327F] \" KOREAN STANDARD SYMBOL +.char \[ff] \[uFB00] \" LATIN SMALL LIGATURE FF +.char \[fi] \[uFB01] \" LATIN SMALL LIGATURE FI +.char \[fl] \[uFB02] \" LATIN SMALL LIGATURE FL +.char \[ffi] \[uFB03] \" LATIN SMALL LIGATURE FFI +.char \[ffl] \[uFB04] \" LATIN SMALL LIGATURE FFL +.char \[ft] \[uFB05] \" LATIN SMALL LIGATURE FT +.char \[st] \[uFB06] \" LATIN SMALL LIGATURE ST +.char \[3+;] \[uFE7D] \" ARABIC SHADDA MEDIAL FORM +.char \[aM.] \[uFE82] \" ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM +.char \[aH.] \[uFE84] \" ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM +.char \[a+-] \[uFE8D] \" ARABIC LETTER ALEF ISOLATED FORM +.char \[a+.] \[uFE8E] \" ARABIC LETTER ALEF FINAL FORM +.char \[b+-] \[uFE8F] \" ARABIC LETTER BEH ISOLATED FORM +.char \[b+,] \[uFE90] \" ARABIC LETTER BEH INITIAL FORM +.char \[b+;] \[uFE91] \" ARABIC LETTER BEH MEDIAL FORM +.char \[b+.] \[uFE92] \" ARABIC LETTER BEH FINAL FORM +.char \[tm-] \[uFE93] \" ARABIC LETTER TEH MARBUTA ISOLATED FORM +.char \[tm.] \[uFE94] \" ARABIC LETTER TEH MARBUTA FINAL FORM +.char \[t+-] \[uFE95] \" ARABIC LETTER TEH ISOLATED FORM +.char \[t+,] \[uFE96] \" ARABIC LETTER TEH INITIAL FORM +.char \[t+;] \[uFE97] \" ARABIC LETTER TEH MEDIAL FORM +.char \[t+.] \[uFE98] \" ARABIC LETTER TEH FINAL FORM +.char \[tk-] \[uFE99] \" ARABIC LETTER THEH ISOLATED FORM +.char \[tk,] \[uFE9A] \" ARABIC LETTER THEH INITIAL FORM +.char \[tk;] \[uFE9B] \" ARABIC LETTER THEH MEDIAL FORM +.char \[tk.] \[uFE9C] \" ARABIC LETTER THEH FINAL FORM +.char \[g+-] \[uFE9D] \" ARABIC LETTER JEEM ISOLATED FORM +.char \[g+,] \[uFE9E] \" ARABIC LETTER JEEM INITIAL FORM +.char \[g+;] \[uFE9F] \" ARABIC LETTER JEEM MEDIAL FORM +.char \[g+.] \[uFEA0] \" ARABIC LETTER JEEM FINAL FORM +.char \[hk-] \[uFEA1] \" ARABIC LETTER HAH ISOLATED FORM +.char \[hk,] \[uFEA2] \" ARABIC LETTER HAH INITIAL FORM +.char \[hk;] \[uFEA3] \" ARABIC LETTER HAH MEDIAL FORM +.char \[hk.] \[uFEA4] \" ARABIC LETTER HAH FINAL FORM +.char \[x+-] \[uFEA5] \" ARABIC LETTER KHAH ISOLATED FORM +.char \[x+,] \[uFEA6] \" ARABIC LETTER KHAH INITIAL FORM +.char \[x+;] \[uFEA7] \" ARABIC LETTER KHAH MEDIAL FORM +.char \[x+.] \[uFEA8] \" ARABIC LETTER KHAH FINAL FORM +.char \[d+-] \[uFEA9] \" ARABIC LETTER DAL ISOLATED FORM +.char \[d+.] \[uFEAA] \" ARABIC LETTER DAL FINAL FORM +.char \[dk-] \[uFEAB] \" ARABIC LETTER THAL ISOLATED FORM +.char \[dk.] \[uFEAC] \" ARABIC LETTER THAL FINAL FORM +.char \[r+-] \[uFEAD] \" ARABIC LETTER REH ISOLATED FORM +.char \[r+.] \[uFEAE] \" ARABIC LETTER REH FINAL FORM +.char \[z+-] \[uFEAF] \" ARABIC LETTER ZAIN ISOLATED FORM +.char \[z+.] \[uFEB0] \" ARABIC LETTER ZAIN FINAL FORM +.char \[s+-] \[uFEB1] \" ARABIC LETTER SEEN ISOLATED FORM +.char \[s+,] \[uFEB2] \" ARABIC LETTER SEEN INITIAL FORM +.char \[s+;] \[uFEB3] \" ARABIC LETTER SEEN MEDIAL FORM +.char \[s+.] \[uFEB4] \" ARABIC LETTER SEEN FINAL FORM +.char \[sn-] \[uFEB5] \" ARABIC LETTER SHEEN ISOLATED FORM +.char \[sn,] \[uFEB6] \" ARABIC LETTER SHEEN INITIAL FORM +.char \[sn;] \[uFEB7] \" ARABIC LETTER SHEEN MEDIAL FORM +.char \[sn.] \[uFEB8] \" ARABIC LETTER SHEEN FINAL FORM +.char \[c+-] \[uFEB9] \" ARABIC LETTER SAD ISOLATED FORM +.char \[c+,] \[uFEBA] \" ARABIC LETTER SAD INITIAL FORM +.char \[c+;] \[uFEBB] \" ARABIC LETTER SAD MEDIAL FORM +.char \[c+.] \[uFEBC] \" ARABIC LETTER SAD FINAL FORM +.char \[dd-] \[uFEBD] \" ARABIC LETTER DAD ISOLATED FORM +.char \[dd,] \[uFEBE] \" ARABIC LETTER DAD INITIAL FORM +.char \[dd;] \[uFEBF] \" ARABIC LETTER DAD MEDIAL FORM +.char \[dd.] \[uFEC0] \" ARABIC LETTER DAD FINAL FORM +.char \[tj-] \[uFEC1] \" ARABIC LETTER TAH ISOLATED FORM +.char \[tj,] \[uFEC2] \" ARABIC LETTER TAH INITIAL FORM +.char \[tj;] \[uFEC3] \" ARABIC LETTER TAH MEDIAL FORM +.char \[tj.] \[uFEC4] \" ARABIC LETTER TAH FINAL FORM +.char \[zH-] \[uFEC5] \" ARABIC LETTER ZAH ISOLATED FORM +.char \[zH,] \[uFEC6] \" ARABIC LETTER ZAH INITIAL FORM +.char \[zH;] \[uFEC7] \" ARABIC LETTER ZAH MEDIAL FORM +.char \[zH.] \[uFEC8] \" ARABIC LETTER ZAH FINAL FORM +.char \[e+-] \[uFEC9] \" ARABIC LETTER AIN ISOLATED FORM +.char \[e+,] \[uFECA] \" ARABIC LETTER AIN INITIAL FORM +.char \[e+;] \[uFECB] \" ARABIC LETTER AIN MEDIAL FORM +.char \[e+.] \[uFECC] \" ARABIC LETTER AIN FINAL FORM +.char \[i+-] \[uFECD] \" ARABIC LETTER GHAIN ISOLATED FORM +.char \[i+,] \[uFECE] \" ARABIC LETTER GHAIN INITIAL FORM +.char \[i+;] \[uFECF] \" ARABIC LETTER GHAIN MEDIAL FORM +.char \[i+.] \[uFED0] \" ARABIC LETTER GHAIN FINAL FORM +.char \[f+-] \[uFED1] \" ARABIC LETTER FEH ISOLATED FORM +.char \[f+,] \[uFED2] \" ARABIC LETTER FEH INITIAL FORM +.char \[f+;] \[uFED3] \" ARABIC LETTER FEH MEDIAL FORM +.char \[f+.] \[uFED4] \" ARABIC LETTER FEH FINAL FORM +.char \[q+-] \[uFED5] \" ARABIC LETTER QAF ISOLATED FORM +.char \[q+,] \[uFED6] \" ARABIC LETTER QAF INITIAL FORM +.char \[q+;] \[uFED7] \" ARABIC LETTER QAF MEDIAL FORM +.char \[q+.] \[uFED8] \" ARABIC LETTER QAF FINAL FORM +.char \[k+-] \[uFED9] \" ARABIC LETTER KAF ISOLATED FORM +.char \[k+,] \[uFEDA] \" ARABIC LETTER KAF INITIAL FORM +.char \[k+;] \[uFEDB] \" ARABIC LETTER KAF MEDIAL FORM +.char \[k+.] \[uFEDC] \" ARABIC LETTER KAF FINAL FORM +.char \[l+-] \[uFEDD] \" ARABIC LETTER LAM ISOLATED FORM +.char \[l+,] \[uFEDE] \" ARABIC LETTER LAM INITIAL FORM +.char \[l+;] \[uFEDF] \" ARABIC LETTER LAM MEDIAL FORM +.char \[l+.] \[uFEE0] \" ARABIC LETTER LAM FINAL FORM +.char \[m+-] \[uFEE1] \" ARABIC LETTER MEEM ISOLATED FORM +.char \[m+,] \[uFEE2] \" ARABIC LETTER MEEM INITIAL FORM +.char \[m+;] \[uFEE3] \" ARABIC LETTER MEEM MEDIAL FORM +.char \[m+.] \[uFEE4] \" ARABIC LETTER MEEM FINAL FORM +.char \[n+-] \[uFEE5] \" ARABIC LETTER NOON ISOLATED FORM +.char \[n+,] \[uFEE6] \" ARABIC LETTER NOON INITIAL FORM +.char \[n+;] \[uFEE7] \" ARABIC LETTER NOON MEDIAL FORM +.char \[n+.] \[uFEE8] \" ARABIC LETTER NOON FINAL FORM +.char \[h+-] \[uFEE9] \" ARABIC LETTER HEH ISOLATED FORM +.char \[h+,] \[uFEEA] \" ARABIC LETTER HEH INITIAL FORM +.char \[h+;] \[uFEEB] \" ARABIC LETTER HEH MEDIAL FORM +.char \[h+.] \[uFEEC] \" ARABIC LETTER HEH FINAL FORM +.char \[w+-] \[uFEED] \" ARABIC LETTER WAW ISOLATED FORM +.char \[w+.] \[uFEEE] \" ARABIC LETTER WAW FINAL FORM +.char \[j+-] \[uFEEF] \" ARABIC LETTER ALEF MAKSURA ISOLATED FORM +.char \[j+.] \[uFEF0] \" ARABIC LETTER ALEF MAKSURA FINAL FORM +.char \[y+-] \[uFEF1] \" ARABIC LETTER YEH ISOLATED FORM +.char \[y+,] \[uFEF2] \" ARABIC LETTER YEH INITIAL FORM +.char \[y+;] \[uFEF3] \" ARABIC LETTER YEH MEDIAL FORM +.char \[y+.] \[uFEF4] \" ARABIC LETTER YEH FINAL FORM +.char \[lM-] \[uFEF5] \" ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM +.char \[lM.] \[uFEF6] \" ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM +.char \[lH-] \[uFEF7] \" ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM +.char \[lH.] \[uFEF8] \" ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM +.char \[lh-] \[uFEF9] \" ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM +.char \[lh.] \[uFEFA] \" ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM +.char \[la-] \[uFEFB] \" ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM +.char \[la.] \[uFEFC] \" ARABIC LIGATURE LAM WITH ALEF FINAL FORM diff --git a/contrib/rfc1345/tests/rfc1345-smoke-test.sh b/contrib/rfc1345/tests/rfc1345-smoke-test.sh new file mode 100755 index 0000000..5fd2fb7 --- /dev/null +++ b/contrib/rfc1345/tests/rfc1345-smoke-test.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file 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/>. +# + +groff="${abs_top_builddir:-.}/test-groff" + +# Smoke-test rfc1345.tmac. + +DOC='\[,.]' + +OUTPUT=$(echo "$DOC" | "$groff" -T utf8 -m rfc1345 -P-cbou -Z) + +echo "$OUTPUT" | grep -Fqx 'Cu2026' + +# vim:set ai et sw=4 ts=4 tw=72: diff --git a/contrib/sboxes/ChangeLog b/contrib/sboxes/ChangeLog new file mode 100644 index 0000000..4d56984 --- /dev/null +++ b/contrib/sboxes/ChangeLog @@ -0,0 +1,202 @@ +2023-02-18 G. Branden Robinson <g.branden.robinson@gmail.com> + + * sboxes.am (uninstall_sboxes): Clean more fastidiously; try to + remove the configured `sboxespdfdocdir` in the event it is + empty, but do not fail if it isn't. (It can be a directory + shared with other groff components; we don't know in what order + the uninstall targets will serialize, but the last one run + should succeed.) + +2022-10-23 G. Branden Robinson <g.branden.robinson@gmail.com> + + * sboxes.tmac: Escape newline after opening conditional block. + +2022-05-20 G. Branden Robinson <g.branden.robinson@gmail.com> + + * sboxes.am: Rename `BUILD_PDFDOC` to `USE_GROPDF`. + +2022-05-01 G. Branden Robinson <g.branden.robinson@gmail.com> + + * sboxes.am ($(sboxes_builddir)/msboxes.pdf): Depend on new name + for devpdf stamp file. + +2022-04-03 Ingo Schwarze <schwarze@openbsd.org> + + * sboxes.am: msboxes.ms is documentation, not merely an example. + Consequently, install msboxes.ms unconditionally and msboxes.pdf + if BUILD_PDFDOC is enabled, both to the documentation directory + rather than to the examples directory. + +2022-04-02 Ingo Schwarze <schwarze@openbsd.org> + + * sboxes.am: Stop installing msboxes.ms.in; + installing msboxes.ms and msboxes.pdf is enough. + +2022-03-29 G. Branden Robinson <g.branden.robinson@gmail.com> + + * sboxes.am: Track rename of `DOC_GROFF_ONLY` to `DOC_GROFF`. + +2022-03-29 G. Branden Robinson <g.branden.robinson@gmail.com> + + * msboxes.ms.in: Tweak sboxes documentation to imply ms + dependency. + + Fixes <https://savannah.gnu.org/bugs/?62062>. + +2022-03-22 Ingo Schwarze <schwarze@openbsd.org> + + * sboxes.am: fix non-portable syntax in the msboxes.pdf target + by using DOC_GROFF_ONLY rather than DOC_GROFF in order to not + use $< outside a suffix rule; DOC_GROFF functionality is not + needed here in the first place. + +2022-03-22 Ingo Schwarze <schwarze@openbsd.org> + + * sboxes.am: make the build of msboxes.{ms,pdf} work with BSD + make by using $(sboxes_builddir) consistently to prevent + variations in target names. + +2022-02-06 G. Branden Robinson <g.branden.robinson@gmail.com> + + * sboxes.tmac: Prefix early diagnostics with package file name + literally. (We don't yet know if we can use \*[] string + interpolation.) It is better to violate DRY a little here than + to obscure from the user what is emitting the diagnostic. + +2022-02-06 G. Branden Robinson <g.branden.robinson@gmail.com> + + * sboxes.tmac: Skip macro package instead of aborting if there + are prerequisite problems. This is an auxiliary package; it is + not necessarily fatal to the user's purposes if it doesn't load. + +2022-02-06 G. Branden Robinson <g.branden.robinson@gmail.com> + + * notquine.sed: Convert tilde to special character when inlining + document source (\~ is used). + +2021-11-01 G. Branden Robinson <g.branden.robinson@gmail.com> + + * msboxes.ms.in: Retitle document to "Using PDF Boxes with + _groff and_ the ms macros" (emphasis added) to make it clearer + that this package does not _require_ ms. + +2021-10-27 G. Branden Robinson <g.branden.robinson@gmail.com> + + * notquine.sed: Improve portability and tighten logic. Thanks + to Axel Kielhorn for the report and Andreas Kusalananda Kähäri + for the suggested improvements. + +2021-10-24 G. Branden Robinson <g.branden.robinson@gmail.com> + + * sboxes.tmac: Rename strings and macro I introduced so that + they fit Deri's selection within the name space (prefix "bx"). + Rename existing macros to use the groff ms(7) naming convention. + None of the macros in this "module" seem meant to be visible to + other modules, so suffix the module name with '*' instead of + '@'. Drop unused 7th argument in a `pdfbackground` call. + +2021-10-24 G. Branden Robinson <g.branden.robinson@gmail.com> + + * sboxes.tmac: Define GSBOX register as 0, then redefine it as 1 + only if the output device is `pdf`. (This way a document author + can easily and separately test the presence of the package and + whether the device-specific feature is likely to work.) + (pdfbackground): Only define (overriding `pdf.tmac`) if GSBOX is + false. + * msboxes.ms.in: Document this aspect of the package interface. + +2021-10-21 G. Branden Robinson <g.branden.robinson@gmail.com> + + * sboxes.am (SBOXES_FLAGS): Drop variable since we only expand + it in one place. + ($(sboxes_builddir)/msboxes.pdf): Be more consistent with the + rest of our build, particularly documentation generated in the + groff `doc` directory. Use `GROFF_V` instead of `AM_V_GEN` to + control output (since it is in fact groff producing the target). + Use `DOC_GROFF` to produce the document rather than + `test-groff`. Use the former `SBOXES_FLAGS` here. + +2021-10-20 G. Branden Robinson <g.branden.robinson@gmail.com> + + * sboxes.am ($(sboxes_builddir)/msboxes.ms, + $(sboxes_builddir)/msboxes.pdf): Be quieter by default; use + $(AM_V_at) and $(AM_V_GEN) more consistently with the rest of + the build. + +2021-10-17 G. Branden Robinson <g.branden.robinson@gmail.com> + + * sboxes.tmac: Rename macros to get out of user name space. Our + ms package documentation says that externally visible names will + consist only of uppercase letters and digits. + (BoxStart): Rename to BOXSTART. + (BoxStop): Rename to BOXSTOP. + * msboxes.ms.in: Document and use new names. + +2021-10-17 G. Branden Robinson <g.branden.robinson@gmail.com> + + * sboxes.tmac: Add more prerequisite checking. Check `GS` + register for groff ms macros specifically. Check installed + version of groff since the gropdf in earlier versions won't + implement the underlying feature. Add new string to introduce + diagnostic messages now that we have more than one (that we can + emit without limp-along AT&T compatibility mode). + (sboxes*error): Use new string in diagnostic message. + +2021-10-17 G. Branden Robinson <g.branden.robinson@gmail.com> + + * sboxes.tmac (sboxes*error): Add new macro to produce + diagnostic message in a standard format. + (BoxStart): Use it. + +2021-10-17 G. Branden Robinson <g.branden.robinson@gmail.com> + + Make msboxes.ms quote its own source through a + self-interpolation process (with help from sed and the build + system), avoiding the need to manually keep the source document + and its quoted form in sync. + + * msboxes.ms: Rename to... + * msboxes.ms.in: ...this. + * notquine.sed: New file; this sed script performs quotation of + roff syntax characters (and hyphens), inserts the quoted form of + the document's source into itself, and reproduces Deri's + SchrĂśdinger's footnote trick. + * sboxes.am: Introduce new variables `sboxes_builddir` and + `sboxesnotquine` for convenience. Update value of + $(SBOXES_EXAMPLEFILES) to point to the new .in source file. Add + the generated ms document to $(SBOXES_PROCESSEDEXAMPLEFILES) and + $(MOSTLYCLEANFILES). Add the `notquine` sed script to the + distribution archive via $(EXTRA_DIST). + ($(sboxes_builddir)/msboxes.ms): New rule produces the ms + document from msboxes.ms.in, constructing it with sed. + ($(sboxes_builddir)/msboxes.pdf): Update rule to add dependency + on source document, use new `sboxes_builddir` variable, and look + for source document in the build tree instead of the source. + +2021-10-17 G. Branden Robinson <g.branden.robinson@gmail.com> + + * sboxes.am: Add this ChangeLog to `EXTRA_DIST`. + +2021-10-11 G. Branden Robinson <g.branden.robinson@gmail.com> + + * sboxes.am (MOSTLYCLEANFILES): Add + `$(SBOXES_PROCESSEDEXAMPLEFILES)`; allows `distcheck` target to + succeed. + +________________________________________________________________________ + +##### License + +Copyright 2021 Free Software Foundation, Inc. + +Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. + +##### Editor settings +Local Variables: +fill-column: 72 +mode: change-log +version-control: never +End: +vim:set autoindent textwidth=72: diff --git a/contrib/sboxes/msboxes.ms.in b/contrib/sboxes/msboxes.ms.in new file mode 100644 index 0000000..a1700df --- /dev/null +++ b/contrib/sboxes/msboxes.ms.in @@ -0,0 +1,272 @@ +.\" groff -ms -msboxes -Tpdf +.nr LL 17c +.nr PO 2c +.nr PS 11 +.nr VS 13 +.nr PI 3.5n +.nr HM 2c +.nr FM 2c +.nr QI 7n +.ss 12 0 +.ND March 2021 +.EH '%''March 2021' +.EF '''' +.OH 'Using PDF boxes with \f[I]groff\f[] and the \f[I]ms\f[] macros''%' +.OF '''' +.\" Define a quotation macro. +.de Qq +. nop \[lq]\\$1\[rq]\\$2 +.. +.\" Define a macro for code literals; use bold and disable hyphenation. +.de Lt +. ft B +. nh +. nop \&\\$1\c +. hy \\n[HY] +. ft +. nop \&\\$2 +.. +.ds FAM H +.TL +Using PDF boxes with +.BI groff +and the +.BI ms +macros +.AU +Deri James +.AI +deri@chuzzlewit.myzen.co.uk +.LP +An extension in version 1.23.0 of +.I gropdf , +the PDF output driver for the +.I groff +document formatting system, +allows coloured rectangles to be placed beneath any output created by +.I groff . +The extension can be accessed via a device control escape sequence +.Lt "\[rs]X\[aq]pdf: background" \~.\|.\|.\|\c +.Lt \[aq] +or a convenience macro +.Lt pdfbackground +supporting the same parameters. +.QS +.BOXSTART SHADED cornsilk OUTLINED brown INDENT 2n WEIGHT 1p +\M[floralwhite]\c +.pdfbackground pagefill +\M[]\c +.B +\[rs]X\[aq]pdf: background +.BI +cmd left top right bottom weight\[aq] +.br +.Lt .pdfbackground +.BI +cmd left top right bottom weight +.LP +each produce a background rectangle on the page, where +.IP \f[I]cmd 8n \" indent enough to fit "bottom" tag +is the command, which can be any of +.Qq page|fill|box +in combination. +Thus, +.Qq pagefill +would draw a rectangle which covers the whole current page size (in +which case the rest of the parameters can be omitted because the box +dimensions are taken from the current media size). +.Qq boxfill , +on the other hand, requires the given dimensions to place the box. +Including +.Qq fill +in the command will paint the rectangle with the current fill colour (as +with +.Lt \[rs]M[] ) +and including +.Qq box +will give the rectangle a border in the current stroke colour +(as with +.Lt \[rs]m[] ). +.sp \n[PD]u +.I cmd +may also be +.Qq off +on its own, which will terminate drawing the current box. +If you have specified a page colour with +.Qq pagefill , +it is always the first box in the stack, and if you specify it again, it +will replace the first entry. +Be aware that the +.Qq pagefill +box renders the page opaque, so tools that +.Qq watermark +PDF pages are unlikely to be successful. +To return the background to transparent, issue an +.Qq off +command with no other boxes open. +.sp \n[PD]u +Finally, +.I cmd +may be +.Qq footnote +followed by a new value for +.I bottom , +which will be used for all open boxes on the current page. +This is to allow room for footnote areas that grow while a page is +processed (to accommodate multiple footnotes, +for instance).\m[red]\**\m[]\" FOOTNOTE +.FS +If the value is negative, it is used as an offset from the bottom of the +page. +.FE +.nr oldPD \n[PD] +.nr PD 0 +.IP \f[I]left +.IP \f[I]top +.IP \f[I]right +.IP \f[I]bottom +.nr PD \n[oldPD] +are the coordinates of the box. +The +.I top +and +.I bottom +coordinates are the minimum and maximum for the box, since the actual +start of the box is +.I groff 's +drawing position when you issue the command, and the bottom of the box +is the point where you turn the box +.Qq off . +The top and bottom coordinates are used only if the box drawing extends +onto the next page; ordinarily, they would be set to the header and +footer margins. +.IP \f[I]weight +provides the line width for the border if +.Qq box +is included in the command. +.BOXSTOP +.QE +For an even more convenient interface, include +.Lt \-msboxes +on the +.I groff +command line; the +.I sboxes +package defines the macros +.Lt BOXSTART +and +.Lt BOXSTOP . +.QS +.BOXSTART SHADED cornsilk OUTLINED brown INDENT 2n WEIGHT 1p +.BOXSTART SHADED cornsilk3 INDENT 2p +.Lt .BOXSTART +.Lt SHADED +.I colour +.Lt OUTLINED +.I colour +.Lt INDENT +.I size +.Lt WEIGHT +.I size +.BOXSTOP +.LP +begins a box, +where the argument after +.Lt SHADED +gives the fill colour and that after +.Lt OUTLINED +the border colour. +Omit the former to get a borderless filled box and the latter for a +border with no fill. +The specified +.Lt WEIGHT +is used if the box is +.Lt OUTLINED . +.LP +.Lt INDENT +precedes a value which leaves a gap between the border and the contents +inside the box. +.LP +Each +.I colour +must be a defined +.I groff +colour name, +and each +.I size +a valid +.I groff +numeric expression. +The keyword/value pairs can be specified in any order. +.BOXSTOP +.QE +Boxes can be stacked, so you can start a box within another box; usually +the later boxes would be smaller than the containing box, but this is +not enforced. +When using +.Lt BOXSTART , +the left position is the current indent minus the +.Lt INDENT +in the command, +and the right position is the left position (calculated above) plus the +current line length and twice the indent. +The synopsis of +.Lt BOXSTART +above itself uses a +.Lt BOXSTART +call without borders and with a +.Lt 2p +(two point) indent. +.QS +.BOXSTART SHADED cornsilk OUTLINED brown INDENT 2n WEIGHT 1p +.BOXSTART SHADED cornsilk3 INDENT 2p +.Lt .BOXSTOP +.BOXSTOP +.LP +takes no parameters. +It closes the most recently started box at the current vertical position +after adding its +.Lt INDENT +spacing. +.BOXSTOP +.QE +Your +.I groff +documents can conditionally exercise the +.I sboxes +macros. +The register +.Lt GSBOX +is defined if the package is loaded, and interpolates a true value if +the +.Lt pdf +output device is in use. +.LP +.I sboxes +furthermore hooks into the +.I "groff ms" +package to receive notifications when footnotes are growing, so that it +can close boxes on a page before footnotes are printed. +When that condition obtains, +.I sboxes +will close open boxes two points\** +.FS +This amount probably will not match the box's +.Lt INDENT . +.FE +above the footnote separator and re-open them on the next page. +.LP +This document was produced using the following code. +.ds FAM C +.nr PS 11 +.nr VS 13 +.LP +.BOXSTART SHADED white OUTLINED brown INDENT 2n WEIGHT 1p +.nf +\# REPLACEME +.BOXSTOP +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/contrib/sboxes/notquine.sed b/contrib/sboxes/notquine.sed new file mode 100644 index 0000000..1a110ab --- /dev/null +++ b/contrib/sboxes/notquine.sed @@ -0,0 +1,18 @@ +s/.*\\##.*/&\ +&/ +s/\\##// +t +s/\\" FOOTNOTE/@FOOTNOTE@/ +s/\\/\\[rs]/g +s/-/\\&/g +s/'/\\[aq]/g +s/~/\\[ti]/g +s/^\./\\\&&/ +/@FOOTNOTE@/a\ +.FS\ +This is a long footnote occupying multiple output lines.\ +Its only purpose is to verify that the bottom of the box on this page\ +has been adjusted upwards to accommodate it.\ +.FE +s/@FOOTNOTE@/\\m[red]\\**\\m[]/ +s/REPLACEME/(replaced by source of this document)/ diff --git a/contrib/sboxes/sboxes.am b/contrib/sboxes/sboxes.am new file mode 100644 index 0000000..7786337 --- /dev/null +++ b/contrib/sboxes/sboxes.am @@ -0,0 +1,74 @@ +# Copyright (C) 2021 Free Software Foundation, Inc. +# Written by Bertrand Garrigues <bertrand.garrigues@laposte.net> +# +# This file 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/>. + +sboxes_srcdir = $(top_srcdir)/contrib/sboxes +sboxes_builddir = $(top_builddir)/contrib/sboxes +sboxesnotquine = $(sboxes_srcdir)/notquine.sed + +sboxestmacdir = $(tmacdir) +dist_sboxestmac_DATA = contrib/sboxes/sboxes.tmac + +EXTRA_DIST += \ + contrib/sboxes/ChangeLog \ + contrib/sboxes/msboxes.ms.in \ + contrib/sboxes/notquine.sed + +SBOXES_EXAMPLEFILES = $(sboxes_srcdir)/msboxes.ms.in + +sboxesotherdocdir = $(docdir) +nodist_sboxesotherdoc_DATA = $(sboxes_builddir)/msboxes.ms + +if USE_GROPDF +sboxespdfdocdir = $(pdfdocdir) +nodist_sboxespdfdoc_DATA = $(sboxes_builddir)/msboxes.pdf +endif + +MOSTLYCLEANFILES += msboxes.ms \ + $(nodist_sboxesotherdoc_DATA) \ + $(nodist_sboxespdfdoc_DATA) + +# The ordering of the sed -e expressions is important. +$(sboxes_builddir)/msboxes.ms: $(SBOXES_EXAMPLEFILES) $(sboxesnotquine) + $(AM_V_at)mkdir -p $(sboxes_builddir) + $(AM_V_at)$(SED) -n -e '1,/REPLACEME/p' \ + $(SBOXES_EXAMPLEFILES) > $@.tmp + $(AM_V_at)$(SED) -f $(sboxesnotquine) \ + $(SBOXES_EXAMPLEFILES) >> $@.tmp + $(AM_V_at)$(SED) -n -e '/REPLACEME/,$$p' \ + $(SBOXES_EXAMPLEFILES) >> $@.tmp + $(AM_V_GEN)mv $@.tmp $@ + +$(sboxes_builddir)/msboxes.pdf: $(sboxes_builddir)/msboxes.ms \ + $(dist_sboxestmac_DATA) groff troff gropdf font/devpdf/stamp + $(GROFF_V)$(DOC_GROFF) -M$(sboxes_srcdir) -ms -msboxes -Tpdf \ + $(sboxes_builddir)/msboxes.ms > $@ + +uninstall_groffdirs: uninstall_sboxes +uninstall_sboxes: + if test -d $(DESTDIR)$(exampledir)/sboxes; then \ + rmdir $(DESTDIR)$(exampledir)/sboxes; \ + fi +if USE_GROPDF + -rmdir $(DESTDIR)$(sboxespdfdocdir) +endif + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/contrib/sboxes/sboxes.tmac b/contrib/sboxes/sboxes.tmac new file mode 100644 index 0000000..63c9263 --- /dev/null +++ b/contrib/sboxes/sboxes.tmac @@ -0,0 +1,147 @@ +.ig + +sboxes.tmac + +Copyright (C) 2021 Free Software Foundation, Inc. + Written by Deri James (deri@chuzzlewit.myzen.co.uk) + +This file 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/>. +.. +.if !\n(.g \{\ +. tm sboxes.tmac: macros require groff extensions; not loading +. nx +.\} +. +.if \n(.C \{\ +. tm sboxes.tmac: macros do not work in compatibility mode; not loading +. nx +.\} +. +.\" Define a string for use in diagnostic messages. +.ds bx*name sboxes.tmac\" +. +.if !r GS \ +. ab \*[bx*name]: ms macros must be loaded first; aborting +. +.if (\n[.x]\n[.y] < 123) \{\ +. ds bx*msg \*[bx*name]: groff 1.23 or later is required,\" +. as bx*msg " but found groff \n[.x].\n[.y]; not loading\" +. tm \*[bx*msg] +. nx +.\} +. +.\" See if already loaded. +.if r GSBOX .nx +. +.\" GSBOX is defined if the package is loaded, and true if it will work. +.nr GSBOX 0 +.if '\*[.T]'pdf' \ +. nr GSBOX 1 +. +.nr bx*stack 0 +. +.de bx*error +. tm \*[bx*name]:\\n[.F]:\\n[.c]: error: \\$* +.. +. +.\" Define dummy macro if we're not formatting for the pdf device. +.if !\n[GSBOX] \{\ +. de pdfbackground +. . +.\} +. +.\" Link into ms macros to trap footnote growth +.am fn@print-sep +. nr bx*pb \\n[nl]u-2p +. nop \!x X pdf: background footnote \\n[bx*pb]z +. rr bx*pb +.. +.\" Has PD been actioned? +.am par*start +. nr bx*PD \\n[PD] +.. +. +.de BOXSTART +. fl +. nr bx*stack \\n[bx*stack]+1u +. nr bx*shad 0 +. nr bx*outl 0 +. nr bx*ind 1P +. ds bx*wt 0 +. ds bx*type "\" +. while \\n[.$] \{\ +. ie 'SHADED'\\$1' \{\ +. nop \\M[\\$2]\c +. nr bx*shad 1 +. as bx*type "fill\" +. shift 2 +. \} +. el \{\ +. ie 'OUTLINED'\\$1' \{\ +. nop \\m[\\$2]\c +. nr bx*outl 1 +. as bx*type "box\" +. shift 2 +. \} +. el \{\ +. ie 'WEIGHT'\\$1' \{\ +. ds bx*wt \\$2 +. shift 2 +. \} +. el \{\ +. ie 'INDENT'\\$1' \{\ +. nr bx*ind \\$2 +. shift 2 +. \} +. el \{\ +. bx*error ignoring unrecognized BOXSTART parameter '\\$1' +. shift +. \} +. \} +. \} +. \} +. \} +. +. if '\\*[bx*type]'' .ds bx*type "fill" +. nr bx*l \\n[\\n[.ev]:li]s+\\n[.o]s-\\n[bx*ind]u +. nr bx*r \\n[bx*l]u+\\n[.l]-\\n[\\n[.ev]:li]+(\\n[bx*ind]u*2u) +. nr bx*gap \\n[.v]-\\n[.ps]+\\*[bx*wt] +. nr bx*bot \\n[.p]u-\\n[FM]u+\\n[bx*ind]u+\\n[.ps]u +. nr bx*top \\n[HM]-\\n[bx*ind]u+\\n[bx*gap]u +. ne \\n[bx*ind]u+2v+\\*[bx*wt] +. sp -(2v-(\\n[bx*PD]u*2u))u +. pdfbackground \\*[bx*type] \\n[bx*l]z \\n[bx*top]z \ + \\n[bx*r]z \\n[bx*bot]z \ + \\*[bx*wt] +. sp (\\n[bx*ind]u-1v)u +. if (\\n[bx*shad]=1) .nop \\M[]\c +. if (\\n[bx*outl]=1) .nop \\m[]\c +. ds bx*ind\\n[bx*stack] \\n[bx*ind] +. rr bx*shad bx*outl bx*ind bx*bot bx*top bx*l bx*r +. rm wt type +. sp -(\\n[bx*gap]u) +. nr bx*PD 0 +.. +.de BOXSTOP +. sp \\*[bx*ind\\n[bx*stack]]u-\\n[.psr]u +. pdfbackground off +. nr bx*stack \\n[bx*stack]-1u +.. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set expandtab filetype=groff textwidth=72: diff --git a/doc/automake.mom b/doc/automake.mom new file mode 100644 index 0000000..5609e19 --- /dev/null +++ b/doc/automake.mom @@ -0,0 +1,789 @@ +.\" -*- mode: text; coding: utf-8; -*- +.\" +.\" Copyright Š2014 - 2022 Free Software Foundation +.\" 51 Franklin St, Fifth Floor, Boston, MA 02110, USA +.\" +.\" Permission is hereby granted, free of charge, to any person +.\" obtaining a copy of this software and associated documentation +.\" files (the "Software"), to deal in the Software without restriction, +.\" including, without limitation, the rights to use, copy, modify, +.\" merge, publish, distribute, sublicense, and sell copies of +.\" the Software, and to permit persons to whom the Software is +.\" furnished to do so, subject to the following conditions: +.\" +.\" The above copyright notice and this permission notice shall be +.\" included in all copies, or substantial portions, of the Software; +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +.\" OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND +.\" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +.\" HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, +.\" WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING +.\" FROM, OUT OF, OR IN CONNECTION WITH, THE SOFTWARE, OR THE USE OF, +.\" OR OTHER DEALINGS IN, THE SOFTWARE. +.\" +.\" Formatted with the mom macros +.\" .RW (reduce) and .EW (expand) control track kerning +.\" .WS controls word spacing +.\" Hanging punctuation and hyphens are inserted manually +.\" +.TITLE "Using Automake in the Groff project" +.AUTHOR "Bertrand Garrigues" +.COPYRIGHT "2014, 2017 Free Software Foundation" +.COVER TITLE AUTHOR DOCTYPE COPYRIGHT +. +.PAPER LETTER +.PRINTSTYLE TYPESET +. +.HEADING_STYLE 1 NUMBER +.HEADING_STYLE 2 NUMBER +.HEADING_STYLE 3 NUMBER +.HEADING_STYLE 4 NUMBER +. +.QUOTE_INDENT 2m +.CODE_FONT CB +. +\# Table of contents +.TOC_PADDING 2 +.SPACE_TOC_ITEMS +.AUTO_RELOCATE_TOC +.TOC_ENTRY_STYLE 2 FONT I +.TOC_LEAD 14 +. +.NO_SHIM \" Flex-spaced +. +.START +. +.PP +This is a quick overview of how to use `automake' in the groff +project, and is intended to help the developers and contributors +find their way when they have to make changes to the sources files +or to the data that are installed. If you need more details on +`automake', here are some reading suggestions: +. +.LEFT +.SP 3p +. +.LIST +.SHIFT_LIST 1m +.ITEM +The Automake Manual: +\*[FWD 1m]\c +.PDF_WWW_LINK https://www.gnu.org/software/automake/manual/automake.html +.SP 3p +.ITEM +A book by John Calcote, with good practical examples: +\*[FWD 1m]\c +.PDF_WWW_LINK http://fsmsh.com/2753 +.SP 3p +.ITEM +This site, by Diego Petteno, with good practical examples too: +\*[FWD 1m]\c +.PDF_WWW_LINK https://autotools.io/index.html +.LIST OFF +. +.JUSTIFY +.HY DEFAULT +. +.HEADING 1 "Overview, the initial build" +. +.HEADING 2 "First build" +. +.PP +Groff integrates the `gnulib' and uses its `bootstrap' script. When +compiling from the git repository, you should first invoke this +script: +.QUOTE +.CODE +$ ./bootstrap +.CODE OFF +.QUOTE OFF +This will: +. +.QUAD LEFT +.HY OFF +. +.LIST +.SHIFT_LIST 1m +.ITEM +.SP 3p +Clone the gnulib repository as a git submodule in `gnulib', +add the needed gnulib sources files in `lib', +add the needed gnulib m4 macros in `gnulib_m4'. +.SP 3p +.ITEM +Invoke autoreconf that will call all the `GNU autotools' (`aclocal', +`autoheader', `autoconf', `automake') in the right order for +creating the following files: +.LIST DASH +.SHIFT_LIST .5m +.SP 3p +.ITEM +INSTALL (a symlink to gnulib's INSTALL file) +.ITEM +Makefile.in +.ITEM +aclocal.m4 +.ITEM +autom4te.cache/ +.ITEM +build-aux/ (that contains all the helper scripts) +.ITEM +configure +.ITEM +src/include/config.hin +.LIST BACK +.LIST OFF +. +.SP 3p +.JUSTIFY +.HY DEFAULT +. +.WS +2 +.EW .5 +The file aclocal.m4 is generated and the groff m4 macros are +included via the acinclude.m4 file. +.WS DEFAULT +.EW 0 +. +.PP +At this point you can invoke the `configure' script and call `make' +to build the groff project. You can do it in the source tree: +.QUOTE +.CODE +$ ./configure +$ make +.CODE OFF +.QUOTE OFF +You can also build groff in an out-of-source build tree, which is +cleaner: +.QUOTE +.CODE +$ mkdir build +$ cd build +$ ../configure +$ make +.CODE OFF +.QUOTE OFF +Parallel build is also supported: `make' can be invoked +with the -j option, which will greatly speed up the build. +. +.HEADING 2 "Automake in the autotools process" +. +.PP +Automake's main job is to generate a Makefile.in file (this file is +maintained manually on projects using only autoconf). The main file +processed by `automake' is the Makefile.am file, which eventually +generates a Makefile. The (simplified) process is: +. +.SP 3p +.QUAD LEFT +.HY OFF +. +.LIST +.SHIFT_LIST 1m +.ITEM +`aclocal' generates the `aclocal.m4' file from `configure.ac' and +the user-defined macros in `acinclude.m4'. +.ITEM +`autoheader' generates config.h.in. +.ITEM +`autoconf' generates the `configure' script from `aclocal.m4' and `configure.ac' +.ITEM +`automake' generates Makefile.in from Makefile.am and the +`configure.ac' file. It also generates some helper scripts, on the +groff project they are located in build-aux. +.ITEM +`configure' generates `config.status' +.ITEM +`config.status' generates the Makefile and config.h. +.LIST OFF +. +.SP 3p +.JUSTIFY +.HY DEFAULT +. +.WS -2 +.RW .16 +Finally, `autoreconf' is the program that can be used to call these +various tools in the correct order. +.RW 0 +.WS DEFAULT +. +.PP +Automake defines a set of special variables that are used to +generate various build rules in the final Makefile. Note however +that if Automake's predefined rules are not enough, you still have +the possibility of adding handwritten standard `make' rules in a +Makefile.am; these rules will be copied verbatim in the Makefile.in +and then in the final Makefile. +. +.HEADING 2 "Modification of autotools files" +. +.PP +Previously, when groff used `autoconf' only and not `automake', +you had to invoke manually the autotools, depending on what you +modified. For example, to change the file `aclocal.m4', you had +to run the shell command `aclocal -I m4'; to recreate the files +`configure' and `Makefile', you had to use the command 'autoreconf +- I m4'. +.PP +Now, as groff uses `automake', you don't need to run `autoreconf'. +If you make some changes in Makefile.am or configure.ac, all the +files that need to be updated will be regenerated when you execute +`make'. +. +.HEADING 1 "Building a program" +. +.HEADING 2 "A program and its source files" +. +.PP +Generally speaking, when using `automake' you will have to write a +Makefile.am file and use the variable \*[CODE]bin_PROGRAMS\*[CODE OFF] +to declare a program that should be built, and then list the +sources of this program in a variable that starts with the name of +your program and ends with \*[CODE]_SOURCES\*[CODE OFF]\&. In the +groff project we have only 1 top-level Makefile.am that includes +several \&.am files. +.PP +Take for example the build of grolbp, in src/devices/grolbp/grolbp.am. +The file starts with: +.QUOTE ADJUST -4p +.CODE +bin_PROGRAMS += grolbp +.CODE OFF +.QUOTE OFF +This says that a program named `grolbp' is added to the list of the +programs that should be built. The variable +\*[CODE]bin_PROGRAMS\*[CODE OFF] is initialized to an empty string in +the top-level Makefile.am, which includes grolbp.am. (We will see later +why we don't write directly +\*[CODE]bin_PROGRAMS\~=\~grolbp\*[CODE OFF] in a Makefile.am in the +grolbp directory.) +.PP +Then, we list the sources of grolbp like this: +.QUOTE ADJUST -4p +.IL 1m +.HI 1m +.CODE +grolbp_SOURCES = \\ +src/devices/grolbp/lbp.cpp \\ +src/devices/grolbp/lbp.h \\ +src/devices/grolbp/charset.h +.CODE OFF +.QUOTE OFF +.ILQ +As you added `grolbp' to \*[CODE]bin_PROGRAMS\*[CODE OFF], +you need to define the sources of grolbp in the variable +\*[CODE]grolbp_SOURCES\*[CODE OFF]\&. If you write in another file +\*[CODE]bin_PROGRAMS += foo\*[CODE OFF] you will list the sources +of `foo' in \*[CODE]foo_SOURCES\*[CODE OFF]\&. +.PP +With these two statements, the resulting generated Makefile +will contain everything that is needed to build, clean, +install and uninstall the `grolbp' binary when invoking the +adequate `make' command. Also, the source files listed in +\*[CODE]grolbp_SOURCES\*[CODE OFF] will automatically be included in +the distribution tarball. That is why the headers are also listed +in \*[CODE]grolbp_SOURCES\*[CODE OFF]: it is not necessary to add +them in order to correctly build `grolbp', but this way the headers +will be distributed. +. +.SP 3p +.QUAD LEFT +.HY OFF +. +.LIST +.SHIFT_LIST 1m +.ITEM +The path to the files are relative to the top-level directory. +.ITEM +The binaries are generated in the top-level build directory. +.ITEM +The \&.o files are generated in the directory where the source files +are located, or, in the case of an out-of-source build tree, in a +directory that is the replication of the source tree directory. +For example if you built groff in a `build' directory, lbp.o +(object file from src/devices/grolbp/lbp.cpp) will be located in +build/src/devices/grolbp/lbp.o. +.LIST OFF +. +.SP 3p +.JUSTIFY +.HY DEFAULT +. +We will also see later the reasons; this is due to the non-recursive +make design. +. +.HEADING 2 "Linking against a library" +. +.PP +To list which libraries grolbp needs to link against, we just write: +.QUOTE +.IL +.HI +.CODE +grolbp_LDADD = $(LIBM) \\ +libdriver.a \\ +libgroff.a \\ +lib/libgnu.a +.CODE OFF +.QUOTE OFF +.ILQ +Again, we use the variable \*[CODE]grolbp_LDADD\*[CODE OFF] because +we added a program named `grolbp'. This will also automatically +set build dependencies between `grolbp' and the libraries it needs: +`libdriver.a' and `libgroff.a', that are convenience libraries built +within the groff project, will be compiled before grolbp. +. +.HEADING 2 "Preprocessor flags" +. +.PP +Preprocessor flags that are common to all the binaries are listed +in the variable \*[CODE]AM_CPPFLAGS\*[CODE OFF] in the top-level +Makefile.am. If a `foo' binary needs specific preprocessor +flags, use \*[CODE]foo_CPPFLAGS\*[CODE OFF], for example, in +src/devices/xditview/xditview.am, extra flags are needed to build +gxditview and are added like this: +.QUOTE +.IL +.HI +.CODE +gxditview_CPPFLAGS = $(AM_CPPFLAGS) $(X_CFLAGS) -Dlint \\ +-I$(top_builddir)/src/devices/xditview +.CODE OFF +.QUOTE OFF +.ILQ +.PP +The use of specific CPPFLAGS changes the name of the generated objects: +the \&.o object files are prefixed with the name of the program. +For example, the \&.o file corresponding to +src/devices/xditview/device.c will be +src/devices/xditview/gxditview-device.o. +. +.HEADING 2 "Cleaning" +. +.PP +You don't need to write rules to clean the programs listed in +\*[CODE]bin_PROGRAMS\*[CODE OFF], `automake' will write them for +you. However, some programs might have generated sources that +should be cleaned. In this case, you have mainly two special +variables to list extra files that should be cleaned: +. +.SP 3p +.QUAD LEFT +.HY OFF +. +.LIST +.SHIFT_LIST 1m +.ITEM +\*[CODE]MOSTLYCLEANFILES\*[CODE OFF] for files that should be +cleaned by `make mostlyclean' +.ITEM +\*[CODE]CLEANFILES\*[CODE OFF ] for files that should be cleaned by +`make clean' +.LIST OFF +. +.JUSTIFY +.HY DEFAULT +.SP 3p +. +There is also the possibility of writing custom rules. We will see +that later. +. +.HEADING 2 "Dependencies" +. +.PP +We have already seen that when linking against a convenience +library, the dependencies are already created by `automake'. +However, some dependencies still need to be manually added, for +example when a source file includes a generated header. In this +case, the easiest way is to add a plain-make dependency. For +example, src/roff/groff/groff.cpp includes defs.h, which is a +generated header. We just add in src/roff/groff/groff.am: +.QUOTE +.CODE +src/roff/groff/groff.$(OBJEXT): defs.h +.CODE OFF +.QUOTE OFF +. +.HEADING 2 "Scripts" +. +.PP +Apart from \*[CODE]bin_PROGRAMS\*[CODE OFF], there is another +similar special variable for scripts: \*[CODE]bin_SCRIPTS\*[CODE OFF]\&. +The scripts listed in this variable will automatically be +built (of course you have to provide your custom rule to build the +script), installed and uninstalled when invoking `make', `make +install' and `make uninstall'. The main difference is that unlike +the programs listed in \*[CODE]bin_PROGRAMS\*[CODE OFF], the scripts +will not be cleaned by default. They are not distributed by default +either. In the groff project, \*[CODE]bin_SCRIPTS\*[CODE OFF] are +cleaned because they are added to \*[CODE]MOSTLYCLEANFILES\*[CODE OFF] +in the top-level Makefile.am. +.PP +A simple example are the gropdf and pdfmom scripts in +src/devices/gropdf/gropdf.am: +.CODE_SIZE 84 +.QUOTE_INDENT 1 +.QUOTE +.CODE +bin_SCRIPTS += gropdf pdfmom + [...] +gropdf: $(gropdf_dir)/gropdf.pl $(SH_DEPS_SED_SCRIPT) + $(AM_V_GEN)$(RM) $@ \\ + sed -f $(SH_DEPS_SED_SCRIPT) \\ + -e "s|[@]VERSION[@]|$(VERSION)|" \\ + -e "s|[@]PERL[@]|$(PERL)|" \\ + -e "s|[@]GROFF_FONT_DIR[@]|$(fontpath)|" \\ + -e "s|[@]RT_SEP[@]|$(RT_SEP)|" $(gropdf_dir)/gropdf.pl \\ + >$@ \ + && chmod +x $@ + +pdfmom: $(gropdf_dir)/pdfmom.pl $(SH_DEPS_SED_SCRIPT) + $(AM_V_GEN)$(RM) $@ \\ + sed -f $(SH_DEPS_SED_SCRIPT) \\ + -e "s|[@]VERSION[@]|$(VERSION)|" \\ + -e "s|[@]RT_SEP[@]|$(RT_SEP)|" \\ + -e "s|[@]PERL[@]|$(PERL)|" $(gropdf_dir)/pdfmom.pl \\ + >$@ + && chmod +x $@ +.QUOTE OFF +.QUOTE_INDENT 2m +.CODE_SIZE 100 +In this example, the `@' symbol is protected by square brackets to +prevent the substitution of the variable by `automake'. +. +.HEADING 1 "Non-recursive make schema" +. +.PP +There are two possibilities for organizing the Makefile.am of a +large project, using a recursive or a non-recursive `make'. +. +.HEADING 2 "1st possibility: make recursion" +. +.PP +A top level Makefile.am includes another Makefile.am, using the +\*[CODE]SUBDIRS\*[CODE OFF] directive, and the Makefile.am of each +sub-directory lists the programs that should be built. If we had +chosen this type of organization, we would have a Makefile.am in +src/devices/grolbp and in each directory that contain sources to +build a program (tbl, eqn, troff, and so on). We would write in the +top-level Makefile.am: +.QUOTE +.IL +.HI +.CODE +SUBDIRS = src/devices/grolbp \\ +\&... (and all the dir that build a program or a script) +.CODE OFF +.QUOTE OFF +and in src/devices/grolbp, we would have a file Makefile.am that +contains: +.QUOTE +.CODE +bin_PROGRAMS = grolbp +grolbp_SOURCES = lbp.cpp lbp.h charset.h +.CODE OFF +.QUOTE OFF +.PP +Only `grolbp' is affected to the variable \*[CODE]bin_PROGRAMS\*[CODE OFF]\&. +It would be the same in, say, src/roff/troff: you would have a Makefile.am +with \*[CODE]bin_PROGRAMS = troff\*[CODE OFF]\&. We would have +one generated Makefile per Makefile.am file: in the build tree +you will have the top-level Makefile, grolbp's Makefile in +src/devices/grolbp, troff's Makefile in src/roff/troff, and so on. +When calling `make' to build everything, `make' will be recursively +called in all the directories that have a Makefile. Thus, the +paths are logically relative to the directory that contains the +Makefile.am. +.PP +This approach has the disadvantage of making dependencies harder +to resolve: each Makefile does not know the targets of the other +Makfiles. It also makes the build slower. +. +.HEADING 2 "Non-recursive make used by the Groff project" +. +.PP +The second possibility, which was chosen for the groff project, is to use +a non-recursive make schema. It is described in paragraph 7.3 of +the Automake manual ("An Alternative Approach to Subdirectories"), +based on the following paper from Peter Miller: +.PDF_WWW_LINK http://miller.emu.id.au/pmiller/books/rmch/ \ + SUFFIX . "\*[IT]Recursive Make Considered Harmful\*[PREV]" +.PP +The idea is to have a single Makefile that contains all the rules. +That is why we have only a single Makefile.am in the top-level +directory which includes all the \&.am files that define rules +to build the various programs. The inclusion is done with the +\*[CODE]include\*[CODE OFF] directive, not \*[CODE]SUBDIRS\*[CODE OFF]\&. +Using `include' is like copying the contents of the included +file into the top-level Makefile.am, and will not generate other +Makefile. +.PP +We first say in this top-level Makefile.am: +.QUOTE +.CODE +bin_PROGAMS = +.CODE OFF +.QUOTE OFF +and then all the \&.am files that define a program to be built (e.g. +src/devices/grolbp/grolbp.am, src/roff/troff/troff.am, and so on) +overload this variable, so that at the end, all the programs that +should be built are listed in this \*[CODE]bin_PROGRAMS\*[CODE OFF] +variable. This is the reason why all the paths in the various \&.am +files are relative to the top-level directory: at the end we will +have only one Makefile in the top-level directory of the build tree. +.PP +As the resulting single Makefile knows all the targets, the +dependencies are easier to manage. The build is also faster, +particularly when compiling a single file: `make' is called once only +and the file will be instantly rebuilt, while on a recursive make +system, `make' will have to be invoked in all the sub-directories. +.PP +Note also that in order to make `gnulib' work with this +non-recursive schema, the `--automake-subdir' +configuration should be selected in bootstrap.conf. +. +.HEADING 1 "Installing data" +. +.PP +Variables that end with \*[CODE]_DATA\*[CODE OFF] are special +variables used to list files that should be installed in a +particular location. The prefix of the variables should refer to +another previously defined variable that ends with a `dir' suffix. +This variable that ends with `dir' defines where the files should be +installed. +. +.HEADING 2 "A simple case" +. +.PP +For example, in font/devX100/devX100.am, we can see this: +.QUOTE +.CODE +if !WITHOUT_X11 +devX100fontdir = $(fontdir)/devX100 +devX100font_DATA = $(DEVX100FONTS) +endif +.SP +EXTRA_DIST += $(DEVX100FONTS) +.CODE OFF +.QUOTE OFF +.WS -4 +\*[CODE]DEVX100FONTS\*[CODE OFF] is just a list of font files, +defined at the beginning of devX100.am. \*[CODE]fontdir\*[CODE OFF] +is where all the font directories are installed, it is defined +in the top-level Makefile.am. The conditional +\*[CODE]if\~!WITHOUT_X11\*[CODE OFF] +is used to prevent the installation of +these files if X11 is not available. +.WS DEFAULT +.PP +We first define where we wants to install the devX100 fonts with: +.QUOTE +.CODE +devX100fontdir = $(fontdir)/devX100 +.CODE OFF +.QUOTE OFF +Because we declared a variable ending with `dir', we are allowed +to define \*[CODE]devX100font_DATA\*[CODE OFF] (you remove the +`dir' suffix and add \*[CODE]_DATA\*[CODE OFF]). Wildcards are not +supported in the special variables that end with +\*[CODE]_DATA\*[CODE OFF]\&. +.PP +With these two lines, `make install' will install the files +listed in \*[CODE]DEVX100FONTS\*[CODE OFF] and `make uninstall' +will uninstall them. \*[CODE]devX100fontdir\*[CODE OFF] will be +automatically created if missing during the installation +process, but not removed during the uninstall. The complete +\*[CODE]fontdir\*[CODE OFF] is removed by a custom uninstall rule +(uninstall_groffdirs in Makefile.am). +.PP +Because the files listed in \*[CODE]devX100font_DATA\*[CODE OFF] +are not distributed by default, we explicitly added them to the +\*[CODE]EXTRA_DIST\*[CODE OFF] variable, which lists all the files +that should be distributed and that are not taken into account by +the default automake rules. +.QUOTE +.CODE + EXTRA_DIST += $(DEVX100FONTS) +.CODE OFF +.QUOTE OFF +Another possibility would have been to add a `dist' prefix to the +\*[CODE]devX100font_DATA\*[CODE OFF] variable, in this case the use +of \*[CODE]EXTRA_DIST\*[CODE OFF] is useless (except of course if +\*[CODE]WITHOUT_X11\*[CODE OFF] is true, in this case we don't +install the files but we still have to distribute them): +.QUOTE +.CODE +if !WITHOUT_X11 +devX100fontdir = $(fontdir)/devX100 +dist_devX100font_DATA = $(DEVX100FONTS) +else +EXTRA_DIST += $(DEVX100FONTS) +endif +.CODE OFF +.QUOTE OFF +. +.HEADING 2 "Dealing with generated files" +. +.PP +In the previous example, all the font files that must be installed +were already present in the source tree. But in some cases, +you need to generate the files you intend to install. In this +case, the files should be installed but not distributed. A +simple way to deal with this is to add a `nodist' prefix to your +\*[CODE]xxx_DATA\*[CODE OFF] variable. +.PP +For example in font/devps/devps.am, we have a list of +font files already present in the source tree, defined +by \*[CODE]DEVPSFONTFILES\*[CODE OFF], and another list +of font files that are generated, listed in the variable +\*[CODE]DEVPSFONTFILES_GENERATED\*[CODE OFF]\&. They should all +by installed in a `devps' directory under the fontdir. Thus +the following three lines, where we use the `dist' and `nodist' +prefixes: +.QUOTE +.CODE +devpsfontdir = $(fontdir)/devps +dist_devpsfont_DATA = $(DEVPSFONTFILES) +nodist_devpsfont_DATA = $(DEVPSFONTFILES_GENERATED) +.CODE OFF +.QUOTE OFF +The generated files are not cleaned by default, thus we add: +.QUOTE +.CODE +MOSTLYCLEANFILES += $(DEVPSFONTFILES_GENERATED) +.CODE OFF +.QUOTE OFF +. +.HEADING 1 "Extending Automake's rules" +. +.HEADING 2 "Local clean rules" +. +.PP +In most of the cases, the files that need to be cleaned are +automatically determined by `automake', or were added to the +\*[CODE]MOSTCLEANFILES\*[CODE OFF] or \*[CODE]CLEANFILES\*[CODE OFF] +variables. However, you might need to define a specific rule +to clean some files that were not added to any list. Automake +defines a set of targets to extend the clean targets with your +own rules: clean-local, mostlyclean-local, distclean-local or +maintainerclean-local. An example of such extension exists in +font/devpdf/devpdf.am: because some fonts are not explicitly listed +in a \*[CODE]xxx_DATA\*[CODE OFF] variable but generated by a custom +rule, we define an extra rule to extend the `mostlyclean' target: +.CODE_SIZE 92 +.QUOTE +.CODE +mostlyclean-local: mostlyclean_devpdf_extra +mostlyclean_devpdf_extra: + @echo Cleaning font/devpdf + rm -rf $(top_builddir)/font/devpdf/enc \\ + $(top_builddir)/font/devpdf/map; + if test -d $(top_builddir)/font/devpdf; then \\ + for f in $(GROFF_FONT_FILES); do \\ + rm -f $(top_builddir)/font/devpdf/$$f; \\ + done; \\ + fi +.CODE OFF +.QUOTE OFF +. +.NO_FLEX OFF \" Prevent upcoming NEWPAGE from disabling flex-spacing. +.HEADING 2 "Local install/uninstall rules and hooks" +. +.PP +Similarly to the clean rules, there are extensions to install and +uninstall rules. They come with two flavous, local rules and hooks. +. +.SP 3p +.QUAD LEFT +.HY OFF +. +.LIST +.SHIFT_LIST 1m +.ITEM +There are 2 rules to extend install commands: `install-exec-local' +for binaries and `install-data-local' for data. +.ITEM +There is 1 uninstall local rule: `uninstall-local'. +.LIST OFF +. +.SP 3p +.JUSTIFY +.HY DEFAULT +. +There are no guarantees on the order of execution of these local +rules. An example of local rule is the installation of GXditview.ad +and GXditview-color.ad files in src/devices/xditview/xditview.am: if +theses files are already installed, the old files are first saved. +Also, the final file that is installed is stripped from its \&.ad +suffix. Thus the usage of a custom rule rather than the definition +of a \*[CODE]xxx_DATA\*[CODE OFF] variable: +.FLEX +.QUOTE +.CODE +# Custom installation of GXditview.ad and GXditview-color.ad +install-data-local: install_xditview +uninstall-local: uninstall_xditview +.SP +[...] +install_xditview: $(xditview_srcdir)/GXditview.ad + -test -d $(DESTDIR)$(appdefdir) \\ + || $(mkinstalldirs) $(DESTDIR)$(appdefdir) + if test -f $(DESTDIR)$(appdefdir)/GXditview; then \\ + mv $(DESTDIR)$(appdefdir)/GXditview \\ + $(DESTDIR)$(appdefdir)/GXditview.old; \\ + fi + [...] + $(INSTALL_DATA) $(xditview_srcdir)/GXditview.ad \\ + $(DESTDIR)$(appdefdir)/GXditview +.CODE OFF +.QUOTE OFF +.PP +Hooks, on the other hand, are guaranteed to be executed after all the +standard targets have been executed. +.BR +.SP 3p +.QUAD LEFT +.HY OFF +. +.LIST +.SHIFT_LIST 1m +.SP 3p +.ITEM +There are 2 install hooks: `install-exec-hook' and +`install-data-hook'. +.ITEM +There is 1 uninstall hook: `unintall-hook' +.LIST OFF +. +.SP 3p +.JUSTIFY +.HY DEFAULT +. +.PP +An example of hook is the `uninstall_groffdirs' rule in the +top-level Makefile.am. This hook is used to remove all the +directories specific to groff introduced by the installation +process. Obviously it could not be a local extension of `uninstall' +because the order of execution is not guaranteed. +.QUOTE +.CODE +# directories specific to groff +uninstall-hook: uninstall_groffdirs +uninstall_groffdirs: + if test -d $(DESTDIR)$(datasubdir); then \\ + rm -rf $(DESTDIR)$(fontdir); \\ + rm -rf $(DESTDIR)$(oldfontdir); \\ + rmdir $(DESTDIR)$(datasubdir); \\ + fi + [...] +.CODE OFF +.QUOTE OFF +.TOC +.\" Local Variables: +.\" mode: nroff +.\" End: +.\" vim: filetype=groff: diff --git a/doc/doc.am b/doc/doc.am new file mode 100644 index 0000000..cddc519 --- /dev/null +++ b/doc/doc.am @@ -0,0 +1,711 @@ +# Copyright (C) 2002-2022 Free Software Foundation, Inc. +# Original Makefile.sub written by Werner Lemberg <wl@gnu.org>. +# Adapted to Automake by Bertrand Garrigues +# (bertrand.garrigues@laposte.net). +# +# This file 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/>. + +doc_srcdir = $(abs_top_srcdir)/doc +doc_builddir = $(abs_top_builddir)/doc + +# Some document sources are parameterized in configuration options like +# the groff version number and the command prefix. Use this in target +# rules to prepare formattable versions of them from .in files. +DOC_SED = $(SED) \ + -e "s;[@]VERSION[@];$(VERSION);" \ + -e "s;[@]g[@];$(g);g;" + +# Use this in target rules to run the build tree's groff. +# +# It includes flags to locate its tmac and device/font description +# directories and to produce verbose diagnostics in the event of syntax +# or formatting problems. +DOC_GROFF = \ + GROFF_COMMAND_PREFIX= \ + GROFF_BIN_PATH="$(GROFF_BIN_PATH)" \ + $(GROFFBIN) -M $(doc_srcdir) $(MFLAG) $(FFLAG) -ww -b + +# This image file is used by several documents in the groff source tree. +DOC_GNU_EPS = doc/gnu.eps + +# Other doc, installed in $(docdir) +# Files located in the source tree +DOCFILES_INST = \ + doc/me-revisions \ + doc/ms.ms \ + doc/pic.ms +DOCFILES_NOINST = \ + doc/meintro.me.in \ + doc/meintro_fr.me.in \ + doc/meref.me.in +# Files that undergo a transformation prior to groff processing +GENERATEDDOCFILES = \ + doc/meintro.me \ + doc/meintro_fr.me \ + doc/meref.me +# Files generated in the build tree +if USE_GROHTML +PROCESSEDDOCFILES_HTML = \ + doc/pic.html +endif +if USE_GROPDF +PROCESSEDDOCFILES_PDF = \ + doc/automake.pdf \ + doc/groff-man-pages.pdf +endif +PROCESSEDDOCFILES_PS = \ + doc/meref.ps \ + doc/meintro.ps \ + doc/meintro_fr.ps \ + doc/ms.ps \ + doc/pic.ps +PROCESSEDDOCFILES_TXT = \ + doc/groff-man-pages.utf8.txt +PROCESSEDDOCFILES = \ + $(PROCESSEDDOCFILES_HTML) \ + $(PROCESSEDDOCFILES_PS) \ + $(PROCESSEDDOCFILES_PDF) \ + $(PROCESSEDDOCFILES_TXT) + +# Declare minimal dependencies for documents by output driver. +PROCESSEDFILES_DEPS_HTML = pre-grohtml groff troff post-grohtml \ + font/devhtml/stamp font/devps/stamp +PROCESSEDFILES_DEPS_PS = groff troff grops font/devps/stamp +PROCESSEDFILES_DEPS_PDF = groff troff gropdf font/devpdf/stamp +PROCESSEDFILES_DEPS_TXT = groff troff grotty font/devutf8/stamp + +if USE_GROHTML +$(PROCESSEDDOCFILES_HTML): $(PROCESSEDFILES_DEPS_HTML) +endif +$(PROCESSEDDOCFILES_PS): $(PROCESSEDFILES_DEPS_PS) +if USE_GROPDF +$(PROCESSEDDOCFILES_PDF): $(PROCESSEDFILES_DEPS_PDF) +endif +$(PROCESSEDDOCFILES_TXT): $(PROCESSEDFILES_DEPS_TXT) + +otherdocdir = $(docdir) +dist_otherdoc_DATA = $(DOCFILES_INST) +nodist_otherdoc_DATA = $(PROCESSEDDOCFILES) $(GENERATEDDOCFILES) +MOSTLYCLEANFILES += $(GENERATEDDOCFILES) $(PROCESSEDDOCFILES) +EXTRA_DIST += $(DOCFILES_NOINST) + +# pdf doc, written in mom and therefore using contrib/mom/mom.am +# definitions +EXTRA_DIST += doc/automake.mom +if USE_GROPDF +docpdfdocdir = $(pdfdocdir) +nodist_docpdfdoc_DATA = doc/automake.pdf +endif +doc/automake.pdf: doc/automake.mom pdfmom contrib/mom/om.tmac + +# GNU PIC html documentation, installed in $(htmldocdir) +# Other pic*.html files are installed by the local rule +if USE_GROHTML +htmlpicdir = $(htmldocdir) +htmlpic_DATA = $(PROCESSEDDOCFILES_HTML) +HTMLDOCFILESALL = pic*.html +HTMLDOCIMAGEFILES = pic* +endif + +# Examples files, installed in $(exampledir) + +# source tree files +EXAMPLEFILES = \ + doc/webpage.ms \ + doc/groff.css \ + doc/grnexmpl.g \ + doc/grnexmpl.me + +# Generated in the build tree +if USE_GROHTML +PROCESSEDEXAMPLEFILES_HTML = doc/webpage.html +else +PROCESSEDEXAMPLEFILES_HTML = +endif +PROCESSEDEXAMPLEFILES_PS = \ + doc/webpage.ps \ + doc/grnexmpl.ps +PROCESSEDEXAMPLEFILES = \ + $(PROCESSEDEXAMPLEFILES_HTML) \ + $(PROCESSEDEXAMPLEFILES_PS) + +$(PROCESSEDEXAMPLEFILES_HTML): $(PROCESSEDFILES_DEPS_HTML) +$(PROCESSEDEXAMPLEFILES_PS): $(PROCESSEDFILES_DEPS_PS) + +docexamplesdir = $(exampledir) +dist_docexamples_DATA = $(EXAMPLEFILES) +nodist_docexamples_DATA = $(PROCESSEDEXAMPLEFILES) +MOSTLYCLEANFILES += $(PROCESSEDEXAMPLEFILES) + +if USE_GROHTML +# webpage.html is generated; webpage*.html files are installed by the +# local rule. +HTMLEXAMPLEFILESALL = webpage*.html +HTMLEXAMPLEIMAGEFILES = webpage* +htmlexamplesdir = $(exampledir) +endif + +# Locate image subdirectory for HTML documents relative to an +# installation directory such as `htmldocdir` or `exampledir`. Do _not_ +# use for locating files within the source or build trees. +imagedir = img + +EXTRA_DIST += \ + doc/txi-en.tex + +# Introduce variables to house the groff man pages. We break the list +# of page sources into multiple chunks because we have to load Swedish +# localization before formatting groff_mmse.7 and then reload English +# localization afterward. This also serves as a test of groff locale +# switching; being lazy and shunting groff_mmse.7 off to the end of the +# document would not achieve this goal (and not loading Swedish +# localization at all to format it would be gauche). +GROFF_MAN_PAGES1 = \ + src/utils/addftinfo/addftinfo.1 \ + src/utils/afmtodit/afmtodit.1 \ + contrib/chem/chem.1 \ + src/preproc/eqn/eqn.1 \ + contrib/eqn2graph/eqn2graph.1 \ + contrib/gdiffmk/gdiffmk.1 \ + contrib/glilypond/glilypond.1 \ + contrib/gperl/gperl.1 \ + contrib/gpinyin/gpinyin.1 \ + contrib/grap2graph/grap2graph.1 \ + src/preproc/grn/grn.1 \ + src/devices/grodvi/grodvi.1 \ + src/roff/groff/groff.1 \ + src/utils/grog/grog.1 \ + src/devices/grohtml/grohtml.1 \ + src/devices/grolbp/grolbp.1 \ + src/devices/grolj4/grolj4.1 \ + src/devices/gropdf/gropdf.1 \ + src/devices/grops/grops.1 \ + src/devices/grotty/grotty.1 \ + $(GXDITVIEW_MAN1) \ + src/utils/hpftodit/hpftodit.1 \ + src/utils/indxbib/indxbib.1 \ + src/utils/lkbib/lkbib.1 \ + src/utils/lookbib/lookbib.1 \ + contrib/mm/mmroff.1 \ + src/preproc/eqn/neqn.1 \ + src/roff/nroff/nroff.1 \ + src/devices/gropdf/pdfmom.1 \ + contrib/pdfmark/pdfroff.1 \ + src/utils/pfbtops/pfbtops.1 \ + src/preproc/pic/pic.1 \ + contrib/pic2graph/pic2graph.1 \ + src/preproc/preconv/preconv.1 \ + src/preproc/refer/refer.1 \ + src/preproc/soelim/soelim.1 \ + src/preproc/tbl/tbl.1 \ + src/utils/tfmtodit/tfmtodit.1 \ + src/roff/troff/troff.1 \ + $(XTOTROFF_MAN1) \ + man/groff_font.5 \ + man/groff_out.5 \ + man/groff_tmac.5 \ + man/groff.7 \ + man/groff_char.7 \ + man/groff_diff.7 \ + contrib/hdtbl/groff_hdtbl.7 \ + tmac/groff_man.7 \ + tmac/groff_man_style.7 \ + tmac/groff_mdoc.7 \ + tmac/groff_me.7 \ + contrib/mm/groff_mm.7 + +GROFF_MAN_PAGES2 = \ + contrib/mm/groff_mmse.7 + +GROFF_MAN_PAGES3 = \ + contrib/mom/groff_mom.7 \ + tmac/groff_ms.7 \ + contrib/rfc1345/groff_rfc1345.7 \ + tmac/groff_trace.7 \ + tmac/groff_www.7 \ + man/roff.7 + +GROFF_MAN_PAGES_ALL = $(GROFF_MAN_PAGES1) $(GROFF_MAN_PAGES2) \ + $(GROFF_MAN_PAGES3) + +# This is a convenience target for (re-)generating all the man pages. +man-all: $(GROFF_MAN_PAGES_ALL) + +# ...and for cleaning them. +man-clean: + $(RM) $(GROFF_MAN_PAGES_ALL) + +# Many pages use tbl, a few use eqn, and soelim(1) uses pic. We also +# need groff's FreeEuro font so we can embed it. +# +# We embed the fonts (-P-e) to (1) honor the current PDF standard, (2) +# ensure consistent rendering of the document, and (3) exercise this +# feature of gropdf. +doc/groff-man-pages.pdf: $(GROFF_MAN_PAGES_ALL) eqn pic tbl \ + $(TMAC_PACKAGE_MAN) $(TMAC_PACKAGE_MDOC) font/devps/freeeuro.pfa + $(GROFF_V)$(DOC_GROFF) -pet -mandoc -dHF=HB -rC1 \ + -rCHECKSTYLE=3 -Tpdf -P-e \ + $(GROFF_MAN_PAGES1) \ + $(tmac_srcdir)/sv.tmac $(GROFF_MAN_PAGES2) \ + $(tmac_srcdir)/en.tmac $(GROFF_MAN_PAGES3) > $@ + +doc/groff-man-pages.utf8.txt: $(GROFF_MAN_PAGES_ALL) eqn pic tbl \ + $(TMAC_PACKAGE_MAN) $(TMAC_PACKAGE_MDOC) + $(GROFF_V)$(DOC_GROFF) -pet -Tutf8 -mandoc \ + -rCHECKSTYLE=3 $(GROFF_MAN_PAGES1) \ + $(tmac_srcdir)/sv.tmac $(GROFF_MAN_PAGES2) \ + $(tmac_srcdir)/en.tmac $(GROFF_MAN_PAGES3) > $@ + +doc/grnexmpl.ps: $(doc_srcdir)/grnexmpl.me $(doc_srcdir)/grnexmpl.g \ + grn eqn + $(GROFF_V)$(MKDIR_P) `dirname $@` \ + && $(DOC_GROFF) -Tps -ge -me $(doc_srcdir)/grnexmpl.me >$@ + +# Generating *.me from *.me.in is, surprisingly, a challenge. +# 1. A pattern rule ("%.me: %.me.in") is not portable to NetBSD or +# OpenBSD make. +# 2. A single-suffix rule works in an isolated Makefile, but _only_ +# with the .SUFFIXES special target, not with the +# (Automake-specific) SUFFIXES macro. +# .SUFFIXES: .in +# .in: +# $(DOC_SED) $< >$@ +# (One can validly complain that this approach is too general.) +# 3. GNU Automake insists that we use the SUFFIXES macro and not the +# special target. +# error: use variable 'SUFFIXES', not target '.SUFFIXES' +# 4. What about a target rule? We'd have to explicitly write the first +# dependency name in the rule commands because NetBSD make (and +# reportedly OpenBSD) refuses to honor the $< variable in target +# rules. +# +# So what is left? A double-suffix rule--but you have to use it in a +# special way that is explicitly not countenanced by POSIX. +# +# "The application shall ensure that the target portion is a valid +# target name (see Target Rules) of the form .s2 or .s1.s2 (where .s1 +# and .s2 are suffixes that have been given as prerequisites of the +# .SUFFIXES special target and s1 and s2 do not contain any <slash> or +# <period> characters.) If there is only one <period> in the target, +# it is a single-suffix inference rule. Targets with two periods are +# double-suffix inference rules. Inference rules can have only one +# target before the <colon>." +# (POSIX Issue 8, make(1), "Inference Rules") +# +# A double-suffix rule won't work in an obvious way because its +# semantics are that the suffix is replaced, not removed. You have to +# add both suffixes to the .SUFFIXES special target, in order with the +# dependency first. +# .SUFFIXES: .me.in .me +# .me.in.me: +# $(DOC_SED) $< >$@ +# Thanks to Automake, we must say +# SUFFIXES += .me.in .me +# for reason 3 above. The GNU Automake manual does not explicitly state +# that it preserves the ordering of the suffixes, but for now it does. +# +# It appears to be dumb luck that this works; the rigamarole by itself +# justifies to me the worth of GNU Make's pattern rules (which require +# neither '.SUFFIXES' nor 'SUFFIXES') and establishing semantics for $< +# in target rules. But I won't hold my breath waiting on other make(1) +# implementors to agree. -- GBR +.PRECIOUS: $(GENERATEDDOCFILES) +SUFFIXES += .me.in .me +.me.in.me: + $(GROFF_V)$(MKDIR_P) `dirname $@` \ + && $(DOC_SED) $< >$@ + +.me.ps: + $(GROFF_V)$(MKDIR_P) `dirname $@` \ + && $(DOC_GROFF) -Tps -me $< >$@ + +# Use '-K utf8', not '-k', in case 'configure' didn't find uchardet. +# The French translation uses tbl; its English counterpart does not. +doc/meintro_fr.ps: doc/meintro_fr.me preconv + $(GROFF_V)$(MKDIR_P) `dirname $@` \ + && $(DOC_GROFF) -K utf8 -t -Tps -me -mfr $< >$@ + +doc/ms.ps: $(doc_srcdir)/ms.ms eqn tbl + $(GROFF_V)$(MKDIR_P) `dirname $@` \ + && $(DOC_GROFF) -et -Tps -ms $(doc_srcdir)/ms.ms >$@ + +doc/pic.ps: $(doc_srcdir)/pic.ms eqn pic tbl + $(GROFF_V)$(MKDIR_P) `dirname $@` \ + && $(DOC_GROFF) -pet -Tps -ms $(doc_srcdir)/pic.ms >$@ + +doc/webpage.ps: $(DOC_GNU_EPS) tmac/www.tmac tbl +doc/webpage.ps: $(doc_srcdir)/webpage.ms + $(GROFF_V)$(MKDIR_P) `dirname $@` \ + && $(DOC_GROFF) -I $(doc_srcdir) -I $(doc_builddir) -t -Tps \ + -ms -mwww $(doc_srcdir)/webpage.ms >$@ + +# We have no "generic" ms documents. +#.ms.ps: +# $(GROFF_V)$(MKDIR_P) `dirname $@` \ +# && $(DOC_GROFF) -Tps -ms $< >$@ + +doc/pic.html: eqn pic tbl +doc/pic.html: tmac/www.tmac +doc/pic.html: $(doc_srcdir)/pic.ms + $(GROFF_V)$(MKDIR_P) $(doc_builddir) \ + && cd $(doc_builddir) \ + && $(DOC_GROFF) -pet -P-Ipic -P-Dimg -P-jpic -Thtml -ms \ + $(doc_srcdir)/pic.ms > pic.html + +doc/webpage.html: tbl +doc/webpage.html: tmac/www.tmac +doc/webpage.html: $(DOC_GNU_EPS) +doc/webpage.html: $(doc_srcdir)/groff.css +doc/webpage.html: $(doc_srcdir)/webpage.ms + $(GROFF_V)$(MKDIR_P) $(doc_builddir) \ + && cd $(doc_builddir) \ + && $(DOC_GROFF) -t -I $(doc_srcdir) -P-jwebpage -P-nrb \ + -P-Iwebpage -P-Dimg -Thtml -ms $(doc_srcdir)/webpage.ms \ + > webpage.html + +# We remove groff.css only from an out-of-source build tree. +mostlyclean-local: mostlyclean_doc +mostlyclean_doc: +if USE_GROHTML + if test -d $(doc_builddir); then \ + cd $(doc_builddir) \ + && for f in $(HTMLDOCFILESALL); do \ + $(RM) $$f; \ + done; \ + fi + if test -d $(doc_builddir)/img; then \ + cd $(doc_builddir)/img \ + && for f in $(HTMLDOCIMAGEFILES); do \ + $(RM) $$f; \ + done; \ + rmdir $(doc_builddir)/img || :; \ + fi +endif + if test $(top_builddir) != $(top_srcdir); then \ + $(RM) $(top_builddir)/doc/groff.css; \ + fi +if USE_GROHTML + if test -d $(doc_builddir); then \ + cd $(doc_builddir) \ + && for f in $(HTMLEXAMPLEFILESALL); do \ + $(RM) $$f; \ + done; \ + fi + if test -d $(doc_builddir)/img; then \ + cd $(doc_builddir)/img \ + && for f in $(HTMLEXAMPLEIMAGEFILES); do \ + $(RM) $$f; \ + done; \ + rmdir $(doc_builddir)/img || :; \ + fi +endif + +install-data-hook: install_doc_htmldoc +install_doc_htmldoc: +if USE_GROHTML + cd $(doc_builddir) \ + && for f in `ls $(HTMLDOCFILESALL)`; do \ + $(RM) $(DESTDIR)$(htmldocdir)/$$f; \ + $(INSTALL_DATA) $$f $(DESTDIR)$(htmldocdir)/$$f; \ + done + -test -d $(DESTDIR)$(htmldocdir)/$(imagedir) \ + || $(mkinstalldirs) $(DESTDIR)$(htmldocdir)/$(imagedir) + $(RM) $(DESTDIR)$(htmldocdir)/$(imagedir)/$(HTMLDOCIMAGEFILES) + $(INSTALL_DATA) $(doc_builddir)/img/$(HTMLDOCIMAGEFILES) \ + $(DESTDIR)$(htmldocdir)/$(imagedir) +endif + +install-data-hook: install_doc_gnu_eps install_doc_examples + +install_doc_gnu_eps: $(DOC_GNU_EPS) + for d in $(doc_builddir) $(doc_srcdir); do \ + if test -f "$$d/gnu.eps"; then \ + $(RM) $(DESTDIR)$(exampledir)/gnu.eps; \ + $(INSTALL_DATA) \ + $$d/gnu.eps $(DESTDIR)$(exampledir)/gnu.eps; \ + break; \ + fi; \ + done + +install_doc_examples: $(DOC_GNU_EPS) +if USE_GROHTML + cd $(doc_builddir) \ + && for f in `ls $(HTMLEXAMPLEFILESALL)`; do \ + $(RM) $(DESTDIR)$(exampledir)/$$f; \ + $(INSTALL_DATA) $$f $(DESTDIR)$(exampledir)/$$f; \ + done + -test -d $(DESTDIR)$(exampledir)/$(imagedir) \ + || $(mkinstalldirs) $(DESTDIR)$(exampledir)/$(imagedir) + $(RM) \ + $(DESTDIR)$(exampledir)/$(imagedir)/$(HTMLEXAMPLEIMAGEFILES) + $(INSTALL_DATA) $(doc_builddir)/img/$(HTMLEXAMPLEIMAGEFILES) \ + $(DESTDIR)$(exampledir)/$(imagedir) +endif + +uninstall-hook: \ + uninstall_doc_examples uninstall_doc_htmldoc +uninstall_doc_examples: + $(RM) $(DESTDIR)$(exampledir)/gnu.eps +if USE_GROHTML + -test -d $(DESTDIR)$(docexamplesdir) \ + && cd $(DESTDIR)$(docexamplesdir) \ + && for f in $(HTMLEXAMPLEFILESALL); do \ + $(RM) $$f; \ + done + -test -d $(DESTDIR)$(docexamplesdir)/$(imagedir) \ + && cd $(DESTDIR)$(docexamplesdir)/$(imagedir) \ + && for f in $(HTMLEXAMPLEIMAGEFILES); do \ + $(RM) $$f; \ + done + -rmdir $(DESTDIR)$(docexamplesdir)/$(imagedir) + -rmdir $(DESTDIR)$(docexamplesdir) +endif + +uninstall_doc_htmldoc: +if USE_GROHTML + -test -d $(DESTDIR)$(htmldocdir) \ + && cd $(DESTDIR)$(htmldocdir) \ + && for f in $(HTMLDOCFILESALL); do \ + $(RM) $$f; \ + done + -test -d $(DESTDIR)$(htmldocdir)/$(imagedir) \ + && cd $(DESTDIR)$(htmldocdir)/$(imagedir) \ + && for f in $(HTMLDOCIMAGEFILES); do \ + $(RM) $$f; \ + done + -rmdir $(DESTDIR)$(htmldocdir)/$(imagedir) + -rmdir $(DESTDIR)$(htmldocdir) +endif + +# groff Texinfo manual +# +# We produce all possible formats by by default and ship them in the +# distribution archive ('make dist') so that people don't need to have +# 'makeinfo' or TeX available. +# +# The GNU info, plain text, and HTML formats require only 'makeinfo'. +# +# DVI and PDF require a working TeX installation. We can't use +# Automake's facilities for PDF production because its 'dist' target +# attempts to generate 'groff.pdf' by invoking 'texi2dvi' without the +# '-E' option (use 'makeinfo' to expand macros), which is needed to +# build this file. 'texi2dvi' honors the 'MAKEINFO' environment +# variable. +# +# Were the foregoing not true, we would simply say this: +#info_TEXINFOS = doc/groff.texi +#doc_groff_TEXINFOS = doc/fdl.texi + +if USE_TEX +GROFF_DVI = doc/groff.dvi +GROFF_PDF = doc/groff.pdf +endif + +all: doc/groff.info doc/groff.txt doc/groff.html $(GROFF_DVI) \ + $(GROFF_PDF) + +# Distribute the manual in source form as well. +EXTRA_DIST += doc/groff.texi doc/fdl.texi + +EXTRA_DIST += doc/groff.info +MAINTAINERCLEANFILES += doc/groff.info +doc/groff.info: $(doc_srcdir)/groff.texi + $(AM_V_at)$(MKDIR_P) $(doc_builddir) + $(AM_V_GEN)LANG=C \ + LC_ALL=C \ + $(MAKEINFO) -o doc/groff.info --enable-encoding \ + -I $(doc_srcdir) $(doc_srcdir)/groff.texi + +# Distribute the Info files. +dist-hook: dist-info-bits +dist-info-bits: + chmod u+w $(distdir)/doc + for d in $(doc_builddir) $(doc_srcdir); do \ + if [ -f "$$d"/groff.info ]; then \ + cp -f "$$d"/groff.info-* $(distdir)/doc; \ + break; \ + fi; \ + done + +EXTRA_DIST += doc/groff.txt +MAINTAINERCLEANFILES += doc/groff.txt +.texi.txt: + $(AM_V_at)$(MKDIR_P) $(doc_builddir) + $(AM_V_GEN)LANG=C \ + LC_ALL=C \ + $(MAKEINFO) --enable-encoding -I $(doc_srcdir) --plaintext \ + -o $@ $< + +# Generate HTML, both split into several files, and as a single file. +# 'html' and its installation counterpart 'install-html' are standard +# Automake targets. +EXTRA_DIST += doc/groff.html doc/groff.html.node +MAINTAINERCLEANFILES += doc/groff.html doc/groff.html.node +.texi.html: + $(AM_V_at)$(MKDIR_P) $(doc_builddir)/ + $(AM_V_GEN)LANG=C \ + LC_ALL=C \ + $(MAKEINFO) --html -I $(doc_srcdir) \ + -o doc/`basename $@`.node $< + $(AM_V_at)LANG=C \ + LC_ALL=C \ + $(MAKEINFO) --html -I $(doc_srcdir) --no-split \ + -o $@ $< + +EXTRA_DIST += doc/groff.dvi doc/groff.pdf + +# Define pattern rules to make our Texinfo manual in DVI and PDF +# formats. 'pdf' and 'dvi' and their installation counterparts +# 'install-pdf' and 'install-dvi' are standard Automake targets. +.texi.dvi: +if HAVE_TEXI2DVI +if USE_TEX + $(AM_V_at)$(MKDIR_P) $(doc_builddir) + $(AM_V_GEN)LANG=C \ + LC_ALL=C \ + TEXINPUTS="$(top_srcdir)/build-aux:$(TEXINPUTS)" \ + MAKEINFO='$(MAKEINFO) -I $(doc_srcdir)' \ + FORCE_SOURCE_DATE=1 \ + $(PROG_TEXI2DVI) -e --batch --build-dir=doc/`basename $@`.t2d \ + -o $@ $< +else + @echo "program 'tex' is missing; cannot generate $@" >&2; \ + exit 1 +endif # USE_TEX +else + @echo "program 'texi2dvi' is missing or too old;" \ + "cannot generate $@" >&2; \ + exit 1 +endif # HAVE_TEXI2DVI + +.texi.pdf: +if HAVE_TEXI2DVI +if USE_TEX + $(AM_V_at)$(MKDIR_P) $(doc_builddir) + $(AM_V_GEN)LANG=C \ + LC_ALL=C \ + TEXINPUTS="$(top_srcdir)/build-aux:$(TEXINPUTS)" \ + MAKEINFO='$(MAKEINFO) -I $(doc_srcdir)' \ + $(PROG_TEXI2DVI) -e --batch --pdf \ + --build-dir=doc/`basename $@`.t2p -o $@ $< +else + @echo "program 'tex' is missing; cannot generate $@" >&2; \ + exit 1 +endif # USE_TEX +else + @echo "program 'texi2dvi' is missing or too old;" \ + "cannot generate $@" >&2; \ + exit 1 +endif # HAVE_TEXI2DVI + +install-doc: install-dvi install-html install-pdf + +maintainer-clean-local: + $(RM) $(doc_builddir)/groff.info* + $(RM) $(doc_builddir)/groff.pdf + $(RM) $(doc_builddir)/groff.dvi + $(RM) $(doc_builddir)/groff.txt + $(RM) -r $(doc_builddir)/groff.html.* + +install-data-local: install-txt +install-txt: + -test -d $(DESTDIR)$(docdir) \ + || $(mkinstalldirs) $(DESTDIR)$(docdir) + cp $(top_srcdir)/doc/groff.txt $(DESTDIR)$(docdir) + +install-data-local: install_infodoc +install_infodoc: doc/groff.info + -test -d $(DESTDIR)$(infodir) \ + || $(mkinstalldirs) $(DESTDIR)$(infodir) + $(RM) $(DESTDIR)/doc/groff.info* + for d in $(doc_builddir) $(doc_srcdir); do \ + if [ -f "$$d"/groff.info ]; then \ + cp "$$d"/groff.info* $(DESTDIR)$(infodir); \ + $(INSTALL_INFO) --info-file="$$d"/groff.info \ + --info-dir=$(DESTDIR)$(infodir); \ + break; \ + fi; \ + done +install-pdf-local: doc/groff.pdf + -test -d $(DESTDIR)$(pdfdocdir) \ + || $(mkinstalldirs) $(DESTDIR)$(pdfdocdir) + cp $(top_srcdir)/doc/groff.pdf $(DESTDIR)$(pdfdocdir) +install-html-local: doc/groff.html + -test -d $(DESTDIR)$(htmldocdir)/groff.html.mono \ + || $(mkinstalldirs) $(DESTDIR)$(htmldocdir)/groff.html.mono + cp -r $(top_srcdir)/doc/groff.html \ + $(DESTDIR)$(htmldocdir)/groff.html.mono + cp -r $(top_srcdir)/doc/groff.html.node \ + $(DESTDIR)$(htmldocdir) + +uninstall-local: uninstall_infodoc uninstall-pdf uninstall-html \ + uninstall-txt +uninstall_doc: uninstall-local +uninstall-doc: uninstall-local +uninstall_infodoc: + -$(INSTALL_INFO) --remove --info-dir=$(DESTDIR)$(infodir) \ + $(DESTDIR)$(infodir)/groff.info + -for f in `ls $(DESTDIR)$(infodir)/groff.info*`; do \ + $(RM) $$f; \ + done +uninstall-pdf: + $(RM) $(DESTDIR)$(pdfdocdir)/groff.pdf + -rmdir $(DESTDIR)$(pdfdocdir) +uninstall-html: + $(RM) $(DESTDIR)$(htmldocdir)/groff.html.mono/* + $(RM) $(DESTDIR)$(htmldocdir)/groff.html.node/* +uninstall-txt: + $(RM) $(DESTDIR)$(docdir)/groff.txt + +# An image of a gnu in enscapsulated PostScript is generated during the +# build process if necessary. Our configure script assumes pnmdepth is +# available if xpmtoppm is (see macro "GROFF_PROG_XPMTOPPM"). +EXTRA_DIST += $(DOC_GNU_EPS) doc/gnu.xpm +$(DOC_GNU_EPS): doc/gnu.xpm + $(AM_V_GEN)if test "$(XPMTOPPM)" != found; then \ + echo "program 'xpmtoppm' is missing; can't generate $@" >&2; \ + exit 1; \ + fi; \ + if test "$(pnmtops)" != found; then \ + echo "program 'pnmtops' is missing; can't generate $@" >&2; \ + exit 1; \ + fi; \ + if ! echo "$(pnmtops_nosetpage)" | grep -q nosetpage; then \ + echo "program 'pnmtops' can't handle -nosetpage option;" \ + "can't generate $@" >&2; \ + exit 1; \ + fi; \ + xpmtoppm $(top_srcdir)/doc/gnu.xpm | pnmdepth 15 \ + | $(pnmtops_nosetpage) -noturn -rle >$@ + +# Provide a copy of the image in the distribution archive to accommodate +# systems without a tool to generate it from an X pixmap. +dist-hook: dist-gnueps +dist-gnueps: + chmod u+w $(distdir)/doc + for d in $(doc_builddir) $(doc_srcdir); do \ + if [ -f "$$d"/$(DOC_GNU_EPS) ]; then \ + cp -f "$$d"/$(DOC_GNU_EPS) $(distdir)/doc; \ + break; \ + fi; \ + done + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/doc/fdl.texi b/doc/fdl.texi new file mode 100644 index 0000000..46f6b81 --- /dev/null +++ b/doc/fdl.texi @@ -0,0 +1,505 @@ +@c The GNU Free Documentation License. +@center Version 1.3, 3 November 2008 + +@c This file is intended to be included within another document, +@c hence no sectioning command or @node. + +@display +Copyright @copyright{} 2000-2018 Free Software Foundation, Inc. +@uref{http://fsf.org/} + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. +@end display + +@enumerate 0 +@item +PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document @dfn{free} in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of ``copyleft'', which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + +@item +APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The ``Document'', below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as ``you''. You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A ``Modified Version'' of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A ``Secondary Section'' is a named appendix or a front-matter section +of the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall +subject (or to related matters) and contains nothing that could fall +directly within that overall subject. (Thus, if the Document is in +part a textbook of mathematics, a Secondary Section may not explain +any mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The ``Invariant Sections'' are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The ``Cover Texts'' are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A ``Transparent'' copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not ``Transparent'' is called ``Opaque''. + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, La@TeX{} input +format, SGML or XML using a publicly available +DTD, and standard-conforming simple HTML, +PostScript or PDF designed for human modification. Examples +of transparent image formats include PNG, XCF and +JPG@. Opaque formats include proprietary formats that can be +read and edited only by proprietary word processors, SGML or +XML for which the DTD and/or processing tools are +not generally available, and the machine-generated HTML, +PostScript or PDF produced by some word processors for +output purposes only. + +The ``Title Page'' means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, ``Title Page'' means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +The ``publisher'' means any person or entity that distributes copies +of the Document to the public. + +A section ``Entitled XYZ'' means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as ``Acknowledgements'', +``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' +of such a section when you modify the Document means that it remains a +section ``Entitled XYZ'' according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + +@item +VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + +@item +COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + +@item +MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +@enumerate A +@item +Use in the Title Page (and on the covers, if any) a title distinct +from that of the Document, and from those of previous versions +(which should, if there were any, be listed in the History section +of the Document). You may use the same title as a previous version +if the original publisher of that version gives permission. + +@item +List on the Title Page, as authors, one or more persons or entities +responsible for authorship of the modifications in the Modified +Version, together with at least five of the principal authors of the +Document (all of its principal authors, if it has fewer than five), +unless they release you from this requirement. + +@item +State on the Title page the name of the publisher of the +Modified Version, as the publisher. + +@item +Preserve all the copyright notices of the Document. + +@item +Add an appropriate copyright notice for your modifications +adjacent to the other copyright notices. + +@item +Include, immediately after the copyright notices, a license notice +giving the public permission to use the Modified Version under the +terms of this License, in the form shown in the Addendum below. + +@item +Preserve in that license notice the full lists of Invariant Sections +and required Cover Texts given in the Document's license notice. + +@item +Include an unaltered copy of this License. + +@item +Preserve the section Entitled ``History'', Preserve its Title, and add +to it an item stating at least the title, year, new authors, and +publisher of the Modified Version as given on the Title Page. If +there is no section Entitled ``History'' in the Document, create one +stating the title, year, authors, and publisher of the Document as +given on its Title Page, then add an item describing the Modified +Version as stated in the previous sentence. + +@item +Preserve the network location, if any, given in the Document for +public access to a Transparent copy of the Document, and likewise +the network locations given in the Document for previous versions +it was based on. These may be placed in the ``History'' section. +You may omit a network location for a work that was published at +least four years before the Document itself, or if the original +publisher of the version it refers to gives permission. + +@item +For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve +the Title of the section, and preserve in the section all the +substance and tone of each of the contributor acknowledgements and/or +dedications given therein. + +@item +Preserve all the Invariant Sections of the Document, +unaltered in their text and in their titles. Section numbers +or the equivalent are not considered part of the section titles. + +@item +Delete any section Entitled ``Endorsements''. Such a section +may not be included in the Modified Version. + +@item +Do not retitle any existing section to be Entitled ``Endorsements'' or +to conflict in title with any Invariant Section. + +@item +Preserve any Warranty Disclaimers. +@end enumerate + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled ``Endorsements'', provided it contains +nothing but endorsements of your Modified Version by various +parties---for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + +@item +COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled ``History'' +in the various original documents, forming one section Entitled +``History''; likewise combine any sections Entitled ``Acknowledgements'', +and any sections Entitled ``Dedications''. You must delete all +sections Entitled ``Endorsements.'' + +@item +COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + +@item +AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an ``aggregate'' if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + +@item +TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled ``Acknowledgements'', +``Dedications'', or ``History'', the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + +@item +TERMINATION + +You may not copy, modify, sublicense, or distribute the Document +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense, or distribute it is void, and +will automatically terminate your rights under this License. + +However, if you cease all violation of this License, then your license +from a particular copyright holder is reinstated (a) provisionally, +unless and until the copyright holder explicitly and finally +terminates your license, and (b) permanently, if the copyright holder +fails to notify you of the violation by some reasonable means prior to +60 days after the cessation. + +Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, receipt of a copy of some or all of the same material does +not give you any rights to use it. + +@item +FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +@uref{http://www.gnu.org/copyleft/}. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License ``or any later version'' applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. If the Document +specifies that a proxy can decide which future versions of this +License can be used, that proxy's public statement of acceptance of a +version permanently authorizes you to choose that version for the +Document. + +@item +RELICENSING + +``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any +World Wide Web server that publishes copyrightable works and also +provides prominent facilities for anybody to edit those works. A +public wiki that anybody can edit is an example of such a server. A +``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the +site means any set of copyrightable works thus published on the MMC +site. + +``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0 +license published by Creative Commons Corporation, a not-for-profit +corporation with a principal place of business in San Francisco, +California, as well as future copyleft versions of that license +published by that same organization. + +``Incorporate'' means to publish or republish a Document, in whole or +in part, as part of another Document. + +An MMC is ``eligible for relicensing'' if it is licensed under this +License, and if all works that were first published under this License +somewhere other than this MMC, and subsequently incorporated in whole +or in part into the MMC, (1) had no cover texts or invariant sections, +and (2) were thus incorporated prior to November 1, 2008. + +The operator of an MMC Site may republish an MMC contained in the site +under CC-BY-SA on the same site at any time before August 1, 2009, +provided the MMC is eligible for relicensing. + +@end enumerate + +@page +@heading ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + +@smallexample +@group + Copyright (C) @var{year} @var{your name}. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. A copy of the license is included in the section entitled ``GNU + Free Documentation License''. +@end group +@end smallexample + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the ``with@dots{}Texts.''@: line with this: + +@smallexample +@group + with the Invariant Sections being @var{list their titles}, with + the Front-Cover Texts being @var{list}, and with the Back-Cover Texts + being @var{list}. +@end group +@end smallexample + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. + +@c Local Variables: +@c ispell-local-pdict: "ispell-dict" +@c End: diff --git a/doc/gnu.eps b/doc/gnu.eps new file mode 100644 index 0000000..6a836c7 --- /dev/null +++ b/doc/gnu.eps @@ -0,0 +1,784 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%LanguageLevel: 2 +%%Creator: pnmtops +%%Title: noname.ps +%%Pages: 1 +%%BoundingBox: 203 311 408 481 +%%EndComments +%%BeginSetup +/rlestr1 1 string def +/readrlestring { + /rlestr exch def + currentfile rlestr1 readhexstring pop + 0 get + dup 127 le { + currentfile rlestr 0 + 4 3 roll + 1 add getinterval + readhexstring pop + length + } { + 257 exch sub dup + currentfile rlestr1 readhexstring pop + 0 get + exch 0 exch 1 exch 1 sub { + rlestr exch 2 index put + } for + pop + } ifelse +} bind def +/readstring { + dup length 0 { + 3 copy exch + 1 index sub + getinterval + readrlestring + add + 2 copy le { exit } if + } loop + pop pop +} bind def +/rpicstr 107 string def +/gpicstr 107 string def +/bpicstr 107 string def +%%EndSetup +%%Page: 1 1 +gsave +203.76 311.04 translate +204.48 169.92 scale +213 177 4 +[ 213 0 0 -177 0 177 ] +{ rpicstr readstring } +{ gpicstr readstring } +{ bpicstr readstring } +true 3 +colorimage +97ff00f097ff00f097ff00f097ff00f097ff00f097ff00f0ecff04eddcaabddeb1ff00f0ecff04ed +dcaabddeb1ff00f0ecff04eddcaabddeb1ff00f0eeff0ad988777478864555678adfb5ff00f0eeff +0ad988777478864555678adfb5ff00f0eeff0ad988777478864555678adfb5ff00f0f0ff0dfdbba9 +4afcb867b544777675447cb6ff00f0f0ff0dfdbba94afcb867b544777675447cb6ff00f0f0ff0dfd +bba94afcb867b544777675447cb6ff00f0f1ff10faab6985449d5d649543484465675558bdd3ff01 +ecdfe8ff00f0f1ff10faab6985449d5d649543484465675558bdd3ff01ecdfe8ff00f0f1ff10faab +6985449d5d649543484465675558bdd3ff01ecdfe8ff00f0f2ff12fb9de89476454897d54a443974 +43575554339fd7ff06d978778998889ceaff00f0f2ff12fb9de89476454897d54a44397443575554 +339fd7ff06d978778998889ceaff00f0f2ff12fb9de89476454897d54a44397443575554339fd7ff +06d978778998889ceaff00f0f3ff14fc9cfff834455554669b487434a5444755555346cfdaff0afc +869cfdcfa9fedaa988dfecff00f0f3ff14fc9cfff834455554669b487434a5444755555346cfdaff +0afc869cfdcfa9fedaa988dfecff00f0f3ff14fc9cfff834455554669b487434a5444755555346cf +daff0afc869cfdcfa9fedaa988dfecff00f0f3ff159bffd5ae84534554454c74b444474444944566 +5549effdff00fee2ff0ce8977adb8874764564444aee99ecff00f0f3ff159bffd5ae84534554454c +74b4444744449445665549effdff00fee2ff0ce8977adb8874764564444aee99ecff00f0f3ff159b +ffd5ae84534554454c74b4444744449445665549effdff00fee2ff0ce8977adb8874764564444aee +99ecff00f0f5ff18fee8defd9975ca4535454445c47844455444554456444558bffeff0176afe4ff +05e8448baa5665fe44054535797efc8bedff00f0f5ff18fee8defd9975ca4535454445c478444554 +44554456444558bffeff0176afe4ff05e8448baa5665fe44054535797efc8bedff00f0f5ff18fee8 +defd9975ca4535454445c47844455444554456444558bffeff0176afe4ff05e8448baa5665fe4405 +4535797efc8bedff00f0f5ff07e7cef97cd76758a4fe540356754b44fe540b46455463855caaacdd +a7bdafedff01fdbefbff07fd77a86754454445fe4405896446effc9eeeff00f0f5ff07e7cef97cd7 +6758a4fe540356754b44fe540b46455463855caaacdda7bdafedff01fdbefbff07fd77a867544544 +45fe4405896446effc9eeeff00f0f5ff07e7cef97cd76758a4fe540356754b44fe540b4645546385 +5caaacdda7bdafedff01fdbefbff07fd77a86754454445fe4405896446effc9eeeff00f0f6ff11fe +8e758a849ec65488444467c86467945646fe440954555757efca78bffaefedff02d675affeff13fe +ed976666844443444343444455677898affbaeefff00f0f6ff11fe8e758a849ec65488444467c864 +67945646fe440954555757efca78bffaefedff02d675affeff13feed976666844443444343444455 +677898affbaeefff00f0f6ff11fe8e758a849ec65488444467c86467945646fe440954555757efca +78bffaefedff02d675affeff13feed976666844443444343444455677898affbaeefff00f0f6ff1d +c79889555655afc64664457efd75b594485445455445494674eefddeefdaecff039efb6466fd4412 +466558444334563454434555434459cfffe9eff0ff00f0f6ff1dc79889555655afc64664457efd75 +b594485445455445494674eefddeefdaecff039efb6466fd44124665584443345634544345554344 +59cfffe9eff0ff00f0f6ff1dc79889555655afc64664457efd75b594485445455445494674eefdde +efdaecff039efb6466fd4412466558444334563454434555434459cfffe9eff0ff00f0f7ff1ef9ac +796686455447eea64589dffffffddc669557656856684494cecba66c8eecff1aa8fefecb985677b6 +5554844434345346433456457899998effffadf0ff00f0f7ff1ef9ac796686455447eea64589dfff +fffddc669557656856684494cecba66c8eecff1aa8fefecb985677b6555484443434534643345645 +7899998effffadf0ff00f0f7ff1ef9ac796686455447eea64589dffffffddc669557656856684494 +cecba66c8eecff1aa8fefecb985677b65554844434345346433456457899998effffadf0ff00f0f7 +ff1dc7ffeffb557555465bfe77ccfffecccbba568c9dfe8aefbed8dbfeeffd99ebff1bf57deef855 +4454555556534333453453345434644454444579fffbdff1ff00f0f7ff1dc7ffeffb557555465bfe +77ccfffecccbba568c9dfe8aefbed8dbfeeffd99ebff1bf57deef855445455555653433345345334 +5434644454444579fffbdff1ff00f0f7ff1dc7ffeffb557555465bfe77ccfffecccbba568c9dfe8a +efbed8dbfeeffd99ebff1bf57deef8554454555556534333453453345434644454444579fffbdff1 +ff00f0f8ff1efe9ffdedffe7445465959ffbefe967abbbcdcb97778999aaacceefffeb89dfeaff10 +94679d9964454555569a65664345334443fb44034568ffbef1ff00f0f8ff1efe9ffdedffe7445465 +959ffbefe967abbbcdcb97778999aaacceefffeb89dfeaff1094679d9964454555569a6566434533 +4443fb44034568ffbef1ff00f0f8ff1efe9ffdedffe7445465959ffbefe967abbbcdcb97778999aa +acceefffeb89dfeaff1094679d9964454555569a65664345334443fb44034568ffbef1ff00f0f8ff +0ef9ffc5457bff944545bd78ffe97aeffbff07edddccbccccccedee8ff1bfe96434689d556686887 +75874765675444443333344455789cfffaeff2ff00f0f8ff0ef9ffc5457bff944545bd78ffe97aef +fbff07edddccbccccccedee8ff1bfe96434689d55668688775874765675444443333344455789cff +faeff2ff00f0f8ff0ef9ffc5457bff944545bd78ffe97aeffbff07edddccbccccccedee8ff1bfe96 +434689d55668688775874765675444443333344455789cfffaeff2ff00f0f8ff0c9ddea6544469e8 +56567efceb9dd6ff05fda754445bdefdff04c65dfe5444fb33043446effebff2ff00f0f8ff0c9dde +a6544469e856567efceb9dd6ff05fda754445bdefdff04c65dfe5444fb33043446effebff2ff00f0 +f8ff0c9ddea6544469e856567efceb9dd6ff05fda754445bdefdff04c65dfe5444fb33043446effe +bff2ff00f0f9ff0cf8bc7559bb853459679aa9fe9dcbff03fea68ed6fd3307344456765467dfaff2 +ff00f0f9ff0cf8bc7559bb853459679aa9fe9dcbff03fea68ed6fd3307344456765467dfaff2ff00 +f0f9ff0cf8bc7559bb853459679aa9fe9dcbff03fea68ed6fd3307344456765467dfaff2ff00f0fa +ff0dfd74469cb646bdb63459eeffd8efc9ff0dc7cd33334444588754334457dfccf2ff00f0faff0d +fd74469cb646bdb63459eeffd8efc9ff0dc7cd33334444588754334457dfccf2ff00f0faff0dfd74 +469cb646bdb63459eeffd8efc9ff0dc7cd33334444588754334457dfccf2ff00f0faff0cf8964444 +5885457dc436cefb8ec7ff028ab445fd3305345676654debf2ff00f0faff0cf89644445885457dc4 +36cefb8ec7ff028ab445fd3305345676654debf2ff00f0faff0cf89644445885457dc436cefb8ec7 +ff028ab445fd3305345676654debf2ff00f0faff0bc8ffeb7444455444895befb9c6ff05fb8c9543 +3334fe4403577769faf2ff00f0faff0bc8ffeb7444455444895befb9c6ff05fb8c95433334fe4403 +577769faf2ff00f0faff0bc8ffeb7444455444895befb9c6ff05fb8c95433334fe4403577769faf2 +ff00f0fbff0cfe7cbbcacdb6444455666ffb9fc5ff02b8fc43fd330444455568caf2ff00f0fbff0c +fe7cbbcacdb6444455666ffb9fc5ff02b8fc43fd330444455568caf2ff00f0fbff0cfe7cbbcacdb6 +444455666ffb9fc5ff02b8fc43fd330444455568caf2ff00f0fbff0be7e555444569a7444558dfd8 +c4ff0cfa7fb53334433333457abbebeff3ff00f0fbff0be7e555444569a7444558dfd8c4ff0cfa7f +b53334433333457abbebeff3ff00f0fbff0be7e555444569a7444558dfd8c4ff0cfa7fb533344333 +33457abbebeff3ff00f0fbff0b9bfc9cea7544568855da8b8eedff05edbbaaaabcefddff0197e6fe +330634578865569dcff3ff00f0fbff0b9bfc9cea7544568855da8b8eedff05edbbaaaabcefddff01 +97e6fe330634578865569dcff3ff00f0fbff0b9bfc9cea7544568855da8b8eedff05edbbaaaabcef +ddff0197e6fe330634578865569dcff3ff00f0fcff0cfe7ffffeefffd9445776eff7dfefff09eb86 +7789998778778adff7ff02cbcdefecff0bfaa5333433433469dfffffbff3ff00f0fcff0cfe7ffffe +efffd9445776eff7dfefff09eb867789998778778adff7ff02cbcdefecff0bfaa5333433433469df +ffffbff3ff00f0fcff0cfe7ffffeefffd9445776eff7dfefff09eb867789998778778adff7ff02cb +cdefecff0bfaa5333433433469dfffffbff3ff00f0fcff0bf9dfffcbaaabceeb556cffabefff0be7 +69cedbb9988aa9abba88cffaff05fea8998889adecff0a77344555455444467cffaff3ff00f0fcff +0bf9dfffcbaaabceeb556cffabefff0be769cedbb9988aa9abba88cffaff05fea8998889adecff0a +77344555455444467cffaff3ff00f0fcff0bf9dfffcbaaabceeb556cffabefff0be769cedbb9988a +a9abba88cffaff05fea8998889adecff0a77344555455444467cffaff3ff00f0fcff0be8ff944433 +44446afb9efc8ff0ff0dfc69a899abdefeecba8668aa78cffcff07fb9aba988abdfcbdedff0ac874 +55544433344458ffbff3ff00f0fcff0be8ff94443344446afb9efc8ff0ff0dfc69a899abdefeecba +8668aa78cffcff07fb9aba988abdfcbdedff0ac87455544433344458ffbff3ff00f0fcff0be8ff94 +443344446afb9efc8ff0ff0dfc69a899abdefeecba8668aa78cffcff07fb9aba988abdfcbdedff0a +c87455544433344458ffbff3ff00f0fcff0a9dc856789a987544dfffe7f0ff03fd747adffaff04ec +877667dffeff09e978879bcedba98aecbfeeff02f7da53fe3304344456efbff3ff00f0fcff0a9dc8 +56789a987544dfffe7f0ff03fd747adffaff04ec877667dffeff09e978879bcedba98aecbfeeff02 +f7da53fe3304344456efbff3ff00f0fcff0a9dc856789a987544dfffe7f0ff03fd747adffaff04ec +877667dffeff09e978879bcedba98aecbfeeff02f7da53fe3304344456efbff3ff00f0fcff0a8f99 +8887765567977bffadf0ff01a58efeff04fdcfefffcefeff0feb8549ffffd9968ceffb5becfffc89 +efeeff0af9c85333333443344679cef3ff00f0fcff0a8f998887765567977bffadf0ff01a58efeff +04fdcfefffcefeff0feb8549ffffd9968ceffb5becfffc89efeeff0af9c85333333443344679cef3 +ff00f0fcff0a8f998887765567977bffadf0ff01a58efeff04fdcfefffcefeff0feb8549ffffd996 +8ceffb5becfffc89efeeff0af9c85333333443344679cef3ff00f0fdff01faadfe4406568aa86576 +df9ff1ff1dfa8efffffeffff9c885de67cffec9bfd848ddab98effffe754547ffffe89eeff0afd9f +645aa6434696445ecef3ff00f0fdff01faadfe4406568aa86576df9ff1ff1dfa8efffffeffff9c88 +5de67cffec9bfd848ddab98effffe754547ffffe89eeff0afd9f645aa6434696445ecef3ff00f0fd +ff01faadfe4406568aa86576df9ff1ff1dfa8efffffeffff9c885de67cffec9bfd848ddab98effff +e754547ffffe89eeff0afd9f645aa6434696445ecef3ff00f0fdff0bf666544565654458dec9bf9f +f1ff009bfeff1af9c8d99aa9485967ee6766cf9c65be88befdca8d4447349aeffd8ceeff097d4433 +47984348684eddf3ff00f0fdff0bf666544565654458dec9bf9ff1ff009bfeff1af9c8d99aa94859 +67ee6766cf9c65be88befdca8d4447349aeffd8ceeff097d443347984348684eddf3ff00f0fdff0b +f666544565654458dec9bf9ff1ff009bfeff1af9c8d99aa9485967ee6766cf9c65be88befdca8d44 +47349aeffd8ceeff097d443347984348684eddf3ff00f0fdff0bb888aaa8877655554ceffdbff2ff +20e8cfffffc9b9aaab69b74b69586865565ba6d786b7559c5d644945a3465da9ea8eefff09786443 +3434685345bfbcf3ff00f0fdff0bb888aaa8877655554ceffdbff2ff20e8cfffffc9b9aaab69b74b +69586865565ba6d786b7559c5d644945a3465da9ea8eefff097864433434685345bfbcf3ff00f0fd +ff0bb888aaa8877655554ceffdbff2ff20e8cfffffc9b9aaab69b74b69586865565ba6d786b7559c +5d644945a3465da9ea8eefff097864433434685345bfbcf3ff00f0fdff0b6efddb9865554445569f +faeff2ff008efeff17887b8a8c57c668874758754764655a869e644566d548a394fe33025bd7dff0 +ff099a44333344447944bfbaf3ff00f0fdff0b6efddb9865554445569ffaeff2ff008efeff17887b +8a8c57c668874758754764655a869e644566d548a394fe33025bd7dff0ff099a44333344447944bf +baf3ff00f0fdff0b6efddb9865554445569ffaeff2ff008efeff17887b8a8c57c668874758754764 +655a869e644566d548a394fe33025bd7dff0ff099a44333344447944bfbaf3ff00f0feff0bfe7ffc +544444555556666df8f2ff22f8cfbea86ea55d697e56d575a546458546554355a64ba454439b34c4 +54334333345a7bf0ff099d544555433445b65dbaf3ff00f0feff0bfe7ffc544444555556666df8f2 +ff22f8cfbea86ea55d697e56d575a546458546554355a64ba454439b34c454334333345a7bf0ff09 +9d544555433445b65dbaf3ff00f0feff0bfe7ffc544444555556666df8f2ff22f8cfbea86ea55d69 +7e56d575a546458546554355a64ba454439b34c454334333345a7bf0ff099d544555433445b65dba +f3ff00f0feff02fbae95fc44034547eee9f2ff239cdd9bc65bd55d677f56e574c454459645544345 +6855d555654d7386453344533334b99ff1ff09ab4444345543454885a9f3ff00f0feff02fbae95fc +44034547eee9f2ff239cdd9bc65bd55d677f56e574c4544596455443456855d555654d7386453344 +533334b99ff1ff09ab4444345543454885a9f3ff00f0feff02fbae95fc44034547eee9f2ff239cdd +9bc65bd55d677f56e574c4544596455443456855d555654d7386453344533334b99ff1ff09ab4444 +345543454885a9f3ff00f0feff0bf8d9444578b9bcba75356e9cf3ff24f9aff768f549e55a857f55 +d463b4444595476454455655ab584844a3784643637443335bb8f1ff09baa443444345544448e9f3 +ff00f0feff0bf8d9444578b9bcba75356e9cf3ff24f9aff768f549e55a857f55d463b44445954764 +54455655ab584844a3784643637443335bb8f1ff09baa443444345544448e9f3ff00f0feff0bf8d9 +444578b9bcba75356e9cf3ff24f9aff768f549e55a857f55d463b4444595476454455655ab584844 +a3784643637443335bb8f1ff09baa443444345544448e9f3ff00f0feff0bf7fb59bba8754444458d +ef8ff3ff25bce9fa56f648f659956f55d474944444a65784563455945b6594b4546c354363854333 +349b9ff2ff09aba433345533344346e9f3ff00f0feff0bf7fb59bba8754444458def8ff3ff25bce9 +fa56f648f659956f55d474944444a65784563455945b6594b4546c354363854333349b9ff2ff09ab +a433345533344346e9f3ff00f0feff0bf7fb59bba8754444458def8ff3ff25bce9fa56f648f65995 +6f55d474944444a65784563455945b6594b4546c354363854333349b9ff2ff09aba4333455333443 +46e9f3ff00f0feff0bf7ffb854346788787569ce9ff4ff21fe8ff77655f645f756a46e55a4747445 +44b566a4754554a446846479864a45435375fe4301499cf2ff098d7643333568634446daf3ff00f0 +feff0bf7ffb854346788787569ce9ff4ff21fe8ff77655f645f756a46e55a474744544b566a47545 +54a446846479864a45435375fe4301499cf2ff098d7643333568634446daf3ff00f0feff0bf7ffb8 +54346788787569ce9ff4ff21fe8ff77655f645f756a46e55a474744544b566a4754554a446846479 +864a45435375fe4301499cf2ff098d7643333568634446daf3ff00f0feff0bf8ff84589876555676 +6acd9ff4ff21e7ee99b445e754e945945f54c584654544b577c46454548566458a5d5c3864446545 +fe43024486eff3ff0a7f8ac7333334774446faeff4ff00f0feff0bf8ff845898765556766acd9ff4 +ff21e7ee99b445e754e945945f54c584654544b577c46454548566458a5d5c3864446545fe430244 +86eff3ff0a7f8ac7333334774446faeff4ff00f0feff0bf8ff845898765556766acd9ff4ff21e7ee +99b445e754e945945f54c584654544b577c46454548566458a5d5c3864446545fe43024486eff3ff +0a7f8ac7333334774446faeff4ff00f0feff0bf8fe576544455666567ace9ff4ff278dbb6a9544d8 +54da45a46f64d584554644c576c4858554655788fe8b84478445464444534344467df4ff0bfe8e55 +44333334557554cbdff4ff00f0feff0bf8fe576544455666567ace9ff4ff278dbb6a9544d854da45 +a46f64d584554644c576c4858554655788fe8b84478445464444534344467df4ff0bfe8e55443333 +34557554cbdff4ff00f0feff0bf8fe576544455666567ace9ff4ff278dbb6a9544d854da45a46f64 +d584554644c576c4858554655788fe8b84478445464444534344467df4ff0bfe8e55443333345575 +54cbdff4ff00f0feff0bfafc57555666655654448d8ff5ff29f8cff6489735c854bc55c56e54d584 +454844c578d485a6755433a47cf96445b4454735446444344456dff5ff02faae57fd3304355854eb +dff4ff00f0feff0bfafc57555666655654448d8ff5ff29f8cff6489735c854bc55c56e54d5844548 +44c578d485a6755433a47cf96445b4454735446444344456dff5ff02faae57fd3304355854ebdff4 +ff00f0feff0bfafc57555666655654448d8ff5ff29f8cff6489735c854bc55c56e54d584454844c5 +78d485a6755433a47cf96445b4454735446444344456dff5ff02faae57fd3304355854ebdff4ff00 +f0feff0bfdf9a44578adb985445bff8ff5ff299afff6488a34c954ad54d66e44d494444655b679d4 +a5c59666c9c445bfb343b54555364465443444456ef5ff03f8efd543fd330355a4cbeff4ff00f0fe +ff0bfdf9a44578adb985445bff8ff5ff299afff6488a34c954ad54d66e44d494444655b679d4a5c5 +9666c9c445bfb343b54555364465443444456ef5ff03f8efd543fd330355a4cbeff4ff00f0feff0b +fdf9a44578adb985445bff8ff5ff299afff6488a34c954ad54d66e44d494444655b679d4a5c59666 +c9c445bfb343b54555364465443444456ef5ff03f8efd543fd330355a4cbeff4ff00f0fdff0af67b +dfea6546988655cf8ff6ff2afaadff55487c34c9549d44c76c44b4a5445546975bc4a5d4a55dfdc3 +334543437735553444564434443446f5ff04f7ffa43453fe3303347cebeff4ff00f0fdff0af67bdf +ea6546988655cf8ff6ff2afaadff55487c34c9549d44c76c44b4a5445546975bc4a5d4a55dfdc333 +4543437735553444564434443446f5ff04f7ffa43453fe3303347cebeff4ff00f0fdff0af67bdfea +6546988655cf8ff6ff2afaadff55487c34c9549d44c76c44b4a5445546975bc4a5d4a55dfdc33345 +43437735553444564434443446f5ff04f7ffa43453fe3303347cebeff4ff00f0feff0bfcf9fb8545 +6875543345cf8ff6ff2ba8fb9d44486e34a7549c45d66a4594a4444446685ca47694844ae5e53465 +554368345434445545454433446ef6ff0bf7fd533346334333345dfbeff4ff00f0feff0bfcf9fb85 +456875543345cf8ff6ff2ba8fb9d44486e34a7549c45d66a4594a4444446685ca47694844ae5e534 +65554368345434445545454433446ef6ff0bf7fd533346334333345dfbeff4ff00f0feff0bfcf9fb +85456875543345cf8ff6ff2ba8fb9d44486e34a7549c45d66a4594a4444446685ca47694844ae5e5 +3465554368345434445545454433446ef6ff0bf7fd533346334333345dfbeff4ff00f0feff0bfbfe +a558754444697657ff8ff7ff2dfa9ffe5e44466f45a7558b45e5763694b44544574d6c9576556347 +e4db747ca544683444344554454454353446eff7ff0ad6543433346434433489fbf3ff00f0feff0b +fbfea558754444697657ff8ff7ff2dfa9ffe5e44466f45a7558b45e5763694b44544574d6c957655 +6347e4db747ca544683444344554454454353446eff7ff0ad6543433346434433489fbf3ff00f0fe +ff0bfbfea558754444697657ff8ff7ff2dfa9ffe5e44466f45a7558b45e5763694b44544574d6c95 +76556347e4db747ca544683444344554454454353446eff7ff0ad6543433346434433489fbf3ff00 +f0feff0bfaee887544459b85448cfd9cf7ff2d9affff5b54565e5486547847d4644866844535457a +4959fe9a6544d5affb4486866834443444644544643744468ef7ff0a958b433333364334347ffaf3 +ff00f0feff0bfaee887544459b85448cfd9cf7ff2d9affff5b54565e5486547847d4644866844535 +457a4959fe9a6544d5affb4486866834443444644544643744468ef7ff0a958b433333364334347f +faf3ff00f0feff0bfaee887544459b85448cfd9cf7ff2d9affff5b54565e5486547847d464486684 +4535457a4959fe9a6544d5affb4486866834443444644544643744468ef7ff0a958b433333364334 +347ffaf3ff00f0feff0bfadc985459da534784578ad8f8ff2ff8bffbbf7844566f54855455488444 +464853543646696fedcdc84a46555effa543545b444443447446445547645ad7acf8ff0274d543fe +3304543343affbf3ff00f0feff0bfadc985459da534784578ad8f8ff2ff8bffbbf7844566f548554 +55488444464853543646696fedcdc84a46555effa543545b444443447446445547645ad7acf8ff02 +74d543fe3304543343affbf3ff00f0feff0bfadc985459da534784578ad8f8ff2ff8bffbbf784456 +6f54855455488444464853543646696fedcdc84a46555effa543545b444443447446445547645ad7 +acf8ff0274d543fe3304543343affbf3ff00f0feff0bfb9ba56ce9534775444598f7f9ff30fe7cff +fc5f9654556f655455445846a7577a556577bf777855547a7b683836acee63455c54454444645743 +65448457ed9af9ff02fb8663fd33043433436ffaf3ff00f0feff0bfb9ba56ce9534775444598f7f9 +ff30fe7cfffc5f9654556f655455445846a7577a556577bf777855547a7b683836acee63455c5445 +444464574365448457ed9af9ff02fb8663fd33043433436ffaf3ff00f0feff0bfb9ba56ce9534775 +444598f7f9ff30fe7cfffc5f9654556f655455445846a7577a556577bf777855547a7b683836acee +63455c5445444464574365448457ed9af9ff02fb8663fd33043433436ffaf3ff00f0feff0cfe8eda +e9444454465445bdeabffaff31e7dffece5eb555466f555474afd99d84aaa954578887445aedc4bf +8a7a76633455335b7b8487446447a944644454448ff99ffaff0be7e834334334333343343afbf3ff +00f0feff0cfe8edae9444454465445bdeabffaff31e7dffece5eb555466f555474afd99d84aaa954 +578887445aedc4bf8a7a76633455335b7b8487446447a944644454448ff99ffaff0be7e834334334 +333343343afbf3ff00f0feff0cfe8edae9444454465445bdeabffaff31e7dffece5eb555466f5554 +74afd99d84aaa954578887445aedc4bf8a7a76633455335b7b8487446447a944644454448ff99ffa +ff0be7e834334334333343343afbf3ff00f0fdff0b7eec56b6434654445566ce9ffbff32fe7dffff +7c7ba5565566487884963466556778887666789beffff65d9358c585455954ad8c73445534556644 +444334544cfe69faff0b7bd44334333343333334dfbef3ff00f0fdff0b7eec56b6434654445566ce +9ffbff32fe7dffff7c7ba5565566487884963466556778887666789beffff65d9358c585455954ad +8c73445534556644444334544cfe69faff0b7bd44334333343333334dfbef3ff00f0fdff0b7eec56 +b6434654445566ce9ffbff32fe7dffff7c7ba5565566487884963466556778887666789beffff65d +9358c585455954ad8c73445534556644444334544cfe69faff0b7bd44334333343333334dfbef3ff +00f0fdff0b7c94774445544454445bef8cfbff0ee8dfffffa887b46644886ec7458aeffaff00eefe +ff19fe48ec535948437958f9566ab87dbefecaa967675574578de69ffcff02f87b63fa330234ef9f +f3ff00f0fdff0b7c94774445544454445bef8cfbff0ee8dfffffa887b46644886ec7458aeffaff00 +eefeff19fe48ec535948437958f9566ab87dbefecaa967675574578de69ffcff02f87b63fa330234 +ef9ff3ff00f0fdff0b7c94774445544454445bef8cfbff0ee8dfffffa887b46644886ec7458aeffa +ff00eefeff19fe48ec535948437958f9566ab87dbefecaa967675574578de69ffcff02f87b63fa33 +0234ef9ff3ff00f0fdff02a97bb6fe4406585446449ff8bffdff0dfe7effffaec7b6c46545bd7579 +cff3ff0dc57dc6335364543a58efffffb79ffeff11fdcb86557455cf97cffddeffea5564943334fe +330434334afdaff3ff00f0fdff02a97bb6fe4406585446449ff8bffdff0dfe7effffaec7b6c46545 +bd7579cff3ff0dc57dc6335364543a58efffffb79ffeff11fdcb86557455cf97cffddeffea556494 +3334fe330434334afdaff3ff00f0fdff02a97bb6fe4406585446449ff8bffdff0dfe7effffaec7b6 +c46545bd7579cff3ff0dc57dc6335364543a58efffffb79ffeff11fdcb86557455cf97cffddeffea +5564943334fe330434334afdaff3ff00f0fdff0cc9ec64444448754475345fff89fdff0bc8efffea +6bc6b484959866aef1ff08fe745885443334549ffdff01b6effdff10fdb685554bfc654456b847e7 +e633433343fe3303436ff9eff3ff00f0fdff0cc9ec64444448754475345fff89fdff0bc8efffea6b +c6b484959866aef1ff08fe745885443334549ffdff01b6effdff10fdb685554bfc654456b847e7e6 +33433343fe3303436ff9eff3ff00f0fdff0cc9ec64444448754475345fff89fdff0bc8efffea6bc6 +b484959866aef1ff08fe745885443334549ffdff01b6effdff10fdb685554bfc654456b847e7e633 +433343fe3303436ff9eff3ff00f0fdff1be7a644654595644853464cfff88dffffd99fffffc969e5 +9595746aeff8ff00eff9ff0dea454589333684dffffdeffffc6ffbff0ea555635cfec8668aeff764 +54233334fd33014bf9f2ff00f0fdff1be7a644654595644853464cfff88dffffd99fffffc969e595 +95746aeff8ff00eff9ff0dea454589333684dffffdeffffc6ffbff0ea555635cfec8668aeff76454 +233334fd33014bf9f2ff00f0fdff1be7a644654595644853464cfff88dffffd99fffffc969e59595 +746aeff8ff00eff9ff0dea454589333684dffffdeffffc6ffbff0ea555635cfec8668aeff7645423 +3334fd33014bf9f2ff00f0fdff10f7d6585468574476447445efffb988889dfeff058957e564459e +f9ff03fea9568ff9ff0dfeedb845339d75bfffc57fffffb7fbff0cfee644338ebdfb99eac5333553 +fc33023467ccf2ff00f0fdff10f7d6585468574476447445efffb988889dfeff058957e564459ef9 +ff03fea9568ff9ff0dfeedb845339d75bfffc57fffffb7fbff0cfee644338ebdfb99eac5333553fc +33023467ccf2ff00f0fdff10f7d6585468574476447445efffb988889dfeff058957e564459ef9ff +03fea9568ff9ff0dfeedb845339d75bfffc57fffffb7fbff0cfee644338ebdfb99eac5333553fc33 +023467ccf2ff00f0fdff0cfab7a54674655764477544b9cffdff07fdecda5d56e437dffaff05feca +aada35effbff10eeefffeedeb436e7487ff9a87efffff9affbff07cd55433444854344fe33084333 +43333334447a9ff2ff00f0fdff0cfab7a54674655764477544b9cffdff07fdecda5d56e437dffaff +05fecaaada35effbff10eeefffeedeb436e7487ff9a87efffff9affbff07cd55433444854344fe33 +08433343333334447a9ff2ff00f0fdff0cfab7a54674655764477544b9cffdff07fdecda5d56e437 +dffaff05fecaaada35effbff10eeefffeedeb436e7487ff9a87efffff9affbff07cd554334448543 +44fe3308433343333334447a9ff2ff00f0fdff0cfc9e94664655764458473455cefdff06f99b875d +75838ff9ff04c446655339fbff11fe7445effffef955b3346ec8646effffef6dfbff02db9443fd33 +0034f8330248fe9ff2ff00f0fdff0cfc9e94664655764458473455cefdff06f99b875d75838ff9ff +04c446655339fbff11fe7445effffef955b3346ec8646effffef6dfbff02db9443fd330034f83302 +48fe9ff2ff00f0fdff0cfc9e94664655764458473455cefdff06f99b875d75838ff9ff04c4466553 +39fbff11fe7445effffef955b3346ec8646effffef6dfbff02db9443fd330034f8330248fe9ff2ff +00f0fcff157f9764556664457464345577fddfffffea4a475d8434f9ff05fa444343336ffaff10d8 +44aeffefffd553338f9433afffffcfb7fbff03fbd54334fd330b4334433333343333443dfadff2ff +00f0fcff157f9764556664457464345577fddfffffea4a475d8434f9ff05fa444343336ffaff10d8 +44aeffefffd553338f9433afffffcfb7fbff03fbd54334fd330b4334433333343333443dfadff2ff +00f0fcff157f9764556664457464345577fddfffffea4a475d8434f9ff05fa444343336ffaff10d8 +44aeffefffd553338f9433afffffcfb7fbff03fbd54334fd330b4334433333343333443dfadff2ff +00f0fcff158deb457866437655733543459b67ffffa947584b8357f9ff05e433344336effaff10fe +a46cffeffc644358de6434dffffebff6fbff02fe9944f633044233343ceaf1ff00f0fcff158deb45 +7866437655733543459b67ffffa947584b8357f9ff05e433344336effaff10fea46cffeffc644358 +de6434dffffebff6fbff02fe9944f633044233343ceaf1ff00f0fcff158deb457866437655733543 +459b67ffffa947584b8357f9ff05e433344336effaff10fea46cffeffc644358de6434dffffebff6 +fbff02fe9944f633044233343ceaf1ff00f0fcff15bbfb669694455548434634554865faedb64559 +4a639ef9ff04934334338ffcff14d7558dfffaaacffffb4368adfe6338dfffffcff7effbff01c844 +fd33ff34fd330043fe33015e9ef1ff00f0fcff15bbfb669694455548434634554865faedb645594a +639ef9ff04934334338ffcff14d7558dfffaaacffffb4368adfe6338dfffffcff7effbff01c844fd +33ff34fd330043fe33015e9ef1ff00f0fcff15bbfb669694455548434634554865faedb645594a63 +9ef9ff04934334338ffcff14d7558dfffaaacffffb4368adfe6338dfffffcff7effbff01c844fd33 +ff34fd330043fe33015e9ef1ff00f0fcff14e9fb5d6b54465455444534544685f77e7645674545f9 +ff04fd4335337cfcff15b5335646fffffc8bbffea8aeffed733aabaadedff8effbff01f854fb3300 +43fc330334447bbff1ff00f0fcff14e9fb5d6b54465455444534544685f77e7645674545f9ff04fd +4335337cfcff15b5335646fffffc8bbffea8aeffed733aabaadedff8effbff01f854fb330043fc33 +0334447bbff1ff00f0fcff14e9fb5d6b54465455444534544685f77e7645674545f9ff04fd433533 +7cfcff15b5335646fffffc8bbffea8aeffed733aabaadedff8effbff01f854fb330043fc33033444 +7bbff1ff00f0fcff14f8c5d896547544644444344555a5f75c6654664489f9ff04f6335438bffdff +15f946aeff74efffffd58ffffefffffa94368dfc8ccff7faff01fb44f533024475a9f0ff00f0fcff +14f8c5d896547544644444344555a5f75c6654664489f9ff04f6335438bffdff15f946aeff74efff +ffd58ffffefffffa94368dfc8ccff7faff01fb44f533024475a9f0ff00f0fcff14f8c5d896547544 +644444344555a5f75c6654664489f9ff04f6335438bffdff15f946aeff74efffffd58ffffefffffa +94368dfc8ccff7faff01fb44f533024475a9f0ff00f0fcff14fa6de875657456445454443654b6f5 +6a6754543bdff9ff04b4367469bffeff0afc65cfffff849fffffb69ffdff07f883357cfeebffe6fa +ff02fd6543fe330334443334fd330253adccf0ff00f0fcff14fa6de875657456445454443654b6f5 +6a6754543bdff9ff04b4367469bffeff0afc65cfffff849fffffb69ffdff07f883357cfeebffe6fa +ff02fd6543fe330334443334fd330253adccf0ff00f0fcff14fa6de875657456445454443654b6f5 +6a6754543bdff9ff04b4367469bffeff0afc65cfffff849fffffb69ffdff07f883357cfeebffe6fa +ff02fd6543fe330334443334fd330253adccf0ff00f0fcff13fe8ffa75685655446463444555a5e5 +6a7845535ff9ff04fc537fdaf5fdff01a38ffeff05d44efffffaaefdff03f98334bffeff00b7faff +03fb643343fe3302443334fe330343566e9ff0ff00f0fcff13fe8ffa75685655446463444555a5e5 +6a7845535ff9ff04fc537fdaf5fdff01a38ffeff05d44efffffaaefdff03f98334bffeff00b7faff +03fb643343fe3302443334fe330343566e9ff0ff00f0fcff13fe8ffa75685655446463444555a5e5 +6a7845535ff9ff04fc537fdaf5fdff01a38ffeff05d44efffffaaefdff03f98334bffeff00b7faff +03fb643343fe3302443334fe330343566e9ff0ff00f0fbff129ef75968545745544354455575b45a +765443bff9ff04c57affffc6fdff0057fdff06f93dfffffc58effeff07fa53339efeffff8bf9ff02 +843343fe330944333334333433bf78cff0ff00f0fbff129ef75968545745544354455575b45a7654 +43bff9ff04c57affffc6fdff0057fdff06f93dfffffc58effeff07fa53339efeffff8bf9ff028433 +43fe330944333334333433bf78cff0ff00f0fbff129ef75968545745544354455575b45a765443bf +f9ff04c57affffc6fdff0057fdff06f93dfffffc58effeff07fa53339efeffff8bf9ff02843343fe +330944333334333433bf78cff0ff00f0fbff06cbfb5795456848fe44074555548559675434f9ff05 +fd9bafffff6afeff0cfc5dfffcb9876639fffffe54bffeff07fc533356779bff8df9ff02fc4435fe +33ff44ff3304443646fe8aefff00f0fbff06cbfb5795456848fe44074555548559675434f9ff05fd +9bafffff6afeff0cfc5dfffcb9876639fffffe54bffeff07fc533356779bff8df9ff02fc4435fe33 +ff44ff3304443646fe8aefff00f0fbff06cbfb5795456848fe44074555548559675434f9ff05fd9b +afffff6afeff0cfc5dfffcb9876639fffffe54bffeff07fc533356779bff8df9ff02fc4435fe33ff +44ff3304443646fe8aefff00f0fbff11f8fea9945895584534444956457459664437f8ff04e8efff +fe4dfeff0cfa38fb5333433335cfffffc4bffeff01fe93fd3301597bf8ff0d743534333334443343 +535559fe8fefff00f0fbff11f8fea9945895584534444956457459664437f8ff04e8effffe4dfeff +0cfa38fb5333433335cfffffc4bffeff01fe93fd3301597bf8ff0d743534333334443343535559fe +8fefff00f0fbff11f8fea9945895584534444956457459664437f8ff04e8effffe4dfeff0cfa38fb +5333433335cfffffc4bffeff01fe93fd3301597bf8ff0d743534333334443343535559fe8fefff00 +f0fbff11fbafff8678c4644434445c5645544b66644bf8ff04eefffffa6ffeff0cfd345333343338 +94bffffff6bffdff06d4354456875449f8ff01c434fe330834444543537cbfd8efefff00f0fbff11 +fbafff8678c4644434445c5645544b66644bf8ff04eefffffa6ffeff0cfd34533334333894bfffff +f6bffdff06d4354456875449f8ff01c434fe330834444543537cbfd8efefff00f0fbff11fbafff86 +78c4644434445c5645544b66644bf8ff04eefffffa6ffeff0cfd34533334333894bffffff6bffdff +06d4354456875449f8ff01c434fe330834444543537cbfd8efefff00f0faff058efff6c89474fe44 +076b5645555b67544ef5ff01f7affeff0cfe533334333338b97ffffffeadfdff07f6464545557744 +eff9ff0cf5333433334333453356fffb6eeeff00f0faff058efff6c89474fe44076b5645555b6754 +4ef5ff01f7affeff0cfe533334333338b97ffffffeadfdff07f6464545557744eff9ff0cf5333433 +334333453356fffb6eeeff00f0faff058efff6c89474fe44076b5645555b67544ef5ff01f7affeff +0cfe533334333338b97ffffffeadfdff07f6464545557744eff9ff0cf5333433334333453356fffb +6eeeff00f0faff10e8eff8ea7544734454886544555b56648ff5ff01f4effdff075335843345338a +7dfeff0079fdff07fe469333435777cff9ff02f64445fe33064466659efa77dfeeff00f0faff10e8 +eff8ea7544734454886544555b56648ff5ff01f4effdff075335843345338a7dfeff0079fdff07fe +469333435777cff9ff02f64445fe33064466659efa77dfeeff00f0faff10e8eff8ea754473445488 +6544555b56648ff5ff01f4effdff075335843345338a7dfeff0079fdff07fe469333435777cff9ff +02f64445fe33064466659efa77dfeeff00f0faff10fd9dfceb6559533844a59554565a5554eff5ff +00e6fdff08fe45bdc43344436edefeff0067fdff07fe747334334789eff9ff0bfb4446333344458e +66b758efedff00f0faff10fd9dfceb6559533844a59554565a5554eff5ff00e6fdff08fe45bdc433 +44436edefeff0067fdff07fe747334334789eff9ff0bfb4446333344458e66b758efedff00f0faff +10fd9dfceb6559533844a59554565a5554eff5ff00e6fdff08fe45bdc43344436edefeff0067fdff +07fe747334334789eff9ff0bfb4446333344458e66b758efedff00f0f9ff0ef8efee669a43484585 +b4657649453cf4ff009afcff0b4cffd33333435daefffffe5dfdff01eec5fe330136bff8ff09fd69 +b643345874bd636bebff00f0f9ff0ef8efee669a43484585b4657649453cf4ff009afcff0b4cffd3 +3333435daefffffe5dfdff01eec5fe330136bff8ff09fd69b643345874bd636bebff00f0f9ff0ef8 +efee669a43484585b4657649453cf4ff009afcff0b4cffd33333435daefffffe5dfdff01eec5fe33 +0136bff8ff09fd69b643345874bd636bebff00f0f9ff0efe9fffa9b634a54768a5b55559549ff4ff +007efcff0b88fef5333334775ffffff8affdff07feeb43333356768ff8ff07c9fb87dcfed876adea +ff00f0f9ff0efe9fffa9b634a54768a5b55559549ff4ff007efcff0b88fef5333334775ffffff8af +fdff07feeb43333356768ff8ff07c9fb87dcfed876adeaff00f0f9ff0efe9fffa9b634a54768a5b5 +5559549ff4ff007efcff0b88fef5333334775ffffff8affdff07feeb43333356768ff8ff07c9fb87 +dcfed876adeaff00f0f8ff0ccbffbae86594775d6684547655f3ff006ffcff07e77cdc433346a56f +f7ff0583333377845ff8ff06f5668877778bdffcff03feffdfdffeff00fef6ff00f0f8ff0ccbffba +e86594775d6684547655f3ff006ffcff07e77cdc433346a56ff7ff0583333377845ff8ff06f56688 +77778bdffcff03feffdfdffeff00fef6ff00f0f8ff0ccbffbae86594775d6684547655f3ff006ffc +ff07e77cdc433346a56ff7ff0583333377845ff8ff06f5668877778bdffcff03feffdfdffeff00fe +f6ff00f0f8ff0cfdaeefffda55b4ab586554954bf4ff01fc4efdff08feeda49fd88989b59ff7ff05 +d445569c94cff8ff03fbdedeeffcff0ddeffe58bff6e6ffffebde597bdbef9ff00f0f8ff0cfdaeef +ffda55b4ab586554954bf4ff01fc4efdff08feeda49fd88989b59ff7ff05d445569c94cff8ff03fb +dedeeffcff0ddeffe58bff6e6ffffebde597bdbef9ff00f0f8ff0cfdaeefffda55b4ab586554954b +f4ff01fc4efdff08feeda49fd88989b59ff7ff05d445569c94cff8ff03fbdedeeffcff0ddeffe58b +ff6e6ffffebde597bdbef9ff00f0f7ff0bfabdfffcbb49e6bf7654854ff4ff01f95efbff05fd67aa +b75558f6ff05f945669859dff7ff008ffaff0fa4cff738fe579fcbfe76db549b6577affbff00f0f7 +ff0bfabdfffcbb49e6bf7654854ff4ff01f95efbff05fd67aab75558f6ff05f945669859dff7ff00 +8ffaff0fa4cff738fe579fcbfe76db549b6577affbff00f0f7ff0bfabdfffcbb49e6bf7654854ff4 +ff01f95efbff05fd67aab75558f6ff05f945669859dff7ff008ffaff0fa4cff738fe579fcbfe76db +549b6577affbff00f0f6ff0afcacfc94aa79fd6855578ff4ff01f59efbff05eefd989abdeff5ff03 +947757daf6ff009dfaff0ffb5dff56fd45eb48dfa55d849b46b6effbff00f0f6ff0afcacfc94aa79 +fd6855578ff4ff01f59efbff05eefd989abdeff5ff03947757daf6ff009dfaff0ffb5dff56fd45eb +48dfa55d849b46b6effbff00f0f6ff0afcacfc94aa79fd6855578ff4ff01f59efbff05eefd989abd +eff5ff03947757daf6ff009dfaff0ffb5dff56fd45eb48dfa55d849b46b6effbff00f0f5ff09feba +befecffcde8cd5dff4ff01e6aefaff03feefffeef4ff03f64dfffcf6ff00e8f9ff0dd6efd8ee5dd4 +36bff846d48c4c6efaff00f0f5ff09febabefecffcde8cd5dff4ff01e6aefaff03feefffeef4ff03 +f64dfffcf6ff00e8f9ff0dd6efd8ee5dd436bff846d48c4c6efaff00f0f5ff09febabefecffcde8c +d5dff4ff01e6aefaff03feefffeef4ff03f64dfffcf6ff00e8f9ff0dd6efd8ee5dd436bff846d48c +4c6efaff00f0f3ffffbb00cefeff00e5f3ff0198ccf8ff01efdff4ff04fd58fff97ff7ff00f8f9ff +0efa6fffffec59358876446467558aeffbff00f0f3ffffbb00cefeff00e5f3ff0198ccf8ff01efdf +f4ff04fd58fff97ff7ff00f8f9ff0efa6fffffec59358876446467558aeffbff00f0f3ffffbb00ce +feff00e5f3ff0198ccf8ff01efdff4ff04fd58fff97ff7ff00f8f9ff0efa6fffffec593588764464 +67558aeffbff00f0f1ff04ecbcceff69f3ff025cfacee9ff03a4cffb58f7ff01fbcffbff0fcaa957 +766664678889bdeff9fffffebffbff00f0f1ff04ecbcceff69f3ff025cfacee9ff03a4cffb58f7ff +01fbcffbff0fcaa957766664678889bdeff9fffffebffbff00f0f1ff04ecbcceff69f3ff025cface +e9ff03a4cffb58f7ff01fbcffbff0fcaa957766664678889bdeff9fffffebffbff00f0efff02fdc9 +4ef4ff03fd3efbcde9ff04f77ffe46dff7ff009ffbff047bcc89bceffbff00fafeff00bffbff00f0 +efff02fdc94ef4ff03fd3efbcde9ff04f77ffe46dff7ff009ffbff047bcc89bceffbff00fafeff00 +bffbff00f0efff02fdc94ef4ff03fd3efbcde9ff04f77ffe46dff7ff009ffbff047bcc89bceffbff +00fafeff00bffbff00f0eeff01f96ff4ff03f73cfedde9ff04fb4dffa78ef7ff00dafbff028fffcf +f9ff04fafffffebffbff00f0eeff01f96ff4ff03f73cfedde9ff04fb4dffa78ef7ff00dafbff028f +ffcff9ff04fafffffebffbff00f0eeff01f96ff4ff03f73cfedde9ff04fb4dffa78ef7ff00dafbff +028fffcff9ff04fafffffebffbff00f0eeff01f4cff4ff03d54efffee8ff0498fff5d7eef8ff01f9 +effcff029ffeaffdff08eddbba9997ab79adbffbff00f0eeff01f4cff4ff03d54efffee8ff0498ff +f5d7eef8ff01f9effcff029ffeaffdff08eddbba9997ab79adbffbff00f0eeff01f4cff4ff03d54e +fffee8ff0498fff5d7eef8ff01f9effcff029ffeaffdff08eddbba9997ab79adbffbff00f0eeff00 +c6f3ff027956dfe7ff04e5eff78e7df8ff01fe9ffdff10fd787658a987765445785796a8dd55a9cf +fbff00f0eeff00c6f3ff027956dfe7ff04e5eff78e7df8ff01fe9ffdff10fd787658a98776544578 +5796a8dd55a9cffbff00f0eeff00c6f3ff027956dfe7ff04e5eff78e7df8ff01fe9ffdff10fd7876 +58a987765445785796a8dd55a9cffbff00f0eeff007af4ff02fc5fb7e6ff05f56ff95fe9cff8ff00 +dbfdff0ffe9a7684bbb968d74bff78f9fedf97dffaff00f0eeff007af4ff02fc5fb7e6ff05f56ff9 +5fe9cff8ff00dbfdff0ffe9a7684bbb968d74bff78f9fedf97dffaff00f0eeff007af4ff02fc5fb7 +e6ff05f56ff95fe9cff8ff00dbfdff0ffe9a7684bbb968d74bff78f9fedf97dffaff00f0efff01fe +4ef4ff02f78f95f1ff00edf7ff06fd5dfa4effaaeff9ff01fbdffcff0d9bd5fffe6af94aff77f9ff +efe7dffaff00f0efff01fe4ef4ff02f78f95f1ff00edf7ff06fd5dfa4effaaeff9ff01fbdffcff0d +9bd5fffe6af94aff77f9ffefe7dffaff00f0efff01fe4ef4ff02f78f95f1ff00edf7ff06fd5dfa4e +ffaaeff9ff01fbdffcff0d9bd5fffe6af94aff77f9ffefe7dffaff00f0efff01fb6ff4ff03c4efb6 +8ef4ff05feeeb4aeffecf9ff0688fc4afffe89eff9ff00aefcff0d8bb5ffff6afa49ff77f9fffff7 +dffaff00f0efff01fb6ff4ff03c4efb68ef4ff05feeeb4aeffecf9ff0688fc4afffe89eff9ff00ae +fcff0d8bb5ffff6afa49ff77f9fffff7dffaff00f0efff01fb6ff4ff03c4efb68ef4ff05feeeb4ae +ffecf9ff0688fc4afffe89eff9ff00aefcff0d8bb5ffff6afa49ff77f9fffff7dffaff00f0efff01 +f7aff5ff05fe59ffd85eeff5ff0596678959ddddf9ff07e6bd59fffffd99aefaff01f98efdff0d6b +c5ffff5afa48ff86f8ffeff7dffaff00f0efff01f7aff5ff05fe59ffd85eeff5ff0596678959dddd +f9ff07e6bd59fffffd99aefaff01f98efdff0d6bc5ffff5afa48ff86f8ffeff7dffaff00f0efff01 +f7aff5ff05fe59ffd85eeff5ff0596678959ddddf9ff07e6bd59fffffd99aefaff01f98efdff0d6b +c5ffff5afa48ff86f8ffeff7dffaff00f0efff01f4eff5ff05f77ffffc668ff2ff05c8667878888b +fcff02fb6c59fdff02d98beffbff01e8effeff0d7ad6fffe5afb49ff75f8fffff7dffaff00f0efff +01f4eff5ff05f77ffffc668ff2ff05c8667878888bfcff02fb6c59fdff02d98beffbff01e8effeff +0d7ad6fffe5afb49ff75f8fffff7dffaff00f0efff01f4eff5ff05f77ffffc668ff2ff05c8667878 +888bfcff02fb6c59fdff02d98beffbff01e8effeff0d7ad6fffe5afb49ff75f8fffff7dffaff00f0 +efff00c5f4ff05a6efffff754df3ff05ecbcccddeeeffaff01685afcff03fb78adeffeff02ebaaef +feff0d7bd6ffff4bfb4aff75f8fffff7dffaff00f0efff00c5f4ff05a6efffff754df3ff05ecbccc +ddeeeffaff01685afcff03fb78adeffeff02ebaaeffeff0d7bd6ffff4bfb4aff75f8fffff7dffaff +00f0efff00c5f4ff05a6efffff754df3ff05ecbcccddeeeffaff01685afcff03fb78adeffeff02eb +aaeffeff0d7bd6ffff4bfb4aff75f8fffff7dffaff00f0efff0089f5ff01e76ffeff01fb6bf5ff06 +fd66787765458df9ff01a46cfaff05c988999989befcff0d7bc7ffff5afc59ff76f8fffff6dffaff +00f0efff0089f5ff01e76ffeff01fb6bf5ff06fd66787765458df9ff01a46cfaff05c988999989be +fcff0d7bc7ffff5afc59ff76f8fffff6dffaff00f0efff0089f5ff01e76ffeff01fb6bf5ff06fd66 +787765458df9ff01a46cfaff05c988999989befcff0d7bc7ffff5afc59ff76f8fffff6dffaff00f0 +efff005ef6ff02fe55dffdff00abf5ff01f5affeff03feb858effbff01d54eefff0d8bc7fffe4afc +5aff77f8fffff6effaff00f0efff005ef6ff02fe55dffdff00abf5ff01f5affeff03feb858effbff +01d54eefff0d8bc7fffe4afc5aff77f8fffff6effaff00f0efff005ef6ff02fe55dffdff00abf5ff +01f5affeff03feb858effbff01d54eefff0d8bc7fffe4afc5aff77f8fffff6effaff00f0f0ff01fb +5ff6ff01c44dfcff00eff5ff0098fbff01d74bfbff02fc4beff0ff0d7bb7fffe4afd4aff87f8ffff +f6effaff00f0f0ff01fb5ff6ff01c44dfcff00eff5ff0098fbff01d74bfbff02fc4beff0ff0d7bb7 +fffe4afd4aff87f8fffff6effaff00f0f0ff01fb5ff6ff01c44dfcff00eff5ff0098fbff01d74bfb +ff02fc4beff0ff0d7bb7fffe4afd4aff87f8fffff6effaff00f0f0ff01f6bff7ff02fd44cff0ff01 +fc4dfaff01b58efbff0474dfedc88af3ff0d7bb7fffe49fe4bff78f7fffff6effaff00f0f0ff01f6 +bff7ff02fd44cff0ff01fc4dfaff01b58efbff0474dfedc88af3ff0d7bb7fffe49fe4bff78f7ffff +f6effaff00f0f0ff01f6bff7ff02fd44cff0ff01fc4dfaff01b58efbff0474dfedc88af3ff0d7bb7 +fffe49fe4bff78f7fffff6effaff00f0f0ff00b5f6ff01b55cefff04f6cfb6448efcff01a5affcff +0596544557776df4ff0d7bb7fffe49fe4cff78f8fffff6effaff00f0f0ff00b5f6ff01b55cefff04 +f6cfb6448efcff01a5affcff0596544557776df4ff0d7bb7fffe49fe4cff78f8fffff6effaff00f0 +f0ff00b5f6ff01b55cefff04f6cfb6448efcff01a5affcff0596544557776df4ff0d7bb7fffe49fe +4cff78f8fffff6effaff00f0f1ff01fe5cf8ff03fea658efefff05e6f8357755dffdff02fd66bffc +ff00fefeff01d5eff5ff0d7ba8fffe49fe4cff88f7fffff6effaff00f0f1ff01fe5cf8ff03fea658 +efefff05e6f8357755dffdff02fd66bffcff00fefeff01d5eff5ff0d7ba8fffe49fe4cff88f7ffff +f6effaff00f0f1ff01fe5cf8ff03fea658efefff05e6f8357755dffdff02fd66bffcff00fefeff01 +d5eff5ff0d7ba8fffe49fe4cff88f7fffff6effaff00f0f1ff01f59ff9ff03eb7457afeeff05a8a3 +7ffffceffcff02fa57dff9ff01fa8ff5ff0d7bb8fffd4afe4dff89f7fffff6effaff00f0f1ff01f5 +9ff9ff03eb7457afeeff05a8a37ffffceffcff02fa57dff9ff01fa8ff5ff0d7bb8fffd4afe4dff89 +f7fffff6effaff00f0f1ff01f59ff9ff03eb7457afeeff05a8a37ffffceffcff02fa57dff9ff01fa +8ff5ff0d7bb8fffd4afe4dff89f7fffff6effaff00f0f1ff0086fbff05eca876678ccdedff027d53 +bff8ff01e75bf8ff005ff5ff0c7cb8fffd4afe4cffacf8fffff6f9ff00f0f1ff0086fbff05eca876 +678ccdedff027d53bff8ff01e75bf8ff005ff5ff0c7cb8fffd4afe4cffacf8fffff6f9ff00f0f1ff +0086fbff05eca876678ccdedff027d53bff8ff01e75bf8ff005ff5ff0c7cb8fffd4afe4cffacf8ff +fff6f9ff00f0f2ff01fa4efdff08fb75468beffe9db9efeeff026d84eff7ff0185aff9ff006df5ff +0c6cb8fffc4bfb4dff8cf7fffff5f9ff00f0f2ff01fa4efdff08fb75468beffe9db9efeeff026d84 +eff7ff0185aff9ff006df5ff0c6cb8fffc4bfb4dff8cf7fffff5f9ff00f0f2ff01fa4efdff08fb75 +468beffe9db9efeeff026d84eff7ff0185aff9ff006df5ff0c6cb8fffc4bfb4dff8cf7fffff5f9ff +00f0f2ff01a4dffeff03f95799bffeff02fa8abfeeff076dc5ffffc74579effcff00faf8ff008bf5 +ff0c6ca9fffc4bfb4cff8cf7fffff5f9ff00f0f2ff01a4dffeff03f95799bffeff02fa8abfeeff07 +6dc5ffffc74579effcff00faf8ff008bf5ff0c6ca9fffc4bfb4cff8cf7fffff5f9ff00f0f2ff01a4 +dffeff03f95799bffeff02fa8abfeeff076dc5ffffc74579effcff00faf8ff008bf5ff0c6ca9fffc +4bfb4cff8cf7fffff5f9ff00f0f3ff01fa4cfdff0284efe9fdff02fe87bfeeff07befdffff75dca6 +5ef2ff00a9f5ff0c6da9fffc4bfb4cff8bf7fffff5f9ff00f0f3ff01fa4cfdff0284efe9fdff02fe +87bfeeff07befdffff75dca65ef2ff00a9f5ff0c6da9fffc4bfb4cff8bf7fffff5f9ff00f0f3ff01 +fa4cfdff0284efe9fdff02fe87bfeeff07befdffff75dca65ef2ff00a9f5ff0c6da9fffc4bfb4cff +8bf7fffff5f9ff00f0f3ff0173bffeff03fd4bff9dfcff01c4efeeff07dcfffffe43643567f2ff00 +a9f5ff0c6c99fffb4bfb4cff8cf7fffff5f9ff00f0f3ff0173bffeff03fd4bff9dfcff01c4efeeff +07dcfffffe43643567f2ff00a9f5ff0c6c99fffb4bfb4cff8cf7fffff5f9ff00f0f3ff0173bffeff +03fd4bff9dfcff01c4efeeff07dcfffffe43643567f2ff00a9f5ff0c6c99fffb4bfb4cff8cf7ffff +f5f9ff00f0f4ff01f939fdff03f66fff7ffcff00f6f2ff00cefaff06fe433333569adff5ff01db7c +f5ff0c5d99fffb4aa539ff7cf7fffff5f9ff00f0f4ff01f939fdff03f66fff7ffcff00f6f2ff00ce +faff06fe433333569adff5ff01db7cf5ff0c5d99fffb4aa539ff7cf7fffff5f9ff00f0f4ff01f939 +fdff03f66fff7ffcff00f6f2ff00cefaff06fe433333569adff5ff01db7cf5ff0c5d99fffb4aa539 +ff7cf7fffff5f9ff00f0f4ff01f57ffdff03b4bfff7ffcff01f7bff4ff01edeffaff06fe6333333b +546ef6ff02fe875ff5ff0c6da9fffb479dc6bf6cf7fffff5f9ff00f0f4ff01f57ffdff03b4bfff7f +fcff01f7bff4ff01edeffaff06fe6333333b546ef6ff02fe875ff5ff0c6da9fffb479dc6bf6cf7ff +fff5f9ff00f0f4ff01f57ffdff03b4bfff7ffcff01f7bff4ff01edeffaff06fe6333333b546ef6ff +02fe875ff5ff0c6da9fffb479dc6bf6cf7fffff5f9ff00f0f4ff09f4effea69ec849fffe8ffcff01 +f85ff6ff02fe866df8ff05e633334d553af6ff02f7577ff5ff0c5db8fffb46ffec5e6cf7fffff5f9 +ff00f0f4ff09f4effea69ec849fffe8ffcff01f85ff6ff02fe866df8ff05e633334d553af6ff02f7 +577ff5ff0c5db8fffb46ffec5e6cf7fffff5f9ff00f0f4ff09f4effea69ec849fffe8ffcff01f85f +f6ff02fe866df8ff05e633334d553af6ff02f7577ff5ff0c5db8fffb46ffec5e6cf7fffff5f9ff00 +f0f4ff09f77863577347dffffb9ffcff01f95bf6ff01d6aef6ff04b8aeff5b46f6ff0283447ff5ff +0c6ec8fffb4afff9344497ffffe5f9ff00f0f4ff09f77863577347dffffb9ffcff01f95bf6ff01d6 +aef6ff04b8aeff5b46f6ff0283447ff5ff0c6ec8fffb4afff9344497ffffe5f9ff00f0f4ff09f778 +63577347dffffb9ffcff01f95bf6ff01d6aef6ff04b8aeff5b46f6ff0283447ff5ff0c6ec8fffb4a +fff9344497ffffe5f9ff00f0f4ff09fe99abfffedffffffabffcff01f8c9f6ff005df2ff026cb3ef +f8ff03f84334cff5ff0c5eb9fffb38ffe46745a7fffeb6f9ff00f0f4ff09fe99abfffedffffffabf +fcff01f8c9f6ff005df2ff026cb3eff8ff03f84334cff5ff0c5eb9fffb38ffe46745a7fffeb6f9ff +00f0f4ff09fe99abfffedffffffabffcff01f8c9f6ff005df2ff026cb3eff8ff03f84334cff5ff0c +5eb9fffb38ffe46745a7fffeb6f9ff00f0ecff01f9dffcfffff8f2ff01baeff7ff025ce4aff9ff03 +fe743337f4ff0c5eb8fffa45ffe5ff6cf7eadda6f9ff00f0ecff01f9dffcfffff8f2ff01baeff7ff +025ce4aff9ff03fe743337f4ff0c5eb8fffa45ffe5ff6cf7eadda6f9ff00f0ecff01f9dffcfffff8 +f2ff01baeff7ff025ce4aff9ff03fe743337f4ff0c5eb8fffa45ffe5ff6cf7eadda6f9ff00f0ecff +01f8dffcfffff8f3ff05c5464afffffefbff03fe6ff57ffaff04feb643345ef4ff0c4eb8fff944cf +88ff5bf7a37ba6f9ff00f0ecff01f8dffcfffff8f3ff05c5464afffffefbff03fe6ff57ffaff04fe +b643345ef4ff0c4eb8fff944cf88ff5bf7a37ba6f9ff00f0ecff01f8dffcfffff8f3ff05c5464aff +fffefbff03fe6ff57ffaff04feb643345ef4ff0c4eb8fff944cf88ff5bf7a37ba6f9ff00f0ecff01 +f9cffcff01f9e7f3ff05aedfe5bffdeff9ff01f99ffbff05eed7433346bff4ff0c4db9fff846df59 +ff6bf7a35ca7f9ff00f0ecff01f9cffcff01f9e7f3ff05aedfe5bffdeff9ff01f99ffbff05eed743 +3346bff4ff0c4db9fff846df59ff6bf7a35ca7f9ff00f0ecff01f9cffcff01f9e7f3ff05aedfe5bf +fdeff9ff01f99ffbff05eed7433346bff4ff0c4db9fff846df59ff6bf7a35ca7f9ff00f0ecff01f9 +cffcff02fac8dff2ff02fc4df8f0ff04fc64333378f3ff0c4ca9fff639ee84af5bf7834b97f9ff00 +f0ecff01f9cffcff02fac8dff2ff02fc4df8f0ff04fc64333378f3ff0c4ca9fff639ee84af5bf783 +4b97f9ff00f0ecff01f9cffcff02fac8dff2ff02fc4df8f0ff04fc64333378f3ff0c4ca9fff639ee +84af5bf7834b97f9ff00f0ecff01fabffbff01a85ef1ff0179e8f1ff05fe853333356ef3ff0c4da5 +585445759a5a5bf7c69b97f9ff00f0ecff01fabffbff01a85ef1ff0179e8f1ff05fe853333356ef3 +ff0c4da5585445759a5a5bf7c69b97f9ff00f0ecff01fabffbff01a85ef1ff0179e8f1ff05fe8533 +33356ef3ff0c4da5585445759a5a5bf7c69b97f9ff00f0ecff01fb9ffaff0097f1ff01d6aaf1ff05 +e743433346dff3ff0c4da85eedba8654444bf7edfb97f9ff00f0ecff01fb9ffaff0097f1ff01d6aa +f1ff05e743433346dff3ff0c4da85eedba8654444bf7edfb97f9ff00f0ecff01fb9ffaff0097f1ff +01d6aaf1ff05e743433346dff3ff0c4da85eedba8654444bf7edfb97f9ff00f0ecff01fd8ffaff01 +e6cff2ff01f96af2ff05fe743433346ef2ff0c5d8668aceffffffe5bf7effc97f9ff00f0ecff01fd +8ffaff01e6cff2ff01f96af2ff05fe743433346ef2ff0c5d8668aceffffffe5bf7effc97f9ff00f0 +ecff01fd8ffaff01e6cff2ff01f96af2ff05fe743433346ef2ff0c5d8668aceffffffe5bf7effc97 +f9ff00f0ecff01fe7ffaff01f89ff2ff01fe58f4ff07feede744443346dff2ff0c7d746456555666 +685bf7fffd98f9ff00f0ecff01fe7ffaff01f89ff2ff01fe58f4ff07feede744443346dff2ff0c7d +746456555666685bf7fffd98f9ff00f0ecff01fe7ffaff01f89ff2ff01fe58f4ff07feede7444433 +46dff2ff0c7d746456555666685bf7fffd98f9ff00f0ebff007ffaff01eb8ff1ff00b5f2ff05c889 +755459eff2ff0c6c8555bfffffec585bf7fffda8f9ff00f0ebff007ffaff01eb8ff1ff00b5f2ff05 +c889755459eff2ff0c6c8555bfffffec585bf7fffda8f9ff00f0ebff007ffaff01eb8ff1ff00b5f2 +ff05c889755459eff2ff0c6c8555bfffffec585bf7fffda8f9ff00f0ebff007ffaff01bd8ff1ff01 +f6cff3ff09eeffedbafd8efffeeedff7ff04fe696597fefeff05d55bf6fffea9f9ff00f0ebff007f +faff01bd8ff1ff01f6cff3ff09eeffedbafd8efffeeedff7ff04fe696597fefeff05d55bf6fffea9 +f9ff00f0ebff007ffaff01bd8ff1ff01f6cff3ff09eeffedbafd8efffeeedff7ff04fe696597fefe +ff05d55bf6fffea9f9ff00f0ebff007efaff01db9cf1ff01fb8feeff06fb67656764666dfaff0efd +84434658abceeeecb64af6fffea8f9ff00f0ebff007efaff01db9cf1ff01fb8feeff06fb67656764 +666dfaff0efd84434658abceeeecb64af6fffea8f9ff00f0ebff007efaff01db9cf1ff01fb8feeff +06fb67656764666dfaff0efd84434658abceeeecb64af6fffea8f9ff00f0ebff009bfaff01f9c8f0 +ff007eedff05ccfffebefe7afaff0ef86aa98999a8764444364af6fffea9f9ff00f0ebff009bfaff +01f9c8f0ff007eedff05ccfffebefe7afaff0ef86aa98999a8764444364af6fffea9f9ff00f0ebff +009bfaff01f9c8f0ff007eedff05ccfffebefe7afaff0ef86aa98999a8764444364af6fffea9f9ff +00f0ebff00bafaff02fe95acf1ff00d8edff06fbdf97cceee6effbff0eb86544665567594666444a +e6fffd9af9ff00f0ebff00bafaff02fe95acf1ff00d8edff06fbdf97cceee6effbff0eb865446655 +67594666444ae6fffd9af9ff00f0ebff00bafaff02fe95acf1ff00d8edff06fbdf97cceee6effbff +0eb86544665567594666444ae6fffd9af9ff00f0ebff00d8f9ff03fbcb88eff3ff01fd8feeff06fe +9eb4386efc7ffbff0efeb764957acb5756544649d5fffd8af9ff00f0ebff00d8f9ff03fbcb88eff3 +ff01fd8feeff06fe9eb4386efc7ffbff0efeb764957acb5756544649d5fffd8af9ff00f0ebff00d8 +f9ff03fbcb88eff3ff01fd8feeff06fe9eb4386efc7ffbff0efeb764957acb5756544649d5fffd8a +f9ff00f0ebff00f7f9ff04fcbffd88eff3ff00c9eeff06fd7ed5439eff8af9ff0ce5f7aefe6ecdbd +dc58d6fffc8af9ff00f0ebff00f7f9ff04fcbffd88eff3ff00c9eeff06fd7ed5439eff8af9ff0ce5 +f7aefe6ecdbddc58d6fffc8af9ff00f0ebff00f7f9ff04fcbffd88eff3ff00c9eeff06fd7ed5439e +ff8af9ff0ce5f7aefe6ecdbddc58d6fffc8af9ff00f0ebff00f7f8ff03baacfd7cf3ff01fc9ff2ff +0aeffebaa638e8547fffd5dffaff0ce5f6adec58deebba57e6fffb8af9ff00f0ebff00f7f8ff03ba +acfd7cf3ff01fc9ff2ff0aeffebaa638e8547fffd5dffaff0ce5f6adec58deebba57e6fffb8af9ff +00f0ebff00f7f8ff03baacfd7cf3ff01fc9ff2ff0aeffebaa638e8547fffd5dffaff0ce5f6adec58 +deebba57e6fffb8af9ff00f0ebff01facff8ff03eb9cf7dff3ff0186cff7ff0ec96655556798674a +54ba555cfffc6dfbff10feb5b76554445569a738f6fffa88ccccdffcff00f0ebff01facff8ff03eb +9cf7dff3ff0186cff7ff0ec96655556798674a54ba555cfffc6dfbff10feb5b76554445569a738f6 +fffa88ccccdffcff00f0ebff01facff8ff03eb9cf7dff3ff0186cff7ff0ec96655556798674a54ba +555cfffc6dfbff10feb5b76554445569a738f6fffa88ccccdffcff00f0ebff01fd9ff7ff02fab86a +f3ff1be749effecbceefffeed996543344444333334bdeb36a454779bec68efcff00b6fc440b5444 +564ae6fffd855554456dfdff00f0ebff01fd9ff7ff02fab86af3ff1be749effecbceefffeed99654 +3344444333334bdeb36a454779bec68efcff00b6fc440b5444564ae6fffd855554456dfdff00f0eb +ff01fd9ff7ff02fab86af3ff1be749effecbceefffeed996543344444333334bdeb36a454779bec6 +8efcff00b6fc440b5444564ae6fffd855554456dfdff00f0eaff006ff7ff02fe99e7f2ff08a45553 +3469cdcdb643fa3322349ffff73435469766774688898899996444455555455555454af6ffff8645 +4444489afeff00f0eaff006ff7ff02fe99e7f2ff08a455533469cdcdb643fa3322349ffff7343546 +9766774688898899996444455555455555454af6ffff86454444489afeff00f0eaff006ff7ff02fe +99e7f2ff08a455533469cdcdb643fa3322349ffff734354697667746888988999964444555554555 +55454af6ffff86454444489afeff00f0eaff008df7ff02f9e8f8f2ff06fc445bdcdb9754fc331034 +44334438fffffd455844678bdfdacebafeab00a8fb990f98775cf5efff78bbcbaaaab77ffffff0ea +ff008df7ff02f9e8f8f2ff06fc445bdcdb9754fc33103444334438fffffd455844678bdfdacebafe +ab00a8fb990f98775cf5efff78bbcbaaaab77ffffff0eaff008df7ff02f9e8f8f2ff06fc445bdcdb +9754fc33103444334438fffffd455844678bdfdacebafeab00a8fb990f98775cf5efff78bbcbaaaa +b77ffffff0eaff00d8f7ff02f8d9acf1ff04e534444343fd33134433456655437ffffffe466857ec +a37be8788767fe8815778799998aaabbba5bc5efff7899866658869ffffff0eaff00d8f7ff02f8d9 +acf1ff04e534444343fd33134433456655437ffffffe466857eca37be8788767fe8815778799998a +aabbba5bc5efff7899866658869ffffff0eaff00d8f7ff02f8d9acf1ff04e534444343fd33134433 +456655437ffffffe466857eca37be8788767fe8815778799998aaabbba5bc5efff7899866658869f +fffff0eaff00f7f7ff02f98e8ef1ff0ffc74333334688887abcbaaefefded9affeff22488666fed3 +47c49ddcbbaabbba75a469c85cccdccb7db5cffe7cfff8bd6ff9cffffff0eaff00f7f7ff02f98e8e +f1ff0ffc74333334688887abcbaaefefded9affeff22488666fed347c49ddcbbaabbba75a469c85c +ccdccb7db5cffe7cfff8bd6ff9cffffff0eaff00f7f7ff02f98e8ef1ff0ffc74333334688887abcb +aaefefded9affeff22488666fed347c49ddcbbaabbba75a469c85cccdccb7db5cffe7cfff8bd6ff9 +cffffff0eaff00f7f7ff02f78f8fefff03edcdddeff9ff01fd8ffeff0757b585dfe447c4bffcff04 +86e49efa7ffeff0d8ee5cffd7dfff8ce6ff9dffffff0eaff00f7f7ff02f78f8fefff03edcdddeff9 +ff01fd8ffeff0757b585dfe447c4bffcff0486e49efa7ffeff0d8ee5cffd7dfff8ce6ff9dffffff0 +eaff00f7f7ff02f78f8fefff03edcdddeff9ff01fd8ffeff0757b585dfe447c4bffcff0486e49efa +7ffeff0d8ee5cffd7dfff8ce6ff9dffffff0eaff01f8dff8ff02f78cafedff00fcf8ff0cfe7fffff +fe58c6949fe559b4dffcff04a7f48fe99ffeff0d8ff5dffe6dfff9ce6ff9dffffff0eaff01f8dff8 +ff02f78cafedff00fcf8ff0cfe7ffffffe58c6949fe559b4dffcff04a7f48fe99ffeff0d8ff5dffe +6dfff9ce6ff9dffffff0eaff01f8dff8ff02f78cafedff00fcf8ff0cfe7ffffffe58c6949fe559b4 +dffcff04a7f48fe99ffeff0d8ff5dffe6dfff9ce6ff9dffffff0eaff01fbaff8ff02f96cafe3ff0b +fb8ffffffe58d8955ff65cb6fbff1596e58ff88ffffffd7ee5dfff6dfff8cd7ff9effffff0eaff01 +fbaff8ff02f96cafe3ff0bfb8ffffffe58d8955ff65cb6fbff1596e58ff88ffffffd7ee5dfff6dff +f8cd7ff9effffff0eaff01fbaff8ff02f96cafe3ff0bfb8ffffffe58d8955ff65cb6fbff1596e58f +f88ffffffd7ee5dfff6dfff8cd7ff9effffff0e9ff007ff7ff01798fe3ff0bf6dffffffd58e7765e +f66e97fbff1596f57ff98ffffffd7ff5efff6dfff8dd8ff8effffff0e9ff007ff7ff01798fe3ff0b +f6dffffffd58e7765ef66e97fbff1596f57ff98ffffffd7ff5efff6dfff8dd8ff8effffff0e9ff00 +7ff7ff01798fe3ff0bf6dffffffd58e7765ef66e97fbff1596f57ff98ffffffd7ff5efff6dfff8dd +8ff8effffff0e9ff00baf7ff01f66ce3ff00c6feff07fd69e6685be66f88fbff1196f59ff99fffff +fe8fe6ffff5efff8ec9ff7feff00f0e9ff00baf7ff01f66ce3ff00c6feff07fd69e6685be66f88fb +ff1196f59ff99ffffffe8fe6ffff5efff8ec9ff7feff00f0e9ff00baf7ff01f66ce3ff00c6feff07 +fd69e6685be66f88fbff1196f59ff99ffffffe8fe6ffff5efff8ec9ff7feff00f0e9ff00f7f7ff03 +fe87fffde6ff01fe7dfeff07fc5af67938d67f6afbff04a5d59ff89ffeff099fe7ffff5efff8fbaf +f7feff00f0e9ff00f7f7ff03fe87fffde6ff01fe7dfeff07fc5af67938d67f6afbff04a5d59ff89f +feff099fe7ffff5efff8fbaff7feff00f0e9ff00f7f7ff03fe87fffde6ff01fe7dfeff07fc5af679 +38d67f6afbff04a5d59ff89ffeff099fe7ffff5efff8fbaff7feff00f0e9ff01f9cff7ff02fbbff7 +e7ff02fd88effeff07fb5ce67935d78e5efbff0495c49ff89ffeff099fe7ffff5efff8fabff6feff +00f0e9ff01f9cff7ff02fbbff7e7ff02fd88effeff07fb5ce67935d78e5efbff0495c49ff89ffeff +099fe7ffff5efff8fabff6feff00f0e9ff01f9cff7ff02fbbff7e7ff02fd88effeff07fb5ce67935 +d78e5efbff0495c49ff89ffeff099fe7ffff5efff8fabff6feff00f0e9ff01fd8ff6ff01aee8eaff +fffe02b88aeffdff07fb4ec8a944b7ad5ffbff0496c49ff7affeff099fe7ffff5ffff8f9dff7feff +00f0e9ff01fd8ff6ff01aee8eafffffe02b88aeffdff07fb4ec8a944b7ad5ffbff0496c49ff7affe +ff099fe7ffff5ffff8f9dff7feff00f0e9ff01fd8ff6ff01aee8eafffffe02b88aeffdff07fb4ec8 +a944b7ad5ffbff0496c49ff7affeff099fe7ffff5ffff8f9dff7feff00f0e8ff007ef6ff03fac9ff +dff1ff07db967665555788cffbff07fb4eb8d67587c97ffbff0486d49fe7affeff099fe7ffff6fff +f8f8efe6feff00f0e8ff007ef6ff03fac9ffdff1ff07db967665555788cffbff07fb4eb8d67587c9 +7ffbff0486d49fe7affeff099fe7ffff6ffff8f8efe6feff00f0e8ff007ef6ff03fac9ffdff1ff07 +db967665555788cffbff07fb4eb8d67587c97ffbff0486d49fe7affeff099fe7ffff6ffff8f8efe6 +feff00f0e8ff00b8f6ff03fac9ffdff2ff06b643333343334ef9ff07f95faae6a566d79ffbff1186 +d49fe6affffffe8fe8ffff6ffff8f8ffd5feff00f0e8ff00b8f6ff03fac9ffdff2ff06b643333343 +334ef9ff07f95faae6a566d79ffbff1186d49fe6affffffe8fe8ffff6ffff8f8ffd5feff00f0e8ff +00b8f6ff03fac9ffdff2ff06b643333343334ef9ff07f95faae6a566d79ffbff1186d49fe6afffff +fe8fe8ffff6ffff8f8ffd5feff00f0e8ff01f9bff7ff03cbb9fe8ff4ff01fe94fb33007ff9ff07f8 +6f8af7d655d5dffbff1186d4aff5affffffe7fe8ffff7ffff7f7ffb5feff00f0e8ff01f9bff7ff03 +cbb9fe8ff4ff01fe94fb33007ff9ff07f86f8af7d655d5dffbff1186d4aff5affffffe7fe8ffff7f +fff7f7ffb5feff00f0e8ff01f9bff7ff03cbb9fe8ff4ff01fe94fb33007ff9ff07f86f8af7d655d5 +dffbff1186d4aff5affffffe7fe8ffff7ffff7f7ffb5feff00f0e7ff007ef7ff03adc9fadff4ff08 +b544333334333434dff9ff06f76f7bf97656e5faff0496e3bff4cffeff099fe8ffff7fffe8f7ffc8 +feff00f0e7ff007ef7ff03adc9fadff4ff08b544333334333434dff9ff06f76f7bf97656e5faff04 +96e3bff4cffeff099fe8ffff7fffe8f7ffc8feff00f0e7ff007ef7ff03adc9fadff4ff08b5443333 +34333434dff9ff06f76f7bf97656e5faff0496e3bff4cffeff099fe8ffff7fffe8f7ffc8feff00f0 +e7ff00d9f7ff03cae7f8fef4ff0083fc33014339f8ff06f68f6dfc5947c5faff11a5e3cff4aaa978 +998fd8fffc49ffe8f7ffcbfeff00f0e7ff00d9f7ff03cae7f8fef4ff0083fc33014339f8ff06f68f +6dfc5947c5faff11a5e3cff4aaa978998fd8fffc49ffe8f7ffcbfeff00f0e7ff00d9f7ff03cae7f8 +fef4ff0083fc33014339f8ff06f68f6dfc5947c5faff11a5e3cff4aaa978998fd8fffc49ffe8f7ff +cbfeff00f0e7ff01facff8ff02f7e8c7f3ff079c665655469de63af8ff1ff59f6ffe4b48c4666777 +6678776656d4cff49bbba9978fc7fffe546db8f7ffcafeff00f0e7ff01facff8ff02f7e8c7f3ff07 +9c665655469de63af8ff1ff59f6ffe4b48c46667776678776656d4cff49bbba9978fc7fffe546db8 +f7ffcafeff00f0e7ff01facff8ff02f7e8c7f3ff079c665655469de63af8ff1ff59f6ffe4b48c466 +67776678776656d4cff49bbba9978fc7fffe546db8f7ffcafeff00f0e6ff008ef8ff04fe8977fffc +f4ff07c58e7ad9cfe864cff9ff1fe59f6ffe7769c6eeeedddeddeeffc5e4cfd4dffffffb9fd7ffff +ac6478e8ffcafeff00f0e6ff008ef8ff04fe8977fffcf4ff07c58e7ad9cfe864cff9ff1fe59f6ffe +7769c6eeeedddeddeeffc5e4cfd4dffffffb9fd7ffffac6478e8ffcafeff00f0e6ff008ef8ff04fe +8977fffcf4ff07c58e7ad9cfe864cff9ff1fe59f6ffe7769c6eeeedddeddeeffc5e4cfd4dffffffb +9fd7ffffac6478e8ffcafeff00f0e6ff01e7eff8ff0afa45dffcfffdbefdfffaeffbff07f7cd6ffc +bffbf86ff9ff07b69e6fffd46bd49efbff11c6f3cfe4effffffccfe9fffe9ffc67d9ffbbfeff00f0 +e6ff01e7eff8ff0afa45dffcfffdbefdfffaeffbff07f7cd6ffcbffbf86ff9ff07b69e6fffd46bd4 +9efbff11c6f3cfe4effffffccfe9fffe9ffc67d9ffbbfeff00f0e6ff01e7eff8ff0afa45dffcfffd +befdfffaeffbff07f7cd6ffcbffbf86ff9ff07b69e6fffd46bd49efbff11c6f3cfe4effffffccfe9 +fffe9ffc67d9ffbbfeff00f0e6ff01fe7cf8ff09fe74affcfcfe8cefffb6faff07fa9a8efe9ffffd +4df9ff08b6cd7ffff55da877dffcff11b6d4dfd4effffffddff9fffe9fffa9caffadfeff00f0e6ff +01fe7cf8ff09fe74affcfcfe8cefffb6faff07fa9a8efe9ffffd4df9ff08b6cd7ffff55da877dffc +ff11b6d4dfd4effffffddff9fffe9fffa9caffadfeff00f0e6ff01fe7cf8ff09fe74affcfcfe8cef +ffb6faff07fa9a8efe9ffffd4df9ff08b6cd7ffff55da877dffcff11b6d4dfd4effffffddff9fffe +9fffa9caffadfeff00f0e5ff01f9bff9ff02fe946ffefb03cebfff5cfaff07fe8e8afe9fcdff76f9 +ff0985e99ffff85e5adc69effdff03d6435554feff0afebff8fffe8fff8aabefaffeff00f0e5ff01 +f9bff9ff02fe946ffefb03cebfff5cfaff07fe8e8afe9fcdff76f9ff0985e99ffff85e5adc69effd +ff03d6435554feff0afebff8fffe8fff8aabefaffeff00f0e5ff01f9bff9ff02fe946ffefb03cebf +ff5cfaff07fe8e8afe9fcdff76f9ff0985e99ffff85e5adc69effdff03d6435554feff0afebff8ff +fe8fff8aabefaffeff00f0e4ff00a9f8ff08f94dfbfce8df9ffbaaf9ff06df8a9bbfd8ffb7f9ff09 +d565cffff86d658ee749fcff02ecbacefeff0afe8fe5fffe9fff6656896cfeff00f0e4ff00a9f8ff +08f94dfbfce8df9ffbaaf9ff06df8a9bbfd8ffb7f9ff09d565cffff86d658ee749fcff02ecbacefe +ff0afe8fe5fffe9fff6656896cfeff00f0e4ff00a9f8ff08f94dfbfce8df9ffbaaf9ff06df8a9bbf +d8ffb7f9ff09d565cffff86d658ee749fcff02ecbacefeff0afe8fe5fffe9fff6656896cfeff00f0 +e4ff01fc7df9ff08fd46ebfdd9cb8ef8ccf9ff06fedf97fff7ff98f8ff09faefffe89e6e859fd75b +f6ff0d56a8fffebfffcdfedd648dfffff0e4ff01fc7df9ff08fd46ebfdd9cb8ef8ccf9ff06fedf97 +fff7ff98f8ff09faefffe89e6e859fd75bf6ff0d56a8fffebfffcdfedd648dfffff0e4ff01fc7df9 +ff08fd46ebfdd9cb8ef8ccf9ff06fedf97fff7ff98f8ff09faefffe89e6e859fd75bf6ff0d56a8ff +febfffcdfedd648dfffff0e3ff01e8cff9ff0797c8febc69caf8fbf7ff04a6ffe7ff6cf5ff1fc5ae +7ffc54bfe767777665555567988899aa86455557aaaaababbbb969fffff0e3ff01e8cff9ff0797c8 +febc69caf8fbf7ff04a6ffe7ff6cf5ff1fc5ae7ffc54bfe767777665555567988899aa86455557aa +aaababbbb969fffff0e3ff01e8cff9ff0797c8febc69caf8fbf7ff04a6ffe7ff6cf5ff1fc5ae7ffc +54bfe767777665555567988899aa86455557aaaaababbbb969fffff0e2ff008ef9ff07f999aeae56 +e8f8fbf8ff05fd89bfbafb8ff5ff16a5ac9fffd536ce4cedeeeecb99aa9cddccbbbbaa99a98afeaa +05a98989fffff0e2ff008ef9ff07f999aeae56e8f8fbf8ff05fd89bfbafb8ff5ff16a5ac9fffd536 +ce4cedeeeecb99aa9cddccbbbbaa99a98afeaa05a98989fffff0e2ff008ef9ff07f999aeae56e8f8 +fbf8ff05fd89bfbafb8ff5ff16a5ac9fffd536ce4cedeeeecb99aa9cddccbbbbaa99a98afeaa05a9 +8989fffff0e2ff00edf8ff0796eaaf859ba7fcdff9ff05ebfcbf7ef6eff5ff079478affffe95344e +edff03d8fffff0e2ff00edf8ff0796eaaf859ba7fcdff9ff05ebfcbf7ef6eff5ff079478affffe95 +344eedff03d8fffff0e2ff00edf8ff0796eaaf859ba7fcdff9ff05ebfcbf7ef6eff5ff079478afff +fe95344eedff03d8fffff0d8ff07fdbb9fd85da6bfaff8ff03e9ec8f7cf4ff02fc75bffeff03d538 +99abfecc12bbabbabaaabcdeedcb98888999a9987afffff0d8ff07fdbb9fd85da6bfaff8ff03e9ec +8f7cf4ff02fc75bffeff03d53899abfecc12bbabbabaaabcdeedcb98888999a9987afffff0d8ff07 +fdbb9fd85da6bfaff8ff03e9ec8f7cf4ff02fc75bffeff03d53899abfecc12bbabbabaaabcdeedcb +98888999a9987afffff0d7ff06aad9ff96e86edcf8ff039dd7e8cff3ff00fefdff10fed787666556 +677788888999987667789bfecc01cdeefeff00f0d7ff06aad9ff96e86edcf8ff039dd7e8cff3ff00 +fefdff10fed787666556677788888999987667789bfecc01cdeefeff00f0d7ff06aad9ff96e86edc +f8ff039dd7e8cff3ff00fefdff10fed787666556677788888999987667789bfecc01cdeefeff00f0 +d8ff07fddbfd98e67e77faf9ff03f9cd7ebdd4ff00f0d8ff07fddbfd98e67e77faf9ff03f9cd7ebd +d4ff00f0d8ff07fddbfd98e67e77faf9ff03f9cd7ebdd4ff00f0d8ff08fbaffffecd8ba9adbffbff +04fe9bc7ebbfd4ff00f0d8ff08fbaffffecd8ba9adbffbff04fe9bc7ebbfd4ff00f0d8ff08fbafff +fecd8ba9adbffbff04fe9bc7ebbfd4ff00f0d8ff08bcdfffffefb7e88fbefcff04edcbee7eacd3ff +00f0d8ff08bcdfffffefb7e88fbefcff04edcbee7eacd3ff00f0d8ff08bcdfffffefb7e88fbefcff +04edcbee7eacd3ff00f0d9ff09feb9fffffeecd7e98ffafdff09f857dfe7e9efffeca99ed7ff00f0 +d9ff09feb9fffffeecd7e98ffafdff09f857dfe7e9efffeca99ed7ff00f0d9ff09feb9fffffeecd7 +e98ffafdff09f857dfe7e9efffeca99ed7ff00f0d9ff01faf8feff05c9e8e89efe9ffeff0ae76cff +8d8cfd98adfbb8ced8ff00f0d9ff01faf8feff05c9e8e89efe9ffeff0ae76cff8d8cfd98adfbb8ce +d8ff00f0d9ff01faf8feff05c9e8e89efe9ffeff0ae76cff8d8cfd98adfbb8ced8ff00f0d9ff0af9 +f8ffffdbe7ca9caeff8ffeff0b8a6ff9c8ce875effeeff8bdfd9ff00f0d9ff0af9f8ffffdbe7ca9c +aeff8ffeff0b8a6ff9c8ce875effeeff8bdfd9ff00f0d9ff0af9f8ffffdbe7ca9caeff8ffeff0b8a +6ff9c8ce875effeeff8bdfd9ff00f0d9fffff908ffeacf9e9e7eadfbbffeff0b6a7fc99cf7c746ca +47bfe8bfd9ff00f0d9fffff908ffeacf9e9e7eadfbbffeff0b6a7fc99cf7c746ca47bfe8bfd9ff00 +f0d9fffff908ffeacf9e9e7eadfbbffeff0b6a7fc99cf7c746ca47bfe8bfd9ff00f0d9ff09faebfd +bfeadf8e8f9ef9fdff0b6a8f89afe77444b8498ff7bfd9ff00f0d9ff09faebfdbfeadf8e8f9ef9fd +ff0b6a8f89afe77444b8498ff7bfd9ff00f0d9ff09faebfdbfeadf8e8f9ef9fdff0b6a8f89afe774 +44b8498ff7bfd9ff00f0d9ff09fdddfbfb9eff8b9f8fdbfdff0b5c8e68ff95433386447865afd9ff +00f0d9ff09fdddfbfb9eff8b9f8fdbfdff0b5c8e68ff95433386447865afd9ff00f0d9ff09fdddfb +fb9eff8b9f8fdbfdff0b5c8e68ff95433386447865afd9ff00f0d7ff17ce9effff9c8f9fbdfffffe +ff6f7b5eff643343453543688fd9ff00f0d7ff17ce9effff9c8f9fbdfffffeff6f7b5eff64334345 +3543688fd9ff00f0d7ff17ce9effff9c8f9fbdfffffeff6f7b5eff643343453543688fd9ff00f0d7 +ff17e9efffffab6cdb9efffffdff6f8b4fff64434437443345bfd9ff00f0d7ff17e9efffffab6cdb +9efffffdff6f8b4fff64434437443345bfd9ff00f0d7ff17e9efffffab6cdb9efffffdff6f8b4fff +64434437443345bfd9ff00f0d7ff00dbfeff12e89afabdfffffddf8bca7bff83436434433466d8ff +00f0d7ff00dbfeff12e89afabdfffffddf8bca7bff83436434433466d8ff00f0d7ff00dbfeff12e8 +9afabdfffffddf8bca7bff83436434433466d8ff00f0d7ff00befeff12f9b6cbeafeffffafb5fef9 +bfc359d834433598d8ff00f0d7ff00befeff12f9b6cbeafeffffafb5fef9bfc359d834433598d8ff +00f0d7ff00befeff12f9b6cbeafeffffafb5fef9bfc359d834433598d8ff00f0d2ff119c8ffbffef +ff8ee58fff99e548784433455ed8ff00f0d2ff119c8ffbffefff8ee58fff99e548784433455ed8ff +00f0d2ff119c8ffbffefff8ee58fff99e548784433455ed8ff00f0d2ff01fccffdff06b9fa8afffb +7743fe3301548ed8ff00f0d2ff01fccffdff06b9fa8afffb7743fe3301548ed8ff00f0d2ff01fccf +fdff06b9fa8afffb7743fe3301548ed8ff00f0d2ff00fafcff0cfa68858efffc87433333356549d9 +ff00f0d2ff00fafcff0cfa68858efffc87433333356549d9ff00f0d2ff00fafcff0cfa68858efffc +87433333356549d9ff00f0d2ff00ebfbff0cb99a769effffdca7568effe69adaff00f0d2ff00ebfb +ff0cb99a769effffdca7568effe69adaff00f0d2ff00ebfbff0cb99a769effffdca7568effe69ada +ff00f0d2ff00cffaff03feffc7effdff03efffb68adaff00f0d2ff00cffaff03feffc7effdff03ef +ffb68adaff00f0d2ff00cffaff03feffc7effdff03efffb68adaff00f0c8ff01fedffcff02fe645a +daff00f0c8ff01fedffcff02fe645adaff00f0c8ff01fedffcff02fe645adaff00f097ff00f097ff +00f097ff00f097ff00f097ff00f097ff00f097ff00f097ff00f097ff00f0 +currentdict /inputf undef +currentdict /picstr undef +currentdict /rpicstr undef +currentdict /gpicstr undef +currentdict /bpicstr undef +grestore +showpage +%%Trailer diff --git a/doc/gnu.xpm b/doc/gnu.xpm new file mode 100644 index 0000000..bc54934 --- /dev/null +++ b/doc/gnu.xpm @@ -0,0 +1,198 @@ +/* XPM */ +static char *noname[] = { +/* width height ncolors chars_per_pixel */ +"213 177 14 1", +/* colors */ +"` c #FFF", +"a c #DDD", +"b c #BBB", +"c c #999", +"d c #777", +"e c #555", +"f c #333", +"g c #EEE", +"h c #CCC", +"i c #AAA", +"j c #888", +"k c #666", +"l c #444", +"m c #222", +/* pixels */ +"`````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````", +"`````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````", +"``````````````````````````````````````````gaahiibaag`````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````", +"``````````````````````````````````````acjjdddldjjkleeekdjia``````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````", +"```````````````````````````````````abbicli`hbjkdbelldddkdelldh```````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````", +"`````````````````````````````````iibkcjellcaeaklcelfljllkekdeeejba````````````````````````````````````````````````````````````````````````````````````````````gha````````````````````````````````````````````````````", +"```````````````````````````````bcagjcldkleljcdaelillfcdllfedeeelffc`````````````````````````````````````````````````````````````````````````````````````acdjddjccjjjch```````````````````````````````````````````````", +"`````````````````````````````hch```jflleeeelkkcbljdlfliellldeeeeeflkh````````````````````````````````````````````````````````````````````````````````hjkch`ah`ic`gaiicjja````````````````````````````````````````````", +"````````````````````````````cb``aeigjlefleellelhdlblllldllllcllekkeelcg``````````g``````````````````````````````````````````````````````````````gjcddiabjjdldkleklllliggcc```````````````````````````````````````````", +"`````````````````````````ggjag`accdehilefelelllehldjllleellleellekllleejb```````dki```````````````````````````````````````````````````````````gjlljbiiekkelllllllefedcdg`hjb`````````````````````````````````````````", +"````````````````````````gdhg`cdhadkdejilelelelekdelbllelelellkleelkfjeehiiihaaidbai``````````````````````````````````````````abg`````````````addijkdellelllelllllljckllkg``hcg```````````````````````````````````````", +"```````````````````````gjgdejijlcghkeljjllllkdhjklkdcleklklllllleleeededg`hidjb``ig`````````````````````````````````````````akdei````````ggacdkkkkjllllflllflflllleekddjcji``big`````````````````````````````````````", +"``````````````````````hdcjjceeekeei`hklkklledg`adebeclljelleleellelclkdlgg`aagg`ai``````````````````````````````````````````cg`bklkklllllllllkkeejlllfflekflellfleeelfllech```gcg````````````````````````````````````", +"`````````````````````cihdckkjkleelldggiklejca``````aahkkceedkekjekkjllclhghbikkhjg``````````````````````````````````````````ij`g`ghbcjekddbkeeeljlllflfleflklfflekledjccccjg````ia```````````````````````````````````", +"````````````````````hd``g``beedeeelkeb`gddhh```ghhhbbiekjhca`gjig`bgajab`gg``acc`````````````````````````````````````````````edagg`jeelleleeeeekeflfffleflefflelflklllelllledc```ba``````````````````````````````````", +"```````````````````gc``aga``gdllelkecec``bg`gckdibbbhahbcdddjccciiihhgg```gbjca```````````````````````````````````````````````clkdcaccklleleeeekcikekklflefflllflllllllllllllekj``bg`````````````````````````````````", +"```````````````````c``heledb``cllelebadj``gcdig`````````````gaaahhbhhhhhhgag```````````````````````````````````````````````````gcklflkjcaeekkjkjjddejdldkekdelllllfffffllleedjch```ig````````````````````````````````", +"``````````````````caagikelllkcgjekekdg`hgbca```````````````````````````````````````````````````````````````````````````````````````aidelllebag````````hkea`gelllfffffffffffffllkg``gb````````````````````````````````", +"`````````````````jbhdeecbbjefleckdciic`gca`````````````````````````````````````````````````````````````````````````````````````````````````````````````gikjgakffffffffflllekdkelkda`i````````````````````````````````", +"```````````````adllkchbklkbabkflecgg``ajg`````````````````````````````````````````````````````````````````````````````````````````````````````````````````hdhaffffllllejjdelfflleda`hh```````````````````````````````", +"```````````````jckllllejjeledahlfkhg`bjg````````````````````````````````````````````````````````````````````````````````````````````````````````````````````jiblleffffffffflekdkkelagb```````````````````````````````", +"``````````````hj``gbdlllleellljcebg`bc```````````````````````````````````````````````````````````````````````````````````````````````````````````````````````bjhcelffffllllllledddkc`i```````````````````````````````", +"`````````````gdhbbhihabklllleekkk``bc`````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````bj`hlfffffffffllleeekjhi```````````````````````````````", +"````````````gdgeeelllekcidllleeja`aj```````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````id`befffllfffffledibbgbg``````````````````````````````", +"````````````cb`hchgidellekjjeeaijbjg````````````````````````````````````````gabbiiiibhg`````````````````````````````````````````````````````````````````````````cdgkfffffffledjjkeekcah``````````````````````````````", +"```````````gd````gg```aclleddkg``da`````````````````````````````````````gbjkddjcccjddjddjia`````````````````````hbhag````````````````````````````````````````````iieffflfflfflkca`````b``````````````````````````````", +"```````````ca```hbiiibhggbeekh``ib````````````````````````````````````gdkchgabbccjjiicibbijjh````````````````gijccjjjcia``````````````````````````````````````````ddflleeeleellllkdh``i``````````````````````````````", +"``````````gj``clllffllllki`bcg`hj````````````````````````````````````hkcijccibag`gghbijkkjiidjh````````````bcibicjjiba`hba````````````````````````````````````````hjdleeelllffflllej``b``````````````````````````````", +"``````````cahjekdjcicjdella```gd```````````````````````````````````adldia```````````````ghjddkkda```````gcdjjdcbhgabicjighb````````````````````````````````````````daiefffffffflllekg`b``````````````````````````````", +"``````````j`ccjjjddkeekdcddb``ia``````````````````````````````````iejg```````ah`g```hg``````gbjelc````acckjhg``bebgh```hjcg````````````````````````````````````````chjeffffffllffllkdchg`````````````````````````````", +"`````````iiallllllekjiijkedka`c``````````````````````````````````ijg`````g````chjjeagkdh``ghcb`ajljaaibcjg````gdeleld````gjc```````````````````````````````````````ac`kleiiklflkcklleghg`````````````````````````````", +"`````````kkkellekekellejaghcb`c`````````````````````````````````cb```````chjacciicljeckdggkdkkh`chkebgjjbg`ahijallldflcig``ajh``````````````````````````````````````dallffldcjlfljkjlgaa`````````````````````````````", +"````````bjjjiiijjddkeeeelhg``ab```````````````````````````````gjh`````hcbciiibkcbdlbkcejkjkeekebikadjkbdeecheakllcleiflkeaicgijg````````````````````````````````````djkllfflflkjefleb`bh`````````````````````````````", +"````````kg`aabcjkeeellleekc``ig```````````````````````````````jg``````jjdbjijhedhkkjjdldejdeldklkeeijkcgkllekkaeljifclffffffebada```````````````````````````````````cillfffflllldcllb`bi`````````````````````````````", +"```````gd``hellllleeeeekkkka`j```````````````````````````````jh`bgijkgieeakcdgekaedeielklejelkeelfeeiklbilellfcbflhlelfflffffleidb``````````````````````````````````caelleeelffllebkeabi`````````````````````````````", +"```````bigcellllllllllleldgggc``````````````````````````````chaacbhkebaeeakdd`ekgedlhlelleckleellflekjeeaeeekeladfjkleffllefffflbcc`````````````````````````````````ibllllfleelfleljjeic`````````````````````````````", +"```````jacllledjbcbhbidefekgch`````````````````````````````ci``dkj`elcgeeijed`eealkfblllleceldklelleekeeibejljllifdjlklfkfdllfffebbj````````````````````````````````biillflllfleelllljgc`````````````````````````````", +"```````d`becbbijdelllllejag`j`````````````````````````````bhgc`iek`klj`keccek`eealdlclllllikedjlekfleeclebkeclblelkhfelfkfjelfffflcbc```````````````````````````````ibilfffleefffllflkgc`````````````````````````````", +"```````d``bjelflkdjjdjdekchgc````````````````````````````gj``ddkee`kle`dekilkgeeildldllellbekkildeleelillkjlkldcjklilelfefdelflflflcch``````````````````````````````jadklffffekjkflllkai`````````````````````````````", +"```````j``jlejcjdkeeekdkkihac```````````````````````````gdggccbllegdelgclecle`elhejlkelellbeddhlkleleljekklejieaehfjklllkelelflflflljkg`````````````````````````````d`jihdffffflddlllk`ig````````````````````````````", +"```````j`gedkellleekkkekdihgc```````````````````````````jabbkicellajelaileilk`klaejleelkllhedkhljejeelkeedjj`gjbjlldjllelklllleflflllkda```````````````````````````gjgeellfffffleedeelhba````````````````````````````", +"```````i`hedeeekkkkeekellljaj``````````````````````````jh``kljcdfehjelbheehekgelaejlleljllhedjaljeikdeelffildh`cklleblleldfellklllfllleka``````````````````````````iigedfffffffffeejelgba````````````````````````````", +"```````a`cilledjiabcjelleb``j`````````````````````````ci```kljjiflhceliaelakkgllalcllllkeebkdcalieheckkkhchlleb`bflfbeleeefkllkellfllllekg`````````````````````````jg`aelfffffffffeeilhbg````````````````````````````", +"`````````kdba`gikelkcjjkeeh`j````````````````````````iia``eeljdhflhcelcallhdkhllblielleelkcdebhliealieea`ahffflelflfddfeeeflllekllflllfllk`````````````````````````d``ilfleffffffffldhgbg````````````````````````````", +"```````h`c`bjelekjdeelffleh`j```````````````````````ij`bcallljkgflidelchleakkileclillllllkkjehildkcljlligegeflkeeelfkjflelfllleelelellffllkg```````````````````````d`aeffflkfflfffflea`bg````````````````````````````", +"```````b`gieejdellllkcdked``j``````````````````````ic``geglllkk`leideejblegedkfkclbllelledlakhcedkeekfldglabdldhiellkjflllflleellellelfefllkg`````````````````````akelflffflklfllffljc`b`````````````````````````````", +"```````iggjjdelllecbjelljh`ach````````````````````ci````ebelekegeljkeldjldalklljkkjllefeledilcec`gcikellaei``blljkjkkjflllflllkllellklfdlllkjg````````````````````cejblffffffklfflfld``i`````````````````````````````", +"```````iahcjelecaiefldjledjiaj```````````````````jb``bb`djllekk`eljeeleeljjllllkljefelfklkkck`gahahjlilkeeeg``ielfeleblllllflldllklleeldkleiadih``````````````````dlaelfffffffelfflfi``b`````````````````````````````", +"```````bcbiekhgceflddelllecj`d`````````````````gdh```he`ckeleek`keeleellejlkideddieekeddb`dddjeeeldidbkjfjfkihggkfleehellellllkledlfkelljledgaci`````````````````bjkkfffffffffflfflfk``i`````````````````````````````", +"```````gjgaigcllllellkellebagib```````````````gda``ghgegbeeelkk`eeeldli`accajliiiceledjjjdlleigahlb`jididkkffleeffebdbjljdllklldicllklllelllj``cc```````````````gdgjflfflfflfffflfflfi`b`````````````````````````````", +"````````dgghekbklflkellleekkhgc``````````````gda````dhdbieekeekkljdjjlckflkkeekddjjjdkkkdjcbg````keacfejhejeleeceliajhdflleefleekklllllfflellh`gkc``````````````dballfflfffflffffffla`bg`````````````````````````````", +"````````dhclddllleelllelllebg`jh````````````gja`````ijjdblkklljjkghdlejig```````````````gg```````gljghefecljlfdcej`cekkibjdabg`ghiickdkdeedledjagkc````````````jdbkfffffffffffffffflg`c``````````````````````````````", +"````````icdbbkllllllejellkllc``jb``````````gdg````ighdbkhlkelebadedch`````````````````````````````hedahkffefklelfiejg`````bdc````````ahbjkeedleeh`cdh``aag``gieeklclffflffffffflffli`ai``````````````````````````````", +"````````hcghklllllljdelldefle```jc````````hjg```gikbhkbljlcecjkkig`````````````````````````````````gdlejjellffflelc`````````bkg``````````abkjeeelb`hkellekbjldgdgkfflffflffffffflfk``cg``````````````````````````````", +"````````gdikllkeleceklljeflklh```jja````acc`````hckcgececedlkig```````````````````g`````````````````gilelejcfffkjla````ag````hk`````````````ieeekfeh`ghjkkjig``dklelmfffflfffffffflb`c```````````````````````````````", +"`````````dakejelkjedlldklldlleg```bcjjjjca``````jcedgekllecg`````````````````gicekj``````````````````ggabjleffcadeb```hed`````bd`````````````ggkllffjgba`bccgihefffeefffffffffffflkdhh```````````````````````````````", +"`````````ibdielkdlkeedkllddellbch``````````aghaieaekglfda````````````````ghiiiaifeg`````````````ggg```ggagblfkgdljd``cijdg`````ci`````````````haeelffllljelfllfffffflffflffffffllldic````````````````````````````````", +"`````````hcgclkklkeedkllejldfleehg`````````ccbjdeadejfj`````````````````hllkkeeffc`````````````gdlleg````g`ceebfflkghjklkg````g`ka````````````abcllfffffffffflfffffffffffffffffflj`gc````````````````````````````````", +"``````````d`cdkleekkklledlklfleedd`aa`````gilildeajlfl`````````````````illlflfffk```````````````ajllig``g```aeefffj`clffi`````h`bd`````````````baelfflfffffffflffllfffffflffffllfa`ia````````````````````````````````", +"``````````jagbledjkklfdkeedffelflecbkd````icldejlbjfed````````````````glfffllffkg````````````````gilkh``g``hkllfejagklfla````gb``k`````````````gccllfffffffffffffffffffffflmffflfhgi`````````````````````````````````", +"``````````bb`bkkckclleeeljlflkfleeljke`igabkleeclikfcg````````````````cflfflffj```````````adeeja```iiih````blfkjia`gkffja`````h``dg`````````````hjllffffffffflflfffffffflfffffffegcg`````````````````````````````````", +"``````````gc`beakbellkeleellleflellkje`ddgdklekdlele`````````````````alffeffdh``````````beffeklk`````hjbb``gijig``gadffiibiiaga``jg``````````````jelfffffffffffflffffffffffffllldbb``````````````````````````````````", +"```````````jheajckeldellklllllflleeeie`dehkkelkklljc`````````````````kffelfjb``````````clkig``dlg`````aej````g`````iclfkja`hjhh``d```````````````bllfffffffffffffffffffffffflldeic```````````````````````````````````", +"```````````ikagjdekedlekllelelllfkelbk`ekikdelelfba`````````````````blfkdlkcb````````hkeh`````jlc`````bkc``````````jjffedh`ggb``gk```````````````akelfffffffflllffflffffffffefiahh```````````````````````````````````", +"```````````gj``idekjekeellklkfllleeeiegekidjleefe``````````````````hefd`ai`e````````ifj```````allg`````iig`````````cjfflb```````bd```````````````bklfflfffffffllffflfffffflfekkgc````````````````````````````````````", +"````````````cg`deckjeledleellfelleeedebleidkellfb`````````````````hedi````hk````````ed`````````cfa`````hejg````````iefffcg`g````jb````````````````jlfflfffffffllffffflffflffb`djh````````````````````````````````````", +"````````````hb`bedcelekjljllllllleeeeljeeckdelfl`````````````````acbi`````ki```````hea```hbcjdkkfc`````gelb````````hefffekddcb``ja`````````````````hllfeffffffllllffffllfklk`gji`````````````````````````````````````", +"`````````````j`gicclejceejlefllllcekledleckkllfd``````````````````gjg````gla```````ifj`beffflffffeh`````hlb````````gcfffffffffecdb``````````````````dlfeflffffflllfflfefeeec`gj``````````````````````````````````````", +"`````````````bi```jkdjhlklllflllehekleellbkkkllb``````````````````gg`````ik````````aflefffflfffjclb``````kb`````````alfellekjdellc``````````````````hlflfffffffllllelfefdhb`ajg``````````````````````````````````````", +"``````````````jg```khjcldlllllllkbekleeeebkdellg`````````````````````````di````````gefffflfffffjbcd``````gia`````````klkleleeeddllg``````````````````effflfffflfffleffek```bkg```````````````````````````````````````", +"``````````````gjg``jgidelldflleljjkelleeebekklj``````````````````````````lg`````````effejlffleffjida``````dc`````````glkcffflfedddh``````````````````kllleffffffllkkkecg`idda````````````````````````````````````````", +"```````````````aca`hgbkeeceffjllieceelekeieeelg`````````````````````````gk`````````glebahlfflllfkgag``````kd`````````gdldfflffldjcg``````````````````blllkfffflllejgkkbdejg``````````````````````````````````````````", +"`````````````````jg`ggkkcilfljlejeblkedklclefh``````````````````````````ci``````````lh``affffflfeaig`````gea````````gghefffffffkb````````````````````akcbklfflejdlbakfkb`````````````````````````````````````````````", +"`````````````````gc```icbkflieldkjiebeeeecelc```````````````````````````dg``````````jj`g`efffffldde``````ji``````````ggblfffffekdkj```````````````````hc`bjdah`gajdkia```````````````````````````````````````````````", +"``````````````````hb``bigjkeclddeakkjleldkee````````````````````````````k```````````gddhahlffflkiek`````````````````````jfffffddjle````````````````````ekkjjddddjba````````````g``a`a````````g```````````````````````", +"```````````````````aigg```aieeblibejkeelcelb```````````````````````````hlg`````````ggailc`ajjcjcbec`````````````````````alleekchclh````````````````````bagagg```````````ag``gejb``kgk````gbagecdbabg`````````````````", +"`````````````````````iba```hbblcgkb`dkeljel````````````````````````````ceg`````````````akdiibdeeej```````````````````````clekkcjeca`````````````````````j```````````````ilh``dfj`gedc`hb`gdkabelcbkeddi``````````````", +"```````````````````````hih`hcliidc`akjeeedj````````````````````````````ecg````````````gg`acjcibag`````````````````````````clddedai``````````````````````ca```````````````bea``ek`alegblja`ieeajlcblkbkg``````````````", +"`````````````````````````gbibg`gh``hagjhaea```````````````````````````gkig```````````````gg```gg```````````````````````````kla```h``````````````````````gj````````````````akg`ajggeaalfkb``jlkaljhlhkg```````````````", +"````````````````````````````bbbbhg``````ge````````````````````````````cjhh``````````````````g`a````````````````````````````aej```cd``````````````````````j`````````````````ik`````ghecfejjdkllklkdeejig``````````````", +"````````````````````````````````ghbhhg``kc````````````````````````````eh`ihg````````````````````````````````````````````````ilh``bej`````````````````````bh`````````````hiiceddkkkklkdjjjcbag``c`````gb``````````````", +"`````````````````````````````````````ahclg```````````````````````````afg`bha`````````````````````````````````````````````````dd``glka`````````````````````c`````````````dbhhjcbhg``````````````i``````b``````````````", +"```````````````````````````````````````ck````````````````````````````dfh`gaa`````````````````````````````````````````````````bla``idjg````````````````````ai````````````j```h``````````````````i`````gb``````````````", +"```````````````````````````````````````lh```````````````````````````aelg```g``````````````````````````````````````````````````cj```eadgg```````````````````cg```````````c``gi`````````gaabbicccdibdciab``````````````", +"``````````````````````````````````````hk````````````````````````````dceka`````````````````````````````````````````````````````geg``djgda```````````````````gc``````````adjdkejicjddkelledjedckijaaeeich``````````````", +"``````````````````````````````````````di```````````````````````````he`bd```````````````````````````````````````````````````````ek``ce`gch```````````````````ab`````````gcidkjlbbbckjadlb``dj`c`ga`cda````````````````", +"`````````````````````````````````````glg```````````````````````````dj`ce````````````````````````````````ga`````````````````````aea`ilg``iig``````````````````ba```````````cbae```gki`cli``dd`c``g`gda````````````````", +"`````````````````````````````````````bk```````````````````````````hlg`bkjg```````````````````````````gggblig``gh````````````````jj`hli```gjcg`````````````````ig``````````jbbe````ki`ilc``dd`c`````da````````````````", +"`````````````````````````````````````di``````````````````````````gec``ajegg`````````````````````````ckkdjcecaaaa````````````````gkbaec`````accig```````````````cjg````````kbhe````ei`ilj``jk`j``g``da````````````````", +"`````````````````````````````````````lg``````````````````````````dd````hkkj```````````````````````````````hjkkdjdjjjjb```````````bkhec````````acjbg`````````````gjg```````diak```gei`blc``de`j`````da````````````````", +"````````````````````````````````````he``````````````````````````ikg`````dela````````````````````````````ghbhhhaaggg```````````````kjei```````````bdjiag```````gbiig```````dbak````lb`bli``de`j`````da````````````````", +"````````````````````````````````````jc````````````````````````gdk````````bkb`````````````````````````akkdjddkeleja````````````````ilkh``````````````hcjjccccjcbg``````````dbhd````ei`hec``dk`j`````ka````````````````", +"````````````````````````````````````eg```````````````````````geea`````````ib`````````````````````````ei````````gbjejg`````````````aelg````````````````````````````````````jbhd```gli`hei``dd`j`````kg````````````````", +"```````````````````````````````````be```````````````````````hlla``````````g`````````````````````````cj````````````adlb`````````````hlbg```````````````````````````````````dbbd```gli`ali``jd`j`````kg````````````````", +"```````````````````````````````````kb``````````````````````allh````````````````````````````````````hla``````````````bejg````````````dla`gahjji````````````````````````````dbbd```glc`glb``dj`d`````kg````````````````", +"``````````````````````````````````be``````````````````````beeh`````````````````````````````````````kh`bklljg``````````iei```````````ckelleedddka``````````````````````````dbbd```glc`glh``dj`j`````kg````````````````", +"`````````````````````````````````geh```````````````````gikejg`````````````````````````````````````gk`jfeddeea``````````akkb````````````g``````aeg`````````````````````````dbij```glc`glh``jj`d`````kg````````````````", +"`````````````````````````````````ec`````````````````gbdledi```````````````````````````````````````ijifd````hg````````````ieda``````````````````ij`````````````````````````dbbj```ali`gla``jc`d`````kg````````````````", +"````````````````````````````````jk````````````ghijdkkdjhha````````````````````````````````````````daefb```````````````````gdeb``````````````````e`````````````````````````dhbj```ali`glh``ih`j`````k`````````````````", +"```````````````````````````````ilg`````````bdelkjbg``gcabcg```````````````````````````````````````kajlg`````````````````````jei`````````````````ka````````````````````````khbj```hlb`bla``jh`d`````e`````````````````", +"``````````````````````````````ila````````cedccb````````ijib```````````````````````````````````````kahe````hdledcg````````````i``````````````````jb````````````````````````khic```hlb`blh``jh`d`````e`````````````````", +"`````````````````````````````ilh````````jlg`gc`````````gjdb```````````````````````````````````````bg`a````deahikeg``````````````````````````````ic````````````````````````kaic```hlb`blh``jb`d`````e`````````````````", +"````````````````````````````dfb````````alb``ca``````````hlg```````````````````````````````````````ah`````glfklfekd``````````````````````````````ic````````````````````````khcc```blb`blh``jh`d`````e`````````````````", +"```````````````````````````cfc`````````kk```d````````````k``````````````````````````````hg```````````````glfffffekcia`````````````````````````abdh````````````````````````eacc```bliiefc``dh`d`````e`````````````````", +"```````````````````````````ed`````````blb```d````````````db```````````````````````````gag````````````````gkffffffbelkg```````````````````````gjde`````````````````````````kaic```bldcahkb`kh`d`````e`````````````````", +"```````````````````````````lg``gikcghjlc```gj````````````je````````````````````````gjkka``````````````````gkfffflaeefi```````````````````````dedd`````````````````````````eabj```blk``ghegkh`d`````e`````````````````", +"```````````````````````````ddjkfeddflda````bc````````````ceb``````````````````````akig``````````````````````bjig``eblk``````````````````````jflld`````````````````````````kghj```bli```cflllcd````ge`````````````````", +"```````````````````````````gccib```ga``````ib````````````jhc``````````````````````ea``````````````````````````````khbfg````````````````````jlfflh`````````````````````````egbc```bfj``glkdleid```gbk`````````````````", +"```````````````````````````````````````````ca````````````j`j``````````````````````````````big`````````````````````ehgli``````````````````gdlfffd``````````````````````````egbj```ile``ge``kh`dgiaaik`````````````````", +"```````````````````````````````````````````ja````````````j`j````````````````````````````helkli`````g`````````````gk``ed````````````````gbklffleg``````````````````````````lgbj```cllh`jj``eb`difdbik`````````````````", +"```````````````````````````````````````````ch````````````cgd````````````````````````````iga`geb``ag``````````````````cc`````````````ggadlffflkb```````````````````````````labc```jlka`ec``kb`difehid`````````````````", +"```````````````````````````````````````````ch````````````ihja````````````````````````````````hla`j```````````````````````````````````hklffffdj````````````````````````````lhic```kfcggjli`eb`djflbcd`````````````````", +"```````````````````````````````````````````ib`````````````ijeg````````````````````````````````dcgj`````````````````````````````````gjefffffekg````````````````````````````laieejelledecieieb`dhkcbcd`````````````````", +"```````````````````````````````````````````bc```````````````cd````````````````````````````````akii````````````````````````````````gdlflffflka`````````````````````````````laijeggabijkellllb`dga`bcd`````````````````", +"```````````````````````````````````````````aj```````````````gkh````````````````````````````````cki```````````````````````````````gdlflffflkg``````````````````````````````eajkkjihg``````geb`dg``hcd`````````````````", +"```````````````````````````````````````````gd````````````````jc````````````````````````````````gej```````````````````````````ggagdllllfflka```````````````````````````````dadlklekeeekkkkjeb`d```acj`````````````````", +"````````````````````````````````````````````d```````````````gbj`````````````````````````````````be``````````````````````````````hjjcdeelecg```````````````````````````````khjeeeb`````ghejeb`d```aij`````````````````", +"````````````````````````````````````````````d```````````````baj``````````````````````````````````kh`````````````````````````````gg``gabi`ajg```ggga``````````````````````gkckecd`g``````aeeb`k```gic`````````````````", +"````````````````````````````````````````````dg``````````````abch`````````````````````````````````bj````````````````````````````````````````bkdkekdklkkka```````````````ajllflkejibhgggghbkli`k```gij`````````````````", +"````````````````````````````````````````````cb```````````````chj``````````````````````````````````dg````````````````````````````````````````hh```gbg`gdi```````````````jkiicjcccijdkllllfkli`k```gic`````````````````", +"````````````````````````````````````````````bi```````````````gceih````````````````````````````````aj`````````````````````````````````````````ba`cdhhgggkg`````````````bjkellkkeekdeclkkkllligk```aci`````````````````", +"````````````````````````````````````````````aj`````````````````bhbjjg``````````````````````````````aj````````````````````````````````````````gcgblfjkg`hd``````````````gbdklcedihbedekellklcae```aji`````````````````", +"`````````````````````````````````````````````d`````````````````hb``ajjg`````````````````````````````hc```````````````````````````````````````adgaelfcg``ji````````````````ge`dig`gkghabaahejak```hji`````````````````", +"`````````````````````````````````````````````d``````````````````biih`adh`````````````````````````````hc```````````````````````````````g``gbiikfjgjeld```aea```````````````ge`kiaghejaggbbiedgk```bji`````````````````", +"`````````````````````````````````````````````ih```````````````````gbch`da`````````````````````````````jkh`````````````````````hckkeeeekdcjkdlielbieeeh```hka`````````````gbebdkeellleekcidfj`k```ijjhhhha````````````", +"`````````````````````````````````````````````ac``````````````````````ibjki````````````````````````````gdlcg``ghbhgg```ggacckelfflllllffffflbagbfkilelddcbghkjg``````````bkllllllllllelllekligk```ajeeeelleka`````````", +"``````````````````````````````````````````````k``````````````````````gccgd``````````````````````````````ileeefflkchahabklfffffffffffffffflc````dflfelkcdkkddlkjjjcjjccccklllleeeeeleeeeeleli`k````jklellllljci```````", +"``````````````````````````````````````````````ja`````````````````````cgj`j```````````````````````````````hllebahabcdelffffffffffflllffllfj`````aleejllkdjba`aihgbiibibibijcccccccccccccjddeh`eg```djbbhbiiiibdd``````", +"``````````````````````````````````````````````aj`````````````````````jacih````````````````````````````````gefllllflfffffffffllfflekkeelfd``````glkkjedghifdbgjdjjdkdjjjjjjddjdccccjiiibbbiebheg```djccjkkkejjkc``````", +"```````````````````````````````````````````````d`````````````````````cjgjg`````````````````````````````````hdlffffflkjjjjdibhbiig`g`agaci```````ljjkkk`gafldhlcaahbbiibbbideilkchjehhhahhbdabeh``gdh```jbak``ch``````", +"```````````````````````````````````````````````d`````````````````````dj`j`````````````````````````````````````gahaaag``````````````````aj```````edbejea`glldhlb```````````jkglcg`id```````jggeh``ada```jhgk``ca``````", +"```````````````````````````````````````````````ja````````````````````djhi``````````````````````````````````````````h```````````````````gd``````gejhkclc`geecbla```````````id`lj`gcc```````j``ea``gka```chgk``ca``````", +"```````````````````````````````````````````````bi````````````````````ckhi``````````````````````````````````````````````````````````````bj``````gejajcee``kehbk````````````ckgej``jj``````adggea```ka```jhad``cg``````", +"````````````````````````````````````````````````d`````````````````````dcj``````````````````````````````````````````````````````````````ka``````aejgddkeg`kkgcd````````````ck`ed``cj``````ad``eg```ka```jaaj``jg``````", +"````````````````````````````````````````````````bi`````````````````````kkh````````````````````````````````````````````````````````````hk```````akcgkkjebgkk`jj````````````ck`ec``cc``````gj`gk````eg```jghc``d```````", +"`````````````````````````````````````````````````d`````````````````````gjd```a```````````````````````````````````````````````````````gda```````hei`kdcfjakd`ki````````````ieaec``jc```````c`gd````eg```j`bi``d```````", +"`````````````````````````````````````````````````ch``````````````````````bb``d`````````````````````````````````````````````````````ajjg````````behgkdcfeadjgeg````````````cehlc``jc```````c`gd````eg```j`ib``k```````", +"`````````````````````````````````````````````````aj```````````````````````iggj```````````````````````````````````````````````g`gbjjig``````````blghjicllbdiae`````````````ckhlc``di```````c`gd````e````j`ca``d```````", +"``````````````````````````````````````````````````dg```````````````````````ihc``a`````````````````````````````````abckdkkeeeedjjh``````````````blgbjakdejdhcd`````````````jkalc`gdi```````c`gd````k````j`jg`gk```````", +"``````````````````````````````````````````````````bj```````````````````````ihc``a```````````````````````````````bklffffflffflg`````````````````ce`iigkiekkadc`````````````jkalc`gki``````gj`gj````k````j`j``ae```````", +"```````````````````````````````````````````````````cb`````````````````````hbbc`gj````````````````````````````gclffffffffffffd``````````````````jk`ji`dakeeaea`````````````jkali``ei``````gd`gj````d````d`d``be```````", +"````````````````````````````````````````````````````dg````````````````````iahc`ia```````````````````````````bellffffflffflfla``````````````````dk`db`cdkekge``````````````ckgfb``lh```````c`gj````d```gj`d``hj```````", +"````````````````````````````````````````````````````ac````````````````````higd`j`g``````````````````````````jffffffffffflffc```````````````````kj`ka`hecldhe``````````````iegfh``liiicdjccj`aj```hlc``gj`d``hb```````", +"`````````````````````````````````````````````````````ih````````````````````dgjhd````````````````````````````chkkekeelkcagkfi```````````````````ec`k``glbljhlkkkdddkkdjddkkekalh``lcbbbiccdj`hd```gelkabj`d``hi```````", +"``````````````````````````````````````````````````````jg```````````````````gjcdd```h``````````````````````````hejgdiach`gjklh`````````````````gec`k``gddkchkggggaaagaagg``heglh`ala``````bc`ad````ihkldjgj``hi```````", +"``````````````````````````````````````````````````````gdg````````````````````ilea``h```abg`a```ig``````````````dhak``hb``b`jk`````````````````bkcgk```alkbalcg````````````hk`fh`glg``````hh`gc```gc``hkdac``bb```````", +"```````````````````````````````````````````````````````gdh```````````````````gdli``h`h`gjhg```bk```````````````icijg`gc````ala````````````````bkhad````eeaijdda```````````bkala`alg``````aa``c```gc```ichi``ia```````", +"`````````````````````````````````````````````````````````cb``````````````````gclk``b`b`bhgb```eh```````````````gjgji`gc`ha``dk````````````````jegcc````jegeiahkcg`````````aklfeeel```````gb``j```gj```jiibg`i````````", +"``````````````````````````````````````````````````````````ic```````````````````cla`b`hgja`c``bii````````````````a`jicbb`aj``bd````````````````aekeh````jkakejggdlc``````````ghbihg```````gj`ge```gc```kkekjckh```````", +"```````````````````````````````````````````````````````````hda`````````````````alkgb`aachbjg`jhh`````````````````ga`cd```d``cj```````````````````ig```gjcgkgjec`adeb``````````````````````ekij```gb```ha`gaaklja`````", +"````````````````````````````````````````````````````````````gjh`````````````````cdhj`gbhkchi`j`b````````````````````ik``gd``kh````````````````````````heigd``helb`gdkddddkkeeeeekdcjjjcciijkleeeediiiiibibbbbckc`````", +"``````````````````````````````````````````````````````````````jg`````````````````cccigigekgj`j`b```````````````````ajcb`bi`bj`````````````````````````ieihc```aefkhglhgagggghbcciichaahhbbbbiiccicjiiiiiiiicjcjc`````", +"``````````````````````````````````````````````````````````````ga``````````````````ckgii`jecbid`ha`````````````````gb`hb`dg`kg`````````````````````````cldji````gcefllg````````````````````````````````````````aj`````", +"```````````````````````````````````````````````````````````````````````````````````abbc`ajeaikb`i```````````````````gcghj`dh```````````````````````````hdeb```````aefjccibhhhhhhbbibbibiiibhaggahbcjjjjccciccjdi`````", +"````````````````````````````````````````````````````````````````````````````````````iiac``ckgjkgah``````````````````caadgjh``````````````````````````````g`````````gadjdkkkeekkdddjjjjjccccjdkkddjcbhhhhhhhagg```````", +"```````````````````````````````````````````````````````````````````````````````````aab`acjgkdgdd`i`````````````````chadgba```````````````````````````````````````````````````````````````````````````````````````````", +"```````````````````````````````````````````````````````````````````````````````````bi````ghajbiciab``````````````gcbhdgbb````````````````````````````````````````````````````````````````````````````````````````````", +"``````````````````````````````````````````````````````````````````````````````````bha`````g`bdgjj`bg``````````gahbggdgih`````````````````````````````````````````````````````````````````````````````````````````````", +"`````````````````````````````````````````````````````````````````````````````````gbc`````gghadgcj``i`````````jeda`gdgcg```ghiccg`````````````````````````````````````````````````````````````````````````````````````", +"`````````````````````````````````````````````````````````````````````````````````i`j``````hcgjgjcg`gc```````gdkh``jajh`acjia`bbjhg```````````````````````````````````````````````````````````````````````````````````", +"`````````````````````````````````````````````````````````````````````````````````c`j````abgdhichig``j```````jik``chjhgjdeg``gg``jba``````````````````````````````````````````````````````````````````````````````````", +"`````````````````````````````````````````````````````````````````````````````````c`c``gih`cgcgdgia`bb```````kid`hcch`dhdlkhildb`gjb``````````````````````````````````````````````````````````````````````````````````", +"`````````````````````````````````````````````````````````````````````````````````igb`ab`gia`jgj`cg`c````````kij`jci`gddlllbjlcj``db``````````````````````````````````````````````````````````````````````````````````", +"`````````````````````````````````````````````````````````````````````````````````aaa`b`bcg``jbc`j`ab````````ehjgkj``celfffjklldjkei``````````````````````````````````````````````````````````````````````````````````", +"````````````````````````````````````````````````````````````````````````````````````hgcg````chj`c`ba`````g``k`dbeg``klfflflefelfkjj``````````````````````````````````````````````````````````````````````````````````", +"````````````````````````````````````````````````````````````````````````````````````gcg`````ibkhabcg`````a``k`jbl```kllfllfdllffleb``````````````````````````````````````````````````````````````````````````````````", +"````````````````````````````````````````````````````````````````````````````````````ab``````gjci`iba`````aa`jbhidb``jflfklfllfflkk```````````````````````````````````````````````````````````````````````````````````", +"````````````````````````````````````````````````````````````````````````````````````bg```````cbkhbgi`g````i`be`g`cb`hfecajfllffecj```````````````````````````````````````````````````````````````````````````````````", +"``````````````````````````````````````````````````````````````````````````````````````````````chj``b``g```jggej```ccgeljdjllffleeg```````````````````````````````````````````````````````````````````````````````````", +"```````````````````````````````````````````````````````````````````````````````````````````````hh`````````bc`iji```bddlfffffffeljg```````````````````````````````````````````````````````````````````````````````````", +"```````````````````````````````````````````````````````````````````````````````````````````````i```````````ikjjejg```hjdlffffffekelc`````````````````````````````````````````````````````````````````````````````````", +"``````````````````````````````````````````````````````````````````````````````````````````````gb````````````bccidkcg````ahidekjg``gkci```````````````````````````````````````````````````````````````````````````````", +"``````````````````````````````````````````````````````````````````````````````````````````````h````````````````g``hdg`````````g```bkji```````````````````````````````````````````````````````````````````````````````", +"```````````````````````````````````````````````````````````````````````````````````````````````````````````````````ga````````````gklei```````````````````````````````````````````````````````````````````````````````", +"`````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````", +"`````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````", +"`````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````" +}; diff --git a/doc/grnexmpl.g b/doc/grnexmpl.g new file mode 100644 index 0000000..ba1a1b8 --- /dev/null +++ b/doc/grnexmpl.g @@ -0,0 +1,3250 @@ +sungremlinfile +0 320.00 240.00 +ARC +320.00 240.00 +320.00 416.00 +320.00 416.00 +320.00 64.00 +496.00 240.00 +144.00 240.00 +* +4 0 +0 +CURVE BSPLINE +764.00 288.00 +776.00 304.00 +764.00 320.00 +* +3 0 +0 +CURVE BSPLINE +768.00 288.00 +780.00 304.00 +768.00 320.00 +* +3 0 +0 +CURVE BSPLINE +768.00 320.00 +788.00 320.00 +800.00 304.00 +* +3 0 +0 +CURVE BSPLINE +768.00 288.00 +788.00 288.00 +800.00 304.00 +* +3 0 +0 +ARC +192.00 268.00 +192.00 267.00 +192.00 269.00 +192.00 267.00 +193.00 268.00 +191.00 268.00 +* +3 0 +0 +ARC +192.00 212.00 +192.00 211.00 +192.00 213.00 +192.00 211.00 +193.00 212.00 +191.00 212.00 +* +3 0 +0 +CENTRIGHT +476.00 32.00 +430.00 28.00 +453.00 28.00 +476.00 28.00 +* +1 1 +10 $DP sub 2$ +CENTRIGHT +476.00 224.00 +430.00 220.00 +453.00 220.00 +476.00 220.00 +* +1 1 +10 $DP sub 2$ +CENTRIGHT +476.00 256.00 +430.00 252.00 +453.00 252.00 +476.00 252.00 +* +1 1 +10 $DP sub 2$ +CENTRIGHT +476.00 448.00 +430.00 444.00 +453.00 444.00 +476.00 444.00 +* +1 1 +10 $DP sub 2$ +VECTOR +604.00 344.00 +612.00 344.00 +612.00 364.00 +620.00 364.00 +* +6 0 +0 +ARC +416.00 320.00 +416.00 319.00 +416.00 321.00 +416.00 319.00 +417.00 320.00 +415.00 320.00 +* +3 0 +0 +CENTLEFT +596.00 336.00 +596.00 332.00 +604.00 332.00 +613.00 332.00 +* +1 1 +3 $-$ +CENTLEFT +596.00 368.00 +596.00 364.00 +604.00 364.00 +612.00 364.00 +* +1 1 +3 $+$ +POLYGON +592.00 320.00 +592.00 384.00 +656.00 352.00 +592.00 320.00 +* +3 1 +0 +ARC +392.00 390.00 +392.00 392.00 +392.00 392.00 +392.00 388.00 +390.00 390.00 +394.00 390.00 +* +3 0 +0 +VECTOR +396.00 388.00 +384.00 384.00 +* +3 0 +0 +ARC +392.00 378.00 +392.00 380.00 +392.00 380.00 +392.00 376.00 +390.00 378.00 +394.00 378.00 +* +3 0 +0 +ARC +312.00 326.00 +312.00 328.00 +312.00 328.00 +312.00 324.00 +314.00 326.00 +310.00 326.00 +* +3 0 +0 +CENTRIGHT +276.00 352.00 +243.00 348.00 +259.00 348.00 +276.00 348.00 +* +1 1 +7 $vv B2$ +POLYGON +280.00 356.00 +280.00 348.00 +284.00 348.00 +288.00 352.00 +284.00 356.00 +* +3 21 +0 +VECTOR +308.00 324.00 +320.00 320.00 +* +3 0 +0 +ARC +312.00 314.00 +312.00 316.00 +312.00 316.00 +312.00 312.00 +314.00 314.00 +310.00 314.00 +* +3 0 +0 +CENTLEFT +292.00 212.00 +292.00 208.00 +300.00 208.00 +308.00 208.00 +* +1 1 +3 $+$ +CENTLEFT +292.00 268.00 +292.00 264.00 +300.00 264.00 +309.00 264.00 +* +1 1 +3 $-$ +POLYGON +288.00 192.00 +288.00 288.00 +384.00 240.00 +288.00 192.00 +* +3 1 +0 +ARC +256.00 268.00 +256.00 267.00 +256.00 269.00 +256.00 267.00 +257.00 268.00 +255.00 268.00 +* +3 0 +0 +VECTOR +328.00 268.00 +416.00 268.00 +416.00 320.00 +356.00 320.00 +* +6 0 +0 +VECTOR +356.00 328.00 +356.00 312.00 +* +3 0 +0 +VECTOR +352.00 328.00 +352.00 312.00 +* +6 0 +0 +VECTOR +320.00 320.00 +352.00 320.00 +* +6 0 +0 +VECTOR +312.00 312.00 +256.00 312.00 +256.00 268.00 +288.00 268.00 +* +6 0 +0 +VECTOR +224.00 276.00 +224.00 260.00 +* +3 0 +0 +VECTOR +228.00 276.00 +228.00 260.00 +* +6 0 +0 +VECTOR +228.00 268.00 +256.00 268.00 +* +6 0 +0 +VECTOR +224.00 268.00 +192.00 268.00 +192.00 384.00 +316.00 384.00 +* +6 0 +0 +VECTOR +320.00 392.00 +320.00 376.00 +* +3 0 +0 +VECTOR +316.00 392.00 +316.00 376.00 +* +6 0 +0 +VECTOR +312.00 328.00 +312.00 352.00 +288.00 352.00 +* +6 0 +0 +VECTOR +392.00 392.00 +416.00 392.00 +416.00 320.00 +* +6 0 +0 +VECTOR +320.00 384.00 +384.00 384.00 +* +6 0 +0 +VECTOR +192.00 256.00 +192.00 268.00 +160.00 268.00 +* +6 0 +0 +ARC +160.00 266.00 +160.00 268.00 +160.00 268.00 +160.00 264.00 +158.00 266.00 +162.00 266.00 +* +3 0 +0 +VECTOR +164.00 256.00 +152.00 260.00 +* +3 0 +0 +ARC +160.00 254.00 +160.00 256.00 +160.00 256.00 +160.00 252.00 +158.00 254.00 +162.00 254.00 +* +3 0 +0 +ARC +194.00 256.00 +196.00 256.00 +196.00 256.00 +192.00 256.00 +194.00 254.00 +194.00 258.00 +* +3 0 +0 +VECTOR +204.00 260.00 +200.00 248.00 +* +3 0 +0 +VECTOR +200.00 248.00 +200.00 232.00 +* +6 0 +0 +VECTOR +152.00 260.00 +128.00 260.00 +* +6 0 +0 +ARC +96.00 266.00 +96.00 268.00 +96.00 268.00 +96.00 264.00 +98.00 266.00 +94.00 266.00 +* +3 0 +0 +VECTOR +92.00 256.00 +104.00 260.00 +* +3 0 +0 +ARC +96.00 254.00 +96.00 256.00 +96.00 256.00 +96.00 252.00 +98.00 254.00 +94.00 254.00 +* +3 0 +0 +VECTOR +124.00 268.00 +124.00 252.00 +* +3 0 +0 +VECTOR +128.00 268.00 +128.00 252.00 +* +6 0 +0 +VECTOR +104.00 260.00 +124.00 260.00 +* +6 0 +0 +VECTOR +96.00 268.00 +96.00 320.00 +40.00 320.00 +* +6 0 +0 +ARC +28.00 338.00 +28.00 340.00 +28.00 340.00 +28.00 336.00 +30.00 338.00 +26.00 338.00 +* +3 0 +0 +VECTOR +24.00 336.00 +40.00 320.00 +* +3 0 +0 +ARC +28.00 302.00 +28.00 304.00 +28.00 304.00 +28.00 300.00 +30.00 302.00 +26.00 302.00 +* +3 0 +0 +ARC +14.00 320.00 +12.00 320.00 +12.00 320.00 +16.00 320.00 +14.00 322.00 +14.00 318.00 +* +3 0 +0 +VECTOR +96.00 252.00 +76.00 252.00 +* +6 0 +0 +ARC +68.00 258.00 +68.00 260.00 +68.00 260.00 +68.00 256.00 +70.00 258.00 +66.00 258.00 +* +3 0 +0 +VECTOR +64.00 248.00 +76.00 252.00 +* +3 0 +0 +ARC +68.00 246.00 +68.00 248.00 +68.00 248.00 +68.00 244.00 +70.00 246.00 +66.00 246.00 +* +3 0 +0 +VECTOR +352.00 384.00 +352.00 416.00 +512.00 416.00 +* +6 0 +0 +VECTOR +512.00 424.00 +512.00 408.00 +* +3 0 +0 +VECTOR +516.00 424.00 +516.00 408.00 +* +6 0 +0 +VECTOR +516.00 416.00 +564.00 416.00 +564.00 368.00 +592.00 368.00 +* +6 0 +0 +VECTOR +564.00 416.00 +564.00 448.00 +516.00 448.00 +* +6 0 +0 +ARC +480.00 454.00 +480.00 456.00 +480.00 456.00 +480.00 452.00 +482.00 454.00 +478.00 454.00 +* +3 0 +0 +VECTOR +476.00 444.00 +488.00 448.00 +* +3 0 +0 +ARC +480.00 442.00 +480.00 444.00 +480.00 444.00 +480.00 440.00 +482.00 442.00 +478.00 442.00 +* +3 0 +0 +VECTOR +512.00 456.00 +512.00 440.00 +* +3 0 +0 +VECTOR +516.00 456.00 +516.00 440.00 +* +6 0 +0 +VECTOR +488.00 448.00 +512.00 448.00 +* +6 0 +0 +VECTOR +480.00 440.00 +480.00 416.00 +* +6 0 +0 +ARC +352.00 384.00 +352.00 383.00 +352.00 385.00 +352.00 383.00 +353.00 384.00 +351.00 384.00 +* +3 0 +0 +ARC +480.00 416.00 +480.00 415.00 +480.00 417.00 +480.00 415.00 +481.00 416.00 +479.00 416.00 +* +3 0 +0 +ARC +564.00 416.00 +564.00 415.00 +564.00 417.00 +564.00 415.00 +565.00 416.00 +563.00 416.00 +* +3 0 +0 +VECTOR +480.00 456.00 +480.00 472.00 +* +6 0 +0 +BOTCENT +480.00 488.00 +452.00 488.00 +480.00 488.00 +509.00 488.00 +* +1 1 +12 $- ^ vv REF$ +POLYGON +484.00 480.00 +476.00 480.00 +476.00 476.00 +480.00 472.00 +484.00 476.00 +* +3 21 +0 +ARC +550.00 396.00 +548.00 396.00 +548.00 396.00 +552.00 396.00 +550.00 394.00 +550.00 398.00 +* +3 0 +0 +VECTOR +540.00 400.00 +544.00 388.00 +* +3 0 +0 +VECTOR +544.00 388.00 +544.00 316.00 +* +6 0 +0 +VECTOR +552.00 396.00 +552.00 416.00 +* +6 0 +0 +ARC +552.00 416.00 +552.00 415.00 +552.00 417.00 +552.00 415.00 +553.00 416.00 +551.00 416.00 +* +3 0 +0 +CENTRIGHT +516.00 352.00 +483.00 348.00 +499.00 348.00 +516.00 348.00 +* +1 1 +7 $vv B1$ +POLYGON +520.00 356.00 +520.00 348.00 +524.00 348.00 +528.00 352.00 +524.00 356.00 +* +3 21 +0 +VECTOR +512.00 280.00 +512.00 296.00 +* +3 0 +0 +VECTOR +516.00 280.00 +516.00 296.00 +* +6 0 +0 +VECTOR +564.00 288.00 +564.00 256.00 +516.00 256.00 +* +6 0 +0 +ARC +480.00 250.00 +480.00 248.00 +480.00 248.00 +480.00 252.00 +482.00 250.00 +478.00 250.00 +* +3 0 +0 +VECTOR +476.00 260.00 +488.00 256.00 +* +3 0 +0 +ARC +480.00 262.00 +480.00 260.00 +480.00 260.00 +480.00 264.00 +482.00 262.00 +478.00 262.00 +* +3 0 +0 +VECTOR +512.00 248.00 +512.00 264.00 +* +3 0 +0 +VECTOR +516.00 248.00 +516.00 264.00 +* +6 0 +0 +VECTOR +488.00 256.00 +512.00 256.00 +* +6 0 +0 +VECTOR +480.00 264.00 +480.00 288.00 +* +6 0 +0 +ARC +480.00 288.00 +480.00 289.00 +480.00 287.00 +480.00 289.00 +481.00 288.00 +479.00 288.00 +* +3 0 +0 +ARC +564.00 288.00 +564.00 289.00 +564.00 287.00 +564.00 289.00 +565.00 288.00 +563.00 288.00 +* +3 0 +0 +VECTOR +480.00 248.00 +480.00 232.00 +* +6 0 +0 +ARC +550.00 308.00 +548.00 308.00 +548.00 308.00 +552.00 308.00 +550.00 310.00 +550.00 306.00 +* +3 0 +0 +VECTOR +540.00 304.00 +544.00 316.00 +* +3 0 +0 +VECTOR +552.00 308.00 +552.00 288.00 +* +6 0 +0 +ARC +552.00 288.00 +552.00 289.00 +552.00 287.00 +552.00 289.00 +553.00 288.00 +551.00 288.00 +* +3 0 +0 +VECTOR +528.00 352.00 +544.00 352.00 +* +6 0 +0 +ARC +544.00 352.00 +544.00 351.00 +544.00 353.00 +544.00 351.00 +545.00 352.00 +543.00 352.00 +* +3 0 +0 +VECTOR +516.00 288.00 +564.00 288.00 +564.00 336.00 +592.00 336.00 +* +6 0 +0 +VECTOR +512.00 288.00 +448.00 288.00 +448.00 64.00 +* +6 0 +0 +VECTOR +352.00 416.00 +352.00 448.00 +* +6 0 +0 +ARC +352.00 416.00 +352.00 415.00 +352.00 417.00 +352.00 415.00 +353.00 416.00 +351.00 416.00 +* +3 0 +0 +BOTCENT +352.00 460.00 +343.00 460.00 +352.00 460.00 +361.00 460.00 +* +1 1 +3 $A$ +POLYGON +356.00 448.00 +348.00 448.00 +348.00 452.00 +352.00 456.00 +356.00 452.00 +* +3 21 +0 +BOTCENT +320.00 396.00 +307.00 396.00 +320.00 396.00 +333.00 396.00 +* +1 1 +6 $cc F$ +BOTRIGHT +348.00 328.00 +321.00 328.00 +334.00 328.00 +348.00 328.00 +* +1 1 +6 $cc O$ +BOTCENT +228.00 280.00 +215.00 280.00 +228.00 280.00 +242.00 280.00 +* +1 1 +6 $cc C$ +BOTCENT +128.00 272.00 +116.00 272.00 +128.00 272.00 +141.00 272.00 +* +1 1 +6 $cc S$ +CENTLEFT +204.00 256.00 +204.00 252.00 +227.00 252.00 +250.00 252.00 +* +1 1 +10 $DP sub 2$ +BOTCENT +68.00 264.00 +56.00 264.00 +68.00 264.00 +80.00 264.00 +* +1 1 +4 $PN$ +TOPRIGHT +388.00 380.00 +342.00 371.00 +365.00 371.00 +388.00 371.00 +* +1 1 +10 $DP sub 2$ +TOPCENT +392.00 348.00 +372.00 339.00 +392.00 339.00 +412.00 339.00 +* +1 1 +6 $AGND$ +POLYGON +396.00 352.00 +388.00 352.00 +388.00 356.00 +392.00 360.00 +396.00 356.00 +* +3 21 +0 +VECTOR +392.00 360.00 +392.00 376.00 +* +6 0 +0 +TOPRIGHT +540.00 396.00 +494.00 387.00 +517.00 387.00 +540.00 387.00 +* +1 1 +10 $DP sub 1$ +CENTRIGHT +508.00 440.00 +476.00 436.00 +492.00 436.00 +508.00 436.00 +* +1 1 +7 $cc D1$ +CENTRIGHT +508.00 408.00 +476.00 404.00 +492.00 404.00 +508.00 404.00 +* +1 1 +7 $cc D2$ +BOTRIGHT +508.00 268.00 +476.00 268.00 +492.00 268.00 +508.00 268.00 +* +1 1 +7 $cc D1$ +BOTRIGHT +508.00 300.00 +476.00 300.00 +492.00 300.00 +508.00 300.00 +* +1 1 +7 $cc D2$ +VECTOR +672.00 392.00 +672.00 344.00 +720.00 344.00 +720.00 392.00 +672.00 392.00 +* +3 0 +0 +ARC +696.00 396.00 +696.00 392.00 +696.00 400.00 +696.00 392.00 +700.00 396.00 +692.00 396.00 +* +3 0 +0 +TOPCENT +696.00 392.00 +688.00 383.00 +696.00 383.00 +705.00 383.00 +* +1 1 +3 $R$ +ARC +668.00 368.00 +668.00 364.00 +668.00 372.00 +668.00 364.00 +672.00 368.00 +664.00 368.00 +* +3 0 +0 +CENTLEFT +676.00 368.00 +676.00 364.00 +688.00 364.00 +700.00 364.00 +* +1 1 +4 $CK$ +ARC +724.00 368.00 +724.00 364.00 +724.00 372.00 +724.00 364.00 +720.00 368.00 +728.00 368.00 +* +3 0 +0 +CENTRIGHT +720.00 368.00 +688.00 364.00 +704.00 364.00 +720.00 364.00 +* +1 1 +7 $O bar$ +CENTLEFT +676.00 352.00 +676.00 348.00 +684.00 348.00 +693.00 348.00 +* +1 1 +3 $D$ +CENTRIGHT +720.00 352.00 +703.00 348.00 +711.00 348.00 +720.00 348.00 +* +1 1 +3 $O$ +VECTOR +656.00 352.00 +672.00 352.00 +* +6 0 +0 +VECTOR +720.00 352.00 +736.00 352.00 +736.00 176.00 +768.00 176.00 +* +6 0 +0 +VECTOR +728.00 368.00 +800.00 368.00 +* +6 0 +0 +BOTRIGHT +804.00 376.00 +762.00 376.00 +783.00 376.00 +804.00 376.00 +* +1 1 +6 $DOWN$ +POLYGON +800.00 372.00 +800.00 364.00 +804.00 364.00 +808.00 368.00 +804.00 372.00 +* +3 21 +0 +VECTOR +516.00 192.00 +564.00 192.00 +564.00 144.00 +592.00 144.00 +* +6 0 +0 +VECTOR +512.00 192.00 +432.00 192.00 +432.00 416.00 +* +6 0 +0 +VECTOR +512.00 200.00 +512.00 184.00 +* +3 0 +0 +VECTOR +516.00 200.00 +516.00 184.00 +* +6 0 +0 +VECTOR +564.00 192.00 +564.00 224.00 +516.00 224.00 +* +6 0 +0 +ARC +480.00 230.00 +480.00 232.00 +480.00 232.00 +480.00 228.00 +482.00 230.00 +478.00 230.00 +* +3 0 +0 +VECTOR +476.00 220.00 +488.00 224.00 +* +3 0 +0 +ARC +480.00 218.00 +480.00 220.00 +480.00 220.00 +480.00 216.00 +482.00 218.00 +478.00 218.00 +* +3 0 +0 +VECTOR +512.00 232.00 +512.00 216.00 +* +3 0 +0 +VECTOR +516.00 232.00 +516.00 216.00 +* +6 0 +0 +VECTOR +488.00 224.00 +512.00 224.00 +* +6 0 +0 +VECTOR +480.00 216.00 +480.00 192.00 +* +6 0 +0 +ARC +480.00 192.00 +480.00 191.00 +480.00 193.00 +480.00 191.00 +481.00 192.00 +479.00 192.00 +* +3 0 +0 +ARC +564.00 192.00 +564.00 191.00 +564.00 193.00 +564.00 191.00 +565.00 192.00 +563.00 192.00 +* +3 0 +0 +VECTOR +480.00 232.00 +480.00 248.00 +* +6 0 +0 +VECTOR +552.00 172.00 +552.00 192.00 +* +6 0 +0 +ARC +552.00 192.00 +552.00 191.00 +552.00 193.00 +552.00 191.00 +553.00 192.00 +551.00 192.00 +* +3 0 +0 +TOPRIGHT +508.00 220.00 +476.00 211.00 +492.00 211.00 +508.00 211.00 +* +1 1 +7 $cc D1$ +TOPRIGHT +508.00 188.00 +476.00 179.00 +492.00 179.00 +508.00 179.00 +* +1 1 +7 $cc D2$ +VECTOR +224.00 212.00 +192.00 212.00 +192.00 96.00 +316.00 96.00 +* +6 0 +0 +VECTOR +312.00 168.00 +256.00 168.00 +256.00 212.00 +288.00 212.00 +* +6 0 +0 +VECTOR +328.00 212.00 +416.00 212.00 +416.00 160.00 +356.00 160.00 +* +6 0 +0 +VECTOR +604.00 136.00 +612.00 136.00 +612.00 116.00 +620.00 116.00 +* +6 0 +0 +ARC +416.00 160.00 +416.00 161.00 +416.00 159.00 +416.00 161.00 +417.00 160.00 +415.00 160.00 +* +3 0 +0 +CENTLEFT +596.00 112.00 +596.00 108.00 +604.00 108.00 +613.00 108.00 +* +1 1 +3 $-$ +CENTLEFT +596.00 144.00 +596.00 140.00 +604.00 140.00 +612.00 140.00 +* +1 1 +3 $+$ +POLYGON +592.00 160.00 +592.00 96.00 +656.00 128.00 +592.00 160.00 +* +3 1 +0 +ARC +392.00 90.00 +392.00 88.00 +392.00 88.00 +392.00 92.00 +390.00 90.00 +394.00 90.00 +* +3 0 +0 +VECTOR +396.00 92.00 +384.00 96.00 +* +3 0 +0 +ARC +392.00 102.00 +392.00 100.00 +392.00 100.00 +392.00 104.00 +390.00 102.00 +394.00 102.00 +* +3 0 +0 +ARC +312.00 154.00 +312.00 152.00 +312.00 152.00 +312.00 156.00 +314.00 154.00 +310.00 154.00 +* +3 0 +0 +CENTRIGHT +276.00 128.00 +243.00 124.00 +259.00 124.00 +276.00 124.00 +* +1 1 +7 $vv B2$ +POLYGON +280.00 124.00 +280.00 132.00 +284.00 132.00 +288.00 128.00 +284.00 124.00 +* +3 21 +0 +VECTOR +308.00 156.00 +320.00 160.00 +* +3 0 +0 +ARC +312.00 166.00 +312.00 164.00 +312.00 164.00 +312.00 168.00 +314.00 166.00 +310.00 166.00 +* +3 0 +0 +VECTOR +356.00 152.00 +356.00 168.00 +* +3 0 +0 +VECTOR +352.00 152.00 +352.00 168.00 +* +6 0 +0 +VECTOR +320.00 160.00 +352.00 160.00 +* +6 0 +0 +VECTOR +320.00 88.00 +320.00 104.00 +* +3 0 +0 +VECTOR +316.00 88.00 +316.00 104.00 +* +6 0 +0 +VECTOR +312.00 152.00 +312.00 128.00 +288.00 128.00 +* +6 0 +0 +VECTOR +392.00 88.00 +416.00 88.00 +416.00 160.00 +* +6 0 +0 +VECTOR +320.00 96.00 +384.00 96.00 +* +6 0 +0 +VECTOR +352.00 96.00 +352.00 64.00 +512.00 64.00 +* +6 0 +0 +VECTOR +512.00 56.00 +512.00 72.00 +* +3 0 +0 +VECTOR +516.00 56.00 +516.00 72.00 +* +6 0 +0 +VECTOR +516.00 64.00 +564.00 64.00 +564.00 112.00 +592.00 112.00 +* +6 0 +0 +VECTOR +564.00 64.00 +564.00 32.00 +516.00 32.00 +* +6 0 +0 +ARC +480.00 26.00 +480.00 24.00 +480.00 24.00 +480.00 28.00 +482.00 26.00 +478.00 26.00 +* +3 0 +0 +VECTOR +476.00 36.00 +488.00 32.00 +* +3 0 +0 +ARC +480.00 38.00 +480.00 36.00 +480.00 36.00 +480.00 40.00 +482.00 38.00 +478.00 38.00 +* +3 0 +0 +VECTOR +512.00 24.00 +512.00 40.00 +* +3 0 +0 +VECTOR +516.00 24.00 +516.00 40.00 +* +6 0 +0 +VECTOR +488.00 32.00 +512.00 32.00 +* +6 0 +0 +VECTOR +480.00 40.00 +480.00 64.00 +* +6 0 +0 +ARC +352.00 96.00 +352.00 97.00 +352.00 95.00 +352.00 97.00 +353.00 96.00 +351.00 96.00 +* +3 0 +0 +ARC +480.00 64.00 +480.00 65.00 +480.00 63.00 +480.00 65.00 +481.00 64.00 +479.00 64.00 +* +3 0 +0 +ARC +564.00 64.00 +564.00 65.00 +564.00 63.00 +564.00 65.00 +565.00 64.00 +563.00 64.00 +* +3 0 +0 +VECTOR +480.00 24.00 +480.00 8.00 +* +6 0 +0 +TOPCENT +480.00 -4.00 +452.00 -13.00 +480.00 -13.00 +509.00 -13.00 +* +1 1 +12 $- ^ vv REF$ +POLYGON +484.00 0.00 +476.00 0.00 +476.00 4.00 +480.00 8.00 +484.00 4.00 +* +3 21 +0 +ARC +550.00 84.00 +548.00 84.00 +548.00 84.00 +552.00 84.00 +550.00 86.00 +550.00 82.00 +* +3 0 +0 +VECTOR +540.00 80.00 +544.00 92.00 +* +3 0 +0 +VECTOR +544.00 92.00 +544.00 164.00 +* +6 0 +0 +VECTOR +552.00 84.00 +552.00 64.00 +* +6 0 +0 +ARC +552.00 64.00 +552.00 65.00 +552.00 63.00 +552.00 65.00 +553.00 64.00 +551.00 64.00 +* +3 0 +0 +CENTRIGHT +516.00 128.00 +483.00 124.00 +499.00 124.00 +516.00 124.00 +* +1 1 +7 $vv B1$ +POLYGON +520.00 124.00 +520.00 132.00 +524.00 132.00 +528.00 128.00 +524.00 124.00 +* +3 21 +0 +ARC +550.00 172.00 +548.00 172.00 +548.00 172.00 +552.00 172.00 +550.00 170.00 +550.00 174.00 +* +3 0 +0 +VECTOR +540.00 176.00 +544.00 164.00 +* +3 0 +0 +VECTOR +528.00 128.00 +544.00 128.00 +* +6 0 +0 +ARC +544.00 128.00 +544.00 129.00 +544.00 127.00 +544.00 129.00 +545.00 128.00 +543.00 128.00 +* +3 0 +0 +VECTOR +352.00 64.00 +352.00 32.00 +* +6 0 +0 +ARC +352.00 64.00 +352.00 65.00 +352.00 63.00 +352.00 65.00 +353.00 64.00 +351.00 64.00 +* +3 0 +0 +CENTCENT +352.00 16.00 +344.00 12.00 +352.00 12.00 +360.00 12.00 +* +1 1 +3 $B$ +POLYGON +356.00 32.00 +348.00 32.00 +348.00 28.00 +352.00 24.00 +356.00 28.00 +* +3 21 +0 +TOPCENT +320.00 84.00 +307.00 75.00 +320.00 75.00 +333.00 75.00 +* +1 1 +6 $cc F$ +TOPRIGHT +348.00 160.00 +321.00 151.00 +334.00 151.00 +348.00 151.00 +* +1 1 +6 $cc O$ +BOTRIGHT +388.00 100.00 +342.00 100.00 +365.00 100.00 +388.00 100.00 +* +1 1 +10 $DP sub 2$ +BOTCENT +392.00 132.00 +372.00 132.00 +392.00 132.00 +412.00 132.00 +* +1 1 +6 $AGND$ +POLYGON +396.00 128.00 +388.00 128.00 +388.00 124.00 +392.00 120.00 +396.00 124.00 +* +3 21 +0 +VECTOR +392.00 120.00 +392.00 104.00 +* +6 0 +0 +BOTRIGHT +540.00 84.00 +494.00 84.00 +517.00 84.00 +540.00 84.00 +* +1 1 +10 $DP sub 1$ +BOTRIGHT +508.00 44.00 +476.00 44.00 +492.00 44.00 +508.00 44.00 +* +1 1 +7 $cc D1$ +BOTRIGHT +508.00 76.00 +476.00 76.00 +492.00 76.00 +508.00 76.00 +* +1 1 +7 $cc D2$ +VECTOR +672.00 88.00 +672.00 136.00 +720.00 136.00 +720.00 88.00 +672.00 88.00 +* +3 0 +0 +ARC +696.00 84.00 +696.00 88.00 +696.00 80.00 +696.00 88.00 +700.00 84.00 +692.00 84.00 +* +3 0 +0 +BOTCENT +696.00 88.00 +688.00 88.00 +696.00 88.00 +705.00 88.00 +* +1 1 +3 $R$ +ARC +668.00 112.00 +668.00 116.00 +668.00 108.00 +668.00 116.00 +672.00 112.00 +664.00 112.00 +* +3 0 +0 +CENTLEFT +676.00 112.00 +676.00 108.00 +688.00 108.00 +700.00 108.00 +* +1 1 +4 $CK$ +ARC +724.00 112.00 +724.00 116.00 +724.00 108.00 +724.00 116.00 +720.00 112.00 +728.00 112.00 +* +3 0 +0 +CENTRIGHT +720.00 112.00 +688.00 108.00 +704.00 108.00 +720.00 108.00 +* +1 1 +7 $O bar$ +CENTLEFT +676.00 128.00 +676.00 124.00 +684.00 124.00 +693.00 124.00 +* +1 1 +3 $D$ +CENTRIGHT +720.00 128.00 +703.00 124.00 +711.00 124.00 +720.00 124.00 +* +1 1 +3 $O$ +VECTOR +656.00 128.00 +672.00 128.00 +* +6 0 +0 +VECTOR +720.00 128.00 +800.00 128.00 +* +6 0 +0 +CENTRIGHT +804.00 120.00 +780.00 116.00 +792.00 116.00 +804.00 116.00 +* +1 1 +4 $UP$ +POLYGON +800.00 124.00 +800.00 132.00 +804.00 132.00 +808.00 128.00 +804.00 124.00 +* +3 21 +0 +ARC +256.00 212.00 +256.00 213.00 +256.00 211.00 +256.00 213.00 +257.00 212.00 +255.00 212.00 +* +3 0 +0 +VECTOR +224.00 204.00 +224.00 220.00 +* +3 0 +0 +VECTOR +228.00 204.00 +228.00 220.00 +* +6 0 +0 +VECTOR +228.00 212.00 +256.00 212.00 +* +6 0 +0 +VECTOR +192.00 224.00 +192.00 212.00 +160.00 212.00 +* +6 0 +0 +ARC +160.00 214.00 +160.00 212.00 +160.00 212.00 +160.00 216.00 +158.00 214.00 +162.00 214.00 +* +3 0 +0 +VECTOR +164.00 224.00 +152.00 220.00 +* +3 0 +0 +ARC +160.00 226.00 +160.00 224.00 +160.00 224.00 +160.00 228.00 +158.00 226.00 +162.00 226.00 +* +3 0 +0 +ARC +194.00 224.00 +196.00 224.00 +196.00 224.00 +192.00 224.00 +194.00 226.00 +194.00 222.00 +* +3 0 +0 +VECTOR +204.00 220.00 +200.00 232.00 +* +3 0 +0 +VECTOR +152.00 220.00 +128.00 220.00 +* +6 0 +0 +ARC +96.00 214.00 +96.00 212.00 +96.00 212.00 +96.00 216.00 +98.00 214.00 +94.00 214.00 +* +3 0 +0 +VECTOR +92.00 224.00 +104.00 220.00 +* +3 0 +0 +ARC +96.00 226.00 +96.00 224.00 +96.00 224.00 +96.00 228.00 +98.00 226.00 +94.00 226.00 +* +3 0 +0 +VECTOR +124.00 212.00 +124.00 228.00 +* +3 0 +0 +VECTOR +128.00 212.00 +128.00 228.00 +* +6 0 +0 +VECTOR +104.00 220.00 +124.00 220.00 +* +6 0 +0 +VECTOR +96.00 212.00 +96.00 160.00 +40.00 160.00 +* +6 0 +0 +VECTOR +96.00 228.00 +76.00 228.00 +* +6 0 +0 +ARC +68.00 222.00 +68.00 220.00 +68.00 220.00 +68.00 224.00 +70.00 222.00 +66.00 222.00 +* +3 0 +0 +VECTOR +64.00 232.00 +76.00 228.00 +* +3 0 +0 +ARC +68.00 234.00 +68.00 232.00 +68.00 232.00 +68.00 236.00 +70.00 234.00 +66.00 234.00 +* +3 0 +0 +TOPCENT +228.00 200.00 +215.00 191.00 +228.00 191.00 +242.00 191.00 +* +1 1 +6 $cc C$ +TOPCENT +128.00 208.00 +116.00 199.00 +128.00 199.00 +141.00 199.00 +* +1 1 +6 $cc S$ +CENTLEFT +204.00 224.00 +204.00 220.00 +227.00 220.00 +250.00 220.00 +* +1 1 +10 $DP sub 2$ +CENTRIGHT +154.00 240.00 +129.00 236.00 +141.00 236.00 +154.00 236.00 +* +1 1 +5 $ITS$ +CENTCENT +94.00 240.00 +84.00 236.00 +94.00 236.00 +105.00 236.00 +* +1 1 +4 $SP$ +TOPCENT +68.00 216.00 +56.00 207.00 +68.00 207.00 +80.00 207.00 +* +1 1 +4 $PN$ +ARC +432.00 416.00 +432.00 415.00 +432.00 417.00 +432.00 415.00 +433.00 416.00 +431.00 416.00 +* +3 0 +0 +ARC +448.00 64.00 +448.00 63.00 +448.00 65.00 +448.00 63.00 +449.00 64.00 +447.00 64.00 +* +3 0 +0 +VECTOR +480.00 248.00 +480.00 232.00 +* +6 0 +0 +CENTRIGHT +452.00 240.00 +396.00 236.00 +424.00 236.00 +452.00 236.00 +* +1 1 +12 $+ ^ vv REF$ +POLYGON +452.00 244.00 +452.00 236.00 +456.00 236.00 +460.00 240.00 +456.00 244.00 +* +3 21 +0 +VECTOR +460.00 240.00 +480.00 240.00 +* +6 0 +0 +ARC +480.00 240.00 +480.00 241.00 +480.00 239.00 +480.00 241.00 +481.00 240.00 +479.00 240.00 +* +3 0 +0 +VECTOR +160.00 252.00 +160.00 228.00 +* +6 0 +0 +VECTOR +160.00 240.00 +224.00 240.00 +* +6 0 +0 +ARC +160.00 240.00 +160.00 239.00 +160.00 241.00 +160.00 239.00 +161.00 240.00 +159.00 240.00 +* +3 0 +0 +ARC +200.00 240.00 +200.00 239.00 +200.00 241.00 +200.00 239.00 +201.00 240.00 +199.00 240.00 +* +3 0 +0 +CENTLEFT +236.00 240.00 +236.00 236.00 +252.00 236.00 +268.00 236.00 +* +1 1 +5 $GND$ +POLYGON +232.00 244.00 +232.00 236.00 +228.00 236.00 +224.00 240.00 +228.00 244.00 +* +3 21 +0 +TOPRIGHT +540.00 172.00 +494.00 163.00 +517.00 163.00 +540.00 163.00 +* +1 1 +10 $DP sub 1$ +BOTRIGHT +540.00 308.00 +494.00 308.00 +517.00 308.00 +540.00 308.00 +* +1 1 +10 $DP sub 1$ +VECTOR +340.00 260.00 +340.00 220.00 +300.00 240.00 +340.00 260.00 +* +3 0 +0 +VECTOR +340.00 232.00 +384.00 232.00 +384.00 224.00 +* +6 0 +0 +POLYGON +380.00 224.00 +392.00 224.00 +384.00 216.00 +376.00 224.00 +* +6 21 +0 +VECTOR +340.00 248.00 +392.00 248.00 +* +6 0 +0 +BOTLEFT +396.00 256.00 +396.00 256.00 +416.00 256.00 +437.00 256.00 +* +1 1 +8 $vv INC$ +POLYGON +400.00 252.00 +400.00 244.00 +396.00 244.00 +392.00 248.00 +396.00 252.00 +* +3 21 +0 +CENTRIGHT +336.00 248.00 +319.00 244.00 +327.00 244.00 +336.00 244.00 +* +1 1 +3 $-$ +CENTRIGHT +336.00 232.00 +320.00 228.00 +328.00 228.00 +336.00 228.00 +* +1 1 +3 $+$ +VECTOR +784.00 192.00 +768.00 192.00 +768.00 160.00 +784.00 160.00 +* +3 0 +0 +ARC +784.00 176.00 +784.00 160.00 +784.00 192.00 +* +3 180 +0 +VECTOR +784.00 256.00 +768.00 256.00 +768.00 224.00 +784.00 224.00 +* +3 0 +0 +ARC +784.00 240.00 +784.00 224.00 +784.00 256.00 +* +3 180 +0 +ARC +832.00 312.00 +832.00 296.00 +832.00 328.00 +* +3 180 +0 +VECTOR +832.00 328.00 +816.00 328.00 +816.00 296.00 +832.00 296.00 +* +3 0 +0 +VECTOR +744.00 368.00 +744.00 312.00 +772.00 312.00 +* +6 0 +0 +VECTOR +744.00 312.00 +744.00 240.00 +768.00 240.00 +* +6 0 +0 +VECTOR +728.00 112.00 +744.00 112.00 +744.00 232.00 +768.00 232.00 +* +6 0 +0 +VECTOR +800.00 304.00 +816.00 304.00 +* +6 0 +0 +VECTOR +816.00 320.00 +800.00 320.00 +800.00 332.00 +720.00 332.00 +* +6 0 +0 +CENTRIGHT +708.00 332.00 +683.00 328.00 +695.00 328.00 +708.00 328.00 +* +1 1 +5 $ITS$ +POLYGON +712.00 336.00 +712.00 328.00 +716.00 328.00 +720.00 332.00 +716.00 336.00 +* +3 21 +0 +VECTOR +760.00 332.00 +760.00 184.00 +768.00 184.00 +* +6 0 +0 +VECTOR +760.00 248.00 +768.00 248.00 +* +6 0 +0 +VECTOR +752.00 128.00 +752.00 168.00 +768.00 168.00 +* +6 0 +0 +CENTLEFT +828.00 240.00 +828.00 236.00 +843.00 236.00 +858.00 236.00 +* +1 1 +5 $ABP$ +POLYGON +816.00 244.00 +816.00 236.00 +820.00 236.00 +824.00 240.00 +820.00 244.00 +* +3 21 +0 +VECTOR +800.00 240.00 +816.00 240.00 +* +6 0 +0 +CENTLEFT +828.00 176.00 +828.00 172.00 +844.00 172.00 +860.00 172.00 +* +1 1 +5 $ABN$ +POLYGON +816.00 180.00 +816.00 172.00 +820.00 172.00 +824.00 176.00 +820.00 180.00 +* +3 21 +0 +VECTOR +800.00 176.00 +816.00 176.00 +* +6 0 +0 +VECTOR +848.00 312.00 +864.00 312.00 +* +6 0 +0 +POLYGON +864.00 316.00 +864.00 308.00 +868.00 308.00 +872.00 312.00 +868.00 316.00 +* +3 21 +0 +CENTLEFT +876.00 312.00 +876.00 308.00 +891.00 308.00 +907.00 308.00 +* +1 1 +5 $ABC$ +ARC +760.00 332.00 +760.00 331.00 +760.00 333.00 +760.00 331.00 +761.00 332.00 +759.00 332.00 +* +3 0 +0 +ARC +744.00 368.00 +744.00 367.00 +744.00 369.00 +744.00 367.00 +745.00 368.00 +743.00 368.00 +* +3 0 +0 +ARC +744.00 312.00 +744.00 311.00 +744.00 313.00 +744.00 311.00 +745.00 312.00 +743.00 312.00 +* +3 0 +0 +ARC +760.00 248.00 +760.00 247.00 +760.00 249.00 +760.00 247.00 +761.00 248.00 +759.00 248.00 +* +3 0 +0 +VECTOR +752.00 168.00 +752.00 296.00 +772.00 296.00 +* +6 0 +0 +ARC +752.00 128.00 +752.00 127.00 +752.00 129.00 +752.00 127.00 +753.00 128.00 +751.00 128.00 +* +3 0 +0 +ARC +752.00 168.00 +752.00 167.00 +752.00 169.00 +752.00 167.00 +753.00 168.00 +751.00 168.00 +* +3 0 +0 +ARC +28.00 178.00 +28.00 180.00 +28.00 180.00 +28.00 176.00 +30.00 178.00 +26.00 178.00 +* +3 0 +0 +VECTOR +24.00 176.00 +40.00 160.00 +* +3 0 +0 +ARC +28.00 142.00 +28.00 144.00 +28.00 144.00 +28.00 140.00 +30.00 142.00 +26.00 142.00 +* +3 0 +0 +ARC +14.00 160.00 +12.00 160.00 +12.00 160.00 +16.00 160.00 +14.00 162.00 +14.00 158.00 +* +3 0 +0 +VECTOR +28.00 300.00 +0.00 300.00 +0.00 180.00 +28.00 180.00 +* +6 0 +0 +VECTOR +12.00 320.00 +-16.00 320.00 +-16.00 160.00 +12.00 160.00 +* +6 0 +0 +VECTOR +28.00 140.00 +-32.00 140.00 +-32.00 340.00 +28.00 340.00 +* +6 0 +0 +CENTRIGHT +-60.00 268.00 +-116.00 264.00 +-88.00 264.00 +-60.00 264.00 +* +1 1 +12 $+ ^ vv REF$ +POLYGON +-56.00 272.00 +-56.00 264.00 +-52.00 264.00 +-48.00 268.00 +-52.00 272.00 +* +3 21 +0 +VECTOR +-48.00 268.00 +-32.00 268.00 +* +6 0 +0 +ARC +-32.00 268.00 +-32.00 267.00 +-32.00 269.00 +-32.00 267.00 +-31.00 268.00 +-33.00 268.00 +* +3 0 +0 +ARC +-16.00 240.00 +-16.00 239.00 +-16.00 241.00 +-16.00 239.00 +-15.00 240.00 +-17.00 240.00 +* +3 0 +0 +VECTOR +-48.00 240.00 +-16.00 240.00 +* +6 0 +0 +POLYGON +-56.00 244.00 +-56.00 236.00 +-52.00 236.00 +-48.00 240.00 +-52.00 244.00 +* +3 21 +0 +CENTRIGHT +-60.00 240.00 +-100.00 236.00 +-80.00 236.00 +-60.00 236.00 +* +1 1 +6 $AGND$ +CENTRIGHT +-60.00 212.00 +-117.00 208.00 +-89.00 208.00 +-60.00 208.00 +* +1 1 +12 $- ^ vv REF$ +POLYGON +-56.00 216.00 +-56.00 208.00 +-52.00 208.00 +-48.00 212.00 +-52.00 216.00 +* +3 21 +0 +VECTOR +-48.00 212.00 +0.00 212.00 +* +6 0 +0 +ARC +0.00 212.00 +0.00 211.00 +0.00 213.00 +0.00 211.00 +1.00 212.00 +-1.00 212.00 +* +3 0 +0 +BOTRIGHT +24.00 344.00 +-6.00 344.00 +9.00 344.00 +24.00 344.00 +* +1 1 +5 $ABP$ +BOTRIGHT +12.00 324.00 +-19.00 324.00 +-4.00 324.00 +12.00 324.00 +* +1 1 +5 $ABC$ +BOTRIGHT +24.00 304.00 +-8.00 304.00 +8.00 304.00 +24.00 304.00 +* +1 1 +5 $ABN$ +BOTRIGHT +24.00 184.00 +-6.00 184.00 +9.00 184.00 +24.00 184.00 +* +1 1 +5 $ABP$ +BOTRIGHT +12.00 164.00 +-19.00 164.00 +-4.00 164.00 +12.00 164.00 +* +1 1 +5 $ABC$ +BOTRIGHT +24.00 144.00 +-8.00 144.00 +8.00 144.00 +24.00 144.00 +* +1 1 +5 $ABN$ +VECTOR +68.00 260.00 +52.00 260.00 +52.00 220.00 +68.00 220.00 +* +6 0 +0 +VECTOR +68.00 244.00 +68.00 236.00 +* +6 0 +0 +VECTOR +68.00 240.00 +40.00 240.00 +* +6 0 +0 +VECTOR +52.00 260.00 +40.00 260.00 +* +6 0 +0 +CENTRIGHT +32.00 260.00 +-21.00 256.00 +5.00 256.00 +32.00 256.00 +* +1 1 +12 $+ ^ vv SIG$ +POLYGON +32.00 264.00 +32.00 256.00 +36.00 256.00 +40.00 260.00 +36.00 264.00 +* +3 21 +0 +POLYGON +32.00 244.00 +32.00 236.00 +36.00 236.00 +40.00 240.00 +36.00 244.00 +* +3 21 +0 +CENTRIGHT +32.00 240.00 +-22.00 236.00 +5.00 236.00 +32.00 236.00 +* +1 1 +12 $- ^ vv SIG$ +ARC +52.00 260.00 +52.00 259.00 +52.00 261.00 +52.00 259.00 +53.00 260.00 +51.00 260.00 +* +3 0 +0 +ARC +68.00 240.00 +68.00 239.00 +68.00 241.00 +68.00 239.00 +69.00 240.00 +67.00 240.00 +* +3 0 +0 +VECTOR +64.00 112.00 +96.00 112.00 +96.00 96.00 +* +6 0 +0 +VECTOR +88.00 96.00 +104.00 96.00 +* +3 0 +0 +VECTOR +88.00 92.00 +104.00 92.00 +* +6 0 +0 +VECTOR +96.00 92.00 +96.00 76.00 +* +6 0 +0 +ARC +90.00 68.00 +88.00 68.00 +88.00 68.00 +92.00 68.00 +90.00 70.00 +90.00 66.00 +* +3 0 +0 +VECTOR +92.00 64.00 +96.00 76.00 +* +3 0 +0 +ARC +102.00 68.00 +100.00 68.00 +100.00 68.00 +104.00 68.00 +102.00 70.00 +102.00 66.00 +* +3 0 +0 +VECTOR +128.00 92.00 +128.00 4.00 +* +6 0 +0 +VECTOR +120.00 96.00 +136.00 96.00 +* +3 0 +0 +VECTOR +120.00 92.00 +136.00 92.00 +* +6 0 +0 +BOTCENT +128.00 124.00 +119.00 124.00 +128.00 124.00 +137.00 124.00 +* +1 1 +3 $A$ +POLYGON +132.00 120.00 +124.00 120.00 +124.00 116.00 +128.00 112.00 +132.00 116.00 +* +3 21 +0 +VECTOR +128.00 112.00 +128.00 96.00 +* +6 0 +0 +VECTOR +88.00 68.00 +76.00 68.00 +76.00 28.00 +88.00 28.00 +* +6 0 +0 +VECTOR +104.00 68.00 +116.00 68.00 +116.00 28.00 +104.00 28.00 +* +6 0 +0 +BOTLEFT +100.00 100.00 +100.00 100.00 +114.00 100.00 +128.00 100.00 +* +1 1 +6 $cc Y$ +BOTLEFT +132.00 100.00 +132.00 100.00 +145.00 100.00 +158.00 100.00 +* +1 1 +6 $cc Z$ +BOTRIGHT +92.00 72.00 +46.00 72.00 +69.00 72.00 +92.00 72.00 +* +1 1 +10 $DP sub 1$ +CENTRIGHT +52.00 112.00 +8.00 108.00 +30.00 108.00 +52.00 108.00 +* +1 1 +10 $+ ^ vv O$ +POLYGON +56.00 116.00 +56.00 108.00 +60.00 108.00 +64.00 112.00 +60.00 116.00 +* +3 21 +0 +BOTCENT +384.00 300.00 +362.00 300.00 +384.00 300.00 +406.00 300.00 +* +1 1 +10 $+ ^ vv O$ +POLYGON +388.00 288.00 +380.00 288.00 +380.00 292.00 +384.00 296.00 +388.00 292.00 +* +3 21 +0 +VECTOR +384.00 288.00 +384.00 268.00 +* +6 0 +0 +ARC +384.00 268.00 +384.00 267.00 +384.00 269.00 +384.00 267.00 +385.00 268.00 +383.00 268.00 +* +3 0 +0 +TOPCENT +384.00 180.00 +362.00 171.00 +384.00 171.00 +407.00 171.00 +* +1 1 +10 $- ^ vv O$ +POLYGON +388.00 192.00 +380.00 192.00 +380.00 188.00 +384.00 184.00 +388.00 188.00 +* +3 21 +0 +VECTOR +384.00 192.00 +384.00 212.00 +* +6 0 +0 +ARC +384.00 212.00 +384.00 213.00 +384.00 211.00 +384.00 213.00 +385.00 212.00 +383.00 212.00 +* +3 0 +0 +TOPLEFT +132.00 -4.00 +132.00 -13.00 +145.00 -13.00 +158.00 -13.00 +* +1 1 +6 $cc Z$ +VECTOR +64.00 -16.00 +96.00 -16.00 +96.00 0.00 +* +6 0 +0 +VECTOR +88.00 0.00 +104.00 0.00 +* +3 0 +0 +VECTOR +88.00 4.00 +104.00 4.00 +* +6 0 +0 +VECTOR +96.00 4.00 +96.00 20.00 +* +6 0 +0 +ARC +90.00 28.00 +88.00 28.00 +88.00 28.00 +92.00 28.00 +90.00 26.00 +90.00 30.00 +* +3 0 +0 +VECTOR +92.00 32.00 +96.00 20.00 +* +3 0 +0 +ARC +102.00 28.00 +100.00 28.00 +100.00 28.00 +104.00 28.00 +102.00 26.00 +102.00 30.00 +* +3 0 +0 +VECTOR +120.00 0.00 +136.00 0.00 +* +3 0 +0 +VECTOR +120.00 4.00 +136.00 4.00 +* +6 0 +0 +TOPCENT +128.00 -28.00 +120.00 -37.00 +128.00 -37.00 +136.00 -37.00 +* +1 1 +3 $B$ +POLYGON +132.00 -24.00 +124.00 -24.00 +124.00 -20.00 +128.00 -16.00 +132.00 -20.00 +* +3 21 +0 +VECTOR +128.00 -16.00 +128.00 0.00 +* +6 0 +0 +TOPLEFT +100.00 -4.00 +100.00 -13.00 +114.00 -13.00 +128.00 -13.00 +* +1 1 +6 $cc Y$ +CENTRIGHT +92.00 24.00 +46.00 20.00 +69.00 20.00 +92.00 20.00 +* +1 1 +10 $DP sub 1$ +CENTRIGHT +52.00 -16.00 +8.00 -20.00 +30.00 -20.00 +52.00 -20.00 +* +1 1 +10 $+ ^ vv O$ +POLYGON +56.00 -20.00 +56.00 -12.00 +60.00 -12.00 +64.00 -16.00 +60.00 -20.00 +* +3 21 +0 +VECTOR +116.00 48.00 +152.00 48.00 +* +6 0 +0 +CENTLEFT +164.00 48.00 +164.00 44.00 +184.00 44.00 +205.00 44.00 +* +1 1 +8 $vv INC$ +POLYGON +152.00 44.00 +152.00 52.00 +156.00 52.00 +160.00 48.00 +156.00 44.00 +* +3 21 +0 +ARC +116.00 48.00 +116.00 49.00 +116.00 47.00 +116.00 49.00 +117.00 48.00 +115.00 48.00 +* +3 0 +0 +ARC +128.00 48.00 +128.00 49.00 +128.00 47.00 +128.00 49.00 +129.00 48.00 +127.00 48.00 +* +3 0 +0 +ARC +76.00 48.00 +76.00 49.00 +76.00 47.00 +76.00 49.00 +77.00 48.00 +75.00 48.00 +* +3 0 +0 +VECTOR +56.00 48.00 +76.00 48.00 +* +6 0 +0 +POLYGON +48.00 52.00 +48.00 44.00 +52.00 44.00 +56.00 48.00 +52.00 52.00 +* +3 21 +0 +CENTRIGHT +48.00 48.00 +15.00 44.00 +31.00 44.00 +48.00 44.00 +* +1 1 +7 $vv B1$ +-1 diff --git a/doc/grnexmpl.me b/doc/grnexmpl.me new file mode 100644 index 0000000..641d15c --- /dev/null +++ b/doc/grnexmpl.me @@ -0,0 +1,88 @@ +.nr pp 12 +.nr tp 12 +.nr sp 12 +.nr fi 0 +.ls 1 +.po 1i +.pl 11i +.EQ +gsize 12 +delim $$ +define // 'over down 10' +define sw 'phi sub' +define aa 'A sub' +define vv 'V sub' +define mm 'M sub' +define nn 'N sub' +define cc 'C sub' +define ll 'L sub' +define rr 'R sub' +define ss 'S sub' +define gg 'g sub' +define ff 'F sub' +define qq 'Q sub' +define qqq '{C prime} sub' +define pp 'P sub' +define tt 'T sub' +define zz 'Z sub' +define kk 'K sub' +define ii 'I sub' +define iis 'IC sub' +define e2 '2 sup' +define sunc '{ sin x } / x' +define vddm1V 'vv DD - 1 ^ roman V' +define vssp1V 'vv SS + 1 ^ roman V' +.EN +.pp +The following slide shows the complete schematics of the +fully-differential RIC. The operation includes a +correlated-double-sampling phase that occurs once every 256 +clock periods, also called the +.i "spreading ratio" . +This reset phase is controlled by clocks $ DP sub 1 $ and $ DP +sub 2 $ in which the integrator is initialized by totally +removing the charge from $ cc F $ and storing the low-frequency +noise of the op amp in $ cc C $. At the same time the comparison +thresholds are set. +.fl +.po -0.2i +.sp 2 +.lp +.(b +.EQ +gsize -4 +.EN +.GS +roman 1 +italics 2 +bold 3 +special 4 +narrow 1 +medium 3 +thick 5 +width 5.5 +l mg +file grnexmpl.g +.GE +.EQ +gsize +4 +.EN +.)b +.fl +.po +0.2i +.pp +The faster clocks are $ PN $, $ ITS $ and $ SP $. The sampling +capacitor $ cc S $ performs the delayed subtraction of a sample +of the input signal $ +- ^ vv SIG $ and a choice of $ - ^ vv REF +$, $ AGND $ or $ + ^ vv REF $ according to the operations +performed by the logic partially depicted operating on past +results of the comparisons. The synchronous comparators are +reset at this fast rates, thus performing one comparison for +every fast clock cycle. The dynamic common-mode feedback +arrangement operates synchronously with the reset time slot and +its configuration is equivalent to that in the differential +feedback path. +.\" Local Variables: +.\" mode: nroff +.\" End: +.\" vim: filetype=groff: diff --git a/doc/groff.css b/doc/groff.css new file mode 100644 index 0000000..ea36359 --- /dev/null +++ b/doc/groff.css @@ -0,0 +1,17 @@ + +body { + margin-top: 0%; + margin-left: 0%; + margin-right: 0%; + margin-bottom: 0%; + background-color: white; + color: black; +} + +pre { + background-color: #E0E0E0; + color: black; + border: thin; + border-style: solid; +} + diff --git a/doc/groff.dvi b/doc/groff.dvi new file mode 100644 index 0000000..9efd1f6 Binary files /dev/null and b/doc/groff.dvi differ diff --git a/doc/groff.html b/doc/groff.html new file mode 100644 index 0000000..e085b9e --- /dev/null +++ b/doc/groff.html @@ -0,0 +1,24945 @@ +<!DOCTYPE html> +<html> +<!-- Created by GNU Texinfo 7.0.3, https://www.gnu.org/software/texinfo/ --> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> +<!-- This manual documents GNU troff version 1.23.0. + +Copyright Š 1994-2023 Free Software Foundation, Inc. + +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 or +any later version published by the Free Software Foundation; with no +Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A +copy of the license is included in the section entitled "GNU Free +Documentation License". --> +<title>The GNU Troff Manual + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +

GNU troff

+ + +

This manual documents GNU troff version 1.23.0. +

+

Copyright © 1994–2023 Free Software Foundation, Inc. +

+
+

Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 or +any later version published by the Free Software Foundation; with no +Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A +copy of the license is included in the section entitled “GNU Free +Documentation License”. +

+ + + + + +
+

Table of Contents

+ +
+ + +
+
+
+
+ +

1 Introduction

+ + +

GNU roff (or groff) is a programming system for +typesetting documents. It is highly flexible and has been used +extensively for over thirty years. +

+ + + + +
+
+ +

1.1 Background

+ + +

M. Douglas McIlroy, formerly of AT&T Bell Laboratories and present at +the creation of the Unix operating system, offers an authoritative +historical summary. +

+
+

The prime reason for Unix was the desire of Ken [Thompson], Dennis +[Ritchie], and Joe Ossanna to have a pleasant environment for software +development. The fig leaf that got the nod from … +management was that an early use would be to develop a “stand-alone” +word-processing system for use in typing pools and secretarial offices. +Perhaps they had in mind “dedicated”, as distinct from +“stand-alone”; that’s what eventuated in various cases, most notably +in the legal/patent department and in the AT&T CEO’s office. +

+

Both those systems were targets of opportunity, not foreseen from the +start. When Unix was up and running on the PDP-11, Joe got wind of +the legal department having installed a commercial word processor. +He went to pitch Unix as an alternative and clinched a trial by +promising to make roff able to number lines by tomorrow in order +to fulfill a patent-office requirement that the commercial system did +not support. +

+

Modems were installed so legal-department secretaries could try the +Research machine. They liked it and Joe’s superb customer service. +Soon the legal department got a system of their own. Joe went on to +create nroff and troff. Document preparation became a +widespread use of Unix, but no stand-alone word-processing system was +ever undertaken. +

+ +

A history relating groff to its predecessors roff, +nroff, and troff is available in the roff(7) +man page. +

+ + +
+
+
+ +

1.2 What Is groff?

+ + + +

groff (GNU roff) is a typesetting system that reads plain +text input files that include formatting commands to produce output in +PostScript, PDF, HTML, DVI, or other formats, or for display to a +terminal. Formatting commands can be low-level typesetting primitives, +macros from a supplied package, or user-defined macros. All three +approaches can be combined. +

+

A reimplementation and extension of the typesetter from AT&T +Unix, groff is present on most POSIX systems owing to +its long association with Unix manuals (including man pages). It and +its predecessor are notable for their production of several best-selling +software engineering texts. groff is capable of producing +typographically sophisticated documents while consuming minimal system +resources. +

+ + +
+
+
+ +

1.3 groff Capabilities

+ + + +

GNU troff is a typesetting document formatter; it provides a wide +range of low-level text and page operations within the framework of a +programming language. These operations compose to generate footnotes, +tables of contents, mathematical equations, diagrams, multi-column text, +and other elements of typeset works. Here is a survey of formatter +features; all are under precise user control. +

+
    +
  • text filling, breaking, alignment to the left or right margin; centering + +
  • adjustment of inter-word space size to justify text, and of +inter-sentence space size to suit local style conventions + +
  • automatic and manual determination of hyphenation break points + +
  • pagination + +
  • selection of any font available to the output device + +
  • adjustment of type size and vertical spacing (or “leading”) + +
  • configuration of line length and indentation amounts; columnation + +
  • drawing of geometric primitives (lines, arcs, polygons, circles, +…) + +
  • setup of stroke and fill colors (where supported by the output +device) + +
  • embedding of hyperlinks, images, document metadata, and other inclusions +(where supported by the output device) +
+ + + +
+
+
+ +

1.4 Macro Packages

+ + + +

Elemental typesetting functions can be be challenging to use directly +with complex documents. A macro facility specifies how certain +routine operations, such as starting paragraphs, or printing headers and +footers, should be performed in terms of those low-level instructions. +Macros can be specific to one document or collected together into a +macro package for use by many. Several macro packages available; +the most widely used are provided with groff. They are +man, mdoc, me, mm, mom, and +ms. +

+ + +
+
+
+ +

1.5 Preprocessors

+ + +

An alternative approach to complexity management, particularly when +constructing tables, setting mathematics, or drawing diagrams, lies in +preprocessing. A preprocessor employs a domian-specific language +to ease the generation of tables, equations, and so forth in terms that +are convenient for human entry. Each preprocessor reads a document and +translates the parts of it that apply to it into GNU troff input. +Command-line options to groff tell it which preprocessors to +use. +

+

groff provides preprocessors for laying out tables +(gtbl), typesetting equations (geqn), drawing +diagrams (gpic and ggrn), inserting bibliographic +references (grefer), and drawing chemical structures +(gchem). An associated program that is useful when dealing +with preprocessors is gsoelim.1 +

+

groff also supports grap, a preprocessor for drawing +graphs. A free implementation of it can be obtained separately. +

+

Unique to groff is the preconv preprocessor that enables +groff to handle documents in a variety of input encodings. +

+

Other preprocessors exist, but no free implementations +are known. An example is ideal, which draws diagrams using a +mathematical constraint language. +

+ + +
+
+
+ +

1.6 Output Devices

+ + + + +

GNU troff’s output is in a device-independent page description +language, which is then read by an output driver that translates +this language into a file format or byte stream that a piece of +(possibly emulated) hardware understands. groff features output +drivers for PostScript devices, terminal emulators (and other simple +typewriter-like machines), X11 (for previewing), TeX DVI, HP +LaserJet 4/PCL5 and Canon LBP printers (which use CaPSL), +HTML, XHTML, and PDF. +

+ + +
+
+
+ +

1.7 Installation

+ + +

Locate installation instructions in the files INSTALL, +INSTALL.extra, and INSTALL.REPO in the groff source +distribution. Being a GNU project, groff supports the familiar +‘./configure && make’ command sequence. +

+ + +
+
+
+ +

1.8 Conventions Used in This Manual

+ +

We apply the term “groff” to the language documented here, the GNU +implementation of the overall system, the project that develops that +system, and the command of that name. In the first sense, groff +is an extended dialect of the roff language, for which many +similar implementations exist. +

+

The roff language features several major categories for which +many items are predefined. Presentations of these items feature the +form in which the item is most commonly used on the left, and, aligned +to the right margin, the name of the category in brackets. +

+
+
Register: \n[example]
+

The register ‘example’ is one that that groff doesn’t +predefine. You can create it yourself, though; see Setting Registers. +

+ +

To make this document useful as a reference and not merely amiable +bedtime reading, we tend to present these syntax items in exhaustive +detail when they arise. References to topics discussed later in the +text are frequent; skip material you don’t understand yet. +

+

We use Texinfo’s “result” (⇒) and error→ notations to +present output written to the standard output and standard error +streams, respectively. Diagnostic messages from the GNU troff +formatter and other programs are examples of the latter, but the +formatter can also be directed to write user-specified messages to the +standard error stream. The notation then serves to identify the +output stream and does not necessarily mean that an error has +occurred.2 +

+
+
$ echo "Twelve o'clock and" | groff -Tascii | sed '/^$/d'
+    ⇒ Twelve o'clock and
+$ echo '.tm all is well.' | groff > /dev/null
+    error→ all is well.
+
+ +

Sometimes we use ⇒ somewhat abstractly to represent formatted +text that you will need to use a PostScript or PDF viewer program (or a +printer) to observe. While arguably an abuse of notation, we think this +preferable to requiring the reader to understand the syntax of these +page description languages. +

+

We also present diagnostic messages in an abbreviated form, often +omitting the name of the program issuing them, the input file name, and +line number or other positional information when such data do not serve +to illuminate the topic under discussion. +

+

Most examples are of roff language input that would be placed in +a text file. Occasionally, we start an example with a ‘$’ +character to indicate a shell prompt, as seen above. +

+

You are encouraged to try the examples yourself, and to alter them to +better learn groff’s behavior. Our examples frequently need to +direct the formatter to set a line length (with ‘.ll’) that will +fit within the page margins of this manual. We mention this so that you +know why it is there before we discuss the ll request +formally.3 +

+ + +
+
+
+ +

1.9 Credits

+ + +

We adapted portions of this manual from existing documents. James +Clark’s man pages were an essential resource; we have updated them in +parallel with the development of this manual. We based the tutorial for +macro users on Eric Allman’s introduction to his me macro package +(which we also provide, little altered from 4.4BSD). Larry Kollar +contributed much of the material on the ms macro package. +

+ + +
+
+
+
+ +

2 Invoking groff

+ + + +

This chapter focuses on how to invoke the groff front end. This +front end takes care of the details of constructing the pipeline among +the preprocessors, gtroff and the postprocessor. +

+

It has become a tradition that GNU programs get the prefix ‘g’ to +distinguish them from their original counterparts provided by the host +(see Environment). Thus, for example, geqn is GNU +eqn. On operating systems like GNU/Linux or the Hurd, which +don’t contain proprietary versions of troff, and on +MS-DOS/MS-Windows, where troff and associated programs are not +available at all, this prefix is omitted since GNU troff is the +only incarnation of troff used. Exception: ‘groff’ is never +replaced by ‘roff’. +

+

In this document, we consequently say ‘gtroff’ when talking about +the GNU troff program. All other implementations of troff are called AT&T +troff, which is the common origin of almost all troff +implementations4 (with more or less compatible changes). Similarly, we say +‘gpic’, ‘geqn’, and so on. +

+ + + + +
+
+ +

2.1 Options

+ + + + + + + + + + + + + +

groff normally runs the gtroff program and a +postprocessor appropriate for the selected device. The default device +is ‘ps’ (but it can be changed when groff is configured and +built). It can optionally preprocess with any of gpic, +geqn, gtbl, ggrn, grap, gchem, +grefer, gsoelim, or preconv. +

+

This section documents only options to the groff front end. Many +of the arguments to groff are passed on to gtroff; +therefore, those are also included. Arguments to preprocessors and +output drivers can be found in the man pages gpic(1), +geqn(1), gtbl(1), ggrn(1), +grefer(1), gchem(1), gsoelim(1), +preconv(1), grotty(1), grops(1), +gropdf(1), grohtml(1), grodvi(1), +grolj4(1), grolbp(1), and gxditview(1). +

+

The command-line format for groff is: +

+
+
groff [ -abceghijklpstvzCEGNRSUVXZ ] [ -dcs ] [ -Darg ]
+      [ -ffam ] [ -Fdir ] [ -Idir ] [ -Karg ]
+      [ -Larg ] [ -mname ] [ -Mdir ] [ -nnum ]
+      [ -olist ] [ -Parg ] [ -rcn ] [ -Tdev ]
+      [ -wname ] [ -Wname ] [ files… ]
+
+ +

The command-line format for gtroff is as follows. +

+
+
gtroff [ -abcivzCERU ] [ -dcs ] [ -ffam ] [ -Fdir ]
+       [ -mname ] [ -Mdir ] [ -nnum ] [ -olist ]
+       [ -rcn ] [ -Tname ] [ -wname ] [ -Wname ]
+       [ files… ]
+
+ +

Obviously, many of the options to groff are actually passed on to +gtroff. +

+

Options without an argument can be grouped behind a +single -. A filename of - denotes the +standard input. Whitespace is permitted between an option and its +argument. +

+

The grog command can be used to guess the correct groff +command to format a file. See its man page grog(1); type +‘man grog’ at the command line to view it. +

+

groff’s command-line options are as follows. +

+ +
+
-a
+

Generate a plain text approximation of the typeset output. The +read-only register .A is set to 1. See Built-in Registers. This option produces a sort of abstract preview of the +formatted output. +

+
    +
  • Page breaks are marked by a phrase in angle brackets; for example, +‘<beginning of page>’. + +
  • Lines are broken where they would be in the formatted output. + +
  • A horizontal motion of any size is represented as one space. Adjacent +horizontal motions are not combined. Inter-sentence space nodes (those +arising from the second argument to the ss request) are not +represented. + +
  • Vertical motions are not represented. + +
  • Special characters are rendered in angle brackets; for example, the +default soft hyphen character appears as ‘<hy>’. +
+ +

The above description should not be considered a specification; the +details of -a output are subject to change. +

+
+
-b
+

Write a backtrace reporting the state of gtroff’s input parser +to the standard error stream with each diagnostic message. The line +numbers given in the backtrace might not always be correct, because +gtroff’s idea of line numbers can be confused by requests that +append to +macros. +

+
+
-c
+

Start with color output disabled. +

+
+
-C
+

Enable AT&T troff compatibility mode; implies -c. +See Implementation Differences, for the list of incompatibilities +between groff and AT&T troff. +

+
+
-dctext
+
-dstring=text
+

Define roff string c or string as t or +text. c must be one character; string can be +of arbitrary length. Such string assignments happen before any macro +file is loaded, including the startup file. Due to getopt_long +limitations, c cannot be, and string cannot contain, an +equals sign, even though that is a valid character in a roff +identifier. +

+
+
-Denc
+

Set fallback input encoding used by preconv to enc; +implies -k. +

+
+
-e
+

Run geqn preprocessor. +

+
+
-E
+

Inhibit gtroff error messages. This option does not +suppress messages sent to the standard error stream by documents or +macro packages using tm or related requests. +

+
+
-ffam
+

Use fam as the default font family. See Font Families. +

+
+
-Fdir
+

Search in directory dir for the selected output device’s +directory of device and font description files. See the description of +GROFF_FONT_PATH in Environment below for the default search +locations and ordering. +

+
+
-g
+

Run ggrn preprocessor. +

+
+
-G
+

Run grap preprocessor; implies -p. +

+
+
-h
+

Display a usage message and exit. +

+
+
-i
+

Read the standard input after all the named input files have been +processed. +

+
+
-Idir
+

Search the directory dir for files named in several contexts; +implies -g and -s. +

+
    +
  • gsoelim replaces so requests with the contents of their +file name arguments. + +
  • gtroff searches for files named as operands in its command +line and as arguments to psbb, so, and soquiet +requests. + +
  • Output drivers may search for files; for instance, grops looks +for files named in ‘\X'ps: import '’, ‘\X'ps: file +'’, and ‘\X'pdf: pdfpic '’ device control +escape sequences. +
+ +

This option may be specified more than once; the directories are +searched in the order specified. If you want to search the current +directory before others, add ‘-I .’ at the desired place. The +current working directory is otherwise searched last. -I works +similarly to, and is named for, the “include” option of Unix C +compilers. +

+

-I options are passed to gsoelim, gtroff, +and output drivers; with the flag letter changed to -M, they +are also passed to ggrn. +

+
+
-j
+

Run gchem preprocessor. Implies -p. +

+
+
-k
+

Run preconv preprocessor. Refer to its man page for its +behavior if neither of groff’s -K or -D +options is also specified. +

+
+
-Kenc
+

Set input encoding used by preconv to enc; implies +-k. +

+
+
-l
+

Send the output to a spooler for printing. The print directive +in the device description file specifies the default command to be used; +see Device and Font Description Files. +See options -L and -X. +

+
+
-Larg
+

Pass arg to the print spooler program. If multiple args are +required, pass each with a separate -L option. groff +does not prefix an option dash to arg before passing it to the +spooler program. +

+
+
-mname
+

Process the file name.tmac prior to any input files. +If not found, tmac.name is attempted. name +(in both arrangements) is presumed to be a macro file; see the +description of GROFF_TMAC_PATH in Environment below for the +default search locations and ordering. This option and its argument are +also passed to geqn, grap, and ggrn. +

+
+
-Mdir
+

Search directory dir for macro files; see the description +of GROFF_TMAC_PATH in Environment below for the default +search locations and ordering. This option and its argument are also +passed to geqn, grap, and ggrn. +

+
+
-nnum
+

Number the first page num. +

+
+
-N
+

Prohibit newlines between eqn delimiters: pass -N to +geqn. +

+
+
-olist
+

Output only pages in list, which is a comma-separated list of page +ranges; ‘n’ means page n, ‘m-n’ +means every page between m and n, ‘-n’ means +every page up to n, ‘n-’ means every page from +n on. gtroff stops processing and exits after +formatting the last page enumerated in list. +

+
+
-p
+

Run gpic preprocessor. +

+
+
-Parg
+

Pass arg to the postprocessor. If multiple args are +required, pass each with a separate -P option. groff +does not prefix an option dash to arg before passing it to the +postprocessor. +

+
+
-rcnumeric-expression
+
-rregister=expr
+

Set roff register c or register to the value +numeric-expression (see Numeric Expressions). +c must be one character; register can be of arbitrary +length. Such register assignments happen before any macro file is +loaded, including the startup file. Due to getopt_long +limitations, c cannot be, and register cannot contain, +an equals sign, even though that is a valid character in a roff +identifier. +

+
+
-R
+

Run grefer preprocessor. No mechanism is provided for passing +arguments to grefer because most grefer options have +equivalent language elements that can be specified within the document. +

+ + +

gtroff also accepts a -R option, which is not +accessible via groff. This option prevents the loading of the +troffrc and troffrc-end files. +

+
+
-s
+

Run gsoelim preprocessor. +

+
+
-S
+
+ + + + + +

Operate in “safer” mode; see -U below for its opposite. For +security reasons, safer mode is enabled by default. +

+
+
-t
+

Run gtbl preprocessor. +

+
+
-Tdev
+

Direct gtroff to format the input for the output device +dev. groff then calls an output driver to convert +gtroff’s output to a form appropriate for dev. The +following output devices are available. +

+
+
ps
+

For PostScript printers and previewers. +

+
+
pdf
+

For PDF viewers or printers. +

+
+
dvi
+

For TeX DVI format. +

+
+
X75
+

For a 75dpi X11 previewer. +

+
+
X75-12
+

For a 75dpi X11 previewer with a 12-point base font in the +document. +

+
+
X100
+

For a 100dpi X11 previewer. +

+
+
X100-12
+

For a 100dpi X11 previewer with a 12-point base font in the +document. +

+
+
ascii
+
+ + + + +

For typewriter-like devices using the (7-bit) ASCII +(ISO 646) character set. +

+
+
latin1
+
+ + +

For typewriter-like devices that support the Latin-1 +(ISO 8859-1) character set. +

+
+
utf8
+
+ +

For typewriter-like devices that use the Unicode (ISO 10646) +character set with UTF-8 encoding. +

+
+
cp1047
+
+ + + + + + +

For typewriter-like devices that use the EBCDIC encoding IBM +code page 1047. +

+
+
lj4
+

For HP LaserJet4-compatible (or other PCL5-compatible) printers. +

+
+
lbp
+

For Canon CaPSL printers (LBP-4 and LBP-8 series laser +printers). +

+ + + +
+
html
+
xhtml
+

To produce HTML and XHTML output, respectively. +This driver consists of two parts, a preprocessor +(pre-grohtml) and a postprocessor (post-grohtml). +

+
+ + + +

The predefined GNU troff string .T contains the name of +the output device; the read-only register .T is set to 1 if +this option is used (which is always true if groff is used to +call GNU troff). See Built-in Registers. +

+

The postprocessor to be used for a device is specified by the +postpro command in the device description file. (See Device and Font Description Files.) This can be overridden with the +-X option. +

+
+
-U
+
+

Operate in unsafe mode, which enables the open, +opena, pi, pso, and sy requests. These +requests are disabled by default because they allow an untrusted input +document to write to arbitrary file names and run arbitrary commands. +This option also adds the current directory to the macro package search +path; see the -m option above. -U is passed to +gpic and gtroff. +

+
+
-v
+

Write version information for groff and all programs run by it +to the standard output stream; that is, the given command line is +processed in the usual way, passing -v to the formatter and any +pre- or postprocessors invoked. +

+
+
-V
+

Output the pipeline that would be run by groff +(as a wrapper program) to the standard output stream, but do not execute +it. If given more than once, the pipeline is both written to the +standard error stream and run. +

+
+
-wcategory
+

Enable warnings in category. Categories are listed in +Warnings. +

+
+
-Wcategory
+

Inhibit warnings in category. Categories are listed in +Warnings. +

+
+
-X
+

Use gxditview instead of the usual postprocessor to (pre)view +a document on an X11 display. Combining this option with +-Tps uses the font metrics of the PostScript device, whereas +the -TX75 and -TX100 options use the metrics of X11 +fonts. +

+
+
-z
+

Suppress formatted output from gtroff. +

+
+
-Z
+

Disable postprocessing. gtroff output will appear on the +standard output stream (unless suppressed with -z; see +gtroff Output for a description of this format. +

+
+ + + +
+
+
+ +

2.2 Environment

+ + + +

There are also several environment variables (of the operating system, +not within gtroff) that can modify the behavior of groff. +

+
+
GROFF_BIN_PATH
+

This search path, followed by PATH, is used for commands executed +by groff. +

+
+
GROFF_COMMAND_PREFIX
+
+ +

If this is set to X, then groff runs +Xtroff instead of gtroff. This also applies +to tbl, pic, eqn, grn, +chem, refer, and soelim. It does not +apply to grops, grodvi, grotty, +pre-grohtml, post-grohtml, preconv, +grolj4, gropdf, and gxditview. +

+

The default command prefix is determined during the installation +process. If a non-GNU troff system is found, prefix ‘g’ is +used, none otherwise. +

+
+
GROFF_ENCODING
+

The value of this variable is passed to the preconv +preprocessor’s -e option to select the character encoding of +input files. This variable’s existence implies the groff option +-k. If set but empty, groff calls preconv +without an -e option. groff’s -K option +overrides GROFF_ENCODING. See the preconv(7) man page; +type ‘man preconv’ at the command line to view it. +

+
+
GROFF_FONT_PATH
+

A list of directories in which to seek the selected output device’s +directory of device and font description files. GNU troff +will search directories given as arguments to any specified -F +options before these, and a built-in list of directories after them. +See Font Directories and the troff(1) or +gtroff(1) man pages. +

+
+
GROFF_TMAC_PATH
+

A list of directories in which to seek macro files. GNU troff +will search directories given as arguments to any specified -M +options before these, and a built-in list of directories after them. +See Macro Directories and the troff(1) or +gtroff(1) man pages. +

+
+
GROFF_TMPDIR
+
+

The directory in which groff creates temporary files. If this is +not set and TMPDIR is set, temporary files are created in that +directory. Otherwise temporary files are created in a system-dependent +default directory (on Unix and GNU/Linux systems, this is usually +/tmp). grops, grefer, pre-grohtml, and +post-grohtml can create temporary files in this directory. +

+
+
GROFF_TYPESETTER
+

Sets the default output device. If empty or not set, a build-time +default (often ps) is used. The -Tdev option +overrides GROFF_TYPESETTER. +

+
+
SOURCE_DATE_EPOCH
+

A timestamp (expressed as seconds since the Unix epoch) to use as the +output creation timestamp in place of the current time. The time is +converted to human-readable form using localtime(3) when the +formatter starts up and stored in registers usable by documents and +macro packages (see Built-in Registers). +

+
+
TZ
+

The time zone to use when converting the current time (or value of +SOURCE_DATE_EPOCH) to human-readable form; see +tzset(3). +

+
+ +

MS-DOS and MS-Windows ports of groff use semicolons, rather than +colons, to separate the directories in the lists described above. +

+ + +
+
+
+ +

2.3 Macro Directories

+ + + + + +

A macro file must have a name in the form name.tmac or +tmac.name and be placed in a tmac directory to be +found by the -mname command-line option.5 + + + + + + + + + + +Together, these directories constitute the tmac path. Each +directory is searched in the following order until the desired macro +file is found or the list is exhausted. +

+
    +
  • Directories specified with GNU troff’s or groff’s +-M command-line option. + +
  • +Directories listed in the GROFF_TMAC_PATH environment variable. + +
  • + + + + + +The current working directory (only if in unsafe mode using the +-U command-line option). + +
  • + +The user’s home directory, HOME. + +
  • + + + +A platform-dependent directory, a site-local (platform-independent) +directory, and the main tmac directory. The locations +corresponding to your installation are listed in section “Environment” +of gtroff(1). If not otherwise configured, they are as +follows. + +
    +
    /usr/local/lib/groff/site-tmac
    +/usr/local/share/groff/site-tmac
    +/usr/local/share/groff/1.23.0/tmac
    +
    + +

    The foregoing assumes that the version of groff is 1.23.0, and +that the installation prefix was /usr/local. It is possible to +fine-tune these locations during the source configuration process. +

+ + + +
+
+
+ +

2.4 Font Directories

+ + + + + +

groff enforces few restrictions on how font description files are +named. For its family/style mechanism to work (see Font Families), +the names of fonts within a family should start with the family name, +followed by the style. For example, the Times family uses ‘T’ for +the family name and ‘R’, ‘B’, ‘I’, and ‘BI’ to +indicate the styles ‘roman’, ‘bold’, ‘italic’, and ‘bold italic’, +respectively. Thus the final font names are ‘TR’, ‘TB’, +‘TI’, and ‘TBI’. +

+ + +

Font description files are kept in font directories, which +together constitute the font path. The search procedure +always appends the directory devname, where name is +the name of the output device. Assuming TeX DVI output, and +/foo/bar as a font directory, the font description files for +grodvi must be in /foo/bar/devdvi. +Each directory in the font path is searched in the following order until +the desired font description file is found or the list is exhausted. +

+
    +
  • Directories specified with GNU troff’s or groff’s +-f command-line option. All output drivers (and some +preprocessors) support this option as well, because they require +information about the glyphs to be rendered in the document. + +
  • +Directories listed in the GROFF_FONT_PATH environment variable. + +
  • + +A site-local directory and the main font description directory. +The locations corresponding to your installation are listed in section +“Environment” of gtroff(1). If not otherwise configured, +they are as follows. + +
    +
    /usr/local/share/groff/site-font
    +/usr/local/share/groff/1.23.0/font
    +
    + +

    The foregoing assumes that the version of groff is 1.23.0, and +that the installation prefix was /usr/local. It is possible to +fine-tune these locations during the source configuration process. +

+ + + +
+
+
+ +

2.5 Paper Format

+ + + + + + + + +

In groff, the page dimensions for the formatter GNU troff +and for output devices are handled separately. See Page Layout, for +vertical manipulation of the page size, and See Line Layout, for +horizontal changes. + + +The papersize macro package, normally loaded by troffrc at +startup, provides an interface for configuring page dimensions by +convenient names, like ‘letter’ or ‘a4’; see +groff_tmac(5). The default used by the formatter depends on +its build configuration, but is usually one of the foregoing, as +geographically appropriate. +

+

It is up to each macro package to respect the page dimensions configured +in this way. +

+

For each output device, the size of the output medium can be set in its +DESC file. Most output drivers also recognize a command-line +option -p to override the default dimensions and an option +-l to use landscape orientation. See DESC File Format, for +a description of the papersize keyword, which takes an argument +of the same form as -p. The output driver’s man page, such as +grops(1), may also be helpful. +

+

groff uses the command-line option -P to pass options to +postprocessors; for example, use the following for PostScript output on +A4 paper in landscape orientation. +

+
+
groff -Tps -dpaper=a4l -P-pa4 -P-l -ms foo.ms > foo.ps
+
+ + + +
+
+
+ +

2.6 Invocation Examples

+ + + +

roff systems are best known for formatting man pages. Once a +man librarian program has located a man page, it may execute +a groff command much like the following. +

+
+
groff -t -man -Tutf8 /usr/share/man/man1/groff.1
+
+ +

The librarian will also pipe the output through a pager, which might not +interpret the SGR terminal escape sequences groff emits for +boldface, underlining, or italics; see the grotty(1) man page +for a discussion. +

+

To process a roff input file using the preprocessors +gtbl and gpic and the me macro package in the +way to which AT&T troff users were accustomed, one would type (or +script) a pipeline. +

+
+
gpic foo.me | gtbl | gtroff -me -Tutf8 | grotty
+
+ +

Using groff, this pipe can be shortened to an equivalent +command. +

+
+
groff -p -t -me -T utf8 foo.me
+
+ +

An even easier way to do this is to use grog to guess the +preprocessor and macro options and execute the result by using the +command substitution feature of the shell. +

+
+
$(grog -Tutf8 foo.me)
+
+ +

Each command-line option to a postprocessor must be specified with any +required leading dashes ‘-’ +because groff passes the arguments as-is to the postprocessor; +this permits arbitrary arguments to be transmitted. For example, to +pass a title to the gxditview postprocessor, +the shell commands +

+
+
groff -X -P -title -P 'trial run' mydoc.t
+
+ +

and +

+
+
groff -X -Z mydoc.t | gxditview -title 'trial run' -
+
+ +

are equivalent. +

+ + + +
+
+
+
+ +

3 Tutorial for Macro Users

+ + + + + +

Most users of the roff language employ a macro package to format +their documents. Successful macro packages ease the composition +process; their users need not have mastered the full formatting +language, nor understand features like diversions, traps, and +environments. This chapter aims to familiarize you with basic concepts +and mechanisms common to many macro packages (like “displays”). If +you prefer a meticulous and comprehensive presentation, try GNU troff Reference instead. +

+ + + + +
+
+ +

3.1 Basics

+ + + +

Let us first survey some basic concepts necessary to use a macro package +fruitfully.6 +References are made throughout to more detailed information. +

+

GNU troff reads an input file prepared by the user and outputs a +formatted document suitable for publication or framing. The input +consists of text, or words to be printed, and embedded commands +(requests and escape sequences), which tell GNU +troff how to format the output. See Formatter Instructions. +

+

The word argument is used in this chapter to mean a word or +number that appears on the same line as a request, and which modifies +the meaning of that request. For example, the request +

+
+
.sp
+
+ +

spaces one line, but +

+
+
.sp 4
+
+ +

spaces four lines. The number 4 is an argument to the sp +request, which says to space four lines instead of one. Arguments are +separated from the request and from each other by spaces (not +tabs). See Invoking Requests. +

+

The primary function of GNU troff is to collect words from input +lines, fill output lines with those words, adjust the line to the +right-hand margin by widening spaces, and output the result. For +example, the input: +

+
+
Now is the time
+for all good men
+to come to the aid
+of their party.
+Four score and seven
+years ago, etc.
+
+ +

is read, packed onto output lines, and justified to produce: +

+
+
  ⇒ Now is the time for all good men to come to the aid of
+  ⇒ their party.  Four score and seven years ago, etc.
+
+ +

Sometimes a new output line should be started even though the current +line is not yet full—for example, at the end of a paragraph. To do +this it is possible to force a break, starting a new output +line. Some requests cause a break automatically, as do (normally) blank +input lines and input lines beginning with a space or tab. +

+

Not all input lines are text lines—words to be formatted. +Some are control lines that tell a macro package (or GNU +troff directly) how to format the text. Control lines start with +a dot (‘.’) or an apostrophe (‘'’) as the first character, and +can be followed by a macro call. +

+

The formatter also does more complex things, such as automatically +numbering pages, skipping over page boundaries, putting footnotes in the +correct place, and so forth. +

+

Here are a few hints for preparing text for input to GNU troff. +

+
    +
  • First, keep the input lines short. Short input lines are easier to +edit, and GNU troff packs words onto longer lines anyhow. + +
  • In keeping with this, it is helpful to begin a new line after every +comma or phrase, since common corrections are to add or delete sentences +or phrases. + +
  • End each sentence with two spaces—or better, start each sentence on a +new line. GNU troff recognizes characters that usually end a +sentence, and inserts inter-sentence space accordingly. + +
  • Do not hyphenate words at the end of lines—GNU troff is smart +enough to hyphenate words as needed, but is not smart enough to take +hyphens out and join a word back together. Also, words such as +“mother-in-law” should not be broken over a line, since then a space +can occur where not wanted, such as “mother- in-law”. +
+ +

We offer further advice in Input Conventions. +

+ + +

GNU troff permits alteration of the distance between lines of +text. This is termed vertical spacing and is expressed in the +same units as the type size—the point. The default is 10-point type +on 12-point spacing. To get double-spaced text you would set +the vertical spacing to 24 points. Some, but not all, macro packages +expose a macro or register to configure the vertical spacing. +

+

A number of requests allow you to change the way the output is arranged +on the page, sometimes called the layout of the output page. +Most macro packages don’t supply macros for performing these (at least +not without performing other actions besides), as they are such basic +operations. The macro packages for writing man pages, man and +mdoc, don’t encourage explicit use of these requests at all. +

+ +

The request ‘.sp N leaves N lines of blank +space. N can be omitted (skipping a single line) or can +be of the form Ni (for N inches) or Nc (for +N centimeters). For example, the input: +

+
+
.sp 1.5i
+My thoughts on the subject
+.sp
+
+ +

leaves one and a half inches of space, followed by the line “My +thoughts on the subject”, followed by a single blank line (more +measurement units are available; see Measurements). +

+

If you seek precision in spacing, be advised when using a macro package +that it might not honor sp requests as you expect; it can use a +formatter feature called no-space mode to prevent excess space +from accumulating. Macro packages typically offer registers to control +spacing between paragraphs, before section headings, and around displays +(discussed below); use these facilities preferentially. +See Manipulating Spacing. +

+ + +

Text lines can be centered by using the ce request. The line +after ce is centered (horizontally) on the page. To center more +than one line, use ‘.ce N (where N is the number +of lines to center), followed by the N lines. To center many +lines without counting them, type: +

+
+
.ce 1000
+lines to center
+.ce 0
+
+ +

The ‘.ce 0 request tells GNU troff to center zero more +lines, in other words, stop centering. +

+ + + + +

GNU troff also offers the rj request for right-aligning +text. It works analogously to ce and is convenient for setting +epigraphs. +

+ + +

The bp request starts a new page; this necessarily implies an +ordinary (line) break. +

+ + +

All of these requests cause a break; that is, they always start a new +line. To start a new line without performing any other action, use +br. If you invoke them with the apostrophe ‘'’, the +no-break control character, the (initial) break they normally +perform is suppressed. ‘'br’ does nothing. +

+ + +
+
+
+ +

3.2 Common Features

+ + + +

GNU troff provides low-level operations for formatting a +document. Many routine operations are undertaken in nearly all +documents that require a series of such primitive operations to be +performed. These common tasks are grouped into macros, which +are then collected into a macro package. +

+

Macro packages come in two varieties: “major” or “full-service” +ones that manage page layout, and “minor” or “auxiliary” ones that +do not, instead fulfilling narrow, specific tasks. Find a list in the +groff_tmac(5) man page. Type ‘man groff_tmac’ at the +command line to view it. +

+

We survey several capabilities of full-service macro package below. +Each package employs its own macros to exercise them. For details, +consult its man page or, for ms, see ms. +

+ + + +
+
+ +

3.2.1 Paragraphs

+ + +

Paragraphs can be separated and indented in various ways. Some start +with a blank line and have a first-line indentation, like most of the +ones in this manual. Block paragraphs omit the indentation. +

+
+
  ⇒ Some  men  look  at constitutions with sanctimonious
+  ⇒ reverence,  and  deem  them  like  the  ark  of  the
+  ⇒ covenant, too sacred to be touched.
+
+ + + + +

We also frequently encounter tagged paragraphs, which begin +with a tag or label at the left margin and indent the remaining text. +

+
+
  ⇒ one  This  is the first paragraph.  Notice how the
+  ⇒      first line of the resulting  paragraph  lines
+  ⇒      up with the other lines in the paragraph.
+
+ +

If the tag is too wide for the indentation, the line is broken. +

+
+
  ⇒ longlabel
+  ⇒      The  label does not align with the subsequent
+  ⇒      lines, but they align with each other.
+
+ +

A variation of the tagged paragraph is the itemized or enumerated +paragraph, which might use punctuation or a digit for a tag, +respectively. These are frequently used to construct lists. +

+
+
  ⇒ o    This  list  item  starts with a bullet.  When
+  ⇒      producing output for a device using the ASCII
+  ⇒      character set, an 'o' is formatted instead.
+
+ +

Often, use of the same macro without a tag continues such a discussion. +

+
+
  ⇒ -xyz  This option is recognized but ignored.
+  ⇒
+  ⇒       It had a security hole that we don't discuss.
+
+ + +
+
+
+ +

3.2.2 Sections and Chapters

+ +

The simplest kind of section heading is unnumbered, set in a bold or +italic style, and occupies a line by itself. Others possess +automatically numbered multi-level headings and/or different typeface +styles or sizes at different levels. More sophisticated macro packages +supply macros for designating chapters and appendices. +

+ +
+
+
+ +

3.2.3 Headers and Footers

+ +

Headers and footers occupy the top and bottom of +each page, respectively, and contain data like the page number and the +article or chapter title. Their appearance is not affected by the +running text. Some packages allow for different titles on even- and +odd-numbered pages (for printed, bound material). +

+

Headers and footers are together called titles, and comprise +three parts: left-aligned, centered, and right-aligned. A ‘%’ +character appearing anywhere in a title is automatically replaced by the +page number. See Page Layout. +

+ +
+
+
+ +

3.2.4 Page Layout

+ +

Most macro packages let the user specify the size of the page margins. +The top and bottom margins are typically handled differently than the +left and right margins; the latter two are derived from the +page offset, indentation, and line length. +See Line Layout. Commonly, packages support registers to tune these +values. +

+ +
+
+
+ +

3.2.5 Displays and Keeps

+ + +

Displays are sections of text set off from the surrounding +material (typically paragraphs), often differing in indentation, and/or +spacing. Tables, block quotations, and figures are displayed. +Equations and code examples, when not much shorter than an output line, +often are. Lists may or may not be. Packages for setting man pages +support example displays but not keeps. +

+ +

A keep is a group of output lines, often a display, that is +formatted on a single page if possible; it causes a page break to happen +early so as to not interrupt the kept material. +

+ + +

Floating keeps can move, or “float”, relative to the text +around them in the input. They are useful for displays that are +captioned and referred to by name, as with “See figure 3”. +Depending on the package, a floating keep appears at the bottom of the +current page if it fits, and at the top of the next otherwise. +Alternatively, floating keeps might be deferred to the end of a section. +Using a floating keep can avoid the large vertical spaces that may +precede a tall keep of the ordinary sort when it won’t fit on the page. +

+ +
+
+
+ +

3.2.6 Footnotes and Endnotes

+ + + +

Footnotes and endnotes are forms of delayed +formatting. They are recorded at their points of relevance in +the input, but not formatted there. Instead, a mark cues the +reader to check the “foot”, or bottom, of the current page, or in the +case of endnotes, an annotation list later in the document. Macro +packages that support these features also supply a means of +automatically numbering either type of annotation. +

+ +
+
+
+ +

3.2.7 Table of Contents

+ + + +

A package may handle a table of contents by directing section +heading macros to save section heading text and the page number where it +occurs for use in a later entry for a table of contents. It +writes the collected entries at the end of the document, once all are +known, upon request. A row of dots (a leader) bridges the +text on the left with its location on the right. Other collections +might work in this manner, providing lists of figures or tables. +

+

A table of contents is often found at the end of a GNU troff +document because the formatter processes the document in a single pass. +The gropdf output driver supports a PDF feature that relocates +pages at the time the document is rendered; see the gropdf(1) +man page. Type ‘man gropdf’ at the command line to view it. +

+ +
+
+
+ +

3.2.8 Indexing

+ + + +

An index is similar to a table of contents, in that entry labels and +locations must be collected, but poses a greater challenge because it +needs to be sorted before it is output. Here, processing the document +in multiple passes is inescapable, and tools like the makeindex +program are necessary. +

+ +
+
+
+ +

3.2.9 Document Formats

+ + +

Some macro packages supply stock configurations of certain documents, +like business letters and memoranda. These often also have provision +for a cover sheet, which may be rigid in its format. With +these features, it is even more important to use the package’s macros in +preference to the formatter requests presented earlier, where possible. +

+ +
+
+
+ +

3.2.10 Columnation

+ +

Macro packages apart from man and mdoc for man page +formatting offer a facility for setting multiple columns on the page. +

+ +
+
+
+ +

3.2.11 Font and Size Changes

+ +

The formatter’s requests and escape sequences for setting the typeface +and size are not always intuitive, so all macro packages provide macros +to make these operations simpler. They also make it more convenient to +change typefaces in the middle of a word and can handle italic +corrections automatically. See Italic Corrections. +

+ +
+
+
+ +

3.2.12 Predefined Text

+ +

Most macro packages supply predefined strings to set prepared text like +the date, or to perform operations like super- and subscripting. +

+ +
+
+
+ +

3.2.13 Preprocessor Support

+ +

All macro packages provide support for various preprocessors and may +extend their functionality by defining macros to set their contents in +displays. Examples include TS and TE for gtbl, +EQ and EN for geqn, and PS and PE +for gpic. +

+ +
+
+
+ +

3.2.14 Configuration and Customization

+ +

Packages provide means of customizing many of the details of how the +package behaves. These range from setting the default type size to +changing the appearance of section headers. +

+ + + + +
+
+
+
+
+ +

4 Macro Packages

+ + + + +

This chapter surveys the “major” macro packages that come with +groff. One, ms, is presented in detail. +

+ + + +

Major macro packages are also sometimes described as full-service +due to the breadth of features they provide and because more than one +cannot be used by the same document; for example +

+
+
groff -m man foo.man -m ms bar.doc
+
+ +

doesn’t work. Option arguments are processed before non-option +arguments; the above (failing) sample is thus reordered to +

+
+
groff -m man -m ms foo.man bar.doc
+
+ + + + + + + +

Many auxiliary, or “minor”, macro packages are also available. They +may in general be used with any full-service macro package and handle a +variety of tasks from character encoding selection, to language +localization, to inlining of raster images. See the +groff_tmac(5) man page for a list. Type ‘man +groff_tmac’ at the command line to view it. +

+ + + + +
+
+ +

4.1 man

+ + + + + +

The man macro package is the most widely used and probably the +most important ever developed for troff. It is easy to use, and +a vast majority of manual pages (“man pages”) are written in it. +

+

groff’s implementation is documented in the +groff_man(7) man page. Type ‘man groff_man’ at the +command line to view it. +

+ + + +
+
+ +

4.1.1 Optional man extensions

+ + +

Use the file man.local for local extensions to the man +macros or for style changes. +

+ +
+

Custom headers and footers

+ + +

In groff versions 1.18.2 and later, you can specify custom +headers and footers by redefining the following macros in +man.local. +

+
+
Macro: .PT
+
+

Control the content of the headers. Normally, the header prints the +command name and section number on either side, and the optional fifth +argument to TH in the center. +

+ +
+
Macro: .BT
+
+

Control the content of the footers. Normally, the footer prints the +page number and the third and fourth arguments to TH. +

+

Use the FT register to specify the footer position. The default +is −0.5i. +

+ +
+
+

Ultrix-specific man macros

+ + + + +

The groff source distribution includes a file named +man.ultrix, containing macros compatible with the Ultrix variant +of man. Copy this file into man.local (or use the +mso request to load it) to enable the following macros. +

+
+
Macro: .CT key
+
+

Print ‘<CTRL/key>’. +

+ +
+
Macro: .CW
+
+

Print subsequent text using a “constant-width” (monospaced) typeface +(Courier roman). +

+ +
+
Macro: .Ds
+
+

Begin a non-filled display. +

+ +
+
Macro: .De
+
+

End a non-filled display started with Ds. +

+ +
+
Macro: .EX [indent]
+
+

Begin a non-filled display using a monospaced typeface (Courier roman). +Use the optional indent argument to indent the display. +

+ +
+
Macro: .EE
+
+

End a non-filled display started with EX. +

+ +
+
Macro: .G [text]
+
+

Set text in Helvetica. If no text is present on the line where +the macro is called, then the text of the next line appears in +Helvetica. +

+ +
+
Macro: .GL [text]
+
+

Set text in Helvetica oblique. If no text is present on the line +where the macro is called, then the text of the next line appears in +Helvetica Oblique. +

+ +
+
Macro: .HB [text]
+
+

Set text in Helvetica bold. If no text is present on the line +where the macro is called, then all text up to the next HB +appears in Helvetica bold. +

+ +
+
Macro: .TB [text]
+
+

Identical to HB. +

+ +
+
Macro: .MS title sect [punct]
+
+

Set a man page reference in Ultrix format. The title is in +Courier instead of italic. Optional punctuation follows the section +number without an intervening space. +

+ +
+
Macro: .NT [C] [title]
+
+

Begin a note. Print the optional title, or the word “Note”, +centered on the page. Text following the macro makes up the body of the +note, and is indented on both sides. If the first argument is C, +the body of the note is printed centered (the second argument replaces +the word “Note” if specified). +

+ +
+
Macro: .NE
+
+

End a note begun with NT. +

+ +
+
Macro: .PN path [punct]
+
+

Set the path name in a monospaced typeface (Courier roman), followed by +optional punctuation. +

+ +
+
Macro: .Pn [punct] path [punct]
+
+

If called with two arguments, identical to PN. If called with +three arguments, set the second argument in a monospaced typeface +(Courier roman), bracketed by the first and third arguments in the +current font. +

+ +
+
Macro: .R
+
+

Switch to roman font and turn off any underlining in effect. +

+ +
+
Macro: .RN
+
+

Print the string ‘<RETURN>’. +

+ +
+
Macro: .VS [4]
+
+

Start printing a change bar in the margin if the number 4 is +specified. Otherwise, this macro does nothing. +

+ +
+
Macro: .VE
+
+

End printing the change bar begun by VS. +

+ +
+
+

Simple example

+ +

The following example man.local file alters the SH macro +to add some extra vertical space before printing the heading. Headings +are printed in Helvetica bold. +

+
+
.\" Make the heading fonts Helvetica
+.ds HF HB
+.
+.\" Put more space in front of headings.
+.rn SH SH-orig
+.de SH
+.  if t .sp (u;\\n[PD]*2)
+.  SH-orig \\$*
+..
+
+ + + +
+
+
+
+
+ +

4.2 mdoc

+ + +

groff’s implementation of the BSD doc package for man +pages is documented in the groff_mdoc(7) man page. Type +‘man groff_mdoc’ at the command line to view it. +

+ + +
+
+
+ +

4.3 me

+ + +

groff’s implementation of the BSD me macro package is +documented using itself. A tutorial, meintro.me, and reference, +meref.me, are available in groff’s documentation +directory. A groff_me(7) man page is also available and +identifies the installation path for these documents. Type ‘man +groff_me’ at the command line to view it. +

+

A French translation of the tutorial is available as +meintro_fr.me and installed parallel to the English version. +

+ + +
+
+
+ +

4.4 mm

+ + +

groff’s implementation of the AT&T memorandum macro +package is documented in the groff_mm(7) man page. Type +‘man groff_mm’ at the command line) to view it. +

+

A Swedish localization of mm is also available; see +groff_mmse(7). +

+ + +
+
+
+ +

4.5 mom

+ + +

The main documentation files for the mom macros are in +HTML format. Additional, useful documentation is in +PDF format. See the groff(1) man page, section +“Installation Directories”, for their location. +

+
    +
  • toc.html +Entry point to the full mom manual. + +
  • macrolist.html +Hyperlinked index of macros with brief descriptions, arranged by +category. + +
  • mom-pdf.pdf +PDF features and usage. +
+ +

The mom macros are in active development between groff releases. +The most recent version, along with up-to-date documentation, is +available at http://www.schaffter.ca/mom/mom-05.html. +

+

The groff_mom(7) man page (type ‘man groff_mom’ at +the command line) contains a partial list of available macros, however +their usage is best understood by consulting the HTML +documentation. +

+ + + +
+
+
+ +

4.6 ms

+ + +

The ms (“manuscript”) package is suitable for the preparation +of letters, memoranda, reports, and books. These groff +macros feature cover page and table of contents generation, +automatically numbered headings, several paragraph styles, a variety of +text styling options, footnotes, and multi-column page layouts. +ms supports the tbl, eqn, pic, and +refer preprocessors for inclusion of tables, mathematical +equations, diagrams, and standardized bibliographic citations. This +implementation is mostly compatible with the documented interface and +behavior of AT&T Unix Version 7 ms. Many extensions from +4.2BSD (Berkeley) +and Tenth Edition Research Unix have been recreated. +

+ + + +
+
+ +

4.6.1 Introduction

+ +

The ms macros are the oldest surviving package for roff +systems.7 While the man +package was designed for brief reference documents, the ms macros +are also suitable for longer works intended for printing and possible +publication. +

+ + + +
+
+ +

4.6.1.1 Basic information

+ +

ms documents are plain text files; prepare them with your +preferred text editor. If you’re in a hurry to start, know that +ms needs one of its macros called at the beginning of a document +so that it can initialize. A macro is a formatting instruction to +ms. Put a macro call on a line by itself. Use ‘.PP’ if you +want your paragraph’s first line to be indented, or ‘.LP’ if you +don’t. +

+

After that, start typing normally. It is a good practice to start each +sentence on a new line, or to put two spaces after sentence-ending +punctuation, so that the formatter knows where the sentence boundaries +are. You can separate paragraphs with further paragraphing macros, or +with blank lines, and you can indent with tabs. When you need one of +the features mentioned earlier (see ms), return to this part of the +manual. +

+

Format the document with the groff command. nroff +can be useful for previewing. +

+
+
+
$ editor radical.ms
+$ nroff -ww -z -ms radical.ms # check for errors
+$ nroff -ms radical.ms | less -R
+$ groff -T ps -ms radical.ms > radical.ps
+$ see radical.ps
+
+
+ +

Our radical.ms document might look like this. +

+
+
+
.LP
+Radical novelties are so disturbing that they tend to be
+suppressed or ignored, to the extent that even the
+possibility of their existence in general is more often
+denied than admitted.
+
+→That's what Dijkstra said, anyway.
+
+
+ +

ms exposes many aspects of document layout to user control via +groff’s registers and strings, which store numbers +and text, respectively. Measurements in groff are expressed with +a suffix called a scaling unit. +

+
+
i
+

inches +

+
+
c
+

centimeters +

+
+
p
+

points (1/72 inch) +

+
+
P
+

picas (1/6 inch) +

+
+
v
+

vees; current vertical spacing +

+
+
m
+

ems; width of an “M” in the current font +

+
+
n
+

ens; one-half em +

+
+ +

Set registers with the nr request and strings with the ds +request. Requests are like macro calls; they go on lines by +themselves and start with the control character, a dot (.). +The difference is that they directly instruct the formatter program, +rather than the macro package. We’ll discuss a few as applicable. It +is wise to specify a scaling unit when setting any register that +represents a length, size, or distance. +

+
+
+
.nr PS 10.5p \" Use 10.5-point type.
+.ds FAM P    \" Use Palatino font family.
+
+
+ +

In the foregoing, we see that \" begins a comment. This is an +example of an escape sequence, the other kind of formatting +instruction. Escape sequences can appear anywhere. They begin with the +escape character (\) and are followed by at least one more +character. ms documents +tend to use only a few of groff’s many requests and escape +sequences; see Request Index and Escape Sequence Index or +the groff(7) man page for complete lists. +

+
+
\"
+

Begin comment; ignore remainder of line. +

+
+
\n[reg]
+

Interpolate value of register reg. +

+
+
\*[str]
+

Interpolate contents of string str. +

+
+
\*s
+

abbreviation of \*[s]; the name s must be only one +character +

+
+
\[char]
+

Interpolate glyph of special character named char. +

+
+
\&
+

dummy character +

+
+
\~
+

Insert an unbreakable space that is adjustable like a normal space. +

+
+
\|
+

Move horizontally by one-sixth em (“thin space”). +

+
+ +

Prefix any words that start with a dot ‘.’ or neutral apostrophe +‘'’ with \& if they are at the beginning of an input line +(or might become that way in editing) to prevent them from being +interpreted as macro calls or requests. Suffix ‘.’, ‘?’, and +‘!’ with \& when needed to cancel end-of-sentence detection. +

+
+
+
My exposure was \&.5 to \&.6 Sv of neutrons, said Dr.\&
+Wallace after the criticality incident.
+
+
+ + +
+
+
+
+ +

4.6.2 Document Structure

+ + +

The ms macro package expects a certain amount of structure: +a well-formed document contains at least one paragraphing or heading +macro call. Longer documents have a structure as follows. +

+
+
Document type
+

Calling the RP macro at the beginning of your document puts the +document description (see below) on a cover page. Otherwise, ms +places the information (if any) on the first page, followed immediately +by the body text. Some document types found in other ms +implementations are specific to AT&T or Berkeley, and are not +supported by groff ms. +

+
+
Format and layout
+

By setting registers and strings, you can configure your document’s +typeface, margins, spacing, headers and footers, and footnote +arrangement. See Document Control Settings. +

+
+
Document description
+

A document description consists of any of: a title, one or more authors’ +names and affiliated institutions, an abstract, and a date or other +identifier. See Document Description Macros. +

+
+
Body text
+

The main matter of your document follows its description (if any). +ms supports highly structured text consisting of paragraphs +interspersed with multi-level headings (chapters, sections, subsections, +and so forth) and augmented by lists, footnotes, tables, diagrams, and +similar material. See Body Text. +

+
+
Tables of contents
+

Macros enable the collection of entries for a table of contents (or +index) as the material they discuss appears in the document. You then +call a macro to emit the table of contents at the end of your document. +The table of contents must necessarily follow the rest of the text since +GNU troff is a single-pass formatter; it thus cannot determine +the page number of a division of the text until it has been set and +output. Since ms was designed for the production of hard copy, +the traditional procedure was to manually relocate the pages containing +the table of contents between the cover page and the body text. Today, +page resequencing is more often done in the digital domain. An index +works similarly, but because it typically needs to be sorted after +collection, its preparation requires separate processing. +

+
+ + +
+
+
+ +

4.6.3 Document Control Settings

+ + +

ms exposes many aspects of document layout to user control via +groff requests. To use them, you must understand how to define +registers and strings. +

+
+
Request: .nr reg value
+
+

Set register reg to value. If reg doesn’t exist, GNU +troff creates it. +

+ +
+
Request: .ds name contents
+
+

Set string name to contents. +

+ +

A list of document control registers and strings follows. For any +parameter whose default is unsatisfactory, define its register or string +before calling any ms macro other than RP. +

+ +
+

Margin settings

+ +
+
Register: \n[PO]
+
+

Defines the page offset (i.e., the left margin). +

+

Effective: next page. +

+

Default: Varies by output device and paper format; 1i is used for +typesetters using U.S. letter paper, and zero for terminals. +See Paper Format. +

+ +
+
Register: \n[LL]
+
+

Defines the line length (i.e., the width of the body text). +

+

Effective: next paragraph. +

+

Default: Varies by output device and paper format; 6.5i is used +for typesetters using U.S. letter paper (see Paper Format) and +65n on terminals. +

+ +
+
Register: \n[LT]
+
+

Defines the title line length (i.e., the header and footer width). This +is usually the same as LL, but need not be. +

+

Effective: next paragraph. +

+

Default: Varies by output device and paper format; 6.5i is used +for typesetters using U.S. letter paper (see Paper Format) and +65n on terminals. +

+ +
+
Register: \n[HM]
+
+

Defines the header margin height at the top of the page. +

+

Effective: next page. +

+

Default: 1i. +

+ +
+
Register: \n[FM]
+
+

Defines the footer margin height at the bottom of the page. +

+

Effective: next page. +

+

Default: 1i. +

+ +
+
+

Titles (headers, footers)

+ +
+
String: \*[LH]
+
+

Defines the text displayed in the left header position. +

+

Effective: next header. +

+

Default: empty. +

+ +
+
String: \*[CH]
+
+

Defines the text displayed in the center header position. +

+

Effective: next header. +

+

Default: ‘-\n[%]-’. +

+ +
+
String: \*[RH]
+
+

Defines the text displayed in the right header position. +

+

Effective: next header. +

+

Default: empty. +

+ +
+
String: \*[LF]
+
+

Defines the text displayed in the left footer position. +

+

Effective: next footer. +

+

Default: empty. +

+ +
+
String: \*[CF]
+
+

Defines the text displayed in the center footer position. +

+

Effective: next footer. +

+

Default: empty. +

+ +
+
String: \*[RF]
+
+

Defines the text displayed in the right footer position. +

+

Effective: next footer. +

+

Default: empty. +

+ +
+
+

Text settings

+ +
+
Register: \n[PS]
+
+

Defines the type size of the body text. +

+

Effective: next paragraph. +

+

Default: 10p. +

+ +
+
Register: \n[VS]
+
+

Defines the vertical spacing (type size plus leading). +

+

Effective: next paragraph. +

+

Default: 12p. +

+ +
+
Register: \n[HY]
+
+

Defines the automatic hyphenation mode used with the hy request. +Setting HY to 0 is equivalent to using the nh +request. This is a Tenth Edition Research Unix extension. +

+

Effective: next paragraph. +

+

Default: 6. +

+ +
+
String: \*[FAM]
+
+

Defines the font family used to typeset the document. This is a GNU +extension. +

+

Effective: next paragraph. +

+

Default: defined by the output device; often ‘T’ (see Body Text) +

+ +
+
+

Paragraph settings

+ +
+
Register: \n[PI]
+
+

Defines the indentation amount used by the PP, IP (unless +overridden by an optional argument), XP, and RS macros. +

+

Effective: next paragraph. +

+

Default: 5n. +

+ +
+
Register: \n[PD]
+
+

Defines the space between paragraphs. +

+

Effective: next paragraph. +

+

Default: 0.3v (1v on low-resolution devices). +

+ +
+
Register: \n[QI]
+
+

Defines the indentation amount used on both sides of a paragraph set +with the QP or between the QS and QE macros. +

+

Effective: next paragraph. +

+

Default: 5n. +

+ +
+
Register: \n[PORPHANS]
+
+

Defines the minimum number of initial lines of any paragraph that must +be kept together to avoid isolated lines at the bottom of a page. If a +new paragraph is started close to the bottom of a page, and there is +insufficient space to accommodate PORPHANS lines before an +automatic page break, then a page break is forced before the start of +the paragraph. This is a GNU extension. +

+

Effective: next paragraph. +

+

Default: 1. +

+ +
+
+

Heading settings

+ +
+
Register: \n[PSINCR]
+
+

Defines an increment in type size to be applied to a heading at a +lesser depth than that specified in GROWPS. The value of +PSINCR should be specified in points with the p scaling +unit and may include a fractional component; for example, ‘.nr PSINCR 1.5p sets a type size increment of 1.5p. This is a GNU +extension. +

+

Effective: next heading. +

+

Default: 1p. +

+ +
+
Register: \n[GROWPS]
+
+

Defines the heading depth above which the type size increment set by +PSINCR becomes effective. For each heading depth less than the +value of GROWPS, the type size is increased by PSINCR. +Setting GROWPS to any value less than 2 disables the +incremental heading size feature. This is a GNU extension. +

+

Effective: next heading. +

+

Default: 0. +

+ +
+
Register: \n[HORPHANS]
+
+

Defines the minimum number of lines of an immediately succeeding +paragraph that should be kept together with any heading introduced by +the NH or SH macros. If a heading is placed close to the +bottom of a page, and there is insufficient space to accommodate both +the heading and at least HORPHANS lines of the following +paragraph, before an automatic page break, then the page break is forced +before the heading. This is a GNU extension. +

+

Effective: next paragraph. +

+

Default: 1. +

+ +
+
String: \*[SN-STYLE]
+
+

Defines the style used to print numbered headings. See Headings. This is a GNU extension. +

+

Effective: next heading. +

+

Default: alias of SN-DOT +

+ +
+
+

Footnote settings

+ +
+
Register: \n[FI]
+
+

Defines the footnote indentation. This is a Berkeley extension. +

+

Effective: next footnote. +

+

Default: 2n. +

+ +
+
Register: \n[FF]
+
+

Defines the format of automatically numbered footnotes, +and those for which the FS request is given a marker argument, at +the bottom of a column or page. This is a Berkeley extension. +

+
0
+

Set an automatic number8 as a +superscript (on typesetter devices) or surrounded by square brackets (on +terminals). The footnote paragraph is indented as with PP if +there is an FS argument or an automatic number, and as with +LP otherwise. This is the default. +

+
+
1
+

As 0, but set the marker as regular text and follow an +automatic number with a period. +

+
+
2
+

As 1, but without indentation (like LP). +

+
+
3
+

As 1, but set the footnote paragraph with the marker hanging +(like IP). +

+
+ +

Effective: next footnote. +

+

Default: 0. +

+ +
+
Register: \n[FPS]
+
+

Defines the footnote type size. +

+

Effective: next footnote. +

+

Default: \n[PS] - 2p. +

+ +
+
Register: \n[FVS]
+
+

Defines the footnote vertical spacing. +

+

Effective: next footnote. +

+

Default: \n[FPS] + 2p. +

+ +
+
Register: \n[FPD]
+
+

Defines the footnote paragraph spacing. This is a GNU extension. +

+

Effective: next footnote. +

+

Default: \n[PD] / 2. +

+ +
+
String: \*[FR]
+
+

Defines the ratio of the footnote line length to the current line +length. This is a GNU extension. +

+

Effective: next footnote in single-column arrangements, next page +otherwise. +

+

Default: 11/12. +

+ +
+
+

Display settings

+ +
+
Register: \n[DD]
+
+

Sets the display distance—the vertical spacing before and after a +display, a tbl table, an eqn equation, or a pic +image. This is a Berkeley extension. +

+

Effective: next display boundary. +

+

Default: 0.5v (1v on low-resolution devices). +

+ +
+
Register: \n[DI]
+
+

Sets the default amount by which to indent a display started with +DS and ID without arguments, to ‘.DS I’ without +an indentation argument, and to equations set with ‘.EQ I’. +This is a GNU extension. +

+

Effective: next indented display. +

+

Default: 0.5i. +

+ +
+
+

Other settings

+ +
+
Register: \n[MINGW]
+
+

Defines the default minimum width between columns in a multi-column +document. This is a GNU extension. +

+

Effective: next page. +

+

Default: 2n. +

+ +
+
Register: \n[TC-MARGIN]
+
+

Defines the width of the field in which page numbers are set in a table +of contents entry; the right margin thus moves inboard by this amount. +This is a GNU extension. +

+

Effective: next PX call. +

+

Default: \w'000' +

+ + + +
+
+
+
+ +

4.6.4 Document Description Macros

+ + + +

Only the simplest document lacks a title.9 As its level of sophistication (or +complexity) increases, it tends to acquire a date of revision, +explicitly identified authors, sponsoring institutions for authors, and, +at the rarefied heights, an abstract of its content. Define these +data by calling the macros below in the order shown; DA or +ND can be called to set the document date (or other identifier) +at any time before (a) the abstract, if present, or (b) its information +is required in a header or footer. Use of these macros is optional, +except that TL is mandatory if any of RP, AU, +AI, or AB is called, and AE is mandatory if +AB is called. +

+
+
Macro: .RP [no-repeat-info] [no-renumber]
+
+

Use the “report” (AT&T: “released paper”) format for your +document, creating a separate cover page. The default arrangement is to +place most of the document description (title, author names and +institutions, and abstract, but not the date) at the top of the first +page. If the optional no-repeat-info argument is given, +ms produces a cover page but does not repeat any of its +information subsequently (but see the DA macro below regarding +the date). Normally, RP sets the page number following the cover +page to 1. Specifying the optional no-renumber argument +suppresses this alteration. Optional arguments can occur in any order. +no is recognized as a synonym of no-repeat-info for +AT&T compatibility. +

+ +
+
Macro: .TL
+
+

Specify the document title. ms collects text on input lines +following this call into the title until reaching AU, AB, +or a heading or paragraphing macro call. +

+ +
+
Macro: .AU
+
+

Specify an author’s name. ms collects text on input lines +following this call into the author’s name until reaching AI, +AB, another AU, or a heading or paragraphing macro call. +Call it repeatedly to specify multiple authors. +

+ +
+
Macro: .AI
+
+

Specify the preceding author’s institution. An AU call is +usefully followed by at most one AI call; if there are more, the +last AI call controls. ms collects text on input lines +following this call into the author’s institution until reaching +AU, AB, or a heading or paragraphing macro call. +

+ +
+
Macro: .DA [x …]
+
+

Typeset the current date, or any arguments x, in the center +footer, and, if RP is also called, left-aligned at the end of the +description information on the cover page. +

+ +
+
Macro: .ND [x …]
+
+

Typeset the current date, or any arguments x, if RP is also +called, left-aligned at the end of the document description on the cover +page. This is groff ms’s default. +

+ +
+
Macro: .AB [no]
+
+

Begin the abstract. ms collects text on input lines following +this call into the abstract until reaching an AE call. By +default, ms places the word “ABSTRACT” centered and in italics +above the text of the abstract. The optional argument no +suppresses this heading. +

+ +
+
Macro: .AE
+
+

End the abstract. +

+ +

An example document description, using a cover page, follows. + + +

+
+
+
.RP
+.TL
+The Inevitability of Code Bloat
+in Commercial and Free Software
+.AU
+J.\& Random Luser
+.AI
+University of West Bumblefuzz
+.AB
+This report examines the long-term growth of the code
+bases in two large,
+popular software packages;
+the free Emacs and the commercial Microsoft Word.
+While differences appear in the type or order of
+features added,
+due to the different methodologies used,
+the results are the same in the end.
+.PP
+The free software approach is shown to be superior in
+that while free software can become as bloated as
+commercial offerings,
+free software tends to have fewer serious bugs and the
+added features are more in line with user demand.
+.AE
+
+…the rest of the paper…
+
+
+ + +
+
+
+ +

4.6.5 Body Text

+ + +

A variety of macros, registers, and strings can be used to structure and +style the body of your document. They organize your text into +paragraphs, headings, footnotes, and inclusions of material such as +tables and figures. +

+ + + +
+
+ +

4.6.5.1 Text settings

+ + +

The FAM string, a GNU extension, sets the font family for body +text; the default is ‘T’. The PS and VS registers +set the type size and vertical spacing (distance between text +baselines), respectively. The font family and type size are ignored on +terminal devices. Setting these parameters before the first call of a +heading, paragraphing, or (non-date) document description macro also +applies them to headers, footers, and (for FAM) footnotes. +

+

Which font families are available depends on the output device; as a +convention, T selects a serif family (“Times”), H a +sans-serif family (“Helvetica”), and C a monospaced family +(“Courier”). The man page for the output driver documents its font +repertoire. Consult the groff(1) man page for lists of +available output devices and their drivers. +

+

The hyphenation mode (as used by the hy request) is set from the +HY register. Setting HY to ‘0’ is equivalent to +using the nh request. This is a Tenth Edition Research Unix +extension. +

+ +
+
+
+ +

4.6.5.2 Typographical symbols

+ + +

ms provides a few strings to obtain typographical symbols not +easily entered with the keyboard. These and many others are available +as special character escape sequences—see the groff_char(7) +man page. +

+
+
String: \*[-]
+
+

Interpolate an em dash. +

+ +
+
String: \*[Q]
+
+
String: \*[U]
+
+

Interpolate typographer’s quotation marks where available, and neutral +double quotes otherwise. \*Q is the left quote and \*U +the right. +

+ + +
+
+
+ +

4.6.5.3 Paragraphs

+ + +

Paragraphing macros break, or terminate, any pending output line +so that a new paragraph can begin. Several paragraph types are +available, differing in how indentation applies to them: to left, right, +or both margins; to the first output line of the paragraph, all output +lines, or all but the first. All paragraphing macro calls cause the +insertion of vertical space in the amount stored in the PD +register, except at page or column breaks. Alternatively, a blank input +line breaks the output line and vertically spaces by one vee. +

+
+
Macro: .LP
+
+

Set a paragraph without any (additional) indentation. +

+ +
+
Macro: .PP
+
+

Set a paragraph with a first-line left indentation in the amount stored +in the PI register. +

+ +
+
Macro: .IP [marker [width]]
+
+

Set a paragraph with a left indentation. The optional marker is +not indented and is empty by default. It has several applications; +see Lists. width overrides the indentation amount +stored in the PI register; its default unit is ‘n’. Once +specified, width applies to further IP calls until +specified again or a heading or different paragraphing macro is called. +

+ +
+
Macro: .QP
+
+

Set a paragraph indented from both left and right margins by the amount +stored in the QI register. +

+ +
+
Macro: .QS
+
+
Macro: .QE
+
+

Begin (QS) and end (QE) a region where each paragraph is +indented from both margins by the amount stored in the QI +register. The text between QS and QE can be structured +further by use of other paragraphing macros. +

+ +
+
Macro: .XP
+
+

Set an “exdented” paragraph—one with a left indentation in the +amount stored in the PI register on every line except the +first (also known as a hanging indent). This is a Berkeley extension. +

+ +

The following example illustrates the use of paragraphing macros. +

+
+
+
.NH 2
+Cases used in the 2001 study
+.LP
+Two software releases were considered for this report.
+.PP
+The first is commercial software;
+the second is free.
+.IP \[bu]
+Microsoft Word for Windows,
+starting with version 1.0 through the current version
+(Word 2000).
+.IP \[bu]
+GNU Emacs,
+from its first appearance as a standalone editor through
+the current version (v20).
+See [Bloggs 2002] for details.
+.QP
+Franklin's Law applied to software:
+software expands to outgrow both RAM and disk space over
+time.
+.SH
+Bibliography
+.XP
+Bloggs, Joseph R.,
+.I "Everyone's a Critic" ,
+Underground Press, March 2002.
+A definitive work that answers all questions and
+criticisms about the quality and usability of free
+software.
+
+
+ + +
+
+
+ +

4.6.5.4 Headings

+ + +

Use headings to create a sequential or hierarchical structure for your +document. The ms macros print headings in bold using +the same font family and, by default, type size as the body text. +Headings are available with and without automatic numbering. Text on +input lines following the macro call becomes the heading’s title. Call +a paragraphing macro to end the heading text and start the section’s +content. +

+
+
Macro: .NH [depth]
+
+
Macro: .NH S heading-depth-index
+

Set an automatically numbered heading. +

+

ms produces a numbered heading the form a.b.c…, to +any depth desired, with the numbering of each depth increasing +automatically and being reset to zero when a more significant level is +increased. “1” is the most significant or coarsest division of +the document. Only non-zero values are output. If depth is +omitted, it is taken to be ‘1’. +

+

If you specify depth such that an ascending gap occurs relative to +the previous NH call—that is, you “skip a depth”, as by +‘.NH 1’ and then ‘.NH 3’—groff ms emits a +warning on the standard error stream. +

+

Alternatively, you can give NH a first argument of S, +followed by integers to number the heading depths explicitly. Further +automatic numbering, if used, resumes using the specified indices as +their predecessors. +This feature is a Berkeley extension. +

+ +

An example may be illustrative. +

+
+
+
.NH 1
+Animalia
+.NH 2
+Arthropoda
+.NH 3
+Crustacea
+.NH 2
+Chordata
+.NH S 6 6 6
+Daimonia
+.NH 1
+Plantae
+
+
+ +

The above results in numbering as follows; the vertical space that +normally precedes each heading is omitted. +

+
+
1.  Animalia
+1.1.  Arthropoda
+1.1.1.  Crustacea
+1.2.  Chordata
+6.6.6.  Daimonia
+7.  Plantae
+
+ +
+
String: \*[SN-STYLE]
+
+
String: \*[SN-DOT]
+
+
String: \*[SN-NO-DOT]
+
+
String: \*[SN]
+
+

After NH is called, the assigned number is made available in the +strings SN-DOT (as it appears in a printed heading with default +formatting, followed by a terminating period) and SN-NO-DOT (with +the terminating period omitted). These are GNU extensions. +

+

You can control the style used to print numbered headings by defining an +appropriate alias for the string SN-STYLE. By default, +SN-STYLE is aliased to SN-DOT. If you prefer to omit the +terminating period from numbers appearing in numbered headings, you may +define the alias as follows. +

+
+
.als SN-STYLE SN-NO-DOT
+
+ +

Any such change in numbering style becomes effective from the next use +of NH following redefinition of the alias for SN-STYLE. +The formatted number of the current heading is available in the +SN string (a feature first documented by Berkeley), which +facilitates its inclusion in, for example, table captions, equation +labels, and XS/XA/XE table of contents entries. +

+ +
+
Macro: .SH [depth]
+
+

Set an unnumbered heading. +

+

The optional depth argument is a GNU extension indicating the +heading depth corresponding to the depth argument of NH. +It matches the type size at which the heading is set to that of a +numbered heading at the same depth when the GROWPS and +PSINCR heading size adjustment mechanism is in effect. +

+ +

If the GROWPS register is set to a value greater than the +level argument to NH or SH, the type size of a +heading produced by these macros increases by PSINCR units over +the size specified by PS multiplied by the difference of +GROWPS and level. The value stored in PSINCR is +interpreted in groff basic units; the p scaling unit +should be employed when assigning a value specified in points. For +example, the sequence +

+
+
+
.nr PS 10
+.nr GROWPS 3
+.nr PSINCR 1.5p
+.NH 1
+Carnivora
+.NH 2
+Felinae
+.NH 3
+Felis catus
+.SH 2
+Machairodontinae
+
+
+ +

will cause “1. Carnivora” to be printed in 13-point text, followed by +“1.1. Felinae” in 11.5-point text, while “1.1.1. Felis catus” and +all more deeply nested heading levels will remain in the 10-point text +specified by the PS register. “Machairodontinae” is printed at +11.5 points, since it corresponds to heading level 2. +

+

The HORPHANS register operates in conjunction with the NH +and SH macros to inhibit the printing of isolated headings at the +bottom of a page; it specifies the minimum number of lines of an +immediately subsequent paragraph that must be kept on the same page as +the heading. If insufficient space remains on the current page to +accommodate the heading and this number of lines of paragraph text, a +page break is forced before the heading is printed. Any display macro +call or tbl, pic, or eqn region between the heading +and the subsequent paragraph suppresses this grouping. See Keeps, boxed keeps, and displays and Tables, figures, equations, and references. +

+ +
+
+
+ +

4.6.5.5 Typeface and decoration

+ +

The ms macros provide a variety of ways to style text. +Attend closely to the ordering of arguments labeled pre and +post, which is not intuitive. Support for pre +arguments is a GNU extension.10 +

+
+
Macro: .B [text [post [pre]]]
+
+

Style text in bold, followed by post in the previous +font style without intervening space, and preceded by pre +similarly. Without arguments, ms styles subsequent text in bold +until the next paragraphing, heading, or no-argument typeface macro +call. +

+ +
+
Macro: .R [text [post [pre]]]
+
+

As B, but use the roman style (upright text of normal weight) +instead of bold. Argument recognition is a GNU extension. +

+ +
+
Macro: .I [text [post [pre]]]
+
+

As B, but use an italic or oblique style instead of bold. +

+ +
+
Macro: .BI [text [post [pre]]]
+
+

As B, but use a bold italic or bold oblique style instead of +upright bold. This is a Tenth Edition Research Unix extension. +

+ +
+
Macro: .CW [text [post [pre]]]
+
+

As B, but use a constant-width (monospaced) roman typeface +instead of bold. This is a Tenth Edition Research Unix extension. +

+ +
+
Macro: .BX [text]
+
+

Typeset text and draw a box around it. On terminal devices, +reverse video is used instead. If you want text to contain space, +use unbreakable space or horizontal motion escape sequences (\~, +\SP, \^, \|, \0 or \h). +

+ +
+
Macro: .UL [text [post]]
+
+

Typeset text with an underline. post, if present, is set +after text with no intervening space. +

+ +
+
Macro: .LG
+
+

Set subsequent text in larger type (two points larger than the +current size) until the next type size, paragraphing, or heading macro +call. You can specify this macro multiple times to enlarge the type +size as needed. +

+ +
+
Macro: .SM
+
+

Set subsequent text in smaller type (two points smaller than the current +size) until the next type size, paragraphing, or heading macro call. +You can specify this macro multiple times to reduce the type size as +needed. +

+ +
+
Macro: .NL
+
+

Set subsequent text at the normal type size (the amount in the PS +register). +

+ +

pre and post arguments are typically used to simplify the +attachment of punctuation to styled words. When pre is used, +a hyphenation control escape sequence \% that would ordinarily +start text must start pre instead to have the desired +effect. +

+
+
+
The CS course's students found one C language keyword
+.CW static ) \%(
+most troublesome.
+
+
+ +

The foregoing example produces output as follows. +

+
+
+
The CS course’s students found one C language keyword (static)
+most troublesome.
+
+
+ +

You can use the output line continuation escape sequence \c to +achieve the same result (see Line Continuation). It is also +portable to older ms implementations. +

+
+
+
The CS course's students found one C language keyword
+\%(\c
+.CW \%static )
+most troublesome.
+
+
+ +

groff ms also offers strings to begin and end super- and +subscripting. These are GNU extensions. +

+
+
String: \*[{]
+
+
String: \*[}]
+
+

Begin and end superscripting, respectively. +

+ +
+
String: \*[<]
+
+
String: \*[>]
+
+

Begin and end subscripting, respectively. +

+ +

Rather than calling the CW macro, in groff ms you +might prefer to change the font family to Courier by setting the +FAM string to ‘C’. You can then use all four style macros +above, returning to the default family (Times) with ‘.ds FAM T’. +Because changes to FAM take effect only at the next paragraph, +CW remains useful to “inline” a change to the font family, +similarly to the practice of this document in noting syntactical +elements of ms and groff. +

+ +
+
+
+ +

4.6.5.6 Lists

+ + +

The marker argument to the IP macro can be employed to +present a variety of lists; for instance, you can use a bullet glyph +(\[bu]) for unordered lists, a number (or auto-incrementing +register) for numbered lists, or a word or phrase for glossary-style or +definition lists. If you set the paragraph indentation register +PI before calling IP, you can later reorder the items in +the list without having to ensure that a width argument remains +affixed to the first call. +

+

The following is an example of a bulleted list. + + +

+
+
+
.nr PI 2n
+A bulleted list:
+.IP \[bu]
+lawyers
+.IP \[bu]
+guns
+.IP \[bu]
+money
+
+
+ +
+
A bulleted list:
+
+• lawyers
+
+• guns
+
+• money
+
+ +

The following is an example of a numbered list. + + +

+
+
+
.nr step 0 1
+.nr PI 3n
+A numbered list:
+.IP \n+[step]
+lawyers
+.IP \n+[step]
+guns
+.IP \n+[step]
+money
+
+
+ +
+
A numbered list:
+
+1. lawyers
+
+2. guns
+
+3. money
+
+ +

Here we have employed the nr request to create a register of our +own, ‘step’. We initialized it to zero and assigned it an +auto-increment of 1. Each time we use the escape sequence +‘\n+[PI]’ (note the plus sign), the formatter applies the increment +just before interpolating the register’s value. Preparing the PI +register as well enables us to rearrange the list without the tedium of +updating macro calls. +

+

The next example illustrates a glossary-style list. + + +

+
+
+
A glossary-style list:
+.IP lawyers 0.4i
+Two or more attorneys.
+.IP guns
+Firearms,
+preferably large-caliber.
+.IP money
+Gotta pay for those
+lawyers and guns!
+
+
+ +
+
A glossary-style list:
+
+lawyers
+      Two or more attorneys.
+
+guns  Firearms, preferably large-caliber.
+
+money
+      Gotta pay for those lawyers and guns!
+
+ +

In the previous example, observe how the IP macro places the +definition on the same line as the term if it has enough space. If this +is not what you want, there are a few workarounds we will illustrate by +modifying the example. First, you can use a br request to force +a break after printing the term or label. +

+
+
+
.IP guns
+.br
+Firearms,
+
+
+ +

Second, you could apply the \p escape sequence to force a break. +The space following the escape sequence is important; if you omit it, +groff prints the first word of the paragraph text on the same +line as the term or label (if it fits) then breaks the line. +

+
+
+
.IP guns
+\p Firearms,
+
+
+ +

Finally, you may append a horizontal motion to the marker with the +\h escape sequence; using the same amount as the indentation will +ensure that the marker is too wide for groff to treat it as +“fitting” on the same line as the paragraph text. +

+
+
+
.IP guns\h'0.4i'
+Firearms,
+
+
+ +

In each case, the result is the same. +

+
+
A glossary-style list:
+
+lawyers
+      Two or more attorneys.
+
+guns
+      Firearms, preferably large-caliber.
+
+money
+      Gotta pay for those lawyers and guns!
+
+ + +
+
+
+ +

4.6.5.7 Indented regions

+ +

You may need to indent a region of text while otherwise formatting it +normally. Indented regions can be nested; you can change \n[PI] +before each call to vary the amount of inset. +

+
+
Macro: .RS
+
+

Begin a region where headings, paragraphs, and displays are indented +(further) by the amount stored in the PI register. +

+ +
+
Macro: .RE
+
+

End the (next) most recent indented region. +

+ +

This feature enables you to easily line up text under hanging and +indented paragraphs. + + +For example, you may wish to structure lists hierarchically. +

+
+
+
.IP \[bu] 2
+Lawyers:
+.RS
+.IP \[bu]
+Dewey,
+.IP \[bu]
+Cheatham,
+and
+.IP \[bu]
+and Howe.
+.RE
+.IP \[bu]
+Guns
+
+
+ +
+
• Lawyers:
+
+  •  Dewey,
+
+  •  Cheatham, and
+
+  •  Howe.
+
+• Guns
+
+ + +
+
+
+ +

4.6.5.8 Keeps, boxed keeps, and displays

+ + + + +

On occasion, you may want to keep several lines of text, or a +region of a document, together on a single page, preventing an automatic +page break within certain boundaries. This can cause a page break to +occur earlier than it normally would. For example, you may want to keep +two paragraphs together, or a paragraph that refers to a table, list, or +figure adjacent to the item it discusses. ms provides the +KS and KE macros for this purpose. +

+

You can alternatively specify a floating keep: if a keep cannot +fit on the current page, ms holds its contents and +allows material following the keep (in the source document) to fill the +remainder of the current page. When the page breaks, whether by +reaching the end or bp request, ms puts the floating keep +at the beginning of the next page. This is useful for placing large +graphics or tables that do not need to appear exactly where they occur +in the source document. +

+
+
Macro: .KS
+
+
Macro: .KF
+
+
Macro: .KE
+
+

KS begins a keep, KF a floating keep, and KE ends a +keep of either kind. +

+ +

As an alternative to the keep mechanism, the ne request forces a +page break if there is not at least the amount of vertical space +specified in its argument remaining on the page (see Page Control). +One application of ne is to reserve space on the page for a +figure or illustration to be included later. +

+ +

A boxed keep has a frame drawn around it. +

+
+
Macro: .B1
+
+
Macro: .B2
+
+

B1 begins a keep with a box drawn around it. B2 ends a +boxed keep. +

+ +

Boxed keep macros cause breaks; if you need to box a word or phrase +within a line, see the BX macro in Typeface and decoration. +Box lines are drawn as close as possible to the text they enclose so +that they are usable within paragraphs. If you wish to box one or more +paragraphs, you may improve the appearance by calling B1 after +the first paragraphing macro, and by adding a small amount of vertical +space before calling B2. +

+
+
+
.LP
+.B1
+.I Warning:
+Happy Fun Ball may suddenly accelerate to dangerous
+speeds.
+.sp \n[PD]/2 \" space by half the inter-paragraph distance
+.B2
+
+
+ +

If you want a boxed keep to float, you will need to enclose the +B1 and B2 calls within a pair of KF and KE +calls. +

+ +

Displays turn off filling; lines of verse or program code are +shown with their lines broken as in the source document without +requiring br requests between lines. Displays can be kept on a +single page or allowed to break across pages. The DS macro +begins a kept display of the layout specified in its first argument; +non-kept displays are begun with dedicated macros corresponding to their +layout. +

+
+
Macro: .DS L
+
+
Macro: .LD
+
+

Begin (DS: kept) left-aligned display. +

+ +
+
Macro: .DS [I [indent]]
+
+
Macro: .ID [indent]
+
+

Begin (DS: kept) display indented by indent if specified, +and by the amount of the DI register otherwise. +

+ +
+
Macro: .DS B
+
+
Macro: .BD
+
+

Begin a (DS: kept) a block display: the entire display is +left-aligned, but indented such that the longest line in the display +is centered on the page. +

+ +
+
Macro: .DS C
+
+
Macro: .CD
+
+

Begin a (DS: kept) centered display: each line in the display +is centered. +

+ +
+
Macro: .DS R
+
+
Macro: .RD
+
+

Begin a (DS: kept) right-aligned display. This is a GNU +extension. +

+ +
+
Macro: .DE
+
+

End any display. +

+ +

The distance stored in the DD register is inserted before and +after each pair of display macros; this is a Berkeley extension. In +groff ms, this distance replaces any adjacent +inter-paragraph distance or subsequent spacing prior to a section +heading. The DI register is a GNU extension; its value is an +indentation applied to displays created with ‘.DS’ and ‘.ID’ +without arguments, to ‘.DS I’ without an indentation argument, and +to indented equations set with ‘.EQ’. Changes to either register +take effect at the next display boundary. +

+ +
+
+
+ +

4.6.5.9 Tables, figures, equations, and references

+ + + + + + + + + +

The ms package is often used with the tbl, pic, +eqn, and refer preprocessors. + + + + +Mark text meant for preprocessors by enclosing it in pairs of tokens +as follows, with nothing between the dot and the macro name. The +preprocessors match these tokens only at the start of an input line. +

+
+
Macro: .TS [H]
+
+
Macro: .TE
+
+

Demarcate a table to be processed by the tbl preprocessor. The +optional argument H to TS instructs ms to +repeat table rows (often column headings) at the top of each new page +the table spans, if applicable; calling the TH macro marks the +end of such rows. The GNU tbl(1) man page provides a +comprehensive reference to the preprocessor and offers examples of its +use. +

+ +
+
Macro: .PS
+
+
Macro: .PE
+
+
Macro: .PF
+
+

PS begins a picture to be processed by the gpic +preprocessor; either of PE or PF ends it, the latter with +“flyback” to the vertical position at its top. You can create +pic input manually or with a program such as xfig. +

+ +
+
Macro: .EQ [align [label]]
+
+
Macro: .EN
+
+

Demarcate an equation to be processed by the eqn preprocessor. +The equation is centered by default; align can be ‘C’, +‘L’, or ‘I’ to (explicitly) center, left-align, or indent it +by the amount stored in the DI register, respectively. If +specified, label is set right-aligned. +

+ +
+
Macro: .[
+
+
Macro: .]
+
+

Demarcate a bibliographic citation to be processed by the refer +preprocessor. The GNU refer(1) man page provides a +comprehensive reference to the preprocessor and the format of its +bibliographic database. Type ‘man refer’ at the command line to +view it. +

+ +

When refer emits collected references (as might be done on a +“Works Cited” page), it interpolates the REFERENCES string as +an unnumbered heading (SH). +

+ + +

The following is an example of how to set up a table that may print +across two or more pages. +

+
+
+
.TS H
+allbox;
+Cb | Cb .
+Part→Description
+_
+.TH
+.T&
+GH-1978→Fribulating gonkulator
+…the rest of the table follows…
+.TE
+
+
+ +

Attempting to place a multi-page table inside a keep can lead to +unpleasant results, particularly if the tbl allbox option +is used. +

+ +

Mathematics can be typeset using the language of the eqn +preprocessor. +

+
+
+
.EQ C (\*[SN-NO-DOT]a)
+p ~ = ~ q sqrt { ( 1 + ~ ( x / q sup 2 ) }
+.EN
+
+
+ +

This input formats a labelled equation. We used the SN-NO-DOT +string to base the equation label on the current heading number, giving +us more flexibility to reorganize the document. +

+

Use groff options to run preprocessors on the input: +-e for geqn, -p for gpic, +-R for grefer, and -t for gtbl. +

+ +
+
+
+ +

4.6.5.10 Footnotes

+ + + + + +

A footnote is typically anchored to a place in the text with a +marker, which is a small integer, a symbol such as a dagger, or +arbitrary user-specified text. +

+
+
String: \*[*]
+
+

Place an automatic number, an automatically generated numeric +footnote marker, in the text. Each time this string is interpolated, +the number it produces increments by one. Automatic numbers start at 1. +This is a Berkeley extension. +

+ +

Enclose the footnote text in FS and FE macro calls to set +it at the nearest available “foot”, or bottom, of a text column or +page. +

+
+
Macro: .FS [marker]
+
+
Macro: .FE
+
+

Begin (FS) and end (FE) a footnote. FS calls +FS-MARK with any supplied marker argument, which is then +also placed at the beginning of the footnote text. If marker is +omitted, the next pending automatic footnote number enqueued by +interpolation of the * string is used, and if none exists, +nothing is prefixed. +

+ +

You may not desire automatically numbered footnotes in spite of their +convenience. You can indicate a footnote with a symbol or other text by +specifying its marker at the appropriate place (for example, by using +\[dg] for the dagger glyph) and as an argument to the +FS macro. Such manual marks should be repeated as arguments to +FS or as part of the footnote text to disambiguate their +correspondence. You may wish to use \*{ and \*} to +superscript the marker at the anchor point, in the footnote text, or +both. +

+

groff ms provides a hook macro, FS-MARK, for +user-determined operations to be performed when the FS macro is +called. It is passed the same arguments as FS itself. An +application of FS-MARK is anchor placement for a hyperlink +reference, so that a footnote can link back to its referential +context.11 By default, this macro has an empty definition. +FS-MARK is a GNU extension. +

+ + + + +

Footnotes can be safely used within keeps and displays, but you should +avoid using automatically numbered footnotes within floating keeps. You +can place a second \** interpolation between a \** and its +corresponding FS call as long as each FS call occurs +after the corresponding \** and occurrences of FS +are in the same order as corresponding occurrences of \**. +

+

Footnote text is formatted as paragraphs are, using analogous +parameters. The registers FI, FPD, FPS, and +FVS correspond to PI, PD, PS, and CS, +respectively; FPD, FPS, and FVS are GNU extensions. +

+

The FF register controls the formatting of automatically numbered +footnote paragraphs and those for which FS is given a marker +argument. See Document Control Settings. +

+

The default footnote line length is 11/12ths of the normal line length +for compatibility with the expectations of historical ms +documents; you may wish to set the FR string to ‘1’ to align +with contemporary typesetting practices. In the +past,12 an FL register +was used for the line length in footnotes; however, setting this +register at document initialization time had no effect on the footnote +line length in multi-column arrangements.13 +

+

FR should be used in preference to the old FL register in +contemporary documents. The footnote line length is effectively +computed as ‘column-width * \*[FR]’. If an absolute +footnote line length is required, recall that arithmetic expressions in +roff input are evaluated strictly from left to right, with no +operator precedence (parentheses are honored). +

+
+
.ds FR 0+3i \" Set footnote line length to 3 inches.
+
+ + +
+
+
+ +

4.6.5.11 Language and localization

+ + + + + +

groff ms provides several strings that you can customize +for your own purposes, or redefine to adapt the macro package to +languages other than English. It is already localized for +Czech, German, French, Italian, and Swedish. Load the desired +localization macro package after ms; see the +groff_tmac(5) man page. +

+
+
+
$ groff -ms -mfr bienvenue.ms
+
+
+ +

The following strings are available. +

+
+
String: \*[REFERENCES]
+
+

Contains the string printed at the beginning of a references +(bibliography) page produced with GNU refer(1). The default +is ‘References’. +

+ +
+
String: \*[ABSTRACT]
+
+

Contains the string printed at the beginning of the abstract. The +default is ‘\f[I]ABSTRACT\f[]’; it includes font selection escape +sequences to set the word in italics. +

+ +
+
String: \*[TOC]
+
+

Contains the string printed at the beginning of the table of contents. +The default is ‘Table of Contents’. +

+ +
+
String: \*[MONTH1]
+
+
String: \*[MONTH2]
+
+
String: \*[MONTH3]
+
+
String: \*[MONTH4]
+
+
String: \*[MONTH5]
+
+
String: \*[MONTH6]
+
+
String: \*[MONTH7]
+
+
String: \*[MONTH8]
+
+
String: \*[MONTH9]
+
+
String: \*[MONTH10]
+
+
String: \*[MONTH11]
+
+
String: \*[MONTH12]
+
+

Contain the full names of the calendar months. The defaults are in +English: ‘January’, ‘February’, and so on. +

+ + +
+
+
+
+ +

4.6.6 Page layout

+ + + +

ms’s default page layout arranges text in a single column with +the page number between hyphens centered in a header on each page except +the first, and produces no footers. You can customize this arrangement. +

+ + + +
+
+ +

4.6.6.1 Headers and footers

+ + + + + +

There are multiple ways to produce headers and footers. One is to +define the strings LH, CH, and RH to set the left, +center, and right headers, respectively; and LF, CF, and +RF to set the left, center, and right footers. This approach +suffices for documents that do not distinguish odd- and even-numbered +pages. +

+

Another method is to call macros that set headers or footers for odd- or +even-numbered pages. Each such macro takes a delimited argument +separating the left, center, and right header or footer texts from each +other. You can replace the neutral apostrophes (') shown below +with any character not appearing in the header or footer text. These +macros are Berkeley extensions. +

+
+
Macro: .OH 'left'center'right'
+
+
Macro: .EH 'left'center'right'
+
+
Macro: .OF 'left'center'right'
+
+
Macro: .EF 'left'center'right'
+
+

The OH and EH macros define headers for odd- (recto) +and even-numbered (verso) pages, respectively; the OF and +EF macros define footers for them. +

+ +

With either method, a percent sign % in header or footer text is +replaced by the current page number. By default, ms places no +header on a page numbered “1” (regardless of its number format). +

+
+
Macro: .P1
+
+

Typeset the header even on page 1. To be effective, this macro +must be called before the header trap is sprung on any page numbered +“1”; in practice, unless your page numbering is unusual, this means +that you should call it early, before TL or any heading or +paragraphing macro. This is a Berkeley extension. +

+ +

For even greater flexibility, ms is designed to permit the +redefinition of the macros that are called when the groff traps +that ordinarily cause the headers and footers to be output are sprung. +PT (“page trap”) is called by ms when the header is to +be written, and BT (“bottom trap”) when the footer is to be. +The groff page location trap that ms sets up to format the +header also calls the (normally undefined) HD macro after +PT; you can define HD if you need additional processing +after setting the header (for example, to draw a line below it). +The HD hook is a Berkeley extension. Any such macros you +(re)define must implement any desired specialization for odd-, even-, or +first numbered pages. +

+ +
+
+
+ +

4.6.6.2 Tab stops

+ +

Use the ta request to define tab stops as needed. See Tabs and Fields. +

+
+
Macro: .TA
+
+

Reset the tab stops to the ms default (every 5 ens). +Redefine this macro to create a different set of default tab stops. +

+ + +
+
+
+ +

4.6.6.3 Margins

+ + +

Control margins using the registers summarized in “Margin settings” in +Document Control Settings above. There is no setting for the +right margin; the combination of page offset \n[PO] and line +length \n[LL] determines it. +

+ +
+
+
+ +

4.6.6.4 Multiple columns

+ + + +

ms can set text in as many columns as reasonably fit on the page. +The following macros force a page break if a multi-column layout is +active when they are called. The MINGW register stores the +default minimum gutter width; it is a GNU extension. When multiple +columns are in use, keeps and the HORPHANS and PORPHANS +registers work with respect to column breaks instead of page breaks. +

+
+
Macro: .1C
+
+

Arrange page text in a single column (the default). +

+ +
+
Macro: .2C
+
+

Arrange page text in two columns. +

+ +
+
Macro: .MC [column-width [gutter-width]]
+
+

Arrange page text in multiple columns. If you specify no arguments, it +is equivalent to the 2C macro. Otherwise, column-width is +the width of each column and gutter-width is the minimum distance +between columns. +

+ + +
+
+
+ +

4.6.6.5 Creating a table of contents

+ + + +

Because roff formatters process their input in a single pass, +material on page 50, for example, cannot influence what appears on +page 1—this poses a challenge for a table of contents at its +traditional location in front matter, if you wish to avoid manually +maintaining it. ms enables the collection of material to be +presented in the table of contents as it appears, saving its page number +along with it, and then emitting the collected contents on demand toward +the end of the document. The table of contents can then be resequenced +to its desired location by physically rearranging the pages of a printed +document, or as part of post-processing—with a sed(1) +script to reorder the pages in troff’s output, with +pdfjam(1), or with gropdf(1)’s +‘.pdfswitchtopage’ feature, for example. +

+

Define an entry to appear in the table of contents by bracketing its +text between calls to the XS and XE macros. A typical +application is to call them immediately after NH or SH and +repeat the heading text within them. The XA macro, used within +‘.XS’/‘.XE’ pairs, supplements an entry—for instance, when +it requires multiple output lines, whether because a heading is too long +to fit or because style dictates that page numbers not be repeated. You +may wish to indent the text thus wrapped to correspond to its heading +depth; this can be done in the entry text by prefixing it with tabs or +horizontal motion escape sequences, or by providing a second argument to +the XA macro. XS and XA automatically associate +the page number where they are called with the text following them, but +they accept arguments to override this behavior. At the end of the +document, call TC or PX to emit the table of contents; +TC resets the page number to ‘i’ (Roman numeral one), and +then calls PX. All of these macros are Berkeley extensions. +

+
+
Macro: .XS [page-number]
+
+
Macro: .XA [page-number [indentation]]
+
+
Macro: .XE
+
+

Begin, supplement, and end a table of contents entry. Each entry is +associated with page-number (otherwise the current page number); a +page-number of ‘no’ prevents a leader and page number from +being emitted for that entry. Use of XA within +XS/XE is optional; it can be repeated. If +indentation is present, a supplemental entry is indented by that +amount; ens are assumed if no unit is indicated. Text on input lines +between XS and XE is stored for later recall by PX. +

+ +
+
Macro: .PX [no]
+
+

Switch to single-column layout. Unless no is specified, center +and interpolate the TOC string in bold and two points larger than +the body text. Emit the table of contents entries. +

+ +
+
Macro: .TC [no]
+
+

Set the page number to 1, the page number format to lowercase Roman +numerals, and call PX (with a no argument, if present). +

+ +

Here’s an example of typical ms table of contents preparation. +We employ horizontal escape sequences \h to indent the entries by +sectioning depth. +

+
+
+
.NH 1
+Introduction
+.XS
+Introduction
+.XE
+
+.NH 2
+Methodology
+.XS
+\h'2n'Methodology
+.XA
+\h'4n'Fassbinder's Approach
+\h'4n'Kahiu's Approach
+.XE
+
+.NH 1
+Findings
+.XS
+Findings
+.XE
+
+.TC
+
+
+ +

The remaining features in this subsubsection are GNU extensions. +groff ms obviates the need to repeat heading text after +XS calls. Call XN and XH after NH and +SH, respectively. +

+
+
Macro: .XN heading-text
+
+
Macro: .XH depth heading-text
+
+

Format heading-text and create a corresponding table of contents +entry. XN computes the indentation from the depth of the +preceding NH call; XH requires a depth argument to +do so. +

+ +

groff ms encourages customization of table of contents +entry production. +

+
+
Macro: .XN-REPLACEMENT heading-text
+
+
Macro: .XH-REPLACEMENT depth heading-text
+
+

These hook macros implement XN and XH, respectively. +They call XN-INIT and pass their heading-text arguments to +XH-UPDATE-TOC. +

+ +
+
Macro: .XN-INIT
+
+
Macro: .XH-UPDATE-TOC depth heading-text
+
+

The XN-INIT hook macro does nothing by default. +XH-UPDATE-TOC brackets heading-text with XS and +XE calls, indenting it by 2 ens per level of depth beyond +the first. +

+ +

We could therefore produce a table of contents similar to that in the +previous example with fewer macro calls. (The difference is that this +input follows the “Approach” entries with leaders and page numbers.) +

+
+
+
.NH 1
+.XN Introduction
+
+.NH 2
+.XN Methodology
+.XH 3 "Fassbinder's Approach"
+.XH 3 "Kahiu's Approach"
+
+.NH 1
+.XN Findings
+
+
+
+ +

To get the section number of the numbered headings into the table of +contents entries, we might define XN-REPLACEMENT as follows. +(We obtain the heading depth from groff ms’s internal +register nh*hl.) +

+
+
+
.de XN-REPLACEMENT
+.XN-INIT
+.XH-UPDATE-TOC \\n[nh*hl] \\$@
+\&\\*[SN] \\$*
+..
+
+
+ +

You can change the style of the leader that bridges each table of +contents entry with its page number; define the TC-LEADER special +character by using the char request. A typical leader combines +the dot glyph ‘.’ with a horizontal motion escape sequence to +spread the dots. The width of the page number field is stored in the +TC-MARGIN register. +

+ +
+
+
+
+ +

4.6.7 Differences from AT&T ms

+ + + +

The groff ms macros are an independent reimplementation, +using no AT&T code. Since they take advantage of the extended +features of groff, they cannot be used with AT&T +troff. groff ms supports features described above +as Berkeley and Tenth Edition Research Unix extensions, and adds several +of its own. +

+
    +
  • The internals of groff ms differ from the internals of +AT&T ms. Documents that depend upon implementation +details of AT&T ms may not format properly with +groff ms. Such details include macros whose function was +not documented in the AT&T ms +manual.14 + +
  • The error-handling policy of groff ms is to detect and +report errors, rather than to ignore them silently. + +
  • Tenth Edition Research Unix supported P1/P2 macros to bracket code +examples; groff ms does not. + +
  • groff ms does not work in GNU troff’s +AT&T compatibility mode. If loaded when that mode is enabled, +it aborts processing with a diagnostic message. + +
  • Multiple line spacing is not supported. Use a larger vertical spacing +instead. + +
  • groff ms uses the same header and footer defaults in both +nroff and troff modes as AT&T ms does in +troff mode; AT&T’s default in nroff mode is to +put the date, in U.S. traditional format (e.g., “January 1, 2021”), +in the center footer (the CF string). + +
  • Many groff ms macros, including those for paragraphs, +headings, and displays, cause a reset of paragraph rendering parameters, +and may change the indentation; they do so not by incrementing or +decrementing it, but by setting it absolutely. This can cause problems +for documents that define additional macros of their own that try to +manipulate indentation. Use the ms RS and RE +macros instead of the in request. + +
  • + +AT&T ms interpreted the values of the registers +PS and VS in points, and did not support the use of +scaling units with them. groff ms interprets values of +the registers PS, VS, FPS, and FVS equal to +or larger than 1,000 (one thousand) as decimal fractions multiplied +by 1,000.15 This threshold makes use of a +scaling unit with these parameters practical for high-resolution +devices while preserving backward compatibility. It also permits +expression of non-integral type sizes. For example, ‘groff +-rPS=10.5p’ at the shell prompt is equivalent to placing ‘.nr PS +10.5p’ at the beginning of the document. + +
  • AT&T ms’s AU macro supported arguments used with +some document types; groff ms does not. + +
  • Right-aligned displays are available. The AT&T ms +manual observes that “it is tempting to assume that ‘.DS R’ will +right adjust lines, but it doesn’t work”. In groff ms, +it does. + +
  • To make groff ms use the default page offset (which also +specifies the left margin), the PO register must stay undefined +until the first ms macro is called. + +

    This implies that ‘\n[PO]’ should not be used early in the +document, unless it is changed also: accessing an undefined register +automatically defines it. +

    +
  • groff ms supports the PN register, but it is not +necessary; you can access the page number via the usual % +register and invoke the af request to assign a different format +to it if desired.16 + +
  • The AT&T ms manual documents registers CW and +GW as setting the default column width and “intercolumn gap”, +respectively, and which applied when MC was called with fewer +than two arguments. groff ms instead treats MC +without arguments as synonymous with 2C; there is thus no +occasion for a default column width register. Further, the MINGW +register and the second argument to MC specify a minimum +space between columns, not the fixed gutter width of AT&T +ms. + +
  • The AT&T ms manual did not document the QI +register; Berkeley and groff ms do. +
+ +
+
Register: \n[GS]
+
+

The register GS is set to 1 by the groff ms +macros, but is not used by the AT&T ms package. +Documents that need to determine whether they are being formatted with +groff ms or another implementation should test this +register. +

+ + + + +
+
+ +

4.6.7.1 Unix Version 7 ms macros not implemented by groff ms

+ +

Several macros described in the Unix Version 7 ms +documentation are unimplemented by groff ms because they +are specific to the requirements of documents produced internally by +Bell Laboratories, some of which also require a glyph for the Bell +System logo that groff does not support. These macros +implemented several document type formats +(EG, IM, MF, MR, TM, TR), were meaningful only in conjunction with the use of certain document +types +(AT, CS, CT, OK, SG), stored the postal addresses of Bell Labs sites +(HO, IH, MH, PY, WH), or lacked a stable definition over time +(UX). To compatibly render historical ms documents using these macros, +we advise your documents to invoke the rm request to remove any +such macros it uses and then define replacements with an authentically +typeset original at hand.17 For +informal purposes, a simple definition of UX should maintain the +readability of the document’s substance. +

+
+
+
.rm UX
+.ds UX Unix\"
+
+
+ + +
+
+
+
+ +

4.6.8 Legacy Features

+ + + + + + + +

groff ms retains some legacy features solely to support +formatting of historical documents; contemporary ones should not use +them because they can render poorly. See the groff_char(7) +man page. +

+ +
+

AT&T accent mark strings

+ +

AT&T ms defined accent mark strings as follows. +

+
+
String: \*[']
+
+

Apply acute accent to subsequent glyph. +

+ +
+
String: \*[`]
+
+

Apply grave accent to subsequent glyph. +

+ +
+
String: \*[:]
+
+

Apply dieresis (umlaut) to subsequent glyph. +

+ +
+
String: \*[^]
+
+

Apply circumflex accent to subsequent glyph. +

+ +
+
String: \*[~]
+
+

Apply tilde accent to subsequent glyph. +

+ +
+
String: \*[C]
+
+

Apply caron to subsequent glyph. +

+ +
+
String: \*[,]
+
+

Apply cedilla to subsequent glyph. +

+ +
+
+

Berkeley accent mark and glyph strings

+ +

Berkeley ms offered an AM macro; calling it redefined the +AT&T accent mark strings (except for ‘\*C’), applied them to the +preceding glyph, and defined additional strings, some for spacing +glyphs. +

+
+
Macro: .AM
+
+

Enable alternative accent mark and glyph-producing strings. +

+ +
+
String: \*[']
+
+

Apply acute accent to preceding glyph. +

+ +
+
String: \*[`]
+
+

Apply grave accent to preceding glyph. +

+ +
+
String: \*[:]
+
+

Apply dieresis (umlaut) to preceding glyph. +

+ +
+
String: \*[^]
+
+

Apply circumflex accent to preceding glyph. +

+ +
+
String: \*[~]
+
+

Apply tilde accent to preceding glyph. +

+ +
+
String: \*[,]
+
+

Apply cedilla to preceding glyph. +

+ +
+
String: \*[/]
+
+

Apply stroke (slash) to preceding glyph. +

+ +
+
String: \*[v]
+
+

Apply caron to preceding glyph. +

+ +
+
String: \*[_]
+
+

Apply macron to preceding glyph. +

+ +
+
String: \*[.]
+
+

Apply underdot to preceding glyph. +

+ +
+
String: \*[o]
+
+

Apply ring accent to preceding glyph. +

+ +
+
String: \*[?]
+
+

Interpolate inverted question mark. +

+ +
+
String: \*[!]
+
+

Interpolate inverted exclamation mark. +

+ +
+
String: \*[8]
+
+

Interpolate small letter sharp s. +

+ +
+
String: \*[q]
+
+

Interpolate small letter o with hook accent (ogonek). +

+ +
+
String: \*[3]
+
+

Interpolate small letter yogh. +

+ +
+
String: \*[d-]
+
+

Interpolate small letter eth. +

+ +
+
String: \*[D-]
+
+

Interpolate capital letter eth. +

+ +
+
String: \*[th]
+
+

Interpolate small letter thorn. +

+ +
+
String: \*[Th]
+
+

Interpolate capital letter thorn. +

+ +
+
String: \*[ae]
+
+

Interpolate small ć ligature. +

+ +
+
String: \*[Ae]
+
+

Interpolate capital Ć ligature. +

+ +
+
String: \*[oe]
+
+

Interpolate small oe ligature. +

+ +
+
String: \*[OE]
+
+

Interpolate capital OE ligature. +

+ + +
+
+
+
+ +

4.6.9 Naming Conventions

+ + + +

The following conventions are used for names of macros, strings, and +registers. External names available to documents that use the +groff ms macros contain only uppercase letters and digits. +

+

Internally, the macros are divided into modules. Conventions for +identifier names are as follows. +

+
    +
  • Names used only within one module are of the form +module*name. + +
  • Names used outside the module in which they are defined are of the form +module@name. + +
  • Names associated with a particular environment are of the form +environment:name; these are used only within the +par module. + +
  • name does not have a module prefix. + +
  • Constructed names used to implement arrays are of the form +array!index. +
+ +

Thus the groff ms macros reserve the following names. +

+
    +
  • Names containing the characters *, @, and :. + +
  • Names containing only uppercase letters and digits. +
+ + + +
+
+
+
+
+ +

5 GNU troff Reference

+ + + +

This chapter covers all of the facilities of the GNU +troff formatting engine. Users of macro packages may skip it if +not interested in details. +

+ + + + + +
+
+ +

5.1 Text

+ + +

AT&T troff was designed to take input as it would be +composed on a typewriter, including the teletypewriters used as early +computer terminals, and relieve the user drafting a document of concern +with details like line length, hyphenation breaking, and the achievement +of straight margins. Early in its development, the program gained the +ability to prepare output for a phototypesetter; a document could then +be prepared for output to either a teletypewriter, a phototypesetter, or +both. GNU troff continues this tradition of permitting an author +to compose a single master version of a document which can then be +rendered for a variety of output formats or devices. +

+

roff input files contain text interspersed with instructions to +control the formatter. Even in the absence of such instructions, GNU +troff still processes its input in several ways, by filling, +hyphenating, breaking, and adjusting it, and supplementing it with +inter-sentence space. +

+ + + +
+
+ +

5.1.1 Filling

+ +

When GNU troff starts up, it obtains information about the device +for which it is preparing output.18 An essential property is the length of the output +line, such as “6.5 inches”. +

+ + +

GNU troff interprets plain text files employing the Unix +line-ending convention. It reads input a character at a time, +collecting words as it goes, and fits as many words together on an +output line as it can—this is known as filling. To GNU +troff, a word is any sequence of one or more characters +that aren’t spaces or newlines. The exceptions separate +words.19 To disable filling, see +Manipulating Filling and Adjustment. +

+
+
It is a truth universally acknowledged
+that a single man in possession of a
+good fortune must be in want of a wife.
+    ⇒ It is a truth universally acknowledged that a
+    ⇒ single man in possession of a good fortune must
+    ⇒ be in want of a wife.
+
+ + +
+
+
+ +

5.1.2 Sentences

+ + +

A passionate debate has raged for decades among writers of the English +language over whether more space should appear between adjacent +sentences than between words within a sentence, and if so, how much, and +what other circumstances should influence this spacing.20 +GNU troff follows the example of AT&T troff; +it attempts to detect the boundaries between sentences, and supplies +additional inter-sentence space between them. +

+
+
Hello, world!
+Welcome to groff.
+    ⇒ Hello, world!  Welcome to groff.
+
+ + + + + +

GNU troff flags certain characters (normally ‘!’, ‘?’, +and ‘.’) as potentially ending a sentence. When GNU troff +encounters one of these end-of-sentence characters at the end of +an input line, or one of them is followed by two (unescaped) spaces on +the same input line, it appends an inter-word space followed by an +inter-sentence space in the output. +

+
+
R. Harper subscribes to a maxim of P. T. Barnum.
+    ⇒ R. Harper subscribes to a maxim of P. T. Barnum.
+
+ +

In the above example, inter-sentence space is not added after ‘P.’ +or ‘T.’ because the periods do not occur at the end of an input +line, nor are they followed by two or more spaces. Let’s imagine that +we’ve heard something about defamation from Mr. Harper’s attorney, +recast the sentence, and reflowed it in our text editor. +

+
+
I submit that R. Harper subscribes to a maxim of P. T.
+Barnum.
+    ⇒ I submit that R. Harper subscribes to a maxim of
+    ⇒ P. T.  Barnum.
+
+ +

“Barnum” doesn’t begin a sentence! What to do? Let us meet our first +escape sequence, a series of input characters that give +instructions to GNU troff instead of being used to construct +output device glyphs.21 An escape sequence begins with the backslash character \ +by default, an uncommon character in natural language text, and is +always followed by at least one other character, hence the term +“sequence”. +

+ +

The dummy character escape sequence \& can be used after an +end-of-sentence character to defeat end-of-sentence detection on a +per-instance basis. We can therefore rewrite our input more +defensively. +

+
+
I submit that R.\& Harper subscribes to a maxim of P.\&
+T.\& Barnum.
+    ⇒ I submit that R. Harper subscribes to a maxim of
+    ⇒ P. T. Barnum.
+
+ +

Adding text caused our input to wrap; now, we don’t need \& after +‘T.’ but we do after ‘P.’. Consistent use of the escape +sequence ensures that potential sentence boundaries are robust to +editing activities. Further advice along these lines will follow in +Input Conventions. +

+ + + + + + + + + + + + + +

Normally, the occurrence of a visible non-end-of-sentence character (as +opposed to a space or tab) immediately after an end-of-sentence +character cancels detection of the end of a sentence. For example, it +would be incorrect for GNU troff to infer the end of a sentence +after the dot in ‘3.14159’. However, several characters are +treated transparently after the occurrence of an end-of-sentence +character. That is, GNU troff does not cancel end-of-sentence +detection when it processes them. This is because such characters are +often used as footnote markers or to close quotations and +parentheticals. The default set is ‘"’, ‘'’, ‘)’, +‘]’, ‘*’, \[dg], \[dd], \[rq], and +\[cq]. The last four are examples of special characters, +escape sequences whose purpose is to obtain glyphs that are not easily +typed at the keyboard, or which have special meaning to GNU troff +(like \ itself).22 +

+
+
\[lq]The idea that the poor should have leisure has always
+been shocking to the rich.\[rq]
+(Bertrand Russell, 1935)
+    ⇒ "The idea that the poor should have
+    ⇒ leisure has always been shocking to
+    ⇒ the rich."  (Bertrand Russell, 1935)
+
+ +

The sets of characters that potentially end sentences or are transparent +to sentence endings are configurable. See the cflags request in +Using Symbols. To change the additional inter-sentence space +amount—even to remove it entirely—see Manipulating Filling and Adjustment. +

+ +
+
+
+ +

5.1.3 Hyphenation

+ + +

When an output line is nearly full, it is uncommon for the next word +collected from the input to exactly fill it—typically, there is room +left over only for part of the next word. The process of splitting a +word so that it appears partially on one line (with a hyphen to indicate +to the reader that the word has been broken) with its remainder on the +next is hyphenation. Hyphenation points can be manually +specified; GNU troff also uses a hyphenation algorithm and +language-specific pattern files (based on those used in TeX) to +decide which words can be hyphenated and where. +

+

Hyphenation does not always occur even when the hyphenation rules for a +word allow it; it can be disabled, and when not disabled there are +several parameters that can prevent it in certain circumstances. +See Manipulating Hyphenation. +

+ +
+
+
+ +

5.1.4 Breaking

+ + + + + +

Once an output line is full, the next word (or remainder of a hyphenated +one) is placed on a different output line; this is called a break. +In this manual and in roff discussions generally, a “break” if +not further qualified always refers to the termination of an output +line. When the formatter is filling text, it introduces breaks +automatically to keep output lines from exceeding the configured line +length. After an automatic break, GNU troff adjusts the line if +applicable (see below), and then resumes collecting and filling text on +the next output line. +

+

Sometimes, a line cannot be broken automatically. This usually does +not happen with natural language text unless the output line length has +been manipulated to be extremely short, but it can with specialized +text like program source code. We can use perl at the shell +prompt to contrive an example of failure to break the line. We also +employ the -z option to suppress normal output. +

+
+
$ perl -e 'print "#" x 80, "\n";' | nroff -z
+    error→ warning: cannot break line
+
+ +

The remedy for these cases is to tell GNU troff where the line +may be broken without hyphens. This is done with the non-printing break +point escape sequence ‘\:’; see Manipulating Hyphenation. +

+ + + + +

What if the document author wants to stop filling lines temporarily, for +instance to start a new paragraph? There are several solutions. A +blank input line not only causes a break, but by default it also outputs +a one-line vertical space (effectively a blank output line). This +behavior can be modified; see Blank Line Traps. Macro packages +may discourage or disable the blank line method of paragraphing in favor +of their own macros. +

+ + + + +

A line that begins with one or more spaces causes a break. The spaces +are output at the beginning of the next line without being +adjusted (see below); however, this behavior can be modified +(see Leading Space Traps). Again, macro packages may provide other +methods of producing indented paragraphs. Trailing spaces on text lines +are discarded.23 +

+

What if the file ends before enough words have been collected to fill an +output line? Or the output line is exactly full but not yet broken, and +there is no more input? GNU troff interprets the end of input as +a break. Certain requests also cause breaks, implicitly or explicitly. +This is discussed in Manipulating Filling and Adjustment. +

+ +
+
+
+ +

5.1.5 Adjustment

+ + +

After GNU troff performs an automatic break, it may then +adjust the line, widening inter-word spaces until the text reaches +the right margin. Extra spaces between words are preserved. Leading +and trailing spaces are handled as noted above. Text can be aligned to +the left or right margin only, or centered; see Manipulating Filling and Adjustment. +

+ +
+
+
+ +

5.1.6 Tabs and Leaders

+ + + + + + + + +

GNU troff translates input horizontal tab characters (“tabs”) +and Control+A characters (“leaders”) into movements to the next +tab stop. Tabs simply move to the next tab stop; leaders place enough +periods to fill the space. Tab stops are by default located every half +inch measured from the drawing position corresponding to the beginning +of the input line; see Page Geometry. Tabs and leaders do not +cause breaks and therefore do not interrupt filling. Below, we use +arrows → and bullets • to indicate input tabs and +leaders, respectively. +

+
+
1
+→ 2 → 3 • 4
+→ • 5
+⇒ 1         2       3.......4         ........5
+
+ +

Tabs and leaders lend themselves to table construction.24 The tab and leader glyphs can be +configured, and further facilities for sophisticated table composition +are available; see Tabs and Fields. There are many details to +track when using such low-level features, so most users turn to the +tbl(1) preprocessor to lay out tables. +

+ +
+
+
+ +

5.1.7 Requests and Macros

+ +

We have now encountered almost all of the syntax there is in the +roff language, with an exception already noted in passing. + + + + + + +A request is an instruction to the formatter that occurs after a +control character, which is recognized at the beginning of an +input line. The regular control character is a dot (.). Its +counterpart, the no-break control character, a neutral apostrophe +('), suppresses the break that is implied by some requests. +These characters were chosen because it is uncommon for lines of text in +natural languages to begin with them. + + +If you require a formatted period or apostrophe (closing single +quotation mark) where GNU troff is expecting a control character, +prefix the dot or neutral apostrophe with the dummy character escape +sequence, ‘\&’. +

+ +

An input line beginning with a control character is called a +control line. + +Every line of input that is not a control line is a text +line.25 +

+ +

Requests often take arguments, words (separated from the request +name and each other by spaces) that specify details of the action GNU +troff is expected to perform. If a request is meaningless +without arguments, it is typically ignored. +

+

GNU troff’s requests and escape sequences comprise the control +language of the formatter. Of key importance are the requests that +define macros. Macros are invoked like requests, enabling the request +repertoire to be extended or overridden.26 +

+ + + +

A macro can be thought of as an abbreviation you can define for a +collection of control and text lines. When the macro is called by +giving its name after a control character, it is replaced with what it +stands for. The process of textual replacement is known as +interpolation.27 Interpolations are handled as soon as they are +recognized, and once performed, a roff formatter scans the +replacement for further requests, macro calls, and escape sequences. +

+

In roff systems, the de request defines a +macro.28 +

+
+
.de DATE
+2020-11-14
+..
+
+ +

The foregoing input produces no output by itself; all we have done is +store some information. Observe the pair of dots that ends the macro +definition. This is a default; you can specify your own terminator for +the macro definition as the second argument to the de request. +

+
+
.de NAME ENDNAME
+Heywood Jabuzzoff
+.ENDNAME
+
+ +

In fact, the ending marker is itself the name of a macro to be +called, or a request to be invoked, if it is defined at the time its +control line is read. +

+
+
.de END
+Big Rip
+..
+.de START END
+Big Bang
+.END
+.START
+    ⇒ Big Rip Big Bang
+
+ +

In the foregoing example, “Big Rip” printed before “Big Bang” +because its macro was called first. Consider what would happen +if we dropped END from the ‘.de START’ line and added +.. after .END. Would the order change? +

+

Let us consider a more elaborate example. +

+
+
.de DATE
+2020-10-05
+..
+.
+.de BOSS
+D.\& Kruger,
+J.\& Peterman
+..
+.
+.de NOTICE
+Approved:
+.DATE
+by
+.BOSS
+..
+.
+Insert tedious regulatory compliance paragraph here.
+
+.NOTICE
+
+Insert tedious liability disclaimer paragraph here.
+
+.NOTICE
+    ⇒ Insert tedious regulatory compliance paragraph here.
+    ⇒
+    ⇒ Approved: 2020-10-05 by D. Kruger, J. Peterman
+    ⇒
+    ⇒ Insert tedious liability disclaimer paragraph here.
+    ⇒
+    ⇒ Approved: 2020-10-05 by D. Kruger, J. Peterman
+
+ +

The above document started with a series of control lines. Three macros +were defined, with a de request declaring each macro’s name, and +the “body” of the macro starting on the next line and continuing until +a line with two dots ‘..’ marked its end. The text proper +began only after the macros were defined; this is a common pattern. +Only the NOTICE macro was called “directly” by the document; +DATE and BOSS were called only by NOTICE itself. +Escape sequences were used in BOSS, two levels of macro +interpolation deep. +

+

The advantage in typing and maintenance economy may not be obvious from +such a short example, but imagine a much longer document with dozens of +such paragraphs, each requiring a notice of managerial approval. +Consider what must happen if you are in charge of generating a new +version of such a document with a different date, for a different boss. +With well-chosen macros, you only have to change each datum in one +place. +

+

In practice, we would probably use strings (see Strings) instead of +macros for such simple interpolations; what is important here is to +glimpse the potential of macros and the power of recursive +interpolation. +

+

We could have defined DATE and BOSS in the opposite order; +perhaps less obviously, we could also have defined them after +NOTICE. “Forward references” like this are acceptable because +the body of a macro definition is not (completely) interpreted, but +stored instead (see Copy Mode). While a macro is being defined (or +appended to), requests are not interpreted and macros not interpolated, +whereas some commonly used escape sequences are interpreted. +roff systems also support recursive macro calls, as long as you +have a way to break the recursion (see Conditionals and Loops). +Maintainable roff documents tend to arrange macro definitions to +minimize forward references. +

+ +
+
+
+ +

5.1.8 Macro Packages

+ + + +

Macro definitions can be collected into macro files, roff +input files designed to produce no output themselves but instead ease +the preparation of other roff documents. There is no syntactical +difference between a macro file and any other roff document; only +its purpose distinguishes it. When a macro file is installed at a +standard location and suitable for use by a general audience, it is +often termed a macro package.29 Macro packages can be +loaded by supplying the -m option to GNU troff or a +groff front end. Alternatively, a document requiring a macro +package can load it with the mso (“macro source”) request. +

+ + +
+
+
+ +

5.1.9 Input Encodings

+ +

The groff command’s -k option calls the +preconv preprocessor to perform input character encoding +conversions. Input to the GNU troff formatter itself, on the +other hand, must be in one of two encodings it can recognize. +

+
+
cp1047
+
+ + + + + + +

The code page 1047 input encoding works only on EBCDIC +platforms (and conversely, the other input encodings don’t work with +EBCDIC); the file cp1047.tmac is loaded at startup. +

+
+
latin1
+
+ + + +

ISO Latin-1, an encoding for Western European languages, is the +default input encoding on non-EBCDIC platforms; the file +latin1.tmac is loaded at startup. +

+
+ +

Any document that is encoded in ISO 646:1991 (a descendant of USAS +X3.4-1968 or “US-ASCII”), or, equivalently, uses only code points +from the “C0 Controls” and “Basic Latin” parts of the Unicode +character set is also a valid ISO Latin-1 document; the standards +are interchangeable in their first 128 code points.30 +

+

Other encodings are supported by means of macro packages. +

+
+
latin2
+
+ + + +

To use ISO Latin-2, an encoding for Central and Eastern European +languages, invoke ‘.mso latin2.tmac at the beginning of your +document or supply ‘-mlatin2’ as a command-line argument to +groff. +

+
+
latin5
+
+ + + +

To use ISO Latin-5, an encoding for the Turkish language, invoke +‘.mso latin5.tmac at the beginning of your document or +supply ‘-mlatin5’ as a command-line argument to groff. +

+
+
latin9
+
+ + + +

ISO Latin-9 succeeds Latin-1; it includes a Euro sign and better +glyph coverage for French. To use this encoding, invoke ‘.mso latin9.tmac at the beginning of your document or supply +‘-mlatin9’ as a command-line argument to groff. +

+
+ +

Some characters from an input encoding may not be available with a +particular output driver, or their glyphs may not have representation in +the font used. For terminal devices, fallbacks are defined, like +‘EUR’ for the Euro sign and ‘(C)’ for the copyright sign. For +typesetter devices, you may need to “mount” fonts that support glyphs +required by the document. See Font Positions. +

+ + +

Because a Euro glyph was not historically defined in PostScript fonts, +groff comes with a font called freeeuro.pfa that provides +the Euro in several styles. Standard PostScript fonts contain the +glyphs from Latin-5 and Latin-9 that Latin-1 lacks, so these +encodings are supported for the ps and pdf output +devices as groff ships, while Latin-2 is not. +

+

Unicode supports characters from all other input encodings; the +utf8 output driver for terminals therefore does as well. The +DVI output driver supports the Latin-2 and Latin-9 encodings if +the command-line option -mec is used as well. 31 +

+ +
+
+
+ +

5.1.10 Input Conventions

+ + + +

Since GNU troff fills text automatically, it is common practice +in the roff language to avoid visual composition of text in input +files: the esthetic appeal of the formatted output is what matters. +Therefore, roff input should be arranged such that it is easy for +authors and maintainers to compose and develop the document, understand +the syntax of roff requests, macro calls, and preprocessor +languages used, and predict the behavior of the formatter. Several +traditions have accrued in service of these goals. +

+
    +
  • Follow sentence endings in the input with newlines to ease their +recognition (see Sentences). It is frequently convenient to end +text lines after colons and semicolons as well, as these typically +precede independent clauses. Consider doing so after commas; they often +occur in lists that become easy to scan when itemized by line, or +constitute supplements to the sentence that are added, deleted, or +updated to clarify it. Parenthetical and quoted phrases are also good +candidates for placement on text lines by themselves. + +
  • Set your text editor’s line length to 72 characters or +fewer.32 +This limit, combined with the previous item of advice, makes it less +common that an input line will wrap in your text editor, and thus will +help you perceive excessively long constructions in your text. Recall +that natural languages originate in speech, not writing, and that +punctuation is correlated with pauses for breathing and changes in +prosody. + +
  • Use \& after ‘!’, ‘?’, and ‘.’ if they are +followed by space, tab, or newline characters and don’t end a sentence. + +
  • In filled text lines, use \& before ‘.’ and ‘'’ if they +are preceded by space, so that reflowing the input doesn’t turn them +into control lines. + +
  • Do not use spaces to perform indentation or align columns of a table. +Leading spaces are reliable when text is not being filled. + +
  • Comment your document. It is never too soon to apply comments to +record information of use to future document maintainers (including your +future self). We thus introduce another escape sequence, \", +which causes GNU troff to ignore the remainder of the input line. + +
  • Use the empty request—a control character followed immediately by a +newline—to visually manage separation of material in input files. +Many of the groff project’s own documents use an empty request +between sentences, after macro definitions, and where a break is +expected, and two empty requests between paragraphs or other requests or +macro calls that will introduce vertical space into the document. + +

    You can combine the empty request with the comment escape sequence to +include whole-line comments in your document, and even “comment out” +sections of it. +

+ +

We conclude this section with an example sufficiently long to illustrate +most of the above suggestions in practice. For the purpose of fitting +the example between the margins of this manual with the font used for +its typeset version, we have shortened the input line length to 56 +columns. As before, an arrow → indicates a tab character. +

+
+
+
.\"   nroff this_file.roff | less
+.\"   groff -T ps this_file.roff > this_file.ps
+→The theory of relativity is intimately connected with
+the theory of space and time.
+.
+I shall therefore begin with a brief investigation of
+the origin of our ideas of space and time,
+although in doing so I know that I introduce a
+controversial subject.  \" remainder of paragraph elided
+.
+.
+
+→The experiences of an individual appear to us arranged
+in a series of events;
+in this series the single events which we remember
+appear to be ordered according to the criterion of
+\[lq]earlier\[rq] and \[lq]later\[rq], \" punct swapped
+which cannot be analysed further.
+.
+There exists,
+therefore,
+for the individual,
+an I-time,
+or subjective time.
+.
+This itself is not measurable.
+.
+I can,
+indeed,
+associate numbers with the events,
+in such a way that the greater number is associated with
+the later event than with an earlier one;
+but the nature of this association may be quite
+arbitrary.
+.
+This association I can define by means of a clock by
+comparing the order of events furnished by the clock
+with the order of a given series of events.
+.
+We understand by a clock something which provides a
+series of events which can be counted,
+and which has other properties of which we shall speak
+later.
+.\" Albert Einstein, _The Meaning of Relativity_, 1922
+
+
+ +
+
+
+
+ +

5.2 Page Geometry

+ + + +

roff systems format text under certain assumptions about the size +of the output medium, or page. For the formatter to correctly break a +line it is filling, it must know the line length, which it derives from +the page width (see Line Layout). For it to decide whether to write +an output line to the current page or wait until the next one, it must +know the page length (see Page Layout). +

+ + + + + + +

A device’s resolution converts practical units like inches or +centimeters to basic units, a convenient length measure for the +output device or file format. The formatter and output driver use basic +units to reckon page measurements. The device description file defines +its resolution and page dimensions (see DESC File Format). +

+ +

A page is a two-dimensional structure upon which a roff +system imposes a rectangular coordinate system with its upper left +corner as the origin. Coordinate values are in basic units and increase +down and to the right. Useful ones are therefore always positive and +within numeric ranges corresponding to the page boundaries. +

+ + +

While the formatter (and, later, output driver) is processing a page, it +keeps track of its drawing position, which is the location at +which the next glyph will be written, from which the next motion will be +measured, or where a geometric object will commence rendering. + + +Notionally, glyphs are drawn from the text baseline upward and to the +right.33 The text baseline is a (usually invisible) line upon +which the glyphs of a typeface are aligned. A glyph therefore +“starts” at its bottom-left corner. If drawn at the origin, a typical +letter glyph would lie partially or wholly off the page, depending on +whether, like “g”, it features a descender below the baseline. +

+ + +

Such a situation is nearly always undesirable. It is furthermore +conventional not to write or draw at the extreme edges of the page. +Therefore the initial drawing position of a roff formatter is not +at the origin, but below and to the right of it. This rightward shift +from the left edge is known as the page +offset.34 The downward shift leaves room for a text output +line. +

+

Text is arranged on a one-dimensional lattice of text baselines from the +top to the bottom of the page. + + + +Vertical spacing is the distance between adjacent text baselines. +Typographic tradition sets this quantity to 120% of the type size. The +initial drawing position is one unit of vertical spacing below the page +top. Typographers term this unit a vee. +

+ + + + +

Vertical spacing has an impact on page-breaking decisions. Generally, +when a break occurs, the formatter moves the drawing position to the +next text baseline automatically. If the formatter were already writing +to the last line that would fit on the page, advancing by one vee would +place the next text baseline off the page. Rather than let that happen, +roff formatters instruct the output driver to eject the page, +start a new one, and again set the drawing position to one vee below the +page top; this is a page break. +

+

When the last line of input text corresponds to the last output line +that fits on the page, the break caused by the end of input will also +break the page, producing a useless blank one. Macro packages keep +users from having to confront this difficulty by setting “traps” +(see Traps); moreover, all but the simplest page layouts tend to +have headers and footers, or at least bear vertical margins larger than +one vee. +

+ + +
+
+
+ +

5.3 Measurements

+ + + + + + +

The formatter sometimes requires the input of numeric parameters to +specify measurements. These are specified as integers or decimal +fractions with an optional scaling unit suffixed. A scaling unit +is a letter that immediately follows the last digit of a number. Digits +after the decimal point are optional. Measurement expressions include +‘10.5p’, ‘11i’, and ‘3.c’. +

+ + + +

Measurements are scaled by the scaling unit and stored internally (with +any fractional part discarded) in basic units. + + +The device resolution can therefore be obtained by storing a value of +‘1i’ to a register. The only constraint on the basic unit is that +it is at least as small as any other unit. +

+
+
+ + + +
+
u
+

Basic unit. +

+
+
i
+
+ + +

Inch; defined as 2.54 centimeters. +

+
+
c
+
+ + +

Centimeter; a centimeter is about 0.3937 inches. +

+
+
p
+
+ + +

Point; a typesetter’s unit used for measuring type size. +There are 72 points to an inch. +

+
+
P
+
+ + +

Pica; another typesetter’s unit. There are 6 picas to an inch and +12 points to a pica. +

+
+
s
+
z
+

See Using Fractional Type Sizes, for a discussion of these units. +

+
+
f
+

GNU troff defines this unit to scale decimal fractions in the +interval [0, 1] to 16-bit unsigned integers. It multiplies a quantity +by 65,536. See Colors, for usage. +

+
+ +

The magnitudes of other scaling units depend on the text formatting +parameters in effect. These are useful when specifying measurements +that need to scale with the typeface or vertical spacing. +

+
+
m
+
+ + +

Em; an em is equal to the current type size in points. It is named thus +because it is approximately the width of the letter ‘M’. +

+
+
n
+
+ + +

En; an en is one-half em. +

+
+
v
+
+ + + + +

Vee; recall Page Geometry. +

+
+
M
+
+ +

Hundredth of an em. +

+
+ + + + +
+
+ +

5.3.1 Motion Quanta

+ + + +

An output device’s basic unit u is not necessarily its smallest +addressable length; u can be smaller to avoid problems with +integer roundoff. The minimum distances that a device can work with in +the horizontal and vertical directions are termed its motion +quanta. Measurements are rounded to applicable motion quanta. +Half-quantum fractions round toward zero. +

+ + + + +
+
Register: \n[.H]
+
+
Register: \n[.V]
+
+

These read-only registers interpolate the horizontal and vertical motion +quanta, respectively, of the output device in basic units. +

+ +

For example, we might draw short baseline rules on a terminal device as +follows. See Drawing Geometric Objects. +

+
+
.tm \n[.H]
+    error→ 24
+.nf
+\l'36u' 36u
+\l'37u' 37u
+    ⇒ _ 36u
+    ⇒ __ 37u
+
+ + +
+
+
+ +

5.3.2 Default Units

+ + + +

A general-purpose register (one created or updated with the nr +request; see see Registers) is implicitly dimensionless, or reckoned +in basic units if interpreted in a measurement context. But it is +convenient for many requests and escape sequences to infer a scaling +unit for an argument if none is specified. An explicit scaling unit +(not after a closing parenthesis) can override an undesirable default. +Effectively, the default unit is suffixed to the expression if a scaling +unit is not already present. GNU troff’s use of integer +arithmetic should also be kept in mind (see Numeric Expressions). +

+

The ll request interprets its argument in ems by default. +Consider several attempts to set a line length of 3.5 inches when +the type size is 10 points on a terminal device with a resolution +of 240 basic units and horizontal motion quantum of 24. Some +expressions become zero; the request clamps them to that quantum. +

+
+
.ll 3.5i      \" 3.5i (= 840u)
+.ll 7/2       \" 7u/2u -> 3u -> 3m -> 0, clamped to 24u
+.ll (7 / 2)u  \" 7u/2u -> as above
+.ll 7/2i      \" 7u/2i -> 7u/480u -> 0 -> as above
+.ll 7i/2      \" 7i/2u -> 1680u/2m -> 1680u/24u -> 35u
+.ll 7i/2u     \" 3.5i (= 840u)
+
+ + +

The safest way to specify measurements is to attach a scaling unit. To +multiply or divide by a dimensionless quantity, use ‘u’ as its +scaling unit. +

+ + +
+
+
+
+ +

5.4 Numeric Expressions

+ + + +

A numeric expression evaluates to an integer: it can be as +simple as a literal ‘0’ or it can be a complex sequence of register +and string interpolations interleaved with measurements and operators. +

+

GNU troff provides a set of mathematical and logical operators +familiar to programmers—as well as some unusual ones—but supports +only integer arithmetic.35 The internal data type +used for computing results is usually a 32-bit signed integer, which +suffices to represent magnitudes within a range of ą2 +billion.36 +

+ + + + + + + + + + + + + +

Arithmetic infix operators perform a function on the numeric expressions +to their left and right; they are + (addition), - +(subtraction), * (multiplication), / (truncating +division), and % (modulus). Truncating division rounds to +the integer nearer to zero, no matter how large the fractional portion. +Overflow and division (or modulus) by zero are errors and abort +evaluation of a numeric expression. + + + + + + + + +

+

Arithmetic unary operators operate on the numeric expression to their +right; they are - (negation) and + (assertion—for +completeness; it does nothing). The unary minus must often be used +with parentheses to avoid confusion with the decrementation operator, +discussed below. +

+

Observe the rounding behavior and effect of negative operands on the +modulus and truncating division operators. +

+
+
.nr T 199/100
+.nr U 5/2
+.nr V (-5)/2
+.nr W 5/-2
+.nr X 5%2
+.nr Y (-5)%2
+.nr Z 5%-2
+T=\n[T] U=\n[U] V=\n[V] W=\n[W] X=\n[X] Y=\n[Y] Z=\n[Z]
+    ⇒ T=1 U=2 V=-2 W=-2 X=1 Y=-1 Z=1
+
+ +

The sign of the modulus of operands of mixed signs is determined by the +sign of the first. Division and modulus operators satisfy the following +property: given a dividend a and a divisor b, a +quotient q formed by ‘(a / b)’ and a +remainder r by ‘(a % b)’, then qb + r = a. +

+ + + +

GNU troff’s scaling operator, used with parentheses as +(c;e), evaluates a numeric expression e +using c as the default scaling unit. If c is omitted, +scaling units are ignored in the evaluation of e. This +operator can save typing by avoiding the attachment of scaling units to +every operand out of caution. Your macros can select a sensible default +unit in case the user neglects to supply one. +

+
+
.\" Indent by amount given in first argument; assume ens.
+.de Indent
+.  in (n;\\$1)
+..
+
+ +

Without the scaling operator, the foregoing macro would, if called with +a unitless argument, cause indentation by the in request’s +default scaling unit (ems). The result would be twice as much +indentation as expected. +

+ + + + + + +

GNU troff also provides a pair of operators to compute the +extrema of two operands: >? (maximum) and <? (minimum). +

+
+
.nr slots 5
+.nr candidates 3
+.nr salaries (\n[slots] <? \n[candidates])
+Looks like we'll end up paying \n[salaries] salaries.
+    ⇒ Looks like we'll end up paying 3 salaries.
+
+ + + + + + + + + + + + +

Comparison operators comprise < (less than), > (greater +than), <= (less than or equal), >= (greater than or +equal), and = (equal). == is a synonym for =. +When evaluated, a comparison is replaced with ‘0’ if it is false +and ‘1’ if true. In the roff language, positive values are +true, others false. +

+ + + + + + + + +

We can operate on truth values with the logical operators & +(logical conjunction or “and”) and : (logical disjunction or +“or”). They evaluate as comparison operators do. +

+ + + + + +

A logical complementation (“not”) operator, !, works only +within if, ie, and while requests. +Furthermore, ! is recognized only at the beginning of a numeric +expression not contained by another numeric expression. In other words, +it must be the “outermost” operator. Including it elsewhere in the +expression produces a warning in the ‘number’ category +(see Warnings), and its expression evaluates false. This +unfortunate limitation maintains compatibility with AT&T +troff. Test a numeric expression for falsity by +comparing it to a false value.37 +

+
+
.nr X 1
+.nr Y 0
+.\" This does not work as expected.
+.if (\n[X])&(!\n[Y]) .nop A: X is true, Y is false
+.
+.\" Use this construct instead.
+.if (\n[X])&(\n[Y]<=0) .nop B: X is true, Y is false
+    error→ warning: expected numeric expression, got '!'
+    ⇒ B: X is true, Y is false
+
+ + + + + + +

The roff language has no operator precedence: expressions are +evaluated strictly from left to right, in contrast to schoolhouse +arithmetic. Use parentheses ( ) to impose a desired +precedence upon subexpressions. +

+
+
.nr X 3+5*4
+.nr Y (3+5)*4
+.nr Z 3+(5*4)
+X=\n[X] Y=\n[Y] Z=\n[Z]
+    ⇒ X=32 Y=32 Z=23
+
+ + + + + + + +

For many requests and escape sequences that cause motion on the page, +the unary operators + and - work differently when leading +a numeric expression. They then indicate a motion relative to the +drawing position: positive is down in vertical contexts, right in +horizontal ones. +

+ + + + + + + + + + + + + + + + +

+ and - are also treated differently by the following +requests and escape sequences: bp, in, ll, +lt, nm, nr, pl, pn, po, +ps, pvs, rt, ti, \H, \R, and +\s. Here, leading plus and minus signs serve as incrementation +and decrementation operators, respectively. To negate an expression, +subtract it from zero or include the unary minus in parentheses with its +argument. See Setting Registers, for examples. +

+ + + + + +

A leading | operator indicates a motion relative not to the +drawing position but to a boundary. For horizontal motions, the +measurement specifies a distance relative to a drawing position +corresponding to the beginning of the input line. By default, +tab stops reckon movements in this way. Most escape sequences do not; +| tells them to do so. +

+
+
Mind the \h'1.2i'gap.
+.br
+Mind the \h'|1.2i'gap.
+.br
+Mind the
+\h'|1.2i'gap.
+    ⇒ Mind the             gap.
+    ⇒ Mind the    gap.
+    ⇒ Mind the             gap.
+
+ +

One use of this feature is to define macros whose scope is limited to +the output they format. +

+
+
.\" underline word $1 with trailing punctuation $2
+.de Underline
+.  nop \\$1\l'|0\[ul]'\\$2
+..
+Typographical emphasis is best used
+.Underline sparingly .
+
+ +

In the above example, ‘|0’ specifies a negative motion from the +current position (at the end of the argument just emitted, \$1) +to the beginning of the input line. Thus, the \l escape sequence +in this case draws a line from right to left. A macro call occurs at +the beginning of an input line;38 if the | +operator were omitted, then the underline would be drawn at zero +distance from the current position, producing device-dependent, and +likely undesirable, results. On the ‘ps’ output device, it +underlines the period. +

+

For vertical motions, the | operator specifies a distance from +the first text baseline on the page or in the current +diversion,39 using the current vertical +spacing. +

+
+
A
+.br
+B \Z'C'\v'|0'D
+    ⇒ A D
+    ⇒ B C
+
+ +

In the foregoing example, we’ve used the \Z escape sequence +(see Page Motions) to restore the drawing position after formatting +‘C’, then moved vertically to the first text baseline on the page. +

+
+
Escape sequence: \B'anything'
+
+ + +

Interpolate 1 if anything is a valid numeric expression, +and 0 otherwise. The delimiter need not be a neutral apostrophe; +see Delimiters. +

+ +

You might use \B along with the if request to filter out +invalid macro or string arguments. See Conditionals and Loops. +

+
+
.\" Indent by amount given in first argument; assume ens.
+.de Indent
+.  if \B'\\$1' .in (n;\\$1)
+..
+
+ +

A register interpolated as an operand in a numeric expression must have +an Arabic format; luckily, this is the default. See Assigning Register Formats. +

+ + +

Because spaces separate arguments to requests, spaces are not allowed in +numeric expressions unless the (sub)expression containing them is +surrounded by parentheses. See Invoking Requests, and +Conditionals and Loops. +

+
+
.nf
+.nr a 1+2 + 2+1
+\na
+    error→ expected numeric expression, got a space
+    ⇒ 3
+.nr a 1+(2 + 2)+1
+\na
+    ⇒ 6
+
+ +

The nr request (see Setting Registers) expects its second and +optional third arguments to be numeric expressions; a bare + does +not qualify, so our first attempt got a warning. +

+ + +
+
+
+ +

5.5 Identifiers

+ + +

An identifier labels a GNU troff datum such as a register, +name (macro, string, or diversion), typeface, color, special character, +character class, environment, or stream. Valid identifiers consist of +one or more ordinary characters. + + +An ordinary character is an input character that is not the +escape character, a leader, tab, newline, or invalid as GNU troff +input. +

+ + + + +

Invalid input characters are a subset of control characters (from the +sets “C0 Controls” and “C1 Controls” as Unicode describes them). +When GNU troff encounters one in an identifier, it produces a +warning in category ‘input’ (see Warnings). They are removed +during interpretation: an identifier ‘foo’, followed by an invalid +character and then ‘bar’, is processed as ‘foobar’. +

+

On a machine using the ISO 646, 8859, or 10646 character encodings, +invalid input characters are 0x00, 0x08, 0x0B, +0x0D0x1F, and 0x800x9F. On an +EBCDIC host, they are 0x000x01, 0x08, +0x09, 0x0B, 0x0D0x14, +0x170x1F, and +0x300x3F.40 Some of these code points are used +by GNU troff internally, making it non-trivial to extend the +program to accept UTF-8 or other encodings that use characters from +these ranges.41 +

+

Thus, the identifiers ‘br’, ‘PP’, ‘end-list’, +‘ref*normal-print’, ‘|’, ‘@_’, and ‘!"#$%'()*+,-./’ +are all valid. Discretion should be exercised to prevent confusion. +Identifiers starting with ‘(’ or ‘[’ require care. +

+
+
.nr x 9
+.nr y 1
+.nr (x 2
+.nr [y 3
+.nr sum1 (\n(x + \n[y])
+    error→ a space character is not allowed in an escape
+    error→   sequence parameter
+A:2+3=\n[sum1]
+.nr sum2 (\n((x + \n[[y])
+B:2+3=\n[sum2]
+.nr sum3 (\n[(x] + \n([y)
+C:2+3=\n[sum3]
+    ⇒ A:2+3=1 B:2+3=5 C:2+3=5
+
+ + +

An identifier with a closing bracket (‘]’) in its name can’t be +accessed with bracket-form escape sequences that expect an identifier as +a parameter. For example, ‘\[foo]]’ accesses the glyph ‘foo’, +followed by ‘]’ in whatever the surrounding context is, whereas +‘\C'foo]'’ formats a glyph named ‘foo]’. Similarly, the +identifier ‘(’ can’t be interpolated except with bracket +forms. +

+ + + + +

If you begin a macro, string, or diversion name with either of the +characters ‘[’ or ‘]’, you foreclose use of the grefer +preprocessor, which recognizes ‘.[’ and ‘.]’ as bibliographic +reference delimiters. +

+
+
Escape sequence: \A'anything'
+
+

Interpolate 1 if anything is a valid identifier, and 0 +otherwise. The delimiter need not be a neutral apostrophe; see +Delimiters. Because invalid input characters are removed (see +above), invalid identifiers are empty or contain spaces, tabs, or +newlines. +

+

You can employ \A to validate a macro argument before using it to +construct another escape sequence or identifier. +

+
+
.\" usage: .init-coordinate-pair name val1 val2
+.\" Create a coordinate pair where name!x=val1 and
+.\" name!y=val2.
+.de init-coordinate-pair
+.  if \A'\\$1' \{\
+.    if \B'\\$2' .nr \\$1!x \\$2
+.    if \B'\\$3' .nr \\$1!y \\$3
+.  \}
+..
+.init-coordinate-pair center 5 10
+The center is at (\n[center!x], \n[center!y]).
+.init-coordinate-pair "poi→nt" trash garbage \" ignored
+.init-coordinate-pair point trash garbage \" ignored
+    ⇒ The center is at (5, 10).
+
+ +

In this example, we also validated the numeric arguments; the registers +‘point!x’ and ‘point!y’ remain undefined. See Numeric Expressions for the \B escape sequence. +

+ + + +

How GNU troff handles the interpretation of an undefined +identifier depends on the context. There is no way to invoke an +undefined request; such syntax is interpreted as a macro call instead. +If the identifier is interpreted as a string, macro, or diversion, GNU +troff emits a warning in category ‘mac’, defines it as +empty, and interpolates nothing. If the identifier is interpreted as a +register, GNU troff emits a warning in category ‘reg’, +initializes it to zero, and interpolates that value. See Warnings, +Interpolating Registers, and Strings. Attempting to use an +undefined typeface, special character, color, character class, +environment, or stream generally provokes an error diagnostic. +

+ + + + + +

Identifiers for requests, macros, strings, and diversions share one name +space; special characters and character classes another. No other +object types do. +

+
+
.de xxx
+.  nop foo
+..
+.di xxx
+bar
+.br
+.di
+.
+.xxx
+    ⇒ bar
+
+ +

The foregoing example shows that GNU troff reuses the identifier +‘xxx’, changing it from a macro to a diversion. No warning is +emitted, and the previous contents of ‘xxx’ are lost. +

+ + +
+
+
+ +

5.6 Formatter Instructions

+ + + +

To support documents that require more than filling, automatic line +breaking and hyphenation, adjustment, and supplemental inter-sentence +space, the roff language offers two means of embedding +instructions to the formatter. +

+ +

One is a request, which begins with a control character and takes +up the remainder of the input line. Requests often perform relatively +large-scale operations such as setting the page length, breaking the +line, or starting a new page. They also conduct internal operations +like defining macros. +

+ + +

The other is an escape sequence, which begins with the escape +character and can be embedded anywhere in the input, even in arguments +to requests and other escape sequences. Escape sequences interpolate +special characters, strings, or registers, and handle comparatively +minor formatting tasks like sub- and superscripting. +

+

Some operations, such as font selection and type size alteration, are +available via both requests and escape sequences. +

+ + + +
+
+ +

5.6.1 Control Characters

+ + + + +

The mechanism of using roff’s control characters to invoke +requests and call macros was introduced in Requests and Macros. +Control characters are recognized only at the beginning of an input +line, or at the beginning of the branch of a control structure request; +see Conditionals and Loops. +

+

A few requests cause a break implicitly; use the no-break control +character to prevent the break. Break suppression is its sole +behavioral distinction. Employing the no-break control character to +invoke requests that don’t cause breaks is harmless but poor style. +See Manipulating Filling and Adjustment. +

+ + + + + +

The control ‘.’ and no-break control ‘'’ characters can each +be changed to any ordinary character42 +with the cc and c2 requests, respectively. +

+
+
Request: .cc [o]
+
+

Recognize the ordinary character o as the control character. +If o is absent or invalid, the default control character +‘.’ is selected. The identity of the control character is +associated with the environment (see Environments). +

+ +
+
Request: .c2 [o]
+
+

Recognize the ordinary character o as the no-break control +character. If o is absent or invalid, the default no-break +control character ‘'’ is selected. The identity of the no-break +control character is associated with the environment +(see Environments). +

+ +

When writing a macro, you might wish to know which control character was +used to call it. +

+
+
Register: \n[.br]
+
+

This read-only register interpolates 1 if the currently executing +macro was called using the normal control character and 0 +otherwise. If a macro is interpolated as a string, the .br +register’s value is inherited from the context of the string +interpolation. See Strings. +

+ + + + +

Use this register to reliably intercept requests that imply breaks. +

+
+
.als bp*orig bp
+.de bp
+.  ie \\n[.br] .bp*orig
+.  el          'bp*orig
+..
+
+ +

Testing the .br register outside of a macro definition makes no +sense. +

+ + +
+
+
+ +

5.6.2 Invoking Requests

+ + + +

A control character is optionally followed by tabs and/or spaces and +then an identifier naming a request or macro. The invocation of an +unrecognized request is interpreted as a macro call. Defining a macro +with the same name as a request replaces the request. Deleting a +request name with the rm request makes it unavailable. The +als request can alias requests, permitting them to be wrapped or +non-destructively replaced. See Strings. +

+ + + + + + + + +

There is no inherent limit on argument length or quantity. Most +requests take one or more arguments, and ignore any they do not expect. +A request may be separated from its arguments by tabs or spaces, but +only spaces can separate an argument from its successor. Only one +between arguments is necessary; any excess is ignored. GNU troff +does not allow tabs for argument separation.43 +

+

Generally, a space within a request argument is not relevant, not +meaningful, or is supported by bespoke provisions, as with the tl +request’s delimiters (see Page Layout). Some requests, like +ds, interpret the remainder of the control line as a single +argument. See Strings. +

+ + + + + +

Spaces and tabs immediately after a control character are ignored. +Commonly, authors structure the source of documents or macro files with +them. +

+
+
.de center
+.  if \\n[.br] \
+.    br
+.  ce \\$1
+..
+.
+.
+.de right-align
+.→if \\n[.br] \
+.→→br
+.→rj \\$1
+..
+
+ + + +

If you assign an empty blank line trap, you can separate macro +definitions (or any input lines) with blank lines. +

+
+
.de do-nothing
+..
+.blm do-nothing  \" activate blank line trap
+
+.de center
+.  if \\n[.br] \
+.    br
+.  ce \\$1
+..
+
+
+.de right-align
+.→if \\n[.br] \
+.→→br
+.→rj \\$1
+..
+
+.blm             \" deactivate blank line trap
+
+ +

See Blank Line Traps. +

+ +
+
+
+ +

5.6.3 Calling Macros

+ + + + +

If a macro of the desired name does not exist when called, it is +created, assigned an empty definition, and a warning in category +‘mac’ is emitted. Calling an undefined macro does end a +macro definition naming it as its end macro (see Writing Macros). +

+ +

To embed spaces within a macro argument, enclose the argument in +neutral double quotes ". Horizontal motion escape sequences are +sometimes a better choice for arguments to be formatted as text. +

+

Consider calls to a hypothetical section heading macro ‘uh’. +

+
+
.uh The Mouse Problem
+.uh "The Mouse Problem"
+.uh The\~Mouse\~Problem
+.uh The\ Mouse\ Problem
+
+ + + +

The first line calls uh with three arguments: ‘The’, +‘Mouse’, and ‘Problem’. The remainder call the uh +macro with one argument, ‘The Mouse Problem’. The last solution, +using escaped spaces, can be found in documents prepared for +AT&T troff. It can cause surprise when text is +adjusted, because \SP inserts a fixed-width, +non-breaking space. GNU troff’s \~ escape sequence +inserts an adjustable, non-breaking space.44 +

+ + + + +

The foregoing raises the question of how to embed neutral double quotes +or backslashes in macro arguments when those characters are +desired as literals. In GNU troff, the special character escape +sequence \[rs] produces a backslash and \[dq] a neutral +double quote. +

+

In GNU troff’s AT&T compatibility mode, these +characters remain available as \(rs and \(dq, +respectively. AT&T troff did not consistently define +these special characters, +but its descendants can be made to support them. See Device and Font Description Files. +

+

If even that is not feasible, options remain. To obtain a literal +escape character in a macro argument, you can simply type it if you +change or disable the escape character first. See Using Escape Sequences. Otherwise, you must escape the escape character repeatedly +to a context-dependent extent. See Copy Mode. +

+

For the (neutral) double quote, you have recourse to an obscure +syntactical feature of AT&T troff. Because a double +quote can begin a macro argument, the formatter keeps track of whether +the current argument was started thus, and doesn’t require a space after +the double quote that ends it.45 In +the argument list to a macro, a double quote that isn’t preceded +by a space doesn’t start a macro argument. If not preceded by a +double quote that began an argument, this double quote becomes part of +the argument. Furthermore, within a quoted argument, a pair of adjacent +double quotes becomes a literal double quote. +

+
+
.de eq
+.  tm arg1:\\$1 arg2:\\$2 arg3:\\$3
+.  tm arg4:\\$4 arg5:\\$5 arg6:\\$6
+.. \" 4 backslashes on the next line
+.eq a" "b c" "de"f\\\\g" h""i "j""k"
+    error→ arg1:a" arg2:b c arg3:de
+    error→ arg4:f\g" arg5:h""i arg6:j"k
+
+ +

Apart from the complexity of the rules, this traditional solution has +the disadvantage that double quotes don’t survive repeated argument +expansion in AT&T troff or GNU troff’s +compatibility mode. This can frustrate efforts to pass such arguments +intact through multiple macro calls. +

+
+
.cp 1
+.de eq
+.  tm arg1:\\$1 arg2:\\$2 arg3:\\$3
+.  tm arg4:\\$4 arg5:\\$5 arg6:\\$6
+..
+.de xe
+.  eq \\$1 \\$2 \\$3 \\$4 \\$5 \\$6
+.. \" 8 backslashes on the next line
+.xe a" "b c" "de"f\\\\\\\\g" h""i "j""k"
+    error→ arg1:a" arg2:b arg3:c
+    error→ arg4:de arg5:f\g" arg6:h""i
+
+ + + + + +

Outside of compatibility mode, GNU troff doesn’t exhibit this +problem because it tracks the nesting depth of interpolations. +See Implementation Differences. +

+ +
+
+
+ +

5.6.4 Using Escape Sequences

+ + + +

Whereas requests must occur on control lines, escape sequences can occur +intermixed with text and may appear in arguments to requests, macros, +and other escape sequences. + +An escape sequence is introduced by the escape character, a backslash +\ (but see the ec request below). The next character +selects the escape’s function. +

+

Escape sequences vary in length. Some take an argument, and of those, +some have different syntactical forms for a one-character, +two-character, or arbitrary-length argument. Others accept only +an arbitrary-length argument. In the former scheme, a one-character +argument follows the function character immediately, an opening +parenthesis ‘(’ introduces a two-character argument (no closing +parenthesis is used), and an argument of arbitrary length is enclosed in +brackets ‘[]’. In the latter scheme, the user selects a delimiter +character. A few escape sequences are idiosyncratic, and support both +of the foregoing conventions (\s), designate their own +termination sequence (\?), consume input until the next newline +(\!, \", \#), or support an additional modifier +character (\s again, and \n). As with requests, use of +some escape sequences in source documents may interact poorly with a +macro package you use; consult its documentation to learn of “safe” +sequences or alternative facilities it provides to achieve the desired +result. +

+

If an escape character is followed by a character that does not +identify a defined operation, the escape character is ignored (producing +a diagnostic of the ‘escape’ warning category, which is not enabled +by default) and the following character is processed normally. +

+
+
$ groff -Tps -ww
+.nr N 12
+.ds co white
+.ds animal elephant
+I have \fI\nN \*(co \*[animal]s,\f[]
+said \P.\&\~Pseudo Pachyderm.
+    error→ warning: escape character ignored before 'P'
+    ⇒ I have 12 white elephants, said P. Pseudo Pachyderm.
+
+ +

Escape sequence interpolation is of higher precedence than escape +sequence argument interpretation. This rule affords flexibility in +using escape sequences to construct parameters to other escape +sequences. +

+
+
.ds family C\" Courier
+.ds style I\" oblique
+Choice a typeface \f(\*[family]\*[style]wisely.
+    ⇒ Choose a typeface wisely.
+
+ +

In the above, the syntax form ‘\f(’ accepts only two characters for +an argument; the example works because the subsequent escape sequences +are interpolated before the selection escape sequence argument is +processed, and strings family and style interpolate one +character each.46 +

+

The escape character is nearly always interpreted when encountered; it +is therefore desirable to have a way to interpolate it, disable it, or +change it. +

+ + +
+
Escape sequence: \e
+
+

Interpolate the escape character. +

+ + + +

The \[rs] special character escape sequence formats a backslash +glyph. In macro and string definitions, the input sequences \\ +and \E defer interpretation of escape sequences. See Copy Mode. +

+
+
Request: .eo
+
+ + +

Disable the escape mechanism except in copy mode. Once this request is +invoked, no input character is recognized as starting an escape +sequence in interpretation mode. +

+ +
+
Request: .ec [o]
+
+ + +

Recognize the ordinary character o as the escape character. +If o is absent or invalid, the default escape character +‘\’ is selected. +

+ +

Switching escape sequence interpretation off to define a macro and back +on afterward can obviate the need to double the escape character within +the definition. See Writing Macros. This technique is not available +if your macro needs to interpolate values at the time it is +defined—but many do not. +

+
+
.\" simplified `BR` macro from the man(7) macro package
+.eo
+.de BR
+.  ds result \&
+.  while (\n[.$] >= 2) \{\
+.    as result \fB\$1\fR\$2\"
+.    shift 2
+.  \}
+.  if \n[.$] .as result \fB\$1\"
+\*[result]
+.  rm result
+.  ft R
+..
+.ec
+
+ +
+
Request: .ecs
+
+
Request: .ecr
+
+

The ecs request stores the escape character for recall with +ecr. ecr sets the escape character to ‘\’ if none +has been saved. +

+

Use these requests together to temporarily change the escape character. +

+ +

Using a different escape character, or disabling it, when calling macros +not under your control will likely cause errors, since GNU troff +has no mechanism to “intern” macros—that is, to convert a macro +definition into a form independent of its +representation.47 When a +macro is called, its contents are interpreted literally. +

+ +
+
+
+ +

5.6.5 Delimiters

+ + + + + + + +

Some escape sequences that require parameters use delimiters. The +neutral apostrophe ' is a popular choice and shown in this +document. The neutral double quote " is also commonly seen. +Letters, numerals, and leaders can be used. Punctuation characters +are likely better choices, except for those defined as infix operators +in numeric expressions; see below. +

+
+
\l'1.5i\[bu]' \" draw 1.5 inches of bullet glyphs
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

The following escape sequences don’t take arguments and thus are allowed +as delimiters: +\SP, \%, \|, \^, \{, +\}, \', \`, \-, \_, \!, +\?, \), \/, \,, \&, \:, +\~, \0, \a, \c, \d, \e, +\E, \p, \r, \t, and \u. However, +using them this way is discouraged; they can make the input confusing to +read. +

+ + + + + + + +

A few escape sequences, +\A, +\b, +\o, +\w, +\X, +and \Z, accept a newline as a delimiter. Newlines that serve +as delimiters continue to be recognized as input line terminators. +

+
+
A caf\o
+e\(aa
+in Paris
+    ⇒ A café in Paris
+
+ +

Use of newlines as delimiters in escape sequences is also discouraged. +

+ + + + + + + + + + + +

Finally, the escape sequences \D, \h, \H, +\l, \L, \N, \R, \s, \S, +\v, and \x prohibit many delimiters. +

+
    +
  • + + + + +the numerals 0-9 and the decimal point . + +
  • + + + + + + + + + + + + +the (single-character) operators ‘+-/*%<>=&:()’ + +
  • + +the space and tab characters + +
  • + + + + + + + + + + + + +any escape sequences other than \%, \:, \{, +\}, \', \`, \-, \_, \!, +\/, \c, \e, and \p +
+ +

Delimiter syntax is complex and flexible primarily for historical +reasons; the foregoing restrictions need be kept in mind mainly when +using groff in AT&T compatibility mode. GNU +troff keeps track of the nesting depth of escape sequence +interpolations, so the only characters you need to avoid using as +delimiters are those that appear in the arguments you input, not any +that result from interpolation. Typically, ' works fine. +See Implementation Differences. +

+
+
$ groff -Tps
+.de Mw
+.  nr wd \w'\\$1'
+.  tm "\\$1" is \\n(wd units wide.
+..
+.Mw Wet'suwet'en
+.Mw Wet+200i
+.cp 1 \" turn on compatibility mode
+.Mw Wet'suwet'en
+.Mw Wet'
+.Mw Wet+200i
+    error→ "Wet'suwet'en" is 54740 units wide.
+    error→ "Wet'+200i" is 42610 units wide.
+    error→ "Wet'suwet'en" is 15860 units wide.
+    error→ "Wet'" is 15860 units wide.
+    error→ "Wet'+200i" is 14415860 units wide.
+
+ +

We see here that in compatibility mode, the part of the argument after +the ' delimiter escapes from its context and, if nefariously +crafted, influences the computation of the wd register’s value in +a surprising way. +

+
+
+
+
+ +

5.7 Comments

+ + +

One of the most common forms of escape sequence is the +comment.48 +

+
+
Escape sequence: \"
+
+

Start a comment. Everything up to the next newline is ignored. +

+

This may sound simple, but it can be tricky to keep the comments from +interfering with the appearance of the output. + + +If the escape sequence is to the right of some text or a request, that +portion of the line is ignored, but spaces preceding it are processed +normally by GNU troff. This affects only the ds and +as requests and their variants. +

+ + +

One possibly irritating idiosyncrasy is that tabs should not be used to +vertically align comments in the source document. Tab characters are +not treated as separators between a request name and its first argument, +nor between arguments. +

+ + +

A comment on a line by itself is treated as a blank line, because after +eliminating the comment, that is all that remains. +

+
+
Test
+\" comment
+Test
+    ⇒ Test
+    ⇒
+    ⇒ Test
+
+ +

To avoid this, it is common to combine the empty request with the +comment escape sequence as ‘.\"’, causing the input line to be +ignored. +

+ +

Another commenting scheme sometimes seen is three consecutive single +quotes (''') at the beginning of a line. This works, but GNU +troff emits a warning diagnostic (if enabled) about an undefined +macro (namely ‘''’). +

+ +
+
Escape sequence: \#
+
+

Start a comment; everything up to and including the next newline is +ignored. This groff extension was introduced to avoid the +problems described above. +

+
+
Test
+\# comment
+Test
+    ⇒ Test Test
+
+
+ +
+
Request: .ig [end]
+
+

Ignore input until, in the current conditional block (if +any),49 the macro end is called +at the start of a control line, or the control line ‘..’ is +encountered if end is not specified. ig is parsed as if it +were a macro definition, but its contents are discarded, not +stored.50 +

+
+
hand\c
+.de TX
+fasting
+..
+.ig TX
+This is part of a large block of input that has been
+temporarily(?) commented out.
+We can restore it simply by removing the .ig request and
+the call of its end macro.
+.TX
+
+
+
    ⇒ handfasting
+
+
+ + + +
+
+
+ +

5.8 Registers

+ + +

In the roff language, numbers can be stored in registers. +Many built-in registers exist, supplying anything from the date to +details of formatting parameters. You can also define your own. +See Identifiers, for information on constructing a valid name for a +register. +

+ + + +
+
+ +

5.8.1 Setting Registers

+ + + +

Define registers and update their values with the nr request or +the \R escape sequence. +

+
+
Request: .nr ident value
+
+
Escape sequence: \R'ident value'
+
+

Set register ident to value. If ident doesn’t exist, +GNU troff creates it. In the \R escape sequence, the +delimiter need not be a neutral apostrophe; see Delimiters. It +also does not produce an input token in GNU troff. See gtroff Internals. +

+
+
.nr a (((17 + (3 * 4))) % 4)
+\n[a]
+.\R'a (((17 + (3 * 4))) % 4)'
+\n[a]
+    ⇒ 1 1
+
+ +

(Later, we will discuss additional forms of nr and \R that +can change a register’s value after it is dereferenced but before it is +interpolated. See Auto-increment.) +

+

The complete transparency of \R can cause surprising effects if +you use registers like .k, which get evaluated at the time they +are accessed. +

+
+
.ll 1.6i
+.
+aaa bbb ccc ddd eee fff ggg hhh\R':k \n[.k]'
+.tm :k == \n[:k]
+    ⇒ :k == 126950
+.
+.br
+.
+aaa bbb ccc ddd eee fff ggg hhh\h'0'\R':k \n[.k]'
+.tm :k == \n[:k]
+    ⇒ :k == 15000
+
+ +

If you process this with the PostScript device (-Tps), there will +be a line break eventually after ggg in both input lines. +However, after processing the space after ggg, the partially +collected line is not overfull yet, so GNU troff continues to +collect input until it sees the space (or in this case, the newline) +after hhh. At this point, the line is longer than the line +length, and the line gets broken. +

+

In the first input line, since the \R escape sequence leaves no +traces, the check for the overfull line hasn’t been done yet at the +point where \R gets handled, and you get a value for the +.k register that is even greater than the current line length. +

+

In the second input line, the insertion of \h'0' to cause a +zero-width motion forces GNU troff to check the line length, +which in turn causes the start of a new output line. Now .k +returns the expected value. +

+ +

nr and \R each have two additional special forms to +increment or decrement a register. +

+
+
Request: .nr ident +value
+
+
Request: .nr ident -value
+
Escape sequence: \R'ident +value'
+
+
Escape sequence: \R'ident -value'
+

Increment (decrement) register ident by value. In the +\R escape sequence, the delimiter need not be a neutral +apostrophe; see Delimiters. +

+
+
.nr a 1
+.nr a +1
+\na
+    ⇒ 2
+
+ + +

A leading minus sign in value is always interpreted as a +decrementation operator, not an algebraic sign. To assign a register a +negative value or the negated value of another register, you can +force GNU troff to interpret ‘-’ as a negation or minus, +rather than decrementation, operator: enclose it with its operand in +parentheses or subtract it from zero. +

+
+
.nr a 7
+.nr b 3
+.nr a -\nb
+\na
+    ⇒ 4
+.nr a (-\nb)
+\na
+    ⇒ -3
+.nr a 0-\nb
+\na
+    ⇒ -3
+
+ +

If a register’s prior value does not exist (the register was undefined), +an increment or decrement is applied as if to 0. +

+ +
+
Request: .rr ident
+
+ + +

Remove register ident. If ident doesn’t exist, the request +is ignored. Technically, only the name is removed; the register’s +contents are still accessible under aliases created with aln, if +any. +

+ +
+
Request: .rnn ident1 ident2
+
+ + +

Rename register ident1 to ident2. If ident1 doesn’t +exist, the request is ignored. Renaming a built-in register does not +otherwise alter its properties. +

+ +
+
Request: .aln new old
+
+ + + +

Create an alias new for an existing register old, causing +the names to refer to the same stored object. If old is +undefined, a warning in category ‘reg’ is produced and the request +is ignored. See Warnings, for information about the enablement and +suppression of warnings. +

+ + + +

To remove a register alias, invoke rr on its name. A register’s +contents do not become inaccessible until it has no more names. +

+ + +
+
+
+ +

5.8.2 Interpolating Registers

+ + + +

Register contents are interpolated with the \n escape sequence. +

+
+
Escape sequence: \ni
+
+
Escape sequence: \n(id
+
Escape sequence: \n[ident]
+
+ + + +

Interpolate register with name ident (one-character +name i, two-character name id). \n is +interpreted even in copy mode (see Copy Mode). If the register is +undefined, it is created and assigned a value of ‘0’, that +value is interpolated, and a warning in category ‘reg’ is emitted. +See Warnings, for information about the enablement and suppression of +warnings. +

+
+
.nr a 5
+.nr as \na+\na
+\n(as
+    ⇒ 10
+
+ +
+
.nr a1 5
+.nr ab 6
+.ds str b
+.ds num 1
+\n[a\n[num]]
+    ⇒ 5
+\n[a\*[str]]
+    ⇒ 6
+
+
+ + +
+
+
+ +

5.8.3 Auto-increment

+ + + + +

Registers can also be incremented or decremented by a configured amount +at the time they are interpolated. The value of the increment is +specified with a third argument to the nr request, and a special +interpolation syntax is used to alter and then retrieve the register’s +value. Together, these features are called +auto-increment.51 +

+
+
Request: .nr ident value incr
+
+ +

Set register ident to value and its auto-incrementation +amount to to incr. The \R escape sequence doesn’t support +an incr argument. +

+ +

Auto-incrementation is not completely automatic; the \n +escape sequence in its basic form never alters the value of a register. +To apply auto-incrementation to a register, interpolate it with +‘\ną’. +

+
+
Escape sequence: \n+i
+
+
Escape sequence: \n-i
+
Escape sequence: \n+(id
+
Escape sequence: \n-(id
+
Escape sequence: \n+[ident]
+
Escape sequence: \n-[ident]
+

Increment or decrement ident (one-character +name i, two-character name id) by the register’s +auto-incrementation value and then interpolate the new register value. +If ident has no auto-incrementation value, interpolate as with +\n. +

+ +
+
.nr a 0 1
+.nr xx 0 5
+.nr foo 0 -2
+\n+a, \n+a, \n+a, \n+a, \n+a
+.br
+\n-(xx, \n-(xx, \n-(xx, \n-(xx, \n-(xx
+.br
+\n+[foo], \n+[foo], \n+[foo], \n+[foo], \n+[foo]
+    ⇒ 1, 2, 3, 4, 5
+    ⇒ -5, -10, -15, -20, -25
+    ⇒ -2, -4, -6, -8, -10
+
+ + + +

To change the increment value without changing the value of a register, +assign the register’s value to itself by interpolating it, and specify +the desired increment normally. Apply an increment of ‘0’ to +disable auto-incrementation of the register. +

+ +
+
+
+ +

5.8.4 Assigning Register Formats

+ + + + +

A writable register’s value can be interpolated in several number +formats. By default, conventional Arabic numerals are used. +Other formats see use in sectioning and outlining schemes and +alternative page numbering arrangements. +

+
+
Request: .af reg fmt
+
+

Use number format fmt when interpolating register reg. +Valid number formats are as follows. +

+
+
0
+

Arabic numerals 0, 1, 2, and so on. +Any decimal digit is equivalent to ‘0’; the formatter merely counts +the digits specified. Multiple Arabic numerals in fmt cause +interpolations to be zero-padded on the left if necessary to at least as +many digits as specified (interpolations never truncate a register +value). A register with format ‘00’ interpolates values 1, 2, 3 as +‘01’, ‘02’, ‘03’. The default format for all writable +registers is ‘0’. +

+
+
I
+
+

Uppercase Roman numerals: 0, I, II, III, IV, ... +

+
+
i
+

Lowercase Roman numerals: 0, i, ii, iii, iv, ... +

+
+
A
+

Uppercase letters: 0, A, B, C, …, Z, AA, AB, ... +

+
+
a
+

Lowercase letters: 0, a, b, c, …, z, aa, ab, ... +

+
+ +

Omitting fmt causes a warning in category ‘missing’. +See Warnings, for information about the enablement and suppression of +warnings. Specifying an unrecognized format is an error. +

+

Zero values are interpolated as ‘0’ in non-Arabic formats. +Negative quantities are prefixed with ‘-’ irrespective of format. +In Arabic formats, the sign supplements the field width. If reg +doesn’t exist, it is created with a zero value. +

+
+
.nr a 10
+.af a 0           \" the default format
+\na,
+.af a I
+\na,
+.af a 321
+.nr a (-\na)
+\na,
+.af a a
+\na
+    ⇒ 10, X, -010, -j
+
+ + + + + +

The representable extrema in the ‘i’ and ‘I’ formats +correspond to Arabic ą39,999. GNU troff uses ‘w’ and +‘z’ to represent 5,000 and 10,000 in Roman numerals, respectively, +following the convention of AT&T troff—currently, the +correct glyphs for Roman numerals five thousand (U+2181) and ten +thousand (U+2182) are not used. +

+ + +

Assigning the format of a read-only register is an error. Instead, copy +the read-only register’s value to, and assign the format of, a writable +register. +

+ +
+
Escape sequence: \gr
+
+
Escape sequence: \g(rg
+
Escape sequence: \g[reg]
+
+ +

Interpolate the format of the register reg (one-character +name r, two-character name rg). Zeroes represent +Arabic formats. If reg is not defined, reg is not created +and nothing is interpolated. \g is interpreted even in copy mode +(see Copy Mode). +

+ + + +

GNU troff interprets only Arabic numerals. The Roman numeral or +alphabetic formats cannot be used as operands to arithmetic operators in +expressions (see Numeric Expressions). For instance, it may be +desirable to test the page number independently of its format. +

+
+
.af % i \" front matter
+.de header-trap
+.  \" To test the page number, we need it in Arabic.
+.  ds saved-page-number-format \\g%\"
+.  af % 0
+.  nr page-number-in-decimal \\n%
+.  af % \\*[saved-page-number-format]
+.  ie \\n[page-number-in-decimal]=1 .do-first-page-stuff
+.  el \{\
+.    ie o .do-odd-numbered-page-stuff
+.    el   .do-even-numbered-page-stuff
+.  \}
+.  rm saved-page-number-format
+..
+.wh 0 header-trap
+
+ + +
+
+
+ +

5.8.5 Built-in Registers

+ + + +

Predefined registers whose identifiers start with a dot are read-only. +Many are Boolean-valued, interpolating a true or false value testable +with the if, ie, or while requests. Some read-only +registers are string-valued, meaning that they interpolate text. +

+ + + +

Caution: Built-in registers are subject to removal like +others; once removed, they can be recreated only as normal writable +registers and will not reflect formatter state. +

+

A register name (without the dot) is often associated with a request of +the same name. A complete listing of all built-in registers can be +found in Register Index. +

+

We present here a few built-in registers that are not described +elsewhere in this manual; they have to do with invariant properties of +GNU troff, or obtain information about the formatter’s +command-line options, processing progress, or the operating environment. +

+
+
\n[.A]
+
+ +

Approximate output is being formatted (Boolean-valued); see +groff -a option (Options). +

+
+
\n[.c]
+
+
+
\n[c.]
+
+ +

Input line number. ‘c.’ is a writable synonym, +affecting subsequent interpolations of both ‘.c’ and ‘c.’. +

+
+
\n[.F]
+
+ +

Name of input file (string-valued). +

+
+
\n[.g]
+
+ +

Always true in GNU troff (Boolean-valued). Documents can use +this to ask the formatter if it claims groff compatibility. +

+
+
\n[.P]
+

Output page selection status (Boolean-valued); see groff +-o option (Options). +

+
+
\n[.R]
+
+ +

Count of available unused registers; always 10,000 in GNU +troff.52 +

+
+
\n[.T]
+

Indicator of output device selection (Boolean-valued); see +groff -T option (Options). +

+
+
\n[.U]
+
+ + + +

Unsafe mode enablement status (Boolean-valued); see groff +-U option (Options). +

+
+
\n[.x]
+
+ +

Major version number of the running GNU troff formatter. For +example, if the version number is 1.23.0, then .x +contains ‘1’. +

+
+
\n[.y]
+
+ +

Minor version number of the running GNU troff formatter. For +example, if the version number is 1.23.0, then .y +contains ‘23’. +

+
+
\n[.Y]
+
+

Revision number of the running GNU troff formatter. For example, +if the version number is 1.23.0, then .Y contains ‘0’. +

+
+
\n[$$]
+
+ + + +

Process identifier (PID) of the GNU troff program in its +operating environment. +

+
+ +

Date- and time-related registers are set per the local time as +determined by localtime(3) when the formatter launches. This +initialization can be overridden by SOURCE_DATE_EPOCH and +TZ; see Environment. +

+
+
\n[seconds]
+
+ + +

Count of seconds elapsed in the minute (0–60).

+
+
\n[minutes]
+
+ + +

Count of minutes elapsed in the hour (0–59). +

+
+
\n[hours]
+
+ + +

Count of hours elapsed since midnight (0–23). +

+
+
\n[dw]
+
+ +

Day of the week (1–7; 1 is Sunday). +

+
+
\n[dy]
+
+ +

Day of the month (1–31). +

+
+
\n[mo]
+
+ +

Month of the year (1–12). +

+
+
\n[year]
+
+ +

Gregorian year. +

+ + +
+
\n[yr]
+

Gregorian year minus 1900. This register is incorrectly documented +in the AT&T troff manual as storing the last two digits +of the current year. That claim stopped being true in 2000. Old +troff input that looks like: +

+
+
'\" The year number is a surprise after 1999.
+This document was formatted in 19\n(yr.
+
+ +

can be corrected to: +

+
+
This document was formatted in \n[year].
+
+ +

or, for portability across many roff programs, to the following. +

+
+
.nr y4 1900+\n(yr
+This document was formatted in \n(y4.
+
+
+
+ + + +
+
+
+
+ +

5.9 Manipulating Filling and Adjustment

+ + + + + + + + + + + + + + + + + + + +

When an output line is pending (see below), a break moves the drawing +position to the beginning of the next text baseline, interrupting +filling. Various ways of causing breaks were shown in Breaking. +The br request likewise causes a break. Several other requests +imply breaks: bp, ce, cf, fi, fl, +in, nf, rj, sp, ti, and trf. +If the no-break control character is used with any of these requests, +GNU troff suppresses the break; instead the requested operation +takes effect at the next break. ‘'br’ does nothing. +

+
+
.ll 55n
+This line is normally filled and adjusted.
+.br
+A line's alignment is decided
+'ce \" Center the next input line (no break).
+when it is output.
+This line returns to normal filling and adjustment.
+    ⇒ This line is normally filled and adjusted.
+    ⇒    A line's alignment is decided when it is output.
+    ⇒ This line returns to normal filling and adjustment.
+
+ + + + + +

Output line properties like page offset, indentation, adjustment, and +even the location of its text baseline, are not determined until the +line has been broken. An output line is said to be pending if +some input has been collected but an output line corresponding to it has +not yet been written; such an output line is also termed partially +collected. If no output line is pending, it is as if a break has +already happened; additional breaks, whether explicit or implicit, have +no effect. If the vertical drawing position is negative—as it is when +the formatter starts up—a break starts a new page (even if no output +line is pending) unless an end-of-input macro is being interpreted. +See End-of-input Traps. +

+
+
Request: .br
+
+

Break the line: emit any pending output line without adjustment. +

+
+
foo bar
+.br
+baz
+'br
+qux
+    ⇒ foo bar
+    ⇒ baz qux
+
+
+ +

Sometimes you want to prevent a break within a phrase or between a +quantity and its units. +

+
+
Escape sequence: \~
+
+ + +

Insert an unbreakable space that is adjustable like an ordinary space. +It is discarded from the end of an output line if a break is forced. +

+
+
Set the output speed to\~1.
+There are 1,024\~bytes in 1\~KiB.
+J.\~F.\~Ossanna wrote the original CSTR\~#54.
+
+
+ +

By default, GNU troff fills text and adjusts it to reach the +output line length. The nf request disables filling; the +fi request reënables it. +

+
+
Request: .fi
+
+
Register: \n[.u]
+
+ + + + +

Enable filling of output lines; a pending output line is broken. The +read-only register .u is set to 1. The filling enablement +status, sometimes called fill mode, is associated with the +environment (see Environments). See Line Continuation, for +interaction with the \c escape sequence. +

+ +
+
Request: .nf
+
+ + + + + + +

Disable filling of output lines: the output line length (see Line Layout) is ignored and output lines are broken where the input lines +are. A pending output line is broken and adjustment is suppressed. The +read-only register .u is set to 0. The filling enablement +status is associated with the environment (see Environments). See +Line Continuation, for interaction with the \c escape +sequence. +

+ +
+
Request: .ad [mode]
+
+
Register: \n[.j]
+
+

Enable output line adjustment in mode, taking effect when the +pending (or next) output line is broken. Adjustment is suppressed when +filling is. mode can have one of the following values. +

+
+
b
+
n
+

Adjust “normally”: if the output line does not consume the distance +between the indentation and the configured output line length, GNU +troff stretches adjustable spaces within the line until that +length is reached. When the indentation is zero, this mode spreads the +line to both the left and right margins. This is the GNU troff +default. +

+
+
c
+

Center filled text. Contrast with the ce request, which centers +text without filling it. +

+
+
l
+

Align text to the left without adjusting it. +

+
+
r
+

Align text to the right without adjusting it. +

+
+ +

mode can also be a value previously stored in the .j +register. Using ad without an argument is the same as ‘.ad +\n[.j]’; unless filling is disabled, GNU troff resumes adjusting +lines in the same way it did before adjustment was disabled by +invocation of the na request. +

+ +

The adjustment mode and enablement status are encoded in the read-only +register .j. These parameters are associated with the +environment (see Environments). +

+

The value of .j for any adjustment mode is an implementation +detail and should not be relied upon as a programmer’s interface. Do +not write logic to interpret or perform arithmetic on it. +

+
+
.ll 48n
+.de AD
+.  br
+.  ad \\$1
+..
+.de NA
+.  br
+.  na
+..
+left
+.AD r
+.nr ad \n(.j
+right
+.AD c
+center
+.NA
+left
+.AD
+center
+.AD \n(ad
+right
+
+
+
    ⇒ left
+    ⇒                                            right
+    ⇒                      center
+    ⇒ left
+    ⇒                      center
+    ⇒                                            right
+
+
+ +
+
Request: .na
+
+

Disable output line adjustment. This produces the same output as +left-alignment, but the value of the adjustment mode register .j +is altered differently. The adjustment mode and enablement status are +associated with the environment (see Environments). +

+ +
+
Request: .brp
+
+
Escape sequence: \p
+
+

Break, adjusting the line per the current adjustment mode. \p +schedules a break with adjustment at the next word boundary. The escape +sequence is itself neither a break nor a space of any kind; it can thus +be placed in the middle of a word to cause a break at the end of that +word. +

+

Breaking with immediate adjustment can produce ugly results since GNU +troff doesn’t have a sophisticated paragraph-building algorithm, +as TeX has, for example. Instead, GNU troff fills and adjusts +a paragraph line by line. +

+
+
.ll 4.5i
+This is an uninteresting sentence.
+This is an uninteresting sentence.\p
+This is an uninteresting sentence.
+
+ +

is formatted as follows. +

+
+
This  is  an uninteresting sentence.  This is
+an          uninteresting           sentence.
+This is an uninteresting sentence.
+
+
+ + + + +

To clearly present the next couple of requests, we must introduce the +concept of “productive” input lines. A productive input line is +one that directly produces formatted output. Text lines produce +output,53 as do control +lines containing requests like tl or escape sequences like +\D. Macro calls are not directly productive, and thus not +counted, but their interpolated contents can be. Empty requests, and +requests and escape sequences that define registers or strings or alter +the formatting environment (as with changes to the size, face, height, +slant, or color of the type) are not productive. We will also preview +the output line continuation escape sequence, \c, which +“connects” two input lines that would otherwise be counted separately. +54 +

+
+
.de hello
+Hello, world!
+..
+.ce \" center output of next productive input line
+.
+.nr junk-reg 1
+.ft I
+Chorus: \c
+.ft
+.hello
+Went the day well?
+  ⇒                  Chorus: Hello, world!
+  ⇒ Went the day well?
+
+ +
+
Request: .ce [n]
+
+
Register: \n[.ce]
+
+ + + +

Break (unless the no-break control character is used), center the output +of the next n productive input lines with respect to the line +length and indentation without filling, then break again regardless of +the invoking control character. +If the argument is not positive, centering is disabled. Omitting the +argument implies an n of ‘1’. The count of lines remaining +to be centered is stored in the read-only register .ce and is +associated with the environment (see Environments). +

+ +

While the ‘.ad c request also centers text, it fills the text +as well. +

+
+
.de FR
+This is a small text fragment that shows the differences
+between the `.ce' and the `.ad c' requests.
+..
+.ll 4i
+.ce 1000
+.FR
+.ce 0
+
+.ad c
+.FR
+    ⇒ This is a small text fragment that shows
+    ⇒              the differences
+    ⇒ between the ‘.ce’ and the ‘.ad c’ requests.
+    ⇒
+    ⇒ This is a small text fragment that shows
+    ⇒  the differences between the ‘.ce’ and
+    ⇒         the ‘.ad c’ requests.
+
+ +

The previous example illustrates a common idiom of turning centering on +for a quantity of lines far in excess of what is required, and off again +after the text to be centered. This technique relieves humans of +counting lines for requests that take a count of input lines as an +argument. +

+ +
+
Request: .rj [n]
+
+
Register: \n[.rj]
+
+ + + +

Break (unless the no-break control character is used), align the output +of the next n productive input lines to the right margin without +filling, then break again regardless of the control character. +If the argument is not positive, right-alignment is disabled. Omitting +the argument implies an n of ‘1’. The count of lines +remaining to be right-aligned is stored in the read-only register +.rj and is associated with the environment +(see Environments). +

+
+
.ll 49n
+.rj 3
+At first I hoped that such a technically unsound
+project would collapse but I soon realized it was
+doomed to success. \[em] C. A. R. Hoare
+    ⇒  At first I hoped that such a technically unsound
+    ⇒ project would collapse but I soon realized it was
+    ⇒              doomed to success. -- C. A. R. Hoare
+
+
+ +
+
Request: .ss word-space-size [additional-sentence-space-size]
+
+
Register: \n[.ss]
+
+
Register: \n[.sss]
+
+ + + + + + + +

Set the sizes of spaces between words and +sentences55 in twelfths +of font’s space width (typically one-fourth to one-third em for Western +scripts). The default for both parameters is 12. Negative values +are erroneous. + + + +The first argument is a minimum; if an output line undergoes adjustment, +such spaces may increase in width. + + + +The optional second argument sets the amount of additional space +separating sentences on the same output line. If omitted, this amount +is set to word-space-size. The request is ignored if there are no +parameters. +

+ + +

Additional inter-sentence space is used only if the output line is not +full when the end of a sentence occurs in the input. If a sentence ends +at the end of an input line, then both an inter-word space and an +inter-sentence space are added to the output; if two spaces follow the +end of a sentence in the middle of an input line, then the second space +becomes an inter-sentence space in the output. Additional +inter-sentence space is not adjusted, but the inter-word space that +always precedes it may be. Further input spaces after the second, if +present, are adjusted as normal. +

+

The read-only registers .ss and .sss hold the minimal +inter-word space and additional inter-sentence space amounts, +respectively. These parameters are part of the environment +(see Environments), and rounded down to the nearest multiple +of 12 on terminals. +

+ + + +

The ss request can insert discardable horizontal space; that is, +space that is discarded at a break. For example, some footnote styles +collect the notes into a single paragraph with large gaps between +each note. +

+
+
.ll 48n
+1.\~J. Fict. Ch. Soc. 6 (2020), 3\[en]14.
+.ss 12 48 \" applies to next sentence ending
+Reprints no longer available through FCS.
+.ss 12 \" go back to normal
+2.\~Better known for other work.
+    ⇒ 1.  J.  Fict. Ch. Soc. 6 (2020), 3-14.  Reprints
+    ⇒ no longer available through FCS.      2.  Better
+    ⇒ known for other work.
+
+ +

If undiscardable space is required, use the \h escape +sequence. +

+ + + +
+
+
+ +

5.10 Manipulating Hyphenation

+ + + + + +

When filling, GNU troff hyphenates words as needed at +user-specified and automatically determined hyphenation points. The +machine-driven determination of hyphenation points in words requires +algorithms and data, and is susceptible to conventions and preferences. +Before tackling such automatic hyphenation, let us consider how +hyphenation points can be set explicitly. +

+ + + + +

Explicitly hyphenated words such as “mother-in-law” are eligible for +breaking after each of their hyphens. Relatively few words in a +language offer such obvious break points, however, and automatic +detection of syllabic (or phonetic) boundaries for hyphenation is not +perfect,56 particularly for +unusual words found in technical literature. We can instruct GNU +troff how to hyphenate specific words if the need arises. +

+ +
+
Request: .hw word …
+
+

Define each hyphenation exception word with each hyphen ‘-’ +in the word indicating a hyphenation point. For example, the request +

+
+
.hw in-sa-lub-rious alpha
+
+ +

marks potential hyphenation points in “insalubrious”, and prevents +“alpha” from being hyphenated at all. +

+

Besides the space character, any character whose hyphenation code is +zero can be used to separate the arguments of hw (see the +hcode request below). In addition, this request can be used more +than once. +

+ +

Hyphenation points specified with hw are not subject to the +within-word placement restrictions imposed by the hy request (see +below). +

+

Hyphenation exceptions specified with the hw request are +associated with the hyphenation language (see the hla request +below) and environment (see Environments); invoking the hw +request in the absence of a hyphenation language is an error. +

+

The request is ignored if there are no parameters. +

+ +

These are known as hyphenation exceptions in the expectation +that most users will avail themselves of automatic hyphenation; these +exceptions override any rules that would normally apply to a word +matching a hyphenation exception defined with hw. +

+

Situations also arise when only a specific occurrence of a word needs +its hyphenation altered or suppressed, or when a URL or similar string +needs to be breakable in sensible places without hyphenation. +

+
+
Escape sequence: \%
+
+
Escape sequence: \:
+
+ + + + +

To tell GNU troff how to hyphenate words as they occur in input, +use the \% escape sequence; it is the default hyphenation +character. Each instance within a word indicates to GNU troff +that the word may be hyphenated at that point, while prefixing a word +with this escape sequence prevents it from being otherwise hyphenated. +This mechanism affects only that occurrence of the word; to change the +hyphenation of a word for the remainder of input processing, use the +hw request. +

+ + + +

GNU troff regards the escape sequences \X and \Y as +starting a word; that is, the \% escape sequence in, say, +‘\X'...'\%foobar or ‘\Y'...'\%foobar no longer +prevents hyphenation of ‘foobar’ but inserts a hyphenation point +just prior to it; most likely this isn’t what you want. +See Postprocessor Access. +

+ + + + + + +

\: inserts a non-printing break point; that is, a word can break +there, but the soft hyphen glyph (see below) is not written to the +output if it does. This escape sequence is an input word boundary, so +the remainder of the word is subject to hyphenation as normal. +

+

You can combine \: and \% to control breaking of a file +name or URL, or to permit hyphenation only after certain explicit +hyphens within a word. +

+
+
The \%Lethbridge-Stewart-\:\%Sackville-Baggins divorce
+was, in retrospect, inevitable once the contents of
+\%/var/log/\:\%httpd/\:\%access_log on the family web
+server came to light, revealing visitors from Hogwarts.
+
+
+ +
+
Request: .hc [char]
+
+

Change the hyphenation character to char. This character then +works as the \% escape sequence normally does, and thus no longer +appears in the output.57 Without an +argument, hc resets the hyphenation character to \% (the +default). The hyphenation character is associated with the environment +(see Environments). +

+ +
+
Request: .shc [c]
+
+ + + + + + +

Set the soft hyphen character, inserted when a word is hyphenated +automatically or at a hyphenation character, to the ordinary or special +character c.58 If the argument is omitted, the soft +hyphen character is set to the default, \[hy]. If no glyph for +c exists in the font in use at a potential hyphenation point, then +the line is not broken there. Neither character definitions (specified +with the char and similar requests) nor translations (specified +with the tr request) are applied to c. +

+ + + +

Several requests influence automatic hyphenation. Because conventions +vary, a variety of hyphenation modes is available to the hy +request; these determine whether hyphenation will apply to a +word prior to breaking a line at the end of a page (more or less; see +below for details), and at which positions within that word +automatically determined hyphenation points are permissible. The places +within a word that are eligible for hyphenation are determined by +language-specific data and lettercase relationships. Furthermore, +hyphenation of a word might be suppressed due to a limit on +consecutive hyphenated lines (hlm), a minimum line length +threshold (hym), or because the line can instead be adjusted with +additional inter-word space (hys). +

+ +
+
Request: .hy [mode]
+
+
Register: \n[.hy]
+
+

Set automatic hyphenation mode to mode, an integer encoding +conditions for hyphenation; if omitted, ‘1’ is implied. The +hyphenation mode is available in the read-only register ‘.hy’; it +is associated with the environment (see Environments). The default +hyphenation mode depends on the localization file loaded when GNU +troff starts up; see the hpf request below. +

+

Typesetting practice generally does not avail itself of every +opportunity for hyphenation, but the details differ by language and site +mandates. The hyphenation modes of AT&T troff were +implemented with English-language publishing practices of the 1970s in +mind, not a scrupulous enumeration of conceivable parameters. GNU +troff extends those modes such that finer-grained control is +possible, favoring compatibility with older implementations over a more +intuitive arrangement. The means of hyphenation mode control is a set +of numbers that can be added up to encode the behavior +sought.59 The entries in the +following table are termed values; the sum of the desired +values is the mode. +

+
+
0
+

disables hyphenation. +

+
+
1
+

enables hyphenation except after the first and before the last character +of a word. +

+
+ +

The remaining values “imply” 1; that is, they enable hyphenation +under the same conditions as ‘.hy 1’, and then apply or lift +restrictions relative to that basis. +

+
+
2
+

disables hyphenation of the last word on a page,60 even for explicitly hyphenated words. +

+
+
4
+

disables hyphenation before the last two characters of a word. +

+
+
8
+

disables hyphenation after the first two characters of a word. +

+
+
16
+

enables hyphenation before the last character of a word. +

+
+
32
+

enables hyphenation after the first character of a word. +

+
+ +

Apart from value 2, restrictions imposed by the hyphenation mode +are not respected for words whose hyphenations have been +specified with the hyphenation character (‘\%’ by default) or the +hw request. +

+

Nonzero values in the previous table are additive. For example, +mode 12 causes GNU troff to hyphenate neither the last two +nor the first two characters of a word. Some values cannot be used +together because they contradict; for instance, values 4 and 16, +and values 8 and 32. As noted, it is superfluous to add 1 to any +non-zero even mode. +

+ + +

The automatic placement of hyphens in words is determined by +pattern files, which are derived from TeX and available for +several languages. The number of characters at the beginning of a word +after which the first hyphenation point should be inserted is determined +by the patterns themselves; it can’t be reduced further without +introducing additional, invalid hyphenation points (unfortunately, this +information is not part of a pattern file—you have to know it in +advance). The same is true for the number of characters at the end of +a word before the last hyphenation point should be inserted. For +example, you can supply the following input to ‘echo $(nroff)’. +

+
+
.ll 1
+.hy 48
+splitting
+
+ +

You will get +

+
+
s- plit- t- in- g
+
+ +

instead of the correct ‘split- ting’. English patterns as distributed +with GNU troff need two characters at the beginning and three +characters at the end; this means that value 4 of hy is +mandatory. Value 8 is possible as an additional restriction, but +values 16 and 32 should be avoided, as should mode 1. +Modes 4 and 6 are typical. +

+

A table of left and right minimum character counts for hyphenation as +needed by the patterns distributed with GNU troff follows; see +the groff_tmac(5) man page for more information on GNU +troff’s language macro files. +

+ + + + + + + + + + +
languagepattern nameleft minright min
Czechcs22
Englishen23
Frenchfr23
German traditionaldet22
German reformedden22
Italianit22
Swedishsv12
+ +

Hyphenation exceptions within pattern files (i.e., the words within a +TeX \hyphenation group) obey the hyphenation restrictions +given by hy. +

+ +
+
Request: .nh
+
+

Disable automatic hyphenation; i.e., set the hyphenation mode to 0 +(see above). The hyphenation mode of the last call to hy is not +remembered. +

+ +
+
Request: .hpf pattern-file
+
+
Request: .hpfa pattern-file
+
+
Request: .hpfcode a b [c d] …
+
+ + +

Read hyphenation patterns from pattern-file, which is sought +in the same way that macro files are with the mso request or the +-mname command-line option to groff. The +pattern-file should have the same format as (simple) TeX +pattern files. More specifically, the following scanning rules are +implemented. +

+
    +
  • A percent sign starts a comment (up to the end of the line) even if +preceded by a backslash. + +
  • “Digraphs” like \$ are not supported. + +
  • ^^xx (where each x is 0–9 or a–f) and +^^c (character c in the code point range 0–127 +decimal) are recognized; other uses of ^ cause an error. + +
  • No macro expansion is performed. + +
  • hpf checks for the expression \patterns{…} +(possibly with whitespace before or after the braces). Everything +between the braces is taken as hyphenation patterns. Consequently, +{ and } are not allowed in patterns. + +
  • Similarly, \hyphenation{…} gives a list of hyphenation +exceptions. + +
  • \endinput is recognized also. + +
  • For backward compatibility, if \patterns is missing, the whole +file is treated as a list of hyphenation patterns (except that the +% character is recognized as the start of a comment). +
+ +

The hpfa request appends a file of patterns to the current list. +

+

The hpfcode request defines mapping values for character codes in +pattern files. It is an older mechanism no longer used by GNU +troff’s own macro files; for its successor, see hcode +below. hpf or hpfa apply the mapping after reading the +patterns but before replacing or appending to the active list of +patterns. Its arguments are pairs of character codes—integers from 0 +to 255. The request maps character code a to +code b, code c to code d, and so on. +Character codes that would otherwise be invalid in GNU troff can +be used. By default, every code maps to itself except those for letters +‘A’ to ‘Z’, which map to those for ‘a’ to ‘z’. +

+ + + + + + + + + + +

The set of hyphenation patterns is associated with the language set by +the hla request (see below). The hpf request is usually +invoked by a localization file loaded by the troffrc +file.61 +

+

A second call to hpf (for the same language) replaces the +hyphenation patterns with the new ones. Invoking hpf or +hpfa causes an error if there is no hyphenation language. If no +hpf request is specified (either in the document, in a file +loaded at startup, or in a macro package), GNU troff won’t +automatically hyphenate at all. +

+ +
+
Request: .hcode c1 code1 [c2 code2] …
+
+ + +

Set the hyphenation code of character c1 to code1, that of +c2 to code2, and so on. A hyphenation code must be an +ordinary character (not a special character escape sequence) other than +a digit or a space. The request is ignored if given no arguments. +

+

For hyphenation to work, hyphenation codes must be set up. At +startup, GNU troff assigns hyphenation codes to the letters +‘a’–‘z’ (mapped to themselves), to the letters +‘A’–‘Z’ (mapped to ‘a’–‘z’), and zero to all other +characters. Normally, hyphenation patterns contain only lowercase +letters which should be applied regardless of case. In other words, +they assume that the words ‘FOO’ and ‘Foo’ should be hyphenated exactly +as ‘foo’ is. The hcode request extends this principle to letters +outside the Unicode basic Latin alphabet; without it, words containing +such letters won’t be hyphenated properly even if the corresponding +hyphenation patterns contain them. +

+

For example, the following hcode requests are necessary to assign +hyphenation codes to the letters ‘ÄäÖöÜüß’, needed for German. +

+
+
.hcode ä ä  Ä ä
+.hcode ö ö  Ö ö
+.hcode ü ü  Ü ü
+.hcode ß ß
+
+ +

Without these assignments, GNU troff treats the German word +‘Kindergärten’ (the plural form of ‘kindergarten’) as two words +‘kinderg’ and ‘rten’ because the hyphenation code of the +umlaut a is zero by default, just like a space. There is a German +hyphenation pattern that covers ‘kinder’, so GNU troff finds +the hyphenation ‘kin-der’. The other two hyphenation points +(‘kin-der-gär-ten’) are missed. +

+ +
+
Request: .hla lang
+
+
Register: \n[.hla]
+
+ + + + +

Set the hyphenation language to lang. Hyphenation exceptions +specified with the hw request and hyphenation patterns and +exceptions specified with the hpf and hpfa requests are +associated with the hyphenation language. The hla request is +usually invoked by a localization file, which is turn loaded by the +troffrc or troffrc-end file; see the hpf request +above. +

+ +

The hyphenation language is available in the read-only string-valued +register ‘.hla’; it is associated with the environment +(see Environments). +

+ +
+
Request: .hlm [n]
+
+
Register: \n[.hlm]
+
+
Register: \n[.hlc]
+
+ + + + + +

Set the maximum quantity of consecutive hyphenated lines to n. If +n is negative, there is no maximum. If omitted, n +is −1. This value is associated with the environment +(see Environments). Only lines output from a given environment +count toward the maximum associated with that environment. Hyphens +resulting from \% are counted; explicit hyphens are not. +

+ + +

The .hlm read-only register stores this maximum. The count of +immediately preceding consecutive hyphenated lines is available in the +read-only register .hlc. +

+ +
+
Request: .hym [length]
+
+
Register: \n[.hym]
+
+ + + +

Set the (right) hyphenation margin to length. If the adjustment +mode is not ‘b’ or ‘n’, the line is not hyphenated if it is +shorter than length. Without an argument, the hyphenation margin +is reset to its default value, 0. The default scaling unit is ‘m’. +The hyphenation margin is associated with the environment +(see Environments). +

+

A negative argument resets the hyphenation margin to zero, emitting a +warning in category ‘range’. +

+ +

The hyphenation margin is available in the .hym read-only +register. +

+ +
+
Request: .hys [hyphenation-space]
+
+
Register: \n[.hys]
+
+ + + +

Suppress hyphenation of the line in adjustment modes ‘b’ or +‘n’ if it can be justified by adding no more than +hyphenation-space extra space to each inter-word space. Without +an argument, the hyphenation space adjustment threshold is set to its +default value, 0. The default scaling unit is ‘m’. The +hyphenation space adjustment threshold is associated with the +environment (see Environments). +

+

A negative argument resets the hyphenation space adjustment threshold to +zero, emitting a warning in category ‘range’. +

+ +

The hyphenation space adjustment threshold is available in the +.hys read-only register. +

+ + + +
+
+
+ +

5.11 Manipulating Spacing

+ + + +

A break causes the formatter to update the vertical drawing position at +which the new text baseline is aligned. You can alter this location. +

+
+
Request: .sp [distance]
+
+

Break and move the next text baseline down by distance, or until +springing a page location trap.62 +If invoked with the no-break control character, sp moves the +pending output line’s text baseline by distance. A negative +distance will not reduce the position of the text baseline below +zero. Inside a diversion, any distance argument is ignored. The +default scaling unit is ‘v’. If distance is not specified, +‘1v’ is assumed. +

+
+
.pl 5v \" Set page length to 5 vees.
+.de xx
+\-\-\-
+.  br
+..
+.wh 0 xx \" Set a trap at the top of the page.
+foo on page \n%
+.sp 2v
+bar on page \n%
+.sp 50v \" This will cause a page break.
+baz on page \n%
+.pl \n(nlu \" Truncate page to current position.
+    ⇒ ---
+    ⇒ foo on page 1
+    ⇒
+    ⇒
+    ⇒ bar on page 1
+    ⇒ ---
+    ⇒ baz on page 2
+
+ +

You might use the following macros to set the baseline of the next +output text at a given distance from the top or the bottom of the page. +We subtract one line height (\n[.v]) because the | +operator moves to one vee below the page top (recall Numeric Expressions). +

+
+
.de y-from-top-down
+.  sp |\\$1-\\n[.v]u
+..
+.
+.de y-from-bot-up
+.  sp |\\n[.p]u-\\$1-\\n[.v]u
+..
+
+ +

A call to ‘.y-from-bot-up 10c’ means that the next text baseline +will be 10 cm from the bottom edge of the paper. +

+ +
+
Request: .ls [count]
+
+
Register: \n[.L]
+
+ +

Set the line spacing; add count−1 blank lines after each +line of text. With no argument, GNU troff uses the previous +value before the last ls call. The default is 1. +

+ + +

The read-only register .L contains the current line spacing; it +is associated with the environment (see Environments). +

+ +

The ls request is a coarse mechanism. See Changing the Type Size, for the requests vs and pvs as alternatives to +ls. +

+
+
Escape sequence: \x'spacing'
+
+
Register: \n[.a]
+
+

Sometimes, an output line requires additional vertical spacing, for +instance to allow room for a tall construct like an inline equation with +exponents or subscripts (particularly if they are iterated). The +\x escape sequence takes a delimited measurement (like +‘\x'3p'’) to increase the vertical spacing of the pending output +line. The default scaling unit is ‘v’. If the measurement is +positive, extra vertical space is inserted below the current line; a +negative measurement adds space above. If \x is applied to the +pending output line multiple times, the maxima of the positive and +negative adjustments are separately applied. The delimiter need not be +a neutral apostrophe; see Delimiters. +

+ +

The .a read-only register contains the extra vertical spacing +after the text baseline of the most recently emitted output line. +(In other words, it is the largest positive argument to \x +encountered on that line.) This quantity is exposed via a register +because if an output line requires this “extra post-vertical line +spacing”, and the subsequent output line requires “extra pre-vertical +line spacing” (a negative argument to \x), then applying both +can lead to excessive spacing between the output lines. Text that is +piling high on line n might not require (as much) extra +pre-vertical line spacing if line n−1 carries extra +post-vertical line spacing. +

+

Use of \x can be necessary in combination with the +bracket-building escape sequence \b,63 as the following example shows. +

+
+
.nf
+This is a test of \[rs]b (1).
+This is a test of \[rs]b (2).
+This is a test of \b'xyz'\x'-1m'\x'1m' (3).
+This is a test of \[rs]b (4).
+This is a test of \[rs]b (5).
+    ⇒ This is a test of \b (1).
+    ⇒ This is a test of \b (2).
+    ⇒                   x
+    ⇒ This is a test of y (3).
+    ⇒                   z
+    ⇒ This is a test of \b (4).
+    ⇒ This is a test of \b (5).
+
+
+ +

Without \x, the backslashes on the lines marked ‘(2)’ and +‘(4)’ would be overprinted. +

+
+
Request: .ns
+
+
Request: .rs
+
+
Register: \n[.ns]
+
+ + + + + +

Enable no-space mode. Vertical spacing, whether by sp +requests or blank input lines, is disabled. The bp request to +advance to the next page is also disabled, unless it is accompanied by a +page number (see Page Control). No-space mode ends automatically +when text64 is formatted for output 65 or the rs request is invoked, which ends +no-space mode. The read-only register .ns interpolates a Boolean +value indicating the enablement of no-space mode. +

+

A paragraphing macro might ordinarily insert vertical space to separate +paragraphs. A section heading macro could invoke ns to suppress +this spacing for the first paragraph in a section. +

+ + + +
+
+
+ +

5.12 Tabs and Fields

+ + + + +

A tab character (ISO code point 9, EBCDIC +code point 5) causes a horizontal movement to the next tab stop, if +any. +

+
+
Escape sequence: \t
+
+ + + + + +

Interpolate a tab in copy mode; see Copy Mode. +

+ +
+
Request: .ta [[n1 n2nn ]T r1 r2rn]
+
+
Register: \n[.tabs]
+
+

Change tab stop positions. This request takes a series of tab +specifiers as arguments (optionally divided into two groups with the +letter ‘T’) that indicate where each tab stop is to be, overriding +any previous settings. The default scaling unit is ‘m’. Invoking +ta without an argument removes all tab stops. + + +GNU troff’s startup value is ‘T 0.5i. +

+

Tab stops can be specified absolutely—as distances from the left +margin. The following example sets six tab stops, one every inch. +

+
+
.ta 1i 2i 3i 4i 5i 6i
+
+ +

Tab stops can also be specified using a leading ‘+’, which means +that the specified tab stop is set relative to the previous tab stop. +For example, the following is equivalent to the previous example. +

+
+
.ta 1i +1i +1i +1i +1i +1i
+
+ +

GNU troff supports an extended syntax to specify repeating tab +stops. These stops appear after a ‘T’ argument. Their values are +always taken as distances relative to the previous tab stop. This is +the idiomatic way to specify tab stops at equal intervals in +groff. The following is, yet again, the same as the previous +examples. It does more, in fact, since it defines an infinite number of +tab stops at one-inch intervals. +

+
+
.ta T 1i
+
+ +

Now we are ready to interpret the full syntax given above. The +ta request sets tabs at positions n1, n2, …, +nn, then at nn+r1, nn+r2, …, +nn+rn, then at nn+rn+r1, +nn+rn+r2, …, nn+rn+rn, and so +on. +

+

For example, ‘4c +6c T 3c 5c 2c’ is equivalent to ‘4c 10c 13c +18c 20c 23c 28c 30c …’. +

+

Text written to a tab column (i.e., between two tab stops, or between a +tab stop and an output line boundary) may be aligned to the right or +left, or centered in the column. This alignment is determined by +appending ‘R’, ‘L’, or ‘C’ to the tab specifier. The +default is ‘L’. +

+
+
.ta 1i 2iC 3iR
+
+ +

The beginning of an output line is not a tab stop; the text that begins +an output line is placed according to the configured alignment and +indentation; see Manipulating Filling and Adjustment and Line Layout. +

+

A tab stop is converted into a non-breakable horizontal movement that +cannot be adjusted. +

+
+
.ll 2i
+.ds foo a\tb\tc
+.ta T 1i
+\*[foo]
+    error→ warning: cannot break line
+    ⇒ a         b         c
+
+ +

The above creates a single output line that is a bit longer than two +inches (we use a string to show exactly where the tab stops are). +Now consider the following. +

+
+
.ll 2i
+.ds bar a\tb c\td
+.ta T 1i
+\*[bar]
+    error→ warning: cannot adjust line
+    ⇒ a         b
+    ⇒ c       d
+
+ +

GNU troff first converts the line’s tab stops into unbreakable +horizontal movements, then breaks after ‘b’. This usually isn’t +what you want. +

+

Superfluous tab characters—those that do not correspond to a tab +stop—are ignored except for the first, which delimits the characters +belonging to the last tab stop for right-alignment or centering. +

+
+
.ds Z   foo\tbar\tbaz
+.ds ZZ  foo\tbar\tbazqux
+.ds ZZZ foo\tbar\tbaz\tqux
+.ta 2i 4iR
+\*[Z]
+.br
+\*[ZZ]
+.br
+\*[ZZZ]
+.br
+    ⇒ foo                 bar              baz
+    ⇒ foo                 bar           bazqux
+    ⇒ foo                 bar              bazqux
+
+ +

The first line right-aligns “baz” within the second tab stop. The +second line right-aligns “bazqux” within it. The third line +right-aligns only “baz” because of the additional tab character, which +marks the end of the text occupying the last tab stop defined. +

+

Tab stops are associated with the environment (see Environments). +

+ + + +

The read-only register .tabs contains a string +representation of the current tab settings suitable for use as an +argument to the ta request.66 +

+
+
.ds tab-string \n[.tabs]
+\*[tab-string]
+    ⇒ T120u
+
+
+ +
+
Request: .tc [c]
+
+ + + +

Set the tab repetition character to the ordinary or special character +c; normally, no glyph is written when moving to a tab stop (and +some output devices may output space characters to achieve this motion). +A tab repetition character causes the formatter to write as many +instances of c as are necessary to occupy the interval from the +horizontal drawing position to the next tab stop. With no argument, GNU +troff reverts to the default behavior. The tab repetition +character is associated with the environment (see Environments). +Only a single character of c is recognized; any excess is ignored. +

+ +
+
Request: .linetabs n
+
+
Register: \n[.linetabs]
+
+ + + +

If n is missing or non-zero, activate line-tabs; deactivate +it otherwise (the default). Active line-tabs cause GNU troff +to compute tab distances relative to the start of the output line +instead of the input line. +

+
+
.de Tabs
+.  ds x a\t\c
+.  ds y b\t\c
+.  ds z c
+.  ta 1i 3i
+\\*x
+\\*y
+\\*z
+..
+.Tabs
+.br
+.linetabs
+.Tabs
+    ⇒ a         b         c
+    ⇒ a         b                   c
+
+ +

Line-tabs activation is associated with the environment +(see Environments). The read-only register .linetabs +interpolates 1 if line-tabs are active, and 0 otherwise. +

+ + + + +
+
+ +

5.12.1 Leaders

+ + +

Sometimes it is desirable to fill a tab stop with a given glyph, +but also use tab stops normally on the same output line. An example is +a table of contents entry that uses dots to bridge the entry name with +its page number, which is itself aligned between tab stops. The +roff language provides leaders for this +purpose.67 +

+ +

A leader character (ISO and EBCDIC code +point 1, also known as SOH or “start of heading”), +behaves similarly to a tab character: it moves to the next tab stop. +The difference is that for this movement, the default fill character is +a period ‘.’. +

+
+
Escape sequence: \a
+
+ + + + + +

Interpolate a leader in copy mode; see Copy Mode. +

+ +
+
Request: .lc [c]
+
+ + + +

Set the leader repetition character to the ordinary or special character +c. Recall Tabs and Leaders: when encountering a leader +character in the input, the formatter writes as many dots ‘.’ as +are necessary until +reaching the next tab stop; this is the leader definition +character. Omitting c unsets the leader +character. With no argument, GNU troff treats leaders the same +as tabs. The leader repetition character is associated with the +environment (see Environments). Only a single c is +recognized; any excess is ignored. +

+ + + +

A table of contents, for example, may define tab stops after a section +number, a title, and a gap to be filled with leader dots. The page +number follows the leader, after a right-aligned final tab stop wide +enough to house the largest page number occurring in the document. +

+
+
.ds entry1 19.\tThe Prophet\a\t98
+.ds entry2 20.\tAll Astir\a\t101
+.ta .5i 4.5i +.5iR
+.nf
+\*[entry1]
+\*[entry2]
+    ⇒ 19.  The Prophet.............................   98
+    ⇒ 20.  All Astir...............................  101
+
+ + +
+
+
+ +

5.12.2 Fields

+ + + + + + + + +

Fields are a more general way of laying out tabular data. A field +is defined as the data between a pair of delimiting characters. +It contains substrings that are separated by padding characters. +The width of a field is the distance on the input line from the +position where the field starts to the next tab stop. A padding +character inserts an adjustable space similar to TeX’s \hss +command (thus it can even be negative) to make the sum of all substring +lengths plus the adjustable space equal to the field width. If more +than one padding character is inserted, the available space is evenly +distributed among them. +

+
+
Request: .fc [delim-char [padding-char]]
+
+

Define a delimiting and a padding character for fields. If the latter +is missing, the padding character defaults to a space character. If +there is no argument at all, the field mechanism is disabled (which is +the default). In contrast to, e.g., the tab repetition character, +delimiting and padding characters are not associated with the +environment (see Environments). +

+
+
.fc # ^
+.ta T 3i
+#foo^bar^smurf#
+.br
+#foo^^bar^smurf#
+    ⇒ foo         bar          smurf
+    ⇒ foo            bar       smurf
+
+
+ + + +
+
+
+
+ +

5.13 Character Translations

+ + + +

A translation is a mapping of an input character to an output +glyph. The mapping occurs at output time, i.e., the input character +gets assigned the metric information of the mapped output character +right before input tokens are converted to nodes (see gtroff Internals, for more on this process). +

+
+
Request: .tr abcd
+
+
Request: .trin abcd
+
+

Translate character a to glyph b, character c to +glyph d, and so on. If there is an odd number of characters +in the argument, the last one is translated to a fixed-width space (the +same one obtained by the \SP escape sequence). +

+

The trin request is identical to tr, but when you unformat +a diversion with asciify it ignores the translation. +See Diversions, for details about the asciify request. +

+

Some notes: +

+
    +
  • + + + + + + + + + + + + +Special characters (\(xx, \[xxx], +\C'xxx', \', \`, \-, \_), +glyphs defined with the char request, and numbered glyphs +(\N'xxx') can be translated also. + +
  • +The \e escape can be translated also. + +
  • + +Characters can be mapped onto the \% and \~ escape +sequences (but \% and \~ can’t be mapped onto another +glyph). + +
  • + + + + + + + + + +The following characters can’t be translated: space (with one exception, +see below), backspace, newline, leader (and \a), tab (and +\t). + +
  • +Translations are not considered for finding the soft hyphen character +set with the shc request. + +
  • +The pair ‘c\&’ (an arbitrary character c followed +by the dummy character) maps this character to “nothing”. + +
    +
    .tr a\&
    +foo bar
    +    ⇒ foo br
    +
    + +

    Even the space character can be mapped to the dummy character. +

    +
    +
    .tr aa \&
    +foo bar
    +    ⇒ foobar
    +
    + +

    As shown in the example, the space character can’t be the first +character/glyph pair as an argument of tr. Additionally, it is +not possible to map the space character to any other glyph; requests +like ‘.tr aa x undo ‘.tr aa \& instead. +

    +

    If justification is active, lines are justified in spite of the ‘empty’ +space character (but there is no minimal distance, i.e., the space +character, between words). +

    +
  • After an output glyph has been constructed (this happens at the moment +immediately before the glyph is appended to an output glyph list, either +by direct output, in a macro, diversion, or string), it is no longer +affected by tr. + +
  • Translating character to glyphs where one of them or both are undefined +is possible also; tr does not check whether the elements of its +argument exist. + +

    See gtroff Internals. +

    +
  • Without an argument, the tr request is ignored. +
+
+ +
+
Request: .trnt abcd
+
+ +

trnt is the same as the tr request except that the +translations do not apply to text that is transparently throughput into +a diversion with \!. See Diversions. +

+

For example, +

+
+
.tr ab
+.di x
+\!.tm a
+.di
+.x
+
+ +

prints ‘b’ to the standard error stream; if trnt is used +instead of tr it prints ‘a’. +

+ + + +
+
+
+ +

5.14 troff and nroff Modes

+ + + + + +

Historically, nroff and troff were two separate programs; +the former for terminal output, the latter for typesetters. GNU +troff merges both functions into one executable68 that sends its output to a +device driver (grotty for terminal devices, grops for +PostScript, and so on) which interprets this intermediate output format. +When discussing AT&T troff, it makes sense to talk +about nroff mode and troff mode since the +differences are hard-coded. GNU troff takes information from +device and font description files without handling requests specially if +a terminal output device is used, so such a strong distinction is +unnecessary. +

+

Usually, a macro package can be used with all output devices. +Nevertheless, it is sometimes necessary to make a distinction between +terminal and non-terminal devices: GNU troff provides two +built-in conditions ‘n’ and ‘t’ for the if, ie, +and while requests to decide whether GNU troff shall +behave like nroff or like troff. +

+
+
Request: .troff
+
+ + +

Make the ‘t’ built-in condition true (and the ‘n’ built-in +condition false) for if, ie, and while conditional +requests. This is the default if GNU troff (not +groff) is started with the -R switch to avoid loading of +the startup files troffrc and troffrc-end. Without +-R, GNU troff stays in troff mode if the output +device is not a terminal (e.g., ‘ps’). +

+ +
+
Request: .nroff
+
+ +

Make the ‘n’ built-in condition true (and the ‘t’ built-in +condition false) for if, ie, and while conditional +requests. This is the default if GNU troff uses a terminal +output device; the code for switching to nroff mode is in the +file tty.tmac, which is loaded by the startup file +troffrc. +

+ +

See Conditionals and Loops, for more details on built-in conditions. +

+ + +
+
+
+ +

5.15 Line Layout

+ + + + + +

The following drawing shows the dimensions that gtroff uses for +placing a line of output onto the page. They are labeled with the +request that manipulates each dimension. +

+
+
     -->| in |<--
+        |<-----------ll------------>|
+   +----+----+----------------------+----+
+   |    :    :                      :    |
+   +----+----+----------------------+----+
+-->| po |<--
+   |<--------paper width---------------->|
+
+ +

These dimensions are: +

+
+
po
+
+ + + +

Page offset—this is the leftmost position of text on the final +output, defining the left margin. +

+
+
in
+
+ +

Indentation—this is the distance from the left margin where +text is printed. +

+
+
ll
+
+ +

Line length—this is the distance from the left margin to right +margin. +

+
+ + + +

The right margin is not explicitly configured; the combination of page +offset and line length provides the information necessary to derive it. +

+

A simple demonstration: +

+
+
.ll 3i
+This is text without indentation.
+The line length has been set to 3\~inches.
+.in +.5i
+.ll -.5i
+Now the left and right margins are both increased.
+.in
+.ll
+Calling .in and .ll without parameters restores
+the previous values.
+
+ +
+
    ⇒ This  is text without indenta-
+    ⇒ tion.   The  line  length  has
+    ⇒ been set to 3 inches.
+    ⇒      Now   the  left  and
+    ⇒      right  margins   are
+    ⇒      both increased.
+    ⇒ Calling  .in  and  .ll without
+    ⇒ parameters restores the previ-
+    ⇒ ous values.
+
+ +
+
Request: .po [offset]
+
+
Request: .po +offset
+
Request: .po -offset
+
Register: \n[.o]
+
+ +

Set page offset to offset (or increment or decrement its current +value by offset). If invoked without an argument, the page offset +is restored to the value before the previous po request. +This request does not cause a break; the page offset in effect when an +output line is broken prevails (see Manipulating Filling and Adjustment). The initial value is 1i and the default scaling +unit is ‘m’. On terminal devices, the page offset is set to zero +by a driver-specific macro file, tty.tmac. The current page +offset can be found in the read-only register ‘.o’. + + +This request is incorrectly documented in the AT&T +troff manual as using a default scaling unit of ‘v’. +

+
+
.po 3i
+\n[.o]
+    ⇒ 720
+.po -1i
+\n[.o]
+    ⇒ 480
+.po
+\n[.o]
+    ⇒ 720
+
+
+ +
+
Request: .in [indent]
+
+
Request: .in +indent
+
Request: .in -indent
+
Register: \n[.i]
+
+

Set indentation to indent (or increment or decrement the current +value by indent). This request causes a break. Initially, there +is no indentation. +

+

If in is called without an argument, the indentation is reset to +the previous value before the last call to in. The default +scaling unit is ‘m’. +

+

If a negative indentation value is specified (which is not allowed), +gtroff emits a warning in category ‘range’ and sets the +indentation to zero. +

+

The effect of in is delayed until a partially collected line (if +it exists) is output. A temporary indentation value is reset to zero +also. +

+

The current indentation (as set by in) can be found in the +read-only register ‘.i’. The indentation is associated with the +environment (see Environments). +

+ +
+
Request: .ti offset
+
+
Request: .ti +offset
+
Request: .ti -offset
+
Register: \n[.in]
+
+

Temporarily indent the next output line by offset. If an +increment or decrement value is specified, adjust the temporary +indentation relative to the value set by the in request. +

+

This request causes a break; its value is associated with the +environment (see Environments). The default scaling unit is +‘m’. A call of ti without an argument is ignored. +

+

If the total indentation value is negative (which is not allowed), +gtroff emits a warning in category ‘range’ and sets the +temporary indentation to zero. ‘Total indentation’ is either +offset if specified as an absolute value, or the temporary plus +normal indentation, if offset is given as a relative value. +

+

The effect of ti is delayed until a partially collected line (if +it exists) is output. +

+

The read-only register .in is the indentation that applies to the +current output line. +

+

The difference between .i and .in is that the latter takes +into account whether a partially collected line still uses the old +indentation value or a temporary indentation value is active. +

+ +
+
Request: .ll [length]
+
+
Request: .ll +length
+
Request: .ll -length
+
Register: \n[.l]
+
+
Register: \n[.ll]
+
+

Set the line length to length (or increment or decrement the +current value by length). Initially, the line length is set to +6.5i. The effect of ll is delayed until a partially +collected line (if it exists) is output. The default scaling unit is +‘m’. +

+

If ll is called without an argument, the line length is reset to +the previous value before the last call to ll. If a negative +line length is specified (which is not allowed), gtroff emits a +warning in category ‘range’ and sets the line length to zero. The +line length is associated with the environment (see Environments). +

+ +

The current line length (as set by ll) can be found in the +read-only register ‘.l’. The read-only register .ll is the +line length that applies to the current output line. +

+

Similar to .i and .in, the difference between .l +and .ll is that the latter takes into account whether a partially +collected line still uses the old line length value. +

+ + + +
+
+
+ +

5.16 Line Continuation

+ + + +

When filling is enabled, input and output line breaks generally do not +correspond. The roff language therefore distinguishes input and +output line continuation. +

+
+
Escape sequence: \RET
+
+ + + + +

\RET (a backslash immediately followed by a newline) +suppresses the effects of that newline in the input. The next input +line thus retains the classification of its predecessor as a control or +text line. \RET is useful for managing line lengths in the +input during document maintenance; you can break an input line in the +middle of a request invocation, macro call, or escape sequence. Input +line continuation is invisible to the formatter, with two exceptions: +the | operator recognizes the new input line +(see Numeric Expressions), and the input line counter register +.c is incremented. +

+
+
.ll 50n
+.de I
+.  ft I
+.  nop \\$*
+.  ft
+..
+Our film class watched
+.I The Effect of Gamma Rays on Man-in-the-Moon
+Marigolds. \" whoops, the input line wrapped
+.br
+.I My own opus begins on line \n[.c] \
+and ends on line \n[.c].
+
+
+
    ⇒ Our film class watched The Effect of Gamma Rays on
+    ⇒ Man-in-the-Moon Marigolds.
+    ⇒ My own opus begins on line 11 and ends on line 12.
+
+
+ +
+
Escape sequence: \c
+
+
Register: \n[.int]
+
+ + + + + + +

\c continues an output line. Nothing after it on the input line +is formatted. In contrast to \RET, a line after \c +remains a new input line, so a control character is recognized at its +beginning. The visual results depend on whether filling is enabled; see +Manipulating Filling and Adjustment. +

+
    +
  • + + +If filling is enabled, a word interrupted with \c is continued +with the text on the next input text line, without an intervening space. + +
    +
    This is a te\c
    +st.
    +    ⇒ This is a test.
    +
    + +
  • + + +If filling is disabled, the next input text line after \c is +handled as a continuation of the same input text line. + +
    +
    .nf
    +This is a \c
    +test.
    +    ⇒ This is a test.
    +
    +
+ +

An intervening control line that causes a break overrides \c, +flushing out the pending output line in the usual way. +

+ + +

The .int register contains a positive value if the last output +line was continued with \c; this datum is associated with the +environment (see Environments).69 +

+ + + +
+
+
+ +

5.17 Page Layout

+ + + +

The formatter permits configuration of the page length and page number. +

+
+
Request: .pl [length]
+
+
Request: .pl +length
+
Request: .pl -length
+
Register: \n[.p]
+
+ + + + +

Change (increase or decrease) the page length per the numeric expression +length. The default scaling unit is ‘v’. A negative +length is valid, but an uncommon application: it prevents page +location traps from being sprung,70 and each +output line is placed on a new page. If length is invalid, GNU +troff emits a warning in category ‘number’. If length +is absent or invalid, ‘11i’ is assumed. +

+ +

The read-only register ‘.p’ interpolates the current page length. +

+ +
+
Request: .pn num
+
+
Request: .pn +num
+
Request: .pn -num
+
Register: \n[.pn]
+
+ + + +

Change (increase or decrease) the page number of the next page +per the numeric expression num. If num is invalid, GNU +troff emits a warning in category ‘number’ and ignores the +request. Without an argument, pn is ignored. +

+ + +

The read-only register .pn interpolates num if set by +pn on the current page, or the current page number plus 1. +

+ + + + +

The formatter offers special support for typesetting headers and +footers, collectively termed titles. Titles have an independent +line length, and their placement on the page is not restricted. +

+
+
Request: .tl 'left'center'right'
+
+ + + + +

Format an output line as a title consisting of left, center, +and right, each aligned accordingly. The delimiter need not be a +neutral apostrophe: tl accepts the same delimiters as most escape +sequences; see Delimiters. If not used as the delimiter, any +page number character character is replaced with the current page +number; the default is ‘%’; see the the pc request below. +Without an argument, tl is ignored. tl writes the title +line immediately, ignoring any partially collected line. +

+

It is not an error to omit delimiters after the first. For example, +‘.tl /Thesis is interpreted as ‘.tl /Thesis///: it +sets a title line comprising only the left-aligned word ‘Thesis’. +

+ +
+
Request: .lt [length]
+
+
Request: .lt +length
+
Request: .lt -length
+
Register: \n[.lt]
+
+ + +

Change (increase or decrease) the line length used by titles per the +numeric expression length. The default scaling unit is ‘m’. +If length is negative, GNU emits a warning in category +‘range’ and treats length as ‘0’. If length is +invalid, GNU troff emits a warning in category ‘number’ and +ignores the request. The formatter’s default title length is +‘6.5i’. With no argument, the title length is restored to the +previous value. The title length is is associated with the environment +(see Environments). +

+ +

The read-only register ‘.lt’ interpolates the title line length. +

+ +
+
Request: .pc [char]
+
+ + + +

Set the page number character to char. With no argument, the page +number character is disabled. pc does not affect the +register %. +

+ +

The following example exercises title features. +

+
+
.lt 50n
+This is my partially collected
+.tl 'Isomers 2023'%'Dextrose Edition'
+line.
+    ⇒ Isomers 2023             1        Dextrose Edition
+    ⇒ This is my partially collected line.
+
+ +

We most often see titles used in page header and footer traps. +See Traps. +

+ +
+
+
+ +

5.18 Page Control

+ + + + + + + +

Discretionary page breaks can prevent the unwanted separation of +content. A new page number takes effect during page ejection; see +The Implicit Page Trap. +

+
+
Request: .bp [page-number]
+
+
Request: .bp +page-number
+
Request: .bp -page-number
+
Register: \n[%]
+
+ + +

Break the page and change (increase or decrease) the next page number +per the numeric expression page-number. If page-number is +invalid, GNU troff emits a warning in category ‘number’ and +ignores the argument. This request causes a break. A page break +advances the vertical drawing position to the bottom of the page, +springing traps. See Page Location Traps. + + + +bp has effect only if invoked within the top-level +diversion.71 + + +This request is incorrectly documented in the AT&T +troff manual as having a default scaling unit of ‘v’. +

+ + +

The register % interpolates the current page number. +

+
+
.de BP
+'  bp \" schedule page break once current line is output
+..
+
+
+ +
+
Request: .ne [space]
+
+ + + +

Force a page break if insufficient vertical space is available (assert +“needed” space). ne tests the distance to the next page +location trap; see Page Location Traps, and breaks the page if +that amount is less than space. The default scaling unit is +‘v’. If space is invalid, GNU troff emits a warning +in category ‘number’ and ignores the argument. If space is +not specified, ‘1v’ is assumed. +

+ +

We can require space for at least the first two output lines of a +paragraph, preventing its first line from being widowed at the +page bottom. +

+
+
.ne 2v
+Considering how common illness is,
+how tremendous the spiritual change that it brings,
+how astonishing,
+when the lights of health go down,
+the undiscovered countries that are then disclosed,
+what wastes and deserts of the soul a slight attack
+of influenza brings to view,
+
+ +

This method is reliable only if no output line is pending when ne +is invoked. When macro packages are used, this is often not the case: +their paragraphing macros perform the break. You may need to experiment +with placing the ne after the paragraphing macro, or br +and ne before it. +

+ + +

ne is also useful to force grouping of section headings with +their subsequent paragraphs, or tables with their captions and/or +explanations. Macro packages often use ne with diversions to +implement keeps and displays; see Diversions. They may also offer +parameters for widow and orphan management. +

+ +
+
Request: .sv [space]
+
+
Request: .os
+
+ +

Require vertical space as ne does, but also save it for +later output by the os request. If space is available +before the next page location trap, it is output immediately. Both +requests ignore a partially collected line, taking effect at the next +break. + + +sv and os ignore no-space mode (recall Manipulating Spacing). While the sv request allows negative values for +space, os ignores them. The default scaling unit is +‘v’. If space is not specified, ‘1v’ is assumed. +

+ +
+
Register: \n[nl]
+
+ + + +

nl interpolates or sets the vertical drawing position. When the +formatter starts, the first page transition hasn’t happened yet, and +nl is negative. If a header trap has been planted on the page +(typically at vertical position 0), you can assign a negative +value to nl to spring it if that page has already started +(see Page Location Traps). +

+
+
.de HD
+.  sp
+.  tl ''Goldbach Solution''
+.  sp
+..
+.
+First page.
+.bp
+.wh 0 HD \" plant header trap at top of page
+.nr nl (-1)
+Second page.
+    ⇒ First page.
+    ⇒
+    ⇒ (blank lines elided)
+    ⇒
+    ⇒                         Goldbach Solution
+    ⇒
+    ⇒ (blank lines elided)
+    ⇒
+    ⇒ Second page.
+
+ +

Without resetting nl to a negative value, the trap just planted +would be active beginning with the next page, not the current +one. +

+

See Diversions, for a comparison of nl with the .h and +.d registers. +

+ + + +
+
+
+ +

5.19 Using Fonts

+ + + + + + + + + + + + + +

In digital typography, a font is a collection of characters in a +specific typeface that a device can render as glyphs at a desired +size.72 A roff formatter can change typefaces at any +point in the text. The basic faces are a set of styles combining +upright and slanted shapes with normal and heavy stroke weights: +‘R’, ‘I’, ‘B’, and ‘BI’—these stand for +roman, italic, bold, and +bold-italic. For linguistic text, GNU troff groups +typefaces into families containing each of these +styles.73 A text font is thus often a family +combined with a style, but it need not be: consider the ps and +pdf devices’ ZCMI (Zapf Chancery Medium italic)—often, +no other style of Zapf Chancery Medium is provided. On typesetting +devices, at least one special font is available, comprising +unstyled glyphs for mathematical operators and other purposes. +

+ + + + + + + + +

Like AT&T troff, GNU troff does not itself load +or manipulate a digital font file;74 instead it +works with a font description file that characterizes it, +including its glyph repertoire and the metrics (dimensions) of +each glyph.75 This +information permits the formatter to accurately place glyphs with +respect to each other. Before using a font description, the formatter +associates it with a mounting position, a place in an ordered list +of available typefaces. + + + +So that a document need not be strongly coupled to a specific font +family, in GNU troff an output device can associate a style in +the abstract sense with a mounting position. Thus the default family +can be combined with a style dynamically, producing a resolved font +name. +

+

Fonts often have trademarked names, and even Free Software fonts can +require renaming upon modification. groff maintains a +convention that a device’s serif font family is given the name ‘T’ +(“Times”), its sans-serif family ‘H’ (“Helvetica”), and its +monospaced family ‘C’ (“Courier”). Historical inertia has driven +groff’s font identifiers to short uppercase abbreviations of font +names, as with ‘TR’, ‘TI’, ‘TB’, ‘TBI’, and a +special font ‘S’. +

+

The default family used with abstract styles can be changed at any time; +initially, it is ‘T’. Typically, abstract styles are arranged in +the first four mounting positions in the order shown above. The default +mounting position, and therefore style, is always ‘1’ (‘R’). +By issuing appropriate formatter instructions, you can override these +defaults before your document writes its first glyph. +

+ + + + + +

Terminal output devices cannot change font families and lack special +fonts. They support style changes by overstriking, or by altering +ISO 6429/ECMA-48 graphic renditions (character cell +attributes). +

+ + + +
+
+ +

5.19.1 Selecting Fonts

+ + +

We use font to refer to any of several means of identifying a +font: by mounting position (‘3’), by abstract style (‘B’), or +by its identifier (‘TB’). +

+
+
Request: .ft [font]
+
+
Escape sequence: \ff
+
+
Escape sequence: \f(fn
+
Escape sequence: \f[font]
+
Register: \n[.fn]
+
+ + + + + + + + + + + +

The ft request selects the typeface font. If the argument +is absent or ‘P’, it selects the previously chosen font. If +font is a non-negative integer, it is interpreted as mounting +position; the font mounted there is selected. If that position refers +to an abstract style, it is combined with the default family (see +fam and \F below) to make a resolved font name. If the +mounting position is not a style and no font is mounted there, GNU +troff emits a warning in category ‘font’ and ignores the +request. +

+

If font matches a style name, it is combined with the current +family to make a resolved font name. Otherwise, font is assumed +to already be a resolved font name. +

+ + + +

The resolved font name is subject to translation (see request ftr +below). Next, the (possibly translated) font name’s mounting position +is looked up; if not mounted, font is sought on the file system as +a font description file and, if located, automatically mounted at the +next available position (see register .fp below). If the font +was mounted using an identifier different from its font description file +name (see request fp below), that file name is then looked up. +If a font description file for the resolved font name is not found, GNU +troff emits a warning in category ‘font’ and ignores the +request. +

+

The \f escape sequence is similar, using one-character name (or +mounting position) f, two-character name fn, or a name +font of arbitrary length. + + +‘\f[]’ selects the previous font. The syntax form ‘\fP’ is +supported for backward compatibility, and ‘\f[P]’ for consistency. +

+
+
eggs, bacon,
+.ft I
+spam,
+.ft
+and sausage.
+.br
+eggs, bacon, \fIspam,\fP and sausage.
+    ⇒ eggs, bacon, spam, and sausage
+    ⇒ eggs, bacon, spam, and sausage
+
+ +

The current and previously selected fonts are properties of the +environment (see Environments). +

+

The read-only string-valued register .fn contains the resolved +font name of the selected font. +

+

\f doesn’t produce an input token in GNU troff; it thus +can be used in requests that expect a single-character argument. We can +assign a font to a margin character as follows (see Miscellaneous). +

+
+
.mc \f[I]x\f[]
+
+
+ +
+
Request: .ftr f [g]
+
+ + + + + + + + + + + + + + +

Translate font f to font g. Whenever a font +named f is referred to in a \f escape sequence, in the +F and S conditional operators, or in the ft, +ul, bd, cs, tkf, special, +fspecial, fp, or sty requests, font g is +used. If g is missing or equal to f the translation is +undone. +

+

Font translations cannot be chained. +

+
+
.ftr XXX TR
+.ftr XXX YYY
+.ft XXX
+    error→ warning: can't find font 'XXX'
+
+
+ +
+
Request: .fzoom f [zoom]
+
+
Register: \n[.zoom]
+
+ + + + + + + + +

Set magnification of font f to factor zoom, which must +be a non-negative integer multiple of 1/1000th. This request is useful +to adjust the optical size of a font in relation to the others. In the +example below, font CR is magnified by 10% (the zoom factor is +thus 1.1). +

+
+
.fam P
+.fzoom CR 1100
+.ps 12
+Palatino and \f[CR]Courier\f[]
+
+ +

A missing or zero value of zoom is the same as a value of 1000, +which means no magnification. f must be a resolved font +name, not an abstract style. +

+

The magnification of a font is completely transparent to GNU +troff; a change of the zoom factor doesn’t cause any effect +except that the dimensions of glyphs, (word) spaces, kerns, etc., of the +affected font are adjusted accordingly. +

+

The zoom factor of the current font is available in the read-only +register ‘.zoom’, in multiples of 1/1000th. It returns zero if +there is no magnification. +

+ + +
+
+
+ +

5.19.2 Font Families

+ + + + + +

To accommodate the wide variety of fonts available, GNU troff +distinguishes font families and font styles. A resolved +font name is the catenation of a font family and a style. Selecting an +abstract style causes GNU troff to combine it with the default +font family. +

+

You can thus compose a document using abstract styles exclusively for +its body or running text, selecting a specific family only for titles or +examples, for instance, and change the default family on the command +line (recall Options). +

+

Fonts for the devices ps, pdf, dvi, lj4, +lbp, and the X11 devices support this mechanism. By default, +GNU troff uses the Times family with the four styles ‘R’, +‘I’, ‘B’, and ‘BI’. +

+
+
Request: .fam [family]
+
+
Register: \n[.fam]
+
+
Escape sequence: \Ff
+
+
Escape sequence: \F(fm
+
Escape sequence: \F[family]
+
+ +

Set the default font family, used in combination with abstract styles to +construct a resolved font name, to family (one-character +name f, two-character name fm). If no argument is +given, GNU troff selects the previous font family; if there none, +is it falls back to the device’s default76 or its own (‘T’). +

+

The \F escape sequence works similarly. In disanalogy to +\f, ‘\FP’ makes ‘P’ the default family. Use +‘\F[]’ to select the previous default family. The default font +family is available in the read-only string-valued register .fam; +it is associated with the environment (see Environments). +

+
+
spam,     \" startup defaults are T (Times) R (roman)
+.fam H    \" make Helvetica the default family
+spam,     \" family H + style R = HR
+.ft B     \" family H + style B = HB
+spam,
+.ft CR    \" Courier roman (default family not changed)
+spam,
+.ft       \" back to Helvetica bold
+spam,
+.fam T    \" make Times the default family
+spam,     \" family T + style B = TB
+.ft AR    \" font AR (not a style)
+baked beans,
+.ft R     \" family T + style R = TR
+and spam.
+
+ +

\F doesn’t produce an input token in GNU troff. As a +consequence, it can be used in requests like mc (which expects +a single character as an argument) to change the font family on the fly. +

+
+
.mc \F[P]x\F[]
+
+
+ +
+
Request: .sty n style
+
+
Register: \n[.sty]
+
+ + + + + + + + + +

Associate an abstract style style with mounting +position n, which must be a non-negative integer. If the +requests cs, bd, tkf, uf, or fspecial +are applied to an abstract style, they are instead applied to the member +of the current family corresponding to that style. +

+ + +

The default family can be set with the -f option (see Options). The styles command in the DESC file controls +which font positions (if any) are initially associated with abstract +styles rather than fonts. +

+

Caution: The style argument is not validated. +Errors may occur later, when the formatter attempts to construct a +resolved font name, or format a character for output. +

+
+
.nr BarPos \n[.fp]
+.sty \n[.fp] Bar
+.fam Foo
+.ft \n[BarPos]
+.tm .f=\n[.f]
+A
+    error→ error: no font family named 'Foo' exists
+    error→ .f=41
+    error→ error: cannot format glyph: no current font
+
+ +

When an abstract style has been selected, the read-only string-valued +register ‘.sty’ interpolates its name; this datum is associated +with the environment (see Environments). Otherwise, ‘.sty’ +interpolates nothing. +

+ + +
+
+
+ +

5.19.3 Font Positions

+ + + +

To support typeface indirection through abstract styles, and for +compatibility with AT&T troff, the formatter maintains +a list of font positions at which fonts required by a document are +mounted. An output device’s description file DESC +typically configures a set of pre-mounted fonts; see Device and Font Description Files. A font need not be explicitly mounted before +it is selected; GNU troff will search GROFF_FONT_PATH for +it by name and mount it at the first free mounting position on demand. +

+
+
Request: .fp pos id [font-description-file-name]
+
+
Register: \n[.f]
+
+
Register: \n[.fp]
+
+ + +

Mount a font under the name id at mounting position pos, a +non-negative integer. When the formatter starts up, it reads the output +device’s description to mount an initial set of faces, and selects font +position 1. Position 0 is unused by default. Unless the +font-description-file-name argument is given, id should be +the name of a font description file stored in a directory corresponding +to the selected output device. GNU troff does not traverse +directories to locate the font description file. +

+ + +

The optional third argument enables font names to be aliased, which can +be necessary in compatibility mode since AT&T troff syntax +affords no means of identifying fonts with names longer than two +characters, like ‘TBI’ or ‘ZCMI’, in a font selection escape +sequence. See Compatibility Mode. You can also alias fonts on +mounting for convenience or abstraction. (See below regarding the +.fp register.) +

+
+
.fp \n[.fp] SC ZCMI
+Send a \f(SChand-written\fP thank-you note.
+.fp \n[.fp] Emph TI
+.fp \n[.fp] Strong TB
+Are \f[Emph]these names\f[] \f[Strong]comfortable\f[]?
+
+ +

DESC’, ‘P’, and non-negative integers are not usable as font +identifiers. +

+ +

The position of the currently selected font (or abstract style) is +available in the read-only register ‘.f’. It is associated with +the environment (see Environments). +

+

You can copy the value of .f to another register to save it for +later use. +

+
+
.nr saved-font \n[.f]
+text involving many font changes
+.ft \n[saved-font]
+
+ + +

The index of the next (non-zero) free font position is available in the +read-only register ‘.fp’. + +Fonts not listed in the DESC file are automatically mounted at +position ‘\n[.fp]’ when selected with the ft request or +\f escape sequence. When mounting a font at a position +explicitly with the fp request, this same practice should be +followed, although GNU troff does not enforce this strictly. +

+ + +
+
+
+ +

5.19.4 Using Symbols

+ + + + + + + + +

A glyph is a graphical representation of a character. While +a character is an abstraction of semantic information, a glyph is +something that can be seen on screen or paper. A character has many +possible representation forms (for example, the character ‘A’ can be +written in an upright or slanted typeface, producing distinct +glyphs). Sometimes, a sequence of characters map to a single glyph: +this is a ligature—the most common is ‘fi’. +

+

Space characters never become glyphs in GNU troff. If not +discarded (as when trailing on text lines), they are represented by +horizontal motions in the output. +

+ + + + + + +

A symbol is simply a named glyph. Within gtroff, all glyph +names of a particular font are defined in its font file. If the user +requests a glyph not available in this font, gtroff looks up an +ordered list of special fonts. By default, the PostScript output +device supports the two special fonts ‘SS’ (slanted symbols) and +‘S’ (symbols) (the former is looked up before the latter). Other +output devices use different names for special fonts. Fonts mounted +with the fonts keyword in the DESC file are globally +available. To install additional special fonts locally (i.e., for a +particular font), use the fspecial request. +

+

Here are the exact rules how gtroff searches a given symbol: +

+
    +
  • If the symbol has been defined with the char request, use it. +This hides a symbol with the same name in the current font. + +
  • Check the current font. + +
  • If the symbol has been defined with the fchar request, use it. + +
  • Check whether the current font has a font-specific list of special +fonts; test all fonts in the order of appearance in the last +fspecial call if appropriate. + +
  • If the symbol has been defined with the fschar request for the +current font, use it. + +
  • Check all fonts in the order of appearance in the last special +call. + +
  • If the symbol has been defined with the schar request, use it. + +
  • As a last resort, consult all fonts loaded up to now for special fonts +and check them, starting with the lowest font number. This can +sometimes lead to surprising results since the fonts line in +the DESC file often contains empty positions, which are filled +later on. For example, consider the following: + +
    +
    fonts 3 0 0 FOO
    +
    + +

    This mounts font foo at font position 3. We assume that +FOO is a special font, containing glyph foo, and that no +font has been loaded yet. The line +

    +
    +
    .fspecial BAR BAZ
    +
    + +

    makes font BAZ special only if font BAR is active. We +further assume that BAZ is really a special font, i.e., the font +description file contains the special keyword, and that it also +contains glyph foo with a special shape fitting to font +BAR. After executing fspecial, font BAR is loaded +at font position 1, and BAZ at position 2. +

    +

    We now switch to a new font XXX, trying to access glyph +foo that is assumed to be missing. There are neither +font-specific special fonts for XXX nor any other fonts made +special with the special request, so gtroff starts the +search for special fonts in the list of already mounted fonts, with +increasing font positions. Consequently, it finds BAZ before +FOO even for XXX, which is not the intended behaviour. +

+ +

See Device and Font Description Files, and Special Fonts, for +more details. +

+ + + + + +

The groff_char(7) man page houses a complete list of +predefined special character names, but the availability of any as a +glyph is device- and font-dependent. For example, say +

+
+
man -Tdvi groff_char > groff_char.dvi
+
+ +

to obtain those available with the DVI device and default font +configuration.77 If you want to use an additional macro package to change +the fonts used, groff (or gtroff) must be run directly. +

+
+
groff -Tdvi -mec -man groff_char.7 > groff_char.dvi
+
+ + + + + + +

Special character names not listed in groff_char(7) are +derived algorithmically, using a simplified version of the Adobe Glyph +List (AGL) algorithm, which is described in +https://github.com/adobe-type-tools/agl-aglfn. The (frozen) +set of names that can’t be derived algorithmically is called the +groff glyph list (GGL). +

+
    +
  • A glyph for Unicode character U+XXXX[X[X]], which is +not a composite character is named +uXXXX[X[X]]. X must be an +uppercase hexadecimal digit. Examples: u1234, u008E, +u12DB8. The largest Unicode value is 0x10FFFF. There must be at +least four X digits; if necessary, add leading zeroes (after the +‘u’). No zero padding is allowed for character codes greater than +0xFFFF. Surrogates (i.e., Unicode values greater than 0xFFFF +represented with character codes from the surrogate area U+D800-U+DFFF) +are not allowed either. + +
  • A glyph representing more than a single input character is named + +
    +
    ucomponent1_component2_component3 …
    +
    + +

    Example: u0045_0302_0301. +

    +

    For simplicity, all Unicode characters that are composites must be +maximally decomposed to NFD;78 for example, +u00CA_0301 is not a valid glyph name since U+00CA (LATIN +CAPITAL LETTER E WITH CIRCUMFLEX) can be further decomposed into U+0045 +(LATIN CAPITAL LETTER E) and U+0302 (COMBINING CIRCUMFLEX +ACCENT). u0045_0302_0301 is thus the glyph name for U+1EBE, +LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE. +

    +
  • groff maintains a table to decompose all algorithmically derived glyph +names that are composites itself. For example, u0100 (LATIN +LETTER A WITH MACRON) is automatically decomposed into +u0041_0304. Additionally, a glyph name of the GGL is preferred +to an algorithmically derived glyph name; groff also +automatically does the mapping. Example: The glyph u0045_0302 is +mapped to ^E. + +
  • glyph names of the GGL can’t be used in composite glyph names; for +example, ^E_u0301 is invalid. +
+ +
+
Escape sequence: \(nm
+
+
Escape sequence: \[name]
+
Escape sequence: \[base-glyph combining-component …]
+
+ +

Typeset a special character name (two-character name nm) or +a composite glyph consisting of base-glyph overlaid with one or +more combining-components. For example, ‘\[A ho]’ is a +capital letter “A” with a “hook accent” (ogonek). +

+

There is no special syntax for one-character names—the analogous form +‘\n’ would collide with other escape sequences. However, the +four escape sequences \', \-, \_, and \`, +are translated on input to the special character escape sequences +\[aa], \[-], \[ul], and \[ga], respectively. +

+

A special character name of length one is not the same thing as an +ordinary character: that is, the character a is not the same as +\[a]. +

+

If name is undefined, a warning in category ‘char’ is +produced and the escape is ignored. See Warnings, for information +about the enablement and suppression of warnings. +

+

GNU troff resolves \[] with more than a single +component as follows: +

+
    +
  • Any component that is found in the GGL is converted to the +uXXXX form. + +
  • Any component uXXXX that is found in the list of +decomposable glyphs is decomposed. + +
  • The resulting elements are then concatenated with ‘_’ in between, +dropping the leading ‘u’ in all elements but the first. +
+ +

No check for the existence of any component (similar to tr +request) is done. +

+

Examples: +

+
+
\[A ho]
+

A’ maps to u0041, ‘ho’ maps to u02DB, thus the +final glyph name would be u0041_02DB. This is not the expected +result: the ogonek glyph ‘ho’ is a spacing ogonek, but for a +proper composite a non-spacing ogonek (U+0328) is necessary. Looking +into the file composite.tmac, one can find ‘.composite ho u0328, which changes the mapping of ‘ho’ while a composite glyph +name is constructed, causing the final glyph name to be +u0041_0328. +

+
+
\[^E u0301]
+
\[^E aa]
+
\[E a^ aa]
+
\[E ^ ']
+

^E’ maps to u0045_0302, thus the final glyph name is +u0045_0302_0301 in all forms (assuming proper calls of the +composite request). +

+
+ +

It is not possible to define glyphs with names like ‘A ho +within a groff font file. This is not really a limitation; +instead, you have to define u0041_0328. +

+ +
+
Escape sequence: \C'xxx'
+
+ + +

Typeset the glyph of the special character xxx. Normally, it is +more convenient to use \[xxx], but \C has some +advantages: it is compatible with AT&T device-independent +troff (and therefore available in compatibility +mode79) and can interpolate special +characters with ‘]’ in their names. The delimiter need not be +a neutral apostrophe; see Delimiters. +

+ +
+
Request: .composite id1 id2
+
+ +

Map special character name id1 to id2 if id1 is used +in \[...] with more than one component. See above for examples. +This is a strict rewriting of the special character name; no check is +performed for the existence of a glyph for either. A set of default +mappings for many accents can be found in the file +composite.tmac, loaded by the default troffrc at startup. +

+ +
+
Escape sequence: \N'n'
+
+ + + + +

Typeset the glyph with code n in the current font +(n is not the input character code). The number +n can be any non-negative decimal integer. Most devices only +have glyphs with codes between 0 and 255; the Unicode output device +uses codes in the range 0–65535. If the current font does not contain +a glyph with that code, special fonts are not searched. The +\N escape sequence can be conveniently used in conjunction with +the char request: +

+
+
.char \[phone] \f[ZD]\N'37'
+
+ + + + +

The code of each glyph is given in the fourth column in the font +description file after the charset command. It is possible to +include unnamed glyphs in the font description file by using a name of +‘---’; the \N escape sequence is the only way to use these. +

+

No kerning is applied to glyphs accessed with \N. The delimiter +need not be a neutral apostrophe; see Delimiters. +

+ +

A few escape sequences are also special characters. +

+
+
Escape sequence: \'
+
+

An escaped neutral apostrophe is a synonym for \[aa] (acute +accent). +

+ +
+
Escape sequence: \`
+
+

An escaped grave accent is a synonym for \[ga] (grave accent). +

+ +
+
Escape sequence: \-
+
+

An escaped hyphen-minus is a synonym for \[-] (minus sign). +

+ +
+
Escape sequence: \_
+
+

An escaped underscore (“low line”) is a synonym for \[ul] +(underrule). On typesetting devices, the underrule is font-invariant +and drawn lower than the underscore ‘_’. +

+ +
+
Request: .cflags n c1 c2 …
+
+ + + + +

Assign properties encoded by the number n to characters c1, +c2, and so on. +

+

Input characters, including special characters introduced by an escape, +have certain properties associated with them.80 +These properties can be modified with this request. The first argument +is the sum of the desired flags and the remaining arguments are the +characters to be assigned those properties. Spaces between the cn +arguments are optional. Any argument cn can be a character class +defined with the class request rather than an individual +character. See Character Classes. +

+

The non-negative integer n is the sum of any of the following. +Some combinations are nonsensical, such as ‘33’ (1 + 32). +

+
+
1
+
+

Recognize the character as ending a sentence if followed by a newline +or two spaces. Initially, characters ‘.?!’ have this property. +

+
+
2
+
+

Enable breaks before the character. A line is not broken at a character +with this property unless the characters on each side both have non-zero +hyphenation codes. This exception can be overridden by adding 64. +Initially, no characters have this property. +

+
+
4
+
+ +

Enable breaks after the character. A line is not broken at a character +with this property unless the characters on each side both have non-zero +hyphenation codes. This exception can be overridden by adding 64. +Initially, characters ‘\-\[hy]\[em]’ have this property. +

+
+
8
+
+ + + + + +

Mark the glyph associated with this character as overlapping other +instances of itself horizontally. Initially, characters +‘\[ul]\[rn]\[ru]\[radicalex]\[sqrtex]’ have this property. +

+
+
16
+

Mark the glyph associated with this character as overlapping other +instances of itself vertically. Initially, the character ‘\[br]’ +has this property. +

+
+
32
+
+ + + + + + + + + +

Mark the character as transparent for the purpose of end-of-sentence +recognition. In other words, an end-of-sentence character followed by +any number of characters with this property is treated as the end of a +sentence if followed by a newline or two spaces. This is the same as +having a zero space factor in TeX. Initially, characters +‘"')]*\[dg]\[dd]\[rq]\[cq]’ have this property. +

+
+
64
+

Ignore hyphenation codes of the surrounding characters. Use this in +combination with values 2 and 4 (initially, no characters have this +property). +

+

For example, if you need an automatic break point after the en-dash in +numeric ranges like “3000–5000”, insert +

+
+
.cflags 68 \[en]
+
+ +

into your document. However, this practice can lead to bad layout if +done thoughtlessly; in most situations, a better solution instead of +changing the cflags value is to insert \: right after the +hyphen at the places that really need a break point. +

+
+ +

The remaining values were implemented for East Asian language support; +those who use alphabetic scripts exclusively can disregard them. +

+
+
128
+

Prohibit a line break before the character, but allow a line break after +the character. This works only in combination with flags 256 and 512 +and has no effect otherwise. Initially, no characters have this +property. +

+
+
256
+

Prohibit a line break after the character, but allow a line break before +the character. This works only in combination with flags 128 and 512 +and has no effect otherwise. Initially, no characters have this +property. +

+
+
512
+

Allow line break before or after the character. This works only in +combination with flags 128 and 256 and has no effect otherwise. +Initially, no characters have this property. +

+
+ +

In contrast to values 2 and 4, the values 128, 256, and 512 work +pairwise. If, for example, the left character has value 512, and the +right character 128, no break will be automatically inserted between +them. If we use value 6 instead for the left character, a break +after the character can’t be suppressed since the neighboring character +on the right doesn’t get examined. +

+ +
+
Request: .char c [contents]
+
+
Request: .fchar c [contents]
+
+
Request: .fschar f c [contents]
+
+
Request: .schar c [contents]
+
+ + + + + + + + + + + + + + + + + + + + + +

Define a new character or glyph c to be contents, which +can be empty. More precisely, char defines a groff object +(or redefines an existing one) that is accessed with the +name c on input, and produces contents on output. +Every time glyph c needs to be printed, contents is +processed in a temporary environment and the result is wrapped up into a +single object. Compatibility mode is turned off and the escape +character is set to \ while contents is processed. +Any emboldening, constant spacing, or track kerning is applied to this +object rather than to individual glyphs in contents. +

+

An object defined by these requests can be used just like a normal glyph +provided by the output device. In particular, other characters can be +translated to it with the tr or trin requests; it can be +made the leader character with the lc request; repeated patterns +can be drawn with it using the \l and \L escape sequences; +and words containing c can be hyphenated correctly if the +hcode request is used to give the object a hyphenation code. +

+

There is a special anti-recursion feature: use of the object within its +own definition is handled like a normal character (not +defined with char). +

+

The tr and trin requests take precedence if char +accesses the same symbol. +

+
+
.tr XY
+X
+    ⇒ Y
+.char X Z
+X
+    ⇒ Y
+.tr XX
+X
+    ⇒ Z
+
+ +

The fchar request defines a fallback glyph: gtroff only +checks for glyphs defined with fchar if it cannot find the glyph +in the current font. gtroff carries out this test before +checking special fonts. +

+

fschar defines a fallback glyph for font f: +gtroff checks for glyphs defined with fschar after the +list of fonts declared as font-specific special fonts with the +fspecial request, but before the list of fonts declared as global +special fonts with the special request. +

+

Finally, the schar request defines a global fallback glyph: +gtroff checks for glyphs defined with schar after the list +of fonts declared as global special fonts with the special +request, but before the already mounted special fonts. +

+

See Character Classes. +

+ +
+
Request: .rchar c …
+
+
Request: .rfschar f c …
+
+ + + +

Remove definition of each ordinary or special character c, +undoing the effect of a char, fchar, or schar +request. Those supplied by font description files cannot be removed. +Spaces and tabs may separate c arguments. +

+

The request rfschar removes glyph definitions defined with +fschar for font f. +

+ + +
+
+
+ +

5.19.5 Character Classes

+ + + +

Classes are particularly useful for East Asian languages such as +Chinese, Japanese, and Korean, where the number of needed characters is +much larger than in European languages, and where large sets of +characters share the same properties. +

+
+
Request: .class name c1 c2 …
+
+ + + +

Define a character class (or simply “class”) name comprising +the characters c1, c2, and so on. +

+

A class thus defined can then be referred to in lieu of listing all the +characters within it. Currently, only the cflags request can +handle references to character classes. +

+

In the request’s simplest form, each cn is a character (or special +character). +

+
+
.class [quotes] ' \[aq] \[dq] \[oq] \[cq] \[lq] \[rq]
+
+ +

Since class and glyph names share the same name space, it is recommended +to start and end the class name with [ and ], +respectively, to avoid collisions with existing character names defined +by GNU troff or the user (with char and related requests). +This practice applies the presence of ] in the class name to +prevent the use of the special character escape form +\[], thus you must use the \C escape to access +a class with such a name. +

+ + +

You can also use a character range notation consisting of a +start character followed by ‘-’ and then an end character. +Internally, GNU troff converts these two symbol names to +Unicode code points (according to the groff glyph list [GGL]), +which then give the start and end value of the range. If that fails, +the class definition is skipped. +

+

Furthermore, classes can be nested. +

+
+
.class [prepunct] , : ; > }
+.class [prepunctx] \C'[prepunct]' \[u2013]-\[u2016]
+
+ +

The class ‘[prepunctx]’ thus contains the contents of the class +[prepunct] as defined above (the set ‘, : ; > }’), and +characters in the range between U+2013 and U+2016. +

+

If you want to include ‘-’ in a class, it must be the first +character value in the argument list, otherwise it gets misinterpreted +as part of the range syntax. +

+

It is not possible to use class names as end points of range +definitions. +

+

A typical use of the class request is to control line-breaking +and hyphenation rules as defined by the cflags request. For +example, to inhibit line breaks before the characters belonging to the +prepunctx class defined in the previous example, you can write +the following. +

+
+
.cflags 2 \C'[prepunctx]'
+
+ +

See the cflags request in Using Symbols, for more details. +

+ + +
+
+
+ +

5.19.6 Special Fonts

+ + + +

Special fonts are those that gtroff searches when it cannot find +the requested glyph in the current font. The Symbol font is usually a +special font. +

+

gtroff provides the following two requests to add more special +fonts. See Using Symbols, for a detailed description of the glyph +searching mechanism in gtroff. +

+

Usually, only non-TTY devices have special fonts. +

+
+
Request: .special [s1 s2 …]
+
+
Request: .fspecial f [s1 s2 …]
+
+ + +

Use the special request to define special fonts. Initially, this +list is empty. +

+

Use the fspecial request to designate special fonts only when +font f is active. Initially, this list is empty. +

+

Previous calls to special or fspecial are overwritten; +without arguments, the particular list of special fonts is set to empty. +Special fonts are searched in the order they appear as arguments. +

+

All fonts that appear in a call to special or fspecial +are loaded. +

+

See Using Symbols, for the exact search order of glyphs. +

+ + +
+
+
+ +

5.19.7 Artificial Fonts

+ + + +

There are a number of requests and escape sequences for artificially +creating fonts. These are largely vestiges of the days when output +devices did not have a wide variety of fonts, and when nroff and +troff were separate programs. Most of them are no longer +necessary in GNU troff. Nevertheless, they are supported. +

+
+
Escape sequence: \H'height'
+
+
Escape sequence: \H'+height'
+
Escape sequence: \H'-height'
+
Register: \n[.height]
+
+ + + +

Change (increment, decrement) the height of the current font, but not +the width. If height is zero, restore the original height. +Default scaling unit is ‘z’. +

+

The read-only register .height contains the font height as set by +\H. +

+

Currently, only the -Tps and -Tpdf devices support +this feature. +

+

\H doesn’t produce an input token in GNU troff. As a +consequence, it can be used in requests like mc (which expects +a single character as an argument) to change the font on the fly: +

+
+
.mc \H'+5z'x\H'0'
+
+ +

In compatibility mode, gtroff behaves differently: If an +increment or decrement is used, it is always taken relative to the +current type size and not relative to the previously selected font +height. Thus, +

+
+
.cp 1
+\H'+5'test \H'+5'test
+
+ +

prints the word ‘test’ twice with the same font height (five points +larger than the current font size). +

+ +
+
Escape sequence: \S'slant'
+
+
Register: \n[.slant]
+
+ + + +

Slant the current font by slant degrees. Positive values slant to +the right. Only integer values are possible. +

+

The read-only register .slant contains the font slant as set by +\S. +

+

Currently, only the -Tps and -Tpdf devices support +this feature. +

+

\S doesn’t produce an input token in GNU troff. As a +consequence, it can be used in requests like mc (which expects +a single character as an argument) to change the font on the fly: +

+
+
.mc \S'20'x\S'0'
+
+ + + +

This escape is incorrectly documented in the AT&T +troff manual; the slant is always set to an absolute value. +

+ +
+
Request: .ul [lines]
+
+ +

The ul request normally underlines subsequent lines if a TTY +output device is used. Otherwise, the lines are printed in italics +(only the term ‘underlined’ is used in the following). The single +argument is the quantity of input lines to be underlined; with no +argument, the next line is underlined. If lines is zero or +negative, stop the effects of ul (if it was active). Requests +and empty lines do not count for computing the number of underlined +input lines, even if they produce some output like tl. Lines +inserted by macros (e.g., invoked by a trap) do count. +

+

At the beginning of ul, the current font is stored and the +underline font is activated. Within the span of a ul request, it +is possible to change fonts, but after the last line affected by +ul the saved font is restored. +

+

This number of lines still to be underlined is associated with the +environment (see Environments). The underline font can be changed +with the uf request. +

+ + +

The ul request does not underline spaces. +

+ +
+
Request: .cu [lines]
+
+ + +

The cu request is similar to ul but underlines spaces as +well (if a TTY output device is used). +

+ +
+
Request: .uf font
+
+ + +

Set the underline font (globally) used by ul and cu. By +default, this is the font at position 2. font can be either +a non-negative font position or the name of a font. +

+ +
+
Request: .bd font [offset]
+
+
Request: .bd font1 font2 [offset]
+
Register: \n[.b]
+
+ + +

Embolden font by overstriking its glyphs offset by offset +units minus one. +

+

Two syntax forms are available. +

+
    +
  • Imitate a bold font unconditionally. The first argument specifies the +font to embolden, and the second is the number of basic units, minus +one, by which the two glyphs are offset. If the second argument is +missing, emboldening is turned off. + +

    font can be either a non-negative font position or the name of a +font. +

    +

    offset is available in the .b read-only register if a +special font is active; in the bd request, its default unit is +‘u’. +

    +
  • + + + +Imitate a bold form conditionally. Embolden font1 by offset +only if font font2 is the current font. This request can be +issued repeatedly to set up different emboldening values for different +current fonts. If the second argument is missing, emboldening is turned +off for this particular current font. + +

    This affects special fonts only (either set up with the special +command in font files or with the fspecial request). +

+
+ +
+
Request: .cs font [width [em-size]]
+
+ + + + +

Switch to and from constant glyph space mode. If activated, the +width of every glyph is width/36 ems. The em size is given +absolutely by em-size; if this argument is missing, the em value +is taken from the current font size (as set with the ps request) +when the font is effectively in use. Without second and third argument, +constant glyph space mode is deactivated. +

+

Default scaling unit for em-size is ‘z’; width is an +integer. +

+ + +
+
+
+ +

5.19.8 Ligatures and Kerning

+ + + +

Ligatures are groups of characters that are run together, i.e, producing +a single glyph. For example, the letters ‘f’ and ‘i’ can form a +ligature ‘fi’ as in the word ‘file’. This produces a cleaner look +(albeit subtle) to the printed output. Usually, ligatures are not +available in fonts for TTY output devices. +

+

Most PostScript fonts support the fi and fl ligatures. The C/A/T +typesetter that was the target of AT&T troff also +supported ‘ff’, ‘ffi’, and ‘ffl’ ligatures. Advanced typesetters or +‘expert’ fonts may include ligatures for ‘ft’ and ‘ct’, although GNU +troff does not support these (yet). +

+

Only the current font is checked for ligatures and kerns; neither +special fonts nor special charcters defined with the char request +(and its siblings) are taken into account. +

+
+
Request: .lg [flag]
+
+
Register: \n[.lg]
+
+ + + +

Switch the ligature mechanism on or off; if the parameter is non-zero or +missing, ligatures are enabled, otherwise disabled. Default is on. The +current ligature mode can be found in the read-only register .lg +(set to 1 or 2 if ligatures are enabled, 0 otherwise). +

+

Setting the ligature mode to 2 enables the two-character ligatures +(fi, fl, and ff) and disables the three-character ligatures (ffi and +ffl). +

+ +

Pairwise kerning is another subtle typesetting mechanism that +modifies the distance between a glyph pair to improve readability. In +most cases (but not always) the distance is decreased. +Typewriter-like fonts and fonts for terminals where all glyphs have the +same width don’t use kerning. +

+
+
Request: .kern [flag]
+
+
Register: \n[.kern]
+
+ + + +

Switch kerning on or off. If the parameter is non-zero or missing, +enable pairwise kerning, otherwise disable it. The read-only register +.kern is set to 1 if pairwise kerning is enabled, +0 otherwise. +

+ + +

If the font description file contains pairwise kerning information, +glyphs from that font are kerned. Kerning between two glyphs can be +inhibited by placing \& between them: ‘V\&A’. +

+

See Font Description File Format. +

+ + + +

Track kerning expands or reduces the space between glyphs. This +can be handy, for example, if you need to squeeze a long word onto a +single line or spread some text to fill a narrow column. It must be +used with great care since it is usually considered bad typography if +the reader notices the effect. +

+
+
Request: .tkf f s1 n1 s2 n2
+
+ + +

Enable track kerning for font f. If the current font +is f the width of every glyph is increased by an amount +between n1 and n2 (n1, n2 can be negative); if +the current type size is less than or equal to s1 the width is +increased by n1; if it is greater than or equal to s2 the +width is increased by n2; if the type size is greater than or +equal to s1 and less than or equal to s2 the increase in +width is a linear function of the type size. +

+

The default scaling unit is ‘z’ for s1 and s2, ‘p’ +for n1 and n2. +

+

The track kerning amount is added even to the rightmost glyph in a line; +for large values it is thus recommended to increase the line length by +the same amount to compensate. +

+ + +
+
+
+ +

5.19.9 Italic Corrections

+ +

When typesetting adjacent glyphs from typefaces of different slants, the +space between them may require adjustment. +

+
+
Escape sequence: \/
+
+ + + + + +

Apply an italic correction: modify the spacing of the preceding +glyph so that the distance between it and the following glyph is correct +if the latter is of upright shape. For example, if an +italic ‘f’ is followed immediately by a roman right +parenthesis, then in many fonts the top right portion of +the ‘f’ overlaps the top left of the right parenthesis, which +is ugly. Use this escape sequence whenever an oblique glyph is +immediately followed by an upright glyph without any intervening space. +

+ +
+
Escape sequence: \,
+
+ + + + + +

Apply a left italic correction: modify the spacing of the +following glyph so that the distance between it and the preceding +glyph is correct if the latter is of upright shape. For example, +if a roman left parenthesis is immediately followed by an +italic ‘f’, then in many fonts the bottom left portion of +the ‘f’ overlaps the bottom of the left parenthesis, which is +ugly. Use this escape sequence whenever an upright glyph is followed +immediately by an oblique glyph without any intervening space. +

+ +
+
+
+ +

5.19.10 Dummy Characters

+ +

As discussed in Requests and Macros, the first character on an +input line is treated specially. Further, formatting a glyph has many +consequences on formatter state (see Environments). Occasionally, +we want to escape this context or embrace some of those consequences +without actually rendering a glyph to the output. +

+
+
Escape sequence: \&
+
+ + +

Interpolate a dummy character, which is constitutive of output but +invisible.81 Its presence alters the interpretation context of a +subsequent input character, and enjoys several applications. +

+
    +
  • Prevent insertion of extra space after an end-of-sentence character. + +
    +
    Test.
    +Test.
    +    ⇒ Test.  Test.
    +Test.\&
    +Test.
    +    ⇒ Test. Test.
    +
    + +
  • Prevent recognition of a control character. + +
    +
    .Test
    +    error→ warning: macro 'Test' not defined
    +\&.Test
    +    ⇒ .Test
    +
    + +
  • Prevent kerning between two glyphs. + + +
  • Translate a character to “nothing”. + +
    +
    .tr JIjiK\&k\&UVuv
    +Post universitum, alea jacta est, OK?
    +    ⇒ Post vniversitvm, alea iacta est, O?
    +
    +
+ +

The dummy character escape sequence sees use in macro definitions as a +means of ensuring that arguments are treated as text even if they begin +with spaces or control characters. +

+
+
.de HD \" typeset a simple bold heading
+.  sp
+.  ft B
+\&\\$1 \" exercise: remove the \&
+.  ft
+.  sp
+..
+.HD .\|.\|.\|surprised?
+
+
+ +

One way to think about the dummy character is to imagine placing the +symbol ‘&’ in the input at a certain location; if doing so has all +the side effects on formatting that you desire except for sticking an +ugly ampersand in the midst of your text, the dummy character is what +you want in its place. +

+
+
Escape sequence: \)
+
+ + + +

Interpolate a transparent dummy character—one that is +transparent to end-of-sentence detection. It behaves as \&, +except that \& is treated as letters and numerals normally are +after ‘.’, ‘?’ and ‘!’; \& cancels end-of-sentence +detection, and \) does not. +

+
+
.de Suffix-&
+.  nop \&\\$1
+..
+.
+.de Suffix-)
+.  nop \)\\$1
+..
+.
+Here's a sentence.\c
+.Suffix-& '
+Another one.\c
+.Suffix-) '
+And a third.
+    ⇒ Here's a sentence.' Another one.'  And a third.
+
+
+ + + + +
+
+
+
+ +

5.20 Manipulating Type Size and Vertical Spacing

+ + + + + + + + +

These concepts were introduced in Page Geometry. The height of a +font’s tallest glyph is one em, which is equal to the type size in +points.82 A vertical spacing of less than 120% of +the type size can make a document hard to read. Larger proportions can +be useful to spread the text for annotations or proofreader’s marks. By +default, GNU troff uses 10 point type on 12 point +spacing. + +Typographers call the difference between type size and vertical spacing +leading.83 +

+ + + +
+
+ +

5.20.1 Changing the Type Size

+ +
+
Request: .ps [size]
+
+
Request: .ps +size
+
Request: .ps -size
+
Escape sequence: \ssize
+
+
Register: \n[.s]
+
+ + + +

Use the ps request or the \s escape sequence to change +(increase, decrease) the type size (in scaled points). Specify +size as either an absolute type size, or as a relative change from +the current size. ps with no argument restores the previous +size. The ps request’s default scaling unit is ‘z’. The +requested size is rounded to the nearest valid size (with ties rounding +down) within the limits supported by the device. If the requested size +is non-positive, it is treated as 1u. +

+ + + +

Type size alteration is incorrectly documented in the AT&T +troff manual, which claims “if [the requested size] is invalid, +the next larger valid size will result, with a maximum of +36”.84 +

+ + +

The read-only string-valued register .s interpolates the type +size in points as a decimal fraction; it is associated with the +environment (see Environments). To obtain the type size in scaled +points, interpolate the .ps register instead (see Using Fractional Type Sizes). +

+

The \s escape sequence supports a variety of syntax forms. +

+
+
\sn
+

Set the type size to n points. n must be a single +digit. If n is 0, restore the previous size. +

+
+
\s+n
+
\s-n
+

Increase or decrease the type size by n points. +n must be exactly one digit. +

+
+
\s(nn
+

Set the type size to nn points. nn must be exactly two +digits. +

+
+
\s+(nn
+
\s-(nn
+
\s(+nn
+
\s(-nn
+

Alter the type size in points by the two-digit value nn. +

+
+ +

See Using Fractional Type Sizes, for further syntactical forms of the +\s escape sequence that additionally accept decimal fractions. +

+
+
snap, snap,
+.ps +2
+grin, grin,
+.ps +2
+wink, wink, \s+2nudge, nudge,\s+8 say no more!
+.ps 10
+
+
+ +

The \s escape sequence affects the environment immediately and +doesn’t produce an input token. Consequently, it can be used in +requests like mc, which expects a single character as an +argument, to change the type size on the fly. +

+
+
.mc \s[20]x\s[0]
+
+ +
+
Request: .sizes s1 s2 … sn [0]
+
+

The DESC file specifies which type sizes are allowed by the +output device; see DESC File Format. Use the sizes request +to change this set of permissible sizes. Arguments are in scaled +points; see Using Fractional Type Sizes. Each can be a single +type size (such as ‘12000’), or a range of sizes (such as +‘4000-72000’). You can optionally end the list with a ‘0’. +

+ +
+
+
+ +

5.20.2 Changing the Vertical Spacing

+ +
+
Request: .vs [space]
+
+
Request: .vs +space
+
Request: .vs -space
+
Register: \n[.v]
+
+ + + +

Set the vertical spacing to, or alter it by, space. The default +scaling unit is ‘p’. If vs is called without an argument, +the vertical spacing is reset to the previous value before the last call +to vs. + +GNU troff emits a warning in category ‘range’ if space +is negative; the vertical spacing is then set to the smallest possible +positive value, the vertical motion quantum (as found in the .V +register). +

+

.vs 0 isn’t saved in a diversion since it doesn’t result in +a vertical motion. You must explicitly issue this request before +interpolating the diversion. +

+

The read-only register .v contains the vertical spacing; it is +associated with the environment (see Environments). +

+ + +

When a break occurs, GNU troff performs the following procedure. +

+
    +
  • + +Move the drawing position vertically by the extra pre-vertical line +space, the minimum of all negative \x escape sequence arguments +in the pending output line. + +
  • Move the drawing position vertically by the vertical line spacing. + +
  • Write out the pending output line. + +
  • + +Move the drawing position vertically by the extra post-vertical line +space, the maximum of all positive \x escape sequence arguments +in the line that has just been output. + +
  • + +Move the drawing position vertically by the post-vertical line +spacing (see below). +
+ + +

Prefer vs or pvs over ls to produce double-spaced +documents. vs and pvs have finer granularity than +ls; moreover, some preprocessors assume single spacing. +See Manipulating Spacing, regarding the \x escape sequence and +the ls request. +

+
+
Request: .pvs [space]
+
+
Request: .pvs +space
+
Request: .pvs -space
+
Register: \n[.pvs]
+
+ + + +

Set the post-vertical spacing to, or alter it by, space. The +default scaling unit is ‘p’. If pvs is called without an +argument, the post-vertical spacing is reset to the previous value +before the last call to pvs. GNU troff emits a warning in +category ‘range’ if space is negative; the post-vertical +spacing is then set to zero. +

+

The read-only register .pvs contains the post-vertical spacing; +it is associated with the environment (see Environments). +

+ + +
+
+
+ +

5.20.3 Using Fractional Type Sizes

+ + + + + + +

AT&T troff interpreted all type size measurements in points. +Combined with integer arithmetic, this design choice made it impossible +to support, for instance, ten and a half-point type. In GNU +troff, an output device can select a scaling factor that +subdivides a point into “scaled points”. A type size expressed in +scaled points can thus represent a non-integral type size. +

+ + + + + + + + + + + +

A scaled point is equal to 1/sizescale points, where +sizescale is specified in the device description file DESC, +and defaults to 1.85 Requests and escape sequences in GNU troff interpret +arguments that represent a type size in scaled points, which the +formatter multiplies by sizescale and converts to an integer. +Arguments treated in this way comprise those to the escape sequences +\H and \s, to the request ps, the third argument to +the cs request, and the second and fourth arguments to the +tkf request. Scaled points may be specified explicitly with the +z scaling unit. +

+

For example, if sizescale is 1000, then a scaled point is one +thousandth of a point. The request ‘.ps 10.5’ is synonymous with +‘.ps 10.5z’ and sets the type size to 10,500 scaled points, or +10.5 points. Consequently, in GNU troff, the register +.s can interpolate a non-integral type size. +

+
+
Register: \n[.ps]
+
+

This read-only register interpolates the type size in scaled points; it +is associated with the environment (see Environments). +

+ +

It makes no sense to use the ‘z’ scaling unit in a numeric +expression whose default scaling unit is neither ‘u’ nor ‘z’, +so GNU troff disallows this. Similarly, it is nonsensical to use +a scaling unit other than ‘z’ or ‘u’ in a numeric expression +whose default scaling unit is ‘z’, and so GNU troff +disallows this as well. +

+

Another GNU troff scaling unit, ‘s’, multiplies by the +number of basic units in a scaled point. Thus, ‘\n[.ps]s’ is equal +to ‘1m’ by definition. Do not confuse the ‘s’ and ‘z’ +scaling units. +

+
+
Register: \n[.psr]
+
+
Register: \n[.sr]
+
+ + + + + + +

Output devices may be limited in the type sizes they can employ. The +.s and .ps registers represent the type size selected by +the output driver as it understands a device’s capability. The last +requested type size is interpolated in scaled points by the +read-only register .psr and in points as a decimal fraction by +the read-only string-valued register .sr. Both are associated +with the environment (see Environments). +

+

For example, if a type size of 10.95 points is requested, and the +nearest size permitted by a sizes request (or by the sizes +or sizescale directives in the device’s DESC file) is 11 +points, the output driver uses the latter value. +

+ +

The \s escape sequence offers the following syntax forms that +work with fractional type sizes and accept scaling units. You may of +course give them integral arguments. The delimited forms need not use +the neutral apostrophe; see Delimiters. +

+
+
\s[n]
+
\s'n'
+

Set the type size to n scaled points; n is a +numeric expression with a default scaling unit of ‘z’. +

+
+
\s[+n]
+
\s[-n]
+
\s+[n]
+
\s-[n]
+
\s'+n'
+
\s'-n'
+
\s+'n'
+
\s-'n'
+

Increase or decrease the type size by n scaled points; +n is a numeric expression (which may start with a minus sign) +with a default scaling unit of ‘z’. +

+
+ + + +
+
+
+
+ +

5.21 Colors

+ + + + + + +

GNU troff supports color output with a variety of color spaces +and up to 16 bits per channel. Some devices, particularly terminals, +may be more limited. When color support is enabled, two colors are +current at any given time: the stroke color, with which glyphs, +rules (lines), and geometric objects like circles and polygons are +drawn, and the fill color, which can be used to paint the interior +of a closed geometric figure. +

+
+
Request: .color [n]
+
+
Register: \n[.color]
+
+

If n is missing or non-zero, enable the output of color-related +device-independent output commands (this is the default); otherwise, +disable them. This request sets a global flag; it does not produce an +input token (see gtroff Internals). +

+

The read-only register .color is 1 if colors are enabled, +0 otherwise. +

+

Color can also be disabled with the -c command-line option. +

+ +
+
Request: .defcolor ident scheme color-component …
+
+

Define a color named ident. scheme selects a color space +and determines the quantity of required color-components; it must +be one of ‘rgb’ (three components), ‘cmy’ (three), ‘cmyk’ +(four), or ‘gray’ (one). ‘grey’ is accepted as a synonym of +‘gray’. The color components can be encoded as a single +hexadecimal value starting with ‘#’ or ‘##’. The former +indicates that each component is in the range 0–255 (0–FF), the latter +the range 0–65,535 (0–FFFF). +

+
+
.defcolor half gray #7f
+.defcolor pink rgb #FFC0CB
+.defcolor magenta rgb  ##ffff0000ffff
+
+ + + + +

Alternatively, each color component can be specified as a decimal +fraction in the range 0–1, interpreted using a default scaling +unit of f, which multiplies its value by 65,536 (but +clamps it at 65,535). +

+
+
.defcolor gray50 rgb 0.5 0.5 0.5
+.defcolor darkgreen rgb 0.1f 0.5f 0.2f
+
+
+ + + +

Each output device has a color named ‘default’, which cannot be +redefined. A device’s default stroke and fill colors are not +necessarily the same. For the dvi, html, pdf, +ps, and xhtml output devices, GNU troff +automatically loads a macro file defining many color names at startup. +By the same mechanism, the devices supported by grotty recognize +the eight standard ISO 6429/EMCA-48 color names.86 +

+
+
Request: .gcolor [color]
+
+
Escape sequence: \mc
+
+
Escape sequence: \m(co
+
Escape sequence: \m[color]
+
Register: \n[.m]
+
+

Set the stroke color to color. +

+
+
.gcolor red
+The next words
+.gcolor
+\m[red]are in red\m[]
+and these words are in the previous color.
+
+ +

The escape sequence \m[] restores the previous stroke color, as +does a gcolor request without an argument. +

+ + + +

The name of the current stroke color is available in the read-only +string-valued register ‘.m’; it is associated with the environment +(see Environments). It interpolates nothing when the stroke color +is the default. +

+

\m doesn’t produce an input token in GNU troff +(see gtroff Internals). It therefore can be used in requests like +mc (which expects a single character as an argument) to change +the color on the fly: +

+
+
.mc \m[red]x\m[]
+
+
+ +
+
Request: .fcolor [color]
+
+
Escape sequence: \Mc
+
+
Escape sequence: \M(co
+
Escape sequence: \M[color]
+
Register: \n[.M]
+
+

Set the fill color for objects drawn with \D'…' escape +sequences. The escape sequence \M[] restores the previous fill +color, as does an fcolor request without an argument. +

+ + + + + + +

The name of the current fill color is available in the read-only +string-valued register ‘.M’; it is associated with the environment +(see Environments). It interpolates nothing when the fill color +is the default. \M doesn’t produce an input token in GNU +troff. +

+

Create an ellipse with a red interior as follows. +

+
+
\M[red]\h'0.5i'\D'E 2i 1i'\M[]
+
+
+ + + +
+
+
+ +

5.22 Strings

+ + +

GNU troff supports strings primarily for user convenience. +Conventionally, if one would define a macro only to interpolate a small +amount of text, without invoking requests or calling any other macros, +one defines a string instead. Only one string is predefined by the +language. +

+
+
String: \*[.T]
+
+ + +

Contains the name of the output device (for example, ‘utf8’ or +‘pdf’). +

+ +

The ds request creates a string with a specified name and +contents and the \* escape sequence dereferences its name, +interpolating its contents. If the string named by the \* escape +sequence does not exist, it is defined as empty, nothing is +interpolated, and a warning in category ‘mac’ is emitted. +See Warnings, for information about the enablement and suppression of +warnings. +

+
+
Request: .ds name [contents]
+
+
Request: .ds1 name [contents]
+
+
Escape sequence: \*n
+
+
Escape sequence: \*(nm
+
Escape sequence: \*[name [arg1 arg2 …]]
+
+ + + + + +

Define a string called name with contents contents. If +name already exists as an alias, the target of the alias is +redefined; see als and rm below. If ds is called +with only one argument, name is defined as an empty string. +Otherwise, GNU troff stores contents in copy +mode.87 +

+

The \* escape sequence interpolates a previously defined string +variable name (one-character name n, two-character name +nm). The bracketed interpolation form accepts arguments that are +handled as macro arguments are; recall Calling Macros. In +contrast to macro calls, however, if a closing bracket ‘]’ occurs +in a string argument, that argument must be enclosed in double quotes. +\* is interpreted even in copy mode. When defining strings, +argument interpolations must be escaped if they are to reference +parameters from the calling context; See Parameters. +

+
+
.ds cite (\\$1, \\$2)
+Gray codes are explored in \*[cite Morgan 1998].
+    ⇒ Gray codes are explored in (Morgan, 1998).
+
+ + + + + +

Caution: Unlike other requests, the second argument to the +ds request consumes the remainder of the input line, including +trailing spaces. This means that comments on a line with such a request +can introduce unwanted space into a string when they are set off from +the material they annotate, as is conventional. +

+
+
.ds H2O H\v'+.3m'\s'-2'2\v'-.3m'\s0O \" water
+
+ +

Instead, place the comment on another line or put the comment escape +sequence immediately adjacent to the last character of the string. +

+
+
.ds H2O H\v'+.3m'\s'-2'2\v'-.3m'\s0O\" water
+
+ +

Ending string definitions (and appendments) with a comment, even an +empty one, prevents unwanted space from creeping into them during source +document maintenance. +

+
+
.ds author Alice Pleasance Liddell\"
+.ds empty \" might be appended to later with .as
+
+ + + + + + + +

An initial neutral double quote " in contents is stripped +to allow embedding of leading spaces. Any other " is interpreted +literally, but it is wise to use the special character escape sequence +\[dq] instead if the string might be interpolated as part of a +macro argument; see Calling Macros. +

+
+
.ds salutation "         Yours in a white wine sauce,\"
+.ds c-var-defn "  char mydate[]=\[dq]2020-07-29\[dq];\"
+
+ + + + + +

Strings are not limited to a single input line of text. +\RET works just as it does elsewhere. The resulting string +is stored without the newlines. Care is therefore required when +interpolating strings while filling is disabled. +

+
+
.ds foo This string contains \
+text on multiple lines \
+of input.
+
+ +

It is not possible to embed a newline in a string that will be +interpreted as such when the string is interpolated. To achieve that +effect, use \* to interpolate a macro instead; see Punning Names. +

+

Because strings are similar to macros, they too can be defined so as to +suppress AT&T troff compatibility mode when used; see +Writing Macros and Compatibility Mode. The ds1 +request defines a string such that compatibility mode is off when the +string is later interpolated. To be more precise, a compatibility +save input token is inserted at the beginning of the string, and a +compatibility restore input token at the end. +

+
+
.nr xxx 12345
+.ds aa The value of xxx is \\n[xxx].
+.ds1 bb The value of xxx is \\n[xxx].
+.
+.cp 1
+.
+\*(aa
+    error→ warning: register '[' not defined
+    ⇒ The value of xxx is 0xxx].
+\*(bb
+    ⇒ The value of xxx is 12345.
+
+
+ +
+
Request: .as name [contents]
+
+
Request: .as1 name [contents]
+
+ + +

The as request is similar to ds but appends contents +to the string stored as name instead of redefining it. If +name doesn’t exist yet, it is created. If as is called +with only one argument, no operation is performed (beyond dereferencing +the string). +

+
+
.as salutation " with shallots, onions and garlic,\"
+
+ +

The as1 request is similar to as, but compatibility mode +is switched off when the appended portion of the string is later +interpolated. To be more precise, a compatibility save input +token is inserted at the beginning of the appended string, and a +compatibility restore input token at the end. +

+ +

Several requests exist to perform rudimentary string operations. +Strings can be queried (length) and modified (chop, +substring, stringup, stringdown), and their names +can be manipulated through renaming, removal, and aliasing (rn, +rm, als). +

+
+
Request: .length reg anything
+
+ + + + + +

Compute the number of characters of anything and store the count +in the register reg. If reg doesn’t exist, it is created. +anything is read in copy mode. +

+
+
.ds xxx abcd\h'3i'efgh
+.length yyy \*[xxx]
+\n[yyy]
+    ⇒ 14
+
+
+ +
+
Request: .chop object
+
+

Remove the last character from the macro, string, or diversion named +object. This is useful for removing the newline from the end of a +diversion that is to be interpolated as a string. This request can be +used repeatedly on the same object; see gtroff Internals, +for details on nodes inserted additionally by GNU troff. +

+ +
+
Request: .substring str start [end]
+
+ +

Replace the string named str with its substring bounded by the +indices start and end, inclusively. The first character in +the string has index 0. If end is omitted, it is implicitly +set to the largest valid value (the string length minus one). Negative +indices count backward from the end of the string: the last character +has index −1, the character before the last has +index −2, and so on. +

+
+
.ds xxx abcdefgh
+.substring xxx 1 -4
+\*[xxx]
+    ⇒ bcde
+.substring xxx 2
+\*[xxx]
+    ⇒ de
+
+
+ +
+
Request: .stringdown str
+
+
Request: .stringup str
+
+ + + + + +

Alter the string named str by replacing each of its bytes with its +lowercase (stringdown) or uppercase (stringup) version (if +one exists). Special characters in the string will often transform in +the expected way due to the regular naming convention for accented +characters. When they do not, use substrings and/or catenation. +

+
+
.ds resume R\['e]sum\['e]
+\*[resume]
+.stringdown resume
+\*[resume]
+.stringup resume
+\*[resume]
+    ⇒ Résumé résumé RÉSUMÉ
+
+
+ +

(In practice, we would end the ds request with a comment escape +\" to prevent space from creeping into the definition during +source document maintenance.) +

+
+
Request: .rn old new
+
+ + + + + + + + +

Rename the request, macro, diversion, or string old to new. +

+ +
+
Request: .rm name
+
+ + + + + + + + +

Remove the request, macro, diversion, or string name. GNU +troff treats subsequent invocations as if the name had never +been defined. +

+ +
+
Request: .als new old
+
+ + + + + + + + + +

Create an alias new for the existing request, string, macro, or +diversion object named old, causing the names to refer to the same +stored object. If old is undefined, a warning in category +‘mac’ is produced, and the request is ignored. See Warnings, +for information about the enablement and suppression of warnings. +

+

To understand how the als request works, consider two different +storage pools: one for objects (macros, strings, etc.), and another +for names. As soon as an object is defined, GNU troff adds it to +the object pool, adds its name to the name pool, and creates a link +between them. When als creates an alias, it adds a new name to +the name pool that gets linked to the same object as the old name. +

+

Now consider this example. +

+
+
.de foo
+..
+.
+.als bar foo
+.
+.de bar
+.  foo
+..
+.
+.bar
+    error→ input stack limit exceeded (probable infinite
+    error→ loop)
+
+ +

In the above, bar remains an alias—another name +for—the object referred to by foo, which the second de +request replaces. Alternatively, imagine that the de request +dereferences its argument before replacing it. Either way, the +result of calling bar is a recursive loop that finally leads to +an error. See Writing Macros. +

+ + + + + + + + + +

To remove an alias, call rm on its name. The object itself is +not destroyed until it has no more names. +

+

When a request, macro, string, or diversion is aliased, redefinitions +and appendments “write through” alias names. To replace an alias with +a separately defined object, you must use the rm request on its +name first. +

+ + + +
+
+
+ +

5.23 Conditionals and Loops

+ + + +

groff has if and while control structures like +other languages. However, the syntax for grouping multiple input lines +in the branches or bodies of these structures is unusual. +

+ + + +
+
+ +

5.23.1 Operators in Conditionals

+ + + + + + +

In if, ie, and while requests, in addition to the +numeric expressions described in Numeric Expressions, several +Boolean operators are available; the members of this expanded class are +termed conditional expressions. +

+
+
c glyph
+

True if glyph is available, where glyph is an ordinary +character, a special character ‘\(xx’ or ‘\[xxx]’, +‘\N'xxx'’, or has been defined by any of the char, +fchar, fschar, or schar requests. +

+
+
d name
+

True if a string, macro, diversion, or request called name exists. +

+
+
e
+

True if the current page is even-numbered. +

+
+
F font
+

True if font exists. font is handled as if it were opened +with the ft request (that is, font translation and styles are +applied), without actually mounting it. +

+
+
m color
+

True if color is defined. +

+
+
n
+
+ +

True if the document is being processed in nroff mode. +See troff and nroff Modes. +

+
+
o
+

True if the current page is odd-numbered. +

+
+
r register
+

True if register exists. +

+
+
S style
+

True if style is available for the current font family. Font +translation is applied. +

+
+
t
+

True if the document is being processed in troff mode. +See troff and nroff Modes. +

+ +
+
v
+

Always false. This condition is recognized only for compatibility with +certain other troff implementations.88 +

+
+ +

If the first argument to an if, ie, or while +request begins with a non-alphanumeric character apart from ! +(see below); it performs an output comparison test. +89 +

+ +
+
'xxx'yyy'
+

True if formatting the comparands xxx and yyy produces the +same output commands. The delimiter need not be a neutral apostrophe: +the output comparison operator accepts the same delimiters as most +escape sequences; see Delimiters. This output comparison +operator formats xxx and yyy in separate environments; +after the comparison, the resulting data are discarded. +

+
+
.ie "|"\fR|\fP" true
+.el false
+    ⇒ true
+
+ +

The resulting glyph properties, including font family, style, size, and +slant, must match, but not necessarily the requests and/or escape +sequences used to obtain them. In the previous example, ‘|’ and +‘\fR|\fP’ result in ‘|’ glyphs in the same typefaces at the +same positions, so the comparands are equal. If ‘.ft I’ had +been added before the ‘.ie’, they would differ: the first ‘|’ +would produce an italic ‘|’, not a roman one. Motions must match +in orientation and magnitude to within the applicable horizontal and +vertical motion quanta of the device, after rounding. ‘.if +"\u\d"\v'0'"’ is false even though both comparands result in zero net +motion, because motions are not interpreted or optimized but sent as-is +to the output.90 On the other hand, ‘.if "\d"\v'0.5m'"’ is true, because +\d is defined as a downward motion of one-half em.91 +

+ + +

Surround the comparands with \? to avoid formatting them; this +causes them to be compared character by character, as with string +comparisons in other programming languages. +

+
+
.ie "\?|\?"\?\fR|\fP\?" true
+.el false
+    ⇒ false
+
+ + + + +

Since comparands protected with \? are read in copy mode +(see Copy Mode), they need not even be valid groff syntax. +The escape character is still lexically recognized, however, and +consumes the next character. +

+
+
.ds a \[
+.ds b \[
+.if '\?\*a\?'\?\*b\?' a and b equivalent
+.if '\?\\?'\?\\?' backslashes equivalent
+    ⇒ a and b equivalent
+
+
+
+ +

The above operators can’t be combined with most others, but a leading +‘!’, not followed immediately by spaces or tabs, complements an +expression. +

+
+
.nr x 1
+.ie !r x register x is not defined
+.el      register x is defined
+    ⇒ register x is defined
+
+ +

Spaces and tabs are optional immediately after the ‘c’, ‘d’, +‘F’, ‘m’, ‘r’, and ‘S’ operators, but right after +‘!’, they end the predicate and the conditional evaluates +true.92 +

+
+
.nr x 1
+.ie ! r x register x is not defined
+.el       register x is defined
+    ⇒ r x register x is not defined
+
+ +

The unexpected ‘r x’ in the output is a clue that our conditional +was not interpreted as we planned, but matters may not always be so +obvious. +

+ +
+
+
+ +

5.23.2 if-then

+ + +
+
Request: .if cond-expr anything
+
+

Evaluate the conditional expression cond-expr, and if it evaluates +true (or to a positive value), interpret the remainder of the line +anything as if it were an input line. Recall from Invoking Requests that any quantity of spaces between arguments to requests +serves only to separate them; leading spaces in anything are thus +not seen. anything effectively cannot be omitted; if +cond-expr is true and anything is empty, the newline at the +end of the control line is interpreted as a blank input line (and +therefore a blank text line). +

+
+
super\c
+tanker
+.nr force-word-break 1
+super\c
+.if ((\n[force-word-break] = 1) & \n[.int])
+tanker
+    ⇒ supertanker super tanker
+
+
+ +
+
Request: .nop anything
+
+

Interpret anything as if it were an input line. This is similar +to ‘.if 1’. nop is not really “no operation”; its +argument is processed—unconditionally. It can be used to cause +text lines to share indentation with surrounding control lines. +

+
+
.als real-MAC MAC
+.de wrapped-MAC
+.  tm MAC: called with arguments \\$@
+.  nop \\*[real-MAC]\\
+..
+.als MAC wrapped-MAC
+\# Later...
+.als MAC real-MAC
+
+ +

In the above, we’ve used aliasing, nop, and the interpolation of +a macro as a string to interpose a wrapper around the macro ‘MAC’ +(perhaps to debug it). +

+ + +
+
+
+ +

5.23.3 if-else

+ + +
+
Request: .ie cond-expr anything
+
+
Request: .el anything
+
+

Use the ie and el requests to write an if-then-else. The +first request is the “if” part and the latter is the “else” part. +Unusually among programming languages, any number of non-conditional +requests may be interposed between the ie branch and the +el branch. +

+
+
.nr a 0
+.ie \na a is non-zero.
+.nr a +1
+.el a was not positive but is now \na.
+    ⇒ a was not positive but is now 1.
+
+ +

Another way in which el is an ordinary request is that it does +not lexically “bind” more tightly to its ie counterpart than it +does to any other request. This fact can surprise C programmers. +

+
+
.nr a 1
+.nr z 0
+.ie \nz \
+.  ie \na a is true
+.  el     a is false
+.el z is false
+    error→ warning: unbalanced 'el' request
+    ⇒ a is false
+
+ +

To conveniently nest conditionals, keep reading. +

+
+ + +
+
+
+ +

5.23.4 Conditional Blocks

+ + + +

It is frequently desirable for a control structure to govern more than +one request, macro call, text line, or a combination of the foregoing. +The opening and closing brace escape sequences \{ and \} +define such groups. These conditional blocks can furthermore be +nested. +

+
+
Escape sequence: \{
+
+
Escape sequence: \}
+
+ + + + + + + + + + + + + +

\{ begins a conditional block; it must appear (after optional +spaces and tabs) immediately subsequent to the conditional expression of +an if, ie, or while +request,93 or as the argument to an el +request. +

+

\} ends a condition block and should appear on a line with other +occurrences of itself as necessary to match \{ sequences. It +can be preceded by a control character, spaces, and tabs. Input after +any quantity of \} sequences on the same line is processed only +if all of the preceding conditions to which they correspond are true. +Furthermore, a \} closing the body of a while request +must be the last such escape sequence on an input line. +

+

Brace escape sequences outside of control structures have no meaning and +produce no output. +

+

Caution: Input lines using \{ often end with +\RET, especially in macros that consist primarily of control +lines. Forgetting to use \RET on an input line after \{ +is a common source of error. +

+ +

We might write the following in a page header macro. If we delete +\RET, the header will carry an unwanted extra empty line (except +on page 1). +

+
+
.if (\\n[%] != 1) \{\
+.  ie ((\\n[%] % 2) = 0) .tl \\*[even-numbered-page-title]
+.  el                    .tl \\*[odd-numbered-page-title]
+.\}
+
+ +

Let us take a closer look at how conditional blocks nest. +

+
+
A
+.if 0 \{ B
+C
+D
+\}E
+F
+    ⇒ A F
+
+ +
+
N
+.if 1 \{ O
+.  if 0 \{ P
+Q
+R\} S\} T
+U
+    ⇒ N O U
+
+ +

The above behavior may challenge the intuition; it was implemented to +retain compatibility with AT&T troff. For clarity, it +is idiomatic to end input lines with \{ (followed by +\RET if appropriate), and to precede \} on an input +line with nothing more than a control character, spaces, tabs, and other +instances of itself. +

+

We can use ie, el, and conditional blocks to simulate the +multi-way “switch” or “case” control structures of other languages. +The following example is adapted from the groff man +package. Indentation is used to clarify the logic. +

+
+
.\" Simulate switch/case in roff.
+.      ie '\\$2'1' .ds title General Commands\"
+.el \{.ie '\\$2'2' .ds title System Calls\"
+.el \{.ie '\\$2'3' .ds title Library Functions\"
+.el \{.ie '\\$2'4' .ds title Kernel Interfaces\"
+.el \{.ie '\\$2'5' .ds title File Formats\"
+.el \{.ie '\\$2'6' .ds title Games\"
+.el \{.ie '\\$2'7' .ds title Miscellaneous Information\"
+.el \{.ie '\\$2'8' .ds title System Management\"
+.el \{.ie '\\$2'9' .ds title Kernel Development\"
+.el                .ds title \" empty
+.\}\}\}\}\}\}\}\}
+
+ + +
+
+
+ +

5.23.5 while

+ + +

groff provides a looping construct: the while request. +Its syntax matches the if request. +

+ +
+
Request: .while cond-expr anything
+
+

Evaluate the conditional expression cond-expr, and repeatedly +execute anything unless and until cond-expr evaluates false. +anything, which is often a conditional block, is referred to as +the while request’s body. +

+
+
.nr a 0 1
+.while (\na < 9) \{\
+\n+a,
+.\}
+\n+a
+    ⇒ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
+
+ + +

GNU troff treats the body of a while request similarly to +that of a de request (albeit one not read in copy +mode94), but stores it under an internal name +and deletes it when the loop finishes. The operation of a macro +containing a while request can slow significantly if the +while body is large. Each time the macro is executed, the +while body is parsed and stored again. +

+
+
.de xxx
+.  nr num 10
+.  while (\\n[num] > 0) \{\
+.    \" many lines of code
+.    nr num -1
+.  \}
+..
+
+ + + +

An often better solution—and one that is more portable, since +AT&T troff lacked the while request—is to +instead write a recursive macro. It will be parsed only +once.95 +

+
+
.de yyy
+.  if (\\n[num] > 0) \{\
+.    \" many lines of code
+.    nr num -1
+.    yyy
+.  \}
+..
+.
+.de xxx
+.  nr num 10
+.  yyy
+..
+
+ +

To prevent infinite loops, the default number of available recursion +levels is 1,000 or somewhat less.96 You can +disable this protective measure, or raise the limit, by setting the +slimit register. See Debugging. +

+

As noted above, if a while body begins with a conditional block, +its closing brace must end an input line. +

+
+
.if 1 \{\
+.  nr a 0 1
+.  while (\n[a] < 10) \{\
+.    nop \n+[a]
+.\}\}
+    error→ unbalanced brace escape sequences
+
+
+ +
+
Request: .break
+
+ + + +

Exit a while loop. Do not confuse this request with a +typographical break or the br request. +

+ +
+
Request: .continue
+
+

Skip the remainder of a while loop’s body, immediately starting +the next iteration. +

+ + + +
+
+
+
+ +

5.24 Writing Macros

+ + + +

A macro is a stored collection of text and control lines that can +be interpolated multiple times. Use macros to define common operations. +Macros are called in the same way that requests are invoked. While +requests exist for the purpose of creating macros, simply calling an +undefined macro, or interpolating it as a string, will cause it to be +defined as empty. See Identifiers. +

+
+
Request: .de name [end]
+
+

Define a macro name, replacing the definition of any existing +request, macro, string, or diversion called name. If +name already exists as an alias, the target of the alias is +redefined; recall Strings. GNU troff enters copy +mode,97 storing subsequent input lines as the +macro definition. If the optional second argument is not specified, the +definition ends with the control line ‘..’ (two dots). +Alternatively, end identifies a macro whose call syntax at the +start of a control line ends the definition of name; end is +then called normally. A macro definition must end in the same +conditional block (if any) in which it began (see Conditional Blocks). Spaces or tabs are permitted after the control character in +the line containing this ending token (either ‘.’ or +‘end’), but a tab immediately after the token prevents its +recognition as the end of a macro definition. The macro end can +be called with arguments.98 +

+

Here is a small example macro called ‘P’ that causes a break and +inserts some vertical space. It could be used to separate paragraphs. +

+
+
.de P
+.  br
+.  sp .8v
+..
+
+ +

We can define one macro within another. Attempting to nest ‘..’ +naďvely will end the outer definition because the inner definition +isn’t interpreted as such until the outer macro is later interpolated. +We can use an end macro instead. Each level of nesting should use a +unique end macro. +

+

An end macro need not be defined until it is called. This fact enables +a nested macro definition to begin inside one macro and end inside +another. Consider the following example.99 +

+
+
.de m1
+.  de m2 m3
+you
+..
+.de m3
+Hello,
+Joe.
+..
+.de m4
+do
+..
+.m1
+know?
+.  m3
+What
+.m4
+.m2
+    ⇒ Hello, Joe.  What do you know?
+
+ +

A nested macro definition can be terminated with ‘..’ and +nested macros can reuse end macros, but these control lines must +be escaped multiple times for each level of nesting. The necessity of +this escaping and the utility of nested macro definitions will become +clearer when we employ macro parameters and consider the behavior of +copy mode in detail. +

+ +

de defines a macro that inherits the compatibility mode +enablement status of its context (see Implementation Differences). +Often it is desirable to make a macro that uses groff features +callable from contexts where compatibility mode is on; for instance, +when writing extensions to a historical macro package. To achieve this, +compatibility mode needs to be switched off while such a macro is +interpreted—without disturbing that state when it is finished. +

+
+
Request: .de1 name [end]
+
+

The de1 request defines a macro to be interpreted with +compatibility mode disabled. When name is called, compatibility +mode enablement status is saved; it is restored when the call completes. +Observe the extra backlash before the interpolation of register +‘xxx’; we’ll explore this subject in Copy Mode. +

+
+
.nr xxx 12345
+.de aa
+The value of xxx is \\n[xxx].
+.  br
+..
+.de1 bb
+The value of xxx is \\n[xxx].
+..
+.cp 1
+.aa
+    error→ warning: register '[' not defined
+    ⇒ The value of xxx is 0xxx].
+.bb
+    ⇒ The value of xxx is 12345.
+
+
+ +
+
Request: .dei name [end]
+
+
Request: .dei1 name [end]
+
+

The dei request defines a macro with its name and end +macro indirected through strings. That is, it interpolates strings +named name and end before performing the definition. +

+

The following examples are equivalent. +

+
+
.ds xx aa
+.ds yy bb
+.dei xx yy
+
+ +
+
.de aa bb
+
+ +

The dei1 request bears the same relationship to dei as +de1 does to de; it temporarily turns compatibility mode +off when name is called. +

+ +
+
Request: .am name [end]
+
+
Request: .am1 name [end]
+
+
Request: .ami name [end]
+
+
Request: .ami1 name [end]
+
+ + +

am appends subsequent input lines to macro name, extending +its definition, and otherwise working as de does. +

+

To make the previously defined ‘P’ macro set indented instead of +block paragraphs, add the necessary code to the existing macro. +

+
+
.am P
+.ti +5n
+..
+
+ +

The other requests are analogous to their ‘de’ counterparts. The +am1 request turns off compatibility mode during interpretation of +the appendment. The ami request appends indirectly, meaning that +strings name and end are interpolated with the resulting +names used before appending. The ami1 request is similar to +ami, disabling compatibility mode during interpretation of the +appended lines. +

+ + +

Using trace.tmac, you can trace calls to de, +de1, am, and am1. You can also use the +backtrace request at any point desired to troubleshoot tricky +spots (see Debugging). +

+

See Strings, for the als, rm, and rn requests to +create an alias of, remove, and rename a macro, respectively. +

+ +

Macro identifiers share their name space with requests, strings, and +diversions; see Identifiers. The am, as, da, +de, di, and ds requests (together with their +variants) create a new object only if the name of the macro, diversion, +or string is currently undefined or if it is defined as a request; +normally, they modify the value of an existing object. See the +description of the als request, for pitfalls when redefining a +macro that is aliased. +

+
+
Request: .return [anything]
+
+

Exit a macro, immediately returning to the caller. If called with an +argument anything, exit twice—the current macro and the macro +one level higher. This is used to define a wrapper macro for +return in trace.tmac. +

+ + + + +
+
+ +

5.24.1 Parameters

+ + +

Macro calls and string interpolations optionally accept a list of +arguments; recall Calling Macros. At the time such an +interpolation takes place, these parameters can be examined using +a register and a variety of escape sequences starting with ‘\$’. +All such escape sequences are interpreted even in copy mode, a fact we +shall motivate and explain below (see Copy Mode). +

+
+
Register: \n[.$]
+
+ +

The count of parameters available to a macro or string is kept in this +read-only register. The shift request can change its value. +

+ +

Any individual parameter can be accessed by its position in the list of +arguments to the macro call, numbered from left to right starting at 1, +with one of the following escape sequences. +

+
+
Escape sequence: \$n
+
+
Escape sequence: \$(nn
+
Escape sequence: \$[nnn]
+

Interpolate the nth, nnth, or nnnth parameter. The +first form expects only a single digit (1≤n≤9)), the +second two digits (01≤nn≤99)), and the third any +positive integer nnn. Macros and strings accept an unlimited +number of parameters. +

+ +
+
Request: .shift [n]
+
+

Shift the parameters n places (1 by default). This is a +“left shift”: what was parameter i becomes parameter +i-n. The parameters formerly in positions 1 +to n are no longer available. Shifting by a non-positive +amount performs no operation. The register .$ is adjusted +accordingly. +

+ + + + + +

In practice, parameter interpolations are usually seen prefixed with an +extra escape character. This is because the \$ family of escape +sequences is interpreted even in copy mode.100 +

+
+
Escape sequence: \$*
+
+
Escape sequence: \$@
+
+
Escape sequence: \$^
+
+

In some cases it is convenient to interpolate all of the parameters at +once (to pass them to a request, for instance). The \$* escape +concatenates the parameters, separating them with spaces. \$@ +is similar, concatenating the parameters, surrounding each with double +quotes and separating them with spaces. If not in compatibility mode, +the interpolation depth of double quotes is preserved (see Calling Macros). \$^ interpolates all parameters as if they were +arguments to the ds request. +

+
+
.de foo
+. tm $1='\\$1'
+. tm $2='\\$2'
+. tm $*='\\$*'
+. tm $@='\\$@'
+. tm $^='\\$^'
+..
+.foo " This is a "test"
+    error→ $1=' This is a '
+    error→ $2='test"'
+    error→ $*=' This is a  test"'
+    error→ $@='" This is a " "test""'
+    error→ $^='" This is a "test"'
+
+ +

\$* is useful when writing a macro that doesn’t need to +distinguish its arguments, or even to not interpret them; examples +include macros that produce diagnostic messages by wrapping the +tm or ab requests. Use \$@ when writing a macro +that may need to shift its parameters and/or wrap a macro or request +that finds the count significant. If in doubt, prefer \$@ to +\$*. An application of \$^ is seen in trace.tmac, +which redefines some requests and macros for debugging purposes. +

+ +
+
Escape sequence: \$0
+
+ + +

Interpolate the name by which the macro being interpreted was called. +The als request can cause a macro to have more than one name. +Applying string interpolation to a macro does not change this name. +

+
+
.de foo
+.  tm \\$0
+..
+.als bar foo
+.
+.de aaa
+.  foo
+..
+.de bbb
+.  bar
+..
+.de ccc
+\\*[foo]\\
+..
+.de ddd
+\\*[bar]\\
+..
+.
+.aaa
+    error→ foo
+.bbb
+    error→ bar
+.ccc
+    error→ ccc
+.ddd
+    error→ ddd
+
+
+ + +
+
+
+ +

5.24.2 Copy Mode

+ + + + + + + + + +

When GNU troff processes certain requests, most importantly those +which define or append to a macro or string, it does so in copy +mode: it copies the characters of the definition into a dedicated +storage region, interpolating the escape sequences \n, \g, +\$, \*, \V, and \? normally; interpreting +\RET immediately; discarding comments \" and +\#; interpolating the current leader, escape, or tab character +with \a, \e, and \t, respectively; and storing all +other escape sequences in an encoded form. +

+ + +

The complement of copy mode—a roff formatter’s behavior when +not defining or appending to a macro, string, or diversion—where all +macros are interpolated, requests invoked, and valid escape sequences +processed immediately upon recognition, can be termed +interpretation mode. +

+
+
Escape sequence: \\
+
+

The escape character, \ by default, can escape itself. This +enables you to control whether a given \n, \g, \$, +\*, \V, or \? escape sequence is interpreted at the +time the macro containing it is defined, or later when the macro is +called.101 +

+
+
.nr x 20
+.de y
+.nr x 10
+\&\nx
+\&\\nx
+..
+.y
+    ⇒ 20 10
+
+ +

You can think of \\ as a “delayed” backslash; it is the escape +character followed by a backslash from which the escape character has +removed its special meaning. Consequently, ‘\\’ is not an escape +sequence in the usual sense. In any escape sequence ‘\X’ +that GNU troff does not recognize, the escape character is +ignored and X is output. An unrecognized escape sequence causes +a warning in category ‘escape’, with two exceptions—‘\\’ is +the first. +

+ + +
+
Escape sequence: \.
+
+

\. escapes the control character. It is similar to \\ in +that it isn’t a true escape sequence. It is used to permit nested macro +definitions to end without a named macro call to conclude them. Without +a syntax for escaping the control character, this would not be possible. +

+
+
.de m1
+foo
+.
+.  de m2
+bar
+\\..
+.
+..
+.m1
+.m2
+    ⇒ foo bar
+
+ +

The first backslash is consumed while the macro is read, and the second +is interpreted when macro m1 is called. +

+ +

roff documents should not use the \\ or \. +character sequences outside of copy mode; they serve only to obfuscate +the input. Use \e to represent the escape character, +\[rs] to obtain a backslash glyph, and \& before ‘.’ +and ‘'’ where GNU troff expects them as control characters +if you mean to use them literally (recall Requests and Macros). +

+

Macro definitions can be nested to arbitrary depth. The mechanics of +parsing the escape character have significant consequences for this +practice. +

+
+
.de M1
+\\$1
+.  de M2
+\\\\$1
+.    de M3
+\\\\\\\\$1
+\\\\..
+.    M3 hand.
+\\..
+.  M2 of
+..
+This understeer is getting
+.M1 out
+    ⇒ This understeer is getting out of hand.
+
+ +

Each escape character is interpreted twice—once in copy mode, when the +macro is defined, and once in interpretation mode, when the macro is +called. As seen above, this fact leads to exponential growth in the +quantity of escape characters required to delay interpolation of +\n, \g, \$, \*, \V, and \? at +each nesting level, which can be daunting. GNU troff offers a +solution. +

+
+
Escape sequence: \E
+
+

\E represents an escape character that is not interpreted in copy +mode. You can use it to ease the writing of nested macro definitions. +

+
+
.de M1
+.  nop \E$1
+.  de M2
+.    nop \E$1
+.    de M3
+.      nop \E$1
+\\\\..
+.    M3 better.
+\\..
+.  M2 bit
+..
+This vehicle handles
+.M1 a
+    ⇒ This vehicle handles a bit better.
+
+ +

Observe that because \. is not a true escape sequence, we can’t +use \E to keep ‘..’ from ending a macro definition +prematurely. If the multiplicity of backslashes complicates +maintenance, use end macros. +

+

\E is also convenient to define strings containing escape +sequences that need to work when used in copy mode (for example, as +macro arguments), or which will be interpolated at varying macro nesting +depths. We might define strings to begin and end superscripting +as follows.102 +

+
+
.ds { \v'-.9m\s'\En[.s]*7u/10u'+.7m'
+.ds } \v'-.7m\s0+.9m'
+
+ +

When the ec request is used to redefine the escape character, +\E also makes it easier to distinguish the semantics of an escape +character from the other meaning(s) its character might have. Consider +the use of an unusual escape character, ‘-’. +

+
+
.nr a 1
+.ec -
+.de xx
+--na
+..
+.xx
+    ⇒ -na
+
+ +

This result may surprise you; some people expect ‘1’ to be output +since register ‘a’ has clearly been defined with that value. What +has happened? The robotic replacement of ‘\’ with ‘-’ has led +us astray. You might recognize the sequence ‘--’ more readily with +the default escape character as ‘\-’, the special character escape +sequence for the minus sign glyph. +

+
+
.nr a 1
+.ec -
+.de xx
+-Ena
+..
+.xx
+    ⇒ 1
+
+
+ + + +
+
+
+
+ +

5.25 Page Motions

+ + + +

See Manipulating Spacing, for a discussion of the most commonly used +request for vertical motion, sp, which spaces downward by one +vee. +

+
+
Request: .mk [reg]
+
+
Request: .rt [dist]
+
+ + + + + + + + +

You can mark a location on a page for subsequent return. +mk takes an argument, a register name in which to store the +current page location. If given no argument, it stores the location in +an internal register. This location can be used later by the rt +or the sp requests (or the \v escape). +

+

The rt request returns upward to the location marked with +the last mk request. If used with an argument, it returns to a +vertical position dist from the top of the page (no previous +call to mk is necessary in this case). The default scaling +unit is ‘v’. +

+

If a page break occurs between a mk request and its matching +rt request, the rt request is silently ignored. +

+

A simple implementation of a macro to set text in two columns follows. +

+
+
.nr column-length 1.5i
+.nr column-gap 4m
+.nr bottom-margin 1m
+.
+.de 2c
+.  br
+.  mk
+.  ll \\n[column-length]u
+.  wh -\\n[bottom-margin]u 2c-trap
+.  nr right-side 0
+..
+.
+.de 2c-trap
+.  ie \\n[right-side] \{\
+.    nr right-side 0
+.    po -(\\n[column-length]u + \\n[column-gap]u)
+.    \" remove trap
+.    wh -\\n[bottom-margin]u
+.  \}
+.  el \{\
+.    \" switch to right side
+.    nr right-side 1
+.    po +(\\n[column-length]u + \\n[column-gap]u)
+.    rt
+.  \}
+..
+
+ +

Now let us apply our two-column macro. +

+
+
.pl 1.5i
+.ll 4i
+This is a small test that shows how the
+rt request works in combination with mk.
+
+.2c
+Starting here, text is typeset in two columns.
+Note that this implementation isn't robust
+and thus not suited for a real two-column
+macro.
+    ⇒ This is a small test that shows how the
+    ⇒ rt request works in combination with mk.
+    ⇒
+    ⇒ Starting  here,    isn't    robust
+    ⇒ text is typeset    and   thus  not
+    ⇒ in two columns.    suited  for   a
+    ⇒ Note that  this    real two-column
+    ⇒ implementation     macro.
+
+
+ +

Several escape sequences enable fine control of movement about the page. +

+
+
Escape sequence: \v'expr'
+
+ + +

Vertically move the drawing position. expr indicates the +magnitude of motion: positive is downward and and negative upward. The +default scaling unit is ‘v’. The motion is relative to the current +drawing position unless expr begins with the boundary-relative +motion operator ‘|’. See Numeric Expressions. +

+

Text processing continues at the new drawing position; usually, vertical +motions should be in balanced pairs to avoid a confusing page layout. +

+

\v will not spring a vertical position trap. This can be useful; +for example, consider a page bottom trap macro that prints a marker in +the margin to indicate continuation of a footnote. See Traps. +

+ +

A few escape sequences that produce vertical motion are unusual. They +are thought to originate early in AT&T nroff history to achieve +super- and subscripting by half-line motions on line printers and +teletypewriters before the phototypesetter made more precise positioning +available. They are reckoned in ems—not vees—to maintain continuity +with their original purpose of moving relative to the size of the type +rather than the distance between text baselines (vees).103 +

+
+
Escape sequence: \r
+
+
Escape sequence: \u
+
+
Escape sequence: \d
+
+

Move upward 1m, upward .5m, and +downward .5m, respectively. +

+ +

Let us see these escape sequences in use. +

+
+
Obtain 100 cm\u3\d of \ka\d\092\h'|\nau'\r233\dU.
+
+ +

In the foregoing we have paired \u and \d to typeset a +superscript, and later a full em negative (“reverse”) motion to place +a superscript above a subscript. A numeral-width horizontal motion +escape sequence aligns the proton and nucleon numbers, while \k +marks a horizontal position to which \h returns so that we could +stack them. (We shall discuss these horizontal motion escape sequences +presently.) In serious applications, we often want to alter the type +size of the -scripts and to fine-tune the vertical motions, as the +groff ms package does with its super- and subscripting +string definitions. +

+
+
Escape sequence: \h'expr'
+
+ + + + + +

Horizontally move the drawing position. expr indicates the +magnitude of motion: positive is rightward and negative leftward. The +default scaling unit is ‘m’. The motion is relative to the current +drawing position unless expr begins with the boundary-relative +motion operator ‘|’. See Numeric Expressions. +

+ +

The following string definition sets the TeX +logo.104 +

+
+
.ds TeX T\h'-.1667m'\v'.224m'E\v'-.224m'\h'-.125m'X\"
+
+ +

There are a number of special-case escape sequences for horizontal +motion. +

+
+
Escape sequence: \SP
+
+ + + + +

Move right one word space. (The input is a backslash followed by a +space.) This escape sequence can be thought of as a non-adjustable, +unbreakable space. Usually you want \~ instead; see +Manipulating Filling and Adjustment. +

+ + + +
+
Escape sequence: \|
+
+

Move one-sixth em to the right on typesetting output devices. If +a glyph named ‘\|’ is defined in the current font, its width is +used instead, even on terminal output devices. +

+ + + +
+
Escape sequence: \^
+
+

Move one-twelfth em to the right on typesetting output devices. +If a glyph named ‘\^’ is defined in the current font, its width is +used instead, even on terminal output devices. +

+ +
+
Escape sequence: \0
+
+ + + + +

Move right by the width of a numeral in the current font. +

+ +

Horizontal motions are not discarded at the end of an output line as +word spaces are. See Breaking. +

+
+
Escape sequence: \w'anything'
+
+
Register: \n[st]
+
+
Register: \n[sb]
+
+
Register: \n[rst]
+
+
Register: \n[rsb]
+
+
Register: \n[ct]
+
+
Register: \n[ssc]
+
+
Register: \n[skw]
+
+ +

Interpolate the width of anything in basic units. This escape +sequence allows several properties of formatted output to be measured +without writing it out. +

+
+
The length of the string 'abc' is \w'abc'u.
+    ⇒ The length of the string 'abc' is 72u.
+
+ + + +

anything is processed in a dummy environment: this means that +font and type size changes, for example, may occur within it without +affecting subsequent output. +

+

After each use, \w sets several registers. +

+ + + +
+
st
+
sb
+

The maximum vertical displacements of the text baseline above and below, +respectively. The sign convention is opposite that of relative vertical +motions; that is, depth below the (original) baseline is negative. +These registers are incorrectly documented in the AT&T +troff manual as “the highest and lowest extent of [the argument +to \w] relative to the baseline”. +

+
+
rst
+
rsb
+

Like st and sb, but taking account of the heights and +depths of glyphs. In other words, these registers store the highest and +lowest vertical positions attained by anything, doing what +AT&T troff documented st and sb as doing. +

+
+
ct
+

Characterizes the geometry of glyphs occurring in anything. +

+
+
0
+

only short glyphs, no descenders or tall glyphs +

+
+
1
+

at least one descender +

+
+
2
+

at least one tall glyph +

+
+
3
+

at least one each of a descender and a tall glyph +

+
+ +
+
ssc
+

The amount of horizontal space (possibly negative) that should be added +to the last glyph before a subscript. +

+
+
skw
+

How far to right of the center of the last glyph in the \w +argument, the center of an accent from a roman font should be placed +over that glyph. +

+
+
+ +
+
Escape sequence: \kp
+
+
Escape sequence: \k(ps
+
Escape sequence: \k[position]
+
+ + + + +

Store the current horizontal position in the input line in a +register with the name position (one-character name p, +two-character name ps). Use this, for example, to return to the +beginning of a string for highlighting or other decoration. +

+ +
+
Register: \n[hp]
+
+ + + + +

The current horizontal position at the input line. +

+ +
+
Register: \n[.k]
+
+ + + + +

A read-only register containing the current horizontal output position +(relative to the current indentation). +

+ +
+
Escape sequence: \o'abc…'
+
+ + +

Overstrike the glyphs of characters a, b, c, …; +the glyphs are centered, written, and the drawing position advanced by +the widest of the glyphs. +

+ +
+
Escape sequence: \zc
+
+ + +

Format the character c with zero width; that is, without advancing +the drawing position. Use \z to overstrike glyphs aligned to +their left edges, in contrast to \o’s centering. +

+ +
+
Escape sequence: \Z'anything'
+
+ + +

Save the drawing position, format anything, then restore it. Tabs +and leaders in the argument are ignored with an error diagnostic. +

+

We might implement a strike-through macro thus. +

+
+
.de ST
+.nr width \w'\\$1'
+\Z@\v'-.25m'\l'\\n[width]u'@\\$1
+..
+.
+This is
+.ST "a test"
+an actual emergency!
+
+
+ + + +
+
+
+ +

5.26 Drawing Geometric Objects

+ + + +

A few of the formatter’s escape sequences draw lines and other geometric +objects. Combined with each other and with page motion commands +(see Page Motions), a wide variety of figures is possible. For +complex drawings, these operations can be cumbersome; the preprocessors +gpic or ggrn are typically used instead. +

+

The \l and \L escape sequences draw horizontal and +vertical sequences of glyphs, respectively. Even the simplest of +output devices supports them. +

+
+
Escape sequence: \l'l'
+
+
Escape sequence: \l'lc'
+
+ + +

Draw a horizontal line of length l from the drawing position. +Rightward motion is positive. Afterward, the drawing position is at the +right end of the line. The default scaling unit is ‘m’. +

+ + + + +

The optional second parameter c is a character with which to +draw the line. The default is the baseline rule special character, +\[ru]. +

+ + +

If c is a valid scaling unit, put \& after l to +disambiguate the input. +

+
+
.de textbox
+\[br]\\$*\[br]\l'|0\[rn]'\l'|0\[ul]'
+..
+
+ +

The foregoing outputs a box rule (a vertical line), the text +argument(s), and another box rule. We employ the boundary-relative +motion operator ‘|’. Finally, the line-drawing escape sequences +draw a radical extender (a form of overline) and an underline from the +drawing position to the position coresponding to beginning of the +input line. The drawing position returns to just after the +right-hand box rule because the lengths of the drawn lines are negative, +as noted above. +

+ +
+
Escape sequence: \L'l'
+
+
Escape sequence: \L'lc'
+
+ + + + + + +

Draw a vertical line of length l from the drawing position. +Downward motion is positive. The default scaling unit is ‘v’. The +default character is the box rule, \[br]. As with vertical +motion escape sequences, text processing continues where the line ends. +\L is otherwise similar to \l. +

+
+
$ nroff <<EOF
+This is a \L'3v'test.
+EOF
+    ⇒ This is a
+    ⇒           |
+    ⇒           |
+    ⇒           |test.
+
+ +

When writing text, the drawing position is at the text baseline; recall +Page Geometry. +

+ +

The \D escape sequence provides drawing commands that +direct the output device to render geometrical objects rather than +glyphs. Specific devices may support only a subset, or may feature +additional ones; consult the man page for the output driver in use. +Terminal devices in particular implement almost none. See Graphics Commands. +

+

Rendering starts at the drawing position; when finished, the drawing +position is left at the rightmost point of the object, even for closed +figures, except where noted. GNU troff draws stroked (outlined) +objects with the stroke color, and shades filled ones with the fill +color. See Colors. Coordinates h and v are horizontal +and vertical motions relative to the drawing position or previous point +in the command. The default scaling unit for horizontal measurements +(and diameters of circles) is ‘m’; for vertical ones, ‘v’. +

+

Circles, ellipses, and polygons can be drawn filled or stroked. These +are independent properties; if you want a filled, stroked figure, you +must draw the same figure twice using each drawing command. A filled +figure is always smaller than an outlined one because the former is +drawn only within its defined area, whereas strokes have a line +thickness (set with ‘\D't'’). +

+
+
\h'1i'\v'1i'\
+\# increase line thickness
+\Z'\D't 5p''\
+\# draw stroked (unfilled) polygon
+\Z'\D'p 3 3 -6 0''\
+\# draw filled (solid) polygon
+\Z'\D'P 3 3 -6 0''
+
+ +
+
Escape sequence: \D'command argument …'
+
+

Drawing command escape sequence parameters begin with an ordinary +character, command, selecting the type of object to be drawn, +followed by arguments whose meaning is determined by +command. +

+
+
\D'~ h1 v1hn vn'
+
+

Draw a B-spline to each point in sequence, leaving the drawing position +at (hn, vn). +

+
+
\D'a hc vc h v'
+
+

Draw a circular arc centered at (hc, vc) counterclockwise +from the drawing position to a point (h, v) relative to the +center. 105 +

+
+
\D'c d'
+
+ + + + +

Draw a circle of diameter d with its leftmost point at the drawing +position. +

+
+
\D'C d'
+
+ + + + +

As ‘\D'C '’, but the circle is filled. +

+
+
\D'e h v'
+
+ + + + +

Draw an ellipse of width h and height v with its leftmost +point at the drawing position. +

+
+
\D'E x y'
+
+ + + + +

As ‘\D'e '’, but the ellipse is filled. +

+
+
\D'l dx dy'
+
+

Draw line from the drawing position to (h, v). +

+

The following is a macro for drawing a box around a text argument; for +simplicity, the box margin is a fixed at 0.2m. +

+
+
.de TEXTBOX
+.  nr @wd \w'\\$1'
+\h'.2m'\
+\h'-.2m'\v'(.2m - \\n[rsb]u)'\
+\D'l 0 -(\\n[rst]u - \\n[rsb]u + .4m)'\
+\D'l (\\n[@wd]u + .4m) 0'\
+\D'l 0 (\\n[rst]u - \\n[rsb]u + .4m)'\
+\D'l -(\\n[@wd]u + .4m) 0'\
+\h'.2m'\v'-(.2m - \\n[rsb]u)'\
+\\$1\
+\h'.2m'
+..
+
+ +

The argument is measured with the \w escape sequence. Its width +is stored in register @wd. \w also sets the registers +rst and rsb; these contain its maximum vertical extents of +the argument. Then, four lines are drawn to form a box, offset by the +box margin. +

+
+
\D'p h1 v1hn vn'
+
+ + + + +

Draw polygon with vertices at drawing position and each point in +sequence. GNU troff closes the polygon by drawing a line from +(hn, vn) back to the initial drawing position. +Afterward, the drawing position is left at (hn, vn). +

+
+
\D'P dx1 dy1 dx2 dy2 …'
+
+ + + + +

As ‘\D'P '’, but the polygon is filled. +

+

The following macro is like the ‘\D'l'’ example, but shades the +box. We draw the box before writing the text because colors in GNU +troff have no transparency; in othe opposite order, the filled +polygon would occlude the text. +

+
+
.de TEXTBOX
+.  nr @wd \w'\\$1'
+\h'.2m'\
+\h'-.2m'\v'(.2m - \\n[rsb]u)'\
+\M[lightcyan]\
+\D'P 0 -(\\n[rst]u - \\n[rsb]u + .4m) \
+     (\\n[@wd]u + .4m) 0 \
+     0 (\\n[rst]u - \\n[rsb]u + .4m) \
+     -(\\n[@wd]u + .4m) 0'\
+\h'.2m'\v'-(.2m - \\n[rsb]u)'\
+\M[]\
+\\$1\
+\h'.2m'
+..
+
+ +
+
\D't n'
+
+

Set the stroke thickness of geometric objects to n basic units. A +zero n selects the minimal supported thickness. A negative +n selects a thickness proportional to the type size; this is the +default. +

+
+
+ +

In a hazy penumbra between text rendering and drawing commands we locate +the bracket-building escape sequence, \b. It can assemble +apparently large glyphs by vertically stacking ordinary ones. +

+
+
Escape sequence: \b'contents'
+
+ + + +

Pile and center a sequence of glyphs vertically on the output line. +Piling stacks glyphs corresponding to each character in +contents, read from left to right, and placed from top to bottom. +GNU troff separates the glyphs vertically by 1m, and the +pile itself is centered 0.5m above the text baseline. The +horizontal drawing position is then advanced by the width of the widest +glyph in the pile. +

+ + +

This rather inflexible positioning algorithm doesn’t work with the +dvi output device since its bracket pieces vary in height. +Instead, use the geqn preprocessor. +

+

Manipulating Spacing describes how to adjust the vertical spacing +of the output line with the \x escape sequence. +

+

The application of \b that lends its name is construction of +brackets, braces, and parentheses when typesetting mathematics. We +might construct a large opening (left) brace as follows. +

+
+
\b'\[lt]\[bv]\[lk]\[bv]\[lb]'
+
+ +

See groff_char(7) for a list of special character +identifiers. +

+ + + +
+
+
+ +

5.27 Deferring Output

+ + + + + +

A few roff language elements are generally not used in simple +documents, but arise as page layouts become more sophisticated and +demanding. Environments collect formatting parameters like line +length and typeface. A diversion stores formatted output for +later use. A trap is a condition on the input or output, tested +automatically by the formatter, that is associated with a macro, causing +it to be called when that condition is fulfilled. +

+

Footnote support often exercises all three of the foregoing features. A +simple implementation might work as follows. A pair of macros is +defined: one starts a footnote and the other ends it. The author calls +the first macro where a footnote marker is desired. The macro +establishes a diversion so that the footnote text is collected at the +place in the body text where its corresponding marker appears. An +environment is created for the footnote so that it is set at a smaller +typeface. The footnote text is formatted in the diversion using that +environment, but it does not yet appear in the output. The document +author calls the footnote end macro, which returns to the previous +environment and ends the diversion. Later, after much more body text in +the document, a trap, set a small distance above the page bottom, is +sprung. The macro called by the trap draws a line across the page and +emits the stored diversion. Thus, the footnote is rendered. +

+

Diversions and traps make the text formatting process non-linear. Let +us imagine a set of text lines or paragraphs labelled ‘A’, +‘B’, and so on. If we set up a trap that produces text ‘T’ +(as a page footer, say), and we also use a diversion to store the +formatted text ‘D’, then a document with input text in the order +‘A B C D E F’ might render as ‘A B C E T F’. The diversion +‘D’ will never be output if we do not call for it. +

+

Environments of themselves are not a source of non-linearity in document +formatting: environment switches have immediate effect. One could +always write a macro to change as many formatting parameters as desired +with a single convenient call. But because diversions can be nested and +macros called by traps that are sprung by other trap-called macros, they +may be called upon in varying contexts. For example, consider a page +header that is always to be set in Helvetica. A document that uses +Times for most of its body text, but Courier for displayed code +examples, poses a challenge if a page break occurs in the middle of a +code display; if the header trap assumes that the “previous font” is +always Times, the rest of the example will be formatted in the wrong +typeface. One could carefully save all formatting parameters upon +entering the trap and restore them upon leaving it, but this is verbose, +error-prone, and not future-proof as the groff language develops. +Environments save us considerable effort. +

+ +
+
+
+ +

5.28 Traps

+ + +

Traps are locations in the output or conditions on the input that, +when reached or fulfilled, call a specified macro. These traps can +occur at a given location on the page, at a given location in the +current diversion (together, these are known as vertical +position traps), at a blank line, at a line with leading space +characters, after a quantity of input lines, or at the end of input. +Macros called by traps are passed no arguments. + + +Setting a trap is also called planting one. + + +It is said that a trap is sprung if its condition is fulfilled. +

+ + + +
+
+ +

5.28.1 Vertical Position Traps

+ + + +

A vertical position trap calls a macro when the formatter’s +vertical drawing position reaches or passes, in the downward direction, +a certain location on the output page or in a diversion. Its +applications include setting page headers and footers, body text in +multiple columns, and footnotes. +

+
+
Request: .vpt [flag]
+
+
Register: \n[.vpt]
+
+ + + +

Enable vertical position traps if flag is non-zero or absent; +disable them otherwise. Vertical position traps are those set by the +wh request or by dt within a diversion. The parameter +that controls whether vertical position traps are enabled is global. +Initially, vertical position traps are enabled. The current value is +stored in the .vpt read-only register. +

+ + + + +

A page can’t be ejected if vpt is set to zero; see The Implicit Page Trap. +

+ + + + +
+
+ +

5.28.1.1 Page Location Traps

+ + + +

A page location trap is a vertical position trap that applies to +the page; that is, to undiverted output. Many can be present; manage +them with the wh and ch requests. +

+
+
Request: .wh dist [name]
+
+

Plant macro name as page location trap at dist. The default +scaling unit is ‘v’. Non-negative values for dist set the +trap relative to the top of the page; negative values set the trap +relative to the bottom of the page. It is not possible to plant a trap +less than one basic unit from the page bottom: a dist of -0 +is interpreted as 0, the top of the page.106 An existing visible trap (see below) at +dist is removed; this is wh’s sole function if name +is missing. +

+

A trap is sprung only if it is visible, meaning that its location +is reachable on the page107 and it +is not hidden by another trap at the same location already planted +there. +

+ + + + + + + + +

A macro package might set headers and footers as follows; this example +configures vertical margins of one inch to the body text, and one +half-inch to the titles. Observe the use of the no-break control +character with sp request to position our text baselines, +and the page number character ‘%’ used with the tl request. +

+
+
.\" hdfo.roff
+.de hd                  \" page header
+'  sp .5i
+'  tl '\\*(Ti''\\*(Da'  \" title and date strings
+'  sp .5i
+..
+.de fo                  \" page footer
+'  sp .5i
+.  tl ''%''
+.  bp
+..
+.wh 0   hd             \" trap at top of the page
+.wh -1i fo             \" trap 1 inch from bottom
+
+ +

To use these traps, copy the above (or load it from a file with the +so or mso requests), then set up the strings it uses. +

+
+
.so hdfo.roff
+.ds Ti Final Report\"
+.ds Da 21 May 2023\"
+.ti
+On 5 August of last year,
+this committee tasked me with the investigation of the
+CFIT (controlled flight into terrain) incident of
+.\" ...and so on...
+
+ +

A trap above the top or at or below the bottom of the page can be made +visible by either moving it into the page area or increasing the page +length so that the trap is on the page. Negative trap values always use +the current page length; they are not converted to an absolute +vertical position. + + +We can use the ptr request to dump our page location traps to the +standard error stream (see Debugging). Their positions are reported +in basic units; an nroff device example follows. +

+
+
.pl 5i
+.wh -1i xx
+.ptr
+    error→ xx      -240
+.pl 100i
+.ptr
+    error→ xx      -240
+
+ +

It is possible to have more than one trap at the same location (although +only one at a time can be visible); to achieve this, the traps must be +defined at different locations, then moved to the same place with the +ch request. In the following example, the many empty lines +caused by the bp request are not shown in the output. +

+
+
.de a
+.  nop a
+..
+.de b
+.  nop b
+..
+.de c
+.  nop c
+..
+.
+.wh 1i a
+.wh 2i b
+.wh 3i c
+.bp
+    ⇒ a b c
+
+
+
.ch b 1i
+.ch c 1i
+.bp
+    ⇒ a
+
+
+
.ch a 0.5i
+.bp
+    ⇒ a b
+
+
+ +
+
Register: \n[.t]
+
+ + +

The read-only register .t holds the distance to the next vertical +position trap. If there are no traps between the current position and +the bottom of the page, it contains the distance to the page bottom. +Within a diversion, in the absence of a diversion trap, this distance is +the largest representable integer in basic units—effectively infinite. +

+ +
+
Request: .ch name [dist]
+
+ + +

Change the location of a trap by moving macro name to new location +dist, or by unplanting it altogether if dist is absent. The +default scaling unit is ‘v’. Parameters to ch are specified +in the opposite order from wh. If name is the earliest +planted macro of multiple traps at the same location, (re)moving it from +that location exposes the macro next least recently planted at the same +place.108 +

+

Changing a trap’s location is useful for building up footnotes in a +diversion to allow more space at the bottom of the page for them. +

+ +
+ +

The same macro can be installed simultaneously at multiple locations; +however, only the earliest-planted instance—that has not yet been +deleted with wh—will be moved by ch. The following +example (using an nroff device) illustrates this behavior. Blank +lines have been elided from the output. +

+
+
.de T
+Trap sprung at \\n(nlu.
+.br
+..
+.wh 1i T
+.wh 2i T
+foo
+.sp 11i
+.bp
+.ch T 4i
+bar
+.sp 11i
+.bp
+.ch T 5i
+baz
+.sp 11i
+.bp
+.wh 5i
+.ch T 6i
+qux
+.sp 11i
+
+
+
    ⇒ foo
+    ⇒ Trap sprung at 240u.
+    ⇒ Trap sprung at 480u.
+    ⇒ bar
+    ⇒ Trap sprung at 480u.
+    ⇒ Trap sprung at 960u.
+    ⇒ baz
+    ⇒ Trap sprung at 480u.
+    ⇒ Trap sprung at 1200u.
+    ⇒ qux
+    ⇒ Trap sprung at 1440u.
+
+ +
+
Register: \n[.ne]
+
+

The read-only register .ne contains the amount of space that was +needed in the last ne request that caused a trap to be sprung; +it is useful in conjunction with the .trunc register. See Page Control. Since the .ne register is set only by traps, it +doesn’t make sense to interpolate it outside of macros called by traps. +

+ +
+
Register: \n[.trunc]
+
+ + +

A read-only register containing the amount of vertical space truncated +from an sp request by the most recently sprung vertical +position trap, or, if the trap was sprung by an ne request, +minus the amount of vertical motion produced by the ne +request. In other words, at the point a trap is sprung, it +represents the difference of what the vertical position would have +been but for the trap, and what the vertical position actually is. +Since the .trunc register is set only by traps, it doesn’t make +sense to interpolate it outside of macros called by traps. +

+ +
+
Register: \n[.pe]
+
+ + + +

This Boolean-valued, read-only register interpolates 1 while a page +is being ejected, and 0 otherwise. +

+

In the following example, we plant the same trap at the top and the +bottom of the page. We also make the trap report its name and the +vertical drawing position. +

+
+
.de T
+.tm \\$0: page \\n%, nl=\\n[nl] .pe=\\n[.pe]
+..
+.ll 46n
+.wh 0 T
+.wh -1v T
+Those who can make you believe absurdities can make you
+commit atrocities. \[em] Voltaire
+    error→ T: page 1, nl=0 .pe=0
+    error→ T: page 1, nl=2600 .pe=1
+    ⇒ Those who can make you believe absurdities can
+    ⇒ make you commit atrocities. -- Voltaire
+
+
+ + + +

When designing macros, keep in mind that diversions and traps do +normally interact. For example, if a trap calls a header macro (while +outputting a diversion) that tries to change the font on the current +page, the effect is not visible before the diversion has completely been +printed (except for input protected with \! or \?) since +the data in the diversion is already formatted. In most cases, this is +not the expected behaviour. +

+ +
+
+
+ +

5.28.1.2 The Implicit Page Trap

+ + + + + + + +

If, after starting GNU troff without loading a macro package, you +use the ptr request to dump a list of the active traps to the +standard error stream,109 nothing is reported. +Yet the .t register will report a steadily decreasing value with +every output line your document produces, and once the value of +.t gets to within .V of zero, you will notice that +something trap-like happens—the page is ejected, a new one begins, and +the value of .t becomes large once more. +

+

This implicit page trap always exists in the top-level +diversion;110 it works like a trap in some +ways but not others. Its purpose is to eject the current page and start +the next one. It has no name, so it cannot be moved or deleted with +wh or ch requests. You cannot hide it by placing another +trap at its location, and can move it only by redefining the page length +with pl. Its operation is suppressed when vertical page traps +are disabled with GNU troff’s vpt request. +

+ +
+
+
+ +

5.28.1.3 Diversion Traps

+ + + +

A diversion is not formatted in the context of a page, so it lacks page +location traps; instead it can have a diversion trap. There can +exist at most one such vertical position trap per diversion. +

+
+
Request: .dt [dist name]
+
+ + + + +

Set a trap within a diversion at location dist, which is +interpreted relative to diversion rather than page boundaries. If invoked with +fewer than two arguments, any diversion trap in the current diversion is +removed. The register .t works within diversions. It is an +error to invoke dt in the top-level diversion. +See Diversions. +

+ + +
+
+
+
+ +

5.28.2 Input Line Traps

+ + + +
+
Request: .it [n name]
+
+
Request: .itc [n name]
+
+ + + + + + +

Set an input line trap, calling macro name after processing the +next n productive input lines (recall Manipulating Filling and Adjustment). Any existing input line trap in the +environment is replaced. Without arguments, it and itc +clear any input line trap that has not yet sprung. +

+

Consider a macro ‘.ST s n’ which sets the next +n input lines in the font style s. +

+
+
.de ST \" Use style $1 for next $2 text lines.
+.  it \\$2 ES
+.  ft \\$1
+..
+.de ES \" end ST
+.  ft R
+..
+.ST I 1
+oblique
+face
+.ST I 1
+oblique\c
+face
+    ⇒ oblique face obliqueface  (second “face” upright)
+
+ + + + + +

Unlike the ce and rj requests, it counts lines +interrupted with the \c escape sequence separately (see Line Continuation); itc does not. To see the difference, let’s +change the previous example to use itc instead. +

+
+

+.  itc \\$2 ES
+
+    ⇒ oblique face obliqueface  (second “face” oblique)
+
+ +

You can think of the ce and rj requests as implicitly +creating an input line trap with itc that schedules a break when +the trap is sprung. +

+
+
.de BR
+.  br
+.  internal: disable centering-without-filling
+..
+.
+.de ce
+.  if \\n[.br] .br
+.  itc \\$1 BR
+.  internal: enable centering-without-filling
+..
+
+ +

Let us consider in more detail the sorts of input lines that are or are +not “productive”. +

+
+
.de Trap
+TRAP SPRUNG
+..
+.de Mac
+.if r a \l'5n'
+..
+.it 2 Trap
+.
+foo
+.Mac
+bar
+baz
+.it 1 Trap
+.sp \" moves, but does not write or draw
+qux
+.itc 1 Trap
+\h'5n'\c \" moves, but does not write or draw
+jat
+
+ +

When ‘Trap’ gets called depends on whether the ‘a’ register is +defined; the control line with the if request may or may not +produce written output. We also see that the spacing request sp, +while certainly affecting the output, does not spring the input line +trap. Similarly, the horizontal motion escape sequence \h also +affected the output, but was not “written”. Observe that we had to +follow it with \c and use itc to prevent the newline at +the end of the text line from causing a word break, which, like an +ordinary space character, counts as written output. +

+
+
$ groff -Tascii input-trap-example.groff
+    ⇒ foo bar TRAP SPRUNG baz
+    ⇒
+    ⇒ qux TRAP SPRUNG      jat TRAP SPRUNG
+$ groff -Tascii -ra1 input-trap-example.groff
+    ⇒ foo _____ TRAP SPRUNG bar baz
+    ⇒
+    ⇒ qux TRAP SPRUNG      jat TRAP SPRUNG
+
+
+ +

Input line traps are associated with the environment +(see Environments); switching to another environment suspends the +current input line trap, and going back resumes it, restoring the count +of qualifying lines enumerated in that environment. +

+ +
+
+
+ +

5.28.3 Blank Line Traps

+ + + +
+
Request: .blm [name]
+
+ +

Set a blank line trap, calling the macro name when GNU +troff encounters a blank line in an input file, instead of the +usual behavior (see Breaking). A line consisting only of spaces is +also treated as blank and subject to this trap. If no argument is +supplied, the default blank line behavior is (re-)established. +

+ + +
+
+
+ +

5.28.4 Leading Space Traps

+ + + +
+
Request: .lsm [name]
+
+
Register: \n[lsn]
+
+
Register: \n[lss]
+
+ +

Set a leading space trap, calling the macro name when GNU +troff encounters leading spaces in an input line; the implicit +line break that normally happens in this case is suppressed. If no +argument is supplied, the default leading space behavior is +(re-)established (see Breaking). +

+

The count of leading spaces on an input line is stored in register +lsn, and the amount of corresponding horizontal motion in +register lss, irrespective of whether a leading space trap is +set. When it is, the leading spaces are removed from the input line, +and no motion is produced before calling name. +

+
+ + +
+
+
+ +

5.28.5 End-of-input Traps

+ + + +
+
Request: .em [name]
+
+ + + + + +

Set a trap at the end of input, calling macro name after the last +line of the last input file has been processed. If no argument is +given, any existing end-of-input trap is removed. +

+

For example, if the document had to have a section at the bottom of the +last page for someone to approve it, the em request could be +used. +

+
+
.de approval
+\c
+.  ne 3v
+.  sp (\\n[.t]u - 3v)
+.  in +4i
+.  lc _
+.  br
+Approved:\t\a
+.  sp
+Date:\t\t\a
+..
+.
+.em approval
+
+ +

The \c in the above example needs explanation. For historical +reasons (compatibility with AT&T troff), the +end-of-input macro exits as soon as it causes a page break if no +partially collected line remains.111 +

+ + + + +

Let us assume that there is no \c in the above approval +macro, that the page is full, and last output line has been broken with, +say, a br request. Because there is no more room, a ne +request at this point causes a page ejection, which in turn makes +troff exit immediately as just described. In most situations, +this is not desired; people generally want to format the input after +ne. +

+

To force processing of the whole end-of-input macro independently of +this behavior, it is thus advisable to (invisibly) ensure the existence +of a partially collected line (\c) whenever there is a chance +that a page break can happen. In the above example, invoking the +ne request ensures that there is room for the subsequent +formatted output on the same page, so we need insert \c only +once. +

+

The next example shows how to append three lines, then start a new page +unconditionally. Since ‘.ne 1 doesn’t give the desired +effect—there is always one line available or we are already at the +beginning of the next page—we temporarily increase the page length by +one line so that we can use ‘.ne 2. +

+
+
.de EM
+.pl +1v
+\c
+.ne 2
+line one
+.br
+\c
+.ne 2
+line two
+.br
+\c
+.ne 2
+line three
+.br
+.pl -1v
+\c
+'bp
+..
+.em EM
+
+ +

This specific feature affects only the first potential page break caused +by the end-of-input macro; further page breaks emitted by the macro are +handled normally. +

+

Another possible use of the em request is to make GNU +troff emit a single large page instead of multiple pages. For +example, one may want to produce a long plain text file for reading +in a terminal or emulator without page footers and headers interrupting +the body of the document. One approach is to set the page length at the +beginning of the document to a very large value to hold all the +text,112 and +automatically adjust it to the exact height of the document after the +text has been output. +

+
+
.de adjust-page-length
+.  br
+.  pl \\n[nl]u \" \n[nl]: current vertical position
+..
+.
+.de single-page-mode
+.  pl 99999
+.  em adjust-page-length
+..
+.
+.\" Activate the above code if configured.
+.if \n[do-continuous-rendering] \
+.  single-page-mode
+
+ +

Since only one end-of-input trap exists and another macro package may +already use it, care must be taken not to break the mechanism. A simple +solution would be to append the above macro to the macro package’s +end-of-input macro using the am request. +

+ + + +
+
+
+
+ +

5.29 Diversions

+ + +

In roff systems it is possible to format text as if for output, +but instead of writing it immediately, one can divert the +formatted text into a named storage area. It is retrieved later by +specifying its name after a control character. The same name space is +used for such diversions as for strings and macros; see +Identifiers. Such text is sometimes said to be “stored in a +macro”, but this coinage obscures the important distinction between +macros and strings on one hand and diversions on the other; the former +store unformatted input text, and the latter capture +formatted output. Diversions also do not interpret arguments. +Applications of diversions include “keeps” (preventing a page break +from occurring at an inconvenient place by forcing a set of output lines +to be set as a group), footnotes, tables of contents, and indices. + + +For orthogonality it is said that GNU troff is in the +top-level diversion if no diversion is active (that is, formatted +output is being “diverted” immediately to the output device). +

+

Dereferencing an undefined diversion will create an empty one of that +name and cause a warning in category ‘mac’ to be emitted. +See Warnings, for information about the enablement and suppression of +warnings. A diversion does not exist for the purpose of testing with +the d conditional operator until its initial definition ends +(see Operators in Conditionals). The following requests are used to +create and alter diversions. +

+
+
Request: .di [name]
+
+
Request: .da [name]
+
+ + + + + + +

Start collecting formatted output in a diversion called name. The +da request appends to a diversion called name, creating it +if necessary. If name already exists as an alias, the target of +the alias is replaced or appended to; recall Strings. The pending +output line is diverted as well. Switching to another environment (with +the ev request) before invoking di or da avoids +including any pending output line in the diversion; see +Environments. +

+

Invoking di or da without an argument stops diverting +output to the diversion named by the most recent corresponding request. +If di or da is called without an argument when there is no +current diversion, a warning in category ‘di’ is produced. +See Warnings, for information about the enablement and suppression +of warnings. +

+
+
Before the diversion.
+.di yyy
+In the diversion.
+.br
+.di
+After the diversion.
+.br
+    ⇒ After the diversion.
+.yyy
+    ⇒ Before the diversion.  In the diversion.
+
+
+ + +

GNU troff supports box requests to exclude a partially +collected line from a diversion, as this is often desirable. +

+
+
Request: .box [name]
+
+
Request: .boxa [name]
+
+

Divert (or append) output to name, similarly to the di and +da requests, respectively. Any pending output line is not +included in the diversion. Without an argument, stop diverting output; +any pending output line inside the diversion is discarded. +

+
+
Before the box.
+.box xxx
+In the box.
+.br
+Hidden treasure.
+.box
+After the box.
+.br
+    ⇒ Before the box.  After the box.
+.xxx
+    ⇒ In the box.
+
+
+ +

Apart from pending output line inclusion and the request names that +populate them, boxes are handled exactly as diversions are. All of the +following groff language elements can be used with them +interchangeably. +

+
+
Register: \n[.z]
+
+
Register: \n[.d]
+
+ + + + + + + +

Diversions may be nested. The read-only string-valued register +.z contains the name of the current diversion. The read-only +register .d contains the current vertical place in the diversion. +If the input text is not being diverted, .d reports the same +location as the register nl. +

+ +
+
Register: \n[.h]
+
+ + + + +

The read-only register .h stores the high-water mark on the +current page or in the current diversion. It corresponds to the text +baseline of the lowest line on the page.113 +

+
+
.tm .h==\n[.h], nl==\n[nl]
+    ⇒ .h==0, nl==-1
+This is a test.
+.br
+.sp 2
+.tm .h==\n[.h], nl==\n[nl]
+    ⇒ .h==40, nl==120
+
+ + + +

As implied by the example, vertical motion does not produce text +baselines and thus does not increase the value interpolated by +‘\n[.h]’. +

+ +
+
Register: \n[dn]
+
+
Register: \n[dl]
+
+ + + + +

After completing a diversion, the writable registers dn and +dl contain its vertical and horizontal sizes. Only the lines +just processed are counted: for the computation of dn and +dl, the requests da and boxa are handled as if +di and box had been used, respectively—lines that have +been already stored in the diversion (box) are not taken into account. +

+
+
.\" Center text both horizontally and vertically.
+.\" Macro .(c starts centering mode; .)c terminates it.
+.
+.\" Disable the escape character with .eo so that we
+.\" don't have to double backslashes on the "\n"s.
+.eo
+.de (c
+.  br
+.  ev (c
+.  evc 0
+.  in 0
+.  nf
+.  di @c
+..
+
+
+
.de )c
+.  br
+.  ev
+.  di
+.  nr @s (((\n[.t]u - \n[dn]u) / 2u) - 1v)
+.  sp \n[@s]u
+.  ce 1000
+.  @c
+.  ce 0
+.  sp \n[@s]u
+.  br
+.  fi
+.  rr @s
+.  rm @c
+..
+.ec
+
+
+ +
+
Escape sequence: \!anything
+
+
Escape sequence: \?anything\?
+
+ + +

Transparently embed anything into the current diversion, +preventing requests, macro calls, and escape sequences from being +interpreted when read into a diversion. This is useful for preventing +them from taking effect until the diverted text is actually output. The +\! escape sequence transparently embeds input up to and including +the end of the line. The \? escape sequence transparently embeds +input until its own next occurrence. +

+ + + + + + +

anything may not contain newlines; use \! by itself to +embed newlines in a diversion. The escape sequence \? is also +recognized in copy mode and turned into a single internal code; it is +this code that terminates anything. Thus the following example +prints 4. +

+
+
.nr x 1
+.nf
+.di d
+\?\\?\\\\?\\\\\\\\nx\\\\?\\?\?
+.di
+.nr x 2
+.di e
+.d
+.di
+.nr x 3
+.di f
+.e
+.di
+.nr x 4
+.f
+
+ +

Both escape sequences read the data in copy mode. +

+ + + +

If \! is used in the top-level diversion, its argument is +directly embedded into GNU troff’s intermediate output. This can +be used, for example, to control a postprocessor that processes the data +before it is sent to an output driver. +

+ + + +

The \? escape used in the top-level diversion produces no output +at all; its argument is simply ignored. +

+ + + + + + +
+
Request: .output contents
+
+

Emit contents directly to GNU troff’s intermediate output +(subject to copy mode interpretation); this is similar to \! used +at the top level. An initial neutral double quote in contents is +stripped to allow embedding of leading spaces. +

+

This request can’t be used before the first page has started—if you +get an error, simply insert .br before the output request. +

+

Use with caution! It is normally only needed for mark-up used by a +postprocessor that does something with the output before sending it to +the output device, filtering out contents again. +

+ +
+
Request: .asciify div
+
+ + + +

Unformat the diversion div in a way such that Unicode basic +Latin (ASCII) characters, characters translated with the +trin request, space characters, and some escape sequences, that +were formatted and diverted into div are treated like ordinary +input characters when div is reread. Doing so can be useful in +conjunction with the writem request. asciify can be also +used for gross hacks; for example, the following sets +register n to 1. +

+
+
.tr @.
+.di x
+@nr n 1
+.br
+.di
+.tr @@
+.asciify x
+.x
+
+ +

asciify cannot return all items in a diversion to their source +equivalent: nodes such as those produced by the \N escape +sequence will remain nodes, so the result cannot be guaranteed to be a +pure string. See Copy Mode. Glyph parameters such as the type face +and size are not preserved; use unformat to achieve that. +

+ +
+
Request: .unformat div
+
+

Like asciify, unformat the diversion div. However, +unformat handles only tabs and spaces between words, the latter +usually arising from spaces or newlines in the input. Tabs are treated +as input tokens, and spaces become adjustable again. The vertical sizes +of lines are not preserved, but glyph information (font, type size, +space width, and so on) is retained. +

+ + + +
+
+
+ +

5.30 Punning Names

+ + +

Macros, strings, and diversions share a name space; recall +Identifiers. Internally, the same mechanism is used to store +them. You can thus call a macro with string interpolation syntax and +vice versa. +

+
+
.de subject
+Typesetting
+..
+.de predicate
+rewards attention to detail
+..
+\*[subject] \*[predicate].
+Truly.
+    ⇒ Typesetting
+    ⇒  rewards attention to detail Truly.
+
+ +

What went wrong? Strings don’t contain newlines, but macros do. String +interpolation placed a newline at the end of ‘\*[subject]’, and the +next thing on the input was a space. Then when ‘\*[predicate]’ was +interpolated, it was followed by the empty request ‘.’ on a line by +itself. If we want to use macros as strings, we must take interpolation +behavior into account. +

+
+
.de subject
+Typesetting\\
+..
+.de predicate
+rewards attention to detail\\
+..
+\*[subject] \*[predicate].
+Truly.
+    ⇒ Typesetting rewards attention to detail.  Truly.
+
+ +

By ending each text line of the macros with an escaped +\RET, we get the desired effect (see Line Continuation).114 +What would have happened if we had used only one backslash at a time +instead? +

+

Interpolating a string does not hide existing macro arguments. We can +also place the escaped newline outside the string interpolation instead +of within the string definition. Thus, in a macro, a more efficient way +of doing +

+
+
.xx \\$@
+
+ +

is +

+
+
\\*[xx]\\
+
+ +

The latter calling syntax doesn’t change the value of \$0, which +is then inherited from the calling macro (see Parameters). +

+

Diversions can be also called with string syntax. It is sometimes +convenient to copy one-line diversions to a string. +

+
+
.di xx
+the
+.ft I
+interpolation system
+.ft
+.br
+.di
+.ds yy This is a test of \*(xx\c
+\*(yy.
+    ⇒ This is a test of the interpolation system.
+
+ +

As the previous example shows, it is possible to store formatted output +in strings. The \c escape sequence prevents the subsequent +newline from being interpreted as a break (again, +see Line Continuation). +

+

Copying multi-output line diversions produces unexpected results. +

+
+
.di xxx
+a funny
+.br
+test
+.br
+.di
+.ds yyy This is \*[xxx]\c
+\*[yyy].
+    ⇒ test This is a funny.
+
+ +

Usually, it is not predictable whether a diversion contains one or more +output lines, so this mechanism should be avoided. With AT&T +troff, this was the only solution to strip off a final newline +from a diversion. Another disadvantage is that the spaces in the copied +string are already formatted, preventing their adjustment. This can +cause ugly results. +

+ + + + + + + +

A clean solution to this problem is available in GNU troff, using +the requests chop to remove the final newline of a diversion, and +unformat to make the horizontal spaces adjustable again. +

+
+
.box xxx
+a funny
+.br
+test
+.br
+.box
+.chop xxx
+.unformat xxx
+This is \*[xxx].
+    ⇒ This is a funny test.
+
+ +

See gtroff Internals. +

+ +
+
+
+ +

5.31 Environments

+ + +

As discussed in Deferring Output, environments store most of the +parameters that determine the appearance of text. A default environment +named ‘0’ exists when GNU troff starts up; it is modified by +formatting-related requests and escape sequences. +

+ +

You can create new environments and switch among them. Only one is +current at any given time. Active environments are managed using a +stack, a data structure supporting “push” and “pop” +operations. The current environment is at the top of the stack. +The same environment name can be pushed onto the stack multiple times, +possibly interleaved with others. Popping the environment stack does +not destroy the current environment; it remains accessible by name and +can be made current again by pushing it at any time. Environments +cannot be renamed or deleted, and can only be modified when current. To +inspect the environment stack, use the pev request; see +Debugging. +

+

Environments store the following information. +

+
    +
  • a partially collected line, if any + +
  • data about the most recently output glyph and line (registers +.cdp, .cht, .csk, .n, .w) + +
  • typeface parameters (size, family, style, height and slant, inter-word +and inter-sentence space sizes) + +
  • page parameters (line length, title length, vertical spacing, line +spacing, indentation, line numbering, centering, right-alignment, +underlining, hyphenation parameters) + +
  • filling enablement; adjustment enablement and mode + +
  • tab stops; tab, leader, escape, control, no-break control, hyphenation, +and margin characters + +
  • input line traps + +
  • stroke and fill colors +
+ +
+
Request: .ev [ident]
+
+
Register: \n[.ev]
+
+ + + +

Enter the environment ident, which is created if it does not +already exist, using the same parameters as for the default environment +used at startup. With no argument, GNU troff switches to the +previous environment. +

+

Invoking ev with an argument puts environment ident onto +the top of the environment stack. (If it isn’t already present in the +stack, this is a proper push.) Without an argument, ev pops the +environment stack, making the previous environment current. It is an +error to pop the environment stack with no previous environment +available. The read-only string-valued register .ev contains the +name of the current environment—the one at the top of the stack. +

+
+
.ev footnote-env
+.fam N
+.ps 6
+.vs 8
+.ll -.5i
+.ev
+
+
+
+.ev footnote-env
+\[dg] Observe the smaller text and vertical spacing.
+.ev
+
+ +

We can familiarize ourselves with stack behavior by wrapping the +ev request with a macro that reports the contents of the +.ev register to the standard error stream. +

+
+
.de EV
+.  ev \\$1
+.  tm environment is now \\n[.ev]
+..
+.
+.EV foo
+.EV bar
+.EV
+.EV baz
+.EV
+.EV
+.EV
+
+ +
+
    error→ environment is now foo
+    error→ environment is now bar
+    error→ environment is now foo
+    error→ environment is now baz
+    error→ environment is now foo
+    error→ environment is now 0
+    error→ error: environment stack underflow
+    error→ environment is now 0
+
+ +
+ +
+
Request: .evc environment
+
+ + +

Copy the contents of environment to the current environment. +

+

The following environment data are not copied. +

+
    +
  • a partially collected line, if present; + +
  • the interruption status of the previous input line (due to use of the +\c escape sequence); + +
  • the count of remaining lines to center, to right-justify, or to +underline (with or without underlined spaces)—these are set to zero; + +
  • the activation status of temporary indentation; + +
  • input line traps and their associated data; + +
  • the activation status of line numbering (which can be reactivated with +‘.nm +0); and + +
  • the count of consecutive hyphenated lines (set to zero). +
+
+ +
+
Register: \n[.w]
+
+
Register: \n[.cht]
+
+
Register: \n[.cdp]
+
+
Register: \n[.csk]
+
+ + + + + + + +

The \n[.w] register contains the width of the last glyph +formatted in the environment. +

+

The \n[.cht] register contains the height of the last glyph +formatted in the environment. +

+

The \n[.cdp] register contains the depth of the last glyph +formatted in the environment. It is positive for glyphs extending below +the baseline. +

+

The \n[.csk] register contains the skew (how far to the +right of the glyph’s center that GNU troff should place an +accent) of the last glyph formatted in the environment. +

+ +
+
Register: \n[.n]
+
+ + + + +

The \n[.n] register contains the length of the previous output +line emitted in the environment. +

+ + + + +
+
+
+ +

5.32 Suppressing Output

+ +
+
Escape sequence: \O[num]
+
+ + +

Suppress GNU troff output of glyphs and geometric objects. The +sequences \O2, \O3, \O4, and \O5 are +intended for internal use by grohtml. +

+
+
\O0
+

Disable the emission of glyphs and geometric objects to the output +driver, provided that this sequence occurs at the outermost suppression +level (see \O3 and \04 below). Horizontal motions +corresponding to non-overstruck glyph widths still occur. +

+
+
\O1
+

Enable the emission of glyphs and geometric objects to the output +driver, provided that this sequence occurs at the outermost suppression +level. +

+
+ + + + + +

\O0 and \O1 also reset the four registers opminx, +opminy, opmaxx, and opmaxy to −1. These +four registers mark the top left and bottom right hand corners of a box +encompassing all written or drawn output. +

+
+
\O2
+

At the outermost suppression level, enable emission of glyphs and +geometric objects, and write to the standard error stream the page +number and values of the four aforementioned registers encompassing +glyphs written since the last interpolation of a \O sequence, as +well as the page offset, line length, image file name (if any), +horizontal and vertical device motion quanta, and input file name. +Numeric values are in basic units. +

+
+
\O3
+

Begin a nested suppression level. grohtml uses this mechanism +to create images of output preprocessed with gpic, +geqn, and gtbl. At startup, GNU troff is at +the outermost suppression level. pre-grohtml generates these +sequences when processing the document, using GNU troff with +the ps output device, Ghostscript, and the PNM tools to produce +images in PNG format. They start a new page if the device is not +html or xhtml, to reduce the number of images crossing a +page boundary. +

+
+
\O4
+

End a nested suppression level. +

+
+ +
+
\O[5Pfile]
+

At the outermost suppression level, write the name file to the +standard error stream at position P, which must be one of +l, r, c, or i, corresponding to left, +right, centered, and inline alignments within the document, +respectively. file is a name associated with the production of +the next image. +

+
+
+ +
+
Register: \n[.O]
+
+ + + +

Output suppression nesting level applied by \O3 and \O4 +escape sequences. +

+ + + +
+
+
+ +

5.33 I/O

+ + + + + +

gtroff has several requests for including files: +

+
+
Request: .so file
+
+
Request: .soquiet file
+
+ + +

Replace the so request’s control line with the contents of the +file named by the argument, “sourcing” it. file is sought in +the directories specified by -I command-line option. If +file does not exist, a warning in category ‘file’ is produced +and the request has no further effect. See Warnings, for +information about the enablement and suppression of warnings. +

+

so can be useful for large documents; e.g., allowing each chapter +of a book to be kept in a separate file. However, files interpolated +with so are not preprocessed; to overcome this limitation, see +the gsoelim(1) man page. +

+

Since GNU troff replaces the entire control line with the +contents of a file, it matters whether file is terminated with a +newline or not. Assume that file xxx contains only the word +‘foo’ without a trailing newline. +

+
+
$ printf 'foo' > xxx
+
+The situation is
+.so xxx
+bar.
+    ⇒ The situation is foobar.
+
+ +

soquiet works the same way, except that no warning diagnostic is +issued if file does not exist. +

+ +
+
Request: .pso command
+
+

Read the standard output from the specified command and include +it in place of the pso request. +

+ + + + +

It is an error to use this request in safer mode, which is the +default. Invoke GNU troff or a front end with the -U +option to enable unsafe mode. +

+

The comment regarding a final newline for the so request is valid +for pso also. +

+ +
+
Request: .mso file
+
+
Request: .msoquiet file
+
+

Identical to the so and soquiet requests, respectively, +except that gtroff searches for the specified file in the +same directories as macro files for the -m command-line option. +If the file name to be included has the form name.tmac and +it isn’t found, these requests try to include tmac.name and +vice versa. +

+ +
+
Request: .trf file
+
+
Request: .cf file
+
+ + + + + + + + +

Transparently output the contents of file. Each line is output as +if it were preceded by \!; however, the lines are not +subject to copy mode interpretation. If the file does not end with a +newline, trf adds one. Both requests cause a break. +

+

When used in a diversion, these requests embed a node (see gtroff Internals) in it that, when reread, causes the contents of file +to be transparently copied to the output. In AT&T +troff, the contents of file are immediately copied to the +output regardless of whether there is a current diversion; this +behaviour is so anomalous that it must be considered a bug. +

+ + + +

While cf copies the contents of file completely +unprocessed, trf disallows characters such as NUL that are not +valid gtroff input characters (see Identifiers). +

+

For cf, within a diversion, “completely unprocessed” means that +each line of a file to be inserted is handled as if it were preceded by +\!\\!. +

+

To define a macro x containing the contents of +file f, use +

+
+
.ev 1
+.di x
+.trf f
+.di
+.ev
+
+ +

The calls to ev prevent the partially collected output line +from becoming part of the diversion (see Diversions). +

+ +
+
Request: .nx [file]
+
+ + + +

Force gtroff to continue processing of the file specified as an +argument. If no argument is given, immediately jump to the end of file. +

+ +
+
Request: .rd [prompt [arg1 arg2 …]]
+
+ + + +

Read from standard input, and include what is read as though it were +part of the input file. Text is read until a blank line is encountered. +

+

If standard input is a TTY input device (keyboard), write prompt +to standard error, followed by a colon (or send BEL for a beep if no +argument is given). +

+

Arguments after prompt are available for the input. For example, +the line +

+
+
.rd data foo bar
+
+ +

with the input ‘This is \$2. prints +

+
+
This is bar.
+
+
+ + + +

Using the nx and rd requests, it is easy to set up form +letters. The form letter template is constructed like this, putting the +following lines into a file called repeat.let: +

+
+
.ce
+\*(td
+.sp 2
+.nf
+.rd
+.sp
+.rd
+.fi
+Body of letter.
+.bp
+.nx repeat.let
+
+ + +

When this is run, a file containing the following lines should be +redirected in. Requests included in this file are executed as though +they were part of the form letter. The last block of input is the +ex request, which tells GNU troff to stop processing. If +this were not there, troff would not know when to stop. +

+
+
Trent A. Fisher
+708 NW 19th Av., #202
+Portland, OR  97209
+
+Dear Trent,
+
+Len Adollar
+4315 Sierra Vista
+San Diego, CA  92103
+
+Dear Mr. Adollar,
+
+.ex
+
+ +
+
Request: .pi pipe
+
+

Pipe the output of gtroff to the shell command(s) specified by +pipe. This request must occur before gtroff has a chance +to print anything. +

+ + + + +

It is an error to use this request in safer mode, which is the +default. Invoke GNU troff or a front end with the -U +option to enable unsafe mode. +

+

Multiple calls to pi are allowed, acting as a chain. For +example, +

+
+
.pi foo
+.pi bar
+...
+
+ +

is the same as ‘.pi foo | bar. +

+ + +

The intermediate output format of GNU troff is piped to the +specified commands. Consequently, calling groff without the +-Z option normally causes a fatal error. +

+ + + +
+
Request: .sy cmds
+
+
Register: \n[systat]
+
+

Execute the shell command(s) specified by cmds. The output is not +saved anywhere, so it is up to the user to do so. +

+ + + + +

It is an error to use this request in safer mode; this is the default. +Give GNU troff or a front end program the -U option to +enable unsafe mode. +

+

The following code fragment introduces the current time into a document. +

+ +
+
.sy perl -e 'printf ".nr H %d\\n.nr M %d\\n.nr S %d\\n",\
+             (localtime(time))[2,1,0]' > /tmp/x\n[$$]
+.so /tmp/x\n[$$]
+.sy rm /tmp/x\n[$$]
+\nH:\nM:\nS
+
+ +

This works by having the Perl script (run by sy) write +nr requests that set the registers H, M, and +S to a temporary file. The roff document then reads the +temporary file using the so request. +

+ + +

The registers seconds, minutes, and hours, +initialized at startup of GNU troff, should satisfy most +requirements. Use the af request to format their values for +output. +

+
+
.af hours 00
+.af minutes 00
+.af seconds 00
+\n[hours]:\n[minutes]:\n[seconds]
+    ⇒ 02:17:54
+
+ + +

The writable register systat contains the return value of the +system() function executed by the last sy request. +

+ +
+
Request: .open stream file
+
+
Request: .opena stream file
+
+ + + + +

Open the specified file for writing and associates the specified +stream with it. +

+

The opena request is like open, but if the file exists, +append to it instead of truncating it. +

+ + + + +

It is an error to use these requests in safer mode; this is the default. +Give GNU troff or a front end program the -U option to +enable unsafe mode. +

+ +
+
Request: .write stream data
+
+
Request: .writec stream data
+
+ + + + + + + + +

Write to the file associated with the specified stream. The +stream must previously have been the subject of an open request. The +remainder of the line is interpreted as the ds request reads its +second argument: an initial neutral double quote in contents is +stripped to allow embedding of leading spaces, and it is read in copy +mode. +

+

The writec request is like write, but only write +appends a newline to the data. +

+ +
+
Request: .writem stream xx
+
+ +

Write the contents of the macro or string xx to the file +associated with the specified stream. +

+ + + +

xx is read in copy mode, i.e., already formatted elements are +ignored. Consequently, diversions must be unformatted with the +asciify request before calling writem. Usually, this +means a loss of information. +

+ +
+
Request: .close stream
+
+ + +

Close the specified stream; the stream is no longer an acceptable +argument to the write request. +

+

Here a simple macro to write an index entry. +

+
+
.open idx test.idx
+.
+.de IX
+.  write idx \\n[%] \\$*
+..
+.
+.IX test entry
+.
+.close idx
+
+
+ +
+
Escape sequence: \Ve
+
+
Escape sequence: \V(ev
+
Escape sequence: \V[env]
+
+ + +

Interpolate the contents of the specified environment variable env +(one-character name e, two-character name ev) as +returned by the function getenv(3). \V is interpreted +even in copy mode (see Copy Mode). +

+ + + +
+
+
+ +

5.34 Postprocessor Access

+ + + +

Two escape sequences and two requests enable documents to pass +information directly to a postprocessor. These are useful for +exercising device-specific capabilities that the groff language +does not abstract or generalize; examples include the embedding of +hyperlinks and image files. Device-specific functions are documented in +each output driver’s man page, such as gropdf(1), +grops(1), or grotty(1). +

+
+
Request: .device xxx
+
+
Escape sequence: \X'xxx '
+
+

Embed all xxx arguments into GNU troff output as parameters +to a device control command ‘x X. The meaning and +interpretation of such parameters is determined by the output driver or +other postprocessor. +

+ + + +

The device request processes its arguments in copy mode +(see Copy Mode). An initial neutral double quote in contents +is stripped to allow embedding of leading spaces. + + + + +By contrast, within \X arguments, the escape sequences \&, +\), \%, and \: are ignored; \SP and +\~ are converted to single space characters; and \\ has +its escape character stripped. So that the basic Latin subset of the +Unicode character set115 can be reliably encoded in device control +commands, seven special character escape sequences (‘\-’, +‘\[aq]’, ‘\[dq]’, ‘\[ga]’, ‘\[ha]’, ‘\[rs]’, +and ‘\[ti]’,) are mapped to basic Latin characters; see the +groff_char(7) man page. For this transformation, character +translations and special character definitions are +ignored.116 The use of any +other escape sequence in \X parameters is normally an error. +

+ + + +

If the use_charnames_in_special directive appears in the output +device’s DESC file, the use of special character escape sequences +is not an error; they are simply output verbatim (with the +exception of the seven mapped to Unicode basic Latin characters, +discussed above). use_charnames_in_special is currently employed +only by grohtml. +

+ +
+
Request: .devicem name
+
+
Escape sequence: \Yn
+
+
Escape sequence: \Y(nm
+
Escape sequence: \Y[name]
+

This is approximately equivalent to ‘\X'\*[name]'’ +(one-character name n, two-character name nm). +However, the contents of the string or macro name are not +interpreted; also it is permitted for name to have been defined as +a macro and thus contain newlines (it is not permitted for the argument +to \X to contain newlines). The inclusion of newlines requires +an extension to the AT&T troff output format, and +confuses drivers that do not know about this extension (see Device Control Commands). +

+ +
+
Request: .tag name
+
+
Request: .taga name
+
+

Reserved for internal use. +

+ + + +
+
+
+ +

5.35 Miscellaneous

+ +

We document here GNU troff features that fit poorly elsewhere. +

+
+
Request: .nm [start [increment [space [indentation]]]]
+
+
Register: \n[ln]
+
+
Register: \n[.nm]
+
+ + + +

Begin (or, with no arguments, cease) numbering output lines. +start assigns the number of the next output line. Only +line numbers divisible by increment are marked (default: +‘1’). space configures the horizontal spacing between the +number and the text (default: ‘1’). Any given indentation is +applied to the numbers (default: ‘0’). The third and fourth +arguments are reckoned in numeral widths (\0). start must +be non-negative and increment positive. +

+

The formatter aligns the number to the right in a width of three numeral +spaces plus indentation, then catenates space and the output +line. The line length is not reduced. Depending on the value of +the page offset,117 numbers wider than +the allocated space protrude into the left margin, or shift the output +line to the right. +

+

Line numbering parameters corresponding to missing arguments are not +altered. After numbering is disabled, ‘.nm +0’ resumes it using +the previously active parameters. +

+

The parameters of nm are associated with the environment +(see Environments). +

+ + +

While numbering is enabled, the output line number register ln is +updated as each line is output, even if no line number is formatted with +it because it is being skipped (it is not a multiple of increment) +or because numbering is suppressed (see the nn request below). +

+

The .nm register tracks the enablement status of numbering. +Temporary suspension of numbering with the nn request does +not alter its value. +

+
+
.po 5n
+.ll 44n
+Programming,
+when stripped of all its circumstantial irrelevancies,
+.nm 999 1 1 -4
+boils down to no more and no less than
+.nm +0 3
+very effective thinking so as to avoid unmastered
+.nn 2
+complexity,
+to very vigorous separation of your many
+different concerns.
+.br
+\(em Edsger Dijkstra
+.sp
+.nm 1 1 1
+This guy's arrogance takes your breath away.
+.br
+\(em John Backus
+    ⇒      Programming,  when  stripped of all its cir-
+    ⇒  999 cumstantial irrelevancies, boils down to  no
+    ⇒      more  and no less than very effective think-
+    ⇒      ing so as to avoid unmastered complexity, to
+    ⇒      very vigorous separation of your  many  dif-
+    ⇒      ferent concerns.
+    ⇒ 1002 -- Edsger Dijkstra
+    ⇒
+    ⇒    1 This guy’s arrogance takes your breath away.
+    ⇒    2 -- John Backus
+
+
+ +
+
Request: .nn [skip]
+
+
Register: \n[.nn]
+
+

Suppress numbering of the next skip output lines that would +otherwise be numbered. The default is 1. nn can be invoked +when line numbering is not active; suppression of numbering will take +effect for skip lines once nm enables it. +

+

The .nn register stores the count of output lines still to have +their numbering suppressed. +

+

This count is associated with the environment (see Environments). +

+ +

To test whether the current output line will be numbered, you must check +both the .nm and .nn registers. +

+
+
  .de is-numbered
+  .  nop This line
+  .  ie (\\n[.nm] & (1-\\n[.nn])) IS
+  .  el                           ISN'T
+  .  nop numbered.
+  .  br
+  ..
+  Test line numbering.
+  .is-numbered
+  .nm 1
+  .nn 1
+  .is-numbered
+  .is-numbered
+  .nm
+  .is-numbered
+    ⇒ Test line numbering.  This line ISN’T numbered.
+    ⇒ This line ISN’T numbered.
+    ⇒   1 This line IS numbered.
+    ⇒ This line ISN’T numbered.
+
+ +
+
Request: .mc [margin-character [distance]
+
+ + +

Begin (or, with no arguments, cease) writing a margin-character to +the right of each output line. The distance argument separates +margin-character from the right margin. If absent, the most +recent value is used; the default is 10 points. If an output line +exceeds the line length, the margin character is appended to it. + +No margin character is written on lines produced by the tl +request. +

+

The margin character is a property of the output line; the margin +character last configured when the line is output controls. If the +margin character is disabled before an output line breaks, none is +output (but see below). +

+

The margin character is associated with the environment +(see Environments). +

+
+
.ll 5i
+.nf
+.mc \[br]
+This paragraph is marked with a margin character.
+.sp
+As seen above, vertical space isn't thus marked.
+\&
+An output line that is present, but empty, is.
+    ⇒ This paragraph is marked with a margin character.  |
+    ⇒
+    ⇒ As seen above, vertical space isn’t thus marked.   |
+    ⇒                                                    |
+    ⇒ An output line that is present, but empty, is.     |
+
+
+ +

For compatibility with AT&T troff, a call to mc +to set the margin character can’t be undone immediately; at least one +line gets a margin character. +

+
+
.ll 10n
+.nf
+.mc |
+.mc *
+.mc
+foo
+bar
+    ⇒ foo        *
+    ⇒ bar
+
+ + + + + +

The margin character mechanism is commonly used to annotate changes in +documents. The groff distribution ships a program, +gdiffmk, to assist with this task.118 +

+
+
Request: .psbb file
+
+
Register: \n[llx]
+
+
Register: \n[lly]
+
+
Register: \n[urx]
+
+
Register: \n[ury]
+
+ + +

Retrieve the bounding box of the PostScript image found in file, +which must conform to Adobe’s Document Structuring Conventions +(DSC), locate a %%BoundingBox comment, and store the (upper-, +lower-, -left, -right) values into the registers llx, +lly, urx, and ury. If an error occurs (for +example, if no %%BoundingBox comment is present), the formatter +sets these registers to 0. +

+

The search path for file can be controlled with the -I +command-line option. +

+ + + + +
+
+
+ +

5.36 gtroff Internals

+ + + + + +

gtroff processes input in three steps. One or more input +characters are converted to an input token.119 Then, one or more input tokens are converted to +an output node. Finally, output nodes are converted to the +intermediate output language understood by all output devices. +

+

Actually, before step one happens, gtroff converts certain escape +sequences into reserved input characters (not accessible by the user); +such reserved characters are used for other internal processing also – +this is the very reason why not all characters are valid input. +See Identifiers, for more on this topic. +

+

For example, the input string ‘fi\[:u]’ is converted into a +character token ‘f’, a character token ‘i’, and a special +token ‘:u’ (representing u umlaut). Later on, the character +tokens ‘f’ and ‘i’ are merged to a single output node +representing the ligature glyph ‘fi’ (provided the current font has +a glyph for this ligature); the same happens with ‘:u’. All output +glyph nodes are ‘processed’, which means that they are invariably +associated with a given font, font size, advance width, etc. During the +formatting process, gtroff itself adds various nodes to control +the data flow. +

+

Macros, diversions, and strings collect elements in two chained lists: a +list of input tokens that have been passed unprocessed, and a list of +output nodes. Consider the following diversion. +

+
+
.di xxx
+a
+\!b
+c
+.br
+.di
+
+ +

It contains these elements. +

+ + + + + + + + + + + + +
node listtoken listelement number
line start node1
glyph node a2
word space node3
b4
\n5
glyph node c6
vertical size node7
vertical size node8
\n9
+ + +

Elements 1, 7, and 8 are inserted by gtroff; the latter two +(which are always present) specify the vertical extent of the last line, +possibly modified by \x. The br request finishes the +pending output line, inserting a newline input token, which is +subsequently converted to a space when the diversion is reread. Note +that the word space node has a fixed width that isn’t adjustable +anymore. To convert horizontal space nodes back to input tokens, use +the unformat request. +

+

Macros only contain elements in the token list (and the node list is +empty); diversions and strings can contain elements in both lists. +

+

The chop request simply reduces the number of elements in a +macro, string, or diversion by one. Exceptions are compatibility +save and compatibility ignore input tokens, which are ignored. +The substring request also ignores those input tokens. +

+

Some requests like tr or cflags work on glyph identifiers +only; this means that the associated glyph can be changed without +destroying this association. This can be very helpful for substituting +glyphs. In the following example, we assume that glyph ‘foo’ isn’t +available by default, so we provide a substitution using the +fchar request and map it to input character ‘x’. +

+
+
.fchar \[foo] foo
+.tr x \[foo]
+
+ +

Now let us assume that we install an additional special font ‘bar’ +that has glyph ‘foo’. +

+
+
.special bar
+.rchar \[foo]
+
+ +

Since glyphs defined with fchar are searched before glyphs in +special fonts, we must call rchar to remove the definition of the +fallback glyph. Anyway, the translation is still active; ‘x’ now +maps to the real glyph ‘foo’. +

+ + + + + + +

Macro and request arguments preserve compatibility mode enablement. +

+
+
.cp 1     \" switch to compatibility mode
+.de xx
+\\$1
+..
+.cp 0     \" switch compatibility mode off
+.xx caf\['e]
+    ⇒ café
+
+ +

Since compatibility mode is enabled while de is invoked, the +macro xx enables compatibility mode when it is called. Argument +$1 can still be handled properly because it inherits the +compatibility mode enablement status that was active at the point where +xx was called. +

+

After interpolation of the parameters, the compatibility save and +restore tokens are removed. +

+ + + +
+
+
+ +

5.37 Debugging

+ + +

Standard troff voodoo, just put a power of two backslashes in +front of it until it works and if you still have problems add a \c. +— Ron Natalie +

+

GNU troff is not the easiest language to debug, in part thanks to +its design features of recursive interpolation and the use of +multi-stage pipeline processing in the surrounding system. Nevertheless +there exist several features useful for troubleshooting. +

+

Preprocessors use the lf request to preserve the identity of the +line numbers and names of input files. GNU troff emits a variety +of error diagnostics and supports several categories of warning; the +output of these can be selectively suppressed. A trace of the +formatter’s input processing stack can be emitted when errors or +warnings occur by means of GNU troff’s -b option, or +produced on demand with the backtrace request. The tm +and related requests can be used to emit customized diagnostic messages +or for instrumentation while troubleshooting. The ex and +ab requests cause early termination with successful and error +exit codes respectively, to halt further processing when continuing +would be fruitless. Examine the state of the formatter with requests +that write lists of defined names (macros, strings, and diversions), +environments, registers, and page location traps to the standard error +stream. +

+
+
Request: .lf line [file]
+
+ + + + + + +

Set the input line number (and, optionally, the file name) GNU +troff shall use for error and warning messages. line is +the input line number of the next line. Without an argument, the +request is ignored. +

+

lf’s primary purpose is to aid the debugging of documents that +undergo preprocessing. Programs like tbl that transform input +in their own languages into roff requests use it so that any +diagnostic messages emitted by troff correspond to the source +document. +

+ +
+
Request: .tm message
+
+
Request: .tm1 message
+
+
Request: .tmc message
+
+ + +

Send message, which consumes the remainder of the input line and +cannot contain special characters, to the standard error stream, +followed by a newline. Leading spaces in message are ignored. +

+

tm1 is similar, but recognizes and strips a leading neutral +double quote from message to allow the embedding of leading +spaces. +

+

tmc works as tm1, but does not append a newline. +

+ +
+
Request: .ab [message]
+
+ +

Write any message to the standard error stream (like tm) +and then abort GNU troff; that is, stop processing and terminate +with a failure status. +

+ +
+
Request: .ex
+
+ + +

Exit GNU troff; that is, stop processing and terminate with a +successful status. To stop processing only the current file, use the +nx request; see I/O. +

+ +

When doing something involved, it is useful to leave the debugging +statements in the code and have them turned on by a command-line flag. +

+
+
.if \n[DB] .tm debugging output
+
+ +

To activate such statements, use the -r option to set the +register. +

+
+
groff -rDB=1 file
+
+ +

If it is known in advance that there are many errors and no useful +output, GNU troff can be forced to suppress formatted output with +the -z option. +

+
+
Request: .pev
+
+ + +

Report the state of the current environment followed by that of all +other environments to the standard error stream. +

+ +
+
Request: .pm
+
+ + +

Report, to the standard error stream, the names of all defined macros, +strings, and diversions with their sizes in bytes. +

+ +
+
Request: .pnr
+
+ + +

Report the names and contents of all currently defined registers to the +standard error stream. +

+ +
+
Request: .ptr
+
+ + + + +

Report the names and positions of all page location traps to the +standard error stream. Empty slots in the list, where a trap has been +planted but subsequently (re)moved, are printed as well. +

+ +
+
Request: .fl
+
+ + + + +

Instruct gtroff to flush its output immediately. The intent is +for interactive use, but this behaviour is currently not implemented in +gtroff. Contrary to Unix troff, TTY output is sent to a +device driver also (grotty), making it non-trivial to communicate +interactively. +

+

This request causes a line break. +

+ +
+
Request: .backtrace
+
+ + +

Write the state of the input stack to the standard error stream. +

+

Consider the following in a file test. +

+
+
.de xxx
+.  backtrace
+..
+.de yyy
+.  xxx
+..
+.
+.yyy
+    error→ troff: backtrace: 'test':2: macro 'xxx'
+    error→ troff: backtrace: 'test':5: macro 'yyy'
+    error→ troff: backtrace: file 'test':8
+
+ +

The -b option of GNU troff causes a backtrace to be +generated on each error or warning. Some warnings have to be enabled; +See Warnings. +

+ +
+
Register: \n[slimit]
+
+ +

If greater than 0, sets the maximum quantity of objects on GNU +troff’s internal input stack. If less than or equal to 0, +there is no limit: recursion can continue until program memory is +exhausted. The default is 1,000. +

+ +
+
Request: .warnscale su
+
+

Set the scaling unit used in certain warnings to su, which can take the values ‘u’, ‘i’, ‘c’, +‘p’, and ‘P’. The default is ‘i’. +

+ +
+
Request: .spreadwarn [limit]
+
+

Emit a break warning if the additional space inserted for each +space between words in an output line adjusted to both margins with +‘.ad b is larger than or equal to limit. A negative +value is treated as zero; an absent argument toggles the warning on and +off without changing limit. The default scaling unit is ‘m’. +At startup, spreadwarn is inactive and limit is 3m. +

+

For example, +

+
+
.spreadwarn 0.2m
+
+ +

causes a warning if break warnings are not suppressed and +gtroff must add 0.2m or more for each inter-word space in a +line. See Warnings. +

+ + +

GNU troff has command-line options for reporting warnings +(-w) and backtraces (-b) when a warning or an error +occurs. +

+
+
Request: .warn [n]
+
+
Register: \n[.warn]
+
+ +

Select the categories, or “types”, of reported warnings. +n is the sum of the numeric codes associated with each +warning category that is to be enabled; all other categories are +disabled. The categories and their associated codes are listed in +Warnings. For example, ‘.warn 0’ disables all warnings, and +‘.warn 1’ disables all warnings except those about missing glyphs. +If no argument is given, all warning categories are enabled. +

+

The read-only register .warn contains the sum of the numeric +codes of enabled warning categories. +

+ + + + +
+
+ +

5.37.1 Warnings

+ + +

Warning diagnostics emitted by GNU troff are divided into named, +numbered categories. The name associated with each warning category is +used by the -w and -W options. Each category is also +assigned a power of two; the sum of enabled category values is used by +the warn request and the .warn register. +

+

Warnings of each category are produced under the following +circumstances. +

+ + +
+
char
+
1
+

No mounted font defines a glyph for the requested character. This +category is enabled by default. +

+
+
number
+
2
+

An invalid numeric expression was encountered. This category is enabled +by default. +See Numeric Expressions. +

+
+
break
+
4
+
+

A filled output line could not be broken such that its length was less +than the output line length ‘\n[.l]’. This category is enabled by +default. +

+
+
delim
+
8
+

The closing delimiter in an escape sequence was missing or mismatched. +

+
+
el
+
16
+
+

The el request was encountered with no prior corresponding +ie request. See if-else. +

+
+
scale
+
32
+

A scaling unit inappropriate to its context was used in a numeric +expression. +

+
+
range
+
64
+

A numeric expression was out of range for its context. +

+
+
syntax
+
128
+

A self-contradictory hyphenation mode was requested; an empty or +incomplete numeric expression was encountered; an operand to a numeric +operator was missing; an attempt was made to define a recursive, empty, +or nonsensical character class; or a groff extension conditional +expression operator was used while in compatibility mode. +

+
+
di
+
256
+
+ + +

A di, da, box, or boxa request was invoked +without an argument when there was no current diversion. +

+
+
mac
+
512
+
+ + + + + + +

An undefined string, macro, or diversion was used. When such an object +is dereferenced, an empty one of that name is automatically created. +So, unless it is later deleted, at most one warning is given for each. +

+

This warning is also emitted upon an attempt to move an unplanted trap +macro (see Page Location Traps). In such cases, the unplanted macro +is not dereferenced, so it is not created if it does not exist. +

+
+
reg
+
1024
+
+ +

An undefined register was used. When an undefined register is +dereferenced, it is automatically defined with a value of 0. So, +unless it is later deleted, at most one warning is given for each. +

+
+
tab
+
2048
+

A tab character was encountered where a number was expected, or appeared +in an unquoted macro argument. +

+
+
right-brace
+
4096
+

A right brace escape sequence \} was encountered where a number +was expected. +

+
+
missing
+
8192
+

A request was invoked with a mandatory argument absent. +

+
+
input
+
16384
+

An invalid character occurred on the input stream. +

+
+
escape
+
32768
+

An unsupported escape sequence was encountered. +

+
+
space
+
65536
+

A space was missing between a request or macro and its argument. This +warning is produced when an undefined name longer than two characters is +encountered and the first two characters of the name constitute a +defined name. No request is invoked, no macro called, and an empty +macro is not defined. This category is enabled by default. It never +occurs in compatibility mode. +

+
+
font
+
131072
+

A non-existent font was selected, or the selection was ignored because a +font selection escape sequence was used after the output line +continuation escape sequence on an input line. This category is enabled +by default. +

+
+
ig
+
262144
+

An invalid escape sequence occurred in input ignored using the ig +request. This warning category diagnoses a condition that is an error +when it occurs in non-ignored input. +

+
+
color
+
524288
+

An undefined color was selected, an attempt was made to define a color +using an unrecognized color space, an invalid component in a color +definition was encountered, or an attempt was made to redefine a default +color. +

+
+
file
+
1048576
+

An attempt was made to load a file that does not exist. This category +is enabled by default. +

+
+ +

Two warning names group other warning categories for convenience. +

+
+
all
+

All warning categories except ‘di’, ‘mac’ and ‘reg’. +This shorthand is intended to produce all warnings that are useful with +macro packages written for AT&T troff and its +descendants, which have less fastidious diagnostics than GNU +troff. +

+
+
w
+

All warning categories. Authors of documents and macro packages +targeting groff are encouraged to use this setting. +

+
+ + +
+
+
+
+ +

5.38 Implementation Differences

+ + + + +

GNU troff has a number of features that cause incompatibilities +with documents written for other versions of troff. Some GNU +extensions to troff have become supported by other +implementations. +

+ + + +
+
+ +

5.38.1 Safer Mode

+ + + + + +

The formatter operates in “safer” mode by default; to mitigate risks +from untrusted input documents, the pi and sy requests are +disabled. GNU troff’s -U option enables “unsafe +mode”, restoring their function and enabling additional groff +extension requests, open, opena, and pso. +See I/O. +

+ +
+
+
+ +

5.38.2 Compatibility Mode

+ + + + + + + +

Long identifier names may be GNU troff’s most obvious innovation. +AT&T troff interprets ‘.dsabcd’ as defining a +string ‘ab’ with contents ‘cd’. Normally, GNU troff +interprets this as a call of a macro named dsabcd. +AT&T troff also interprets ‘\*[’ and ‘\n[’ as +an interpolation of a string or register, respectively, named ‘[’. +In GNU troff, however, the ‘[’ is normally interpreted as +delimiting a long name. In compatibility mode, GNU troff +interprets names in the traditional way; they thus can be two characters +long at most. +

+
+
Request: .cp [n]
+
+
Register: \n[.C]
+
+

If n is missing or non-zero, turn on compatibility mode; +otherwise, turn it off. +

+

The read-only register .C is 1 if compatibility mode is on, +0 otherwise. +

+

Compatibility mode can be also turned on with the -C +command-line option. +

+ +
+
Request: .do name
+
+
Register: \n[.cp]
+
+

The do request interprets the string, request, diversion, or +macro name (along with any further arguments) with compatibility +mode disabled. Compatibility mode is restored (only if it was active) +when the expansion of name is interpreted; that is, the +restored compatibility state applies to the contents of the macro, +string, or diversion name as well as data read from files or pipes +if name is any of the so, soquiet, mso, +msoquiet, or pso requests. +

+

The following example illustrates several aspects of do behavior. +

+
+
.de mac1
+FOO
+..
+.de1 mac2
+groff
+.mac1
+..
+.de mac3
+compatibility
+.mac1
+..
+.de ma
+\\$1
+..
+.cp 1
+.do mac1
+.do mac2 \" mac2, defined with .de1, calls "mac1"
+.do mac3 \" mac3 calls "ma" with argument "c1"
+.do mac3 \[ti] \" groff syntax accepted in .do arguments
+    ⇒ FOO groff FOO compatibility c1 ~
+
+ +

The read-only register .cp, meaningful only when dereferenced +from a do request, is 1 if compatibility mode was on when +the do request was encountered, and 0 if it was not. This +register is specialized and may require a statement of rationale. +

+

When writing macro packages or documents that use GNU troff +features and which may be mixed with other packages or documents that do +not—common scenarios include serial processing of man pages or use of +the so or mso requests—you may desire correct operation +regardless of compatibility mode enablement in the surrounding context. +It may occur to you to save the existing value of ‘\n(.C’ into a +register, say, ‘_C’, at the beginning of your file, turn +compatibility mode off with ‘.cp 0’, then restore it from that +register at the end with ‘.cp \n(_C’. At the same time, a modular +design of a document or macro package may lead you to multiple layers of +inclusion. You cannot use the same register name everywhere lest you +“clobber” the value from a preceding or enclosing context. The +two-character register name space of AT&T troff is +confining and mnemonically challenging; you may wish to use the more +capacious name space of GNU troff. However, attempting ‘.nr +_my_saved_C \n(.C’ will not work in compatibility mode; the register +name is too long. “This is exactly what do is for,” you think, +‘.do nr _my_saved_C \n(.C’. The foregoing will always save zero to +your register, because do turns compatibility mode off +while it interprets its argument list. +

+

To robustly save compatibility mode before switching it off, use +

+
+
.do nr _my_saved_C \n[.cp]
+.cp 0
+
+ +

at the beginning of your file, followed by +

+
+
.cp \n[_my_saved_C]
+.do rr _my_saved_C
+
+ +

at the end. As in the C language, we all have to share one big +name space, so choose a register name that is unlikely to collide with +other uses. +

+ + + + +

Normally, GNU troff preserves the interpolation depth in +delimited arguments, but not in compatibility mode. +

+
+
.ds xx '
+\w'abc\*(xxdef'
+    ⇒ 168 (normal mode on a terminal device)
+    ⇒ 72def' (compatibility mode on a terminal device)
+
+ + + + + +

Furthermore, the escape sequences \f, \H, \m, +\M, \R, \s, and \S are transparent for the +purpose of recognizing a control character at the beginning of a line +only in compatibility mode. For example, this code produces bold output +in both cases, but the text differs. +

+
+
.de xx
+Hello!
+..
+\fB.xx\fP
+    ⇒ .xx (normal mode)
+    ⇒ Hello! (compatibility mode)
+
+ + +

Normally, the syntax form \sn accepts only a single +character (a digit) for n, consistently with other forms that +originated in AT&T troff, like \*, \$, +\f, \g, \k, \n, and \z. In +compatibility mode only, a non-zero n must be in the range +4–39. Legacy documents relying upon this quirk of parsing120 should be migrated to another +\s form. +

+ +
+
+
+ +

5.38.3 Other Differences

+ +

groff request names unrecognized by other troff +implementations will likely be ignored by them; escape sequences that +are groff extensions are liable to be interpreted as if the +escape character were not present. + +For example, the adjustable, non-breaking escape sequence \~ +is also supported by Heirloom Doctools troff 050915 (September +2005), mandoc 1.9.5 (2009-09-21), neatroff (commit +1c6ab0f6e, 2016-09-13), and Plan 9 from User Space troff +(commit 93f8143600, 2022-08-12), but not by Solaris or Documenter’s +Workbench troffs. +See Manipulating Filling and Adjustment. +

+ + + + + + + + + + + + + + +

GNU troff does not allow the use of the escape sequences +\|, \^, \&, \{, \}, +\SP, \', \`, \-, \_, \!, +\%, and \c in identifiers; AT&T troff +does. The \A escape sequence (see Identifiers) may be +helpful in avoiding use of these escape sequences in names. +

+ + +

When adjusting to both margins, AT&T troff at first +adjusts spaces starting from the right; GNU troff begins from +the left. Both implementations adjust spaces from opposite ends on +alternating output lines in this adjustment mode to prevent “rivers” +in the text. +

+ +

GNU troff does not always hyphenate words as AT&T +troff does. The AT&T implementation uses a set of +hard-coded rules specific to English, while GNU troff uses +language-specific hyphenation pattern files derived from TeX. +Furthermore, in old versions of troff there was a limited amount +of space to store hyphenation exceptions (arguments to the hw +request); GNU troff has no such restriction. +

+ +

GNU troff predefines a string .T containing the argument +given to the -T command-line option, namely the current output +device (for example, ‘pdf’ or ‘utf8’). The existence of this +string is a common feature of post-CSTR #54 +troffs121 but valid values are specific +to each implementation. +

+ + + +

AT&T troff ignored attempts to remove read-only +registers; GNU troff honors such requests. See Built-in Registers. +

+ +

The (read-only) register .T interpolates 1 if GNU +troff is called with the -T command-line option, and +0 otherwise. This behavior differs from AT&T troff, which +interpolated 1 only if nroff was the formatter and was +called with -T. +

+ +

AT&T troff and other implementations handle the +lf request differently. For them, its line argument +changes the line number of the current line. +

+ +

AT&T troff had only environments named ‘0’, +‘1’, and ‘2’. In GNU troff, any number of environments +may exist, using any valid identifiers for their names +(see Identifiers.) +

+ + + + + + +

Fractional type sizes cause one noteworthy incompatibility. In +AT&T troff the ps request ignores scaling units +and thus ‘.ps 10u’ sets the type size to 10 points, whereas in +GNU troff it sets the type size to 10 scaled points. +See Using Fractional Type Sizes. +

+ +

The ab request differs from AT&T troff: +GNU troff writes no message to the standard error stream if no +arguments are given, and it exits with a failure status instead of a +successful one. +

+ +

The bp request differs from AT&T troff: +GNU troff does not accept a scaling unit on the argument, a page +number; the former (somewhat uselessly) does. +

+ +

The pm request differs from AT&T troff: +GNU troff reports the sizes of macros, strings, and diversions in +bytes and ignores an argument to report only the sum of the sizes. +

+ +

Unlike AT&T troff, GNU troff does not ignore the +ss request if the output is a terminal device; instead, the +values of minimal inter-word and additional inter-sentence space are +each rounded down to the nearest multiple of 12. +

+ + + + + + + + +

In GNU troff there is a fundamental difference between +(unformatted) characters and (formatted) glyphs. Everything that +affects how a glyph is output is stored with the glyph node; once a +glyph node has been constructed, it is unaffected by any subsequent +requests that are executed, including bd, cs, tkf, +tr, or fp requests. Normally, glyphs are constructed from +characters immediately before the glyph is added to an output line. +Macros, diversions, and strings are all, in fact, the same type of +object; they contain a sequence of intermixed character and glyph nodes. +Special characters transform from one to the other: before being added +to the output, they behave as characters; afterward, they are glyphs. A +glyph node does not behave like a character node when it is processed by +a macro: it does not inherit any of the special properties that the +character from which it was constructed might have had. For example, +the input +

+
+
.di x
+\\\\
+.br
+.di
+.x
+
+ +

produces ‘\\’ in GNU troff. Each pair of backslashes +becomes one backslash glyph; the resulting backslashes are thus +not interpreted as escape characters when they are reread as the +diversion is output. AT&T troff would interpret +them as escape characters when rereading them and end up printing one +‘\’. +

+ + + + + + + +

One correct way to obtain a printable backslash in most documents is to +use the \e escape sequence; this always prints a single instance +of the current escape character,122 regardless of whether or not it is used in a diversion; it +also works in both GNU troff and AT&T troff. +

+

The other correct way, appropriate in contexts independent of the +backslash’s common use as a troff escape character—perhaps in +discussion of character sets or other programming languages—is +the character escape \(rs or \[rs], for “reverse +solidus”, from its name in the ECMA-6 (ISO/IEC 646) +standard.123 +

+

To store an escape sequence in a diversion that is interpreted when the +diversion is reread, either use the traditional \! transparent +output facility, or, if this is unsuitable, the new \? escape +sequence. See Diversions and gtroff Internals. +

+

In the somewhat pathological case where a diversion exists containing a +partially collected line and a partially collected line at the top-level +diversion has never existed, AT&T troff will output the +partially collected line at the end of input; GNU troff will not. +

+ + + + +
+
+
+
+
+ +

6 File Formats

+ + + +

All files read and written by gtroff are text files. The +following two sections describe their format. +

+ + + + + +
+
+ +

6.1 gtroff Output

+ + + +

This section describes the groff intermediate output format +produced by GNU troff. +

+

As groff is a wrapper program around GNU troff and +automatically calls an output driver (or “postprocessor”), this output +does not show up normally. This is why it is called +intermediate. groff provides the option -Z to +inhibit postprocessing such that the produced intermediate output is +sent to standard output just as it is when calling GNU troff +directly. +

+ + + + +

Here, the term troff output describes what is output by +GNU troff, while intermediate output refers to the language +that is accepted by the parser that prepares this output for the output +drivers. This parser handles whitespace more flexibly than +AT&T’s implementation and implements obsolete elements for +compatibility; otherwise, both formats are the same.124 +

+

The main purpose of the intermediate output concept is to facilitate the +development of postprocessors by providing a common programming +interface for all devices. It has a language of its own that is +completely different from the gtroff language. While the +gtroff language is a high-level programming language for text +processing, the intermediate output language is a kind of low-level +assembler language by specifying all positions on the page for writing +and drawing. +

+

The intermediate output produced by gtroff is fairly readable, +while output from AT&T troff is rather hard to +understand because of strange habits that are still supported, but not +used any longer by gtroff. +

+ + + +
+
+ +

6.1.1 Language Concepts

+ +

The fundamental operation of the GNU troff formatter is the +translation of the groff input language into a device-independent +form primarily concerned with what has to be written or drawn at +specific positions on the output device. This language is simple and +imperative. In the following discussion, the term command always +refers to this intermediate output language, and never to the +groff language intended for direct use by document authors. +Intermediate output commands comprise several categories: glyph output; +font, color, and text size selection; motion of the printing position; +page advancement; drawing of geometric objects; and device control +commands, a catch-all for operations not easily classified as any of the +foregoing, such as directives to start and stop output, identify the +intended output device, or place URL hyperlinks in supported output +formats. +

+ + +
+
+ +

6.1.1.1 Separation

+ +

AT&T troff output has strange requirements regarding +whitespace. The gtroff output parser, however, is more tolerant, +making whitespace maximally optional. Such characters, i.e., the tab, +space, and newline, always have a syntactical meaning. They are never +printable because spacing within the output is always done by +positioning commands. +

+

Any sequence of space or tab characters is treated as a single +syntactical space. It separates commands and arguments, but is +only required when there would occur a clashing between the command code +and the arguments without the space. Most often, this happens when +variable-length command names, arguments, argument lists, or command +clusters meet. Commands and arguments with a known, fixed length need +not be separated by syntactical space. +

+

A line break is a syntactical element, too. Every command argument can +be followed by whitespace, a comment, or a newline character. Thus a +syntactical line break is defined to consist of optional +syntactical space that is optionally followed by a comment, and a +newline character. +

+

The normal commands, those for positioning and text, consist of a single +letter taking a fixed number of arguments. For historical reasons, the +parser allows stacking of such commands on the same line, but +fortunately, in gtroff’s intermediate output, every command with +at least one argument is followed by a line break, thus providing +excellent readability. +

+

The other commands—those for drawing and device controlling—have a +more complicated structure; some recognize long command names, and some +take a variable number of arguments. So all ‘D’ and ‘x’ +commands were designed to request a syntactical line break after their +last argument. Only one command, ‘x X, has an argument that +can span several input lines; all other commands must have all of +their arguments on the same line as the command, i.e., the arguments may +not be split by a line break. +

+

Empty lines (these are lines containing only space and/or a comment), +can occur everywhere. They are just ignored. +

+
+
+
+ +

6.1.1.2 Argument Units

+ +

Some commands take integer arguments that are assumed to represent +values in a measurement unit, but the letter for the corresponding +scaling unit is not written with the output command arguments. Most +commands assume the scaling unit ‘u’, the basic unit of the device, +some use ‘z’, the scaled point unit of the device, while others, +such as the color commands, expect plain integers. +

+

Single characters can have the eighth bit set, as can the names of +fonts and special characters. The names of characters and fonts can be +of arbitrary length. A character that is to be printed is always in +the current font. +

+

A string argument is always terminated by the next whitespace character +(space, tab, or newline); an embedded ‘#’ character is regarded as +part of the argument, not as the beginning of a comment command. An +integer argument is already terminated by the next non-digit character, +which then is regarded as the first character of the next argument or +command. +

+
+
+
+ +

6.1.1.3 Document Parts

+ +

A correct intermediate output document consists of two parts, the +prologue and the body. +

+

The task of the prologue is to set the general device parameters using +three exactly specified commands. gtroff’s prologue is +guaranteed to consist of the following three lines (in that order): +

+
+
x T device
+x res n h v
+x init
+
+ +

with the arguments set as outlined in Device Control Commands. +The parser for the intermediate output format is able to interpret +additional whitespace and comments as well even in the prologue. +

+

The body is the main section for processing the document data. +Syntactically, it is a sequence of any commands different from the ones +used in the prologue. Processing is terminated as soon as the first +‘x stop command is encountered; the last line of any +gtroff intermediate output always contains such a command. +

+

Semantically, the body is page oriented. A new page is started by a +‘p’ command. Positioning, writing, and drawing commands are always +done within the current page, so they cannot occur before the first +‘p’ command. Absolute positioning (by the ‘H’ and ‘V’ +commands) is done relative to the current page; all other positioning is +done relative to the current location within this page. +

+ +
+
+
+
+ +

6.1.2 Command Reference

+ +

This section describes all intermediate output commands, both from +AT&T troff as well as the gtroff extensions. +

+ + +
+
+ +

6.1.2.1 Comment Command

+ +
+
#anythingend of line
+

A comment. Ignore any characters from the ‘#’ character up to the +next newline character. +

+

This command is the only possibility for commenting in the intermediate +output. Each comment can be preceded by arbitrary syntactical space; +every command can be terminated by a comment. +

+
+ +
+
+
+ +

6.1.2.2 Simple Commands

+ +

The commands in this subsection have a command code consisting of a +single character, taking a fixed number of arguments. Most of them are +commands for positioning and text writing. These commands are tolerant +of whitespace. Optionally, syntactical space can be inserted before, +after, and between the command letter and its arguments. All of these +commands are stackable; i.e., they can be preceded by other simple +commands or followed by arbitrary other commands on the same line. A +separating syntactical space is necessary only when two integer +arguments would clash or if the preceding argument ends with a string +argument. +

+
+
C idwhitespace
+

Typeset the glyph of the special character id. Trailing +syntactical space is necessary to allow special character names of +arbitrary length. The drawing position is not advanced. +

+
+
c g
+

Typeset the glyph of the ordinary character c. The drawing +position is not advanced. +

+
+
f n
+

Select the font mounted at position n. n cannot +be negative. +

+
+
H n
+

Horizontally move the drawing position to n basic units from +the left edge of the page. n cannot be negative. +

+
+
h n
+

Move the drawing position right n basic units. AT&T +troff allowed negative n; GNU troff does not produce +such values, but groff’s output driver library handles them. +

+
+
m color-scheme [component]
+

Select the stroke color using the components in the color space +scheme. Each component is an integer between 0 and 65535. +The quantity of components and their meanings vary with each +scheme. This command is a groff extension. +

+
+
mc cyan magenta yellow
+

Use the CMY color scheme with components cyan, magenta, and yellow. +

+
+
md
+

Use the default color (no components; black in most cases). +

+
+
mg gray
+

Use a grayscale color scheme with a component ranging between 0 (black) +and 65535 (white). +

+
+
mk cyan magenta yellow black
+

Use the CMYK color scheme with components cyan, magenta, yellow, and +black. +

+
+
mr red green blue
+

Use the RGB color scheme with components red, green, and blue. +

+
+ +
+
N n
+

Typeset the glyph with index n in the current font. +n is normally a non-negative integer. The drawing position +is not advanced. The html and xhtml devices use this +command with negative n to produce unbreakable space; the +absolute value of n is taken and interpreted in basic units. +

+
+
n b a
+

Indicate a break. No action is performed; the command is present to +make the output more easily parsed. The integers b +and a describe the vertical space amounts before and after +the break, respectively. GNU troff issues this command but +groff’s output driver library ignores it. See v and +V below. +

+
+
p n
+

Begin a new page, setting its number to n. Each page is +independent, even from those using the same number. The vertical +drawing position is set to 0. All positioning, writing, and +drawing commands are interpreted in the context of a page, so a +p command must precede them. +

+
+
s n
+

Set type size to n scaled points (unit z in GNU +troff. +AT&T troff used unscaled points p instead; +see Output Language Compatibility. +

+
+
t xyzwhitespace
+
t xyz dummy-argwhitespace
+

Typeset a word xyz; that is, set a sequence of ordinary glyphs +named x, y, z, …, terminated by a space +character or a line break; an optional second integer argument is +ignored (this allows the formatter to generate an even number of +arguments). Each glyph is set at the current drawing position, and the position is +then advanced horizontally by the glyph’s width. A glyph’s width is +read from its metrics in the font description file, scaled to the +current type size, and rounded to a multiple of the horizontal motion +quantum. Use the C command to emplace glyphs of special +characters. The t command is a groff extension and +is output only for devices whose DESC file contains the +tcommand directive; see DESC File Format. +

+
+
u n xyzwhitespace
+

Typeset word xyz with track kerning. As t, but after +placing each glyph, the drawing position is further advanced +horizontally by n basic units (u). The +u command is a groff extension and is output only for +devices whose DESC file contains the tcommand directive; +see DESC File Format. +

+
+
V n
+

Vertically move the drawing position to n basic units from +the top edge of the page. n cannot be negative. +

+
+
v n
+

Move the drawing position down n basic units. AT&T +troff allowed negative n; GNU troff does not produce +such values, but groff’s output driver library handles them. +

+
+
w
+

Indicate an inter-word space. No action is performed; the command is +present to make the output more easily parsed. Only adjustable, +breakable inter-word spaces are thus described; those resulting from +\~ or horizontal motion escape sequences are not. GNU +troff issues this command but groff’s output driver +library ignores it. See h and H above. +

+
+ +
+
+
+ +

6.1.2.3 Graphics Commands

+ +

Each graphics or drawing command in the intermediate output starts with +the letter ‘D’, followed by one or two characters that specify a +subcommand; this is followed by a fixed or variable number of integer +arguments that are separated by a single space character. A ‘D’ +command may not be followed by another command on the same line (apart +from a comment), so each ‘D’ command is terminated by a syntactical +line break. +

+

gtroff output follows the classical spacing rules (no space +between command and subcommand, all arguments are preceded by a single +space character), but the parser allows optional space between the +command letters and makes the space before the first argument optional. +As usual, each space can be any sequence of tab and space characters. +

+

Some graphics commands can take a variable number of arguments. In this +case, they are integers representing a size measured in basic units +‘u’. The arguments called h1, h2, …, hn +stand for horizontal distances where positive means right, negative +left. The arguments called v1, v2, …, vn stand +for vertical distances where positive means down, negative up. All +these distances are offsets relative to the current location. +

+

Each graphics command directly corresponds to a similar gtroff +\D escape sequence. See Drawing Geometric Objects. +

+

Unknown ‘D’ commands are assumed to be device-specific. Its +arguments are parsed as strings; the whole information is then sent to +the postprocessor. +

+

In the following command reference, the syntax element ‹line +break› means a syntactical line break as defined above. +

+
+
D~ h1 v1 h2 v2hn vnline break
+

Draw B-spline from current position to offset (h1,v1), then +to offset (h2,v2), if given, etc., up to +(hn,vn). This command takes a variable number of argument +pairs; the current position is moved to the terminal point of the drawn +curve. +

+
+
Da h1 v1 h2 v2line break
+

Draw arc from current position to +(h1,v1)+(h2,v2) with center at +(h1,v1); then move the current position to the final point +of the arc. +

+
+
DC dline break
+
DC d dummy-argline break
+

Draw a solid circle using the current fill color with +diameter d (integer in basic units ‘u’) with leftmost +point at the current position; then move the current position to the +rightmost point of the circle. An optional second integer argument is +ignored (this allows the formatter to generate an even number of +arguments). This command is a gtroff extension. +

+
+
Dc dline break
+

Draw circle line with diameter d (integer in basic units +‘u’) with leftmost point at the current position; then move the +current position to the rightmost point of the circle. +

+
+
DE h vline break
+

Draw a solid ellipse in the current fill color with a horizontal +diameter of h and a vertical diameter of v (both +integers in basic units ‘u’) with the leftmost point at the current +position; then move to the rightmost point of the ellipse. This command +is a gtroff extension. +

+
+
De h vline break
+

Draw an outlined ellipse with a horizontal diameter of h and +a vertical diameter of v (both integers in basic units +‘u’) with the leftmost point at current position; then move to the +rightmost point of the ellipse. +

+
+
DF color-scheme [component]line break
+

Set fill color for solid drawing objects using different color schemes; +the analogous command for setting the color of text, line graphics, and +the outline of graphic objects is ‘m’. The color components are +specified as integer arguments between 0 and 65535. The number of color +components and their meaning vary for the different color schemes. +These commands are generated by gtroff’s escape sequences +‘\D'F …'’ and \M (with no other corresponding +graphics commands). No position changing. This command is a +gtroff extension. +

+
+
DFc cyan magenta yellowline break
+

Set fill color for solid drawing objects using the CMY color scheme, +having the 3 color components cyan, magenta, and +yellow. +

+
+
DFd‹line break
+

Set fill color for solid drawing objects to the default fill color value +(black in most cases). No component arguments. +

+
+
DFg grayline break
+

Set fill color for solid drawing objects to the shade of gray given by +the argument, an integer between 0 (black) and 65535 (white). +

+
+
DFk cyan magenta yellow blackline break
+

Set fill color for solid drawing objects using the CMYK color scheme, +having the 4 color components cyan, magenta, +yellow, and black. +

+
+
DFr red green blueline break
+

Set fill color for solid drawing objects using the RGB color scheme, +having the 3 color components red, green, and +blue. +

+
+ +
+
Df nline break
+

The argument n must be an integer in the range -32767 +to 32767. +

+
+
0 ≤ n ≤ 1000
+

Set the color for filling solid drawing objects to a shade of gray, +where 0 corresponds to solid white, 1000 (the default) to solid black, +and values in between to intermediate shades of gray; this is obsoleted +by command ‘DFg’. +

+
+
n < 0 or n > 1000
+

Set the filling color to the color that is currently being used for the +text and the outline, see command ‘m’. For example, the command +sequence +

+
+
mg 0 0 65535
+Df -1
+
+ +

sets all colors to blue. +

+
+ +

No position changing. This command is a gtroff extension. +

+
+
Dl h vline break
+

Draw line from current position to offset (h,v) (integers in +basic units ‘u’); then set current position to the end of the drawn +line. +

+
+
Dp h1 v1 h2 v2hn vnline break
+

Draw a polygon line from current position to offset (h1,v1), +from there to offset (h2,v2), etc., up to offset +(hn,vn), and from there back to the starting position. For +historical reasons, the position is changed by adding the sum of all +arguments with odd index to the actual horizontal position and the even +ones to the vertical position. Although this doesn’t make sense it is +kept for compatibility. +This command is a gtroff extension. +

+
+
DP h1 v1 h2 v2hn vnline break
+

Draw a solid polygon in the current fill color rather than an outlined +polygon, using the same arguments and positioning as the corresponding +‘Dp’ command. +This command is a gtroff extension. +

+
+
Dt nline break
+

Set the current line thickness to n (an integer in basic +units ‘u’) if n>0; if n=0 select the +smallest available line thickness; if n<0 set the line +thickness proportional to the type size (this is the default before the +first ‘Dt’ command was specified). For historical reasons, the +horizontal position is changed by adding the argument to the actual +horizontal position, while the vertical position is not changed. +Although this doesn’t make sense it is kept for compatibility. +This command is a gtroff extension. +

+
+ +
+
+
+ +

6.1.2.4 Device Control Commands

+ +

Each device control command starts with the letter ‘x’, followed by +a space character (optional or arbitrary space or tab in gtroff) +and a subcommand letter or word; each argument (if any) must be preceded +by a syntactical space. All ‘x’ commands are terminated by a +syntactical line break; no device control command can be followed by +another command on the same line (except a comment). +

+

The subcommand is basically a single letter, but to increase +readability, it can be written as a word, i.e., an arbitrary sequence of +characters terminated by the next tab, space, or newline character. All +characters of the subcommand word but the first are simply ignored. For +example, gtroff outputs the initialization command ‘x i +as ‘x init and the resolution command ‘x r as +‘x res. +

+

In the following, the syntax element ‹line break› means a +syntactical line break (see Separation). +

+
+
xF nameline break
+

The ‘F’ stands for Filename. +

+

Use name as the intended name for the current file in error +reports. This is useful for remembering the original file name when +gtroff uses an internal piping mechanism. The input file is not +changed by this command. This command is a gtroff extension. +

+
+
xf n sline break
+

The ‘f’ stands for font. +

+

Mount font position n (a non-negative integer) with font +named s (a text word). See Font Positions. +

+
+
xH nline break
+

The ‘H’ stands for Height. +

+

Set glyph height to n (a positive integer in scaled points +‘z’). AT&T troff uses the unit points (‘p’) +instead. See Output Language Compatibility. +

+
+
xi‹line break
+

The ‘i’ stands for init. +

+

Initialize device. This is the third command of the prologue. +

+
+
xp‹line break
+

The ‘p’ stands for pause. +

+

Parsed but ignored. The AT&T troff manual documents +this command as +

+
+
pause device, can be restarted
+
+ +

but GNU troff output drivers do nothing with this command. +

+
+
xr n h vline break
+

The ‘r’ stands for resolution. +

+

Resolution is n, while h is the minimal horizontal +motion, and v the minimal vertical motion possible with this +device; all arguments are positive integers in basic units ‘u’ per +inch. This is the second command of the prologue. +

+
+
xS nline break
+

The ‘S’ stands for Slant. +

+

Set slant to n (an integer in basic units ‘u’). +

+
+
xs‹line break
+

The ‘s’ stands for stop. +

+

Terminates the processing of the current file; issued as the last +command of any intermediate troff output. +

+
+
xt‹line break
+

The ‘t’ stands for trailer. +

+

Generate trailer information, if any. In GNU troff, this is +ignored. +

+
+
xT xxxline break
+

The ‘T’ stands for Typesetter. +

+

Set the name of the output driver to xxx, a sequence of +non-whitespace characters terminated by whitespace. The possible names +correspond to those of groff’s -T option. This is the +first command of the prologue. +

+
+
xu nline break
+

The ‘u’ stands for underline. +

+

Configure underlining of spaces. If n is 1, start +underlining of spaces; if n is 0, stop underlining of spaces. +This is needed for the cu request in nroff mode and is +ignored otherwise. This command is a gtroff extension. +

+
+
xX anythingline break
+

The ‘x’ stands for X-escape. +

+

Send string anything uninterpreted to the device. If the line +following this command starts with a ‘+’ character this line is +interpreted as a continuation line in the following sense. The ‘+’ +is ignored, but a newline character is sent instead to the device, the +rest of the line is sent uninterpreted. The same applies to all +following lines until the first character of a line is not a ‘+’ +character. This command is generated by the gtroff escape +sequence \X. The line-continuing feature is a gtroff +extension. +

+
+ +
+
+
+ +

6.1.2.5 Obsolete Command

+

In AT&T troff output, the writing of a single glyph is +mostly done by a very strange command that combines a horizontal move +and a single character giving the glyph name. It doesn’t have a command +code, but is represented by a 3-character argument consisting of exactly +2 digits and a character. +

+
+
ddg
+

Move right dd (exactly two decimal digits) basic units ‘u’, +then print glyph g (represented as a single character). +

+

In GNU troff, arbitrary syntactical space around and within this +command is allowed. Only when a preceding command on the same line ends +with an argument of variable length is a separating space obligatory. +In AT&T troff, large clusters of these and other +commands are used, mostly without spaces; this made such output almost +unreadable. +

+
+ +

For modern high-resolution devices, this command does not make sense +because the width of the glyphs can become much larger than two decimal +digits. In gtroff, this is only used for the devices X75, +X75-12, X100, and X100-12. For other devices, the +commands ‘t’ and ‘u’ provide a better functionality. +

+ +
+
+
+
+ +

6.1.3 Intermediate Output Examples

+ +

This section presents the intermediate output generated from the same +input for three different devices. The input is the sentence ‘hell +world’ fed into gtroff on the command line. +

+
+
High-resolution device ps
+
+

This is the standard output of gtroff if no -T option is +given. +

+
+
shell> echo "hell world" | groff -Z -T ps
+
+x T ps
+x res 72000 1 1
+x init
+
p1
+x font 5 TR
+f5
+s10000
+V12000
+H72000
+thell
+wh2500
+tw
+H96620
+torld
+n12000 0
+
x trailer
+V792000
+x stop
+
+ +

This output can be fed into grops to get its representation as a +PostScript file. +

+
+
Low-resolution device latin1
+
+

This is similar to the high-resolution device except that the +positioning is done at a minor scale. Some comments (lines starting +with ‘#’) were added for clarification; they were not generated by +the formatter. +

+
+
shell> echo "hell world" | groff -Z -T latin1
+
+# prologue
+x T latin1
+x res 240 24 40
+x init
+
# begin a new page
+p1
+# font setup
+x font 1 R
+f1
+s10
+# initial positioning on the page
+V40
+H0
+# write text 'hell'
+thell
+# inform about space, and issue a horizontal jump
+wh24
+# write text 'world'
+tworld
+# announce line break, but do nothing because...
+n40 0
+
# ...the end of the document has been reached
+x trailer
+V2640
+x stop
+
+ +

This output can be fed into grotty to get a formatted text +document. +

+
+
AT&T troff output
+

Since a computer monitor has a much lower resolution than modern +printers, the intermediate output for X11 devices can use the +jump-and-write command with its 2-digit displacements. +

+
+
shell> echo "hell world" | groff -Z -T X100
+
+x T X100
+x res 100 1 1
+x init
+
p1
+x font 5 TR
+f5
+s10
+V16
+H100
+# write text with jump-and-write commands
+ch07e07l03lw06w11o07r05l03dh7
+n16 0
+
x trailer
+V1100
+x stop
+
+ +

This output can be fed into xditview or gxditview for +displaying in X. +

+

Due to the obsolete jump-and-write command, the text clusters in the +AT&T troff output are almost unreadable. +

+
+ + +
+
+
+ +

6.1.4 Output Language Compatibility

+ +

The intermediate output language of AT&T troff was +first documented in A Typesetter-independent TROFF, by Brian +Kernighan, and by 1992 the AT&T troff manual was +updated to incorprate a description of it. +

+

The GNU troff intermediate output format is compatible with this +specification except for the following features. +

+
    +
  • The classical quasi-device independence is not yet implemented. + +
  • The old hardware was very different from what we use today. So the +groff devices are also fundamentally different from the ones +in AT&T troff. For example, the AT&T +PostScript device is called post and has a resolution of only 720 +units per inch, suitable for printers 20 years ago, while groff’s +ps device has a resolution of 72000 units per inch. Maybe, by +implementing some rescaling mechanism similar to the classical +quasi-device independence, groff could emulate AT&T’s +post device. + +
  • The B-spline command ‘D~’ is correctly handled by the intermediate +output parser, but the drawing routines aren’t implemented in some of +the postprocessor programs. + +
  • The argument of the commands ‘s’ and ‘x H has the +implicit unit scaled point ‘z’ in gtroff, while +AT&T troff has point (‘p’). This isn’t an +incompatibility but a compatible extension, for both units coincide for +all devices without a sizescale parameter in the DESC +file, including all postprocessors from AT&T and +groff’s text devices. The few groff devices with a +sizescale parameter either do not exist for AT&T +troff, have a different name, or seem to have a different +resolution. So conflicts are very unlikely. + +
  • The position changing after the commands ‘Dp’, ‘DP’, and +‘Dt’ is illogical, but as old versions of gtroff used this +feature it is kept for compatibility reasons. + + +
+ + + +
+
+
+
+ +

6.2 Device and Font Description Files

+ + + +

The groff font and output device description formats are slight +extensions of those used by AT&T device-independent +troff. In distinction to the AT&T implementation, +groff lacks a binary format; all files are text +files.125 The device and font description files for a device name +are stored in a devname directory. The device description +file is called DESC, and, for each font supported by the device, +a font description file is called f, where +f is usually an abbreviation of a font’s name and/or style. +For example, the ps (PostScript) device has groff font +description files for Times roman (TR) and Zapf Chancery Medium +italic (ZCMI), among many others, while the utf8 device +(for terminal emulators) has only font descriptions for the roman, +italic, bold, and bold-italic styles (R, I, B, and +BI, respectively). +

+

Device and font description files are read both by the formatter, GNU +troff, and by output drivers. The programs delegate these files’ +processing to an internal library, libgroff, ensuring their +consistent interpretation. +

+ + + +
+
+ +

6.2.1 DESC File Format

+ + + + +

The DESC file contains a series of directives; each begins a +line. Their order is not important, with two exceptions: (1) the +res directive must precede any papersize directive; and +(2) the charset directive must come last (if at all). If a +directive name is repeated, later entries in the file override previous +ones (except that the paper dimensions are computed based on the +res directive last seen when papersize is encountered). +Spaces and/or tabs separate words and are ignored at line boundaries. + + + +Comments start with the ‘#’ character and extend to the end of a +line. Empty lines are ignored. +

+
+
family fam
+

The default font family is fam. +

+
+
fonts n F1 Fn
+

Fonts F1, …, Fn are mounted at font positions +m+1, …, m+n where m is the number of +styles (see below). This directive may extend over more than one +line. A font name of 0 causes no font to be mounted at the +corresponding position. +

+
+
hor n
+
+ + + + +

The horizontal motion quantum is n basic units. All +horizontal quantities are rounded to multiples of n. +

+
+
image_generator program
+
+ +

Use program to generate PNG images from PostScript input. Under +GNU/Linux, this is usually gs, but under other systems (notably +Cygwin) it might be set to another name. The grohtml driver uses +this directive. +

+
+
paperlength n
+

The vertical dimension of the output medium is n basic units +(deprecated: use papersize instead). +

+
+
papersize format-or-dimension-pair-or-file-name
+

The dimensions of the output medium are as according to the +argument, which is either a standard paper format, a pair of dimensions, +or the name of a plain text file containing either of the foregoing. +

+

Recognized paper formats are the ISO and DIN formats +A0A7, B0B7, C0C7, +D0D7; the U.S. paper types letter, +legal, tabloid, ledger, statement, and +executive; and the envelope formats com10, monarch, +and DL. Matching is performed without regard for lettercase. +

+

Alternatively, the argument can be a custom paper format in the format +length,width (with no spaces before or after the +comma). Both length and width must have a unit appended; +valid units are ‘i’ for inches, ‘c’ for centimeters, ‘p’ +for points, and ‘P’ for picas. Example: ‘12c,235p’. An +argument that starts with a digit is always treated as a custom paper +format. +

+

Finally, the argument can be a file name (e.g., /etc/papersize); +if the file can be opened, the first line is read and a match attempted +against each of the other forms. No comment syntax is supported. +

+

More than one argument can be specified; +each is scanned in turn and the first valid paper specification used. +

+
+
paperwidth n
+

The horizontal dimension of the output medium is n basic +units (deprecated: use papersize instead). +

+
+
pass_filenames
+

Direct GNU troff to emit the name of the source file being +processed. This is achieved with the intermediate output command +‘x F’, which grohtml interprets. +

+
+
postpro program
+

Use program as the postprocessor. +

+
+
prepro program
+

Use program as a preprocessor. The html and xhtml +output devices use this directive. +

+
+
print program
+

Use program as a spooler program for printing. If omitted, the +-l and -L options of groff are ignored. +

+
+
res n
+
+ +

The device resolution is n basic units per inch. +

+
+
sizes s1 sn 0
+

The device has fonts at s1, …, sn scaled points (see +below). The list of sizes must be terminated by 0. Each +si can also be a range of sizes mn. The list can +extend over more than one line. +

+
+
sizescale n
+

A typographical point is subdivided into n scaled points. +The default is 1. See Using Fractional Type Sizes. +

+
+
styles S1 Sm
+

The first m mounting positions are associated with styles +S1, …, Sm. +

+
+
tcommand
+

The postprocessor can handle the ‘t’ and ‘u’ intermediate +output commands. +

+
+
unicode
+

The output device supports the complete Unicode repertoire. This +directive is useful only for devices that produce character entities +instead of glyphs. +

+

If unicode is present, no charset section is required in +the font description files since the Unicode handling built into +groff is used. However, if there are entries in a font +description file’s charset section, they either override the +default mappings for those particular characters or add new mappings +(normally for composite characters). +

+

The utf8, html, and xhtml output devices use this +directive. +

+
+
unitwidth n
+

Quantities in the font description files are in basic units for fonts +whose type size is n scaled points. +

+
+
unscaled_charwidths
+

Make the font handling module always return unscaled character widths. +The grohtml driver uses this directive. +

+
+
use_charnames_in_special
+

GNU troff should encode special characters inside device control +commands; see Postprocessor Access. The grohtml driver +uses this directive. +

+
+
vert n
+
+ + + + +

The vertical motion quantum is n basic units. All vertical +quantities are rounded to multiples of n. +

+
+
charset
+

This line and everything following it in the file are ignored. It is +recognized for compatibility with other troff implementations. +In GNU troff, character set repertoire is described on a +per-font basis. +

+
+ + + + +

GNU troff recognizes but ignores the directives spare1, +spare2, and biggestfont. +

+

The res, unitwidth, fonts, and sizes lines +are mandatory. Directives not listed above are ignored by GNU +troff but may be used by postprocessors to obtain further +information about the device. +

+ +
+
+
+ +

6.2.2 Font Description File Format

+ + + + + +

On typesetting output devices, each font is typically available at +multiple sizes. While paper measurements in the device description file +are in absolute units, measurements applicable to fonts must be +proportional to the type size. groff achieves this using the +precedent set by AT&T device-independent troff: one +font size is chosen as a norm, and all others are scaled linearly +relative to that basis. The “unit width” is the number of basic units +per point when the font is rendered at this nominal size. +

+

For instance, groff’s lbp device uses a unitwidth +of 800. Its Times roman font ‘TR’ has a spacewidth +of 833; this is also the width of its comma, period, centered +period, and mathematical asterisk, while its ‘M’ is 2,963 basic +units. Thus, an ‘M’ on the lbp device is 2,963 basic units +wide at a notional type size of 800 points.126 +

+

A font description file has two sections. The first is a sequence of +directives, and is parsed similarly to the DESC file described +above. Except for the directive names that begin the second section, +their ordering is immaterial. Later directives of the same name +override earlier ones, spaces and tabs are handled in the same way, + + + +and the same comment syntax is supported. Empty lines are ignored +throughout. +

+
+
name f
+

The name of the font is f. ‘DESC’ is an invalid font +name. Simple integers are valid, but their use is +discouraged.127 +

+
+
spacewidth n
+

The width of an unadjusted inter-word space is n basic units. +

+
+ +

The directives above must appear in the first section; those below are +optional. +

+
+
slant n
+

The font’s glyphs have a slant of n degrees; a positive +n slants in the direction of text flow. +

+
+
ligatures lig1 lign [0]
+

Glyphs lig1, …, lign are ligatures; possible ligatures +are ‘ff’, ‘fi’, ‘fl’, ‘ffi’ and ‘ffl’. For +compatibility with other troff implementations, the list of +ligatures may be terminated with a 0. The list of ligatures +must not extend over more than one line. +

+
+
special
+
+

The font is special: when a glyph is requested that is not present +in the current font, it is sought in any mounted fonts that bear this +property. +

+
+ +

Other directives in this section are ignored by GNU troff, but +may be used by postprocessors to obtain further information about the +font. +

+

The second section contains one or two subsections. These can appear in +either order; the first one encountered commences the second section. +Each starts with a directive on a line by itself. A charset +subsection is mandatory unless the associated DESC file contains +the unicode directive. Another subsection, kernpairs, +is optional. +

+ +

The directive charset starts the character set +subsection.128 It precedes a series +of glyph descriptions, one per line. Each such glyph description +comprises a set of fields separated by spaces or tabs and organized as +follows. +

+
+

name metrics type code [entity-name] +[-- comment] +

+ + + + + + + + +

name identifies the glyph: +if name is a printable character c, it corresponds to +the troff ordinary character c. If name is a +multi-character sequence not beginning with \, it corresponds to +the GNU troff special character escape sequence +‘\[name]’. A name consisting of three minus signs, +‘---’, is special and indicates that the glyph is unnamed: such +glyphs can be accessed only by the \N escape sequence in +troff. A special character named ‘---’ can still be defined +using char and similar requests. The name\-’ +defines the minus sign glyph. Finally, name can be the +unbreakable one-sixth and one-twelfth space escape sequences, \| +and \^ (“thin” and “hair” spaces, respectively), in which +case only the width metric described below is interpreted; a font can +thus customize the widths of these spaces. +

+

The form of the metrics field is as follows. +

+
+
width[,[height[,[depth[,[italic-correction
+  [,[left-italic-correction[,[subscript-correction]]]]]]]]]]
+
+ +

There must not be any spaces, tabs, or newlines between these +subfields (which have been split here into two lines only for +better legibility). The subfields are in basic units expressed as +decimal integers. Unspecified subfields default to 0. +Since there is no associated binary format, these values are not +required to fit into the C language data type ‘char’ as they are in +AT&T device-independent troff. +

+

The width subfield gives the width of the glyph. The height +subfield gives the height of the glyph (upward is positive); if a glyph +does not extend above the baseline, it should be given a zero height, +rather than a negative height. The depth subfield gives the depth +of the glyph, that is, the distance below the baseline to which the +glyph extends (downward is positive); if a glyph does not extend below +the baseline, it should be given a zero depth, rather than a negative +depth. Italic corrections are relevant to glyphs in italic or oblique +styles. The italic-correction is the amount of space that should +be added after an oblique glyph to be followed immediately by an upright +glyph. The left-italic-correction is the amount of space that +should be added before an oblique glyph to be preceded immediately by an +upright glyph. The subscript-correction is the amount of space +that should be added after an oblique glyph to be followed by a +subscript; it should be less than the italic correction. +

+

For fonts used with typesetting devices, the type field gives a +featural description of the glyph: it is a bit mask recording whether +the glyph is an ascender, descender, both, or neither. When a \w +escape sequence is interpolated, these values are bitwise or-ed +together for each glyph and stored in the nr register. In font +descriptions for terminal devices, all glyphs might have a type of zero, +regardless of their appearance. +

+
+
0
+

means the glyph lies entirely between the baseline and a horizontal line +at the “x-height” of the font; typical examples are ‘a’, +‘c’, and ‘x’; +

+
+
1
+

means the glyph descends below the baseline, like ‘p’; +

+
+
2
+

means the glyph ascends above the font’s x-height, like ‘A’ or +‘b’; and +

+
+
3
+

means the glyph is both an ascender and a descender—this is true of +parentheses in some fonts. +

+
+ +

The code field gives a numeric identifier that the postprocessor +uses to render the glyph. The glyph can be specified to troff +using this code by means of the \N escape sequence. code +can be any integer.129 +

+

The entity-name field defines an identifier for the glyph that the +postprocessor uses to print the GNU troff glyph name. This +field is optional; it was introduced so that the grohtml output +driver could encode its character set. For example, the glyph +‘\[Po]’ is represented by ‘&pound;’ in HTML 4.0. +For efficiency, these data are now compiled directly into +grohtml. grops uses the field to build sub-encoding +arrays for PostScript fonts containing more than 256 glyphs. Anything +on the line after the entity-name field or ‘--’ is ignored. +

+

A line in the charset section can also have the form +

+
+
name "
+
+ +

identifying name as another name for the glyph mentioned in the +preceding line. Such aliases can be chained. +

+ +

The directive kernpairs starts a list of kerning adjustments to +be made to adjacent glyph pairs from this font. It contains a sequence +of lines formatted as follows. +

+
+
g1 g2 n
+
+ +

The foregoing means that when glyph g1 is typeset immediately +before g2, the space between them should be increased +by n. Most kerning pairs should have a negative value +for n. +

+ + + + +
+
+
+
+
+ +

Appendix A Copying This Manual

+ +
Version 1.3, 3 November 2008 +
+ +
+
Copyright © 2000-2018 Free Software Foundation, Inc.
+http://fsf.org/
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+ +
    +
  1. PREAMBLE + +

    The purpose of this License is to make a manual, textbook, or other +functional and useful document free in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. +

    +

    This License is a kind of “copyleft”, which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. +

    +

    We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. +

    +
  2. APPLICABILITY AND DEFINITIONS + +

    This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The “Document”, below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as “you”. You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. +

    +

    A “Modified Version” of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. +

    +

    A “Secondary Section” is a named appendix or a front-matter section +of the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document’s overall +subject (or to related matters) and contains nothing that could fall +directly within that overall subject. (Thus, if the Document is in +part a textbook of mathematics, a Secondary Section may not explain +any mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. +

    +

    The “Invariant Sections” are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. +

    +

    The “Cover Texts” are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. +

    +

    A “Transparent” copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not “Transparent” is called “Opaque”. +

    +

    Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input +format, SGML or XML using a publicly available +DTD, and standard-conforming simple HTML, +PostScript or PDF designed for human modification. Examples +of transparent image formats include PNG, XCF and +JPG. Opaque formats include proprietary formats that can be +read and edited only by proprietary word processors, SGML or +XML for which the DTD and/or processing tools are +not generally available, and the machine-generated HTML, +PostScript or PDF produced by some word processors for +output purposes only. +

    +

    The “Title Page” means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, “Title Page” means +the text near the most prominent appearance of the work’s title, +preceding the beginning of the body of the text. +

    +

    The “publisher” means any person or entity that distributes copies +of the Document to the public. +

    +

    A section “Entitled XYZ” means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as “Acknowledgements”, +“Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” +of such a section when you modify the Document means that it remains a +section “Entitled XYZ” according to this definition. +

    +

    The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. +

    +
  3. VERBATIM COPYING + +

    You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. +

    +

    You may also lend copies, under the same conditions stated above, and +you may publicly display copies. +

    +
  4. COPYING IN QUANTITY + +

    If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document’s license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. +

    +

    If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. +

    +

    If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. +

    +

    It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. +

    +
  5. MODIFICATIONS + +

    You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: +

    +
      +
    1. Use in the Title Page (and on the covers, if any) a title distinct +from that of the Document, and from those of previous versions +(which should, if there were any, be listed in the History section +of the Document). You may use the same title as a previous version +if the original publisher of that version gives permission. + +
    2. List on the Title Page, as authors, one or more persons or entities +responsible for authorship of the modifications in the Modified +Version, together with at least five of the principal authors of the +Document (all of its principal authors, if it has fewer than five), +unless they release you from this requirement. + +
    3. State on the Title page the name of the publisher of the +Modified Version, as the publisher. + +
    4. Preserve all the copyright notices of the Document. + +
    5. Add an appropriate copyright notice for your modifications +adjacent to the other copyright notices. + +
    6. Include, immediately after the copyright notices, a license notice +giving the public permission to use the Modified Version under the +terms of this License, in the form shown in the Addendum below. + +
    7. Preserve in that license notice the full lists of Invariant Sections +and required Cover Texts given in the Document’s license notice. + +
    8. Include an unaltered copy of this License. + +
    9. Preserve the section Entitled “History”, Preserve its Title, and add +to it an item stating at least the title, year, new authors, and +publisher of the Modified Version as given on the Title Page. If +there is no section Entitled “History” in the Document, create one +stating the title, year, authors, and publisher of the Document as +given on its Title Page, then add an item describing the Modified +Version as stated in the previous sentence. + +
    10. Preserve the network location, if any, given in the Document for +public access to a Transparent copy of the Document, and likewise +the network locations given in the Document for previous versions +it was based on. These may be placed in the “History” section. +You may omit a network location for a work that was published at +least four years before the Document itself, or if the original +publisher of the version it refers to gives permission. + +
    11. For any section Entitled “Acknowledgements” or “Dedications”, Preserve +the Title of the section, and preserve in the section all the +substance and tone of each of the contributor acknowledgements and/or +dedications given therein. + +
    12. Preserve all the Invariant Sections of the Document, +unaltered in their text and in their titles. Section numbers +or the equivalent are not considered part of the section titles. + +
    13. Delete any section Entitled “Endorsements”. Such a section +may not be included in the Modified Version. + +
    14. Do not retitle any existing section to be Entitled “Endorsements” or +to conflict in title with any Invariant Section. + +
    15. Preserve any Warranty Disclaimers. +
    + +

    If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version’s license notice. +These titles must be distinct from any other section titles. +

    +

    You may add a section Entitled “Endorsements”, provided it contains +nothing but endorsements of your Modified Version by various +parties—for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. +

    +

    You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. +

    +

    The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. +

    +
  6. COMBINING DOCUMENTS + +

    You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. +

    +

    The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. +

    +

    In the combination, you must combine any sections Entitled “History” +in the various original documents, forming one section Entitled +“History”; likewise combine any sections Entitled “Acknowledgements”, +and any sections Entitled “Dedications”. You must delete all +sections Entitled “Endorsements.” +

    +
  7. COLLECTIONS OF DOCUMENTS + +

    You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. +

    +

    You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. +

    +
  8. AGGREGATION WITH INDEPENDENT WORKS + +

    A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an “aggregate” if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation’s users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. +

    +

    If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document’s Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. +

    +
  9. TRANSLATION + +

    Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. +

    +

    If a section in the Document is Entitled “Acknowledgements”, +“Dedications”, or “History”, the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. +

    +
  10. TERMINATION + +

    You may not copy, modify, sublicense, or distribute the Document +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense, or distribute it is void, and +will automatically terminate your rights under this License. +

    +

    However, if you cease all violation of this License, then your license +from a particular copyright holder is reinstated (a) provisionally, +unless and until the copyright holder explicitly and finally +terminates your license, and (b) permanently, if the copyright holder +fails to notify you of the violation by some reasonable means prior to +60 days after the cessation. +

    +

    Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. +

    +

    Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, receipt of a copy of some or all of the same material does +not give you any rights to use it. +

    +
  11. FUTURE REVISIONS OF THIS LICENSE + +

    The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +http://www.gnu.org/copyleft/. +

    +

    Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License “or any later version” applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. If the Document +specifies that a proxy can decide which future versions of this +License can be used, that proxy’s public statement of acceptance of a +version permanently authorizes you to choose that version for the +Document. +

    +
  12. RELICENSING + +

    “Massive Multiauthor Collaboration Site” (or “MMC Site”) means any +World Wide Web server that publishes copyrightable works and also +provides prominent facilities for anybody to edit those works. A +public wiki that anybody can edit is an example of such a server. A +“Massive Multiauthor Collaboration” (or “MMC”) contained in the +site means any set of copyrightable works thus published on the MMC +site. +

    +

    “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 +license published by Creative Commons Corporation, a not-for-profit +corporation with a principal place of business in San Francisco, +California, as well as future copyleft versions of that license +published by that same organization. +

    +

    “Incorporate” means to publish or republish a Document, in whole or +in part, as part of another Document. +

    +

    An MMC is “eligible for relicensing” if it is licensed under this +License, and if all works that were first published under this License +somewhere other than this MMC, and subsequently incorporated in whole +or in part into the MMC, (1) had no cover texts or invariant sections, +and (2) were thus incorporated prior to November 1, 2008. +

    +

    The operator of an MMC Site may republish an MMC contained in the site +under CC-BY-SA on the same site at any time before August 1, 2009, +provided the MMC is eligible for relicensing. +

    +
+ +

ADDENDUM: How to use this License for your documents

+ +

To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: +

+
+
  Copyright (C)  year  your name.
+  Permission is granted to copy, distribute and/or modify this document
+  under the terms of the GNU Free Documentation License, Version 1.3
+  or any later version published by the Free Software Foundation;
+  with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+  Texts.  A copy of the license is included in the section entitled ``GNU
+  Free Documentation License''.
+
+ +

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the “with…Texts.” line with this: +

+
+
    with the Invariant Sections being list their titles, with
+    the Front-Cover Texts being list, and with the Back-Cover Texts
+    being list.
+
+ +

If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. +

+

If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. +

+ + + + + +
+
+
+ +

Appendix B Request Index

+ +

Request names appear without a leading control character; the defaults +are . for the regular control character and ' for the +no-break control character. +

+
+
Jump to:   A +   +B +   +C +   +D +   +E +   +F +   +G +   +H +   +I +   +K +   +L +   +M +   +N +   +O +   +P +   +R +   +S +   +T +   +U +   +V +   +W +   +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

A
ab: Debugging
ad: Manipulating Filling and Adjustment
af: Assigning Register Formats
aln: Setting Registers
als: Strings
am: Writing Macros
am1: Writing Macros
ami: Writing Macros
ami1: Writing Macros
as: Strings
as1: Strings
asciify: Diversions

B
backtrace: Debugging
bd: Artificial Fonts
blm: Blank Line Traps
box: Diversions
boxa: Diversions
bp: Page Control
br: Manipulating Filling and Adjustment
break: while
brp: Manipulating Filling and Adjustment

C
c2: Control Characters
cc: Control Characters
ce: Manipulating Filling and Adjustment
cf: I/O
cflags: Using Symbols
ch: Page Location Traps
char: Using Symbols
chop: Strings
class: Character Classes
close: I/O
color: Colors
composite: Using Symbols
continue: while
cp: Compatibility Mode
cs: Artificial Fonts
cu: Artificial Fonts

D
da: Diversions
de: Writing Macros
de1: Writing Macros
defcolor: Colors
dei: Writing Macros
dei1: Writing Macros
device: Postprocessor Access
devicem: Postprocessor Access
di: Diversions
do: Compatibility Mode
ds: ms Document Control Settings
ds: Strings
ds1: Strings
dt: Diversion Traps

E
ec: Using Escape Sequences
ecr: Using Escape Sequences
ecs: Using Escape Sequences
el: if-else
em: End-of-input Traps
eo: Using Escape Sequences
ev: Environments
evc: Environments
ex: Debugging

F
fam: Font Families
fc: Fields
fchar: Using Symbols
fcolor: Colors
fi: Manipulating Filling and Adjustment
fl: Debugging
fp: Font Positions
fschar: Using Symbols
fspecial: Special Fonts
ft: Selecting Fonts
ftr: Selecting Fonts
fzoom: Selecting Fonts

G
gcolor: Colors

H
hc: Manipulating Hyphenation
hcode: Manipulating Hyphenation
hla: Manipulating Hyphenation
hlm: Manipulating Hyphenation
hpf: Manipulating Hyphenation
hpfa: Manipulating Hyphenation
hpfcode: Manipulating Hyphenation
hw: Manipulating Hyphenation
hy: Manipulating Hyphenation
hym: Manipulating Hyphenation
hys: Manipulating Hyphenation

I
ie: if-else
if: if-then
ig: Comments
in: Line Layout
it: Input Line Traps
itc: Input Line Traps

K
kern: Ligatures and Kerning

L
lc: Leaders
length: Strings
lf: Debugging
lg: Ligatures and Kerning
linetabs: Tabs and Fields
ll: Line Layout
ls: Manipulating Spacing
lsm: Leading Space Traps
lt: Page Layout

M
mc: Miscellaneous
mk: Page Motions
mso: I/O
msoquiet: I/O

N
na: Manipulating Filling and Adjustment
ne: Page Control
nf: Manipulating Filling and Adjustment
nh: Manipulating Hyphenation
nm: Miscellaneous
nn: Miscellaneous
nop: if-then
nr: ms Document Control Settings
nr: Setting Registers
nr: Setting Registers
nr: Auto-increment
nroff: troff and nroff Modes
ns: Manipulating Spacing
nx: I/O

O
open: I/O
opena: I/O
os: Page Control
output: Diversions

P
pc: Page Layout
pev: Debugging
pi: I/O
pl: Page Layout
pm: Debugging
pn: Page Layout
pnr: Debugging
po: Line Layout
ps: Changing the Type Size
psbb: Miscellaneous
pso: I/O
ptr: Debugging
pvs: Changing the Vertical Spacing

R
rchar: Using Symbols
rd: I/O
return: Writing Macros
rfschar: Using Symbols
rj: Manipulating Filling and Adjustment
rm: Strings
rn: Strings
rnn: Setting Registers
rr: Setting Registers
rs: Manipulating Spacing
rt: Page Motions

S
schar: Using Symbols
shc: Manipulating Hyphenation
shift: Parameters
sizes: Changing the Type Size
so: I/O
soquiet: I/O
sp: Manipulating Spacing
special: Special Fonts
spreadwarn: Debugging
ss: Manipulating Filling and Adjustment
stringdown: Strings
stringup: Strings
sty: Font Families
substring: Strings
sv: Page Control
sy: I/O

T
ta: Tabs and Fields
tag: Postprocessor Access
taga: Postprocessor Access
tc: Tabs and Fields
ti: Line Layout
tkf: Ligatures and Kerning
tl: Page Layout
tm: Debugging
tm1: Debugging
tmc: Debugging
tr: Character Translations
trf: I/O
trin: Character Translations
trnt: Character Translations
troff: troff and nroff Modes

U
uf: Artificial Fonts
ul: Artificial Fonts
unformat: Diversions

V
vpt: Vertical Position Traps
vs: Changing the Vertical Spacing

W
warn: Debugging
warnscale: Debugging
wh: Page Location Traps
while: while
write: I/O
writec: I/O
writem: I/O

+ +
+ + + + +
+
+
+ +

Appendix C Escape Sequence Index

+ +

The escape character, \ by default, is always followed by at +least one more input character, making an escape sequence. Any +input token \X with X not in the list below emits a +warning and interpolates glyph X. Note the entries for \., +which may be obscured by the leader dots, and for \RET and +\SP, which are sorted alphabetically, not by code point +order. +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

\
\: Using Escape Sequences
\: Using Symbols
\!: Diversions
\": Comments
\#: Comments
\$: Parameters
\$*: Parameters
\$0: Parameters
\$@: Parameters
\$^: Parameters
\%: Manipulating Hyphenation
\&: Dummy Characters
\': Using Symbols
\(: Using Symbols
\): Dummy Characters
\*: Strings
\,: Italic Corrections
\-: Using Symbols
\.: Copy Mode
\/: Italic Corrections
\0: Page Motions
\:: Manipulating Hyphenation
\?: Diversions
\A: Identifiers
\a: Leaders
\B: Numeric Expressions
\b: Drawing Geometric Objects
\c: Line Continuation
\C: Using Symbols
\d: Page Motions
\D: Drawing Geometric Objects
\e: Using Escape Sequences
\E: Copy Mode
\f: Selecting Fonts
\F: Font Families
\g: Assigning Register Formats
\H: Artificial Fonts
\h: Page Motions
\k: Page Motions
\l: Drawing Geometric Objects
\L: Drawing Geometric Objects
\m: Colors
\M: Colors
\n: Interpolating Registers
\n: Auto-increment
\N: Using Symbols
\newline: Line Continuation
\o: Page Motions
\O: Suppressing Output
\p: Manipulating Filling and Adjustment
\R: Setting Registers
\R: Setting Registers
\r: Page Motions
\RET: Line Continuation
\S: Artificial Fonts
\s: Changing the Type Size
\SP: Page Motions
\space: Page Motions
\t: Tabs and Fields
\u: Page Motions
\v: Page Motions
\V: I/O
\w: Page Motions
\x: Manipulating Spacing
\X: Postprocessor Access
\Y: Postprocessor Access
\z: Page Motions
\Z: Page Motions
\[: Using Symbols
\\: Copy Mode
\^: Page Motions
\_: Using Symbols
\`: Using Symbols
\{: Conditional Blocks
\{: Conditional Blocks
\|: Page Motions
\}: Conditional Blocks
\~: Manipulating Filling and Adjustment

+
+ + + + +
+
+
+ +

Appendix D Operator Index

+ +
+
Jump to:   ! +   +% +   +& +   +( +   +) +   +* +   ++ +   +- +   +/ +   +: +   +; +   +< +   += +   +> +   +| +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

!
!: Numeric Expressions

%
%: Numeric Expressions

&
&: Numeric Expressions

(
(: Numeric Expressions

)
): Numeric Expressions

*
*: Numeric Expressions

+
+: Numeric Expressions
+: Numeric Expressions
+ (unary): Numeric Expressions

-
-: Numeric Expressions
-: Numeric Expressions
- (unary): Numeric Expressions

/
/: Numeric Expressions

:
:: Numeric Expressions

;
;: Numeric Expressions

<
<: Numeric Expressions
<=: Numeric Expressions
<?: Numeric Expressions

=
=: Numeric Expressions
==: Numeric Expressions

>
>: Numeric Expressions
>=: Numeric Expressions
>?: Numeric Expressions

|
|: Numeric Expressions

+ +
+ + + + +
+
+
+ +

Appendix E Register Index

+ +

The macro package or program a specific register belongs to is appended +in brackets. +

+

A register name x consisting of exactly one character can be +accessed as ‘\nx’. A register name xx consisting of exactly +two characters can be accessed as ‘\n(xx’. Register names +xxx of any length can be accessed as ‘\n[xxx]’. +

+
+
Jump to:   $ +   +% +   +. +   +
+C +   +D +   +F +   +G +   +H +   +L +   +M +   +N +   +O +   +P +   +Q +   +R +   +S +   +T +   +U +   +V +   +Y +   +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

$
$$: Built-in Registers

%
%: Page Layout
%: Page Control

.
.$: Parameters
.A: Built-in Registers
.a: Manipulating Spacing
.b: Artificial Fonts
.br: Control Characters
.c: Built-in Registers
.C: Compatibility Mode
.cdp: Environments
.ce: Manipulating Filling and Adjustment
.cht: Environments
.color: Colors
.cp: Compatibility Mode
.csk: Environments
.d: Diversions
.ev: Environments
.F: Built-in Registers
.f: Font Positions
.fam: Font Families
.fn: Selecting Fonts
.fp: Font Positions
.g: Built-in Registers
.H: Motion Quanta
.h: Diversions
.height: Artificial Fonts
.hla: Manipulating Hyphenation
.hlc: Manipulating Hyphenation
.hlm: Manipulating Hyphenation
.hy: Manipulating Hyphenation
.hym: Manipulating Hyphenation
.hys: Manipulating Hyphenation
.i: Line Layout
.in: Line Layout
.int: Line Continuation
.j: Manipulating Filling and Adjustment
.k: Page Motions
.kern: Ligatures and Kerning
.L: Manipulating Spacing
.l: Line Layout
.lg: Ligatures and Kerning
.linetabs: Tabs and Fields
.ll: Line Layout
.lt: Page Layout
.m: Colors
.M: Colors
.n: Environments
.ne: Page Location Traps
.nm: Miscellaneous
.nn: Miscellaneous
.ns: Manipulating Spacing
.o: Line Layout
.O: Suppressing Output
.P: Built-in Registers
.p: Page Layout
.pe: Page Location Traps
.pn: Page Layout
.ps: Using Fractional Type Sizes
.psr: Using Fractional Type Sizes
.pvs: Changing the Vertical Spacing
.R: Built-in Registers
.rj: Manipulating Filling and Adjustment
.s: Changing the Type Size
.slant: Artificial Fonts
.sr: Using Fractional Type Sizes
.ss: Manipulating Filling and Adjustment
.sss: Manipulating Filling and Adjustment
.sty: Font Families
.T: Built-in Registers
.t: Page Location Traps
.tabs: Tabs and Fields
.trunc: Page Location Traps
.U: Built-in Registers
.u: Manipulating Filling and Adjustment
.V: Motion Quanta
.v: Changing the Vertical Spacing
.vpt: Vertical Position Traps
.w: Environments
.warn: Debugging
.x: Built-in Registers
.y: Built-in Registers
.Y: Built-in Registers
.z: Diversions
.zoom: Selecting Fonts

C
c.: Built-in Registers
ct: Page Motions

D
DD [ms]: ms Document Control Settings
DI [ms]: ms Document Control Settings
dl: Diversions
dn: Diversions
dw: Built-in Registers
dy: Built-in Registers

F
FF [ms]: ms Document Control Settings
FI [ms]: ms Document Control Settings
FM [ms]: ms Document Control Settings
FPD [ms]: ms Document Control Settings
FPS [ms]: ms Document Control Settings
FVS [ms]: ms Document Control Settings

G
GROWPS [ms]: ms Document Control Settings
GS [ms]: Differences from AT&T ms

H
HM [ms]: ms Document Control Settings
HORPHANS [ms]: ms Document Control Settings
hours: Built-in Registers
hp: Page Motions
HY [ms]: ms Document Control Settings

L
LL [ms]: ms Document Control Settings
llx: Miscellaneous
lly: Miscellaneous
ln: Miscellaneous
lsn: Leading Space Traps
lss: Leading Space Traps
LT [ms]: ms Document Control Settings

M
MINGW [ms]: ms Document Control Settings
minutes: Built-in Registers
mo: Built-in Registers

N
nl: Page Control

O
opmaxx: Suppressing Output
opmaxy: Suppressing Output
opminx: Suppressing Output
opminy: Suppressing Output

P
PD [ms]: ms Document Control Settings
PI [ms]: ms Document Control Settings
PO [ms]: ms Document Control Settings
PORPHANS [ms]: ms Document Control Settings
PS [ms]: ms Document Control Settings
PSINCR [ms]: ms Document Control Settings

Q
QI [ms]: ms Document Control Settings

R
rsb: Page Motions
rst: Page Motions

S
sb: Page Motions
seconds: Built-in Registers
skw: Page Motions
slimit: Debugging
ssc: Page Motions
st: Page Motions
systat: I/O

T
TC-MARGIN [ms]: ms Document Control Settings

U
urx: Miscellaneous
ury: Miscellaneous

V
VS [ms]: ms Document Control Settings

Y
year: Built-in Registers
yr: Built-in Registers

+ +
+ + + + +
+
+
+ +

Appendix F Macro Index

+ +

The macro package a specific macro belongs to is appended in brackets. +They appear without the leading control character (normally ‘.’). +

+
+
Jump to:   1 +   +2 +   +[ +   +] +   +
+A +   +B +   +C +   +D +   +E +   +F +   +G +   +H +   +I +   +K +   +L +   +M +   +N +   +O +   +P +   +Q +   +R +   +S +   +T +   +U +   +V +   +X +   +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

1
1C [ms]: ms Multiple Columns

2
2C [ms]: ms Multiple Columns

[
[ [ms]: ms Insertions

]
] [ms]: ms Insertions

A
AB [ms]: ms Document Description Macros
AE [ms]: ms Document Description Macros
AI [ms]: ms Document Description Macros
AM [ms]: ms Legacy Features
AU [ms]: ms Document Description Macros

B
B [ms]: Typeface and decoration
B1 [ms]: ms keeps and displays
B2 [ms]: ms keeps and displays
BD [ms]: ms keeps and displays
BI [ms]: Typeface and decoration
BT [man]: Optional man extensions
BX [ms]: Typeface and decoration

C
CD [ms]: ms keeps and displays
CT [man]: Optional man extensions
CW [man]: Optional man extensions
CW [ms]: Typeface and decoration

D
DA [ms]: ms Document Description Macros
De [man]: Optional man extensions
DE [ms]: ms keeps and displays
Ds [man]: Optional man extensions
DS [ms]: ms keeps and displays
DS [ms]: ms keeps and displays
DS [ms]: ms keeps and displays
DS [ms]: ms keeps and displays
DS [ms]: ms keeps and displays

E
EE [man]: Optional man extensions
EF [ms]: ms Headers and Footers
EH [ms]: ms Headers and Footers
EN [ms]: ms Insertions
EQ [ms]: ms Insertions
EX [man]: Optional man extensions

F
FE [ms]: ms Footnotes
FS [ms]: ms Footnotes

G
G [man]: Optional man extensions
GL [man]: Optional man extensions

H
HB [man]: Optional man extensions

I
I [ms]: Typeface and decoration
ID [ms]: ms keeps and displays
IP [ms]: Paragraphs in ms

K
KE [ms]: ms keeps and displays
KF [ms]: ms keeps and displays
KS [ms]: ms keeps and displays

L
LD [ms]: ms keeps and displays
LG [ms]: Typeface and decoration
LP [ms]: Paragraphs in ms

M
MC [ms]: ms Multiple Columns
MS [man]: Optional man extensions

N
ND [ms]: ms Document Description Macros
NE [man]: Optional man extensions
NH [ms]: Headings in ms
NL [ms]: Typeface and decoration
NT [man]: Optional man extensions

O
OF [ms]: ms Headers and Footers
OH [ms]: ms Headers and Footers

P
P1 [ms]: ms Headers and Footers
PE [ms]: ms Insertions
PF [ms]: ms Insertions
PN [man]: Optional man extensions
Pn [man]: Optional man extensions
PP [ms]: Paragraphs in ms
PS [ms]: ms Insertions
PT [man]: Optional man extensions
PX [ms]: ms TOC

Q
QE [ms]: Paragraphs in ms
QP [ms]: Paragraphs in ms
QS [ms]: Paragraphs in ms

R
R [man]: Optional man extensions
R [ms]: Typeface and decoration
RD [ms]: ms keeps and displays
RE [ms]: Indented regions in ms
RN [man]: Optional man extensions
RP [ms]: ms Document Description Macros
RS [ms]: Indented regions in ms

S
SH [ms]: Headings in ms
SM [ms]: Typeface and decoration

T
TA [ms]: Tab Stops in ms
TB [man]: Optional man extensions
TC [ms]: ms TOC
TE [ms]: ms Insertions
TL [ms]: ms Document Description Macros
TS [ms]: ms Insertions

U
UL [ms]: Typeface and decoration

V
VE [man]: Optional man extensions
VS [man]: Optional man extensions

X
XA [ms]: ms TOC
XE [ms]: ms TOC
XH [ms]: ms TOC
XH-REPLACEMENT [ms]: ms TOC
XH-UPDATE-TOC [ms]: ms TOC
XN [ms]: ms TOC
XN-INIT [ms]: ms TOC
XN-REPLACEMENT [ms]: ms TOC
XP [ms]: Paragraphs in ms
XS [ms]: ms TOC

+ +
+ + + + +
+
+
+ +

Appendix G String Index

+ +

The macro package or program a that defines or uses each string is +appended in brackets. (Only one string, .T, is defined by the +troff formatter itself.) See Strings. +

+ +
+
Jump to:   ! +   +' +   +* +   +, +   +- +   +. +   +/ +   +3 +   +8 +   +: +   +< +   +> +   +? +   +^ +   +_ +   +` +   +{ +   +} +   +~ +   +
+A +   +C +   +D +   +F +   +L +   +M +   +O +   +Q +   +R +   +S +   +T +   +U +   +V +   +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

!
! [ms]: ms Legacy Features

'
' [ms]: ms Legacy Features
' [ms]: ms Legacy Features

*
* [ms]: ms Footnotes

,
, [ms]: ms Legacy Features
, [ms]: ms Legacy Features

-
- [ms]: Typographical symbols in ms

.
. [ms]: ms Legacy Features
.T: Strings
.T: Strings

/
/ [ms]: ms Legacy Features

3
3 [ms]: ms Legacy Features

8
8 [ms]: ms Legacy Features

:
: [ms]: ms Legacy Features
: [ms]: ms Legacy Features

<
< [ms]: Typeface and decoration

>
> [ms]: Typeface and decoration

?
? [ms]: ms Legacy Features

^
^ [ms]: ms Legacy Features
^ [ms]: ms Legacy Features

_
_ [ms]: ms Legacy Features

`
` [ms]: ms Legacy Features
` [ms]: ms Legacy Features

{
{ [ms]: Typeface and decoration

}
} [ms]: Typeface and decoration

~
~ [ms]: ms Legacy Features
~ [ms]: ms Legacy Features

A
ABSTRACT [ms]: ms language and localization
ae [ms]: ms Legacy Features
Ae [ms]: ms Legacy Features

C
C [ms]: ms Legacy Features
CF [ms]: ms Document Control Settings
CH [ms]: ms Document Control Settings

D
d- [ms]: ms Legacy Features
D- [ms]: ms Legacy Features

F
FAM [ms]: ms Document Control Settings
FR [ms]: ms Document Control Settings

L
LF [ms]: ms Document Control Settings
LH [ms]: ms Document Control Settings

M
MONTH1 [ms]: ms language and localization
MONTH10 [ms]: ms language and localization
MONTH11 [ms]: ms language and localization
MONTH12 [ms]: ms language and localization
MONTH2 [ms]: ms language and localization
MONTH3 [ms]: ms language and localization
MONTH4 [ms]: ms language and localization
MONTH5 [ms]: ms language and localization
MONTH6 [ms]: ms language and localization
MONTH7 [ms]: ms language and localization
MONTH8 [ms]: ms language and localization
MONTH9 [ms]: ms language and localization

O
o [ms]: ms Legacy Features
oe [ms]: ms Legacy Features
OE [ms]: ms Legacy Features

Q
Q [ms]: Typographical symbols in ms
q [ms]: ms Legacy Features

R
REFERENCES [ms]: ms language and localization
RF [ms]: ms Document Control Settings
RH [ms]: ms Document Control Settings

S
SN [ms]: Headings in ms
SN-DOT [ms]: Headings in ms
SN-NO-DOT [ms]: Headings in ms
SN-STYLE [ms]: ms Document Control Settings
SN-STYLE [ms]: Headings in ms

T
th [ms]: ms Legacy Features
Th [ms]: ms Legacy Features
TOC [ms]: ms language and localization

U
U [ms]: Typographical symbols in ms

V
v [ms]: ms Legacy Features

+ +
+ + + + +
+
+
+ +

Appendix H File Keyword Index

+ +
+
Jump to:   # +   +- +   +
+B +   +C +   +F +   +H +   +I +   +K +   +L +   +N +   +P +   +R +   +S +   +T +   +U +   +V +   +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

#
#: DESC File Format
#: Font Description File Format

-
---: Font Description File Format

B
biggestfont: DESC File Format

C
charset: DESC File Format
charset: Font Description File Format

F
family: Selecting Fonts
family: DESC File Format
fonts: Using Symbols
fonts: Special Fonts
fonts: DESC File Format

H
hor: DESC File Format

I
image_generator: DESC File Format

K
kernpairs: Font Description File Format

L
ligatures: Font Description File Format

N
name: Font Description File Format

P
paperlength: DESC File Format
papersize: DESC File Format
paperwidth: DESC File Format
pass_filenames: DESC File Format
postpro: DESC File Format
prepro: DESC File Format
print: DESC File Format

R
res: DESC File Format

S
sizes: DESC File Format
sizescale: DESC File Format
slant: Font Description File Format
spacewidth: Font Description File Format
spare1: DESC File Format
spare2: DESC File Format
special: Artificial Fonts
special: Font Description File Format
styles: Selecting Fonts
styles: Font Families
styles: DESC File Format

T
tcommand: DESC File Format

U
unicode: DESC File Format
unitwidth: DESC File Format
unscaled_charwidths: DESC File Format
use_charnames_in_special: Postprocessor Access
use_charnames_in_special: DESC File Format

V
vert: DESC File Format

+ +
+ + + + +
+
+
+ +

Appendix I Program and File Index

+ +
+
Jump to:   A +   +C +   +D +   +E +   +F +   +G +   +I +   +J +   +L +   +M +   +N +   +P +   +R +   +S +   +T +   +V +   +Z +   +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

A
an.tmac: man

C
changebar: Miscellaneous
composite.tmac: Using Symbols
cp1047.tmac: Input Encodings
cs.tmac: Manipulating Hyphenation

D
de.tmac: Manipulating Hyphenation
DESC: Selecting Fonts
DESC: Font Families
DESC: Using Symbols
DESC: Using Symbols
DESC: Special Fonts
diffmk: Miscellaneous

E
ec.tmac: Input Encodings
en.tmac: Manipulating Hyphenation
eqn: ms Insertions

F
fr.tmac: Manipulating Hyphenation
freeeuro.pfa: Input Encodings

G
gchem: Groff Options
gdiffmk: Miscellaneous
geqn: Groff Options
ggrn: Groff Options
gpic: Groff Options
grap: Groff Options
grefer: Groff Options
groff: Groff Options
gsoelim: Groff Options
gtbl: Groff Options
gtroff: Groff Options

I
it.tmac: Manipulating Hyphenation

J
ja.tmac: Manipulating Hyphenation

L
latin1.tmac: Input Encodings
latin2.tmac: Input Encodings
latin5.tmac: Input Encodings
latin9.tmac: Input Encodings

M
makeindex: Indexing
man.local: Optional man extensions
man.tmac: man
man.ultrix: Optional man extensions

N
nrchbar: Miscellaneous

P
papersize.tmac: Paper Format
perl: I/O
pic: ms Insertions
post-grohtml: Groff Options
pre-grohtml: Groff Options
preconv: Groff Options

R
refer: ms Insertions

S
soelim: Debugging
sv.tmac: Manipulating Hyphenation

T
tbl: ms Insertions
trace.tmac: Writing Macros
troffrc: Groff Options
troffrc: Paper Format
troffrc: Manipulating Hyphenation
troffrc: Manipulating Hyphenation
troffrc: troff and nroff Modes
troffrc-end: Groff Options
troffrc-end: Manipulating Hyphenation
troffrc-end: troff and nroff Modes
tty.tmac: troff and nroff Modes
tty.tmac: Line Layout

V
vtroff: Operators in Conditionals

Z
zh.tmac: Manipulating Hyphenation

+ +
+ + + + +
+
+
+ +

Appendix J Concept Index

+ +
+
Jump to:   " +   +% +   +& +   +' +   +( +   +) +   +* +   ++ +   +- +   +. +   +/ +   +8 +   +: +   +< +   += +   +> +   +[ +   +\ +   +] +   +| +   +
+A +   +B +   +C +   +D +   +E +   +F +   +G +   +H +   +I +   +J +   +K +   +L +   +M +   +N +   +O +   +P +   +Q +   +R +   +S +   +T +   +U +   +V +   +W +   +Y +   +Z +   +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

"
", as delimiter: Delimiters
", at end of sentence: Sentences
", at end of sentence: Using Symbols
", embedding in a macro argument: Calling Macros

%
%, as delimiter: Delimiters

&
&, as delimiter: Delimiters

'
', as a comment: Comments
', as delimiter: Delimiters
', at end of sentence: Sentences
', at end of sentence: Using Symbols

(
(, as delimiter: Delimiters

)
), as delimiter: Delimiters
), at end of sentence: Sentences
), at end of sentence: Using Symbols

*
*, as delimiter: Delimiters
*, at end of sentence: Sentences
*, at end of sentence: Using Symbols

+
+, and page motion: Numeric Expressions
+, as delimiter: Delimiters

-
-, and page motion: Numeric Expressions
-, as delimiter: Delimiters

.
., as delimiter: Delimiters
.h register, difference from nl: Diversions
.ps register, in comparison with .psr: Using Fractional Type Sizes
.s register, in comparison with .sr: Using Fractional Type Sizes
.S register, Plan 9 alias for .tabs: Tabs and Fields
.t register, and diversions: Diversion Traps
.tabs register, Plan 9 alias (.S): Tabs and Fields
.V register, and vs: Changing the Vertical Spacing

/
/, as delimiter: Delimiters

8
8-bit input: Font Description File Format

:
:, as delimiter: Delimiters

<
<, as delimiter: Delimiters

=
=, as delimiter: Delimiters

>
>, as delimiter: Delimiters

[
[, macro names starting with, and refer: Identifiers

\
\!, and copy mode: Diversions
\!, and output request: Diversions
\!, and trnt: Character Translations
\!, as delimiter: Delimiters
\!, as delimiter: Delimiters
\!, in top-level diversion: Diversions
\!, incompatibilities with AT&T troff: Other Differences
\!, incompatibilities with AT&T troff: Other Differences
\$, when reading text for a macro: Copy Mode
\%, and translations: Character Translations
\%, as delimiter: Delimiters
\%, as delimiter: Delimiters
\%, following \X or \Y: Manipulating Hyphenation
\%, in \X: Postprocessor Access
\%, incompatibilities with AT&T troff: Other Differences
\&, and glyph definitions: Using Symbols
\&, and translations: Character Translations
\&, as delimiter: Delimiters
\&, at end of sentence: Sentences
\&, in \X: Postprocessor Access
\&, incompatibilities with AT&T troff: Other Differences
\', and translations: Character Translations
\', as delimiter: Delimiters
\', as delimiter: Delimiters
\', incompatibilities with AT&T troff: Other Differences
\(, and translations: Character Translations
\), as delimiter: Delimiters
\), in \X: Postprocessor Access
\*, and warnings: Warnings
\*, incompatibilities with AT&T troff: Compatibility Mode
\*, when reading text for a macro: Copy Mode
\, disabling (eo): Using Escape Sequences
\, embedding in a macro argument: Calling Macros
\,, as delimiter: Delimiters
\- glyph, and cflags: Using Symbols
\-, and translations: Character Translations
\-, as delimiter: Delimiters
\-, as delimiter: Delimiters
\-, incompatibilities with AT&T troff: Other Differences
\/, as delimiter: Delimiters
\/, as delimiter: Delimiters
\0, as delimiter: Delimiters
\:, as delimiter: Delimiters
\:, as delimiter: Delimiters
\:, in \X: Postprocessor Access
\?, and copy mode: Operators in Conditionals
\?, and copy mode: Diversions
\?, as delimiter: Delimiters
\?, in top-level diversion: Diversions
\?, incompatibilities with AT&T troff: Other Differences
\a, and copy mode: Leaders
\a, and translations: Character Translations
\a, as delimiter: Delimiters
\A, delimiters allowed by: Delimiters
\A, incompatibilities with AT&T troff: Other Differences
\b, delimiters allowed by: Delimiters
\b, limitations of: Drawing Geometric Objects
\C, and translations: Character Translations
\c, as delimiter: Delimiters
\c, as delimiter: Delimiters
\c, incompatibilities with AT&T troff: Other Differences
\c, when filling disabled: Line Continuation
\c, when filling enabled: Line Continuation
\d, as delimiter: Delimiters
\D, delimiters allowed by: Delimiters
\e, and glyph definitions: Using Symbols
\e, and translations: Character Translations
\e, as delimiter: Delimiters
\E, as delimiter: Delimiters
\e, as delimiter: Delimiters
\e, incompatibilities with AT&T troff: Other Differences
\F, and changing fonts: Selecting Fonts
\f, and font translations: Selecting Fonts
\f, incompatibilities with AT&T troff: Compatibility Mode
\h, delimiters allowed by: Delimiters
\H, delimiters allowed by: Delimiters
\H, incompatibilities with AT&T troff: Compatibility Mode
\H, using + and - with: Numeric Expressions
\H, with fractional type sizes: Using Fractional Type Sizes
\l, and glyph definitions: Using Symbols
\L, and glyph definitions: Using Symbols
\l, delimiters allowed by: Delimiters
\L, delimiters allowed by: Delimiters
\N, and translations: Character Translations
\n, and warnings: Warnings
\N, delimiters allowed by: Delimiters
\n, incompatibilities with AT&T troff: Compatibility Mode
\n, when reading text for a macro: Copy Mode
\o, delimiters allowed by: Delimiters
\p, as delimiter: Delimiters
\p, as delimiter: Delimiters
\R, after \c: Line Continuation
\R, and warnings: Warnings
\r, as delimiter: Delimiters
\R, delimiters allowed by: Delimiters
\R, difference from nr: Auto-increment
\R, using + and - with: Numeric Expressions
\RET, when reading text for a macro: Copy Mode
\s, delimiters allowed by: Delimiters
\S, delimiters allowed by: Delimiters
\s, incompatibilities with AT&T troff: Compatibility Mode
\S, incompatibilities with AT&T troff: Compatibility Mode
\s, incompatibilities with AT&T troff: Compatibility Mode
\s, using + and - with: Numeric Expressions
\s, with fractional type sizes: Using Fractional Type Sizes
\SP, as delimiter: Delimiters
\SP, difference from \~: Calling Macros
\SP, incompatibilities with AT&T troff: Other Differences
\t, and copy mode: Tabs and Fields
\t, and translations: Character Translations
\t, and warnings: Warnings
\t, as delimiter: Delimiters
\u, as delimiter: Delimiters
\V, and copy mode: I/O
\v, delimiters allowed by: Delimiters
\v, internal representation: Gtroff Internals
\w, delimiters allowed by: Delimiters
\X, and special characters: Postprocessor Access
\X, delimiters allowed by: Delimiters
\x, delimiters allowed by: Delimiters
\X, followed by \%: Manipulating Hyphenation
\Y, followed by \%: Manipulating Hyphenation
\Z, delimiters allowed by: Delimiters
\[, and translations: Character Translations
\\, when reading text for a macro: Copy Mode
\^, as delimiter: Delimiters
\^, incompatibilities with AT&T troff: Other Differences
\_, and translations: Character Translations
\_, as delimiter: Delimiters
\_, as delimiter: Delimiters
\_, incompatibilities with AT&T troff: Other Differences
\`, and translations: Character Translations
\`, as delimiter: Delimiters
\`, as delimiter: Delimiters
\`, incompatibilities with AT&T troff: Other Differences
\{, as delimiter: Delimiters
\{, as delimiter: Delimiters
\{, incompatibilities with AT&T troff: Other Differences
\|, as delimiter: Delimiters
\|, incompatibilities with AT&T troff: Other Differences
\}, and warnings: Warnings
\}, as delimiter: Delimiters
\}, as delimiter: Delimiters
\}, incompatibilities with AT&T troff: Other Differences
\~, and translations: Character Translations
\~, as delimiter: Delimiters
\~, difference from \SP: Calling Macros
\~, incompatibilities with AT&T troff: Other Differences

]
], as part of an identifier: Identifiers
], at end of sentence: Sentences
], at end of sentence: Using Symbols
], macro names starting with, and refer: Identifiers

|
|, and page motion: Numeric Expressions

A
ab request, incompatibilities with AT&T troff: Other Differences
aborting (ab): Debugging
absolute (sic) position operator (|): Numeric Expressions
abstract font style: Using Fonts
abstract font style, setting up (sty): Font Families
accent marks [ms]: ms Legacy Features
access to postprocessor: Postprocessor Access
accessing unnamed glyphs with \N: Font Description File Format
activating kerning (kern): Ligatures and Kerning
activating ligatures (lg): Ligatures and Kerning
activating track kerning (tkf): Ligatures and Kerning
ad request, and hyphenation margin: Manipulating Hyphenation
ad request, and hyphenation space: Manipulating Hyphenation
addition: Numeric Expressions
additional inter-sentence space: Manipulating Filling and Adjustment
adjustment and filling, manipulating: Manipulating Filling and Adjustment
adjustment mode register (.j): Manipulating Filling and Adjustment
adjustment to both margins, difference from AT&T troff: Other Differences
Adobe Glyph List (AGL): Using Symbols
alias, diversion, creating (als): Strings
alias, diversion, removing (rm): Strings
alias, macro, creating (als): Strings
alias, macro, removing (rm): Strings
alias, register, creating (aln): Setting Registers
alias, register, removing (rr): Setting Registers
alias, string, creating (als): Strings
alias, string, removing (rm): Strings
aliasing fonts with third argument to fp request: Font Positions
als request, and \$0: Parameters
am, am1, ami requests, and warnings: Warnings
appending to a diversion (da, boxa): Diversions
appending to a file (opena): I/O
appending to a macro (am): Writing Macros
appending to a string (as): Strings
approximation output register (.A): Built-in Registers
arc, drawing (‘\D'a …'’): Drawing Geometric Objects
argument: Requests and Macros
arguments to macros: Calling Macros
arguments to macros, and tabs: Invoking Requests
arguments to requests: Invoking Requests
arguments to requests, and tabs: Invoking Requests
arguments, and compatibility mode: Gtroff Internals
arguments, to escape sequences, delimiting: Delimiters
arguments, to strings: Strings
arithmetic operators: Numeric Expressions
artificial fonts: Artificial Fonts
as, as1 requests, and comments: Comments
as, as1 requests, and warnings: Warnings
ASCII output encoding: Groff Options
asciify request, and writem: I/O
assertion (arithmetic operator): Numeric Expressions
assign number format to register (af): Assigning Register Formats
assignments, indirect: Interpolating Registers
assignments, nested: Interpolating Registers
AT&T ms, macro package differences: Differences from AT&T ms
attributes, character cell: Using Fonts
auto-incrementation of a register: Auto-increment
automatic font mounting: Selecting Fonts
automatic hyphenation: Manipulating Hyphenation
automatic hyphenation parameters: Manipulating Hyphenation
auxiliary macro package: Major Macro Packages
available glyphs, list of (groff_char(7) man page): Using Symbols

B
background: Background
background color name register (.M): Colors
backslash glyph, formatting (\[rs]): Using Escape Sequences
backslash, embedding in a macro argument: Calling Macros
backslash, printing (\\, \e, \E, \[rs]): Other Differences
backspace character, and translations: Character Translations
backtrace of input stack (backtrace): Debugging
baseline rule special character(\[ru]): Drawing Geometric Objects
baseline, text: Page Geometry
baseline, text: Manipulating Type Size and Vertical Spacing
basic scaling unit (u): Measurements
basic units: Page Geometry
basic units, conversion to: Measurements
basics of macro package usage: Basics
bd request, and font styles: Font Families
bd request, and font translations: Selecting Fonts
bd request, incompatibilities with AT&T troff: Other Differences
beginning diversion (di, box): Diversions
beginning of conditional block (\{): Conditional Blocks
blank line: Breaking
blank line macro (blm): Breaking
blank line macro (blm): Invoking Requests
blank line macro (blm): Blank Line Traps
blank line trap (blm): Invoking Requests
blank line traps: Blank Line Traps
blank lines, disabling: Manipulating Spacing
block, conditional, beginning (\{): Conditional Blocks
block, conditional, end (\}): Conditional Blocks
blocks, conditional: Conditional Blocks
body, of a while request: while
boldface, imitating (bd): Artificial Fonts
bottom margin: Page Location Traps
boundary-relative motion operator (|): Numeric Expressions
bounding box: Miscellaneous
box (diversion operation): Diversions
box request, and warnings: Warnings
box rule glyph (\[br]): Drawing Geometric Objects
box, boxa requests, and warnings: Warnings
boxa request, and dn (dl): Diversions
boxa request, and warnings: Warnings
boxes [ms]: ms keeps and displays
bp request, and top-level diversion: Page Control
bp request, and traps (.pe): Page Location Traps
bp request, causing implicit break: Manipulating Filling and Adjustment
bp request, incompatibilities with AT&T troff: Other Differences
bp request, using + and - with: Numeric Expressions
br glyph, and cflags: Using Symbols
brace escape sequence, closing (\}): Conditional Blocks
brace escape sequence, opening (\}): Conditional Blocks
brace escape sequences (\{, \}): Conditional Blocks
break: Breaking
break: Manipulating Filling and Adjustment
break (introduction): Basics
break request, in a while loop: while
break, page: Page Geometry
break, page: Page Control
break, page: The Implicit Page Trap
break, page (introduction): Basics
break, page, final: End-of-input Traps
break, page, prevented by vpt: Vertical Position Traps
breaking file names (\:): Manipulating Hyphenation
breaking URLs (\:): Manipulating Hyphenation
breaking without hyphens (\:): Manipulating Hyphenation
built-in register, removing: Built-in Registers
built-in registers: Built-in Registers
bulleted list, example markup [ms]: Lists in ms

C
c scaling unit: Measurements
calling a macro: Requests and Macros
calling macros: Calling Macros
capabilities of groff: groff Capabilities
case-transforming a string (stringdown, stringup): Strings
categories, warning: Warnings
CCSID 1047 output encoding (EBCDIC): Groff Options
ce request, causing implicit break: Manipulating Filling and Adjustment
ce request, difference from ‘.ad c: Manipulating Filling and Adjustment
cell, character, attributes: Using Fonts
centered text (filled): Manipulating Filling and Adjustment
centered text (unfilled): Manipulating Filling and Adjustment
centering lines (ce): Manipulating Filling and Adjustment
centering lines (introduction): Basics
centimeter scaling unit (c): Measurements
cf request, and copy mode: I/O
cf request, causing implicit break: Manipulating Filling and Adjustment
changing control characters: Control Characters
changing font family (fam, \F): Font Families
changing fonts (ft, \f): Selecting Fonts
changing format, and read-only registers: Assigning Register Formats
changing the font height (\H): Artificial Fonts
changing the font slant (\S): Artificial Fonts
changing the page number character (pc): Page Layout
changing trap location (ch): Page Location Traps
changing type sizes (ps, \s): Changing the Type Size
changing vertical line spacing (vs): Changing the Vertical Spacing
char request, and soft hyphen character: Manipulating Hyphenation
char request, and translations: Character Translations
char request, used with \N: Using Symbols
character: Using Symbols
character cell attributes: Using Fonts
character class (class): Character Classes
character classes: Character Classes
character properties (cflags): Using Symbols
character translations: Character Translations
character, backspace, and translations: Character Translations
character, control (.): Requests and Macros
character, control, changing (cc): Control Characters
character, defining (char): Using Symbols
character, defining fallback (fchar, fschar, schar): Using Symbols
character, distinguished from glyph: Using Symbols
character, dummy (\&): Dummy Characters
character, dummy (\&), as control character suppressor: Requests and Macros
character, dummy (\&), effect on kerning: Ligatures and Kerning
character, dummy (\&), effect on \l escape sequence: Drawing Geometric Objects
character, escape, changing (ec): Using Escape Sequences
character, escape, while defining glyph: Using Symbols
character, field delimiting (fc): Fields
character, field padding (fc): Fields
character, horizontal tab: Tabs and Leaders
character, hyphenation (\%): Manipulating Hyphenation
character, leader: Tabs and Leaders
character, leader repetition (lc): Leaders
character, leader, and translations: Character Translations
character, leader, non-interpreted (\a): Leaders
character, named (\C): Using Symbols
character, newline, and translations: Character Translations
character, no-break control ('): Requests and Macros
character, no-break control, changing (c2): Control Characters
character, ordinary: Identifiers
character, soft hyphen, setting (shc): Manipulating Hyphenation
character, special: Character Translations
character, tab repetition (tc): Tabs and Fields
character, tab, and translations: Character Translations
character, tab, non-interpreted (\t): Tabs and Fields
character, transparent: Using Symbols
character, transparent dummy (\)): Dummy Characters
characters, end-of-sentence: Using Symbols
characters, end-of-sentence transparent: Sentences
characters, hyphenation: Using Symbols
characters, input, and output glyphs, compatibility with AT&T troff: Other Differences
characters, invalid for trf request: I/O
characters, invalid input: Identifiers
characters, overlapping: Using Symbols
characters, special: Sentences
characters, special, list of (groff_char(7) man page): Using Symbols
characters, unnamed, accessing with \N: Font Description File Format
circle, filled, drawing (‘\D'C …'’): Drawing Geometric Objects
circle, outlined, drawing (‘\D'c …'’): Drawing Geometric Objects
circle, solid, drawing (‘\D'C …'’): Drawing Geometric Objects
circle, stroked, drawing (‘\D'c …'’): Drawing Geometric Objects
class of characters (class): Character Classes
classes, character: Character Classes
clearing input line trap (it, itc): Input Line Traps
closing brace escape sequence (\}): Conditional Blocks
closing file (close): I/O
code page 1047 output encoding: Groff Options
code page 1047, input encoding: Input Encodings
code, hyphenation (hcode): Manipulating Hyphenation
color name, background, register (.M): Colors
color name, fill, register (.M): Colors
color name, stroke, register (.m): Colors
color, default: Colors
color, fill: Colors
color, stroke: Colors
colors: Colors
command prefix: Environment
command-line options: Groff Options
comments: Comments
comments in device description files: DESC File Format
comments in font description files: Font Description File Format
comments, lining up with tabs: Comments
comments, with ds: Strings
common features: Common Features
common name space of macros, diversions, and strings: Identifiers
comparison of strings: Operators in Conditionals
comparison operators: Numeric Expressions
compatibility mode: Warnings
compatibility mode: Compatibility Mode
compatibility mode, and parameters: Gtroff Internals
complementation, logical: Numeric Expressions
composite glyph names: Using Symbols
conditional block, beginning (\{): Conditional Blocks
conditional block, end (\}): Conditional Blocks
conditional blocks: Conditional Blocks
conditional expressions: Operators in Conditionals
conditional output for terminal (TTY): Operators in Conditionals
conditional page break (ne): Page Control
conditionals and loops: Conditionals and Loops
configuring control characters: Control Characters
configuring the page length (pl): Page Layout
consecutive hyphenated lines (hlm): Manipulating Hyphenation
constant glyph space mode (cs): Artificial Fonts
contents, table of: Table of Contents
contents, table of: Leaders
continuation, input line (\RET): Line Continuation
continuation, output line (\c): Line Continuation
continue request, in a while loop: while
continued output line register (.int): Line Continuation
continuous underlining (cu): Artificial Fonts
control character (.): Requests and Macros
control character, changing (cc): Control Characters
control character, no-break ('): Requests and Macros
control character, no-break, changing (c2): Control Characters
control characters: Control Characters
control line: Requests and Macros
control, line: Line Continuation
control, page: Page Control
conventions for input: Input Conventions
conversion to basic units: Measurements
copy mode: Copy Mode
copy mode: Copy Mode
copy mode, and cf request: I/O
copy mode, and device request: Postprocessor Access
copy mode, and length request: Strings
copy mode, and macro parameters: Parameters
copy mode, and output request: Diversions
copy mode, and trf request: I/O
copy mode, and write request: I/O
copy mode, and writec request: I/O
copy mode, and writem request: I/O
copy mode, and \!: Diversions
copy mode, and \?: Operators in Conditionals
copy mode, and \?: Diversions
copy mode, and \a: Leaders
copy mode, and \t: Tabs and Fields
copy mode, and \V: I/O
copying environment (evc): Environments
correction between oblique and upright glyph (\/, \,): Italic Corrections
correction between upright and oblique glyph (\/, \,): Italic Corrections
correction, italic (\/): Italic Corrections
correction, left italic (\,): Italic Corrections
cover page in [ms], example markup: ms Document Description Macros
cp request, and glyph definitions: Using Symbols
cq glyph, at end of sentence: Sentences
cq glyph, at end of sentence: Using Symbols
creating alias for register (aln): Setting Registers
creating alias, for diversion (als): Strings
creating alias, for macro (als): Strings
creating alias, for string (als): Strings
creating new characters (char): Using Symbols
credits: Credits
cs request, and font styles: Font Families
cs request, and font translations: Selecting Fonts
cs request, incompatibilities with AT&T troff: Other Differences
cs request, with fractional type sizes: Using Fractional Type Sizes
CSTR #54 errata: Built-in Registers
CSTR #54 errata: Line Layout
CSTR #54 errata: Page Control
CSTR #54 errata: Artificial Fonts
CSTR #54 errata: Changing the Type Size
CSTR #54 errata: Page Motions
CSTR #54 erratum, bp request: Page Control
CSTR #54 erratum, po request: Line Layout
CSTR #54 erratum, ps request: Changing the Type Size
CSTR #54 erratum, sb register: Page Motions
CSTR #54 erratum, st register: Page Motions
CSTR #54 erratum, yr register: Built-in Registers
CSTR #54 erratum, \S escape: Artificial Fonts
CSTR #54 erratum, \s escape sequence: Changing the Type Size
current directory: Macro Directories
current input file name register (.F): Built-in Registers
current page number (%): Page Control
current time, hours (hours): Built-in Registers
current time, minutes (minutes): Built-in Registers
current time, seconds (seconds): Built-in Registers

D
da request, and dn (dl): Diversions
da request, and warnings: Warnings
da request, and warnings: Warnings
date, day of the month register (dy): Built-in Registers
date, day of the week register (dw): Built-in Registers
date, month of the year register (mo): Built-in Registers
date, year register (year, yr): Built-in Registers
day of the month register (dy): Built-in Registers
day of the week register (dw): Built-in Registers
dd glyph, at end of sentence: Sentences
dd glyph, at end of sentence: Using Symbols
de request, and while: while
de, de1, dei requests, and warnings: Warnings
debugging: Debugging
debugging page location traps: Page Location Traps
decimal point, as delimiter: Delimiters
decrementation, automatic, of a register: Auto-increment
default color: Colors
default tab stops: Tabs and Fields
default units: Default Units
deferred output: Deferring Output
defining character (char): Using Symbols
defining character class (class): Character Classes
defining fallback character (fchar, fschar, schar): Using Symbols
defining glyph (char): Using Symbols
defining symbol (char): Using Symbols
delimited arguments, incompatibilities with AT&T troff: Compatibility Mode
delimiters, for escape sequence arguments: Delimiters
delimiting character, for fields (fc): Fields
delimiting escape sequence arguments: Delimiters
depth, interpolation: Calling Macros
depth, of last glyph (.cdp): Environments
DESC file format: DESC File Format
DESC file, and font mounting: Font Positions
DESC file, and use_charnames_in_special keyword: Postprocessor Access
description file, font: Using Fonts
device description files, comments: DESC File Format
device request, and copy mode: Postprocessor Access
device resolution: Page Geometry
device resolution: DESC File Format
device resolution, obtaining in the formatter: Measurements
devices for output: Output Device Intro
dg glyph, at end of sentence: Sentences
dg glyph, at end of sentence: Using Symbols
di request, and warnings: Warnings
di request, and warnings: Warnings
differences in implementation: Implementation Differences
digit-width space (\0): Page Motions
digits, as delimiters: Delimiters
dimensions, line: Line Layout
directories for fonts: Font Directories
directories for macros: Macro Directories
directory, current: Macro Directories
directory, for tmac files: Macro Directories
directory, home: Macro Directories
directory, platform-specific: Macro Directories
directory, site-local: Macro Directories
directory, site-local: Font Directories
disabling hyphenation (\%): Manipulating Hyphenation
disabling \ (eo): Using Escape Sequences
discardable horizontal space: Manipulating Filling and Adjustment
displays: Displays and Keeps
displays [ms]: ms keeps and displays
displays, and footnotes [ms]: ms Footnotes
distance to next vertical position trap register (.t): Page Location Traps
diversion: Deferring Output
diversion name register (.z): Diversions
diversion trap, setting (dt): Diversion Traps
diversion traps: Diversion Traps
diversion, appending to (da, boxa): Diversions
diversion, beginning (di, box): Diversions
diversion, creating alias for (als): Strings
diversion, ending (di, box): Diversions
diversion, nested: Diversions
diversion, removing (rm): Strings
diversion, removing alias for (rm): Strings
diversion, renaming (rn): Strings
diversion, stripping final newline: Punning Names
diversion, top-level: Diversions
diversion, top-level, and bp: Page Control
diversion, top-level, and \!: Diversions
diversion, top-level, and \?: Diversions
diversion, unformatting (asciify): Diversions
diversion, vertical position in, register (.d): Diversions
diversions: Diversions
diversions: Punning Names
diversions, and traps: Page Location Traps
diversions, shared name space with macros and strings: Identifiers
division, truncating: Numeric Expressions
dl register, and da (boxa): Diversions
dn register, and da (boxa): Diversions
document description macros, [ms]: ms Document Description Macros
document formats: Document Formats
documents, multi-file: Debugging
documents, structuring the source of: Invoking Requests
dot, as delimiter: Delimiters
double quote, embedding in a macro argument: Calling Macros
double quotes, trailing, in strings: Strings
double-spacing (ls): Manipulating Spacing
double-spacing (vs, pvs): Changing the Vertical Spacing
down-casing a string (stringdown): Strings
drawing a filled circle (‘\D'C …'’): Drawing Geometric Objects
drawing a filled ellipse (‘\D'E …'’): Drawing Geometric Objects
drawing a filled polygon (‘\D'P …'’): Drawing Geometric Objects
drawing a line (‘\D'l …'’): Drawing Geometric Objects
drawing a solid circle (‘\D'C …'’): Drawing Geometric Objects
drawing a solid ellipse (‘\D'E …'’): Drawing Geometric Objects
drawing a solid polygon (‘\D'P …'’): Drawing Geometric Objects
drawing a spline (‘\D'~ …'’): Drawing Geometric Objects
drawing a stroked circle (‘\D'c …'’): Drawing Geometric Objects
drawing a stroked ellipse (‘\D'e …'’): Drawing Geometric Objects
drawing a stroked polygon (‘\D'p …'’): Drawing Geometric Objects
drawing an arc (‘\D'a …'’): Drawing Geometric Objects
drawing an outlined circle (‘\D'c …'’): Drawing Geometric Objects
drawing an outlined ellipse (‘\D'e …'’): Drawing Geometric Objects
drawing an outlined polygon (‘\D'p …'’): Drawing Geometric Objects
drawing horizontal lines (\l): Drawing Geometric Objects
drawing position: Page Geometry
drawing position, vertical (nl): Page Control
drawing requests: Drawing Geometric Objects
drawing vertical lines (\L): Drawing Geometric Objects
ds request, and comments: Strings
ds request, and double quotes: Strings
ds request, and leading spaces: Strings
ds, ds1 requests, and comments: Comments
ds, ds1 requests, and warnings: Warnings
dummy character (\&): Dummy Characters
dummy character (\&), as control character suppressor: Requests and Macros
dummy character (\&), effect on kerning: Ligatures and Kerning
dummy character (\&), effect on \l escape sequence: Drawing Geometric Objects
dummy character, transparent (\)): Dummy Characters
dummy environment, used by \w escape sequence: Page Motions
dumping environments (pev): Debugging
dumping page location traps (ptr): Debugging
dumping registers (pnr): Debugging
dumping symbol table (pm): Debugging

E
EBCDIC output encoding: Groff Options
EBCDIC, input encoding: Input Encodings
ejection, page: Page Geometry
ejection, page: Page Control
ejection, page: The Implicit Page Trap
ejection, page, of final page: End-of-input Traps
ejection, page, prevented by vpt: Vertical Position Traps
el request, and warnings: Warnings
ellipse, filled, drawing (‘\D'E …'’): Drawing Geometric Objects
ellipse, outlined, drawing (‘\D'e …'’): Drawing Geometric Objects
ellipse, solid, drawing (‘\D'E …'’): Drawing Geometric Objects
ellipse, stroked, drawing (‘\D'e …'’): Drawing Geometric Objects
em glyph, and cflags: Using Symbols
em scaling unit (m): Measurements
embolding of special fonts: Artificial Fonts
empty line: Breaking
en scaling unit (n): Measurements
enabling vertical position traps (vpt): Vertical Position Traps
encoding, input, code page 1047: Input Encodings
encoding, input, EBCDIC: Input Encodings
encoding, input, Latin-1 (ISO 8859-1): Input Encodings
encoding, input, Latin-2 (ISO 8859-2): Input Encodings
encoding, input, Latin-5 (ISO 8859-9): Input Encodings
encoding, input, Latin-9 (ISO 8859-15): Input Encodings
encoding, output, ASCII: Groff Options
encoding, output, code page 1047: Groff Options
encoding, output, EBCDIC: Groff Options
encoding, output, ISO 646: Groff Options
encoding, output, Latin-1 (ISO 8859-1): Groff Options
encoding, output, UTF-8: Groff Options
end of conditional block (\}): Conditional Blocks
end-of-input macro (em): End-of-input Traps
end-of-input trap, setting (em): End-of-input Traps
end-of-input traps: End-of-input Traps
end-of-sentence characters: Sentences
end-of-sentence characters: Using Symbols
end-of-sentence transparent characters: Sentences
ending diversion (di, box): Diversions
endnotes: Footnotes and Endnotes
environment: Deferring Output
environment availability and naming, incompatibilities with: Other Differences
environment number/name register (.ev): Environments
environment variables: Environment
environment, copying (evc): Environments
environment, dimensions of last glyph (.w, .cht, .cdp, .csk): Environments
environment, dummy, used by \w escape sequence: Page Motions
environment, previous line length (.n): Environments
environment, switching (ev): Environments
environments: Environments
environments, dumping (pev): Debugging
equality operator: Numeric Expressions
equation example [ms]: ms Insertions
equations [ms]: ms Insertions
escape character, changing (ec): Using Escape Sequences
escape character, formatting (\e): Using Escape Sequences
escape character, while defining glyph: Using Symbols
escape sequence: Formatter Instructions
escape sequence argument delimiters: Delimiters
escape sequences: Using Escape Sequences
escape sequences, brace (\{, \}): Conditional Blocks
escaping newline characters, in strings: Strings
ex request, use in debugging: Debugging
ex request, used with nx and rd: I/O
example markup, bulleted list [ms]: Lists in ms
example markup, cover page in [ms]: ms Document Description Macros
example markup, glossary-style list [ms]: Lists in ms
example markup, numbered list [ms]: Lists in ms
examples of invocation: Invocation Examples
exiting (ex): Debugging
expansion of strings (\*): Strings
explicit hyphen (\%): Manipulating Hyphenation
explicit hyphenation: Manipulating Hyphenation
expression, limitation of logical not in: Numeric Expressions
expression, order of evaluation: Numeric Expressions
expressions, and register format: Assigning Register Formats
expressions, and space characters: Numeric Expressions
expressions, conditional: Operators in Conditionals
expressions, numeric: Numeric Expressions
extra post-vertical line space (\x): Changing the Vertical Spacing
extra post-vertical line space register (.a): Manipulating Spacing
extra pre-vertical line space (\x): Changing the Vertical Spacing
extra spaces between words: Adjustment
extreme values representable with Roman numerals: Assigning Register Formats
extremum operators (>?, <?): Numeric Expressions

F
f scaling unit: Colors
factor, zoom, of a font (fzoom): Selecting Fonts
fallback character, defining (fchar, fschar, schar): Using Symbols
fallback glyph, removing definition (rchar, rfschar): Using Symbols
fam request, and changing fonts: Selecting Fonts
families, font: Font Families
family, font: Using Fonts
features, common: Common Features
fi request, causing implicit break: Manipulating Filling and Adjustment
field delimiting character (fc): Fields
field padding character (fc): Fields
fields: Fields
fields, and tabs: Tabs and Fields
figure space (\0): Page Motions
figures [ms]: ms Insertions
file formats: File Formats
file names, breaking (\:): Manipulating Hyphenation
file, appending to (opena): I/O
file, closing (close): I/O
file, font description: Using Fonts
file, inclusion (so): I/O
file, macro, search path: Macro Directories
file, opening (open): I/O
file, processing next (nx): I/O
file, writing to (write, writec): I/O
files, font: Device and Font Description Files
fill color: Colors
fill color name register (.M): Colors
fill mode (fi), enabling: Manipulating Filling and Adjustment
fill mode, and \c: Line Continuation
fill mode, disabling: Manipulating Filling and Adjustment
filled circle, drawing (‘\D'C …'’): Drawing Geometric Objects
filled ellipse, drawing (‘\D'E …'’): Drawing Geometric Objects
filled polygon, drawing (‘\D'P …'’): Drawing Geometric Objects
filling: Filling
filling and adjustment, manipulating: Manipulating Filling and Adjustment
filling of output, disabling (nf): Manipulating Filling and Adjustment
filling of output, enabling (fi): Manipulating Filling and Adjustment
filling, and break warnings: Warnings
filling, and inter-sentence space: Manipulating Filling and Adjustment
final newline, stripping in diversions: Punning Names
fl request, causing implicit break: Manipulating Filling and Adjustment
floating keep: Displays and Keeps
flush output (fl): Debugging
font: Using Fonts
font aliasing with third argument to fp request: Font Positions
font description file: Using Fonts
font description file format: DESC File Format
font description file, format: Font Description File Format
font description files, comments: Font Description File Format
font directories: Font Directories
font families: Font Families
font family: Using Fonts
font family, changing (fam, \F): Font Families
font file, format: Font Description File Format
font files: Device and Font Description Files
font for underlining (uf): Artificial Fonts
font height, changing (\H): Artificial Fonts
font metrics: Using Fonts
font mounting, automatic: Selecting Fonts
font path: Font Directories
font position register (.f): Font Positions
font positions: Font Positions
font slant, changing (\S): Artificial Fonts
font style: Using Fonts
font style, abstract: Using Fonts
font style, abstract, setting up (sty): Font Families
font styles: Font Families
font translation (ftr): Selecting Fonts
font, magnification (fzoom): Selecting Fonts
font, mounting (fp): Font Positions
font, optical size: Selecting Fonts
font, previous, selecting (\f[], \fP): Selecting Fonts
font, previous, slecting (ft): Selecting Fonts
font, selection: Selecting Fonts
font, special: Using Fonts
font, text: Using Fonts
font, unstyled: Using Fonts
font, zoom factor (fzoom): Selecting Fonts
fonts, artificial: Artificial Fonts
fonts, changing (ft, \f): Selecting Fonts
fonts, searching: Font Directories
fonts, special: Special Fonts
footers: Page Layout
footers: Page Location Traps
footers [ms]: ms Headers and Footers
footnote marker [ms]: ms Footnotes
footnotes: Footnotes and Endnotes
footnotes [ms]: ms Footnotes
footnotes, and displays [ms]: ms Footnotes
footnotes, and keeps [ms]: ms Footnotes
form letters: I/O
format of font description file: DESC File Format
format of font description files: Font Description File Format
format of font files: Font Description File Format
format of register (\g): Assigning Register Formats
format, paper: Paper Format
formats, file: File Formats
formatter instructions: Formatter Instructions
formatting a backslash glyph (\[rs]): Using Escape Sequences
formatting a title line (tl): Page Layout
formatting the escape character (\e): Using Escape Sequences
formatting the time: I/O
fp request, and font translations: Selecting Fonts
fp request, incompatibilities with AT&T troff: Other Differences
fractional point sizes: Using Fractional Type Sizes
fractional point sizes: Other Differences
fractional type sizes: Using Fractional Type Sizes
fractional type sizes: Other Differences
fractional type sizes in ms macros: Differences from AT&T ms
French spacing: Sentences
fspecial request, and font styles: Font Families
fspecial request, and font translations: Selecting Fonts
fspecial request, and glyph search order: Using Symbols
fspecial request, and imitating bold: Artificial Fonts
ft request, and font translations: Selecting Fonts
full-service macro package: Major Macro Packages

G
geometry, page: Page Geometry
GGL (groff glyph list): Using Symbols
GGL (groff glyph list): Character Classes
glossary-style list, example markup [ms]: Lists in ms
glyph: Using Symbols
glyph for line drawing: Drawing Geometric Objects
glyph names, composite: Using Symbols
glyph pile (\b): Drawing Geometric Objects
glyph properties (cflags): Using Symbols
glyph, box rule (\[br]): Drawing Geometric Objects
glyph, constant space: Artificial Fonts
glyph, defining (char): Using Symbols
glyph, distinguished from character: Using Symbols
glyph, for line drawing: Drawing Geometric Objects
glyph, for margins (mc): Miscellaneous
glyph, last, dimensions (.w, .cht, .cdp, .csk): Environments
glyph, leader repetition (lc): Leaders
glyph, numbered (\N): Character Translations
glyph, numbered (\N): Using Symbols
glyph, removing definition (rchar, rfschar): Using Symbols
glyph, soft hyphen (hy): Manipulating Hyphenation
glyph, tab repetition (tc): Tabs and Fields
glyph, underscore (\[ru]): Drawing Geometric Objects
glyphs, available, list of (groff_char(7) man page): Using Symbols
glyphs, output, and input characters, compatibility with AT&T troff: Other Differences
glyphs, overstriking (\o): Page Motions
glyphs, unnamed: Using Symbols
glyphs, unnamed, accessing with \N: Font Description File Format
GNU troff, identification register (.g): Built-in Registers
GNU troff, PID register ($$): Built-in Registers
GNU troff, process ID register ($$): Built-in Registers
GNU-specific register (.g): Built-in Registers
graphic renditions: Using Fonts
greater than (or equal to) operator: Numeric Expressions
groff capabilities: groff Capabilities
groff glyph list (GGL): Using Symbols
groff glyph list (GGL): Character Classes
groff invocation: Invoking groff
groff, and pi request: I/O
groff—what is it?: What Is groff?
GROFF_BIN_PATH, environment variable: Environment
GROFF_COMMAND_PREFIX, environment variable: Environment
GROFF_ENCODING, environment variable: Environment
GROFF_FONT_PATH, environment variable: Environment
GROFF_FONT_PATH, environment variable: Font Directories
GROFF_TMAC_PATH, environment variable: Environment
GROFF_TMAC_PATH, environment variable: Macro Directories
GROFF_TMPDIR, environment variable: Environment
GROFF_TYPESETTER, environment variable: Environment
grohtml, the program: Groff Options
gtroff, interactive use: Debugging
gtroff, output: gtroff Output
gtroff, reference: GNU troff Reference

H
hair space (\^): Page Motions
hcode request, and glyph definitions: Using Symbols
headers: Page Layout
headers: Page Location Traps
headers [ms]: ms Headers and Footers
height, font, changing (\H): Artificial Fonts
height, of last glyph (.cht): Environments
high-water mark register (.h): Diversions
home directory: Macro Directories
horizontal discardable space: Manipulating Filling and Adjustment
horizontal input line position register (hp): Page Motions
horizontal input line position, saving (\k): Page Motions
horizontal line, drawing (\l): Drawing Geometric Objects
horizontal motion (\h): Page Motions
horizontal motion quantum: DESC File Format
horizontal motion quantum register (.H): Motion Quanta
horizontal output line position register (.k): Page Motions
horizontal resolution: DESC File Format
horizontal resolution register (.H): Motion Quanta
horizontal space (\h): Page Motions
horizontal space, unformatting: Punning Names
horizontal tab character: Tabs and Leaders
hours, current time (hours): Built-in Registers
hpf request, and hyphenation language: Manipulating Hyphenation
hw request, and hy restrictions: Manipulating Hyphenation
hw request, and hyphenation language: Manipulating Hyphenation
hy glyph, and cflags: Using Symbols
hyphen, explicit (\%): Manipulating Hyphenation
hyphenated lines, consecutive (hlm): Manipulating Hyphenation
hyphenating characters: Using Symbols
hyphenation: Hyphenation
hyphenation character (\%): Manipulating Hyphenation
hyphenation code (hcode): Manipulating Hyphenation
hyphenation consecutive line count register (.hlc): Manipulating Hyphenation
hyphenation consecutive line limit register (.hlm): Manipulating Hyphenation
hyphenation exceptions: Manipulating Hyphenation
hyphenation language register (.hla): Manipulating Hyphenation
hyphenation margin (hym): Manipulating Hyphenation
hyphenation margin register (.hym): Manipulating Hyphenation
hyphenation mode register (.hy): Manipulating Hyphenation
hyphenation parameters, automatic: Manipulating Hyphenation
hyphenation pattern files: Manipulating Hyphenation
hyphenation patterns (hpf): Manipulating Hyphenation
hyphenation space (hys): Manipulating Hyphenation
hyphenation space adjustment threshold: Manipulating Hyphenation
hyphenation space adjustment threshold register (.hys): Manipulating Hyphenation
hyphenation, automatic: Manipulating Hyphenation
hyphenation, disabling (\%): Manipulating Hyphenation
hyphenation, explicit: Manipulating Hyphenation
hyphenation, incompatibilities with AT&T troff: Other Differences
hyphenation, manipulating: Manipulating Hyphenation
hyphenation, manual: Manipulating Hyphenation

I
i scaling unit: Measurements
i/o: I/O
IBM code page 1047 input encoding: Input Encodings
IBM code page 1047 output encoding: Groff Options
identifiers: Identifiers
identifiers, undefined: Identifiers
ie request, and font translations: Selecting Fonts
ie request, and warnings: Warnings
ie request, operators to use with: Operators in Conditionals
if request, and font translations: Selecting Fonts
if request, and the ‘!’ operator: Numeric Expressions
if request, operators to use with: Operators in Conditionals
if-else: if-else
if-then: if-then
imitating boldface (bd): Artificial Fonts
implementation differences: Implementation Differences
implicit line break: Breaking
implicit trap: The Implicit Page Trap
in request, causing implicit break: Manipulating Filling and Adjustment
in request, using + and - with: Numeric Expressions
inch scaling unit (i): Measurements
including a file (so): I/O
incompatibilities with AT&T troff: Implementation Differences
increment value without changing the register: Auto-increment
incrementation, automatic, of a register: Auto-increment
indentation (in): Line Layout
indentation, of roff source code: Invoking Requests
index, in macro package: Indexing
indicator, scaling: Measurements
indirect assignments: Interpolating Registers
input and output requests: I/O
input characters and output glyphs, compatibility with AT&T troff: Other Differences
input characters, invalid: Identifiers
input conventions: Input Conventions
input encoding, code page 1047: Input Encodings
input encoding, EBCDIC: Input Encodings
input encoding, Latin-1 (ISO 8859-1): Input Encodings
input encoding, Latin-2 (ISO 8859-2): Input Encodings
input encoding, Latin-5 (ISO 8859-9): Input Encodings
input encoding, Latin-9 (ISO 8859-15): Input Encodings
input file name, current, register (.F): Built-in Registers
input level: Calling Macros
input level in delimited arguments: Compatibility Mode
input line continuation (\RET): Line Continuation
input line number register (.c, c.): Built-in Registers
input line number, setting (lf): Debugging
input line position, horizontal, saving (\k): Page Motions
input line trap, clearing (it, itc): Input Line Traps
input line trap, setting (it, itc): Input Line Traps
input line traps: Input Line Traps
input line traps and interrupted lines (itc): Input Line Traps
input line, horizontal position, register (hp): Page Motions
input line, productive: Manipulating Filling and Adjustment
input stack, backtrace (backtrace): Debugging
input stack, setting limit: Debugging
input token: Gtroff Internals
input, 8-bit: Font Description File Format
input, standard, reading from (rd): I/O
inserting horizontal space (\h): Page Motions
installation: Installation
instructing the formatter: Formatter Instructions
inter-sentence space size register (.sss): Manipulating Filling and Adjustment
inter-sentence space, additional: Manipulating Filling and Adjustment
inter-word spacing, minimal: Manipulating Filling and Adjustment
interactive use of gtroff: Debugging
intercepting requests: Control Characters
intermediate output: gtroff Output
interpolating registers (\n): Interpolating Registers
interpolation: Requests and Macros
interpolation depth: Calling Macros
interpolation depth in delimited arguments: Compatibility Mode
interpolation of strings (\*): Strings
interpretation mode: Copy Mode
interrupted line: Line Continuation
interrupted line register (.int): Line Continuation
interrupted lines and input line traps (itc): Input Line Traps
introduction: Introduction
invalid characters for trf request: I/O
invalid input characters: Identifiers
invocation examples: Invocation Examples
invoking groff: Invoking groff
invoking requests: Invoking Requests
ISO 646 output encoding: Groff Options
ISO 8859-1 (Latin-1) output encoding: Groff Options
ISO 8859-1 (Latin-1), input encoding: Input Encodings
ISO 8859-15 (Latin-9), input encoding: Input Encodings
ISO 8859-2 (Latin-2), input encoding: Input Encodings
ISO 8859-9 (Latin-5), input encoding: Input Encodings
italic correction (\/): Italic Corrections

J
justifying text: Manipulating Filling and Adjustment
justifying text (rj): Manipulating Filling and Adjustment

K
keep, floating: Displays and Keeps
keeps (introduction): Displays and Keeps
keeps [ms]: ms keeps and displays
keeps, and footnotes [ms]: ms Footnotes
kerning and ligatures: Ligatures and Kerning
kerning enabled register (.kern): Ligatures and Kerning
kerning, activating (kern): Ligatures and Kerning
kerning, track: Ligatures and Kerning

L
landscape page orientation: Paper Format
language [ms]: ms language and localization
last glyph, dimensions (.w, .cht, .cdp, .csk): Environments
last-requested point size registers (.psr, .sr): Using Fractional Type Sizes
last-requested type size registers (.psr, .sr): Using Fractional Type Sizes
Latin-1 (ISO 8859-1) output encoding: Groff Options
Latin-1 (ISO 8859-1), input encoding: Input Encodings
Latin-2 (ISO 8859-2), input encoding: Input Encodings
Latin-5 (ISO 8859-9), input encoding: Input Encodings
Latin-9 (ISO 8859-15), input encoding: Input Encodings
layout, line: Line Layout
layout, page: Page Layout
lc request, and glyph definitions: Using Symbols
leader character: Tabs and Leaders
leader character: Leaders
leader character, and translations: Character Translations
leader character, non-interpreted (\a): Leaders
leader repetition character (lc): Leaders
leaders: Leaders
leading: Manipulating Type Size and Vertical Spacing
leading space macro (lsm): Breaking
leading space traps: Leading Space Traps
leading spaces: Breaking
leading spaces macro (lsm): Leading Space Traps
leading spaces with ds: Strings
left italic correction (\,): Italic Corrections
left margin (po): Line Layout
length of a string (length): Strings
length of line (ll): Line Layout
length of previous line (.n): Environments
length of the page, configuring (pl): Page Layout
length of title line, configuring (lt): Page Layout
length request, and copy mode: Strings
less than (or equal to) operator: Numeric Expressions
letters, form: I/O
level, input: Calling Macros
level, suppression nesting, register: Suppressing Output
lf request, incompatibilities with AT&T troff: Other Differences
ligature: Using Symbols
ligatures and kerning: Ligatures and Kerning
ligatures enabled register (.lg): Ligatures and Kerning
ligatures, activating (lg): Ligatures and Kerning
limitations of \b escape sequence: Drawing Geometric Objects
line break: Manipulating Filling and Adjustment
line break (introduction): Basics
line break, output: Breaking
line control: Line Continuation
line dimensions: Line Layout
line drawing glyph: Drawing Geometric Objects
line drawing glyph: Drawing Geometric Objects
line indentation (in): Line Layout
line layout: Line Layout
line length (ll): Line Layout
line length register (.l): Line Layout
line length, previous (.n): Environments
line number, input, register (.c, c.): Built-in Registers
line number, output, register (ln): Miscellaneous
line numbers, printing (nm): Miscellaneous
line space, extra post-vertical (\x): Changing the Vertical Spacing
line space, extra pre-vertical (\x): Changing the Vertical Spacing
line spacing register (.L): Manipulating Spacing
line spacing, post-vertical (pvs): Changing the Vertical Spacing
line thickness (‘\D't …'’): Drawing Geometric Objects
line, blank: Breaking
line, drawing (‘\D'l …'’): Drawing Geometric Objects
line, horizontal, drawing (\l): Drawing Geometric Objects
line, input, continuation (\RET): Line Continuation
line, input, horizontal position, register (hp): Page Motions
line, input, horizontal position, saving (\k): Page Motions
line, interrupted: Line Continuation
line, output, continuation (\c): Line Continuation
line, output, horizontal position, register (.k): Page Motions
line, productive input: Manipulating Filling and Adjustment
line, vertical, drawing (\L): Drawing Geometric Objects
line-tabs mode: Tabs and Fields
lines, blank, disabling: Manipulating Spacing
lines, centering (ce): Manipulating Filling and Adjustment
lines, centering (introduction): Basics
lines, consecutive hyphenated (hlm): Manipulating Hyphenation
lines, interrupted, and input line traps (itc): Input Line Traps
lines, right-aligning (introduction): Basics
lines, right-justifying (introduction): Basics
list of special characters (groff_char(7) man page): Using Symbols
listing page location traps (ptr): Debugging
lists: Paragraphs
ll request, using + and - with: Numeric Expressions
localization: Manipulating Hyphenation
localization [ms]: ms language and localization
locating macro files: Macro Directories
locating macro packages: Macro Directories
location, vertical, page, marking (mk): Page Motions
location, vertical, page, returning to marked (rt): Page Motions
logical “and” operator: Numeric Expressions
logical “or” operator: Numeric Expressions
logical complementation operator: Numeric Expressions
logical conjunction operator: Numeric Expressions
logical disjunction operator: Numeric Expressions
logical not, limitation in expression: Numeric Expressions
logical operators: Numeric Expressions
long names: Compatibility Mode
loops and conditionals: Conditionals and Loops
lowercasing a string (stringdown): Strings
ls request, alternative to (pvs): Changing the Vertical Spacing
lt request, using + and - with: Numeric Expressions

M
m scaling unit: Measurements
M scaling unit: Measurements
machine units: Page Geometry
macro: Requests and Macros
macro arguments: Calling Macros
macro arguments, and compatibility mode: Gtroff Internals
macro arguments, and tabs: Invoking Requests
macro directories: Macro Directories
macro file search path: Macro Directories
macro name register (\$0): Parameters
macro names, starting with [ or ], and refer: Identifiers
macro package: Macro Packages
macro package search path: Macro Directories
macro package usage, basics of: Basics
macro package, auxiliary: Major Macro Packages
macro package, full-service: Major Macro Packages
macro package, introduction: Macro Package Intro
macro package, major: Major Macro Packages
macro package, minor: Major Macro Packages
macro package, structuring the source of: Invoking Requests
macro, appending to (am): Writing Macros
macro, creating alias for (als): Strings
macro, end-of-input (em): End-of-input Traps
macro, parameters (\$): Parameters
macro, removing (rm): Strings
macro, removing alias for (rm): Strings
macro, renaming (rn): Strings
macros, recursive: while
macros, searching: Macro Directories
macros, shared name space with strings and diversions: Identifiers
macros, tutorial for users: Tutorial for Macro Users
macros, writing: Writing Macros
magnification of a font (fzoom): Selecting Fonts
major macro package: Major Macro Packages
major version number register (.x): Built-in Registers
man macros, custom headers and footers: Optional man extensions
man macros, Ultrix-specific: Optional man extensions
man pages: man
manipulating filling and adjustment: Manipulating Filling and Adjustment
manipulating hyphenation: Manipulating Hyphenation
manipulating spacing: Manipulating Spacing
manipulating type size and vertical spacing: Manipulating Type Size and Vertical Spacing
manual hyphenation: Manipulating Hyphenation
manual pages: man
margin for hyphenation (hym): Manipulating Hyphenation
margin glyph (mc): Miscellaneous
margin, bottom: Page Location Traps
margin, left (po): Line Layout
margin, right: Line Layout
margin, top: Page Location Traps
mark, high-water, register (.h): Diversions
marker, footnote [ms]: ms Footnotes
marking vertical page location (mk): Page Motions
maximum operator: Numeric Expressions
maximum value representable with Roman numerals: Assigning Register Formats
mdoc macros: mdoc
me macro package: me
measurement units: Measurements
measurements: Measurements
measurements, specifying safely: Default Units
metrics, font: Using Fonts
minimal inter-word spacing: Manipulating Filling and Adjustment
minimum operator: Numeric Expressions
minimum value representable with Roman numerals: Assigning Register Formats
minor macro package: Major Macro Packages
minor version number register (.y): Built-in Registers
minutes, current time (minutes): Built-in Registers
mm macro package: mm
mode for constant glyph space (cs): Artificial Fonts
mode, compatibility: Compatibility Mode
mode, compatibility, and parameters: Gtroff Internals
mode, copy: Copy Mode
mode, copy: Copy Mode
mode, copy, and cf request: I/O
mode, copy, and device request: Postprocessor Access
mode, copy, and length request: Strings
mode, copy, and macro parameters: Parameters
mode, copy, and output request: Diversions
mode, copy, and trf request: I/O
mode, copy, and write request: I/O
mode, copy, and writec request: I/O
mode, copy, and writem request: I/O
mode, copy, and \!: Diversions
mode, copy, and \?: Operators in Conditionals
mode, copy, and \?: Diversions
mode, copy, and \a: Leaders
mode, copy, and \t: Tabs and Fields
mode, copy, and \V: I/O
mode, fill (fi), enabling: Manipulating Filling and Adjustment
mode, fill, and break warnings: Warnings
mode, fill, and inter-sentence space: Manipulating Filling and Adjustment
mode, fill, and \c: Line Continuation
mode, fill, disabling: Manipulating Filling and Adjustment
mode, interpretation: Copy Mode
mode, line-tabs: Tabs and Fields
mode, no-fill: Manipulating Filling and Adjustment
mode, no-fill, and \c: Line Continuation
mode, no-space (ns): Manipulating Spacing
mode, nroff: troff and nroff Modes
mode, safer: Groff Options
mode, safer: Macro Directories
mode, safer: Built-in Registers
mode, safer: I/O
mode, safer: I/O
mode, safer: I/O
mode, safer: I/O
mode, safer: Safer Mode
mode, troff: troff and nroff Modes
mode, unsafe: Groff Options
mode, unsafe: Macro Directories
mode, unsafe: Built-in Registers
mode, unsafe: I/O
mode, unsafe: I/O
mode, unsafe: I/O
mode, unsafe: I/O
modifying requests: Control Characters
modulus: Numeric Expressions
mom macro package: mom
month of the year register (mo): Built-in Registers
motion operators: Numeric Expressions
motion quanta: Motion Quanta
motion quantum, horizontal: DESC File Format
motion quantum, horizontal, register (.H): Motion Quanta
motion quantum, vertical: DESC File Format
motion, horizontal (\h): Page Motions
motion, vertical (\v): Page Motions
motions, page: Page Motions
mounting a font (fp): Font Positions
mounting position: Using Fonts
mounting position: Using Fonts
mounting, font, automatic: Selecting Fonts
ms macros: ms
ms macros, accent marks: ms Legacy Features
ms macros, body text: ms Body Text
ms macros, creating table of contents: ms TOC
ms macros, displays: ms keeps and displays
ms macros, document control settings: ms Document Control Settings
ms macros, document description: ms Document Description Macros
ms macros, equations: ms Insertions
ms macros, figures: ms Insertions
ms macros, footers: ms Headers and Footers
ms macros, footnotes: ms Footnotes
ms macros, fractional type sizes in: Differences from AT&T ms
ms macros, general structure: ms Document Structure
ms macros, groff differences from AT&T: Differences from AT&T ms
ms macros, headers: ms Headers and Footers
ms macros, headings: Headings in ms
ms macros, keeps: ms keeps and displays
ms macros, language: ms language and localization
ms macros, lists: Lists in ms
ms macros, localization: ms language and localization
ms macros, margins: ms Margins
ms macros, multiple columns: ms Multiple Columns
ms macros, naming conventions: ms Naming Conventions
ms macros, nested lists: Indented regions in ms
ms macros, obtaining typographical symbols: Typographical symbols in ms
ms macros, page layout: ms Page Layout
ms macros, paragraph handling: Paragraphs in ms
ms macros, references: ms Insertions
ms macros, special characters: ms Legacy Features
ms macros, strings: ms Legacy Features
ms macros, tables: ms Insertions
ms macros, text settings: Text settings in ms
multi-file documents: Debugging
multi-line strings: Strings
multi-page table example [ms]: ms Insertions
multiple columns [ms]: ms Multiple Columns
multiplication: Numeric Expressions

N
n scaling unit: Measurements
name space, common, of macros, diversions, and strings: Identifiers
name, background color, register (.M): Colors
name, fill color, register (.M): Colors
name, stroke color, register (.m): Colors
named character (\C): Using Symbols
names, long: Compatibility Mode
naming conventions, ms macros: ms Naming Conventions
ne request, and the .trunc register: Page Location Traps
ne request, comparison with sv: Page Control
negating register values: Setting Registers
negation: Numeric Expressions
nested assignments: Interpolating Registers
nested diversions: Diversions
nested lists [ms]: Indented regions in ms
nesting level, suppression, register: Suppressing Output
new page (bp): Page Control
newline character, and translations: Character Translations
newline character, in strings, escaping: Strings
newline, as delimiter: Delimiters
newline, final, stripping in diversions: Punning Names
next file, processing (nx): I/O
next free font position register (.fp): Font Positions
next page number register (.pn): Page Layout
next page number, configuring (pn): Page Layout
nf request, causing implicit break: Manipulating Filling and Adjustment
nl register, and .d: Diversions
nl register, difference from .h: Diversions
nm request, using + and - with: Numeric Expressions
no-break control character ('): Requests and Macros
no-break control character, changing (c2): Control Characters
no-fill mode: Manipulating Filling and Adjustment
no-fill mode, and \c: Line Continuation
no-space mode (ns): Manipulating Spacing
node, output: Gtroff Internals
non-printing break point (\:): Manipulating Hyphenation
nr request, and warnings: Warnings
nr request, using + and - with: Numeric Expressions
nroff mode: troff and nroff Modes
number formats, assigning to register (af): Assigning Register Formats
number of registers register (.R): Built-in Registers
number, input line, setting (lf): Debugging
number, page, next, configuring (pn): Page Layout
numbered glyph (\N): Character Translations
numbered glyph (\N): Using Symbols
numbered list, example markup [ms]: Lists in ms
numbers, line, printing (nm): Miscellaneous
numeral-width space (\0): Page Motions
numerals, as delimiters: Delimiters
numerals, Roman: Assigning Register Formats
numeric expression, valid: Numeric Expressions
numeric expressions: Numeric Expressions

O
object creation: Writing Macros
offset, page: Page Geometry
offset, page (po): Line Layout
open request, and safer mode: Groff Options
opena request, and safer mode: Groff Options
opening brace escape sequence (\}): Conditional Blocks
opening file (open): I/O
operator, scaling: Numeric Expressions
operators, arithmetic: Numeric Expressions
operators, as delimiters: Delimiters
operators, comparison: Numeric Expressions
operators, extremum (>?, <?): Numeric Expressions
operators, logical: Numeric Expressions
operators, motion: Numeric Expressions
operators, unary arithmetic: Numeric Expressions
optical size of a font: Selecting Fonts
options: Groff Options
order of evaluation in expressions: Numeric Expressions
ordinary character: Identifiers
orientation, landscape: Paper Format
orphan: Page Control
orphan lines, preventing with ne: Page Control
os request, and no-space mode: Page Control
outlined circle, drawing (‘\D'c …'’): Drawing Geometric Objects
outlined ellipse, drawing (‘\D'e …'’): Drawing Geometric Objects
outlined polygon, drawing (‘\D'p …'’): Drawing Geometric Objects
output and input requests: I/O
output comparison operator: Operators in Conditionals
output device name string (.T): Groff Options
output device name string (.T): Strings
output device name string (.T), in other implementations: Other Differences
output device usage register (.T): Groff Options
output device usage register (.T), incompatibility with AT&T troff: Other Differences
output devices: Output Device Intro
output encoding, ASCII: Groff Options
output encoding, code page 1047: Groff Options
output encoding, EBCDIC: Groff Options
output encoding, ISO 646: Groff Options
output encoding, Latin-1 (ISO 8859-1): Groff Options
output encoding, UTF-8: Groff Options
output glyphs, and input characters, compatibility with AT&T troff: Other Differences
output line break: Breaking
output line number register (ln): Miscellaneous
output line properties: Manipulating Filling and Adjustment
output line, continuation (\c): Line Continuation
output line, horizontal position, register (.k): Page Motions
output node: Gtroff Internals
output request, and copy mode: Diversions
output request, and \!: Diversions
output, filling, disablement of (nf): Manipulating Filling and Adjustment
output, filling, enablement of (fi): Manipulating Filling and Adjustment
output, flush (fl): Debugging
output, gtroff: gtroff Output
output, intermediate: gtroff Output
output, suppressing (\O): Suppressing Output
output, transparent (cf, trf): I/O
output, transparent (\!, \?): Diversions
output, transparent, incompatibilities with AT&T troff: Other Differences
output, troff: gtroff Output
overlapping characters: Using Symbols
overstriking glyphs (\o): Page Motions

P
p scaling unit: Measurements
P scaling unit: Measurements
package, macro: Macro Packages
package, macro, auxiliary: Major Macro Packages
package, macro, full-service: Major Macro Packages
package, macro, introduction: Macro Package Intro
package, macro, major: Major Macro Packages
package, macro, minor: Major Macro Packages
package, macro, search path: Macro Directories
package, package, structuring the source of: Invoking Requests
padding character, for fields (fc): Fields
page: Page Geometry
page break: Page Geometry
page break: Page Control
page break: The Implicit Page Trap
page break (introduction): Basics
page break, conditional (ne): Page Control
page break, final: End-of-input Traps
page break, prevented by vpt: Vertical Position Traps
page control: Page Control
page ejection: Page Geometry
page ejection: Page Control
page ejection: The Implicit Page Trap
page ejection status register (.pe): Page Location Traps
page ejection, of final page: End-of-input Traps
page ejection, prevented by vpt: Vertical Position Traps
page footers: Page Location Traps
page headers: Page Location Traps
page layout: Page Layout
page layout [ms]: ms Page Layout
page length register (.p): Page Layout
page length, configuring (pl): Page Layout
page location traps: Page Location Traps
page location traps, debugging: Page Location Traps
page location, vertical, marking (mk): Page Motions
page location, vertical, returning to marked (rt): Page Motions
page motions: Page Motions
page number character (%): Page Layout
page number character, changing (pc): Page Layout
page number register (%): Page Control
page number, configuring next (pn): Page Layout
page number, next, register (.pn): Page Layout
page offset: Page Geometry
page offset (po): Line Layout
page orientation, landscape: Paper Format
page, geometry of: Page Geometry
page, new (bp): Page Control
paper format: Paper Format
paper size: Paper Format
paragraphs: Paragraphs
parameter count register (.$): Parameters
parameters: Parameters
parameters, and compatibility mode: Gtroff Internals
parameters, macro (\$): Parameters
parentheses: Numeric Expressions
partially collected line: Manipulating Filling and Adjustment
path, for font files: Font Directories
path, for tmac files: Macro Directories
pattern files, for hyphenation: Manipulating Hyphenation
patterns for hyphenation (hpf): Manipulating Hyphenation
pending output line: Manipulating Filling and Adjustment
pi request, and groff: I/O
pi request, and safer mode: Groff Options
pi request, disabled by default: Safer Mode
pica scaling unit (P): Measurements
PID of GNU troff register ($$): Built-in Registers
pile, glyph (\b): Drawing Geometric Objects
pl request, using + and - with: Numeric Expressions
plain text approximation output register (.A): Groff Options
plain text approximation output register (.A): Built-in Registers
planting a trap: Traps
platform-specific directory: Macro Directories
pm request, incompatibilities with AT&T troff: Other Differences
pn request, using + and - with: Numeric Expressions
PNG image generation from PostScript: DESC File Format
po request, using + and - with: Numeric Expressions
point scaling unit (p): Measurements
point size registers (.s, .ps): Changing the Type Size
point size registers, last-requested (.psr, .sr): Using Fractional Type Sizes
point sizes, changing (ps, \s): Changing the Type Size
point sizes, fractional: Using Fractional Type Sizes
point sizes, fractional: Other Differences
polygon, filled, drawing (‘\D'P …'’): Drawing Geometric Objects
polygon, outlined, drawing (‘\D'p …'’): Drawing Geometric Objects
polygon, solid, drawing (‘\D'P …'’): Drawing Geometric Objects
polygon, stroked, drawing (‘\D'p …'’): Drawing Geometric Objects
position of lowest text line (.h): Diversions
position, absolute (sic) operator (|): Numeric Expressions
position, drawing: Page Geometry
position, horizontal input line, saving (\k): Page Motions
position, horizontal, in input line, register (hp): Page Motions
position, horizontal, in output line, register (.k): Page Motions
position, mounting: Using Fonts
position, vertical, in diversion, register (.d): Diversions
positions, font: Font Positions
post-vertical line spacing: Changing the Vertical Spacing
post-vertical line spacing register (.pvs): Changing the Vertical Spacing
post-vertical line spacing, changing (pvs): Changing the Vertical Spacing
postprocessor access: Postprocessor Access
postprocessors: Output Device Intro
PostScript, bounding box: Miscellaneous
PostScript, PNG image generation: DESC File Format
prefix, for commands: Environment
preprocessors: Preprocessor Intro
previous font, selecting (ft): Selecting Fonts
previous font, selecting (\f[], \fP): Selecting Fonts
previous line length (.n): Environments
print current page register (.P): Groff Options
printing backslash (\\, \e, \E, \[rs]): Other Differences
printing line numbers (nm): Miscellaneous
printing to stderr (tm, tm1, tmc): Debugging
printing, zero-width (\z, \Z): Page Motions
printing, zero-width (\z, \Z): Page Motions
process ID of GNU troff register ($$): Built-in Registers
processing next file (nx): I/O
productive input line: Manipulating Filling and Adjustment
properties of characters (cflags): Using Symbols
properties of glyphs (cflags): Using Symbols
properties of output lines: Manipulating Filling and Adjustment
ps request, and constant glyph space mode: Artificial Fonts
ps request, incompatibilities with AT&T troff: Other Differences
ps request, using + and - with: Numeric Expressions
ps request, with fractional type sizes: Using Fractional Type Sizes
pso request, and safer mode: Groff Options
pvs request, using + and - with: Numeric Expressions

Q
quanta, motion: Motion Quanta
quantum, horizontal motion: DESC File Format
quantum, vertical motion: DESC File Format

R
radicalex glyph, and cflags: Using Symbols
ragged-left text: Manipulating Filling and Adjustment
ragged-right text: Manipulating Filling and Adjustment
rc request, and glyph definitions: Using Symbols
read-only register removal, incompatibility with AT&T troff: Other Differences
read-only register, changing format: Assigning Register Formats
reading from standard input (rd): I/O
recursive macros: while
refer, and macro names starting with [ or ]: Identifiers
reference, gtroff: GNU troff Reference
references [ms]: ms Insertions
register format, in expressions: Assigning Register Formats
register, assigning number format to (af): Assigning Register Formats
register, built-in, removing: Built-in Registers
register, creating alias for (aln): Setting Registers
register, format (\g): Assigning Register Formats
register, read-only, removal, incompatibility with AT&T troff: Other Differences
register, removing (rr): Setting Registers
register, removing alias for (rr): Setting Registers
register, renaming (rnn): Setting Registers
registers: Registers
registers, built-in: Built-in Registers
registers, dumping (pnr): Debugging
registers, interpolating (\n): Interpolating Registers
registers, number of, register (.R): Built-in Registers
registers, setting (nr, \R): Setting Registers
removal of read-only registers, incompatibility with AT&T troff: Other Differences
removing a built-in register: Built-in Registers
removing a register (rr): Setting Registers
removing alias for register (rr): Setting Registers
removing alias, for diversion (rm): Strings
removing alias, for macro (rm): Strings
removing alias, for string (rm): Strings
removing diversion (rm): Strings
removing glyph definition (rchar, rfschar): Using Symbols
removing macro (rm): Strings
removing request (rm): Strings
removing string (rm): Strings
renaming a register (rnn): Setting Registers
renaming diversion (rn): Strings
renaming macro (rn): Strings
renaming request (rn): Strings
renaming string (rn): Strings
renditions, graphic: Using Fonts
request: Requests and Macros
request: Formatter Instructions
request arguments: Invoking Requests
request arguments, and compatibility mode: Gtroff Internals
request arguments, and tabs: Invoking Requests
request, removing (rm): Strings
request, renaming (rn): Strings
request, undefined: Comments
requests for drawing: Drawing Geometric Objects
requests for input and output: I/O
requests, intercepting: Control Characters
requests, invoking: Invoking Requests
requests, modifying: Control Characters
resolution, device: Page Geometry
resolution, device: DESC File Format
resolution, device, obtaining in the formatter: Measurements
resolution, horizontal: DESC File Format
resolution, horizontal, register (.H): Motion Quanta
resolution, vertical: DESC File Format
returning to marked vertical page location (rt): Page Motions
revision number register (.Y): Built-in Registers
right margin: Line Layout
right-aligning lines (introduction): Basics
right-justifying (rj): Manipulating Filling and Adjustment
right-justifying lines (introduction): Basics
rivers: Other Differences
rj request, causing implicit break: Manipulating Filling and Adjustment
rn glyph, and cflags: Using Symbols
roman glyph, correction after italic glyph (\/): Italic Corrections
roman glyph, correction before italic glyph (\,): Italic Corrections
Roman numerals: Assigning Register Formats
Roman numerals, extrema (maximum and minimum): Assigning Register Formats
rq glyph, at end of sentence: Sentences
rq glyph, at end of sentence: Using Symbols
rt request, using + and - with: Numeric Expressions
ru glyph, and cflags: Using Symbols
running system commands: I/O

S
s scaling unit: Using Fractional Type Sizes
safer mode: Groff Options
safer mode: Macro Directories
safer mode: Built-in Registers
safer mode: I/O
safer mode: I/O
safer mode: I/O
safer mode: I/O
safer mode: Safer Mode
saving horizontal input line position (\k): Page Motions
scaling indicator: Measurements
scaling operator: Numeric Expressions
scaling unit c: Measurements
scaling unit f: Colors
scaling unit i: Measurements
scaling unit m: Measurements
scaling unit M: Measurements
scaling unit n: Measurements
scaling unit p: Measurements
scaling unit P: Measurements
scaling unit s: Using Fractional Type Sizes
scaling unit u: Measurements
scaling unit v: Measurements
scaling unit z: Using Fractional Type Sizes
searching fonts: Font Directories
searching macros: Macro Directories
seconds, current time (seconds): Built-in Registers
selecting the previous font (ft): Selecting Fonts
sentence space: Sentences
sentence space size register (.sss): Manipulating Filling and Adjustment
sentences: Sentences
sequence, escape: Formatter Instructions
setting diversion trap (dt): Diversion Traps
setting end-of-input trap (em): End-of-input Traps
setting input line number (lf): Debugging
setting input line trap (it, itc): Input Line Traps
setting registers (nr, \R): Setting Registers
setting the page length (pl): Page Layout
setting up an abstract font style (sty): Font Families
shc request, and translations: Character Translations
site-local directory: Macro Directories
site-local directory: Font Directories
size of sentence space register (.sss): Manipulating Filling and Adjustment
size of word space register (.ss): Manipulating Filling and Adjustment
size, optical, of a font: Selecting Fonts
size, paper: Paper Format
size, size: Manipulating Type Size and Vertical Spacing
sizes, fractional: Other Differences
sizes, fractional type: Using Fractional Type Sizes
skew, of last glyph (.csk): Environments
slant, font, changing (\S): Artificial Fonts
soft hyphen character, setting (shc): Manipulating Hyphenation
soft hyphen glyph (hy): Manipulating Hyphenation
solid circle, drawing (‘\D'C …'’): Drawing Geometric Objects
solid ellipse, drawing (‘\D'E …'’): Drawing Geometric Objects
solid polygon, drawing (‘\D'P …'’): Drawing Geometric Objects
SOURCE_DATE_EPOCH, environment variable: Environment
sp request, and no-space mode: Manipulating Spacing
sp request, causing implicit break: Manipulating Filling and Adjustment
space between sentences: Sentences
space between sentences register (.sss): Manipulating Filling and Adjustment
space between words register (.ss): Manipulating Filling and Adjustment
space character, as delimiter: Delimiters
space characters, in expressions: Numeric Expressions
space, between sentences: Manipulating Filling and Adjustment
space, between words: Manipulating Filling and Adjustment
space, discardable, horizontal: Manipulating Filling and Adjustment
space, hair (\^): Page Motions
space, horizontal (\h): Page Motions
space, horizontal, unformatting: Punning Names
space, thin (\|): Page Motions
space, unbreakable (\~): Manipulating Filling and Adjustment
space, unbreakable and unadjustable (\SP): Page Motions
space, vertical, unit (v): Measurements
space, width of a digit (numeral) (\0): Page Motions
spaces with ds: Strings
spaces, in a macro argument: Calling Macros
spaces, leading and trailing: Breaking
spacing (introduction): Basics
spacing, manipulating: Manipulating Spacing
spacing, vertical: Page Geometry
spacing, vertical: Manipulating Type Size and Vertical Spacing
spacing, vertical (introduction): Basics
special characters: Sentences
special characters: Character Translations
special characters [ms]: ms Legacy Features
special characters, list of (groff_char(7) man page): Using Symbols
special font: Using Fonts
special fonts: Using Symbols
special fonts: Special Fonts
special fonts: Font Description File Format
special fonts, emboldening: Artificial Fonts
special request, and font translations: Selecting Fonts
special request, and glyph search order: Using Symbols
spline, drawing (‘\D'~ …'’): Drawing Geometric Objects
springing a trap: Traps
sqrtex glyph, and cflags: Using Symbols
ss request, incompatibilities with AT&T troff: Other Differences
stack: Environments
stacking glyphs (\b): Drawing Geometric Objects
standard input, reading from (rd): I/O
stderr, printing to (tm, tm1, tmc): Debugging
stops, tab: Tabs and Leaders
string arguments: Strings
string comparison: Operators in Conditionals
string expansion (\*): Strings
string interpolation (\*): Strings
string, appending (as): Strings
string, creating alias for (als): Strings
string, length of (length): Strings
string, removing (rm): Strings
string, removing alias for (rm): Strings
string, renaming (rn): Strings
strings: Strings
strings [ms]: ms Legacy Features
strings, multi-line: Strings
strings, shared name space with macros and diversions: Identifiers
stripping final newline in diversions: Punning Names
stroke color: Colors
stroke color name register (.m): Colors
stroked circle, drawing (‘\D'c …'’): Drawing Geometric Objects
stroked ellipse, drawing (‘\D'e …'’): Drawing Geometric Objects
stroked polygon, drawing (‘\D'p …'’): Drawing Geometric Objects
structuring source code of documents or macro packages: Invoking Requests
sty request, and changing fonts: Selecting Fonts
sty request, and font translations: Selecting Fonts
style, font: Using Fonts
style, font, abstract: Using Fonts
style, font, abstract, setting up (sty): Font Families
styles, font: Font Families
substring (substring): Strings
subtraction: Numeric Expressions
suppressing output (\O): Suppressing Output
suppression nesting level register: Suppressing Output
sv request, and no-space mode: Page Control
switching environments (ev): Environments
sy request, and safer mode: Groff Options
sy request, disabled by default: Safer Mode
symbol: Using Symbols
symbol table, dumping (pm): Debugging
symbol, defining (char): Using Symbols
symbols, using: Using Symbols
system commands, running: I/O
system() return value register (systat): I/O

T
tab character: Tabs and Leaders
tab character encoding: Tabs and Fields
tab character, and translations: Character Translations
tab character, as delimiter: Delimiters
tab character, non-interpreted (\t): Tabs and Fields
tab repetition character (tc): Tabs and Fields
tab stop settings register (.tabs): Tabs and Fields
tab stops: Tabs and Leaders
tab stops, default: Tabs and Fields
tab, line-tabs mode: Tabs and Fields
table of contents: Table of Contents
table of contents: Leaders
table of contents, creating [ms]: ms TOC
table, multi-page, example [ms]: ms Insertions
tables [ms]: ms Insertions
tabs, and fields: Tabs and Fields
tabs, and macro arguments: Invoking Requests
tabs, and request arguments: Invoking Requests
tabs, before comments: Comments
tagged paragraphs: Paragraphs
tags, paragraph: Paragraphs
terminal, conditional output for: Operators in Conditionals
text baseline: Page Geometry
text baseline: Manipulating Type Size and Vertical Spacing
text font: Using Fonts
text line: Requests and Macros
text line, position of lowest (.h): Diversions
text, GNU troff processing: Text
text, justifying: Manipulating Filling and Adjustment
text, justifying (rj): Manipulating Filling and Adjustment
thickness of lines (‘\D't …'’): Drawing Geometric Objects
thin space (\|): Page Motions
three-part title (tl): Page Layout
ti request, causing implicit break: Manipulating Filling and Adjustment
ti request, using + and - with: Numeric Expressions
time, current, hours (hours): Built-in Registers
time, current, minutes (minutes): Built-in Registers
time, current, seconds (seconds): Built-in Registers
time, formatting: I/O
title length, configuring (lt): Page Layout
title line length register (.lt): Page Layout
title line, formatting (tl): Page Layout
titles: Page Layout
tkf request, and font styles: Font Families
tkf request, and font translations: Selecting Fonts
tkf request, with fractional type sizes: Using Fractional Type Sizes
tl request, and mc: Miscellaneous
tmac, directory: Macro Directories
tmac, path: Macro Directories
TMPDIR, environment variable: Environment
token, input: Gtroff Internals
top margin: Page Location Traps
top-level diversion: Diversions
top-level diversion, and bp: Page Control
top-level diversion, and \!: Diversions
top-level diversion, and \?: Diversions
tr request, and glyph definitions: Using Symbols
tr request, and soft hyphen character: Manipulating Hyphenation
tr request, incompatibilities with AT&T troff: Other Differences
track kerning: Ligatures and Kerning
track kerning, activating (tkf): Ligatures and Kerning
trailing double quotes in strings: Strings
trailing spaces in string definitions and appendments: Strings
trailing spaces on text lines: Breaking
translations of characters: Character Translations
transparent characters: Using Symbols
transparent dummy character (\)): Dummy Characters
transparent output (cf, trf): I/O
transparent output (\!, \?): Diversions
transparent output, incompatibilities with AT&T troff: Other Differences
trap: Deferring Output
trap, changing location (ch): Page Location Traps
trap, distance to next vertical position, register (.t): Page Location Traps
trap, diversion, setting (dt): Diversion Traps
trap, end-of-input, setting (em): End-of-input Traps
trap, implicit: The Implicit Page Trap
trap, input line, clearing (it, itc): Input Line Traps
trap, input line, setting (it, itc): Input Line Traps
trap, planting: Traps
trap, springing: Traps
traps: Traps
traps, and diversions: Page Location Traps
traps, blank line: Blank Line Traps
traps, diversion: Diversion Traps
traps, end-of-input: End-of-input Traps
traps, input line: Input Line Traps
traps, input line, and interrupted lines (itc): Input Line Traps
traps, leading space: Leading Space Traps
traps, page location: Page Location Traps
traps, page location, dumping (ptr): Debugging
traps, page location, listing (ptr): Debugging
traps, sprung by bp request (.pe): Page Location Traps
traps, vertical position: Vertical Position Traps
trf request, and copy mode: I/O
trf request, and invalid characters: I/O
trf request, causing implicit break: Manipulating Filling and Adjustment
trin request, and asciify: Diversions
troff mode: troff and nroff Modes
troff output: gtroff Output
truncated vertical space register (.trunc): Page Location Traps
truncating division: Numeric Expressions
TTY, conditional output for: Operators in Conditionals
tutorial for macro users: Tutorial for Macro Users
type size: Manipulating Type Size and Vertical Spacing
type size registers (.s, .ps): Changing the Type Size
type size registers, last-requested (.psr, .sr): Using Fractional Type Sizes
type sizes, changing (ps, \s): Changing the Type Size
type sizes, fractional: Using Fractional Type Sizes
type sizes, fractional: Other Differences
typeface: Using Fonts
TZ, environment variable: Environment

U
u scaling unit: Measurements
uf request, and font styles: Font Families
ul glyph, and cflags: Using Symbols
ul request, and font translations: Selecting Fonts
Ultrix-specific man macros: Optional man extensions
unadjustable and unbreakable space (\SP): Page Motions
unary arithmetic operators: Numeric Expressions
unbreakable and unadjustable space (\SP): Page Motions
unbreakable space (\~): Manipulating Filling and Adjustment
undefined identifiers: Identifiers
undefined request: Comments
underline font (uf): Artificial Fonts
underlining (ul): Artificial Fonts
underlining, continuous (cu): Artificial Fonts
unformatting diversions (asciify): Diversions
unformatting horizontal space: Punning Names
Unicode: Identifiers
Unicode: Using Symbols
unit, scaling, c: Measurements
unit, scaling, f: Colors
unit, scaling, i: Measurements
unit, scaling, m: Measurements
unit, scaling, M: Measurements
unit, scaling, n: Measurements
unit, scaling, p: Measurements
unit, scaling, P: Measurements
unit, scaling, s: Using Fractional Type Sizes
unit, scaling, u: Measurements
unit, scaling, v: Measurements
unit, scaling, z: Using Fractional Type Sizes
units of measurement: Measurements
units, basic: Page Geometry
units, basic, conversion to: Measurements
units, default: Default Units
units, machine: Page Geometry
unnamed glyphs: Using Symbols
unnamed glyphs, accessing with \N: Font Description File Format
unsafe mode: Groff Options
unsafe mode: Macro Directories
unsafe mode: Built-in Registers
unsafe mode: I/O
unsafe mode: I/O
unsafe mode: I/O
unsafe mode: I/O
unstyled font: Using Fonts
up-casing a string (stringup): Strings
uppercasing a string (stringup): Strings
upright glyph, correction after oblique glyph (\/): Italic Corrections
upright glyph, correction before oblique glyph (\,): Italic Corrections
URLs, breaking (\:): Manipulating Hyphenation
user’s macro tutorial: Tutorial for Macro Users
user’s tutorial for macros: Tutorial for Macro Users
using escape sequences: Using Escape Sequences
using symbols: Using Symbols
UTF-8 output encoding: Groff Options

V
v scaling unit: Measurements
valid numeric expression: Numeric Expressions
value, incrementing without changing the register: Auto-increment
variables in environment: Environment
vee: Page Geometry
vee scaling unit (v): Measurements
version number, major, register (.x): Built-in Registers
version number, minor, register (.y): Built-in Registers
vertical drawing position (nl): Page Control
vertical line drawing (\L): Drawing Geometric Objects
vertical line spacing register (.v): Changing the Vertical Spacing
vertical line spacing, changing (vs): Changing the Vertical Spacing
vertical line spacing, effective value: Changing the Vertical Spacing
vertical motion (\v): Page Motions
vertical motion quantum: DESC File Format
vertical page location, marking (mk): Page Motions
vertical page location, returning to marked (rt): Page Motions
vertical position in diversion register (.d): Diversions
vertical position trap enable register (.vpt): Vertical Position Traps
vertical position traps: Vertical Position Traps
vertical position traps, enabling (vpt): Vertical Position Traps
vertical position, drawing (nl): Page Control
vertical resolution: DESC File Format
vertical space unit (v): Measurements
vertical spacing: Page Geometry
vertical spacing: Manipulating Type Size and Vertical Spacing
vertical spacing (introduction): Basics

W
warning categories: Warnings
warning level (warn): Debugging
warnings: Debugging
warnings: Warnings
what is groff?: What Is groff?
while: while
while request, and font translations: Selecting Fonts
while request, and the ‘!’ operator: Numeric Expressions
while request, confusing with br: while
while request, operators to use with: Operators in Conditionals
widow: Page Control
widow: Page Control
width escape (\w): Page Motions
width, of last glyph (.w): Environments
word space size register (.ss): Manipulating Filling and Adjustment
word, definition of: Filling
write request, and copy mode: I/O
writec request, and copy mode: I/O
writem request, and copy mode: I/O
writing macros: Writing Macros
writing to file (write, writec): I/O

Y
year, current, register (year, yr): Built-in Registers

Z
z scaling unit: Using Fractional Type Sizes
zero-width printing (\z, \Z): Page Motions
zero-width printing (\z, \Z): Page Motions
zoom factor of a font (fzoom): Selecting Fonts

+ +
+ + +
+
+
+
+ +

Footnotes

+ +
(1)
+

The ‘g’ prefix is +not used on all systems; see Invoking groff.

+
(2)
+

Unix and related operating systems distinguish +standard output and standard error streams because of +troff: +https://minnie.tuhs.org/pipermail/tuhs/2013-December/006113.html.

+
(3)
+

See Line Layout.

+
(4)
+

Besides groff, neatroff is an +exception.

+
(5)
+

The +mso request does not have these limitations. See I/O.

+
(6)
+

The remainder of this chapter is based on +Writing Papers with nroff using -me by Eric P. Allman, +which is distributed with groff as meintro.me.

+
(7)
+

While manual pages are older, early ones used +macros supplanted by the man package of Seventh Edition Unix +(1979). ms shipped with Sixth Edition (1975) and was documented +by Mike Lesk in a Bell Labs internal memorandum.

+
(8)
+

defined in Footnotes

+
(9)
+

Distinguish a +document title from “titles”, which are what roff systems call +headers and footers collectively.

+
(10)
+

This idiosyncrasy arose through +feature accretion; for example, the B macro in Version 6 +Unix ms (1975) accepted only one argument, the text to be set in +boldface. By Version 7 (1979) it recognized a second argument; in +1990, groff ms added a “pre” argument, placing it third +to avoid breaking support for older documents.

+
(11)
+

“Portable Document Format Publishing with GNU +Troff”, pdfmark.ms in the groff distribution, uses this +technique.

+
(12)
+

Unix Version 7 ms, its descendants, and GNU +ms prior to groff version 1.23.0

+
(13)
+

You could reset it +after each call to .1C, .2C, or .MC.

+
(14)
+

Typing Documents on the UNIX System: Using the +-ms Macros with Troff and Nroff, M. E. Lesk, Bell Laboratories, +1978

+
(15)
+

Register values are converted to and stored as +basic units. See Measurements.

+
(16)
+

If you redefine the ms PT macro +and desire special treatment of certain page numbers (like ‘1’), +you may need to handle a non-Arabic page number format, as groff +ms’s PT does; see the macro package source. groff +ms aliases the PN register to %.

+
(17)
+

The removal beforehand is necessary +because groff ms aliases these macros to a diagnostic +macro, and you want to redefine the aliased name, not its target.

+
(18)
+

See Device and Font Description Files.

+
(19)
+

Tabs and leaders also separate +words. Escape sequences can function as word characters, word +separators, or neither—the last simply have no effect on GNU +troff’s idea of whether an input character is within a word. +We’ll discuss all of these in due course.

+
(20)
+

A +well-researched jeremiad appreciated by groff contributors on +both sides of the sentence-spacing debate can be found at +https://web.archive.org/web/20171217060354/http://www.heracliteanriver.com/?p=324.

+
(21)
+

This statement oversimplifies; there are +escape sequences whose purpose is precisely to produce glyphs on the +output device, and input characters that aren’t part of escape +sequences can undergo a great deal of processing before getting to the +output.

+
(22)
+

The mnemonics for the special +characters shown here are “dagger”, “double dagger”, “right +(double) quote”, and “closing (single) quote”. See the +groff_char(7) man page.

+
(23)
+

“Text lines” are defined in Requests and Macros.

+
(24)
+

“Tab” +is short for “tabulation”, revealing the term’s origin as a spacing +mechanism for table arrangement.

+
(25)
+

The \RET escape sequence can alter how an +input line is classified; see Line Continuation.

+
(26)
+

Argument handling in +macros is more flexible but also more complex. See Calling Macros.

+
(27)
+

Some escape sequences undergo +interpolation as well.

+
(28)
+

GNU troff offers additional ones. See Writing Macros.

+
(29)
+

Macro files and packages +frequently define registers and strings as well.

+
(30)
+

The +semantics of certain punctuation code points have gotten stricter +with the successive standards, a cause of some frustration among man +page writers; see the groff_char(7) man page.

+
(31)
+

The +DVI output device defaults to using the Computer Modern (CM) fonts; +ec.tmac loads the EC fonts instead, which provide Euro +‘\[Eu]’ and per mille ‘\[%0]’ glyphs.

+
(32)
+

Emacs: fill-column: 72; Vim: textwidth=72

+
(33)
+

groff does not yet support right-to-left +scripts.

+
(34)
+

groff’s terminal output devices have page +offsets of zero.

+
(35)
+

Provision is made for interpreting and +reporting decimal fractions in certain cases.

+
(36)
+

If that’s not enough, see the groff_tmac(5) +man page for the 62bit.tmac macro package.

+
(37)
+

See Conditionals and Loops.

+
(38)
+

Control structure syntax +creates an exception to this rule, but is designed to remain useful: +recalling our example, ‘.if 1 .Underline this’ would underline only +“this”, precisely. See Conditionals and Loops.

+
(39)
+

See Diversions.

+
(40)
+

Historically, control characters like +ASCII STX, ETX, and BEL (Control+B, Control+C, and +Control+G) have been observed in roff documents, +particularly in macro packages employing them as delimiters with the +output comparison operator to try to avoid collisions with the content +of arbitrary user-supplied parameters (see Operators in Conditionals). We discourage this expedient; in GNU troff it is +unnecessary (outside of compatibility mode) because delimited arguments +are parsed at a different input level than the surrounding context. +See Implementation Differences.

+
(41)
+

Consider what happens when a C1 control +0x800x9F is necessary as a continuation byte in a UTF-8 +sequence.

+
(42)
+

Recall Identifiers.

+
(43)
+

In compatibility +mode, a space is not necessary after a request or macro name of two +characters’ length. Also, Plan 9 troff allows tabs to +separate arguments.

+
(44)
+

\~ is fairly +portable; see Other Differences.

+
(45)
+

Strictly, you can neglect to +close the last quoted macro argument, relying on the end of the control +line to do so. We consider this lethargic practice poor style.

+
(46)
+

The omission of spaces before the comment +escape sequences is necessary; see Strings.

+
(47)
+

TeX does have such a mechanism.

+
(48)
+

This claim may be more aspirational than descriptive.

+
(49)
+

See Conditional Blocks.

+
(50)
+

Exception: auto-incrementing registers defined outside +the ignored region will be modified if interpolated with +\ną inside it. See Auto-increment.

+
(51)
+

A negative auto-increment can be +considered an “auto-decrement”.

+
(52)
+

GNU troff dynamically allocates memory for +as many registers as required.

+
(53)
+

unless diverted; see Diversions

+
(54)
+

See Line Continuation.

+
(55)
+

Recall Filling and Sentences for the +definitions of word and sentence boundaries, respectively.

+
(56)
+

Whether a perfect algorithm for this application is +even possible is an unsolved problem in computer science: +https://tug.org/docs/liang/liang-thesis.pdf.

+
(57)
+

\% itself stops marking +hyphenation points but still produces no output glyph.

+
(58)
+

“Soft” because it appears in output +only where a hyphenation break is performed; a “hard” hyphen, as in +“long-term”, always appears.

+
(59)
+

The mode is a vector of Booleans encoded as an integer. +To a programmer, this fact is easily deduced from the exclusive use of +powers of two for the configuration parameters; they are computationally +easy to “mask off” and compare to zero. To almost everyone else, the +arrangement seems recondite and unfriendly.

+
(60)
+

Hyphenation is +prevented if the next page location trap is closer to the vertical +drawing position than the next text baseline would be. See Page Location Traps.

+
(61)
+

For more on localization, see the +groff_tmac(5) man page.

+
(62)
+

See Page Location Traps.

+
(63)
+

See Drawing Geometric Objects.

+
(64)
+

or geometric objects; see Drawing Geometric Objects

+
(65)
+

to the top-level diversion; +see Diversions

+
(66)
+

Plan 9 troff +uses the register .S for this purpose.

+
(67)
+

This is pronounced to rhyme with “feeder”, and +refers to how the glyphs “lead” the eye across the page to the +corresponding page number or other datum.

+
(68)
+

A +GNU nroff program is available for convenience; it calls GNU +troff to perform the formatting.

+
(69)
+

Historically, the \c +escape sequence has proven challenging to characterize. Some sources +say it “connects the next input text” (to the input line on which it +appears); others describe it as “interrupting” text, on the grounds +that a text line is interrupted without breaking, perhaps to inject a +request invocation or macro call.

+
(70)
+

See Traps.

+
(71)
+

See Diversions.

+
(72)
+

Terminals and some output devices have fonts that render +at only one or two sizes. As examples of the latter, take the +groff lj4 device’s Lineprinter, and lbp’s Courier +and Elite faces.

+
(73)
+

Font designers prepare families such that the styles +share esthetic properties.

+
(74)
+

Historically, the fonts +troffs dealt with were not Free Software or, as with the Graphic +Systems C/A/T, did not even exist in the digital domain.

+
(75)
+

See Font Description File Format.

+
(76)
+

See DESC File Format.

+
(77)
+

Not all versions of the man program +support the -T option; use the subsequent example for an +alternative.

+
(78)
+

This is “Normalization Form D” +as documented in Unicode Standard Annex #15 +(https://unicode.org/reports/tr15/).

+
(79)
+

See Compatibility Mode.

+
(80)
+

Output glyphs +don’t—to GNU troff, a glyph is simply a box with an index into +a font, a given height above and depth below the baseline, and a width.

+
(81)
+

Opinions of this escape sequence’s name abound. +“Zero-width space” is a popular misnomer: roff formatters do +not treat it like a space. Ossanna called it a “non-printing, +zero-width character”, but the character causes output even +though it does not “print”. If no output line is pending, the dummy +character starts one. Contrast an empty input document with one +containing only \&. The former produces no output; the latter, a +blank page.

+
(82)
+

In text fonts, the tallest glyphs are typically +parentheses. Unfortunately, in many cases the actual dimensions of the +glyphs in a font do not closely match its declared type size! For +example, in the standard PostScript font families, 10-point Times sets +better with 9-point Helvetica and 11-point Courier than if all three +were used at 10 points.

+
(83)
+

Rhyme with “sledding”; mechanical typography +used lead metal (Latin plumbum).

+
(84)
+

The claim appears to have been true of Ossanna +troff for the C/A/T device; Kernighan made device-independent +troff more flexible.

+
(85)
+

See Device and Font Description Files.

+
(86)
+

also +known vulgarly as “ANSI colors”

+
(87)
+

See Copy Mode.

+
(88)
+

This refers to +vtroff, a translator that would convert the C/A/T output from +early-vintage AT&T troff to a form suitable for +Versatec and Benson-Varian plotters.

+
(89)
+

Strictly, letters not otherwise recognized are treated +as output comparison delimiters. For portability, it is wise to avoid +using letters not in the list above; for example, Plan 9 +troff uses ‘h’ to test a mode it calls htmlroff, and +GNU troff may provide additional operators in the future.

+
(90)
+

Because formatting of the comparands takes place +in a dummy environment, vertical motions within them cannot spring +traps.

+
(91)
+

All +of this is to say that the lists of output nodes created by formatting +xxx and yyy must be identical. See gtroff Internals.

+
(92)
+

This bizarre behavior maintains compatibility with +AT&T troff.

+
(93)
+

See while.

+
(94)
+

See Copy Mode.

+
(95)
+

unless you redefine it

+
(96)
+

“somewhat less” because +things other than macro calls can be on the input stack

+
(97)
+

See Copy Mode.

+
(98)
+

While it is possible to define and +call a macro ‘.’, you can’t use it as an end macro: during a macro +definition, ‘..’ is never handled as calling ‘.’, even if +‘.de name .’ explicitly precedes it.

+
(99)
+

Its structure is +adapted from, and isomorphic to, part of a solution by Tadziu Hoffman to +the problem of reflowing text multiple times to find an optimal +configuration for it. +https://lists.gnu.org/archive/html/groff/2008-12/msg00006.html

+
(100)
+

If they were not, +parameter interpolations would be similar to command-line +parameters—fixed for the entire duration of a roff program’s +run. The advantage of interpolating \$ escape sequences even in +copy mode is that they can interpolate different contents from one call +to the next, like function parameters in a procedural language. The +additional escape character is the price of this power.

+
(101)
+

Compare this to the \def and \edef +commands in TeX.

+
(102)
+

These are lightly adapted from the groff +implementation of the ms macros.

+
(103)
+

At the +grops defaults of 10-point type on 12-point vertical spacing, the +difference between half a vee and half an em can be subtle: large +spacings like ‘.vs .5i’ make it obvious.

+
(104)
+

See Strings, for an explanation of the trailing +‘\"’.

+
(105)
+

(hc, vc) is adjusted to the point nearest +the perpendicular bisector of the arc’s chord.

+
(106)
+

See The Implicit Page Trap.

+
(107)
+

A trap planted at ‘20i’ or +‘-30i’ will not be sprung on a page of length ‘11i’.

+
(108)
+

It may help to think of each trap location as +maintaining a queue; wh operates on the head of the queue, and +ch operates on its tail. Only the trap at the head of the queue +is visible.

+
(109)
+

See Debugging.

+
(110)
+

See Diversions.

+
(111)
+

While processing an +end-of-input macro, the formatter assumes that the next page break must +be the last; it goes into “sudden death overtime”.

+
(112)
+

Another, taken by the groff man macros, is +to intercept ne requests and wrap bp ones.

+
(113)
+

Thus, the “water” +gets “higher” proceeding down the page.

+
(114)
+

The backslash is doubled. See Copy Mode.

+
(115)
+

that is, ISO 646:1991-IRV or, +popularly, “US-ASCII”

+
(116)
+

They are bypassed because these parameters are not +rendered as glyphs in the output; instead, they remain abstract +characters—in a PDF bookmark or a URL, for example.

+
(117)
+

Recall Line Layout.

+
(118)
+

Historically, +tools named nrchbar and changebar were developed for +marking changes with margin characters and could be found in archives of +the comp.sources.unix USENET group. Some proprietary +Unices also offer(ed) a diffmk program.

+
(119)
+

Except the +escape sequences \f, \F, \H, \m, \M, +\R, \s, and \S, which are processed immediately if +not in copy mode.

+
(120)
+

The +Graphic Systems C/A/T phototypesetter (the original device target for +AT&T troff) supported only a few discrete type sizes +in the range 6–36 points, so Ossanna contrived a special case in the +parser to do what the user must have meant. Kernighan warned of this in +the 1992 revision of CSTR #54 (§2.3), and more recently, McIlroy +referred to it as a “living fossil”.

+
(121)
+

DWB 3.3, Solaris, Heirloom Doctools, and +Plan 9 troff all support it.

+
(122)
+

Naturally, if you’ve changed +the escape character, you need to prefix the e with whatever it +is—and you’ll likely get something other than a backslash in the +output.

+
(123)
+

The rs special character identifier was not +defined in AT&T troff’s font description files, but is +in those of its lineal descendant, Heirloom Doctools troff, as of +the latter’s 060716 release (July 2006).

+
(124)
+

The parser +and postprocessor for intermediate output can be found in the file
+groff-source-dir/src/libs/libdriver/input.cpp.

+
(125)
+

Plan 9 troff has also abandoned the binary +format.

+
(126)
+

800-point type +is not practical for most purposes, but using it enables the quantities +in the font description files to be expressed as integers.

+
(127)
+

groff requests and escape sequences +interpret non-negative font names as mounting positions instead. +Further, a font named ‘0’ cannot be automatically mounted by the +fonts directive of a DESC file.

+
(128)
+

For typesetter devices, this directive is misnamed +since it starts a list of glyphs, not characters.

+
(129)
+

that is, any integer parsable by the C +standard library’s strtol(3) function

+
+ + + + diff --git a/doc/groff.html.node/Adjustment.html b/doc/groff.html.node/Adjustment.html new file mode 100644 index 0000000..60b01c4 --- /dev/null +++ b/doc/groff.html.node/Adjustment.html @@ -0,0 +1,57 @@ + + + + + + +Adjustment (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.1.5 Adjustment

+ + +

After GNU troff performs an automatic break, it may then +adjust the line, widening inter-word spaces until the text reaches +the right margin. Extra spaces between words are preserved. Leading +and trailing spaces are handled as noted above. Text can be aligned to +the left or right margin only, or centered; see Manipulating Filling and Adjustment. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Argument-Units.html b/doc/groff.html.node/Argument-Units.html new file mode 100644 index 0000000..c7cbb16 --- /dev/null +++ b/doc/groff.html.node/Argument-Units.html @@ -0,0 +1,68 @@ + + + + + + +Argument Units (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

6.1.1.2 Argument Units

+ +

Some commands take integer arguments that are assumed to represent +values in a measurement unit, but the letter for the corresponding +scaling unit is not written with the output command arguments. Most +commands assume the scaling unit ‘u’, the basic unit of the device, +some use ‘z’, the scaled point unit of the device, while others, +such as the color commands, expect plain integers. +

+

Single characters can have the eighth bit set, as can the names of +fonts and special characters. The names of characters and fonts can be +of arbitrary length. A character that is to be printed is always in +the current font. +

+

A string argument is always terminated by the next whitespace character +(space, tab, or newline); an embedded ‘#’ character is regarded as +part of the argument, not as the beginning of a comment command. An +integer argument is already terminated by the next non-digit character, +which then is regarded as the first character of the next argument or +command. +

+
+ + + + + diff --git a/doc/groff.html.node/Artificial-Fonts.html b/doc/groff.html.node/Artificial-Fonts.html new file mode 100644 index 0000000..6f9d43d --- /dev/null +++ b/doc/groff.html.node/Artificial-Fonts.html @@ -0,0 +1,252 @@ + + + + + + +Artificial Fonts (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.19.7 Artificial Fonts

+ + + +

There are a number of requests and escape sequences for artificially +creating fonts. These are largely vestiges of the days when output +devices did not have a wide variety of fonts, and when nroff and +troff were separate programs. Most of them are no longer +necessary in GNU troff. Nevertheless, they are supported. +

+
+
Escape sequence: \H'height'
+
+
Escape sequence: \H'+height'
+
Escape sequence: \H'-height'
+
Register: \n[.height]
+
+ + + +

Change (increment, decrement) the height of the current font, but not +the width. If height is zero, restore the original height. +Default scaling unit is ‘z’. +

+

The read-only register .height contains the font height as set by +\H. +

+

Currently, only the -Tps and -Tpdf devices support +this feature. +

+

\H doesn’t produce an input token in GNU troff. As a +consequence, it can be used in requests like mc (which expects +a single character as an argument) to change the font on the fly: +

+
+
.mc \H'+5z'x\H'0'
+
+ +

In compatibility mode, gtroff behaves differently: If an +increment or decrement is used, it is always taken relative to the +current type size and not relative to the previously selected font +height. Thus, +

+
+
.cp 1
+\H'+5'test \H'+5'test
+
+ +

prints the word ‘test’ twice with the same font height (five points +larger than the current font size). +

+ +
+
Escape sequence: \S'slant'
+
+
Register: \n[.slant]
+
+ + + +

Slant the current font by slant degrees. Positive values slant to +the right. Only integer values are possible. +

+

The read-only register .slant contains the font slant as set by +\S. +

+

Currently, only the -Tps and -Tpdf devices support +this feature. +

+

\S doesn’t produce an input token in GNU troff. As a +consequence, it can be used in requests like mc (which expects +a single character as an argument) to change the font on the fly: +

+
+
.mc \S'20'x\S'0'
+
+ + + +

This escape is incorrectly documented in the AT&T +troff manual; the slant is always set to an absolute value. +

+ +
+
Request: .ul [lines]
+
+ +

The ul request normally underlines subsequent lines if a TTY +output device is used. Otherwise, the lines are printed in italics +(only the term ‘underlined’ is used in the following). The single +argument is the quantity of input lines to be underlined; with no +argument, the next line is underlined. If lines is zero or +negative, stop the effects of ul (if it was active). Requests +and empty lines do not count for computing the number of underlined +input lines, even if they produce some output like tl. Lines +inserted by macros (e.g., invoked by a trap) do count. +

+

At the beginning of ul, the current font is stored and the +underline font is activated. Within the span of a ul request, it +is possible to change fonts, but after the last line affected by +ul the saved font is restored. +

+

This number of lines still to be underlined is associated with the +environment (see Environments). The underline font can be changed +with the uf request. +

+ + +

The ul request does not underline spaces. +

+ +
+
Request: .cu [lines]
+
+ + +

The cu request is similar to ul but underlines spaces as +well (if a TTY output device is used). +

+ +
+
Request: .uf font
+
+ + +

Set the underline font (globally) used by ul and cu. By +default, this is the font at position 2. font can be either +a non-negative font position or the name of a font. +

+ +
+
Request: .bd font [offset]
+
+
Request: .bd font1 font2 [offset]
+
Register: \n[.b]
+
+ + +

Embolden font by overstriking its glyphs offset by offset +units minus one. +

+

Two syntax forms are available. +

+
    +
  • Imitate a bold font unconditionally. The first argument specifies the +font to embolden, and the second is the number of basic units, minus +one, by which the two glyphs are offset. If the second argument is +missing, emboldening is turned off. + +

    font can be either a non-negative font position or the name of a +font. +

    +

    offset is available in the .b read-only register if a +special font is active; in the bd request, its default unit is +‘u’. +

    +
  • + + + +Imitate a bold form conditionally. Embolden font1 by offset +only if font font2 is the current font. This request can be +issued repeatedly to set up different emboldening values for different +current fonts. If the second argument is missing, emboldening is turned +off for this particular current font. + +

    This affects special fonts only (either set up with the special +command in font files or with the fspecial request). +

+
+ +
+
Request: .cs font [width [em-size]]
+
+ + + + +

Switch to and from constant glyph space mode. If activated, the +width of every glyph is width/36 ems. The em size is given +absolutely by em-size; if this argument is missing, the em value +is taken from the current font size (as set with the ps request) +when the font is effectively in use. Without second and third argument, +constant glyph space mode is deactivated. +

+

Default scaling unit for em-size is ‘z’; width is an +integer. +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Assigning-Register-Formats.html b/doc/groff.html.node/Assigning-Register-Formats.html new file mode 100644 index 0000000..ff0ddfa --- /dev/null +++ b/doc/groff.html.node/Assigning-Register-Formats.html @@ -0,0 +1,188 @@ + + + + + + +Assigning Register Formats (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.8.4 Assigning Register Formats

+ + + + +

A writable register’s value can be interpolated in several number +formats. By default, conventional Arabic numerals are used. +Other formats see use in sectioning and outlining schemes and +alternative page numbering arrangements. +

+
+
Request: .af reg fmt
+
+

Use number format fmt when interpolating register reg. +Valid number formats are as follows. +

+
+
0
+

Arabic numerals 0, 1, 2, and so on. +Any decimal digit is equivalent to ‘0’; the formatter merely counts +the digits specified. Multiple Arabic numerals in fmt cause +interpolations to be zero-padded on the left if necessary to at least as +many digits as specified (interpolations never truncate a register +value). A register with format ‘00’ interpolates values 1, 2, 3 as +‘01’, ‘02’, ‘03’. The default format for all writable +registers is ‘0’. +

+
+
I
+
+

Uppercase Roman numerals: 0, I, II, III, IV, ... +

+
+
i
+

Lowercase Roman numerals: 0, i, ii, iii, iv, ... +

+
+
A
+

Uppercase letters: 0, A, B, C, …, Z, AA, AB, ... +

+
+
a
+

Lowercase letters: 0, a, b, c, …, z, aa, ab, ... +

+
+ +

Omitting fmt causes a warning in category ‘missing’. +See Warnings, for information about the enablement and suppression of +warnings. Specifying an unrecognized format is an error. +

+

Zero values are interpolated as ‘0’ in non-Arabic formats. +Negative quantities are prefixed with ‘-’ irrespective of format. +In Arabic formats, the sign supplements the field width. If reg +doesn’t exist, it is created with a zero value. +

+
+
.nr a 10
+.af a 0           \" the default format
+\na,
+.af a I
+\na,
+.af a 321
+.nr a (-\na)
+\na,
+.af a a
+\na
+    ⇒ 10, X, -010, -j
+
+ + + + + +

The representable extrema in the ‘i’ and ‘I’ formats +correspond to Arabic ą39,999. GNU troff uses ‘w’ and +‘z’ to represent 5,000 and 10,000 in Roman numerals, respectively, +following the convention of AT&T troff—currently, the +correct glyphs for Roman numerals five thousand (U+2181) and ten +thousand (U+2182) are not used. +

+ + +

Assigning the format of a read-only register is an error. Instead, copy +the read-only register’s value to, and assign the format of, a writable +register. +

+ +
+
Escape sequence: \gr
+
+
Escape sequence: \g(rg
+
Escape sequence: \g[reg]
+
+ +

Interpolate the format of the register reg (one-character +name r, two-character name rg). Zeroes represent +Arabic formats. If reg is not defined, reg is not created +and nothing is interpolated. \g is interpreted even in copy mode +(see Copy Mode). +

+ + + +

GNU troff interprets only Arabic numerals. The Roman numeral or +alphabetic formats cannot be used as operands to arithmetic operators in +expressions (see Numeric Expressions). For instance, it may be +desirable to test the page number independently of its format. +

+
+
.af % i \" front matter
+.de header-trap
+.  \" To test the page number, we need it in Arabic.
+.  ds saved-page-number-format \\g%\"
+.  af % 0
+.  nr page-number-in-decimal \\n%
+.  af % \\*[saved-page-number-format]
+.  ie \\n[page-number-in-decimal]=1 .do-first-page-stuff
+.  el \{\
+.    ie o .do-odd-numbered-page-stuff
+.    el   .do-even-numbered-page-stuff
+.  \}
+.  rm saved-page-number-format
+..
+.wh 0 header-trap
+
+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Auto_002dincrement.html b/doc/groff.html.node/Auto_002dincrement.html new file mode 100644 index 0000000..2680f67 --- /dev/null +++ b/doc/groff.html.node/Auto_002dincrement.html @@ -0,0 +1,124 @@ + + + + + + +Auto-increment (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.8.3 Auto-increment

+ + + + +

Registers can also be incremented or decremented by a configured amount +at the time they are interpolated. The value of the increment is +specified with a third argument to the nr request, and a special +interpolation syntax is used to alter and then retrieve the register’s +value. Together, these features are called +auto-increment.51 +

+
+
Request: .nr ident value incr
+
+ +

Set register ident to value and its auto-incrementation +amount to to incr. The \R escape sequence doesn’t support +an incr argument. +

+ +

Auto-incrementation is not completely automatic; the \n +escape sequence in its basic form never alters the value of a register. +To apply auto-incrementation to a register, interpolate it with +‘\ną’. +

+
+
Escape sequence: \n+i
+
+
Escape sequence: \n-i
+
Escape sequence: \n+(id
+
Escape sequence: \n-(id
+
Escape sequence: \n+[ident]
+
Escape sequence: \n-[ident]
+

Increment or decrement ident (one-character +name i, two-character name id) by the register’s +auto-incrementation value and then interpolate the new register value. +If ident has no auto-incrementation value, interpolate as with +\n. +

+ +
+
.nr a 0 1
+.nr xx 0 5
+.nr foo 0 -2
+\n+a, \n+a, \n+a, \n+a, \n+a
+.br
+\n-(xx, \n-(xx, \n-(xx, \n-(xx, \n-(xx
+.br
+\n+[foo], \n+[foo], \n+[foo], \n+[foo], \n+[foo]
+    ⇒ 1, 2, 3, 4, 5
+    ⇒ -5, -10, -15, -20, -25
+    ⇒ -2, -4, -6, -8, -10
+
+ + + +

To change the increment value without changing the value of a register, +assign the register’s value to itself by interpolating it, and specify +the desired increment normally. Apply an increment of ‘0’ to +disable auto-incrementation of the register. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Background.html b/doc/groff.html.node/Background.html new file mode 100644 index 0000000..1ce4224 --- /dev/null +++ b/doc/groff.html.node/Background.html @@ -0,0 +1,96 @@ + + + + + + +Background (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

1.1 Background

+ + +

M. Douglas McIlroy, formerly of AT&T Bell Laboratories and present at +the creation of the Unix operating system, offers an authoritative +historical summary. +

+
+

The prime reason for Unix was the desire of Ken [Thompson], Dennis +[Ritchie], and Joe Ossanna to have a pleasant environment for software +development. The fig leaf that got the nod from … +management was that an early use would be to develop a “stand-alone” +word-processing system for use in typing pools and secretarial offices. +Perhaps they had in mind “dedicated”, as distinct from +“stand-alone”; that’s what eventuated in various cases, most notably +in the legal/patent department and in the AT&T CEO’s office. +

+

Both those systems were targets of opportunity, not foreseen from the +start. When Unix was up and running on the PDP-11, Joe got wind of +the legal department having installed a commercial word processor. +He went to pitch Unix as an alternative and clinched a trial by +promising to make roff able to number lines by tomorrow in order +to fulfill a patent-office requirement that the commercial system did +not support. +

+

Modems were installed so legal-department secretaries could try the +Research machine. They liked it and Joe’s superb customer service. +Soon the legal department got a system of their own. Joe went on to +create nroff and troff. Document preparation became a +widespread use of Unix, but no stand-alone word-processing system was +ever undertaken. +

+ +

A history relating groff to its predecessors roff, +nroff, and troff is available in the roff(7) +man page. +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Basics.html b/doc/groff.html.node/Basics.html new file mode 100644 index 0000000..95db07b --- /dev/null +++ b/doc/groff.html.node/Basics.html @@ -0,0 +1,232 @@ + + + + + + +Basics (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

3.1 Basics

+ + + +

Let us first survey some basic concepts necessary to use a macro package +fruitfully.6 +References are made throughout to more detailed information. +

+

GNU troff reads an input file prepared by the user and outputs a +formatted document suitable for publication or framing. The input +consists of text, or words to be printed, and embedded commands +(requests and escape sequences), which tell GNU +troff how to format the output. See Formatter Instructions. +

+

The word argument is used in this chapter to mean a word or +number that appears on the same line as a request, and which modifies +the meaning of that request. For example, the request +

+
+
.sp
+
+ +

spaces one line, but +

+
+
.sp 4
+
+ +

spaces four lines. The number 4 is an argument to the sp +request, which says to space four lines instead of one. Arguments are +separated from the request and from each other by spaces (not +tabs). See Invoking Requests. +

+

The primary function of GNU troff is to collect words from input +lines, fill output lines with those words, adjust the line to the +right-hand margin by widening spaces, and output the result. For +example, the input: +

+
+
Now is the time
+for all good men
+to come to the aid
+of their party.
+Four score and seven
+years ago, etc.
+
+ +

is read, packed onto output lines, and justified to produce: +

+
+
  ⇒ Now is the time for all good men to come to the aid of
+  ⇒ their party.  Four score and seven years ago, etc.
+
+ +

Sometimes a new output line should be started even though the current +line is not yet full—for example, at the end of a paragraph. To do +this it is possible to force a break, starting a new output +line. Some requests cause a break automatically, as do (normally) blank +input lines and input lines beginning with a space or tab. +

+

Not all input lines are text lines—words to be formatted. +Some are control lines that tell a macro package (or GNU +troff directly) how to format the text. Control lines start with +a dot (‘.’) or an apostrophe (‘'’) as the first character, and +can be followed by a macro call. +

+

The formatter also does more complex things, such as automatically +numbering pages, skipping over page boundaries, putting footnotes in the +correct place, and so forth. +

+

Here are a few hints for preparing text for input to GNU troff. +

+
    +
  • First, keep the input lines short. Short input lines are easier to +edit, and GNU troff packs words onto longer lines anyhow. + +
  • In keeping with this, it is helpful to begin a new line after every +comma or phrase, since common corrections are to add or delete sentences +or phrases. + +
  • End each sentence with two spaces—or better, start each sentence on a +new line. GNU troff recognizes characters that usually end a +sentence, and inserts inter-sentence space accordingly. + +
  • Do not hyphenate words at the end of lines—GNU troff is smart +enough to hyphenate words as needed, but is not smart enough to take +hyphens out and join a word back together. Also, words such as +“mother-in-law” should not be broken over a line, since then a space +can occur where not wanted, such as “mother- in-law”. +
+ +

We offer further advice in Input Conventions. +

+ + +

GNU troff permits alteration of the distance between lines of +text. This is termed vertical spacing and is expressed in the +same units as the type size—the point. The default is 10-point type +on 12-point spacing. To get double-spaced text you would set +the vertical spacing to 24 points. Some, but not all, macro packages +expose a macro or register to configure the vertical spacing. +

+

A number of requests allow you to change the way the output is arranged +on the page, sometimes called the layout of the output page. +Most macro packages don’t supply macros for performing these (at least +not without performing other actions besides), as they are such basic +operations. The macro packages for writing man pages, man and +mdoc, don’t encourage explicit use of these requests at all. +

+ +

The request ‘.sp N leaves N lines of blank +space. N can be omitted (skipping a single line) or can +be of the form Ni (for N inches) or Nc (for +N centimeters). For example, the input: +

+
+
.sp 1.5i
+My thoughts on the subject
+.sp
+
+ +

leaves one and a half inches of space, followed by the line “My +thoughts on the subject”, followed by a single blank line (more +measurement units are available; see Measurements). +

+

If you seek precision in spacing, be advised when using a macro package +that it might not honor sp requests as you expect; it can use a +formatter feature called no-space mode to prevent excess space +from accumulating. Macro packages typically offer registers to control +spacing between paragraphs, before section headings, and around displays +(discussed below); use these facilities preferentially. +See Manipulating Spacing. +

+ + +

Text lines can be centered by using the ce request. The line +after ce is centered (horizontally) on the page. To center more +than one line, use ‘.ce N (where N is the number +of lines to center), followed by the N lines. To center many +lines without counting them, type: +

+
+
.ce 1000
+lines to center
+.ce 0
+
+ +

The ‘.ce 0 request tells GNU troff to center zero more +lines, in other words, stop centering. +

+ + + + +

GNU troff also offers the rj request for right-aligning +text. It works analogously to ce and is convenient for setting +epigraphs. +

+ + +

The bp request starts a new page; this necessarily implies an +ordinary (line) break. +

+ + +

All of these requests cause a break; that is, they always start a new +line. To start a new line without performing any other action, use +br. If you invoke them with the apostrophe ‘'’, the +no-break control character, the (initial) break they normally +perform is suppressed. ‘'br’ does nothing. +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Blank-Line-Traps.html b/doc/groff.html.node/Blank-Line-Traps.html new file mode 100644 index 0000000..b7b0ae4 --- /dev/null +++ b/doc/groff.html.node/Blank-Line-Traps.html @@ -0,0 +1,71 @@ + + + + + + +Blank Line Traps (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.28.3 Blank Line Traps

+ + + +
+
Request: .blm [name]
+
+ +

Set a blank line trap, calling the macro name when GNU +troff encounters a blank line in an input file, instead of the +usual behavior (see Breaking). A line consisting only of spaces is +also treated as blank and subject to this trap. If no argument is +supplied, the default blank line behavior is (re-)established. +

+ + +
+ + + + + diff --git a/doc/groff.html.node/Breaking.html b/doc/groff.html.node/Breaking.html new file mode 100644 index 0000000..a883e07 --- /dev/null +++ b/doc/groff.html.node/Breaking.html @@ -0,0 +1,119 @@ + + + + + + +Breaking (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.1.4 Breaking

+ + + + + +

Once an output line is full, the next word (or remainder of a hyphenated +one) is placed on a different output line; this is called a break. +In this manual and in roff discussions generally, a “break” if +not further qualified always refers to the termination of an output +line. When the formatter is filling text, it introduces breaks +automatically to keep output lines from exceeding the configured line +length. After an automatic break, GNU troff adjusts the line if +applicable (see below), and then resumes collecting and filling text on +the next output line. +

+

Sometimes, a line cannot be broken automatically. This usually does +not happen with natural language text unless the output line length has +been manipulated to be extremely short, but it can with specialized +text like program source code. We can use perl at the shell +prompt to contrive an example of failure to break the line. We also +employ the -z option to suppress normal output. +

+
+
$ perl -e 'print "#" x 80, "\n";' | nroff -z
+    error→ warning: cannot break line
+
+ +

The remedy for these cases is to tell GNU troff where the line +may be broken without hyphens. This is done with the non-printing break +point escape sequence ‘\:’; see Manipulating Hyphenation. +

+ + + + +

What if the document author wants to stop filling lines temporarily, for +instance to start a new paragraph? There are several solutions. A +blank input line not only causes a break, but by default it also outputs +a one-line vertical space (effectively a blank output line). This +behavior can be modified; see Blank Line Traps. Macro packages +may discourage or disable the blank line method of paragraphing in favor +of their own macros. +

+ + + + +

A line that begins with one or more spaces causes a break. The spaces +are output at the beginning of the next line without being +adjusted (see below); however, this behavior can be modified +(see Leading Space Traps). Again, macro packages may provide other +methods of producing indented paragraphs. Trailing spaces on text lines +are discarded.23 +

+

What if the file ends before enough words have been collected to fill an +output line? Or the output line is exactly full but not yet broken, and +there is no more input? GNU troff interprets the end of input as +a break. Certain requests also cause breaks, implicitly or explicitly. +This is discussed in Manipulating Filling and Adjustment. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Built_002din-Registers.html b/doc/groff.html.node/Built_002din-Registers.html new file mode 100644 index 0000000..a1b0530 --- /dev/null +++ b/doc/groff.html.node/Built_002din-Registers.html @@ -0,0 +1,253 @@ + + + + + + +Built-in Registers (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.8.5 Built-in Registers

+ + + +

Predefined registers whose identifiers start with a dot are read-only. +Many are Boolean-valued, interpolating a true or false value testable +with the if, ie, or while requests. Some read-only +registers are string-valued, meaning that they interpolate text. +

+ + + +

Caution: Built-in registers are subject to removal like +others; once removed, they can be recreated only as normal writable +registers and will not reflect formatter state. +

+

A register name (without the dot) is often associated with a request of +the same name. A complete listing of all built-in registers can be +found in Register Index. +

+

We present here a few built-in registers that are not described +elsewhere in this manual; they have to do with invariant properties of +GNU troff, or obtain information about the formatter’s +command-line options, processing progress, or the operating environment. +

+
+
\n[.A]
+
+ +

Approximate output is being formatted (Boolean-valued); see +groff -a option (Options). +

+
+
\n[.c]
+
+
+
\n[c.]
+
+ +

Input line number. ‘c.’ is a writable synonym, +affecting subsequent interpolations of both ‘.c’ and ‘c.’. +

+
+
\n[.F]
+
+ +

Name of input file (string-valued). +

+
+
\n[.g]
+
+ +

Always true in GNU troff (Boolean-valued). Documents can use +this to ask the formatter if it claims groff compatibility. +

+
+
\n[.P]
+

Output page selection status (Boolean-valued); see groff +-o option (Options). +

+
+
\n[.R]
+
+ +

Count of available unused registers; always 10,000 in GNU +troff.52 +

+
+
\n[.T]
+

Indicator of output device selection (Boolean-valued); see +groff -T option (Options). +

+
+
\n[.U]
+
+ + + +

Unsafe mode enablement status (Boolean-valued); see groff +-U option (Options). +

+
+
\n[.x]
+
+ +

Major version number of the running GNU troff formatter. For +example, if the version number is 1.23.0, then .x +contains ‘1’. +

+
+
\n[.y]
+
+ +

Minor version number of the running GNU troff formatter. For +example, if the version number is 1.23.0, then .y +contains ‘23’. +

+
+
\n[.Y]
+
+

Revision number of the running GNU troff formatter. For example, +if the version number is 1.23.0, then .Y contains ‘0’. +

+
+
\n[$$]
+
+ + + +

Process identifier (PID) of the GNU troff program in its +operating environment. +

+
+ +

Date- and time-related registers are set per the local time as +determined by localtime(3) when the formatter launches. This +initialization can be overridden by SOURCE_DATE_EPOCH and +TZ; see Environment. +

+
+
\n[seconds]
+
+ + +

Count of seconds elapsed in the minute (0–60).

+
+
\n[minutes]
+
+ + +

Count of minutes elapsed in the hour (0–59). +

+
+
\n[hours]
+
+ + +

Count of hours elapsed since midnight (0–23). +

+
+
\n[dw]
+
+ +

Day of the week (1–7; 1 is Sunday). +

+
+
\n[dy]
+
+ +

Day of the month (1–31). +

+
+
\n[mo]
+
+ +

Month of the year (1–12). +

+
+
\n[year]
+
+ +

Gregorian year. +

+ + +
+
\n[yr]
+

Gregorian year minus 1900. This register is incorrectly documented +in the AT&T troff manual as storing the last two digits +of the current year. That claim stopped being true in 2000. Old +troff input that looks like: +

+
+
'\" The year number is a surprise after 1999.
+This document was formatted in 19\n(yr.
+
+ +

can be corrected to: +

+
+
This document was formatted in \n[year].
+
+ +

or, for portability across many roff programs, to the following. +

+
+
.nr y4 1900+\n(yr
+This document was formatted in \n(y4.
+
+
+
+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Calling-Macros.html b/doc/groff.html.node/Calling-Macros.html new file mode 100644 index 0000000..1e8d81a --- /dev/null +++ b/doc/groff.html.node/Calling-Macros.html @@ -0,0 +1,164 @@ + + + + + + +Calling Macros (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.6.3 Calling Macros

+ + + + +

If a macro of the desired name does not exist when called, it is +created, assigned an empty definition, and a warning in category +‘mac’ is emitted. Calling an undefined macro does end a +macro definition naming it as its end macro (see Writing Macros). +

+ +

To embed spaces within a macro argument, enclose the argument in +neutral double quotes ". Horizontal motion escape sequences are +sometimes a better choice for arguments to be formatted as text. +

+

Consider calls to a hypothetical section heading macro ‘uh’. +

+
+
.uh The Mouse Problem
+.uh "The Mouse Problem"
+.uh The\~Mouse\~Problem
+.uh The\ Mouse\ Problem
+
+ + + +

The first line calls uh with three arguments: ‘The’, +‘Mouse’, and ‘Problem’. The remainder call the uh +macro with one argument, ‘The Mouse Problem’. The last solution, +using escaped spaces, can be found in documents prepared for +AT&T troff. It can cause surprise when text is +adjusted, because \SP inserts a fixed-width, +non-breaking space. GNU troff’s \~ escape sequence +inserts an adjustable, non-breaking space.44 +

+ + + + +

The foregoing raises the question of how to embed neutral double quotes +or backslashes in macro arguments when those characters are +desired as literals. In GNU troff, the special character escape +sequence \[rs] produces a backslash and \[dq] a neutral +double quote. +

+

In GNU troff’s AT&T compatibility mode, these +characters remain available as \(rs and \(dq, +respectively. AT&T troff did not consistently define +these special characters, +but its descendants can be made to support them. See Device and Font Description Files. +

+

If even that is not feasible, options remain. To obtain a literal +escape character in a macro argument, you can simply type it if you +change or disable the escape character first. See Using Escape Sequences. Otherwise, you must escape the escape character repeatedly +to a context-dependent extent. See Copy Mode. +

+

For the (neutral) double quote, you have recourse to an obscure +syntactical feature of AT&T troff. Because a double +quote can begin a macro argument, the formatter keeps track of whether +the current argument was started thus, and doesn’t require a space after +the double quote that ends it.45 In +the argument list to a macro, a double quote that isn’t preceded +by a space doesn’t start a macro argument. If not preceded by a +double quote that began an argument, this double quote becomes part of +the argument. Furthermore, within a quoted argument, a pair of adjacent +double quotes becomes a literal double quote. +

+
+
.de eq
+.  tm arg1:\\$1 arg2:\\$2 arg3:\\$3
+.  tm arg4:\\$4 arg5:\\$5 arg6:\\$6
+.. \" 4 backslashes on the next line
+.eq a" "b c" "de"f\\\\g" h""i "j""k"
+    error→ arg1:a" arg2:b c arg3:de
+    error→ arg4:f\g" arg5:h""i arg6:j"k
+
+ +

Apart from the complexity of the rules, this traditional solution has +the disadvantage that double quotes don’t survive repeated argument +expansion in AT&T troff or GNU troff’s +compatibility mode. This can frustrate efforts to pass such arguments +intact through multiple macro calls. +

+
+
.cp 1
+.de eq
+.  tm arg1:\\$1 arg2:\\$2 arg3:\\$3
+.  tm arg4:\\$4 arg5:\\$5 arg6:\\$6
+..
+.de xe
+.  eq \\$1 \\$2 \\$3 \\$4 \\$5 \\$6
+.. \" 8 backslashes on the next line
+.xe a" "b c" "de"f\\\\\\\\g" h""i "j""k"
+    error→ arg1:a" arg2:b arg3:c
+    error→ arg4:de arg5:f\g" arg6:h""i
+
+ + + + + +

Outside of compatibility mode, GNU troff doesn’t exhibit this +problem because it tracks the nesting depth of interpolations. +See Implementation Differences. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Changing-the-Type-Size.html b/doc/groff.html.node/Changing-the-Type-Size.html new file mode 100644 index 0000000..da02d8b --- /dev/null +++ b/doc/groff.html.node/Changing-the-Type-Size.html @@ -0,0 +1,159 @@ + + + + + + +Changing the Type Size (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.20.1 Changing the Type Size

+ +
+
Request: .ps [size]
+
+
Request: .ps +size
+
Request: .ps -size
+
Escape sequence: \ssize
+
+
Register: \n[.s]
+
+ + + +

Use the ps request or the \s escape sequence to change +(increase, decrease) the type size (in scaled points). Specify +size as either an absolute type size, or as a relative change from +the current size. ps with no argument restores the previous +size. The ps request’s default scaling unit is ‘z’. The +requested size is rounded to the nearest valid size (with ties rounding +down) within the limits supported by the device. If the requested size +is non-positive, it is treated as 1u. +

+ + + +

Type size alteration is incorrectly documented in the AT&T +troff manual, which claims “if [the requested size] is invalid, +the next larger valid size will result, with a maximum of +36”.84 +

+ + +

The read-only string-valued register .s interpolates the type +size in points as a decimal fraction; it is associated with the +environment (see Environments). To obtain the type size in scaled +points, interpolate the .ps register instead (see Using Fractional Type Sizes). +

+

The \s escape sequence supports a variety of syntax forms. +

+
+
\sn
+

Set the type size to n points. n must be a single +digit. If n is 0, restore the previous size. +

+
+
\s+n
+
\s-n
+

Increase or decrease the type size by n points. +n must be exactly one digit. +

+
+
\s(nn
+

Set the type size to nn points. nn must be exactly two +digits. +

+
+
\s+(nn
+
\s-(nn
+
\s(+nn
+
\s(-nn
+

Alter the type size in points by the two-digit value nn. +

+
+ +

See Using Fractional Type Sizes, for further syntactical forms of the +\s escape sequence that additionally accept decimal fractions. +

+
+
snap, snap,
+.ps +2
+grin, grin,
+.ps +2
+wink, wink, \s+2nudge, nudge,\s+8 say no more!
+.ps 10
+
+
+ +

The \s escape sequence affects the environment immediately and +doesn’t produce an input token. Consequently, it can be used in +requests like mc, which expects a single character as an +argument, to change the type size on the fly. +

+
+
.mc \s[20]x\s[0]
+
+ +
+
Request: .sizes s1 s2 … sn [0]
+
+

The DESC file specifies which type sizes are allowed by the +output device; see DESC File Format. Use the sizes request +to change this set of permissible sizes. Arguments are in scaled +points; see Using Fractional Type Sizes. Each can be a single +type size (such as ‘12000’), or a range of sizes (such as +‘4000-72000’). You can optionally end the list with a ‘0’. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Changing-the-Vertical-Spacing.html b/doc/groff.html.node/Changing-the-Vertical-Spacing.html new file mode 100644 index 0000000..cca1634 --- /dev/null +++ b/doc/groff.html.node/Changing-the-Vertical-Spacing.html @@ -0,0 +1,146 @@ + + + + + + +Changing the Vertical Spacing (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.20.2 Changing the Vertical Spacing

+ +
+
Request: .vs [space]
+
+
Request: .vs +space
+
Request: .vs -space
+
Register: \n[.v]
+
+ + + +

Set the vertical spacing to, or alter it by, space. The default +scaling unit is ‘p’. If vs is called without an argument, +the vertical spacing is reset to the previous value before the last call +to vs. + +GNU troff emits a warning in category ‘range’ if space +is negative; the vertical spacing is then set to the smallest possible +positive value, the vertical motion quantum (as found in the .V +register). +

+

.vs 0 isn’t saved in a diversion since it doesn’t result in +a vertical motion. You must explicitly issue this request before +interpolating the diversion. +

+

The read-only register .v contains the vertical spacing; it is +associated with the environment (see Environments). +

+ + +

When a break occurs, GNU troff performs the following procedure. +

+
    +
  • + +Move the drawing position vertically by the extra pre-vertical line +space, the minimum of all negative \x escape sequence arguments +in the pending output line. + +
  • Move the drawing position vertically by the vertical line spacing. + +
  • Write out the pending output line. + +
  • + +Move the drawing position vertically by the extra post-vertical line +space, the maximum of all positive \x escape sequence arguments +in the line that has just been output. + +
  • + +Move the drawing position vertically by the post-vertical line +spacing (see below). +
+ + +

Prefer vs or pvs over ls to produce double-spaced +documents. vs and pvs have finer granularity than +ls; moreover, some preprocessors assume single spacing. +See Manipulating Spacing, regarding the \x escape sequence and +the ls request. +

+
+
Request: .pvs [space]
+
+
Request: .pvs +space
+
Request: .pvs -space
+
Register: \n[.pvs]
+
+ + + +

Set the post-vertical spacing to, or alter it by, space. The +default scaling unit is ‘p’. If pvs is called without an +argument, the post-vertical spacing is reset to the previous value +before the last call to pvs. GNU troff emits a warning in +category ‘range’ if space is negative; the post-vertical +spacing is then set to zero. +

+

The read-only register .pvs contains the post-vertical spacing; +it is associated with the environment (see Environments). +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Character-Classes.html b/doc/groff.html.node/Character-Classes.html new file mode 100644 index 0000000..6e315dd --- /dev/null +++ b/doc/groff.html.node/Character-Classes.html @@ -0,0 +1,140 @@ + + + + + + +Character Classes (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.19.5 Character Classes

+ + + +

Classes are particularly useful for East Asian languages such as +Chinese, Japanese, and Korean, where the number of needed characters is +much larger than in European languages, and where large sets of +characters share the same properties. +

+
+
Request: .class name c1 c2 …
+
+ + + +

Define a character class (or simply “class”) name comprising +the characters c1, c2, and so on. +

+

A class thus defined can then be referred to in lieu of listing all the +characters within it. Currently, only the cflags request can +handle references to character classes. +

+

In the request’s simplest form, each cn is a character (or special +character). +

+
+
.class [quotes] ' \[aq] \[dq] \[oq] \[cq] \[lq] \[rq]
+
+ +

Since class and glyph names share the same name space, it is recommended +to start and end the class name with [ and ], +respectively, to avoid collisions with existing character names defined +by GNU troff or the user (with char and related requests). +This practice applies the presence of ] in the class name to +prevent the use of the special character escape form +\[], thus you must use the \C escape to access +a class with such a name. +

+ + +

You can also use a character range notation consisting of a +start character followed by ‘-’ and then an end character. +Internally, GNU troff converts these two symbol names to +Unicode code points (according to the groff glyph list [GGL]), +which then give the start and end value of the range. If that fails, +the class definition is skipped. +

+

Furthermore, classes can be nested. +

+
+
.class [prepunct] , : ; > }
+.class [prepunctx] \C'[prepunct]' \[u2013]-\[u2016]
+
+ +

The class ‘[prepunctx]’ thus contains the contents of the class +[prepunct] as defined above (the set ‘, : ; > }’), and +characters in the range between U+2013 and U+2016. +

+

If you want to include ‘-’ in a class, it must be the first +character value in the argument list, otherwise it gets misinterpreted +as part of the range syntax. +

+

It is not possible to use class names as end points of range +definitions. +

+

A typical use of the class request is to control line-breaking +and hyphenation rules as defined by the cflags request. For +example, to inhibit line breaks before the characters belonging to the +prepunctx class defined in the previous example, you can write +the following. +

+
+
.cflags 2 \C'[prepunctx]'
+
+ +

See the cflags request in Using Symbols, for more details. +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Character-Translations.html b/doc/groff.html.node/Character-Translations.html new file mode 100644 index 0000000..a867be8 --- /dev/null +++ b/doc/groff.html.node/Character-Translations.html @@ -0,0 +1,200 @@ + + + + + + +Character Translations (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.13 Character Translations

+ + + +

A translation is a mapping of an input character to an output +glyph. The mapping occurs at output time, i.e., the input character +gets assigned the metric information of the mapped output character +right before input tokens are converted to nodes (see gtroff Internals, for more on this process). +

+
+
Request: .tr abcd
+
+
Request: .trin abcd
+
+

Translate character a to glyph b, character c to +glyph d, and so on. If there is an odd number of characters +in the argument, the last one is translated to a fixed-width space (the +same one obtained by the \SP escape sequence). +

+

The trin request is identical to tr, but when you unformat +a diversion with asciify it ignores the translation. +See Diversions, for details about the asciify request. +

+

Some notes: +

+
    +
  • + + + + + + + + + + + + +Special characters (\(xx, \[xxx], +\C'xxx', \', \`, \-, \_), +glyphs defined with the char request, and numbered glyphs +(\N'xxx') can be translated also. + +
  • +The \e escape can be translated also. + +
  • + +Characters can be mapped onto the \% and \~ escape +sequences (but \% and \~ can’t be mapped onto another +glyph). + +
  • + + + + + + + + + +The following characters can’t be translated: space (with one exception, +see below), backspace, newline, leader (and \a), tab (and +\t). + +
  • +Translations are not considered for finding the soft hyphen character +set with the shc request. + +
  • +The pair ‘c\&’ (an arbitrary character c followed +by the dummy character) maps this character to “nothing”. + +
    +
    .tr a\&
    +foo bar
    +    ⇒ foo br
    +
    + +

    Even the space character can be mapped to the dummy character. +

    +
    +
    .tr aa \&
    +foo bar
    +    ⇒ foobar
    +
    + +

    As shown in the example, the space character can’t be the first +character/glyph pair as an argument of tr. Additionally, it is +not possible to map the space character to any other glyph; requests +like ‘.tr aa x undo ‘.tr aa \& instead. +

    +

    If justification is active, lines are justified in spite of the ‘empty’ +space character (but there is no minimal distance, i.e., the space +character, between words). +

    +
  • After an output glyph has been constructed (this happens at the moment +immediately before the glyph is appended to an output glyph list, either +by direct output, in a macro, diversion, or string), it is no longer +affected by tr. + +
  • Translating character to glyphs where one of them or both are undefined +is possible also; tr does not check whether the elements of its +argument exist. + +

    See gtroff Internals. +

    +
  • Without an argument, the tr request is ignored. +
+
+ +
+
Request: .trnt abcd
+
+ +

trnt is the same as the tr request except that the +translations do not apply to text that is transparently throughput into +a diversion with \!. See Diversions. +

+

For example, +

+
+
.tr ab
+.di x
+\!.tm a
+.di
+.x
+
+ +

prints ‘b’ to the standard error stream; if trnt is used +instead of tr it prints ‘a’. +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Colors.html b/doc/groff.html.node/Colors.html new file mode 100644 index 0000000..8c23dcb --- /dev/null +++ b/doc/groff.html.node/Colors.html @@ -0,0 +1,208 @@ + + + + + + +Colors (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.21 Colors

+ + + + + + +

GNU troff supports color output with a variety of color spaces +and up to 16 bits per channel. Some devices, particularly terminals, +may be more limited. When color support is enabled, two colors are +current at any given time: the stroke color, with which glyphs, +rules (lines), and geometric objects like circles and polygons are +drawn, and the fill color, which can be used to paint the interior +of a closed geometric figure. +

+
+
Request: .color [n]
+
+
Register: \n[.color]
+
+

If n is missing or non-zero, enable the output of color-related +device-independent output commands (this is the default); otherwise, +disable them. This request sets a global flag; it does not produce an +input token (see gtroff Internals). +

+

The read-only register .color is 1 if colors are enabled, +0 otherwise. +

+

Color can also be disabled with the -c command-line option. +

+ +
+
Request: .defcolor ident scheme color-component …
+
+

Define a color named ident. scheme selects a color space +and determines the quantity of required color-components; it must +be one of ‘rgb’ (three components), ‘cmy’ (three), ‘cmyk’ +(four), or ‘gray’ (one). ‘grey’ is accepted as a synonym of +‘gray’. The color components can be encoded as a single +hexadecimal value starting with ‘#’ or ‘##’. The former +indicates that each component is in the range 0–255 (0–FF), the latter +the range 0–65,535 (0–FFFF). +

+
+
.defcolor half gray #7f
+.defcolor pink rgb #FFC0CB
+.defcolor magenta rgb  ##ffff0000ffff
+
+ + + + +

Alternatively, each color component can be specified as a decimal +fraction in the range 0–1, interpreted using a default scaling +unit of f, which multiplies its value by 65,536 (but +clamps it at 65,535). +

+
+
.defcolor gray50 rgb 0.5 0.5 0.5
+.defcolor darkgreen rgb 0.1f 0.5f 0.2f
+
+
+ + + +

Each output device has a color named ‘default’, which cannot be +redefined. A device’s default stroke and fill colors are not +necessarily the same. For the dvi, html, pdf, +ps, and xhtml output devices, GNU troff +automatically loads a macro file defining many color names at startup. +By the same mechanism, the devices supported by grotty recognize +the eight standard ISO 6429/EMCA-48 color names.86 +

+
+
Request: .gcolor [color]
+
+
Escape sequence: \mc
+
+
Escape sequence: \m(co
+
Escape sequence: \m[color]
+
Register: \n[.m]
+
+

Set the stroke color to color. +

+
+
.gcolor red
+The next words
+.gcolor
+\m[red]are in red\m[]
+and these words are in the previous color.
+
+ +

The escape sequence \m[] restores the previous stroke color, as +does a gcolor request without an argument. +

+ + + +

The name of the current stroke color is available in the read-only +string-valued register ‘.m’; it is associated with the environment +(see Environments). It interpolates nothing when the stroke color +is the default. +

+

\m doesn’t produce an input token in GNU troff +(see gtroff Internals). It therefore can be used in requests like +mc (which expects a single character as an argument) to change +the color on the fly: +

+
+
.mc \m[red]x\m[]
+
+
+ +
+
Request: .fcolor [color]
+
+
Escape sequence: \Mc
+
+
Escape sequence: \M(co
+
Escape sequence: \M[color]
+
Register: \n[.M]
+
+

Set the fill color for objects drawn with \D'…' escape +sequences. The escape sequence \M[] restores the previous fill +color, as does an fcolor request without an argument. +

+ + + + + + +

The name of the current fill color is available in the read-only +string-valued register ‘.M’; it is associated with the environment +(see Environments). It interpolates nothing when the fill color +is the default. \M doesn’t produce an input token in GNU +troff. +

+

Create an ellipse with a red interior as follows. +

+
+
\M[red]\h'0.5i'\D'E 2i 1i'\M[]
+
+
+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Columnation.html b/doc/groff.html.node/Columnation.html new file mode 100644 index 0000000..7ac057f --- /dev/null +++ b/doc/groff.html.node/Columnation.html @@ -0,0 +1,53 @@ + + + + + + +Columnation (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

3.2.10 Columnation

+ +

Macro packages apart from man and mdoc for man page +formatting offer a facility for setting multiple columns on the page. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Command-Reference.html b/doc/groff.html.node/Command-Reference.html new file mode 100644 index 0000000..bd5cd9e --- /dev/null +++ b/doc/groff.html.node/Command-Reference.html @@ -0,0 +1,60 @@ + + + + + + +Command Reference (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

6.1.2 Command Reference

+ +

This section describes all intermediate output commands, both from +AT&T troff as well as the gtroff extensions. +

+ + +
+ + + + + diff --git a/doc/groff.html.node/Comment-Command.html b/doc/groff.html.node/Comment-Command.html new file mode 100644 index 0000000..1ef8d94 --- /dev/null +++ b/doc/groff.html.node/Comment-Command.html @@ -0,0 +1,65 @@ + + + + + + +Comment Command (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

6.1.2.1 Comment Command

+ +
+
#anythingend of line
+

A comment. Ignore any characters from the ‘#’ character up to the +next newline character. +

+

This command is the only possibility for commenting in the intermediate +output. Each comment can be preceded by arbitrary syntactical space; +every command can be terminated by a comment. +

+
+ +
+ + + + + diff --git a/doc/groff.html.node/Comments.html b/doc/groff.html.node/Comments.html new file mode 100644 index 0000000..46b3523 --- /dev/null +++ b/doc/groff.html.node/Comments.html @@ -0,0 +1,157 @@ + + + + + + +Comments (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.7 Comments

+ + +

One of the most common forms of escape sequence is the +comment.48 +

+
+
Escape sequence: \"
+
+

Start a comment. Everything up to the next newline is ignored. +

+

This may sound simple, but it can be tricky to keep the comments from +interfering with the appearance of the output. + + +If the escape sequence is to the right of some text or a request, that +portion of the line is ignored, but spaces preceding it are processed +normally by GNU troff. This affects only the ds and +as requests and their variants. +

+ + +

One possibly irritating idiosyncrasy is that tabs should not be used to +vertically align comments in the source document. Tab characters are +not treated as separators between a request name and its first argument, +nor between arguments. +

+ + +

A comment on a line by itself is treated as a blank line, because after +eliminating the comment, that is all that remains. +

+
+
Test
+\" comment
+Test
+    ⇒ Test
+    ⇒
+    ⇒ Test
+
+ +

To avoid this, it is common to combine the empty request with the +comment escape sequence as ‘.\"’, causing the input line to be +ignored. +

+ +

Another commenting scheme sometimes seen is three consecutive single +quotes (''') at the beginning of a line. This works, but GNU +troff emits a warning diagnostic (if enabled) about an undefined +macro (namely ‘''’). +

+ +
+
Escape sequence: \#
+
+

Start a comment; everything up to and including the next newline is +ignored. This groff extension was introduced to avoid the +problems described above. +

+
+
Test
+\# comment
+Test
+    ⇒ Test Test
+
+
+ +
+
Request: .ig [end]
+
+

Ignore input until, in the current conditional block (if +any),49 the macro end is called +at the start of a control line, or the control line ‘..’ is +encountered if end is not specified. ig is parsed as if it +were a macro definition, but its contents are discarded, not +stored.50 +

+
+
hand\c
+.de TX
+fasting
+..
+.ig TX
+This is part of a large block of input that has been
+temporarily(?) commented out.
+We can restore it simply by removing the .ig request and
+the call of its end macro.
+.TX
+
+
+
    ⇒ handfasting
+
+
+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Common-Features.html b/doc/groff.html.node/Common-Features.html new file mode 100644 index 0000000..074015e --- /dev/null +++ b/doc/groff.html.node/Common-Features.html @@ -0,0 +1,89 @@ + + + + + + +Common Features (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

3.2 Common Features

+ + + +

GNU troff provides low-level operations for formatting a +document. Many routine operations are undertaken in nearly all +documents that require a series of such primitive operations to be +performed. These common tasks are grouped into macros, which +are then collected into a macro package. +

+

Macro packages come in two varieties: “major” or “full-service” +ones that manage page layout, and “minor” or “auxiliary” ones that +do not, instead fulfilling narrow, specific tasks. Find a list in the +groff_tmac(5) man page. Type ‘man groff_tmac’ at the +command line to view it. +

+

We survey several capabilities of full-service macro package below. +Each package employs its own macros to exercise them. For details, +consult its man page or, for ms, see ms. +

+ + + +
+ + + + + diff --git a/doc/groff.html.node/Compatibility-Mode.html b/doc/groff.html.node/Compatibility-Mode.html new file mode 100644 index 0000000..60c376b --- /dev/null +++ b/doc/groff.html.node/Compatibility-Mode.html @@ -0,0 +1,221 @@ + + + + + + +Compatibility Mode (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.38.2 Compatibility Mode

+ + + + + + + +

Long identifier names may be GNU troff’s most obvious innovation. +AT&T troff interprets ‘.dsabcd’ as defining a +string ‘ab’ with contents ‘cd’. Normally, GNU troff +interprets this as a call of a macro named dsabcd. +AT&T troff also interprets ‘\*[’ and ‘\n[’ as +an interpolation of a string or register, respectively, named ‘[’. +In GNU troff, however, the ‘[’ is normally interpreted as +delimiting a long name. In compatibility mode, GNU troff +interprets names in the traditional way; they thus can be two characters +long at most. +

+
+
Request: .cp [n]
+
+
Register: \n[.C]
+
+

If n is missing or non-zero, turn on compatibility mode; +otherwise, turn it off. +

+

The read-only register .C is 1 if compatibility mode is on, +0 otherwise. +

+

Compatibility mode can be also turned on with the -C +command-line option. +

+ +
+
Request: .do name
+
+
Register: \n[.cp]
+
+

The do request interprets the string, request, diversion, or +macro name (along with any further arguments) with compatibility +mode disabled. Compatibility mode is restored (only if it was active) +when the expansion of name is interpreted; that is, the +restored compatibility state applies to the contents of the macro, +string, or diversion name as well as data read from files or pipes +if name is any of the so, soquiet, mso, +msoquiet, or pso requests. +

+

The following example illustrates several aspects of do behavior. +

+
+
.de mac1
+FOO
+..
+.de1 mac2
+groff
+.mac1
+..
+.de mac3
+compatibility
+.mac1
+..
+.de ma
+\\$1
+..
+.cp 1
+.do mac1
+.do mac2 \" mac2, defined with .de1, calls "mac1"
+.do mac3 \" mac3 calls "ma" with argument "c1"
+.do mac3 \[ti] \" groff syntax accepted in .do arguments
+    ⇒ FOO groff FOO compatibility c1 ~
+
+ +

The read-only register .cp, meaningful only when dereferenced +from a do request, is 1 if compatibility mode was on when +the do request was encountered, and 0 if it was not. This +register is specialized and may require a statement of rationale. +

+

When writing macro packages or documents that use GNU troff +features and which may be mixed with other packages or documents that do +not—common scenarios include serial processing of man pages or use of +the so or mso requests—you may desire correct operation +regardless of compatibility mode enablement in the surrounding context. +It may occur to you to save the existing value of ‘\n(.C’ into a +register, say, ‘_C’, at the beginning of your file, turn +compatibility mode off with ‘.cp 0’, then restore it from that +register at the end with ‘.cp \n(_C’. At the same time, a modular +design of a document or macro package may lead you to multiple layers of +inclusion. You cannot use the same register name everywhere lest you +“clobber” the value from a preceding or enclosing context. The +two-character register name space of AT&T troff is +confining and mnemonically challenging; you may wish to use the more +capacious name space of GNU troff. However, attempting ‘.nr +_my_saved_C \n(.C’ will not work in compatibility mode; the register +name is too long. “This is exactly what do is for,” you think, +‘.do nr _my_saved_C \n(.C’. The foregoing will always save zero to +your register, because do turns compatibility mode off +while it interprets its argument list. +

+

To robustly save compatibility mode before switching it off, use +

+
+
.do nr _my_saved_C \n[.cp]
+.cp 0
+
+ +

at the beginning of your file, followed by +

+
+
.cp \n[_my_saved_C]
+.do rr _my_saved_C
+
+ +

at the end. As in the C language, we all have to share one big +name space, so choose a register name that is unlikely to collide with +other uses. +

+ + + + +

Normally, GNU troff preserves the interpolation depth in +delimited arguments, but not in compatibility mode. +

+
+
.ds xx '
+\w'abc\*(xxdef'
+    ⇒ 168 (normal mode on a terminal device)
+    ⇒ 72def' (compatibility mode on a terminal device)
+
+ + + + + +

Furthermore, the escape sequences \f, \H, \m, +\M, \R, \s, and \S are transparent for the +purpose of recognizing a control character at the beginning of a line +only in compatibility mode. For example, this code produces bold output +in both cases, but the text differs. +

+
+
.de xx
+Hello!
+..
+\fB.xx\fP
+    ⇒ .xx (normal mode)
+    ⇒ Hello! (compatibility mode)
+
+ + +

Normally, the syntax form \sn accepts only a single +character (a digit) for n, consistently with other forms that +originated in AT&T troff, like \*, \$, +\f, \g, \k, \n, and \z. In +compatibility mode only, a non-zero n must be in the range +4–39. Legacy documents relying upon this quirk of parsing120 should be migrated to another +\s form. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Concept-Index.html b/doc/groff.html.node/Concept-Index.html new file mode 100644 index 0000000..3adcfcb --- /dev/null +++ b/doc/groff.html.node/Concept-Index.html @@ -0,0 +1,2359 @@ + + + + + + +Concept Index (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

Appendix J Concept Index

+ +
+
Jump to:   " +   +% +   +& +   +' +   +( +   +) +   +* +   ++ +   +- +   +. +   +/ +   +8 +   +: +   +< +   += +   +> +   +[ +   +\ +   +] +   +| +   +
+A +   +B +   +C +   +D +   +E +   +F +   +G +   +H +   +I +   +J +   +K +   +L +   +M +   +N +   +O +   +P +   +Q +   +R +   +S +   +T +   +U +   +V +   +W +   +Y +   +Z +   +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

"
", as delimiter: Delimiters
", at end of sentence: Sentences
", at end of sentence: Using Symbols
", embedding in a macro argument: Calling Macros

%
%, as delimiter: Delimiters

&
&, as delimiter: Delimiters

'
', as a comment: Comments
', as delimiter: Delimiters
', at end of sentence: Sentences
', at end of sentence: Using Symbols

(
(, as delimiter: Delimiters

)
), as delimiter: Delimiters
), at end of sentence: Sentences
), at end of sentence: Using Symbols

*
*, as delimiter: Delimiters
*, at end of sentence: Sentences
*, at end of sentence: Using Symbols

+
+, and page motion: Numeric Expressions
+, as delimiter: Delimiters

-
-, and page motion: Numeric Expressions
-, as delimiter: Delimiters

.
., as delimiter: Delimiters
.h register, difference from nl: Diversions
.ps register, in comparison with .psr: Using Fractional Type Sizes
.s register, in comparison with .sr: Using Fractional Type Sizes
.S register, Plan 9 alias for .tabs: Tabs and Fields
.t register, and diversions: Diversion Traps
.tabs register, Plan 9 alias (.S): Tabs and Fields
.V register, and vs: Changing the Vertical Spacing

/
/, as delimiter: Delimiters

8
8-bit input: Font Description File Format

:
:, as delimiter: Delimiters

<
<, as delimiter: Delimiters

=
=, as delimiter: Delimiters

>
>, as delimiter: Delimiters

[
[, macro names starting with, and refer: Identifiers

\
\!, and copy mode: Diversions
\!, and output request: Diversions
\!, and trnt: Character Translations
\!, as delimiter: Delimiters
\!, as delimiter: Delimiters
\!, in top-level diversion: Diversions
\!, incompatibilities with AT&T troff: Other Differences
\!, incompatibilities with AT&T troff: Other Differences
\$, when reading text for a macro: Copy Mode
\%, and translations: Character Translations
\%, as delimiter: Delimiters
\%, as delimiter: Delimiters
\%, following \X or \Y: Manipulating Hyphenation
\%, in \X: Postprocessor Access
\%, incompatibilities with AT&T troff: Other Differences
\&, and glyph definitions: Using Symbols
\&, and translations: Character Translations
\&, as delimiter: Delimiters
\&, at end of sentence: Sentences
\&, in \X: Postprocessor Access
\&, incompatibilities with AT&T troff: Other Differences
\', and translations: Character Translations
\', as delimiter: Delimiters
\', as delimiter: Delimiters
\', incompatibilities with AT&T troff: Other Differences
\(, and translations: Character Translations
\), as delimiter: Delimiters
\), in \X: Postprocessor Access
\*, and warnings: Warnings
\*, incompatibilities with AT&T troff: Compatibility Mode
\*, when reading text for a macro: Copy Mode
\, disabling (eo): Using Escape Sequences
\, embedding in a macro argument: Calling Macros
\,, as delimiter: Delimiters
\- glyph, and cflags: Using Symbols
\-, and translations: Character Translations
\-, as delimiter: Delimiters
\-, as delimiter: Delimiters
\-, incompatibilities with AT&T troff: Other Differences
\/, as delimiter: Delimiters
\/, as delimiter: Delimiters
\0, as delimiter: Delimiters
\:, as delimiter: Delimiters
\:, as delimiter: Delimiters
\:, in \X: Postprocessor Access
\?, and copy mode: Operators in Conditionals
\?, and copy mode: Diversions
\?, as delimiter: Delimiters
\?, in top-level diversion: Diversions
\?, incompatibilities with AT&T troff: Other Differences
\a, and copy mode: Leaders
\a, and translations: Character Translations
\a, as delimiter: Delimiters
\A, delimiters allowed by: Delimiters
\A, incompatibilities with AT&T troff: Other Differences
\b, delimiters allowed by: Delimiters
\b, limitations of: Drawing Geometric Objects
\C, and translations: Character Translations
\c, as delimiter: Delimiters
\c, as delimiter: Delimiters
\c, incompatibilities with AT&T troff: Other Differences
\c, when filling disabled: Line Continuation
\c, when filling enabled: Line Continuation
\d, as delimiter: Delimiters
\D, delimiters allowed by: Delimiters
\e, and glyph definitions: Using Symbols
\e, and translations: Character Translations
\e, as delimiter: Delimiters
\E, as delimiter: Delimiters
\e, as delimiter: Delimiters
\e, incompatibilities with AT&T troff: Other Differences
\F, and changing fonts: Selecting Fonts
\f, and font translations: Selecting Fonts
\f, incompatibilities with AT&T troff: Compatibility Mode
\h, delimiters allowed by: Delimiters
\H, delimiters allowed by: Delimiters
\H, incompatibilities with AT&T troff: Compatibility Mode
\H, using + and - with: Numeric Expressions
\H, with fractional type sizes: Using Fractional Type Sizes
\l, and glyph definitions: Using Symbols
\L, and glyph definitions: Using Symbols
\l, delimiters allowed by: Delimiters
\L, delimiters allowed by: Delimiters
\N, and translations: Character Translations
\n, and warnings: Warnings
\N, delimiters allowed by: Delimiters
\n, incompatibilities with AT&T troff: Compatibility Mode
\n, when reading text for a macro: Copy Mode
\o, delimiters allowed by: Delimiters
\p, as delimiter: Delimiters
\p, as delimiter: Delimiters
\R, after \c: Line Continuation
\R, and warnings: Warnings
\r, as delimiter: Delimiters
\R, delimiters allowed by: Delimiters
\R, difference from nr: Auto-increment
\R, using + and - with: Numeric Expressions
\RET, when reading text for a macro: Copy Mode
\s, delimiters allowed by: Delimiters
\S, delimiters allowed by: Delimiters
\s, incompatibilities with AT&T troff: Compatibility Mode
\S, incompatibilities with AT&T troff: Compatibility Mode
\s, incompatibilities with AT&T troff: Compatibility Mode
\s, using + and - with: Numeric Expressions
\s, with fractional type sizes: Using Fractional Type Sizes
\SP, as delimiter: Delimiters
\SP, difference from \~: Calling Macros
\SP, incompatibilities with AT&T troff: Other Differences
\t, and copy mode: Tabs and Fields
\t, and translations: Character Translations
\t, and warnings: Warnings
\t, as delimiter: Delimiters
\u, as delimiter: Delimiters
\V, and copy mode: I/O
\v, delimiters allowed by: Delimiters
\v, internal representation: Gtroff Internals
\w, delimiters allowed by: Delimiters
\X, and special characters: Postprocessor Access
\X, delimiters allowed by: Delimiters
\x, delimiters allowed by: Delimiters
\X, followed by \%: Manipulating Hyphenation
\Y, followed by \%: Manipulating Hyphenation
\Z, delimiters allowed by: Delimiters
\[, and translations: Character Translations
\\, when reading text for a macro: Copy Mode
\^, as delimiter: Delimiters
\^, incompatibilities with AT&T troff: Other Differences
\_, and translations: Character Translations
\_, as delimiter: Delimiters
\_, as delimiter: Delimiters
\_, incompatibilities with AT&T troff: Other Differences
\`, and translations: Character Translations
\`, as delimiter: Delimiters
\`, as delimiter: Delimiters
\`, incompatibilities with AT&T troff: Other Differences
\{, as delimiter: Delimiters
\{, as delimiter: Delimiters
\{, incompatibilities with AT&T troff: Other Differences
\|, as delimiter: Delimiters
\|, incompatibilities with AT&T troff: Other Differences
\}, and warnings: Warnings
\}, as delimiter: Delimiters
\}, as delimiter: Delimiters
\}, incompatibilities with AT&T troff: Other Differences
\~, and translations: Character Translations
\~, as delimiter: Delimiters
\~, difference from \SP: Calling Macros
\~, incompatibilities with AT&T troff: Other Differences

]
], as part of an identifier: Identifiers
], at end of sentence: Sentences
], at end of sentence: Using Symbols
], macro names starting with, and refer: Identifiers

|
|, and page motion: Numeric Expressions

A
ab request, incompatibilities with AT&T troff: Other Differences
aborting (ab): Debugging
absolute (sic) position operator (|): Numeric Expressions
abstract font style: Using Fonts
abstract font style, setting up (sty): Font Families
accent marks [ms]: ms Legacy Features
access to postprocessor: Postprocessor Access
accessing unnamed glyphs with \N: Font Description File Format
activating kerning (kern): Ligatures and Kerning
activating ligatures (lg): Ligatures and Kerning
activating track kerning (tkf): Ligatures and Kerning
ad request, and hyphenation margin: Manipulating Hyphenation
ad request, and hyphenation space: Manipulating Hyphenation
addition: Numeric Expressions
additional inter-sentence space: Manipulating Filling and Adjustment
adjustment and filling, manipulating: Manipulating Filling and Adjustment
adjustment mode register (.j): Manipulating Filling and Adjustment
adjustment to both margins, difference from AT&T troff: Other Differences
Adobe Glyph List (AGL): Using Symbols
alias, diversion, creating (als): Strings
alias, diversion, removing (rm): Strings
alias, macro, creating (als): Strings
alias, macro, removing (rm): Strings
alias, register, creating (aln): Setting Registers
alias, register, removing (rr): Setting Registers
alias, string, creating (als): Strings
alias, string, removing (rm): Strings
aliasing fonts with third argument to fp request: Font Positions
als request, and \$0: Parameters
am, am1, ami requests, and warnings: Warnings
appending to a diversion (da, boxa): Diversions
appending to a file (opena): I/O
appending to a macro (am): Writing Macros
appending to a string (as): Strings
approximation output register (.A): Built-in Registers
arc, drawing (‘\D'a …'’): Drawing Geometric Objects
argument: Requests and Macros
arguments to macros: Calling Macros
arguments to macros, and tabs: Invoking Requests
arguments to requests: Invoking Requests
arguments to requests, and tabs: Invoking Requests
arguments, and compatibility mode: Gtroff Internals
arguments, to escape sequences, delimiting: Delimiters
arguments, to strings: Strings
arithmetic operators: Numeric Expressions
artificial fonts: Artificial Fonts
as, as1 requests, and comments: Comments
as, as1 requests, and warnings: Warnings
ASCII output encoding: Groff Options
asciify request, and writem: I/O
assertion (arithmetic operator): Numeric Expressions
assign number format to register (af): Assigning Register Formats
assignments, indirect: Interpolating Registers
assignments, nested: Interpolating Registers
AT&T ms, macro package differences: Differences from AT&T ms
attributes, character cell: Using Fonts
auto-incrementation of a register: Auto-increment
automatic font mounting: Selecting Fonts
automatic hyphenation: Manipulating Hyphenation
automatic hyphenation parameters: Manipulating Hyphenation
auxiliary macro package: Major Macro Packages
available glyphs, list of (groff_char(7) man page): Using Symbols

B
background: Background
background color name register (.M): Colors
backslash glyph, formatting (\[rs]): Using Escape Sequences
backslash, embedding in a macro argument: Calling Macros
backslash, printing (\\, \e, \E, \[rs]): Other Differences
backspace character, and translations: Character Translations
backtrace of input stack (backtrace): Debugging
baseline rule special character(\[ru]): Drawing Geometric Objects
baseline, text: Page Geometry
baseline, text: Manipulating Type Size and Vertical Spacing
basic scaling unit (u): Measurements
basic units: Page Geometry
basic units, conversion to: Measurements
basics of macro package usage: Basics
bd request, and font styles: Font Families
bd request, and font translations: Selecting Fonts
bd request, incompatibilities with AT&T troff: Other Differences
beginning diversion (di, box): Diversions
beginning of conditional block (\{): Conditional Blocks
blank line: Breaking
blank line macro (blm): Breaking
blank line macro (blm): Invoking Requests
blank line macro (blm): Blank Line Traps
blank line trap (blm): Invoking Requests
blank line traps: Blank Line Traps
blank lines, disabling: Manipulating Spacing
block, conditional, beginning (\{): Conditional Blocks
block, conditional, end (\}): Conditional Blocks
blocks, conditional: Conditional Blocks
body, of a while request: while
boldface, imitating (bd): Artificial Fonts
bottom margin: Page Location Traps
boundary-relative motion operator (|): Numeric Expressions
bounding box: Miscellaneous
box (diversion operation): Diversions
box request, and warnings: Warnings
box rule glyph (\[br]): Drawing Geometric Objects
box, boxa requests, and warnings: Warnings
boxa request, and dn (dl): Diversions
boxa request, and warnings: Warnings
boxes [ms]: ms keeps and displays
bp request, and top-level diversion: Page Control
bp request, and traps (.pe): Page Location Traps
bp request, causing implicit break: Manipulating Filling and Adjustment
bp request, incompatibilities with AT&T troff: Other Differences
bp request, using + and - with: Numeric Expressions
br glyph, and cflags: Using Symbols
brace escape sequence, closing (\}): Conditional Blocks
brace escape sequence, opening (\}): Conditional Blocks
brace escape sequences (\{, \}): Conditional Blocks
break: Breaking
break: Manipulating Filling and Adjustment
break (introduction): Basics
break request, in a while loop: while
break, page: Page Geometry
break, page: Page Control
break, page: The Implicit Page Trap
break, page (introduction): Basics
break, page, final: End-of-input Traps
break, page, prevented by vpt: Vertical Position Traps
breaking file names (\:): Manipulating Hyphenation
breaking URLs (\:): Manipulating Hyphenation
breaking without hyphens (\:): Manipulating Hyphenation
built-in register, removing: Built-in Registers
built-in registers: Built-in Registers
bulleted list, example markup [ms]: Lists in ms

C
c scaling unit: Measurements
calling a macro: Requests and Macros
calling macros: Calling Macros
capabilities of groff: groff Capabilities
case-transforming a string (stringdown, stringup): Strings
categories, warning: Warnings
CCSID 1047 output encoding (EBCDIC): Groff Options
ce request, causing implicit break: Manipulating Filling and Adjustment
ce request, difference from ‘.ad c: Manipulating Filling and Adjustment
cell, character, attributes: Using Fonts
centered text (filled): Manipulating Filling and Adjustment
centered text (unfilled): Manipulating Filling and Adjustment
centering lines (ce): Manipulating Filling and Adjustment
centering lines (introduction): Basics
centimeter scaling unit (c): Measurements
cf request, and copy mode: I/O
cf request, causing implicit break: Manipulating Filling and Adjustment
changing control characters: Control Characters
changing font family (fam, \F): Font Families
changing fonts (ft, \f): Selecting Fonts
changing format, and read-only registers: Assigning Register Formats
changing the font height (\H): Artificial Fonts
changing the font slant (\S): Artificial Fonts
changing the page number character (pc): Page Layout
changing trap location (ch): Page Location Traps
changing type sizes (ps, \s): Changing the Type Size
changing vertical line spacing (vs): Changing the Vertical Spacing
char request, and soft hyphen character: Manipulating Hyphenation
char request, and translations: Character Translations
char request, used with \N: Using Symbols
character: Using Symbols
character cell attributes: Using Fonts
character class (class): Character Classes
character classes: Character Classes
character properties (cflags): Using Symbols
character translations: Character Translations
character, backspace, and translations: Character Translations
character, control (.): Requests and Macros
character, control, changing (cc): Control Characters
character, defining (char): Using Symbols
character, defining fallback (fchar, fschar, schar): Using Symbols
character, distinguished from glyph: Using Symbols
character, dummy (\&): Dummy Characters
character, dummy (\&), as control character suppressor: Requests and Macros
character, dummy (\&), effect on kerning: Ligatures and Kerning
character, dummy (\&), effect on \l escape sequence: Drawing Geometric Objects
character, escape, changing (ec): Using Escape Sequences
character, escape, while defining glyph: Using Symbols
character, field delimiting (fc): Fields
character, field padding (fc): Fields
character, horizontal tab: Tabs and Leaders
character, hyphenation (\%): Manipulating Hyphenation
character, leader: Tabs and Leaders
character, leader repetition (lc): Leaders
character, leader, and translations: Character Translations
character, leader, non-interpreted (\a): Leaders
character, named (\C): Using Symbols
character, newline, and translations: Character Translations
character, no-break control ('): Requests and Macros
character, no-break control, changing (c2): Control Characters
character, ordinary: Identifiers
character, soft hyphen, setting (shc): Manipulating Hyphenation
character, special: Character Translations
character, tab repetition (tc): Tabs and Fields
character, tab, and translations: Character Translations
character, tab, non-interpreted (\t): Tabs and Fields
character, transparent: Using Symbols
character, transparent dummy (\)): Dummy Characters
characters, end-of-sentence: Using Symbols
characters, end-of-sentence transparent: Sentences
characters, hyphenation: Using Symbols
characters, input, and output glyphs, compatibility with AT&T troff: Other Differences
characters, invalid for trf request: I/O
characters, invalid input: Identifiers
characters, overlapping: Using Symbols
characters, special: Sentences
characters, special, list of (groff_char(7) man page): Using Symbols
characters, unnamed, accessing with \N: Font Description File Format
circle, filled, drawing (‘\D'C …'’): Drawing Geometric Objects
circle, outlined, drawing (‘\D'c …'’): Drawing Geometric Objects
circle, solid, drawing (‘\D'C …'’): Drawing Geometric Objects
circle, stroked, drawing (‘\D'c …'’): Drawing Geometric Objects
class of characters (class): Character Classes
classes, character: Character Classes
clearing input line trap (it, itc): Input Line Traps
closing brace escape sequence (\}): Conditional Blocks
closing file (close): I/O
code page 1047 output encoding: Groff Options
code page 1047, input encoding: Input Encodings
code, hyphenation (hcode): Manipulating Hyphenation
color name, background, register (.M): Colors
color name, fill, register (.M): Colors
color name, stroke, register (.m): Colors
color, default: Colors
color, fill: Colors
color, stroke: Colors
colors: Colors
command prefix: Environment
command-line options: Groff Options
comments: Comments
comments in device description files: DESC File Format
comments in font description files: Font Description File Format
comments, lining up with tabs: Comments
comments, with ds: Strings
common features: Common Features
common name space of macros, diversions, and strings: Identifiers
comparison of strings: Operators in Conditionals
comparison operators: Numeric Expressions
compatibility mode: Warnings
compatibility mode: Compatibility Mode
compatibility mode, and parameters: Gtroff Internals
complementation, logical: Numeric Expressions
composite glyph names: Using Symbols
conditional block, beginning (\{): Conditional Blocks
conditional block, end (\}): Conditional Blocks
conditional blocks: Conditional Blocks
conditional expressions: Operators in Conditionals
conditional output for terminal (TTY): Operators in Conditionals
conditional page break (ne): Page Control
conditionals and loops: Conditionals and Loops
configuring control characters: Control Characters
configuring the page length (pl): Page Layout
consecutive hyphenated lines (hlm): Manipulating Hyphenation
constant glyph space mode (cs): Artificial Fonts
contents, table of: Table of Contents
contents, table of: Leaders
continuation, input line (\RET): Line Continuation
continuation, output line (\c): Line Continuation
continue request, in a while loop: while
continued output line register (.int): Line Continuation
continuous underlining (cu): Artificial Fonts
control character (.): Requests and Macros
control character, changing (cc): Control Characters
control character, no-break ('): Requests and Macros
control character, no-break, changing (c2): Control Characters
control characters: Control Characters
control line: Requests and Macros
control, line: Line Continuation
control, page: Page Control
conventions for input: Input Conventions
conversion to basic units: Measurements
copy mode: Copy Mode
copy mode: Copy Mode
copy mode, and cf request: I/O
copy mode, and device request: Postprocessor Access
copy mode, and length request: Strings
copy mode, and macro parameters: Parameters
copy mode, and output request: Diversions
copy mode, and trf request: I/O
copy mode, and write request: I/O
copy mode, and writec request: I/O
copy mode, and writem request: I/O
copy mode, and \!: Diversions
copy mode, and \?: Operators in Conditionals
copy mode, and \?: Diversions
copy mode, and \a: Leaders
copy mode, and \t: Tabs and Fields
copy mode, and \V: I/O
copying environment (evc): Environments
correction between oblique and upright glyph (\/, \,): Italic Corrections
correction between upright and oblique glyph (\/, \,): Italic Corrections
correction, italic (\/): Italic Corrections
correction, left italic (\,): Italic Corrections
cover page in [ms], example markup: ms Document Description Macros
cp request, and glyph definitions: Using Symbols
cq glyph, at end of sentence: Sentences
cq glyph, at end of sentence: Using Symbols
creating alias for register (aln): Setting Registers
creating alias, for diversion (als): Strings
creating alias, for macro (als): Strings
creating alias, for string (als): Strings
creating new characters (char): Using Symbols
credits: Credits
cs request, and font styles: Font Families
cs request, and font translations: Selecting Fonts
cs request, incompatibilities with AT&T troff: Other Differences
cs request, with fractional type sizes: Using Fractional Type Sizes
CSTR #54 errata: Built-in Registers
CSTR #54 errata: Line Layout
CSTR #54 errata: Page Control
CSTR #54 errata: Artificial Fonts
CSTR #54 errata: Changing the Type Size
CSTR #54 errata: Page Motions
CSTR #54 erratum, bp request: Page Control
CSTR #54 erratum, po request: Line Layout
CSTR #54 erratum, ps request: Changing the Type Size
CSTR #54 erratum, sb register: Page Motions
CSTR #54 erratum, st register: Page Motions
CSTR #54 erratum, yr register: Built-in Registers
CSTR #54 erratum, \S escape: Artificial Fonts
CSTR #54 erratum, \s escape sequence: Changing the Type Size
current directory: Macro Directories
current input file name register (.F): Built-in Registers
current page number (%): Page Control
current time, hours (hours): Built-in Registers
current time, minutes (minutes): Built-in Registers
current time, seconds (seconds): Built-in Registers

D
da request, and dn (dl): Diversions
da request, and warnings: Warnings
da request, and warnings: Warnings
date, day of the month register (dy): Built-in Registers
date, day of the week register (dw): Built-in Registers
date, month of the year register (mo): Built-in Registers
date, year register (year, yr): Built-in Registers
day of the month register (dy): Built-in Registers
day of the week register (dw): Built-in Registers
dd glyph, at end of sentence: Sentences
dd glyph, at end of sentence: Using Symbols
de request, and while: while
de, de1, dei requests, and warnings: Warnings
debugging: Debugging
debugging page location traps: Page Location Traps
decimal point, as delimiter: Delimiters
decrementation, automatic, of a register: Auto-increment
default color: Colors
default tab stops: Tabs and Fields
default units: Default Units
deferred output: Deferring Output
defining character (char): Using Symbols
defining character class (class): Character Classes
defining fallback character (fchar, fschar, schar): Using Symbols
defining glyph (char): Using Symbols
defining symbol (char): Using Symbols
delimited arguments, incompatibilities with AT&T troff: Compatibility Mode
delimiters, for escape sequence arguments: Delimiters
delimiting character, for fields (fc): Fields
delimiting escape sequence arguments: Delimiters
depth, interpolation: Calling Macros
depth, of last glyph (.cdp): Environments
DESC file format: DESC File Format
DESC file, and font mounting: Font Positions
DESC file, and use_charnames_in_special keyword: Postprocessor Access
description file, font: Using Fonts
device description files, comments: DESC File Format
device request, and copy mode: Postprocessor Access
device resolution: Page Geometry
device resolution: DESC File Format
device resolution, obtaining in the formatter: Measurements
devices for output: Output Device Intro
dg glyph, at end of sentence: Sentences
dg glyph, at end of sentence: Using Symbols
di request, and warnings: Warnings
di request, and warnings: Warnings
differences in implementation: Implementation Differences
digit-width space (\0): Page Motions
digits, as delimiters: Delimiters
dimensions, line: Line Layout
directories for fonts: Font Directories
directories for macros: Macro Directories
directory, current: Macro Directories
directory, for tmac files: Macro Directories
directory, home: Macro Directories
directory, platform-specific: Macro Directories
directory, site-local: Macro Directories
directory, site-local: Font Directories
disabling hyphenation (\%): Manipulating Hyphenation
disabling \ (eo): Using Escape Sequences
discardable horizontal space: Manipulating Filling and Adjustment
displays: Displays and Keeps
displays [ms]: ms keeps and displays
displays, and footnotes [ms]: ms Footnotes
distance to next vertical position trap register (.t): Page Location Traps
diversion: Deferring Output
diversion name register (.z): Diversions
diversion trap, setting (dt): Diversion Traps
diversion traps: Diversion Traps
diversion, appending to (da, boxa): Diversions
diversion, beginning (di, box): Diversions
diversion, creating alias for (als): Strings
diversion, ending (di, box): Diversions
diversion, nested: Diversions
diversion, removing (rm): Strings
diversion, removing alias for (rm): Strings
diversion, renaming (rn): Strings
diversion, stripping final newline: Punning Names
diversion, top-level: Diversions
diversion, top-level, and bp: Page Control
diversion, top-level, and \!: Diversions
diversion, top-level, and \?: Diversions
diversion, unformatting (asciify): Diversions
diversion, vertical position in, register (.d): Diversions
diversions: Diversions
diversions: Punning Names
diversions, and traps: Page Location Traps
diversions, shared name space with macros and strings: Identifiers
division, truncating: Numeric Expressions
dl register, and da (boxa): Diversions
dn register, and da (boxa): Diversions
document description macros, [ms]: ms Document Description Macros
document formats: Document Formats
documents, multi-file: Debugging
documents, structuring the source of: Invoking Requests
dot, as delimiter: Delimiters
double quote, embedding in a macro argument: Calling Macros
double quotes, trailing, in strings: Strings
double-spacing (ls): Manipulating Spacing
double-spacing (vs, pvs): Changing the Vertical Spacing
down-casing a string (stringdown): Strings
drawing a filled circle (‘\D'C …'’): Drawing Geometric Objects
drawing a filled ellipse (‘\D'E …'’): Drawing Geometric Objects
drawing a filled polygon (‘\D'P …'’): Drawing Geometric Objects
drawing a line (‘\D'l …'’): Drawing Geometric Objects
drawing a solid circle (‘\D'C …'’): Drawing Geometric Objects
drawing a solid ellipse (‘\D'E …'’): Drawing Geometric Objects
drawing a solid polygon (‘\D'P …'’): Drawing Geometric Objects
drawing a spline (‘\D'~ …'’): Drawing Geometric Objects
drawing a stroked circle (‘\D'c …'’): Drawing Geometric Objects
drawing a stroked ellipse (‘\D'e …'’): Drawing Geometric Objects
drawing a stroked polygon (‘\D'p …'’): Drawing Geometric Objects
drawing an arc (‘\D'a …'’): Drawing Geometric Objects
drawing an outlined circle (‘\D'c …'’): Drawing Geometric Objects
drawing an outlined ellipse (‘\D'e …'’): Drawing Geometric Objects
drawing an outlined polygon (‘\D'p …'’): Drawing Geometric Objects
drawing horizontal lines (\l): Drawing Geometric Objects
drawing position: Page Geometry
drawing position, vertical (nl): Page Control
drawing requests: Drawing Geometric Objects
drawing vertical lines (\L): Drawing Geometric Objects
ds request, and comments: Strings
ds request, and double quotes: Strings
ds request, and leading spaces: Strings
ds, ds1 requests, and comments: Comments
ds, ds1 requests, and warnings: Warnings
dummy character (\&): Dummy Characters
dummy character (\&), as control character suppressor: Requests and Macros
dummy character (\&), effect on kerning: Ligatures and Kerning
dummy character (\&), effect on \l escape sequence: Drawing Geometric Objects
dummy character, transparent (\)): Dummy Characters
dummy environment, used by \w escape sequence: Page Motions
dumping environments (pev): Debugging
dumping page location traps (ptr): Debugging
dumping registers (pnr): Debugging
dumping symbol table (pm): Debugging

E
EBCDIC output encoding: Groff Options
EBCDIC, input encoding: Input Encodings
ejection, page: Page Geometry
ejection, page: Page Control
ejection, page: The Implicit Page Trap
ejection, page, of final page: End-of-input Traps
ejection, page, prevented by vpt: Vertical Position Traps
el request, and warnings: Warnings
ellipse, filled, drawing (‘\D'E …'’): Drawing Geometric Objects
ellipse, outlined, drawing (‘\D'e …'’): Drawing Geometric Objects
ellipse, solid, drawing (‘\D'E …'’): Drawing Geometric Objects
ellipse, stroked, drawing (‘\D'e …'’): Drawing Geometric Objects
em glyph, and cflags: Using Symbols
em scaling unit (m): Measurements
embolding of special fonts: Artificial Fonts
empty line: Breaking
en scaling unit (n): Measurements
enabling vertical position traps (vpt): Vertical Position Traps
encoding, input, code page 1047: Input Encodings
encoding, input, EBCDIC: Input Encodings
encoding, input, Latin-1 (ISO 8859-1): Input Encodings
encoding, input, Latin-2 (ISO 8859-2): Input Encodings
encoding, input, Latin-5 (ISO 8859-9): Input Encodings
encoding, input, Latin-9 (ISO 8859-15): Input Encodings
encoding, output, ASCII: Groff Options
encoding, output, code page 1047: Groff Options
encoding, output, EBCDIC: Groff Options
encoding, output, ISO 646: Groff Options
encoding, output, Latin-1 (ISO 8859-1): Groff Options
encoding, output, UTF-8: Groff Options
end of conditional block (\}): Conditional Blocks
end-of-input macro (em): End-of-input Traps
end-of-input trap, setting (em): End-of-input Traps
end-of-input traps: End-of-input Traps
end-of-sentence characters: Sentences
end-of-sentence characters: Using Symbols
end-of-sentence transparent characters: Sentences
ending diversion (di, box): Diversions
endnotes: Footnotes and Endnotes
environment: Deferring Output
environment availability and naming, incompatibilities with: Other Differences
environment number/name register (.ev): Environments
environment variables: Environment
environment, copying (evc): Environments
environment, dimensions of last glyph (.w, .cht, .cdp, .csk): Environments
environment, dummy, used by \w escape sequence: Page Motions
environment, previous line length (.n): Environments
environment, switching (ev): Environments
environments: Environments
environments, dumping (pev): Debugging
equality operator: Numeric Expressions
equation example [ms]: ms Insertions
equations [ms]: ms Insertions
escape character, changing (ec): Using Escape Sequences
escape character, formatting (\e): Using Escape Sequences
escape character, while defining glyph: Using Symbols
escape sequence: Formatter Instructions
escape sequence argument delimiters: Delimiters
escape sequences: Using Escape Sequences
escape sequences, brace (\{, \}): Conditional Blocks
escaping newline characters, in strings: Strings
ex request, use in debugging: Debugging
ex request, used with nx and rd: I/O
example markup, bulleted list [ms]: Lists in ms
example markup, cover page in [ms]: ms Document Description Macros
example markup, glossary-style list [ms]: Lists in ms
example markup, numbered list [ms]: Lists in ms
examples of invocation: Invocation Examples
exiting (ex): Debugging
expansion of strings (\*): Strings
explicit hyphen (\%): Manipulating Hyphenation
explicit hyphenation: Manipulating Hyphenation
expression, limitation of logical not in: Numeric Expressions
expression, order of evaluation: Numeric Expressions
expressions, and register format: Assigning Register Formats
expressions, and space characters: Numeric Expressions
expressions, conditional: Operators in Conditionals
expressions, numeric: Numeric Expressions
extra post-vertical line space (\x): Changing the Vertical Spacing
extra post-vertical line space register (.a): Manipulating Spacing
extra pre-vertical line space (\x): Changing the Vertical Spacing
extra spaces between words: Adjustment
extreme values representable with Roman numerals: Assigning Register Formats
extremum operators (>?, <?): Numeric Expressions

F
f scaling unit: Colors
factor, zoom, of a font (fzoom): Selecting Fonts
fallback character, defining (fchar, fschar, schar): Using Symbols
fallback glyph, removing definition (rchar, rfschar): Using Symbols
fam request, and changing fonts: Selecting Fonts
families, font: Font Families
family, font: Using Fonts
features, common: Common Features
fi request, causing implicit break: Manipulating Filling and Adjustment
field delimiting character (fc): Fields
field padding character (fc): Fields
fields: Fields
fields, and tabs: Tabs and Fields
figure space (\0): Page Motions
figures [ms]: ms Insertions
file formats: File Formats
file names, breaking (\:): Manipulating Hyphenation
file, appending to (opena): I/O
file, closing (close): I/O
file, font description: Using Fonts
file, inclusion (so): I/O
file, macro, search path: Macro Directories
file, opening (open): I/O
file, processing next (nx): I/O
file, writing to (write, writec): I/O
files, font: Device and Font Description Files
fill color: Colors
fill color name register (.M): Colors
fill mode (fi), enabling: Manipulating Filling and Adjustment
fill mode, and \c: Line Continuation
fill mode, disabling: Manipulating Filling and Adjustment
filled circle, drawing (‘\D'C …'’): Drawing Geometric Objects
filled ellipse, drawing (‘\D'E …'’): Drawing Geometric Objects
filled polygon, drawing (‘\D'P …'’): Drawing Geometric Objects
filling: Filling
filling and adjustment, manipulating: Manipulating Filling and Adjustment
filling of output, disabling (nf): Manipulating Filling and Adjustment
filling of output, enabling (fi): Manipulating Filling and Adjustment
filling, and break warnings: Warnings
filling, and inter-sentence space: Manipulating Filling and Adjustment
final newline, stripping in diversions: Punning Names
fl request, causing implicit break: Manipulating Filling and Adjustment
floating keep: Displays and Keeps
flush output (fl): Debugging
font: Using Fonts
font aliasing with third argument to fp request: Font Positions
font description file: Using Fonts
font description file format: DESC File Format
font description file, format: Font Description File Format
font description files, comments: Font Description File Format
font directories: Font Directories
font families: Font Families
font family: Using Fonts
font family, changing (fam, \F): Font Families
font file, format: Font Description File Format
font files: Device and Font Description Files
font for underlining (uf): Artificial Fonts
font height, changing (\H): Artificial Fonts
font metrics: Using Fonts
font mounting, automatic: Selecting Fonts
font path: Font Directories
font position register (.f): Font Positions
font positions: Font Positions
font slant, changing (\S): Artificial Fonts
font style: Using Fonts
font style, abstract: Using Fonts
font style, abstract, setting up (sty): Font Families
font styles: Font Families
font translation (ftr): Selecting Fonts
font, magnification (fzoom): Selecting Fonts
font, mounting (fp): Font Positions
font, optical size: Selecting Fonts
font, previous, selecting (\f[], \fP): Selecting Fonts
font, previous, slecting (ft): Selecting Fonts
font, selection: Selecting Fonts
font, special: Using Fonts
font, text: Using Fonts
font, unstyled: Using Fonts
font, zoom factor (fzoom): Selecting Fonts
fonts, artificial: Artificial Fonts
fonts, changing (ft, \f): Selecting Fonts
fonts, searching: Font Directories
fonts, special: Special Fonts
footers: Page Layout
footers: Page Location Traps
footers [ms]: ms Headers and Footers
footnote marker [ms]: ms Footnotes
footnotes: Footnotes and Endnotes
footnotes [ms]: ms Footnotes
footnotes, and displays [ms]: ms Footnotes
footnotes, and keeps [ms]: ms Footnotes
form letters: I/O
format of font description file: DESC File Format
format of font description files: Font Description File Format
format of font files: Font Description File Format
format of register (\g): Assigning Register Formats
format, paper: Paper Format
formats, file: File Formats
formatter instructions: Formatter Instructions
formatting a backslash glyph (\[rs]): Using Escape Sequences
formatting a title line (tl): Page Layout
formatting the escape character (\e): Using Escape Sequences
formatting the time: I/O
fp request, and font translations: Selecting Fonts
fp request, incompatibilities with AT&T troff: Other Differences
fractional point sizes: Using Fractional Type Sizes
fractional point sizes: Other Differences
fractional type sizes: Using Fractional Type Sizes
fractional type sizes: Other Differences
fractional type sizes in ms macros: Differences from AT&T ms
French spacing: Sentences
fspecial request, and font styles: Font Families
fspecial request, and font translations: Selecting Fonts
fspecial request, and glyph search order: Using Symbols
fspecial request, and imitating bold: Artificial Fonts
ft request, and font translations: Selecting Fonts
full-service macro package: Major Macro Packages

G
geometry, page: Page Geometry
GGL (groff glyph list): Using Symbols
GGL (groff glyph list): Character Classes
glossary-style list, example markup [ms]: Lists in ms
glyph: Using Symbols
glyph for line drawing: Drawing Geometric Objects
glyph names, composite: Using Symbols
glyph pile (\b): Drawing Geometric Objects
glyph properties (cflags): Using Symbols
glyph, box rule (\[br]): Drawing Geometric Objects
glyph, constant space: Artificial Fonts
glyph, defining (char): Using Symbols
glyph, distinguished from character: Using Symbols
glyph, for line drawing: Drawing Geometric Objects
glyph, for margins (mc): Miscellaneous
glyph, last, dimensions (.w, .cht, .cdp, .csk): Environments
glyph, leader repetition (lc): Leaders
glyph, numbered (\N): Character Translations
glyph, numbered (\N): Using Symbols
glyph, removing definition (rchar, rfschar): Using Symbols
glyph, soft hyphen (hy): Manipulating Hyphenation
glyph, tab repetition (tc): Tabs and Fields
glyph, underscore (\[ru]): Drawing Geometric Objects
glyphs, available, list of (groff_char(7) man page): Using Symbols
glyphs, output, and input characters, compatibility with AT&T troff: Other Differences
glyphs, overstriking (\o): Page Motions
glyphs, unnamed: Using Symbols
glyphs, unnamed, accessing with \N: Font Description File Format
GNU troff, identification register (.g): Built-in Registers
GNU troff, PID register ($$): Built-in Registers
GNU troff, process ID register ($$): Built-in Registers
GNU-specific register (.g): Built-in Registers
graphic renditions: Using Fonts
greater than (or equal to) operator: Numeric Expressions
groff capabilities: groff Capabilities
groff glyph list (GGL): Using Symbols
groff glyph list (GGL): Character Classes
groff invocation: Invoking groff
groff, and pi request: I/O
groff—what is it?: What Is groff?
GROFF_BIN_PATH, environment variable: Environment
GROFF_COMMAND_PREFIX, environment variable: Environment
GROFF_ENCODING, environment variable: Environment
GROFF_FONT_PATH, environment variable: Environment
GROFF_FONT_PATH, environment variable: Font Directories
GROFF_TMAC_PATH, environment variable: Environment
GROFF_TMAC_PATH, environment variable: Macro Directories
GROFF_TMPDIR, environment variable: Environment
GROFF_TYPESETTER, environment variable: Environment
grohtml, the program: Groff Options
gtroff, interactive use: Debugging
gtroff, output: gtroff Output
gtroff, reference: GNU troff Reference

H
hair space (\^): Page Motions
hcode request, and glyph definitions: Using Symbols
headers: Page Layout
headers: Page Location Traps
headers [ms]: ms Headers and Footers
height, font, changing (\H): Artificial Fonts
height, of last glyph (.cht): Environments
high-water mark register (.h): Diversions
home directory: Macro Directories
horizontal discardable space: Manipulating Filling and Adjustment
horizontal input line position register (hp): Page Motions
horizontal input line position, saving (\k): Page Motions
horizontal line, drawing (\l): Drawing Geometric Objects
horizontal motion (\h): Page Motions
horizontal motion quantum: DESC File Format
horizontal motion quantum register (.H): Motion Quanta
horizontal output line position register (.k): Page Motions
horizontal resolution: DESC File Format
horizontal resolution register (.H): Motion Quanta
horizontal space (\h): Page Motions
horizontal space, unformatting: Punning Names
horizontal tab character: Tabs and Leaders
hours, current time (hours): Built-in Registers
hpf request, and hyphenation language: Manipulating Hyphenation
hw request, and hy restrictions: Manipulating Hyphenation
hw request, and hyphenation language: Manipulating Hyphenation
hy glyph, and cflags: Using Symbols
hyphen, explicit (\%): Manipulating Hyphenation
hyphenated lines, consecutive (hlm): Manipulating Hyphenation
hyphenating characters: Using Symbols
hyphenation: Hyphenation
hyphenation character (\%): Manipulating Hyphenation
hyphenation code (hcode): Manipulating Hyphenation
hyphenation consecutive line count register (.hlc): Manipulating Hyphenation
hyphenation consecutive line limit register (.hlm): Manipulating Hyphenation
hyphenation exceptions: Manipulating Hyphenation
hyphenation language register (.hla): Manipulating Hyphenation
hyphenation margin (hym): Manipulating Hyphenation
hyphenation margin register (.hym): Manipulating Hyphenation
hyphenation mode register (.hy): Manipulating Hyphenation
hyphenation parameters, automatic: Manipulating Hyphenation
hyphenation pattern files: Manipulating Hyphenation
hyphenation patterns (hpf): Manipulating Hyphenation
hyphenation space (hys): Manipulating Hyphenation
hyphenation space adjustment threshold: Manipulating Hyphenation
hyphenation space adjustment threshold register (.hys): Manipulating Hyphenation
hyphenation, automatic: Manipulating Hyphenation
hyphenation, disabling (\%): Manipulating Hyphenation
hyphenation, explicit: Manipulating Hyphenation
hyphenation, incompatibilities with AT&T troff: Other Differences
hyphenation, manipulating: Manipulating Hyphenation
hyphenation, manual: Manipulating Hyphenation

I
i scaling unit: Measurements
i/o: I/O
IBM code page 1047 input encoding: Input Encodings
IBM code page 1047 output encoding: Groff Options
identifiers: Identifiers
identifiers, undefined: Identifiers
ie request, and font translations: Selecting Fonts
ie request, and warnings: Warnings
ie request, operators to use with: Operators in Conditionals
if request, and font translations: Selecting Fonts
if request, and the ‘!’ operator: Numeric Expressions
if request, operators to use with: Operators in Conditionals
if-else: if-else
if-then: if-then
imitating boldface (bd): Artificial Fonts
implementation differences: Implementation Differences
implicit line break: Breaking
implicit trap: The Implicit Page Trap
in request, causing implicit break: Manipulating Filling and Adjustment
in request, using + and - with: Numeric Expressions
inch scaling unit (i): Measurements
including a file (so): I/O
incompatibilities with AT&T troff: Implementation Differences
increment value without changing the register: Auto-increment
incrementation, automatic, of a register: Auto-increment
indentation (in): Line Layout
indentation, of roff source code: Invoking Requests
index, in macro package: Indexing
indicator, scaling: Measurements
indirect assignments: Interpolating Registers
input and output requests: I/O
input characters and output glyphs, compatibility with AT&T troff: Other Differences
input characters, invalid: Identifiers
input conventions: Input Conventions
input encoding, code page 1047: Input Encodings
input encoding, EBCDIC: Input Encodings
input encoding, Latin-1 (ISO 8859-1): Input Encodings
input encoding, Latin-2 (ISO 8859-2): Input Encodings
input encoding, Latin-5 (ISO 8859-9): Input Encodings
input encoding, Latin-9 (ISO 8859-15): Input Encodings
input file name, current, register (.F): Built-in Registers
input level: Calling Macros
input level in delimited arguments: Compatibility Mode
input line continuation (\RET): Line Continuation
input line number register (.c, c.): Built-in Registers
input line number, setting (lf): Debugging
input line position, horizontal, saving (\k): Page Motions
input line trap, clearing (it, itc): Input Line Traps
input line trap, setting (it, itc): Input Line Traps
input line traps: Input Line Traps
input line traps and interrupted lines (itc): Input Line Traps
input line, horizontal position, register (hp): Page Motions
input line, productive: Manipulating Filling and Adjustment
input stack, backtrace (backtrace): Debugging
input stack, setting limit: Debugging
input token: Gtroff Internals
input, 8-bit: Font Description File Format
input, standard, reading from (rd): I/O
inserting horizontal space (\h): Page Motions
installation: Installation
instructing the formatter: Formatter Instructions
inter-sentence space size register (.sss): Manipulating Filling and Adjustment
inter-sentence space, additional: Manipulating Filling and Adjustment
inter-word spacing, minimal: Manipulating Filling and Adjustment
interactive use of gtroff: Debugging
intercepting requests: Control Characters
intermediate output: gtroff Output
interpolating registers (\n): Interpolating Registers
interpolation: Requests and Macros
interpolation depth: Calling Macros
interpolation depth in delimited arguments: Compatibility Mode
interpolation of strings (\*): Strings
interpretation mode: Copy Mode
interrupted line: Line Continuation
interrupted line register (.int): Line Continuation
interrupted lines and input line traps (itc): Input Line Traps
introduction: Introduction
invalid characters for trf request: I/O
invalid input characters: Identifiers
invocation examples: Invocation Examples
invoking groff: Invoking groff
invoking requests: Invoking Requests
ISO 646 output encoding: Groff Options
ISO 8859-1 (Latin-1) output encoding: Groff Options
ISO 8859-1 (Latin-1), input encoding: Input Encodings
ISO 8859-15 (Latin-9), input encoding: Input Encodings
ISO 8859-2 (Latin-2), input encoding: Input Encodings
ISO 8859-9 (Latin-5), input encoding: Input Encodings
italic correction (\/): Italic Corrections

J
justifying text: Manipulating Filling and Adjustment
justifying text (rj): Manipulating Filling and Adjustment

K
keep, floating: Displays and Keeps
keeps (introduction): Displays and Keeps
keeps [ms]: ms keeps and displays
keeps, and footnotes [ms]: ms Footnotes
kerning and ligatures: Ligatures and Kerning
kerning enabled register (.kern): Ligatures and Kerning
kerning, activating (kern): Ligatures and Kerning
kerning, track: Ligatures and Kerning

L
landscape page orientation: Paper Format
language [ms]: ms language and localization
last glyph, dimensions (.w, .cht, .cdp, .csk): Environments
last-requested point size registers (.psr, .sr): Using Fractional Type Sizes
last-requested type size registers (.psr, .sr): Using Fractional Type Sizes
Latin-1 (ISO 8859-1) output encoding: Groff Options
Latin-1 (ISO 8859-1), input encoding: Input Encodings
Latin-2 (ISO 8859-2), input encoding: Input Encodings
Latin-5 (ISO 8859-9), input encoding: Input Encodings
Latin-9 (ISO 8859-15), input encoding: Input Encodings
layout, line: Line Layout
layout, page: Page Layout
lc request, and glyph definitions: Using Symbols
leader character: Tabs and Leaders
leader character: Leaders
leader character, and translations: Character Translations
leader character, non-interpreted (\a): Leaders
leader repetition character (lc): Leaders
leaders: Leaders
leading: Manipulating Type Size and Vertical Spacing
leading space macro (lsm): Breaking
leading space traps: Leading Space Traps
leading spaces: Breaking
leading spaces macro (lsm): Leading Space Traps
leading spaces with ds: Strings
left italic correction (\,): Italic Corrections
left margin (po): Line Layout
length of a string (length): Strings
length of line (ll): Line Layout
length of previous line (.n): Environments
length of the page, configuring (pl): Page Layout
length of title line, configuring (lt): Page Layout
length request, and copy mode: Strings
less than (or equal to) operator: Numeric Expressions
letters, form: I/O
level, input: Calling Macros
level, suppression nesting, register: Suppressing Output
lf request, incompatibilities with AT&T troff: Other Differences
ligature: Using Symbols
ligatures and kerning: Ligatures and Kerning
ligatures enabled register (.lg): Ligatures and Kerning
ligatures, activating (lg): Ligatures and Kerning
limitations of \b escape sequence: Drawing Geometric Objects
line break: Manipulating Filling and Adjustment
line break (introduction): Basics
line break, output: Breaking
line control: Line Continuation
line dimensions: Line Layout
line drawing glyph: Drawing Geometric Objects
line drawing glyph: Drawing Geometric Objects
line indentation (in): Line Layout
line layout: Line Layout
line length (ll): Line Layout
line length register (.l): Line Layout
line length, previous (.n): Environments
line number, input, register (.c, c.): Built-in Registers
line number, output, register (ln): Miscellaneous
line numbers, printing (nm): Miscellaneous
line space, extra post-vertical (\x): Changing the Vertical Spacing
line space, extra pre-vertical (\x): Changing the Vertical Spacing
line spacing register (.L): Manipulating Spacing
line spacing, post-vertical (pvs): Changing the Vertical Spacing
line thickness (‘\D't …'’): Drawing Geometric Objects
line, blank: Breaking
line, drawing (‘\D'l …'’): Drawing Geometric Objects
line, horizontal, drawing (\l): Drawing Geometric Objects
line, input, continuation (\RET): Line Continuation
line, input, horizontal position, register (hp): Page Motions
line, input, horizontal position, saving (\k): Page Motions
line, interrupted: Line Continuation
line, output, continuation (\c): Line Continuation
line, output, horizontal position, register (.k): Page Motions
line, productive input: Manipulating Filling and Adjustment
line, vertical, drawing (\L): Drawing Geometric Objects
line-tabs mode: Tabs and Fields
lines, blank, disabling: Manipulating Spacing
lines, centering (ce): Manipulating Filling and Adjustment
lines, centering (introduction): Basics
lines, consecutive hyphenated (hlm): Manipulating Hyphenation
lines, interrupted, and input line traps (itc): Input Line Traps
lines, right-aligning (introduction): Basics
lines, right-justifying (introduction): Basics
list of special characters (groff_char(7) man page): Using Symbols
listing page location traps (ptr): Debugging
lists: Paragraphs
ll request, using + and - with: Numeric Expressions
localization: Manipulating Hyphenation
localization [ms]: ms language and localization
locating macro files: Macro Directories
locating macro packages: Macro Directories
location, vertical, page, marking (mk): Page Motions
location, vertical, page, returning to marked (rt): Page Motions
logical “and” operator: Numeric Expressions
logical “or” operator: Numeric Expressions
logical complementation operator: Numeric Expressions
logical conjunction operator: Numeric Expressions
logical disjunction operator: Numeric Expressions
logical not, limitation in expression: Numeric Expressions
logical operators: Numeric Expressions
long names: Compatibility Mode
loops and conditionals: Conditionals and Loops
lowercasing a string (stringdown): Strings
ls request, alternative to (pvs): Changing the Vertical Spacing
lt request, using + and - with: Numeric Expressions

M
m scaling unit: Measurements
M scaling unit: Measurements
machine units: Page Geometry
macro: Requests and Macros
macro arguments: Calling Macros
macro arguments, and compatibility mode: Gtroff Internals
macro arguments, and tabs: Invoking Requests
macro directories: Macro Directories
macro file search path: Macro Directories
macro name register (\$0): Parameters
macro names, starting with [ or ], and refer: Identifiers
macro package: Macro Packages
macro package search path: Macro Directories
macro package usage, basics of: Basics
macro package, auxiliary: Major Macro Packages
macro package, full-service: Major Macro Packages
macro package, introduction: Macro Package Intro
macro package, major: Major Macro Packages
macro package, minor: Major Macro Packages
macro package, structuring the source of: Invoking Requests
macro, appending to (am): Writing Macros
macro, creating alias for (als): Strings
macro, end-of-input (em): End-of-input Traps
macro, parameters (\$): Parameters
macro, removing (rm): Strings
macro, removing alias for (rm): Strings
macro, renaming (rn): Strings
macros, recursive: while
macros, searching: Macro Directories
macros, shared name space with strings and diversions: Identifiers
macros, tutorial for users: Tutorial for Macro Users
macros, writing: Writing Macros
magnification of a font (fzoom): Selecting Fonts
major macro package: Major Macro Packages
major version number register (.x): Built-in Registers
man macros, custom headers and footers: Optional man extensions
man macros, Ultrix-specific: Optional man extensions
man pages: man
manipulating filling and adjustment: Manipulating Filling and Adjustment
manipulating hyphenation: Manipulating Hyphenation
manipulating spacing: Manipulating Spacing
manipulating type size and vertical spacing: Manipulating Type Size and Vertical Spacing
manual hyphenation: Manipulating Hyphenation
manual pages: man
margin for hyphenation (hym): Manipulating Hyphenation
margin glyph (mc): Miscellaneous
margin, bottom: Page Location Traps
margin, left (po): Line Layout
margin, right: Line Layout
margin, top: Page Location Traps
mark, high-water, register (.h): Diversions
marker, footnote [ms]: ms Footnotes
marking vertical page location (mk): Page Motions
maximum operator: Numeric Expressions
maximum value representable with Roman numerals: Assigning Register Formats
mdoc macros: mdoc
me macro package: me
measurement units: Measurements
measurements: Measurements
measurements, specifying safely: Default Units
metrics, font: Using Fonts
minimal inter-word spacing: Manipulating Filling and Adjustment
minimum operator: Numeric Expressions
minimum value representable with Roman numerals: Assigning Register Formats
minor macro package: Major Macro Packages
minor version number register (.y): Built-in Registers
minutes, current time (minutes): Built-in Registers
mm macro package: mm
mode for constant glyph space (cs): Artificial Fonts
mode, compatibility: Compatibility Mode
mode, compatibility, and parameters: Gtroff Internals
mode, copy: Copy Mode
mode, copy: Copy Mode
mode, copy, and cf request: I/O
mode, copy, and device request: Postprocessor Access
mode, copy, and length request: Strings
mode, copy, and macro parameters: Parameters
mode, copy, and output request: Diversions
mode, copy, and trf request: I/O
mode, copy, and write request: I/O
mode, copy, and writec request: I/O
mode, copy, and writem request: I/O
mode, copy, and \!: Diversions
mode, copy, and \?: Operators in Conditionals
mode, copy, and \?: Diversions
mode, copy, and \a: Leaders
mode, copy, and \t: Tabs and Fields
mode, copy, and \V: I/O
mode, fill (fi), enabling: Manipulating Filling and Adjustment
mode, fill, and break warnings: Warnings
mode, fill, and inter-sentence space: Manipulating Filling and Adjustment
mode, fill, and \c: Line Continuation
mode, fill, disabling: Manipulating Filling and Adjustment
mode, interpretation: Copy Mode
mode, line-tabs: Tabs and Fields
mode, no-fill: Manipulating Filling and Adjustment
mode, no-fill, and \c: Line Continuation
mode, no-space (ns): Manipulating Spacing
mode, nroff: troff and nroff Modes
mode, safer: Groff Options
mode, safer: Macro Directories
mode, safer: Built-in Registers
mode, safer: I/O
mode, safer: I/O
mode, safer: I/O
mode, safer: I/O
mode, safer: Safer Mode
mode, troff: troff and nroff Modes
mode, unsafe: Groff Options
mode, unsafe: Macro Directories
mode, unsafe: Built-in Registers
mode, unsafe: I/O
mode, unsafe: I/O
mode, unsafe: I/O
mode, unsafe: I/O
modifying requests: Control Characters
modulus: Numeric Expressions
mom macro package: mom
month of the year register (mo): Built-in Registers
motion operators: Numeric Expressions
motion quanta: Motion Quanta
motion quantum, horizontal: DESC File Format
motion quantum, horizontal, register (.H): Motion Quanta
motion quantum, vertical: DESC File Format
motion, horizontal (\h): Page Motions
motion, vertical (\v): Page Motions
motions, page: Page Motions
mounting a font (fp): Font Positions
mounting position: Using Fonts
mounting position: Using Fonts
mounting, font, automatic: Selecting Fonts
ms macros: ms
ms macros, accent marks: ms Legacy Features
ms macros, body text: ms Body Text
ms macros, creating table of contents: ms TOC
ms macros, displays: ms keeps and displays
ms macros, document control settings: ms Document Control Settings
ms macros, document description: ms Document Description Macros
ms macros, equations: ms Insertions
ms macros, figures: ms Insertions
ms macros, footers: ms Headers and Footers
ms macros, footnotes: ms Footnotes
ms macros, fractional type sizes in: Differences from AT&T ms
ms macros, general structure: ms Document Structure
ms macros, groff differences from AT&T: Differences from AT&T ms
ms macros, headers: ms Headers and Footers
ms macros, headings: Headings in ms
ms macros, keeps: ms keeps and displays
ms macros, language: ms language and localization
ms macros, lists: Lists in ms
ms macros, localization: ms language and localization
ms macros, margins: ms Margins
ms macros, multiple columns: ms Multiple Columns
ms macros, naming conventions: ms Naming Conventions
ms macros, nested lists: Indented regions in ms
ms macros, obtaining typographical symbols: Typographical symbols in ms
ms macros, page layout: ms Page Layout
ms macros, paragraph handling: Paragraphs in ms
ms macros, references: ms Insertions
ms macros, special characters: ms Legacy Features
ms macros, strings: ms Legacy Features
ms macros, tables: ms Insertions
ms macros, text settings: Text settings in ms
multi-file documents: Debugging
multi-line strings: Strings
multi-page table example [ms]: ms Insertions
multiple columns [ms]: ms Multiple Columns
multiplication: Numeric Expressions

N
n scaling unit: Measurements
name space, common, of macros, diversions, and strings: Identifiers
name, background color, register (.M): Colors
name, fill color, register (.M): Colors
name, stroke color, register (.m): Colors
named character (\C): Using Symbols
names, long: Compatibility Mode
naming conventions, ms macros: ms Naming Conventions
ne request, and the .trunc register: Page Location Traps
ne request, comparison with sv: Page Control
negating register values: Setting Registers
negation: Numeric Expressions
nested assignments: Interpolating Registers
nested diversions: Diversions
nested lists [ms]: Indented regions in ms
nesting level, suppression, register: Suppressing Output
new page (bp): Page Control
newline character, and translations: Character Translations
newline character, in strings, escaping: Strings
newline, as delimiter: Delimiters
newline, final, stripping in diversions: Punning Names
next file, processing (nx): I/O
next free font position register (.fp): Font Positions
next page number register (.pn): Page Layout
next page number, configuring (pn): Page Layout
nf request, causing implicit break: Manipulating Filling and Adjustment
nl register, and .d: Diversions
nl register, difference from .h: Diversions
nm request, using + and - with: Numeric Expressions
no-break control character ('): Requests and Macros
no-break control character, changing (c2): Control Characters
no-fill mode: Manipulating Filling and Adjustment
no-fill mode, and \c: Line Continuation
no-space mode (ns): Manipulating Spacing
node, output: Gtroff Internals
non-printing break point (\:): Manipulating Hyphenation
nr request, and warnings: Warnings
nr request, using + and - with: Numeric Expressions
nroff mode: troff and nroff Modes
number formats, assigning to register (af): Assigning Register Formats
number of registers register (.R): Built-in Registers
number, input line, setting (lf): Debugging
number, page, next, configuring (pn): Page Layout
numbered glyph (\N): Character Translations
numbered glyph (\N): Using Symbols
numbered list, example markup [ms]: Lists in ms
numbers, line, printing (nm): Miscellaneous
numeral-width space (\0): Page Motions
numerals, as delimiters: Delimiters
numerals, Roman: Assigning Register Formats
numeric expression, valid: Numeric Expressions
numeric expressions: Numeric Expressions

O
object creation: Writing Macros
offset, page: Page Geometry
offset, page (po): Line Layout
open request, and safer mode: Groff Options
opena request, and safer mode: Groff Options
opening brace escape sequence (\}): Conditional Blocks
opening file (open): I/O
operator, scaling: Numeric Expressions
operators, arithmetic: Numeric Expressions
operators, as delimiters: Delimiters
operators, comparison: Numeric Expressions
operators, extremum (>?, <?): Numeric Expressions
operators, logical: Numeric Expressions
operators, motion: Numeric Expressions
operators, unary arithmetic: Numeric Expressions
optical size of a font: Selecting Fonts
options: Groff Options
order of evaluation in expressions: Numeric Expressions
ordinary character: Identifiers
orientation, landscape: Paper Format
orphan: Page Control
orphan lines, preventing with ne: Page Control
os request, and no-space mode: Page Control
outlined circle, drawing (‘\D'c …'’): Drawing Geometric Objects
outlined ellipse, drawing (‘\D'e …'’): Drawing Geometric Objects
outlined polygon, drawing (‘\D'p …'’): Drawing Geometric Objects
output and input requests: I/O
output comparison operator: Operators in Conditionals
output device name string (.T): Groff Options
output device name string (.T): Strings
output device name string (.T), in other implementations: Other Differences
output device usage register (.T): Groff Options
output device usage register (.T), incompatibility with AT&T troff: Other Differences
output devices: Output Device Intro
output encoding, ASCII: Groff Options
output encoding, code page 1047: Groff Options
output encoding, EBCDIC: Groff Options
output encoding, ISO 646: Groff Options
output encoding, Latin-1 (ISO 8859-1): Groff Options
output encoding, UTF-8: Groff Options
output glyphs, and input characters, compatibility with AT&T troff: Other Differences
output line break: Breaking
output line number register (ln): Miscellaneous
output line properties: Manipulating Filling and Adjustment
output line, continuation (\c): Line Continuation
output line, horizontal position, register (.k): Page Motions
output node: Gtroff Internals
output request, and copy mode: Diversions
output request, and \!: Diversions
output, filling, disablement of (nf): Manipulating Filling and Adjustment
output, filling, enablement of (fi): Manipulating Filling and Adjustment
output, flush (fl): Debugging
output, gtroff: gtroff Output
output, intermediate: gtroff Output
output, suppressing (\O): Suppressing Output
output, transparent (cf, trf): I/O
output, transparent (\!, \?): Diversions
output, transparent, incompatibilities with AT&T troff: Other Differences
output, troff: gtroff Output
overlapping characters: Using Symbols
overstriking glyphs (\o): Page Motions

P
p scaling unit: Measurements
P scaling unit: Measurements
package, macro: Macro Packages
package, macro, auxiliary: Major Macro Packages
package, macro, full-service: Major Macro Packages
package, macro, introduction: Macro Package Intro
package, macro, major: Major Macro Packages
package, macro, minor: Major Macro Packages
package, macro, search path: Macro Directories
package, package, structuring the source of: Invoking Requests
padding character, for fields (fc): Fields
page: Page Geometry
page break: Page Geometry
page break: Page Control
page break: The Implicit Page Trap
page break (introduction): Basics
page break, conditional (ne): Page Control
page break, final: End-of-input Traps
page break, prevented by vpt: Vertical Position Traps
page control: Page Control
page ejection: Page Geometry
page ejection: Page Control
page ejection: The Implicit Page Trap
page ejection status register (.pe): Page Location Traps
page ejection, of final page: End-of-input Traps
page ejection, prevented by vpt: Vertical Position Traps
page footers: Page Location Traps
page headers: Page Location Traps
page layout: Page Layout
page layout [ms]: ms Page Layout
page length register (.p): Page Layout
page length, configuring (pl): Page Layout
page location traps: Page Location Traps
page location traps, debugging: Page Location Traps
page location, vertical, marking (mk): Page Motions
page location, vertical, returning to marked (rt): Page Motions
page motions: Page Motions
page number character (%): Page Layout
page number character, changing (pc): Page Layout
page number register (%): Page Control
page number, configuring next (pn): Page Layout
page number, next, register (.pn): Page Layout
page offset: Page Geometry
page offset (po): Line Layout
page orientation, landscape: Paper Format
page, geometry of: Page Geometry
page, new (bp): Page Control
paper format: Paper Format
paper size: Paper Format
paragraphs: Paragraphs
parameter count register (.$): Parameters
parameters: Parameters
parameters, and compatibility mode: Gtroff Internals
parameters, macro (\$): Parameters
parentheses: Numeric Expressions
partially collected line: Manipulating Filling and Adjustment
path, for font files: Font Directories
path, for tmac files: Macro Directories
pattern files, for hyphenation: Manipulating Hyphenation
patterns for hyphenation (hpf): Manipulating Hyphenation
pending output line: Manipulating Filling and Adjustment
pi request, and groff: I/O
pi request, and safer mode: Groff Options
pi request, disabled by default: Safer Mode
pica scaling unit (P): Measurements
PID of GNU troff register ($$): Built-in Registers
pile, glyph (\b): Drawing Geometric Objects
pl request, using + and - with: Numeric Expressions
plain text approximation output register (.A): Groff Options
plain text approximation output register (.A): Built-in Registers
planting a trap: Traps
platform-specific directory: Macro Directories
pm request, incompatibilities with AT&T troff: Other Differences
pn request, using + and - with: Numeric Expressions
PNG image generation from PostScript: DESC File Format
po request, using + and - with: Numeric Expressions
point scaling unit (p): Measurements
point size registers (.s, .ps): Changing the Type Size
point size registers, last-requested (.psr, .sr): Using Fractional Type Sizes
point sizes, changing (ps, \s): Changing the Type Size
point sizes, fractional: Using Fractional Type Sizes
point sizes, fractional: Other Differences
polygon, filled, drawing (‘\D'P …'’): Drawing Geometric Objects
polygon, outlined, drawing (‘\D'p …'’): Drawing Geometric Objects
polygon, solid, drawing (‘\D'P …'’): Drawing Geometric Objects
polygon, stroked, drawing (‘\D'p …'’): Drawing Geometric Objects
position of lowest text line (.h): Diversions
position, absolute (sic) operator (|): Numeric Expressions
position, drawing: Page Geometry
position, horizontal input line, saving (\k): Page Motions
position, horizontal, in input line, register (hp): Page Motions
position, horizontal, in output line, register (.k): Page Motions
position, mounting: Using Fonts
position, vertical, in diversion, register (.d): Diversions
positions, font: Font Positions
post-vertical line spacing: Changing the Vertical Spacing
post-vertical line spacing register (.pvs): Changing the Vertical Spacing
post-vertical line spacing, changing (pvs): Changing the Vertical Spacing
postprocessor access: Postprocessor Access
postprocessors: Output Device Intro
PostScript, bounding box: Miscellaneous
PostScript, PNG image generation: DESC File Format
prefix, for commands: Environment
preprocessors: Preprocessor Intro
previous font, selecting (ft): Selecting Fonts
previous font, selecting (\f[], \fP): Selecting Fonts
previous line length (.n): Environments
print current page register (.P): Groff Options
printing backslash (\\, \e, \E, \[rs]): Other Differences
printing line numbers (nm): Miscellaneous
printing to stderr (tm, tm1, tmc): Debugging
printing, zero-width (\z, \Z): Page Motions
printing, zero-width (\z, \Z): Page Motions
process ID of GNU troff register ($$): Built-in Registers
processing next file (nx): I/O
productive input line: Manipulating Filling and Adjustment
properties of characters (cflags): Using Symbols
properties of glyphs (cflags): Using Symbols
properties of output lines: Manipulating Filling and Adjustment
ps request, and constant glyph space mode: Artificial Fonts
ps request, incompatibilities with AT&T troff: Other Differences
ps request, using + and - with: Numeric Expressions
ps request, with fractional type sizes: Using Fractional Type Sizes
pso request, and safer mode: Groff Options
pvs request, using + and - with: Numeric Expressions

Q
quanta, motion: Motion Quanta
quantum, horizontal motion: DESC File Format
quantum, vertical motion: DESC File Format

R
radicalex glyph, and cflags: Using Symbols
ragged-left text: Manipulating Filling and Adjustment
ragged-right text: Manipulating Filling and Adjustment
rc request, and glyph definitions: Using Symbols
read-only register removal, incompatibility with AT&T troff: Other Differences
read-only register, changing format: Assigning Register Formats
reading from standard input (rd): I/O
recursive macros: while
refer, and macro names starting with [ or ]: Identifiers
reference, gtroff: GNU troff Reference
references [ms]: ms Insertions
register format, in expressions: Assigning Register Formats
register, assigning number format to (af): Assigning Register Formats
register, built-in, removing: Built-in Registers
register, creating alias for (aln): Setting Registers
register, format (\g): Assigning Register Formats
register, read-only, removal, incompatibility with AT&T troff: Other Differences
register, removing (rr): Setting Registers
register, removing alias for (rr): Setting Registers
register, renaming (rnn): Setting Registers
registers: Registers
registers, built-in: Built-in Registers
registers, dumping (pnr): Debugging
registers, interpolating (\n): Interpolating Registers
registers, number of, register (.R): Built-in Registers
registers, setting (nr, \R): Setting Registers
removal of read-only registers, incompatibility with AT&T troff: Other Differences
removing a built-in register: Built-in Registers
removing a register (rr): Setting Registers
removing alias for register (rr): Setting Registers
removing alias, for diversion (rm): Strings
removing alias, for macro (rm): Strings
removing alias, for string (rm): Strings
removing diversion (rm): Strings
removing glyph definition (rchar, rfschar): Using Symbols
removing macro (rm): Strings
removing request (rm): Strings
removing string (rm): Strings
renaming a register (rnn): Setting Registers
renaming diversion (rn): Strings
renaming macro (rn): Strings
renaming request (rn): Strings
renaming string (rn): Strings
renditions, graphic: Using Fonts
request: Requests and Macros
request: Formatter Instructions
request arguments: Invoking Requests
request arguments, and compatibility mode: Gtroff Internals
request arguments, and tabs: Invoking Requests
request, removing (rm): Strings
request, renaming (rn): Strings
request, undefined: Comments
requests for drawing: Drawing Geometric Objects
requests for input and output: I/O
requests, intercepting: Control Characters
requests, invoking: Invoking Requests
requests, modifying: Control Characters
resolution, device: Page Geometry
resolution, device: DESC File Format
resolution, device, obtaining in the formatter: Measurements
resolution, horizontal: DESC File Format
resolution, horizontal, register (.H): Motion Quanta
resolution, vertical: DESC File Format
returning to marked vertical page location (rt): Page Motions
revision number register (.Y): Built-in Registers
right margin: Line Layout
right-aligning lines (introduction): Basics
right-justifying (rj): Manipulating Filling and Adjustment
right-justifying lines (introduction): Basics
rivers: Other Differences
rj request, causing implicit break: Manipulating Filling and Adjustment
rn glyph, and cflags: Using Symbols
roman glyph, correction after italic glyph (\/): Italic Corrections
roman glyph, correction before italic glyph (\,): Italic Corrections
Roman numerals: Assigning Register Formats
Roman numerals, extrema (maximum and minimum): Assigning Register Formats
rq glyph, at end of sentence: Sentences
rq glyph, at end of sentence: Using Symbols
rt request, using + and - with: Numeric Expressions
ru glyph, and cflags: Using Symbols
running system commands: I/O

S
s scaling unit: Using Fractional Type Sizes
safer mode: Groff Options
safer mode: Macro Directories
safer mode: Built-in Registers
safer mode: I/O
safer mode: I/O
safer mode: I/O
safer mode: I/O
safer mode: Safer Mode
saving horizontal input line position (\k): Page Motions
scaling indicator: Measurements
scaling operator: Numeric Expressions
scaling unit c: Measurements
scaling unit f: Colors
scaling unit i: Measurements
scaling unit m: Measurements
scaling unit M: Measurements
scaling unit n: Measurements
scaling unit p: Measurements
scaling unit P: Measurements
scaling unit s: Using Fractional Type Sizes
scaling unit u: Measurements
scaling unit v: Measurements
scaling unit z: Using Fractional Type Sizes
searching fonts: Font Directories
searching macros: Macro Directories
seconds, current time (seconds): Built-in Registers
selecting the previous font (ft): Selecting Fonts
sentence space: Sentences
sentence space size register (.sss): Manipulating Filling and Adjustment
sentences: Sentences
sequence, escape: Formatter Instructions
setting diversion trap (dt): Diversion Traps
setting end-of-input trap (em): End-of-input Traps
setting input line number (lf): Debugging
setting input line trap (it, itc): Input Line Traps
setting registers (nr, \R): Setting Registers
setting the page length (pl): Page Layout
setting up an abstract font style (sty): Font Families
shc request, and translations: Character Translations
site-local directory: Macro Directories
site-local directory: Font Directories
size of sentence space register (.sss): Manipulating Filling and Adjustment
size of word space register (.ss): Manipulating Filling and Adjustment
size, optical, of a font: Selecting Fonts
size, paper: Paper Format
size, size: Manipulating Type Size and Vertical Spacing
sizes, fractional: Other Differences
sizes, fractional type: Using Fractional Type Sizes
skew, of last glyph (.csk): Environments
slant, font, changing (\S): Artificial Fonts
soft hyphen character, setting (shc): Manipulating Hyphenation
soft hyphen glyph (hy): Manipulating Hyphenation
solid circle, drawing (‘\D'C …'’): Drawing Geometric Objects
solid ellipse, drawing (‘\D'E …'’): Drawing Geometric Objects
solid polygon, drawing (‘\D'P …'’): Drawing Geometric Objects
SOURCE_DATE_EPOCH, environment variable: Environment
sp request, and no-space mode: Manipulating Spacing
sp request, causing implicit break: Manipulating Filling and Adjustment
space between sentences: Sentences
space between sentences register (.sss): Manipulating Filling and Adjustment
space between words register (.ss): Manipulating Filling and Adjustment
space character, as delimiter: Delimiters
space characters, in expressions: Numeric Expressions
space, between sentences: Manipulating Filling and Adjustment
space, between words: Manipulating Filling and Adjustment
space, discardable, horizontal: Manipulating Filling and Adjustment
space, hair (\^): Page Motions
space, horizontal (\h): Page Motions
space, horizontal, unformatting: Punning Names
space, thin (\|): Page Motions
space, unbreakable (\~): Manipulating Filling and Adjustment
space, unbreakable and unadjustable (\SP): Page Motions
space, vertical, unit (v): Measurements
space, width of a digit (numeral) (\0): Page Motions
spaces with ds: Strings
spaces, in a macro argument: Calling Macros
spaces, leading and trailing: Breaking
spacing (introduction): Basics
spacing, manipulating: Manipulating Spacing
spacing, vertical: Page Geometry
spacing, vertical: Manipulating Type Size and Vertical Spacing
spacing, vertical (introduction): Basics
special characters: Sentences
special characters: Character Translations
special characters [ms]: ms Legacy Features
special characters, list of (groff_char(7) man page): Using Symbols
special font: Using Fonts
special fonts: Using Symbols
special fonts: Special Fonts
special fonts: Font Description File Format
special fonts, emboldening: Artificial Fonts
special request, and font translations: Selecting Fonts
special request, and glyph search order: Using Symbols
spline, drawing (‘\D'~ …'’): Drawing Geometric Objects
springing a trap: Traps
sqrtex glyph, and cflags: Using Symbols
ss request, incompatibilities with AT&T troff: Other Differences
stack: Environments
stacking glyphs (\b): Drawing Geometric Objects
standard input, reading from (rd): I/O
stderr, printing to (tm, tm1, tmc): Debugging
stops, tab: Tabs and Leaders
string arguments: Strings
string comparison: Operators in Conditionals
string expansion (\*): Strings
string interpolation (\*): Strings
string, appending (as): Strings
string, creating alias for (als): Strings
string, length of (length): Strings
string, removing (rm): Strings
string, removing alias for (rm): Strings
string, renaming (rn): Strings
strings: Strings
strings [ms]: ms Legacy Features
strings, multi-line: Strings
strings, shared name space with macros and diversions: Identifiers
stripping final newline in diversions: Punning Names
stroke color: Colors
stroke color name register (.m): Colors
stroked circle, drawing (‘\D'c …'’): Drawing Geometric Objects
stroked ellipse, drawing (‘\D'e …'’): Drawing Geometric Objects
stroked polygon, drawing (‘\D'p …'’): Drawing Geometric Objects
structuring source code of documents or macro packages: Invoking Requests
sty request, and changing fonts: Selecting Fonts
sty request, and font translations: Selecting Fonts
style, font: Using Fonts
style, font, abstract: Using Fonts
style, font, abstract, setting up (sty): Font Families
styles, font: Font Families
substring (substring): Strings
subtraction: Numeric Expressions
suppressing output (\O): Suppressing Output
suppression nesting level register: Suppressing Output
sv request, and no-space mode: Page Control
switching environments (ev): Environments
sy request, and safer mode: Groff Options
sy request, disabled by default: Safer Mode
symbol: Using Symbols
symbol table, dumping (pm): Debugging
symbol, defining (char): Using Symbols
symbols, using: Using Symbols
system commands, running: I/O
system() return value register (systat): I/O

T
tab character: Tabs and Leaders
tab character encoding: Tabs and Fields
tab character, and translations: Character Translations
tab character, as delimiter: Delimiters
tab character, non-interpreted (\t): Tabs and Fields
tab repetition character (tc): Tabs and Fields
tab stop settings register (.tabs): Tabs and Fields
tab stops: Tabs and Leaders
tab stops, default: Tabs and Fields
tab, line-tabs mode: Tabs and Fields
table of contents: Table of Contents
table of contents: Leaders
table of contents, creating [ms]: ms TOC
table, multi-page, example [ms]: ms Insertions
tables [ms]: ms Insertions
tabs, and fields: Tabs and Fields
tabs, and macro arguments: Invoking Requests
tabs, and request arguments: Invoking Requests
tabs, before comments: Comments
tagged paragraphs: Paragraphs
tags, paragraph: Paragraphs
terminal, conditional output for: Operators in Conditionals
text baseline: Page Geometry
text baseline: Manipulating Type Size and Vertical Spacing
text font: Using Fonts
text line: Requests and Macros
text line, position of lowest (.h): Diversions
text, GNU troff processing: Text
text, justifying: Manipulating Filling and Adjustment
text, justifying (rj): Manipulating Filling and Adjustment
thickness of lines (‘\D't …'’): Drawing Geometric Objects
thin space (\|): Page Motions
three-part title (tl): Page Layout
ti request, causing implicit break: Manipulating Filling and Adjustment
ti request, using + and - with: Numeric Expressions
time, current, hours (hours): Built-in Registers
time, current, minutes (minutes): Built-in Registers
time, current, seconds (seconds): Built-in Registers
time, formatting: I/O
title length, configuring (lt): Page Layout
title line length register (.lt): Page Layout
title line, formatting (tl): Page Layout
titles: Page Layout
tkf request, and font styles: Font Families
tkf request, and font translations: Selecting Fonts
tkf request, with fractional type sizes: Using Fractional Type Sizes
tl request, and mc: Miscellaneous
tmac, directory: Macro Directories
tmac, path: Macro Directories
TMPDIR, environment variable: Environment
token, input: Gtroff Internals
top margin: Page Location Traps
top-level diversion: Diversions
top-level diversion, and bp: Page Control
top-level diversion, and \!: Diversions
top-level diversion, and \?: Diversions
tr request, and glyph definitions: Using Symbols
tr request, and soft hyphen character: Manipulating Hyphenation
tr request, incompatibilities with AT&T troff: Other Differences
track kerning: Ligatures and Kerning
track kerning, activating (tkf): Ligatures and Kerning
trailing double quotes in strings: Strings
trailing spaces in string definitions and appendments: Strings
trailing spaces on text lines: Breaking
translations of characters: Character Translations
transparent characters: Using Symbols
transparent dummy character (\)): Dummy Characters
transparent output (cf, trf): I/O
transparent output (\!, \?): Diversions
transparent output, incompatibilities with AT&T troff: Other Differences
trap: Deferring Output
trap, changing location (ch): Page Location Traps
trap, distance to next vertical position, register (.t): Page Location Traps
trap, diversion, setting (dt): Diversion Traps
trap, end-of-input, setting (em): End-of-input Traps
trap, implicit: The Implicit Page Trap
trap, input line, clearing (it, itc): Input Line Traps
trap, input line, setting (it, itc): Input Line Traps
trap, planting: Traps
trap, springing: Traps
traps: Traps
traps, and diversions: Page Location Traps
traps, blank line: Blank Line Traps
traps, diversion: Diversion Traps
traps, end-of-input: End-of-input Traps
traps, input line: Input Line Traps
traps, input line, and interrupted lines (itc): Input Line Traps
traps, leading space: Leading Space Traps
traps, page location: Page Location Traps
traps, page location, dumping (ptr): Debugging
traps, page location, listing (ptr): Debugging
traps, sprung by bp request (.pe): Page Location Traps
traps, vertical position: Vertical Position Traps
trf request, and copy mode: I/O
trf request, and invalid characters: I/O
trf request, causing implicit break: Manipulating Filling and Adjustment
trin request, and asciify: Diversions
troff mode: troff and nroff Modes
troff output: gtroff Output
truncated vertical space register (.trunc): Page Location Traps
truncating division: Numeric Expressions
TTY, conditional output for: Operators in Conditionals
tutorial for macro users: Tutorial for Macro Users
type size: Manipulating Type Size and Vertical Spacing
type size registers (.s, .ps): Changing the Type Size
type size registers, last-requested (.psr, .sr): Using Fractional Type Sizes
type sizes, changing (ps, \s): Changing the Type Size
type sizes, fractional: Using Fractional Type Sizes
type sizes, fractional: Other Differences
typeface: Using Fonts
TZ, environment variable: Environment

U
u scaling unit: Measurements
uf request, and font styles: Font Families
ul glyph, and cflags: Using Symbols
ul request, and font translations: Selecting Fonts
Ultrix-specific man macros: Optional man extensions
unadjustable and unbreakable space (\SP): Page Motions
unary arithmetic operators: Numeric Expressions
unbreakable and unadjustable space (\SP): Page Motions
unbreakable space (\~): Manipulating Filling and Adjustment
undefined identifiers: Identifiers
undefined request: Comments
underline font (uf): Artificial Fonts
underlining (ul): Artificial Fonts
underlining, continuous (cu): Artificial Fonts
unformatting diversions (asciify): Diversions
unformatting horizontal space: Punning Names
Unicode: Identifiers
Unicode: Using Symbols
unit, scaling, c: Measurements
unit, scaling, f: Colors
unit, scaling, i: Measurements
unit, scaling, m: Measurements
unit, scaling, M: Measurements
unit, scaling, n: Measurements
unit, scaling, p: Measurements
unit, scaling, P: Measurements
unit, scaling, s: Using Fractional Type Sizes
unit, scaling, u: Measurements
unit, scaling, v: Measurements
unit, scaling, z: Using Fractional Type Sizes
units of measurement: Measurements
units, basic: Page Geometry
units, basic, conversion to: Measurements
units, default: Default Units
units, machine: Page Geometry
unnamed glyphs: Using Symbols
unnamed glyphs, accessing with \N: Font Description File Format
unsafe mode: Groff Options
unsafe mode: Macro Directories
unsafe mode: Built-in Registers
unsafe mode: I/O
unsafe mode: I/O
unsafe mode: I/O
unsafe mode: I/O
unstyled font: Using Fonts
up-casing a string (stringup): Strings
uppercasing a string (stringup): Strings
upright glyph, correction after oblique glyph (\/): Italic Corrections
upright glyph, correction before oblique glyph (\,): Italic Corrections
URLs, breaking (\:): Manipulating Hyphenation
user’s macro tutorial: Tutorial for Macro Users
user’s tutorial for macros: Tutorial for Macro Users
using escape sequences: Using Escape Sequences
using symbols: Using Symbols
UTF-8 output encoding: Groff Options

V
v scaling unit: Measurements
valid numeric expression: Numeric Expressions
value, incrementing without changing the register: Auto-increment
variables in environment: Environment
vee: Page Geometry
vee scaling unit (v): Measurements
version number, major, register (.x): Built-in Registers
version number, minor, register (.y): Built-in Registers
vertical drawing position (nl): Page Control
vertical line drawing (\L): Drawing Geometric Objects
vertical line spacing register (.v): Changing the Vertical Spacing
vertical line spacing, changing (vs): Changing the Vertical Spacing
vertical line spacing, effective value: Changing the Vertical Spacing
vertical motion (\v): Page Motions
vertical motion quantum: DESC File Format
vertical page location, marking (mk): Page Motions
vertical page location, returning to marked (rt): Page Motions
vertical position in diversion register (.d): Diversions
vertical position trap enable register (.vpt): Vertical Position Traps
vertical position traps: Vertical Position Traps
vertical position traps, enabling (vpt): Vertical Position Traps
vertical position, drawing (nl): Page Control
vertical resolution: DESC File Format
vertical space unit (v): Measurements
vertical spacing: Page Geometry
vertical spacing: Manipulating Type Size and Vertical Spacing
vertical spacing (introduction): Basics

W
warning categories: Warnings
warning level (warn): Debugging
warnings: Debugging
warnings: Warnings
what is groff?: What Is groff?
while: while
while request, and font translations: Selecting Fonts
while request, and the ‘!’ operator: Numeric Expressions
while request, confusing with br: while
while request, operators to use with: Operators in Conditionals
widow: Page Control
widow: Page Control
width escape (\w): Page Motions
width, of last glyph (.w): Environments
word space size register (.ss): Manipulating Filling and Adjustment
word, definition of: Filling
write request, and copy mode: I/O
writec request, and copy mode: I/O
writem request, and copy mode: I/O
writing macros: Writing Macros
writing to file (write, writec): I/O

Y
year, current, register (year, yr): Built-in Registers

Z
z scaling unit: Using Fractional Type Sizes
zero-width printing (\z, \Z): Page Motions
zero-width printing (\z, \Z): Page Motions
zoom factor of a font (fzoom): Selecting Fonts

+ +
+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Conditional-Blocks.html b/doc/groff.html.node/Conditional-Blocks.html new file mode 100644 index 0000000..b2b789b --- /dev/null +++ b/doc/groff.html.node/Conditional-Blocks.html @@ -0,0 +1,174 @@ + + + + + + +Conditional Blocks (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.23.4 Conditional Blocks

+ + + +

It is frequently desirable for a control structure to govern more than +one request, macro call, text line, or a combination of the foregoing. +The opening and closing brace escape sequences \{ and \} +define such groups. These conditional blocks can furthermore be +nested. +

+
+
Escape sequence: \{
+
+
Escape sequence: \}
+
+ + + + + + + + + + + + + +

\{ begins a conditional block; it must appear (after optional +spaces and tabs) immediately subsequent to the conditional expression of +an if, ie, or while +request,93 or as the argument to an el +request. +

+

\} ends a condition block and should appear on a line with other +occurrences of itself as necessary to match \{ sequences. It +can be preceded by a control character, spaces, and tabs. Input after +any quantity of \} sequences on the same line is processed only +if all of the preceding conditions to which they correspond are true. +Furthermore, a \} closing the body of a while request +must be the last such escape sequence on an input line. +

+

Brace escape sequences outside of control structures have no meaning and +produce no output. +

+

Caution: Input lines using \{ often end with +\RET, especially in macros that consist primarily of control +lines. Forgetting to use \RET on an input line after \{ +is a common source of error. +

+ +

We might write the following in a page header macro. If we delete +\RET, the header will carry an unwanted extra empty line (except +on page 1). +

+
+
.if (\\n[%] != 1) \{\
+.  ie ((\\n[%] % 2) = 0) .tl \\*[even-numbered-page-title]
+.  el                    .tl \\*[odd-numbered-page-title]
+.\}
+
+ +

Let us take a closer look at how conditional blocks nest. +

+
+
A
+.if 0 \{ B
+C
+D
+\}E
+F
+    ⇒ A F
+
+ +
+
N
+.if 1 \{ O
+.  if 0 \{ P
+Q
+R\} S\} T
+U
+    ⇒ N O U
+
+ +

The above behavior may challenge the intuition; it was implemented to +retain compatibility with AT&T troff. For clarity, it +is idiomatic to end input lines with \{ (followed by +\RET if appropriate), and to precede \} on an input +line with nothing more than a control character, spaces, tabs, and other +instances of itself. +

+

We can use ie, el, and conditional blocks to simulate the +multi-way “switch” or “case” control structures of other languages. +The following example is adapted from the groff man +package. Indentation is used to clarify the logic. +

+
+
.\" Simulate switch/case in roff.
+.      ie '\\$2'1' .ds title General Commands\"
+.el \{.ie '\\$2'2' .ds title System Calls\"
+.el \{.ie '\\$2'3' .ds title Library Functions\"
+.el \{.ie '\\$2'4' .ds title Kernel Interfaces\"
+.el \{.ie '\\$2'5' .ds title File Formats\"
+.el \{.ie '\\$2'6' .ds title Games\"
+.el \{.ie '\\$2'7' .ds title Miscellaneous Information\"
+.el \{.ie '\\$2'8' .ds title System Management\"
+.el \{.ie '\\$2'9' .ds title Kernel Development\"
+.el                .ds title \" empty
+.\}\}\}\}\}\}\}\}
+
+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Conditionals-and-Loops.html b/doc/groff.html.node/Conditionals-and-Loops.html new file mode 100644 index 0000000..b05ce5d --- /dev/null +++ b/doc/groff.html.node/Conditionals-and-Loops.html @@ -0,0 +1,64 @@ + + + + + + +Conditionals and Loops (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.23 Conditionals and Loops

+ + + +

groff has if and while control structures like +other languages. However, the syntax for grouping multiple input lines +in the branches or bodies of these structures is unusual. +

+ + + +
+ + + + + diff --git a/doc/groff.html.node/Configuration-and-Customization.html b/doc/groff.html.node/Configuration-and-Customization.html new file mode 100644 index 0000000..6f76a47 --- /dev/null +++ b/doc/groff.html.node/Configuration-and-Customization.html @@ -0,0 +1,56 @@ + + + + + + +Configuration and Customization (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + +
+ +
+

3.2.14 Configuration and Customization

+ +

Packages provide means of customizing many of the details of how the +package behaves. These range from setting the default type size to +changing the appearance of section headers. +

+ + + + +
+ + + + + diff --git a/doc/groff.html.node/Control-Characters.html b/doc/groff.html.node/Control-Characters.html new file mode 100644 index 0000000..13ebe41 --- /dev/null +++ b/doc/groff.html.node/Control-Characters.html @@ -0,0 +1,137 @@ + + + + + + +Control Characters (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.6.1 Control Characters

+ + + + +

The mechanism of using roff’s control characters to invoke +requests and call macros was introduced in Requests and Macros. +Control characters are recognized only at the beginning of an input +line, or at the beginning of the branch of a control structure request; +see Conditionals and Loops. +

+

A few requests cause a break implicitly; use the no-break control +character to prevent the break. Break suppression is its sole +behavioral distinction. Employing the no-break control character to +invoke requests that don’t cause breaks is harmless but poor style. +See Manipulating Filling and Adjustment. +

+ + + + + +

The control ‘.’ and no-break control ‘'’ characters can each +be changed to any ordinary character42 +with the cc and c2 requests, respectively. +

+
+
Request: .cc [o]
+
+

Recognize the ordinary character o as the control character. +If o is absent or invalid, the default control character +‘.’ is selected. The identity of the control character is +associated with the environment (see Environments). +

+ +
+
Request: .c2 [o]
+
+

Recognize the ordinary character o as the no-break control +character. If o is absent or invalid, the default no-break +control character ‘'’ is selected. The identity of the no-break +control character is associated with the environment +(see Environments). +

+ +

When writing a macro, you might wish to know which control character was +used to call it. +

+
+
Register: \n[.br]
+
+

This read-only register interpolates 1 if the currently executing +macro was called using the normal control character and 0 +otherwise. If a macro is interpolated as a string, the .br +register’s value is inherited from the context of the string +interpolation. See Strings. +

+ + + + +

Use this register to reliably intercept requests that imply breaks. +

+
+
.als bp*orig bp
+.de bp
+.  ie \\n[.br] .bp*orig
+.  el          'bp*orig
+..
+
+ +

Testing the .br register outside of a macro definition makes no +sense. +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Conventions-Used-in-This-Manual.html b/doc/groff.html.node/Conventions-Used-in-This-Manual.html new file mode 100644 index 0000000..95e85b3 --- /dev/null +++ b/doc/groff.html.node/Conventions-Used-in-This-Manual.html @@ -0,0 +1,124 @@ + + + + + + +Conventions Used in This Manual (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

1.8 Conventions Used in This Manual

+ +

We apply the term “groff” to the language documented here, the GNU +implementation of the overall system, the project that develops that +system, and the command of that name. In the first sense, groff +is an extended dialect of the roff language, for which many +similar implementations exist. +

+

The roff language features several major categories for which +many items are predefined. Presentations of these items feature the +form in which the item is most commonly used on the left, and, aligned +to the right margin, the name of the category in brackets. +

+
+
Register: \n[example]
+

The register ‘example’ is one that that groff doesn’t +predefine. You can create it yourself, though; see Setting Registers. +

+ +

To make this document useful as a reference and not merely amiable +bedtime reading, we tend to present these syntax items in exhaustive +detail when they arise. References to topics discussed later in the +text are frequent; skip material you don’t understand yet. +

+

We use Texinfo’s “result” (⇒) and error→ notations to +present output written to the standard output and standard error +streams, respectively. Diagnostic messages from the GNU troff +formatter and other programs are examples of the latter, but the +formatter can also be directed to write user-specified messages to the +standard error stream. The notation then serves to identify the +output stream and does not necessarily mean that an error has +occurred.2 +

+
+
$ echo "Twelve o'clock and" | groff -Tascii | sed '/^$/d'
+    ⇒ Twelve o'clock and
+$ echo '.tm all is well.' | groff > /dev/null
+    error→ all is well.
+
+ +

Sometimes we use ⇒ somewhat abstractly to represent formatted +text that you will need to use a PostScript or PDF viewer program (or a +printer) to observe. While arguably an abuse of notation, we think this +preferable to requiring the reader to understand the syntax of these +page description languages. +

+

We also present diagnostic messages in an abbreviated form, often +omitting the name of the program issuing them, the input file name, and +line number or other positional information when such data do not serve +to illuminate the topic under discussion. +

+

Most examples are of roff language input that would be placed in +a text file. Occasionally, we start an example with a ‘$’ +character to indicate a shell prompt, as seen above. +

+

You are encouraged to try the examples yourself, and to alter them to +better learn groff’s behavior. Our examples frequently need to +direct the formatter to set a line length (with ‘.ll’) that will +fit within the page margins of this manual. We mention this so that you +know why it is there before we discuss the ll request +formally.3 +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Copy-Mode.html b/doc/groff.html.node/Copy-Mode.html new file mode 100644 index 0000000..cc7de66 --- /dev/null +++ b/doc/groff.html.node/Copy-Mode.html @@ -0,0 +1,256 @@ + + + + + + +Copy Mode (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.24.2 Copy Mode

+ + + + + + + + + +

When GNU troff processes certain requests, most importantly those +which define or append to a macro or string, it does so in copy +mode: it copies the characters of the definition into a dedicated +storage region, interpolating the escape sequences \n, \g, +\$, \*, \V, and \? normally; interpreting +\RET immediately; discarding comments \" and +\#; interpolating the current leader, escape, or tab character +with \a, \e, and \t, respectively; and storing all +other escape sequences in an encoded form. +

+ + +

The complement of copy mode—a roff formatter’s behavior when +not defining or appending to a macro, string, or diversion—where all +macros are interpolated, requests invoked, and valid escape sequences +processed immediately upon recognition, can be termed +interpretation mode. +

+
+
Escape sequence: \\
+
+

The escape character, \ by default, can escape itself. This +enables you to control whether a given \n, \g, \$, +\*, \V, or \? escape sequence is interpreted at the +time the macro containing it is defined, or later when the macro is +called.101 +

+
+
.nr x 20
+.de y
+.nr x 10
+\&\nx
+\&\\nx
+..
+.y
+    ⇒ 20 10
+
+ +

You can think of \\ as a “delayed” backslash; it is the escape +character followed by a backslash from which the escape character has +removed its special meaning. Consequently, ‘\\’ is not an escape +sequence in the usual sense. In any escape sequence ‘\X’ +that GNU troff does not recognize, the escape character is +ignored and X is output. An unrecognized escape sequence causes +a warning in category ‘escape’, with two exceptions—‘\\’ is +the first. +

+ + +
+
Escape sequence: \.
+
+

\. escapes the control character. It is similar to \\ in +that it isn’t a true escape sequence. It is used to permit nested macro +definitions to end without a named macro call to conclude them. Without +a syntax for escaping the control character, this would not be possible. +

+
+
.de m1
+foo
+.
+.  de m2
+bar
+\\..
+.
+..
+.m1
+.m2
+    ⇒ foo bar
+
+ +

The first backslash is consumed while the macro is read, and the second +is interpreted when macro m1 is called. +

+ +

roff documents should not use the \\ or \. +character sequences outside of copy mode; they serve only to obfuscate +the input. Use \e to represent the escape character, +\[rs] to obtain a backslash glyph, and \& before ‘.’ +and ‘'’ where GNU troff expects them as control characters +if you mean to use them literally (recall Requests and Macros). +

+

Macro definitions can be nested to arbitrary depth. The mechanics of +parsing the escape character have significant consequences for this +practice. +

+
+
.de M1
+\\$1
+.  de M2
+\\\\$1
+.    de M3
+\\\\\\\\$1
+\\\\..
+.    M3 hand.
+\\..
+.  M2 of
+..
+This understeer is getting
+.M1 out
+    ⇒ This understeer is getting out of hand.
+
+ +

Each escape character is interpreted twice—once in copy mode, when the +macro is defined, and once in interpretation mode, when the macro is +called. As seen above, this fact leads to exponential growth in the +quantity of escape characters required to delay interpolation of +\n, \g, \$, \*, \V, and \? at +each nesting level, which can be daunting. GNU troff offers a +solution. +

+
+
Escape sequence: \E
+
+

\E represents an escape character that is not interpreted in copy +mode. You can use it to ease the writing of nested macro definitions. +

+
+
.de M1
+.  nop \E$1
+.  de M2
+.    nop \E$1
+.    de M3
+.      nop \E$1
+\\\\..
+.    M3 better.
+\\..
+.  M2 bit
+..
+This vehicle handles
+.M1 a
+    ⇒ This vehicle handles a bit better.
+
+ +

Observe that because \. is not a true escape sequence, we can’t +use \E to keep ‘..’ from ending a macro definition +prematurely. If the multiplicity of backslashes complicates +maintenance, use end macros. +

+

\E is also convenient to define strings containing escape +sequences that need to work when used in copy mode (for example, as +macro arguments), or which will be interpolated at varying macro nesting +depths. We might define strings to begin and end superscripting +as follows.102 +

+
+
.ds { \v'-.9m\s'\En[.s]*7u/10u'+.7m'
+.ds } \v'-.7m\s0+.9m'
+
+ +

When the ec request is used to redefine the escape character, +\E also makes it easier to distinguish the semantics of an escape +character from the other meaning(s) its character might have. Consider +the use of an unusual escape character, ‘-’. +

+
+
.nr a 1
+.ec -
+.de xx
+--na
+..
+.xx
+    ⇒ -na
+
+ +

This result may surprise you; some people expect ‘1’ to be output +since register ‘a’ has clearly been defined with that value. What +has happened? The robotic replacement of ‘\’ with ‘-’ has led +us astray. You might recognize the sequence ‘--’ more readily with +the default escape character as ‘\-’, the special character escape +sequence for the minus sign glyph. +

+
+
.nr a 1
+.ec -
+.de xx
+-Ena
+..
+.xx
+    ⇒ 1
+
+
+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Copying-This-Manual.html b/doc/groff.html.node/Copying-This-Manual.html new file mode 100644 index 0000000..47c4c3e --- /dev/null +++ b/doc/groff.html.node/Copying-This-Manual.html @@ -0,0 +1,534 @@ + + + + + + +Copying This Manual (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

Appendix A Copying This Manual

+ +
Version 1.3, 3 November 2008 +
+ +
+
Copyright © 2000-2018 Free Software Foundation, Inc.
+http://fsf.org/
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+ +
    +
  1. PREAMBLE + +

    The purpose of this License is to make a manual, textbook, or other +functional and useful document free in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. +

    +

    This License is a kind of “copyleft”, which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. +

    +

    We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. +

    +
  2. APPLICABILITY AND DEFINITIONS + +

    This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The “Document”, below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as “you”. You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. +

    +

    A “Modified Version” of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. +

    +

    A “Secondary Section” is a named appendix or a front-matter section +of the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document’s overall +subject (or to related matters) and contains nothing that could fall +directly within that overall subject. (Thus, if the Document is in +part a textbook of mathematics, a Secondary Section may not explain +any mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. +

    +

    The “Invariant Sections” are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. +

    +

    The “Cover Texts” are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. +

    +

    A “Transparent” copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not “Transparent” is called “Opaque”. +

    +

    Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input +format, SGML or XML using a publicly available +DTD, and standard-conforming simple HTML, +PostScript or PDF designed for human modification. Examples +of transparent image formats include PNG, XCF and +JPG. Opaque formats include proprietary formats that can be +read and edited only by proprietary word processors, SGML or +XML for which the DTD and/or processing tools are +not generally available, and the machine-generated HTML, +PostScript or PDF produced by some word processors for +output purposes only. +

    +

    The “Title Page” means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, “Title Page” means +the text near the most prominent appearance of the work’s title, +preceding the beginning of the body of the text. +

    +

    The “publisher” means any person or entity that distributes copies +of the Document to the public. +

    +

    A section “Entitled XYZ” means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as “Acknowledgements”, +“Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” +of such a section when you modify the Document means that it remains a +section “Entitled XYZ” according to this definition. +

    +

    The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. +

    +
  3. VERBATIM COPYING + +

    You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. +

    +

    You may also lend copies, under the same conditions stated above, and +you may publicly display copies. +

    +
  4. COPYING IN QUANTITY + +

    If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document’s license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. +

    +

    If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. +

    +

    If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. +

    +

    It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. +

    +
  5. MODIFICATIONS + +

    You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: +

    +
      +
    1. Use in the Title Page (and on the covers, if any) a title distinct +from that of the Document, and from those of previous versions +(which should, if there were any, be listed in the History section +of the Document). You may use the same title as a previous version +if the original publisher of that version gives permission. + +
    2. List on the Title Page, as authors, one or more persons or entities +responsible for authorship of the modifications in the Modified +Version, together with at least five of the principal authors of the +Document (all of its principal authors, if it has fewer than five), +unless they release you from this requirement. + +
    3. State on the Title page the name of the publisher of the +Modified Version, as the publisher. + +
    4. Preserve all the copyright notices of the Document. + +
    5. Add an appropriate copyright notice for your modifications +adjacent to the other copyright notices. + +
    6. Include, immediately after the copyright notices, a license notice +giving the public permission to use the Modified Version under the +terms of this License, in the form shown in the Addendum below. + +
    7. Preserve in that license notice the full lists of Invariant Sections +and required Cover Texts given in the Document’s license notice. + +
    8. Include an unaltered copy of this License. + +
    9. Preserve the section Entitled “History”, Preserve its Title, and add +to it an item stating at least the title, year, new authors, and +publisher of the Modified Version as given on the Title Page. If +there is no section Entitled “History” in the Document, create one +stating the title, year, authors, and publisher of the Document as +given on its Title Page, then add an item describing the Modified +Version as stated in the previous sentence. + +
    10. Preserve the network location, if any, given in the Document for +public access to a Transparent copy of the Document, and likewise +the network locations given in the Document for previous versions +it was based on. These may be placed in the “History” section. +You may omit a network location for a work that was published at +least four years before the Document itself, or if the original +publisher of the version it refers to gives permission. + +
    11. For any section Entitled “Acknowledgements” or “Dedications”, Preserve +the Title of the section, and preserve in the section all the +substance and tone of each of the contributor acknowledgements and/or +dedications given therein. + +
    12. Preserve all the Invariant Sections of the Document, +unaltered in their text and in their titles. Section numbers +or the equivalent are not considered part of the section titles. + +
    13. Delete any section Entitled “Endorsements”. Such a section +may not be included in the Modified Version. + +
    14. Do not retitle any existing section to be Entitled “Endorsements” or +to conflict in title with any Invariant Section. + +
    15. Preserve any Warranty Disclaimers. +
    + +

    If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version’s license notice. +These titles must be distinct from any other section titles. +

    +

    You may add a section Entitled “Endorsements”, provided it contains +nothing but endorsements of your Modified Version by various +parties—for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. +

    +

    You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. +

    +

    The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. +

    +
  6. COMBINING DOCUMENTS + +

    You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. +

    +

    The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. +

    +

    In the combination, you must combine any sections Entitled “History” +in the various original documents, forming one section Entitled +“History”; likewise combine any sections Entitled “Acknowledgements”, +and any sections Entitled “Dedications”. You must delete all +sections Entitled “Endorsements.” +

    +
  7. COLLECTIONS OF DOCUMENTS + +

    You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. +

    +

    You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. +

    +
  8. AGGREGATION WITH INDEPENDENT WORKS + +

    A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an “aggregate” if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation’s users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. +

    +

    If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document’s Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. +

    +
  9. TRANSLATION + +

    Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. +

    +

    If a section in the Document is Entitled “Acknowledgements”, +“Dedications”, or “History”, the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. +

    +
  10. TERMINATION + +

    You may not copy, modify, sublicense, or distribute the Document +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense, or distribute it is void, and +will automatically terminate your rights under this License. +

    +

    However, if you cease all violation of this License, then your license +from a particular copyright holder is reinstated (a) provisionally, +unless and until the copyright holder explicitly and finally +terminates your license, and (b) permanently, if the copyright holder +fails to notify you of the violation by some reasonable means prior to +60 days after the cessation. +

    +

    Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. +

    +

    Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, receipt of a copy of some or all of the same material does +not give you any rights to use it. +

    +
  11. FUTURE REVISIONS OF THIS LICENSE + +

    The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +http://www.gnu.org/copyleft/. +

    +

    Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License “or any later version” applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. If the Document +specifies that a proxy can decide which future versions of this +License can be used, that proxy’s public statement of acceptance of a +version permanently authorizes you to choose that version for the +Document. +

    +
  12. RELICENSING + +

    “Massive Multiauthor Collaboration Site” (or “MMC Site”) means any +World Wide Web server that publishes copyrightable works and also +provides prominent facilities for anybody to edit those works. A +public wiki that anybody can edit is an example of such a server. A +“Massive Multiauthor Collaboration” (or “MMC”) contained in the +site means any set of copyrightable works thus published on the MMC +site. +

    +

    “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 +license published by Creative Commons Corporation, a not-for-profit +corporation with a principal place of business in San Francisco, +California, as well as future copyleft versions of that license +published by that same organization. +

    +

    “Incorporate” means to publish or republish a Document, in whole or +in part, as part of another Document. +

    +

    An MMC is “eligible for relicensing” if it is licensed under this +License, and if all works that were first published under this License +somewhere other than this MMC, and subsequently incorporated in whole +or in part into the MMC, (1) had no cover texts or invariant sections, +and (2) were thus incorporated prior to November 1, 2008. +

    +

    The operator of an MMC Site may republish an MMC contained in the site +under CC-BY-SA on the same site at any time before August 1, 2009, +provided the MMC is eligible for relicensing. +

    +
+ +

ADDENDUM: How to use this License for your documents

+ +

To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: +

+
+
  Copyright (C)  year  your name.
+  Permission is granted to copy, distribute and/or modify this document
+  under the terms of the GNU Free Documentation License, Version 1.3
+  or any later version published by the Free Software Foundation;
+  with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+  Texts.  A copy of the license is included in the section entitled ``GNU
+  Free Documentation License''.
+
+ +

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the “with…Texts.” line with this: +

+
+
    with the Invariant Sections being list their titles, with
+    the Front-Cover Texts being list, and with the Back-Cover Texts
+    being list.
+
+ +

If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. +

+

If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. +

+ + + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Credits.html b/doc/groff.html.node/Credits.html new file mode 100644 index 0000000..4f46327 --- /dev/null +++ b/doc/groff.html.node/Credits.html @@ -0,0 +1,58 @@ + + + + + + +Credits (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + +
+ +
+

1.9 Credits

+ + +

We adapted portions of this manual from existing documents. James +Clark’s man pages were an essential resource; we have updated them in +parallel with the development of this manual. We based the tutorial for +macro users on Eric Allman’s introduction to his me macro package +(which we also provide, little altered from 4.4BSD). Larry Kollar +contributed much of the material on the ms macro package. +

+ + +
+ + + + + diff --git a/doc/groff.html.node/DESC-File-Format.html b/doc/groff.html.node/DESC-File-Format.html new file mode 100644 index 0000000..11e1b73 --- /dev/null +++ b/doc/groff.html.node/DESC-File-Format.html @@ -0,0 +1,258 @@ + + + + + + +DESC File Format (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

6.2.1 DESC File Format

+ + + + +

The DESC file contains a series of directives; each begins a +line. Their order is not important, with two exceptions: (1) the +res directive must precede any papersize directive; and +(2) the charset directive must come last (if at all). If a +directive name is repeated, later entries in the file override previous +ones (except that the paper dimensions are computed based on the +res directive last seen when papersize is encountered). +Spaces and/or tabs separate words and are ignored at line boundaries. + + + +Comments start with the ‘#’ character and extend to the end of a +line. Empty lines are ignored. +

+
+
family fam
+

The default font family is fam. +

+
+
fonts n F1 Fn
+

Fonts F1, …, Fn are mounted at font positions +m+1, …, m+n where m is the number of +styles (see below). This directive may extend over more than one +line. A font name of 0 causes no font to be mounted at the +corresponding position. +

+
+
hor n
+
+ + + + +

The horizontal motion quantum is n basic units. All +horizontal quantities are rounded to multiples of n. +

+
+
image_generator program
+
+ +

Use program to generate PNG images from PostScript input. Under +GNU/Linux, this is usually gs, but under other systems (notably +Cygwin) it might be set to another name. The grohtml driver uses +this directive. +

+
+
paperlength n
+

The vertical dimension of the output medium is n basic units +(deprecated: use papersize instead). +

+
+
papersize format-or-dimension-pair-or-file-name
+

The dimensions of the output medium are as according to the +argument, which is either a standard paper format, a pair of dimensions, +or the name of a plain text file containing either of the foregoing. +

+

Recognized paper formats are the ISO and DIN formats +A0A7, B0B7, C0C7, +D0D7; the U.S. paper types letter, +legal, tabloid, ledger, statement, and +executive; and the envelope formats com10, monarch, +and DL. Matching is performed without regard for lettercase. +

+

Alternatively, the argument can be a custom paper format in the format +length,width (with no spaces before or after the +comma). Both length and width must have a unit appended; +valid units are ‘i’ for inches, ‘c’ for centimeters, ‘p’ +for points, and ‘P’ for picas. Example: ‘12c,235p’. An +argument that starts with a digit is always treated as a custom paper +format. +

+

Finally, the argument can be a file name (e.g., /etc/papersize); +if the file can be opened, the first line is read and a match attempted +against each of the other forms. No comment syntax is supported. +

+

More than one argument can be specified; +each is scanned in turn and the first valid paper specification used. +

+
+
paperwidth n
+

The horizontal dimension of the output medium is n basic +units (deprecated: use papersize instead). +

+
+
pass_filenames
+

Direct GNU troff to emit the name of the source file being +processed. This is achieved with the intermediate output command +‘x F’, which grohtml interprets. +

+
+
postpro program
+

Use program as the postprocessor. +

+
+
prepro program
+

Use program as a preprocessor. The html and xhtml +output devices use this directive. +

+
+
print program
+

Use program as a spooler program for printing. If omitted, the +-l and -L options of groff are ignored. +

+
+
res n
+
+ +

The device resolution is n basic units per inch. +

+
+
sizes s1 sn 0
+

The device has fonts at s1, …, sn scaled points (see +below). The list of sizes must be terminated by 0. Each +si can also be a range of sizes mn. The list can +extend over more than one line. +

+
+
sizescale n
+

A typographical point is subdivided into n scaled points. +The default is 1. See Using Fractional Type Sizes. +

+
+
styles S1 Sm
+

The first m mounting positions are associated with styles +S1, …, Sm. +

+
+
tcommand
+

The postprocessor can handle the ‘t’ and ‘u’ intermediate +output commands. +

+
+
unicode
+

The output device supports the complete Unicode repertoire. This +directive is useful only for devices that produce character entities +instead of glyphs. +

+

If unicode is present, no charset section is required in +the font description files since the Unicode handling built into +groff is used. However, if there are entries in a font +description file’s charset section, they either override the +default mappings for those particular characters or add new mappings +(normally for composite characters). +

+

The utf8, html, and xhtml output devices use this +directive. +

+
+
unitwidth n
+

Quantities in the font description files are in basic units for fonts +whose type size is n scaled points. +

+
+
unscaled_charwidths
+

Make the font handling module always return unscaled character widths. +The grohtml driver uses this directive. +

+
+
use_charnames_in_special
+

GNU troff should encode special characters inside device control +commands; see Postprocessor Access. The grohtml driver +uses this directive. +

+
+
vert n
+
+ + + + +

The vertical motion quantum is n basic units. All vertical +quantities are rounded to multiples of n. +

+
+
charset
+

This line and everything following it in the file are ignored. It is +recognized for compatibility with other troff implementations. +In GNU troff, character set repertoire is described on a +per-font basis. +

+
+ + + + +

GNU troff recognizes but ignores the directives spare1, +spare2, and biggestfont. +

+

The res, unitwidth, fonts, and sizes lines +are mandatory. Directives not listed above are ignored by GNU +troff but may be used by postprocessors to obtain further +information about the device. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Debugging.html b/doc/groff.html.node/Debugging.html new file mode 100644 index 0000000..594201c --- /dev/null +++ b/doc/groff.html.node/Debugging.html @@ -0,0 +1,317 @@ + + + + + + +Debugging (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.37 Debugging

+ + +

Standard troff voodoo, just put a power of two backslashes in +front of it until it works and if you still have problems add a \c. +— Ron Natalie +

+

GNU troff is not the easiest language to debug, in part thanks to +its design features of recursive interpolation and the use of +multi-stage pipeline processing in the surrounding system. Nevertheless +there exist several features useful for troubleshooting. +

+

Preprocessors use the lf request to preserve the identity of the +line numbers and names of input files. GNU troff emits a variety +of error diagnostics and supports several categories of warning; the +output of these can be selectively suppressed. A trace of the +formatter’s input processing stack can be emitted when errors or +warnings occur by means of GNU troff’s -b option, or +produced on demand with the backtrace request. The tm +and related requests can be used to emit customized diagnostic messages +or for instrumentation while troubleshooting. The ex and +ab requests cause early termination with successful and error +exit codes respectively, to halt further processing when continuing +would be fruitless. Examine the state of the formatter with requests +that write lists of defined names (macros, strings, and diversions), +environments, registers, and page location traps to the standard error +stream. +

+
+
Request: .lf line [file]
+
+ + + + + + +

Set the input line number (and, optionally, the file name) GNU +troff shall use for error and warning messages. line is +the input line number of the next line. Without an argument, the +request is ignored. +

+

lf’s primary purpose is to aid the debugging of documents that +undergo preprocessing. Programs like tbl that transform input +in their own languages into roff requests use it so that any +diagnostic messages emitted by troff correspond to the source +document. +

+ +
+
Request: .tm message
+
+
Request: .tm1 message
+
+
Request: .tmc message
+
+ + +

Send message, which consumes the remainder of the input line and +cannot contain special characters, to the standard error stream, +followed by a newline. Leading spaces in message are ignored. +

+

tm1 is similar, but recognizes and strips a leading neutral +double quote from message to allow the embedding of leading +spaces. +

+

tmc works as tm1, but does not append a newline. +

+ +
+
Request: .ab [message]
+
+ +

Write any message to the standard error stream (like tm) +and then abort GNU troff; that is, stop processing and terminate +with a failure status. +

+ +
+
Request: .ex
+
+ + +

Exit GNU troff; that is, stop processing and terminate with a +successful status. To stop processing only the current file, use the +nx request; see I/O. +

+ +

When doing something involved, it is useful to leave the debugging +statements in the code and have them turned on by a command-line flag. +

+
+
.if \n[DB] .tm debugging output
+
+ +

To activate such statements, use the -r option to set the +register. +

+
+
groff -rDB=1 file
+
+ +

If it is known in advance that there are many errors and no useful +output, GNU troff can be forced to suppress formatted output with +the -z option. +

+
+
Request: .pev
+
+ + +

Report the state of the current environment followed by that of all +other environments to the standard error stream. +

+ +
+
Request: .pm
+
+ + +

Report, to the standard error stream, the names of all defined macros, +strings, and diversions with their sizes in bytes. +

+ +
+
Request: .pnr
+
+ + +

Report the names and contents of all currently defined registers to the +standard error stream. +

+ +
+
Request: .ptr
+
+ + + + +

Report the names and positions of all page location traps to the +standard error stream. Empty slots in the list, where a trap has been +planted but subsequently (re)moved, are printed as well. +

+ +
+
Request: .fl
+
+ + + + +

Instruct gtroff to flush its output immediately. The intent is +for interactive use, but this behaviour is currently not implemented in +gtroff. Contrary to Unix troff, TTY output is sent to a +device driver also (grotty), making it non-trivial to communicate +interactively. +

+

This request causes a line break. +

+ +
+
Request: .backtrace
+
+ + +

Write the state of the input stack to the standard error stream. +

+

Consider the following in a file test. +

+
+
.de xxx
+.  backtrace
+..
+.de yyy
+.  xxx
+..
+.
+.yyy
+    error→ troff: backtrace: 'test':2: macro 'xxx'
+    error→ troff: backtrace: 'test':5: macro 'yyy'
+    error→ troff: backtrace: file 'test':8
+
+ +

The -b option of GNU troff causes a backtrace to be +generated on each error or warning. Some warnings have to be enabled; +See Warnings. +

+ +
+
Register: \n[slimit]
+
+ +

If greater than 0, sets the maximum quantity of objects on GNU +troff’s internal input stack. If less than or equal to 0, +there is no limit: recursion can continue until program memory is +exhausted. The default is 1,000. +

+ +
+
Request: .warnscale su
+
+

Set the scaling unit used in certain warnings to su, which can take the values ‘u’, ‘i’, ‘c’, +‘p’, and ‘P’. The default is ‘i’. +

+ +
+
Request: .spreadwarn [limit]
+
+

Emit a break warning if the additional space inserted for each +space between words in an output line adjusted to both margins with +‘.ad b is larger than or equal to limit. A negative +value is treated as zero; an absent argument toggles the warning on and +off without changing limit. The default scaling unit is ‘m’. +At startup, spreadwarn is inactive and limit is 3m. +

+

For example, +

+
+
.spreadwarn 0.2m
+
+ +

causes a warning if break warnings are not suppressed and +gtroff must add 0.2m or more for each inter-word space in a +line. See Warnings. +

+ + +

GNU troff has command-line options for reporting warnings +(-w) and backtraces (-b) when a warning or an error +occurs. +

+
+
Request: .warn [n]
+
+
Register: \n[.warn]
+
+ +

Select the categories, or “types”, of reported warnings. +n is the sum of the numeric codes associated with each +warning category that is to be enabled; all other categories are +disabled. The categories and their associated codes are listed in +Warnings. For example, ‘.warn 0’ disables all warnings, and +‘.warn 1’ disables all warnings except those about missing glyphs. +If no argument is given, all warning categories are enabled. +

+

The read-only register .warn contains the sum of the numeric +codes of enabled warning categories. +

+ + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Default-Units.html b/doc/groff.html.node/Default-Units.html new file mode 100644 index 0000000..168c5cc --- /dev/null +++ b/doc/groff.html.node/Default-Units.html @@ -0,0 +1,87 @@ + + + + + + +Default Units (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.3.2 Default Units

+ + + +

A general-purpose register (one created or updated with the nr +request; see see Registers) is implicitly dimensionless, or reckoned +in basic units if interpreted in a measurement context. But it is +convenient for many requests and escape sequences to infer a scaling +unit for an argument if none is specified. An explicit scaling unit +(not after a closing parenthesis) can override an undesirable default. +Effectively, the default unit is suffixed to the expression if a scaling +unit is not already present. GNU troff’s use of integer +arithmetic should also be kept in mind (see Numeric Expressions). +

+

The ll request interprets its argument in ems by default. +Consider several attempts to set a line length of 3.5 inches when +the type size is 10 points on a terminal device with a resolution +of 240 basic units and horizontal motion quantum of 24. Some +expressions become zero; the request clamps them to that quantum. +

+
+
.ll 3.5i      \" 3.5i (= 840u)
+.ll 7/2       \" 7u/2u -> 3u -> 3m -> 0, clamped to 24u
+.ll (7 / 2)u  \" 7u/2u -> as above
+.ll 7/2i      \" 7u/2i -> 7u/480u -> 0 -> as above
+.ll 7i/2      \" 7i/2u -> 1680u/2m -> 1680u/24u -> 35u
+.ll 7i/2u     \" 3.5i (= 840u)
+
+ + +

The safest way to specify measurements is to attach a scaling unit. To +multiply or divide by a dimensionless quantity, use ‘u’ as its +scaling unit. +

+ + +
+ + + + + diff --git a/doc/groff.html.node/Deferring-Output.html b/doc/groff.html.node/Deferring-Output.html new file mode 100644 index 0000000..81ab360 --- /dev/null +++ b/doc/groff.html.node/Deferring-Output.html @@ -0,0 +1,106 @@ + + + + + + +Deferring Output (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.27 Deferring Output

+ + + + + +

A few roff language elements are generally not used in simple +documents, but arise as page layouts become more sophisticated and +demanding. Environments collect formatting parameters like line +length and typeface. A diversion stores formatted output for +later use. A trap is a condition on the input or output, tested +automatically by the formatter, that is associated with a macro, causing +it to be called when that condition is fulfilled. +

+

Footnote support often exercises all three of the foregoing features. A +simple implementation might work as follows. A pair of macros is +defined: one starts a footnote and the other ends it. The author calls +the first macro where a footnote marker is desired. The macro +establishes a diversion so that the footnote text is collected at the +place in the body text where its corresponding marker appears. An +environment is created for the footnote so that it is set at a smaller +typeface. The footnote text is formatted in the diversion using that +environment, but it does not yet appear in the output. The document +author calls the footnote end macro, which returns to the previous +environment and ends the diversion. Later, after much more body text in +the document, a trap, set a small distance above the page bottom, is +sprung. The macro called by the trap draws a line across the page and +emits the stored diversion. Thus, the footnote is rendered. +

+

Diversions and traps make the text formatting process non-linear. Let +us imagine a set of text lines or paragraphs labelled ‘A’, +‘B’, and so on. If we set up a trap that produces text ‘T’ +(as a page footer, say), and we also use a diversion to store the +formatted text ‘D’, then a document with input text in the order +‘A B C D E F’ might render as ‘A B C E T F’. The diversion +‘D’ will never be output if we do not call for it. +

+

Environments of themselves are not a source of non-linearity in document +formatting: environment switches have immediate effect. One could +always write a macro to change as many formatting parameters as desired +with a single convenient call. But because diversions can be nested and +macros called by traps that are sprung by other trap-called macros, they +may be called upon in varying contexts. For example, consider a page +header that is always to be set in Helvetica. A document that uses +Times for most of its body text, but Courier for displayed code +examples, poses a challenge if a page break occurs in the middle of a +code display; if the header trap assumes that the “previous font” is +always Times, the rest of the example will be formatted in the wrong +typeface. One could carefully save all formatting parameters upon +entering the trap and restore them upon leaving it, but this is verbose, +error-prone, and not future-proof as the groff language develops. +Environments save us considerable effort. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Delimiters.html b/doc/groff.html.node/Delimiters.html new file mode 100644 index 0000000..fa117db --- /dev/null +++ b/doc/groff.html.node/Delimiters.html @@ -0,0 +1,233 @@ + + + + + + +Delimiters (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.6.5 Delimiters

+ + + + + + + +

Some escape sequences that require parameters use delimiters. The +neutral apostrophe ' is a popular choice and shown in this +document. The neutral double quote " is also commonly seen. +Letters, numerals, and leaders can be used. Punctuation characters +are likely better choices, except for those defined as infix operators +in numeric expressions; see below. +

+
+
\l'1.5i\[bu]' \" draw 1.5 inches of bullet glyphs
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

The following escape sequences don’t take arguments and thus are allowed +as delimiters: +\SP, \%, \|, \^, \{, +\}, \', \`, \-, \_, \!, +\?, \), \/, \,, \&, \:, +\~, \0, \a, \c, \d, \e, +\E, \p, \r, \t, and \u. However, +using them this way is discouraged; they can make the input confusing to +read. +

+ + + + + + + +

A few escape sequences, +\A, +\b, +\o, +\w, +\X, +and \Z, accept a newline as a delimiter. Newlines that serve +as delimiters continue to be recognized as input line terminators. +

+
+
A caf\o
+e\(aa
+in Paris
+    ⇒ A café in Paris
+
+ +

Use of newlines as delimiters in escape sequences is also discouraged. +

+ + + + + + + + + + + +

Finally, the escape sequences \D, \h, \H, +\l, \L, \N, \R, \s, \S, +\v, and \x prohibit many delimiters. +

+
    +
  • + + + + +the numerals 0-9 and the decimal point . + +
  • + + + + + + + + + + + + +the (single-character) operators ‘+-/*%<>=&:()’ + +
  • + +the space and tab characters + +
  • + + + + + + + + + + + + +any escape sequences other than \%, \:, \{, +\}, \', \`, \-, \_, \!, +\/, \c, \e, and \p +
+ +

Delimiter syntax is complex and flexible primarily for historical +reasons; the foregoing restrictions need be kept in mind mainly when +using groff in AT&T compatibility mode. GNU +troff keeps track of the nesting depth of escape sequence +interpolations, so the only characters you need to avoid using as +delimiters are those that appear in the arguments you input, not any +that result from interpolation. Typically, ' works fine. +See Implementation Differences. +

+
+
$ groff -Tps
+.de Mw
+.  nr wd \w'\\$1'
+.  tm "\\$1" is \\n(wd units wide.
+..
+.Mw Wet'suwet'en
+.Mw Wet+200i
+.cp 1 \" turn on compatibility mode
+.Mw Wet'suwet'en
+.Mw Wet'
+.Mw Wet+200i
+    error→ "Wet'suwet'en" is 54740 units wide.
+    error→ "Wet'+200i" is 42610 units wide.
+    error→ "Wet'suwet'en" is 15860 units wide.
+    error→ "Wet'" is 15860 units wide.
+    error→ "Wet'+200i" is 14415860 units wide.
+
+ +

We see here that in compatibility mode, the part of the argument after +the ' delimiter escapes from its context and, if nefariously +crafted, influences the computation of the wd register’s value in +a surprising way. +

+
+
+ + + + + + diff --git a/doc/groff.html.node/Device-Control-Commands.html b/doc/groff.html.node/Device-Control-Commands.html new file mode 100644 index 0000000..9d56288 --- /dev/null +++ b/doc/groff.html.node/Device-Control-Commands.html @@ -0,0 +1,185 @@ + + + + + + +Device Control Commands (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

6.1.2.4 Device Control Commands

+ +

Each device control command starts with the letter ‘x’, followed by +a space character (optional or arbitrary space or tab in gtroff) +and a subcommand letter or word; each argument (if any) must be preceded +by a syntactical space. All ‘x’ commands are terminated by a +syntactical line break; no device control command can be followed by +another command on the same line (except a comment). +

+

The subcommand is basically a single letter, but to increase +readability, it can be written as a word, i.e., an arbitrary sequence of +characters terminated by the next tab, space, or newline character. All +characters of the subcommand word but the first are simply ignored. For +example, gtroff outputs the initialization command ‘x i +as ‘x init and the resolution command ‘x r as +‘x res. +

+

In the following, the syntax element ‹line break› means a +syntactical line break (see Separation). +

+
+
xF nameline break
+

The ‘F’ stands for Filename. +

+

Use name as the intended name for the current file in error +reports. This is useful for remembering the original file name when +gtroff uses an internal piping mechanism. The input file is not +changed by this command. This command is a gtroff extension. +

+
+
xf n sline break
+

The ‘f’ stands for font. +

+

Mount font position n (a non-negative integer) with font +named s (a text word). See Font Positions. +

+
+
xH nline break
+

The ‘H’ stands for Height. +

+

Set glyph height to n (a positive integer in scaled points +‘z’). AT&T troff uses the unit points (‘p’) +instead. See Output Language Compatibility. +

+
+
xi‹line break
+

The ‘i’ stands for init. +

+

Initialize device. This is the third command of the prologue. +

+
+
xp‹line break
+

The ‘p’ stands for pause. +

+

Parsed but ignored. The AT&T troff manual documents +this command as +

+
+
pause device, can be restarted
+
+ +

but GNU troff output drivers do nothing with this command. +

+
+
xr n h vline break
+

The ‘r’ stands for resolution. +

+

Resolution is n, while h is the minimal horizontal +motion, and v the minimal vertical motion possible with this +device; all arguments are positive integers in basic units ‘u’ per +inch. This is the second command of the prologue. +

+
+
xS nline break
+

The ‘S’ stands for Slant. +

+

Set slant to n (an integer in basic units ‘u’). +

+
+
xs‹line break
+

The ‘s’ stands for stop. +

+

Terminates the processing of the current file; issued as the last +command of any intermediate troff output. +

+
+
xt‹line break
+

The ‘t’ stands for trailer. +

+

Generate trailer information, if any. In GNU troff, this is +ignored. +

+
+
xT xxxline break
+

The ‘T’ stands for Typesetter. +

+

Set the name of the output driver to xxx, a sequence of +non-whitespace characters terminated by whitespace. The possible names +correspond to those of groff’s -T option. This is the +first command of the prologue. +

+
+
xu nline break
+

The ‘u’ stands for underline. +

+

Configure underlining of spaces. If n is 1, start +underlining of spaces; if n is 0, stop underlining of spaces. +This is needed for the cu request in nroff mode and is +ignored otherwise. This command is a gtroff extension. +

+
+
xX anythingline break
+

The ‘x’ stands for X-escape. +

+

Send string anything uninterpreted to the device. If the line +following this command starts with a ‘+’ character this line is +interpreted as a continuation line in the following sense. The ‘+’ +is ignored, but a newline character is sent instead to the device, the +rest of the line is sent uninterpreted. The same applies to all +following lines until the first character of a line is not a ‘+’ +character. This command is generated by the gtroff escape +sequence \X. The line-continuing feature is a gtroff +extension. +

+
+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Device-and-Font-Description-Files.html b/doc/groff.html.node/Device-and-Font-Description-Files.html new file mode 100644 index 0000000..b935830 --- /dev/null +++ b/doc/groff.html.node/Device-and-Font-Description-Files.html @@ -0,0 +1,77 @@ + + + + + + +Device and Font Description Files (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + +
+ +
+

6.2 Device and Font Description Files

+ + + +

The groff font and output device description formats are slight +extensions of those used by AT&T device-independent +troff. In distinction to the AT&T implementation, +groff lacks a binary format; all files are text +files.125 The device and font description files for a device name +are stored in a devname directory. The device description +file is called DESC, and, for each font supported by the device, +a font description file is called f, where +f is usually an abbreviation of a font’s name and/or style. +For example, the ps (PostScript) device has groff font +description files for Times roman (TR) and Zapf Chancery Medium +italic (ZCMI), among many others, while the utf8 device +(for terminal emulators) has only font descriptions for the roman, +italic, bold, and bold-italic styles (R, I, B, and +BI, respectively). +

+

Device and font description files are read both by the formatter, GNU +troff, and by output drivers. The programs delegate these files’ +processing to an internal library, libgroff, ensuring their +consistent interpretation. +

+ + + +
+ + + + + diff --git a/doc/groff.html.node/Differences-from-AT_0026T-ms.html b/doc/groff.html.node/Differences-from-AT_0026T-ms.html new file mode 100644 index 0000000..6d45741 --- /dev/null +++ b/doc/groff.html.node/Differences-from-AT_0026T-ms.html @@ -0,0 +1,171 @@ + + + + + + +Differences from AT&T ms (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.7 Differences from AT&T ms

+ + + +

The groff ms macros are an independent reimplementation, +using no AT&T code. Since they take advantage of the extended +features of groff, they cannot be used with AT&T +troff. groff ms supports features described above +as Berkeley and Tenth Edition Research Unix extensions, and adds several +of its own. +

+
    +
  • The internals of groff ms differ from the internals of +AT&T ms. Documents that depend upon implementation +details of AT&T ms may not format properly with +groff ms. Such details include macros whose function was +not documented in the AT&T ms +manual.14 + +
  • The error-handling policy of groff ms is to detect and +report errors, rather than to ignore them silently. + +
  • Tenth Edition Research Unix supported P1/P2 macros to bracket code +examples; groff ms does not. + +
  • groff ms does not work in GNU troff’s +AT&T compatibility mode. If loaded when that mode is enabled, +it aborts processing with a diagnostic message. + +
  • Multiple line spacing is not supported. Use a larger vertical spacing +instead. + +
  • groff ms uses the same header and footer defaults in both +nroff and troff modes as AT&T ms does in +troff mode; AT&T’s default in nroff mode is to +put the date, in U.S. traditional format (e.g., “January 1, 2021”), +in the center footer (the CF string). + +
  • Many groff ms macros, including those for paragraphs, +headings, and displays, cause a reset of paragraph rendering parameters, +and may change the indentation; they do so not by incrementing or +decrementing it, but by setting it absolutely. This can cause problems +for documents that define additional macros of their own that try to +manipulate indentation. Use the ms RS and RE +macros instead of the in request. + +
  • + +AT&T ms interpreted the values of the registers +PS and VS in points, and did not support the use of +scaling units with them. groff ms interprets values of +the registers PS, VS, FPS, and FVS equal to +or larger than 1,000 (one thousand) as decimal fractions multiplied +by 1,000.15 This threshold makes use of a +scaling unit with these parameters practical for high-resolution +devices while preserving backward compatibility. It also permits +expression of non-integral type sizes. For example, ‘groff +-rPS=10.5p’ at the shell prompt is equivalent to placing ‘.nr PS +10.5p’ at the beginning of the document. + +
  • AT&T ms’s AU macro supported arguments used with +some document types; groff ms does not. + +
  • Right-aligned displays are available. The AT&T ms +manual observes that “it is tempting to assume that ‘.DS R’ will +right adjust lines, but it doesn’t work”. In groff ms, +it does. + +
  • To make groff ms use the default page offset (which also +specifies the left margin), the PO register must stay undefined +until the first ms macro is called. + +

    This implies that ‘\n[PO]’ should not be used early in the +document, unless it is changed also: accessing an undefined register +automatically defines it. +

    +
  • groff ms supports the PN register, but it is not +necessary; you can access the page number via the usual % +register and invoke the af request to assign a different format +to it if desired.16 + +
  • The AT&T ms manual documents registers CW and +GW as setting the default column width and “intercolumn gap”, +respectively, and which applied when MC was called with fewer +than two arguments. groff ms instead treats MC +without arguments as synonymous with 2C; there is thus no +occasion for a default column width register. Further, the MINGW +register and the second argument to MC specify a minimum +space between columns, not the fixed gutter width of AT&T +ms. + +
  • The AT&T ms manual did not document the QI +register; Berkeley and groff ms do. +
+ +
+
Register: \n[GS]
+
+

The register GS is set to 1 by the groff ms +macros, but is not used by the AT&T ms package. +Documents that need to determine whether they are being formatted with +groff ms or another implementation should test this +register. +

+ + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Displays-and-Keeps.html b/doc/groff.html.node/Displays-and-Keeps.html new file mode 100644 index 0000000..9d8f2b0 --- /dev/null +++ b/doc/groff.html.node/Displays-and-Keeps.html @@ -0,0 +1,74 @@ + + + + + + +Displays and Keeps (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

3.2.5 Displays and Keeps

+ + +

Displays are sections of text set off from the surrounding +material (typically paragraphs), often differing in indentation, and/or +spacing. Tables, block quotations, and figures are displayed. +Equations and code examples, when not much shorter than an output line, +often are. Lists may or may not be. Packages for setting man pages +support example displays but not keeps. +

+ +

A keep is a group of output lines, often a display, that is +formatted on a single page if possible; it causes a page break to happen +early so as to not interrupt the kept material. +

+ + +

Floating keeps can move, or “float”, relative to the text +around them in the input. They are useful for displays that are +captioned and referred to by name, as with “See figure 3”. +Depending on the package, a floating keep appears at the bottom of the +current page if it fits, and at the top of the next otherwise. +Alternatively, floating keeps might be deferred to the end of a section. +Using a floating keep can avoid the large vertical spaces that may +precede a tall keep of the ordinary sort when it won’t fit on the page. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Diversion-Traps.html b/doc/groff.html.node/Diversion-Traps.html new file mode 100644 index 0000000..4c924e7 --- /dev/null +++ b/doc/groff.html.node/Diversion-Traps.html @@ -0,0 +1,79 @@ + + + + + + +Diversion Traps (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.28.1.3 Diversion Traps

+ + + +

A diversion is not formatted in the context of a page, so it lacks page +location traps; instead it can have a diversion trap. There can +exist at most one such vertical position trap per diversion. +

+
+
Request: .dt [dist name]
+
+ + + + +

Set a trap within a diversion at location dist, which is +interpreted relative to diversion rather than page boundaries. If invoked with +fewer than two arguments, any diversion trap in the current diversion is +removed. The register .t works within diversions. It is an +error to invoke dt in the top-level diversion. +See Diversions. +

+ + +
+ + + + + diff --git a/doc/groff.html.node/Diversions.html b/doc/groff.html.node/Diversions.html new file mode 100644 index 0000000..c0dc8e9 --- /dev/null +++ b/doc/groff.html.node/Diversions.html @@ -0,0 +1,394 @@ + + + + + + +Diversions (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.29 Diversions

+ + +

In roff systems it is possible to format text as if for output, +but instead of writing it immediately, one can divert the +formatted text into a named storage area. It is retrieved later by +specifying its name after a control character. The same name space is +used for such diversions as for strings and macros; see +Identifiers. Such text is sometimes said to be “stored in a +macro”, but this coinage obscures the important distinction between +macros and strings on one hand and diversions on the other; the former +store unformatted input text, and the latter capture +formatted output. Diversions also do not interpret arguments. +Applications of diversions include “keeps” (preventing a page break +from occurring at an inconvenient place by forcing a set of output lines +to be set as a group), footnotes, tables of contents, and indices. + + +For orthogonality it is said that GNU troff is in the +top-level diversion if no diversion is active (that is, formatted +output is being “diverted” immediately to the output device). +

+

Dereferencing an undefined diversion will create an empty one of that +name and cause a warning in category ‘mac’ to be emitted. +See Warnings, for information about the enablement and suppression of +warnings. A diversion does not exist for the purpose of testing with +the d conditional operator until its initial definition ends +(see Operators in Conditionals). The following requests are used to +create and alter diversions. +

+
+
Request: .di [name]
+
+
Request: .da [name]
+
+ + + + + + +

Start collecting formatted output in a diversion called name. The +da request appends to a diversion called name, creating it +if necessary. If name already exists as an alias, the target of +the alias is replaced or appended to; recall Strings. The pending +output line is diverted as well. Switching to another environment (with +the ev request) before invoking di or da avoids +including any pending output line in the diversion; see +Environments. +

+

Invoking di or da without an argument stops diverting +output to the diversion named by the most recent corresponding request. +If di or da is called without an argument when there is no +current diversion, a warning in category ‘di’ is produced. +See Warnings, for information about the enablement and suppression +of warnings. +

+
+
Before the diversion.
+.di yyy
+In the diversion.
+.br
+.di
+After the diversion.
+.br
+    ⇒ After the diversion.
+.yyy
+    ⇒ Before the diversion.  In the diversion.
+
+
+ + +

GNU troff supports box requests to exclude a partially +collected line from a diversion, as this is often desirable. +

+
+
Request: .box [name]
+
+
Request: .boxa [name]
+
+

Divert (or append) output to name, similarly to the di and +da requests, respectively. Any pending output line is not +included in the diversion. Without an argument, stop diverting output; +any pending output line inside the diversion is discarded. +

+
+
Before the box.
+.box xxx
+In the box.
+.br
+Hidden treasure.
+.box
+After the box.
+.br
+    ⇒ Before the box.  After the box.
+.xxx
+    ⇒ In the box.
+
+
+ +

Apart from pending output line inclusion and the request names that +populate them, boxes are handled exactly as diversions are. All of the +following groff language elements can be used with them +interchangeably. +

+
+
Register: \n[.z]
+
+
Register: \n[.d]
+
+ + + + + + + +

Diversions may be nested. The read-only string-valued register +.z contains the name of the current diversion. The read-only +register .d contains the current vertical place in the diversion. +If the input text is not being diverted, .d reports the same +location as the register nl. +

+ +
+
Register: \n[.h]
+
+ + + + +

The read-only register .h stores the high-water mark on the +current page or in the current diversion. It corresponds to the text +baseline of the lowest line on the page.113 +

+
+
.tm .h==\n[.h], nl==\n[nl]
+    ⇒ .h==0, nl==-1
+This is a test.
+.br
+.sp 2
+.tm .h==\n[.h], nl==\n[nl]
+    ⇒ .h==40, nl==120
+
+ + + +

As implied by the example, vertical motion does not produce text +baselines and thus does not increase the value interpolated by +‘\n[.h]’. +

+ +
+
Register: \n[dn]
+
+
Register: \n[dl]
+
+ + + + +

After completing a diversion, the writable registers dn and +dl contain its vertical and horizontal sizes. Only the lines +just processed are counted: for the computation of dn and +dl, the requests da and boxa are handled as if +di and box had been used, respectively—lines that have +been already stored in the diversion (box) are not taken into account. +

+
+
.\" Center text both horizontally and vertically.
+.\" Macro .(c starts centering mode; .)c terminates it.
+.
+.\" Disable the escape character with .eo so that we
+.\" don't have to double backslashes on the "\n"s.
+.eo
+.de (c
+.  br
+.  ev (c
+.  evc 0
+.  in 0
+.  nf
+.  di @c
+..
+
+
+
.de )c
+.  br
+.  ev
+.  di
+.  nr @s (((\n[.t]u - \n[dn]u) / 2u) - 1v)
+.  sp \n[@s]u
+.  ce 1000
+.  @c
+.  ce 0
+.  sp \n[@s]u
+.  br
+.  fi
+.  rr @s
+.  rm @c
+..
+.ec
+
+
+ +
+
Escape sequence: \!anything
+
+
Escape sequence: \?anything\?
+
+ + +

Transparently embed anything into the current diversion, +preventing requests, macro calls, and escape sequences from being +interpreted when read into a diversion. This is useful for preventing +them from taking effect until the diverted text is actually output. The +\! escape sequence transparently embeds input up to and including +the end of the line. The \? escape sequence transparently embeds +input until its own next occurrence. +

+ + + + + + +

anything may not contain newlines; use \! by itself to +embed newlines in a diversion. The escape sequence \? is also +recognized in copy mode and turned into a single internal code; it is +this code that terminates anything. Thus the following example +prints 4. +

+
+
.nr x 1
+.nf
+.di d
+\?\\?\\\\?\\\\\\\\nx\\\\?\\?\?
+.di
+.nr x 2
+.di e
+.d
+.di
+.nr x 3
+.di f
+.e
+.di
+.nr x 4
+.f
+
+ +

Both escape sequences read the data in copy mode. +

+ + + +

If \! is used in the top-level diversion, its argument is +directly embedded into GNU troff’s intermediate output. This can +be used, for example, to control a postprocessor that processes the data +before it is sent to an output driver. +

+ + + +

The \? escape used in the top-level diversion produces no output +at all; its argument is simply ignored. +

+ + + + + + +
+
Request: .output contents
+
+

Emit contents directly to GNU troff’s intermediate output +(subject to copy mode interpretation); this is similar to \! used +at the top level. An initial neutral double quote in contents is +stripped to allow embedding of leading spaces. +

+

This request can’t be used before the first page has started—if you +get an error, simply insert .br before the output request. +

+

Use with caution! It is normally only needed for mark-up used by a +postprocessor that does something with the output before sending it to +the output device, filtering out contents again. +

+ +
+
Request: .asciify div
+
+ + + +

Unformat the diversion div in a way such that Unicode basic +Latin (ASCII) characters, characters translated with the +trin request, space characters, and some escape sequences, that +were formatted and diverted into div are treated like ordinary +input characters when div is reread. Doing so can be useful in +conjunction with the writem request. asciify can be also +used for gross hacks; for example, the following sets +register n to 1. +

+
+
.tr @.
+.di x
+@nr n 1
+.br
+.di
+.tr @@
+.asciify x
+.x
+
+ +

asciify cannot return all items in a diversion to their source +equivalent: nodes such as those produced by the \N escape +sequence will remain nodes, so the result cannot be guaranteed to be a +pure string. See Copy Mode. Glyph parameters such as the type face +and size are not preserved; use unformat to achieve that. +

+ +
+
Request: .unformat div
+
+

Like asciify, unformat the diversion div. However, +unformat handles only tabs and spaces between words, the latter +usually arising from spaces or newlines in the input. Tabs are treated +as input tokens, and spaces become adjustable again. The vertical sizes +of lines are not preserved, but glyph information (font, type size, +space width, and so on) is retained. +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Document-Formats.html b/doc/groff.html.node/Document-Formats.html new file mode 100644 index 0000000..9079d67 --- /dev/null +++ b/doc/groff.html.node/Document-Formats.html @@ -0,0 +1,57 @@ + + + + + + +Document Formats (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

3.2.9 Document Formats

+ + +

Some macro packages supply stock configurations of certain documents, +like business letters and memoranda. These often also have provision +for a cover sheet, which may be rigid in its format. With +these features, it is even more important to use the package’s macros in +preference to the formatter requests presented earlier, where possible. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Document-Parts.html b/doc/groff.html.node/Document-Parts.html new file mode 100644 index 0000000..7b83511 --- /dev/null +++ b/doc/groff.html.node/Document-Parts.html @@ -0,0 +1,84 @@ + + + + + + +Document Parts (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

6.1.1.3 Document Parts

+ +

A correct intermediate output document consists of two parts, the +prologue and the body. +

+

The task of the prologue is to set the general device parameters using +three exactly specified commands. gtroff’s prologue is +guaranteed to consist of the following three lines (in that order): +

+
+
x T device
+x res n h v
+x init
+
+ +

with the arguments set as outlined in Device Control Commands. +The parser for the intermediate output format is able to interpret +additional whitespace and comments as well even in the prologue. +

+

The body is the main section for processing the document data. +Syntactically, it is a sequence of any commands different from the ones +used in the prologue. Processing is terminated as soon as the first +‘x stop command is encountered; the last line of any +gtroff intermediate output always contains such a command. +

+

Semantically, the body is page oriented. A new page is started by a +‘p’ command. Positioning, writing, and drawing commands are always +done within the current page, so they cannot occur before the first +‘p’ command. Absolute positioning (by the ‘H’ and ‘V’ +commands) is done relative to the current page; all other positioning is +done relative to the current location within this page. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Drawing-Geometric-Objects.html b/doc/groff.html.node/Drawing-Geometric-Objects.html new file mode 100644 index 0000000..fa0732f --- /dev/null +++ b/doc/groff.html.node/Drawing-Geometric-Objects.html @@ -0,0 +1,361 @@ + + + + + + +Drawing Geometric Objects (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.26 Drawing Geometric Objects

+ + + +

A few of the formatter’s escape sequences draw lines and other geometric +objects. Combined with each other and with page motion commands +(see Page Motions), a wide variety of figures is possible. For +complex drawings, these operations can be cumbersome; the preprocessors +gpic or ggrn are typically used instead. +

+

The \l and \L escape sequences draw horizontal and +vertical sequences of glyphs, respectively. Even the simplest of +output devices supports them. +

+
+
Escape sequence: \l'l'
+
+
Escape sequence: \l'lc'
+
+ + +

Draw a horizontal line of length l from the drawing position. +Rightward motion is positive. Afterward, the drawing position is at the +right end of the line. The default scaling unit is ‘m’. +

+ + + + +

The optional second parameter c is a character with which to +draw the line. The default is the baseline rule special character, +\[ru]. +

+ + +

If c is a valid scaling unit, put \& after l to +disambiguate the input. +

+
+
.de textbox
+\[br]\\$*\[br]\l'|0\[rn]'\l'|0\[ul]'
+..
+
+ +

The foregoing outputs a box rule (a vertical line), the text +argument(s), and another box rule. We employ the boundary-relative +motion operator ‘|’. Finally, the line-drawing escape sequences +draw a radical extender (a form of overline) and an underline from the +drawing position to the position coresponding to beginning of the +input line. The drawing position returns to just after the +right-hand box rule because the lengths of the drawn lines are negative, +as noted above. +

+ +
+
Escape sequence: \L'l'
+
+
Escape sequence: \L'lc'
+
+ + + + + + +

Draw a vertical line of length l from the drawing position. +Downward motion is positive. The default scaling unit is ‘v’. The +default character is the box rule, \[br]. As with vertical +motion escape sequences, text processing continues where the line ends. +\L is otherwise similar to \l. +

+
+
$ nroff <<EOF
+This is a \L'3v'test.
+EOF
+    ⇒ This is a
+    ⇒           |
+    ⇒           |
+    ⇒           |test.
+
+ +

When writing text, the drawing position is at the text baseline; recall +Page Geometry. +

+ +

The \D escape sequence provides drawing commands that +direct the output device to render geometrical objects rather than +glyphs. Specific devices may support only a subset, or may feature +additional ones; consult the man page for the output driver in use. +Terminal devices in particular implement almost none. See Graphics Commands. +

+

Rendering starts at the drawing position; when finished, the drawing +position is left at the rightmost point of the object, even for closed +figures, except where noted. GNU troff draws stroked (outlined) +objects with the stroke color, and shades filled ones with the fill +color. See Colors. Coordinates h and v are horizontal +and vertical motions relative to the drawing position or previous point +in the command. The default scaling unit for horizontal measurements +(and diameters of circles) is ‘m’; for vertical ones, ‘v’. +

+

Circles, ellipses, and polygons can be drawn filled or stroked. These +are independent properties; if you want a filled, stroked figure, you +must draw the same figure twice using each drawing command. A filled +figure is always smaller than an outlined one because the former is +drawn only within its defined area, whereas strokes have a line +thickness (set with ‘\D't'’). +

+
+
\h'1i'\v'1i'\
+\# increase line thickness
+\Z'\D't 5p''\
+\# draw stroked (unfilled) polygon
+\Z'\D'p 3 3 -6 0''\
+\# draw filled (solid) polygon
+\Z'\D'P 3 3 -6 0''
+
+ +
+
Escape sequence: \D'command argument …'
+
+

Drawing command escape sequence parameters begin with an ordinary +character, command, selecting the type of object to be drawn, +followed by arguments whose meaning is determined by +command. +

+
+
\D'~ h1 v1hn vn'
+
+

Draw a B-spline to each point in sequence, leaving the drawing position +at (hn, vn). +

+
+
\D'a hc vc h v'
+
+

Draw a circular arc centered at (hc, vc) counterclockwise +from the drawing position to a point (h, v) relative to the +center. 105 +

+
+
\D'c d'
+
+ + + + +

Draw a circle of diameter d with its leftmost point at the drawing +position. +

+
+
\D'C d'
+
+ + + + +

As ‘\D'C '’, but the circle is filled. +

+
+
\D'e h v'
+
+ + + + +

Draw an ellipse of width h and height v with its leftmost +point at the drawing position. +

+
+
\D'E x y'
+
+ + + + +

As ‘\D'e '’, but the ellipse is filled. +

+
+
\D'l dx dy'
+
+

Draw line from the drawing position to (h, v). +

+

The following is a macro for drawing a box around a text argument; for +simplicity, the box margin is a fixed at 0.2m. +

+
+
.de TEXTBOX
+.  nr @wd \w'\\$1'
+\h'.2m'\
+\h'-.2m'\v'(.2m - \\n[rsb]u)'\
+\D'l 0 -(\\n[rst]u - \\n[rsb]u + .4m)'\
+\D'l (\\n[@wd]u + .4m) 0'\
+\D'l 0 (\\n[rst]u - \\n[rsb]u + .4m)'\
+\D'l -(\\n[@wd]u + .4m) 0'\
+\h'.2m'\v'-(.2m - \\n[rsb]u)'\
+\\$1\
+\h'.2m'
+..
+
+ +

The argument is measured with the \w escape sequence. Its width +is stored in register @wd. \w also sets the registers +rst and rsb; these contain its maximum vertical extents of +the argument. Then, four lines are drawn to form a box, offset by the +box margin. +

+
+
\D'p h1 v1hn vn'
+
+ + + + +

Draw polygon with vertices at drawing position and each point in +sequence. GNU troff closes the polygon by drawing a line from +(hn, vn) back to the initial drawing position. +Afterward, the drawing position is left at (hn, vn). +

+
+
\D'P dx1 dy1 dx2 dy2 …'
+
+ + + + +

As ‘\D'P '’, but the polygon is filled. +

+

The following macro is like the ‘\D'l'’ example, but shades the +box. We draw the box before writing the text because colors in GNU +troff have no transparency; in othe opposite order, the filled +polygon would occlude the text. +

+
+
.de TEXTBOX
+.  nr @wd \w'\\$1'
+\h'.2m'\
+\h'-.2m'\v'(.2m - \\n[rsb]u)'\
+\M[lightcyan]\
+\D'P 0 -(\\n[rst]u - \\n[rsb]u + .4m) \
+     (\\n[@wd]u + .4m) 0 \
+     0 (\\n[rst]u - \\n[rsb]u + .4m) \
+     -(\\n[@wd]u + .4m) 0'\
+\h'.2m'\v'-(.2m - \\n[rsb]u)'\
+\M[]\
+\\$1\
+\h'.2m'
+..
+
+ +
+
\D't n'
+
+

Set the stroke thickness of geometric objects to n basic units. A +zero n selects the minimal supported thickness. A negative +n selects a thickness proportional to the type size; this is the +default. +

+
+
+ +

In a hazy penumbra between text rendering and drawing commands we locate +the bracket-building escape sequence, \b. It can assemble +apparently large glyphs by vertically stacking ordinary ones. +

+
+
Escape sequence: \b'contents'
+
+ + + +

Pile and center a sequence of glyphs vertically on the output line. +Piling stacks glyphs corresponding to each character in +contents, read from left to right, and placed from top to bottom. +GNU troff separates the glyphs vertically by 1m, and the +pile itself is centered 0.5m above the text baseline. The +horizontal drawing position is then advanced by the width of the widest +glyph in the pile. +

+ + +

This rather inflexible positioning algorithm doesn’t work with the +dvi output device since its bracket pieces vary in height. +Instead, use the geqn preprocessor. +

+

Manipulating Spacing describes how to adjust the vertical spacing +of the output line with the \x escape sequence. +

+

The application of \b that lends its name is construction of +brackets, braces, and parentheses when typesetting mathematics. We +might construct a large opening (left) brace as follows. +

+
+
\b'\[lt]\[bv]\[lk]\[bv]\[lb]'
+
+ +

See groff_char(7) for a list of special character +identifiers. +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Dummy-Characters.html b/doc/groff.html.node/Dummy-Characters.html new file mode 100644 index 0000000..769574d --- /dev/null +++ b/doc/groff.html.node/Dummy-Characters.html @@ -0,0 +1,166 @@ + + + + + + +Dummy Characters (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.19.10 Dummy Characters

+ +

As discussed in Requests and Macros, the first character on an +input line is treated specially. Further, formatting a glyph has many +consequences on formatter state (see Environments). Occasionally, +we want to escape this context or embrace some of those consequences +without actually rendering a glyph to the output. +

+
+
Escape sequence: \&
+
+ + +

Interpolate a dummy character, which is constitutive of output but +invisible.81 Its presence alters the interpretation context of a +subsequent input character, and enjoys several applications. +

+
    +
  • Prevent insertion of extra space after an end-of-sentence character. + +
    +
    Test.
    +Test.
    +    ⇒ Test.  Test.
    +Test.\&
    +Test.
    +    ⇒ Test. Test.
    +
    + +
  • Prevent recognition of a control character. + +
    +
    .Test
    +    error→ warning: macro 'Test' not defined
    +\&.Test
    +    ⇒ .Test
    +
    + +
  • Prevent kerning between two glyphs. + + +
  • Translate a character to “nothing”. + +
    +
    .tr JIjiK\&k\&UVuv
    +Post universitum, alea jacta est, OK?
    +    ⇒ Post vniversitvm, alea iacta est, O?
    +
    +
+ +

The dummy character escape sequence sees use in macro definitions as a +means of ensuring that arguments are treated as text even if they begin +with spaces or control characters. +

+
+
.de HD \" typeset a simple bold heading
+.  sp
+.  ft B
+\&\\$1 \" exercise: remove the \&
+.  ft
+.  sp
+..
+.HD .\|.\|.\|surprised?
+
+
+ +

One way to think about the dummy character is to imagine placing the +symbol ‘&’ in the input at a certain location; if doing so has all +the side effects on formatting that you desire except for sticking an +ugly ampersand in the midst of your text, the dummy character is what +you want in its place. +

+
+
Escape sequence: \)
+
+ + + +

Interpolate a transparent dummy character—one that is +transparent to end-of-sentence detection. It behaves as \&, +except that \& is treated as letters and numerals normally are +after ‘.’, ‘?’ and ‘!’; \& cancels end-of-sentence +detection, and \) does not. +

+
+
.de Suffix-&
+.  nop \&\\$1
+..
+.
+.de Suffix-)
+.  nop \)\\$1
+..
+.
+Here's a sentence.\c
+.Suffix-& '
+Another one.\c
+.Suffix-) '
+And a third.
+    ⇒ Here's a sentence.' Another one.'  And a third.
+
+
+ + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/End_002dof_002dinput-Traps.html b/doc/groff.html.node/End_002dof_002dinput-Traps.html new file mode 100644 index 0000000..4dad1f2 --- /dev/null +++ b/doc/groff.html.node/End_002dof_002dinput-Traps.html @@ -0,0 +1,187 @@ + + + + + + +End-of-input Traps (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.28.5 End-of-input Traps

+ + + +
+
Request: .em [name]
+
+ + + + + +

Set a trap at the end of input, calling macro name after the last +line of the last input file has been processed. If no argument is +given, any existing end-of-input trap is removed. +

+

For example, if the document had to have a section at the bottom of the +last page for someone to approve it, the em request could be +used. +

+
+
.de approval
+\c
+.  ne 3v
+.  sp (\\n[.t]u - 3v)
+.  in +4i
+.  lc _
+.  br
+Approved:\t\a
+.  sp
+Date:\t\t\a
+..
+.
+.em approval
+
+ +

The \c in the above example needs explanation. For historical +reasons (compatibility with AT&T troff), the +end-of-input macro exits as soon as it causes a page break if no +partially collected line remains.111 +

+ + + + +

Let us assume that there is no \c in the above approval +macro, that the page is full, and last output line has been broken with, +say, a br request. Because there is no more room, a ne +request at this point causes a page ejection, which in turn makes +troff exit immediately as just described. In most situations, +this is not desired; people generally want to format the input after +ne. +

+

To force processing of the whole end-of-input macro independently of +this behavior, it is thus advisable to (invisibly) ensure the existence +of a partially collected line (\c) whenever there is a chance +that a page break can happen. In the above example, invoking the +ne request ensures that there is room for the subsequent +formatted output on the same page, so we need insert \c only +once. +

+

The next example shows how to append three lines, then start a new page +unconditionally. Since ‘.ne 1 doesn’t give the desired +effect—there is always one line available or we are already at the +beginning of the next page—we temporarily increase the page length by +one line so that we can use ‘.ne 2. +

+
+
.de EM
+.pl +1v
+\c
+.ne 2
+line one
+.br
+\c
+.ne 2
+line two
+.br
+\c
+.ne 2
+line three
+.br
+.pl -1v
+\c
+'bp
+..
+.em EM
+
+ +

This specific feature affects only the first potential page break caused +by the end-of-input macro; further page breaks emitted by the macro are +handled normally. +

+

Another possible use of the em request is to make GNU +troff emit a single large page instead of multiple pages. For +example, one may want to produce a long plain text file for reading +in a terminal or emulator without page footers and headers interrupting +the body of the document. One approach is to set the page length at the +beginning of the document to a very large value to hold all the +text,112 and +automatically adjust it to the exact height of the document after the +text has been output. +

+
+
.de adjust-page-length
+.  br
+.  pl \\n[nl]u \" \n[nl]: current vertical position
+..
+.
+.de single-page-mode
+.  pl 99999
+.  em adjust-page-length
+..
+.
+.\" Activate the above code if configured.
+.if \n[do-continuous-rendering] \
+.  single-page-mode
+
+ +

Since only one end-of-input trap exists and another macro package may +already use it, care must be taken not to break the mechanism. A simple +solution would be to append the above macro to the macro package’s +end-of-input macro using the am request. +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Environment.html b/doc/groff.html.node/Environment.html new file mode 100644 index 0000000..cd92fd5 --- /dev/null +++ b/doc/groff.html.node/Environment.html @@ -0,0 +1,151 @@ + + + + + + +Environment (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

2.2 Environment

+ + + +

There are also several environment variables (of the operating system, +not within gtroff) that can modify the behavior of groff. +

+
+
GROFF_BIN_PATH
+

This search path, followed by PATH, is used for commands executed +by groff. +

+
+
GROFF_COMMAND_PREFIX
+
+ +

If this is set to X, then groff runs +Xtroff instead of gtroff. This also applies +to tbl, pic, eqn, grn, +chem, refer, and soelim. It does not +apply to grops, grodvi, grotty, +pre-grohtml, post-grohtml, preconv, +grolj4, gropdf, and gxditview. +

+

The default command prefix is determined during the installation +process. If a non-GNU troff system is found, prefix ‘g’ is +used, none otherwise. +

+
+
GROFF_ENCODING
+

The value of this variable is passed to the preconv +preprocessor’s -e option to select the character encoding of +input files. This variable’s existence implies the groff option +-k. If set but empty, groff calls preconv +without an -e option. groff’s -K option +overrides GROFF_ENCODING. See the preconv(7) man page; +type ‘man preconv’ at the command line to view it. +

+
+
GROFF_FONT_PATH
+

A list of directories in which to seek the selected output device’s +directory of device and font description files. GNU troff +will search directories given as arguments to any specified -F +options before these, and a built-in list of directories after them. +See Font Directories and the troff(1) or +gtroff(1) man pages. +

+
+
GROFF_TMAC_PATH
+

A list of directories in which to seek macro files. GNU troff +will search directories given as arguments to any specified -M +options before these, and a built-in list of directories after them. +See Macro Directories and the troff(1) or +gtroff(1) man pages. +

+
+
GROFF_TMPDIR
+
+

The directory in which groff creates temporary files. If this is +not set and TMPDIR is set, temporary files are created in that +directory. Otherwise temporary files are created in a system-dependent +default directory (on Unix and GNU/Linux systems, this is usually +/tmp). grops, grefer, pre-grohtml, and +post-grohtml can create temporary files in this directory. +

+
+
GROFF_TYPESETTER
+

Sets the default output device. If empty or not set, a build-time +default (often ps) is used. The -Tdev option +overrides GROFF_TYPESETTER. +

+
+
SOURCE_DATE_EPOCH
+

A timestamp (expressed as seconds since the Unix epoch) to use as the +output creation timestamp in place of the current time. The time is +converted to human-readable form using localtime(3) when the +formatter starts up and stored in registers usable by documents and +macro packages (see Built-in Registers). +

+
+
TZ
+

The time zone to use when converting the current time (or value of +SOURCE_DATE_EPOCH) to human-readable form; see +tzset(3). +

+
+ +

MS-DOS and MS-Windows ports of groff use semicolons, rather than +colons, to separate the directories in the lists described above. +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Environments.html b/doc/groff.html.node/Environments.html new file mode 100644 index 0000000..489ee62 --- /dev/null +++ b/doc/groff.html.node/Environments.html @@ -0,0 +1,250 @@ + + + + + + +Environments (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.31 Environments

+ + +

As discussed in Deferring Output, environments store most of the +parameters that determine the appearance of text. A default environment +named ‘0’ exists when GNU troff starts up; it is modified by +formatting-related requests and escape sequences. +

+ +

You can create new environments and switch among them. Only one is +current at any given time. Active environments are managed using a +stack, a data structure supporting “push” and “pop” +operations. The current environment is at the top of the stack. +The same environment name can be pushed onto the stack multiple times, +possibly interleaved with others. Popping the environment stack does +not destroy the current environment; it remains accessible by name and +can be made current again by pushing it at any time. Environments +cannot be renamed or deleted, and can only be modified when current. To +inspect the environment stack, use the pev request; see +Debugging. +

+

Environments store the following information. +

+
    +
  • a partially collected line, if any + +
  • data about the most recently output glyph and line (registers +.cdp, .cht, .csk, .n, .w) + +
  • typeface parameters (size, family, style, height and slant, inter-word +and inter-sentence space sizes) + +
  • page parameters (line length, title length, vertical spacing, line +spacing, indentation, line numbering, centering, right-alignment, +underlining, hyphenation parameters) + +
  • filling enablement; adjustment enablement and mode + +
  • tab stops; tab, leader, escape, control, no-break control, hyphenation, +and margin characters + +
  • input line traps + +
  • stroke and fill colors +
+ +
+
Request: .ev [ident]
+
+
Register: \n[.ev]
+
+ + + +

Enter the environment ident, which is created if it does not +already exist, using the same parameters as for the default environment +used at startup. With no argument, GNU troff switches to the +previous environment. +

+

Invoking ev with an argument puts environment ident onto +the top of the environment stack. (If it isn’t already present in the +stack, this is a proper push.) Without an argument, ev pops the +environment stack, making the previous environment current. It is an +error to pop the environment stack with no previous environment +available. The read-only string-valued register .ev contains the +name of the current environment—the one at the top of the stack. +

+
+
.ev footnote-env
+.fam N
+.ps 6
+.vs 8
+.ll -.5i
+.ev
+
+
+
+.ev footnote-env
+\[dg] Observe the smaller text and vertical spacing.
+.ev
+
+ +

We can familiarize ourselves with stack behavior by wrapping the +ev request with a macro that reports the contents of the +.ev register to the standard error stream. +

+
+
.de EV
+.  ev \\$1
+.  tm environment is now \\n[.ev]
+..
+.
+.EV foo
+.EV bar
+.EV
+.EV baz
+.EV
+.EV
+.EV
+
+ +
+
    error→ environment is now foo
+    error→ environment is now bar
+    error→ environment is now foo
+    error→ environment is now baz
+    error→ environment is now foo
+    error→ environment is now 0
+    error→ error: environment stack underflow
+    error→ environment is now 0
+
+ +
+ +
+
Request: .evc environment
+
+ + +

Copy the contents of environment to the current environment. +

+

The following environment data are not copied. +

+
    +
  • a partially collected line, if present; + +
  • the interruption status of the previous input line (due to use of the +\c escape sequence); + +
  • the count of remaining lines to center, to right-justify, or to +underline (with or without underlined spaces)—these are set to zero; + +
  • the activation status of temporary indentation; + +
  • input line traps and their associated data; + +
  • the activation status of line numbering (which can be reactivated with +‘.nm +0); and + +
  • the count of consecutive hyphenated lines (set to zero). +
+
+ +
+
Register: \n[.w]
+
+
Register: \n[.cht]
+
+
Register: \n[.cdp]
+
+
Register: \n[.csk]
+
+ + + + + + + +

The \n[.w] register contains the width of the last glyph +formatted in the environment. +

+

The \n[.cht] register contains the height of the last glyph +formatted in the environment. +

+

The \n[.cdp] register contains the depth of the last glyph +formatted in the environment. It is positive for glyphs extending below +the baseline. +

+

The \n[.csk] register contains the skew (how far to the +right of the glyph’s center that GNU troff should place an +accent) of the last glyph formatted in the environment. +

+ +
+
Register: \n[.n]
+
+ + + + +

The \n[.n] register contains the length of the previous output +line emitted in the environment. +

+ + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Escape-Sequence-Index.html b/doc/groff.html.node/Escape-Sequence-Index.html new file mode 100644 index 0000000..19e5a61 --- /dev/null +++ b/doc/groff.html.node/Escape-Sequence-Index.html @@ -0,0 +1,162 @@ + + + + + + +Escape Sequence Index (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

Appendix C Escape Sequence Index

+ +

The escape character, \ by default, is always followed by at +least one more input character, making an escape sequence. Any +input token \X with X not in the list below emits a +warning and interpolates glyph X. Note the entries for \., +which may be obscured by the leader dots, and for \RET and +\SP, which are sorted alphabetically, not by code point +order. +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

\
\: Using Escape Sequences
\: Using Symbols
\!: Diversions
\": Comments
\#: Comments
\$: Parameters
\$*: Parameters
\$0: Parameters
\$@: Parameters
\$^: Parameters
\%: Manipulating Hyphenation
\&: Dummy Characters
\': Using Symbols
\(: Using Symbols
\): Dummy Characters
\*: Strings
\,: Italic Corrections
\-: Using Symbols
\.: Copy Mode
\/: Italic Corrections
\0: Page Motions
\:: Manipulating Hyphenation
\?: Diversions
\A: Identifiers
\a: Leaders
\B: Numeric Expressions
\b: Drawing Geometric Objects
\c: Line Continuation
\C: Using Symbols
\d: Page Motions
\D: Drawing Geometric Objects
\e: Using Escape Sequences
\E: Copy Mode
\f: Selecting Fonts
\F: Font Families
\g: Assigning Register Formats
\H: Artificial Fonts
\h: Page Motions
\k: Page Motions
\l: Drawing Geometric Objects
\L: Drawing Geometric Objects
\m: Colors
\M: Colors
\n: Interpolating Registers
\n: Auto-increment
\N: Using Symbols
\newline: Line Continuation
\o: Page Motions
\O: Suppressing Output
\p: Manipulating Filling and Adjustment
\R: Setting Registers
\R: Setting Registers
\r: Page Motions
\RET: Line Continuation
\S: Artificial Fonts
\s: Changing the Type Size
\SP: Page Motions
\space: Page Motions
\t: Tabs and Fields
\u: Page Motions
\v: Page Motions
\V: I/O
\w: Page Motions
\x: Manipulating Spacing
\X: Postprocessor Access
\Y: Postprocessor Access
\z: Page Motions
\Z: Page Motions
\[: Using Symbols
\\: Copy Mode
\^: Page Motions
\_: Using Symbols
\`: Using Symbols
\{: Conditional Blocks
\{: Conditional Blocks
\|: Page Motions
\}: Conditional Blocks
\~: Manipulating Filling and Adjustment

+
+ + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Fields.html b/doc/groff.html.node/Fields.html new file mode 100644 index 0000000..6e1754a --- /dev/null +++ b/doc/groff.html.node/Fields.html @@ -0,0 +1,98 @@ + + + + + + +Fields (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.12.2 Fields

+ + + + + + + + +

Fields are a more general way of laying out tabular data. A field +is defined as the data between a pair of delimiting characters. +It contains substrings that are separated by padding characters. +The width of a field is the distance on the input line from the +position where the field starts to the next tab stop. A padding +character inserts an adjustable space similar to TeX’s \hss +command (thus it can even be negative) to make the sum of all substring +lengths plus the adjustable space equal to the field width. If more +than one padding character is inserted, the available space is evenly +distributed among them. +

+
+
Request: .fc [delim-char [padding-char]]
+
+

Define a delimiting and a padding character for fields. If the latter +is missing, the padding character defaults to a space character. If +there is no argument at all, the field mechanism is disabled (which is +the default). In contrast to, e.g., the tab repetition character, +delimiting and padding characters are not associated with the +environment (see Environments). +

+
+
.fc # ^
+.ta T 3i
+#foo^bar^smurf#
+.br
+#foo^^bar^smurf#
+    ⇒ foo         bar          smurf
+    ⇒ foo            bar       smurf
+
+
+ + + +
+ + + + + diff --git a/doc/groff.html.node/File-Formats.html b/doc/groff.html.node/File-Formats.html new file mode 100644 index 0000000..c5d4d54 --- /dev/null +++ b/doc/groff.html.node/File-Formats.html @@ -0,0 +1,62 @@ + + + + + + +File Formats (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

6 File Formats

+ + + +

All files read and written by gtroff are text files. The +following two sections describe their format. +

+ + + + + +
+ + + + + diff --git a/doc/groff.html.node/File-Keyword-Index.html b/doc/groff.html.node/File-Keyword-Index.html new file mode 100644 index 0000000..348d292 --- /dev/null +++ b/doc/groff.html.node/File-Keyword-Index.html @@ -0,0 +1,215 @@ + + + + + + +File Keyword Index (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

Appendix H File Keyword Index

+ +
+
Jump to:   # +   +- +   +
+B +   +C +   +F +   +H +   +I +   +K +   +L +   +N +   +P +   +R +   +S +   +T +   +U +   +V +   +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

#
#: DESC File Format
#: Font Description File Format

-
---: Font Description File Format

B
biggestfont: DESC File Format

C
charset: DESC File Format
charset: Font Description File Format

F
family: Selecting Fonts
family: DESC File Format
fonts: Using Symbols
fonts: Special Fonts
fonts: DESC File Format

H
hor: DESC File Format

I
image_generator: DESC File Format

K
kernpairs: Font Description File Format

L
ligatures: Font Description File Format

N
name: Font Description File Format

P
paperlength: DESC File Format
papersize: DESC File Format
paperwidth: DESC File Format
pass_filenames: DESC File Format
postpro: DESC File Format
prepro: DESC File Format
print: DESC File Format

R
res: DESC File Format

S
sizes: DESC File Format
sizescale: DESC File Format
slant: Font Description File Format
spacewidth: Font Description File Format
spare1: DESC File Format
spare2: DESC File Format
special: Artificial Fonts
special: Font Description File Format
styles: Selecting Fonts
styles: Font Families
styles: DESC File Format

T
tcommand: DESC File Format

U
unicode: DESC File Format
unitwidth: DESC File Format
unscaled_charwidths: DESC File Format
use_charnames_in_special: Postprocessor Access
use_charnames_in_special: DESC File Format

V
vert: DESC File Format

+ +
+ + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Filling.html b/doc/groff.html.node/Filling.html new file mode 100644 index 0000000..f6db6f3 --- /dev/null +++ b/doc/groff.html.node/Filling.html @@ -0,0 +1,79 @@ + + + + + + +Filling (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.1.1 Filling

+ +

When GNU troff starts up, it obtains information about the device +for which it is preparing output.18 An essential property is the length of the output +line, such as “6.5 inches”. +

+ + +

GNU troff interprets plain text files employing the Unix +line-ending convention. It reads input a character at a time, +collecting words as it goes, and fits as many words together on an +output line as it can—this is known as filling. To GNU +troff, a word is any sequence of one or more characters +that aren’t spaces or newlines. The exceptions separate +words.19 To disable filling, see +Manipulating Filling and Adjustment. +

+
+
It is a truth universally acknowledged
+that a single man in possession of a
+good fortune must be in want of a wife.
+    ⇒ It is a truth universally acknowledged that a
+    ⇒ single man in possession of a good fortune must
+    ⇒ be in want of a wife.
+
+ + +
+ + + + + diff --git a/doc/groff.html.node/Font-Description-File-Format.html b/doc/groff.html.node/Font-Description-File-Format.html new file mode 100644 index 0000000..a44cf20 --- /dev/null +++ b/doc/groff.html.node/Font-Description-File-Format.html @@ -0,0 +1,280 @@ + + + + + + +Font Description File Format (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

6.2.2 Font Description File Format

+ + + + + +

On typesetting output devices, each font is typically available at +multiple sizes. While paper measurements in the device description file +are in absolute units, measurements applicable to fonts must be +proportional to the type size. groff achieves this using the +precedent set by AT&T device-independent troff: one +font size is chosen as a norm, and all others are scaled linearly +relative to that basis. The “unit width” is the number of basic units +per point when the font is rendered at this nominal size. +

+

For instance, groff’s lbp device uses a unitwidth +of 800. Its Times roman font ‘TR’ has a spacewidth +of 833; this is also the width of its comma, period, centered +period, and mathematical asterisk, while its ‘M’ is 2,963 basic +units. Thus, an ‘M’ on the lbp device is 2,963 basic units +wide at a notional type size of 800 points.126 +

+

A font description file has two sections. The first is a sequence of +directives, and is parsed similarly to the DESC file described +above. Except for the directive names that begin the second section, +their ordering is immaterial. Later directives of the same name +override earlier ones, spaces and tabs are handled in the same way, + + + +and the same comment syntax is supported. Empty lines are ignored +throughout. +

+
+
name f
+

The name of the font is f. ‘DESC’ is an invalid font +name. Simple integers are valid, but their use is +discouraged.127 +

+
+
spacewidth n
+

The width of an unadjusted inter-word space is n basic units. +

+
+ +

The directives above must appear in the first section; those below are +optional. +

+
+
slant n
+

The font’s glyphs have a slant of n degrees; a positive +n slants in the direction of text flow. +

+
+
ligatures lig1 lign [0]
+

Glyphs lig1, …, lign are ligatures; possible ligatures +are ‘ff’, ‘fi’, ‘fl’, ‘ffi’ and ‘ffl’. For +compatibility with other troff implementations, the list of +ligatures may be terminated with a 0. The list of ligatures +must not extend over more than one line. +

+
+
special
+
+

The font is special: when a glyph is requested that is not present +in the current font, it is sought in any mounted fonts that bear this +property. +

+
+ +

Other directives in this section are ignored by GNU troff, but +may be used by postprocessors to obtain further information about the +font. +

+

The second section contains one or two subsections. These can appear in +either order; the first one encountered commences the second section. +Each starts with a directive on a line by itself. A charset +subsection is mandatory unless the associated DESC file contains +the unicode directive. Another subsection, kernpairs, +is optional. +

+ +

The directive charset starts the character set +subsection.128 It precedes a series +of glyph descriptions, one per line. Each such glyph description +comprises a set of fields separated by spaces or tabs and organized as +follows. +

+
+

name metrics type code [entity-name] +[-- comment] +

+ + + + + + + + +

name identifies the glyph: +if name is a printable character c, it corresponds to +the troff ordinary character c. If name is a +multi-character sequence not beginning with \, it corresponds to +the GNU troff special character escape sequence +‘\[name]’. A name consisting of three minus signs, +‘---’, is special and indicates that the glyph is unnamed: such +glyphs can be accessed only by the \N escape sequence in +troff. A special character named ‘---’ can still be defined +using char and similar requests. The name\-’ +defines the minus sign glyph. Finally, name can be the +unbreakable one-sixth and one-twelfth space escape sequences, \| +and \^ (“thin” and “hair” spaces, respectively), in which +case only the width metric described below is interpreted; a font can +thus customize the widths of these spaces. +

+

The form of the metrics field is as follows. +

+
+
width[,[height[,[depth[,[italic-correction
+  [,[left-italic-correction[,[subscript-correction]]]]]]]]]]
+
+ +

There must not be any spaces, tabs, or newlines between these +subfields (which have been split here into two lines only for +better legibility). The subfields are in basic units expressed as +decimal integers. Unspecified subfields default to 0. +Since there is no associated binary format, these values are not +required to fit into the C language data type ‘char’ as they are in +AT&T device-independent troff. +

+

The width subfield gives the width of the glyph. The height +subfield gives the height of the glyph (upward is positive); if a glyph +does not extend above the baseline, it should be given a zero height, +rather than a negative height. The depth subfield gives the depth +of the glyph, that is, the distance below the baseline to which the +glyph extends (downward is positive); if a glyph does not extend below +the baseline, it should be given a zero depth, rather than a negative +depth. Italic corrections are relevant to glyphs in italic or oblique +styles. The italic-correction is the amount of space that should +be added after an oblique glyph to be followed immediately by an upright +glyph. The left-italic-correction is the amount of space that +should be added before an oblique glyph to be preceded immediately by an +upright glyph. The subscript-correction is the amount of space +that should be added after an oblique glyph to be followed by a +subscript; it should be less than the italic correction. +

+

For fonts used with typesetting devices, the type field gives a +featural description of the glyph: it is a bit mask recording whether +the glyph is an ascender, descender, both, or neither. When a \w +escape sequence is interpolated, these values are bitwise or-ed +together for each glyph and stored in the nr register. In font +descriptions for terminal devices, all glyphs might have a type of zero, +regardless of their appearance. +

+
+
0
+

means the glyph lies entirely between the baseline and a horizontal line +at the “x-height” of the font; typical examples are ‘a’, +‘c’, and ‘x’; +

+
+
1
+

means the glyph descends below the baseline, like ‘p’; +

+
+
2
+

means the glyph ascends above the font’s x-height, like ‘A’ or +‘b’; and +

+
+
3
+

means the glyph is both an ascender and a descender—this is true of +parentheses in some fonts. +

+
+ +

The code field gives a numeric identifier that the postprocessor +uses to render the glyph. The glyph can be specified to troff +using this code by means of the \N escape sequence. code +can be any integer.129 +

+

The entity-name field defines an identifier for the glyph that the +postprocessor uses to print the GNU troff glyph name. This +field is optional; it was introduced so that the grohtml output +driver could encode its character set. For example, the glyph +‘\[Po]’ is represented by ‘&pound;’ in HTML 4.0. +For efficiency, these data are now compiled directly into +grohtml. grops uses the field to build sub-encoding +arrays for PostScript fonts containing more than 256 glyphs. Anything +on the line after the entity-name field or ‘--’ is ignored. +

+

A line in the charset section can also have the form +

+
+
name "
+
+ +

identifying name as another name for the glyph mentioned in the +preceding line. Such aliases can be chained. +

+ +

The directive kernpairs starts a list of kerning adjustments to +be made to adjacent glyph pairs from this font. It contains a sequence +of lines formatted as follows. +

+
+
g1 g2 n
+
+ +

The foregoing means that when glyph g1 is typeset immediately +before g2, the space between them should be increased +by n. Most kerning pairs should have a negative value +for n. +

+ + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Font-Directories.html b/doc/groff.html.node/Font-Directories.html new file mode 100644 index 0000000..89cb39d --- /dev/null +++ b/doc/groff.html.node/Font-Directories.html @@ -0,0 +1,113 @@ + + + + + + +Font Directories (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

2.4 Font Directories

+ + + + + +

groff enforces few restrictions on how font description files are +named. For its family/style mechanism to work (see Font Families), +the names of fonts within a family should start with the family name, +followed by the style. For example, the Times family uses ‘T’ for +the family name and ‘R’, ‘B’, ‘I’, and ‘BI’ to +indicate the styles ‘roman’, ‘bold’, ‘italic’, and ‘bold italic’, +respectively. Thus the final font names are ‘TR’, ‘TB’, +‘TI’, and ‘TBI’. +

+ + +

Font description files are kept in font directories, which +together constitute the font path. The search procedure +always appends the directory devname, where name is +the name of the output device. Assuming TeX DVI output, and +/foo/bar as a font directory, the font description files for +grodvi must be in /foo/bar/devdvi. +Each directory in the font path is searched in the following order until +the desired font description file is found or the list is exhausted. +

+
    +
  • Directories specified with GNU troff’s or groff’s +-f command-line option. All output drivers (and some +preprocessors) support this option as well, because they require +information about the glyphs to be rendered in the document. + +
  • +Directories listed in the GROFF_FONT_PATH environment variable. + +
  • + +A site-local directory and the main font description directory. +The locations corresponding to your installation are listed in section +“Environment” of gtroff(1). If not otherwise configured, +they are as follows. + +
    +
    /usr/local/share/groff/site-font
    +/usr/local/share/groff/1.23.0/font
    +
    + +

    The foregoing assumes that the version of groff is 1.23.0, and +that the installation prefix was /usr/local. It is possible to +fine-tune these locations during the source configuration process. +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Font-Families.html b/doc/groff.html.node/Font-Families.html new file mode 100644 index 0000000..f631c1a --- /dev/null +++ b/doc/groff.html.node/Font-Families.html @@ -0,0 +1,182 @@ + + + + + + +Font Families (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.19.2 Font Families

+ + + + + +

To accommodate the wide variety of fonts available, GNU troff +distinguishes font families and font styles. A resolved +font name is the catenation of a font family and a style. Selecting an +abstract style causes GNU troff to combine it with the default +font family. +

+

You can thus compose a document using abstract styles exclusively for +its body or running text, selecting a specific family only for titles or +examples, for instance, and change the default family on the command +line (recall Options). +

+

Fonts for the devices ps, pdf, dvi, lj4, +lbp, and the X11 devices support this mechanism. By default, +GNU troff uses the Times family with the four styles ‘R’, +‘I’, ‘B’, and ‘BI’. +

+
+
Request: .fam [family]
+
+
Register: \n[.fam]
+
+
Escape sequence: \Ff
+
+
Escape sequence: \F(fm
+
Escape sequence: \F[family]
+
+ +

Set the default font family, used in combination with abstract styles to +construct a resolved font name, to family (one-character +name f, two-character name fm). If no argument is +given, GNU troff selects the previous font family; if there none, +is it falls back to the device’s default76 or its own (‘T’). +

+

The \F escape sequence works similarly. In disanalogy to +\f, ‘\FP’ makes ‘P’ the default family. Use +‘\F[]’ to select the previous default family. The default font +family is available in the read-only string-valued register .fam; +it is associated with the environment (see Environments). +

+
+
spam,     \" startup defaults are T (Times) R (roman)
+.fam H    \" make Helvetica the default family
+spam,     \" family H + style R = HR
+.ft B     \" family H + style B = HB
+spam,
+.ft CR    \" Courier roman (default family not changed)
+spam,
+.ft       \" back to Helvetica bold
+spam,
+.fam T    \" make Times the default family
+spam,     \" family T + style B = TB
+.ft AR    \" font AR (not a style)
+baked beans,
+.ft R     \" family T + style R = TR
+and spam.
+
+ +

\F doesn’t produce an input token in GNU troff. As a +consequence, it can be used in requests like mc (which expects +a single character as an argument) to change the font family on the fly. +

+
+
.mc \F[P]x\F[]
+
+
+ +
+
Request: .sty n style
+
+
Register: \n[.sty]
+
+ + + + + + + + + +

Associate an abstract style style with mounting +position n, which must be a non-negative integer. If the +requests cs, bd, tkf, uf, or fspecial +are applied to an abstract style, they are instead applied to the member +of the current family corresponding to that style. +

+ + +

The default family can be set with the -f option (see Options). The styles command in the DESC file controls +which font positions (if any) are initially associated with abstract +styles rather than fonts. +

+

Caution: The style argument is not validated. +Errors may occur later, when the formatter attempts to construct a +resolved font name, or format a character for output. +

+
+
.nr BarPos \n[.fp]
+.sty \n[.fp] Bar
+.fam Foo
+.ft \n[BarPos]
+.tm .f=\n[.f]
+A
+    error→ error: no font family named 'Foo' exists
+    error→ .f=41
+    error→ error: cannot format glyph: no current font
+
+ +

When an abstract style has been selected, the read-only string-valued +register ‘.sty’ interpolates its name; this datum is associated +with the environment (see Environments). Otherwise, ‘.sty’ +interpolates nothing. +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Font-Positions.html b/doc/groff.html.node/Font-Positions.html new file mode 100644 index 0000000..387b4bb --- /dev/null +++ b/doc/groff.html.node/Font-Positions.html @@ -0,0 +1,138 @@ + + + + + + +Font Positions (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.19.3 Font Positions

+ + + +

To support typeface indirection through abstract styles, and for +compatibility with AT&T troff, the formatter maintains +a list of font positions at which fonts required by a document are +mounted. An output device’s description file DESC +typically configures a set of pre-mounted fonts; see Device and Font Description Files. A font need not be explicitly mounted before +it is selected; GNU troff will search GROFF_FONT_PATH for +it by name and mount it at the first free mounting position on demand. +

+
+
Request: .fp pos id [font-description-file-name]
+
+
Register: \n[.f]
+
+
Register: \n[.fp]
+
+ + +

Mount a font under the name id at mounting position pos, a +non-negative integer. When the formatter starts up, it reads the output +device’s description to mount an initial set of faces, and selects font +position 1. Position 0 is unused by default. Unless the +font-description-file-name argument is given, id should be +the name of a font description file stored in a directory corresponding +to the selected output device. GNU troff does not traverse +directories to locate the font description file. +

+ + +

The optional third argument enables font names to be aliased, which can +be necessary in compatibility mode since AT&T troff syntax +affords no means of identifying fonts with names longer than two +characters, like ‘TBI’ or ‘ZCMI’, in a font selection escape +sequence. See Compatibility Mode. You can also alias fonts on +mounting for convenience or abstraction. (See below regarding the +.fp register.) +

+
+
.fp \n[.fp] SC ZCMI
+Send a \f(SChand-written\fP thank-you note.
+.fp \n[.fp] Emph TI
+.fp \n[.fp] Strong TB
+Are \f[Emph]these names\f[] \f[Strong]comfortable\f[]?
+
+ +

DESC’, ‘P’, and non-negative integers are not usable as font +identifiers. +

+ +

The position of the currently selected font (or abstract style) is +available in the read-only register ‘.f’. It is associated with +the environment (see Environments). +

+

You can copy the value of .f to another register to save it for +later use. +

+
+
.nr saved-font \n[.f]
+text involving many font changes
+.ft \n[saved-font]
+
+ + +

The index of the next (non-zero) free font position is available in the +read-only register ‘.fp’. + +Fonts not listed in the DESC file are automatically mounted at +position ‘\n[.fp]’ when selected with the ft request or +\f escape sequence. When mounting a font at a position +explicitly with the fp request, this same practice should be +followed, although GNU troff does not enforce this strictly. +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Font-and-Size-Changes.html b/doc/groff.html.node/Font-and-Size-Changes.html new file mode 100644 index 0000000..d8319bf --- /dev/null +++ b/doc/groff.html.node/Font-and-Size-Changes.html @@ -0,0 +1,56 @@ + + + + + + +Font and Size Changes (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

3.2.11 Font and Size Changes

+ +

The formatter’s requests and escape sequences for setting the typeface +and size are not always intuitive, so all macro packages provide macros +to make these operations simpler. They also make it more convenient to +change typefaces in the middle of a word and can handle italic +corrections automatically. See Italic Corrections. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Footnotes-and-Endnotes.html b/doc/groff.html.node/Footnotes-and-Endnotes.html new file mode 100644 index 0000000..82d14e7 --- /dev/null +++ b/doc/groff.html.node/Footnotes-and-Endnotes.html @@ -0,0 +1,60 @@ + + + + + + +Footnotes and Endnotes (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

3.2.6 Footnotes and Endnotes

+ + + +

Footnotes and endnotes are forms of delayed +formatting. They are recorded at their points of relevance in +the input, but not formatted there. Instead, a mark cues the +reader to check the “foot”, or bottom, of the current page, or in the +case of endnotes, an annotation list later in the document. Macro +packages that support these features also supply a means of +automatically numbering either type of annotation. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Formatter-Instructions.html b/doc/groff.html.node/Formatter-Instructions.html new file mode 100644 index 0000000..b6527ad --- /dev/null +++ b/doc/groff.html.node/Formatter-Instructions.html @@ -0,0 +1,83 @@ + + + + + + +Formatter Instructions (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.6 Formatter Instructions

+ + + +

To support documents that require more than filling, automatic line +breaking and hyphenation, adjustment, and supplemental inter-sentence +space, the roff language offers two means of embedding +instructions to the formatter. +

+ +

One is a request, which begins with a control character and takes +up the remainder of the input line. Requests often perform relatively +large-scale operations such as setting the page length, breaking the +line, or starting a new page. They also conduct internal operations +like defining macros. +

+ + +

The other is an escape sequence, which begins with the escape +character and can be embedded anywhere in the input, even in arguments +to requests and other escape sequences. Escape sequences interpolate +special characters, strings, or registers, and handle comparatively +minor formatting tasks like sub- and superscripting. +

+

Some operations, such as font selection and type size alteration, are +available via both requests and escape sequences. +

+ + + +
+ + + + + diff --git a/doc/groff.html.node/GNU-troff-Reference.html b/doc/groff.html.node/GNU-troff-Reference.html new file mode 100644 index 0000000..396d40a --- /dev/null +++ b/doc/groff.html.node/GNU-troff-Reference.html @@ -0,0 +1,99 @@ + + + + + + +GNU troff Reference (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/groff.html.node/Graphics-Commands.html b/doc/groff.html.node/Graphics-Commands.html new file mode 100644 index 0000000..87a856c --- /dev/null +++ b/doc/groff.html.node/Graphics-Commands.html @@ -0,0 +1,247 @@ + + + + + + +Graphics Commands (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

6.1.2.3 Graphics Commands

+ +

Each graphics or drawing command in the intermediate output starts with +the letter ‘D’, followed by one or two characters that specify a +subcommand; this is followed by a fixed or variable number of integer +arguments that are separated by a single space character. A ‘D’ +command may not be followed by another command on the same line (apart +from a comment), so each ‘D’ command is terminated by a syntactical +line break. +

+

gtroff output follows the classical spacing rules (no space +between command and subcommand, all arguments are preceded by a single +space character), but the parser allows optional space between the +command letters and makes the space before the first argument optional. +As usual, each space can be any sequence of tab and space characters. +

+

Some graphics commands can take a variable number of arguments. In this +case, they are integers representing a size measured in basic units +‘u’. The arguments called h1, h2, …, hn +stand for horizontal distances where positive means right, negative +left. The arguments called v1, v2, …, vn stand +for vertical distances where positive means down, negative up. All +these distances are offsets relative to the current location. +

+

Each graphics command directly corresponds to a similar gtroff +\D escape sequence. See Drawing Geometric Objects. +

+

Unknown ‘D’ commands are assumed to be device-specific. Its +arguments are parsed as strings; the whole information is then sent to +the postprocessor. +

+

In the following command reference, the syntax element ‹line +break› means a syntactical line break as defined above. +

+
+
D~ h1 v1 h2 v2hn vnline break
+

Draw B-spline from current position to offset (h1,v1), then +to offset (h2,v2), if given, etc., up to +(hn,vn). This command takes a variable number of argument +pairs; the current position is moved to the terminal point of the drawn +curve. +

+
+
Da h1 v1 h2 v2line break
+

Draw arc from current position to +(h1,v1)+(h2,v2) with center at +(h1,v1); then move the current position to the final point +of the arc. +

+
+
DC dline break
+
DC d dummy-argline break
+

Draw a solid circle using the current fill color with +diameter d (integer in basic units ‘u’) with leftmost +point at the current position; then move the current position to the +rightmost point of the circle. An optional second integer argument is +ignored (this allows the formatter to generate an even number of +arguments). This command is a gtroff extension. +

+
+
Dc dline break
+

Draw circle line with diameter d (integer in basic units +‘u’) with leftmost point at the current position; then move the +current position to the rightmost point of the circle. +

+
+
DE h vline break
+

Draw a solid ellipse in the current fill color with a horizontal +diameter of h and a vertical diameter of v (both +integers in basic units ‘u’) with the leftmost point at the current +position; then move to the rightmost point of the ellipse. This command +is a gtroff extension. +

+
+
De h vline break
+

Draw an outlined ellipse with a horizontal diameter of h and +a vertical diameter of v (both integers in basic units +‘u’) with the leftmost point at current position; then move to the +rightmost point of the ellipse. +

+
+
DF color-scheme [component]line break
+

Set fill color for solid drawing objects using different color schemes; +the analogous command for setting the color of text, line graphics, and +the outline of graphic objects is ‘m’. The color components are +specified as integer arguments between 0 and 65535. The number of color +components and their meaning vary for the different color schemes. +These commands are generated by gtroff’s escape sequences +‘\D'F …'’ and \M (with no other corresponding +graphics commands). No position changing. This command is a +gtroff extension. +

+
+
DFc cyan magenta yellowline break
+

Set fill color for solid drawing objects using the CMY color scheme, +having the 3 color components cyan, magenta, and +yellow. +

+
+
DFd‹line break
+

Set fill color for solid drawing objects to the default fill color value +(black in most cases). No component arguments. +

+
+
DFg grayline break
+

Set fill color for solid drawing objects to the shade of gray given by +the argument, an integer between 0 (black) and 65535 (white). +

+
+
DFk cyan magenta yellow blackline break
+

Set fill color for solid drawing objects using the CMYK color scheme, +having the 4 color components cyan, magenta, +yellow, and black. +

+
+
DFr red green blueline break
+

Set fill color for solid drawing objects using the RGB color scheme, +having the 3 color components red, green, and +blue. +

+
+ +
+
Df nline break
+

The argument n must be an integer in the range -32767 +to 32767. +

+
+
0 ≤ n ≤ 1000
+

Set the color for filling solid drawing objects to a shade of gray, +where 0 corresponds to solid white, 1000 (the default) to solid black, +and values in between to intermediate shades of gray; this is obsoleted +by command ‘DFg’. +

+
+
n < 0 or n > 1000
+

Set the filling color to the color that is currently being used for the +text and the outline, see command ‘m’. For example, the command +sequence +

+
+
mg 0 0 65535
+Df -1
+
+ +

sets all colors to blue. +

+
+ +

No position changing. This command is a gtroff extension. +

+
+
Dl h vline break
+

Draw line from current position to offset (h,v) (integers in +basic units ‘u’); then set current position to the end of the drawn +line. +

+
+
Dp h1 v1 h2 v2hn vnline break
+

Draw a polygon line from current position to offset (h1,v1), +from there to offset (h2,v2), etc., up to offset +(hn,vn), and from there back to the starting position. For +historical reasons, the position is changed by adding the sum of all +arguments with odd index to the actual horizontal position and the even +ones to the vertical position. Although this doesn’t make sense it is +kept for compatibility. +This command is a gtroff extension. +

+
+
DP h1 v1 h2 v2hn vnline break
+

Draw a solid polygon in the current fill color rather than an outlined +polygon, using the same arguments and positioning as the corresponding +‘Dp’ command. +This command is a gtroff extension. +

+
+
Dt nline break
+

Set the current line thickness to n (an integer in basic +units ‘u’) if n>0; if n=0 select the +smallest available line thickness; if n<0 set the line +thickness proportional to the type size (this is the default before the +first ‘Dt’ command was specified). For historical reasons, the +horizontal position is changed by adding the argument to the actual +horizontal position, while the vertical position is not changed. +Although this doesn’t make sense it is kept for compatibility. +This command is a gtroff extension. +

+
+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Groff-Options.html b/doc/groff.html.node/Groff-Options.html new file mode 100644 index 0000000..48ea5e5 --- /dev/null +++ b/doc/groff.html.node/Groff-Options.html @@ -0,0 +1,536 @@ + + + + + + +Groff Options (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

2.1 Options

+ + + + + + + + + + + + + +

groff normally runs the gtroff program and a +postprocessor appropriate for the selected device. The default device +is ‘ps’ (but it can be changed when groff is configured and +built). It can optionally preprocess with any of gpic, +geqn, gtbl, ggrn, grap, gchem, +grefer, gsoelim, or preconv. +

+

This section documents only options to the groff front end. Many +of the arguments to groff are passed on to gtroff; +therefore, those are also included. Arguments to preprocessors and +output drivers can be found in the man pages gpic(1), +geqn(1), gtbl(1), ggrn(1), +grefer(1), gchem(1), gsoelim(1), +preconv(1), grotty(1), grops(1), +gropdf(1), grohtml(1), grodvi(1), +grolj4(1), grolbp(1), and gxditview(1). +

+

The command-line format for groff is: +

+
+
groff [ -abceghijklpstvzCEGNRSUVXZ ] [ -dcs ] [ -Darg ]
+      [ -ffam ] [ -Fdir ] [ -Idir ] [ -Karg ]
+      [ -Larg ] [ -mname ] [ -Mdir ] [ -nnum ]
+      [ -olist ] [ -Parg ] [ -rcn ] [ -Tdev ]
+      [ -wname ] [ -Wname ] [ files… ]
+
+ +

The command-line format for gtroff is as follows. +

+
+
gtroff [ -abcivzCERU ] [ -dcs ] [ -ffam ] [ -Fdir ]
+       [ -mname ] [ -Mdir ] [ -nnum ] [ -olist ]
+       [ -rcn ] [ -Tname ] [ -wname ] [ -Wname ]
+       [ files… ]
+
+ +

Obviously, many of the options to groff are actually passed on to +gtroff. +

+

Options without an argument can be grouped behind a +single -. A filename of - denotes the +standard input. Whitespace is permitted between an option and its +argument. +

+

The grog command can be used to guess the correct groff +command to format a file. See its man page grog(1); type +‘man grog’ at the command line to view it. +

+

groff’s command-line options are as follows. +

+ +
+
-a
+

Generate a plain text approximation of the typeset output. The +read-only register .A is set to 1. See Built-in Registers. This option produces a sort of abstract preview of the +formatted output. +

+
    +
  • Page breaks are marked by a phrase in angle brackets; for example, +‘<beginning of page>’. + +
  • Lines are broken where they would be in the formatted output. + +
  • A horizontal motion of any size is represented as one space. Adjacent +horizontal motions are not combined. Inter-sentence space nodes (those +arising from the second argument to the ss request) are not +represented. + +
  • Vertical motions are not represented. + +
  • Special characters are rendered in angle brackets; for example, the +default soft hyphen character appears as ‘<hy>’. +
+ +

The above description should not be considered a specification; the +details of -a output are subject to change. +

+
+
-b
+

Write a backtrace reporting the state of gtroff’s input parser +to the standard error stream with each diagnostic message. The line +numbers given in the backtrace might not always be correct, because +gtroff’s idea of line numbers can be confused by requests that +append to +macros. +

+
+
-c
+

Start with color output disabled. +

+
+
-C
+

Enable AT&T troff compatibility mode; implies -c. +See Implementation Differences, for the list of incompatibilities +between groff and AT&T troff. +

+
+
-dctext
+
-dstring=text
+

Define roff string c or string as t or +text. c must be one character; string can be +of arbitrary length. Such string assignments happen before any macro +file is loaded, including the startup file. Due to getopt_long +limitations, c cannot be, and string cannot contain, an +equals sign, even though that is a valid character in a roff +identifier. +

+
+
-Denc
+

Set fallback input encoding used by preconv to enc; +implies -k. +

+
+
-e
+

Run geqn preprocessor. +

+
+
-E
+

Inhibit gtroff error messages. This option does not +suppress messages sent to the standard error stream by documents or +macro packages using tm or related requests. +

+
+
-ffam
+

Use fam as the default font family. See Font Families. +

+
+
-Fdir
+

Search in directory dir for the selected output device’s +directory of device and font description files. See the description of +GROFF_FONT_PATH in Environment below for the default search +locations and ordering. +

+
+
-g
+

Run ggrn preprocessor. +

+
+
-G
+

Run grap preprocessor; implies -p. +

+
+
-h
+

Display a usage message and exit. +

+
+
-i
+

Read the standard input after all the named input files have been +processed. +

+
+
-Idir
+

Search the directory dir for files named in several contexts; +implies -g and -s. +

+
    +
  • gsoelim replaces so requests with the contents of their +file name arguments. + +
  • gtroff searches for files named as operands in its command +line and as arguments to psbb, so, and soquiet +requests. + +
  • Output drivers may search for files; for instance, grops looks +for files named in ‘\X'ps: import '’, ‘\X'ps: file +'’, and ‘\X'pdf: pdfpic '’ device control +escape sequences. +
+ +

This option may be specified more than once; the directories are +searched in the order specified. If you want to search the current +directory before others, add ‘-I .’ at the desired place. The +current working directory is otherwise searched last. -I works +similarly to, and is named for, the “include” option of Unix C +compilers. +

+

-I options are passed to gsoelim, gtroff, +and output drivers; with the flag letter changed to -M, they +are also passed to ggrn. +

+
+
-j
+

Run gchem preprocessor. Implies -p. +

+
+
-k
+

Run preconv preprocessor. Refer to its man page for its +behavior if neither of groff’s -K or -D +options is also specified. +

+
+
-Kenc
+

Set input encoding used by preconv to enc; implies +-k. +

+
+
-l
+

Send the output to a spooler for printing. The print directive +in the device description file specifies the default command to be used; +see Device and Font Description Files. +See options -L and -X. +

+
+
-Larg
+

Pass arg to the print spooler program. If multiple args are +required, pass each with a separate -L option. groff +does not prefix an option dash to arg before passing it to the +spooler program. +

+
+
-mname
+

Process the file name.tmac prior to any input files. +If not found, tmac.name is attempted. name +(in both arrangements) is presumed to be a macro file; see the +description of GROFF_TMAC_PATH in Environment below for the +default search locations and ordering. This option and its argument are +also passed to geqn, grap, and ggrn. +

+
+
-Mdir
+

Search directory dir for macro files; see the description +of GROFF_TMAC_PATH in Environment below for the default +search locations and ordering. This option and its argument are also +passed to geqn, grap, and ggrn. +

+
+
-nnum
+

Number the first page num. +

+
+
-N
+

Prohibit newlines between eqn delimiters: pass -N to +geqn. +

+
+
-olist
+

Output only pages in list, which is a comma-separated list of page +ranges; ‘n’ means page n, ‘m-n’ +means every page between m and n, ‘-n’ means +every page up to n, ‘n-’ means every page from +n on. gtroff stops processing and exits after +formatting the last page enumerated in list. +

+
+
-p
+

Run gpic preprocessor. +

+
+
-Parg
+

Pass arg to the postprocessor. If multiple args are +required, pass each with a separate -P option. groff +does not prefix an option dash to arg before passing it to the +postprocessor. +

+
+
-rcnumeric-expression
+
-rregister=expr
+

Set roff register c or register to the value +numeric-expression (see Numeric Expressions). +c must be one character; register can be of arbitrary +length. Such register assignments happen before any macro file is +loaded, including the startup file. Due to getopt_long +limitations, c cannot be, and register cannot contain, +an equals sign, even though that is a valid character in a roff +identifier. +

+
+
-R
+

Run grefer preprocessor. No mechanism is provided for passing +arguments to grefer because most grefer options have +equivalent language elements that can be specified within the document. +

+ + +

gtroff also accepts a -R option, which is not +accessible via groff. This option prevents the loading of the +troffrc and troffrc-end files. +

+
+
-s
+

Run gsoelim preprocessor. +

+
+
-S
+
+ + + + + +

Operate in “safer” mode; see -U below for its opposite. For +security reasons, safer mode is enabled by default. +

+
+
-t
+

Run gtbl preprocessor. +

+
+
-Tdev
+

Direct gtroff to format the input for the output device +dev. groff then calls an output driver to convert +gtroff’s output to a form appropriate for dev. The +following output devices are available. +

+
+
ps
+

For PostScript printers and previewers. +

+
+
pdf
+

For PDF viewers or printers. +

+
+
dvi
+

For TeX DVI format. +

+
+
X75
+

For a 75dpi X11 previewer. +

+
+
X75-12
+

For a 75dpi X11 previewer with a 12-point base font in the +document. +

+
+
X100
+

For a 100dpi X11 previewer. +

+
+
X100-12
+

For a 100dpi X11 previewer with a 12-point base font in the +document. +

+
+
ascii
+
+ + + + +

For typewriter-like devices using the (7-bit) ASCII +(ISO 646) character set. +

+
+
latin1
+
+ + +

For typewriter-like devices that support the Latin-1 +(ISO 8859-1) character set. +

+
+
utf8
+
+ +

For typewriter-like devices that use the Unicode (ISO 10646) +character set with UTF-8 encoding. +

+
+
cp1047
+
+ + + + + + +

For typewriter-like devices that use the EBCDIC encoding IBM +code page 1047. +

+
+
lj4
+

For HP LaserJet4-compatible (or other PCL5-compatible) printers. +

+
+
lbp
+

For Canon CaPSL printers (LBP-4 and LBP-8 series laser +printers). +

+ + + +
+
html
+
xhtml
+

To produce HTML and XHTML output, respectively. +This driver consists of two parts, a preprocessor +(pre-grohtml) and a postprocessor (post-grohtml). +

+
+ + + +

The predefined GNU troff string .T contains the name of +the output device; the read-only register .T is set to 1 if +this option is used (which is always true if groff is used to +call GNU troff). See Built-in Registers. +

+

The postprocessor to be used for a device is specified by the +postpro command in the device description file. (See Device and Font Description Files.) This can be overridden with the +-X option. +

+
+
-U
+
+

Operate in unsafe mode, which enables the open, +opena, pi, pso, and sy requests. These +requests are disabled by default because they allow an untrusted input +document to write to arbitrary file names and run arbitrary commands. +This option also adds the current directory to the macro package search +path; see the -m option above. -U is passed to +gpic and gtroff. +

+
+
-v
+

Write version information for groff and all programs run by it +to the standard output stream; that is, the given command line is +processed in the usual way, passing -v to the formatter and any +pre- or postprocessors invoked. +

+
+
-V
+

Output the pipeline that would be run by groff +(as a wrapper program) to the standard output stream, but do not execute +it. If given more than once, the pipeline is both written to the +standard error stream and run. +

+
+
-wcategory
+

Enable warnings in category. Categories are listed in +Warnings. +

+
+
-Wcategory
+

Inhibit warnings in category. Categories are listed in +Warnings. +

+
+
-X
+

Use gxditview instead of the usual postprocessor to (pre)view +a document on an X11 display. Combining this option with +-Tps uses the font metrics of the PostScript device, whereas +the -TX75 and -TX100 options use the metrics of X11 +fonts. +

+
+
-z
+

Suppress formatted output from gtroff. +

+
+
-Z
+

Disable postprocessing. gtroff output will appear on the +standard output stream (unless suppressed with -z; see +gtroff Output for a description of this format. +

+
+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Gtroff-Internals.html b/doc/groff.html.node/Gtroff-Internals.html new file mode 100644 index 0000000..2e38fe7 --- /dev/null +++ b/doc/groff.html.node/Gtroff-Internals.html @@ -0,0 +1,187 @@ + + + + + + +Gtroff Internals (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.36 gtroff Internals

+ + + + + +

gtroff processes input in three steps. One or more input +characters are converted to an input token.119 Then, one or more input tokens are converted to +an output node. Finally, output nodes are converted to the +intermediate output language understood by all output devices. +

+

Actually, before step one happens, gtroff converts certain escape +sequences into reserved input characters (not accessible by the user); +such reserved characters are used for other internal processing also – +this is the very reason why not all characters are valid input. +See Identifiers, for more on this topic. +

+

For example, the input string ‘fi\[:u]’ is converted into a +character token ‘f’, a character token ‘i’, and a special +token ‘:u’ (representing u umlaut). Later on, the character +tokens ‘f’ and ‘i’ are merged to a single output node +representing the ligature glyph ‘fi’ (provided the current font has +a glyph for this ligature); the same happens with ‘:u’. All output +glyph nodes are ‘processed’, which means that they are invariably +associated with a given font, font size, advance width, etc. During the +formatting process, gtroff itself adds various nodes to control +the data flow. +

+

Macros, diversions, and strings collect elements in two chained lists: a +list of input tokens that have been passed unprocessed, and a list of +output nodes. Consider the following diversion. +

+
+
.di xxx
+a
+\!b
+c
+.br
+.di
+
+ +

It contains these elements. +

+ + + + + + + + + + + + +
node listtoken listelement number
line start node1
glyph node a2
word space node3
b4
\n5
glyph node c6
vertical size node7
vertical size node8
\n9
+ + +

Elements 1, 7, and 8 are inserted by gtroff; the latter two +(which are always present) specify the vertical extent of the last line, +possibly modified by \x. The br request finishes the +pending output line, inserting a newline input token, which is +subsequently converted to a space when the diversion is reread. Note +that the word space node has a fixed width that isn’t adjustable +anymore. To convert horizontal space nodes back to input tokens, use +the unformat request. +

+

Macros only contain elements in the token list (and the node list is +empty); diversions and strings can contain elements in both lists. +

+

The chop request simply reduces the number of elements in a +macro, string, or diversion by one. Exceptions are compatibility +save and compatibility ignore input tokens, which are ignored. +The substring request also ignores those input tokens. +

+

Some requests like tr or cflags work on glyph identifiers +only; this means that the associated glyph can be changed without +destroying this association. This can be very helpful for substituting +glyphs. In the following example, we assume that glyph ‘foo’ isn’t +available by default, so we provide a substitution using the +fchar request and map it to input character ‘x’. +

+
+
.fchar \[foo] foo
+.tr x \[foo]
+
+ +

Now let us assume that we install an additional special font ‘bar’ +that has glyph ‘foo’. +

+
+
.special bar
+.rchar \[foo]
+
+ +

Since glyphs defined with fchar are searched before glyphs in +special fonts, we must call rchar to remove the definition of the +fallback glyph. Anyway, the translation is still active; ‘x’ now +maps to the real glyph ‘foo’. +

+ + + + + + +

Macro and request arguments preserve compatibility mode enablement. +

+
+
.cp 1     \" switch to compatibility mode
+.de xx
+\\$1
+..
+.cp 0     \" switch compatibility mode off
+.xx caf\['e]
+    ⇒ café
+
+ +

Since compatibility mode is enabled while de is invoked, the +macro xx enables compatibility mode when it is called. Argument +$1 can still be handled properly because it inherits the +compatibility mode enablement status that was active at the point where +xx was called. +

+

After interpolation of the parameters, the compatibility save and +restore tokens are removed. +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Headers-and-Footers.html b/doc/groff.html.node/Headers-and-Footers.html new file mode 100644 index 0000000..5d1c50a --- /dev/null +++ b/doc/groff.html.node/Headers-and-Footers.html @@ -0,0 +1,61 @@ + + + + + + +Headers and Footers (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

3.2.3 Headers and Footers

+ +

Headers and footers occupy the top and bottom of +each page, respectively, and contain data like the page number and the +article or chapter title. Their appearance is not affected by the +running text. Some packages allow for different titles on even- and +odd-numbered pages (for printed, bound material). +

+

Headers and footers are together called titles, and comprise +three parts: left-aligned, centered, and right-aligned. A ‘%’ +character appearing anywhere in a title is automatically replaced by the +page number. See Page Layout. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Headings-in-ms.html b/doc/groff.html.node/Headings-in-ms.html new file mode 100644 index 0000000..a5d0cc7 --- /dev/null +++ b/doc/groff.html.node/Headings-in-ms.html @@ -0,0 +1,214 @@ + + + + + + +Headings in ms (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.5.4 Headings

+ + +

Use headings to create a sequential or hierarchical structure for your +document. The ms macros print headings in bold using +the same font family and, by default, type size as the body text. +Headings are available with and without automatic numbering. Text on +input lines following the macro call becomes the heading’s title. Call +a paragraphing macro to end the heading text and start the section’s +content. +

+
+
Macro: .NH [depth]
+
+
Macro: .NH S heading-depth-index
+

Set an automatically numbered heading. +

+

ms produces a numbered heading the form a.b.c…, to +any depth desired, with the numbering of each depth increasing +automatically and being reset to zero when a more significant level is +increased. “1” is the most significant or coarsest division of +the document. Only non-zero values are output. If depth is +omitted, it is taken to be ‘1’. +

+

If you specify depth such that an ascending gap occurs relative to +the previous NH call—that is, you “skip a depth”, as by +‘.NH 1’ and then ‘.NH 3’—groff ms emits a +warning on the standard error stream. +

+

Alternatively, you can give NH a first argument of S, +followed by integers to number the heading depths explicitly. Further +automatic numbering, if used, resumes using the specified indices as +their predecessors. +This feature is a Berkeley extension. +

+ +

An example may be illustrative. +

+
+
+
.NH 1
+Animalia
+.NH 2
+Arthropoda
+.NH 3
+Crustacea
+.NH 2
+Chordata
+.NH S 6 6 6
+Daimonia
+.NH 1
+Plantae
+
+
+ +

The above results in numbering as follows; the vertical space that +normally precedes each heading is omitted. +

+
+
1.  Animalia
+1.1.  Arthropoda
+1.1.1.  Crustacea
+1.2.  Chordata
+6.6.6.  Daimonia
+7.  Plantae
+
+ +
+
String: \*[SN-STYLE]
+
+
String: \*[SN-DOT]
+
+
String: \*[SN-NO-DOT]
+
+
String: \*[SN]
+
+

After NH is called, the assigned number is made available in the +strings SN-DOT (as it appears in a printed heading with default +formatting, followed by a terminating period) and SN-NO-DOT (with +the terminating period omitted). These are GNU extensions. +

+

You can control the style used to print numbered headings by defining an +appropriate alias for the string SN-STYLE. By default, +SN-STYLE is aliased to SN-DOT. If you prefer to omit the +terminating period from numbers appearing in numbered headings, you may +define the alias as follows. +

+
+
.als SN-STYLE SN-NO-DOT
+
+ +

Any such change in numbering style becomes effective from the next use +of NH following redefinition of the alias for SN-STYLE. +The formatted number of the current heading is available in the +SN string (a feature first documented by Berkeley), which +facilitates its inclusion in, for example, table captions, equation +labels, and XS/XA/XE table of contents entries. +

+ +
+
Macro: .SH [depth]
+
+

Set an unnumbered heading. +

+

The optional depth argument is a GNU extension indicating the +heading depth corresponding to the depth argument of NH. +It matches the type size at which the heading is set to that of a +numbered heading at the same depth when the GROWPS and +PSINCR heading size adjustment mechanism is in effect. +

+ +

If the GROWPS register is set to a value greater than the +level argument to NH or SH, the type size of a +heading produced by these macros increases by PSINCR units over +the size specified by PS multiplied by the difference of +GROWPS and level. The value stored in PSINCR is +interpreted in groff basic units; the p scaling unit +should be employed when assigning a value specified in points. For +example, the sequence +

+
+
+
.nr PS 10
+.nr GROWPS 3
+.nr PSINCR 1.5p
+.NH 1
+Carnivora
+.NH 2
+Felinae
+.NH 3
+Felis catus
+.SH 2
+Machairodontinae
+
+
+ +

will cause “1. Carnivora” to be printed in 13-point text, followed by +“1.1. Felinae” in 11.5-point text, while “1.1.1. Felis catus” and +all more deeply nested heading levels will remain in the 10-point text +specified by the PS register. “Machairodontinae” is printed at +11.5 points, since it corresponds to heading level 2. +

+

The HORPHANS register operates in conjunction with the NH +and SH macros to inhibit the printing of isolated headings at the +bottom of a page; it specifies the minimum number of lines of an +immediately subsequent paragraph that must be kept on the same page as +the heading. If insufficient space remains on the current page to +accommodate the heading and this number of lines of paragraph text, a +page break is forced before the heading is printed. Any display macro +call or tbl, pic, or eqn region between the heading +and the subsequent paragraph suppresses this grouping. See Keeps, boxed keeps, and displays and Tables, figures, equations, and references. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Hyphenation.html b/doc/groff.html.node/Hyphenation.html new file mode 100644 index 0000000..ec22419 --- /dev/null +++ b/doc/groff.html.node/Hyphenation.html @@ -0,0 +1,66 @@ + + + + + + +Hyphenation (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.1.3 Hyphenation

+ + +

When an output line is nearly full, it is uncommon for the next word +collected from the input to exactly fill it—typically, there is room +left over only for part of the next word. The process of splitting a +word so that it appears partially on one line (with a hyphen to indicate +to the reader that the word has been broken) with its remainder on the +next is hyphenation. Hyphenation points can be manually +specified; GNU troff also uses a hyphenation algorithm and +language-specific pattern files (based on those used in TeX) to +decide which words can be hyphenated and where. +

+

Hyphenation does not always occur even when the hyphenation rules for a +word allow it; it can be disabled, and when not disabled there are +several parameters that can prevent it in certain circumstances. +See Manipulating Hyphenation. +

+ +
+ + + + + diff --git a/doc/groff.html.node/I_002fO.html b/doc/groff.html.node/I_002fO.html new file mode 100644 index 0000000..92a7fc0 --- /dev/null +++ b/doc/groff.html.node/I_002fO.html @@ -0,0 +1,457 @@ + + + + + + +I/O (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.33 I/O

+ + + + + +

gtroff has several requests for including files: +

+
+
Request: .so file
+
+
Request: .soquiet file
+
+ + +

Replace the so request’s control line with the contents of the +file named by the argument, “sourcing” it. file is sought in +the directories specified by -I command-line option. If +file does not exist, a warning in category ‘file’ is produced +and the request has no further effect. See Warnings, for +information about the enablement and suppression of warnings. +

+

so can be useful for large documents; e.g., allowing each chapter +of a book to be kept in a separate file. However, files interpolated +with so are not preprocessed; to overcome this limitation, see +the gsoelim(1) man page. +

+

Since GNU troff replaces the entire control line with the +contents of a file, it matters whether file is terminated with a +newline or not. Assume that file xxx contains only the word +‘foo’ without a trailing newline. +

+
+
$ printf 'foo' > xxx
+
+The situation is
+.so xxx
+bar.
+    ⇒ The situation is foobar.
+
+ +

soquiet works the same way, except that no warning diagnostic is +issued if file does not exist. +

+ +
+
Request: .pso command
+
+

Read the standard output from the specified command and include +it in place of the pso request. +

+ + + + +

It is an error to use this request in safer mode, which is the +default. Invoke GNU troff or a front end with the -U +option to enable unsafe mode. +

+

The comment regarding a final newline for the so request is valid +for pso also. +

+ +
+
Request: .mso file
+
+
Request: .msoquiet file
+
+

Identical to the so and soquiet requests, respectively, +except that gtroff searches for the specified file in the +same directories as macro files for the -m command-line option. +If the file name to be included has the form name.tmac and +it isn’t found, these requests try to include tmac.name and +vice versa. +

+ +
+
Request: .trf file
+
+
Request: .cf file
+
+ + + + + + + + +

Transparently output the contents of file. Each line is output as +if it were preceded by \!; however, the lines are not +subject to copy mode interpretation. If the file does not end with a +newline, trf adds one. Both requests cause a break. +

+

When used in a diversion, these requests embed a node (see gtroff Internals) in it that, when reread, causes the contents of file +to be transparently copied to the output. In AT&T +troff, the contents of file are immediately copied to the +output regardless of whether there is a current diversion; this +behaviour is so anomalous that it must be considered a bug. +

+ + + +

While cf copies the contents of file completely +unprocessed, trf disallows characters such as NUL that are not +valid gtroff input characters (see Identifiers). +

+

For cf, within a diversion, “completely unprocessed” means that +each line of a file to be inserted is handled as if it were preceded by +\!\\!. +

+

To define a macro x containing the contents of +file f, use +

+
+
.ev 1
+.di x
+.trf f
+.di
+.ev
+
+ +

The calls to ev prevent the partially collected output line +from becoming part of the diversion (see Diversions). +

+ +
+
Request: .nx [file]
+
+ + + +

Force gtroff to continue processing of the file specified as an +argument. If no argument is given, immediately jump to the end of file. +

+ +
+
Request: .rd [prompt [arg1 arg2 …]]
+
+ + + +

Read from standard input, and include what is read as though it were +part of the input file. Text is read until a blank line is encountered. +

+

If standard input is a TTY input device (keyboard), write prompt +to standard error, followed by a colon (or send BEL for a beep if no +argument is given). +

+

Arguments after prompt are available for the input. For example, +the line +

+
+
.rd data foo bar
+
+ +

with the input ‘This is \$2. prints +

+
+
This is bar.
+
+
+ + + +

Using the nx and rd requests, it is easy to set up form +letters. The form letter template is constructed like this, putting the +following lines into a file called repeat.let: +

+
+
.ce
+\*(td
+.sp 2
+.nf
+.rd
+.sp
+.rd
+.fi
+Body of letter.
+.bp
+.nx repeat.let
+
+ + +

When this is run, a file containing the following lines should be +redirected in. Requests included in this file are executed as though +they were part of the form letter. The last block of input is the +ex request, which tells GNU troff to stop processing. If +this were not there, troff would not know when to stop. +

+
+
Trent A. Fisher
+708 NW 19th Av., #202
+Portland, OR  97209
+
+Dear Trent,
+
+Len Adollar
+4315 Sierra Vista
+San Diego, CA  92103
+
+Dear Mr. Adollar,
+
+.ex
+
+ +
+
Request: .pi pipe
+
+

Pipe the output of gtroff to the shell command(s) specified by +pipe. This request must occur before gtroff has a chance +to print anything. +

+ + + + +

It is an error to use this request in safer mode, which is the +default. Invoke GNU troff or a front end with the -U +option to enable unsafe mode. +

+

Multiple calls to pi are allowed, acting as a chain. For +example, +

+
+
.pi foo
+.pi bar
+...
+
+ +

is the same as ‘.pi foo | bar. +

+ + +

The intermediate output format of GNU troff is piped to the +specified commands. Consequently, calling groff without the +-Z option normally causes a fatal error. +

+ + + +
+
Request: .sy cmds
+
+
Register: \n[systat]
+
+

Execute the shell command(s) specified by cmds. The output is not +saved anywhere, so it is up to the user to do so. +

+ + + + +

It is an error to use this request in safer mode; this is the default. +Give GNU troff or a front end program the -U option to +enable unsafe mode. +

+

The following code fragment introduces the current time into a document. +

+ +
+
.sy perl -e 'printf ".nr H %d\\n.nr M %d\\n.nr S %d\\n",\
+             (localtime(time))[2,1,0]' > /tmp/x\n[$$]
+.so /tmp/x\n[$$]
+.sy rm /tmp/x\n[$$]
+\nH:\nM:\nS
+
+ +

This works by having the Perl script (run by sy) write +nr requests that set the registers H, M, and +S to a temporary file. The roff document then reads the +temporary file using the so request. +

+ + +

The registers seconds, minutes, and hours, +initialized at startup of GNU troff, should satisfy most +requirements. Use the af request to format their values for +output. +

+
+
.af hours 00
+.af minutes 00
+.af seconds 00
+\n[hours]:\n[minutes]:\n[seconds]
+    ⇒ 02:17:54
+
+ + +

The writable register systat contains the return value of the +system() function executed by the last sy request. +

+ +
+
Request: .open stream file
+
+
Request: .opena stream file
+
+ + + + +

Open the specified file for writing and associates the specified +stream with it. +

+

The opena request is like open, but if the file exists, +append to it instead of truncating it. +

+ + + + +

It is an error to use these requests in safer mode; this is the default. +Give GNU troff or a front end program the -U option to +enable unsafe mode. +

+ +
+
Request: .write stream data
+
+
Request: .writec stream data
+
+ + + + + + + + +

Write to the file associated with the specified stream. The +stream must previously have been the subject of an open request. The +remainder of the line is interpreted as the ds request reads its +second argument: an initial neutral double quote in contents is +stripped to allow embedding of leading spaces, and it is read in copy +mode. +

+

The writec request is like write, but only write +appends a newline to the data. +

+ +
+
Request: .writem stream xx
+
+ +

Write the contents of the macro or string xx to the file +associated with the specified stream. +

+ + + +

xx is read in copy mode, i.e., already formatted elements are +ignored. Consequently, diversions must be unformatted with the +asciify request before calling writem. Usually, this +means a loss of information. +

+ +
+
Request: .close stream
+
+ + +

Close the specified stream; the stream is no longer an acceptable +argument to the write request. +

+

Here a simple macro to write an index entry. +

+
+
.open idx test.idx
+.
+.de IX
+.  write idx \\n[%] \\$*
+..
+.
+.IX test entry
+.
+.close idx
+
+
+ +
+
Escape sequence: \Ve
+
+
Escape sequence: \V(ev
+
Escape sequence: \V[env]
+
+ + +

Interpolate the contents of the specified environment variable env +(one-character name e, two-character name ev) as +returned by the function getenv(3). \V is interpreted +even in copy mode (see Copy Mode). +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Identifiers.html b/doc/groff.html.node/Identifiers.html new file mode 100644 index 0000000..5734bb5 --- /dev/null +++ b/doc/groff.html.node/Identifiers.html @@ -0,0 +1,210 @@ + + + + + + +Identifiers (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.5 Identifiers

+ + +

An identifier labels a GNU troff datum such as a register, +name (macro, string, or diversion), typeface, color, special character, +character class, environment, or stream. Valid identifiers consist of +one or more ordinary characters. + + +An ordinary character is an input character that is not the +escape character, a leader, tab, newline, or invalid as GNU troff +input. +

+ + + + +

Invalid input characters are a subset of control characters (from the +sets “C0 Controls” and “C1 Controls” as Unicode describes them). +When GNU troff encounters one in an identifier, it produces a +warning in category ‘input’ (see Warnings). They are removed +during interpretation: an identifier ‘foo’, followed by an invalid +character and then ‘bar’, is processed as ‘foobar’. +

+

On a machine using the ISO 646, 8859, or 10646 character encodings, +invalid input characters are 0x00, 0x08, 0x0B, +0x0D0x1F, and 0x800x9F. On an +EBCDIC host, they are 0x000x01, 0x08, +0x09, 0x0B, 0x0D0x14, +0x170x1F, and +0x300x3F.40 Some of these code points are used +by GNU troff internally, making it non-trivial to extend the +program to accept UTF-8 or other encodings that use characters from +these ranges.41 +

+

Thus, the identifiers ‘br’, ‘PP’, ‘end-list’, +‘ref*normal-print’, ‘|’, ‘@_’, and ‘!"#$%'()*+,-./’ +are all valid. Discretion should be exercised to prevent confusion. +Identifiers starting with ‘(’ or ‘[’ require care. +

+
+
.nr x 9
+.nr y 1
+.nr (x 2
+.nr [y 3
+.nr sum1 (\n(x + \n[y])
+    error→ a space character is not allowed in an escape
+    error→   sequence parameter
+A:2+3=\n[sum1]
+.nr sum2 (\n((x + \n[[y])
+B:2+3=\n[sum2]
+.nr sum3 (\n[(x] + \n([y)
+C:2+3=\n[sum3]
+    ⇒ A:2+3=1 B:2+3=5 C:2+3=5
+
+ + +

An identifier with a closing bracket (‘]’) in its name can’t be +accessed with bracket-form escape sequences that expect an identifier as +a parameter. For example, ‘\[foo]]’ accesses the glyph ‘foo’, +followed by ‘]’ in whatever the surrounding context is, whereas +‘\C'foo]'’ formats a glyph named ‘foo]’. Similarly, the +identifier ‘(’ can’t be interpolated except with bracket +forms. +

+ + + + +

If you begin a macro, string, or diversion name with either of the +characters ‘[’ or ‘]’, you foreclose use of the grefer +preprocessor, which recognizes ‘.[’ and ‘.]’ as bibliographic +reference delimiters. +

+
+
Escape sequence: \A'anything'
+
+

Interpolate 1 if anything is a valid identifier, and 0 +otherwise. The delimiter need not be a neutral apostrophe; see +Delimiters. Because invalid input characters are removed (see +above), invalid identifiers are empty or contain spaces, tabs, or +newlines. +

+

You can employ \A to validate a macro argument before using it to +construct another escape sequence or identifier. +

+
+
.\" usage: .init-coordinate-pair name val1 val2
+.\" Create a coordinate pair where name!x=val1 and
+.\" name!y=val2.
+.de init-coordinate-pair
+.  if \A'\\$1' \{\
+.    if \B'\\$2' .nr \\$1!x \\$2
+.    if \B'\\$3' .nr \\$1!y \\$3
+.  \}
+..
+.init-coordinate-pair center 5 10
+The center is at (\n[center!x], \n[center!y]).
+.init-coordinate-pair "poi→nt" trash garbage \" ignored
+.init-coordinate-pair point trash garbage \" ignored
+    ⇒ The center is at (5, 10).
+
+ +

In this example, we also validated the numeric arguments; the registers +‘point!x’ and ‘point!y’ remain undefined. See Numeric Expressions for the \B escape sequence. +

+ + + +

How GNU troff handles the interpretation of an undefined +identifier depends on the context. There is no way to invoke an +undefined request; such syntax is interpreted as a macro call instead. +If the identifier is interpreted as a string, macro, or diversion, GNU +troff emits a warning in category ‘mac’, defines it as +empty, and interpolates nothing. If the identifier is interpreted as a +register, GNU troff emits a warning in category ‘reg’, +initializes it to zero, and interpolates that value. See Warnings, +Interpolating Registers, and Strings. Attempting to use an +undefined typeface, special character, color, character class, +environment, or stream generally provokes an error diagnostic. +

+ + + + + +

Identifiers for requests, macros, strings, and diversions share one name +space; special characters and character classes another. No other +object types do. +

+
+
.de xxx
+.  nop foo
+..
+.di xxx
+bar
+.br
+.di
+.
+.xxx
+    ⇒ bar
+
+ +

The foregoing example shows that GNU troff reuses the identifier +‘xxx’, changing it from a macro to a diversion. No warning is +emitted, and the previous contents of ‘xxx’ are lost. +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Implementation-Differences.html b/doc/groff.html.node/Implementation-Differences.html new file mode 100644 index 0000000..4645778 --- /dev/null +++ b/doc/groff.html.node/Implementation-Differences.html @@ -0,0 +1,64 @@ + + + + + + +Implementation Differences (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.38 Implementation Differences

+ + + + +

GNU troff has a number of features that cause incompatibilities +with documents written for other versions of troff. Some GNU +extensions to troff have become supported by other +implementations. +

+ + + +
+ + + + + diff --git a/doc/groff.html.node/Indented-regions-in-ms.html b/doc/groff.html.node/Indented-regions-in-ms.html new file mode 100644 index 0000000..44c648f --- /dev/null +++ b/doc/groff.html.node/Indented-regions-in-ms.html @@ -0,0 +1,112 @@ + + + + + + +Indented regions in ms (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.5.7 Indented regions

+ +

You may need to indent a region of text while otherwise formatting it +normally. Indented regions can be nested; you can change \n[PI] +before each call to vary the amount of inset. +

+
+
Macro: .RS
+
+

Begin a region where headings, paragraphs, and displays are indented +(further) by the amount stored in the PI register. +

+ +
+
Macro: .RE
+
+

End the (next) most recent indented region. +

+ +

This feature enables you to easily line up text under hanging and +indented paragraphs. + + +For example, you may wish to structure lists hierarchically. +

+
+
+
.IP \[bu] 2
+Lawyers:
+.RS
+.IP \[bu]
+Dewey,
+.IP \[bu]
+Cheatham,
+and
+.IP \[bu]
+and Howe.
+.RE
+.IP \[bu]
+Guns
+
+
+ +
+
• Lawyers:
+
+  •  Dewey,
+
+  •  Cheatham, and
+
+  •  Howe.
+
+• Guns
+
+ + +
+ + + + + diff --git a/doc/groff.html.node/Indexing.html b/doc/groff.html.node/Indexing.html new file mode 100644 index 0000000..26895ca --- /dev/null +++ b/doc/groff.html.node/Indexing.html @@ -0,0 +1,58 @@ + + + + + + +Indexing (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

3.2.8 Indexing

+ + + +

An index is similar to a table of contents, in that entry labels and +locations must be collected, but poses a greater challenge because it +needs to be sorted before it is output. Here, processing the document +in multiple passes is inescapable, and tools like the makeindex +program are necessary. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Input-Conventions.html b/doc/groff.html.node/Input-Conventions.html new file mode 100644 index 0000000..35005bd --- /dev/null +++ b/doc/groff.html.node/Input-Conventions.html @@ -0,0 +1,171 @@ + + + + + + +Input Conventions (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.1.10 Input Conventions

+ + + +

Since GNU troff fills text automatically, it is common practice +in the roff language to avoid visual composition of text in input +files: the esthetic appeal of the formatted output is what matters. +Therefore, roff input should be arranged such that it is easy for +authors and maintainers to compose and develop the document, understand +the syntax of roff requests, macro calls, and preprocessor +languages used, and predict the behavior of the formatter. Several +traditions have accrued in service of these goals. +

+
    +
  • Follow sentence endings in the input with newlines to ease their +recognition (see Sentences). It is frequently convenient to end +text lines after colons and semicolons as well, as these typically +precede independent clauses. Consider doing so after commas; they often +occur in lists that become easy to scan when itemized by line, or +constitute supplements to the sentence that are added, deleted, or +updated to clarify it. Parenthetical and quoted phrases are also good +candidates for placement on text lines by themselves. + +
  • Set your text editor’s line length to 72 characters or +fewer.32 +This limit, combined with the previous item of advice, makes it less +common that an input line will wrap in your text editor, and thus will +help you perceive excessively long constructions in your text. Recall +that natural languages originate in speech, not writing, and that +punctuation is correlated with pauses for breathing and changes in +prosody. + +
  • Use \& after ‘!’, ‘?’, and ‘.’ if they are +followed by space, tab, or newline characters and don’t end a sentence. + +
  • In filled text lines, use \& before ‘.’ and ‘'’ if they +are preceded by space, so that reflowing the input doesn’t turn them +into control lines. + +
  • Do not use spaces to perform indentation or align columns of a table. +Leading spaces are reliable when text is not being filled. + +
  • Comment your document. It is never too soon to apply comments to +record information of use to future document maintainers (including your +future self). We thus introduce another escape sequence, \", +which causes GNU troff to ignore the remainder of the input line. + +
  • Use the empty request—a control character followed immediately by a +newline—to visually manage separation of material in input files. +Many of the groff project’s own documents use an empty request +between sentences, after macro definitions, and where a break is +expected, and two empty requests between paragraphs or other requests or +macro calls that will introduce vertical space into the document. + +

    You can combine the empty request with the comment escape sequence to +include whole-line comments in your document, and even “comment out” +sections of it. +

+ +

We conclude this section with an example sufficiently long to illustrate +most of the above suggestions in practice. For the purpose of fitting +the example between the margins of this manual with the font used for +its typeset version, we have shortened the input line length to 56 +columns. As before, an arrow → indicates a tab character. +

+
+
+
.\"   nroff this_file.roff | less
+.\"   groff -T ps this_file.roff > this_file.ps
+→The theory of relativity is intimately connected with
+the theory of space and time.
+.
+I shall therefore begin with a brief investigation of
+the origin of our ideas of space and time,
+although in doing so I know that I introduce a
+controversial subject.  \" remainder of paragraph elided
+.
+.
+
+→The experiences of an individual appear to us arranged
+in a series of events;
+in this series the single events which we remember
+appear to be ordered according to the criterion of
+\[lq]earlier\[rq] and \[lq]later\[rq], \" punct swapped
+which cannot be analysed further.
+.
+There exists,
+therefore,
+for the individual,
+an I-time,
+or subjective time.
+.
+This itself is not measurable.
+.
+I can,
+indeed,
+associate numbers with the events,
+in such a way that the greater number is associated with
+the later event than with an earlier one;
+but the nature of this association may be quite
+arbitrary.
+.
+This association I can define by means of a clock by
+comparing the order of events furnished by the clock
+with the order of a given series of events.
+.
+We understand by a clock something which provides a
+series of events which can be counted,
+and which has other properties of which we shall speak
+later.
+.\" Albert Einstein, _The Meaning of Relativity_, 1922
+
+
+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Input-Encodings.html b/doc/groff.html.node/Input-Encodings.html new file mode 100644 index 0000000..f9ef79d --- /dev/null +++ b/doc/groff.html.node/Input-Encodings.html @@ -0,0 +1,154 @@ + + + + + + +Input Encodings (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.1.9 Input Encodings

+ +

The groff command’s -k option calls the +preconv preprocessor to perform input character encoding +conversions. Input to the GNU troff formatter itself, on the +other hand, must be in one of two encodings it can recognize. +

+
+
cp1047
+
+ + + + + + +

The code page 1047 input encoding works only on EBCDIC +platforms (and conversely, the other input encodings don’t work with +EBCDIC); the file cp1047.tmac is loaded at startup. +

+
+
latin1
+
+ + + +

ISO Latin-1, an encoding for Western European languages, is the +default input encoding on non-EBCDIC platforms; the file +latin1.tmac is loaded at startup. +

+
+ +

Any document that is encoded in ISO 646:1991 (a descendant of USAS +X3.4-1968 or “US-ASCII”), or, equivalently, uses only code points +from the “C0 Controls” and “Basic Latin” parts of the Unicode +character set is also a valid ISO Latin-1 document; the standards +are interchangeable in their first 128 code points.30 +

+

Other encodings are supported by means of macro packages. +

+
+
latin2
+
+ + + +

To use ISO Latin-2, an encoding for Central and Eastern European +languages, invoke ‘.mso latin2.tmac at the beginning of your +document or supply ‘-mlatin2’ as a command-line argument to +groff. +

+
+
latin5
+
+ + + +

To use ISO Latin-5, an encoding for the Turkish language, invoke +‘.mso latin5.tmac at the beginning of your document or +supply ‘-mlatin5’ as a command-line argument to groff. +

+
+
latin9
+
+ + + +

ISO Latin-9 succeeds Latin-1; it includes a Euro sign and better +glyph coverage for French. To use this encoding, invoke ‘.mso latin9.tmac at the beginning of your document or supply +‘-mlatin9’ as a command-line argument to groff. +

+
+ +

Some characters from an input encoding may not be available with a +particular output driver, or their glyphs may not have representation in +the font used. For terminal devices, fallbacks are defined, like +‘EUR’ for the Euro sign and ‘(C)’ for the copyright sign. For +typesetter devices, you may need to “mount” fonts that support glyphs +required by the document. See Font Positions. +

+ + +

Because a Euro glyph was not historically defined in PostScript fonts, +groff comes with a font called freeeuro.pfa that provides +the Euro in several styles. Standard PostScript fonts contain the +glyphs from Latin-5 and Latin-9 that Latin-1 lacks, so these +encodings are supported for the ps and pdf output +devices as groff ships, while Latin-2 is not. +

+

Unicode supports characters from all other input encodings; the +utf8 output driver for terminals therefore does as well. The +DVI output driver supports the Latin-2 and Latin-9 encodings if +the command-line option -mec is used as well. 31 +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Input-Line-Traps.html b/doc/groff.html.node/Input-Line-Traps.html new file mode 100644 index 0000000..f0d7fef --- /dev/null +++ b/doc/groff.html.node/Input-Line-Traps.html @@ -0,0 +1,185 @@ + + + + + + +Input Line Traps (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.28.2 Input Line Traps

+ + + +
+
Request: .it [n name]
+
+
Request: .itc [n name]
+
+ + + + + + +

Set an input line trap, calling macro name after processing the +next n productive input lines (recall Manipulating Filling and Adjustment). Any existing input line trap in the +environment is replaced. Without arguments, it and itc +clear any input line trap that has not yet sprung. +

+

Consider a macro ‘.ST s n’ which sets the next +n input lines in the font style s. +

+
+
.de ST \" Use style $1 for next $2 text lines.
+.  it \\$2 ES
+.  ft \\$1
+..
+.de ES \" end ST
+.  ft R
+..
+.ST I 1
+oblique
+face
+.ST I 1
+oblique\c
+face
+    ⇒ oblique face obliqueface  (second “face” upright)
+
+ + + + + +

Unlike the ce and rj requests, it counts lines +interrupted with the \c escape sequence separately (see Line Continuation); itc does not. To see the difference, let’s +change the previous example to use itc instead. +

+
+

+.  itc \\$2 ES
+
+    ⇒ oblique face obliqueface  (second “face” oblique)
+
+ +

You can think of the ce and rj requests as implicitly +creating an input line trap with itc that schedules a break when +the trap is sprung. +

+
+
.de BR
+.  br
+.  internal: disable centering-without-filling
+..
+.
+.de ce
+.  if \\n[.br] .br
+.  itc \\$1 BR
+.  internal: enable centering-without-filling
+..
+
+ +

Let us consider in more detail the sorts of input lines that are or are +not “productive”. +

+
+
.de Trap
+TRAP SPRUNG
+..
+.de Mac
+.if r a \l'5n'
+..
+.it 2 Trap
+.
+foo
+.Mac
+bar
+baz
+.it 1 Trap
+.sp \" moves, but does not write or draw
+qux
+.itc 1 Trap
+\h'5n'\c \" moves, but does not write or draw
+jat
+
+ +

When ‘Trap’ gets called depends on whether the ‘a’ register is +defined; the control line with the if request may or may not +produce written output. We also see that the spacing request sp, +while certainly affecting the output, does not spring the input line +trap. Similarly, the horizontal motion escape sequence \h also +affected the output, but was not “written”. Observe that we had to +follow it with \c and use itc to prevent the newline at +the end of the text line from causing a word break, which, like an +ordinary space character, counts as written output. +

+
+
$ groff -Tascii input-trap-example.groff
+    ⇒ foo bar TRAP SPRUNG baz
+    ⇒
+    ⇒ qux TRAP SPRUNG      jat TRAP SPRUNG
+$ groff -Tascii -ra1 input-trap-example.groff
+    ⇒ foo _____ TRAP SPRUNG bar baz
+    ⇒
+    ⇒ qux TRAP SPRUNG      jat TRAP SPRUNG
+
+
+ +

Input line traps are associated with the environment +(see Environments); switching to another environment suspends the +current input line trap, and going back resumes it, restoring the count +of qualifying lines enumerated in that environment. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Installation.html b/doc/groff.html.node/Installation.html new file mode 100644 index 0000000..659fdce --- /dev/null +++ b/doc/groff.html.node/Installation.html @@ -0,0 +1,57 @@ + + + + + + +Installation (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

1.7 Installation

+ + +

Locate installation instructions in the files INSTALL, +INSTALL.extra, and INSTALL.REPO in the groff source +distribution. Being a GNU project, groff supports the familiar +‘./configure && make’ command sequence. +

+ + +
+ + + + + diff --git a/doc/groff.html.node/Intermediate-Output-Examples.html b/doc/groff.html.node/Intermediate-Output-Examples.html new file mode 100644 index 0000000..0947e86 --- /dev/null +++ b/doc/groff.html.node/Intermediate-Output-Examples.html @@ -0,0 +1,171 @@ + + + + + + +Intermediate Output Examples (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

6.1.3 Intermediate Output Examples

+ +

This section presents the intermediate output generated from the same +input for three different devices. The input is the sentence ‘hell +world’ fed into gtroff on the command line. +

+
+
High-resolution device ps
+
+

This is the standard output of gtroff if no -T option is +given. +

+
+
shell> echo "hell world" | groff -Z -T ps
+
+x T ps
+x res 72000 1 1
+x init
+
p1
+x font 5 TR
+f5
+s10000
+V12000
+H72000
+thell
+wh2500
+tw
+H96620
+torld
+n12000 0
+
x trailer
+V792000
+x stop
+
+ +

This output can be fed into grops to get its representation as a +PostScript file. +

+
+
Low-resolution device latin1
+
+

This is similar to the high-resolution device except that the +positioning is done at a minor scale. Some comments (lines starting +with ‘#’) were added for clarification; they were not generated by +the formatter. +

+
+
shell> echo "hell world" | groff -Z -T latin1
+
+# prologue
+x T latin1
+x res 240 24 40
+x init
+
# begin a new page
+p1
+# font setup
+x font 1 R
+f1
+s10
+# initial positioning on the page
+V40
+H0
+# write text 'hell'
+thell
+# inform about space, and issue a horizontal jump
+wh24
+# write text 'world'
+tworld
+# announce line break, but do nothing because...
+n40 0
+
# ...the end of the document has been reached
+x trailer
+V2640
+x stop
+
+ +

This output can be fed into grotty to get a formatted text +document. +

+
+
AT&T troff output
+

Since a computer monitor has a much lower resolution than modern +printers, the intermediate output for X11 devices can use the +jump-and-write command with its 2-digit displacements. +

+
+
shell> echo "hell world" | groff -Z -T X100
+
+x T X100
+x res 100 1 1
+x init
+
p1
+x font 5 TR
+f5
+s10
+V16
+H100
+# write text with jump-and-write commands
+ch07e07l03lw06w11o07r05l03dh7
+n16 0
+
x trailer
+V1100
+x stop
+
+ +

This output can be fed into xditview or gxditview for +displaying in X. +

+

Due to the obsolete jump-and-write command, the text clusters in the +AT&T troff output are almost unreadable. +

+
+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Interpolating-Registers.html b/doc/groff.html.node/Interpolating-Registers.html new file mode 100644 index 0000000..21d01f8 --- /dev/null +++ b/doc/groff.html.node/Interpolating-Registers.html @@ -0,0 +1,99 @@ + + + + + + +Interpolating Registers (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.8.2 Interpolating Registers

+ + + +

Register contents are interpolated with the \n escape sequence. +

+
+
Escape sequence: \ni
+
+
Escape sequence: \n(id
+
Escape sequence: \n[ident]
+
+ + + +

Interpolate register with name ident (one-character +name i, two-character name id). \n is +interpreted even in copy mode (see Copy Mode). If the register is +undefined, it is created and assigned a value of ‘0’, that +value is interpolated, and a warning in category ‘reg’ is emitted. +See Warnings, for information about the enablement and suppression of +warnings. +

+
+
.nr a 5
+.nr as \na+\na
+\n(as
+    ⇒ 10
+
+ +
+
.nr a1 5
+.nr ab 6
+.ds str b
+.ds num 1
+\n[a\n[num]]
+    ⇒ 5
+\n[a\*[str]]
+    ⇒ 6
+
+
+ + +
+ + + + + diff --git a/doc/groff.html.node/Introduction.html b/doc/groff.html.node/Introduction.html new file mode 100644 index 0000000..65499fc --- /dev/null +++ b/doc/groff.html.node/Introduction.html @@ -0,0 +1,68 @@ + + + + + + +Introduction (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

1 Introduction

+ + +

GNU roff (or groff) is a programming system for +typesetting documents. It is highly flexible and has been used +extensively for over thirty years. +

+ + + + +
+ + + + + diff --git a/doc/groff.html.node/Invocation-Examples.html b/doc/groff.html.node/Invocation-Examples.html new file mode 100644 index 0000000..c72781d --- /dev/null +++ b/doc/groff.html.node/Invocation-Examples.html @@ -0,0 +1,120 @@ + + + + + + +Invocation Examples (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

2.6 Invocation Examples

+ + + +

roff systems are best known for formatting man pages. Once a +man librarian program has located a man page, it may execute +a groff command much like the following. +

+
+
groff -t -man -Tutf8 /usr/share/man/man1/groff.1
+
+ +

The librarian will also pipe the output through a pager, which might not +interpret the SGR terminal escape sequences groff emits for +boldface, underlining, or italics; see the grotty(1) man page +for a discussion. +

+

To process a roff input file using the preprocessors +gtbl and gpic and the me macro package in the +way to which AT&T troff users were accustomed, one would type (or +script) a pipeline. +

+
+
gpic foo.me | gtbl | gtroff -me -Tutf8 | grotty
+
+ +

Using groff, this pipe can be shortened to an equivalent +command. +

+
+
groff -p -t -me -T utf8 foo.me
+
+ +

An even easier way to do this is to use grog to guess the +preprocessor and macro options and execute the result by using the +command substitution feature of the shell. +

+
+
$(grog -Tutf8 foo.me)
+
+ +

Each command-line option to a postprocessor must be specified with any +required leading dashes ‘-’ +because groff passes the arguments as-is to the postprocessor; +this permits arbitrary arguments to be transmitted. For example, to +pass a title to the gxditview postprocessor, +the shell commands +

+
+
groff -X -P -title -P 'trial run' mydoc.t
+
+ +

and +

+
+
groff -X -Z mydoc.t | gxditview -title 'trial run' -
+
+ +

are equivalent. +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Invoking-Requests.html b/doc/groff.html.node/Invoking-Requests.html new file mode 100644 index 0000000..1864553 --- /dev/null +++ b/doc/groff.html.node/Invoking-Requests.html @@ -0,0 +1,143 @@ + + + + + + +Invoking Requests (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.6.2 Invoking Requests

+ + + +

A control character is optionally followed by tabs and/or spaces and +then an identifier naming a request or macro. The invocation of an +unrecognized request is interpreted as a macro call. Defining a macro +with the same name as a request replaces the request. Deleting a +request name with the rm request makes it unavailable. The +als request can alias requests, permitting them to be wrapped or +non-destructively replaced. See Strings. +

+ + + + + + + + +

There is no inherent limit on argument length or quantity. Most +requests take one or more arguments, and ignore any they do not expect. +A request may be separated from its arguments by tabs or spaces, but +only spaces can separate an argument from its successor. Only one +between arguments is necessary; any excess is ignored. GNU troff +does not allow tabs for argument separation.43 +

+

Generally, a space within a request argument is not relevant, not +meaningful, or is supported by bespoke provisions, as with the tl +request’s delimiters (see Page Layout). Some requests, like +ds, interpret the remainder of the control line as a single +argument. See Strings. +

+ + + + + +

Spaces and tabs immediately after a control character are ignored. +Commonly, authors structure the source of documents or macro files with +them. +

+
+
.de center
+.  if \\n[.br] \
+.    br
+.  ce \\$1
+..
+.
+.
+.de right-align
+.→if \\n[.br] \
+.→→br
+.→rj \\$1
+..
+
+ + + +

If you assign an empty blank line trap, you can separate macro +definitions (or any input lines) with blank lines. +

+
+
.de do-nothing
+..
+.blm do-nothing  \" activate blank line trap
+
+.de center
+.  if \\n[.br] \
+.    br
+.  ce \\$1
+..
+
+
+.de right-align
+.→if \\n[.br] \
+.→→br
+.→rj \\$1
+..
+
+.blm             \" deactivate blank line trap
+
+ +

See Blank Line Traps. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Invoking-groff.html b/doc/groff.html.node/Invoking-groff.html new file mode 100644 index 0000000..a302025 --- /dev/null +++ b/doc/groff.html.node/Invoking-groff.html @@ -0,0 +1,82 @@ + + + + + + +Invoking groff (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

2 Invoking groff

+ + + +

This chapter focuses on how to invoke the groff front end. This +front end takes care of the details of constructing the pipeline among +the preprocessors, gtroff and the postprocessor. +

+

It has become a tradition that GNU programs get the prefix ‘g’ to +distinguish them from their original counterparts provided by the host +(see Environment). Thus, for example, geqn is GNU +eqn. On operating systems like GNU/Linux or the Hurd, which +don’t contain proprietary versions of troff, and on +MS-DOS/MS-Windows, where troff and associated programs are not +available at all, this prefix is omitted since GNU troff is the +only incarnation of troff used. Exception: ‘groff’ is never +replaced by ‘roff’. +

+

In this document, we consequently say ‘gtroff’ when talking about +the GNU troff program. All other implementations of troff are called AT&T +troff, which is the common origin of almost all troff +implementations4 (with more or less compatible changes). Similarly, we say +‘gpic’, ‘geqn’, and so on. +

+ + + + +
+ + + + + diff --git a/doc/groff.html.node/Italic-Corrections.html b/doc/groff.html.node/Italic-Corrections.html new file mode 100644 index 0000000..42620d8 --- /dev/null +++ b/doc/groff.html.node/Italic-Corrections.html @@ -0,0 +1,96 @@ + + + + + + +Italic Corrections (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.19.9 Italic Corrections

+ +

When typesetting adjacent glyphs from typefaces of different slants, the +space between them may require adjustment. +

+
+
Escape sequence: \/
+
+ + + + + +

Apply an italic correction: modify the spacing of the preceding +glyph so that the distance between it and the following glyph is correct +if the latter is of upright shape. For example, if an +italic ‘f’ is followed immediately by a roman right +parenthesis, then in many fonts the top right portion of +the ‘f’ overlaps the top left of the right parenthesis, which +is ugly. Use this escape sequence whenever an oblique glyph is +immediately followed by an upright glyph without any intervening space. +

+ +
+
Escape sequence: \,
+
+ + + + + +

Apply a left italic correction: modify the spacing of the +following glyph so that the distance between it and the preceding +glyph is correct if the latter is of upright shape. For example, +if a roman left parenthesis is immediately followed by an +italic ‘f’, then in many fonts the bottom left portion of +the ‘f’ overlaps the bottom of the left parenthesis, which is +ugly. Use this escape sequence whenever an upright glyph is followed +immediately by an oblique glyph without any intervening space. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Language-Concepts.html b/doc/groff.html.node/Language-Concepts.html new file mode 100644 index 0000000..16badc5 --- /dev/null +++ b/doc/groff.html.node/Language-Concepts.html @@ -0,0 +1,70 @@ + + + + + + +Language Concepts (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

6.1.1 Language Concepts

+ +

The fundamental operation of the GNU troff formatter is the +translation of the groff input language into a device-independent +form primarily concerned with what has to be written or drawn at +specific positions on the output device. This language is simple and +imperative. In the following discussion, the term command always +refers to this intermediate output language, and never to the +groff language intended for direct use by document authors. +Intermediate output commands comprise several categories: glyph output; +font, color, and text size selection; motion of the printing position; +page advancement; drawing of geometric objects; and device control +commands, a catch-all for operations not easily classified as any of the +foregoing, such as directives to start and stop output, identify the +intended output device, or place URL hyperlinks in supported output +formats. +

+ + +
+ + + + + diff --git a/doc/groff.html.node/Leaders.html b/doc/groff.html.node/Leaders.html new file mode 100644 index 0000000..1a590e8 --- /dev/null +++ b/doc/groff.html.node/Leaders.html @@ -0,0 +1,126 @@ + + + + + + +Leaders (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.12.1 Leaders

+ + +

Sometimes it is desirable to fill a tab stop with a given glyph, +but also use tab stops normally on the same output line. An example is +a table of contents entry that uses dots to bridge the entry name with +its page number, which is itself aligned between tab stops. The +roff language provides leaders for this +purpose.67 +

+ +

A leader character (ISO and EBCDIC code +point 1, also known as SOH or “start of heading”), +behaves similarly to a tab character: it moves to the next tab stop. +The difference is that for this movement, the default fill character is +a period ‘.’. +

+
+
Escape sequence: \a
+
+ + + + + +

Interpolate a leader in copy mode; see Copy Mode. +

+ +
+
Request: .lc [c]
+
+ + + +

Set the leader repetition character to the ordinary or special character +c. Recall Tabs and Leaders: when encountering a leader +character in the input, the formatter writes as many dots ‘.’ as +are necessary until +reaching the next tab stop; this is the leader definition +character. Omitting c unsets the leader +character. With no argument, GNU troff treats leaders the same +as tabs. The leader repetition character is associated with the +environment (see Environments). Only a single c is +recognized; any excess is ignored. +

+ + + +

A table of contents, for example, may define tab stops after a section +number, a title, and a gap to be filled with leader dots. The page +number follows the leader, after a right-aligned final tab stop wide +enough to house the largest page number occurring in the document. +

+
+
.ds entry1 19.\tThe Prophet\a\t98
+.ds entry2 20.\tAll Astir\a\t101
+.ta .5i 4.5i +.5iR
+.nf
+\*[entry1]
+\*[entry2]
+    ⇒ 19.  The Prophet.............................   98
+    ⇒ 20.  All Astir...............................  101
+
+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Leading-Space-Traps.html b/doc/groff.html.node/Leading-Space-Traps.html new file mode 100644 index 0000000..b107793 --- /dev/null +++ b/doc/groff.html.node/Leading-Space-Traps.html @@ -0,0 +1,82 @@ + + + + + + +Leading Space Traps (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.28.4 Leading Space Traps

+ + + +
+
Request: .lsm [name]
+
+
Register: \n[lsn]
+
+
Register: \n[lss]
+
+ +

Set a leading space trap, calling the macro name when GNU +troff encounters leading spaces in an input line; the implicit +line break that normally happens in this case is suppressed. If no +argument is supplied, the default leading space behavior is +(re-)established (see Breaking). +

+

The count of leading spaces on an input line is stored in register +lsn, and the amount of corresponding horizontal motion in +register lss, irrespective of whether a leading space trap is +set. When it is, the leading spaces are removed from the input line, +and no motion is produced before calling name. +

+
+ + +
+ + + + + diff --git a/doc/groff.html.node/Ligatures-and-Kerning.html b/doc/groff.html.node/Ligatures-and-Kerning.html new file mode 100644 index 0000000..b00ed74 --- /dev/null +++ b/doc/groff.html.node/Ligatures-and-Kerning.html @@ -0,0 +1,157 @@ + + + + + + +Ligatures and Kerning (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.19.8 Ligatures and Kerning

+ + + +

Ligatures are groups of characters that are run together, i.e, producing +a single glyph. For example, the letters ‘f’ and ‘i’ can form a +ligature ‘fi’ as in the word ‘file’. This produces a cleaner look +(albeit subtle) to the printed output. Usually, ligatures are not +available in fonts for TTY output devices. +

+

Most PostScript fonts support the fi and fl ligatures. The C/A/T +typesetter that was the target of AT&T troff also +supported ‘ff’, ‘ffi’, and ‘ffl’ ligatures. Advanced typesetters or +‘expert’ fonts may include ligatures for ‘ft’ and ‘ct’, although GNU +troff does not support these (yet). +

+

Only the current font is checked for ligatures and kerns; neither +special fonts nor special charcters defined with the char request +(and its siblings) are taken into account. +

+
+
Request: .lg [flag]
+
+
Register: \n[.lg]
+
+ + + +

Switch the ligature mechanism on or off; if the parameter is non-zero or +missing, ligatures are enabled, otherwise disabled. Default is on. The +current ligature mode can be found in the read-only register .lg +(set to 1 or 2 if ligatures are enabled, 0 otherwise). +

+

Setting the ligature mode to 2 enables the two-character ligatures +(fi, fl, and ff) and disables the three-character ligatures (ffi and +ffl). +

+ +

Pairwise kerning is another subtle typesetting mechanism that +modifies the distance between a glyph pair to improve readability. In +most cases (but not always) the distance is decreased. +Typewriter-like fonts and fonts for terminals where all glyphs have the +same width don’t use kerning. +

+
+
Request: .kern [flag]
+
+
Register: \n[.kern]
+
+ + + +

Switch kerning on or off. If the parameter is non-zero or missing, +enable pairwise kerning, otherwise disable it. The read-only register +.kern is set to 1 if pairwise kerning is enabled, +0 otherwise. +

+ + +

If the font description file contains pairwise kerning information, +glyphs from that font are kerned. Kerning between two glyphs can be +inhibited by placing \& between them: ‘V\&A’. +

+

See Font Description File Format. +

+ + + +

Track kerning expands or reduces the space between glyphs. This +can be handy, for example, if you need to squeeze a long word onto a +single line or spread some text to fill a narrow column. It must be +used with great care since it is usually considered bad typography if +the reader notices the effect. +

+
+
Request: .tkf f s1 n1 s2 n2
+
+ + +

Enable track kerning for font f. If the current font +is f the width of every glyph is increased by an amount +between n1 and n2 (n1, n2 can be negative); if +the current type size is less than or equal to s1 the width is +increased by n1; if it is greater than or equal to s2 the +width is increased by n2; if the type size is greater than or +equal to s1 and less than or equal to s2 the increase in +width is a linear function of the type size. +

+

The default scaling unit is ‘z’ for s1 and s2, ‘p’ +for n1 and n2. +

+

The track kerning amount is added even to the rightmost glyph in a line; +for large values it is thus recommended to increase the line length by +the same amount to compensate. +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Line-Continuation.html b/doc/groff.html.node/Line-Continuation.html new file mode 100644 index 0000000..f818cd9 --- /dev/null +++ b/doc/groff.html.node/Line-Continuation.html @@ -0,0 +1,166 @@ + + + + + + +Line Continuation (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.16 Line Continuation

+ + + +

When filling is enabled, input and output line breaks generally do not +correspond. The roff language therefore distinguishes input and +output line continuation. +

+
+
Escape sequence: \RET
+
+ + + + +

\RET (a backslash immediately followed by a newline) +suppresses the effects of that newline in the input. The next input +line thus retains the classification of its predecessor as a control or +text line. \RET is useful for managing line lengths in the +input during document maintenance; you can break an input line in the +middle of a request invocation, macro call, or escape sequence. Input +line continuation is invisible to the formatter, with two exceptions: +the | operator recognizes the new input line +(see Numeric Expressions), and the input line counter register +.c is incremented. +

+
+
.ll 50n
+.de I
+.  ft I
+.  nop \\$*
+.  ft
+..
+Our film class watched
+.I The Effect of Gamma Rays on Man-in-the-Moon
+Marigolds. \" whoops, the input line wrapped
+.br
+.I My own opus begins on line \n[.c] \
+and ends on line \n[.c].
+
+
+
    ⇒ Our film class watched The Effect of Gamma Rays on
+    ⇒ Man-in-the-Moon Marigolds.
+    ⇒ My own opus begins on line 11 and ends on line 12.
+
+
+ +
+
Escape sequence: \c
+
+
Register: \n[.int]
+
+ + + + + + +

\c continues an output line. Nothing after it on the input line +is formatted. In contrast to \RET, a line after \c +remains a new input line, so a control character is recognized at its +beginning. The visual results depend on whether filling is enabled; see +Manipulating Filling and Adjustment. +

+
    +
  • + + +If filling is enabled, a word interrupted with \c is continued +with the text on the next input text line, without an intervening space. + +
    +
    This is a te\c
    +st.
    +    ⇒ This is a test.
    +
    + +
  • + + +If filling is disabled, the next input text line after \c is +handled as a continuation of the same input text line. + +
    +
    .nf
    +This is a \c
    +test.
    +    ⇒ This is a test.
    +
    +
+ +

An intervening control line that causes a break overrides \c, +flushing out the pending output line in the usual way. +

+ + +

The .int register contains a positive value if the last output +line was continued with \c; this datum is associated with the +environment (see Environments).69 +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Line-Layout.html b/doc/groff.html.node/Line-Layout.html new file mode 100644 index 0000000..4cfed5f --- /dev/null +++ b/doc/groff.html.node/Line-Layout.html @@ -0,0 +1,267 @@ + + + + + + +Line Layout (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.15 Line Layout

+ + + + + +

The following drawing shows the dimensions that gtroff uses for +placing a line of output onto the page. They are labeled with the +request that manipulates each dimension. +

+
+
     -->| in |<--
+        |<-----------ll------------>|
+   +----+----+----------------------+----+
+   |    :    :                      :    |
+   +----+----+----------------------+----+
+-->| po |<--
+   |<--------paper width---------------->|
+
+ +

These dimensions are: +

+
+
po
+
+ + + +

Page offset—this is the leftmost position of text on the final +output, defining the left margin. +

+
+
in
+
+ +

Indentation—this is the distance from the left margin where +text is printed. +

+
+
ll
+
+ +

Line length—this is the distance from the left margin to right +margin. +

+
+ + + +

The right margin is not explicitly configured; the combination of page +offset and line length provides the information necessary to derive it. +

+

A simple demonstration: +

+
+
.ll 3i
+This is text without indentation.
+The line length has been set to 3\~inches.
+.in +.5i
+.ll -.5i
+Now the left and right margins are both increased.
+.in
+.ll
+Calling .in and .ll without parameters restores
+the previous values.
+
+ +
+
    ⇒ This  is text without indenta-
+    ⇒ tion.   The  line  length  has
+    ⇒ been set to 3 inches.
+    ⇒      Now   the  left  and
+    ⇒      right  margins   are
+    ⇒      both increased.
+    ⇒ Calling  .in  and  .ll without
+    ⇒ parameters restores the previ-
+    ⇒ ous values.
+
+ +
+
Request: .po [offset]
+
+
Request: .po +offset
+
Request: .po -offset
+
Register: \n[.o]
+
+ +

Set page offset to offset (or increment or decrement its current +value by offset). If invoked without an argument, the page offset +is restored to the value before the previous po request. +This request does not cause a break; the page offset in effect when an +output line is broken prevails (see Manipulating Filling and Adjustment). The initial value is 1i and the default scaling +unit is ‘m’. On terminal devices, the page offset is set to zero +by a driver-specific macro file, tty.tmac. The current page +offset can be found in the read-only register ‘.o’. + + +This request is incorrectly documented in the AT&T +troff manual as using a default scaling unit of ‘v’. +

+
+
.po 3i
+\n[.o]
+    ⇒ 720
+.po -1i
+\n[.o]
+    ⇒ 480
+.po
+\n[.o]
+    ⇒ 720
+
+
+ +
+
Request: .in [indent]
+
+
Request: .in +indent
+
Request: .in -indent
+
Register: \n[.i]
+
+

Set indentation to indent (or increment or decrement the current +value by indent). This request causes a break. Initially, there +is no indentation. +

+

If in is called without an argument, the indentation is reset to +the previous value before the last call to in. The default +scaling unit is ‘m’. +

+

If a negative indentation value is specified (which is not allowed), +gtroff emits a warning in category ‘range’ and sets the +indentation to zero. +

+

The effect of in is delayed until a partially collected line (if +it exists) is output. A temporary indentation value is reset to zero +also. +

+

The current indentation (as set by in) can be found in the +read-only register ‘.i’. The indentation is associated with the +environment (see Environments). +

+ +
+
Request: .ti offset
+
+
Request: .ti +offset
+
Request: .ti -offset
+
Register: \n[.in]
+
+

Temporarily indent the next output line by offset. If an +increment or decrement value is specified, adjust the temporary +indentation relative to the value set by the in request. +

+

This request causes a break; its value is associated with the +environment (see Environments). The default scaling unit is +‘m’. A call of ti without an argument is ignored. +

+

If the total indentation value is negative (which is not allowed), +gtroff emits a warning in category ‘range’ and sets the +temporary indentation to zero. ‘Total indentation’ is either +offset if specified as an absolute value, or the temporary plus +normal indentation, if offset is given as a relative value. +

+

The effect of ti is delayed until a partially collected line (if +it exists) is output. +

+

The read-only register .in is the indentation that applies to the +current output line. +

+

The difference between .i and .in is that the latter takes +into account whether a partially collected line still uses the old +indentation value or a temporary indentation value is active. +

+ +
+
Request: .ll [length]
+
+
Request: .ll +length
+
Request: .ll -length
+
Register: \n[.l]
+
+
Register: \n[.ll]
+
+

Set the line length to length (or increment or decrement the +current value by length). Initially, the line length is set to +6.5i. The effect of ll is delayed until a partially +collected line (if it exists) is output. The default scaling unit is +‘m’. +

+

If ll is called without an argument, the line length is reset to +the previous value before the last call to ll. If a negative +line length is specified (which is not allowed), gtroff emits a +warning in category ‘range’ and sets the line length to zero. The +line length is associated with the environment (see Environments). +

+ +

The current line length (as set by ll) can be found in the +read-only register ‘.l’. The read-only register .ll is the +line length that applies to the current output line. +

+

Similar to .i and .in, the difference between .l +and .ll is that the latter takes into account whether a partially +collected line still uses the old line length value. +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Lists-in-ms.html b/doc/groff.html.node/Lists-in-ms.html new file mode 100644 index 0000000..bde2b7c --- /dev/null +++ b/doc/groff.html.node/Lists-in-ms.html @@ -0,0 +1,216 @@ + + + + + + +Lists in ms (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.5.6 Lists

+ + +

The marker argument to the IP macro can be employed to +present a variety of lists; for instance, you can use a bullet glyph +(\[bu]) for unordered lists, a number (or auto-incrementing +register) for numbered lists, or a word or phrase for glossary-style or +definition lists. If you set the paragraph indentation register +PI before calling IP, you can later reorder the items in +the list without having to ensure that a width argument remains +affixed to the first call. +

+

The following is an example of a bulleted list. + + +

+
+
+
.nr PI 2n
+A bulleted list:
+.IP \[bu]
+lawyers
+.IP \[bu]
+guns
+.IP \[bu]
+money
+
+
+ +
+
A bulleted list:
+
+• lawyers
+
+• guns
+
+• money
+
+ +

The following is an example of a numbered list. + + +

+
+
+
.nr step 0 1
+.nr PI 3n
+A numbered list:
+.IP \n+[step]
+lawyers
+.IP \n+[step]
+guns
+.IP \n+[step]
+money
+
+
+ +
+
A numbered list:
+
+1. lawyers
+
+2. guns
+
+3. money
+
+ +

Here we have employed the nr request to create a register of our +own, ‘step’. We initialized it to zero and assigned it an +auto-increment of 1. Each time we use the escape sequence +‘\n+[PI]’ (note the plus sign), the formatter applies the increment +just before interpolating the register’s value. Preparing the PI +register as well enables us to rearrange the list without the tedium of +updating macro calls. +

+

The next example illustrates a glossary-style list. + + +

+
+
+
A glossary-style list:
+.IP lawyers 0.4i
+Two or more attorneys.
+.IP guns
+Firearms,
+preferably large-caliber.
+.IP money
+Gotta pay for those
+lawyers and guns!
+
+
+ +
+
A glossary-style list:
+
+lawyers
+      Two or more attorneys.
+
+guns  Firearms, preferably large-caliber.
+
+money
+      Gotta pay for those lawyers and guns!
+
+ +

In the previous example, observe how the IP macro places the +definition on the same line as the term if it has enough space. If this +is not what you want, there are a few workarounds we will illustrate by +modifying the example. First, you can use a br request to force +a break after printing the term or label. +

+
+
+
.IP guns
+.br
+Firearms,
+
+
+ +

Second, you could apply the \p escape sequence to force a break. +The space following the escape sequence is important; if you omit it, +groff prints the first word of the paragraph text on the same +line as the term or label (if it fits) then breaks the line. +

+
+
+
.IP guns
+\p Firearms,
+
+
+ +

Finally, you may append a horizontal motion to the marker with the +\h escape sequence; using the same amount as the indentation will +ensure that the marker is too wide for groff to treat it as +“fitting” on the same line as the paragraph text. +

+
+
+
.IP guns\h'0.4i'
+Firearms,
+
+
+ +

In each case, the result is the same. +

+
+
A glossary-style list:
+
+lawyers
+      Two or more attorneys.
+
+guns
+      Firearms, preferably large-caliber.
+
+money
+      Gotta pay for those lawyers and guns!
+
+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Macro-Directories.html b/doc/groff.html.node/Macro-Directories.html new file mode 100644 index 0000000..c1557bd --- /dev/null +++ b/doc/groff.html.node/Macro-Directories.html @@ -0,0 +1,125 @@ + + + + + + +Macro Directories (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

2.3 Macro Directories

+ + + + + +

A macro file must have a name in the form name.tmac or +tmac.name and be placed in a tmac directory to be +found by the -mname command-line option.5 + + + + + + + + + + +Together, these directories constitute the tmac path. Each +directory is searched in the following order until the desired macro +file is found or the list is exhausted. +

+
    +
  • Directories specified with GNU troff’s or groff’s +-M command-line option. + +
  • +Directories listed in the GROFF_TMAC_PATH environment variable. + +
  • + + + + + +The current working directory (only if in unsafe mode using the +-U command-line option). + +
  • + +The user’s home directory, HOME. + +
  • + + + +A platform-dependent directory, a site-local (platform-independent) +directory, and the main tmac directory. The locations +corresponding to your installation are listed in section “Environment” +of gtroff(1). If not otherwise configured, they are as +follows. + +
    +
    /usr/local/lib/groff/site-tmac
    +/usr/local/share/groff/site-tmac
    +/usr/local/share/groff/1.23.0/tmac
    +
    + +

    The foregoing assumes that the version of groff is 1.23.0, and +that the installation prefix was /usr/local. It is possible to +fine-tune these locations during the source configuration process. +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Macro-Index.html b/doc/groff.html.node/Macro-Index.html new file mode 100644 index 0000000..c727a85 --- /dev/null +++ b/doc/groff.html.node/Macro-Index.html @@ -0,0 +1,335 @@ + + + + + + +Macro Index (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

Appendix F Macro Index

+ +

The macro package a specific macro belongs to is appended in brackets. +They appear without the leading control character (normally ‘.’). +

+
+
Jump to:   1 +   +2 +   +[ +   +] +   +
+A +   +B +   +C +   +D +   +E +   +F +   +G +   +H +   +I +   +K +   +L +   +M +   +N +   +O +   +P +   +Q +   +R +   +S +   +T +   +U +   +V +   +X +   +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

1
1C [ms]: ms Multiple Columns

2
2C [ms]: ms Multiple Columns

[
[ [ms]: ms Insertions

]
] [ms]: ms Insertions

A
AB [ms]: ms Document Description Macros
AE [ms]: ms Document Description Macros
AI [ms]: ms Document Description Macros
AM [ms]: ms Legacy Features
AU [ms]: ms Document Description Macros

B
B [ms]: Typeface and decoration
B1 [ms]: ms keeps and displays
B2 [ms]: ms keeps and displays
BD [ms]: ms keeps and displays
BI [ms]: Typeface and decoration
BT [man]: Optional man extensions
BX [ms]: Typeface and decoration

C
CD [ms]: ms keeps and displays
CT [man]: Optional man extensions
CW [man]: Optional man extensions
CW [ms]: Typeface and decoration

D
DA [ms]: ms Document Description Macros
De [man]: Optional man extensions
DE [ms]: ms keeps and displays
Ds [man]: Optional man extensions
DS [ms]: ms keeps and displays
DS [ms]: ms keeps and displays
DS [ms]: ms keeps and displays
DS [ms]: ms keeps and displays
DS [ms]: ms keeps and displays

E
EE [man]: Optional man extensions
EF [ms]: ms Headers and Footers
EH [ms]: ms Headers and Footers
EN [ms]: ms Insertions
EQ [ms]: ms Insertions
EX [man]: Optional man extensions

F
FE [ms]: ms Footnotes
FS [ms]: ms Footnotes

G
G [man]: Optional man extensions
GL [man]: Optional man extensions

H
HB [man]: Optional man extensions

I
I [ms]: Typeface and decoration
ID [ms]: ms keeps and displays
IP [ms]: Paragraphs in ms

K
KE [ms]: ms keeps and displays
KF [ms]: ms keeps and displays
KS [ms]: ms keeps and displays

L
LD [ms]: ms keeps and displays
LG [ms]: Typeface and decoration
LP [ms]: Paragraphs in ms

M
MC [ms]: ms Multiple Columns
MS [man]: Optional man extensions

N
ND [ms]: ms Document Description Macros
NE [man]: Optional man extensions
NH [ms]: Headings in ms
NL [ms]: Typeface and decoration
NT [man]: Optional man extensions

O
OF [ms]: ms Headers and Footers
OH [ms]: ms Headers and Footers

P
P1 [ms]: ms Headers and Footers
PE [ms]: ms Insertions
PF [ms]: ms Insertions
PN [man]: Optional man extensions
Pn [man]: Optional man extensions
PP [ms]: Paragraphs in ms
PS [ms]: ms Insertions
PT [man]: Optional man extensions
PX [ms]: ms TOC

Q
QE [ms]: Paragraphs in ms
QP [ms]: Paragraphs in ms
QS [ms]: Paragraphs in ms

R
R [man]: Optional man extensions
R [ms]: Typeface and decoration
RD [ms]: ms keeps and displays
RE [ms]: Indented regions in ms
RN [man]: Optional man extensions
RP [ms]: ms Document Description Macros
RS [ms]: Indented regions in ms

S
SH [ms]: Headings in ms
SM [ms]: Typeface and decoration

T
TA [ms]: Tab Stops in ms
TB [man]: Optional man extensions
TC [ms]: ms TOC
TE [ms]: ms Insertions
TL [ms]: ms Document Description Macros
TS [ms]: ms Insertions

U
UL [ms]: Typeface and decoration

V
VE [man]: Optional man extensions
VS [man]: Optional man extensions

X
XA [ms]: ms TOC
XE [ms]: ms TOC
XH [ms]: ms TOC
XH-REPLACEMENT [ms]: ms TOC
XH-UPDATE-TOC [ms]: ms TOC
XN [ms]: ms TOC
XN-INIT [ms]: ms TOC
XN-REPLACEMENT [ms]: ms TOC
XP [ms]: Paragraphs in ms
XS [ms]: ms TOC

+ +
+ + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Macro-Package-Intro.html b/doc/groff.html.node/Macro-Package-Intro.html new file mode 100644 index 0000000..77f2036 --- /dev/null +++ b/doc/groff.html.node/Macro-Package-Intro.html @@ -0,0 +1,63 @@ + + + + + + +Macro Package Intro (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

1.4 Macro Packages

+ + + +

Elemental typesetting functions can be be challenging to use directly +with complex documents. A macro facility specifies how certain +routine operations, such as starting paragraphs, or printing headers and +footers, should be performed in terms of those low-level instructions. +Macros can be specific to one document or collected together into a +macro package for use by many. Several macro packages available; +the most widely used are provided with groff. They are +man, mdoc, me, mm, mom, and +ms. +

+ + +
+ + + + + diff --git a/doc/groff.html.node/Macro-Packages.html b/doc/groff.html.node/Macro-Packages.html new file mode 100644 index 0000000..762ea31 --- /dev/null +++ b/doc/groff.html.node/Macro-Packages.html @@ -0,0 +1,64 @@ + + + + + + +Macro Packages (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.1.8 Macro Packages

+ + + +

Macro definitions can be collected into macro files, roff +input files designed to produce no output themselves but instead ease +the preparation of other roff documents. There is no syntactical +difference between a macro file and any other roff document; only +its purpose distinguishes it. When a macro file is installed at a +standard location and suitable for use by a general audience, it is +often termed a macro package.29 Macro packages can be +loaded by supplying the -m option to GNU troff or a +groff front end. Alternatively, a document requiring a macro +package can load it with the mso (“macro source”) request. +

+ + +
+ + + + + diff --git a/doc/groff.html.node/Major-Macro-Packages.html b/doc/groff.html.node/Major-Macro-Packages.html new file mode 100644 index 0000000..414994f --- /dev/null +++ b/doc/groff.html.node/Major-Macro-Packages.html @@ -0,0 +1,103 @@ + + + + + + +Major Macro Packages (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4 Macro Packages

+ + + + +

This chapter surveys the “major” macro packages that come with +groff. One, ms, is presented in detail. +

+ + + +

Major macro packages are also sometimes described as full-service +due to the breadth of features they provide and because more than one +cannot be used by the same document; for example +

+
+
groff -m man foo.man -m ms bar.doc
+
+ +

doesn’t work. Option arguments are processed before non-option +arguments; the above (failing) sample is thus reordered to +

+
+
groff -m man -m ms foo.man bar.doc
+
+ + + + + + + +

Many auxiliary, or “minor”, macro packages are also available. They +may in general be used with any full-service macro package and handle a +variety of tasks from character encoding selection, to language +localization, to inlining of raster images. See the +groff_tmac(5) man page for a list. Type ‘man +groff_tmac’ at the command line to view it. +

+ + + + +
+ + + + + diff --git a/doc/groff.html.node/Manipulating-Filling-and-Adjustment.html b/doc/groff.html.node/Manipulating-Filling-and-Adjustment.html new file mode 100644 index 0000000..632aade --- /dev/null +++ b/doc/groff.html.node/Manipulating-Filling-and-Adjustment.html @@ -0,0 +1,501 @@ + + + + + + +Manipulating Filling and Adjustment (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.9 Manipulating Filling and Adjustment

+ + + + + + + + + + + + + + + + + + + +

When an output line is pending (see below), a break moves the drawing +position to the beginning of the next text baseline, interrupting +filling. Various ways of causing breaks were shown in Breaking. +The br request likewise causes a break. Several other requests +imply breaks: bp, ce, cf, fi, fl, +in, nf, rj, sp, ti, and trf. +If the no-break control character is used with any of these requests, +GNU troff suppresses the break; instead the requested operation +takes effect at the next break. ‘'br’ does nothing. +

+
+
.ll 55n
+This line is normally filled and adjusted.
+.br
+A line's alignment is decided
+'ce \" Center the next input line (no break).
+when it is output.
+This line returns to normal filling and adjustment.
+    ⇒ This line is normally filled and adjusted.
+    ⇒    A line's alignment is decided when it is output.
+    ⇒ This line returns to normal filling and adjustment.
+
+ + + + + +

Output line properties like page offset, indentation, adjustment, and +even the location of its text baseline, are not determined until the +line has been broken. An output line is said to be pending if +some input has been collected but an output line corresponding to it has +not yet been written; such an output line is also termed partially +collected. If no output line is pending, it is as if a break has +already happened; additional breaks, whether explicit or implicit, have +no effect. If the vertical drawing position is negative—as it is when +the formatter starts up—a break starts a new page (even if no output +line is pending) unless an end-of-input macro is being interpreted. +See End-of-input Traps. +

+
+
Request: .br
+
+

Break the line: emit any pending output line without adjustment. +

+
+
foo bar
+.br
+baz
+'br
+qux
+    ⇒ foo bar
+    ⇒ baz qux
+
+
+ +

Sometimes you want to prevent a break within a phrase or between a +quantity and its units. +

+
+
Escape sequence: \~
+
+ + +

Insert an unbreakable space that is adjustable like an ordinary space. +It is discarded from the end of an output line if a break is forced. +

+
+
Set the output speed to\~1.
+There are 1,024\~bytes in 1\~KiB.
+J.\~F.\~Ossanna wrote the original CSTR\~#54.
+
+
+ +

By default, GNU troff fills text and adjusts it to reach the +output line length. The nf request disables filling; the +fi request reënables it. +

+
+
Request: .fi
+
+
Register: \n[.u]
+
+ + + + +

Enable filling of output lines; a pending output line is broken. The +read-only register .u is set to 1. The filling enablement +status, sometimes called fill mode, is associated with the +environment (see Environments). See Line Continuation, for +interaction with the \c escape sequence. +

+ +
+
Request: .nf
+
+ + + + + + +

Disable filling of output lines: the output line length (see Line Layout) is ignored and output lines are broken where the input lines +are. A pending output line is broken and adjustment is suppressed. The +read-only register .u is set to 0. The filling enablement +status is associated with the environment (see Environments). See +Line Continuation, for interaction with the \c escape +sequence. +

+ +
+
Request: .ad [mode]
+
+
Register: \n[.j]
+
+

Enable output line adjustment in mode, taking effect when the +pending (or next) output line is broken. Adjustment is suppressed when +filling is. mode can have one of the following values. +

+
+
b
+
n
+

Adjust “normally”: if the output line does not consume the distance +between the indentation and the configured output line length, GNU +troff stretches adjustable spaces within the line until that +length is reached. When the indentation is zero, this mode spreads the +line to both the left and right margins. This is the GNU troff +default. +

+
+
c
+

Center filled text. Contrast with the ce request, which centers +text without filling it. +

+
+
l
+

Align text to the left without adjusting it. +

+
+
r
+

Align text to the right without adjusting it. +

+
+ +

mode can also be a value previously stored in the .j +register. Using ad without an argument is the same as ‘.ad +\n[.j]’; unless filling is disabled, GNU troff resumes adjusting +lines in the same way it did before adjustment was disabled by +invocation of the na request. +

+ +

The adjustment mode and enablement status are encoded in the read-only +register .j. These parameters are associated with the +environment (see Environments). +

+

The value of .j for any adjustment mode is an implementation +detail and should not be relied upon as a programmer’s interface. Do +not write logic to interpret or perform arithmetic on it. +

+
+
.ll 48n
+.de AD
+.  br
+.  ad \\$1
+..
+.de NA
+.  br
+.  na
+..
+left
+.AD r
+.nr ad \n(.j
+right
+.AD c
+center
+.NA
+left
+.AD
+center
+.AD \n(ad
+right
+
+
+
    ⇒ left
+    ⇒                                            right
+    ⇒                      center
+    ⇒ left
+    ⇒                      center
+    ⇒                                            right
+
+
+ +
+
Request: .na
+
+

Disable output line adjustment. This produces the same output as +left-alignment, but the value of the adjustment mode register .j +is altered differently. The adjustment mode and enablement status are +associated with the environment (see Environments). +

+ +
+
Request: .brp
+
+
Escape sequence: \p
+
+

Break, adjusting the line per the current adjustment mode. \p +schedules a break with adjustment at the next word boundary. The escape +sequence is itself neither a break nor a space of any kind; it can thus +be placed in the middle of a word to cause a break at the end of that +word. +

+

Breaking with immediate adjustment can produce ugly results since GNU +troff doesn’t have a sophisticated paragraph-building algorithm, +as TeX has, for example. Instead, GNU troff fills and adjusts +a paragraph line by line. +

+
+
.ll 4.5i
+This is an uninteresting sentence.
+This is an uninteresting sentence.\p
+This is an uninteresting sentence.
+
+ +

is formatted as follows. +

+
+
This  is  an uninteresting sentence.  This is
+an          uninteresting           sentence.
+This is an uninteresting sentence.
+
+
+ + + + +

To clearly present the next couple of requests, we must introduce the +concept of “productive” input lines. A productive input line is +one that directly produces formatted output. Text lines produce +output,53 as do control +lines containing requests like tl or escape sequences like +\D. Macro calls are not directly productive, and thus not +counted, but their interpolated contents can be. Empty requests, and +requests and escape sequences that define registers or strings or alter +the formatting environment (as with changes to the size, face, height, +slant, or color of the type) are not productive. We will also preview +the output line continuation escape sequence, \c, which +“connects” two input lines that would otherwise be counted separately. +54 +

+
+
.de hello
+Hello, world!
+..
+.ce \" center output of next productive input line
+.
+.nr junk-reg 1
+.ft I
+Chorus: \c
+.ft
+.hello
+Went the day well?
+  ⇒                  Chorus: Hello, world!
+  ⇒ Went the day well?
+
+ +
+
Request: .ce [n]
+
+
Register: \n[.ce]
+
+ + + +

Break (unless the no-break control character is used), center the output +of the next n productive input lines with respect to the line +length and indentation without filling, then break again regardless of +the invoking control character. +If the argument is not positive, centering is disabled. Omitting the +argument implies an n of ‘1’. The count of lines remaining +to be centered is stored in the read-only register .ce and is +associated with the environment (see Environments). +

+ +

While the ‘.ad c request also centers text, it fills the text +as well. +

+
+
.de FR
+This is a small text fragment that shows the differences
+between the `.ce' and the `.ad c' requests.
+..
+.ll 4i
+.ce 1000
+.FR
+.ce 0
+
+.ad c
+.FR
+    ⇒ This is a small text fragment that shows
+    ⇒              the differences
+    ⇒ between the ‘.ce’ and the ‘.ad c’ requests.
+    ⇒
+    ⇒ This is a small text fragment that shows
+    ⇒  the differences between the ‘.ce’ and
+    ⇒         the ‘.ad c’ requests.
+
+ +

The previous example illustrates a common idiom of turning centering on +for a quantity of lines far in excess of what is required, and off again +after the text to be centered. This technique relieves humans of +counting lines for requests that take a count of input lines as an +argument. +

+ +
+
Request: .rj [n]
+
+
Register: \n[.rj]
+
+ + + +

Break (unless the no-break control character is used), align the output +of the next n productive input lines to the right margin without +filling, then break again regardless of the control character. +If the argument is not positive, right-alignment is disabled. Omitting +the argument implies an n of ‘1’. The count of lines +remaining to be right-aligned is stored in the read-only register +.rj and is associated with the environment +(see Environments). +

+
+
.ll 49n
+.rj 3
+At first I hoped that such a technically unsound
+project would collapse but I soon realized it was
+doomed to success. \[em] C. A. R. Hoare
+    ⇒  At first I hoped that such a technically unsound
+    ⇒ project would collapse but I soon realized it was
+    ⇒              doomed to success. -- C. A. R. Hoare
+
+
+ +
+
Request: .ss word-space-size [additional-sentence-space-size]
+
+
Register: \n[.ss]
+
+
Register: \n[.sss]
+
+ + + + + + + +

Set the sizes of spaces between words and +sentences55 in twelfths +of font’s space width (typically one-fourth to one-third em for Western +scripts). The default for both parameters is 12. Negative values +are erroneous. + + + +The first argument is a minimum; if an output line undergoes adjustment, +such spaces may increase in width. + + + +The optional second argument sets the amount of additional space +separating sentences on the same output line. If omitted, this amount +is set to word-space-size. The request is ignored if there are no +parameters. +

+ + +

Additional inter-sentence space is used only if the output line is not +full when the end of a sentence occurs in the input. If a sentence ends +at the end of an input line, then both an inter-word space and an +inter-sentence space are added to the output; if two spaces follow the +end of a sentence in the middle of an input line, then the second space +becomes an inter-sentence space in the output. Additional +inter-sentence space is not adjusted, but the inter-word space that +always precedes it may be. Further input spaces after the second, if +present, are adjusted as normal. +

+

The read-only registers .ss and .sss hold the minimal +inter-word space and additional inter-sentence space amounts, +respectively. These parameters are part of the environment +(see Environments), and rounded down to the nearest multiple +of 12 on terminals. +

+ + + +

The ss request can insert discardable horizontal space; that is, +space that is discarded at a break. For example, some footnote styles +collect the notes into a single paragraph with large gaps between +each note. +

+
+
.ll 48n
+1.\~J. Fict. Ch. Soc. 6 (2020), 3\[en]14.
+.ss 12 48 \" applies to next sentence ending
+Reprints no longer available through FCS.
+.ss 12 \" go back to normal
+2.\~Better known for other work.
+    ⇒ 1.  J.  Fict. Ch. Soc. 6 (2020), 3-14.  Reprints
+    ⇒ no longer available through FCS.      2.  Better
+    ⇒ known for other work.
+
+ +

If undiscardable space is required, use the \h escape +sequence. +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Manipulating-Hyphenation.html b/doc/groff.html.node/Manipulating-Hyphenation.html new file mode 100644 index 0000000..6d88ea8 --- /dev/null +++ b/doc/groff.html.node/Manipulating-Hyphenation.html @@ -0,0 +1,580 @@ + + + + + + +Manipulating Hyphenation (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.10 Manipulating Hyphenation

+ + + + + +

When filling, GNU troff hyphenates words as needed at +user-specified and automatically determined hyphenation points. The +machine-driven determination of hyphenation points in words requires +algorithms and data, and is susceptible to conventions and preferences. +Before tackling such automatic hyphenation, let us consider how +hyphenation points can be set explicitly. +

+ + + + +

Explicitly hyphenated words such as “mother-in-law” are eligible for +breaking after each of their hyphens. Relatively few words in a +language offer such obvious break points, however, and automatic +detection of syllabic (or phonetic) boundaries for hyphenation is not +perfect,56 particularly for +unusual words found in technical literature. We can instruct GNU +troff how to hyphenate specific words if the need arises. +

+ +
+
Request: .hw word …
+
+

Define each hyphenation exception word with each hyphen ‘-’ +in the word indicating a hyphenation point. For example, the request +

+
+
.hw in-sa-lub-rious alpha
+
+ +

marks potential hyphenation points in “insalubrious”, and prevents +“alpha” from being hyphenated at all. +

+

Besides the space character, any character whose hyphenation code is +zero can be used to separate the arguments of hw (see the +hcode request below). In addition, this request can be used more +than once. +

+ +

Hyphenation points specified with hw are not subject to the +within-word placement restrictions imposed by the hy request (see +below). +

+

Hyphenation exceptions specified with the hw request are +associated with the hyphenation language (see the hla request +below) and environment (see Environments); invoking the hw +request in the absence of a hyphenation language is an error. +

+

The request is ignored if there are no parameters. +

+ +

These are known as hyphenation exceptions in the expectation +that most users will avail themselves of automatic hyphenation; these +exceptions override any rules that would normally apply to a word +matching a hyphenation exception defined with hw. +

+

Situations also arise when only a specific occurrence of a word needs +its hyphenation altered or suppressed, or when a URL or similar string +needs to be breakable in sensible places without hyphenation. +

+
+
Escape sequence: \%
+
+
Escape sequence: \:
+
+ + + + +

To tell GNU troff how to hyphenate words as they occur in input, +use the \% escape sequence; it is the default hyphenation +character. Each instance within a word indicates to GNU troff +that the word may be hyphenated at that point, while prefixing a word +with this escape sequence prevents it from being otherwise hyphenated. +This mechanism affects only that occurrence of the word; to change the +hyphenation of a word for the remainder of input processing, use the +hw request. +

+ + + +

GNU troff regards the escape sequences \X and \Y as +starting a word; that is, the \% escape sequence in, say, +‘\X'...'\%foobar or ‘\Y'...'\%foobar no longer +prevents hyphenation of ‘foobar’ but inserts a hyphenation point +just prior to it; most likely this isn’t what you want. +See Postprocessor Access. +

+ + + + + + +

\: inserts a non-printing break point; that is, a word can break +there, but the soft hyphen glyph (see below) is not written to the +output if it does. This escape sequence is an input word boundary, so +the remainder of the word is subject to hyphenation as normal. +

+

You can combine \: and \% to control breaking of a file +name or URL, or to permit hyphenation only after certain explicit +hyphens within a word. +

+
+
The \%Lethbridge-Stewart-\:\%Sackville-Baggins divorce
+was, in retrospect, inevitable once the contents of
+\%/var/log/\:\%httpd/\:\%access_log on the family web
+server came to light, revealing visitors from Hogwarts.
+
+
+ +
+
Request: .hc [char]
+
+

Change the hyphenation character to char. This character then +works as the \% escape sequence normally does, and thus no longer +appears in the output.57 Without an +argument, hc resets the hyphenation character to \% (the +default). The hyphenation character is associated with the environment +(see Environments). +

+ +
+
Request: .shc [c]
+
+ + + + + + +

Set the soft hyphen character, inserted when a word is hyphenated +automatically or at a hyphenation character, to the ordinary or special +character c.58 If the argument is omitted, the soft +hyphen character is set to the default, \[hy]. If no glyph for +c exists in the font in use at a potential hyphenation point, then +the line is not broken there. Neither character definitions (specified +with the char and similar requests) nor translations (specified +with the tr request) are applied to c. +

+ + + +

Several requests influence automatic hyphenation. Because conventions +vary, a variety of hyphenation modes is available to the hy +request; these determine whether hyphenation will apply to a +word prior to breaking a line at the end of a page (more or less; see +below for details), and at which positions within that word +automatically determined hyphenation points are permissible. The places +within a word that are eligible for hyphenation are determined by +language-specific data and lettercase relationships. Furthermore, +hyphenation of a word might be suppressed due to a limit on +consecutive hyphenated lines (hlm), a minimum line length +threshold (hym), or because the line can instead be adjusted with +additional inter-word space (hys). +

+ +
+
Request: .hy [mode]
+
+
Register: \n[.hy]
+
+

Set automatic hyphenation mode to mode, an integer encoding +conditions for hyphenation; if omitted, ‘1’ is implied. The +hyphenation mode is available in the read-only register ‘.hy’; it +is associated with the environment (see Environments). The default +hyphenation mode depends on the localization file loaded when GNU +troff starts up; see the hpf request below. +

+

Typesetting practice generally does not avail itself of every +opportunity for hyphenation, but the details differ by language and site +mandates. The hyphenation modes of AT&T troff were +implemented with English-language publishing practices of the 1970s in +mind, not a scrupulous enumeration of conceivable parameters. GNU +troff extends those modes such that finer-grained control is +possible, favoring compatibility with older implementations over a more +intuitive arrangement. The means of hyphenation mode control is a set +of numbers that can be added up to encode the behavior +sought.59 The entries in the +following table are termed values; the sum of the desired +values is the mode. +

+
+
0
+

disables hyphenation. +

+
+
1
+

enables hyphenation except after the first and before the last character +of a word. +

+
+ +

The remaining values “imply” 1; that is, they enable hyphenation +under the same conditions as ‘.hy 1’, and then apply or lift +restrictions relative to that basis. +

+
+
2
+

disables hyphenation of the last word on a page,60 even for explicitly hyphenated words. +

+
+
4
+

disables hyphenation before the last two characters of a word. +

+
+
8
+

disables hyphenation after the first two characters of a word. +

+
+
16
+

enables hyphenation before the last character of a word. +

+
+
32
+

enables hyphenation after the first character of a word. +

+
+ +

Apart from value 2, restrictions imposed by the hyphenation mode +are not respected for words whose hyphenations have been +specified with the hyphenation character (‘\%’ by default) or the +hw request. +

+

Nonzero values in the previous table are additive. For example, +mode 12 causes GNU troff to hyphenate neither the last two +nor the first two characters of a word. Some values cannot be used +together because they contradict; for instance, values 4 and 16, +and values 8 and 32. As noted, it is superfluous to add 1 to any +non-zero even mode. +

+ + +

The automatic placement of hyphens in words is determined by +pattern files, which are derived from TeX and available for +several languages. The number of characters at the beginning of a word +after which the first hyphenation point should be inserted is determined +by the patterns themselves; it can’t be reduced further without +introducing additional, invalid hyphenation points (unfortunately, this +information is not part of a pattern file—you have to know it in +advance). The same is true for the number of characters at the end of +a word before the last hyphenation point should be inserted. For +example, you can supply the following input to ‘echo $(nroff)’. +

+
+
.ll 1
+.hy 48
+splitting
+
+ +

You will get +

+
+
s- plit- t- in- g
+
+ +

instead of the correct ‘split- ting’. English patterns as distributed +with GNU troff need two characters at the beginning and three +characters at the end; this means that value 4 of hy is +mandatory. Value 8 is possible as an additional restriction, but +values 16 and 32 should be avoided, as should mode 1. +Modes 4 and 6 are typical. +

+

A table of left and right minimum character counts for hyphenation as +needed by the patterns distributed with GNU troff follows; see +the groff_tmac(5) man page for more information on GNU +troff’s language macro files. +

+ + + + + + + + + + +
languagepattern nameleft minright min
Czechcs22
Englishen23
Frenchfr23
German traditionaldet22
German reformedden22
Italianit22
Swedishsv12
+ +

Hyphenation exceptions within pattern files (i.e., the words within a +TeX \hyphenation group) obey the hyphenation restrictions +given by hy. +

+ +
+
Request: .nh
+
+

Disable automatic hyphenation; i.e., set the hyphenation mode to 0 +(see above). The hyphenation mode of the last call to hy is not +remembered. +

+ +
+
Request: .hpf pattern-file
+
+
Request: .hpfa pattern-file
+
+
Request: .hpfcode a b [c d] …
+
+ + +

Read hyphenation patterns from pattern-file, which is sought +in the same way that macro files are with the mso request or the +-mname command-line option to groff. The +pattern-file should have the same format as (simple) TeX +pattern files. More specifically, the following scanning rules are +implemented. +

+
    +
  • A percent sign starts a comment (up to the end of the line) even if +preceded by a backslash. + +
  • “Digraphs” like \$ are not supported. + +
  • ^^xx (where each x is 0–9 or a–f) and +^^c (character c in the code point range 0–127 +decimal) are recognized; other uses of ^ cause an error. + +
  • No macro expansion is performed. + +
  • hpf checks for the expression \patterns{…} +(possibly with whitespace before or after the braces). Everything +between the braces is taken as hyphenation patterns. Consequently, +{ and } are not allowed in patterns. + +
  • Similarly, \hyphenation{…} gives a list of hyphenation +exceptions. + +
  • \endinput is recognized also. + +
  • For backward compatibility, if \patterns is missing, the whole +file is treated as a list of hyphenation patterns (except that the +% character is recognized as the start of a comment). +
+ +

The hpfa request appends a file of patterns to the current list. +

+

The hpfcode request defines mapping values for character codes in +pattern files. It is an older mechanism no longer used by GNU +troff’s own macro files; for its successor, see hcode +below. hpf or hpfa apply the mapping after reading the +patterns but before replacing or appending to the active list of +patterns. Its arguments are pairs of character codes—integers from 0 +to 255. The request maps character code a to +code b, code c to code d, and so on. +Character codes that would otherwise be invalid in GNU troff can +be used. By default, every code maps to itself except those for letters +‘A’ to ‘Z’, which map to those for ‘a’ to ‘z’. +

+ + + + + + + + + + +

The set of hyphenation patterns is associated with the language set by +the hla request (see below). The hpf request is usually +invoked by a localization file loaded by the troffrc +file.61 +

+

A second call to hpf (for the same language) replaces the +hyphenation patterns with the new ones. Invoking hpf or +hpfa causes an error if there is no hyphenation language. If no +hpf request is specified (either in the document, in a file +loaded at startup, or in a macro package), GNU troff won’t +automatically hyphenate at all. +

+ +
+
Request: .hcode c1 code1 [c2 code2] …
+
+ + +

Set the hyphenation code of character c1 to code1, that of +c2 to code2, and so on. A hyphenation code must be an +ordinary character (not a special character escape sequence) other than +a digit or a space. The request is ignored if given no arguments. +

+

For hyphenation to work, hyphenation codes must be set up. At +startup, GNU troff assigns hyphenation codes to the letters +‘a’–‘z’ (mapped to themselves), to the letters +‘A’–‘Z’ (mapped to ‘a’–‘z’), and zero to all other +characters. Normally, hyphenation patterns contain only lowercase +letters which should be applied regardless of case. In other words, +they assume that the words ‘FOO’ and ‘Foo’ should be hyphenated exactly +as ‘foo’ is. The hcode request extends this principle to letters +outside the Unicode basic Latin alphabet; without it, words containing +such letters won’t be hyphenated properly even if the corresponding +hyphenation patterns contain them. +

+

For example, the following hcode requests are necessary to assign +hyphenation codes to the letters ‘ÄäÖöÜüß’, needed for German. +

+
+
.hcode ä ä  Ä ä
+.hcode ö ö  Ö ö
+.hcode ü ü  Ü ü
+.hcode ß ß
+
+ +

Without these assignments, GNU troff treats the German word +‘Kindergärten’ (the plural form of ‘kindergarten’) as two words +‘kinderg’ and ‘rten’ because the hyphenation code of the +umlaut a is zero by default, just like a space. There is a German +hyphenation pattern that covers ‘kinder’, so GNU troff finds +the hyphenation ‘kin-der’. The other two hyphenation points +(‘kin-der-gär-ten’) are missed. +

+ +
+
Request: .hla lang
+
+
Register: \n[.hla]
+
+ + + + +

Set the hyphenation language to lang. Hyphenation exceptions +specified with the hw request and hyphenation patterns and +exceptions specified with the hpf and hpfa requests are +associated with the hyphenation language. The hla request is +usually invoked by a localization file, which is turn loaded by the +troffrc or troffrc-end file; see the hpf request +above. +

+ +

The hyphenation language is available in the read-only string-valued +register ‘.hla’; it is associated with the environment +(see Environments). +

+ +
+
Request: .hlm [n]
+
+
Register: \n[.hlm]
+
+
Register: \n[.hlc]
+
+ + + + + +

Set the maximum quantity of consecutive hyphenated lines to n. If +n is negative, there is no maximum. If omitted, n +is −1. This value is associated with the environment +(see Environments). Only lines output from a given environment +count toward the maximum associated with that environment. Hyphens +resulting from \% are counted; explicit hyphens are not. +

+ + +

The .hlm read-only register stores this maximum. The count of +immediately preceding consecutive hyphenated lines is available in the +read-only register .hlc. +

+ +
+
Request: .hym [length]
+
+
Register: \n[.hym]
+
+ + + +

Set the (right) hyphenation margin to length. If the adjustment +mode is not ‘b’ or ‘n’, the line is not hyphenated if it is +shorter than length. Without an argument, the hyphenation margin +is reset to its default value, 0. The default scaling unit is ‘m’. +The hyphenation margin is associated with the environment +(see Environments). +

+

A negative argument resets the hyphenation margin to zero, emitting a +warning in category ‘range’. +

+ +

The hyphenation margin is available in the .hym read-only +register. +

+ +
+
Request: .hys [hyphenation-space]
+
+
Register: \n[.hys]
+
+ + + +

Suppress hyphenation of the line in adjustment modes ‘b’ or +‘n’ if it can be justified by adding no more than +hyphenation-space extra space to each inter-word space. Without +an argument, the hyphenation space adjustment threshold is set to its +default value, 0. The default scaling unit is ‘m’. The +hyphenation space adjustment threshold is associated with the +environment (see Environments). +

+

A negative argument resets the hyphenation space adjustment threshold to +zero, emitting a warning in category ‘range’. +

+ +

The hyphenation space adjustment threshold is available in the +.hys read-only register. +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Manipulating-Spacing.html b/doc/groff.html.node/Manipulating-Spacing.html new file mode 100644 index 0000000..6b45b8a --- /dev/null +++ b/doc/groff.html.node/Manipulating-Spacing.html @@ -0,0 +1,220 @@ + + + + + + +Manipulating Spacing (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.11 Manipulating Spacing

+ + + +

A break causes the formatter to update the vertical drawing position at +which the new text baseline is aligned. You can alter this location. +

+
+
Request: .sp [distance]
+
+

Break and move the next text baseline down by distance, or until +springing a page location trap.62 +If invoked with the no-break control character, sp moves the +pending output line’s text baseline by distance. A negative +distance will not reduce the position of the text baseline below +zero. Inside a diversion, any distance argument is ignored. The +default scaling unit is ‘v’. If distance is not specified, +‘1v’ is assumed. +

+
+
.pl 5v \" Set page length to 5 vees.
+.de xx
+\-\-\-
+.  br
+..
+.wh 0 xx \" Set a trap at the top of the page.
+foo on page \n%
+.sp 2v
+bar on page \n%
+.sp 50v \" This will cause a page break.
+baz on page \n%
+.pl \n(nlu \" Truncate page to current position.
+    ⇒ ---
+    ⇒ foo on page 1
+    ⇒
+    ⇒
+    ⇒ bar on page 1
+    ⇒ ---
+    ⇒ baz on page 2
+
+ +

You might use the following macros to set the baseline of the next +output text at a given distance from the top or the bottom of the page. +We subtract one line height (\n[.v]) because the | +operator moves to one vee below the page top (recall Numeric Expressions). +

+
+
.de y-from-top-down
+.  sp |\\$1-\\n[.v]u
+..
+.
+.de y-from-bot-up
+.  sp |\\n[.p]u-\\$1-\\n[.v]u
+..
+
+ +

A call to ‘.y-from-bot-up 10c’ means that the next text baseline +will be 10 cm from the bottom edge of the paper. +

+ +
+
Request: .ls [count]
+
+
Register: \n[.L]
+
+ +

Set the line spacing; add count−1 blank lines after each +line of text. With no argument, GNU troff uses the previous +value before the last ls call. The default is 1. +

+ + +

The read-only register .L contains the current line spacing; it +is associated with the environment (see Environments). +

+ +

The ls request is a coarse mechanism. See Changing the Type Size, for the requests vs and pvs as alternatives to +ls. +

+
+
Escape sequence: \x'spacing'
+
+
Register: \n[.a]
+
+

Sometimes, an output line requires additional vertical spacing, for +instance to allow room for a tall construct like an inline equation with +exponents or subscripts (particularly if they are iterated). The +\x escape sequence takes a delimited measurement (like +‘\x'3p'’) to increase the vertical spacing of the pending output +line. The default scaling unit is ‘v’. If the measurement is +positive, extra vertical space is inserted below the current line; a +negative measurement adds space above. If \x is applied to the +pending output line multiple times, the maxima of the positive and +negative adjustments are separately applied. The delimiter need not be +a neutral apostrophe; see Delimiters. +

+ +

The .a read-only register contains the extra vertical spacing +after the text baseline of the most recently emitted output line. +(In other words, it is the largest positive argument to \x +encountered on that line.) This quantity is exposed via a register +because if an output line requires this “extra post-vertical line +spacing”, and the subsequent output line requires “extra pre-vertical +line spacing” (a negative argument to \x), then applying both +can lead to excessive spacing between the output lines. Text that is +piling high on line n might not require (as much) extra +pre-vertical line spacing if line n−1 carries extra +post-vertical line spacing. +

+

Use of \x can be necessary in combination with the +bracket-building escape sequence \b,63 as the following example shows. +

+
+
.nf
+This is a test of \[rs]b (1).
+This is a test of \[rs]b (2).
+This is a test of \b'xyz'\x'-1m'\x'1m' (3).
+This is a test of \[rs]b (4).
+This is a test of \[rs]b (5).
+    ⇒ This is a test of \b (1).
+    ⇒ This is a test of \b (2).
+    ⇒                   x
+    ⇒ This is a test of y (3).
+    ⇒                   z
+    ⇒ This is a test of \b (4).
+    ⇒ This is a test of \b (5).
+
+
+ +

Without \x, the backslashes on the lines marked ‘(2)’ and +‘(4)’ would be overprinted. +

+
+
Request: .ns
+
+
Request: .rs
+
+
Register: \n[.ns]
+
+ + + + + +

Enable no-space mode. Vertical spacing, whether by sp +requests or blank input lines, is disabled. The bp request to +advance to the next page is also disabled, unless it is accompanied by a +page number (see Page Control). No-space mode ends automatically +when text64 is formatted for output 65 or the rs request is invoked, which ends +no-space mode. The read-only register .ns interpolates a Boolean +value indicating the enablement of no-space mode. +

+

A paragraphing macro might ordinarily insert vertical space to separate +paragraphs. A section heading macro could invoke ns to suppress +this spacing for the first paragraph in a section. +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Manipulating-Type-Size-and-Vertical-Spacing.html b/doc/groff.html.node/Manipulating-Type-Size-and-Vertical-Spacing.html new file mode 100644 index 0000000..e566ad7 --- /dev/null +++ b/doc/groff.html.node/Manipulating-Type-Size-and-Vertical-Spacing.html @@ -0,0 +1,74 @@ + + + + + + +Manipulating Type Size and Vertical Spacing (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.20 Manipulating Type Size and Vertical Spacing

+ + + + + + + + +

These concepts were introduced in Page Geometry. The height of a +font’s tallest glyph is one em, which is equal to the type size in +points.82 A vertical spacing of less than 120% of +the type size can make a document hard to read. Larger proportions can +be useful to spread the text for annotations or proofreader’s marks. By +default, GNU troff uses 10 point type on 12 point +spacing. + +Typographers call the difference between type size and vertical spacing +leading.83 +

+ + + +
+ + + + + diff --git a/doc/groff.html.node/Measurements.html b/doc/groff.html.node/Measurements.html new file mode 100644 index 0000000..a4f1c82 --- /dev/null +++ b/doc/groff.html.node/Measurements.html @@ -0,0 +1,177 @@ + + + + + + +Measurements (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.3 Measurements

+ + + + + + +

The formatter sometimes requires the input of numeric parameters to +specify measurements. These are specified as integers or decimal +fractions with an optional scaling unit suffixed. A scaling unit +is a letter that immediately follows the last digit of a number. Digits +after the decimal point are optional. Measurement expressions include +‘10.5p’, ‘11i’, and ‘3.c’. +

+ + + +

Measurements are scaled by the scaling unit and stored internally (with +any fractional part discarded) in basic units. + + +The device resolution can therefore be obtained by storing a value of +‘1i’ to a register. The only constraint on the basic unit is that +it is at least as small as any other unit. +

+
+
+ + + +
+
u
+

Basic unit. +

+
+
i
+
+ + +

Inch; defined as 2.54 centimeters. +

+
+
c
+
+ + +

Centimeter; a centimeter is about 0.3937 inches. +

+
+
p
+
+ + +

Point; a typesetter’s unit used for measuring type size. +There are 72 points to an inch. +

+
+
P
+
+ + +

Pica; another typesetter’s unit. There are 6 picas to an inch and +12 points to a pica. +

+
+
s
+
z
+

See Using Fractional Type Sizes, for a discussion of these units. +

+
+
f
+

GNU troff defines this unit to scale decimal fractions in the +interval [0, 1] to 16-bit unsigned integers. It multiplies a quantity +by 65,536. See Colors, for usage. +

+
+ +

The magnitudes of other scaling units depend on the text formatting +parameters in effect. These are useful when specifying measurements +that need to scale with the typeface or vertical spacing. +

+
+
m
+
+ + +

Em; an em is equal to the current type size in points. It is named thus +because it is approximately the width of the letter ‘M’. +

+
+
n
+
+ + +

En; an en is one-half em. +

+
+
v
+
+ + + + +

Vee; recall Page Geometry. +

+
+
M
+
+ +

Hundredth of an em. +

+
+ + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Miscellaneous.html b/doc/groff.html.node/Miscellaneous.html new file mode 100644 index 0000000..db1eef3 --- /dev/null +++ b/doc/groff.html.node/Miscellaneous.html @@ -0,0 +1,275 @@ + + + + + + +Miscellaneous (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.35 Miscellaneous

+ +

We document here GNU troff features that fit poorly elsewhere. +

+
+
Request: .nm [start [increment [space [indentation]]]]
+
+
Register: \n[ln]
+
+
Register: \n[.nm]
+
+ + + +

Begin (or, with no arguments, cease) numbering output lines. +start assigns the number of the next output line. Only +line numbers divisible by increment are marked (default: +‘1’). space configures the horizontal spacing between the +number and the text (default: ‘1’). Any given indentation is +applied to the numbers (default: ‘0’). The third and fourth +arguments are reckoned in numeral widths (\0). start must +be non-negative and increment positive. +

+

The formatter aligns the number to the right in a width of three numeral +spaces plus indentation, then catenates space and the output +line. The line length is not reduced. Depending on the value of +the page offset,117 numbers wider than +the allocated space protrude into the left margin, or shift the output +line to the right. +

+

Line numbering parameters corresponding to missing arguments are not +altered. After numbering is disabled, ‘.nm +0’ resumes it using +the previously active parameters. +

+

The parameters of nm are associated with the environment +(see Environments). +

+ + +

While numbering is enabled, the output line number register ln is +updated as each line is output, even if no line number is formatted with +it because it is being skipped (it is not a multiple of increment) +or because numbering is suppressed (see the nn request below). +

+

The .nm register tracks the enablement status of numbering. +Temporary suspension of numbering with the nn request does +not alter its value. +

+
+
.po 5n
+.ll 44n
+Programming,
+when stripped of all its circumstantial irrelevancies,
+.nm 999 1 1 -4
+boils down to no more and no less than
+.nm +0 3
+very effective thinking so as to avoid unmastered
+.nn 2
+complexity,
+to very vigorous separation of your many
+different concerns.
+.br
+\(em Edsger Dijkstra
+.sp
+.nm 1 1 1
+This guy's arrogance takes your breath away.
+.br
+\(em John Backus
+    ⇒      Programming,  when  stripped of all its cir-
+    ⇒  999 cumstantial irrelevancies, boils down to  no
+    ⇒      more  and no less than very effective think-
+    ⇒      ing so as to avoid unmastered complexity, to
+    ⇒      very vigorous separation of your  many  dif-
+    ⇒      ferent concerns.
+    ⇒ 1002 -- Edsger Dijkstra
+    ⇒
+    ⇒    1 This guy’s arrogance takes your breath away.
+    ⇒    2 -- John Backus
+
+
+ +
+
Request: .nn [skip]
+
+
Register: \n[.nn]
+
+

Suppress numbering of the next skip output lines that would +otherwise be numbered. The default is 1. nn can be invoked +when line numbering is not active; suppression of numbering will take +effect for skip lines once nm enables it. +

+

The .nn register stores the count of output lines still to have +their numbering suppressed. +

+

This count is associated with the environment (see Environments). +

+ +

To test whether the current output line will be numbered, you must check +both the .nm and .nn registers. +

+
+
  .de is-numbered
+  .  nop This line
+  .  ie (\\n[.nm] & (1-\\n[.nn])) IS
+  .  el                           ISN'T
+  .  nop numbered.
+  .  br
+  ..
+  Test line numbering.
+  .is-numbered
+  .nm 1
+  .nn 1
+  .is-numbered
+  .is-numbered
+  .nm
+  .is-numbered
+    ⇒ Test line numbering.  This line ISN’T numbered.
+    ⇒ This line ISN’T numbered.
+    ⇒   1 This line IS numbered.
+    ⇒ This line ISN’T numbered.
+
+ +
+
Request: .mc [margin-character [distance]
+
+ + +

Begin (or, with no arguments, cease) writing a margin-character to +the right of each output line. The distance argument separates +margin-character from the right margin. If absent, the most +recent value is used; the default is 10 points. If an output line +exceeds the line length, the margin character is appended to it. + +No margin character is written on lines produced by the tl +request. +

+

The margin character is a property of the output line; the margin +character last configured when the line is output controls. If the +margin character is disabled before an output line breaks, none is +output (but see below). +

+

The margin character is associated with the environment +(see Environments). +

+
+
.ll 5i
+.nf
+.mc \[br]
+This paragraph is marked with a margin character.
+.sp
+As seen above, vertical space isn't thus marked.
+\&
+An output line that is present, but empty, is.
+    ⇒ This paragraph is marked with a margin character.  |
+    ⇒
+    ⇒ As seen above, vertical space isn’t thus marked.   |
+    ⇒                                                    |
+    ⇒ An output line that is present, but empty, is.     |
+
+
+ +

For compatibility with AT&T troff, a call to mc +to set the margin character can’t be undone immediately; at least one +line gets a margin character. +

+
+
.ll 10n
+.nf
+.mc |
+.mc *
+.mc
+foo
+bar
+    ⇒ foo        *
+    ⇒ bar
+
+ + + + + +

The margin character mechanism is commonly used to annotate changes in +documents. The groff distribution ships a program, +gdiffmk, to assist with this task.118 +

+
+
Request: .psbb file
+
+
Register: \n[llx]
+
+
Register: \n[lly]
+
+
Register: \n[urx]
+
+
Register: \n[ury]
+
+ + +

Retrieve the bounding box of the PostScript image found in file, +which must conform to Adobe’s Document Structuring Conventions +(DSC), locate a %%BoundingBox comment, and store the (upper-, +lower-, -left, -right) values into the registers llx, +lly, urx, and ury. If an error occurs (for +example, if no %%BoundingBox comment is present), the formatter +sets these registers to 0. +

+

The search path for file can be controlled with the -I +command-line option. +

+ + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Missing-Unix-Version-7-ms-Macros.html b/doc/groff.html.node/Missing-Unix-Version-7-ms-Macros.html new file mode 100644 index 0000000..99f7b62 --- /dev/null +++ b/doc/groff.html.node/Missing-Unix-Version-7-ms-Macros.html @@ -0,0 +1,78 @@ + + + + + + +Missing Unix Version 7 ms Macros (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.7.1 Unix Version 7 ms macros not implemented by groff ms

+ +

Several macros described in the Unix Version 7 ms +documentation are unimplemented by groff ms because they +are specific to the requirements of documents produced internally by +Bell Laboratories, some of which also require a glyph for the Bell +System logo that groff does not support. These macros +implemented several document type formats +(EG, IM, MF, MR, TM, TR), were meaningful only in conjunction with the use of certain document +types +(AT, CS, CT, OK, SG), stored the postal addresses of Bell Labs sites +(HO, IH, MH, PY, WH), or lacked a stable definition over time +(UX). To compatibly render historical ms documents using these macros, +we advise your documents to invoke the rm request to remove any +such macros it uses and then define replacements with an authentically +typeset original at hand.17 For +informal purposes, a simple definition of UX should maintain the +readability of the document’s substance. +

+
+
+
.rm UX
+.ds UX Unix\"
+
+
+ + +
+ + + + + diff --git a/doc/groff.html.node/Motion-Quanta.html b/doc/groff.html.node/Motion-Quanta.html new file mode 100644 index 0000000..5df1c72 --- /dev/null +++ b/doc/groff.html.node/Motion-Quanta.html @@ -0,0 +1,93 @@ + + + + + + +Motion Quanta (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.3.1 Motion Quanta

+ + + +

An output device’s basic unit u is not necessarily its smallest +addressable length; u can be smaller to avoid problems with +integer roundoff. The minimum distances that a device can work with in +the horizontal and vertical directions are termed its motion +quanta. Measurements are rounded to applicable motion quanta. +Half-quantum fractions round toward zero. +

+ + + + +
+
Register: \n[.H]
+
+
Register: \n[.V]
+
+

These read-only registers interpolate the horizontal and vertical motion +quanta, respectively, of the output device in basic units. +

+ +

For example, we might draw short baseline rules on a terminal device as +follows. See Drawing Geometric Objects. +

+
+
.tm \n[.H]
+    error→ 24
+.nf
+\l'36u' 36u
+\l'37u' 37u
+    ⇒ _ 36u
+    ⇒ __ 37u
+
+ + +
+ + + + + diff --git a/doc/groff.html.node/Numeric-Expressions.html b/doc/groff.html.node/Numeric-Expressions.html new file mode 100644 index 0000000..7da6bd3 --- /dev/null +++ b/doc/groff.html.node/Numeric-Expressions.html @@ -0,0 +1,395 @@ + + + + + + +Numeric Expressions (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.4 Numeric Expressions

+ + + +

A numeric expression evaluates to an integer: it can be as +simple as a literal ‘0’ or it can be a complex sequence of register +and string interpolations interleaved with measurements and operators. +

+

GNU troff provides a set of mathematical and logical operators +familiar to programmers—as well as some unusual ones—but supports +only integer arithmetic.35 The internal data type +used for computing results is usually a 32-bit signed integer, which +suffices to represent magnitudes within a range of ą2 +billion.36 +

+ + + + + + + + + + + + + +

Arithmetic infix operators perform a function on the numeric expressions +to their left and right; they are + (addition), - +(subtraction), * (multiplication), / (truncating +division), and % (modulus). Truncating division rounds to +the integer nearer to zero, no matter how large the fractional portion. +Overflow and division (or modulus) by zero are errors and abort +evaluation of a numeric expression. + + + + + + + + +

+

Arithmetic unary operators operate on the numeric expression to their +right; they are - (negation) and + (assertion—for +completeness; it does nothing). The unary minus must often be used +with parentheses to avoid confusion with the decrementation operator, +discussed below. +

+

Observe the rounding behavior and effect of negative operands on the +modulus and truncating division operators. +

+
+
.nr T 199/100
+.nr U 5/2
+.nr V (-5)/2
+.nr W 5/-2
+.nr X 5%2
+.nr Y (-5)%2
+.nr Z 5%-2
+T=\n[T] U=\n[U] V=\n[V] W=\n[W] X=\n[X] Y=\n[Y] Z=\n[Z]
+    ⇒ T=1 U=2 V=-2 W=-2 X=1 Y=-1 Z=1
+
+ +

The sign of the modulus of operands of mixed signs is determined by the +sign of the first. Division and modulus operators satisfy the following +property: given a dividend a and a divisor b, a +quotient q formed by ‘(a / b)’ and a +remainder r by ‘(a % b)’, then qb + r = a. +

+ + + +

GNU troff’s scaling operator, used with parentheses as +(c;e), evaluates a numeric expression e +using c as the default scaling unit. If c is omitted, +scaling units are ignored in the evaluation of e. This +operator can save typing by avoiding the attachment of scaling units to +every operand out of caution. Your macros can select a sensible default +unit in case the user neglects to supply one. +

+
+
.\" Indent by amount given in first argument; assume ens.
+.de Indent
+.  in (n;\\$1)
+..
+
+ +

Without the scaling operator, the foregoing macro would, if called with +a unitless argument, cause indentation by the in request’s +default scaling unit (ems). The result would be twice as much +indentation as expected. +

+ + + + + + +

GNU troff also provides a pair of operators to compute the +extrema of two operands: >? (maximum) and <? (minimum). +

+
+
.nr slots 5
+.nr candidates 3
+.nr salaries (\n[slots] <? \n[candidates])
+Looks like we'll end up paying \n[salaries] salaries.
+    ⇒ Looks like we'll end up paying 3 salaries.
+
+ + + + + + + + + + + + +

Comparison operators comprise < (less than), > (greater +than), <= (less than or equal), >= (greater than or +equal), and = (equal). == is a synonym for =. +When evaluated, a comparison is replaced with ‘0’ if it is false +and ‘1’ if true. In the roff language, positive values are +true, others false. +

+ + + + + + + + +

We can operate on truth values with the logical operators & +(logical conjunction or “and”) and : (logical disjunction or +“or”). They evaluate as comparison operators do. +

+ + + + + +

A logical complementation (“not”) operator, !, works only +within if, ie, and while requests. +Furthermore, ! is recognized only at the beginning of a numeric +expression not contained by another numeric expression. In other words, +it must be the “outermost” operator. Including it elsewhere in the +expression produces a warning in the ‘number’ category +(see Warnings), and its expression evaluates false. This +unfortunate limitation maintains compatibility with AT&T +troff. Test a numeric expression for falsity by +comparing it to a false value.37 +

+
+
.nr X 1
+.nr Y 0
+.\" This does not work as expected.
+.if (\n[X])&(!\n[Y]) .nop A: X is true, Y is false
+.
+.\" Use this construct instead.
+.if (\n[X])&(\n[Y]<=0) .nop B: X is true, Y is false
+    error→ warning: expected numeric expression, got '!'
+    ⇒ B: X is true, Y is false
+
+ + + + + + +

The roff language has no operator precedence: expressions are +evaluated strictly from left to right, in contrast to schoolhouse +arithmetic. Use parentheses ( ) to impose a desired +precedence upon subexpressions. +

+
+
.nr X 3+5*4
+.nr Y (3+5)*4
+.nr Z 3+(5*4)
+X=\n[X] Y=\n[Y] Z=\n[Z]
+    ⇒ X=32 Y=32 Z=23
+
+ + + + + + + +

For many requests and escape sequences that cause motion on the page, +the unary operators + and - work differently when leading +a numeric expression. They then indicate a motion relative to the +drawing position: positive is down in vertical contexts, right in +horizontal ones. +

+ + + + + + + + + + + + + + + + +

+ and - are also treated differently by the following +requests and escape sequences: bp, in, ll, +lt, nm, nr, pl, pn, po, +ps, pvs, rt, ti, \H, \R, and +\s. Here, leading plus and minus signs serve as incrementation +and decrementation operators, respectively. To negate an expression, +subtract it from zero or include the unary minus in parentheses with its +argument. See Setting Registers, for examples. +

+ + + + + +

A leading | operator indicates a motion relative not to the +drawing position but to a boundary. For horizontal motions, the +measurement specifies a distance relative to a drawing position +corresponding to the beginning of the input line. By default, +tab stops reckon movements in this way. Most escape sequences do not; +| tells them to do so. +

+
+
Mind the \h'1.2i'gap.
+.br
+Mind the \h'|1.2i'gap.
+.br
+Mind the
+\h'|1.2i'gap.
+    ⇒ Mind the             gap.
+    ⇒ Mind the    gap.
+    ⇒ Mind the             gap.
+
+ +

One use of this feature is to define macros whose scope is limited to +the output they format. +

+
+
.\" underline word $1 with trailing punctuation $2
+.de Underline
+.  nop \\$1\l'|0\[ul]'\\$2
+..
+Typographical emphasis is best used
+.Underline sparingly .
+
+ +

In the above example, ‘|0’ specifies a negative motion from the +current position (at the end of the argument just emitted, \$1) +to the beginning of the input line. Thus, the \l escape sequence +in this case draws a line from right to left. A macro call occurs at +the beginning of an input line;38 if the | +operator were omitted, then the underline would be drawn at zero +distance from the current position, producing device-dependent, and +likely undesirable, results. On the ‘ps’ output device, it +underlines the period. +

+

For vertical motions, the | operator specifies a distance from +the first text baseline on the page or in the current +diversion,39 using the current vertical +spacing. +

+
+
A
+.br
+B \Z'C'\v'|0'D
+    ⇒ A D
+    ⇒ B C
+
+ +

In the foregoing example, we’ve used the \Z escape sequence +(see Page Motions) to restore the drawing position after formatting +‘C’, then moved vertically to the first text baseline on the page. +

+
+
Escape sequence: \B'anything'
+
+ + +

Interpolate 1 if anything is a valid numeric expression, +and 0 otherwise. The delimiter need not be a neutral apostrophe; +see Delimiters. +

+ +

You might use \B along with the if request to filter out +invalid macro or string arguments. See Conditionals and Loops. +

+
+
.\" Indent by amount given in first argument; assume ens.
+.de Indent
+.  if \B'\\$1' .in (n;\\$1)
+..
+
+ +

A register interpolated as an operand in a numeric expression must have +an Arabic format; luckily, this is the default. See Assigning Register Formats. +

+ + +

Because spaces separate arguments to requests, spaces are not allowed in +numeric expressions unless the (sub)expression containing them is +surrounded by parentheses. See Invoking Requests, and +Conditionals and Loops. +

+
+
.nf
+.nr a 1+2 + 2+1
+\na
+    error→ expected numeric expression, got a space
+    ⇒ 3
+.nr a 1+(2 + 2)+1
+\na
+    ⇒ 6
+
+ +

The nr request (see Setting Registers) expects its second and +optional third arguments to be numeric expressions; a bare + does +not qualify, so our first attempt got a warning. +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Obsolete-Command.html b/doc/groff.html.node/Obsolete-Command.html new file mode 100644 index 0000000..b656c38 --- /dev/null +++ b/doc/groff.html.node/Obsolete-Command.html @@ -0,0 +1,74 @@ + + + + + + +Obsolete Command (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + +
+ +
+

6.1.2.5 Obsolete Command

+

In AT&T troff output, the writing of a single glyph is +mostly done by a very strange command that combines a horizontal move +and a single character giving the glyph name. It doesn’t have a command +code, but is represented by a 3-character argument consisting of exactly +2 digits and a character. +

+
+
ddg
+

Move right dd (exactly two decimal digits) basic units ‘u’, +then print glyph g (represented as a single character). +

+

In GNU troff, arbitrary syntactical space around and within this +command is allowed. Only when a preceding command on the same line ends +with an argument of variable length is a separating space obligatory. +In AT&T troff, large clusters of these and other +commands are used, mostly without spaces; this made such output almost +unreadable. +

+
+ +

For modern high-resolution devices, this command does not make sense +because the width of the glyphs can become much larger than two decimal +digits. In gtroff, this is only used for the devices X75, +X75-12, X100, and X100-12. For other devices, the +commands ‘t’ and ‘u’ provide a better functionality. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Operator-Index.html b/doc/groff.html.node/Operator-Index.html new file mode 100644 index 0000000..b70458f --- /dev/null +++ b/doc/groff.html.node/Operator-Index.html @@ -0,0 +1,188 @@ + + + + + + +Operator Index (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

Appendix D Operator Index

+ +
+
Jump to:   ! +   +% +   +& +   +( +   +) +   +* +   ++ +   +- +   +/ +   +: +   +; +   +< +   += +   +> +   +| +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

!
!: Numeric Expressions

%
%: Numeric Expressions

&
&: Numeric Expressions

(
(: Numeric Expressions

)
): Numeric Expressions

*
*: Numeric Expressions

+
+: Numeric Expressions
+: Numeric Expressions
+ (unary): Numeric Expressions

-
-: Numeric Expressions
-: Numeric Expressions
- (unary): Numeric Expressions

/
/: Numeric Expressions

:
:: Numeric Expressions

;
;: Numeric Expressions

<
<: Numeric Expressions
<=: Numeric Expressions
<?: Numeric Expressions

=
=: Numeric Expressions
==: Numeric Expressions

>
>: Numeric Expressions
>=: Numeric Expressions
>?: Numeric Expressions

|
|: Numeric Expressions

+ +
+ + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Operators-in-Conditionals.html b/doc/groff.html.node/Operators-in-Conditionals.html new file mode 100644 index 0000000..a04b761 --- /dev/null +++ b/doc/groff.html.node/Operators-in-Conditionals.html @@ -0,0 +1,222 @@ + + + + + + +Operators in Conditionals (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.23.1 Operators in Conditionals

+ + + + + + +

In if, ie, and while requests, in addition to the +numeric expressions described in Numeric Expressions, several +Boolean operators are available; the members of this expanded class are +termed conditional expressions. +

+
+
c glyph
+

True if glyph is available, where glyph is an ordinary +character, a special character ‘\(xx’ or ‘\[xxx]’, +‘\N'xxx'’, or has been defined by any of the char, +fchar, fschar, or schar requests. +

+
+
d name
+

True if a string, macro, diversion, or request called name exists. +

+
+
e
+

True if the current page is even-numbered. +

+
+
F font
+

True if font exists. font is handled as if it were opened +with the ft request (that is, font translation and styles are +applied), without actually mounting it. +

+
+
m color
+

True if color is defined. +

+
+
n
+
+ +

True if the document is being processed in nroff mode. +See troff and nroff Modes. +

+
+
o
+

True if the current page is odd-numbered. +

+
+
r register
+

True if register exists. +

+
+
S style
+

True if style is available for the current font family. Font +translation is applied. +

+
+
t
+

True if the document is being processed in troff mode. +See troff and nroff Modes. +

+ +
+
v
+

Always false. This condition is recognized only for compatibility with +certain other troff implementations.88 +

+
+ +

If the first argument to an if, ie, or while +request begins with a non-alphanumeric character apart from ! +(see below); it performs an output comparison test. +89 +

+ +
+
'xxx'yyy'
+

True if formatting the comparands xxx and yyy produces the +same output commands. The delimiter need not be a neutral apostrophe: +the output comparison operator accepts the same delimiters as most +escape sequences; see Delimiters. This output comparison +operator formats xxx and yyy in separate environments; +after the comparison, the resulting data are discarded. +

+
+
.ie "|"\fR|\fP" true
+.el false
+    ⇒ true
+
+ +

The resulting glyph properties, including font family, style, size, and +slant, must match, but not necessarily the requests and/or escape +sequences used to obtain them. In the previous example, ‘|’ and +‘\fR|\fP’ result in ‘|’ glyphs in the same typefaces at the +same positions, so the comparands are equal. If ‘.ft I’ had +been added before the ‘.ie’, they would differ: the first ‘|’ +would produce an italic ‘|’, not a roman one. Motions must match +in orientation and magnitude to within the applicable horizontal and +vertical motion quanta of the device, after rounding. ‘.if +"\u\d"\v'0'"’ is false even though both comparands result in zero net +motion, because motions are not interpreted or optimized but sent as-is +to the output.90 On the other hand, ‘.if "\d"\v'0.5m'"’ is true, because +\d is defined as a downward motion of one-half em.91 +

+ + +

Surround the comparands with \? to avoid formatting them; this +causes them to be compared character by character, as with string +comparisons in other programming languages. +

+
+
.ie "\?|\?"\?\fR|\fP\?" true
+.el false
+    ⇒ false
+
+ + + + +

Since comparands protected with \? are read in copy mode +(see Copy Mode), they need not even be valid groff syntax. +The escape character is still lexically recognized, however, and +consumes the next character. +

+
+
.ds a \[
+.ds b \[
+.if '\?\*a\?'\?\*b\?' a and b equivalent
+.if '\?\\?'\?\\?' backslashes equivalent
+    ⇒ a and b equivalent
+
+
+
+ +

The above operators can’t be combined with most others, but a leading +‘!’, not followed immediately by spaces or tabs, complements an +expression. +

+
+
.nr x 1
+.ie !r x register x is not defined
+.el      register x is defined
+    ⇒ register x is defined
+
+ +

Spaces and tabs are optional immediately after the ‘c’, ‘d’, +‘F’, ‘m’, ‘r’, and ‘S’ operators, but right after +‘!’, they end the predicate and the conditional evaluates +true.92 +

+
+
.nr x 1
+.ie ! r x register x is not defined
+.el       register x is defined
+    ⇒ r x register x is not defined
+
+ +

The unexpected ‘r x’ in the output is a clue that our conditional +was not interpreted as we planned, but matters may not always be so +obvious. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Optional-man-extensions.html b/doc/groff.html.node/Optional-man-extensions.html new file mode 100644 index 0000000..035f410 --- /dev/null +++ b/doc/groff.html.node/Optional-man-extensions.html @@ -0,0 +1,264 @@ + + + + + + +Optional man extensions (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + +
+ +
+

4.1.1 Optional man extensions

+ + +

Use the file man.local for local extensions to the man +macros or for style changes. +

+ +
+

Custom headers and footers

+ + +

In groff versions 1.18.2 and later, you can specify custom +headers and footers by redefining the following macros in +man.local. +

+
+
Macro: .PT
+
+

Control the content of the headers. Normally, the header prints the +command name and section number on either side, and the optional fifth +argument to TH in the center. +

+ +
+
Macro: .BT
+
+

Control the content of the footers. Normally, the footer prints the +page number and the third and fourth arguments to TH. +

+

Use the FT register to specify the footer position. The default +is −0.5i. +

+ +
+
+

Ultrix-specific man macros

+ + + + +

The groff source distribution includes a file named +man.ultrix, containing macros compatible with the Ultrix variant +of man. Copy this file into man.local (or use the +mso request to load it) to enable the following macros. +

+
+
Macro: .CT key
+
+

Print ‘<CTRL/key>’. +

+ +
+
Macro: .CW
+
+

Print subsequent text using a “constant-width” (monospaced) typeface +(Courier roman). +

+ +
+
Macro: .Ds
+
+

Begin a non-filled display. +

+ +
+
Macro: .De
+
+

End a non-filled display started with Ds. +

+ +
+
Macro: .EX [indent]
+
+

Begin a non-filled display using a monospaced typeface (Courier roman). +Use the optional indent argument to indent the display. +

+ +
+
Macro: .EE
+
+

End a non-filled display started with EX. +

+ +
+
Macro: .G [text]
+
+

Set text in Helvetica. If no text is present on the line where +the macro is called, then the text of the next line appears in +Helvetica. +

+ +
+
Macro: .GL [text]
+
+

Set text in Helvetica oblique. If no text is present on the line +where the macro is called, then the text of the next line appears in +Helvetica Oblique. +

+ +
+
Macro: .HB [text]
+
+

Set text in Helvetica bold. If no text is present on the line +where the macro is called, then all text up to the next HB +appears in Helvetica bold. +

+ +
+
Macro: .TB [text]
+
+

Identical to HB. +

+ +
+
Macro: .MS title sect [punct]
+
+

Set a man page reference in Ultrix format. The title is in +Courier instead of italic. Optional punctuation follows the section +number without an intervening space. +

+ +
+
Macro: .NT [C] [title]
+
+

Begin a note. Print the optional title, or the word “Note”, +centered on the page. Text following the macro makes up the body of the +note, and is indented on both sides. If the first argument is C, +the body of the note is printed centered (the second argument replaces +the word “Note” if specified). +

+ +
+
Macro: .NE
+
+

End a note begun with NT. +

+ +
+
Macro: .PN path [punct]
+
+

Set the path name in a monospaced typeface (Courier roman), followed by +optional punctuation. +

+ +
+
Macro: .Pn [punct] path [punct]
+
+

If called with two arguments, identical to PN. If called with +three arguments, set the second argument in a monospaced typeface +(Courier roman), bracketed by the first and third arguments in the +current font. +

+ +
+
Macro: .R
+
+

Switch to roman font and turn off any underlining in effect. +

+ +
+
Macro: .RN
+
+

Print the string ‘<RETURN>’. +

+ +
+
Macro: .VS [4]
+
+

Start printing a change bar in the margin if the number 4 is +specified. Otherwise, this macro does nothing. +

+ +
+
Macro: .VE
+
+

End printing the change bar begun by VS. +

+ +
+
+

Simple example

+ +

The following example man.local file alters the SH macro +to add some extra vertical space before printing the heading. Headings +are printed in Helvetica bold. +

+
+
.\" Make the heading fonts Helvetica
+.ds HF HB
+.
+.\" Put more space in front of headings.
+.rn SH SH-orig
+.de SH
+.  if t .sp (u;\\n[PD]*2)
+.  SH-orig \\$*
+..
+
+ + + +
+
+
+ + + + + + diff --git a/doc/groff.html.node/Other-Differences.html b/doc/groff.html.node/Other-Differences.html new file mode 100644 index 0000000..6a92cad --- /dev/null +++ b/doc/groff.html.node/Other-Differences.html @@ -0,0 +1,248 @@ + + + + + + +Other Differences (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.38.3 Other Differences

+ +

groff request names unrecognized by other troff +implementations will likely be ignored by them; escape sequences that +are groff extensions are liable to be interpreted as if the +escape character were not present. + +For example, the adjustable, non-breaking escape sequence \~ +is also supported by Heirloom Doctools troff 050915 (September +2005), mandoc 1.9.5 (2009-09-21), neatroff (commit +1c6ab0f6e, 2016-09-13), and Plan 9 from User Space troff +(commit 93f8143600, 2022-08-12), but not by Solaris or Documenter’s +Workbench troffs. +See Manipulating Filling and Adjustment. +

+ + + + + + + + + + + + + + +

GNU troff does not allow the use of the escape sequences +\|, \^, \&, \{, \}, +\SP, \', \`, \-, \_, \!, +\%, and \c in identifiers; AT&T troff +does. The \A escape sequence (see Identifiers) may be +helpful in avoiding use of these escape sequences in names. +

+ + +

When adjusting to both margins, AT&T troff at first +adjusts spaces starting from the right; GNU troff begins from +the left. Both implementations adjust spaces from opposite ends on +alternating output lines in this adjustment mode to prevent “rivers” +in the text. +

+ +

GNU troff does not always hyphenate words as AT&T +troff does. The AT&T implementation uses a set of +hard-coded rules specific to English, while GNU troff uses +language-specific hyphenation pattern files derived from TeX. +Furthermore, in old versions of troff there was a limited amount +of space to store hyphenation exceptions (arguments to the hw +request); GNU troff has no such restriction. +

+ +

GNU troff predefines a string .T containing the argument +given to the -T command-line option, namely the current output +device (for example, ‘pdf’ or ‘utf8’). The existence of this +string is a common feature of post-CSTR #54 +troffs121 but valid values are specific +to each implementation. +

+ + + +

AT&T troff ignored attempts to remove read-only +registers; GNU troff honors such requests. See Built-in Registers. +

+ +

The (read-only) register .T interpolates 1 if GNU +troff is called with the -T command-line option, and +0 otherwise. This behavior differs from AT&T troff, which +interpolated 1 only if nroff was the formatter and was +called with -T. +

+ +

AT&T troff and other implementations handle the +lf request differently. For them, its line argument +changes the line number of the current line. +

+ +

AT&T troff had only environments named ‘0’, +‘1’, and ‘2’. In GNU troff, any number of environments +may exist, using any valid identifiers for their names +(see Identifiers.) +

+ + + + + + +

Fractional type sizes cause one noteworthy incompatibility. In +AT&T troff the ps request ignores scaling units +and thus ‘.ps 10u’ sets the type size to 10 points, whereas in +GNU troff it sets the type size to 10 scaled points. +See Using Fractional Type Sizes. +

+ +

The ab request differs from AT&T troff: +GNU troff writes no message to the standard error stream if no +arguments are given, and it exits with a failure status instead of a +successful one. +

+ +

The bp request differs from AT&T troff: +GNU troff does not accept a scaling unit on the argument, a page +number; the former (somewhat uselessly) does. +

+ +

The pm request differs from AT&T troff: +GNU troff reports the sizes of macros, strings, and diversions in +bytes and ignores an argument to report only the sum of the sizes. +

+ +

Unlike AT&T troff, GNU troff does not ignore the +ss request if the output is a terminal device; instead, the +values of minimal inter-word and additional inter-sentence space are +each rounded down to the nearest multiple of 12. +

+ + + + + + + + +

In GNU troff there is a fundamental difference between +(unformatted) characters and (formatted) glyphs. Everything that +affects how a glyph is output is stored with the glyph node; once a +glyph node has been constructed, it is unaffected by any subsequent +requests that are executed, including bd, cs, tkf, +tr, or fp requests. Normally, glyphs are constructed from +characters immediately before the glyph is added to an output line. +Macros, diversions, and strings are all, in fact, the same type of +object; they contain a sequence of intermixed character and glyph nodes. +Special characters transform from one to the other: before being added +to the output, they behave as characters; afterward, they are glyphs. A +glyph node does not behave like a character node when it is processed by +a macro: it does not inherit any of the special properties that the +character from which it was constructed might have had. For example, +the input +

+
+
.di x
+\\\\
+.br
+.di
+.x
+
+ +

produces ‘\\’ in GNU troff. Each pair of backslashes +becomes one backslash glyph; the resulting backslashes are thus +not interpreted as escape characters when they are reread as the +diversion is output. AT&T troff would interpret +them as escape characters when rereading them and end up printing one +‘\’. +

+ + + + + + + +

One correct way to obtain a printable backslash in most documents is to +use the \e escape sequence; this always prints a single instance +of the current escape character,122 regardless of whether or not it is used in a diversion; it +also works in both GNU troff and AT&T troff. +

+

The other correct way, appropriate in contexts independent of the +backslash’s common use as a troff escape character—perhaps in +discussion of character sets or other programming languages—is +the character escape \(rs or \[rs], for “reverse +solidus”, from its name in the ECMA-6 (ISO/IEC 646) +standard.123 +

+

To store an escape sequence in a diversion that is interpreted when the +diversion is reread, either use the traditional \! transparent +output facility, or, if this is unsuitable, the new \? escape +sequence. See Diversions and gtroff Internals. +

+

In the somewhat pathological case where a diversion exists containing a +partially collected line and a partially collected line at the top-level +diversion has never existed, AT&T troff will output the +partially collected line at the end of input; GNU troff will not. +

+ + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Output-Device-Intro.html b/doc/groff.html.node/Output-Device-Intro.html new file mode 100644 index 0000000..815a509 --- /dev/null +++ b/doc/groff.html.node/Output-Device-Intro.html @@ -0,0 +1,63 @@ + + + + + + +Output Device Intro (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

1.6 Output Devices

+ + + + +

GNU troff’s output is in a device-independent page description +language, which is then read by an output driver that translates +this language into a file format or byte stream that a piece of +(possibly emulated) hardware understands. groff features output +drivers for PostScript devices, terminal emulators (and other simple +typewriter-like machines), X11 (for previewing), TeX DVI, HP +LaserJet 4/PCL5 and Canon LBP printers (which use CaPSL), +HTML, XHTML, and PDF. +

+ + +
+ + + + + diff --git a/doc/groff.html.node/Output-Language-Compatibility.html b/doc/groff.html.node/Output-Language-Compatibility.html new file mode 100644 index 0000000..4ad971f --- /dev/null +++ b/doc/groff.html.node/Output-Language-Compatibility.html @@ -0,0 +1,103 @@ + + + + + + +Output Language Compatibility (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

6.1.4 Output Language Compatibility

+ +

The intermediate output language of AT&T troff was +first documented in A Typesetter-independent TROFF, by Brian +Kernighan, and by 1992 the AT&T troff manual was +updated to incorprate a description of it. +

+

The GNU troff intermediate output format is compatible with this +specification except for the following features. +

+
    +
  • The classical quasi-device independence is not yet implemented. + +
  • The old hardware was very different from what we use today. So the +groff devices are also fundamentally different from the ones +in AT&T troff. For example, the AT&T +PostScript device is called post and has a resolution of only 720 +units per inch, suitable for printers 20 years ago, while groff’s +ps device has a resolution of 72000 units per inch. Maybe, by +implementing some rescaling mechanism similar to the classical +quasi-device independence, groff could emulate AT&T’s +post device. + +
  • The B-spline command ‘D~’ is correctly handled by the intermediate +output parser, but the drawing routines aren’t implemented in some of +the postprocessor programs. + +
  • The argument of the commands ‘s’ and ‘x H has the +implicit unit scaled point ‘z’ in gtroff, while +AT&T troff has point (‘p’). This isn’t an +incompatibility but a compatible extension, for both units coincide for +all devices without a sizescale parameter in the DESC +file, including all postprocessors from AT&T and +groff’s text devices. The few groff devices with a +sizescale parameter either do not exist for AT&T +troff, have a different name, or seem to have a different +resolution. So conflicts are very unlikely. + +
  • The position changing after the commands ‘Dp’, ‘DP’, and +‘Dt’ is illogical, but as old versions of gtroff used this +feature it is kept for compatibility reasons. + + +
+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Page-Control.html b/doc/groff.html.node/Page-Control.html new file mode 100644 index 0000000..da2edc3 --- /dev/null +++ b/doc/groff.html.node/Page-Control.html @@ -0,0 +1,218 @@ + + + + + + +Page Control (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.18 Page Control

+ + + + + + + +

Discretionary page breaks can prevent the unwanted separation of +content. A new page number takes effect during page ejection; see +The Implicit Page Trap. +

+
+
Request: .bp [page-number]
+
+
Request: .bp +page-number
+
Request: .bp -page-number
+
Register: \n[%]
+
+ + +

Break the page and change (increase or decrease) the next page number +per the numeric expression page-number. If page-number is +invalid, GNU troff emits a warning in category ‘number’ and +ignores the argument. This request causes a break. A page break +advances the vertical drawing position to the bottom of the page, +springing traps. See Page Location Traps. + + + +bp has effect only if invoked within the top-level +diversion.71 + + +This request is incorrectly documented in the AT&T +troff manual as having a default scaling unit of ‘v’. +

+ + +

The register % interpolates the current page number. +

+
+
.de BP
+'  bp \" schedule page break once current line is output
+..
+
+
+ +
+
Request: .ne [space]
+
+ + + +

Force a page break if insufficient vertical space is available (assert +“needed” space). ne tests the distance to the next page +location trap; see Page Location Traps, and breaks the page if +that amount is less than space. The default scaling unit is +‘v’. If space is invalid, GNU troff emits a warning +in category ‘number’ and ignores the argument. If space is +not specified, ‘1v’ is assumed. +

+ +

We can require space for at least the first two output lines of a +paragraph, preventing its first line from being widowed at the +page bottom. +

+
+
.ne 2v
+Considering how common illness is,
+how tremendous the spiritual change that it brings,
+how astonishing,
+when the lights of health go down,
+the undiscovered countries that are then disclosed,
+what wastes and deserts of the soul a slight attack
+of influenza brings to view,
+
+ +

This method is reliable only if no output line is pending when ne +is invoked. When macro packages are used, this is often not the case: +their paragraphing macros perform the break. You may need to experiment +with placing the ne after the paragraphing macro, or br +and ne before it. +

+ + +

ne is also useful to force grouping of section headings with +their subsequent paragraphs, or tables with their captions and/or +explanations. Macro packages often use ne with diversions to +implement keeps and displays; see Diversions. They may also offer +parameters for widow and orphan management. +

+ +
+
Request: .sv [space]
+
+
Request: .os
+
+ +

Require vertical space as ne does, but also save it for +later output by the os request. If space is available +before the next page location trap, it is output immediately. Both +requests ignore a partially collected line, taking effect at the next +break. + + +sv and os ignore no-space mode (recall Manipulating Spacing). While the sv request allows negative values for +space, os ignores them. The default scaling unit is +‘v’. If space is not specified, ‘1v’ is assumed. +

+ +
+
Register: \n[nl]
+
+ + + +

nl interpolates or sets the vertical drawing position. When the +formatter starts, the first page transition hasn’t happened yet, and +nl is negative. If a header trap has been planted on the page +(typically at vertical position 0), you can assign a negative +value to nl to spring it if that page has already started +(see Page Location Traps). +

+
+
.de HD
+.  sp
+.  tl ''Goldbach Solution''
+.  sp
+..
+.
+First page.
+.bp
+.wh 0 HD \" plant header trap at top of page
+.nr nl (-1)
+Second page.
+    ⇒ First page.
+    ⇒
+    ⇒ (blank lines elided)
+    ⇒
+    ⇒                         Goldbach Solution
+    ⇒
+    ⇒ (blank lines elided)
+    ⇒
+    ⇒ Second page.
+
+ +

Without resetting nl to a negative value, the trap just planted +would be active beginning with the next page, not the current +one. +

+

See Diversions, for a comparison of nl with the .h and +.d registers. +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Page-Geometry.html b/doc/groff.html.node/Page-Geometry.html new file mode 100644 index 0000000..1486533 --- /dev/null +++ b/doc/groff.html.node/Page-Geometry.html @@ -0,0 +1,140 @@ + + + + + + +Page Geometry (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.2 Page Geometry

+ + + +

roff systems format text under certain assumptions about the size +of the output medium, or page. For the formatter to correctly break a +line it is filling, it must know the line length, which it derives from +the page width (see Line Layout). For it to decide whether to write +an output line to the current page or wait until the next one, it must +know the page length (see Page Layout). +

+ + + + + + +

A device’s resolution converts practical units like inches or +centimeters to basic units, a convenient length measure for the +output device or file format. The formatter and output driver use basic +units to reckon page measurements. The device description file defines +its resolution and page dimensions (see DESC File Format). +

+ +

A page is a two-dimensional structure upon which a roff +system imposes a rectangular coordinate system with its upper left +corner as the origin. Coordinate values are in basic units and increase +down and to the right. Useful ones are therefore always positive and +within numeric ranges corresponding to the page boundaries. +

+ + +

While the formatter (and, later, output driver) is processing a page, it +keeps track of its drawing position, which is the location at +which the next glyph will be written, from which the next motion will be +measured, or where a geometric object will commence rendering. + + +Notionally, glyphs are drawn from the text baseline upward and to the +right.33 The text baseline is a (usually invisible) line upon +which the glyphs of a typeface are aligned. A glyph therefore +“starts” at its bottom-left corner. If drawn at the origin, a typical +letter glyph would lie partially or wholly off the page, depending on +whether, like “g”, it features a descender below the baseline. +

+ + +

Such a situation is nearly always undesirable. It is furthermore +conventional not to write or draw at the extreme edges of the page. +Therefore the initial drawing position of a roff formatter is not +at the origin, but below and to the right of it. This rightward shift +from the left edge is known as the page +offset.34 The downward shift leaves room for a text output +line. +

+

Text is arranged on a one-dimensional lattice of text baselines from the +top to the bottom of the page. + + + +Vertical spacing is the distance between adjacent text baselines. +Typographic tradition sets this quantity to 120% of the type size. The +initial drawing position is one unit of vertical spacing below the page +top. Typographers term this unit a vee. +

+ + + + +

Vertical spacing has an impact on page-breaking decisions. Generally, +when a break occurs, the formatter moves the drawing position to the +next text baseline automatically. If the formatter were already writing +to the last line that would fit on the page, advancing by one vee would +place the next text baseline off the page. Rather than let that happen, +roff formatters instruct the output driver to eject the page, +start a new one, and again set the drawing position to one vee below the +page top; this is a page break. +

+

When the last line of input text corresponds to the last output line +that fits on the page, the break caused by the end of input will also +break the page, producing a useless blank one. Macro packages keep +users from having to confront this difficulty by setting “traps” +(see Traps); moreover, all but the simplest page layouts tend to +have headers and footers, or at least bear vertical margins larger than +one vee. +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Page-Layout-Adjustment.html b/doc/groff.html.node/Page-Layout-Adjustment.html new file mode 100644 index 0000000..7570214 --- /dev/null +++ b/doc/groff.html.node/Page-Layout-Adjustment.html @@ -0,0 +1,57 @@ + + + + + + +Page Layout Adjustment (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

3.2.4 Page Layout

+ +

Most macro packages let the user specify the size of the page margins. +The top and bottom margins are typically handled differently than the +left and right margins; the latter two are derived from the +page offset, indentation, and line length. +See Line Layout. Commonly, packages support registers to tune these +values. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Page-Layout.html b/doc/groff.html.node/Page-Layout.html new file mode 100644 index 0000000..8a6a4ad --- /dev/null +++ b/doc/groff.html.node/Page-Layout.html @@ -0,0 +1,188 @@ + + + + + + +Page Layout (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.17 Page Layout

+ + + +

The formatter permits configuration of the page length and page number. +

+
+
Request: .pl [length]
+
+
Request: .pl +length
+
Request: .pl -length
+
Register: \n[.p]
+
+ + + + +

Change (increase or decrease) the page length per the numeric expression +length. The default scaling unit is ‘v’. A negative +length is valid, but an uncommon application: it prevents page +location traps from being sprung,70 and each +output line is placed on a new page. If length is invalid, GNU +troff emits a warning in category ‘number’. If length +is absent or invalid, ‘11i’ is assumed. +

+ +

The read-only register ‘.p’ interpolates the current page length. +

+ +
+
Request: .pn num
+
+
Request: .pn +num
+
Request: .pn -num
+
Register: \n[.pn]
+
+ + + +

Change (increase or decrease) the page number of the next page +per the numeric expression num. If num is invalid, GNU +troff emits a warning in category ‘number’ and ignores the +request. Without an argument, pn is ignored. +

+ + +

The read-only register .pn interpolates num if set by +pn on the current page, or the current page number plus 1. +

+ + + + +

The formatter offers special support for typesetting headers and +footers, collectively termed titles. Titles have an independent +line length, and their placement on the page is not restricted. +

+
+
Request: .tl 'left'center'right'
+
+ + + + +

Format an output line as a title consisting of left, center, +and right, each aligned accordingly. The delimiter need not be a +neutral apostrophe: tl accepts the same delimiters as most escape +sequences; see Delimiters. If not used as the delimiter, any +page number character character is replaced with the current page +number; the default is ‘%’; see the the pc request below. +Without an argument, tl is ignored. tl writes the title +line immediately, ignoring any partially collected line. +

+

It is not an error to omit delimiters after the first. For example, +‘.tl /Thesis is interpreted as ‘.tl /Thesis///: it +sets a title line comprising only the left-aligned word ‘Thesis’. +

+ +
+
Request: .lt [length]
+
+
Request: .lt +length
+
Request: .lt -length
+
Register: \n[.lt]
+
+ + +

Change (increase or decrease) the line length used by titles per the +numeric expression length. The default scaling unit is ‘m’. +If length is negative, GNU emits a warning in category +‘range’ and treats length as ‘0’. If length is +invalid, GNU troff emits a warning in category ‘number’ and +ignores the request. The formatter’s default title length is +‘6.5i’. With no argument, the title length is restored to the +previous value. The title length is is associated with the environment +(see Environments). +

+ +

The read-only register ‘.lt’ interpolates the title line length. +

+ +
+
Request: .pc [char]
+
+ + + +

Set the page number character to char. With no argument, the page +number character is disabled. pc does not affect the +register %. +

+ +

The following example exercises title features. +

+
+
.lt 50n
+This is my partially collected
+.tl 'Isomers 2023'%'Dextrose Edition'
+line.
+    ⇒ Isomers 2023             1        Dextrose Edition
+    ⇒ This is my partially collected line.
+
+ +

We most often see titles used in page header and footer traps. +See Traps. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Page-Location-Traps.html b/doc/groff.html.node/Page-Location-Traps.html new file mode 100644 index 0000000..3d388bf --- /dev/null +++ b/doc/groff.html.node/Page-Location-Traps.html @@ -0,0 +1,326 @@ + + + + + + +Page Location Traps (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.28.1.1 Page Location Traps

+ + + +

A page location trap is a vertical position trap that applies to +the page; that is, to undiverted output. Many can be present; manage +them with the wh and ch requests. +

+
+
Request: .wh dist [name]
+
+

Plant macro name as page location trap at dist. The default +scaling unit is ‘v’. Non-negative values for dist set the +trap relative to the top of the page; negative values set the trap +relative to the bottom of the page. It is not possible to plant a trap +less than one basic unit from the page bottom: a dist of -0 +is interpreted as 0, the top of the page.106 An existing visible trap (see below) at +dist is removed; this is wh’s sole function if name +is missing. +

+

A trap is sprung only if it is visible, meaning that its location +is reachable on the page107 and it +is not hidden by another trap at the same location already planted +there. +

+ + + + + + + + +

A macro package might set headers and footers as follows; this example +configures vertical margins of one inch to the body text, and one +half-inch to the titles. Observe the use of the no-break control +character with sp request to position our text baselines, +and the page number character ‘%’ used with the tl request. +

+
+
.\" hdfo.roff
+.de hd                  \" page header
+'  sp .5i
+'  tl '\\*(Ti''\\*(Da'  \" title and date strings
+'  sp .5i
+..
+.de fo                  \" page footer
+'  sp .5i
+.  tl ''%''
+.  bp
+..
+.wh 0   hd             \" trap at top of the page
+.wh -1i fo             \" trap 1 inch from bottom
+
+ +

To use these traps, copy the above (or load it from a file with the +so or mso requests), then set up the strings it uses. +

+
+
.so hdfo.roff
+.ds Ti Final Report\"
+.ds Da 21 May 2023\"
+.ti
+On 5 August of last year,
+this committee tasked me with the investigation of the
+CFIT (controlled flight into terrain) incident of
+.\" ...and so on...
+
+ +

A trap above the top or at or below the bottom of the page can be made +visible by either moving it into the page area or increasing the page +length so that the trap is on the page. Negative trap values always use +the current page length; they are not converted to an absolute +vertical position. + + +We can use the ptr request to dump our page location traps to the +standard error stream (see Debugging). Their positions are reported +in basic units; an nroff device example follows. +

+
+
.pl 5i
+.wh -1i xx
+.ptr
+    error→ xx      -240
+.pl 100i
+.ptr
+    error→ xx      -240
+
+ +

It is possible to have more than one trap at the same location (although +only one at a time can be visible); to achieve this, the traps must be +defined at different locations, then moved to the same place with the +ch request. In the following example, the many empty lines +caused by the bp request are not shown in the output. +

+
+
.de a
+.  nop a
+..
+.de b
+.  nop b
+..
+.de c
+.  nop c
+..
+.
+.wh 1i a
+.wh 2i b
+.wh 3i c
+.bp
+    ⇒ a b c
+
+
+
.ch b 1i
+.ch c 1i
+.bp
+    ⇒ a
+
+
+
.ch a 0.5i
+.bp
+    ⇒ a b
+
+
+ +
+
Register: \n[.t]
+
+ + +

The read-only register .t holds the distance to the next vertical +position trap. If there are no traps between the current position and +the bottom of the page, it contains the distance to the page bottom. +Within a diversion, in the absence of a diversion trap, this distance is +the largest representable integer in basic units—effectively infinite. +

+ +
+
Request: .ch name [dist]
+
+ + +

Change the location of a trap by moving macro name to new location +dist, or by unplanting it altogether if dist is absent. The +default scaling unit is ‘v’. Parameters to ch are specified +in the opposite order from wh. If name is the earliest +planted macro of multiple traps at the same location, (re)moving it from +that location exposes the macro next least recently planted at the same +place.108 +

+

Changing a trap’s location is useful for building up footnotes in a +diversion to allow more space at the bottom of the page for them. +

+ +
+ +

The same macro can be installed simultaneously at multiple locations; +however, only the earliest-planted instance—that has not yet been +deleted with wh—will be moved by ch. The following +example (using an nroff device) illustrates this behavior. Blank +lines have been elided from the output. +

+
+
.de T
+Trap sprung at \\n(nlu.
+.br
+..
+.wh 1i T
+.wh 2i T
+foo
+.sp 11i
+.bp
+.ch T 4i
+bar
+.sp 11i
+.bp
+.ch T 5i
+baz
+.sp 11i
+.bp
+.wh 5i
+.ch T 6i
+qux
+.sp 11i
+
+
+
    ⇒ foo
+    ⇒ Trap sprung at 240u.
+    ⇒ Trap sprung at 480u.
+    ⇒ bar
+    ⇒ Trap sprung at 480u.
+    ⇒ Trap sprung at 960u.
+    ⇒ baz
+    ⇒ Trap sprung at 480u.
+    ⇒ Trap sprung at 1200u.
+    ⇒ qux
+    ⇒ Trap sprung at 1440u.
+
+ +
+
Register: \n[.ne]
+
+

The read-only register .ne contains the amount of space that was +needed in the last ne request that caused a trap to be sprung; +it is useful in conjunction with the .trunc register. See Page Control. Since the .ne register is set only by traps, it +doesn’t make sense to interpolate it outside of macros called by traps. +

+ +
+
Register: \n[.trunc]
+
+ + +

A read-only register containing the amount of vertical space truncated +from an sp request by the most recently sprung vertical +position trap, or, if the trap was sprung by an ne request, +minus the amount of vertical motion produced by the ne +request. In other words, at the point a trap is sprung, it +represents the difference of what the vertical position would have +been but for the trap, and what the vertical position actually is. +Since the .trunc register is set only by traps, it doesn’t make +sense to interpolate it outside of macros called by traps. +

+ +
+
Register: \n[.pe]
+
+ + + +

This Boolean-valued, read-only register interpolates 1 while a page +is being ejected, and 0 otherwise. +

+

In the following example, we plant the same trap at the top and the +bottom of the page. We also make the trap report its name and the +vertical drawing position. +

+
+
.de T
+.tm \\$0: page \\n%, nl=\\n[nl] .pe=\\n[.pe]
+..
+.ll 46n
+.wh 0 T
+.wh -1v T
+Those who can make you believe absurdities can make you
+commit atrocities. \[em] Voltaire
+    error→ T: page 1, nl=0 .pe=0
+    error→ T: page 1, nl=2600 .pe=1
+    ⇒ Those who can make you believe absurdities can
+    ⇒ make you commit atrocities. -- Voltaire
+
+
+ + + +

When designing macros, keep in mind that diversions and traps do +normally interact. For example, if a trap calls a header macro (while +outputting a diversion) that tries to change the font on the current +page, the effect is not visible before the diversion has completely been +printed (except for input protected with \! or \?) since +the data in the diversion is already formatted. In most cases, this is +not the expected behaviour. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Page-Motions.html b/doc/groff.html.node/Page-Motions.html new file mode 100644 index 0000000..bb94bdb --- /dev/null +++ b/doc/groff.html.node/Page-Motions.html @@ -0,0 +1,454 @@ + + + + + + +Page Motions (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.25 Page Motions

+ + + +

See Manipulating Spacing, for a discussion of the most commonly used +request for vertical motion, sp, which spaces downward by one +vee. +

+
+
Request: .mk [reg]
+
+
Request: .rt [dist]
+
+ + + + + + + + +

You can mark a location on a page for subsequent return. +mk takes an argument, a register name in which to store the +current page location. If given no argument, it stores the location in +an internal register. This location can be used later by the rt +or the sp requests (or the \v escape). +

+

The rt request returns upward to the location marked with +the last mk request. If used with an argument, it returns to a +vertical position dist from the top of the page (no previous +call to mk is necessary in this case). The default scaling +unit is ‘v’. +

+

If a page break occurs between a mk request and its matching +rt request, the rt request is silently ignored. +

+

A simple implementation of a macro to set text in two columns follows. +

+
+
.nr column-length 1.5i
+.nr column-gap 4m
+.nr bottom-margin 1m
+.
+.de 2c
+.  br
+.  mk
+.  ll \\n[column-length]u
+.  wh -\\n[bottom-margin]u 2c-trap
+.  nr right-side 0
+..
+.
+.de 2c-trap
+.  ie \\n[right-side] \{\
+.    nr right-side 0
+.    po -(\\n[column-length]u + \\n[column-gap]u)
+.    \" remove trap
+.    wh -\\n[bottom-margin]u
+.  \}
+.  el \{\
+.    \" switch to right side
+.    nr right-side 1
+.    po +(\\n[column-length]u + \\n[column-gap]u)
+.    rt
+.  \}
+..
+
+ +

Now let us apply our two-column macro. +

+
+
.pl 1.5i
+.ll 4i
+This is a small test that shows how the
+rt request works in combination with mk.
+
+.2c
+Starting here, text is typeset in two columns.
+Note that this implementation isn't robust
+and thus not suited for a real two-column
+macro.
+    ⇒ This is a small test that shows how the
+    ⇒ rt request works in combination with mk.
+    ⇒
+    ⇒ Starting  here,    isn't    robust
+    ⇒ text is typeset    and   thus  not
+    ⇒ in two columns.    suited  for   a
+    ⇒ Note that  this    real two-column
+    ⇒ implementation     macro.
+
+
+ +

Several escape sequences enable fine control of movement about the page. +

+
+
Escape sequence: \v'expr'
+
+ + +

Vertically move the drawing position. expr indicates the +magnitude of motion: positive is downward and and negative upward. The +default scaling unit is ‘v’. The motion is relative to the current +drawing position unless expr begins with the boundary-relative +motion operator ‘|’. See Numeric Expressions. +

+

Text processing continues at the new drawing position; usually, vertical +motions should be in balanced pairs to avoid a confusing page layout. +

+

\v will not spring a vertical position trap. This can be useful; +for example, consider a page bottom trap macro that prints a marker in +the margin to indicate continuation of a footnote. See Traps. +

+ +

A few escape sequences that produce vertical motion are unusual. They +are thought to originate early in AT&T nroff history to achieve +super- and subscripting by half-line motions on line printers and +teletypewriters before the phototypesetter made more precise positioning +available. They are reckoned in ems—not vees—to maintain continuity +with their original purpose of moving relative to the size of the type +rather than the distance between text baselines (vees).103 +

+
+
Escape sequence: \r
+
+
Escape sequence: \u
+
+
Escape sequence: \d
+
+

Move upward 1m, upward .5m, and +downward .5m, respectively. +

+ +

Let us see these escape sequences in use. +

+
+
Obtain 100 cm\u3\d of \ka\d\092\h'|\nau'\r233\dU.
+
+ +

In the foregoing we have paired \u and \d to typeset a +superscript, and later a full em negative (“reverse”) motion to place +a superscript above a subscript. A numeral-width horizontal motion +escape sequence aligns the proton and nucleon numbers, while \k +marks a horizontal position to which \h returns so that we could +stack them. (We shall discuss these horizontal motion escape sequences +presently.) In serious applications, we often want to alter the type +size of the -scripts and to fine-tune the vertical motions, as the +groff ms package does with its super- and subscripting +string definitions. +

+
+
Escape sequence: \h'expr'
+
+ + + + + +

Horizontally move the drawing position. expr indicates the +magnitude of motion: positive is rightward and negative leftward. The +default scaling unit is ‘m’. The motion is relative to the current +drawing position unless expr begins with the boundary-relative +motion operator ‘|’. See Numeric Expressions. +

+ +

The following string definition sets the TeX +logo.104 +

+
+
.ds TeX T\h'-.1667m'\v'.224m'E\v'-.224m'\h'-.125m'X\"
+
+ +

There are a number of special-case escape sequences for horizontal +motion. +

+
+
Escape sequence: \SP
+
+ + + + +

Move right one word space. (The input is a backslash followed by a +space.) This escape sequence can be thought of as a non-adjustable, +unbreakable space. Usually you want \~ instead; see +Manipulating Filling and Adjustment. +

+ + + +
+
Escape sequence: \|
+
+

Move one-sixth em to the right on typesetting output devices. If +a glyph named ‘\|’ is defined in the current font, its width is +used instead, even on terminal output devices. +

+ + + +
+
Escape sequence: \^
+
+

Move one-twelfth em to the right on typesetting output devices. +If a glyph named ‘\^’ is defined in the current font, its width is +used instead, even on terminal output devices. +

+ +
+
Escape sequence: \0
+
+ + + + +

Move right by the width of a numeral in the current font. +

+ +

Horizontal motions are not discarded at the end of an output line as +word spaces are. See Breaking. +

+
+
Escape sequence: \w'anything'
+
+
Register: \n[st]
+
+
Register: \n[sb]
+
+
Register: \n[rst]
+
+
Register: \n[rsb]
+
+
Register: \n[ct]
+
+
Register: \n[ssc]
+
+
Register: \n[skw]
+
+ +

Interpolate the width of anything in basic units. This escape +sequence allows several properties of formatted output to be measured +without writing it out. +

+
+
The length of the string 'abc' is \w'abc'u.
+    ⇒ The length of the string 'abc' is 72u.
+
+ + + +

anything is processed in a dummy environment: this means that +font and type size changes, for example, may occur within it without +affecting subsequent output. +

+

After each use, \w sets several registers. +

+ + + +
+
st
+
sb
+

The maximum vertical displacements of the text baseline above and below, +respectively. The sign convention is opposite that of relative vertical +motions; that is, depth below the (original) baseline is negative. +These registers are incorrectly documented in the AT&T +troff manual as “the highest and lowest extent of [the argument +to \w] relative to the baseline”. +

+
+
rst
+
rsb
+

Like st and sb, but taking account of the heights and +depths of glyphs. In other words, these registers store the highest and +lowest vertical positions attained by anything, doing what +AT&T troff documented st and sb as doing. +

+
+
ct
+

Characterizes the geometry of glyphs occurring in anything. +

+
+
0
+

only short glyphs, no descenders or tall glyphs +

+
+
1
+

at least one descender +

+
+
2
+

at least one tall glyph +

+
+
3
+

at least one each of a descender and a tall glyph +

+
+ +
+
ssc
+

The amount of horizontal space (possibly negative) that should be added +to the last glyph before a subscript. +

+
+
skw
+

How far to right of the center of the last glyph in the \w +argument, the center of an accent from a roman font should be placed +over that glyph. +

+
+
+ +
+
Escape sequence: \kp
+
+
Escape sequence: \k(ps
+
Escape sequence: \k[position]
+
+ + + + +

Store the current horizontal position in the input line in a +register with the name position (one-character name p, +two-character name ps). Use this, for example, to return to the +beginning of a string for highlighting or other decoration. +

+ +
+
Register: \n[hp]
+
+ + + + +

The current horizontal position at the input line. +

+ +
+
Register: \n[.k]
+
+ + + + +

A read-only register containing the current horizontal output position +(relative to the current indentation). +

+ +
+
Escape sequence: \o'abc…'
+
+ + +

Overstrike the glyphs of characters a, b, c, …; +the glyphs are centered, written, and the drawing position advanced by +the widest of the glyphs. +

+ +
+
Escape sequence: \zc
+
+ + +

Format the character c with zero width; that is, without advancing +the drawing position. Use \z to overstrike glyphs aligned to +their left edges, in contrast to \o’s centering. +

+ +
+
Escape sequence: \Z'anything'
+
+ + +

Save the drawing position, format anything, then restore it. Tabs +and leaders in the argument are ignored with an error diagnostic. +

+

We might implement a strike-through macro thus. +

+
+
.de ST
+.nr width \w'\\$1'
+\Z@\v'-.25m'\l'\\n[width]u'@\\$1
+..
+.
+This is
+.ST "a test"
+an actual emergency!
+
+
+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Paper-Format.html b/doc/groff.html.node/Paper-Format.html new file mode 100644 index 0000000..f6f9e72 --- /dev/null +++ b/doc/groff.html.node/Paper-Format.html @@ -0,0 +1,101 @@ + + + + + + +Paper Format (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

2.5 Paper Format

+ + + + + + + + +

In groff, the page dimensions for the formatter GNU troff +and for output devices are handled separately. See Page Layout, for +vertical manipulation of the page size, and See Line Layout, for +horizontal changes. + + +The papersize macro package, normally loaded by troffrc at +startup, provides an interface for configuring page dimensions by +convenient names, like ‘letter’ or ‘a4’; see +groff_tmac(5). The default used by the formatter depends on +its build configuration, but is usually one of the foregoing, as +geographically appropriate. +

+

It is up to each macro package to respect the page dimensions configured +in this way. +

+

For each output device, the size of the output medium can be set in its +DESC file. Most output drivers also recognize a command-line +option -p to override the default dimensions and an option +-l to use landscape orientation. See DESC File Format, for +a description of the papersize keyword, which takes an argument +of the same form as -p. The output driver’s man page, such as +grops(1), may also be helpful. +

+

groff uses the command-line option -P to pass options to +postprocessors; for example, use the following for PostScript output on +A4 paper in landscape orientation. +

+
+
groff -Tps -dpaper=a4l -P-pa4 -P-l -ms foo.ms > foo.ps
+
+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Paragraphs-in-ms.html b/doc/groff.html.node/Paragraphs-in-ms.html new file mode 100644 index 0000000..e6c3a28 --- /dev/null +++ b/doc/groff.html.node/Paragraphs-in-ms.html @@ -0,0 +1,160 @@ + + + + + + +Paragraphs in ms (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.5.3 Paragraphs

+ + +

Paragraphing macros break, or terminate, any pending output line +so that a new paragraph can begin. Several paragraph types are +available, differing in how indentation applies to them: to left, right, +or both margins; to the first output line of the paragraph, all output +lines, or all but the first. All paragraphing macro calls cause the +insertion of vertical space in the amount stored in the PD +register, except at page or column breaks. Alternatively, a blank input +line breaks the output line and vertically spaces by one vee. +

+
+
Macro: .LP
+
+

Set a paragraph without any (additional) indentation. +

+ +
+
Macro: .PP
+
+

Set a paragraph with a first-line left indentation in the amount stored +in the PI register. +

+ +
+
Macro: .IP [marker [width]]
+
+

Set a paragraph with a left indentation. The optional marker is +not indented and is empty by default. It has several applications; +see Lists. width overrides the indentation amount +stored in the PI register; its default unit is ‘n’. Once +specified, width applies to further IP calls until +specified again or a heading or different paragraphing macro is called. +

+ +
+
Macro: .QP
+
+

Set a paragraph indented from both left and right margins by the amount +stored in the QI register. +

+ +
+
Macro: .QS
+
+
Macro: .QE
+
+

Begin (QS) and end (QE) a region where each paragraph is +indented from both margins by the amount stored in the QI +register. The text between QS and QE can be structured +further by use of other paragraphing macros. +

+ +
+
Macro: .XP
+
+

Set an “exdented” paragraph—one with a left indentation in the +amount stored in the PI register on every line except the +first (also known as a hanging indent). This is a Berkeley extension. +

+ +

The following example illustrates the use of paragraphing macros. +

+
+
+
.NH 2
+Cases used in the 2001 study
+.LP
+Two software releases were considered for this report.
+.PP
+The first is commercial software;
+the second is free.
+.IP \[bu]
+Microsoft Word for Windows,
+starting with version 1.0 through the current version
+(Word 2000).
+.IP \[bu]
+GNU Emacs,
+from its first appearance as a standalone editor through
+the current version (v20).
+See [Bloggs 2002] for details.
+.QP
+Franklin's Law applied to software:
+software expands to outgrow both RAM and disk space over
+time.
+.SH
+Bibliography
+.XP
+Bloggs, Joseph R.,
+.I "Everyone's a Critic" ,
+Underground Press, March 2002.
+A definitive work that answers all questions and
+criticisms about the quality and usability of free
+software.
+
+
+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Paragraphs.html b/doc/groff.html.node/Paragraphs.html new file mode 100644 index 0000000..a230bcd --- /dev/null +++ b/doc/groff.html.node/Paragraphs.html @@ -0,0 +1,109 @@ + + + + + + +Paragraphs (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

3.2.1 Paragraphs

+ + +

Paragraphs can be separated and indented in various ways. Some start +with a blank line and have a first-line indentation, like most of the +ones in this manual. Block paragraphs omit the indentation. +

+
+
  ⇒ Some  men  look  at constitutions with sanctimonious
+  ⇒ reverence,  and  deem  them  like  the  ark  of  the
+  ⇒ covenant, too sacred to be touched.
+
+ + + + +

We also frequently encounter tagged paragraphs, which begin +with a tag or label at the left margin and indent the remaining text. +

+
+
  ⇒ one  This  is the first paragraph.  Notice how the
+  ⇒      first line of the resulting  paragraph  lines
+  ⇒      up with the other lines in the paragraph.
+
+ +

If the tag is too wide for the indentation, the line is broken. +

+
+
  ⇒ longlabel
+  ⇒      The  label does not align with the subsequent
+  ⇒      lines, but they align with each other.
+
+ +

A variation of the tagged paragraph is the itemized or enumerated +paragraph, which might use punctuation or a digit for a tag, +respectively. These are frequently used to construct lists. +

+
+
  ⇒ o    This  list  item  starts with a bullet.  When
+  ⇒      producing output for a device using the ASCII
+  ⇒      character set, an 'o' is formatted instead.
+
+ +

Often, use of the same macro without a tag continues such a discussion. +

+
+
  ⇒ -xyz  This option is recognized but ignored.
+  ⇒
+  ⇒       It had a security hole that we don't discuss.
+
+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Parameters.html b/doc/groff.html.node/Parameters.html new file mode 100644 index 0000000..ddf31cf --- /dev/null +++ b/doc/groff.html.node/Parameters.html @@ -0,0 +1,195 @@ + + + + + + +Parameters (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.24.1 Parameters

+ + +

Macro calls and string interpolations optionally accept a list of +arguments; recall Calling Macros. At the time such an +interpolation takes place, these parameters can be examined using +a register and a variety of escape sequences starting with ‘\$’. +All such escape sequences are interpreted even in copy mode, a fact we +shall motivate and explain below (see Copy Mode). +

+
+
Register: \n[.$]
+
+ +

The count of parameters available to a macro or string is kept in this +read-only register. The shift request can change its value. +

+ +

Any individual parameter can be accessed by its position in the list of +arguments to the macro call, numbered from left to right starting at 1, +with one of the following escape sequences. +

+
+
Escape sequence: \$n
+
+
Escape sequence: \$(nn
+
Escape sequence: \$[nnn]
+

Interpolate the nth, nnth, or nnnth parameter. The +first form expects only a single digit (1≤n≤9)), the +second two digits (01≤nn≤99)), and the third any +positive integer nnn. Macros and strings accept an unlimited +number of parameters. +

+ +
+
Request: .shift [n]
+
+

Shift the parameters n places (1 by default). This is a +“left shift”: what was parameter i becomes parameter +i-n. The parameters formerly in positions 1 +to n are no longer available. Shifting by a non-positive +amount performs no operation. The register .$ is adjusted +accordingly. +

+ + + + + +

In practice, parameter interpolations are usually seen prefixed with an +extra escape character. This is because the \$ family of escape +sequences is interpreted even in copy mode.100 +

+
+
Escape sequence: \$*
+
+
Escape sequence: \$@
+
+
Escape sequence: \$^
+
+

In some cases it is convenient to interpolate all of the parameters at +once (to pass them to a request, for instance). The \$* escape +concatenates the parameters, separating them with spaces. \$@ +is similar, concatenating the parameters, surrounding each with double +quotes and separating them with spaces. If not in compatibility mode, +the interpolation depth of double quotes is preserved (see Calling Macros). \$^ interpolates all parameters as if they were +arguments to the ds request. +

+
+
.de foo
+. tm $1='\\$1'
+. tm $2='\\$2'
+. tm $*='\\$*'
+. tm $@='\\$@'
+. tm $^='\\$^'
+..
+.foo " This is a "test"
+    error→ $1=' This is a '
+    error→ $2='test"'
+    error→ $*=' This is a  test"'
+    error→ $@='" This is a " "test""'
+    error→ $^='" This is a "test"'
+
+ +

\$* is useful when writing a macro that doesn’t need to +distinguish its arguments, or even to not interpret them; examples +include macros that produce diagnostic messages by wrapping the +tm or ab requests. Use \$@ when writing a macro +that may need to shift its parameters and/or wrap a macro or request +that finds the count significant. If in doubt, prefer \$@ to +\$*. An application of \$^ is seen in trace.tmac, +which redefines some requests and macros for debugging purposes. +

+ +
+
Escape sequence: \$0
+
+ + +

Interpolate the name by which the macro being interpreted was called. +The als request can cause a macro to have more than one name. +Applying string interpolation to a macro does not change this name. +

+
+
.de foo
+.  tm \\$0
+..
+.als bar foo
+.
+.de aaa
+.  foo
+..
+.de bbb
+.  bar
+..
+.de ccc
+\\*[foo]\\
+..
+.de ddd
+\\*[bar]\\
+..
+.
+.aaa
+    error→ foo
+.bbb
+    error→ bar
+.ccc
+    error→ ccc
+.ddd
+    error→ ddd
+
+
+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Postprocessor-Access.html b/doc/groff.html.node/Postprocessor-Access.html new file mode 100644 index 0000000..3b06a80 --- /dev/null +++ b/doc/groff.html.node/Postprocessor-Access.html @@ -0,0 +1,144 @@ + + + + + + +Postprocessor Access (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.34 Postprocessor Access

+ + + +

Two escape sequences and two requests enable documents to pass +information directly to a postprocessor. These are useful for +exercising device-specific capabilities that the groff language +does not abstract or generalize; examples include the embedding of +hyperlinks and image files. Device-specific functions are documented in +each output driver’s man page, such as gropdf(1), +grops(1), or grotty(1). +

+
+
Request: .device xxx
+
+
Escape sequence: \X'xxx '
+
+

Embed all xxx arguments into GNU troff output as parameters +to a device control command ‘x X. The meaning and +interpretation of such parameters is determined by the output driver or +other postprocessor. +

+ + + +

The device request processes its arguments in copy mode +(see Copy Mode). An initial neutral double quote in contents +is stripped to allow embedding of leading spaces. + + + + +By contrast, within \X arguments, the escape sequences \&, +\), \%, and \: are ignored; \SP and +\~ are converted to single space characters; and \\ has +its escape character stripped. So that the basic Latin subset of the +Unicode character set115 can be reliably encoded in device control +commands, seven special character escape sequences (‘\-’, +‘\[aq]’, ‘\[dq]’, ‘\[ga]’, ‘\[ha]’, ‘\[rs]’, +and ‘\[ti]’,) are mapped to basic Latin characters; see the +groff_char(7) man page. For this transformation, character +translations and special character definitions are +ignored.116 The use of any +other escape sequence in \X parameters is normally an error. +

+ + + +

If the use_charnames_in_special directive appears in the output +device’s DESC file, the use of special character escape sequences +is not an error; they are simply output verbatim (with the +exception of the seven mapped to Unicode basic Latin characters, +discussed above). use_charnames_in_special is currently employed +only by grohtml. +

+ +
+
Request: .devicem name
+
+
Escape sequence: \Yn
+
+
Escape sequence: \Y(nm
+
Escape sequence: \Y[name]
+

This is approximately equivalent to ‘\X'\*[name]'’ +(one-character name n, two-character name nm). +However, the contents of the string or macro name are not +interpreted; also it is permitted for name to have been defined as +a macro and thus contain newlines (it is not permitted for the argument +to \X to contain newlines). The inclusion of newlines requires +an extension to the AT&T troff output format, and +confuses drivers that do not know about this extension (see Device Control Commands). +

+ +
+
Request: .tag name
+
+
Request: .taga name
+
+

Reserved for internal use. +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Predefined-Text.html b/doc/groff.html.node/Predefined-Text.html new file mode 100644 index 0000000..8b03b1f --- /dev/null +++ b/doc/groff.html.node/Predefined-Text.html @@ -0,0 +1,53 @@ + + + + + + +Predefined Text (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

3.2.12 Predefined Text

+ +

Most macro packages supply predefined strings to set prepared text like +the date, or to perform operations like super- and subscripting. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Preprocessor-Intro.html b/doc/groff.html.node/Preprocessor-Intro.html new file mode 100644 index 0000000..7bb43a7 --- /dev/null +++ b/doc/groff.html.node/Preprocessor-Intro.html @@ -0,0 +1,78 @@ + + + + + + +Preprocessor Intro (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

1.5 Preprocessors

+ + +

An alternative approach to complexity management, particularly when +constructing tables, setting mathematics, or drawing diagrams, lies in +preprocessing. A preprocessor employs a domian-specific language +to ease the generation of tables, equations, and so forth in terms that +are convenient for human entry. Each preprocessor reads a document and +translates the parts of it that apply to it into GNU troff input. +Command-line options to groff tell it which preprocessors to +use. +

+

groff provides preprocessors for laying out tables +(gtbl), typesetting equations (geqn), drawing +diagrams (gpic and ggrn), inserting bibliographic +references (grefer), and drawing chemical structures +(gchem). An associated program that is useful when dealing +with preprocessors is gsoelim.1 +

+

groff also supports grap, a preprocessor for drawing +graphs. A free implementation of it can be obtained separately. +

+

Unique to groff is the preconv preprocessor that enables +groff to handle documents in a variety of input encodings. +

+

Other preprocessors exist, but no free implementations +are known. An example is ideal, which draws diagrams using a +mathematical constraint language. +

+ + +
+ + + + + diff --git a/doc/groff.html.node/Preprocessor-Support.html b/doc/groff.html.node/Preprocessor-Support.html new file mode 100644 index 0000000..43e961c --- /dev/null +++ b/doc/groff.html.node/Preprocessor-Support.html @@ -0,0 +1,56 @@ + + + + + + +Preprocessor Support (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

3.2.13 Preprocessor Support

+ +

All macro packages provide support for various preprocessors and may +extend their functionality by defining macros to set their contents in +displays. Examples include TS and TE for gtbl, +EQ and EN for geqn, and PS and PE +for gpic. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Program-and-File-Index.html b/doc/groff.html.node/Program-and-File-Index.html new file mode 100644 index 0000000..ecc30ec --- /dev/null +++ b/doc/groff.html.node/Program-and-File-Index.html @@ -0,0 +1,239 @@ + + + + + + +Program and File Index (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

Appendix I Program and File Index

+ +
+
Jump to:   A +   +C +   +D +   +E +   +F +   +G +   +I +   +J +   +L +   +M +   +N +   +P +   +R +   +S +   +T +   +V +   +Z +   +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

A
an.tmac: man

C
changebar: Miscellaneous
composite.tmac: Using Symbols
cp1047.tmac: Input Encodings
cs.tmac: Manipulating Hyphenation

D
de.tmac: Manipulating Hyphenation
DESC: Selecting Fonts
DESC: Font Families
DESC: Using Symbols
DESC: Using Symbols
DESC: Special Fonts
diffmk: Miscellaneous

E
ec.tmac: Input Encodings
en.tmac: Manipulating Hyphenation
eqn: ms Insertions

F
fr.tmac: Manipulating Hyphenation
freeeuro.pfa: Input Encodings

G
gchem: Groff Options
gdiffmk: Miscellaneous
geqn: Groff Options
ggrn: Groff Options
gpic: Groff Options
grap: Groff Options
grefer: Groff Options
groff: Groff Options
gsoelim: Groff Options
gtbl: Groff Options
gtroff: Groff Options

I
it.tmac: Manipulating Hyphenation

J
ja.tmac: Manipulating Hyphenation

L
latin1.tmac: Input Encodings
latin2.tmac: Input Encodings
latin5.tmac: Input Encodings
latin9.tmac: Input Encodings

M
makeindex: Indexing
man.local: Optional man extensions
man.tmac: man
man.ultrix: Optional man extensions

N
nrchbar: Miscellaneous

P
papersize.tmac: Paper Format
perl: I/O
pic: ms Insertions
post-grohtml: Groff Options
pre-grohtml: Groff Options
preconv: Groff Options

R
refer: ms Insertions

S
soelim: Debugging
sv.tmac: Manipulating Hyphenation

T
tbl: ms Insertions
trace.tmac: Writing Macros
troffrc: Groff Options
troffrc: Paper Format
troffrc: Manipulating Hyphenation
troffrc: Manipulating Hyphenation
troffrc: troff and nroff Modes
troffrc-end: Groff Options
troffrc-end: Manipulating Hyphenation
troffrc-end: troff and nroff Modes
tty.tmac: troff and nroff Modes
tty.tmac: Line Layout

V
vtroff: Operators in Conditionals

Z
zh.tmac: Manipulating Hyphenation

+ +
+ + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Punning-Names.html b/doc/groff.html.node/Punning-Names.html new file mode 100644 index 0000000..dde1a20 --- /dev/null +++ b/doc/groff.html.node/Punning-Names.html @@ -0,0 +1,190 @@ + + + + + + +Punning Names (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.30 Punning Names

+ + +

Macros, strings, and diversions share a name space; recall +Identifiers. Internally, the same mechanism is used to store +them. You can thus call a macro with string interpolation syntax and +vice versa. +

+
+
.de subject
+Typesetting
+..
+.de predicate
+rewards attention to detail
+..
+\*[subject] \*[predicate].
+Truly.
+    ⇒ Typesetting
+    ⇒  rewards attention to detail Truly.
+
+ +

What went wrong? Strings don’t contain newlines, but macros do. String +interpolation placed a newline at the end of ‘\*[subject]’, and the +next thing on the input was a space. Then when ‘\*[predicate]’ was +interpolated, it was followed by the empty request ‘.’ on a line by +itself. If we want to use macros as strings, we must take interpolation +behavior into account. +

+
+
.de subject
+Typesetting\\
+..
+.de predicate
+rewards attention to detail\\
+..
+\*[subject] \*[predicate].
+Truly.
+    ⇒ Typesetting rewards attention to detail.  Truly.
+
+ +

By ending each text line of the macros with an escaped +\RET, we get the desired effect (see Line Continuation).114 +What would have happened if we had used only one backslash at a time +instead? +

+

Interpolating a string does not hide existing macro arguments. We can +also place the escaped newline outside the string interpolation instead +of within the string definition. Thus, in a macro, a more efficient way +of doing +

+
+
.xx \\$@
+
+ +

is +

+
+
\\*[xx]\\
+
+ +

The latter calling syntax doesn’t change the value of \$0, which +is then inherited from the calling macro (see Parameters). +

+

Diversions can be also called with string syntax. It is sometimes +convenient to copy one-line diversions to a string. +

+
+
.di xx
+the
+.ft I
+interpolation system
+.ft
+.br
+.di
+.ds yy This is a test of \*(xx\c
+\*(yy.
+    ⇒ This is a test of the interpolation system.
+
+ +

As the previous example shows, it is possible to store formatted output +in strings. The \c escape sequence prevents the subsequent +newline from being interpreted as a break (again, +see Line Continuation). +

+

Copying multi-output line diversions produces unexpected results. +

+
+
.di xxx
+a funny
+.br
+test
+.br
+.di
+.ds yyy This is \*[xxx]\c
+\*[yyy].
+    ⇒ test This is a funny.
+
+ +

Usually, it is not predictable whether a diversion contains one or more +output lines, so this mechanism should be avoided. With AT&T +troff, this was the only solution to strip off a final newline +from a diversion. Another disadvantage is that the spaces in the copied +string are already formatted, preventing their adjustment. This can +cause ugly results. +

+ + + + + + + +

A clean solution to this problem is available in GNU troff, using +the requests chop to remove the final newline of a diversion, and +unformat to make the horizontal spaces adjustable again. +

+
+
.box xxx
+a funny
+.br
+test
+.br
+.box
+.chop xxx
+.unformat xxx
+This is \*[xxx].
+    ⇒ This is a funny test.
+
+ +

See gtroff Internals. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Register-Index.html b/doc/groff.html.node/Register-Index.html new file mode 100644 index 0000000..979a346 --- /dev/null +++ b/doc/groff.html.node/Register-Index.html @@ -0,0 +1,349 @@ + + + + + + +Register Index (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

Appendix E Register Index

+ +

The macro package or program a specific register belongs to is appended +in brackets. +

+

A register name x consisting of exactly one character can be +accessed as ‘\nx’. A register name xx consisting of exactly +two characters can be accessed as ‘\n(xx’. Register names +xxx of any length can be accessed as ‘\n[xxx]’. +

+
+
Jump to:   $ +   +% +   +. +   +
+C +   +D +   +F +   +G +   +H +   +L +   +M +   +N +   +O +   +P +   +Q +   +R +   +S +   +T +   +U +   +V +   +Y +   +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

$
$$: Built-in Registers

%
%: Page Layout
%: Page Control

.
.$: Parameters
.A: Built-in Registers
.a: Manipulating Spacing
.b: Artificial Fonts
.br: Control Characters
.c: Built-in Registers
.C: Compatibility Mode
.cdp: Environments
.ce: Manipulating Filling and Adjustment
.cht: Environments
.color: Colors
.cp: Compatibility Mode
.csk: Environments
.d: Diversions
.ev: Environments
.F: Built-in Registers
.f: Font Positions
.fam: Font Families
.fn: Selecting Fonts
.fp: Font Positions
.g: Built-in Registers
.H: Motion Quanta
.h: Diversions
.height: Artificial Fonts
.hla: Manipulating Hyphenation
.hlc: Manipulating Hyphenation
.hlm: Manipulating Hyphenation
.hy: Manipulating Hyphenation
.hym: Manipulating Hyphenation
.hys: Manipulating Hyphenation
.i: Line Layout
.in: Line Layout
.int: Line Continuation
.j: Manipulating Filling and Adjustment
.k: Page Motions
.kern: Ligatures and Kerning
.L: Manipulating Spacing
.l: Line Layout
.lg: Ligatures and Kerning
.linetabs: Tabs and Fields
.ll: Line Layout
.lt: Page Layout
.m: Colors
.M: Colors
.n: Environments
.ne: Page Location Traps
.nm: Miscellaneous
.nn: Miscellaneous
.ns: Manipulating Spacing
.o: Line Layout
.O: Suppressing Output
.P: Built-in Registers
.p: Page Layout
.pe: Page Location Traps
.pn: Page Layout
.ps: Using Fractional Type Sizes
.psr: Using Fractional Type Sizes
.pvs: Changing the Vertical Spacing
.R: Built-in Registers
.rj: Manipulating Filling and Adjustment
.s: Changing the Type Size
.slant: Artificial Fonts
.sr: Using Fractional Type Sizes
.ss: Manipulating Filling and Adjustment
.sss: Manipulating Filling and Adjustment
.sty: Font Families
.T: Built-in Registers
.t: Page Location Traps
.tabs: Tabs and Fields
.trunc: Page Location Traps
.U: Built-in Registers
.u: Manipulating Filling and Adjustment
.V: Motion Quanta
.v: Changing the Vertical Spacing
.vpt: Vertical Position Traps
.w: Environments
.warn: Debugging
.x: Built-in Registers
.y: Built-in Registers
.Y: Built-in Registers
.z: Diversions
.zoom: Selecting Fonts

C
c.: Built-in Registers
ct: Page Motions

D
DD [ms]: ms Document Control Settings
DI [ms]: ms Document Control Settings
dl: Diversions
dn: Diversions
dw: Built-in Registers
dy: Built-in Registers

F
FF [ms]: ms Document Control Settings
FI [ms]: ms Document Control Settings
FM [ms]: ms Document Control Settings
FPD [ms]: ms Document Control Settings
FPS [ms]: ms Document Control Settings
FVS [ms]: ms Document Control Settings

G
GROWPS [ms]: ms Document Control Settings
GS [ms]: Differences from AT&T ms

H
HM [ms]: ms Document Control Settings
HORPHANS [ms]: ms Document Control Settings
hours: Built-in Registers
hp: Page Motions
HY [ms]: ms Document Control Settings

L
LL [ms]: ms Document Control Settings
llx: Miscellaneous
lly: Miscellaneous
ln: Miscellaneous
lsn: Leading Space Traps
lss: Leading Space Traps
LT [ms]: ms Document Control Settings

M
MINGW [ms]: ms Document Control Settings
minutes: Built-in Registers
mo: Built-in Registers

N
nl: Page Control

O
opmaxx: Suppressing Output
opmaxy: Suppressing Output
opminx: Suppressing Output
opminy: Suppressing Output

P
PD [ms]: ms Document Control Settings
PI [ms]: ms Document Control Settings
PO [ms]: ms Document Control Settings
PORPHANS [ms]: ms Document Control Settings
PS [ms]: ms Document Control Settings
PSINCR [ms]: ms Document Control Settings

Q
QI [ms]: ms Document Control Settings

R
rsb: Page Motions
rst: Page Motions

S
sb: Page Motions
seconds: Built-in Registers
skw: Page Motions
slimit: Debugging
ssc: Page Motions
st: Page Motions
systat: I/O

T
TC-MARGIN [ms]: ms Document Control Settings

U
urx: Miscellaneous
ury: Miscellaneous

V
VS [ms]: ms Document Control Settings

Y
year: Built-in Registers
yr: Built-in Registers

+ +
+ + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Registers.html b/doc/groff.html.node/Registers.html new file mode 100644 index 0000000..6f33d51 --- /dev/null +++ b/doc/groff.html.node/Registers.html @@ -0,0 +1,65 @@ + + + + + + +Registers (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.8 Registers

+ + +

In the roff language, numbers can be stored in registers. +Many built-in registers exist, supplying anything from the date to +details of formatting parameters. You can also define your own. +See Identifiers, for information on constructing a valid name for a +register. +

+ + + +
+ + + + + diff --git a/doc/groff.html.node/Request-Index.html b/doc/groff.html.node/Request-Index.html new file mode 100644 index 0000000..dc328f2 --- /dev/null +++ b/doc/groff.html.node/Request-Index.html @@ -0,0 +1,394 @@ + + + + + + +Request Index (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

Appendix B Request Index

+ +

Request names appear without a leading control character; the defaults +are . for the regular control character and ' for the +no-break control character. +

+
+
Jump to:   A +   +B +   +C +   +D +   +E +   +F +   +G +   +H +   +I +   +K +   +L +   +M +   +N +   +O +   +P +   +R +   +S +   +T +   +U +   +V +   +W +   +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

A
ab: Debugging
ad: Manipulating Filling and Adjustment
af: Assigning Register Formats
aln: Setting Registers
als: Strings
am: Writing Macros
am1: Writing Macros
ami: Writing Macros
ami1: Writing Macros
as: Strings
as1: Strings
asciify: Diversions

B
backtrace: Debugging
bd: Artificial Fonts
blm: Blank Line Traps
box: Diversions
boxa: Diversions
bp: Page Control
br: Manipulating Filling and Adjustment
break: while
brp: Manipulating Filling and Adjustment

C
c2: Control Characters
cc: Control Characters
ce: Manipulating Filling and Adjustment
cf: I/O
cflags: Using Symbols
ch: Page Location Traps
char: Using Symbols
chop: Strings
class: Character Classes
close: I/O
color: Colors
composite: Using Symbols
continue: while
cp: Compatibility Mode
cs: Artificial Fonts
cu: Artificial Fonts

D
da: Diversions
de: Writing Macros
de1: Writing Macros
defcolor: Colors
dei: Writing Macros
dei1: Writing Macros
device: Postprocessor Access
devicem: Postprocessor Access
di: Diversions
do: Compatibility Mode
ds: ms Document Control Settings
ds: Strings
ds1: Strings
dt: Diversion Traps

E
ec: Using Escape Sequences
ecr: Using Escape Sequences
ecs: Using Escape Sequences
el: if-else
em: End-of-input Traps
eo: Using Escape Sequences
ev: Environments
evc: Environments
ex: Debugging

F
fam: Font Families
fc: Fields
fchar: Using Symbols
fcolor: Colors
fi: Manipulating Filling and Adjustment
fl: Debugging
fp: Font Positions
fschar: Using Symbols
fspecial: Special Fonts
ft: Selecting Fonts
ftr: Selecting Fonts
fzoom: Selecting Fonts

G
gcolor: Colors

H
hc: Manipulating Hyphenation
hcode: Manipulating Hyphenation
hla: Manipulating Hyphenation
hlm: Manipulating Hyphenation
hpf: Manipulating Hyphenation
hpfa: Manipulating Hyphenation
hpfcode: Manipulating Hyphenation
hw: Manipulating Hyphenation
hy: Manipulating Hyphenation
hym: Manipulating Hyphenation
hys: Manipulating Hyphenation

I
ie: if-else
if: if-then
ig: Comments
in: Line Layout
it: Input Line Traps
itc: Input Line Traps

K
kern: Ligatures and Kerning

L
lc: Leaders
length: Strings
lf: Debugging
lg: Ligatures and Kerning
linetabs: Tabs and Fields
ll: Line Layout
ls: Manipulating Spacing
lsm: Leading Space Traps
lt: Page Layout

M
mc: Miscellaneous
mk: Page Motions
mso: I/O
msoquiet: I/O

N
na: Manipulating Filling and Adjustment
ne: Page Control
nf: Manipulating Filling and Adjustment
nh: Manipulating Hyphenation
nm: Miscellaneous
nn: Miscellaneous
nop: if-then
nr: ms Document Control Settings
nr: Setting Registers
nr: Setting Registers
nr: Auto-increment
nroff: troff and nroff Modes
ns: Manipulating Spacing
nx: I/O

O
open: I/O
opena: I/O
os: Page Control
output: Diversions

P
pc: Page Layout
pev: Debugging
pi: I/O
pl: Page Layout
pm: Debugging
pn: Page Layout
pnr: Debugging
po: Line Layout
ps: Changing the Type Size
psbb: Miscellaneous
pso: I/O
ptr: Debugging
pvs: Changing the Vertical Spacing

R
rchar: Using Symbols
rd: I/O
return: Writing Macros
rfschar: Using Symbols
rj: Manipulating Filling and Adjustment
rm: Strings
rn: Strings
rnn: Setting Registers
rr: Setting Registers
rs: Manipulating Spacing
rt: Page Motions

S
schar: Using Symbols
shc: Manipulating Hyphenation
shift: Parameters
sizes: Changing the Type Size
so: I/O
soquiet: I/O
sp: Manipulating Spacing
special: Special Fonts
spreadwarn: Debugging
ss: Manipulating Filling and Adjustment
stringdown: Strings
stringup: Strings
sty: Font Families
substring: Strings
sv: Page Control
sy: I/O

T
ta: Tabs and Fields
tag: Postprocessor Access
taga: Postprocessor Access
tc: Tabs and Fields
ti: Line Layout
tkf: Ligatures and Kerning
tl: Page Layout
tm: Debugging
tm1: Debugging
tmc: Debugging
tr: Character Translations
trf: I/O
trin: Character Translations
trnt: Character Translations
troff: troff and nroff Modes

U
uf: Artificial Fonts
ul: Artificial Fonts
unformat: Diversions

V
vpt: Vertical Position Traps
vs: Changing the Vertical Spacing

W
warn: Debugging
warnscale: Debugging
wh: Page Location Traps
while: while
write: I/O
writec: I/O
writem: I/O

+ +
+ + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Requests-and-Macros.html b/doc/groff.html.node/Requests-and-Macros.html new file mode 100644 index 0000000..8a009b3 --- /dev/null +++ b/doc/groff.html.node/Requests-and-Macros.html @@ -0,0 +1,221 @@ + + + + + + +Requests and Macros (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.1.7 Requests and Macros

+ +

We have now encountered almost all of the syntax there is in the +roff language, with an exception already noted in passing. + + + + + + +A request is an instruction to the formatter that occurs after a +control character, which is recognized at the beginning of an +input line. The regular control character is a dot (.). Its +counterpart, the no-break control character, a neutral apostrophe +('), suppresses the break that is implied by some requests. +These characters were chosen because it is uncommon for lines of text in +natural languages to begin with them. + + +If you require a formatted period or apostrophe (closing single +quotation mark) where GNU troff is expecting a control character, +prefix the dot or neutral apostrophe with the dummy character escape +sequence, ‘\&’. +

+ +

An input line beginning with a control character is called a +control line. + +Every line of input that is not a control line is a text +line.25 +

+ +

Requests often take arguments, words (separated from the request +name and each other by spaces) that specify details of the action GNU +troff is expected to perform. If a request is meaningless +without arguments, it is typically ignored. +

+

GNU troff’s requests and escape sequences comprise the control +language of the formatter. Of key importance are the requests that +define macros. Macros are invoked like requests, enabling the request +repertoire to be extended or overridden.26 +

+ + + +

A macro can be thought of as an abbreviation you can define for a +collection of control and text lines. When the macro is called by +giving its name after a control character, it is replaced with what it +stands for. The process of textual replacement is known as +interpolation.27 Interpolations are handled as soon as they are +recognized, and once performed, a roff formatter scans the +replacement for further requests, macro calls, and escape sequences. +

+

In roff systems, the de request defines a +macro.28 +

+
+
.de DATE
+2020-11-14
+..
+
+ +

The foregoing input produces no output by itself; all we have done is +store some information. Observe the pair of dots that ends the macro +definition. This is a default; you can specify your own terminator for +the macro definition as the second argument to the de request. +

+
+
.de NAME ENDNAME
+Heywood Jabuzzoff
+.ENDNAME
+
+ +

In fact, the ending marker is itself the name of a macro to be +called, or a request to be invoked, if it is defined at the time its +control line is read. +

+
+
.de END
+Big Rip
+..
+.de START END
+Big Bang
+.END
+.START
+    ⇒ Big Rip Big Bang
+
+ +

In the foregoing example, “Big Rip” printed before “Big Bang” +because its macro was called first. Consider what would happen +if we dropped END from the ‘.de START’ line and added +.. after .END. Would the order change? +

+

Let us consider a more elaborate example. +

+
+
.de DATE
+2020-10-05
+..
+.
+.de BOSS
+D.\& Kruger,
+J.\& Peterman
+..
+.
+.de NOTICE
+Approved:
+.DATE
+by
+.BOSS
+..
+.
+Insert tedious regulatory compliance paragraph here.
+
+.NOTICE
+
+Insert tedious liability disclaimer paragraph here.
+
+.NOTICE
+    ⇒ Insert tedious regulatory compliance paragraph here.
+    ⇒
+    ⇒ Approved: 2020-10-05 by D. Kruger, J. Peterman
+    ⇒
+    ⇒ Insert tedious liability disclaimer paragraph here.
+    ⇒
+    ⇒ Approved: 2020-10-05 by D. Kruger, J. Peterman
+
+ +

The above document started with a series of control lines. Three macros +were defined, with a de request declaring each macro’s name, and +the “body” of the macro starting on the next line and continuing until +a line with two dots ‘..’ marked its end. The text proper +began only after the macros were defined; this is a common pattern. +Only the NOTICE macro was called “directly” by the document; +DATE and BOSS were called only by NOTICE itself. +Escape sequences were used in BOSS, two levels of macro +interpolation deep. +

+

The advantage in typing and maintenance economy may not be obvious from +such a short example, but imagine a much longer document with dozens of +such paragraphs, each requiring a notice of managerial approval. +Consider what must happen if you are in charge of generating a new +version of such a document with a different date, for a different boss. +With well-chosen macros, you only have to change each datum in one +place. +

+

In practice, we would probably use strings (see Strings) instead of +macros for such simple interpolations; what is important here is to +glimpse the potential of macros and the power of recursive +interpolation. +

+

We could have defined DATE and BOSS in the opposite order; +perhaps less obviously, we could also have defined them after +NOTICE. “Forward references” like this are acceptable because +the body of a macro definition is not (completely) interpreted, but +stored instead (see Copy Mode). While a macro is being defined (or +appended to), requests are not interpreted and macros not interpolated, +whereas some commonly used escape sequences are interpreted. +roff systems also support recursive macro calls, as long as you +have a way to break the recursion (see Conditionals and Loops). +Maintainable roff documents tend to arrange macro definitions to +minimize forward references. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Safer-Mode.html b/doc/groff.html.node/Safer-Mode.html new file mode 100644 index 0000000..eca3efd --- /dev/null +++ b/doc/groff.html.node/Safer-Mode.html @@ -0,0 +1,61 @@ + + + + + + +Safer Mode (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.38.1 Safer Mode

+ + + + + +

The formatter operates in “safer” mode by default; to mitigate risks +from untrusted input documents, the pi and sy requests are +disabled. GNU troff’s -U option enables “unsafe +mode”, restoring their function and enabling additional groff +extension requests, open, opena, and pso. +See I/O. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Sections-and-Chapters.html b/doc/groff.html.node/Sections-and-Chapters.html new file mode 100644 index 0000000..b94de73 --- /dev/null +++ b/doc/groff.html.node/Sections-and-Chapters.html @@ -0,0 +1,56 @@ + + + + + + +Sections and Chapters (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

3.2.2 Sections and Chapters

+ +

The simplest kind of section heading is unnumbered, set in a bold or +italic style, and occupies a line by itself. Others possess +automatically numbered multi-level headings and/or different typeface +styles or sizes at different levels. More sophisticated macro packages +supply macros for designating chapters and appendices. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Selecting-Fonts.html b/doc/groff.html.node/Selecting-Fonts.html new file mode 100644 index 0000000..d6a59e7 --- /dev/null +++ b/doc/groff.html.node/Selecting-Fonts.html @@ -0,0 +1,227 @@ + + + + + + +Selecting Fonts (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.19.1 Selecting Fonts

+ + +

We use font to refer to any of several means of identifying a +font: by mounting position (‘3’), by abstract style (‘B’), or +by its identifier (‘TB’). +

+
+
Request: .ft [font]
+
+
Escape sequence: \ff
+
+
Escape sequence: \f(fn
+
Escape sequence: \f[font]
+
Register: \n[.fn]
+
+ + + + + + + + + + + +

The ft request selects the typeface font. If the argument +is absent or ‘P’, it selects the previously chosen font. If +font is a non-negative integer, it is interpreted as mounting +position; the font mounted there is selected. If that position refers +to an abstract style, it is combined with the default family (see +fam and \F below) to make a resolved font name. If the +mounting position is not a style and no font is mounted there, GNU +troff emits a warning in category ‘font’ and ignores the +request. +

+

If font matches a style name, it is combined with the current +family to make a resolved font name. Otherwise, font is assumed +to already be a resolved font name. +

+ + + +

The resolved font name is subject to translation (see request ftr +below). Next, the (possibly translated) font name’s mounting position +is looked up; if not mounted, font is sought on the file system as +a font description file and, if located, automatically mounted at the +next available position (see register .fp below). If the font +was mounted using an identifier different from its font description file +name (see request fp below), that file name is then looked up. +If a font description file for the resolved font name is not found, GNU +troff emits a warning in category ‘font’ and ignores the +request. +

+

The \f escape sequence is similar, using one-character name (or +mounting position) f, two-character name fn, or a name +font of arbitrary length. + + +‘\f[]’ selects the previous font. The syntax form ‘\fP’ is +supported for backward compatibility, and ‘\f[P]’ for consistency. +

+
+
eggs, bacon,
+.ft I
+spam,
+.ft
+and sausage.
+.br
+eggs, bacon, \fIspam,\fP and sausage.
+    ⇒ eggs, bacon, spam, and sausage
+    ⇒ eggs, bacon, spam, and sausage
+
+ +

The current and previously selected fonts are properties of the +environment (see Environments). +

+

The read-only string-valued register .fn contains the resolved +font name of the selected font. +

+

\f doesn’t produce an input token in GNU troff; it thus +can be used in requests that expect a single-character argument. We can +assign a font to a margin character as follows (see Miscellaneous). +

+
+
.mc \f[I]x\f[]
+
+
+ +
+
Request: .ftr f [g]
+
+ + + + + + + + + + + + + + +

Translate font f to font g. Whenever a font +named f is referred to in a \f escape sequence, in the +F and S conditional operators, or in the ft, +ul, bd, cs, tkf, special, +fspecial, fp, or sty requests, font g is +used. If g is missing or equal to f the translation is +undone. +

+

Font translations cannot be chained. +

+
+
.ftr XXX TR
+.ftr XXX YYY
+.ft XXX
+    error→ warning: can't find font 'XXX'
+
+
+ +
+
Request: .fzoom f [zoom]
+
+
Register: \n[.zoom]
+
+ + + + + + + + +

Set magnification of font f to factor zoom, which must +be a non-negative integer multiple of 1/1000th. This request is useful +to adjust the optical size of a font in relation to the others. In the +example below, font CR is magnified by 10% (the zoom factor is +thus 1.1). +

+
+
.fam P
+.fzoom CR 1100
+.ps 12
+Palatino and \f[CR]Courier\f[]
+
+ +

A missing or zero value of zoom is the same as a value of 1000, +which means no magnification. f must be a resolved font +name, not an abstract style. +

+

The magnification of a font is completely transparent to GNU +troff; a change of the zoom factor doesn’t cause any effect +except that the dimensions of glyphs, (word) spaces, kerns, etc., of the +affected font are adjusted accordingly. +

+

The zoom factor of the current font is available in the read-only +register ‘.zoom’, in multiples of 1/1000th. It returns zero if +there is no magnification. +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Sentences.html b/doc/groff.html.node/Sentences.html new file mode 100644 index 0000000..47d7462 --- /dev/null +++ b/doc/groff.html.node/Sentences.html @@ -0,0 +1,174 @@ + + + + + + +Sentences (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.1.2 Sentences

+ + +

A passionate debate has raged for decades among writers of the English +language over whether more space should appear between adjacent +sentences than between words within a sentence, and if so, how much, and +what other circumstances should influence this spacing.20 +GNU troff follows the example of AT&T troff; +it attempts to detect the boundaries between sentences, and supplies +additional inter-sentence space between them. +

+
+
Hello, world!
+Welcome to groff.
+    ⇒ Hello, world!  Welcome to groff.
+
+ + + + + +

GNU troff flags certain characters (normally ‘!’, ‘?’, +and ‘.’) as potentially ending a sentence. When GNU troff +encounters one of these end-of-sentence characters at the end of +an input line, or one of them is followed by two (unescaped) spaces on +the same input line, it appends an inter-word space followed by an +inter-sentence space in the output. +

+
+
R. Harper subscribes to a maxim of P. T. Barnum.
+    ⇒ R. Harper subscribes to a maxim of P. T. Barnum.
+
+ +

In the above example, inter-sentence space is not added after ‘P.’ +or ‘T.’ because the periods do not occur at the end of an input +line, nor are they followed by two or more spaces. Let’s imagine that +we’ve heard something about defamation from Mr. Harper’s attorney, +recast the sentence, and reflowed it in our text editor. +

+
+
I submit that R. Harper subscribes to a maxim of P. T.
+Barnum.
+    ⇒ I submit that R. Harper subscribes to a maxim of
+    ⇒ P. T.  Barnum.
+
+ +

“Barnum” doesn’t begin a sentence! What to do? Let us meet our first +escape sequence, a series of input characters that give +instructions to GNU troff instead of being used to construct +output device glyphs.21 An escape sequence begins with the backslash character \ +by default, an uncommon character in natural language text, and is +always followed by at least one other character, hence the term +“sequence”. +

+ +

The dummy character escape sequence \& can be used after an +end-of-sentence character to defeat end-of-sentence detection on a +per-instance basis. We can therefore rewrite our input more +defensively. +

+
+
I submit that R.\& Harper subscribes to a maxim of P.\&
+T.\& Barnum.
+    ⇒ I submit that R. Harper subscribes to a maxim of
+    ⇒ P. T. Barnum.
+
+ +

Adding text caused our input to wrap; now, we don’t need \& after +‘T.’ but we do after ‘P.’. Consistent use of the escape +sequence ensures that potential sentence boundaries are robust to +editing activities. Further advice along these lines will follow in +Input Conventions. +

+ + + + + + + + + + + + + +

Normally, the occurrence of a visible non-end-of-sentence character (as +opposed to a space or tab) immediately after an end-of-sentence +character cancels detection of the end of a sentence. For example, it +would be incorrect for GNU troff to infer the end of a sentence +after the dot in ‘3.14159’. However, several characters are +treated transparently after the occurrence of an end-of-sentence +character. That is, GNU troff does not cancel end-of-sentence +detection when it processes them. This is because such characters are +often used as footnote markers or to close quotations and +parentheticals. The default set is ‘"’, ‘'’, ‘)’, +‘]’, ‘*’, \[dg], \[dd], \[rq], and +\[cq]. The last four are examples of special characters, +escape sequences whose purpose is to obtain glyphs that are not easily +typed at the keyboard, or which have special meaning to GNU troff +(like \ itself).22 +

+
+
\[lq]The idea that the poor should have leisure has always
+been shocking to the rich.\[rq]
+(Bertrand Russell, 1935)
+    ⇒ "The idea that the poor should have
+    ⇒ leisure has always been shocking to
+    ⇒ the rich."  (Bertrand Russell, 1935)
+
+ +

The sets of characters that potentially end sentences or are transparent +to sentence endings are configurable. See the cflags request in +Using Symbols. To change the additional inter-sentence space +amount—even to remove it entirely—see Manipulating Filling and Adjustment. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Separation.html b/doc/groff.html.node/Separation.html new file mode 100644 index 0000000..d7dfe3e --- /dev/null +++ b/doc/groff.html.node/Separation.html @@ -0,0 +1,94 @@ + + + + + + +Separation (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

6.1.1.1 Separation

+ +

AT&T troff output has strange requirements regarding +whitespace. The gtroff output parser, however, is more tolerant, +making whitespace maximally optional. Such characters, i.e., the tab, +space, and newline, always have a syntactical meaning. They are never +printable because spacing within the output is always done by +positioning commands. +

+

Any sequence of space or tab characters is treated as a single +syntactical space. It separates commands and arguments, but is +only required when there would occur a clashing between the command code +and the arguments without the space. Most often, this happens when +variable-length command names, arguments, argument lists, or command +clusters meet. Commands and arguments with a known, fixed length need +not be separated by syntactical space. +

+

A line break is a syntactical element, too. Every command argument can +be followed by whitespace, a comment, or a newline character. Thus a +syntactical line break is defined to consist of optional +syntactical space that is optionally followed by a comment, and a +newline character. +

+

The normal commands, those for positioning and text, consist of a single +letter taking a fixed number of arguments. For historical reasons, the +parser allows stacking of such commands on the same line, but +fortunately, in gtroff’s intermediate output, every command with +at least one argument is followed by a line break, thus providing +excellent readability. +

+

The other commands—those for drawing and device controlling—have a +more complicated structure; some recognize long command names, and some +take a variable number of arguments. So all ‘D’ and ‘x’ +commands were designed to request a syntactical line break after their +last argument. Only one command, ‘x X, has an argument that +can span several input lines; all other commands must have all of +their arguments on the same line as the command, i.e., the arguments may +not be split by a line break. +

+

Empty lines (these are lines containing only space and/or a comment), +can occur everywhere. They are just ignored. +

+
+
+ + + + + + diff --git a/doc/groff.html.node/Setting-Registers.html b/doc/groff.html.node/Setting-Registers.html new file mode 100644 index 0000000..6fdf746 --- /dev/null +++ b/doc/groff.html.node/Setting-Registers.html @@ -0,0 +1,215 @@ + + + + + + +Setting Registers (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.8.1 Setting Registers

+ + + +

Define registers and update their values with the nr request or +the \R escape sequence. +

+
+
Request: .nr ident value
+
+
Escape sequence: \R'ident value'
+
+

Set register ident to value. If ident doesn’t exist, +GNU troff creates it. In the \R escape sequence, the +delimiter need not be a neutral apostrophe; see Delimiters. It +also does not produce an input token in GNU troff. See gtroff Internals. +

+
+
.nr a (((17 + (3 * 4))) % 4)
+\n[a]
+.\R'a (((17 + (3 * 4))) % 4)'
+\n[a]
+    ⇒ 1 1
+
+ +

(Later, we will discuss additional forms of nr and \R that +can change a register’s value after it is dereferenced but before it is +interpolated. See Auto-increment.) +

+

The complete transparency of \R can cause surprising effects if +you use registers like .k, which get evaluated at the time they +are accessed. +

+
+
.ll 1.6i
+.
+aaa bbb ccc ddd eee fff ggg hhh\R':k \n[.k]'
+.tm :k == \n[:k]
+    ⇒ :k == 126950
+.
+.br
+.
+aaa bbb ccc ddd eee fff ggg hhh\h'0'\R':k \n[.k]'
+.tm :k == \n[:k]
+    ⇒ :k == 15000
+
+ +

If you process this with the PostScript device (-Tps), there will +be a line break eventually after ggg in both input lines. +However, after processing the space after ggg, the partially +collected line is not overfull yet, so GNU troff continues to +collect input until it sees the space (or in this case, the newline) +after hhh. At this point, the line is longer than the line +length, and the line gets broken. +

+

In the first input line, since the \R escape sequence leaves no +traces, the check for the overfull line hasn’t been done yet at the +point where \R gets handled, and you get a value for the +.k register that is even greater than the current line length. +

+

In the second input line, the insertion of \h'0' to cause a +zero-width motion forces GNU troff to check the line length, +which in turn causes the start of a new output line. Now .k +returns the expected value. +

+ +

nr and \R each have two additional special forms to +increment or decrement a register. +

+
+
Request: .nr ident +value
+
+
Request: .nr ident -value
+
Escape sequence: \R'ident +value'
+
+
Escape sequence: \R'ident -value'
+

Increment (decrement) register ident by value. In the +\R escape sequence, the delimiter need not be a neutral +apostrophe; see Delimiters. +

+
+
.nr a 1
+.nr a +1
+\na
+    ⇒ 2
+
+ + +

A leading minus sign in value is always interpreted as a +decrementation operator, not an algebraic sign. To assign a register a +negative value or the negated value of another register, you can +force GNU troff to interpret ‘-’ as a negation or minus, +rather than decrementation, operator: enclose it with its operand in +parentheses or subtract it from zero. +

+
+
.nr a 7
+.nr b 3
+.nr a -\nb
+\na
+    ⇒ 4
+.nr a (-\nb)
+\na
+    ⇒ -3
+.nr a 0-\nb
+\na
+    ⇒ -3
+
+ +

If a register’s prior value does not exist (the register was undefined), +an increment or decrement is applied as if to 0. +

+ +
+
Request: .rr ident
+
+ + +

Remove register ident. If ident doesn’t exist, the request +is ignored. Technically, only the name is removed; the register’s +contents are still accessible under aliases created with aln, if +any. +

+ +
+
Request: .rnn ident1 ident2
+
+ + +

Rename register ident1 to ident2. If ident1 doesn’t +exist, the request is ignored. Renaming a built-in register does not +otherwise alter its properties. +

+ +
+
Request: .aln new old
+
+ + + +

Create an alias new for an existing register old, causing +the names to refer to the same stored object. If old is +undefined, a warning in category ‘reg’ is produced and the request +is ignored. See Warnings, for information about the enablement and +suppression of warnings. +

+ + + +

To remove a register alias, invoke rr on its name. A register’s +contents do not become inaccessible until it has no more names. +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Simple-Commands.html b/doc/groff.html.node/Simple-Commands.html new file mode 100644 index 0000000..b76b0a6 --- /dev/null +++ b/doc/groff.html.node/Simple-Commands.html @@ -0,0 +1,207 @@ + + + + + + +Simple Commands (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

6.1.2.2 Simple Commands

+ +

The commands in this subsection have a command code consisting of a +single character, taking a fixed number of arguments. Most of them are +commands for positioning and text writing. These commands are tolerant +of whitespace. Optionally, syntactical space can be inserted before, +after, and between the command letter and its arguments. All of these +commands are stackable; i.e., they can be preceded by other simple +commands or followed by arbitrary other commands on the same line. A +separating syntactical space is necessary only when two integer +arguments would clash or if the preceding argument ends with a string +argument. +

+
+
C idwhitespace
+

Typeset the glyph of the special character id. Trailing +syntactical space is necessary to allow special character names of +arbitrary length. The drawing position is not advanced. +

+
+
c g
+

Typeset the glyph of the ordinary character c. The drawing +position is not advanced. +

+
+
f n
+

Select the font mounted at position n. n cannot +be negative. +

+
+
H n
+

Horizontally move the drawing position to n basic units from +the left edge of the page. n cannot be negative. +

+
+
h n
+

Move the drawing position right n basic units. AT&T +troff allowed negative n; GNU troff does not produce +such values, but groff’s output driver library handles them. +

+
+
m color-scheme [component]
+

Select the stroke color using the components in the color space +scheme. Each component is an integer between 0 and 65535. +The quantity of components and their meanings vary with each +scheme. This command is a groff extension. +

+
+
mc cyan magenta yellow
+

Use the CMY color scheme with components cyan, magenta, and yellow. +

+
+
md
+

Use the default color (no components; black in most cases). +

+
+
mg gray
+

Use a grayscale color scheme with a component ranging between 0 (black) +and 65535 (white). +

+
+
mk cyan magenta yellow black
+

Use the CMYK color scheme with components cyan, magenta, yellow, and +black. +

+
+
mr red green blue
+

Use the RGB color scheme with components red, green, and blue. +

+
+ +
+
N n
+

Typeset the glyph with index n in the current font. +n is normally a non-negative integer. The drawing position +is not advanced. The html and xhtml devices use this +command with negative n to produce unbreakable space; the +absolute value of n is taken and interpreted in basic units. +

+
+
n b a
+

Indicate a break. No action is performed; the command is present to +make the output more easily parsed. The integers b +and a describe the vertical space amounts before and after +the break, respectively. GNU troff issues this command but +groff’s output driver library ignores it. See v and +V below. +

+
+
p n
+

Begin a new page, setting its number to n. Each page is +independent, even from those using the same number. The vertical +drawing position is set to 0. All positioning, writing, and +drawing commands are interpreted in the context of a page, so a +p command must precede them. +

+
+
s n
+

Set type size to n scaled points (unit z in GNU +troff. +AT&T troff used unscaled points p instead; +see Output Language Compatibility. +

+
+
t xyzwhitespace
+
t xyz dummy-argwhitespace
+

Typeset a word xyz; that is, set a sequence of ordinary glyphs +named x, y, z, …, terminated by a space +character or a line break; an optional second integer argument is +ignored (this allows the formatter to generate an even number of +arguments). Each glyph is set at the current drawing position, and the position is +then advanced horizontally by the glyph’s width. A glyph’s width is +read from its metrics in the font description file, scaled to the +current type size, and rounded to a multiple of the horizontal motion +quantum. Use the C command to emplace glyphs of special +characters. The t command is a groff extension and +is output only for devices whose DESC file contains the +tcommand directive; see DESC File Format. +

+
+
u n xyzwhitespace
+

Typeset word xyz with track kerning. As t, but after +placing each glyph, the drawing position is further advanced +horizontally by n basic units (u). The +u command is a groff extension and is output only for +devices whose DESC file contains the tcommand directive; +see DESC File Format. +

+
+
V n
+

Vertically move the drawing position to n basic units from +the top edge of the page. n cannot be negative. +

+
+
v n
+

Move the drawing position down n basic units. AT&T +troff allowed negative n; GNU troff does not produce +such values, but groff’s output driver library handles them. +

+
+
w
+

Indicate an inter-word space. No action is performed; the command is +present to make the output more easily parsed. Only adjustable, +breakable inter-word spaces are thus described; those resulting from +\~ or horizontal motion escape sequences are not. GNU +troff issues this command but groff’s output driver +library ignores it. See h and H above. +

+
+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Special-Fonts.html b/doc/groff.html.node/Special-Fonts.html new file mode 100644 index 0000000..214c74e --- /dev/null +++ b/doc/groff.html.node/Special-Fonts.html @@ -0,0 +1,93 @@ + + + + + + +Special Fonts (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.19.6 Special Fonts

+ + + +

Special fonts are those that gtroff searches when it cannot find +the requested glyph in the current font. The Symbol font is usually a +special font. +

+

gtroff provides the following two requests to add more special +fonts. See Using Symbols, for a detailed description of the glyph +searching mechanism in gtroff. +

+

Usually, only non-TTY devices have special fonts. +

+
+
Request: .special [s1 s2 …]
+
+
Request: .fspecial f [s1 s2 …]
+
+ + +

Use the special request to define special fonts. Initially, this +list is empty. +

+

Use the fspecial request to designate special fonts only when +font f is active. Initially, this list is empty. +

+

Previous calls to special or fspecial are overwritten; +without arguments, the particular list of special fonts is set to empty. +Special fonts are searched in the order they appear as arguments. +

+

All fonts that appear in a call to special or fspecial +are loaded. +

+

See Using Symbols, for the exact search order of glyphs. +

+ + +
+ + + + + diff --git a/doc/groff.html.node/String-Index.html b/doc/groff.html.node/String-Index.html new file mode 100644 index 0000000..335d2b8 --- /dev/null +++ b/doc/groff.html.node/String-Index.html @@ -0,0 +1,344 @@ + + + + + + +String Index (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

Appendix G String Index

+ +

The macro package or program a that defines or uses each string is +appended in brackets. (Only one string, .T, is defined by the +troff formatter itself.) See Strings. +

+ +
+
Jump to:   ! +   +' +   +* +   +, +   +- +   +. +   +/ +   +3 +   +8 +   +: +   +< +   +> +   +? +   +^ +   +_ +   +` +   +{ +   +} +   +~ +   +
+A +   +C +   +D +   +F +   +L +   +M +   +O +   +Q +   +R +   +S +   +T +   +U +   +V +   +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

!
! [ms]: ms Legacy Features

'
' [ms]: ms Legacy Features
' [ms]: ms Legacy Features

*
* [ms]: ms Footnotes

,
, [ms]: ms Legacy Features
, [ms]: ms Legacy Features

-
- [ms]: Typographical symbols in ms

.
. [ms]: ms Legacy Features
.T: Strings
.T: Strings

/
/ [ms]: ms Legacy Features

3
3 [ms]: ms Legacy Features

8
8 [ms]: ms Legacy Features

:
: [ms]: ms Legacy Features
: [ms]: ms Legacy Features

<
< [ms]: Typeface and decoration

>
> [ms]: Typeface and decoration

?
? [ms]: ms Legacy Features

^
^ [ms]: ms Legacy Features
^ [ms]: ms Legacy Features

_
_ [ms]: ms Legacy Features

`
` [ms]: ms Legacy Features
` [ms]: ms Legacy Features

{
{ [ms]: Typeface and decoration

}
} [ms]: Typeface and decoration

~
~ [ms]: ms Legacy Features
~ [ms]: ms Legacy Features

A
ABSTRACT [ms]: ms language and localization
ae [ms]: ms Legacy Features
Ae [ms]: ms Legacy Features

C
C [ms]: ms Legacy Features
CF [ms]: ms Document Control Settings
CH [ms]: ms Document Control Settings

D
d- [ms]: ms Legacy Features
D- [ms]: ms Legacy Features

F
FAM [ms]: ms Document Control Settings
FR [ms]: ms Document Control Settings

L
LF [ms]: ms Document Control Settings
LH [ms]: ms Document Control Settings

M
MONTH1 [ms]: ms language and localization
MONTH10 [ms]: ms language and localization
MONTH11 [ms]: ms language and localization
MONTH12 [ms]: ms language and localization
MONTH2 [ms]: ms language and localization
MONTH3 [ms]: ms language and localization
MONTH4 [ms]: ms language and localization
MONTH5 [ms]: ms language and localization
MONTH6 [ms]: ms language and localization
MONTH7 [ms]: ms language and localization
MONTH8 [ms]: ms language and localization
MONTH9 [ms]: ms language and localization

O
o [ms]: ms Legacy Features
oe [ms]: ms Legacy Features
OE [ms]: ms Legacy Features

Q
Q [ms]: Typographical symbols in ms
q [ms]: ms Legacy Features

R
REFERENCES [ms]: ms language and localization
RF [ms]: ms Document Control Settings
RH [ms]: ms Document Control Settings

S
SN [ms]: Headings in ms
SN-DOT [ms]: Headings in ms
SN-NO-DOT [ms]: Headings in ms
SN-STYLE [ms]: ms Document Control Settings
SN-STYLE [ms]: Headings in ms

T
th [ms]: ms Legacy Features
Th [ms]: ms Legacy Features
TOC [ms]: ms language and localization

U
U [ms]: Typographical symbols in ms

V
v [ms]: ms Legacy Features

+ +
+ + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Strings.html b/doc/groff.html.node/Strings.html new file mode 100644 index 0000000..726e0b0 --- /dev/null +++ b/doc/groff.html.node/Strings.html @@ -0,0 +1,429 @@ + + + + + + +Strings (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.22 Strings

+ + +

GNU troff supports strings primarily for user convenience. +Conventionally, if one would define a macro only to interpolate a small +amount of text, without invoking requests or calling any other macros, +one defines a string instead. Only one string is predefined by the +language. +

+
+
String: \*[.T]
+
+ + +

Contains the name of the output device (for example, ‘utf8’ or +‘pdf’). +

+ +

The ds request creates a string with a specified name and +contents and the \* escape sequence dereferences its name, +interpolating its contents. If the string named by the \* escape +sequence does not exist, it is defined as empty, nothing is +interpolated, and a warning in category ‘mac’ is emitted. +See Warnings, for information about the enablement and suppression of +warnings. +

+
+
Request: .ds name [contents]
+
+
Request: .ds1 name [contents]
+
+
Escape sequence: \*n
+
+
Escape sequence: \*(nm
+
Escape sequence: \*[name [arg1 arg2 …]]
+
+ + + + + +

Define a string called name with contents contents. If +name already exists as an alias, the target of the alias is +redefined; see als and rm below. If ds is called +with only one argument, name is defined as an empty string. +Otherwise, GNU troff stores contents in copy +mode.87 +

+

The \* escape sequence interpolates a previously defined string +variable name (one-character name n, two-character name +nm). The bracketed interpolation form accepts arguments that are +handled as macro arguments are; recall Calling Macros. In +contrast to macro calls, however, if a closing bracket ‘]’ occurs +in a string argument, that argument must be enclosed in double quotes. +\* is interpreted even in copy mode. When defining strings, +argument interpolations must be escaped if they are to reference +parameters from the calling context; See Parameters. +

+
+
.ds cite (\\$1, \\$2)
+Gray codes are explored in \*[cite Morgan 1998].
+    ⇒ Gray codes are explored in (Morgan, 1998).
+
+ + + + + +

Caution: Unlike other requests, the second argument to the +ds request consumes the remainder of the input line, including +trailing spaces. This means that comments on a line with such a request +can introduce unwanted space into a string when they are set off from +the material they annotate, as is conventional. +

+
+
.ds H2O H\v'+.3m'\s'-2'2\v'-.3m'\s0O \" water
+
+ +

Instead, place the comment on another line or put the comment escape +sequence immediately adjacent to the last character of the string. +

+
+
.ds H2O H\v'+.3m'\s'-2'2\v'-.3m'\s0O\" water
+
+ +

Ending string definitions (and appendments) with a comment, even an +empty one, prevents unwanted space from creeping into them during source +document maintenance. +

+
+
.ds author Alice Pleasance Liddell\"
+.ds empty \" might be appended to later with .as
+
+ + + + + + + +

An initial neutral double quote " in contents is stripped +to allow embedding of leading spaces. Any other " is interpreted +literally, but it is wise to use the special character escape sequence +\[dq] instead if the string might be interpolated as part of a +macro argument; see Calling Macros. +

+
+
.ds salutation "         Yours in a white wine sauce,\"
+.ds c-var-defn "  char mydate[]=\[dq]2020-07-29\[dq];\"
+
+ + + + + +

Strings are not limited to a single input line of text. +\RET works just as it does elsewhere. The resulting string +is stored without the newlines. Care is therefore required when +interpolating strings while filling is disabled. +

+
+
.ds foo This string contains \
+text on multiple lines \
+of input.
+
+ +

It is not possible to embed a newline in a string that will be +interpreted as such when the string is interpolated. To achieve that +effect, use \* to interpolate a macro instead; see Punning Names. +

+

Because strings are similar to macros, they too can be defined so as to +suppress AT&T troff compatibility mode when used; see +Writing Macros and Compatibility Mode. The ds1 +request defines a string such that compatibility mode is off when the +string is later interpolated. To be more precise, a compatibility +save input token is inserted at the beginning of the string, and a +compatibility restore input token at the end. +

+
+
.nr xxx 12345
+.ds aa The value of xxx is \\n[xxx].
+.ds1 bb The value of xxx is \\n[xxx].
+.
+.cp 1
+.
+\*(aa
+    error→ warning: register '[' not defined
+    ⇒ The value of xxx is 0xxx].
+\*(bb
+    ⇒ The value of xxx is 12345.
+
+
+ +
+
Request: .as name [contents]
+
+
Request: .as1 name [contents]
+
+ + +

The as request is similar to ds but appends contents +to the string stored as name instead of redefining it. If +name doesn’t exist yet, it is created. If as is called +with only one argument, no operation is performed (beyond dereferencing +the string). +

+
+
.as salutation " with shallots, onions and garlic,\"
+
+ +

The as1 request is similar to as, but compatibility mode +is switched off when the appended portion of the string is later +interpolated. To be more precise, a compatibility save input +token is inserted at the beginning of the appended string, and a +compatibility restore input token at the end. +

+ +

Several requests exist to perform rudimentary string operations. +Strings can be queried (length) and modified (chop, +substring, stringup, stringdown), and their names +can be manipulated through renaming, removal, and aliasing (rn, +rm, als). +

+
+
Request: .length reg anything
+
+ + + + + +

Compute the number of characters of anything and store the count +in the register reg. If reg doesn’t exist, it is created. +anything is read in copy mode. +

+
+
.ds xxx abcd\h'3i'efgh
+.length yyy \*[xxx]
+\n[yyy]
+    ⇒ 14
+
+
+ +
+
Request: .chop object
+
+

Remove the last character from the macro, string, or diversion named +object. This is useful for removing the newline from the end of a +diversion that is to be interpolated as a string. This request can be +used repeatedly on the same object; see gtroff Internals, +for details on nodes inserted additionally by GNU troff. +

+ +
+
Request: .substring str start [end]
+
+ +

Replace the string named str with its substring bounded by the +indices start and end, inclusively. The first character in +the string has index 0. If end is omitted, it is implicitly +set to the largest valid value (the string length minus one). Negative +indices count backward from the end of the string: the last character +has index −1, the character before the last has +index −2, and so on. +

+
+
.ds xxx abcdefgh
+.substring xxx 1 -4
+\*[xxx]
+    ⇒ bcde
+.substring xxx 2
+\*[xxx]
+    ⇒ de
+
+
+ +
+
Request: .stringdown str
+
+
Request: .stringup str
+
+ + + + + +

Alter the string named str by replacing each of its bytes with its +lowercase (stringdown) or uppercase (stringup) version (if +one exists). Special characters in the string will often transform in +the expected way due to the regular naming convention for accented +characters. When they do not, use substrings and/or catenation. +

+
+
.ds resume R\['e]sum\['e]
+\*[resume]
+.stringdown resume
+\*[resume]
+.stringup resume
+\*[resume]
+    ⇒ Résumé résumé RÉSUMÉ
+
+
+ +

(In practice, we would end the ds request with a comment escape +\" to prevent space from creeping into the definition during +source document maintenance.) +

+
+
Request: .rn old new
+
+ + + + + + + + +

Rename the request, macro, diversion, or string old to new. +

+ +
+
Request: .rm name
+
+ + + + + + + + +

Remove the request, macro, diversion, or string name. GNU +troff treats subsequent invocations as if the name had never +been defined. +

+ +
+
Request: .als new old
+
+ + + + + + + + + +

Create an alias new for the existing request, string, macro, or +diversion object named old, causing the names to refer to the same +stored object. If old is undefined, a warning in category +‘mac’ is produced, and the request is ignored. See Warnings, +for information about the enablement and suppression of warnings. +

+

To understand how the als request works, consider two different +storage pools: one for objects (macros, strings, etc.), and another +for names. As soon as an object is defined, GNU troff adds it to +the object pool, adds its name to the name pool, and creates a link +between them. When als creates an alias, it adds a new name to +the name pool that gets linked to the same object as the old name. +

+

Now consider this example. +

+
+
.de foo
+..
+.
+.als bar foo
+.
+.de bar
+.  foo
+..
+.
+.bar
+    error→ input stack limit exceeded (probable infinite
+    error→ loop)
+
+ +

In the above, bar remains an alias—another name +for—the object referred to by foo, which the second de +request replaces. Alternatively, imagine that the de request +dereferences its argument before replacing it. Either way, the +result of calling bar is a recursive loop that finally leads to +an error. See Writing Macros. +

+ + + + + + + + + +

To remove an alias, call rm on its name. The object itself is +not destroyed until it has no more names. +

+

When a request, macro, string, or diversion is aliased, redefinitions +and appendments “write through” alias names. To replace an alias with +a separately defined object, you must use the rm request on its +name first. +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Suppressing-Output.html b/doc/groff.html.node/Suppressing-Output.html new file mode 100644 index 0000000..bd32161 --- /dev/null +++ b/doc/groff.html.node/Suppressing-Output.html @@ -0,0 +1,147 @@ + + + + + + +Suppressing Output (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.32 Suppressing Output

+ +
+
Escape sequence: \O[num]
+
+ + +

Suppress GNU troff output of glyphs and geometric objects. The +sequences \O2, \O3, \O4, and \O5 are +intended for internal use by grohtml. +

+
+
\O0
+

Disable the emission of glyphs and geometric objects to the output +driver, provided that this sequence occurs at the outermost suppression +level (see \O3 and \04 below). Horizontal motions +corresponding to non-overstruck glyph widths still occur. +

+
+
\O1
+

Enable the emission of glyphs and geometric objects to the output +driver, provided that this sequence occurs at the outermost suppression +level. +

+
+ + + + + +

\O0 and \O1 also reset the four registers opminx, +opminy, opmaxx, and opmaxy to −1. These +four registers mark the top left and bottom right hand corners of a box +encompassing all written or drawn output. +

+
+
\O2
+

At the outermost suppression level, enable emission of glyphs and +geometric objects, and write to the standard error stream the page +number and values of the four aforementioned registers encompassing +glyphs written since the last interpolation of a \O sequence, as +well as the page offset, line length, image file name (if any), +horizontal and vertical device motion quanta, and input file name. +Numeric values are in basic units. +

+
+
\O3
+

Begin a nested suppression level. grohtml uses this mechanism +to create images of output preprocessed with gpic, +geqn, and gtbl. At startup, GNU troff is at +the outermost suppression level. pre-grohtml generates these +sequences when processing the document, using GNU troff with +the ps output device, Ghostscript, and the PNM tools to produce +images in PNG format. They start a new page if the device is not +html or xhtml, to reduce the number of images crossing a +page boundary. +

+
+
\O4
+

End a nested suppression level. +

+
+ +
+
\O[5Pfile]
+

At the outermost suppression level, write the name file to the +standard error stream at position P, which must be one of +l, r, c, or i, corresponding to left, +right, centered, and inline alignments within the document, +respectively. file is a name associated with the production of +the next image. +

+
+
+ +
+
Register: \n[.O]
+
+ + + +

Output suppression nesting level applied by \O3 and \O4 +escape sequences. +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Tab-Stops-in-ms.html b/doc/groff.html.node/Tab-Stops-in-ms.html new file mode 100644 index 0000000..3302ce5 --- /dev/null +++ b/doc/groff.html.node/Tab-Stops-in-ms.html @@ -0,0 +1,67 @@ + + + + + + +Tab Stops in ms (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.6.2 Tab stops

+ +

Use the ta request to define tab stops as needed. See Tabs and Fields. +

+
+
Macro: .TA
+
+

Reset the tab stops to the ms default (every 5 ens). +Redefine this macro to create a different set of default tab stops. +

+ + +
+ + + + + diff --git a/doc/groff.html.node/Table-of-Contents.html b/doc/groff.html.node/Table-of-Contents.html new file mode 100644 index 0000000..4d169cd --- /dev/null +++ b/doc/groff.html.node/Table-of-Contents.html @@ -0,0 +1,71 @@ + + + + + + +Table of Contents (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

3.2.7 Table of Contents

+ + + +

A package may handle a table of contents by directing section +heading macros to save section heading text and the page number where it +occurs for use in a later entry for a table of contents. It +writes the collected entries at the end of the document, once all are +known, upon request. A row of dots (a leader) bridges the +text on the left with its location on the right. Other collections +might work in this manner, providing lists of figures or tables. +

+

A table of contents is often found at the end of a GNU troff +document because the formatter processes the document in a single pass. +The gropdf output driver supports a PDF feature that relocates +pages at the time the document is rendered; see the gropdf(1) +man page. Type ‘man gropdf’ at the command line to view it. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Tabs-and-Fields.html b/doc/groff.html.node/Tabs-and-Fields.html new file mode 100644 index 0000000..83c156e --- /dev/null +++ b/doc/groff.html.node/Tabs-and-Fields.html @@ -0,0 +1,276 @@ + + + + + + +Tabs and Fields (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.12 Tabs and Fields

+ + + + +

A tab character (ISO code point 9, EBCDIC +code point 5) causes a horizontal movement to the next tab stop, if +any. +

+
+
Escape sequence: \t
+
+ + + + + +

Interpolate a tab in copy mode; see Copy Mode. +

+ +
+
Request: .ta [[n1 n2nn ]T r1 r2rn]
+
+
Register: \n[.tabs]
+
+

Change tab stop positions. This request takes a series of tab +specifiers as arguments (optionally divided into two groups with the +letter ‘T’) that indicate where each tab stop is to be, overriding +any previous settings. The default scaling unit is ‘m’. Invoking +ta without an argument removes all tab stops. + + +GNU troff’s startup value is ‘T 0.5i. +

+

Tab stops can be specified absolutely—as distances from the left +margin. The following example sets six tab stops, one every inch. +

+
+
.ta 1i 2i 3i 4i 5i 6i
+
+ +

Tab stops can also be specified using a leading ‘+’, which means +that the specified tab stop is set relative to the previous tab stop. +For example, the following is equivalent to the previous example. +

+
+
.ta 1i +1i +1i +1i +1i +1i
+
+ +

GNU troff supports an extended syntax to specify repeating tab +stops. These stops appear after a ‘T’ argument. Their values are +always taken as distances relative to the previous tab stop. This is +the idiomatic way to specify tab stops at equal intervals in +groff. The following is, yet again, the same as the previous +examples. It does more, in fact, since it defines an infinite number of +tab stops at one-inch intervals. +

+
+
.ta T 1i
+
+ +

Now we are ready to interpret the full syntax given above. The +ta request sets tabs at positions n1, n2, …, +nn, then at nn+r1, nn+r2, …, +nn+rn, then at nn+rn+r1, +nn+rn+r2, …, nn+rn+rn, and so +on. +

+

For example, ‘4c +6c T 3c 5c 2c’ is equivalent to ‘4c 10c 13c +18c 20c 23c 28c 30c …’. +

+

Text written to a tab column (i.e., between two tab stops, or between a +tab stop and an output line boundary) may be aligned to the right or +left, or centered in the column. This alignment is determined by +appending ‘R’, ‘L’, or ‘C’ to the tab specifier. The +default is ‘L’. +

+
+
.ta 1i 2iC 3iR
+
+ +

The beginning of an output line is not a tab stop; the text that begins +an output line is placed according to the configured alignment and +indentation; see Manipulating Filling and Adjustment and Line Layout. +

+

A tab stop is converted into a non-breakable horizontal movement that +cannot be adjusted. +

+
+
.ll 2i
+.ds foo a\tb\tc
+.ta T 1i
+\*[foo]
+    error→ warning: cannot break line
+    ⇒ a         b         c
+
+ +

The above creates a single output line that is a bit longer than two +inches (we use a string to show exactly where the tab stops are). +Now consider the following. +

+
+
.ll 2i
+.ds bar a\tb c\td
+.ta T 1i
+\*[bar]
+    error→ warning: cannot adjust line
+    ⇒ a         b
+    ⇒ c       d
+
+ +

GNU troff first converts the line’s tab stops into unbreakable +horizontal movements, then breaks after ‘b’. This usually isn’t +what you want. +

+

Superfluous tab characters—those that do not correspond to a tab +stop—are ignored except for the first, which delimits the characters +belonging to the last tab stop for right-alignment or centering. +

+
+
.ds Z   foo\tbar\tbaz
+.ds ZZ  foo\tbar\tbazqux
+.ds ZZZ foo\tbar\tbaz\tqux
+.ta 2i 4iR
+\*[Z]
+.br
+\*[ZZ]
+.br
+\*[ZZZ]
+.br
+    ⇒ foo                 bar              baz
+    ⇒ foo                 bar           bazqux
+    ⇒ foo                 bar              bazqux
+
+ +

The first line right-aligns “baz” within the second tab stop. The +second line right-aligns “bazqux” within it. The third line +right-aligns only “baz” because of the additional tab character, which +marks the end of the text occupying the last tab stop defined. +

+

Tab stops are associated with the environment (see Environments). +

+ + + +

The read-only register .tabs contains a string +representation of the current tab settings suitable for use as an +argument to the ta request.66 +

+
+
.ds tab-string \n[.tabs]
+\*[tab-string]
+    ⇒ T120u
+
+
+ +
+
Request: .tc [c]
+
+ + + +

Set the tab repetition character to the ordinary or special character +c; normally, no glyph is written when moving to a tab stop (and +some output devices may output space characters to achieve this motion). +A tab repetition character causes the formatter to write as many +instances of c as are necessary to occupy the interval from the +horizontal drawing position to the next tab stop. With no argument, GNU +troff reverts to the default behavior. The tab repetition +character is associated with the environment (see Environments). +Only a single character of c is recognized; any excess is ignored. +

+ +
+
Request: .linetabs n
+
+
Register: \n[.linetabs]
+
+ + + +

If n is missing or non-zero, activate line-tabs; deactivate +it otherwise (the default). Active line-tabs cause GNU troff +to compute tab distances relative to the start of the output line +instead of the input line. +

+
+
.de Tabs
+.  ds x a\t\c
+.  ds y b\t\c
+.  ds z c
+.  ta 1i 3i
+\\*x
+\\*y
+\\*z
+..
+.Tabs
+.br
+.linetabs
+.Tabs
+    ⇒ a         b         c
+    ⇒ a         b                   c
+
+ +

Line-tabs activation is associated with the environment +(see Environments). The read-only register .linetabs +interpolates 1 if line-tabs are active, and 0 otherwise. +

+ + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Tabs-and-Leaders.html b/doc/groff.html.node/Tabs-and-Leaders.html new file mode 100644 index 0000000..c8298a1 --- /dev/null +++ b/doc/groff.html.node/Tabs-and-Leaders.html @@ -0,0 +1,87 @@ + + + + + + +Tabs and Leaders (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.1.6 Tabs and Leaders

+ + + + + + + + +

GNU troff translates input horizontal tab characters (“tabs”) +and Control+A characters (“leaders”) into movements to the next +tab stop. Tabs simply move to the next tab stop; leaders place enough +periods to fill the space. Tab stops are by default located every half +inch measured from the drawing position corresponding to the beginning +of the input line; see Page Geometry. Tabs and leaders do not +cause breaks and therefore do not interrupt filling. Below, we use +arrows → and bullets • to indicate input tabs and +leaders, respectively. +

+
+
1
+→ 2 → 3 • 4
+→ • 5
+⇒ 1         2       3.......4         ........5
+
+ +

Tabs and leaders lend themselves to table construction.24 The tab and leader glyphs can be +configured, and further facilities for sophisticated table composition +are available; see Tabs and Fields. There are many details to +track when using such low-level features, so most users turn to the +tbl(1) preprocessor to lay out tables. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Text-settings-in-ms.html b/doc/groff.html.node/Text-settings-in-ms.html new file mode 100644 index 0000000..f13be1e --- /dev/null +++ b/doc/groff.html.node/Text-settings-in-ms.html @@ -0,0 +1,76 @@ + + + + + + +Text settings in ms (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.5.1 Text settings

+ + +

The FAM string, a GNU extension, sets the font family for body +text; the default is ‘T’. The PS and VS registers +set the type size and vertical spacing (distance between text +baselines), respectively. The font family and type size are ignored on +terminal devices. Setting these parameters before the first call of a +heading, paragraphing, or (non-date) document description macro also +applies them to headers, footers, and (for FAM) footnotes. +

+

Which font families are available depends on the output device; as a +convention, T selects a serif family (“Times”), H a +sans-serif family (“Helvetica”), and C a monospaced family +(“Courier”). The man page for the output driver documents its font +repertoire. Consult the groff(1) man page for lists of +available output devices and their drivers. +

+

The hyphenation mode (as used by the hy request) is set from the +HY register. Setting HY to ‘0’ is equivalent to +using the nh request. This is a Tenth Edition Research Unix +extension. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Text.html b/doc/groff.html.node/Text.html new file mode 100644 index 0000000..16a1d83 --- /dev/null +++ b/doc/groff.html.node/Text.html @@ -0,0 +1,81 @@ + + + + + + +Text (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.1 Text

+ + +

AT&T troff was designed to take input as it would be +composed on a typewriter, including the teletypewriters used as early +computer terminals, and relieve the user drafting a document of concern +with details like line length, hyphenation breaking, and the achievement +of straight margins. Early in its development, the program gained the +ability to prepare output for a phototypesetter; a document could then +be prepared for output to either a teletypewriter, a phototypesetter, or +both. GNU troff continues this tradition of permitting an author +to compose a single master version of a document which can then be +rendered for a variety of output formats or devices. +

+

roff input files contain text interspersed with instructions to +control the formatter. Even in the absence of such instructions, GNU +troff still processes its input in several ways, by filling, +hyphenating, breaking, and adjusting it, and supplementing it with +inter-sentence space. +

+ + + +
+ + + + + diff --git a/doc/groff.html.node/The-Implicit-Page-Trap.html b/doc/groff.html.node/The-Implicit-Page-Trap.html new file mode 100644 index 0000000..82d1a6b --- /dev/null +++ b/doc/groff.html.node/The-Implicit-Page-Trap.html @@ -0,0 +1,74 @@ + + + + + + +The Implicit Page Trap (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.28.1.2 The Implicit Page Trap

+ + + + + + + +

If, after starting GNU troff without loading a macro package, you +use the ptr request to dump a list of the active traps to the +standard error stream,109 nothing is reported. +Yet the .t register will report a steadily decreasing value with +every output line your document produces, and once the value of +.t gets to within .V of zero, you will notice that +something trap-like happens—the page is ejected, a new one begins, and +the value of .t becomes large once more. +

+

This implicit page trap always exists in the top-level +diversion;110 it works like a trap in some +ways but not others. Its purpose is to eject the current page and start +the next one. It has no name, so it cannot be moved or deleted with +wh or ch requests. You cannot hide it by placing another +trap at its location, and can move it only by redefining the page length +with pl. Its operation is suppressed when vertical page traps +are disabled with GNU troff’s vpt request. +

+ +
+ + + + + diff --git a/doc/groff.html.node/Traps.html b/doc/groff.html.node/Traps.html new file mode 100644 index 0000000..3386bdb --- /dev/null +++ b/doc/groff.html.node/Traps.html @@ -0,0 +1,73 @@ + + + + + + +Traps (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.28 Traps

+ + +

Traps are locations in the output or conditions on the input that, +when reached or fulfilled, call a specified macro. These traps can +occur at a given location on the page, at a given location in the +current diversion (together, these are known as vertical +position traps), at a blank line, at a line with leading space +characters, after a quantity of input lines, or at the end of input. +Macros called by traps are passed no arguments. + + +Setting a trap is also called planting one. + + +It is said that a trap is sprung if its condition is fulfilled. +

+ + + +
+ + + + + diff --git a/doc/groff.html.node/Tutorial-for-Macro-Users.html b/doc/groff.html.node/Tutorial-for-Macro-Users.html new file mode 100644 index 0000000..3fc9bce --- /dev/null +++ b/doc/groff.html.node/Tutorial-for-Macro-Users.html @@ -0,0 +1,68 @@ + + + + + + +Tutorial for Macro Users (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

3 Tutorial for Macro Users

+ + + + + +

Most users of the roff language employ a macro package to format +their documents. Successful macro packages ease the composition +process; their users need not have mastered the full formatting +language, nor understand features like diversions, traps, and +environments. This chapter aims to familiarize you with basic concepts +and mechanisms common to many macro packages (like “displays”). If +you prefer a meticulous and comprehensive presentation, try GNU troff Reference instead. +

+ + + + +
+ + + + + diff --git a/doc/groff.html.node/Typeface-and-decoration.html b/doc/groff.html.node/Typeface-and-decoration.html new file mode 100644 index 0000000..759a761 --- /dev/null +++ b/doc/groff.html.node/Typeface-and-decoration.html @@ -0,0 +1,212 @@ + + + + + + +Typeface and decoration (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.5.5 Typeface and decoration

+ +

The ms macros provide a variety of ways to style text. +Attend closely to the ordering of arguments labeled pre and +post, which is not intuitive. Support for pre +arguments is a GNU extension.10 +

+
+
Macro: .B [text [post [pre]]]
+
+

Style text in bold, followed by post in the previous +font style without intervening space, and preceded by pre +similarly. Without arguments, ms styles subsequent text in bold +until the next paragraphing, heading, or no-argument typeface macro +call. +

+ +
+
Macro: .R [text [post [pre]]]
+
+

As B, but use the roman style (upright text of normal weight) +instead of bold. Argument recognition is a GNU extension. +

+ +
+
Macro: .I [text [post [pre]]]
+
+

As B, but use an italic or oblique style instead of bold. +

+ +
+
Macro: .BI [text [post [pre]]]
+
+

As B, but use a bold italic or bold oblique style instead of +upright bold. This is a Tenth Edition Research Unix extension. +

+ +
+
Macro: .CW [text [post [pre]]]
+
+

As B, but use a constant-width (monospaced) roman typeface +instead of bold. This is a Tenth Edition Research Unix extension. +

+ +
+
Macro: .BX [text]
+
+

Typeset text and draw a box around it. On terminal devices, +reverse video is used instead. If you want text to contain space, +use unbreakable space or horizontal motion escape sequences (\~, +\SP, \^, \|, \0 or \h). +

+ +
+
Macro: .UL [text [post]]
+
+

Typeset text with an underline. post, if present, is set +after text with no intervening space. +

+ +
+
Macro: .LG
+
+

Set subsequent text in larger type (two points larger than the +current size) until the next type size, paragraphing, or heading macro +call. You can specify this macro multiple times to enlarge the type +size as needed. +

+ +
+
Macro: .SM
+
+

Set subsequent text in smaller type (two points smaller than the current +size) until the next type size, paragraphing, or heading macro call. +You can specify this macro multiple times to reduce the type size as +needed. +

+ +
+
Macro: .NL
+
+

Set subsequent text at the normal type size (the amount in the PS +register). +

+ +

pre and post arguments are typically used to simplify the +attachment of punctuation to styled words. When pre is used, +a hyphenation control escape sequence \% that would ordinarily +start text must start pre instead to have the desired +effect. +

+
+
+
The CS course's students found one C language keyword
+.CW static ) \%(
+most troublesome.
+
+
+ +

The foregoing example produces output as follows. +

+
+
+
The CS course’s students found one C language keyword (static)
+most troublesome.
+
+
+ +

You can use the output line continuation escape sequence \c to +achieve the same result (see Line Continuation). It is also +portable to older ms implementations. +

+
+
+
The CS course's students found one C language keyword
+\%(\c
+.CW \%static )
+most troublesome.
+
+
+ +

groff ms also offers strings to begin and end super- and +subscripting. These are GNU extensions. +

+
+
String: \*[{]
+
+
String: \*[}]
+
+

Begin and end superscripting, respectively. +

+ +
+
String: \*[<]
+
+
String: \*[>]
+
+

Begin and end subscripting, respectively. +

+ +

Rather than calling the CW macro, in groff ms you +might prefer to change the font family to Courier by setting the +FAM string to ‘C’. You can then use all four style macros +above, returning to the default family (Times) with ‘.ds FAM T’. +Because changes to FAM take effect only at the next paragraph, +CW remains useful to “inline” a change to the font family, +similarly to the practice of this document in noting syntactical +elements of ms and groff. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Typographical-symbols-in-ms.html b/doc/groff.html.node/Typographical-symbols-in-ms.html new file mode 100644 index 0000000..3323bcd --- /dev/null +++ b/doc/groff.html.node/Typographical-symbols-in-ms.html @@ -0,0 +1,80 @@ + + + + + + +Typographical symbols in ms (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.5.2 Typographical symbols

+ + +

ms provides a few strings to obtain typographical symbols not +easily entered with the keyboard. These and many others are available +as special character escape sequences—see the groff_char(7) +man page. +

+
+
String: \*[-]
+
+

Interpolate an em dash. +

+ +
+
String: \*[Q]
+
+
String: \*[U]
+
+

Interpolate typographer’s quotation marks where available, and neutral +double quotes otherwise. \*Q is the left quote and \*U +the right. +

+ + +
+ + + + + diff --git a/doc/groff.html.node/Using-Escape-Sequences.html b/doc/groff.html.node/Using-Escape-Sequences.html new file mode 100644 index 0000000..9eabad1 --- /dev/null +++ b/doc/groff.html.node/Using-Escape-Sequences.html @@ -0,0 +1,206 @@ + + + + + + +Using Escape Sequences (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.6.4 Using Escape Sequences

+ + + +

Whereas requests must occur on control lines, escape sequences can occur +intermixed with text and may appear in arguments to requests, macros, +and other escape sequences. + +An escape sequence is introduced by the escape character, a backslash +\ (but see the ec request below). The next character +selects the escape’s function. +

+

Escape sequences vary in length. Some take an argument, and of those, +some have different syntactical forms for a one-character, +two-character, or arbitrary-length argument. Others accept only +an arbitrary-length argument. In the former scheme, a one-character +argument follows the function character immediately, an opening +parenthesis ‘(’ introduces a two-character argument (no closing +parenthesis is used), and an argument of arbitrary length is enclosed in +brackets ‘[]’. In the latter scheme, the user selects a delimiter +character. A few escape sequences are idiosyncratic, and support both +of the foregoing conventions (\s), designate their own +termination sequence (\?), consume input until the next newline +(\!, \", \#), or support an additional modifier +character (\s again, and \n). As with requests, use of +some escape sequences in source documents may interact poorly with a +macro package you use; consult its documentation to learn of “safe” +sequences or alternative facilities it provides to achieve the desired +result. +

+

If an escape character is followed by a character that does not +identify a defined operation, the escape character is ignored (producing +a diagnostic of the ‘escape’ warning category, which is not enabled +by default) and the following character is processed normally. +

+
+
$ groff -Tps -ww
+.nr N 12
+.ds co white
+.ds animal elephant
+I have \fI\nN \*(co \*[animal]s,\f[]
+said \P.\&\~Pseudo Pachyderm.
+    error→ warning: escape character ignored before 'P'
+    ⇒ I have 12 white elephants, said P. Pseudo Pachyderm.
+
+ +

Escape sequence interpolation is of higher precedence than escape +sequence argument interpretation. This rule affords flexibility in +using escape sequences to construct parameters to other escape +sequences. +

+
+
.ds family C\" Courier
+.ds style I\" oblique
+Choice a typeface \f(\*[family]\*[style]wisely.
+    ⇒ Choose a typeface wisely.
+
+ +

In the above, the syntax form ‘\f(’ accepts only two characters for +an argument; the example works because the subsequent escape sequences +are interpolated before the selection escape sequence argument is +processed, and strings family and style interpolate one +character each.46 +

+

The escape character is nearly always interpreted when encountered; it +is therefore desirable to have a way to interpolate it, disable it, or +change it. +

+ + +
+
Escape sequence: \e
+
+

Interpolate the escape character. +

+ + + +

The \[rs] special character escape sequence formats a backslash +glyph. In macro and string definitions, the input sequences \\ +and \E defer interpretation of escape sequences. See Copy Mode. +

+
+
Request: .eo
+
+ + +

Disable the escape mechanism except in copy mode. Once this request is +invoked, no input character is recognized as starting an escape +sequence in interpretation mode. +

+ +
+
Request: .ec [o]
+
+ + +

Recognize the ordinary character o as the escape character. +If o is absent or invalid, the default escape character +‘\’ is selected. +

+ +

Switching escape sequence interpretation off to define a macro and back +on afterward can obviate the need to double the escape character within +the definition. See Writing Macros. This technique is not available +if your macro needs to interpolate values at the time it is +defined—but many do not. +

+
+
.\" simplified `BR` macro from the man(7) macro package
+.eo
+.de BR
+.  ds result \&
+.  while (\n[.$] >= 2) \{\
+.    as result \fB\$1\fR\$2\"
+.    shift 2
+.  \}
+.  if \n[.$] .as result \fB\$1\"
+\*[result]
+.  rm result
+.  ft R
+..
+.ec
+
+ +
+
Request: .ecs
+
+
Request: .ecr
+
+

The ecs request stores the escape character for recall with +ecr. ecr sets the escape character to ‘\’ if none +has been saved. +

+

Use these requests together to temporarily change the escape character. +

+ +

Using a different escape character, or disabling it, when calling macros +not under your control will likely cause errors, since GNU troff +has no mechanism to “intern” macros—that is, to convert a macro +definition into a form independent of its +representation.47 When a +macro is called, its contents are interpreted literally. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/Using-Fonts.html b/doc/groff.html.node/Using-Fonts.html new file mode 100644 index 0000000..81f48e6 --- /dev/null +++ b/doc/groff.html.node/Using-Fonts.html @@ -0,0 +1,148 @@ + + + + + + +Using Fonts (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.19 Using Fonts

+ + + + + + + + + + + + + +

In digital typography, a font is a collection of characters in a +specific typeface that a device can render as glyphs at a desired +size.72 A roff formatter can change typefaces at any +point in the text. The basic faces are a set of styles combining +upright and slanted shapes with normal and heavy stroke weights: +‘R’, ‘I’, ‘B’, and ‘BI’—these stand for +roman, italic, bold, and +bold-italic. For linguistic text, GNU troff groups +typefaces into families containing each of these +styles.73 A text font is thus often a family +combined with a style, but it need not be: consider the ps and +pdf devices’ ZCMI (Zapf Chancery Medium italic)—often, +no other style of Zapf Chancery Medium is provided. On typesetting +devices, at least one special font is available, comprising +unstyled glyphs for mathematical operators and other purposes. +

+ + + + + + + + +

Like AT&T troff, GNU troff does not itself load +or manipulate a digital font file;74 instead it +works with a font description file that characterizes it, +including its glyph repertoire and the metrics (dimensions) of +each glyph.75 This +information permits the formatter to accurately place glyphs with +respect to each other. Before using a font description, the formatter +associates it with a mounting position, a place in an ordered list +of available typefaces. + + + +So that a document need not be strongly coupled to a specific font +family, in GNU troff an output device can associate a style in +the abstract sense with a mounting position. Thus the default family +can be combined with a style dynamically, producing a resolved font +name. +

+

Fonts often have trademarked names, and even Free Software fonts can +require renaming upon modification. groff maintains a +convention that a device’s serif font family is given the name ‘T’ +(“Times”), its sans-serif family ‘H’ (“Helvetica”), and its +monospaced family ‘C’ (“Courier”). Historical inertia has driven +groff’s font identifiers to short uppercase abbreviations of font +names, as with ‘TR’, ‘TI’, ‘TB’, ‘TBI’, and a +special font ‘S’. +

+

The default family used with abstract styles can be changed at any time; +initially, it is ‘T’. Typically, abstract styles are arranged in +the first four mounting positions in the order shown above. The default +mounting position, and therefore style, is always ‘1’ (‘R’). +By issuing appropriate formatter instructions, you can override these +defaults before your document writes its first glyph. +

+ + + + + +

Terminal output devices cannot change font families and lack special +fonts. They support style changes by overstriking, or by altering +ISO 6429/ECMA-48 graphic renditions (character cell +attributes). +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Using-Fractional-Type-Sizes.html b/doc/groff.html.node/Using-Fractional-Type-Sizes.html new file mode 100644 index 0000000..7445fc5 --- /dev/null +++ b/doc/groff.html.node/Using-Fractional-Type-Sizes.html @@ -0,0 +1,172 @@ + + + + + + +Using Fractional Type Sizes (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.20.3 Using Fractional Type Sizes

+ + + + + + +

AT&T troff interpreted all type size measurements in points. +Combined with integer arithmetic, this design choice made it impossible +to support, for instance, ten and a half-point type. In GNU +troff, an output device can select a scaling factor that +subdivides a point into “scaled points”. A type size expressed in +scaled points can thus represent a non-integral type size. +

+ + + + + + + + + + + +

A scaled point is equal to 1/sizescale points, where +sizescale is specified in the device description file DESC, +and defaults to 1.85 Requests and escape sequences in GNU troff interpret +arguments that represent a type size in scaled points, which the +formatter multiplies by sizescale and converts to an integer. +Arguments treated in this way comprise those to the escape sequences +\H and \s, to the request ps, the third argument to +the cs request, and the second and fourth arguments to the +tkf request. Scaled points may be specified explicitly with the +z scaling unit. +

+

For example, if sizescale is 1000, then a scaled point is one +thousandth of a point. The request ‘.ps 10.5’ is synonymous with +‘.ps 10.5z’ and sets the type size to 10,500 scaled points, or +10.5 points. Consequently, in GNU troff, the register +.s can interpolate a non-integral type size. +

+
+
Register: \n[.ps]
+
+

This read-only register interpolates the type size in scaled points; it +is associated with the environment (see Environments). +

+ +

It makes no sense to use the ‘z’ scaling unit in a numeric +expression whose default scaling unit is neither ‘u’ nor ‘z’, +so GNU troff disallows this. Similarly, it is nonsensical to use +a scaling unit other than ‘z’ or ‘u’ in a numeric expression +whose default scaling unit is ‘z’, and so GNU troff +disallows this as well. +

+

Another GNU troff scaling unit, ‘s’, multiplies by the +number of basic units in a scaled point. Thus, ‘\n[.ps]s’ is equal +to ‘1m’ by definition. Do not confuse the ‘s’ and ‘z’ +scaling units. +

+
+
Register: \n[.psr]
+
+
Register: \n[.sr]
+
+ + + + + + +

Output devices may be limited in the type sizes they can employ. The +.s and .ps registers represent the type size selected by +the output driver as it understands a device’s capability. The last +requested type size is interpolated in scaled points by the +read-only register .psr and in points as a decimal fraction by +the read-only string-valued register .sr. Both are associated +with the environment (see Environments). +

+

For example, if a type size of 10.95 points is requested, and the +nearest size permitted by a sizes request (or by the sizes +or sizescale directives in the device’s DESC file) is 11 +points, the output driver uses the latter value. +

+ +

The \s escape sequence offers the following syntax forms that +work with fractional type sizes and accept scaling units. You may of +course give them integral arguments. The delimited forms need not use +the neutral apostrophe; see Delimiters. +

+
+
\s[n]
+
\s'n'
+

Set the type size to n scaled points; n is a +numeric expression with a default scaling unit of ‘z’. +

+
+
\s[+n]
+
\s[-n]
+
\s+[n]
+
\s-[n]
+
\s'+n'
+
\s'-n'
+
\s+'n'
+
\s-'n'
+

Increase or decrease the type size by n scaled points; +n is a numeric expression (which may start with a minus sign) +with a default scaling unit of ‘z’. +

+
+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/Using-Symbols.html b/doc/groff.html.node/Using-Symbols.html new file mode 100644 index 0000000..af4a7cf --- /dev/null +++ b/doc/groff.html.node/Using-Symbols.html @@ -0,0 +1,632 @@ + + + + + + +Using Symbols (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.19.4 Using Symbols

+ + + + + + + + +

A glyph is a graphical representation of a character. While +a character is an abstraction of semantic information, a glyph is +something that can be seen on screen or paper. A character has many +possible representation forms (for example, the character ‘A’ can be +written in an upright or slanted typeface, producing distinct +glyphs). Sometimes, a sequence of characters map to a single glyph: +this is a ligature—the most common is ‘fi’. +

+

Space characters never become glyphs in GNU troff. If not +discarded (as when trailing on text lines), they are represented by +horizontal motions in the output. +

+ + + + + + +

A symbol is simply a named glyph. Within gtroff, all glyph +names of a particular font are defined in its font file. If the user +requests a glyph not available in this font, gtroff looks up an +ordered list of special fonts. By default, the PostScript output +device supports the two special fonts ‘SS’ (slanted symbols) and +‘S’ (symbols) (the former is looked up before the latter). Other +output devices use different names for special fonts. Fonts mounted +with the fonts keyword in the DESC file are globally +available. To install additional special fonts locally (i.e., for a +particular font), use the fspecial request. +

+

Here are the exact rules how gtroff searches a given symbol: +

+
    +
  • If the symbol has been defined with the char request, use it. +This hides a symbol with the same name in the current font. + +
  • Check the current font. + +
  • If the symbol has been defined with the fchar request, use it. + +
  • Check whether the current font has a font-specific list of special +fonts; test all fonts in the order of appearance in the last +fspecial call if appropriate. + +
  • If the symbol has been defined with the fschar request for the +current font, use it. + +
  • Check all fonts in the order of appearance in the last special +call. + +
  • If the symbol has been defined with the schar request, use it. + +
  • As a last resort, consult all fonts loaded up to now for special fonts +and check them, starting with the lowest font number. This can +sometimes lead to surprising results since the fonts line in +the DESC file often contains empty positions, which are filled +later on. For example, consider the following: + +
    +
    fonts 3 0 0 FOO
    +
    + +

    This mounts font foo at font position 3. We assume that +FOO is a special font, containing glyph foo, and that no +font has been loaded yet. The line +

    +
    +
    .fspecial BAR BAZ
    +
    + +

    makes font BAZ special only if font BAR is active. We +further assume that BAZ is really a special font, i.e., the font +description file contains the special keyword, and that it also +contains glyph foo with a special shape fitting to font +BAR. After executing fspecial, font BAR is loaded +at font position 1, and BAZ at position 2. +

    +

    We now switch to a new font XXX, trying to access glyph +foo that is assumed to be missing. There are neither +font-specific special fonts for XXX nor any other fonts made +special with the special request, so gtroff starts the +search for special fonts in the list of already mounted fonts, with +increasing font positions. Consequently, it finds BAZ before +FOO even for XXX, which is not the intended behaviour. +

+ +

See Device and Font Description Files, and Special Fonts, for +more details. +

+ + + + + +

The groff_char(7) man page houses a complete list of +predefined special character names, but the availability of any as a +glyph is device- and font-dependent. For example, say +

+
+
man -Tdvi groff_char > groff_char.dvi
+
+ +

to obtain those available with the DVI device and default font +configuration.77 If you want to use an additional macro package to change +the fonts used, groff (or gtroff) must be run directly. +

+
+
groff -Tdvi -mec -man groff_char.7 > groff_char.dvi
+
+ + + + + + +

Special character names not listed in groff_char(7) are +derived algorithmically, using a simplified version of the Adobe Glyph +List (AGL) algorithm, which is described in +https://github.com/adobe-type-tools/agl-aglfn. The (frozen) +set of names that can’t be derived algorithmically is called the +groff glyph list (GGL). +

+
    +
  • A glyph for Unicode character U+XXXX[X[X]], which is +not a composite character is named +uXXXX[X[X]]. X must be an +uppercase hexadecimal digit. Examples: u1234, u008E, +u12DB8. The largest Unicode value is 0x10FFFF. There must be at +least four X digits; if necessary, add leading zeroes (after the +‘u’). No zero padding is allowed for character codes greater than +0xFFFF. Surrogates (i.e., Unicode values greater than 0xFFFF +represented with character codes from the surrogate area U+D800-U+DFFF) +are not allowed either. + +
  • A glyph representing more than a single input character is named + +
    +
    ucomponent1_component2_component3 …
    +
    + +

    Example: u0045_0302_0301. +

    +

    For simplicity, all Unicode characters that are composites must be +maximally decomposed to NFD;78 for example, +u00CA_0301 is not a valid glyph name since U+00CA (LATIN +CAPITAL LETTER E WITH CIRCUMFLEX) can be further decomposed into U+0045 +(LATIN CAPITAL LETTER E) and U+0302 (COMBINING CIRCUMFLEX +ACCENT). u0045_0302_0301 is thus the glyph name for U+1EBE, +LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE. +

    +
  • groff maintains a table to decompose all algorithmically derived glyph +names that are composites itself. For example, u0100 (LATIN +LETTER A WITH MACRON) is automatically decomposed into +u0041_0304. Additionally, a glyph name of the GGL is preferred +to an algorithmically derived glyph name; groff also +automatically does the mapping. Example: The glyph u0045_0302 is +mapped to ^E. + +
  • glyph names of the GGL can’t be used in composite glyph names; for +example, ^E_u0301 is invalid. +
+ +
+
Escape sequence: \(nm
+
+
Escape sequence: \[name]
+
Escape sequence: \[base-glyph combining-component …]
+
+ +

Typeset a special character name (two-character name nm) or +a composite glyph consisting of base-glyph overlaid with one or +more combining-components. For example, ‘\[A ho]’ is a +capital letter “A” with a “hook accent” (ogonek). +

+

There is no special syntax for one-character names—the analogous form +‘\n’ would collide with other escape sequences. However, the +four escape sequences \', \-, \_, and \`, +are translated on input to the special character escape sequences +\[aa], \[-], \[ul], and \[ga], respectively. +

+

A special character name of length one is not the same thing as an +ordinary character: that is, the character a is not the same as +\[a]. +

+

If name is undefined, a warning in category ‘char’ is +produced and the escape is ignored. See Warnings, for information +about the enablement and suppression of warnings. +

+

GNU troff resolves \[] with more than a single +component as follows: +

+
    +
  • Any component that is found in the GGL is converted to the +uXXXX form. + +
  • Any component uXXXX that is found in the list of +decomposable glyphs is decomposed. + +
  • The resulting elements are then concatenated with ‘_’ in between, +dropping the leading ‘u’ in all elements but the first. +
+ +

No check for the existence of any component (similar to tr +request) is done. +

+

Examples: +

+
+
\[A ho]
+

A’ maps to u0041, ‘ho’ maps to u02DB, thus the +final glyph name would be u0041_02DB. This is not the expected +result: the ogonek glyph ‘ho’ is a spacing ogonek, but for a +proper composite a non-spacing ogonek (U+0328) is necessary. Looking +into the file composite.tmac, one can find ‘.composite ho u0328, which changes the mapping of ‘ho’ while a composite glyph +name is constructed, causing the final glyph name to be +u0041_0328. +

+
+
\[^E u0301]
+
\[^E aa]
+
\[E a^ aa]
+
\[E ^ ']
+

^E’ maps to u0045_0302, thus the final glyph name is +u0045_0302_0301 in all forms (assuming proper calls of the +composite request). +

+
+ +

It is not possible to define glyphs with names like ‘A ho +within a groff font file. This is not really a limitation; +instead, you have to define u0041_0328. +

+ +
+
Escape sequence: \C'xxx'
+
+ + +

Typeset the glyph of the special character xxx. Normally, it is +more convenient to use \[xxx], but \C has some +advantages: it is compatible with AT&T device-independent +troff (and therefore available in compatibility +mode79) and can interpolate special +characters with ‘]’ in their names. The delimiter need not be +a neutral apostrophe; see Delimiters. +

+ +
+
Request: .composite id1 id2
+
+ +

Map special character name id1 to id2 if id1 is used +in \[...] with more than one component. See above for examples. +This is a strict rewriting of the special character name; no check is +performed for the existence of a glyph for either. A set of default +mappings for many accents can be found in the file +composite.tmac, loaded by the default troffrc at startup. +

+ +
+
Escape sequence: \N'n'
+
+ + + + +

Typeset the glyph with code n in the current font +(n is not the input character code). The number +n can be any non-negative decimal integer. Most devices only +have glyphs with codes between 0 and 255; the Unicode output device +uses codes in the range 0–65535. If the current font does not contain +a glyph with that code, special fonts are not searched. The +\N escape sequence can be conveniently used in conjunction with +the char request: +

+
+
.char \[phone] \f[ZD]\N'37'
+
+ + + + +

The code of each glyph is given in the fourth column in the font +description file after the charset command. It is possible to +include unnamed glyphs in the font description file by using a name of +‘---’; the \N escape sequence is the only way to use these. +

+

No kerning is applied to glyphs accessed with \N. The delimiter +need not be a neutral apostrophe; see Delimiters. +

+ +

A few escape sequences are also special characters. +

+
+
Escape sequence: \'
+
+

An escaped neutral apostrophe is a synonym for \[aa] (acute +accent). +

+ +
+
Escape sequence: \`
+
+

An escaped grave accent is a synonym for \[ga] (grave accent). +

+ +
+
Escape sequence: \-
+
+

An escaped hyphen-minus is a synonym for \[-] (minus sign). +

+ +
+
Escape sequence: \_
+
+

An escaped underscore (“low line”) is a synonym for \[ul] +(underrule). On typesetting devices, the underrule is font-invariant +and drawn lower than the underscore ‘_’. +

+ +
+
Request: .cflags n c1 c2 …
+
+ + + + +

Assign properties encoded by the number n to characters c1, +c2, and so on. +

+

Input characters, including special characters introduced by an escape, +have certain properties associated with them.80 +These properties can be modified with this request. The first argument +is the sum of the desired flags and the remaining arguments are the +characters to be assigned those properties. Spaces between the cn +arguments are optional. Any argument cn can be a character class +defined with the class request rather than an individual +character. See Character Classes. +

+

The non-negative integer n is the sum of any of the following. +Some combinations are nonsensical, such as ‘33’ (1 + 32). +

+
+
1
+
+

Recognize the character as ending a sentence if followed by a newline +or two spaces. Initially, characters ‘.?!’ have this property. +

+
+
2
+
+

Enable breaks before the character. A line is not broken at a character +with this property unless the characters on each side both have non-zero +hyphenation codes. This exception can be overridden by adding 64. +Initially, no characters have this property. +

+
+
4
+
+ +

Enable breaks after the character. A line is not broken at a character +with this property unless the characters on each side both have non-zero +hyphenation codes. This exception can be overridden by adding 64. +Initially, characters ‘\-\[hy]\[em]’ have this property. +

+
+
8
+
+ + + + + +

Mark the glyph associated with this character as overlapping other +instances of itself horizontally. Initially, characters +‘\[ul]\[rn]\[ru]\[radicalex]\[sqrtex]’ have this property. +

+
+
16
+

Mark the glyph associated with this character as overlapping other +instances of itself vertically. Initially, the character ‘\[br]’ +has this property. +

+
+
32
+
+ + + + + + + + + +

Mark the character as transparent for the purpose of end-of-sentence +recognition. In other words, an end-of-sentence character followed by +any number of characters with this property is treated as the end of a +sentence if followed by a newline or two spaces. This is the same as +having a zero space factor in TeX. Initially, characters +‘"')]*\[dg]\[dd]\[rq]\[cq]’ have this property. +

+
+
64
+

Ignore hyphenation codes of the surrounding characters. Use this in +combination with values 2 and 4 (initially, no characters have this +property). +

+

For example, if you need an automatic break point after the en-dash in +numeric ranges like “3000–5000”, insert +

+
+
.cflags 68 \[en]
+
+ +

into your document. However, this practice can lead to bad layout if +done thoughtlessly; in most situations, a better solution instead of +changing the cflags value is to insert \: right after the +hyphen at the places that really need a break point. +

+
+ +

The remaining values were implemented for East Asian language support; +those who use alphabetic scripts exclusively can disregard them. +

+
+
128
+

Prohibit a line break before the character, but allow a line break after +the character. This works only in combination with flags 256 and 512 +and has no effect otherwise. Initially, no characters have this +property. +

+
+
256
+

Prohibit a line break after the character, but allow a line break before +the character. This works only in combination with flags 128 and 512 +and has no effect otherwise. Initially, no characters have this +property. +

+
+
512
+

Allow line break before or after the character. This works only in +combination with flags 128 and 256 and has no effect otherwise. +Initially, no characters have this property. +

+
+ +

In contrast to values 2 and 4, the values 128, 256, and 512 work +pairwise. If, for example, the left character has value 512, and the +right character 128, no break will be automatically inserted between +them. If we use value 6 instead for the left character, a break +after the character can’t be suppressed since the neighboring character +on the right doesn’t get examined. +

+ +
+
Request: .char c [contents]
+
+
Request: .fchar c [contents]
+
+
Request: .fschar f c [contents]
+
+
Request: .schar c [contents]
+
+ + + + + + + + + + + + + + + + + + + + + +

Define a new character or glyph c to be contents, which +can be empty. More precisely, char defines a groff object +(or redefines an existing one) that is accessed with the +name c on input, and produces contents on output. +Every time glyph c needs to be printed, contents is +processed in a temporary environment and the result is wrapped up into a +single object. Compatibility mode is turned off and the escape +character is set to \ while contents is processed. +Any emboldening, constant spacing, or track kerning is applied to this +object rather than to individual glyphs in contents. +

+

An object defined by these requests can be used just like a normal glyph +provided by the output device. In particular, other characters can be +translated to it with the tr or trin requests; it can be +made the leader character with the lc request; repeated patterns +can be drawn with it using the \l and \L escape sequences; +and words containing c can be hyphenated correctly if the +hcode request is used to give the object a hyphenation code. +

+

There is a special anti-recursion feature: use of the object within its +own definition is handled like a normal character (not +defined with char). +

+

The tr and trin requests take precedence if char +accesses the same symbol. +

+
+
.tr XY
+X
+    ⇒ Y
+.char X Z
+X
+    ⇒ Y
+.tr XX
+X
+    ⇒ Z
+
+ +

The fchar request defines a fallback glyph: gtroff only +checks for glyphs defined with fchar if it cannot find the glyph +in the current font. gtroff carries out this test before +checking special fonts. +

+

fschar defines a fallback glyph for font f: +gtroff checks for glyphs defined with fschar after the +list of fonts declared as font-specific special fonts with the +fspecial request, but before the list of fonts declared as global +special fonts with the special request. +

+

Finally, the schar request defines a global fallback glyph: +gtroff checks for glyphs defined with schar after the list +of fonts declared as global special fonts with the special +request, but before the already mounted special fonts. +

+

See Character Classes. +

+ +
+
Request: .rchar c …
+
+
Request: .rfschar f c …
+
+ + + +

Remove definition of each ordinary or special character c, +undoing the effect of a char, fchar, or schar +request. Those supplied by font description files cannot be removed. +Spaces and tabs may separate c arguments. +

+

The request rfschar removes glyph definitions defined with +fschar for font f. +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/Vertical-Position-Traps.html b/doc/groff.html.node/Vertical-Position-Traps.html new file mode 100644 index 0000000..d12f564 --- /dev/null +++ b/doc/groff.html.node/Vertical-Position-Traps.html @@ -0,0 +1,94 @@ + + + + + + +Vertical Position Traps (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.28.1 Vertical Position Traps

+ + + +

A vertical position trap calls a macro when the formatter’s +vertical drawing position reaches or passes, in the downward direction, +a certain location on the output page or in a diversion. Its +applications include setting page headers and footers, body text in +multiple columns, and footnotes. +

+
+
Request: .vpt [flag]
+
+
Register: \n[.vpt]
+
+ + + +

Enable vertical position traps if flag is non-zero or absent; +disable them otherwise. Vertical position traps are those set by the +wh request or by dt within a diversion. The parameter +that controls whether vertical position traps are enabled is global. +Initially, vertical position traps are enabled. The current value is +stored in the .vpt read-only register. +

+ + + + +

A page can’t be ejected if vpt is set to zero; see The Implicit Page Trap. +

+ + + + +
+ + + + + diff --git a/doc/groff.html.node/Warnings.html b/doc/groff.html.node/Warnings.html new file mode 100644 index 0000000..b61ec3a --- /dev/null +++ b/doc/groff.html.node/Warnings.html @@ -0,0 +1,246 @@ + + + + + + +Warnings (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.37.1 Warnings

+ + +

Warning diagnostics emitted by GNU troff are divided into named, +numbered categories. The name associated with each warning category is +used by the -w and -W options. Each category is also +assigned a power of two; the sum of enabled category values is used by +the warn request and the .warn register. +

+

Warnings of each category are produced under the following +circumstances. +

+ + +
+
char
+
1
+

No mounted font defines a glyph for the requested character. This +category is enabled by default. +

+
+
number
+
2
+

An invalid numeric expression was encountered. This category is enabled +by default. +See Numeric Expressions. +

+
+
break
+
4
+
+

A filled output line could not be broken such that its length was less +than the output line length ‘\n[.l]’. This category is enabled by +default. +

+
+
delim
+
8
+

The closing delimiter in an escape sequence was missing or mismatched. +

+
+
el
+
16
+
+

The el request was encountered with no prior corresponding +ie request. See if-else. +

+
+
scale
+
32
+

A scaling unit inappropriate to its context was used in a numeric +expression. +

+
+
range
+
64
+

A numeric expression was out of range for its context. +

+
+
syntax
+
128
+

A self-contradictory hyphenation mode was requested; an empty or +incomplete numeric expression was encountered; an operand to a numeric +operator was missing; an attempt was made to define a recursive, empty, +or nonsensical character class; or a groff extension conditional +expression operator was used while in compatibility mode. +

+
+
di
+
256
+
+ + +

A di, da, box, or boxa request was invoked +without an argument when there was no current diversion. +

+
+
mac
+
512
+
+ + + + + + +

An undefined string, macro, or diversion was used. When such an object +is dereferenced, an empty one of that name is automatically created. +So, unless it is later deleted, at most one warning is given for each. +

+

This warning is also emitted upon an attempt to move an unplanted trap +macro (see Page Location Traps). In such cases, the unplanted macro +is not dereferenced, so it is not created if it does not exist. +

+
+
reg
+
1024
+
+ +

An undefined register was used. When an undefined register is +dereferenced, it is automatically defined with a value of 0. So, +unless it is later deleted, at most one warning is given for each. +

+
+
tab
+
2048
+

A tab character was encountered where a number was expected, or appeared +in an unquoted macro argument. +

+
+
right-brace
+
4096
+

A right brace escape sequence \} was encountered where a number +was expected. +

+
+
missing
+
8192
+

A request was invoked with a mandatory argument absent. +

+
+
input
+
16384
+

An invalid character occurred on the input stream. +

+
+
escape
+
32768
+

An unsupported escape sequence was encountered. +

+
+
space
+
65536
+

A space was missing between a request or macro and its argument. This +warning is produced when an undefined name longer than two characters is +encountered and the first two characters of the name constitute a +defined name. No request is invoked, no macro called, and an empty +macro is not defined. This category is enabled by default. It never +occurs in compatibility mode. +

+
+
font
+
131072
+

A non-existent font was selected, or the selection was ignored because a +font selection escape sequence was used after the output line +continuation escape sequence on an input line. This category is enabled +by default. +

+
+
ig
+
262144
+

An invalid escape sequence occurred in input ignored using the ig +request. This warning category diagnoses a condition that is an error +when it occurs in non-ignored input. +

+
+
color
+
524288
+

An undefined color was selected, an attempt was made to define a color +using an unrecognized color space, an invalid component in a color +definition was encountered, or an attempt was made to redefine a default +color. +

+
+
file
+
1048576
+

An attempt was made to load a file that does not exist. This category +is enabled by default. +

+
+ +

Two warning names group other warning categories for convenience. +

+
+
all
+

All warning categories except ‘di’, ‘mac’ and ‘reg’. +This shorthand is intended to produce all warnings that are useful with +macro packages written for AT&T troff and its +descendants, which have less fastidious diagnostics than GNU +troff. +

+
+
w
+

All warning categories. Authors of documents and macro packages +targeting groff are encouraged to use this setting. +

+
+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/What-Is-groff_003f.html b/doc/groff.html.node/What-Is-groff_003f.html new file mode 100644 index 0000000..99939ea --- /dev/null +++ b/doc/groff.html.node/What-Is-groff_003f.html @@ -0,0 +1,68 @@ + + + + + + +What Is groff? (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

1.2 What Is groff?

+ + + +

groff (GNU roff) is a typesetting system that reads plain +text input files that include formatting commands to produce output in +PostScript, PDF, HTML, DVI, or other formats, or for display to a +terminal. Formatting commands can be low-level typesetting primitives, +macros from a supplied package, or user-defined macros. All three +approaches can be combined. +

+

A reimplementation and extension of the typesetter from AT&T +Unix, groff is present on most POSIX systems owing to +its long association with Unix manuals (including man pages). It and +its predecessor are notable for their production of several best-selling +software engineering texts. groff is capable of producing +typographically sophisticated documents while consuming minimal system +resources. +

+ + +
+ + + + + diff --git a/doc/groff.html.node/Writing-Macros.html b/doc/groff.html.node/Writing-Macros.html new file mode 100644 index 0000000..e08b9fa --- /dev/null +++ b/doc/groff.html.node/Writing-Macros.html @@ -0,0 +1,267 @@ + + + + + + +Writing Macros (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.24 Writing Macros

+ + + +

A macro is a stored collection of text and control lines that can +be interpolated multiple times. Use macros to define common operations. +Macros are called in the same way that requests are invoked. While +requests exist for the purpose of creating macros, simply calling an +undefined macro, or interpolating it as a string, will cause it to be +defined as empty. See Identifiers. +

+
+
Request: .de name [end]
+
+

Define a macro name, replacing the definition of any existing +request, macro, string, or diversion called name. If +name already exists as an alias, the target of the alias is +redefined; recall Strings. GNU troff enters copy +mode,97 storing subsequent input lines as the +macro definition. If the optional second argument is not specified, the +definition ends with the control line ‘..’ (two dots). +Alternatively, end identifies a macro whose call syntax at the +start of a control line ends the definition of name; end is +then called normally. A macro definition must end in the same +conditional block (if any) in which it began (see Conditional Blocks). Spaces or tabs are permitted after the control character in +the line containing this ending token (either ‘.’ or +‘end’), but a tab immediately after the token prevents its +recognition as the end of a macro definition. The macro end can +be called with arguments.98 +

+

Here is a small example macro called ‘P’ that causes a break and +inserts some vertical space. It could be used to separate paragraphs. +

+
+
.de P
+.  br
+.  sp .8v
+..
+
+ +

We can define one macro within another. Attempting to nest ‘..’ +naďvely will end the outer definition because the inner definition +isn’t interpreted as such until the outer macro is later interpolated. +We can use an end macro instead. Each level of nesting should use a +unique end macro. +

+

An end macro need not be defined until it is called. This fact enables +a nested macro definition to begin inside one macro and end inside +another. Consider the following example.99 +

+
+
.de m1
+.  de m2 m3
+you
+..
+.de m3
+Hello,
+Joe.
+..
+.de m4
+do
+..
+.m1
+know?
+.  m3
+What
+.m4
+.m2
+    ⇒ Hello, Joe.  What do you know?
+
+ +

A nested macro definition can be terminated with ‘..’ and +nested macros can reuse end macros, but these control lines must +be escaped multiple times for each level of nesting. The necessity of +this escaping and the utility of nested macro definitions will become +clearer when we employ macro parameters and consider the behavior of +copy mode in detail. +

+ +

de defines a macro that inherits the compatibility mode +enablement status of its context (see Implementation Differences). +Often it is desirable to make a macro that uses groff features +callable from contexts where compatibility mode is on; for instance, +when writing extensions to a historical macro package. To achieve this, +compatibility mode needs to be switched off while such a macro is +interpreted—without disturbing that state when it is finished. +

+
+
Request: .de1 name [end]
+
+

The de1 request defines a macro to be interpreted with +compatibility mode disabled. When name is called, compatibility +mode enablement status is saved; it is restored when the call completes. +Observe the extra backlash before the interpolation of register +‘xxx’; we’ll explore this subject in Copy Mode. +

+
+
.nr xxx 12345
+.de aa
+The value of xxx is \\n[xxx].
+.  br
+..
+.de1 bb
+The value of xxx is \\n[xxx].
+..
+.cp 1
+.aa
+    error→ warning: register '[' not defined
+    ⇒ The value of xxx is 0xxx].
+.bb
+    ⇒ The value of xxx is 12345.
+
+
+ +
+
Request: .dei name [end]
+
+
Request: .dei1 name [end]
+
+

The dei request defines a macro with its name and end +macro indirected through strings. That is, it interpolates strings +named name and end before performing the definition. +

+

The following examples are equivalent. +

+
+
.ds xx aa
+.ds yy bb
+.dei xx yy
+
+ +
+
.de aa bb
+
+ +

The dei1 request bears the same relationship to dei as +de1 does to de; it temporarily turns compatibility mode +off when name is called. +

+ +
+
Request: .am name [end]
+
+
Request: .am1 name [end]
+
+
Request: .ami name [end]
+
+
Request: .ami1 name [end]
+
+ + +

am appends subsequent input lines to macro name, extending +its definition, and otherwise working as de does. +

+

To make the previously defined ‘P’ macro set indented instead of +block paragraphs, add the necessary code to the existing macro. +

+
+
.am P
+.ti +5n
+..
+
+ +

The other requests are analogous to their ‘de’ counterparts. The +am1 request turns off compatibility mode during interpretation of +the appendment. The ami request appends indirectly, meaning that +strings name and end are interpolated with the resulting +names used before appending. The ami1 request is similar to +ami, disabling compatibility mode during interpretation of the +appended lines. +

+ + +

Using trace.tmac, you can trace calls to de, +de1, am, and am1. You can also use the +backtrace request at any point desired to troubleshoot tricky +spots (see Debugging). +

+

See Strings, for the als, rm, and rn requests to +create an alias of, remove, and rename a macro, respectively. +

+ +

Macro identifiers share their name space with requests, strings, and +diversions; see Identifiers. The am, as, da, +de, di, and ds requests (together with their +variants) create a new object only if the name of the macro, diversion, +or string is currently undefined or if it is defined as a request; +normally, they modify the value of an existing object. See the +description of the als request, for pitfalls when redefining a +macro that is aliased. +

+
+
Request: .return [anything]
+
+

Exit a macro, immediately returning to the caller. If called with an +argument anything, exit twice—the current macro and the macro +one level higher. This is used to define a wrapper macro for +return in trace.tmac. +

+ + + + +
+
+ + + + + + diff --git a/doc/groff.html.node/als.html b/doc/groff.html.node/als.html new file mode 100644 index 0000000..711bc84 --- /dev/null +++ b/doc/groff.html.node/als.html @@ -0,0 +1,33 @@ + + + + + + + +als (The GNU Troff Manual) + + + + + + + + + + + + + + +

The node you are looking for is at als.

+ diff --git a/doc/groff.html.node/groff-Capabilities.html b/doc/groff.html.node/groff-Capabilities.html new file mode 100644 index 0000000..424779a --- /dev/null +++ b/doc/groff.html.node/groff-Capabilities.html @@ -0,0 +1,91 @@ + + + + + + +groff Capabilities (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

1.3 groff Capabilities

+ + + +

GNU troff is a typesetting document formatter; it provides a wide +range of low-level text and page operations within the framework of a +programming language. These operations compose to generate footnotes, +tables of contents, mathematical equations, diagrams, multi-column text, +and other elements of typeset works. Here is a survey of formatter +features; all are under precise user control. +

+
    +
  • text filling, breaking, alignment to the left or right margin; centering + +
  • adjustment of inter-word space size to justify text, and of +inter-sentence space size to suit local style conventions + +
  • automatic and manual determination of hyphenation break points + +
  • pagination + +
  • selection of any font available to the output device + +
  • adjustment of type size and vertical spacing (or “leading”) + +
  • configuration of line length and indentation amounts; columnation + +
  • drawing of geometric primitives (lines, arcs, polygons, circles, +…) + +
  • setup of stroke and fill colors (where supported by the output +device) + +
  • embedding of hyperlinks, images, document metadata, and other inclusions +(where supported by the output device) +
+ + + +
+ + + + + diff --git a/doc/groff.html.node/groff.html_fot.html b/doc/groff.html.node/groff.html_fot.html new file mode 100644 index 0000000..1230044 --- /dev/null +++ b/doc/groff.html.node/groff.html_fot.html @@ -0,0 +1,525 @@ + + + + + + +Footnotes (The GNU Troff Manual) + + + + + + + + + + + + + + + + + +
+ +
+

Footnotes

+ +
(1)
+

The ‘g’ prefix is +not used on all systems; see Invoking groff.

+
(2)
+

Unix and related operating systems distinguish +standard output and standard error streams because of +troff: +https://minnie.tuhs.org/pipermail/tuhs/2013-December/006113.html.

+
(3)
+

See Line Layout.

+
(4)
+

Besides groff, neatroff is an +exception.

+
(5)
+

The +mso request does not have these limitations. See I/O.

+
(6)
+

The remainder of this chapter is based on +Writing Papers with nroff using -me by Eric P. Allman, +which is distributed with groff as meintro.me.

+
(7)
+

While manual pages are older, early ones used +macros supplanted by the man package of Seventh Edition Unix +(1979). ms shipped with Sixth Edition (1975) and was documented +by Mike Lesk in a Bell Labs internal memorandum.

+
(8)
+

defined in Footnotes

+
(9)
+

Distinguish a +document title from “titles”, which are what roff systems call +headers and footers collectively.

+
(10)
+

This idiosyncrasy arose through +feature accretion; for example, the B macro in Version 6 +Unix ms (1975) accepted only one argument, the text to be set in +boldface. By Version 7 (1979) it recognized a second argument; in +1990, groff ms added a “pre” argument, placing it third +to avoid breaking support for older documents.

+
(11)
+

“Portable Document Format Publishing with GNU +Troff”, pdfmark.ms in the groff distribution, uses this +technique.

+
(12)
+

Unix Version 7 ms, its descendants, and GNU +ms prior to groff version 1.23.0

+
(13)
+

You could reset it +after each call to .1C, .2C, or .MC.

+
(14)
+

Typing Documents on the UNIX System: Using the +-ms Macros with Troff and Nroff, M. E. Lesk, Bell Laboratories, +1978

+
(15)
+

Register values are converted to and stored as +basic units. See Measurements.

+
(16)
+

If you redefine the ms PT macro +and desire special treatment of certain page numbers (like ‘1’), +you may need to handle a non-Arabic page number format, as groff +ms’s PT does; see the macro package source. groff +ms aliases the PN register to %.

+
(17)
+

The removal beforehand is necessary +because groff ms aliases these macros to a diagnostic +macro, and you want to redefine the aliased name, not its target.

+
(18)
+

See Device and Font Description Files.

+
(19)
+

Tabs and leaders also separate +words. Escape sequences can function as word characters, word +separators, or neither—the last simply have no effect on GNU +troff’s idea of whether an input character is within a word. +We’ll discuss all of these in due course.

+
(20)
+

A +well-researched jeremiad appreciated by groff contributors on +both sides of the sentence-spacing debate can be found at +https://web.archive.org/web/20171217060354/http://www.heracliteanriver.com/?p=324.

+
(21)
+

This statement oversimplifies; there are +escape sequences whose purpose is precisely to produce glyphs on the +output device, and input characters that aren’t part of escape +sequences can undergo a great deal of processing before getting to the +output.

+
(22)
+

The mnemonics for the special +characters shown here are “dagger”, “double dagger”, “right +(double) quote”, and “closing (single) quote”. See the +groff_char(7) man page.

+
(23)
+

“Text lines” are defined in Requests and Macros.

+
(24)
+

“Tab” +is short for “tabulation”, revealing the term’s origin as a spacing +mechanism for table arrangement.

+
(25)
+

The \RET escape sequence can alter how an +input line is classified; see Line Continuation.

+
(26)
+

Argument handling in +macros is more flexible but also more complex. See Calling Macros.

+
(27)
+

Some escape sequences undergo +interpolation as well.

+
(28)
+

GNU troff offers additional ones. See Writing Macros.

+
(29)
+

Macro files and packages +frequently define registers and strings as well.

+
(30)
+

The +semantics of certain punctuation code points have gotten stricter +with the successive standards, a cause of some frustration among man +page writers; see the groff_char(7) man page.

+
(31)
+

The +DVI output device defaults to using the Computer Modern (CM) fonts; +ec.tmac loads the EC fonts instead, which provide Euro +‘\[Eu]’ and per mille ‘\[%0]’ glyphs.

+
(32)
+

Emacs: fill-column: 72; Vim: textwidth=72

+
(33)
+

groff does not yet support right-to-left +scripts.

+
(34)
+

groff’s terminal output devices have page +offsets of zero.

+
(35)
+

Provision is made for interpreting and +reporting decimal fractions in certain cases.

+
(36)
+

If that’s not enough, see the groff_tmac(5) +man page for the 62bit.tmac macro package.

+
(37)
+

See Conditionals and Loops.

+
(38)
+

Control structure syntax +creates an exception to this rule, but is designed to remain useful: +recalling our example, ‘.if 1 .Underline this’ would underline only +“this”, precisely. See Conditionals and Loops.

+
(39)
+

See Diversions.

+
(40)
+

Historically, control characters like +ASCII STX, ETX, and BEL (Control+B, Control+C, and +Control+G) have been observed in roff documents, +particularly in macro packages employing them as delimiters with the +output comparison operator to try to avoid collisions with the content +of arbitrary user-supplied parameters (see Operators in Conditionals). We discourage this expedient; in GNU troff it is +unnecessary (outside of compatibility mode) because delimited arguments +are parsed at a different input level than the surrounding context. +See Implementation Differences.

+
(41)
+

Consider what happens when a C1 control +0x800x9F is necessary as a continuation byte in a UTF-8 +sequence.

+
(42)
+

Recall Identifiers.

+
(43)
+

In compatibility +mode, a space is not necessary after a request or macro name of two +characters’ length. Also, Plan 9 troff allows tabs to +separate arguments.

+
(44)
+

\~ is fairly +portable; see Other Differences.

+
(45)
+

Strictly, you can neglect to +close the last quoted macro argument, relying on the end of the control +line to do so. We consider this lethargic practice poor style.

+
(46)
+

The omission of spaces before the comment +escape sequences is necessary; see Strings.

+
(47)
+

TeX does have such a mechanism.

+
(48)
+

This claim may be more aspirational than descriptive.

+
(49)
+

See Conditional Blocks.

+
(50)
+

Exception: auto-incrementing registers defined outside +the ignored region will be modified if interpolated with +\ną inside it. See Auto-increment.

+
(51)
+

A negative auto-increment can be +considered an “auto-decrement”.

+
(52)
+

GNU troff dynamically allocates memory for +as many registers as required.

+
(53)
+

unless diverted; see Diversions

+
(54)
+

See Line Continuation.

+
(55)
+

Recall Filling and Sentences for the +definitions of word and sentence boundaries, respectively.

+
(56)
+

Whether a perfect algorithm for this application is +even possible is an unsolved problem in computer science: +https://tug.org/docs/liang/liang-thesis.pdf.

+
(57)
+

\% itself stops marking +hyphenation points but still produces no output glyph.

+
(58)
+

“Soft” because it appears in output +only where a hyphenation break is performed; a “hard” hyphen, as in +“long-term”, always appears.

+
(59)
+

The mode is a vector of Booleans encoded as an integer. +To a programmer, this fact is easily deduced from the exclusive use of +powers of two for the configuration parameters; they are computationally +easy to “mask off” and compare to zero. To almost everyone else, the +arrangement seems recondite and unfriendly.

+
(60)
+

Hyphenation is +prevented if the next page location trap is closer to the vertical +drawing position than the next text baseline would be. See Page Location Traps.

+
(61)
+

For more on localization, see the +groff_tmac(5) man page.

+
(62)
+

See Page Location Traps.

+
(63)
+

See Drawing Geometric Objects.

+
(64)
+

or geometric objects; see Drawing Geometric Objects

+
(65)
+

to the top-level diversion; +see Diversions

+
(66)
+

Plan 9 troff +uses the register .S for this purpose.

+
(67)
+

This is pronounced to rhyme with “feeder”, and +refers to how the glyphs “lead” the eye across the page to the +corresponding page number or other datum.

+
(68)
+

A +GNU nroff program is available for convenience; it calls GNU +troff to perform the formatting.

+
(69)
+

Historically, the \c +escape sequence has proven challenging to characterize. Some sources +say it “connects the next input text” (to the input line on which it +appears); others describe it as “interrupting” text, on the grounds +that a text line is interrupted without breaking, perhaps to inject a +request invocation or macro call.

+
(70)
+

See Traps.

+
(71)
+

See Diversions.

+
(72)
+

Terminals and some output devices have fonts that render +at only one or two sizes. As examples of the latter, take the +groff lj4 device’s Lineprinter, and lbp’s Courier +and Elite faces.

+
(73)
+

Font designers prepare families such that the styles +share esthetic properties.

+
(74)
+

Historically, the fonts +troffs dealt with were not Free Software or, as with the Graphic +Systems C/A/T, did not even exist in the digital domain.

+
(75)
+

See Font Description File Format.

+
(76)
+

See DESC File Format.

+
(77)
+

Not all versions of the man program +support the -T option; use the subsequent example for an +alternative.

+
(78)
+

This is “Normalization Form D” +as documented in Unicode Standard Annex #15 +(https://unicode.org/reports/tr15/).

+
(79)
+

See Compatibility Mode.

+
(80)
+

Output glyphs +don’t—to GNU troff, a glyph is simply a box with an index into +a font, a given height above and depth below the baseline, and a width.

+
(81)
+

Opinions of this escape sequence’s name abound. +“Zero-width space” is a popular misnomer: roff formatters do +not treat it like a space. Ossanna called it a “non-printing, +zero-width character”, but the character causes output even +though it does not “print”. If no output line is pending, the dummy +character starts one. Contrast an empty input document with one +containing only \&. The former produces no output; the latter, a +blank page.

+
(82)
+

In text fonts, the tallest glyphs are typically +parentheses. Unfortunately, in many cases the actual dimensions of the +glyphs in a font do not closely match its declared type size! For +example, in the standard PostScript font families, 10-point Times sets +better with 9-point Helvetica and 11-point Courier than if all three +were used at 10 points.

+
(83)
+

Rhyme with “sledding”; mechanical typography +used lead metal (Latin plumbum).

+
(84)
+

The claim appears to have been true of Ossanna +troff for the C/A/T device; Kernighan made device-independent +troff more flexible.

+
(85)
+

See Device and Font Description Files.

+
(86)
+

also +known vulgarly as “ANSI colors”

+
(87)
+

See Copy Mode.

+
(88)
+

This refers to +vtroff, a translator that would convert the C/A/T output from +early-vintage AT&T troff to a form suitable for +Versatec and Benson-Varian plotters.

+
(89)
+

Strictly, letters not otherwise recognized are treated +as output comparison delimiters. For portability, it is wise to avoid +using letters not in the list above; for example, Plan 9 +troff uses ‘h’ to test a mode it calls htmlroff, and +GNU troff may provide additional operators in the future.

+
(90)
+

Because formatting of the comparands takes place +in a dummy environment, vertical motions within them cannot spring +traps.

+
(91)
+

All +of this is to say that the lists of output nodes created by formatting +xxx and yyy must be identical. See gtroff Internals.

+
(92)
+

This bizarre behavior maintains compatibility with +AT&T troff.

+
(93)
+

See while.

+
(94)
+

See Copy Mode.

+
(95)
+

unless you redefine it

+
(96)
+

“somewhat less” because +things other than macro calls can be on the input stack

+
(97)
+

See Copy Mode.

+
(98)
+

While it is possible to define and +call a macro ‘.’, you can’t use it as an end macro: during a macro +definition, ‘..’ is never handled as calling ‘.’, even if +‘.de name .’ explicitly precedes it.

+
(99)
+

Its structure is +adapted from, and isomorphic to, part of a solution by Tadziu Hoffman to +the problem of reflowing text multiple times to find an optimal +configuration for it. +https://lists.gnu.org/archive/html/groff/2008-12/msg00006.html

+
(100)
+

If they were not, +parameter interpolations would be similar to command-line +parameters—fixed for the entire duration of a roff program’s +run. The advantage of interpolating \$ escape sequences even in +copy mode is that they can interpolate different contents from one call +to the next, like function parameters in a procedural language. The +additional escape character is the price of this power.

+
(101)
+

Compare this to the \def and \edef +commands in TeX.

+
(102)
+

These are lightly adapted from the groff +implementation of the ms macros.

+
(103)
+

At the +grops defaults of 10-point type on 12-point vertical spacing, the +difference between half a vee and half an em can be subtle: large +spacings like ‘.vs .5i’ make it obvious.

+
(104)
+

See Strings, for an explanation of the trailing +‘\"’.

+
(105)
+

(hc, vc) is adjusted to the point nearest +the perpendicular bisector of the arc’s chord.

+
(106)
+

See The Implicit Page Trap.

+
(107)
+

A trap planted at ‘20i’ or +‘-30i’ will not be sprung on a page of length ‘11i’.

+
(108)
+

It may help to think of each trap location as +maintaining a queue; wh operates on the head of the queue, and +ch operates on its tail. Only the trap at the head of the queue +is visible.

+
(109)
+

See Debugging.

+
(110)
+

See Diversions.

+
(111)
+

While processing an +end-of-input macro, the formatter assumes that the next page break must +be the last; it goes into “sudden death overtime”.

+
(112)
+

Another, taken by the groff man macros, is +to intercept ne requests and wrap bp ones.

+
(113)
+

Thus, the “water” +gets “higher” proceeding down the page.

+
(114)
+

The backslash is doubled. See Copy Mode.

+
(115)
+

that is, ISO 646:1991-IRV or, +popularly, “US-ASCII”

+
(116)
+

They are bypassed because these parameters are not +rendered as glyphs in the output; instead, they remain abstract +characters—in a PDF bookmark or a URL, for example.

+
(117)
+

Recall Line Layout.

+
(118)
+

Historically, +tools named nrchbar and changebar were developed for +marking changes with margin characters and could be found in archives of +the comp.sources.unix USENET group. Some proprietary +Unices also offer(ed) a diffmk program.

+
(119)
+

Except the +escape sequences \f, \F, \H, \m, \M, +\R, \s, and \S, which are processed immediately if +not in copy mode.

+
(120)
+

The +Graphic Systems C/A/T phototypesetter (the original device target for +AT&T troff) supported only a few discrete type sizes +in the range 6–36 points, so Ossanna contrived a special case in the +parser to do what the user must have meant. Kernighan warned of this in +the 1992 revision of CSTR #54 (§2.3), and more recently, McIlroy +referred to it as a “living fossil”.

+
(121)
+

DWB 3.3, Solaris, Heirloom Doctools, and +Plan 9 troff all support it.

+
(122)
+

Naturally, if you’ve changed +the escape character, you need to prefix the e with whatever it +is—and you’ll likely get something other than a backslash in the +output.

+
(123)
+

The rs special character identifier was not +defined in AT&T troff’s font description files, but is +in those of its lineal descendant, Heirloom Doctools troff, as of +the latter’s 060716 release (July 2006).

+
(124)
+

The parser +and postprocessor for intermediate output can be found in the file
+groff-source-dir/src/libs/libdriver/input.cpp.

+
(125)
+

Plan 9 troff has also abandoned the binary +format.

+
(126)
+

800-point type +is not practical for most purposes, but using it enables the quantities +in the font description files to be expressed as integers.

+
(127)
+

groff requests and escape sequences +interpret non-negative font names as mounting positions instead. +Further, a font named ‘0’ cannot be automatically mounted by the +fonts directive of a DESC file.

+
(128)
+

For typesetter devices, this directive is misnamed +since it starts a list of glyphs, not characters.

+
(129)
+

that is, any integer parsable by the C +standard library’s strtol(3) function

+

+ + + + + + diff --git a/doc/groff.html.node/gtroff-Output.html b/doc/groff.html.node/gtroff-Output.html new file mode 100644 index 0000000..cab0daf --- /dev/null +++ b/doc/groff.html.node/gtroff-Output.html @@ -0,0 +1,100 @@ + + + + + + +gtroff Output (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

6.1 gtroff Output

+ + + +

This section describes the groff intermediate output format +produced by GNU troff. +

+

As groff is a wrapper program around GNU troff and +automatically calls an output driver (or “postprocessor”), this output +does not show up normally. This is why it is called +intermediate. groff provides the option -Z to +inhibit postprocessing such that the produced intermediate output is +sent to standard output just as it is when calling GNU troff +directly. +

+ + + + +

Here, the term troff output describes what is output by +GNU troff, while intermediate output refers to the language +that is accepted by the parser that prepares this output for the output +drivers. This parser handles whitespace more flexibly than +AT&T’s implementation and implements obsolete elements for +compatibility; otherwise, both formats are the same.124 +

+

The main purpose of the intermediate output concept is to facilitate the +development of postprocessors by providing a common programming +interface for all devices. It has a language of its own that is +completely different from the gtroff language. While the +gtroff language is a high-level programming language for text +processing, the intermediate output language is a kind of low-level +assembler language by specifying all positions on the page for writing +and drawing. +

+

The intermediate output produced by gtroff is fairly readable, +while output from AT&T troff is rather hard to +understand because of strange habits that are still supported, but not +used any longer by gtroff. +

+ + + +
+
+ + + + + + diff --git a/doc/groff.html.node/if_002delse.html b/doc/groff.html.node/if_002delse.html new file mode 100644 index 0000000..3c67fa9 --- /dev/null +++ b/doc/groff.html.node/if_002delse.html @@ -0,0 +1,97 @@ + + + + + + +if-else (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.23.3 if-else

+ + +
+
Request: .ie cond-expr anything
+
+
Request: .el anything
+
+

Use the ie and el requests to write an if-then-else. The +first request is the “if” part and the latter is the “else” part. +Unusually among programming languages, any number of non-conditional +requests may be interposed between the ie branch and the +el branch. +

+
+
.nr a 0
+.ie \na a is non-zero.
+.nr a +1
+.el a was not positive but is now \na.
+    ⇒ a was not positive but is now 1.
+
+ +

Another way in which el is an ordinary request is that it does +not lexically “bind” more tightly to its ie counterpart than it +does to any other request. This fact can surprise C programmers. +

+
+
.nr a 1
+.nr z 0
+.ie \nz \
+.  ie \na a is true
+.  el     a is false
+.el z is false
+    error→ warning: unbalanced 'el' request
+    ⇒ a is false
+
+ +

To conveniently nest conditionals, keep reading. +

+
+ + +
+ + + + + diff --git a/doc/groff.html.node/if_002dthen.html b/doc/groff.html.node/if_002dthen.html new file mode 100644 index 0000000..e2fba2b --- /dev/null +++ b/doc/groff.html.node/if_002dthen.html @@ -0,0 +1,111 @@ + + + + + + +if-then (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.23.2 if-then

+ + +
+
Request: .if cond-expr anything
+
+

Evaluate the conditional expression cond-expr, and if it evaluates +true (or to a positive value), interpret the remainder of the line +anything as if it were an input line. Recall from Invoking Requests that any quantity of spaces between arguments to requests +serves only to separate them; leading spaces in anything are thus +not seen. anything effectively cannot be omitted; if +cond-expr is true and anything is empty, the newline at the +end of the control line is interpreted as a blank input line (and +therefore a blank text line). +

+
+
super\c
+tanker
+.nr force-word-break 1
+super\c
+.if ((\n[force-word-break] = 1) & \n[.int])
+tanker
+    ⇒ supertanker super tanker
+
+
+ +
+
Request: .nop anything
+
+

Interpret anything as if it were an input line. This is similar +to ‘.if 1’. nop is not really “no operation”; its +argument is processed—unconditionally. It can be used to cause +text lines to share indentation with surrounding control lines. +

+
+
.als real-MAC MAC
+.de wrapped-MAC
+.  tm MAC: called with arguments \\$@
+.  nop \\*[real-MAC]\\
+..
+.als MAC wrapped-MAC
+\# Later...
+.als MAC real-MAC
+
+ +

In the above, we’ve used aliasing, nop, and the interpolation of +a macro as a string to interpose a wrapper around the macro ‘MAC’ +(perhaps to debug it). +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/index.html b/doc/groff.html.node/index.html new file mode 100644 index 0000000..d1b9973 --- /dev/null +++ b/doc/groff.html.node/index.html @@ -0,0 +1,453 @@ + + + + + + +Top (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+

GNU troff

+ + +

This manual documents GNU troff version 1.23.0. +

+

Copyright © 1994–2023 Free Software Foundation, Inc. +

+
+

Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 or +any later version published by the Free Software Foundation; with no +Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A +copy of the license is included in the section entitled “GNU Free +Documentation License”. +

+ + + + + +
+

Table of Contents

+ +
+ + +
+
+
+
+ + + + + + diff --git a/doc/groff.html.node/man.html b/doc/groff.html.node/man.html new file mode 100644 index 0000000..93ec854 --- /dev/null +++ b/doc/groff.html.node/man.html @@ -0,0 +1,71 @@ + + + + + + +man (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.1 man

+ + + + + +

The man macro package is the most widely used and probably the +most important ever developed for troff. It is easy to use, and +a vast majority of manual pages (“man pages”) are written in it. +

+

groff’s implementation is documented in the +groff_man(7) man page. Type ‘man groff_man’ at the +command line to view it. +

+ + + +
+ + + + + diff --git a/doc/groff.html.node/mdoc.html b/doc/groff.html.node/mdoc.html new file mode 100644 index 0000000..d752098 --- /dev/null +++ b/doc/groff.html.node/mdoc.html @@ -0,0 +1,61 @@ + + + + + + +mdoc (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.2 mdoc

+ + +

groff’s implementation of the BSD doc package for man +pages is documented in the groff_mdoc(7) man page. Type +‘man groff_mdoc’ at the command line to view it. +

+ + +
+ + + + + diff --git a/doc/groff.html.node/me.html b/doc/groff.html.node/me.html new file mode 100644 index 0000000..35da9f2 --- /dev/null +++ b/doc/groff.html.node/me.html @@ -0,0 +1,67 @@ + + + + + + +me (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.3 me

+ + +

groff’s implementation of the BSD me macro package is +documented using itself. A tutorial, meintro.me, and reference, +meref.me, are available in groff’s documentation +directory. A groff_me(7) man page is also available and +identifies the installation path for these documents. Type ‘man +groff_me’ at the command line to view it. +

+

A French translation of the tutorial is available as +meintro_fr.me and installed parallel to the English version. +

+ + +
+ + + + + diff --git a/doc/groff.html.node/mm.html b/doc/groff.html.node/mm.html new file mode 100644 index 0000000..38dc3b9 --- /dev/null +++ b/doc/groff.html.node/mm.html @@ -0,0 +1,64 @@ + + + + + + +mm (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.4 mm

+ + +

groff’s implementation of the AT&T memorandum macro +package is documented in the groff_mm(7) man page. Type +‘man groff_mm’ at the command line) to view it. +

+

A Swedish localization of mm is also available; see +groff_mmse(7). +

+ + +
+ + + + + diff --git a/doc/groff.html.node/mom.html b/doc/groff.html.node/mom.html new file mode 100644 index 0000000..6d0840d --- /dev/null +++ b/doc/groff.html.node/mom.html @@ -0,0 +1,85 @@ + + + + + + +mom (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.5 mom

+ + +

The main documentation files for the mom macros are in +HTML format. Additional, useful documentation is in +PDF format. See the groff(1) man page, section +“Installation Directories”, for their location. +

+
    +
  • toc.html +Entry point to the full mom manual. + +
  • macrolist.html +Hyperlinked index of macros with brief descriptions, arranged by +category. + +
  • mom-pdf.pdf +PDF features and usage. +
+ +

The mom macros are in active development between groff releases. +The most recent version, along with up-to-date documentation, is +available at http://www.schaffter.ca/mom/mom-05.html. +

+

The groff_mom(7) man page (type ‘man groff_mom’ at +the command line) contains a partial list of available macros, however +their usage is best understood by consulting the HTML +documentation. +

+ + + +
+ + + + + diff --git a/doc/groff.html.node/ms-Body-Text.html b/doc/groff.html.node/ms-Body-Text.html new file mode 100644 index 0000000..f2d370b --- /dev/null +++ b/doc/groff.html.node/ms-Body-Text.html @@ -0,0 +1,70 @@ + + + + + + +ms Body Text (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.5 Body Text

+ + +

A variety of macros, registers, and strings can be used to structure and +style the body of your document. They organize your text into +paragraphs, headings, footnotes, and inclusions of material such as +tables and figures. +

+ + + +
+ + + + + diff --git a/doc/groff.html.node/ms-Document-Control-Settings.html b/doc/groff.html.node/ms-Document-Control-Settings.html new file mode 100644 index 0000000..ef8f2a4 --- /dev/null +++ b/doc/groff.html.node/ms-Document-Control-Settings.html @@ -0,0 +1,524 @@ + + + + + + +ms Document Control Settings (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.3 Document Control Settings

+ + +

ms exposes many aspects of document layout to user control via +groff requests. To use them, you must understand how to define +registers and strings. +

+
+
Request: .nr reg value
+
+

Set register reg to value. If reg doesn’t exist, GNU +troff creates it. +

+ +
+
Request: .ds name contents
+
+

Set string name to contents. +

+ +

A list of document control registers and strings follows. For any +parameter whose default is unsatisfactory, define its register or string +before calling any ms macro other than RP. +

+ +
+

Margin settings

+ +
+
Register: \n[PO]
+
+

Defines the page offset (i.e., the left margin). +

+

Effective: next page. +

+

Default: Varies by output device and paper format; 1i is used for +typesetters using U.S. letter paper, and zero for terminals. +See Paper Format. +

+ +
+
Register: \n[LL]
+
+

Defines the line length (i.e., the width of the body text). +

+

Effective: next paragraph. +

+

Default: Varies by output device and paper format; 6.5i is used +for typesetters using U.S. letter paper (see Paper Format) and +65n on terminals. +

+ +
+
Register: \n[LT]
+
+

Defines the title line length (i.e., the header and footer width). This +is usually the same as LL, but need not be. +

+

Effective: next paragraph. +

+

Default: Varies by output device and paper format; 6.5i is used +for typesetters using U.S. letter paper (see Paper Format) and +65n on terminals. +

+ +
+
Register: \n[HM]
+
+

Defines the header margin height at the top of the page. +

+

Effective: next page. +

+

Default: 1i. +

+ +
+
Register: \n[FM]
+
+

Defines the footer margin height at the bottom of the page. +

+

Effective: next page. +

+

Default: 1i. +

+ +
+
+

Titles (headers, footers)

+ +
+
String: \*[LH]
+
+

Defines the text displayed in the left header position. +

+

Effective: next header. +

+

Default: empty. +

+ +
+
String: \*[CH]
+
+

Defines the text displayed in the center header position. +

+

Effective: next header. +

+

Default: ‘-\n[%]-’. +

+ +
+
String: \*[RH]
+
+

Defines the text displayed in the right header position. +

+

Effective: next header. +

+

Default: empty. +

+ +
+
String: \*[LF]
+
+

Defines the text displayed in the left footer position. +

+

Effective: next footer. +

+

Default: empty. +

+ +
+
String: \*[CF]
+
+

Defines the text displayed in the center footer position. +

+

Effective: next footer. +

+

Default: empty. +

+ +
+
String: \*[RF]
+
+

Defines the text displayed in the right footer position. +

+

Effective: next footer. +

+

Default: empty. +

+ +
+
+

Text settings

+ +
+
Register: \n[PS]
+
+

Defines the type size of the body text. +

+

Effective: next paragraph. +

+

Default: 10p. +

+ +
+
Register: \n[VS]
+
+

Defines the vertical spacing (type size plus leading). +

+

Effective: next paragraph. +

+

Default: 12p. +

+ +
+
Register: \n[HY]
+
+

Defines the automatic hyphenation mode used with the hy request. +Setting HY to 0 is equivalent to using the nh +request. This is a Tenth Edition Research Unix extension. +

+

Effective: next paragraph. +

+

Default: 6. +

+ +
+
String: \*[FAM]
+
+

Defines the font family used to typeset the document. This is a GNU +extension. +

+

Effective: next paragraph. +

+

Default: defined by the output device; often ‘T’ (see Body Text) +

+ +
+
+

Paragraph settings

+ +
+
Register: \n[PI]
+
+

Defines the indentation amount used by the PP, IP (unless +overridden by an optional argument), XP, and RS macros. +

+

Effective: next paragraph. +

+

Default: 5n. +

+ +
+
Register: \n[PD]
+
+

Defines the space between paragraphs. +

+

Effective: next paragraph. +

+

Default: 0.3v (1v on low-resolution devices). +

+ +
+
Register: \n[QI]
+
+

Defines the indentation amount used on both sides of a paragraph set +with the QP or between the QS and QE macros. +

+

Effective: next paragraph. +

+

Default: 5n. +

+ +
+
Register: \n[PORPHANS]
+
+

Defines the minimum number of initial lines of any paragraph that must +be kept together to avoid isolated lines at the bottom of a page. If a +new paragraph is started close to the bottom of a page, and there is +insufficient space to accommodate PORPHANS lines before an +automatic page break, then a page break is forced before the start of +the paragraph. This is a GNU extension. +

+

Effective: next paragraph. +

+

Default: 1. +

+ +
+
+

Heading settings

+ +
+
Register: \n[PSINCR]
+
+

Defines an increment in type size to be applied to a heading at a +lesser depth than that specified in GROWPS. The value of +PSINCR should be specified in points with the p scaling +unit and may include a fractional component; for example, ‘.nr PSINCR 1.5p sets a type size increment of 1.5p. This is a GNU +extension. +

+

Effective: next heading. +

+

Default: 1p. +

+ +
+
Register: \n[GROWPS]
+
+

Defines the heading depth above which the type size increment set by +PSINCR becomes effective. For each heading depth less than the +value of GROWPS, the type size is increased by PSINCR. +Setting GROWPS to any value less than 2 disables the +incremental heading size feature. This is a GNU extension. +

+

Effective: next heading. +

+

Default: 0. +

+ +
+
Register: \n[HORPHANS]
+
+

Defines the minimum number of lines of an immediately succeeding +paragraph that should be kept together with any heading introduced by +the NH or SH macros. If a heading is placed close to the +bottom of a page, and there is insufficient space to accommodate both +the heading and at least HORPHANS lines of the following +paragraph, before an automatic page break, then the page break is forced +before the heading. This is a GNU extension. +

+

Effective: next paragraph. +

+

Default: 1. +

+ +
+
String: \*[SN-STYLE]
+
+

Defines the style used to print numbered headings. See Headings. This is a GNU extension. +

+

Effective: next heading. +

+

Default: alias of SN-DOT +

+ +
+
+

Footnote settings

+ +
+
Register: \n[FI]
+
+

Defines the footnote indentation. This is a Berkeley extension. +

+

Effective: next footnote. +

+

Default: 2n. +

+ +
+
Register: \n[FF]
+
+

Defines the format of automatically numbered footnotes, +and those for which the FS request is given a marker argument, at +the bottom of a column or page. This is a Berkeley extension. +

+
0
+

Set an automatic number8 as a +superscript (on typesetter devices) or surrounded by square brackets (on +terminals). The footnote paragraph is indented as with PP if +there is an FS argument or an automatic number, and as with +LP otherwise. This is the default. +

+
+
1
+

As 0, but set the marker as regular text and follow an +automatic number with a period. +

+
+
2
+

As 1, but without indentation (like LP). +

+
+
3
+

As 1, but set the footnote paragraph with the marker hanging +(like IP). +

+
+ +

Effective: next footnote. +

+

Default: 0. +

+ +
+
Register: \n[FPS]
+
+

Defines the footnote type size. +

+

Effective: next footnote. +

+

Default: \n[PS] - 2p. +

+ +
+
Register: \n[FVS]
+
+

Defines the footnote vertical spacing. +

+

Effective: next footnote. +

+

Default: \n[FPS] + 2p. +

+ +
+
Register: \n[FPD]
+
+

Defines the footnote paragraph spacing. This is a GNU extension. +

+

Effective: next footnote. +

+

Default: \n[PD] / 2. +

+ +
+
String: \*[FR]
+
+

Defines the ratio of the footnote line length to the current line +length. This is a GNU extension. +

+

Effective: next footnote in single-column arrangements, next page +otherwise. +

+

Default: 11/12. +

+ +
+
+

Display settings

+ +
+
Register: \n[DD]
+
+

Sets the display distance—the vertical spacing before and after a +display, a tbl table, an eqn equation, or a pic +image. This is a Berkeley extension. +

+

Effective: next display boundary. +

+

Default: 0.5v (1v on low-resolution devices). +

+ +
+
Register: \n[DI]
+
+

Sets the default amount by which to indent a display started with +DS and ID without arguments, to ‘.DS I’ without +an indentation argument, and to equations set with ‘.EQ I’. +This is a GNU extension. +

+

Effective: next indented display. +

+

Default: 0.5i. +

+ +
+
+

Other settings

+ +
+
Register: \n[MINGW]
+
+

Defines the default minimum width between columns in a multi-column +document. This is a GNU extension. +

+

Effective: next page. +

+

Default: 2n. +

+ +
+
Register: \n[TC-MARGIN]
+
+

Defines the width of the field in which page numbers are set in a table +of contents entry; the right margin thus moves inboard by this amount. +This is a GNU extension. +

+

Effective: next PX call. +

+

Default: \w'000' +

+ + + +
+
+
+ + + + + + diff --git a/doc/groff.html.node/ms-Document-Description-Macros.html b/doc/groff.html.node/ms-Document-Description-Macros.html new file mode 100644 index 0000000..4801e47 --- /dev/null +++ b/doc/groff.html.node/ms-Document-Description-Macros.html @@ -0,0 +1,189 @@ + + + + + + +ms Document Description Macros (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.4 Document Description Macros

+ + + +

Only the simplest document lacks a title.9 As its level of sophistication (or +complexity) increases, it tends to acquire a date of revision, +explicitly identified authors, sponsoring institutions for authors, and, +at the rarefied heights, an abstract of its content. Define these +data by calling the macros below in the order shown; DA or +ND can be called to set the document date (or other identifier) +at any time before (a) the abstract, if present, or (b) its information +is required in a header or footer. Use of these macros is optional, +except that TL is mandatory if any of RP, AU, +AI, or AB is called, and AE is mandatory if +AB is called. +

+
+
Macro: .RP [no-repeat-info] [no-renumber]
+
+

Use the “report” (AT&T: “released paper”) format for your +document, creating a separate cover page. The default arrangement is to +place most of the document description (title, author names and +institutions, and abstract, but not the date) at the top of the first +page. If the optional no-repeat-info argument is given, +ms produces a cover page but does not repeat any of its +information subsequently (but see the DA macro below regarding +the date). Normally, RP sets the page number following the cover +page to 1. Specifying the optional no-renumber argument +suppresses this alteration. Optional arguments can occur in any order. +no is recognized as a synonym of no-repeat-info for +AT&T compatibility. +

+ +
+
Macro: .TL
+
+

Specify the document title. ms collects text on input lines +following this call into the title until reaching AU, AB, +or a heading or paragraphing macro call. +

+ +
+
Macro: .AU
+
+

Specify an author’s name. ms collects text on input lines +following this call into the author’s name until reaching AI, +AB, another AU, or a heading or paragraphing macro call. +Call it repeatedly to specify multiple authors. +

+ +
+
Macro: .AI
+
+

Specify the preceding author’s institution. An AU call is +usefully followed by at most one AI call; if there are more, the +last AI call controls. ms collects text on input lines +following this call into the author’s institution until reaching +AU, AB, or a heading or paragraphing macro call. +

+ +
+
Macro: .DA [x …]
+
+

Typeset the current date, or any arguments x, in the center +footer, and, if RP is also called, left-aligned at the end of the +description information on the cover page. +

+ +
+
Macro: .ND [x …]
+
+

Typeset the current date, or any arguments x, if RP is also +called, left-aligned at the end of the document description on the cover +page. This is groff ms’s default. +

+ +
+
Macro: .AB [no]
+
+

Begin the abstract. ms collects text on input lines following +this call into the abstract until reaching an AE call. By +default, ms places the word “ABSTRACT” centered and in italics +above the text of the abstract. The optional argument no +suppresses this heading. +

+ +
+
Macro: .AE
+
+

End the abstract. +

+ +

An example document description, using a cover page, follows. + + +

+
+
+
.RP
+.TL
+The Inevitability of Code Bloat
+in Commercial and Free Software
+.AU
+J.\& Random Luser
+.AI
+University of West Bumblefuzz
+.AB
+This report examines the long-term growth of the code
+bases in two large,
+popular software packages;
+the free Emacs and the commercial Microsoft Word.
+While differences appear in the type or order of
+features added,
+due to the different methodologies used,
+the results are the same in the end.
+.PP
+The free software approach is shown to be superior in
+that while free software can become as bloated as
+commercial offerings,
+free software tends to have fewer serious bugs and the
+added features are more in line with user demand.
+.AE
+
+…the rest of the paper…
+
+
+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/ms-Document-Structure.html b/doc/groff.html.node/ms-Document-Structure.html new file mode 100644 index 0000000..de4be0e --- /dev/null +++ b/doc/groff.html.node/ms-Document-Structure.html @@ -0,0 +1,106 @@ + + + + + + +ms Document Structure (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.2 Document Structure

+ + +

The ms macro package expects a certain amount of structure: +a well-formed document contains at least one paragraphing or heading +macro call. Longer documents have a structure as follows. +

+
+
Document type
+

Calling the RP macro at the beginning of your document puts the +document description (see below) on a cover page. Otherwise, ms +places the information (if any) on the first page, followed immediately +by the body text. Some document types found in other ms +implementations are specific to AT&T or Berkeley, and are not +supported by groff ms. +

+
+
Format and layout
+

By setting registers and strings, you can configure your document’s +typeface, margins, spacing, headers and footers, and footnote +arrangement. See Document Control Settings. +

+
+
Document description
+

A document description consists of any of: a title, one or more authors’ +names and affiliated institutions, an abstract, and a date or other +identifier. See Document Description Macros. +

+
+
Body text
+

The main matter of your document follows its description (if any). +ms supports highly structured text consisting of paragraphs +interspersed with multi-level headings (chapters, sections, subsections, +and so forth) and augmented by lists, footnotes, tables, diagrams, and +similar material. See Body Text. +

+
+
Tables of contents
+

Macros enable the collection of entries for a table of contents (or +index) as the material they discuss appears in the document. You then +call a macro to emit the table of contents at the end of your document. +The table of contents must necessarily follow the rest of the text since +GNU troff is a single-pass formatter; it thus cannot determine +the page number of a division of the text until it has been set and +output. Since ms was designed for the production of hard copy, +the traditional procedure was to manually relocate the pages containing +the table of contents between the cover page and the body text. Today, +page resequencing is more often done in the digital domain. An index +works similarly, but because it typically needs to be sorted after +collection, its preparation requires separate processing. +

+
+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/ms-Footnotes.html b/doc/groff.html.node/ms-Footnotes.html new file mode 100644 index 0000000..8c5f1f5 --- /dev/null +++ b/doc/groff.html.node/ms-Footnotes.html @@ -0,0 +1,155 @@ + + + + + + +ms Footnotes (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.5.10 Footnotes

+ + + + + +

A footnote is typically anchored to a place in the text with a +marker, which is a small integer, a symbol such as a dagger, or +arbitrary user-specified text. +

+
+
String: \*[*]
+
+

Place an automatic number, an automatically generated numeric +footnote marker, in the text. Each time this string is interpolated, +the number it produces increments by one. Automatic numbers start at 1. +This is a Berkeley extension. +

+ +

Enclose the footnote text in FS and FE macro calls to set +it at the nearest available “foot”, or bottom, of a text column or +page. +

+
+
Macro: .FS [marker]
+
+
Macro: .FE
+
+

Begin (FS) and end (FE) a footnote. FS calls +FS-MARK with any supplied marker argument, which is then +also placed at the beginning of the footnote text. If marker is +omitted, the next pending automatic footnote number enqueued by +interpolation of the * string is used, and if none exists, +nothing is prefixed. +

+ +

You may not desire automatically numbered footnotes in spite of their +convenience. You can indicate a footnote with a symbol or other text by +specifying its marker at the appropriate place (for example, by using +\[dg] for the dagger glyph) and as an argument to the +FS macro. Such manual marks should be repeated as arguments to +FS or as part of the footnote text to disambiguate their +correspondence. You may wish to use \*{ and \*} to +superscript the marker at the anchor point, in the footnote text, or +both. +

+

groff ms provides a hook macro, FS-MARK, for +user-determined operations to be performed when the FS macro is +called. It is passed the same arguments as FS itself. An +application of FS-MARK is anchor placement for a hyperlink +reference, so that a footnote can link back to its referential +context.11 By default, this macro has an empty definition. +FS-MARK is a GNU extension. +

+ + + + +

Footnotes can be safely used within keeps and displays, but you should +avoid using automatically numbered footnotes within floating keeps. You +can place a second \** interpolation between a \** and its +corresponding FS call as long as each FS call occurs +after the corresponding \** and occurrences of FS +are in the same order as corresponding occurrences of \**. +

+

Footnote text is formatted as paragraphs are, using analogous +parameters. The registers FI, FPD, FPS, and +FVS correspond to PI, PD, PS, and CS, +respectively; FPD, FPS, and FVS are GNU extensions. +

+

The FF register controls the formatting of automatically numbered +footnote paragraphs and those for which FS is given a marker +argument. See Document Control Settings. +

+

The default footnote line length is 11/12ths of the normal line length +for compatibility with the expectations of historical ms +documents; you may wish to set the FR string to ‘1’ to align +with contemporary typesetting practices. In the +past,12 an FL register +was used for the line length in footnotes; however, setting this +register at document initialization time had no effect on the footnote +line length in multi-column arrangements.13 +

+

FR should be used in preference to the old FL register in +contemporary documents. The footnote line length is effectively +computed as ‘column-width * \*[FR]’. If an absolute +footnote line length is required, recall that arithmetic expressions in +roff input are evaluated strictly from left to right, with no +operator precedence (parentheses are honored). +

+
+
.ds FR 0+3i \" Set footnote line length to 3 inches.
+
+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/ms-Headers-and-Footers.html b/doc/groff.html.node/ms-Headers-and-Footers.html new file mode 100644 index 0000000..472f19c --- /dev/null +++ b/doc/groff.html.node/ms-Headers-and-Footers.html @@ -0,0 +1,122 @@ + + + + + + +ms Headers and Footers (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.6.1 Headers and footers

+ + + + + +

There are multiple ways to produce headers and footers. One is to +define the strings LH, CH, and RH to set the left, +center, and right headers, respectively; and LF, CF, and +RF to set the left, center, and right footers. This approach +suffices for documents that do not distinguish odd- and even-numbered +pages. +

+

Another method is to call macros that set headers or footers for odd- or +even-numbered pages. Each such macro takes a delimited argument +separating the left, center, and right header or footer texts from each +other. You can replace the neutral apostrophes (') shown below +with any character not appearing in the header or footer text. These +macros are Berkeley extensions. +

+
+
Macro: .OH 'left'center'right'
+
+
Macro: .EH 'left'center'right'
+
+
Macro: .OF 'left'center'right'
+
+
Macro: .EF 'left'center'right'
+
+

The OH and EH macros define headers for odd- (recto) +and even-numbered (verso) pages, respectively; the OF and +EF macros define footers for them. +

+ +

With either method, a percent sign % in header or footer text is +replaced by the current page number. By default, ms places no +header on a page numbered “1” (regardless of its number format). +

+
+
Macro: .P1
+
+

Typeset the header even on page 1. To be effective, this macro +must be called before the header trap is sprung on any page numbered +“1”; in practice, unless your page numbering is unusual, this means +that you should call it early, before TL or any heading or +paragraphing macro. This is a Berkeley extension. +

+ +

For even greater flexibility, ms is designed to permit the +redefinition of the macros that are called when the groff traps +that ordinarily cause the headers and footers to be output are sprung. +PT (“page trap”) is called by ms when the header is to +be written, and BT (“bottom trap”) when the footer is to be. +The groff page location trap that ms sets up to format the +header also calls the (normally undefined) HD macro after +PT; you can define HD if you need additional processing +after setting the header (for example, to draw a line below it). +The HD hook is a Berkeley extension. Any such macros you +(re)define must implement any desired specialization for odd-, even-, or +first numbered pages. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/ms-Insertions.html b/doc/groff.html.node/ms-Insertions.html new file mode 100644 index 0000000..bb58a90 --- /dev/null +++ b/doc/groff.html.node/ms-Insertions.html @@ -0,0 +1,181 @@ + + + + + + +ms Insertions (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.5.9 Tables, figures, equations, and references

+ + + + + + + + + +

The ms package is often used with the tbl, pic, +eqn, and refer preprocessors. + + + + +Mark text meant for preprocessors by enclosing it in pairs of tokens +as follows, with nothing between the dot and the macro name. The +preprocessors match these tokens only at the start of an input line. +

+
+
Macro: .TS [H]
+
+
Macro: .TE
+
+

Demarcate a table to be processed by the tbl preprocessor. The +optional argument H to TS instructs ms to +repeat table rows (often column headings) at the top of each new page +the table spans, if applicable; calling the TH macro marks the +end of such rows. The GNU tbl(1) man page provides a +comprehensive reference to the preprocessor and offers examples of its +use. +

+ +
+
Macro: .PS
+
+
Macro: .PE
+
+
Macro: .PF
+
+

PS begins a picture to be processed by the gpic +preprocessor; either of PE or PF ends it, the latter with +“flyback” to the vertical position at its top. You can create +pic input manually or with a program such as xfig. +

+ +
+
Macro: .EQ [align [label]]
+
+
Macro: .EN
+
+

Demarcate an equation to be processed by the eqn preprocessor. +The equation is centered by default; align can be ‘C’, +‘L’, or ‘I’ to (explicitly) center, left-align, or indent it +by the amount stored in the DI register, respectively. If +specified, label is set right-aligned. +

+ +
+
Macro: .[
+
+
Macro: .]
+
+

Demarcate a bibliographic citation to be processed by the refer +preprocessor. The GNU refer(1) man page provides a +comprehensive reference to the preprocessor and the format of its +bibliographic database. Type ‘man refer’ at the command line to +view it. +

+ +

When refer emits collected references (as might be done on a +“Works Cited” page), it interpolates the REFERENCES string as +an unnumbered heading (SH). +

+ + +

The following is an example of how to set up a table that may print +across two or more pages. +

+
+
+
.TS H
+allbox;
+Cb | Cb .
+Part→Description
+_
+.TH
+.T&
+GH-1978→Fribulating gonkulator
+…the rest of the table follows…
+.TE
+
+
+ +

Attempting to place a multi-page table inside a keep can lead to +unpleasant results, particularly if the tbl allbox option +is used. +

+ +

Mathematics can be typeset using the language of the eqn +preprocessor. +

+
+
+
.EQ C (\*[SN-NO-DOT]a)
+p ~ = ~ q sqrt { ( 1 + ~ ( x / q sup 2 ) }
+.EN
+
+
+ +

This input formats a labelled equation. We used the SN-NO-DOT +string to base the equation label on the current heading number, giving +us more flexibility to reorganize the document. +

+

Use groff options to run preprocessors on the input: +-e for geqn, -p for gpic, +-R for grefer, and -t for gtbl. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/ms-Introduction.html b/doc/groff.html.node/ms-Introduction.html new file mode 100644 index 0000000..4069ac7 --- /dev/null +++ b/doc/groff.html.node/ms-Introduction.html @@ -0,0 +1,60 @@ + + + + + + +ms Introduction (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.1 Introduction

+ +

The ms macros are the oldest surviving package for roff +systems.7 While the man +package was designed for brief reference documents, the ms macros +are also suitable for longer works intended for printing and possible +publication. +

+ + + +
+ + + + + diff --git a/doc/groff.html.node/ms-Legacy-Features.html b/doc/groff.html.node/ms-Legacy-Features.html new file mode 100644 index 0000000..2f24f41 --- /dev/null +++ b/doc/groff.html.node/ms-Legacy-Features.html @@ -0,0 +1,285 @@ + + + + + + +ms Legacy Features (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.8 Legacy Features

+ + + + + + + +

groff ms retains some legacy features solely to support +formatting of historical documents; contemporary ones should not use +them because they can render poorly. See the groff_char(7) +man page. +

+ +
+

AT&T accent mark strings

+ +

AT&T ms defined accent mark strings as follows. +

+
+
String: \*[']
+
+

Apply acute accent to subsequent glyph. +

+ +
+
String: \*[`]
+
+

Apply grave accent to subsequent glyph. +

+ +
+
String: \*[:]
+
+

Apply dieresis (umlaut) to subsequent glyph. +

+ +
+
String: \*[^]
+
+

Apply circumflex accent to subsequent glyph. +

+ +
+
String: \*[~]
+
+

Apply tilde accent to subsequent glyph. +

+ +
+
String: \*[C]
+
+

Apply caron to subsequent glyph. +

+ +
+
String: \*[,]
+
+

Apply cedilla to subsequent glyph. +

+ +
+
+

Berkeley accent mark and glyph strings

+ +

Berkeley ms offered an AM macro; calling it redefined the +AT&T accent mark strings (except for ‘\*C’), applied them to the +preceding glyph, and defined additional strings, some for spacing +glyphs. +

+
+
Macro: .AM
+
+

Enable alternative accent mark and glyph-producing strings. +

+ +
+
String: \*[']
+
+

Apply acute accent to preceding glyph. +

+ +
+
String: \*[`]
+
+

Apply grave accent to preceding glyph. +

+ +
+
String: \*[:]
+
+

Apply dieresis (umlaut) to preceding glyph. +

+ +
+
String: \*[^]
+
+

Apply circumflex accent to preceding glyph. +

+ +
+
String: \*[~]
+
+

Apply tilde accent to preceding glyph. +

+ +
+
String: \*[,]
+
+

Apply cedilla to preceding glyph. +

+ +
+
String: \*[/]
+
+

Apply stroke (slash) to preceding glyph. +

+ +
+
String: \*[v]
+
+

Apply caron to preceding glyph. +

+ +
+
String: \*[_]
+
+

Apply macron to preceding glyph. +

+ +
+
String: \*[.]
+
+

Apply underdot to preceding glyph. +

+ +
+
String: \*[o]
+
+

Apply ring accent to preceding glyph. +

+ +
+
String: \*[?]
+
+

Interpolate inverted question mark. +

+ +
+
String: \*[!]
+
+

Interpolate inverted exclamation mark. +

+ +
+
String: \*[8]
+
+

Interpolate small letter sharp s. +

+ +
+
String: \*[q]
+
+

Interpolate small letter o with hook accent (ogonek). +

+ +
+
String: \*[3]
+
+

Interpolate small letter yogh. +

+ +
+
String: \*[d-]
+
+

Interpolate small letter eth. +

+ +
+
String: \*[D-]
+
+

Interpolate capital letter eth. +

+ +
+
String: \*[th]
+
+

Interpolate small letter thorn. +

+ +
+
String: \*[Th]
+
+

Interpolate capital letter thorn. +

+ +
+
String: \*[ae]
+
+

Interpolate small ć ligature. +

+ +
+
String: \*[Ae]
+
+

Interpolate capital Ć ligature. +

+ +
+
String: \*[oe]
+
+

Interpolate small oe ligature. +

+ +
+
String: \*[OE]
+
+

Interpolate capital OE ligature. +

+ + +
+
+
+ + + + + + diff --git a/doc/groff.html.node/ms-Margins.html b/doc/groff.html.node/ms-Margins.html new file mode 100644 index 0000000..f47f698 --- /dev/null +++ b/doc/groff.html.node/ms-Margins.html @@ -0,0 +1,56 @@ + + + + + + +ms Margins (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.6.3 Margins

+ + +

Control margins using the registers summarized in “Margin settings” in +Document Control Settings above. There is no setting for the +right margin; the combination of page offset \n[PO] and line +length \n[LL] determines it. +

+ +
+ + + + + diff --git a/doc/groff.html.node/ms-Multiple-Columns.html b/doc/groff.html.node/ms-Multiple-Columns.html new file mode 100644 index 0000000..c95792f --- /dev/null +++ b/doc/groff.html.node/ms-Multiple-Columns.html @@ -0,0 +1,88 @@ + + + + + + +ms Multiple Columns (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.6.4 Multiple columns

+ + + +

ms can set text in as many columns as reasonably fit on the page. +The following macros force a page break if a multi-column layout is +active when they are called. The MINGW register stores the +default minimum gutter width; it is a GNU extension. When multiple +columns are in use, keeps and the HORPHANS and PORPHANS +registers work with respect to column breaks instead of page breaks. +

+
+
Macro: .1C
+
+

Arrange page text in a single column (the default). +

+ +
+
Macro: .2C
+
+

Arrange page text in two columns. +

+ +
+
Macro: .MC [column-width [gutter-width]]
+
+

Arrange page text in multiple columns. If you specify no arguments, it +is equivalent to the 2C macro. Otherwise, column-width is +the width of each column and gutter-width is the minimum distance +between columns. +

+ + +
+ + + + + diff --git a/doc/groff.html.node/ms-Naming-Conventions.html b/doc/groff.html.node/ms-Naming-Conventions.html new file mode 100644 index 0000000..db31955 --- /dev/null +++ b/doc/groff.html.node/ms-Naming-Conventions.html @@ -0,0 +1,89 @@ + + + + + + +ms Naming Conventions (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.9 Naming Conventions

+ + + +

The following conventions are used for names of macros, strings, and +registers. External names available to documents that use the +groff ms macros contain only uppercase letters and digits. +

+

Internally, the macros are divided into modules. Conventions for +identifier names are as follows. +

+
    +
  • Names used only within one module are of the form +module*name. + +
  • Names used outside the module in which they are defined are of the form +module@name. + +
  • Names associated with a particular environment are of the form +environment:name; these are used only within the +par module. + +
  • name does not have a module prefix. + +
  • Constructed names used to implement arrays are of the form +array!index. +
+ +

Thus the groff ms macros reserve the following names. +

+
    +
  • Names containing the characters *, @, and :. + +
  • Names containing only uppercase letters and digits. +
+ + + +
+ + + + + diff --git a/doc/groff.html.node/ms-Page-Layout.html b/doc/groff.html.node/ms-Page-Layout.html new file mode 100644 index 0000000..7bea36d --- /dev/null +++ b/doc/groff.html.node/ms-Page-Layout.html @@ -0,0 +1,64 @@ + + + + + + +ms Page Layout (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.6 Page layout

+ + + +

ms’s default page layout arranges text in a single column with +the page number between hyphens centered in a header on each page except +the first, and produces no footers. You can customize this arrangement. +

+ + + +
+ + + + + diff --git a/doc/groff.html.node/ms-TOC.html b/doc/groff.html.node/ms-TOC.html new file mode 100644 index 0000000..96a2f76 --- /dev/null +++ b/doc/groff.html.node/ms-TOC.html @@ -0,0 +1,242 @@ + + + + + + +ms TOC (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.6.5 Creating a table of contents

+ + + +

Because roff formatters process their input in a single pass, +material on page 50, for example, cannot influence what appears on +page 1—this poses a challenge for a table of contents at its +traditional location in front matter, if you wish to avoid manually +maintaining it. ms enables the collection of material to be +presented in the table of contents as it appears, saving its page number +along with it, and then emitting the collected contents on demand toward +the end of the document. The table of contents can then be resequenced +to its desired location by physically rearranging the pages of a printed +document, or as part of post-processing—with a sed(1) +script to reorder the pages in troff’s output, with +pdfjam(1), or with gropdf(1)’s +‘.pdfswitchtopage’ feature, for example. +

+

Define an entry to appear in the table of contents by bracketing its +text between calls to the XS and XE macros. A typical +application is to call them immediately after NH or SH and +repeat the heading text within them. The XA macro, used within +‘.XS’/‘.XE’ pairs, supplements an entry—for instance, when +it requires multiple output lines, whether because a heading is too long +to fit or because style dictates that page numbers not be repeated. You +may wish to indent the text thus wrapped to correspond to its heading +depth; this can be done in the entry text by prefixing it with tabs or +horizontal motion escape sequences, or by providing a second argument to +the XA macro. XS and XA automatically associate +the page number where they are called with the text following them, but +they accept arguments to override this behavior. At the end of the +document, call TC or PX to emit the table of contents; +TC resets the page number to ‘i’ (Roman numeral one), and +then calls PX. All of these macros are Berkeley extensions. +

+
+
Macro: .XS [page-number]
+
+
Macro: .XA [page-number [indentation]]
+
+
Macro: .XE
+
+

Begin, supplement, and end a table of contents entry. Each entry is +associated with page-number (otherwise the current page number); a +page-number of ‘no’ prevents a leader and page number from +being emitted for that entry. Use of XA within +XS/XE is optional; it can be repeated. If +indentation is present, a supplemental entry is indented by that +amount; ens are assumed if no unit is indicated. Text on input lines +between XS and XE is stored for later recall by PX. +

+ +
+
Macro: .PX [no]
+
+

Switch to single-column layout. Unless no is specified, center +and interpolate the TOC string in bold and two points larger than +the body text. Emit the table of contents entries. +

+ +
+
Macro: .TC [no]
+
+

Set the page number to 1, the page number format to lowercase Roman +numerals, and call PX (with a no argument, if present). +

+ +

Here’s an example of typical ms table of contents preparation. +We employ horizontal escape sequences \h to indent the entries by +sectioning depth. +

+
+
+
.NH 1
+Introduction
+.XS
+Introduction
+.XE
+
+.NH 2
+Methodology
+.XS
+\h'2n'Methodology
+.XA
+\h'4n'Fassbinder's Approach
+\h'4n'Kahiu's Approach
+.XE
+
+.NH 1
+Findings
+.XS
+Findings
+.XE
+
+.TC
+
+
+ +

The remaining features in this subsubsection are GNU extensions. +groff ms obviates the need to repeat heading text after +XS calls. Call XN and XH after NH and +SH, respectively. +

+
+
Macro: .XN heading-text
+
+
Macro: .XH depth heading-text
+
+

Format heading-text and create a corresponding table of contents +entry. XN computes the indentation from the depth of the +preceding NH call; XH requires a depth argument to +do so. +

+ +

groff ms encourages customization of table of contents +entry production. +

+
+
Macro: .XN-REPLACEMENT heading-text
+
+
Macro: .XH-REPLACEMENT depth heading-text
+
+

These hook macros implement XN and XH, respectively. +They call XN-INIT and pass their heading-text arguments to +XH-UPDATE-TOC. +

+ +
+
Macro: .XN-INIT
+
+
Macro: .XH-UPDATE-TOC depth heading-text
+
+

The XN-INIT hook macro does nothing by default. +XH-UPDATE-TOC brackets heading-text with XS and +XE calls, indenting it by 2 ens per level of depth beyond +the first. +

+ +

We could therefore produce a table of contents similar to that in the +previous example with fewer macro calls. (The difference is that this +input follows the “Approach” entries with leaders and page numbers.) +

+
+
+
.NH 1
+.XN Introduction
+
+.NH 2
+.XN Methodology
+.XH 3 "Fassbinder's Approach"
+.XH 3 "Kahiu's Approach"
+
+.NH 1
+.XN Findings
+
+
+
+ +

To get the section number of the numbered headings into the table of +contents entries, we might define XN-REPLACEMENT as follows. +(We obtain the heading depth from groff ms’s internal +register nh*hl.) +

+
+
+
.de XN-REPLACEMENT
+.XN-INIT
+.XH-UPDATE-TOC \\n[nh*hl] \\$@
+\&\\*[SN] \\$*
+..
+
+
+ +

You can change the style of the leader that bridges each table of +contents entry with its page number; define the TC-LEADER special +character by using the char request. A typical leader combines +the dot glyph ‘.’ with a horizontal motion escape sequence to +spread the dots. The width of the page number field is stored in the +TC-MARGIN register. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/ms-basic-information.html b/doc/groff.html.node/ms-basic-information.html new file mode 100644 index 0000000..cc87b0b --- /dev/null +++ b/doc/groff.html.node/ms-basic-information.html @@ -0,0 +1,211 @@ + + + + + + +ms basic information (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.1.1 Basic information

+ +

ms documents are plain text files; prepare them with your +preferred text editor. If you’re in a hurry to start, know that +ms needs one of its macros called at the beginning of a document +so that it can initialize. A macro is a formatting instruction to +ms. Put a macro call on a line by itself. Use ‘.PP’ if you +want your paragraph’s first line to be indented, or ‘.LP’ if you +don’t. +

+

After that, start typing normally. It is a good practice to start each +sentence on a new line, or to put two spaces after sentence-ending +punctuation, so that the formatter knows where the sentence boundaries +are. You can separate paragraphs with further paragraphing macros, or +with blank lines, and you can indent with tabs. When you need one of +the features mentioned earlier (see ms), return to this part of the +manual. +

+

Format the document with the groff command. nroff +can be useful for previewing. +

+
+
+
$ editor radical.ms
+$ nroff -ww -z -ms radical.ms # check for errors
+$ nroff -ms radical.ms | less -R
+$ groff -T ps -ms radical.ms > radical.ps
+$ see radical.ps
+
+
+ +

Our radical.ms document might look like this. +

+
+
+
.LP
+Radical novelties are so disturbing that they tend to be
+suppressed or ignored, to the extent that even the
+possibility of their existence in general is more often
+denied than admitted.
+
+→That's what Dijkstra said, anyway.
+
+
+ +

ms exposes many aspects of document layout to user control via +groff’s registers and strings, which store numbers +and text, respectively. Measurements in groff are expressed with +a suffix called a scaling unit. +

+
+
i
+

inches +

+
+
c
+

centimeters +

+
+
p
+

points (1/72 inch) +

+
+
P
+

picas (1/6 inch) +

+
+
v
+

vees; current vertical spacing +

+
+
m
+

ems; width of an “M” in the current font +

+
+
n
+

ens; one-half em +

+
+ +

Set registers with the nr request and strings with the ds +request. Requests are like macro calls; they go on lines by +themselves and start with the control character, a dot (.). +The difference is that they directly instruct the formatter program, +rather than the macro package. We’ll discuss a few as applicable. It +is wise to specify a scaling unit when setting any register that +represents a length, size, or distance. +

+
+
+
.nr PS 10.5p \" Use 10.5-point type.
+.ds FAM P    \" Use Palatino font family.
+
+
+ +

In the foregoing, we see that \" begins a comment. This is an +example of an escape sequence, the other kind of formatting +instruction. Escape sequences can appear anywhere. They begin with the +escape character (\) and are followed by at least one more +character. ms documents +tend to use only a few of groff’s many requests and escape +sequences; see Request Index and Escape Sequence Index or +the groff(7) man page for complete lists. +

+
+
\"
+

Begin comment; ignore remainder of line. +

+
+
\n[reg]
+

Interpolate value of register reg. +

+
+
\*[str]
+

Interpolate contents of string str. +

+
+
\*s
+

abbreviation of \*[s]; the name s must be only one +character +

+
+
\[char]
+

Interpolate glyph of special character named char. +

+
+
\&
+

dummy character +

+
+
\~
+

Insert an unbreakable space that is adjustable like a normal space. +

+
+
\|
+

Move horizontally by one-sixth em (“thin space”). +

+
+ +

Prefix any words that start with a dot ‘.’ or neutral apostrophe +‘'’ with \& if they are at the beginning of an input line +(or might become that way in editing) to prevent them from being +interpreted as macro calls or requests. Suffix ‘.’, ‘?’, and +‘!’ with \& when needed to cancel end-of-sentence detection. +

+
+
+
My exposure was \&.5 to \&.6 Sv of neutrons, said Dr.\&
+Wallace after the criticality incident.
+
+
+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/ms-keeps-and-displays.html b/doc/groff.html.node/ms-keeps-and-displays.html new file mode 100644 index 0000000..47088aa --- /dev/null +++ b/doc/groff.html.node/ms-keeps-and-displays.html @@ -0,0 +1,207 @@ + + + + + + +ms keeps and displays (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.5.8 Keeps, boxed keeps, and displays

+ + + + +

On occasion, you may want to keep several lines of text, or a +region of a document, together on a single page, preventing an automatic +page break within certain boundaries. This can cause a page break to +occur earlier than it normally would. For example, you may want to keep +two paragraphs together, or a paragraph that refers to a table, list, or +figure adjacent to the item it discusses. ms provides the +KS and KE macros for this purpose. +

+

You can alternatively specify a floating keep: if a keep cannot +fit on the current page, ms holds its contents and +allows material following the keep (in the source document) to fill the +remainder of the current page. When the page breaks, whether by +reaching the end or bp request, ms puts the floating keep +at the beginning of the next page. This is useful for placing large +graphics or tables that do not need to appear exactly where they occur +in the source document. +

+
+
Macro: .KS
+
+
Macro: .KF
+
+
Macro: .KE
+
+

KS begins a keep, KF a floating keep, and KE ends a +keep of either kind. +

+ +

As an alternative to the keep mechanism, the ne request forces a +page break if there is not at least the amount of vertical space +specified in its argument remaining on the page (see Page Control). +One application of ne is to reserve space on the page for a +figure or illustration to be included later. +

+ +

A boxed keep has a frame drawn around it. +

+
+
Macro: .B1
+
+
Macro: .B2
+
+

B1 begins a keep with a box drawn around it. B2 ends a +boxed keep. +

+ +

Boxed keep macros cause breaks; if you need to box a word or phrase +within a line, see the BX macro in Typeface and decoration. +Box lines are drawn as close as possible to the text they enclose so +that they are usable within paragraphs. If you wish to box one or more +paragraphs, you may improve the appearance by calling B1 after +the first paragraphing macro, and by adding a small amount of vertical +space before calling B2. +

+
+
+
.LP
+.B1
+.I Warning:
+Happy Fun Ball may suddenly accelerate to dangerous
+speeds.
+.sp \n[PD]/2 \" space by half the inter-paragraph distance
+.B2
+
+
+ +

If you want a boxed keep to float, you will need to enclose the +B1 and B2 calls within a pair of KF and KE +calls. +

+ +

Displays turn off filling; lines of verse or program code are +shown with their lines broken as in the source document without +requiring br requests between lines. Displays can be kept on a +single page or allowed to break across pages. The DS macro +begins a kept display of the layout specified in its first argument; +non-kept displays are begun with dedicated macros corresponding to their +layout. +

+
+
Macro: .DS L
+
+
Macro: .LD
+
+

Begin (DS: kept) left-aligned display. +

+ +
+
Macro: .DS [I [indent]]
+
+
Macro: .ID [indent]
+
+

Begin (DS: kept) display indented by indent if specified, +and by the amount of the DI register otherwise. +

+ +
+
Macro: .DS B
+
+
Macro: .BD
+
+

Begin a (DS: kept) a block display: the entire display is +left-aligned, but indented such that the longest line in the display +is centered on the page. +

+ +
+
Macro: .DS C
+
+
Macro: .CD
+
+

Begin a (DS: kept) centered display: each line in the display +is centered. +

+ +
+
Macro: .DS R
+
+
Macro: .RD
+
+

Begin a (DS: kept) right-aligned display. This is a GNU +extension. +

+ +
+
Macro: .DE
+
+

End any display. +

+ +

The distance stored in the DD register is inserted before and +after each pair of display macros; this is a Berkeley extension. In +groff ms, this distance replaces any adjacent +inter-paragraph distance or subsequent spacing prior to a section +heading. The DI register is a GNU extension; its value is an +indentation applied to displays created with ‘.DS’ and ‘.ID’ +without arguments, to ‘.DS I’ without an indentation argument, and +to indented equations set with ‘.EQ’. Changes to either register +take effect at the next display boundary. +

+ +
+
+ + + + + + diff --git a/doc/groff.html.node/ms-language-and-localization.html b/doc/groff.html.node/ms-language-and-localization.html new file mode 100644 index 0000000..032b4a0 --- /dev/null +++ b/doc/groff.html.node/ms-language-and-localization.html @@ -0,0 +1,135 @@ + + + + + + +ms language and localization (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

4.6.5.11 Language and localization

+ + + + + +

groff ms provides several strings that you can customize +for your own purposes, or redefine to adapt the macro package to +languages other than English. It is already localized for +Czech, German, French, Italian, and Swedish. Load the desired +localization macro package after ms; see the +groff_tmac(5) man page. +

+
+
+
$ groff -ms -mfr bienvenue.ms
+
+
+ +

The following strings are available. +

+
+
String: \*[REFERENCES]
+
+

Contains the string printed at the beginning of a references +(bibliography) page produced with GNU refer(1). The default +is ‘References’. +

+ +
+
String: \*[ABSTRACT]
+
+

Contains the string printed at the beginning of the abstract. The +default is ‘\f[I]ABSTRACT\f[]’; it includes font selection escape +sequences to set the word in italics. +

+ +
+
String: \*[TOC]
+
+

Contains the string printed at the beginning of the table of contents. +The default is ‘Table of Contents’. +

+ +
+
String: \*[MONTH1]
+
+
String: \*[MONTH2]
+
+
String: \*[MONTH3]
+
+
String: \*[MONTH4]
+
+
String: \*[MONTH5]
+
+
String: \*[MONTH6]
+
+
String: \*[MONTH7]
+
+
String: \*[MONTH8]
+
+
String: \*[MONTH9]
+
+
String: \*[MONTH10]
+
+
String: \*[MONTH11]
+
+
String: \*[MONTH12]
+
+

Contain the full names of the calendar months. The defaults are in +English: ‘January’, ‘February’, and so on. +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/ms.html b/doc/groff.html.node/ms.html new file mode 100644 index 0000000..aaf7bf1 --- /dev/null +++ b/doc/groff.html.node/ms.html @@ -0,0 +1,75 @@ + + + + + + +ms (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + +
+ +
+

4.6 ms

+ + +

The ms (“manuscript”) package is suitable for the preparation +of letters, memoranda, reports, and books. These groff +macros feature cover page and table of contents generation, +automatically numbered headings, several paragraph styles, a variety of +text styling options, footnotes, and multi-column page layouts. +ms supports the tbl, eqn, pic, and +refer preprocessors for inclusion of tables, mathematical +equations, diagrams, and standardized bibliographic citations. This +implementation is mostly compatible with the documented interface and +behavior of AT&T Unix Version 7 ms. Many extensions from +4.2BSD (Berkeley) +and Tenth Edition Research Unix have been recreated. +

+ + + +
+ + + + + diff --git a/doc/groff.html.node/troff-and-nroff-Modes.html b/doc/groff.html.node/troff-and-nroff-Modes.html new file mode 100644 index 0000000..257d36e --- /dev/null +++ b/doc/groff.html.node/troff-and-nroff-Modes.html @@ -0,0 +1,114 @@ + + + + + + +troff and nroff Modes (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + + +
+ +
+

5.14 troff and nroff Modes

+ + + + + +

Historically, nroff and troff were two separate programs; +the former for terminal output, the latter for typesetters. GNU +troff merges both functions into one executable68 that sends its output to a +device driver (grotty for terminal devices, grops for +PostScript, and so on) which interprets this intermediate output format. +When discussing AT&T troff, it makes sense to talk +about nroff mode and troff mode since the +differences are hard-coded. GNU troff takes information from +device and font description files without handling requests specially if +a terminal output device is used, so such a strong distinction is +unnecessary. +

+

Usually, a macro package can be used with all output devices. +Nevertheless, it is sometimes necessary to make a distinction between +terminal and non-terminal devices: GNU troff provides two +built-in conditions ‘n’ and ‘t’ for the if, ie, +and while requests to decide whether GNU troff shall +behave like nroff or like troff. +

+
+
Request: .troff
+
+ + +

Make the ‘t’ built-in condition true (and the ‘n’ built-in +condition false) for if, ie, and while conditional +requests. This is the default if GNU troff (not +groff) is started with the -R switch to avoid loading of +the startup files troffrc and troffrc-end. Without +-R, GNU troff stays in troff mode if the output +device is not a terminal (e.g., ‘ps’). +

+ +
+
Request: .nroff
+
+ +

Make the ‘n’ built-in condition true (and the ‘t’ built-in +condition false) for if, ie, and while conditional +requests. This is the default if GNU troff uses a terminal +output device; the code for switching to nroff mode is in the +file tty.tmac, which is loaded by the startup file +troffrc. +

+ +

See Conditionals and Loops, for more details on built-in conditions. +

+ + +
+
+ + + + + + diff --git a/doc/groff.html.node/while.html b/doc/groff.html.node/while.html new file mode 100644 index 0000000..f9a0bae --- /dev/null +++ b/doc/groff.html.node/while.html @@ -0,0 +1,161 @@ + + + + + + +while (The GNU Troff Manual) + + + + + + + + + + + + + + + + + + + +
+ +
+

5.23.5 while

+ + +

groff provides a looping construct: the while request. +Its syntax matches the if request. +

+ +
+
Request: .while cond-expr anything
+
+

Evaluate the conditional expression cond-expr, and repeatedly +execute anything unless and until cond-expr evaluates false. +anything, which is often a conditional block, is referred to as +the while request’s body. +

+
+
.nr a 0 1
+.while (\na < 9) \{\
+\n+a,
+.\}
+\n+a
+    ⇒ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
+
+ + +

GNU troff treats the body of a while request similarly to +that of a de request (albeit one not read in copy +mode94), but stores it under an internal name +and deletes it when the loop finishes. The operation of a macro +containing a while request can slow significantly if the +while body is large. Each time the macro is executed, the +while body is parsed and stored again. +

+
+
.de xxx
+.  nr num 10
+.  while (\\n[num] > 0) \{\
+.    \" many lines of code
+.    nr num -1
+.  \}
+..
+
+ + + +

An often better solution—and one that is more portable, since +AT&T troff lacked the while request—is to +instead write a recursive macro. It will be parsed only +once.95 +

+
+
.de yyy
+.  if (\\n[num] > 0) \{\
+.    \" many lines of code
+.    nr num -1
+.    yyy
+.  \}
+..
+.
+.de xxx
+.  nr num 10
+.  yyy
+..
+
+ +

To prevent infinite loops, the default number of available recursion +levels is 1,000 or somewhat less.96 You can +disable this protective measure, or raise the limit, by setting the +slimit register. See Debugging. +

+

As noted above, if a while body begins with a conditional block, +its closing brace must end an input line. +

+
+
.if 1 \{\
+.  nr a 0 1
+.  while (\n[a] < 10) \{\
+.    nop \n+[a]
+.\}\}
+    error→ unbalanced brace escape sequences
+
+
+ +
+
Request: .break
+
+ + + +

Exit a while loop. Do not confuse this request with a +typographical break or the br request. +

+ +
+
Request: .continue
+
+

Skip the remainder of a while loop’s body, immediately starting +the next iteration. +

+ + + +
+
+ + + + + + diff --git a/doc/groff.info b/doc/groff.info new file mode 100644 index 0000000..0b36c23 --- /dev/null +++ b/doc/groff.info @@ -0,0 +1,423 @@ +This is groff.info, produced by makeinfo version 7.0.3 from groff.texi. + +This manual documents GNU 'troff' version 1.23.0. + + Copyright Š 1994-2023 Free Software Foundation, Inc. + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.3 or any later version published by the Free Software + Foundation; with no Invariant Sections, no Front-Cover Texts, and + no Back-Cover Texts. A copy of the license is included in the + section entitled "GNU Free Documentation License". +INFO-DIR-SECTION Typesetting +START-INFO-DIR-ENTRY +* Groff: (groff). The GNU roff document formatting system. +END-INFO-DIR-ENTRY + + +Indirect: +groff.info-1: 723 +groff.info-2: 303755 +groff.info-3: 616581 + +Tag Table: +(Indirect) +Node: Top723 +Node: Introduction1683 +Node: Background2155 +Node: What Is groff?3968 +Node: groff Capabilities4894 +Node: Macro Package Intro6241 +Node: Preprocessor Intro6920 +Node: Preprocessor Intro-Footnotes8331 +Ref: Preprocessor Intro-Footnote-18413 +Node: Output Device Intro8492 +Node: Installation9120 +Node: Conventions Used in This Manual9504 +Node: Conventions Used in This Manual-Footnotes12548 +Ref: Conventions Used in This Manual-Footnote-112656 +Ref: Conventions Used in This Manual-Footnote-212844 +Node: Credits12873 +Node: Invoking groff13398 +Node: Invoking groff-Footnotes14739 +Ref: Invoking groff-Footnote-114813 +Node: Groff Options14866 +Node: Environment27526 +Node: Macro Directories30791 +Node: Macro Directories-Footnotes32254 +Ref: Macro Directories-Footnote-132334 +Node: Font Directories32407 +Node: Paper Format34380 +Node: Invocation Examples35840 +Node: Tutorial for Macro Users37422 +Node: Basics38129 +Node: Basics-Footnotes44199 +Ref: Basics-Footnote-144257 +Node: Common Features44415 +Node: Paragraphs45648 +Node: Sections and Chapters47257 +Node: Headers and Footers47761 +Node: Page Layout Adjustment48487 +Node: Displays and Keeps48979 +Node: Footnotes and Endnotes50257 +Node: Table of Contents50860 +Node: Indexing51812 +Node: Document Formats52253 +Node: Columnation52749 +Node: Font and Size Changes53032 +Node: Predefined Text53542 +Node: Preprocessor Support53852 +Node: Configuration and Customization54295 +Node: Major Macro Packages54667 +Node: man55737 +Node: Optional man extensions56224 +Node: mdoc60222 +Node: me60495 +Node: mm61061 +Node: mom61398 +Node: ms62297 +Node: ms Introduction63317 +Node: ms Introduction-Footnotes63762 +Ref: ms Introduction-Footnote-163838 +Node: ms basic information64073 +Node: ms Document Structure67998 +Node: ms Document Control Settings70473 +Node: ms Document Control Settings-Footnotes79653 +Ref: ms Document Control Settings-Footnote-179755 +Node: ms Document Description Macros79795 +Node: ms Document Description Macros-Footnotes84030 +Ref: ms Document Description Macros-Footnote-184136 +Node: ms Body Text84257 +Node: Text settings in ms84898 +Node: Typographical symbols in ms86081 +Node: Paragraphs in ms86721 +Node: Headings in ms89617 +Node: Typeface and decoration94721 +Node: Typeface and decoration-Footnotes98631 +Ref: Typeface and decoration-Footnote-198723 +Node: Lists in ms99063 +Node: Indented regions in ms102246 +Node: ms keeps and displays103228 +Node: ms Insertions107422 +Node: ms Footnotes110390 +Node: ms Footnotes-Footnotes114176 +Ref: ms Footnotes-Footnote-1114246 +Ref: ms Footnotes-Footnote-2114371 +Ref: ms Footnotes-Footnote-3114462 +Node: ms language and localization114532 +Node: ms Page Layout116058 +Node: ms Headers and Footers116520 +Node: Tab Stops in ms119000 +Node: ms Margins119381 +Node: ms Multiple Columns119765 +Node: ms TOC120726 +Node: Differences from AT&T ms126332 +Node: Differences from AT&T ms-Footnotes131038 +Ref: Differences from AT&T ms-Footnote-1131132 +Ref: Differences from AT&T ms-Footnote-2131258 +Ref: Differences from AT&T ms-Footnote-3131348 +Node: Missing Unix Version 7 ms Macros131620 +Node: Missing Unix Version 7 ms Macros-Footnotes132934 +Ref: Missing Unix Version 7 ms Macros-Footnote-1133044 +Node: ms Legacy Features133212 +Node: ms Naming Conventions135940 +Node: GNU troff Reference136988 +Node: Text138082 +Node: Filling139361 +Node: Filling-Footnotes140444 +Ref: Filling-Footnote-1140504 +Ref: Filling-Footnote-2140555 +Node: Sentences140825 +Node: Sentences-Footnotes145108 +Ref: Sentences-Footnote-1145172 +Ref: Sentences-Footnote-2145389 +Ref: Sentences-Footnote-3145651 +Node: Hyphenation145830 +Node: Breaking146782 +Node: Breaking-Footnotes149367 +Ref: Breaking-Footnote-1149429 +Node: Adjustment149494 +Node: Tabs and Leaders149985 +Node: Tabs and Leaders-Footnotes151169 +Ref: Tabs and Leaders-Footnote-1151247 +Node: Requests and Macros151362 +Node: Requests and Macros-Footnotes157082 +Ref: Requests and Macros-Footnote-1157166 +Ref: Requests and Macros-Footnote-2157277 +Ref: Requests and Macros-Footnote-3157378 +Ref: Requests and Macros-Footnote-4157439 +Node: Macro Packages157508 +Node: Macro Packages-Footnotes158336 +Ref: Macro Packages-Footnote-1158410 +Node: Input Encodings158492 +Node: Input Encodings-Footnotes161415 +Ref: Input Encodings-Footnote-1161491 +Ref: Input Encodings-Footnote-2161688 +Node: Input Conventions161863 +Node: Input Conventions-Footnotes166824 +Ref: Input Conventions-Footnote-1166904 +Node: Page Geometry166958 +Node: Page Geometry-Footnotes170630 +Ref: Page Geometry-Footnote-1170702 +Ref: Page Geometry-Footnote-2170762 +Node: Measurements170831 +Node: Motion Quanta172770 +Node: Default Units173707 +Node: Numeric Expressions175213 +Node: Numeric Expressions-Footnotes183975 +Ref: Numeric Expressions-Footnote-1184059 +Ref: Numeric Expressions-Footnote-2184152 +Ref: Numeric Expressions-Footnote-3184251 +Ref: Numeric Expressions-Footnote-4184291 +Ref: Numeric Expressions-Footnote-5184513 +Node: Identifiers184541 +Node: Identifiers-Footnotes189589 +Ref: Identifiers-Footnote-1189657 +Ref: Identifiers-Footnote-2190254 +Node: Formatter Instructions190373 +Node: Control Characters191643 +Node: Control Characters-Footnotes193934 +Ref: Control Characters-Footnote-1194016 +Node: Invoking Requests194052 +Node: Invoking Requests-Footnotes196161 +Ref: Invoking Requests-Footnote-1196241 +Node: Calling Macros196411 +Node: Calling Macros-Footnotes200319 +Ref: Calling Macros-Footnote-1200393 +Ref: Calling Macros-Footnote-2200457 +Node: Using Escape Sequences200630 +Node: Using Escape Sequences-Footnotes205504 +Ref: Using Escape Sequences-Footnote-1205594 +Ref: Using Escape Sequences-Footnote-2205696 +Node: Delimiters205736 +Node: Comments208561 +Node: Comments-Footnotes211181 +Ref: Comments-Footnote-1211243 +Ref: Comments-Footnote-2211305 +Ref: Comments-Footnote-3211341 +Node: Registers211504 +Node: Setting Registers212084 +Node: Interpolating Registers216559 +Node: Auto-increment217536 +Node: Auto-increment-Footnotes219451 +Ref: Auto-increment-Footnote-1219525 +Node: Assigning Register Formats219598 +Node: Built-in Registers223328 +Node: Built-in Registers-Footnotes227032 +Ref: Built-in Registers-Footnote-1227114 +Node: Manipulating Filling and Adjustment227198 +Node: Manipulating Filling and Adjustment-Footnotes240315 +Ref: Manipulating Filling and Adjustment-Footnote-1240431 +Ref: Manipulating Filling and Adjustment-Footnote-2240479 +Ref: Manipulating Filling and Adjustment-Footnote-3240514 +Node: Manipulating Hyphenation240634 +Node: Manipulating Hyphenation-Footnotes258827 +Ref: Manipulating Hyphenation-Footnote-1258921 +Ref: Manipulating Hyphenation-Footnote-2259086 +Ref: Manipulating Hyphenation-Footnote-3259175 +Ref: Manipulating Hyphenation-Footnote-4259316 +Ref: Manipulating Hyphenation-Footnote-5259639 +Ref: Manipulating Hyphenation-Footnote-6259813 +Node: Manipulating Spacing259881 +Node: Manipulating Spacing-Footnotes265594 +Ref: Manipulating Spacing-Footnote-1265680 +Ref: Manipulating Spacing-Footnote-2265717 +Ref: Manipulating Spacing-Footnote-3265760 +Ref: Manipulating Spacing-Footnote-4265828 +Node: Tabs and Fields265887 +Node: Tabs and Fields-Footnotes272139 +Ref: Tabs and Fields-Footnote-1272215 +Node: Leaders272279 +Node: Leaders-Footnotes274266 +Ref: Leaders-Footnote-1274326 +Node: Fields274486 +Node: Character Translations275876 +Node: troff and nroff Modes279395 +Node: troff and nroff Modes-Footnotes281486 +Ref: troff and nroff Modes-Footnote-1281574 +Node: Line Layout281682 +Node: Line Continuation287718 +Node: Line Continuation-Footnotes290503 +Ref: Line Continuation-Footnote-1290583 +Node: Page Layout290925 +Node: Page Layout-Footnotes294492 +Ref: Page Layout-Footnote-1294560 +Node: Page Control294583 +Node: Page Control-Footnotes299166 +Ref: Page Control-Footnote-1299236 +Node: Using Fonts299264 +Node: Using Fonts-Footnotes302473 +Ref: Using Fonts-Footnote-1302541 +Ref: Using Fonts-Footnote-2302742 +Ref: Using Fonts-Footnote-3302830 +Ref: Using Fonts-Footnote-4302986 +Node: Selecting Fonts303755 +Node: Font Families308177 +Node: Font Families-Footnotes312061 +Ref: Font Families-Footnote-1312133 +Node: Font Positions312167 +Node: Using Symbols315056 +Node: Using Symbols-Footnotes333721 +Ref: Using Symbols-Footnote-1333793 +Ref: Using Symbols-Footnote-2333911 +Ref: Using Symbols-Footnote-3334033 +Ref: Using Symbols-Footnote-4334069 +Node: Character Classes334229 +Node: Special Fonts337008 +Node: Artificial Fonts338195 +Node: Ligatures and Kerning343712 +Node: Italic Corrections347081 +Node: Dummy Characters348505 +Node: Dummy Characters-Footnotes351282 +Ref: Dummy Characters-Footnote-1351360 +Node: Manipulating Type Size and Vertical Spacing351819 +Node: Manipulating Type Size and Vertical Spacing-Footnotes352771 +Ref: Manipulating Type Size and Vertical Spacing-Footnote-1352903 +Ref: Manipulating Type Size and Vertical Spacing-Footnote-2353261 +Node: Changing the Type Size353349 +Node: Changing the Type Size-Footnotes356390 +Ref: Changing the Type Size-Footnote-1356480 +Node: Changing the Vertical Spacing356622 +Node: Using Fractional Type Sizes359239 +Node: Using Fractional Type Sizes-Footnotes362878 +Ref: Using Fractional Type Sizes-Footnote-1362978 +Node: Colors363029 +Node: Colors-Footnotes367195 +Ref: Colors-Footnote-1367253 +Node: Strings367298 +Ref: als375644 +Node: Strings-Footnotes377468 +Ref: Strings-Footnote-1377528 +Node: Conditionals and Loops377555 +Node: Operators in Conditionals378008 +Node: Operators in Conditionals-Footnotes382841 +Ref: Operators in Conditionals-Footnote-1382937 +Ref: Operators in Conditionals-Footnote-2383111 +Ref: Operators in Conditionals-Footnote-3383421 +Ref: Operators in Conditionals-Footnote-4383552 +Ref: Operators in Conditionals-Footnote-5383693 +Node: if-then383766 +Node: if-else385440 +Node: Conditional Blocks386605 +Node: Conditional Blocks-Footnotes389892 +Ref: Conditional Blocks-Footnote-1389974 +Node: while389997 +Node: while-Footnotes392531 +Ref: while-Footnote-1392587 +Ref: while-Footnote-2392614 +Ref: while-Footnote-3392645 +Node: Writing Macros392733 +Node: Writing Macros-Footnotes399609 +Ref: Writing Macros-Footnote-1399683 +Ref: Writing Macros-Footnote-2399710 +Ref: Writing Macros-Footnote-3399915 +Node: Parameters400164 +Node: Parameters-Footnotes404230 +Ref: Parameters-Footnote-1404296 +Node: Copy Mode404707 +Node: Copy Mode-Footnotes410433 +Ref: Copy Mode-Footnote-1410497 +Ref: Copy Mode-Footnote-2410561 +Node: Page Motions410647 +Node: Page Motions-Footnotes420569 +Ref: Page Motions-Footnote-1420639 +Ref: Page Motions-Footnote-2420829 +Node: Drawing Geometric Objects420895 +Node: Drawing Geometric Objects-Footnotes429469 +Ref: Drawing Geometric Objects-Footnote-1429565 +Node: Deferring Output429662 +Node: Traps432701 +Node: Vertical Position Traps433531 +Node: Page Location Traps434625 +Node: Page Location Traps-Footnotes442638 +Ref: Page Location Traps-Footnote-1442722 +Ref: Page Location Traps-Footnote-2442762 +Ref: Page Location Traps-Footnote-3442850 +Node: The Implicit Page Trap443048 +Node: The Implicit Page Trap-Footnotes444309 +Ref: The Implicit Page Trap-Footnote-1444399 +Ref: The Implicit Page Trap-Footnote-2444426 +Node: Diversion Traps444454 +Node: Input Line Traps445241 +Node: Blank Line Traps448690 +Node: Leading Space Traps449222 +Node: End-of-input Traps450106 +Node: End-of-input Traps-Footnotes454067 +Ref: End-of-input Traps-Footnote-1454149 +Ref: End-of-input Traps-Footnote-2454300 +Node: Diversions454402 +Node: Diversions-Footnotes463874 +Ref: Diversions-Footnote-1463940 +Node: Punning Names464008 +Node: Punning Names-Footnotes467295 +Ref: Punning Names-Footnote-1467367 +Node: Environments467421 +Node: Suppressing Output472573 +Node: I/O475340 +Node: Postprocessor Access484470 +Node: Postprocessor Access-Footnotes487454 +Ref: Postprocessor Access-Footnote-1487540 +Ref: Postprocessor Access-Footnote-2487600 +Node: Miscellaneous487776 +Node: Miscellaneous-Footnotes494416 +Ref: Miscellaneous-Footnote-1494488 +Ref: Miscellaneous-Footnote-2494524 +Node: Gtroff Internals494774 +Node: Gtroff Internals-Footnotes499136 +Ref: Gtroff Internals-Footnote-1499214 +Node: Debugging499355 +Node: Warnings506281 +Node: Implementation Differences511010 +Node: Safer Mode511464 +Node: Compatibility Mode511946 +Node: Compatibility Mode-Footnotes517233 +Ref: Compatibility Mode-Footnote-1517315 +Node: Other Differences517696 +Node: Other Differences-Footnotes524092 +Ref: Other Differences-Footnote-1524172 +Ref: Other Differences-Footnote-2524252 +Ref: Other Differences-Footnote-3524429 +Node: File Formats524649 +Node: gtroff Output524960 +Node: gtroff Output-Footnotes526820 +Ref: gtroff Output-Footnote-1526892 +Node: Language Concepts527027 +Node: Separation528140 +Node: Argument Units530374 +Node: Document Parts531511 +Node: Command Reference532909 +Node: Comment Command533325 +Node: Simple Commands533823 +Node: Graphics Commands539265 +Node: Device Control Commands546605 +Node: Obsolete Command550738 +Node: Intermediate Output Examples552015 +Node: Output Language Compatibility554799 +Node: Device and Font Description Files556878 +Node: Device and Font Description Files-Footnotes558261 +Ref: Device and Font Description Files-Footnote-1558373 +Node: DESC File Format558434 +Node: Font Description File Format564511 +Node: Font Description File Format-Footnotes572537 +Ref: Font Description File Format-Footnote-1572639 +Ref: Font Description File Format-Footnote-2572793 +Ref: Font Description File Format-Footnote-3573006 +Ref: Font Description File Format-Footnote-4573115 +Node: Copying This Manual573202 +Node: Request Index598317 +Node: Escape Sequence Index616581 +Node: Operator Index623925 +Node: Register Index625858 +Node: Macro Index640236 +Node: String Index651800 +Node: File Keyword Index659362 +Node: Program and File Index663322 +Node: Concept Index669178 + +End Tag Table + + +Local Variables: +coding: iso-8859-1 +End: diff --git a/doc/groff.info-1 b/doc/groff.info-1 new file mode 100644 index 0000000..e2db4ec --- /dev/null +++ b/doc/groff.info-1 @@ -0,0 +1,7824 @@ +This is groff.info, produced by makeinfo version 7.0.3 from groff.texi. + +This manual documents GNU 'troff' version 1.23.0. + + Copyright Š 1994-2023 Free Software Foundation, Inc. + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.3 or any later version published by the Free Software + Foundation; with no Invariant Sections, no Front-Cover Texts, and + no Back-Cover Texts. A copy of the license is included in the + section entitled "GNU Free Documentation License". +INFO-DIR-SECTION Typesetting +START-INFO-DIR-ENTRY +* Groff: (groff). The GNU roff document formatting system. +END-INFO-DIR-ENTRY + + +File: groff.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir) + +GNU 'troff' +*********** + +* Menu: + +* Introduction:: +* Invoking groff:: +* Tutorial for Macro Users:: +* Major Macro Packages:: +* GNU troff Reference:: +* File Formats:: +* Copying This Manual:: +* Request Index:: +* Escape Sequence Index:: +* Operator Index:: +* Register Index:: +* Macro Index:: +* String Index:: +* File Keyword Index:: +* Program and File Index:: +* Concept Index:: + +This manual documents GNU 'troff' version 1.23.0. + + Copyright Š 1994-2023 Free Software Foundation, Inc. + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.3 or any later version published by the Free Software + Foundation; with no Invariant Sections, no Front-Cover Texts, and + no Back-Cover Texts. A copy of the license is included in the + section entitled "GNU Free Documentation License". + + +File: groff.info, Node: Introduction, Next: Invoking groff, Prev: Top, Up: Top + +1 Introduction +************** + +GNU 'roff' (or 'groff') is a programming system for typesetting +documents. It is highly flexible and has been used extensively for over +thirty years. + +* Menu: + +* Background:: +* What Is groff?:: +* groff Capabilities:: +* Macro Package Intro:: +* Preprocessor Intro:: +* Output Device Intro:: +* Conventions Used in This Manual:: +* Installation:: +* Credits:: + + +File: groff.info, Node: Background, Next: What Is groff?, Prev: Introduction, Up: Introduction + +1.1 Background +============== + +M. Douglas McIlroy, formerly of AT&T Bell Laboratories and present at +the creation of the Unix operating system, offers an authoritative +historical summary. + + The prime reason for Unix was the desire of Ken [Thompson], Dennis + [Ritchie], and Joe Ossanna to have a pleasant environment for + software development. The fig leaf that got the nod from ... + management was that an early use would be to develop a + "stand-alone" word-processing system for use in typing pools and + secretarial offices. Perhaps they had in mind "dedicated", as + distinct from "stand-alone"; that's what eventuated in various + cases, most notably in the legal/patent department and in the AT&T + CEO's office. + + Both those systems were targets of opportunity, not foreseen from + the start. When Unix was up and running on the PDP-11, Joe got + wind of the legal department having installed a commercial word + processor. He went to pitch Unix as an alternative and clinched a + trial by promising to make 'roff' able to number lines by tomorrow + in order to fulfill a patent-office requirement that the commercial + system did not support. + + Modems were installed so legal-department secretaries could try the + Research machine. They liked it and Joe's superb customer service. + Soon the legal department got a system of their own. Joe went on + to create 'nroff' and 'troff'. Document preparation became a + widespread use of Unix, but no stand-alone word-processing system + was ever undertaken. + + A history relating 'groff' to its predecessors 'roff', 'nroff', and +'troff' is available in the 'roff(7)' man page. + + +File: groff.info, Node: What Is groff?, Next: groff Capabilities, Prev: Introduction, Up: Introduction + +1.2 What Is 'groff'? +==================== + +'groff' (GNU 'roff') is a typesetting system that reads plain text input +files that include formatting commands to produce output in PostScript, +PDF, HTML, DVI, or other formats, or for display to a terminal. +Formatting commands can be low-level typesetting primitives, macros from +a supplied package, or user-defined macros. All three approaches can be +combined. + + A reimplementation and extension of the typesetter from AT&T Unix, +'groff' is present on most POSIX systems owing to its long association +with Unix manuals (including man pages). It and its predecessor are +notable for their production of several best-selling software +engineering texts. 'groff' is capable of producing typographically +sophisticated documents while consuming minimal system resources. + + +File: groff.info, Node: groff Capabilities, Next: Macro Package Intro, Prev: What Is groff?, Up: Introduction + +1.3 'groff' Capabilities +======================== + +GNU 'troff' is a typesetting document formatter; it provides a wide +range of low-level text and page operations within the framework of a +programming language. These operations compose to generate footnotes, +tables of contents, mathematical equations, diagrams, multi-column text, +and other elements of typeset works. Here is a survey of formatter +features; all are under precise user control. + + * text filling, breaking, alignment to the left or right margin; + centering + + * adjustment of inter-word space size to justify text, and of + inter-sentence space size to suit local style conventions + + * automatic and manual determination of hyphenation break points + + * pagination + + * selection of any font available to the output device + + * adjustment of type size and vertical spacing (or "leading") + + * configuration of line length and indentation amounts; columnation + + * drawing of geometric primitives (lines, arcs, polygons, circles, + ...) + + * setup of stroke and fill colors (where supported by the output + device) + + * embedding of hyperlinks, images, document metadata, and other + inclusions (where supported by the output device) + + +File: groff.info, Node: Macro Package Intro, Next: Preprocessor Intro, Prev: groff Capabilities, Up: Introduction + +1.4 Macro Packages +================== + +Elemental typesetting functions can be be challenging to use directly +with complex documents. A "macro" facility specifies how certain +routine operations, such as starting paragraphs, or printing headers and +footers, should be performed in terms of those low-level instructions. +Macros can be specific to one document or collected together into a +"macro package" for use by many. Several macro packages available; the +most widely used are provided with 'groff'. They are 'man', 'mdoc', +'me', 'mm', 'mom', and 'ms'. + + +File: groff.info, Node: Preprocessor Intro, Next: Output Device Intro, Prev: Macro Package Intro, Up: Introduction + +1.5 Preprocessors +================= + +An alternative approach to complexity management, particularly when +constructing tables, setting mathematics, or drawing diagrams, lies in +preprocessing. A "preprocessor" employs a domian-specific language to +ease the generation of tables, equations, and so forth in terms that are +convenient for human entry. Each preprocessor reads a document and +translates the parts of it that apply to it into GNU 'troff' input. +Command-line options to 'groff' tell it which preprocessors to use. + + 'groff' provides preprocessors for laying out tables ('gtbl'), +typesetting equations ('geqn'), drawing diagrams ('gpic' and 'ggrn'), +inserting bibliographic references ('grefer'), and drawing chemical +structures ('gchem'). An associated program that is useful when dealing +with preprocessors is 'gsoelim'.(1) (*note Preprocessor +Intro-Footnote-1::) + + 'groff' also supports 'grap', a preprocessor for drawing graphs. A +free implementation of it can be obtained separately. + + Unique to 'groff' is the 'preconv' preprocessor that enables 'groff' +to handle documents in a variety of input encodings. + + Other preprocessors exist, but no free implementations are known. An +example is 'ideal', which draws diagrams using a mathematical constraint +language. + + +File: groff.info, Node: Preprocessor Intro-Footnotes, Up: Preprocessor Intro + + (1) The 'g' prefix is not used on all systems; see *note Invoking +groff::. + + +File: groff.info, Node: Output Device Intro, Next: Installation, Prev: Preprocessor Intro, Up: Introduction + +1.6 Output Devices +================== + +GNU 'troff''s output is in a device-independent page description +language, which is then read by an "output driver" that translates this +language into a file format or byte stream that a piece of (possibly +emulated) hardware understands. 'groff' features output drivers for +PostScript devices, terminal emulators (and other simple typewriter-like +machines), X11 (for previewing), TeX DVI, HP LaserJet 4/PCL5 and Canon +LBP printers (which use CaPSL), HTML, XHTML, and PDF. + + +File: groff.info, Node: Installation, Next: Conventions Used in This Manual, Prev: Output Device Intro, Up: Introduction + +1.7 Installation +================ + +Locate installation instructions in the files 'INSTALL', +'INSTALL.extra', and 'INSTALL.REPO' in the 'groff' source distribution. +Being a GNU project, 'groff' supports the familiar './configure && make' +command sequence. + + +File: groff.info, Node: Conventions Used in This Manual, Next: Credits, Prev: Installation, Up: Introduction + +1.8 Conventions Used in This Manual +=================================== + +We apply the term "groff" to the language documented here, the GNU +implementation of the overall system, the project that develops that +system, and the command of that name. In the first sense, 'groff' is an +extended dialect of the 'roff' language, for which many similar +implementations exist. + + The 'roff' language features several major categories for which many +items are predefined. Presentations of these items feature the form in +which the item is most commonly used on the left, and, aligned to the +right margin, the name of the category in brackets. + + -- Register: \n[example] + The register 'example' is one that that 'groff' _doesn't_ + predefine. You can create it yourself, though; see *note Setting + Registers::. + + To make this document useful as a reference and not merely amiable +bedtime reading, we tend to present these syntax items in exhaustive +detail when they arise. References to topics discussed later in the +text are frequent; skip material you don't understand yet. + + We use Texinfo's "result" (=>) and error-> notations to present +output written to the standard output and standard error streams, +respectively. Diagnostic messages from the GNU 'troff' formatter and +other programs are examples of the latter, but the formatter can also be +directed to write user-specified messages to the standard error stream. +The notation then serves to identify the output stream and does not +necessarily mean that an error has occurred.(1) (*note Conventions Used +in This Manual-Footnote-1::) + + $ echo "Twelve o'clock and" | groff -Tascii | sed '/^$/d' + => Twelve o'clock and + $ echo '.tm all is well.' | groff > /dev/null + error-> all is well. + + Sometimes we use => somewhat abstractly to represent formatted text +that you will need to use a PostScript or PDF viewer program (or a +printer) to observe. While arguably an abuse of notation, we think this +preferable to requiring the reader to understand the syntax of these +page description languages. + + We also present diagnostic messages in an abbreviated form, often +omitting the name of the program issuing them, the input file name, and +line number or other positional information when such data do not serve +to illuminate the topic under discussion. + + Most examples are of 'roff' language input that would be placed in a +text file. Occasionally, we start an example with a '$' character to +indicate a shell prompt, as seen above. + + You are encouraged to try the examples yourself, and to alter them to +better learn 'groff''s behavior. Our examples frequently need to direct +the formatter to set a line length (with '.ll') that will fit within the +page margins of this manual. We mention this so that you know why it is +there before we discuss the 'll' request formally.(2) (*note +Conventions Used in This Manual-Footnote-2::) + + +File: groff.info, Node: Conventions Used in This Manual-Footnotes, Up: Conventions Used in This Manual + + (1) Unix and related operating systems distinguish standard output +and standard error streams _because_ of 'troff': +. + + (2) *Note Line Layout::. + + +File: groff.info, Node: Credits, Prev: Conventions Used in This Manual, Up: Introduction + +1.9 Credits +=========== + +We adapted portions of this manual from existing documents. James +Clark's man pages were an essential resource; we have updated them in +parallel with the development of this manual. We based the tutorial for +macro users on Eric Allman's introduction to his 'me' macro package +(which we also provide, little altered from 4.4BSD). Larry Kollar +contributed much of the material on the 'ms' macro package. + + +File: groff.info, Node: Invoking groff, Next: Tutorial for Macro Users, Prev: Introduction, Up: Top + +2 Invoking 'groff' +****************** + +This chapter focuses on how to invoke the 'groff' front end. This front +end takes care of the details of constructing the pipeline among the +preprocessors, 'gtroff' and the postprocessor. + + It has become a tradition that GNU programs get the prefix 'g' to +distinguish them from their original counterparts provided by the host +(*note Environment::). Thus, for example, 'geqn' is GNU 'eqn'. On +operating systems like GNU/Linux or the Hurd, which don't contain +proprietary versions of 'troff', and on MS-DOS/MS-Windows, where 'troff' +and associated programs are not available at all, this prefix is omitted +since GNU 'troff' is the only incarnation of 'troff' used. Exception: +'groff' is never replaced by 'roff'. + + In this document, we consequently say 'gtroff' when talking about the +GNU 'troff' program. All other implementations of 'troff' are called +AT&T 'troff', which is the common origin of almost all 'troff' +implementations(1) (*note Invoking groff-Footnote-1::) (with more or +less compatible changes). Similarly, we say 'gpic', 'geqn', and so on. + +* Menu: + +* Groff Options:: +* Environment:: +* Macro Directories:: +* Font Directories:: +* Paper Format:: +* Invocation Examples:: + + +File: groff.info, Node: Invoking groff-Footnotes, Up: Invoking groff + + (1) Besides 'groff', 'neatroff' is an exception. + + +File: groff.info, Node: Groff Options, Next: Environment, Prev: Invoking groff, Up: Invoking groff + +2.1 Options +=========== + +'groff' normally runs the 'gtroff' program and a postprocessor +appropriate for the selected device. The default device is 'ps' (but it +can be changed when 'groff' is configured and built). It can optionally +preprocess with any of 'gpic', 'geqn', 'gtbl', 'ggrn', 'grap', 'gchem', +'grefer', 'gsoelim', or 'preconv'. + + This section documents only options to the 'groff' front end. Many +of the arguments to 'groff' are passed on to 'gtroff'; therefore, those +are also included. Arguments to preprocessors and output drivers can be +found in the man pages 'gpic(1)', 'geqn(1)', 'gtbl(1)', 'ggrn(1)', +'grefer(1)', 'gchem(1)', 'gsoelim(1)', 'preconv(1)', 'grotty(1)', +'grops(1)', 'gropdf(1)', 'grohtml(1)', 'grodvi(1)', 'grolj4(1)', +'grolbp(1)', and 'gxditview(1)'. + + The command-line format for 'groff' is: + + groff [ -abceghijklpstvzCEGNRSUVXZ ] [ -dCS ] [ -DARG ] + [ -fFAM ] [ -FDIR ] [ -IDIR ] [ -KARG ] + [ -LARG ] [ -mNAME ] [ -MDIR ] [ -nNUM ] + [ -oLIST ] [ -PARG ] [ -rCN ] [ -TDEV ] + [ -wNAME ] [ -WNAME ] [ FILES... ] + + The command-line format for 'gtroff' is as follows. + + gtroff [ -abcivzCERU ] [ -dCS ] [ -fFAM ] [ -FDIR ] + [ -mNAME ] [ -MDIR ] [ -nNUM ] [ -oLIST ] + [ -rCN ] [ -TNAME ] [ -wNAME ] [ -WNAME ] + [ FILES... ] + +Obviously, many of the options to 'groff' are actually passed on to +'gtroff'. + + Options without an argument can be grouped behind a single '-'. A +filename of '-' denotes the standard input. Whitespace is permitted +between an option and its argument. + + The 'grog' command can be used to guess the correct 'groff' command +to format a file. See its man page 'grog(1)'; type 'man grog' at the +command line to view it. + + 'groff''s command-line options are as follows. + +'-a' + Generate a plain text approximation of the typeset output. The + read-only register '.A' is set to 1. *Note Built-in Registers::. + This option produces a sort of abstract preview of the formatted + output. + + * Page breaks are marked by a phrase in angle brackets; for + example, ''. + + * Lines are broken where they would be in the formatted output. + + * A horizontal motion of any size is represented as one space. + Adjacent horizontal motions are not combined. Inter-sentence + space nodes (those arising from the second argument to the + 'ss' request) are not represented. + + * Vertical motions are not represented. + + * Special characters are rendered in angle brackets; for + example, the default soft hyphen character appears as ''. + + The above description should not be considered a specification; the + details of '-a' output are subject to change. + +'-b' + Write a backtrace reporting the state of 'gtroff''s input parser to + the standard error stream with each diagnostic message. The line + numbers given in the backtrace might not always be correct, because + 'gtroff''s idea of line numbers can be confused by requests that + append to macros. + +'-c' + Start with color output disabled. + +'-C' + Enable AT&T 'troff' compatibility mode; implies '-c'. *Note + Implementation Differences::, for the list of incompatibilities + between 'groff' and AT&T 'troff'. + +'-dCTEXT' +'-dSTRING=TEXT' + Define 'roff' string C or STRING as T or TEXT. C must be one + character; STRING can be of arbitrary length. Such string + assignments happen before any macro file is loaded, including the + startup file. Due to 'getopt_long' limitations, C cannot be, and + STRING cannot contain, an equals sign, even though that is a valid + character in a 'roff' identifier. + +'-DENC' + Set fallback input encoding used by 'preconv' to ENC; implies '-k'. + +'-e' + Run 'geqn' preprocessor. + +'-E' + Inhibit 'gtroff' error messages. This option does _not_ suppress + messages sent to the standard error stream by documents or macro + packages using 'tm' or related requests. + +'-fFAM' + Use FAM as the default font family. *Note Font Families::. + +'-FDIR' + Search in directory 'DIR' for the selected output device's + directory of device and font description files. See the + description of 'GROFF_FONT_PATH' in *note Environment:: below for + the default search locations and ordering. + +'-g' + Run 'ggrn' preprocessor. + +'-G' + Run 'grap' preprocessor; implies '-p'. + +'-h' + Display a usage message and exit. + +'-i' + Read the standard input after all the named input files have been + processed. + +'-IDIR' + Search the directory DIR for files named in several contexts; + implies '-g' and '-s'. + + * 'gsoelim' replaces 'so' requests with the contents of their + file name arguments. + + * 'gtroff' searches for files named as operands in its command + line and as arguments to 'psbb', 'so', and 'soquiet' requests. + + * Output drivers may search for files; for instance, 'grops' + looks for files named in '\X'ps: import ...'', '\X'ps: file + ...'', and '\X'pdf: pdfpic ...'' device control escape + sequences. + + This option may be specified more than once; the directories are + searched in the order specified. If you want to search the current + directory before others, add '-I .' at the desired place. The + current working directory is otherwise searched last. '-I' works + similarly to, and is named for, the "include" option of Unix C + compilers. + + '-I' options are passed to 'gsoelim', 'gtroff', and output drivers; + with the flag letter changed to '-M', they are also passed to + 'ggrn'. + +'-j' + Run 'gchem' preprocessor. Implies '-p'. + +'-k' + Run 'preconv' preprocessor. Refer to its man page for its behavior + if neither of 'groff''s '-K' or '-D' options is also specified. + +'-KENC' + Set input encoding used by 'preconv' to ENC; implies '-k'. + +'-l' + Send the output to a spooler for printing. The 'print' directive + in the device description file specifies the default command to be + used; see *note Device and Font Description Files::. See options + '-L' and '-X'. + +'-LARG' + Pass ARG to the print spooler program. If multiple ARGs are + required, pass each with a separate '-L' option. 'groff' does not + prefix an option dash to ARG before passing it to the spooler + program. + +'-mNAME' + Process the file 'NAME.tmac' prior to any input files. If not + found, 'tmac.NAME' is attempted. NAME (in both arrangements) is + presumed to be a macro file; see the description of + 'GROFF_TMAC_PATH' in *note Environment:: below for the default + search locations and ordering. This option and its argument are + also passed to 'geqn', 'grap', and 'ggrn'. + +'-MDIR' + Search directory 'DIR' for macro files; see the description of + 'GROFF_TMAC_PATH' in *note Environment:: below for the default + search locations and ordering. This option and its argument are + also passed to 'geqn', 'grap', and 'ggrn'. + +'-nNUM' + Number the first page NUM. + +'-N' + Prohibit newlines between 'eqn' delimiters: pass '-N' to 'geqn'. + +'-oLIST' + Output only pages in LIST, which is a comma-separated list of page + ranges; 'N' means page N, 'M-N' means every page between M and N, + '-N' means every page up to N, 'N-' means every page from N on. + 'gtroff' stops processing and exits after formatting the last page + enumerated in LIST. + +'-p' + Run 'gpic' preprocessor. + +'-PARG' + Pass ARG to the postprocessor. If multiple ARGs are required, pass + each with a separate '-P' option. 'groff' does not prefix an + option dash to ARG before passing it to the postprocessor. + +'-rCNUMERIC-EXPRESSION' +'-rREGISTER=EXPR' + Set 'roff' register C or REGISTER to the value NUMERIC-EXPRESSION + (*note Numeric Expressions::). C must be one character; REGISTER + can be of arbitrary length. Such register assignments happen + before any macro file is loaded, including the startup file. Due + to 'getopt_long' limitations, C cannot be, and REGISTER cannot + contain, an equals sign, even though that is a valid character in a + 'roff' identifier. + +'-R' + Run 'grefer' preprocessor. No mechanism is provided for passing + arguments to 'grefer' because most 'grefer' options have equivalent + language elements that can be specified within the document. + + 'gtroff' also accepts a '-R' option, which is not accessible via + 'groff'. This option prevents the loading of the 'troffrc' and + 'troffrc-end' files. + +'-s' + Run 'gsoelim' preprocessor. + +'-S' + Operate in "safer" mode; see '-U' below for its opposite. For + security reasons, safer mode is enabled by default. + +'-t' + Run 'gtbl' preprocessor. + +'-TDEV' + Direct 'gtroff' to format the input for the output device DEV. + 'groff' then calls an output driver to convert 'gtroff''s output to + a form appropriate for DEV. The following output devices are + available. + + 'ps' + For PostScript printers and previewers. + + 'pdf' + For PDF viewers or printers. + + 'dvi' + For TeX DVI format. + + 'X75' + For a 75dpi X11 previewer. + + 'X75-12' + For a 75dpi X11 previewer with a 12-point base font in the + document. + + 'X100' + For a 100dpi X11 previewer. + + 'X100-12' + For a 100dpi X11 previewer with a 12-point base font in the + document. + + 'ascii' + For typewriter-like devices using the (7-bit) ASCII (ISO 646) + character set. + + 'latin1' + For typewriter-like devices that support the Latin-1 + (ISO 8859-1) character set. + + 'utf8' + For typewriter-like devices that use the Unicode (ISO 10646) + character set with UTF-8 encoding. + + 'cp1047' + For typewriter-like devices that use the EBCDIC encoding IBM + code page 1047. + + 'lj4' + For HP LaserJet4-compatible (or other PCL5-compatible) + printers. + + 'lbp' + For Canon CaPSL printers (LBP-4 and LBP-8 series laser + printers). + + 'html' + 'xhtml' + To produce HTML and XHTML output, respectively. This driver + consists of two parts, a preprocessor ('pre-grohtml') and a + postprocessor ('post-grohtml'). + + The predefined GNU 'troff' string '.T' contains the name of the + output device; the read-only register '.T' is set to 1 if this + option is used (which is always true if 'groff' is used to call GNU + 'troff'). *Note Built-in Registers::. + + The postprocessor to be used for a device is specified by the + 'postpro' command in the device description file. (*Note Device + and Font Description Files::.) This can be overridden with the + '-X' option. + +'-U' + Operate in "unsafe mode", which enables the 'open', 'opena', 'pi', + 'pso', and 'sy' requests. These requests are disabled by default + because they allow an untrusted input document to write to + arbitrary file names and run arbitrary commands. This option also + adds the current directory to the macro package search path; see + the '-m' option above. '-U' is passed to 'gpic' and 'gtroff'. + +'-v' + Write version information for 'groff' and all programs run by it to + the standard output stream; that is, the given command line is + processed in the usual way, passing '-v' to the formatter and any + pre- or postprocessors invoked. + +'-V' + Output the pipeline that would be run by 'groff' (as a wrapper + program) to the standard output stream, but do not execute it. If + given more than once, the pipeline is both written to the standard + error stream and run. + +'-wCATEGORY' + Enable warnings in CATEGORY. Categories are listed in *note + Warnings::. + +'-WCATEGORY' + Inhibit warnings in CATEGORY. Categories are listed in *note + Warnings::. + +'-X' + Use 'gxditview' instead of the usual postprocessor to (pre)view a + document on an X11 display. Combining this option with '-Tps' uses + the font metrics of the PostScript device, whereas the '-TX75' and + '-TX100' options use the metrics of X11 fonts. + +'-z' + Suppress formatted output from 'gtroff'. + +'-Z' + Disable postprocessing. 'gtroff' output will appear on the + standard output stream (unless suppressed with '-z'; see *note + gtroff Output:: for a description of this format. + + +File: groff.info, Node: Environment, Next: Macro Directories, Prev: Groff Options, Up: Invoking groff + +2.2 Environment +=============== + +There are also several environment variables (of the operating system, +not within 'gtroff') that can modify the behavior of 'groff'. + +'GROFF_BIN_PATH' + This search path, followed by 'PATH', is used for commands executed + by 'groff'. + +'GROFF_COMMAND_PREFIX' + If this is set to X, then 'groff' runs 'Xtroff' instead of + 'gtroff'. This also applies to 'tbl', 'pic', 'eqn', 'grn', 'chem', + 'refer', and 'soelim'. It does not apply to 'grops', 'grodvi', + 'grotty', 'pre-grohtml', 'post-grohtml', 'preconv', 'grolj4', + 'gropdf', and 'gxditview'. + + The default command prefix is determined during the installation + process. If a non-GNU 'troff' system is found, prefix 'g' is used, + none otherwise. + +'GROFF_ENCODING' + The value of this variable is passed to the 'preconv' + preprocessor's '-e' option to select the character encoding of + input files. This variable's existence implies the 'groff' option + '-k'. If set but empty, 'groff' calls 'preconv' without an '-e' + option. 'groff''s '-K' option overrides 'GROFF_ENCODING'. See the + 'preconv(7)' man page; type 'man preconv' at the command line to + view it. + +'GROFF_FONT_PATH' + A list of directories in which to seek the selected output device's + directory of device and font description files. GNU 'troff' will + search directories given as arguments to any specified '-F' options + before these, and a built-in list of directories after them. *Note + Font Directories:: and the 'troff(1)' or 'gtroff(1)' man pages. + +'GROFF_TMAC_PATH' + A list of directories in which to seek macro files. GNU 'troff' + will search directories given as arguments to any specified '-M' + options before these, and a built-in list of directories after + them. *Note Macro Directories:: and the 'troff(1)' or 'gtroff(1)' + man pages. + +'GROFF_TMPDIR' + The directory in which 'groff' creates temporary files. If this is + not set and 'TMPDIR' is set, temporary files are created in that + directory. Otherwise temporary files are created in a + system-dependent default directory (on Unix and GNU/Linux systems, + this is usually '/tmp'). 'grops', 'grefer', 'pre-grohtml', and + 'post-grohtml' can create temporary files in this directory. + +'GROFF_TYPESETTER' + Sets the default output device. If empty or not set, a build-time + default (often 'ps') is used. The '-TDEV' option overrides + 'GROFF_TYPESETTER'. + +'SOURCE_DATE_EPOCH' + A timestamp (expressed as seconds since the Unix epoch) to use as + the output creation timestamp in place of the current time. The + time is converted to human-readable form using 'localtime(3)' when + the formatter starts up and stored in registers usable by documents + and macro packages (*note Built-in Registers::). + +'TZ' + The time zone to use when converting the current time (or value of + 'SOURCE_DATE_EPOCH') to human-readable form; see 'tzset(3)'. + + MS-DOS and MS-Windows ports of 'groff' use semicolons, rather than +colons, to separate the directories in the lists described above. + + +File: groff.info, Node: Macro Directories, Next: Font Directories, Prev: Environment, Up: Invoking groff + +2.3 Macro Directories +===================== + +A macro file must have a name in the form 'NAME.tmac' or 'tmac.NAME' and +be placed in a "tmac directory" to be found by the '-mNAME' command-line +option.(1) (*note Macro Directories-Footnote-1::) Together, these +directories constitute the "tmac path". Each directory is searched in +the following order until the desired macro file is found or the list is +exhausted. + + * Directories specified with GNU 'troff''s or 'groff''s '-M' + command-line option. + + * Directories listed in the 'GROFF_TMAC_PATH' environment variable. + + * The current working directory (only if in unsafe mode using the + '-U' command-line option). + + * The user's home directory, 'HOME'. + + * A platform-dependent directory, a site-local (platform-independent) + directory, and the main tmac directory. The locations + corresponding to your installation are listed in section + "Environment" of 'gtroff(1)'. If not otherwise configured, they + are as follows. + + /usr/local/lib/groff/site-tmac + /usr/local/share/groff/site-tmac + /usr/local/share/groff/1.23.0/tmac + + The foregoing assumes that the version of 'groff' is 1.23.0, and + that the installation prefix was '/usr/local'. It is possible to + fine-tune these locations during the source configuration process. + + +File: groff.info, Node: Macro Directories-Footnotes, Up: Macro Directories + + (1) The 'mso' request does not have these limitations. *Note I/O::. + + +File: groff.info, Node: Font Directories, Next: Paper Format, Prev: Macro Directories, Up: Invoking groff + +2.4 Font Directories +==================== + +'groff' enforces few restrictions on how font description files are +named. For its family/style mechanism to work (*note Font Families::), +the names of fonts within a family should start with the family name, +followed by the style. For example, the Times family uses 'T' for the +family name and 'R', 'B', 'I', and 'BI' to indicate the styles 'roman', +'bold', 'italic', and 'bold italic', respectively. Thus the final font +names are 'TR', 'TB', 'TI', and 'TBI'. + + Font description files are kept in "font directories", which together +constitute the "font path". The search procedure always appends the +directory 'dev'NAME, where NAME is the name of the output device. +Assuming TeX DVI output, and '/foo/bar' as a font directory, the font +description files for 'grodvi' must be in '/foo/bar/devdvi'. Each +directory in the font path is searched in the following order until the +desired font description file is found or the list is exhausted. + + * Directories specified with GNU 'troff''s or 'groff''s '-f' + command-line option. All output drivers (and some preprocessors) + support this option as well, because they require information about + the glyphs to be rendered in the document. + + * Directories listed in the 'GROFF_FONT_PATH' environment variable. + + * A site-local directory and the main font description directory. + The locations corresponding to your installation are listed in + section "Environment" of 'gtroff(1)'. If not otherwise configured, + they are as follows. + + /usr/local/share/groff/site-font + /usr/local/share/groff/1.23.0/font + + The foregoing assumes that the version of 'groff' is 1.23.0, and + that the installation prefix was '/usr/local'. It is possible to + fine-tune these locations during the source configuration process. + + +File: groff.info, Node: Paper Format, Next: Invocation Examples, Prev: Font Directories, Up: Invoking groff + +2.5 Paper Format +================ + +In 'groff', the page dimensions for the formatter GNU 'troff' and for +output devices are handled separately. *Note Page Layout::, for +vertical manipulation of the page size, and *Note Line Layout::, for +horizontal changes. The 'papersize' macro package, normally loaded by +'troffrc' at startup, provides an interface for configuring page +dimensions by convenient names, like 'letter' or 'a4'; see +'groff_tmac(5)'. The default used by the formatter depends on its build +configuration, but is usually one of the foregoing, as geographically +appropriate. + + It is up to each macro package to respect the page dimensions +configured in this way. + + For each output device, the size of the output medium can be set in +its 'DESC' file. Most output drivers also recognize a command-line +option '-p' to override the default dimensions and an option '-l' to use +landscape orientation. *Note DESC File Format::, for a description of +the 'papersize' keyword, which takes an argument of the same form as +'-p'. The output driver's man page, such as 'grops(1)', may also be +helpful. + + 'groff' uses the command-line option '-P' to pass options to +postprocessors; for example, use the following for PostScript output on +A4 paper in landscape orientation. + + groff -Tps -dpaper=a4l -P-pa4 -P-l -ms foo.ms > foo.ps + + +File: groff.info, Node: Invocation Examples, Prev: Paper Format, Up: Invoking groff + +2.6 Invocation Examples +======================= + +'roff' systems are best known for formatting man pages. Once a 'man' +librarian program has located a man page, it may execute a 'groff' +command much like the following. + + groff -t -man -Tutf8 /usr/share/man/man1/groff.1 + + The librarian will also pipe the output through a pager, which might +not interpret the SGR terminal escape sequences 'groff' emits for +boldface, underlining, or italics; see the 'grotty(1)' man page for a +discussion. + + To process a 'roff' input file using the preprocessors 'gtbl' and +'gpic' and the 'me' macro package in the way to which AT&T 'troff' users +were accustomed, one would type (or script) a pipeline. + + gpic foo.me | gtbl | gtroff -me -Tutf8 | grotty + + Using 'groff', this pipe can be shortened to an equivalent command. + + groff -p -t -me -T utf8 foo.me + + An even easier way to do this is to use 'grog' to guess the +preprocessor and macro options and execute the result by using the +command substitution feature of the shell. + + $(grog -Tutf8 foo.me) + + Each command-line option to a postprocessor must be specified with +any required leading dashes '-' because 'groff' passes the arguments +as-is to the postprocessor; this permits arbitrary arguments to be +transmitted. For example, to pass a title to the 'gxditview' +postprocessor, the shell commands + + groff -X -P -title -P 'trial run' mydoc.t + +and + + groff -X -Z mydoc.t | gxditview -title 'trial run' - + +are equivalent. + + +File: groff.info, Node: Tutorial for Macro Users, Next: Major Macro Packages, Prev: Invoking groff, Up: Top + +3 Tutorial for Macro Users +************************** + +Most users of the 'roff' language employ a macro package to format their +documents. Successful macro packages ease the composition process; +their users need not have mastered the full formatting language, nor +understand features like diversions, traps, and environments. This +chapter aims to familiarize you with basic concepts and mechanisms +common to many macro packages (like "displays"). If you prefer a +meticulous and comprehensive presentation, try *note GNU troff +Reference:: instead. + +* Menu: + +* Basics:: +* Common Features:: + + +File: groff.info, Node: Basics, Next: Common Features, Prev: Tutorial for Macro Users, Up: Tutorial for Macro Users + +3.1 Basics +========== + +Let us first survey some basic concepts necessary to use a macro package +fruitfully.(1) (*note Basics-Footnote-1::) References are made +throughout to more detailed information. + + GNU 'troff' reads an input file prepared by the user and outputs a +formatted document suitable for publication or framing. The input +consists of text, or words to be printed, and embedded commands +(requests and escape sequences), which tell GNU 'troff' how to format +the output. *Note Formatter Instructions::. + + The word argument is used in this chapter to mean a word or number +that appears on the same line as a request, and which modifies the +meaning of that request. For example, the request + + .sp + +spaces one line, but + + .sp 4 + +spaces four lines. The number 4 is an argument to the 'sp' request, +which says to space four lines instead of one. Arguments are separated +from the request and from each other by spaces (_not_ tabs). *Note +Invoking Requests::. + + The primary function of GNU 'troff' is to collect words from input +lines, fill output lines with those words, adjust the line to the +right-hand margin by widening spaces, and output the result. For +example, the input: + + Now is the time + for all good men + to come to the aid + of their party. + Four score and seven + years ago, etc. + +is read, packed onto output lines, and justified to produce: + + => Now is the time for all good men to come to the aid of + => their party. Four score and seven years ago, etc. + + Sometimes a new output line should be started even though the current +line is not yet full--for example, at the end of a paragraph. To do +this it is possible to force a break, starting a new output line. Some +requests cause a break automatically, as do (normally) blank input lines +and input lines beginning with a space or tab. + + Not all input lines are text lines--words to be formatted. Some are +control lines that tell a macro package (or GNU 'troff' directly) how to +format the text. Control lines start with a dot ('.') or an apostrophe +(''') as the first character, and can be followed by a macro call. + + The formatter also does more complex things, such as automatically +numbering pages, skipping over page boundaries, putting footnotes in the +correct place, and so forth. + + Here are a few hints for preparing text for input to GNU 'troff'. + + * First, keep the input lines short. Short input lines are easier to + edit, and GNU 'troff' packs words onto longer lines anyhow. + + * In keeping with this, it is helpful to begin a new line after every + comma or phrase, since common corrections are to add or delete + sentences or phrases. + + * End each sentence with two spaces--or better, start each sentence + on a new line. GNU 'troff' recognizes characters that usually end + a sentence, and inserts inter-sentence space accordingly. + + * Do not hyphenate words at the end of lines--GNU 'troff' is smart + enough to hyphenate words as needed, but is not smart enough to + take hyphens out and join a word back together. Also, words such + as "mother-in-law" should not be broken over a line, since then a + space can occur where not wanted, such as "mother- in-law". + + We offer further advice in *note Input Conventions::. + + GNU 'troff' permits alteration of the distance between lines of text. +This is termed vertical spacing and is expressed in the same units as +the type size--the point. The default is 10-point type on 12-point +spacing. To get double-spaced text you would set the vertical spacing +to 24 points. Some, but not all, macro packages expose a macro or +register to configure the vertical spacing. + + A number of requests allow you to change the way the output is +arranged on the page, sometimes called the layout of the output page. +Most macro packages don't supply macros for performing these (at least +not without performing other actions besides), as they are such basic +operations. The macro packages for writing man pages, 'man' and 'mdoc', +don't encourage explicit use of these requests at all. + + The request '.sp N' leaves N lines of blank space. N can be omitted +(skipping a single line) or can be of the form Ni (for N inches) or Nc +(for N centimeters). For example, the input: + + .sp 1.5i + My thoughts on the subject + .sp + +leaves one and a half inches of space, followed by the line "My thoughts +on the subject", followed by a single blank line (more measurement units +are available; see *note Measurements::). + + If you seek precision in spacing, be advised when using a macro +package that it might not honor 'sp' requests as you expect; it can use +a formatter feature called no-space mode to prevent excess space from +accumulating. Macro packages typically offer registers to control +spacing between paragraphs, before section headings, and around displays +(discussed below); use these facilities preferentially. *Note +Manipulating Spacing::. + + Text lines can be centered by using the 'ce' request. The line after +'ce' is centered (horizontally) on the page. To center more than one +line, use '.ce N' (where N is the number of lines to center), followed +by the N lines. To center many lines without counting them, type: + + .ce 1000 + lines to center + .ce 0 + +The '.ce 0' request tells GNU 'troff' to center zero more lines, in +other words, stop centering. + + GNU 'troff' also offers the 'rj' request for right-aligning text. It +works analogously to 'ce' and is convenient for setting epigraphs. + + The 'bp' request starts a new page; this necessarily implies an +ordinary (line) break. + + All of these requests cause a break; that is, they always start a new +line. To start a new line without performing any other action, use +'br'. If you invoke them with the apostrophe ''', the no-break control +character, the (initial) break they normally perform is suppressed. +''br' does nothing. + + +File: groff.info, Node: Basics-Footnotes, Up: Basics + + (1) The remainder of this chapter is based on 'Writing Papers with +nroff using -me' by Eric P. Allman, which is distributed with 'groff' as +'meintro.me'. + + +File: groff.info, Node: Common Features, Prev: Basics, Up: Tutorial for Macro Users + +3.2 Common Features +=================== + +GNU 'troff' provides low-level operations for formatting a document. +Many routine operations are undertaken in nearly all documents that +require a series of such primitive operations to be performed. These +common tasks are grouped into macros, which are then collected into a +macro package. + + Macro packages come in two varieties: "major" or "full-service" ones +that manage page layout, and "minor" or "auxiliary" ones that do not, +instead fulfilling narrow, specific tasks. Find a list in the +'groff_tmac(5)' man page. Type 'man groff_tmac' at the command line to +view it. + + We survey several capabilities of full-service macro package below. +Each package employs its own macros to exercise them. For details, +consult its man page or, for 'ms', see *note ms::. + +* Menu: + +* Paragraphs:: +* Sections and Chapters:: +* Headers and Footers:: +* Page Layout Adjustment:: +* Displays and Keeps:: +* Footnotes and Endnotes:: +* Table of Contents:: +* Indexing:: +* Document Formats:: +* Columnation:: +* Font and Size Changes:: +* Predefined Text:: +* Preprocessor Support:: +* Configuration and Customization:: + + +File: groff.info, Node: Paragraphs, Next: Sections and Chapters, Prev: Common Features, Up: Common Features + +3.2.1 Paragraphs +---------------- + +Paragraphs can be separated and indented in various ways. Some start +with a blank line and have a first-line indentation, like most of the +ones in this manual. Block paragraphs omit the indentation. + + => Some men look at constitutions with sanctimonious + => reverence, and deem them like the ark of the + => covenant, too sacred to be touched. + +We also frequently encounter tagged paragraphs, which begin with a tag +or label at the left margin and indent the remaining text. + + => one This is the first paragraph. Notice how the + => first line of the resulting paragraph lines + => up with the other lines in the paragraph. + +If the tag is too wide for the indentation, the line is broken. + + => longlabel + => The label does not align with the subsequent + => lines, but they align with each other. + +A variation of the tagged paragraph is the itemized or enumerated +paragraph, which might use punctuation or a digit for a tag, +respectively. These are frequently used to construct lists. + + => o This list item starts with a bullet. When + => producing output for a device using the ASCII + => character set, an 'o' is formatted instead. + +Often, use of the same macro without a tag continues such a discussion. + + => -xyz This option is recognized but ignored. + => + => It had a security hole that we don't discuss. + + +File: groff.info, Node: Sections and Chapters, Next: Headers and Footers, Prev: Paragraphs, Up: Common Features + +3.2.2 Sections and Chapters +--------------------------- + +The simplest kind of section heading is unnumbered, set in a bold or +italic style, and occupies a line by itself. Others possess +automatically numbered multi-level headings and/or different typeface +styles or sizes at different levels. More sophisticated macro packages +supply macros for designating chapters and appendices. + + +File: groff.info, Node: Headers and Footers, Next: Page Layout Adjustment, Prev: Sections and Chapters, Up: Common Features + +3.2.3 Headers and Footers +------------------------- + +Headers and footers occupy the top and bottom of each page, +respectively, and contain data like the page number and the article or +chapter title. Their appearance is not affected by the running text. +Some packages allow for different titles on even- and odd-numbered pages +(for printed, bound material). + + Headers and footers are together called titles, and comprise three +parts: left-aligned, centered, and right-aligned. A '%' character +appearing anywhere in a title is automatically replaced by the page +number. *Note Page Layout::. + + +File: groff.info, Node: Page Layout Adjustment, Next: Displays and Keeps, Prev: Headers and Footers, Up: Common Features + +3.2.4 Page Layout +----------------- + +Most macro packages let the user specify the size of the page margins. +The top and bottom margins are typically handled differently than the +left and right margins; the latter two are derived from the page offset, +indentation, and line length. *Note Line Layout::. Commonly, packages +support registers to tune these values. + + +File: groff.info, Node: Displays and Keeps, Next: Footnotes and Endnotes, Prev: Page Layout Adjustment, Up: Common Features + +3.2.5 Displays and Keeps +------------------------ + +Displays are sections of text set off from the surrounding material +(typically paragraphs), often differing in indentation, and/or spacing. +Tables, block quotations, and figures are displayed. Equations and code +examples, when not much shorter than an output line, often are. Lists +may or may not be. Packages for setting man pages support example +displays but not keeps. + + A keep is a group of output lines, often a display, that is formatted +on a single page if possible; it causes a page break to happen early so +as to not interrupt the kept material. + + Floating keeps can move, or "float", relative to the text around them +in the input. They are useful for displays that are captioned and +referred to by name, as with "See figure 3". Depending on the package, +a floating keep appears at the bottom of the current page if it fits, +and at the top of the next otherwise. Alternatively, floating keeps +might be deferred to the end of a section. Using a floating keep can +avoid the large vertical spaces that may precede a tall keep of the +ordinary sort when it won't fit on the page. + + +File: groff.info, Node: Footnotes and Endnotes, Next: Table of Contents, Prev: Displays and Keeps, Up: Common Features + +3.2.6 Footnotes and Endnotes +---------------------------- + +Footnotes and endnotes are forms of delayed formatting. They are +recorded at their points of relevance in the input, but not formatted +there. Instead, a mark cues the reader to check the "foot", or bottom, +of the current page, or in the case of endnotes, an annotation list +later in the document. Macro packages that support these features also +supply a means of automatically numbering either type of annotation. + + +File: groff.info, Node: Table of Contents, Next: Indexing, Prev: Footnotes and Endnotes, Up: Common Features + +3.2.7 Table of Contents +----------------------- + +A package may handle a table of contents by directing section heading +macros to save section heading text and the page number where it occurs +for use in a later entry for a table of contents. It writes the +collected entries at the end of the document, once all are known, upon +request. A row of dots (a leader) bridges the text on the left with its +location on the right. Other collections might work in this manner, +providing lists of figures or tables. + + A table of contents is often found at the end of a GNU 'troff' +document because the formatter processes the document in a single pass. +The 'gropdf' output driver supports a PDF feature that relocates pages +at the time the document is rendered; see the 'gropdf(1)' man page. +Type 'man gropdf' at the command line to view it. + + +File: groff.info, Node: Indexing, Next: Document Formats, Prev: Table of Contents, Up: Common Features + +3.2.8 Indexing +-------------- + +An index is similar to a table of contents, in that entry labels and +locations must be collected, but poses a greater challenge because it +needs to be sorted before it is output. Here, processing the document +in multiple passes is inescapable, and tools like the 'makeindex' +program are necessary. + + +File: groff.info, Node: Document Formats, Next: Columnation, Prev: Indexing, Up: Common Features + +3.2.9 Document Formats +---------------------- + +Some macro packages supply stock configurations of certain documents, +like business letters and memoranda. These often also have provision +for a cover sheet, which may be rigid in its format. With these +features, it is even more important to use the package's macros in +preference to the formatter requests presented earlier, where possible. + + +File: groff.info, Node: Columnation, Next: Font and Size Changes, Prev: Document Formats, Up: Common Features + +3.2.10 Columnation +------------------ + +Macro packages apart from 'man' and 'mdoc' for man page formatting offer +a facility for setting multiple columns on the page. + + +File: groff.info, Node: Font and Size Changes, Next: Predefined Text, Prev: Columnation, Up: Common Features + +3.2.11 Font and Size Changes +---------------------------- + +The formatter's requests and escape sequences for setting the typeface +and size are not always intuitive, so all macro packages provide macros +to make these operations simpler. They also make it more convenient to +change typefaces in the middle of a word and can handle italic +corrections automatically. *Note Italic Corrections::. + + +File: groff.info, Node: Predefined Text, Next: Preprocessor Support, Prev: Font and Size Changes, Up: Common Features + +3.2.12 Predefined Text +---------------------- + +Most macro packages supply predefined strings to set prepared text like +the date, or to perform operations like super- and subscripting. + + +File: groff.info, Node: Preprocessor Support, Next: Configuration and Customization, Prev: Predefined Text, Up: Common Features + +3.2.13 Preprocessor Support +--------------------------- + +All macro packages provide support for various preprocessors and may +extend their functionality by defining macros to set their contents in +displays. Examples include 'TS' and 'TE' for 'gtbl', 'EQ' and 'EN' for +'geqn', and 'PS' and 'PE' for 'gpic'. + + +File: groff.info, Node: Configuration and Customization, Prev: Preprocessor Support, Up: Common Features + +3.2.14 Configuration and Customization +-------------------------------------- + +Packages provide means of customizing many of the details of how the +package behaves. These range from setting the default type size to +changing the appearance of section headers. + + +File: groff.info, Node: Major Macro Packages, Next: GNU troff Reference, Prev: Tutorial for Macro Users, Up: Top + +4 Macro Packages +**************** + +This chapter surveys the "major" macro packages that come with 'groff'. +One, 'ms', is presented in detail. + + Major macro packages are also sometimes described as "full-service" +due to the breadth of features they provide and because more than one +cannot be used by the same document; for example + + groff -m man foo.man -m ms bar.doc + +doesn't work. Option arguments are processed before non-option +arguments; the above (failing) sample is thus reordered to + + groff -m man -m ms foo.man bar.doc + + Many auxiliary, or "minor", macro packages are also available. They +may in general be used with any full-service macro package and handle a +variety of tasks from character encoding selection, to language +localization, to inlining of raster images. See the 'groff_tmac(5)' man +page for a list. Type 'man groff_tmac' at the command line to view it. + +* Menu: + +* man:: +* mdoc:: +* me:: +* mm:: +* mom:: +* ms:: + + +File: groff.info, Node: man, Next: mdoc, Prev: Major Macro Packages, Up: Major Macro Packages + +4.1 'man' +========= + +The 'man' macro package is the most widely used and probably the most +important ever developed for 'troff'. It is easy to use, and a vast +majority of manual pages ("man pages") are written in it. + + 'groff''s implementation is documented in the 'groff_man(7)' man +page. Type 'man groff_man' at the command line to view it. + +* Menu: + +* Optional man extensions:: + + +File: groff.info, Node: Optional man extensions, Up: man + +4.1.1 Optional 'man' extensions +------------------------------- + +Use the file 'man.local' for local extensions to the 'man' macros or for +style changes. + +Custom headers and footers +.......................... + +In 'groff' versions 1.18.2 and later, you can specify custom headers and +footers by redefining the following macros in 'man.local'. + + -- Macro: .PT + Control the content of the headers. Normally, the header prints + the command name and section number on either side, and the + optional fifth argument to 'TH' in the center. + + -- Macro: .BT + Control the content of the footers. Normally, the footer prints + the page number and the third and fourth arguments to 'TH'. + + Use the 'FT' register to specify the footer position. The default + is -0.5i. + +Ultrix-specific man macros +.......................... + +The 'groff' source distribution includes a file named 'man.ultrix', +containing macros compatible with the Ultrix variant of 'man'. Copy +this file into 'man.local' (or use the 'mso' request to load it) to +enable the following macros. + + -- Macro: .CT key + Print ''. + + -- Macro: .CW + Print subsequent text using a "constant-width" (monospaced) + typeface (Courier roman). + + -- Macro: .Ds + Begin a non-filled display. + + -- Macro: .De + End a non-filled display started with 'Ds'. + + -- Macro: .EX [indent] + Begin a non-filled display using a monospaced typeface (Courier + roman). Use the optional INDENT argument to indent the display. + + -- Macro: .EE + End a non-filled display started with 'EX'. + + -- Macro: .G [text] + Set TEXT in Helvetica. If no text is present on the line where the + macro is called, then the text of the next line appears in + Helvetica. + + -- Macro: .GL [text] + Set TEXT in Helvetica oblique. If no text is present on the line + where the macro is called, then the text of the next line appears + in Helvetica Oblique. + + -- Macro: .HB [text] + Set TEXT in Helvetica bold. If no text is present on the line + where the macro is called, then all text up to the next 'HB' + appears in Helvetica bold. + + -- Macro: .TB [text] + Identical to 'HB'. + + -- Macro: .MS title sect [punct] + Set a man page reference in Ultrix format. The TITLE is in Courier + instead of italic. Optional punctuation follows the section number + without an intervening space. + + -- Macro: .NT [C] [title] + Begin a note. Print the optional title, or the word "Note", + centered on the page. Text following the macro makes up the body + of the note, and is indented on both sides. If the first argument + is 'C', the body of the note is printed centered (the second + argument replaces the word "Note" if specified). + + -- Macro: .NE + End a note begun with 'NT'. + + -- Macro: .PN path [punct] + Set the path name in a monospaced typeface (Courier roman), + followed by optional punctuation. + + -- Macro: .Pn [punct] path [punct] + If called with two arguments, identical to 'PN'. If called with + three arguments, set the second argument in a monospaced typeface + (Courier roman), bracketed by the first and third arguments in the + current font. + + -- Macro: .R + Switch to roman font and turn off any underlining in effect. + + -- Macro: .RN + Print the string ''. + + -- Macro: .VS [4] + Start printing a change bar in the margin if the number '4' is + specified. Otherwise, this macro does nothing. + + -- Macro: .VE + End printing the change bar begun by 'VS'. + +Simple example +.............. + +The following example 'man.local' file alters the 'SH' macro to add some +extra vertical space before printing the heading. Headings are printed +in Helvetica bold. + + .\" Make the heading fonts Helvetica + .ds HF HB + . + .\" Put more space in front of headings. + .rn SH SH-orig + .de SH + . if t .sp (u;\\n[PD]*2) + . SH-orig \\$* + .. + + +File: groff.info, Node: mdoc, Next: me, Prev: man, Up: Major Macro Packages + +4.2 'mdoc' +========== + +'groff''s implementation of the BSD 'doc' package for man pages is +documented in the 'groff_mdoc(7)' man page. Type 'man groff_mdoc' at +the command line to view it. + + +File: groff.info, Node: me, Next: mm, Prev: mdoc, Up: Major Macro Packages + +4.3 'me' +======== + +'groff''s implementation of the BSD 'me' macro package is documented +using itself. A tutorial, 'meintro.me', and reference, 'meref.me', are +available in 'groff''s documentation directory. A 'groff_me(7)' man +page is also available and identifies the installation path for these +documents. Type 'man groff_me' at the command line to view it. + + A French translation of the tutorial is available as 'meintro_fr.me' +and installed parallel to the English version. + + +File: groff.info, Node: mm, Next: mom, Prev: me, Up: Major Macro Packages + +4.4 'mm' +======== + +'groff''s implementation of the AT&T memorandum macro package is +documented in the 'groff_mm(7)' man page. Type 'man groff_mm' at the +command line) to view it. + + A Swedish localization of 'mm' is also available; see +'groff_mmse(7)'. + + +File: groff.info, Node: mom, Next: ms, Prev: mm, Up: Major Macro Packages + +4.5 'mom' +========= + +The main documentation files for the 'mom' macros are in HTML format. +Additional, useful documentation is in PDF format. See the 'groff(1)' +man page, section "Installation Directories", for their location. + + * 'toc.html' Entry point to the full mom manual. + + * 'macrolist.html' Hyperlinked index of macros with brief + descriptions, arranged by category. + + * 'mom-pdf.pdf' PDF features and usage. + + The mom macros are in active development between 'groff' releases. +The most recent version, along with up-to-date documentation, is +available at . + + The 'groff_mom(7)' man page (type 'man groff_mom' at the command +line) contains a partial list of available macros, however their usage +is best understood by consulting the HTML documentation. + + +File: groff.info, Node: ms, Prev: mom, Up: Major Macro Packages + +4.6 'ms' +======== + +The 'ms' ("manuscript") package is suitable for the preparation of +letters, memoranda, reports, and books. These 'groff' macros feature +cover page and table of contents generation, automatically numbered +headings, several paragraph styles, a variety of text styling options, +footnotes, and multi-column page layouts. 'ms' supports the 'tbl', +'eqn', 'pic', and 'refer' preprocessors for inclusion of tables, +mathematical equations, diagrams, and standardized bibliographic +citations. This implementation is mostly compatible with the documented +interface and behavior of AT&T Unix Version 7 'ms'. Many extensions +from 4.2BSD (Berkeley) and Tenth Edition Research Unix have been +recreated. + +* Menu: + +* ms Introduction:: +* ms Document Structure:: +* ms Document Control Settings:: +* ms Document Description Macros:: +* ms Body Text:: +* ms Page Layout:: +* Differences from AT&T ms:: +* ms Legacy Features:: +* ms Naming Conventions:: + + +File: groff.info, Node: ms Introduction, Next: ms Document Structure, Prev: ms, Up: ms + +4.6.1 Introduction +------------------ + +The 'ms' macros are the oldest surviving package for 'roff' systems.(1) +(*note ms Introduction-Footnote-1::) While the 'man' package was +designed for brief reference documents, the 'ms' macros are also +suitable for longer works intended for printing and possible +publication. + +* Menu: + +* ms basic information:: + + +File: groff.info, Node: ms Introduction-Footnotes, Up: ms Introduction + + (1) While manual _pages_ are older, early ones used macros supplanted +by the 'man' package of Seventh Edition Unix (1979). 'ms' shipped with +Sixth Edition (1975) and was documented by Mike Lesk in a Bell Labs +internal memorandum. + + +File: groff.info, Node: ms basic information, Next: ms Document Structure, Prev: ms Introduction, Up: ms Introduction + +4.6.1.1 Basic information +......................... + +'ms' documents are plain text files; prepare them with your preferred +text editor. If you're in a hurry to start, know that 'ms' needs one of +its macros called at the beginning of a document so that it can +initialize. A "macro" is a formatting instruction to 'ms'. Put a macro +call on a line by itself. Use '.PP' if you want your paragraph's first +line to be indented, or '.LP' if you don't. + + After that, start typing normally. It is a good practice to start +each sentence on a new line, or to put two spaces after sentence-ending +punctuation, so that the formatter knows where the sentence boundaries +are. You can separate paragraphs with further paragraphing macros, or +with blank lines, and you can indent with tabs. When you need one of +the features mentioned earlier (*note ms::), return to this part of the +manual. + + Format the document with the 'groff' command. 'nroff' can be useful +for previewing. + + $ editor radical.ms + $ nroff -ww -z -ms radical.ms # check for errors + $ nroff -ms radical.ms | less -R + $ groff -T ps -ms radical.ms > radical.ps + $ see radical.ps + + Our 'radical.ms' document might look like this. + + .LP + Radical novelties are so disturbing that they tend to be + suppressed or ignored, to the extent that even the + possibility of their existence in general is more often + denied than admitted. + + ->That's what Dijkstra said, anyway. + + 'ms' exposes many aspects of document layout to user control via +'groff''s "registers" and "strings", which store numbers and text, +respectively. Measurements in 'groff' are expressed with a suffix +called a "scaling unit". + +'i' + inches + +'c' + centimeters + +'p' + points (1/72 inch) + +'P' + picas (1/6 inch) + +'v' + vees; current vertical spacing + +'m' + ems; width of an "M" in the current font + +'n' + ens; one-half em + + Set registers with the 'nr' request and strings with the 'ds' +request. "Requests" are like macro calls; they go on lines by +themselves and start with the "control character", a dot ('.'). The +difference is that they directly instruct the formatter program, rather +than the macro package. We'll discuss a few as applicable. It is wise +to specify a scaling unit when setting any register that represents a +length, size, or distance. + + .nr PS 10.5p \" Use 10.5-point type. + .ds FAM P \" Use Palatino font family. + +In the foregoing, we see that '\"' begins a comment. This is an example +of an "escape sequence", the other kind of formatting instruction. +Escape sequences can appear anywhere. They begin with the escape +character ('\') and are followed by at least one more character. 'ms' +documents tend to use only a few of 'groff''s many requests and escape +sequences; see *note Request Index:: and *note Escape Sequence Index:: +or the 'groff(7)' man page for complete lists. + +'\"' + Begin comment; ignore remainder of line. + +'\n[REG]' + Interpolate value of register REG. + +'\*[STR]' + Interpolate contents of string STR. + +'\*S' + abbreviation of '\*[S]'; the name S must be only one character + +'\[CHAR]' + Interpolate glyph of special character named CHAR. + +'\&' + dummy character + +'\~' + Insert an unbreakable space that is adjustable like a normal space. + +'\|' + Move horizontally by one-sixth em ("thin space"). + + Prefix any words that start with a dot '.' or neutral apostrophe ''' +with '\&' if they are at the beginning of an input line (or might become +that way in editing) to prevent them from being interpreted as macro +calls or requests. Suffix '.', '?', and '!' with '\&' when needed to +cancel end-of-sentence detection. + + My exposure was \&.5 to \&.6 Sv of neutrons, said Dr.\& + Wallace after the criticality incident. + + +File: groff.info, Node: ms Document Structure, Next: ms Document Control Settings, Prev: ms Introduction, Up: ms + +4.6.2 Document Structure +------------------------ + +The 'ms' macro package expects a certain amount of structure: a +well-formed document contains at least one paragraphing or heading macro +call. Longer documents have a structure as follows. + +*Document type* + Calling the 'RP' macro at the beginning of your document puts the + document description (see below) on a cover page. Otherwise, 'ms' + places the information (if any) on the first page, followed + immediately by the body text. Some document types found in other + 'ms' implementations are specific to AT&T or Berkeley, and are not + supported by 'groff' 'ms'. + +*Format and layout* + By setting registers and strings, you can configure your document's + typeface, margins, spacing, headers and footers, and footnote + arrangement. *Note ms Document Control Settings::. + +*Document description* + A document description consists of any of: a title, one or more + authors' names and affiliated institutions, an abstract, and a date + or other identifier. *Note ms Document Description Macros::. + +*Body text* + The main matter of your document follows its description (if any). + 'ms' supports highly structured text consisting of paragraphs + interspersed with multi-level headings (chapters, sections, + subsections, and so forth) and augmented by lists, footnotes, + tables, diagrams, and similar material. *Note ms Body Text::. + +*Tables of contents* + Macros enable the collection of entries for a table of contents (or + index) as the material they discuss appears in the document. You + then call a macro to emit the table of contents at the end of your + document. The table of contents must necessarily follow the rest + of the text since GNU 'troff' is a single-pass formatter; it thus + cannot determine the page number of a division of the text until it + has been set and output. Since 'ms' was designed for the + production of hard copy, the traditional procedure was to manually + relocate the pages containing the table of contents between the + cover page and the body text. Today, page resequencing is more + often done in the digital domain. An index works similarly, but + because it typically needs to be sorted after collection, its + preparation requires separate processing. + + +File: groff.info, Node: ms Document Control Settings, Next: ms Document Description Macros, Prev: ms Document Structure, Up: ms + +4.6.3 Document Control Settings +------------------------------- + +'ms' exposes many aspects of document layout to user control via 'groff' +requests. To use them, you must understand how to define registers and +strings. + + -- Request: .nr reg value + Set register REG to VALUE. If REG doesn't exist, GNU 'troff' + creates it. + + -- Request: .ds name contents + Set string NAME to CONTENTS. + + A list of document control registers and strings follows. For any +parameter whose default is unsatisfactory, define its register or string +before calling any 'ms' macro other than 'RP'. + +Margin settings +............... + + -- Register: \n[PO] + Defines the page offset (i.e., the left margin). + + Effective: next page. + + Default: Varies by output device and paper format; 1i is used for + typesetters using U.S. letter paper, and zero for terminals. *Note + Paper Format::. + + -- Register: \n[LL] + Defines the line length (i.e., the width of the body text). + + Effective: next paragraph. + + Default: Varies by output device and paper format; 6.5i is used for + typesetters using U.S. letter paper (*note Paper Format::) and 65n + on terminals. + + -- Register: \n[LT] + Defines the title line length (i.e., the header and footer width). + This is usually the same as 'LL', but need not be. + + Effective: next paragraph. + + Default: Varies by output device and paper format; 6.5i is used for + typesetters using U.S. letter paper (*note Paper Format::) and 65n + on terminals. + + -- Register: \n[HM] + Defines the header margin height at the top of the page. + + Effective: next page. + + Default: 1i. + + -- Register: \n[FM] + Defines the footer margin height at the bottom of the page. + + Effective: next page. + + Default: 1i. + +Titles (headers, footers) +......................... + + -- String: \*[LH] + Defines the text displayed in the left header position. + + Effective: next header. + + Default: empty. + + -- String: \*[CH] + Defines the text displayed in the center header position. + + Effective: next header. + + Default: '-\n[%]-'. + + -- String: \*[RH] + Defines the text displayed in the right header position. + + Effective: next header. + + Default: empty. + + -- String: \*[LF] + Defines the text displayed in the left footer position. + + Effective: next footer. + + Default: empty. + + -- String: \*[CF] + Defines the text displayed in the center footer position. + + Effective: next footer. + + Default: empty. + + -- String: \*[RF] + Defines the text displayed in the right footer position. + + Effective: next footer. + + Default: empty. + +Text settings +............. + + -- Register: \n[PS] + Defines the type size of the body text. + + Effective: next paragraph. + + Default: 10p. + + -- Register: \n[VS] + Defines the vertical spacing (type size plus leading). + + Effective: next paragraph. + + Default: 12p. + + -- Register: \n[HY] + Defines the automatic hyphenation mode used with the 'hy' request. + Setting 'HY' to 0 is equivalent to using the 'nh' request. This is + a Tenth Edition Research Unix extension. + + Effective: next paragraph. + + Default: 6. + + -- String: \*[FAM] + Defines the font family used to typeset the document. This is a + GNU extension. + + Effective: next paragraph. + + Default: defined by the output device; often 'T' (*note ms Body + Text::) + +Paragraph settings +.................. + + -- Register: \n[PI] + Defines the indentation amount used by the 'PP', 'IP' (unless + overridden by an optional argument), 'XP', and 'RS' macros. + + Effective: next paragraph. + + Default: 5n. + + -- Register: \n[PD] + Defines the space between paragraphs. + + Effective: next paragraph. + + Default: 0.3v (1v on low-resolution devices). + + -- Register: \n[QI] + Defines the indentation amount used on both sides of a paragraph + set with the 'QP' or between the 'QS' and 'QE' macros. + + Effective: next paragraph. + + Default: 5n. + + -- Register: \n[PORPHANS] + Defines the minimum number of initial lines of any paragraph that + must be kept together to avoid isolated lines at the bottom of a + page. If a new paragraph is started close to the bottom of a page, + and there is insufficient space to accommodate 'PORPHANS' lines + before an automatic page break, then a page break is forced before + the start of the paragraph. This is a GNU extension. + + Effective: next paragraph. + + Default: 1. + +Heading settings +................ + + -- Register: \n[PSINCR] + Defines an increment in type size to be applied to a heading at a + lesser depth than that specified in 'GROWPS'. The value of + 'PSINCR' should be specified in points with the p scaling unit and + may include a fractional component; for example, '.nr PSINCR 1.5p' + sets a type size increment of 1.5p. This is a GNU extension. + + Effective: next heading. + + Default: 1p. + + -- Register: \n[GROWPS] + Defines the heading depth above which the type size increment set + by 'PSINCR' becomes effective. For each heading depth less than + the value of 'GROWPS', the type size is increased by 'PSINCR'. + Setting 'GROWPS' to any value less than 2 disables the incremental + heading size feature. This is a GNU extension. + + Effective: next heading. + + Default: 0. + + -- Register: \n[HORPHANS] + Defines the minimum number of lines of an immediately succeeding + paragraph that should be kept together with any heading introduced + by the 'NH' or 'SH' macros. If a heading is placed close to the + bottom of a page, and there is insufficient space to accommodate + both the heading and at least 'HORPHANS' lines of the following + paragraph, before an automatic page break, then the page break is + forced before the heading. This is a GNU extension. + + Effective: next paragraph. + + Default: 1. + + -- String: \*[SN-STYLE] + Defines the style used to print numbered headings. *Note Headings + in ms::. This is a GNU extension. + + Effective: next heading. + + Default: alias of 'SN-DOT' + +Footnote settings +................. + + -- Register: \n[FI] + Defines the footnote indentation. This is a Berkeley extension. + + Effective: next footnote. + + Default: 2n. + + -- Register: \n[FF] + Defines the format of automatically numbered footnotes, and those + for which the 'FS' request is given a marker argument, at the + bottom of a column or page. This is a Berkeley extension. + '0' + Set an automatic number(1) (*note ms Document Control + Settings-Footnote-1::) as a superscript (on typesetter + devices) or surrounded by square brackets (on terminals). The + footnote paragraph is indented as with 'PP' if there is an + 'FS' argument or an automatic number, and as with 'LP' + otherwise. This is the default. + + '1' + As '0', but set the marker as regular text and follow an + automatic number with a period. + + '2' + As '1', but without indentation (like 'LP'). + + '3' + As '1', but set the footnote paragraph with the marker hanging + (like 'IP'). + + Effective: next footnote. + + Default: 0. + + -- Register: \n[FPS] + Defines the footnote type size. + + Effective: next footnote. + + Default: '\n[PS] - 2p'. + + -- Register: \n[FVS] + Defines the footnote vertical spacing. + + Effective: next footnote. + + Default: '\n[FPS] + 2p'. + + -- Register: \n[FPD] + Defines the footnote paragraph spacing. This is a GNU extension. + + Effective: next footnote. + + Default: '\n[PD] / 2'. + + -- String: \*[FR] + Defines the ratio of the footnote line length to the current line + length. This is a GNU extension. + + Effective: next footnote in single-column arrangements, next page + otherwise. + + Default: '11/12'. + +Display settings +................ + + -- Register: \n[DD] + Sets the display distance--the vertical spacing before and after a + display, a 'tbl' table, an 'eqn' equation, or a 'pic' image. This + is a Berkeley extension. + + Effective: next display boundary. + + Default: 0.5v (1v on low-resolution devices). + + -- Register: \n[DI] + Sets the default amount by which to indent a display started with + 'DS' and 'ID' without arguments, to '.DS I' without an indentation + argument, and to equations set with '.EQ I'. This is a GNU + extension. + + Effective: next indented display. + + Default: 0.5i. + +Other settings +.............. + + -- Register: \n[MINGW] + Defines the default minimum width between columns in a multi-column + document. This is a GNU extension. + + Effective: next page. + + Default: 2n. + + -- Register: \n[TC-MARGIN] + Defines the width of the field in which page numbers are set in a + table of contents entry; the right margin thus moves inboard by + this amount. This is a GNU extension. + + Effective: next 'PX' call. + + Default: '\w'000'' + + +File: groff.info, Node: ms Document Control Settings-Footnotes, Up: ms Document Control Settings + + (1) defined in *note ms Footnotes:: + + +File: groff.info, Node: ms Document Description Macros, Next: ms Body Text, Prev: ms Document Control Settings, Up: ms + +4.6.4 Document Description Macros +--------------------------------- + +Only the simplest document lacks a title.(1) (*note ms Document +Description Macros-Footnote-1::) As its level of sophistication (or +complexity) increases, it tends to acquire a date of revision, +explicitly identified authors, sponsoring institutions for authors, and, +at the rarefied heights, an abstract of its content. Define these data +by calling the macros below in the order shown; 'DA' or 'ND' can be +called to set the document date (or other identifier) at any time before +(a) the abstract, if present, or (b) its information is required in a +header or footer. Use of these macros is optional, except that 'TL' is +mandatory if any of 'RP', 'AU', 'AI', or 'AB' is called, and 'AE' is +mandatory if 'AB' is called. + + -- Macro: .RP [no-repeat-info] [no-renumber] + Use the "report" (AT&T: "released paper") format for your document, + creating a separate cover page. The default arrangement is to + place most of the document description (title, author names and + institutions, and abstract, but not the date) at the top of the + first page. If the optional 'no-repeat-info' argument is given, + 'ms' produces a cover page but does not repeat any of its + information subsequently (but see the 'DA' macro below regarding + the date). Normally, 'RP' sets the page number following the cover + page to 1. Specifying the optional 'no-renumber' argument + suppresses this alteration. Optional arguments can occur in any + order. 'no' is recognized as a synonym of 'no-repeat-info' for + 'AT&T' compatibility. + + -- Macro: .TL + Specify the document title. 'ms' collects text on input lines + following this call into the title until reaching 'AU', 'AB', or a + heading or paragraphing macro call. + + -- Macro: .AU + Specify an author's name. 'ms' collects text on input lines + following this call into the author's name until reaching 'AI', + 'AB', another 'AU', or a heading or paragraphing macro call. Call + it repeatedly to specify multiple authors. + + -- Macro: .AI + Specify the preceding author's institution. An 'AU' call is + usefully followed by at most one 'AI' call; if there are more, the + last 'AI' call controls. 'ms' collects text on input lines + following this call into the author's institution until reaching + 'AU', 'AB', or a heading or paragraphing macro call. + + -- Macro: .DA [x ...] + Typeset the current date, or any arguments X, in the center footer, + and, if 'RP' is also called, left-aligned at the end of the + description information on the cover page. + + -- Macro: .ND [x ...] + Typeset the current date, or any arguments X, if 'RP' is also + called, left-aligned at the end of the document description on the + cover page. This is 'groff' 'ms''s default. + + -- Macro: .AB [no] + Begin the abstract. 'ms' collects text on input lines following + this call into the abstract until reaching an 'AE' call. By + default, 'ms' places the word "ABSTRACT" centered and in italics + above the text of the abstract. The optional argument 'no' + suppresses this heading. + + -- Macro: .AE + End the abstract. + + An example document description, using a cover page, follows. + + .RP + .TL + The Inevitability of Code Bloat + in Commercial and Free Software + .AU + J.\& Random Luser + .AI + University of West Bumblefuzz + .AB + This report examines the long-term growth of the code + bases in two large, + popular software packages; + the free Emacs and the commercial Microsoft Word. + While differences appear in the type or order of + features added, + due to the different methodologies used, + the results are the same in the end. + .PP + The free software approach is shown to be superior in + that while free software can become as bloated as + commercial offerings, + free software tends to have fewer serious bugs and the + added features are more in line with user demand. + .AE + + ...the rest of the paper... + + +File: groff.info, Node: ms Document Description Macros-Footnotes, Up: ms Document Description Macros + + (1) Distinguish a document title from "titles", which are what 'roff' +systems call headers and footers collectively. + + +File: groff.info, Node: ms Body Text, Next: ms Page Layout, Prev: ms Document Description Macros, Up: ms + +4.6.5 Body Text +--------------- + +A variety of macros, registers, and strings can be used to structure and +style the body of your document. They organize your text into +paragraphs, headings, footnotes, and inclusions of material such as +tables and figures. + +* Menu: + +* Text settings in ms:: +* Typographical symbols in ms:: +* Paragraphs in ms:: +* Headings in ms:: +* Typeface and decoration:: +* Lists in ms:: +* Indented regions in ms:: +* ms keeps and displays:: +* ms Insertions:: +* ms Footnotes:: +* ms language and localization:: + + +File: groff.info, Node: Text settings in ms, Next: Typographical symbols in ms, Prev: ms Body Text, Up: ms Body Text + +4.6.5.1 Text settings +..................... + +The 'FAM' string, a GNU extension, sets the font family for body text; +the default is 'T'. The 'PS' and 'VS' registers set the type size and +vertical spacing (distance between text baselines), respectively. The +font family and type size are ignored on terminal devices. Setting +these parameters before the first call of a heading, paragraphing, or +(non-date) document description macro also applies them to headers, +footers, and (for 'FAM') footnotes. + + Which font families are available depends on the output device; as a +convention, 'T' selects a serif family ("Times"), 'H' a sans-serif +family ("Helvetica"), and 'C' a monospaced family ("Courier"). The man +page for the output driver documents its font repertoire. Consult the +'groff(1)' man page for lists of available output devices and their +drivers. + + The hyphenation mode (as used by the 'hy' request) is set from the +'HY' register. Setting 'HY' to '0' is equivalent to using the 'nh' +request. This is a Tenth Edition Research Unix extension. + + +File: groff.info, Node: Typographical symbols in ms, Next: Paragraphs in ms, Prev: Text settings in ms, Up: ms Body Text + +4.6.5.2 Typographical symbols +............................. + +'ms' provides a few strings to obtain typographical symbols not easily +entered with the keyboard. These and many others are available as +special character escape sequences--see the 'groff_char(7)' man page. + + -- String: \*[-] + Interpolate an em dash. + + -- String: \*[Q] + -- String: \*[U] + Interpolate typographer's quotation marks where available, and + neutral double quotes otherwise. '\*Q' is the left quote and '\*U' + the right. + + +File: groff.info, Node: Paragraphs in ms, Next: Headings in ms, Prev: Typographical symbols in ms, Up: ms Body Text + +4.6.5.3 Paragraphs +.................. + +Paragraphing macros "break", or terminate, any pending output line so +that a new paragraph can begin. Several paragraph types are available, +differing in how indentation applies to them: to left, right, or both +margins; to the first output line of the paragraph, all output lines, or +all but the first. All paragraphing macro calls cause the insertion of +vertical space in the amount stored in the 'PD' register, except at page +or column breaks. Alternatively, a blank input line breaks the output +line and vertically spaces by one vee. + + -- Macro: .LP + Set a paragraph without any (additional) indentation. + + -- Macro: .PP + Set a paragraph with a first-line left indentation in the amount + stored in the 'PI' register. + + -- Macro: .IP [marker [width]] + Set a paragraph with a left indentation. The optional MARKER is + not indented and is empty by default. It has several applications; + see *note Lists in ms::. WIDTH overrides the indentation amount + stored in the 'PI' register; its default unit is 'n'. Once + specified, WIDTH applies to further 'IP' calls until specified + again or a heading or different paragraphing macro is called. + + -- Macro: .QP + Set a paragraph indented from both left and right margins by the + amount stored in the 'QI' register. + + -- Macro: .QS + -- Macro: .QE + Begin ('QS') and end ('QE') a region where each paragraph is + indented from both margins by the amount stored in the 'QI' + register. The text between 'QS' and 'QE' can be structured further + by use of other paragraphing macros. + + -- Macro: .XP + Set an "exdented" paragraph--one with a left indentation in the + amount stored in the 'PI' register on every line _except_ the first + (also known as a hanging indent). This is a Berkeley extension. + + The following example illustrates the use of paragraphing macros. + + .NH 2 + Cases used in the 2001 study + .LP + Two software releases were considered for this report. + .PP + The first is commercial software; + the second is free. + .IP \[bu] + Microsoft Word for Windows, + starting with version 1.0 through the current version + (Word 2000). + .IP \[bu] + GNU Emacs, + from its first appearance as a standalone editor through + the current version (v20). + See [Bloggs 2002] for details. + .QP + Franklin's Law applied to software: + software expands to outgrow both RAM and disk space over + time. + .SH + Bibliography + .XP + Bloggs, Joseph R., + .I "Everyone's a Critic" , + Underground Press, March 2002. + A definitive work that answers all questions and + criticisms about the quality and usability of free + software. + + +File: groff.info, Node: Headings in ms, Next: Typeface and decoration, Prev: Paragraphs in ms, Up: ms Body Text + +4.6.5.4 Headings +................ + +Use headings to create a sequential or hierarchical structure for your +document. The 'ms' macros print headings in *bold* using the same font +family and, by default, type size as the body text. Headings are +available with and without automatic numbering. Text on input lines +following the macro call becomes the heading's title. Call a +paragraphing macro to end the heading text and start the section's +content. + + -- Macro: .NH [depth] + -- Macro: .NH S heading-depth-index ... + Set an automatically numbered heading. + + 'ms' produces a numbered heading the form A.B.C..., to any depth + desired, with the numbering of each depth increasing automatically + and being reset to zero when a more significant level is increased. + "1" is the most significant or coarsest division of the document. + Only non-zero values are output. If DEPTH is omitted, it is taken + to be '1'. + + If you specify DEPTH such that an ascending gap occurs relative to + the previous 'NH' call--that is, you "skip a depth", as by '.NH 1' + and then '.NH 3'--'groff' 'ms' emits a warning on the standard + error stream. + + Alternatively, you can give 'NH' a first argument of 'S', followed + by integers to number the heading depths explicitly. Further + automatic numbering, if used, resumes using the specified indices + as their predecessors. This feature is a Berkeley extension. + + An example may be illustrative. + + .NH 1 + Animalia + .NH 2 + Arthropoda + .NH 3 + Crustacea + .NH 2 + Chordata + .NH S 6 6 6 + Daimonia + .NH 1 + Plantae + + The above results in numbering as follows; the vertical space that +normally precedes each heading is omitted. + + 1. Animalia + 1.1. Arthropoda + 1.1.1. Crustacea + 1.2. Chordata + 6.6.6. Daimonia + 7. Plantae + + -- String: \*[SN-STYLE] + -- String: \*[SN-DOT] + -- String: \*[SN-NO-DOT] + -- String: \*[SN] + After 'NH' is called, the assigned number is made available in the + strings 'SN-DOT' (as it appears in a printed heading with default + formatting, followed by a terminating period) and 'SN-NO-DOT' (with + the terminating period omitted). These are GNU extensions. + + You can control the style used to print numbered headings by + defining an appropriate alias for the string 'SN-STYLE'. By + default, 'SN-STYLE' is aliased to 'SN-DOT'. If you prefer to omit + the terminating period from numbers appearing in numbered headings, + you may define the alias as follows. + + .als SN-STYLE SN-NO-DOT + + Any such change in numbering style becomes effective from the next + use of 'NH' following redefinition of the alias for 'SN-STYLE'. + The formatted number of the current heading is available in the + 'SN' string (a feature first documented by Berkeley), which + facilitates its inclusion in, for example, table captions, equation + labels, and 'XS'/'XA'/'XE' table of contents entries. + + -- Macro: .SH [depth] + Set an unnumbered heading. + + The optional DEPTH argument is a GNU extension indicating the + heading depth corresponding to the DEPTH argument of 'NH'. It + matches the type size at which the heading is set to that of a + numbered heading at the same depth when the 'GROWPS' and 'PSINCR' + heading size adjustment mechanism is in effect. + + If the 'GROWPS' register is set to a value greater than the LEVEL +argument to 'NH' or 'SH', the type size of a heading produced by these +macros increases by 'PSINCR' units over the size specified by 'PS' +multiplied by the difference of 'GROWPS' and LEVEL. The value stored in +'PSINCR' is interpreted in 'groff' basic units; the 'p' scaling unit +should be employed when assigning a value specified in points. For +example, the sequence + + .nr PS 10 + .nr GROWPS 3 + .nr PSINCR 1.5p + .NH 1 + Carnivora + .NH 2 + Felinae + .NH 3 + Felis catus + .SH 2 + Machairodontinae + +will cause "1. Carnivora" to be printed in 13-point text, followed by +"1.1. Felinae" in 11.5-point text, while "1.1.1. Felis catus" and all +more deeply nested heading levels will remain in the 10-point text +specified by the 'PS' register. "Machairodontinae" is printed at 11.5 +points, since it corresponds to heading level 2. + + The 'HORPHANS' register operates in conjunction with the 'NH' and +'SH' macros to inhibit the printing of isolated headings at the bottom +of a page; it specifies the minimum number of lines of an immediately +subsequent paragraph that must be kept on the same page as the heading. +If insufficient space remains on the current page to accommodate the +heading and this number of lines of paragraph text, a page break is +forced before the heading is printed. Any display macro call or 'tbl', +'pic', or 'eqn' region between the heading and the subsequent paragraph +suppresses this grouping. *Note ms keeps and displays:: and *note ms +Insertions::. + + +File: groff.info, Node: Typeface and decoration, Next: Lists in ms, Prev: Headings in ms, Up: ms Body Text + +4.6.5.5 Typeface and decoration +............................... + +The 'ms' macros provide a variety of ways to style text. Attend closely +to the ordering of arguments labeled PRE and POST, which is not +intuitive. Support for PRE arguments is a GNU extension.(1) (*note +Typeface and decoration-Footnote-1::) + + -- Macro: .B [text [post [pre]]] + Style TEXT in bold, followed by POST in the previous font style + without intervening space, and preceded by PRE similarly. Without + arguments, 'ms' styles subsequent text in bold until the next + paragraphing, heading, or no-argument typeface macro call. + + -- Macro: .R [text [post [pre]]] + As 'B', but use the roman style (upright text of normal weight) + instead of bold. Argument recognition is a GNU extension. + + -- Macro: .I [text [post [pre]]] + As 'B', but use an italic or oblique style instead of bold. + + -- Macro: .BI [text [post [pre]]] + As 'B', but use a bold italic or bold oblique style instead of + upright bold. This is a Tenth Edition Research Unix extension. + + -- Macro: .CW [text [post [pre]]] + As 'B', but use a constant-width (monospaced) roman typeface + instead of bold. This is a Tenth Edition Research Unix extension. + + -- Macro: .BX [text] + Typeset TEXT and draw a box around it. On terminal devices, + reverse video is used instead. If you want TEXT to contain space, + use unbreakable space or horizontal motion escape sequences ('\~', + '\', '\^', '\|', '\0' or '\h'). + + -- Macro: .UL [text [post]] + Typeset TEXT with an underline. POST, if present, is set after + TEXT with no intervening space. + + -- Macro: .LG + Set subsequent text in larger type (two points larger than the + current size) until the next type size, paragraphing, or heading + macro call. You can specify this macro multiple times to enlarge + the type size as needed. + + -- Macro: .SM + Set subsequent text in smaller type (two points smaller than the + current size) until the next type size, paragraphing, or heading + macro call. You can specify this macro multiple times to reduce + the type size as needed. + + -- Macro: .NL + Set subsequent text at the normal type size (the amount in the 'PS' + register). + + PRE and POST arguments are typically used to simplify the attachment +of punctuation to styled words. When PRE is used, a hyphenation control +escape sequence '\%' that would ordinarily start TEXT must start PRE +instead to have the desired effect. + + The CS course's students found one C language keyword + .CW static ) \%( + most troublesome. + + The foregoing example produces output as follows. + + The CS course's students found one C language keyword (static) + most troublesome. + + You can use the output line continuation escape sequence '\c' to +achieve the same result (*note Line Continuation::). It is also +portable to older 'ms' implementations. + + The CS course's students found one C language keyword + \%(\c + .CW \%static ) + most troublesome. + + 'groff' 'ms' also offers strings to begin and end super- and +subscripting. These are GNU extensions. + + -- String: \*[{] + -- String: \*[}] + Begin and end superscripting, respectively. + + -- String: \*[<] + -- String: \*[>] + Begin and end subscripting, respectively. + + Rather than calling the 'CW' macro, in 'groff' 'ms' you might prefer +to change the font family to Courier by setting the 'FAM' string to 'C'. +You can then use all four style macros above, returning to the default +family (Times) with '.ds FAM T'. Because changes to 'FAM' take effect +only at the next paragraph, 'CW' remains useful to "inline" a change to +the font family, similarly to the practice of this document in noting +syntactical elements of 'ms' and 'groff'. + + +File: groff.info, Node: Typeface and decoration-Footnotes, Up: Typeface and decoration + + (1) This idiosyncrasy arose through feature accretion; for example, +the 'B' macro in Version 6 Unix 'ms' (1975) accepted only one argument, +the text to be set in boldface. By Version 7 (1979) it recognized a +second argument; in 1990, 'groff' 'ms' added a "pre" argument, placing +it third to avoid breaking support for older documents. + + +File: groff.info, Node: Lists in ms, Next: Indented regions in ms, Prev: Typeface and decoration, Up: ms Body Text + +4.6.5.6 Lists +............. + +The MARKER argument to the 'IP' macro can be employed to present a +variety of lists; for instance, you can use a bullet glyph ('\[bu]') for +unordered lists, a number (or auto-incrementing register) for numbered +lists, or a word or phrase for glossary-style or definition lists. If +you set the paragraph indentation register 'PI' before calling 'IP', you +can later reorder the items in the list without having to ensure that a +WIDTH argument remains affixed to the first call. + + The following is an example of a bulleted list. + + .nr PI 2n + A bulleted list: + .IP \[bu] + lawyers + .IP \[bu] + guns + .IP \[bu] + money + + A bulleted list: + + * lawyers + + * guns + + * money + + The following is an example of a numbered list. + + .nr step 0 1 + .nr PI 3n + A numbered list: + .IP \n+[step] + lawyers + .IP \n+[step] + guns + .IP \n+[step] + money + + A numbered list: + + 1. lawyers + + 2. guns + + 3. money + + Here we have employed the 'nr' request to create a register of our +own, 'step'. We initialized it to zero and assigned it an +auto-increment of 1. Each time we use the escape sequence '\n+[PI]' +(note the plus sign), the formatter applies the increment just before +interpolating the register's value. Preparing the 'PI' register as well +enables us to rearrange the list without the tedium of updating macro +calls. + + The next example illustrates a glossary-style list. + + A glossary-style list: + .IP lawyers 0.4i + Two or more attorneys. + .IP guns + Firearms, + preferably large-caliber. + .IP money + Gotta pay for those + lawyers and guns! + + A glossary-style list: + + lawyers + Two or more attorneys. + + guns Firearms, preferably large-caliber. + + money + Gotta pay for those lawyers and guns! + + In the previous example, observe how the 'IP' macro places the +definition on the same line as the term if it has enough space. If this +is not what you want, there are a few workarounds we will illustrate by +modifying the example. First, you can use a 'br' request to force a +break after printing the term or label. + + .IP guns + .br + Firearms, + + Second, you could apply the '\p' escape sequence to force a break. +The space following the escape sequence is important; if you omit it, +'groff' prints the first word of the paragraph text on the same line as +the term or label (if it fits) _then_ breaks the line. + + .IP guns + \p Firearms, + + Finally, you may append a horizontal motion to the marker with the +'\h' escape sequence; using the same amount as the indentation will +ensure that the marker is too wide for 'groff' to treat it as "fitting" +on the same line as the paragraph text. + + .IP guns\h'0.4i' + Firearms, + + In each case, the result is the same. + + A glossary-style list: + + lawyers + Two or more attorneys. + + guns + Firearms, preferably large-caliber. + + money + Gotta pay for those lawyers and guns! + + +File: groff.info, Node: Indented regions in ms, Next: ms keeps and displays, Prev: Lists in ms, Up: ms Body Text + +4.6.5.7 Indented regions +........................ + +You may need to indent a region of text while otherwise formatting it +normally. Indented regions can be nested; you can change '\n[PI]' +before each call to vary the amount of inset. + + -- Macro: .RS + Begin a region where headings, paragraphs, and displays are + indented (further) by the amount stored in the 'PI' register. + + -- Macro: .RE + End the (next) most recent indented region. + + This feature enables you to easily line up text under hanging and +indented paragraphs. For example, you may wish to structure lists +hierarchically. + + .IP \[bu] 2 + Lawyers: + .RS + .IP \[bu] + Dewey, + .IP \[bu] + Cheatham, + and + .IP \[bu] + and Howe. + .RE + .IP \[bu] + Guns + + * Lawyers: + + * Dewey, + + * Cheatham, and + + * Howe. + + * Guns + + +File: groff.info, Node: ms keeps and displays, Next: ms Insertions, Prev: Indented regions in ms, Up: ms Body Text + +4.6.5.8 Keeps, boxed keeps, and displays +........................................ + +On occasion, you may want to "keep" several lines of text, or a region +of a document, together on a single page, preventing an automatic page +break within certain boundaries. This can cause a page break to occur +earlier than it normally would. For example, you may want to keep two +paragraphs together, or a paragraph that refers to a table, list, or +figure adjacent to the item it discusses. 'ms' provides the 'KS' and +'KE' macros for this purpose. + + You can alternatively specify a "floating keep": if a keep cannot fit +on the current page, 'ms' holds its contents and allows material +following the keep (in the source document) to fill the remainder of the +current page. When the page breaks, whether by reaching the end or 'bp' +request, 'ms' puts the floating keep at the beginning of the next page. +This is useful for placing large graphics or tables that do not need to +appear exactly where they occur in the source document. + + -- Macro: .KS + -- Macro: .KF + -- Macro: .KE + 'KS' begins a keep, 'KF' a floating keep, and 'KE' ends a keep of + either kind. + + As an alternative to the keep mechanism, the 'ne' request forces a +page break if there is not at least the amount of vertical space +specified in its argument remaining on the page (*note Page Control::). +One application of 'ne' is to reserve space on the page for a figure or +illustration to be included later. + + A "boxed keep" has a frame drawn around it. + + -- Macro: .B1 + -- Macro: .B2 + 'B1' begins a keep with a box drawn around it. 'B2' ends a boxed + keep. + + Boxed keep macros cause breaks; if you need to box a word or phrase +within a line, see the 'BX' macro in *note Typeface and decoration::. +Box lines are drawn as close as possible to the text they enclose so +that they are usable within paragraphs. If you wish to box one or more +paragraphs, you may improve the appearance by calling 'B1' after the +first paragraphing macro, and by adding a small amount of vertical space +before calling 'B2'. + + .LP + .B1 + .I Warning: + Happy Fun Ball may suddenly accelerate to dangerous + speeds. + .sp \n[PD]/2 \" space by half the inter-paragraph distance + .B2 + + If you want a boxed keep to float, you will need to enclose the 'B1' +and 'B2' calls within a pair of 'KF' and 'KE' calls. + + "Displays" turn off filling; lines of verse or program code are shown +with their lines broken as in the source document without requiring 'br' +requests between lines. Displays can be kept on a single page or +allowed to break across pages. The 'DS' macro begins a kept display of +the layout specified in its first argument; non-kept displays are begun +with dedicated macros corresponding to their layout. + + -- Macro: .DS L + -- Macro: .LD + Begin ('DS': kept) left-aligned display. + + -- Macro: .DS [I [indent]] + -- Macro: .ID [indent] + Begin ('DS': kept) display indented by INDENT if specified, and by + the amount of the 'DI' register otherwise. + + -- Macro: .DS B + -- Macro: .BD + Begin a ('DS': kept) a block display: the entire display is + left-aligned, but indented such that the longest line in the + display is centered on the page. + + -- Macro: .DS C + -- Macro: .CD + Begin a ('DS': kept) centered display: each line in the display is + centered. + + -- Macro: .DS R + -- Macro: .RD + Begin a ('DS': kept) right-aligned display. This is a GNU + extension. + + -- Macro: .DE + End any display. + + The distance stored in the 'DD' register is inserted before and after +each pair of display macros; this is a Berkeley extension. In 'groff' +'ms', this distance replaces any adjacent inter-paragraph distance or +subsequent spacing prior to a section heading. The 'DI' register is a +GNU extension; its value is an indentation applied to displays created +with '.DS' and '.ID' without arguments, to '.DS I' without an +indentation argument, and to indented equations set with '.EQ'. Changes +to either register take effect at the next display boundary. + + +File: groff.info, Node: ms Insertions, Next: ms Footnotes, Prev: ms keeps and displays, Up: ms Body Text + +4.6.5.9 Tables, figures, equations, and references +.................................................. + +The 'ms' package is often used with the 'tbl', 'pic', 'eqn', and 'refer' +preprocessors. Mark text meant for preprocessors by enclosing it in +pairs of tokens as follows, with nothing between the dot and the macro +name. The preprocessors match these tokens only at the start of an +input line. + + -- Macro: .TS [H] + -- Macro: .TE + Demarcate a table to be processed by the 'tbl' preprocessor. The + optional argument 'H' to 'TS' instructs 'ms' to repeat table rows + (often column headings) at the top of each new page the table + spans, if applicable; calling the 'TH' macro marks the end of such + rows. The GNU 'tbl(1)' man page provides a comprehensive reference + to the preprocessor and offers examples of its use. + + -- Macro: .PS + -- Macro: .PE + -- Macro: .PF + 'PS' begins a picture to be processed by the 'gpic' preprocessor; + either of 'PE' or 'PF' ends it, the latter with "flyback" to the + vertical position at its top. You can create 'pic' input manually + or with a program such as 'xfig'. + + -- Macro: .EQ [align [label]] + -- Macro: .EN + Demarcate an equation to be processed by the 'eqn' preprocessor. + The equation is centered by default; ALIGN can be 'C', 'L', or 'I' + to (explicitly) center, left-align, or indent it by the amount + stored in the 'DI' register, respectively. If specified, LABEL is + set right-aligned. + + -- Macro: .[ + -- Macro: .] + Demarcate a bibliographic citation to be processed by the 'refer' + preprocessor. The GNU 'refer(1)' man page provides a comprehensive + reference to the preprocessor and the format of its bibliographic + database. Type 'man refer' at the command line to view it. + + When 'refer' emits collected references (as might be done on a "Works +Cited" page), it interpolates the 'REFERENCES' string as an unnumbered +heading ('SH'). + + The following is an example of how to set up a table that may print +across two or more pages. + + .TS H + allbox; + Cb | Cb . + Part->Description + _ + .TH + .T& + GH-1978->Fribulating gonkulator + ...the rest of the table follows... + .TE + +Attempting to place a multi-page table inside a keep can lead to +unpleasant results, particularly if the 'tbl' 'allbox' option is used. + + Mathematics can be typeset using the language of the 'eqn' +preprocessor. + + .EQ C (\*[SN-NO-DOT]a) + p ~ = ~ q sqrt { ( 1 + ~ ( x / q sup 2 ) } + .EN + +This input formats a labelled equation. We used the 'SN-NO-DOT' string +to base the equation label on the current heading number, giving us more +flexibility to reorganize the document. + + Use 'groff' options to run preprocessors on the input: '-e' for +'geqn', '-p' for 'gpic', '-R' for 'grefer', and '-t' for 'gtbl'. + + +File: groff.info, Node: ms Footnotes, Prev: ms Insertions, Up: ms Body Text + +4.6.5.10 Footnotes +.................. + +A footnote is typically anchored to a place in the text with a "marker", +which is a small integer, a symbol such as a dagger, or arbitrary +user-specified text. + + -- String: \*[*] + Place an "automatic number", an automatically generated numeric + footnote marker, in the text. Each time this string is + interpolated, the number it produces increments by one. Automatic + numbers start at 1. This is a Berkeley extension. + + Enclose the footnote text in 'FS' and 'FE' macro calls to set it at +the nearest available "foot", or bottom, of a text column or page. + + -- Macro: .FS [marker] + -- Macro: .FE + Begin ('FS') and end ('FE') a footnote. 'FS' calls 'FS-MARK' with + any supplied MARKER argument, which is then also placed at the + beginning of the footnote text. If MARKER is omitted, the next + pending automatic footnote number enqueued by interpolation of the + '*' string is used, and if none exists, nothing is prefixed. + + You may not desire automatically numbered footnotes in spite of their +convenience. You can indicate a footnote with a symbol or other text by +specifying its marker at the appropriate place (for example, by using +'\[dg]' for the dagger glyph) _and_ as an argument to the 'FS' macro. +Such manual marks should be repeated as arguments to 'FS' or as part of +the footnote text to disambiguate their correspondence. You may wish to +use '\*{' and '\*}' to superscript the marker at the anchor point, in +the footnote text, or both. + + 'groff' 'ms' provides a hook macro, 'FS-MARK', for user-determined +operations to be performed when the 'FS' macro is called. It is passed +the same arguments as 'FS' itself. An application of 'FS-MARK' is +anchor placement for a hyperlink reference, so that a footnote can link +back to its referential context.(1) (*note ms Footnotes-Footnote-1::) +By default, this macro has an empty definition. 'FS-MARK' is a GNU +extension. + + Footnotes can be safely used within keeps and displays, but you +should avoid using automatically numbered footnotes within floating +keeps. You can place a second '\**' interpolation between a '\**' and +its corresponding 'FS' call as long as each 'FS' call occurs _after_ the +corresponding '\**' and occurrences of 'FS' are in the same order as +corresponding occurrences of '\**'. + + Footnote text is formatted as paragraphs are, using analogous +parameters. The registers 'FI', 'FPD', 'FPS', and 'FVS' correspond to +'PI', 'PD', 'PS', and 'CS', respectively; 'FPD', 'FPS', and 'FVS' are +GNU extensions. + + The 'FF' register controls the formatting of automatically numbered +footnote paragraphs and those for which 'FS' is given a marker argument. +*Note ms Document Control Settings::. + + The default footnote line length is 11/12ths of the normal line +length for compatibility with the expectations of historical 'ms' +documents; you may wish to set the 'FR' string to '1' to align with +contemporary typesetting practices. In the past,(2) (*note ms +Footnotes-Footnote-2::) an 'FL' register was used for the line length in +footnotes; however, setting this register at document initialization +time had no effect on the footnote line length in multi-column +arrangements.(3) (*note ms Footnotes-Footnote-3::) + + 'FR' should be used in preference to the old 'FL' register in +contemporary documents. The footnote line length is effectively +computed as 'column-width * \*[FR]'. If an absolute footnote line +length is required, recall that arithmetic expressions in 'roff' input +are evaluated strictly from left to right, with no operator precedence +(parentheses are honored). + + .ds FR 0+3i \" Set footnote line length to 3 inches. + + +File: groff.info, Node: ms Footnotes-Footnotes, Up: ms Footnotes + + (1) "Portable Document Format Publishing with GNU Troff", +'pdfmark.ms' in the 'groff' distribution, uses this technique. + + (2) Unix Version 7 'ms', its descendants, and GNU 'ms' prior to +'groff' version 1.23.0 + + (3) You could reset it after each call to '.1C', '.2C', or '.MC'. + + +File: groff.info, Node: ms language and localization, Next: ms Page Layout, Prev: ms Footnotes, Up: ms Body Text + +4.6.5.11 Language and localization +.................................. + +'groff' 'ms' provides several strings that you can customize for your +own purposes, or redefine to adapt the macro package to languages other +than English. It is already localized for Czech, German, French, +Italian, and Swedish. Load the desired localization macro package after +'ms'; see the 'groff_tmac(5)' man page. + + $ groff -ms -mfr bienvenue.ms + + The following strings are available. + + -- String: \*[REFERENCES] + Contains the string printed at the beginning of a references + (bibliography) page produced with GNU 'refer(1)'. The default is + 'References'. + + -- String: \*[ABSTRACT] + Contains the string printed at the beginning of the abstract. The + default is '\f[I]ABSTRACT\f[]'; it includes font selection escape + sequences to set the word in italics. + + -- String: \*[TOC] + Contains the string printed at the beginning of the table of + contents. The default is 'Table of Contents'. + + -- String: \*[MONTH1] + -- String: \*[MONTH2] + -- String: \*[MONTH3] + -- String: \*[MONTH4] + -- String: \*[MONTH5] + -- String: \*[MONTH6] + -- String: \*[MONTH7] + -- String: \*[MONTH8] + -- String: \*[MONTH9] + -- String: \*[MONTH10] + -- String: \*[MONTH11] + -- String: \*[MONTH12] + Contain the full names of the calendar months. The defaults are in + English: 'January', 'February', and so on. + + +File: groff.info, Node: ms Page Layout, Next: Differences from AT&T ms, Prev: ms Body Text, Up: ms + +4.6.6 Page layout +----------------- + +'ms''s default page layout arranges text in a single column with the +page number between hyphens centered in a header on each page except the +first, and produces no footers. You can customize this arrangement. + +* Menu: + +* ms Headers and Footers:: +* Tab Stops in ms:: +* ms Margins:: +* ms Multiple Columns:: +* ms TOC:: + + +File: groff.info, Node: ms Headers and Footers, Next: Tab Stops in ms, Prev: ms Page Layout, Up: ms Page Layout + +4.6.6.1 Headers and footers +........................... + +There are multiple ways to produce headers and footers. One is to +define the strings 'LH', 'CH', and 'RH' to set the left, center, and +right headers, respectively; and 'LF', 'CF', and 'RF' to set the left, +center, and right footers. This approach suffices for documents that do +not distinguish odd- and even-numbered pages. + + Another method is to call macros that set headers or footers for odd- +or even-numbered pages. Each such macro takes a delimited argument +separating the left, center, and right header or footer texts from each +other. You can replace the neutral apostrophes (''') shown below with +any character not appearing in the header or footer text. These macros +are Berkeley extensions. + + -- Macro: .OH 'left'center'right' + -- Macro: .EH 'left'center'right' + -- Macro: .OF 'left'center'right' + -- Macro: .EF 'left'center'right' + The 'OH' and 'EH' macros define headers for odd- (recto) and + even-numbered (verso) pages, respectively; the 'OF' and 'EF' macros + define footers for them. + + With either method, a percent sign '%' in header or footer text is +replaced by the current page number. By default, 'ms' places no header +on a page numbered "1" (regardless of its number format). + + -- Macro: .P1 + Typeset the header even on page 1. To be effective, this macro + must be called before the header trap is sprung on any page + numbered "1"; in practice, unless your page numbering is unusual, + this means that you should call it early, before 'TL' or any + heading or paragraphing macro. This is a Berkeley extension. + + For even greater flexibility, 'ms' is designed to permit the +redefinition of the macros that are called when the 'groff' traps that +ordinarily cause the headers and footers to be output are sprung. 'PT' +("page trap") is called by 'ms' when the header is to be written, and +'BT' ("bottom trap") when the footer is to be. The 'groff' page +location trap that 'ms' sets up to format the header also calls the +(normally undefined) 'HD' macro after 'PT'; you can define 'HD' if you +need additional processing after setting the header (for example, to +draw a line below it). The 'HD' hook is a Berkeley extension. Any such +macros you (re)define must implement any desired specialization for +odd-, even-, or first numbered pages. + + +File: groff.info, Node: Tab Stops in ms, Next: ms Margins, Prev: ms Headers and Footers, Up: ms Page Layout + +4.6.6.2 Tab stops +................. + +Use the 'ta' request to define tab stops as needed. *Note Tabs and +Fields::. + + -- Macro: .TA + Reset the tab stops to the 'ms' default (every 5 ens). Redefine + this macro to create a different set of default tab stops. + + +File: groff.info, Node: ms Margins, Next: ms Multiple Columns, Prev: Tab Stops in ms, Up: ms Page Layout + +4.6.6.3 Margins +............... + +Control margins using the registers summarized in "Margin settings" in +*note ms Document Control Settings:: above. There is no setting for the +right margin; the combination of page offset '\n[PO]' and line length +'\n[LL]' determines it. + + +File: groff.info, Node: ms Multiple Columns, Next: ms TOC, Prev: ms Margins, Up: ms Page Layout + +4.6.6.4 Multiple columns +........................ + +'ms' can set text in as many columns as reasonably fit on the page. The +following macros force a page break if a multi-column layout is active +when they are called. The 'MINGW' register stores the default minimum +gutter width; it is a GNU extension. When multiple columns are in use, +keeps and the 'HORPHANS' and 'PORPHANS' registers work with respect to +column breaks instead of page breaks. + + -- Macro: .1C + Arrange page text in a single column (the default). + + -- Macro: .2C + Arrange page text in two columns. + + -- Macro: .MC [column-width [gutter-width]] + Arrange page text in multiple columns. If you specify no + arguments, it is equivalent to the '2C' macro. Otherwise, + COLUMN-WIDTH is the width of each column and GUTTER-WIDTH is the + minimum distance between columns. + + +File: groff.info, Node: ms TOC, Next: Differences from AT&T ms, Prev: ms Multiple Columns, Up: ms Page Layout + +4.6.6.5 Creating a table of contents +.................................... + +Because 'roff' formatters process their input in a single pass, material +on page 50, for example, cannot influence what appears on page 1--this +poses a challenge for a table of contents at its traditional location in +front matter, if you wish to avoid manually maintaining it. 'ms' +enables the collection of material to be presented in the table of +contents as it appears, saving its page number along with it, and then +emitting the collected contents on demand toward the end of the +document. The table of contents can then be resequenced to its desired +location by physically rearranging the pages of a printed document, or +as part of post-processing--with a 'sed(1)' script to reorder the pages +in 'troff''s output, with 'pdfjam(1)', or with 'gropdf(1)''s +'.pdfswitchtopage' feature, for example. + + Define an entry to appear in the table of contents by bracketing its +text between calls to the 'XS' and 'XE' macros. A typical application +is to call them immediately after 'NH' or 'SH' and repeat the heading +text within them. The 'XA' macro, used within '.XS'/'.XE' pairs, +supplements an entry--for instance, when it requires multiple output +lines, whether because a heading is too long to fit or because style +dictates that page numbers not be repeated. You may wish to indent the +text thus wrapped to correspond to its heading depth; this can be done +in the entry text by prefixing it with tabs or horizontal motion escape +sequences, or by providing a second argument to the 'XA' macro. 'XS' +and 'XA' automatically associate the page number where they are called +with the text following them, but they accept arguments to override this +behavior. At the end of the document, call 'TC' or 'PX' to emit the +table of contents; 'TC' resets the page number to 'i' (Roman numeral +one), and then calls 'PX'. All of these macros are Berkeley extensions. + + -- Macro: .XS [page-number] + -- Macro: .XA [page-number [indentation]] + -- Macro: .XE + Begin, supplement, and end a table of contents entry. Each entry + is associated with PAGE-NUMBER (otherwise the current page number); + a PAGE-NUMBER of 'no' prevents a leader and page number from being + emitted for that entry. Use of 'XA' within 'XS'/'XE' is optional; + it can be repeated. If INDENTATION is present, a supplemental + entry is indented by that amount; ens are assumed if no unit is + indicated. Text on input lines between 'XS' and 'XE' is stored for + later recall by 'PX'. + + -- Macro: .PX [no] + Switch to single-column layout. Unless 'no' is specified, center + and interpolate the 'TOC' string in bold and two points larger than + the body text. Emit the table of contents entries. + + -- Macro: .TC [no] + Set the page number to 1, the page number format to lowercase Roman + numerals, and call 'PX' (with a 'no' argument, if present). + + Here's an example of typical 'ms' table of contents preparation. We +employ horizontal escape sequences '\h' to indent the entries by +sectioning depth. + + .NH 1 + Introduction + .XS + Introduction + .XE + ... + .NH 2 + Methodology + .XS + \h'2n'Methodology + .XA + \h'4n'Fassbinder's Approach + \h'4n'Kahiu's Approach + .XE + ... + .NH 1 + Findings + .XS + Findings + .XE + ... + .TC + + The remaining features in this subsubsection are GNU extensions. +'groff' 'ms' obviates the need to repeat heading text after 'XS' calls. +Call 'XN' and 'XH' after 'NH' and 'SH', respectively. + + -- Macro: .XN heading-text + -- Macro: .XH depth heading-text + Format HEADING-TEXT and create a corresponding table of contents + entry. 'XN' computes the indentation from the depth of the + preceding 'NH' call; 'XH' requires a DEPTH argument to do so. + + 'groff' 'ms' encourages customization of table of contents entry +production. + + -- Macro: .XN-REPLACEMENT heading-text + -- Macro: .XH-REPLACEMENT depth heading-text + These hook macros implement 'XN' and 'XH', respectively. They call + 'XN-INIT' and pass their HEADING-TEXT arguments to 'XH-UPDATE-TOC'. + + -- Macro: .XN-INIT + -- Macro: .XH-UPDATE-TOC depth heading-text + The 'XN-INIT' hook macro does nothing by default. 'XH-UPDATE-TOC' + brackets HEADING-TEXT with 'XS' and 'XE' calls, indenting it by 2 + ens per level of DEPTH beyond the first. + + We could therefore produce a table of contents similar to that in the +previous example with fewer macro calls. (The difference is that this +input follows the "Approach" entries with leaders and page numbers.) + + .NH 1 + .XN Introduction + ... + .NH 2 + .XN Methodology + .XH 3 "Fassbinder's Approach" + .XH 3 "Kahiu's Approach" + ... + .NH 1 + .XN Findings + ... + + To get the section number of the numbered headings into the table of +contents entries, we might define 'XN-REPLACEMENT' as follows. (We +obtain the heading depth from 'groff' 'ms''s internal register 'nh*hl'.) + + .de XN-REPLACEMENT + .XN-INIT + .XH-UPDATE-TOC \\n[nh*hl] \\$@ + \&\\*[SN] \\$* + .. + + You can change the style of the leader that bridges each table of +contents entry with its page number; define the 'TC-LEADER' special +character by using the 'char' request. A typical leader combines the +dot glyph '.' with a horizontal motion escape sequence to spread the +dots. The width of the page number field is stored in the 'TC-MARGIN' +register. + + +File: groff.info, Node: Differences from AT&T ms, Next: ms Naming Conventions, Prev: ms Page Layout, Up: ms + +4.6.7 Differences from AT&T 'ms' +-------------------------------- + +The 'groff' 'ms' macros are an independent reimplementation, using no +AT&T code. Since they take advantage of the extended features of +'groff', they cannot be used with AT&T 'troff'. 'groff' 'ms' supports +features described above as Berkeley and Tenth Edition Research Unix +extensions, and adds several of its own. + + * The internals of 'groff' 'ms' differ from the internals of AT&T + 'ms'. Documents that depend upon implementation details of AT&T + 'ms' may not format properly with 'groff' 'ms'. Such details + include macros whose function was not documented in the AT&T 'ms' + manual.(1) (*note Differences from AT&T ms-Footnote-1::) + + * The error-handling policy of 'groff' 'ms' is to detect and report + errors, rather than to ignore them silently. + + * Tenth Edition Research Unix supported 'P1'/'P2' macros to bracket + code examples; 'groff' 'ms' does not. + + * 'groff' 'ms' does not work in GNU 'troff''s AT&T compatibility + mode. If loaded when that mode is enabled, it aborts processing + with a diagnostic message. + + * Multiple line spacing is not supported. Use a larger vertical + spacing instead. + + * 'groff' 'ms' uses the same header and footer defaults in both + 'nroff' and 'troff' modes as AT&T 'ms' does in 'troff' mode; AT&T's + default in 'nroff' mode is to put the date, in U.S. traditional + format (e.g., "January 1, 2021"), in the center footer (the 'CF' + string). + + * Many 'groff' 'ms' macros, including those for paragraphs, headings, + and displays, cause a reset of paragraph rendering parameters, and + may change the indentation; they do so not by incrementing or + decrementing it, but by setting it absolutely. This can cause + problems for documents that define additional macros of their own + that try to manipulate indentation. Use the 'ms' 'RS' and 'RE' + macros instead of the 'in' request. + + * AT&T 'ms' interpreted the values of the registers 'PS' and 'VS' in + points, and did not support the use of scaling units with them. + 'groff' 'ms' interprets values of the registers 'PS', 'VS', 'FPS', + and 'FVS' equal to or larger than 1,000 (one thousand) as decimal + fractions multiplied by 1,000.(2) (*note Differences from AT&T + ms-Footnote-2::) This threshold makes use of a scaling unit with + these parameters practical for high-resolution devices while + preserving backward compatibility. It also permits expression of + non-integral type sizes. For example, 'groff -rPS=10.5p' at the + shell prompt is equivalent to placing '.nr PS 10.5p' at the + beginning of the document. + + * AT&T 'ms''s 'AU' macro supported arguments used with some document + types; 'groff' 'ms' does not. + + * Right-aligned displays are available. The AT&T 'ms' manual + observes that "it is tempting to assume that '.DS R' will right + adjust lines, but it doesn't work". In 'groff' 'ms', it does. + + * To make 'groff' 'ms' use the default page offset (which also + specifies the left margin), the 'PO' register must stay undefined + until the first 'ms' macro is called. + + This implies that '\n[PO]' should not be used early in the + document, unless it is changed also: accessing an undefined + register automatically defines it. + + * 'groff' 'ms' supports the 'PN' register, but it is not necessary; + you can access the page number via the usual '%' register and + invoke the 'af' request to assign a different format to it if + desired.(3) (*note Differences from AT&T ms-Footnote-3::) + + * The AT&T 'ms' manual documents registers 'CW' and 'GW' as setting + the default column width and "intercolumn gap", respectively, and + which applied when 'MC' was called with fewer than two arguments. + 'groff' 'ms' instead treats 'MC' without arguments as synonymous + with '2C'; there is thus no occasion for a default column width + register. Further, the 'MINGW' register and the second argument to + 'MC' specify a _minimum_ space between columns, not the fixed + gutter width of AT&T 'ms'. + + * The AT&T 'ms' manual did not document the 'QI' register; Berkeley + and 'groff' 'ms' do. + + -- Register: \n[GS] + The register 'GS' is set to 1 by the 'groff' 'ms' macros, but is + not used by the AT&T 'ms' package. Documents that need to + determine whether they are being formatted with 'groff' 'ms' or + another implementation should test this register. + +* Menu: + +* Missing Unix Version 7 ms Macros:: + + +File: groff.info, Node: Differences from AT&T ms-Footnotes, Up: Differences from AT&T ms + + (1) 'Typing Documents on the UNIX System: Using the -ms Macros with +Troff and Nroff', M. E. Lesk, Bell Laboratories, 1978 + + (2) Register values are converted to and stored as basic units. +*Note Measurements::. + + (3) If you redefine the 'ms' 'PT' macro and desire special treatment +of certain page numbers (like '1'), you may need to handle a non-Arabic +page number format, as 'groff' 'ms''s 'PT' does; see the macro package +source. 'groff' 'ms' aliases the 'PN' register to '%'. + + +File: groff.info, Node: Missing Unix Version 7 ms Macros, Prev: Differences from AT&T ms, Up: Differences from AT&T ms + +4.6.7.1 Unix Version 7 'ms' macros not implemented by 'groff' 'ms' +.................................................................. + +Several macros described in the Unix Version 7 'ms' documentation are +unimplemented by 'groff' 'ms' because they are specific to the +requirements of documents produced internally by Bell Laboratories, some +of which also require a glyph for the Bell System logo that 'groff' does +not support. These macros implemented several document type formats +('EG', 'IM', 'MF', 'MR', 'TM', 'TR'), were meaningful only in +conjunction with the use of certain document types ('AT', 'CS', 'CT', +'OK', 'SG'), stored the postal addresses of Bell Labs sites ('HO', 'IH', +'MH', 'PY', 'WH'), or lacked a stable definition over time ('UX'). To +compatibly render historical 'ms' documents using these macros, we +advise your documents to invoke the 'rm' request to remove any such +macros it uses and then define replacements with an authentically +typeset original at hand.(1) (*note Missing Unix Version 7 ms +Macros-Footnote-1::) For informal purposes, a simple definition of 'UX' +should maintain the readability of the document's substance. + + .rm UX + .ds UX Unix\" + + +File: groff.info, Node: Missing Unix Version 7 ms Macros-Footnotes, Up: Missing Unix Version 7 ms Macros + + (1) The removal beforehand is necessary because 'groff' 'ms' aliases +these macros to a diagnostic macro, and you want to redefine the aliased +name, not its target. + + +File: groff.info, Node: ms Legacy Features, Next: ms Naming Conventions, Prev: Differences from AT&T ms, Up: ms + +4.6.8 Legacy Features +--------------------- + +'groff' 'ms' retains some legacy features solely to support formatting +of historical documents; contemporary ones should not use them because +they can render poorly. See the 'groff_char(7)' man page. + +AT&T accent mark strings +........................ + +AT&T 'ms' defined accent mark strings as follows. + + -- String: \*['] + Apply acute accent to subsequent glyph. + + -- String: \*[`] + Apply grave accent to subsequent glyph. + + -- String: \*[:] + Apply dieresis (umlaut) to subsequent glyph. + + -- String: \*[^] + Apply circumflex accent to subsequent glyph. + + -- String: \*[~] + Apply tilde accent to subsequent glyph. + + -- String: \*[C] + Apply caron to subsequent glyph. + + -- String: \*[,] + Apply cedilla to subsequent glyph. + +Berkeley accent mark and glyph strings +...................................... + +Berkeley 'ms' offered an 'AM' macro; calling it redefined the AT&T +accent mark strings (except for '\*C'), applied them to the _preceding_ +glyph, and defined additional strings, some for spacing glyphs. + + -- Macro: .AM + Enable alternative accent mark and glyph-producing strings. + + -- String: \*['] + Apply acute accent to preceding glyph. + + -- String: \*[`] + Apply grave accent to preceding glyph. + + -- String: \*[:] + Apply dieresis (umlaut) to preceding glyph. + + -- String: \*[^] + Apply circumflex accent to preceding glyph. + + -- String: \*[~] + Apply tilde accent to preceding glyph. + + -- String: \*[,] + Apply cedilla to preceding glyph. + + -- String: \*[/] + Apply stroke (slash) to preceding glyph. + + -- String: \*[v] + Apply caron to preceding glyph. + + -- String: \*[_] + Apply macron to preceding glyph. + + -- String: \*[.] + Apply underdot to preceding glyph. + + -- String: \*[o] + Apply ring accent to preceding glyph. + + -- String: \*[?] + Interpolate inverted question mark. + + -- String: \*[!] + Interpolate inverted exclamation mark. + + -- String: \*[8] + Interpolate small letter sharp s. + + -- String: \*[q] + Interpolate small letter o with hook accent (ogonek). + + -- String: \*[3] + Interpolate small letter yogh. + + -- String: \*[d-] + Interpolate small letter eth. + + -- String: \*[D-] + Interpolate capital letter eth. + + -- String: \*[th] + Interpolate small letter thorn. + + -- String: \*[Th] + Interpolate capital letter thorn. + + -- String: \*[ae] + Interpolate small ć ligature. + + -- String: \*[Ae] + Interpolate capital Ć ligature. + + -- String: \*[oe] + Interpolate small oe ligature. + + -- String: \*[OE] + Interpolate capital OE ligature. + + +File: groff.info, Node: ms Naming Conventions, Prev: ms Legacy Features, Up: ms + +4.6.9 Naming Conventions +------------------------ + +The following conventions are used for names of macros, strings, and +registers. External names available to documents that use the 'groff' +'ms' macros contain only uppercase letters and digits. + + Internally, the macros are divided into modules. Conventions for +identifier names are as follows. + + * Names used only within one module are of the form MODULE'*'NAME. + + * Names used outside the module in which they are defined are of the + form MODULE'@'NAME. + + * Names associated with a particular environment are of the form + ENVIRONMENT':'NAME; these are used only within the 'par' module. + + * NAME does not have a module prefix. + + * Constructed names used to implement arrays are of the form + ARRAY'!'INDEX. + + Thus the 'groff' 'ms' macros reserve the following names. + + * Names containing the characters '*', '@', and ':'. + + * Names containing only uppercase letters and digits. + + +File: groff.info, Node: GNU troff Reference, Next: File Formats, Prev: Major Macro Packages, Up: Top + +5 GNU 'troff' Reference +*********************** + +This chapter covers _all_ of the facilities of the GNU 'troff' +formatting engine. Users of macro packages may skip it if not +interested in details. + +* Menu: + +* Text:: +* Page Geometry:: +* Measurements:: +* Numeric Expressions:: +* Identifiers:: +* Formatter Instructions:: +* Comments:: +* Registers:: +* Manipulating Filling and Adjustment:: +* Manipulating Hyphenation:: +* Manipulating Spacing:: +* Tabs and Fields:: +* Character Translations:: +* troff and nroff Modes:: +* Line Layout:: +* Line Continuation:: +* Page Layout:: +* Page Control:: +* Using Fonts:: +* Manipulating Type Size and Vertical Spacing:: +* Colors:: +* Strings:: +* Conditionals and Loops:: +* Writing Macros:: +* Page Motions:: +* Drawing Geometric Objects:: +* Deferring Output:: +* Traps:: +* Diversions:: +* Punning Names:: +* Environments:: +* Suppressing Output:: +* I/O:: +* Postprocessor Access:: +* Miscellaneous:: +* Gtroff Internals:: +* Debugging:: +* Implementation Differences:: + + +File: groff.info, Node: Text, Next: Measurements, Prev: GNU troff Reference, Up: GNU troff Reference + +5.1 Text +======== + +AT&T 'troff' was designed to take input as it would be composed on a +typewriter, including the teletypewriters used as early computer +terminals, and relieve the user drafting a document of concern with +details like line length, hyphenation breaking, and the achievement of +straight margins. Early in its development, the program gained the +ability to prepare output for a phototypesetter; a document could then +be prepared for output to either a teletypewriter, a phototypesetter, or +both. GNU 'troff' continues this tradition of permitting an author to +compose a single master version of a document which can then be rendered +for a variety of output formats or devices. + + 'roff' input files contain text interspersed with instructions to +control the formatter. Even in the absence of such instructions, GNU +'troff' still processes its input in several ways, by filling, +hyphenating, breaking, and adjusting it, and supplementing it with +inter-sentence space. + +* Menu: + +* Filling:: +* Hyphenation:: +* Sentences:: +* Breaking:: +* Adjustment:: +* Tabs and Leaders:: +* Requests and Macros:: +* Macro Packages:: +* Input Encodings:: +* Input Conventions:: + + +File: groff.info, Node: Filling, Next: Sentences, Prev: Text, Up: Text + +5.1.1 Filling +------------- + +When GNU 'troff' starts up, it obtains information about the device for +which it is preparing output.(1) (*note Filling-Footnote-1::) An +essential property is the length of the output line, such as "6.5 +inches". + + GNU 'troff' interprets plain text files employing the Unix +line-ending convention. It reads input a character at a time, +collecting words as it goes, and fits as many words together on an +output line as it can--this is known as "filling". To GNU 'troff', a +"word" is any sequence of one or more characters that aren't spaces or +newlines. The exceptions separate words.(2) (*note +Filling-Footnote-2::) To disable filling, see *note Manipulating Filling +and Adjustment::. + + It is a truth universally acknowledged + that a single man in possession of a + good fortune must be in want of a wife. + => It is a truth universally acknowledged that a + => single man in possession of a good fortune must + => be in want of a wife. + + +File: groff.info, Node: Filling-Footnotes, Up: Filling + + (1) *Note Device and Font Description Files::. + + (2) Tabs and leaders also separate words. Escape sequences can +function as word characters, word separators, or neither--the last +simply have no effect on GNU 'troff''s idea of whether an input +character is within a word. We'll discuss all of these in due course. + + +File: groff.info, Node: Sentences, Next: Hyphenation, Prev: Filling, Up: Text + +5.1.2 Sentences +--------------- + +A passionate debate has raged for decades among writers of the English +language over whether more space should appear between adjacent +sentences than between words within a sentence, and if so, how much, and +what other circumstances should influence this spacing.(1) (*note +Sentences-Footnote-1::) GNU 'troff' follows the example of AT&T 'troff'; +it attempts to detect the boundaries between sentences, and supplies +additional inter-sentence space between them. + + Hello, world! + Welcome to groff. + => Hello, world! Welcome to groff. + + GNU 'troff' flags certain characters (normally '!', '?', and '.') as +potentially ending a sentence. When GNU 'troff' encounters one of these +"end-of-sentence characters" at the end of an input line, or one of them +is followed by two (unescaped) spaces on the same input line, it appends +an inter-word space followed by an inter-sentence space in the output. + + R. Harper subscribes to a maxim of P. T. Barnum. + => R. Harper subscribes to a maxim of P. T. Barnum. + + In the above example, inter-sentence space is not added after 'P.' or +'T.' because the periods do not occur at the end of an input line, nor +are they followed by two or more spaces. Let's imagine that we've heard +something about defamation from Mr. Harper's attorney, recast the +sentence, and reflowed it in our text editor. + + I submit that R. Harper subscribes to a maxim of P. T. + Barnum. + => I submit that R. Harper subscribes to a maxim of + => P. T. Barnum. + + "Barnum" doesn't begin a sentence! What to do? Let us meet our +first "escape sequence", a series of input characters that give +instructions to GNU 'troff' instead of being used to construct output +device glyphs.(2) (*note Sentences-Footnote-2::) An escape sequence +begins with the backslash character '\' by default, an uncommon +character in natural language text, and is _always_ followed by at least +one other character, hence the term "sequence". + + The dummy character escape sequence '\&' can be used after an +end-of-sentence character to defeat end-of-sentence detection on a +per-instance basis. We can therefore rewrite our input more +defensively. + + I submit that R.\& Harper subscribes to a maxim of P.\& + T.\& Barnum. + => I submit that R. Harper subscribes to a maxim of + => P. T. Barnum. + + Adding text caused our input to wrap; now, we don't need '\&' after +'T.' but we do after 'P.'. Consistent use of the escape sequence +ensures that potential sentence boundaries are robust to editing +activities. Further advice along these lines will follow in *note Input +Conventions::. + + Normally, the occurrence of a visible non-end-of-sentence character +(as opposed to a space or tab) immediately after an end-of-sentence +character cancels detection of the end of a sentence. For example, it +would be incorrect for GNU 'troff' to infer the end of a sentence after +the dot in '3.14159'. However, several characters are treated +_transparently_ after the occurrence of an end-of-sentence character. +That is, GNU 'troff' does not cancel end-of-sentence detection when it +processes them. This is because such characters are often used as +footnote markers or to close quotations and parentheticals. The default +set is '"', ''', ')', ']', '*', '\[dg]', '\[dd]', '\[rq]', and '\[cq]'. +The last four are examples of "special characters", escape sequences +whose purpose is to obtain glyphs that are not easily typed at the +keyboard, or which have special meaning to GNU 'troff' (like '\' +itself).(3) (*note Sentences-Footnote-3::) + + \[lq]The idea that the poor should have leisure has always + been shocking to the rich.\[rq] + (Bertrand Russell, 1935) + => "The idea that the poor should have + => leisure has always been shocking to + => the rich." (Bertrand Russell, 1935) + + The sets of characters that potentially end sentences or are +transparent to sentence endings are configurable. See the 'cflags' +request in *note Using Symbols::. To change the additional +inter-sentence space amount--even to remove it entirely--see *note +Manipulating Filling and Adjustment::. + + +File: groff.info, Node: Sentences-Footnotes, Up: Sentences + + (1) A well-researched jeremiad appreciated by 'groff' contributors on +both sides of the sentence-spacing debate can be found at +. + + (2) This statement oversimplifies; there are escape sequences whose +purpose is precisely to produce glyphs on the output device, and input +characters that _aren't_ part of escape sequences can undergo a great +deal of processing before getting to the output. + + (3) The mnemonics for the special characters shown here are "dagger", +"double dagger", "right (double) quote", and "closing (single) quote". +See the 'groff_char(7)' man page. + + +File: groff.info, Node: Hyphenation, Next: Breaking, Prev: Sentences, Up: Text + +5.1.3 Hyphenation +----------------- + +When an output line is nearly full, it is uncommon for the next word +collected from the input to exactly fill it--typically, there is room +left over only for part of the next word. The process of splitting a +word so that it appears partially on one line (with a hyphen to indicate +to the reader that the word has been broken) with its remainder on the +next is "hyphenation". Hyphenation points can be manually specified; +GNU 'troff' also uses a hyphenation algorithm and language-specific +pattern files (based on those used in TeX) to decide which words can be +hyphenated and where. + + Hyphenation does not always occur even when the hyphenation rules for +a word allow it; it can be disabled, and when not disabled there are +several parameters that can prevent it in certain circumstances. *Note +Manipulating Hyphenation::. + + +File: groff.info, Node: Breaking, Next: Adjustment, Prev: Hyphenation, Up: Text + +5.1.4 Breaking +-------------- + +Once an output line is full, the next word (or remainder of a hyphenated +one) is placed on a different output line; this is called a "break". In +this manual and in 'roff' discussions generally, a "break" if not +further qualified always refers to the termination of an output line. +When the formatter is filling text, it introduces breaks automatically +to keep output lines from exceeding the configured line length. After +an automatic break, GNU 'troff' adjusts the line if applicable (see +below), and then resumes collecting and filling text on the next output +line. + + Sometimes, a line cannot be broken automatically. This usually does +not happen with natural language text unless the output line length has +been manipulated to be extremely short, but it can with specialized text +like program source code. We can use 'perl' at the shell prompt to +contrive an example of failure to break the line. We also employ the +'-z' option to suppress normal output. + + $ perl -e 'print "#" x 80, "\n";' | nroff -z + error-> warning: cannot break line + + The remedy for these cases is to tell GNU 'troff' where the line may +be broken without hyphens. This is done with the non-printing break +point escape sequence '\:'; see *note Manipulating Hyphenation::. + + What if the document author wants to stop filling lines temporarily, +for instance to start a new paragraph? There are several solutions. A +blank input line not only causes a break, but by default it also outputs +a one-line vertical space (effectively a blank output line). This +behavior can be modified; see *note Blank Line Traps::. Macro packages +may discourage or disable the blank line method of paragraphing in favor +of their own macros. + + A line that begins with one or more spaces causes a break. The +spaces are output at the beginning of the next line without being +_adjusted_ (see below); however, this behavior can be modified (*note +Leading Space Traps::). Again, macro packages may provide other methods +of producing indented paragraphs. Trailing spaces on text lines are +discarded.(1) (*note Breaking-Footnote-1::) + + What if the file ends before enough words have been collected to fill +an output line? Or the output line is exactly full but not yet broken, +and there is no more input? GNU 'troff' interprets the end of input as +a break. Certain requests also cause breaks, implicitly or explicitly. +This is discussed in *note Manipulating Filling and Adjustment::. + + +File: groff.info, Node: Breaking-Footnotes, Up: Breaking + + (1) "Text lines" are defined in *note Requests and Macros::. + + +File: groff.info, Node: Adjustment, Next: Tabs and Leaders, Prev: Breaking, Up: Text + +5.1.5 Adjustment +---------------- + +After GNU 'troff' performs an automatic break, it may then "adjust" the +line, widening inter-word spaces until the text reaches the right +margin. Extra spaces between words are preserved. Leading and trailing +spaces are handled as noted above. Text can be aligned to the left or +right margin only, or centered; see *note Manipulating Filling and +Adjustment::. + + +File: groff.info, Node: Tabs and Leaders, Next: Input Conventions, Prev: Adjustment, Up: Text + +5.1.6 Tabs and Leaders +---------------------- + +GNU 'troff' translates input horizontal tab characters ("tabs") and + characters ("leaders") into movements to the next tab stop. +Tabs simply move to the next tab stop; leaders place enough periods to +fill the space. Tab stops are by default located every half inch +measured from the drawing position corresponding to the beginning of the +input line; see *note Page Geometry::. Tabs and leaders do not cause +breaks and therefore do not interrupt filling. Below, we use arrows -> +and bullets * to indicate input tabs and leaders, respectively. + + 1 + -> 2 -> 3 * 4 + -> * 5 + => 1 2 3.......4 ........5 + + Tabs and leaders lend themselves to table construction.(1) (*note +Tabs and Leaders-Footnote-1::) The tab and leader glyphs can be +configured, and further facilities for sophisticated table composition +are available; see *note Tabs and Fields::. There are many details to +track when using such low-level features, so most users turn to the +'tbl(1)' preprocessor to lay out tables. + + +File: groff.info, Node: Tabs and Leaders-Footnotes, Up: Tabs and Leaders + + (1) "Tab" is short for "tabulation", revealing the term's origin as a +spacing mechanism for table arrangement. + + +File: groff.info, Node: Requests and Macros, Next: Macro Packages, Prev: Tabs and Leaders, Up: Text + +5.1.7 Requests and Macros +------------------------- + +We have now encountered almost all of the syntax there is in the 'roff' +language, with an exception already noted in passing. A "request" is an +instruction to the formatter that occurs after a "control character", +which is recognized at the beginning of an input line. The regular +control character is a dot ('.'). Its counterpart, the "no-break +control character", a neutral apostrophe ('''), suppresses the break +that is implied by some requests. These characters were chosen because +it is uncommon for lines of text in natural languages to begin with +them. If you require a formatted period or apostrophe (closing single +quotation mark) where GNU 'troff' is expecting a control character, +prefix the dot or neutral apostrophe with the dummy character escape +sequence, '\&'. + + An input line beginning with a control character is called a "control +line". Every line of input that is not a control line is a "text +line".(1) (*note Requests and Macros-Footnote-1::) + + Requests often take "arguments", words (separated from the request +name and each other by spaces) that specify details of the action GNU +'troff' is expected to perform. If a request is meaningless without +arguments, it is typically ignored. + + GNU 'troff''s requests and escape sequences comprise the control +language of the formatter. Of key importance are the requests that +define macros. Macros are invoked like requests, enabling the request +repertoire to be extended or overridden.(2) (*note Requests and +Macros-Footnote-2::) + + A "macro" can be thought of as an abbreviation you can define for a +collection of control and text lines. When the macro is "called" by +giving its name after a control character, it is replaced with what it +stands for. The process of textual replacement is known as +"interpolation".(3) (*note Requests and Macros-Footnote-3::) +Interpolations are handled as soon as they are recognized, and once +performed, a 'roff' formatter scans the replacement for further +requests, macro calls, and escape sequences. + + In 'roff' systems, the 'de' request defines a macro.(4) (*note +Requests and Macros-Footnote-4::) + + .de DATE + 2020-11-14 + .. + +The foregoing input produces no output by itself; all we have done is +store some information. Observe the pair of dots that ends the macro +definition. This is a default; you can specify your own terminator for +the macro definition as the second argument to the 'de' request. + + .de NAME ENDNAME + Heywood Jabuzzoff + .ENDNAME + + In fact, the ending marker is itself the name of a macro to be +called, or a request to be invoked, if it is defined at the time its +control line is read. + + .de END + Big Rip + .. + .de START END + Big Bang + .END + .START + => Big Rip Big Bang + +In the foregoing example, "Big Rip" printed before "Big Bang" because +its macro was _called_ first. Consider what would happen if we dropped +'END' from the '.de START' line and added '..' after '.END'. Would the +order change? + + Let us consider a more elaborate example. + + .de DATE + 2020-10-05 + .. + . + .de BOSS + D.\& Kruger, + J.\& Peterman + .. + . + .de NOTICE + Approved: + .DATE + by + .BOSS + .. + . + Insert tedious regulatory compliance paragraph here. + + .NOTICE + + Insert tedious liability disclaimer paragraph here. + + .NOTICE + => Insert tedious regulatory compliance paragraph here. + => + => Approved: 2020-10-05 by D. Kruger, J. Peterman + => + => Insert tedious liability disclaimer paragraph here. + => + => Approved: 2020-10-05 by D. Kruger, J. Peterman + +The above document started with a series of control lines. Three macros +were defined, with a 'de' request declaring each macro's name, and the +"body" of the macro starting on the next line and continuing until a +line with two dots ''..'' marked its end. The text proper began only +after the macros were defined; this is a common pattern. Only the +'NOTICE' macro was called "directly" by the document; 'DATE' and 'BOSS' +were called only by 'NOTICE' itself. Escape sequences were used in +'BOSS', two levels of macro interpolation deep. + + The advantage in typing and maintenance economy may not be obvious +from such a short example, but imagine a much longer document with +dozens of such paragraphs, each requiring a notice of managerial +approval. Consider what must happen if you are in charge of generating +a new version of such a document with a different date, for a different +boss. With well-chosen macros, you only have to change each datum in +one place. + + In practice, we would probably use strings (*note Strings::) instead +of macros for such simple interpolations; what is important here is to +glimpse the potential of macros and the power of recursive +interpolation. + + We could have defined 'DATE' and 'BOSS' in the opposite order; +perhaps less obviously, we could also have defined them _after_ +'NOTICE'. "Forward references" like this are acceptable because the +body of a macro definition is not (completely) interpreted, but stored +instead (*note Copy Mode::). While a macro is being defined (or +appended to), requests are not interpreted and macros not interpolated, +whereas some commonly used escape sequences _are_ interpreted. 'roff' +systems also support recursive macro calls, as long as you have a way to +break the recursion (*note Conditionals and Loops::). Maintainable +'roff' documents tend to arrange macro definitions to minimize forward +references. + + +File: groff.info, Node: Requests and Macros-Footnotes, Up: Requests and Macros + + (1) The '\' escape sequence can alter how an input line is +classified; see *note Line Continuation::. + + (2) Argument handling in macros is more flexible but also more +complex. *Note Calling Macros::. + + (3) Some escape sequences undergo interpolation as well. + + (4) GNU 'troff' offers additional ones. *Note Writing Macros::. + + +File: groff.info, Node: Macro Packages, Next: Input Encodings, Prev: Requests and Macros, Up: Text + +5.1.8 Macro Packages +-------------------- + +Macro definitions can be collected into "macro files", 'roff' input +files designed to produce no output themselves but instead ease the +preparation of other 'roff' documents. There is no syntactical +difference between a macro file and any other 'roff' document; only its +purpose distinguishes it. When a macro file is installed at a standard +location and suitable for use by a general audience, it is often termed +a "macro package".(1) (*note Macro Packages-Footnote-1::) Macro +packages can be loaded by supplying the '-m' option to GNU 'troff' or a +'groff' front end. Alternatively, a document requiring a macro package +can load it with the 'mso' ("macro source") request. + + +File: groff.info, Node: Macro Packages-Footnotes, Up: Macro Packages + + (1) Macro files and packages frequently define registers and strings +as well. + + +File: groff.info, Node: Input Encodings, Next: Input Conventions, Prev: Macro Packages, Up: Text + +5.1.9 Input Encodings +--------------------- + +The 'groff' command's '-k' option calls the 'preconv' preprocessor to +perform input character encoding conversions. Input to the GNU 'troff' +formatter itself, on the other hand, must be in one of two encodings it +can recognize. + +'cp1047' + The code page 1047 input encoding works only on EBCDIC platforms + (and conversely, the other input encodings don't work with EBCDIC); + the file 'cp1047.tmac' is loaded at startup. + +'latin1' + ISO Latin-1, an encoding for Western European languages, is the + default input encoding on non-EBCDIC platforms; the file + 'latin1.tmac' is loaded at startup. + +Any document that is encoded in ISO 646:1991 (a descendant of USAS +X3.4-1968 or "US-ASCII"), or, equivalently, uses only code points from +the "C0 Controls" and "Basic Latin" parts of the Unicode character set +is also a valid ISO Latin-1 document; the standards are interchangeable +in their first 128 code points.(1) (*note Input Encodings-Footnote-1::) + + Other encodings are supported by means of macro packages. + +'latin2' + To use ISO Latin-2, an encoding for Central and Eastern European + languages, invoke '.mso latin2.tmac' at the beginning of your + document or supply '-mlatin2' as a command-line argument to + 'groff'. + +'latin5' + To use ISO Latin-5, an encoding for the Turkish language, invoke + '.mso latin5.tmac' at the beginning of your document or supply + '-mlatin5' as a command-line argument to 'groff'. + +'latin9' + ISO Latin-9 succeeds Latin-1; it includes a Euro sign and better + glyph coverage for French. To use this encoding, invoke + '.mso latin9.tmac' at the beginning of your document or supply + '-mlatin9' as a command-line argument to 'groff'. + + Some characters from an input encoding may not be available with a +particular output driver, or their glyphs may not have representation in +the font used. For terminal devices, fallbacks are defined, like 'EUR' +for the Euro sign and '(C)' for the copyright sign. For typesetter +devices, you may need to "mount" fonts that support glyphs required by +the document. *Note Font Positions::. + + Because a Euro glyph was not historically defined in PostScript +fonts, 'groff' comes with a font called 'freeeuro.pfa' that provides the +Euro in several styles. Standard PostScript fonts contain the glyphs +from Latin-5 and Latin-9 that Latin-1 lacks, so these encodings are +supported for the 'ps' and 'pdf' output devices as 'groff' ships, while +Latin-2 is not. + + Unicode supports characters from all other input encodings; the +'utf8' output driver for terminals therefore does as well. The DVI +output driver supports the Latin-2 and Latin-9 encodings if the +command-line option '-mec' is used as well. (2) (*note Input +Encodings-Footnote-2::) + + +File: groff.info, Node: Input Encodings-Footnotes, Up: Input Encodings + + (1) The _semantics_ of certain punctuation code points have gotten +stricter with the successive standards, a cause of some frustration +among man page writers; see the 'groff_char(7)' man page. + + (2) The DVI output device defaults to using the Computer Modern (CM) +fonts; 'ec.tmac' loads the EC fonts instead, which provide Euro '\[Eu]' +and per mille '\[%0]' glyphs. + + +File: groff.info, Node: Input Conventions, Prev: Input Encodings, Up: Text + +5.1.10 Input Conventions +------------------------ + +Since GNU 'troff' fills text automatically, it is common practice in the +'roff' language to avoid visual composition of text in input files: the +esthetic appeal of the formatted output is what matters. Therefore, +'roff' input should be arranged such that it is easy for authors and +maintainers to compose and develop the document, understand the syntax +of 'roff' requests, macro calls, and preprocessor languages used, and +predict the behavior of the formatter. Several traditions have accrued +in service of these goals. + + * Follow sentence endings in the input with newlines to ease their + recognition (*note Sentences::). It is frequently convenient to + end text lines after colons and semicolons as well, as these + typically precede independent clauses. Consider doing so after + commas; they often occur in lists that become easy to scan when + itemized by line, or constitute supplements to the sentence that + are added, deleted, or updated to clarify it. Parenthetical and + quoted phrases are also good candidates for placement on text lines + by themselves. + + * Set your text editor's line length to 72 characters or fewer.(1) + (*note Input Conventions-Footnote-1::) This limit, combined with + the previous item of advice, makes it less common that an input + line will wrap in your text editor, and thus will help you perceive + excessively long constructions in your text. Recall that natural + languages originate in speech, not writing, and that punctuation is + correlated with pauses for breathing and changes in prosody. + + * Use '\&' after '!', '?', and '.' if they are followed by space, + tab, or newline characters and don't end a sentence. + + * In filled text lines, use '\&' before '.' and ''' if they are + preceded by space, so that reflowing the input doesn't turn them + into control lines. + + * Do not use spaces to perform indentation or align columns of a + table. Leading spaces are reliable when text is not being filled. + + * Comment your document. It is never too soon to apply comments to + record information of use to future document maintainers (including + your future self). We thus introduce another escape sequence, + '\"', which causes GNU 'troff' to ignore the remainder of the input + line. + + * Use the empty request--a control character followed immediately by + a newline--to visually manage separation of material in input + files. Many of the 'groff' project's own documents use an empty + request between sentences, after macro definitions, and where a + break is expected, and two empty requests between paragraphs or + other requests or macro calls that will introduce vertical space + into the document. + + You can combine the empty request with the comment escape sequence + to include whole-line comments in your document, and even "comment + out" sections of it. + + We conclude this section with an example sufficiently long to +illustrate most of the above suggestions in practice. For the purpose +of fitting the example between the margins of this manual with the font +used for its typeset version, we have shortened the input line length to +56 columns. As before, an arrow -> indicates a tab character. + + .\" nroff this_file.roff | less + .\" groff -T ps this_file.roff > this_file.ps + ->The theory of relativity is intimately connected with + the theory of space and time. + . + I shall therefore begin with a brief investigation of + the origin of our ideas of space and time, + although in doing so I know that I introduce a + controversial subject. \" remainder of paragraph elided + . + . + + ->The experiences of an individual appear to us arranged + in a series of events; + in this series the single events which we remember + appear to be ordered according to the criterion of + \[lq]earlier\[rq] and \[lq]later\[rq], \" punct swapped + which cannot be analysed further. + . + There exists, + therefore, + for the individual, + an I-time, + or subjective time. + . + This itself is not measurable. + . + I can, + indeed, + associate numbers with the events, + in such a way that the greater number is associated with + the later event than with an earlier one; + but the nature of this association may be quite + arbitrary. + . + This association I can define by means of a clock by + comparing the order of events furnished by the clock + with the order of a given series of events. + . + We understand by a clock something which provides a + series of events which can be counted, + and which has other properties of which we shall speak + later. + .\" Albert Einstein, _The Meaning of Relativity_, 1922 + + +File: groff.info, Node: Input Conventions-Footnotes, Up: Input Conventions + + (1) Emacs: 'fill-column: 72'; Vim: 'textwidth=72' + + +File: groff.info, Node: Page Geometry, Next: Measurements, Prev: Text, Up: GNU troff Reference + +5.2 Page Geometry +================= + +'roff' systems format text under certain assumptions about the size of +the output medium, or page. For the formatter to correctly break a line +it is filling, it must know the line length, which it derives from the +page width (*note Line Layout::). For it to decide whether to write an +output line to the current page or wait until the next one, it must know +the page length (*note Page Layout::). + + A device's "resolution" converts practical units like inches or +centimeters to "basic units", a convenient length measure for the output +device or file format. The formatter and output driver use basic units +to reckon page measurements. The device description file defines its +resolution and page dimensions (*note DESC File Format::). + + A "page" is a two-dimensional structure upon which a 'roff' system +imposes a rectangular coordinate system with its upper left corner as +the origin. Coordinate values are in basic units and increase down and +to the right. Useful ones are therefore always positive and within +numeric ranges corresponding to the page boundaries. + + While the formatter (and, later, output driver) is processing a page, +it keeps track of its "drawing position", which is the location at which +the next glyph will be written, from which the next motion will be +measured, or where a geometric object will commence rendering. +Notionally, glyphs are drawn from the text baseline upward and to the +right.(1) (*note Page Geometry-Footnote-1::) The "text baseline" is a +(usually invisible) line upon which the glyphs of a typeface are +aligned. A glyph therefore "starts" at its bottom-left corner. If +drawn at the origin, a typical letter glyph would lie partially or +wholly off the page, depending on whether, like "g", it features a +descender below the baseline. + + Such a situation is nearly always undesirable. It is furthermore +conventional not to write or draw at the extreme edges of the page. +Therefore the initial drawing position of a 'roff' formatter is not at +the origin, but below and to the right of it. This rightward shift from +the left edge is known as the "page offset".(2) (*note Page +Geometry-Footnote-2::) The downward shift leaves room for a text output +line. + + Text is arranged on a one-dimensional lattice of text baselines from +the top to the bottom of the page. "Vertical spacing" is the distance +between adjacent text baselines. Typographic tradition sets this +quantity to 120% of the type size. The initial drawing position is one +unit of vertical spacing below the page top. Typographers term this +unit a vee. + + Vertical spacing has an impact on page-breaking decisions. +Generally, when a break occurs, the formatter moves the drawing position +to the next text baseline automatically. If the formatter were already +writing to the last line that would fit on the page, advancing by one +vee would place the next text baseline off the page. Rather than let +that happen, 'roff' formatters instruct the output driver to eject the +page, start a new one, and again set the drawing position to one vee +below the page top; this is a "page break". + + When the last line of input text corresponds to the last output line +that fits on the page, the break caused by the end of input will also +break the page, producing a useless blank one. Macro packages keep +users from having to confront this difficulty by setting "traps" (*note +Traps::); moreover, all but the simplest page layouts tend to have +headers and footers, or at least bear vertical margins larger than one +vee. + + +File: groff.info, Node: Page Geometry-Footnotes, Up: Page Geometry + + (1) 'groff' does not yet support right-to-left scripts. + + (2) 'groff''s terminal output devices have page offsets of zero. + + +File: groff.info, Node: Measurements, Next: Numeric Expressions, Prev: Text, Up: GNU troff Reference + +5.3 Measurements +================ + +The formatter sometimes requires the input of numeric parameters to +specify measurements. These are specified as integers or decimal +fractions with an optional "scaling unit" suffixed. A scaling unit is a +letter that immediately follows the last digit of a number. Digits +after the decimal point are optional. Measurement expressions include +'10.5p', '11i', and '3.c'. + + Measurements are scaled by the scaling unit and stored internally +(with any fractional part discarded) in basic units. The device +resolution can therefore be obtained by storing a value of '1i' to a +register. The only constraint on the basic unit is that it is at least +as small as any other unit. + +'u' + Basic unit. + +'i' + Inch; defined as 2.54 centimeters. + +'c' + Centimeter; a centimeter is about 0.3937 inches. + +'p' + Point; a typesetter's unit used for measuring type size. There are + 72 points to an inch. + +'P' + Pica; another typesetter's unit. There are 6 picas to an inch and + 12 points to a pica. + +'s' +'z' + *Note Using Fractional Type Sizes::, for a discussion of these + units. + +'f' + GNU 'troff' defines this unit to scale decimal fractions in the + interval [0, 1] to 16-bit unsigned integers. It multiplies a + quantity by 65,536. *Note Colors::, for usage. + + The magnitudes of other scaling units depend on the text formatting +parameters in effect. These are useful when specifying measurements +that need to scale with the typeface or vertical spacing. + +'m' + Em; an em is equal to the current type size in points. It is named + thus because it is approximately the width of the letter 'M'. + +'n' + En; an en is one-half em. + +'v' + Vee; recall *note Page Geometry::. + +'M' + Hundredth of an em. + +* Menu: + +* Motion Quanta:: +* Default Units:: + + +File: groff.info, Node: Motion Quanta, Next: Default Units, Prev: Measurements, Up: Measurements + +5.3.1 Motion Quanta +------------------- + +An output device's basic unit 'u' is not necessarily its smallest +addressable length; 'u' can be smaller to avoid problems with integer +roundoff. The minimum distances that a device can work with in the +horizontal and vertical directions are termed its "motion quanta". +Measurements are rounded to applicable motion quanta. Half-quantum +fractions round toward zero. + + -- Register: \n[.H] + -- Register: \n[.V] + These read-only registers interpolate the horizontal and vertical + motion quanta, respectively, of the output device in basic units. + + For example, we might draw short baseline rules on a terminal device +as follows. *Note Drawing Geometric Objects::. + + .tm \n[.H] + error-> 24 + .nf + \l'36u' 36u + \l'37u' 37u + => _ 36u + => __ 37u + + +File: groff.info, Node: Default Units, Prev: Motion Quanta, Up: Measurements + +5.3.2 Default Units +------------------- + +A general-purpose register (one created or updated with the 'nr' +request; see *note Registers::) is implicitly dimensionless, or reckoned +in basic units if interpreted in a measurement context. But it is +convenient for many requests and escape sequences to infer a scaling +unit for an argument if none is specified. An explicit scaling unit +(not after a closing parenthesis) can override an undesirable default. +Effectively, the default unit is suffixed to the expression if a scaling +unit is not already present. GNU 'troff''s use of integer arithmetic +should also be kept in mind (*note Numeric Expressions::). + + The 'll' request interprets its argument in ems by default. Consider +several attempts to set a line length of 3.5 inches when the type size +is 10 points on a terminal device with a resolution of 240 basic units +and horizontal motion quantum of 24. Some expressions become zero; the +request clamps them to that quantum. + + .ll 3.5i \" 3.5i (= 840u) + .ll 7/2 \" 7u/2u -> 3u -> 3m -> 0, clamped to 24u + .ll (7 / 2)u \" 7u/2u -> as above + .ll 7/2i \" 7u/2i -> 7u/480u -> 0 -> as above + .ll 7i/2 \" 7i/2u -> 1680u/2m -> 1680u/24u -> 35u + .ll 7i/2u \" 3.5i (= 840u) + +The safest way to specify measurements is to attach a scaling unit. To +multiply or divide by a dimensionless quantity, use 'u' as its scaling +unit. + + +File: groff.info, Node: Numeric Expressions, Next: Identifiers, Prev: Measurements, Up: GNU troff Reference + +5.4 Numeric Expressions +======================= + +A "numeric expression" evaluates to an integer: it can be as simple as a +literal '0' or it can be a complex sequence of register and string +interpolations interleaved with measurements and operators. + + GNU 'troff' provides a set of mathematical and logical operators +familiar to programmers--as well as some unusual ones--but supports only +integer arithmetic.(1) (*note Numeric Expressions-Footnote-1::) The +internal data type used for computing results is usually a 32-bit signed +integer, which suffices to represent magnitudes within a range of ą2 +billion.(2) (*note Numeric Expressions-Footnote-2::) + + Arithmetic infix operators perform a function on the numeric +expressions to their left and right; they are '+' (addition), '-' +(subtraction), '*' (multiplication), '/' (truncating division), and '%' +(modulus). "Truncating division" rounds to the integer nearer to zero, +no matter how large the fractional portion. Overflow and division (or +modulus) by zero are errors and abort evaluation of a numeric +expression. + + Arithmetic unary operators operate on the numeric expression to their +right; they are '-' (negation) and '+' (assertion--for completeness; it +does nothing). The unary minus must often be used with parentheses to +avoid confusion with the decrementation operator, discussed below. + + Observe the rounding behavior and effect of negative operands on the +modulus and truncating division operators. + + .nr T 199/100 + .nr U 5/2 + .nr V (-5)/2 + .nr W 5/-2 + .nr X 5%2 + .nr Y (-5)%2 + .nr Z 5%-2 + T=\n[T] U=\n[U] V=\n[V] W=\n[W] X=\n[X] Y=\n[Y] Z=\n[Z] + => T=1 U=2 V=-2 W=-2 X=1 Y=-1 Z=1 + +The sign of the modulus of operands of mixed signs is determined by the +sign of the first. Division and modulus operators satisfy the following +property: given a dividend A and a divisor B, a quotient Q formed by '(a +/ b)' and a remainder R by '(a % b)', then qb + r = a. + + GNU 'troff''s scaling operator, used with parentheses as '(C;E)', +evaluates a numeric expression E using C as the default scaling unit. +If C is omitted, scaling units are ignored in the evaluation of E. This +operator can save typing by avoiding the attachment of scaling units to +every operand out of caution. Your macros can select a sensible default +unit in case the user neglects to supply one. + + .\" Indent by amount given in first argument; assume ens. + .de Indent + . in (n;\\$1) + .. + +Without the scaling operator, the foregoing macro would, if called with +a unitless argument, cause indentation by the 'in' request's default +scaling unit (ems). The result would be twice as much indentation as +expected. + + GNU 'troff' also provides a pair of operators to compute the extrema +of two operands: '>?' (maximum) and ' Looks like we'll end up paying 3 salaries. + + Comparison operators comprise '<' (less than), '>' (greater than), +'<=' (less than or equal), '>=' (greater than or equal), and '=' +(equal). '==' is a synonym for '='. When evaluated, a comparison is +replaced with '0' if it is false and '1' if true. In the 'roff' +language, positive values are true, others false. + + We can operate on truth values with the logical operators '&' +(logical conjunction or "and") and ':' (logical disjunction or "or"). +They evaluate as comparison operators do. + + A logical complementation ("not") operator, '!', works only within +'if', 'ie', and 'while' requests. Furthermore, '!' is recognized only +at the beginning of a numeric expression not contained by another +numeric expression. In other words, it must be the "outermost" +operator. Including it elsewhere in the expression produces a warning +in the 'number' category (*note Warnings::), and its expression +evaluates false. This unfortunate limitation maintains compatibility +with AT&T 'troff'. Test a numeric expression for falsity by comparing +it to a false value.(3) (*note Numeric Expressions-Footnote-3::) + + .nr X 1 + .nr Y 0 + .\" This does not work as expected. + .if (\n[X])&(!\n[Y]) .nop A: X is true, Y is false + . + .\" Use this construct instead. + .if (\n[X])&(\n[Y]<=0) .nop B: X is true, Y is false + error-> warning: expected numeric expression, got '!' + => B: X is true, Y is false + + The 'roff' language has no operator precedence: expressions are +evaluated strictly from left to right, in contrast to schoolhouse +arithmetic. Use parentheses '(' ')' to impose a desired precedence upon +subexpressions. + + .nr X 3+5*4 + .nr Y (3+5)*4 + .nr Z 3+(5*4) + X=\n[X] Y=\n[Y] Z=\n[Z] + => X=32 Y=32 Z=23 + + For many requests and escape sequences that cause motion on the page, +the unary operators '+' and '-' work differently when leading a numeric +expression. They then indicate a motion relative to the drawing +position: positive is down in vertical contexts, right in horizontal +ones. + + '+' and '-' are also treated differently by the following requests +and escape sequences: 'bp', 'in', 'll', 'lt', 'nm', 'nr', 'pl', 'pn', +'po', 'ps', 'pvs', 'rt', 'ti', '\H', '\R', and '\s'. Here, leading plus +and minus signs serve as incrementation and decrementation operators, +respectively. To negate an expression, subtract it from zero or include +the unary minus in parentheses with its argument. *Note Setting +Registers::, for examples. + + A leading '|' operator indicates a motion relative not to the drawing +position but to a boundary. For horizontal motions, the measurement +specifies a distance relative to a drawing position corresponding to the +beginning of the _input_ line. By default, tab stops reckon movements +in this way. Most escape sequences do not; '|' tells them to do so. + + Mind the \h'1.2i'gap. + .br + Mind the \h'|1.2i'gap. + .br + Mind the + \h'|1.2i'gap. + => Mind the gap. + => Mind the gap. + => Mind the gap. + + One use of this feature is to define macros whose scope is limited to +the output they format. + + .\" underline word $1 with trailing punctuation $2 + .de Underline + . nop \\$1\l'|0\[ul]'\\$2 + .. + Typographical emphasis is best used + .Underline sparingly . + +In the above example, '|0' specifies a negative motion from the current +position (at the end of the argument just emitted, '\$1') to the +beginning of the input line. Thus, the '\l' escape sequence in this +case draws a line from right to left. A macro call occurs at the +beginning of an input line;(4) (*note Numeric Expressions-Footnote-4::) +if the '|' operator were omitted, then the underline would be drawn at +zero distance from the current position, producing device-dependent, and +likely undesirable, results. On the 'ps' output device, it underlines +the period. + + For vertical motions, the '|' operator specifies a distance from the +first text baseline on the page or in the current diversion,(5) (*note +Numeric Expressions-Footnote-5::) using the current vertical spacing. + + A + .br + B \Z'C'\v'|0'D + => A D + => B C + + In the foregoing example, we've used the '\Z' escape sequence (*note +Page Motions::) to restore the drawing position after formatting 'C', +then moved vertically to the first text baseline on the page. + + -- Escape sequence: \B'anything' + Interpolate 1 if ANYTHING is a valid numeric expression, and 0 + otherwise. The delimiter need not be a neutral apostrophe; see + *note Delimiters::. + + You might use '\B' along with the 'if' request to filter out invalid +macro or string arguments. *Note Conditionals and Loops::. + + .\" Indent by amount given in first argument; assume ens. + .de Indent + . if \B'\\$1' .in (n;\\$1) + .. + + A register interpolated as an operand in a numeric expression must +have an Arabic format; luckily, this is the default. *Note Assigning +Register Formats::. + + Because spaces separate arguments to requests, spaces are not allowed +in numeric expressions unless the (sub)expression containing them is +surrounded by parentheses. *Note Invoking Requests::, and *note +Conditionals and Loops::. + + .nf + .nr a 1+2 + 2+1 + \na + error-> expected numeric expression, got a space + => 3 + .nr a 1+(2 + 2)+1 + \na + => 6 + + The 'nr' request (*note Setting Registers::) expects its second and +optional third arguments to be numeric expressions; a bare '+' does not +qualify, so our first attempt got a warning. + + +File: groff.info, Node: Numeric Expressions-Footnotes, Up: Numeric Expressions + + (1) Provision is made for interpreting and reporting decimal +fractions in certain cases. + + (2) If that's not enough, see the 'groff_tmac(5)' man page for the +'62bit.tmac' macro package. + + (3) *Note Conditionals and Loops::. + + (4) Control structure syntax creates an exception to this rule, but +is designed to remain useful: recalling our example, '.if 1 .Underline +this' would underline only "this", precisely. *Note Conditionals and +Loops::. + + (5) *Note Diversions::. + + +File: groff.info, Node: Identifiers, Next: Formatter Instructions, Prev: Numeric Expressions, Up: GNU troff Reference + +5.5 Identifiers +=============== + +An "identifier" labels a GNU 'troff' datum such as a register, name +(macro, string, or diversion), typeface, color, special character, +character class, environment, or stream. Valid identifiers consist of +one or more ordinary characters. An ordinary character is an input +character that is not the escape character, a leader, tab, newline, or +invalid as GNU 'troff' input. + + Invalid input characters are a subset of control characters (from the +sets "C0 Controls" and "C1 Controls" as Unicode describes them). When +GNU 'troff' encounters one in an identifier, it produces a warning in +category 'input' (*note Warnings::). They are removed during +interpretation: an identifier 'foo', followed by an invalid character +and then 'bar', is processed as 'foobar'. + + On a machine using the ISO 646, 8859, or 10646 character encodings, +invalid input characters are '0x00', '0x08', '0x0B', '0x0D'-'0x1F', and +'0x80'-'0x9F'. On an EBCDIC host, they are '0x00'-'0x01', '0x08', +'0x09', '0x0B', '0x0D'-'0x14', '0x17'-'0x1F', and '0x30'-'0x3F'.(1) +(*note Identifiers-Footnote-1::) Some of these code points are used by +GNU 'troff' internally, making it non-trivial to extend the program to +accept UTF-8 or other encodings that use characters from these +ranges.(2) (*note Identifiers-Footnote-2::) + + Thus, the identifiers 'br', 'PP', 'end-list', 'ref*normal-print', +'|', '@_', and '!"#$%'()*+,-./' are all valid. Discretion should be +exercised to prevent confusion. Identifiers starting with '(' or '[' +require care. + + .nr x 9 + .nr y 1 + .nr (x 2 + .nr [y 3 + .nr sum1 (\n(x + \n[y]) + error-> a space character is not allowed in an escape + error-> sequence parameter + A:2+3=\n[sum1] + .nr sum2 (\n((x + \n[[y]) + B:2+3=\n[sum2] + .nr sum3 (\n[(x] + \n([y) + C:2+3=\n[sum3] + => A:2+3=1 B:2+3=5 C:2+3=5 + +An identifier with a closing bracket (']') in its name can't be accessed +with bracket-form escape sequences that expect an identifier as a +parameter. For example, '\[foo]]' accesses the glyph 'foo', followed by +']' in whatever the surrounding context is, whereas '\C'foo]'' formats a +glyph named 'foo]'. Similarly, the identifier '(' can't be interpolated +_except_ with bracket forms. + + If you begin a macro, string, or diversion name with either of the +characters '[' or ']', you foreclose use of the 'grefer' preprocessor, +which recognizes '.[' and '.]' as bibliographic reference delimiters. + + -- Escape sequence: \A'anything' + Interpolate 1 if ANYTHING is a valid identifier, and 0 otherwise. + The delimiter need not be a neutral apostrophe; see *note + Delimiters::. Because invalid input characters are removed (see + above), invalid identifiers are empty or contain spaces, tabs, or + newlines. + + You can employ '\A' to validate a macro argument before using it to + construct another escape sequence or identifier. + + .\" usage: .init-coordinate-pair name val1 val2 + .\" Create a coordinate pair where name!x=val1 and + .\" name!y=val2. + .de init-coordinate-pair + . if \A'\\$1' \{\ + . if \B'\\$2' .nr \\$1!x \\$2 + . if \B'\\$3' .nr \\$1!y \\$3 + . \} + .. + .init-coordinate-pair center 5 10 + The center is at (\n[center!x], \n[center!y]). + .init-coordinate-pair "poi->nt" trash garbage \" ignored + .init-coordinate-pair point trash garbage \" ignored + => The center is at (5, 10). + + In this example, we also validated the numeric arguments; the + registers 'point!x' and 'point!y' remain undefined. *Note Numeric + Expressions:: for the '\B' escape sequence. + + How GNU 'troff' handles the interpretation of an undefined identifier +depends on the context. There is no way to invoke an undefined request; +such syntax is interpreted as a macro call instead. If the identifier +is interpreted as a string, macro, or diversion, GNU 'troff' emits a +warning in category 'mac', defines it as empty, and interpolates +nothing. If the identifier is interpreted as a register, GNU 'troff' +emits a warning in category 'reg', initializes it to zero, and +interpolates that value. *Note Warnings::, *note Interpolating +Registers::, and *note Strings::. Attempting to use an undefined +typeface, special character, color, character class, environment, or +stream generally provokes an error diagnostic. + + Identifiers for requests, macros, strings, and diversions share one +name space; special characters and character classes another. No other +object types do. + + .de xxx + . nop foo + .. + .di xxx + bar + .br + .di + . + .xxx + => bar + +The foregoing example shows that GNU 'troff' reuses the identifier +'xxx', changing it from a macro to a diversion. No warning is emitted, +and the previous contents of 'xxx' are lost. + + +File: groff.info, Node: Identifiers-Footnotes, Up: Identifiers + + (1) Historically, control characters like ASCII STX, ETX, and BEL +(, , and ) have been observed in 'roff' +documents, particularly in macro packages employing them as delimiters +with the output comparison operator to try to avoid collisions with the +content of arbitrary user-supplied parameters (*note Operators in +Conditionals::). We discourage this expedient; in GNU 'troff' it is +unnecessary (outside of compatibility mode) because delimited arguments +are parsed at a different input level than the surrounding context. +*Note Implementation Differences::. + + (2) Consider what happens when a C1 control '0x80'-'0x9F' is +necessary as a continuation byte in a UTF-8 sequence. + + +File: groff.info, Node: Formatter Instructions, Next: Registers, Prev: Identifiers, Up: GNU troff Reference + +5.6 Formatter Instructions +========================== + +To support documents that require more than filling, automatic line +breaking and hyphenation, adjustment, and supplemental inter-sentence +space, the 'roff' language offers two means of embedding instructions to +the formatter. + + One is a "request", which begins with a control character and takes +up the remainder of the input line. Requests often perform relatively +large-scale operations such as setting the page length, breaking the +line, or starting a new page. They also conduct internal operations +like defining macros. + + The other is an "escape sequence", which begins with the escape +character and can be embedded anywhere in the input, even in arguments +to requests and other escape sequences. Escape sequences interpolate +special characters, strings, or registers, and handle comparatively +minor formatting tasks like sub- and superscripting. + + Some operations, such as font selection and type size alteration, are +available via both requests and escape sequences. + +* Menu: + +* Control Characters:: +* Invoking Requests:: +* Calling Macros:: +* Using Escape Sequences:: +* Delimiters:: + + +File: groff.info, Node: Control Characters, Next: Invoking Requests, Prev: Formatter Instructions, Up: Formatter Instructions + +5.6.1 Control Characters +------------------------ + +The mechanism of using 'roff''s control characters to invoke requests +and call macros was introduced in *note Requests and Macros::. Control +characters are recognized only at the beginning of an input line, or at +the beginning of the branch of a control structure request; see *note +Conditionals and Loops::. + + A few requests cause a break implicitly; use the no-break control +character to prevent the break. Break suppression is its sole +behavioral distinction. Employing the no-break control character to +invoke requests that don't cause breaks is harmless but poor style. +*Note Manipulating Filling and Adjustment::. + + The control '.' and no-break control ''' characters can each be +changed to any ordinary character(1) (*note Control +Characters-Footnote-1::) with the 'cc' and 'c2' requests, respectively. + + -- Request: .cc [o] + Recognize the ordinary character O as the control character. If O + is absent or invalid, the default control character '.' is + selected. The identity of the control character is associated with + the environment (*note Environments::). + + -- Request: .c2 [o] + Recognize the ordinary character O as the no-break control + character. If O is absent or invalid, the default no-break control + character ''' is selected. The identity of the no-break control + character is associated with the environment (*note + Environments::). + + When writing a macro, you might wish to know which control character +was used to call it. + + -- Register: \n[.br] + This read-only register interpolates 1 if the currently executing + macro was called using the normal control character and 0 + otherwise. If a macro is interpolated as a string, the '.br' + register's value is inherited from the context of the string + interpolation. *Note Strings::. + + Use this register to reliably intercept requests that imply breaks. + + .als bp*orig bp + .de bp + . ie \\n[.br] .bp*orig + . el 'bp*orig + .. + + Testing the '.br' register outside of a macro definition makes no + sense. + + +File: groff.info, Node: Control Characters-Footnotes, Up: Control Characters + + (1) Recall *note Identifiers::. + + +File: groff.info, Node: Invoking Requests, Next: Calling Macros, Prev: Control Characters, Up: Formatter Instructions + +5.6.2 Invoking Requests +----------------------- + +A control character is optionally followed by tabs and/or spaces and +then an identifier naming a request or macro. The invocation of an +unrecognized request is interpreted as a macro call. Defining a macro +with the same name as a request replaces the request. Deleting a +request name with the 'rm' request makes it unavailable. The 'als' +request can alias requests, permitting them to be wrapped or +non-destructively replaced. *Note Strings::. + + There is no inherent limit on argument length or quantity. Most +requests take one or more arguments, and ignore any they do not expect. +A request may be separated from its arguments by tabs or spaces, but +only spaces can separate an argument from its successor. Only one +between arguments is necessary; any excess is ignored. GNU 'troff' does +not allow tabs for argument separation.(1) (*note Invoking +Requests-Footnote-1::) + + Generally, a space _within_ a request argument is not relevant, not +meaningful, or is supported by bespoke provisions, as with the 'tl' +request's delimiters (*note Page Layout::). Some requests, like 'ds', +interpret the remainder of the control line as a single argument. *Note +Strings::. + + Spaces and tabs immediately after a control character are ignored. +Commonly, authors structure the source of documents or macro files with +them. + + .de center + . if \\n[.br] \ + . br + . ce \\$1 + .. + . + . + .de right-align + .->if \\n[.br] \ + .->->br + .->rj \\$1 + .. + + If you assign an empty blank line trap, you can separate macro +definitions (or any input lines) with blank lines. + + .de do-nothing + .. + .blm do-nothing \" activate blank line trap + + .de center + . if \\n[.br] \ + . br + . ce \\$1 + .. + + + .de right-align + .->if \\n[.br] \ + .->->br + .->rj \\$1 + .. + + .blm \" deactivate blank line trap + + *Note Blank Line Traps::. + + +File: groff.info, Node: Invoking Requests-Footnotes, Up: Invoking Requests + + (1) In compatibility mode, a space is not necessary after a request +or macro name of two characters' length. Also, Plan 9 'troff' allows +tabs to separate arguments. + + +File: groff.info, Node: Calling Macros, Next: Using Escape Sequences, Prev: Invoking Requests, Up: Formatter Instructions + +5.6.3 Calling Macros +-------------------- + +If a macro of the desired name does not exist when called, it is +created, assigned an empty definition, and a warning in category 'mac' +is emitted. Calling an undefined macro _does_ end a macro definition +naming it as its end macro (*note Writing Macros::). + + To embed spaces _within_ a macro argument, enclose the argument in +neutral double quotes '"'. Horizontal motion escape sequences are +sometimes a better choice for arguments to be formatted as text. + + Consider calls to a hypothetical section heading macro 'uh'. + + .uh The Mouse Problem + .uh "The Mouse Problem" + .uh The\~Mouse\~Problem + .uh The\ Mouse\ Problem + +The first line calls 'uh' with three arguments: 'The', 'Mouse', and +'Problem'. The remainder call the 'uh' macro with one argument, 'The +Mouse Problem'. The last solution, using escaped spaces, can be found +in documents prepared for AT&T 'troff'. It can cause surprise when text +is adjusted, because '\' inserts a _fixed-width_, non-breaking +space. GNU 'troff''s '\~' escape sequence inserts an adjustable, +non-breaking space.(1) (*note Calling Macros-Footnote-1::) + + The foregoing raises the question of how to embed neutral double +quotes or backslashes in macro arguments when _those_ characters are +desired as literals. In GNU 'troff', the special character escape +sequence '\[rs]' produces a backslash and '\[dq]' a neutral double +quote. + + In GNU 'troff''s AT&T compatibility mode, these characters remain +available as '\(rs' and '\(dq', respectively. AT&T 'troff' did not +consistently define these special characters, but its descendants can be +made to support them. *Note Device and Font Description Files::. + + If even that is not feasible, options remain. To obtain a literal +escape character in a macro argument, you can simply type it if you +change or disable the escape character first. *Note Using Escape +Sequences::. Otherwise, you must escape the escape character repeatedly +to a context-dependent extent. *Note Copy Mode::. + + For the (neutral) double quote, you have recourse to an obscure +syntactical feature of AT&T 'troff'. Because a double quote can begin a +macro argument, the formatter keeps track of whether the current +argument was started thus, and doesn't require a space after the double +quote that ends it.(2) (*note Calling Macros-Footnote-2::) In the +argument list to a macro, a double quote that _isn't_ preceded by a +space _doesn't_ start a macro argument. If not preceded by a double +quote that began an argument, this double quote becomes part of the +argument. Furthermore, within a quoted argument, a pair of adjacent +double quotes becomes a literal double quote. + + .de eq + . tm arg1:\\$1 arg2:\\$2 arg3:\\$3 + . tm arg4:\\$4 arg5:\\$5 arg6:\\$6 + .. \" 4 backslashes on the next line + .eq a" "b c" "de"f\\\\g" h""i "j""k" + error-> arg1:a" arg2:b c arg3:de + error-> arg4:f\g" arg5:h""i arg6:j"k + + Apart from the complexity of the rules, this traditional solution has +the disadvantage that double quotes don't survive repeated argument +expansion in AT&T 'troff' or GNU 'troff''s compatibility mode. This can +frustrate efforts to pass such arguments intact through multiple macro +calls. + + .cp 1 + .de eq + . tm arg1:\\$1 arg2:\\$2 arg3:\\$3 + . tm arg4:\\$4 arg5:\\$5 arg6:\\$6 + .. + .de xe + . eq \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 + .. \" 8 backslashes on the next line + .xe a" "b c" "de"f\\\\\\\\g" h""i "j""k" + error-> arg1:a" arg2:b arg3:c + error-> arg4:de arg5:f\g" arg6:h""i + + Outside of compatibility mode, GNU 'troff' doesn't exhibit this +problem because it tracks the nesting depth of interpolations. *Note +Implementation Differences::. + + +File: groff.info, Node: Calling Macros-Footnotes, Up: Calling Macros + + (1) '\~' is fairly portable; see *note Other Differences::. + + (2) Strictly, you can neglect to close the last quoted macro +argument, relying on the end of the control line to do so. We consider +this lethargic practice poor style. + + +File: groff.info, Node: Using Escape Sequences, Next: Delimiters, Prev: Calling Macros, Up: Formatter Instructions + +5.6.4 Using Escape Sequences +---------------------------- + +Whereas requests must occur on control lines, escape sequences can occur +intermixed with text and may appear in arguments to requests, macros, +and other escape sequences. An escape sequence is introduced by the +escape character, a backslash '\' (but see the 'ec' request below). The +next character selects the escape's function. + + Escape sequences vary in length. Some take an argument, and of +those, some have different syntactical forms for a one-character, +two-character, or arbitrary-length argument. Others accept _only_ an +arbitrary-length argument. In the former scheme, a one-character +argument follows the function character immediately, an opening +parenthesis '(' introduces a two-character argument (no closing +parenthesis is used), and an argument of arbitrary length is enclosed in +brackets '[]'. In the latter scheme, the user selects a delimiter +character. A few escape sequences are idiosyncratic, and support both +of the foregoing conventions ('\s'), designate their own termination +sequence ('\?'), consume input until the next newline ('\!', '\"', +'\#'), or support an additional modifier character ('\s' again, and +'\n'). As with requests, use of some escape sequences in source +documents may interact poorly with a macro package you use; consult its +documentation to learn of "safe" sequences or alternative facilities it +provides to achieve the desired result. + + If an escape character is followed by a character that does not +identify a defined operation, the escape character is ignored (producing +a diagnostic of the 'escape' warning category, which is not enabled by +default) and the following character is processed normally. + + $ groff -Tps -ww + .nr N 12 + .ds co white + .ds animal elephant + I have \fI\nN \*(co \*[animal]s,\f[] + said \P.\&\~Pseudo Pachyderm. + error-> warning: escape character ignored before 'P' + => I have 12 white elephants, said P. Pseudo Pachyderm. + + Escape sequence interpolation is of higher precedence than escape +sequence argument interpretation. This rule affords flexibility in +using escape sequences to construct parameters to other escape +sequences. + + .ds family C\" Courier + .ds style I\" oblique + Choice a typeface \f(\*[family]\*[style]wisely. + => Choose a typeface wisely. + +In the above, the syntax form '\f(' accepts only two characters for an +argument; the example works because the subsequent escape sequences are +interpolated before the selection escape sequence argument is processed, +and strings 'family' and 'style' interpolate one character each.(1) +(*note Using Escape Sequences-Footnote-1::) + + The escape character is nearly always interpreted when encountered; +it is therefore desirable to have a way to interpolate it, disable it, +or change it. + + -- Escape sequence: \e + Interpolate the escape character. + + The '\[rs]' special character escape sequence formats a backslash +glyph. In macro and string definitions, the input sequences '\\' and +'\E' defer interpretation of escape sequences. *Note Copy Mode::. + + -- Request: .eo + Disable the escape mechanism except in copy mode. Once this + request is invoked, no input character is recognized as starting an + escape sequence in interpretation mode. + + -- Request: .ec [o] + Recognize the ordinary character O as the escape character. If O + is absent or invalid, the default escape character '\' is selected. + + Switching escape sequence interpretation off to define a macro and +back on afterward can obviate the need to double the escape character +within the definition. *Note Writing Macros::. This technique is not +available if your macro needs to interpolate values at the time it is +_defined_--but many do not. + + .\" simplified `BR` macro from the man(7) macro package + .eo + .de BR + . ds result \& + . while (\n[.$] >= 2) \{\ + . as result \fB\$1\fR\$2\" + . shift 2 + . \} + . if \n[.$] .as result \fB\$1\" + \*[result] + . rm result + . ft R + .. + .ec + + -- Request: .ecs + -- Request: .ecr + The 'ecs' request stores the escape character for recall with + 'ecr'. 'ecr' sets the escape character to '\' if none has been + saved. + + Use these requests together to temporarily change the escape + character. + + Using a different escape character, or disabling it, when calling +macros not under your control will likely cause errors, since GNU +'troff' has no mechanism to "intern" macros--that is, to convert a macro +definition into a form independent of its representation.(2) (*note +Using Escape Sequences-Footnote-2::) When a macro is called, its +contents are interpreted literally. + + +File: groff.info, Node: Using Escape Sequences-Footnotes, Up: Using Escape Sequences + + (1) The omission of spaces before the comment escape sequences is +necessary; see *note Strings::. + + (2) TeX does have such a mechanism. + + +File: groff.info, Node: Delimiters, Prev: Using Escape Sequences, Up: Formatter Instructions + +5.6.5 Delimiters +---------------- + +Some escape sequences that require parameters use delimiters. The +neutral apostrophe ''' is a popular choice and shown in this document. +The neutral double quote '"' is also commonly seen. Letters, numerals, +and leaders can be used. Punctuation characters are likely better +choices, except for those defined as infix operators in numeric +expressions; see below. + + \l'1.5i\[bu]' \" draw 1.5 inches of bullet glyphs + + The following escape sequences don't take arguments and thus are +allowed as delimiters: '\', '\%', '\|', '\^', '\{', '\}', '\'', +'\`', '\-', '\_', '\!', '\?', '\)', '\/', '\,', '\&', '\:', '\~', '\0', +'\a', '\c', '\d', '\e', '\E', '\p', '\r', '\t', and '\u'. However, +using them this way is discouraged; they can make the input confusing to +read. + + A few escape sequences, '\A', '\b', '\o', '\w', '\X', and '\Z', +accept a newline as a delimiter. Newlines that serve as delimiters +continue to be recognized as input line terminators. + + A caf\o + e\(aa + in Paris + => A café in Paris + +Use of newlines as delimiters in escape sequences is also discouraged. + + Finally, the escape sequences '\D', '\h', '\H', '\l', '\L', '\N', +'\R', '\s', '\S', '\v', and '\x' prohibit many delimiters. + + * the numerals '0'-'9' and the decimal point '.' + + * the (single-character) operators '+-/*%<>=&:()' + + * the space and tab characters + + * any escape sequences other than '\%', '\:', '\{', '\}', '\'', '\`', + '\-', '\_', '\!', '\/', '\c', '\e', and '\p' + + Delimiter syntax is complex and flexible primarily for historical +reasons; the foregoing restrictions need be kept in mind mainly when +using 'groff' in AT&T compatibility mode. GNU 'troff' keeps track of +the nesting depth of escape sequence interpolations, so the only +characters you need to avoid using as delimiters are those that appear +in the arguments you input, not any that result from interpolation. +Typically, ''' works fine. *Note Implementation Differences::. + + $ groff -Tps + .de Mw + . nr wd \w'\\$1' + . tm "\\$1" is \\n(wd units wide. + .. + .Mw Wet'suwet'en + .Mw Wet+200i + .cp 1 \" turn on compatibility mode + .Mw Wet'suwet'en + .Mw Wet' + .Mw Wet+200i + error-> "Wet'suwet'en" is 54740 units wide. + error-> "Wet'+200i" is 42610 units wide. + error-> "Wet'suwet'en" is 15860 units wide. + error-> "Wet'" is 15860 units wide. + error-> "Wet'+200i" is 14415860 units wide. + + We see here that in compatibility mode, the part of the argument +after the ''' delimiter escapes from its context and, if nefariously +crafted, influences the computation of the WD register's value in a +surprising way. + + +File: groff.info, Node: Comments, Next: Registers, Prev: Formatter Instructions, Up: GNU troff Reference + +5.7 Comments +============ + +One of the most common forms of escape sequence is the comment.(1) +(*note Comments-Footnote-1::) + + -- Escape sequence: \" + Start a comment. Everything up to the next newline is ignored. + + This may sound simple, but it can be tricky to keep the comments + from interfering with the appearance of the output. If the escape + sequence is to the right of some text or a request, that portion of + the line is ignored, but spaces preceding it are processed normally + by GNU 'troff'. This affects only the 'ds' and 'as' requests and + their variants. + + One possibly irritating idiosyncrasy is that tabs should not be + used to vertically align comments in the source document. Tab + characters are not treated as separators between a request name and + its first argument, nor between arguments. + + A comment on a line by itself is treated as a blank line, because + after eliminating the comment, that is all that remains. + + Test + \" comment + Test + => Test + => + => Test + + To avoid this, it is common to combine the empty request with the + comment escape sequence as '.\"', causing the input line to be + ignored. + + Another commenting scheme sometimes seen is three consecutive + single quotes (''''') at the beginning of a line. This works, but + GNU 'troff' emits a warning diagnostic (if enabled) about an + undefined macro (namely ''''). + + -- Escape sequence: \# + Start a comment; everything up to and including the next newline is + ignored. This 'groff' extension was introduced to avoid the + problems described above. + + Test + \# comment + Test + => Test Test + + -- Request: .ig [end] + Ignore input until, in the current conditional block (if any),(2) + (*note Comments-Footnote-2::) the macro END is called at the start + of a control line, or the control line '..' is encountered if END + is not specified. 'ig' is parsed as if it were a macro definition, + but its contents are discarded, not stored.(3) (*note + Comments-Footnote-3::) + + hand\c + .de TX + fasting + .. + .ig TX + This is part of a large block of input that has been + temporarily(?) commented out. + We can restore it simply by removing the .ig request and + the call of its end macro. + .TX + => handfasting + + +File: groff.info, Node: Comments-Footnotes, Up: Comments + + (1) This claim may be more aspirational than descriptive. + + (2) *Note Conditional Blocks::. + + (3) Exception: auto-incrementing registers defined outside the +ignored region _will_ be modified if interpolated with '\ną' inside it. +*Note Auto-increment::. + + +File: groff.info, Node: Registers, Next: Manipulating Filling and Adjustment, Prev: Formatter Instructions, Up: GNU troff Reference + +5.8 Registers +============= + +In the 'roff' language, numbers can be stored in "registers". Many +built-in registers exist, supplying anything from the date to details of +formatting parameters. You can also define your own. *Note +Identifiers::, for information on constructing a valid name for a +register. + +* Menu: + +* Setting Registers:: +* Interpolating Registers:: +* Auto-increment:: +* Assigning Register Formats:: +* Built-in Registers:: + + +File: groff.info, Node: Setting Registers, Next: Interpolating Registers, Prev: Registers, Up: Registers + +5.8.1 Setting Registers +----------------------- + +Define registers and update their values with the 'nr' request or the +'\R' escape sequence. + + -- Request: .nr ident value + -- Escape sequence: \R'ident value' + Set register IDENT to VALUE. If IDENT doesn't exist, GNU 'troff' + creates it. In the '\R' escape sequence, the delimiter need not be + a neutral apostrophe; see *note Delimiters::. It also does not + produce an input token in GNU 'troff'. *Note Gtroff Internals::. + + .nr a (((17 + (3 * 4))) % 4) + \n[a] + .\R'a (((17 + (3 * 4))) % 4)' + \n[a] + => 1 1 + + (Later, we will discuss additional forms of 'nr' and '\R' that can + change a register's value after it is dereferenced but before it is + interpolated. *Note Auto-increment::.) + + The complete transparency of '\R' can cause surprising effects if + you use registers like '.k', which get evaluated at the time they + are accessed. + + .ll 1.6i + . + aaa bbb ccc ddd eee fff ggg hhh\R':k \n[.k]' + .tm :k == \n[:k] + => :k == 126950 + . + .br + . + aaa bbb ccc ddd eee fff ggg hhh\h'0'\R':k \n[.k]' + .tm :k == \n[:k] + => :k == 15000 + + If you process this with the PostScript device ('-Tps'), there will + be a line break eventually after 'ggg' in both input lines. + However, after processing the space after 'ggg', the partially + collected line is not overfull yet, so GNU 'troff' continues to + collect input until it sees the space (or in this case, the + newline) after 'hhh'. At this point, the line is longer than the + line length, and the line gets broken. + + In the first input line, since the '\R' escape sequence leaves no + traces, the check for the overfull line hasn't been done yet at the + point where '\R' gets handled, and you get a value for the '.k' + register that is even greater than the current line length. + + In the second input line, the insertion of '\h'0'' to cause a + zero-width motion forces GNU 'troff' to check the line length, + which in turn causes the start of a new output line. Now '.k' + returns the expected value. + + 'nr' and '\R' each have two additional special forms to increment or +decrement a register. + + -- Request: .nr ident +value + -- Request: .nr ident -value + -- Escape sequence: \R'ident +value' + -- Escape sequence: \R'ident -value' + Increment (decrement) register IDENT by VALUE. In the '\R' escape + sequence, the delimiter need not be a neutral apostrophe; see *note + Delimiters::. + + .nr a 1 + .nr a +1 + \na + => 2 + + A leading minus sign in VALUE is always interpreted as a + decrementation operator, not an algebraic sign. To assign a + register a negative value or the negated value of another register, + you can force GNU 'troff' to interpret '-' as a negation or minus, + rather than decrementation, operator: enclose it with its operand + in parentheses or subtract it from zero. + + .nr a 7 + .nr b 3 + .nr a -\nb + \na + => 4 + .nr a (-\nb) + \na + => -3 + .nr a 0-\nb + \na + => -3 + + If a register's prior value does not exist (the register was + undefined), an increment or decrement is applied as if to 0. + + -- Request: .rr ident + Remove register IDENT. If IDENT doesn't exist, the request is + ignored. Technically, only the name is removed; the register's + contents are still accessible under aliases created with 'aln', if + any. + + -- Request: .rnn ident1 ident2 + Rename register IDENT1 to IDENT2. If IDENT1 doesn't exist, the + request is ignored. Renaming a built-in register does not + otherwise alter its properties. + + -- Request: .aln new old + Create an alias NEW for an existing register OLD, causing the names + to refer to the same stored object. If OLD is undefined, a warning + in category 'reg' is produced and the request is ignored. *Note + Warnings::, for information about the enablement and suppression of + warnings. + + To remove a register alias, invoke 'rr' on its name. A register's + contents do not become inaccessible until it has no more names. + + +File: groff.info, Node: Interpolating Registers, Next: Auto-increment, Prev: Setting Registers, Up: Registers + +5.8.2 Interpolating Registers +----------------------------- + +Register contents are interpolated with the '\n' escape sequence. + + -- Escape sequence: \ni + -- Escape sequence: \n(id + -- Escape sequence: \n[ident] + Interpolate register with name IDENT (one-character name I, + two-character name ID). '\n' is interpreted even in copy mode + (*note Copy Mode::). If the register is undefined, it is created + and assigned a value of '0', that value is interpolated, and a + warning in category 'reg' is emitted. *Note Warnings::, for + information about the enablement and suppression of warnings. + + .nr a 5 + .nr as \na+\na + \n(as + => 10 + + .nr a1 5 + .nr ab 6 + .ds str b + .ds num 1 + \n[a\n[num]] + => 5 + \n[a\*[str]] + => 6 + + +File: groff.info, Node: Auto-increment, Next: Assigning Register Formats, Prev: Interpolating Registers, Up: Registers + +5.8.3 Auto-increment +-------------------- + +Registers can also be incremented or decremented by a configured amount +at the time they are interpolated. The value of the increment is +specified with a third argument to the 'nr' request, and a special +interpolation syntax is used to alter and then retrieve the register's +value. Together, these features are called "auto-increment".(1) (*note +Auto-increment-Footnote-1::) + + -- Request: .nr ident value incr + Set register IDENT to VALUE and its auto-incrementation amount to + to INCR. The '\R' escape sequence doesn't support an INCR + argument. + + Auto-incrementation is not _completely_ automatic; the '\n' escape +sequence in its basic form never alters the value of a register. To +apply auto-incrementation to a register, interpolate it with '\ną'. + + -- Escape sequence: \n+i + -- Escape sequence: \n-i + -- Escape sequence: \n+(id + -- Escape sequence: \n-(id + -- Escape sequence: \n+[ident] + -- Escape sequence: \n-[ident] + Increment or decrement IDENT (one-character name I, two-character + name ID) by the register's auto-incrementation value and then + interpolate the new register value. If IDENT has no + auto-incrementation value, interpolate as with '\n'. + + .nr a 0 1 + .nr xx 0 5 + .nr foo 0 -2 + \n+a, \n+a, \n+a, \n+a, \n+a + .br + \n-(xx, \n-(xx, \n-(xx, \n-(xx, \n-(xx + .br + \n+[foo], \n+[foo], \n+[foo], \n+[foo], \n+[foo] + => 1, 2, 3, 4, 5 + => -5, -10, -15, -20, -25 + => -2, -4, -6, -8, -10 + + To change the increment value without changing the value of a +register, assign the register's value to itself by interpolating it, and +specify the desired increment normally. Apply an increment of '0' to +disable auto-incrementation of the register. + + +File: groff.info, Node: Auto-increment-Footnotes, Up: Auto-increment + + (1) A negative auto-increment can be considered an "auto-decrement". + + +File: groff.info, Node: Assigning Register Formats, Next: Built-in Registers, Prev: Auto-increment, Up: Registers + +5.8.4 Assigning Register Formats +-------------------------------- + +A writable register's value can be interpolated in several number +formats. By default, conventional Arabic numerals are used. Other +formats see use in sectioning and outlining schemes and alternative page +numbering arrangements. + + -- Request: .af reg fmt + Use number format FMT when interpolating register REG. Valid + number formats are as follows. + + '0...' + Arabic numerals 0, 1, 2, and so on. Any decimal digit is + equivalent to '0'; the formatter merely counts the digits + specified. Multiple Arabic numerals in FMT cause + interpolations to be zero-padded on the left if necessary to + at least as many digits as specified (interpolations never + truncate a register value). A register with format '00' + interpolates values 1, 2, 3 as '01', '02', '03'. The default + format for all writable registers is '0'. + + 'I' + Uppercase Roman numerals: 0, I, II, III, IV, ... + + 'i' + Lowercase Roman numerals: 0, i, ii, iii, iv, ... + + 'A' + Uppercase letters: 0, A, B, C, ..., Z, AA, AB, ... + + 'a' + Lowercase letters: 0, a, b, c, ..., z, aa, ab, ... + + Omitting FMT causes a warning in category 'missing'. *Note + Warnings::, for information about the enablement and suppression of + warnings. Specifying an unrecognized format is an error. + + Zero values are interpolated as '0' in non-Arabic formats. + Negative quantities are prefixed with '-' irrespective of format. + In Arabic formats, the sign supplements the field width. If REG + doesn't exist, it is created with a zero value. + + .nr a 10 + .af a 0 \" the default format + \na, + .af a I + \na, + .af a 321 + .nr a (-\na) + \na, + .af a a + \na + => 10, X, -010, -j + + The representable extrema in the 'i' and 'I' formats correspond to + Arabic ą39,999. GNU 'troff' uses 'w' and 'z' to represent 5,000 + and 10,000 in Roman numerals, respectively, following the + convention of AT&T 'troff'--currently, the correct glyphs for Roman + numerals five thousand ('U+2181') and ten thousand ('U+2182') are + not used. + + Assigning the format of a read-only register is an error. Instead, + copy the read-only register's value to, and assign the format of, a + writable register. + + -- Escape sequence: \gr + -- Escape sequence: \g(rg + -- Escape sequence: \g[reg] + Interpolate the format of the register REG (one-character name R, + two-character name RG). Zeroes represent Arabic formats. If REG + is not defined, REG is not created and nothing is interpolated. + '\g' is interpreted even in copy mode (*note Copy Mode::). + + GNU 'troff' interprets only Arabic numerals. The Roman numeral or +alphabetic formats cannot be used as operands to arithmetic operators in +expressions (*note Numeric Expressions::). For instance, it may be +desirable to test the page number independently of its format. + + .af % i \" front matter + .de header-trap + . \" To test the page number, we need it in Arabic. + . ds saved-page-number-format \\g%\" + . af % 0 + . nr page-number-in-decimal \\n% + . af % \\*[saved-page-number-format] + . ie \\n[page-number-in-decimal]=1 .do-first-page-stuff + . el \{\ + . ie o .do-odd-numbered-page-stuff + . el .do-even-numbered-page-stuff + . \} + . rm saved-page-number-format + .. + .wh 0 header-trap + + +File: groff.info, Node: Built-in Registers, Prev: Assigning Register Formats, Up: Registers + +5.8.5 Built-in Registers +------------------------ + +Predefined registers whose identifiers start with a dot are read-only. +Many are Boolean-valued, interpolating a true or false value testable +with the 'if', 'ie', or 'while' requests. Some read-only registers are +string-valued, meaning that they interpolate text. + + *Caution:* Built-in registers are subject to removal like others; +once removed, they can be recreated only as normal writable registers +and will not reflect formatter state. + + A register name (without the dot) is often associated with a request +of the same name. A complete listing of all built-in registers can be +found in *note Register Index::. + + We present here a few built-in registers that are not described +elsewhere in this manual; they have to do with invariant properties of +GNU 'troff', or obtain information about the formatter's command-line +options, processing progress, or the operating environment. + +'\n[.A]' + Approximate output is being formatted (Boolean-valued); see 'groff' + '-a' option (*note Groff Options::). + +'\n[.c]' +'\n[c.]' + Input line number. 'c.' is a writable synonym, affecting + subsequent interpolations of both '.c' and 'c.'. + +'\n[.F]' + Name of input file (string-valued). + +'\n[.g]' + Always true in GNU 'troff' (Boolean-valued). Documents can use + this to ask the formatter if it claims 'groff' compatibility. + +'\n[.P]' + Output page selection status (Boolean-valued); see 'groff' '-o' + option (*note Groff Options::). + +'\n[.R]' + Count of available unused registers; always 10,000 in GNU + 'troff'.(1) (*note Built-in Registers-Footnote-1::) + +'\n[.T]' + Indicator of output device selection (Boolean-valued); see 'groff' + '-T' option (*note Groff Options::). + +'\n[.U]' + Unsafe mode enablement status (Boolean-valued); see 'groff' '-U' + option (*note Groff Options::). + +'\n[.x]' + Major version number of the running GNU 'troff' formatter. For + example, if the version number is 1.23.0, then '.x' contains '1'. + +'\n[.y]' + Minor version number of the running GNU 'troff' formatter. For + example, if the version number is 1.23.0, then '.y' contains '23'. + +'\n[.Y]' + Revision number of the running GNU 'troff' formatter. For example, + if the version number is 1.23.0, then '.Y' contains '0'. + +'\n[$$]' + Process identifier (PID) of the GNU 'troff' program in its + operating environment. + + Date- and time-related registers are set per the local time as +determined by 'localtime(3)' when the formatter launches. This +initialization can be overridden by 'SOURCE_DATE_EPOCH' and 'TZ'; see +*note Environment::. + +'\n[seconds]' + Count of seconds elapsed in the minute (0-60). + +'\n[minutes]' + Count of minutes elapsed in the hour (0-59). + +'\n[hours]' + Count of hours elapsed since midnight (0-23). + +'\n[dw]' + Day of the week (1-7; 1 is Sunday). + +'\n[dy]' + Day of the month (1-31). + +'\n[mo]' + Month of the year (1-12). + +'\n[year]' + Gregorian year. + +'\n[yr]' + Gregorian year minus 1900. This register is incorrectly documented + in the AT&T 'troff' manual as storing the last two digits of the + current year. That claim stopped being true in 2000. Old 'troff' + input that looks like: + + '\" The year number is a surprise after 1999. + This document was formatted in 19\n(yr. + + can be corrected to: + + This document was formatted in \n[year]. + + or, for portability across many 'roff' programs, to the following. + + .nr y4 1900+\n(yr + This document was formatted in \n(y4. + + +File: groff.info, Node: Built-in Registers-Footnotes, Up: Built-in Registers + + (1) GNU 'troff' dynamically allocates memory for as many registers as +required. + + +File: groff.info, Node: Manipulating Filling and Adjustment, Next: Manipulating Hyphenation, Prev: Registers, Up: GNU troff Reference + +5.9 Manipulating Filling and Adjustment +======================================= + +When an output line is pending (see below), a break moves the drawing +position to the beginning of the next text baseline, interrupting +filling. Various ways of causing breaks were shown in *note Breaking::. +The 'br' request likewise causes a break. Several other requests imply +breaks: 'bp', 'ce', 'cf', 'fi', 'fl', 'in', 'nf', 'rj', 'sp', 'ti', and +'trf'. If the no-break control character is used with any of these +requests, GNU 'troff' suppresses the break; instead the requested +operation takes effect at the next break. ''br' does nothing. + + .ll 55n + This line is normally filled and adjusted. + .br + A line's alignment is decided + 'ce \" Center the next input line (no break). + when it is output. + This line returns to normal filling and adjustment. + => This line is normally filled and adjusted. + => A line's alignment is decided when it is output. + => This line returns to normal filling and adjustment. + +Output line properties like page offset, indentation, adjustment, and +even the location of its text baseline, are not determined until the +line has been broken. An output line is said to be "pending" if some +input has been collected but an output line corresponding to it has not +yet been written; such an output line is also termed "partially +collected". If no output line is pending, it is as if a break has +already happened; additional breaks, whether explicit or implicit, have +no effect. If the vertical drawing position is negative--as it is when +the formatter starts up--a break starts a new page (even if no output +line is pending) unless an end-of-input macro is being interpreted. +*Note End-of-input Traps::. + + -- Request: .br + Break the line: emit any pending output line without adjustment. + + foo bar + .br + baz + 'br + qux + => foo bar + => baz qux + + Sometimes you want to prevent a break within a phrase or between a +quantity and its units. + + -- Escape sequence: \~ + Insert an unbreakable space that is adjustable like an ordinary + space. It is discarded from the end of an output line if a break + is forced. + + Set the output speed to\~1. + There are 1,024\~bytes in 1\~KiB. + J.\~F.\~Ossanna wrote the original CSTR\~#54. + + By default, GNU 'troff' fills text and adjusts it to reach the output +line length. The 'nf' request disables filling; the 'fi' request +reënables it. + + -- Request: .fi + -- Register: \n[.u] + Enable filling of output lines; a pending output line is broken. + The read-only register '.u' is set to 1. The filling enablement + status, sometimes called "fill mode", is associated with the + environment (*note Environments::). *Note Line Continuation::, for + interaction with the '\c' escape sequence. + + -- Request: .nf + Disable filling of output lines: the output line length (*note Line + Layout::) is ignored and output lines are broken where the input + lines are. A pending output line is broken and adjustment is + suppressed. The read-only register '.u' is set to 0. The filling + enablement status is associated with the environment (*note + Environments::). See *note Line Continuation::, for interaction + with the '\c' escape sequence. + + -- Request: .ad [mode] + -- Register: \n[.j] + Enable output line adjustment in MODE, taking effect when the + pending (or next) output line is broken. Adjustment is suppressed + when filling is. MODE can have one of the following values. + + 'b' + 'n' + Adjust "normally": if the output line does not consume the + distance between the indentation and the configured output + line length, GNU 'troff' stretches adjustable spaces within + the line until that length is reached. When the indentation + is zero, this mode spreads the line to both the left and right + margins. This is the GNU 'troff' default. + + 'c' + Center filled text. Contrast with the 'ce' request, which + centers text _without_ filling it. + + 'l' + Align text to the left without adjusting it. + + 'r' + Align text to the right without adjusting it. + + MODE can also be a value previously stored in the '.j' register. + Using 'ad' without an argument is the same as '.ad \n[.j]'; unless + filling is disabled, GNU 'troff' resumes adjusting lines in the + same way it did before adjustment was disabled by invocation of the + 'na' request. + + The adjustment mode and enablement status are encoded in the + read-only register '.j'. These parameters are associated with the + environment (*note Environments::). + + The value of '.j' for any adjustment mode is an implementation + detail and should not be relied upon as a programmer's interface. + Do not write logic to interpret or perform arithmetic on it. + + .ll 48n + .de AD + . br + . ad \\$1 + .. + .de NA + . br + . na + .. + left + .AD r + .nr ad \n(.j + right + .AD c + center + .NA + left + .AD + center + .AD \n(ad + right + => left + => right + => center + => left + => center + => right + + -- Request: .na + Disable output line adjustment. This produces the same output as + left-alignment, but the value of the adjustment mode register '.j' + is altered differently. The adjustment mode and enablement status + are associated with the environment (*note Environments::). + + -- Request: .brp + -- Escape sequence: \p + Break, adjusting the line per the current adjustment mode. '\p' + schedules a break with adjustment at the next word boundary. The + escape sequence is itself neither a break nor a space of any kind; + it can thus be placed in the middle of a word to cause a break at + the end of that word. + + Breaking with immediate adjustment can produce ugly results since + GNU 'troff' doesn't have a sophisticated paragraph-building + algorithm, as TeX has, for example. Instead, GNU 'troff' fills and + adjusts a paragraph line by line. + + .ll 4.5i + This is an uninteresting sentence. + This is an uninteresting sentence.\p + This is an uninteresting sentence. + + is formatted as follows. + + This is an uninteresting sentence. This is + an uninteresting sentence. + This is an uninteresting sentence. + + To clearly present the next couple of requests, we must introduce the +concept of "productive" input lines. A "productive input line" is one +that directly produces formatted output. Text lines produce output,(1) +(*note Manipulating Filling and Adjustment-Footnote-1::) as do control +lines containing requests like 'tl' or escape sequences like '\D'. +Macro calls are not _directly_ productive, and thus not counted, but +their interpolated contents can be. Empty requests, and requests and +escape sequences that define registers or strings or alter the +formatting environment (as with changes to the size, face, height, +slant, or color of the type) are not productive. We will also preview +the output line continuation escape sequence, '\c', which "connects" two +input lines that would otherwise be counted separately. (2) (*note +Manipulating Filling and Adjustment-Footnote-2::) + + .de hello + Hello, world! + .. + .ce \" center output of next productive input line + . + .nr junk-reg 1 + .ft I + Chorus: \c + .ft + .hello + Went the day well? + => Chorus: Hello, world! + => Went the day well? + + -- Request: .ce [n] + -- Register: \n[.ce] + Break (unless the no-break control character is used), center the + output of the next N productive input lines with respect to the + line length and indentation without filling, then break again + regardless of the invoking control character. If the argument is + not positive, centering is disabled. Omitting the argument implies + an N of '1'. The count of lines remaining to be centered is stored + in the read-only register '.ce' and is associated with the + environment (*note Environments::). + + While the '.ad c' request also centers text, it fills the text as + well. + + .de FR + This is a small text fragment that shows the differences + between the `.ce' and the `.ad c' requests. + .. + .ll 4i + .ce 1000 + .FR + .ce 0 + + .ad c + .FR + => This is a small text fragment that shows + => the differences + => between the `.ce' and the `.ad c' requests. + => + => This is a small text fragment that shows + => the differences between the `.ce' and + => the `.ad c' requests. + + The previous example illustrates a common idiom of turning + centering on for a quantity of lines far in excess of what is + required, and off again after the text to be centered. This + technique relieves humans of counting lines for requests that take + a count of input lines as an argument. + + -- Request: .rj [n] + -- Register: \n[.rj] + Break (unless the no-break control character is used), align the + output of the next N productive input lines to the right margin + without filling, then break again regardless of the control + character. If the argument is not positive, right-alignment is + disabled. Omitting the argument implies an N of '1'. The count of + lines remaining to be right-aligned is stored in the read-only + register '.rj' and is associated with the environment (*note + Environments::). + + .ll 49n + .rj 3 + At first I hoped that such a technically unsound + project would collapse but I soon realized it was + doomed to success. \[em] C. A. R. Hoare + => At first I hoped that such a technically unsound + => project would collapse but I soon realized it was + => doomed to success. -- C. A. R. Hoare + + -- Request: .ss word-space-size [additional-sentence-space-size] + -- Register: \n[.ss] + -- Register: \n[.sss] + Set the sizes of spaces between words and sentences(3) (*note + Manipulating Filling and Adjustment-Footnote-3::) in twelfths of + font's space width (typically one-fourth to one-third em for + Western scripts). The default for both parameters is 12. Negative + values are erroneous. The first argument is a minimum; if an + output line undergoes adjustment, such spaces may increase in + width. The optional second argument sets the amount of additional + space separating sentences on the same output line. If omitted, + this amount is set to WORD-SPACE-SIZE. The request is ignored if + there are no parameters. + + Additional inter-sentence space is used only if the output line is + not full when the end of a sentence occurs in the input. If a + sentence ends at the end of an input line, then both an inter-word + space and an inter-sentence space are added to the output; if two + spaces follow the end of a sentence in the middle of an input line, + then the second space becomes an inter-sentence space in the + output. Additional inter-sentence space is not adjusted, but the + inter-word space that always precedes it may be. Further input + spaces after the second, if present, are adjusted as normal. + + The read-only registers '.ss' and '.sss' hold the minimal + inter-word space and additional inter-sentence space amounts, + respectively. These parameters are part of the environment (*note + Environments::), and rounded down to the nearest multiple of 12 on + terminals. + + The 'ss' request can insert discardable horizontal space; that is, + space that is discarded at a break. For example, some footnote + styles collect the notes into a single paragraph with large gaps + between each note. + + .ll 48n + 1.\~J. Fict. Ch. Soc. 6 (2020), 3\[en]14. + .ss 12 48 \" applies to next sentence ending + Reprints no longer available through FCS. + .ss 12 \" go back to normal + 2.\~Better known for other work. + => 1. J. Fict. Ch. Soc. 6 (2020), 3-14. Reprints + => no longer available through FCS. 2. Better + => known for other work. + + If _undiscardable_ space is required, use the '\h' escape sequence. + + +File: groff.info, Node: Manipulating Filling and Adjustment-Footnotes, Up: Manipulating Filling and Adjustment + + (1) unless diverted; see *note Diversions:: + + (2) *Note Line Continuation::. + + (3) Recall *note Filling:: and *note Sentences:: for the definitions +of word and sentence boundaries, respectively. + + +File: groff.info, Node: Manipulating Hyphenation, Next: Manipulating Spacing, Prev: Manipulating Filling and Adjustment, Up: GNU troff Reference + +5.10 Manipulating Hyphenation +============================= + +When filling, GNU 'troff' hyphenates words as needed at user-specified +and automatically determined hyphenation points. The machine-driven +determination of hyphenation points in words requires algorithms and +data, and is susceptible to conventions and preferences. Before +tackling such "automatic hyphenation", let us consider how hyphenation +points can be set explicitly. + + Explicitly hyphenated words such as "mother-in-law" are eligible for +breaking after each of their hyphens. Relatively few words in a +language offer such obvious break points, however, and automatic +detection of syllabic (or phonetic) boundaries for hyphenation is not +perfect,(1) (*note Manipulating Hyphenation-Footnote-1::) particularly +for unusual words found in technical literature. We can instruct GNU +'troff' how to hyphenate specific words if the need arises. + + -- Request: .hw word ... + Define each "hyphenation exception" WORD with each hyphen '-' in + the word indicating a hyphenation point. For example, the request + + .hw in-sa-lub-rious alpha + + marks potential hyphenation points in "insalubrious", and prevents + "alpha" from being hyphenated at all. + + Besides the space character, any character whose hyphenation code + is zero can be used to separate the arguments of 'hw' (see the + 'hcode' request below). In addition, this request can be used more + than once. + + Hyphenation points specified with 'hw' are not subject to the + within-word placement restrictions imposed by the 'hy' request (see + below). + + Hyphenation exceptions specified with the 'hw' request are + associated with the hyphenation language (see the 'hla' request + below) and environment (*note Environments::); invoking the 'hw' + request in the absence of a hyphenation language is an error. + + The request is ignored if there are no parameters. + + These are known as hyphenation exceptions in the expectation that +most users will avail themselves of automatic hyphenation; these +exceptions override any rules that would normally apply to a word +matching a hyphenation exception defined with 'hw'. + + Situations also arise when only a specific occurrence of a word needs +its hyphenation altered or suppressed, or when a URL or similar string +needs to be breakable in sensible places without hyphenation. + + -- Escape sequence: \% + -- Escape sequence: \: + To tell GNU 'troff' how to hyphenate words as they occur in input, + use the '\%' escape sequence; it is the default "hyphenation + character". Each instance within a word indicates to GNU 'troff' + that the word may be hyphenated at that point, while prefixing a + word with this escape sequence prevents it from being otherwise + hyphenated. This mechanism affects only that occurrence of the + word; to change the hyphenation of a word for the remainder of + input processing, use the 'hw' request. + + GNU 'troff' regards the escape sequences '\X' and '\Y' as starting + a word; that is, the '\%' escape sequence in, say, + '\X'...'\%foobar' or '\Y'...'\%foobar' no longer prevents + hyphenation of 'foobar' but inserts a hyphenation point just prior + to it; most likely this isn't what you want. *Note Postprocessor + Access::. + + '\:' inserts a non-printing break point; that is, a word can break + there, but the soft hyphen glyph (see below) is not written to the + output if it does. This escape sequence is an input word boundary, + so the remainder of the word is subject to hyphenation as normal. + + You can combine '\:' and '\%' to control breaking of a file name or + URL, or to permit hyphenation only after certain explicit hyphens + within a word. + + The \%Lethbridge-Stewart-\:\%Sackville-Baggins divorce + was, in retrospect, inevitable once the contents of + \%/var/log/\:\%httpd/\:\%access_log on the family web + server came to light, revealing visitors from Hogwarts. + + -- Request: .hc [char] + Change the hyphenation character to CHAR. This character then + works as the '\%' escape sequence normally does, and thus no longer + appears in the output.(2) (*note Manipulating + Hyphenation-Footnote-2::) Without an argument, 'hc' resets the + hyphenation character to '\%' (the default). The hyphenation + character is associated with the environment (*note + Environments::). + + -- Request: .shc [c] + Set the "soft hyphen character", inserted when a word is hyphenated + automatically or at a hyphenation character, to the ordinary or + special character C.(3) (*note Manipulating + Hyphenation-Footnote-3::) If the argument is omitted, the soft + hyphen character is set to the default, '\[hy]'. If no glyph for C + exists in the font in use at a potential hyphenation point, then + the line is not broken there. Neither character definitions + (specified with the 'char' and similar requests) nor translations + (specified with the 'tr' request) are applied to C. + + Several requests influence automatic hyphenation. Because +conventions vary, a variety of hyphenation modes is available to the +'hy' request; these determine whether hyphenation will apply to a word +prior to breaking a line at the end of a page (more or less; see below +for details), and at which positions within that word automatically +determined hyphenation points are permissible. The places within a word +that are eligible for hyphenation are determined by language-specific +data and lettercase relationships. Furthermore, hyphenation of a word +might be suppressed due to a limit on consecutive hyphenated lines +('hlm'), a minimum line length threshold ('hym'), or because the line +can instead be adjusted with additional inter-word space ('hys'). + + -- Request: .hy [mode] + -- Register: \n[.hy] + Set automatic hyphenation mode to MODE, an integer encoding + conditions for hyphenation; if omitted, '1' is implied. The + hyphenation mode is available in the read-only register '.hy'; it + is associated with the environment (*note Environments::). The + default hyphenation mode depends on the localization file loaded + when GNU 'troff' starts up; see the 'hpf' request below. + + Typesetting practice generally does not avail itself of every + opportunity for hyphenation, but the details differ by language and + site mandates. The hyphenation modes of AT&T 'troff' were + implemented with English-language publishing practices of the 1970s + in mind, not a scrupulous enumeration of conceivable parameters. + GNU 'troff' extends those modes such that finer-grained control is + possible, favoring compatibility with older implementations over a + more intuitive arrangement. The means of hyphenation mode control + is a set of numbers that can be added up to encode the behavior + sought.(4) (*note Manipulating Hyphenation-Footnote-4::) The + entries in the following table are termed "values"; the sum of the + desired values is the "mode". + + '0' + disables hyphenation. + + '1' + enables hyphenation except after the first and before the last + character of a word. + + The remaining values "imply" 1; that is, they enable hyphenation + under the same conditions as '.hy 1', and then apply or lift + restrictions relative to that basis. + + '2' + disables hyphenation of the last word on a page,(5) (*note + Manipulating Hyphenation-Footnote-5::) even for explicitly + hyphenated words. + + '4' + disables hyphenation before the last two characters of a word. + + '8' + disables hyphenation after the first two characters of a word. + + '16' + enables hyphenation before the last character of a word. + + '32' + enables hyphenation after the first character of a word. + + Apart from value 2, restrictions imposed by the hyphenation mode + are _not_ respected for words whose hyphenations have been + specified with the hyphenation character ('\%' by default) or the + 'hw' request. + + Nonzero values in the previous table are additive. For example, + mode 12 causes GNU 'troff' to hyphenate neither the last two nor + the first two characters of a word. Some values cannot be used + together because they contradict; for instance, values 4 and 16, + and values 8 and 32. As noted, it is superfluous to add 1 to any + non-zero even mode. + + The automatic placement of hyphens in words is determined by + "pattern files", which are derived from TeX and available for + several languages. The number of characters at the beginning of a + word after which the first hyphenation point should be inserted is + determined by the patterns themselves; it can't be reduced further + without introducing additional, invalid hyphenation points + (unfortunately, this information is not part of a pattern file--you + have to know it in advance). The same is true for the number of + characters at the end of a word before the last hyphenation point + should be inserted. For example, you can supply the following + input to 'echo $(nroff)'. + + .ll 1 + .hy 48 + splitting + + You will get + + s- plit- t- in- g + + instead of the correct 'split- ting'. English patterns as + distributed with GNU 'troff' need two characters at the beginning + and three characters at the end; this means that value 4 of 'hy' is + mandatory. Value 8 is possible as an additional restriction, but + values 16 and 32 should be avoided, as should mode 1. Modes 4 + and 6 are typical. + + A table of left and right minimum character counts for hyphenation + as needed by the patterns distributed with GNU 'troff' follows; see + the 'groff_tmac(5)' man page for more information on GNU 'troff''s + language macro files. + + language pattern name left min right min + ----------------------------------------------------------- + Czech cs 2 2 + English en 2 3 + French fr 2 3 + German traditional det 2 2 + German reformed den 2 2 + Italian it 2 2 + Swedish sv 1 2 + + Hyphenation exceptions within pattern files (i.e., the words within + a TeX '\hyphenation' group) obey the hyphenation restrictions given + by 'hy'. + + -- Request: .nh + Disable automatic hyphenation; i.e., set the hyphenation mode to 0 + (see above). The hyphenation mode of the last call to 'hy' is not + remembered. + + -- Request: .hpf pattern-file + -- Request: .hpfa pattern-file + -- Request: .hpfcode a b [c d] ... + Read hyphenation patterns from PATTERN-FILE, which is sought in the + same way that macro files are with the 'mso' request or the + '-mNAME' command-line option to 'groff'. The PATTERN-FILE should + have the same format as (simple) TeX pattern files. More + specifically, the following scanning rules are implemented. + + * A percent sign starts a comment (up to the end of the line) + even if preceded by a backslash. + + * "Digraphs" like '\$' are not supported. + + * '^^XX' (where each X is 0-9 or a-f) and '^^C' (character C in + the code point range 0-127 decimal) are recognized; other uses + of '^' cause an error. + + * No macro expansion is performed. + + * 'hpf' checks for the expression '\patterns{...}' (possibly + with whitespace before or after the braces). Everything + between the braces is taken as hyphenation patterns. + Consequently, '{' and '}' are not allowed in patterns. + + * Similarly, '\hyphenation{...}' gives a list of hyphenation + exceptions. + + * '\endinput' is recognized also. + + * For backward compatibility, if '\patterns' is missing, the + whole file is treated as a list of hyphenation patterns + (except that the '%' character is recognized as the start of a + comment). + + The 'hpfa' request appends a file of patterns to the current list. + + The 'hpfcode' request defines mapping values for character codes in + pattern files. It is an older mechanism no longer used by GNU + 'troff''s own macro files; for its successor, see 'hcode' below. + 'hpf' or 'hpfa' apply the mapping after reading the patterns but + before replacing or appending to the active list of patterns. Its + arguments are pairs of character codes--integers from 0 to 255. + The request maps character code A to code B, code C to code D, and + so on. Character codes that would otherwise be invalid in GNU + 'troff' can be used. By default, every code maps to itself except + those for letters 'A' to 'Z', which map to those for 'a' to 'z'. + + The set of hyphenation patterns is associated with the language set + by the 'hla' request (see below). The 'hpf' request is usually + invoked by a localization file loaded by the 'troffrc' file.(6) + (*note Manipulating Hyphenation-Footnote-6::) + + A second call to 'hpf' (for the same language) replaces the + hyphenation patterns with the new ones. Invoking 'hpf' or 'hpfa' + causes an error if there is no hyphenation language. If no 'hpf' + request is specified (either in the document, in a file loaded at + startup, or in a macro package), GNU 'troff' won't automatically + hyphenate at all. + + -- Request: .hcode c1 code1 [c2 code2] ... + Set the hyphenation code of character C1 to CODE1, that of C2 to + CODE2, and so on. A hyphenation code must be an ordinary character + (not a special character escape sequence) other than a digit or a + space. The request is ignored if given no arguments. + + For hyphenation to work, hyphenation codes must be set up. At + startup, GNU 'troff' assigns hyphenation codes to the letters + 'a'-'z' (mapped to themselves), to the letters 'A'-'Z' (mapped to + 'a'-'z'), and zero to all other characters. Normally, hyphenation + patterns contain only lowercase letters which should be applied + regardless of case. In other words, they assume that the words + 'FOO' and 'Foo' should be hyphenated exactly as 'foo' is. The + 'hcode' request extends this principle to letters outside the + Unicode basic Latin alphabet; without it, words containing such + letters won't be hyphenated properly even if the corresponding + hyphenation patterns contain them. + + For example, the following 'hcode' requests are necessary to assign + hyphenation codes to the letters 'ÄäÖöÜüß', needed for German. + + .hcode ä ä Ä ä + .hcode ö ö Ö ö + .hcode ü ü Ü ü + .hcode ß ß + + Without these assignments, GNU 'troff' treats the German word + 'Kindergärten' (the plural form of 'kindergarten') as two words + 'kinderg' and 'rten' because the hyphenation code of the umlaut a + is zero by default, just like a space. There is a German + hyphenation pattern that covers 'kinder', so GNU 'troff' finds the + hyphenation 'kin-der'. The other two hyphenation points + ('kin-der-gär-ten') are missed. + + -- Request: .hla lang + -- Register: \n[.hla] + Set the hyphenation language to LANG. Hyphenation exceptions + specified with the 'hw' request and hyphenation patterns and + exceptions specified with the 'hpf' and 'hpfa' requests are + associated with the hyphenation language. The 'hla' request is + usually invoked by a localization file, which is turn loaded by the + 'troffrc' or 'troffrc-end' file; see the 'hpf' request above. + + The hyphenation language is available in the read-only + string-valued register '.hla'; it is associated with the + environment (*note Environments::). + + -- Request: .hlm [n] + -- Register: \n[.hlm] + -- Register: \n[.hlc] + Set the maximum quantity of consecutive hyphenated lines to N. If + N is negative, there is no maximum. If omitted, N is -1. This + value is associated with the environment (*note Environments::). + Only lines output from a given environment count toward the maximum + associated with that environment. Hyphens resulting from '\%' are + counted; explicit hyphens are not. + + The '.hlm' read-only register stores this maximum. The count of + immediately preceding consecutive hyphenated lines is available in + the read-only register '.hlc'. + + -- Request: .hym [length] + -- Register: \n[.hym] + Set the (right) hyphenation margin to LENGTH. If the adjustment + mode is not 'b' or 'n', the line is not hyphenated if it is shorter + than LENGTH. Without an argument, the hyphenation margin is reset + to its default value, 0. The default scaling unit is 'm'. The + hyphenation margin is associated with the environment (*note + Environments::). + + A negative argument resets the hyphenation margin to zero, emitting + a warning in category 'range'. + + The hyphenation margin is available in the '.hym' read-only + register. + + -- Request: .hys [hyphenation-space] + -- Register: \n[.hys] + Suppress hyphenation of the line in adjustment modes 'b' or 'n' if + it can be justified by adding no more than HYPHENATION-SPACE extra + space to each inter-word space. Without an argument, the + hyphenation space adjustment threshold is set to its default value, + 0. The default scaling unit is 'm'. The hyphenation space + adjustment threshold is associated with the environment (*note + Environments::). + + A negative argument resets the hyphenation space adjustment + threshold to zero, emitting a warning in category 'range'. + + The hyphenation space adjustment threshold is available in the + '.hys' read-only register. + + +File: groff.info, Node: Manipulating Hyphenation-Footnotes, Up: Manipulating Hyphenation + + (1) Whether a perfect algorithm for this application is even possible +is an unsolved problem in computer science: +. + + (2) '\%' itself stops marking hyphenation points but still produces +no output glyph. + + (3) "Soft" because it appears in output only where a hyphenation +break is performed; a "hard" hyphen, as in "long-term", always appears. + + (4) The mode is a vector of Booleans encoded as an integer. To a +programmer, this fact is easily deduced from the exclusive use of powers +of two for the configuration parameters; they are computationally easy +to "mask off" and compare to zero. To almost everyone else, the +arrangement seems recondite and unfriendly. + + (5) Hyphenation is prevented if the next page location trap is closer +to the vertical drawing position than the next text baseline would be. +*Note Page Location Traps::. + + (6) For more on localization, see the 'groff_tmac(5)' man page. + + +File: groff.info, Node: Manipulating Spacing, Next: Tabs and Fields, Prev: Manipulating Hyphenation, Up: GNU troff Reference + +5.11 Manipulating Spacing +========================= + +A break causes the formatter to update the vertical drawing position at +which the new text baseline is aligned. You can alter this location. + + -- Request: .sp [distance] + Break and move the next text baseline down by DISTANCE, or until + springing a page location trap.(1) (*note Manipulating + Spacing-Footnote-1::) If invoked with the no-break control + character, 'sp' moves the pending output line's text baseline by + DISTANCE. A negative DISTANCE will not reduce the position of the + text baseline below zero. Inside a diversion, any DISTANCE + argument is ignored. The default scaling unit is 'v'. If DISTANCE + is not specified, '1v' is assumed. + + .pl 5v \" Set page length to 5 vees. + .de xx + \-\-\- + . br + .. + .wh 0 xx \" Set a trap at the top of the page. + foo on page \n% + .sp 2v + bar on page \n% + .sp 50v \" This will cause a page break. + baz on page \n% + .pl \n(nlu \" Truncate page to current position. + => --- + => foo on page 1 + => + => + => bar on page 1 + => --- + => baz on page 2 + + You might use the following macros to set the baseline of the next + output text at a given distance from the top or the bottom of the + page. We subtract one line height ('\n[.v]') because the '|' + operator moves to one vee below the page top (recall *note Numeric + Expressions::). + + .de y-from-top-down + . sp |\\$1-\\n[.v]u + .. + . + .de y-from-bot-up + . sp |\\n[.p]u-\\$1-\\n[.v]u + .. + + A call to '.y-from-bot-up 10c' means that the next text baseline + will be 10 cm from the bottom edge of the paper. + + -- Request: .ls [count] + -- Register: \n[.L] + Set the line spacing; add COUNT-1 blank lines after each line of + text. With no argument, GNU 'troff' uses the previous value before + the last 'ls' call. The default is '1'. + + The read-only register '.L' contains the current line spacing; it + is associated with the environment (*note Environments::). + + The 'ls' request is a coarse mechanism. *Note Changing the Type +Size::, for the requests 'vs' and 'pvs' as alternatives to 'ls'. + + -- Escape sequence: \x'spacing' + -- Register: \n[.a] + Sometimes, an output line requires additional vertical spacing, for + instance to allow room for a tall construct like an inline equation + with exponents or subscripts (particularly if they are iterated). + The '\x' escape sequence takes a delimited measurement (like + '\x'3p'') to increase the vertical spacing of the pending output + line. The default scaling unit is 'v'. If the measurement is + positive, extra vertical space is inserted below the current line; + a negative measurement adds space above. If '\x' is applied to the + pending output line multiple times, the maxima of the positive and + negative adjustments are separately applied. The delimiter need + not be a neutral apostrophe; see *note Delimiters::. + + The '.a' read-only register contains the extra vertical spacing + _after_ the text baseline of the most recently emitted output line. + (In other words, it is the largest positive argument to '\x' + encountered on that line.) This quantity is exposed via a register + because if an output line requires this "extra post-vertical line + spacing", and the subsequent output line requires "extra + pre-vertical line spacing" (a negative argument to '\x'), then + applying both can lead to excessive spacing between the output + lines. Text that is piling high on line N might not require (as + much) extra pre-vertical line spacing if line N-1 carries extra + post-vertical line spacing. + + Use of '\x' can be necessary in combination with the + bracket-building escape sequence '\b',(2) (*note Manipulating + Spacing-Footnote-2::) as the following example shows. + + .nf + This is a test of \[rs]b (1). + This is a test of \[rs]b (2). + This is a test of \b'xyz'\x'-1m'\x'1m' (3). + This is a test of \[rs]b (4). + This is a test of \[rs]b (5). + => This is a test of \b (1). + => This is a test of \b (2). + => x + => This is a test of y (3). + => z + => This is a test of \b (4). + => This is a test of \b (5). + +Without '\x', the backslashes on the lines marked '(2)' and '(4)' would +be overprinted. + + -- Request: .ns + -- Request: .rs + -- Register: \n[.ns] + Enable "no-space mode". Vertical spacing, whether by 'sp' requests + or blank input lines, is disabled. The 'bp' request to advance to + the next page is also disabled, unless it is accompanied by a page + number (*note Page Control::). No-space mode ends automatically + when text(3) (*note Manipulating Spacing-Footnote-3::) is formatted + for output (4) (*note Manipulating Spacing-Footnote-4::) or the + 'rs' request is invoked, which ends no-space mode. The read-only + register '.ns' interpolates a Boolean value indicating the + enablement of no-space mode. + + A paragraphing macro might ordinarily insert vertical space to + separate paragraphs. A section heading macro could invoke 'ns' to + suppress this spacing for the first paragraph in a section. + + +File: groff.info, Node: Manipulating Spacing-Footnotes, Up: Manipulating Spacing + + (1) *Note Page Location Traps::. + + (2) *Note Drawing Geometric Objects::. + + (3) or geometric objects; see *note Drawing Geometric Objects:: + + (4) to the top-level diversion; see *note Diversions:: + + +File: groff.info, Node: Tabs and Fields, Next: Character Translations, Prev: Manipulating Spacing, Up: GNU troff Reference + +5.12 Tabs and Fields +==================== + +A tab character (ISO code point 9, EBCDIC code point 5) causes a +horizontal movement to the next tab stop, if any. + + -- Escape sequence: \t + Interpolate a tab in copy mode; see *note Copy Mode::. + + -- Request: .ta [[n1 n2 ... nn ]T r1 r2 ... rn] + -- Register: \n[.tabs] + Change tab stop positions. This request takes a series of tab + specifiers as arguments (optionally divided into two groups with + the letter 'T') that indicate where each tab stop is to be, + overriding any previous settings. The default scaling unit is 'm'. + Invoking 'ta' without an argument removes all tab stops. GNU + 'troff''s startup value is 'T 0.5i'. + + Tab stops can be specified absolutely--as distances from the left + margin. The following example sets six tab stops, one every inch. + + .ta 1i 2i 3i 4i 5i 6i + + Tab stops can also be specified using a leading '+', which means + that the specified tab stop is set relative to the previous tab + stop. For example, the following is equivalent to the previous + example. + + .ta 1i +1i +1i +1i +1i +1i + + GNU 'troff' supports an extended syntax to specify repeating tab + stops. These stops appear after a 'T' argument. Their values are + always taken as distances relative to the previous tab stop. This + is the idiomatic way to specify tab stops at equal intervals in + 'groff'. The following is, yet again, the same as the previous + examples. It does more, in fact, since it defines an infinite + number of tab stops at one-inch intervals. + + .ta T 1i + + Now we are ready to interpret the full syntax given above. The + 'ta' request sets tabs at positions N1, N2, ..., NN, then at NN+R1, + NN+R2, ..., NN+RN, then at NN+RN+R1, NN+RN+R2, ..., NN+RN+RN, and + so on. + + For example, '4c +6c T 3c 5c 2c' is equivalent to '4c 10c 13c 18c + 20c 23c 28c 30c ...'. + + Text written to a tab column (i.e., between two tab stops, or + between a tab stop and an output line boundary) may be aligned to + the right or left, or centered in the column. This alignment is + determined by appending 'R', 'L', or 'C' to the tab specifier. The + default is 'L'. + + .ta 1i 2iC 3iR + + The beginning of an output line is not a tab stop; the text that + begins an output line is placed according to the configured + alignment and indentation; see *note Manipulating Filling and + Adjustment:: and *note Line Layout::. + + A tab stop is converted into a non-breakable horizontal movement + that cannot be adjusted. + + .ll 2i + .ds foo a\tb\tc + .ta T 1i + \*[foo] + error-> warning: cannot break line + => a b c + + The above creates a single output line that is a bit longer than + two inches (we use a string to show exactly where the tab stops + are). Now consider the following. + + .ll 2i + .ds bar a\tb c\td + .ta T 1i + \*[bar] + error-> warning: cannot adjust line + => a b + => c d + + GNU 'troff' first converts the line's tab stops into unbreakable + horizontal movements, then breaks after 'b'. This usually isn't + what you want. + + Superfluous tab characters--those that do not correspond to a tab + stop--are ignored except for the first, which delimits the + characters belonging to the last tab stop for right-alignment or + centering. + + .ds Z foo\tbar\tbaz + .ds ZZ foo\tbar\tbazqux + .ds ZZZ foo\tbar\tbaz\tqux + .ta 2i 4iR + \*[Z] + .br + \*[ZZ] + .br + \*[ZZZ] + .br + => foo bar baz + => foo bar bazqux + => foo bar bazqux + + The first line right-aligns "baz" within the second tab stop. The + second line right-aligns "bazqux" within it. The third line + right-aligns only "baz" because of the additional tab character, + which marks the end of the text occupying the last tab stop + defined. + + Tab stops are associated with the environment (*note + Environments::). + + The read-only register '.tabs' contains a string representation of + the current tab settings suitable for use as an argument to the + 'ta' request.(1) (*note Tabs and Fields-Footnote-1::) + + .ds tab-string \n[.tabs] + \*[tab-string] + => T120u + + -- Request: .tc [c] + Set the tab repetition character to the ordinary or special + character C; normally, no glyph is written when moving to a tab + stop (and some output devices may output space characters to + achieve this motion). A "tab repetition character" causes the + formatter to write as many instances of C as are necessary to + occupy the interval from the horizontal drawing position to the + next tab stop. With no argument, GNU 'troff' reverts to the + default behavior. The tab repetition character is associated with + the environment (*note Environments::). Only a single character of + C is recognized; any excess is ignored. + + -- Request: .linetabs n + -- Register: \n[.linetabs] + If N is missing or non-zero, activate "line-tabs"; deactivate it + otherwise (the default). Active line-tabs cause GNU 'troff' to + compute tab distances relative to the start of the output line + instead of the input line. + + .de Tabs + . ds x a\t\c + . ds y b\t\c + . ds z c + . ta 1i 3i + \\*x + \\*y + \\*z + .. + .Tabs + .br + .linetabs + .Tabs + => a b c + => a b c + + Line-tabs activation is associated with the environment (*note + Environments::). The read-only register '.linetabs' interpolates 1 + if line-tabs are active, and 0 otherwise. + +* Menu: + +* Leaders:: +* Fields:: + + +File: groff.info, Node: Tabs and Fields-Footnotes, Up: Tabs and Fields + + (1) Plan 9 'troff' uses the register '.S' for this purpose. + + +File: groff.info, Node: Leaders, Next: Fields, Prev: Tabs and Fields, Up: Tabs and Fields + +5.12.1 Leaders +-------------- + +Sometimes it is desirable to fill a tab stop with a given glyph, but +also use tab stops normally on the same output line. An example is a +table of contents entry that uses dots to bridge the entry name with its +page number, which is itself aligned between tab stops. The 'roff' +language provides "leaders" for this purpose.(1) (*note +Leaders-Footnote-1::) + + A leader character (ISO and EBCDIC code point 1, also known as SOH or +"start of heading"), behaves similarly to a tab character: it moves to +the next tab stop. The difference is that for this movement, the +default fill character is a period '.'. + + -- Escape sequence: \a + Interpolate a leader in copy mode; see *note Copy Mode::. + + -- Request: .lc [c] + Set the leader repetition character to the ordinary or special + character C. Recall *note Tabs and Leaders::: when encountering a + leader character in the input, the formatter writes as many dots + '.' as are necessary until reaching the next tab stop; this is the + "leader definition character". Omitting C unsets the leader + character. With no argument, GNU 'troff' treats leaders the same + as tabs. The leader repetition character is associated with the + environment (*note Environments::). Only a single C is recognized; + any excess is ignored. + + A table of contents, for example, may define tab stops after a +section number, a title, and a gap to be filled with leader dots. The +page number follows the leader, after a right-aligned final tab stop +wide enough to house the largest page number occurring in the document. + + .ds entry1 19.\tThe Prophet\a\t98 + .ds entry2 20.\tAll Astir\a\t101 + .ta .5i 4.5i +.5iR + .nf + \*[entry1] + \*[entry2] + => 19. The Prophet............................. 98 + => 20. All Astir............................... 101 + + +File: groff.info, Node: Leaders-Footnotes, Up: Leaders + + (1) This is pronounced to rhyme with "feeder", and refers to how the +glyphs "lead" the eye across the page to the corresponding page number +or other datum. + + +File: groff.info, Node: Fields, Prev: Leaders, Up: Tabs and Fields + +5.12.2 Fields +------------- + +"Fields" are a more general way of laying out tabular data. A field is +defined as the data between a pair of "delimiting characters". It +contains substrings that are separated by "padding characters". The +width of a field is the distance on the _input_ line from the position +where the field starts to the next tab stop. A padding character +inserts an adjustable space similar to TeX's '\hss' command (thus it can +even be negative) to make the sum of all substring lengths plus the +adjustable space equal to the field width. If more than one padding +character is inserted, the available space is evenly distributed among +them. + + -- Request: .fc [delim-char [padding-char]] + Define a delimiting and a padding character for fields. If the + latter is missing, the padding character defaults to a space + character. If there is no argument at all, the field mechanism is + disabled (which is the default). In contrast to, e.g., the tab + repetition character, delimiting and padding characters are _not_ + associated with the environment (*note Environments::). + + .fc # ^ + .ta T 3i + #foo^bar^smurf# + .br + #foo^^bar^smurf# + => foo bar smurf + => foo bar smurf + + +File: groff.info, Node: Character Translations, Next: troff and nroff Modes, Prev: Tabs and Fields, Up: GNU troff Reference + +5.13 Character Translations +=========================== + +A "translation" is a mapping of an input character to an output glyph. +The mapping occurs at output time, i.e., the input character gets +assigned the metric information of the mapped output character right +before input tokens are converted to nodes (*note Gtroff Internals::, +for more on this process). + + -- Request: .tr abcd... + -- Request: .trin abcd... + Translate character A to glyph B, character C to glyph D, and so + on. If there is an odd number of characters in the argument, the + last one is translated to a fixed-width space (the same one + obtained by the '\' escape sequence). + + The 'trin' request is identical to 'tr', but when you unformat a + diversion with 'asciify' it ignores the translation. *Note + Diversions::, for details about the 'asciify' request. + + Some notes: + + * Special characters ('\(XX', '\[XXX]', '\C'XXX'', '\'', '\`', + '\-', '\_'), glyphs defined with the 'char' request, and + numbered glyphs ('\N'XXX'') can be translated also. + + * The '\e' escape can be translated also. + + * Characters can be mapped onto the '\%' and '\~' escape + sequences (but '\%' and '\~' can't be mapped onto another + glyph). + + * The following characters can't be translated: space (with one + exception, see below), backspace, newline, leader (and '\a'), + tab (and '\t'). + + * Translations are not considered for finding the soft hyphen + character set with the 'shc' request. + + * The pair 'C\&' (an arbitrary character C followed by the dummy + character) maps this character to "nothing". + + .tr a\& + foo bar + => foo br + + Even the space character can be mapped to the dummy character. + + .tr aa \& + foo bar + => foobar + + As shown in the example, the space character can't be the + first character/glyph pair as an argument of 'tr'. + Additionally, it is not possible to map the space character to + any other glyph; requests like '.tr aa x' undo '.tr aa \&' + instead. + + If justification is active, lines are justified in spite of + the 'empty' space character (but there is no minimal distance, + i.e., the space character, between words). + + * After an output glyph has been constructed (this happens at + the moment immediately before the glyph is appended to an + output glyph list, either by direct output, in a macro, + diversion, or string), it is no longer affected by 'tr'. + + * Translating character to glyphs where one of them or both are + undefined is possible also; 'tr' does not check whether the + elements of its argument exist. + + *Note Gtroff Internals::. + + * Without an argument, the 'tr' request is ignored. + + -- Request: .trnt abcd... + 'trnt' is the same as the 'tr' request except that the translations + do not apply to text that is transparently throughput into a + diversion with '\!'. *Note Diversions::. + + For example, + + .tr ab + .di x + \!.tm a + .di + .x + + prints 'b' to the standard error stream; if 'trnt' is used instead + of 'tr' it prints 'a'. + + +File: groff.info, Node: troff and nroff Modes, Next: Line Layout, Prev: Character Translations, Up: GNU troff Reference + +5.14 'troff' and 'nroff' Modes +============================== + +Historically, 'nroff' and 'troff' were two separate programs; the former +for terminal output, the latter for typesetters. GNU 'troff' merges +both functions into one executable(1) (*note troff and nroff +Modes-Footnote-1::) that sends its output to a device driver ('grotty' +for terminal devices, 'grops' for PostScript, and so on) which +interprets this intermediate output format. When discussing AT&T +'troff', it makes sense to talk about "'nroff' mode" and "'troff' mode" +since the differences are hard-coded. GNU 'troff' takes information +from device and font description files without handling requests +specially if a terminal output device is used, so such a strong +distinction is unnecessary. + + Usually, a macro package can be used with all output devices. +Nevertheless, it is sometimes necessary to make a distinction between +terminal and non-terminal devices: GNU 'troff' provides two built-in +conditions 'n' and 't' for the 'if', 'ie', and 'while' requests to +decide whether GNU 'troff' shall behave like 'nroff' or like 'troff'. + + -- Request: .troff + Make the 't' built-in condition true (and the 'n' built-in + condition false) for 'if', 'ie', and 'while' conditional requests. + This is the default if GNU 'troff' (_not_ 'groff') is started with + the '-R' switch to avoid loading of the startup files 'troffrc' and + 'troffrc-end'. Without '-R', GNU 'troff' stays in 'troff' mode if + the output device is not a terminal (e.g., 'ps'). + + -- Request: .nroff + Make the 'n' built-in condition true (and the 't' built-in + condition false) for 'if', 'ie', and 'while' conditional requests. + This is the default if GNU 'troff' uses a terminal output device; + the code for switching to 'nroff' mode is in the file 'tty.tmac', + which is loaded by the startup file 'troffrc'. + + *Note Conditionals and Loops::, for more details on built-in +conditions. + + +File: groff.info, Node: troff and nroff Modes-Footnotes, Up: troff and nroff Modes + + (1) A GNU 'nroff' program is available for convenience; it calls GNU +'troff' to perform the formatting. + + +File: groff.info, Node: Line Layout, Next: Line Continuation, Prev: troff and nroff Modes, Up: GNU troff Reference + +5.15 Line Layout +================ + +The following drawing shows the dimensions that 'gtroff' uses for +placing a line of output onto the page. They are labeled with the +request that manipulates each dimension. + + -->| in |<-- + |<-----------ll------------>| + +----+----+----------------------+----+ + | : : : | + +----+----+----------------------+----+ + -->| po |<-- + |<--------paper width---------------->| + +These dimensions are: + +'po' + "Page offset"--this is the leftmost position of text on the final + output, defining the "left margin". + +'in' + "Indentation"--this is the distance from the left margin where text + is printed. + +'ll' + "Line length"--this is the distance from the left margin to right + margin. + + The right margin is not explicitly configured; the combination of +page offset and line length provides the information necessary to derive +it. + + A simple demonstration: + + .ll 3i + This is text without indentation. + The line length has been set to 3\~inches. + .in +.5i + .ll -.5i + Now the left and right margins are both increased. + .in + .ll + Calling .in and .ll without parameters restores + the previous values. + + => This is text without indenta- + => tion. The line length has + => been set to 3 inches. + => Now the left and + => right margins are + => both increased. + => Calling .in and .ll without + => parameters restores the previ- + => ous values. + + -- Request: .po [offset] + -- Request: .po +offset + -- Request: .po -offset + -- Register: \n[.o] + Set page offset to OFFSET (or increment or decrement its current + value by OFFSET). If invoked without an argument, the page offset + is restored to the value before the previous 'po' request. This + request does not cause a break; the page offset in effect when an + output line is broken prevails (*note Manipulating Filling and + Adjustment::). The initial value is 1i and the default scaling + unit is 'm'. On terminal devices, the page offset is set to zero + by a driver-specific macro file, 'tty.tmac'. The current page + offset can be found in the read-only register '.o'. This request + is incorrectly documented in the AT&T 'troff' manual as using a + default scaling unit of 'v'. + + .po 3i + \n[.o] + => 720 + .po -1i + \n[.o] + => 480 + .po + \n[.o] + => 720 + + -- Request: .in [indent] + -- Request: .in +indent + -- Request: .in -indent + -- Register: \n[.i] + Set indentation to INDENT (or increment or decrement the current + value by INDENT). This request causes a break. Initially, there + is no indentation. + + If 'in' is called without an argument, the indentation is reset to + the previous value before the last call to 'in'. The default + scaling unit is 'm'. + + If a negative indentation value is specified (which is not + allowed), 'gtroff' emits a warning in category 'range' and sets the + indentation to zero. + + The effect of 'in' is delayed until a partially collected line (if + it exists) is output. A temporary indentation value is reset to + zero also. + + The current indentation (as set by 'in') can be found in the + read-only register '.i'. The indentation is associated with the + environment (*note Environments::). + + -- Request: .ti offset + -- Request: .ti +offset + -- Request: .ti -offset + -- Register: \n[.in] + Temporarily indent the next output line by OFFSET. If an increment + or decrement value is specified, adjust the temporary indentation + relative to the value set by the 'in' request. + + This request causes a break; its value is associated with the + environment (*note Environments::). The default scaling unit is + 'm'. A call of 'ti' without an argument is ignored. + + If the total indentation value is negative (which is not allowed), + 'gtroff' emits a warning in category 'range' and sets the temporary + indentation to zero. 'Total indentation' is either OFFSET if + specified as an absolute value, or the temporary plus normal + indentation, if OFFSET is given as a relative value. + + The effect of 'ti' is delayed until a partially collected line (if + it exists) is output. + + The read-only register '.in' is the indentation that applies to the + current output line. + + The difference between '.i' and '.in' is that the latter takes into + account whether a partially collected line still uses the old + indentation value or a temporary indentation value is active. + + -- Request: .ll [length] + -- Request: .ll +length + -- Request: .ll -length + -- Register: \n[.l] + -- Register: \n[.ll] + Set the line length to LENGTH (or increment or decrement the + current value by LENGTH). Initially, the line length is set to + 6.5i. The effect of 'll' is delayed until a partially collected + line (if it exists) is output. The default scaling unit is 'm'. + + If 'll' is called without an argument, the line length is reset to + the previous value before the last call to 'll'. If a negative + line length is specified (which is not allowed), 'gtroff' emits a + warning in category 'range' and sets the line length to zero. The + line length is associated with the environment (*note + Environments::). + + The current line length (as set by 'll') can be found in the + read-only register '.l'. The read-only register '.ll' is the line + length that applies to the current output line. + + Similar to '.i' and '.in', the difference between '.l' and '.ll' is + that the latter takes into account whether a partially collected + line still uses the old line length value. + + +File: groff.info, Node: Line Continuation, Next: Page Layout, Prev: Line Layout, Up: GNU troff Reference + +5.16 Line Continuation +====================== + +When filling is enabled, input and output line breaks generally do not +correspond. The 'roff' language therefore distinguishes input and +output line continuation. + + -- Escape sequence: \ + '\' (a backslash immediately followed by a newline) suppresses + the effects of that newline in the input. The next input line thus + retains the classification of its predecessor as a control or text + line. '\' is useful for managing line lengths in the input + during document maintenance; you can break an input line in the + middle of a request invocation, macro call, or escape sequence. + Input line continuation is invisible to the formatter, with two + exceptions: the '|' operator recognizes the new input line (*note + Numeric Expressions::), and the input line counter register '.c' is + incremented. + + .ll 50n + .de I + . ft I + . nop \\$* + . ft + .. + Our film class watched + .I The Effect of Gamma Rays on Man-in-the-Moon + Marigolds. \" whoops, the input line wrapped + .br + .I My own opus begins on line \n[.c] \ + and ends on line \n[.c]. + => Our film class watched The Effect of Gamma Rays on + => Man-in-the-Moon Marigolds. + => My own opus begins on line 11 and ends on line 12. + + -- Escape sequence: \c + -- Register: \n[.int] + '\c' continues an output line. Nothing after it on the input line + is formatted. In contrast to '\', a line after '\c' remains a + new input line, so a control character is recognized at its + beginning. The visual results depend on whether filling is + enabled; see *note Manipulating Filling and Adjustment::. + + * If filling is enabled, a word interrupted with '\c' is + continued with the text on the next input text line, without + an intervening space. + + This is a te\c + st. + => This is a test. + + * If filling is disabled, the next input text line after '\c' is + handled as a continuation of the same input text line. + + .nf + This is a \c + test. + => This is a test. + + An intervening control line that causes a break overrides '\c', + flushing out the pending output line in the usual way. + + The '.int' register contains a positive value if the last output + line was continued with '\c'; this datum is associated with the + environment (*note Environments::).(1) (*note Line + Continuation-Footnote-1::) + + +File: groff.info, Node: Line Continuation-Footnotes, Up: Line Continuation + + (1) Historically, the '\c' escape sequence has proven challenging to +characterize. Some sources say it "connects the next input text" (to +the input line on which it appears); others describe it as +"interrupting" text, on the grounds that a text line is interrupted +without breaking, perhaps to inject a request invocation or macro call. + + +File: groff.info, Node: Page Layout, Next: Page Control, Prev: Line Continuation, Up: GNU troff Reference + +5.17 Page Layout +================ + +The formatter permits configuration of the page length and page number. + + -- Request: .pl [length] + -- Request: .pl +length + -- Request: .pl -length + -- Register: \n[.p] + Change (increase or decrease) the page length per the numeric + expression LENGTH. The default scaling unit is 'v'. A negative + LENGTH is valid, but an uncommon application: it prevents page + location traps from being sprung,(1) (*note Page + Layout-Footnote-1::) and each output line is placed on a new page. + If LENGTH is invalid, GNU 'troff' emits a warning in category + 'number'. If LENGTH is absent or invalid, '11i' is assumed. + + The read-only register '.p' interpolates the current page length. + + -- Request: .pn num + -- Request: .pn +num + -- Request: .pn -num + -- Register: \n[.pn] + Change (increase or decrease) the page number of the _next_ page + per the numeric expression NUM. If NUM is invalid, GNU 'troff' + emits a warning in category 'number' and ignores the request. + Without an argument, 'pn' is ignored. + + The read-only register '.pn' interpolates NUM if set by 'pn' on the + current page, or the current page number plus 1. + + The formatter offers special support for typesetting headers and +footers, collectively termed "titles". Titles have an independent line +length, and their placement on the page is not restricted. + + -- Request: .tl 'left'center'right' + Format an output line as a title consisting of LEFT, CENTER, and + RIGHT, each aligned accordingly. The delimiter need not be a + neutral apostrophe: 'tl' accepts the same delimiters as most escape + sequences; see *note Delimiters::. If not used as the delimiter, + any "page number character" character is replaced with the current + page number; the default is '%'; see the the 'pc' request below. + Without an argument, 'tl' is ignored. 'tl' writes the title line + immediately, ignoring any partially collected line. + + It is not an error to omit delimiters after the first. For + example, '.tl /Thesis' is interpreted as '.tl /Thesis///': it sets + a title line comprising only the left-aligned word 'Thesis'. + + -- Request: .lt [length] + -- Request: .lt +length + -- Request: .lt -length + -- Register: \n[.lt] + Change (increase or decrease) the line length used by titles per + the numeric expression LENGTH. The default scaling unit is 'm'. + If LENGTH is negative, GNU emits a warning in category 'range' and + treats LENGTH as '0'. If LENGTH is invalid, GNU 'troff' emits a + warning in category 'number' and ignores the request. The + formatter's default title length is '6.5i'. With no argument, the + title length is restored to the previous value. The title length + is is associated with the environment (*note Environments::). + + The read-only register '.lt' interpolates the title line length. + + -- Request: .pc [char] + Set the page number character to CHAR. With no argument, the page + number character is disabled. 'pc' does not affect the + register '%'. + + The following example exercises title features. + + .lt 50n + This is my partially collected + .tl 'Isomers 2023'%'Dextrose Edition' + line. + => Isomers 2023 1 Dextrose Edition + => This is my partially collected line. + + We most often see titles used in page header and footer traps. *Note +Traps::. + + +File: groff.info, Node: Page Layout-Footnotes, Up: Page Layout + + (1) *Note Traps::. + + +File: groff.info, Node: Page Control, Next: Using Fonts, Prev: Page Layout, Up: GNU troff Reference + +5.18 Page Control +================= + +Discretionary page breaks can prevent the unwanted separation of +content. A new page number takes effect during page ejection; see *note +The Implicit Page Trap::. + + -- Request: .bp [page-number] + -- Request: .bp +page-number + -- Request: .bp -page-number + -- Register: \n[%] + Break the page and change (increase or decrease) the next page + number per the numeric expression PAGE-NUMBER. If PAGE-NUMBER is + invalid, GNU 'troff' emits a warning in category 'number' and + ignores the argument. This request causes a break. A page break + advances the vertical drawing position to the bottom of the page, + springing traps. *Note Page Location Traps::. 'bp' has effect + only if invoked within the top-level diversion.(1) (*note Page + Control-Footnote-1::) This request is incorrectly documented in the + AT&T 'troff' manual as having a default scaling unit of 'v'. + + The register '%' interpolates the current page number. + + .de BP + ' bp \" schedule page break once current line is output + .. + + -- Request: .ne [space] + Force a page break if insufficient vertical space is available + (assert "needed" space). 'ne' tests the distance to the next page + location trap; see *note Page Location Traps::, and breaks the page + if that amount is less than SPACE. The default scaling unit is + 'v'. If SPACE is invalid, GNU 'troff' emits a warning in category + 'number' and ignores the argument. If SPACE is not specified, '1v' + is assumed. + + We can require space for at least the first two output lines of a + paragraph, preventing its first line from being widowed at the page + bottom. + + .ne 2v + Considering how common illness is, + how tremendous the spiritual change that it brings, + how astonishing, + when the lights of health go down, + the undiscovered countries that are then disclosed, + what wastes and deserts of the soul a slight attack + of influenza brings to view, + + This method is reliable only if no output line is pending when 'ne' + is invoked. When macro packages are used, this is often not the + case: their paragraphing macros perform the break. You may need to + experiment with placing the 'ne' after the paragraphing macro, or + 'br' and 'ne' before it. + + 'ne' is also useful to force grouping of section headings with + their subsequent paragraphs, or tables with their captions and/or + explanations. Macro packages often use 'ne' with diversions to + implement keeps and displays; see *note Diversions::. They may + also offer parameters for widow and orphan management. + + -- Request: .sv [space] + -- Request: .os + Require vertical space as 'ne' does, but also save it for later + output by the 'os' request. If SPACE is available before the next + page location trap, it is output immediately. Both requests ignore + a partially collected line, taking effect at the next break. 'sv' + and 'os' ignore no-space mode (recall *note Manipulating + Spacing::). While the 'sv' request allows negative values for + SPACE, 'os' ignores them. The default scaling unit is 'v'. If + SPACE is not specified, '1v' is assumed. + + -- Register: \n[nl] + 'nl' interpolates or sets the vertical drawing position. When the + formatter starts, the first page transition hasn't happened yet, + and 'nl' is negative. If a header trap has been planted on the + page (typically at vertical position '0'), you can assign a + negative value to 'nl' to spring it if that page has already + started (*note Page Location Traps::). + + .de HD + . sp + . tl ''Goldbach Solution'' + . sp + .. + . + First page. + .bp + .wh 0 HD \" plant header trap at top of page + .nr nl (-1) + Second page. + => First page. + => + => (blank lines elided) + => + => Goldbach Solution + => + => (blank lines elided) + => + => Second page. + + Without resetting 'nl' to a negative value, the trap just planted + would be active beginning with the _next_ page, not the current + one. + + *Note Diversions::, for a comparison of 'nl' with the '.h' and '.d' + registers. + + +File: groff.info, Node: Page Control-Footnotes, Up: Page Control + + (1) *Note Diversions::. + + +File: groff.info, Node: Using Fonts, Next: Manipulating Type Size and Vertical Spacing, Prev: Page Control, Up: GNU troff Reference + +5.19 Using Fonts +================ + +In digital typography, a "font" is a collection of characters in a +specific typeface that a device can render as glyphs at a desired +size.(1) (*note Using Fonts-Footnote-1::) A 'roff' formatter can change +typefaces at any point in the text. The basic faces are a set of +"styles" combining upright and slanted shapes with normal and heavy +stroke weights: 'R', 'I', 'B', and 'BI'--these stand for roman, italic, +bold, and bold-italic. For linguistic text, GNU 'troff' groups +typefaces into "families" containing each of these styles.(2) (*note +Using Fonts-Footnote-2::) A "text font" is thus often a family combined +with a style, but it need not be: consider the 'ps' and 'pdf' devices' +'ZCMI' (Zapf Chancery Medium italic)--often, no other style of Zapf +Chancery Medium is provided. On typesetting devices, at least one +"special font" is available, comprising "unstyled" glyphs for +mathematical operators and other purposes. + + Like AT&T 'troff', GNU 'troff' does not itself load or manipulate a +digital font file;(3) (*note Using Fonts-Footnote-3::) instead it works +with a "font description file" that characterizes it, including its +glyph repertoire and the "metrics" (dimensions) of each glyph.(4) +(*note Using Fonts-Footnote-4::) This information permits the formatter +to accurately place glyphs with respect to each other. Before using a +font description, the formatter associates it with a "mounting +position", a place in an ordered list of available typefaces. So that a +document need not be strongly coupled to a specific font family, in GNU +'troff' an output device can associate a style in the abstract sense +with a mounting position. Thus the default family can be combined with +a style dynamically, producing a "resolved font name". + + Fonts often have trademarked names, and even Free Software fonts can +require renaming upon modification. 'groff' maintains a convention that +a device's serif font family is given the name 'T' ("Times"), its +sans-serif family 'H' ("Helvetica"), and its monospaced family 'C' +("Courier"). Historical inertia has driven 'groff''s font identifiers +to short uppercase abbreviations of font names, as with 'TR', 'TI', +'TB', 'TBI', and a special font 'S'. + + The default family used with abstract styles can be changed at any +time; initially, it is 'T'. Typically, abstract styles are arranged in +the first four mounting positions in the order shown above. The default +mounting position, and therefore style, is always '1' ('R'). By issuing +appropriate formatter instructions, you can override these defaults +before your document writes its first glyph. + + Terminal output devices cannot change font families and lack special +fonts. They support style changes by overstriking, or by altering +ISO 6429/ECMA-48 "graphic renditions" (character cell attributes). + +* Menu: + +* Selecting Fonts:: +* Font Families:: +* Font Positions:: +* Using Symbols:: +* Character Classes:: +* Special Fonts:: +* Artificial Fonts:: +* Ligatures and Kerning:: +* Italic Corrections:: +* Dummy Characters:: + + +File: groff.info, Node: Using Fonts-Footnotes, Up: Using Fonts + + (1) Terminals and some output devices have fonts that render at only +one or two sizes. As examples of the latter, take the 'groff' 'lj4' +device's Lineprinter, and 'lbp''s Courier and Elite faces. + + (2) Font designers prepare families such that the styles share +esthetic properties. + + (3) Historically, the fonts 'troff's dealt with were not Free +Software or, as with the Graphic Systems C/A/T, did not even exist in +the digital domain. + + (4) *Note Font Description File Format::. + diff --git a/doc/groff.info-2 b/doc/groff.info-2 new file mode 100644 index 0000000..44572a0 --- /dev/null +++ b/doc/groff.info-2 @@ -0,0 +1,7529 @@ +This is groff.info, produced by makeinfo version 7.0.3 from groff.texi. + +This manual documents GNU 'troff' version 1.23.0. + + Copyright Š 1994-2023 Free Software Foundation, Inc. + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.3 or any later version published by the Free Software + Foundation; with no Invariant Sections, no Front-Cover Texts, and + no Back-Cover Texts. A copy of the license is included in the + section entitled "GNU Free Documentation License". +INFO-DIR-SECTION Typesetting +START-INFO-DIR-ENTRY +* Groff: (groff). The GNU roff document formatting system. +END-INFO-DIR-ENTRY + + +File: groff.info, Node: Selecting Fonts, Next: Font Families, Prev: Using Fonts, Up: Using Fonts + +5.19.1 Selecting Fonts +---------------------- + +We use "font" to refer to any of several means of identifying a font: by +mounting position ('3'), by abstract style ('B'), or by its identifier +('TB'). + + -- Request: .ft [font] + -- Escape sequence: \ff + -- Escape sequence: \f(fn + -- Escape sequence: \f[font] + -- Register: \n[.fn] + The 'ft' request selects the typeface FONT. If the argument is + absent or 'P', it selects the previously chosen font. If FONT is a + non-negative integer, it is interpreted as mounting position; the + font mounted there is selected. If that position refers to an + abstract style, it is combined with the default family (see 'fam' + and '\F' below) to make a resolved font name. If the mounting + position is not a style and no font is mounted there, GNU 'troff' + emits a warning in category 'font' and ignores the request. + + If FONT matches a style name, it is combined with the current + family to make a resolved font name. Otherwise, FONT is assumed to + already be a resolved font name. + + The resolved font name is subject to translation (see request 'ftr' + below). Next, the (possibly translated) font name's mounting + position is looked up; if not mounted, FONT is sought on the file + system as a font description file and, if located, automatically + mounted at the next available position (see register '.fp' below). + If the font was mounted using an identifier different from its font + description file name (see request 'fp' below), that file name is + then looked up. If a font description file for the resolved font + name is not found, GNU 'troff' emits a warning in category 'font' + and ignores the request. + + The '\f' escape sequence is similar, using one-character name (or + mounting position) F, two-character name FN, or a name FONT of + arbitrary length. '\f[]' selects the previous font. The syntax + form '\fP' is supported for backward compatibility, and '\f[P]' for + consistency. + + eggs, bacon, + .ft I + spam, + .ft + and sausage. + .br + eggs, bacon, \fIspam,\fP and sausage. + => eggs, bacon, spam, and sausage + => eggs, bacon, spam, and sausage + + The current and previously selected fonts are properties of the + environment (*note Environments::). + + The read-only string-valued register '.fn' contains the resolved + font name of the selected font. + + '\f' doesn't produce an input token in GNU 'troff'; it thus can be + used in requests that expect a single-character argument. We can + assign a font to a margin character as follows (*note + Miscellaneous::). + + .mc \f[I]x\f[] + + -- Request: .ftr f [g] + Translate font F to font G. Whenever a font named F is referred to + in a '\f' escape sequence, in the 'F' and 'S' conditional + operators, or in the 'ft', 'ul', 'bd', 'cs', 'tkf', 'special', + 'fspecial', 'fp', or 'sty' requests, font G is used. If G is + missing or equal to F the translation is undone. + + Font translations cannot be chained. + + .ftr XXX TR + .ftr XXX YYY + .ft XXX + error-> warning: can't find font 'XXX' + + -- Request: .fzoom f [zoom] + -- Register: \n[.zoom] + Set magnification of font F to factor ZOOM, which must be a + non-negative integer multiple of 1/1000th. This request is useful + to adjust the optical size of a font in relation to the others. In + the example below, font 'CR' is magnified by 10% (the zoom factor + is thus 1.1). + + .fam P + .fzoom CR 1100 + .ps 12 + Palatino and \f[CR]Courier\f[] + + A missing or zero value of ZOOM is the same as a value of 1000, + which means no magnification. F must be a resolved font name, not + an abstract style. + + The magnification of a font is completely transparent to GNU + 'troff'; a change of the zoom factor doesn't cause any effect + except that the dimensions of glyphs, (word) spaces, kerns, etc., + of the affected font are adjusted accordingly. + + The zoom factor of the current font is available in the read-only + register '.zoom', in multiples of 1/1000th. It returns zero if + there is no magnification. + + +File: groff.info, Node: Font Families, Next: Font Positions, Prev: Selecting Fonts, Up: Using Fonts + +5.19.2 Font Families +-------------------- + +To accommodate the wide variety of fonts available, GNU 'troff' +distinguishes "font families" and "font styles". A resolved font name +is the catenation of a font family and a style. Selecting an abstract +style causes GNU 'troff' to combine it with the default font family. + + You can thus compose a document using abstract styles exclusively for +its body or running text, selecting a specific family only for titles or +examples, for instance, and change the default family on the command +line (recall *note Groff Options::). + + Fonts for the devices 'ps', 'pdf', 'dvi', 'lj4', 'lbp', and the X11 +devices support this mechanism. By default, GNU 'troff' uses the Times +family with the four styles 'R', 'I', 'B', and 'BI'. + + -- Request: .fam [family] + -- Register: \n[.fam] + -- Escape sequence: \Ff + -- Escape sequence: \F(fm + -- Escape sequence: \F[family] + Set the default font family, used in combination with abstract + styles to construct a resolved font name, to FAMILY (one-character + name F, two-character name FM). If no argument is given, GNU + 'troff' selects the previous font family; if there none, is it + falls back to the device's default(1) (*note Font + Families-Footnote-1::) or its own ('T'). + + The '\F' escape sequence works similarly. In disanalogy to '\f', + '\FP' makes 'P' the default family. Use '\F[]' to select the + previous default family. The default font family is available in + the read-only string-valued register '.fam'; it is associated with + the environment (*note Environments::). + + spam, \" startup defaults are T (Times) R (roman) + .fam H \" make Helvetica the default family + spam, \" family H + style R = HR + .ft B \" family H + style B = HB + spam, + .ft CR \" Courier roman (default family not changed) + spam, + .ft \" back to Helvetica bold + spam, + .fam T \" make Times the default family + spam, \" family T + style B = TB + .ft AR \" font AR (not a style) + baked beans, + .ft R \" family T + style R = TR + and spam. + + '\F' doesn't produce an input token in GNU 'troff'. As a + consequence, it can be used in requests like 'mc' (which expects a + single character as an argument) to change the font family on the + fly. + + .mc \F[P]x\F[] + + -- Request: .sty n style + -- Register: \n[.sty] + Associate an abstract style STYLE with mounting position N, which + must be a non-negative integer. If the requests 'cs', 'bd', 'tkf', + 'uf', or 'fspecial' are applied to an abstract style, they are + instead applied to the member of the current family corresponding + to that style. + + The default family can be set with the '-f' option (*note Groff + Options::). The 'styles' command in the 'DESC' file controls which + font positions (if any) are initially associated with abstract + styles rather than fonts. + + *Caution:* The STYLE argument is not validated. Errors may occur + later, when the formatter attempts to construct a resolved font + name, or format a character for output. + + .nr BarPos \n[.fp] + .sty \n[.fp] Bar + .fam Foo + .ft \n[BarPos] + .tm .f=\n[.f] + A + error-> error: no font family named 'Foo' exists + error-> .f=41 + error-> error: cannot format glyph: no current font + + When an abstract style has been selected, the read-only + string-valued register '.sty' interpolates its name; this datum is + associated with the environment (*note Environments::). Otherwise, + '.sty' interpolates nothing. + + +File: groff.info, Node: Font Families-Footnotes, Up: Font Families + + (1) *Note DESC File Format::. + + +File: groff.info, Node: Font Positions, Next: Using Symbols, Prev: Font Families, Up: Using Fonts + +5.19.3 Font Positions +--------------------- + +To support typeface indirection through abstract styles, and for +compatibility with AT&T 'troff', the formatter maintains a list of font +"positions" at which fonts required by a document are "mounted". An +output device's description file 'DESC' typically configures a set of +pre-mounted fonts; see *note Device and Font Description Files::. A +font need not be explicitly mounted before it is selected; GNU 'troff' +will search 'GROFF_FONT_PATH' for it by name and mount it at the first +free mounting position on demand. + + -- Request: .fp pos id [font-description-file-name] + -- Register: \n[.f] + -- Register: \n[.fp] + Mount a font under the name ID at mounting position POS, a + non-negative integer. When the formatter starts up, it reads the + output device's description to mount an initial set of faces, and + selects font position 1. Position 0 is unused by default. Unless + the FONT-DESCRIPTION-FILE-NAME argument is given, ID should be the + name of a font description file stored in a directory corresponding + to the selected output device. GNU 'troff' does not traverse + directories to locate the font description file. + + The optional third argument enables font names to be aliased, which + can be necessary in compatibility mode since AT&T 'troff' syntax + affords no means of identifying fonts with names longer than two + characters, like 'TBI' or 'ZCMI', in a font selection escape + sequence. *Note Compatibility Mode::. You can also alias fonts on + mounting for convenience or abstraction. (See below regarding the + '.fp' register.) + + .fp \n[.fp] SC ZCMI + Send a \f(SChand-written\fP thank-you note. + .fp \n[.fp] Emph TI + .fp \n[.fp] Strong TB + Are \f[Emph]these names\f[] \f[Strong]comfortable\f[]? + + 'DESC', 'P', and non-negative integers are not usable as font + identifiers. + + The position of the currently selected font (or abstract style) is + available in the read-only register '.f'. It is associated with + the environment (*note Environments::). + + You can copy the value of '.f' to another register to save it for + later use. + + .nr saved-font \n[.f] + ... text involving many font changes ... + .ft \n[saved-font] + + The index of the next (non-zero) free font position is available in + the read-only register '.fp'. Fonts not listed in the 'DESC' file + are automatically mounted at position '\n[.fp]' when selected with + the 'ft' request or '\f' escape sequence. When mounting a font at + a position explicitly with the 'fp' request, this same practice + should be followed, although GNU 'troff' does not enforce this + strictly. + + +File: groff.info, Node: Using Symbols, Next: Character Classes, Prev: Font Positions, Up: Using Fonts + +5.19.4 Using Symbols +-------------------- + +A "glyph" is a graphical representation of a "character". While a +character is an abstraction of semantic information, a glyph is +something that can be seen on screen or paper. A character has many +possible representation forms (for example, the character 'A' can be +written in an upright or slanted typeface, producing distinct glyphs). +Sometimes, a sequence of characters map to a single glyph: this is a +"ligature"--the most common is 'fi'. + + Space characters never become glyphs in GNU 'troff'. If not +discarded (as when trailing on text lines), they are represented by +horizontal motions in the output. + + A "symbol" is simply a named glyph. Within 'gtroff', all glyph names +of a particular font are defined in its font file. If the user requests +a glyph not available in this font, 'gtroff' looks up an ordered list of +"special fonts". By default, the PostScript output device supports the +two special fonts 'SS' (slanted symbols) and 'S' (symbols) (the former +is looked up before the latter). Other output devices use different +names for special fonts. Fonts mounted with the 'fonts' keyword in the +'DESC' file are globally available. To install additional special fonts +locally (i.e., for a particular font), use the 'fspecial' request. + + Here are the exact rules how 'gtroff' searches a given symbol: + + * If the symbol has been defined with the 'char' request, use it. + This hides a symbol with the same name in the current font. + + * Check the current font. + + * If the symbol has been defined with the 'fchar' request, use it. + + * Check whether the current font has a font-specific list of special + fonts; test all fonts in the order of appearance in the last + 'fspecial' call if appropriate. + + * If the symbol has been defined with the 'fschar' request for the + current font, use it. + + * Check all fonts in the order of appearance in the last 'special' + call. + + * If the symbol has been defined with the 'schar' request, use it. + + * As a last resort, consult all fonts loaded up to now for special + fonts and check them, starting with the lowest font number. This + can sometimes lead to surprising results since the 'fonts' line in + the 'DESC' file often contains empty positions, which are filled + later on. For example, consider the following: + + fonts 3 0 0 FOO + + This mounts font 'foo' at font position 3. We assume that 'FOO' is + a special font, containing glyph 'foo', and that no font has been + loaded yet. The line + + .fspecial BAR BAZ + + makes font 'BAZ' special only if font 'BAR' is active. We further + assume that 'BAZ' is really a special font, i.e., the font + description file contains the 'special' keyword, and that it also + contains glyph 'foo' with a special shape fitting to font 'BAR'. + After executing 'fspecial', font 'BAR' is loaded at font + position 1, and 'BAZ' at position 2. + + We now switch to a new font 'XXX', trying to access glyph 'foo' + that is assumed to be missing. There are neither font-specific + special fonts for 'XXX' nor any other fonts made special with the + 'special' request, so 'gtroff' starts the search for special fonts + in the list of already mounted fonts, with increasing font + positions. Consequently, it finds 'BAZ' before 'FOO' even for + 'XXX', which is not the intended behaviour. + + *Note Device and Font Description Files::, and *note Special Fonts::, +for more details. + + The 'groff_char(7)' man page houses a complete list of predefined +special character names, but the availability of any as a glyph is +device- and font-dependent. For example, say + + man -Tdvi groff_char > groff_char.dvi + +to obtain those available with the DVI device and default font +configuration.(1) (*note Using Symbols-Footnote-1::) If you want to use +an additional macro package to change the fonts used, 'groff' (or +'gtroff') must be run directly. + + groff -Tdvi -mec -man groff_char.7 > groff_char.dvi + + Special character names not listed in 'groff_char(7)' are derived +algorithmically, using a simplified version of the Adobe Glyph List +(AGL) algorithm, which is described in +. The (frozen) set of +names that can't be derived algorithmically is called the "'groff' glyph +list (GGL)". + + * A glyph for Unicode character U+XXXX[X[X]], which is not a + composite character is named 'uXXXX[X[X]]'. X must be an uppercase + hexadecimal digit. Examples: 'u1234', 'u008E', 'u12DB8'. The + largest Unicode value is 0x10FFFF. There must be at least four 'X' + digits; if necessary, add leading zeroes (after the 'u'). No zero + padding is allowed for character codes greater than 0xFFFF. + Surrogates (i.e., Unicode values greater than 0xFFFF represented + with character codes from the surrogate area U+D800-U+DFFF) are not + allowed either. + + * A glyph representing more than a single input character is named + + 'u' COMPONENT1 '_' COMPONENT2 '_' COMPONENT3 ... + + Example: 'u0045_0302_0301'. + + For simplicity, all Unicode characters that are composites must be + maximally decomposed to NFD;(2) (*note Using Symbols-Footnote-2::) + for example, 'u00CA_0301' is not a valid glyph name since U+00CA + (LATIN CAPITAL LETTER E WITH CIRCUMFLEX) can be further decomposed + into U+0045 (LATIN CAPITAL LETTER E) and U+0302 (COMBINING + CIRCUMFLEX ACCENT). 'u0045_0302_0301' is thus the glyph name for + U+1EBE, LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE. + + * groff maintains a table to decompose all algorithmically derived + glyph names that are composites itself. For example, 'u0100' + (LATIN LETTER A WITH MACRON) is automatically decomposed into + 'u0041_0304'. Additionally, a glyph name of the GGL is preferred + to an algorithmically derived glyph name; 'groff' also + automatically does the mapping. Example: The glyph 'u0045_0302' is + mapped to '^E'. + + * glyph names of the GGL can't be used in composite glyph names; for + example, '^E_u0301' is invalid. + + -- Escape sequence: \(nm + -- Escape sequence: \[name] + -- Escape sequence: \[base-glyph combining-component ...] + Typeset a special character NAME (two-character name NM) or a + composite glyph consisting of BASE-GLYPH overlaid with one or more + COMBINING-COMPONENTs. For example, '\[A ho]' is a capital letter + "A" with a "hook accent" (ogonek). + + There is no special syntax for one-character names--the analogous + form '\N' would collide with other escape sequences. However, the + four escape sequences '\'', '\-', '\_', and '\`', are translated on + input to the special character escape sequences '\[aa]', '\[-]', + '\[ul]', and '\[ga]', respectively. + + A special character name of length one is not the same thing as an + ordinary character: that is, the character 'a' is not the same as + '\[a]'. + + If NAME is undefined, a warning in category 'char' is produced and + the escape is ignored. *Note Warnings::, for information about the + enablement and suppression of warnings. + + GNU 'troff' resolves '\[...]' with more than a single component as + follows: + + * Any component that is found in the GGL is converted to the + 'uXXXX' form. + + * Any component 'uXXXX' that is found in the list of + decomposable glyphs is decomposed. + + * The resulting elements are then concatenated with '_' in + between, dropping the leading 'u' in all elements but the + first. + + No check for the existence of any component (similar to 'tr' + request) is done. + + Examples: + + '\[A ho]' + 'A' maps to 'u0041', 'ho' maps to 'u02DB', thus the final + glyph name would be 'u0041_02DB'. This is not the expected + result: the ogonek glyph 'ho' is a spacing ogonek, but for a + proper composite a non-spacing ogonek (U+0328) is necessary. + Looking into the file 'composite.tmac', one can find + '.composite ho u0328', which changes the mapping of 'ho' while + a composite glyph name is constructed, causing the final glyph + name to be 'u0041_0328'. + + '\[^E u0301]' + '\[^E aa]' + '\[E a^ aa]' + '\[E ^ ']' + '^E' maps to 'u0045_0302', thus the final glyph name is + 'u0045_0302_0301' in all forms (assuming proper calls of the + 'composite' request). + + It is not possible to define glyphs with names like 'A ho' within a + 'groff' font file. This is not really a limitation; instead, you + have to define 'u0041_0328'. + + -- Escape sequence: \C'xxx' + Typeset the glyph of the special character XXX. Normally, it is + more convenient to use '\[XXX]', but '\C' has some advantages: it + is compatible with AT&T device-independent 'troff' (and therefore + available in compatibility mode(3) (*note Using + Symbols-Footnote-3::)) and can interpolate special characters with + ']' in their names. The delimiter need not be a neutral + apostrophe; see *note Delimiters::. + + -- Request: .composite id1 id2 + Map special character name ID1 to ID2 if ID1 is used in '\[...]' + with more than one component. See above for examples. This is a + strict rewriting of the special character name; no check is + performed for the existence of a glyph for either. A set of + default mappings for many accents can be found in the file + 'composite.tmac', loaded by the default 'troffrc' at startup. + + -- Escape sequence: \N'n' + Typeset the glyph with code N in the current font ('n' is _not_ the + input character code). The number N can be any non-negative + decimal integer. Most devices only have glyphs with codes between + 0 and 255; the Unicode output device uses codes in the range + 0-65535. If the current font does not contain a glyph with that + code, special fonts are _not_ searched. The '\N' escape sequence + can be conveniently used in conjunction with the 'char' request: + + .char \[phone] \f[ZD]\N'37' + + The code of each glyph is given in the fourth column in the font + description file after the 'charset' command. It is possible to + include unnamed glyphs in the font description file by using a name + of '---'; the '\N' escape sequence is the only way to use these. + + No kerning is applied to glyphs accessed with '\N'. The delimiter + need not be a neutral apostrophe; see *note Delimiters::. + + A few escape sequences are also special characters. + + -- Escape sequence: \' + An escaped neutral apostrophe is a synonym for '\[aa]' (acute + accent). + + -- Escape sequence: \` + An escaped grave accent is a synonym for '\[ga]' (grave accent). + + -- Escape sequence: \- + An escaped hyphen-minus is a synonym for '\[-]' (minus sign). + + -- Escape sequence: \_ + An escaped underscore ("low line") is a synonym for '\[ul]' + (underrule). On typesetting devices, the underrule is + font-invariant and drawn lower than the underscore '_'. + + -- Request: .cflags n c1 c2 ... + Assign properties encoded by the number N to characters C1, C2, and + so on. + + Input characters, including special characters introduced by an + escape, have certain properties associated with them.(4) (*note + Using Symbols-Footnote-4::) These properties can be modified with + this request. The first argument is the sum of the desired flags + and the remaining arguments are the characters to be assigned those + properties. Spaces between the CN arguments are optional. Any + argument CN can be a character class defined with the 'class' + request rather than an individual character. *Note Character + Classes::. + + The non-negative integer N is the sum of any of the following. + Some combinations are nonsensical, such as '33' (1 + 32). + + '1' + Recognize the character as ending a sentence if followed by a + newline or two spaces. Initially, characters '.?!' have this + property. + + '2' + Enable breaks before the character. A line is not broken at a + character with this property unless the characters on each + side both have non-zero hyphenation codes. This exception can + be overridden by adding 64. Initially, no characters have + this property. + + '4' + Enable breaks after the character. A line is not broken at a + character with this property unless the characters on each + side both have non-zero hyphenation codes. This exception can + be overridden by adding 64. Initially, characters + '\-\[hy]\[em]' have this property. + + '8' + Mark the glyph associated with this character as overlapping + other instances of itself horizontally. Initially, characters + '\[ul]\[rn]\[ru]\[radicalex]\[sqrtex]' have this property. + + '16' + Mark the glyph associated with this character as overlapping + other instances of itself vertically. Initially, the + character '\[br]' has this property. + + '32' + Mark the character as transparent for the purpose of + end-of-sentence recognition. In other words, an + end-of-sentence character followed by any number of characters + with this property is treated as the end of a sentence if + followed by a newline or two spaces. This is the same as + having a zero space factor in TeX. Initially, characters + '"')]*\[dg]\[dd]\[rq]\[cq]' have this property. + + '64' + Ignore hyphenation codes of the surrounding characters. Use + this in combination with values 2 and 4 (initially, no + characters have this property). + + For example, if you need an automatic break point after the + en-dash in numeric ranges like "3000-5000", insert + + .cflags 68 \[en] + + into your document. However, this practice can lead to bad + layout if done thoughtlessly; in most situations, a better + solution instead of changing the 'cflags' value is to insert + '\:' right after the hyphen at the places that really need a + break point. + + The remaining values were implemented for East Asian language + support; those who use alphabetic scripts exclusively can disregard + them. + + '128' + Prohibit a line break before the character, but allow a line + break after the character. This works only in combination + with flags 256 and 512 and has no effect otherwise. + Initially, no characters have this property. + + '256' + Prohibit a line break after the character, but allow a line + break before the character. This works only in combination + with flags 128 and 512 and has no effect otherwise. + Initially, no characters have this property. + + '512' + Allow line break before or after the character. This works + only in combination with flags 128 and 256 and has no effect + otherwise. Initially, no characters have this property. + + In contrast to values 2 and 4, the values 128, 256, and 512 work + pairwise. If, for example, the left character has value 512, and + the right character 128, no break will be automatically inserted + between them. If we use value 6 instead for the left character, a + break after the character can't be suppressed since the neighboring + character on the right doesn't get examined. + + -- Request: .char c [contents] + -- Request: .fchar c [contents] + -- Request: .fschar f c [contents] + -- Request: .schar c [contents] + Define a new character or glyph C to be CONTENTS, which can be + empty. More precisely, 'char' defines a 'groff' object (or + redefines an existing one) that is accessed with the name C on + input, and produces CONTENTS on output. Every time glyph C needs + to be printed, CONTENTS is processed in a temporary environment and + the result is wrapped up into a single object. Compatibility mode + is turned off and the escape character is set to '\' while CONTENTS + is processed. Any emboldening, constant spacing, or track kerning + is applied to this object rather than to individual glyphs in + CONTENTS. + + An object defined by these requests can be used just like a normal + glyph provided by the output device. In particular, other + characters can be translated to it with the 'tr' or 'trin' + requests; it can be made the leader character with the 'lc' + request; repeated patterns can be drawn with it using the '\l' and + '\L' escape sequences; and words containing C can be hyphenated + correctly if the 'hcode' request is used to give the object a + hyphenation code. + + There is a special anti-recursion feature: use of the object within + its own definition is handled like a normal character (not defined + with 'char'). + + The 'tr' and 'trin' requests take precedence if 'char' accesses the + same symbol. + + .tr XY + X + => Y + .char X Z + X + => Y + .tr XX + X + => Z + + The 'fchar' request defines a fallback glyph: 'gtroff' only checks + for glyphs defined with 'fchar' if it cannot find the glyph in the + current font. 'gtroff' carries out this test before checking + special fonts. + + 'fschar' defines a fallback glyph for font F: 'gtroff' checks for + glyphs defined with 'fschar' after the list of fonts declared as + font-specific special fonts with the 'fspecial' request, but before + the list of fonts declared as global special fonts with the + 'special' request. + + Finally, the 'schar' request defines a global fallback glyph: + 'gtroff' checks for glyphs defined with 'schar' after the list of + fonts declared as global special fonts with the 'special' request, + but before the already mounted special fonts. + + *Note Character Classes::. + + -- Request: .rchar c ... + -- Request: .rfschar f c ... + Remove definition of each ordinary or special character C, undoing + the effect of a 'char', 'fchar', or 'schar' request. Those + supplied by font description files cannot be removed. Spaces and + tabs may separate C arguments. + + The request 'rfschar' removes glyph definitions defined with + 'fschar' for font F. + + +File: groff.info, Node: Using Symbols-Footnotes, Up: Using Symbols + + (1) Not all versions of the 'man' program support the '-T' option; +use the subsequent example for an alternative. + + (2) This is "Normalization Form D" as documented in Unicode Standard +Annex #15 (). + + (3) *Note Compatibility Mode::. + + (4) Output glyphs don't--to GNU 'troff', a glyph is simply a box with +an index into a font, a given height above and depth below the baseline, +and a width. + + +File: groff.info, Node: Character Classes, Next: Special Fonts, Prev: Using Symbols, Up: Using Fonts + +5.19.5 Character Classes +------------------------ + +Classes are particularly useful for East Asian languages such as +Chinese, Japanese, and Korean, where the number of needed characters is +much larger than in European languages, and where large sets of +characters share the same properties. + + -- Request: .class name c1 c2 ... + Define a character class (or simply "class") NAME comprising the + characters C1, C2, and so on. + + A class thus defined can then be referred to in lieu of listing all + the characters within it. Currently, only the 'cflags' request can + handle references to character classes. + + In the request's simplest form, each CN is a character (or special + character). + + .class [quotes] ' \[aq] \[dq] \[oq] \[cq] \[lq] \[rq] + + Since class and glyph names share the same name space, it is + recommended to start and end the class name with '[' and ']', + respectively, to avoid collisions with existing character names + defined by GNU 'troff' or the user (with 'char' and related + requests). This practice applies the presence of ']' in the class + name to prevent the use of the special character escape form + '\[...]', thus you must use the '\C' escape to access a class with + such a name. + + You can also use a character range notation consisting of a start + character followed by '-' and then an end character. Internally, + GNU 'troff' converts these two symbol names to Unicode code points + (according to the 'groff' glyph list [GGL]), which then give the + start and end value of the range. If that fails, the class + definition is skipped. + + Furthermore, classes can be nested. + + .class [prepunct] , : ; > } + .class [prepunctx] \C'[prepunct]' \[u2013]-\[u2016] + + The class '[prepunctx]' thus contains the contents of the class + '[prepunct]' as defined above (the set ', : ; > }'), and characters + in the range between 'U+2013' and 'U+2016'. + + If you want to include '-' in a class, it must be the first + character value in the argument list, otherwise it gets + misinterpreted as part of the range syntax. + + It is not possible to use class names as end points of range + definitions. + + A typical use of the 'class' request is to control line-breaking + and hyphenation rules as defined by the 'cflags' request. For + example, to inhibit line breaks before the characters belonging to + the 'prepunctx' class defined in the previous example, you can + write the following. + + .cflags 2 \C'[prepunctx]' + + See the 'cflags' request in *note Using Symbols::, for more + details. + + +File: groff.info, Node: Special Fonts, Next: Artificial Fonts, Prev: Character Classes, Up: Using Fonts + +5.19.6 Special Fonts +-------------------- + +Special fonts are those that 'gtroff' searches when it cannot find the +requested glyph in the current font. The Symbol font is usually a +special font. + + 'gtroff' provides the following two requests to add more special +fonts. *Note Using Symbols::, for a detailed description of the glyph +searching mechanism in 'gtroff'. + + Usually, only non-TTY devices have special fonts. + + -- Request: .special [s1 s2 ...] + -- Request: .fspecial f [s1 s2 ...] + Use the 'special' request to define special fonts. Initially, this + list is empty. + + Use the 'fspecial' request to designate special fonts only when + font F is active. Initially, this list is empty. + + Previous calls to 'special' or 'fspecial' are overwritten; without + arguments, the particular list of special fonts is set to empty. + Special fonts are searched in the order they appear as arguments. + + All fonts that appear in a call to 'special' or 'fspecial' are + loaded. + + *Note Using Symbols::, for the exact search order of glyphs. + + +File: groff.info, Node: Artificial Fonts, Next: Ligatures and Kerning, Prev: Special Fonts, Up: Using Fonts + +5.19.7 Artificial Fonts +----------------------- + +There are a number of requests and escape sequences for artificially +creating fonts. These are largely vestiges of the days when output +devices did not have a wide variety of fonts, and when 'nroff' and +'troff' were separate programs. Most of them are no longer necessary in +GNU 'troff'. Nevertheless, they are supported. + + -- Escape sequence: \H'height' + -- Escape sequence: \H'+height' + -- Escape sequence: \H'-height' + -- Register: \n[.height] + Change (increment, decrement) the height of the current font, but + not the width. If HEIGHT is zero, restore the original height. + Default scaling unit is 'z'. + + The read-only register '.height' contains the font height as set by + '\H'. + + Currently, only the '-Tps' and '-Tpdf' devices support this + feature. + + '\H' doesn't produce an input token in GNU 'troff'. As a + consequence, it can be used in requests like 'mc' (which expects a + single character as an argument) to change the font on the fly: + + .mc \H'+5z'x\H'0' + + In compatibility mode, 'gtroff' behaves differently: If an + increment or decrement is used, it is always taken relative to the + current type size and not relative to the previously selected font + height. Thus, + + .cp 1 + \H'+5'test \H'+5'test + + prints the word 'test' twice with the same font height (five points + larger than the current font size). + + -- Escape sequence: \S'slant' + -- Register: \n[.slant] + Slant the current font by SLANT degrees. Positive values slant to + the right. Only integer values are possible. + + The read-only register '.slant' contains the font slant as set by + '\S'. + + Currently, only the '-Tps' and '-Tpdf' devices support this + feature. + + '\S' doesn't produce an input token in GNU 'troff'. As a + consequence, it can be used in requests like 'mc' (which expects a + single character as an argument) to change the font on the fly: + + .mc \S'20'x\S'0' + + This escape is incorrectly documented in the AT&T 'troff' manual; + the slant is always set to an absolute value. + + -- Request: .ul [lines] + The 'ul' request normally underlines subsequent lines if a TTY + output device is used. Otherwise, the lines are printed in italics + (only the term 'underlined' is used in the following). The single + argument is the quantity of input lines to be underlined; with no + argument, the next line is underlined. If LINES is zero or + negative, stop the effects of 'ul' (if it was active). Requests + and empty lines do not count for computing the number of underlined + input lines, even if they produce some output like 'tl'. Lines + inserted by macros (e.g., invoked by a trap) do count. + + At the beginning of 'ul', the current font is stored and the + underline font is activated. Within the span of a 'ul' request, it + is possible to change fonts, but after the last line affected by + 'ul' the saved font is restored. + + This number of lines still to be underlined is associated with the + environment (*note Environments::). The underline font can be + changed with the 'uf' request. + + The 'ul' request does not underline spaces. + + -- Request: .cu [lines] + The 'cu' request is similar to 'ul' but underlines spaces as well + (if a TTY output device is used). + + -- Request: .uf font + Set the underline font (globally) used by 'ul' and 'cu'. By + default, this is the font at position 2. FONT can be either a + non-negative font position or the name of a font. + + -- Request: .bd font [offset] + -- Request: .bd font1 font2 [offset] + -- Register: \n[.b] + Embolden FONT by overstriking its glyphs offset by OFFSET units + minus one. + + Two syntax forms are available. + + * Imitate a bold font unconditionally. The first argument + specifies the font to embolden, and the second is the number + of basic units, minus one, by which the two glyphs are offset. + If the second argument is missing, emboldening is turned off. + + FONT can be either a non-negative font position or the name of + a font. + + OFFSET is available in the '.b' read-only register if a + special font is active; in the 'bd' request, its default unit + is 'u'. + + * Imitate a bold form conditionally. Embolden FONT1 by OFFSET + only if font FONT2 is the current font. This request can be + issued repeatedly to set up different emboldening values for + different current fonts. If the second argument is missing, + emboldening is turned off for this particular current font. + + This affects special fonts only (either set up with the + 'special' command in font files or with the 'fspecial' + request). + + -- Request: .cs font [width [em-size]] + Switch to and from "constant glyph space mode". If activated, the + width of every glyph is WIDTH/36 ems. The em size is given + absolutely by EM-SIZE; if this argument is missing, the em value is + taken from the current font size (as set with the 'ps' request) + when the font is effectively in use. Without second and third + argument, constant glyph space mode is deactivated. + + Default scaling unit for EM-SIZE is 'z'; WIDTH is an integer. + + +File: groff.info, Node: Ligatures and Kerning, Next: Dummy Characters, Prev: Artificial Fonts, Up: Using Fonts + +5.19.8 Ligatures and Kerning +---------------------------- + +Ligatures are groups of characters that are run together, i.e, producing +a single glyph. For example, the letters 'f' and 'i' can form a +ligature 'fi' as in the word 'file'. This produces a cleaner look +(albeit subtle) to the printed output. Usually, ligatures are not +available in fonts for TTY output devices. + + Most PostScript fonts support the fi and fl ligatures. The C/A/T +typesetter that was the target of AT&T 'troff' also supported 'ff', +'ffi', and 'ffl' ligatures. Advanced typesetters or 'expert' fonts may +include ligatures for 'ft' and 'ct', although GNU 'troff' does not +support these (yet). + + Only the current font is checked for ligatures and kerns; neither +special fonts nor special charcters defined with the 'char' request (and +its siblings) are taken into account. + + -- Request: .lg [flag] + -- Register: \n[.lg] + Switch the ligature mechanism on or off; if the parameter is + non-zero or missing, ligatures are enabled, otherwise disabled. + Default is on. The current ligature mode can be found in the + read-only register '.lg' (set to 1 or 2 if ligatures are enabled, + 0 otherwise). + + Setting the ligature mode to 2 enables the two-character ligatures + (fi, fl, and ff) and disables the three-character ligatures (ffi + and ffl). + + "Pairwise kerning" is another subtle typesetting mechanism that +modifies the distance between a glyph pair to improve readability. In +most cases (but not always) the distance is decreased. Typewriter-like +fonts and fonts for terminals where all glyphs have the same width don't +use kerning. + + -- Request: .kern [flag] + -- Register: \n[.kern] + Switch kerning on or off. If the parameter is non-zero or missing, + enable pairwise kerning, otherwise disable it. The read-only + register '.kern' is set to 1 if pairwise kerning is enabled, + 0 otherwise. + + If the font description file contains pairwise kerning information, + glyphs from that font are kerned. Kerning between two glyphs can + be inhibited by placing '\&' between them: 'V\&A'. + + *Note Font Description File Format::. + + "Track kerning" expands or reduces the space between glyphs. This +can be handy, for example, if you need to squeeze a long word onto a +single line or spread some text to fill a narrow column. It must be +used with great care since it is usually considered bad typography if +the reader notices the effect. + + -- Request: .tkf f s1 n1 s2 n2 + Enable track kerning for font F. If the current font is F the + width of every glyph is increased by an amount between N1 and N2 + (N1, N2 can be negative); if the current type size is less than or + equal to S1 the width is increased by N1; if it is greater than or + equal to S2 the width is increased by N2; if the type size is + greater than or equal to S1 and less than or equal to S2 the + increase in width is a linear function of the type size. + + The default scaling unit is 'z' for S1 and S2, 'p' for N1 and N2. + + The track kerning amount is added even to the rightmost glyph in a + line; for large values it is thus recommended to increase the line + length by the same amount to compensate. + + +File: groff.info, Node: Italic Corrections, Next: Dummy Characters, Prev: Ligatures and Kerning, Up: Using Fonts + +5.19.9 Italic Corrections +------------------------- + +When typesetting adjacent glyphs from typefaces of different slants, the +space between them may require adjustment. + + -- Escape sequence: \/ + Apply an "italic correction": modify the spacing of the preceding + glyph so that the distance between it and the following glyph is + correct if the latter is of upright shape. For example, if an + italic 'f' is followed immediately by a roman right parenthesis, + then in many fonts the top right portion of the 'f' overlaps the + top left of the right parenthesis, which is ugly. Use this escape + sequence whenever an oblique glyph is immediately followed by an + upright glyph without any intervening space. + + -- Escape sequence: \, + Apply a "left italic correction": modify the spacing of the + following glyph so that the distance between it and the preceding + glyph is correct if the latter is of upright shape. For example, + if a roman left parenthesis is immediately followed by an + italic 'f', then in many fonts the bottom left portion of the 'f' + overlaps the bottom of the left parenthesis, which is ugly. Use + this escape sequence whenever an upright glyph is followed + immediately by an oblique glyph without any intervening space. + + +File: groff.info, Node: Dummy Characters, Prev: Italic Corrections, Up: Using Fonts + +5.19.10 Dummy Characters +------------------------ + +As discussed in *note Requests and Macros::, the first character on an +input line is treated specially. Further, formatting a glyph has many +consequences on formatter state (*note Environments::). Occasionally, +we want to escape this context or embrace some of those consequences +without actually rendering a glyph to the output. + + -- Escape sequence: \& + Interpolate a dummy character, which is constitutive of output but + invisible.(1) (*note Dummy Characters-Footnote-1::) Its presence + alters the interpretation context of a subsequent input character, + and enjoys several applications. + + * Prevent insertion of extra space after an end-of-sentence + character. + + Test. + Test. + => Test. Test. + Test.\& + Test. + => Test. Test. + + * Prevent recognition of a control character. + + .Test + error-> warning: macro 'Test' not defined + \&.Test + => .Test + + * Prevent kerning between two glyphs. + + * Translate a character to "nothing". + + .tr JIjiK\&k\&UVuv + Post universitum, alea jacta est, OK? + => Post vniversitvm, alea iacta est, O? + + The dummy character escape sequence sees use in macro definitions + as a means of ensuring that arguments are treated as text even if + they begin with spaces or control characters. + + .de HD \" typeset a simple bold heading + . sp + . ft B + \&\\$1 \" exercise: remove the \& + . ft + . sp + .. + .HD .\|.\|.\|surprised? + + One way to think about the dummy character is to imagine placing the +symbol '&' in the input at a certain location; if doing so has all the +side effects on formatting that you desire except for sticking an ugly +ampersand in the midst of your text, the dummy character is what you +want in its place. + + -- Escape sequence: \) + Interpolate a transparent dummy character--one that is transparent + to end-of-sentence detection. It behaves as '\&', except that '\&' + is treated as letters and numerals normally are after '.', '?' and + '!'; '\&' cancels end-of-sentence detection, and '\)' does not. + + .de Suffix-& + . nop \&\\$1 + .. + . + .de Suffix-) + . nop \)\\$1 + .. + . + Here's a sentence.\c + .Suffix-& ' + Another one.\c + .Suffix-) ' + And a third. + => Here's a sentence.' Another one.' And a third. + + +File: groff.info, Node: Dummy Characters-Footnotes, Up: Dummy Characters + + (1) Opinions of this escape sequence's name abound. "Zero-width +space" is a popular misnomer: 'roff' formatters do not treat it like a +space. Ossanna called it a "non-printing, zero-width character", but +the character causes _output_ even though it does not "print". If no +output line is pending, the dummy character starts one. Contrast an +empty input document with one containing only '\&'. The former produces +no output; the latter, a blank page. + + +File: groff.info, Node: Manipulating Type Size and Vertical Spacing, Next: Colors, Prev: Using Fonts, Up: GNU troff Reference + +5.20 Manipulating Type Size and Vertical Spacing +================================================ + +These concepts were introduced in *note Page Geometry::. The height of +a font's tallest glyph is one em, which is equal to the type size in +points.(1) (*note Manipulating Type Size and Vertical +Spacing-Footnote-1::) A vertical spacing of less than 120% of the type +size can make a document hard to read. Larger proportions can be useful +to spread the text for annotations or proofreader's marks. By default, +GNU 'troff' uses 10 point type on 12 point spacing. Typographers call +the difference between type size and vertical spacing "leading".(2) +(*note Manipulating Type Size and Vertical Spacing-Footnote-2::) + +* Menu: + +* Changing the Type Size:: +* Changing the Vertical Spacing:: +* Using Fractional Type Sizes:: + + +File: groff.info, Node: Manipulating Type Size and Vertical Spacing-Footnotes, Up: Manipulating Type Size and Vertical Spacing + + (1) In text fonts, the tallest glyphs are typically parentheses. +Unfortunately, in many cases the actual dimensions of the glyphs in a +font do not closely match its declared type size! For example, in the +standard PostScript font families, 10-point Times sets better with +9-point Helvetica and 11-point Courier than if all three were used at +10 points. + + (2) Rhyme with "sledding"; mechanical typography used lead metal +(Latin _plumbum_). + + +File: groff.info, Node: Changing the Type Size, Next: Changing the Vertical Spacing, Prev: Manipulating Type Size and Vertical Spacing, Up: Manipulating Type Size and Vertical Spacing + +5.20.1 Changing the Type Size +----------------------------- + + -- Request: .ps [size] + -- Request: .ps +size + -- Request: .ps -size + -- Escape sequence: \ssize + -- Register: \n[.s] + Use the 'ps' request or the '\s' escape sequence to change + (increase, decrease) the type size (in scaled points). Specify + SIZE as either an absolute type size, or as a relative change from + the current size. 'ps' with no argument restores the previous + size. The 'ps' request's default scaling unit is 'z'. The + requested size is rounded to the nearest valid size (with ties + rounding down) within the limits supported by the device. If the + requested size is non-positive, it is treated as 1u. + + Type size alteration is incorrectly documented in the AT&T 'troff' + manual, which claims "if [the requested size] is invalid, the next + larger valid size will result, with a maximum of 36".(1) (*note + Changing the Type Size-Footnote-1::) + + The read-only string-valued register '.s' interpolates the type + size in points as a decimal fraction; it is associated with the + environment (*note Environments::). To obtain the type size in + scaled points, interpolate the '.ps' register instead (*note Using + Fractional Type Sizes::). + + The '\s' escape sequence supports a variety of syntax forms. + + '\sN' + Set the type size to N points. N must be a single digit. If + N is 0, restore the previous size. + + '\s+N' + '\s-N' + Increase or decrease the type size by N points. N must be + exactly one digit. + + '\s(NN' + Set the type size to NN points. NN must be exactly two + digits. + + '\s+(NN' + '\s-(NN' + '\s(+NN' + '\s(-NN' + Alter the type size in points by the two-digit value NN. + + *Note Using Fractional Type Sizes::, for further syntactical forms + of the '\s' escape sequence that additionally accept decimal + fractions. + + snap, snap, + .ps +2 + grin, grin, + .ps +2 + wink, wink, \s+2nudge, nudge,\s+8 say no more! + .ps 10 + + The '\s' escape sequence affects the environment immediately and +doesn't produce an input token. Consequently, it can be used in +requests like 'mc', which expects a single character as an argument, to +change the type size on the fly. + + .mc \s[20]x\s[0] + + -- Request: .sizes s1 s2 ... sn [0] + The 'DESC' file specifies which type sizes are allowed by the + output device; see *note DESC File Format::. Use the 'sizes' + request to change this set of permissible sizes. Arguments are in + scaled points; see *note Using Fractional Type Sizes::. Each can + be a single type size (such as '12000'), or a range of sizes (such + as '4000-72000'). You can optionally end the list with a '0'. + + +File: groff.info, Node: Changing the Type Size-Footnotes, Up: Changing the Type Size + + (1) The claim appears to have been true of Ossanna 'troff' for the +C/A/T device; Kernighan made device-independent 'troff' more flexible. + + +File: groff.info, Node: Changing the Vertical Spacing, Next: Using Fractional Type Sizes, Prev: Changing the Type Size, Up: Manipulating Type Size and Vertical Spacing + +5.20.2 Changing the Vertical Spacing +------------------------------------ + + -- Request: .vs [space] + -- Request: .vs +space + -- Request: .vs -space + -- Register: \n[.v] + Set the vertical spacing to, or alter it by, SPACE. The default + scaling unit is 'p'. If 'vs' is called without an argument, the + vertical spacing is reset to the previous value before the last + call to 'vs'. GNU 'troff' emits a warning in category 'range' if + SPACE is negative; the vertical spacing is then set to the smallest + possible positive value, the vertical motion quantum (as found in + the '.V' register). + + '.vs 0' isn't saved in a diversion since it doesn't result in a + vertical motion. You must explicitly issue this request before + interpolating the diversion. + + The read-only register '.v' contains the vertical spacing; it is + associated with the environment (*note Environments::). + +When a break occurs, GNU 'troff' performs the following procedure. + + * Move the drawing position vertically by the "extra pre-vertical + line space", the minimum of all negative '\x' escape sequence + arguments in the pending output line. + + * Move the drawing position vertically by the vertical line spacing. + + * Write out the pending output line. + + * Move the drawing position vertically by the "extra post-vertical + line space", the maximum of all positive '\x' escape sequence + arguments in the line that has just been output. + + * Move the drawing position vertically by the "post-vertical line + spacing" (see below). + + Prefer 'vs' or 'pvs' over 'ls' to produce double-spaced documents. +'vs' and 'pvs' have finer granularity than 'ls'; moreover, some +preprocessors assume single spacing. *Note Manipulating Spacing::, +regarding the '\x' escape sequence and the 'ls' request. + + -- Request: .pvs [space] + -- Request: .pvs +space + -- Request: .pvs -space + -- Register: \n[.pvs] + Set the post-vertical spacing to, or alter it by, SPACE. The + default scaling unit is 'p'. If 'pvs' is called without an + argument, the post-vertical spacing is reset to the previous value + before the last call to 'pvs'. GNU 'troff' emits a warning in + category 'range' if SPACE is negative; the post-vertical spacing is + then set to zero. + + The read-only register '.pvs' contains the post-vertical spacing; + it is associated with the environment (*note Environments::). + + +File: groff.info, Node: Using Fractional Type Sizes, Prev: Changing the Type Size, Up: Manipulating Type Size and Vertical Spacing + +5.20.3 Using Fractional Type Sizes +---------------------------------- + +AT&T 'troff' interpreted all type size measurements in points. Combined +with integer arithmetic, this design choice made it impossible to +support, for instance, ten and a half-point type. In GNU 'troff', an +output device can select a scaling factor that subdivides a point into +"scaled points". A type size expressed in scaled points can thus +represent a non-integral type size. + + A "scaled point" is equal to 1/SIZESCALE points, where SIZESCALE is +specified in the device description file 'DESC', and defaults to 1.(1) +(*note Using Fractional Type Sizes-Footnote-1::) Requests and escape +sequences in GNU 'troff' interpret arguments that represent a type size +in scaled points, which the formatter multiplies by SIZESCALE and +converts to an integer. Arguments treated in this way comprise those to +the escape sequences '\H' and '\s', to the request 'ps', the third +argument to the 'cs' request, and the second and fourth arguments to the +'tkf' request. Scaled points may be specified explicitly with the 'z' +scaling unit. + + For example, if SIZESCALE is 1000, then a scaled point is one +thousandth of a point. The request '.ps 10.5' is synonymous with '.ps +10.5z' and sets the type size to 10,500 scaled points, or 10.5 points. +Consequently, in GNU 'troff', the register '.s' can interpolate a +non-integral type size. + + -- Register: \n[.ps] + This read-only register interpolates the type size in scaled + points; it is associated with the environment (*note + Environments::). + + It makes no sense to use the 'z' scaling unit in a numeric expression +whose default scaling unit is neither 'u' nor 'z', so GNU 'troff' +disallows this. Similarly, it is nonsensical to use a scaling unit +other than 'z' or 'u' in a numeric expression whose default scaling unit +is 'z', and so GNU 'troff' disallows this as well. + + Another GNU 'troff' scaling unit, 's', multiplies by the number of +basic units in a scaled point. Thus, '\n[.ps]s' is equal to '1m' by +definition. Do not confuse the 's' and 'z' scaling units. + + -- Register: \n[.psr] + -- Register: \n[.sr] + Output devices may be limited in the type sizes they can employ. + The '.s' and '.ps' registers represent the type size selected by + the output driver as it understands a device's capability. The + last _requested_ type size is interpolated in scaled points by the + read-only register '.psr' and in points as a decimal fraction by + the read-only string-valued register '.sr'. Both are associated + with the environment (*note Environments::). + + For example, if a type size of 10.95 points is requested, and the + nearest size permitted by a 'sizes' request (or by the 'sizes' or + 'sizescale' directives in the device's 'DESC' file) is 11 points, + the output driver uses the latter value. + + The '\s' escape sequence offers the following syntax forms that work +with fractional type sizes and accept scaling units. You may of course +give them integral arguments. The delimited forms need not use the +neutral apostrophe; see *note Delimiters::. + +'\s[N]' +'\s'N'' + Set the type size to N scaled points; N is a numeric expression + with a default scaling unit of 'z'. + +'\s[+N]' +'\s[-N]' +'\s+[N]' +'\s-[N]' +'\s'+N'' +'\s'-N'' +'\s+'N'' +'\s-'N'' + Increase or decrease the type size by N scaled points; N is a + numeric expression (which may start with a minus sign) with a + default scaling unit of 'z'. + + +File: groff.info, Node: Using Fractional Type Sizes-Footnotes, Up: Using Fractional Type Sizes + + (1) *Note Device and Font Description Files::. + + +File: groff.info, Node: Colors, Next: Strings, Prev: Manipulating Type Size and Vertical Spacing, Up: GNU troff Reference + +5.21 Colors +=========== + +GNU 'troff' supports color output with a variety of color spaces and up +to 16 bits per channel. Some devices, particularly terminals, may be +more limited. When color support is enabled, two colors are current at +any given time: the "stroke color", with which glyphs, rules (lines), +and geometric objects like circles and polygons are drawn, and the "fill +color", which can be used to paint the interior of a closed geometric +figure. + + -- Request: .color [n] + -- Register: \n[.color] + If N is missing or non-zero, enable the output of color-related + device-independent output commands (this is the default); + otherwise, disable them. This request sets a global flag; it does + not produce an input token (*note Gtroff Internals::). + + The read-only register '.color' is 1 if colors are enabled, + 0 otherwise. + + Color can also be disabled with the '-c' command-line option. + + -- Request: .defcolor ident scheme color-component ... + Define a color named IDENT. SCHEME selects a color space and + determines the quantity of required COLOR-COMPONENTs; it must be + one of 'rgb' (three components), 'cmy' (three), 'cmyk' (four), or + 'gray' (one). 'grey' is accepted as a synonym of 'gray'. The + color components can be encoded as a single hexadecimal value + starting with '#' or '##'. The former indicates that each + component is in the range 0-255 (0-FF), the latter the range + 0-65,535 (0-FFFF). + + .defcolor half gray #7f + .defcolor pink rgb #FFC0CB + .defcolor magenta rgb ##ffff0000ffff + + Alternatively, each color component can be specified as a decimal + fraction in the range 0-1, interpreted using a default scaling unit + of 'f', which multiplies its value by 65,536 (but clamps it at + 65,535). + + .defcolor gray50 rgb 0.5 0.5 0.5 + .defcolor darkgreen rgb 0.1f 0.5f 0.2f + + Each output device has a color named 'default', which cannot be +redefined. A device's default stroke and fill colors are not +necessarily the same. For the 'dvi', 'html', 'pdf', 'ps', and 'xhtml' +output devices, GNU 'troff' automatically loads a macro file defining +many color names at startup. By the same mechanism, the devices +supported by 'grotty' recognize the eight standard ISO 6429/EMCA-48 +color names.(1) (*note Colors-Footnote-1::) + + -- Request: .gcolor [color] + -- Escape sequence: \mc + -- Escape sequence: \m(co + -- Escape sequence: \m[color] + -- Register: \n[.m] + Set the stroke color to COLOR. + + .gcolor red + The next words + .gcolor + \m[red]are in red\m[] + and these words are in the previous color. + + The escape sequence '\m[]' restores the previous stroke color, as + does a 'gcolor' request without an argument. + + The name of the current stroke color is available in the read-only + string-valued register '.m'; it is associated with the environment + (*note Environments::). It interpolates nothing when the stroke + color is the default. + + '\m' doesn't produce an input token in GNU 'troff' (*note Gtroff + Internals::). It therefore can be used in requests like 'mc' + (which expects a single character as an argument) to change the + color on the fly: + + .mc \m[red]x\m[] + + -- Request: .fcolor [color] + -- Escape sequence: \Mc + -- Escape sequence: \M(co + -- Escape sequence: \M[color] + -- Register: \n[.M] + Set the fill color for objects drawn with '\D'...'' escape + sequences. The escape sequence '\M[]' restores the previous fill + color, as does an 'fcolor' request without an argument. + + The name of the current fill color is available in the read-only + string-valued register '.M'; it is associated with the environment + (*note Environments::). It interpolates nothing when the fill + color is the default. '\M' doesn't produce an input token in GNU + 'troff'. + + Create an ellipse with a red interior as follows. + + \M[red]\h'0.5i'\D'E 2i 1i'\M[] + + +File: groff.info, Node: Colors-Footnotes, Up: Colors + + (1) also known vulgarly as "ANSI colors" + + +File: groff.info, Node: Strings, Next: Conditionals and Loops, Prev: Colors, Up: GNU troff Reference + +5.22 Strings +============ + +GNU 'troff' supports strings primarily for user convenience. +Conventionally, if one would define a macro only to interpolate a small +amount of text, without invoking requests or calling any other macros, +one defines a string instead. Only one string is predefined by the +language. + + -- String: \*[.T] + Contains the name of the output device (for example, 'utf8' or + 'pdf'). + + The 'ds' request creates a string with a specified name and contents +and the '\*' escape sequence dereferences its name, interpolating its +contents. If the string named by the '\*' escape sequence does not +exist, it is defined as empty, nothing is interpolated, and a warning in +category 'mac' is emitted. *Note Warnings::, for information about the +enablement and suppression of warnings. + + -- Request: .ds name [contents] + -- Request: .ds1 name [contents] + -- Escape sequence: \*n + -- Escape sequence: \*(nm + -- Escape sequence: \*[name [arg1 arg2 ...]] + Define a string called NAME with contents CONTENTS. If NAME + already exists as an alias, the target of the alias is redefined; + see 'als' and 'rm' below. If 'ds' is called with only one + argument, NAME is defined as an empty string. Otherwise, GNU + 'troff' stores CONTENTS in copy mode.(1) (*note + Strings-Footnote-1::) + + The '\*' escape sequence interpolates a previously defined string + variable NAME (one-character name N, two-character name NM). The + bracketed interpolation form accepts arguments that are handled as + macro arguments are; recall *note Calling Macros::. In contrast to + macro calls, however, if a closing bracket ']' occurs in a string + argument, that argument must be enclosed in double quotes. '\*' is + interpreted even in copy mode. When defining strings, argument + interpolations must be escaped if they are to reference parameters + from the calling context; *Note Parameters::. + + .ds cite (\\$1, \\$2) + Gray codes are explored in \*[cite Morgan 1998]. + => Gray codes are explored in (Morgan, 1998). + + *Caution:* Unlike other requests, the second argument to the 'ds' + request consumes the remainder of the input line, including + trailing spaces. This means that comments on a line with such a + request can introduce unwanted space into a string when they are + set off from the material they annotate, as is conventional. + + .ds H2O H\v'+.3m'\s'-2'2\v'-.3m'\s0O \" water + + Instead, place the comment on another line or put the comment + escape sequence immediately adjacent to the last character of the + string. + + .ds H2O H\v'+.3m'\s'-2'2\v'-.3m'\s0O\" water + + Ending string definitions (and appendments) with a comment, even an + empty one, prevents unwanted space from creeping into them during + source document maintenance. + + .ds author Alice Pleasance Liddell\" + .ds empty \" might be appended to later with .as + + An initial neutral double quote '"' in CONTENTS is stripped to + allow embedding of leading spaces. Any other '"' is interpreted + literally, but it is wise to use the special character escape + sequence '\[dq]' instead if the string might be interpolated as + part of a macro argument; see *note Calling Macros::. + + .ds salutation " Yours in a white wine sauce,\" + .ds c-var-defn " char mydate[]=\[dq]2020-07-29\[dq];\" + + Strings are not limited to a single input line of text. '\' + works just as it does elsewhere. The resulting string is stored + _without_ the newlines. Care is therefore required when + interpolating strings while filling is disabled. + + .ds foo This string contains \ + text on multiple lines \ + of input. + + It is not possible to embed a newline in a string that will be + interpreted as such when the string is interpolated. To achieve + that effect, use '\*' to interpolate a macro instead; see *note + Punning Names::. + + Because strings are similar to macros, they too can be defined so + as to suppress AT&T 'troff' compatibility mode when used; see *note + Writing Macros:: and *note Compatibility Mode::. The 'ds1' request + defines a string such that compatibility mode is off when the + string is later interpolated. To be more precise, a "compatibility + save" input token is inserted at the beginning of the string, and a + "compatibility restore" input token at the end. + + .nr xxx 12345 + .ds aa The value of xxx is \\n[xxx]. + .ds1 bb The value of xxx is \\n[xxx]. + . + .cp 1 + . + \*(aa + error-> warning: register '[' not defined + => The value of xxx is 0xxx]. + \*(bb + => The value of xxx is 12345. + + -- Request: .as name [contents] + -- Request: .as1 name [contents] + The 'as' request is similar to 'ds' but appends CONTENTS to the + string stored as NAME instead of redefining it. If NAME doesn't + exist yet, it is created. If 'as' is called with only one + argument, no operation is performed (beyond dereferencing the + string). + + .as salutation " with shallots, onions and garlic,\" + + The 'as1' request is similar to 'as', but compatibility mode is + switched off when the appended portion of the string is later + interpolated. To be more precise, a "compatibility save" input + token is inserted at the beginning of the appended string, and a + "compatibility restore" input token at the end. + + Several requests exist to perform rudimentary string operations. +Strings can be queried ('length') and modified ('chop', 'substring', +'stringup', 'stringdown'), and their names can be manipulated through +renaming, removal, and aliasing ('rn', 'rm', 'als'). + + -- Request: .length reg anything + Compute the number of characters of ANYTHING and store the count in + the register REG. If REG doesn't exist, it is created. ANYTHING + is read in copy mode. + + .ds xxx abcd\h'3i'efgh + .length yyy \*[xxx] + \n[yyy] + => 14 + + -- Request: .chop object + Remove the last character from the macro, string, or diversion + named OBJECT. This is useful for removing the newline from the end + of a diversion that is to be interpolated as a string. This + request can be used repeatedly on the same OBJECT; see *note Gtroff + Internals::, for details on nodes inserted additionally by GNU + 'troff'. + + -- Request: .substring str start [end] + Replace the string named STR with its substring bounded by the + indices START and END, inclusively. The first character in the + string has index 0. If END is omitted, it is implicitly set to the + largest valid value (the string length minus one). Negative + indices count backward from the end of the string: the last + character has index -1, the character before the last has index -2, + and so on. + + .ds xxx abcdefgh + .substring xxx 1 -4 + \*[xxx] + => bcde + .substring xxx 2 + \*[xxx] + => de + + -- Request: .stringdown str + -- Request: .stringup str + Alter the string named STR by replacing each of its bytes with its + lowercase ('stringdown') or uppercase ('stringup') version (if one + exists). Special characters in the string will often transform in + the expected way due to the regular naming convention for accented + characters. When they do not, use substrings and/or catenation. + + .ds resume R\['e]sum\['e] + \*[resume] + .stringdown resume + \*[resume] + .stringup resume + \*[resume] + => Résumé résumé RÉSUMÉ + + (In practice, we would end the 'ds' request with a comment escape +'\"' to prevent space from creeping into the definition during source +document maintenance.) + + -- Request: .rn old new + Rename the request, macro, diversion, or string OLD to NEW. + + -- Request: .rm name + Remove the request, macro, diversion, or string NAME. GNU 'troff' + treats subsequent invocations as if the name had never been + defined. + + -- Request: .als new old + Create an alias NEW for the existing request, string, macro, or + diversion object named OLD, causing the names to refer to the same + stored object. If OLD is undefined, a warning in category 'mac' is + produced, and the request is ignored. *Note Warnings::, for + information about the enablement and suppression of warnings. + + To understand how the 'als' request works, consider two different + storage pools: one for objects (macros, strings, etc.), and another + for names. As soon as an object is defined, GNU 'troff' adds it to + the object pool, adds its name to the name pool, and creates a link + between them. When 'als' creates an alias, it adds a new name to + the name pool that gets linked to the same object as the old name. + + Now consider this example. + + .de foo + .. + . + .als bar foo + . + .de bar + . foo + .. + . + .bar + error-> input stack limit exceeded (probable infinite + error-> loop) + + In the above, 'bar' remains an _alias_--another name for--the + object referred to by 'foo', which the second 'de' request + replaces. Alternatively, imagine that the 'de' request + _dereferences_ its argument before replacing it. Either way, the + result of calling 'bar' is a recursive loop that finally leads to + an error. *Note Writing Macros::. + + To remove an alias, call 'rm' on its name. The object itself is + not destroyed until it has no more names. + + When a request, macro, string, or diversion is aliased, + redefinitions and appendments "write through" alias names. To + replace an alias with a separately defined object, you must use the + 'rm' request on its name first. + + +File: groff.info, Node: Strings-Footnotes, Up: Strings + + (1) *Note Copy Mode::. + + +File: groff.info, Node: Conditionals and Loops, Next: Writing Macros, Prev: Strings, Up: GNU troff Reference + +5.23 Conditionals and Loops +=========================== + +'groff' has 'if' and 'while' control structures like other languages. +However, the syntax for grouping multiple input lines in the branches or +bodies of these structures is unusual. + +* Menu: + +* Operators in Conditionals:: +* if-then:: +* if-else:: +* Conditional Blocks:: +* while:: + + +File: groff.info, Node: Operators in Conditionals, Next: if-then, Prev: Conditionals and Loops, Up: Conditionals and Loops + +5.23.1 Operators in Conditionals +-------------------------------- + +In 'if', 'ie', and 'while' requests, in addition to the numeric +expressions described in *note Numeric Expressions::, several Boolean +operators are available; the members of this expanded class are termed +"conditional expressions". + +'c GLYPH' + True if GLYPH is available, where GLYPH is an ordinary character, a + special character '\(XX' or '\[XXX]', '\N'XXX'', or has been + defined by any of the 'char', 'fchar', 'fschar', or 'schar' + requests. + +'d NAME' + True if a string, macro, diversion, or request called NAME exists. + +'e' + True if the current page is even-numbered. + +'F FONT' + True if FONT exists. FONT is handled as if it were opened with the + 'ft' request (that is, font translation and styles are applied), + without actually mounting it. + +'m COLOR' + True if COLOR is defined. + +'n' + True if the document is being processed in 'nroff' mode. *Note + troff and nroff Modes::. + +'o' + True if the current page is odd-numbered. + +'r REGISTER' + True if REGISTER exists. + +'S STYLE' + True if STYLE is available for the current font family. Font + translation is applied. + +'t' + True if the document is being processed in 'troff' mode. *Note + troff and nroff Modes::. + +'v' + Always false. This condition is recognized only for compatibility + with certain other 'troff' implementations.(1) (*note Operators in + Conditionals-Footnote-1::) + + If the first argument to an 'if', 'ie', or 'while' request begins +with a non-alphanumeric character apart from '!' (see below); it +performs an output comparison test. (2) (*note Operators in +Conditionals-Footnote-2::) + +''XXX'YYY'' + True if formatting the comparands XXX and YYY produces the same + output commands. The delimiter need not be a neutral apostrophe: + the output comparison operator accepts the same delimiters as most + escape sequences; see *note Delimiters::. This "output comparison + operator" formats XXX and YYY in separate environments; after the + comparison, the resulting data are discarded. + + .ie "|"\fR|\fP" true + .el false + => true + + The resulting glyph properties, including font family, style, size, + and slant, must match, but not necessarily the requests and/or + escape sequences used to obtain them. In the previous example, '|' + and '\fR|\fP' result in '|' glyphs in the same typefaces at the + same positions, so the comparands are equal. If '.ft I' had been + added before the '.ie', they would differ: the first '|' would + produce an italic '|', not a roman one. Motions must match in + orientation and magnitude to within the applicable horizontal and + vertical motion quanta of the device, after rounding. '.if + "\u\d"\v'0'"' is false even though both comparands result in zero + net motion, because motions are not interpreted or optimized but + sent as-is to the output.(3) (*note Operators in + Conditionals-Footnote-3::) On the other hand, '.if "\d"\v'0.5m'"' + is true, because '\d' is defined as a downward motion of one-half + em.(4) (*note Operators in Conditionals-Footnote-4::) + + Surround the comparands with '\?' to avoid formatting them; this + causes them to be compared character by character, as with string + comparisons in other programming languages. + + .ie "\?|\?"\?\fR|\fP\?" true + .el false + => false + + Since comparands protected with '\?' are read in copy mode (*note + Copy Mode::), they need not even be valid 'groff' syntax. The + escape character is still lexically recognized, however, and + consumes the next character. + + .ds a \[ + .ds b \[ + .if '\?\*a\?'\?\*b\?' a and b equivalent + .if '\?\\?'\?\\?' backslashes equivalent + => a and b equivalent + + The above operators can't be combined with most others, but a leading +'!', not followed immediately by spaces or tabs, complements an +expression. + + .nr x 1 + .ie !r x register x is not defined + .el register x is defined + => register x is defined + + Spaces and tabs are optional immediately after the 'c', 'd', 'F', +'m', 'r', and 'S' operators, but right after '!', they end the predicate +and the conditional evaluates true.(5) (*note Operators in +Conditionals-Footnote-5::) + + .nr x 1 + .ie ! r x register x is not defined + .el register x is defined + => r x register x is not defined + +The unexpected 'r x' in the output is a clue that our conditional was +not interpreted as we planned, but matters may not always be so obvious. + + +File: groff.info, Node: Operators in Conditionals-Footnotes, Up: Operators in Conditionals + + (1) This refers to 'vtroff', a translator that would convert the +C/A/T output from early-vintage AT&T 'troff' to a form suitable for +Versatec and Benson-Varian plotters. + + (2) Strictly, letters not otherwise recognized _are_ treated as +output comparison delimiters. For portability, it is wise to avoid +using letters not in the list above; for example, Plan 9 'troff' uses +'h' to test a mode it calls 'htmlroff', and GNU 'troff' may provide +additional operators in the future. + + (3) Because formatting of the comparands takes place in a dummy +environment, vertical motions within them cannot spring traps. + + (4) All of this is to say that the lists of output nodes created by +formatting XXX and YYY must be identical. *Note Gtroff Internals::. + + (5) This bizarre behavior maintains compatibility with AT&T 'troff'. + + +File: groff.info, Node: if-then, Next: if-else, Prev: Operators in Conditionals, Up: Conditionals and Loops + +5.23.2 if-then +-------------- + + -- Request: .if cond-expr anything + Evaluate the conditional expression COND-EXPR, and if it evaluates + true (or to a positive value), interpret the remainder of the line + ANYTHING as if it were an input line. Recall from *note Invoking + Requests:: that any quantity of spaces between arguments to + requests serves only to separate them; leading spaces in ANYTHING + are thus not seen. ANYTHING effectively _cannot_ be omitted; if + COND-EXPR is true and ANYTHING is empty, the newline at the end of + the control line is interpreted as a blank input line (and + therefore a blank text line). + + super\c + tanker + .nr force-word-break 1 + super\c + .if ((\n[force-word-break] = 1) & \n[.int]) + tanker + => supertanker super tanker + + -- Request: .nop anything + Interpret ANYTHING as if it were an input line. This is similar to + '.if 1'. 'nop' is not really "no operation"; its argument _is_ + processed--unconditionally. It can be used to cause text lines to + share indentation with surrounding control lines. + + .als real-MAC MAC + .de wrapped-MAC + . tm MAC: called with arguments \\$@ + . nop \\*[real-MAC]\\ + .. + .als MAC wrapped-MAC + \# Later... + .als MAC real-MAC + + In the above, we've used aliasing, 'nop', and the interpolation of + a macro as a string to interpose a wrapper around the macro 'MAC' + (perhaps to debug it). + + +File: groff.info, Node: if-else, Next: while, Prev: Operators in Conditionals, Up: Conditionals and Loops + +5.23.3 if-else +-------------- + + -- Request: .ie cond-expr anything + -- Request: .el anything + Use the 'ie' and 'el' requests to write an if-then-else. The first + request is the "if" part and the latter is the "else" part. + Unusually among programming languages, any number of + non-conditional requests may be interposed between the 'ie' branch + and the 'el' branch. + + .nr a 0 + .ie \na a is non-zero. + .nr a +1 + .el a was not positive but is now \na. + => a was not positive but is now 1. + + Another way in which 'el' is an ordinary request is that it does + not lexically "bind" more tightly to its 'ie' counterpart than it + does to any other request. This fact can surprise C programmers. + + .nr a 1 + .nr z 0 + .ie \nz \ + . ie \na a is true + . el a is false + .el z is false + error-> warning: unbalanced 'el' request + => a is false + + To conveniently nest conditionals, keep reading. + + +File: groff.info, Node: Conditional Blocks, Next: while, Prev: Operators in Conditionals, Up: Conditionals and Loops + +5.23.4 Conditional Blocks +------------------------- + +It is frequently desirable for a control structure to govern more than +one request, macro call, text line, or a combination of the foregoing. +The opening and closing brace escape sequences '\{' and '\}' define such +groups. These "conditional blocks" can furthermore be nested. + + -- Escape sequence: \{ + -- Escape sequence: \} + '\{' begins a conditional block; it must appear (after optional + spaces and tabs) immediately subsequent to the conditional + expression of an 'if', 'ie', or 'while' request,(1) (*note + Conditional Blocks-Footnote-1::) or as the argument to an 'el' + request. + + '\}' ends a condition block and should appear on a line with other + occurrences of itself as necessary to match '\{' sequences. It can + be preceded by a control character, spaces, and tabs. Input after + any quantity of '\}' sequences on the same line is processed only + if all of the preceding conditions to which they correspond are + true. Furthermore, a '\}' closing the body of a 'while' request + must be the last such escape sequence on an input line. + + Brace escape sequences outside of control structures have no + meaning and produce no output. + + *Caution:* Input lines using '\{' often end with '\RET', especially + in macros that consist primarily of control lines. Forgetting to + use '\RET' on an input line after '\{' is a common source of error. + + We might write the following in a page header macro. If we delete +'\RET', the header will carry an unwanted extra empty line (except on +page 1). + + .if (\\n[%] != 1) \{\ + . ie ((\\n[%] % 2) = 0) .tl \\*[even-numbered-page-title] + . el .tl \\*[odd-numbered-page-title] + .\} + + Let us take a closer look at how conditional blocks nest. + + A + .if 0 \{ B + C + D + \}E + F + => A F + + N + .if 1 \{ O + . if 0 \{ P + Q + R\} S\} T + U + => N O U + + The above behavior may challenge the intuition; it was implemented to +retain compatibility with AT&T 'troff'. For clarity, it is idiomatic to +end input lines with '\{' (followed by '\' if appropriate), and to +precede '\}' on an input line with nothing more than a control +character, spaces, tabs, and other instances of itself. + + We can use 'ie', 'el', and conditional blocks to simulate the +multi-way "switch" or "case" control structures of other languages. The +following example is adapted from the 'groff' 'man' package. +Indentation is used to clarify the logic. + + .\" Simulate switch/case in roff. + . ie '\\$2'1' .ds title General Commands\" + .el \{.ie '\\$2'2' .ds title System Calls\" + .el \{.ie '\\$2'3' .ds title Library Functions\" + .el \{.ie '\\$2'4' .ds title Kernel Interfaces\" + .el \{.ie '\\$2'5' .ds title File Formats\" + .el \{.ie '\\$2'6' .ds title Games\" + .el \{.ie '\\$2'7' .ds title Miscellaneous Information\" + .el \{.ie '\\$2'8' .ds title System Management\" + .el \{.ie '\\$2'9' .ds title Kernel Development\" + .el .ds title \" empty + .\}\}\}\}\}\}\}\} + + +File: groff.info, Node: Conditional Blocks-Footnotes, Up: Conditional Blocks + + (1) *Note while::. + + +File: groff.info, Node: while, Prev: if-else, Up: Conditionals and Loops + +5.23.5 while +------------ + +'groff' provides a looping construct: the 'while' request. Its syntax +matches the 'if' request. + + -- Request: .while cond-expr anything + Evaluate the conditional expression COND-EXPR, and repeatedly + execute ANYTHING unless and until COND-EXPR evaluates false. + ANYTHING, which is often a conditional block, is referred to as the + 'while' request's "body". + + .nr a 0 1 + .while (\na < 9) \{\ + \n+a, + .\} + \n+a + => 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 + + GNU 'troff' treats the body of a 'while' request similarly to that + of a 'de' request (albeit one not read in copy mode(1) (*note + while-Footnote-1::)), but stores it under an internal name and + deletes it when the loop finishes. The operation of a macro + containing a 'while' request can slow significantly if the 'while' + body is large. Each time the macro is executed, the 'while' body + is parsed and stored again. + + .de xxx + . nr num 10 + . while (\\n[num] > 0) \{\ + . \" many lines of code + . nr num -1 + . \} + .. + + An often better solution--and one that is more portable, since AT&T + 'troff' lacked the 'while' request--is to instead write a recursive + macro. It will be parsed only once.(2) (*note while-Footnote-2::) + + .de yyy + . if (\\n[num] > 0) \{\ + . \" many lines of code + . nr num -1 + . yyy + . \} + .. + . + .de xxx + . nr num 10 + . yyy + .. + + To prevent infinite loops, the default number of available + recursion levels is 1,000 or somewhat less.(3) (*note + while-Footnote-3::) You can disable this protective measure, or + raise the limit, by setting the 'slimit' register. *Note + Debugging::. + + As noted above, if a 'while' body begins with a conditional block, + its closing brace must end an input line. + + .if 1 \{\ + . nr a 0 1 + . while (\n[a] < 10) \{\ + . nop \n+[a] + .\}\} + error-> unbalanced brace escape sequences + + -- Request: .break + Exit a 'while' loop. Do not confuse this request with a + typographical break or the 'br' request. + + -- Request: .continue + Skip the remainder of a 'while' loop's body, immediately starting + the next iteration. + + +File: groff.info, Node: while-Footnotes, Up: while + + (1) *Note Copy Mode::. + + (2) unless you redefine it + + (3) "somewhat less" because things other than macro calls can be on +the input stack + + +File: groff.info, Node: Writing Macros, Next: Page Motions, Prev: Conditionals and Loops, Up: GNU troff Reference + +5.24 Writing Macros +=================== + +A "macro" is a stored collection of text and control lines that can be +interpolated multiple times. Use macros to define common operations. +Macros are called in the same way that requests are invoked. While +requests exist for the purpose of creating macros, simply calling an +undefined macro, or interpolating it as a string, will cause it to be +defined as empty. *Note Identifiers::. + + -- Request: .de name [end] + Define a macro NAME, replacing the definition of any existing + request, macro, string, or diversion called NAME. If NAME already + exists as an alias, the target of the alias is redefined; recall + *note Strings::. GNU 'troff' enters copy mode,(1) (*note Writing + Macros-Footnote-1::) storing subsequent input lines as the macro + definition. If the optional second argument is not specified, the + definition ends with the control line '..' (two dots). + Alternatively, END identifies a macro whose call syntax at the + start of a control line ends the definition of NAME; END is then + called normally. A macro definition must end in the same + conditional block (if any) in which it began (*note Conditional + Blocks::). Spaces or tabs are permitted after the control + character in the line containing this ending token (either '.' or + 'END'), but a tab immediately after the token prevents its + recognition as the end of a macro definition. The macro END can be + called with arguments.(2) (*note Writing Macros-Footnote-2::) + + Here is a small example macro called 'P' that causes a break and + inserts some vertical space. It could be used to separate + paragraphs. + + .de P + . br + . sp .8v + .. + + We can define one macro within another. Attempting to nest '..' + naďvely will end the outer definition because the inner definition + isn't interpreted as such until the outer macro is later + interpolated. We can use an end macro instead. Each level of + nesting should use a unique end macro. + + An end macro need not be defined until it is called. This fact + enables a nested macro definition to begin inside one macro and end + inside another. Consider the following example.(3) (*note Writing + Macros-Footnote-3::) + + .de m1 + . de m2 m3 + you + .. + .de m3 + Hello, + Joe. + .. + .de m4 + do + .. + .m1 + know? + . m3 + What + .m4 + .m2 + => Hello, Joe. What do you know? + + A nested macro definition _can_ be terminated with '..' and nested + macros _can_ reuse end macros, but these control lines must be + escaped multiple times for each level of nesting. The necessity of + this escaping and the utility of nested macro definitions will + become clearer when we employ macro parameters and consider the + behavior of copy mode in detail. + + 'de' defines a macro that inherits the compatibility mode enablement +status of its context (*note Implementation Differences::). Often it is +desirable to make a macro that uses 'groff' features callable from +contexts where compatibility mode is on; for instance, when writing +extensions to a historical macro package. To achieve this, +compatibility mode needs to be switched off while such a macro is +interpreted--without disturbing that state when it is finished. + + -- Request: .de1 name [end] + The 'de1' request defines a macro to be interpreted with + compatibility mode disabled. When NAME is called, compatibility + mode enablement status is saved; it is restored when the call + completes. Observe the extra backlash before the interpolation of + register 'xxx'; we'll explore this subject in *note Copy Mode::. + + .nr xxx 12345 + .de aa + The value of xxx is \\n[xxx]. + . br + .. + .de1 bb + The value of xxx is \\n[xxx]. + .. + .cp 1 + .aa + error-> warning: register '[' not defined + => The value of xxx is 0xxx]. + .bb + => The value of xxx is 12345. + + -- Request: .dei name [end] + -- Request: .dei1 name [end] + The 'dei' request defines a macro with its name and end macro + indirected through strings. That is, it interpolates strings named + NAME and END before performing the definition. + + The following examples are equivalent. + + .ds xx aa + .ds yy bb + .dei xx yy + + .de aa bb + + The 'dei1' request bears the same relationship to 'dei' as 'de1' + does to 'de'; it temporarily turns compatibility mode off when NAME + is called. + + -- Request: .am name [end] + -- Request: .am1 name [end] + -- Request: .ami name [end] + -- Request: .ami1 name [end] + 'am' appends subsequent input lines to macro NAME, extending its + definition, and otherwise working as 'de' does. + + To make the previously defined 'P' macro set indented instead of + block paragraphs, add the necessary code to the existing macro. + + .am P + .ti +5n + .. + + The other requests are analogous to their 'de' counterparts. The + 'am1' request turns off compatibility mode during interpretation of + the appendment. The 'ami' request appends indirectly, meaning that + strings NAME and END are interpolated with the resulting names used + before appending. The 'ami1' request is similar to 'ami', + disabling compatibility mode during interpretation of the appended + lines. + + Using 'trace.tmac', you can trace calls to 'de', 'de1', 'am', and +'am1'. You can also use the 'backtrace' request at any point desired to +troubleshoot tricky spots (*note Debugging::). + + *Note Strings::, for the 'als', 'rm', and 'rn' requests to create an +alias of, remove, and rename a macro, respectively. + + Macro identifiers share their name space with requests, strings, and +diversions; see *note Identifiers::. The 'am', 'as', 'da', 'de', 'di', +and 'ds' requests (together with their variants) create a new object +only if the name of the macro, diversion, or string is currently +undefined or if it is defined as a request; normally, they modify the +value of an existing object. *Note the description of the 'als' +request: als, for pitfalls when redefining a macro that is aliased. + + -- Request: .return [anything] + Exit a macro, immediately returning to the caller. If called with + an argument ANYTHING, exit twice--the current macro and the macro + one level higher. This is used to define a wrapper macro for + 'return' in 'trace.tmac'. + +* Menu: + +* Parameters:: +* Copy Mode:: + + +File: groff.info, Node: Writing Macros-Footnotes, Up: Writing Macros + + (1) *Note Copy Mode::. + + (2) While it is possible to define and call a macro '.', you can't +use it as an end macro: during a macro definition, '..' is never handled +as calling '.', even if '.de NAME .' explicitly precedes it. + + (3) Its structure is adapted from, and isomorphic to, part of a +solution by Tadziu Hoffman to the problem of reflowing text multiple +times to find an optimal configuration for it. + + + +File: groff.info, Node: Parameters, Next: Copy Mode, Prev: Writing Macros, Up: Writing Macros + +5.24.1 Parameters +----------------- + +Macro calls and string interpolations optionally accept a list of +arguments; recall *note Calling Macros::. At the time such an +interpolation takes place, these "parameters" can be examined using a +register and a variety of escape sequences starting with '\$'. All such +escape sequences are interpreted even in copy mode, a fact we shall +motivate and explain below (*note Copy Mode::). + + -- Register: \n[.$] + The count of parameters available to a macro or string is kept in + this read-only register. The 'shift' request can change its value. + + Any individual parameter can be accessed by its position in the list +of arguments to the macro call, numbered from left to right starting at +1, with one of the following escape sequences. + + -- Escape sequence: \$n + -- Escape sequence: \$(nn + -- Escape sequence: \$[nnn] + Interpolate the Nth, NNth, or NNNth parameter. The first form + expects only a single digit (1<=N<=9)), the second two digits + (01<=NN<=99)), and the third any positive integer NNN. Macros and + strings accept an unlimited number of parameters. + + -- Request: .shift [n] + Shift the parameters N places (1 by default). This is a "left + shift": what was parameter I becomes parameter I-N. The parameters + formerly in positions 1 to N are no longer available. Shifting by + a non-positive amount performs no operation. The register '.$' is + adjusted accordingly. + + In practice, parameter interpolations are usually seen prefixed with +an extra escape character. This is because the '\$' family of escape +sequences is interpreted even in copy mode.(1) (*note +Parameters-Footnote-1::) + + -- Escape sequence: \$* + -- Escape sequence: \$@ + -- Escape sequence: \$^ + In some cases it is convenient to interpolate all of the parameters + at once (to pass them to a request, for instance). The '\$*' + escape concatenates the parameters, separating them with spaces. + '\$@' is similar, concatenating the parameters, surrounding each + with double quotes and separating them with spaces. If not in + compatibility mode, the interpolation depth of double quotes is + preserved (*note Calling Macros::). '\$^' interpolates all + parameters as if they were arguments to the 'ds' request. + + .de foo + . tm $1='\\$1' + . tm $2='\\$2' + . tm $*='\\$*' + . tm $@='\\$@' + . tm $^='\\$^' + .. + .foo " This is a "test" + error-> $1=' This is a ' + error-> $2='test"' + error-> $*=' This is a test"' + error-> $@='" This is a " "test""' + error-> $^='" This is a "test"' + + '\$*' is useful when writing a macro that doesn't need to + distinguish its arguments, or even to not interpret them; examples + include macros that produce diagnostic messages by wrapping the + 'tm' or 'ab' requests. Use '\$@' when writing a macro that may + need to shift its parameters and/or wrap a macro or request that + finds the count significant. If in doubt, prefer '\$@' to '\$*'. + An application of '\$^' is seen in 'trace.tmac', which redefines + some requests and macros for debugging purposes. + + -- Escape sequence: \$0 + Interpolate the name by which the macro being interpreted was + called. The 'als' request can cause a macro to have more than one + name. Applying string interpolation to a macro does not change + this name. + + .de foo + . tm \\$0 + .. + .als bar foo + . + .de aaa + . foo + .. + .de bbb + . bar + .. + .de ccc + \\*[foo]\\ + .. + .de ddd + \\*[bar]\\ + .. + . + .aaa + error-> foo + .bbb + error-> bar + .ccc + error-> ccc + .ddd + error-> ddd + + +File: groff.info, Node: Parameters-Footnotes, Up: Parameters + + (1) If they were not, parameter interpolations would be similar to +command-line parameters--fixed for the entire duration of a 'roff' +program's run. The advantage of interpolating '\$' escape sequences +even in copy mode is that they can interpolate different contents from +one call to the next, like function parameters in a procedural language. +The additional escape character is the price of this power. + + +File: groff.info, Node: Copy Mode, Prev: Parameters, Up: Writing Macros + +5.24.2 Copy Mode +---------------- + +When GNU 'troff' processes certain requests, most importantly those +which define or append to a macro or string, it does so in "copy mode": +it copies the characters of the definition into a dedicated storage +region, interpolating the escape sequences '\n', '\g', '\$', '\*', '\V', +and '\?' normally; interpreting '\' immediately; discarding +comments '\"' and '\#'; interpolating the current leader, escape, or tab +character with '\a', '\e', and '\t', respectively; and storing all other +escape sequences in an encoded form. + + The complement of copy mode--a 'roff' formatter's behavior when not +defining or appending to a macro, string, or diversion--where all macros +are interpolated, requests invoked, and valid escape sequences processed +immediately upon recognition, can be termed "interpretation mode". + + -- Escape sequence: \\ + The escape character, '\' by default, can escape itself. This + enables you to control whether a given '\n', '\g', '\$', '\*', + '\V', or '\?' escape sequence is interpreted at the time the macro + containing it is defined, or later when the macro is called.(1) + (*note Copy Mode-Footnote-1::) + + .nr x 20 + .de y + .nr x 10 + \&\nx + \&\\nx + .. + .y + => 20 10 + + You can think of '\\' as a "delayed" backslash; it is the escape + character followed by a backslash from which the escape character + has removed its special meaning. Consequently, '\\' is not an + escape sequence in the usual sense. In any escape sequence '\X' + that GNU 'troff' does not recognize, the escape character is + ignored and X is output. An unrecognized escape sequence causes a + warning in category 'escape', with two exceptions--'\\' is the + first. + + -- Escape sequence: \. + '\.' escapes the control character. It is similar to '\\' in that + it isn't a true escape sequence. It is used to permit nested macro + definitions to end without a named macro call to conclude them. + Without a syntax for escaping the control character, this would not + be possible. + + .de m1 + foo + . + . de m2 + bar + \\.. + . + .. + .m1 + .m2 + => foo bar + + The first backslash is consumed while the macro is read, and the + second is interpreted when macro 'm1' is called. + + 'roff' documents should not use the '\\' or '\.' character sequences +outside of copy mode; they serve only to obfuscate the input. Use '\e' +to represent the escape character, '\[rs]' to obtain a backslash glyph, +and '\&' before '.' and ''' where GNU 'troff' expects them as control +characters if you mean to use them literally (recall *note Requests and +Macros::). + + Macro definitions can be nested to arbitrary depth. The mechanics of +parsing the escape character have significant consequences for this +practice. + + .de M1 + \\$1 + . de M2 + \\\\$1 + . de M3 + \\\\\\\\$1 + \\\\.. + . M3 hand. + \\.. + . M2 of + .. + This understeer is getting + .M1 out + => This understeer is getting out of hand. + + Each escape character is interpreted twice--once in copy mode, when +the macro is defined, and once in interpretation mode, when the macro is +called. As seen above, this fact leads to exponential growth in the +quantity of escape characters required to delay interpolation of '\n', +'\g', '\$', '\*', '\V', and '\?' at each nesting level, which can be +daunting. GNU 'troff' offers a solution. + + -- Escape sequence: \E + '\E' represents an escape character that is not interpreted in copy + mode. You can use it to ease the writing of nested macro + definitions. + + .de M1 + . nop \E$1 + . de M2 + . nop \E$1 + . de M3 + . nop \E$1 + \\\\.. + . M3 better. + \\.. + . M2 bit + .. + This vehicle handles + .M1 a + => This vehicle handles a bit better. + + Observe that because '\.' is not a true escape sequence, we can't + use '\E' to keep '..' from ending a macro definition prematurely. + If the multiplicity of backslashes complicates maintenance, use end + macros. + + '\E' is also convenient to define strings containing escape + sequences that need to work when used in copy mode (for example, as + macro arguments), or which will be interpolated at varying macro + nesting depths. We might define strings to begin and end + superscripting as follows.(2) (*note Copy Mode-Footnote-2::) + + .ds { \v'-.9m\s'\En[.s]*7u/10u'+.7m' + .ds } \v'-.7m\s0+.9m' + + When the 'ec' request is used to redefine the escape character, + '\E' also makes it easier to distinguish the semantics of an escape + character from the other meaning(s) its character might have. + Consider the use of an unusual escape character, '-'. + + .nr a 1 + .ec - + .de xx + --na + .. + .xx + => -na + + This result may surprise you; some people expect '1' to be output + since register 'a' has clearly been defined with that value. What + has happened? The robotic replacement of '\' with '-' has led us + astray. You might recognize the sequence '--' more readily with + the default escape character as '\-', the special character escape + sequence for the minus sign glyph. + + .nr a 1 + .ec - + .de xx + -Ena + .. + .xx + => 1 + + +File: groff.info, Node: Copy Mode-Footnotes, Up: Copy Mode + + (1) Compare this to the '\def' and '\edef' commands in TeX. + + (2) These are lightly adapted from the 'groff' implementation of the +'ms' macros. + + +File: groff.info, Node: Page Motions, Next: Drawing Geometric Objects, Prev: Writing Macros, Up: GNU troff Reference + +5.25 Page Motions +================= + +*Note Manipulating Spacing::, for a discussion of the most commonly used +request for vertical motion, 'sp', which spaces downward by one vee. + + -- Request: .mk [reg] + -- Request: .rt [dist] + You can "mark" a location on a page for subsequent "return". 'mk' + takes an argument, a register name in which to store the current + page location. If given no argument, it stores the location in an + internal register. This location can be used later by the 'rt' or + the 'sp' requests (or the '\v' escape). + + The 'rt' request returns _upward_ to the location marked with the + last 'mk' request. If used with an argument, it returns to a + vertical position DIST from the top of the page (no previous call + to 'mk' is necessary in this case). The default scaling unit is + 'v'. + + If a page break occurs between a 'mk' request and its matching 'rt' + request, the 'rt' request is silently ignored. + + A simple implementation of a macro to set text in two columns + follows. + + .nr column-length 1.5i + .nr column-gap 4m + .nr bottom-margin 1m + . + .de 2c + . br + . mk + . ll \\n[column-length]u + . wh -\\n[bottom-margin]u 2c-trap + . nr right-side 0 + .. + . + .de 2c-trap + . ie \\n[right-side] \{\ + . nr right-side 0 + . po -(\\n[column-length]u + \\n[column-gap]u) + . \" remove trap + . wh -\\n[bottom-margin]u + . \} + . el \{\ + . \" switch to right side + . nr right-side 1 + . po +(\\n[column-length]u + \\n[column-gap]u) + . rt + . \} + .. + + Now let us apply our two-column macro. + + .pl 1.5i + .ll 4i + This is a small test that shows how the + rt request works in combination with mk. + + .2c + Starting here, text is typeset in two columns. + Note that this implementation isn't robust + and thus not suited for a real two-column + macro. + => This is a small test that shows how the + => rt request works in combination with mk. + => + => Starting here, isn't robust + => text is typeset and thus not + => in two columns. suited for a + => Note that this real two-column + => implementation macro. + + Several escape sequences enable fine control of movement about the +page. + + -- Escape sequence: \v'expr' + Vertically move the drawing position. EXPR indicates the magnitude + of motion: positive is downward and and negative upward. The + default scaling unit is 'v'. The motion is relative to the current + drawing position unless EXPR begins with the boundary-relative + motion operator '|'. *Note Numeric Expressions::. + + Text processing continues at the new drawing position; usually, + vertical motions should be in balanced pairs to avoid a confusing + page layout. + + '\v' will not spring a vertical position trap. This can be useful; + for example, consider a page bottom trap macro that prints a marker + in the margin to indicate continuation of a footnote. *Note + Traps::. + + A few escape sequences that produce vertical motion are unusual. +They are thought to originate early in AT&T 'nroff' history to achieve +super- and subscripting by half-line motions on line printers and +teletypewriters before the phototypesetter made more precise positioning +available. They are reckoned in ems--not vees--to maintain continuity +with their original purpose of moving relative to the size of the type +rather than the distance between text baselines (vees).(1) (*note Page +Motions-Footnote-1::) + + -- Escape sequence: \r + -- Escape sequence: \u + -- Escape sequence: \d + Move upward 1m, upward .5m, and downward .5m, respectively. + +Let us see these escape sequences in use. + + Obtain 100 cm\u3\d of \ka\d\092\h'|\nau'\r233\dU. + + In the foregoing we have paired '\u' and '\d' to typeset a +superscript, and later a full em negative ("reverse") motion to place a +superscript above a subscript. A numeral-width horizontal motion escape +sequence aligns the proton and nucleon numbers, while '\k' marks a +horizontal position to which '\h' returns so that we could stack them. +(We shall discuss these horizontal motion escape sequences presently.) +In serious applications, we often want to alter the type size of the +-scripts and to fine-tune the vertical motions, as the 'groff' 'ms' +package does with its super- and subscripting string definitions. + + -- Escape sequence: \h'expr' + Horizontally move the drawing position. EXPR indicates the + magnitude of motion: positive is rightward and negative leftward. + The default scaling unit is 'm'. The motion is relative to the + current drawing position unless EXPR begins with the + boundary-relative motion operator '|'. *Note Numeric + Expressions::. + + The following string definition sets the TeX logo.(2) (*note Page +Motions-Footnote-2::) + + .ds TeX T\h'-.1667m'\v'.224m'E\v'-.224m'\h'-.125m'X\" + + There are a number of special-case escape sequences for horizontal +motion. + + -- Escape sequence: \ + Move right one word space. (The input is a backslash followed by a + space.) This escape sequence can be thought of as a + non-adjustable, unbreakable space. Usually you want '\~' instead; + see *note Manipulating Filling and Adjustment::. + + -- Escape sequence: \| + Move one-sixth em to the right on typesetting output devices. If a + glyph named '\|' is defined in the current font, its width is used + instead, even on terminal output devices. + + -- Escape sequence: \^ + Move one-twelfth em to the right on typesetting output devices. If + a glyph named '\^' is defined in the current font, its width is + used instead, even on terminal output devices. + + -- Escape sequence: \0 + Move right by the width of a numeral in the current font. + + Horizontal motions are not discarded at the end of an output line as +word spaces are. *Note Breaking::. + + -- Escape sequence: \w'anything' + -- Register: \n[st] + -- Register: \n[sb] + -- Register: \n[rst] + -- Register: \n[rsb] + -- Register: \n[ct] + -- Register: \n[ssc] + -- Register: \n[skw] + Interpolate the width of ANYTHING in basic units. This escape + sequence allows several properties of formatted output to be + measured without writing it out. + + The length of the string 'abc' is \w'abc'u. + => The length of the string 'abc' is 72u. + + ANYTHING is processed in a dummy environment: this means that font + and type size changes, for example, may occur within it without + affecting subsequent output. + + After each use, '\w' sets several registers. + + 'st' + 'sb' + The maximum vertical displacements of the text baseline above + and below, respectively. The sign convention is opposite that + of relative vertical motions; that is, depth below the + (original) baseline is negative. These registers are + incorrectly documented in the AT&T 'troff' manual as "the + highest and lowest extent of [the argument to '\w'] relative + to the baseline". + + 'rst' + 'rsb' + Like 'st' and 'sb', but taking account of the heights and + depths of glyphs. In other words, these registers store the + highest and lowest vertical positions attained by ANYTHING, + doing what AT&T 'troff' documented 'st' and 'sb' as doing. + + 'ct' + Characterizes the geometry of glyphs occurring in ANYTHING. + + 0 + only short glyphs, no descenders or tall glyphs + + 1 + at least one descender + + 2 + at least one tall glyph + + 3 + at least one each of a descender and a tall glyph + + 'ssc' + The amount of horizontal space (possibly negative) that should + be added to the last glyph before a subscript. + + 'skw' + How far to right of the center of the last glyph in the '\w' + argument, the center of an accent from a roman font should be + placed over that glyph. + + -- Escape sequence: \kp + -- Escape sequence: \k(ps + -- Escape sequence: \k[position] + Store the current horizontal position in the _input_ line in a + register with the name POSITION (one-character name P, + two-character name PS). Use this, for example, to return to the + beginning of a string for highlighting or other decoration. + + -- Register: \n[hp] + The current horizontal position at the input line. + + -- Register: \n[.k] + A read-only register containing the current horizontal output + position (relative to the current indentation). + + -- Escape sequence: \o'abc...' + Overstrike the glyphs of characters A, B, C, ...; the glyphs are + centered, written, and the drawing position advanced by the widest + of the glyphs. + + -- Escape sequence: \zc + Format the character C with zero width; that is, without advancing + the drawing position. Use '\z' to overstrike glyphs aligned to + their left edges, in contrast to '\o''s centering. + + -- Escape sequence: \Z'anything' + Save the drawing position, format ANYTHING, then restore it. Tabs + and leaders in the argument are ignored with an error diagnostic. + + We might implement a strike-through macro thus. + + .de ST + .nr width \w'\\$1' + \Z@\v'-.25m'\l'\\n[width]u'@\\$1 + .. + . + This is + .ST "a test" + an actual emergency! + + +File: groff.info, Node: Page Motions-Footnotes, Up: Page Motions + + (1) At the 'grops' defaults of 10-point type on 12-point vertical +spacing, the difference between half a vee and half an em can be subtle: +large spacings like '.vs .5i' make it obvious. + + (2) *Note Strings::, for an explanation of the trailing '\"'. + + +File: groff.info, Node: Drawing Geometric Objects, Next: Traps, Prev: Page Motions, Up: GNU troff Reference + +5.26 Drawing Geometric Objects +============================== + +A few of the formatter's escape sequences draw lines and other geometric +objects. Combined with each other and with page motion commands (*note +Page Motions::), a wide variety of figures is possible. For complex +drawings, these operations can be cumbersome; the preprocessors 'gpic' +or 'ggrn' are typically used instead. + + The '\l' and '\L' escape sequences draw horizontal and vertical +sequences of glyphs, respectively. Even the simplest of output devices +supports them. + + -- Escape sequence: \l'l' + -- Escape sequence: \l'lc' + Draw a horizontal line of length L from the drawing position. + Rightward motion is positive. Afterward, the drawing position is + at the right end of the line. The default scaling unit is 'm'. + + The optional second parameter C is a character with which to draw + the line. The default is the baseline rule special character, + '\[ru]'. + + If C is a valid scaling unit, put '\&' after L to disambiguate the + input. + + .de textbox + \[br]\\$*\[br]\l'|0\[rn]'\l'|0\[ul]' + .. + + The foregoing outputs a box rule (a vertical line), the text + argument(s), and another box rule. We employ the boundary-relative + motion operator '|'. Finally, the line-drawing escape sequences + draw a radical extender (a form of overline) and an underline from + the drawing position to the position coresponding to beginning of + the _input_ line. The drawing position returns to just after the + right-hand box rule because the lengths of the drawn lines are + negative, as noted above. + + -- Escape sequence: \L'l' + -- Escape sequence: \L'lc' + Draw a vertical line of length L from the drawing position. + Downward motion is positive. The default scaling unit is 'v'. The + default character is the box rule, '\[br]'. As with vertical + motion escape sequences, text processing continues where the line + ends. '\L' is otherwise similar to '\l'. + + $ nroff < This is a + => | + => | + => |test. + + When writing text, the drawing position is at the text baseline; + recall *note Page Geometry::. + + The '\D' escape sequence provides "drawing commands" that direct the +output device to render geometrical objects rather than glyphs. +Specific devices may support only a subset, or may feature additional +ones; consult the man page for the output driver in use. Terminal +devices in particular implement almost none. *Note Graphics Commands::. + + Rendering starts at the drawing position; when finished, the drawing +position is left at the rightmost point of the object, even for closed +figures, except where noted. GNU 'troff' draws stroked (outlined) +objects with the stroke color, and shades filled ones with the fill +color. *Note Colors::. Coordinates H and V are horizontal and vertical +motions relative to the drawing position or previous point in the +command. The default scaling unit for horizontal measurements (and +diameters of circles) is 'm'; for vertical ones, 'v'. + + Circles, ellipses, and polygons can be drawn filled or stroked. +These are independent properties; if you want a filled, stroked figure, +you must draw the same figure twice using each drawing command. A +filled figure is always smaller than an outlined one because the former +is drawn only within its defined area, whereas strokes have a line +thickness (set with '\D't''). + + \h'1i'\v'1i'\ + \# increase line thickness + \Z'\D't 5p''\ + \# draw stroked (unfilled) polygon + \Z'\D'p 3 3 -6 0''\ + \# draw filled (solid) polygon + \Z'\D'P 3 3 -6 0'' + + -- Escape sequence: \D'command argument ...' + Drawing command escape sequence parameters begin with an ordinary + character, COMMAND, selecting the type of object to be drawn, + followed by ARGUMENTs whose meaning is determined by COMMAND. + + '\D'~ H1 V1 ... HN VN'' + Draw a B-spline to each point in sequence, leaving the drawing + position at (HN, VN). + + '\D'a HC VC H V'' + Draw a circular arc centered at (HC, VC) counterclockwise from + the drawing position to a point (H, V) relative to the center. + (1) (*note Drawing Geometric Objects-Footnote-1::) + + '\D'c D'' + Draw a circle of diameter D with its leftmost point at the + drawing position. + + '\D'C D'' + As '\D'C ...'', but the circle is filled. + + '\D'e H V'' + Draw an ellipse of width H and height V with its leftmost + point at the drawing position. + + '\D'E X Y'' + As '\D'e ...'', but the ellipse is filled. + + '\D'l DX DY'' + Draw line from the drawing position to (H, V). + + The following is a macro for drawing a box around a text + argument; for simplicity, the box margin is a fixed at 0.2m. + + .de TEXTBOX + . nr @wd \w'\\$1' + \h'.2m'\ + \h'-.2m'\v'(.2m - \\n[rsb]u)'\ + \D'l 0 -(\\n[rst]u - \\n[rsb]u + .4m)'\ + \D'l (\\n[@wd]u + .4m) 0'\ + \D'l 0 (\\n[rst]u - \\n[rsb]u + .4m)'\ + \D'l -(\\n[@wd]u + .4m) 0'\ + \h'.2m'\v'-(.2m - \\n[rsb]u)'\ + \\$1\ + \h'.2m' + .. + + The argument is measured with the '\w' escape sequence. Its + width is stored in register '@wd'. '\w' also sets the + registers 'rst' and 'rsb'; these contain its maximum vertical + extents of the argument. Then, four lines are drawn to form a + box, offset by the box margin. + + '\D'p H1 V1 ... HN VN'' + Draw polygon with vertices at drawing position and each point + in sequence. GNU 'troff' closes the polygon by drawing a line + from (HN, VN) back to the initial drawing position. + Afterward, the drawing position is left at (HN, VN). + + '\D'P DX1 DY1 DX2 DY2 ...'' + As '\D'P ...'', but the polygon is filled. + + The following macro is like the '\D'l'' example, but shades + the box. We draw the box before writing the text because + colors in GNU 'troff' have no transparency; in othe opposite + order, the filled polygon would occlude the text. + + .de TEXTBOX + . nr @wd \w'\\$1' + \h'.2m'\ + \h'-.2m'\v'(.2m - \\n[rsb]u)'\ + \M[lightcyan]\ + \D'P 0 -(\\n[rst]u - \\n[rsb]u + .4m) \ + (\\n[@wd]u + .4m) 0 \ + 0 (\\n[rst]u - \\n[rsb]u + .4m) \ + -(\\n[@wd]u + .4m) 0'\ + \h'.2m'\v'-(.2m - \\n[rsb]u)'\ + \M[]\ + \\$1\ + \h'.2m' + .. + + '\D't N'' + Set the stroke thickness of geometric objects to N basic + units. A zero N selects the minimal supported thickness. A + negative N selects a thickness proportional to the type size; + this is the default. + + In a hazy penumbra between text rendering and drawing commands we +locate the bracket-building escape sequence, '\b'. It can assemble +apparently large glyphs by vertically stacking ordinary ones. + + -- Escape sequence: \b'contents' + Pile and center a sequence of glyphs vertically on the output line. + "Piling" stacks glyphs corresponding to each character in CONTENTS, + read from left to right, and placed from top to bottom. GNU + 'troff' separates the glyphs vertically by 1m, and the pile itself + is centered 0.5m above the text baseline. The horizontal drawing + position is then advanced by the width of the widest glyph in the + pile. + + This rather inflexible positioning algorithm doesn't work with the + 'dvi' output device since its bracket pieces vary in height. + Instead, use the 'geqn' preprocessor. + + *note Manipulating Spacing:: describes how to adjust the vertical + spacing of the output line with the '\x' escape sequence. + + The application of '\b' that lends its name is construction of + brackets, braces, and parentheses when typesetting mathematics. We + might construct a large opening (left) brace as follows. + + \b'\[lt]\[bv]\[lk]\[bv]\[lb]' + + See 'groff_char(7)' for a list of special character identifiers. + + +File: groff.info, Node: Drawing Geometric Objects-Footnotes, Up: Drawing Geometric Objects + + (1) (HC, VC) is adjusted to the point nearest the perpendicular +bisector of the arc's chord. + + +File: groff.info, Node: Deferring Output, Next: Traps, Prev: Drawing Geometric Objects, Up: GNU troff Reference + +5.27 Deferring Output +===================== + +A few 'roff' language elements are generally not used in simple +documents, but arise as page layouts become more sophisticated and +demanding. "Environments" collect formatting parameters like line +length and typeface. A "diversion" stores formatted output for later +use. A "trap" is a condition on the input or output, tested +automatically by the formatter, that is associated with a macro, causing +it to be called when that condition is fulfilled. + + Footnote support often exercises all three of the foregoing features. +A simple implementation might work as follows. A pair of macros is +defined: one starts a footnote and the other ends it. The author calls +the first macro where a footnote marker is desired. The macro +establishes a diversion so that the footnote text is collected at the +place in the body text where its corresponding marker appears. An +environment is created for the footnote so that it is set at a smaller +typeface. The footnote text is formatted in the diversion using that +environment, but it does not yet appear in the output. The document +author calls the footnote end macro, which returns to the previous +environment and ends the diversion. Later, after much more body text in +the document, a trap, set a small distance above the page bottom, is +sprung. The macro called by the trap draws a line across the page and +emits the stored diversion. Thus, the footnote is rendered. + + Diversions and traps make the text formatting process non-linear. +Let us imagine a set of text lines or paragraphs labelled 'A', 'B', and +so on. If we set up a trap that produces text 'T' (as a page footer, +say), and we also use a diversion to store the formatted text 'D', then +a document with input text in the order 'A B C D E F' might render as 'A +B C E T F'. The diversion 'D' will never be output if we do not call +for it. + + Environments of themselves are not a source of non-linearity in +document formatting: environment switches have immediate effect. One +could always write a macro to change as many formatting parameters as +desired with a single convenient call. But because diversions can be +nested and macros called by traps that are sprung by other trap-called +macros, they may be called upon in varying contexts. For example, +consider a page header that is always to be set in Helvetica. A +document that uses Times for most of its body text, but Courier for +displayed code examples, poses a challenge if a page break occurs in the +middle of a code display; if the header trap assumes that the "previous +font" is always Times, the rest of the example will be formatted in the +wrong typeface. One could carefully save all formatting parameters upon +entering the trap and restore them upon leaving it, but this is verbose, +error-prone, and not future-proof as the 'groff' language develops. +Environments save us considerable effort. + + +File: groff.info, Node: Traps, Next: Diversions, Prev: Deferring Output, Up: GNU troff Reference + +5.28 Traps +========== + +"Traps" are locations in the output or conditions on the input that, +when reached or fulfilled, call a specified macro. These traps can +occur at a given location on the page, at a given location in the +current diversion (together, these are known as vertical position +traps), at a blank line, at a line with leading space characters, after +a quantity of input lines, or at the end of input. Macros called by +traps are passed no arguments. Setting a trap is also called "planting" +one. It is said that a trap is "sprung" if its condition is fulfilled. + +* Menu: + +* Vertical Position Traps:: +* Diversion Traps:: +* Input Line Traps:: +* Blank Line Traps:: +* Leading Space Traps:: +* End-of-input Traps:: + + +File: groff.info, Node: Vertical Position Traps, Next: Page Location Traps, Prev: Traps, Up: Traps + +5.28.1 Vertical Position Traps +------------------------------ + +A "vertical position trap" calls a macro when the formatter's vertical +drawing position reaches or passes, in the downward direction, a certain +location on the output page or in a diversion. Its applications include +setting page headers and footers, body text in multiple columns, and +footnotes. + + -- Request: .vpt [flag] + -- Register: \n[.vpt] + Enable vertical position traps if FLAG is non-zero or absent; + disable them otherwise. Vertical position traps are those set by + the 'wh' request or by 'dt' within a diversion. The parameter that + controls whether vertical position traps are enabled is global. + Initially, vertical position traps are enabled. The current value + is stored in the '.vpt' read-only register. + + A page can't be ejected if 'vpt' is set to zero; see *note The + Implicit Page Trap::. + +* Menu: + +* Page Location Traps:: +* The Implicit Page Trap:: +* Diversion Traps:: + + +File: groff.info, Node: Page Location Traps, Next: The Implicit Page Trap, Prev: Vertical Position Traps, Up: Vertical Position Traps + +5.28.1.1 Page Location Traps +............................ + +A "page location trap" is a vertical position trap that applies to the +page; that is, to undiverted output. Many can be present; manage them +with the 'wh' and 'ch' requests. + + -- Request: .wh dist [name] + Plant macro NAME as page location trap at DIST. The default + scaling unit is 'v'. Non-negative values for DIST set the trap + relative to the top of the page; negative values set the trap + relative to the bottom of the page. It is not possible to plant a + trap less than one basic unit from the page bottom: a DIST of '-0' + is interpreted as '0', the top of the page.(1) (*note Page + Location Traps-Footnote-1::) An existing _visible_ trap (see below) + at DIST is removed; this is 'wh''s sole function if NAME is + missing. + + A trap is sprung only if it is "visible", meaning that its location + is reachable on the page(2) (*note Page Location + Traps-Footnote-2::) and it is not hidden by another trap at the + same location already planted there. + + A macro package might set headers and footers as follows; this + example configures vertical margins of one inch to the body text, + and one half-inch to the titles. Observe the use of the no-break + control character with 'sp' request to position our text baselines, + and the page number character '%' used with the 'tl' request. + + .\" hdfo.roff + .de hd \" page header + ' sp .5i + ' tl '\\*(Ti''\\*(Da' \" title and date strings + ' sp .5i + .. + .de fo \" page footer + ' sp .5i + . tl ''%'' + . bp + .. + .wh 0 hd \" trap at top of the page + .wh -1i fo \" trap 1 inch from bottom + + To use these traps, copy the above (or load it from a file with the + 'so' or 'mso' requests), then set up the strings it uses. + + .so hdfo.roff + .ds Ti Final Report\" + .ds Da 21 May 2023\" + .ti + On 5 August of last year, + this committee tasked me with the investigation of the + CFIT (controlled flight into terrain) incident of + .\" ...and so on... + + A trap above the top or at or below the bottom of the page can be + made visible by either moving it into the page area or increasing + the page length so that the trap is on the page. Negative trap + values always use the _current_ page length; they are not converted + to an absolute vertical position. We can use the 'ptr' request to + dump our page location traps to the standard error stream (*note + Debugging::). Their positions are reported in basic units; an + 'nroff' device example follows. + + .pl 5i + .wh -1i xx + .ptr + error-> xx -240 + .pl 100i + .ptr + error-> xx -240 + + It is possible to have more than one trap at the same location + (although only one at a time can be visible); to achieve this, the + traps must be defined at different locations, then moved to the + same place with the 'ch' request. In the following example, the + many empty lines caused by the 'bp' request are not shown in the + output. + + .de a + . nop a + .. + .de b + . nop b + .. + .de c + . nop c + .. + . + .wh 1i a + .wh 2i b + .wh 3i c + .bp + => a b c + .ch b 1i + .ch c 1i + .bp + => a + .ch a 0.5i + .bp + => a b + + -- Register: \n[.t] + The read-only register '.t' holds the distance to the next vertical + position trap. If there are no traps between the current position + and the bottom of the page, it contains the distance to the page + bottom. Within a diversion, in the absence of a diversion trap, + this distance is the largest representable integer in basic + units--effectively infinite. + + -- Request: .ch name [dist] + Change the location of a trap by moving macro NAME to new location + DIST, or by unplanting it altogether if DIST is absent. The + default scaling unit is 'v'. Parameters to 'ch' are specified in + the opposite order from 'wh'. If NAME is the earliest planted + macro of multiple traps at the same location, (re)moving it from + that location exposes the macro next least recently planted at the + same place.(3) (*note Page Location Traps-Footnote-3::) + + Changing a trap's location is useful for building up footnotes in a + diversion to allow more space at the bottom of the page for them. + + The same macro can be installed simultaneously at multiple locations; +however, only the earliest-planted instance--that has not yet been +deleted with 'wh'--will be moved by 'ch'. The following example (using +an 'nroff' device) illustrates this behavior. Blank lines have been +elided from the output. + + .de T + Trap sprung at \\n(nlu. + .br + .. + .wh 1i T + .wh 2i T + foo + .sp 11i + .bp + .ch T 4i + bar + .sp 11i + .bp + .ch T 5i + baz + .sp 11i + .bp + .wh 5i + .ch T 6i + qux + .sp 11i + => foo + => Trap sprung at 240u. + => Trap sprung at 480u. + => bar + => Trap sprung at 480u. + => Trap sprung at 960u. + => baz + => Trap sprung at 480u. + => Trap sprung at 1200u. + => qux + => Trap sprung at 1440u. + + -- Register: \n[.ne] + The read-only register '.ne' contains the amount of space that was + needed in the last 'ne' request that caused a trap to be sprung; it + is useful in conjunction with the '.trunc' register. *Note Page + Control::. Since the '.ne' register is set only by traps, it + doesn't make sense to interpolate it outside of macros called by + traps. + + -- Register: \n[.trunc] + A read-only register containing the amount of vertical space + truncated from an 'sp' request by the most recently sprung vertical + position trap, or, if the trap was sprung by an 'ne' request, minus + the amount of vertical motion produced by the 'ne' request. In + other words, at the point a trap is sprung, it represents the + difference of what the vertical position would have been but for + the trap, and what the vertical position actually is. Since the + '.trunc' register is set only by traps, it doesn't make sense to + interpolate it outside of macros called by traps. + + -- Register: \n[.pe] + This Boolean-valued, read-only register interpolates 1 while a page + is being ejected, and 0 otherwise. + + In the following example, we plant the same trap at the top and the + bottom of the page. We also make the trap report its name and the + vertical drawing position. + + .de T + .tm \\$0: page \\n%, nl=\\n[nl] .pe=\\n[.pe] + .. + .ll 46n + .wh 0 T + .wh -1v T + Those who can make you believe absurdities can make you + commit atrocities. \[em] Voltaire + error-> T: page 1, nl=0 .pe=0 + error-> T: page 1, nl=2600 .pe=1 + => Those who can make you believe absurdities can + => make you commit atrocities. -- Voltaire + + When designing macros, keep in mind that diversions and traps do +normally interact. For example, if a trap calls a header macro (while +outputting a diversion) that tries to change the font on the current +page, the effect is not visible before the diversion has completely been +printed (except for input protected with '\!' or '\?') since the data in +the diversion is already formatted. In most cases, this is not the +expected behaviour. + + +File: groff.info, Node: Page Location Traps-Footnotes, Up: Page Location Traps + + (1) *Note The Implicit Page Trap::. + + (2) A trap planted at '20i' or '-30i' will not be sprung on a page of +length '11i'. + + (3) It may help to think of each trap location as maintaining a +queue; 'wh' operates on the head of the queue, and 'ch' operates on its +tail. Only the trap at the head of the queue is visible. + + +File: groff.info, Node: The Implicit Page Trap, Next: Diversion Traps, Prev: Page Location Traps, Up: Vertical Position Traps + +5.28.1.2 The Implicit Page Trap +............................... + +If, after starting GNU 'troff' without loading a macro package, you use +the 'ptr' request to dump a list of the active traps to the standard +error stream,(1) (*note The Implicit Page Trap-Footnote-1::) nothing is +reported. Yet the '.t' register will report a steadily decreasing value +with every output line your document produces, and once the value of +'.t' gets to within '.V' of zero, you will notice that something +trap-like happens--the page is ejected, a new one begins, and the value +of '.t' becomes large once more. + + This "implicit page trap" always exists in the top-level +diversion;(2) (*note The Implicit Page Trap-Footnote-2::) it works like +a trap in some ways but not others. Its purpose is to eject the current +page and start the next one. It has no name, so it cannot be moved or +deleted with 'wh' or 'ch' requests. You cannot hide it by placing +another trap at its location, and can move it only by redefining the +page length with 'pl'. Its operation is suppressed when vertical page +traps are disabled with GNU 'troff''s 'vpt' request. + + +File: groff.info, Node: The Implicit Page Trap-Footnotes, Up: The Implicit Page Trap + + (1) *Note Debugging::. + + (2) *Note Diversions::. + + +File: groff.info, Node: Diversion Traps, Next: Input Line Traps, Prev: The Implicit Page Trap, Up: Vertical Position Traps + +5.28.1.3 Diversion Traps +........................ + +A diversion is not formatted in the context of a page, so it lacks page +location traps; instead it can have a "diversion trap". There can exist +at most one such vertical position trap per diversion. + + -- Request: .dt [dist name] + Set a trap _within_ a diversion at location DIST, which is + interpreted relative to diversion rather than page boundaries. If + invoked with fewer than two arguments, any diversion trap in the + current diversion is removed. The register '.t' works within + diversions. It is an error to invoke 'dt' in the top-level + diversion. *Note Diversions::. + + +File: groff.info, Node: Input Line Traps, Next: Blank Line Traps, Prev: Diversion Traps, Up: Traps + +5.28.2 Input Line Traps +----------------------- + + -- Request: .it [n name] + -- Request: .itc [n name] + Set an input line trap, calling macro NAME after processing the + next N productive input lines (recall *note Manipulating Filling + and Adjustment::). Any existing input line trap in the environment + is replaced. Without arguments, 'it' and 'itc' clear any input + line trap that has not yet sprung. + + Consider a macro '.ST S N' which sets the next N input lines in the + font style S. + + .de ST \" Use style $1 for next $2 text lines. + . it \\$2 ES + . ft \\$1 + .. + .de ES \" end ST + . ft R + .. + .ST I 1 + oblique + face + .ST I 1 + oblique\c + face + => oblique face obliqueface (second "face" upright) + + Unlike the 'ce' and 'rj' requests, 'it' counts lines interrupted + with the '\c' escape sequence separately (*note Line + Continuation::); 'itc' does not. To see the difference, let's + change the previous example to use 'itc' instead. + + ... + . itc \\$2 ES + ... + => oblique face obliqueface (second "face" oblique) + + You can think of the 'ce' and 'rj' requests as implicitly creating + an input line trap with 'itc' that schedules a break when the trap + is sprung. + + .de BR + . br + . internal: disable centering-without-filling + .. + . + .de ce + . if \\n[.br] .br + . itc \\$1 BR + . internal: enable centering-without-filling + .. + + Let us consider in more detail the sorts of input lines that are or + are not "productive". + + .de Trap + TRAP SPRUNG + .. + .de Mac + .if r a \l'5n' + .. + .it 2 Trap + . + foo + .Mac + bar + baz + .it 1 Trap + .sp \" moves, but does not write or draw + qux + .itc 1 Trap + \h'5n'\c \" moves, but does not write or draw + jat + + When 'Trap' gets called depends on whether the 'a' register is + defined; the control line with the 'if' request may or may not + produce written output. We also see that the spacing request 'sp', + while certainly affecting the output, does not spring the input + line trap. Similarly, the horizontal motion escape sequence '\h' + also affected the output, but was not "written". Observe that we + had to follow it with '\c' and use 'itc' to prevent the newline at + the end of the text line from causing a word break, which, like an + ordinary space character, counts as written output. + + $ groff -Tascii input-trap-example.groff + => foo bar TRAP SPRUNG baz + => + => qux TRAP SPRUNG jat TRAP SPRUNG + $ groff -Tascii -ra1 input-trap-example.groff + => foo _____ TRAP SPRUNG bar baz + => + => qux TRAP SPRUNG jat TRAP SPRUNG + + Input line traps are associated with the environment (*note +Environments::); switching to another environment suspends the current +input line trap, and going back resumes it, restoring the count of +qualifying lines enumerated in that environment. + + +File: groff.info, Node: Blank Line Traps, Next: Leading Space Traps, Prev: Input Line Traps, Up: Traps + +5.28.3 Blank Line Traps +----------------------- + + -- Request: .blm [name] + Set a blank line trap, calling the macro NAME when GNU 'troff' + encounters a blank line in an input file, instead of the usual + behavior (*note Breaking::). A line consisting only of spaces is + also treated as blank and subject to this trap. If no argument is + supplied, the default blank line behavior is (re-)established. + + +File: groff.info, Node: Leading Space Traps, Next: End-of-input Traps, Prev: Blank Line Traps, Up: Traps + +5.28.4 Leading Space Traps +-------------------------- + + -- Request: .lsm [name] + -- Register: \n[lsn] + -- Register: \n[lss] + Set a leading space trap, calling the macro NAME when GNU 'troff' + encounters leading spaces in an input line; the implicit line break + that normally happens in this case is suppressed. If no argument + is supplied, the default leading space behavior is (re-)established + (*note Breaking::). + + The count of leading spaces on an input line is stored in register + 'lsn', and the amount of corresponding horizontal motion in + register 'lss', irrespective of whether a leading space trap is + set. When it is, the leading spaces are removed from the input + line, and no motion is produced before calling NAME. + + +File: groff.info, Node: End-of-input Traps, Prev: Leading Space Traps, Up: Traps + +5.28.5 End-of-input Traps +------------------------- + + -- Request: .em [name] + Set a trap at the end of input, calling macro NAME after the last + line of the last input file has been processed. If no argument is + given, any existing end-of-input trap is removed. + + For example, if the document had to have a section at the bottom of + the last page for someone to approve it, the 'em' request could be + used. + + .de approval + \c + . ne 3v + . sp (\\n[.t]u - 3v) + . in +4i + . lc _ + . br + Approved:\t\a + . sp + Date:\t\t\a + .. + . + .em approval + + The '\c' in the above example needs explanation. For historical + reasons (compatibility with AT&T 'troff'), the end-of-input macro + exits as soon as it causes a page break if no partially collected + line remains.(1) (*note End-of-input Traps-Footnote-1::) + + Let us assume that there is no '\c' in the above 'approval' macro, + that the page is full, and last output line has been broken with, + say, a 'br' request. Because there is no more room, a 'ne' request + at this point causes a page ejection, which in turn makes 'troff' + exit immediately as just described. In most situations, this is + not desired; people generally want to format the input after 'ne'. + + To force processing of the whole end-of-input macro independently + of this behavior, it is thus advisable to (invisibly) ensure the + existence of a partially collected line ('\c') whenever there is a + chance that a page break can happen. In the above example, + invoking the 'ne' request ensures that there is room for the + subsequent formatted output on the same page, so we need insert + '\c' only once. + + The next example shows how to append three lines, then start a new + page unconditionally. Since '.ne 1' doesn't give the desired + effect--there is always one line available or we are already at the + beginning of the next page--we temporarily increase the page length + by one line so that we can use '.ne 2'. + + .de EM + .pl +1v + \c + .ne 2 + line one + .br + \c + .ne 2 + line two + .br + \c + .ne 2 + line three + .br + .pl -1v + \c + 'bp + .. + .em EM + + This specific feature affects only the first potential page break + caused by the end-of-input macro; further page breaks emitted by + the macro are handled normally. + + Another possible use of the 'em' request is to make GNU 'troff' + emit a single large page instead of multiple pages. For example, + one may want to produce a long plain text file for reading in a + terminal or emulator without page footers and headers interrupting + the body of the document. One approach is to set the page length + at the beginning of the document to a very large value to hold all + the text,(2) (*note End-of-input Traps-Footnote-2::) and + automatically adjust it to the exact height of the document after + the text has been output. + + .de adjust-page-length + . br + . pl \\n[nl]u \" \n[nl]: current vertical position + .. + . + .de single-page-mode + . pl 99999 + . em adjust-page-length + .. + . + .\" Activate the above code if configured. + .if \n[do-continuous-rendering] \ + . single-page-mode + + Since only one end-of-input trap exists and another macro package + may already use it, care must be taken not to break the mechanism. + A simple solution would be to append the above macro to the macro + package's end-of-input macro using the 'am' request. + + +File: groff.info, Node: End-of-input Traps-Footnotes, Up: End-of-input Traps + + (1) While processing an end-of-input macro, the formatter assumes +that the next page break must be the last; it goes into "sudden death +overtime". + + (2) Another, taken by the 'groff' 'man' macros, is to intercept 'ne' +requests and wrap 'bp' ones. + + +File: groff.info, Node: Diversions, Next: Punning Names, Prev: Traps, Up: GNU troff Reference + +5.29 Diversions +=============== + +In 'roff' systems it is possible to format text as if for output, but +instead of writing it immediately, one can "divert" the formatted text +into a named storage area. It is retrieved later by specifying its name +after a control character. The same name space is used for such +diversions as for strings and macros; see *note Identifiers::. Such +text is sometimes said to be "stored in a macro", but this coinage +obscures the important distinction between macros and strings on one +hand and diversions on the other; the former store _unformatted_ input +text, and the latter capture _formatted_ output. Diversions also do not +interpret arguments. Applications of diversions include "keeps" +(preventing a page break from occurring at an inconvenient place by +forcing a set of output lines to be set as a group), footnotes, tables +of contents, and indices. For orthogonality it is said that GNU 'troff' +is in the "top-level diversion" if no diversion is active (that is, +formatted output is being "diverted" immediately to the output device). + + Dereferencing an undefined diversion will create an empty one of that +name and cause a warning in category 'mac' to be emitted. *Note +Warnings::, for information about the enablement and suppression of +warnings. A diversion does not exist for the purpose of testing with +the 'd' conditional operator until its initial definition ends (*note +Operators in Conditionals::). The following requests are used to create +and alter diversions. + + -- Request: .di [name] + -- Request: .da [name] + Start collecting formatted output in a diversion called NAME. The + 'da' request appends to a diversion called NAME, creating it if + necessary. If NAME already exists as an alias, the target of the + alias is replaced or appended to; recall *note Strings::. The + pending output line is diverted as well. Switching to another + environment (with the 'ev' request) before invoking 'di' or 'da' + avoids including any pending output line in the diversion; see + *note Environments::. + + Invoking 'di' or 'da' without an argument stops diverting output to + the diversion named by the most recent corresponding request. If + 'di' or 'da' is called without an argument when there is no current + diversion, a warning in category 'di' is produced. *Note + Warnings::, for information about the enablement and suppression of + warnings. + + Before the diversion. + .di yyy + In the diversion. + .br + .di + After the diversion. + .br + => After the diversion. + .yyy + => Before the diversion. In the diversion. + + GNU 'troff' supports "box" requests to exclude a partially collected +line from a diversion, as this is often desirable. + + -- Request: .box [name] + -- Request: .boxa [name] + Divert (or append) output to NAME, similarly to the 'di' and 'da' + requests, respectively. Any pending output line is _not_ included + in the diversion. Without an argument, stop diverting output; any + pending output line inside the diversion is discarded. + + Before the box. + .box xxx + In the box. + .br + Hidden treasure. + .box + After the box. + .br + => Before the box. After the box. + .xxx + => In the box. + + Apart from pending output line inclusion and the request names that +populate them, boxes are handled exactly as diversions are. All of the +following 'groff' language elements can be used with them +interchangeably. + + -- Register: \n[.z] + -- Register: \n[.d] + Diversions may be nested. The read-only string-valued register + '.z' contains the name of the current diversion. The read-only + register '.d' contains the current vertical place in the diversion. + If the input text is not being diverted, '.d' reports the same + location as the register 'nl'. + + -- Register: \n[.h] + The read-only register '.h' stores the "high-water mark" on the + current page or in the current diversion. It corresponds to the + text baseline of the lowest line on the page.(1) (*note + Diversions-Footnote-1::) + + .tm .h==\n[.h], nl==\n[nl] + => .h==0, nl==-1 + This is a test. + .br + .sp 2 + .tm .h==\n[.h], nl==\n[nl] + => .h==40, nl==120 + + As implied by the example, vertical motion does not produce text + baselines and thus does not increase the value interpolated by + '\n[.h]'. + + -- Register: \n[dn] + -- Register: \n[dl] + After completing a diversion, the writable registers 'dn' and 'dl' + contain its vertical and horizontal sizes. Only the lines just + processed are counted: for the computation of 'dn' and 'dl', the + requests 'da' and 'boxa' are handled as if 'di' and 'box' had been + used, respectively--lines that have been already stored in the + diversion (box) are not taken into account. + + .\" Center text both horizontally and vertically. + .\" Macro .(c starts centering mode; .)c terminates it. + . + .\" Disable the escape character with .eo so that we + .\" don't have to double backslashes on the "\n"s. + .eo + .de (c + . br + . ev (c + . evc 0 + . in 0 + . nf + . di @c + .. + .de )c + . br + . ev + . di + . nr @s (((\n[.t]u - \n[dn]u) / 2u) - 1v) + . sp \n[@s]u + . ce 1000 + . @c + . ce 0 + . sp \n[@s]u + . br + . fi + . rr @s + . rm @c + .. + .ec + + -- Escape sequence: \!anything + -- Escape sequence: \?anything\? + "Transparently" embed ANYTHING into the current diversion, + preventing requests, macro calls, and escape sequences from being + interpreted when read into a diversion. This is useful for + preventing them from taking effect until the diverted text is + actually output. The '\!' escape sequence transparently embeds + input up to and including the end of the line. The '\?' escape + sequence transparently embeds input until its own next occurrence. + + ANYTHING may not contain newlines; use '\!' by itself to embed + newlines in a diversion. The escape sequence '\?' is also + recognized in copy mode and turned into a single internal code; it + is this code that terminates ANYTHING. Thus the following example + prints 4. + + .nr x 1 + .nf + .di d + \?\\?\\\\?\\\\\\\\nx\\\\?\\?\? + .di + .nr x 2 + .di e + .d + .di + .nr x 3 + .di f + .e + .di + .nr x 4 + .f + + Both escape sequences read the data in copy mode. + + If '\!' is used in the top-level diversion, its argument is + directly embedded into GNU 'troff''s intermediate output. This can + be used, for example, to control a postprocessor that processes the + data before it is sent to an output driver. + + The '\?' escape used in the top-level diversion produces no output + at all; its argument is simply ignored. + + -- Request: .output contents + Emit CONTENTS directly to GNU 'troff''s intermediate output + (subject to copy mode interpretation); this is similar to '\!' used + at the top level. An initial neutral double quote in CONTENTS is + stripped to allow embedding of leading spaces. + + This request can't be used before the first page has started--if + you get an error, simply insert '.br' before the 'output' request. + + Use with caution! It is normally only needed for mark-up used by a + postprocessor that does something with the output before sending it + to the output device, filtering out CONTENTS again. + + -- Request: .asciify div + "Unformat" the diversion DIV in a way such that Unicode basic Latin + (ASCII) characters, characters translated with the 'trin' request, + space characters, and some escape sequences, that were formatted + and diverted into DIV are treated like ordinary input characters + when DIV is reread. Doing so can be useful in conjunction with the + 'writem' request. 'asciify' can be also used for gross hacks; for + example, the following sets register 'n' to 1. + + .tr @. + .di x + @nr n 1 + .br + .di + .tr @@ + .asciify x + .x + + 'asciify' cannot return all items in a diversion to their source + equivalent: nodes such as those produced by the '\N' escape + sequence will remain nodes, so the result cannot be guaranteed to + be a pure string. *Note Copy Mode::. Glyph parameters such as the + type face and size are not preserved; use 'unformat' to achieve + that. + + -- Request: .unformat div + Like 'asciify', unformat the diversion DIV. However, 'unformat' + handles only tabs and spaces between words, the latter usually + arising from spaces or newlines in the input. Tabs are treated as + input tokens, and spaces become adjustable again. The vertical + sizes of lines are not preserved, but glyph information (font, type + size, space width, and so on) is retained. + + +File: groff.info, Node: Diversions-Footnotes, Up: Diversions + + (1) Thus, the "water" gets "higher" proceeding _down_ the page. + + +File: groff.info, Node: Punning Names, Next: Environments, Prev: Diversions, Up: GNU troff Reference + +5.30 Punning Names +================== + +Macros, strings, and diversions share a name space; recall *note +Identifiers::. Internally, the same mechanism is used to store them. +You can thus call a macro with string interpolation syntax and vice +versa. + + .de subject + Typesetting + .. + .de predicate + rewards attention to detail + .. + \*[subject] \*[predicate]. + Truly. + => Typesetting + => rewards attention to detail Truly. + +What went wrong? Strings don't contain newlines, but macros do. String +interpolation placed a newline at the end of '\*[subject]', and the next +thing on the input was a space. Then when '\*[predicate]' was +interpolated, it was followed by the empty request '.' on a line by +itself. If we want to use macros as strings, we must take interpolation +behavior into account. + + .de subject + Typesetting\\ + .. + .de predicate + rewards attention to detail\\ + .. + \*[subject] \*[predicate]. + Truly. + => Typesetting rewards attention to detail. Truly. + +By ending each text line of the macros with an escaped '\', we get +the desired effect (*note Line Continuation::).(1) (*note Punning +Names-Footnote-1::) What would have happened if we had used only one +backslash at a time instead? + + Interpolating a string does not hide existing macro arguments. We +can also place the escaped newline outside the string interpolation +instead of within the string definition. Thus, in a macro, a more +efficient way of doing + + .xx \\$@ + +is + + \\*[xx]\\ + +The latter calling syntax doesn't change the value of '\$0', which is +then inherited from the calling macro (*note Parameters::). + + Diversions can be also called with string syntax. It is sometimes +convenient to copy one-line diversions to a string. + + .di xx + the + .ft I + interpolation system + .ft + .br + .di + .ds yy This is a test of \*(xx\c + \*(yy. + => This is a test of the interpolation system. + +As the previous example shows, it is possible to store formatted output +in strings. The '\c' escape sequence prevents the subsequent newline +from being interpreted as a break (again, *note Line Continuation::). + + Copying multi-output line diversions produces unexpected results. + + .di xxx + a funny + .br + test + .br + .di + .ds yyy This is \*[xxx]\c + \*[yyy]. + => test This is a funny. + + Usually, it is not predictable whether a diversion contains one or +more output lines, so this mechanism should be avoided. With AT&T +'troff', this was the only solution to strip off a final newline from a +diversion. Another disadvantage is that the spaces in the copied string +are already formatted, preventing their adjustment. This can cause ugly +results. + + A clean solution to this problem is available in GNU 'troff', using +the requests 'chop' to remove the final newline of a diversion, and +'unformat' to make the horizontal spaces adjustable again. + + .box xxx + a funny + .br + test + .br + .box + .chop xxx + .unformat xxx + This is \*[xxx]. + => This is a funny test. + + *Note Gtroff Internals::. + + +File: groff.info, Node: Punning Names-Footnotes, Up: Punning Names + + (1) The backslash is doubled. *Note Copy Mode::. + + +File: groff.info, Node: Environments, Next: Suppressing Output, Prev: Diversions, Up: GNU troff Reference + +5.31 Environments +================= + +As discussed in *note Deferring Output::, environments store most of the +parameters that determine the appearance of text. A default environment +named '0' exists when GNU 'troff' starts up; it is modified by +formatting-related requests and escape sequences. + + You can create new environments and switch among them. Only one is +current at any given time. Active environments are managed using a +"stack", a data structure supporting "push" and "pop" operations. The +current environment is at the top of the stack. The same environment +name can be pushed onto the stack multiple times, possibly interleaved +with others. Popping the environment stack does not destroy the current +environment; it remains accessible by name and can be made current again +by pushing it at any time. Environments cannot be renamed or deleted, +and can only be modified when current. To inspect the environment +stack, use the 'pev' request; see *note Debugging::. + + Environments store the following information. + + * a partially collected line, if any + + * data about the most recently output glyph and line (registers + '.cdp', '.cht', '.csk', '.n', '.w') + + * typeface parameters (size, family, style, height and slant, + inter-word and inter-sentence space sizes) + + * page parameters (line length, title length, vertical spacing, line + spacing, indentation, line numbering, centering, right-alignment, + underlining, hyphenation parameters) + + * filling enablement; adjustment enablement and mode + + * tab stops; tab, leader, escape, control, no-break control, + hyphenation, and margin characters + + * input line traps + + * stroke and fill colors + + -- Request: .ev [ident] + -- Register: \n[.ev] + Enter the environment IDENT, which is created if it does not + already exist, using the same parameters as for the default + environment used at startup. With no argument, GNU 'troff' + switches to the previous environment. + + Invoking 'ev' with an argument puts environment IDENT onto the top + of the environment stack. (If it isn't already present in the + stack, this is a proper push.) Without an argument, 'ev' pops the + environment stack, making the previous environment current. It is + an error to pop the environment stack with no previous environment + available. The read-only string-valued register '.ev' contains the + name of the current environment--the one at the top of the stack. + + .ev footnote-env + .fam N + .ps 6 + .vs 8 + .ll -.5i + .ev + + ... + + .ev footnote-env + \[dg] Observe the smaller text and vertical spacing. + .ev + + We can familiarize ourselves with stack behavior by wrapping the + 'ev' request with a macro that reports the contents of the '.ev' + register to the standard error stream. + + .de EV + . ev \\$1 + . tm environment is now \\n[.ev] + .. + . + .EV foo + .EV bar + .EV + .EV baz + .EV + .EV + .EV + + error-> environment is now foo + error-> environment is now bar + error-> environment is now foo + error-> environment is now baz + error-> environment is now foo + error-> environment is now 0 + error-> error: environment stack underflow + error-> environment is now 0 + + -- Request: .evc environment + Copy the contents of ENVIRONMENT to the current environment. + + The following environment data are not copied. + + * a partially collected line, if present; + + * the interruption status of the previous input line (due to use + of the '\c' escape sequence); + + * the count of remaining lines to center, to right-justify, or + to underline (with or without underlined spaces)--these are + set to zero; + + * the activation status of temporary indentation; + + * input line traps and their associated data; + + * the activation status of line numbering (which can be + reactivated with '.nm +0'); and + + * the count of consecutive hyphenated lines (set to zero). + + -- Register: \n[.w] + -- Register: \n[.cht] + -- Register: \n[.cdp] + -- Register: \n[.csk] + The '\n[.w]' register contains the width of the last glyph + formatted in the environment. + + The '\n[.cht]' register contains the height of the last glyph + formatted in the environment. + + The '\n[.cdp]' register contains the depth of the last glyph + formatted in the environment. It is positive for glyphs extending + below the baseline. + + The '\n[.csk]' register contains the "skew" (how far to the right + of the glyph's center that GNU 'troff' should place an accent) of + the last glyph formatted in the environment. + + -- Register: \n[.n] + The '\n[.n]' register contains the length of the previous output + line emitted in the environment. + + +File: groff.info, Node: Suppressing Output, Next: Colors, Prev: Environments, Up: GNU troff Reference + +5.32 Suppressing Output +======================= + + -- Escape sequence: \O[num] + Suppress GNU 'troff' output of glyphs and geometric objects. The + sequences '\O2', '\O3', '\O4', and '\O5' are intended for internal + use by 'grohtml'. + + '\O0' + Disable the emission of glyphs and geometric objects to the + output driver, provided that this sequence occurs at the + outermost suppression level (see '\O3' and '\04' below). + Horizontal motions corresponding to non-overstruck glyph + widths still occur. + + '\O1' + Enable the emission of glyphs and geometric objects to the + output driver, provided that this sequence occurs at the + outermost suppression level. + + '\O0' and '\O1' also reset the four registers 'opminx', 'opminy', + 'opmaxx', and 'opmaxy' to -1. These four registers mark the top + left and bottom right hand corners of a box encompassing all + written or drawn output. + + '\O2' + At the outermost suppression level, enable emission of glyphs + and geometric objects, and write to the standard error stream + the page number and values of the four aforementioned + registers encompassing glyphs written since the last + interpolation of a '\O' sequence, as well as the page offset, + line length, image file name (if any), horizontal and vertical + device motion quanta, and input file name. Numeric values are + in basic units. + + '\O3' + Begin a nested suppression level. 'grohtml' uses this + mechanism to create images of output preprocessed with 'gpic', + 'geqn', and 'gtbl'. At startup, GNU 'troff' is at the + outermost suppression level. 'pre-grohtml' generates these + sequences when processing the document, using GNU 'troff' with + the 'ps' output device, Ghostscript, and the PNM tools to + produce images in PNG format. They start a new page if the + device is not 'html' or 'xhtml', to reduce the number of + images crossing a page boundary. + + '\O4' + End a nested suppression level. + + '\O[5PFILE]' + At the outermost suppression level, write the name 'file' to + the standard error stream at position P, which must be one of + 'l', 'r', 'c', or 'i', corresponding to left, right, centered, + and inline alignments within the document, respectively. FILE + is a name associated with the production of the next image. + + -- Register: \n[.O] + Output suppression nesting level applied by '\O3' and '\O4' escape + sequences. + + +File: groff.info, Node: I/O, Next: Postprocessor Access, Prev: Suppressing Output, Up: GNU troff Reference + +5.33 I/O +======== + +'gtroff' has several requests for including files: + + -- Request: .so file + -- Request: .soquiet file + Replace the 'so' request's control line with the contents of the + file named by the argument, "sourcing" it. FILE is sought in the + directories specified by '-I' command-line option. If FILE does + not exist, a warning in category 'file' is produced and the request + has no further effect. *Note Warnings::, for information about the + enablement and suppression of warnings. + + 'so' can be useful for large documents; e.g., allowing each chapter + of a book to be kept in a separate file. However, files + interpolated with 'so' are not preprocessed; to overcome this + limitation, see the 'gsoelim(1)' man page. + + Since GNU 'troff' replaces the entire control line with the + contents of a file, it matters whether 'file' is terminated with a + newline or not. Assume that file 'xxx' contains only the word + 'foo' without a trailing newline. + + $ printf 'foo' > xxx + + The situation is + .so xxx + bar. + => The situation is foobar. + + 'soquiet' works the same way, except that no warning diagnostic is + issued if FILE does not exist. + + -- Request: .pso command + Read the standard output from the specified COMMAND and include it + in place of the 'pso' request. + + It is an error to use this request in safer mode, which is the + default. Invoke GNU 'troff' or a front end with the '-U' option to + enable unsafe mode. + + The comment regarding a final newline for the 'so' request is valid + for 'pso' also. + + -- Request: .mso file + -- Request: .msoquiet file + Identical to the 'so' and 'soquiet' requests, respectively, except + that 'gtroff' searches for the specified FILE in the same + directories as macro files for the '-m' command-line option. If + the file name to be included has the form 'NAME.tmac' and it isn't + found, these requests try to include 'tmac.NAME' and vice versa. + + -- Request: .trf file + -- Request: .cf file + Transparently output the contents of FILE. Each line is output as + if it were preceded by '\!'; however, the lines are _not_ subject + to copy mode interpretation. If the file does not end with a + newline, 'trf' adds one. Both requests cause a break. + + When used in a diversion, these requests embed a node (*note Gtroff + Internals::) in it that, when reread, causes the contents of FILE + to be transparently copied to the output. In AT&T 'troff', the + contents of FILE are immediately copied to the output regardless of + whether there is a current diversion; this behaviour is so + anomalous that it must be considered a bug. + + While 'cf' copies the contents of FILE completely unprocessed, + 'trf' disallows characters such as NUL that are not valid 'gtroff' + input characters (*note Identifiers::). + + For 'cf', within a diversion, "completely unprocessed" means that + each line of a file to be inserted is handled as if it were + preceded by '\!\\!'. + + To define a macro 'x' containing the contents of file 'f', use + + .ev 1 + .di x + .trf f + .di + .ev + + The calls to 'ev' prevent the partially collected output line from + becoming part of the diversion (*note Diversions::). + + -- Request: .nx [file] + Force 'gtroff' to continue processing of the file specified as an + argument. If no argument is given, immediately jump to the end of + file. + + -- Request: .rd [prompt [arg1 arg2 ...]] + Read from standard input, and include what is read as though it + were part of the input file. Text is read until a blank line is + encountered. + + If standard input is a TTY input device (keyboard), write PROMPT to + standard error, followed by a colon (or send BEL for a beep if no + argument is given). + + Arguments after PROMPT are available for the input. For example, + the line + + .rd data foo bar + + with the input 'This is \$2.' prints + + This is bar. + + Using the 'nx' and 'rd' requests, it is easy to set up form letters. +The form letter template is constructed like this, putting the following +lines into a file called 'repeat.let': + + .ce + \*(td + .sp 2 + .nf + .rd + .sp + .rd + .fi + Body of letter. + .bp + .nx repeat.let + +When this is run, a file containing the following lines should be +redirected in. Requests included in this file are executed as though +they were part of the form letter. The last block of input is the 'ex' +request, which tells GNU 'troff' to stop processing. If this were not +there, 'troff' would not know when to stop. + + Trent A. Fisher + 708 NW 19th Av., #202 + Portland, OR 97209 + + Dear Trent, + + Len Adollar + 4315 Sierra Vista + San Diego, CA 92103 + + Dear Mr. Adollar, + + .ex + + -- Request: .pi pipe + Pipe the output of 'gtroff' to the shell command(s) specified by + PIPE. This request must occur before 'gtroff' has a chance to + print anything. + + It is an error to use this request in safer mode, which is the + default. Invoke GNU 'troff' or a front end with the '-U' option to + enable unsafe mode. + + Multiple calls to 'pi' are allowed, acting as a chain. For + example, + + .pi foo + .pi bar + ... + + is the same as '.pi foo | bar'. + + The intermediate output format of GNU 'troff' is piped to the + specified commands. Consequently, calling 'groff' without the '-Z' + option normally causes a fatal error. + + -- Request: .sy cmds + -- Register: \n[systat] + Execute the shell command(s) specified by CMDS. The output is not + saved anywhere, so it is up to the user to do so. + + It is an error to use this request in safer mode; this is the + default. Give GNU 'troff' or a front end program the '-U' option + to enable unsafe mode. + + The following code fragment introduces the current time into a + document. + + .sy perl -e 'printf ".nr H %d\\n.nr M %d\\n.nr S %d\\n",\ + (localtime(time))[2,1,0]' > /tmp/x\n[$$] + .so /tmp/x\n[$$] + .sy rm /tmp/x\n[$$] + \nH:\nM:\nS + + This works by having the Perl script (run by 'sy') write 'nr' + requests that set the registers 'H', 'M', and 'S' to a temporary + file. The 'roff' document then reads the temporary file using the + 'so' request. + + The registers 'seconds', 'minutes', and 'hours', initialized at + startup of GNU 'troff', should satisfy most requirements. Use the + 'af' request to format their values for output. + + .af hours 00 + .af minutes 00 + .af seconds 00 + \n[hours]:\n[minutes]:\n[seconds] + => 02:17:54 + + The writable register 'systat' contains the return value of the + 'system()' function executed by the last 'sy' request. + + -- Request: .open stream file + -- Request: .opena stream file + Open the specified FILE for writing and associates the specified + STREAM with it. + + The 'opena' request is like 'open', but if the file exists, append + to it instead of truncating it. + + It is an error to use these requests in safer mode; this is the + default. Give GNU 'troff' or a front end program the '-U' option + to enable unsafe mode. + + -- Request: .write stream data + -- Request: .writec stream data + Write to the file associated with the specified STREAM. The stream + must previously have been the subject of an open request. The + remainder of the line is interpreted as the 'ds' request reads its + second argument: an initial neutral double quote in CONTENTS is + stripped to allow embedding of leading spaces, and it is read in + copy mode. + + The 'writec' request is like 'write', but only 'write' appends a + newline to the data. + + -- Request: .writem stream xx + Write the contents of the macro or string XX to the file associated + with the specified STREAM. + + XX is read in copy mode, i.e., already formatted elements are + ignored. Consequently, diversions must be unformatted with the + 'asciify' request before calling 'writem'. Usually, this means a + loss of information. + + -- Request: .close stream + Close the specified STREAM; the stream is no longer an acceptable + argument to the 'write' request. + + Here a simple macro to write an index entry. + + .open idx test.idx + . + .de IX + . write idx \\n[%] \\$* + .. + . + .IX test entry + . + .close idx + + -- Escape sequence: \Ve + -- Escape sequence: \V(ev + -- Escape sequence: \V[env] + Interpolate the contents of the specified environment variable ENV + (one-character name E, two-character name EV) as returned by the + function 'getenv(3)'. '\V' is interpreted even in copy mode (*note + Copy Mode::). + + +File: groff.info, Node: Postprocessor Access, Next: Miscellaneous, Prev: I/O, Up: GNU troff Reference + +5.34 Postprocessor Access +========================= + +Two escape sequences and two requests enable documents to pass +information directly to a postprocessor. These are useful for +exercising device-specific capabilities that the 'groff' language does +not abstract or generalize; examples include the embedding of hyperlinks +and image files. Device-specific functions are documented in each +output driver's man page, such as 'gropdf(1)', 'grops(1)', or +'grotty(1)'. + + -- Request: .device xxx ... + -- Escape sequence: \X'xxx ...' + Embed all XXX arguments into GNU 'troff' output as parameters to a + device control command 'x X'. The meaning and interpretation of + such parameters is determined by the output driver or other + postprocessor. + + The 'device' request processes its arguments in copy mode (*note + Copy Mode::). An initial neutral double quote in CONTENTS is + stripped to allow embedding of leading spaces. By contrast, within + '\X' arguments, the escape sequences '\&', '\)', '\%', and '\:' are + ignored; '\' and '\~' are converted to single space characters; + and '\\' has its escape character stripped. So that the basic + Latin subset of the Unicode character set(1) (*note Postprocessor + Access-Footnote-1::) can be reliably encoded in device control + commands, seven special character escape sequences ('\-', '\[aq]', + '\[dq]', '\[ga]', '\[ha]', '\[rs]', and '\[ti]',) are mapped to + basic Latin characters; see the 'groff_char(7)' man page. For this + transformation, character translations and special character + definitions are ignored.(2) (*note Postprocessor + Access-Footnote-2::) The use of any other escape sequence in '\X' + parameters is normally an error. + + If the 'use_charnames_in_special' directive appears in the output + device's 'DESC' file, the use of special character escape sequences + is _not_ an error; they are simply output verbatim (with the + exception of the seven mapped to Unicode basic Latin characters, + discussed above). 'use_charnames_in_special' is currently employed + only by 'grohtml'. + + -- Request: .devicem name + -- Escape sequence: \Yn + -- Escape sequence: \Y(nm + -- Escape sequence: \Y[name] + This is approximately equivalent to '\X'\*[NAME]'' (one-character + name N, two-character name NM). However, the contents of the + string or macro NAME are not interpreted; also it is permitted for + NAME to have been defined as a macro and thus contain newlines (it + is not permitted for the argument to '\X' to contain newlines). + The inclusion of newlines requires an extension to the AT&T 'troff' + output format, and confuses drivers that do not know about this + extension (*note Device Control Commands::). + + -- Request: .tag name + -- Request: .taga name + Reserved for internal use. + + +File: groff.info, Node: Postprocessor Access-Footnotes, Up: Postprocessor Access + + (1) that is, ISO 646:1991-IRV or, popularly, "US-ASCII" + + (2) They are bypassed because these parameters are not rendered as +glyphs in the output; instead, they remain abstract characters--in a PDF +bookmark or a URL, for example. + + +File: groff.info, Node: Miscellaneous, Next: Gtroff Internals, Prev: Postprocessor Access, Up: GNU troff Reference + +5.35 Miscellaneous +================== + +We document here GNU 'troff' features that fit poorly elsewhere. + + -- Request: .nm [start [increment [space [indentation]]]] + -- Register: \n[ln] + -- Register: \n[.nm] + Begin (or, with no arguments, cease) numbering output lines. START + assigns the number of the _next_ output line. Only line numbers + divisible by INCREMENT are marked (default: '1'). SPACE configures + the horizontal spacing between the number and the text (default: + '1'). Any given INDENTATION is applied to the numbers (default: + '0'). The third and fourth arguments are reckoned in numeral + widths ('\0'). START must be non-negative and INCREMENT positive. + + The formatter aligns the number to the right in a width of three + numeral spaces plus INDENTATION, then catenates SPACE and the + output line. The line length is _not_ reduced. Depending on the + value of the page offset,(1) (*note Miscellaneous-Footnote-1::) + numbers wider than the allocated space protrude into the left + margin, or shift the output line to the right. + + Line numbering parameters corresponding to missing arguments are + not altered. After numbering is disabled, '.nm +0' resumes it + using the previously active parameters. + + The parameters of 'nm' are associated with the environment (*note + Environments::). + + While numbering is enabled, the output line number register 'ln' is + updated as each line is output, even if no line number is formatted + with it because it is being skipped (it is not a multiple of + INCREMENT) or because numbering is suppressed (see the 'nn' request + below). + + The '.nm' register tracks the enablement status of numbering. + Temporary suspension of numbering with the 'nn' request does _not_ + alter its value. + + .po 5n + .ll 44n + Programming, + when stripped of all its circumstantial irrelevancies, + .nm 999 1 1 -4 + boils down to no more and no less than + .nm +0 3 + very effective thinking so as to avoid unmastered + .nn 2 + complexity, + to very vigorous separation of your many + different concerns. + .br + \(em Edsger Dijkstra + .sp + .nm 1 1 1 + This guy's arrogance takes your breath away. + .br + \(em John Backus + => Programming, when stripped of all its cir- + => 999 cumstantial irrelevancies, boils down to no + => more and no less than very effective think- + => ing so as to avoid unmastered complexity, to + => very vigorous separation of your many dif- + => ferent concerns. + => 1002 -- Edsger Dijkstra + => + => 1 This guy's arrogance takes your breath away. + => 2 -- John Backus + + -- Request: .nn [skip] + -- Register: \n[.nn] + Suppress numbering of the next SKIP output lines that would + otherwise be numbered. The default is 1. 'nn' can be invoked when + line numbering is not active; suppression of numbering will take + effect for SKIP lines once 'nm' enables it. + + The '.nn' register stores the count of output lines still to have + their numbering suppressed. + + This count is associated with the environment (*note + Environments::). + + To test whether the current output line will be numbered, you must +check both the '.nm' and '.nn' registers. + + .de is-numbered + . nop This line + . ie (\\n[.nm] & (1-\\n[.nn])) IS + . el ISN'T + . nop numbered. + . br + .. + Test line numbering. + .is-numbered + .nm 1 + .nn 1 + .is-numbered + .is-numbered + .nm + .is-numbered + => Test line numbering. This line ISN'T numbered. + => This line ISN'T numbered. + => 1 This line IS numbered. + => This line ISN'T numbered. + + -- Request: .mc [margin-character [distance] + Begin (or, with no arguments, cease) writing a "margin-character" + to the right of each output line. The DISTANCE argument separates + MARGIN-CHARACTER from the right margin. If absent, the most recent + value is used; the default is 10 points. If an output line exceeds + the line length, the margin character is appended to it. No margin + character is written on lines produced by the 'tl' request. + + The margin character is a property of the output line; the margin + character last configured when the line is output controls. If the + margin character is disabled before an output line breaks, none is + output (but see below). + + The margin character is associated with the environment (*note + Environments::). + + .ll 5i + .nf + .mc \[br] + This paragraph is marked with a margin character. + .sp + As seen above, vertical space isn't thus marked. + \& + An output line that is present, but empty, is. + => This paragraph is marked with a margin character. | + => + => As seen above, vertical space isn't thus marked. | + => | + => An output line that is present, but empty, is. | + + For compatibility with AT&T 'troff', a call to 'mc' to set the margin +character can't be undone immediately; at least one line gets a margin +character. + + .ll 10n + .nf + .mc | + .mc * + .mc + foo + bar + => foo * + => bar + + The margin character mechanism is commonly used to annotate changes +in documents. The 'groff' distribution ships a program, 'gdiffmk', to +assist with this task.(2) (*note Miscellaneous-Footnote-2::) + + -- Request: .psbb file + -- Register: \n[llx] + -- Register: \n[lly] + -- Register: \n[urx] + -- Register: \n[ury] + Retrieve the bounding box of the PostScript image found in FILE, + which must conform to Adobe's "Document Structuring Conventions" + (DSC), locate a '%%BoundingBox' comment, and store the (upper-, + lower-, -left, -right) values into the registers 'llx', 'lly', + 'urx', and 'ury'. If an error occurs (for example, if no + '%%BoundingBox' comment is present), the formatter sets these + registers to 0. + + The search path for FILE can be controlled with the '-I' + command-line option. + + +File: groff.info, Node: Miscellaneous-Footnotes, Up: Miscellaneous + + (1) Recall *note Line Layout::. + + (2) Historically, tools named 'nrchbar' and 'changebar' were +developed for marking changes with margin characters and could be found +in archives of the 'comp.sources.unix' USENET group. Some proprietary +Unices also offer(ed) a 'diffmk' program. + + +File: groff.info, Node: Gtroff Internals, Next: Debugging, Prev: Miscellaneous, Up: GNU troff Reference + +5.36 'gtroff' Internals +======================= + +'gtroff' processes input in three steps. One or more input characters +are converted to an "input token".(1) (*note Gtroff +Internals-Footnote-1::) Then, one or more input tokens are converted to +an "output node". Finally, output nodes are converted to the +intermediate output language understood by all output devices. + + Actually, before step one happens, 'gtroff' converts certain escape +sequences into reserved input characters (not accessible by the user); +such reserved characters are used for other internal processing also - +this is the very reason why not all characters are valid input. *Note +Identifiers::, for more on this topic. + + For example, the input string 'fi\[:u]' is converted into a character +token 'f', a character token 'i', and a special token ':u' (representing +u umlaut). Later on, the character tokens 'f' and 'i' are merged to a +single output node representing the ligature glyph 'fi' (provided the +current font has a glyph for this ligature); the same happens with ':u'. +All output glyph nodes are 'processed', which means that they are +invariably associated with a given font, font size, advance width, etc. +During the formatting process, 'gtroff' itself adds various nodes to +control the data flow. + + Macros, diversions, and strings collect elements in two chained +lists: a list of input tokens that have been passed unprocessed, and a +list of output nodes. Consider the following diversion. + + .di xxx + a + \!b + c + .br + .di + +It contains these elements. + +node list token list element number + +line start node -- 1 +glyph node 'a' -- 2 +word space node -- 3 +-- 'b' 4 +-- '\n' 5 +glyph node 'c' -- 6 +vertical size node -- 7 +vertical size node -- 8 +-- '\n' 9 + +Elements 1, 7, and 8 are inserted by 'gtroff'; the latter two (which are +always present) specify the vertical extent of the last line, possibly +modified by '\x'. The 'br' request finishes the pending output line, +inserting a newline input token, which is subsequently converted to a +space when the diversion is reread. Note that the word space node has a +fixed width that isn't adjustable anymore. To convert horizontal space +nodes back to input tokens, use the 'unformat' request. + + Macros only contain elements in the token list (and the node list is +empty); diversions and strings can contain elements in both lists. + + The 'chop' request simply reduces the number of elements in a macro, +string, or diversion by one. Exceptions are "compatibility save" and +"compatibility ignore" input tokens, which are ignored. The 'substring' +request also ignores those input tokens. + + Some requests like 'tr' or 'cflags' work on glyph identifiers only; +this means that the associated glyph can be changed without destroying +this association. This can be very helpful for substituting glyphs. In +the following example, we assume that glyph 'foo' isn't available by +default, so we provide a substitution using the 'fchar' request and map +it to input character 'x'. + + .fchar \[foo] foo + .tr x \[foo] + +Now let us assume that we install an additional special font 'bar' that +has glyph 'foo'. + + .special bar + .rchar \[foo] + +Since glyphs defined with 'fchar' are searched before glyphs in special +fonts, we must call 'rchar' to remove the definition of the fallback +glyph. Anyway, the translation is still active; 'x' now maps to the +real glyph 'foo'. + + Macro and request arguments preserve compatibility mode enablement. + + .cp 1 \" switch to compatibility mode + .de xx + \\$1 + .. + .cp 0 \" switch compatibility mode off + .xx caf\['e] + => café + +Since compatibility mode is enabled while 'de' is invoked, the macro +'xx' enables compatibility mode when it is called. Argument '$1' can +still be handled properly because it inherits the compatibility mode +enablement status that was active at the point where 'xx' was called. + + After interpolation of the parameters, the compatibility save and +restore tokens are removed. + + +File: groff.info, Node: Gtroff Internals-Footnotes, Up: Gtroff Internals + + (1) Except the escape sequences '\f', '\F', '\H', '\m', '\M', '\R', +'\s', and '\S', which are processed immediately if not in copy mode. + + +File: groff.info, Node: Debugging, Next: Implementation Differences, Prev: Gtroff Internals, Up: GNU troff Reference + +5.37 Debugging +============== + + Standard troff voodoo, just put a power of two backslashes in + front of it until it works and if you still have problems add a \c. + -- Ron Natalie + + GNU 'troff' is not the easiest language to debug, in part thanks to +its design features of recursive interpolation and the use of +multi-stage pipeline processing in the surrounding system. Nevertheless +there exist several features useful for troubleshooting. + + Preprocessors use the 'lf' request to preserve the identity of the +line numbers and names of input files. GNU 'troff' emits a variety of +error diagnostics and supports several categories of warning; the output +of these can be selectively suppressed. A trace of the formatter's +input processing stack can be emitted when errors or warnings occur by +means of GNU 'troff''s '-b' option, or produced on demand with the +'backtrace' request. The 'tm' and related requests can be used to emit +customized diagnostic messages or for instrumentation while +troubleshooting. The 'ex' and 'ab' requests cause early termination +with successful and error exit codes respectively, to halt further +processing when continuing would be fruitless. Examine the state of the +formatter with requests that write lists of defined names (macros, +strings, and diversions), environments, registers, and page location +traps to the standard error stream. + + -- Request: .lf line [file] + Set the input line number (and, optionally, the file name) GNU + 'troff' shall use for error and warning messages. LINE is the + input line number of the _next_ line. Without an argument, the + request is ignored. + + 'lf''s primary purpose is to aid the debugging of documents that + undergo preprocessing. Programs like 'tbl' that transform input in + their own languages into 'roff' requests use it so that any + diagnostic messages emitted by 'troff' correspond to the source + document. + + -- Request: .tm message + -- Request: .tm1 message + -- Request: .tmc message + Send MESSAGE, which consumes the remainder of the input line and + cannot contain special characters, to the standard error stream, + followed by a newline. Leading spaces in MESSAGE are ignored. + + 'tm1' is similar, but recognizes and strips a leading neutral + double quote from MESSAGE to allow the embedding of leading spaces. + + 'tmc' works as 'tm1', but does not append a newline. + + -- Request: .ab [message] + Write any MESSAGE to the standard error stream (like 'tm') and then + abort GNU 'troff'; that is, stop processing and terminate with a + failure status. + + -- Request: .ex + Exit GNU 'troff'; that is, stop processing and terminate with a + successful status. To stop processing only the current file, use + the 'nx' request; see *note I/O::. + + When doing something involved, it is useful to leave the debugging +statements in the code and have them turned on by a command-line flag. + + .if \n[DB] .tm debugging output + +To activate such statements, use the '-r' option to set the register. + + groff -rDB=1 file + + If it is known in advance that there are many errors and no useful +output, GNU 'troff' can be forced to suppress formatted output with the +'-z' option. + + -- Request: .pev + Report the state of the current environment followed by that of all + other environments to the standard error stream. + + -- Request: .pm + Report, to the standard error stream, the names of all defined + macros, strings, and diversions with their sizes in bytes. + + -- Request: .pnr + Report the names and contents of all currently defined registers to + the standard error stream. + + -- Request: .ptr + Report the names and positions of all page location traps to the + standard error stream. Empty slots in the list, where a trap has + been planted but subsequently (re)moved, are printed as well. + + -- Request: .fl + Instruct 'gtroff' to flush its output immediately. The intent is + for interactive use, but this behaviour is currently not + implemented in 'gtroff'. Contrary to Unix 'troff', TTY output is + sent to a device driver also ('grotty'), making it non-trivial to + communicate interactively. + + This request causes a line break. + + -- Request: .backtrace + Write the state of the input stack to the standard error stream. + + Consider the following in a file 'test'. + + .de xxx + . backtrace + .. + .de yyy + . xxx + .. + . + .yyy + error-> troff: backtrace: 'test':2: macro 'xxx' + error-> troff: backtrace: 'test':5: macro 'yyy' + error-> troff: backtrace: file 'test':8 + + The '-b' option of GNU 'troff' causes a backtrace to be generated + on each error or warning. Some warnings have to be enabled; *Note + Warnings::. + + -- Register: \n[slimit] + If greater than 0, sets the maximum quantity of objects on GNU + 'troff''s internal input stack. If less than or equal to 0, there + is no limit: recursion can continue until program memory is + exhausted. The default is 1,000. + + -- Request: .warnscale su + Set the scaling unit used in certain warnings to SU, which can take + the values 'u', 'i', 'c', 'p', and 'P'. The default is 'i'. + + -- Request: .spreadwarn [limit] + Emit a 'break' warning if the additional space inserted for each + space between words in an output line adjusted to both margins with + '.ad b' is larger than or equal to LIMIT. A negative value is + treated as zero; an absent argument toggles the warning on and off + without changing LIMIT. The default scaling unit is 'm'. At + startup, 'spreadwarn' is inactive and LIMIT is 3m. + + For example, + + .spreadwarn 0.2m + + causes a warning if 'break' warnings are not suppressed and + 'gtroff' must add 0.2m or more for each inter-word space in a line. + *Note Warnings::. + + GNU 'troff' has command-line options for reporting warnings ('-w') +and backtraces ('-b') when a warning or an error occurs. + + -- Request: .warn [n] + -- Register: \n[.warn] + Select the categories, or "types", of reported warnings. N is the + sum of the numeric codes associated with each warning category that + is to be enabled; all other categories are disabled. The + categories and their associated codes are listed in *note + Warnings::. For example, '.warn 0' disables all warnings, and + '.warn 1' disables all warnings except those about missing glyphs. + If no argument is given, all warning categories are enabled. + + The read-only register '.warn' contains the sum of the numeric + codes of enabled warning categories. + +* Menu: + +* Warnings:: + + +File: groff.info, Node: Warnings, Prev: Debugging, Up: Debugging + +5.37.1 Warnings +--------------- + +Warning diagnostics emitted by GNU 'troff' are divided into named, +numbered categories. The name associated with each warning category is +used by the '-w' and '-W' options. Each category is also assigned a +power of two; the sum of enabled category values is used by the 'warn' +request and the '.warn' register. + + Warnings of each category are produced under the following +circumstances. + +'char' +'1' + No mounted font defines a glyph for the requested character. This + category is enabled by default. + +'number' +'2' + An invalid numeric expression was encountered. This category is + enabled by default. *Note Numeric Expressions::. + +'break' +'4' + A filled output line could not be broken such that its length was + less than the output line length '\n[.l]'. This category is + enabled by default. + +'delim' +'8' + The closing delimiter in an escape sequence was missing or + mismatched. + +'el' +'16' + The 'el' request was encountered with no prior corresponding 'ie' + request. *Note if-else::. + +'scale' +'32' + A scaling unit inappropriate to its context was used in a numeric + expression. + +'range' +'64' + A numeric expression was out of range for its context. + +'syntax' +'128' + A self-contradictory hyphenation mode was requested; an empty or + incomplete numeric expression was encountered; an operand to a + numeric operator was missing; an attempt was made to define a + recursive, empty, or nonsensical character class; or a 'groff' + extension conditional expression operator was used while in + compatibility mode. + +'di' +'256' + A 'di', 'da', 'box', or 'boxa' request was invoked without an + argument when there was no current diversion. + +'mac' +'512' + An undefined string, macro, or diversion was used. When such an + object is dereferenced, an empty one of that name is automatically + created. So, unless it is later deleted, at most one warning is + given for each. + + This warning is also emitted upon an attempt to move an unplanted + trap macro (*note Page Location Traps::). In such cases, the + unplanted macro is _not_ dereferenced, so it is not created if it + does not exist. + +'reg' +'1024' + An undefined register was used. When an undefined register is + dereferenced, it is automatically defined with a value of 0. So, + unless it is later deleted, at most one warning is given for each. + +'tab' +'2048' + A tab character was encountered where a number was expected, or + appeared in an unquoted macro argument. + +'right-brace' +'4096' + A right brace escape sequence '\}' was encountered where a number + was expected. + +'missing' +'8192' + A request was invoked with a mandatory argument absent. + +'input' +'16384' + An invalid character occurred on the input stream. + +'escape' +'32768' + An unsupported escape sequence was encountered. + +'space' +'65536' + A space was missing between a request or macro and its argument. + This warning is produced when an undefined name longer than two + characters is encountered and the first two characters of the name + constitute a defined name. No request is invoked, no macro called, + and an empty macro is not defined. This category is enabled by + default. It never occurs in compatibility mode. + +'font' +'131072' + A non-existent font was selected, or the selection was ignored + because a font selection escape sequence was used after the output + line continuation escape sequence on an input line. This category + is enabled by default. + +'ig' +'262144' + An invalid escape sequence occurred in input ignored using the 'ig' + request. This warning category diagnoses a condition that is an + error when it occurs in non-ignored input. + +'color' +'524288' + An undefined color was selected, an attempt was made to define a + color using an unrecognized color space, an invalid component in a + color definition was encountered, or an attempt was made to + redefine a default color. + +'file' +'1048576' + An attempt was made to load a file that does not exist. This + category is enabled by default. + + Two warning names group other warning categories for convenience. + +'all' + All warning categories except 'di', 'mac' and 'reg'. This + shorthand is intended to produce all warnings that are useful with + macro packages written for AT&T 'troff' and its descendants, which + have less fastidious diagnostics than GNU 'troff'. + +'w' + All warning categories. Authors of documents and macro packages + targeting 'groff' are encouraged to use this setting. + + +File: groff.info, Node: Implementation Differences, Next: Safer Mode, Prev: Debugging, Up: GNU troff Reference + +5.38 Implementation Differences +=============================== + +GNU 'troff' has a number of features that cause incompatibilities with +documents written for other versions of 'troff'. Some GNU extensions to +'troff' have become supported by other implementations. + +* Menu: + +* Safer Mode:: +* Compatibility Mode:: +* Other Differences:: + + +File: groff.info, Node: Safer Mode, Next: Compatibility Mode, Prev: Implementation Differences, Up: Implementation Differences + +5.38.1 Safer Mode +----------------- + +The formatter operates in "safer" mode by default; to mitigate risks +from untrusted input documents, the 'pi' and 'sy' requests are disabled. +GNU 'troff''s '-U' option enables "unsafe mode", restoring their +function and enabling additional 'groff' extension requests, 'open', +'opena', and 'pso'. *Note I/O::. + + +File: groff.info, Node: Compatibility Mode, Next: Safer Mode, Prev: Other Differences, Up: Implementation Differences + +5.38.2 Compatibility Mode +------------------------- + +Long identifier names may be GNU 'troff''s most obvious innovation. +AT&T 'troff' interprets '.dsabcd' as defining a string 'ab' with +contents 'cd'. Normally, GNU 'troff' interprets this as a call of a +macro named 'dsabcd'. AT&T 'troff' also interprets '\*[' and '\n[' as +an interpolation of a string or register, respectively, named '['. In +GNU 'troff', however, the '[' is normally interpreted as delimiting a +long name. In compatibility mode, GNU 'troff' interprets names in the +traditional way; they thus can be two characters long at most. + + -- Request: .cp [n] + -- Register: \n[.C] + If N is missing or non-zero, turn on compatibility mode; otherwise, + turn it off. + + The read-only register '.C' is 1 if compatibility mode is on, + 0 otherwise. + + Compatibility mode can be also turned on with the '-C' command-line + option. + + -- Request: .do name + -- Register: \n[.cp] + The 'do' request interprets the string, request, diversion, or + macro NAME (along with any further arguments) with compatibility + mode disabled. Compatibility mode is restored (only if it was + active) when the _expansion_ of NAME is interpreted; that is, the + restored compatibility state applies to the contents of the macro, + string, or diversion NAME as well as data read from files or pipes + if NAME is any of the 'so', 'soquiet', 'mso', 'msoquiet', or 'pso' + requests. + + The following example illustrates several aspects of 'do' behavior. + + .de mac1 + FOO + .. + .de1 mac2 + groff + .mac1 + .. + .de mac3 + compatibility + .mac1 + .. + .de ma + \\$1 + .. + .cp 1 + .do mac1 + .do mac2 \" mac2, defined with .de1, calls "mac1" + .do mac3 \" mac3 calls "ma" with argument "c1" + .do mac3 \[ti] \" groff syntax accepted in .do arguments + => FOO groff FOO compatibility c1 ~ + + The read-only register '.cp', meaningful only when dereferenced + from a 'do' request, is 1 if compatibility mode was on when the + 'do' request was encountered, and 0 if it was not. This register + is specialized and may require a statement of rationale. + + When writing macro packages or documents that use GNU 'troff' + features and which may be mixed with other packages or documents + that do not--common scenarios include serial processing of man + pages or use of the 'so' or 'mso' requests--you may desire correct + operation regardless of compatibility mode enablement in the + surrounding context. It may occur to you to save the existing + value of '\n(.C' into a register, say, '_C', at the beginning of + your file, turn compatibility mode off with '.cp 0', then restore + it from that register at the end with '.cp \n(_C'. At the same + time, a modular design of a document or macro package may lead you + to multiple layers of inclusion. You cannot use the same register + name everywhere lest you "clobber" the value from a preceding or + enclosing context. The two-character register name space of AT&T + 'troff' is confining and mnemonically challenging; you may wish to + use the more capacious name space of GNU 'troff'. However, + attempting '.nr _my_saved_C \n(.C' will not work in compatibility + mode; the register name is too long. "This is exactly what 'do' is + for," you think, '.do nr _my_saved_C \n(.C'. The foregoing will + always save zero to your register, because 'do' turns compatibility + mode _off_ while it interprets its argument list. + + To robustly save compatibility mode before switching it off, use + + .do nr _my_saved_C \n[.cp] + .cp 0 + + at the beginning of your file, followed by + + .cp \n[_my_saved_C] + .do rr _my_saved_C + + at the end. As in the C language, we all have to share one big + name space, so choose a register name that is unlikely to collide + with other uses. + + Normally, GNU 'troff' preserves the interpolation depth in delimited +arguments, but not in compatibility mode. + + .ds xx ' + \w'abc\*(xxdef' + => 168 (normal mode on a terminal device) + => 72def' (compatibility mode on a terminal device) + + Furthermore, the escape sequences '\f', '\H', '\m', '\M', '\R', '\s', +and '\S' are transparent for the purpose of recognizing a control +character at the beginning of a line only in compatibility mode. For +example, this code produces bold output in both cases, but the text +differs. + + .de xx + Hello! + .. + \fB.xx\fP + => .xx (normal mode) + => Hello! (compatibility mode) + + Normally, the syntax form '\s'N accepts only a single character (a +digit) for N, consistently with other forms that originated in AT&T +'troff', like '\*', '\$', '\f', '\g', '\k', '\n', and '\z'. In +compatibility mode only, a non-zero N must be in the range 4-39. Legacy +documents relying upon this quirk of parsing(1) (*note Compatibility +Mode-Footnote-1::) should be migrated to another '\s' form. + + +File: groff.info, Node: Compatibility Mode-Footnotes, Up: Compatibility Mode + + (1) The Graphic Systems C/A/T phototypesetter (the original device +target for AT&T 'troff') supported only a few discrete type sizes in the +range 6-36 points, so Ossanna contrived a special case in the parser to +do what the user must have meant. Kernighan warned of this in the 1992 +revision of CSTR #54 (§2.3), and more recently, McIlroy referred to it +as a "living fossil". + + +File: groff.info, Node: Other Differences, Prev: Compatibility Mode, Up: Implementation Differences + +5.38.3 Other Differences +------------------------ + +'groff' request names unrecognized by other 'troff' implementations will +likely be ignored by them; escape sequences that are 'groff' extensions +are liable to be interpreted as if the escape character were not +present. For example, the adjustable, non-breaking escape sequence '\~' +is also supported by Heirloom Doctools 'troff' 050915 (September 2005), +'mandoc' 1.9.5 (2009-09-21), 'neatroff' (commit 1c6ab0f6e, 2016-09-13), +and Plan 9 from User Space 'troff' (commit 93f8143600, 2022-08-12), but +not by Solaris or Documenter's Workbench 'troff's. *Note Manipulating +Filling and Adjustment::. + + GNU 'troff' does not allow the use of the escape sequences '\|', +'\^', '\&', '\{', '\}', '\', '\'', '\`', '\-', '\_', '\!', '\%', and +'\c' in identifiers; AT&T 'troff' does. The '\A' escape sequence (*note +Identifiers::) may be helpful in avoiding use of these escape sequences +in names. + + When adjusting to both margins, AT&T 'troff' at first adjusts spaces +starting from the right; GNU 'troff' begins from the left. Both +implementations adjust spaces from opposite ends on alternating output +lines in this adjustment mode to prevent "rivers" in the text. + + GNU 'troff' does not always hyphenate words as AT&T 'troff' does. +The AT&T implementation uses a set of hard-coded rules specific to +English, while GNU 'troff' uses language-specific hyphenation pattern +files derived from TeX. Furthermore, in old versions of 'troff' there +was a limited amount of space to store hyphenation exceptions (arguments +to the 'hw' request); GNU 'troff' has no such restriction. + + GNU 'troff' predefines a string '.T' containing the argument given to +the '-T' command-line option, namely the current output device (for +example, 'pdf' or 'utf8'). The existence of this string is a common +feature of post-CSTR #54 'troff's(1) (*note Other +Differences-Footnote-1::) but valid values are specific to each +implementation. + + AT&T 'troff' ignored attempts to remove read-only registers; GNU +'troff' honors such requests. *Note Built-in Registers::. + + The (read-only) register '.T' interpolates 1 if GNU 'troff' is called +with the '-T' command-line option, and 0 otherwise. This behavior +differs from AT&T 'troff', which interpolated 1 only if 'nroff' was the +formatter and was called with '-T'. + + AT&T 'troff' and other implementations handle the 'lf' request +differently. For them, its LINE argument changes the line number of the +_current_ line. + + AT&T 'troff' had only environments named '0', '1', and '2'. In GNU +'troff', any number of environments may exist, using any valid +identifiers for their names (*note Identifiers::.) + + Fractional type sizes cause one noteworthy incompatibility. In AT&T +'troff' the 'ps' request ignores scaling units and thus '.ps 10u' sets +the type size to 10 points, whereas in GNU 'troff' it sets the type size +to 10 _scaled_ points. *Note Using Fractional Type Sizes::. + + The 'ab' request differs from AT&T 'troff': GNU 'troff' writes no +message to the standard error stream if no arguments are given, and it +exits with a failure status instead of a successful one. + + The 'bp' request differs from AT&T 'troff': GNU 'troff' does not +accept a scaling unit on the argument, a page number; the former +(somewhat uselessly) does. + + The 'pm' request differs from AT&T 'troff': GNU 'troff' reports the +sizes of macros, strings, and diversions in bytes and ignores an +argument to report only the sum of the sizes. + + Unlike AT&T 'troff', GNU 'troff' does not ignore the 'ss' request if +the output is a terminal device; instead, the values of minimal +inter-word and additional inter-sentence space are each rounded down to +the nearest multiple of 12. + + In GNU 'troff' there is a fundamental difference between +(unformatted) characters and (formatted) glyphs. Everything that +affects how a glyph is output is stored with the glyph node; once a +glyph node has been constructed, it is unaffected by any subsequent +requests that are executed, including 'bd', 'cs', 'tkf', 'tr', or 'fp' +requests. Normally, glyphs are constructed from characters immediately +before the glyph is added to an output line. Macros, diversions, and +strings are all, in fact, the same type of object; they contain a +sequence of intermixed character and glyph nodes. Special characters +transform from one to the other: before being added to the output, they +behave as characters; afterward, they are glyphs. A glyph node does not +behave like a character node when it is processed by a macro: it does +not inherit any of the special properties that the character from which +it was constructed might have had. For example, the input + + .di x + \\\\ + .br + .di + .x + +produces '\\' in GNU 'troff'. Each pair of backslashes becomes one +backslash _glyph_; the resulting backslashes are thus not interpreted as +escape _characters_ when they are reread as the diversion is output. +AT&T 'troff' _would_ interpret them as escape characters when rereading +them and end up printing one '\'. + + One correct way to obtain a printable backslash in most documents is +to use the '\e' escape sequence; this always prints a single instance of +the current escape character,(2) (*note Other Differences-Footnote-2::) +regardless of whether or not it is used in a diversion; it also works in +both GNU 'troff' and AT&T 'troff'. + + The other correct way, appropriate in contexts independent of the +backslash's common use as a 'troff' escape character--perhaps in +discussion of character sets or other programming languages--is the +character escape '\(rs' or '\[rs]', for "reverse solidus", from its name +in the ECMA-6 (ISO/IEC 646) standard.(3) (*note Other +Differences-Footnote-3::) + + To store an escape sequence in a diversion that is interpreted when +the diversion is reread, either use the traditional '\!' transparent +output facility, or, if this is unsuitable, the new '\?' escape +sequence. *Note Diversions:: and *note Gtroff Internals::. + + In the somewhat pathological case where a diversion exists containing +a partially collected line and a partially collected line at the +top-level diversion has never existed, AT&T 'troff' will output the +partially collected line at the end of input; GNU 'troff' will not. + + +File: groff.info, Node: Other Differences-Footnotes, Up: Other Differences + + (1) DWB 3.3, Solaris, Heirloom Doctools, and Plan 9 'troff' all +support it. + + (2) Naturally, if you've changed the escape character, you need to +prefix the 'e' with whatever it is--and you'll likely get something +other than a backslash in the output. + + (3) The 'rs' special character identifier was not defined in AT&T +'troff''s font description files, but is in those of its lineal +descendant, Heirloom Doctools 'troff', as of the latter's 060716 release +(July 2006). + + +File: groff.info, Node: File Formats, Next: Copying This Manual, Prev: GNU troff Reference, Up: Top + +6 File Formats +************** + +All files read and written by 'gtroff' are text files. The following +two sections describe their format. + +* Menu: + +* gtroff Output:: +* Device and Font Description Files:: + + +File: groff.info, Node: gtroff Output, Next: Device and Font Description Files, Prev: File Formats, Up: File Formats + +6.1 'gtroff' Output +=================== + +This section describes the 'groff' intermediate output format produced +by GNU 'troff'. + + As 'groff' is a wrapper program around GNU 'troff' and automatically +calls an output driver (or "postprocessor"), this output does not show +up normally. This is why it is called _intermediate_. 'groff' provides +the option '-Z' to inhibit postprocessing such that the produced +intermediate output is sent to standard output just as it is when +calling GNU 'troff' directly. + + Here, the term "troff output" describes what is output by GNU +'troff', while "intermediate output" refers to the language that is +accepted by the parser that prepares this output for the output drivers. +This parser handles whitespace more flexibly than AT&T's implementation +and implements obsolete elements for compatibility; otherwise, both +formats are the same.(1) (*note gtroff Output-Footnote-1::) + + The main purpose of the intermediate output concept is to facilitate +the development of postprocessors by providing a common programming +interface for all devices. It has a language of its own that is +completely different from the 'gtroff' language. While the 'gtroff' +language is a high-level programming language for text processing, the +intermediate output language is a kind of low-level assembler language +by specifying all positions on the page for writing and drawing. + + The intermediate output produced by 'gtroff' is fairly readable, +while output from AT&T 'troff' is rather hard to understand because of +strange habits that are still supported, but not used any longer by +'gtroff'. + +* Menu: + +* Language Concepts:: +* Command Reference:: +* Intermediate Output Examples:: +* Output Language Compatibility:: + + +File: groff.info, Node: gtroff Output-Footnotes, Up: gtroff Output + + (1) The parser and postprocessor for intermediate output can be found +in the file +'GROFF-SOURCE-DIR/src/libs/libdriver/input.cpp'. + + +File: groff.info, Node: Language Concepts, Next: Command Reference, Prev: gtroff Output, Up: gtroff Output + +6.1.1 Language Concepts +----------------------- + +The fundamental operation of the GNU 'troff' formatter is the +translation of the 'groff' input language into a device-independent form +primarily concerned with what has to be written or drawn at specific +positions on the output device. This language is simple and imperative. +In the following discussion, the term "command" always refers to this +intermediate output language, and never to the 'groff' language intended +for direct use by document authors. Intermediate output commands +comprise several categories: glyph output; font, color, and text size +selection; motion of the printing position; page advancement; drawing of +geometric objects; and device control commands, a catch-all for +operations not easily classified as any of the foregoing, such as +directives to start and stop output, identify the intended output +device, or place URL hyperlinks in supported output formats. + +* Menu: + +* Separation:: +* Argument Units:: +* Document Parts:: + + +File: groff.info, Node: Separation, Next: Argument Units, Prev: Language Concepts, Up: Language Concepts + +6.1.1.1 Separation +.................. + +AT&T 'troff' output has strange requirements regarding whitespace. The +'gtroff' output parser, however, is more tolerant, making whitespace +maximally optional. Such characters, i.e., the tab, space, and newline, +always have a syntactical meaning. They are never printable because +spacing within the output is always done by positioning commands. + + Any sequence of space or tab characters is treated as a single +"syntactical space". It separates commands and arguments, but is only +required when there would occur a clashing between the command code and +the arguments without the space. Most often, this happens when +variable-length command names, arguments, argument lists, or command +clusters meet. Commands and arguments with a known, fixed length need +not be separated by syntactical space. + + A line break is a syntactical element, too. Every command argument +can be followed by whitespace, a comment, or a newline character. Thus +a "syntactical line break" is defined to consist of optional syntactical +space that is optionally followed by a comment, and a newline character. + + The normal commands, those for positioning and text, consist of a +single letter taking a fixed number of arguments. For historical +reasons, the parser allows stacking of such commands on the same line, +but fortunately, in 'gtroff''s intermediate output, every command with +at least one argument is followed by a line break, thus providing +excellent readability. + + The other commands--those for drawing and device controlling--have a +more complicated structure; some recognize long command names, and some +take a variable number of arguments. So all 'D' and 'x' commands were +designed to request a syntactical line break after their last argument. +Only one command, 'x X', has an argument that can span several input +lines; all other commands must have all of their arguments on the same +line as the command, i.e., the arguments may not be split by a line +break. + + Empty lines (these are lines containing only space and/or a comment), +can occur everywhere. They are just ignored. + + +File: groff.info, Node: Argument Units, Next: Document Parts, Prev: Separation, Up: Language Concepts + +6.1.1.2 Argument Units +...................... + +Some commands take integer arguments that are assumed to represent +values in a measurement unit, but the letter for the corresponding +scaling unit is not written with the output command arguments. Most +commands assume the scaling unit 'u', the basic unit of the device, some +use 'z', the scaled point unit of the device, while others, such as the +color commands, expect plain integers. + + Single characters can have the eighth bit set, as can the names of +fonts and special characters. The names of characters and fonts can be +of arbitrary length. A character that is to be printed is always in the +current font. + + A string argument is always terminated by the next whitespace +character (space, tab, or newline); an embedded '#' character is +regarded as part of the argument, not as the beginning of a comment +command. An integer argument is already terminated by the next +non-digit character, which then is regarded as the first character of +the next argument or command. + + +File: groff.info, Node: Document Parts, Prev: Argument Units, Up: Language Concepts + +6.1.1.3 Document Parts +...................... + +A correct intermediate output document consists of two parts, the +"prologue" and the "body". + + The task of the prologue is to set the general device parameters +using three exactly specified commands. 'gtroff''s prologue is +guaranteed to consist of the following three lines (in that order): + + x T DEVICE + x res N H V + x init + +with the arguments set as outlined in *note Device Control Commands::. +The parser for the intermediate output format is able to interpret +additional whitespace and comments as well even in the prologue. + + The body is the main section for processing the document data. +Syntactically, it is a sequence of any commands different from the ones +used in the prologue. Processing is terminated as soon as the first +'x stop' command is encountered; the last line of any 'gtroff' +intermediate output always contains such a command. + + Semantically, the body is page oriented. A new page is started by a +'p' command. Positioning, writing, and drawing commands are always done +within the current page, so they cannot occur before the first 'p' +command. Absolute positioning (by the 'H' and 'V' commands) is done +relative to the current page; all other positioning is done relative to +the current location within this page. + + +File: groff.info, Node: Command Reference, Next: Intermediate Output Examples, Prev: Language Concepts, Up: gtroff Output + +6.1.2 Command Reference +----------------------- + +This section describes all intermediate output commands, both from AT&T +'troff' as well as the 'gtroff' extensions. + +* Menu: + +* Comment Command:: +* Simple Commands:: +* Graphics Commands:: +* Device Control Commands:: +* Obsolete Command:: + + +File: groff.info, Node: Comment Command, Next: Simple Commands, Prev: Command Reference, Up: Command Reference + +6.1.2.1 Comment Command +....................... + +'#ANYTHING' + A comment. Ignore any characters from the '#' character up to the + next newline character. + + This command is the only possibility for commenting in the + intermediate output. Each comment can be preceded by arbitrary + syntactical space; every command can be terminated by a comment. + + +File: groff.info, Node: Simple Commands, Next: Graphics Commands, Prev: Comment Command, Up: Command Reference + +6.1.2.2 Simple Commands +....................... + +The commands in this subsection have a command code consisting of a +single character, taking a fixed number of arguments. Most of them are +commands for positioning and text writing. These commands are tolerant +of whitespace. Optionally, syntactical space can be inserted before, +after, and between the command letter and its arguments. All of these +commands are stackable; i.e., they can be preceded by other simple +commands or followed by arbitrary other commands on the same line. A +separating syntactical space is necessary only when two integer +arguments would clash or if the preceding argument ends with a string +argument. + +'C ID' + Typeset the glyph of the special character ID. Trailing + syntactical space is necessary to allow special character names of + arbitrary length. The drawing position is not advanced. + +'c G' + Typeset the glyph of the ordinary character C. The drawing + position is not advanced. + +'f N' + Select the font mounted at position N. N cannot be negative. + +'H N' + Horizontally move the drawing position to N basic units from the + left edge of the page. N cannot be negative. + +'h N' + Move the drawing position right N basic units. AT&T 'troff' + allowed negative N; GNU 'troff' does not produce such values, but + 'groff''s output driver library handles them. + +'m COLOR-SCHEME [COMPONENT ...]' + Select the stroke color using the COMPONENTs in the color space + SCHEME. Each COMPONENT is an integer between 0 and 65535. The + quantity of components and their meanings vary with each SCHEME. + This command is a 'groff' extension. + + 'mc CYAN MAGENTA YELLOW' + Use the CMY color scheme with components cyan, magenta, and + yellow. + + 'md' + Use the default color (no components; black in most cases). + + 'mg GRAY' + Use a grayscale color scheme with a component ranging between + 0 (black) and 65535 (white). + + 'mk CYAN MAGENTA YELLOW BLACK' + Use the CMYK color scheme with components cyan, magenta, + yellow, and black. + + 'mr RED GREEN BLUE' + Use the RGB color scheme with components red, green, and blue. + +'N N' + Typeset the glyph with index N in the current font. N is normally + a non-negative integer. The drawing position is not advanced. The + 'html' and 'xhtml' devices use this command with negative N to + produce unbreakable space; the absolute value of N is taken and + interpreted in basic units. + +'n B A' + Indicate a break. No action is performed; the command is present + to make the output more easily parsed. The integers B and A + describe the vertical space amounts before and after the break, + respectively. GNU 'troff' issues this command but 'groff''s output + driver library ignores it. See 'v' and 'V' below. + +'p N' + Begin a new page, setting its number to N. Each page is + independent, even from those using the same number. The vertical + drawing position is set to 0. All positioning, writing, and + drawing commands are interpreted in the context of a page, so a + 'p' command must precede them. + +'s N' + Set type size to N scaled points (unit 'z' in GNU 'troff'. AT&T + 'troff' used unscaled points 'p' instead; see *note Output Language + Compatibility::. + +'t XYZ' +'t XYZ DUMMY-ARG' + Typeset a word XYZ; that is, set a sequence of ordinary glyphs + named X, Y, Z, ..., terminated by a space character or a line + break; an optional second integer argument is ignored (this allows + the formatter to generate an even number of arguments). Each glyph + is set at the current drawing position, and the position is then + advanced horizontally by the glyph's width. A glyph's width is + read from its metrics in the font description file, scaled to the + current type size, and rounded to a multiple of the horizontal + motion quantum. Use the 'C' command to emplace glyphs of special + characters. The 't' command is a 'groff' extension and is output + only for devices whose 'DESC' file contains the 'tcommand' + directive; see *note DESC File Format::. + +'u N XYZ' + Typeset word XYZ with track kerning. As 't', but after placing + each glyph, the drawing position is further advanced horizontally + by N basic units ('u'). The 'u' command is a 'groff' extension and + is output only for devices whose 'DESC' file contains the + 'tcommand' directive; see *note DESC File Format::. + +'V N' + Vertically move the drawing position to N basic units from the top + edge of the page. N cannot be negative. + +'v N' + Move the drawing position down N basic units. AT&T 'troff' allowed + negative N; GNU 'troff' does not produce such values, but 'groff''s + output driver library handles them. + +'w' + Indicate an inter-word space. No action is performed; the command + is present to make the output more easily parsed. Only adjustable, + breakable inter-word spaces are thus described; those resulting + from '\~' or horizontal motion escape sequences are not. GNU + 'troff' issues this command but 'groff''s output driver library + ignores it. See 'h' and 'H' above. + + +File: groff.info, Node: Graphics Commands, Next: Device Control Commands, Prev: Simple Commands, Up: Command Reference + +6.1.2.3 Graphics Commands +......................... + +Each graphics or drawing command in the intermediate output starts with +the letter 'D', followed by one or two characters that specify a +subcommand; this is followed by a fixed or variable number of integer +arguments that are separated by a single space character. A 'D' command +may not be followed by another command on the same line (apart from a +comment), so each 'D' command is terminated by a syntactical line break. + + 'gtroff' output follows the classical spacing rules (no space between +command and subcommand, all arguments are preceded by a single space +character), but the parser allows optional space between the command +letters and makes the space before the first argument optional. As +usual, each space can be any sequence of tab and space characters. + + Some graphics commands can take a variable number of arguments. In +this case, they are integers representing a size measured in basic units +'u'. The arguments called H1, H2, ..., HN stand for horizontal +distances where positive means right, negative left. The arguments +called V1, V2, ..., VN stand for vertical distances where positive means +down, negative up. All these distances are offsets relative to the +current location. + + Each graphics command directly corresponds to a similar 'gtroff' '\D' +escape sequence. *Note Drawing Geometric Objects::. + + Unknown 'D' commands are assumed to be device-specific. Its +arguments are parsed as strings; the whole information is then sent to +the postprocessor. + + In the following command reference, the syntax element +means a syntactical line break as defined above. + +'D~ H1 V1 H2 V2 ... HN VN' + Draw B-spline from current position to offset (H1,V1), then to + offset (H2,V2), if given, etc., up to (HN,VN). This command takes + a variable number of argument pairs; the current position is moved + to the terminal point of the drawn curve. + +'Da H1 V1 H2 V2' + Draw arc from current position to (H1,V1)+(H2,V2) with center at + (H1,V1); then move the current position to the final point of the + arc. + +'DC D' +'DC D DUMMY-ARG' + Draw a solid circle using the current fill color with diameter D + (integer in basic units 'u') with leftmost point at the current + position; then move the current position to the rightmost point of + the circle. An optional second integer argument is ignored (this + allows the formatter to generate an even number of arguments). + This command is a 'gtroff' extension. + +'Dc D' + Draw circle line with diameter D (integer in basic units 'u') with + leftmost point at the current position; then move the current + position to the rightmost point of the circle. + +'DE H V' + Draw a solid ellipse in the current fill color with a horizontal + diameter of H and a vertical diameter of V (both integers in basic + units 'u') with the leftmost point at the current position; then + move to the rightmost point of the ellipse. This command is a + 'gtroff' extension. + +'De H V' + Draw an outlined ellipse with a horizontal diameter of H and a + vertical diameter of V (both integers in basic units 'u') with the + leftmost point at current position; then move to the rightmost + point of the ellipse. + +'DF COLOR-SCHEME [COMPONENT ...]' + Set fill color for solid drawing objects using different color + schemes; the analogous command for setting the color of text, line + graphics, and the outline of graphic objects is 'm'. The color + components are specified as integer arguments between 0 and 65535. + The number of color components and their meaning vary for the + different color schemes. These commands are generated by + 'gtroff''s escape sequences '\D'F ...'' and '\M' (with no other + corresponding graphics commands). No position changing. This + command is a 'gtroff' extension. + + 'DFc CYAN MAGENTA YELLOW' + Set fill color for solid drawing objects using the CMY color + scheme, having the 3 color components CYAN, MAGENTA, and + YELLOW. + + 'DFd' + Set fill color for solid drawing objects to the default fill + color value (black in most cases). No component arguments. + + 'DFg GRAY' + Set fill color for solid drawing objects to the shade of gray + given by the argument, an integer between 0 (black) and 65535 + (white). + + 'DFk CYAN MAGENTA YELLOW BLACK' + Set fill color for solid drawing objects using the CMYK color + scheme, having the 4 color components CYAN, MAGENTA, YELLOW, + and BLACK. + + 'DFr RED GREEN BLUE' + Set fill color for solid drawing objects using the RGB color + scheme, having the 3 color components RED, GREEN, and BLUE. + +'Df N' + The argument N must be an integer in the range -32767 to 32767. + + 0 <= N <= 1000 + Set the color for filling solid drawing objects to a shade of + gray, where 0 corresponds to solid white, 1000 (the default) + to solid black, and values in between to intermediate shades + of gray; this is obsoleted by command 'DFg'. + + N < 0 or N > 1000 + Set the filling color to the color that is currently being + used for the text and the outline, see command 'm'. For + example, the command sequence + + mg 0 0 65535 + Df -1 + + sets all colors to blue. + + No position changing. This command is a 'gtroff' extension. + +'Dl H V' + Draw line from current position to offset (H,V) (integers in basic + units 'u'); then set current position to the end of the drawn line. + +'Dp H1 V1 H2 V2 ... HN VN' + Draw a polygon line from current position to offset (H1,V1), from + there to offset (H2,V2), etc., up to offset (HN,VN), and from there + back to the starting position. For historical reasons, the + position is changed by adding the sum of all arguments with odd + index to the actual horizontal position and the even ones to the + vertical position. Although this doesn't make sense it is kept for + compatibility. This command is a 'gtroff' extension. + +'DP H1 V1 H2 V2 ... HN VN' + Draw a solid polygon in the current fill color rather than an + outlined polygon, using the same arguments and positioning as the + corresponding 'Dp' command. This command is a 'gtroff' extension. + +'Dt N' + Set the current line thickness to N (an integer in basic units 'u') + if N>0; if N=0 select the smallest available line thickness; if N<0 + set the line thickness proportional to the type size (this is the + default before the first 'Dt' command was specified). For + historical reasons, the horizontal position is changed by adding + the argument to the actual horizontal position, while the vertical + position is not changed. Although this doesn't make sense it is + kept for compatibility. This command is a 'gtroff' extension. + + +File: groff.info, Node: Device Control Commands, Next: Obsolete Command, Prev: Graphics Commands, Up: Command Reference + +6.1.2.4 Device Control Commands +............................... + +Each device control command starts with the letter 'x', followed by a +space character (optional or arbitrary space or tab in 'gtroff') and a +subcommand letter or word; each argument (if any) must be preceded by a +syntactical space. All 'x' commands are terminated by a syntactical +line break; no device control command can be followed by another command +on the same line (except a comment). + + The subcommand is basically a single letter, but to increase +readability, it can be written as a word, i.e., an arbitrary sequence of +characters terminated by the next tab, space, or newline character. All +characters of the subcommand word but the first are simply ignored. For +example, 'gtroff' outputs the initialization command 'x i' as 'x init' +and the resolution command 'x r' as 'x res'. + + In the following, the syntax element means a syntactical +line break (*note Separation::). + +'xF NAME' + The 'F' stands for FILENAME. + + Use NAME as the intended name for the current file in error + reports. This is useful for remembering the original file name + when 'gtroff' uses an internal piping mechanism. The input file is + not changed by this command. This command is a 'gtroff' extension. + +'xf N S' + The 'f' stands for FONT. + + Mount font position N (a non-negative integer) with font named S (a + text word). *Note Font Positions::. + +'xH N' + The 'H' stands for HEIGHT. + + Set glyph height to N (a positive integer in scaled points 'z'). + AT&T 'troff' uses the unit points ('p') instead. *Note Output + Language Compatibility::. + +'xi' + The 'i' stands for INIT. + + Initialize device. This is the third command of the prologue. + +'xp' + The 'p' stands for PAUSE. + + Parsed but ignored. The AT&T 'troff' manual documents this command + as + + pause device, can be restarted + + but GNU 'troff' output drivers do nothing with this command. + +'xr N H V' + The 'r' stands for RESOLUTION. + + Resolution is N, while H is the minimal horizontal motion, and V + the minimal vertical motion possible with this device; all + arguments are positive integers in basic units 'u' per inch. This + is the second command of the prologue. + +'xS N' + The 'S' stands for SLANT. + + Set slant to N (an integer in basic units 'u'). + +'xs' + The 's' stands for STOP. + + Terminates the processing of the current file; issued as the last + command of any intermediate 'troff' output. + +'xt' + The 't' stands for TRAILER. + + Generate trailer information, if any. In GNU 'troff', this is + ignored. + +'xT XXX' + The 'T' stands for TYPESETTER. + + Set the name of the output driver to XXX, a sequence of + non-whitespace characters terminated by whitespace. The possible + names correspond to those of 'groff''s '-T' option. This is the + first command of the prologue. + +'xu N' + The 'u' stands for UNDERLINE. + + Configure underlining of spaces. If N is 1, start underlining of + spaces; if N is 0, stop underlining of spaces. This is needed for + the 'cu' request in 'nroff' mode and is ignored otherwise. This + command is a 'gtroff' extension. + +'xX ANYTHING' + The 'x' stands for X-ESCAPE. + + Send string ANYTHING uninterpreted to the device. If the line + following this command starts with a '+' character this line is + interpreted as a continuation line in the following sense. The '+' + is ignored, but a newline character is sent instead to the device, + the rest of the line is sent uninterpreted. The same applies to + all following lines until the first character of a line is not a + '+' character. This command is generated by the 'gtroff' escape + sequence '\X'. The line-continuing feature is a 'gtroff' + extension. + + +File: groff.info, Node: Obsolete Command, Prev: Device Control Commands, Up: Command Reference + +6.1.2.5 Obsolete Command +........................ + +In AT&T 'troff' output, the writing of a single glyph is mostly done by +a very strange command that combines a horizontal move and a single +character giving the glyph name. It doesn't have a command code, but is +represented by a 3-character argument consisting of exactly 2 digits and +a character. + +DDG + Move right DD (exactly two decimal digits) basic units 'u', then + print glyph G (represented as a single character). + + In GNU 'troff', arbitrary syntactical space around and within this + command is allowed. Only when a preceding command on the same line + ends with an argument of variable length is a separating space + obligatory. In AT&T 'troff', large clusters of these and other + commands are used, mostly without spaces; this made such output + almost unreadable. + + For modern high-resolution devices, this command does not make sense +because the width of the glyphs can become much larger than two decimal +digits. In 'gtroff', this is only used for the devices 'X75', 'X75-12', +'X100', and 'X100-12'. For other devices, the commands 't' and 'u' +provide a better functionality. + + +File: groff.info, Node: Intermediate Output Examples, Next: Output Language Compatibility, Prev: Command Reference, Up: gtroff Output + +6.1.3 Intermediate Output Examples +---------------------------------- + +This section presents the intermediate output generated from the same +input for three different devices. The input is the sentence 'hell +world' fed into 'gtroff' on the command line. + +High-resolution device 'ps' + + This is the standard output of 'gtroff' if no '-T' option is given. + + shell> echo "hell world" | groff -Z -T ps + + x T ps + x res 72000 1 1 + x init + p1 + x font 5 TR + f5 + s10000 + V12000 + H72000 + thell + wh2500 + tw + H96620 + torld + n12000 0 + x trailer + V792000 + x stop + + This output can be fed into 'grops' to get its representation as a + PostScript file. + +Low-resolution device 'latin1' + + This is similar to the high-resolution device except that the + positioning is done at a minor scale. Some comments (lines + starting with '#') were added for clarification; they were not + generated by the formatter. + + shell> echo "hell world" | groff -Z -T latin1 + + # prologue + x T latin1 + x res 240 24 40 + x init + # begin a new page + p1 + # font setup + x font 1 R + f1 + s10 + # initial positioning on the page + V40 + H0 + # write text 'hell' + thell + # inform about space, and issue a horizontal jump + wh24 + # write text 'world' + tworld + # announce line break, but do nothing because... + n40 0 + # ...the end of the document has been reached + x trailer + V2640 + x stop + + This output can be fed into 'grotty' to get a formatted text + document. + +AT&T 'troff' output + Since a computer monitor has a much lower resolution than modern + printers, the intermediate output for X11 devices can use the + jump-and-write command with its 2-digit displacements. + + shell> echo "hell world" | groff -Z -T X100 + + x T X100 + x res 100 1 1 + x init + p1 + x font 5 TR + f5 + s10 + V16 + H100 + # write text with jump-and-write commands + ch07e07l03lw06w11o07r05l03dh7 + n16 0 + x trailer + V1100 + x stop + + This output can be fed into 'xditview' or 'gxditview' for + displaying in X. + + Due to the obsolete jump-and-write command, the text clusters in + the AT&T 'troff' output are almost unreadable. + + +File: groff.info, Node: Output Language Compatibility, Prev: Intermediate Output Examples, Up: gtroff Output + +6.1.4 Output Language Compatibility +----------------------------------- + +The intermediate output language of AT&T 'troff' was first documented in +'A Typesetter-independent TROFF', by Brian Kernighan, and by 1992 the +AT&T 'troff' manual was updated to incorprate a description of it. + + The GNU 'troff' intermediate output format is compatible with this +specification except for the following features. + + * The classical quasi-device independence is not yet implemented. + + * The old hardware was very different from what we use today. So the + 'groff' devices are also fundamentally different from the ones in + AT&T 'troff'. For example, the AT&T PostScript device is called + 'post' and has a resolution of only 720 units per inch, suitable + for printers 20 years ago, while 'groff''s 'ps' device has a + resolution of 72000 units per inch. Maybe, by implementing some + rescaling mechanism similar to the classical quasi-device + independence, 'groff' could emulate AT&T's 'post' device. + + * The B-spline command 'D~' is correctly handled by the intermediate + output parser, but the drawing routines aren't implemented in some + of the postprocessor programs. + + * The argument of the commands 's' and 'x H' has the implicit unit + scaled point 'z' in 'gtroff', while AT&T 'troff' has point ('p'). + This isn't an incompatibility but a compatible extension, for both + units coincide for all devices without a 'sizescale' parameter in + the 'DESC' file, including all postprocessors from AT&T and + 'groff''s text devices. The few 'groff' devices with a 'sizescale' + parameter either do not exist for AT&T 'troff', have a different + name, or seem to have a different resolution. So conflicts are + very unlikely. + + * The position changing after the commands 'Dp', 'DP', and 'Dt' is + illogical, but as old versions of 'gtroff' used this feature it is + kept for compatibility reasons. + + +File: groff.info, Node: Device and Font Description Files, Prev: gtroff Output, Up: File Formats + +6.2 Device and Font Description Files +===================================== + +The 'groff' font and output device description formats are slight +extensions of those used by AT&T device-independent 'troff'. In +distinction to the AT&T implementation, 'groff' lacks a binary format; +all files are text files.(1) (*note Device and Font Description +Files-Footnote-1::) The device and font description files for a device +NAME are stored in a 'devNAME' directory. The device description file +is called 'DESC', and, for each font supported by the device, a font +description file is called 'F', where F is usually an abbreviation of a +font's name and/or style. For example, the 'ps' (PostScript) device has +'groff' font description files for Times roman ('TR') and Zapf Chancery +Medium italic ('ZCMI'), among many others, while the 'utf8' device (for +terminal emulators) has only font descriptions for the roman, italic, +bold, and bold-italic styles ('R', 'I', 'B', and 'BI', respectively). + + Device and font description files are read both by the formatter, GNU +'troff', and by output drivers. The programs delegate these files' +processing to an internal library, 'libgroff', ensuring their consistent +interpretation. + +* Menu: + +* DESC File Format:: +* Font Description File Format:: + + +File: groff.info, Node: Device and Font Description Files-Footnotes, Up: Device and Font Description Files + + (1) Plan 9 'troff' has also abandoned the binary format. + + +File: groff.info, Node: DESC File Format, Next: Font Description File Format, Prev: Device and Font Description Files, Up: Device and Font Description Files + +6.2.1 'DESC' File Format +------------------------ + +The 'DESC' file contains a series of directives; each begins a line. +Their order is not important, with two exceptions: (1) the 'res' +directive must precede any 'papersize' directive; and (2) the 'charset' +directive must come last (if at all). If a directive name is repeated, +later entries in the file override previous ones (except that the paper +dimensions are computed based on the 'res' directive last seen when +'papersize' is encountered). Spaces and/or tabs separate words and are +ignored at line boundaries. Comments start with the '#' character and +extend to the end of a line. Empty lines are ignored. + +'family FAM' + The default font family is FAM. + +'fonts N F1 ... FN' + Fonts F1, ..., FN are mounted at font positions M+1, ..., M+N where + M is the number of 'styles' (see below). This directive may extend + over more than one line. A font name of '0' causes no font to be + mounted at the corresponding position. + +'hor N' + The horizontal motion quantum is N basic units. All horizontal + quantities are rounded to multiples of N. + +'image_generator PROGRAM' + Use PROGRAM to generate PNG images from PostScript input. Under + GNU/Linux, this is usually 'gs', but under other systems (notably + Cygwin) it might be set to another name. The 'grohtml' driver uses + this directive. + +'paperlength N' + The vertical dimension of the output medium is N basic units + (deprecated: use 'papersize' instead). + +'papersize FORMAT-OR-DIMENSION-PAIR-OR-FILE-NAME ...' + The dimensions of the output medium are as according to the + argument, which is either a standard paper format, a pair of + dimensions, or the name of a plain text file containing either of + the foregoing. + + Recognized paper formats are the ISO and DIN formats 'A0'-'A7', + 'B0'-'B7', 'C0'-'C7', 'D0'-'D7'; the U.S. paper types 'letter', + 'legal', 'tabloid', 'ledger', 'statement', and 'executive'; and the + envelope formats 'com10', 'monarch', and 'DL'. Matching is + performed without regard for lettercase. + + Alternatively, the argument can be a custom paper format in the + format 'LENGTH,WIDTH' (with no spaces before or after the comma). + Both LENGTH and WIDTH must have a unit appended; valid units are + 'i' for inches, 'c' for centimeters, 'p' for points, and 'P' for + picas. Example: '12c,235p'. An argument that starts with a digit + is always treated as a custom paper format. + + Finally, the argument can be a file name (e.g., '/etc/papersize'); + if the file can be opened, the first line is read and a match + attempted against each of the other forms. No comment syntax is + supported. + + More than one argument can be specified; each is scanned in turn + and the first valid paper specification used. + +'paperwidth N' + The horizontal dimension of the output medium is N basic units + (deprecated: use 'papersize' instead). + +'pass_filenames' + Direct GNU 'troff' to emit the name of the source file being + processed. This is achieved with the intermediate output command + 'x F', which 'grohtml' interprets. + +'postpro PROGRAM' + Use PROGRAM as the postprocessor. + +'prepro PROGRAM' + Use PROGRAM as a preprocessor. The 'html' and 'xhtml' output + devices use this directive. + +'print PROGRAM' + Use PROGRAM as a spooler program for printing. If omitted, the + '-l' and '-L' options of 'groff' are ignored. + +'res N' + The device resolution is N basic units per inch. + +'sizes S1 ... SN 0' + The device has fonts at S1, ..., SN scaled points (see below). The + list of sizes must be terminated by '0'. Each SI can also be a + range of sizes M-N. The list can extend over more than one line. + +'sizescale N' + A typographical point is subdivided into N scaled points. The + default is '1'. *Note Using Fractional Type Sizes::. + +'styles S1 ... SM' + The first M mounting positions are associated with styles S1, ..., + SM. + +'tcommand' + The postprocessor can handle the 't' and 'u' intermediate output + commands. + +'unicode' + The output device supports the complete Unicode repertoire. This + directive is useful only for devices that produce character + entities instead of glyphs. + + If 'unicode' is present, no 'charset' section is required in the + font description files since the Unicode handling built into + 'groff' is used. However, if there are entries in a font + description file's 'charset' section, they either override the + default mappings for those particular characters or add new + mappings (normally for composite characters). + + The 'utf8', 'html', and 'xhtml' output devices use this directive. + +'unitwidth N' + Quantities in the font description files are in basic units for + fonts whose type size is N scaled points. + +'unscaled_charwidths' + Make the font handling module always return unscaled character + widths. The 'grohtml' driver uses this directive. + +'use_charnames_in_special' + GNU 'troff' should encode special characters inside device control + commands; see *note Postprocessor Access::. The 'grohtml' driver + uses this directive. + +'vert N' + The vertical motion quantum is N basic units. All vertical + quantities are rounded to multiples of N. + +'charset' + This line and everything following it in the file are ignored. It + is recognized for compatibility with other 'troff' implementations. + In GNU 'troff', character set repertoire is described on a per-font + basis. + + GNU 'troff' recognizes but ignores the directives 'spare1', 'spare2', +and 'biggestfont'. + + The 'res', 'unitwidth', 'fonts', and 'sizes' lines are mandatory. +Directives not listed above are ignored by GNU 'troff' but may be used +by postprocessors to obtain further information about the device. + + +File: groff.info, Node: Font Description File Format, Prev: DESC File Format, Up: Device and Font Description Files + +6.2.2 Font Description File Format +---------------------------------- + +On typesetting output devices, each font is typically available at +multiple sizes. While paper measurements in the device description file +are in absolute units, measurements applicable to fonts must be +proportional to the type size. 'groff' achieves this using the +precedent set by AT&T device-independent 'troff': one font size is +chosen as a norm, and all others are scaled linearly relative to that +basis. The "unit width" is the number of basic units per point when the +font is rendered at this nominal size. + + For instance, 'groff''s 'lbp' device uses a 'unitwidth' of 800. Its +Times roman font 'TR' has a 'spacewidth' of 833; this is also the width +of its comma, period, centered period, and mathematical asterisk, while +its 'M' is 2,963 basic units. Thus, an 'M' on the 'lbp' device is 2,963 +basic units wide at a notional type size of 800 points.(1) (*note Font +Description File Format-Footnote-1::) + + A font description file has two sections. The first is a sequence of +directives, and is parsed similarly to the 'DESC' file described above. +Except for the directive names that begin the second section, their +ordering is immaterial. Later directives of the same name override +earlier ones, spaces and tabs are handled in the same way, and the same +comment syntax is supported. Empty lines are ignored throughout. + +'name F' + The name of the font is F. 'DESC' is an invalid font name. Simple + integers are valid, but their use is discouraged.(2) (*note Font + Description File Format-Footnote-2::) + +'spacewidth N' + The width of an unadjusted inter-word space is N basic units. + + The directives above must appear in the first section; those below +are optional. + +'slant N' + The font's glyphs have a slant of N degrees; a positive N slants in + the direction of text flow. + +'ligatures LIG1 ... LIGN [0]' + Glyphs LIG1, ..., LIGN are ligatures; possible ligatures are 'ff', + 'fi', 'fl', 'ffi' and 'ffl'. For compatibility with other 'troff' + implementations, the list of ligatures may be terminated with + a '0'. The list of ligatures must not extend over more than one + line. + +'special' + The font is "special": when a glyph is requested that is not + present in the current font, it is sought in any mounted fonts that + bear this property. + + Other directives in this section are ignored by GNU 'troff', but may +be used by postprocessors to obtain further information about the font. + + The second section contains one or two subsections. These can appear +in either order; the first one encountered commences the second section. +Each starts with a directive on a line by itself. A 'charset' +subsection is mandatory unless the associated 'DESC' file contains the +'unicode' directive. Another subsection, 'kernpairs', is optional. + + The directive 'charset' starts the character set subsection.(3) +(*note Font Description File Format-Footnote-3::) It precedes a series +of glyph descriptions, one per line. Each such glyph description +comprises a set of fields separated by spaces or tabs and organized as +follows. + + NAME METRICS TYPE CODE [ENTITY-NAME] ['--' COMMENT] + +NAME identifies the glyph: if NAME is a printable character C, it +corresponds to the 'troff' ordinary character C. If NAME is a +multi-character sequence not beginning with '\', it corresponds to the +GNU 'troff' special character escape sequence '\[NAME]'. A name +consisting of three minus signs, '---', is special and indicates that +the glyph is unnamed: such glyphs can be accessed only by the '\N' +escape sequence in 'troff'. A special character named '---' can still +be defined using 'char' and similar requests. The NAME '\-' defines the +minus sign glyph. Finally, NAME can be the unbreakable one-sixth and +one-twelfth space escape sequences, '\|' and '\^' ("thin" and "hair" +spaces, respectively), in which case only the width metric described +below is interpreted; a font can thus customize the widths of these +spaces. + + The form of the METRICS field is as follows. + + WIDTH[','[HEIGHT[','[DEPTH[','[ITALIC-CORRECTION + [','[LEFT-ITALIC-CORRECTION[','[SUBSCRIPT-CORRECTION]]]]]]]]]] + +There must not be any spaces, tabs, or newlines between these +"subfields" (which have been split here into two lines only for better +legibility). The subfields are in basic units expressed as decimal +integers. Unspecified subfields default to '0'. Since there is no +associated binary format, these values are not required to fit into the +C language data type 'char' as they are in AT&T device-independent +'troff'. + + The WIDTH subfield gives the width of the glyph. The HEIGHT subfield +gives the height of the glyph (upward is positive); if a glyph does not +extend above the baseline, it should be given a zero height, rather than +a negative height. The DEPTH subfield gives the depth of the glyph, +that is, the distance below the baseline to which the glyph extends +(downward is positive); if a glyph does not extend below the baseline, +it should be given a zero depth, rather than a negative depth. Italic +corrections are relevant to glyphs in italic or oblique styles. The +ITALIC-CORRECTION is the amount of space that should be added after an +oblique glyph to be followed immediately by an upright glyph. The +LEFT-ITALIC-CORRECTION is the amount of space that should be added +before an oblique glyph to be preceded immediately by an upright glyph. +The SUBSCRIPT-CORRECTION is the amount of space that should be added +after an oblique glyph to be followed by a subscript; it should be less +than the italic correction. + + For fonts used with typesetting devices, the TYPE field gives a +featural description of the glyph: it is a bit mask recording whether +the glyph is an ascender, descender, both, or neither. When a '\w' +escape sequence is interpolated, these values are bitwise or-ed together +for each glyph and stored in the 'nr' register. In font descriptions +for terminal devices, all glyphs might have a type of zero, regardless +of their appearance. + +'0' + means the glyph lies entirely between the baseline and a horizontal + line at the "x-height" of the font; typical examples are 'a', 'c', + and 'x'; + +'1' + means the glyph descends below the baseline, like 'p'; + +'2' + means the glyph ascends above the font's x-height, like 'A' or 'b'; + and + +'3' + means the glyph is both an ascender and a descender--this is true + of parentheses in some fonts. + + The CODE field gives a numeric identifier that the postprocessor uses +to render the glyph. The glyph can be specified to 'troff' using this +code by means of the '\N' escape sequence. CODE can be any integer.(4) +(*note Font Description File Format-Footnote-4::) + + The ENTITY-NAME field defines an identifier for the glyph that the +postprocessor uses to print the GNU 'troff' glyph NAME. This field is +optional; it was introduced so that the 'grohtml' output driver could +encode its character set. For example, the glyph '\[Po]' is represented +by '£' in HTML 4.0. For efficiency, these data are now compiled +directly into 'grohtml'. 'grops' uses the field to build sub-encoding +arrays for PostScript fonts containing more than 256 glyphs. Anything +on the line after the ENTITY-NAME field or '--' is ignored. + + A line in the 'charset' section can also have the form + + NAME " + +identifying NAME as another name for the glyph mentioned in the +preceding line. Such aliases can be chained. + + The directive 'kernpairs' starts a list of kerning adjustments to be +made to adjacent glyph pairs from this font. It contains a sequence of +lines formatted as follows. + + G1 G2 N + +The foregoing means that when glyph G1 is typeset immediately before G2, +the space between them should be increased by N. Most kerning pairs +should have a negative value for N. + + +File: groff.info, Node: Font Description File Format-Footnotes, Up: Font Description File Format + + (1) 800-point type is not practical for most purposes, but using it +enables the quantities in the font description files to be expressed as +integers. + + (2) 'groff' requests and escape sequences interpret non-negative font +names as mounting positions instead. Further, a font named '0' cannot +be automatically mounted by the 'fonts' directive of a 'DESC' file. + + (3) For typesetter devices, this directive is misnamed since it +starts a list of glyphs, not characters. + + (4) that is, any integer parsable by the C standard library's +'strtol(3)' function + + +File: groff.info, Node: Copying This Manual, Next: Request Index, Prev: Font Description File Format, Up: Top + +Appendix A Copying This Manual +****************************** + + Version 1.3, 3 November 2008 + + Copyright Š 2000-2018 Free Software Foundation, Inc. + + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + 0. PREAMBLE + + The purpose of this License is to make a manual, textbook, or other + functional and useful document "free" in the sense of freedom: to + assure everyone the effective freedom to copy and redistribute it, + with or without modifying it, either commercially or + noncommercially. Secondarily, this License preserves for the + author and publisher a way to get credit for their work, while not + being considered responsible for modifications made by others. + + This License is a kind of "copyleft", which means that derivative + works of the document must themselves be free in the same sense. + It complements the GNU General Public License, which is a copyleft + license designed for free software. + + We have designed this License in order to use it for manuals for + free software, because free software needs free documentation: a + free program should come with manuals providing the same freedoms + that the software does. But this License is not limited to + software manuals; it can be used for any textual work, regardless + of subject matter or whether it is published as a printed book. We + recommend this License principally for works whose purpose is + instruction or reference. + + 1. APPLICABILITY AND DEFINITIONS + + This License applies to any manual or other work, in any medium, + that contains a notice placed by the copyright holder saying it can + be distributed under the terms of this License. Such a notice + grants a world-wide, royalty-free license, unlimited in duration, + to use that work under the conditions stated herein. The + "Document", below, refers to any such manual or work. Any member + of the public is a licensee, and is addressed as "you". You accept + the license if you copy, modify or distribute the work in a way + requiring permission under copyright law. + + A "Modified Version" of the Document means any work containing the + Document or a portion of it, either copied verbatim, or with + modifications and/or translated into another language. + + A "Secondary Section" is a named appendix or a front-matter section + of the Document that deals exclusively with the relationship of the + publishers or authors of the Document to the Document's overall + subject (or to related matters) and contains nothing that could + fall directly within that overall subject. (Thus, if the Document + is in part a textbook of mathematics, a Secondary Section may not + explain any mathematics.) The relationship could be a matter of + historical connection with the subject or with related matters, or + of legal, commercial, philosophical, ethical or political position + regarding them. + + The "Invariant Sections" are certain Secondary Sections whose + titles are designated, as being those of Invariant Sections, in the + notice that says that the Document is released under this License. + If a section does not fit the above definition of Secondary then it + is not allowed to be designated as Invariant. The Document may + contain zero Invariant Sections. If the Document does not identify + any Invariant Sections then there are none. + + The "Cover Texts" are certain short passages of text that are + listed, as Front-Cover Texts or Back-Cover Texts, in the notice + that says that the Document is released under this License. A + Front-Cover Text may be at most 5 words, and a Back-Cover Text may + be at most 25 words. + + A "Transparent" copy of the Document means a machine-readable copy, + represented in a format whose specification is available to the + general public, that is suitable for revising the document + straightforwardly with generic text editors or (for images composed + of pixels) generic paint programs or (for drawings) some widely + available drawing editor, and that is suitable for input to text + formatters or for automatic translation to a variety of formats + suitable for input to text formatters. A copy made in an otherwise + Transparent file format whose markup, or absence of markup, has + been arranged to thwart or discourage subsequent modification by + readers is not Transparent. An image format is not Transparent if + used for any substantial amount of text. A copy that is not + "Transparent" is called "Opaque". + + Examples of suitable formats for Transparent copies include plain + ASCII without markup, Texinfo input format, LaTeX input format, + SGML or XML using a publicly available DTD, and standard-conforming + simple HTML, PostScript or PDF designed for human modification. + Examples of transparent image formats include PNG, XCF and JPG. + Opaque formats include proprietary formats that can be read and + edited only by proprietary word processors, SGML or XML for which + the DTD and/or processing tools are not generally available, and + the machine-generated HTML, PostScript or PDF produced by some word + processors for output purposes only. + + The "Title Page" means, for a printed book, the title page itself, + plus such following pages as are needed to hold, legibly, the + material this License requires to appear in the title page. For + works in formats which do not have any title page as such, "Title + Page" means the text near the most prominent appearance of the + work's title, preceding the beginning of the body of the text. + + The "publisher" means any person or entity that distributes copies + of the Document to the public. + + A section "Entitled XYZ" means a named subunit of the Document + whose title either is precisely XYZ or contains XYZ in parentheses + following text that translates XYZ in another language. (Here XYZ + stands for a specific section name mentioned below, such as + "Acknowledgements", "Dedications", "Endorsements", or "History".) + To "Preserve the Title" of such a section when you modify the + Document means that it remains a section "Entitled XYZ" according + to this definition. + + The Document may include Warranty Disclaimers next to the notice + which states that this License applies to the Document. These + Warranty Disclaimers are considered to be included by reference in + this License, but only as regards disclaiming warranties: any other + implication that these Warranty Disclaimers may have is void and + has no effect on the meaning of this License. + + 2. VERBATIM COPYING + + You may copy and distribute the Document in any medium, either + commercially or noncommercially, provided that this License, the + copyright notices, and the license notice saying this License + applies to the Document are reproduced in all copies, and that you + add no other conditions whatsoever to those of this License. You + may not use technical measures to obstruct or control the reading + or further copying of the copies you make or distribute. However, + you may accept compensation in exchange for copies. If you + distribute a large enough number of copies you must also follow the + conditions in section 3. + + You may also lend copies, under the same conditions stated above, + and you may publicly display copies. + + 3. COPYING IN QUANTITY + + If you publish printed copies (or copies in media that commonly + have printed covers) of the Document, numbering more than 100, and + the Document's license notice requires Cover Texts, you must + enclose the copies in covers that carry, clearly and legibly, all + these Cover Texts: Front-Cover Texts on the front cover, and + Back-Cover Texts on the back cover. Both covers must also clearly + and legibly identify you as the publisher of these copies. The + front cover must present the full title with all words of the title + equally prominent and visible. You may add other material on the + covers in addition. Copying with changes limited to the covers, as + long as they preserve the title of the Document and satisfy these + conditions, can be treated as verbatim copying in other respects. + + If the required texts for either cover are too voluminous to fit + legibly, you should put the first ones listed (as many as fit + reasonably) on the actual cover, and continue the rest onto + adjacent pages. + + If you publish or distribute Opaque copies of the Document + numbering more than 100, you must either include a machine-readable + Transparent copy along with each Opaque copy, or state in or with + each Opaque copy a computer-network location from which the general + network-using public has access to download using public-standard + network protocols a complete Transparent copy of the Document, free + of added material. If you use the latter option, you must take + reasonably prudent steps, when you begin distribution of Opaque + copies in quantity, to ensure that this Transparent copy will + remain thus accessible at the stated location until at least one + year after the last time you distribute an Opaque copy (directly or + through your agents or retailers) of that edition to the public. + + It is requested, but not required, that you contact the authors of + the Document well before redistributing any large number of copies, + to give them a chance to provide you with an updated version of the + Document. + + 4. MODIFICATIONS + + You may copy and distribute a Modified Version of the Document + under the conditions of sections 2 and 3 above, provided that you + release the Modified Version under precisely this License, with the + Modified Version filling the role of the Document, thus licensing + distribution and modification of the Modified Version to whoever + possesses a copy of it. In addition, you must do these things in + the Modified Version: + + A. Use in the Title Page (and on the covers, if any) a title + distinct from that of the Document, and from those of previous + versions (which should, if there were any, be listed in the + History section of the Document). You may use the same title + as a previous version if the original publisher of that + version gives permission. + + B. List on the Title Page, as authors, one or more persons or + entities responsible for authorship of the modifications in + the Modified Version, together with at least five of the + principal authors of the Document (all of its principal + authors, if it has fewer than five), unless they release you + from this requirement. + + C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. + + D. Preserve all the copyright notices of the Document. + + E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. + + F. Include, immediately after the copyright notices, a license + notice giving the public permission to use the Modified + Version under the terms of this License, in the form shown in + the Addendum below. + + G. Preserve in that license notice the full lists of Invariant + Sections and required Cover Texts given in the Document's + license notice. + + H. Include an unaltered copy of this License. + + I. Preserve the section Entitled "History", Preserve its Title, + and add to it an item stating at least the title, year, new + authors, and publisher of the Modified Version as given on the + Title Page. If there is no section Entitled "History" in the + Document, create one stating the title, year, authors, and + publisher of the Document as given on its Title Page, then add + an item describing the Modified Version as stated in the + previous sentence. + + J. Preserve the network location, if any, given in the Document + for public access to a Transparent copy of the Document, and + likewise the network locations given in the Document for + previous versions it was based on. These may be placed in the + "History" section. You may omit a network location for a work + that was published at least four years before the Document + itself, or if the original publisher of the version it refers + to gives permission. + + K. For any section Entitled "Acknowledgements" or "Dedications", + Preserve the Title of the section, and preserve in the section + all the substance and tone of each of the contributor + acknowledgements and/or dedications given therein. + + L. Preserve all the Invariant Sections of the Document, unaltered + in their text and in their titles. Section numbers or the + equivalent are not considered part of the section titles. + + M. Delete any section Entitled "Endorsements". Such a section + may not be included in the Modified Version. + + N. Do not retitle any existing section to be Entitled + "Endorsements" or to conflict in title with any Invariant + Section. + + O. Preserve any Warranty Disclaimers. + + If the Modified Version includes new front-matter sections or + appendices that qualify as Secondary Sections and contain no + material copied from the Document, you may at your option designate + some or all of these sections as invariant. To do this, add their + titles to the list of Invariant Sections in the Modified Version's + license notice. These titles must be distinct from any other + section titles. + + You may add a section Entitled "Endorsements", provided it contains + nothing but endorsements of your Modified Version by various + parties--for example, statements of peer review or that the text + has been approved by an organization as the authoritative + definition of a standard. + + You may add a passage of up to five words as a Front-Cover Text, + and a passage of up to 25 words as a Back-Cover Text, to the end of + the list of Cover Texts in the Modified Version. Only one passage + of Front-Cover Text and one of Back-Cover Text may be added by (or + through arrangements made by) any one entity. If the Document + already includes a cover text for the same cover, previously added + by you or by arrangement made by the same entity you are acting on + behalf of, you may not add another; but you may replace the old + one, on explicit permission from the previous publisher that added + the old one. + + The author(s) and publisher(s) of the Document do not by this + License give permission to use their names for publicity for or to + assert or imply endorsement of any Modified Version. + + 5. COMBINING DOCUMENTS + + You may combine the Document with other documents released under + this License, under the terms defined in section 4 above for + modified versions, provided that you include in the combination all + of the Invariant Sections of all of the original documents, + unmodified, and list them all as Invariant Sections of your + combined work in its license notice, and that you preserve all + their Warranty Disclaimers. + + The combined work need only contain one copy of this License, and + multiple identical Invariant Sections may be replaced with a single + copy. If there are multiple Invariant Sections with the same name + but different contents, make the title of each such section unique + by adding at the end of it, in parentheses, the name of the + original author or publisher of that section if known, or else a + unique number. Make the same adjustment to the section titles in + the list of Invariant Sections in the license notice of the + combined work. + + In the combination, you must combine any sections Entitled + "History" in the various original documents, forming one section + Entitled "History"; likewise combine any sections Entitled + "Acknowledgements", and any sections Entitled "Dedications". You + must delete all sections Entitled "Endorsements." + + 6. COLLECTIONS OF DOCUMENTS + + You may make a collection consisting of the Document and other + documents released under this License, and replace the individual + copies of this License in the various documents with a single copy + that is included in the collection, provided that you follow the + rules of this License for verbatim copying of each of the documents + in all other respects. + + You may extract a single document from such a collection, and + distribute it individually under this License, provided you insert + a copy of this License into the extracted document, and follow this + License in all other respects regarding verbatim copying of that + document. + + 7. AGGREGATION WITH INDEPENDENT WORKS + + A compilation of the Document or its derivatives with other + separate and independent documents or works, in or on a volume of a + storage or distribution medium, is called an "aggregate" if the + copyright resulting from the compilation is not used to limit the + legal rights of the compilation's users beyond what the individual + works permit. When the Document is included in an aggregate, this + License does not apply to the other works in the aggregate which + are not themselves derivative works of the Document. + + If the Cover Text requirement of section 3 is applicable to these + copies of the Document, then if the Document is less than one half + of the entire aggregate, the Document's Cover Texts may be placed + on covers that bracket the Document within the aggregate, or the + electronic equivalent of covers if the Document is in electronic + form. Otherwise they must appear on printed covers that bracket + the whole aggregate. + + 8. TRANSLATION + + Translation is considered a kind of modification, so you may + distribute translations of the Document under the terms of section + 4. Replacing Invariant Sections with translations requires special + permission from their copyright holders, but you may include + translations of some or all Invariant Sections in addition to the + original versions of these Invariant Sections. You may include a + translation of this License, and all the license notices in the + Document, and any Warranty Disclaimers, provided that you also + include the original English version of this License and the + original versions of those notices and disclaimers. In case of a + disagreement between the translation and the original version of + this License or a notice or disclaimer, the original version will + prevail. + + If a section in the Document is Entitled "Acknowledgements", + "Dedications", or "History", the requirement (section 4) to + Preserve its Title (section 1) will typically require changing the + actual title. + + 9. TERMINATION + + You may not copy, modify, sublicense, or distribute the Document + except as expressly provided under this License. Any attempt + otherwise to copy, modify, sublicense, or distribute it is void, + and will automatically terminate your rights under this License. + + However, if you cease all violation of this License, then your + license from a particular copyright holder is reinstated (a) + provisionally, unless and until the copyright holder explicitly and + finally terminates your license, and (b) permanently, if the + copyright holder fails to notify you of the violation by some + reasonable means prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is + reinstated permanently if the copyright holder notifies you of the + violation by some reasonable means, this is the first time you have + received notice of violation of this License (for any work) from + that copyright holder, and you cure the violation prior to 30 days + after your receipt of the notice. + + Termination of your rights under this section does not terminate + the licenses of parties who have received copies or rights from you + under this License. If your rights have been terminated and not + permanently reinstated, receipt of a copy of some or all of the + same material does not give you any rights to use it. + + 10. FUTURE REVISIONS OF THIS LICENSE + + The Free Software Foundation may publish new, revised versions of + the GNU Free Documentation License from time to time. Such new + versions will be similar in spirit to the present version, but may + differ in detail to address new problems or concerns. See + . + + Each version of the License is given a distinguishing version + number. If the Document specifies that a particular numbered + version of this License "or any later version" applies to it, you + have the option of following the terms and conditions either of + that specified version or of any later version that has been + published (not as a draft) by the Free Software Foundation. If the + Document does not specify a version number of this License, you may + choose any version ever published (not as a draft) by the Free + Software Foundation. If the Document specifies that a proxy can + decide which future versions of this License can be used, that + proxy's public statement of acceptance of a version permanently + authorizes you to choose that version for the Document. + + 11. RELICENSING + + "Massive Multiauthor Collaboration Site" (or "MMC Site") means any + World Wide Web server that publishes copyrightable works and also + provides prominent facilities for anybody to edit those works. A + public wiki that anybody can edit is an example of such a server. + A "Massive Multiauthor Collaboration" (or "MMC") contained in the + site means any set of copyrightable works thus published on the MMC + site. + + "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 + license published by Creative Commons Corporation, a not-for-profit + corporation with a principal place of business in San Francisco, + California, as well as future copyleft versions of that license + published by that same organization. + + "Incorporate" means to publish or republish a Document, in whole or + in part, as part of another Document. + + An MMC is "eligible for relicensing" if it is licensed under this + License, and if all works that were first published under this + License somewhere other than this MMC, and subsequently + incorporated in whole or in part into the MMC, (1) had no cover + texts or invariant sections, and (2) were thus incorporated prior + to November 1, 2008. + + The operator of an MMC Site may republish an MMC contained in the + site under CC-BY-SA on the same site at any time before August 1, + 2009, provided the MMC is eligible for relicensing. + +ADDENDUM: How to use this License for your documents +==================================================== + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and license +notices just after the title page: + + Copyright (C) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. A copy of the license is included in the section entitled ``GNU + Free Documentation License''. + + If you have Invariant Sections, Front-Cover Texts and Back-Cover +Texts, replace the "with...Texts." line with this: + + with the Invariant Sections being LIST THEIR TITLES, with + the Front-Cover Texts being LIST, and with the Back-Cover Texts + being LIST. + + If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + + If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of free +software license, such as the GNU General Public License, to permit +their use in free software. + + +File: groff.info, Node: Request Index, Next: Escape Sequence Index, Prev: Copying This Manual, Up: Top + +Appendix B Request Index +************************ + +Request names appear without a leading control character; the defaults +are '.' for the regular control character and ''' for the no-break +control character. + +[index] +* Menu: + +* ab: Debugging. (line 55) +* ad: Manipulating Filling and Adjustment. + (line 83) +* af: Assigning Register Formats. + (line 12) +* aln: Setting Registers. (line 110) +* als: Strings. (line 198) +* am: Writing Macros. (line 126) +* am1: Writing Macros. (line 127) +* ami: Writing Macros. (line 128) +* ami1: Writing Macros. (line 129) +* as: Strings. (line 114) +* as1: Strings. (line 115) +* asciify: Diversions. (line 208) +* backtrace: Debugging. (line 104) +* bd: Artificial Fonts. (line 95) +* blm: Blank Line Traps. (line 7) +* box: Diversions. (line 63) +* boxa: Diversions. (line 64) +* bp: Page Control. (line 11) +* br: Manipulating Filling and Adjustment. + (line 39) +* break: while. (line 72) +* brp: Manipulating Filling and Adjustment. + (line 156) +* c2: Control Characters. (line 29) +* cc: Control Characters. (line 23) +* ce: Manipulating Filling and Adjustment. + (line 208) +* cf: I/O. (line 58) +* cflags: Using Symbols. (line 252) +* ch: Page Location Traps. (line 114) +* char: Using Symbols. (line 351) +* chop: Strings. (line 145) +* class: Character Classes. (line 12) +* close: I/O. (line 240) +* color: Colors. (line 15) +* composite: Using Symbols. (line 208) +* continue: while. (line 76) +* cp: Compatibility Mode. (line 16) +* cs: Artificial Fonts. (line 125) +* cu: Artificial Fonts. (line 86) +* da: Diversions. (line 32) +* de: Writing Macros. (line 14) +* de1: Writing Macros. (line 86) +* defcolor: Colors. (line 27) +* dei: Writing Macros. (line 108) +* dei1: Writing Macros. (line 109) +* device: Postprocessor Access. + (line 15) +* devicem: Postprocessor Access. + (line 45) +* di: Diversions. (line 31) +* do: Compatibility Mode. (line 27) +* ds: ms Document Control Settings. + (line 15) +* ds <1>: Strings. (line 24) +* ds1: Strings. (line 25) +* dt: Diversion Traps. (line 11) +* ec: Using Escape Sequences. + (line 76) +* ecr: Using Escape Sequences. + (line 102) +* ecs: Using Escape Sequences. + (line 101) +* el: if-else. (line 8) +* em: End-of-input Traps. (line 7) +* eo: Using Escape Sequences. + (line 71) +* ev: Environments. (line 46) +* evc: Environments. (line 100) +* ex: Debugging. (line 60) +* fam: Font Families. (line 21) +* fc: Fields. (line 18) +* fchar: Using Symbols. (line 352) +* fcolor: Colors. (line 85) +* fi: Manipulating Filling and Adjustment. + (line 66) +* fl: Debugging. (line 95) +* fp: Font Positions. (line 16) +* fschar: Using Symbols. (line 353) +* fspecial: Special Fonts. (line 18) +* ft: Selecting Fonts. (line 11) +* ftr: Selecting Fonts. (line 69) +* fzoom: Selecting Fonts. (line 83) +* gcolor: Colors. (line 57) +* hc: Manipulating Hyphenation. + (line 88) +* hcode: Manipulating Hyphenation. + (line 293) +* hla: Manipulating Hyphenation. + (line 327) +* hlm: Manipulating Hyphenation. + (line 340) +* hpf: Manipulating Hyphenation. + (line 233) +* hpfa: Manipulating Hyphenation. + (line 234) +* hpfcode: Manipulating Hyphenation. + (line 235) +* hw: Manipulating Hyphenation. + (line 22) +* hy: Manipulating Hyphenation. + (line 120) +* hym: Manipulating Hyphenation. + (line 354) +* hys: Manipulating Hyphenation. + (line 369) +* ie: if-else. (line 7) +* if: if-then. (line 7) +* ig: Comments. (line 54) +* in: Line Layout. (line 86) +* it: Input Line Traps. (line 7) +* itc: Input Line Traps. (line 8) +* kern: Ligatures and Kerning. + (line 41) +* lc: Leaders. (line 22) +* length: Strings. (line 135) +* lf: Debugging. (line 31) +* lg: Ligatures and Kerning. + (line 23) +* linetabs: Tabs and Fields. (line 139) +* ll: Line Layout. (line 138) +* ls: Manipulating Spacing. + (line 57) +* lsm: Leading Space Traps. (line 7) +* lt: Page Layout. (line 53) +* mc: Miscellaneous. (line 110) +* mk: Page Motions. (line 10) +* mso: I/O. (line 49) +* msoquiet: I/O. (line 50) +* na: Manipulating Filling and Adjustment. + (line 150) +* ne: Page Control. (line 31) +* nf: Manipulating Filling and Adjustment. + (line 74) +* nh: Manipulating Hyphenation. + (line 228) +* nm: Miscellaneous. (line 9) +* nn: Miscellaneous. (line 74) +* nop: if-then. (line 26) +* nr: ms Document Control Settings. + (line 11) +* nr <1>: Setting Registers. (line 10) +* nr <2>: Setting Registers. (line 64) +* nr <3>: Auto-increment. (line 14) +* nroff: troff and nroff Modes. + (line 33) +* ns: Manipulating Spacing. + (line 116) +* nx: I/O. (line 90) +* open: I/O. (line 207) +* opena: I/O. (line 208) +* os: Page Control. (line 66) +* output: Diversions. (line 195) +* pc: Page Layout. (line 68) +* pev: Debugging. (line 78) +* pi: I/O. (line 149) +* pl: Page Layout. (line 9) +* pm: Debugging. (line 82) +* pn: Page Layout. (line 23) +* pnr: Debugging. (line 86) +* po: Line Layout. (line 60) +* ps: Changing the Type Size. + (line 7) +* psbb: Miscellaneous. (line 158) +* pso: I/O. (line 38) +* ptr: Debugging. (line 90) +* pvs: Changing the Vertical Spacing. + (line 48) +* rchar: Using Symbols. (line 410) +* rd: I/O. (line 95) +* return: Writing Macros. (line 163) +* rfschar: Using Symbols. (line 411) +* rj: Manipulating Filling and Adjustment. + (line 247) +* rm: Strings. (line 193) +* rn: Strings. (line 190) +* rnn: Setting Registers. (line 105) +* rr: Setting Registers. (line 99) +* rs: Manipulating Spacing. + (line 117) +* rt: Page Motions. (line 11) +* schar: Using Symbols. (line 354) +* shc: Manipulating Hyphenation. + (line 97) +* shift: Parameters. (line 30) +* sizes: Changing the Type Size. + (line 71) +* so: I/O. (line 9) +* soquiet: I/O. (line 10) +* sp: Manipulating Spacing. + (line 10) +* special: Special Fonts. (line 17) +* spreadwarn: Debugging. (line 135) +* ss: Manipulating Filling and Adjustment. + (line 267) +* stringdown: Strings. (line 170) +* stringup: Strings. (line 171) +* sty: Font Families. (line 62) +* substring: Strings. (line 153) +* sv: Page Control. (line 65) +* sy: I/O. (line 171) +* ta: Tabs and Fields. (line 13) +* tag: Postprocessor Access. + (line 58) +* taga: Postprocessor Access. + (line 59) +* tc: Tabs and Fields. (line 127) +* ti: Line Layout. (line 110) +* tkf: Ligatures and Kerning. + (line 60) +* tl: Page Layout. (line 39) +* tm: Debugging. (line 43) +* tm1: Debugging. (line 44) +* tmc: Debugging. (line 45) +* tr: Character Translations. + (line 13) +* trf: I/O. (line 57) +* trin: Character Translations. + (line 14) +* trnt: Character Translations. + (line 79) +* troff: troff and nroff Modes. + (line 25) +* uf: Artificial Fonts. (line 90) +* ul: Artificial Fonts. (line 64) +* unformat: Diversions. (line 233) +* vpt: Vertical Position Traps. + (line 13) +* vs: Changing the Vertical Spacing. + (line 7) +* warn: Debugging. (line 154) +* warnscale: Debugging. (line 131) +* wh: Page Location Traps. (line 11) +* while: while. (line 10) +* write: I/O. (line 219) +* writec: I/O. (line 220) +* writem: I/O. (line 231) + diff --git a/doc/groff.info-3 b/doc/groff.info-3 new file mode 100644 index 0000000..151c796 Binary files /dev/null and b/doc/groff.info-3 differ diff --git a/doc/groff.pdf b/doc/groff.pdf new file mode 100644 index 0000000..84e8422 Binary files /dev/null and b/doc/groff.pdf differ diff --git a/doc/groff.texi b/doc/groff.texi new file mode 100644 index 0000000..2a6635e --- /dev/null +++ b/doc/groff.texi @@ -0,0 +1,18927 @@ +\input texinfo + +@c +@c Please convert this manual with `texi2dvi -e groff.texi' due to +@c problems in texinfo regarding expansion of user-defined macros. +@c +@c You need texinfo 5.0 or newer to format this document! +@c + +@c %**start of header (This is for running Texinfo on a region.) +@setfilename groff.info +@settitle The GNU Troff Manual +@setchapternewpage odd +@footnotestyle separate +@c %**end of header (This is for running Texinfo on a region.) + +@documentlanguage en +@documentencoding ISO-8859-1 + + +@smallbook + +@finalout + + +@copying +This manual documents GNU @code{troff} version 1.23.0. + +Copyright @copyright{} 1994--2023 Free Software Foundation, Inc. + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 or +any later version published by the Free Software Foundation; with no +Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A +copy of the license is included in the section entitled ``GNU Free +Documentation License''. +@end quotation +@end copying + + +@c We use the following indices: +@c +@c cindex: concepts +@c rqindex: requests +@c esindex: escape sequences +@c vindex: registers +@c kindex: commands in font files +@c pindex: programs and files +@c tindex: environment variables +@c maindex: macros +@c stindex: strings +@c opindex: operators +@c +@c tindex and cindex are merged. + +@defcodeindex rq +@defcodeindex es +@defcodeindex ma +@defcodeindex st +@defcodeindex op +@syncodeindex tp cp + + +@c To avoid uppercasing in @deffn while converting to info, we define +@c our special @Var{}. + +@macro Var{arg} +@r{@slanted{\arg\}} +@end macro + + +@c To assure correct HTML translation, some ugly hacks are necessary. +@c While processing a @def... request, the HTML translator looks at the +@c next line to decide whether to start indentation, and if the line +@c starts with @def... (e.g. @deffnx), indentation is started. We must +@c therefore ensure that a @def... is seen, during macro expansion. +@c +@c The following macros have to be used: +@c +@c One item: +@c +@c @Def... +@c +@c Two items: +@c +@c @Def...List +@c @Def...ListEnd +@c +@c More than two: +@c +@c @Def...List +@c @Def...Item +@c @Def...Item +@c ... +@c @Def...ListEnd +@c +@c The definition block must end with +@c +@c @endDef... +@c +@c The above is valid for texinfo 4.0f and above. +@c +@c By default, only the first item generates an index entry. To +@c override this, use a variant with a trailing `x' (like +@c `@DefmacItemx'). + + +@c a dummy macro to assure the `@def...' + +@macro defdummy +@c +@end macro + + +@c definition of requests + +@macro Defreq{name, arg} +@deffn Request @t{.\name\} \arg\ +@rqindex \name\ +@c +@end macro + +@macro DefreqList{name, arg} +@deffn Request @t{.\name\} \arg\ +@defdummy +@rqindex \name\ +@c +@end macro + +@macro DefreqItem{name, arg} +@deffnx Request @t{.\name\} \arg\ +@defdummy +@c +@end macro + +@macro DefreqItemx{name, arg} +@deffnx Request @t{.\name\} \arg\ +@defdummy +@rqindex \name\ +@c +@end macro + +@macro DefreqListEnd{name, arg} +@deffnx Request @t{.\name\} \arg\ +@c +@end macro + +@macro DefreqListEndx{name, arg} +@deffnx Request @t{.\name\} \arg\ +@rqindex \name\ +@c +@end macro + +@macro endDefreq +@end deffn +@end macro + + +@c definition of escape sequences + +@macro Defesc{name, delimI, arg, delimII} +@deffn Escape@tie{}sequence @t{\name\\delimI\}@Var{\arg\}@t{\delimII\} +@esindex \name\ +@c +@end macro + +@macro DefescList{name, delimI, arg, delimII} +@deffn Escape@tie{}sequence @t{\name\\delimI\}@Var{\arg\}@t{\delimII\} +@defdummy +@esindex \name\ +@c +@end macro + +@macro DefescItem{name, delimI, arg, delimII} +@deffnx Escape@tie{}sequence @t{\name\\delimI\}@Var{\arg\}@t{\delimII\} +@defdummy +@c +@end macro + +@macro DefescItemx{name, delimI, arg, delimII} +@deffnx Escape@tie{}sequence @t{\name\\delimI\}@Var{\arg\}@t{\delimII\} +@defdummy +@esindex \name\ +@c +@end macro + +@macro DefescListEnd{name, delimI, arg, delimII} +@deffnx Escape@tie{}sequence @t{\name\\delimI\}@Var{\arg\}@t{\delimII\} +@c +@end macro + +@macro DefescListEndx{name, delimI, arg, delimII} +@deffnx Escape@tie{}sequence @t{\name\\delimI\}@Var{\arg\}@t{\delimII\} +@esindex \name\ +@c +@end macro + +@macro endDefesc +@end deffn +@end macro + + +@c definition of registers (built in to GNU troff) + +@macro Defreg{name} +@deffn Register @t{\\n[\name\]} +@vindex \name\ +@c +@end macro + +@macro DefregList{name} +@deffn Register @t{\\n[\name\]} +@defdummy +@vindex \name\ +@c +@end macro + +@macro DefregItem{name} +@deffnx Register @t{\\n[\name\]} +@defdummy +@c +@end macro + +@macro DefregItemx{name} +@deffnx Register @t{\\n[\name\]} +@defdummy +@vindex \name\ +@c +@end macro + +@macro DefregListEnd{name} +@deffnx Register @t{\\n[\name\]} +@c +@end macro + +@macro DefregListEndx{name} +@deffnx Register @t{\\n[\name\]} +@vindex \name\ +@c +@end macro + +@macro endDefreg +@end deffn +@end macro + + +@c string definitions (built in to GNU troff) + +@macro Defstr{name} +@deffn String @t{\\*[\name\]} +@stindex \name\ +@c +@end macro + +@macro DefstrList{name} +@deffn String @t{\\*[\name\]} +@defdummy +@stindex \name\ +@c +@end macro + +@macro DefstrItem{name} +@deffnx String @t{\\*[\name\]} +@defdummy +@c +@end macro + +@macro DefstrItemx{name} +@deffnx String @t{\\*[\name\]} +@defdummy +@stindex \name\ +@c +@end macro + +@macro DefstrListEnd{name} +@deffnx String @t{\\*[\name\]} +@c +@end macro + +@macro DefstrListEndx{name} +@deffnx String @t{\\*[\name\]} +@stindex \name\ +@c +@end macro + +@macro endDefstr +@end deffn +@end macro + + +@c register definitions specific to macro packages, preprocessors, ... + +@macro Defmpreg{name, package} +@deffn Register @t{\\n[\name\]} +@vindex \name\ @r{[}\package\@r{]} +@c +@end macro + +@macro DefmpregList{name, package} +@deffn Register @t{\\n[\name\]} +@defdummy +@vindex \name\ @r{[}\package\@r{]} +@c +@end macro + +@macro DefmpregItem{name, package} +@deffnx Register @t{\\n[\name\]} +@defdummy +@c +@end macro + +@macro DefmpregItemx{name, package} +@deffnx Register @t{\\n[\name\]} +@defdummy +@vindex \name\ @r{[}\package\@r{]} +@c +@end macro + +@macro DefmpregListEnd{name, package} +@deffnx Register @t{\\n[\name\]} +@c +@end macro + +@macro DefmpregListEndx{name, package} +@deffnx Register @t{\\n[\name\]} +@vindex \name\ @r{[}\package\@r{]} +@c +@end macro + +@macro endDefmpreg +@end deffn +@end macro + + +@c definition of macros + +@macro Defmac{name, arg, package} +@defmac @t{.\name\} \arg\ +@maindex \name\ @r{[}\package\@r{]} +@c +@end macro + +@macro DefmacList{name, arg, package} +@defmac @t{.\name\} \arg\ +@defdummy +@maindex \name\ @r{[}\package\@r{]} +@c +@end macro + +@macro DefmacItem{name, arg, package} +@defmacx @t{.\name\} \arg\ +@defdummy +@c +@end macro + +@macro DefmacItemx{name, arg, package} +@defmacx @t{.\name\} \arg\ +@defdummy +@maindex \name\ @r{[}\package\@r{]} +@c +@end macro + +@macro DefmacListEnd{name, arg, package} +@defmacx @t{.\name\} \arg\ +@c +@end macro + +@macro DefmacListEndx{name, arg, package} +@defmacx @t{.\name\} \arg\ +@maindex \name\ @r{[}\package\@r{]} +@c +@end macro + +@macro endDefmac +@end defmac +@end macro + + +@c string definitions specific to macro packages, preprocessors, ... + +@macro Defmpstr{name, package} +@deffn String @t{\\*[\name\]} +@stindex \name\ @r{[}\package\@r{]} +@c +@end macro + +@macro DefmpstrList{name, package} +@deffn String @t{\\*[\name\]} +@defdummy +@stindex \name\ @r{[}\package\@r{]} +@c +@end macro + +@macro DefmpstrItem{name, package} +@deffnx String @t{\\*[\name\]} +@defdummy +@c +@end macro + +@macro DefmpstrItemx{name, package} +@deffnx String @t{\\*[\name\]} +@defdummy +@stindex \name\ @r{[}\package\@r{]} +@c +@end macro + +@macro DefmpstrListEnd{name, package} +@deffnx String @t{\\*[\name\]} +@c +@end macro + +@macro DefmpstrListEndx{name, package} +@deffnx String @t{\\*[\name\]} +@stindex \name\ @r{[}\package\@r{]} +@c +@end macro + +@macro endDefmpstr +@end deffn +@end macro + + +@c our example macros + +@macro Example +@example +@group +@end macro + +@macro endExample +@end group +@end example +@end macro + +@macro CartoucheExample +@cartouche +@example +@end macro + +@macro endCartoucheExample +@end example +@end cartouche +@end macro + + +@c Render text with angle brackets around it, as in . + +@macro angles{text} +@guilsinglleft{}@r{\text\}@guilsinglright{} +@end macro + + +@c Note: We say `Roman numerals' but `roman font'. + + +@dircategory Typesetting +@direntry +* Groff: (groff). The GNU roff document formatting system. +@end direntry + + +@titlepage +@title groff +@subtitle The GNU implementation of @code{troff} +@subtitle Edition 1.23.0 +@subtitle June 2023 +@author Trent@tie{}A.@: Fisher +@author Werner Lemberg +@author G.@tie{}Branden Robinson + +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@contents + +@ifnottex +@node Top, Introduction, (dir), (dir) +@top GNU @code{troff} +@end ifnottex + +@menu +* Introduction:: +* Invoking groff:: +* Tutorial for Macro Users:: +* Major Macro Packages:: +* GNU troff Reference:: +* File Formats:: +* Copying This Manual:: +* Request Index:: +* Escape Sequence Index:: +* Operator Index:: +* Register Index:: +* Macro Index:: +* String Index:: +* File Keyword Index:: +* Program and File Index:: +* Concept Index:: +@end menu + +@ifnottex +@insertcopying +@end ifnottex + + + +@c ===================================================================== +@c ===================================================================== + +@codequotebacktick on +@codequoteundirected on + +@node Introduction, Invoking groff, Top, Top +@chapter Introduction +@cindex introduction + +GNU @code{roff} (or @code{groff}) is a programming system for +typesetting documents. It is highly flexible and has been used +extensively for over thirty years. + +@menu +* Background:: +* What Is @code{groff}?:: +* @code{groff} Capabilities:: +* Macro Package Intro:: +* Preprocessor Intro:: +* Output Device Intro:: +* Conventions Used in This Manual:: +* Installation:: +* Credits:: +@end menu + + +@c ===================================================================== + +@node Background, What Is @code{groff}?, Introduction, Introduction +@section Background +@cindex background + +M.@: Douglas McIlroy, formerly of AT&T Bell Laboratories and present at +the creation of the Unix operating system, offers an authoritative +historical summary. + +@quotation +The prime reason for Unix was the desire of Ken [Thompson], Dennis +[Ritchie], and Joe Ossanna to have a pleasant environment for software +development. The fig leaf that got the nod from @dots{} +management was that an early use would be to develop a ``stand-alone'' +word-processing system for use in typing pools and secretarial offices. +Perhaps they had in mind ``dedicated'', as distinct from +``stand-alone''; that's what eventuated in various cases, most notably +in the legal/patent department and in the AT&T CEO's office. + +Both those systems were targets of opportunity, not foreseen from the +start. When Unix was up and running on the PDP-11, Joe got wind of +the legal department having installed a commercial word processor. +He went to pitch Unix as an alternative and clinched a trial by +promising to make @code{roff} able to number lines by tomorrow in order +to fulfill a patent-office requirement that the commercial system did +not support. + +Modems were installed so legal-department secretaries could try the +Research machine. They liked it and Joe's superb customer service. +Soon the legal department got a system of their own. Joe went on to +create @code{nroff} and @code{troff}. Document preparation became a +widespread use of Unix, but no stand-alone word-processing system was +ever undertaken. +@end quotation +@c https://minnie.tuhs.org/pipermail/tuhs/2022-March/025535.html + +A history relating @code{groff} to its predecessors @code{roff}, +@code{nroff}, and @code{troff} is available in the @cite{roff@r{(7)}} +man page. + + +@c ===================================================================== + +@node What Is @code{groff}?, @code{groff} Capabilities, Introduction, Introduction +@section What Is @code{groff}? +@cindex what is @code{groff}? +@cindex @code{groff}---what is it? + +@c BEGIN Keep parallel with groff(1), section "Description" (after the +@c first sentence). +@c This language is slightly expanded from that in the "ANNOUNCE" file +@c and on the groff home page. +@code{groff} (GNU @code{roff}) is a typesetting system that reads plain +text input files that include formatting commands to produce output in +PostScript, PDF, HTML, DVI, or other formats, or for display to a +terminal. Formatting commands can be low-level typesetting primitives, +macros from a supplied package, or user-defined macros. All three +approaches can be combined. + +A reimplementation and extension of the typesetter from @acronym{AT&T} +Unix, @code{groff} is present on most @acronym{POSIX} systems owing to +its long association with Unix manuals (including man pages). It and +its predecessor are notable for their production of several best-selling +software engineering texts. @code{groff} is capable of producing +typographically sophisticated documents while consuming minimal system +resources. +@c END Keep parallel with groff(1), section "Description" (after the +@c first sentence). + + +@c ===================================================================== + +@node @code{groff} Capabilities, Macro Package Intro, What Is @code{groff}?, Introduction +@section @code{groff} Capabilities +@cindex @code{groff} capabilities +@cindex capabilities of @code{groff} + +GNU @code{troff} is a typesetting document formatter; it provides a wide +range of low-level text and page operations within the framework of a +programming language. These operations compose to generate footnotes, +tables of contents, mathematical equations, diagrams, multi-column text, +and other elements of typeset works. Here is a survey of formatter +features; all are under precise user control. + +@itemize @bullet +@item +text filling, breaking, alignment to the left or right margin; centering + +@item +adjustment of inter-word space size to justify text, and of +inter-sentence space size to suit local style conventions + +@item +automatic and manual determination of hyphenation break points + +@item +pagination + +@item +selection of any font available to the output device + +@item +adjustment of type size and vertical spacing (or ``leading'') + +@item +configuration of line length and indentation amounts; columnation + +@item +drawing of geometric primitives (lines, arcs, polygons, circles, +@dots{}) + +@item +setup of stroke and fill colors (where supported by the output +device) + +@item +embedding of hyperlinks, images, document metadata, and other inclusions +(where supported by the output device) +@end itemize + + +@c ===================================================================== + +@node Macro Package Intro, Preprocessor Intro, @code{groff} Capabilities, Introduction +@section Macro Packages +@cindex macro package, introduction +@cindex package, macro, introduction + +Elemental typesetting functions can be be challenging to use directly +with complex documents. A @dfn{macro} facility specifies how certain +routine operations, such as starting paragraphs, or printing headers and +footers, should be performed in terms of those low-level instructions. +Macros can be specific to one document or collected together into a +@dfn{macro package} for use by many. Several macro packages available; +the most widely used are provided with @code{groff}. They are +@file{man}, @file{mdoc}, @file{me}, @file{mm}, @file{mom}, and +@file{ms}. + + +@c ===================================================================== + +@node Preprocessor Intro, Output Device Intro, Macro Package Intro, Introduction +@section Preprocessors +@cindex preprocessors + +An alternative approach to complexity management, particularly when +constructing tables, setting mathematics, or drawing diagrams, lies in +preprocessing. A @dfn{preprocessor} employs a domian-specific language +to ease the generation of tables, equations, and so forth in terms that +are convenient for human entry. Each preprocessor reads a document and +translates the parts of it that apply to it into GNU @code{troff} input. +Command-line options to @command{groff} tell it which preprocessors to +use. + +@code{groff} provides preprocessors for laying out tables +(@command{gtbl}), typesetting equations (@command{geqn}), drawing +diagrams (@command{gpic} and @command{ggrn}), inserting bibliographic +references (@command{grefer}), and drawing chemical structures +(@command{gchem}). An associated program that is useful when dealing +with preprocessors is @command{gsoelim}.@footnote{The @samp{g} prefix is +not used on all systems; see @ref{Invoking groff}.} + +@code{groff} also supports @code{grap}, a preprocessor for drawing +graphs. A free implementation of it can be obtained separately. + +Unique to @code{groff} is the @code{preconv} preprocessor that enables +@code{groff} to handle documents in a variety of input encodings. + +Other preprocessors exist, but no free implementations +are known. An example is @command{ideal}, which draws diagrams using a +mathematical constraint language. + + +@c ===================================================================== + +@node Output Device Intro, Installation, Preprocessor Intro, Introduction +@section Output Devices +@cindex postprocessors +@cindex output devices +@cindex devices for output + +GNU @code{troff}'s output is in a device-independent page description +language, which is then read by an @dfn{output driver} that translates +this language into a file format or byte stream that a piece of +(possibly emulated) hardware understands. @code{groff} features output +drivers for PostScript devices, terminal emulators (and other simple +typewriter-like machines), X11 (for previewing), @TeX{} DVI, HP +LaserJet@tie{}4/PCL5 and Canon LBP printers (which use @acronym{CaPSL}), +@acronym{HTML}, @acronym{XHTML}, and @acronym{PDF}. + + +@c ===================================================================== + +@node Installation, Conventions Used in This Manual, Output Device Intro, Introduction +@section Installation +@cindex installation + +Locate installation instructions in the files @file{INSTALL}, +@file{INSTALL.extra}, and @file{INSTALL.REPO} in the @code{groff} source +distribution. Being a GNU project, @code{groff} supports the familiar +@samp{./configure && make} command sequence. + + +@c ===================================================================== + +@node Conventions Used in This Manual, Credits, Installation, Introduction +@section Conventions Used in This Manual + +We apply the term ``groff'' to the language documented here, the GNU +implementation of the overall system, the project that develops that +system, and the command of that name. In the first sense, @code{groff} +is an extended dialect of the @code{roff} language, for which many +similar implementations exist. + +The @code{roff} language features several major categories for which +many items are predefined. Presentations of these items feature the +form in which the item is most commonly used on the left, and, aligned +to the right margin, the name of the category in brackets. + +@deffn Register \n[example] +The register @samp{example} is one that that @code{groff} @emph{doesn't} +predefine. You can create it yourself, though; see @ref{Setting +Registers}. +@end deffn + +To make this document useful as a reference and not merely amiable +bedtime reading, we tend to present these syntax items in exhaustive +detail when they arise. References to topics discussed later in the +text are frequent; skip material you don't understand yet. + +We use Texinfo's ``result'' (@result{}) and @error{} notations to +present output written to the standard output and standard error +streams, respectively. Diagnostic messages from the GNU @code{troff} +formatter and other programs are examples of the latter, but the +formatter can also be directed to write user-specified messages to the +standard error stream. The notation then serves to identify the +output stream and does not necessarily mean that an error has +occurred.@footnote{Unix and related operating systems distinguish +standard output and standard error streams @emph{because} of +@code{troff}:@: +@uref{https://minnie.tuhs.org/pipermail/tuhs/2013-December/006113.html}.} + +@Example +$ echo "Twelve o'clock and" | groff -Tascii | sed '/^$/d' + @result{} Twelve o'clock and +$ echo '.tm all is well.' | groff > /dev/null + @error{} all is well. +@endExample + +Sometimes we use @result{} somewhat abstractly to represent formatted +text that you will need to use a PostScript or PDF viewer program (or a +printer) to observe. While arguably an abuse of notation, we think this +preferable to requiring the reader to understand the syntax of these +page description languages. + +We also present diagnostic messages in an abbreviated form, often +omitting the name of the program issuing them, the input file name, and +line number or other positional information when such data do not serve +to illuminate the topic under discussion. + +Most examples are of @code{roff} language input that would be placed in +a text file. Occasionally, we start an example with a @samp{$} +character to indicate a shell prompt, as seen above. + +You are encouraged to try the examples yourself, and to alter them to +better learn @code{groff}'s behavior. Our examples frequently need to +direct the formatter to set a line length (with @samp{.ll}) that will +fit within the page margins of this manual. We mention this so that you +know why it is there before we discuss the @code{ll} request +formally.@footnote{@xref{Line Layout}.} + + +@c ===================================================================== + +@node Credits, , Conventions Used in This Manual, Introduction +@section Credits +@cindex credits + +We adapted portions of this manual from existing documents. James +Clark's man pages were an essential resource; we have updated them in +parallel with the development of this manual. We based the tutorial for +macro users on Eric Allman's introduction to his @file{me} macro package +(which we also provide, little altered from 4.4BSD). Larry Kollar +contributed much of the material on the @file{ms} macro package. + + +@c ===================================================================== +@c ===================================================================== + +@node Invoking groff, Tutorial for Macro Users, Introduction, Top +@chapter Invoking @code{groff} +@cindex invoking @code{groff} +@cindex @code{groff} invocation + +This chapter focuses on how to invoke the @code{groff} front end. This +front end takes care of the details of constructing the pipeline among +the preprocessors, @code{gtroff} and the postprocessor. + +It has become a tradition that GNU programs get the prefix @samp{g} to +distinguish them from their original counterparts provided by the host +(@pxref{Environment}). Thus, for example, @code{geqn} is GNU +@code{eqn}. On operating systems like GNU/Linux or the Hurd, which +don't contain proprietary versions of @code{troff}, and on +MS-DOS/MS-Windows, where @code{troff} and associated programs are not +available at all, this prefix is omitted since GNU @code{troff} is the +only incarnation of @code{troff} used. Exception: @samp{groff} is never +replaced by @samp{roff}. + +In this document, we consequently say @samp{gtroff} when talking about +the GNU @code{troff} program. @c XXX: Not for much longer... -- GBR +All other implementations of @code{troff} are called @acronym{AT&T} +@code{troff}, which is the common origin of almost all @code{troff} +implementations@footnote{Besides @code{groff}, @code{neatroff} is an +exception.} (with more or less compatible changes). Similarly, we say +@samp{gpic}, @samp{geqn}, and so on. + +@menu +* Groff Options:: +* Environment:: +* Macro Directories:: +* Font Directories:: +* Paper Format:: +* Invocation Examples:: +@end menu + + +@c ===================================================================== + +@node Groff Options, Environment, Invoking groff, Invoking groff +@section Options +@cindex options + +@pindex groff +@pindex gtroff +@pindex gpic +@pindex geqn +@pindex ggrn +@pindex grap +@pindex gtbl +@pindex gchem +@pindex grefer +@pindex gsoelim +@pindex preconv +@code{groff} normally runs the @code{gtroff} program and a +postprocessor appropriate for the selected device. The default device +is @samp{ps} (but it can be changed when @code{groff} is configured and +built). It can optionally preprocess with any of @code{gpic}, +@code{geqn}, @code{gtbl}, @code{ggrn}, @code{grap}, @code{gchem}, +@code{grefer}, @code{gsoelim}, or @code{preconv}. + +This section documents only options to the @code{groff} front end. Many +of the arguments to @code{groff} are passed on to @code{gtroff}; +therefore, those are also included. Arguments to preprocessors and +output drivers can be found in the man pages @cite{gpic@r{(1)}}, +@cite{geqn@r{(1)}}, @cite{gtbl@r{(1)}}, @cite{ggrn@r{(1)}}, +@cite{grefer@r{(1)}}, @cite{gchem@r{(1)}}, @cite{gsoelim@r{(1)}}, +@cite{preconv@r{(1)}}, @cite{grotty@r{(1)}}, @cite{grops@r{(1)}}, +@cite{gropdf@r{(1)}}, @cite{grohtml@r{(1)}}, @cite{grodvi@r{(1)}}, +@cite{grolj4@r{(1)}}, @cite{grolbp@r{(1)}}, and @cite{gxditview@r{(1)}}. + +The command-line format for @code{groff} is: + +@Example +groff [ -abceghijklpstvzCEGNRSUVXZ ] [ -d@var{cs} ] [ -D@var{arg} ] + [ -f@var{fam} ] [ -F@var{dir} ] [ -I@var{dir} ] [ -K@var{arg} ] + [ -L@var{arg} ] [ -m@var{name} ] [ -M@var{dir} ] [ -n@var{num} ] + [ -o@var{list} ] [ -P@var{arg} ] [ -r@var{cn} ] [ -T@var{dev} ] + [ -w@var{name} ] [ -W@var{name} ] [ @var{files}@dots{} ] +@endExample + +The command-line format for @code{gtroff} is as follows. + +@Example +gtroff [ -abcivzCERU ] [ -d@var{cs} ] [ -f@var{fam} ] [ -F@var{dir} ] + [ -m@var{name} ] [ -M@var{dir} ] [ -n@var{num} ] [ -o@var{list} ] + [ -r@var{cn} ] [ -T@var{name} ] [ -w@var{name} ] [ -W@var{name} ] + [ @var{files}@dots{} ] +@endExample + +@noindent +Obviously, many of the options to @code{groff} are actually passed on to +@code{gtroff}. + +Options without an argument can be grouped behind a +single@tie{}@option{-}. A filename of@tie{}@file{-} denotes the +standard input. Whitespace is permitted between an option and its +argument. + +The @code{grog} command can be used to guess the correct @code{groff} +command to format a file. See its man page @cite{grog@r{(1)}}; type +@samp{man grog} at the command line to view it. + +@command{groff}'s command-line options are as follows. + +@cindex command-line options +@table @samp +@item -a +@cindex plain text approximation output register (@code{.A}) +Generate a plain text approximation of the typeset output. The +read-only register @code{.A} is set to@tie{}1. @xref{Built-in +Registers}. This option produces a sort of abstract preview of the +formatted output. + +@itemize @bullet +@item +Page breaks are marked by a phrase in angle brackets; for example, +@samp{}. + +@item +Lines are broken where they would be in the formatted output. + +@item +A horizontal motion of any size is represented as one space. Adjacent +horizontal motions are not combined. Inter-sentence space nodes (those +arising from the second argument to the @code{ss} request) are not +represented. + +@item +Vertical motions are not represented. + +@item +Special characters are rendered in angle brackets; for example, the +default soft hyphen character appears as @samp{}. +@end itemize + +The above description should not be considered a specification; the +details of @option{-a} output are subject to change. + +@item -b +Write a backtrace reporting the state of @command{gtroff}'s input parser +to the standard error stream with each diagnostic message. The line +numbers given in the backtrace might not always be correct, because +@command{gtroff}'s idea of line numbers can be confused by requests that +append to +@c XXX: strings or (??? strings never contain newlines) +macros. + +@item -c +Start with color output disabled. + +@item -C +Enable AT&T @command{troff} compatibility mode; implies @option{-c}. +@xref{Implementation Differences}, for the list of incompatibilities +between @command{groff} and @acronym{AT&T} @command{troff}. + +@item -d@var{c}@var{text} +@itemx -d@var{string}=@var{text} +Define @code{roff} string @var{c} or @var{string} as@tie{}@var{t} or +@var{text}. @var{c}@tie{}must be one character; @var{string} can be +of arbitrary length. Such string assignments happen before any macro +file is loaded, including the startup file. Due to @code{getopt_long} +limitations, @var{c}@tie{}cannot be, and @var{string} cannot contain, an +equals sign, even though that is a valid character in a @code{roff} +identifier. + +@item -D@var{enc} +Set fallback input encoding used by @command{preconv} to @var{enc}; +implies @option{-k}. + +@item -e +Run @command{geqn} preprocessor. + +@item -E +Inhibit @command{gtroff} error messages. This option does @emph{not} +suppress messages sent to the standard error stream by documents or +macro packages using @code{tm} or related requests. + +@item -f@var{fam} +Use @var{fam} as the default font family. @xref{Font Families}. + +@item -F@var{dir} +Search in directory @file{@var{dir}} for the selected output device's +directory of device and font description files. See the description of +@env{GROFF_FONT_PATH} in @ref{Environment} below for the default search +locations and ordering. + +@item -g +Run @command{ggrn} preprocessor. + +@item -G +Run @command{grap} preprocessor; implies @option{-p}. + +@item -h +Display a usage message and exit. + +@item -i +Read the standard input after all the named input files have been +processed. + +@item -I@var{dir} +Search the directory @var{dir} for files named in several contexts; +implies @option{-g} and @option{-s}. + +@itemize +@item +@command{gsoelim} replaces @code{so} requests with the contents of their +file name arguments. + +@item +@command{gtroff} searches for files named as operands in its command +line and as arguments to @code{psbb}, @code{so}, and @code{soquiet} +requests. + +@item +Output drivers may search for files; for instance, @command{grops} looks +for files named in @samp{\X'ps: import @r{@dots{}}'}, @samp{\X'ps: file +@r{@dots{}}'}, and @samp{\X'pdf: pdfpic @r{@dots{}}'} device control +escape sequences. +@end itemize + +This option may be specified more than once; the directories are +searched in the order specified. If you want to search the current +directory before others, add @samp{-I .} at the desired place. The +current working directory is otherwise searched last. @option{-I} works +similarly to, and is named for, the ``include'' option of Unix C +compilers. + +@option{-I} options are passed to @command{gsoelim}, @command{gtroff}, +and output drivers; with the flag letter changed to @option{-M}, they +are also passed to @command{ggrn}. + +@item -j +Run @command{gchem} preprocessor. Implies @option{-p}. + +@item -k +Run @command{preconv} preprocessor. Refer to its man page for its +behavior if neither of @command{groff}'s @option{-K} or @option{-D} +options is also specified. + +@item -K@var{enc} +Set input encoding used by @command{preconv} to @var{enc}; implies +@option{-k}. + +@item -l +Send the output to a spooler for printing. The @code{print} directive +in the device description file specifies the default command to be used; +see @ref{Device and Font Description Files}. +@c XXX: This document is not parameterized in configuration variables. +@c If no such directive is present for the output device, +@c .ie '@PSPRINT@'' \{\ +@c this option is ignored. +@c .\} +@c .el \{\ +@c output is piped to +@c .MR @PSPRINT@ 1 . +@c .\} +See options @option{-L} and @option{-X}. + +@item -L@var{arg} +Pass @var{arg} to the print spooler program. If multiple @var{arg}s are +required, pass each with a separate @option{-L} option. @command{groff} +does not prefix an option dash to @var{arg} before passing it to the +spooler program. + +@item -m@var{name} +Process the file @file{@var{name}.tmac} prior to any input files. +If not found, @file{tmac.@var{name}} is attempted. @var{name} +(in both arrangements) is presumed to be a macro file; see the +description of @env{GROFF_TMAC_PATH} in @ref{Environment} below for the +default search locations and ordering. This option and its argument are +also passed to @command{geqn}, @command{grap}, and @command{ggrn}. + +@item -M@var{dir} +Search directory @file{@var{dir}} for macro files; see the description +of @env{GROFF_TMAC_PATH} in @ref{Environment} below for the default +search locations and ordering. This option and its argument are also +passed to @command{geqn}, @command{grap}, and @command{ggrn}. + +@item -n@var{num} +Number the first page @var{num}. + +@item -N +Prohibit newlines between @code{eqn} delimiters:@: pass @option{-N} to +@command{geqn}. + +@item -o@var{list} +@cindex print current page register (@code{.P}) +Output only pages in @var{list}, which is a comma-separated list of page +ranges; @samp{@var{n}} means page@tie{}@var{n}, @samp{@var{m}-@var{n}} +means every page between @var{m} and@tie{}@var{n}, @samp{-@var{n}} means +every page up to@tie{}@var{n}, @samp{@var{n}-} means every page from +@var{n}@tie{}on. @command{gtroff} stops processing and exits after +formatting the last page enumerated in @var{list}. + +@item -p +Run @command{gpic} preprocessor. + +@item -P@var{arg} +Pass @var{arg} to the postprocessor. If multiple @var{arg}s are +required, pass each with a separate @option{-P} option. @command{groff} +does not prefix an option dash to @var{arg} before passing it to the +postprocessor. + +@item -r@var{c}@var{numeric-expression} +@itemx -r@var{register}=@var{expr} +Set @code{roff} register@tie{}@var{c} or @var{register} to the value +@var{numeric-expression} (@pxref{Numeric Expressions}). +@var{c}@tie{}must be one character; @var{register} can be of arbitrary +length. Such register assignments happen before any macro file is +loaded, including the startup file. Due to @code{getopt_long} +limitations, @var{c}@tie{}cannot be, and @var{register} cannot contain, +an equals sign, even though that is a valid character in a @code{roff} +identifier. + +@item -R +Run @command{grefer} preprocessor. No mechanism is provided for passing +arguments to @command{grefer} because most @command{grefer} options have +equivalent language elements that can be specified within the document. + +@pindex troffrc +@pindex troffrc-end +@command{gtroff} also accepts a @option{-R} option, which is not +accessible via @command{groff}. This option prevents the loading of the +@file{troffrc} and @file{troffrc-end} files. + +@item -s +Run @command{gsoelim} preprocessor. + +@item -S +@cindex @code{open} request, and safer mode +@cindex @code{opena} request, and safer mode +@cindex @code{pso} request, and safer mode +@cindex @code{sy} request, and safer mode +@cindex @code{pi} request, and safer mode +@cindex safer mode +@cindex mode, safer +Operate in ``safer'' mode; see @option{-U} below for its opposite. For +security reasons, safer mode is enabled by default. + +@item -t +Run @command{gtbl} preprocessor. + +@item -T@var{dev} +Direct @command{gtroff} to format the input for the output device +@var{dev}. @command{groff} then calls an output driver to convert +@command{gtroff}'s output to a form appropriate for @var{dev}. The +following output devices are available. + +@table @code +@item ps +For PostScript printers and previewers. + +@item pdf +For @acronym{PDF} viewers or printers. + +@item dvi +For @TeX{} DVI format. + +@item X75 +For a 75@dmn{dpi} X11 previewer. + +@item X75-12 +For a 75@dmn{dpi} X11 previewer with a 12-point base font in the +document. + +@item X100 +For a 100@dmn{dpi} X11 previewer. + +@item X100-12 +For a 100@dmn{dpi} X11 previewer with a 12-point base font in the +document. + +@item ascii +@cindex encoding, output, @acronym{ASCII} +@cindex encoding, output, ISO@tie{}646 +@cindex @acronym{ASCII} output encoding +@cindex ISO@tie{}646 output encoding +@cindex output encoding, @acronym{ASCII} +@cindex output encoding, ISO@tie{}646 +For typewriter-like devices using the (7-bit) @acronym{ASCII} +(ISO@tie{}646) character set. + +@item latin1 +@cindex encoding, output, @w{Latin-1} (ISO @w{8859-1}) +@cindex @w{Latin-1} (ISO @w{8859-1}) output encoding +@cindex ISO @w{8859-1} (@w{Latin-1}) output encoding +@cindex output encoding, @w{Latin-1} (ISO @w{8859-1}) +For typewriter-like devices that support the @w{Latin-1} +(ISO@tie{}@w{8859-1}) character set. + +@item utf8 +@cindex encoding, output, @w{UTF-8} +@cindex @w{UTF-8} output encoding +@cindex output encoding, @w{UTF-8} +For typewriter-like devices that use the Unicode (ISO@tie{}10646) +character set with @w{UTF-8} encoding. + +@item cp1047 +@cindex encoding, output, @acronym{EBCDIC} +@cindex @acronym{EBCDIC} output encoding +@cindex output encoding, @acronym{EBCDIC} +@cindex encoding, output, code page 1047 +@cindex code page 1047 output encoding +@cindex output encoding, code page 1047 +@cindex IBM code page 1047 output encoding +@cindex CCSID 1047 output encoding (EBCDIC) +For typewriter-like devices that use the @acronym{EBCDIC} encoding IBM +code page 1047. + +@item lj4 +For HP LaserJet4-compatible (or other PCL5-compatible) printers. + +@item lbp +For Canon @acronym{CaPSL} printers (@w{LBP-4} and @w{LBP-8} series laser +printers). + +@pindex pre-grohtml +@pindex post-grohtml +@cindex @code{grohtml}, the program +@item html +@itemx xhtml +To produce @acronym{HTML} and @acronym{XHTML} output, respectively. +This driver consists of two parts, a preprocessor +(@command{pre-grohtml}) and a postprocessor (@command{post-grohtml}). +@end table + +@cindex output device name string (@code{.T}) +@cindex output device usage register (@code{.T}) +The predefined GNU @code{troff} string @code{.T} contains the name of +the output device; the read-only register @code{.T} is set to@tie{}1 if +this option is used (which is always true if @command{groff} is used to +call GNU @command{troff}). @xref{Built-in Registers}. + +The postprocessor to be used for a device is specified by the +@code{postpro} command in the device description file. (@xref{Device +and Font Description Files}.) This can be overridden with the +@option{-X} option. + +@item -U +@cindex mode, unsafe +@cindex unsafe mode +Operate in @dfn{unsafe mode}, which enables the @code{open}, +@code{opena}, @code{pi}, @code{pso}, and @code{sy} requests. These +requests are disabled by default because they allow an untrusted input +document to write to arbitrary file names and run arbitrary commands. +This option also adds the current directory to the macro package search +path; see the @option{-m} option above. @option{-U} is passed to +@command{gpic} and @command{gtroff}. + +@item -v +Write version information for @command{groff} and all programs run by it +to the standard output stream; that is, the given command line is +processed in the usual way, passing @option{-v} to the formatter and any +pre- or postprocessors invoked. + +@item -V +Output the pipeline that would be run by @command{groff} +(as a wrapper program) to the standard output stream, but do not execute +it. If given more than once, the pipeline is both written to the +standard error stream and run. + +@item -w@var{category} +Enable warnings in @var{category}. Categories are listed in +@ref{Warnings}. + +@item -W@var{category} +Inhibit warnings in @var{category}. Categories are listed in +@ref{Warnings}. + +@item -X +Use @command{gxditview} instead of the usual postprocessor to (pre)view +a document on an X11 display. Combining this option with +@option{-Tps} uses the font metrics of the PostScript device, whereas +the @option{-TX75} and @option{-TX100} options use the metrics of X11 +fonts. + +@item -z +Suppress formatted output from @command{gtroff}. + +@item -Z +Disable postprocessing. @command{gtroff} output will appear on the +standard output stream (unless suppressed with @option{-z}; see +@ref{gtroff Output} for a description of this format. +@end table + + +@c ===================================================================== + +@node Environment, Macro Directories, Groff Options, Invoking groff +@section Environment +@cindex environment variables +@cindex variables in environment + +There are also several environment variables (of the operating system, +not within @code{gtroff}) that can modify the behavior of @code{groff}. + +@table @code +@item GROFF_BIN_PATH +@tindex GROFF_BIN_PATH@r{, environment variable} +This search path, followed by @code{PATH}, is used for commands executed +by @code{groff}. + +@item GROFF_COMMAND_PREFIX +@tindex GROFF_COMMAND_PREFIX@r{, environment variable} +@cindex command prefix +@cindex prefix, for commands +If this is set to@tie{}@var{X}, then @command{groff} runs +@command{@var{X}troff} instead of @command{gtroff}. This also applies +to @command{tbl}, @command{pic}, @command{eqn}, @command{grn}, +@command{chem}, @command{refer}, and @command{soelim}. It does not +apply to @command{grops}, @command{grodvi}, @command{grotty}, +@command{pre-grohtml}, @command{post-grohtml}, @command{preconv}, +@command{grolj4}, @command{gropdf}, and @command{gxditview}. + +The default command prefix is determined during the installation +process. If a non-GNU @code{troff} system is found, prefix @samp{g} is +used, none otherwise. + +@item GROFF_ENCODING +@tindex GROFF_ENCODING@r{, environment variable} +The value of this variable is passed to the @code{preconv} +preprocessor's @option{-e} option to select the character encoding of +input files. This variable's existence implies the @code{groff} option +@option{-k}. If set but empty, @code{groff} calls @code{preconv} +without an @option{-e} option. @code{groff}'s @option{-K} option +overrides @env{GROFF_ENCODING}. See the @cite{preconv@r{(7)}} man page; +type @samp{man preconv} at the command line to view it. + +@item GROFF_FONT_PATH +@tindex GROFF_FONT_PATH@r{, environment variable} +A list of directories in which to seek the selected output device's +directory of device and font description files. GNU @code{troff} +will search directories given as arguments to any specified @option{-F} +options before these, and a built-in list of directories after them. +@xref{Font Directories} and the @cite{troff@r{(1)}} or +@cite{gtroff@r{(1)}} man pages. + +@item GROFF_TMAC_PATH +@tindex GROFF_TMAC_PATH@r{, environment variable} +A list of directories in which to seek macro files. GNU @code{troff} +will search directories given as arguments to any specified @option{-M} +options before these, and a built-in list of directories after them. +@xref{Macro Directories} and the @cite{troff@r{(1)}} or +@cite{gtroff@r{(1)}} man pages. + +@item GROFF_TMPDIR +@tindex GROFF_TMPDIR@r{, environment variable} +@tindex TMPDIR@r{, environment variable} +The directory in which @code{groff} creates temporary files. If this is +not set and @env{TMPDIR} is set, temporary files are created in that +directory. Otherwise temporary files are created in a system-dependent +default directory (on Unix and GNU/Linux systems, this is usually +@file{/tmp}). @code{grops}, @code{grefer}, @code{pre-grohtml}, and +@code{post-grohtml} can create temporary files in this directory. + +@item GROFF_TYPESETTER +@tindex GROFF_TYPESETTER@r{, environment variable} +Sets the default output device. If empty or not set, a build-time +default (often @code{ps}) is used. The @option{-T@var{dev}} option +overrides @env{GROFF_TYPESETTER}. + +@item SOURCE_DATE_EPOCH +@tindex SOURCE_DATE_EPOCH@r{, environment variable} +A timestamp (expressed as seconds since the Unix epoch) to use as the +output creation timestamp in place of the current time. The time is +converted to human-readable form using @cite{localtime@r{(3)}} when the +formatter starts up and stored in registers usable by documents and +macro packages (@pxref{Built-in Registers}). + +@item TZ +@tindex TZ@r{, environment variable} +The time zone to use when converting the current time (or value of +@env{SOURCE_DATE_EPOCH}) to human-readable form; see +@cite{tzset@r{(3)}}. +@end table + +MS-DOS and MS-Windows ports of @code{groff} use semicolons, rather than +colons, to separate the directories in the lists described above. + + +@c ===================================================================== + +@node Macro Directories, Font Directories, Environment, Invoking groff +@section Macro Directories +@cindex macro directories +@cindex directories for macros +@cindex searching macros +@cindex macros, searching + +A macro file must have a name in the form @code{@var{name}.tmac} or +@code{tmac.@var{name}} and be placed in a @dfn{tmac directory} to be +found by the @option{-m@var{name}} command-line option.@footnote{The +@code{mso} request does not have these limitations. @xref{I/O}.} +@cindex tmac, directory +@cindex directory, for tmac files +@cindex tmac, path +@cindex path, for tmac files +@cindex locating macro files +@cindex macro file search path +@cindex file, macro, search path +@cindex locating macro packages +@cindex macro package search path +@cindex package, macro, search path +Together, these directories constitute the @dfn{tmac path}. Each +directory is searched in the following order until the desired macro +file is found or the list is exhausted. + +@itemize @bullet +@item +Directories specified with GNU @code{troff}'s or @code{groff}'s +@option{-M} command-line option. + +@item +@tindex GROFF_TMAC_PATH@r{, environment variable} +Directories listed in the @env{GROFF_TMAC_PATH} environment variable. + +@item +@cindex safer mode +@cindex mode, safer +@cindex unsafe mode +@cindex mode, unsafe +@cindex current directory +@cindex directory, current +The current working directory (only if in unsafe mode using the +@option{-U} command-line option). + +@item +@cindex home directory +@cindex directory, home +The user's home directory, @env{HOME}. + +@item +@cindex site-local directory +@cindex directory, site-local +@cindex platform-specific directory +@cindex directory, platform-specific +A platform-dependent directory, a site-local (platform-independent) +directory, and the main @slanted{tmac} directory. The locations +corresponding to your installation are listed in section ``Environment'' +of @cite{gtroff@r{(1)}}. If not otherwise configured, they are as +follows. + +@Example +/usr/local/lib/groff/site-tmac +/usr/local/share/groff/site-tmac +/usr/local/share/groff/1.23.0/tmac +@endExample + +@noindent +The foregoing assumes that the version of @code{groff} is 1.23.0, and +that the installation prefix was @file{/usr/local}. It is possible to +fine-tune these locations during the source configuration process. +@end itemize + + +@c ===================================================================== + +@node Font Directories, Paper Format, Macro Directories, Invoking groff +@section Font Directories +@cindex font directories +@cindex directories for fonts +@cindex searching fonts +@cindex fonts, searching + +@code{groff} enforces few restrictions on how font description files are +named. For its family/style mechanism to work (@pxref{Font Families}), +the names of fonts within a family should start with the family name, +followed by the style. For example, the Times family uses @samp{T} for +the family name and @samp{R}, @samp{B}, @samp{I}, and @samp{BI} to +indicate the styles `roman', `bold', `italic', and `bold italic', +respectively. Thus the final font names are @samp{TR}, @samp{TB}, +@samp{TI}, and @samp{TBI}. + +@cindex font path +@cindex path, for font files +Font description files are kept in @dfn{font directories}, which +together constitute the @dfn{font path}. The search procedure +always appends the directory @code{dev}@var{name}, where @var{name} is +the name of the output device. Assuming @TeX{} DVI output, and +@file{/foo/bar} as a font directory, the font description files for +@command{grodvi} must be in @file{/foo/bar/devdvi}. +Each directory in the font path is searched in the following order until +the desired font description file is found or the list is exhausted. + +@itemize @bullet +@item +Directories specified with GNU @code{troff}'s or @code{groff}'s +@option{-f} command-line option. All output drivers (and some +preprocessors) support this option as well, because they require +information about the glyphs to be rendered in the document. + +@item +@tindex GROFF_FONT_PATH@r{, environment variable} +Directories listed in the @env{GROFF_FONT_PATH} environment variable. + +@item +@cindex site-local directory +@cindex directory, site-local +A site-local directory and the main font description directory. +The locations corresponding to your installation are listed in section +``Environment'' of @cite{gtroff@r{(1)}}. If not otherwise configured, +they are as follows. + +@Example +/usr/local/share/groff/site-font +/usr/local/share/groff/1.23.0/font +@endExample + +@noindent +The foregoing assumes that the version of @code{groff} is 1.23.0, and +that the installation prefix was @file{/usr/local}. It is possible to +fine-tune these locations during the source configuration process. +@end itemize + + +@c ===================================================================== + +@node Paper Format, Invocation Examples, Font Directories, Invoking groff +@section Paper Format +@cindex paper format +@cindex format, paper +@cindex paper size +@cindex size, paper +@cindex landscape page orientation +@cindex orientation, landscape +@cindex page orientation, landscape + +In @code{groff}, the page dimensions for the formatter GNU @code{troff} +and for output devices are handled separately. @xref{Page Layout}, for +vertical manipulation of the page size, and @xref{Line Layout}, for +horizontal changes. +@pindex papersize.tmac +@pindex troffrc +The @file{papersize} macro package, normally loaded by @file{troffrc} at +startup, provides an interface for configuring page dimensions by +convenient names, like @samp{letter} or @samp{a4}; see +@cite{groff_tmac@r{(5)}}. The default used by the formatter depends on +its build configuration, but is usually one of the foregoing, as +geographically appropriate. +@c groff(1), being generated, says what the default is. + +It is up to each macro package to respect the page dimensions configured +in this way. + +For each output device, the size of the output medium can be set in its +@file{DESC} file. Most output drivers also recognize a command-line +option @option{-p} to override the default dimensions and an option +@option{-l} to use landscape orientation. @xref{DESC File Format}, for +a description of the @code{papersize} keyword, which takes an argument +of the same form as @option{-p}. The output driver's man page, such as +@cite{grops@r{(1)}}, may also be helpful. + +@code{groff} uses the command-line option @option{-P} to pass options to +postprocessors; for example, use the following for PostScript output on +A4 paper in landscape orientation. + +@Example +groff -Tps -dpaper=a4l -P-pa4 -P-l -ms foo.ms > foo.ps +@endExample + + +@c ===================================================================== + +@c BEGIN Keep parallel with groff(1), section "Examples". +@node Invocation Examples, , Paper Format, Invoking groff +@section Invocation Examples +@cindex invocation examples +@cindex examples of invocation + +@code{roff} systems are best known for formatting man pages. Once a +@command{man} librarian program has located a man page, it may execute +a @code{groff} command much like the following. + +@Example +groff -t -man -Tutf8 /usr/share/man/man1/groff.1 +@endExample + +The librarian will also pipe the output through a pager, which might not +interpret the SGR terminal escape sequences @command{groff} emits for +boldface, underlining, or italics; see the @cite{grotty@r{(1)}} man page +for a discussion. + +To process a @code{roff} input file using the preprocessors +@command{gtbl} and @command{gpic} and the @file{me} macro package in the +way to which AT&T @code{troff} users were accustomed, one would type (or +script) a pipeline. + +@Example +gpic foo.me | gtbl | gtroff -me -Tutf8 | grotty +@endExample + +Using @command{groff}, this pipe can be shortened to an equivalent +command. + +@Example +groff -p -t -me -T utf8 foo.me +@endExample + +An even easier way to do this is to use @command{grog} to guess the +preprocessor and macro options and execute the result by using the +command substitution feature of the shell. + +@Example +$(grog -Tutf8 foo.me) +@endExample + +Each command-line option to a postprocessor must be specified with any +required leading dashes @samp{-} +@c No GNU roff postprocessor uses long options for anything except +@c --help or --version. +@c or @samp{--} +@c XXX: grolbp does. +because @command{groff} passes the arguments as-is to the postprocessor; +this permits arbitrary arguments to be transmitted. For example, to +pass a title to the @command{gxditview} postprocessor, +the shell commands + +@Example +groff -X -P -title -P 'trial run' mydoc.t +@endExample + +@noindent +and + +@Example +groff -X -Z mydoc.t | gxditview -title 'trial run' - +@endExample + +@noindent +are equivalent. +@c END Keep parallel with groff(1), section "Examples". + + + +@c ===================================================================== +@c ===================================================================== + +@node Tutorial for Macro Users, Major Macro Packages, Invoking groff, Top +@chapter Tutorial for Macro Users +@cindex tutorial for macro users +@cindex macros, tutorial for users +@cindex user's tutorial for macros +@cindex user's macro tutorial + +Most users of the @code{roff} language employ a macro package to format +their documents. Successful macro packages ease the composition +process; their users need not have mastered the full formatting +language, nor understand features like diversions, traps, and +environments. This chapter aims to familiarize you with basic concepts +and mechanisms common to many macro packages (like ``displays''). If +you prefer a meticulous and comprehensive presentation, try @ref{GNU +troff Reference} instead. + +@menu +* Basics:: +* Common Features:: +@end menu + + +@c ===================================================================== + +@node Basics, Common Features, Tutorial for Macro Users, Tutorial for Macro Users +@section Basics +@cindex basics of macro package usage +@cindex macro package usage, basics of + +Let us first survey some basic concepts necessary to use a macro package +fruitfully.@footnote{The remainder of this chapter is based on +@cite{Writing Papers with nroff using -me} by Eric@tie{}P.@: Allman, +which is distributed with @code{groff} as @file{meintro.me}.} +References are made throughout to more detailed information. + +GNU @code{troff} reads an input file prepared by the user and outputs a +formatted document suitable for publication or framing. The input +consists of text, or words to be printed, and embedded commands +(@slanted{requests} and @slanted{escape sequences}), which tell GNU +@code{troff} how to format the output. @xref{Formatter Instructions}. + +The word @slanted{argument} is used in this chapter to mean a word or +number that appears on the same line as a request, and which modifies +the meaning of that request. For example, the request + +@Example +.sp +@endExample + +@noindent +spaces one line, but + +@Example +.sp 4 +@endExample + +@noindent +spaces four lines. The number@tie{}4 is an argument to the @code{sp} +request, which says to space four lines instead of one. Arguments are +separated from the request and from each other by spaces (@emph{not} +tabs). @xref{Invoking Requests}. + +The primary function of GNU @code{troff} is to collect words from input +lines, fill output lines with those words, adjust the line to the +right-hand margin by widening spaces, and output the result. For +example, the input: + +@Example +Now is the time +for all good men +to come to the aid +of their party. +Four score and seven +years ago, etc. +@endExample + +@noindent +is read, packed onto output lines, and justified to produce: + +@Example + @result{} Now is the time for all good men to come to the aid of + @result{} their party. Four score and seven years ago, etc. +@endExample + +Sometimes a new output line should be started even though the current +line is not yet full---for example, at the end of a paragraph. To do +this it is possible to force a @slanted{break}, starting a new output +line. Some requests cause a break automatically, as do (normally) blank +input lines and input lines beginning with a space or tab. + +Not all input lines are @slanted{text lines}---words to be formatted. +Some are @slanted{control lines} that tell a macro package (or GNU +@code{troff} directly) how to format the text. Control lines start with +a dot (@samp{.}) or an apostrophe (@samp{'}) as the first character, and +can be followed by a @slanted{macro call}. + +The formatter also does more complex things, such as automatically +numbering pages, skipping over page boundaries, putting footnotes in the +correct place, and so forth. + +Here are a few hints for preparing text for input to GNU @code{troff}. + +@itemize @bullet +@item +First, keep the input lines short. Short input lines are easier to +edit, and GNU @code{troff} packs words onto longer lines anyhow. + +@item +In keeping with this, it is helpful to begin a new line after every +comma or phrase, since common corrections are to add or delete sentences +or phrases. + +@item +End each sentence with two spaces---or better, start each sentence on a +new line. GNU @code{troff} recognizes characters that usually end a +sentence, and inserts inter-sentence space accordingly. + +@item +Do not hyphenate words at the end of lines---GNU @code{troff} is smart +enough to hyphenate words as needed, but is not smart enough to take +hyphens out and join a word back together. Also, words such as +``mother-in-law'' should not be broken over a line, since then a space +can occur where not wanted, such as ``@w{mother- in}-law''. +@end itemize + +We offer further advice in @ref{Input Conventions}. + +@cindex vertical spacing (introduction) +@cindex spacing, vertical (introduction) +GNU @code{troff} permits alteration of the distance between lines of +text. This is termed @slanted{vertical spacing} and is expressed in the +same units as the type size---the point. The default is 10-point type +on 12-point spacing. To get @slanted{double-spaced} text you would set +the vertical spacing to 24 points. Some, but not all, macro packages +expose a macro or register to configure the vertical spacing. + +A number of requests allow you to change the way the output is arranged +on the page, sometimes called the @slanted{layout} of the output page. +Most macro packages don't supply macros for performing these (at least +not without performing other actions besides), as they are such basic +operations. The macro packages for writing man pages, @file{man} and +@file{mdoc}, don't encourage explicit use of these requests at all. + +@cindex spacing (introduction) +The request @w{@samp{.sp @var{N}}} leaves @var{N}@tie{}lines of blank +space. @var{N}@tie{}can be omitted (skipping a single line) or can +be of the form @var{N}i (for @var{N}@tie{}inches) or @var{N}c (for +@var{N}@tie{}centimeters). For example, the input: + +@Example +.sp 1.5i +My thoughts on the subject +.sp +@endExample + +@noindent +leaves one and a half inches of space, followed by the line ``My +thoughts on the subject'', followed by a single blank line (more +measurement units are available; see @ref{Measurements}). + +If you seek precision in spacing, be advised when using a macro package +that it might not honor @code{sp} requests as you expect; it can use a +formatter feature called @slanted{no-space mode} to prevent excess space +from accumulating. Macro packages typically offer registers to control +spacing between paragraphs, before section headings, and around displays +(discussed below); use these facilities preferentially. +@xref{Manipulating Spacing}. + +@cindex centering lines (introduction) +@cindex lines, centering (introduction) +Text lines can be centered by using the @code{ce} request. The line +after @code{ce} is centered (horizontally) on the page. To center more +than one line, use @w{@samp{.ce @var{N}}} (where @var{N} is the number +of lines to center), followed by the @var{N}@tie{}lines. To center many +lines without counting them, type: + +@Example +.ce 1000 +lines to center +.ce 0 +@endExample + +@noindent +The @w{@samp{.ce 0}} request tells GNU @code{troff} to center zero more +lines, in other words, stop centering. + +@cindex right-aligning lines (introduction) +@cindex lines, right-aligning (introduction) +@cindex right-justifying lines (introduction) +@cindex lines, right-justifying (introduction) +GNU @code{troff} also offers the @code{rj} request for right-aligning +text. It works analogously to @code{ce} and is convenient for setting +epigraphs. + +@cindex page break (introduction) +@cindex break, page (introduction) +The @code{bp} request starts a new page; this necessarily implies an +ordinary (line) break. + +@cindex break (introduction) +@cindex line break (introduction) +All of these requests cause a break; that is, they always start a new +line. To start a new line without performing any other action, use +@code{br}. If you invoke them with the apostrophe @samp{'}, the +@slanted{no-break control character}, the (initial) break they normally +perform is suppressed. @samp{'br} does nothing. + + +@c ===================================================================== + +@node Common Features, , Basics, Tutorial for Macro Users +@section Common Features +@cindex common features +@cindex features, common + +GNU @code{troff} provides low-level operations for formatting a +document. Many routine operations are undertaken in nearly all +documents that require a series of such primitive operations to be +performed. These common tasks are grouped into @slanted{macros}, which +are then collected into a @slanted{macro package}. + +Macro packages come in two varieties:@: ``major'' or ``full-service'' +ones that manage page layout, and ``minor'' or ``auxiliary'' ones that +do not, instead fulfilling narrow, specific tasks. Find a list in the +@cite{groff_tmac@r{(5)}} man page. Type @samp{man groff_tmac} at the +command line to view it. + +We survey several capabilities of full-service macro package below. +Each package employs its own macros to exercise them. For details, +consult its man page or, for @file{ms}, see @ref{ms}. + +@menu +* Paragraphs:: +* Sections and Chapters:: +* Headers and Footers:: +* Page Layout Adjustment:: +* Displays and Keeps:: +* Footnotes and Endnotes:: +* Table of Contents:: +* Indexing:: +* Document Formats:: +* Columnation:: +* Font and Size Changes:: +* Predefined Text:: +* Preprocessor Support:: +* Configuration and Customization:: +@end menu + +@c --------------------------------------------------------------------- + +@node Paragraphs, Sections and Chapters, Common Features, Common Features +@subsection Paragraphs +@cindex paragraphs + +Paragraphs can be separated and indented in various ways. Some start +with a blank line and have a first-line indentation, like most of the +ones in this manual. Block paragraphs omit the indentation. + +@Example + @result{} Some men look at constitutions with sanctimonious + @result{} reverence, and deem them like the ark of the + @result{} covenant, too sacred to be touched. +@endExample + +@cindex tags, paragraph +@cindex tagged paragraphs +@cindex lists +@noindent +We also frequently encounter @slanted{tagged} paragraphs, which begin +with a tag or label at the left margin and indent the remaining text. + +@Example + @result{} one This is the first paragraph. Notice how the + @result{} first line of the resulting paragraph lines + @result{} up with the other lines in the paragraph. +@endExample + +@noindent +If the tag is too wide for the indentation, the line is broken. + +@Example + @result{} longlabel + @result{} The label does not align with the subsequent + @result{} lines, but they align with each other. +@endExample + +@noindent +A variation of the tagged paragraph is the itemized or enumerated +paragraph, which might use punctuation or a digit for a tag, +respectively. These are frequently used to construct lists. + +@Example + @result{} o This list item starts with a bullet. When + @result{} producing output for a device using the ASCII + @result{} character set, an 'o' is formatted instead. +@endExample + +@noindent +Often, use of the same macro without a tag continues such a discussion. + +@Example + @result{} -xyz This option is recognized but ignored. + @result{} + @result{} It had a security hole that we don't discuss. +@endExample + +@c --------------------------------------------------------------------- + +@node Sections and Chapters, Headers and Footers, Paragraphs, Common Features +@subsection Sections and Chapters + +The simplest kind of section heading is unnumbered, set in a bold or +italic style, and occupies a line by itself. Others possess +automatically numbered multi-level headings and/or different typeface +styles or sizes at different levels. More sophisticated macro packages +supply macros for designating chapters and appendices. + +@c --------------------------------------------------------------------- + +@node Headers and Footers, Page Layout Adjustment, Sections and Chapters, Common Features +@subsection Headers and Footers + +@slanted{Headers} and @slanted{footers} occupy the top and bottom of +each page, respectively, and contain data like the page number and the +article or chapter title. Their appearance is not affected by the +running text. Some packages allow for different titles on even- and +odd-numbered pages (for printed, bound material). + +Headers and footers are together called @slanted{titles}, and comprise +three parts:@: left-aligned, centered, and right-aligned. A @samp{%} +character appearing anywhere in a title is automatically replaced by the +page number. @xref{Page Layout}. + +@c --------------------------------------------------------------------- + +@node Page Layout Adjustment, Displays and Keeps, Headers and Footers, Common Features +@subsection Page Layout + +Most macro packages let the user specify the size of the page margins. +The top and bottom margins are typically handled differently than the +left and right margins; the latter two are derived from the +@slanted{page offset}, @slanted{indentation}, and @slanted{line length}. +@xref{Line Layout}. Commonly, packages support registers to tune these +values. + +@c --------------------------------------------------------------------- + +@node Displays and Keeps, Footnotes and Endnotes, Page Layout Adjustment, Common Features +@subsection Displays and Keeps +@cindex displays + +@slanted{Displays} are sections of text set off from the surrounding +material (typically paragraphs), often differing in indentation, and/or +spacing. Tables, block quotations, and figures are displayed. +Equations and code examples, when not much shorter than an output line, +often are. Lists may or may not be. Packages for setting man pages +support example displays but not keeps. +@c XXX: man, mdoc keep support planned + +@cindex keeps (introduction) +A @slanted{keep} is a group of output lines, often a display, that is +formatted on a single page if possible; it causes a page break to happen +early so as to not interrupt the kept material. + +@cindex keep, floating +@cindex floating keep +@slanted{Floating keeps} can move, or ``float'', relative to the text +around them in the input. They are useful for displays that are +captioned and referred to by name, as with ``See figure@tie{}3''. +Depending on the package, a floating keep appears at the bottom of the +current page if it fits, and at the top of the next otherwise. +Alternatively, floating keeps might be deferred to the end of a section. +Using a floating keep can avoid the large vertical spaces that may +precede a tall keep of the ordinary sort when it won't fit on the page. + +@c --------------------------------------------------------------------- + +@node Footnotes and Endnotes, Table of Contents, Displays and Keeps, Common Features +@subsection Footnotes and Endnotes +@cindex footnotes +@cindex endnotes + +@slanted{Footnotes} and @slanted{endnotes} are forms of delayed +formatting. They are recorded at their points of relevance in +the input, but not formatted there. Instead, a @slanted{mark} cues the +reader to check the ``foot'', or bottom, of the current page, or in the +case of endnotes, an annotation list later in the document. Macro +packages that support these features also supply a means of +automatically numbering either type of annotation. + +@c --------------------------------------------------------------------- + +@node Table of Contents, Indexing, Footnotes and Endnotes, Common Features +@subsection Table of Contents +@cindex table of contents +@cindex contents, table of + +A package may handle a @slanted{table of contents} by directing section +heading macros to save section heading text and the page number where it +occurs for use in a later @slanted{entry} for a table of contents. It +writes the collected entries at the end of the document, once all are +known, upon request. A row of dots (a @slanted{leader}) bridges the +text on the left with its location on the right. Other collections +might work in this manner, providing lists of figures or tables. + +A table of contents is often found at the end of a GNU @code{troff} +document because the formatter processes the document in a single pass. +The @command{gropdf} output driver supports a PDF feature that relocates +pages at the time the document is rendered; see the @cite{gropdf@r{(1)}} +man page. Type @samp{man gropdf} at the command line to view it. + +@c --------------------------------------------------------------------- + +@node Indexing, Document Formats, Table of Contents, Common Features +@subsection Indexing +@cindex index, in macro package + +@pindex makeindex +An index is similar to a table of contents, in that entry labels and +locations must be collected, but poses a greater challenge because it +needs to be sorted before it is output. Here, processing the document +in multiple passes is inescapable, and tools like the @code{makeindex} +program are necessary. + +@c --------------------------------------------------------------------- + +@node Document Formats, Columnation, Indexing, Common Features +@subsection Document Formats +@cindex document formats + +Some macro packages supply stock configurations of certain documents, +like business letters and memoranda. These often also have provision +for a @slanted{cover sheet}, which may be rigid in its format. With +these features, it is even more important to use the package's macros in +preference to the formatter requests presented earlier, where possible. + +@c --------------------------------------------------------------------- + +@node Columnation, Font and Size Changes, Document Formats, Common Features +@subsection Columnation + +Macro packages apart from @file{man} and @file{mdoc} for man page +formatting offer a facility for setting multiple columns on the page. + +@c --------------------------------------------------------------------- + +@node Font and Size Changes, Predefined Text, Columnation, Common Features +@subsection Font and Size Changes + +The formatter's requests and escape sequences for setting the typeface +and size are not always intuitive, so all macro packages provide macros +to make these operations simpler. They also make it more convenient to +change typefaces in the middle of a word and can handle italic +corrections automatically. @xref{Italic Corrections}. + +@c --------------------------------------------------------------------- + +@node Predefined Text, Preprocessor Support, Font and Size Changes, Common Features +@subsection Predefined Text + +Most macro packages supply predefined strings to set prepared text like +the date, or to perform operations like super- and subscripting. + +@c --------------------------------------------------------------------- + +@node Preprocessor Support, Configuration and Customization, Predefined Text, Common Features +@subsection Preprocessor Support + +All macro packages provide support for various preprocessors and may +extend their functionality by defining macros to set their contents in +displays. Examples include @code{TS} and @code{TE} for @command{gtbl}, +@code{EQ} and @code{EN} for @command{geqn}, and @code{PS} and @code{PE} +for @command{gpic}. + +@c --------------------------------------------------------------------- + +@node Configuration and Customization, , Preprocessor Support, Common Features +@subsection Configuration and Customization + +Packages provide means of customizing many of the details of how the +package behaves. These range from setting the default type size to +changing the appearance of section headers. + +@codequotebacktick off +@codequoteundirected off + + + +@c ===================================================================== +@c ===================================================================== + +@node Major Macro Packages, GNU troff Reference, Tutorial for Macro Users, Top +@chapter Macro Packages +@cindex major macro package +@cindex package, macro, major +@cindex macro package, major + +This chapter surveys the ``major'' macro packages that come with +@code{groff}. One, @file{ms}, is presented in detail. + +@cindex full-service macro package +@cindex package, macro, full-service +@cindex macro package, full-service +Major macro packages are also sometimes described as @dfn{full-service} +due to the breadth of features they provide and because more than one +cannot be used by the same document; for example + +@Example +groff -m man foo.man -m ms bar.doc +@endExample + +@noindent +doesn't work. Option arguments are processed before non-option +arguments; the above (failing) sample is thus reordered to + +@Example +groff -m man -m ms foo.man bar.doc +@endExample + +@cindex minor macro package +@cindex package, macro, minor +@cindex macro package, minor +@cindex auxiliary macro package +@cindex package, macro, auxiliary +@cindex macro package, auxiliary +Many auxiliary, or ``minor'', macro packages are also available. They +may in general be used with any full-service macro package and handle a +variety of tasks from character encoding selection, to language +localization, to inlining of raster images. See the +@cite{groff_tmac@r{(5)}} man page for a list. Type @samp{man +groff_tmac} at the command line to view it. + +@menu +* man:: +* mdoc:: +* me:: +* mm:: +* mom:: +* ms:: +@end menu + + +@c ===================================================================== + +@node man, mdoc, Major Macro Packages, Major Macro Packages +@section @file{man} +@cindex manual pages +@cindex man pages +@pindex an.tmac +@pindex man.tmac + +The @code{man} macro package is the most widely used and probably the +most important ever developed for @code{troff}. It is easy to use, and +a vast majority of manual pages (``man pages'') are written in it. + +@code{groff}'s implementation is documented in the +@cite{groff_man@r{(7)}} man page. Type @samp{man groff_man} at the +command line to view it. + +@menu +* Optional man extensions:: +@end menu + +@c --------------------------------------------------------------------- + +@node Optional man extensions, , , man +@subsection Optional @file{man} extensions + +@pindex man.local +Use the file @file{man.local} for local extensions to the @code{man} +macros or for style changes. + +@unnumberedsubsubsec Custom headers and footers +@cindex @code{man} macros, custom headers and footers + +In @code{groff} versions 1.18.2 and later, you can specify custom +headers and footers by redefining the following macros in +@file{man.local}. + +@Defmac {PT, , man} +Control the content of the headers. Normally, the header prints the +command name and section number on either side, and the optional fifth +argument to @code{TH} in the center. +@endDefmac + +@Defmac {BT, , man} +Control the content of the footers. Normally, the footer prints the +page number and the third and fourth arguments to @code{TH}. + +Use the @code{FT} register to specify the footer position. The default +is @minus{}0.5@dmn{i}. +@endDefmac + +@unnumberedsubsubsec Ultrix-specific man macros +@cindex Ultrix-specific @code{man} macros +@cindex @code{man} macros, Ultrix-specific + +@pindex man.ultrix +The @code{groff} source distribution includes a file named +@file{man.ultrix}, containing macros compatible with the Ultrix variant +of @code{man}. Copy this file into @file{man.local} (or use the +@code{mso} request to load it) to enable the following macros. + +@Defmac {CT, @Var{key}, man} +Print @samp{}. +@endDefmac + +@Defmac {CW, , man} +Print subsequent text using a ``constant-width'' (monospaced) typeface +(Courier roman). +@endDefmac + +@Defmac {Ds, , man} +Begin a non-filled display. +@endDefmac + +@Defmac {De, , man} +End a non-filled display started with @code{Ds}. +@endDefmac + +@Defmac {EX, [@Var{indent}], man} +Begin a non-filled display using a monospaced typeface (Courier roman). +Use the optional @var{indent} argument to indent the display. +@endDefmac + +@Defmac {EE, , man} +End a non-filled display started with @code{EX}. +@endDefmac + +@Defmac {G, [@Var{text}], man} +Set @var{text} in Helvetica. If no text is present on the line where +the macro is called, then the text of the next line appears in +Helvetica. +@endDefmac + +@Defmac {GL, [@Var{text}], man} +Set @var{text} in Helvetica oblique. If no text is present on the line +where the macro is called, then the text of the next line appears in +Helvetica Oblique. +@endDefmac + +@Defmac {HB, [@Var{text}], man} +Set @var{text} in Helvetica bold. If no text is present on the line +where the macro is called, then all text up to the next @code{HB} +appears in Helvetica bold. +@endDefmac + +@Defmac {TB, [@Var{text}], man} +Identical to @code{HB}. +@endDefmac + +@Defmac {MS, @Var{title} @Var{sect} [@Var{punct}], man} +Set a man page reference in Ultrix format. The @var{title} is in +Courier instead of italic. Optional punctuation follows the section +number without an intervening space. +@endDefmac + +@Defmac {NT, [@code{C}] [@Var{title}], man} +Begin a note. Print the optional @Var{title}, or the word ``Note'', +centered on the page. Text following the macro makes up the body of the +note, and is indented on both sides. If the first argument is @code{C}, +the body of the note is printed centered (the second argument replaces +the word ``Note'' if specified). +@endDefmac + +@Defmac {NE, , man} +End a note begun with @code{NT}. +@endDefmac + +@Defmac {PN, @Var{path} [@Var{punct}], man} +Set the path name in a monospaced typeface (Courier roman), followed by +optional punctuation. +@endDefmac + +@Defmac {Pn, [@Var{punct}] @Var{path} [@Var{punct}], man} +If called with two arguments, identical to @code{PN}. If called with +three arguments, set the second argument in a monospaced typeface +(Courier roman), bracketed by the first and third arguments in the +current font. +@endDefmac + +@Defmac {R, , man} +Switch to roman font and turn off any underlining in effect. +@endDefmac + +@Defmac {RN, , man} +Print the string @samp{}. +@endDefmac + +@Defmac {VS, [@code{4}], man} +Start printing a change bar in the margin if the number@tie{}@code{4} is +specified. Otherwise, this macro does nothing. +@endDefmac + +@Defmac {VE, , man} +End printing the change bar begun by @code{VS}. +@endDefmac + +@unnumberedsubsubsec Simple example + +The following example @file{man.local} file alters the @code{SH} macro +to add some extra vertical space before printing the heading. Headings +are printed in Helvetica bold. + +@Example +.\" Make the heading fonts Helvetica +.ds HF HB +. +.\" Put more space in front of headings. +.rn SH SH-orig +.de SH +. if t .sp (u;\\n[PD]*2) +. SH-orig \\$* +.. +@endExample + + +@c ===================================================================== + +@node mdoc, me, man, Major Macro Packages +@section @file{mdoc} +@cindex @code{mdoc} macros + +@code{groff}'s implementation of the BSD @file{doc} package for man +pages is documented in the @cite{groff_mdoc@r{(7)}} man page. Type +@samp{man groff_mdoc} at the command line to view it. + + +@c ===================================================================== + +@node me, mm, mdoc, Major Macro Packages +@section @file{me} +@cindex @code{me} macro package + +@code{groff}'s implementation of the BSD @file{me} macro package is +documented using itself. A tutorial, @file{meintro.me}, and reference, +@file{meref.me}, are available in @code{groff}'s documentation +directory. A @cite{groff_me@r{(7)}} man page is also available and +identifies the installation path for these documents. Type @samp{man +groff_me} at the command line to view it. + +A French translation of the tutorial is available as +@file{meintro_fr.me} and installed parallel to the English version. + + +@c ===================================================================== + +@node mm, mom, me, Major Macro Packages +@section @file{mm} +@cindex @code{mm} macro package + +@code{groff}'s implementation of the @acronym{AT&T} memorandum macro +package is documented in the @cite{groff_mm@r{(7)}} man page. Type +@samp{man groff_mm} at the command line) to view it. + +A Swedish localization of @file{mm} is also available; see +@cite{groff_mmse@r{(7)}}. + + +@c ===================================================================== + +@node mom, ms, mm, Major Macro Packages +@section @file{mom} +@cindex @code{mom} macro package + +The main documentation files for the @file{mom} macros are in +@acronym{HTML} format. Additional, useful documentation is in +@acronym{PDF} format. See the @cite{groff@r{(1)}} man page, section +``Installation Directories'', for their location. + +@itemize @bullet +@item +@file{toc.html} +@noindent +Entry point to the full mom manual. + +@item +@file{macrolist.html} +@noindent +Hyperlinked index of macros with brief descriptions, arranged by +category. + +@item +@file{mom-pdf.pdf} +@noindent +@acronym{PDF} features and usage. +@end itemize + +The mom macros are in active development between @code{groff} releases. +The most recent version, along with up-to-date documentation, is +available at @uref{http://www.schaffter.ca/mom/mom-05.html}. + +The @cite{groff_mom@r{(7)}} man page (type @samp{man groff_mom} at +the command line) contains a partial list of available macros, however +their usage is best understood by consulting the @acronym{HTML} +documentation. + + +@c ===================================================================== + +@codequotebacktick on +@codequoteundirected on + +@node ms, , mom, Major Macro Packages +@section @file{ms} +@cindex @file{ms} macros + +The @file{ms} (``manuscript'') package is suitable for the preparation +of letters, memoranda, reports, and books. These @code{groff} +macros feature cover page and table of contents generation, +automatically numbered headings, several paragraph styles, a variety of +text styling options, footnotes, and multi-column page layouts. +@file{ms} supports the @command{tbl}, @command{eqn}, @command{pic}, and +@command{refer} preprocessors for inclusion of tables, mathematical +equations, diagrams, and standardized bibliographic citations. This +implementation is mostly compatible with the documented interface and +behavior of AT&T Unix Version@tie{}7 @file{ms}. Many extensions from +4.2BSD (Berkeley) +@c Few changes were made in 4.3, Tahoe, Reno, or 4.4. +and Tenth Edition Research Unix have been recreated. + +@menu +* ms Introduction:: +* ms Document Structure:: +* ms Document Control Settings:: +* ms Document Description Macros:: +* ms Body Text:: +* ms Page Layout:: +* Differences from AT&T ms:: +* ms Legacy Features:: +* ms Naming Conventions:: +@end menu + +@c --------------------------------------------------------------------- + +@node ms Introduction, ms Document Structure, ms, ms +@subsection Introduction + +The @file{ms} macros are the oldest surviving package for @code{roff} +systems.@footnote{While manual @emph{pages} are older, early ones used +macros supplanted by the @file{man} package of Seventh Edition Unix +(1979). @file{ms} shipped with Sixth Edition (1975) and was documented +by Mike Lesk in a Bell Labs internal memorandum.} While the @file{man} +package was designed for brief reference documents, the @file{ms} macros +are also suitable for longer works intended for printing and possible +publication. + +@menu +* ms basic information:: +@end menu + +@c --------------------------------------------------------------------- + +@node ms basic information, ms Document Structure, ms Introduction, ms Introduction +@subsubsection Basic information + +@file{ms} documents are plain text files; prepare them with your +preferred text editor. If you're in a hurry to start, know that +@file{ms} needs one of its macros called at the beginning of a document +so that it can initialize. A @dfn{macro} is a formatting instruction to +@file{ms}. Put a macro call on a line by itself. Use @samp{.PP} if you +want your paragraph's first line to be indented, or @samp{.LP} if you +don't. + +After that, start typing normally. It is a good practice to start each +sentence on a new line, or to put two spaces after sentence-ending +punctuation, so that the formatter knows where the sentence boundaries +are. You can separate paragraphs with further paragraphing macros, or +with blank lines, and you can indent with tabs. When you need one of +the features mentioned earlier (@pxref{ms}), return to this part of the +manual. + +Format the document with the @command{groff} command. @command{nroff} +can be useful for previewing. + +@CartoucheExample +$ editor radical.ms +$ nroff -ww -z -ms radical.ms # check for errors +$ nroff -ms radical.ms | less -R +$ groff -T ps -ms radical.ms > radical.ps +$ see radical.ps +@endCartoucheExample + +Our @file{radical.ms} document might look like this. + +@CartoucheExample +.LP +Radical novelties are so disturbing that they tend to be +suppressed or ignored, to the extent that even the +possibility of their existence in general is more often +denied than admitted. + +@arrow{}That's what Dijkstra said, anyway. +@endCartoucheExample + +@file{ms} exposes many aspects of document layout to user control via +@code{groff}'s @dfn{registers} and @dfn{strings}, which store numbers +and text, respectively. Measurements in @code{groff} are expressed with +a suffix called a @dfn{scaling unit}. + +@table @code +@item i +inches + +@item c +centimeters + +@item p +points (1/72 inch) + +@item P +picas (1/6 inch) + +@item v +vees; current vertical spacing + +@item m +ems; width of an ``M'' in the current font + +@item n +ens; one-half em +@end table + +Set registers with the @code{nr} request and strings with the @code{ds} +request. @dfn{Requests} are like macro calls; they go on lines by +themselves and start with the @dfn{control character}, a dot (@code{.}). +The difference is that they directly instruct the formatter program, +rather than the macro package. We'll discuss a few as applicable. It +is wise to specify a scaling unit when setting any register that +represents a length, size, or distance. + +@CartoucheExample +.nr PS 10.5p \" Use 10.5-point type. +.ds FAM P \" Use Palatino font family. +@endCartoucheExample + +@noindent +In the foregoing, we see that @code{\"} begins a comment. This is an +example of an @dfn{escape sequence}, the other kind of formatting +instruction. Escape sequences can appear anywhere. They begin with the +escape character (@code{\}) and are followed by at least one more +character. @file{ms} documents +@c like this one +tend to use only a few of @code{groff}'s many requests and escape +sequences; see @ref{Request Index} and @ref{Escape Sequence Index} or +the @cite{groff@r{(7)}} man page for complete lists. + +@table @code +@item \" +Begin comment; ignore remainder of line. + +@item \n[@var{reg}] +Interpolate value of register @var{reg}. + +@item \*[@var{str}] +Interpolate contents of string @var{str}. + +@item \*@var{s} +abbreviation of @code{\*[@var{s}]}; the name @var{s} must be only one +character + +@item \[@var{char}] +Interpolate glyph of special character named @var{char}. + +@item \& +dummy character + +@item \~ +Insert an unbreakable space that is adjustable like a normal space. + +@item \| +Move horizontally by one-sixth em (``thin space''). +@end table + +Prefix any words that start with a dot @samp{.} or neutral apostrophe +@samp{'} with @code{\&} if they are at the beginning of an input line +(or might become that way in editing) to prevent them from being +interpreted as macro calls or requests. Suffix @samp{.}, @samp{?}, and +@samp{!} with @code{\&} when needed to cancel end-of-sentence detection. + +@CartoucheExample +My exposure was \&.5 to \&.6 Sv of neutrons, said Dr.\& +Wallace after the criticality incident. +@endCartoucheExample + +@c --------------------------------------------------------------------- + +@node ms Document Structure, ms Document Control Settings, ms Introduction, ms +@subsection Document Structure +@cindex @file{ms} macros, general structure + +The @file{ms} macro package expects a certain amount of structure: +a well-formed document contains at least one paragraphing or heading +macro call. Longer documents have a structure as follows. + +@table @strong +@item Document type +Calling the @code{RP} macro at the beginning of your document puts the +document description (see below) on a cover page. Otherwise, @file{ms} +places the information (if any) on the first page, followed immediately +by the body text. Some document types found in other @file{ms} +implementations are specific to @acronym{AT&T} or Berkeley, and are not +supported by @code{groff} @file{ms}. + +@item Format and layout +By setting registers and strings, you can configure your document's +typeface, margins, spacing, headers and footers, and footnote +arrangement. @xref{ms Document Control Settings}. + +@item Document description +A document description consists of any of: a title, one or more authors' +names and affiliated institutions, an abstract, and a date or other +identifier. @xref{ms Document Description Macros}. + +@item Body text +The main matter of your document follows its description (if any). +@file{ms} supports highly structured text consisting of paragraphs +interspersed with multi-level headings (chapters, sections, subsections, +and so forth) and augmented by lists, footnotes, tables, diagrams, and +similar material. @xref{ms Body Text}. + +@item Tables of contents +Macros enable the collection of entries for a table of contents (or +index) as the material they discuss appears in the document. You then +call a macro to emit the table of contents at the end of your document. +The table of contents must necessarily follow the rest of the text since +GNU @code{troff} is a single-pass formatter; it thus cannot determine +the page number of a division of the text until it has been set and +output. Since @file{ms} was designed for the production of hard copy, +the traditional procedure was to manually relocate the pages containing +the table of contents between the cover page and the body text. Today, +page resequencing is more often done in the digital domain. An index +works similarly, but because it typically needs to be sorted after +collection, its preparation requires separate processing. +@end table + +@c --------------------------------------------------------------------- + +@node ms Document Control Settings, ms Document Description Macros, ms Document Structure, ms +@subsection Document Control Settings +@cindex @file{ms} macros, document control settings + +@file{ms} exposes many aspects of document layout to user control via +@code{groff} requests. To use them, you must understand how to define +registers and strings. + +@Defreq {nr, reg value} +Set register @var{reg} to @var{value}. If @var{reg} doesn't exist, GNU +@code{troff} creates it. +@endDefreq + +@Defreq {ds, name contents} +Set string @var{name} to @var{contents}. +@endDefreq + +A list of document control registers and strings follows. For any +parameter whose default is unsatisfactory, define its register or string +before calling any @file{ms} macro other than @code{RP}. + +@unnumberedsubsubsec Margin settings + +@Defmpreg {PO, ms} +Defines the page offset (i.e., the left margin). +@c not in V6 + +Effective: next page. + +Default: Varies by output device and paper format; 1@dmn{i} is used for +typesetters using U.S.@: letter paper, and zero for terminals. +@xref{Paper Format}. +@endDefmpreg + +@Defmpreg {LL, ms} +Defines the line length (i.e., the width of the body text). + +Effective: next paragraph. + +Default: Varies by output device and paper format; 6.5@dmn{i} is used +for typesetters using U.S.@: letter paper (@pxref{Paper Format}) and +65@dmn{n} on terminals. +@endDefmpreg + +@Defmpreg {LT, ms} +Defines the title line length (i.e., the header and footer width). This +is usually the same as @code{LL}, but need not be. + +Effective: next paragraph. + +Default: Varies by output device and paper format; 6.5@dmn{i} is used +for typesetters using U.S.@: letter paper (@pxref{Paper Format}) and +65@dmn{n} on terminals. +@endDefmpreg + +@Defmpreg {HM, ms} +Defines the header margin height at the top of the page. +@c not in V6 + +Effective: next page. + +Default: 1@dmn{i}. +@endDefmpreg + +@Defmpreg {FM, ms} +Defines the footer margin height at the bottom of the page. +@c not in V6 + +Effective: next page. + +Default: 1@dmn{i}. +@endDefmpreg + +@unnumberedsubsubsec Titles (headers, footers) + +@Defmpstr {LH, ms} +Defines the text displayed in the left header position. + +Effective: next header. + +Default: empty. +@endDefmpstr + +@Defmpstr {CH, ms} +Defines the text displayed in the center header position. + +Effective: next header. + +Default: @samp{-\n[%]-}. +@endDefmpstr + +@Defmpstr {RH, ms} +Defines the text displayed in the right header position. + +Effective: next header. + +Default: empty. +@endDefmpstr + +@Defmpstr {LF, ms} +Defines the text displayed in the left footer position. + +Effective: next footer. + +Default: empty. +@endDefmpstr + +@Defmpstr {CF, ms} +Defines the text displayed in the center footer position. + +Effective: next footer. + +Default: empty. +@endDefmpstr + +@Defmpstr {RF, ms} +Defines the text displayed in the right footer position. + +Effective: next footer. + +Default: empty. +@endDefmpstr + +@unnumberedsubsubsec Text settings + +@Defmpreg {PS, ms} +Defines the type size of the body text. + +Effective: next paragraph. + +Default: 10@dmn{p}. +@endDefmpreg + +@Defmpreg {VS, ms} +Defines the vertical spacing (type size plus leading). + +Effective: next paragraph. + +Default: 12@dmn{p}. +@endDefmpreg + +@Defmpreg {HY, ms} +Defines the automatic hyphenation mode used with the @code{hy} request. +Setting @code{HY} to@tie{}0 is equivalent to using the @code{nh} +request. This is a Tenth Edition Research Unix extension. +@c possibly 9th, but definitely not Berkeley + +Effective: next paragraph. + +Default: 6. +@endDefmpreg + +@Defmpstr {FAM, ms} +Defines the font family used to typeset the document. This is a GNU +extension. + +Effective: next paragraph. + +Default: defined by the output device; often @samp{T} (@pxref{ms Body +Text}) +@endDefmpstr + +@unnumberedsubsubsec Paragraph settings + +@Defmpreg {PI, ms} +Defines the indentation amount used by the @code{PP}, @code{IP} (unless +overridden by an optional argument), @code{XP}, and @code{RS} macros. +@c not in V6 + +Effective: next paragraph. + +Default: 5@dmn{n}. +@endDefmpreg + +@Defmpreg {PD, ms} +Defines the space between paragraphs. +@c not in V6 + +Effective: next paragraph. + +Default: 0.3@dmn{v} (1@dmn{v} on low-resolution devices). +@endDefmpreg + +@Defmpreg {QI, ms} +Defines the indentation amount used on both sides of a paragraph set +with the @code{QP} or between the @code{QS} and @code{QE} macros. + +Effective: next paragraph. + +Default: 5@dmn{n}. +@endDefmpreg + +@Defmpreg {PORPHANS, ms} +Defines the minimum number of initial lines of any paragraph that must +be kept together to avoid isolated lines at the bottom of a page. If a +new paragraph is started close to the bottom of a page, and there is +insufficient space to accommodate @code{PORPHANS} lines before an +automatic page break, then a page break is forced before the start of +the paragraph. This is a GNU extension. + +Effective: next paragraph. + +Default: 1. +@endDefmpreg + +@unnumberedsubsubsec Heading settings + +@Defmpreg {PSINCR, ms} +Defines an increment in type size to be applied to a heading at a +lesser depth than that specified in @code{GROWPS}. The value of +@code{PSINCR} should be specified in points with the @dmn{p} scaling +unit and may include a fractional component; for example, @w{@samp{.nr +PSINCR 1.5p}} sets a type size increment of 1.5@dmn{p}. This is a GNU +extension. + +Effective: next heading. + +Default: 1@dmn{p}. +@endDefmpreg + +@Defmpreg {GROWPS, ms} +Defines the heading depth above which the type size increment set by +@code{PSINCR} becomes effective. For each heading depth less than the +value of @code{GROWPS}, the type size is increased by @code{PSINCR}. +Setting @code{GROWPS} to any value less than@tie{}2 disables the +incremental heading size feature. This is a GNU extension. + +Effective: next heading. + +Default: 0. +@endDefmpreg + +@Defmpreg {HORPHANS, ms} +Defines the minimum number of lines of an immediately succeeding +paragraph that should be kept together with any heading introduced by +the @code{NH} or @code{SH} macros. If a heading is placed close to the +bottom of a page, and there is insufficient space to accommodate both +the heading and at least @code{HORPHANS} lines of the following +paragraph, before an automatic page break, then the page break is forced +before the heading. This is a GNU extension. + +Effective: next paragraph. + +Default: 1. +@endDefmpreg + +@Defmpstr {SN-STYLE, ms} +Defines the style used to print numbered headings. @xref{Headings in +ms}. This is a GNU extension. + +Effective: next heading. + +Default: alias of @code{SN-DOT} +@endDefmpstr + +@unnumberedsubsubsec Footnote settings + +@Defmpreg {FI, ms} +Defines the footnote indentation. This is a Berkeley extension. + +Effective: next footnote. + +Default: 2@dmn{n}. +@endDefmpreg + +@Defmpreg {FF, ms} +Defines the format of automatically numbered footnotes, +and those for which the @code{FS} request is given a marker argument, at +the bottom of a column or page. This is a Berkeley extension. +@table @code +@item 0 +Set an automatic number@footnote{defined in @ref{ms Footnotes}} as a +superscript (on typesetter devices) or surrounded by square brackets (on +terminals). The footnote paragraph is indented as with @code{PP} if +there is an @code{FS} argument or an automatic number, and as with +@code{LP} otherwise. This is the default. + +@item 1 +As @code{0}, but set the marker as regular text and follow an +automatic number with a period. + +@item 2 +As @code{1}, but without indentation (like @code{LP}). + +@item 3 +As @code{1}, but set the footnote paragraph with the marker hanging +(like @code{IP}). +@end table + +Effective: next footnote. + +Default: 0. +@endDefmpreg + +@Defmpreg {FPS, ms} +Defines the footnote type size. + +Effective: next footnote. + +Default: @code{\n[PS] - 2p}. +@endDefmpreg + +@Defmpreg {FVS, ms} +Defines the footnote vertical spacing. + +Effective: next footnote. + +Default: @code{\n[FPS] + 2p}. +@endDefmpreg + +@Defmpreg {FPD, ms} +Defines the footnote paragraph spacing. This is a GNU extension. + +Effective: next footnote. + +Default: @code{\n[PD] / 2}. +@endDefmpreg + +@Defmpstr {FR, ms} +Defines the ratio of the footnote line length to the current line +length. This is a GNU extension. + +Effective: next footnote in single-column arrangements, next page +otherwise. + +Default: @code{11/12}. +@endDefmpstr + +@unnumberedsubsubsec Display settings + +@Defmpreg {DD, ms} +Sets the display distance---the vertical spacing before and after a +display, a @code{tbl} table, an @code{eqn} equation, or a @code{pic} +image. This is a Berkeley extension. + +Effective: next display boundary. + +Default: 0.5@dmn{v} (1@dmn{v} on low-resolution devices). +@endDefmpreg + +@Defmpreg {DI, ms} +Sets the default amount by which to indent a display started with +@code{DS} and @code{ID} without arguments, to @samp{.DS@tie{}I} without +an indentation argument, and to equations set with @samp{.EQ@tie{}I}. +This is a GNU extension. + +Effective: next indented display. + +Default: 0.5@dmn{i}. +@endDefmpreg + +@unnumberedsubsubsec Other settings + +@Defmpreg {MINGW, ms} +Defines the default minimum width between columns in a multi-column +document. This is a GNU extension. + +Effective: next page. + +Default: 2@dmn{n}. +@endDefmpreg + +@Defmpreg {TC-MARGIN, ms} +Defines the width of the field in which page numbers are set in a table +of contents entry; the right margin thus moves inboard by this amount. +This is a GNU extension. + +Effective: next @code{PX} call. + +Default: @code{\w'000'} +@endDefmpreg + +@c XXX: Normally we'd have an entry for TC-LEADER here, but it's a +@c special character and we have no custom Texinfo macros for defining +@c (and indexing) these. There would be little point in an index for +@c one item, and the plan is to drop this entire @section from this +@c manual once doc/ms.ms is ready. See Savannah #60061. + +@c --------------------------------------------------------------------- + +@node ms Document Description Macros, ms Body Text, ms Document Control Settings, ms +@subsection Document Description Macros +@cindex @file{ms} macros, document description +@cindex document description macros, [@file{ms}] + +Only the simplest document lacks a title.@footnote{Distinguish a +document title from ``titles'', which are what @code{roff} systems call +headers and footers collectively.} As its level of sophistication (or +complexity) increases, it tends to acquire a date of revision, +explicitly identified authors, sponsoring institutions for authors, and, +at the rarefied heights, an abstract of its content. Define these +data by calling the macros below in the order shown; @code{DA} or +@code{ND} can be called to set the document date (or other identifier) +at any time before (a) the abstract, if present, or (b) its information +is required in a header or footer. Use of these macros is optional, +except that @code{TL} is mandatory if any of @code{RP}, @code{AU}, +@code{AI}, or @code{AB} is called, and @code{AE} is mandatory if +@code{AB} is called. + +@Defmac {RP, [@code{no-repeat-info}] [@code{no-renumber}], ms} +Use the ``report'' (@acronym{AT&T}: ``released paper'') format for your +document, creating a separate cover page. The default arrangement is to +place most of the document description (title, author names and +institutions, and abstract, but not the date) at the top of the first +page. If the optional @code{no-repeat-info} argument is given, +@file{ms} produces a cover page but does not repeat any of its +information subsequently (but see the @code{DA} macro below regarding +the date). Normally, @code{RP} sets the page number following the cover +page to@tie{}1. Specifying the optional @code{no-renumber} argument +suppresses this alteration. Optional arguments can occur in any order. +@code{no} is recognized as a synonym of @code{no-repeat-info} for +@code{AT&T} compatibility. +@endDefmac + +@Defmac {TL, , ms} +Specify the document title. @file{ms} collects text on input lines +following this call into the title until reaching @code{AU}, @code{AB}, +or a heading or paragraphing macro call. +@endDefmac + +@Defmac {AU, , ms} +Specify an author's name. @file{ms} collects text on input lines +following this call into the author's name until reaching @code{AI}, +@code{AB}, another @code{AU}, or a heading or paragraphing macro call. +Call it repeatedly to specify multiple authors. +@endDefmac + +@Defmac {AI, , ms} +Specify the preceding author's institution. An @code{AU} call is +usefully followed by at most one @code{AI} call; if there are more, the +last @code{AI} call controls. @file{ms} collects text on input lines +following this call into the author's institution until reaching +@code{AU}, @code{AB}, or a heading or paragraphing macro call. +@endDefmac + +@Defmac {DA, [@Var{x} @dots{}], ms} +Typeset the current date, or any arguments @var{x}, in the center +footer, and, if @code{RP} is also called, left-aligned at the end of the +description information on the cover page. +@endDefmac + +@Defmac {ND, [@Var{x} @dots{}], ms} +Typeset the current date, or any arguments @var{x}, if @code{RP} is also +called, left-aligned at the end of the document description on the cover +page. This is @code{groff} @file{ms}'s default. +@endDefmac + +@Defmac {AB, [@code{no}], ms} +Begin the abstract. @file{ms} collects text on input lines following +this call into the abstract until reaching an @code{AE} call. By +default, @file{ms} places the word ``ABSTRACT'' centered and in italics +above the text of the abstract. The optional argument @code{no} +suppresses this heading. +@endDefmac + +@Defmac {AE, , ms} +End the abstract. +@endDefmac + +An example document description, using a cover page, follows. +@cindex cover page in [@file{ms}], example markup +@cindex example markup, cover page in [@file{ms}] + +@CartoucheExample +.RP +.TL +The Inevitability of Code Bloat +in Commercial and Free Software +.AU +J.\& Random Luser +.AI +University of West Bumblefuzz +.AB +This report examines the long-term growth of the code +bases in two large, +popular software packages; +the free Emacs and the commercial Microsoft Word. +While differences appear in the type or order of +features added, +due to the different methodologies used, +the results are the same in the end. +.PP +The free software approach is shown to be superior in +that while free software can become as bloated as +commercial offerings, +free software tends to have fewer serious bugs and the +added features are more in line with user demand. +.AE + +@r{@dots{}the rest of the paper@dots{}} +@endCartoucheExample + +@c --------------------------------------------------------------------- + +@node ms Body Text, ms Page Layout, ms Document Description Macros, ms +@subsection Body Text +@cindex @file{ms} macros, body text + +A variety of macros, registers, and strings can be used to structure and +style the body of your document. They organize your text into +paragraphs, headings, footnotes, and inclusions of material such as +tables and figures. + +@menu +* Text settings in ms:: +* Typographical symbols in ms:: +* Paragraphs in ms:: +* Headings in ms:: +* Typeface and decoration:: +* Lists in ms:: +* Indented regions in ms:: +* ms keeps and displays:: +* ms Insertions:: +* ms Footnotes:: +* ms language and localization:: +@end menu + +@c --------------------------------------------------------------------- + +@node Text settings in ms, Typographical symbols in ms, ms Body Text, ms Body Text +@subsubsection Text settings +@cindex @file{ms} macros, text settings + +The @code{FAM} string, a GNU extension, sets the font family for body +text; the default is @samp{T}. The @code{PS} and @code{VS} registers +set the type size and vertical spacing (distance between text +baselines), respectively. The font family and type size are ignored on +terminal devices. Setting these parameters before the first call of a +heading, paragraphing, or (non-date) document description macro also +applies them to headers, footers, and (for @code{FAM}) footnotes. + +Which font families are available depends on the output device; as a +convention, @code{T} selects a serif family (``Times''), @code{H} a +sans-serif family (``Helvetica''), and @code{C} a monospaced family +(``Courier''). The man page for the output driver documents its font +repertoire. Consult the @cite{groff@r{(1)}} man page for lists of +available output devices and their drivers. + +The hyphenation mode (as used by the @code{hy} request) is set from the +@code{HY} register. Setting @code{HY} to @samp{0} is equivalent to +using the @code{nh} request. This is a Tenth Edition Research Unix +extension. + +@c --------------------------------------------------------------------- + +@node Typographical symbols in ms, Paragraphs in ms, Text settings in ms, ms Body Text +@subsubsection Typographical symbols +@cindex @file{ms} macros, obtaining typographical symbols + +@file{ms} provides a few strings to obtain typographical symbols not +easily entered with the keyboard. These and many others are available +as special character escape sequences---see the @cite{groff_char@r{(7)}} +man page. + +@Defmpstr {-, ms} +Interpolate an em dash. +@endDefmpstr + +@DefmpstrList {Q, ms} +@DefmpstrListEndx {U, ms} +Interpolate typographer's quotation marks where available, and neutral +double quotes otherwise. @code{\*Q} is the left quote and @code{\*U} +the right. +@endDefmpstr + +@c --------------------------------------------------------------------- + +@node Paragraphs in ms, Headings in ms, Typographical symbols in ms, ms Body Text +@subsubsection Paragraphs +@cindex @file{ms} macros, paragraph handling + +Paragraphing macros @dfn{break}, or terminate, any pending output line +so that a new paragraph can begin. Several paragraph types are +available, differing in how indentation applies to them: to left, right, +or both margins; to the first output line of the paragraph, all output +lines, or all but the first. All paragraphing macro calls cause the +insertion of vertical space in the amount stored in the @code{PD} +register, except at page or column breaks. Alternatively, a blank input +line breaks the output line and vertically spaces by one vee. + +@Defmac {LP, , ms} +Set a paragraph without any (additional) indentation. +@endDefmac + +@Defmac {PP, , ms} +Set a paragraph with a first-line left indentation in the amount stored +in the @code{PI} register. +@endDefmac + +@Defmac {IP, [@Var{marker} [@Var{width}]], ms} +Set a paragraph with a left indentation. The optional @var{marker} is +not indented and is empty by default. It has several applications; +see @ref{Lists in ms}. @var{width} overrides the indentation amount +stored in the @code{PI} register; its default unit is @samp{n}. Once +specified, @var{width} applies to further @code{IP} calls until +specified again or a heading or different paragraphing macro is called. +@endDefmac + +@Defmac {QP, , ms} +Set a paragraph indented from both left and right margins by the amount +stored in the @code{QI} register. +@endDefmac + +@DefmacList {QS, , ms} +@DefmacListEndx {QE, , ms} +Begin (@code{QS}) and end (@code{QE}) a region where each paragraph is +indented from both margins by the amount stored in the @code{QI} +register. The text between @code{QS} and @code{QE} can be structured +further by use of other paragraphing macros. +@endDefmac + +@Defmac {XP, , ms} +Set an ``exdented'' paragraph---one with a left indentation in the +amount stored in the @code{PI} register on every line @emph{except} the +first (also known as a hanging indent). This is a Berkeley extension. +@endDefmac + +The following example illustrates the use of paragraphing macros. + +@CartoucheExample +.NH 2 +Cases used in the 2001 study +.LP +Two software releases were considered for this report. +.PP +The first is commercial software; +the second is free. +.IP \[bu] +Microsoft Word for Windows, +starting with version 1.0 through the current version +(Word 2000). +.IP \[bu] +GNU Emacs, +from its first appearance as a standalone editor through +the current version (v20). +See [Bloggs 2002] for details. +.QP +Franklin's Law applied to software: +software expands to outgrow both RAM and disk space over +time. +.SH +Bibliography +.XP +Bloggs, Joseph R., +.I "Everyone's a Critic" , +Underground Press, March 2002. +A definitive work that answers all questions and +criticisms about the quality and usability of free +software. +@endCartoucheExample + +@c --------------------------------------------------------------------- + +@node Headings in ms, Typeface and decoration, Paragraphs in ms, ms Body Text +@subsubsection Headings +@cindex @file{ms} macros, headings + +Use headings to create a sequential or hierarchical structure for your +document. The @file{ms} macros print headings in @strong{bold} using +the same font family and, by default, type size as the body text. +Headings are available with and without automatic numbering. Text on +input lines following the macro call becomes the heading's title. Call +a paragraphing macro to end the heading text and start the section's +content. + +@DefmacList {NH, [@Var{depth}], ms} +@DefmacListEnd {NH, @t{S} @Var{heading-depth-index} @dots{}, ms} +Set an automatically numbered heading. + +@file{ms} produces a numbered heading the form @var{a.b.c@dots{}}, to +any depth desired, with the numbering of each depth increasing +automatically and being reset to zero when a more significant level is +increased. ``1''@tie{}is the most significant or coarsest division of +the document. Only non-zero values are output. If @var{depth} is +omitted, it is taken to be @samp{1}. + +If you specify @var{depth} such that an ascending gap occurs relative to +the previous @code{NH} call---that is, you ``skip a depth'', as by +@samp{.NH 1} and then @samp{.NH 3}---@code{groff} @file{ms} emits a +warning on the standard error stream. + +Alternatively, you can give @code{NH} a first argument of@tie{}@code{S}, +followed by integers to number the heading depths explicitly. Further +automatic numbering, if used, resumes using the specified indices as +their predecessors. +@c Although undocumented in Tuthill's 4.2BSD ms.diffs paper... +This feature is a Berkeley extension. +@endDefmac + +An example may be illustrative. + +@CartoucheExample +.NH 1 +Animalia +.NH 2 +Arthropoda +.NH 3 +Crustacea +.NH 2 +Chordata +.NH S 6 6 6 +Daimonia +.NH 1 +Plantae +@endCartoucheExample + +The above results in numbering as follows; the vertical space that +normally precedes each heading is omitted. + +@Example +1. Animalia +1.1. Arthropoda +1.1.1. Crustacea +1.2. Chordata +6.6.6. Daimonia +7. Plantae +@endExample + +@DefmpstrList {SN-STYLE, ms} +@DefmpstrItemx {SN-DOT, ms} +@DefmpstrItemx {SN-NO-DOT, ms} +@DefmpstrListEndx {SN, ms} +After @code{NH} is called, the assigned number is made available in the +strings @code{SN-DOT} (as it appears in a printed heading with default +formatting, followed by a terminating period) and @code{SN-NO-DOT} (with +the terminating period omitted). These are GNU extensions. + +You can control the style used to print numbered headings by defining an +appropriate alias for the string @code{SN-STYLE}. By default, +@code{SN-STYLE} is aliased to @code{SN-DOT}. If you prefer to omit the +terminating period from numbers appearing in numbered headings, you may +define the alias as follows. + +@Example +.als SN-STYLE SN-NO-DOT +@endExample + +@noindent +Any such change in numbering style becomes effective from the next use +of @code{NH} following redefinition of the alias for @code{SN-STYLE}. +The formatted number of the current heading is available in the +@code{SN} string (a feature first documented by Berkeley), which +facilitates its inclusion in, for example, table captions, equation +labels, and @code{XS}/@code{XA}/@code{XE} table of contents entries. +@endDefmpstr + +@Defmac {SH, [@Var{depth}], ms} +Set an unnumbered heading. + +The optional @var{depth} argument is a GNU extension indicating the +heading depth corresponding to the @var{depth} argument of @code{NH}. +It matches the type size at which the heading is set to that of a +numbered heading at the same depth when the @code{GROWPS} and +@code{PSINCR} heading size adjustment mechanism is in effect. +@endDefmac + +If the @code{GROWPS} register is set to a value greater than the +@var{level} argument to @code{NH} or @code{SH}, the type size of a +heading produced by these macros increases by @code{PSINCR} units over +the size specified by @code{PS} multiplied by the difference of +@code{GROWPS} and @var{level}. The value stored in @code{PSINCR} is +interpreted in @code{groff} basic units; the @code{p} scaling unit +should be employed when assigning a value specified in points. For +example, the sequence + +@CartoucheExample +.nr PS 10 +.nr GROWPS 3 +.nr PSINCR 1.5p +.NH 1 +Carnivora +.NH 2 +Felinae +.NH 3 +Felis catus +.SH 2 +Machairodontinae +@endCartoucheExample + +@noindent +will cause ``1. Carnivora'' to be printed in 13-point text, followed by +``1.1. Felinae'' in 11.5-point text, while ``1.1.1. Felis catus'' and +all more deeply nested heading levels will remain in the 10-point text +specified by the @code{PS} register. ``Machairodontinae'' is printed at +11.5 points, since it corresponds to heading level@tie{}2. + +The @code{HORPHANS} register operates in conjunction with the @code{NH} +and @code{SH} macros to inhibit the printing of isolated headings at the +bottom of a page; it specifies the minimum number of lines of an +immediately subsequent paragraph that must be kept on the same page as +the heading. If insufficient space remains on the current page to +accommodate the heading and this number of lines of paragraph text, a +page break is forced before the heading is printed. Any display macro +call or @code{tbl}, @code{pic}, or @code{eqn} region between the heading +and the subsequent paragraph suppresses this grouping. @xref{ms keeps +and displays} and @ref{ms Insertions}. + +@c --------------------------------------------------------------------- + +@node Typeface and decoration, Lists in ms, Headings in ms, ms Body Text +@subsubsection Typeface and decoration + +The @file{ms} macros provide a variety of ways to style text. +Attend closely to the ordering of arguments labeled @var{pre} and +@var{post}, which is not intuitive. Support for @var{pre} +arguments is a GNU extension.@footnote{This idiosyncrasy arose through +feature accretion; for example, the @code{B} macro in Version@tie{}6 +Unix @file{ms} (1975) accepted only one argument, the text to be set in +boldface. By Version@tie{}7 (1979) it recognized a second argument; in +1990, @code{groff} @file{ms} added a ``pre'' argument, placing it third +to avoid breaking support for older documents.} + +@Defmac {B, [@Var{text} [@Var{post} [@Var{pre}]]], ms} +Style @var{text} in @b{bold}, followed by @var{post} in the previous +font style without intervening space, and preceded by @var{pre} +similarly. Without arguments, @file{ms} styles subsequent text in bold +until the next paragraphing, heading, or no-argument typeface macro +call. +@endDefmac + +@Defmac {R, [@Var{text} [@Var{post} [@Var{pre}]]], ms} +As @code{B}, but use the roman style (upright text of normal weight) +instead of bold. Argument recognition is a GNU extension. +@endDefmac + +@Defmac {I, [@Var{text} [@Var{post} [@Var{pre}]]], ms} +As @code{B}, but use an @i{italic} or oblique style instead of bold. +@endDefmac + +@Defmac {BI, [@Var{text} [@Var{post} [@Var{pre}]]], ms} +As @code{B}, but use a bold italic or bold oblique style instead of +upright bold. This is a Tenth Edition Research Unix extension. +@c possibly 9th, but definitely not Berkeley +@endDefmac + +@Defmac {CW, [@Var{text} [@Var{post} [@Var{pre}]]], ms} +As @code{B}, but use a @t{constant-width} (monospaced) roman typeface +instead of bold. This is a Tenth Edition Research Unix extension. +@c possibly 9th, but definitely not Berkeley +@endDefmac + +@Defmac {BX, [@Var{text}], ms} +Typeset @var{text} and draw a box around it. On terminal devices, +reverse video is used instead. If you want @var{text} to contain space, +use unbreakable space or horizontal motion escape sequences (@code{\~}, +@code{\@key{SP}}, @code{\^}, @code{\|}, @code{\0} or @code{\h}). +@endDefmac + +@Defmac {UL, [@Var{text} [@Var{post}]], ms} +Typeset @var{text} with an underline. @var{post}, if present, is set +after @var{text} with no intervening space. +@endDefmac + +@Defmac {LG, , ms} +Set subsequent text in larger type (two points larger than the +current size) until the next type size, paragraphing, or heading macro +call. You can specify this macro multiple times to enlarge the type +size as needed. +@endDefmac + +@Defmac {SM, , ms} +Set subsequent text in smaller type (two points smaller than the current +size) until the next type size, paragraphing, or heading macro call. +You can specify this macro multiple times to reduce the type size as +needed. +@endDefmac + +@Defmac {NL, , ms} +Set subsequent text at the normal type size (the amount in the @code{PS} +register). +@endDefmac + +@var{pre} and @var{post} arguments are typically used to simplify the +attachment of punctuation to styled words. When @var{pre} is used, +a hyphenation control escape sequence @code{\%} that would ordinarily +start @var{text} must start @var{pre} instead to have the desired +effect. + +@CartoucheExample +The CS course's students found one C language keyword +.CW static ) \%( +most troublesome. +@endCartoucheExample + +The foregoing example produces output as follows. + +@CartoucheExample +@r{The CS course's students found one C language keyword (@t{static}) +most troublesome.} +@endCartoucheExample + +You can use the output line continuation escape sequence @code{\c} to +achieve the same result (@pxref{Line Continuation}). It is also +portable to older @file{ms} implementations. + +@CartoucheExample +The CS course's students found one C language keyword +\%(\c +.CW \%static ) +most troublesome. +@endCartoucheExample + +@code{groff} @file{ms} also offers strings to begin and end super- and +subscripting. These are GNU extensions. + +@DefmpstrList {@lbracechar{}, ms} +@DefmpstrListEndx {@rbracechar{}, ms} +Begin and end superscripting, respectively. +@endDefmpstr + +@DefmpstrList {<, ms} +@DefmpstrListEndx {>, ms} +Begin and end subscripting, respectively. +@endDefmpstr + +Rather than calling the @code{CW} macro, in @code{groff} @file{ms} you +might prefer to change the font family to Courier by setting the +@code{FAM} string to @samp{C}. You can then use all four style macros +above, returning to the default family (Times) with @samp{.ds FAM T}. +Because changes to @code{FAM} take effect only at the next paragraph, +@code{CW} remains useful to ``inline'' a change to the font family, +similarly to the practice of this document in noting syntactical +elements of @file{ms} and @code{groff}. + +@c --------------------------------------------------------------------- + +@node Lists in ms, Indented regions in ms, Typeface and decoration, ms Body Text +@subsubsection Lists +@cindex @file{ms} macros, lists + +The @var{marker} argument to the @code{IP} macro can be employed to +present a variety of lists; for instance, you can use a bullet glyph +(@code{\[bu]}) for unordered lists, a number (or auto-incrementing +register) for numbered lists, or a word or phrase for glossary-style or +definition lists. If you set the paragraph indentation register +@code{PI} before calling @code{IP}, you can later reorder the items in +the list without having to ensure that a @var{width} argument remains +affixed to the first call. + +The following is an example of a bulleted list. +@cindex example markup, bulleted list [@file{ms}] +@cindex bulleted list, example markup [@file{ms}] + +@CartoucheExample +.nr PI 2n +A bulleted list: +.IP \[bu] +lawyers +.IP \[bu] +guns +.IP \[bu] +money +@endCartoucheExample + +@Example +A bulleted list: + +@bullet{} lawyers + +@bullet{} guns + +@bullet{} money +@endExample + +The following is an example of a numbered list. +@cindex example markup, numbered list [@file{ms}] +@cindex numbered list, example markup [@file{ms}] + +@CartoucheExample +.nr step 0 1 +.nr PI 3n +A numbered list: +.IP \n+[step] +lawyers +.IP \n+[step] +guns +.IP \n+[step] +money +@endCartoucheExample + +@Example +A numbered list: + +1. lawyers + +2. guns + +3. money +@endExample + +Here we have employed the @code{nr} request to create a register of our +own, @samp{step}. We initialized it to zero and assigned it an +auto-increment of 1. Each time we use the escape sequence +@samp{\n+[PI]} (note the plus sign), the formatter applies the increment +just before interpolating the register's value. Preparing the @code{PI} +register as well enables us to rearrange the list without the tedium of +updating macro calls. + +The next example illustrates a glossary-style list. +@cindex example markup, glossary-style list [@file{ms}] +@cindex glossary-style list, example markup [@file{ms}] + +@CartoucheExample +A glossary-style list: +.IP lawyers 0.4i +Two or more attorneys. +.IP guns +Firearms, +preferably large-caliber. +.IP money +Gotta pay for those +lawyers and guns! +@endCartoucheExample + +@Example +A glossary-style list: + +lawyers + Two or more attorneys. + +guns Firearms, preferably large-caliber. + +money + Gotta pay for those lawyers and guns! +@endExample + +In the previous example, observe how the @code{IP} macro places the +definition on the same line as the term if it has enough space. If this +is not what you want, there are a few workarounds we will illustrate by +modifying the example. First, you can use a @code{br} request to force +a break after printing the term or label. + +@CartoucheExample +.IP guns +.br +Firearms, +@endCartoucheExample + +Second, you could apply the @code{\p} escape sequence to force a break. +The space following the escape sequence is important; if you omit it, +@code{groff} prints the first word of the paragraph text on the same +line as the term or label (if it fits) @emph{then} breaks the line. + +@CartoucheExample +.IP guns +\p Firearms, +@endCartoucheExample + +Finally, you may append a horizontal motion to the marker with the +@code{\h} escape sequence; using the same amount as the indentation will +ensure that the marker is too wide for @code{groff} to treat it as +``fitting'' on the same line as the paragraph text. + +@CartoucheExample +.IP guns\h'0.4i' +Firearms, +@endCartoucheExample + +In each case, the result is the same. + +@Example +A glossary-style list: + +lawyers + Two or more attorneys. + +guns + Firearms, preferably large-caliber. + +money + Gotta pay for those lawyers and guns! +@endExample + +@c --------------------------------------------------------------------- + +@node Indented regions in ms, ms keeps and displays, Lists in ms, ms Body Text +@subsubsection Indented regions + +You may need to indent a region of text while otherwise formatting it +normally. Indented regions can be nested; you can change @code{\n[PI]} +before each call to vary the amount of inset. + +@Defmac {RS, , ms} +Begin a region where headings, paragraphs, and displays are indented +(further) by the amount stored in the @code{PI} register. +@endDefmac + +@Defmac {RE, , ms} +End the (next) most recent indented region. +@endDefmac + +This feature enables you to easily line up text under hanging and +indented paragraphs. +@cindex @file{ms} macros, nested lists +@cindex nested lists [@file{ms}] +For example, you may wish to structure lists hierarchically. + +@CartoucheExample +.IP \[bu] 2 +Lawyers: +.RS +.IP \[bu] +Dewey, +.IP \[bu] +Cheatham, +and +.IP \[bu] +and Howe. +.RE +.IP \[bu] +Guns +@endCartoucheExample + +@Example +@bullet{} Lawyers: + + @bullet{} Dewey, + + @bullet{} Cheatham, and + + @bullet{} Howe. + +@bullet{} Guns +@endExample + +@c --------------------------------------------------------------------- + +@node ms keeps and displays, ms Insertions, Indented regions in ms, ms Body Text +@subsubsection Keeps, boxed keeps, and displays +@cindex @file{ms} macros, displays +@cindex @file{ms} macros, keeps +@cindex keeps [@file{ms}] + +On occasion, you may want to @dfn{keep} several lines of text, or a +region of a document, together on a single page, preventing an automatic +page break within certain boundaries. This can cause a page break to +occur earlier than it normally would. For example, you may want to keep +two paragraphs together, or a paragraph that refers to a table, list, or +figure adjacent to the item it discusses. @file{ms} provides the +@code{KS} and @code{KE} macros for this purpose. + +You can alternatively specify a @dfn{floating keep}:@: if a keep cannot +fit on the current page, @file{ms} holds its contents and +allows material following the keep (in the source document) to fill the +remainder of the current page. When the page breaks, whether by +reaching the end or @code{bp} request, @file{ms} puts the floating keep +at the beginning of the next page. This is useful for placing large +graphics or tables that do not need to appear exactly where they occur +in the source document. + +@DefmacList {KS, , ms} +@DefmacItemx {KF, , ms} +@DefmacListEndx {KE, , ms} +@code{KS} begins a keep, @code{KF} a floating keep, and @code{KE} ends a +keep of either kind. +@endDefmac + +As an alternative to the keep mechanism, the @code{ne} request forces a +page break if there is not at least the amount of vertical space +specified in its argument remaining on the page (@pxref{Page Control}). +One application of @code{ne} is to reserve space on the page for a +figure or illustration to be included later. + +@cindex boxes [@file{ms}] +A @dfn{boxed keep} has a frame drawn around it. + +@DefmacList {B1, , ms} +@DefmacListEndx {B2, , ms} +@code{B1} begins a keep with a box drawn around it. @code{B2} ends a +boxed keep. +@endDefmac + +Boxed keep macros cause breaks; if you need to box a word or phrase +within a line, see the @code{BX} macro in @ref{Typeface and decoration}. +Box lines are drawn as close as possible to the text they enclose so +that they are usable within paragraphs. If you wish to box one or more +paragraphs, you may improve the appearance by calling @code{B1} after +the first paragraphing macro, and by adding a small amount of vertical +space before calling @code{B2}. + +@c Wrap example at 58 columns. +@CartoucheExample +.LP +.B1 +.I Warning: +Happy Fun Ball may suddenly accelerate to dangerous +speeds. +.sp \n[PD]/2 \" space by half the inter-paragraph distance +.B2 +@endCartoucheExample + +If you want a boxed keep to float, you will need to enclose the +@code{B1} and @code{B2} calls within a pair of @code{KF} and @code{KE} +calls. + +@cindex displays [@file{ms}] +@dfn{Displays} turn off filling; lines of verse or program code are +shown with their lines broken as in the source document without +requiring @code{br} requests between lines. Displays can be kept on a +single page or allowed to break across pages. The @code{DS} macro +begins a kept display of the layout specified in its first argument; +non-kept displays are begun with dedicated macros corresponding to their +layout. + +@DefmacList {DS, @t{L}, ms} +@DefmacListEndx {LD, , ms} +Begin (@code{DS}:@: kept) left-aligned display. +@endDefmac + +@DefmacList {DS, [@t{I} [@Var{indent}]], ms} +@DefmacListEndx {ID, [@Var{indent}], ms} +Begin (@code{DS}:@: kept) display indented by @var{indent} if specified, +and by the amount of the @code{DI} register otherwise. +@endDefmac + +@DefmacList {DS, @t{B}, ms} +@DefmacListEndx {BD, , ms} +Begin a (@code{DS}:@: kept) a block display:@: the entire display is +left-aligned, but indented such that the longest line in the display +is centered on the page. +@endDefmac + +@DefmacList {DS, @t{C}, ms} +@DefmacListEndx {CD, , ms} +Begin a (@code{DS}:@: kept) centered display:@: each line in the display +is centered. +@endDefmac + +@DefmacList {DS, @t{R}, ms} +@DefmacListEndx {RD, , ms} +Begin a (@code{DS}:@: kept) right-aligned display. This is a GNU +extension. +@endDefmac + +@Defmac {DE, , ms} +End any display. +@endDefmac + +The distance stored in the @code{DD} register is inserted before and +after each pair of display macros; this is a Berkeley extension. In +@code{groff} @file{ms}, this distance replaces any adjacent +inter-paragraph distance or subsequent spacing prior to a section +heading. The @code{DI} register is a GNU extension; its value is an +indentation applied to displays created with @samp{.DS} and @samp{.ID} +without arguments, to @samp{.DS I} without an indentation argument, and +to indented equations set with @samp{.EQ}. Changes to either register +take effect at the next display boundary. + +@c --------------------------------------------------------------------- + +@node ms Insertions, ms Footnotes, ms keeps and displays, ms Body Text +@subsubsection Tables, figures, equations, and references +@cindex @file{ms} macros, tables +@cindex @file{ms} macros, figures +@cindex @file{ms} macros, equations +@cindex @file{ms} macros, references +@cindex tables [@file{ms}] +@cindex figures [@file{ms}] +@cindex equations [@file{ms}] +@cindex references [@file{ms}] + +The @file{ms} package is often used with the @code{tbl}, @code{pic}, +@code{eqn}, and @code{refer} preprocessors. +@pindex tbl +@pindex pic +@pindex eqn +@pindex refer +Mark text meant for preprocessors by enclosing it in pairs of tokens +as follows, with nothing between the dot and the macro name. The +preprocessors match these tokens only at the start of an input line. + +@DefmacList {TS, [@code{H}], ms} +@DefmacListEndx {TE, , ms} +Demarcate a table to be processed by the @code{tbl} preprocessor. The +optional argument@tie{}@code{H} to @code{TS} instructs @file{ms} to +repeat table rows (often column headings) at the top of each new page +the table spans, if applicable; calling the @code{TH} macro marks the +end of such rows. The GNU @cite{tbl@r{(1)}} man page provides a +comprehensive reference to the preprocessor and offers examples of its +use. +@endDefmac + +@DefmacList {PS, , ms} +@DefmacItemx {PE, , ms} +@DefmacListEndx {PF, , ms} +@code{PS} begins a picture to be processed by the @command{gpic} +preprocessor; either of @code{PE} or @code{PF} ends it, the latter with +``flyback'' to the vertical position at its top. You can create +@code{pic} input manually or with a program such as @code{xfig}. +@endDefmac + +@DefmacList {EQ, [@Var{align} [@Var{label}]], ms} +@DefmacListEndx {EN, , ms} +Demarcate an equation to be processed by the @code{eqn} preprocessor. +The equation is centered by default; @var{align} can be @samp{C}, +@samp{L}, or @samp{I} to (explicitly) center, left-align, or indent it +by the amount stored in the @code{DI} register, respectively. If +specified, @var{label} is set right-aligned. +@endDefmac + +@DefmacList {[, , ms} +@DefmacListEndx {], , ms} +Demarcate a bibliographic citation to be processed by the @code{refer} +preprocessor. The GNU @cite{refer@r{(1)}} man page provides a +comprehensive reference to the preprocessor and the format of its +bibliographic database. Type @samp{man refer} at the command line to +view it. +@endDefmac + +When @code{refer} emits collected references (as might be done on a +``Works Cited'' page), it interpolates the @code{REFERENCES} string as +an unnumbered heading (@code{SH}). + +@cindex table, multi-page, example [@file{ms}] +@cindex multi-page table example [@file{ms}] +The following is an example of how to set up a table that may print +across two or more pages. + +@CartoucheExample +.TS H +allbox; +Cb | Cb . +Part@arrow{}Description +_ +.TH +.T& +GH-1978@arrow{}Fribulating gonkulator +@r{@dots{}the rest of the table follows@dots{}} +.TE +@endCartoucheExample + +@noindent +Attempting to place a multi-page table inside a keep can lead to +unpleasant results, particularly if the @code{tbl} @code{allbox} option +is used. + +@cindex equation example [@file{ms}] +Mathematics can be typeset using the language of the @code{eqn} +preprocessor. + +@CartoucheExample +.EQ C (\*[SN-NO-DOT]a) +p ~ = ~ q sqrt @{ ( 1 + ~ ( x / q sup 2 ) @} +.EN +@endCartoucheExample + +@noindent +This input formats a labelled equation. We used the @code{SN-NO-DOT} +string to base the equation label on the current heading number, giving +us more flexibility to reorganize the document. + +Use @command{groff} options to run preprocessors on the input:@: +@option{-e} for @command{geqn}, @option{-p} for @command{gpic}, +@option{-R} for @command{grefer}, and @option{-t} for @command{gtbl}. + +@c --------------------------------------------------------------------- + +@node ms Footnotes, , ms Insertions, ms Body Text +@subsubsection Footnotes +@cindex @file{ms} macros, footnotes +@cindex footnotes [@file{ms}] + +@cindex footnote marker [@file{ms}] +@cindex marker, footnote [@file{ms}] +A footnote is typically anchored to a place in the text with a +@dfn{marker}, which is a small integer, a symbol such as a dagger, or +arbitrary user-specified text. + +@Defmpstr {*, ms} +Place an @dfn{automatic number}, an automatically generated numeric +footnote marker, in the text. Each time this string is interpolated, +the number it produces increments by one. Automatic numbers start at 1. +This is a Berkeley extension. +@endDefesc + +Enclose the footnote text in @code{FS} and @code{FE} macro calls to set +it at the nearest available ``foot'', or bottom, of a text column or +page. + +@DefmacList {FS, [@Var{marker}], ms} +@DefmacListEndx {FE, , ms} +Begin (@code{FS}) and end (@code{FE}) a footnote. @code{FS} calls +@code{FS-MARK} with any supplied @var{marker} argument, which is then +also placed at the beginning of the footnote text. If @var{marker} is +omitted, the next pending automatic footnote number enqueued by +interpolation of the @code{*} string is used, and if none exists, +nothing is prefixed. +@endDefmac + +You may not desire automatically numbered footnotes in spite of their +convenience. You can indicate a footnote with a symbol or other text by +specifying its marker at the appropriate place (for example, by using +@code{\[dg]} for the dagger glyph) @emph{and} as an argument to the +@code{FS} macro. Such manual marks should be repeated as arguments to +@code{FS} or as part of the footnote text to disambiguate their +correspondence. You may wish to use @code{\*@{} and @code{\*@}} to +superscript the marker at the anchor point, in the footnote text, or +both. + +@code{groff} @file{ms} provides a hook macro, @code{FS-MARK}, for +user-determined operations to be performed when the @code{FS} macro is +called. It is passed the same arguments as @code{FS} itself. An +application of @code{FS-MARK} is anchor placement for a hyperlink +reference, so that a footnote can link back to its referential +context.@footnote{``Portable Document Format Publishing with GNU +Troff'', @file{pdfmark.ms} in the @code{groff} distribution, uses this +technique.} By default, this macro has an empty definition. +@code{FS-MARK} is a GNU extension. + +@cindex footnotes, and keeps [@file{ms}] +@cindex keeps, and footnotes [@file{ms}] +@cindex footnotes, and displays [@file{ms}] +@cindex displays, and footnotes [@file{ms}] +Footnotes can be safely used within keeps and displays, but you should +avoid using automatically numbered footnotes within floating keeps. You +can place a second @code{\**} interpolation between a @code{\**} and its +corresponding @code{FS} call as long as each @code{FS} call occurs +@emph{after} the corresponding @code{\**} and occurrences of @code{FS} +are in the same order as corresponding occurrences of @code{\**}. + +Footnote text is formatted as paragraphs are, using analogous +parameters. The registers @code{FI}, @code{FPD}, @code{FPS}, and +@code{FVS} correspond to @code{PI}, @code{PD}, @code{PS}, and @code{CS}, +respectively; @code{FPD}, @code{FPS}, and @code{FVS} are GNU extensions. + +The @code{FF} register controls the formatting of automatically numbered +footnote paragraphs and those for which @code{FS} is given a marker +argument. @xref{ms Document Control Settings}. + +The default footnote line length is 11/12ths of the normal line length +for compatibility with the expectations of historical @file{ms} +documents; you may wish to set the @code{FR} string to @samp{1} to align +with contemporary typesetting practices. In the +past,@footnote{Unix Version@tie{}7 @file{ms}, its descendants, and GNU +@file{ms} prior to @code{groff} version 1.23.0} an @code{FL} register +was used for the line length in footnotes; however, setting this +register at document initialization time had no effect on the footnote +line length in multi-column arrangements.@footnote{You could reset it +after each call to @code{.1C}, @code{.2C}, or @code{.MC}.} + +@code{FR} should be used in preference to the old @code{FL} register in +contemporary documents. The footnote line length is effectively +computed as @samp{@slanted{column-width} * \*[FR]}. If an absolute +footnote line length is required, recall that arithmetic expressions in +@code{roff} input are evaluated strictly from left to right, with no +operator precedence (parentheses are honored). + +@Example +.ds FR 0+3i \" Set footnote line length to 3 inches. +@endExample + +@c --------------------------------------------------------------------- + +@node ms language and localization, ms Page Layout, ms Footnotes, ms Body Text +@subsubsection Language and localization +@cindex @file{ms} macros, language +@cindex @file{ms} macros, localization +@cindex language [@file{ms}] +@cindex localization [@file{ms}] + +@code{groff} @file{ms} provides several strings that you can customize +for your own purposes, or redefine to adapt the macro package to +languages other than English. It is already localized for +@c cs, de, fr, it, sv +Czech, German, French, Italian, and Swedish. Load the desired +localization macro package after @file{ms}; see the +@cite{groff_tmac@r{(5)}} man page. + +@CartoucheExample +$ groff -ms -mfr bienvenue.ms +@endCartoucheExample + +The following strings are available. + +@Defmpstr {REFERENCES, ms} +Contains the string printed at the beginning of a references +(bibliography) page produced with GNU @cite{refer@r{(1)}}. The default +is @samp{References}. +@c XXX: Use of refer(1) with ms is insufficiently documented. +@endDefmpstr + +@Defmpstr {ABSTRACT, ms} +Contains the string printed at the beginning of the abstract. The +default is @samp{\f[I]ABSTRACT\f[]}; it includes font selection escape +sequences to set the word in italics. +@endDefmpstr + +@Defmpstr {TOC, ms} +Contains the string printed at the beginning of the table of contents. +The default is @samp{Table of Contents}. +@endDefmpstr + +@DefmpstrList {MONTH1, ms} +@DefmpstrItemx {MONTH2, ms} +@DefmpstrItemx {MONTH3, ms} +@DefmpstrItemx {MONTH4, ms} +@DefmpstrItemx {MONTH5, ms} +@DefmpstrItemx {MONTH6, ms} +@DefmpstrItemx {MONTH7, ms} +@DefmpstrItemx {MONTH8, ms} +@DefmpstrItemx {MONTH9, ms} +@DefmpstrItemx {MONTH10, ms} +@DefmpstrItemx {MONTH11, ms} +@DefmpstrListEndx {MONTH12, ms} +Contain the full names of the calendar months. The defaults are in +English: @samp{January}, @samp{February}, and so on. +@endDefmpstr + +@c --------------------------------------------------------------------- + +@node ms Page Layout, Differences from AT&T ms, ms Body Text, ms +@subsection Page layout +@cindex @file{ms} macros, page layout +@cindex page layout [@file{ms}] + +@file{ms}'s default page layout arranges text in a single column with +the page number between hyphens centered in a header on each page except +the first, and produces no footers. You can customize this arrangement. + +@menu +* ms Headers and Footers:: +* Tab Stops in ms:: +* ms Margins:: +* ms Multiple Columns:: +* ms TOC:: +@end menu + +@c --------------------------------------------------------------------- + +@node ms Headers and Footers, Tab Stops in ms, ms Page Layout, ms Page Layout +@subsubsection Headers and footers +@cindex @file{ms} macros, headers +@cindex @file{ms} macros, footers +@cindex headers [@file{ms}] +@cindex footers [@file{ms}] + +There are multiple ways to produce headers and footers. One is to +define the strings @code{LH}, @code{CH}, and @code{RH} to set the left, +center, and right headers, respectively; and @code{LF}, @code{CF}, and +@code{RF} to set the left, center, and right footers. This approach +suffices for documents that do not distinguish odd- and even-numbered +pages. + +Another method is to call macros that set headers or footers for odd- or +even-numbered pages. Each such macro takes a delimited argument +separating the left, center, and right header or footer texts from each +other. You can replace the neutral apostrophes (@code{'}) shown below +with any character not appearing in the header or footer text. These +macros are Berkeley extensions. + +@DefmacList {OH, @code{'}@Var{left}@code{'}@Var{center}@code{'}@Var{right}@code{'}, ms} +@DefmacItemx {EH, @code{'}@Var{left}@code{'}@Var{center}@code{'}@Var{right}@code{'}, ms} +@DefmacItemx {OF, @code{'}@Var{left}@code{'}@Var{center}@code{'}@Var{right}@code{'}, ms} +@DefmacListEndx {EF, @code{'}@Var{left}@code{'}@Var{center}@code{'}@Var{right}@code{'}, ms} +The @code{OH} and @code{EH} macros define headers for odd- (recto) +and even-numbered (verso) pages, respectively; the @code{OF} and +@code{EF} macros define footers for them. +@endDefmac + +With either method, a percent sign @code{%} in header or footer text is +replaced by the current page number. By default, @file{ms} places no +header on a page numbered ``1'' (regardless of its number format). + +@Defmac {P1, , ms} +Typeset the header even on page@tie{}1. To be effective, this macro +must be called before the header trap is sprung on any page numbered +``1''; in practice, unless your page numbering is unusual, this means +that you should call it early, before @code{TL} or any heading or +paragraphing macro. This is a Berkeley extension. +@endDefmac + +For even greater flexibility, @file{ms} is designed to permit the +redefinition of the macros that are called when the @code{groff} traps +that ordinarily cause the headers and footers to be output are sprung. +@code{PT} (``page trap'') is called by @file{ms} when the header is to +be written, and @code{BT} (``bottom trap'') when the footer is to be. +The @code{groff} page location trap that @file{ms} sets up to format the +header also calls the (normally undefined) @code{HD} macro after +@code{PT}; you can define @code{HD} if you need additional processing +after setting the header (for example, to draw a line below it). +@c Although undocumented in Tuthill's 4.2BSD ms.diffs paper... +The @code{HD} hook is a Berkeley extension. Any such macros you +(re)define must implement any desired specialization for odd-, even-, or +first numbered pages. + +@c --------------------------------------------------------------------- + +@node Tab Stops in ms, ms Margins, ms Headers and Footers, ms Page Layout +@subsubsection Tab stops + +Use the @code{ta} request to define tab stops as needed. @xref{Tabs and +Fields}. + +@Defmac {TA, , ms} +Reset the tab stops to the @file{ms} default (every 5 ens). +Redefine this macro to create a different set of default tab stops. +@endDefmac + +@c --------------------------------------------------------------------- + +@node ms Margins, ms Multiple Columns, Tab Stops in ms, ms Page Layout +@subsubsection Margins +@cindex @file{ms} macros, margins + +Control margins using the registers summarized in ``Margin settings'' in +@ref{ms Document Control Settings} above. There is no setting for the +right margin; the combination of page offset @code{\n[PO]} and line +length @code{\n[LL]} determines it. + +@c --------------------------------------------------------------------- + +@node ms Multiple Columns, ms TOC, ms Margins, ms Page Layout +@subsubsection Multiple columns +@cindex @file{ms} macros, multiple columns +@cindex multiple columns [@file{ms}] + +@file{ms} can set text in as many columns as reasonably fit on the page. +The following macros force a page break if a multi-column layout is +active when they are called. The @code{MINGW} register stores the +default minimum gutter width; it is a GNU extension. When multiple +columns are in use, keeps and the @code{HORPHANS} and @code{PORPHANS} +registers work with respect to column breaks instead of page breaks. + +@Defmac {1C, , ms} +Arrange page text in a single column (the default). +@endDefmac + +@Defmac {2C, , ms} +Arrange page text in two columns. +@endDefmac + +@Defmac {MC, [@Var{column-width} [@Var{gutter-width}]], ms} +Arrange page text in multiple columns. If you specify no arguments, it +is equivalent to the @code{2C} macro. Otherwise, @var{column-width} is +the width of each column and @var{gutter-width} is the minimum distance +between columns. +@endDefmac + +@c --------------------------------------------------------------------- + +@node ms TOC, Differences from AT&T ms, ms Multiple Columns, ms Page Layout +@subsubsection Creating a table of contents +@cindex @file{ms} macros, creating table of contents +@cindex table of contents, creating [@file{ms}] + +Because @code{roff} formatters process their input in a single pass, +material on page 50, for example, cannot influence what appears on +page@tie{}1---this poses a challenge for a table of contents at its +traditional location in front matter, if you wish to avoid manually +maintaining it. @file{ms} enables the collection of material to be +presented in the table of contents as it appears, saving its page number +along with it, and then emitting the collected contents on demand toward +the end of the document. The table of contents can then be resequenced +to its desired location by physically rearranging the pages of a printed +document, or as part of post-processing---with a @cite{sed@r{(1)}} +script to reorder the pages in @command{troff}'s output, with +@cite{pdfjam@r{(1)}}, or with @cite{gropdf@r{(1)}}'s +@samp{.pdfswitchtopage} feature, for example. + +Define an entry to appear in the table of contents by bracketing its +text between calls to the @code{XS} and @code{XE} macros. A typical +application is to call them immediately after @code{NH} or @code{SH} and +repeat the heading text within them. The @code{XA} macro, used within +@samp{.XS}/@samp{.XE} pairs, supplements an entry---for instance, when +it requires multiple output lines, whether because a heading is too long +to fit or because style dictates that page numbers not be repeated. You +may wish to indent the text thus wrapped to correspond to its heading +depth; this can be done in the entry text by prefixing it with tabs or +horizontal motion escape sequences, or by providing a second argument to +the @code{XA} macro. @code{XS} and @code{XA} automatically associate +the page number where they are called with the text following them, but +they accept arguments to override this behavior. At the end of the +document, call @code{TC} or @code{PX} to emit the table of contents; +@code{TC} resets the page number to @samp{i} (Roman numeral one), and +then calls @code{PX}. All of these macros are Berkeley extensions. + +@DefmacList {XS, [@Var{page-number}], ms} +@DefmacItemx {XA, [@Var{page-number} [@Var{indentation}]], ms} +@DefmacListEndx {XE, , ms} +Begin, supplement, and end a table of contents entry. Each entry is +associated with @var{page-number} (otherwise the current page number); a +@var{page-number} of @samp{no} prevents a leader and page number from +being emitted for that entry. Use of @code{XA} within +@code{XS}/@code{XE} is optional; it can be repeated. If +@var{indentation} is present, a supplemental entry is indented by that +amount; ens are assumed if no unit is indicated. Text on input lines +between @code{XS} and @code{XE} is stored for later recall by @code{PX}. +@endDefmac + +@Defmac {PX, [@code{no}], ms} +Switch to single-column layout. Unless @code{no} is specified, center +and interpolate the @code{TOC} string in bold and two points larger than +the body text. Emit the table of contents entries. +@endDefmac + +@Defmac {TC, [@code{no}], ms} +Set the page number to@tie{}1, the page number format to lowercase Roman +numerals, and call @code{PX} (with a @code{no} argument, if present). +@endDefmac + +Here's an example of typical @file{ms} table of contents preparation. +We employ horizontal escape sequences @code{\h} to indent the entries by +sectioning depth. + +@CartoucheExample +.NH 1 +Introduction +.XS +Introduction +.XE +@r{@dots{}} +.NH 2 +Methodology +.XS +\h'2n'Methodology +.XA +\h'4n'Fassbinder's Approach +\h'4n'Kahiu's Approach +.XE +@r{@dots{}} +.NH 1 +Findings +.XS +Findings +.XE +@r{@dots{}} +.TC +@endCartoucheExample + +The remaining features in this subsubsection are GNU extensions. +@code{groff} @file{ms} obviates the need to repeat heading text after +@code{XS} calls. Call @code{XN} and @code{XH} after @code{NH} and +@code{SH}, respectively. + +@DefmacList {XN, @Var{heading-text}, ms} +@DefmacListEndx {XH, @Var{depth} @Var{heading-text}, ms} +Format @var{heading-text} and create a corresponding table of contents +entry. @code{XN} computes the indentation from the depth of the +preceding @code{NH} call; @code{XH} requires a @var{depth} argument to +do so. +@endDefmac + +@code{groff} @file{ms} encourages customization of table of contents +entry production. + +@DefmacList {XN-REPLACEMENT, @Var{heading-text}, ms} +@DefmacListEndx {XH-REPLACEMENT, @Var{depth} @Var{heading-text}, ms} +These hook macros implement @code{XN} and @code{XH}, respectively. +They call @code{XN-INIT} and pass their @var{heading-text} arguments to +@code{XH-UPDATE-TOC}. +@endDefmac + +@DefmacList {XN-INIT, , ms} +@DefmacListEndx {XH-UPDATE-TOC, @Var{depth} @Var{heading-text}, ms} +The @code{XN-INIT} hook macro does nothing by default. +@code{XH-UPDATE-TOC} brackets @var{heading-text} with @code{XS} and +@code{XE} calls, indenting it by 2 ens per level of @var{depth} beyond +the first. +@endDefmac + +We could therefore produce a table of contents similar to that in the +previous example with fewer macro calls. (The difference is that this +input follows the ``Approach'' entries with leaders and page numbers.) + +@CartoucheExample +.NH 1 +.XN Introduction +@r{@dots{}} +.NH 2 +.XN Methodology +.XH 3 "Fassbinder's Approach" +.XH 3 "Kahiu's Approach" +@r{@dots{}} +.NH 1 +.XN Findings +@r{@dots{}} +@endCartoucheExample + +To get the section number of the numbered headings into the table of +contents entries, we might define @code{XN-REPLACEMENT} as follows. +(We obtain the heading depth from @code{groff} @file{ms}'s internal +register @code{nh*hl}.) + +@CartoucheExample +.de XN-REPLACEMENT +.XN-INIT +.XH-UPDATE-TOC \\n[nh*hl] \\$@@ +\&\\*[SN] \\$* +.. +@endCartoucheExample + +You can change the style of the leader that bridges each table of +contents entry with its page number; define the @code{TC-LEADER} special +character by using the @code{char} request. A typical leader combines +the dot glyph @samp{.} with a horizontal motion escape sequence to +spread the dots. The width of the page number field is stored in the +@code{TC-MARGIN} register. + +@c --------------------------------------------------------------------- + +@node Differences from AT&T ms, ms Naming Conventions, ms Page Layout, ms +@subsection Differences from @acronym{AT&T} @file{ms} +@cindex @file{ms} macros, @code{groff} differences from @acronym{AT&T} +@cindex @acronym{AT&T} @file{ms}, macro package differences + +The @code{groff} @file{ms} macros are an independent reimplementation, +using no @acronym{AT&T} code. Since they take advantage of the extended +features of @code{groff}, they cannot be used with @acronym{AT&T} +@code{troff}. @code{groff} @file{ms} supports features described above +as Berkeley and Tenth Edition Research Unix extensions, and adds several +of its own. + +@itemize @bullet +@item +The internals of @code{groff} @file{ms} differ from the internals of +@acronym{AT&T} @file{ms}. Documents that depend upon implementation +details of @acronym{AT&T} @file{ms} may not format properly with +@code{groff} @file{ms}. Such details include macros whose function was +not documented in the @acronym{AT&T} @file{ms} +manual.@footnote{@cite{Typing Documents on the UNIX System: Using the +-ms Macros with Troff and Nroff}, M.@tie{}E.@: Lesk, Bell Laboratories, +1978} +@c XXX: We support RT anyway; maybe we should stop? + +@item +The error-handling policy of @code{groff} @file{ms} is to detect and +report errors, rather than to ignore them silently. + +@item +Tenth Edition @c possibly 9th +Research Unix supported @code{P1}/@code{P2} macros to bracket code +examples; @code{groff} @file{ms} does not. + +@item +@code{groff} @file{ms} does not work in GNU @code{troff}'s +@acronym{AT&T} compatibility mode. If loaded when that mode is enabled, +it aborts processing with a diagnostic message. + +@item +Multiple line spacing is not supported. Use a larger vertical spacing +instead. + +@item +@code{groff} @file{ms} uses the same header and footer defaults in both +@code{nroff} and @code{troff} modes as @acronym{AT&T} @file{ms} does in +@code{troff} mode; @acronym{AT&T}'s default in @code{nroff} mode is to +put the date, in U.S.@: traditional format (e.g., ``January 1, 2021''), +in the center footer (the @code{CF} string). + +@item +Many @code{groff} @file{ms} macros, including those for paragraphs, +headings, and displays, cause a reset of paragraph rendering parameters, +and may change the indentation; they do so not by incrementing or +decrementing it, but by setting it absolutely. This can cause problems +for documents that define additional macros of their own that try to +manipulate indentation. Use the @file{ms} @code{RS} and @code{RE} +macros instead of the @code{in} request. + +@item +@cindex fractional type sizes in @file{ms} macros +@cindex @file{ms} macros, fractional type sizes in +@acronym{AT&T} @file{ms} interpreted the values of the registers +@code{PS} and @code{VS} in points, and did not support the use of +scaling units with them. @code{groff} @file{ms} interprets values of +the registers @code{PS}, @code{VS}, @code{FPS}, and @code{FVS} equal to +or larger than@tie{}1,000 (one thousand) as decimal fractions multiplied +by@tie{}1,000.@footnote{Register values are converted to and stored as +basic units. @xref{Measurements}.} This threshold makes use of a +scaling unit with these parameters practical for high-resolution +devices while preserving backward compatibility. It also permits +expression of non-integral type sizes. For example, @samp{groff +-rPS=10.5p} at the shell prompt is equivalent to placing @samp{.nr PS +10.5p} at the beginning of the document. + +@item +@acronym{AT&T} @file{ms}'s @code{AU} macro supported arguments used with +some document types; @code{groff} @file{ms} does not. + +@item +Right-aligned displays are available. The @acronym{AT&T} @file{ms} +manual observes that ``it is tempting to assume that @samp{.DS R} will +right adjust lines, but it doesn't work''. In @code{groff} @file{ms}, +it does. + +@item +To make @code{groff} @file{ms} use the default page offset (which also +specifies the left margin), the @code{PO} register must stay undefined +until the first @file{ms} macro is called. + +This implies that @samp{\n[PO]} should not be used early in the +document, unless it is changed also: accessing an undefined register +automatically defines it. + +@item +@code{groff} @file{ms} supports the @code{PN} register, but it is not +necessary; you can access the page number via the usual @code{%} +register and invoke the @code{af} request to assign a different format +to it if desired.@footnote{If you redefine the @file{ms} @code{PT} macro +@c I wouldn't mention that, but Lesk 1978 encourages doing so. :-/ +and desire special treatment of certain page numbers (like @samp{1}), +you may need to handle a non-Arabic page number format, as @code{groff} +@file{ms}'s @code{PT} does; see the macro package source. @code{groff} +@file{ms} aliases the @code{PN} register to @code{%}.} + +@item +The @acronym{AT&T} @file{ms} manual documents registers @code{CW} and +@code{GW} as setting the default column width and ``intercolumn gap'', +respectively, and which applied when @code{MC} was called with fewer +than two arguments. @code{groff} @file{ms} instead treats @code{MC} +without arguments as synonymous with @code{2C}; there is thus no +occasion for a default column width register. Further, the @code{MINGW} +register and the second argument to @code{MC} specify a @emph{minimum} +space between columns, not the fixed gutter width of @acronym{AT&T} +@file{ms}. + +@item +The @acronym{AT&T} @file{ms} manual did not document the @code{QI} +register; Berkeley and @code{groff} @file{ms} do. +@end itemize + +@Defmpreg {GS, ms} +The register @code{GS} is set to@tie{}1 by the @code{groff} @file{ms} +macros, but is not used by the @acronym{AT&T} @file{ms} package. +Documents that need to determine whether they are being formatted with +@code{groff} @file{ms} or another implementation should test this +register. +@endDefmpreg + +@menu +* Missing Unix Version 7 ms Macros:: +@end menu + +@c --------------------------------------------------------------------- + +@node Missing Unix Version 7 ms Macros, , Differences from AT&T ms, Differences from AT&T ms +@subsubsection Unix Version 7 @file{ms} macros not implemented by @code{groff} @file{ms} + +Several macros described in the Unix Version@tie{}7 @file{ms} +documentation are unimplemented by @code{groff} @file{ms} because they +are specific to the requirements of documents produced internally by +Bell Laboratories, some of which also require a glyph for the Bell +System logo that @code{groff} does not support. These macros +implemented several document type formats +(@code{EG}, @c engineer's notes +@code{IM}, @c internal memorandum +@code{MF}, @c memorandum for file +@code{MR}, @c memorandum for record +@code{TM}, @c technical memorandum +@code{TR}), @c technical report +were meaningful only in conjunction with the use of certain document +types +(@code{AT}, @c attachments +@code{CS}, @c cover sheet info for `TM` documents +@code{CT}, @c copies to +@code{OK}, @c "other keywords" for `TM` documents +@code{SG}), @c signatures for `TM` documents +stored the postal addresses of Bell Labs sites +(@code{HO}, @c Holmdel +@code{IH}, @c Naperville +@code{MH}, @c Murray Hill +@code{PY}, @c Piscataway +@code{WH}), @c Whippany +or lacked a stable definition over time +(@code{UX}). @c Unix; on 1st use, add footnote id'ing trademark owner +To compatibly render historical @file{ms} documents using these macros, +we advise your documents to invoke the @code{rm} request to remove any +such macros it uses and then define replacements with an authentically +typeset original at hand.@footnote{The removal beforehand is necessary +because @code{groff} @file{ms} aliases these macros to a diagnostic +macro, and you want to redefine the aliased name, not its target.} For +informal purposes, a simple definition of @code{UX} should maintain the +readability of the document's substance. + +@CartoucheExample +.rm UX +.ds UX Unix\" +@endCartoucheExample + +@c --------------------------------------------------------------------- + +@node ms Legacy Features, ms Naming Conventions, Differences from AT&T ms, ms +@subsection Legacy Features +@cindex @file{ms} macros, strings +@cindex @file{ms} macros, special characters +@cindex @file{ms} macros, accent marks +@cindex accent marks [@file{ms}] +@cindex special characters [@file{ms}] +@cindex strings [@file{ms}] + +@code{groff} @file{ms} retains some legacy features solely to support +formatting of historical documents; contemporary ones should not use +them because they can render poorly. See the @cite{groff_char@r{(7)}} +man page. + +@unnumberedsubsubsec AT&T accent mark strings + +AT&T @file{ms} defined accent mark strings as follows. + +@Defmpstr {@code{'}, ms} +Apply acute accent to subsequent glyph. +@endDefmpstr + +@Defmpstr {@code{`}, ms} +Apply grave accent to subsequent glyph. +@endDefmpstr + +@Defmpstr {:, ms} +Apply dieresis (umlaut) to subsequent glyph. +@endDefmpstr + +@Defmpstr {^, ms} +Apply circumflex accent to subsequent glyph. +@endDefmpstr + +@Defmpstr {~, ms} +Apply tilde accent to subsequent glyph. +@endDefmpstr + +@Defmpstr {C, ms} +Apply caron to subsequent glyph. +@endDefmpstr + +@Defmpstr {\,, ms} +Apply cedilla to subsequent glyph. +@endDefmpstr + +@unnumberedsubsubsec Berkeley accent mark and glyph strings + +Berkeley @file{ms} offered an @code{AM} macro; calling it redefined the +AT&T accent mark strings (except for @samp{\*C}), applied them to the +@emph{preceding} glyph, and defined additional strings, some for spacing +glyphs. + +@Defmac {AM, , ms} +Enable alternative accent mark and glyph-producing strings. +@endDefmac + +@Defmpstr {@code{'}, ms} +Apply acute accent to preceding glyph. +@endDefmpstr + +@Defmpstr {@code{`}, ms} +Apply grave accent to preceding glyph. +@endDefmpstr + +@Defmpstr {:, ms} +Apply dieresis (umlaut) to preceding glyph. +@endDefmpstr + +@Defmpstr {^, ms} +Apply circumflex accent to preceding glyph. +@endDefmpstr + +@Defmpstr {~, ms} +Apply tilde accent to preceding glyph. +@endDefmpstr + +@Defmpstr {\,, ms} +Apply cedilla to preceding glyph. +@endDefmpstr + +@Defmpstr {/, ms} +Apply stroke (slash) to preceding glyph. +@endDefmpstr + +@Defmpstr {v, ms} +Apply caron to preceding glyph. +@endDefmpstr + +@Defmpstr {_, ms} +Apply macron to preceding glyph. +@endDefmpstr + +@Defmpstr {., ms} +Apply underdot to preceding glyph. +@endDefmpstr + +@Defmpstr {o, ms} +Apply ring accent to preceding glyph. +@endDefmpstr + +@Defmpstr {?, ms} +Interpolate inverted question mark. +@endDefmpstr + +@Defmpstr {!, ms} +Interpolate inverted exclamation mark. +@endDefmpstr + +@Defmpstr {8, ms} +Interpolate small letter sharp s. +@endDefmpstr + +@Defmpstr {q, ms} +Interpolate small letter o with hook accent (ogonek). +@endDefmpstr + +@Defmpstr {3, ms} +Interpolate small letter yogh. +@endDefmpstr + +@Defmpstr {d-, ms} +Interpolate small letter eth. +@endDefmpstr + +@Defmpstr {D-, ms} +Interpolate capital letter eth. +@endDefmpstr + +@Defmpstr {th, ms} +Interpolate small letter thorn. +@endDefmpstr + +@Defmpstr {Th, ms} +Interpolate capital letter thorn. +@endDefmpstr + +@Defmpstr {ae, ms} +Interpolate small ć ligature. +@endDefmpstr + +@Defmpstr {Ae, ms} +Interpolate capital Ć ligature. +@endDefmpstr + +@Defmpstr {oe, ms} +Interpolate small oe ligature. +@endDefmpstr + +@Defmpstr {OE, ms} +Interpolate capital OE ligature. +@endDefmpstr + +@c --------------------------------------------------------------------- + +@node ms Naming Conventions, , ms Legacy Features, ms +@subsection Naming Conventions +@cindex @file{ms} macros, naming conventions +@cindex naming conventions, @file{ms} macros + +The following conventions are used for names of macros, strings, and +registers. External names available to documents that use the +@code{groff} @file{ms} macros contain only uppercase letters and digits. + +Internally, the macros are divided into modules. Conventions for +identifier names are as follows. + +@itemize @bullet +@item +Names used only within one module are of the form +@var{module}@code{*}@var{name}. + +@item +Names used outside the module in which they are defined are of the form +@var{module}@code{@@}@var{name}. + +@item +Names associated with a particular environment are of the form +@var{environment}@code{:}@var{name}; these are used only within the +@code{par} module. + +@item +@var{name} does not have a module prefix. + +@item +Constructed names used to implement arrays are of the form +@var{array}@code{!}@var{index}. +@end itemize + +Thus the @code{groff} @file{ms} macros reserve the following names. + +@itemize @bullet +@item +Names containing the characters @code{*}, @code{@@}, and@tie{}@code{:}. + +@item +Names containing only uppercase letters and digits. +@end itemize + + +@c ===================================================================== +@c ===================================================================== + +@node GNU troff Reference, File Formats, Major Macro Packages, Top +@chapter GNU @code{troff} Reference +@cindex reference, @code{gtroff} +@cindex @code{gtroff}, reference + +This chapter covers @emph{all} of the facilities of the GNU +@code{troff} formatting engine. Users of macro packages may skip it if +not interested in details. + + +@menu +* Text:: +* Page Geometry:: +* Measurements:: +* Numeric Expressions:: +* Identifiers:: +* Formatter Instructions:: +* Comments:: +* Registers:: +* Manipulating Filling and Adjustment:: +* Manipulating Hyphenation:: +* Manipulating Spacing:: +* Tabs and Fields:: +* Character Translations:: +* @code{troff} and @code{nroff} Modes:: +* Line Layout:: +* Line Continuation:: +* Page Layout:: +* Page Control:: +* Using Fonts:: +* Manipulating Type Size and Vertical Spacing:: +* Colors:: +* Strings:: +* Conditionals and Loops:: +* Writing Macros:: +* Page Motions:: +* Drawing Geometric Objects:: +* Deferring Output:: +* Traps:: +* Diversions:: +* Punning Names:: +* Environments:: +* Suppressing Output:: +* I/O:: +* Postprocessor Access:: +* Miscellaneous:: +* Gtroff Internals:: +* Debugging:: +* Implementation Differences:: +@end menu + + +@c ===================================================================== + +@c BEGIN Keep roughly parallel with roff(7) section "Concepts". +@node Text, Measurements, GNU troff Reference, GNU troff Reference +@section Text +@cindex text, GNU @code{troff} processing + +@acronym{AT&T} @code{troff} was designed to take input as it would be +composed on a typewriter, including the teletypewriters used as early +computer terminals, and relieve the user drafting a document of concern +with details like line length, hyphenation breaking, and the achievement +of straight margins. Early in its development, the program gained the +ability to prepare output for a phototypesetter; a document could then +be prepared for output to either a teletypewriter, a phototypesetter, or +both. GNU @code{troff} continues this tradition of permitting an author +to compose a single master version of a document which can then be +rendered for a variety of output formats or devices. + +@code{roff} input files contain text interspersed with instructions to +control the formatter. Even in the absence of such instructions, GNU +@code{troff} still processes its input in several ways, by filling, +hyphenating, breaking, and adjusting it, and supplementing it with +inter-sentence space. + +@menu +* Filling:: +* Hyphenation:: +* Sentences:: +* Breaking:: +* Adjustment:: +* Tabs and Leaders:: +* Requests and Macros:: +* Macro Packages:: +* Input Encodings:: +* Input Conventions:: +@end menu + +@c --------------------------------------------------------------------- + +@node Filling, Sentences, Text, Text +@subsection Filling + +When GNU @code{troff} starts up, it obtains information about the device +for which it is preparing output.@footnote{@xref{Device and Font +Description Files}.} An essential property is the length of the output +line, such as ``6.5 inches''. + +@cindex word, definition of +@cindex filling +GNU @code{troff} interprets plain text files employing the Unix +line-ending convention. It reads input a character at a time, +collecting words as it goes, and fits as many words together on an +output line as it can---this is known as @dfn{filling}. To GNU +@code{troff}, a @dfn{word} is any sequence of one or more characters +that aren't spaces or newlines. The exceptions separate +words.@footnote{@slanted{Tabs} and @slanted{leaders} also separate +words. @slanted{Escape sequences} can function as word characters, word +separators, or neither---the last simply have no effect on GNU +@code{troff}'s idea of whether an input character is within a word. +We'll discuss all of these in due course.} To disable filling, see +@ref{Manipulating Filling and Adjustment}. + +@Example +It is a truth universally acknowledged +that a single man in possession of a +good fortune must be in want of a wife. + @result{} It is a truth universally acknowledged that a + @result{} single man in possession of a good fortune must + @result{} be in want of a wife. +@endExample + +@c --------------------------------------------------------------------- + +@node Sentences, Hyphenation, Filling, Text +@subsection Sentences +@cindex sentences + +A passionate debate has raged for decades among writers of the English +language over whether more space should appear between adjacent +sentences than between words within a sentence, and if so, how much, and +what other circumstances should influence this spacing.@footnote{A +well-researched jeremiad appreciated by @code{groff} contributors on +both sides of the sentence-spacing debate can be found at +@uref{https://web.archive.org@//web@//20171217060354@//http://www.heracliteanriver.com@//?p=324}.} +GNU @code{troff} follows the example of @acronym{AT&T} @code{troff}; +it attempts to detect the boundaries between sentences, and supplies +additional inter-sentence space between them. + +@Example +Hello, world! +Welcome to groff. + @result{} Hello, world! Welcome to groff. +@endExample + +@cindex end-of-sentence characters +@cindex sentence space +@cindex space between sentences +@cindex French spacing +GNU @code{troff} flags certain characters (normally @samp{!}, @samp{?}, +and @samp{.}) as potentially ending a sentence. When GNU @code{troff} +encounters one of these @dfn{end-of-sentence characters} at the end of +an input line, or one of them is followed by two (unescaped) spaces on +the same input line, it appends an inter-word space followed by an +inter-sentence space in the output. + +@Example +R. Harper subscribes to a maxim of P. T. Barnum. + @result{} R. Harper subscribes to a maxim of P. T. Barnum. +@endExample + +In the above example, inter-sentence space is not added after @samp{P.} +or @samp{T.} because the periods do not occur at the end of an input +line, nor are they followed by two or more spaces. Let's imagine that +we've heard something about defamation from Mr.@: Harper's attorney, +recast the sentence, and reflowed it in our text editor. + +@Example +I submit that R. Harper subscribes to a maxim of P. T. +Barnum. + @result{} I submit that R. Harper subscribes to a maxim of + @result{} P. T. Barnum. +@endExample + +``Barnum'' doesn't begin a sentence! What to do? Let us meet our first +@dfn{escape sequence}, a series of input characters that give +instructions to GNU @code{troff} instead of being used to construct +output device glyphs.@footnote{This statement oversimplifies; there are +escape sequences whose purpose is precisely to produce glyphs on the +output device, and input characters that @emph{aren't} part of escape +sequences can undergo a great deal of processing before getting to the +output.} An escape sequence begins with the backslash character @code{\} +by default, an uncommon character in natural language text, and is +@emph{always} followed by at least one other character, hence the term +``sequence''. + +@cindex @code{\&}, at end of sentence +The dummy character escape sequence @code{\&} can be used after an +end-of-sentence character to defeat end-of-sentence detection on a +per-instance basis. We can therefore rewrite our input more +defensively. + +@Example +I submit that R.\& Harper subscribes to a maxim of P.\& +T.\& Barnum. + @result{} I submit that R. Harper subscribes to a maxim of + @result{} P. T. Barnum. +@endExample + +Adding text caused our input to wrap; now, we don't need @code{\&} after +@samp{T.} but we do after @samp{P.}. Consistent use of the escape +sequence ensures that potential sentence boundaries are robust to +editing activities. Further advice along these lines will follow in +@ref{Input Conventions}. + +@cindex end-of-sentence transparent characters +@cindex characters, end-of-sentence transparent +@cindex @code{dg} glyph, at end of sentence +@cindex @code{dd} glyph, at end of sentence +@cindex @code{rq} glyph, at end of sentence +@cindex @code{cq} glyph, at end of sentence +@cindex @code{"}, at end of sentence +@cindex @code{'}, at end of sentence +@cindex @code{)}, at end of sentence +@cindex @code{]}, at end of sentence +@cindex @code{*}, at end of sentence +@cindex special characters +@cindex characters, special +Normally, the occurrence of a visible non-end-of-sentence character (as +opposed to a space or tab) immediately after an end-of-sentence +character cancels detection of the end of a sentence. For example, it +would be incorrect for GNU @code{troff} to infer the end of a sentence +after the dot in @samp{3.14159}. However, several characters are +treated @emph{transparently} after the occurrence of an end-of-sentence +character. That is, GNU @code{troff} does not cancel end-of-sentence +detection when it processes them. This is because such characters are +often used as footnote markers or to close quotations and +parentheticals. The default set is @samp{"}, @samp{'}, @samp{)}, +@samp{]}, @samp{*}, @code{\[dg]}, @code{\[dd]}, @code{\[rq]}, and +@code{\[cq]}. The last four are examples of @dfn{special characters}, +escape sequences whose purpose is to obtain glyphs that are not easily +typed at the keyboard, or which have special meaning to GNU @code{troff} +(like @code{\} itself).@footnote{The mnemonics for the special +characters shown here are ``dagger'', ``double dagger'', ``right +(double) quote'', and ``closing (single) quote''. See the +@cite{groff_char@r{(7)}} man page.} + +@Example +\[lq]The idea that the poor should have leisure has always +been shocking to the rich.\[rq] +(Bertrand Russell, 1935) +@c XXX: @iftex puts a blank line on the output. This seems like a bug. +@c @newline works around it. But we need a weird inverse indent. +@iftex @ + @result{} @quotedblleft{}The idea that the poor should have + @result{} leisure has always been shocking to + @result{} the rich.@quotedblright{} (Bertrand Russell, 1935) +@end iftex +@ifnottex + @result{} "The idea that the poor should have + @result{} leisure has always been shocking to + @result{} the rich." (Bertrand Russell, 1935) +@end ifnottex +@endExample + +The sets of characters that potentially end sentences or are transparent +to sentence endings are configurable. See the @code{cflags} request in +@ref{Using Symbols}. To change the additional inter-sentence space +amount---even to remove it entirely---see @ref{Manipulating Filling and +Adjustment}. + +@c --------------------------------------------------------------------- + +@node Hyphenation, Breaking, Sentences, Text +@subsection Hyphenation +@cindex hyphenation + +When an output line is nearly full, it is uncommon for the next word +collected from the input to exactly fill it---typically, there is room +left over only for part of the next word. The process of splitting a +word so that it appears partially on one line (with a hyphen to indicate +to the reader that the word has been broken) with its remainder on the +next is @dfn{hyphenation}. Hyphenation points can be manually +specified; GNU @code{troff} also uses a hyphenation algorithm and +language-specific pattern files (based on those used in @TeX{}) to +decide which words can be hyphenated and where. + +Hyphenation does not always occur even when the hyphenation rules for a +word allow it; it can be disabled, and when not disabled there are +several parameters that can prevent it in certain circumstances. +@xref{Manipulating Hyphenation}. + +@c --------------------------------------------------------------------- + +@node Breaking, Adjustment, Hyphenation, Text +@subsection Breaking +@cindex break +@cindex implicit line break +@cindex line break, output +@cindex output line break + +Once an output line is full, the next word (or remainder of a hyphenated +one) is placed on a different output line; this is called a @dfn{break}. +In this manual and in @code{roff} discussions generally, a ``break'' if +not further qualified always refers to the termination of an output +line. When the formatter is filling text, it introduces breaks +automatically to keep output lines from exceeding the configured line +length. After an automatic break, GNU @code{troff} adjusts the line if +applicable (see below), and then resumes collecting and filling text on +the next output line. + +Sometimes, a line cannot be broken automatically. This usually does +not happen with natural language text unless the output line length has +been manipulated to be extremely short, but it can with specialized +text like program source code. We can use @code{perl} at the shell +prompt to contrive an example of failure to break the line. We also +employ the @option{-z} option to suppress normal output. + +@Example +$ perl -e 'print "#" x 80, "\n";' | nroff -z + @error{} warning: cannot break line +@endExample + +The remedy for these cases is to tell GNU @code{troff} where the line +may be broken without hyphens. This is done with the non-printing break +point escape sequence @samp{\:}; see @ref{Manipulating Hyphenation}. + +@cindex blank line +@cindex empty line +@cindex line, blank +@cindex blank line macro (@code{blm}) +What if the document author wants to stop filling lines temporarily, for +instance to start a new paragraph? There are several solutions. A +blank input line not only causes a break, but by default it also outputs +a one-line vertical space (effectively a blank output line). This +behavior can be modified; see @ref{Blank Line Traps}. Macro packages +may discourage or disable the blank line method of paragraphing in favor +of their own macros. + +@cindex leading spaces +@cindex spaces, leading and trailing +@cindex trailing spaces on text lines +@cindex leading space macro (@code{lsm}) +A line that begins with one or more spaces causes a break. The spaces +are output at the beginning of the next line without being +@emph{adjusted} (see below); however, this behavior can be modified +(@pxref{Leading Space Traps}). Again, macro packages may provide other +methods of producing indented paragraphs. Trailing spaces on text lines +are discarded.@footnote{``Text lines'' are defined in @ref{Requests and +Macros}.} + +What if the file ends before enough words have been collected to fill an +output line? Or the output line is exactly full but not yet broken, and +there is no more input? GNU @code{troff} interprets the end of input as +a break. Certain requests also cause breaks, implicitly or explicitly. +This is discussed in @ref{Manipulating Filling and Adjustment}. + +@c --------------------------------------------------------------------- + +@node Adjustment, Tabs and Leaders, Breaking, Text +@subsection Adjustment + +@cindex extra spaces between words +After GNU @code{troff} performs an automatic break, it may then +@dfn{adjust} the line, widening inter-word spaces until the text reaches +the right margin. Extra spaces between words are preserved. Leading +and trailing spaces are handled as noted above. Text can be aligned to +the left or right margin only, or centered; see @ref{Manipulating +Filling and Adjustment}. +@c END Keep roughly parallel with roff(7) section "Concepts". + +@c --------------------------------------------------------------------- + +@node Tabs and Leaders, Input Conventions, Adjustment, Text +@subsection Tabs and Leaders + +@cindex horizontal tab character +@cindex tab character +@cindex character, horizontal tab +@cindex leader character +@cindex character, leader +@cindex tab stops +@cindex stops, tab +GNU @code{troff} translates input horizontal tab characters (``tabs'') +and @key{Control+A} characters (``leaders'') into movements to the next +tab stop. Tabs simply move to the next tab stop; leaders place enough +periods to fill the space. Tab stops are by default located every half +inch measured from the drawing position corresponding to the beginning +of the input line; see @ref{Page Geometry}. Tabs and leaders do not +cause breaks and therefore do not interrupt filling. Below, we use +arrows @arrow{} and bullets @bullet{} to indicate input tabs and +leaders, respectively. + +@Example +1 +@arrow{} 2 @arrow{} 3 @bullet{} 4 +@arrow{} @bullet{} 5 +@result{} 1 2 3.......4 ........5 +@endExample + +Tabs and leaders lend themselves to table construction.@footnote{``Tab'' +is short for ``tabulation'', revealing the term's origin as a spacing +mechanism for table arrangement.} The tab and leader glyphs can be +configured, and further facilities for sophisticated table composition +are available; see @ref{Tabs and Fields}. There are many details to +track when using such low-level features, so most users turn to the +@cite{tbl@r{(1)}} preprocessor to lay out tables. + +@c --------------------------------------------------------------------- + +@node Requests and Macros, Macro Packages, Tabs and Leaders, Text +@subsection Requests and Macros + +We have now encountered almost all of the syntax there is in the +@code{roff} language, with an exception already noted in passing. +@cindex request +@cindex control character (@code{.}) +@cindex character, control (@code{.}) +@cindex no-break control character (@code{'}) +@cindex character, no-break control (@code{'}) +@cindex control character, no-break (@code{'}) +A @dfn{request} is an instruction to the formatter that occurs after a +@dfn{control character}, which is recognized at the beginning of an +input line. The regular control character is a dot (@code{.}). Its +counterpart, the @dfn{no-break control character}, a neutral apostrophe +(@code{'}), suppresses the break that is implied by some requests. +These characters were chosen because it is uncommon for lines of text in +natural languages to begin with them. +@cindex dummy character (@code{\&}), as control character suppressor +@cindex character, dummy (@code{\&}), as control character suppressor +If you require a formatted period or apostrophe (closing single +quotation mark) where GNU @code{troff} is expecting a control character, +prefix the dot or neutral apostrophe with the dummy character escape +sequence, @samp{\&}. + +@cindex control line +An input line beginning with a control character is called a +@dfn{control line}. +@cindex text line +Every line of input that is not a control line is a @dfn{text +line}.@footnote{The @code{\@key{RET}} escape sequence can alter how an +input line is classified; see @ref{Line Continuation}.} + +@cindex argument +Requests often take @dfn{arguments}, words (separated from the request +name and each other by spaces) that specify details of the action GNU +@code{troff} is expected to perform. If a request is meaningless +without arguments, it is typically ignored. + +GNU @code{troff}'s requests and escape sequences comprise the control +language of the formatter. Of key importance are the requests that +define macros. Macros are invoked like requests, enabling the request +repertoire to be extended or overridden.@footnote{Argument handling in +macros is more flexible but also more complex. @xref{Calling Macros}.} + +@cindex macro +@cindex calling a macro +@cindex interpolation +A @dfn{macro} can be thought of as an abbreviation you can define for a +collection of control and text lines. When the macro is @dfn{called} by +giving its name after a control character, it is replaced with what it +stands for. The process of textual replacement is known as +@dfn{interpolation}.@footnote{Some escape sequences undergo +interpolation as well.} Interpolations are handled as soon as they are +recognized, and once performed, a @code{roff} formatter scans the +replacement for further requests, macro calls, and escape sequences. + +In @code{roff} systems, the @code{de} request defines a +macro.@footnote{GNU @code{troff} offers additional ones. @xref{Writing +Macros}.} + +@Example +.de DATE +2020-11-14 +.. +@endExample + +@noindent +The foregoing input produces no output by itself; all we have done is +store some information. Observe the pair of dots that ends the macro +definition. This is a default; you can specify your own terminator for +the macro definition as the second argument to the @code{de} request. + +@Example +.de NAME ENDNAME +Heywood Jabuzzoff +.ENDNAME +@endExample + +In fact, the ending marker is itself the name of a macro to be +called, or a request to be invoked, if it is defined at the time its +control line is read. + +@Example +.de END +Big Rip +.. +.de START END +Big Bang +.END +.START + @result{} Big Rip Big Bang +@endExample + +@noindent +In the foregoing example, ``Big Rip'' printed before ``Big Bang'' +because its macro was @emph{called} first. Consider what would happen +if we dropped @code{END} from the @samp{.de START} line and added +@code{..} after @code{.END}. Would the order change? + +Let us consider a more elaborate example. + +@Example +.de DATE +2020-10-05 +.. +. +.de BOSS +D.\& Kruger, +J.\& Peterman +.. +. +.de NOTICE +Approved: +.DATE +by +.BOSS +.. +. +Insert tedious regulatory compliance paragraph here. + +.NOTICE + +Insert tedious liability disclaimer paragraph here. + +.NOTICE + @result{} Insert tedious regulatory compliance paragraph here. + @result{} + @result{} Approved: 2020-10-05 by D. Kruger, J. Peterman + @result{} + @result{} Insert tedious liability disclaimer paragraph here. + @result{} + @result{} Approved: 2020-10-05 by D. Kruger, J. Peterman +@endExample + +@noindent +The above document started with a series of control lines. Three macros +were defined, with a @code{de} request declaring each macro's name, and +the ``body'' of the macro starting on the next line and continuing until +a line with two dots @samp{@code{..}} marked its end. The text proper +began only after the macros were defined; this is a common pattern. +Only the @code{NOTICE} macro was called ``directly'' by the document; +@code{DATE} and @code{BOSS} were called only by @code{NOTICE} itself. +Escape sequences were used in @code{BOSS}, two levels of macro +interpolation deep. + +The advantage in typing and maintenance economy may not be obvious from +such a short example, but imagine a much longer document with dozens of +such paragraphs, each requiring a notice of managerial approval. +Consider what must happen if you are in charge of generating a new +version of such a document with a different date, for a different boss. +With well-chosen macros, you only have to change each datum in one +place. + +In practice, we would probably use strings (@pxref{Strings}) instead of +macros for such simple interpolations; what is important here is to +glimpse the potential of macros and the power of recursive +interpolation. + +We could have defined @code{DATE} and @code{BOSS} in the opposite order; +perhaps less obviously, we could also have defined them @emph{after} +@code{NOTICE}. ``Forward references'' like this are acceptable because +the body of a macro definition is not (completely) interpreted, but +stored instead (@pxref{Copy Mode}). While a macro is being defined (or +appended to), requests are not interpreted and macros not interpolated, +whereas some commonly used escape sequences @emph{are} interpreted. +@code{roff} systems also support recursive macro calls, as long as you +have a way to break the recursion (@pxref{Conditionals and Loops}). +Maintainable @code{roff} documents tend to arrange macro definitions to +minimize forward references. + +@c --------------------------------------------------------------------- + +@node Macro Packages, Input Encodings, Requests and Macros, Text +@subsection Macro Packages +@cindex macro package +@cindex package, macro + +@c TODO: Consider parallelizing with groff_tmac(5) "Description". +Macro definitions can be collected into @dfn{macro files}, @code{roff} +input files designed to produce no output themselves but instead ease +the preparation of other @code{roff} documents. There is no syntactical +difference between a macro file and any other @code{roff} document; only +its purpose distinguishes it. When a macro file is installed at a +standard location and suitable for use by a general audience, it is +often termed a @dfn{macro package}.@footnote{Macro files and packages +frequently define registers and strings as well.} Macro packages can be +loaded by supplying the @option{-m} option to GNU @command{troff} or a +@code{groff} front end. Alternatively, a document requiring a macro +package can load it with the @code{mso} (``macro source'') request. + +@c --------------------------------------------------------------------- + +@c TODO: Move a lot of this node to the "Invoking groff" chapter. Some +@c of the discussion is better placed in discussion of output drivers +@c (e.g., what character encodings _they_ support for output and their +@c responsibility for converting to them) as well. + +@node Input Encodings, Input Conventions, Macro Packages, Text +@subsection Input Encodings + +The @command{groff} command's @option{-k} option calls the +@command{preconv} preprocessor to perform input character encoding +conversions. Input to the GNU @code{troff} formatter itself, on the +other hand, must be in one of two encodings it can recognize. + +@table @code +@item cp1047 +@cindex encoding, input, @acronym{EBCDIC} +@cindex @acronym{EBCDIC}, input encoding +@cindex input encoding, @acronym{EBCDIC} +@cindex encoding, input, code page 1047 +@cindex code page 1047, input encoding +@cindex input encoding, code page 1047 +@cindex IBM code page 1047 input encoding +@pindex cp1047.tmac +The code page 1047 input encoding works only on @acronym{EBCDIC} +platforms (and conversely, the other input encodings don't work with +@acronym{EBCDIC}); the file @file{cp1047.tmac} is loaded at startup. + +@item latin1 +@cindex encoding, input, @w{Latin-1} (ISO @w{8859-1}) +@cindex @w{Latin-1} (ISO @w{8859-1}), input encoding +@cindex ISO @w{8859-1} (@w{Latin-1}), input encoding +@cindex input encoding, @w{Latin-1} (ISO @w{8859-1}) +@pindex latin1.tmac +ISO @w{Latin-1}, an encoding for Western European languages, is the +default input encoding on non-@acronym{EBCDIC} platforms; the file +@file{latin1.tmac} is loaded at startup. +@end table + +@noindent +Any document that is encoded in ISO 646:1991 (a descendant of USAS +@w{X3.4-1968} or ``US-ASCII''), or, equivalently, uses only code points +from the ``C0 Controls'' and ``Basic Latin'' parts of the Unicode +character set is also a valid ISO @w{Latin-1} document; the standards +are interchangeable in their first 128 code points.@footnote{The +@emph{semantics} of certain punctuation code points have gotten stricter +with the successive standards, a cause of some frustration among man +page writers; see the @cite{groff_char@r{(7)}} man page.} + +Other encodings are supported by means of macro packages. + +@table @code +@item latin2 +@cindex encoding, input, @w{Latin-2} (ISO @w{8859-2}) +@cindex @w{Latin-2} (ISO @w{8859-2}), input encoding +@cindex ISO @w{8859-2} (@w{Latin-2}), input encoding +@cindex input encoding, @w{Latin-2} (ISO @w{8859-2}) +@pindex latin2.tmac +To use ISO @w{Latin-2}, an encoding for Central and Eastern European +languages, invoke @w{@samp{.mso latin2.tmac}} at the beginning of your +document or supply @samp{-mlatin2} as a command-line argument to +@code{groff}. + +@item latin5 +@cindex encoding, input, @w{Latin-5} (ISO @w{8859-9}) +@cindex @w{Latin-5} (ISO @w{8859-9}), input encoding +@cindex ISO @w{8859-9} (@w{Latin-5}), input encoding +@cindex input encoding, @w{Latin-5} (ISO @w{8859-9}) +@pindex latin5.tmac +To use ISO @w{Latin-5}, an encoding for the Turkish language, invoke +@w{@samp{.mso latin5.tmac}} at the beginning of your document or +supply @samp{-mlatin5} as a command-line argument to @code{groff}. + +@item latin9 +@cindex encoding, input, @w{Latin-9} (ISO @w{8859-15}) +@cindex @w{Latin-9} (ISO @w{8859-15}), input encoding +@cindex ISO @w{8859-15} (@w{Latin-9}), input encoding +@cindex input encoding, @w{Latin-9} (ISO @w{8859-15}) +@pindex latin9.tmac +ISO @w{Latin-9} succeeds @w{Latin-1}; it includes a Euro sign and better +glyph coverage for French. To use this encoding, invoke @w{@samp{.mso +latin9.tmac}} at the beginning of your document or supply +@samp{-mlatin9} as a command-line argument to @code{groff}. +@end table + +Some characters from an input encoding may not be available with a +particular output driver, or their glyphs may not have representation in +the font used. For terminal devices, fallbacks are defined, like +@samp{EUR} for the Euro sign and @samp{(C)} for the copyright sign. For +typesetter devices, you may need to ``mount'' fonts that support glyphs +required by the document. @xref{Font Positions}. + +@pindex freeeuro.pfa +@pindex ec.tmac +Because a Euro glyph was not historically defined in PostScript fonts, +@code{groff} comes with a font called @file{freeeuro.pfa} that provides +the Euro in several styles. Standard PostScript fonts contain the +glyphs from @w{Latin-5} and @w{Latin-9} that @w{Latin-1} lacks, so these +encodings are supported for the @option{ps} and @option{pdf} output +devices as @code{groff} ships, while @w{Latin-2} is not. + +Unicode supports characters from all other input encodings; the +@option{utf8} output driver for terminals therefore does as well. The +DVI output driver supports the @w{Latin-2} and @w{Latin-9} encodings if +the command-line option @option{-mec} is used as well. @footnote{The +DVI output device defaults to using the Computer Modern (CM) fonts; +@file{ec.tmac} loads the EC fonts instead, which provide Euro +@samp{\[Eu]} and per mille @samp{\[%0]} glyphs.} + +@c --------------------------------------------------------------------- + +@node Input Conventions, , Input Encodings, Text +@subsection Input Conventions +@cindex input conventions +@cindex conventions for input + +Since GNU @code{troff} fills text automatically, it is common practice +in the @code{roff} language to avoid visual composition of text in input +files: the esthetic appeal of the formatted output is what matters. +Therefore, @code{roff} input should be arranged such that it is easy for +authors and maintainers to compose and develop the document, understand +the syntax of @code{roff} requests, macro calls, and preprocessor +languages used, and predict the behavior of the formatter. Several +traditions have accrued in service of these goals. + +@itemize @bullet +@item +Follow sentence endings in the input with newlines to ease their +recognition (@pxref{Sentences}). It is frequently convenient to end +text lines after colons and semicolons as well, as these typically +precede independent clauses. Consider doing so after commas; they often +occur in lists that become easy to scan when itemized by line, or +constitute supplements to the sentence that are added, deleted, or +updated to clarify it. Parenthetical and quoted phrases are also good +candidates for placement on text lines by themselves. + +@item +Set your text editor's line length to 72 characters or +fewer.@footnote{Emacs: @code{fill-column: 72}; Vim: @code{textwidth=72}} +This limit, combined with the previous item of advice, makes it less +common that an input line will wrap in your text editor, and thus will +help you perceive excessively long constructions in your text. Recall +that natural languages originate in speech, not writing, and that +punctuation is correlated with pauses for breathing and changes in +prosody. + +@item +Use @code{\&} after @samp{!}, @samp{?}, and @samp{.} if they are +followed by space, tab, or newline characters and don't end a sentence. + +@item +In filled text lines, use @code{\&} before @samp{.} and @samp{'} if they +are preceded by space, so that reflowing the input doesn't turn them +into control lines. + +@item +Do not use spaces to perform indentation or align columns of a table. +Leading spaces are reliable when text is not being filled. + +@item +Comment your document. It is never too soon to apply comments to +record information of use to future document maintainers (including your +future self). We thus introduce another escape sequence, @code{\"}, +which causes GNU @code{troff} to ignore the remainder of the input line. + +@item +Use the empty request---a control character followed immediately by a +newline---to visually manage separation of material in input files. +Many of the @code{groff} project's own documents use an empty request +between sentences, after macro definitions, and where a break is +expected, and two empty requests between paragraphs or other requests or +macro calls that will introduce vertical space into the document. + +You can combine the empty request with the comment escape sequence to +include whole-line comments in your document, and even ``comment out'' +sections of it. +@end itemize + +We conclude this section with an example sufficiently long to illustrate +most of the above suggestions in practice. For the purpose of fitting +the example between the margins of this manual with the font used for +its typeset version, we have shortened the input line length to 56 +columns. As before, an arrow @arrow{} indicates a tab character. + +@c Wrap example at 56 columns (not counting @arrow{}). +@CartoucheExample +.\" nroff this_file.roff | less +.\" groff -T ps this_file.roff > this_file.ps +@arrow{}The theory of relativity is intimately connected with +the theory of space and time. +. +I shall therefore begin with a brief investigation of +the origin of our ideas of space and time, +although in doing so I know that I introduce a +controversial subject. \" remainder of paragraph elided +. +. + +@arrow{}The experiences of an individual appear to us arranged +in a series of events; +in this series the single events which we remember +appear to be ordered according to the criterion of +\[lq]earlier\[rq] and \[lq]later\[rq], \" punct swapped +which cannot be analysed further. +. +There exists, +therefore, +for the individual, +an I-time, +or subjective time. +. +This itself is not measurable. +. +I can, +indeed, +associate numbers with the events, +in such a way that the greater number is associated with +the later event than with an earlier one; +but the nature of this association may be quite +arbitrary. +. +This association I can define by means of a clock by +comparing the order of events furnished by the clock +with the order of a given series of events. +. +We understand by a clock something which provides a +series of events which can be counted, +and which has other properties of which we shall speak +later. +.\" Albert Einstein, _The Meaning of Relativity_, 1922 +@endCartoucheExample + +@node Page Geometry, Measurements, Text, GNU troff Reference +@section Page Geometry +@cindex page, geometry of +@cindex geometry, page + +@code{roff} systems format text under certain assumptions about the size +of the output medium, or page. For the formatter to correctly break a +line it is filling, it must know the line length, which it derives from +the page width (@pxref{Line Layout}). For it to decide whether to write +an output line to the current page or wait until the next one, it must +know the page length (@pxref{Page Layout}). + +@cindex device resolution +@cindex resolution, device +@cindex basic units +@cindex units, basic +@cindex machine units +@cindex units, machine +A device's @dfn{resolution} converts practical units like inches or +centimeters to @dfn{basic units}, a convenient length measure for the +output device or file format. The formatter and output driver use basic +units to reckon page measurements. The device description file defines +its resolution and page dimensions (@pxref{DESC File Format}). + +@cindex page +A @dfn{page} is a two-dimensional structure upon which a @code{roff} +system imposes a rectangular coordinate system with its upper left +corner as the origin. Coordinate values are in basic units and increase +down and to the right. Useful ones are therefore always positive and +within numeric ranges corresponding to the page boundaries. + +@cindex drawing position +@cindex position, drawing +While the formatter (and, later, output driver) is processing a page, it +keeps track of its @dfn{drawing position}, which is the location at +which the next glyph will be written, from which the next motion will be +measured, or where a geometric object will commence rendering. +@cindex text baseline +@cindex baseline, text +Notionally, glyphs are drawn from the text baseline upward and to the +right.@footnote{@code{groff} does not yet support right-to-left +scripts.} The @dfn{text baseline} is a (usually invisible) line upon +which the glyphs of a typeface are aligned. A glyph therefore +``starts'' at its bottom-left corner. If drawn at the origin, a typical +letter glyph would lie partially or wholly off the page, depending on +whether, like ``g'', it features a descender below the baseline. + +@cindex page offset +@cindex offset, page +Such a situation is nearly always undesirable. It is furthermore +conventional not to write or draw at the extreme edges of the page. +Therefore the initial drawing position of a @code{roff} formatter is not +at the origin, but below and to the right of it. This rightward shift +from the left edge is known as the @dfn{page +offset}.@footnote{@code{groff}'s terminal output devices have page +offsets of zero.} The downward shift leaves room for a text output +line. + +Text is arranged on a one-dimensional lattice of text baselines from the +top to the bottom of the page. +@cindex vertical spacing +@cindex spacing, vertical +@cindex vee +@dfn{Vertical spacing} is the distance between adjacent text baselines. +Typographic tradition sets this quantity to 120% of the type size. The +initial drawing position is one unit of vertical spacing below the page +top. Typographers term this unit a @slanted{vee}. + +@cindex page break +@cindex break, page +@cindex page ejection +@cindex ejection, page +Vertical spacing has an impact on page-breaking decisions. Generally, +when a break occurs, the formatter moves the drawing position to the +next text baseline automatically. If the formatter were already writing +to the last line that would fit on the page, advancing by one vee would +place the next text baseline off the page. Rather than let that happen, +@code{roff} formatters instruct the output driver to eject the page, +start a new one, and again set the drawing position to one vee below the +page top; this is a @dfn{page break}. + +When the last line of input text corresponds to the last output line +that fits on the page, the break caused by the end of input will also +break the page, producing a useless blank one. Macro packages keep +users from having to confront this difficulty by setting ``traps'' +(@pxref{Traps}); moreover, all but the simplest page layouts tend to +have headers and footers, or at least bear vertical margins larger than +one vee. + + +@c ===================================================================== +@c TODO: Add a section here about interpolations and input processing. +@c +@c We need to level up the reader's macro brain from reasoning about +@c interpolation at the scope of input lines to interpolations _within_ +@c lines. It is also a good time to introduce the \n and \* escape +@c sequences to avoid painful, "WTF"-producing forward references later. +@c Some materal from groff_mm(7) might be adaptable to this purpose. +@c +@c Earlier material from @Defesc{\\n}: +@c "This means that the value of the register is expanded in place while +@c GNU @code{troff} is parsing the input line. Nested assignments (also +@c called indirect assignments) are possible." +@c +@c We can probably drop the term "indirect assignments"; there's nothing +@c special about these--they are a consequence of *roffs' left-to-right +@c parsing and they apply to escape sequences in general. +@c ===================================================================== + +@c BEGIN Keep (roughly) parallel with section "Measurements" of +@c groff(7). +@node Measurements, Numeric Expressions, Text, GNU troff Reference +@section Measurements +@cindex measurements +@cindex scaling indicator +@cindex indicator, scaling + +@cindex units of measurement +@cindex measurement units +The formatter sometimes requires the input of numeric parameters to +specify measurements. These are specified as integers or decimal +fractions with an optional @dfn{scaling unit} suffixed. A scaling unit +is a letter that immediately follows the last digit of a number. Digits +after the decimal point are optional. Measurement expressions include +@samp{10.5p}, @samp{11i}, and @samp{3.c}. + +@cindex basic units, conversion to +@cindex units, basic, conversion to +@cindex conversion to basic units +Measurements are scaled by the scaling unit and stored internally (with +any fractional part discarded) in basic units. +@cindex device resolution, obtaining in the formatter +@cindex resolution, device, obtaining in the formatter +The device resolution can therefore be obtained by storing a value of +@samp{1i} to a register. The only constraint on the basic unit is that +it is at least as small as any other unit. +@c That's a fib. A device resolution of around 2^31 would surely also +@c cause problems. But nobody does that. + +@table @code +@cindex basic scaling unit (@code{u}) +@cindex @code{u} scaling unit +@cindex unit, scaling, @code{u} +@cindex scaling unit @code{u} +@item u +Basic unit. + +@item i +@cindex inch scaling unit (@code{i}) +@cindex @code{i} scaling unit +@cindex unit, scaling, @code{i} +@cindex scaling unit @code{i} +Inch; defined as 2.54@tie{}centimeters. + +@item c +@cindex centimeter scaling unit (@code{c}) +@cindex @code{c} scaling unit +@cindex unit, scaling, @code{c} +@cindex scaling unit @code{c} +Centimeter; a centimeter is about 0.3937@tie{}inches. + +@item p +@cindex point scaling unit (@code{p}) +@cindex @code{p} scaling unit +@cindex unit, scaling, @code{p} +@cindex scaling unit @code{p} +Point; a typesetter's unit used for measuring type size. +There are 72@tie{}points to an inch. + +@item P +@cindex pica scaling unit (@code{P}) +@cindex @code{P} scaling unit +@cindex unit, scaling, @code{P} +@cindex scaling unit @code{P} +Pica; another typesetter's unit. There are 6@tie{}picas to an inch and +12@tie{}points to a pica. + +@item s +@itemx z +@xref{Using Fractional Type Sizes}, for a discussion of these units. + +@item f +GNU @code{troff} defines this unit to scale decimal fractions in the +interval [0, 1] to 16-bit unsigned integers. It multiplies a quantity +by 65,536. @xref{Colors}, for usage. +@end table + +The magnitudes of other scaling units depend on the text formatting +parameters in effect. These are useful when specifying measurements +that need to scale with the typeface or vertical spacing. + +@table @code +@item m +@cindex em scaling unit (@code{m}) +@cindex @code{m} scaling unit +@cindex unit, scaling, @code{m} +@cindex scaling unit @code{m} +Em; an em is equal to the current type size in points. It is named thus +because it is approximately the width of the letter@tie{}@samp{M}. + +@item n +@cindex en scaling unit (@code{n}) +@cindex @code{n} scaling unit +@cindex unit, scaling, @code{n} +@cindex scaling unit @code{n} +En; an en is one-half em. + +@item v +@cindex vertical space unit (@code{v}) +@cindex space, vertical, unit (@code{v}) +@cindex vee scaling unit (@code{v}) +@cindex @code{v} scaling unit +@cindex unit, scaling, @code{v} +@cindex scaling unit @code{v} +Vee; recall @ref{Page Geometry}. + +@item M +@cindex @code{M} scaling unit +@cindex unit, scaling, @code{M} +@cindex scaling unit @code{M} +Hundredth of an em. +@end table + +@menu +* Motion Quanta:: +* Default Units:: +@end menu +@c END Keep (roughly) parallel with section "Measurements" of groff(7). + +@c --------------------------------------------------------------------- + +@node Motion Quanta, Default Units, Measurements, Measurements +@subsection Motion Quanta +@cindex motion quanta +@cindex quanta, motion + +@c BEGIN Keep (roughly) parallel with subsection "Motion quanta" of +@c groff(7). +An output device's basic unit @code{u} is not necessarily its smallest +addressable length; @code{u} can be smaller to avoid problems with +integer roundoff. The minimum distances that a device can work with in +the horizontal and vertical directions are termed its @dfn{motion +quanta}. Measurements are rounded to applicable motion quanta. +Half-quantum fractions round toward zero. + +@cindex horizontal motion quantum register (@code{.H}) +@cindex motion quantum, horizontal, register (@code{.H}) +@cindex horizontal resolution register (@code{.H}) +@cindex resolution, horizontal, register (@code{.H}) +@DefregList {.H} +@DefregListEndx {.V} +These read-only registers interpolate the horizontal and vertical motion +quanta, respectively, of the output device in basic units. +@endDefreg + +For example, we might draw short baseline rules on a terminal device as +follows. @xref{Drawing Geometric Objects}. + +@Example +.tm \n[.H] + @error{} 24 +.nf +\l'36u' 36u +\l'37u' 37u + @result{} _ 36u + @result{} __ 37u +@endExample +@c END Keep (roughly) parallel with subsection "Motion quanta" of +@c groff(7). + +@c --------------------------------------------------------------------- + +@node Default Units, , Motion Quanta, Measurements +@subsection Default Units +@cindex default units +@cindex units, default + +@c BEGIN Keep (roughly) parallel with subsection "Default units" of +@c groff(7). +A general-purpose register (one created or updated with the @code{nr} +request; see @pxref{Registers}) is implicitly dimensionless, or reckoned +in basic units if interpreted in a measurement context. But it is +convenient for many requests and escape sequences to infer a scaling +unit for an argument if none is specified. An explicit scaling unit +(not after a closing parenthesis) can override an undesirable default. +Effectively, the default unit is suffixed to the expression if a scaling +unit is not already present. GNU @code{troff}'s use of integer +arithmetic should also be kept in mind (@pxref{Numeric Expressions}). + +The @code{ll} request interprets its argument in ems by default. +Consider several attempts to set a line length of 3.5@tie{}inches when +the type size is 10@tie{}points on a terminal device with a resolution +of 240 basic units and horizontal motion quantum of 24. Some +expressions become zero; the request clamps them to that quantum. + +@Example +.ll 3.5i \" 3.5i (= 840u) +.ll 7/2 \" 7u/2u -> 3u -> 3m -> 0, clamped to 24u +.ll (7 / 2)u \" 7u/2u -> as above +.ll 7/2i \" 7u/2i -> 7u/480u -> 0 -> as above +.ll 7i/2 \" 7i/2u -> 1680u/2m -> 1680u/24u -> 35u +.ll 7i/2u \" 3.5i (= 840u) +@endExample + +@noindent +@cindex measurements, specifying safely +The safest way to specify measurements is to attach a scaling unit. To +multiply or divide by a dimensionless quantity, use @samp{u} as its +scaling unit. +@c END Keep (roughly) parallel with subsection "Default units" of +@c groff(7). + + +@c ===================================================================== + +@c BEGIN Keep (roughly) parallel with section "Numeric expressions" of +@c groff(7). +@node Numeric Expressions, Identifiers, Measurements, GNU troff Reference +@section Numeric Expressions +@cindex numeric expressions +@cindex expressions, numeric + +A @dfn{numeric expression} evaluates to an integer:@: it can be as +simple as a literal @samp{0} or it can be a complex sequence of register +and string interpolations interleaved with measurements and operators. + +GNU @code{troff} provides a set of mathematical and logical operators +familiar to programmers---as well as some unusual ones---but supports +only integer arithmetic.@footnote{Provision is made for interpreting and +reporting decimal fractions in certain cases.} The internal data type +used for computing results is usually a 32-bit signed integer, which +suffices to represent magnitudes within a range of ą2 +billion.@footnote{If that's not enough, see the @cite{groff_tmac@r{(5)}} +man page for the @file{62bit.tmac} macro package.} + +@cindex arithmetic operators +@cindex operators, arithmetic +@cindex truncating division +@cindex addition +@cindex subtraction +@cindex multiplication +@cindex division, truncating +@cindex modulus +@opindex + +@opindex - +@opindex * +@opindex / +@opindex % +Arithmetic infix operators perform a function on the numeric expressions +to their left and right; they are @code{+} (addition), @code{-} +(subtraction), @code{*} (multiplication), @code{/} (truncating +division), and @code{%} (modulus). @dfn{Truncating division} rounds to +the integer nearer to zero, no matter how large the fractional portion. +Overflow and division (or modulus) by zero are errors and abort +evaluation of a numeric expression. +@cindex unary arithmetic operators +@cindex operators, unary arithmetic +@cindex negation +@cindex assertion (arithmetic operator) +@opindex - +@opindex + +@cindex @code{if} request, and the @samp{!} operator +@cindex @code{while} request, and the @samp{!} operator + +Arithmetic unary operators operate on the numeric expression to their +right; they are @code{-} (negation) and @code{+} (assertion---for +completeness; it does nothing). The unary minus must often be used +with parentheses to avoid confusion with the decrementation operator, +discussed below. + +Observe the rounding behavior and effect of negative operands on the +modulus and truncating division operators. + +@Example +.nr T 199/100 +.nr U 5/2 +.nr V (-5)/2 +.nr W 5/-2 +.nr X 5%2 +.nr Y (-5)%2 +.nr Z 5%-2 +T=\n[T] U=\n[U] V=\n[V] W=\n[W] X=\n[X] Y=\n[Y] Z=\n[Z] + @result{} T=1 U=2 V=-2 W=-2 X=1 Y=-1 Z=1 +@endExample + +@noindent +The sign of the modulus of operands of mixed signs is determined by the +sign of the first. Division and modulus operators satisfy the following +property:@: given a dividend@tie{}@var{a} and a divisor@tie{}@var{b}, a +quotient@tie{}@var{q} formed by @samp{(a / b)} and a +remainder@tie{}@var{r} by @samp{(a % b)}, then @math{qb + r = a}. + +@cindex scaling operator +@cindex operator, scaling +@opindex ; +GNU @code{troff}'s scaling operator, used with parentheses as +@code{(@var{c};@var{e})}, evaluates a numeric expression@tie{}@var{e} +using@tie{}@var{c} as the default scaling unit. If @var{c} is omitted, +scaling units are ignored in the evaluation of@tie{}@var{e}. This +operator can save typing by avoiding the attachment of scaling units to +every operand out of caution. Your macros can select a sensible default +unit in case the user neglects to supply one. + +@Example +.\" Indent by amount given in first argument; assume ens. +.de Indent +. in (n;\\$1) +.. +@endExample + +@noindent +Without the scaling operator, the foregoing macro would, if called with +a unitless argument, cause indentation by the @code{in} request's +default scaling unit (ems). The result would be twice as much +indentation as expected. + +@cindex extremum operators (@code{>?}, @code{?}, @code{? +@opindex ?} (maximum) and @code{ +@opindex >= +@opindex <= +@opindex = +@opindex == +Comparison operators comprise @code{<} (less than), @code{>} (greater +than), @code{<=} (less than or equal), @code{>=} (greater than or +equal), and @code{=} (equal). @code{==} is a synonym for @code{=}. +When evaluated, a comparison is replaced with @samp{0} if it is false +and @samp{1} if true. In the @code{roff} language, positive values are +true, others false. + +@cindex logical operators +@cindex operators, logical +@cindex logical ``and'' operator +@cindex logical conjunction operator +@cindex logical ``or'' operator +@cindex logical disjunction operator +@opindex & +@ifnotinfo +@opindex : +@end ifnotinfo +@ifinfo +@opindex @r{} +@end ifinfo +We can operate on truth values with the logical operators @code{&} +(logical conjunction or ``and'') and @code{:} (logical disjunction or +``or''). They evaluate as comparison operators do. + +@opindex ! +@cindex complementation, logical +@cindex logical complementation operator +@cindex logical not, limitation in expression +@cindex expression, limitation of logical not in +A logical complementation (``not'') operator, @code{!}, works only +within @code{if}, @code{ie}, and @code{while} requests. +@c This is worded to avoid implying that the operator doesn't apply +@c to conditional expressions in general, albeit without mentioning them +@c because they're out of scope. +Furthermore, @code{!} is recognized only at the beginning of a numeric +expression not contained by another numeric expression. In other words, +it must be the ``outermost'' operator. Including it elsewhere in the +expression produces a warning in the @samp{number} category +(@pxref{Warnings}), and its expression evaluates false. This +unfortunate limitation maintains compatibility with @acronym{AT&T} +@code{troff}. Test a numeric expression for falsity by +comparing it to a false value.@footnote{@xref{Conditionals and Loops}.} + +@Example +.nr X 1 +.nr Y 0 +.\" This does not work as expected. +.if (\n[X])&(!\n[Y]) .nop A: X is true, Y is false +. +.\" Use this construct instead. +.if (\n[X])&(\n[Y]<=0) .nop B: X is true, Y is false + @error{} warning: expected numeric expression, got '!' + @result{} B: X is true, Y is false +@endExample + +@cindex parentheses +@cindex order of evaluation in expressions +@cindex expression, order of evaluation +@opindex ( +@opindex ) +The @code{roff} language has no operator precedence:@: expressions are +evaluated strictly from left to right, in contrast to schoolhouse +arithmetic. Use parentheses @code{(} @code{)} to impose a desired +precedence upon subexpressions. + +@Example +.nr X 3+5*4 +.nr Y (3+5)*4 +.nr Z 3+(5*4) +X=\n[X] Y=\n[Y] Z=\n[Z] + @result{} X=32 Y=32 Z=23 +@endExample + +@cindex @code{+}, and page motion +@cindex @code{-}, and page motion +@cindex motion operators +@cindex operators, motion +@opindex + @r{(unary)} +@opindex - @r{(unary)} +For many requests and escape sequences that cause motion on the page, +the unary operators @code{+} and @code{-} work differently when leading +a numeric expression. They then indicate a motion relative to the +drawing position:@: positive is down in vertical contexts, right in +horizontal ones. + +@cindex @code{bp} request, using @code{+} and@tie{}@code{-} with +@cindex @code{in} request, using @code{+} and@tie{}@code{-} with +@cindex @code{ll} request, using @code{+} and@tie{}@code{-} with +@cindex @code{lt} request, using @code{+} and@tie{}@code{-} with +@cindex @code{nm} request, using @code{+} and@tie{}@code{-} with +@cindex @code{nr} request, using @code{+} and@tie{}@code{-} with +@cindex @code{pl} request, using @code{+} and@tie{}@code{-} with +@cindex @code{pn} request, using @code{+} and@tie{}@code{-} with +@cindex @code{po} request, using @code{+} and@tie{}@code{-} with +@cindex @code{ps} request, using @code{+} and@tie{}@code{-} with +@cindex @code{pvs} request, using @code{+} and@tie{}@code{-} with +@cindex @code{rt} request, using @code{+} and@tie{}@code{-} with +@cindex @code{ti} request, using @code{+} and@tie{}@code{-} with +@cindex @code{\H}, using @code{+} and@tie{}@code{-} with +@cindex @code{\R}, using @code{+} and@tie{}@code{-} with +@cindex @code{\s}, using @code{+} and@tie{}@code{-} with +@code{+} and @code{-} are also treated differently by the following +requests and escape sequences:@: @code{bp}, @code{in}, @code{ll}, +@code{lt}, @code{nm}, @code{nr}, @code{pl}, @code{pn}, @code{po}, +@code{ps}, @code{pvs}, @code{rt}, @code{ti}, @code{\H}, @code{\R}, and +@code{\s}. Here, leading plus and minus signs serve as incrementation +and decrementation operators, respectively. To negate an expression, +subtract it from zero or include the unary minus in parentheses with its +argument. @xref{Setting Registers}, for examples. + +@opindex | +@cindex @code{|}, and page motion +@cindex absolute @slanted{(sic)} position operator (@code{|}) +@cindex position, absolute @slanted{(sic)} operator (@code{|}) +@cindex boundary-relative motion operator (@code{|}) +@c "motion" and "operators" already indexed above +A leading @code{|} operator indicates a motion relative not to the +drawing position but to a boundary. For horizontal motions, the +measurement specifies a distance relative to a drawing position +corresponding to the beginning of the @emph{input} line. By default, +tab stops reckon movements in this way. Most escape sequences do not; +@c XXX: Which ones do? +@code{|} tells them to do so. + +@Example +Mind the \h'1.2i'gap. +.br +Mind the \h'|1.2i'gap. +.br +Mind the +\h'|1.2i'gap. +@c 13 spaces, 4 spaces, 13 spaces + @result{} Mind the gap. + @result{} Mind the gap. + @result{} Mind the gap. +@endExample + +One use of this feature is to define macros whose scope is limited to +the output they format. + +@Example +.\" underline word $1 with trailing punctuation $2 +.de Underline +. nop \\$1\l'|0\[ul]'\\$2 +.. +Typographical emphasis is best used +.Underline sparingly . +@endExample + +@noindent +In the above example, @samp{|0} specifies a negative motion from the +current position (at the end of the argument just emitted, @code{\$1}) +to the beginning of the input line. Thus, the @code{\l} escape sequence +in this case draws a line from right to left. A macro call occurs at +the beginning of an input line;@footnote{Control structure syntax +creates an exception to this rule, but is designed to remain useful:@: +recalling our example, @samp{.if 1 .Underline this} would underline only +``this'', precisely. @xref{Conditionals and Loops}.} if the @code{|} +operator were omitted, then the underline would be drawn at zero +distance from the current position, producing device-dependent, and +likely undesirable, results. On the @samp{ps} output device, it +underlines the period. + +For vertical motions, the @code{|} operator specifies a distance from +the first text baseline on the page or in the current +diversion,@footnote{@xref{Diversions}.} using the current vertical +spacing. + +@Example +A +.br +B \Z'C'\v'|0'D + @result{} A D + @result{} B C +@endExample + +In the foregoing example, we've used the @code{\Z} escape sequence +(@pxref{Page Motions}) to restore the drawing position after formatting +@samp{C}, then moved vertically to the first text baseline on the page. + +@Defesc {\\B, @code{'}, anything, @code{'}} +@cindex numeric expression, valid +@cindex valid numeric expression +Interpolate@tie{}1 if @var{anything} is a valid numeric expression, +and@tie{}0 otherwise. The delimiter need not be a neutral apostrophe; +see @ref{Delimiters}. +@endDefesc + +You might use @code{\B} along with the @code{if} request to filter out +invalid macro or string arguments. @xref{Conditionals and Loops}. + +@Example +.\" Indent by amount given in first argument; assume ens. +.de Indent +. if \B'\\$1' .in (n;\\$1) +.. +@endExample + +A register interpolated as an operand in a numeric expression must have +an Arabic format; luckily, this is the default. @xref{Assigning +Register Formats}. + +@cindex space characters, in expressions +@cindex expressions, and space characters +Because spaces separate arguments to requests, spaces are not allowed in +numeric expressions unless the (sub)expression containing them is +surrounded by parentheses. @xref{Invoking Requests}, and +@ref{Conditionals and Loops}. + +@Example +.nf +.nr a 1+2 + 2+1 +\na + @error{} expected numeric expression, got a space + @result{} 3 +.nr a 1+(2 + 2)+1 +\na + @result{} 6 +@endExample + +The @code{nr} request (@pxref{Setting Registers}) expects its second and +optional third arguments to be numeric expressions; a bare @code{+} does +not qualify, so our first attempt got a warning. +@c END Keep (roughly) parallel with section "Numeric expressions" of +@c groff(7). + + +@c ===================================================================== + +@c BEGIN Keep (roughly) parallel with section "Identifiers" of groff(7). +@node Identifiers, Formatter Instructions, Numeric Expressions, GNU troff Reference +@section Identifiers +@cindex identifiers + +An @dfn{identifier} labels a GNU @code{troff} datum such as a register, +name (macro, string, or diversion), typeface, color, special character, +character class, environment, or stream. Valid identifiers consist of +one or more ordinary characters. +@cindex ordinary character +@cindex character, ordinary +An @slanted{ordinary character} is an input character that is not the +escape character, a leader, tab, newline, or invalid as GNU @code{troff} +input. + +@c XXX: We might move this discussion earlier since it is applicable to +@c troff input in general, and include a reference to the `trin` +@c request. +@cindex invalid input characters +@cindex input characters, invalid +@cindex characters, invalid input +@cindex Unicode +Invalid input characters are a subset of control characters (from the +sets ``C0 Controls'' and ``C1 Controls'' as Unicode describes them). +When GNU @code{troff} encounters one in an identifier, it produces a +warning in category @samp{input} (@pxref{Warnings}). They are removed +during interpretation: an identifier @samp{foo}, followed by an invalid +character and then @samp{bar}, is processed as @samp{foobar}. + +On a machine using the ISO 646, 8859, or 10646 character encodings, +invalid input characters are @code{0x00}, @code{0x08}, @code{0x0B}, +@code{0x0D}--@code{0x1F}, and @code{0x80}--@code{0x9F}. On an +@acronym{EBCDIC} host, they are @code{0x00}--@code{0x01}, @code{0x08}, +@code{0x09}, @code{0x0B}, @code{0x0D}--@code{0x14}, +@code{0x17}--@code{0x1F}, and +@code{0x30}--@code{0x3F}.@footnote{Historically, control characters like +ASCII STX, ETX, and BEL (@key{Control+B}, @key{Control+C}, and +@key{Control+G}) have been observed in @code{roff} documents, +particularly in macro packages employing them as delimiters with the +output comparison operator to try to avoid collisions with the content +of arbitrary user-supplied parameters (@pxref{Operators in +Conditionals}). We discourage this expedient; in GNU @code{troff} it is +unnecessary (outside of compatibility mode) because delimited arguments +are parsed at a different input level than the surrounding context. +@xref{Implementation Differences}.} Some of these code points are used +by GNU @code{troff} internally, making it non-trivial to extend the +program to accept UTF-8 or other encodings that use characters from +these ranges.@footnote{Consider what happens when a C1 control +@code{0x80}--@code{0x9F} is necessary as a continuation byte in a UTF-8 +sequence.} + +Thus, the identifiers @samp{br}, @samp{PP}, @samp{end-list}, +@samp{ref*normal-print}, @samp{|}, @samp{@@_}, and @samp{!"#$%'()*+,-./} +are all valid. Discretion should be exercised to prevent confusion. +Identifiers starting with @samp{(} or @samp{[} require care. + +@Example +.nr x 9 +.nr y 1 +.nr (x 2 +.nr [y 3 +.nr sum1 (\n(x + \n[y]) + @error{} a space character is not allowed in an escape + @error{} sequence parameter +A:2+3=\n[sum1] +.nr sum2 (\n((x + \n[[y]) +B:2+3=\n[sum2] +.nr sum3 (\n[(x] + \n([y) +C:2+3=\n[sum3] + @result{} A:2+3=1 B:2+3=5 C:2+3=5 +@endExample + +@cindex @code{]}, as part of an identifier +@noindent +An identifier with a closing bracket (@samp{]}) in its name can't be +accessed with bracket-form escape sequences that expect an identifier as +a parameter. For example, @samp{\[foo]]} accesses the glyph @samp{foo}, +followed by @samp{]} in whatever the surrounding context is, whereas +@samp{\C'foo]'} formats a glyph named @samp{foo]}. Similarly, the +identifier @samp{(} can't be interpolated @emph{except} with bracket +forms. + +@cindex @code{refer}, and macro names starting with @code{[} or @code{]} +@cindex @code{[}, macro names starting with, and @code{refer} +@cindex @code{]}, macro names starting with, and @code{refer} +@cindex macro names, starting with @code{[} or @code{]}, and @code{refer} +If you begin a macro, string, or diversion name with either of the +characters @samp{[} or @samp{]}, you foreclose use of the @code{grefer} +preprocessor, which recognizes @samp{.[} and @samp{.]} as bibliographic +reference delimiters. + +@Defesc {\\A, @code{'}, anything, @code{'}} +Interpolate@tie{}1 if @var{anything} is a valid identifier, and@tie{}0 +otherwise. The delimiter need not be a neutral apostrophe; see +@ref{Delimiters}. Because invalid input characters are removed (see +above), invalid identifiers are empty or contain spaces, tabs, or +newlines. + +You can employ @code{\A} to validate a macro argument before using it to +construct another escape sequence or identifier. + +@Example +.\" usage: .init-coordinate-pair name val1 val2 +.\" Create a coordinate pair where name!x=val1 and +.\" name!y=val2. +.de init-coordinate-pair +. if \A'\\$1' \@{\ +. if \B'\\$2' .nr \\$1!x \\$2 +. if \B'\\$3' .nr \\$1!y \\$3 +. \@} +.. +.init-coordinate-pair center 5 10 +The center is at (\n[center!x], \n[center!y]). +.init-coordinate-pair "poi@arrow{}nt" trash garbage \" ignored +.init-coordinate-pair point trash garbage \" ignored + @result{} The center is at (5, 10). +@endExample + +@noindent +In this example, we also validated the numeric arguments; the registers +@samp{point!x} and @samp{point!y} remain undefined. @xref{Numeric +Expressions} for the @code{\B} escape sequence. +@endDefesc + +@cindex undefined identifiers +@cindex identifiers, undefined +How GNU @code{troff} handles the interpretation of an undefined +identifier depends on the context. There is no way to invoke an +undefined request; such syntax is interpreted as a macro call instead. +If the identifier is interpreted as a string, macro, or diversion, GNU +@code{troff} emits a warning in category @samp{mac}, defines it as +empty, and interpolates nothing. If the identifier is interpreted as a +register, GNU @code{troff} emits a warning in category @samp{reg}, +initializes it to zero, and interpolates that value. @xref{Warnings}, +@ref{Interpolating Registers}, and @ref{Strings}. Attempting to use an +undefined typeface, special character, color, character class, +environment, or stream generally provokes an error diagnostic. + +@need 1000 +@cindex name space, common, of macros, diversions, and strings +@cindex common name space of macros, diversions, and strings +@cindex macros, shared name space with strings and diversions +@cindex strings, shared name space with macros and diversions +@cindex diversions, shared name space with macros and strings +Identifiers for requests, macros, strings, and diversions share one name +space; special characters and character classes another. No other +object types do. + +@Example +.de xxx +. nop foo +.. +@c . slack line for pagination management +.di xxx +bar +.br +.di +. +.xxx + @result{} bar +@endExample + +@noindent +The foregoing example shows that GNU @code{troff} reuses the identifier +@samp{xxx}, changing it from a macro to a diversion. No warning is +emitted, and the previous contents of @samp{xxx} are lost. +@c END Keep (roughly) parallel with section "Identifiers" of groff(7). + + +@c ===================================================================== + +@node Formatter Instructions, Registers, Identifiers, GNU troff Reference +@section Formatter Instructions +@cindex formatter instructions +@cindex instructing the formatter + +To support documents that require more than filling, automatic line +breaking and hyphenation, adjustment, and supplemental inter-sentence +space, the @code{roff} language offers two means of embedding +instructions to the formatter. + +@cindex request +One is a @dfn{request}, which begins with a control character and takes +up the remainder of the input line. Requests often perform relatively +large-scale operations such as setting the page length, breaking the +line, or starting a new page. They also conduct internal operations +like defining macros. + +@cindex escape sequence +@cindex sequence, escape +The other is an @dfn{escape sequence}, which begins with the escape +character and can be embedded anywhere in the input, even in arguments +to requests and other escape sequences. Escape sequences interpolate +special characters, strings, or registers, and handle comparatively +minor formatting tasks like sub- and superscripting. + +Some operations, such as font selection and type size alteration, are +available via both requests and escape sequences. + +@menu +* Control Characters:: +* Invoking Requests:: +* Calling Macros:: +* Using Escape Sequences:: +* Delimiters:: +@end menu + +@c --------------------------------------------------------------------- + +@node Control Characters, Invoking Requests, Formatter Instructions, Formatter Instructions +@subsection Control Characters +@cindex control characters +@cindex configuring control characters +@cindex changing control characters + +The mechanism of using @code{roff}'s control characters to invoke +requests and call macros was introduced in @ref{Requests and Macros}. +Control characters are recognized only at the beginning of an input +line, or at the beginning of the branch of a control structure request; +see @ref{Conditionals and Loops}. + +A few requests cause a break implicitly; use the no-break control +character to prevent the break. Break suppression is its sole +behavioral distinction. Employing the no-break control character to +invoke requests that don't cause breaks is harmless but poor style. +@xref{Manipulating Filling and Adjustment}. + +@cindex control character, changing (@code{cc}) +@cindex character, control, changing (@code{cc}) +@cindex no-break control character, changing (@code{c2}) +@cindex character, no-break control, changing (@code{c2}) +@cindex control character, no-break, changing (@code{c2}) +The control @samp{.} and no-break control @samp{'} characters can each +be changed to any ordinary character@footnote{Recall @ref{Identifiers}.} +with the @code{cc} and @code{c2} requests, respectively. + +@Defreq {cc, [@Var{o}]} +Recognize the ordinary character@tie{}@var{o} as the control character. +If@tie{}@var{o} is absent or invalid, the default control character +@samp{.} is selected. The identity of the control character is +associated with the environment (@pxref{Environments}). +@endDefreq + +@Defreq {c2, [@Var{o}]} +Recognize the ordinary character@tie{}@var{o} as the no-break control +character. If@tie{}@var{o} is absent or invalid, the default no-break +control character @samp{'} is selected. The identity of the no-break +control character is associated with the environment +(@pxref{Environments}). +@endDefreq + +When writing a macro, you might wish to know which control character was +used to call it. + +@Defreg {.br} +This read-only register interpolates@tie{}1 if the currently executing +macro was called using the normal control character and@tie{}0 +otherwise. If a macro is interpolated as a string, the @code{.br} +register's value is inherited from the context of the string +interpolation. @xref{Strings}. + +@cindex intercepting requests +@cindex requests, intercepting +@cindex modifying requests +@cindex requests, modifying +Use this register to reliably intercept requests that imply breaks. + +@Example +.als bp*orig bp +.de bp +. ie \\n[.br] .bp*orig +. el 'bp*orig +.. +@endExample + +Testing the @code{.br} register outside of a macro definition makes no +sense. +@endDefreg + +@c --------------------------------------------------------------------- + +@c BEGIN Keep (roughly) parallel with section "Requests" of groff(7). +@node Invoking Requests, Calling Macros, Control Characters, Formatter Instructions +@subsection Invoking Requests +@cindex invoking requests +@cindex requests, invoking + +A control character is optionally followed by tabs and/or spaces and +then an identifier naming a request or macro. The invocation of an +unrecognized request is interpreted as a macro call. Defining a macro +with the same name as a request replaces the request. Deleting a +request name with the @code{rm} request makes it unavailable. The +@code{als} request can alias requests, permitting them to be wrapped or +non-destructively replaced. @xref{Strings}. + +@cindex request arguments +@cindex arguments to requests +@cindex tabs, and macro arguments +@cindex macro arguments, and tabs +@cindex arguments to macros, and tabs +@cindex tabs, and request arguments +@cindex request arguments, and tabs +@cindex arguments to requests, and tabs +There is no inherent limit on argument length or quantity. Most +requests take one or more arguments, and ignore any they do not expect. +A request may be separated from its arguments by tabs or spaces, but +only spaces can separate an argument from its successor. Only one +between arguments is necessary; any excess is ignored. GNU @code{troff} +does not allow tabs for argument separation.@footnote{In compatibility +mode, a space is not necessary after a request or macro name of two +characters' length. Also, Plan@tie{}9 @code{troff} allows tabs to +separate arguments.} + +Generally, a space @emph{within} a request argument is not relevant, not +meaningful, or is supported by bespoke provisions, as with the @code{tl} +request's delimiters (@pxref{Page Layout}). Some requests, like +@code{ds}, interpret the remainder of the control line as a single +argument. @xref{Strings}. + +@need 1000 +@cindex structuring source code of documents or macro packages +@cindex documents, structuring the source of +@cindex macro package, structuring the source of +@cindex package, package, structuring the source of +@cindex indentation, of @code{roff} source code +Spaces and tabs immediately after a control character are ignored. +Commonly, authors structure the source of documents or macro files with +them. + +@Example +.de center +. if \\n[.br] \ +. br +. ce \\$1 +.. +. +. +.de right-align +.@arrow{}if \\n[.br] \ +.@arrow{}@arrow{}br +.@arrow{}rj \\$1 +.. +@endExample + +@cindex blank line trap (@code{blm}) +@cindex blank line macro (@code{blm}) +If you assign an empty blank line trap, you can separate macro +definitions (or any input lines) with blank lines. + +@Example +.de do-nothing +.. +.blm do-nothing \" activate blank line trap + +.de center +. if \\n[.br] \ +. br +. ce \\$1 +.. + + +.de right-align +.@arrow{}if \\n[.br] \ +.@arrow{}@arrow{}br +.@arrow{}rj \\$1 +.. + +.blm \" deactivate blank line trap +@endExample + +@xref{Blank Line Traps}. +@c END Keep (roughly) parallel with section "Requests" of groff(7). + +@c --------------------------------------------------------------------- + +@need 1000 +@node Calling Macros, Using Escape Sequences, Invoking Requests, Formatter Instructions +@subsection Calling Macros +@cindex calling macros +@cindex macro arguments +@cindex arguments to macros + +If a macro of the desired name does not exist when called, it is +created, assigned an empty definition, and a warning in category +@samp{mac} is emitted. Calling an undefined macro @emph{does} end a +macro definition naming it as its end macro (@pxref{Writing Macros}). + +@cindex spaces, in a macro argument +To embed spaces @emph{within} a macro argument, enclose the argument in +neutral double quotes @code{"}. Horizontal motion escape sequences are +sometimes a better choice for arguments to be formatted as text. + +Consider calls to a hypothetical section heading macro @samp{uh}. + +@Example +.uh The Mouse Problem +.uh "The Mouse Problem" +.uh The\~Mouse\~Problem +.uh The\ Mouse\ Problem +@endExample + +@cindex @code{\~}, difference from @code{\@key{SP}} +@cindex @code{\@key{SP}}, difference from @code{\~} +@noindent +The first line calls @code{uh} with three arguments: @samp{The}, +@samp{Mouse}, and @samp{Problem}. The remainder call the @code{uh} +macro with one argument, @samp{The Mouse Problem}. The last solution, +using escaped spaces, can be found in documents prepared for +@acronym{AT&T} @code{troff}. It can cause surprise when text is +adjusted, because @code{\@key{SP}} inserts a @emph{fixed-width}, +non-breaking space. GNU @code{troff}'s @code{\~} escape sequence +inserts an adjustable, non-breaking space.@footnote{@code{\~} is fairly +portable; see @ref{Other Differences}.} + +@cindex @code{"}, embedding in a macro argument +@cindex double quote, embedding in a macro argument +@cindex @code{\}, embedding in a macro argument +@cindex backslash, embedding in a macro argument +The foregoing raises the question of how to embed neutral double quotes +or backslashes in macro arguments when @emph{those} characters are +desired as literals. In GNU @code{troff}, the special character escape +sequence @code{\[rs]} produces a backslash and @code{\[dq]} a neutral +double quote. + +In GNU @code{troff}'s @acronym{AT&T} compatibility mode, these +characters remain available as @code{\(rs} and @code{\(dq}, +respectively. @acronym{AT&T} @code{troff} did not consistently define +these special characters, +@c It seems that AT&T troff never recognized \(rs, though DWB 3.3 +@c defined \(bs as an alias of "\" on its "Latin1" device, in +@c deliberate(?) collision with the Bell System logo identifier. It +@c also defined \(dq for several devices (pcl, Latin1, nroff, ...) along +@c with \(aq. +but its descendants can be made to support them. @xref{Device and Font +Description Files}. + +If even that is not feasible, options remain. To obtain a literal +escape character in a macro argument, you can simply type it if you +change or disable the escape character first. @xref{Using Escape +Sequences}. Otherwise, you must escape the escape character repeatedly +to a context-dependent extent. @xref{Copy Mode}. + +For the (neutral) double quote, you have recourse to an obscure +syntactical feature of @acronym{AT&T} @code{troff}. Because a double +quote can begin a macro argument, the formatter keeps track of whether +the current argument was started thus, and doesn't require a space after +the double quote that ends it.@footnote{Strictly, you can neglect to +close the last quoted macro argument, relying on the end of the control +line to do so. We consider this lethargic practice poor style.} In +the argument list to a macro, a double quote that @emph{isn't} preceded +by a space @emph{doesn't} start a macro argument. If not preceded by a +double quote that began an argument, this double quote becomes part of +the argument. Furthermore, within a quoted argument, a pair of adjacent +double quotes becomes a literal double quote. + +@Example +.de eq +. tm arg1:\\$1 arg2:\\$2 arg3:\\$3 +. tm arg4:\\$4 arg5:\\$5 arg6:\\$6 +.. \" 4 backslashes on the next line +.eq a" "b c" "de"f\\\\g" h""i "j""k" + @error{} arg1:a" arg2:b c arg3:de + @error{} arg4:f\g" arg5:h""i arg6:j"k +@endExample + +Apart from the complexity of the rules, this traditional solution has +the disadvantage that double quotes don't survive repeated argument +expansion in @acronym{AT&T} @code{troff} or GNU @code{troff}'s +compatibility mode. This can frustrate efforts to pass such arguments +intact through multiple macro calls. + +@Example +.cp 1 +.de eq +. tm arg1:\\$1 arg2:\\$2 arg3:\\$3 +. tm arg4:\\$4 arg5:\\$5 arg6:\\$6 +.. +.de xe +. eq \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 +.. \" 8 backslashes on the next line +.xe a" "b c" "de"f\\\\\\\\g" h""i "j""k" + @error{} arg1:a" arg2:b arg3:c + @error{} arg4:de arg5:f\g" arg6:h""i +@endExample + +@cindex input level +@cindex level, input +@cindex interpolation depth +@cindex depth, interpolation +Outside of compatibility mode, GNU @code{troff} doesn't exhibit this +problem because it tracks the nesting depth of interpolations. +@xref{Implementation Differences}. + +@c --------------------------------------------------------------------- + +@c BEGIN Keep (roughly) parallel with section "Using escape sequences" +@c of groff(7). +@node Using Escape Sequences, Delimiters, Calling Macros, Formatter Instructions +@subsection Using Escape Sequences +@cindex using escape sequences +@cindex escape sequences + +Whereas requests must occur on control lines, escape sequences can occur +intermixed with text and may appear in arguments to requests, macros, +and other escape sequences. +@esindex \ +An escape sequence is introduced by the escape character, a backslash +@code{\} (but see the @code{ec} request below). The next character +selects the escape's function. + +Escape sequences vary in length. Some take an argument, and of those, +some have different syntactical forms for a one-character, +two-character, or arbitrary-length argument. Others accept @emph{only} +an arbitrary-length argument. In the former scheme, a one-character +argument follows the function character immediately, an opening +parenthesis @samp{(} introduces a two-character argument (no closing +parenthesis is used), and an argument of arbitrary length is enclosed in +brackets @samp{[]}. In the latter scheme, the user selects a delimiter +character. A few escape sequences are idiosyncratic, and support both +of the foregoing conventions (@code{\s}), designate their own +termination sequence (@code{\?}), consume input until the next newline +(@code{\!}, @code{\"}, @code{\#}), or support an additional modifier +character (@code{\s} again, and @code{\n}). As with requests, use of +some escape sequences in source documents may interact poorly with a +macro package you use; consult its documentation to learn of ``safe'' +sequences or alternative facilities it provides to achieve the desired +result. + +If an escape character is followed by a character that does not +identify a defined operation, the escape character is ignored (producing +a diagnostic of the @samp{escape} warning category, which is not enabled +by default) and the following character is processed normally. + +@Example +$ groff -Tps -ww +.nr N 12 +.ds co white +.ds animal elephant +I have \fI\nN \*(co \*[animal]s,\f[] +said \P.\&\~Pseudo Pachyderm. + @error{} warning: escape character ignored before 'P' + @result{} I have @slanted{12 white elephants,} said P. Pseudo Pachyderm. +@endExample + +Escape sequence interpolation is of higher precedence than escape +sequence argument interpretation. This rule affords flexibility in +using escape sequences to construct parameters to other escape +sequences. +@c END Keep (roughly) parallel with section "Escape sequences" of +@c groff(7). + +@Example +.ds family C\" Courier +.ds style I\" oblique +Choice a typeface \f(\*[family]\*[style]wisely. + @result{} Choose a typeface @slanted{wisely.} +@endExample + +@noindent +In the above, the syntax form @samp{\f(} accepts only two characters for +an argument; the example works because the subsequent escape sequences +are interpolated before the selection escape sequence argument is +processed, and strings @code{family} and @code{style} interpolate one +character each.@footnote{The omission of spaces before the comment +escape sequences is necessary; see @ref{Strings}.} + +@c @need 1000 +The escape character is nearly always interpreted when encountered; it +is therefore desirable to have a way to interpolate it, disable it, or +change it. + +@cindex formatting the escape character (@code{\e}) +@cindex escape character, formatting (@code{\e}) +@Defesc {\\e, , , } +Interpolate the escape character. +@endDefesc + +@cindex formatting a backslash glyph (@code{\[rs]}) +@cindex backslash glyph, formatting (@code{\[rs]}) +The @code{\[rs]} special character escape sequence formats a backslash +glyph. In macro and string definitions, the input sequences @code{\\} +and @code{\E} defer interpretation of escape sequences. @xref{Copy +Mode}. + +@Defreq {eo, } +@cindex disabling @code{\} (@code{eo}) +@cindex @code{\}, disabling (@code{eo}) +Disable the escape mechanism except in copy mode. Once this request is +invoked, no input character is recognized as starting an escape +sequence in interpretation mode. +@endDefreq + +@Defreq {ec, [@Var{o}]} +@cindex escape character, changing (@code{ec}) +@cindex character, escape, changing (@code{ec}) +Recognize the ordinary character@tie{}@var{o} as the escape character. +If@tie{}@var{o} is absent or invalid, the default escape character +@samp{\} is selected. +@endDefreq + +Switching escape sequence interpretation off to define a macro and back +on afterward can obviate the need to double the escape character within +the definition. @xref{Writing Macros}. This technique is not available +if your macro needs to interpolate values at the time it is +@emph{defined}---but many do not. + +@Example +.\" simplified `BR` macro from the man(7) macro package +.eo +.de BR +. ds result \& +. while (\n[.$] >= 2) \@{\ +. as result \fB\$1\fR\$2\" +. shift 2 +. \@} +. if \n[.$] .as result \fB\$1\" +\*[result] +. rm result +. ft R +.. +.ec +@endExample + +@DefreqList {ecs, } +@DefreqListEndx {ecr, } +The @code{ecs} request stores the escape character for recall with +@code{ecr}. @code{ecr} sets the escape character to @samp{\} if none +has been saved. + +Use these requests together to temporarily change the escape character. +@endDefreq + +Using a different escape character, or disabling it, when calling macros +not under your control will likely cause errors, since GNU @code{troff} +has no mechanism to ``intern'' macros---that is, to convert a macro +definition into a form independent of its +representation.@footnote{@TeX{} does have such a mechanism.} When a +macro is called, its contents are interpreted literally. +@c XXX: all that stuff mapped into the C0 and C1 controls seems pretty +@c close to an interning mechanism to me, though... --GBR + +@c XXX: Motivation? Why are we directing the reader to these? +@c @xref{Diversions}, and @ref{Identifiers}. + +@c BEGIN Keep (roughly) parallel with subsection "Delimiters" of +@c groff(7). +@node Delimiters, , Using Escape Sequences, Formatter Instructions +@subsection Delimiters +@cindex delimiting escape sequence arguments +@cindex escape sequence argument delimiters +@cindex delimiters, for escape sequence arguments +@cindex arguments, to escape sequences, delimiting + +@cindex @code{'}, as delimiter +@cindex @code{"}, as delimiter +Some escape sequences that require parameters use delimiters. The +neutral apostrophe @code{'} is a popular choice and shown in this +document. The neutral double quote @code{"} is also commonly seen. +Letters, numerals, and leaders can be used. Punctuation characters +are likely better choices, except for those defined as infix operators +in numeric expressions; see below. + +@Example +\l'1.5i\[bu]' \" draw 1.5 inches of bullet glyphs +@endExample + +@cindex @code{\%}, as delimiter +@cindex @code{\@key{SP}}, as delimiter +@cindex @code{\|}, as delimiter +@cindex @code{\^}, as delimiter +@cindex @code{\@{}, as delimiter +@cindex @code{\@}}, as delimiter +@cindex @code{\'}, as delimiter +@cindex @code{\`}, as delimiter +@cindex @code{\-}, as delimiter +@cindex @code{\_}, as delimiter +@cindex @code{\!}, as delimiter +@cindex @code{\?}, as delimiter +@cindex @code{\)}, as delimiter +@cindex @code{\/}, as delimiter +@cindex @code{\,}, as delimiter +@cindex @code{\&}, as delimiter +@cindex @code{\:}, as delimiter +@cindex @code{\~}, as delimiter +@cindex @code{\0}, as delimiter +@cindex @code{\a}, as delimiter +@cindex @code{\c}, as delimiter +@cindex @code{\d}, as delimiter +@cindex @code{\e}, as delimiter +@cindex @code{\E}, as delimiter +@cindex @code{\p}, as delimiter +@cindex @code{\r}, as delimiter +@cindex @code{\t}, as delimiter +@cindex @code{\u}, as delimiter +The following escape sequences don't take arguments and thus are allowed +as delimiters: +@code{\@key{SP}}, @code{\%}, @code{\|}, @code{\^}, @code{\@{}, +@code{\@}}, @code{\'}, @code{\`}, @code{\-}, @code{\_}, @code{\!}, +@code{\?}, @code{\)}, @code{\/}, @code{\,}, @code{\&}, @code{\:}, +@code{\~}, @code{\0}, @code{\a}, @code{\c}, @code{\d}, @code{\e}, +@code{\E}, @code{\p}, @code{\r}, @code{\t}, and @code{\u}. However, +using them this way is discouraged; they can make the input confusing to +read. + +@cindex @code{\A}, delimiters allowed by +@cindex @code{\b}, delimiters allowed by +@cindex @code{\o}, delimiters allowed by +@cindex @code{\w}, delimiters allowed by +@cindex @code{\X}, delimiters allowed by +@cindex @code{\Z}, delimiters allowed by +@cindex newline, as delimiter +A few escape sequences, +@code{\A}, +@code{\b}, +@code{\o}, +@code{\w}, +@code{\X}, +and @code{\Z}, accept a newline as a delimiter. Newlines that serve +as delimiters continue to be recognized as input line terminators. + +@Example +A caf\o +e\(aa +in Paris + @result{} A café in Paris +@endExample + +@noindent +Use of newlines as delimiters in escape sequences is also discouraged. + +@cindex @code{\D}, delimiters allowed by +@cindex @code{\h}, delimiters allowed by +@cindex @code{\H}, delimiters allowed by +@cindex @code{\l}, delimiters allowed by +@cindex @code{\L}, delimiters allowed by +@cindex @code{\N}, delimiters allowed by +@cindex @code{\R}, delimiters allowed by +@cindex @code{\s}, delimiters allowed by +@cindex @code{\S}, delimiters allowed by +@cindex @code{\v}, delimiters allowed by +@cindex @code{\x}, delimiters allowed by +Finally, the escape sequences @code{\D}, @code{\h}, @code{\H}, +@code{\l}, @code{\L}, @code{\N}, @code{\R}, @code{\s}, @code{\S}, +@code{\v}, and @code{\x} prohibit many delimiters. + +@itemize @bullet +@item +@cindex numerals, as delimiters +@cindex digits, as delimiters +@cindex @code{.}, as delimiter +@cindex decimal point, as delimiter +@cindex dot, as delimiter +the numerals @code{0}-@code{9} and the decimal point @code{.} + +@item +@cindex operators, as delimiters +@cindex @code{+}, as delimiter +@cindex @code{-}, as delimiter +@cindex @code{/}, as delimiter +@cindex @code{*}, as delimiter +@cindex @code{%}, as delimiter +@cindex @code{<}, as delimiter +@cindex @code{>}, as delimiter +@cindex @code{=}, as delimiter +@cindex @code{&}, as delimiter +@ifnotinfo +@cindex @code{:}, as delimiter +@end ifnotinfo +@ifinfo +@cindex , as delimiter +@end ifinfo +@cindex @code{(}, as delimiter +@cindex @code{)}, as delimiter +the (single-character) operators @samp{+-/*%<>=&:()} + +@item +@cindex space character, as delimiter +@cindex tab character, as delimiter +the space and tab characters + +@item +@cindex @code{\%}, as delimiter +@cindex @code{\:}, as delimiter +@cindex @code{\@{}, as delimiter +@cindex @code{\@}}, as delimiter +@cindex @code{\'}, as delimiter +@cindex @code{\`}, as delimiter +@cindex @code{\-}, as delimiter +@cindex @code{\_}, as delimiter +@cindex @code{\!}, as delimiter +@cindex @code{\/}, as delimiter +@cindex @code{\c}, as delimiter +@cindex @code{\e}, as delimiter +@cindex @code{\p}, as delimiter +any escape sequences other than @code{\%}, @code{\:}, @code{\@{}, +@code{\@}}, @code{\'}, @code{\`}, @code{\-}, @code{\_}, @code{\!}, +@code{\/}, @code{\c}, @code{\e}, and @code{\p} +@end itemize + +Delimiter syntax is complex and flexible primarily for historical +reasons; the foregoing restrictions need be kept in mind mainly when +using @code{groff} in @acronym{AT&T} compatibility mode. GNU +@code{troff} keeps track of the nesting depth of escape sequence +interpolations, so the only characters you need to avoid using as +delimiters are those that appear in the arguments you input, not any +that result from interpolation. Typically, @code{'} works fine. +@xref{Implementation Differences}. + +@Example +$ groff -Tps +.de Mw +. nr wd \w'\\$1' +. tm "\\$1" is \\n(wd units wide. +.. +.Mw Wet'suwet'en +.Mw Wet+200i +.cp 1 \" turn on compatibility mode +.Mw Wet'suwet'en +.Mw Wet' +.Mw Wet+200i + @error{} "Wet'suwet'en" is 54740 units wide. + @error{} "Wet'+200i" is 42610 units wide. + @error{} "Wet'suwet'en" is 15860 units wide. + @error{} "Wet'" is 15860 units wide. + @error{} "Wet'+200i" is 14415860 units wide. +@endExample + +We see here that in compatibility mode, the part of the argument after +the @code{'} delimiter escapes from its context and, if nefariously +crafted, influences the computation of the @var{wd} register's value in +a surprising way. +@c END Keep (roughly) parallel with subsection " Delimiters" of +@c groff(7). + +@node Comments, Registers, Formatter Instructions, GNU troff Reference +@section Comments +@cindex comments + +One of the most common forms of escape sequence is the +comment.@footnote{This claim may be more aspirational than descriptive.} + +@Defesc {\\", , , } +Start a comment. Everything up to the next newline is ignored. + +This may sound simple, but it can be tricky to keep the comments from +interfering with the appearance of the output. +@cindex @code{ds}, @code{ds1} requests, and comments +@cindex @code{as}, @code{as1} requests, and comments +If the escape sequence is to the right of some text or a request, that +portion of the line is ignored, but spaces preceding it are processed +normally by GNU @code{troff}. This affects only the @code{ds} and +@code{as} requests and their variants. + +@cindex tabs, before comments +@cindex comments, lining up with tabs +One possibly irritating idiosyncrasy is that tabs should not be used to +vertically align comments in the source document. Tab characters are +not treated as separators between a request name and its first argument, +nor between arguments. + +@cindex undefined request +@cindex request, undefined +A comment on a line by itself is treated as a blank line, because after +eliminating the comment, that is all that remains. + +@Example +Test +\" comment +Test + @result{} Test + @result{} + @result{} Test +@endExample + +To avoid this, it is common to combine the empty request with the +comment escape sequence as @samp{.\"}, causing the input line to be +ignored. + +@cindex @code{'}, as a comment +Another commenting scheme sometimes seen is three consecutive single +quotes (@code{'''}) at the beginning of a line. This works, but GNU +@code{troff} emits a warning diagnostic (if enabled) about an undefined +macro (namely @samp{''}). +@endDefesc + +@Defesc {\\#, , , } +Start a comment; everything up to and including the next newline is +ignored. This @code{groff} extension was introduced to avoid the +problems described above. + +@Example +Test +\# comment +Test + @result{} Test Test +@endExample +@endDefesc + +@Defreq {ig, [@Var{end}]} +Ignore input until, in the current conditional block (if +any),@footnote{@xref{Conditional Blocks}.} the macro @var{end} is called +at the start of a control line, or the control line @samp{..} is +encountered if @var{end} is not specified. @code{ig} is parsed as if it +were a macro definition, but its contents are discarded, not +stored.@footnote{Exception: auto-incrementing registers defined outside +the ignored region @emph{will} be modified if interpolated with +@code{\ną} inside it. @xref{Auto-increment}.} + +@c Wrap example at 56 columns. +@Example +hand\c +.de TX +fasting +.. +.ig TX +This is part of a large block of input that has been +temporarily(?) commented out. +We can restore it simply by removing the .ig request and +the call of its end macro. +.TX +@endExample +@Example + @result{} handfasting +@endExample +@endDefreq + + +@c ===================================================================== + +@c BEGIN Keep (roughly) parallel with subsection "Registers" of +@c groff(7). +@node Registers, Manipulating Filling and Adjustment, Formatter Instructions, GNU troff Reference +@section Registers +@cindex registers + +In the @code{roff} language, numbers can be stored in @dfn{registers}. +Many built-in registers exist, supplying anything from the date to +details of formatting parameters. You can also define your own. +@xref{Identifiers}, for information on constructing a valid name for a +register. + +@menu +* Setting Registers:: +* Interpolating Registers:: +* Auto-increment:: +* Assigning Register Formats:: +* Built-in Registers:: +@end menu + +@c --------------------------------------------------------------------- + +@node Setting Registers, Interpolating Registers, Registers, Registers +@subsection Setting Registers +@cindex setting registers (@code{nr}, @code{\R}) +@cindex registers, setting (@code{nr}, @code{\R}) + +Define registers and update their values with the @code{nr} request or +the @code{\R} escape sequence. + +@DefreqList {nr, ident value} +@DefescListEndx {\\R, @code{'}, ident value, @code{'}} +Set register @var{ident} to @var{value}. If @var{ident} doesn't exist, +GNU @code{troff} creates it. In the @code{\R} escape sequence, the +delimiter need not be a neutral apostrophe; see @ref{Delimiters}. It +also does not produce an input token in GNU @code{troff}. @xref{Gtroff +Internals}. + +@Example +.nr a (((17 + (3 * 4))) % 4) +\n[a] +.\R'a (((17 + (3 * 4))) % 4)' +\n[a] + @result{} 1 1 +@endExample + +(Later, we will discuss additional forms of @code{nr} and @code{\R} that +can change a register's value after it is dereferenced but before it is +interpolated. @xref{Auto-increment}.) + +The complete transparency of @code{\R} can cause surprising effects if +you use registers like @code{.k}, which get evaluated at the time they +are accessed. + +@Example +.ll 1.6i +. +aaa bbb ccc ddd eee fff ggg hhh\R':k \n[.k]' +.tm :k == \n[:k] + @result{} :k == 126950 +. +.br +. +aaa bbb ccc ddd eee fff ggg hhh\h'0'\R':k \n[.k]' +.tm :k == \n[:k] + @result{} :k == 15000 +@endExample + +If you process this with the PostScript device (@code{-Tps}), there will +be a line break eventually after @code{ggg} in both input lines. +However, after processing the space after @code{ggg}, the partially +collected line is not overfull yet, so GNU @code{troff} continues to +collect input until it sees the space (or in this case, the newline) +after @code{hhh}. At this point, the line is longer than the line +length, and the line gets broken. + +In the first input line, since the @code{\R} escape sequence leaves no +traces, the check for the overfull line hasn't been done yet at the +point where @code{\R} gets handled, and you get a value for the +@code{.k} register that is even greater than the current line length. + +In the second input line, the insertion of @code{\h'0'} to cause a +zero-width motion forces GNU @code{troff} to check the line length, +which in turn causes the start of a new output line. Now @code{.k} +returns the expected value. +@endDefreq + +@code{nr} and @code{\R} each have two additional special forms to +increment or decrement a register. + +@DefreqList {nr, ident @t{+}@Var{value}} +@DefreqItem {nr, ident @t{-}@Var{value}} +@DefescItemx {\\R, @code{'}, ident @t{+}value, @code{'}} +@DefescListEnd {\\R, @code{'}, ident @t{-}value, @code{'}} +Increment (decrement) register @var{ident} by @var{value}. In the +@code{\R} escape sequence, the delimiter need not be a neutral +apostrophe; see @ref{Delimiters}. + +@Example +.nr a 1 +.nr a +1 +\na + @result{} 2 +@endExample + +@cindex negating register values +A leading minus sign in @var{value} is always interpreted as a +decrementation operator, not an algebraic sign. To assign a register a +negative value or the negated value of another register, you can +force GNU @code{troff} to interpret @samp{-} as a negation or minus, +rather than decrementation, operator: enclose it with its operand in +parentheses or subtract it from zero. + +@Example +.nr a 7 +.nr b 3 +.nr a -\nb +\na + @result{} 4 +.nr a (-\nb) +\na + @result{} -3 +.nr a 0-\nb +\na + @result{} -3 +@endExample + +If a register's prior value does not exist (the register was undefined), +an increment or decrement is applied as if to@tie{}0. +@endDefreq + +@Defreq {rr, ident} +@cindex removing a register (@code{rr}) +@cindex register, removing (@code{rr}) +Remove register @var{ident}. If @var{ident} doesn't exist, the request +is ignored. Technically, only the name is removed; the register's +contents are still accessible under aliases created with @code{aln}, if +any. +@endDefreq + +@Defreq {rnn, ident1 ident2} +@cindex renaming a register (@code{rnn}) +@cindex register, renaming (@code{rnn}) +Rename register @var{ident1} to @var{ident2}. If @var{ident1} doesn't +exist, the request is ignored. Renaming a built-in register does not +otherwise alter its properties. +@endDefreq + +@Defreq {aln, new old} +@cindex alias, register, creating (@code{aln}) +@cindex creating alias for register (@code{aln}) +@cindex register, creating alias for (@code{aln}) +Create an alias @var{new} for an existing register @var{old}, causing +the names to refer to the same stored object. If @var{old} is +undefined, a warning in category @samp{reg} is produced and the request +is ignored. @xref{Warnings}, for information about the enablement and +suppression of warnings. + +@cindex alias, register, removing (@code{rr}) +@cindex removing alias for register (@code{rr}) +@cindex register, removing alias for (@code{rr}) +To remove a register alias, invoke @code{rr} on its name. A register's +contents do not become inaccessible until it has no more names. +@endDefreq +@c END Keep (roughly) parallel with subsection "Registers" of groff(7). + +@c --------------------------------------------------------------------- + +@node Interpolating Registers, Auto-increment, Setting Registers, Registers +@subsection Interpolating Registers +@cindex interpolating registers (@code{\n}) +@cindex registers, interpolating (@code{\n}) + +Register contents are interpolated with the @code{\n} escape sequence. + +@DefescList {\\n, , i, } +@DefescItem {\\n, (, id, } +@DefescListEnd {\\n, [, ident, ]} +@cindex nested assignments +@cindex assignments, nested +@cindex indirect assignments +@cindex assignments, indirect +Interpolate register with name @var{ident} (one-character +name@tie{}@var{i}, two-character name @var{id}). @code{\n} is +interpreted even in copy mode (@pxref{Copy Mode}). If the register is +undefined, it is created and assigned a value of@tie{}@samp{0}, that +value is interpolated, and a warning in category @samp{reg} is emitted. +@xref{Warnings}, for information about the enablement and suppression of +warnings. + +@Example +.nr a 5 +.nr as \na+\na +\n(as + @result{} 10 +@endExample + +@Example +.nr a1 5 +.nr ab 6 +.ds str b +.ds num 1 +\n[a\n[num]] + @result{} 5 +\n[a\*[str]] + @result{} 6 +@endExample +@endDefesc + +@c --------------------------------------------------------------------- + +@node Auto-increment, Assigning Register Formats, Interpolating Registers, Registers +@subsection Auto-increment +@cindex auto-incrementation of a register +@cindex incrementation, automatic, of a register +@cindex decrementation, automatic, of a register + +Registers can also be incremented or decremented by a configured amount +at the time they are interpolated. The value of the increment is +specified with a third argument to the @code{nr} request, and a special +interpolation syntax is used to alter and then retrieve the register's +value. Together, these features are called +@dfn{auto-increment}.@footnote{A negative auto-increment can be +considered an ``auto-decrement''.} + +@Defreq {nr, ident value incr} +@cindex @code{\R}, difference from @code{nr} +Set register @var{ident} to @var{value} and its auto-incrementation +amount to to @var{incr}. The @code{\R} escape sequence doesn't support +an @var{incr} argument. +@endDefreq + +Auto-incrementation is not @emph{completely} automatic; the @code{\n} +escape sequence in its basic form never alters the value of a register. +To apply auto-incrementation to a register, interpolate it with +@samp{\ną}. + +@DefescList {\\n, +, i, } +@DefescItem {\\n, -, i, } +@DefescItem {\\n, +(, id, } +@DefescItem {\\n, -(, id, } +@DefescItem {\\n, +[, ident, ]} +@DefescListEnd {\\n, -[, ident, ]} +Increment or decrement @var{ident} (one-character +name@tie{}@var{i}, two-character name @var{id}) by the register's +auto-incrementation value and then interpolate the new register value. +If @var{ident} has no auto-incrementation value, interpolate as with +@code{\n}. +@endDefesc + +@need 1000 +@Example +.nr a 0 1 +.nr xx 0 5 +.nr foo 0 -2 +\n+a, \n+a, \n+a, \n+a, \n+a +.br +\n-(xx, \n-(xx, \n-(xx, \n-(xx, \n-(xx +.br +\n+[foo], \n+[foo], \n+[foo], \n+[foo], \n+[foo] + @result{} 1, 2, 3, 4, 5 + @result{} -5, -10, -15, -20, -25 + @result{} -2, -4, -6, -8, -10 +@endExample + +@cindex increment value without changing the register +@cindex value, incrementing without changing the register +To change the increment value without changing the value of a register, +assign the register's value to itself by interpolating it, and specify +the desired increment normally. Apply an increment of @samp{0} to +disable auto-incrementation of the register. + +@c --------------------------------------------------------------------- + +@node Assigning Register Formats, Built-in Registers, Auto-increment, Registers +@subsection Assigning Register Formats +@cindex assign number format to register (@code{af}) +@cindex number formats, assigning to register (@code{af}) +@cindex register, assigning number format to (@code{af}) + +A writable register's value can be interpolated in several number +formats. By default, conventional Arabic numerals are used. +Other formats see use in sectioning and outlining schemes and +alternative page numbering arrangements. + +@Defreq {af, reg fmt} +Use number format @var{fmt} when interpolating register @var{reg}. +Valid number formats are as follows. + +@table @code +@item 0@r{@dots{}} +Arabic numerals 0, 1, 2, and so on. +Any decimal digit is equivalent to @samp{0}; the formatter merely counts +the digits specified. Multiple Arabic numerals in @var{fmt} cause +interpolations to be zero-padded on the left if necessary to at least as +many digits as specified (interpolations never truncate a register +value). A register with format @samp{00} interpolates values 1, 2, 3 as +@samp{01}, @samp{02}, @samp{03}. The default format for all writable +registers is @samp{0}. + +@item I +@cindex Roman numerals +@cindex numerals, Roman +Uppercase Roman numerals: 0, I, II, III, IV,@tie{}@enddots{} + +@item i +Lowercase Roman numerals: 0, i, ii, iii, iv,@tie{}@enddots{} + +@item A +Uppercase letters: 0, A, B, C, @dots{},@tie{}Z, AA, AB,@tie{}@enddots{} + +@item a +Lowercase letters: 0, a, b, c, @dots{},@tie{}z, aa, ab,@tie{}@enddots{} +@end table + +Omitting @var{fmt} causes a warning in category @samp{missing}. +@xref{Warnings}, for information about the enablement and suppression of +warnings. Specifying an unrecognized format is an error. + +Zero values are interpolated as @samp{0} in non-Arabic formats. +Negative quantities are prefixed with @samp{-} irrespective of format. +In Arabic formats, the sign supplements the field width. If @var{reg} +doesn't exist, it is created with a zero value. + +@Example +.nr a 10 +.af a 0 \" the default format +\na, +.af a I +\na, +.af a 321 +.nr a (-\na) +\na, +.af a a +\na + @result{} 10, X, -010, -j +@endExample + +@cindex Roman numerals, extrema (maximum and minimum) +@cindex extreme values representable with Roman numerals +@cindex maximum value representable with Roman numerals +@cindex minimum value representable with Roman numerals +The representable extrema in the @samp{i} and @samp{I} formats +correspond to Arabic ą39,999. GNU @code{troff} uses @samp{w} and +@samp{z} to represent 5,000 and 10,000 in Roman numerals, respectively, +following the convention of @acronym{AT&T} @code{troff}---currently, the +correct glyphs for Roman numerals five thousand (@code{U+2181}) and ten +thousand (@code{U+2182}) are not used. + +@cindex read-only register, changing format +@cindex changing format, and read-only registers +Assigning the format of a read-only register is an error. Instead, copy +the read-only register's value to, and assign the format of, a writable +register. +@endDefreq + +@DefescList {\\g, , r, } +@DefescItem {\\g, (, rg, } +@DefescListEnd {\\g, [, reg, ]} +@cindex format of register (@code{\g}) +@cindex register, format (@code{\g}) +Interpolate the format of the register @var{reg} (one-character +name@tie{}@var{r}, two-character name @var{rg}). Zeroes represent +Arabic formats. If @var{reg} is not defined, @var{reg} is not created +and nothing is interpolated. @code{\g} is interpreted even in copy mode +(@pxref{Copy Mode}). +@endDefesc + +@cindex register format, in expressions +@cindex expressions, and register format +GNU @code{troff} interprets only Arabic numerals. The Roman numeral or +alphabetic formats cannot be used as operands to arithmetic operators in +expressions (@pxref{Numeric Expressions}). For instance, it may be +desirable to test the page number independently of its format. + +@Example +.af % i \" front matter +.de header-trap +. \" To test the page number, we need it in Arabic. +. ds saved-page-number-format \\g%\" +. af % 0 +. nr page-number-in-decimal \\n% +. af % \\*[saved-page-number-format] +. ie \\n[page-number-in-decimal]=1 .do-first-page-stuff +. el \@{\ +. ie o .do-odd-numbered-page-stuff +. el .do-even-numbered-page-stuff +. \@} +. rm saved-page-number-format +.. +.wh 0 header-trap +@endExample + +@c --------------------------------------------------------------------- + +@node Built-in Registers, , Assigning Register Formats, Registers +@subsection Built-in Registers +@cindex built-in registers +@cindex registers, built-in + +Predefined registers whose identifiers start with a dot are read-only. +Many are Boolean-valued, interpolating a true or false value testable +with the @code{if}, @code{ie}, or @code{while} requests. Some read-only +registers are string-valued, meaning that they interpolate text. + +@cindex removing a built-in register +@cindex register, built-in, removing +@cindex built-in register, removing +@strong{Caution:@:} Built-in registers are subject to removal like +others; once removed, they can be recreated only as normal writable +registers and will not reflect formatter state. + +A register name (without the dot) is often associated with a request of +the same name. A complete listing of all built-in registers can be +found in @ref{Register Index}. + +We present here a few built-in registers that are not described +elsewhere in this manual; they have to do with invariant properties of +GNU @code{troff}, or obtain information about the formatter's +command-line options, processing progress, or the operating environment. + +@table @code +@item \n[.A] +@vindex .A +@cindex approximation output register (@code{.A}) +@cindex plain text approximation output register (@code{.A}) +Approximate output is being formatted (Boolean-valued); see +@command{groff} @option{-a} option (@ref{Groff Options}). + +@item \n[.c] +@vindex .c +@itemx \n[c.] +@vindex c. +@cindex input line number register (@code{.c}, @code{c.}) +@cindex line number, input, register (@code{.c}, @code{c.}) +Input line number. @samp{c.} is a writable synonym, +@c introduced in AT&T device-independent troff (CSTR #54, 1981-01) +affecting subsequent interpolations of both @samp{.c} and @samp{c.}. + +@item \n[.F] +@cindex current input file name register (@code{.F}) +@cindex input file name, current, register (@code{.F}) +@vindex .F +Name of input file (string-valued). + +@item \n[.g] +@vindex .g +@cindex GNU @code{troff}, identification register (@code{.g}) +@cindex GNU-specific register (@code{.g}) +Always true in GNU @code{troff} (Boolean-valued). Documents can use +this to ask the formatter if it claims @code{groff} compatibility. + +@item \n[.P] +@vindex .P +Output page selection status (Boolean-valued); see @command{groff} +@option{-o} option (@ref{Groff Options}). + +@item \n[.R] +@cindex number of registers register (@code{.R}) +@cindex registers, number of, register (@code{.R}) +@vindex .R +Count of available unused registers; always 10,000 in GNU +@code{troff}.@footnote{GNU @code{troff} dynamically allocates memory for +as many registers as required.} + +@item \n[.T] +@vindex .T +Indicator of output device selection (Boolean-valued); see +@command{groff} @option{-T} option (@ref{Groff Options}). + +@item \n[.U] +@cindex safer mode +@cindex mode, safer +@cindex unsafe mode +@cindex mode, unsafe +@vindex .U +Unsafe mode enablement status (Boolean-valued); see @command{groff} +@option{-U} option (@ref{Groff Options}). + +@item \n[.x] +@vindex .x +@cindex major version number register (@code{.x}) +@cindex version number, major, register (@code{.x}) +Major version number of the running GNU @code{troff} formatter. For +example, if the version number is 1.23.0, then @code{.x} +contains@tie{}@samp{1}. + +@item \n[.y] +@vindex .y +@cindex minor version number register (@code{.y}) +@cindex version number, minor, register (@code{.y}) +Minor version number of the running GNU @code{troff} formatter. For +example, if the version number is 1.23.0, then @code{.y} +contains@tie{}@samp{23}. + +@item \n[.Y] +@vindex .Y +@cindex revision number register (@code{.Y}) +Revision number of the running GNU @code{troff} formatter. For example, +if the version number is 1.23.0, then @code{.Y} contains@tie{}@samp{0}. + +@item \n[$$] +@vindex $$ +@cindex process ID of GNU @code{troff} register (@code{$$}) +@cindex PID of GNU @code{troff} register (@code{$$}) +@cindex GNU @code{troff}, process ID register (@code{$$}) +@cindex GNU @code{troff}, PID register (@code{$$}) +Process identifier (PID) of the GNU @code{troff} program in its +operating environment. +@end table + +Date- and time-related registers are set per the local time as +determined by @cite{localtime@r{(3)}} when the formatter launches. This +initialization can be overridden by @env{SOURCE_DATE_EPOCH} and +@env{TZ}; see @ref{Environment}. + +@table @code +@item \n[seconds] +@cindex seconds, current time (@code{seconds}) +@cindex time, current, seconds (@code{seconds}) +@cindex current time, seconds (@code{seconds}) +@vindex seconds +Count of seconds elapsed in the minute (0--60). @c not 59; see POSIX + +@item \n[minutes] +@cindex minutes, current time (@code{minutes}) +@cindex time, current, minutes (@code{minutes}) +@cindex current time, minutes (@code{minutes}) +@vindex minutes +Count of minutes elapsed in the hour (0--59). + +@item \n[hours] +@cindex hours, current time (@code{hours}) +@cindex time, current, hours (@code{hours}) +@cindex current time, hours (@code{hours}) +@vindex hours +Count of hours elapsed since midnight (0--23). + +@item \n[dw] +@cindex day of the week register (@code{dw}) +@cindex date, day of the week register (@code{dw}) +@vindex dw +Day of the week (1--7; 1 is Sunday). + +@item \n[dy] +@cindex day of the month register (@code{dy}) +@cindex date, day of the month register (@code{dy}) +@vindex dy +Day of the month (1--31). + +@item \n[mo] +@cindex month of the year register (@code{mo}) +@cindex date, month of the year register (@code{mo}) +@vindex mo +Month of the year (1--12). + +@item \n[year] +@cindex date, year register (@code{year}, @code{yr}) +@cindex year, current, register (@code{year}, @code{yr}) +@vindex year +Gregorian year. + +@cindex CSTR@tie{}#54 errata +@cindex CSTR@tie{}#54 erratum, @code{yr} register +@item \n[yr] +@vindex yr +Gregorian year minus@tie{}1900. This register is incorrectly documented +in the @acronym{AT&T} @code{troff} manual as storing the last two digits +of the current year. That claim stopped being true in 2000. Old +@code{troff} input that looks like: + +@Example +'\" The year number is a surprise after 1999. +This document was formatted in 19\n(yr. +@endExample + +@noindent +can be corrected to: + +@Example +This document was formatted in \n[year]. +@endExample + +@noindent +or, for portability across many @code{roff} programs, to the following. + +@Example +.nr y4 1900+\n(yr +This document was formatted in \n(y4. +@endExample +@end table + + +@c ===================================================================== + +@node Manipulating Filling and Adjustment, Manipulating Hyphenation, Registers, GNU troff Reference +@section Manipulating Filling and Adjustment +@cindex manipulating filling and adjustment +@cindex filling and adjustment, manipulating +@cindex adjustment and filling, manipulating +@cindex justifying text +@cindex text, justifying + +@cindex break +@cindex line break +@cindex @code{bp} request, causing implicit break +@cindex @code{ce} request, causing implicit break +@cindex @code{cf} request, causing implicit break +@cindex @code{fi} request, causing implicit break +@cindex @code{fl} request, causing implicit break +@cindex @code{in} request, causing implicit break +@cindex @code{nf} request, causing implicit break +@cindex @code{rj} request, causing implicit break +@cindex @code{sp} request, causing implicit break +@cindex @code{ti} request, causing implicit break +@cindex @code{trf} request, causing implicit break +When an output line is pending (see below), a break moves the drawing +position to the beginning of the next text baseline, interrupting +filling. Various ways of causing breaks were shown in @ref{Breaking}. +The @code{br} request likewise causes a break. Several other requests +imply breaks:@: @code{bp}, @code{ce}, @code{cf}, @code{fi}, @code{fl}, +@code{in}, @code{nf}, @code{rj}, @code{sp}, @code{ti}, and @code{trf}. +If the no-break control character is used with any of these requests, +GNU @code{troff} suppresses the break; instead the requested operation +takes effect at the next break. @samp{'br} does nothing. + +@Example +.ll 55n +This line is normally filled and adjusted. +.br +A line's alignment is decided +'ce \" Center the next input line (no break). +when it is output. +This line returns to normal filling and adjustment. + @result{} This line is normally filled and adjusted. + @result{} A line's alignment is decided when it is output. + @result{} This line returns to normal filling and adjustment. +@endExample + +@noindent +@cindex pending output line +@cindex partially collected line +@cindex output line properties +@cindex properties of output lines +Output line properties like page offset, indentation, adjustment, and +even the location of its text baseline, are not determined until the +line has been broken. An output line is said to be @dfn{pending} if +some input has been collected but an output line corresponding to it has +not yet been written; such an output line is also termed @dfn{partially +collected}. If no output line is pending, it is as if a break has +already happened; additional breaks, whether explicit or implicit, have +no effect. If the vertical drawing position is negative---as it is when +the formatter starts up---a break starts a new page (even if no output +line is pending) unless an end-of-input macro is being interpreted. +@xref{End-of-input Traps}. + +@Defreq {br, } +Break the line: emit any pending output line without adjustment. + +@Example +foo bar +.br +baz +'br +qux + @result{} foo bar + @result{} baz qux +@endExample +@endDefreq + +Sometimes you want to prevent a break within a phrase or between a +quantity and its units. + +@Defesc {\\~, , , } +@cindex unbreakable space (@code{\~}) +@cindex space, unbreakable (@code{\~}) +Insert an unbreakable space that is adjustable like an ordinary space. +It is discarded from the end of an output line if a break is forced. + +@Example +Set the output speed to\~1. +There are 1,024\~bytes in 1\~KiB. +J.\~F.\~Ossanna wrote the original CSTR\~#54. +@endExample +@endDefesc + +By default, GNU @code{troff} fills text and adjusts it to reach the +output line length. The @code{nf} request disables filling; the +@code{fi} request reënables it. + +@DefreqList {fi, } +@DefregListEndx {.u} +@cindex filling of output, enabling (@code{fi}) +@cindex output, filling, enablement of (@code{fi}) +@cindex fill mode (@code{fi}), enabling +@cindex mode, fill (@code{fi}), enabling +Enable filling of output lines; a pending output line is broken. The +read-only register @code{.u} is set to@tie{}1. The filling enablement +status, sometimes called @dfn{fill mode}, is associated with the +environment (@pxref{Environments}). @xref{Line Continuation}, for +interaction with the @code{\c} escape sequence. +@endDefreq + +@Defreq {nf, } +@cindex filling of output, disabling (@code{nf}) +@cindex output, filling, disablement of (@code{nf}) +@cindex no-fill mode +@cindex mode, no-fill +@cindex fill mode, disabling +@cindex mode, fill, disabling +Disable filling of output lines: the output line length (@pxref{Line +Layout}) is ignored and output lines are broken where the input lines +are. A pending output line is broken and adjustment is suppressed. The +read-only register @code{.u} is set to@tie{}0. The filling enablement +status is associated with the environment (@pxref{Environments}). See +@ref{Line Continuation}, for interaction with the @code{\c} escape +sequence. +@endDefreq + +@DefreqList {ad, [@Var{mode}]} +@DefregListEndx {.j} +Enable output line adjustment in @var{mode}, taking effect when the +pending (or next) output line is broken. Adjustment is suppressed when +filling is. @var{mode} can have one of the following values. + +@table @code +@item b +@itemx n +Adjust ``normally'':@: if the output line does not consume the distance +between the indentation and the configured output line length, GNU +@code{troff} stretches adjustable spaces within the line until that +length is reached. When the indentation is zero, this mode spreads the +line to both the left and right margins. This is the GNU @code{troff} +default. + +@item c +@cindex centered text (filled) +Center filled text. Contrast with the @code{ce} request, which centers +text @emph{without} filling it. + +@item l +@cindex ragged-right text +Align text to the left without adjusting it. + +@item r +@cindex ragged-left text +Align text to the right without adjusting it. +@end table + +@var{mode} can also be a value previously stored in the @code{.j} +register. Using @code{ad} without an argument is the same as @samp{.ad +\n[.j]}; unless filling is disabled, GNU @code{troff} resumes adjusting +lines in the same way it did before adjustment was disabled by +invocation of the @code{na} request. + +@cindex adjustment mode register (@code{.j}) +The adjustment mode and enablement status are encoded in the read-only +register @code{.j}. These parameters are associated with the +environment (@pxref{Environments}). + +The value of @code{.j} for any adjustment mode is an implementation +detail and should not be relied upon as a programmer's interface. Do +not write logic to interpret or perform arithmetic on it. + +@Example +.ll 48n +.de AD +. br +. ad \\$1 +.. +@c . @c XXX: Restore this line when the page has room for it. +.de NA +. br +. na +.. +@c . @c XXX: Restore this line when the page has room for it. +left +.AD r +.nr ad \n(.j +right +.AD c +center +.NA +left +.AD +center +.AD \n(ad +right +@endExample +@Example + @result{} left + @result{} right + @result{} center + @result{} left + @result{} center + @result{} right +@endExample +@endDefreq + +@Defreq {na, } +Disable output line adjustment. This produces the same output as +left-alignment, but the value of the adjustment mode register @code{.j} +is altered differently. The adjustment mode and enablement status are +associated with the environment (@pxref{Environments}). +@endDefreq + +@DefreqList {brp, } +@DefescListEndx {\\p, , , } +Break, adjusting the line per the current adjustment mode. @code{\p} +schedules a break with adjustment at the next word boundary. The escape +sequence is itself neither a break nor a space of any kind; it can thus +be placed in the middle of a word to cause a break at the end of that +word. + +Breaking with immediate adjustment can produce ugly results since GNU +@code{troff} doesn't have a sophisticated paragraph-building algorithm, +as @TeX{} has, for example. Instead, GNU @code{troff} fills and adjusts +a paragraph line by line. + +@Example +.ll 4.5i +This is an uninteresting sentence. +This is an uninteresting sentence.\p +This is an uninteresting sentence. +@endExample + +@noindent +is formatted as follows. + +@Example +This is an uninteresting sentence. This is +an uninteresting sentence. +This is an uninteresting sentence. +@endExample +@endDefreq + +@cindex productive input line +@cindex input line, productive +@cindex line, productive input +To clearly present the next couple of requests, we must introduce the +concept of ``productive'' input lines. A @dfn{productive input line} is +one that directly produces formatted output. Text lines produce +output,@footnote{unless diverted; see @ref{Diversions}} as do control +lines containing requests like @code{tl} or escape sequences like +@code{\D}. Macro calls are not @emph{directly} productive, and thus not +counted, but their interpolated contents can be. Empty requests, and +requests and escape sequences that define registers or strings or alter +the formatting environment (as with changes to the size, face, height, +slant, or color of the type) are not productive. We will also preview +the output line continuation escape sequence, @code{\c}, which +``connects'' two input lines that would otherwise be counted separately. +@footnote{@xref{Line Continuation}.} + +@Example +@c .ll 56n +.de hello +Hello, world! +.. +.ce \" center output of next productive input line +. +.nr junk-reg 1 +.ft I +Chorus: \c +.ft +.hello +Went the day well? + @result{} @slanted{Chorus:} Hello, world! + @result{} Went the day well? +@endExample + +@DefreqList {ce, [@Var{n}]} +@DefregListEndx {.ce} +@cindex centered text (unfilled) +@cindex centering lines (@code{ce}) +@cindex lines, centering (@code{ce}) +Break (unless the no-break control character is used), center the output +of the next @var{n} productive input lines with respect to the line +length and indentation without filling, then break again regardless of +the invoking control character. +@c Temporary indentation is ignored. +If the argument is not positive, centering is disabled. Omitting the +argument implies an @var{n} of @samp{1}. The count of lines remaining +to be centered is stored in the read-only register @code{.ce} and is +associated with the environment (@pxref{Environments}). + +@cindex @code{ce} request, difference from @w{@samp{.ad c}} +While the @w{@samp{.ad c}} request also centers text, it fills the text +as well. + +@c Wrap example at 56 columns. +@Example +.de FR +This is a small text fragment that shows the differences +between the `.ce' and the `.ad c' requests. +.. +.ll 4i +.ce 1000 +.FR +.ce 0 + +.ad c +.FR + @result{} This is a small text fragment that shows + @result{} the differences + @result{} between the @quoteleft{}.ce@quoteright{} and the @quoteleft{}.ad c@quoteright{} requests. + @result{} + @result{} This is a small text fragment that shows + @result{} the differences between the @quoteleft{}.ce@quoteright{} and + @result{} the @quoteleft{}.ad c@quoteright{} requests. +@endExample + +The previous example illustrates a common idiom of turning centering on +for a quantity of lines far in excess of what is required, and off again +after the text to be centered. This technique relieves humans of +counting lines for requests that take a count of input lines as an +argument. +@endDefreq + +@DefreqList {rj, [@Var{n}]} +@DefregListEndx {.rj} +@cindex justifying text (@code{rj}) +@cindex text, justifying (@code{rj}) +@cindex right-justifying (@code{rj}) +Break (unless the no-break control character is used), align the output +of the next @var{n} productive input lines to the right margin without +filling, then break again regardless of the control character. +@c Temporary indentation is ignored. +If the argument is not positive, right-alignment is disabled. Omitting +the argument implies an @var{n} of @samp{1}. The count of lines +remaining to be right-aligned is stored in the read-only register +@code{.rj} and is associated with the environment +(@pxref{Environments}). + +@Example +.ll 49n +.rj 3 +At first I hoped that such a technically unsound +project would collapse but I soon realized it was +doomed to success. \[em] C. A. R. Hoare + @result{} At first I hoped that such a technically unsound + @result{} project would collapse but I soon realized it was + @result{} doomed to success. -- C. A. R. Hoare +@endExample +@endDefreq + +@need 2000 +@DefreqList {ss, word-space-size [@Var{additional-sentence-space-size}]} +@DefregItemx {.ss} +@DefregListEndx {.sss} +@cindex word space size register (@code{.ss}) +@cindex size of word space register (@code{.ss}) +@cindex space between words register (@code{.ss}) +@cindex inter-sentence space size register (@code{.sss}) +@cindex sentence space size register (@code{.sss}) +@cindex size of sentence space register (@code{.sss}) +@cindex space between sentences register (@code{.sss}) +Set the sizes of spaces between words and +sentences@footnote{Recall @ref{Filling} and @ref{Sentences} for the +definitions of word and sentence boundaries, respectively.} in twelfths +of font's space width (typically one-fourth to one-third em for Western +scripts). The default for both parameters is@tie{}12. Negative values +are erroneous. +@cindex inter-word spacing, minimal +@cindex minimal inter-word spacing +@cindex space, between words +The first argument is a minimum; if an output line undergoes adjustment, +such spaces may increase in width. +@cindex inter-sentence space, additional +@cindex additional inter-sentence space +@cindex space, between sentences +The optional second argument sets the amount of additional space +separating sentences on the same output line. If omitted, this amount +is set to @var{word-space-size}. The request is ignored if there are no +parameters. + +@cindex filling, and inter-sentence space +@cindex mode, fill, and inter-sentence space +Additional inter-sentence space is used only if the output line is not +full when the end of a sentence occurs in the input. If a sentence ends +at the end of an input line, then both an inter-word space and an +inter-sentence space are added to the output; if two spaces follow the +end of a sentence in the middle of an input line, then the second space +becomes an inter-sentence space in the output. Additional +inter-sentence space is not adjusted, but the inter-word space that +always precedes it may be. Further input spaces after the second, if +present, are adjusted as normal. + +The read-only registers @code{.ss} and @code{.sss} hold the minimal +inter-word space and additional inter-sentence space amounts, +respectively. These parameters are part of the environment +(@pxref{Environments}), and rounded down to the nearest multiple +of@tie{}12 on terminals. + +@cindex discardable horizontal space +@cindex space, discardable, horizontal +@cindex horizontal discardable space +The @code{ss} request can insert discardable horizontal space; that is, +space that is discarded at a break. For example, some footnote styles +collect the notes into a single paragraph with large gaps between +each note. + +@Example +.ll 48n +1.\~J. Fict. Ch. Soc. 6 (2020), 3\[en]14. +.ss 12 48 \" applies to next sentence ending +Reprints no longer available through FCS. +.ss 12 \" go back to normal +2.\~Better known for other work. + @result{} 1. J. Fict. Ch. Soc. 6 (2020), 3-14. Reprints + @result{} no longer available through FCS. 2. Better + @result{} known for other work. +@endExample + +@noindent +If @emph{undiscardable} space is required, use the @code{\h} escape +sequence. +@endDefreq + + +@c ===================================================================== + +@node Manipulating Hyphenation, Manipulating Spacing, Manipulating Filling and Adjustment, GNU troff Reference +@section Manipulating Hyphenation +@cindex manipulating hyphenation +@cindex hyphenation, manipulating + +@cindex hyphenation, automatic +@cindex automatic hyphenation +When filling, GNU @code{troff} hyphenates words as needed at +user-specified and automatically determined hyphenation points. The +machine-driven determination of hyphenation points in words requires +algorithms and data, and is susceptible to conventions and preferences. +Before tackling such @dfn{automatic hyphenation}, let us consider how +hyphenation points can be set explicitly. + +@cindex hyphenation, explicit +@cindex explicit hyphenation +@cindex hyphenation, manual +@cindex manual hyphenation +Explicitly hyphenated words such as ``mother-in-law'' are eligible for +breaking after each of their hyphens. Relatively few words in a +language offer such obvious break points, however, and automatic +detection of syllabic (or phonetic) boundaries for hyphenation is not +perfect,@footnote{Whether a perfect algorithm for this application is +even possible is an unsolved problem in computer science:@: +@url{https://tug.org/docs/liang/liang-thesis.pdf}.} particularly for +unusual words found in technical literature. We can instruct GNU +@code{troff} how to hyphenate specific words if the need arises. + +@cindex hyphenation exceptions +@Defreq {hw, word @dots{}} +Define each @dfn{hyphenation exception} @var{word} with each hyphen `-' +in the word indicating a hyphenation point. For example, the request + +@Example +.hw in-sa-lub-rious alpha +@endExample + +@c Serendipitously, in PDF output, the "alpha" below gets hyphenated. +@c Try to preserve this felicity in future edits. +marks potential hyphenation points in ``insalubrious'', and prevents +``alpha'' from being hyphenated at all. + +Besides the space character, any character whose hyphenation code is +zero can be used to separate the arguments of @code{hw} (see the +@code{hcode} request below). In addition, this request can be used more +than once. + +@cindex @code{hw} request, and @code{hy} restrictions +Hyphenation points specified with @code{hw} are not subject to the +within-word placement restrictions imposed by the @code{hy} request (see +below). + +Hyphenation exceptions specified with the @code{hw} request are +associated with the hyphenation language (see the @code{hla} request +below) and environment (@pxref{Environments}); invoking the @code{hw} +request in the absence of a hyphenation language is an error. + +The request is ignored if there are no parameters. +@endDefreq + +These are known as hyphenation @slanted{exceptions} in the expectation +that most users will avail themselves of automatic hyphenation; these +exceptions override any rules that would normally apply to a word +matching a hyphenation exception defined with @code{hw}. + +Situations also arise when only a specific occurrence of a word needs +its hyphenation altered or suppressed, or when a URL or similar string +needs to be breakable in sensible places without hyphenation. + +@DefescList {\\%, , , } +@DefescListEndx {\:, , , } +@cindex hyphenation character (@code{\%}) +@cindex character, hyphenation (@code{\%}) +@cindex disabling hyphenation (@code{\%}) +@cindex hyphenation, disabling (@code{\%}) +To tell GNU @code{troff} how to hyphenate words as they occur in input, +use the @code{\%} escape sequence; it is the default @dfn{hyphenation +character}. Each instance within a word indicates to GNU @code{troff} +that the word may be hyphenated at that point, while prefixing a word +with this escape sequence prevents it from being otherwise hyphenated. +This mechanism affects only that occurrence of the word; to change the +hyphenation of a word for the remainder of input processing, use the +@code{hw} request. + +@cindex @code{\X}, followed by @code{\%} +@cindex @code{\Y}, followed by @code{\%} +@cindex @code{\%}, following @code{\X} or @code{\Y} +GNU @code{troff} regards the escape sequences @code{\X} and @code{\Y} as +starting a word; that is, the @code{\%} escape sequence in, say, +@w{@samp{\X'...'\%foobar}} or @w{@samp{\Y'...'\%foobar}} no longer +prevents hyphenation of @samp{foobar} but inserts a hyphenation point +just prior to it; most likely this isn't what you want. +@xref{Postprocessor Access}. + +@cindex non-printing break point (@code{\:}) +@cindex breaking without hyphens (@code{\:}) +@cindex file names, breaking (@code{\:}) +@cindex breaking file names (@code{\:}) +@cindex URLs, breaking (@code{\:}) +@cindex breaking URLs (@code{\:}) +@code{\:} inserts a non-printing break point; that is, a word can break +there, but the soft hyphen glyph (see below) is not written to the +output if it does. This escape sequence is an input word boundary, so +the remainder of the word is subject to hyphenation as normal. + +You can combine @code{\:} and @code{\%} to control breaking of a file +name or URL, or to permit hyphenation only after certain explicit +hyphens within a word. + +@Example +@c Wrap example at 56 columns. +The \%Lethbridge-Stewart-\:\%Sackville-Baggins divorce +was, in retrospect, inevitable once the contents of +\%/var/log/\:\%httpd/\:\%access_log on the family web +server came to light, revealing visitors from Hogwarts. +@endExample +@endDefesc + +@Defreq {hc, [@Var{char}]} +Change the hyphenation character to @var{char}. This character then +works as the @code{\%} escape sequence normally does, and thus no longer +appears in the output.@footnote{@code{\%} itself stops marking +hyphenation points but still produces no output glyph.} Without an +argument, @code{hc} resets the hyphenation character to @code{\%} (the +default). The hyphenation character is associated with the environment +(@pxref{Environments}). +@endDefreq + +@Defreq {shc, [@Var{c}]} +@cindex soft hyphen character, setting (@code{shc}) +@cindex character, soft hyphen, setting (@code{shc}) +@cindex glyph, soft hyphen (@code{hy}) +@cindex soft hyphen glyph (@code{hy}) +@cindex @code{char} request, and soft hyphen character +@cindex @code{tr} request, and soft hyphen character +Set the @dfn{soft hyphen character}, inserted when a word is hyphenated +automatically or at a hyphenation character, to the ordinary or special +character@tie{}@var{c}.@footnote{``Soft'' because it appears in output +only where a hyphenation break is performed; a ``hard'' hyphen, as in +``long-term'', always appears.} If the argument is omitted, the soft +hyphen character is set to the default, @code{\[hy]}. If no glyph for +@var{c} exists in the font in use at a potential hyphenation point, then +the line is not broken there. Neither character definitions (specified +with the @code{char} and similar requests) nor translations (specified +with the @code{tr} request) are applied to @var{c}. +@endDefreq + +@cindex hyphenation parameters, automatic +@cindex automatic hyphenation parameters +Several requests influence automatic hyphenation. Because conventions +vary, a variety of hyphenation modes is available to the @code{hy} +request; these determine whether hyphenation will apply to a +word prior to breaking a line at the end of a page (more or less; see +below for details), and at which positions within that word +automatically determined hyphenation points are permissible. The places +within a word that are eligible for hyphenation are determined by +language-specific data and lettercase relationships. Furthermore, +hyphenation of a word might be suppressed due to a limit on +consecutive hyphenated lines (@code{hlm}), a minimum line length +threshold (@code{hym}), or because the line can instead be adjusted with +additional inter-word space (@code{hys}). + +@cindex hyphenation mode register (@code{.hy}) +@DefreqList {hy, [@Var{mode}]} +@DefregListEndx {.hy} +Set automatic hyphenation mode to @var{mode}, an integer encoding +conditions for hyphenation; if omitted, @samp{1} is implied. The +hyphenation mode is available in the read-only register @samp{.hy}; it +is associated with the environment (@pxref{Environments}). The default +hyphenation mode depends on the localization file loaded when GNU +@code{troff} starts up; see the @code{hpf} request below. + +Typesetting practice generally does not avail itself of every +opportunity for hyphenation, but the details differ by language and site +mandates. The hyphenation modes of @acronym{AT&T} @code{troff} were +implemented with English-language publishing practices of the 1970s in +mind, not a scrupulous enumeration of conceivable parameters. GNU +@code{troff} extends those modes such that finer-grained control is +possible, favoring compatibility with older implementations over a more +intuitive arrangement. The means of hyphenation mode control is a set +of numbers that can be added up to encode the behavior +sought.@footnote{The mode is a vector of Booleans encoded as an integer. +To a programmer, this fact is easily deduced from the exclusive use of +powers of two for the configuration parameters; they are computationally +easy to ``mask off'' and compare to zero. To almost everyone else, the +arrangement seems recondite and unfriendly.} The entries in the +following table are termed @dfn{values}; the sum of the desired +values is the @dfn{mode}. + +@table @code +@item 0 +disables hyphenation. + +@item 1 +enables hyphenation except after the first and before the last character +of a word. +@end table + +The remaining values ``imply'' 1; that is, they enable hyphenation +under the same conditions as @samp{.hy 1}, and then apply or lift +restrictions relative to that basis. + +@table @code +@item 2 +disables hyphenation of the last word on a page,@footnote{Hyphenation is +prevented if the next page location trap is closer to the vertical +drawing position than the next text baseline would be. @xref{Page +Location Traps}.} even for explicitly hyphenated words. + +@item 4 +disables hyphenation before the last two characters of a word. + +@item 8 +disables hyphenation after the first two characters of a word. + +@item 16 +enables hyphenation before the last character of a word. + +@item 32 +enables hyphenation after the first character of a word. +@end table + +Apart from value@tie{}2, restrictions imposed by the hyphenation mode +are @emph{not} respected for words whose hyphenations have been +specified with the hyphenation character (@samp{\%} by default) or the +@code{hw} request. + +Nonzero values in the previous table are additive. For example, +mode@tie{}12 causes GNU @code{troff} to hyphenate neither the last two +nor the first two characters of a word. Some values cannot be used +together because they contradict; for instance, values 4 and@tie{}16, +and values 8 and@tie{}32. As noted, it is superfluous to add 1 to any +non-zero even mode. + +@cindex hyphenation pattern files +@cindex pattern files, for hyphenation +The automatic placement of hyphens in words is determined by +@dfn{pattern files}, which are derived from @TeX{} and available for +several languages. The number of characters at the beginning of a word +after which the first hyphenation point should be inserted is determined +by the patterns themselves; it can't be reduced further without +introducing additional, invalid hyphenation points (unfortunately, this +information is not part of a pattern file---you have to know it in +advance). The same is true for the number of characters at the end of +a word before the last hyphenation point should be inserted. For +example, you can supply the following input to @samp{echo $(nroff)}. + +@Example +.ll 1 +.hy 48 +splitting +@endExample + +@noindent +You will get + +@Example +s- plit- t- in- g +@endExample + +@noindent +instead of the correct `split- ting'. English patterns as distributed +with GNU @code{troff} need two characters at the beginning and three +characters at the end; this means that value@tie{}4 of @code{hy} is +mandatory. Value@tie{}8 is possible as an additional restriction, but +values@tie{}16 and@tie{}32 should be avoided, as should mode@tie{}1. +Modes@tie{}4 and@tie{}6 are typical. + +A table of left and right minimum character counts for hyphenation as +needed by the patterns distributed with GNU @code{troff} follows; see +the @cite{groff_tmac@r{(5)}} man page for more information on GNU +@code{troff}'s language macro files. + +@multitable {German traditional} {pattern name} {left min} {right min} +@headitem language @tab pattern name @tab left min @tab right min +@item Czech @tab cs @tab 2 @tab 2 +@item English @tab en @tab 2 @tab 3 +@item French @tab fr @tab 2 @tab 3 +@item German traditional @tab det @tab 2 @tab 2 +@item German reformed @tab den @tab 2 @tab 2 +@item Italian @tab it @tab 2 @tab 2 +@item Swedish @tab sv @tab 1 @tab 2 +@end multitable + +Hyphenation exceptions within pattern files (i.e., the words within a +@TeX{} @code{\hyphenation} group) obey the hyphenation restrictions +given by @code{hy}. +@endDefreq + +@Defreq {nh, } +Disable automatic hyphenation; i.e., set the hyphenation mode to@tie{}0 +(see above). The hyphenation mode of the last call to @code{hy} is not +remembered. +@endDefreq + +@need 200 +@DefreqList {hpf, pattern-file} +@DefreqItemx {hpfa, pattern-file} +@DefreqListEndx {hpfcode, a b [c d] @dots{}} +@cindex hyphenation patterns (@code{hpf}) +@cindex patterns for hyphenation (@code{hpf}) +Read hyphenation patterns from @var{pattern-file}, which is sought +in the same way that macro files are with the @code{mso} request or the +@option{-m@var{name}} command-line option to @code{groff}. The +@var{pattern-file} should have the same format as (simple) @TeX{} +pattern files. More specifically, the following scanning rules are +implemented. + +@itemize @bullet +@item +A percent sign starts a comment (up to the end of the line) even if +preceded by a backslash. + +@item +``Digraphs'' like @code{\$} are not supported. + +@item +@code{^^@var{xx}} (where each @var{x} is 0--9 or a--f) and +@code{^^@var{c}} (character @var{c} in the code point range 0--127 +decimal) are recognized; other uses of @code{^} cause an error. + +@item +No macro expansion is performed. + +@item +@code{hpf} checks for the expression @code{\patterns@{@dots{}@}} +(possibly with whitespace before or after the braces). Everything +between the braces is taken as hyphenation patterns. Consequently, +@code{@{} and @code{@}} are not allowed in patterns. + +@item +Similarly, @code{\hyphenation@{@dots{}@}} gives a list of hyphenation +exceptions. + +@item +@code{\endinput} is recognized also. + +@item +For backward compatibility, if @code{\patterns} is missing, the whole +file is treated as a list of hyphenation patterns (except that the +@code{%} character is recognized as the start of a comment). +@end itemize + +The @code{hpfa} request appends a file of patterns to the current list. + +The @code{hpfcode} request defines mapping values for character codes in +pattern files. It is an older mechanism no longer used by GNU +@code{troff}'s own macro files; for its successor, see @code{hcode} +below. @code{hpf} or @code{hpfa} apply the mapping after reading the +patterns but before replacing or appending to the active list of +patterns. Its arguments are pairs of character codes---integers from 0 +to@tie{}255. The request maps character code@tie{}@var{a} to +code@tie{}@var{b}, code@tie{}@var{c} to code@tie{}@var{d}, and so on. +Character codes that would otherwise be invalid in GNU @code{troff} can +be used. By default, every code maps to itself except those for letters +`A' to `Z', which map to those for `a' to `z'. + +@cindex localization +@pindex troffrc +@pindex cs.tmac +@pindex de.tmac +@pindex en.tmac +@pindex fr.tmac +@pindex it.tmac +@pindex ja.tmac +@pindex sv.tmac +@pindex zh.tmac +The set of hyphenation patterns is associated with the language set by +the @code{hla} request (see below). The @code{hpf} request is usually +invoked by a localization file loaded by the @file{troffrc} +file.@footnote{For more on localization, see the +@cite{groff_tmac@r{(5)}} man page.} + +A second call to @code{hpf} (for the same language) replaces the +hyphenation patterns with the new ones. Invoking @code{hpf} or +@code{hpfa} causes an error if there is no hyphenation language. If no +@code{hpf} request is specified (either in the document, in a file +loaded at startup, or in a macro package), GNU @code{troff} won't +automatically hyphenate at all. +@endDefreq + +@Defreq {hcode, c1 code1 [c2 code2] @dots{}} +@cindex hyphenation code (@code{hcode}) +@cindex code, hyphenation (@code{hcode}) +Set the hyphenation code of character @var{c1} to @var{code1}, that of +@var{c2} to @var{code2}, and so on. A hyphenation code must be an +ordinary character (not a special character escape sequence) other than +a digit or a space. The request is ignored if given no arguments. + +For hyphenation to work, hyphenation codes must be set up. At +startup, GNU @code{troff} assigns hyphenation codes to the letters +@samp{a}--@samp{z} (mapped to themselves), to the letters +@samp{A}--@samp{Z} (mapped to @samp{a}--@samp{z}), and zero to all other +characters. Normally, hyphenation patterns contain only lowercase +letters which should be applied regardless of case. In other words, +they assume that the words `FOO' and `Foo' should be hyphenated exactly +as `foo' is. The @code{hcode} request extends this principle to letters +outside the Unicode basic Latin alphabet; without it, words containing +such letters won't be hyphenated properly even if the corresponding +hyphenation patterns contain them. + +For example, the following @code{hcode} requests are necessary to assign +hyphenation codes to the letters @samp{ÄäÖöÜüß}, needed for German. + +@Example +.hcode ä ä Ä ä +.hcode ö ö Ö ö +.hcode ü ü Ü ü +.hcode ß ß +@endExample + +Without these assignments, GNU @code{troff} treats the German word +@w{`Kindergärten'} (the plural form of `kindergarten') as two words +@w{`kinderg'} and @w{`rten'} because the hyphenation code of the +umlaut@tie{}a is zero by default, just like a space. There is a German +hyphenation pattern that covers @w{`kinder'}, so GNU @code{troff} finds +the hyphenation `kin-der'. The other two hyphenation points +(`kin-der-gär-ten') are missed. +@endDefreq + +@DefreqList {hla, lang} +@DefregListEndx {.hla} +@cindex @code{hpf} request, and hyphenation language +@cindex @code{hw} request, and hyphenation language +@pindex troffrc +@pindex troffrc-end +Set the hyphenation language to @var{lang}. Hyphenation exceptions +specified with the @code{hw} request and hyphenation patterns and +exceptions specified with the @code{hpf} and @code{hpfa} requests are +associated with the hyphenation language. The @code{hla} request is +usually invoked by a localization file, which is turn loaded by the +@file{troffrc} or @file{troffrc-end} file; see the @code{hpf} request +above. + +@cindex hyphenation language register (@code{.hla}) +The hyphenation language is available in the read-only string-valued +register @samp{.hla}; it is associated with the environment +(@pxref{Environments}). +@endDefreq + +@DefreqList {hlm, [@Var{n}]} +@DefregItemx {.hlm} +@DefregListEndx {.hlc} +@cindex explicit hyphen (@code{\%}) +@cindex hyphen, explicit (@code{\%}) +@cindex consecutive hyphenated lines (@code{hlm}) +@cindex lines, consecutive hyphenated (@code{hlm}) +@cindex hyphenated lines, consecutive (@code{hlm}) +Set the maximum quantity of consecutive hyphenated lines to @var{n}. If +@var{n} is negative, there is no maximum. If omitted, @var{n} +is@tie{}@minus{}1. This value is associated with the environment +(@pxref{Environments}). Only lines output from a given environment +count toward the maximum associated with that environment. Hyphens +resulting from @code{\%} are counted; explicit hyphens are not. + +@cindex hyphenation consecutive line limit register (@code{.hlm}) +@cindex hyphenation consecutive line count register (@code{.hlc}) +The @code{.hlm} read-only register stores this maximum. The count of +immediately preceding consecutive hyphenated lines is available in the +read-only register @code{.hlc}. +@endDefreq + +@DefreqList {hym, [@Var{length}]} +@DefregListEndx {.hym} +@cindex hyphenation margin (@code{hym}) +@cindex margin for hyphenation (@code{hym}) +@cindex @code{ad} request, and hyphenation margin +Set the (right) hyphenation margin to @var{length}. If the adjustment +mode is not @samp{b} or @samp{n}, the line is not hyphenated if it is +shorter than @var{length}. Without an argument, the hyphenation margin +is reset to its default value, 0. The default scaling unit is @samp{m}. +The hyphenation margin is associated with the environment +(@pxref{Environments}). + +A negative argument resets the hyphenation margin to zero, emitting a +warning in category @samp{range}. + +@cindex hyphenation margin register (@code{.hym}) +The hyphenation margin is available in the @code{.hym} read-only +register. +@endDefreq + +@DefreqList {hys, [@Var{hyphenation-space}]} +@DefregListEndx {.hys} +@cindex hyphenation space (@code{hys}) +@cindex hyphenation space adjustment threshold +@cindex @code{ad} request, and hyphenation space +Suppress hyphenation of the line in adjustment modes @samp{b} or +@samp{n} if it can be justified by adding no more than +@var{hyphenation-space} extra space to each inter-word space. Without +an argument, the hyphenation space adjustment threshold is set to its +default value, 0. The default scaling unit is @samp{m}. The +hyphenation space adjustment threshold is associated with the +environment (@pxref{Environments}). + +A negative argument resets the hyphenation space adjustment threshold to +zero, emitting a warning in category @samp{range}. + +@cindex hyphenation space adjustment threshold register (@code{.hys}) +The hyphenation space adjustment threshold is available in the +@code{.hys} read-only register. +@endDefreq + + +@c ===================================================================== + +@node Manipulating Spacing, Tabs and Fields, Manipulating Hyphenation, GNU troff Reference +@section Manipulating Spacing +@cindex manipulating spacing +@cindex spacing, manipulating + +A break causes the formatter to update the vertical drawing position at +which the new text baseline is aligned. You can alter this location. + +@Defreq {sp, [@Var{distance}]} +Break and move the next text baseline down by @var{distance}, or until +springing a page location trap.@footnote{@xref{Page Location Traps}.} +If invoked with the no-break control character, @code{sp} moves the +pending output line's text baseline by @var{distance}. A negative +@var{distance} will not reduce the position of the text baseline below +zero. Inside a diversion, any @var{distance} argument is ignored. The +default scaling unit is @samp{v}. If @var{distance} is not specified, +@samp{1v} is assumed. + +@Example +.pl 5v \" Set page length to 5 vees. +.de xx +\-\-\- +. br +.. +.wh 0 xx \" Set a trap at the top of the page. +foo on page \n% +.sp 2v +bar on page \n% +.sp 50v \" This will cause a page break. +baz on page \n% +.pl \n(nlu \" Truncate page to current position. + @result{} --- + @result{} foo on page 1 + @result{} + @result{} + @result{} bar on page 1 + @result{} --- + @result{} baz on page 2 +@endExample + +You might use the following macros to set the baseline of the next +output text at a given distance from the top or the bottom of the page. +We subtract one line height (@code{\n[.v]}) because the @code{|} +operator moves to one vee below the page top (recall @ref{Numeric +Expressions}). + +@Example +.de y-from-top-down +. sp |\\$1-\\n[.v]u +.. +. +.de y-from-bot-up +. sp |\\n[.p]u-\\$1-\\n[.v]u +.. +@endExample + +@noindent +A call to @samp{.y-from-bot-up 10c} means that the next text baseline +will be 10@tie{}cm from the bottom edge of the paper. +@endDefreq + +@DefreqList {ls, [@Var{count}]} +@DefregListEndx {.L} +@cindex double-spacing (@code{ls}) +Set the line spacing; add @w{@var{count}@minus{}1} blank lines after each +line of text. With no argument, GNU @code{troff} uses the previous +value before the last @code{ls} call. The default is @code{1}. + +@c This example is fairly obvious, doesn't realistically reflect the +@c fact that formatted text would occur between each of these requests, +@c and doesn't fit well on the (PDF) page as of this writing. +@c @Example +@c .ls 2 \" begin double-spaced output +@c .ls 3 \" begin triple-spaced output +@c .ls \" return to double-spaced output +@c @endExample + +@cindex line spacing register (@code{.L}) +The read-only register @code{.L} contains the current line spacing; it +is associated with the environment (@pxref{Environments}). +@endDefreq + +The @code{ls} request is a coarse mechanism. @xref{Changing the Type +Size}, for the requests @code{vs} and @code{pvs} as alternatives to +@code{ls}. + +@DefescList {\\x, @code{'}, spacing, @code{'}} +@DefregListEndx {.a} +Sometimes, an output line requires additional vertical spacing, for +instance to allow room for a tall construct like an inline equation with +exponents or subscripts (particularly if they are iterated). The +@code{\x} escape sequence takes a delimited measurement (like +@samp{\x'3p'}) to increase the vertical spacing of the pending output +line. The default scaling unit is @samp{v}. If the measurement is +positive, extra vertical space is inserted below the current line; a +negative measurement adds space above. If @code{\x} is applied to the +pending output line multiple times, the maxima of the positive and +negative adjustments are separately applied. The delimiter need not be +a neutral apostrophe; see @ref{Delimiters}. + +@cindex extra post-vertical line space register (@code{.a}) +The @code{.a} read-only register contains the extra vertical spacing +@emph{after} the text baseline of the most recently emitted output line. +(In other words, it is the largest positive argument to @code{\x} +encountered on that line.) This quantity is exposed via a register +because if an output line requires this ``extra post-vertical line +spacing'', and the subsequent output line requires ``extra pre-vertical +line spacing'' (a negative argument to @code{\x}), then applying both +can lead to excessive spacing between the output lines. Text that is +piling high on line @var{n} might not require (as much) extra +pre-vertical line spacing if line @var{n}@minus{}1 carries extra +post-vertical line spacing. + +Use of @code{\x} can be necessary in combination with the +bracket-building escape sequence @code{\b},@footnote{@xref{Drawing +Geometric Objects}.} as the following example shows. + +@Example +.nf +This is a test of \[rs]b (1). +This is a test of \[rs]b (2). +This is a test of \b'xyz'\x'-1m'\x'1m' (3). +This is a test of \[rs]b (4). +This is a test of \[rs]b (5). + @result{} This is a test of \b (1). + @result{} This is a test of \b (2). + @result{} x + @result{} This is a test of y (3). + @result{} z + @result{} This is a test of \b (4). + @result{} This is a test of \b (5). +@endExample +@endDefesc + +@noindent +Without @code{\x}, the backslashes on the lines marked @samp{(2)} and +@samp{(4)} would be overprinted. + +@need 1000 +@DefreqList {ns, } +@DefreqItemx {rs, } +@DefregListEndx {.ns} +@cindex @code{sp} request, and no-space mode +@cindex no-space mode (@code{ns}) +@cindex mode, no-space (@code{ns}) +@cindex blank lines, disabling +@cindex lines, blank, disabling +Enable @dfn{no-space mode}. Vertical spacing, whether by @code{sp} +requests or blank input lines, is disabled. The @code{bp} request to +advance to the next page is also disabled, unless it is accompanied by a +page number (@pxref{Page Control}). No-space mode ends automatically +when text@footnote{or geometric objects; see @ref{Drawing Geometric +Objects}} is formatted for output @footnote{to the top-level diversion; +see @ref{Diversions}} or the @code{rs} request is invoked, which ends +no-space mode. The read-only register @code{.ns} interpolates a Boolean +value indicating the enablement of no-space mode. + +A paragraphing macro might ordinarily insert vertical space to separate +paragraphs. A section heading macro could invoke @code{ns} to suppress +this spacing for the first paragraph in a section. +@endDefreq + + +@c ===================================================================== + +@node Tabs and Fields, Character Translations, Manipulating Spacing, GNU troff Reference +@section Tabs and Fields +@cindex tabs, and fields +@cindex fields, and tabs + +@cindex tab character encoding +A tab character (@acronym{ISO} code point@tie{}9, @acronym{EBCDIC} +code point@tie{}5) causes a horizontal movement to the next tab stop, if +any. + +@Defesc {\\t, , , } +@cindex tab character, non-interpreted (@code{\t}) +@cindex character, tab, non-interpreted (@code{\t}) +@cindex @code{\t}, and copy mode +@cindex copy mode, and @code{\t} +@cindex mode, copy, and @code{\t} +Interpolate a tab in copy mode; see @ref{Copy Mode}. +@endDefesc + +@DefreqList {ta, [[@Var{n1} @Var{n2} @dots{} @Var{nn} ]@t{T} @Var{r1} @ + @Var{r2} @dots{} @Var{rn}]} +@DefregListEndx {.tabs} +Change tab stop positions. This request takes a series of tab +specifiers as arguments (optionally divided into two groups with the +letter @samp{T}) that indicate where each tab stop is to be, overriding +any previous settings. The default scaling unit is @samp{m}. Invoking +@code{ta} without an argument removes all tab stops. +@cindex default tab stops +@cindex tab stops, default +GNU @code{troff}'s startup value is @w{@samp{T 0.5i}}. + +Tab stops can be specified absolutely---as distances from the left +margin. The following example sets six tab stops, one every inch. + +@Example +.ta 1i 2i 3i 4i 5i 6i +@endExample + +Tab stops can also be specified using a leading @samp{+}, which means +that the specified tab stop is set relative to the previous tab stop. +For example, the following is equivalent to the previous example. + +@Example +.ta 1i +1i +1i +1i +1i +1i +@endExample + +GNU @code{troff} supports an extended syntax to specify repeating tab +stops. These stops appear after a @samp{T} argument. Their values are +always taken as distances relative to the previous tab stop. This is +the idiomatic way to specify tab stops at equal intervals in +@code{groff}. The following is, yet again, the same as the previous +examples. It does more, in fact, since it defines an infinite number of +tab stops at one-inch intervals. + +@Example +.ta T 1i +@endExample + +Now we are ready to interpret the full syntax given above. The +@code{ta} request sets tabs at positions @var{n1}, @var{n2}, @dots{}, +@var{nn}, then at @var{nn}+@var{r1}, @var{nn}+@var{r2}, @dots{}, +@var{nn}+@var{rn}, then at @var{nn}+@var{rn}+@var{r1}, +@var{nn}+@var{rn}+@var{r2}, @dots{}, @var{nn}+@var{rn}+@var{rn}, and so +on. + +For example, @samp{4c +6c T 3c 5c 2c} is equivalent to @samp{4c 10c 13c +18c 20c 23c 28c 30c @dots{}}. + +Text written to a tab column (i.e., between two tab stops, or between a +tab stop and an output line boundary) may be aligned to the right or +left, or centered in the column. This alignment is determined by +appending @samp{R}, @samp{L}, or @samp{C} to the tab specifier. The +default is @samp{L}. + +@Example +.ta 1i 2iC 3iR +@endExample + +The beginning of an output line is not a tab stop; the text that begins +an output line is placed according to the configured alignment and +indentation; see @ref{Manipulating Filling and Adjustment} and @ref{Line +Layout}. + +A tab stop is converted into a non-breakable horizontal movement that +cannot be adjusted. + +@Example +.ll 2i +.ds foo a\tb\tc +.ta T 1i +\*[foo] + @error{} warning: cannot break line + @result{} a b c +@endExample + +@noindent +The above creates a single output line that is a bit longer than two +inches (we use a string to show exactly where the tab stops are). +Now consider the following. + +@Example +.ll 2i +.ds bar a\tb c\td +.ta T 1i +\*[bar] + @error{} warning: cannot adjust line + @result{} a b + @result{} c d +@endExample + +@noindent +GNU @code{troff} first converts the line's tab stops into unbreakable +horizontal movements, then breaks after @samp{b}. This usually isn't +what you want. + +Superfluous tab characters---those that do not correspond to a tab +stop---are ignored except for the first, which delimits the characters +belonging to the last tab stop for right-alignment or centering. + +@Example +.ds Z foo\tbar\tbaz +.ds ZZ foo\tbar\tbazqux +.ds ZZZ foo\tbar\tbaz\tqux +.ta 2i 4iR +\*[Z] +.br +\*[ZZ] +.br +\*[ZZZ] +.br + @result{} foo bar baz + @result{} foo bar bazqux + @result{} foo bar bazqux +@endExample + +@noindent +The first line right-aligns ``baz'' within the second tab stop. The +second line right-aligns ``bazqux'' within it. The third line +right-aligns only ``baz'' because of the additional tab character, which +marks the end of the text occupying the last tab stop defined. + +Tab stops are associated with the environment (@pxref{Environments}). + +@cindex tab stop settings register (@code{.tabs}) +@cindex @code{.S} register, Plan@tie{}9 alias for @code{.tabs} +@cindex @code{.tabs} register, Plan@tie{}9 alias (@code{.S}) +The read-only register @code{.tabs} contains a string +representation of the current tab settings suitable for use as an +argument to the @code{ta} request.@footnote{Plan@tie{}9 @code{troff} +uses the register @code{.S} for this purpose.} + +@Example +.ds tab-string \n[.tabs] +\*[tab-string] + @result{} T120u +@endExample +@endDefreq + +@Defreq {tc, [@Var{c}]} +@cindex tab repetition character (@code{tc}) +@cindex character, tab repetition (@code{tc}) +@cindex glyph, tab repetition (@code{tc}) +Set the tab repetition character to the ordinary or special character +@var{c}; normally, no glyph is written when moving to a tab stop (and +some output devices may output space characters to achieve this motion). +A @dfn{tab repetition character} causes the formatter to write as many +instances of @var{c} as are necessary to occupy the interval from the +horizontal drawing position to the next tab stop. With no argument, GNU +@code{troff} reverts to the default behavior. The tab repetition +character is associated with the environment (@pxref{Environments}). +Only a single character of @var{c} is recognized; any excess is ignored. +@endDefreq + +@DefreqList {linetabs, n} +@DefregListEndx {.linetabs} +@cindex tab, line-tabs mode +@cindex line-tabs mode +@cindex mode, line-tabs +If @var{n} is missing or non-zero, activate @dfn{line-tabs}; deactivate +it otherwise (the default). Active line-tabs cause GNU @code{troff} +to compute tab distances relative to the start of the output line +instead of the input line. + +@Example +.de Tabs +. ds x a\t\c +. ds y b\t\c +. ds z c +. ta 1i 3i +\\*x +\\*y +\\*z +.. +.Tabs +.br +.linetabs +.Tabs + @result{} a b c + @result{} a b c +@endExample + +Line-tabs activation is associated with the environment +(@pxref{Environments}). The read-only register @code{.linetabs} +interpolates@tie{}1 if line-tabs are active, and 0 otherwise. +@endDefreq + +@menu +* Leaders:: +* Fields:: +@end menu + +@c --------------------------------------------------------------------- + +@node Leaders, Fields, Tabs and Fields, Tabs and Fields +@subsection Leaders +@cindex leaders + +Sometimes it is desirable to fill a tab stop with a given glyph, +but also use tab stops normally on the same output line. An example is +a table of contents entry that uses dots to bridge the entry name with +its page number, which is itself aligned between tab stops. The +@code{roff} language provides @dfn{leaders} for this +purpose.@footnote{This is pronounced to rhyme with ``feeder'', and +refers to how the glyphs ``lead'' the eye across the page to the +corresponding page number or other datum.} + +@cindex leader character +A leader character (@acronym{ISO} and @acronym{EBCDIC} code +point@tie{}1, also known as @acronym{SOH} or ``start of heading''), +behaves similarly to a tab character:@: it moves to the next tab stop. +The difference is that for this movement, the default fill character is +a period @samp{.}. + +@Defesc {\\a, , , } +@cindex leader character, non-interpreted (@code{\a}) +@cindex character, leader, non-interpreted (@code{\a}) +@cindex @code{\a}, and copy mode +@cindex copy mode, and @code{\a} +@cindex mode, copy, and @code{\a} +Interpolate a leader in copy mode; see @ref{Copy Mode}. +@endDefesc + +@Defreq {lc, [@Var{c}]} +@cindex leader repetition character (@code{lc}) +@cindex character, leader repetition (@code{lc}) +@cindex glyph, leader repetition (@code{lc}) +Set the leader repetition character to the ordinary or special character +@var{c}. Recall @ref{Tabs and Leaders}:@: when encountering a leader +character in the input, the formatter writes as many dots @samp{.} as +are necessary until +reaching the next tab stop; this is the @dfn{leader definition +character}. Omitting @var{c} unsets the leader +character. With no argument, GNU @code{troff} treats leaders the same +as tabs. The leader repetition character is associated with the +environment (@pxref{Environments}). Only a single @var{c} is +recognized; any excess is ignored. +@endDefreq + +@cindex table of contents +@cindex contents, table of +A table of contents, for example, may define tab stops after a section +number, a title, and a gap to be filled with leader dots. The page +number follows the leader, after a right-aligned final tab stop wide +enough to house the largest page number occurring in the document. + +@Example +.ds entry1 19.\tThe Prophet\a\t98 +.ds entry2 20.\tAll Astir\a\t101 +.ta .5i 4.5i +.5iR +.nf +\*[entry1] +\*[entry2] + @result{} 19. The Prophet............................. 98 + @result{} 20. All Astir............................... 101 +@endExample + +@c --------------------------------------------------------------------- + +@node Fields, , Leaders, Tabs and Fields +@subsection Fields +@cindex fields + +@cindex field delimiting character (@code{fc}) +@cindex delimiting character, for fields (@code{fc}) +@cindex character, field delimiting (@code{fc}) +@cindex field padding character (@code{fc}) +@cindex padding character, for fields (@code{fc}) +@cindex character, field padding (@code{fc}) +@dfn{Fields} are a more general way of laying out tabular data. A field +is defined as the data between a pair of @dfn{delimiting characters}. +It contains substrings that are separated by @dfn{padding characters}. +The width of a field is the distance on the @emph{input} line from the +position where the field starts to the next tab stop. A padding +character inserts an adjustable space similar to @TeX{}'s @code{\hss} +command (thus it can even be negative) to make the sum of all substring +lengths plus the adjustable space equal to the field width. If more +than one padding character is inserted, the available space is evenly +distributed among them. + +@Defreq {fc, [@Var{delim-char} [@Var{padding-char}]]} +Define a delimiting and a padding character for fields. If the latter +is missing, the padding character defaults to a space character. If +there is no argument at all, the field mechanism is disabled (which is +the default). In contrast to, e.g., the tab repetition character, +delimiting and padding characters are @emph{not} associated with the +environment (@pxref{Environments}). + +@Example +.fc # ^ +.ta T 3i +#foo^bar^smurf# +.br +#foo^^bar^smurf# + @result{} foo bar smurf + @result{} foo bar smurf +@endExample +@endDefreq + + +@c ===================================================================== + +@node Character Translations, @code{troff} and @code{nroff} Modes, Tabs and Fields, GNU troff Reference +@section Character Translations +@cindex character translations +@cindex translations of characters + +A @dfn{translation} is a mapping of an input character to an output +glyph. The mapping occurs at output time, i.e., the input character +gets assigned the metric information of the mapped output character +right before input tokens are converted to nodes (@pxref{Gtroff +Internals}, for more on this process). + +@DefreqList {tr, @Var{a}@Var{b}@Var{c}@Var{d}@dots{}} +@DefreqListEndx {trin, @Var{a}@Var{b}@Var{c}@Var{d}@dots{}} +Translate character @var{a} to glyph@tie{}@var{b}, character @var{c} to +glyph@tie{}@var{d}, and so on. If there is an odd number of characters +in the argument, the last one is translated to a fixed-width space (the +same one obtained by the @code{\@key{SP}} escape sequence). + +The @code{trin} request is identical to @code{tr}, but when you unformat +a diversion with @code{asciify} it ignores the translation. +@xref{Diversions}, for details about the @code{asciify} request. + +Some notes: + +@itemize @bullet +@item +@cindex @code{\(}, and translations +@cindex @code{\[}, and translations +@cindex @code{\'}, and translations +@cindex @code{\`}, and translations +@cindex @code{\-}, and translations +@cindex @code{\_}, and translations +@cindex @code{\C}, and translations +@cindex @code{\N}, and translations +@cindex @code{char} request, and translations +@cindex special characters +@cindex character, special +@cindex numbered glyph (@code{\N}) +@cindex glyph, numbered (@code{\N}) +Special characters (@code{\(@var{xx}}, @code{\[@var{xxx}]}, +@code{\C'@var{xxx}'}, @code{\'}, @code{\`}, @code{\-}, @code{\_}), +glyphs defined with the @code{char} request, and numbered glyphs +(@code{\N'@var{xxx}'}) can be translated also. + +@item +@cindex @code{\e}, and translations +The @code{\e} escape can be translated also. + +@item +@cindex @code{\%}, and translations +@cindex @code{\~}, and translations +Characters can be mapped onto the @code{\%} and @code{\~} escape +sequences (but @code{\%} and @code{\~} can't be mapped onto another +glyph). + +@item +@cindex backspace character, and translations +@cindex character, backspace, and translations +@cindex leader character, and translations +@cindex character, leader, and translations +@cindex newline character, and translations +@cindex character, newline, and translations +@cindex tab character, and translations +@cindex character, tab, and translations +@cindex @code{\a}, and translations +@cindex @code{\t}, and translations +The following characters can't be translated: space (with one exception, +see below), backspace, newline, leader (and @code{\a}), tab (and +@code{\t}). + +@item +@cindex @code{shc} request, and translations +Translations are not considered for finding the soft hyphen character +set with the @code{shc} request. + +@item +@cindex @code{\&}, and translations +The pair @samp{@var{c}\&} (an arbitrary character@tie{}@var{c} followed +by the dummy character) maps this character to ``nothing''. + +@Example +.tr a\& +foo bar + @result{} foo br +@endExample + +@noindent +Even the space character can be mapped to the dummy character. + +@Example +.tr aa \& +foo bar + @result{} foobar +@endExample + +@noindent +As shown in the example, the space character can't be the first +character/glyph pair as an argument of @code{tr}. Additionally, it is +not possible to map the space character to any other glyph; requests +like @w{@samp{.tr aa x}} undo @w{@samp{.tr aa \&}} instead. + +If justification is active, lines are justified in spite of the `empty' +space character (but there is no minimal distance, i.e., the space +character, between words). + +@item +After an output glyph has been constructed (this happens at the moment +immediately before the glyph is appended to an output glyph list, either +by direct output, in a macro, diversion, or string), it is no longer +affected by @code{tr}. + +@item +Translating character to glyphs where one of them or both are undefined +is possible also; @code{tr} does not check whether the elements of its +argument exist. + +@xref{Gtroff Internals}. + +@item +Without an argument, the @code{tr} request is ignored. +@end itemize +@endDefreq + +@Defreq {trnt, @Var{a}@Var{b}@Var{c}@Var{d}@dots{}} +@cindex @code{\!}, and @code{trnt} +@code{trnt} is the same as the @code{tr} request except that the +translations do not apply to text that is transparently throughput into +a diversion with @code{\!}. @xref{Diversions}. + +For example, + +@Example +.tr ab +.di x +\!.tm a +.di +.x +@endExample + +@noindent +prints @samp{b} to the standard error stream; if @code{trnt} is used +instead of @code{tr} it prints @samp{a}. +@endDefreq + + +@c ===================================================================== + +@node @code{troff} and @code{nroff} Modes, Line Layout, Character Translations, GNU troff Reference +@section @code{troff} and @code{nroff} Modes +@cindex @code{troff} mode +@cindex mode, @code{troff} +@cindex @code{nroff} mode +@cindex mode, @code{nroff} + +Historically, @code{nroff} and @code{troff} were two separate programs; +the former for terminal output, the latter for typesetters. GNU +@code{troff} merges both functions into one executable@footnote{A +GNU @command{nroff} program is available for convenience; it calls GNU +@code{troff} to perform the formatting.} that sends its output to a +device driver (@code{grotty} for terminal devices, @code{grops} for +PostScript, and so on) which interprets this intermediate output format. +When discussing @acronym{AT&T} @code{troff}, it makes sense to talk +about @dfn{@code{nroff} mode} and @dfn{@code{troff} mode} since the +differences are hard-coded. GNU @code{troff} takes information from +device and font description files without handling requests specially if +a terminal output device is used, so such a strong distinction is +unnecessary. + +Usually, a macro package can be used with all output devices. +Nevertheless, it is sometimes necessary to make a distinction between +terminal and non-terminal devices: GNU @code{troff} provides two +built-in conditions @samp{n} and @samp{t} for the @code{if}, @code{ie}, +and @code{while} requests to decide whether GNU @code{troff} shall +behave like @code{nroff} or like @code{troff}. + +@Defreq {troff, } +@pindex troffrc +@pindex troffrc-end +Make the @samp{t} built-in condition true (and the @samp{n} built-in +condition false) for @code{if}, @code{ie}, and @code{while} conditional +requests. This is the default if GNU @code{troff} (@emph{not} +@code{groff}) is started with the @option{-R} switch to avoid loading of +the startup files @file{troffrc} and @file{troffrc-end}. Without +@option{-R}, GNU @code{troff} stays in @code{troff} mode if the output +device is not a terminal (e.g., `ps'). +@endDefreq + +@Defreq {nroff, } +@pindex tty.tmac +Make the @samp{n} built-in condition true (and the @samp{t} built-in +condition false) for @code{if}, @code{ie}, and @code{while} conditional +requests. This is the default if GNU @code{troff} uses a terminal +output device; the code for switching to @code{nroff} mode is in the +file @file{tty.tmac}, which is loaded by the startup file +@code{troffrc}. +@endDefreq + +@xref{Conditionals and Loops}, for more details on built-in conditions. + + +@c ===================================================================== + +@node Line Layout, Line Continuation, @code{troff} and @code{nroff} Modes, GNU troff Reference +@section Line Layout +@cindex line layout +@cindex layout, line + +@cindex dimensions, line +@cindex line dimensions +The following drawing shows the dimensions that @code{gtroff} uses for +placing a line of output onto the page. They are labeled with the +request that manipulates each dimension. + +@Example + -->| in |<-- + |<-----------ll------------>| + +----+----+----------------------+----+ + | : : : | + +----+----+----------------------+----+ +-->| po |<-- + |<--------paper width---------------->| +@endExample + +@noindent +These dimensions are: + +@ftable @code +@item po +@cindex left margin (@code{po}) +@cindex margin, left (@code{po}) +@cindex page offset (@code{po}) +@cindex offset, page (@code{po}) +@dfn{Page offset}---this is the leftmost position of text on the final +output, defining the @dfn{left margin}. + +@item in +@cindex indentation (@code{in}) +@cindex line indentation (@code{in}) +@dfn{Indentation}---this is the distance from the left margin where +text is printed. + +@item ll +@cindex line length (@code{ll}) +@cindex length of line (@code{ll}) +@dfn{Line length}---this is the distance from the left margin to right +margin. +@end ftable + +@cindex margin, right +@cindex right margin +The right margin is not explicitly configured; the combination of page +offset and line length provides the information necessary to derive it. + +A simple demonstration: + +@Example +.ll 3i +This is text without indentation. +The line length has been set to 3\~inches. +.in +.5i +.ll -.5i +Now the left and right margins are both increased. +.in +.ll +Calling .in and .ll without parameters restores +the previous values. +@endExample + +@Example + @result{} This is text without indenta- + @result{} tion. The line length has + @result{} been set to 3 inches. + @result{} Now the left and + @result{} right margins are + @result{} both increased. + @result{} Calling .in and .ll without + @result{} parameters restores the previ- + @result{} ous values. +@endExample + +@DefreqList {po, [@Var{offset}]} +@DefreqItem {po, @t{+}@Var{offset}} +@DefreqItem {po, @t{-}@Var{offset}} +@DefregListEndx {.o} +@pindex tty.tmac +Set page offset to @var{offset} (or increment or decrement its current +value by @var{offset}). If invoked without an argument, the page offset +is restored to the value before the previous @code{po} request. +This request does not cause a break; the page offset in effect when an +output line is broken prevails (@pxref{Manipulating Filling and +Adjustment}). The initial value is 1@dmn{i} and the default scaling +unit is @samp{m}. On terminal devices, the page offset is set to zero +by a driver-specific macro file, @file{tty.tmac}. The current page +offset can be found in the read-only register @samp{.o}. +@cindex CSTR@tie{}#54 errata +@cindex CSTR@tie{}#54 erratum, @code{po} request +This request is incorrectly documented in the @acronym{AT&T} +@code{troff} manual as using a default scaling unit of @samp{v}. + +@Example +.po 3i +\n[.o] + @result{} 720 +.po -1i +\n[.o] + @result{} 480 +.po +\n[.o] + @result{} 720 +@endExample +@endDefreq + +@DefreqList {in, [@Var{indent}]} +@DefreqItem {in, @t{+}@Var{indent}} +@DefreqItem {in, @t{-}@Var{indent}} +@DefregListEndx {.i} +Set indentation to @var{indent} (or increment or decrement the current +value by @var{indent}). This request causes a break. Initially, there +is no indentation. + +If @code{in} is called without an argument, the indentation is reset to +the previous value before the last call to @code{in}. The default +scaling unit is @samp{m}. + +If a negative indentation value is specified (which is not allowed), +@code{gtroff} emits a warning in category @samp{range} and sets the +indentation to zero. + +The effect of @code{in} is delayed until a partially collected line (if +it exists) is output. A temporary indentation value is reset to zero +also. + +The current indentation (as set by @code{in}) can be found in the +read-only register @samp{.i}. The indentation is associated with the +environment (@pxref{Environments}). +@endDefreq + +@DefreqList {ti, offset} +@DefreqItem {ti, @t{+}@Var{offset}} +@DefreqItem {ti, @t{-}@Var{offset}} +@DefregListEndx {.in} +Temporarily indent the next output line by @var{offset}. If an +increment or decrement value is specified, adjust the temporary +indentation relative to the value set by the @code{in} request. + +This request causes a break; its value is associated with the +environment (@pxref{Environments}). The default scaling unit is +@samp{m}. A call of @code{ti} without an argument is ignored. + +If the total indentation value is negative (which is not allowed), +@code{gtroff} emits a warning in category @samp{range} and sets the +temporary indentation to zero. `Total indentation' is either +@var{offset} if specified as an absolute value, or the temporary plus +normal indentation, if @var{offset} is given as a relative value. + +The effect of @code{ti} is delayed until a partially collected line (if +it exists) is output. + +The read-only register @code{.in} is the indentation that applies to the +current output line. + +The difference between @code{.i} and @code{.in} is that the latter takes +into account whether a partially collected line still uses the old +indentation value or a temporary indentation value is active. +@endDefreq + +@DefreqList {ll, [@Var{length}]} +@DefreqItem {ll, @t{+}@Var{length}} +@DefreqItem {ll, @t{-}@Var{length}} +@DefregItemx {.l} +@DefregListEndx {.ll} +Set the line length to @var{length} (or increment or decrement the +current value by @var{length}). Initially, the line length is set to +6.5@dmn{i}. The effect of @code{ll} is delayed until a partially +collected line (if it exists) is output. The default scaling unit is +@samp{m}. + +If @code{ll} is called without an argument, the line length is reset to +the previous value before the last call to @code{ll}. If a negative +line length is specified (which is not allowed), @code{gtroff} emits a +warning in category @samp{range} and sets the line length to zero. The +line length is associated with the environment (@pxref{Environments}). + +@cindex line length register (@code{.l}) +The current line length (as set by @code{ll}) can be found in the +read-only register @samp{.l}. The read-only register @code{.ll} is the +line length that applies to the current output line. + +Similar to @code{.i} and @code{.in}, the difference between @code{.l} +and @code{.ll} is that the latter takes into account whether a partially +collected line still uses the old line length value. +@endDefreq + + +@c ===================================================================== + +@node Line Continuation, Page Layout, Line Layout, GNU troff Reference +@section Line Continuation +@cindex line control +@cindex control, line + +When filling is enabled, input and output line breaks generally do not +correspond. The @code{roff} language therefore distinguishes input and +output line continuation. + +@Defesc {\\@key{RET}, , ,} +@cindex input line continuation (@code{\@key{RET}}) +@cindex line, input, continuation (@code{\@key{RET}}) +@cindex continuation, input line (@code{\@key{RET}}) +@c We use the following notation in our man pages; Texinfo is bound to +@c the GNU Emacs dialect. +@esindex \@slanted{newline} +@code{\@key{RET}} (a backslash immediately followed by a newline) +suppresses the effects of that newline in the input. The next input +line thus retains the classification of its predecessor as a control or +text line. @code{\@key{RET}} is useful for managing line lengths in the +input during document maintenance; you can break an input line in the +middle of a request invocation, macro call, or escape sequence. Input +line continuation is invisible to the formatter, with two exceptions: +the @code{|} operator recognizes the new input line +(@pxref{Numeric Expressions}), and the input line counter register +@code{.c} is incremented. + +@c Wrap example at 56 columns (on the _output_). We use 50n in the +@c groff input to avoid line adjustment. +@Example +.ll 50n +.de I +. ft I +. nop \\$* +. ft +.. +Our film class watched +.I The Effect of Gamma Rays on Man-in-the-Moon +Marigolds. \" whoops, the input line wrapped +.br +.I My own opus begins on line \n[.c] \ +and ends on line \n[.c]. +@endExample +@Example + @result{} Our film class watched @i{The Effect of Gamma Rays on} + @result{} @i{Man-in-the-Moon} Marigolds. + @result{} @i{My own opus begins on line 11 and ends on line 12.} +@endExample +@endDefesc + +@DefescList {\\c, , ,} +@DefregListEndx {.int} +@cindex output line, continuation (@code{\c}) +@cindex line, output, continuation (@code{\c}) +@cindex continuation, output line (@code{\c}) +@cindex interrupted line +@cindex line, interrupted +@cindex @code{\R}, after @code{\c} +@code{\c} continues an output line. Nothing after it on the input line +is formatted. In contrast to @code{\@key{RET}}, a line after @code{\c} +remains a new input line, so a control character is recognized at its +beginning. The visual results depend on whether filling is enabled; see +@ref{Manipulating Filling and Adjustment}. + +@itemize @bullet +@item +@cindex @code{\c}, when filling enabled +@cindex fill mode, and @code{\c} +@cindex mode, fill, and @code{\c} +If filling is enabled, a word interrupted with @code{\c} is continued +with the text on the next input text line, without an intervening space. + +@Example +This is a te\c +st. + @result{} This is a test. +@endExample + +@item +@cindex @code{\c}, when filling disabled +@cindex no-fill mode, and @code{\c} +@cindex mode, no-fill, and @code{\c} +If filling is disabled, the next input text line after @code{\c} is +handled as a continuation of the same input text line. + +@Example +.nf +This is a \c +test. + @result{} This is a test. +@endExample +@end itemize + +An intervening control line that causes a break overrides @code{\c}, +flushing out the pending output line in the usual way. + +@cindex interrupted line register (@code{.int}) +@cindex continued output line register (@code{.int}) +The @code{.int} register contains a positive value if the last output +line was continued with @code{\c}; this datum is associated with the +environment (@pxref{Environments}).@footnote{Historically, the @code{\c} +escape sequence has proven challenging to characterize. Some sources +say it ``connects the next input text'' (to the input line on which it +appears); others describe it as ``interrupting'' text, on the grounds +that a text line is interrupted without breaking, perhaps to inject a +request invocation or macro call.} +@endDefesc + + +@c ===================================================================== + +@node Page Layout, Page Control, Line Continuation, GNU troff Reference +@section Page Layout +@cindex page layout +@cindex layout, page + +The formatter permits configuration of the page length and page number. + +@DefreqList {pl, [@Var{length}]} +@DefreqItem {pl, @t{+}@Var{length}} +@DefreqItem {pl, @t{-}@Var{length}} +@DefregListEndx {.p} +@cindex page length, configuring (@code{pl}) +@cindex length of the page, configuring (@code{pl}) +@cindex configuring the page length (@code{pl}) +@cindex setting the page length (@code{pl}) +Change (increase or decrease) the page length per the numeric expression +@var{length}. The default scaling unit is @samp{v}. A negative +@var{length} is valid, but an uncommon application:@: it prevents page +location traps from being sprung,@footnote{@xref{Traps}.} and each +output line is placed on a new page. If @var{length} is invalid, GNU +@code{troff} emits a warning in category @samp{number}. If @var{length} +is absent or invalid, @samp{11i} is assumed. + +@cindex page length register (@code{.p}) +The read-only register @samp{.p} interpolates the current page length. +@endDefreq + +@DefreqList {pn, num} +@DefreqItem {pn, @t{+}@Var{num}} +@DefreqItem {pn, @t{-}@Var{num}} +@DefregListEndx {.pn} +@cindex page number, configuring next (@code{pn}) +@cindex next page number, configuring (@code{pn}) +@cindex number, page, next, configuring (@code{pn}) +Change (increase or decrease) the page number of the @emph{next} page +per the numeric expression @var{num}. If @var{num} is invalid, GNU +@code{troff} emits a warning in category @samp{number} and ignores the +request. Without an argument, @code{pn} is ignored. + +@cindex next page number register (@code{.pn}) +@cindex page number, next, register (@code{.pn}) +The read-only register @code{.pn} interpolates @var{num} if set by +@code{pn} on the current page, or the current page number plus@tie{}1. +@endDefreq + +@cindex headers +@cindex footers +@cindex titles +The formatter offers special support for typesetting headers and +footers, collectively termed @dfn{titles}. Titles have an independent +line length, and their placement on the page is not restricted. + +@Defreq {tl, @code{'}@Var{left}@code{'}@Var{center}@code{'}@Var{right}@code{'}} +@cindex title line, formatting (@code{tl}) +@cindex formatting a title line (@code{tl}) +@cindex three-part title (@code{tl}) +@cindex page number character (@code{%}) +Format an output line as a title consisting of @var{left}, @var{center}, +and @var{right}, each aligned accordingly. The delimiter need not be a +neutral apostrophe: @code{tl} accepts the same delimiters as most escape +sequences; see @ref{Delimiters}. If not used as the delimiter, any +@dfn{page number character} character is replaced with the current page +number; the default is @samp{%}; see the the @code{pc} request below. +Without an argument, @code{tl} is ignored. @code{tl} writes the title +line immediately, ignoring any partially collected line. + +It is not an error to omit delimiters after the first. For example, +@w{@samp{.tl /Thesis}} is interpreted as @w{@samp{.tl /Thesis///}}:@: it +sets a title line comprising only the left-aligned word @samp{Thesis}. +@endDefreq + +@DefreqList {lt, [@Var{length}]} +@DefreqItem {lt, @t{+}@Var{length}} +@DefreqItem {lt, @t{-}@Var{length}} +@DefregListEndx {.lt} +@cindex length of title line, configuring (@code{lt}) +@cindex title length, configuring (@code{lt}) +Change (increase or decrease) the line length used by titles per the +numeric expression @var{length}. The default scaling unit is @samp{m}. +If @var{length} is negative, GNU emits a warning in category +@samp{range} and treats @var{length} as @samp{0}. If @var{length} is +invalid, GNU @code{troff} emits a warning in category @samp{number} and +ignores the request. The formatter's default title length is +@samp{6.5i}. With no argument, the title length is restored to the +previous value. The title length is is associated with the environment +(@pxref{Environments}). + +@cindex title line length register (@code{.lt}) +The read-only register @samp{.lt} interpolates the title line length. +@endDefreq + +@Defreq {pc, [@Var{char}]} +@cindex changing the page number character (@code{pc}) +@cindex page number character, changing (@code{pc}) +@vindex % +Set the page number character to @var{char}. With no argument, the page +number character is disabled. @code{pc} does not affect the +register@tie{}@code{%}. +@endDefreq + +The following example exercises title features. + +@Example +.lt 50n +This is my partially collected +.tl 'Isomers 2023'%'Dextrose Edition' +line. + @result{} Isomers 2023 1 Dextrose Edition + @result{} This is my partially collected line. +@endExample + +We most often see titles used in page header and footer traps. +@xref{Traps}. + +@c ===================================================================== + +@node Page Control, Using Fonts, Page Layout, GNU troff Reference +@section Page Control +@cindex page control +@cindex control, page + +@cindex page break +@cindex break, page +@cindex page ejection +@cindex ejection, page +Discretionary page breaks can prevent the unwanted separation of +content. A new page number takes effect during page ejection; see +@ref{The Implicit Page Trap}. + +@DefreqList {bp, [@Var{page-number}]} +@DefreqItem {bp, @t{+}@Var{page-number}} +@DefreqItem {bp, @t{-}@Var{page-number}} +@DefregListEndx {%} +@cindex new page (@code{bp}) +@cindex page, new (@code{bp}) +Break the page and change (increase or decrease) the next page number +per the numeric expression @var{page-number}. If @var{page-number} is +invalid, GNU @code{troff} emits a warning in category @samp{number} and +ignores the argument. This request causes a break. A page break +advances the vertical drawing position to the bottom of the page, +springing traps. @xref{Page Location Traps}. +@cindex @code{bp} request, and top-level diversion +@cindex top-level diversion, and @code{bp} +@cindex diversion, top-level, and @code{bp} +@code{bp} has effect only if invoked within the top-level +diversion.@footnote{@xref{Diversions}.} +@cindex CSTR@tie{}#54 errata +@cindex CSTR@tie{}#54 erratum, @code{bp} request +This request is incorrectly documented in the @acronym{AT&T} +@code{troff} manual as having a default scaling unit of @samp{v}. + +@cindex page number register (@code{%}) +@cindex current page number (@code{%}) +The register @code{%} interpolates the current page number. + +@Example +.de BP +' bp \" schedule page break once current line is output +.. +@endExample +@endDefreq + +@Defreq {ne, [@Var{space}]} +@cindex orphan lines, preventing with @code{ne} +@cindex conditional page break (@code{ne}) +@cindex page break, conditional (@code{ne}) +Force a page break if insufficient vertical space is available (assert +``needed'' space). @code{ne} tests the distance to the next page +location trap; see @ref{Page Location Traps}, and breaks the page if +that amount is less than @var{space}. The default scaling unit is +@samp{v}. If @var{space} is invalid, GNU @code{troff} emits a warning +in category @samp{number} and ignores the argument. If @var{space} is +not specified, @samp{1v} is assumed. + +@cindex widow +We can require space for at least the first two output lines of a +paragraph, preventing its first line from being @slanted{widowed} at the +page bottom. + +@Example +.ne 2v +Considering how common illness is, +how tremendous the spiritual change that it brings, +how astonishing, +when the lights of health go down, +the undiscovered countries that are then disclosed, +what wastes and deserts of the soul a slight attack +of influenza brings to view, +@c -- Virgina Woolf, "On Being Ill", 1926 +@endExample + +@c XXX: Some of this might be better placed in a revised Chapter 3. +This method is reliable only if no output line is pending when @code{ne} +is invoked. When macro packages are used, this is often not the case:@: +their paragraphing macros perform the break. You may need to experiment +with placing the @code{ne} after the paragraphing macro, or @code{br} +and @code{ne} before it. + +@cindex orphan +@cindex widow +@code{ne} is also useful to force grouping of section headings with +their subsequent paragraphs, or tables with their captions and/or +explanations. Macro packages often use @code{ne} with diversions to +implement keeps and displays; see @ref{Diversions}. They may also offer +parameters for widow and orphan management. +@endDefreq + +@DefreqList {sv, [@Var{space}]} +@DefreqListEndx {os, } +@cindex @code{ne} request, comparison with @code{sv} +Require vertical space as @code{ne} does, but also @slanted{save} it for +later output by the @code{os} request. If @var{space} is available +before the next page location trap, it is output immediately. Both +requests ignore a partially collected line, taking effect at the next +break. +@cindex @code{sv} request, and no-space mode +@cindex @code{os} request, and no-space mode +@code{sv} and @code{os} ignore no-space mode (recall @ref{Manipulating +Spacing}). While the @code{sv} request allows negative values for +@var{space}, @code{os} ignores them. The default scaling unit is +@samp{v}. If @var{space} is not specified, @samp{1v} is assumed. +@endDefreq + +@Defreg {nl} +@cindex vertical drawing position (@code{nl}) +@cindex vertical position, drawing (@code{nl}) +@cindex drawing position, vertical (@code{nl}) +@c TODO: We should talk somewhere prior to this point about how the +@c formatter doesn't start a page until it has to. +@code{nl} interpolates or sets the vertical drawing position. When the +formatter starts, the first page transition hasn't happened yet, and +@code{nl} is negative. If a header trap has been planted on the page +(typically at vertical position @code{0}), you can assign a negative +value to @code{nl} to spring it if that page has already started +(@pxref{Page Location Traps}). + +@Example +.de HD +. sp +. tl ''Goldbach Solution'' +. sp +.. +. +First page. +.bp +.wh 0 HD \" plant header trap at top of page +.nr nl (-1) +Second page. + @result{} First page. + @result{} + @result{} @r{@i{(blank lines elided)}} + @result{} + @result{} Goldbach Solution + @result{} + @result{} @r{@i{(blank lines elided)}} + @result{} + @result{} Second page. +@endExample + +@noindent +Without resetting @code{nl} to a negative value, the trap just planted +would be active beginning with the @emph{next} page, not the current +one. + +@xref{Diversions}, for a comparison of @code{nl} with the @code{.h} and +@code{.d} registers. +@endDefreg + + +@c ===================================================================== + +@c BEGIN Keep (roughly) parallel with section "Using fonts" of groff(7). +@node Using Fonts, Manipulating Type Size and Vertical Spacing, Page Control, GNU troff Reference +@section Using Fonts +@cindex font + +@cindex typeface +@cindex font family +@cindex font style +@cindex style, font +@cindex family, font +@cindex text font +@cindex special font +@cindex unstyled font +@cindex font, text +@cindex font, special +@cindex font, unstyled +In digital typography, a @dfn{font} is a collection of characters in a +specific typeface that a device can render as glyphs at a desired +size.@footnote{Terminals and some output devices have fonts that render +at only one or two sizes. As examples of the latter, take the +@code{groff} @code{lj4} device's Lineprinter, and @code{lbp}'s Courier +and Elite faces.} A @code{roff} formatter can change typefaces at any +point in the text. The basic faces are a set of @dfn{styles} combining +upright and slanted shapes with normal and heavy stroke weights: +@samp{R}, @samp{I}, @samp{B}, and @samp{BI}---these stand for +@slanted{roman}, @slanted{italic}, @slanted{bold}, and +@slanted{bold-italic}. For linguistic text, GNU @code{troff} groups +typefaces into @dfn{families} containing each of these +styles.@footnote{Font designers prepare families such that the styles +share esthetic properties.} A @dfn{text font} is thus often a family +combined with a style, but it need not be:@: consider the @code{ps} and +@code{pdf} devices' @code{ZCMI} (Zapf Chancery Medium italic)---often, +no other style of Zapf Chancery Medium is provided. On typesetting +devices, at least one @dfn{special font} is available, comprising +@dfn{unstyled} glyphs for mathematical operators and other purposes. + +@cindex font description file +@cindex description file, font +@cindex file, font description +@cindex font metrics +@cindex metrics, font +@cindex mounting position +@cindex mounting position +@cindex position, mounting +Like @acronym{AT&T} @code{troff}, GNU @code{troff} does not itself load +or manipulate a digital font file;@footnote{Historically, the fonts +@code{troff}s dealt with were not Free Software or, as with the Graphic +Systems C/A/T, did not even exist in the digital domain.} instead it +works with a @dfn{font description file} that characterizes it, +including its glyph repertoire and the @dfn{metrics} (dimensions) of +each glyph.@footnote{@xref{Font Description File Format}.} This +information permits the formatter to accurately place glyphs with +respect to each other. Before using a font description, the formatter +associates it with a @dfn{mounting position}, a place in an ordered list +of available typefaces. +@cindex abstract font style +@cindex font style, abstract +@cindex style, font, abstract +So that a document need not be strongly coupled to a specific font +family, in GNU @code{troff} an output device can associate a style in +the abstract sense with a mounting position. Thus the default family +can be combined with a style dynamically, producing a @dfn{resolved font +name}. + +Fonts often have trademarked names, and even Free Software fonts can +require renaming upon modification. @code{groff} maintains a +convention that a device's serif font family is given the name @samp{T} +(``Times''), its sans-serif family @samp{H} (``Helvetica''), and its +monospaced family @samp{C} (``Courier''). Historical inertia has driven +@code{groff}'s font identifiers to short uppercase abbreviations of font +names, as with @samp{TR}, @samp{TI}, @samp{TB}, @samp{TBI}, and a +special font @samp{S}. + +The default family used with abstract styles can be changed at any time; +initially, it is @samp{T}. Typically, abstract styles are arranged in +the first four mounting positions in the order shown above. The default +mounting position, and therefore style, is always @samp{1} (@samp{R}). +By issuing appropriate formatter instructions, you can override these +defaults before your document writes its first glyph. + +@cindex graphic renditions +@cindex renditions, graphic +@cindex character cell attributes +@cindex attributes, character cell +@cindex cell, character, attributes +Terminal output devices cannot change font families and lack special +fonts. They support style changes by overstriking, or by altering +ISO@tie{}6429/ECMA-48 @dfn{graphic renditions} (character cell +attributes). +@c END Keep (roughly) parallel with section "Using fonts" of groff(7). + +@menu +* Selecting Fonts:: +* Font Families:: +* Font Positions:: +* Using Symbols:: +* Character Classes:: +* Special Fonts:: +* Artificial Fonts:: +* Ligatures and Kerning:: +* Italic Corrections:: +* Dummy Characters:: +@end menu + +@c --------------------------------------------------------------------- + +@node Selecting Fonts, Font Families, Using Fonts, Using Fonts +@subsection Selecting Fonts +@cindex font, selection + +We use @dfn{font} to refer to any of several means of identifying a +font: by mounting position (@samp{3}), by abstract style (@samp{B}), or +by its identifier (@samp{TB}). + +@DefreqList {ft, [@Var{font}]} +@DefescItemx {\\f, , f, } +@DefescItem {\\f, (, fn, } +@DefescItem {\\f, [, font, ]} +@DefregListEndx {.fn} +@cindex changing fonts (@code{ft}, @code{\f}) +@cindex fonts, changing (@code{ft}, @code{\f}) +@cindex @code{sty} request, and changing fonts +@cindex @code{fam} request, and changing fonts +@cindex @code{\F}, and changing fonts +@kindex styles +@kindex family +@pindex DESC +@cindex selecting the previous font (@code{ft}) +@cindex previous font, selecting (@code{ft}) +@cindex font, previous, slecting (@code{ft}) +The @code{ft} request selects the typeface @var{font}. If the argument +is absent or @samp{P}, it selects the previously chosen font. If +@var{font} is a non-negative integer, it is interpreted as mounting +position; the font mounted there is selected. If that position refers +to an abstract style, it is combined with the default family (see +@code{fam} and @code{\F} below) to make a resolved font name. If the +mounting position is not a style and no font is mounted there, GNU +@code{troff} emits a warning in category @samp{font} and ignores the +request. + +If @var{font} matches a style name, it is combined with the current +family to make a resolved font name. Otherwise, @var{font} is assumed +to already be a resolved font name. + +@cindex automatic font mounting +@cindex font mounting, automatic +@cindex mounting, font, automatic +The resolved font name is subject to translation (see request @code{ftr} +below). Next, the (possibly translated) font name's mounting position +is looked up; if not mounted, @var{font} is sought on the file system as +a font description file and, if located, automatically mounted at the +next available position (see register @code{.fp} below). If the font +was mounted using an identifier different from its font description file +name (see request @code{fp} below), that file name is then looked up. +If a font description file for the resolved font name is not found, GNU +@code{troff} emits a warning in category @samp{font} and ignores the +request. + +The @code{\f} escape sequence is similar, using one-character name (or +mounting position) @var{f}, two-character name @var{fn}, or a name +@var{font} of arbitrary length. +@cindex previous font, selecting (@code{\f[]}, @code{\fP}) +@cindex font, previous, selecting (@code{\f[]}, @code{\fP}) +@samp{\f[]} selects the previous font. The syntax form @samp{\fP} is +supported for backward compatibility, and @samp{\f[P]} for consistency. + +@Example +eggs, bacon, +.ft I +spam, +.ft +and sausage. +.br +eggs, bacon, \fIspam,\fP and sausage. + @result{} eggs, bacon, @slanted{spam,} and sausage + @result{} eggs, bacon, @slanted{spam,} and sausage +@endExample + +The current and previously selected fonts are properties of the +environment (@pxref{Environments}). + +The read-only string-valued register @code{.fn} contains the resolved +font name of the selected font. + +@code{\f} doesn't produce an input token in GNU @code{troff}; it thus +can be used in requests that expect a single-character argument. We can +assign a font to a margin character as follows (@pxref{Miscellaneous}). + +@Example +.mc \f[I]x\f[] +@endExample +@endDefreq + +@Defreq {ftr, f [@Var{g}]} +@cindex font translation (@code{ftr}) +@cindex @code{ft} request, and font translations +@cindex @code{ul} request, and font translations +@cindex @code{bd} request, and font translations +@cindex @code{\f}, and font translations +@cindex @code{cs} request, and font translations +@cindex @code{tkf} request, and font translations +@cindex @code{special} request, and font translations +@cindex @code{fspecial} request, and font translations +@cindex @code{fp} request, and font translations +@cindex @code{sty} request, and font translations +@cindex @code{if} request, and font translations +@cindex @code{ie} request, and font translations +@cindex @code{while} request, and font translations +Translate font@tie{}@var{f} to font@tie{}@var{g}. Whenever a font +named@tie{}@var{f} is referred to in a @code{\f} escape sequence, in the +@code{F} and @code{S} conditional operators, or in the @code{ft}, +@code{ul}, @code{bd}, @code{cs}, @code{tkf}, @code{special}, +@code{fspecial}, @code{fp}, or @code{sty} requests, font@tie{}@var{g} is +used. If @var{g} is missing or equal to@tie{}@var{f} the translation is +undone. +@c XXX: Do font translations work on mounting positions? Abstract +@c styles? + +Font translations cannot be chained. + +@Example +.ftr XXX TR +.ftr XXX YYY +.ft XXX + @error{} warning: can't find font 'XXX' +@endExample +@endDefreq + +@DefreqList {fzoom, f [@Var{zoom}]} +@DefregListEndx {.zoom} +@cindex magnification of a font (@code{fzoom}) +@cindex font, magnification (@code{fzoom}) +@cindex zoom factor of a font (@code{fzoom}) +@cindex factor, zoom, of a font (@code{fzoom}) +@cindex font, zoom factor (@code{fzoom}) +@cindex optical size of a font +@cindex font, optical size +@cindex size, optical, of a font +Set magnification of font@tie{}@var{f} to factor @var{zoom}, which must +be a non-negative integer multiple of 1/1000th. This request is useful +to adjust the optical size of a font in relation to the others. In the +example below, font @code{CR} is magnified by 10% (the zoom factor is +thus 1.1). + +@Example +.fam P +.fzoom CR 1100 +.ps 12 +Palatino and \f[CR]Courier\f[] +@endExample + +A missing or zero value of @var{zoom} is the same as a value of 1000, +which means no magnification. @var{f}@tie{}must be a resolved font +name, not an abstract style. +@c XXX: What about a mounting position? It's not rejected... + +The magnification of a font is completely transparent to GNU +@code{troff}; a change of the zoom factor doesn't cause any effect +except that the dimensions of glyphs, (word) spaces, kerns, etc., of the +affected font are adjusted accordingly. + +The zoom factor of the current font is available in the read-only +register @samp{.zoom}, in multiples of 1/1000th. It returns zero if +there is no magnification. +@endDefreq + +@c --------------------------------------------------------------------- + +@node Font Families, Font Positions, Selecting Fonts, Using Fonts +@subsection Font Families +@cindex font families +@cindex families, font +@cindex font styles +@cindex styles, font + +To accommodate the wide variety of fonts available, GNU @code{troff} +distinguishes @dfn{font families} and @dfn{font styles}. A resolved +font name is the catenation of a font family and a style. Selecting an +abstract style causes GNU @code{troff} to combine it with the default +font family. + +You can thus compose a document using abstract styles exclusively for +its body or running text, selecting a specific family only for titles or +examples, for instance, and change the default family on the command +line (recall @ref{Groff Options}). + +Fonts for the devices @code{ps}, @code{pdf}, @code{dvi}, @code{lj4}, +@code{lbp}, and the X11 devices support this mechanism. By default, +GNU @code{troff} uses the Times family with the four styles @samp{R}, +@samp{I}, @samp{B}, and @samp{BI}. + +@DefreqList {fam, [@Var{family}]} +@DefregItemx {.fam} +@DefescItemx {\\F, , f, } +@DefescItem {\\F, (, fm, } +@DefescListEnd {\\F, [, family, ]} +@cindex changing font family (@code{fam}, @code{\F}) +@cindex font family, changing (@code{fam}, @code{\F}) +Set the default font family, used in combination with abstract styles to +construct a resolved font name, to @var{family} (one-character +name@tie{}@var{f}, two-character name @var{fm}). If no argument is +given, GNU @code{troff} selects the previous font family; if there none, +is it falls back to the device's default@footnote{@xref{DESC File +Format}.} or its own (@samp{T}). + +The @code{\F} escape sequence works similarly. In disanalogy to +@code{\f}, @samp{\FP} makes @samp{P} the default family. Use +@samp{\F[]} to select the previous default family. The default font +family is available in the read-only string-valued register @code{.fam}; +it is associated with the environment (@pxref{Environments}). + +@Example +spam, \" startup defaults are T (Times) R (roman) +.fam H \" make Helvetica the default family +spam, \" family H + style R = HR +.ft B \" family H + style B = HB +spam, +.ft CR \" Courier roman (default family not changed) +spam, +.ft \" back to Helvetica bold +spam, +.fam T \" make Times the default family +spam, \" family T + style B = TB +.ft AR \" font AR (not a style) +baked beans, +.ft R \" family T + style R = TR +and spam. +@endExample + +@code{\F} doesn't produce an input token in GNU @code{troff}. As a +consequence, it can be used in requests like @code{mc} (which expects +a single character as an argument) to change the font family on the fly. + +@Example +.mc \F[P]x\F[] +@endExample +@endDefreq + +@need 1000 +@DefreqList {sty, n style} +@DefregListEndx {.sty} +@cindex setting up an abstract font style (@code{sty}) +@cindex abstract font style, setting up (@code{sty}) +@cindex font style, abstract, setting up (@code{sty}) +@cindex style, font, abstract, setting up (@code{sty}) +@cindex @code{cs} request, and font styles +@cindex @code{bd} request, and font styles +@cindex @code{tkf} request, and font styles +@cindex @code{uf} request, and font styles +@cindex @code{fspecial} request, and font styles +Associate an abstract style @var{style} with mounting +position@tie{}@var{n}, which must be a non-negative integer. If the +requests @code{cs}, @code{bd}, @code{tkf}, @code{uf}, or @code{fspecial} +are applied to an abstract style, they are instead applied to the member +of the current family corresponding to that style. + +@pindex DESC +@kindex styles +The default family can be set with the @option{-f} option (@pxref{Groff +Options}). The @code{styles} command in the @file{DESC} file controls +which font positions (if any) are initially associated with abstract +styles rather than fonts. + +@strong{Caution:@:} The @var{style} argument is not validated. +@c XXX: This would be a really good thing to fix. +Errors may occur later, when the formatter attempts to construct a +resolved font name, or format a character for output. + +@Example +.nr BarPos \n[.fp] +.sty \n[.fp] Bar +.fam Foo +.ft \n[BarPos] +.tm .f=\n[.f] +A + @error{} error: no font family named 'Foo' exists + @error{} .f=41 + @error{} error: cannot format glyph: no current font +@endExample + +When an abstract style has been selected, the read-only string-valued +register @samp{.sty} interpolates its name; this datum is associated +with the environment (@pxref{Environments}). Otherwise, @samp{.sty} +interpolates nothing. +@endDefreq + +@c --------------------------------------------------------------------- + +@node Font Positions, Using Symbols, Font Families, Using Fonts +@subsection Font Positions +@cindex font positions +@cindex positions, font + +To support typeface indirection through abstract styles, and for +compatibility with @acronym{AT&T} @code{troff}, the formatter maintains +a list of font @dfn{positions} at which fonts required by a document are +@dfn{mounted}. An output device's description file @file{DESC} +typically configures a set of pre-mounted fonts; see @ref{Device and +Font Description Files}. A font need not be explicitly mounted before +it is selected; GNU @code{troff} will search @env{GROFF_FONT_PATH} for +it by name and mount it at the first free mounting position on demand. + +@need 500 +@DefreqList {fp, pos id [@Var{font-description-file-name}]} +@DefregItemx {.f} +@DefregListEndx {.fp} +@cindex mounting a font (@code{fp}) +@cindex font, mounting (@code{fp}) +Mount a font under the name @var{id} at mounting position @var{pos}, a +non-negative integer. When the formatter starts up, it reads the output +device's description to mount an initial set of faces, and selects font +position@tie{}1. Position@tie{}0 is unused by default. Unless the +@var{font-description-file-name} argument is given, @var{id} should be +the name of a font description file stored in a directory corresponding +to the selected output device. GNU @code{troff} does not traverse +directories to locate the font description file. + +@c The third argument was a late revision to device-independent troff. +@c It wasn't in the "Unix 4.0" version of CSTR #54 (January 1981), which +@c featured Kernighan's device-independent rewrite, but appeared by the +@c time of its 1992 revision. +@cindex font aliasing with third argument to @code{fp} request +@cindex aliasing fonts with third argument to @code{fp} request +The optional third argument enables font names to be aliased, which can +be necessary in compatibility mode since AT&T @code{troff} syntax +affords no means of identifying fonts with names longer than two +characters, like @samp{TBI} or @samp{ZCMI}, in a font selection escape +sequence. @xref{Compatibility Mode}. You can also alias fonts on +mounting for convenience or abstraction. (See below regarding the +@code{.fp} register.) + +@Example +.fp \n[.fp] SC ZCMI +Send a \f(SChand-written\fP thank-you note. +.fp \n[.fp] Emph TI +.fp \n[.fp] Strong TB +Are \f[Emph]these names\f[] \f[Strong]comfortable\f[]? +@endExample + +@samp{DESC}, @samp{P}, and non-negative integers are not usable as font +identifiers. +@c XXX: TODO: Catch the DESC case earlier and throw an error for it. +@c XXX: This identifier could be used as a style name, but no one's +@c exercised this freedom in 30+ years, and we should consider +@c prohibiting it. --GBR + +@cindex font position register (@code{.f}) +The position of the currently selected font (or abstract style) is +available in the read-only register @samp{.f}. It is associated with +the environment (@pxref{Environments}). + +You can copy the value of @code{.f} to another register to save it for +later use. + +@Example +.nr saved-font \n[.f] +@r{@dots{} @i{text involving many font changes} @dots{}} +.ft \n[saved-font] +@endExample + +@cindex next free font position register (@code{.fp}) +The index of the next (non-zero) free font position is available in the +read-only register @samp{.fp}. +@cindex @file{DESC} file, and font mounting +Fonts not listed in the @file{DESC} file are automatically mounted at +position @samp{\n[.fp]} when selected with the @code{ft} request or +@code{\f} escape sequence. When mounting a font at a position +explicitly with the @code{fp} request, this same practice should be +followed, although GNU @code{troff} does not enforce this strictly. +@endDefreq + +@c --------------------------------------------------------------------- + +@node Using Symbols, Character Classes, Font Positions, Using Fonts +@subsection Using Symbols +@cindex using symbols +@cindex symbols, using + +@cindex glyph +@cindex character +@cindex glyph, distinguished from character +@cindex character, distinguished from glyph +@cindex ligature +A @dfn{glyph} is a graphical representation of a @dfn{character}. While +a character is an abstraction of semantic information, a glyph is +something that can be seen on screen or paper. A character has many +possible representation forms (for example, the character `A' can be +written in an upright or slanted typeface, producing distinct +glyphs). Sometimes, a sequence of characters map to a single glyph:@: +this is a @dfn{ligature}---the most common is `fi'. + +Space characters never become glyphs in GNU @code{troff}. If not +discarded (as when trailing on text lines), they are represented by +horizontal motions in the output. + +@cindex symbol +@cindex special fonts +@kindex fonts +@pindex DESC +@cindex @code{special} request, and glyph search order +@cindex @code{fspecial} request, and glyph search order +A @dfn{symbol} is simply a named glyph. Within @code{gtroff}, all glyph +names of a particular font are defined in its font file. If the user +requests a glyph not available in this font, @code{gtroff} looks up an +ordered list of @dfn{special fonts}. By default, the PostScript output +device supports the two special fonts @samp{SS} (slanted symbols) and +@samp{S} (symbols) (the former is looked up before the latter). Other +output devices use different names for special fonts. Fonts mounted +with the @code{fonts} keyword in the @file{DESC} file are globally +available. To install additional special fonts locally (i.e., for a +particular font), use the @code{fspecial} request. + +Here are the exact rules how @code{gtroff} searches a given symbol: + +@itemize @bullet +@item +If the symbol has been defined with the @code{char} request, use it. +This hides a symbol with the same name in the current font. + +@item +Check the current font. + +@item +If the symbol has been defined with the @code{fchar} request, use it. + +@item +Check whether the current font has a font-specific list of special +fonts; test all fonts in the order of appearance in the last +@code{fspecial} call if appropriate. + +@item +If the symbol has been defined with the @code{fschar} request for the +current font, use it. + +@item +Check all fonts in the order of appearance in the last @code{special} +call. + +@item +If the symbol has been defined with the @code{schar} request, use it. + +@item +As a last resort, consult all fonts loaded up to now for special fonts +and check them, starting with the lowest font number. This can +sometimes lead to surprising results since the @code{fonts} line in +the @file{DESC} file often contains empty positions, which are filled +later on. For example, consider the following: + +@Example +fonts 3 0 0 FOO +@endExample + +@noindent +This mounts font @code{foo} at font position@tie{}3. We assume that +@code{FOO} is a special font, containing glyph @code{foo}, and that no +font has been loaded yet. The line + +@Example +.fspecial BAR BAZ +@endExample + +@noindent +makes font @code{BAZ} special only if font @code{BAR} is active. We +further assume that @code{BAZ} is really a special font, i.e., the font +description file contains the @code{special} keyword, and that it also +contains glyph @code{foo} with a special shape fitting to font +@code{BAR}. After executing @code{fspecial}, font @code{BAR} is loaded +at font position@tie{}1, and @code{BAZ} at position@tie{}2. + +We now switch to a new font @code{XXX}, trying to access glyph +@code{foo} that is assumed to be missing. There are neither +font-specific special fonts for @code{XXX} nor any other fonts made +special with the @code{special} request, so @code{gtroff} starts the +search for special fonts in the list of already mounted fonts, with +increasing font positions. Consequently, it finds @code{BAZ} before +@code{FOO} even for @code{XXX}, which is not the intended behaviour. +@end itemize + +@xref{Device and Font Description Files}, and @ref{Special Fonts}, for +more details. + +@cindex list of special characters (@cite{groff_char@r{(7)}} man page) +@cindex special characters, list of (@cite{groff_char@r{(7)}} man page) +@cindex characters, special, list of (@cite{groff_char@r{(7)}} man page) +@cindex available glyphs, list of (@cite{groff_char@r{(7)}} man page) +@cindex glyphs, available, list of (@cite{groff_char@r{(7)}} man page) +The @cite{groff_char@r{(7)}} man page houses a complete list of +predefined special character names, but the availability of any as a +glyph is device- and font-dependent. For example, say + +@Example +man -Tdvi groff_char > groff_char.dvi +@endExample + +@noindent +to obtain those available with the DVI device and default font +configuration.@footnote{Not all versions of the @code{man} program +support the @option{-T} option; use the subsequent example for an +alternative.} If you want to use an additional macro package to change +the fonts used, @code{groff} (or @code{gtroff}) must be run directly. + +@Example +groff -Tdvi -mec -man groff_char.7 > groff_char.dvi +@endExample + +@cindex composite glyph names +@cindex glyph names, composite +@cindex @code{groff} glyph list (GGL) +@cindex GGL (@code{groff} glyph list) +@cindex Adobe Glyph List (AGL) +Special character names not listed in @cite{groff_char@r{(7)}} are +derived algorithmically, using a simplified version of the Adobe Glyph +List (AGL) algorithm, which is described in +@uref{https://github.com@//adobe-type-tools@//agl-aglfn}. The (frozen) +set of names that can't be derived algorithmically is called the +@dfn{@code{groff} glyph list (GGL)}. + +@itemize @bullet +@item +A glyph for Unicode character U+@var{XXXX}[@var{X}[@var{X}]], which is +not a composite character is named +@code{u@var{XXXX}@r{[}@var{X}@r{[}@var{X}@r{]]}}. @var{X} must be an +uppercase hexadecimal digit. Examples: @code{u1234}, @code{u008E}, +@code{u12DB8}. The largest Unicode value is 0x10FFFF. There must be at +least four @code{X} digits; if necessary, add leading zeroes (after the +@samp{u}). No zero padding is allowed for character codes greater than +0xFFFF. Surrogates (i.e., Unicode values greater than 0xFFFF +represented with character codes from the surrogate area U+D800-U+DFFF) +are not allowed either. + +@item +A glyph representing more than a single input character is named + +@display +@samp{u} @var{component1} @samp{_} @var{component2} @samp{_} @var{component3} @dots{} +@end display + +@noindent +Example: @code{u0045_0302_0301}. + +For simplicity, all Unicode characters that are composites must be +maximally decomposed to NFD;@footnote{This is ``Normalization Form D'' +as documented in Unicode Standard Annex #15 +(@uref{https://unicode.org@//reports@//tr15/}).} for example, +@code{u00CA_0301} is not a valid glyph name since U+00CA (@sc{latin +capital letter e with circumflex}) can be further decomposed into U+0045 +(@sc{latin capital letter e}) and U+0302 (@sc{combining circumflex +accent}). @code{u0045_0302_0301} is thus the glyph name for U+1EBE, +@sc{latin capital letter e with circumflex and acute}. + +@item +groff maintains a table to decompose all algorithmically derived glyph +names that are composites itself. For example, @code{u0100} (@sc{latin +letter a with macron}) is automatically decomposed into +@code{u0041_0304}. Additionally, a glyph name of the GGL is preferred +to an algorithmically derived glyph name; @code{groff} also +automatically does the mapping. Example: The glyph @code{u0045_0302} is +mapped to @code{^E}. + +@item +glyph names of the GGL can't be used in composite glyph names; for +example, @code{^E_u0301} is invalid. +@end itemize + +@DefescList {\\, (, nm, } +@DefescItem {\\, [, name, ]} +@DefescListEnd {\\, [, base-glyph combining-component @dots{}, ]} +@esindex \( +@esindex \[ +Typeset a special character @var{name} (two-character name @var{nm}) or +a composite glyph consisting of @var{base-glyph} overlaid with one or +more @var{combining-component}s. For example, @samp{\[A ho]} is a +capital letter ``A'' with a ``hook accent'' (ogonek). + +There is no special syntax for one-character names---the analogous form +@samp{\@var{n}} would collide with other escape sequences. However, the +four escape sequences @code{\'}, @code{\-}, @code{\_}, and @code{\`}, +are translated on input to the special character escape sequences +@code{\[aa]}, @code{\[-]}, @code{\[ul]}, and @code{\[ga]}, respectively. + +A special character name of length one is not the same thing as an +ordinary character: that is, the character @code{a} is not the same as +@code{\[a]}. + +If @var{name} is undefined, a warning in category @samp{char} is +produced and the escape is ignored. @xref{Warnings}, for information +about the enablement and suppression of warnings. + +GNU @code{troff} resolves @code{\[@r{@dots{}}]} with more than a single +component as follows: + +@itemize @bullet +@item +Any component that is found in the GGL is converted to the +@code{u@var{XXXX}} form. + +@item +Any component @code{u@var{XXXX}} that is found in the list of +decomposable glyphs is decomposed. + +@item +The resulting elements are then concatenated with @samp{_} in between, +dropping the leading @samp{u} in all elements but the first. +@end itemize + +No check for the existence of any component (similar to @code{tr} +request) is done. + +Examples: + +@table @code +@item \[A ho] +@samp{A} maps to @code{u0041}, @samp{ho} maps to @code{u02DB}, thus the +final glyph name would be @code{u0041_02DB}. This is not the expected +result:@: the ogonek glyph @samp{ho} is a spacing ogonek, but for a +proper composite a non-spacing ogonek (U+0328) is necessary. Looking +into the file @file{composite.tmac}, one can find @w{@samp{.composite ho +u0328}}, which changes the mapping of @samp{ho} while a composite glyph +name is constructed, causing the final glyph name to be +@code{u0041_0328}. + +@item \[^E u0301] +@itemx \[^E aa] +@itemx \[E a^ aa] +@itemx \[E ^ @code{'}] +@samp{^E} maps to @code{u0045_0302}, thus the final glyph name is +@code{u0045_0302_0301} in all forms (assuming proper calls of the +@code{composite} request). +@end table + +It is not possible to define glyphs with names like @w{@samp{A ho}} +within a @code{groff} font file. This is not really a limitation; +instead, you have to define @code{u0041_0328}. +@endDefesc + +@Defesc {\\C, @code{'}, xxx, @code{'}} +@cindex named character (@code{\C}) +@cindex character, named (@code{\C}) +Typeset the glyph of the special character @var{xxx}. Normally, it is +more convenient to use @code{\[@var{xxx}]}, but @code{\C} has some +advantages: it is compatible with @acronym{AT&T} device-independent +@code{troff} (and therefore available in compatibility +mode@footnote{@xref{Compatibility Mode}.}) and can interpolate special +characters with @samp{]} in their names. The delimiter need not be +a neutral apostrophe; see @ref{Delimiters}. +@endDefesc + +@Defreq {composite, id1 id2} +@pindex composite.tmac +Map special character name @var{id1} to @var{id2} if @var{id1} is used +in @code{\[...]} with more than one component. See above for examples. +This is a strict rewriting of the special character name; no check is +performed for the existence of a glyph for either. A set of default +mappings for many accents can be found in the file +@file{composite.tmac}, loaded by the default @file{troffrc} at startup. +@endDefreq + +@Defesc {\\N, @code{'}, n, @code{'}} +@cindex numbered glyph (@code{\N}) +@cindex glyph, numbered (@code{\N}) +@cindex @code{char} request, used with @code{\N} +@cindex Unicode +Typeset the glyph with code@tie{}@var{n} in the current font +(@code{n}@tie{}is @emph{not} the input character code). The number +@var{n}@tie{}can be any non-negative decimal integer. Most devices only +have glyphs with codes between 0 and@tie{}255; the Unicode output device +uses codes in the range 0--65535. If the current font does not contain +a glyph with that code, special fonts are @emph{not} searched. The +@code{\N} escape sequence can be conveniently used in conjunction with +the @code{char} request: + +@Example +.char \[phone] \f[ZD]\N'37' +@endExample + +@noindent +@pindex DESC +@cindex unnamed glyphs +@cindex glyphs, unnamed +The code of each glyph is given in the fourth column in the font +description file after the @code{charset} command. It is possible to +include unnamed glyphs in the font description file by using a name of +@samp{---}; the @code{\N} escape sequence is the only way to use these. + +No kerning is applied to glyphs accessed with @code{\N}. The delimiter +need not be a neutral apostrophe; see @ref{Delimiters}. +@endDefesc + +A few escape sequences are also special characters. + +@Defesc {\@code{'}, , , } +An escaped neutral apostrophe is a synonym for @code{\[aa]} (acute +accent). +@endDefesc + +@Defesc {\@code{`}, , , } +An escaped grave accent is a synonym for @code{\[ga]} (grave accent). +@endDefesc + +@Defesc {\\-, , , } +An escaped hyphen-minus is a synonym for @code{\[-]} (minus sign). +@endDefesc + +@Defesc {\\_, , , } +An escaped underscore (``low line'') is a synonym for @code{\[ul]} +(underrule). On typesetting devices, the underrule is font-invariant +and drawn lower than the underscore @samp{_}. +@endDefesc + +@Defreq {cflags, n c1 c2 @dots{}} +@cindex glyph properties (@code{cflags}) +@cindex character properties (@code{cflags}) +@cindex properties of glyphs (@code{cflags}) +@cindex properties of characters (@code{cflags}) +Assign properties encoded by the number @var{n} to characters @var{c1}, +@var{c2}, and so on. + +Input characters, including special characters introduced by an escape, +have certain properties associated with them.@footnote{Output glyphs +don't---to GNU @code{troff}, a glyph is simply a box with an index into +a font, a given height above and depth below the baseline, and a width.} +These properties can be modified with this request. The first argument +is the sum of the desired flags and the remaining arguments are the +characters to be assigned those properties. Spaces between the @var{cn} +arguments are optional. Any argument @var{cn} can be a character class +defined with the @code{class} request rather than an individual +character. @xref{Character Classes}. + +The non-negative integer @var{n} is the sum of any of the following. +Some combinations are nonsensical, such as @samp{33} (1 + 32). + +@table @code +@item 1 +@cindex end-of-sentence characters +@cindex characters, end-of-sentence +Recognize the character as ending a sentence if followed by a newline +or two spaces. Initially, characters @samp{.?!} have this property. + +@item 2 +@cindex hyphenating characters +@cindex characters, hyphenation +Enable breaks before the character. A line is not broken at a character +with this property unless the characters on each side both have non-zero +hyphenation codes. This exception can be overridden by adding 64. +Initially, no characters have this property. + +@item 4 +@cindex @code{\-} glyph, and @code{cflags} +@cindex @code{hy} glyph, and @code{cflags} +@cindex @code{em} glyph, and @code{cflags} +Enable breaks after the character. A line is not broken at a character +with this property unless the characters on each side both have non-zero +hyphenation codes. This exception can be overridden by adding 64. +Initially, characters @samp{\-\[hy]\[em]} have this property. + +@item 8 +@cindex overlapping characters +@cindex characters, overlapping +@cindex @code{ul} glyph, and @code{cflags} +@cindex @code{rn} glyph, and @code{cflags} +@cindex @code{ru} glyph, and @code{cflags} +@cindex @code{radicalex} glyph, and @code{cflags} +@cindex @code{sqrtex} glyph, and @code{cflags} +Mark the glyph associated with this character as overlapping other +instances of itself horizontally. Initially, characters +@samp{\[ul]\[rn]\[ru]\[radicalex]\[sqrtex]} have this property. + +@item 16 +@cindex @code{br} glyph, and @code{cflags} +Mark the glyph associated with this character as overlapping other +instances of itself vertically. Initially, the character @samp{\[br]} +has this property. + +@item 32 +@cindex transparent characters +@cindex character, transparent +@cindex @code{"}, at end of sentence +@cindex @code{'}, at end of sentence +@cindex @code{)}, at end of sentence +@cindex @code{]}, at end of sentence +@cindex @code{*}, at end of sentence +@cindex @code{dg} glyph, at end of sentence +@cindex @code{dd} glyph, at end of sentence +@cindex @code{rq} glyph, at end of sentence +@cindex @code{cq} glyph, at end of sentence +Mark the character as transparent for the purpose of end-of-sentence +recognition. In other words, an end-of-sentence character followed by +any number of characters with this property is treated as the end of a +sentence if followed by a newline or two spaces. This is the same as +having a zero space factor in @TeX{}. Initially, characters +@samp{"')]*\[dg]\[dd]\[rq]\[cq]} have this property. + +@item 64 +Ignore hyphenation codes of the surrounding characters. Use this in +combination with values 2 and@tie{}4 (initially, no characters have this +property). + +For example, if you need an automatic break point after the en-dash in +numeric ranges like ``3000--5000'', insert + +@Example +.cflags 68 \[en] +@endExample + +@noindent +into your document. However, this practice can lead to bad layout if +done thoughtlessly; in most situations, a better solution instead of +changing the @code{cflags} value is to insert @code{\:} right after the +hyphen at the places that really need a break point. +@end table + +The remaining values were implemented for East Asian language support; +those who use alphabetic scripts exclusively can disregard them. + +@table @code +@item 128 +Prohibit a line break before the character, but allow a line break after +the character. This works only in combination with flags 256 and 512 +and has no effect otherwise. Initially, no characters have this +property. + +@item 256 +Prohibit a line break after the character, but allow a line break before +the character. This works only in combination with flags 128 and 512 +and has no effect otherwise. Initially, no characters have this +property. + +@item 512 +Allow line break before or after the character. This works only in +combination with flags 128 and 256 and has no effect otherwise. +Initially, no characters have this property. +@end table + +In contrast to values 2 and@tie{}4, the values 128, 256, and 512 work +pairwise. If, for example, the left character has value 512, and the +right character 128, no break will be automatically inserted between +them. If we use value@tie{}6 instead for the left character, a break +after the character can't be suppressed since the neighboring character +on the right doesn't get examined. +@endDefreq + +@DefreqList {char, c [@Var{contents}]} +@DefreqItemx {fchar, c [@Var{contents}]} +@DefreqItemx {fschar, f c [@Var{contents}]} +@DefreqListEndx {schar, c [@Var{contents}]} +@cindex defining character (@code{char}) +@cindex defining fallback character (@code{fchar}, @code{fschar}, @code{schar}) +@cindex character, defining (@code{char}) +@cindex character, defining fallback (@code{fchar}, @code{fschar}, @code{schar}) +@cindex fallback character, defining (@code{fchar}, @code{fschar}, @code{schar}) +@cindex creating new characters (@code{char}) +@cindex defining symbol (@code{char}) +@cindex symbol, defining (@code{char}) +@cindex defining glyph (@code{char}) +@cindex glyph, defining (@code{char}) +@cindex escape character, while defining glyph +@cindex character, escape, while defining glyph +@cindex @code{tr} request, and glyph definitions +@cindex @code{cp} request, and glyph definitions +@cindex @code{rc} request, and glyph definitions +@cindex @code{lc} request, and glyph definitions +@cindex @code{\l}, and glyph definitions +@cindex @code{\L}, and glyph definitions +@cindex @code{\&}, and glyph definitions +@cindex @code{\e}, and glyph definitions +@cindex @code{hcode} request, and glyph definitions +Define a new character or glyph@tie{}@var{c} to be @var{contents}, which +can be empty. More precisely, @code{char} defines a @code{groff} object +(or redefines an existing one) that is accessed with the +name@tie{}@var{c} on input, and produces @var{contents} on output. +Every time glyph@tie{}@var{c} needs to be printed, @var{contents} is +processed in a temporary environment and the result is wrapped up into a +single object. Compatibility mode is turned off and the escape +character is set to@tie{}@code{\} while @var{contents} is processed. +Any emboldening, constant spacing, or track kerning is applied to this +object rather than to individual glyphs in @var{contents}. + +An object defined by these requests can be used just like a normal glyph +provided by the output device. In particular, other characters can be +translated to it with the @code{tr} or @code{trin} requests; it can be +made the leader character with the @code{lc} request; repeated patterns +can be drawn with it using the @code{\l} and @code{\L} escape sequences; +and words containing@tie{}@var{c} can be hyphenated correctly if the +@code{hcode} request is used to give the object a hyphenation code. + +There is a special anti-recursion feature: use of the object within its +own definition is handled like a normal character (not +defined with @code{char}). + +The @code{tr} and @code{trin} requests take precedence if @code{char} +accesses the same symbol. + +@Example +.tr XY +X + @result{} Y +.char X Z +X + @result{} Y +.tr XX +X + @result{} Z +@endExample + +The @code{fchar} request defines a fallback glyph: @code{gtroff} only +checks for glyphs defined with @code{fchar} if it cannot find the glyph +in the current font. @code{gtroff} carries out this test before +checking special fonts. + +@code{fschar} defines a fallback glyph for font@tie{}@var{f}: +@code{gtroff} checks for glyphs defined with @code{fschar} after the +list of fonts declared as font-specific special fonts with the +@code{fspecial} request, but before the list of fonts declared as global +special fonts with the @code{special} request. + +Finally, the @code{schar} request defines a global fallback glyph: +@code{gtroff} checks for glyphs defined with @code{schar} after the list +of fonts declared as global special fonts with the @code{special} +request, but before the already mounted special fonts. + +@xref{Character Classes}. +@endDefreq + +@DefreqList {rchar, c @dots{}} +@DefreqListEndx {rfschar, f c @dots{}} +@cindex removing glyph definition (@code{rchar}, @code{rfschar}) +@cindex glyph, removing definition (@code{rchar}, @code{rfschar}) +@cindex fallback glyph, removing definition (@code{rchar}, @code{rfschar}) +Remove definition of each ordinary or special character @var{c}, +undoing the effect of a @code{char}, @code{fchar}, or @code{schar} +request. Those supplied by font description files cannot be removed. +Spaces and tabs may separate @var{c}@tie{}arguments. + +The request @code{rfschar} removes glyph definitions defined with +@code{fschar} for font@tie{}@var{f}. +@endDefreq + +@c --------------------------------------------------------------------- + +@node Character Classes, Special Fonts, Using Symbols, Using Fonts +@subsection Character Classes +@cindex character classes +@cindex classes, character + +Classes are particularly useful for East Asian languages such as +Chinese, Japanese, and Korean, where the number of needed characters is +much larger than in European languages, and where large sets of +characters share the same properties. + +@Defreq {class, name c1 c2 @dots{}} +@cindex character class (@code{class}) +@cindex defining character class (@code{class}) +@cindex class of characters (@code{class}) +Define a character class (or simply ``class'') @var{name} comprising +the characters @var{c1}, @var{c2}, and so on. + +A class thus defined can then be referred to in lieu of listing all the +characters within it. Currently, only the @code{cflags} request can +handle references to character classes. + +In the request's simplest form, each @var{cn} is a character (or special +character). + +@Example +.class [quotes] ' \[aq] \[dq] \[oq] \[cq] \[lq] \[rq] +@endExample + +Since class and glyph names share the same name space, it is recommended +to start and end the class name with @code{[} and @code{]}, +respectively, to avoid collisions with existing character names defined +by GNU @code{troff} or the user (with @code{char} and related requests). +This practice applies the presence of @code{]} in the class name to +prevent the use of the special character escape form +@code{\[@r{@dots{}}]}, thus you must use the @code{\C} escape to access +a class with such a name. + +@cindex GGL (@code{groff} glyph list) +@cindex @code{groff} glyph list (GGL) +You can also use a character range notation consisting of a +start character followed by @samp{-} and then an end character. +Internally, GNU @code{troff} converts these two symbol names to +Unicode code points (according to the @code{groff} glyph list [GGL]), +which then give the start and end value of the range. If that fails, +the class definition is skipped. + +Furthermore, classes can be nested. + +@Example +.class [prepunct] , : ; > @} +.class [prepunctx] \C'[prepunct]' \[u2013]-\[u2016] +@endExample + +@noindent +The class @samp{[prepunctx]} thus contains the contents of the class +@code{[prepunct]} as defined above (the set @samp{, : ; > @}}), and +characters in the range between @code{U+2013} and @code{U+2016}. + +If you want to include @samp{-} in a class, it must be the first +character value in the argument list, otherwise it gets misinterpreted +as part of the range syntax. + +It is not possible to use class names as end points of range +definitions. + +A typical use of the @code{class} request is to control line-breaking +and hyphenation rules as defined by the @code{cflags} request. For +example, to inhibit line breaks before the characters belonging to the +@code{prepunctx} class defined in the previous example, you can write +the following. + +@Example +.cflags 2 \C'[prepunctx]' +@endExample + +@noindent +See the @code{cflags} request in @ref{Using Symbols}, for more details. +@endDefreq + +@c --------------------------------------------------------------------- + +@node Special Fonts, Artificial Fonts, Character Classes, Using Fonts +@subsection Special Fonts +@cindex special fonts +@cindex fonts, special + +Special fonts are those that @code{gtroff} searches when it cannot find +the requested glyph in the current font. The Symbol font is usually a +special font. + +@code{gtroff} provides the following two requests to add more special +fonts. @xref{Using Symbols}, for a detailed description of the glyph +searching mechanism in @code{gtroff}. + +Usually, only non-TTY devices have special fonts. + +@DefreqList {special, [@Var{s1} @Var{s2} @dots{}]} +@DefreqListEndx {fspecial, f [@Var{s1} @Var{s2} @dots{}]} +@kindex fonts +@pindex DESC +Use the @code{special} request to define special fonts. Initially, this +list is empty. + +Use the @code{fspecial} request to designate special fonts only when +font@tie{}@var{f} is active. Initially, this list is empty. + +Previous calls to @code{special} or @code{fspecial} are overwritten; +without arguments, the particular list of special fonts is set to empty. +Special fonts are searched in the order they appear as arguments. + +All fonts that appear in a call to @code{special} or @code{fspecial} +are loaded. + +@xref{Using Symbols}, for the exact search order of glyphs. +@endDefreq + +@c --------------------------------------------------------------------- + +@node Artificial Fonts, Ligatures and Kerning, Special Fonts, Using Fonts +@subsection Artificial Fonts +@cindex artificial fonts +@cindex fonts, artificial + +There are a number of requests and escape sequences for artificially +creating fonts. These are largely vestiges of the days when output +devices did not have a wide variety of fonts, and when @code{nroff} and +@code{troff} were separate programs. Most of them are no longer +necessary in GNU @code{troff}. Nevertheless, they are supported. + +@DefescList {\\H, @code{'}, height, @code{'}} +@DefescItem {\\H, @code{'}, @t{+}height, @code{'}} +@DefescItem {\\H, @code{'}, @t{-}height, @code{'}} +@DefregListEndx {.height} +@cindex changing the font height (@code{\H}) +@cindex font height, changing (@code{\H}) +@cindex height, font, changing (@code{\H}) +Change (increment, decrement) the height of the current font, but not +the width. If @var{height} is zero, restore the original height. +Default scaling unit is @samp{z}. + +The read-only register @code{.height} contains the font height as set by +@code{\H}. + +Currently, only the @option{-Tps} and @option{-Tpdf} devices support +this feature. + +@code{\H} doesn't produce an input token in GNU @code{troff}. As a +consequence, it can be used in requests like @code{mc} (which expects +a single character as an argument) to change the font on the fly: + +@Example +.mc \H'+5z'x\H'0' +@endExample + +In compatibility mode, @code{gtroff} behaves differently: If an +increment or decrement is used, it is always taken relative to the +current type size and not relative to the previously selected font +height. Thus, + +@Example +.cp 1 +\H'+5'test \H'+5'test +@endExample + +@noindent +prints the word @samp{test} twice with the same font height (five points +larger than the current font size). +@endDefesc + +@DefescList {\\S, @code{'}, slant, @code{'}} +@DefregListEndx {.slant} +@cindex changing the font slant (@code{\S}) +@cindex font slant, changing (@code{\S}) +@cindex slant, font, changing (@code{\S}) +Slant the current font by @var{slant} degrees. Positive values slant to +the right. Only integer values are possible. + +The read-only register @code{.slant} contains the font slant as set by +@code{\S}. + +Currently, only the @option{-Tps} and @option{-Tpdf} devices support +this feature. + +@code{\S} doesn't produce an input token in GNU @code{troff}. As a +consequence, it can be used in requests like @code{mc} (which expects +a single character as an argument) to change the font on the fly: + +@Example +.mc \S'20'x\S'0' +@endExample + +@cindex CSTR@tie{}#54 errata +@cindex CSTR@tie{}#54 erratum, @code{\S} escape +This escape is incorrectly documented in the @acronym{AT&T} +@code{troff} manual; the slant is always set to an absolute value. +@endDefesc + +@Defreq {ul, [@Var{lines}]} +@cindex underlining (@code{ul}) +The @code{ul} request normally underlines subsequent lines if a TTY +output device is used. Otherwise, the lines are printed in italics +(only the term `underlined' is used in the following). The single +argument is the quantity of input lines to be underlined; with no +argument, the next line is underlined. If @var{lines} is zero or +negative, stop the effects of @code{ul} (if it was active). Requests +and empty lines do not count for computing the number of underlined +input lines, even if they produce some output like @code{tl}. Lines +inserted by macros (e.g., invoked by a trap) do count. + +At the beginning of @code{ul}, the current font is stored and the +underline font is activated. Within the span of a @code{ul} request, it +is possible to change fonts, but after the last line affected by +@code{ul} the saved font is restored. + +This number of lines still to be underlined is associated with the +environment (@pxref{Environments}). The underline font can be changed +with the @code{uf} request. + +@c XXX @xref should be changed to grotty + +@c @xref{@code{troff} and @code{nroff} Modes}, for a discussion of how +@c underlining is implemented for terminal output devices, and what +@c problems can arise. + +The @code{ul} request does not underline spaces. +@endDefreq + +@Defreq {cu, [@Var{lines}]} +@cindex continuous underlining (@code{cu}) +@cindex underlining, continuous (@code{cu}) +The @code{cu} request is similar to @code{ul} but underlines spaces as +well (if a TTY output device is used). +@endDefreq + +@Defreq {uf, font} +@cindex underline font (@code{uf}) +@cindex font for underlining (@code{uf}) +Set the underline font (globally) used by @code{ul} and @code{cu}. By +default, this is the font at position@tie{}2. @var{font} can be either +a non-negative font position or the name of a font. +@endDefreq + +@DefreqList {bd, font [@Var{offset}]} +@DefreqItem {bd, font1 font2 [@Var{offset}]} +@DefregListEndx {.b} +@cindex imitating boldface (@code{bd}) +@cindex boldface, imitating (@code{bd}) +Embolden @var{font} by overstriking its glyphs offset by @var{offset} +units minus one. + +Two syntax forms are available. + +@itemize @bullet +@item +Imitate a bold font unconditionally. The first argument specifies the +font to embolden, and the second is the number of basic units, minus +one, by which the two glyphs are offset. If the second argument is +missing, emboldening is turned off. + +@var{font} can be either a non-negative font position or the name of a +font. + +@var{offset} is available in the @code{.b} read-only register if a +special font is active; in the @code{bd} request, its default unit is +@samp{u}. + +@cindex @code{fspecial} request, and imitating bold +@kindex special +@cindex embolding of special fonts +@cindex special fonts, emboldening +@item +Imitate a bold form conditionally. Embolden @var{font1} by @var{offset} +only if font @var{font2} is the current font. This request can be +issued repeatedly to set up different emboldening values for different +current fonts. If the second argument is missing, emboldening is turned +off for this particular current font. + +This affects special fonts only (either set up with the @code{special} +command in font files or with the @code{fspecial} request). +@end itemize +@endDefreq + +@Defreq {cs, font [@Var{width} [@Var{em-size}]]} +@cindex constant glyph space mode (@code{cs}) +@cindex mode for constant glyph space (@code{cs}) +@cindex glyph, constant space +@cindex @code{ps} request, and constant glyph space mode +Switch to and from @dfn{constant glyph space mode}. If activated, the +width of every glyph is @math{@var{width}/36} ems. The em size is given +absolutely by @var{em-size}; if this argument is missing, the em value +is taken from the current font size (as set with the @code{ps} request) +when the font is effectively in use. Without second and third argument, +constant glyph space mode is deactivated. + +Default scaling unit for @var{em-size} is @samp{z}; @var{width} is an +integer. +@endDefreq + +@c --------------------------------------------------------------------- + +@node Ligatures and Kerning, Dummy Characters, Artificial Fonts, Using Fonts +@subsection Ligatures and Kerning +@cindex ligatures and kerning +@cindex kerning and ligatures + +Ligatures are groups of characters that are run together, i.e, producing +a single glyph. For example, the letters `f' and `i' can form a +ligature `fi' as in the word `file'. This produces a cleaner look +(albeit subtle) to the printed output. Usually, ligatures are not +available in fonts for TTY output devices. + +Most PostScript fonts support the fi and fl ligatures. The C/A/T +typesetter that was the target of @acronym{AT&T} @code{troff} also +supported `ff', `ffi', and `ffl' ligatures. Advanced typesetters or +`expert' fonts may include ligatures for `ft' and `ct', although GNU +@code{troff} does not support these (yet). + +Only the current font is checked for ligatures and kerns; neither +special fonts nor special charcters defined with the @code{char} request +(and its siblings) are taken into account. + +@DefreqList {lg, [@Var{flag}]} +@DefregListEndx {.lg} +@cindex activating ligatures (@code{lg}) +@cindex ligatures, activating (@code{lg}) +@cindex ligatures enabled register (@code{.lg}) +Switch the ligature mechanism on or off; if the parameter is non-zero or +missing, ligatures are enabled, otherwise disabled. Default is on. The +current ligature mode can be found in the read-only register @code{.lg} +(set to 1 or@tie{}2 if ligatures are enabled, 0@tie{}otherwise). + +Setting the ligature mode to@tie{}2 enables the two-character ligatures +(fi, fl, and ff) and disables the three-character ligatures (ffi and +ffl). +@endDefreq + +@dfn{Pairwise kerning} is another subtle typesetting mechanism that +modifies the distance between a glyph pair to improve readability. In +most cases (but not always) the distance is decreased. +@iftex +For example, compare the combination of the letters `V' and `A'. With +kerning, `VA' is printed. Without kerning it appears as `V@w{}A'. +@end iftex +Typewriter-like fonts and fonts for terminals where all glyphs have the +same width don't use kerning. + +@DefreqList {kern, [@Var{flag}]} +@DefregListEndx {.kern} +@cindex activating kerning (@code{kern}) +@cindex kerning, activating (@code{kern}) +@cindex kerning enabled register (@code{.kern}) +Switch kerning on or off. If the parameter is non-zero or missing, +enable pairwise kerning, otherwise disable it. The read-only register +@code{.kern} is set to@tie{}1 if pairwise kerning is enabled, +0@tie{}otherwise. + +@cindex dummy character (@code{\&}), effect on kerning +@cindex character, dummy (@code{\&}), effect on kerning +If the font description file contains pairwise kerning information, +glyphs from that font are kerned. Kerning between two glyphs can be +inhibited by placing @code{\&} between them: @samp{V\&A}. + +@xref{Font Description File Format}. +@endDefreq + +@cindex track kerning +@cindex kerning, track +@dfn{Track kerning} expands or reduces the space between glyphs. This +can be handy, for example, if you need to squeeze a long word onto a +single line or spread some text to fill a narrow column. It must be +used with great care since it is usually considered bad typography if +the reader notices the effect. + +@Defreq {tkf, f s1 n1 s2 n2} +@cindex activating track kerning (@code{tkf}) +@cindex track kerning, activating (@code{tkf}) +Enable track kerning for font@tie{}@var{f}. If the current font +is@tie{}@var{f} the width of every glyph is increased by an amount +between @var{n1} and @var{n2} (@var{n1}, @var{n2} can be negative); if +the current type size is less than or equal to @var{s1} the width is +increased by @var{n1}; if it is greater than or equal to @var{s2} the +width is increased by @var{n2}; if the type size is greater than or +equal to @var{s1} and less than or equal to @var{s2} the increase in +width is a linear function of the type size. + +The default scaling unit is @samp{z} for @var{s1} and @var{s2}, @samp{p} +for @var{n1} and @var{n2}. + +The track kerning amount is added even to the rightmost glyph in a line; +for large values it is thus recommended to increase the line length by +the same amount to compensate. +@endDefreq + +@c --------------------------------------------------------------------- + +@node Italic Corrections, Dummy Characters, Ligatures and Kerning, Using Fonts +@subsection Italic Corrections + +When typesetting adjacent glyphs from typefaces of different slants, the +space between them may require adjustment. + +@Defesc {\\/, , , } +@cindex italic correction (@code{\/}) +@cindex correction, italic (@code{\/}) +@cindex correction between oblique and upright glyph (@code{\/}, @code{\,}) +@cindex roman glyph, correction after italic glyph (@code{\/}) +@cindex upright glyph, correction after oblique glyph (@code{\/}) +Apply an @dfn{italic correction}:@: modify the spacing of the preceding +glyph so that the distance between it and the following glyph is correct +if the latter is of upright shape. For example, if an +italic@tie{}@samp{f} is followed immediately by a roman right +parenthesis, then in many fonts the top right portion of +the@tie{}@samp{f} overlaps the top left of the right parenthesis, which +is ugly. Use this escape sequence whenever an oblique glyph is +immediately followed by an upright glyph without any intervening space. +@endDefesc + +@Defesc {\\\,, , , } +@cindex left italic correction (@code{\,}) +@cindex correction, left italic (@code{\,}) +@cindex correction between upright and oblique glyph (@code{\/}, @code{\,}) +@cindex roman glyph, correction before italic glyph (@code{\,}) +@cindex upright glyph, correction before oblique glyph (@code{\,}) +Apply a @dfn{left italic correction}:@: modify the spacing of the +following glyph so that the distance between it and the preceding +glyph is correct if the latter is of upright shape. For example, +if a roman left parenthesis is immediately followed by an +italic@tie{}@samp{f}, then in many fonts the bottom left portion of +the@tie{}@samp{f} overlaps the bottom of the left parenthesis, which is +ugly. Use this escape sequence whenever an upright glyph is followed +immediately by an oblique glyph without any intervening space. +@endDefesc + +@c XXX: Can we move this node earlier in the text? Should it come +@c before some of the dummy character's multifarious effects? +@need 1000 +@node Dummy Characters, , Italic Corrections, Using Fonts +@subsection Dummy Characters + +As discussed in @ref{Requests and Macros}, the first character on an +input line is treated specially. Further, formatting a glyph has many +consequences on formatter state (@pxref{Environments}). Occasionally, +we want to escape this context or embrace some of those consequences +without actually rendering a glyph to the output. + +@Defesc {\\&, , , } +@cindex dummy character (@code{\&}) +@cindex character, dummy (@code{\&}) +Interpolate a dummy character, which is constitutive of output but +invisible.@footnote{Opinions of this escape sequence's name abound. +``Zero-width space'' is a popular misnomer:@: @code{roff} formatters do +not treat it like a space. Ossanna called it a ``non-printing, +zero-width character'', but the character causes @emph{output} even +though it does not ``print''. If no output line is pending, the dummy +character starts one. Contrast an empty input document with one +containing only @code{\&}. The former produces no output; the latter, a +blank page.} Its presence alters the interpretation context of a +subsequent input character, and enjoys several applications. + +@itemize @bullet +@item +Prevent insertion of extra space after an end-of-sentence character. + +@Example +Test. +Test. + @result{} Test. Test. +Test.\& +Test. + @result{} Test. Test. +@endExample + +@item +Prevent recognition of a control character. + +@Example +.Test + @error{} warning: macro 'Test' not defined +\&.Test + @result{} .Test +@endExample + +@item +Prevent kerning between two glyphs. + +@iftex +@c can't use @Example...@endExample here +@example +@group +VA + @result{} @r{VA} +V\&A + @result{} @r{V@w{}A} +@end group +@end example +@end iftex + +@item +Translate a character to ``nothing''. + +@Example +.tr JIjiK\&k\&UVuv +@c XXX: I might have the wrong noun declension in "university" here. +Post universitum, alea jacta est, OK? + @result{} Post vniversitvm, alea iacta est, O? +@endExample +@end itemize + +The dummy character escape sequence sees use in macro definitions as a +means of ensuring that arguments are treated as text even if they begin +with spaces or control characters. + +@Example +.de HD \" typeset a simple bold heading +. sp +. ft B +\&\\$1 \" exercise: remove the \& +. ft +. sp +.. +.HD .\|.\|.\|surprised? +@endExample +@endDefesc + +One way to think about the dummy character is to imagine placing the +symbol @samp{&} in the input at a certain location; if doing so has all +the side effects on formatting that you desire except for sticking an +ugly ampersand in the midst of your text, the dummy character is what +you want in its place. + +@c XXX: This feature seems nearly impossible to motivate. The _only_ +@c use of it in the groff source tree is for the mdoc package, for which +@c it seems to be special pleading for that package's unique approach to +@c macro argument reprocessing, which also involves an idiosyncratic +@c approach to punctuation characters in macro argument lists. +@Defesc {\\), , , } +@cindex transparent dummy character (@code{\)}) +@cindex character, transparent dummy (@code{\)}) +@cindex dummy character, transparent (@code{\)}) +Interpolate a @slanted{transparent} dummy character---one that is +transparent to end-of-sentence detection. It behaves as @code{\&}, +except that @code{\&} is treated as letters and numerals normally are +after @samp{.}, @samp{?} and @samp{!}; @code{\&} cancels end-of-sentence +detection, and @code{\)} does not. +@c This feature seems too weak to me; see Savannah #60571. -- GBR + +@Example +.de Suffix-& +. nop \&\\$1 +.. +. +.de Suffix-) +. nop \)\\$1 +.. +. +Here's a sentence.\c +.Suffix-& ' +Another one.\c +.Suffix-) ' +And a third. + @result{} Here's a sentence.' Another one.' And a third. +@endExample +@endDefesc + + +@c ===================================================================== + +@c TODO: Move the troff and nroff mode stuff here. Try to keep stuff +@c that isn't ignored in nroff above this point, and stuff for +@c typesetters below, until we hit the programming/advanced concepts. +@c XXX: Thorny issue: nroff/terminal devices ignore type size but +@c _honor_ vertical spacing (to within their crude vertical motion +@c quanta). + +@need 2000 +@node Manipulating Type Size and Vertical Spacing, Colors, Using Fonts, GNU troff Reference +@section Manipulating Type Size and Vertical Spacing +@cindex manipulating type size and vertical spacing + +@cindex text baseline +@cindex baseline, text +@cindex type size +@cindex size, size +@cindex vertical spacing +@cindex spacing, vertical +These concepts were introduced in @ref{Page Geometry}. The height of a +font's tallest glyph is one em, which is equal to the type size in +points.@footnote{In text fonts, the tallest glyphs are typically +parentheses. Unfortunately, in many cases the actual dimensions of the +glyphs in a font do not closely match its declared type size! For +example, in the standard PostScript font families, 10-point Times sets +better with 9-point Helvetica and 11-point Courier than if all three +were used at 10@tie{}points.} A vertical spacing of less than 120% of +the type size can make a document hard to read. Larger proportions can +be useful to spread the text for annotations or proofreader's marks. By +default, GNU @code{troff} uses 10@tie{}point type on 12@tie{}point +spacing. +@cindex leading +Typographers call the difference between type size and vertical spacing +@dfn{leading}.@footnote{Rhyme with ``sledding''; mechanical typography +used lead metal (Latin @emph{plumbum}).} + +@menu +* Changing the Type Size:: +* Changing the Vertical Spacing:: +* Using Fractional Type Sizes:: +@end menu + +@c --------------------------------------------------------------------- + +@node Changing the Type Size, Changing the Vertical Spacing, Manipulating Type Size and Vertical Spacing, Manipulating Type Size and Vertical Spacing +@subsection Changing the Type Size + +@DefreqList {ps, [@Var{size}]} +@DefreqItem {ps, @t{+}@Var{size}} +@DefreqItem {ps, @t{-}@Var{size}} +@DefescItemx {\\s, , size, } +@DefregListEndx {.s} +@cindex changing type sizes (@code{ps}, @code{\s}) +@cindex type sizes, changing (@code{ps}, @code{\s}) +@cindex point sizes, changing (@code{ps}, @code{\s}) +Use the @code{ps} request or the @code{\s} escape sequence to change +(increase, decrease) the type size (in scaled points). Specify +@var{size} as either an absolute type size, or as a relative change from +the current size. @code{ps} with no argument restores the previous +size. The @code{ps} request's default scaling unit is @samp{z}. The +requested size is rounded to the nearest valid size (with ties rounding +down) within the limits supported by the device. If the requested size +is non-positive, it is treated as 1@dmn{u}. + +@cindex CSTR@tie{}#54 errata +@cindex CSTR@tie{}#54 erratum, @code{ps} request +@cindex CSTR@tie{}#54 erratum, @code{\s} escape sequence +Type size alteration is incorrectly documented in the @acronym{AT&T} +@code{troff} manual, which claims ``if [the requested size] is invalid, +the next larger valid size will result, with a maximum of +36''.@footnote{The claim appears to have been true of Ossanna +@code{troff} for the C/A/T device; Kernighan made device-independent +@code{troff} more flexible.} + +@cindex type size registers (@code{.s}, @code{.ps}) +@cindex point size registers (@code{.s}, @code{.ps}) +The read-only string-valued register @code{.s} interpolates the type +size in points as a decimal fraction; it is associated with the +environment (@pxref{Environments}). To obtain the type size in scaled +points, interpolate the @code{.ps} register instead (@pxref{Using +Fractional Type Sizes}). + +The @code{\s} escape sequence supports a variety of syntax forms. + +@table @code +@item \s@var{n} +Set the type size to @var{n}@tie{}points. @var{n}@tie{}must be a single +digit. If @var{n}@tie{}is 0, restore the previous size. + +@item \s+@var{n} +@itemx \s-@var{n} +Increase or decrease the type size by @var{n}@tie{}points. +@var{n}@tie{}must be exactly one digit. + +@item \s(@var{nn} +Set the type size to @var{nn}@tie{}points. @var{nn} must be exactly two +digits. + +@item \s+(@var{nn} +@itemx \s-(@var{nn} +@itemx \s(+@var{nn} +@itemx \s(-@var{nn} +Alter the type size in points by the two-digit value @var{nn}. +@end table + +@xref{Using Fractional Type Sizes}, for further syntactical forms of the +@code{\s} escape sequence that additionally accept decimal fractions. + +@Example +snap, snap, +.ps +2 +grin, grin, +.ps +2 +wink, wink, \s+2nudge, nudge,\s+8 say no more! +.ps 10 +@endExample +@endDefreq + +The @code{\s} escape sequence affects the environment immediately and +doesn't produce an input token. Consequently, it can be used in +requests like @code{mc}, which expects a single character as an +argument, to change the type size on the fly. + +@Example +.mc \s[20]x\s[0] +@endExample + +@Defreq {sizes, s1 s2 @dots{} sn [@t{0}]} +The @file{DESC} file specifies which type sizes are allowed by the +output device; see @ref{DESC File Format}. Use the @code{sizes} request +to change this set of permissible sizes. Arguments are in scaled +points; see @ref{Using Fractional Type Sizes}. Each can be a single +type size (such as @samp{12000}), or a range of sizes (such as +@samp{4000-72000}). You can optionally end the list with a @samp{0}. +@endDefreq + +@need 1000 +@node Changing the Vertical Spacing, Using Fractional Type Sizes, Changing the Type Size, Manipulating Type Size and Vertical Spacing +@subsection Changing the Vertical Spacing + +@DefreqList {vs, [@Var{space}]} +@DefreqItem {vs, @t{+}@Var{space}} +@DefreqItem {vs, @t{-}@Var{space}} +@DefregListEndx {.v} +@cindex changing vertical line spacing (@code{vs}) +@cindex vertical line spacing, changing (@code{vs}) +@cindex vertical line spacing register (@code{.v}) +Set the vertical spacing to, or alter it by, @var{space}. The default +scaling unit is @samp{p}. If @code{vs} is called without an argument, +the vertical spacing is reset to the previous value before the last call +to @code{vs}. +@cindex @code{.V} register, and @code{vs} +GNU @code{troff} emits a warning in category @samp{range} if @var{space} +is negative; the vertical spacing is then set to the smallest possible +positive value, the vertical motion quantum (as found in the @code{.V} +register). + +@w{@samp{.vs 0}} isn't saved in a diversion since it doesn't result in +a vertical motion. You must explicitly issue this request before +interpolating the diversion. + +The read-only register @code{.v} contains the vertical spacing; it is +associated with the environment (@pxref{Environments}). +@endDefreq + +@cindex vertical line spacing, effective value +@noindent +When a break occurs, GNU @code{troff} performs the following procedure. + +@itemize @bullet +@item +@cindex extra pre-vertical line space (@code{\x}) +@cindex line space, extra pre-vertical (@code{\x}) +Move the drawing position vertically by the @dfn{extra pre-vertical line +space}, the minimum of all negative @code{\x} escape sequence arguments +in the pending output line. + +@item +Move the drawing position vertically by the vertical line spacing. + +@item +Write out the pending output line. + +@item +@cindex extra post-vertical line space (@code{\x}) +@cindex line space, extra post-vertical (@code{\x}) +Move the drawing position vertically by the @dfn{extra post-vertical line +space}, the maximum of all positive @code{\x} escape sequence arguments +in the line that has just been output. + +@item +@cindex post-vertical line spacing +@cindex line spacing, post-vertical (@code{pvs}) +Move the drawing position vertically by the @dfn{post-vertical line +spacing} (see below). +@end itemize + +@cindex double-spacing (@code{vs}, @code{pvs}) +Prefer @code{vs} or @code{pvs} over @code{ls} to produce double-spaced +documents. @code{vs} and @code{pvs} have finer granularity than +@code{ls}; moreover, some preprocessors assume single spacing. +@xref{Manipulating Spacing}, regarding the @code{\x} escape sequence and +the @code{ls} request. + +@DefreqList {pvs, [@Var{space}]} +@DefreqItem {pvs, @t{+}@Var{space}} +@DefreqItem {pvs, @t{-}@Var{space}} +@DefregListEndx {.pvs} +@cindex @code{ls} request, alternative to (@code{pvs}) +@cindex post-vertical line spacing, changing (@code{pvs}) +@cindex post-vertical line spacing register (@code{.pvs}) +Set the post-vertical spacing to, or alter it by, @var{space}. The +default scaling unit is @samp{p}. If @code{pvs} is called without an +argument, the post-vertical spacing is reset to the previous value +before the last call to @code{pvs}. GNU @code{troff} emits a warning in +category @samp{range} if @var{space} is negative; the post-vertical +spacing is then set to zero. + +The read-only register @code{.pvs} contains the post-vertical spacing; +it is associated with the environment (@pxref{Environments}). +@endDefreq + +@c --------------------------------------------------------------------- + +@c BEGIN Keep (roughly) parallel with subsection "Fractional type sizes +@c and new scaling units" of groff_diff(7). +@node Using Fractional Type Sizes, , Changing the Type Size, Manipulating Type Size and Vertical Spacing +@subsection Using Fractional Type Sizes +@cindex fractional type sizes +@cindex fractional point sizes +@cindex type sizes, fractional +@cindex point sizes, fractional +@cindex sizes, fractional type + +AT&T @code{troff} interpreted all type size measurements in points. +Combined with integer arithmetic, this design choice made it impossible +to support, for instance, ten and a half-point type. In GNU +@code{troff}, an output device can select a scaling factor that +subdivides a point into ``scaled points''. A type size expressed in +scaled points can thus represent a non-integral type size. + +@cindex @code{s} scaling unit +@cindex unit, scaling, @code{s} +@cindex scaling unit @code{s} +@cindex @code{z} scaling unit +@cindex unit, scaling, @code{z} +@cindex scaling unit @code{z} +@cindex @code{ps} request, with fractional type sizes +@cindex @code{cs} request, with fractional type sizes +@cindex @code{tkf} request, with fractional type sizes +@cindex @code{\H}, with fractional type sizes +@cindex @code{\s}, with fractional type sizes +A @dfn{scaled point} is equal to @math{1/@var{sizescale}} points, where +@var{sizescale} is specified in the device description file @file{DESC}, +and defaults to@tie{}1.@footnote{@xref{Device and Font Description +Files}.} Requests and escape sequences in GNU @code{troff} interpret +arguments that represent a type size in scaled points, which the +formatter multiplies by @var{sizescale} and converts to an integer. +Arguments treated in this way comprise those to the escape sequences +@code{\H} and @code{\s}, to the request @code{ps}, the third argument to +the @code{cs} request, and the second and fourth arguments to the +@code{tkf} request. Scaled points may be specified explicitly with the +@code{z} scaling unit. + +For example, if @var{sizescale} is@tie{}1000, then a scaled point is one +thousandth of a point. The request @samp{.ps 10.5} is synonymous with +@samp{.ps 10.5z} and sets the type size to 10,500@tie{}scaled points, or +10.5@tie{}points. Consequently, in GNU @code{troff}, the register +@code{.s} can interpolate a non-integral type size. + +@Defreg {.ps} +This read-only register interpolates the type size in scaled points; it +is associated with the environment (@pxref{Environments}). +@endDefreg + +It makes no sense to use the @samp{z} scaling unit in a numeric +expression whose default scaling unit is neither @samp{u} nor @samp{z}, +so GNU @code{troff} disallows this. Similarly, it is nonsensical to use +a scaling unit other than @samp{z} or @samp{u} in a numeric expression +whose default scaling unit is @samp{z}, and so GNU @code{troff} +disallows this as well. + +Another GNU @code{troff} scaling unit, @samp{s}, multiplies by the +number of basic units in a scaled point. Thus, @samp{\n[.ps]s} is equal +to @samp{1m} by definition. Do not confuse the @samp{s} and @samp{z} +scaling units. +@c END Keep (roughly) parallel with subsection "Fractional type sizes +@c and new scaling units" of groff_diff(7). + +@DefregList {.psr} +@DefregListEndx {.sr} +@cindex last-requested type size registers (@code{.psr}, @code{.sr}) +@cindex type size registers, last-requested (@code{.psr}, @code{.sr}) +@cindex last-requested point size registers (@code{.psr}, @code{.sr}) +@cindex point size registers, last-requested (@code{.psr}, @code{.sr}) +@cindex @code{.ps} register, in comparison with @code{.psr} +@cindex @code{.s} register, in comparison with @code{.sr} +Output devices may be limited in the type sizes they can employ. The +@code{.s} and @code{.ps} registers represent the type size selected by +the output driver as it understands a device's capability. The last +@emph{requested} type size is interpolated in scaled points by the +read-only register @code{.psr} and in points as a decimal fraction by +the read-only string-valued register @code{.sr}. Both are associated +with the environment (@pxref{Environments}). + +For example, if a type size of 10.95 points is requested, and the +nearest size permitted by a @code{sizes} request (or by the @code{sizes} +or @code{sizescale} directives in the device's @file{DESC} file) is 11 +points, the output driver uses the latter value. +@endDefreg + +The @code{\s} escape sequence offers the following syntax forms that +work with fractional type sizes and accept scaling units. You may of +course give them integral arguments. The delimited forms need not use +the neutral apostrophe; see @ref{Delimiters}. + +@table @code +@item \s[@var{n}] +@itemx \s'@var{n}' +Set the type size to @var{n}@tie{}scaled points; @var{n}@tie{}is a +numeric expression with a default scaling unit of @samp{z}. + +@item \s[+@var{n}] +@itemx \s[-@var{n}] +@itemx \s+[@var{n}] +@itemx \s-[@var{n}] +@itemx \s'+@var{n}' +@itemx \s'-@var{n}' +@itemx \s+'@var{n}' +@itemx \s-'@var{n}' +Increase or decrease the type size by @var{n}@tie{}scaled points; +@var{n}@tie{}is a numeric expression (which may start with a minus sign) +with a default scaling unit of @samp{z}. +@end table + + +@c ===================================================================== + +@c BEGIN Keep (roughly) parallel with section "Colors" of groff(7). +@node Colors, Strings, Manipulating Type Size and Vertical Spacing, GNU troff Reference +@section Colors +@cindex colors + +@cindex stroke color +@cindex color, stroke +@cindex fill color +@cindex color, fill +GNU @code{troff} supports color output with a variety of color spaces +and up to 16 bits per channel. Some devices, particularly terminals, +may be more limited. When color support is enabled, two colors are +current at any given time: the @dfn{stroke color}, with which glyphs, +rules (lines), and geometric objects like circles and polygons are +drawn, and the @dfn{fill color}, which can be used to paint the interior +of a closed geometric figure. + +@DefreqList {color, [@Var{n}]} +@DefregListEndx {.color} +If @var{n} is missing or non-zero, enable the output of color-related +device-independent output commands (this is the default); otherwise, +disable them. This request sets a global flag; it does not produce an +input token (@pxref{Gtroff Internals}). + +The read-only register @code{.color} is@tie{}1 if colors are enabled, +0@tie{}otherwise. + +Color can also be disabled with the @option{-c} command-line option. +@endDefreq + +@Defreq {defcolor, ident scheme color-component @dots{}} +Define a color named @var{ident}. @var{scheme} selects a color space +and determines the quantity of required @var{color-component}s; it must +be one of @samp{rgb} (three components), @samp{cmy} (three), @samp{cmyk} +(four), or @samp{gray} (one). @samp{grey} is accepted as a synonym of +@samp{gray}. The color components can be encoded as a single +hexadecimal value starting with @samp{#} or @samp{##}. The former +indicates that each component is in the range 0--255 (0--FF), the latter +the range 0--65,535 (0--FFFF). + +@Example +.defcolor half gray #7f +.defcolor pink rgb #FFC0CB +.defcolor magenta rgb ##ffff0000ffff +@endExample + +@cindex @code{f} scaling unit +@cindex unit, scaling, @code{f} +@cindex scaling unit @code{f} +Alternatively, each color component can be specified as a decimal +fraction in the range 0--1, interpreted using a default scaling +unit of@tie{}@code{f}, which multiplies its value by 65,536 (but +clamps it at 65,535). + +@Example +.defcolor gray50 rgb 0.5 0.5 0.5 +.defcolor darkgreen rgb 0.1f 0.5f 0.2f +@endExample +@endDefreq + +@cindex default color +@cindex color, default +Each output device has a color named @samp{default}, which cannot be +redefined. A device's default stroke and fill colors are not +necessarily the same. For the @code{dvi}, @code{html}, @code{pdf}, +@code{ps}, and @code{xhtml} output devices, GNU @code{troff} +automatically loads a macro file defining many color names at startup. +By the same mechanism, the devices supported by @code{grotty} recognize +the eight standard ISO@tie{}6429/EMCA-48 color names.@footnote{also +known vulgarly as ``ANSI colors''} + +@DefreqList {gcolor, [@Var{color}]} +@DefescItemx {\\m, , c, } +@DefescItem {\\m, (, co, } +@DefescItem {\\m, [, color, ]} +@DefregListEndx {.m} +Set the stroke color to @var{color}. + +@Example +.gcolor red +The next words +.gcolor +\m[red]are in red\m[] +and these words are in the previous color. +@endExample + +The escape sequence @code{\m[]} restores the previous stroke color, as +does a @code{gcolor} request without an argument. + +@cindex stroke color name register (@code{.m}) +@cindex name, stroke color, register (@code{.m}) +@cindex color name, stroke, register (@code{.m}) +The name of the current stroke color is available in the read-only +string-valued register @samp{.m}; it is associated with the environment +(@pxref{Environments}). It interpolates nothing when the stroke color +is the default. + +@code{\m} doesn't produce an input token in GNU @code{troff} +(@pxref{Gtroff Internals}). It therefore can be used in requests like +@code{mc} (which expects a single character as an argument) to change +the color on the fly: + +@Example +.mc \m[red]x\m[] +@endExample +@endDefesc + +@DefreqList {fcolor, [@Var{color}]} +@DefescItemx {\\M, , c, } +@DefescItem {\\M, (, co, } +@DefescItem {\\M, [, color, ]} +@DefregListEndx {.M} +Set the fill color for objects drawn with @code{\D'@dots{}'} escape +sequences. The escape sequence @code{\M[]} restores the previous fill +color, as does an @code{fcolor} request without an argument. + +@cindex background color name register (@code{.M}) +@cindex name, background color, register (@code{.M}) +@cindex color name, background, register (@code{.M}) +@cindex fill color name register (@code{.M}) +@cindex name, fill color, register (@code{.M}) +@cindex color name, fill, register (@code{.M}) +The name of the current fill color is available in the read-only +string-valued register @samp{.M}; it is associated with the environment +(@pxref{Environments}). It interpolates nothing when the fill color +is the default. @code{\M} doesn't produce an input token in GNU +@code{troff}. + +Create an ellipse with a red interior as follows. + +@Example +\M[red]\h'0.5i'\D'E 2i 1i'\M[] +@endExample +@endDefesc +@c END Keep (roughly) parallel with section "Colors" of groff(7). + + +@c ===================================================================== + +@c BEGIN Keep (roughly) parallel with section "Strings" of groff(7). +@node Strings, Conditionals and Loops, Colors, GNU troff Reference +@section Strings +@cindex strings + +GNU @code{troff} supports strings primarily for user convenience. +Conventionally, if one would define a macro only to interpolate a small +amount of text, without invoking requests or calling any other macros, +one defines a string instead. Only one string is predefined by the +language. + +@Defstr {.T} +@stindex .T +@cindex output device name string (@code{.T}) +Contains the name of the output device (for example, @samp{utf8} or +@samp{pdf}). +@endDefmpstr + +The @code{ds} request creates a string with a specified name and +contents and the @code{\*} escape sequence dereferences its name, +interpolating its contents. If the string named by the @code{\*} escape +sequence does not exist, it is defined as empty, nothing is +interpolated, and a warning in category @samp{mac} is emitted. +@xref{Warnings}, for information about the enablement and suppression of +warnings. + +@DefreqList {ds, name [@Var{contents}]} +@DefreqItemx {ds1, name [@Var{contents}]} +@DefescItemx {\\*, , n, } +@DefescItem {\\*, (, nm, } +@c XXX: Can't mark the parameters with @Var because @Var gets called +@c recursively if we do. +@c @DefescListEnd {\\*, [, name [@Var{arg1} @Var{arg2} @dots{}], ]} +@DefescListEnd {\\*, [, name @sansserif{[}arg1 arg2 @dots{}@sansserif{]}, ]} +@cindex string interpolation (@code{\*}) +@cindex string expansion (@code{\*}) +@cindex interpolation of strings (@code{\*}) +@cindex expansion of strings (@code{\*}) +@cindex string arguments +@cindex arguments, to strings +Define a string called @var{name} with contents @var{contents}. If +@var{name} already exists as an alias, the target of the alias is +redefined; see @code{als} and @code{rm} below. If @code{ds} is called +with only one argument, @var{name} is defined as an empty string. +Otherwise, GNU @code{troff} stores @var{contents} in copy +mode.@footnote{@xref{Copy Mode}.} + +The @code{\*} escape sequence interpolates a previously defined string +variable @var{name} (one-character name@tie{}@var{n}, two-character name +@var{nm}). The bracketed interpolation form accepts arguments that are +handled as macro arguments are; recall @ref{Calling Macros}. In +contrast to macro calls, however, if a closing bracket @samp{]} occurs +in a string argument, that argument must be enclosed in double quotes. +@code{\*} is interpreted even in copy mode. When defining strings, +argument interpolations must be escaped if they are to reference +parameters from the calling context; @xref{Parameters}. + +@Example +.ds cite (\\$1, \\$2) +Gray codes are explored in \*[cite Morgan 1998]. + @result{} Gray codes are explored in (Morgan, 1998). +@endExample + +@c TODO: Consider examples of recursive string calls, particularly where +@c one interpolation is constructed from the argument of an enclosing +@c macro, to illustrate ".ds a \$1 \\$1". +@c +@c @Example +@c .ds a \\$1 wildebeest +@c .ds b big, \*[a hairy] +@c I see a \*[b]. +@c @result{} I see a big, hairy wildebeest. +@c @endExample + +@cindex trailing spaces in string definitions and appendments +@cindex comments, with @code{ds} +@cindex @code{ds} request, and comments +@strong{Caution:@:} Unlike other requests, the second argument to the +@code{ds} request consumes the remainder of the input line, including +trailing spaces. This means that comments on a line with such a request +can introduce unwanted space into a string when they are set off from +the material they annotate, as is conventional. + +@Example +.ds H2O H\v'+.3m'\s'-2'2\v'-.3m'\s0O \" water +@endExample + +@noindent +Instead, place the comment on another line or put the comment escape +sequence immediately adjacent to the last character of the string. + +@Example +.ds H2O H\v'+.3m'\s'-2'2\v'-.3m'\s0O\" water +@endExample + +Ending string definitions (and appendments) with a comment, even an +empty one, prevents unwanted space from creeping into them during source +document maintenance. + +@Example +.ds author Alice Pleasance Liddell\" +.ds empty \" might be appended to later with .as +@endExample + +@cindex trailing double quotes in strings +@cindex double quotes, trailing, in strings +@cindex @code{ds} request, and double quotes +@cindex leading spaces with @code{ds} +@cindex spaces with @code{ds} +@cindex @code{ds} request, and leading spaces +An initial neutral double quote @code{"} in @var{contents} is stripped +to allow embedding of leading spaces. Any other @code{"} is interpreted +literally, but it is wise to use the special character escape sequence +@code{\[dq]} instead if the string might be interpolated as part of a +macro argument; see @ref{Calling Macros}. + +@c Examples should be more accessible than Unix nerd stuff like this, +@c but in general document authors shouldn't want to use "straight" +@c double quotes for ordinary prose anyway. Also, 56 chars is as fat +@c as these examples can get and not overrun the right margin in PDF. +@Example +.ds salutation " Yours in a white wine sauce,\" +.ds c-var-defn " char mydate[]=\[dq]2020-07-29\[dq];\" +@endExample + +@cindex multi-line strings +@cindex strings, multi-line +@cindex newline character, in strings, escaping +@cindex escaping newline characters, in strings +Strings are not limited to a single input line of text. +@code{\@key{RET}} works just as it does elsewhere. The resulting string +is stored @emph{without} the newlines. Care is therefore required when +interpolating strings while filling is disabled. + +@Example +.ds foo This string contains \ +text on multiple lines \ +of input. +@endExample + +It is not possible to embed a newline in a string that will be +interpreted as such when the string is interpolated. To achieve that +effect, use @code{\*} to interpolate a macro instead; see @ref{Punning +Names}. + +Because strings are similar to macros, they too can be defined so as to +suppress AT&T @code{troff} compatibility mode when used; see +@ref{Writing Macros} and @ref{Compatibility Mode}. The @code{ds1} +request defines a string such that compatibility mode is off when the +string is later interpolated. To be more precise, a @dfn{compatibility +save} input token is inserted at the beginning of the string, and a +@dfn{compatibility restore} input token at the end. + +@Example +.nr xxx 12345 +.ds aa The value of xxx is \\n[xxx]. +.ds1 bb The value of xxx is \\n[xxx]. +. +.cp 1 +. +\*(aa + @error{} warning: register '[' not defined + @result{} The value of xxx is 0xxx]. +\*(bb + @result{} The value of xxx is 12345. +@endExample +@endDefreq + +@DefreqList {as, name [@Var{contents}]} +@DefreqListEndx {as1, name [@Var{contents}]} +@cindex appending to a string (@code{as}) +@cindex string, appending (@code{as}) +The @code{as} request is similar to @code{ds} but appends @var{contents} +to the string stored as @var{name} instead of redefining it. If +@var{name} doesn't exist yet, it is created. If @code{as} is called +with only one argument, no operation is performed (beyond dereferencing +the string). + +@Example +.as salutation " with shallots, onions and garlic,\" +@endExample + +The @code{as1} request is similar to @code{as}, but compatibility mode +is switched off when the appended portion of the string is later +interpolated. To be more precise, a @dfn{compatibility save} input +token is inserted at the beginning of the appended string, and a +@dfn{compatibility restore} input token at the end. +@endDefreq + +Several requests exist to perform rudimentary string operations. +Strings can be queried (@code{length}) and modified (@code{chop}, +@code{substring}, @code{stringup}, @code{stringdown}), and their names +can be manipulated through renaming, removal, and aliasing (@code{rn}, +@code{rm}, @code{als}). + +@Defreq {length, reg anything} +@cindex length of a string (@code{length}) +@cindex string, length of (@code{length}) +@cindex @code{length} request, and copy mode +@cindex copy mode, and @code{length} request +@cindex mode, copy, and @code{length} request +Compute the number of characters of @var{anything} and store the count +in the register @var{reg}. If @var{reg} doesn't exist, it is created. +@var{anything} is read in copy mode. + +@Example +.ds xxx abcd\h'3i'efgh +.length yyy \*[xxx] +\n[yyy] + @result{} 14 +@endExample +@endDefreq + +@Defreq {chop, object} +Remove the last character from the macro, string, or diversion named +@var{object}. This is useful for removing the newline from the end of a +diversion that is to be interpolated as a string. This request can be +used repeatedly on the same @var{object}; see @ref{Gtroff Internals}, +for details on nodes inserted additionally by GNU @code{troff}. +@endDefreq + +@Defreq {substring, str start [@Var{end}]} +@cindex substring (@code{substring}) +Replace the string named @var{str} with its substring bounded by the +indices @var{start} and @var{end}, inclusively. The first character in +the string has index@tie{}0. If @var{end} is omitted, it is implicitly +set to the largest valid value (the string length minus one). Negative +indices count backward from the end of the string:@: the last character +has index@tie{}@minus{}1, the character before the last has +index@tie{}@minus{}2, and so on. + +@Example +.ds xxx abcdefgh +.substring xxx 1 -4 +\*[xxx] + @result{} bcde +.substring xxx 2 +\*[xxx] + @result{} de +@endExample +@endDefreq + +@DefreqList {stringdown, str} +@DefreqListEndx {stringup, str} +@cindex case-transforming a string (@code{stringdown}, @code{stringup}) +@cindex uppercasing a string (@code{stringup}) +@cindex lowercasing a string (@code{stringdown}) +@cindex up-casing a string (@code{stringup}) +@cindex down-casing a string (@code{stringdown}) +Alter the string named @var{str} by replacing each of its bytes with its +lowercase (@code{stringdown}) or uppercase (@code{stringup}) version (if +one exists). Special characters in the string will often transform in +the expected way due to the regular naming convention for accented +characters. When they do not, use substrings and/or catenation. + +@Example +.ds resume R\['e]sum\['e] +\*[resume] +.stringdown resume +\*[resume] +.stringup resume +\*[resume] + @result{} Résumé résumé RÉSUMÉ +@endExample +@endDefreq + +(In practice, we would end the @code{ds} request with a comment escape +@code{\"} to prevent space from creeping into the definition during +source document maintenance.) + +@Defreq {rn, old new} +@cindex renaming request (@code{rn}) +@cindex request, renaming (@code{rn}) +@cindex renaming macro (@code{rn}) +@cindex macro, renaming (@code{rn}) +@cindex renaming string (@code{rn}) +@cindex string, renaming (@code{rn}) +@cindex renaming diversion (@code{rn}) +@cindex diversion, renaming (@code{rn}) +Rename the request, macro, diversion, or string @var{old} to @var{new}. +@endDefreq + +@Defreq {rm, name} +@cindex removing request (@code{rm}) +@cindex request, removing (@code{rm}) +@cindex removing macro (@code{rm}) +@cindex macro, removing (@code{rm}) +@cindex removing string (@code{rm}) +@cindex string, removing (@code{rm}) +@cindex removing diversion (@code{rm}) +@cindex diversion, removing (@code{rm}) +Remove the request, macro, diversion, or string @var{name}. GNU +@code{troff} treats subsequent invocations as if the name had never +been defined. +@endDefreq + +@anchor{als} +@Defreq {als, new old} +@cindex alias, string, creating (@code{als}) +@cindex alias, macro, creating (@code{als}) +@cindex alias, diversion, creating (@code{als}) +@cindex creating alias, for string (@code{als}) +@cindex creating alias, for macro (@code{als}) +@cindex creating alias, for diversion (@code{als}) +@cindex string, creating alias for (@code{als}) +@cindex macro, creating alias for (@code{als}) +@cindex diversion, creating alias for (@code{als}) +Create an alias @var{new} for the existing request, string, macro, or +diversion object named @var{old}, causing the names to refer to the same +stored object. If @var{old} is undefined, a warning in category +@samp{mac} is produced, and the request is ignored. @xref{Warnings}, +for information about the enablement and suppression of warnings. + +To understand how the @code{als} request works, consider two different +storage pools:@: one for objects (macros, strings, etc.), and another +for names. As soon as an object is defined, GNU @code{troff} adds it to +the object pool, adds its name to the name pool, and creates a link +between them. When @code{als} creates an alias, it adds a new name to +the name pool that gets linked to the same object as the old name. + +Now consider this example. + +@Example +.de foo +.. +. +.als bar foo +. +.de bar +. foo +.. +. +.bar + @error{} input stack limit exceeded (probable infinite + @error{} loop) +@endExample + +@noindent +In the above, @code{bar} remains an @emph{alias}---another name +for---the object referred to by @code{foo}, which the second @code{de} +request replaces. Alternatively, imagine that the @code{de} request +@emph{dereferences} its argument before replacing it. Either way, the +result of calling @code{bar} is a recursive loop that finally leads to +an error. @xref{Writing Macros}. + +@cindex alias, string, removing (@code{rm}) +@cindex alias, macro, removing (@code{rm}) +@cindex alias, diversion, removing (@code{rm}) +@cindex removing alias, for string (@code{rm}) +@cindex removing alias, for macro (@code{rm}) +@cindex removing alias, for diversion (@code{rm}) +@cindex string, removing alias for (@code{rm}) +@cindex macro, removing alias for (@code{rm}) +@cindex diversion, removing alias for (@code{rm}) +To remove an alias, call @code{rm} on its name. The object itself is +not destroyed until it has no more names. + +When a request, macro, string, or diversion is aliased, redefinitions +and appendments ``write through'' alias names. To replace an alias with +a separately defined object, you must use the @code{rm} request on its +name first. +@endDefreq +@c END Keep (roughly) parallel with section "Strings" of groff(7). + + +@c ===================================================================== + +@node Conditionals and Loops, Writing Macros, Strings, GNU troff Reference +@section Conditionals and Loops +@cindex conditionals and loops +@cindex loops and conditionals + +@code{groff} has @code{if} and @code{while} control structures like +other languages. However, the syntax for grouping multiple input lines +in the branches or bodies of these structures is unusual. + +@menu +* Operators in Conditionals:: +* if-then:: +* if-else:: +* Conditional Blocks:: +* while:: +@end menu + +@c --------------------------------------------------------------------- + +@c BEGIN Keep (roughly) parallel with subsection "Conditional +@c expressions" of groff(7). +@node Operators in Conditionals, if-then, Conditionals and Loops, Conditionals and Loops +@subsection Operators in Conditionals + +@cindex @code{if} request, operators to use with +@cindex @code{ie} request, operators to use with +@cindex @code{while} request, operators to use with +@cindex conditional expressions +@cindex expressions, conditional +In @code{if}, @code{ie}, and @code{while} requests, in addition to the +numeric expressions described in @ref{Numeric Expressions}, several +Boolean operators are available; the members of this expanded class are +termed @dfn{conditional expressions}. + +@table @code +@item c @var{glyph} +True if @var{glyph} is available, where @var{glyph} is an ordinary +character, a special character @samp{\(@var{xx}} or @samp{\[@var{xxx}]}, +@samp{\N'@var{xxx}'}, or has been defined by any of the @code{char}, +@code{fchar}, @code{fschar}, or @code{schar} requests. + +@item d @var{name} +True if a string, macro, diversion, or request called @var{name} exists. + +@item e +True if the current page is even-numbered. + +@item F @var{font} +True if @var{font} exists. @var{font} is handled as if it were opened +with the @code{ft} request (that is, font translation and styles are +applied), without actually mounting it. + +@item m @var{color} +True if @var{color} is defined. + +@item n +@cindex conditional output for terminal (TTY) +@cindex TTY, conditional output for +@cindex terminal, conditional output for +True if the document is being processed in @code{nroff} mode. +@xref{@code{troff} and @code{nroff} Modes}. + +@item o +True if the current page is odd-numbered. + +@item r @var{register} +True if @var{register} exists. + +@item S @var{style} +True if @var{style} is available for the current font family. Font +translation is applied. + +@item t +True if the document is being processed in @code{troff} mode. +@xref{@code{troff} and @code{nroff} Modes}. + +@pindex vtroff +@item v +Always false. This condition is recognized only for compatibility with +certain other @code{troff} implementations.@footnote{This refers to +@code{vtroff}, a translator that would convert the C/A/T output from +early-vintage @acronym{AT&T} @code{troff} to a form suitable for +Versatec and Benson-Varian plotters.} +@end table + +If the first argument to an @code{if}, @code{ie}, or @code{while} +request begins with a non-alphanumeric character apart from @code{!} +(see below); it performs an @slanted{output comparison test}. +@footnote{Strictly, letters not otherwise recognized @emph{are} treated +as output comparison delimiters. For portability, it is wise to avoid +using letters not in the list above; for example, Plan@tie{}9 +@code{troff} uses @samp{h} to test a mode it calls @code{htmlroff}, and +GNU @code{troff} may provide additional operators in the future.} + +@cindex output comparison operator +@table @code +@item @code{'}@var{xxx}@code{'}@var{yyy}@code{'} +True if formatting the comparands @var{xxx} and @var{yyy} produces the +same output commands. The delimiter need not be a neutral apostrophe: +the output comparison operator accepts the same delimiters as most +escape sequences; see @ref{Delimiters}. This @dfn{output comparison +operator} formats @var{xxx} and @var{yyy} in separate environments; +after the comparison, the resulting data are discarded. + +@Example +.ie "|"\fR|\fP" true +.el false + @result{} true +@endExample + +@noindent +The resulting glyph properties, including font family, style, size, and +slant, must match, but not necessarily the requests and/or escape +sequences used to obtain them. In the previous example, @samp{|} and +@samp{\fR|\fP} result in @samp{|} glyphs in the same typefaces at the +same positions, so the comparands are equal. If @samp{.ft@tie{}I} had +been added before the @samp{.ie}, they would differ: the first @samp{|} +would produce an italic @samp{|}, not a roman one. Motions must match +in orientation and magnitude to within the applicable horizontal and +vertical motion quanta of the device, after rounding. @samp{.if +"\u\d"\v'0'"} is false even though both comparands result in zero net +motion, because motions are not interpreted or optimized but sent as-is +to the output.@footnote{Because formatting of the comparands takes place +in a dummy environment, vertical motions within them cannot spring +traps.} On the other hand, @samp{.if "\d"\v'0.5m'"} is true, because +@code{\d} is defined as a downward motion of one-half em.@footnote{All +of this is to say that the lists of output nodes created by formatting +@var{xxx} and @var{yyy} must be identical. @xref{Gtroff Internals}.} + +@cindex string comparison +@cindex comparison of strings +Surround the comparands with @code{\?} to avoid formatting them; this +causes them to be compared character by character, as with string +comparisons in other programming languages. + +@Example +.ie "\?|\?"\?\fR|\fP\?" true +.el false + @result{} false +@endExample + +@cindex @code{\?}, and copy mode +@cindex copy mode, and @code{\?} +@cindex mode, copy, and @code{\?} +@noindent +Since comparands protected with @code{\?} are read in copy mode +(@pxref{Copy Mode}), they need not even be valid @code{groff} syntax. +The escape character is still lexically recognized, however, and +consumes the next character. + +@Example +.ds a \[ +.ds b \[ +.if '\?\*a\?'\?\*b\?' a and b equivalent +.if '\?\\?'\?\\?' backslashes equivalent + @result{} a and b equivalent +@c slack lines for pagination control +@c @error{} warning: missing closing delimiter in +@c @error{} conditional expression (got newline) +@endExample +@end table + +The above operators can't be combined with most others, but a leading +@samp{!}, not followed immediately by spaces or tabs, complements an +expression. + +@Example +.nr x 1 +.ie !r x register x is not defined +.el register x is defined + @result{} register x is defined +@endExample + +Spaces and tabs are optional immediately after the @samp{c}, @samp{d}, +@samp{F}, @samp{m}, @samp{r}, and @samp{S} operators, but right after +@samp{!}, they end the predicate and the conditional evaluates +true.@footnote{This bizarre behavior maintains compatibility with +@acronym{AT&T} @code{troff}.} + +@Example +.nr x 1 +.ie ! r x register x is not defined +.el register x is defined + @result{} r x register x is not defined +@endExample + +@noindent +The unexpected @samp{r x} in the output is a clue that our conditional +was not interpreted as we planned, but matters may not always be so +obvious. +@c END Keep (roughly) parallel with subsection "Conditional expressions" +@c of groff(7). + +@c --------------------------------------------------------------------- + +@node if-then, if-else, Operators in Conditionals, Conditionals and Loops +@subsection if-then +@cindex if-then + +@Defreq {if, cond-expr anything} +Evaluate the conditional expression @var{cond-expr}, and if it evaluates +true (or to a positive value), interpret the remainder of the line +@var{anything} as if it were an input line. Recall from @ref{Invoking +Requests} that any quantity of spaces between arguments to requests +serves only to separate them; leading spaces in @var{anything} are thus +not seen. @var{anything} effectively @emph{cannot} be omitted; if +@var{cond-expr} is true and @var{anything} is empty, the newline at the +end of the control line is interpreted as a blank input line (and +therefore a blank text line). + +@Example +super\c +tanker +.nr force-word-break 1 +super\c +.if ((\n[force-word-break] = 1) & \n[.int]) +tanker + @result{} supertanker super tanker +@endExample +@endDefreq + +@Defreq {nop, anything} +Interpret @var{anything} as if it were an input line. This is similar +to @samp{.if@tie{}1}. @code{nop} is not really ``no operation''; its +argument @emph{is} processed---unconditionally. It can be used to cause +text lines to share indentation with surrounding control lines. + +@Example +.als real-MAC MAC +.de wrapped-MAC +. tm MAC: called with arguments \\$@@ +. nop \\*[real-MAC]\\ +.. +.als MAC wrapped-MAC +\# Later... +.als MAC real-MAC +@endExample + +In the above, we've used aliasing, @code{nop}, and the interpolation of +a macro as a string to interpose a wrapper around the macro @samp{MAC} +(perhaps to debug it). +@endDefreq + +@c --------------------------------------------------------------------- + +@node if-else, while, Operators in Conditionals, Conditionals and Loops +@subsection if-else +@cindex if-else + +@DefreqList {ie, cond-expr anything} +@DefreqListEndx {el, anything} +Use the @code{ie} and @code{el} requests to write an if-then-else. The +first request is the ``if'' part and the latter is the ``else'' part. +Unusually among programming languages, any number of non-conditional +requests may be interposed between the @code{ie} branch and the +@code{el} branch. + +@Example +.nr a 0 +.ie \na a is non-zero. +.nr a +1 +.el a was not positive but is now \na. + @result{} a was not positive but is now 1. +@endExample + +Another way in which @code{el} is an ordinary request is that it does +not lexically ``bind'' more tightly to its @code{ie} counterpart than it +does to any other request. This fact can surprise C programmers. + +@Example +.nr a 1 +.nr z 0 +.ie \nz \ +. ie \na a is true +. el a is false +.el z is false + @error{} warning: unbalanced 'el' request + @result{} a is false +@endExample + +@c Turn the following into a proper @{x,}ref if the conditional blocks +@c node is relocated elsewhere--but consider if it is wise to do so. +To conveniently nest conditionals, keep reading. + +@endDefreq + +@c --------------------------------------------------------------------- + +@node Conditional Blocks, while, Operators in Conditionals, Conditionals and Loops +@subsection Conditional Blocks +@cindex conditional blocks +@cindex blocks, conditional + +It is frequently desirable for a control structure to govern more than +one request, macro call, text line, or a combination of the foregoing. +The opening and closing brace escape sequences @code{\@{} and @code{\@}} +define such groups. These @dfn{conditional blocks} can furthermore be +nested. + +@DefescList {\@\{, , , } +@DefescListEnd {\@\}, , , } +@esindex \@{ +@esindex \@} +@cindex beginning of conditional block (@code{\@{}) +@cindex end of conditional block (@code{\@}}) +@cindex conditional block, beginning (@code{\@{}) +@cindex conditional block, end (@code{\@}}) +@cindex block, conditional, beginning (@code{\@{}) +@cindex block, conditional, end (@code{\@}}) +@cindex brace escape sequences (@code{\@{}, @code{\@}}) +@cindex escape sequences, brace (@code{\@{}, @code{\@}}) +@cindex opening brace escape sequence (@code{\@}}) +@cindex closing brace escape sequence (@code{\@})} +@cindex brace escape sequence, opening (@code{\@})} +@cindex brace escape sequence, closing (@code{\@})} +@code{\@{} begins a conditional block; it must appear (after optional +spaces and tabs) immediately subsequent to the conditional expression of +an @code{if}, @code{ie}, or @code{while} +request,@footnote{@xref{while}.} or as the argument to an @code{el} +request. + +@code{\@}} ends a condition block and should appear on a line with other +occurrences of itself as necessary to match @code{\@{} sequences. It +can be preceded by a control character, spaces, and tabs. Input after +any quantity of @code{\@}} sequences on the same line is processed only +if all of the preceding conditions to which they correspond are true. +Furthermore, a @code{\@}} closing the body of a @code{while} request +must be the last such escape sequence on an input line. + +Brace escape sequences outside of control structures have no meaning and +produce no output. + +@strong{Caution:@:} Input lines using @code{\@{} often end with +@code{\RET}, especially in macros that consist primarily of control +lines. Forgetting to use @code{\RET} on an input line after @code{\@{} +is a common source of error. +@endDefesc + +@need 1000 +We might write the following in a page header macro. If we delete +@code{\RET}, the header will carry an unwanted extra empty line (except +on page@tie{}1). + +@Example +.if (\\n[%] != 1) \@{\ +. ie ((\\n[%] % 2) = 0) .tl \\*[even-numbered-page-title] +. el .tl \\*[odd-numbered-page-title] +.\@} +@endExample + +Let us take a closer look at how conditional blocks nest. + +@Example +A +.if 0 \@{ B +C +D +\@}E +F + @result{} A F +@endExample + +@Example +N +.if 1 \@{ O +. if 0 \@{ P +Q +R\@} S\@} T +U + @result{} N O U +@endExample + +The above behavior may challenge the intuition; it was implemented to +retain compatibility with @acronym{AT&T} @code{troff}. For clarity, it +is idiomatic to end input lines with @code{\@{} (followed by +@code{\@key{RET}} if appropriate), and to precede @code{\@}} on an input +line with nothing more than a control character, spaces, tabs, and other +instances of itself. + +We can use @code{ie}, @code{el}, and conditional blocks to simulate the +multi-way ``switch'' or ``case'' control structures of other languages. +The following example is adapted from the @code{groff} @file{man} +package. Indentation is used to clarify the logic. + +@Example +.\" Simulate switch/case in roff. +. ie '\\$2'1' .ds title General Commands\" +.el \@{.ie '\\$2'2' .ds title System Calls\" +.el \@{.ie '\\$2'3' .ds title Library Functions\" +.el \@{.ie '\\$2'4' .ds title Kernel Interfaces\" +.el \@{.ie '\\$2'5' .ds title File Formats\" +.el \@{.ie '\\$2'6' .ds title Games\" +.el \@{.ie '\\$2'7' .ds title Miscellaneous Information\" +.el \@{.ie '\\$2'8' .ds title System Management\" +.el \@{.ie '\\$2'9' .ds title Kernel Development\" +.el .ds title \" empty +.\@}\@}\@}\@}\@}\@}\@}\@} +@endExample + +@c --------------------------------------------------------------------- + +@node while, , if-else, Conditionals and Loops +@subsection while +@cindex while + +@code{groff} provides a looping construct:@: the @code{while} request. +Its syntax matches the @code{if} request. + +@cindex body, of a while request +@Defreq {while, cond-expr anything} +Evaluate the conditional expression @var{cond-expr}, and repeatedly +execute @var{anything} unless and until @var{cond-expr} evaluates false. +@var{anything}, which is often a conditional block, is referred to as +the @code{while} request's @dfn{body}. + +@Example +.nr a 0 1 +.while (\na < 9) \@{\ +\n+a, +.\@} +\n+a + @result{} 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 +@endExample + +@cindex @code{de} request, and @code{while} +GNU @code{troff} treats the body of a @code{while} request similarly to +that of a @code{de} request (albeit one not read in copy +mode@footnote{@xref{Copy Mode}.}), but stores it under an internal name +and deletes it when the loop finishes. The operation of a macro +containing a @code{while} request can slow significantly if the +@code{while} body is large. Each time the macro is executed, the +@code{while} body is parsed and stored again. + +@Example +.de xxx +. nr num 10 +. while (\\n[num] > 0) \@{\ +. \" many lines of code +. nr num -1 +. \@} +.. +@endExample + +@cindex recursive macros +@cindex macros, recursive +@noindent +An often better solution---and one that is more portable, since +@acronym{AT&T} @code{troff} lacked the @code{while} request---is to +instead write a recursive macro. It will be parsed only +once.@footnote{unless you redefine it} + +@Example +.de yyy +. if (\\n[num] > 0) \@{\ +. \" many lines of code +. nr num -1 +. yyy +. \@} +.. +. +.de xxx +. nr num 10 +. yyy +.. +@endExample + +@noindent +To prevent infinite loops, the default number of available recursion +levels is 1,000 or somewhat less.@footnote{``somewhat less'' because +things other than macro calls can be on the input stack} You can +disable this protective measure, or raise the limit, by setting the +@code{slimit} register. @xref{Debugging}. + +As noted above, if a @code{while} body begins with a conditional block, +its closing brace must end an input line. + +@Example +.if 1 \@{\ +. nr a 0 1 +. while (\n[a] < 10) \@{\ +. nop \n+[a] +.\@}\@} + @error{} unbalanced brace escape sequences +@endExample +@endDefreq + +@Defreq {break, } +@cindex @code{while} request, confusing with @code{br} +@cindex @code{break} request, in a @code{while} loop +@cindex @code{continue} request, in a @code{while} loop +Exit a @code{while} loop. Do not confuse this request with a +typographical break or the @code{br} request. +@endDefreq + +@Defreq {continue, } +Skip the remainder of a @code{while} loop's body, immediately starting +the next iteration. +@endDefreq + + +@c ===================================================================== + +@node Writing Macros, Page Motions, Conditionals and Loops, GNU troff Reference +@section Writing Macros +@cindex writing macros +@cindex macros, writing + +A @dfn{macro} is a stored collection of text and control lines that can +be interpolated multiple times. Use macros to define common operations. +Macros are called in the same way that requests are invoked. While +requests exist for the purpose of creating macros, simply calling an +undefined macro, or interpolating it as a string, will cause it to be +defined as empty. @xref{Identifiers}. + +@Defreq {de, name [@Var{end}]} +Define a macro @var{name}, replacing the definition of any existing +request, macro, string, or diversion called @var{name}. If +@var{name} already exists as an alias, the target of the alias is +redefined; recall @ref{Strings}. GNU @code{troff} enters copy +mode,@footnote{@xref{Copy Mode}.} storing subsequent input lines as the +macro definition. If the optional second argument is not specified, the +definition ends with the control line @samp{..} (two dots). +Alternatively, @var{end} identifies a macro whose call syntax at the +start of a control line ends the definition of @var{name}; @var{end} is +then called normally. A macro definition must end in the same +conditional block (if any) in which it began (@pxref{Conditional +Blocks}). Spaces or tabs are permitted after the control character in +the line containing this ending token (either @samp{.} or +@samp{@var{end}}), but a tab immediately after the token prevents its +recognition as the end of a macro definition. The macro @var{end} can +be called with arguments.@footnote{While it is possible to define and +call a macro @samp{.}, you can't use it as an end macro: during a macro +definition, @samp{..} is never handled as calling @samp{.}, even if +@samp{.de @var{name} .} explicitly precedes it.} +@c +@c @Example +@c .de . +@c (dot macro) +@c .. +@c . +@c .. \" This calls macro '.'! +@c .de m1 . +@c (m1 macro) +@c .. \" This does not. +@c .m1 +@c @result{} (dot macro) (m1 macro) +@c @endExample + +Here is a small example macro called @samp{P} that causes a break and +inserts some vertical space. It could be used to separate paragraphs. + +@Example +.de P +. br +. sp .8v +.. +@endExample + +We can define one macro within another. Attempting to nest @samp{..} +naďvely will end the outer definition because the inner definition +isn't interpreted as such until the outer macro is later interpolated. +We can use an end macro instead. Each level of nesting should use a +unique end macro. + +An end macro need not be defined until it is called. This fact enables +a nested macro definition to begin inside one macro and end inside +another. Consider the following example.@footnote{Its structure is +adapted from, and isomorphic to, part of a solution by Tadziu Hoffman to +the problem of reflowing text multiple times to find an optimal +configuration for it. +@uref{https://lists.gnu.org/archive/html/groff/2008-12/msg00006.html}} + +@Example +.de m1 +. de m2 m3 +you +.. +.de m3 +Hello, +Joe. +.. +.de m4 +do +.. +.m1 +know? +. m3 +What +.m4 +.m2 + @result{} Hello, Joe. What do you know? +@endExample + +@noindent +A nested macro definition @emph{can} be terminated with @samp{..} and +nested macros @emph{can} reuse end macros, but these control lines must +be escaped multiple times for each level of nesting. The necessity of +this escaping and the utility of nested macro definitions will become +clearer when we employ macro parameters and consider the behavior of +copy mode in detail. +@endDefreq + +@code{de} defines a macro that inherits the compatibility mode +enablement status of its context (@pxref{Implementation Differences}). +Often it is desirable to make a macro that uses @code{groff} features +callable from contexts where compatibility mode is on; for instance, +when writing extensions to a historical macro package. To achieve this, +compatibility mode needs to be switched off while such a macro is +interpreted---without disturbing that state when it is finished. + +@Defreq {de1, name [@Var{end}]} +The @code{de1} request defines a macro to be interpreted with +compatibility mode disabled. When @var{name} is called, compatibility +mode enablement status is saved; it is restored when the call completes. +Observe the extra backlash before the interpolation of register +@samp{xxx}; we'll explore this subject in @ref{Copy Mode}. + +@Example +.nr xxx 12345 +.de aa +The value of xxx is \\n[xxx]. +. br +.. +.de1 bb +The value of xxx is \\n[xxx]. +.. +.cp 1 +.aa + @error{} warning: register '[' not defined + @result{} The value of xxx is 0xxx]. +.bb + @result{} The value of xxx is 12345. +@endExample +@endDefreq + +@DefreqList {dei, name [@Var{end}]} +@DefreqListEndx {dei1, name [@Var{end}]} +The @code{dei} request defines a macro with its name and end +macro indirected through strings. That is, it interpolates strings +named @var{name} and @var{end} before performing the definition. + +The following examples are equivalent. + +@Example +.ds xx aa +.ds yy bb +.dei xx yy +@endExample + +@Example +.de aa bb +@endExample + +The @code{dei1} request bears the same relationship to @code{dei} as +@code{de1} does to @code{de}; it temporarily turns compatibility mode +off when @var{name} is called. +@endDefreq + +@DefreqList {am, name [@Var{end}]} +@DefreqItemx {am1, name [@Var{end}]} +@DefreqItemx {ami, name [@Var{end}]} +@DefreqListEndx {ami1, name [@Var{end}]} +@cindex appending to a macro (@code{am}) +@cindex macro, appending to (@code{am}) +@code{am} appends subsequent input lines to macro @var{name}, extending +its definition, and otherwise working as @code{de} does. + +To make the previously defined @samp{P} macro set indented instead of +block paragraphs, add the necessary code to the existing macro. + +@Example +.am P +.ti +5n +.. +@endExample + +The other requests are analogous to their @samp{de} counterparts. The +@code{am1} request turns off compatibility mode during interpretation of +the appendment. The @code{ami} request appends indirectly, meaning that +strings @var{name} and @var{end} are interpolated with the resulting +names used before appending. The @code{ami1} request is similar to +@code{ami}, disabling compatibility mode during interpretation of the +appended lines. +@endDefreq + +@pindex trace.tmac +Using @file{trace.tmac}, you can trace calls to @code{de}, +@code{de1}, @code{am}, and @code{am1}. You can also use the +@code{backtrace} request at any point desired to troubleshoot tricky +spots (@pxref{Debugging}). + +@xref{Strings}, for the @code{als}, @code{rm}, and @code{rn} requests to +create an alias of, remove, and rename a macro, respectively. + +@cindex object creation +Macro identifiers share their name space with requests, strings, and +diversions; see @ref{Identifiers}. The @code{am}, @code{as}, @code{da}, +@code{de}, @code{di}, and @code{ds} requests (together with their +variants) create a new object only if the name of the macro, diversion, +or string is currently undefined or if it is defined as a request; +normally, they modify the value of an existing object. @xref{als,,the +description of the @code{als} request}, for pitfalls when redefining a +macro that is aliased. + +@Defreq {return, [@Var{anything}]} +Exit a macro, immediately returning to the caller. If called with an +argument @var{anything}, exit twice---the current macro and the macro +one level higher. This is used to define a wrapper macro for +@code{return} in @file{trace.tmac}. +@endDefreq + +@menu +* Parameters:: +* Copy Mode:: +@end menu + +@c --------------------------------------------------------------------- + +@node Parameters, Copy Mode, Writing Macros, Writing Macros +@subsection Parameters +@cindex parameters + +Macro calls and string interpolations optionally accept a list of +arguments; recall @ref{Calling Macros}. At the time such an +interpolation takes place, these @dfn{parameters} can be examined using +a register and a variety of escape sequences starting with @samp{\$}. +All such escape sequences are interpreted even in copy mode, a fact we +shall motivate and explain below (@pxref{Copy Mode}). + +@Defreg {.$} +@cindex parameter count register (@code{.$}) +The count of parameters available to a macro or string is kept in this +read-only register. The @code{shift} request can change its value. +@endDefreg + +Any individual parameter can be accessed by its position in the list of +arguments to the macro call, numbered from left to right starting at 1, +with one of the following escape sequences. + +@DefescList {\\$, , n, } +@DefescItem {\\$, (, nn, } +@DefescListEnd {\\$, [, nnn, ]} +Interpolate the @var{n}th, @var{nn}th, or @var{nnn}th parameter. The +first form expects only a single digit (1@leq{}@var{n}@leq{}9)), the +second two digits (01@leq{}@var{nn}@leq{}99)), and the third any +positive integer @var{nnn}. Macros and strings accept an unlimited +number of parameters. +@endDefesc + +@Defreq {shift, [@Var{n}]} +Shift the parameters @var{n} places (1@tie{}by default). This is a +``left shift'': what was parameter@tie{}@var{i} becomes parameter +@math{@var{i}-@var{n}}. The parameters formerly in positions 1 +to@tie{}@var{n} are no longer available. Shifting by a non-positive +amount performs no operation. The register @code{.$} is adjusted +accordingly. +@endDefreq + +@cindex copy mode, and macro parameters +@cindex mode, copy, and macro parameters +@cindex macro, parameters (@code{\$}) +@cindex parameters, macro (@code{\$}) +In practice, parameter interpolations are usually seen prefixed with an +extra escape character. This is because the @code{\$} family of escape +sequences is interpreted even in copy mode.@footnote{If they were not, +parameter interpolations would be similar to command-line +parameters---fixed for the entire duration of a @code{roff} program's +run. The advantage of interpolating @code{\$} escape sequences even in +copy mode is that they can interpolate different contents from one call +to the next, like function parameters in a procedural language. The +additional escape character is the price of this power.} + +@DefescList {\\$*, , , } +@DefescItemx {\\$@@, , , } +@DefescListEndx {\\$^, , , } +In some cases it is convenient to interpolate all of the parameters at +once (to pass them to a request, for instance). The @code{\$*} escape +concatenates the parameters, separating them with spaces. @code{\$@@} +is similar, concatenating the parameters, surrounding each with double +quotes and separating them with spaces. If not in compatibility mode, +the interpolation depth of double quotes is preserved (@pxref{Calling +Macros}). @code{\$^} interpolates all parameters as if they were +arguments to the @code{ds} request. + +@Example +.de foo +. tm $1='\\$1' +. tm $2='\\$2' +. tm $*='\\$*' +. tm $@@='\\$@@' +. tm $^='\\$^' +.. +.foo " This is a "test" + @error{} $1=' This is a ' + @error{} $2='test"' + @error{} $*=' This is a test"' + @error{} $@@='" This is a " "test""' + @error{} $^='" This is a "test"' +@endExample + +@code{\$*} is useful when writing a macro that doesn't need to +distinguish its arguments, or even to not interpret them; examples +include macros that produce diagnostic messages by wrapping the +@code{tm} or @code{ab} requests. Use @code{\$@@} when writing a macro +that may need to shift its parameters and/or wrap a macro or request +that finds the count significant. If in doubt, prefer @code{\$@@} to +@code{\$*}. An application of @code{\$^} is seen in @file{trace.tmac}, +which redefines some requests and macros for debugging purposes. +@endDefesc + +@Defesc {\\$0, , , } +@cindex macro name register (@code{\$0}) +@cindex @code{als} request, and @code{\$0} +Interpolate the name by which the macro being interpreted was called. +The @code{als} request can cause a macro to have more than one name. +Applying string interpolation to a macro does not change this name. + +@Example +.de foo +. tm \\$0 +.. +.als bar foo +. +.de aaa +. foo +.. +.de bbb +. bar +.. +.de ccc +\\*[foo]\\ +.. +.de ddd +\\*[bar]\\ +.. +. +.aaa + @error{} foo +.bbb + @error{} bar +.ccc + @error{} ccc +.ddd + @error{} ddd +@endExample +@endDefesc + +@c --------------------------------------------------------------------- + +@node Copy Mode, , Parameters, Writing Macros +@subsection Copy Mode +@cindex copy mode +@cindex copy mode +@cindex mode, copy +@cindex mode, copy + +@cindex @code{\n}, when reading text for a macro +@cindex @code{\$}, when reading text for a macro +@cindex @code{\*}, when reading text for a macro +@cindex \@key{RET}, when reading text for a macro +When GNU @code{troff} processes certain requests, most importantly those +which define or append to a macro or string, it does so in @dfn{copy +mode}: it copies the characters of the definition into a dedicated +storage region, interpolating the escape sequences @code{\n}, @code{\g}, +@code{\$}, @code{\*}, @code{\V}, and @code{\?} normally; interpreting +@code{\@key{RET}} immediately; discarding comments @code{\"} and +@code{\#}; interpolating the current leader, escape, or tab character +with @code{\a}, @code{\e}, and @code{\t}, respectively; and storing all +other escape sequences in an encoded form. + +@cindex interpretation mode +@cindex mode, interpretation +The complement of copy mode---a @code{roff} formatter's behavior when +not defining or appending to a macro, string, or diversion---where all +macros are interpolated, requests invoked, and valid escape sequences +processed immediately upon recognition, can be termed +@dfn{interpretation mode}. + +@Defesc {\\\\, , , } +The escape character, @code{\} by default, can escape itself. This +enables you to control whether a given @code{\n}, @code{\g}, @code{\$}, +@code{\*}, @code{\V}, or @code{\?} escape sequence is interpreted at the +time the macro containing it is defined, or later when the macro is +called.@footnote{Compare this to the @code{\def} and @code{\edef} +commands in @TeX{}.} + +@Example +.nr x 20 +.de y +.nr x 10 +\&\nx +\&\\nx +.. +.y + @result{} 20 10 +@endExample + +You can think of @code{\\} as a ``delayed'' backslash; it is the escape +character followed by a backslash from which the escape character has +removed its special meaning. Consequently, @samp{\\} is not an escape +sequence in the usual sense. In any escape sequence @samp{\@var{X}} +that GNU @code{troff} does not recognize, the escape character is +ignored and @var{X} is output. An unrecognized escape sequence causes +a warning in category @samp{escape}, with two exceptions---@samp{\\} is +the first. +@endDefesc + +@cindex @code{\\}, when reading text for a macro +@Defesc {\\., , , } +@code{\.} escapes the control character. It is similar to @code{\\} in +that it isn't a true escape sequence. It is used to permit nested macro +definitions to end without a named macro call to conclude them. Without +a syntax for escaping the control character, this would not be possible. + +@Example +.de m1 +foo +. +. de m2 +bar +\\.. +. +.. +.m1 +.m2 + @result{} foo bar +@endExample + +@noindent +The first backslash is consumed while the macro is read, and the second +is interpreted when macro @code{m1} is called. +@endDefesc + +@code{roff} documents should not use the @code{\\} or @code{\.} +character sequences outside of copy mode; they serve only to obfuscate +the input. Use @code{\e} to represent the escape character, +@code{\[rs]} to obtain a backslash glyph, and @code{\&} before @samp{.} +and @samp{'} where GNU @code{troff} expects them as control characters +if you mean to use them literally (recall @ref{Requests and Macros}). + +Macro definitions can be nested to arbitrary depth. The mechanics of +parsing the escape character have significant consequences for this +practice. + +@Example +.de M1 +\\$1 +. de M2 +\\\\$1 +. de M3 +\\\\\\\\$1 +\\\\.. +. M3 hand. +\\.. +. M2 of +.. +This understeer is getting +.M1 out + @result{} This understeer is getting out of hand. +@endExample + +Each escape character is interpreted twice---once in copy mode, when the +macro is defined, and once in interpretation mode, when the macro is +called. As seen above, this fact leads to exponential growth in the +quantity of escape characters required to delay interpolation of +@code{\n}, @code{\g}, @code{\$}, @code{\*}, @code{\V}, and @code{\?} at +each nesting level, which can be daunting. GNU @code{troff} offers a +solution. + +@Defesc {\\E, , , } +@code{\E} represents an escape character that is not interpreted in copy +mode. You can use it to ease the writing of nested macro definitions. + +@Example +.de M1 +. nop \E$1 +. de M2 +. nop \E$1 +. de M3 +. nop \E$1 +\\\\.. +. M3 better. +\\.. +. M2 bit +.. +This vehicle handles +.M1 a + @result{} This vehicle handles a bit better. +@endExample + +Observe that because @code{\.} is not a true escape sequence, we can't +use @code{\E} to keep @samp{..} from ending a macro definition +prematurely. If the multiplicity of backslashes complicates +maintenance, use end macros. + +@code{\E} is also convenient to define strings containing escape +sequences that need to work when used in copy mode (for example, as +macro arguments), or which will be interpolated at varying macro nesting +depths. We might define strings to begin and end superscripting +as follows.@footnote{These are lightly adapted from the @code{groff} +implementation of the @file{ms} macros.} + +@Example +.ds @{ \v'-.9m\s'\En[.s]*7u/10u'+.7m' +.ds @} \v'-.7m\s0+.9m' +@endExample + +When the @code{ec} request is used to redefine the escape character, +@code{\E} also makes it easier to distinguish the semantics of an escape +character from the other meaning(s) its character might have. Consider +the use of an unusual escape character, @samp{-}. + +@Example +.nr a 1 +.ec - +.de xx +--na +.. +.xx + @result{} -na +@endExample + +@noindent +This result may surprise you; some people expect @samp{1} to be output +since register @samp{a} has clearly been defined with that value. What +has happened? The robotic replacement of @samp{\} with @samp{-} has led +us astray. You might recognize the sequence @samp{--} more readily with +the default escape character as @samp{\-}, the special character escape +sequence for the minus sign glyph. + +@Example +.nr a 1 +.ec - +.de xx +-Ena +.. +.xx + @result{} 1 +@endExample +@endDefesc + + +@c ===================================================================== + +@node Page Motions, Drawing Geometric Objects, Writing Macros, GNU troff Reference +@section Page Motions +@cindex page motions +@cindex motions, page + +@xref{Manipulating Spacing}, for a discussion of the most commonly used +request for vertical motion, @code{sp}, which spaces downward by one +vee. + +@DefreqList {mk, [@Var{reg}]} +@DefreqListEndx {rt, [@Var{dist}]} +@cindex marking vertical page location (@code{mk}) +@cindex page location, vertical, marking (@code{mk}) +@cindex location, vertical, page, marking (@code{mk}) +@cindex vertical page location, marking (@code{mk}) +@cindex returning to marked vertical page location (@code{rt}) +@cindex page location, vertical, returning to marked (@code{rt}) +@cindex location, vertical, page, returning to marked (@code{rt}) +@cindex vertical page location, returning to marked (@code{rt}) +You can @dfn{mark} a location on a page for subsequent @dfn{return}. +@code{mk} takes an argument, a register name in which to store the +current page location. If given no argument, it stores the location in +an internal register. This location can be used later by the @code{rt} +or the @code{sp} requests (or the @code{\v} escape). + +The @code{rt} request returns @emph{upward} to the location marked with +the last @code{mk} request. If used with an argument, it returns to a +vertical position@tie{}@var{dist} from the top of the page (no previous +call to @code{mk} is necessary in this case). The default scaling +unit is @samp{v}. + +If a page break occurs between a @code{mk} request and its matching +@code{rt} request, the @code{rt} request is silently ignored. + +A simple implementation of a macro to set text in two columns follows. + +@Example +.nr column-length 1.5i +.nr column-gap 4m +.nr bottom-margin 1m +. +.de 2c +. br +. mk +. ll \\n[column-length]u +. wh -\\n[bottom-margin]u 2c-trap +. nr right-side 0 +.. +. +.de 2c-trap +. ie \\n[right-side] \@{\ +. nr right-side 0 +. po -(\\n[column-length]u + \\n[column-gap]u) +. \" remove trap +. wh -\\n[bottom-margin]u +. \@} +. el \@{\ +. \" switch to right side +. nr right-side 1 +. po +(\\n[column-length]u + \\n[column-gap]u) +. rt +. \@} +.. +@endExample + +Now let us apply our two-column macro. + +@Example +.pl 1.5i +.ll 4i +This is a small test that shows how the +rt request works in combination with mk. + +.2c +Starting here, text is typeset in two columns. +Note that this implementation isn't robust +and thus not suited for a real two-column +macro. + @result{} This is a small test that shows how the + @result{} rt request works in combination with mk. + @result{} + @result{} Starting here, isn't robust + @result{} text is typeset and thus not + @result{} in two columns. suited for a + @result{} Note that this real two-column + @result{} implementation macro. +@endExample +@endDefreq + +Several escape sequences enable fine control of movement about the page. + +@Defesc {\\v, @code{'}, expr, @code{'}} +@cindex vertical motion (@code{\v}) +@cindex motion, vertical (@code{\v}) +Vertically move the drawing position. @var{expr} indicates the +magnitude of motion: positive is downward and and negative upward. The +default scaling unit is @samp{v}. The motion is relative to the current +drawing position unless @var{expr} begins with the boundary-relative +motion operator @samp{|}. @xref{Numeric Expressions}. + +Text processing continues at the new drawing position; usually, vertical +motions should be in balanced pairs to avoid a confusing page layout. + +@code{\v} will not spring a vertical position trap. This can be useful; +for example, consider a page bottom trap macro that prints a marker in +the margin to indicate continuation of a footnote. @xref{Traps}. +@endDefesc + +A few escape sequences that produce vertical motion are unusual. They +are thought to originate early in AT&T @code{nroff} history to achieve +super- and subscripting by half-line motions on line printers and +teletypewriters before the phototypesetter made more precise positioning +available. They are reckoned in ems---not vees---to maintain continuity +with their original purpose of moving relative to the size of the type +rather than the distance between text baselines (vees).@footnote{At the +@code{grops} defaults of 10-point type on 12-point vertical spacing, the +difference between half a vee and half an em can be subtle:@: large +spacings like @samp{.vs .5i} make it obvious.} + +@DefescList {\\r, , , } +@DefescItemx {\\u, , , } +@DefescListEndx {\\d, , , } +Move upward@tie{}1@dmn{m}, upward@tie{}.5@dmn{m}, and +downward@tie{}.5@dmn{m}, respectively. +@endDefesc + +@noindent +Let us see these escape sequences in use. + +@Example +Obtain 100 cm\u3\d of \ka\d\092\h'|\nau'\r233\dU. +@endExample + +In the foregoing we have paired @code{\u} and @code{\d} to typeset a +superscript, and later a full em negative (``reverse'') motion to place +a superscript above a subscript. A numeral-width horizontal motion +escape sequence aligns the proton and nucleon numbers, while @code{\k} +marks a horizontal position to which @code{\h} returns so that we could +stack them. (We shall discuss these horizontal motion escape sequences +presently.) In serious applications, we often want to alter the type +size of the -scripts and to fine-tune the vertical motions, as the +@code{groff} @file{ms} package does with its super- and subscripting +string definitions. + +@Defesc {\\h, @code{'}, expr, @code{'}} +@cindex inserting horizontal space (@code{\h}) +@cindex horizontal space (@code{\h}) +@cindex space, horizontal (@code{\h}) +@cindex horizontal motion (@code{\h}) +@cindex motion, horizontal (@code{\h}) +Horizontally move the drawing position. @var{expr} indicates the +magnitude of motion: positive is rightward and negative leftward. The +default scaling unit is @samp{m}. The motion is relative to the current +drawing position unless @var{expr} begins with the boundary-relative +motion operator @samp{|}. @xref{Numeric Expressions}. +@endDefesc + +The following string definition sets the @TeX{} +logo.@footnote{@xref{Strings}, for an explanation of the trailing +@samp{\"}.} + +@Example +.ds TeX T\h'-.1667m'\v'.224m'E\v'-.224m'\h'-.125m'X\" +@endExample + +There are a number of special-case escape sequences for horizontal +motion. + +@Defesc {\\@key{SP}, , , } +@cindex space, unbreakable and unadjustable (@code{\@key{SP}}) +@cindex unbreakable and unadjustable space (@code{\@key{SP}}) +@cindex unadjustable and unbreakable space (@code{\@key{SP}}) +@c We use the following notation in our man pages; Texinfo is bound to +@c the GNU Emacs dialect. +@esindex \@slanted{space} +Move right one word space. (The input is a backslash followed by a +space.) This escape sequence can be thought of as a non-adjustable, +unbreakable space. Usually you want @code{\~} instead; see +@ref{Manipulating Filling and Adjustment}. +@endDefesc + +@cindex thin space (@code{\|}) +@cindex space, thin (@code{\|}) +@Defesc {\\|, , , } +Move one-sixth @dmn{em} to the right on typesetting output devices. If +a glyph named @samp{\|} is defined in the current font, its width is +used instead, even on terminal output devices. +@endDefesc + +@cindex hair space (@code{\^}) +@cindex space, hair (@code{\^}) +@Defesc {\\^, , , } +Move one-twelfth @dmn{em} to the right on typesetting output devices. +If a glyph named @samp{\^} is defined in the current font, its width is +used instead, even on terminal output devices. +@endDefesc + +@Defesc {\\0, , , } +@cindex space, width of a digit (numeral) (@code{\0}) +@cindex digit-width space (@code{\0}) +@cindex figure space (@code{\0}) +@cindex numeral-width space (@code{\0}) +Move right by the width of a numeral in the current font. +@endDefesc + +Horizontal motions are not discarded at the end of an output line as +word spaces are. @xref{Breaking}. + +@DefescList {\\w, @code{'}, anything, @code{'}} +@DefregItemx {st} +@DefregItemx {sb} +@DefregItemx {rst} +@DefregItemx {rsb} +@DefregItemx {ct} +@DefregItemx {ssc} +@DefregListEndx {skw} +@cindex width escape (@code{\w}) +Interpolate the width of @var{anything} in basic units. This escape +sequence allows several properties of formatted output to be measured +without writing it out. + +@Example +The length of the string 'abc' is \w'abc'u. + @result{} The length of the string 'abc' is 72u. +@endExample + +@cindex dummy environment, used by @code{\w} escape sequence +@cindex environment, dummy, used by @code{\w} escape sequence +@var{anything} is processed in a dummy environment:@: this means that +font and type size changes, for example, may occur within it without +affecting subsequent output. + +@need 500 +After each use, @code{\w} sets several registers. + +@cindex CSTR@tie{}#54 errata +@cindex CSTR@tie{}#54 erratum, @code{sb} register +@cindex CSTR@tie{}#54 erratum, @code{st} register +@table @code +@item st +@itemx sb +The maximum vertical displacements of the text baseline above and below, +respectively. The sign convention is opposite that of relative vertical +motions; that is, depth below the (original) baseline is negative. +These registers are incorrectly documented in the @acronym{AT&T} +@code{troff} manual as ``the highest and lowest extent of [the argument +to @code{\w}] relative to the baseline''. + +@item rst +@itemx rsb +Like @code{st} and @code{sb}, but taking account of the heights and +depths of glyphs. In other words, these registers store the highest and +lowest vertical positions attained by @var{anything}, doing what +@acronym{AT&T} @code{troff} documented @code{st} and @code{sb} as doing. + +@item ct +Characterizes the geometry of glyphs occurring in @var{anything}. + +@table @asis +@item 0 +only short glyphs, no descenders or tall glyphs + +@item 1 +at least one descender + +@item 2 +at least one tall glyph + +@item 3 +at least one each of a descender and a tall glyph +@end table + +@item ssc +The amount of horizontal space (possibly negative) that should be added +to the last glyph before a subscript. + +@item skw +How far to right of the center of the last glyph in the @code{\w} +argument, the center of an accent from a roman font should be placed +over that glyph. +@end table +@endDefesc + +@DefescList {\\k, , p, } +@DefescItem {\\k, (, ps, } +@DefescListEnd {\\k, [, position, ]} +@cindex saving horizontal input line position (@code{\k}) +@cindex horizontal input line position, saving (@code{\k}) +@cindex input line position, horizontal, saving (@code{\k}) +@cindex position, horizontal input line, saving (@code{\k}) +@cindex line, input, horizontal position, saving (@code{\k}) +Store the current horizontal position in the @emph{input} line in a +register with the name @var{position} (one-character name@tie{}@var{p}, +two-character name @var{ps}). Use this, for example, to return to the +beginning of a string for highlighting or other decoration. +@endDefesc + +@Defreg {hp} +@cindex horizontal input line position register (@code{hp}) +@cindex input line, horizontal position, register (@code{hp}) +@cindex position, horizontal, in input line, register (@code{hp}) +@cindex line, input, horizontal position, register (@code{hp}) +The current horizontal position at the input line. +@endDefreg + +@Defreg {.k} +@cindex horizontal output line position register (@code{.k}) +@cindex output line, horizontal position, register (@code{.k}) +@cindex position, horizontal, in output line, register (@code{.k}) +@cindex line, output, horizontal position, register (@code{.k}) +A read-only register containing the current horizontal output position +(relative to the current indentation). +@endDefreg + +@Defesc {\\o, @code{'}, abc@dots{}, @code{'}} +@cindex overstriking glyphs (@code{\o}) +@cindex glyphs, overstriking (@code{\o}) +Overstrike the glyphs of characters @var{a}, @var{b}, @var{c}, @dots{}; +the glyphs are centered, written, and the drawing position advanced by +the widest of the glyphs. +@endDefesc + +@Defesc {\\z, , c, } +@cindex zero-width printing (@code{\z}, @code{\Z}) +@cindex printing, zero-width (@code{\z}, @code{\Z}) +Format the character @var{c} with zero width; that is, without advancing +the drawing position. Use @code{\z} to overstrike glyphs aligned to +their left edges, in contrast to @code{\o}'s centering. +@endDefesc + +@Defesc {\\Z, @code{'}, anything, @code{'}} +@cindex zero-width printing (@code{\z}, @code{\Z}) +@cindex printing, zero-width (@code{\z}, @code{\Z}) +Save the drawing position, format @var{anything}, then restore it. Tabs +and leaders in the argument are ignored with an error diagnostic. + +We might implement a strike-through macro thus. + +@Example +.de ST +.nr width \w'\\$1' +\Z@@\v'-.25m'\l'\\n[width]u'@@\\$1 +.. +. +This is +.ST "a test" +an actual emergency! +@endExample +@endDefesc + + +@c ===================================================================== + +@node Drawing Geometric Objects, Traps, Page Motions, GNU troff Reference +@section Drawing Geometric Objects +@cindex drawing requests +@cindex requests for drawing + +A few of the formatter's escape sequences draw lines and other geometric +objects. Combined with each other and with page motion commands +(@pxref{Page Motions}), a wide variety of figures is possible. For +complex drawings, these operations can be cumbersome; the preprocessors +@code{gpic} or @code{ggrn} are typically used instead. + +The @code{\l} and @code{\L} escape sequences draw horizontal and +vertical sequences of glyphs, respectively. Even the simplest of +output devices supports them. + +@DefescList {\\l, @code{'}, l, @code{'}} +@DefescListEnd {\\l, @code{'}, lc, @code{'}} +@cindex drawing horizontal lines (@code{\l}) +@cindex horizontal line, drawing (@code{\l}) +@cindex line, horizontal, drawing (@code{\l}) +Draw a horizontal line of length @var{l} from the drawing position. +Rightward motion is positive. Afterward, the drawing position is at the +right end of the line. The default scaling unit is @samp{m}. + +@cindex baseline rule special character(@code{\[ru]}) +@cindex glyph, underscore (@code{\[ru]}) +@cindex line drawing glyph +@cindex glyph, for line drawing +The optional second parameter@tie{}@var{c} is a character with which to +draw the line. The default is the baseline rule special character, +@code{\[ru]}. + +@cindex dummy character (@code{\&}), effect on @code{\l} escape sequence +@cindex character, dummy (@code{\&}), effect on @code{\l} escape sequence +If @var{c} is a valid scaling unit, put @code{\&} after @var{l} to +disambiguate the input. + +@Example +.de textbox +\[br]\\$*\[br]\l'|0\[rn]'\l'|0\[ul]' +.. +@endExample + +@noindent +The foregoing outputs a box rule (a vertical line), the text +argument(s), and another box rule. We employ the boundary-relative +motion operator @samp{|}. Finally, the line-drawing escape sequences +draw a radical extender (a form of overline) and an underline from the +drawing position to the position coresponding to beginning of the +@emph{input} line. The drawing position returns to just after the +right-hand box rule because the lengths of the drawn lines are negative, +as noted above. +@endDefesc + +@DefescList {\\L, @code{'}, l, @code{'}} +@DefescListEnd {\\L, @code{'}, lc, @code{'}} +@cindex drawing vertical lines (@code{\L}) +@cindex vertical line drawing (@code{\L}) +@cindex line, vertical, drawing (@code{\L}) +@cindex line drawing glyph +@cindex glyph for line drawing +@cindex box rule glyph (@code{\[br]}) +@cindex glyph, box rule (@code{\[br]}) +Draw a vertical line of length @var{l} from the drawing position. +Downward motion is positive. The default scaling unit is @samp{v}. The +default character is the box rule, @code{\[br]}. As with vertical +motion escape sequences, text processing continues where the line ends. +@code{\L} is otherwise similar to @code{\l}. + +@Example +$ nroff <
" +. LK +. HTML

" +. nr SH-open 1 +.. +. +.\" -------------------------------------------------------------------- +.\" LNE - left navigation end +.\" +.de LNE +. HTML

+. HR +.. +. +.nr SH-open 0 +.nr needs-begin 0 +. +.\" +.\" some auxiliary macros for left navigation lists +.\" +.de www-SH +. if (0\\$1 == 0) \{\ +. if (\\n[SH-open] == 1) \ +. LNE +. nr needs-begin 1 +. @SH-old +. \} +.. +. +.de www-NH +. if (0\\$1 <= 1) \{\ +. if (\\n[SH-open] == 1) \ +. LNE +. nr needs-begin 1 +. @NH-old +. \} +.. +. +.de www-LP +. @LP-old +. if (\\n[needs-begin] == 1) \{\ +. HR +. LNS +. \} +. nr needs-begin 0 +.. +. +.\" -------------------------------------------------------------------- +.\" ALN [colour] [left width percentage] +.\" +.\" Turn on automatic left navigation. This macro should only be +.\" called once (normally at the start of the document) as it +.\" indicates that all top-level section headings form a navigation +.\" list on the left of the main text. +.\" +.de ALN +. if '\*[.T]'html' \{\ +. if !'\\$1'' \ +. ds www-nav-colour \\$1\" +. if (0\\$2 > 0) \{\ +. nr www-nav-width-left \\$2 +. nr www-nav-width-right (100 - \\$2) +. \} +. rn @SH @SH-old +. rn www-SH @SH +. rn @NH @NH-old +. rn www-NH @NH +. rn @LP @LP-old +. rn www-LP @LP +. \} +.. +. +.\" -------------------------------------------------------------------- +.\" LINKSTYLE color [fontstyle [openglyph closeglyph]] +.\" +.\" Initialize www.tmac so that when this macro set is used with +.\" non-HTML devices the urls are rendered the user defined +.\" attributes. For example: +.\" +.\" LINKSTYLE blue CR < > +.\" +.de LINKSTYLE +. if (\\n[.$] < 1) \ +. www:error .\\$0 expects at least 1 argument, got \\n[.$] +. ds www:color \\$1\" +. shift +. if (\\n[.$] < 1) \ +. return +. ds www:fontstyle \\$1\" +. shift +. if (\\n[.$] < 1) \ +. www:error .\\$0 expects both open and close glyphs to be specified +. ds www:open \\$1\" +. ds www:close \\$2\" +.. +. +.\" MATHML - enable eqn mathml output to pass through to the device +.\" driver +. +.de MATHML +. if (\\n[.O] == 0) \ +. MATH \\$* +.. +. +.\" -------------------------------------------------------------------- +.\" final setup +.\" -------------------------------------------------------------------- +. +.LINKSTYLE blue CR \[la] \[ra] +. +.if \n[www-html] \{\ +. nh +. nr HY 0 +.\} +. +.if r ps4html .nop \O[0] +.cp \n[*groff_www_tmac_in_C] +.do rr *groff_www_tmac_in_C +. +.\" now set +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/tmac/zh.tmac b/tmac/zh.tmac new file mode 100644 index 0000000..3b34724 --- /dev/null +++ b/tmac/zh.tmac @@ -0,0 +1,61 @@ +.\" Chinese localization for groff +.\" +.\" Copyright (C) 2015-2020 Free Software Foundation, Inc. +.\" Written by Darcy SHEN +.\" using 'ja.tmac' as a template +.\" +.\" This file 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 +.\" . +.\" +.\" Please send comments to groff@gnu.org. +. +.do nr *groff_zh_tmac_C \n[.cp] +.cp 0 +. +. +.\" The following rules work for both zh_CN and zh_TW. +. +.ds locale chinese\" +. +. +.class [CJKprepunct] \ + , : ; > } \ + \[u2026] \[u201D] \ + \[u3001] \[u3002] \[u3009] \[u300B] \[u300D] \[u300F] \[u3011] \ + \[uFF01] \[uFF09] \[uFF0C] \[uFF1A] \[uFF1B] \[uFF1F] +.class [CJKpostpunct] \ + \[u201C] \[u3008] \[u300A] \[u300C] \[u300E] \[u3010] \[uFF08] +. +.\" Chinese glyphs. +.class [CJKnormal] \ + \[u4E00]-\[u9FFF] +. +.cflags 128 \C'[CJKprepunct]' +.cflags 266 \C'[CJKpostpunct]' +.cflags 512 \C'[CJKnormal]' +. +.\" Chinese hyphenation (disabled) +.nr \*[locale]*hyphenation-mode-base 0 +.nr \*[locale]*hyphenation-mode-trap 0 +. +.cp \n[*groff_zh_tmac_C] +.do rr *groff_zh_tmac_C +. +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 72 +.\" End: +.\" vim: set filetype=groff textwidth=72: -- cgit v1.2.3